1//===- JumpThreading.h - thread control through conditional BBs -*- 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/// \file
10/// See the comments on JumpThreadingPass.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_TRANSFORMS_SCALAR_JUMPTHREADING_H
15#define LLVM_TRANSFORMS_SCALAR_JUMPTHREADING_H
16
17#include "llvm/ADT/ArrayRef.h"
18#include "llvm/ADT/DenseSet.h"
19#include "llvm/ADT/SmallSet.h"
20#include "llvm/ADT/SmallVector.h"
21#include "llvm/Analysis/BlockFrequencyInfo.h"
22#include "llvm/Analysis/BranchProbabilityInfo.h"
23#include "llvm/Analysis/DomTreeUpdater.h"
24#include "llvm/IR/ValueHandle.h"
25#include "llvm/Support/Compiler.h"
26#include "llvm/Transforms/Utils/ValueMapper.h"
27#include <utility>
28
29namespace llvm {
30
31class AAResults;
32class BasicBlock;
33class BinaryOperator;
34class BranchInst;
35class CmpInst;
36class Constant;
37class Function;
38class Instruction;
39class IntrinsicInst;
40class LazyValueInfo;
41class LoadInst;
42class PHINode;
43class SelectInst;
44class SwitchInst;
45class TargetLibraryInfo;
46class TargetTransformInfo;
47class Value;
48
49/// A private "module" namespace for types and utilities used by
50/// JumpThreading.
51/// These are implementation details and should not be used by clients.
52namespace jumpthreading {
53
54// These are at global scope so static functions can use them too.
55using PredValueInfo = SmallVectorImpl<std::pair<Constant *, BasicBlock *>>;
56using PredValueInfoTy = SmallVector<std::pair<Constant *, BasicBlock *>, 8>;
57
58// This is used to keep track of what kind of constant we're currently hoping
59// to find.
60enum ConstantPreference { WantInteger, WantBlockAddress };
61
62} // end namespace jumpthreading
63
64/// This pass performs 'jump threading', which looks at blocks that have
65/// multiple predecessors and multiple successors. If one or more of the
66/// predecessors of the block can be proven to always jump to one of the
67/// successors, we forward the edge from the predecessor to the successor by
68/// duplicating the contents of this block.
69///
70/// An example of when this can occur is code like this:
71///
72/// if () { ...
73/// X = 4;
74/// }
75/// if (X < 3) {
76///
77/// In this case, the unconditional branch at the end of the first if can be
78/// revectored to the false side of the second if.
79class JumpThreadingPass : public PassInfoMixin<JumpThreadingPass> {
80 Function *F = nullptr;
81 FunctionAnalysisManager *FAM = nullptr;
82 TargetLibraryInfo *TLI = nullptr;
83 TargetTransformInfo *TTI = nullptr;
84 LazyValueInfo *LVI = nullptr;
85 AAResults *AA = nullptr;
86 std::unique_ptr<DomTreeUpdater> DTU;
87 BlockFrequencyInfo *BFI = nullptr;
88 BranchProbabilityInfo *BPI = nullptr;
89 bool ChangedSinceLastAnalysisUpdate = false;
90 bool HasGuards = false;
91#ifndef LLVM_ENABLE_ABI_BREAKING_CHECKS
92 SmallSet<AssertingVH<const BasicBlock>, 16> LoopHeaders;
93#else
94 SmallPtrSet<const BasicBlock *, 16> LoopHeaders;
95#endif
96
97 // JumpThreading must not processes blocks unreachable from entry. It's a
98 // waste of compute time and can potentially lead to hangs.
99 SmallPtrSet<BasicBlock *, 16> Unreachable;
100
101 unsigned BBDupThreshold;
102 unsigned DefaultBBDupThreshold;
103
104public:
105 LLVM_ABI JumpThreadingPass(int T = -1);
106
107 // Glue for old PM.
108 LLVM_ABI bool runImpl(Function &F, FunctionAnalysisManager *FAM,
109 TargetLibraryInfo *TLI, TargetTransformInfo *TTI,
110 LazyValueInfo *LVI, AAResults *AA,
111 std::unique_ptr<DomTreeUpdater> DTU,
112 BlockFrequencyInfo *BFI, BranchProbabilityInfo *BPI);
113
114 LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
115
116 DomTreeUpdater *getDomTreeUpdater() const { return DTU.get(); }
117 LLVM_ABI void findLoopHeaders(Function &F);
118 LLVM_ABI bool processBlock(BasicBlock *BB);
119 LLVM_ABI bool maybeMergeBasicBlockIntoOnlyPred(BasicBlock *BB);
120 LLVM_ABI void updateSSA(BasicBlock *BB, BasicBlock *NewBB,
121 ValueToValueMapTy &ValueMapping);
122 LLVM_ABI void cloneInstructions(ValueToValueMapTy &ValueMapping,
123 BasicBlock::iterator BI,
124 BasicBlock::iterator BE, BasicBlock *NewBB,
125 BasicBlock *PredBB);
126 LLVM_ABI bool tryThreadEdge(BasicBlock *BB,
127 const SmallVectorImpl<BasicBlock *> &PredBBs,
128 BasicBlock *SuccBB);
129 LLVM_ABI void threadEdge(BasicBlock *BB,
130 const SmallVectorImpl<BasicBlock *> &PredBBs,
131 BasicBlock *SuccBB);
132 LLVM_ABI bool duplicateCondBranchOnPHIIntoPred(
133 BasicBlock *BB, const SmallVectorImpl<BasicBlock *> &PredBBs);
134
135 LLVM_ABI bool computeValueKnownInPredecessorsImpl(
136 Value *V, BasicBlock *BB, jumpthreading::PredValueInfo &Result,
137 jumpthreading::ConstantPreference Preference,
138 SmallPtrSet<Value *, 4> &RecursionSet, Instruction *CxtI = nullptr);
139 bool
140 computeValueKnownInPredecessors(Value *V, BasicBlock *BB,
141 jumpthreading::PredValueInfo &Result,
142 jumpthreading::ConstantPreference Preference,
143 Instruction *CxtI = nullptr) {
144 SmallPtrSet<Value *, 4> RecursionSet;
145 return computeValueKnownInPredecessorsImpl(V, BB, Result, Preference,
146 RecursionSet, CxtI);
147 }
148
149 LLVM_ABI Constant *evaluateOnPredecessorEdge(BasicBlock *BB,
150 BasicBlock *PredPredBB,
151 Value *cond,
152 const DataLayout &DL);
153 LLVM_ABI bool maybethreadThroughTwoBasicBlocks(BasicBlock *BB, Value *Cond);
154 LLVM_ABI void threadThroughTwoBasicBlocks(BasicBlock *PredPredBB,
155 BasicBlock *PredBB, BasicBlock *BB,
156 BasicBlock *SuccBB);
157 LLVM_ABI bool
158 processThreadableEdges(Value *Cond, BasicBlock *BB,
159 jumpthreading::ConstantPreference Preference,
160 Instruction *CxtI = nullptr);
161
162 LLVM_ABI bool processBranchOnPHI(PHINode *PN);
163 LLVM_ABI bool processBranchOnXOR(BinaryOperator *BO);
164 LLVM_ABI bool processImpliedCondition(BasicBlock *BB);
165
166 LLVM_ABI bool simplifyPartiallyRedundantLoad(LoadInst *LI);
167 LLVM_ABI void unfoldSelectInstr(BasicBlock *Pred, BasicBlock *BB,
168 SelectInst *SI, PHINode *SIUse, unsigned Idx);
169
170 LLVM_ABI bool tryToUnfoldSelect(CmpInst *CondCmp, BasicBlock *BB);
171 LLVM_ABI bool tryToUnfoldSelect(SwitchInst *SI, BasicBlock *BB);
172 LLVM_ABI bool tryToUnfoldSelectInCurrBB(BasicBlock *BB);
173
174 LLVM_ABI bool processGuards(BasicBlock *BB);
175 LLVM_ABI bool threadGuard(BasicBlock *BB, IntrinsicInst *Guard,
176 BranchInst *BI);
177
178private:
179 BasicBlock *splitBlockPreds(BasicBlock *BB, ArrayRef<BasicBlock *> Preds,
180 const char *Suffix);
181 void updateBlockFreqAndEdgeWeight(BasicBlock *PredBB, BasicBlock *BB,
182 BasicBlock *NewBB, BasicBlock *SuccBB,
183 BlockFrequencyInfo *BFI,
184 BranchProbabilityInfo *BPI,
185 bool HasProfile);
186 /// Check if the block has profile metadata for its outgoing edges.
187 bool doesBlockHaveProfileData(BasicBlock *BB);
188
189 /// Returns analysis preserved by the pass.
190 PreservedAnalyses getPreservedAnalysis() const;
191
192 /// Helper function to run "external" analysis in the middle of JumpThreading.
193 /// It takes care of updating/invalidating other existing analysis
194 /// before/after running the "external" one.
195 template <typename AnalysisT>
196 typename AnalysisT::Result *runExternalAnalysis();
197
198 /// Returns an existing instance of BPI if any, otherwise nullptr. By
199 /// "existing" we mean either cached result provided by FunctionAnalysisManger
200 /// or created by preceding call to 'getOrCreateBPI'.
201 BranchProbabilityInfo *getBPI();
202
203 /// Returns an existing instance of BFI if any, otherwise nullptr. By
204 /// "existing" we mean either cached result provided by FunctionAnalysisManger
205 /// or created by preceding call to 'getOrCreateBFI'.
206 BlockFrequencyInfo *getBFI();
207
208 /// Returns an existing instance of BPI if any, otherwise:
209 /// if 'HasProfile' is true creates new instance through
210 /// FunctionAnalysisManager, otherwise nullptr.
211 BranchProbabilityInfo *getOrCreateBPI(bool Force = false);
212
213 /// Returns an existing instance of BFI if any, otherwise:
214 /// if 'HasProfile' is true creates new instance through
215 /// FunctionAnalysisManager, otherwise nullptr.
216 BlockFrequencyInfo *getOrCreateBFI(bool Force = false);
217
218 // Internal overload of evaluateOnPredecessorEdge().
219 Constant *evaluateOnPredecessorEdge(BasicBlock *BB, BasicBlock *PredPredBB,
220 Value *cond, const DataLayout &DL,
221 SmallPtrSet<Value *, 8> &Visited);
222};
223
224} // end namespace llvm
225
226#endif // LLVM_TRANSFORMS_SCALAR_JUMPTHREADING_H
227