1 //===- SpeculativeExecution.h -----------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This pass hoists instructions to enable speculative execution on 11 // targets where branches are expensive. This is aimed at GPUs. It 12 // currently works on simple if-then and if-then-else 13 // patterns. 14 // 15 // Removing branches is not the only motivation for this 16 // pass. E.g. consider this code and assume that there is no 17 // addressing mode for multiplying by sizeof(*a): 18 // 19 // if (b > 0) 20 // c = a[i + 1] 21 // if (d > 0) 22 // e = a[i + 2] 23 // 24 // turns into 25 // 26 // p = &a[i + 1]; 27 // if (b > 0) 28 // c = *p; 29 // q = &a[i + 2]; 30 // if (d > 0) 31 // e = *q; 32 // 33 // which could later be optimized to 34 // 35 // r = &a[i]; 36 // if (b > 0) 37 // c = r[1]; 38 // if (d > 0) 39 // e = r[2]; 40 // 41 // Later passes sink back much of the speculated code that did not enable 42 // further optimization. 43 // 44 // This pass is more aggressive than the function SpeculativeyExecuteBB in 45 // SimplifyCFG. SimplifyCFG will not speculate if no selects are introduced and 46 // it will speculate at most one instruction. It also will not speculate if 47 // there is a value defined in the if-block that is only used in the then-block. 48 // These restrictions make sense since the speculation in SimplifyCFG seems 49 // aimed at introducing cheap selects, while this pass is intended to do more 50 // aggressive speculation while counting on later passes to either capitalize on 51 // that or clean it up. 52 // 53 // If the pass was created by calling 54 // createSpeculativeExecutionIfHasBranchDivergencePass or the 55 // -spec-exec-only-if-divergent-target option is present, this pass only has an 56 // effect on targets where TargetTransformInfo::hasBranchDivergence() is true; 57 // on other targets, it is a nop. 58 // 59 // This lets you include this pass unconditionally in the IR pass pipeline, but 60 // only enable it for relevant targets. 61 // 62 //===----------------------------------------------------------------------===// 63 #ifndef LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H 64 #define LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H 65 66 #include "llvm/Analysis/TargetTransformInfo.h" 67 #include "llvm/IR/PassManager.h" 68 69 namespace llvm { 70 class SpeculativeExecutionPass 71 : public PassInfoMixin<SpeculativeExecutionPass> { 72 public: 73 SpeculativeExecutionPass(bool OnlyIfDivergentTarget = false); 74 75 PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); 76 77 // Glue for old PM 78 bool runImpl(Function &F, TargetTransformInfo *TTI); 79 80 private: 81 bool runOnBasicBlock(BasicBlock &B); 82 bool considerHoistingFromTo(BasicBlock &FromBlock, BasicBlock &ToBlock); 83 84 // If true, this pass is a nop unless the target architecture has branch 85 // divergence. 86 const bool OnlyIfDivergentTarget = false; 87 88 TargetTransformInfo *TTI = nullptr; 89 }; 90 } 91 92 #endif //LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H 93