15 #ifndef LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H 16 #define LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H 24 #define DEBUG_TYPE "ssaupdater" 28 template<
typename T>
class SSAUpdaterTraits;
30 template<
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::GetUndefVal(BB, Updater);
101 (*AvailableVals)[BB] = V;
109 return BBMap[BB]->DefBB->AvailableVal;
120 BBInfo *
Info =
new (Allocator) BBInfo(BB, 0);
128 while (!WorkList.
empty()) {
131 Traits::FindPredecessorBlocks(Info->BB, &Preds);
132 Info->NumPreds = Preds.
size();
133 if (Info->NumPreds == 0)
134 Info->Preds =
nullptr;
136 Info->Preds =
static_cast<BBInfo **
>(Allocator.
Allocate(
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()) {
178 Info = WorkList.
back();
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::GetUndefVal(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) {
305 if (Info->DefBB == Info)
309 BBInfo *NewDefBB = Info->IDom->DefBB;
310 for (
unsigned p = 0; p != Info->NumPreds; ++p) {
319 if (NewDefBB != Info->DefBB) {
320 Info->DefBB = NewDefBB;
337 E = BlockList->
end();
I !=
E; ++
I) {
340 if (Info->DefBB != Info)
345 if (Info->AvailableVal)
348 ValT PHI = Traits::CreateEmptyPHI(Info->BB, Info->NumPreds, Updater);
349 Info->AvailableVal = PHI;
350 (*AvailableVals)[Info->BB] = PHI;
356 E = BlockList->
rend();
I !=
E; ++
I) {
359 if (Info->DefBB != Info) {
362 (*AvailableVals)[Info->BB] = Info->DefBB->AvailableVal;
367 PhiT *PHI = Traits::ValueIsNewPHI(Info->AvailableVal, Updater);
372 for (
unsigned p = 0; p != Info->NumPreds; ++p) {
373 BBInfo *PredInfo = Info->Preds[p];
374 BlkT *Pred = PredInfo->BB;
376 if (PredInfo->DefBB != PredInfo)
377 PredInfo = PredInfo->DefBB;
378 Traits::AddPHIOperand(PHI, PredInfo->AvailableVal, Pred);
384 if (InsertedPHIs) InsertedPHIs->
push_back(PHI);
391 for (
auto &SomePHI : BB->phis()) {
398 E = BlockList->
end();
I !=
E; ++
I)
399 (*I)->PHITag =
nullptr;
410 BBMap[PHI->getParent()]->PHITag = PHI;
412 while (!WorkList.
empty()) {
416 for (
typename Traits::PHI_iterator
I = Traits::PHI_begin(PHI),
417 E = Traits::PHI_end(PHI);
I !=
E; ++
I) {
418 ValT IncomingVal =
I.getIncomingValue();
419 BBInfo *PredInfo = BBMap[
I.getIncomingBlock()];
421 if (PredInfo->DefBB != PredInfo)
422 PredInfo = PredInfo->DefBB;
425 if (PredInfo->AvailableVal) {
426 if (IncomingVal == PredInfo->AvailableVal)
432 PhiT *IncomingPHIVal = Traits::ValueIsPHI(IncomingVal, Updater);
433 if (!IncomingPHIVal || IncomingPHIVal->getParent() != PredInfo->BB)
437 if (PredInfo->PHITag) {
438 if (IncomingPHIVal == PredInfo->PHITag)
442 PredInfo->PHITag = IncomingPHIVal;
454 E = BlockList->
end();
I !=
E; ++
I)
455 if (PhiT *PHI = (*I)->PHITag) {
456 BlkT *BB = PHI->getParent();
457 ValT PHIVal = Traits::GetPHIValue(PHI);
458 (*AvailableVals)[BB] = PHIVal;
459 BBMap[BB]->AvailableVal = PHIVal;
466 #undef DEBUG_TYPE // "ssaupdater" 468 #endif // LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
SSAUpdaterImpl(UpdaterT *U, AvailableValsTy *A, SmallVectorImpl< PhiT *> *Ins)
This class represents lattice values for constants.
void push_back(const T &Elt)
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.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool CheckIfPHIMatches(PhiT *PHI)
CheckIfPHIMatches - Check if a PHI node matches the placement and values in the BBMap.
Analysis containing CSE Info
value_type & FindAndConstruct(const KeyT &Key)
Allocate memory in an ever growing pool, as if by bump-pointer.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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...
std::reverse_iterator< iterator > reverse_iterator
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...
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.
typename SuperClass::iterator iterator
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
BBInfo * IntersectDominators(BBInfo *Blk1, BBInfo *Blk2)
IntersectDominators - This is the dataflow lattice "meet" operation for finding dominators.
LLVM_NODISCARD bool empty() const
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...
reverse_iterator rbegin()
BBInfo * BuildBlockList(BlkT *BB, BlockListTy *BlockList)
BuildBlockList - Starting from the specified basic block, traverse back through its predecessors unti...