Flutter Engine
The Flutter Engine
Public Member Functions | List of all members
dart::PolymorphicInliner Class Reference
Inheritance diagram for dart::PolymorphicInliner:
dart::ValueObject

Public Member Functions

 PolymorphicInliner (CallSiteInliner *owner, PolymorphicInstanceCallInstr *call, const Function &caller_function)
 
bool Inline ()
 
- Public Member Functions inherited from dart::ValueObject
 ValueObject ()
 
 ~ValueObject ()
 

Detailed Description

Definition at line 740 of file inliner.cc.

Constructor & Destructor Documentation

◆ PolymorphicInliner()

dart::PolymorphicInliner::PolymorphicInliner ( CallSiteInliner owner,
PolymorphicInstanceCallInstr call,
const Function caller_function 
)

Definition at line 1973 of file inliner.cc.

1976 : owner_(owner),
1977 call_(call),
1978 num_variants_(call->NumberOfChecks()),
1979 variants_(call->targets_),
1980 inlined_variants_(zone()),
1981 non_inlined_variants_(new(zone()) CallTargets(zone())),
1982 inlined_entries_(num_variants_),
1983 exit_collector_(new(Z) InlineExitCollector(owner->caller_graph(), call)),
1984 caller_function_(caller_function) {}
#define Z
Definition: inliner.cc:88
def call(args)
Definition: dom.py:159

Member Function Documentation

◆ Inline()

bool dart::PolymorphicInliner::Inline ( )

Definition at line 2318 of file inliner.cc.

2318 {
2319 ASSERT(&variants_ == &call_->targets_);
2320
2321 intptr_t total = call_->total_call_count();
2322 for (intptr_t var_idx = 0; var_idx < variants_.length(); ++var_idx) {
2323 TargetInfo* info = variants_.TargetAt(var_idx);
2324 if (variants_.length() > FLAG_max_polymorphic_checks) {
2325 non_inlined_variants_->Add(info);
2326 continue;
2327 }
2328
2329 const Function& target = *variants_.TargetAt(var_idx)->target;
2330 const intptr_t count = variants_.TargetAt(var_idx)->count;
2331
2332 // We we almost inlined all the cases then try a little harder to inline
2333 // the last two, because it's a big win if we inline all of them (compiler
2334 // can see all side effects).
2335 const bool try_harder = (var_idx >= variants_.length() - 2) &&
2336 non_inlined_variants_->length() == 0;
2337
2338 intptr_t size = target.optimized_instruction_count();
2339 bool small = (size != 0 && size < FLAG_inlining_size_threshold);
2340
2341 // If it's less than 3% of the dispatches, we won't even consider
2342 // checking for the class ID and branching to another already-inlined
2343 // version.
2344 if (!try_harder && count < (total >> 5)) {
2346 TracePolyInlining(variants_, var_idx, total, "way too infrequent"));
2347 non_inlined_variants_->Add(info);
2348 continue;
2349 }
2350
2351 // First check if this is the same target as an earlier inlined variant.
2352 if (CheckInlinedDuplicate(target)) {
2353 TRACE_INLINING(TracePolyInlining(variants_, var_idx, total,
2354 "duplicate already inlined"));
2355 inlined_variants_.Add(info);
2356 continue;
2357 }
2358
2359 // If it's less than 12% of the dispatches and it's not already inlined, we
2360 // don't consider inlining. For very small functions we are willing to
2361 // consider inlining for 6% of the cases.
2362 if (!try_harder && count < (total >> (small ? 4 : 3))) {
2364 TracePolyInlining(variants_, var_idx, total, "too infrequent"));
2365 non_inlined_variants_->Add(&variants_[var_idx]);
2366 continue;
2367 }
2368
2369 // Also check if this is the same target as an earlier non-inlined
2370 // variant. If so and since inlining decisions are costly, do not try
2371 // to inline this variant.
2372 if (CheckNonInlinedDuplicate(target)) {
2374 TracePolyInlining(variants_, var_idx, total, "already not inlined"));
2375 non_inlined_variants_->Add(&variants_[var_idx]);
2376 continue;
2377 }
2378
2379 // Make an inlining decision.
2380 if (TryInliningPoly(*info)) {
2381 TRACE_INLINING(TracePolyInlining(variants_, var_idx, total, "inlined"));
2382 inlined_variants_.Add(&variants_[var_idx]);
2383 } else {
2385 TracePolyInlining(variants_, var_idx, total, "not inlined"));
2386 non_inlined_variants_->Add(&variants_[var_idx]);
2387 }
2388 }
2389
2390 // If there are no inlined variants, leave the call in place.
2391 if (inlined_variants_.is_empty()) return false;
2392
2393 // Now build a decision tree (a DAG because of shared inline variants) and
2394 // inline it at the call site.
2395 TargetEntryInstr* entry = BuildDecisionGraph();
2396 exit_collector_->ReplaceCall(entry);
2397 return true;
2398}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
int count
Definition: FontMgrTest.cpp:50
TargetInfo * TargetAt(int i) const
Definition: il.h:796
intptr_t length() const
Definition: il.h:758
void Add(CidRange *target)
Definition: il.h:752
bool is_empty() const
Definition: il.h:762
void ReplaceCall(BlockEntryInstr *callee_entry)
#define ASSERT(E)
uint32_t * target
#define TRACE_INLINING(statement)
Definition: inliner.cc:90
static void TracePolyInlining(const CallTargets &targets, intptr_t idx, intptr_t total, const char *message)
Definition: inliner.cc:2302
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
const Function * target
Definition: il.h:727
intptr_t count
Definition: il.h:728

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