LLVM  8.0.1
SpeculativeExecution.h
Go to the documentation of this file.
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 
67 #include "llvm/IR/PassManager.h"
68 
69 namespace llvm {
71  : public PassInfoMixin<SpeculativeExecutionPass> {
72 public:
73  SpeculativeExecutionPass(bool OnlyIfDivergentTarget = false);
74 
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
This class represents lattice values for constants.
Definition: AllocatorList.h:24
F(f)
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition: PassManager.h:366
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:154
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
SpeculativeExecutionPass(bool OnlyIfDivergentTarget=false)
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
bool runImpl(Function &F, TargetTransformInfo *TTI)
A container for analyses that lazily runs them and caches their results.
This pass exposes codegen information to IR-level passes.
This header defines various interfaces for pass management in LLVM.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)