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

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

Issue 24096018: Fix bug in field type tracking and polymorphic inlining. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 3 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/flow_graph_optimizer.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 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 374
375 GrowableArray<CidTarget> inlined_variants_; 375 GrowableArray<CidTarget> inlined_variants_;
376 GrowableArray<CidTarget> non_inlined_variants_; 376 GrowableArray<CidTarget> non_inlined_variants_;
377 GrowableArray<BlockEntryInstr*> inlined_entries_; 377 GrowableArray<BlockEntryInstr*> inlined_entries_;
378 InlineExitCollector* exit_collector_; 378 InlineExitCollector* exit_collector_;
379 }; 379 };
380 380
381 381
382 class CallSiteInliner : public ValueObject { 382 class CallSiteInliner : public ValueObject {
383 public: 383 public:
384 CallSiteInliner(FlowGraph* flow_graph, 384 explicit CallSiteInliner(FlowGraph* flow_graph)
385 GrowableArray<const Field*>* guarded_fields)
386 : caller_graph_(flow_graph), 385 : caller_graph_(flow_graph),
387 inlined_(false), 386 inlined_(false),
388 initial_size_(flow_graph->InstructionCount()), 387 initial_size_(flow_graph->InstructionCount()),
389 inlined_size_(0), 388 inlined_size_(0),
390 inlining_depth_(1), 389 inlining_depth_(1),
391 collected_call_sites_(NULL), 390 collected_call_sites_(NULL),
392 inlining_call_sites_(NULL), 391 inlining_call_sites_(NULL),
393 function_cache_(), 392 function_cache_() { }
394 guarded_fields_(guarded_fields) { }
395 393
396 FlowGraph* caller_graph() const { return caller_graph_; } 394 FlowGraph* caller_graph() const { return caller_graph_; }
397 395
398 // Inlining heuristics based on Cooper et al. 2008. 396 // Inlining heuristics based on Cooper et al. 2008.
399 bool ShouldWeInline(const Function& callee, 397 bool ShouldWeInline(const Function& callee,
400 intptr_t instr_count, 398 intptr_t instr_count,
401 intptr_t call_site_count, 399 intptr_t call_site_count,
402 intptr_t const_arg_count) { 400 intptr_t const_arg_count) {
403 if (inlined_size_ > FLAG_inlining_caller_size_threshold) { 401 if (inlined_size_ > FLAG_inlining_caller_size_threshold) {
404 // Prevent methods becoming humongous and thus slow to compile. 402 // Prevent methods becoming humongous and thus slow to compile.
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 Array& ic_data_array = Array::Handle(); 534 Array& ic_data_array = Array::Handle();
537 if (function.HasCode()) { 535 if (function.HasCode()) {
538 const Code& unoptimized_code = 536 const Code& unoptimized_code =
539 Code::Handle(function.unoptimized_code()); 537 Code::Handle(function.unoptimized_code());
540 ic_data_array = unoptimized_code.ExtractTypeFeedbackArray(); 538 ic_data_array = unoptimized_code.ExtractTypeFeedbackArray();
541 } 539 }
542 540
543 // Build the callee graph. 541 // Build the callee graph.
544 InlineExitCollector* exit_collector = 542 InlineExitCollector* exit_collector =
545 new InlineExitCollector(caller_graph_, call); 543 new InlineExitCollector(caller_graph_, call);
544 GrowableArray<const Field*> inlined_guarded_fields;
546 FlowGraphBuilder builder(parsed_function, 545 FlowGraphBuilder builder(parsed_function,
547 ic_data_array, 546 ic_data_array,
548 exit_collector, 547 exit_collector,
548 &inlined_guarded_fields,
549 Isolate::kNoDeoptId); 549 Isolate::kNoDeoptId);
550 builder.SetInitialBlockId(caller_graph_->max_block_id()); 550 builder.SetInitialBlockId(caller_graph_->max_block_id());
551 FlowGraph* callee_graph; 551 FlowGraph* callee_graph;
552 { 552 {
553 TimerScope timer(FLAG_compiler_stats, 553 TimerScope timer(FLAG_compiler_stats,
554 &CompilerStats::graphinliner_build_timer, 554 &CompilerStats::graphinliner_build_timer,
555 isolate); 555 isolate);
556 callee_graph = builder.BuildGraph(); 556 callee_graph = builder.BuildGraph();
557 } 557 }
558 558
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 callee_graph->ComputeSSA(caller_graph_->max_virtual_register_number(), 599 callee_graph->ComputeSSA(caller_graph_->max_virtual_register_number(),
600 param_stubs); 600 param_stubs);
601 DEBUG_ASSERT(callee_graph->VerifyUseLists()); 601 DEBUG_ASSERT(callee_graph->VerifyUseLists());
602 } 602 }
603 603
604 { 604 {
605 TimerScope timer(FLAG_compiler_stats, 605 TimerScope timer(FLAG_compiler_stats,
606 &CompilerStats::graphinliner_opt_timer, 606 &CompilerStats::graphinliner_opt_timer,
607 isolate); 607 isolate);
608 // TODO(zerny): Do more optimization passes on the callee graph. 608 // TODO(zerny): Do more optimization passes on the callee graph.
609 FlowGraphOptimizer optimizer(callee_graph, guarded_fields_); 609 FlowGraphOptimizer optimizer(callee_graph);
610 optimizer.ApplyICData(); 610 optimizer.ApplyICData();
611 DEBUG_ASSERT(callee_graph->VerifyUseLists()); 611 DEBUG_ASSERT(callee_graph->VerifyUseLists());
612 } 612 }
613 613
614 if (FLAG_trace_inlining && 614 if (FLAG_trace_inlining &&
615 (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized)) { 615 (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized)) {
616 OS::Print("Callee graph for inlining %s\n", 616 OS::Print("Callee graph for inlining %s\n",
617 function.ToFullyQualifiedCString()); 617 function.ToFullyQualifiedCString());
618 FlowGraphPrinter printer(*callee_graph); 618 FlowGraphPrinter printer(*callee_graph);
619 printer.PrintBlocks(); 619 printer.PrintBlocks();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 660
661 // Build succeeded so we restore the bailout jump. 661 // Build succeeded so we restore the bailout jump.
662 inlined_ = true; 662 inlined_ = true;
663 inlined_size_ += size; 663 inlined_size_ += size;
664 isolate->set_long_jump_base(base); 664 isolate->set_long_jump_base(base);
665 isolate->set_deopt_id(prev_deopt_id); 665 isolate->set_deopt_id(prev_deopt_id);
666 666
667 call_data->callee_graph = callee_graph; 667 call_data->callee_graph = callee_graph;
668 call_data->parameter_stubs = param_stubs; 668 call_data->parameter_stubs = param_stubs;
669 call_data->exit_collector = exit_collector; 669 call_data->exit_collector = exit_collector;
670
671 // When inlined, we add the guarded fields of the callee to the caller's
672 // list of guarded fields.
673 for (intptr_t i = 0; i < inlined_guarded_fields.length(); ++i) {
674 caller_graph_->builder().AddToGuardedFields(*inlined_guarded_fields[i]);
675 }
676
670 TRACE_INLINING(OS::Print(" Success\n")); 677 TRACE_INLINING(OS::Print(" Success\n"));
671 return true; 678 return true;
672 } else { 679 } else {
673 Error& error = Error::Handle(); 680 Error& error = Error::Handle();
674 error = isolate->object_store()->sticky_error(); 681 error = isolate->object_store()->sticky_error();
675 isolate->object_store()->clear_sticky_error(); 682 isolate->object_store()->clear_sticky_error();
676 isolate->set_long_jump_base(base); 683 isolate->set_long_jump_base(base);
677 isolate->set_deopt_id(prev_deopt_id); 684 isolate->set_deopt_id(prev_deopt_id);
678 TRACE_INLINING(OS::Print(" Bailout: %s\n", error.ToErrorCString())); 685 TRACE_INLINING(OS::Print(" Bailout: %s\n", error.ToErrorCString()));
679 return false; 686 return false;
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 995
989 996
990 FlowGraph* caller_graph_; 997 FlowGraph* caller_graph_;
991 bool inlined_; 998 bool inlined_;
992 intptr_t initial_size_; 999 intptr_t initial_size_;
993 intptr_t inlined_size_; 1000 intptr_t inlined_size_;
994 intptr_t inlining_depth_; 1001 intptr_t inlining_depth_;
995 CallSites* collected_call_sites_; 1002 CallSites* collected_call_sites_;
996 CallSites* inlining_call_sites_; 1003 CallSites* inlining_call_sites_;
997 GrowableArray<ParsedFunction*> function_cache_; 1004 GrowableArray<ParsedFunction*> function_cache_;
998 GrowableArray<const Field*>* guarded_fields_;
999 1005
1000 DISALLOW_COPY_AND_ASSIGN(CallSiteInliner); 1006 DISALLOW_COPY_AND_ASSIGN(CallSiteInliner);
1001 }; 1007 };
1002 1008
1003 1009
1004 PolymorphicInliner::PolymorphicInliner(CallSiteInliner* owner, 1010 PolymorphicInliner::PolymorphicInliner(CallSiteInliner* owner,
1005 PolymorphicInstanceCallInstr* call) 1011 PolymorphicInstanceCallInstr* call)
1006 : owner_(owner), 1012 : owner_(owner),
1007 call_(call), 1013 call_(call),
1008 num_variants_(call->ic_data().NumberOfChecks()), 1014 num_variants_(call->ic_data().NumberOfChecks()),
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
1424 flow_graph_->parsed_function().function().ToCString())); 1430 flow_graph_->parsed_function().function().ToCString()));
1425 1431
1426 if (FLAG_trace_inlining && 1432 if (FLAG_trace_inlining &&
1427 (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized)) { 1433 (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized)) {
1428 OS::Print("Before Inlining of %s\n", flow_graph_-> 1434 OS::Print("Before Inlining of %s\n", flow_graph_->
1429 parsed_function().function().ToFullyQualifiedCString()); 1435 parsed_function().function().ToFullyQualifiedCString());
1430 FlowGraphPrinter printer(*flow_graph_); 1436 FlowGraphPrinter printer(*flow_graph_);
1431 printer.PrintBlocks(); 1437 printer.PrintBlocks();
1432 } 1438 }
1433 1439
1434 CallSiteInliner inliner(flow_graph_, guarded_fields_); 1440 CallSiteInliner inliner(flow_graph_);
1435 inliner.InlineCalls(); 1441 inliner.InlineCalls();
1436 1442
1437 if (inliner.inlined()) { 1443 if (inliner.inlined()) {
1438 flow_graph_->DiscoverBlocks(); 1444 flow_graph_->DiscoverBlocks();
1439 if (FLAG_trace_inlining) { 1445 if (FLAG_trace_inlining) {
1440 OS::Print("Inlining growth factor: %f\n", inliner.GrowthFactor()); 1446 OS::Print("Inlining growth factor: %f\n", inliner.GrowthFactor());
1441 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) { 1447 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) {
1442 OS::Print("After Inlining of %s\n", flow_graph_-> 1448 OS::Print("After Inlining of %s\n", flow_graph_->
1443 parsed_function().function().ToFullyQualifiedCString()); 1449 parsed_function().function().ToFullyQualifiedCString());
1444 FlowGraphPrinter printer(*flow_graph_); 1450 FlowGraphPrinter printer(*flow_graph_);
1445 printer.PrintBlocks(); 1451 printer.PrintBlocks();
1446 } 1452 }
1447 } 1453 }
1448 } 1454 }
1449 } 1455 }
1450 1456
1451 } // namespace dart 1457 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_inliner.h ('k') | runtime/vm/flow_graph_optimizer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698