1311116Sdim//===- SpeculativeExecution.h -----------------------------------*- C++ -*-===//
2311116Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6311116Sdim//
7311116Sdim//===----------------------------------------------------------------------===//
8311116Sdim//
9311116Sdim// This pass hoists instructions to enable speculative execution on
10311116Sdim// targets where branches are expensive. This is aimed at GPUs. It
11311116Sdim// currently works on simple if-then and if-then-else
12311116Sdim// patterns.
13311116Sdim//
14311116Sdim// Removing branches is not the only motivation for this
15311116Sdim// pass. E.g. consider this code and assume that there is no
16311116Sdim// addressing mode for multiplying by sizeof(*a):
17311116Sdim//
18311116Sdim//   if (b > 0)
19311116Sdim//     c = a[i + 1]
20311116Sdim//   if (d > 0)
21311116Sdim//     e = a[i + 2]
22311116Sdim//
23311116Sdim// turns into
24311116Sdim//
25311116Sdim//   p = &a[i + 1];
26311116Sdim//   if (b > 0)
27311116Sdim//     c = *p;
28311116Sdim//   q = &a[i + 2];
29311116Sdim//   if (d > 0)
30311116Sdim//     e = *q;
31311116Sdim//
32311116Sdim// which could later be optimized to
33311116Sdim//
34311116Sdim//   r = &a[i];
35311116Sdim//   if (b > 0)
36311116Sdim//     c = r[1];
37311116Sdim//   if (d > 0)
38311116Sdim//     e = r[2];
39311116Sdim//
40311116Sdim// Later passes sink back much of the speculated code that did not enable
41311116Sdim// further optimization.
42311116Sdim//
43311116Sdim// This pass is more aggressive than the function SpeculativeyExecuteBB in
44311116Sdim// SimplifyCFG. SimplifyCFG will not speculate if no selects are introduced and
45311116Sdim// it will speculate at most one instruction. It also will not speculate if
46311116Sdim// there is a value defined in the if-block that is only used in the then-block.
47311116Sdim// These restrictions make sense since the speculation in SimplifyCFG seems
48311116Sdim// aimed at introducing cheap selects, while this pass is intended to do more
49311116Sdim// aggressive speculation while counting on later passes to either capitalize on
50311116Sdim// that or clean it up.
51311116Sdim//
52311116Sdim// If the pass was created by calling
53311116Sdim// createSpeculativeExecutionIfHasBranchDivergencePass or the
54311116Sdim// -spec-exec-only-if-divergent-target option is present, this pass only has an
55311116Sdim// effect on targets where TargetTransformInfo::hasBranchDivergence() is true;
56311116Sdim// on other targets, it is a nop.
57311116Sdim//
58311116Sdim// This lets you include this pass unconditionally in the IR pass pipeline, but
59311116Sdim// only enable it for relevant targets.
60311116Sdim//
61311116Sdim//===----------------------------------------------------------------------===//
62311116Sdim#ifndef LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H
63311116Sdim#define LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H
64311116Sdim
65311116Sdim#include "llvm/Analysis/TargetTransformInfo.h"
66311116Sdim#include "llvm/IR/PassManager.h"
67311116Sdim
68311116Sdimnamespace llvm {
69311116Sdimclass SpeculativeExecutionPass
70311116Sdim    : public PassInfoMixin<SpeculativeExecutionPass> {
71311116Sdimpublic:
72311116Sdim  SpeculativeExecutionPass(bool OnlyIfDivergentTarget = false);
73311116Sdim
74311116Sdim  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
75311116Sdim
76311116Sdim  // Glue for old PM
77311116Sdim  bool runImpl(Function &F, TargetTransformInfo *TTI);
78311116Sdim
79311116Sdimprivate:
80311116Sdim  bool runOnBasicBlock(BasicBlock &B);
81311116Sdim  bool considerHoistingFromTo(BasicBlock &FromBlock, BasicBlock &ToBlock);
82311116Sdim
83311116Sdim  // If true, this pass is a nop unless the target architecture has branch
84341825Sdim  // divergence.
85311116Sdim  const bool OnlyIfDivergentTarget = false;
86311116Sdim
87311116Sdim  TargetTransformInfo *TTI = nullptr;
88311116Sdim};
89311116Sdim}
90311116Sdim
91311116Sdim#endif //LLVM_TRANSFORMS_SCALAR_SPECULATIVEEXECUTION_H
92