77#define DEBUG_TYPE "speculative-execution"
83 cl::desc(
"Speculative execution is not applied to basic blocks where "
84 "the cost of the instructions to speculatively execute "
85 "exceeds this limit."));
93 cl::desc(
"Speculative execution is not applied to basic blocks where the "
94 "number of instructions that would not be speculatively executed "
95 "exceeds this limit."));
99 cl::desc(
"Speculative execution is applied only to targets with divergent "
100 "branches, even if the pass was configured to apply only to all "
105class SpeculativeExecutionLegacyPass :
public FunctionPass {
108 explicit SpeculativeExecutionLegacyPass(
bool OnlyIfDivergentTarget =
false)
109 :
FunctionPass(
ID), OnlyIfDivergentTarget(OnlyIfDivergentTarget ||
111 Impl(OnlyIfDivergentTarget) {}
113 void getAnalysisUsage(AnalysisUsage &AU)
const override;
116 StringRef getPassName()
const override {
117 if (OnlyIfDivergentTarget)
118 return "Speculatively execute instructions if target has divergent "
120 return "Speculatively execute instructions";
125 const bool OnlyIfDivergentTarget;
127 SpeculativeExecutionPass Impl;
131char SpeculativeExecutionLegacyPass::ID = 0;
133 "Speculatively execute instructions",
false,
false)
138void SpeculativeExecutionLegacyPass::getAnalysisUsage(
AnalysisUsage &AU)
const {
141 AU.setPreservesCFG();
144bool SpeculativeExecutionLegacyPass::runOnFunction(
Function &
F) {
148 auto *
TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
153 if (OnlyIfDivergentTarget && !TTI->hasBranchDivergence(&
F)) {
155 "TTI->hasBranchDivergence() is false.\n");
167bool SpeculativeExecutionPass::runOnBasicBlock(
BasicBlock &
B) {
175 if (&
B == &Succ0 || &
B == &Succ1 || &Succ0 == &Succ1) {
182 return considerHoistingFromTo(Succ0,
B);
188 return considerHoistingFromTo(Succ1,
B);
200 if (Succ1.
size() == 1)
201 return considerHoistingFromTo(Succ0,
B);
202 if (Succ0.
size() == 1)
203 return considerHoistingFromTo(Succ1,
B);
212 case Instruction::GetElementPtr:
213 case Instruction::Add:
214 case Instruction::Mul:
215 case Instruction::And:
216 case Instruction::Or:
217 case Instruction::Select:
218 case Instruction::Shl:
219 case Instruction::Sub:
220 case Instruction::LShr:
221 case Instruction::AShr:
222 case Instruction::Xor:
223 case Instruction::ZExt:
224 case Instruction::SExt:
225 case Instruction::Call:
226 case Instruction::BitCast:
227 case Instruction::PtrToInt:
228 case Instruction::PtrToAddr:
229 case Instruction::IntToPtr:
230 case Instruction::AddrSpaceCast:
231 case Instruction::FPToUI:
232 case Instruction::FPToSI:
233 case Instruction::UIToFP:
234 case Instruction::SIToFP:
235 case Instruction::FPExt:
236 case Instruction::FPTrunc:
237 case Instruction::FAdd:
238 case Instruction::FSub:
239 case Instruction::FMul:
240 case Instruction::FDiv:
241 case Instruction::FRem:
242 case Instruction::FNeg:
243 case Instruction::ICmp:
244 case Instruction::FCmp:
245 case Instruction::Trunc:
246 case Instruction::Freeze:
247 case Instruction::ExtractElement:
248 case Instruction::InsertElement:
249 case Instruction::ShuffleVector:
250 case Instruction::ExtractValue:
251 case Instruction::InsertValue:
282bool SpeculativeExecutionPass::considerHoistingFromTo(
283 BasicBlock &FromBlock, BasicBlock &ToBlock) {
284 SmallPtrSet<const Instruction *, 8> NotHoisted;
285 auto HasNoUnhoistedInstr = [&NotHoisted](
auto Values) {
286 for (
const Value *V : Values) {
293 auto AllPrecedingUsesFromBlockHoisted =
294 [&HasNoUnhoistedInstr](
const User *
U) {
295 return HasNoUnhoistedInstr(
U->operand_values());
299 unsigned NotHoistedInstCount = 0;
300 for (
const auto &
I : FromBlock) {
303 AllPrecedingUsesFromBlockHoisted(&
I)) {
304 TotalSpeculationCost +=
Cost;
308 NotHoistedInstCount++;
315 for (
auto I = FromBlock.begin();
I != FromBlock.end();) {
320 if (!NotHoisted.
count(&*Current)) {
322 Current->dropLocation();
329 return new SpeculativeExecutionLegacyPass();
333 return new SpeculativeExecutionLegacyPass(
true);
337 : OnlyIfDivergentTarget(OnlyIfDivergentTarget ||
356 OS, MapClassName2PassName);
358 if (OnlyIfDivergentTarget)
359 OS <<
"only-if-divergent-target";
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool runOnFunction(Function &F, bool PostInlining)
This is the interface for a simple mod/ref and alias analysis over globals.
static bool runOnBasicBlock(MachineBasicBlock *MBB, unsigned BasicBlockNum, VRegRenamer &Renamer)
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file defines the SmallPtrSet class.
static cl::opt< unsigned > SpecExecMaxNotHoisted("spec-exec-max-not-hoisted", cl::init(5), cl::Hidden, cl::desc("Speculative execution is not applied to basic blocks where the " "number of instructions that would not be speculatively executed " "exceeds this limit."))
static cl::opt< unsigned > SpecExecMaxSpeculationCost("spec-exec-max-speculation-cost", cl::init(7), cl::Hidden, cl::desc("Speculative execution is not applied to basic blocks where " "the cost of the instructions to speculatively execute " "exceeds this limit."))
static InstructionCost ComputeSpeculationCost(const Instruction *I, const TargetTransformInfo &TTI)
static cl::opt< bool > SpecExecOnlyIfDivergentTarget("spec-exec-only-if-divergent-target", cl::init(false), 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."))
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
LLVM Basic Block Representation.
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
LLVM_ABI const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Represents analyses that only rely on functions' control flow.
Conditional Branch instruction.
BasicBlock * getSuccessor(unsigned i) const
FunctionPass class - This class is used to implement most global optimizations.
Legacy wrapper pass to provide the GlobalsAAResult object.
static InstructionCost getInvalid(CostType Val=0)
unsigned getOpcode() const
Return the opcode for this Instruction or ConstantExpr.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
bool runImpl(Function &F, TargetTransformInfo *TTI)
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
SpeculativeExecutionPass(bool OnlyIfDivergentTarget=false)
StringRef - Represent a constant reference to a string, i.e.
Analysis pass providing the TargetTransformInfo.
An efficient, type-erasing, non-owning reference to a callable.
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
@ User
could "use" a pointer
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI FunctionPass * createSpeculativeExecutionIfHasBranchDivergencePass()
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI FunctionPass * createSpeculativeExecutionPass()
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
A CRTP mix-in to automatically provide informational APIs needed for passes.