Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:42

0001 //===- SpeculativeExecution.h -----------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This pass hoists instructions to enable speculative execution on
0010 // targets where branches are expensive. This is aimed at GPUs. It
0011 // currently works on simple if-then and if-then-else
0012 // patterns.
0013 //
0014 // Removing branches is not the only motivation for this
0015 // pass. E.g. consider this code and assume that there is no
0016 // addressing mode for multiplying by sizeof(*a):
0017 //
0018 //   if (b > 0)
0019 //     c = a[i + 1]
0020 //   if (d > 0)
0021 //     e = a[i + 2]
0022 //
0023 // turns into
0024 //
0025 //   p = &a[i + 1];
0026 //   if (b > 0)
0027 //     c = *p;
0028 //   q = &a[i + 2];
0029 //   if (d > 0)
0030 //     e = *q;
0031 //
0032 // which could later be optimized to
0033 //
0034 //   r = &a[i];
0035 //   if (b > 0)
0036 //     c = r[1];
0037 //   if (d > 0)
0038 //     e = r[2];
0039 //
0040 // Later passes sink back much of the speculated code that did not enable
0041 // further optimization.
0042 //
0043 // This pass is more aggressive than the function SpeculativeyExecuteBB in
0044 // SimplifyCFG. SimplifyCFG will not speculate if no selects are introduced and
0045 // it will speculate at most one instruction. It also will not speculate if
0046 // there is a value defined in the if-block that is only used in the then-block.
0047 // These restrictions make sense since the speculation in SimplifyCFG seems
0048 // aimed at introducing cheap selects, while this pass is intended to do more
0049 // aggressive speculation while counting on later passes to either capitalize on
0050 // that or clean it up.
0051 //
0052 // If the pass was created by calling
0053 // createSpeculativeExecutionIfHasBranchDivergencePass or the
0054 // -spec-exec-only-if-divergent-target option is present, this pass only has an
0055 // effect on targets where TargetTransformInfo::hasBranchDivergence() is true;
0056 // on other targets, it is a nop.
0057 //
0058 // This lets you include this pass unconditionally in the IR pass pipeline, but
0059 // only enable it for relevant targets.
0060 //
0061 //===----------------------------------------------------------------------===//
0062 #ifndef LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H
0063 #define LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H
0064 
0065 #include "llvm/IR/PassManager.h"
0066 
0067 namespace llvm {
0068 class BasicBlock;
0069 class TargetTransformInfo;
0070 
0071 class SpeculativeExecutionPass
0072     : public PassInfoMixin<SpeculativeExecutionPass> {
0073 public:
0074   SpeculativeExecutionPass(bool OnlyIfDivergentTarget = false);
0075 
0076   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
0077 
0078   void printPipeline(raw_ostream &OS,
0079                      function_ref<StringRef(StringRef)> MapClassName2PassName);
0080 
0081   // Glue for old PM
0082   bool runImpl(Function &F, TargetTransformInfo *TTI);
0083 
0084 private:
0085   bool runOnBasicBlock(BasicBlock &B);
0086   bool considerHoistingFromTo(BasicBlock &FromBlock, BasicBlock &ToBlock);
0087 
0088   // If true, this pass is a nop unless the target architecture has branch
0089   // divergence.
0090   const bool OnlyIfDivergentTarget = false;
0091 
0092   TargetTransformInfo *TTI = nullptr;
0093 };
0094 }
0095 
0096 #endif // LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H