LLVM 22.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"
16#include "llvm/IR/Constants.h"
18#include "llvm/IR/ValueHandle.h"
20
21#define DEBUG_TYPE "control-flow-hub"
22
23using namespace llvm;
24
27
28// Redirects the terminator of the incoming block to the first guard block in
29// the hub. Returns the branch condition from `BB` if it exits.
30// - If only one of Succ0 or Succ1 is not null, the corresponding branch
31// successor is redirected to the FirstGuardBlock.
32// - Else both are not null, and branch is replaced with an unconditional
33// branch to the FirstGuardBlock.
35 BasicBlock *Succ1, BasicBlock *FirstGuardBlock) {
36 assert(isa<BranchInst>(BB->getTerminator()) &&
37 "Only support branch terminator.");
38 auto *Branch = cast<BranchInst>(BB->getTerminator());
39 auto *Condition = Branch->isConditional() ? Branch->getCondition() : nullptr;
40
41 assert(Succ0 || Succ1);
42
43 if (Branch->isUnconditional()) {
44 assert(Succ0 == Branch->getSuccessor(0));
45 assert(!Succ1);
46 Branch->setSuccessor(0, FirstGuardBlock);
47 } else {
48 assert(!Succ1 || Succ1 == Branch->getSuccessor(1));
49 if (Succ0 && !Succ1) {
50 Branch->setSuccessor(0, FirstGuardBlock);
51 } else if (Succ1 && !Succ0) {
52 Branch->setSuccessor(1, FirstGuardBlock);
53 } else {
54 Branch->eraseFromParent();
55 BranchInst::Create(FirstGuardBlock, BB);
56 }
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 int I = 0;
73 for (int E = GuardBlocks.size() - 1; I != E; ++I) {
74 BasicBlock *Out = Outgoing[I];
75 BranchInst::Create(Out, GuardBlocks[I + 1], GuardPredicates[Out],
76 GuardBlocks[I]);
77 }
78 BasicBlock *Out = Outgoing[I];
79 BranchInst::Create(Out, Outgoing[I + 1], GuardPredicates[Out],
80 GuardBlocks[I]);
81}
82
83// Assign an index to each outgoing block. At the corresponding guard
84// block, compute the branch condition by comparing this index.
87 ArrayRef<BasicBlock *> GuardBlocks,
88 BBPredicates &GuardPredicates) {
89 LLVMContext &Context = GuardBlocks.front()->getContext();
90 BasicBlock *FirstGuardBlock = GuardBlocks.front();
91 Type *Int32Ty = Type::getInt32Ty(Context);
92
93 auto *Phi = PHINode::Create(Int32Ty, Branches.size(), "merged.bb.idx",
94 FirstGuardBlock);
95
96 for (auto [BB, Succ0, Succ1] : Branches) {
97 Value *Condition = redirectToHub(BB, Succ0, Succ1, FirstGuardBlock);
98 Value *IncomingId = nullptr;
99 if (Succ0 && Succ1) {
100 auto Succ0Iter = find(Outgoing, Succ0);
101 auto Succ1Iter = find(Outgoing, Succ1);
102 Value *Id0 =
103 ConstantInt::get(Int32Ty, std::distance(Outgoing.begin(), Succ0Iter));
104 Value *Id1 =
105 ConstantInt::get(Int32Ty, std::distance(Outgoing.begin(), Succ1Iter));
106 IncomingId = SelectInst::Create(Condition, Id0, Id1, "target.bb.idx",
107 BB->getTerminator()->getIterator());
108 } else {
109 // Get the index of the non-null successor.
110 auto SuccIter = Succ0 ? find(Outgoing, Succ0) : find(Outgoing, Succ1);
111 IncomingId =
112 ConstantInt::get(Int32Ty, std::distance(Outgoing.begin(), SuccIter));
113 }
114 Phi->addIncoming(IncomingId, BB);
115 }
116
117 for (int I = 0, E = Outgoing.size() - 1; I != E; ++I) {
118 BasicBlock *Out = Outgoing[I];
119 LLVM_DEBUG(dbgs() << "Creating integer guard for " << Out->getName()
120 << "\n");
121 auto *Cmp = ICmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, Phi,
122 ConstantInt::get(Int32Ty, I),
123 Out->getName() + ".predicate", GuardBlocks[I]);
124 GuardPredicates[Out] = Cmp;
125 }
126}
127
128// Determine the branch condition to be used at each guard block from the
129// original boolean values.
132 SmallVectorImpl<BasicBlock *> &GuardBlocks, BBPredicates &GuardPredicates,
133 SmallVectorImpl<WeakVH> &DeletionCandidates) {
134 LLVMContext &Context = GuardBlocks.front()->getContext();
135 auto *BoolTrue = ConstantInt::getTrue(Context);
136 auto *BoolFalse = ConstantInt::getFalse(Context);
137 BasicBlock *FirstGuardBlock = GuardBlocks.front();
138
139 // The predicate for the last outgoing is trivially true, and so we
140 // process only the first N-1 successors.
141 for (int I = 0, E = Outgoing.size() - 1; I != E; ++I) {
142 BasicBlock *Out = Outgoing[I];
143 LLVM_DEBUG(dbgs() << "Creating boolean guard for " << Out->getName()
144 << "\n");
145
146 auto *Phi =
148 StringRef("Guard.") + Out->getName(), FirstGuardBlock);
149 GuardPredicates[Out] = Phi;
150 }
151
152 for (auto [BB, Succ0, Succ1] : Branches) {
153 Value *Condition = redirectToHub(BB, Succ0, Succ1, FirstGuardBlock);
154
155 // Optimization: Consider an incoming block A with both successors
156 // Succ0 and Succ1 in the set of outgoing blocks. The predicates
157 // for Succ0 and Succ1 complement each other. If Succ0 is visited
158 // first in the loop below, control will branch to Succ0 using the
159 // corresponding predicate. But if that branch is not taken, then
160 // control must reach Succ1, which means that the incoming value of
161 // the predicate from `BB` is true for Succ1.
162 bool OneSuccessorDone = false;
163 for (int I = 0, E = Outgoing.size() - 1; I != E; ++I) {
164 BasicBlock *Out = Outgoing[I];
165 PHINode *Phi = cast<PHINode>(GuardPredicates[Out]);
166 if (Out != Succ0 && Out != Succ1) {
167 Phi->addIncoming(BoolFalse, BB);
168 } else if (!Succ0 || !Succ1 || OneSuccessorDone) {
169 // Optimization: When only one successor is an outgoing block,
170 // the incoming predicate from `BB` is always true.
171 Phi->addIncoming(BoolTrue, BB);
172 } else {
173 assert(Succ0 && Succ1);
174 if (Out == Succ0) {
175 Phi->addIncoming(Condition, BB);
176 } else {
177 Value *Inverted = invertCondition(Condition);
178 DeletionCandidates.push_back(Condition);
179 Phi->addIncoming(Inverted, BB);
180 }
181 OneSuccessorDone = true;
182 }
183 }
184 }
185}
186
187// Capture the existing control flow as guard predicates, and redirect
188// control flow from \p Incoming block through the \p GuardBlocks to the
189// \p Outgoing blocks.
190//
191// There is one guard predicate for each outgoing block OutBB. The
192// predicate represents whether the hub should transfer control flow
193// to OutBB. These predicates are NOT ORTHOGONAL. The Hub evaluates
194// them in the same order as the Outgoing set-vector, and control
195// branches to the first outgoing block whose predicate evaluates to true.
196//
197// The last guard block has two outgoing blocks as successors since the
198// condition for the final outgoing block is trivially true. So we create one
199// less block (including the first guard block) than the number of outgoing
200// blocks.
204 SmallVectorImpl<WeakVH> &DeletionCandidates, const StringRef Prefix,
205 std::optional<unsigned> MaxControlFlowBooleans) {
206 BBPredicates GuardPredicates;
207 Function *F = Outgoing.front()->getParent();
208
209 for (int I = 0, E = Outgoing.size() - 1; I != E; ++I)
210 GuardBlocks.push_back(
211 BasicBlock::Create(F->getContext(), Prefix + ".guard", F));
212
213 // When we are using an integer to record which target block to jump to, we
214 // are creating less live values, actually we are using one single integer to
215 // store the index of the target block. When we are using booleans to store
216 // the branching information, we need (N-1) boolean values, where N is the
217 // number of outgoing block.
218 if (!MaxControlFlowBooleans || Outgoing.size() <= *MaxControlFlowBooleans)
219 calcPredicateUsingBooleans(Branches, Outgoing, GuardBlocks, GuardPredicates,
220 DeletionCandidates);
221 else
222 calcPredicateUsingInteger(Branches, Outgoing, GuardBlocks, GuardPredicates);
223
224 setupBranchForGuard(GuardBlocks, Outgoing, GuardPredicates);
225}
226
227// After creating a control flow hub, the operands of PHINodes in an outgoing
228// block Out no longer match the predecessors of that block. Predecessors of Out
229// that are incoming blocks to the hub are now replaced by just one edge from
230// the hub. To match this new control flow, the corresponding values from each
231// PHINode must now be moved a new PHINode in the first guard block of the hub.
232//
233// This operation cannot be performed with SSAUpdater, because it involves one
234// new use: If the block Out is in the list of Incoming blocks, then the newly
235// created PHI in the Hub will use itself along that edge from Out to Hub.
236static void reconnectPhis(BasicBlock *Out, BasicBlock *GuardBlock,
238 BasicBlock *FirstGuardBlock) {
239 auto I = Out->begin();
240 while (I != Out->end() && isa<PHINode>(I)) {
241 auto *Phi = cast<PHINode>(I);
242 auto *NewPhi =
243 PHINode::Create(Phi->getType(), Incoming.size(),
244 Phi->getName() + ".moved", FirstGuardBlock->begin());
245 bool AllUndef = true;
246 for (auto [BB, Succ0, Succ1] : Incoming) {
247 Value *V = PoisonValue::get(Phi->getType());
248 if (Phi->getBasicBlockIndex(BB) != -1) {
249 V = Phi->removeIncomingValue(BB, false);
250 if (BB == Out) {
251 V = NewPhi;
252 }
253 AllUndef &= isa<UndefValue>(V);
254 }
255
256 NewPhi->addIncoming(V, BB);
257 }
258 assert(NewPhi->getNumIncomingValues() == Incoming.size());
259 Value *NewV = NewPhi;
260 if (AllUndef) {
261 NewPhi->eraseFromParent();
262 NewV = PoisonValue::get(Phi->getType());
263 }
264 if (Phi->getNumOperands() == 0) {
265 Phi->replaceAllUsesWith(NewV);
266 I = Phi->eraseFromParent();
267 continue;
268 }
269 Phi->addIncoming(NewV, GuardBlock);
270 ++I;
271 }
272}
273
274std::pair<BasicBlock *, bool> ControlFlowHub::finalize(
276 const StringRef Prefix, std::optional<unsigned> MaxControlFlowBooleans) {
277#ifndef NDEBUG
279#endif
281
282 for (auto [BB, Succ0, Succ1] : Branches) {
283#ifndef NDEBUG
284 assert(Incoming.insert(BB).second && "Duplicate entry for incoming block.");
285#endif
286 if (Succ0)
287 Outgoing.insert(Succ0);
288 if (Succ1)
289 Outgoing.insert(Succ1);
290 }
291
292 if (Outgoing.size() < 2)
293 return {Outgoing.front(), false};
294
296 if (DTU) {
297 for (auto [BB, Succ0, Succ1] : Branches) {
298 if (Succ0)
299 Updates.push_back({DominatorTree::Delete, BB, Succ0});
300 if (Succ1)
301 Updates.push_back({DominatorTree::Delete, BB, Succ1});
302 }
303 }
304
305 SmallVector<WeakVH, 8> DeletionCandidates;
306 convertToGuardPredicates(Branches, Outgoing.getArrayRef(), GuardBlocks,
307 DeletionCandidates, Prefix, MaxControlFlowBooleans);
308 BasicBlock *FirstGuardBlock = GuardBlocks.front();
309
310 // Update the PHINodes in each outgoing block to match the new control flow.
311 for (int I = 0, E = GuardBlocks.size(); I != E; ++I)
312 reconnectPhis(Outgoing[I], GuardBlocks[I], Branches, FirstGuardBlock);
313 // Process the Nth (last) outgoing block with the (N-1)th (last) guard block.
314 reconnectPhis(Outgoing.back(), GuardBlocks.back(), Branches, FirstGuardBlock);
315
316 if (DTU) {
317 int NumGuards = GuardBlocks.size();
318
319 for (auto [BB, Succ0, Succ1] : Branches)
320 Updates.push_back({DominatorTree::Insert, BB, FirstGuardBlock});
321
322 for (int I = 0; I != NumGuards - 1; ++I) {
323 Updates.push_back({DominatorTree::Insert, GuardBlocks[I], Outgoing[I]});
324 Updates.push_back(
325 {DominatorTree::Insert, GuardBlocks[I], GuardBlocks[I + 1]});
326 }
327 // The second successor of the last guard block is an outgoing block instead
328 // of having a "next" guard block.
329 Updates.push_back({DominatorTree::Insert, GuardBlocks[NumGuards - 1],
330 Outgoing[NumGuards - 1]});
331 Updates.push_back({DominatorTree::Insert, GuardBlocks[NumGuards - 1],
332 Outgoing[NumGuards]});
333 DTU->applyUpdates(Updates);
334 }
335
336 for (auto I : DeletionCandidates) {
337 if (I->use_empty())
338 if (auto *Inst = dyn_cast_or_null<Instruction>(I))
339 Inst->eraseFromParent();
340 }
341
342 return {FirstGuardBlock, true};
343}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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)
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)
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file implements a set that has insertion order iteration characteristics.
#define LLVM_DEBUG(...)
Definition: Debug.h:119
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
const T & front() const
front - Get the first element.
Definition: ArrayRef.h:150
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:147
iterator begin() const
Definition: ArrayRef.h:135
LLVM Basic Block Representation.
Definition: BasicBlock.h:62
iterator end()
Definition: BasicBlock.h:472
iterator begin()
Instruction iterator methods.
Definition: BasicBlock.h:459
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 if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.h:233
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
Definition: Constants.cpp:868
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
Definition: Constants.cpp:875
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:68
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.
Definition: Constants.cpp:1885
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, Instruction *MDFrom=nullptr)
A vector that has set insertion semantics.
Definition: SetVector.h:59
ArrayRef< value_type > getArrayRef() const
Definition: SetVector.h:90
size_type size() const
Determine the number of elements in the SetVector.
Definition: SetVector.h:104
const value_type & front() const
Return the first element of the SetVector.
Definition: SetVector.h:149
const value_type & back() const
Return the last element of the SetVector.
Definition: SetVector.h:155
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:168
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:541
size_t size() const
Definition: SmallVector.h:79
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
LLVM Value Representation.
Definition: Value.h:75
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:322
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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:1770
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
LLVM_ABI Value * invertCondition(Value *Condition)
Invert the given true/false value, possibly reusing an existing copy.
Definition: Local.cpp:3923
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
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...