Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Side by Side Diff: runtime/vm/intermediate_language.cc

Issue 10891025: Eliminate class UseVal. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/dart_entry.h" 8 #include "vm/dart_entry.h"
9 #include "vm/flow_graph_allocator.h" 9 #include "vm/flow_graph_allocator.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
11 #include "vm/flow_graph_compiler.h" 11 #include "vm/flow_graph_compiler.h"
12 #include "vm/locations.h" 12 #include "vm/locations.h"
13 #include "vm/object.h" 13 #include "vm/object.h"
14 #include "vm/object_store.h" 14 #include "vm/object_store.h"
15 #include "vm/os.h" 15 #include "vm/os.h"
16 #include "vm/scopes.h" 16 #include "vm/scopes.h"
17 #include "vm/stub_code.h" 17 #include "vm/stub_code.h"
18 #include "vm/symbols.h" 18 #include "vm/symbols.h"
19 19
20 namespace dart { 20 namespace dart {
21 21
22 DECLARE_FLAG(bool, enable_type_checks); 22 DECLARE_FLAG(bool, enable_type_checks);
23 23
24 24
25 intptr_t Computation::Hashcode() const { 25 intptr_t Computation::Hashcode() const {
26 intptr_t result = computation_kind(); 26 intptr_t result = computation_kind();
27 for (intptr_t i = 0; i < InputCount(); ++i) { 27 for (intptr_t i = 0; i < InputCount(); ++i) {
28 UseVal* val = InputAt(i)->AsUse(); 28 Value* value = InputAt(i);
29 intptr_t j = val != NULL 29 intptr_t j = value->definition()->ssa_temp_index();
30 ? val->definition()->ssa_temp_index()
31 : -1;
32 result = result * 31 + j; 30 result = result * 31 + j;
33 } 31 }
34 return result; 32 return result;
35 } 33 }
36 34
37 35
38 bool Computation::Equals(Computation* other) const { 36 bool Computation::Equals(Computation* other) const {
39 if (computation_kind() != other->computation_kind()) return false; 37 if (computation_kind() != other->computation_kind()) return false;
40 for (intptr_t i = 0; i < InputCount(); ++i) { 38 for (intptr_t i = 0; i < InputCount(); ++i) {
41 if (!InputAt(i)->Equals(other->InputAt(i))) return false; 39 if (!InputAt(i)->Equals(other->InputAt(i))) return false;
42 } 40 }
43 return AttributesEqual(other); 41 return AttributesEqual(other);
44 } 42 }
45 43
46 44
47 bool UseVal::Equals(Value* other) const { 45 bool Value::Equals(Value* other) const {
48 return other->IsUse() 46 return definition() == other->definition();
49 && definition() == other->AsUse()->definition();
50 } 47 }
51 48
52 49
53 bool CheckClassComp::AttributesEqual(Computation* other) const { 50 bool CheckClassComp::AttributesEqual(Computation* other) const {
54 CheckClassComp* other_check = other->AsCheckClass(); 51 CheckClassComp* other_check = other->AsCheckClass();
55 if (other_check == NULL) return false; 52 if (other_check == NULL) return false;
56 if (ic_data()->NumberOfChecks() != other->ic_data()->NumberOfChecks()) { 53 if (ic_data()->NumberOfChecks() != other->ic_data()->NumberOfChecks()) {
57 return false; 54 return false;
58 } 55 }
59 for (intptr_t i = 0; i < ic_data()->NumberOfChecks(); ++i) { 56 for (intptr_t i = 0; i < ic_data()->NumberOfChecks(); ++i) {
60 // TODO(fschneider): Make sure ic_data are sorted to hit more cases. 57 // TODO(fschneider): Make sure ic_data are sorted to hit more cases.
61 if (ic_data()->GetReceiverClassIdAt(i) != 58 if (ic_data()->GetReceiverClassIdAt(i) !=
62 other->ic_data()->GetReceiverClassIdAt(i)) { 59 other->ic_data()->GetReceiverClassIdAt(i)) {
63 return false; 60 return false;
64 } 61 }
65 } 62 }
66 return true; 63 return true;
67 } 64 }
68 65
69 66
70 bool CheckArrayBoundComp::AttributesEqual(Computation* other) const { 67 bool CheckArrayBoundComp::AttributesEqual(Computation* other) const {
71 CheckArrayBoundComp* other_check = other->AsCheckArrayBound(); 68 CheckArrayBoundComp* other_check = other->AsCheckArrayBound();
72 if (other_check == NULL) return false; 69 if (other_check == NULL) return false;
73 return array_type() == other_check->array_type(); 70 return array_type() == other_check->array_type();
74 } 71 }
75 72
76 73
77 // Returns true if the value represents a constant. 74 // Returns true if the value represents a constant.
78 bool UseVal::BindsToConstant() const { 75 bool Value::BindsToConstant() const {
79 BindInstr* bind = definition()->AsBind(); 76 BindInstr* bind = definition()->AsBind();
80 return (bind != NULL) && (bind->computation()->AsConstant() != NULL); 77 return (bind != NULL) && (bind->computation()->AsConstant() != NULL);
81 } 78 }
82 79
83 80
84 // Returns true if the value represents constant null. 81 // Returns true if the value represents constant null.
85 bool UseVal::BindsToConstantNull() const { 82 bool Value::BindsToConstantNull() const {
86 BindInstr* bind = definition()->AsBind(); 83 BindInstr* bind = definition()->AsBind();
87 if (bind == NULL) { 84 if (bind == NULL) {
88 return false; 85 return false;
89 } 86 }
90 ConstantComp* constant = bind->computation()->AsConstant(); 87 ConstantComp* constant = bind->computation()->AsConstant();
91 return (constant != NULL) && constant->value().IsNull(); 88 return (constant != NULL) && constant->value().IsNull();
92 } 89 }
93 90
94 91
95 const Object& UseVal::BoundConstant() const { 92 const Object& Value::BoundConstant() const {
96 ASSERT(BindsToConstant()); 93 ASSERT(BindsToConstant());
97 BindInstr* bind = definition()->AsBind(); 94 BindInstr* bind = definition()->AsBind();
98 ASSERT(bind != NULL); 95 ASSERT(bind != NULL);
99 ConstantComp* constant = bind->computation()->AsConstant(); 96 ConstantComp* constant = bind->computation()->AsConstant();
100 ASSERT(constant != NULL); 97 ASSERT(constant != NULL);
101 return constant->value(); 98 return constant->value();
102 } 99 }
103 100
104 101
105 bool ConstantComp::AttributesEqual(Computation* other) const { 102 bool ConstantComp::AttributesEqual(Computation* other) const {
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 } 384 }
388 } 385 }
389 386
390 387
391 void Instruction::RecordAssignedVars(BitVector* assigned_vars, 388 void Instruction::RecordAssignedVars(BitVector* assigned_vars,
392 intptr_t fixed_parameter_count) { 389 intptr_t fixed_parameter_count) {
393 // Nothing to do for the base class. 390 // Nothing to do for the base class.
394 } 391 }
395 392
396 393
397 void UseVal::AddToInputUseList() { 394 void Value::AddToInputUseList() {
398 set_next_use(definition()->input_use_list()); 395 set_next_use(definition()->input_use_list());
399 definition()->set_input_use_list(this); 396 definition()->set_input_use_list(this);
400 } 397 }
401 398
402 399
403 void UseVal::AddToEnvUseList() { 400 void Value::AddToEnvUseList() {
404 set_next_use(definition()->env_use_list()); 401 set_next_use(definition()->env_use_list());
405 definition()->set_env_use_list(this); 402 definition()->set_env_use_list(this);
406 } 403 }
407 404
408 405
409 void Definition::ReplaceUsesWith(Definition* other) { 406 void Definition::ReplaceUsesWith(Definition* other) {
410 ASSERT(other != NULL); 407 ASSERT(other != NULL);
411 ASSERT(this != other); 408 ASSERT(this != other);
412 while (input_use_list_ != NULL) { 409 while (input_use_list_ != NULL) {
413 UseVal* current = input_use_list_; 410 Value* current = input_use_list_;
414 input_use_list_ = input_use_list_->next_use(); 411 input_use_list_ = input_use_list_->next_use();
415 current->set_definition(other); 412 current->set_definition(other);
416 current->AddToInputUseList(); 413 current->AddToInputUseList();
417 } 414 }
418 while (env_use_list_ != NULL) { 415 while (env_use_list_ != NULL) {
419 UseVal* current = env_use_list_; 416 Value* current = env_use_list_;
420 env_use_list_ = env_use_list_->next_use(); 417 env_use_list_ = env_use_list_->next_use();
421 current->set_definition(other); 418 current->set_definition(other);
422 current->AddToEnvUseList(); 419 current->AddToEnvUseList();
423 } 420 }
424 } 421 }
425 422
426 423
427 bool Definition::SetPropagatedCid(intptr_t cid) { 424 bool Definition::SetPropagatedCid(intptr_t cid) {
428 if (cid == kIllegalCid) { 425 if (cid == kIllegalCid) {
429 return false; 426 return false;
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 ASSERT(index == 0); 670 ASSERT(index == 0);
674 return successor(); 671 return successor();
675 } 672 }
676 673
677 674
678 void Instruction::Goto(JoinEntryInstr* entry) { 675 void Instruction::Goto(JoinEntryInstr* entry) {
679 set_next(new GotoInstr(entry)); 676 set_next(new GotoInstr(entry));
680 } 677 }
681 678
682 679
683 RawAbstractType* UseVal::CompileType() const { 680 RawAbstractType* Value::CompileType() const {
684 if (definition()->HasPropagatedType()) { 681 if (definition()->HasPropagatedType()) {
685 return definition()->PropagatedType(); 682 return definition()->PropagatedType();
686 } 683 }
687 // The compile type may be requested when building the flow graph, i.e. before 684 // The compile type may be requested when building the flow graph, i.e. before
688 // type propagation has occurred. To avoid repeatedly computing the compile 685 // type propagation has occurred. To avoid repeatedly computing the compile
689 // type of the definition, we store it as initial propagated type. 686 // type of the definition, we store it as initial propagated type.
690 AbstractType& type = AbstractType::Handle(definition()->CompileType()); 687 AbstractType& type = AbstractType::Handle(definition()->CompileType());
691 definition()->SetPropagatedType(type); 688 definition()->SetPropagatedType(type);
692 return type.raw(); 689 return type.raw();
693 } 690 }
694 691
695 692
696 intptr_t UseVal::ResultCid() const { 693 intptr_t Value::ResultCid() const {
697 return definition()->GetPropagatedCid(); 694 return definition()->GetPropagatedCid();
698 } 695 }
699 696
700 697
701 698
702 RawAbstractType* ConstantComp::CompileType() const { 699 RawAbstractType* ConstantComp::CompileType() const {
703 if (value().IsNull()) { 700 if (value().IsNull()) {
704 return Type::NullType(); 701 return Type::NullType();
705 } 702 }
706 if (value().IsInstance()) { 703 if (value().IsInstance()) {
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
1082 } 1079 }
1083 1080
1084 1081
1085 // Optimizations that eliminate or simplify individual computations. 1082 // Optimizations that eliminate or simplify individual computations.
1086 Definition* Computation::TryReplace(BindInstr* instr) const { 1083 Definition* Computation::TryReplace(BindInstr* instr) const {
1087 return instr; 1084 return instr;
1088 } 1085 }
1089 1086
1090 1087
1091 Definition* StrictCompareComp::TryReplace(BindInstr* instr) const { 1088 Definition* StrictCompareComp::TryReplace(BindInstr* instr) const {
1092 UseVal* left_use = left()->AsUse(); 1089 if (!right()->BindsToConstant()) return instr;
1093 UseVal* right_use = right()->AsUse(); 1090 const Object& right_constant = right()->BoundConstant();
1094 if ((right_use == NULL) || (left_use == NULL)) return instr; 1091 Definition* left_defn = left()->definition();
1095 if (!right_use->BindsToConstant()) return instr;
1096 const Object& right_constant = right_use->BoundConstant();
1097 Definition* left = left_use->definition();
1098 // TODO(fschneider): Handle other cases: e === false and e !== true/false. 1092 // TODO(fschneider): Handle other cases: e === false and e !== true/false.
1099 // Handles e === true. 1093 // Handles e === true.
1100 if ((kind() == Token::kEQ_STRICT) && 1094 if ((kind() == Token::kEQ_STRICT) &&
1101 (right_constant.raw() == Bool::True()) && 1095 (right_constant.raw() == Bool::True()) &&
1102 (left_use->ResultCid() == kBoolCid)) { 1096 (left()->ResultCid() == kBoolCid)) {
1103 // Remove the constant from the graph. 1097 // Remove the constant from the graph.
1104 BindInstr* right = right_use->definition()->AsBind(); 1098 BindInstr* right_defn = right()->definition()->AsBind();
1105 if (right != NULL) { 1099 if (right_defn != NULL) {
1106 right->RemoveFromGraph(); 1100 right_defn->RemoveFromGraph();
1107 } 1101 }
1108 // Return left subexpression as the replacement for this instruction. 1102 // Return left subexpression as the replacement for this instruction.
1109 return left; 1103 return left_defn;
1110 } 1104 }
1111 return instr; 1105 return instr;
1112 } 1106 }
1113 1107
1114 1108
1115 Definition* CheckClassComp::TryReplace(BindInstr* instr) const { 1109 Definition* CheckClassComp::TryReplace(BindInstr* instr) const {
1116 const intptr_t v_cid = value()->ResultCid(); 1110 const intptr_t v_cid = value()->ResultCid();
1117 const intptr_t num_checks = ic_data()->NumberOfChecks(); 1111 const intptr_t num_checks = ic_data()->NumberOfChecks();
1118 if ((num_checks == 1) && 1112 if ((num_checks == 1) &&
1119 (v_cid == ic_data()->GetReceiverClassIdAt(0))) { 1113 (v_cid == ic_data()->GetReceiverClassIdAt(0))) {
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
1512 } 1506 }
1513 } 1507 }
1514 1508
1515 1509
1516 Environment::Environment(const GrowableArray<Definition*>& definitions, 1510 Environment::Environment(const GrowableArray<Definition*>& definitions,
1517 intptr_t fixed_parameter_count) 1511 intptr_t fixed_parameter_count)
1518 : values_(definitions.length()), 1512 : values_(definitions.length()),
1519 locations_(NULL), 1513 locations_(NULL),
1520 fixed_parameter_count_(fixed_parameter_count) { 1514 fixed_parameter_count_(fixed_parameter_count) {
1521 for (intptr_t i = 0; i < definitions.length(); ++i) { 1515 for (intptr_t i = 0; i < definitions.length(); ++i) {
1522 values_.Add(new UseVal(definitions[i])); 1516 values_.Add(new Value(definitions[i]));
1523 } 1517 }
1524 } 1518 }
1525 1519
1526 1520
1527 // Copies the environment and updates the environment use lists. 1521 // Copies the environment and updates the environment use lists.
1528 void Environment::CopyTo(Instruction* instr) const { 1522 void Environment::CopyTo(Instruction* instr) const {
1529 Environment* copy = new Environment(values().length(), 1523 Environment* copy = new Environment(values().length(),
1530 fixed_parameter_count()); 1524 fixed_parameter_count());
1531 GrowableArray<Value*>* values_copy = copy->values_ptr(); 1525 GrowableArray<Value*>* values_copy = copy->values_ptr();
1532 for (intptr_t i = 0; i < values().length(); ++i) { 1526 for (intptr_t i = 0; i < values().length(); ++i) {
1533 Value* value = values()[i]->CopyValue(); 1527 Value* value = values()[i]->Copy();
1534 values_copy->Add(value); 1528 values_copy->Add(value);
1535 UseVal* use = value->AsUse(); 1529 value->set_instruction(instr);
1536 if (use != NULL) { 1530 value->set_use_index(i);
1537 use->set_instruction(instr); 1531 value->AddToEnvUseList();
1538 use->set_use_index(i);
1539 use->AddToEnvUseList();
1540 }
1541 } 1532 }
1542 instr->set_env(copy); 1533 instr->set_env(copy);
1543 } 1534 }
1544 1535
1545 1536
1546 #undef __ 1537 #undef __
1547 1538
1548 } // namespace dart 1539 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698