Flutter Engine
The Flutter Engine
Public Member Functions | Static Public Member Functions | Friends | List of all members
dart::FlowGraphInliner Class Reference

#include <inliner.h>

Inheritance diagram for dart::FlowGraphInliner:
dart::ValueObject

Public Member Functions

 FlowGraphInliner (FlowGraph *flow_graph, GrowableArray< const Function * > *inline_id_to_function, GrowableArray< TokenPosition > *inline_id_to_token_pos, GrowableArray< intptr_t > *caller_inline_id, SpeculativeInliningPolicy *speculative_policy, Precompiler *precompiler)
 
int Inline ()
 
bool AlwaysInline (const Function &function)
 
FlowGraphflow_graph () const
 
intptr_t NextInlineId (const Function &function, const InstructionSource &source)
 
bool trace_inlining () const
 
SpeculativeInliningPolicyspeculative_policy ()
 

Static Public Member Functions

static void CollectGraphInfo (FlowGraph *flow_graph, intptr_t num_constant_args, bool force, intptr_t *instruction_count, intptr_t *call_site_count)
 
static void SetInliningId (FlowGraph *flow_graph, intptr_t inlining_id)
 
static bool FunctionHasPreferInlinePragma (const Function &function)
 
static bool FunctionHasNeverInlinePragma (const Function &function)
 
static bool FunctionHasAlwaysConsiderInliningPragma (const Function &function)
 

Friends

class CallSiteInliner
 

Detailed Description

Definition at line 92 of file inliner.h.

Constructor & Destructor Documentation

◆ FlowGraphInliner()

dart::FlowGraphInliner::FlowGraphInliner ( FlowGraph flow_graph,
GrowableArray< const Function * > *  inline_id_to_function,
GrowableArray< TokenPosition > *  inline_id_to_token_pos,
GrowableArray< intptr_t > *  caller_inline_id,
SpeculativeInliningPolicy speculative_policy,
Precompiler precompiler 
)

Definition at line 2400 of file inliner.cc.

2407 : flow_graph_(flow_graph),
2408 inline_id_to_function_(inline_id_to_function),
2409 inline_id_to_token_pos_(inline_id_to_token_pos),
2410 caller_inline_id_(caller_inline_id),
2411 trace_inlining_(FLAG_trace_inlining && flow_graph->should_print()),
2412 speculative_policy_(speculative_policy),
2413 precompiler_(precompiler) {}
SpeculativeInliningPolicy * speculative_policy()
Definition: inliner.h:134
FlowGraph * flow_graph() const
Definition: inliner.h:128
bool should_print() const
Definition: flow_graph.h:503

Member Function Documentation

◆ AlwaysInline()

bool dart::FlowGraphInliner::AlwaysInline ( const Function function)

Definition at line 2512 of file inliner.cc.

2512 {
2515 THR_Print("vm:prefer-inline pragma for %s\n", function.ToCString()));
2516 return true;
2517 }
2518
2519 COMPILER_TIMINGS_TIMER_SCOPE(dart::Thread::Current(), MakeInliningDecision);
2520 // We don't want to inline DIFs for recognized methods because we would rather
2521 // replace them with inline FG before inlining introduces any superfluous
2522 // AssertAssignable instructions.
2523 if (function.IsDispatcherOrImplicitAccessor() &&
2524 !(function.kind() == UntaggedFunction::kDynamicInvocationForwarder &&
2525 function.IsRecognized())) {
2526 // Smaller or same size as the call.
2527 return true;
2528 }
2529
2530 if (function.is_const()) {
2531 // Inlined const fields are smaller than a call.
2532 return true;
2533 }
2534
2535 if (function.IsMethodExtractor()) {
2536 // Tear-off closure allocation has about the same size as the call.
2537 return true;
2538 }
2539
2540 if (function.IsGetterFunction() || function.IsSetterFunction() ||
2542 (function.kind() == UntaggedFunction::kConstructor)) {
2543 const intptr_t count = function.optimized_instruction_count();
2544 if ((count != 0) && (count < FLAG_inline_getters_setters_smaller_than)) {
2545 return true;
2546 }
2547 }
2548 return false;
2549}
int count
Definition: FontMgrTest.cpp:50
static bool FunctionHasPreferInlinePragma(const Function &function)
Definition: inliner.cc:2475
static Thread * Current()
Definition: thread.h:362
#define COMPILER_TIMINGS_TIMER_SCOPE(thread, timer_id)
#define THR_Print(format,...)
Definition: log.h:20
Dart_NativeFunction function
Definition: fuchsia.cc:51
#define TRACE_INLINING(statement)
Definition: inliner.cc:90
static bool IsInlineableOperator(const Function &function)
Definition: inliner.cc:2468

◆ CollectGraphInfo()

