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