llvm.org GIT mirror llvm / 41f2abf
[Speculation] Add a SpeculativeExecution mode where the pass does nothing unless TTI::hasBranchDivergence() is true. Summary: This lets us add this pass to the IR pass manager unconditionally; it will simply not do anything on targets without branch divergence. Reviewers: tra Subscribers: llvm-commits, jingyue, rnk, chandlerc Differential Revision: http://reviews.llvm.org/D18625 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@266398 91177308-0d34-0410-b5e6-96231b3b80d8 Justin Lebar 3 years ago
4 changed file(s) with 71 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
185185 (void) llvm::createScalarizerPass();
186186 (void) llvm::createSeparateConstOffsetFromGEPPass();
187187 (void) llvm::createSpeculativeExecutionPass();
188 (void) llvm::createSpeculativeExecutionIfHasBranchDivergencePass();
188189 (void) llvm::createRewriteSymbolsPass();
189190 (void) llvm::createStraightLineStrengthReducePass();
190191 (void) llvm::createMemDerefPrinter();
429429 //
430430 FunctionPass *createSpeculativeExecutionPass();
431431
432 // Same as createSpeculativeExecutionPass, but does nothing unless
433 // TargetTransformInfo::hasBranchDivergence() is true.
434 FunctionPass *createSpeculativeExecutionIfHasBranchDivergencePass();
435
432436 //===----------------------------------------------------------------------===//
433437 //
434438 // LoadCombine - Combine loads into bigger loads.
4848 // aimed at introducing cheap selects, while this pass is intended to do more
4949 // aggressive speculation while counting on later passes to either capitalize on
5050 // that or clean it up.
51 //
52 // If the pass was created by calling
53 // createSpeculativeExecutionIfHasBranchDivergencePass or the
54 // -spec-exec-only-if-divergent-target option is present, this pass only has an
55 // effect on targets where TargetTransformInfo::hasBranchDivergence() is true;
56 // on other targets, it is a nop.
57 //
58 // This lets you include this pass unconditionally in the IR pass pipeline, but
59 // only enable it for relevant targets.
5160 //
5261 //===----------------------------------------------------------------------===//
5362
8291 "number of instructions that would not be speculatively executed "
8392 "exceeds this limit."));
8493
94 static cl::opt SpecExecOnlyIfDivergentTarget(
95 "spec-exec-only-if-divergent-target", cl::init(0), cl::Hidden,
96 cl::desc("Speculative execution is applied only to targets with divergent "
97 "branches, even if the pass was configured to apply only to all "
98 "targets."));
99
85100 namespace {
101
86102 class SpeculativeExecution : public FunctionPass {
87103 public:
88 static char ID;
89 SpeculativeExecution(): FunctionPass(ID) {}
90
91 void getAnalysisUsage(AnalysisUsage &AU) const override;
92 bool runOnFunction(Function &F) override;
104 static char ID;
105 explicit SpeculativeExecution(bool OnlyIfDivergentTarget = false)
106 : FunctionPass(ID),
107 OnlyIfDivergentTarget(OnlyIfDivergentTarget ||
108 SpecExecOnlyIfDivergentTarget) {}
109
110 void getAnalysisUsage(AnalysisUsage &AU) const override;
111 bool runOnFunction(Function &F) override;
112
113 const char *getPassName() const override {
114 if (OnlyIfDivergentTarget)
115 return "Speculatively execute instructions if target has divergent "
116 "branches";
117 return "Speculatively execute instructions";
118 }
93119
94120 private:
95121 bool runOnBasicBlock(BasicBlock &B);
96122 bool considerHoistingFromTo(BasicBlock &FromBlock, BasicBlock &ToBlock);
97123
124 // If true, this pass is a nop unless the target Targetitecture has branch
125 // divergence.
126 const bool OnlyIfDivergentTarget;
98127 const TargetTransformInfo *TTI = nullptr;
99128 };
100129 } // namespace
104133 "Speculatively execute instructions", false, false)
105134 INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
106135 INITIALIZE_PASS_END(SpeculativeExecution, "speculative-execution",
107 "Speculatively execute instructions", false, false)
136 "Speculatively execute instructions", false, false)
108137
109138 void SpeculativeExecution::getAnalysisUsage(AnalysisUsage &AU) const {
110139 AU.addRequired();
115144 return false;
116145
117146 TTI = &getAnalysis().getTTI(F);
147 if (OnlyIfDivergentTarget && !TTI->hasBranchDivergence()) {
148 DEBUG(dbgs() << "Not running SpeculativeExecution because "
149 "TTI->hasBranchDivergence() is false.\n");
150 return false;
151 }
118152
119153 bool Changed = false;
120154 for (auto& B : F) {
239273 return new SpeculativeExecution();
240274 }
241275
276 FunctionPass *createSpeculativeExecutionIfHasBranchDivergencePass() {
277 return new SpeculativeExecution(/* OnlyIfDivergentTarget = */ true);
278 }
279
242280 } // namespace llvm
0 ; RUN: opt < %s -S -mtriple=nvptx-nvidia-cuda -speculative-execution | \
1 ; RUN: FileCheck --check-prefix=ON %s
2 ; RUN: opt < %s -S -mtriple=nvptx-nvidia-cuda -speculative-execution \
3 ; RUN: -spec-exec-only-if-divergent-target | \
4 ; RUN: FileCheck --check-prefix=ON %s
5 ; RUN: opt < %s -S -march=x86_64 -speculative-execution \
6 ; RUN: -spec-exec-only-if-divergent-target | \
7 ; RUN: FileCheck --check-prefix=OFF %s
8
9 ; Hoist in if-then pattern.
10 define void @f() {
11 ; ON: %x = add i32 2, 3
12 ; ON: br i1 true
13 ; OFF: br i1 true
14 ; OFF: %x = add i32 2, 3
15 br i1 true, label %a, label %b
16 a:
17 %x = add i32 2, 3
18 br label %b
19 b:
20 ret void
21 }