diff options
Diffstat (limited to 'contrib/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp')
-rw-r--r-- | contrib/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp | 114 |
1 files changed, 75 insertions, 39 deletions
diff --git a/contrib/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp b/contrib/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp index 9bf2d62..a7c308b 100644 --- a/contrib/llvm/lib/Transforms/Scalar/SpeculativeExecution.cpp +++ b/contrib/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; + + StringRef 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; @@ -220,6 +224,24 @@ static unsigned ComputeSpeculationCost(const Instruction *I, case Instruction::Xor: case Instruction::ZExt: case Instruction::SExt: + case Instruction::Call: + case Instruction::BitCast: + case Instruction::PtrToInt: + case Instruction::IntToPtr: + case Instruction::AddrSpaceCast: + case Instruction::FPToUI: + case Instruction::FPToSI: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::FPExt: + case Instruction::FPTrunc: + case Instruction::FAdd: + case Instruction::FSub: + case Instruction::FMul: + case Instruction::FDiv: + case Instruction::FRem: + case Instruction::ICmp: + case Instruction::FCmp: return TTI.getUserCost(I); default: @@ -227,8 +249,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 +292,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 |