| 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 872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 883 | 883 |
| 884 return false; | 884 return false; |
| 885 } | 885 } |
| 886 | 886 |
| 887 | 887 |
| 888 // Inline only simple, frequently called core library methods. | 888 // Inline only simple, frequently called core library methods. |
| 889 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { | 889 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { |
| 890 ASSERT(call->HasICData()); | 890 ASSERT(call->HasICData()); |
| 891 const ICData& ic_data = *call->ic_data(); | 891 const ICData& ic_data = *call->ic_data(); |
| 892 if ((ic_data.NumberOfChecks() == 0) || !ic_data.HasOneTarget()) { | 892 if ((ic_data.NumberOfChecks() == 0) || !ic_data.HasOneTarget()) { |
| 893 // No type feedback collected. | 893 // No type feedback collected or multiple targets found. |
| 894 return false; | 894 return false; |
| 895 } | 895 } |
| 896 Function& target = Function::Handle(); | 896 Function& target = Function::Handle(); |
| 897 GrowableArray<intptr_t> class_ids; | 897 GrowableArray<intptr_t> class_ids; |
| 898 ic_data.GetCheckAt(0, &class_ids, &target); | 898 ic_data.GetCheckAt(0, &class_ids, &target); |
| 899 MethodRecognizer::Kind recognized_kind = | 899 MethodRecognizer::Kind recognized_kind = |
| 900 MethodRecognizer::RecognizeKind(target); | 900 MethodRecognizer::RecognizeKind(target); |
| 901 | 901 |
| 902 if ((recognized_kind == MethodRecognizer::kDoubleToDouble) && | 902 if ((recognized_kind == MethodRecognizer::kDoubleToDouble) && |
| 903 (class_ids[0] == kDoubleCid)) { | 903 (class_ids[0] == kDoubleCid)) { |
| 904 DoubleToDoubleInstr* d2d_instr = | 904 DoubleToDoubleInstr* d2d_instr = |
| 905 new DoubleToDoubleInstr(call->ArgumentAt(0)->value(), call); | 905 new DoubleToDoubleInstr(call->ArgumentAt(0)->value(), call); |
| 906 call->ReplaceWith(d2d_instr, current_iterator()); | 906 call->ReplaceWith(d2d_instr, current_iterator()); |
| 907 RemovePushArguments(call); | 907 RemovePushArguments(call); |
| 908 return true; | 908 return true; |
| 909 } | 909 } |
| 910 | 910 |
| 911 if ((recognized_kind == MethodRecognizer::kIntegerToDouble) && | 911 if ((recognized_kind == MethodRecognizer::kIntegerToDouble) && |
| 912 (class_ids[0] == kSmiCid)) { | 912 (class_ids[0] == kSmiCid)) { |
| 913 SmiToDoubleInstr* s2d_instr = new SmiToDoubleInstr(call); | 913 SmiToDoubleInstr* s2d_instr = new SmiToDoubleInstr(call); |
| 914 call->ReplaceWith(s2d_instr, current_iterator()); | 914 call->ReplaceWith(s2d_instr, current_iterator()); |
| 915 // Pushed arguments are not removed because SmiToDouble is implemented | 915 // Pushed arguments are not removed because SmiToDouble is implemented |
| 916 // as a call. | 916 // as a call. |
| 917 return true; | 917 return true; |
| 918 } | 918 } |
| 919 | 919 |
| 920 const intptr_t cid0 = class_ids[0]; |
| 921 if ((recognized_kind == MethodRecognizer::kIntegerToInteger) && |
| 922 ((cid0 == kSmiCid) || (cid0 == kMintCid) || (cid0 == kBigintCid))) { |
| 923 // TODO(srdjan): implement also for mixed integer cids. |
| 924 InsertBefore(call, |
| 925 new CheckSmiInstr(call->ArgumentAt(0)->value()->Copy(), |
| 926 call->deopt_id()), |
| 927 call->env(), |
| 928 Definition::kEffect); |
| 929 call->ReplaceUsesWith(call->ArgumentAt(0)); |
| 930 RemovePushArguments(call); |
| 931 call->RemoveFromGraph(); |
| 932 return true; |
| 933 } |
| 934 |
| 935 if ((recognized_kind == MethodRecognizer::kDoubleToInteger) && |
| 936 (class_ids[0] == kDoubleCid)) { |
| 937 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); |
| 938 DoubleToIntegerInstr* d2int_instr = |
| 939 new DoubleToIntegerInstr(call->ArgumentAt(0)->value(), call); |
| 940 call->ReplaceWith(d2int_instr, current_iterator()); |
| 941 RemovePushArguments(call); |
| 942 return true; |
| 943 } |
| 944 |
| 920 if (recognized_kind == MethodRecognizer::kStringBaseIsEmpty) { | 945 if (recognized_kind == MethodRecognizer::kStringBaseIsEmpty) { |
| 921 if (!ic_data.HasOneTarget()) { | 946 if (!ic_data.HasOneTarget()) { |
| 922 // Target is not only StringBase_get_length. | 947 // Target is not only StringBase_get_length. |
| 923 return false; | 948 return false; |
| 924 } | 949 } |
| 925 InlineStringIsEmptyTester(call); | 950 InlineStringIsEmptyTester(call); |
| 926 return true; | 951 return true; |
| 927 } | 952 } |
| 928 | 953 |
| 929 return false; | 954 return false; |
| 930 } | 955 } |
| 931 | 956 |
| 932 | 957 |
| 958 // Tries to optimize instance call by replacing it with a faster instruction |
| 959 // (e.g, binary op, field load, ..). |
| 933 void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { | 960 void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { |
| 934 if (instr->HasICData() && (instr->ic_data()->NumberOfChecks() > 0)) { | 961 if (instr->HasICData() && (instr->ic_data()->NumberOfChecks() > 0)) { |
| 935 const Token::Kind op_kind = instr->token_kind(); | 962 const Token::Kind op_kind = instr->token_kind(); |
| 936 if (Token::IsIndexOperator(op_kind) && | 963 if (Token::IsIndexOperator(op_kind) && |
| 937 TryReplaceWithArrayOp(instr, op_kind)) { | 964 TryReplaceWithArrayOp(instr, op_kind)) { |
| 938 return; | 965 return; |
| 939 } | 966 } |
| 940 if (Token::IsBinaryToken(op_kind) && | 967 if (Token::IsBinaryToken(op_kind) && |
| 941 TryReplaceWithBinaryOp(instr, op_kind)) { | 968 TryReplaceWithBinaryOp(instr, op_kind)) { |
| 942 return; | 969 return; |
| (...skipping 2102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3045 } | 3072 } |
| 3046 } | 3073 } |
| 3047 | 3074 |
| 3048 | 3075 |
| 3049 void ConstantPropagator::VisitSmiToDouble(SmiToDoubleInstr* instr) { | 3076 void ConstantPropagator::VisitSmiToDouble(SmiToDoubleInstr* instr) { |
| 3050 // TODO(kmillikin): Handle conversion. | 3077 // TODO(kmillikin): Handle conversion. |
| 3051 SetValue(instr, non_constant_); | 3078 SetValue(instr, non_constant_); |
| 3052 } | 3079 } |
| 3053 | 3080 |
| 3054 | 3081 |
| 3082 void ConstantPropagator::VisitDoubleToInteger(DoubleToIntegerInstr* instr) { |
| 3083 // TODO(kmillikin): Handle conversion. |
| 3084 SetValue(instr, non_constant_); |
| 3085 } |
| 3086 |
| 3087 |
| 3055 void ConstantPropagator::VisitConstant(ConstantInstr* instr) { | 3088 void ConstantPropagator::VisitConstant(ConstantInstr* instr) { |
| 3056 SetValue(instr, instr->value()); | 3089 SetValue(instr, instr->value()); |
| 3057 } | 3090 } |
| 3058 | 3091 |
| 3059 | 3092 |
| 3060 void ConstantPropagator::VisitConstraint(ConstraintInstr* instr) { | 3093 void ConstantPropagator::VisitConstraint(ConstraintInstr* instr) { |
| 3061 // Should not be used outside of range analysis. | 3094 // Should not be used outside of range analysis. |
| 3062 UNREACHABLE(); | 3095 UNREACHABLE(); |
| 3063 } | 3096 } |
| 3064 | 3097 |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3260 | 3293 |
| 3261 if (FLAG_trace_constant_propagation) { | 3294 if (FLAG_trace_constant_propagation) { |
| 3262 OS::Print("\n==== After constant propagation ====\n"); | 3295 OS::Print("\n==== After constant propagation ====\n"); |
| 3263 FlowGraphPrinter printer(*graph_); | 3296 FlowGraphPrinter printer(*graph_); |
| 3264 printer.PrintBlocks(); | 3297 printer.PrintBlocks(); |
| 3265 } | 3298 } |
| 3266 } | 3299 } |
| 3267 | 3300 |
| 3268 | 3301 |
| 3269 } // namespace dart | 3302 } // namespace dart |
| OLD | NEW |