LLVM  9.0.0svn
SpeculativeExecution.h
Go to the documentation of this file.
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 
66 #include "llvm/IR/PassManager.h"
67 
68 namespace llvm {
70  : public PassInfoMixin<SpeculativeExecutionPass> {
71 public:
72  SpeculativeExecutionPass(bool OnlyIfDivergentTarget = false);
73 
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
This class represents lattice values for constants.
Definition: AllocatorList.h:23
F(f)
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition: PassManager.h:372
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:153
LLVM Basic Block Representation.
Definition: BasicBlock.h:57
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)