@@ -308,6 +308,9 @@ class StructurizeCFG {
308
308
309
309
void hoistZeroCostElseBlockPhiValues (BasicBlock *ElseBB, BasicBlock *ThenBB);
310
310
311
+ bool isHoistableInstruction (Instruction *I, BasicBlock *BB,
312
+ BasicBlock *HoistTo);
313
+
311
314
void orderNodes ();
312
315
313
316
void analyzeLoops (RegionNode *N);
@@ -415,11 +418,21 @@ class StructurizeCFGLegacyPass : public RegionPass {
415
418
416
419
} // end anonymous namespace
417
420
421
+ char StructurizeCFGLegacyPass::ID = 0 ;
422
+
423
+ INITIALIZE_PASS_BEGIN (StructurizeCFGLegacyPass, " structurizecfg" ,
424
+ " Structurize the CFG" , false , false )
425
+ INITIALIZE_PASS_DEPENDENCY(UniformityInfoWrapperPass)
426
+ INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
427
+ INITIALIZE_PASS_DEPENDENCY(RegionInfoPass)
428
+ INITIALIZE_PASS_END(StructurizeCFGLegacyPass, " structurizecfg" ,
429
+ " Structurize the CFG" , false , false )
430
+
418
431
// / Checks whether an instruction is zero cost instruction and checks if the
419
432
// / operands are from different BB. If so, this instruction can be coalesced
420
433
// / if its hoisted to predecessor block. So, this returns true.
421
- static bool isHoistableInstruction (Instruction *I, BasicBlock *BB,
422
- const TargetTransformInfo *TTI ) {
434
+ bool StructurizeCFG:: isHoistableInstruction(Instruction *I, BasicBlock *BB,
435
+ BasicBlock *HoistTo ) {
423
436
if (I->getParent () != BB || isa<PHINode>(I))
424
437
return false ;
425
438
@@ -432,27 +445,18 @@ static bool isHoistableInstruction(Instruction *I, BasicBlock *BB,
432
445
if (CostVal != 0 )
433
446
return false ;
434
447
435
- // Check if any operands are instructions defined in the same block .
448
+ // Check if all operands are available at the hoisting destination .
436
449
for (auto &Op : I->operands ()) {
437
450
if (auto *OpI = dyn_cast<Instruction>(Op)) {
438
- if (OpI->getParent () == BB)
451
+ // Operand must dominate the hoisting destination.
452
+ if (!DT->dominates (OpI->getParent (), HoistTo))
439
453
return false ;
440
454
}
441
455
}
442
456
443
457
return true ;
444
458
}
445
459
446
- char StructurizeCFGLegacyPass::ID = 0 ;
447
-
448
- INITIALIZE_PASS_BEGIN (StructurizeCFGLegacyPass, " structurizecfg" ,
449
- " Structurize the CFG" , false , false )
450
- INITIALIZE_PASS_DEPENDENCY(UniformityInfoWrapperPass)
451
- INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
452
- INITIALIZE_PASS_DEPENDENCY(RegionInfoPass)
453
- INITIALIZE_PASS_END(StructurizeCFGLegacyPass, " structurizecfg" ,
454
- " Structurize the CFG" , false , false )
455
-
456
460
// / Structurization can introduce unnecessary VGPR copies due to register
457
461
// / coalescing interference. For example, if the Else block has a zero-cost
458
462
// / instruction and the Then block modifies the VGPR value, only one value is
@@ -478,7 +482,7 @@ void StructurizeCFG::hoistZeroCostElseBlockPhiValues(BasicBlock *ElseBB,
478
482
for (PHINode &Phi : ElseSucc->phis ()) {
479
483
Value *ElseVal = Phi.getIncomingValueForBlock (ElseBB);
480
484
auto *Inst = dyn_cast<Instruction>(ElseVal);
481
- if (!Inst || !isHoistableInstruction (Inst, ElseBB, TTI ))
485
+ if (!Inst || !isHoistableInstruction (Inst, ElseBB, CommonDominator ))
482
486
continue ;
483
487
Inst->removeFromParent ();
484
488
Inst->insertInto (CommonDominator, Term->getIterator ());
0 commit comments