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

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

Issue 905363002: Add --print-flow-graph-filter to allow filtering debugging output. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 10 months 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_inliner.h ('k') | runtime/vm/il_printer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 DECLARE_FLAG(int, deoptimization_counter_threshold); 62 DECLARE_FLAG(int, deoptimization_counter_threshold);
63 DECLARE_FLAG(bool, print_flow_graph); 63 DECLARE_FLAG(bool, print_flow_graph);
64 DECLARE_FLAG(bool, print_flow_graph_optimized); 64 DECLARE_FLAG(bool, print_flow_graph_optimized);
65 DECLARE_FLAG(bool, verify_compiler); 65 DECLARE_FLAG(bool, verify_compiler);
66 66
67 // Quick access to the current zone. 67 // Quick access to the current zone.
68 #define Z (zone()) 68 #define Z (zone())
69 69
70 #define TRACE_INLINING(statement) \ 70 #define TRACE_INLINING(statement) \
71 do { \ 71 do { \
72 if (FLAG_trace_inlining) statement; \ 72 if (trace_inlining()) statement; \
73 } while (false) 73 } while (false)
74 74
75 #define PRINT_INLINING_TREE(comment, caller, target, instance_call) \ 75 #define PRINT_INLINING_TREE(comment, caller, target, instance_call) \
76 do { \ 76 do { \
77 if (FLAG_print_inlining_tree) { \ 77 if (FLAG_print_inlining_tree) { \
78 inlined_info_.Add(InlinedInfo( \ 78 inlined_info_.Add(InlinedInfo( \
79 caller, target, inlining_depth_, instance_call, comment)); \ 79 caller, target, inlining_depth_, instance_call, comment)); \
80 } \ 80 } \
81 } while (false) \ 81 } while (false) \
82 82
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 inlining_call_sites_(NULL), 491 inlining_call_sites_(NULL),
492 function_cache_(), 492 function_cache_(),
493 inlined_info_() { } 493 inlined_info_() { }
494 494
495 FlowGraph* caller_graph() const { return caller_graph_; } 495 FlowGraph* caller_graph() const { return caller_graph_; }
496 496
497 Thread* thread() const { return caller_graph_->thread(); } 497 Thread* thread() const { return caller_graph_->thread(); }
498 Isolate* isolate() const { return caller_graph_->isolate(); } 498 Isolate* isolate() const { return caller_graph_->isolate(); }
499 Zone* zone() const { return caller_graph_->zone(); } 499 Zone* zone() const { return caller_graph_->zone(); }
500 500
501 bool trace_inlining() const { return inliner_->trace_inlining(); }
502
501 // Inlining heuristics based on Cooper et al. 2008. 503 // Inlining heuristics based on Cooper et al. 2008.
502 bool ShouldWeInline(const Function& callee, 504 bool ShouldWeInline(const Function& callee,
503 intptr_t instr_count, 505 intptr_t instr_count,
504 intptr_t call_site_count, 506 intptr_t call_site_count,
505 intptr_t const_arg_count) { 507 intptr_t const_arg_count) {
506 if (FlowGraphInliner::AlwaysInline(callee)) { 508 if (inliner_->AlwaysInline(callee)) {
507 return true; 509 return true;
508 } 510 }
509 if (inlined_size_ > FLAG_inlining_caller_size_threshold) { 511 if (inlined_size_ > FLAG_inlining_caller_size_threshold) {
510 // Prevent methods becoming humongous and thus slow to compile. 512 // Prevent methods becoming humongous and thus slow to compile.
511 return false; 513 return false;
512 } 514 }
513 if (const_arg_count > 0) { 515 if (const_arg_count > 0) {
514 if (instr_count > FLAG_inlining_constant_arguments_max_size_threshold) { 516 if (instr_count > FLAG_inlining_constant_arguments_max_size_threshold) {
515 return false; 517 return false;
516 } 518 }
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
1037 ASSERT(call->ArgumentCount() <= 2); 1039 ASSERT(call->ArgumentCount() <= 2);
1038 // Arg 0: Instantiator type arguments. 1040 // Arg 0: Instantiator type arguments.
1039 // Arg 1: Length (optional). 1041 // Arg 1: Length (optional).
1040 if ((call->ArgumentCount() == 2) && 1042 if ((call->ArgumentCount() == 2) &&
1041 (!call->PushArgumentAt(1)->value()->BindsToConstant())) { 1043 (!call->PushArgumentAt(1)->value()->BindsToConstant())) {
1042 // Do not inline since a non-constant argument was passed. 1044 // Do not inline since a non-constant argument was passed.
1043 continue; 1045 continue;
1044 } 1046 }
1045 } 1047 }
1046 const Function& target = call->function(); 1048 const Function& target = call->function();
1047 if (!FlowGraphInliner::AlwaysInline(target) && 1049 if (!inliner_->AlwaysInline(target) &&
1048 (call_info[call_idx].ratio * 100) < FLAG_inlining_hotness) { 1050 (call_info[call_idx].ratio * 100) < FLAG_inlining_hotness) {
1049 TRACE_INLINING(OS::Print( 1051 TRACE_INLINING(OS::Print(
1050 " => %s (deopt count %d)\n Bailout: cold %f\n", 1052 " => %s (deopt count %d)\n Bailout: cold %f\n",
1051 target.ToCString(), 1053 target.ToCString(),
1052 target.deoptimization_counter(), 1054 target.deoptimization_counter(),
1053 call_info[call_idx].ratio)); 1055 call_info[call_idx].ratio));
1054 PRINT_INLINING_TREE("Too cold", 1056 PRINT_INLINING_TREE("Too cold",
1055 call_info[call_idx].caller, &call->function(), call); 1057 call_info[call_idx].caller, &call->function(), call);
1056 continue; 1058 continue;
1057 } 1059 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 PolymorphicInstanceCallInstr* call = call_info[call_idx].call; 1118 PolymorphicInstanceCallInstr* call = call_info[call_idx].call;
1117 if (call->with_checks()) { 1119 if (call->with_checks()) {
1118 const Function& cl = *call_info[call_idx].caller; 1120 const Function& cl = *call_info[call_idx].caller;
1119 PolymorphicInliner inliner(this, call, cl); 1121 PolymorphicInliner inliner(this, call, cl);
1120 inliner.Inline(); 1122 inliner.Inline();
1121 continue; 1123 continue;
1122 } 1124 }
1123 1125
1124 const ICData& ic_data = call->ic_data(); 1126 const ICData& ic_data = call->ic_data();
1125 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0)); 1127 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0));
1126 if (!FlowGraphInliner::AlwaysInline(target) && 1128 if (!inliner_->AlwaysInline(target) &&
1127 (call_info[call_idx].ratio * 100) < FLAG_inlining_hotness) { 1129 (call_info[call_idx].ratio * 100) < FLAG_inlining_hotness) {
1128 TRACE_INLINING(OS::Print( 1130 TRACE_INLINING(OS::Print(
1129 " => %s (deopt count %d)\n Bailout: cold %f\n", 1131 " => %s (deopt count %d)\n Bailout: cold %f\n",
1130 target.ToCString(), 1132 target.ToCString(),
1131 target.deoptimization_counter(), 1133 target.deoptimization_counter(),
1132 call_info[call_idx].ratio)); 1134 call_info[call_idx].ratio));
1133 PRINT_INLINING_TREE("Too cold", 1135 PRINT_INLINING_TREE("Too cold",
1134 call_info[call_idx].caller, &target, call); 1136 call_info[call_idx].caller, &target, call);
1135 continue; 1137 continue;
1136 } 1138 }
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after
1727 TargetEntryInstr* entry = BuildDecisionGraph(); 1729 TargetEntryInstr* entry = BuildDecisionGraph();
1728 exit_collector_->ReplaceCall(entry); 1730 exit_collector_->ReplaceCall(entry);
1729 } 1731 }
1730 1732
1731 1733
1732 static uint16_t ClampUint16(intptr_t v) { 1734 static uint16_t ClampUint16(intptr_t v) {
1733 return (v > 0xFFFF) ? 0xFFFF : static_cast<uint16_t>(v); 1735 return (v > 0xFFFF) ? 0xFFFF : static_cast<uint16_t>(v);
1734 } 1736 }
1735 1737
1736 1738
1739 static bool ShouldTraceInlining(FlowGraph* flow_graph) {
1740 const Function& top = flow_graph->parsed_function().function();
1741 return FLAG_trace_inlining && FlowGraphPrinter::ShouldPrint(top);
1742 }
1743
1744
1745 FlowGraphInliner::FlowGraphInliner(
1746 FlowGraph* flow_graph,
1747 GrowableArray<const Function*>* inline_id_to_function)
1748 : flow_graph_(flow_graph),
1749 inline_id_to_function_(inline_id_to_function),
1750 trace_inlining_(ShouldTraceInlining(flow_graph)) {
1751 }
1752
1753
1737 void FlowGraphInliner::CollectGraphInfo(FlowGraph* flow_graph, bool force) { 1754 void FlowGraphInliner::CollectGraphInfo(FlowGraph* flow_graph, bool force) {
1738 const Function& function = flow_graph->function(); 1755 const Function& function = flow_graph->function();
1739 if (force || (function.optimized_instruction_count() == 0)) { 1756 if (force || (function.optimized_instruction_count() == 0)) {
1740 GraphInfoCollector info; 1757 GraphInfoCollector info;
1741 info.Collect(*flow_graph); 1758 info.Collect(*flow_graph);
1742 1759
1743 function.set_optimized_instruction_count( 1760 function.set_optimized_instruction_count(
1744 ClampUint16(info.instruction_count())); 1761 ClampUint16(info.instruction_count()));
1745 function.set_optimized_call_site_count(ClampUint16(info.call_site_count())); 1762 function.set_optimized_call_site_count(ClampUint16(info.call_site_count()));
1746 } 1763 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1791 CollectGraphInfo(flow_graph_); 1808 CollectGraphInfo(flow_graph_);
1792 1809
1793 const Function& top = flow_graph_->function(); 1810 const Function& top = flow_graph_->function();
1794 if ((FLAG_inlining_filter != NULL) && 1811 if ((FLAG_inlining_filter != NULL) &&
1795 (strstr(top.ToFullyQualifiedCString(), FLAG_inlining_filter) == NULL)) { 1812 (strstr(top.ToFullyQualifiedCString(), FLAG_inlining_filter) == NULL)) {
1796 return; 1813 return;
1797 } 1814 }
1798 1815
1799 TRACE_INLINING(OS::Print("Inlining calls in %s\n", top.ToCString())); 1816 TRACE_INLINING(OS::Print("Inlining calls in %s\n", top.ToCString()));
1800 1817
1801 if (FLAG_trace_inlining && 1818 if (trace_inlining() &&
1802 (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized)) { 1819 (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized)) {
1803 OS::Print("Before Inlining of %s\n", flow_graph_-> 1820 OS::Print("Before Inlining of %s\n", flow_graph_->
1804 function().ToFullyQualifiedCString()); 1821 function().ToFullyQualifiedCString());
1805 FlowGraphPrinter printer(*flow_graph_); 1822 FlowGraphPrinter printer(*flow_graph_);
1806 printer.PrintBlocks(); 1823 printer.PrintBlocks();
1807 } 1824 }
1808 1825
1809 CallSiteInliner inliner(this); 1826 CallSiteInliner inliner(this);
1810 inliner.InlineCalls(); 1827 inliner.InlineCalls();
1811 if (FLAG_print_inlining_tree) { 1828 if (FLAG_print_inlining_tree) {
1812 inliner.PrintInlinedInfo(top); 1829 inliner.PrintInlinedInfo(top);
1813 } 1830 }
1814 1831
1815 if (inliner.inlined()) { 1832 if (inliner.inlined()) {
1816 flow_graph_->DiscoverBlocks(); 1833 flow_graph_->DiscoverBlocks();
1817 if (FLAG_trace_inlining) { 1834 if (trace_inlining()) {
1818 OS::Print("Inlining growth factor: %f\n", inliner.GrowthFactor()); 1835 OS::Print("Inlining growth factor: %f\n", inliner.GrowthFactor());
1819 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) { 1836 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) {
1820 OS::Print("After Inlining of %s\n", flow_graph_-> 1837 OS::Print("After Inlining of %s\n", flow_graph_->
1821 function().ToFullyQualifiedCString()); 1838 function().ToFullyQualifiedCString());
1822 FlowGraphPrinter printer(*flow_graph_); 1839 FlowGraphPrinter printer(*flow_graph_);
1823 printer.PrintBlocks(); 1840 printer.PrintBlocks();
1824 } 1841 }
1825 } 1842 }
1826 } 1843 }
1827 } 1844 }
1828 1845
1829 1846
1830 intptr_t FlowGraphInliner::NextInlineId(const Function& function) { 1847 intptr_t FlowGraphInliner::NextInlineId(const Function& function) {
1831 const intptr_t id = inline_id_to_function_->length(); 1848 const intptr_t id = inline_id_to_function_->length();
1832 inline_id_to_function_->Add(&function); 1849 inline_id_to_function_->Add(&function);
1833 return id; 1850 return id;
1834 } 1851 }
1835 1852
1836 1853
1837 } // namespace dart 1854 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_inliner.h ('k') | runtime/vm/il_printer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698