| 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/hash_map.h" | 10 #include "vm/hash_map.h" |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 static void RemovePushArguments(InstanceCallInstr* call) { | 267 static void RemovePushArguments(InstanceCallInstr* call) { |
| 268 // Remove original push arguments. | 268 // Remove original push arguments. |
| 269 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { | 269 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { |
| 270 PushArgumentInstr* push = call->ArgumentAt(i); | 270 PushArgumentInstr* push = call->ArgumentAt(i); |
| 271 push->ReplaceUsesWith(push->value()->definition()); | 271 push->ReplaceUsesWith(push->value()->definition()); |
| 272 push->RemoveFromGraph(); | 272 push->RemoveFromGraph(); |
| 273 } | 273 } |
| 274 } | 274 } |
| 275 | 275 |
| 276 | 276 |
| 277 static void RemovePushArguments(StaticCallInstr* call) { |
| 278 // Remove original push arguments. |
| 279 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { |
| 280 PushArgumentInstr* push = call->ArgumentAt(i); |
| 281 push->ReplaceUsesWith(push->value()->definition()); |
| 282 push->RemoveFromGraph(); |
| 283 } |
| 284 } |
| 285 |
| 286 |
| 277 // Returns true if all targets are the same. | 287 // Returns true if all targets are the same. |
| 278 // TODO(srdjan): if targets are native use their C_function to compare. | 288 // TODO(srdjan): if targets are native use their C_function to compare. |
| 279 static bool HasOneTarget(const ICData& ic_data) { | 289 static bool HasOneTarget(const ICData& ic_data) { |
| 280 ASSERT(ic_data.NumberOfChecks() > 0); | 290 ASSERT(ic_data.NumberOfChecks() > 0); |
| 281 const Function& first_target = Function::Handle(ic_data.GetTargetAt(0)); | 291 const Function& first_target = Function::Handle(ic_data.GetTargetAt(0)); |
| 282 Function& test_target = Function::Handle(); | 292 Function& test_target = Function::Handle(); |
| 283 for (intptr_t i = 1; i < ic_data.NumberOfChecks(); i++) { | 293 for (intptr_t i = 1; i < ic_data.NumberOfChecks(); i++) { |
| 284 test_target = ic_data.GetTargetAt(i); | 294 test_target = ic_data.GetTargetAt(i); |
| 285 if (first_target.raw() != test_target.raw()) { | 295 if (first_target.raw() != test_target.raw()) { |
| 286 return false; | 296 return false; |
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 new PolymorphicInstanceCallInstr(instr, unary_checks, | 777 new PolymorphicInstanceCallInstr(instr, unary_checks, |
| 768 call_with_checks); | 778 call_with_checks); |
| 769 instr->ReplaceWith(call, current_iterator()); | 779 instr->ReplaceWith(call, current_iterator()); |
| 770 } | 780 } |
| 771 } | 781 } |
| 772 // An instance call without ICData should continue calling via IC calls | 782 // An instance call without ICData should continue calling via IC calls |
| 773 // which should trigger reoptimization of optimized code. | 783 // which should trigger reoptimization of optimized code. |
| 774 } | 784 } |
| 775 | 785 |
| 776 | 786 |
| 777 void FlowGraphOptimizer::VisitStaticCall(StaticCallInstr* instr) { | 787 void FlowGraphOptimizer::VisitStaticCall(StaticCallInstr* call) { |
| 778 MethodRecognizer::Kind recognized_kind = | 788 MethodRecognizer::Kind recognized_kind = |
| 779 MethodRecognizer::RecognizeKind(instr->function()); | 789 MethodRecognizer::RecognizeKind(call->function()); |
| 780 if (recognized_kind == MethodRecognizer::kMathSqrt) { | 790 if (recognized_kind == MethodRecognizer::kMathSqrt) { |
| 781 instr->set_recognized(MethodRecognizer::kMathSqrt); | 791 MathSqrtInstr* sqrt = new MathSqrtInstr(call->ArgumentAt(0)->value(), call); |
| 792 call->ReplaceWith(sqrt, current_iterator()); |
| 793 RemovePushArguments(call); |
| 782 } | 794 } |
| 783 } | 795 } |
| 784 | 796 |
| 785 | 797 |
| 786 bool FlowGraphOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr) { | 798 bool FlowGraphOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr) { |
| 787 if (FLAG_enable_type_checks) { | 799 if (FLAG_enable_type_checks) { |
| 788 // TODO(srdjan): Add assignable check node if --enable_type_checks. | 800 // TODO(srdjan): Add assignable check node if --enable_type_checks. |
| 789 return false; | 801 return false; |
| 790 } | 802 } |
| 791 | 803 |
| (...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1366 DirectChainedHashMap<Definition*> child_map(*map); // Copy map. | 1378 DirectChainedHashMap<Definition*> child_map(*map); // Copy map. |
| 1367 OptimizeRecursive(child, &child_map); | 1379 OptimizeRecursive(child, &child_map); |
| 1368 } else { | 1380 } else { |
| 1369 OptimizeRecursive(child, map); // Reuse map for the last child. | 1381 OptimizeRecursive(child, map); // Reuse map for the last child. |
| 1370 } | 1382 } |
| 1371 } | 1383 } |
| 1372 } | 1384 } |
| 1373 | 1385 |
| 1374 | 1386 |
| 1375 } // namespace dart | 1387 } // namespace dart |
| OLD | NEW |