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) {
 
  177  if (&
B == &Succ0 || &
B == &Succ1 || &Succ0 == &Succ1) {
 
  184    return considerHoistingFromTo(Succ0, 
B);
 
  190    return considerHoistingFromTo(Succ1, 
B);
 
  202    if (Succ1.
size() == 1) 
 
  203      return considerHoistingFromTo(Succ0, 
B);
 
  204    if (Succ0.
size() == 1) 
 
  205      return considerHoistingFromTo(Succ1, 
B);
 
  214    case Instruction::GetElementPtr:
 
  215    case Instruction::Add:
 
  216    case Instruction::Mul:
 
  217    case Instruction::And:
 
  218    case Instruction::Or:
 
  219    case Instruction::Select:
 
  220    case Instruction::Shl:
 
  221    case Instruction::Sub:
 
  222    case Instruction::LShr:
 
  223    case Instruction::AShr:
 
  224    case Instruction::Xor:
 
  225    case Instruction::ZExt:
 
  226    case Instruction::SExt:
 
  227    case Instruction::Call:
 
  228    case Instruction::BitCast:
 
  229    case Instruction::PtrToInt:
 
  230    case Instruction::PtrToAddr:
 
  231    case Instruction::IntToPtr:
 
  232    case Instruction::AddrSpaceCast:
 
  233    case Instruction::FPToUI:
 
  234    case Instruction::FPToSI:
 
  235    case Instruction::UIToFP:
 
  236    case Instruction::SIToFP:
 
  237    case Instruction::FPExt:
 
  238    case Instruction::FPTrunc:
 
  239    case Instruction::FAdd:
 
  240    case Instruction::FSub:
 
  241    case Instruction::FMul:
 
  242    case Instruction::FDiv:
 
  243    case Instruction::FRem:
 
  244    case Instruction::FNeg:
 
  245    case Instruction::ICmp:
 
  246    case Instruction::FCmp:
 
  247    case Instruction::Trunc:
 
  248    case Instruction::Freeze:
 
  249    case Instruction::ExtractElement:
 
  250    case Instruction::InsertElement:
 
  251    case Instruction::ShuffleVector:
 
  252    case Instruction::ExtractValue:
 
  253    case Instruction::InsertValue:
 
 
  284bool SpeculativeExecutionPass::considerHoistingFromTo(
 
  285    BasicBlock &FromBlock, BasicBlock &ToBlock) {
 
  286  SmallPtrSet<const Instruction *, 8> NotHoisted;
 
  287  auto HasNoUnhoistedInstr = [&NotHoisted](
auto Values) {
 
  288    for (
const Value *V : Values) {
 
  295  auto AllPrecedingUsesFromBlockHoisted =
 
  296      [&HasNoUnhoistedInstr](
const User *
U) {
 
  297        return HasNoUnhoistedInstr(
U->operand_values());
 
  301  unsigned NotHoistedInstCount = 0;
 
  302  for (
const auto &
I : FromBlock) {
 
  305        AllPrecedingUsesFromBlockHoisted(&
I)) {
 
  306      TotalSpeculationCost += 
Cost;
 
  310      NotHoistedInstCount++;
 
  317  for (
auto I = FromBlock.begin(); 
I != FromBlock.end();) {
 
  322    if (!NotHoisted.
count(&*Current)) {
 
  324      Current->dropLocation();
 
  331  return new SpeculativeExecutionLegacyPass();
 
 
  335  return new SpeculativeExecutionLegacyPass( 
true);
 
 
  339    : OnlyIfDivergentTarget(OnlyIfDivergentTarget ||
 
 
  358      OS, MapClassName2PassName);
 
  360  if (OnlyIfDivergentTarget)
 
  361    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...
Conditional or Unconditional Branch instruction.
unsigned getNumSuccessors() const
BasicBlock * getSuccessor(unsigned i) const
Represents analyses that only rely on functions' control flow.
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.