LLVM 24.0.0git
ControlFlowUtils.cpp
Go to the documentation of this file.
1//===- ControlFlowUtils.cpp - Control Flow Utilities -----------------------==//
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// Utilities to manipulate the CFG and restore SSA for the new control flow.
10//
11//===----------------------------------------------------------------------===//
12
14#include "llvm/ADT/SetVector.h"
17#include "llvm/IR/Constants.h"
20#include "llvm/IR/ValueHandle.h"
22
23#define DEBUG_TYPE "control-flow-hub"
24
25using namespace llvm;
26
29
30// Redirects the terminator of the incoming block to the first guard block in
31// the hub. Returns the branch condition from `BB` if it exits.
32// - If only one of Succ0 or Succ1 is not null, the corresponding branch
33// successor is redirected to the FirstGuardBlock.
34// - Else both are not null, and branch is replaced with an unconditional
35// branch to the FirstGuardBlock.
37 BasicBlock *Succ1, BasicBlock *FirstGuardBlock) {
38 if (auto *Branch = dyn_cast<UncondBrInst>(BB->getTerminator())) {
39 assert(Succ0 == Branch->getSuccessor(0));
40 assert(!Succ1);
41 Branch->setSuccessor(FirstGuardBlock);
42 return nullptr;
43 }
44
45 auto *Branch = cast<CondBrInst>(BB->getTerminator());
46 auto *Condition = Branch->getCondition();
47
48 assert(Succ0 || Succ1);
49 assert(!Succ1 || Succ1 == Branch->getSuccessor(1));
50 if (Succ0 && !Succ1) {
51 Branch->setSuccessor(0, FirstGuardBlock);
52 } else if (Succ1 && !Succ0) {
53 Branch->setSuccessor(1, FirstGuardBlock);
54 } else {
55 Branch->eraseFromParent();
56 UncondBrInst::Create(FirstGuardBlock, BB);
57 }
58
59 return Condition;
60}
61
62// Setup the branch instructions for guard blocks.
63//
64// Each guard block terminates in a conditional branch that transfers
65// control to the corresponding outgoing block or the next guard
66// block. The last guard block has two outgoing blocks as successors.
69 BBPredicates &GuardPredicates) {
70 assert(Outgoing.size() > 1);
71 assert(GuardBlocks.size() == Outgoing.size() - 1);
72 // The guard predicates are PHIs merging values from all the incoming blocks,
73 // so the probability of each guard branch cannot be derived locally.
74 int I = 0;
75 for (int E = GuardBlocks.size() - 1; I != E; ++I) {
76 BasicBlock *Out = Outgoing[I];
77 auto *Br = CondBrInst::Create(GuardPredicates[Out], Out, GuardBlocks[I + 1],
78 GuardBlocks[I]);
80 }
81 BasicBlock *Out = Outgoing[I];
82 auto *Br = CondBrInst::Create(GuardPredicates[Out], Out, Outgoing[I + 1],
83 GuardBlocks[I]);
85}
86
87// Assign an index to each outgoing block. At the corresponding guard
88// block, compute the branch condition by comparing this index.
91 ArrayRef<BasicBlock *> GuardBlocks,
92 BBPredicates &GuardPredicates) {
93 LLVMContext &Context = GuardBlocks.front()->getContext();
94 BasicBlock *FirstGuardBlock = GuardBlocks.front();
95 Type *Int32Ty = Type::getInt32Ty(Context);
96
97 auto *Phi = PHINode::Create(Int32Ty, Branches.size(), "merged.bb.idx",
98 FirstGuardBlock);
99
100 for (auto [BB, Succ0, Succ1] : Branches) {
101 Value *Condition = redirectToHub(BB, Succ0, Succ1, FirstGuardBlock);
102 Value *IncomingId = nullptr;
103 if (Succ0 && Succ1 && Succ0 != Succ1) {
104 auto Succ0Iter = find(Outgoing, Succ0);
105 auto Succ1Iter = find(Outgoing, Succ1);
106 Value *Id0 =
107 ConstantInt::get(Int32Ty, std::distance(Outgoing.begin(), Succ0Iter));
108 Value *Id1 =
109 ConstantInt::get(Int32Ty, std::distance(Outgoing.begin(), Succ1Iter));
110 IncomingId = SelectInst::Create(Condition, Id0, Id1, "target.bb.idx",
111 BB->getTerminator()->getIterator());
112 } else {
113 // Get the index of the non-null successor, or when both successors
114 // are the same block, use that block's index directly.
115 auto SuccIter = Succ0 ? find(Outgoing, Succ0) : find(Outgoing, Succ1);
116 IncomingId =
117 ConstantInt::get(Int32Ty, std::distance(Outgoing.begin(), SuccIter));
118 }
119 Phi->addIncoming(IncomingId, BB);
120 }
121
122 for (int I = 0, E = Outgoing.size() - 1; I != E; ++I) {
123 BasicBlock *Out = Outgoing[I];
124 LLVM_DEBUG(dbgs() << "Creating integer guard for " << Out->getName()
125 << "\n");
126 auto *Cmp = ICmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, Phi,
127 ConstantInt::get(Int32Ty, I),
128 Out->getName() + ".predicate", GuardBlocks[I]);
129 GuardPredicates[Out] = Cmp;
130 }
131}
132
133// Determine the branch condition to be used at each guard block from the
134// original boolean values.
137 SmallVectorImpl<BasicBlock *> &GuardBlocks, BBPredicates &GuardPredicates,
138 SmallVectorImpl<WeakVH> &DeletionCandidates) {
139 LLVMContext &Context = GuardBlocks.front()->getContext();
140 auto *BoolTrue = ConstantInt::getTrue(Context);
141 auto *BoolFalse = ConstantInt::getFalse(Context);
142 BasicBlock *FirstGuardBlock = GuardBlocks.front();
143
144 // The predicate for the last outgoing is trivially true, and so we
145 // process only the first N-1 successors.
146 for (int I = 0, E = Outgoing.size() - 1; I != E; ++I) {
147 BasicBlock *Out = Outgoing[I];
148 LLVM_DEBUG(dbgs() << "Creating boolean guard for " << Out->getName()
149 << "\n");
150
151 auto *Phi =
152 PHINode::Create(Type::getInt1Ty(Context), Branches.size(),
153 StringRef("Guard.") + Out->getName(), FirstGuardBlock);
154 GuardPredicates[Out] = Phi;
155 }
156
157 for (auto [BB, Succ0, Succ1] : Branches) {
158 Value *Condition = redirectToHub(BB, Succ0, Succ1, FirstGuardBlock);
159
160 // Optimization: Consider an incoming block A with both successors
161 // Succ0 and Succ1 in the set of outgoing blocks. The predicates
162 // for Succ0 and Succ1 complement each other. If Succ0 is visited
163 // first in the loop below, control will branch to Succ0 using the
164 // corresponding predicate. But if that branch is not taken, then
165 // control must reach Succ1, which means that the incoming value of
166 // the predicate from `BB` is true for Succ1.
167 bool OneSuccessorDone = false;
168 for (int I = 0, E = Outgoing.size() - 1; I != E; ++I) {
169 BasicBlock *Out = Outgoing[I];
170 PHINode *Phi = cast<PHINode>(GuardPredicates[Out]);
171 if (Out != Succ0 && Out != Succ1) {
172 Phi->addIncoming(BoolFalse, BB);
173 } else if (!Succ0 || !Succ1 || Succ0 == Succ1 || OneSuccessorDone) {
174 // Optimization: When only one successor is an outgoing block,
175 // or both successors are the same block, the incoming predicate
176 // from `BB` is always true.
177 Phi->addIncoming(BoolTrue, BB);
178 } else {
179 assert(Succ0 && Succ1);
180 if (Out == Succ0) {
181 Phi->addIncoming(Condition, BB);
182 } else {
183 Value *Inverted = invertCondition(Condition);
184 DeletionCandidates.push_back(Condition);
185 Phi->addIncoming(Inverted, BB);
186 }
187 OneSuccessorDone = true;
188 }
189 }
190 }
191}
192
193// Capture the existing control flow as guard predicates, and redirect
194// control flow from \p Incoming block through the \p GuardBlocks to the
195// \p Outgoing blocks.
196//
197// There is one guard predicate for each outgoing block OutBB. The
198// predicate represents whether the hub should transfer control flow
199// to OutBB. These predicates are NOT ORTHOGONAL. The Hub evaluates
200// them in the same order as the Outgoing set-vector, and control
201// branches to the first outgoing block whose predicate evaluates to true.
202//
203// The last guard block has two outgoing blocks as successors since the
204// condition for the final outgoing block is trivially true. So we create one
205// less block (including the first guard block) than the number of outgoing
206// blocks.
210 SmallVectorImpl<WeakVH> &DeletionCandidates, const StringRef Prefix,
211 std::optional<unsigned> MaxControlFlowBooleans) {
212 BBPredicates GuardPredicates;
213 Function *F = Outgoing.front()->getParent();
214
215 for (int I = 0, E = Outgoing.size() - 1; I != E; ++I)
216 GuardBlocks.push_back(
217 BasicBlock::Create(F->getContext(), Prefix + ".guard", F));
218
219 // When we are using an integer to record which target block to jump to, we
220 // are creating less live values, actually we are using one single integer to
221 // store the index of the target block. When we are using booleans to store
222 // the branching information, we need (N-1) boolean values, where N is the
223 // number of outgoing block.
224 if (!MaxControlFlowBooleans || Outgoing.size() <= *MaxControlFlowBooleans)
225 calcPredicateUsingBooleans(Branches, Outgoing, GuardBlocks, GuardPredicates,
226 DeletionCandidates);
227 else
228 calcPredicateUsingInteger(Branches, Outgoing, GuardBlocks, GuardPredicates);
229
230 setupBranchForGuard(GuardBlocks, Outgoing, GuardPredicates);
231}
232
233// After creating a control flow hub, the operands of PHINodes in an outgoing
234// block Out no longer match the predecessors of that block. The edges to Out
235// that are redirected through the hub are now replaced by just one edge from
236// the hub; other edges to Out, even from incoming blocks of the hub, are kept.
237// To match this new control flow, the values for the redirected edges are
238// moved from each PHINode to a new PHINode in the first guard block of the hub.
239//
240// If Out is itself an incoming block of the hub (a self-loop that is
241// redirected through the hub), the new PHINode receives the value that the
242// original PHINode received along the self-loop. If that value is the original
243// PHINode itself, it becomes the new PHINode when the original is replaced.
244static void reconnectPhis(BasicBlock *Out, BasicBlock *GuardBlock,
246 BasicBlock *FirstGuardBlock) {
247 auto I = Out->begin();
248 while (I != Out->end() && isa<PHINode>(I)) {
249 auto *Phi = cast<PHINode>(I);
250 auto *NewPhi =
251 PHINode::Create(Phi->getType(), Incoming.size(),
252 Phi->getName() + ".moved", FirstGuardBlock->begin());
253 bool AllUndef = true;
254 bool AllPoison = true;
255 for (auto [BB, Succ0, Succ1] : Incoming) {
256 Value *V = PoisonValue::get(Phi->getType());
257 // Only edges from BB to Out that go through the hub move their value.
258 // BB may have another edge to Out that is not redirected.
259 if ((Succ0 == Out || Succ1 == Out) && Phi->getBasicBlockIndex(BB) != -1) {
260 V = Phi->removeIncomingValue(BB, false);
261 // When both successors are the same (Succ0 == Succ1), there are two
262 // edges from BB to Out, so we need to remove the second PHI entry too.
263 if (Succ0 && Succ1 && Succ0 == Succ1 &&
264 Phi->getBasicBlockIndex(BB) != -1)
265 Phi->removeIncomingValue(BB, false);
266 AllUndef &= isa<UndefValue>(V);
267 AllPoison &= isa<PoisonValue>(V);
268 }
269
270 NewPhi->addIncoming(V, BB);
271 }
272 assert(NewPhi->getNumIncomingValues() == Incoming.size());
273 Value *NewV = NewPhi;
274 // If all moved values are undef or poison, use that instead of a PHI. Only
275 // use poison if they are all poison: replacing undef with poison would make
276 // the program less defined.
277 if (AllUndef) {
278 NewPhi->eraseFromParent();
279 NewV = AllPoison ? PoisonValue::get(Phi->getType())
280 : UndefValue::get(Phi->getType());
281 }
282 if (Phi->getNumOperands() == 0) {
283 Phi->replaceAllUsesWith(NewV);
284 I = Phi->eraseFromParent();
285 continue;
286 }
287 Phi->addIncoming(NewV, GuardBlock);
288 ++I;
289 }
290}
291
292std::pair<BasicBlock *, bool> ControlFlowHub::finalize(
294 const StringRef Prefix, std::optional<unsigned> MaxControlFlowBooleans) {
295#ifndef NDEBUG
297#endif
299
300 for (auto [BB, Succ0, Succ1] : Branches) {
301#ifndef NDEBUG
302 assert(
303 (Incoming.insert(BB).second || isa<CallBrInst>(BB->getTerminator())) &&
304 "Duplicate entry for incoming block.");
305#endif
306 if (Succ0)
307 Outgoing.insert(Succ0);
308 if (Succ1)
309 Outgoing.insert(Succ1);
310 }
311
312 assert(Outgoing.size() && "No outgoing edges");
313
314 if (Outgoing.size() < 2)
315 return {Outgoing.front(), false};
316
318 if (DTU) {
319 for (auto [BB, Succ0, Succ1] : Branches) {
320 if (Succ0)
321 Updates.push_back({DominatorTree::Delete, BB, Succ0});
322 // Only add Succ1 if it's different from Succ0 to avoid duplicate updates
323 if (Succ1 && Succ1 != Succ0)
324 Updates.push_back({DominatorTree::Delete, BB, Succ1});
325 }
326 }
327
328 SmallVector<WeakVH, 8> DeletionCandidates;
329 convertToGuardPredicates(Branches, Outgoing.getArrayRef(), GuardBlocks,
330 DeletionCandidates, Prefix, MaxControlFlowBooleans);
331 BasicBlock *FirstGuardBlock = GuardBlocks.front();
332
333 // Update the PHINodes in each outgoing block to match the new control flow.
334 for (int I = 0, E = GuardBlocks.size(); I != E; ++I)
335 reconnectPhis(Outgoing[I], GuardBlocks[I], Branches, FirstGuardBlock);
336 // Process the Nth (last) outgoing block with the (N-1)th (last) guard block.
337 reconnectPhis(Outgoing.back(), GuardBlocks.back(), Branches, FirstGuardBlock);
338
339 if (DTU) {
340 int NumGuards = GuardBlocks.size();
341
342 for (auto [BB, Succ0, Succ1] : Branches)
343 Updates.push_back({DominatorTree::Insert, BB, FirstGuardBlock});
344
345 for (int I = 0; I != NumGuards - 1; ++I) {
346 Updates.push_back({DominatorTree::Insert, GuardBlocks[I], Outgoing[I]});
347 Updates.push_back(
348 {DominatorTree::Insert, GuardBlocks[I], GuardBlocks[I + 1]});
349 }
350 // The second successor of the last guard block is an outgoing block instead
351 // of having a "next" guard block.
352 Updates.push_back({DominatorTree::Insert, GuardBlocks[NumGuards - 1],
353 Outgoing[NumGuards - 1]});
354 Updates.push_back({DominatorTree::Insert, GuardBlocks[NumGuards - 1],
355 Outgoing[NumGuards]});
356 DTU->applyUpdates(Updates);
357 }
358
359 for (auto &I : DeletionCandidates) {
360 if (auto *Inst = dyn_cast_if_present<Instruction>(I)) {
361 if (Inst->use_empty())
362 Inst->eraseFromParent();
363 }
364 }
365
366 return {FirstGuardBlock, true};
367}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static void calcPredicateUsingBooleans(ArrayRef< EdgeDescriptor > Branches, ArrayRef< BasicBlock * > Outgoing, SmallVectorImpl< BasicBlock * > &GuardBlocks, BBPredicates &GuardPredicates, SmallVectorImpl< WeakVH > &DeletionCandidates)
static void setupBranchForGuard(ArrayRef< BasicBlock * > GuardBlocks, ArrayRef< BasicBlock * > Outgoing, BBPredicates &GuardPredicates)
static void reconnectPhis(BasicBlock *Out, BasicBlock *GuardBlock, ArrayRef< EdgeDescriptor > Incoming, BasicBlock *FirstGuardBlock)
static void calcPredicateUsingInteger(ArrayRef< EdgeDescriptor > Branches, ArrayRef< BasicBlock * > Outgoing, ArrayRef< BasicBlock * > GuardBlocks, BBPredicates &GuardPredicates)
DenseMap< BasicBlock *, Instruction * > BBPredicates
static Value * redirectToHub(BasicBlock *BB, BasicBlock *Succ0, BasicBlock *Succ1, BasicBlock *FirstGuardBlock)
static void convertToGuardPredicates(ArrayRef< EdgeDescriptor > Branches, ArrayRef< BasicBlock * > Outgoing, SmallVectorImpl< BasicBlock * > &GuardBlocks, SmallVectorImpl< WeakVH > &DeletionCandidates, const StringRef Prefix, std::optional< unsigned > MaxControlFlowBooleans)
ControlFlowHub::BranchDescriptor EdgeDescriptor
#define DEBUG_TYPE
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file contains the declarations for profiling metadata utility functions.
This file implements a set that has insertion order iteration characteristics.
#define LLVM_DEBUG(...)
Definition Debug.h:119
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
const T & front() const
Get the first element.
Definition ArrayRef.h:144
size_t size() const
Get the array size.
Definition ArrayRef.h:141
iterator begin() const
Definition ArrayRef.h:129
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator begin()
Instruction iterator methods.
Definition BasicBlock.h:440
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
static LLVM_ABI CmpInst * Create(OtherOps Op, Predicate Pred, Value *S1, Value *S2, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Construct a compare instruction, given the opcode, the predicate and the two operands.
static CondBrInst * Create(Value *Cond, BasicBlock *IfTrue, BasicBlock *IfFalse, InsertPosition InsertBefore=nullptr)
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
void applyUpdates(ArrayRef< UpdateT > Updates)
Submit updates to all available trees.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
A vector that has set insertion semantics.
Definition SetVector.h:57
ArrayRef< value_type > getArrayRef() const
Definition SetVector.h:91
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
const value_type & front() const
Return the first element of the SetVector.
Definition SetVector.h:138
const value_type & back() const
Return the last element of the SetVector.
Definition SetVector.h:144
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:299
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:296
static UncondBrInst * Create(BasicBlock *Target, InsertPosition InsertBefore=nullptr)
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
LLVM Value Representation.
Definition Value.h:75
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1781
LLVM_ABI void setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &I, StringRef PassName, const Function *F=nullptr)
Like setExplicitlyUnknownBranchWeights(...), but only sets unknown branch weights in the new instruct...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
Definition Casting.h:732
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI Value * invertCondition(Value *Condition)
Invert the given true/false value, possibly reusing an existing copy.
Definition Local.cpp:4007
LLVM_ABI std::pair< BasicBlock *, bool > finalize(DomTreeUpdater *DTU, SmallVectorImpl< BasicBlock * > &GuardBlocks, const StringRef Prefix, std::optional< unsigned > MaxControlFlowBooleans=std::nullopt)
Return the unified loop exit block and a flag indicating if the CFG was changed at all.
SmallVector< BranchDescriptor > Branches