| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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_inliner.h" | 5 #include "vm/flow_graph_inliner.h" |
| 6 | 6 |
| 7 #include "vm/compiler.h" | 7 #include "vm/compiler.h" |
| 8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
| 9 #include "vm/flow_graph.h" | 9 #include "vm/flow_graph.h" |
| 10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
| (...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 callee_graph->ComputeUseLists(); | 494 callee_graph->ComputeUseLists(); |
| 495 } | 495 } |
| 496 | 496 |
| 497 { | 497 { |
| 498 TimerScope timer(FLAG_compiler_stats, | 498 TimerScope timer(FLAG_compiler_stats, |
| 499 &CompilerStats::graphinliner_opt_timer, | 499 &CompilerStats::graphinliner_opt_timer, |
| 500 isolate); | 500 isolate); |
| 501 // TODO(zerny): Do more optimization passes on the callee graph. | 501 // TODO(zerny): Do more optimization passes on the callee graph. |
| 502 FlowGraphOptimizer optimizer(callee_graph); | 502 FlowGraphOptimizer optimizer(callee_graph); |
| 503 optimizer.ApplyICData(); | 503 optimizer.ApplyICData(); |
| 504 callee_graph->ComputeUseLists(); | 504 DEBUG_ASSERT(callee_graph->VerifyUseLists()); |
| 505 } | 505 } |
| 506 | 506 |
| 507 if (FLAG_trace_inlining && | 507 if (FLAG_trace_inlining && |
| 508 (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized)) { | 508 (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized)) { |
| 509 OS::Print("Callee graph for inlining %s\n", | 509 OS::Print("Callee graph for inlining %s\n", |
| 510 function.ToFullyQualifiedCString()); | 510 function.ToFullyQualifiedCString()); |
| 511 FlowGraphPrinter printer(*callee_graph); | 511 FlowGraphPrinter printer(*callee_graph); |
| 512 printer.PrintBlocks(); | 512 printer.PrintBlocks(); |
| 513 } | 513 } |
| 514 | 514 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 } | 554 } |
| 555 | 555 |
| 556 { | 556 { |
| 557 TimerScope timer(FLAG_compiler_stats, | 557 TimerScope timer(FLAG_compiler_stats, |
| 558 &CompilerStats::graphinliner_subst_timer, | 558 &CompilerStats::graphinliner_subst_timer, |
| 559 isolate); | 559 isolate); |
| 560 | 560 |
| 561 // Plug result in the caller graph. | 561 // Plug result in the caller graph. |
| 562 inlining_context->ReplaceCall(caller_graph_, call, callee_graph); | 562 inlining_context->ReplaceCall(caller_graph_, call, callee_graph); |
| 563 | 563 |
| 564 // Remove push arguments of the call. | |
| 565 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { | |
| 566 PushArgumentInstr* push = call->PushArgumentAt(i); | |
| 567 push->ReplaceUsesWith(push->value()->definition()); | |
| 568 push->RemoveFromGraph(); | |
| 569 } | |
| 570 | |
| 571 // Replace each stub with the actual argument or the caller's constant. | 564 // Replace each stub with the actual argument or the caller's constant. |
| 572 // Nulls denote optional parameters for which no actual was given. | 565 // Nulls denote optional parameters for which no actual was given. |
| 573 for (intptr_t i = 0; i < arguments->length(); ++i) { | 566 for (intptr_t i = 0; i < arguments->length(); ++i) { |
| 574 Definition* stub = param_stubs[i]; | 567 Definition* stub = param_stubs[i]; |
| 575 Value* actual = (*arguments)[i]; | 568 Value* actual = (*arguments)[i]; |
| 576 if (actual != NULL) stub->ReplaceUsesWith(actual->definition()); | 569 if (actual != NULL) stub->ReplaceUsesWith(actual->definition()); |
| 577 } | 570 } |
| 578 | 571 |
| 572 // Remove push arguments of the call. |
| 573 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { |
| 574 PushArgumentInstr* push = call->PushArgumentAt(i); |
| 575 push->ReplaceUsesWith(push->value()->definition()); |
| 576 push->UnuseAllInputs(); |
| 577 push->RemoveFromGraph(); |
| 578 } |
| 579 |
| 579 // Replace remaining constants with uses by constants in the caller's | 580 // Replace remaining constants with uses by constants in the caller's |
| 580 // initial definitions. | 581 // initial definitions. |
| 581 GrowableArray<Definition*>* defns = | 582 GrowableArray<Definition*>* defns = |
| 582 callee_graph->graph_entry()->initial_definitions(); | 583 callee_graph->graph_entry()->initial_definitions(); |
| 583 for (intptr_t i = 0; i < defns->length(); ++i) { | 584 for (intptr_t i = 0; i < defns->length(); ++i) { |
| 584 ConstantInstr* constant = (*defns)[i]->AsConstant(); | 585 ConstantInstr* constant = (*defns)[i]->AsConstant(); |
| 585 if ((constant != NULL) && constant->HasUses()) { | 586 if ((constant != NULL) && constant->HasUses()) { |
| 586 constant->ReplaceUsesWith( | 587 constant->ReplaceUsesWith( |
| 587 caller_graph_->AddConstantToInitialDefinitions( | 588 caller_graph_->AddConstantToInitialDefinitions( |
| 588 constant->value())); | 589 constant->value())); |
| 589 } | 590 } |
| 590 } | 591 } |
| 591 } | 592 } |
| 592 | 593 |
| 593 TRACE_INLINING(OS::Print(" Success\n")); | 594 TRACE_INLINING(OS::Print(" Success\n")); |
| 594 | 595 |
| 595 // Add the function to the cache. | 596 // Add the function to the cache. |
| 596 if (!in_cache) function_cache_.Add(parsed_function); | 597 if (!in_cache) function_cache_.Add(parsed_function); |
| 597 | 598 |
| 598 // Check that inlining maintains use lists. | 599 // Check that inlining maintains use lists. |
| 599 DEBUG_ASSERT(!FLAG_verify_compiler || caller_graph_->ValidateUseLists()); | 600 DEBUG_ASSERT(!FLAG_verify_compiler || caller_graph_->VerifyUseLists()); |
| 600 | 601 |
| 601 // Build succeeded so we restore the bailout jump. | 602 // Build succeeded so we restore the bailout jump. |
| 602 inlined_ = true; | 603 inlined_ = true; |
| 603 inlined_size_ += size; | 604 inlined_size_ += size; |
| 604 isolate->set_long_jump_base(base); | 605 isolate->set_long_jump_base(base); |
| 605 isolate->set_deopt_id(prev_deopt_id); | 606 isolate->set_deopt_id(prev_deopt_id); |
| 606 isolate->set_ic_data_array(prev_ic_data.raw()); | 607 isolate->set_ic_data_array(prev_ic_data.raw()); |
| 607 return true; | 608 return true; |
| 608 } else { | 609 } else { |
| 609 Error& error = Error::Handle(); | 610 Error& error = Error::Handle(); |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 868 OS::Print("After Inlining of %s\n", flow_graph_-> | 869 OS::Print("After Inlining of %s\n", flow_graph_-> |
| 869 parsed_function().function().ToFullyQualifiedCString()); | 870 parsed_function().function().ToFullyQualifiedCString()); |
| 870 FlowGraphPrinter printer(*flow_graph_); | 871 FlowGraphPrinter printer(*flow_graph_); |
| 871 printer.PrintBlocks(); | 872 printer.PrintBlocks(); |
| 872 } | 873 } |
| 873 } | 874 } |
| 874 } | 875 } |
| 875 } | 876 } |
| 876 | 877 |
| 877 } // namespace dart | 878 } // namespace dart |
| OLD | NEW |