15 #ifndef LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
16 #define LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
27 #define DEBUG_TYPE "ssaupdater"
31 template<
typename T>
class SSAUpdaterTraits;
33 template<
typename UpdaterT>
39 typedef typename Traits::BlkT BlkT;
40 typedef typename Traits::ValT ValT;
41 typedef typename Traits::PhiT PhiT;
57 BBInfo(BlkT *ThisBB, ValT V)
58 : BB(ThisBB), AvailableVal(V), DefBB(V ?
this :
nullptr), BlkNum(0),
59 IDom(
nullptr), NumPreds(0), Preds(
nullptr), PHITag(
nullptr) {}
75 Updater(U), AvailableVals(A), InsertedPHIs(Ins) { }
86 if (BlockList.
size() == 0) {
87 ValT V = Traits::GetUndefVal(BB, Updater);
88 (*AvailableVals)[BB] = V;
96 return BBMap[BB]->DefBB->AvailableVal;
107 BBInfo *Info =
new (Allocator) BBInfo(BB, 0);
115 while (!WorkList.
empty()) {
118 Traits::FindPredecessorBlocks(Info->BB, &Preds);
119 Info->NumPreds = Preds.
size();
120 if (Info->NumPreds == 0)
121 Info->Preds =
nullptr;
123 Info->Preds =
static_cast<BBInfo **
>(Allocator.
Allocate(
124 Info->NumPreds *
sizeof(BBInfo *),
alignof(BBInfo *)));
126 for (
unsigned p = 0; p != Info->NumPreds; ++p) {
127 BlkT *Pred = Preds[p];
131 if (BBMapBucket.second) {
132 Info->Preds[p] = BBMapBucket.second;
137 ValT PredVal = AvailableVals->
lookup(Pred);
138 BBInfo *PredInfo =
new (Allocator) BBInfo(Pred, PredVal);
139 BBMapBucket.second = PredInfo;
140 Info->Preds[p] = PredInfo;
142 if (PredInfo->AvailableVal) {
153 BBInfo *PseudoEntry =
new (Allocator) BBInfo(
nullptr, 0);
157 while (!RootList.
empty()) {
159 Info->IDom = PseudoEntry;
164 while (!WorkList.
empty()) {
165 Info = WorkList.
back();
167 if (Info->BlkNum == -2) {
169 Info->BlkNum = BlkNum++;
171 if (!Info->AvailableVal)
184 for (
typename Traits::BlkSucc_iterator
SI =
185 Traits::BlkSucc_begin(Info->BB),
186 E = Traits::BlkSucc_end(Info->BB);
SI !=
E; ++
SI) {
187 BBInfo *SuccInfo = BBMap[*
SI];
188 if (!SuccInfo || SuccInfo->BlkNum)
190 SuccInfo->BlkNum = -1;
194 PseudoEntry->BlkNum = BlkNum;
203 while (Blk1 != Blk2) {
204 while (Blk1->BlkNum < Blk2->BlkNum) {
209 while (Blk2->BlkNum < Blk1->BlkNum) {
234 E = BlockList->
rend();
I !=
E; ++
I) {
236 BBInfo *NewIDom =
nullptr;
239 for (
unsigned p = 0; p != Info->NumPreds; ++p) {
240 BBInfo *Pred = Info->Preds[p];
243 if (Pred->BlkNum == 0) {
244 Pred->AvailableVal = Traits::GetUndefVal(Pred->BB, Updater);
245 (*AvailableVals)[Pred->BB] = Pred->AvailableVal;
247 Pred->BlkNum = PseudoEntry->BlkNum;
248 PseudoEntry->BlkNum++;
258 if (NewIDom && NewIDom != Info->IDom) {
259 Info->IDom = NewIDom;
271 for (; Pred != IDom; Pred = Pred->IDom) {
272 if (Pred->DefBB == Pred)
288 E = BlockList->
rend();
I !=
E; ++
I) {
292 if (Info->DefBB == Info)
296 BBInfo *NewDefBB = Info->IDom->DefBB;
297 for (
unsigned p = 0; p != Info->NumPreds; ++p) {
306 if (NewDefBB != Info->DefBB) {
307 Info->DefBB = NewDefBB;
324 E = BlockList->
end();
I !=
E; ++
I) {
327 if (Info->DefBB != Info)
332 if (Info->AvailableVal)
335 ValT PHI = Traits::CreateEmptyPHI(Info->BB, Info->NumPreds, Updater);
336 Info->AvailableVal = PHI;
337 (*AvailableVals)[Info->BB] = PHI;
343 E = BlockList->
rend();
I !=
E; ++
I) {
346 if (Info->DefBB != Info) {
349 if (Info->NumPreds > 1)
350 (*AvailableVals)[Info->BB] = Info->DefBB->AvailableVal;
355 PhiT *PHI = Traits::ValueIsNewPHI(Info->AvailableVal, Updater);
360 for (
unsigned p = 0; p != Info->NumPreds; ++p) {
361 BBInfo *PredInfo = Info->Preds[p];
362 BlkT *Pred = PredInfo->BB;
364 if (PredInfo->DefBB != PredInfo)
365 PredInfo = PredInfo->DefBB;
366 Traits::AddPHIOperand(PHI, PredInfo->AvailableVal, Pred);
369 DEBUG(
dbgs() <<
" Inserted PHI: " << *PHI <<
"\n");
372 if (InsertedPHIs) InsertedPHIs->
push_back(PHI);
379 for (
typename BlkT::iterator BBI = BB->begin(), BBE = BB->end();
381 PhiT *SomePHI = Traits::InstrIsPHI(&*BBI);
390 E = BlockList->
end();
I !=
E; ++
I)
391 (*I)->PHITag =
nullptr;
402 BBMap[PHI->getParent()]->PHITag = PHI;
404 while (!WorkList.
empty()) {
408 for (
typename Traits::PHI_iterator
I = Traits::PHI_begin(PHI),
409 E = Traits::PHI_end(PHI);
I !=
E; ++
I) {
410 ValT IncomingVal =
I.getIncomingValue();
411 BBInfo *PredInfo = BBMap[
I.getIncomingBlock()];
413 if (PredInfo->DefBB != PredInfo)
414 PredInfo = PredInfo->DefBB;
417 if (PredInfo->AvailableVal) {
418 if (IncomingVal == PredInfo->AvailableVal)
424 PhiT *IncomingPHIVal = Traits::ValueIsPHI(IncomingVal, Updater);
425 if (!IncomingPHIVal || IncomingPHIVal->getParent() != PredInfo->BB)
429 if (PredInfo->PHITag) {
430 if (IncomingPHIVal == PredInfo->PHITag)
434 PredInfo->PHITag = IncomingPHIVal;
446 E = BlockList->
end();
I !=
E; ++
I)
447 if (PhiT *PHI = (*I)->PHITag) {
448 BlkT *BB = PHI->getParent();
449 ValT PHIVal = Traits::GetPHIValue(PHI);
450 (*AvailableVals)[BB] = PHIVal;
451 BBMap[BB]->AvailableVal = PHIVal;
456 #undef DEBUG_TYPE // "ssaupdater"
std::reverse_iterator< iterator > reverse_iterator
void push_back(const T &Elt)
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
ValT GetValue(BlkT *BB)
GetValue - Check to see if AvailableVals has an entry for the specified BB and if so...
void FindPHIPlacement(BlockListTy *BlockList)
FindPHIPlacement - PHIs are needed in the iterated dominance frontiers of the known definitions...
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...
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
LLVM_NODISCARD bool empty() const
bool CheckIfPHIMatches(PhiT *PHI)
CheckIfPHIMatches - Check if a PHI node matches the placement and values in the BBMap.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
value_type & FindAndConstruct(const KeyT &Key)
Allocate memory in an ever growing pool, as if by bump-pointer.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * Allocate(size_t Size, size_t Alignment)
Allocate space at the specified alignment.
void FindDominators(BlockListTy *BlockList, BBInfo *PseudoEntry)
FindDominators - Calculate the dominator tree for the subset of the CFG corresponding to the basic bl...
bool IsDefInDomFrontier(const BBInfo *Pred, const BBInfo *IDom)
IsDefInDomFrontier - Search up the dominator tree from Pred to IDom for any blocks containing definit...
void RecordMatchingPHIs(BlockListTy *BlockList)
RecordMatchingPHIs - For each PHI node that matches, record it in both the BBMap and the AvailableVal...
SSAUpdaterImpl(UpdaterT *U, AvailableValsTy *A, SmallVectorImpl< PhiT * > *Ins)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
LLVM_NODISCARD T pop_back_val()
void FindAvailableVals(BlockListTy *BlockList)
FindAvailableVal - If this block requires a PHI, first check if an existing PHI matches the PHI place...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
BBInfo * IntersectDominators(BBInfo *Blk1, BBInfo *Blk2)
IntersectDominators - This is the dataflow lattice "meet" operation for finding dominators.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
reverse_iterator rbegin()
BBInfo * BuildBlockList(BlkT *BB, BlockListTy *BlockList)
BuildBlockList - Starting from the specified basic block, traverse back through its predecessors unti...
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")