Skip to content

Commit ac24238

Browse files
authored
[LowerSwitch] Don't let pass manager handle the dependency (#68662)
Some passes has limitation that only support simple terminators: branch/unreachable/return. Right now, they ask the pass manager to add LowerSwitch pass to eliminate `switch`. Let's manage such kind of pass dependency by ourselves. Also add the assertion in the related passes.
1 parent b745ce9 commit ac24238

File tree

13 files changed

+29
-28
lines changed

13 files changed

+29
-28
lines changed

llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,9 @@ BasicBlock *CreateControlFlowHub(
702702
// successors
703703
void InvertBranch(BranchInst *PBI, IRBuilderBase &Builder);
704704

705+
// Check whether the function only has simple terminator:
706+
// br/brcond/unreachable/ret
707+
bool hasOnlySimpleTerminator(const Function &F);
705708
} // end namespace llvm
706709

707710
#endif // LLVM_TRANSFORMS_UTILS_BASICBLOCKUTILS_H

llvm/lib/Target/AMDGPU/AMDGPUUnifyDivergentExitNodes.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "llvm/Support/Casting.h"
4747
#include "llvm/Transforms/Scalar.h"
4848
#include "llvm/Transforms/Utils.h"
49+
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
4950
#include "llvm/Transforms/Utils/Local.h"
5051

