[llvm] r266398 - [Speculation] Add a SpeculativeExecution mode where the pass does nothing unless TTI::hasBranchDivergence() is true.
Justin Lebar via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 14 17:32:10 PDT 2016
Author: jlebar
Date: Thu Apr 14 19:32:09 2016
New Revision: 266398
URL: http://llvm.org/viewvc/llvm-project?rev=266398&view=rev
Log:
[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
Added:
llvm/trunk/test/Transforms/SpeculativeExecution/divergent-target.ll
Modified:
llvm/trunk/include/llvm/LinkAllPasses.h
llvm/trunk/include/llvm/Transforms/Scalar.h
llvm/trunk/lib/Transforms/Scalar/SpeculativeExecution.cpp
Modified: llvm/trunk/include/llvm/LinkAllPasses.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=266398&r1=266397&r2=266398&view=diff
==============================================================================
--- llvm/trunk/include/llvm/LinkAllPasses.h (original)
+++ llvm/trunk/include/llvm/LinkAllPasses.h Thu Apr 14 19:32:09 2016
@@ -186,6 +186,7 @@ namespace {
(void) llvm::createScalarizerPass();
(void) llvm::createSeparateConstOffsetFromGEPPass();
(void) llvm::createSpeculativeExecutionPass();
+ (void) llvm::createSpeculativeExecutionIfHasBranchDivergencePass();
(void) llvm::createRewriteSymbolsPass();
(void) llvm::createStraightLineStrengthReducePass();
(void) llvm::createMemDerefPrinter();
Modified: llvm/trunk/include/llvm/Transforms/Scalar.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar.h?rev=266398&r1=266397&r2=266398&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Scalar.h (original)
+++ llvm/trunk/include/llvm/Transforms/Scalar.h Thu Apr 14 19:32:09 2016
@@ -430,6 +430,10 @@ createSeparateConstOffsetFromGEPPass(con
//
FunctionPass *createSpeculativeExecutionPass();
+// Same as createSpeculativeExecutionPass, but does nothing unless
+// TargetTransformInfo::hasBranchDivergence() is true.
+FunctionPass *createSpeculativeExecutionIfHasBranchDivergencePass();
+
//===----------------------------------------------------------------------===//
//
// LoadCombine - Combine loads into bigger loads.
Modified: llvm/trunk/lib/Transforms/Scalar/SpeculativeExecution.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SpeculativeExecution.cpp?rev=266398&r1=266397&r2=266398&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/SpeculativeExecution.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/SpeculativeExecution.cpp Thu Apr 14 19:32:09 2016
@@ -50,6 +50,15 @@
// aggressive speculation while counting on later passes to either capitalize on
// that or clean it up.
//
+// If the pass was created by calling
+// createSpeculativeExecutionIfHasBranchDivergencePass or the
+// -spec-exec-only-if-divergent-target option is present, this pass only has an
+// effect on targets where TargetTransformInfo::hasBranchDivergence() is true;
+// on other targets, it is a nop.
+//
+// This lets you include this pass unconditionally in the IR pass pipeline, but
+// only enable it for relevant targets.
+//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/SmallSet.h"
@@ -83,19 +92,39 @@ static cl::opt<unsigned> SpecExecMaxNotH
"number of instructions that would not be speculatively executed "
"exceeds this limit."));
+static cl::opt<bool> SpecExecOnlyIfDivergentTarget(
+ "spec-exec-only-if-divergent-target", cl::init(0), cl::Hidden,
+ cl::desc("Speculative execution is applied only to targets with divergent "
+ "branches, even if the pass was configured to apply only to all "
+ "targets."));
+
namespace {
+
class SpeculativeExecution : public FunctionPass {
public:
- static char ID;
- SpeculativeExecution(): FunctionPass(ID) {}
-
- void getAnalysisUsage(AnalysisUsage &AU) const override;
- bool runOnFunction(Function &F) override;
+ static char ID;
+ explicit SpeculativeExecution(bool OnlyIfDivergentTarget = false)
+ : FunctionPass(ID),
+ OnlyIfDivergentTarget(OnlyIfDivergentTarget ||
+ SpecExecOnlyIfDivergentTarget) {}
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+ bool runOnFunction(Function &F) override;
+
+ const char *getPassName() const override {
+ if (OnlyIfDivergentTarget)
+ return "Speculatively execute instructions if target has divergent "
+ "branches";
+ return "Speculatively execute instructions";
+ }
private:
bool runOnBasicBlock(BasicBlock &B);
bool considerHoistingFromTo(BasicBlock &FromBlock, BasicBlock &ToBlock);
+ // If true, this pass is a nop unless the target Targetitecture has branch
+ // divergence.
+ const bool OnlyIfDivergentTarget;
const TargetTransformInfo *TTI = nullptr;
};
} // namespace
@@ -105,7 +134,7 @@ INITIALIZE_PASS_BEGIN(SpeculativeExecuti
"Speculatively execute instructions", false, false)
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
INITIALIZE_PASS_END(SpeculativeExecution, "speculative-execution",
- "Speculatively execute instructions", false, false)
+ "Speculatively execute instructions", false, false)
void SpeculativeExecution::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<TargetTransformInfoWrapperPass>();
@@ -116,6 +145,11 @@ bool SpeculativeExecution::runOnFunction
return false;
TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
+ if (OnlyIfDivergentTarget && !TTI->hasBranchDivergence()) {
+ DEBUG(dbgs() << "Not running SpeculativeExecution because "
+ "TTI->hasBranchDivergence() is false.\n");
+ return false;
+ }
bool Changed = false;
for (auto& B : F) {
@@ -240,4 +274,8 @@ FunctionPass *createSpeculativeExecution
return new SpeculativeExecution();
}
+FunctionPass *createSpeculativeExecutionIfHasBranchDivergencePass() {
+ return new SpeculativeExecution(/* OnlyIfDivergentTarget = */ true);
+}
+
} // namespace llvm
Added: llvm/trunk/test/Transforms/SpeculativeExecution/divergent-target.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SpeculativeExecution/divergent-target.ll?rev=266398&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/SpeculativeExecution/divergent-target.ll (added)
+++ llvm/trunk/test/Transforms/SpeculativeExecution/divergent-target.ll Thu Apr 14 19:32:09 2016
@@ -0,0 +1,22 @@
+; RUN: opt < %s -S -mtriple=nvptx-nvidia-cuda -speculative-execution | \
+; RUN: FileCheck --check-prefix=ON %s
+; RUN: opt < %s -S -mtriple=nvptx-nvidia-cuda -speculative-execution \
+; RUN: -spec-exec-only-if-divergent-target | \
+; RUN: FileCheck --check-prefix=ON %s
+; RUN: opt < %s -S -march=x86_64 -speculative-execution \
+; RUN: -spec-exec-only-if-divergent-target | \
+; RUN: FileCheck --check-prefix=OFF %s
+
+; Hoist in if-then pattern.
+define void @f() {
+; ON: %x = add i32 2, 3
+; ON: br i1 true
+; OFF: br i1 true
+; OFF: %x = add i32 2, 3
+ br i1 true, label %a, label %b
+a:
+ %x = add i32 2, 3
+ br label %b
+b:
+ ret void
+}
More information about the llvm-commits
mailing list