14#ifndef LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
15#define LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
24#define DEBUG_TYPE "ssaupdater"
28template<
typename T>
class SSAUpdaterTraits;
30template<
typename UpdaterT>
36 using BlkT =
typename Traits::BlkT;
37 using ValT =
typename Traits::ValT;
38 using PhiT =
typename Traits::PhiT;
58 BBInfo *IDom =
nullptr;
61 unsigned NumPreds = 0;
64 BBInfo **Preds =
nullptr;
67 PhiT *PHITag =
nullptr;
69 BBInfo(BlkT *ThisBB, ValT V)
70 : BB(ThisBB), AvailableVal(V), DefBB(V ?
this :
nullptr) {}
88 Updater(U), AvailableVals(
A), InsertedPHIs(Ins) {}
99 if (BlockList.
size() == 0) {
100 ValT V = Traits::GetPoisonVal(BB, Updater);
101 (*AvailableVals)[BB] = V;
109 return BBMap[BB]->DefBB->AvailableVal;
128 while (!WorkList.
empty()) {
131 Traits::FindPredecessorBlocks(
Info->BB, &Preds);
133 if (
Info->NumPreds == 0)
134 Info->Preds =
nullptr;
137 Info->NumPreds *
sizeof(BBInfo *),
alignof(BBInfo *)));
139 for (
unsigned p = 0; p !=
Info->NumPreds; ++p) {
140 BlkT *Pred = Preds[p];
144 if (BBMapBucket.second) {
145 Info->Preds[p] = BBMapBucket.second;
150 ValT PredVal = AvailableVals->
lookup(Pred);
151 BBInfo *PredInfo =
new (
Allocator) BBInfo(Pred, PredVal);
152 BBMapBucket.second = PredInfo;
153 Info->Preds[p] = PredInfo;
155 if (PredInfo->AvailableVal) {
166 BBInfo *PseudoEntry =
new (
Allocator) BBInfo(
nullptr, 0);
170 while (!RootList.
empty()) {
172 Info->IDom = PseudoEntry;
177 while (!WorkList.
empty()) {
180 if (
Info->BlkNum == -2) {
182 Info->BlkNum = BlkNum++;
184 if (!
Info->AvailableVal)
197 for (
typename Traits::BlkSucc_iterator SI =
198 Traits::BlkSucc_begin(
Info->BB),
199 E = Traits::BlkSucc_end(
Info->BB); SI !=
E; ++SI) {
200 BBInfo *SuccInfo = BBMap[*SI];
201 if (!SuccInfo || SuccInfo->BlkNum)
203 SuccInfo->BlkNum = -1;
207 PseudoEntry->BlkNum = BlkNum;
216 while (Blk1 != Blk2) {
217 while (Blk1->BlkNum < Blk2->BlkNum) {
222 while (Blk2->BlkNum < Blk1->BlkNum) {
247 E = BlockList->
rend();
I !=
E; ++
I) {
249 BBInfo *NewIDom =
nullptr;
252 for (
unsigned p = 0; p !=
Info->NumPreds; ++p) {
253 BBInfo *Pred =
Info->Preds[p];
256 if (Pred->BlkNum == 0) {
257 Pred->AvailableVal = Traits::GetPoisonVal(Pred->BB, Updater);
258 (*AvailableVals)[Pred->BB] = Pred->AvailableVal;
260 Pred->BlkNum = PseudoEntry->BlkNum;
261 PseudoEntry->BlkNum++;
271 if (NewIDom && NewIDom !=
Info->IDom) {
272 Info->IDom = NewIDom;
284 for (; Pred != IDom; Pred = Pred->IDom) {
285 if (Pred->DefBB == Pred)
301 E = BlockList->
rend();
I !=
E; ++
I) {
309 BBInfo *NewDefBB =
Info->IDom->DefBB;
310 for (
unsigned p = 0; p !=
Info->NumPreds; ++p) {
319 if (NewDefBB !=
Info->DefBB) {
320 Info->DefBB = NewDefBB;
333 ValT Singular =
Info->Preds[0]->DefBB->AvailableVal;
337 ValT PredVal =
Info->Preds[
Idx]->DefBB->AvailableVal;
338 if (!PredVal || Singular != PredVal)
342 (*AvailableVals)[
Info->BB] = Singular;
344 Info->AvailableVal = Singular;
345 Info->DefBB =
Info->Preds[0]->DefBB;
359 E = BlockList->
end();
I !=
E; ++
I) {
371 if (
Info->AvailableVal)
374 ValT
PHI = Traits::CreateEmptyPHI(
Info->BB,
Info->NumPreds, Updater);
376 (*AvailableVals)[
Info->BB] =
PHI;
382 E = BlockList->
rend();
I !=
E; ++
I) {
388 (*AvailableVals)[
Info->BB] =
Info->DefBB->AvailableVal;
393 PhiT *
PHI = Traits::ValueIsNewPHI(
Info->AvailableVal, Updater);
398 for (
unsigned p = 0; p !=
Info->NumPreds; ++p) {
399 BBInfo *PredInfo =
Info->Preds[p];
400 BlkT *Pred = PredInfo->BB;
402 if (PredInfo->DefBB != PredInfo)
403 PredInfo = PredInfo->DefBB;
404 Traits::AddPHIOperand(
PHI, PredInfo->AvailableVal, Pred);
418 for (
auto &SomePHI : BB->phis()) {
432 for (BBInfo *TaggedBlock : TaggedBlocks)
433 TaggedBlock->PHITag =
nullptr;
434 TaggedBlocks.clear();
441 BBInfo *PHIBlock = BBMap[
PHI->getParent()];
442 PHIBlock->PHITag =
PHI;
445 while (!WorkList.empty()) {
446 PHI = WorkList.pop_back_val();
449 for (
typename Traits::PHI_iterator
I = Traits::PHI_begin(
PHI),
450 E = Traits::PHI_end(
PHI);
I !=
E; ++
I) {
451 ValT IncomingVal =
I.getIncomingValue();
452 BBInfo *PredInfo = BBMap[
I.getIncomingBlock()];
454 if (PredInfo->DefBB != PredInfo)
455 PredInfo = PredInfo->DefBB;
458 if (PredInfo->AvailableVal) {
459 if (IncomingVal == PredInfo->AvailableVal)
465 PhiT *IncomingPHIVal = Traits::ValueIsPHI(IncomingVal, Updater);
466 if (!IncomingPHIVal || IncomingPHIVal->getParent() != PredInfo->BB)
470 if (PredInfo->PHITag) {
471 if (IncomingPHIVal == PredInfo->PHITag)
475 PredInfo->PHITag = IncomingPHIVal;
478 WorkList.push_back(IncomingPHIVal);
490 E = BlockList->
end();
I !=
E; ++
I)
491 if (PhiT *
PHI = (*I)->PHITag) {
492 BlkT *BB =
PHI->getParent();
493 ValT PHIVal = Traits::GetPHIValue(
PHI);
494 (*AvailableVals)[BB] = PHIVal;
495 BBMap[BB]->AvailableVal = PHIVal;
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")
Analysis containing CSE Info
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
static const HTTPClientCleanup Cleanup
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
This file defines the SmallVector class.
Allocate memory in an ever growing pool, as if by bump-pointer.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
value_type & FindAndConstruct(const KeyT &Key)
void FindDominators(BlockListTy *BlockList, BBInfo *PseudoEntry)
FindDominators - Calculate the dominator tree for the subset of the CFG corresponding to the basic bl...
void RecordMatchingPHIs(BlockListTy *BlockList)
RecordMatchingPHIs - For each PHI node that matches, record it in both the BBMap and the AvailableVal...
bool CheckIfPHIMatches(PhiT *PHI, SmallVectorImpl< BBInfo * > &TaggedBlocks)
CheckIfPHIMatches - Check if a PHI node matches the placement and values in the BBMap.
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...
void FindExistingPHI(BlkT *BB, BlockListTy *BlockList)
FindExistingPHI - Look through the PHI nodes in a block to see if any of them match what is needed.
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.
BBInfo * IntersectDominators(BBInfo *Blk1, BBInfo *Blk2)
IntersectDominators - This is the dataflow lattice "meet" operation for finding dominators.
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.
This is an optimization pass for GlobalISel generic memory operations.
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.