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

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

Issue 19223002: Always try to inline certain core library functions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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 | runtime/vm/intermediate_language.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/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 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 inlined_size_(0), 363 inlined_size_(0),
364 inlining_depth_(1), 364 inlining_depth_(1),
365 collected_call_sites_(NULL), 365 collected_call_sites_(NULL),
366 inlining_call_sites_(NULL), 366 inlining_call_sites_(NULL),
367 function_cache_(), 367 function_cache_(),
368 guarded_fields_(guarded_fields) { } 368 guarded_fields_(guarded_fields) { }
369 369
370 FlowGraph* caller_graph() const { return caller_graph_; } 370 FlowGraph* caller_graph() const { return caller_graph_; }
371 371
372 // Inlining heuristics based on Cooper et al. 2008. 372 // Inlining heuristics based on Cooper et al. 2008.
373 bool ShouldWeInline(intptr_t instr_count, 373 bool ShouldWeInline(const Function& callee,
374 intptr_t instr_count,
374 intptr_t call_site_count, 375 intptr_t call_site_count,
375 intptr_t const_arg_count) { 376 intptr_t const_arg_count) {
376 if (inlined_size_ > FLAG_inlining_caller_size_threshold) { 377 if (inlined_size_ > FLAG_inlining_caller_size_threshold) {
377 // Prevent methods becoming humongous and thus slow to compile. 378 // Prevent methods becoming humongous and thus slow to compile.
378 return false; 379 return false;
379 } 380 }
380 if (instr_count <= FLAG_inlining_size_threshold) { 381 if (instr_count <= FLAG_inlining_size_threshold) {
381 return true; 382 return true;
382 } 383 }
383 if (call_site_count <= FLAG_inlining_callee_call_sites_threshold) { 384 if (call_site_count <= FLAG_inlining_callee_call_sites_threshold) {
384 return true; 385 return true;
385 } 386 }
386 if ((const_arg_count >= FLAG_inlining_constant_arguments_count) && 387 if ((const_arg_count >= FLAG_inlining_constant_arguments_count) &&
387 (instr_count <= FLAG_inlining_constant_arguments_size_threshold)) { 388 (instr_count <= FLAG_inlining_constant_arguments_size_threshold)) {
388 return true; 389 return true;
389 } 390 }
391 if (MethodRecognizer::AlwaysInline(callee)) {
392 return true;
393 }
390 return false; 394 return false;
391 } 395 }
392 396
393 // TODO(srdjan): Handle large 'skip_static_call_deopt_ids'. Currently 397 // TODO(srdjan): Handle large 'skip_static_call_deopt_ids'. Currently
394 // max. size observed is 11 (dart2js). 398 // max. size observed is 11 (dart2js).
395 void InlineCalls() { 399 void InlineCalls() {
396 // If inlining depth is less then one abort. 400 // If inlining depth is less then one abort.
397 if (FLAG_inlining_depth_threshold < 1) return; 401 if (FLAG_inlining_depth_threshold < 1) return;
398 if (caller_graph_->parsed_function().function().deoptimization_counter() >= 402 if (caller_graph_->parsed_function().function().deoptimization_counter() >=
399 FLAG_deoptimization_counter_inlining_threshold) { 403 FLAG_deoptimization_counter_inlining_threshold) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 // Abort if this function has deoptimized too much. 459 // Abort if this function has deoptimized too much.
456 if (function.deoptimization_counter() >= 460 if (function.deoptimization_counter() >=
457 FLAG_deoptimization_counter_threshold) { 461 FLAG_deoptimization_counter_threshold) {
458 function.set_is_inlinable(false); 462 function.set_is_inlinable(false);
459 TRACE_INLINING(OS::Print(" Bailout: deoptimization threshold\n")); 463 TRACE_INLINING(OS::Print(" Bailout: deoptimization threshold\n"));
460 return false; 464 return false;
461 } 465 }
462 466
463 GrowableArray<Value*>* arguments = call_data->arguments; 467 GrowableArray<Value*>* arguments = call_data->arguments;
464 const intptr_t constant_arguments = CountConstants(*arguments); 468 const intptr_t constant_arguments = CountConstants(*arguments);
465 if (!ShouldWeInline(function.optimized_instruction_count(), 469 if (!ShouldWeInline(function,
470 function.optimized_instruction_count(),
466 function.optimized_call_site_count(), 471 function.optimized_call_site_count(),
467 constant_arguments)) { 472 constant_arguments)) {
468 TRACE_INLINING(OS::Print(" Bailout: early heuristics with " 473 TRACE_INLINING(OS::Print(" Bailout: early heuristics with "
469 "code size: %"Pd", " 474 "code size: %"Pd", "
470 "call sites: %"Pd", " 475 "call sites: %"Pd", "
471 "const args: %"Pd"\n", 476 "const args: %"Pd"\n",
472 function.optimized_instruction_count(), 477 function.optimized_instruction_count(),
473 function.optimized_call_site_count(), 478 function.optimized_call_site_count(),
474 constant_arguments)); 479 constant_arguments));
475 return false; 480 return false;
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 } 606 }
602 GraphInfoCollector info; 607 GraphInfoCollector info;
603 info.Collect(*callee_graph); 608 info.Collect(*callee_graph);
604 const intptr_t size = info.instruction_count(); 609 const intptr_t size = info.instruction_count();
605 const intptr_t call_site_count = info.call_site_count(); 610 const intptr_t call_site_count = info.call_site_count();
606 611
607 function.set_optimized_instruction_count(size); 612 function.set_optimized_instruction_count(size);
608 function.set_optimized_call_site_count(call_site_count); 613 function.set_optimized_call_site_count(call_site_count);
609 614
610 // Use heuristics do decide if this call should be inlined. 615 // Use heuristics do decide if this call should be inlined.
611 if (!ShouldWeInline(size, call_site_count, constants_count)) { 616 if (!ShouldWeInline(function, size, call_site_count, constants_count)) {
612 // If size is larger than all thresholds, don't consider it again. 617 // If size is larger than all thresholds, don't consider it again.
613 if ((size > FLAG_inlining_size_threshold) && 618 if ((size > FLAG_inlining_size_threshold) &&
614 (call_site_count > FLAG_inlining_callee_call_sites_threshold) && 619 (call_site_count > FLAG_inlining_callee_call_sites_threshold) &&
615 (size > FLAG_inlining_constant_arguments_size_threshold)) { 620 (size > FLAG_inlining_constant_arguments_size_threshold)) {
616 function.set_is_inlinable(false); 621 function.set_is_inlinable(false);
617 } 622 }
618 isolate->set_long_jump_base(base); 623 isolate->set_long_jump_base(base);
619 isolate->set_deopt_id(prev_deopt_id); 624 isolate->set_deopt_id(prev_deopt_id);
620 TRACE_INLINING(OS::Print(" Bailout: heuristics with " 625 TRACE_INLINING(OS::Print(" Bailout: heuristics with "
621 "code size: %"Pd", " 626 "code size: %"Pd", "
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 ASSERT(call->function().NumImplicitParameters() == 1); 748 ASSERT(call->function().NumImplicitParameters() == 1);
744 ASSERT(call->ArgumentCount() <= 2); 749 ASSERT(call->ArgumentCount() <= 2);
745 // Arg 0: Instantiator type arguments. 750 // Arg 0: Instantiator type arguments.
746 // Arg 1: Length (optional). 751 // Arg 1: Length (optional).
747 if ((call->ArgumentCount() == 2) && 752 if ((call->ArgumentCount() == 2) &&
748 (!call->PushArgumentAt(1)->value()->BindsToConstant())) { 753 (!call->PushArgumentAt(1)->value()->BindsToConstant())) {
749 // Do not inline since a non-constant argument was passed. 754 // Do not inline since a non-constant argument was passed.
750 continue; 755 continue;
751 } 756 }
752 } 757 }
753 if ((call_info[call_idx].ratio * 100) < FLAG_inlining_hotness) { 758 const Function& target = call->function();
754 const Function& target = call->function(); 759 if (!MethodRecognizer::AlwaysInline(target) &&
760 (call_info[call_idx].ratio * 100) < FLAG_inlining_hotness) {
755 TRACE_INLINING(OS::Print( 761 TRACE_INLINING(OS::Print(
756 " => %s (deopt count %d)\n Bailout: cold %f\n", 762 " => %s (deopt count %d)\n Bailout: cold %f\n",
757 target.ToCString(), 763 target.ToCString(),
758 target.deoptimization_counter(), 764 target.deoptimization_counter(),
759 call_info[call_idx].ratio)); 765 call_info[call_idx].ratio));
760 continue; 766 continue;
761 } 767 }
762 GrowableArray<Value*> arguments(call->ArgumentCount()); 768 GrowableArray<Value*> arguments(call->ArgumentCount());
763 for (int i = 0; i < call->ArgumentCount(); ++i) { 769 for (int i = 0; i < call->ArgumentCount(); ++i) {
764 arguments.Add(call->PushArgumentAt(i)->value()); 770 arguments.Add(call->PushArgumentAt(i)->value());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 for (intptr_t call_idx = 0; call_idx < call_info.length(); ++call_idx) { 811 for (intptr_t call_idx = 0; call_idx < call_info.length(); ++call_idx) {
806 PolymorphicInstanceCallInstr* call = call_info[call_idx].call; 812 PolymorphicInstanceCallInstr* call = call_info[call_idx].call;
807 if (call->with_checks()) { 813 if (call->with_checks()) {
808 PolymorphicInliner inliner(this, call); 814 PolymorphicInliner inliner(this, call);
809 inliner.Inline(); 815 inliner.Inline();
810 continue; 816 continue;
811 } 817 }
812 818
813 const ICData& ic_data = call->ic_data(); 819 const ICData& ic_data = call->ic_data();
814 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0)); 820 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0));
815 if ((call_info[call_idx].ratio * 100) < FLAG_inlining_hotness) { 821 if (!MethodRecognizer::AlwaysInline(target) &&
822 (call_info[call_idx].ratio * 100) < FLAG_inlining_hotness) {
816 TRACE_INLINING(OS::Print( 823 TRACE_INLINING(OS::Print(
817 " => %s (deopt count %d)\n Bailout: cold %f\n", 824 " => %s (deopt count %d)\n Bailout: cold %f\n",
818 target.ToCString(), 825 target.ToCString(),
819 target.deoptimization_counter(), 826 target.deoptimization_counter(),
820 call_info[call_idx].ratio)); 827 call_info[call_idx].ratio));
821 continue; 828 continue;
822 } 829 }
823 GrowableArray<Value*> arguments(call->ArgumentCount()); 830 GrowableArray<Value*> arguments(call->ArgumentCount());
824 for (int arg_i = 0; arg_i < call->ArgumentCount(); ++arg_i) { 831 for (int arg_i = 0; arg_i < call->ArgumentCount(); ++arg_i) {
825 arguments.Add(call->PushArgumentAt(arg_i)->value()); 832 arguments.Add(call->PushArgumentAt(arg_i)->value());
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after
1375 OS::Print("After Inlining of %s\n", flow_graph_-> 1382 OS::Print("After Inlining of %s\n", flow_graph_->
1376 parsed_function().function().ToFullyQualifiedCString()); 1383 parsed_function().function().ToFullyQualifiedCString());
1377 FlowGraphPrinter printer(*flow_graph_); 1384 FlowGraphPrinter printer(*flow_graph_);
1378 printer.PrintBlocks(); 1385 printer.PrintBlocks();
1379 } 1386 }
1380 } 1387 }
1381 } 1388 }
1382 } 1389 }
1383 1390
1384 } // namespace dart 1391 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698