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

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

Issue 10894034: Make constants computations instead of values. (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"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 return AttributesEqual(other); 43 return AttributesEqual(other);
44 } 44 }
45 45
46 46
47 bool UseVal::Equals(Value* other) const { 47 bool UseVal::Equals(Value* other) const {
48 return other->IsUse() 48 return other->IsUse()
49 && definition() == other->AsUse()->definition(); 49 && definition() == other->AsUse()->definition();
50 } 50 }
51 51
52 52
53 bool ConstantVal::Equals(Value* other) const {
54 return other->IsConstant()
55 && value().raw() == other->AsConstant()->value().raw();
56 }
57
58
59 bool CheckClassComp::AttributesEqual(Computation* other) const {
60 CheckClassComp* other_check = other->AsCheckClass();
61 if (other_check == NULL) return false;
62 if (ic_data()->NumberOfChecks() != other->ic_data()->NumberOfChecks()) {
63 return false;
64 }
65 for (intptr_t i = 0; i < ic_data()->NumberOfChecks(); ++i) {
66 // TODO(fschneider): Make sure ic_data are sorted to hit more cases.
67 if (ic_data()->GetReceiverClassIdAt(i) !=
68 other->ic_data()->GetReceiverClassIdAt(i)) {
69 return false;
70 }
71 }
72 return true;
73 }
74
75
76 // Returns true if the value represents a constant. 53 // Returns true if the value represents a constant.
77 bool UseVal::BindsToConstant() const { 54 bool UseVal::BindsToConstant() const {
78 BindInstr* bind = definition()->AsBind(); 55 BindInstr* bind = definition()->AsBind();
79 if (bind == NULL) { 56 return (bind != NULL) && (bind->computation()->AsConstant() != NULL);
80 return false;
81 }
82 return bind->computation()->AsMaterialize() != NULL;
83 } 57 }
84 58
85 59
86 // Returns true if the value represents constant null. 60 // Returns true if the value represents constant null.
87 bool UseVal::BindsToConstantNull() const { 61 bool UseVal::BindsToConstantNull() const {
88 BindInstr* bind = definition()->AsBind(); 62 BindInstr* bind = definition()->AsBind();
89 if (bind == NULL) { 63 if (bind == NULL) {
90 return false; 64 return false;
91 } 65 }
92 MaterializeComp* constant = bind->computation()->AsMaterialize(); 66 ConstantComp* constant = bind->computation()->AsConstant();
93 if (constant != NULL) { 67 return (constant != NULL) && constant->value().IsNull();
94 return constant->constant_val()->value().IsNull();
95 }
96 return false;
97 } 68 }
98 69
99 70
100 const Object& UseVal::BoundConstant() const { 71 const Object& UseVal::BoundConstant() const {
101 ASSERT(BindsToConstant()); 72 ASSERT(BindsToConstant());
102 BindInstr* bind = definition()->AsBind(); 73 BindInstr* bind = definition()->AsBind();
103 ASSERT(bind != NULL); 74 ASSERT(bind != NULL);
104 MaterializeComp* constant = bind->computation()->AsMaterialize(); 75 ConstantComp* constant = bind->computation()->AsConstant();
105 ASSERT(constant != NULL); 76 ASSERT(constant != NULL);
106 return constant->constant_val()->value(); 77 return constant->value();
107 } 78 }
108 79
109 80
81 bool ConstantComp::AttributesEqual(Computation* other) const {
82 ConstantComp* other_constant = other->AsConstant();
83 return (other_constant != NULL) &&
84 (value().raw() == other_constant->value().raw());
85 }
86
87
88 bool CheckClassComp::AttributesEqual(Computation* other) const {
89 CheckClassComp* other_check = other->AsCheckClass();
90 if (other_check == NULL) return false;
91 if (ic_data()->NumberOfChecks() != other->ic_data()->NumberOfChecks()) {
92 return false;
93 }
94 for (intptr_t i = 0; i < ic_data()->NumberOfChecks(); ++i) {
95 // TODO(fschneider): Make sure ic_data are sorted to hit more cases.
96 if (ic_data()->GetReceiverClassIdAt(i) !=
97 other->ic_data()->GetReceiverClassIdAt(i)) {
98 return false;
99 }
100 }
101 return true;
102 }
103
104
105 GraphEntryInstr::GraphEntryInstr(TargetEntryInstr* normal_entry)
106 : BlockEntryInstr(),
107 normal_entry_(normal_entry),
108 catch_entries_(),
109 start_env_(NULL),
110 constant_null_(new BindInstr(BindInstr::kUsed,
Florian Schneider 2012/08/29 11:07:48 Maybe break after the first '(' here helps?
111 new ConstantComp(Object::ZoneHandle()))),
112 spill_slot_count_(0) {
113 }
114
115
110 MethodRecognizer::Kind MethodRecognizer::RecognizeKind( 116 MethodRecognizer::Kind MethodRecognizer::RecognizeKind(
111 const Function& function) { 117 const Function& function) {
112 // Only core and math library methods can be recognized. 118 // Only core and math library methods can be recognized.
113 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 119 const Library& core_lib = Library::Handle(Library::CoreLibrary());
114 const Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary()); 120 const Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary());
115 const Library& math_lib = Library::Handle(Library::MathLibrary()); 121 const Library& math_lib = Library::Handle(Library::MathLibrary());
116 const Class& function_class = Class::Handle(function.Owner()); 122 const Class& function_class = Class::Handle(function.Owner());
117 if ((function_class.library() != core_lib.raw()) && 123 if ((function_class.library() != core_lib.raw()) &&
118 (function_class.library() != core_impl_lib.raw()) && 124 (function_class.library() != core_impl_lib.raw()) &&
119 (function_class.library() != math_lib.raw())) { 125 (function_class.library() != math_lib.raw())) {
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 UseVal* current = env_use_list_; 412 UseVal* current = env_use_list_;
407 env_use_list_ = env_use_list_->next_use(); 413 env_use_list_ = env_use_list_->next_use();
408 current->set_definition(other); 414 current->set_definition(other);
409 current->AddToEnvUseList(); 415 current->AddToEnvUseList();
410 } 416 }
411 } 417 }
412 418
413 419
414 void Definition::ReplaceUsesWith(Value* value) { 420 void Definition::ReplaceUsesWith(Value* value) {
415 ASSERT(value != NULL); 421 ASSERT(value != NULL);
416 if (value->IsUse()) { 422 ASSERT(value->IsUse());
417 ReplaceUsesWith(value->AsUse()->definition()); 423 ReplaceUsesWith(value->AsUse()->definition());
418 return; 424 return;
Florian Schneider 2012/08/29 11:07:48 No need for a return here.
Kevin Millikin (Google) 2012/08/29 12:43:44 Actually, this whole function seems kind of pointl
419 }
420 ASSERT(value->IsConstant());
421 while (input_use_list_ != NULL) {
422 Instruction* instr = input_use_list_->instruction();
423 instr->SetInputAt(input_use_list_->use_index(), value);
424 input_use_list_ = input_use_list_->next_use();
425 }
426 while (env_use_list_ != NULL) {
427 Environment* env = env_use_list_->instruction()->env();
428 ASSERT(env != NULL);
429 env->values()[env_use_list_->use_index()] = value;
430 env_use_list_ = env_use_list_->next_use();
431 }
432 } 425 }
433 426
434 427
435 bool Definition::SetPropagatedCid(intptr_t cid) { 428 bool Definition::SetPropagatedCid(intptr_t cid) {
436 if (cid == kIllegalCid) { 429 if (cid == kIllegalCid) {
437 return false; 430 return false;
438 } 431 }
439 if (propagated_cid_ == kIllegalCid) { 432 if (propagated_cid_ == kIllegalCid) {
440 // First setting, nothing has changed. 433 // First setting, nothing has changed.
441 propagated_cid_ = cid; 434 propagated_cid_ = cid;
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 ASSERT(index == 0); 674 ASSERT(index == 0);
682 return successor(); 675 return successor();
683 } 676 }
684 677
685 678
686 void Instruction::Goto(JoinEntryInstr* entry) { 679 void Instruction::Goto(JoinEntryInstr* entry) {
687 set_next(new GotoInstr(entry)); 680 set_next(new GotoInstr(entry));
688 } 681 }
689 682
690 683
691 RawAbstractType* ConstantVal::CompileType() const {
692 if (value().IsNull()) {
693 return Type::NullType();
694 }
695 if (value().IsInstance()) {
696 return Instance::Cast(value()).GetType();
697 } else {
698 ASSERT(value().IsAbstractTypeArguments());
699 return AbstractType::null();
700 }
701 }
702
703
704 intptr_t ConstantVal::ResultCid() const {
705 if (value().IsNull()) {
706 return kNullCid;
707 }
708 if (value().IsInstance()) {
709 return Class::Handle(value().clazz()).id();
710 } else {
711 ASSERT(value().IsAbstractTypeArguments());
712 return kDynamicCid;
713 }
714 }
715
716
717 RawAbstractType* UseVal::CompileType() const { 684 RawAbstractType* UseVal::CompileType() const {
718 if (definition()->HasPropagatedType()) { 685 if (definition()->HasPropagatedType()) {
719 return definition()->PropagatedType(); 686 return definition()->PropagatedType();
720 } 687 }
721 // The compile type may be requested when building the flow graph, i.e. before 688 // The compile type may be requested when building the flow graph, i.e. before
722 // type propagation has occurred. To avoid repeatedly computing the compile 689 // type propagation has occurred. To avoid repeatedly computing the compile
723 // type of the definition, we store it as initial propagated type. 690 // type of the definition, we store it as initial propagated type.
724 AbstractType& type = AbstractType::Handle(definition()->CompileType()); 691 AbstractType& type = AbstractType::Handle(definition()->CompileType());
725 definition()->SetPropagatedType(type); 692 definition()->SetPropagatedType(type);
726 return type.raw(); 693 return type.raw();
727 } 694 }
728 695
729 696
730 intptr_t UseVal::ResultCid() const { 697 intptr_t UseVal::ResultCid() const {
731 return definition()->GetPropagatedCid(); 698 return definition()->GetPropagatedCid();
732 } 699 }
733 700
734 701
735 702
736 RawAbstractType* MaterializeComp::CompileType() const { 703 RawAbstractType* ConstantComp::CompileType() const {
737 return constant_val()->CompileType(); 704 if (value().IsNull()) {
705 return Type::NullType();
706 }
707 if (value().IsInstance()) {
708 return Instance::Cast(value()).GetType();
709 } else {
710 ASSERT(value().IsAbstractTypeArguments());
711 return AbstractType::null();
712 }
738 } 713 }
739 714
740 715
741 intptr_t MaterializeComp::ResultCid() const { 716 intptr_t ConstantComp::ResultCid() const {
742 return constant_val()->ResultCid(); 717 if (value().IsNull()) {
718 return kNullCid;
719 }
720 if (value().IsInstance()) {
721 return Class::Handle(value().clazz()).id();
722 } else {
723 ASSERT(value().IsAbstractTypeArguments());
724 return kDynamicCid;
725 }
743 } 726 }
744 727
745 728
746 RawAbstractType* AssertAssignableComp::CompileType() const { 729 RawAbstractType* AssertAssignableComp::CompileType() const {
747 const AbstractType& value_compile_type = 730 const AbstractType& value_compile_type =
748 AbstractType::Handle(value()->CompileType()); 731 AbstractType::Handle(value()->CompileType());
749 if (!value_compile_type.IsNull() && 732 if (!value_compile_type.IsNull() &&
750 value_compile_type.IsMoreSpecificThan(dst_type(), NULL)) { 733 value_compile_type.IsMoreSpecificThan(dst_type(), NULL)) {
751 return value_compile_type.raw(); 734 return value_compile_type.raw();
752 } 735 }
(...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after
1502 // In SSA mode, we need an explicit push. Nothing to do in non-SSA mode 1485 // In SSA mode, we need an explicit push. Nothing to do in non-SSA mode
1503 // where PushArgument is handled by BindInstr::EmitNativeCode. 1486 // where PushArgument is handled by BindInstr::EmitNativeCode.
1504 // TODO(fschneider): Avoid special-casing for SSA mode here. 1487 // TODO(fschneider): Avoid special-casing for SSA mode here.
1505 if (compiler->is_optimizing()) { 1488 if (compiler->is_optimizing()) {
1506 ASSERT(locs()->in(0).IsRegister()); 1489 ASSERT(locs()->in(0).IsRegister());
1507 __ PushRegister(locs()->in(0).reg()); 1490 __ PushRegister(locs()->in(0).reg());
1508 } 1491 }
1509 } 1492 }
1510 1493
1511 1494
1512 // Helper to either use the constant value of a definition or the definition.
1513 static Value* UseDefinition(Definition* defn) {
1514 if (defn->IsBind() && defn->AsBind()->computation()->IsMaterialize()) {
1515 return defn->AsBind()->computation()->AsMaterialize()->constant_val();
1516 } else {
1517 return new UseVal(defn);
1518 }
1519 }
1520
1521
1522 Environment::Environment(const GrowableArray<Definition*>& definitions, 1495 Environment::Environment(const GrowableArray<Definition*>& definitions,
1523 intptr_t fixed_parameter_count) 1496 intptr_t fixed_parameter_count)
1524 : values_(definitions.length()), 1497 : values_(definitions.length()),
1525 locations_(NULL), 1498 locations_(NULL),
1526 fixed_parameter_count_(fixed_parameter_count) { 1499 fixed_parameter_count_(fixed_parameter_count) {
1527 for (intptr_t i = 0; i < definitions.length(); ++i) { 1500 for (intptr_t i = 0; i < definitions.length(); ++i) {
1528 values_.Add(UseDefinition(definitions[i])); 1501 values_.Add(new UseVal(definitions[i]));
1529 } 1502 }
1530 } 1503 }
1531 1504
1532 1505
1533 Environment* Environment::Copy() const { 1506 Environment* Environment::Copy() const {
1534 Environment* copy = new Environment(values().length(), 1507 Environment* copy = new Environment(values().length(),
1535 fixed_parameter_count()); 1508 fixed_parameter_count());
1536 GrowableArray<Value*>* values_copy = copy->values_ptr(); 1509 GrowableArray<Value*>* values_copy = copy->values_ptr();
1537 for (intptr_t i = 0; i < values().length(); ++i) { 1510 for (intptr_t i = 0; i < values().length(); ++i) {
1538 values_copy->Add(values()[i]->CopyValue()); 1511 values_copy->Add(values()[i]->CopyValue());
1539 } 1512 }
1540 return copy; 1513 return copy;
1541 } 1514 }
1542 1515
1543 1516
1544 #undef __ 1517 #undef __
1545 1518
1546 } // namespace dart 1519 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698