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 |