242 {
243 Zone* zone = flow_graph->zone();
244 bool changed = false;
245
246 const GrowableArray<BlockEntryInstr*>& postorder = flow_graph->postorder();
247 for (BlockIterator it(postorder); !it.Done(); it.Advance()) {
248 BlockEntryInstr* block = it.Current();
249 JoinEntryInstr*
join = block->AsJoinEntry();
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271 if ((
join !=
nullptr) && (
join->phis() !=
nullptr) &&
272 (
join->phis()->length() == 1) && (block->PredecessorCount() == 2)) {
273 BlockEntryInstr* pred1 = block->PredecessorAt(0);
274 BlockEntryInstr* pred2 = block->PredecessorAt(1);
275
276 PhiInstr* phi = (*
join->phis())[0];
277 Value* v1 = phi->InputAt(0);
279
282 (pred1->PredecessorAt(0) == pred2->PredecessorAt(0))) {
283 BlockEntryInstr* pred = pred1->PredecessorAt(0);
284 BranchInstr* branch = pred->last_instruction()->AsBranch();
285
286 if (branch == nullptr) {
287
288
289 ASSERT(pred->last_instruction()->IsGraphEntry() ||
290 pred->last_instruction()->IsIndirectGoto());
291 continue;
292 }
293
294 ComparisonInstr* comparison = branch->comparison();
295
296
297
298
300 Value* if_true = (pred1 == branch->true_successor()) ? v1 :
v2;
301 Value* if_false = (pred2 == branch->true_successor()) ? v1 :
v2;
302
303 ComparisonInstr* new_comparison = comparison->CopyWithNewOperands(
304 comparison->left()->Copy(zone), comparison->right()->Copy(zone));
306 new (zone) IfThenElseInstr(new_comparison, if_true->Copy(zone),
310
312
313
314
315
316
318 pred->set_last_instruction(
join->last_instruction());
319
320
321
322
323 pred->set_block_id(block->block_id());
324
325
326
329
330
331 phi->UnuseAllInputs();
332 branch->UnuseAllInputs();
333 block->UnuseAllInputs();
334
335
336
337 changed = true;
338 }
339 }
340 }
341 }
342
343 if (changed) {
344
345 flow_graph->DiscoverBlocks();
346 GrowableArray<BitVector*> dominance_frontier;
347 flow_graph->ComputeDominators(&dominance_frontier);
348 }
349}
static constexpr intptr_t kNone
static bool Supports(ComparisonInstr *comparison, Value *v1, Value *v2)
static bool IsTrivialBlock(BlockEntryInstr *block, Definition *defn)
static void EliminateTrivialBlock(BlockEntryInstr *block, Definition *instr, IfThenElseInstr *before)
static SkString join(const CommandLineFlags::StringArray &)