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

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

Issue 904763003: Redesign inlining interval computation. (Closed) Base URL: http://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/object.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 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 class CallSites : public ValueObject { 185 class CallSites : public ValueObject {
186 public: 186 public:
187 explicit CallSites(FlowGraph* flow_graph) 187 explicit CallSites(FlowGraph* flow_graph)
188 : static_calls_(), 188 : static_calls_(),
189 closure_calls_(), 189 closure_calls_(),
190 instance_calls_() { } 190 instance_calls_() { }
191 191
192 struct InstanceCallInfo { 192 struct InstanceCallInfo {
193 PolymorphicInstanceCallInstr* call; 193 PolymorphicInstanceCallInstr* call;
194 double ratio; 194 double ratio;
195 const Function* caller; 195 const FlowGraph* caller_graph;
196 InstanceCallInfo(PolymorphicInstanceCallInstr* call_arg, 196 InstanceCallInfo(PolymorphicInstanceCallInstr* call_arg,
197 FlowGraph* flow_graph) 197 FlowGraph* flow_graph)
198 : call(call_arg), 198 : call(call_arg),
199 ratio(0.0), 199 ratio(0.0),
200 caller(&flow_graph->function()) {} 200 caller_graph(flow_graph) {}
201 const Function& caller() const { return caller_graph->function(); }
201 }; 202 };
202 203
203 struct StaticCallInfo { 204 struct StaticCallInfo {
204 StaticCallInstr* call; 205 StaticCallInstr* call;
205 double ratio; 206 double ratio;
206 const Function* caller; 207 FlowGraph* caller_graph;
207 StaticCallInfo(StaticCallInstr* value, FlowGraph* flow_graph) 208 StaticCallInfo(StaticCallInstr* value, FlowGraph* flow_graph)
208 : call(value), 209 : call(value),
209 ratio(0.0), 210 ratio(0.0),
210 caller(&flow_graph->function()) {} 211 caller_graph(flow_graph) {}
212 const Function& caller() const { return caller_graph->function(); }
211 }; 213 };
212 214
213 struct ClosureCallInfo { 215 struct ClosureCallInfo {
214 ClosureCallInstr* call; 216 ClosureCallInstr* call;
215 const Function* caller; 217 FlowGraph* caller_graph;
216 ClosureCallInfo(ClosureCallInstr* value, FlowGraph* flow_graph) 218 ClosureCallInfo(ClosureCallInstr* value, FlowGraph* flow_graph)
217 : call(value), 219 : call(value),
218 caller(&flow_graph->function()) {} 220 caller_graph(flow_graph) {}
221 const Function& caller() const { return caller_graph->function(); }
219 }; 222 };
220 223
221 const GrowableArray<InstanceCallInfo>& instance_calls() const { 224 const GrowableArray<InstanceCallInfo>& instance_calls() const {
222 return instance_calls_; 225 return instance_calls_;
223 } 226 }
224 227
225 const GrowableArray<StaticCallInfo>& static_calls() const { 228 const GrowableArray<StaticCallInfo>& static_calls() const {
226 return static_calls_; 229 return static_calls_;
227 } 230 }
228 231
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 GrowableArray<ClosureCallInfo> closure_calls_; 400 GrowableArray<ClosureCallInfo> closure_calls_;
398 GrowableArray<InstanceCallInfo> instance_calls_; 401 GrowableArray<InstanceCallInfo> instance_calls_;
399 402
400 DISALLOW_COPY_AND_ASSIGN(CallSites); 403 DISALLOW_COPY_AND_ASSIGN(CallSites);
401 }; 404 };
402 405
403 406
404 struct InlinedCallData { 407 struct InlinedCallData {
405 InlinedCallData(Definition* call, 408 InlinedCallData(Definition* call,
406 GrowableArray<Value*>* arguments, 409 GrowableArray<Value*>* arguments,
407 const Function& caller) 410 const Function& caller,
411 intptr_t caller_inlining_id)
408 : call(call), 412 : call(call),
409 arguments(arguments), 413 arguments(arguments),
410 callee_graph(NULL), 414 callee_graph(NULL),
411 parameter_stubs(NULL), 415 parameter_stubs(NULL),
412 exit_collector(NULL), 416 exit_collector(NULL),
413 caller(caller) { } 417 caller(caller),
418 caller_inlining_id_(caller_inlining_id) { }
414 419
415 Definition* call; 420 Definition* call;
416 GrowableArray<Value*>* arguments; 421 GrowableArray<Value*>* arguments;
417 FlowGraph* callee_graph; 422 FlowGraph* callee_graph;
418 ZoneGrowableArray<Definition*>* parameter_stubs; 423 ZoneGrowableArray<Definition*>* parameter_stubs;
419 InlineExitCollector* exit_collector; 424 InlineExitCollector* exit_collector;
420 const Function& caller; 425 const Function& caller;
426 const intptr_t caller_inlining_id_;
421 }; 427 };
422 428
423 429
424 class CallSiteInliner; 430 class CallSiteInliner;
425 431
426 class PolymorphicInliner : public ValueObject { 432 class PolymorphicInliner : public ValueObject {
427 public: 433 public:
428 PolymorphicInliner(CallSiteInliner* owner, 434 PolymorphicInliner(CallSiteInliner* owner,
429 PolymorphicInstanceCallInstr* call, 435 PolymorphicInstanceCallInstr* call,
430 const Function& caller_function); 436 const Function& caller_function,
437 intptr_t caller_inlining_id);
431 438
432 void Inline(); 439 void Inline();
433 440
434 private: 441 private:
435 bool CheckInlinedDuplicate(const Function& target); 442 bool CheckInlinedDuplicate(const Function& target);
436 bool CheckNonInlinedDuplicate(const Function& target); 443 bool CheckNonInlinedDuplicate(const Function& target);
437 444
438 bool TryInliningPoly(intptr_t receiver_cid, const Function& target); 445 bool TryInliningPoly(intptr_t receiver_cid, const Function& target);
439 bool TryInlineRecognizedMethod(intptr_t receiver_cid, const Function& target); 446 bool TryInlineRecognizedMethod(intptr_t receiver_cid, const Function& target);
440 447
441 TargetEntryInstr* BuildDecisionGraph(); 448 TargetEntryInstr* BuildDecisionGraph();
442 449
443 Isolate* isolate() const; 450 Isolate* isolate() const;
444 Zone* zone() const; 451 Zone* zone() const;
445 452
446 CallSiteInliner* const owner_; 453 CallSiteInliner* const owner_;
447 PolymorphicInstanceCallInstr* const call_; 454 PolymorphicInstanceCallInstr* const call_;
448 const intptr_t num_variants_; 455 const intptr_t num_variants_;
449 GrowableArray<CidTarget> variants_; 456 GrowableArray<CidTarget> variants_;
450 457
451 GrowableArray<CidTarget> inlined_variants_; 458 GrowableArray<CidTarget> inlined_variants_;
452 GrowableArray<CidTarget> non_inlined_variants_; 459 GrowableArray<CidTarget> non_inlined_variants_;
453 GrowableArray<BlockEntryInstr*> inlined_entries_; 460 GrowableArray<BlockEntryInstr*> inlined_entries_;
454 InlineExitCollector* exit_collector_; 461 InlineExitCollector* exit_collector_;
455 462
456 const Function& caller_function_; 463 const Function& caller_function_;
464 const intptr_t caller_inlining_id_;
457 }; 465 };
458 466
459 467
460 static bool HasAnnotation(const Function& function, const char* annotation) { 468 static bool HasAnnotation(const Function& function, const char* annotation) {
461 const Class& owner = Class::Handle(function.Owner()); 469 const Class& owner = Class::Handle(function.Owner());
462 const Library& library = Library::Handle(owner.library()); 470 const Library& library = Library::Handle(owner.library());
463 const Array& metadata = 471 const Array& metadata =
464 Array::Cast(Object::Handle(library.GetMetadata(function))); 472 Array::Cast(Object::Handle(library.GetMetadata(function)));
465 473
466 if (metadata.Length() > 0) { 474 if (metadata.Length() > 0) {
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
845 // When inlined, we add the guarded fields of the callee to the caller's 853 // When inlined, we add the guarded fields of the callee to the caller's
846 // list of guarded fields. 854 // list of guarded fields.
847 for (intptr_t i = 0; i < callee_graph->guarded_fields()->length(); ++i) { 855 for (intptr_t i = 0; i < callee_graph->guarded_fields()->length(); ++i) {
848 FlowGraph::AddToGuardedFields(caller_graph_->guarded_fields(), 856 FlowGraph::AddToGuardedFields(caller_graph_->guarded_fields(),
849 (*callee_graph->guarded_fields())[i]); 857 (*callee_graph->guarded_fields())[i]);
850 } 858 }
851 // When inlined, we add the deferred prefixes of the callee to the 859 // When inlined, we add the deferred prefixes of the callee to the
852 // caller's list of deferred prefixes. 860 // caller's list of deferred prefixes.
853 caller_graph()->AddToDeferredPrefixes(callee_graph->deferred_prefixes()); 861 caller_graph()->AddToDeferredPrefixes(callee_graph->deferred_prefixes());
854 862
855 FlowGraphInliner::SetInliningId(*callee_graph, 863 FlowGraphInliner::SetInliningId(callee_graph,
856 inliner_->NextInlineId(callee_graph->function())); 864 inliner_->NextInlineId(callee_graph->function(),
865 call_data->caller_inlining_id_));
857 // We allocate a ZoneHandle for the unoptimized code so that it cannot be 866 // We allocate a ZoneHandle for the unoptimized code so that it cannot be
858 // disconnected from its function during the rest of compilation. 867 // disconnected from its function during the rest of compilation.
859 Code::ZoneHandle(unoptimized_code.raw()); 868 Code::ZoneHandle(unoptimized_code.raw());
860 TRACE_INLINING(ISL_Print(" Success\n")); 869 TRACE_INLINING(ISL_Print(" Success\n"));
861 PRINT_INLINING_TREE(NULL, 870 PRINT_INLINING_TREE(NULL,
862 &call_data->caller, &function, call); 871 &call_data->caller, &function, call);
863 return true; 872 return true;
864 } else { 873 } else {
865 Error& error = Error::Handle(); 874 Error& error = Error::Handle();
866 error = isolate()->object_store()->sticky_error(); 875 error = isolate()->object_store()->sticky_error();
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
1047 } 1056 }
1048 const Function& target = call->function(); 1057 const Function& target = call->function();
1049 if (!inliner_->AlwaysInline(target) && 1058 if (!inliner_->AlwaysInline(target) &&
1050 (call_info[call_idx].ratio * 100) < FLAG_inlining_hotness) { 1059 (call_info[call_idx].ratio * 100) < FLAG_inlining_hotness) {
1051 TRACE_INLINING(ISL_Print( 1060 TRACE_INLINING(ISL_Print(
1052 " => %s (deopt count %d)\n Bailout: cold %f\n", 1061 " => %s (deopt count %d)\n Bailout: cold %f\n",
1053 target.ToCString(), 1062 target.ToCString(),
1054 target.deoptimization_counter(), 1063 target.deoptimization_counter(),
1055 call_info[call_idx].ratio)); 1064 call_info[call_idx].ratio));
1056 PRINT_INLINING_TREE("Too cold", 1065 PRINT_INLINING_TREE("Too cold",
1057 call_info[call_idx].caller, &call->function(), call); 1066 &call_info[call_idx].caller(), &call->function(), call);
1058 continue; 1067 continue;
1059 } 1068 }
1060 GrowableArray<Value*> arguments(call->ArgumentCount()); 1069 GrowableArray<Value*> arguments(call->ArgumentCount());
1061 for (int i = 0; i < call->ArgumentCount(); ++i) { 1070 for (int i = 0; i < call->ArgumentCount(); ++i) {
1062 arguments.Add(call->PushArgumentAt(i)->value()); 1071 arguments.Add(call->PushArgumentAt(i)->value());
1063 } 1072 }
1064 InlinedCallData call_data(call, &arguments, *call_info[call_idx].caller); 1073 InlinedCallData call_data(
1074 call, &arguments, call_info[call_idx].caller(),
1075 call_info[call_idx].caller_graph->inlining_id());
1065 if (TryInlining(call->function(), call->argument_names(), &call_data)) { 1076 if (TryInlining(call->function(), call->argument_names(), &call_data)) {
1066 InlineCall(&call_data); 1077 InlineCall(&call_data);
1067 } 1078 }
1068 } 1079 }
1069 } 1080 }
1070 1081
1071 void InlineClosureCalls() { 1082 void InlineClosureCalls() {
1072 const GrowableArray<CallSites::ClosureCallInfo>& call_info = 1083 const GrowableArray<CallSites::ClosureCallInfo>& call_info =
1073 inlining_call_sites_->closure_calls(); 1084 inlining_call_sites_->closure_calls();
1074 TRACE_INLINING(ISL_Print(" Closure Calls (%" Pd ")\n", 1085 TRACE_INLINING(ISL_Print(" Closure Calls (%" Pd ")\n",
(...skipping 18 matching lines...) Expand all
1093 } 1104 }
1094 1105
1095 if (target.IsNull()) { 1106 if (target.IsNull()) {
1096 TRACE_INLINING(ISL_Print(" Bailout: non-closure operator\n")); 1107 TRACE_INLINING(ISL_Print(" Bailout: non-closure operator\n"));
1097 continue; 1108 continue;
1098 } 1109 }
1099 GrowableArray<Value*> arguments(call->ArgumentCount()); 1110 GrowableArray<Value*> arguments(call->ArgumentCount());
1100 for (int i = 0; i < call->ArgumentCount(); ++i) { 1111 for (int i = 0; i < call->ArgumentCount(); ++i) {
1101 arguments.Add(call->PushArgumentAt(i)->value()); 1112 arguments.Add(call->PushArgumentAt(i)->value());
1102 } 1113 }
1103 InlinedCallData call_data(call, &arguments, *call_info[call_idx].caller); 1114 InlinedCallData call_data(
1115 call, &arguments, call_info[call_idx].caller(),
1116 call_info[call_idx].caller_graph->inlining_id());
1104 if (TryInlining(target, 1117 if (TryInlining(target,
1105 call->argument_names(), 1118 call->argument_names(),
1106 &call_data)) { 1119 &call_data)) {
1107 InlineCall(&call_data); 1120 InlineCall(&call_data);
1108 } 1121 }
1109 } 1122 }
1110 } 1123 }
1111 1124
1112 void InlineInstanceCalls() { 1125 void InlineInstanceCalls() {
1113 const GrowableArray<CallSites::InstanceCallInfo>& call_info = 1126 const GrowableArray<CallSites::InstanceCallInfo>& call_info =
1114 inlining_call_sites_->instance_calls(); 1127 inlining_call_sites_->instance_calls();
1115 TRACE_INLINING(ISL_Print(" Polymorphic Instance Calls (%" Pd ")\n", 1128 TRACE_INLINING(ISL_Print(" Polymorphic Instance Calls (%" Pd ")\n",
1116 call_info.length())); 1129 call_info.length()));
1117 for (intptr_t call_idx = 0; call_idx < call_info.length(); ++call_idx) { 1130 for (intptr_t call_idx = 0; call_idx < call_info.length(); ++call_idx) {
1118 PolymorphicInstanceCallInstr* call = call_info[call_idx].call; 1131 PolymorphicInstanceCallInstr* call = call_info[call_idx].call;
1119 if (call->with_checks()) { 1132 if (call->with_checks()) {
1120 const Function& cl = *call_info[call_idx].caller; 1133 const Function& cl = call_info[call_idx].caller();
1121 PolymorphicInliner inliner(this, call, cl); 1134 intptr_t caller_inlining_id =
1135 call_info[call_idx].caller_graph->inlining_id();
1136 PolymorphicInliner inliner(this, call, cl, caller_inlining_id);
1122 inliner.Inline(); 1137 inliner.Inline();
1123 continue; 1138 continue;
1124 } 1139 }
1125 1140
1126 const ICData& ic_data = call->ic_data(); 1141 const ICData& ic_data = call->ic_data();
1127 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0)); 1142 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0));
1128 if (!inliner_->AlwaysInline(target) && 1143 if (!inliner_->AlwaysInline(target) &&
1129 (call_info[call_idx].ratio * 100) < FLAG_inlining_hotness) { 1144 (call_info[call_idx].ratio * 100) < FLAG_inlining_hotness) {
1130 TRACE_INLINING(ISL_Print( 1145 TRACE_INLINING(ISL_Print(
1131 " => %s (deopt count %d)\n Bailout: cold %f\n", 1146 " => %s (deopt count %d)\n Bailout: cold %f\n",
1132 target.ToCString(), 1147 target.ToCString(),
1133 target.deoptimization_counter(), 1148 target.deoptimization_counter(),
1134 call_info[call_idx].ratio)); 1149 call_info[call_idx].ratio));
1135 PRINT_INLINING_TREE("Too cold", 1150 PRINT_INLINING_TREE("Too cold",
1136 call_info[call_idx].caller, &target, call); 1151 &call_info[call_idx].caller(), &target, call);
1137 continue; 1152 continue;
1138 } 1153 }
1139 GrowableArray<Value*> arguments(call->ArgumentCount()); 1154 GrowableArray<Value*> arguments(call->ArgumentCount());
1140 for (int arg_i = 0; arg_i < call->ArgumentCount(); ++arg_i) { 1155 for (int arg_i = 0; arg_i < call->ArgumentCount(); ++arg_i) {
1141 arguments.Add(call->PushArgumentAt(arg_i)->value()); 1156 arguments.Add(call->PushArgumentAt(arg_i)->value());
1142 } 1157 }
1143 InlinedCallData call_data(call, &arguments, *call_info[call_idx].caller); 1158 InlinedCallData call_data(
1159 call, &arguments, call_info[call_idx].caller(),
1160 call_info[call_idx].caller_graph->inlining_id());
1144 if (TryInlining(target, 1161 if (TryInlining(target,
1145 call->instance_call()->argument_names(), 1162 call->instance_call()->argument_names(),
1146 &call_data)) { 1163 &call_data)) {
1147 InlineCall(&call_data); 1164 InlineCall(&call_data);
1148 } 1165 }
1149 } 1166 }
1150 } 1167 }
1151 1168
1152 bool AdjustForOptionalParameters(const ParsedFunction& parsed_function, 1169 bool AdjustForOptionalParameters(const ParsedFunction& parsed_function,
1153 const Array& argument_names, 1170 const Array& argument_names,
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 CallSites* inlining_call_sites_; 1270 CallSites* inlining_call_sites_;
1254 GrowableArray<ParsedFunction*> function_cache_; 1271 GrowableArray<ParsedFunction*> function_cache_;
1255 GrowableArray<InlinedInfo> inlined_info_; 1272 GrowableArray<InlinedInfo> inlined_info_;
1256 1273
1257 DISALLOW_COPY_AND_ASSIGN(CallSiteInliner); 1274 DISALLOW_COPY_AND_ASSIGN(CallSiteInliner);
1258 }; 1275 };
1259 1276
1260 1277
1261 PolymorphicInliner::PolymorphicInliner(CallSiteInliner* owner, 1278 PolymorphicInliner::PolymorphicInliner(CallSiteInliner* owner,
1262 PolymorphicInstanceCallInstr* call, 1279 PolymorphicInstanceCallInstr* call,
1263 const Function& caller_function) 1280 const Function& caller_function,
1281 intptr_t caller_inlining_id)
1264 : owner_(owner), 1282 : owner_(owner),
1265 call_(call), 1283 call_(call),
1266 num_variants_(call->ic_data().NumberOfChecks()), 1284 num_variants_(call->ic_data().NumberOfChecks()),
1267 variants_(num_variants_), 1285 variants_(num_variants_),
1268 inlined_variants_(num_variants_), 1286 inlined_variants_(num_variants_),
1269 non_inlined_variants_(num_variants_), 1287 non_inlined_variants_(num_variants_),
1270 inlined_entries_(num_variants_), 1288 inlined_entries_(num_variants_),
1271 exit_collector_(new(Z) 1289 exit_collector_(new(Z)
1272 InlineExitCollector(owner->caller_graph(), call)), 1290 InlineExitCollector(owner->caller_graph(), call)),
1273 caller_function_(caller_function) { 1291 caller_function_(caller_function),
1292 caller_inlining_id_(caller_inlining_id) {
1274 } 1293 }
1275 1294
1276 1295
1277 Isolate* PolymorphicInliner::isolate() const { 1296 Isolate* PolymorphicInliner::isolate() const {
1278 return owner_->caller_graph()->isolate(); 1297 return owner_->caller_graph()->isolate();
1279 } 1298 }
1280 1299
1281 1300
1282 Zone* PolymorphicInliner::zone() const { 1301 Zone* PolymorphicInliner::zone() const {
1283 return owner_->caller_graph()->zone(); 1302 return owner_->caller_graph()->zone();
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1361 const Function& target) { 1380 const Function& target) {
1362 if (TryInlineRecognizedMethod(receiver_cid, target)) { 1381 if (TryInlineRecognizedMethod(receiver_cid, target)) {
1363 owner_->inlined_ = true; 1382 owner_->inlined_ = true;
1364 return true; 1383 return true;
1365 } 1384 }
1366 1385
1367 GrowableArray<Value*> arguments(call_->ArgumentCount()); 1386 GrowableArray<Value*> arguments(call_->ArgumentCount());
1368 for (int i = 0; i < call_->ArgumentCount(); ++i) { 1387 for (int i = 0; i < call_->ArgumentCount(); ++i) {
1369 arguments.Add(call_->PushArgumentAt(i)->value()); 1388 arguments.Add(call_->PushArgumentAt(i)->value());
1370 } 1389 }
1371 InlinedCallData call_data(call_, &arguments, caller_function_); 1390 InlinedCallData call_data(call_, &arguments,
1391 caller_function_,
1392 caller_inlining_id_);
1372 if (!owner_->TryInlining(target, 1393 if (!owner_->TryInlining(target,
1373 call_->instance_call()->argument_names(), 1394 call_->instance_call()->argument_names(),
1374 &call_data)) { 1395 &call_data)) {
1375 return false; 1396 return false;
1376 } 1397 }
1377 1398
1378 FlowGraph* callee_graph = call_data.callee_graph; 1399 FlowGraph* callee_graph = call_data.callee_graph;
1379 call_data.exit_collector->PrepareGraphs(callee_graph); 1400 call_data.exit_collector->PrepareGraphs(callee_graph);
1380 inlined_entries_.Add(callee_graph->graph_entry()); 1401 inlined_entries_.Add(callee_graph->graph_entry());
1381 exit_collector_->Union(call_data.exit_collector); 1402 exit_collector_->Union(call_data.exit_collector);
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
1739 1760
1740 1761
1741 static bool ShouldTraceInlining(FlowGraph* flow_graph) { 1762 static bool ShouldTraceInlining(FlowGraph* flow_graph) {
1742 const Function& top = flow_graph->parsed_function().function(); 1763 const Function& top = flow_graph->parsed_function().function();
1743 return FLAG_trace_inlining && FlowGraphPrinter::ShouldPrint(top); 1764 return FLAG_trace_inlining && FlowGraphPrinter::ShouldPrint(top);
1744 } 1765 }
1745 1766
1746 1767
1747 FlowGraphInliner::FlowGraphInliner( 1768 FlowGraphInliner::FlowGraphInliner(
1748 FlowGraph* flow_graph, 1769 FlowGraph* flow_graph,
1749 GrowableArray<const Function*>* inline_id_to_function) 1770 GrowableArray<const Function*>* inline_id_to_function,
1771 GrowableArray<intptr_t>* caller_inline_id)
1750 : flow_graph_(flow_graph), 1772 : flow_graph_(flow_graph),
1751 inline_id_to_function_(inline_id_to_function), 1773 inline_id_to_function_(inline_id_to_function),
1774 caller_inline_id_(caller_inline_id),
1752 trace_inlining_(ShouldTraceInlining(flow_graph)) { 1775 trace_inlining_(ShouldTraceInlining(flow_graph)) {
1753 } 1776 }
1754 1777
1755 1778
1756 void FlowGraphInliner::CollectGraphInfo(FlowGraph* flow_graph, bool force) { 1779 void FlowGraphInliner::CollectGraphInfo(FlowGraph* flow_graph, bool force) {
1757 const Function& function = flow_graph->function(); 1780 const Function& function = flow_graph->function();
1758 if (force || (function.optimized_instruction_count() == 0)) { 1781 if (force || (function.optimized_instruction_count() == 0)) {
1759 GraphInfoCollector info; 1782 GraphInfoCollector info;
1760 info.Collect(*flow_graph); 1783 info.Collect(*flow_graph);
1761 1784
1762 function.set_optimized_instruction_count( 1785 function.set_optimized_instruction_count(
1763 ClampUint16(info.instruction_count())); 1786 ClampUint16(info.instruction_count()));
1764 function.set_optimized_call_site_count(ClampUint16(info.call_site_count())); 1787 function.set_optimized_call_site_count(ClampUint16(info.call_site_count()));
1765 } 1788 }
1766 } 1789 }
1767 1790
1768 1791
1769 // TODO(srdjan): This is only needed when disassembling and/or profiling. 1792 // TODO(srdjan): This is only needed when disassembling and/or profiling.
1770 void FlowGraphInliner::SetInliningId(const FlowGraph& flow_graph, 1793 // Sets inlining id for all instructions of this flow-graph, as well for the
1794 // FlowGraph itself.
1795 void FlowGraphInliner::SetInliningId(FlowGraph* flow_graph,
1771 intptr_t inlining_id) { 1796 intptr_t inlining_id) {
1772 for (BlockIterator block_it = flow_graph.postorder_iterator(); 1797 ASSERT(flow_graph->inlining_id() < 0);
1798 flow_graph->set_inlining_id(inlining_id);
1799 for (BlockIterator block_it = flow_graph->postorder_iterator();
1773 !block_it.Done(); 1800 !block_it.Done();
1774 block_it.Advance()) { 1801 block_it.Advance()) {
1775 for (ForwardInstructionIterator it(block_it.Current()); 1802 for (ForwardInstructionIterator it(block_it.Current());
1776 !it.Done(); 1803 !it.Done();
1777 it.Advance()) { 1804 it.Advance()) {
1778 Instruction* current = it.Current(); 1805 Instruction* current = it.Current();
1779 // Do not overwrite owner function. 1806 // Do not overwrite owner function.
1780 ASSERT(!current->has_inlining_id()); 1807 ASSERT(!current->has_inlining_id());
1781 current->set_inlining_id(inlining_id); 1808 current->set_inlining_id(inlining_id);
1782 } 1809 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1839 ISL_Print("After Inlining of %s\n", flow_graph_-> 1866 ISL_Print("After Inlining of %s\n", flow_graph_->
1840 function().ToFullyQualifiedCString()); 1867 function().ToFullyQualifiedCString());
1841 FlowGraphPrinter printer(*flow_graph_); 1868 FlowGraphPrinter printer(*flow_graph_);
1842 printer.PrintBlocks(); 1869 printer.PrintBlocks();
1843 } 1870 }
1844 } 1871 }
1845 } 1872 }
1846 } 1873 }
1847 1874
1848 1875
1849 intptr_t FlowGraphInliner::NextInlineId(const Function& function) { 1876 intptr_t FlowGraphInliner::NextInlineId(const Function& function,
1877 intptr_t parent_id) {
1850 const intptr_t id = inline_id_to_function_->length(); 1878 const intptr_t id = inline_id_to_function_->length();
1851 inline_id_to_function_->Add(&function); 1879 inline_id_to_function_->Add(&function);
1880 caller_inline_id_->Add(parent_id);
1852 return id; 1881 return id;
1853 } 1882 }
1854 1883
1855 1884
1856 } // namespace dart 1885 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_inliner.h ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698