void dart::FlowGraphInliner::CollectGraphInfo ( FlowGraph flow_graph,
intptr_t  num_constant_args,
bool  force,
intptr_t *  instruction_count,
intptr_t *  call_site_count 
)
static

Definition at line 2415 of file inliner.cc.

2419 {
2421 const Function& function = flow_graph->function();
2422 // For OSR, don't even bother.
2424 *instruction_count = 0;
2425 *call_site_count = 0;
2426 return;
2427 }
2428 // Specialized case: always recompute, never cache.
2429 if (constants_count > 0) {
2430 ASSERT(!force);
2431 GraphInfoCollector info;
2432 info.Collect(*flow_graph);
2433 *instruction_count = info.instruction_count();
2434 *call_site_count = info.call_site_count();
2435 return;
2436 }
2437 // Non-specialized case: unless forced, only recompute on a cache miss.
2438 ASSERT(constants_count == 0);
2439 if (force || (function.optimized_instruction_count() == 0)) {
2440 GraphInfoCollector info;
2441 info.Collect(*flow_graph);
2442 function.SetOptimizedInstructionCountClamped(info.instruction_count());
2443 function.SetOptimizedCallSiteCountClamped(info.call_site_count());
2444 }
2445 *instruction_count = function.optimized_instruction_count();
2446 *call_site_count = function.optimized_call_site_count();
2447}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
static void CollectGraphInfo(FlowGraph *flow_graph, intptr_t num_constant_args, bool force, intptr_t *instruction_count, intptr_t *call_site_count)
Definition: inliner.cc:2415
bool IsCompiledForOsr() const
Definition: flow_graph.h:460
Thread * thread() const
Definition: flow_graph.h:260
const Function & function() const
Definition: flow_graph.h:130
#define ASSERT(E)

◆ flow_graph()

FlowGraph * dart::FlowGraphInliner::flow_graph ( ) const
inline

Definition at line 128 of file inliner.h.

128{ return flow_graph_; }

◆ FunctionHasAlwaysConsiderInliningPragma()

bool dart::FlowGraphInliner::FunctionHasAlwaysConsiderInliningPragma ( const Function function)
static

Definition at line 2499 of file inliner.cc.

2500 {
2501 if (!function.has_pragma()) {
2502 return false;
2503 }
2504 Thread* thread = dart::Thread::Current();
2505 COMPILER_TIMINGS_TIMER_SCOPE(thread, CheckForPragma);
2506 Object& options = Object::Handle();
2507 return Library::FindPragma(thread, /*only_core=*/false, function,
2508 Symbols::vm_always_consider_inlining(),
2509 /*multiple=*/false, &options);
2510}
const char * options
static bool FindPragma(Thread *T, bool only_core, const Object &object, const String &pragma_name, bool multiple=false, Object *options=nullptr)
Definition: object.cc:4151
static Object & Handle()
Definition: object.h:407

◆ FunctionHasNeverInlinePragma()

bool dart::FlowGraphInliner::FunctionHasNeverInlinePragma ( const Function function)
static

Definition at line 2487 of file inliner.cc.

2487 {
2488 if (!function.has_pragma()) {
2489 return false;
2490 }
2491 Thread* thread = dart::Thread::Current();
2492 COMPILER_TIMINGS_TIMER_SCOPE(thread, CheckForPragma);
2493 Object& options = Object::Handle();
2494 return Library::FindPragma(thread, /*only_core=*/false, function,
2495 Symbols::vm_never_inline(),
2496 /*multiple=*/false, &options);
2497}

◆ FunctionHasPreferInlinePragma()

bool dart::FlowGraphInliner::FunctionHasPreferInlinePragma ( const Function function)
static

Definition at line 2475 of file inliner.cc.

2475 {
2476 if (!function.has_pragma()) {
2477 return false;
2478 }
2479 Thread* thread = dart::Thread::Current();
2480 COMPILER_TIMINGS_TIMER_SCOPE(thread, CheckForPragma);
2481 Object& options = Object::Handle();
2482 return Library::FindPragma(thread, /*only_core=*/false, function,
2483 Symbols::vm_prefer_inline(),
2484 /*multiple=*/false, &options);
2485}

◆ Inline()

int dart::FlowGraphInliner::Inline ( )

Definition at line 2551 of file inliner.cc.

