LLVM 23.0.0git
SSAUpdaterImpl.h
Go to the documentation of this file.
1//===- SSAUpdaterImpl.h - SSA Updater Implementation ------------*- 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 file provides a template that implements the core algorithm for the
10// SSAUpdater and MachineSSAUpdater.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
15#define LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
16
17#include "llvm/ADT/DenseMap.h"
18#include "llvm/ADT/ScopeExit.h"
21#include "llvm/Support/Debug.h"
23
24#define DEBUG_TYPE "ssaupdater"
25
26namespace llvm {
27
29
30template<typename T> class SSAUpdaterTraits;
31
32template<typename UpdaterT>
34private:
35 UpdaterT *Updater;
36
37 using Traits = SSAUpdaterTraits<UpdaterT>;
38 using BlkT = typename Traits::BlkT;
39 using ValT = typename Traits::ValT;
40 using PhiT = typename Traits::PhiT;
41
42 /// BBInfo - Per-basic block information used internally by SSAUpdaterImpl.
43 /// The predecessors of each block are cached here since pred_iterator is
44 /// slow and we need to iterate over the blocks at least a few times.
45 class BBInfo {
46 public:
47 // Back-pointer to the corresponding block.
48 BlkT *BB;
49
50 // Value to use in this block.
51 ValT AvailableVal;
52
53 // Block that defines the available value.
54 BBInfo *DefBB;
55
56 // Postorder number.
57 int BlkNum = 0;
58
59 // Immediate dominator.
60 BBInfo *IDom = nullptr;
61
62 // Number of predecessor blocks.
63 unsigned NumPreds = 0;
64
65 // Array[NumPreds] of predecessor blocks.
66 BBInfo **Preds = nullptr;
67
68 // Marker for existing PHIs that match.
69 PhiT *PHITag = nullptr;
70
71 BBInfo(BlkT *ThisBB, ValT V)
72 : BB(ThisBB), AvailableVal(V), DefBB(V ? this : nullptr) {}
73 };
74
75 using AvailableValsTy = DenseMap<BlkT *, ValT>;
76
77 AvailableValsTy *AvailableVals;
78
79 SmallVectorImpl<PhiT *> *InsertedPHIs;
80
81 using BlockListTy = SmallVectorImpl<BBInfo *>;
82 using BBMapTy = DenseMap<BlkT *, BBInfo *>;
83
84 BBMapTy BBMap;
85 BumpPtrAllocator Allocator;
86
87public:
88 explicit SSAUpdaterImpl(UpdaterT *U, AvailableValsTy *A,
90 Updater(U), AvailableVals(A), InsertedPHIs(Ins) {}
91
92 /// GetValue - Check to see if AvailableVals has an entry for the specified
93 /// BB and if so, return it. If not, construct SSA form by first
94 /// calculating the required placement of PHIs and then inserting new PHIs
95 /// where needed.
96 ValT GetValue(BlkT *BB) {
98 BBInfo *PseudoEntry = BuildBlockList(BB, &BlockList);
99
100 // Special case: bail out if BB is unreachable.
101 if (BlockList.size() == 0) {
102 ValT V = Traits::GetPoisonVal(BB, Updater);
103 (*AvailableVals)[BB] = V;
104 return V;
105 }
106
107 FindDominators(&BlockList, PseudoEntry);
108 FindPHIPlacement(&BlockList);
109 FindAvailableVals(&BlockList);
110
111 return BBMap[BB]->DefBB->AvailableVal;
112 }
113
114 /// BuildBlockList - Starting from the specified basic block, traverse back
115 /// through its predecessors until reaching blocks with known values.
116 /// Create BBInfo structures for the blocks and append them to the block
117 /// list.
118 BBInfo *BuildBlockList(BlkT *BB, BlockListTy *BlockList) {
121
122 BBInfo *Info = new (Allocator) BBInfo(BB, 0);
123 BBMap[BB] = Info;
124 WorkList.push_back(Info);
125
126 // Search backward from BB, creating BBInfos along the way and stopping
127 // when reaching blocks that define the value. Record those defining
128 // blocks on the RootList.
130 while (!WorkList.empty()) {
131 Info = WorkList.pop_back_val();
132 Preds.clear();
133 Traits::FindPredecessorBlocks(Info->BB, &Preds);
134 Info->NumPreds = Preds.size();
135 if (Info->NumPreds == 0)
136 Info->Preds = nullptr;
137 else
138 Info->Preds = static_cast<BBInfo **>(Allocator.Allocate(
139 Info->NumPreds * sizeof(BBInfo *), alignof(BBInfo *)));
140
141 for (unsigned p = 0; p != Info->NumPreds; ++p) {
142 BlkT *Pred = Preds[p];
143 // Check if BBMap already has a BBInfo for the predecessor block.
144 BBInfo *&BBMapBucket = BBMap[Pred];
145 if (BBMapBucket) {
146 Info->Preds[p] = BBMapBucket;
147 continue;
148 }
149
150 // Create a new BBInfo for the predecessor.
151 ValT PredVal = AvailableVals->lookup(Pred);
152 BBInfo *PredInfo = new (Allocator) BBInfo(Pred, PredVal);
153 BBMapBucket = PredInfo;
154 Info->Preds[p] = PredInfo;
155
156 if (PredInfo->AvailableVal) {
157 RootList.push_back(PredInfo);
158 continue;
159 }
160 WorkList.push_back(PredInfo);
161 }
162 }
163
164 // Now that we know what blocks are backwards-reachable from the starting
165 // block, do a forward depth-first traversal to assign postorder numbers
166 // to those blocks.
167 BBInfo *PseudoEntry = new (Allocator) BBInfo(nullptr, 0);
168 unsigned BlkNum = 1;
169
170 // Initialize the worklist with the roots from the backward traversal.
171 while (!RootList.empty()) {
172 Info = RootList.pop_back_val();
173 Info->IDom = PseudoEntry;
174 Info->BlkNum = -1;
175 WorkList.push_back(Info);
176 }
177
178 while (!WorkList.empty()) {
179 Info = WorkList.back();
180
181 if (Info->BlkNum == -2) {
182 // All the successors have been handled; assign the postorder number.
183 Info->BlkNum = BlkNum++;
184 // If not a root, put it on the BlockList.
185 if (!Info->AvailableVal)
186 BlockList->push_back(Info);
187 WorkList.pop_back();
188 continue;
189 }
190
191 // Leave this entry on the worklist, but set its BlkNum to mark that its
192 // successors have been put on the worklist. When it returns to the top
193 // the list, after handling its successors, it will be assigned a
194 // number.
195 Info->BlkNum = -2;
196
197 // Add unvisited successors to the work list.
198 for (typename Traits::BlkSucc_iterator SI =
199 Traits::BlkSucc_begin(Info->BB),
200 E = Traits::BlkSucc_end(Info->BB); SI != E; ++SI) {
201 BBInfo *SuccInfo = BBMap[*SI];
202 if (!SuccInfo || SuccInfo->BlkNum)
203 continue;
204 SuccInfo->BlkNum = -1;
205 WorkList.push_back(SuccInfo);
206 }
207 }
208 PseudoEntry->BlkNum = BlkNum;
209 return PseudoEntry;
210 }
211
212 /// IntersectDominators - This is the dataflow lattice "meet" operation for
213 /// finding dominators. Given two basic blocks, it walks up the dominator
214 /// tree until it finds a common dominator of both. It uses the postorder
215 /// number of the blocks to determine how to do that.
216 BBInfo *IntersectDominators(BBInfo *Blk1, BBInfo *Blk2) {
217 while (Blk1 != Blk2) {
218 while (Blk1->BlkNum < Blk2->BlkNum) {
219 Blk1 = Blk1->IDom;
220 if (!Blk1)
221 return Blk2;
222 }
223 while (Blk2->BlkNum < Blk1->BlkNum) {
224 Blk2 = Blk2->IDom;
225 if (!Blk2)
226 return Blk1;
227 }
228 }
229 return Blk1;
230 }
231
232 /// FindDominators - Calculate the dominator tree for the subset of the CFG
233 /// corresponding to the basic blocks on the BlockList. This uses the
234 /// algorithm from: "A Simple, Fast Dominance Algorithm" by Cooper, Harvey
235 /// and Kennedy, published in Software--Practice and Experience, 2001,
236 /// 4:1-10. Because the CFG subset does not include any edges leading into
237 /// blocks that define the value, the results are not the usual dominator
238 /// tree. The CFG subset has a single pseudo-entry node with edges to a set
239 /// of root nodes for blocks that define the value. The dominators for this
240 /// subset CFG are not the standard dominators but they are adequate for
241 /// placing PHIs within the subset CFG.
242 void FindDominators(BlockListTy *BlockList, BBInfo *PseudoEntry) {
243 bool Changed;
244 do {
245 Changed = false;
246 // Iterate over the list in reverse order, i.e., forward on CFG edges.
247 for (typename BlockListTy::reverse_iterator I = BlockList->rbegin(),
248 E = BlockList->rend(); I != E; ++I) {
249 BBInfo *Info = *I;
250 BBInfo *NewIDom = nullptr;
251
252 // Iterate through the block's predecessors.
253 for (unsigned p = 0; p != Info->NumPreds; ++p) {
254 BBInfo *Pred = Info->Preds[p];
255
256 // Treat an unreachable predecessor as a definition with 'poison'.
257 if (Pred->BlkNum == 0) {
258 Pred->AvailableVal = Traits::GetPoisonVal(Pred->BB, Updater);
259 (*AvailableVals)[Pred->BB] = Pred->AvailableVal;
260 Pred->DefBB = Pred;
261 Pred->BlkNum = PseudoEntry->BlkNum;
262 PseudoEntry->BlkNum++;
263 }
264
265 if (!NewIDom)
266 NewIDom = Pred;
267 else
268 NewIDom = IntersectDominators(NewIDom, Pred);
269 }
270
271 // Check if the IDom value has changed.
272 if (NewIDom && NewIDom != Info->IDom) {
273 Info->IDom = NewIDom;
274 Changed = true;
275 }
276 }
277 } while (Changed);
278 }
279
280 /// IsDefInDomFrontier - Search up the dominator tree from Pred to IDom for
281 /// any blocks containing definitions of the value. If one is found, then
282 /// the successor of Pred is in the dominance frontier for the definition,
283 /// and this function returns true.
284 bool IsDefInDomFrontier(const BBInfo *Pred, const BBInfo *IDom) {
285 for (; Pred != IDom; Pred = Pred->IDom) {
286 if (Pred->DefBB == Pred)
287 return true;
288 }
289 return false;
290 }
291
292 /// FindPHIPlacement - PHIs are needed in the iterated dominance frontiers
293 /// of the known definitions. Iteratively add PHIs in the dom frontiers
294 /// until nothing changes. Along the way, keep track of the nearest
295 /// dominating definitions for non-PHI blocks.
296 void FindPHIPlacement(BlockListTy *BlockList) {
297 bool Changed;
298 do {
299 Changed = false;
300 // Iterate over the list in reverse order, i.e., forward on CFG edges.
301 for (typename BlockListTy::reverse_iterator I = BlockList->rbegin(),
302 E = BlockList->rend(); I != E; ++I) {
303 BBInfo *Info = *I;
304
305 // If this block already needs a PHI, there is nothing to do here.
306 if (Info->DefBB == Info)
307 continue;
308
309 // Default to use the same def as the immediate dominator.
310 BBInfo *NewDefBB = Info->IDom->DefBB;
311 for (unsigned p = 0; p != Info->NumPreds; ++p) {
312 if (IsDefInDomFrontier(Info->Preds[p], Info->IDom)) {
313 // Need a PHI here.
314 NewDefBB = Info;
315 break;
316 }
317 }
318
319 // Check if anything changed.
320 if (NewDefBB != Info->DefBB) {
321 Info->DefBB = NewDefBB;
322 Changed = true;
323 }
324 }
325 } while (Changed);
326 }
327
328 /// Check all predecessors and if all of them have the same AvailableVal use
329 /// it as value for block represented by Info. Return true if singluar value
330 /// is found.
331 bool FindSingularVal(BBInfo *Info) {
332 if (!Info->NumPreds)
333 return false;
334 ValT Singular = Info->Preds[0]->DefBB->AvailableVal;
335 if (!Singular)
336 return false;
337 for (unsigned Idx = 1; Idx < Info->NumPreds; ++Idx) {
338 ValT PredVal = Info->Preds[Idx]->DefBB->AvailableVal;
339 if (!PredVal || Singular != PredVal)
340 return false;
341 }
342 // Record Singular value.
343 (*AvailableVals)[Info->BB] = Singular;
344 assert(BBMap[Info->BB] == Info && "Info missed in BBMap?");
345 Info->AvailableVal = Singular;
346 Info->DefBB = Info->Preds[0]->DefBB;
347 return true;
348 }
349
350 /// FindAvailableVal - If this block requires a PHI, first check if an
351 /// existing PHI matches the PHI placement and reaching definitions computed
352 /// earlier, and if not, create a new PHI. Visit all the block's
353 /// predecessors to calculate the available value for each one and fill in
354 /// the incoming values for a new PHI.
355 void FindAvailableVals(BlockListTy *BlockList) {
356 // Go through the worklist in forward order (i.e., backward through the CFG)
357 // and check if existing PHIs can be used. If not, create empty PHIs where
358 // they are needed.
359 for (typename BlockListTy::iterator I = BlockList->begin(),
360 E = BlockList->end(); I != E; ++I) {
361 BBInfo *Info = *I;
362 // Check if there needs to be a PHI in BB.
363 if (Info->DefBB != Info)
364 continue;
365
366 // Look for singular value.
367 if (FindSingularVal(Info))
368 continue;
369
370 // Look for an existing PHI.
371 FindExistingPHI(Info->BB);
372 if (Info->AvailableVal)
373 continue;
374
375 ValT PHI = Traits::CreateEmptyPHI(Info->BB, Info->NumPreds, Updater);
376 Info->AvailableVal = PHI;
377 (*AvailableVals)[Info->BB] = PHI;
378 }
379
380 // Now go back through the worklist in reverse order to fill in the
381 // arguments for any new PHIs added in the forward traversal.
382 for (typename BlockListTy::reverse_iterator I = BlockList->rbegin(),
383 E = BlockList->rend(); I != E; ++I) {
384 BBInfo *Info = *I;
385
386 if (Info->DefBB != Info) {
387 // Record the available value to speed up subsequent uses of this
388 // SSAUpdater for the same value.
389 (*AvailableVals)[Info->BB] = Info->DefBB->AvailableVal;
390 continue;
391 }
392
393 // Check if this block contains a newly added PHI.
394 PhiT *PHI = Traits::ValueIsNewPHI(Info->AvailableVal, Updater);
395 if (!PHI)
396 continue;
397
398 // Iterate through the block's predecessors.
399 for (unsigned p = 0; p != Info->NumPreds; ++p) {
400 BBInfo *PredInfo = Info->Preds[p];
401 BlkT *Pred = PredInfo->BB;
402 // Skip to the nearest preceding definition.
403 if (PredInfo->DefBB != PredInfo)
404 PredInfo = PredInfo->DefBB;
405 Traits::AddPHIOperand(PHI, PredInfo->AvailableVal, Pred);
406 }
407
408 LLVM_DEBUG(dbgs() << " Inserted PHI: " << *PHI << "\n");
409
410 // If the client wants to know about all new instructions, tell it.
411 if (InsertedPHIs) InsertedPHIs->push_back(PHI);
412 }
413 }
414
415 /// FindExistingPHI - Look through the PHI nodes in a block to see if any of
416 /// them match what is needed.
417 void FindExistingPHI(BlkT *BB) {
418 SmallVector<BBInfo *, 20> TaggedBlocks;
419 // SSAUpdaterPhiSearchLimit is needed to guard against pathological cases
420 // (e.g. AMDGPU/large-phi-search.ll) where a large number of searches are
421 // done which all fail. Each search adds another PHI node to be searched.
422 // In a 3-stage build of LLVM the maximum search length was 53.
423 unsigned Count = 0;
424
425 for (auto &SomePHI : BB->phis()) {
426 // Abandon search for match. FindAvailableVals will create a new
427 // phi-node.
429 break;
430 if (CheckIfPHIMatches(&SomePHI, TaggedBlocks)) {
431 RecordMatchingPHIs(TaggedBlocks);
432 break;
433 }
434 }
435 }
436
437 /// CheckIfPHIMatches - Check if a PHI node matches the placement and values
438 /// in the BBMap.
439 bool CheckIfPHIMatches(PhiT *PHI, BlockListTy &TaggedBlocks) {
440 // Match failed: clear all the PHITag values. Only need to clear visited
441 // blocks.
442 scope_exit Cleanup([&]() {
443 for (BBInfo *TaggedBlock : TaggedBlocks)
444 TaggedBlock->PHITag = nullptr;
445 TaggedBlocks.clear();
446 });
447
449 WorkList.push_back(PHI);
450
451 // Mark that the block containing this PHI has been visited.
452 BBInfo *PHIBlock = BBMap[PHI->getParent()];
453 PHIBlock->PHITag = PHI;
454 TaggedBlocks.push_back(PHIBlock);
455
456 while (!WorkList.empty()) {
457 PHI = WorkList.pop_back_val();
458
459 // Iterate through the PHI's incoming values.
460 for (typename Traits::PHI_iterator I = Traits::PHI_begin(PHI),
461 E = Traits::PHI_end(PHI); I != E; ++I) {
462 ValT IncomingVal = I.getIncomingValue();
463 BBInfo *PredInfo = BBMap[I.getIncomingBlock()];
464 // Skip to the nearest preceding definition.
465 if (PredInfo->DefBB != PredInfo)
466 PredInfo = PredInfo->DefBB;
467
468 // Check if it matches the expected value.
469 if (PredInfo->AvailableVal) {
470 if (IncomingVal == PredInfo->AvailableVal)
471 continue;
472 return false;
473 }
474
475 // Check if the value is a PHI in the correct block.
476 PhiT *IncomingPHIVal = Traits::ValueIsPHI(IncomingVal, Updater);
477 if (!IncomingPHIVal || IncomingPHIVal->getParent() != PredInfo->BB)
478 return false;
479
480 // If this block has already been visited, check if this PHI matches.
481 if (PredInfo->PHITag) {
482 if (IncomingPHIVal == PredInfo->PHITag)
483 continue;
484 return false;
485 }
486 PredInfo->PHITag = IncomingPHIVal;
487 TaggedBlocks.push_back(PredInfo);
488
489 WorkList.push_back(IncomingPHIVal);
490 }
491 }
492 // Match found, keep PHITags.
493 Cleanup.release();
494 return true;
495 }
496
497 /// RecordMatchingPHIs - For each PHI node that matches, record it in both
498 /// the BBMap and the AvailableVals mapping.
499 void RecordMatchingPHIs(BlockListTy &TaggedBlocks) {
500 for (BBInfo *Block : TaggedBlocks) {
501 PhiT *PHI = Block->PHITag;
502 assert(PHI && "PHITag didn't set?");
503 BlkT *BB = PHI->getParent();
504 ValT PHIVal = Traits::GetPHIValue(PHI);
505 (*AvailableVals)[BB] = PHIVal;
506 BBMap[BB]->AvailableVal = PHIVal;
507 }
508 }
509};
510
511} // end namespace llvm
512
513#undef DEBUG_TYPE // "ssaupdater"
514
515#endif // LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Rewrite undef for PHI
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
ManagedStatic< HTTPClientCleanup > Cleanup
#define I(x, y, z)
Definition MD5.cpp:57
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
This file defines the SmallVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
void FindDominators(BlockListTy *BlockList, BBInfo *PseudoEntry)
FindDominators - Calculate the dominator tree for the subset of the CFG corresponding to the basic bl...
void FindAvailableVals(BlockListTy *BlockList)
FindAvailableVal - If this block requires a PHI, first check if an existing PHI matches the PHI place...
bool IsDefInDomFrontier(const BBInfo *Pred, const BBInfo *IDom)
IsDefInDomFrontier - Search up the dominator tree from Pred to IDom for any blocks containing definit...
ValT GetValue(BlkT *BB)
GetValue - Check to see if AvailableVals has an entry for the specified BB and if so,...
SSAUpdaterImpl(UpdaterT *U, AvailableValsTy *A, SmallVectorImpl< PhiT * > *Ins)
BBInfo * BuildBlockList(BlkT *BB, BlockListTy *BlockList)
BuildBlockList - Starting from the specified basic block, traverse back through its predecessors unti...
bool FindSingularVal(BBInfo *Info)
Check all predecessors and if all of them have the same AvailableVal use it as value for block repres...
void FindPHIPlacement(BlockListTy *BlockList)
FindPHIPlacement - PHIs are needed in the iterated dominance frontiers of the known definitions.
void FindExistingPHI(BlkT *BB)
FindExistingPHI - Look through the PHI nodes in a block to see if any of them match what is needed.
BBInfo * IntersectDominators(BBInfo *Blk1, BBInfo *Blk2)
IntersectDominators - This is the dataflow lattice "meet" operation for finding dominators.
void RecordMatchingPHIs(BlockListTy &TaggedBlocks)
RecordMatchingPHIs - For each PHI node that matches, record it in both the BBMap and the AvailableVal...
bool CheckIfPHIMatches(PhiT *PHI, BlockListTy &TaggedBlocks)
CheckIfPHIMatches - Check if a PHI node matches the placement and values in the BBMap.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
typename SuperClass::iterator iterator
void push_back(const T &Elt)
std::reverse_iterator< iterator > reverse_iterator
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Changed
template class LLVM_TEMPLATE_ABI opt< unsigned >
This is an optimization pass for GlobalISel generic memory operations.
cl::opt< unsigned > SSAUpdaterPhiSearchLimit
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:383