Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:15

0001 //===- MemorySSAUpdater.h - Memory SSA Updater-------------------*- 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 // \file
0010 // An automatic updater for MemorySSA that handles arbitrary insertion,
0011 // deletion, and moves.  It performs phi insertion where necessary, and
0012 // automatically updates the MemorySSA IR to be correct.
0013 // While updating loads or removing instructions is often easy enough to not
0014 // need this, updating stores should generally not be attemped outside this
0015 // API.
0016 //
0017 // Basic API usage:
0018 // Create the memory access you want for the instruction (this is mainly so
0019 // we know where it is, without having to duplicate the entire set of create
0020 // functions MemorySSA supports).
0021 // Call insertDef or insertUse depending on whether it's a MemoryUse or a
0022 // MemoryDef.
0023 // That's it.
0024 //
0025 // For moving, first, move the instruction itself using the normal SSA
0026 // instruction moving API, then just call moveBefore, moveAfter,or moveTo with
0027 // the right arguments.
0028 //
0029 //===----------------------------------------------------------------------===//
0030 
0031 #ifndef LLVM_ANALYSIS_MEMORYSSAUPDATER_H
0032 #define LLVM_ANALYSIS_MEMORYSSAUPDATER_H
0033 
0034 #include "llvm/ADT/SmallPtrSet.h"
0035 #include "llvm/ADT/SmallSet.h"
0036 #include "llvm/ADT/SmallVector.h"
0037 #include "llvm/Analysis/MemorySSA.h"
0038 #include "llvm/IR/ValueHandle.h"
0039 #include "llvm/IR/ValueMap.h"
0040 #include "llvm/Support/CFGDiff.h"
0041 
0042 namespace llvm {
0043 
0044 class BasicBlock;
0045 class DominatorTree;
0046 class Instruction;
0047 class LoopBlocksRPO;
0048 template <typename T, unsigned int N> class SmallSetVector;
0049 
0050 using ValueToValueMapTy = ValueMap<const Value *, WeakTrackingVH>;
0051 using PhiToDefMap = SmallDenseMap<MemoryPhi *, MemoryAccess *>;
0052 using CFGUpdate = cfg::Update<BasicBlock *>;
0053 
0054 class MemorySSAUpdater {
0055 private:
0056   MemorySSA *MSSA;
0057 
0058   /// We use WeakVH rather than a costly deletion to deal with dangling pointers.
0059   /// MemoryPhis are created eagerly and sometimes get zapped shortly afterwards.
0060   SmallVector<WeakVH, 16> InsertedPHIs;
0061 
0062   SmallPtrSet<BasicBlock *, 8> VisitedBlocks;
0063   SmallSet<AssertingVH<MemoryPhi>, 8> NonOptPhis;
0064 
0065 public:
0066   MemorySSAUpdater(MemorySSA *MSSA) : MSSA(MSSA) {}
0067 
0068   /// Insert a definition into the MemorySSA IR.  RenameUses will rename any use
0069   /// below the new def block (and any inserted phis).  RenameUses should be set
0070   /// to true if the definition may cause new aliases for loads below it.  This
0071   /// is not the case for hoisting or sinking or other forms of code *movement*.
0072   /// It *is* the case for straight code insertion.
0073   /// For example:
0074   /// store a
0075   /// if (foo) { }
0076   /// load a
0077   ///
0078   /// Moving the store into the if block, and calling insertDef, does not
0079   /// require RenameUses.
0080   /// However, changing it to:
0081   /// store a
0082   /// if (foo) { store b }
0083   /// load a
0084   /// Where a mayalias b, *does* require RenameUses be set to true.
0085   void insertDef(MemoryDef *Def, bool RenameUses = false);
0086   void insertUse(MemoryUse *Use, bool RenameUses = false);
0087   /// Update the MemoryPhi in `To` following an edge deletion between `From` and
0088   /// `To`. If `To` becomes unreachable, a call to removeBlocks should be made.
0089   void removeEdge(BasicBlock *From, BasicBlock *To);
0090   /// Update the MemoryPhi in `To` to have a single incoming edge from `From`,
0091   /// following a CFG change that replaced multiple edges (switch) with a direct
0092   /// branch.
0093   void removeDuplicatePhiEdgesBetween(const BasicBlock *From,
0094                                       const BasicBlock *To);
0095   /// Update MemorySSA when inserting a unique backedge block for a loop.
0096   void updatePhisWhenInsertingUniqueBackedgeBlock(BasicBlock *LoopHeader,
0097                                                   BasicBlock *LoopPreheader,
0098                                                   BasicBlock *BackedgeBlock);
0099   /// Update MemorySSA after a loop was cloned, given the blocks in RPO order,
0100   /// the exit blocks and a 1:1 mapping of all blocks and instructions
0101   /// cloned. This involves duplicating all defs and uses in the cloned blocks
0102   /// Updating phi nodes in exit block successors is done separately.
0103   void updateForClonedLoop(const LoopBlocksRPO &LoopBlocks,
0104                            ArrayRef<BasicBlock *> ExitBlocks,
0105                            const ValueToValueMapTy &VM,
0106                            bool IgnoreIncomingWithNoClones = false);
0107   // Block BB was fully or partially cloned into its predecessor P1. Map
0108   // contains the 1:1 mapping of instructions cloned and VM[BB]=P1.
0109   void updateForClonedBlockIntoPred(BasicBlock *BB, BasicBlock *P1,
0110                                     const ValueToValueMapTy &VM);
0111   /// Update phi nodes in exit block successors following cloning. Exit blocks
0112   /// that were not cloned don't have additional predecessors added.
0113   void updateExitBlocksForClonedLoop(ArrayRef<BasicBlock *> ExitBlocks,
0114                                      const ValueToValueMapTy &VMap,
0115                                      DominatorTree &DT);
0116   void updateExitBlocksForClonedLoop(
0117       ArrayRef<BasicBlock *> ExitBlocks,
0118       ArrayRef<std::unique_ptr<ValueToValueMapTy>> VMaps, DominatorTree &DT);
0119 
0120   /// Apply CFG updates, analogous with the DT edge updates. By default, the
0121   /// DT is assumed to be already up to date. If UpdateDTFirst is true, first
0122   /// update the DT with the same updates.
0123   void applyUpdates(ArrayRef<CFGUpdate> Updates, DominatorTree &DT,
0124                     bool UpdateDTFirst = false);
0125   /// Apply CFG insert updates, analogous with the DT edge updates.
0126   void applyInsertUpdates(ArrayRef<CFGUpdate> Updates, DominatorTree &DT);
0127 
0128   void moveBefore(MemoryUseOrDef *What, MemoryUseOrDef *Where);
0129   void moveAfter(MemoryUseOrDef *What, MemoryUseOrDef *Where);
0130   void moveToPlace(MemoryUseOrDef *What, BasicBlock *BB,
0131                    MemorySSA::InsertionPlace Where);
0132   /// `From` block was spliced into `From` and `To`. There is a CFG edge from
0133   /// `From` to `To`. Move all accesses from `From` to `To` starting at
0134   /// instruction `Start`. `To` is newly created BB, so empty of
0135   /// MemorySSA::MemoryAccesses. Edges are already updated, so successors of
0136   /// `To` with MPhi nodes need to update incoming block.
0137   /// |------|        |------|
0138   /// | From |        | From |
0139   /// |      |        |------|
0140   /// |      |           ||
0141   /// |      |   =>      \/
0142   /// |      |        |------|  <- Start
0143   /// |      |        |  To  |
0144   /// |------|        |------|
0145   void moveAllAfterSpliceBlocks(BasicBlock *From, BasicBlock *To,
0146                                 Instruction *Start);
0147   /// `From` block was merged into `To`. There is a CFG edge from `To` to
0148   /// `From`.`To` still branches to `From`, but all instructions were moved and
0149   /// `From` is now an empty block; `From` is about to be deleted. Move all
0150   /// accesses from `From` to `To` starting at instruction `Start`. `To` may
0151   /// have multiple successors, `From` has a single predecessor. `From` may have
0152   /// successors with MPhi nodes, replace their incoming block with `To`.
0153   /// |------|        |------|
0154   /// |  To  |        |  To  |
0155   /// |------|        |      |
0156   ///    ||      =>   |      |
0157   ///    \/           |      |
0158   /// |------|        |      |  <- Start
0159   /// | From |        |      |
0160   /// |------|        |------|
0161   void moveAllAfterMergeBlocks(BasicBlock *From, BasicBlock *To,
0162                                Instruction *Start);
0163   /// A new empty BasicBlock (New) now branches directly to Old. Some of
0164   /// Old's predecessors (Preds) are now branching to New instead of Old.
0165   /// If New is the only predecessor, move Old's Phi, if present, to New.
0166   /// Otherwise, add a new Phi in New with appropriate incoming values, and
0167   /// update the incoming values in Old's Phi node too, if present.
0168   void wireOldPredecessorsToNewImmediatePredecessor(
0169       BasicBlock *Old, BasicBlock *New, ArrayRef<BasicBlock *> Preds,
0170       bool IdenticalEdgesWereMerged = true);
0171   // The below are utility functions. Other than creation of accesses to pass
0172   // to insertDef, and removeAccess to remove accesses, you should generally
0173   // not attempt to update memoryssa yourself. It is very non-trivial to get
0174   // the edge cases right, and the above calls already operate in near-optimal
0175   // time bounds.
0176 
0177   /// Create a MemoryAccess in MemorySSA at a specified point in a block.
0178   ///
0179   /// When used by itself, this method will only insert the new MemoryAccess
0180   /// into the access list, but not make any other changes, such as inserting
0181   /// MemoryPHI nodes, or updating users to point to the new MemoryAccess. You
0182   /// must specify a correct Definition in this case.
0183   ///
0184   /// Usually, this API is instead combined with insertUse() or insertDef(),
0185   /// which will perform all the necessary MSSA updates. If these APIs are used,
0186   /// then nullptr can be used as Definition, as the correct defining access
0187   /// will be automatically determined.
0188   ///
0189   /// Note: If a MemoryAccess already exists for I, this function will make it
0190   /// inaccessible and it *must* have removeMemoryAccess called on it.
0191   MemoryAccess *createMemoryAccessInBB(Instruction *I, MemoryAccess *Definition,
0192                                        const BasicBlock *BB,
0193                                        MemorySSA::InsertionPlace Point,
0194                                        bool CreationMustSucceed = true);
0195 
0196   /// Create a MemoryAccess in MemorySSA before an existing MemoryAccess.
0197   ///
0198   /// See createMemoryAccessInBB() for usage details.
0199   MemoryUseOrDef *createMemoryAccessBefore(Instruction *I,
0200                                            MemoryAccess *Definition,
0201                                            MemoryUseOrDef *InsertPt);
0202   /// Create a MemoryAccess in MemorySSA after an existing MemoryAccess.
0203   ///
0204   /// See createMemoryAccessInBB() for usage details.
0205   MemoryUseOrDef *createMemoryAccessAfter(Instruction *I,
0206                                           MemoryAccess *Definition,
0207                                           MemoryAccess *InsertPt);
0208 
0209   /// Remove a MemoryAccess from MemorySSA, including updating all
0210   /// definitions and uses.
0211   /// This should be called when a memory instruction that has a MemoryAccess
0212   /// associated with it is erased from the program.  For example, if a store or
0213   /// load is simply erased (not replaced), removeMemoryAccess should be called
0214   /// on the MemoryAccess for that store/load.
0215   void removeMemoryAccess(MemoryAccess *, bool OptimizePhis = false);
0216 
0217   /// Remove MemoryAccess for a given instruction, if a MemoryAccess exists.
0218   /// This should be called when an instruction (load/store) is deleted from
0219   /// the program.
0220   void removeMemoryAccess(const Instruction *I, bool OptimizePhis = false) {
0221     if (MemoryAccess *MA = MSSA->getMemoryAccess(I))
0222       removeMemoryAccess(MA, OptimizePhis);
0223   }
0224 
0225   /// Remove all MemoryAcceses in a set of BasicBlocks about to be deleted.
0226   /// Assumption we make here: all uses of deleted defs and phi must either
0227   /// occur in blocks about to be deleted (thus will be deleted as well), or
0228   /// they occur in phis that will simply lose an incoming value.
0229   /// Deleted blocks still have successor info, but their predecessor edges and
0230   /// Phi nodes may already be updated. Instructions in DeadBlocks should be
0231   /// deleted after this call.
0232   void removeBlocks(const SmallSetVector<BasicBlock *, 8> &DeadBlocks);
0233 
0234   /// Instruction I will be changed to an unreachable. Remove all accesses in
0235   /// I's block that follow I (inclusive), and update the Phis in the blocks'
0236   /// successors.
0237   void changeToUnreachable(const Instruction *I);
0238 
0239   /// Get handle on MemorySSA.
0240   MemorySSA* getMemorySSA() const { return MSSA; }
0241 
0242 private:
0243   // Move What before Where in the MemorySSA IR.
0244   template <class WhereType>
0245   void moveTo(MemoryUseOrDef *What, BasicBlock *BB, WhereType Where);
0246   // Move all memory accesses from `From` to `To` starting at `Start`.
0247   // Restrictions apply, see public wrappers of this method.
0248   void moveAllAccesses(BasicBlock *From, BasicBlock *To, Instruction *Start);
0249   MemoryAccess *getPreviousDef(MemoryAccess *);
0250   MemoryAccess *getPreviousDefInBlock(MemoryAccess *);
0251   MemoryAccess *
0252   getPreviousDefFromEnd(BasicBlock *,
0253                         DenseMap<BasicBlock *, TrackingVH<MemoryAccess>> &);
0254   MemoryAccess *
0255   getPreviousDefRecursive(BasicBlock *,
0256                           DenseMap<BasicBlock *, TrackingVH<MemoryAccess>> &);
0257   MemoryAccess *recursePhi(MemoryAccess *Phi);
0258   MemoryAccess *tryRemoveTrivialPhi(MemoryPhi *Phi);
0259   template <class RangeType>
0260   MemoryAccess *tryRemoveTrivialPhi(MemoryPhi *Phi, RangeType &Operands);
0261   void tryRemoveTrivialPhis(ArrayRef<WeakVH> UpdatedPHIs);
0262   void fixupDefs(const SmallVectorImpl<WeakVH> &);
0263   /// Clone all uses and defs from BB to NewBB given a 1:1 map of all
0264   /// instructions and blocks cloned, and a map of MemoryPhi : Definition
0265   /// (MemoryAccess Phi or Def).
0266   ///
0267   /// \param VMap Maps old instructions to cloned instructions and old blocks
0268   ///        to cloned blocks
0269   /// \param MPhiMap, is created in the caller of this private method, and maps
0270   ///        existing MemoryPhis to new definitions that new MemoryAccesses
0271   ///        must point to. These definitions may not necessarily be MemoryPhis
0272   ///        themselves, they may be MemoryDefs. As such, the map is between
0273   ///        MemoryPhis and MemoryAccesses, where the MemoryAccesses may be
0274   ///        MemoryPhis or MemoryDefs and not MemoryUses.
0275   /// \param IsInClonedRegion Determines whether a basic block was cloned.
0276   ///        References to accesses outside the cloned region will not be
0277   ///        remapped.
0278   /// \param CloneWasSimplified If false, the clone was exact. Otherwise,
0279   ///        assume that the clone involved simplifications that may have:
0280   ///        (1) turned a MemoryUse into an instruction that MemorySSA has no
0281   ///        representation for, or (2) turned a MemoryDef into a MemoryUse or
0282   ///        an instruction that MemorySSA has no representation for. No other
0283   ///        cases are supported.
0284   void cloneUsesAndDefs(BasicBlock *BB, BasicBlock *NewBB,
0285                         const ValueToValueMapTy &VMap, PhiToDefMap &MPhiMap,
0286                         function_ref<bool(BasicBlock *)> IsInClonedRegion,
0287                         bool CloneWasSimplified = false);
0288 
0289   template <typename Iter>
0290   void privateUpdateExitBlocksForClonedLoop(ArrayRef<BasicBlock *> ExitBlocks,
0291                                             Iter ValuesBegin, Iter ValuesEnd,
0292                                             DominatorTree &DT);
0293   void applyInsertUpdates(ArrayRef<CFGUpdate>, DominatorTree &DT,
0294                           const GraphDiff<BasicBlock *> *GD);
0295 };
0296 } // end namespace llvm
0297 
0298 #endif // LLVM_ANALYSIS_MEMORYSSAUPDATER_H