Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(295)

Side by Side Diff: runtime/vm/flow_graph_inliner.cc

Issue 1472363002: VM: Inlining of small constructors/factories, optimizations on inlined function bodies (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/block_scheduler.h" 7 #include "vm/block_scheduler.h"
8 #include "vm/compiler.h" 8 #include "vm/compiler.h"
9 #include "vm/flags.h" 9 #include "vm/flags.h"
10 #include "vm/flow_graph.h" 10 #include "vm/flow_graph.h"
11 #include "vm/flow_graph_builder.h" 11 #include "vm/flow_graph_builder.h"
12 #include "vm/flow_graph_compiler.h" 12 #include "vm/flow_graph_compiler.h"
13 #include "vm/flow_graph_optimizer.h" 13 #include "vm/flow_graph_optimizer.h"
14 #include "vm/flow_graph_type_propagator.h"
14 #include "vm/il_printer.h" 15 #include "vm/il_printer.h"
15 #include "vm/intrinsifier.h" 16 #include "vm/intrinsifier.h"
16 #include "vm/longjump.h" 17 #include "vm/longjump.h"
17 #include "vm/object.h" 18 #include "vm/object.h"
18 #include "vm/object_store.h" 19 #include "vm/object_store.h"
19 #include "vm/timer.h" 20 #include "vm/timer.h"
20 21
21 namespace dart { 22 namespace dart {
22 23
23 DEFINE_FLAG(int, deoptimization_counter_inlining_threshold, 12, 24 DEFINE_FLAG(int, deoptimization_counter_inlining_threshold, 12,
(...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 { 770 {
770 CSTAT_TIMER_SCOPE(thread(), graphinliner_ssa_timer); 771 CSTAT_TIMER_SCOPE(thread(), graphinliner_ssa_timer);
771 // Compute SSA on the callee graph, catching bailouts. 772 // Compute SSA on the callee graph, catching bailouts.
772 callee_graph->ComputeSSA(caller_graph_->max_virtual_register_number(), 773 callee_graph->ComputeSSA(caller_graph_->max_virtual_register_number(),
773 param_stubs); 774 param_stubs);
774 DEBUG_ASSERT(callee_graph->VerifyUseLists()); 775 DEBUG_ASSERT(callee_graph->VerifyUseLists());
775 } 776 }
776 777
777 { 778 {
778 CSTAT_TIMER_SCOPE(thread(), graphinliner_opt_timer); 779 CSTAT_TIMER_SCOPE(thread(), graphinliner_opt_timer);
779 // TODO(zerny): Do more optimization passes on the callee graph. 780 // TODO(fschneider): Improve suppression of speculative inlining.
780 FlowGraphOptimizer optimizer(callee_graph); 781 // Deopt-ids overlap between caller and callee.
782 FlowGraphOptimizer optimizer(callee_graph,
783 inliner_->use_speculative_inlining_,
784 inliner_->inlining_black_list_);
781 if (Compiler::always_optimize()) { 785 if (Compiler::always_optimize()) {
782 optimizer.PopulateWithICData(); 786 optimizer.PopulateWithICData();
787
788 optimizer.ApplyClassIds();
789 DEBUG_ASSERT(callee_graph->VerifyUseLists());
790
791 FlowGraphTypePropagator::Propagate(callee_graph);
792 DEBUG_ASSERT(callee_graph->VerifyUseLists());
783 } 793 }
784 optimizer.ApplyICData(); 794 optimizer.ApplyICData();
785 DEBUG_ASSERT(callee_graph->VerifyUseLists()); 795 DEBUG_ASSERT(callee_graph->VerifyUseLists());
786 796
787 // Optimize (a << b) & c patterns, merge instructions. Must occur before 797 // Optimize (a << b) & c patterns, merge instructions. Must occur before
788 // 'SelectRepresentations' which inserts conversion nodes. 798 // 'SelectRepresentations' which inserts conversion nodes.
789 optimizer.TryOptimizePatterns(); 799 optimizer.TryOptimizePatterns();
790 DEBUG_ASSERT(callee_graph->VerifyUseLists()); 800 DEBUG_ASSERT(callee_graph->VerifyUseLists());
791 } 801 }
792 802
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after
1462 Value* input = second->InputAt(i); 1472 Value* input = second->InputAt(i);
1463 input->definition()->AddInputUse(input); 1473 input->definition()->AddInputUse(input);
1464 } 1474 }
1465 first->LinkTo(second); 1475 first->LinkTo(second);
1466 return second; 1476 return second;
1467 } 1477 }
1468 1478
1469 1479
1470 bool PolymorphicInliner::TryInlineRecognizedMethod(intptr_t receiver_cid, 1480 bool PolymorphicInliner::TryInlineRecognizedMethod(intptr_t receiver_cid,
1471 const Function& target) { 1481 const Function& target) {
1472 FlowGraphOptimizer optimizer(owner_->caller_graph()); 1482 FlowGraphOptimizer optimizer(owner_->caller_graph(),
1483 false, // Speculative inlining not applicable.
1484 NULL);
1473 TargetEntryInstr* entry; 1485 TargetEntryInstr* entry;
1474 Definition* last; 1486 Definition* last;
1475 // Replace the receiver argument with a redefinition to prevent code from 1487 // Replace the receiver argument with a redefinition to prevent code from
1476 // the inlined body from being hoisted above the inlined entry. 1488 // the inlined body from being hoisted above the inlined entry.
1477 GrowableArray<Definition*> arguments(call_->ArgumentCount()); 1489 GrowableArray<Definition*> arguments(call_->ArgumentCount());
1478 Definition* receiver = call_->ArgumentAt(0); 1490 Definition* receiver = call_->ArgumentAt(0);
1479 RedefinitionInstr* redefinition = 1491 RedefinitionInstr* redefinition =
1480 new(Z) RedefinitionInstr(new(Z) Value(receiver)); 1492 new(Z) RedefinitionInstr(new(Z) Value(receiver));
1481 redefinition->set_ssa_temp_index( 1493 redefinition->set_ssa_temp_index(
1482 owner_->caller_graph()->alloc_ssa_temp_index()); 1494 owner_->caller_graph()->alloc_ssa_temp_index());
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
1768 1780
1769 static bool ShouldTraceInlining(FlowGraph* flow_graph) { 1781 static bool ShouldTraceInlining(FlowGraph* flow_graph) {
1770 const Function& top = flow_graph->parsed_function().function(); 1782 const Function& top = flow_graph->parsed_function().function();
1771 return FLAG_trace_inlining && FlowGraphPrinter::ShouldPrint(top); 1783 return FLAG_trace_inlining && FlowGraphPrinter::ShouldPrint(top);
1772 } 1784 }
1773 1785
1774 1786
1775 FlowGraphInliner::FlowGraphInliner( 1787 FlowGraphInliner::FlowGraphInliner(
1776 FlowGraph* flow_graph, 1788 FlowGraph* flow_graph,
1777 GrowableArray<const Function*>* inline_id_to_function, 1789 GrowableArray<const Function*>* inline_id_to_function,
1778 GrowableArray<intptr_t>* caller_inline_id) 1790 GrowableArray<intptr_t>* caller_inline_id,
1791 bool use_speculative_inlining,
1792 GrowableArray<intptr_t>* inlining_black_list)
1779 : flow_graph_(flow_graph), 1793 : flow_graph_(flow_graph),
1780 inline_id_to_function_(inline_id_to_function), 1794 inline_id_to_function_(inline_id_to_function),
1781 caller_inline_id_(caller_inline_id), 1795 caller_inline_id_(caller_inline_id),
1782 trace_inlining_(ShouldTraceInlining(flow_graph)) { 1796 trace_inlining_(ShouldTraceInlining(flow_graph)),
1797 use_speculative_inlining_(use_speculative_inlining),
1798 inlining_black_list_(inlining_black_list) {
1799 ASSERT(!use_speculative_inlining || (inlining_black_list != NULL));
1783 } 1800 }
1784 1801
1785 1802
1786 void FlowGraphInliner::CollectGraphInfo(FlowGraph* flow_graph, bool force) { 1803 void FlowGraphInliner::CollectGraphInfo(FlowGraph* flow_graph, bool force) {
1787 const Function& function = flow_graph->function(); 1804 const Function& function = flow_graph->function();
1788 if (force || (function.optimized_instruction_count() == 0)) { 1805 if (force || (function.optimized_instruction_count() == 0)) {
1789 GraphInfoCollector info; 1806 GraphInfoCollector info;
1790 info.Collect(*flow_graph); 1807 info.Collect(*flow_graph);
1791 1808
1792 function.set_optimized_instruction_count( 1809 function.set_optimized_instruction_count(
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1832 const char* kAlwaysInlineAnnotation = "AlwaysInline"; 1849 const char* kAlwaysInlineAnnotation = "AlwaysInline";
1833 if (FLAG_enable_inlining_annotations && 1850 if (FLAG_enable_inlining_annotations &&
1834 HasAnnotation(function, kAlwaysInlineAnnotation)) { 1851 HasAnnotation(function, kAlwaysInlineAnnotation)) {
1835 TRACE_INLINING(THR_Print("AlwaysInline annotation for %s\n", 1852 TRACE_INLINING(THR_Print("AlwaysInline annotation for %s\n",
1836 function.ToCString())); 1853 function.ToCString()));
1837 return true; 1854 return true;
1838 } 1855 }
1839 1856
1840 if (function.IsImplicitGetterFunction() || function.IsGetterFunction() || 1857 if (function.IsImplicitGetterFunction() || function.IsGetterFunction() ||
1841 function.IsImplicitSetterFunction() || function.IsSetterFunction() || 1858 function.IsImplicitSetterFunction() || function.IsSetterFunction() ||
1842 IsInlineableOperator(function)) { 1859 IsInlineableOperator(function) ||
1860 (function.kind() == RawFunction::kConstructor)) {
1843 const intptr_t count = function.optimized_instruction_count(); 1861 const intptr_t count = function.optimized_instruction_count();
1844 if ((count != 0) && (count < FLAG_inline_getters_setters_smaller_than)) { 1862 if ((count != 0) && (count < FLAG_inline_getters_setters_smaller_than)) {
1845 return true; 1863 return true;
1846 } 1864 }
1847 } 1865 }
1848 return MethodRecognizer::AlwaysInline(function); 1866 return MethodRecognizer::AlwaysInline(function);
1849 } 1867 }
1850 1868
1851 1869
1852 void FlowGraphInliner::Inline() { 1870 void FlowGraphInliner::Inline() {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1894 intptr_t FlowGraphInliner::NextInlineId(const Function& function, 1912 intptr_t FlowGraphInliner::NextInlineId(const Function& function,
1895 intptr_t parent_id) { 1913 intptr_t parent_id) {
1896 const intptr_t id = inline_id_to_function_->length(); 1914 const intptr_t id = inline_id_to_function_->length();
1897 inline_id_to_function_->Add(&function); 1915 inline_id_to_function_->Add(&function);
1898 caller_inline_id_->Add(parent_id); 1916 caller_inline_id_->Add(parent_id);
1899 return id; 1917 return id;
1900 } 1918 }
1901 1919
1902 1920
1903 } // namespace dart 1921 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698