Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/flow_graph_optimizer.h" | 5 #include "vm/flow_graph_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/flow_graph_builder.h" | 7 #include "vm/flow_graph_builder.h" |
| 8 #include "vm/il_printer.h" | 8 #include "vm/il_printer.h" |
| 9 #include "vm/object_store.h" | 9 #include "vm/object_store.h" |
| 10 | 10 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 43 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { | 43 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { |
| 44 ic_data.GetOneClassCheckAt(i, &test_class, &target); | 44 ic_data.GetOneClassCheckAt(i, &test_class, &target); |
| 45 if (cls.raw() == test_class.raw()) { | 45 if (cls.raw() == test_class.raw()) { |
| 46 return true; | 46 return true; |
| 47 } | 47 } |
| 48 } | 48 } |
| 49 return false; | 49 return false; |
| 50 } | 50 } |
| 51 | 51 |
| 52 | 52 |
| 53 static bool ICDataHasTwoReceiverClasses(const ICData& ic_data, | 53 static bool ICDataHasReceiverArgumentClasses(const ICData& ic_data, |
| 54 const Class& cls1, | 54 const Class& receiver_cls, |
| 55 const Class& cls2) { | 55 const Class& argument_cls) { |
| 56 ASSERT(!cls1.IsNull() && !cls2.IsNull()); | 56 ASSERT(!receiver_cls.IsNull() && !argument_cls.IsNull()); |
| 57 if (ic_data.num_args_tested() != 2) { | 57 if (ic_data.num_args_tested() != 2) { |
| 58 return false; | 58 return false; |
| 59 } | 59 } |
| 60 Function& target = Function::Handle(); | 60 Function& target = Function::Handle(); |
| 61 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { | 61 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { |
| 62 GrowableArray<const Class*> classes; | 62 GrowableArray<const Class*> classes; |
| 63 ic_data.GetCheckAt(i, &classes, &target); | 63 ic_data.GetCheckAt(i, &classes, &target); |
| 64 ASSERT(classes.length() == 2); | 64 ASSERT(classes.length() == 2); |
| 65 if (classes[0]->raw() == cls1.raw()) { | 65 if (classes[0]->raw() == receiver_cls.raw()) { |
| 66 if (classes[1]->raw() == cls2.raw()) { | 66 if (classes[1]->raw() == argument_cls.raw()) { |
| 67 return true; | 67 return true; |
| 68 } | 68 } |
| 69 } | 69 } |
| 70 } | 70 } |
| 71 return false; | 71 return false; |
| 72 } | 72 } |
| 73 | 73 |
| 74 | 74 |
| 75 static bool HasOneSmi(const ICData& ic_data) { | 75 static bool HasOneSmi(const ICData& ic_data) { |
| 76 const Class& smi_class = | 76 const Class& smi_class = |
| 77 Class::Handle(Isolate::Current()->object_store()->smi_class()); | 77 Class::Handle(Isolate::Current()->object_store()->smi_class()); |
| 78 return ICDataHasReceiverClass(ic_data, smi_class); | 78 return ICDataHasReceiverClass(ic_data, smi_class); |
| 79 } | 79 } |
| 80 | 80 |
| 81 | 81 |
| 82 static bool HasTwoSmi(const ICData& ic_data) { | 82 static bool HasTwoSmi(const ICData& ic_data) { |
| 83 const Class& smi_class = | 83 const Class& smi_class = |
| 84 Class::Handle(Isolate::Current()->object_store()->smi_class()); | 84 Class::Handle(Isolate::Current()->object_store()->smi_class()); |
| 85 return ICDataHasTwoReceiverClasses(ic_data, smi_class, smi_class); | 85 return ICDataHasReceiverArgumentClasses(ic_data, smi_class, smi_class); |
| 86 } | |
| 87 | |
| 88 | |
| 89 static bool HasMintSmi(const ICData& ic_data) { | |
| 90 const Class& mint_class = | |
| 91 Class::Handle(Isolate::Current()->object_store()->mint_class()); | |
| 92 const Class& smi_class = | |
| 93 Class::Handle(Isolate::Current()->object_store()->smi_class()); | |
| 94 return ICDataHasReceiverArgumentClasses(ic_data, mint_class, smi_class); | |
|
srdjan
2012/06/18 20:32:36
Maybe we should modify ICDataHasReceiverArgumentCl
regis
2012/06/18 21:55:25
Done.
| |
| 86 } | 95 } |
| 87 | 96 |
| 88 | 97 |
| 89 static bool HasOneDouble(const ICData& ic_data) { | 98 static bool HasOneDouble(const ICData& ic_data) { |
| 90 const Class& double_class = | 99 const Class& double_class = |
| 91 Class::Handle(Isolate::Current()->object_store()->double_class()); | 100 Class::Handle(Isolate::Current()->object_store()->double_class()); |
| 92 return ICDataHasReceiverClass(ic_data, double_class); | 101 return ICDataHasReceiverClass(ic_data, double_class); |
| 93 } | 102 } |
| 94 | 103 |
| 95 | 104 |
| 96 static bool HasTwoDouble(const ICData& ic_data) { | 105 static bool HasTwoDouble(const ICData& ic_data) { |
| 97 const Class& double_class = | 106 const Class& double_class = |
| 98 Class::Handle(Isolate::Current()->object_store()->double_class()); | 107 Class::Handle(Isolate::Current()->object_store()->double_class()); |
| 99 return ICDataHasTwoReceiverClasses(ic_data, double_class, double_class); | 108 return ICDataHasReceiverArgumentClasses(ic_data, double_class, double_class); |
| 100 } | 109 } |
| 101 | 110 |
| 102 | 111 |
| 103 bool FlowGraphOptimizer::TryReplaceWithBinaryOp(InstanceCallComp* comp, | 112 bool FlowGraphOptimizer::TryReplaceWithBinaryOp(InstanceCallComp* comp, |
| 104 Token::Kind op_kind) { | 113 Token::Kind op_kind) { |
| 114 BinaryOpComp::OperandsType operands_type; | |
| 115 | |
| 116 if (HasMintSmi(*comp->ic_data())) { | |
| 117 // We check for Mint receiver and Smi argument, but we try to support any | |
| 118 // combination of Mint and Smi. | |
| 119 if (op_kind != Token::kBIT_AND) { | |
| 120 // TODO(regis): Not yet supported. | |
| 121 return false; | |
| 122 } | |
| 123 | |
| 124 operands_type = BinaryOpComp::kMintOperands; | |
| 125 } | |
| 126 | |
| 105 if (comp->ic_data()->NumberOfChecks() != 1) { | 127 if (comp->ic_data()->NumberOfChecks() != 1) { |
| 106 // TODO(srdjan): Not yet supported. | 128 // TODO(srdjan): Not yet supported. |
| 107 return false; | 129 return false; |
| 108 } | 130 } |
| 109 | 131 |
| 110 BinaryOpComp::OperandsType operands_type; | |
| 111 | |
| 112 if (HasTwoSmi(*comp->ic_data())) { | 132 if (HasTwoSmi(*comp->ic_data())) { |
| 113 if (op_kind == Token::kDIV || | 133 if (op_kind == Token::kDIV || |
| 114 op_kind == Token::kMOD) { | 134 op_kind == Token::kMOD) { |
| 115 // TODO(srdjan): Not yet supported. | 135 // TODO(srdjan): Not yet supported. |
| 116 return false; | 136 return false; |
| 117 } | 137 } |
| 118 | 138 |
| 119 operands_type = BinaryOpComp::kSmiOperands; | 139 operands_type = BinaryOpComp::kSmiOperands; |
| 120 } else if (HasTwoDouble(*comp->ic_data())) { | 140 } else if (HasTwoDouble(*comp->ic_data())) { |
| 121 if (op_kind != Token::kADD && | 141 if (op_kind != Token::kADD && |
| (...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 585 instr->computation()->Accept(this); | 605 instr->computation()->Accept(this); |
| 586 } | 606 } |
| 587 | 607 |
| 588 | 608 |
| 589 void FlowGraphOptimizer::VisitBind(BindInstr* instr) { | 609 void FlowGraphOptimizer::VisitBind(BindInstr* instr) { |
| 590 instr->computation()->Accept(this); | 610 instr->computation()->Accept(this); |
| 591 } | 611 } |
| 592 | 612 |
| 593 | 613 |
| 594 } // namespace dart | 614 } // namespace dart |
| OLD | NEW |