| 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 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 538 | 538 |
| 539 // Check that either left or right are not a smi. Result or a | 539 // Check that either left or right are not a smi. Result or a |
| 540 // binary operation with two smis is a smi not a double. | 540 // binary operation with two smis is a smi not a double. |
| 541 InsertBefore(call, | 541 InsertBefore(call, |
| 542 new CheckEitherNonSmiInstr(left->Copy(), | 542 new CheckEitherNonSmiInstr(left->Copy(), |
| 543 right->Copy(), | 543 right->Copy(), |
| 544 call), | 544 call), |
| 545 call->env(), | 545 call->env(), |
| 546 Definition::kEffect); | 546 Definition::kEffect); |
| 547 | 547 |
| 548 UnboxedDoubleBinaryOpInstr* double_bin_op = | 548 BinaryDoubleOpInstr* double_bin_op = |
| 549 new UnboxedDoubleBinaryOpInstr(op_kind, | 549 new BinaryDoubleOpInstr(op_kind, left->Copy(), right->Copy(), call); |
| 550 left->Copy(), | |
| 551 right->Copy(), | |
| 552 call); | |
| 553 call->ReplaceWith(double_bin_op, current_iterator()); | 550 call->ReplaceWith(double_bin_op, current_iterator()); |
| 554 RemovePushArguments(call); | 551 RemovePushArguments(call); |
| 555 } else if (operands_type == kMintCid) { | 552 } else if (operands_type == kMintCid) { |
| 556 Value* left = call->ArgumentAt(0)->value(); | 553 Value* left = call->ArgumentAt(0)->value(); |
| 557 Value* right = call->ArgumentAt(1)->value(); | 554 Value* right = call->ArgumentAt(1)->value(); |
| 558 UnboxedMintBinaryOpInstr* bin_op = | 555 BinaryMintOpInstr* bin_op = |
| 559 new UnboxedMintBinaryOpInstr(op_kind, left, right, call); | 556 new BinaryMintOpInstr(op_kind, left, right, call); |
| 560 call->ReplaceWith(bin_op, current_iterator()); | 557 call->ReplaceWith(bin_op, current_iterator()); |
| 561 RemovePushArguments(call); | 558 RemovePushArguments(call); |
| 562 } else if (op_kind == Token::kMOD) { | 559 } else if (op_kind == Token::kMOD) { |
| 563 // TODO(vegorov): implement fast path code for modulo. | 560 // TODO(vegorov): implement fast path code for modulo. |
| 564 ASSERT(operands_type == kSmiCid); | 561 ASSERT(operands_type == kSmiCid); |
| 565 if (!call->ArgumentAt(1)->value()->BindsToConstant()) return false; | 562 if (!call->ArgumentAt(1)->value()->BindsToConstant()) return false; |
| 566 const Object& obj = call->ArgumentAt(1)->value()->BoundConstant(); | 563 const Object& obj = call->ArgumentAt(1)->value()->BoundConstant(); |
| 567 if (!obj.IsSmi()) return false; | 564 if (!obj.IsSmi()) return false; |
| 568 const intptr_t value = Smi::Cast(obj).Value(); | 565 const intptr_t value = Smi::Cast(obj).Value(); |
| 569 if ((value > 0) && Utils::IsPowerOfTwo(value)) { | 566 if ((value > 0) && Utils::IsPowerOfTwo(value)) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 new CheckSmiInstr(value->Copy(), call->deopt_id()), | 610 new CheckSmiInstr(value->Copy(), call->deopt_id()), |
| 614 call->env(), | 611 call->env(), |
| 615 Definition::kEffect); | 612 Definition::kEffect); |
| 616 unary_op = new UnarySmiOpInstr(op_kind, | 613 unary_op = new UnarySmiOpInstr(op_kind, |
| 617 (op_kind == Token::kNEGATE) ? call : NULL, | 614 (op_kind == Token::kNEGATE) ? call : NULL, |
| 618 value); | 615 value); |
| 619 } else if ((op_kind == Token::kBIT_NOT) && | 616 } else if ((op_kind == Token::kBIT_NOT) && |
| 620 HasOnlySmiOrMint(*call->ic_data()) && | 617 HasOnlySmiOrMint(*call->ic_data()) && |
| 621 FlowGraphCompiler::SupportsUnboxedMints()) { | 618 FlowGraphCompiler::SupportsUnboxedMints()) { |
| 622 Value* value = call->ArgumentAt(0)->value(); | 619 Value* value = call->ArgumentAt(0)->value(); |
| 623 unary_op = new UnboxedMintUnaryOpInstr(op_kind, value, call); | 620 unary_op = new UnaryMintOpInstr(op_kind, value, call); |
| 624 } else if (HasOnlyOneDouble(*call->ic_data()) && | 621 } else if (HasOnlyOneDouble(*call->ic_data()) && |
| 625 (op_kind == Token::kNEGATE)) { | 622 (op_kind == Token::kNEGATE)) { |
| 626 Value* value = call->ArgumentAt(0)->value(); | 623 Value* value = call->ArgumentAt(0)->value(); |
| 627 AddCheckClass(call, value->Copy()); | 624 AddCheckClass(call, value->Copy()); |
| 628 ConstantInstr* minus_one = | 625 ConstantInstr* minus_one = |
| 629 new ConstantInstr(Double::ZoneHandle(Double::NewCanonical(-1))); | 626 new ConstantInstr(Double::ZoneHandle(Double::NewCanonical(-1))); |
| 630 InsertBefore(call, minus_one, NULL, Definition::kValue); | 627 InsertBefore(call, minus_one, NULL, Definition::kValue); |
| 631 unary_op = new UnboxedDoubleBinaryOpInstr(Token::kMUL, | 628 unary_op = new BinaryDoubleOpInstr(Token::kMUL, |
| 632 value, | 629 value, |
| 633 new Value(minus_one), | 630 new Value(minus_one), |
| 634 call); | 631 call); |
| 635 } | 632 } |
| 636 if (unary_op == NULL) return false; | 633 if (unary_op == NULL) return false; |
| 637 | 634 |
| 638 call->ReplaceWith(unary_op, current_iterator()); | 635 call->ReplaceWith(unary_op, current_iterator()); |
| 639 RemovePushArguments(call); | 636 RemovePushArguments(call); |
| 640 return true; | 637 return true; |
| 641 } | 638 } |
| 642 | 639 |
| 643 | 640 |
| 644 // Using field class | 641 // Using field class |
| (...skipping 2269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2914 SetValue(instr, non_constant_); | 2911 SetValue(instr, non_constant_); |
| 2915 } | 2912 } |
| 2916 | 2913 |
| 2917 | 2914 |
| 2918 void ConstantPropagator::VisitUnboxInteger(UnboxIntegerInstr* instr) { | 2915 void ConstantPropagator::VisitUnboxInteger(UnboxIntegerInstr* instr) { |
| 2919 // TODO(kmillikin): Handle unbox operation. | 2916 // TODO(kmillikin): Handle unbox operation. |
| 2920 SetValue(instr, non_constant_); | 2917 SetValue(instr, non_constant_); |
| 2921 } | 2918 } |
| 2922 | 2919 |
| 2923 | 2920 |
| 2924 void ConstantPropagator::VisitUnboxedMintBinaryOp( | 2921 void ConstantPropagator::VisitBinaryMintOp( |
| 2925 UnboxedMintBinaryOpInstr* instr) { | 2922 BinaryMintOpInstr* instr) { |
| 2926 // TODO(kmillikin): Handle binary operations. | 2923 // TODO(kmillikin): Handle binary operations. |
| 2927 SetValue(instr, non_constant_); | 2924 SetValue(instr, non_constant_); |
| 2928 } | 2925 } |
| 2929 | 2926 |
| 2930 | 2927 |
| 2931 void ConstantPropagator::VisitUnboxedMintUnaryOp( | 2928 void ConstantPropagator::VisitUnaryMintOp( |
| 2932 UnboxedMintUnaryOpInstr* instr) { | 2929 UnaryMintOpInstr* instr) { |
| 2933 // TODO(kmillikin): Handle unary operations. | 2930 // TODO(kmillikin): Handle unary operations. |
| 2934 SetValue(instr, non_constant_); | 2931 SetValue(instr, non_constant_); |
| 2935 } | 2932 } |
| 2936 | 2933 |
| 2937 | 2934 |
| 2938 void ConstantPropagator::VisitUnarySmiOp(UnarySmiOpInstr* instr) { | 2935 void ConstantPropagator::VisitUnarySmiOp(UnarySmiOpInstr* instr) { |
| 2939 const Object& value = instr->value()->definition()->constant_value(); | 2936 const Object& value = instr->value()->definition()->constant_value(); |
| 2940 if (IsNonConstant(value)) { | 2937 if (IsNonConstant(value)) { |
| 2941 SetValue(instr, non_constant_); | 2938 SetValue(instr, non_constant_); |
| 2942 } else if (IsConstant(value)) { | 2939 } else if (IsConstant(value)) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2967 SetValue(instr, instr->value()); | 2964 SetValue(instr, instr->value()); |
| 2968 } | 2965 } |
| 2969 | 2966 |
| 2970 | 2967 |
| 2971 void ConstantPropagator::VisitConstraint(ConstraintInstr* instr) { | 2968 void ConstantPropagator::VisitConstraint(ConstraintInstr* instr) { |
| 2972 // Should not be used outside of range analysis. | 2969 // Should not be used outside of range analysis. |
| 2973 UNREACHABLE(); | 2970 UNREACHABLE(); |
| 2974 } | 2971 } |
| 2975 | 2972 |
| 2976 | 2973 |
| 2977 void ConstantPropagator::VisitUnboxedDoubleBinaryOp( | 2974 void ConstantPropagator::VisitBinaryDoubleOp( |
| 2978 UnboxedDoubleBinaryOpInstr* instr) { | 2975 BinaryDoubleOpInstr* instr) { |
| 2979 const Object& left = instr->left()->definition()->constant_value(); | 2976 const Object& left = instr->left()->definition()->constant_value(); |
| 2980 const Object& right = instr->right()->definition()->constant_value(); | 2977 const Object& right = instr->right()->definition()->constant_value(); |
| 2981 if (IsNonConstant(left) || IsNonConstant(right)) { | 2978 if (IsNonConstant(left) || IsNonConstant(right)) { |
| 2982 SetValue(instr, non_constant_); | 2979 SetValue(instr, non_constant_); |
| 2983 } else if (IsConstant(left) && IsConstant(right)) { | 2980 } else if (IsConstant(left) && IsConstant(right)) { |
| 2984 // TODO(kmillikin): Handle binary operation. | 2981 // TODO(kmillikin): Handle binary operation. |
| 2985 SetValue(instr, non_constant_); | 2982 SetValue(instr, non_constant_); |
| 2986 } | 2983 } |
| 2987 } | 2984 } |
| 2988 | 2985 |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3171 | 3168 |
| 3172 if (FLAG_trace_constant_propagation) { | 3169 if (FLAG_trace_constant_propagation) { |
| 3173 OS::Print("\n==== After constant propagation ====\n"); | 3170 OS::Print("\n==== After constant propagation ====\n"); |
| 3174 FlowGraphPrinter printer(*graph_); | 3171 FlowGraphPrinter printer(*graph_); |
| 3175 printer.PrintBlocks(); | 3172 printer.PrintBlocks(); |
| 3176 } | 3173 } |
| 3177 } | 3174 } |
| 3178 | 3175 |
| 3179 | 3176 |
| 3180 } // namespace dart | 3177 } // namespace dart |
| OLD | NEW |