14#ifndef LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
15#define LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
25#define DEBUG_TYPE "ssaupdater"
31template<
typename T>
class SSAUpdaterTraits;
33template<
typename UpdaterT>
39 using BlkT =
typename Traits::BlkT;
40 using ValT =
typename Traits::ValT;
41 using PhiT =
typename Traits::PhiT;
61 BBInfo *IDom =
nullptr;
64 unsigned NumPreds = 0;
67 BBInfo **Preds =
nullptr;
70 PhiT *PHITag =
nullptr;
72 BBInfo(BlkT *ThisBB, ValT V)
73 : BB(ThisBB), AvailableVal(V), DefBB(V ?
this :
nullptr) {}
78 AvailableValsTy *AvailableVals;
91 Updater(U), AvailableVals(
A), InsertedPHIs(Ins) {}
102 if (BlockList.
size() == 0) {
103 ValT V = Traits::GetPoisonVal(BB, Updater);
104 (*AvailableVals)[BB] = V;
112 return BBMap[BB]->DefBB->AvailableVal;
123 BBInfo *Info =
new (Allocator) BBInfo(BB, 0);
131 while (!WorkList.
empty()) {
134 Traits::FindPredecessorBlocks(Info->BB, &Preds);
135 Info->NumPreds = Preds.
size();
136 if (Info->NumPreds == 0)
137 Info->Preds =
nullptr;
139 Info->Preds =
static_cast<BBInfo **
>(Allocator.Allocate(
140 Info->NumPreds *
sizeof(BBInfo *),
alignof(BBInfo *)));
142 for (
unsigned p = 0; p != Info->NumPreds; ++p) {
143 BlkT *Pred = Preds[p];
145 BBInfo *&BBMapBucket = BBMap[Pred];
147 Info->Preds[p] = BBMapBucket;
152 ValT PredVal = AvailableVals->lookup(Pred);
153 BBInfo *PredInfo =
new (Allocator) BBInfo(Pred, PredVal);
154 BBMapBucket = PredInfo;
155 Info->Preds[p] = PredInfo;
157 if (PredInfo->AvailableVal) {
168 BBInfo *PseudoEntry =
new (Allocator) BBInfo(
nullptr, 0);
172 while (!RootList.
empty()) {
174 Info->IDom = PseudoEntry;
179 while (!WorkList.
empty()) {
180 Info = WorkList.
back();
182 if (Info->BlkNum == -2) {
184 Info->BlkNum = BlkNum++;
186 if (!Info->AvailableVal)
199 for (
typename Traits::BlkSucc_iterator
SI =
200 Traits::BlkSucc_begin(Info->BB),
201 E = Traits::BlkSucc_end(Info->BB);
SI !=
E; ++
SI) {
202 BBInfo *SuccInfo = BBMap[*
SI];
203 if (!SuccInfo || SuccInfo->BlkNum)
205 SuccInfo->BlkNum = -1;
209 PseudoEntry->BlkNum = BlkNum;
218 while (Blk1 != Blk2) {
219 while (Blk1->BlkNum < Blk2->BlkNum) {
224 while (Blk2->BlkNum < Blk1->BlkNum) {
249 E = BlockList->
rend();
I !=
E; ++
I) {
251 BBInfo *NewIDom =
nullptr;
254 for (
unsigned p = 0; p != Info->NumPreds; ++p) {
255 BBInfo *Pred = Info->Preds[p];
258 if (Pred->BlkNum == 0) {
259 Pred->AvailableVal = Traits::GetPoisonVal(Pred->BB, Updater);
260 (*AvailableVals)[Pred->BB] = Pred->AvailableVal;
262 Pred->BlkNum = PseudoEntry->BlkNum;
263 PseudoEntry->BlkNum++;
273 if (NewIDom && NewIDom != Info->IDom) {
274 Info->IDom = NewIDom;
286 for (; Pred != IDom; Pred = Pred->IDom) {
287 if (Pred->DefBB == Pred)
303 E = BlockList->
rend();
I !=
E; ++
I) {
307 if (Info->DefBB == Info)
311 BBInfo *NewDefBB = Info->IDom->DefBB;
312 for (
unsigned p = 0; p != Info->NumPreds; ++p) {
321 if (NewDefBB != Info->DefBB) {
322 Info->DefBB = NewDefBB;
335 ValT Singular = Info->Preds[0]->DefBB->AvailableVal;
338 for (
unsigned Idx = 1; Idx < Info->NumPreds; ++Idx) {
339 ValT PredVal = Info->Preds[Idx]->DefBB->AvailableVal;
340 if (!PredVal || Singular != PredVal)
344 (*AvailableVals)[Info->BB] = Singular;
345 assert(BBMap[Info->BB] == Info &&
"Info missed in BBMap?");
346 Info->AvailableVal = Singular;
347 Info->DefBB = Info->Preds[0]->DefBB;
361 E = BlockList->
end();
I !=
E; ++
I) {
364 if (Info->DefBB != Info)
373 if (Info->AvailableVal)
376 ValT
PHI = Traits::CreateEmptyPHI(Info->BB, Info->NumPreds, Updater);
377 Info->AvailableVal =
PHI;
378 (*AvailableVals)[Info->BB] =
PHI;
384 E = BlockList->
rend();
I !=
E; ++
I) {
387 if (Info->DefBB != Info) {
390 (*AvailableVals)[Info->BB] = Info->DefBB->AvailableVal;
395 PhiT *
PHI = Traits::ValueIsNewPHI(Info->AvailableVal, Updater);
400 for (
unsigned p = 0; p != Info->NumPreds; ++p) {
401 BBInfo *PredInfo = Info->Preds[p];
402 BlkT *Pred = PredInfo->BB;
404 if (PredInfo->DefBB != PredInfo)
405 PredInfo = PredInfo->DefBB;
406 Traits::AddPHIOperand(
PHI, PredInfo->AvailableVal, Pred);
412 if (InsertedPHIs) InsertedPHIs->push_back(
PHI);
426 for (
auto &SomePHI : BB->phis()) {
444 for (BBInfo *TaggedBlock : TaggedBlocks)
445 TaggedBlock->PHITag =
nullptr;
446 TaggedBlocks.clear();
453 BBInfo *PHIBlock = BBMap[
PHI->getParent()];
454 PHIBlock->PHITag =
PHI;
457 while (!WorkList.empty()) {
458 PHI = WorkList.pop_back_val();
461 for (
typename Traits::PHI_iterator
I = Traits::PHI_begin(
PHI),
462 E = Traits::PHI_end(
PHI);
I !=
E; ++
I) {
463 ValT IncomingVal =
I.getIncomingValue();
464 BBInfo *PredInfo = BBMap[
I.getIncomingBlock()];
466 if (PredInfo->DefBB != PredInfo)
467 PredInfo = PredInfo->DefBB;
470 if (PredInfo->AvailableVal) {
471 if (IncomingVal == PredInfo->AvailableVal)
477 PhiT *IncomingPHIVal = Traits::ValueIsPHI(IncomingVal, Updater);
478 if (!IncomingPHIVal || IncomingPHIVal->getParent() != PredInfo->BB)
482 if (PredInfo->PHITag) {
483 if (IncomingPHIVal == PredInfo->PHITag)
487 PredInfo->PHITag = IncomingPHIVal;
490 WorkList.push_back(IncomingPHIVal);
501 for (BBInfo *
Block : TaggedBlocks) {
504 BlkT *BB =
PHI->getParent();
505 ValT PHIVal = Traits::GetPHIValue(
PHI);
506 (*AvailableVals)[BB] = PHIVal;
507 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.