diff options
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/Scalar.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp | 96 |
2 files changed, 58 insertions, 40 deletions
diff --git a/llvm/lib/Transforms/Scalar/Scalar.cpp b/llvm/lib/Transforms/Scalar/Scalar.cpp index a122984fcf7..4cc61d64647 100644 --- a/llvm/lib/Transforms/Scalar/Scalar.cpp +++ b/llvm/lib/Transforms/Scalar/Scalar.cpp @@ -80,7 +80,7 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) { initializeSinkingLegacyPassPass(Registry); initializeTailCallElimPass(Registry); initializeSeparateConstOffsetFromGEPPass(Registry); - initializeSpeculativeExecutionPass(Registry); + initializeSpeculativeExecutionLegacyPassPass(Registry); initializeStraightLineStrengthReducePass(Registry); initializeLoadCombinePass(Registry); initializePlaceBackedgeSafepointsImplPass(Registry); diff --git a/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp index 9bf2d620681..b33ca5cbc99 100644 --- a/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp +++ b/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp @@ -61,9 +61,9 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Transforms/Scalar/SpeculativeExecution.h" #include "llvm/ADT/SmallSet.h" #include "llvm/Analysis/GlobalsModRef.h" -#include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Module.h" @@ -101,58 +101,62 @@ static cl::opt<bool> SpecExecOnlyIfDivergentTarget( namespace { -class SpeculativeExecution : public FunctionPass { - public: - 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 architecture has branch - // divergence. +class SpeculativeExecutionLegacyPass : public FunctionPass { +public: + static char ID; + explicit SpeculativeExecutionLegacyPass(bool OnlyIfDivergentTarget = false) + : FunctionPass(ID), OnlyIfDivergentTarget(OnlyIfDivergentTarget || + SpecExecOnlyIfDivergentTarget), + Impl(OnlyIfDivergentTarget) {} + + 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: + // Variable preserved purely for correct name printing. const bool OnlyIfDivergentTarget; - const TargetTransformInfo *TTI = nullptr; + + SpeculativeExecutionPass Impl; }; } // namespace -char SpeculativeExecution::ID = 0; -INITIALIZE_PASS_BEGIN(SpeculativeExecution, "speculative-execution", +char SpeculativeExecutionLegacyPass::ID = 0; +INITIALIZE_PASS_BEGIN(SpeculativeExecutionLegacyPass, "speculative-execution", "Speculatively execute instructions", false, false) INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) -INITIALIZE_PASS_END(SpeculativeExecution, "speculative-execution", +INITIALIZE_PASS_END(SpeculativeExecutionLegacyPass, "speculative-execution", "Speculatively execute instructions", false, false) -void SpeculativeExecution::getAnalysisUsage(AnalysisUsage &AU) const { +void SpeculativeExecutionLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<TargetTransformInfoWrapperPass>(); AU.addPreserved<GlobalsAAWrapperPass>(); } -bool SpeculativeExecution::runOnFunction(Function &F) { +bool SpeculativeExecutionLegacyPass::runOnFunction(Function &F) { if (skipFunction(F)) return false; - TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F); + auto *TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F); + return Impl.runImpl(F, TTI); +} + +namespace llvm { + +bool SpeculativeExecutionPass::runImpl(Function &F, TargetTransformInfo *TTI) { if (OnlyIfDivergentTarget && !TTI->hasBranchDivergence()) { DEBUG(dbgs() << "Not running SpeculativeExecution because " "TTI->hasBranchDivergence() is false.\n"); return false; } + this->TTI = TTI; bool Changed = false; for (auto& B : F) { Changed |= runOnBasicBlock(B); @@ -160,7 +164,7 @@ bool SpeculativeExecution::runOnFunction(Function &F) { return Changed; } -bool SpeculativeExecution::runOnBasicBlock(BasicBlock &B) { +bool SpeculativeExecutionPass::runOnBasicBlock(BasicBlock &B) { BranchInst *BI = dyn_cast<BranchInst>(B.getTerminator()); if (BI == nullptr) return false; @@ -227,8 +231,8 @@ static unsigned ComputeSpeculationCost(const Instruction *I, } } -bool SpeculativeExecution::considerHoistingFromTo(BasicBlock &FromBlock, - BasicBlock &ToBlock) { +bool SpeculativeExecutionPass::considerHoistingFromTo( + BasicBlock &FromBlock, BasicBlock &ToBlock) { SmallSet<const Instruction *, 8> NotHoisted; const auto AllPrecedingUsesFromBlockHoisted = [&NotHoisted](User *U) { for (Value* V : U->operand_values()) { @@ -270,14 +274,28 @@ bool SpeculativeExecution::considerHoistingFromTo(BasicBlock &FromBlock, return true; } -namespace llvm { - FunctionPass *createSpeculativeExecutionPass() { - return new SpeculativeExecution(); + return new SpeculativeExecutionLegacyPass(); } FunctionPass *createSpeculativeExecutionIfHasBranchDivergencePass() { - return new SpeculativeExecution(/* OnlyIfDivergentTarget = */ true); + return new SpeculativeExecutionLegacyPass(/* OnlyIfDivergentTarget = */ true); } +SpeculativeExecutionPass::SpeculativeExecutionPass(bool OnlyIfDivergentTarget) + : OnlyIfDivergentTarget(OnlyIfDivergentTarget || + SpecExecOnlyIfDivergentTarget) {} + +PreservedAnalyses SpeculativeExecutionPass::run(Function &F, + FunctionAnalysisManager &AM) { + auto *TTI = &AM.getResult<TargetIRAnalysis>(F); + + bool Changed = runImpl(F, TTI); + + if (!Changed) + return PreservedAnalyses::all(); + PreservedAnalyses PA; + PA.preserve<GlobalsAA>(); + return PA; +} } // namespace llvm |

