19
19
#include " llvm/Analysis/RegionInfo.h"
20
20
#include " llvm/Analysis/RegionIterator.h"
21
21
#include " llvm/Analysis/RegionPass.h"
22
- #include " llvm/Analysis/TargetTransformInfo.h"
23
22
#include " llvm/Analysis/UniformityAnalysis.h"
24
23
#include " llvm/IR/BasicBlock.h"
25
24
#include " llvm/IR/CFG.h"
@@ -129,7 +128,6 @@ struct PredInfo {
129
128
using BBPredicates = DenseMap<BasicBlock *, PredInfo>;
130
129
using PredMap = DenseMap<BasicBlock *, BBPredicates>;
131
130
using BB2BBMap = DenseMap<BasicBlock *, BasicBlock *>;
132
- using Val2BBMap = DenseMap<Value *, BasicBlock *>;
133
131
134
132
// A traits type that is intended to be used in graph algorithms. The graph
135
133
// traits starts at an entry node, and traverses the RegionNodes that are in
@@ -281,7 +279,7 @@ class StructurizeCFG {
281
279
ConstantInt *BoolTrue;
282
280
ConstantInt *BoolFalse;
283
281
Value *BoolPoison;
284
- const TargetTransformInfo *TTI;
282
+
285
283
Function *Func;
286
284
Region *ParentRegion;
287
285
@@ -303,12 +301,8 @@ class StructurizeCFG {
303
301
PredMap LoopPreds;
304
302
BranchVector LoopConds;
305
303
306
- Val2BBMap HoistedValues;
307
-
308
304
RegionNode *PrevNode;
309
305
310
- void hoistZeroCostElseBlockPhiValues (BasicBlock *ElseBB, BasicBlock *ThenBB);
311
-
312
306
void orderNodes ();
313
307
314
308
void analyzeLoops (RegionNode *N);
@@ -338,8 +332,6 @@ class StructurizeCFG {
338
332
339
333
void simplifyAffectedPhis ();
340
334
341
- void simplifyHoistedPhis ();
342
-
343
335
DebugLoc killTerminator (BasicBlock *BB);
344
336
345
337
void changeExit (RegionNode *Node, BasicBlock *NewExit,
@@ -367,7 +359,7 @@ class StructurizeCFG {
367
359
368
360
public:
369
361
void init (Region *R);
370
- bool run (Region *R, DominatorTree *DT, const TargetTransformInfo *TTI );
362
+ bool run (Region *R, DominatorTree *DT);
371
363
bool makeUniformRegion (Region *R, UniformityInfo &UA);
372
364
};
373
365
@@ -393,21 +385,16 @@ class StructurizeCFGLegacyPass : public RegionPass {
393
385
if (SCFG.makeUniformRegion (R, UA))
394
386
return false ;
395
387
}
396
- Function *F = R->getEntry ()->getParent ();
397
- const TargetTransformInfo *TTI =
398
- &getAnalysis<TargetTransformInfoWrapperPass>().getTTI (*F);
399
388
DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree ();
400
- return SCFG.run (R, DT, TTI );
389
+ return SCFG.run (R, DT);
401
390
}
402
391
403
392
StringRef getPassName () const override { return " Structurize control flow" ; }
404
393
405
394
void getAnalysisUsage (AnalysisUsage &AU) const override {
406
395
if (SkipUniformRegions)
407
396
AU.addRequired <UniformityInfoWrapperPass>();
408
- AU.addRequired <TargetTransformInfoWrapperPass>();
409
397
AU.addRequired <DominatorTreeWrapperPass>();
410
- AU.addRequired <TargetTransformInfoWrapperPass>();
411
398
412
399
AU.addPreserved <DominatorTreeWrapperPass>();
413
400
RegionPass::getAnalysisUsage (AU);
@@ -416,34 +403,6 @@ class StructurizeCFGLegacyPass : public RegionPass {
416
403
417
404
} // end anonymous namespace
418
405
419
- // / Checks whether an instruction is zero cost instruction and checks if the
420
- // / operands are from different BB. If so, this instruction can be coalesced
421
- // / if its hoisted to predecessor block. So, this returns true.
422
- static bool isHoistableInstruction (Instruction *I, BasicBlock *BB,
423
- const TargetTransformInfo *TTI) {
424
- if (I->getParent () != BB)
425
- return false ;
426
-
427
- // If the instruction is not a zero cost instruction, return false.
428
- auto Cost = TTI->getInstructionCost (I, TargetTransformInfo::TCK_Latency);
429
- InstructionCost::CostType CostVal =
430
- Cost.isValid ()
431
- ? Cost.getValue ()
432
- : (InstructionCost::CostType)TargetTransformInfo::TCC_Expensive;
433
- if (CostVal != 0 )
434
- return false ;
435
-
436
- // Check if any operands are instructions defined in the same block.
437
- for (auto &Op : I->operands ()) {
438
- if (auto *OpI = dyn_cast<Instruction>(Op)) {
439
- if (OpI->getParent () == BB)
440
- return false ;
441
- }
442
- }
443
-
444
- return true ;
445
- }
446
-
447
406
char StructurizeCFGLegacyPass::ID = 0 ;
448
407
449
408
INITIALIZE_PASS_BEGIN (StructurizeCFGLegacyPass, " structurizecfg" ,
@@ -454,39 +413,6 @@ INITIALIZE_PASS_DEPENDENCY(RegionInfoPass)
454
413
INITIALIZE_PASS_END(StructurizeCFGLegacyPass, " structurizecfg" ,
455
414
" Structurize the CFG" , false , false )
456
415
457
- // / Structurization can introduce unnecessary VGPR copies due to register
458
- // / coalescing interference. For example, if the Else block has a zero-cost
459
- // / instruction and the Then block modifies the VGPR value, only one value is
460
- // / live at a time in merge block before structurization. After structurization,
461
- // / the coalescer may incorrectly treat the Then value as live in the Else block
462
- // / (via the path Then → Flow → Else), leading to unnecessary VGPR copies.
463
- // /
464
- // / This function examines phi nodes whose incoming values are zero-cost
465
- // / instructions in the Else block. It identifies such values that can be safely
466
- // / hoisted and moves them to the nearest common dominator of Then and Else
467
- // / blocks. A follow-up function after setting PhiNodes assigns the hoisted
468
- // / value to poison phi nodes along the if→flow edge, aiding register coalescing
469
- // / and minimizing unnecessary live ranges.
470
- void StructurizeCFG::hoistZeroCostElseBlockPhiValues(BasicBlock *ElseBB,
471
- BasicBlock *ThenBB) {
472
-
473
- BasicBlock *ElseSucc = ElseBB->getSingleSuccessor ();
474
- BasicBlock *CommonDominator = DT->findNearestCommonDominator (ElseBB, ThenBB);
475
-
476
- if (!ElseSucc || !CommonDominator)
477
- return ;
478
- Instruction *Term = CommonDominator->getTerminator ();
479
- for (PHINode &Phi : ElseSucc->phis ()) {
480
- Value *ElseVal = Phi.getIncomingValueForBlock (ElseBB);
481
- auto *Inst = dyn_cast<Instruction>(ElseVal);
482
- if (!Inst || !isHoistableInstruction (Inst, ElseBB, TTI))
483
- continue ;
484
- Inst->removeFromParent ();
485
- Inst->insertInto (CommonDominator, Term->getIterator ());
486
- HoistedValues[Inst] = CommonDominator;
487
- }
488
- }
489
-
490
416
// / Build up the general order of nodes, by performing a topological sort of the
491
417
// / parent region's nodes, while ensuring that there is no outer cycle node
492
418
// / between any two inner cycle nodes.
@@ -609,7 +535,7 @@ void StructurizeCFG::gatherPredicates(RegionNode *N) {
609
535
BasicBlock *Other = Term->getSuccessor (!i);
610
536
if (Visited.count (Other) && !Loops.count (Other) &&
611
537
!Pred.count (Other) && !Pred.count (P)) {
612
- hoistZeroCostElseBlockPhiValues (Succ, Other);
538
+
613
539
Pred[Other] = {BoolFalse, std::nullopt};
614
540
Pred[P] = {BoolTrue, std::nullopt};
615
541
continue ;
@@ -965,44 +891,6 @@ void StructurizeCFG::setPhiValues() {
965
891
AffectedPhis.append (InsertedPhis.begin (), InsertedPhis.end ());
966
892
}
967
893
968
- // / Updates PHI nodes after hoisted zero cost instructions by replacing poison
969
- // / entries on Flow nodes with the appropriate hoisted values
970
- void StructurizeCFG::simplifyHoistedPhis () {
971
- for (WeakVH VH : AffectedPhis) {
972
- PHINode *Phi = dyn_cast_or_null<PHINode>(VH);
973
- if (!Phi || Phi->getNumIncomingValues () != 2 )
974
- continue ;
975
-
976
- for (int i = 0 ; i < 2 ; i++) {
977
- Value *V = Phi->getIncomingValue (i);
978
- auto BBIt = HoistedValues.find (V);
979
-
980
- if (BBIt == HoistedValues.end ())
981
- continue ;
982
-
983
- Value *OtherV = Phi->getIncomingValue (!i);
984
- PHINode *OtherPhi = dyn_cast<PHINode>(OtherV);
985
- if (!OtherPhi)
986
- continue ;
987
-
988
- int PoisonValBBIdx = -1 ;
989
- for (size_t i = 0 ; i < OtherPhi->getNumIncomingValues (); i++) {
990
- if (!isa<PoisonValue>(OtherPhi->getIncomingValue (i)))
991
- continue ;
992
- PoisonValBBIdx = i;
993
- break ;
994
- }
995
- if (PoisonValBBIdx == -1 ||
996
- !DT->dominates (BBIt->second ,
997
- OtherPhi->getIncomingBlock (PoisonValBBIdx)))
998
- continue ;
999
-
1000
- OtherPhi->setIncomingValue (PoisonValBBIdx, V);
1001
- Phi->setIncomingValue (i, OtherV);
1002
- }
1003
- }
1004
- }
1005
-
1006
894
void StructurizeCFG::simplifyAffectedPhis () {
1007
895
bool Changed;
1008
896
do {
@@ -1395,13 +1283,12 @@ bool StructurizeCFG::makeUniformRegion(Region *R, UniformityInfo &UA) {
1395
1283
}
1396
1284
1397
1285
// / Run the transformation for each region found
1398
- bool StructurizeCFG::run (Region *R, DominatorTree *DT,
1399
- const TargetTransformInfo *TTI) {
1286
+ bool StructurizeCFG::run (Region *R, DominatorTree *DT) {
1400
1287
if (R->isTopLevelRegion ())
1401
1288
return false ;
1402
1289
1403
1290
this ->DT = DT;
1404
- this -> TTI = TTI;
1291
+
1405
1292
Func = R->getEntry ()->getParent ();
1406
1293
assert (hasOnlySimpleTerminator (*Func) && " Unsupported block terminator." );
1407
1294
@@ -1413,7 +1300,6 @@ bool StructurizeCFG::run(Region *R, DominatorTree *DT,
1413
1300
insertConditions (false );
1414
1301
insertConditions (true );
1415
1302
setPhiValues ();
1416
- simplifyHoistedPhis ();
1417
1303
simplifyConditions ();
1418
1304
simplifyAffectedPhis ();
1419
1305
rebuildSSA ();
@@ -1463,7 +1349,7 @@ PreservedAnalyses StructurizeCFGPass::run(Function &F,
1463
1349
bool Changed = false ;
1464
1350
DominatorTree *DT = &AM.getResult <DominatorTreeAnalysis>(F);
1465
1351
auto &RI = AM.getResult <RegionInfoAnalysis>(F);
1466
- TargetTransformInfo *TTI = &AM. getResult <TargetIRAnalysis>(F);
1352
+
1467
1353
UniformityInfo *UI = nullptr ;
1468
1354
if (SkipUniformRegions)
1469
1355
UI = &AM.getResult <UniformityInfoAnalysis>(F);
@@ -1482,7 +1368,7 @@ PreservedAnalyses StructurizeCFGPass::run(Function &F,
1482
1368
continue ;
1483
1369
}
1484
1370
1485
- Changed |= SCFG.run (R, DT, TTI );
1371
+ Changed |= SCFG.run (R, DT);
1486
1372
}
1487
1373
if (!Changed)
1488
1374
return PreservedAnalyses::all ();
0 commit comments