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/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/cha.h" | 8 #include "vm/cha.h" |
| 9 #include "vm/flow_graph_builder.h" | 9 #include "vm/flow_graph_builder.h" |
| 10 #include "vm/flow_graph_compiler.h" | 10 #include "vm/flow_graph_compiler.h" |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 141 | 141 |
| 142 void FlowGraphOptimizer::SelectRepresentations() { | 142 void FlowGraphOptimizer::SelectRepresentations() { |
| 143 // Convervatively unbox all phis that were proven to be of type Double. | 143 // Convervatively unbox all phis that were proven to be of type Double. |
| 144 for (intptr_t i = 0; i < block_order_.length(); ++i) { | 144 for (intptr_t i = 0; i < block_order_.length(); ++i) { |
| 145 JoinEntryInstr* join_entry = block_order_[i]->AsJoinEntry(); | 145 JoinEntryInstr* join_entry = block_order_[i]->AsJoinEntry(); |
| 146 if (join_entry == NULL) continue; | 146 if (join_entry == NULL) continue; |
| 147 | 147 |
| 148 if (join_entry->phis() != NULL) { | 148 if (join_entry->phis() != NULL) { |
| 149 for (intptr_t i = 0; i < join_entry->phis()->length(); ++i) { | 149 for (intptr_t i = 0; i < join_entry->phis()->length(); ++i) { |
| 150 PhiInstr* phi = (*join_entry->phis())[i]; | 150 PhiInstr* phi = (*join_entry->phis())[i]; |
| 151 if ((phi != NULL) && (phi->GetPropagatedCid() == kDoubleCid)) { | 151 if (phi == NULL) continue; |
| 152 if (phi->GetPropagatedCid() == kDoubleCid) { | |
| 152 phi->set_representation(kUnboxedDouble); | 153 phi->set_representation(kUnboxedDouble); |
| 153 } | 154 } |
| 154 } | 155 } |
| 155 } | 156 } |
| 156 } | 157 } |
| 157 | 158 |
| 158 // Process all instructions and insert conversions where needed. | 159 // Process all instructions and insert conversions where needed. |
| 159 GraphEntryInstr* graph_entry = block_order_[0]->AsGraphEntry(); | 160 GraphEntryInstr* graph_entry = block_order_[0]->AsGraphEntry(); |
| 160 | 161 |
| 161 // Visit incoming parameters and constants. | 162 // Visit incoming parameters and constants. |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 513 case Token::kBIT_XOR: | 514 case Token::kBIT_XOR: |
| 514 if (HasOnlyTwoSmi(ic_data)) { | 515 if (HasOnlyTwoSmi(ic_data)) { |
| 515 operands_type = kSmiCid; | 516 operands_type = kSmiCid; |
| 516 } else if (HasTwoMintOrSmi(ic_data) && | 517 } else if (HasTwoMintOrSmi(ic_data) && |
| 517 FlowGraphCompiler::SupportsUnboxedMints()) { | 518 FlowGraphCompiler::SupportsUnboxedMints()) { |
| 518 operands_type = kMintCid; | 519 operands_type = kMintCid; |
| 519 } else { | 520 } else { |
| 520 return false; | 521 return false; |
| 521 } | 522 } |
| 522 break; | 523 break; |
| 524 case Token::kSHR: | |
| 525 if (HasOnlyTwoSmi(ic_data)) { | |
|
Kevin Millikin (Google)
2012/10/05 12:52:58
Should really be ...TwoSmis.
Florian Schneider
2012/10/05 14:40:31
Done.
| |
| 526 operands_type = kSmiCid; | |
| 527 } else if (HasTwoMintOrSmi(ic_data) && | |
| 528 FlowGraphCompiler::SupportsUnboxedMints()) { | |
| 529 operands_type = kMintCid; | |
| 530 } else { | |
| 531 return false; | |
| 532 } | |
| 533 break; | |
| 523 case Token::kTRUNCDIV: | 534 case Token::kTRUNCDIV: |
| 524 case Token::kSHR: | |
| 525 case Token::kSHL: | 535 case Token::kSHL: |
| 526 if (HasOnlyTwoSmi(ic_data)) { | 536 if (HasOnlyTwoSmi(ic_data)) { |
| 527 operands_type = kSmiCid; | 537 operands_type = kSmiCid; |
| 528 } else { | 538 } else { |
| 529 return false; | 539 return false; |
| 530 } | 540 } |
| 531 break; | 541 break; |
| 532 default: | 542 default: |
| 533 UNREACHABLE(); | 543 UNREACHABLE(); |
| 534 }; | 544 }; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 547 call->env(), | 557 call->env(), |
| 548 Definition::kEffect); | 558 Definition::kEffect); |
| 549 | 559 |
| 550 BinaryDoubleOpInstr* double_bin_op = | 560 BinaryDoubleOpInstr* double_bin_op = |
| 551 new BinaryDoubleOpInstr(op_kind, left->Copy(), right->Copy(), call); | 561 new BinaryDoubleOpInstr(op_kind, left->Copy(), right->Copy(), call); |
| 552 call->ReplaceWith(double_bin_op, current_iterator()); | 562 call->ReplaceWith(double_bin_op, current_iterator()); |
| 553 RemovePushArguments(call); | 563 RemovePushArguments(call); |
| 554 } else if (operands_type == kMintCid) { | 564 } else if (operands_type == kMintCid) { |
| 555 Value* left = call->ArgumentAt(0)->value(); | 565 Value* left = call->ArgumentAt(0)->value(); |
| 556 Value* right = call->ArgumentAt(1)->value(); | 566 Value* right = call->ArgumentAt(1)->value(); |
| 557 BinaryMintOpInstr* bin_op = | 567 if (op_kind == Token::kSHR) { |
| 558 new BinaryMintOpInstr(op_kind, left, right, call); | 568 ShiftMintOpInstr* shift_op = |
| 559 call->ReplaceWith(bin_op, current_iterator()); | 569 new ShiftMintOpInstr(op_kind, left, right, call); |
| 570 call->ReplaceWith(shift_op, current_iterator()); | |
| 571 } else { | |
| 572 BinaryMintOpInstr* bin_op = | |
| 573 new BinaryMintOpInstr(op_kind, left, right, call); | |
| 574 call->ReplaceWith(bin_op, current_iterator()); | |
| 575 } | |
| 560 RemovePushArguments(call); | 576 RemovePushArguments(call); |
| 561 } else if (op_kind == Token::kMOD) { | 577 } else if (op_kind == Token::kMOD) { |
| 562 // TODO(vegorov): implement fast path code for modulo. | 578 // TODO(vegorov): implement fast path code for modulo. |
| 563 ASSERT(operands_type == kSmiCid); | 579 ASSERT(operands_type == kSmiCid); |
| 564 if (!call->ArgumentAt(1)->value()->BindsToConstant()) return false; | 580 if (!call->ArgumentAt(1)->value()->BindsToConstant()) return false; |
| 565 const Object& obj = call->ArgumentAt(1)->value()->BoundConstant(); | 581 const Object& obj = call->ArgumentAt(1)->value()->BoundConstant(); |
| 566 if (!obj.IsSmi()) return false; | 582 if (!obj.IsSmi()) return false; |
| 567 const intptr_t value = Smi::Cast(obj).Value(); | 583 const intptr_t value = Smi::Cast(obj).Value(); |
| 568 if ((value > 0) && Utils::IsPowerOfTwo(value)) { | 584 if ((value > 0) && Utils::IsPowerOfTwo(value)) { |
| 569 Value* left = call->ArgumentAt(0)->value(); | 585 Value* left = call->ArgumentAt(0)->value(); |
| (...skipping 2406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2976 } | 2992 } |
| 2977 | 2993 |
| 2978 | 2994 |
| 2979 void ConstantPropagator::VisitBinaryMintOp( | 2995 void ConstantPropagator::VisitBinaryMintOp( |
| 2980 BinaryMintOpInstr* instr) { | 2996 BinaryMintOpInstr* instr) { |
| 2981 // TODO(kmillikin): Handle binary operations. | 2997 // TODO(kmillikin): Handle binary operations. |
| 2982 SetValue(instr, non_constant_); | 2998 SetValue(instr, non_constant_); |
| 2983 } | 2999 } |
| 2984 | 3000 |
| 2985 | 3001 |
| 3002 void ConstantPropagator::VisitShiftMintOp( | |
| 3003 ShiftMintOpInstr* instr) { | |
| 3004 // TODO(kmillikin): Handle shift operations. | |
| 3005 SetValue(instr, non_constant_); | |
| 3006 } | |
| 3007 | |
| 3008 | |
| 2986 void ConstantPropagator::VisitUnaryMintOp( | 3009 void ConstantPropagator::VisitUnaryMintOp( |
| 2987 UnaryMintOpInstr* instr) { | 3010 UnaryMintOpInstr* instr) { |
| 2988 // TODO(kmillikin): Handle unary operations. | 3011 // TODO(kmillikin): Handle unary operations. |
| 2989 SetValue(instr, non_constant_); | 3012 SetValue(instr, non_constant_); |
| 2990 } | 3013 } |
| 2991 | 3014 |
| 2992 | 3015 |
| 2993 void ConstantPropagator::VisitUnarySmiOp(UnarySmiOpInstr* instr) { | 3016 void ConstantPropagator::VisitUnarySmiOp(UnarySmiOpInstr* instr) { |
| 2994 const Object& value = instr->value()->definition()->constant_value(); | 3017 const Object& value = instr->value()->definition()->constant_value(); |
| 2995 if (IsNonConstant(value)) { | 3018 if (IsNonConstant(value)) { |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3226 | 3249 |
| 3227 if (FLAG_trace_constant_propagation) { | 3250 if (FLAG_trace_constant_propagation) { |
| 3228 OS::Print("\n==== After constant propagation ====\n"); | 3251 OS::Print("\n==== After constant propagation ====\n"); |
| 3229 FlowGraphPrinter printer(*graph_); | 3252 FlowGraphPrinter printer(*graph_); |
| 3230 printer.PrintBlocks(); | 3253 printer.PrintBlocks(); |
| 3231 } | 3254 } |
| 3232 } | 3255 } |
| 3233 | 3256 |
| 3234 | 3257 |
| 3235 } // namespace dart | 3258 } // namespace dart |
| OLD | NEW |