2551 {
2552 // Collect some early graph information assuming it is non-specialized
2553 // so that the cached approximation may be used later for an early
2554 // bailout from inlining.
2555 intptr_t instruction_count = 0;
2556 intptr_t call_site_count = 0;
2558 /*constants_count*/ 0,
2559 /*force*/ false, &instruction_count,
2560 &call_site_count);
2561
2562 const Function& top = flow_graph_->function();
2563 if ((FLAG_inlining_filter != nullptr) &&
2564 (strstr(top.ToFullyQualifiedCString(), FLAG_inlining_filter) ==
2565 nullptr)) {
2566 return 0;
2567 }
2568
2569 if (trace_inlining()) {
2570 String& name = String::Handle(top.QualifiedUserVisibleName());
2571 THR_Print("Inlining calls in %s\n", name.ToCString());
2572 }
2573
2575 (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized)) {
2576 THR_Print("Before Inlining of %s\n",
2577 flow_graph_->function().ToFullyQualifiedCString());
2578 FlowGraphPrinter printer(*flow_graph_);
2579 printer.PrintBlocks();
2580 }
2581
2582 intptr_t inlining_depth_threshold = FLAG_inlining_depth_threshold;
2583
2584 CallSiteInliner inliner(this, inlining_depth_threshold);
2585 inliner.InlineCalls();
2586 if (FLAG_print_inlining_tree) {
2587 inliner.PrintInlinedInfo(top);
2588 }
2589
2590 if (inliner.inlined()) {
2591 flow_graph_->DiscoverBlocks();
2592 if (trace_inlining()) {
2593 THR_Print("Inlining growth factor: %f\n", inliner.GrowthFactor());
2595 (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized)) {
2596 THR_Print("After Inlining of %s\n",
2597 flow_graph_->function().ToFullyQualifiedCString());
2598 FlowGraphPrinter printer(*flow_graph_);
2599 printer.PrintBlocks();
2600 }
2601 }
2602 }
2603 return inliner.inlining_depth();
2604}
bool trace_inlining() const
Definition: inliner.h:132
friend class CallSiteInliner
Definition: inliner.h:139
void DiscoverBlocks()
Definition: flow_graph.cc:346
const char * ToFullyQualifiedCString() const
Definition: object.cc:9762
constexpr bool FLAG_support_il_printer
Definition: flag_list.h:48
const char *const name

◆ NextInlineId()

intptr_t dart::FlowGraphInliner::NextInlineId ( const Function function,
const InstructionSource source 
)

Definition at line 2606 of file inliner.cc.

2607 {
2608 const intptr_t id = inline_id_to_function_->length();
2609 // TODO(johnmccutchan): Do not allow IsNoSource once all nodes have proper
2610 // source positions.
2611 ASSERT(source.token_pos.IsReal() || source.token_pos.IsSynthetic() ||
2612 source.token_pos.IsNoSource());
2613 RELEASE_ASSERT(!function.IsNull());
2614 ASSERT(FunctionType::Handle(function.signature()).IsFinalized());
2615 inline_id_to_function_->Add(&function);
2616 inline_id_to_token_pos_->Add(source.token_pos);
2617 caller_inline_id_->Add(source.inlining_id);
2618 // We always have one less token position than functions.
2619 ASSERT(inline_id_to_token_pos_->length() ==
2620 (inline_id_to_function_->length() - 1));
2621 return id;
2622}
#define RELEASE_ASSERT(cond)
Definition: assert.h:327
void Add(const T &value)
SkBitmap source
Definition: examples.cpp:28
const uintptr_t id

◆ SetInliningId()

void dart::FlowGraphInliner::SetInliningId ( FlowGraph flow_graph,
intptr_t  inlining_id 
)
static

Definition at line 2449 of file inliner.cc.

2450 {
2452 flow_graph->set_inlining_id(inlining_id);
2453 // We only need to set the inlining ID on instructions that may possibly
2454 // have token positions, so no need to set it on blocks or internal
2455 // definitions.
2456 for (BlockIterator block_it = flow_graph->postorder_iterator();
2457 !block_it.Done(); block_it.Advance()) {
2458 for (ForwardInstructionIterator it(block_it.Current()); !it.Done();
2459 it.Advance()) {
2460 Instruction* current = it.Current();
2461 current->set_inlining_id(inlining_id);
2462 }
2463 }
2464}
bool Done() const
Definition: flow_graph.h:46
intptr_t inlining_id() const
Definition: flow_graph.h:464
BlockIterator postorder_iterator() const
Definition: flow_graph.h:222
void set_inlining_id(intptr_t value)
Definition: flow_graph.h:465

◆ speculative_policy()

SpeculativeInliningPolicy * dart::FlowGraphInliner::speculative_policy ( )
inline

Definition at line 134 of file inliner.h.

134 {
135 return speculative_policy_;
136 }

◆ trace_inlining()

bool dart::FlowGraphInliner::trace_inlining ( ) const
inline

Definition at line 132 of file inliner.h.

132{ return trace_inlining_; }

Friends And Related Function Documentation

◆ CallSiteInliner

friend class CallSiteInliner
friend

Definition at line 139 of file inliner.h.


The documentation for this class was generated from the following files: