14#ifndef LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
15#define LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
24#define DEBUG_TYPE "ssaupdater"
30template<
typename T>
class SSAUpdaterTraits;
32template<
typename UpdaterT>
38 using BlkT =
typename Traits::BlkT;
39 using ValT =
typename Traits::ValT;
40 using PhiT =
typename Traits::PhiT;
60 BBInfo *IDom =
nullptr;
63 unsigned NumPreds = 0;
66 BBInfo **Preds =
nullptr;
69 PhiT *PHITag =
nullptr;
71 BBInfo(BlkT *ThisBB, ValT V)
72 : BB(ThisBB), AvailableVal(V), DefBB(V ?
this :
nullptr) {}
77 AvailableValsTy *AvailableVals;
90 Updater(U), AvailableVals(
A), InsertedPHIs(Ins) {}
101 if (BlockList.
size() == 0) {
102 ValT V = Traits::GetPoisonVal(BB, Updater);
103 (*AvailableVals)[BB] = V;
111 return BBMap[BB]->DefBB->AvailableVal;
122 BBInfo *Info =
new (Allocator) BBInfo(BB, 0);
130 while (!WorkList.
empty()) {
133 Traits::FindPredecessorBlocks(Info->BB, &Preds);
134 Info->NumPreds = Preds.
size();
135 if (Info->NumPreds == 0)
136 Info->Preds =
nullptr;
138 Info->Preds =
static_cast<BBInfo **
>(Allocator.Allocate(
139 Info->NumPreds *
sizeof(BBInfo *),
alignof(BBInfo *)));
141 for (
unsigned p = 0; p != Info->NumPreds; ++p) {
142 BlkT *Pred = Preds[p];
144 BBInfo *&BBMapBucket = BBMap[Pred];
146 Info->Preds[p] = BBMapBucket;
151 ValT PredVal = AvailableVals->lookup(Pred);
152 BBInfo *PredInfo =
new (Allocator) BBInfo(Pred, PredVal);
153 BBMapBucket = PredInfo;
154 Info->Preds[p] = PredInfo;
156 if (PredInfo->AvailableVal) {
167 BBInfo *PseudoEntry =
new (Allocator) BBInfo(
nullptr, 0);
171 while (!RootList.
empty()) {
173 Info->IDom = PseudoEntry;
178 while (!WorkList.
empty()) {
179 Info = WorkList.
back();
181 if (Info->BlkNum == -2) {
183 Info->BlkNum = BlkNum++;
185 if (!Info->AvailableVal)
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)
204 SuccInfo->BlkNum = -1;
208 PseudoEntry->BlkNum = BlkNum;
217 while (Blk1 != Blk2) {
218 while (Blk1->BlkNum < Blk2->BlkNum) {
223 while (Blk2->BlkNum < Blk1->BlkNum) {
248 E = BlockList->
rend();
I !=
E; ++
I) {
250 BBInfo *NewIDom =
nullptr;
253 for (
unsigned p = 0; p != Info->NumPreds; ++p) {
254 BBInfo *Pred = Info->Preds[p];
257 if (Pred->BlkNum == 0) {
258 Pred->AvailableVal = Traits::GetPoisonVal(Pred->BB, Updater);
259 (*AvailableVals)[Pred->BB] = Pred->AvailableVal;
261 Pred->BlkNum = PseudoEntry->BlkNum;
262 PseudoEntry->BlkNum++;
272 if (NewIDom && NewIDom != Info->IDom) {
273 Info->IDom = NewIDom;
285 for (; Pred != IDom; Pred = Pred->IDom) {
286 if (Pred->DefBB == Pred)
302 E = BlockList->
rend();
I !=
E; ++
I) {
306 if (Info->DefBB == Info)
310 BBInfo *NewDefBB = Info->IDom->DefBB;
311 for (
unsigned p = 0; p != Info->NumPreds; ++p) {
320 if (NewDefBB != Info->DefBB) {
321 Info->DefBB = NewDefBB;
334 ValT Singular = Info->Preds[0]->DefBB->AvailableVal;
337 for (
unsigned Idx = 1; Idx < Info->NumPreds; ++Idx) {
338 ValT PredVal = Info->Preds[Idx]->DefBB->AvailableVal;
339 if (!PredVal || Singular != PredVal)
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;
360 E = BlockList->
end();
I !=
E; ++
I) {
363 if (Info->DefBB != Info)
372 if (Info->AvailableVal)
375 ValT
PHI = Traits::CreateEmptyPHI(Info->BB, Info->NumPreds, Updater);
376 Info->AvailableVal =
PHI;
377 (*AvailableVals)[Info->BB] =
PHI;
383 E = BlockList->
rend();
I !=
E; ++
I) {
386 if (Info->DefBB != Info) {
389 (*AvailableVals)[Info->BB] = Info->DefBB->AvailableVal;
394 PhiT *
PHI = Traits::ValueIsNewPHI(Info->AvailableVal, Updater);
399 for (
unsigned p = 0; p != Info->NumPreds; ++p) {
400 BBInfo *PredInfo = Info->Preds[p];
401 BlkT *Pred = PredInfo->BB;
403 if (PredInfo->DefBB != PredInfo)
404 PredInfo = PredInfo->DefBB;
405 Traits::AddPHIOperand(
PHI, PredInfo->AvailableVal, Pred);
411 if (InsertedPHIs) InsertedPHIs->push_back(
PHI);
425 for (
auto &SomePHI : BB->phis()) {
443 for (BBInfo *TaggedBlock : TaggedBlocks)
444 TaggedBlock->PHITag =
nullptr;
445 TaggedBlocks.clear();
452 BBInfo *PHIBlock = BBMap[
PHI->getParent()];
453 PHIBlock->PHITag =
PHI;
456 while (!WorkList.empty()) {
457 PHI = WorkList.pop_back_val();
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()];
465 if (PredInfo->DefBB != PredInfo)
466 PredInfo = PredInfo->DefBB;
469 if (PredInfo->AvailableVal) {
470 if (IncomingVal == PredInfo->AvailableVal)
476 PhiT *IncomingPHIVal = Traits::ValueIsPHI(IncomingVal, Updater);
477 if (!IncomingPHIVal || IncomingPHIVal->getParent() != PredInfo->BB)
481 if (PredInfo->PHITag) {
482 if (IncomingPHIVal == PredInfo->PHITag)
486 PredInfo->PHITag = IncomingPHIVal;
489 WorkList.push_back(IncomingPHIVal);
500 for (BBInfo *
Block : TaggedBlocks) {
503 BlkT *BB =
PHI->getParent();
504 ValT PHIVal = Traits::GetPHIValue(
PHI);
505 (*AvailableVals)[BB] = PHIVal;
506 BBMap[BB]->AvailableVal = PHIVal;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
This file defines the SmallVector class.
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)
reverse_iterator rbegin()
std::reverse_iterator< iterator > reverse_iterator
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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.
FunctionAddr VTableAddr Count
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.