Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:44

0001 //===- SSAUpdaterImpl.h - SSA Updater Implementation ------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file provides a template that implements the core algorithm for the
0010 // SSAUpdater and MachineSSAUpdater.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
0015 #define LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H
0016 
0017 #include "llvm/ADT/DenseMap.h"
0018 #include "llvm/ADT/ScopeExit.h"
0019 #include "llvm/ADT/SmallVector.h"
0020 #include "llvm/Support/Allocator.h"
0021 #include "llvm/Support/Debug.h"
0022 #include "llvm/Support/raw_ostream.h"
0023 
0024 #define DEBUG_TYPE "ssaupdater"
0025 
0026 namespace llvm {
0027 
0028 template<typename T> class SSAUpdaterTraits;
0029 
0030 template<typename UpdaterT>
0031 class SSAUpdaterImpl {
0032 private:
0033   UpdaterT *Updater;
0034 
0035   using Traits = SSAUpdaterTraits<UpdaterT>;
0036   using BlkT = typename Traits::BlkT;
0037   using ValT = typename Traits::ValT;
0038   using PhiT = typename Traits::PhiT;
0039 
0040   /// BBInfo - Per-basic block information used internally by SSAUpdaterImpl.
0041   /// The predecessors of each block are cached here since pred_iterator is
0042   /// slow and we need to iterate over the blocks at least a few times.
0043   class BBInfo {
0044   public:
0045     // Back-pointer to the corresponding block.
0046     BlkT *BB;
0047 
0048     // Value to use in this block.
0049     ValT AvailableVal;
0050 
0051     // Block that defines the available value.
0052     BBInfo *DefBB;
0053 
0054     // Postorder number.
0055     int BlkNum = 0;
0056 
0057     // Immediate dominator.
0058     BBInfo *IDom = nullptr;
0059 
0060     // Number of predecessor blocks.
0061     unsigned NumPreds = 0;
0062 
0063     // Array[NumPreds] of predecessor blocks.
0064     BBInfo **Preds = nullptr;
0065 
0066     // Marker for existing PHIs that match.
0067     PhiT *PHITag = nullptr;
0068 
0069     BBInfo(BlkT *ThisBB, ValT V)
0070       : BB(ThisBB), AvailableVal(V), DefBB(V ? this : nullptr) {}
0071   };
0072 
0073   using AvailableValsTy = DenseMap<BlkT *, ValT>;
0074 
0075   AvailableValsTy *AvailableVals;
0076 
0077   SmallVectorImpl<PhiT *> *InsertedPHIs;
0078 
0079   using BlockListTy = SmallVectorImpl<BBInfo *>;
0080   using BBMapTy = DenseMap<BlkT *, BBInfo *>;
0081 
0082   BBMapTy BBMap;
0083   BumpPtrAllocator Allocator;
0084 
0085 public:
0086   explicit SSAUpdaterImpl(UpdaterT *U, AvailableValsTy *A,
0087                           SmallVectorImpl<PhiT *> *Ins) :
0088     Updater(U), AvailableVals(A), InsertedPHIs(Ins) {}
0089 
0090   /// GetValue - Check to see if AvailableVals has an entry for the specified
0091   /// BB and if so, return it.  If not, construct SSA form by first
0092   /// calculating the required placement of PHIs and then inserting new PHIs
0093   /// where needed.
0094   ValT GetValue(BlkT *BB) {
0095     SmallVector<BBInfo *, 100> BlockList;
0096     BBInfo *PseudoEntry = BuildBlockList(BB, &BlockList);
0097 
0098     // Special case: bail out if BB is unreachable.
0099     if (BlockList.size() == 0) {
0100       ValT V = Traits::GetPoisonVal(BB, Updater);
0101       (*AvailableVals)[BB] = V;
0102       return V;
0103     }
0104 
0105     FindDominators(&BlockList, PseudoEntry);
0106     FindPHIPlacement(&BlockList);
0107     FindAvailableVals(&BlockList);
0108 
0109     return BBMap[BB]->DefBB->AvailableVal;
0110   }
0111 
0112   /// BuildBlockList - Starting from the specified basic block, traverse back
0113   /// through its predecessors until reaching blocks with known values.
0114   /// Create BBInfo structures for the blocks and append them to the block
0115   /// list.
0116   BBInfo *BuildBlockList(BlkT *BB, BlockListTy *BlockList) {
0117     SmallVector<BBInfo *, 10> RootList;
0118     SmallVector<BBInfo *, 64> WorkList;
0119 
0120     BBInfo *Info = new (Allocator) BBInfo(BB, 0);
0121     BBMap[BB] = Info;
0122     WorkList.push_back(Info);
0123 
0124     // Search backward from BB, creating BBInfos along the way and stopping
0125     // when reaching blocks that define the value.  Record those defining
0126     // blocks on the RootList.
0127     SmallVector<BlkT *, 10> Preds;
0128     while (!WorkList.empty()) {
0129       Info = WorkList.pop_back_val();
0130       Preds.clear();
0131       Traits::FindPredecessorBlocks(Info->BB, &Preds);
0132       Info->NumPreds = Preds.size();
0133       if (Info->NumPreds == 0)
0134         Info->Preds = nullptr;
0135       else
0136         Info->Preds = static_cast<BBInfo **>(Allocator.Allocate(
0137             Info->NumPreds * sizeof(BBInfo *), alignof(BBInfo *)));
0138 
0139       for (unsigned p = 0; p != Info->NumPreds; ++p) {
0140         BlkT *Pred = Preds[p];
0141         // Check if BBMap already has a BBInfo for the predecessor block.
0142         BBInfo *&BBMapBucket = BBMap[Pred];
0143         if (BBMapBucket) {
0144           Info->Preds[p] = BBMapBucket;
0145           continue;
0146         }
0147 
0148         // Create a new BBInfo for the predecessor.
0149         ValT PredVal = AvailableVals->lookup(Pred);
0150         BBInfo *PredInfo = new (Allocator) BBInfo(Pred, PredVal);
0151         BBMapBucket = PredInfo;
0152         Info->Preds[p] = PredInfo;
0153 
0154         if (PredInfo->AvailableVal) {
0155           RootList.push_back(PredInfo);
0156           continue;
0157         }
0158         WorkList.push_back(PredInfo);
0159       }
0160     }
0161 
0162     // Now that we know what blocks are backwards-reachable from the starting
0163     // block, do a forward depth-first traversal to assign postorder numbers
0164     // to those blocks.
0165     BBInfo *PseudoEntry = new (Allocator) BBInfo(nullptr, 0);
0166     unsigned BlkNum = 1;
0167 
0168     // Initialize the worklist with the roots from the backward traversal.
0169     while (!RootList.empty()) {
0170       Info = RootList.pop_back_val();
0171       Info->IDom = PseudoEntry;
0172       Info->BlkNum = -1;
0173       WorkList.push_back(Info);
0174     }
0175 
0176     while (!WorkList.empty()) {
0177       Info = WorkList.back();
0178 
0179       if (Info->BlkNum == -2) {
0180         // All the successors have been handled; assign the postorder number.
0181         Info->BlkNum = BlkNum++;
0182         // If not a root, put it on the BlockList.
0183         if (!Info->AvailableVal)
0184           BlockList->push_back(Info);
0185         WorkList.pop_back();
0186         continue;
0187       }
0188 
0189       // Leave this entry on the worklist, but set its BlkNum to mark that its
0190       // successors have been put on the worklist.  When it returns to the top
0191       // the list, after handling its successors, it will be assigned a
0192       // number.
0193       Info->BlkNum = -2;
0194 
0195       // Add unvisited successors to the work list.
0196       for (typename Traits::BlkSucc_iterator SI =
0197              Traits::BlkSucc_begin(Info->BB),
0198              E = Traits::BlkSucc_end(Info->BB); SI != E; ++SI) {
0199         BBInfo *SuccInfo = BBMap[*SI];
0200         if (!SuccInfo || SuccInfo->BlkNum)
0201           continue;
0202         SuccInfo->BlkNum = -1;
0203         WorkList.push_back(SuccInfo);
0204       }
0205     }
0206     PseudoEntry->BlkNum = BlkNum;
0207     return PseudoEntry;
0208   }
0209 
0210   /// IntersectDominators - This is the dataflow lattice "meet" operation for
0211   /// finding dominators.  Given two basic blocks, it walks up the dominator
0212   /// tree until it finds a common dominator of both.  It uses the postorder
0213   /// number of the blocks to determine how to do that.
0214   BBInfo *IntersectDominators(BBInfo *Blk1, BBInfo *Blk2) {
0215     while (Blk1 != Blk2) {
0216       while (Blk1->BlkNum < Blk2->BlkNum) {
0217         Blk1 = Blk1->IDom;
0218         if (!Blk1)
0219           return Blk2;
0220       }
0221       while (Blk2->BlkNum < Blk1->BlkNum) {
0222         Blk2 = Blk2->IDom;
0223         if (!Blk2)
0224           return Blk1;
0225       }
0226     }
0227     return Blk1;
0228   }
0229 
0230   /// FindDominators - Calculate the dominator tree for the subset of the CFG
0231   /// corresponding to the basic blocks on the BlockList.  This uses the
0232   /// algorithm from: "A Simple, Fast Dominance Algorithm" by Cooper, Harvey
0233   /// and Kennedy, published in Software--Practice and Experience, 2001,
0234   /// 4:1-10.  Because the CFG subset does not include any edges leading into
0235   /// blocks that define the value, the results are not the usual dominator
0236   /// tree.  The CFG subset has a single pseudo-entry node with edges to a set
0237   /// of root nodes for blocks that define the value.  The dominators for this
0238   /// subset CFG are not the standard dominators but they are adequate for
0239   /// placing PHIs within the subset CFG.
0240   void FindDominators(BlockListTy *BlockList, BBInfo *PseudoEntry) {
0241     bool Changed;
0242     do {
0243       Changed = false;
0244       // Iterate over the list in reverse order, i.e., forward on CFG edges.
0245       for (typename BlockListTy::reverse_iterator I = BlockList->rbegin(),
0246              E = BlockList->rend(); I != E; ++I) {
0247         BBInfo *Info = *I;
0248         BBInfo *NewIDom = nullptr;
0249 
0250         // Iterate through the block's predecessors.
0251         for (unsigned p = 0; p != Info->NumPreds; ++p) {
0252           BBInfo *Pred = Info->Preds[p];
0253 
0254           // Treat an unreachable predecessor as a definition with 'poison'.
0255           if (Pred->BlkNum == 0) {
0256             Pred->AvailableVal = Traits::GetPoisonVal(Pred->BB, Updater);
0257             (*AvailableVals)[Pred->BB] = Pred->AvailableVal;
0258             Pred->DefBB = Pred;
0259             Pred->BlkNum = PseudoEntry->BlkNum;
0260             PseudoEntry->BlkNum++;
0261           }
0262 
0263           if (!NewIDom)
0264             NewIDom = Pred;
0265           else
0266             NewIDom = IntersectDominators(NewIDom, Pred);
0267         }
0268 
0269         // Check if the IDom value has changed.
0270         if (NewIDom && NewIDom != Info->IDom) {
0271           Info->IDom = NewIDom;
0272           Changed = true;
0273         }
0274       }
0275     } while (Changed);
0276   }
0277 
0278   /// IsDefInDomFrontier - Search up the dominator tree from Pred to IDom for
0279   /// any blocks containing definitions of the value.  If one is found, then
0280   /// the successor of Pred is in the dominance frontier for the definition,
0281   /// and this function returns true.
0282   bool IsDefInDomFrontier(const BBInfo *Pred, const BBInfo *IDom) {
0283     for (; Pred != IDom; Pred = Pred->IDom) {
0284       if (Pred->DefBB == Pred)
0285         return true;
0286     }
0287     return false;
0288   }
0289 
0290   /// FindPHIPlacement - PHIs are needed in the iterated dominance frontiers
0291   /// of the known definitions.  Iteratively add PHIs in the dom frontiers
0292   /// until nothing changes.  Along the way, keep track of the nearest
0293   /// dominating definitions for non-PHI blocks.
0294   void FindPHIPlacement(BlockListTy *BlockList) {
0295     bool Changed;
0296     do {
0297       Changed = false;
0298       // Iterate over the list in reverse order, i.e., forward on CFG edges.
0299       for (typename BlockListTy::reverse_iterator I = BlockList->rbegin(),
0300              E = BlockList->rend(); I != E; ++I) {
0301         BBInfo *Info = *I;
0302 
0303         // If this block already needs a PHI, there is nothing to do here.
0304         if (Info->DefBB == Info)
0305           continue;
0306 
0307         // Default to use the same def as the immediate dominator.
0308         BBInfo *NewDefBB = Info->IDom->DefBB;
0309         for (unsigned p = 0; p != Info->NumPreds; ++p) {
0310           if (IsDefInDomFrontier(Info->Preds[p], Info->IDom)) {
0311             // Need a PHI here.
0312             NewDefBB = Info;
0313             break;
0314           }
0315         }
0316 
0317         // Check if anything changed.
0318         if (NewDefBB != Info->DefBB) {
0319           Info->DefBB = NewDefBB;
0320           Changed = true;
0321         }
0322       }
0323     } while (Changed);
0324   }
0325 
0326   /// Check all predecessors and if all of them have the same AvailableVal use
0327   /// it as value for block represented by Info. Return true if singluar value
0328   /// is found.
0329   bool FindSingularVal(BBInfo *Info) {
0330     if (!Info->NumPreds)
0331       return false;
0332     ValT Singular = Info->Preds[0]->DefBB->AvailableVal;
0333     if (!Singular)
0334       return false;
0335     for (unsigned Idx = 1; Idx < Info->NumPreds; ++Idx) {
0336       ValT PredVal = Info->Preds[Idx]->DefBB->AvailableVal;
0337       if (!PredVal || Singular != PredVal)
0338         return false;
0339     }
0340     // Record Singular value.
0341     (*AvailableVals)[Info->BB] = Singular;
0342     assert(BBMap[Info->BB] == Info && "Info missed in BBMap?");
0343     Info->AvailableVal = Singular;
0344     Info->DefBB = Info->Preds[0]->DefBB;
0345     return true;
0346   }
0347 
0348   /// FindAvailableVal - If this block requires a PHI, first check if an
0349   /// existing PHI matches the PHI placement and reaching definitions computed
0350   /// earlier, and if not, create a new PHI.  Visit all the block's
0351   /// predecessors to calculate the available value for each one and fill in
0352   /// the incoming values for a new PHI.
0353   void FindAvailableVals(BlockListTy *BlockList) {
0354     // Go through the worklist in forward order (i.e., backward through the CFG)
0355     // and check if existing PHIs can be used.  If not, create empty PHIs where
0356     // they are needed.
0357     for (typename BlockListTy::iterator I = BlockList->begin(),
0358            E = BlockList->end(); I != E; ++I) {
0359       BBInfo *Info = *I;
0360       // Check if there needs to be a PHI in BB.
0361       if (Info->DefBB != Info)
0362         continue;
0363 
0364       // Look for singular value.
0365       if (FindSingularVal(Info))
0366         continue;
0367 
0368       // Look for an existing PHI.
0369       FindExistingPHI(Info->BB, BlockList);
0370       if (Info->AvailableVal)
0371         continue;
0372 
0373       ValT PHI = Traits::CreateEmptyPHI(Info->BB, Info->NumPreds, Updater);
0374       Info->AvailableVal = PHI;
0375       (*AvailableVals)[Info->BB] = PHI;
0376     }
0377 
0378     // Now go back through the worklist in reverse order to fill in the
0379     // arguments for any new PHIs added in the forward traversal.
0380     for (typename BlockListTy::reverse_iterator I = BlockList->rbegin(),
0381            E = BlockList->rend(); I != E; ++I) {
0382       BBInfo *Info = *I;
0383 
0384       if (Info->DefBB != Info) {
0385         // Record the available value to speed up subsequent uses of this
0386         // SSAUpdater for the same value.
0387         (*AvailableVals)[Info->BB] = Info->DefBB->AvailableVal;
0388         continue;
0389       }
0390 
0391       // Check if this block contains a newly added PHI.
0392       PhiT *PHI = Traits::ValueIsNewPHI(Info->AvailableVal, Updater);
0393       if (!PHI)
0394         continue;
0395 
0396       // Iterate through the block's predecessors.
0397       for (unsigned p = 0; p != Info->NumPreds; ++p) {
0398         BBInfo *PredInfo = Info->Preds[p];
0399         BlkT *Pred = PredInfo->BB;
0400         // Skip to the nearest preceding definition.
0401         if (PredInfo->DefBB != PredInfo)
0402           PredInfo = PredInfo->DefBB;
0403         Traits::AddPHIOperand(PHI, PredInfo->AvailableVal, Pred);
0404       }
0405 
0406       LLVM_DEBUG(dbgs() << "  Inserted PHI: " << *PHI << "\n");
0407 
0408       // If the client wants to know about all new instructions, tell it.
0409       if (InsertedPHIs) InsertedPHIs->push_back(PHI);
0410     }
0411   }
0412 
0413   /// FindExistingPHI - Look through the PHI nodes in a block to see if any of
0414   /// them match what is needed.
0415   void FindExistingPHI(BlkT *BB, BlockListTy *BlockList) {
0416     SmallVector<BBInfo *, 20> TaggedBlocks;
0417     for (auto &SomePHI : BB->phis()) {
0418       if (CheckIfPHIMatches(&SomePHI, TaggedBlocks)) {
0419         RecordMatchingPHIs(BlockList);
0420         break;
0421       }
0422     }
0423   }
0424 
0425   /// CheckIfPHIMatches - Check if a PHI node matches the placement and values
0426   /// in the BBMap.
0427   bool CheckIfPHIMatches(PhiT *PHI, SmallVectorImpl<BBInfo *> &TaggedBlocks) {
0428     // Match failed: clear all the PHITag values. Only need to clear visited
0429     // blocks.
0430     auto Cleanup = make_scope_exit([&]() {
0431       for (BBInfo *TaggedBlock : TaggedBlocks)
0432         TaggedBlock->PHITag = nullptr;
0433       TaggedBlocks.clear();
0434     });
0435 
0436     SmallVector<PhiT *, 20> WorkList;
0437     WorkList.push_back(PHI);
0438 
0439     // Mark that the block containing this PHI has been visited.
0440     BBInfo *PHIBlock = BBMap[PHI->getParent()];
0441     PHIBlock->PHITag = PHI;
0442     TaggedBlocks.push_back(PHIBlock);
0443 
0444     while (!WorkList.empty()) {
0445       PHI = WorkList.pop_back_val();
0446 
0447       // Iterate through the PHI's incoming values.
0448       for (typename Traits::PHI_iterator I = Traits::PHI_begin(PHI),
0449              E = Traits::PHI_end(PHI); I != E; ++I) {
0450         ValT IncomingVal = I.getIncomingValue();
0451         BBInfo *PredInfo = BBMap[I.getIncomingBlock()];
0452         // Skip to the nearest preceding definition.
0453         if (PredInfo->DefBB != PredInfo)
0454           PredInfo = PredInfo->DefBB;
0455 
0456         // Check if it matches the expected value.
0457         if (PredInfo->AvailableVal) {
0458           if (IncomingVal == PredInfo->AvailableVal)
0459             continue;
0460           return false;
0461         }
0462 
0463         // Check if the value is a PHI in the correct block.
0464         PhiT *IncomingPHIVal = Traits::ValueIsPHI(IncomingVal, Updater);
0465         if (!IncomingPHIVal || IncomingPHIVal->getParent() != PredInfo->BB)
0466           return false;
0467 
0468         // If this block has already been visited, check if this PHI matches.
0469         if (PredInfo->PHITag) {
0470           if (IncomingPHIVal == PredInfo->PHITag)
0471             continue;
0472           return false;
0473         }
0474         PredInfo->PHITag = IncomingPHIVal;
0475         TaggedBlocks.push_back(PredInfo);
0476 
0477         WorkList.push_back(IncomingPHIVal);
0478       }
0479     }
0480     // Match found, keep PHITags.
0481     Cleanup.release();
0482     return true;
0483   }
0484 
0485   /// RecordMatchingPHIs - For each PHI node that matches, record it in both
0486   /// the BBMap and the AvailableVals mapping.
0487   void RecordMatchingPHIs(BlockListTy *BlockList) {
0488     for (typename BlockListTy::iterator I = BlockList->begin(),
0489            E = BlockList->end(); I != E; ++I)
0490       if (PhiT *PHI = (*I)->PHITag) {
0491         BlkT *BB = PHI->getParent();
0492         ValT PHIVal = Traits::GetPHIValue(PHI);
0493         (*AvailableVals)[BB] = PHIVal;
0494         BBMap[BB]->AvailableVal = PHIVal;
0495       }
0496   }
0497 };
0498 
0499 } // end namespace llvm
0500 
0501 #undef DEBUG_TYPE // "ssaupdater"
0502 
0503 #endif // LLVM_TRANSFORMS_UTILS_SSAUPDATERIMPL_H