| 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 959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 970 void FlowGraphOptimizer::InlineStringLengthGetter(InstanceCallInstr* call) { | 970 void FlowGraphOptimizer::InlineStringLengthGetter(InstanceCallInstr* call) { |
| 971 // Check receiver class. | 971 // Check receiver class. |
| 972 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); | 972 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); |
| 973 | 973 |
| 974 LoadFieldInstr* load = BuildLoadStringLength(call->ArgumentAt(0)->value()); | 974 LoadFieldInstr* load = BuildLoadStringLength(call->ArgumentAt(0)->value()); |
| 975 call->ReplaceWith(load, current_iterator()); | 975 call->ReplaceWith(load, current_iterator()); |
| 976 RemovePushArguments(call); | 976 RemovePushArguments(call); |
| 977 } | 977 } |
| 978 | 978 |
| 979 | 979 |
| 980 void FlowGraphOptimizer::InlineStringIsEmptyTester(InstanceCallInstr* call) { | 980 void FlowGraphOptimizer::InlineStringIsEmptyGetter(InstanceCallInstr* call) { |
| 981 // Check receiver class. | 981 // Check receiver class. |
| 982 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); | 982 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); |
| 983 | 983 |
| 984 LoadFieldInstr* load = BuildLoadStringLength(call->ArgumentAt(0)->value()); | 984 LoadFieldInstr* load = BuildLoadStringLength(call->ArgumentAt(0)->value()); |
| 985 InsertBefore(call, load, NULL, Definition::kValue); | 985 InsertBefore(call, load, NULL, Definition::kValue); |
| 986 | 986 |
| 987 ConstantInstr* zero = new ConstantInstr(Smi::Handle(Smi::New(0))); | 987 ConstantInstr* zero = new ConstantInstr(Smi::Handle(Smi::New(0))); |
| 988 InsertBefore(call, zero, NULL, Definition::kValue); | 988 InsertBefore(call, zero, NULL, Definition::kValue); |
| 989 | 989 |
| 990 StrictCompareInstr* compare = | 990 StrictCompareInstr* compare = |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1049 | 1049 |
| 1050 if (recognized_kind == MethodRecognizer::kStringBaseLength) { | 1050 if (recognized_kind == MethodRecognizer::kStringBaseLength) { |
| 1051 if (!ic_data.HasOneTarget()) { | 1051 if (!ic_data.HasOneTarget()) { |
| 1052 // Target is not only StringBase_get_length. | 1052 // Target is not only StringBase_get_length. |
| 1053 return false; | 1053 return false; |
| 1054 } | 1054 } |
| 1055 InlineStringLengthGetter(call); | 1055 InlineStringLengthGetter(call); |
| 1056 return true; | 1056 return true; |
| 1057 } | 1057 } |
| 1058 | 1058 |
| 1059 if (recognized_kind == MethodRecognizer::kStringBaseIsEmpty) { |
| 1060 if (!ic_data.HasOneTarget()) { |
| 1061 // Target is not only StringBase_get_isEmpty. |
| 1062 return false; |
| 1063 } |
| 1064 InlineStringIsEmptyGetter(call); |
| 1065 return true; |
| 1066 } |
| 1067 |
| 1059 return false; | 1068 return false; |
| 1060 } | 1069 } |
| 1061 | 1070 |
| 1062 | 1071 |
| 1063 // Inline only simple, frequently called core library methods. | 1072 // Inline only simple, frequently called core library methods. |
| 1064 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { | 1073 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { |
| 1065 ASSERT(call->HasICData()); | 1074 ASSERT(call->HasICData()); |
| 1066 const ICData& ic_data = *call->ic_data(); | 1075 const ICData& ic_data = *call->ic_data(); |
| 1067 if ((ic_data.NumberOfChecks() == 0) || !ic_data.HasOneTarget()) { | 1076 if ((ic_data.NumberOfChecks() == 0) || !ic_data.HasOneTarget()) { |
| 1068 // No type feedback collected or multiple targets found. | 1077 // No type feedback collected or multiple targets found. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1110 if ((recognized_kind == MethodRecognizer::kDoubleToInteger) && | 1119 if ((recognized_kind == MethodRecognizer::kDoubleToInteger) && |
| 1111 (class_ids[0] == kDoubleCid)) { | 1120 (class_ids[0] == kDoubleCid)) { |
| 1112 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); | 1121 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); |
| 1113 DoubleToIntegerInstr* d2int_instr = | 1122 DoubleToIntegerInstr* d2int_instr = |
| 1114 new DoubleToIntegerInstr(call->ArgumentAt(0)->value(), call); | 1123 new DoubleToIntegerInstr(call->ArgumentAt(0)->value(), call); |
| 1115 call->ReplaceWith(d2int_instr, current_iterator()); | 1124 call->ReplaceWith(d2int_instr, current_iterator()); |
| 1116 RemovePushArguments(call); | 1125 RemovePushArguments(call); |
| 1117 return true; | 1126 return true; |
| 1118 } | 1127 } |
| 1119 | 1128 |
| 1120 if (recognized_kind == MethodRecognizer::kStringBaseIsEmpty) { | |
| 1121 if (!ic_data.HasOneTarget()) { | |
| 1122 // Target is not only StringBase_get_length. | |
| 1123 return false; | |
| 1124 } | |
| 1125 InlineStringIsEmptyTester(call); | |
| 1126 return true; | |
| 1127 } | |
| 1128 | |
| 1129 return false; | 1129 return false; |
| 1130 } | 1130 } |
| 1131 | 1131 |
| 1132 | 1132 |
| 1133 // Tries to optimize instance call by replacing it with a faster instruction | 1133 // Tries to optimize instance call by replacing it with a faster instruction |
| 1134 // (e.g, binary op, field load, ..). | 1134 // (e.g, binary op, field load, ..). |
| 1135 void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { | 1135 void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { |
| 1136 if (instr->HasICData() && (instr->ic_data()->NumberOfChecks() > 0)) { | 1136 if (instr->HasICData() && (instr->ic_data()->NumberOfChecks() > 0)) { |
| 1137 const Token::Kind op_kind = instr->token_kind(); | 1137 const Token::Kind op_kind = instr->token_kind(); |
| 1138 if ((op_kind == Token::kASSIGN_INDEX) && | 1138 if ((op_kind == Token::kASSIGN_INDEX) && |
| (...skipping 2335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3474 | 3474 |
| 3475 if (FLAG_trace_constant_propagation) { | 3475 if (FLAG_trace_constant_propagation) { |
| 3476 OS::Print("\n==== After constant propagation ====\n"); | 3476 OS::Print("\n==== After constant propagation ====\n"); |
| 3477 FlowGraphPrinter printer(*graph_); | 3477 FlowGraphPrinter printer(*graph_); |
| 3478 printer.PrintBlocks(); | 3478 printer.PrintBlocks(); |
| 3479 } | 3479 } |
| 3480 } | 3480 } |
| 3481 | 3481 |
| 3482 | 3482 |
| 3483 } // namespace dart | 3483 } // namespace dart |
| OLD | NEW |