- //===- SpeculativeExecution.h -----------------------------------*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- // This pass hoists instructions to enable speculative execution on 
- // targets where branches are expensive. This is aimed at GPUs. It 
- // currently works on simple if-then and if-then-else 
- // patterns. 
- // 
- // Removing branches is not the only motivation for this 
- // pass. E.g. consider this code and assume that there is no 
- // addressing mode for multiplying by sizeof(*a): 
- // 
- //   if (b > 0) 
- //     c = a[i + 1] 
- //   if (d > 0) 
- //     e = a[i + 2] 
- // 
- // turns into 
- // 
- //   p = &a[i + 1]; 
- //   if (b > 0) 
- //     c = *p; 
- //   q = &a[i + 2]; 
- //   if (d > 0) 
- //     e = *q; 
- // 
- // which could later be optimized to 
- // 
- //   r = &a[i]; 
- //   if (b > 0) 
- //     c = r[1]; 
- //   if (d > 0) 
- //     e = r[2]; 
- // 
- // Later passes sink back much of the speculated code that did not enable 
- // further optimization. 
- // 
- // This pass is more aggressive than the function SpeculativeyExecuteBB in 
- // SimplifyCFG. SimplifyCFG will not speculate if no selects are introduced and 
- // it will speculate at most one instruction. It also will not speculate if 
- // there is a value defined in the if-block that is only used in the then-block. 
- // These restrictions make sense since the speculation in SimplifyCFG seems 
- // aimed at introducing cheap selects, while this pass is intended to do more 
- // aggressive speculation while counting on later passes to either capitalize on 
- // that or clean it up. 
- // 
- // If the pass was created by calling 
- // createSpeculativeExecutionIfHasBranchDivergencePass or the 
- // -spec-exec-only-if-divergent-target option is present, this pass only has an 
- // effect on targets where TargetTransformInfo::hasBranchDivergence() is true; 
- // on other targets, it is a nop. 
- // 
- // This lets you include this pass unconditionally in the IR pass pipeline, but 
- // only enable it for relevant targets. 
- // 
- //===----------------------------------------------------------------------===// 
- #ifndef LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H 
- #define LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H 
-   
- #include "llvm/IR/PassManager.h" 
-   
- namespace llvm { 
- class TargetTransformInfo; 
- class SpeculativeExecutionPass 
-     : public PassInfoMixin<SpeculativeExecutionPass> { 
- public: 
-   SpeculativeExecutionPass(bool OnlyIfDivergentTarget = false); 
-   
-   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); 
-   
-   // Glue for old PM 
-   bool runImpl(Function &F, TargetTransformInfo *TTI); 
-   
- 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. 
-   const bool OnlyIfDivergentTarget = false; 
-   
-   TargetTransformInfo *TTI = nullptr; 
- }; 
- } 
-   
- #endif // LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H 
-