@@ -2266,6 +2266,144 @@ void FlowGraph::AppendExtractNthOutputForMerged(Definition* instr,
2266
2266
InsertAfter (instr, extract, NULL , FlowGraph::kValue );
2267
2267
}
2268
2268
2269
+ //
2270
+ // Static helpers for the flow graph utilities.
2271
+ //
2272
+
2273
+ static TargetEntryInstr* NewTarget (FlowGraph* graph, Instruction* inherit) {
2274
+ TargetEntryInstr* target = new (graph->zone ())
2275
+ TargetEntryInstr (graph->allocate_block_id (),
2276
+ inherit->GetBlock ()->try_index (), Thread::kNoDeoptId );
2277
+ target->InheritDeoptTarget (graph->zone (), inherit);
2278
+ return target;
2279
+ }
2280
+
2281
+ static JoinEntryInstr* NewJoin (FlowGraph* graph, Instruction* inherit) {
2282
+ JoinEntryInstr* join = new (graph->zone ())
2283
+ JoinEntryInstr (graph->allocate_block_id (),
2284
+ inherit->GetBlock ()->try_index (), Thread::kNoDeoptId );
2285
+ join->InheritDeoptTarget (graph->zone (), inherit);
2286
+ return join;
2287
+ }
2288
+
2289
+ static GotoInstr* NewGoto (FlowGraph* graph,
2290
+ JoinEntryInstr* target,
2291
+ Instruction* inherit) {
2292
+ GotoInstr* got = new (graph->zone ()) GotoInstr (target, Thread::kNoDeoptId );
2293
+ got->InheritDeoptTarget (graph->zone (), inherit);
2294
+ return got;
2295
+ }
2296
+
2297
+ static BranchInstr* NewBranch (FlowGraph* graph,
2298
+ ComparisonInstr* cmp,
2299
+ Instruction* inherit) {
2300
+ BranchInstr* bra = new (graph->zone ()) BranchInstr (cmp, Thread::kNoDeoptId );
2301
+ bra->InheritDeoptTarget (graph->zone (), inherit);
2302
+ return bra;
2303
+ }
2304
+
2305
+ //
2306
+ // Flow graph utilities.
2307
+ //
2308
+
2309
+ // Constructs new diamond decision at the given instruction.
2310
+ //
2311
+ // ENTRY
2312
+ // instruction
2313
+ // if (compare)
2314
+ // / \
2315
+ // B_TRUE B_FALSE
2316
+ // \ /
2317
+ // JOIN
2318
+ //
2319
+ JoinEntryInstr* FlowGraph::NewDiamond (Instruction* instruction,
2320
+ Instruction* inherit,
2321
+ ComparisonInstr* compare,
2322
+ TargetEntryInstr** b_true,
2323
+ TargetEntryInstr** b_false) {
2324
+ BlockEntryInstr* entry = instruction->GetBlock ();
2325
+
2326
+ TargetEntryInstr* bt = NewTarget (this , inherit);
2327
+ TargetEntryInstr* bf = NewTarget (this , inherit);
2328
+ JoinEntryInstr* join = NewJoin (this , inherit);
2329
+ GotoInstr* gotot = NewGoto (this , join, inherit);
2330
+ GotoInstr* gotof = NewGoto (this , join, inherit);
2331
+ BranchInstr* bra = NewBranch (this , compare, inherit);
2332
+
2333
+ instruction->AppendInstruction (bra);
2334
+ entry->set_last_instruction (bra);
2335
+
2336
+ *bra->true_successor_address () = bt;
2337
+ *bra->false_successor_address () = bf;
2338
+
2339
+ bt->AppendInstruction (gotot);
2340
+ bt->set_last_instruction (gotot);
2341
+
2342
+ bf->AppendInstruction (gotof);
2343
+ bf->set_last_instruction (gotof);
2344
+
2345
+ // Update dominance relation incrementally.
2346
+ for (intptr_t i = 0 , n = entry->dominated_blocks ().length (); i < n; ++i) {
2347
+ join->AddDominatedBlock (entry->dominated_blocks ()[i]);
2348
+ }
2349
+ entry->ClearDominatedBlocks ();
2350
+ entry->AddDominatedBlock (bt);
2351
+ entry->AddDominatedBlock (bf);
2352
+ entry->AddDominatedBlock (join);
2353
+
2354
+ // TODO(ajcbik): update pred/succ/ordering incrementally too.
2355
+
2356
+ // Return new blocks.
2357
+ *b_true = bt;
2358
+ *b_false = bf;
2359
+ return join;
2360
+ }
2361
+
2362
+ JoinEntryInstr* FlowGraph::NewDiamond (Instruction* instruction,
2363
+ Instruction* inherit,
2364
+ const LogicalAnd& condition,
2365
+ TargetEntryInstr** b_true,
2366
+ TargetEntryInstr** b_false) {
2367
+ // First diamond for first comparison.
2368
+ TargetEntryInstr* bt = nullptr ;
2369
+ TargetEntryInstr* bf = nullptr ;
2370
+ JoinEntryInstr* mid_point =
2371
+ NewDiamond (instruction, inherit, condition.oper1 , &bt, &bf);
2372
+
2373
+ // Short-circuit second comparison and connect through phi.
2374
+ condition.oper2 ->InsertAfter (bt);
2375
+ AllocateSSAIndexes (condition.oper2 );
2376
+ condition.oper2 ->InheritDeoptTarget (zone (), inherit); // must inherit
2377
+ PhiInstr* phi =
2378
+ AddPhi (mid_point, condition.oper2 , GetConstant (Bool::False ()));
2379
+ StrictCompareInstr* circuit = new (zone ()) StrictCompareInstr (
2380
+ inherit->token_pos (), Token::kEQ_STRICT , new (zone ()) Value (phi),
2381
+ new (zone ()) Value (GetConstant (Bool::True ())), false ,
2382
+ Thread::kNoDeoptId ); // don't inherit
2383
+
2384
+ // Return new blocks through the second diamond.
2385
+ return NewDiamond (mid_point, inherit, circuit, b_true, b_false);
2386
+ }
2387
+
2388
+ PhiInstr* FlowGraph::AddPhi (JoinEntryInstr* join,
2389
+ Definition* d1,
2390
+ Definition* d2) {
2391
+ PhiInstr* phi = new (zone ()) PhiInstr (join, 2 );
2392
+ Value* v1 = new (zone ()) Value (d1);
2393
+ Value* v2 = new (zone ()) Value (d2);
2394
+
2395
+ AllocateSSAIndexes (phi);
2396
+
2397
+ phi->mark_alive ();
2398
+ phi->SetInputAt (0 , v1);
2399
+ phi->SetInputAt (1 , v2);
2400
+ d1->AddInputUse (v1);
2401
+ d2->AddInputUse (v2);
2402
+ join->InsertPhi (phi);
2403
+
2404
+ return phi;
2405
+ }
2406
+
2269
2407
} // namespace dart
2270
2408
2271
2409
#endif // !defined(DART_PRECOMPILED_RUNTIME)
0 commit comments