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 3780 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3791 SetValue(instr, non_constant_); | 3791 SetValue(instr, non_constant_); |
| 3792 } | 3792 } |
| 3793 } else if (IsConstant(left) && IsConstant(right)) { | 3793 } else if (IsConstant(left) && IsConstant(right)) { |
| 3794 bool result = (left.raw() == right.raw()); | 3794 bool result = (left.raw() == right.raw()); |
| 3795 if (instr->kind() == Token::kNE_STRICT) result = !result; | 3795 if (instr->kind() == Token::kNE_STRICT) result = !result; |
| 3796 SetValue(instr, Bool::ZoneHandle(Bool::Get(result))); | 3796 SetValue(instr, Bool::ZoneHandle(Bool::Get(result))); |
| 3797 } | 3797 } |
| 3798 } | 3798 } |
| 3799 | 3799 |
| 3800 | 3800 |
| 3801 static bool CompareIntegers(Token::Kind kind, | |
| 3802 const Integer& left, | |
| 3803 const Integer& right) { | |
| 3804 const int result = Integer::Cast(left).CompareWith(right); | |
|
Florian Schneider
2012/12/19 15:07:27
Redundant Integer::Cast
| |
| 3805 switch (kind) { | |
| 3806 case Token::kEQ: return (result == 0); | |
| 3807 case Token::kNE: return (result != 0); | |
| 3808 case Token::kLT: return (result < 0); | |
| 3809 case Token::kGT: return (result > 0); | |
| 3810 case Token::kLTE: return (result <= 0); | |
| 3811 case Token::kGTE: return (result >= 0); | |
| 3812 default: | |
| 3813 UNREACHABLE(); | |
| 3814 return false; | |
| 3815 } | |
| 3816 } | |
| 3817 | |
| 3818 | |
| 3801 void ConstantPropagator::VisitEqualityCompare(EqualityCompareInstr* instr) { | 3819 void ConstantPropagator::VisitEqualityCompare(EqualityCompareInstr* instr) { |
| 3802 const Object& left = instr->left()->definition()->constant_value(); | 3820 const Object& left = instr->left()->definition()->constant_value(); |
| 3803 const Object& right = instr->right()->definition()->constant_value(); | 3821 const Object& right = instr->right()->definition()->constant_value(); |
| 3804 if (IsNonConstant(left) || IsNonConstant(right)) { | 3822 if (IsNonConstant(left) || IsNonConstant(right)) { |
| 3805 SetValue(instr, non_constant_); | 3823 SetValue(instr, non_constant_); |
| 3806 } else if (IsConstant(left) && IsConstant(right)) { | 3824 } else if (IsConstant(left) && IsConstant(right)) { |
| 3807 // TODO(kmillikin): Handle equality comparison of constants. | 3825 if (left.IsInteger() && right.IsInteger()) { |
| 3808 SetValue(instr, non_constant_); | 3826 const bool result = CompareIntegers(instr->kind(), |
| 3827 Integer::Cast(left), | |
| 3828 Integer::Cast(right)); | |
| 3829 SetValue(instr, Bool::ZoneHandle(Bool::Get(result))); | |
| 3830 } else { | |
| 3831 SetValue(instr, non_constant_); | |
| 3832 } | |
| 3809 } | 3833 } |
| 3810 } | 3834 } |
| 3811 | 3835 |
| 3812 | 3836 |
| 3813 void ConstantPropagator::VisitRelationalOp(RelationalOpInstr* instr) { | 3837 void ConstantPropagator::VisitRelationalOp(RelationalOpInstr* instr) { |
| 3814 const Object& left = instr->left()->definition()->constant_value(); | 3838 const Object& left = instr->left()->definition()->constant_value(); |
| 3815 const Object& right = instr->right()->definition()->constant_value(); | 3839 const Object& right = instr->right()->definition()->constant_value(); |
| 3816 if (IsNonConstant(left) || IsNonConstant(right)) { | 3840 if (IsNonConstant(left) || IsNonConstant(right)) { |
| 3817 SetValue(instr, non_constant_); | 3841 SetValue(instr, non_constant_); |
| 3818 } else if (IsConstant(left) && IsConstant(right)) { | 3842 } else if (IsConstant(left) && IsConstant(right)) { |
| 3819 // TODO(kmillikin): Handle relational comparison of constants. | 3843 if (left.IsInteger() && right.IsInteger()) { |
| 3820 SetValue(instr, non_constant_); | 3844 const bool result = CompareIntegers(instr->kind(), |
| 3845 Integer::Cast(left), | |
| 3846 Integer::Cast(right)); | |
| 3847 SetValue(instr, Bool::ZoneHandle(Bool::Get(result))); | |
| 3848 } else { | |
| 3849 SetValue(instr, non_constant_); | |
| 3850 } | |
| 3821 } | 3851 } |
| 3822 } | 3852 } |
| 3823 | 3853 |
| 3824 | 3854 |
| 3825 void ConstantPropagator::VisitNativeCall(NativeCallInstr* instr) { | 3855 void ConstantPropagator::VisitNativeCall(NativeCallInstr* instr) { |
| 3826 SetValue(instr, non_constant_); | 3856 SetValue(instr, non_constant_); |
| 3827 } | 3857 } |
| 3828 | 3858 |
| 3829 | 3859 |
| 3830 void ConstantPropagator::VisitStringCharCodeAt(StringCharCodeAtInstr* instr) { | 3860 void ConstantPropagator::VisitStringCharCodeAt(StringCharCodeAtInstr* instr) { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3901 } | 3931 } |
| 3902 | 3932 |
| 3903 | 3933 |
| 3904 void ConstantPropagator::VisitAllocateObjectWithBoundsCheck( | 3934 void ConstantPropagator::VisitAllocateObjectWithBoundsCheck( |
| 3905 AllocateObjectWithBoundsCheckInstr* instr) { | 3935 AllocateObjectWithBoundsCheckInstr* instr) { |
| 3906 SetValue(instr, non_constant_); | 3936 SetValue(instr, non_constant_); |
| 3907 } | 3937 } |
| 3908 | 3938 |
| 3909 | 3939 |
| 3910 void ConstantPropagator::VisitLoadField(LoadFieldInstr* instr) { | 3940 void ConstantPropagator::VisitLoadField(LoadFieldInstr* instr) { |
| 3911 SetValue(instr, non_constant_); | 3941 if ((instr->recognized_kind() == MethodRecognizer::kObjectArrayLength) && |
| 3942 (instr->value()->definition()->IsCreateArray())) { | |
| 3943 const intptr_t length = | |
| 3944 instr->value()->definition()->AsCreateArray()->ArgumentCount(); | |
| 3945 const Object& result = Smi::ZoneHandle(Smi::New(length)); | |
| 3946 SetValue(instr, result); | |
| 3947 } else { | |
| 3948 SetValue(instr, non_constant_); | |
| 3949 } | |
| 3912 } | 3950 } |
| 3913 | 3951 |
| 3914 | 3952 |
| 3915 void ConstantPropagator::VisitStoreVMField(StoreVMFieldInstr* instr) { | 3953 void ConstantPropagator::VisitStoreVMField(StoreVMFieldInstr* instr) { |
| 3916 SetValue(instr, instr->value()->definition()->constant_value()); | 3954 SetValue(instr, instr->value()->definition()->constant_value()); |
| 3917 } | 3955 } |
| 3918 | 3956 |
| 3919 | 3957 |
| 3920 void ConstantPropagator::VisitInstantiateTypeArguments( | 3958 void ConstantPropagator::VisitInstantiateTypeArguments( |
| 3921 InstantiateTypeArgumentsInstr* instr) { | 3959 InstantiateTypeArgumentsInstr* instr) { |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4242 // Replace branches where one target is unreachable with jumps. | 4280 // Replace branches where one target is unreachable with jumps. |
| 4243 BranchInstr* branch = block->last_instruction()->AsBranch(); | 4281 BranchInstr* branch = block->last_instruction()->AsBranch(); |
| 4244 if (branch != NULL) { | 4282 if (branch != NULL) { |
| 4245 TargetEntryInstr* if_true = branch->true_successor(); | 4283 TargetEntryInstr* if_true = branch->true_successor(); |
| 4246 TargetEntryInstr* if_false = branch->false_successor(); | 4284 TargetEntryInstr* if_false = branch->false_successor(); |
| 4247 JoinEntryInstr* join = NULL; | 4285 JoinEntryInstr* join = NULL; |
| 4248 Instruction* next = NULL; | 4286 Instruction* next = NULL; |
| 4249 | 4287 |
| 4250 if (!reachable_->Contains(if_true->preorder_number())) { | 4288 if (!reachable_->Contains(if_true->preorder_number())) { |
| 4251 ASSERT(reachable_->Contains(if_false->preorder_number())); | 4289 ASSERT(reachable_->Contains(if_false->preorder_number())); |
| 4252 ASSERT(branch->comparison()->IsStrictCompare()); | |
| 4253 ASSERT(if_false->parallel_move() == NULL); | 4290 ASSERT(if_false->parallel_move() == NULL); |
| 4254 ASSERT(if_false->loop_info() == NULL); | 4291 ASSERT(if_false->loop_info() == NULL); |
| 4255 join = new JoinEntryInstr(if_false->block_id(), | 4292 join = new JoinEntryInstr(if_false->block_id(), |
| 4256 if_false->try_index(), | 4293 if_false->try_index(), |
| 4257 if_false->loop_depth()); | 4294 if_false->loop_depth()); |
| 4258 next = if_false->next(); | 4295 next = if_false->next(); |
| 4259 } else if (!reachable_->Contains(if_false->preorder_number())) { | 4296 } else if (!reachable_->Contains(if_false->preorder_number())) { |
| 4260 ASSERT(branch->comparison()->IsStrictCompare()); | |
| 4261 ASSERT(if_true->parallel_move() == NULL); | 4297 ASSERT(if_true->parallel_move() == NULL); |
| 4262 ASSERT(if_true->loop_info() == NULL); | 4298 ASSERT(if_true->loop_info() == NULL); |
| 4263 join = new JoinEntryInstr(if_true->block_id(), | 4299 join = new JoinEntryInstr(if_true->block_id(), |
| 4264 if_true->try_index(), | 4300 if_true->try_index(), |
| 4265 if_true->loop_depth()); | 4301 if_true->loop_depth()); |
| 4266 next = if_true->next(); | 4302 next = if_true->next(); |
| 4267 } | 4303 } |
| 4268 | 4304 |
| 4269 if (join != NULL) { | 4305 if (join != NULL) { |
| 4270 // Replace the branch with a jump to the reachable successor. | 4306 // Replace the branch with a jump to the reachable successor. |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 4297 | 4333 |
| 4298 if (FLAG_trace_constant_propagation) { | 4334 if (FLAG_trace_constant_propagation) { |
| 4299 OS::Print("\n==== After constant propagation ====\n"); | 4335 OS::Print("\n==== After constant propagation ====\n"); |
| 4300 FlowGraphPrinter printer(*graph_); | 4336 FlowGraphPrinter printer(*graph_); |
| 4301 printer.PrintBlocks(); | 4337 printer.PrintBlocks(); |
| 4302 } | 4338 } |
| 4303 } | 4339 } |
| 4304 | 4340 |
| 4305 | 4341 |
| 4306 } // namespace dart | 4342 } // namespace dart |
| OLD | NEW |