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

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

Issue 258543002: Copy of Issue 247503003: Fix inline tree printing and add more information to it. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 8 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 | « no previous file | no next file » | 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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 DECLARE_FLAG(bool, print_flow_graph_optimized); 55 DECLARE_FLAG(bool, print_flow_graph_optimized);
56 DECLARE_FLAG(int, deoptimization_counter_threshold); 56 DECLARE_FLAG(int, deoptimization_counter_threshold);
57 DECLARE_FLAG(bool, verify_compiler); 57 DECLARE_FLAG(bool, verify_compiler);
58 DECLARE_FLAG(bool, compiler_stats); 58 DECLARE_FLAG(bool, compiler_stats);
59 59
60 #define TRACE_INLINING(statement) \ 60 #define TRACE_INLINING(statement) \
61 do { \ 61 do { \
62 if (FLAG_trace_inlining) statement; \ 62 if (FLAG_trace_inlining) statement; \
63 } while (false) 63 } while (false)
64 64
65 #define PRINT_INLINING_TREE(comment, caller, target, instance_call) \
66 do { \
67 if (FLAG_print_inlining_tree) { \
68 inlined_info_.Add(InlinedInfo( \
69 caller, target, inlining_depth_, instance_call, comment)); \
70 } \
71 } while (false) \
72
65 73
66 // Test if a call is recursive by looking in the deoptimization environment. 74 // Test if a call is recursive by looking in the deoptimization environment.
67 static bool IsCallRecursive(const Code& code, Definition* call) { 75 static bool IsCallRecursive(const Code& code, Definition* call) {
68 Environment* env = call->env(); 76 Environment* env = call->env();
69 while (env != NULL) { 77 while (env != NULL) {
70 if (code.raw() == env->code().raw()) { 78 if (code.raw() == env->code().raw()) {
71 return true; 79 return true;
72 } 80 }
73 env = env->outer(); 81 env = env->outer();
74 } 82 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 struct InlinedInfo { 168 struct InlinedInfo {
161 const Function* caller; 169 const Function* caller;
162 const Function* inlined; 170 const Function* inlined;
163 intptr_t inlined_depth; 171 intptr_t inlined_depth;
164 const Definition* call_instr; 172 const Definition* call_instr;
165 const char* bailout_reason; 173 const char* bailout_reason;
166 InlinedInfo(const Function* caller_function, 174 InlinedInfo(const Function* caller_function,
167 const Function* inlined_function, 175 const Function* inlined_function,
168 const intptr_t depth, 176 const intptr_t depth,
169 const Definition* call, 177 const Definition* call,
170 const char* reason = NULL) 178 const char* reason)
171 : caller(caller_function), 179 : caller(caller_function),
172 inlined(inlined_function), 180 inlined(inlined_function),
173 inlined_depth(depth), 181 inlined_depth(depth),
174 call_instr(call), 182 call_instr(call),
175 bailout_reason(reason) {} 183 bailout_reason(reason) {}
176 }; 184 };
177 185
178 186
179 // A collection of call sites to consider for inlining. 187 // A collection of call sites to consider for inlining.
180 class CallSites : public ValueObject { 188 class CallSites : public ValueObject {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 0.0 : static_cast<double>(instance_call_counts[i]) / max_count; 277 0.0 : static_cast<double>(instance_call_counts[i]) / max_count;
270 instance_calls_[i + instance_call_start_ix].ratio = ratio; 278 instance_calls_[i + instance_call_start_ix].ratio = ratio;
271 } 279 }
272 for (intptr_t i = 0; i < num_static_calls; ++i) { 280 for (intptr_t i = 0; i < num_static_calls; ++i) {
273 const double ratio = (max_count == 0) ? 281 const double ratio = (max_count == 0) ?
274 0.0 : static_cast<double>(static_call_counts[i]) / max_count; 282 0.0 : static_cast<double>(static_call_counts[i]) / max_count;
275 static_calls_[i + static_call_start_ix].ratio = ratio; 283 static_calls_[i + static_call_start_ix].ratio = ratio;
276 } 284 }
277 } 285 }
278 286
287 static void RecordAllNotInlinedFunction(
288 FlowGraph* graph,
289 intptr_t depth,
290 GrowableArray<InlinedInfo>* inlined_info) {
291 const Function* caller = &graph->parsed_function().function();
292 Function& target = Function::ZoneHandle();
293 for (BlockIterator block_it = graph->postorder_iterator();
294 !block_it.Done();
295 block_it.Advance()) {
296 for (ForwardInstructionIterator it(block_it.Current());
297 !it.Done();
298 it.Advance()) {
299 Instruction* current = it.Current();
300 Definition* call = NULL;
301 if (current->IsPolymorphicInstanceCall()) {
302 PolymorphicInstanceCallInstr* instance_call =
303 current->AsPolymorphicInstanceCall();
304 target = instance_call->ic_data().GetTargetAt(0);
305 call = instance_call;
306 } else if (current->IsStaticCall()) {
307 StaticCallInstr* static_call = current->AsStaticCall();
308 target = static_call->function().raw();
309 call = static_call;
310 } else if (current->IsClosureCall()) {
311 // TODO(srdjan): Add data for closure calls.
312 }
313 if (call != NULL) {
314 inlined_info->Add(InlinedInfo(
315 caller, &target, depth + 1, call, "Too deep"));
316 }
317 }
318 }
319 }
320
321
279 void FindCallSites(FlowGraph* graph, 322 void FindCallSites(FlowGraph* graph,
280 intptr_t depth, 323 intptr_t depth,
281 GrowableArray<InlinedInfo>* inlined_info) { 324 GrowableArray<InlinedInfo>* inlined_info) {
282 ASSERT(graph != NULL); 325 ASSERT(graph != NULL);
283 326 if (depth > FLAG_inlining_depth_threshold) {
284 if (depth > FLAG_inlining_depth_threshold) return; 327 if (FLAG_print_inlining_tree) {
328 RecordAllNotInlinedFunction(graph, depth, inlined_info);
329 }
330 return;
331 }
285 332
286 // Recognized methods are not treated as normal calls. They don't have 333 // Recognized methods are not treated as normal calls. They don't have
287 // calls in themselves, so we keep adding those even when at the threshold. 334 // calls in themselves, so we keep adding those even when at the threshold.
288 const bool inline_only_recognized_methods = 335 const bool inline_only_recognized_methods =
289 (depth == FLAG_inlining_depth_threshold); 336 (depth == FLAG_inlining_depth_threshold);
290 337
291 const intptr_t instance_call_start_ix = instance_calls_.length(); 338 const intptr_t instance_call_start_ix = instance_calls_.length();
292 const intptr_t static_call_start_ix = static_calls_.length(); 339 const intptr_t static_call_start_ix = static_calls_.length();
293 for (BlockIterator block_it = graph->postorder_iterator(); 340 for (BlockIterator block_it = graph->postorder_iterator();
294 !block_it.Done(); 341 !block_it.Done();
(...skipping 11 matching lines...) Expand all
306 instance_calls_.Add(InstanceCallInfo(instance_call, graph)); 353 instance_calls_.Add(InstanceCallInfo(instance_call, graph));
307 } else { 354 } else {
308 // Method not inlined because inlining too deep and method 355 // Method not inlined because inlining too deep and method
309 // not recognized. 356 // not recognized.
310 if (FLAG_print_inlining_tree) { 357 if (FLAG_print_inlining_tree) {
311 const Function* caller = &graph->parsed_function().function(); 358 const Function* caller = &graph->parsed_function().function();
312 const Function* target = 359 const Function* target =
313 &Function::ZoneHandle( 360 &Function::ZoneHandle(
314 instance_call->ic_data().GetTargetAt(0)); 361 instance_call->ic_data().GetTargetAt(0));
315 inlined_info->Add(InlinedInfo( 362 inlined_info->Add(InlinedInfo(
316 caller, target, depth, instance_call, "Too deep")); 363 caller, target, depth + 1, instance_call, "Too deep"));
317 } 364 }
318 } 365 }
319 } else if (current->IsStaticCall()) { 366 } else if (current->IsStaticCall()) {
320 StaticCallInstr* static_call = current->AsStaticCall(); 367 StaticCallInstr* static_call = current->AsStaticCall();
321 if (!inline_only_recognized_methods || 368 if (!inline_only_recognized_methods ||
322 static_call->function().is_recognized()) { 369 static_call->function().is_recognized()) {
323 static_calls_.Add(StaticCallInfo(static_call, graph)); 370 static_calls_.Add(StaticCallInfo(static_call, graph));
324 } else { 371 } else {
325 // Method not inlined because inlining too deep and method 372 // Method not inlined because inlining too deep and method
326 // not recognized. 373 // not recognized.
327 if (FLAG_print_inlining_tree) { 374 if (FLAG_print_inlining_tree) {
328 const Function* caller = &graph->parsed_function().function(); 375 const Function* caller = &graph->parsed_function().function();
329 const Function* target = &static_call->function(); 376 const Function* target = &static_call->function();
330 inlined_info->Add(InlinedInfo( 377 inlined_info->Add(InlinedInfo(
331 caller, target, depth, static_call, "Too deep")); 378 caller, target, depth + 1, static_call, "Too deep"));
332 } 379 }
333 } 380 }
334 } else if (current->IsClosureCall()) { 381 } else if (current->IsClosureCall()) {
335 if (!inline_only_recognized_methods) { 382 if (!inline_only_recognized_methods) {
336 ClosureCallInstr* closure_call = current->AsClosureCall(); 383 ClosureCallInstr* closure_call = current->AsClosureCall();
337 closure_calls_.Add(ClosureCallInfo(closure_call, graph)); 384 closure_calls_.Add(ClosureCallInfo(closure_call, graph));
338 } 385 }
339 } 386 }
340 } 387 }
341 } 388 }
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 const Array& argument_names, 542 const Array& argument_names,
496 InlinedCallData* call_data) { 543 InlinedCallData* call_data) {
497 TRACE_INLINING(OS::Print(" => %s (deopt count %d)\n", 544 TRACE_INLINING(OS::Print(" => %s (deopt count %d)\n",
498 function.ToCString(), 545 function.ToCString(),
499 function.deoptimization_counter())); 546 function.deoptimization_counter()));
500 547
501 // TODO(fschneider): Enable inlining inside try-blocks. 548 // TODO(fschneider): Enable inlining inside try-blocks.
502 if (call_data->call->GetBlock()->try_index() != 549 if (call_data->call->GetBlock()->try_index() !=
503 CatchClauseNode::kInvalidTryIndex) { 550 CatchClauseNode::kInvalidTryIndex) {
504 TRACE_INLINING(OS::Print(" Bailout: inside try-block\n")); 551 TRACE_INLINING(OS::Print(" Bailout: inside try-block\n"));
505 if (FLAG_print_inlining_tree) { 552 PRINT_INLINING_TREE("Inside try-block",
506 inlined_info_.Add(InlinedInfo( 553 &call_data->caller, &function, call_data->call);
507 &call_data->caller, &function, inlining_depth_, call_data->call,
508 "Inside try-block"));
509 }
510 return false; 554 return false;
511 } 555 }
512 556
513 // Make a handle for the unoptimized code so that it is not disconnected 557 // Make a handle for the unoptimized code so that it is not disconnected
514 // from the function while we are trying to inline it. 558 // from the function while we are trying to inline it.
515 const Code& unoptimized_code = Code::Handle(function.unoptimized_code()); 559 const Code& unoptimized_code = Code::Handle(function.unoptimized_code());
516 // Abort if the inlinable bit on the function is low. 560 // Abort if the inlinable bit on the function is low.
517 if (!function.IsInlineable()) { 561 if (!function.IsInlineable()) {
518 TRACE_INLINING(OS::Print(" Bailout: not inlinable\n")); 562 TRACE_INLINING(OS::Print(" Bailout: not inlinable\n"));
519 if (FLAG_print_inlining_tree) { 563 PRINT_INLINING_TREE("Not inlinable",
520 inlined_info_.Add(InlinedInfo( 564 &call_data->caller, &function, call_data->call);
521 &call_data->caller, &function, inlining_depth_, call_data->call,
522 "Not inlinable"));
523 }
524 return false; 565 return false;
525 } 566 }
526 567
527 // Abort if this function has deoptimized too much. 568 // Abort if this function has deoptimized too much.
528 if (function.deoptimization_counter() >= 569 if (function.deoptimization_counter() >=
529 FLAG_deoptimization_counter_threshold) { 570 FLAG_deoptimization_counter_threshold) {
530 function.set_is_inlinable(false); 571 function.set_is_inlinable(false);
531 TRACE_INLINING(OS::Print(" Bailout: deoptimization threshold\n")); 572 TRACE_INLINING(OS::Print(" Bailout: deoptimization threshold\n"));
532 if (FLAG_print_inlining_tree) { 573 PRINT_INLINING_TREE("Deoptimization threshold exceeded",
533 inlined_info_.Add(InlinedInfo( 574 &call_data->caller, &function, call_data->call);
534 &call_data->caller, &function, inlining_depth_, call_data->call,
535 "Deoptimization threshold exceeded"));
536 }
537 return false; 575 return false;
538 } 576 }
539 577
540 GrowableArray<Value*>* arguments = call_data->arguments; 578 GrowableArray<Value*>* arguments = call_data->arguments;
541 const intptr_t constant_arguments = CountConstants(*arguments); 579 const intptr_t constant_arguments = CountConstants(*arguments);
542 if (!ShouldWeInline(function, 580 if (!ShouldWeInline(function,
543 function.optimized_instruction_count(), 581 function.optimized_instruction_count(),
544 function.optimized_call_site_count(), 582 function.optimized_call_site_count(),
545 constant_arguments)) { 583 constant_arguments)) {
546 TRACE_INLINING(OS::Print(" Bailout: early heuristics with " 584 TRACE_INLINING(OS::Print(" Bailout: early heuristics with "
547 "code size: %" Pd ", " 585 "code size: %" Pd ", "
548 "call sites: %" Pd ", " 586 "call sites: %" Pd ", "
549 "const args: %" Pd "\n", 587 "const args: %" Pd "\n",
550 function.optimized_instruction_count(), 588 function.optimized_instruction_count(),
551 function.optimized_call_site_count(), 589 function.optimized_call_site_count(),
552 constant_arguments)); 590 constant_arguments));
553 if (FLAG_print_inlining_tree) { 591 PRINT_INLINING_TREE("Early heuristic",
554 inlined_info_.Add(InlinedInfo( 592 &call_data->caller, &function, call_data->call);
555 &call_data->caller, &function, inlining_depth_, call_data->call,
556 "Early heuristic"));
557 }
558 return false; 593 return false;
559 } 594 }
560 595
561 // Abort if this is a recursive occurrence. 596 // Abort if this is a recursive occurrence.
562 Definition* call = call_data->call; 597 Definition* call = call_data->call;
563 if (!FLAG_inline_recursive && IsCallRecursive(unoptimized_code, call)) { 598 if (!FLAG_inline_recursive && IsCallRecursive(unoptimized_code, call)) {
564 function.set_is_inlinable(false); 599 function.set_is_inlinable(false);
565 TRACE_INLINING(OS::Print(" Bailout: recursive function\n")); 600 TRACE_INLINING(OS::Print(" Bailout: recursive function\n"));
601 PRINT_INLINING_TREE("Recursive function",
602 &call_data->caller, &function, call_data->call);
566 return false; 603 return false;
567 } 604 }
568 605
569 Isolate* isolate = Isolate::Current(); 606 Isolate* isolate = Isolate::Current();
570 // Save and clear deopt id. 607 // Save and clear deopt id.
571 const intptr_t prev_deopt_id = isolate->deopt_id(); 608 const intptr_t prev_deopt_id = isolate->deopt_id();
572 isolate->set_deopt_id(0); 609 isolate->set_deopt_id(0);
573 // Install bailout jump. 610 // Install bailout jump.
574 LongJumpScope jump; 611 LongJumpScope jump;
575 if (setjmp(*jump.Set()) == 0) { 612 if (setjmp(*jump.Set()) == 0) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 // parameters. 662 // parameters.
626 if (function.HasOptionalParameters()) { 663 if (function.HasOptionalParameters()) {
627 TRACE_INLINING(OS::Print(" adjusting for optional parameters\n")); 664 TRACE_INLINING(OS::Print(" adjusting for optional parameters\n"));
628 if (!AdjustForOptionalParameters(*parsed_function, 665 if (!AdjustForOptionalParameters(*parsed_function,
629 argument_names, 666 argument_names,
630 arguments, 667 arguments,
631 param_stubs, 668 param_stubs,
632 callee_graph)) { 669 callee_graph)) {
633 function.set_is_inlinable(false); 670 function.set_is_inlinable(false);
634 TRACE_INLINING(OS::Print(" Bailout: optional arg mismatch\n")); 671 TRACE_INLINING(OS::Print(" Bailout: optional arg mismatch\n"));
672 PRINT_INLINING_TREE("Optional arg mismatch",
673 &call_data->caller, &function, call_data->call);
635 return false; 674 return false;
636 } 675 }
637 } 676 }
638 677
639 // After treating optional parameters the actual/formal count must match. 678 // After treating optional parameters the actual/formal count must match.
640 ASSERT(arguments->length() == function.NumParameters()); 679 ASSERT(arguments->length() == function.NumParameters());
641 ASSERT(param_stubs->length() == callee_graph->parameter_count()); 680 ASSERT(param_stubs->length() == callee_graph->parameter_count());
642 681
643 BlockScheduler block_scheduler(callee_graph); 682 BlockScheduler block_scheduler(callee_graph);
644 block_scheduler.AssignEdgeWeights(); 683 block_scheduler.AssignEdgeWeights();
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 function.set_is_inlinable(false); 738 function.set_is_inlinable(false);
700 } 739 }
701 isolate->set_deopt_id(prev_deopt_id); 740 isolate->set_deopt_id(prev_deopt_id);
702 TRACE_INLINING(OS::Print(" Bailout: heuristics with " 741 TRACE_INLINING(OS::Print(" Bailout: heuristics with "
703 "code size: %" Pd ", " 742 "code size: %" Pd ", "
704 "call sites: %" Pd ", " 743 "call sites: %" Pd ", "
705 "const args: %" Pd "\n", 744 "const args: %" Pd "\n",
706 size, 745 size,
707 call_site_count, 746 call_site_count,
708 constants_count)); 747 constants_count));
709 if (FLAG_print_inlining_tree) { 748 PRINT_INLINING_TREE("Heuristic fail",
710 inlined_info_.Add(InlinedInfo( 749 &call_data->caller, &function, call_data->call);
711 &call_data->caller, &function, inlining_depth_, call_data->call,
712 "Heuristic fail"));
713 }
714 return false; 750 return false;
715 } 751 }
716 752
717 if (function.IsInvokeFieldDispatcher() || 753 if (function.IsInvokeFieldDispatcher() ||
718 function.IsNoSuchMethodDispatcher()) { 754 function.IsNoSuchMethodDispatcher()) {
719 // Append call sites to the currently processed list so that dispatcher 755 // Append call sites to the currently processed list so that dispatcher
720 // methods get inlined regardless of the current depth. 756 // methods get inlined regardless of the current depth.
721 inlining_call_sites_->FindCallSites(callee_graph, 757 inlining_call_sites_->FindCallSites(callee_graph,
722 0, 758 0,
723 &inlined_info_); 759 &inlined_info_);
(...skipping 21 matching lines...) Expand all
745 // list of guarded fields. 781 // list of guarded fields.
746 for (intptr_t i = 0; i < callee_graph->guarded_fields()->length(); ++i) { 782 for (intptr_t i = 0; i < callee_graph->guarded_fields()->length(); ++i) {
747 FlowGraph::AddToGuardedFields(caller_graph_->guarded_fields(), 783 FlowGraph::AddToGuardedFields(caller_graph_->guarded_fields(),
748 (*callee_graph->guarded_fields())[i]); 784 (*callee_graph->guarded_fields())[i]);
749 } 785 }
750 786
751 // We allocate a ZoneHandle for the unoptimized code so that it cannot be 787 // We allocate a ZoneHandle for the unoptimized code so that it cannot be
752 // disconnected from its function during the rest of compilation. 788 // disconnected from its function during the rest of compilation.
753 Code::ZoneHandle(unoptimized_code.raw()); 789 Code::ZoneHandle(unoptimized_code.raw());
754 TRACE_INLINING(OS::Print(" Success\n")); 790 TRACE_INLINING(OS::Print(" Success\n"));
755 if (FLAG_print_inlining_tree) { 791 PRINT_INLINING_TREE(NULL,
756 inlined_info_.Add( 792 &call_data->caller, &function, call);
757 InlinedInfo(&call_data->caller, &function, inlining_depth_, call));
758 }
759 return true; 793 return true;
760 } else { 794 } else {
761 Error& error = Error::Handle(); 795 Error& error = Error::Handle();
762 error = isolate->object_store()->sticky_error(); 796 error = isolate->object_store()->sticky_error();
763 isolate->object_store()->clear_sticky_error(); 797 isolate->object_store()->clear_sticky_error();
764 isolate->set_deopt_id(prev_deopt_id); 798 isolate->set_deopt_id(prev_deopt_id);
765 TRACE_INLINING(OS::Print(" Bailout: %s\n", error.ToErrorCString())); 799 TRACE_INLINING(OS::Print(" Bailout: %s\n", error.ToErrorCString()));
800 PRINT_INLINING_TREE("Bailout",
801 &call_data->caller, &function, call);
766 return false; 802 return false;
767 } 803 }
768 } 804 }
769 805
770 void PrintInlinedInfo(const Function& top) { 806 void PrintInlinedInfo(const Function& top) {
771 if (inlined_info_.length() > 0) { 807 if (inlined_info_.length() > 0) {
772 OS::Print("Inlining into: '%s' growth: %f (%" Pd " -> %" Pd ")\n", 808 OS::Print("Inlining into: '%s' growth: %f (%" Pd " -> %" Pd ")\n",
773 top.ToFullyQualifiedCString(), 809 top.ToFullyQualifiedCString(),
774 GrowthFactor(), 810 GrowthFactor(),
775 initial_size_, 811 initial_size_,
776 inlined_size_); 812 inlined_size_);
777 PrintInlinedInfoFor(top, 1); 813 PrintInlinedInfoFor(top, 1);
778 } 814 }
779 } 815 }
780 816
781 private: 817 private:
782 friend class PolymorphicInliner; 818 friend class PolymorphicInliner;
783 819
784 void PrintInlinedInfoFor(const Function& caller, intptr_t depth) { 820 void PrintInlinedInfoFor(const Function& caller, intptr_t depth) {
785 // Print those that were inlined. 821 // Print those that were inlined.
786 for (intptr_t i = 0; i < inlined_info_.length(); i++) { 822 for (intptr_t i = 0; i < inlined_info_.length(); i++) {
787 const InlinedInfo& info = inlined_info_[i]; 823 const InlinedInfo& info = inlined_info_[i];
788 if (info.bailout_reason != NULL) continue; 824 if (info.bailout_reason != NULL) {
825 continue;
826 }
789 if ((info.inlined_depth == depth) && 827 if ((info.inlined_depth == depth) &&
790 (info.caller->raw() == caller.raw())) { 828 (info.caller->raw() == caller.raw())) {
791 for (int t = 0; t < depth; t++) { 829 for (int t = 0; t < depth; t++) {
792 OS::Print(" "); 830 OS::Print(" ");
793 } 831 }
794 OS::Print("%" Pd " %s\n", 832 OS::Print("%" Pd " %s\n",
795 info.call_instr->GetDeoptId(), 833 info.call_instr->GetDeoptId(),
796 info.inlined->ToQualifiedCString()); 834 info.inlined->ToQualifiedCString());
797 PrintInlinedInfoFor(*info.inlined, depth + 1); 835 PrintInlinedInfoFor(*info.inlined, depth + 1);
798 } 836 }
799 } 837 }
800 // Print those that were not inlined. 838 // Print those that were not inlined.
801 for (intptr_t i = 0; i < inlined_info_.length(); i++) { 839 for (intptr_t i = 0; i < inlined_info_.length(); i++) {
802 const InlinedInfo& info = inlined_info_[i]; 840 const InlinedInfo& info = inlined_info_[i];
803 if (info.bailout_reason == NULL) continue; 841 if (info.bailout_reason == NULL) {
842 continue;
843 }
804 if ((info.inlined_depth == depth) && 844 if ((info.inlined_depth == depth) &&
805 (info.caller->raw() == caller.raw())) { 845 (info.caller->raw() == caller.raw())) {
806 for (int t = 0; t < depth; t++) { 846 for (int t = 0; t < depth; t++) {
807 OS::Print(" "); 847 OS::Print(" ");
808 } 848 }
809 OS::Print("NO %" Pd " %s - %s\n", 849 OS::Print("NO %" Pd " %s - %s\n",
810 info.call_instr->GetDeoptId(), 850 info.call_instr->GetDeoptId(),
811 info.inlined->ToQualifiedCString(), 851 info.inlined->ToQualifiedCString(),
812 info.bailout_reason); 852 info.bailout_reason);
813 } 853 }
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 } 963 }
924 } 964 }
925 const Function& target = call->function(); 965 const Function& target = call->function();
926 if (!FlowGraphInliner::AlwaysInline(target) && 966 if (!FlowGraphInliner::AlwaysInline(target) &&
927 (call_info[call_idx].ratio * 100) < FLAG_inlining_hotness) { 967 (call_info[call_idx].ratio * 100) < FLAG_inlining_hotness) {
928 TRACE_INLINING(OS::Print( 968 TRACE_INLINING(OS::Print(
929 " => %s (deopt count %d)\n Bailout: cold %f\n", 969 " => %s (deopt count %d)\n Bailout: cold %f\n",
930 target.ToCString(), 970 target.ToCString(),
931 target.deoptimization_counter(), 971 target.deoptimization_counter(),
932 call_info[call_idx].ratio)); 972 call_info[call_idx].ratio));
933 if (FLAG_print_inlining_tree) { 973 PRINT_INLINING_TREE("Too cold",
934 inlined_info_.Add(InlinedInfo( 974 call_info[call_idx].caller, &call->function(), call);
935 call_info[call_idx].caller,
936 &call->function(),
937 inlining_depth_,
938 call,
939 "Too cold"));
940 }
941 continue; 975 continue;
942 } 976 }
943 GrowableArray<Value*> arguments(call->ArgumentCount()); 977 GrowableArray<Value*> arguments(call->ArgumentCount());
944 for (int i = 0; i < call->ArgumentCount(); ++i) { 978 for (int i = 0; i < call->ArgumentCount(); ++i) {
945 arguments.Add(call->PushArgumentAt(i)->value()); 979 arguments.Add(call->PushArgumentAt(i)->value());
946 } 980 }
947 InlinedCallData call_data(call, &arguments, *call_info[call_idx].caller); 981 InlinedCallData call_data(call, &arguments, *call_info[call_idx].caller);
948 if (TryInlining(call->function(), call->argument_names(), &call_data)) { 982 if (TryInlining(call->function(), call->argument_names(), &call_data)) {
949 InlineCall(&call_data); 983 InlineCall(&call_data);
950 } 984 }
(...skipping 11 matching lines...) Expand all
962 ASSERT(call->ArgumentCount() > 0); 996 ASSERT(call->ArgumentCount() > 0);
963 Function& target = Function::ZoneHandle(); 997 Function& target = Function::ZoneHandle();
964 AllocateObjectInstr* alloc = 998 AllocateObjectInstr* alloc =
965 call->ArgumentAt(0)->AsAllocateObject(); 999 call->ArgumentAt(0)->AsAllocateObject();
966 if ((alloc != NULL) && !alloc->closure_function().IsNull()) { 1000 if ((alloc != NULL) && !alloc->closure_function().IsNull()) {
967 target ^= alloc->closure_function().raw(); 1001 target ^= alloc->closure_function().raw();
968 ASSERT(target.signature_class() == alloc->cls().raw()); 1002 ASSERT(target.signature_class() == alloc->cls().raw());
969 } 1003 }
970 if (target.IsNull()) { 1004 if (target.IsNull()) {
971 TRACE_INLINING(OS::Print(" Bailout: non-closure operator\n")); 1005 TRACE_INLINING(OS::Print(" Bailout: non-closure operator\n"));
1006 PRINT_INLINING_TREE("Non-closure operator",
1007 call_info[call_idx].caller, &target, call);
972 continue; 1008 continue;
973 } 1009 }
974 GrowableArray<Value*> arguments(call->ArgumentCount()); 1010 GrowableArray<Value*> arguments(call->ArgumentCount());
975 for (int i = 0; i < call->ArgumentCount(); ++i) { 1011 for (int i = 0; i < call->ArgumentCount(); ++i) {
976 arguments.Add(call->PushArgumentAt(i)->value()); 1012 arguments.Add(call->PushArgumentAt(i)->value());
977 } 1013 }
978 InlinedCallData call_data(call, &arguments, *call_info[call_idx].caller); 1014 InlinedCallData call_data(call, &arguments, *call_info[call_idx].caller);
979 if (TryInlining(target, 1015 if (TryInlining(target,
980 call->argument_names(), 1016 call->argument_names(),
981 &call_data)) { 1017 &call_data)) {
(...skipping 18 matching lines...) Expand all
1000 1036
1001 const ICData& ic_data = call->ic_data(); 1037 const ICData& ic_data = call->ic_data();
1002 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0)); 1038 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0));
1003 if (!FlowGraphInliner::AlwaysInline(target) && 1039 if (!FlowGraphInliner::AlwaysInline(target) &&
1004 (call_info[call_idx].ratio * 100) < FLAG_inlining_hotness) { 1040 (call_info[call_idx].ratio * 100) < FLAG_inlining_hotness) {
1005 TRACE_INLINING(OS::Print( 1041 TRACE_INLINING(OS::Print(
1006 " => %s (deopt count %d)\n Bailout: cold %f\n", 1042 " => %s (deopt count %d)\n Bailout: cold %f\n",
1007 target.ToCString(), 1043 target.ToCString(),
1008 target.deoptimization_counter(), 1044 target.deoptimization_counter(),
1009 call_info[call_idx].ratio)); 1045 call_info[call_idx].ratio));
1010 if (FLAG_print_inlining_tree) { 1046 PRINT_INLINING_TREE("Too cold",
1011 inlined_info_.Add(InlinedInfo( 1047 call_info[call_idx].caller, &target, call);
1012 call_info[call_idx].caller,
1013 &target,
1014 inlining_depth_,
1015 call,
1016 "Too cold"));
1017 }
1018 continue; 1048 continue;
1019 } 1049 }
1020 GrowableArray<Value*> arguments(call->ArgumentCount()); 1050 GrowableArray<Value*> arguments(call->ArgumentCount());
1021 for (int arg_i = 0; arg_i < call->ArgumentCount(); ++arg_i) { 1051 for (int arg_i = 0; arg_i < call->ArgumentCount(); ++arg_i) {
1022 arguments.Add(call->PushArgumentAt(arg_i)->value()); 1052 arguments.Add(call->PushArgumentAt(arg_i)->value());
1023 } 1053 }
1024 InlinedCallData call_data(call, &arguments, *call_info[call_idx].caller); 1054 InlinedCallData call_data(call, &arguments, *call_info[call_idx].caller);
1025 if (TryInlining(target, 1055 if (TryInlining(target,
1026 call->instance_call()->argument_names(), 1056 call->instance_call()->argument_names(),
1027 &call_data)) { 1057 &call_data)) {
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after
1659 OS::Print("After Inlining of %s\n", flow_graph_-> 1689 OS::Print("After Inlining of %s\n", flow_graph_->
1660 parsed_function().function().ToFullyQualifiedCString()); 1690 parsed_function().function().ToFullyQualifiedCString());
1661 FlowGraphPrinter printer(*flow_graph_); 1691 FlowGraphPrinter printer(*flow_graph_);
1662 printer.PrintBlocks(); 1692 printer.PrintBlocks();
1663 } 1693 }
1664 } 1694 }
1665 } 1695 }
1666 } 1696 }
1667 1697
1668 } // namespace dart 1698 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698