|
|
|||
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
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|