5152
using namespace llvm;
@@ -114,8 +115,6 @@ void AMDGPUUnifyDivergentExitNodes::getAnalysisUsage(AnalysisUsage &AU) const {
114115
// We preserve the non-critical-edgeness property
115116
AU.addPreservedID(BreakCriticalEdgesID);
116117

117-
// This is a cluster of orthogonal Transforms
118-
AU.addPreservedID(LowerSwitchID);
119118
FunctionPass::getAnalysisUsage(AU);
120119

121120
AU.addRequired<TargetTransformInfoWrapperPass>();
@@ -192,6 +191,8 @@ BasicBlock *AMDGPUUnifyDivergentExitNodesImpl::unifyReturnBlockSet(
192191
bool AMDGPUUnifyDivergentExitNodesImpl::run(Function &F, DominatorTree *DT,
193192
const PostDominatorTree &PDT,
194193
const UniformityInfo &UA) {
194+
assert(hasOnlySimpleTerminator(F) && "Unsupported block terminator.");
195+
195196
if (PDT.root_size() == 0 ||
196197
(PDT.root_size() == 1 &&
197198
!isa<BranchInst>(PDT.getRoot()->getTerminator())))

llvm/lib/Transforms/Scalar/StructurizeCFG.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "llvm/Support/raw_ostream.h"
4343
#include "llvm/Transforms/Scalar.h"
4444
#include "llvm/Transforms/Utils.h"
45+
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
4546
#include "llvm/Transforms/Utils/Local.h"
4647
#include "llvm/Transforms/Utils/SSAUpdater.h"
4748
#include <algorithm>
@@ -353,7 +354,6 @@ class StructurizeCFGLegacyPass : public RegionPass {
353354
void getAnalysisUsage(AnalysisUsage &AU) const override {
354355
if (SkipUniformRegions)
355356
AU.addRequired<UniformityInfoWrapperPass>();
356-
AU.addRequiredID(LowerSwitchID);
357357
AU.addRequired<DominatorTreeWrapperPass>();
358358

359359
AU.addPreserved<DominatorTreeWrapperPass>();
@@ -368,7 +368,6 @@ char StructurizeCFGLegacyPass::ID = 0;
368368
INITIALIZE_PASS_BEGIN(StructurizeCFGLegacyPass, "structurizecfg",
369369
"Structurize the CFG", false, false)
370370
INITIALIZE_PASS_DEPENDENCY(UniformityInfoWrapperPass)
371-
INITIALIZE_PASS_DEPENDENCY(LowerSwitchLegacyPass)
372371
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
373372
INITIALIZE_PASS_DEPENDENCY(RegionInfoPass)
374373
INITIALIZE_PASS_END(StructurizeCFGLegacyPass, "structurizecfg",
@@ -1173,6 +1172,8 @@ bool StructurizeCFG::run(Region *R, DominatorTree *DT) {
11731172
this->DT = DT;
11741173

11751174
Func = R->getEntry()->getParent();
1175+
assert(hasOnlySimpleTerminator(*Func) && "Unsupported block terminator.");
1176+
11761177
ParentRegion = R;
11771178

11781179
orderNodes();

llvm/lib/Transforms/Utils/BasicBlockUtils.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2076,3 +2076,13 @@ void llvm::InvertBranch(BranchInst *PBI, IRBuilderBase &Builder) {
20762076
PBI->setCondition(NewCond);
20772077
PBI->swapSuccessors();
20782078
}
2079+
2080+
bool llvm::hasOnlySimpleTerminator(const Function &F) {
2081+
for (auto &BB : F) {
2082+
auto *Term = BB.getTerminator();
2083+
if (!(isa<ReturnInst>(Term) || isa<UnreachableInst>(Term) ||
2084+
isa<BranchInst>(Term)))
2085+
return false;
2086+
}
2087+
return true;
2088+
}

llvm/lib/Transforms/Utils/FixIrreducible.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,8 @@ struct FixIrreducible : public FunctionPass {
8787
}
8888

8989
void getAnalysisUsage(AnalysisUsage &AU) const override {
90-
AU.addRequiredID(LowerSwitchID);
9190
AU.addRequired<DominatorTreeWrapperPass>();
9291
AU.addRequired<LoopInfoWrapperPass>();
93-
AU.addPreservedID(LowerSwitchID);
9492
AU.addPreserved<DominatorTreeWrapperPass>();
9593
AU.addPreserved<LoopInfoWrapperPass>();
9694
}
@@ -106,7 +104,6 @@ FunctionPass *llvm::createFixIrreduciblePass() { return new FixIrreducible(); }
106104
INITIALIZE_PASS_BEGIN(FixIrreducible, "fix-irreducible",
107105
"Convert irreducible control-flow into natural loops",
108106
false /* Only looks at CFG */, false /* Analysis Pass */)
109-
INITIALIZE_PASS_DEPENDENCY(LowerSwitchLegacyPass)
110107
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
111108
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
112109
INITIALIZE_PASS_END(FixIrreducible, "fix-irreducible",
@@ -317,6 +314,8 @@ static bool FixIrreducibleImpl(Function &F, LoopInfo &LI, DominatorTree &DT) {
317314
LLVM_DEBUG(dbgs() << "===== Fix irreducible control-flow in function: "
318315
<< F.getName() << "\n");
319316

317+
assert(hasOnlySimpleTerminator(F) && "Unsupported block terminator.");
318+
320319
bool Changed = false;
321320
SmallVector<Loop *, 8> WorkList;
322321

llvm/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ void UnifyFunctionExitNodesLegacyPass::getAnalysisUsage(
3939
AnalysisUsage &AU) const {
4040
// We preserve the non-critical-edgeness property
4141
AU.addPreservedID(BreakCriticalEdgesID);
42-
// This is a cluster of orthogonal Transforms
43-
AU.addPreservedID(LowerSwitchID);
4442
}
4543

4644
namespace {

llvm/lib/Transforms/Utils/UnifyLoopExits.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,8 @@ struct UnifyLoopExitsLegacyPass : public FunctionPass {
4444
}
4545

4646
void getAnalysisUsage(AnalysisUsage &AU) const override {
47-
AU.addRequiredID(LowerSwitchID);
4847
AU.addRequired<LoopInfoWrapperPass>();
4948
AU.addRequired<DominatorTreeWrapperPass>();
50-
AU.addPreservedID(LowerSwitchID);
5149
AU.addPreserved<LoopInfoWrapperPass>();
5250
AU.addPreserved<DominatorTreeWrapperPass>();
5351
}
@@ -65,7 +63,6 @@ FunctionPass *llvm::createUnifyLoopExitsPass() {
6563
INITIALIZE_PASS_BEGIN(UnifyLoopExitsLegacyPass, "unify-loop-exits",
6664
"Fixup each natural loop to have a single exit block",
6765
false /* Only looks at CFG */, false /* Analysis Pass */)
68-
INITIALIZE_PASS_DEPENDENCY(LowerSwitchLegacyPass)
6966
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
7067
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
7168
INITIALIZE_PASS_END(UnifyLoopExitsLegacyPass, "unify-loop-exits",
@@ -234,6 +231,8 @@ bool UnifyLoopExitsLegacyPass::runOnFunction(Function &F) {
234231
auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
235232
auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
236233

234+
assert(hasOnlySimpleTerminator(F) && "Unsupported block terminator.");
235+
237236
return runImpl(LI, DT);
238237
}
239238

llvm/test/CodeGen/AMDGPU/llc-pipeline.ll

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,6 @@
6060
; GCN-O0-NEXT: Cycle Info Analysis
6161
; GCN-O0-NEXT: Uniformity Analysis
6262
; GCN-O0-NEXT: Unify divergent function exit nodes
63-
; GCN-O0-NEXT: Lazy Value Information Analysis
64-
; GCN-O0-NEXT: Lower SwitchInst's to branches
6563
; GCN-O0-NEXT: Dominator Tree Construction
6664
; GCN-O0-NEXT: Natural Loop Information
6765
; GCN-O0-NEXT: Convert irreducible control-flow into natural loops
@@ -251,8 +249,6 @@
251249
; GCN-O1-NEXT: Code sinking
252250
; GCN-O1-NEXT: Post-Dominator Tree Construction
253251
; GCN-O1-NEXT: Unify divergent function exit nodes
254-
; GCN-O1-NEXT: Lazy Value Information Analysis
255-
; GCN-O1-NEXT: Lower SwitchInst's to branches
256252
; GCN-O1-NEXT: Dominator Tree Construction
257253
; GCN-O1-NEXT: Natural Loop Information
258254
; GCN-O1-NEXT: Convert irreducible control-flow into natural loops
@@ -537,8 +533,6 @@
537533
; GCN-O1-OPTS-NEXT: Code sinking
538534
; GCN-O1-OPTS-NEXT: Post-Dominator Tree Construction
539535
; GCN-O1-OPTS-NEXT: Unify divergent function exit nodes
540-
; GCN-O1-OPTS-NEXT: Lazy Value Information Analysis
541-
; GCN-O1-OPTS-NEXT: Lower SwitchInst's to branches
542536
; GCN-O1-OPTS-NEXT: Dominator Tree Construction
543537
; GCN-O1-OPTS-NEXT: Natural Loop Information
544538
; GCN-O1-OPTS-NEXT: Convert irreducible control-flow into natural loops
@@ -841,8 +835,6 @@
841835
; GCN-O2-NEXT: Code sinking
842836
; GCN-O2-NEXT: Post-Dominator Tree Construction
843837
; GCN-O2-NEXT: Unify divergent function exit nodes
844-
; GCN-O2-NEXT: Lazy Value Information Analysis
845-
; GCN-O2-NEXT: Lower SwitchInst's to branches
846838
; GCN-O2-NEXT: Dominator Tree Construction
847839
; GCN-O2-NEXT: Natural Loop Information
848840
; GCN-O2-NEXT: Convert irreducible control-flow into natural loops
@@ -1159,8 +1151,6 @@
11591151
; GCN-O3-NEXT: Code sinking
11601152
; GCN-O3-NEXT: Post-Dominator Tree Construction
11611153
; GCN-O3-NEXT: Unify divergent function exit nodes
1162-
; GCN-O3-NEXT: Lazy Value Information Analysis
1163-
; GCN-O3-NEXT: Lower SwitchInst's to branches
11641154
; GCN-O3-NEXT: Dominator Tree Construction
11651155
; GCN-O3-NEXT: Natural Loop Information
11661156
; GCN-O3-NEXT: Convert irreducible control-flow into natural loops

llvm/test/CodeGen/AMDGPU/multi-divergent-exit-region.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
; RUN: opt -mtriple=amdgcn-- -mcpu=gfx600 -S -amdgpu-unify-divergent-exit-nodes -verify -structurizecfg -verify -si-annotate-control-flow -simplifycfg-require-and-preserve-domtree=1 %s | FileCheck -check-prefix=IR %s
2-
; RUN: opt -mtriple=amdgcn-- -mcpu=gfx1100 -mattr=-wavefrontsize32,+wavefrontsize64 -S -amdgpu-unify-divergent-exit-nodes -verify -structurizecfg -verify -si-annotate-control-flow -simplifycfg-require-and-preserve-domtree=1 %s | FileCheck -check-prefix=IR %s
1+
; RUN: opt -mtriple=amdgcn-- -mcpu=gfx600 -S -lowerswitch -amdgpu-unify-divergent-exit-nodes -verify -structurizecfg -verify -si-annotate-control-flow -simplifycfg-require-and-preserve-domtree=1 %s | FileCheck -check-prefix=IR %s
2+
; RUN: opt -mtriple=amdgcn-- -mcpu=gfx1100 -mattr=-wavefrontsize32,+wavefrontsize64 -S -lowerswitch -amdgpu-unify-divergent-exit-nodes -verify -structurizecfg -verify -si-annotate-control-flow -simplifycfg-require-and-preserve-domtree=1 %s | FileCheck -check-prefix=IR %s
33
; RUN: llc -march=amdgcn -verify-machineinstrs -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck -check-prefix=GCN %s
44

55
; Add an extra verifier runs. There were some cases where invalid IR

llvm/test/CodeGen/AMDGPU/multilevel-break.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2-
; RUN: opt -S -mtriple=amdgcn-- -structurizecfg -si-annotate-control-flow < %s | FileCheck -check-prefix=OPT %s
2+
; RUN: opt -S -mtriple=amdgcn-- -lowerswitch -structurizecfg -si-annotate-control-flow < %s | FileCheck -check-prefix=OPT %s
33
; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=GCN %s
44

55
; Ensure two if.break calls, for both the inner and outer loops

llvm/test/CodeGen/AMDGPU/si-unify-exit-return-unreachable.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
22
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
33
; RUN: llc -mtriple=amdgcn-amd-amdhsa -verify-machineinstrs %s -o - | FileCheck -check-prefix=GCN %s
4-
; RUN: opt -mtriple=amdgcn-amd-amdhsa -amdgpu-unify-divergent-exit-nodes -verify -structurizecfg -verify -si-annotate-control-flow -verify -S %s -o - | FileCheck -check-prefix=IR %s
4+
; RUN: opt -mtriple=amdgcn-amd-amdhsa -lowerswitch -amdgpu-unify-divergent-exit-nodes -verify -structurizecfg -verify -si-annotate-control-flow -verify -S %s -o - | FileCheck -check-prefix=IR %s
55

66
; A test with a divergent unreachable block and uniform return block. The
77
; compiler needs to create a regions that includes them so that

llvm/test/Transforms/FixIrreducible/switch.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2-
; RUN: opt < %s -fix-irreducible -S | FileCheck %s
2+
; RUN: opt < %s -passes='lowerswitch,fix-irreducible' -S | FileCheck %s
33

44
define void @loop_1(i32 %Value, i1 %PredEntry, i1 %PredD) {
55
; CHECK-LABEL: @loop_1(

llvm/test/Transforms/StructurizeCFG/switch.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: opt -S -structurizecfg %s -o - | FileCheck %s
1+
; RUN: opt -S -passes='lowerswitch,structurizecfg' %s -o - | FileCheck %s
22

33
; The structurizecfg pass cannot handle switch instructions, so we need to
44
; make sure the lower switch pass is always run before structurizecfg.

0 commit comments

Comments
 (0)