| 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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 } | 97 } |
| 98 return true; | 98 return true; |
| 99 } | 99 } |
| 100 | 100 |
| 101 | 101 |
| 102 static bool HasOneSmi(const ICData& ic_data) { | 102 static bool HasOneSmi(const ICData& ic_data) { |
| 103 return ICDataHasReceiverClassId(ic_data, kSmi); | 103 return ICDataHasReceiverClassId(ic_data, kSmi); |
| 104 } | 104 } |
| 105 | 105 |
| 106 | 106 |
| 107 static bool HasTwoSmi(const ICData& ic_data) { | 107 static bool HasOnlyTwoSmi(const ICData& ic_data) { |
| 108 return ICDataHasReceiverArgumentClassIds(ic_data, kSmi, kSmi); | 108 return (ic_data.NumberOfChecks() == 1) && |
| 109 ICDataHasReceiverArgumentClassIds(ic_data, kSmi, kSmi); |
| 109 } | 110 } |
| 110 | 111 |
| 111 | 112 |
| 112 // Returns false if the ICData contains anything other than the 4 combinations | 113 // Returns false if the ICData contains anything other than the 4 combinations |
| 113 // of Mint and Smi for the receiver and argument classes. | 114 // of Mint and Smi for the receiver and argument classes. |
| 114 static bool HasTwoMintOrSmi(const ICData& ic_data) { | 115 static bool HasTwoMintOrSmi(const ICData& ic_data) { |
| 115 GrowableArray<intptr_t> class_ids; | 116 GrowableArray<intptr_t> class_ids; |
| 116 class_ids.Add(kSmi); | 117 class_ids.Add(kSmi); |
| 117 class_ids.Add(kMint); | 118 class_ids.Add(kMint); |
| 118 return ICDataHasOnlyReceiverArgumentClassIds(ic_data, &class_ids, &class_ids); | 119 return ICDataHasOnlyReceiverArgumentClassIds(ic_data, &class_ids, &class_ids); |
| 119 } | 120 } |
| 120 | 121 |
| 121 | 122 |
| 122 static bool HasOneDouble(const ICData& ic_data) { | 123 static bool HasOneDouble(const ICData& ic_data) { |
| 123 return ICDataHasReceiverClassId(ic_data, kDouble); | 124 return ICDataHasReceiverClassId(ic_data, kDouble); |
| 124 } | 125 } |
| 125 | 126 |
| 126 | 127 |
| 127 static bool HasTwoDouble(const ICData& ic_data) { | 128 static bool HasOnlyTwoDouble(const ICData& ic_data) { |
| 128 return ICDataHasReceiverArgumentClassIds(ic_data, kDouble, kDouble); | 129 return (ic_data.NumberOfChecks() == 1) && |
| 130 ICDataHasReceiverArgumentClassIds(ic_data, kDouble, kDouble); |
| 129 } | 131 } |
| 130 | 132 |
| 131 | 133 |
| 132 bool FlowGraphOptimizer::TryReplaceWithBinaryOp(InstanceCallComp* comp, | 134 bool FlowGraphOptimizer::TryReplaceWithBinaryOp(InstanceCallComp* comp, |
| 133 Token::Kind op_kind) { | 135 Token::Kind op_kind) { |
| 134 BinaryOpComp::OperandsType operands_type; | 136 BinaryOpComp::OperandsType operands_type = BinaryOpComp::kDynamicOperands; |
| 135 if ((op_kind == Token::kBIT_AND) && HasTwoMintOrSmi(*comp->ic_data())) { | 137 ASSERT(comp->HasICData()); |
| 136 operands_type = BinaryOpComp::kMintOperands; | 138 const ICData& ic_data = *comp->ic_data(); |
| 137 } else if (comp->ic_data()->NumberOfChecks() != 1) { | 139 switch (op_kind) { |
| 138 // TODO(srdjan): Not yet supported. | 140 case Token::kADD: |
| 139 return false; | 141 case Token::kSUB: |
| 140 } else if (HasTwoSmi(*comp->ic_data())) { | 142 case Token::kMUL: |
| 141 if (op_kind == Token::kDIV || | 143 if (HasOnlyTwoSmi(ic_data)) { |
| 142 op_kind == Token::kMOD) { | 144 operands_type = BinaryOpComp::kSmiOperands; |
| 143 // TODO(srdjan): Not yet supported. | 145 } else if (HasOnlyTwoDouble(ic_data)) { |
| 144 return false; | 146 operands_type = BinaryOpComp::kDoubleOperands; |
| 145 } | 147 } else { |
| 146 operands_type = BinaryOpComp::kSmiOperands; | 148 return false; |
| 147 } else if (HasTwoDouble(*comp->ic_data())) { | 149 } |
| 148 if (op_kind != Token::kADD && | 150 break; |
| 149 op_kind != Token::kSUB && | 151 case Token::kDIV: |
| 150 op_kind != Token::kMUL && | 152 case Token::kMOD: |
| 151 op_kind != Token::kDIV) { | 153 if (HasOnlyTwoDouble(ic_data)) { |
| 152 // TODO(vegorov): Not yet supported. | 154 operands_type = BinaryOpComp::kDoubleOperands; |
| 153 return false; | 155 } else { |
| 154 } | 156 return false; |
| 155 operands_type = BinaryOpComp::kDoubleOperands; | 157 } |
| 156 } else { | 158 case Token::kBIT_AND: |
| 157 // TODO(srdjan): Not yet supported. | 159 if (HasOnlyTwoSmi(ic_data)) { |
| 158 return false; | 160 operands_type = BinaryOpComp::kSmiOperands; |
| 159 } | 161 } else if (HasTwoMintOrSmi(ic_data)) { |
| 162 operands_type = BinaryOpComp::kMintOperands; |
| 163 } else { |
| 164 return false; |
| 165 } |
| 166 break; |
| 167 case Token::kBIT_OR: |
| 168 case Token::kBIT_XOR: |
| 169 case Token::kTRUNCDIV: |
| 170 case Token::kSHR: |
| 171 case Token::kSHL: |
| 172 if (HasOnlyTwoSmi(ic_data)) { |
| 173 operands_type = BinaryOpComp::kSmiOperands; |
| 174 } else { |
| 175 return false; |
| 176 } |
| 177 break; |
| 178 default: |
| 179 UNREACHABLE(); |
| 180 }; |
| 160 | 181 |
| 161 ASSERT(comp->instr() != NULL); | 182 ASSERT(comp->instr() != NULL); |
| 162 ASSERT(comp->InputCount() == 2); | 183 ASSERT(comp->InputCount() == 2); |
| 163 Value* left = comp->InputAt(0); | 184 Value* left = comp->InputAt(0); |
| 164 Value* right = comp->InputAt(1); | 185 Value* right = comp->InputAt(1); |
| 165 BinaryOpComp* bin_op = | 186 BinaryOpComp* bin_op = |
| 166 new BinaryOpComp(op_kind, | 187 new BinaryOpComp(op_kind, |
| 167 operands_type, | 188 operands_type, |
| 168 comp, | 189 comp, |
| 169 left, | 190 left, |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 | 565 |
| 545 void FlowGraphOptimizer::VisitRelationalOp(RelationalOpComp* comp) { | 566 void FlowGraphOptimizer::VisitRelationalOp(RelationalOpComp* comp) { |
| 546 if (!comp->HasICData()) return; | 567 if (!comp->HasICData()) return; |
| 547 | 568 |
| 548 const ICData& ic_data = *comp->ic_data(); | 569 const ICData& ic_data = *comp->ic_data(); |
| 549 if (ic_data.NumberOfChecks() == 0) return; | 570 if (ic_data.NumberOfChecks() == 0) return; |
| 550 // TODO(srdjan): Add multiple receiver type support. | 571 // TODO(srdjan): Add multiple receiver type support. |
| 551 if (ic_data.NumberOfChecks() != 1) return; | 572 if (ic_data.NumberOfChecks() != 1) return; |
| 552 ASSERT(HasOneTarget(ic_data)); | 573 ASSERT(HasOneTarget(ic_data)); |
| 553 | 574 |
| 554 if (HasTwoSmi(ic_data)) { | 575 if (HasOnlyTwoSmi(ic_data)) { |
| 555 comp->set_operands_class_id(kSmi); | 576 comp->set_operands_class_id(kSmi); |
| 556 } else if (HasTwoDouble(ic_data)) { | 577 } else if (HasOnlyTwoDouble(ic_data)) { |
| 557 comp->set_operands_class_id(kDouble); | 578 comp->set_operands_class_id(kDouble); |
| 558 } else { | 579 } else { |
| 559 return; | 580 return; |
| 560 } | 581 } |
| 561 | 582 |
| 562 // For smi and double comparisons if the next instruction is a conditional | 583 // For smi and double comparisons if the next instruction is a conditional |
| 563 // branch that uses the value of this comparison mark them as fused together | 584 // branch that uses the value of this comparison mark them as fused together |
| 564 // to avoid materializing a boolean value. | 585 // to avoid materializing a boolean value. |
| 565 TryFuseComparisonWithBranch(comp); | 586 TryFuseComparisonWithBranch(comp); |
| 566 } | 587 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 587 instr->computation()->Accept(this); | 608 instr->computation()->Accept(this); |
| 588 } | 609 } |
| 589 | 610 |
| 590 | 611 |
| 591 void FlowGraphOptimizer::VisitBind(BindInstr* instr) { | 612 void FlowGraphOptimizer::VisitBind(BindInstr* instr) { |
| 592 instr->computation()->Accept(this); | 613 instr->computation()->Accept(this); |
| 593 } | 614 } |
| 594 | 615 |
| 595 | 616 |
| 596 } // namespace dart | 617 } // namespace dart |
| OLD | NEW |