LLVM 22.0.0git
MemorySSAUpdater.h
Go to the documentation of this file.
1//===- MemorySSAUpdater.h - Memory SSA Updater-------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// \file
10// An automatic updater for MemorySSA that handles arbitrary insertion,
11// deletion, and moves. It performs phi insertion where necessary, and
12// automatically updates the MemorySSA IR to be correct.
13// While updating loads or removing instructions is often easy enough to not
14// need this, updating stores should generally not be attemped outside this
15// API.
16//
17// Basic API usage:
18// Create the memory access you want for the instruction (this is mainly so
19// we know where it is, without having to duplicate the entire set of create
20// functions MemorySSA supports).
21// Call insertDef or insertUse depending on whether it's a MemoryUse or a
22// MemoryDef.
23// That's it.
24//
25// For moving, first, move the instruction itself using the normal SSA
26// instruction moving API, then just call moveBefore, moveAfter,or moveTo with
27// the right arguments.
28//
29//===----------------------------------------------------------------------===//
30
31#ifndef LLVM_ANALYSIS_MEMORYSSAUPDATER_H
32#define LLVM_ANALYSIS_MEMORYSSAUPDATER_H
33
35#include "llvm/ADT/SmallSet.h"
38#include "llvm/IR/ValueHandle.h"
39#include "llvm/IR/ValueMap.h"
42
43namespace llvm {
44
45class BasicBlock;
46class DominatorTree;
47class Instruction;
48class LoopBlocksRPO;
49template <typename T, unsigned int N> class SmallSetVector;
50
54
56private:
57 MemorySSA *MSSA;
58
59 /// We use WeakVH rather than a costly deletion to deal with dangling pointers.
60 /// MemoryPhis are created eagerly and sometimes get zapped shortly afterwards.
61 SmallVector<WeakVH, 16> InsertedPHIs;
62
63 SmallPtrSet<BasicBlock *, 8> VisitedBlocks;
65
66public:
67 MemorySSAUpdater(MemorySSA *MSSA) : MSSA(MSSA) {}
68
69 /// Insert a definition into the MemorySSA IR. RenameUses will rename any use
70 /// below the new def block (and any inserted phis). RenameUses should be set
71 /// to true if the definition may cause new aliases for loads below it. This
72 /// is not the case for hoisting or sinking or other forms of code *movement*.
73 /// It *is* the case for straight code insertion.
74 /// For example:
75 /// store a
76 /// if (foo) { }
77 /// load a
78 ///
79 /// Moving the store into the if block, and calling insertDef, does not
80 /// require RenameUses.
81 /// However, changing it to:
82 /// store a
83 /// if (foo) { store b }
84 /// load a
85 /// Where a mayalias b, *does* require RenameUses be set to true.
86 LLVM_ABI void insertDef(MemoryDef *Def, bool RenameUses = false);
87 LLVM_ABI void insertUse(MemoryUse *Use, bool RenameUses = false);
88 /// Update the MemoryPhi in `To` following an edge deletion between `From` and
89 /// `To`. If `To` becomes unreachable, a call to removeBlocks should be made.
91 /// Update the MemoryPhi in `To` to have a single incoming edge from `From`,
92 /// following a CFG change that replaced multiple edges (switch) with a direct
93 /// branch.
95 const BasicBlock *To);
96 /// Update MemorySSA when inserting a unique backedge block for a loop.
97 LLVM_ABI void
99 BasicBlock *LoopPreheader,
100 BasicBlock *BackedgeBlock);
101 /// Update MemorySSA after a loop was cloned, given the blocks in RPO order,
102 /// the exit blocks and a 1:1 mapping of all blocks and instructions
103 /// cloned. This involves duplicating all defs and uses in the cloned blocks
104 /// Updating phi nodes in exit block successors is done separately.
105 LLVM_ABI void updateForClonedLoop(const LoopBlocksRPO &LoopBlocks,
106 ArrayRef<BasicBlock *> ExitBlocks,
107 const ValueToValueMapTy &VM,
108 bool IgnoreIncomingWithNoClones = false);
109 // Block BB was fully or partially cloned into its predecessor P1. Map
110 // contains the 1:1 mapping of instructions cloned and VM[BB]=P1.
112 const ValueToValueMapTy &VM);
113 /// Update phi nodes in exit block successors following cloning. Exit blocks
114 /// that were not cloned don't have additional predecessors added.
116 const ValueToValueMapTy &VMap,
117 DominatorTree &DT);
119 ArrayRef<BasicBlock *> ExitBlocks,
120 ArrayRef<std::unique_ptr<ValueToValueMapTy>> VMaps, DominatorTree &DT);
121
122 /// Apply CFG updates, analogous with the DT edge updates. By default, the
123 /// DT is assumed to be already up to date. If UpdateDTFirst is true, first
124 /// update the DT with the same updates.
126 bool UpdateDTFirst = false);
127 /// Apply CFG insert updates, analogous with the DT edge updates.
129 DominatorTree &DT);
130
135 /// `From` block was spliced into `From` and `To`. There is a CFG edge from
136 /// `From` to `To`. Move all accesses from `From` to `To` starting at
137 /// instruction `Start`. `To` is newly created BB, so empty of
138 /// MemorySSA::MemoryAccesses. Edges are already updated, so successors of
139 /// `To` with MPhi nodes need to update incoming block.
140 /// |------| |------|
141 /// | From | | From |
142 /// | | |------|
143 /// | | ||
144 /// | | => \/
145 /// | | |------| <- Start
146 /// | | | To |
147 /// |------| |------|
149 Instruction *Start);
150 /// `From` block was merged into `To`. There is a CFG edge from `To` to
151 /// `From`.`To` still branches to `From`, but all instructions were moved and
152 /// `From` is now an empty block; `From` is about to be deleted. Move all
153 /// accesses from `From` to `To` starting at instruction `Start`. `To` may
154 /// have multiple successors, `From` has a single predecessor. `From` may have
155 /// successors with MPhi nodes, replace their incoming block with `To`.
156 /// |------| |------|
157 /// | To | | To |
158 /// |------| | |
159 /// || => | |
160 /// \/ | |
161 /// |------| | | <- Start
162 /// | From | | |
163 /// |------| |------|
165 Instruction *Start);
166 /// A new empty BasicBlock (New) now branches directly to Old. Some of
167 /// Old's predecessors (Preds) are now branching to New instead of Old.
168 /// If New is the only predecessor, move Old's Phi, if present, to New.
169 /// Otherwise, add a new Phi in New with appropriate incoming values, and
170 /// update the incoming values in Old's Phi node too, if present.
173 bool IdenticalEdgesWereMerged = true);
174 // The below are utility functions. Other than creation of accesses to pass
175 // to insertDef, and removeAccess to remove accesses, you should generally
176 // not attempt to update memoryssa yourself. It is very non-trivial to get
177 // the edge cases right, and the above calls already operate in near-optimal
178 // time bounds.
179
180 /// Create a MemoryAccess in MemorySSA at a specified point in a block.
181 ///
182 /// When used by itself, this method will only insert the new MemoryAccess
183 /// into the access list, but not make any other changes, such as inserting
184 /// MemoryPHI nodes, or updating users to point to the new MemoryAccess. You
185 /// must specify a correct Definition in this case.
186 ///
187 /// Usually, this API is instead combined with insertUse() or insertDef(),
188 /// which will perform all the necessary MSSA updates. If these APIs are used,
189 /// then nullptr can be used as Definition, as the correct defining access
190 /// will be automatically determined.
191 ///
192 /// Note: If a MemoryAccess already exists for I, this function will make it
193 /// inaccessible and it *must* have removeMemoryAccess called on it.
196 const BasicBlock *BB, MemorySSA::InsertionPlace Point,
197 bool CreationMustSucceed = true);
198
199 /// Create a MemoryAccess in MemorySSA before an existing MemoryAccess.
200 ///
201 /// See createMemoryAccessInBB() for usage details.
203 MemoryAccess *Definition,
204 MemoryUseOrDef *InsertPt);
205 /// Create a MemoryAccess in MemorySSA after an existing MemoryAccess.
206 ///
207 /// See createMemoryAccessInBB() for usage details.
209 MemoryAccess *Definition,
210 MemoryAccess *InsertPt);
211
212 /// Remove a MemoryAccess from MemorySSA, including updating all
213 /// definitions and uses.
214 /// This should be called when a memory instruction that has a MemoryAccess
215 /// associated with it is erased from the program. For example, if a store or
216 /// load is simply erased (not replaced), removeMemoryAccess should be called
217 /// on the MemoryAccess for that store/load.
218 LLVM_ABI void removeMemoryAccess(MemoryAccess *, bool OptimizePhis = false);
219
220 /// Remove MemoryAccess for a given instruction, if a MemoryAccess exists.
221 /// This should be called when an instruction (load/store) is deleted from
222 /// the program.
223 void removeMemoryAccess(const Instruction *I, bool OptimizePhis = false) {
224 if (MemoryAccess *MA = MSSA->getMemoryAccess(I))
225 removeMemoryAccess(MA, OptimizePhis);
226 }
227
228 /// Remove all MemoryAcceses in a set of BasicBlocks about to be deleted.
229 /// Assumption we make here: all uses of deleted defs and phi must either
230 /// occur in blocks about to be deleted (thus will be deleted as well), or
231 /// they occur in phis that will simply lose an incoming value.
232 /// Deleted blocks still have successor info, but their predecessor edges and
233 /// Phi nodes may already be updated. Instructions in DeadBlocks should be
234 /// deleted after this call.
236
237 /// Instruction I will be changed to an unreachable. Remove all accesses in
238 /// I's block that follow I (inclusive), and update the Phis in the blocks'
239 /// successors.
241
242 /// Get handle on MemorySSA.
243 MemorySSA* getMemorySSA() const { return MSSA; }
244
245private:
246 // Move What before Where in the MemorySSA IR.
247 template <class WhereType>
248 void moveTo(MemoryUseOrDef *What, BasicBlock *BB, WhereType Where);
249 // Move all memory accesses from `From` to `To` starting at `Start`.
250 // Restrictions apply, see public wrappers of this method.
251 void moveAllAccesses(BasicBlock *From, BasicBlock *To, Instruction *Start);
252 MemoryAccess *getPreviousDef(MemoryAccess *);
253 MemoryAccess *getPreviousDefInBlock(MemoryAccess *);
255 getPreviousDefFromEnd(BasicBlock *,
258 getPreviousDefRecursive(BasicBlock *,
260 MemoryAccess *recursePhi(MemoryAccess *Phi);
261 MemoryAccess *tryRemoveTrivialPhi(MemoryPhi *Phi);
262 template <class RangeType>
263 MemoryAccess *tryRemoveTrivialPhi(MemoryPhi *Phi, RangeType &Operands);
264 void tryRemoveTrivialPhis(ArrayRef<WeakVH> UpdatedPHIs);
265 void fixupDefs(const SmallVectorImpl<WeakVH> &);
266 /// Clone all uses and defs from BB to NewBB given a 1:1 map of all
267 /// instructions and blocks cloned, and a map of MemoryPhi : Definition
268 /// (MemoryAccess Phi or Def).
269 ///
270 /// \param VMap Maps old instructions to cloned instructions and old blocks
271 /// to cloned blocks
272 /// \param MPhiMap, is created in the caller of this private method, and maps
273 /// existing MemoryPhis to new definitions that new MemoryAccesses
274 /// must point to. These definitions may not necessarily be MemoryPhis
275 /// themselves, they may be MemoryDefs. As such, the map is between
276 /// MemoryPhis and MemoryAccesses, where the MemoryAccesses may be
277 /// MemoryPhis or MemoryDefs and not MemoryUses.
278 /// \param IsInClonedRegion Determines whether a basic block was cloned.
279 /// References to accesses outside the cloned region will not be
280 /// remapped.
281 /// \param CloneWasSimplified If false, the clone was exact. Otherwise,
282 /// assume that the clone involved simplifications that may have:
283 /// (1) turned a MemoryUse into an instruction that MemorySSA has no
284 /// representation for, or (2) turned a MemoryDef into a MemoryUse or
285 /// an instruction that MemorySSA has no representation for. No other
286 /// cases are supported.
287 void cloneUsesAndDefs(BasicBlock *BB, BasicBlock *NewBB,
288 const ValueToValueMapTy &VMap, PhiToDefMap &MPhiMap,
289 function_ref<bool(BasicBlock *)> IsInClonedRegion,
290 bool CloneWasSimplified = false);
291
292 template <typename Iter>
293 void privateUpdateExitBlocksForClonedLoop(ArrayRef<BasicBlock *> ExitBlocks,
294 Iter ValuesBegin, Iter ValuesEnd,
295 DominatorTree &DT);
297 const GraphDiff<BasicBlock *> *GD);
298};
299} // end namespace llvm
300
301#endif // LLVM_ANALYSIS_MEMORYSSAUPDATER_H
BlockVerifier::State From
#define LLVM_ABI
Definition: Compiler.h:213
#define I(x, y, z)
Definition: MD5.cpp:58
mir Rename Register Operands
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
LLVM Basic Block Representation.
Definition: BasicBlock.h:62
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition: Dominators.h:165
Wrapper class to LoopBlocksDFS that provides a standard begin()/end() interface for the DFS reverse p...
Definition: LoopIterator.h:172
Represents a read-write access to memory, whether it is a must-alias, or a may-alias.
Definition: MemorySSA.h:371
Represents phi nodes for memory accesses.
Definition: MemorySSA.h:479
MemorySSA * getMemorySSA() const
Get handle on MemorySSA.
LLVM_ABI MemoryUseOrDef * createMemoryAccessBefore(Instruction *I, MemoryAccess *Definition, MemoryUseOrDef *InsertPt)
Create a MemoryAccess in MemorySSA before an existing MemoryAccess.
LLVM_ABI void insertDef(MemoryDef *Def, bool RenameUses=false)
Insert a definition into the MemorySSA IR.
LLVM_ABI void moveAfter(MemoryUseOrDef *What, MemoryUseOrDef *Where)
LLVM_ABI void removeEdge(BasicBlock *From, BasicBlock *To)
Update the MemoryPhi in To following an edge deletion between From and To.
LLVM_ABI void updateForClonedLoop(const LoopBlocksRPO &LoopBlocks, ArrayRef< BasicBlock * > ExitBlocks, const ValueToValueMapTy &VM, bool IgnoreIncomingWithNoClones=false)
Update MemorySSA after a loop was cloned, given the blocks in RPO order, the exit blocks and a 1:1 ma...
LLVM_ABI void changeToUnreachable(const Instruction *I)
Instruction I will be changed to an unreachable.
LLVM_ABI void removeDuplicatePhiEdgesBetween(const BasicBlock *From, const BasicBlock *To)
Update the MemoryPhi in To to have a single incoming edge from From, following a CFG change that repl...
LLVM_ABI void updatePhisWhenInsertingUniqueBackedgeBlock(BasicBlock *LoopHeader, BasicBlock *LoopPreheader, BasicBlock *BackedgeBlock)
Update MemorySSA when inserting a unique backedge block for a loop.
LLVM_ABI void insertUse(MemoryUse *Use, bool RenameUses=false)
MemorySSAUpdater(MemorySSA *MSSA)
LLVM_ABI void removeBlocks(const SmallSetVector< BasicBlock *, 8 > &DeadBlocks)
Remove all MemoryAcceses in a set of BasicBlocks about to be deleted.
LLVM_ABI void moveAllAfterSpliceBlocks(BasicBlock *From, BasicBlock *To, Instruction *Start)
From block was spliced into From and To.
LLVM_ABI MemoryAccess * createMemoryAccessInBB(Instruction *I, MemoryAccess *Definition, const BasicBlock *BB, MemorySSA::InsertionPlace Point, bool CreationMustSucceed=true)
Create a MemoryAccess in MemorySSA at a specified point in a block.
LLVM_ABI void removeMemoryAccess(MemoryAccess *, bool OptimizePhis=false)
Remove a MemoryAccess from MemorySSA, including updating all definitions and uses.
LLVM_ABI void applyInsertUpdates(ArrayRef< CFGUpdate > Updates, DominatorTree &DT)
Apply CFG insert updates, analogous with the DT edge updates.
LLVM_ABI MemoryUseOrDef * createMemoryAccessAfter(Instruction *I, MemoryAccess *Definition, MemoryAccess *InsertPt)
Create a MemoryAccess in MemorySSA after an existing MemoryAccess.
LLVM_ABI void updateForClonedBlockIntoPred(BasicBlock *BB, BasicBlock *P1, const ValueToValueMapTy &VM)
LLVM_ABI void applyUpdates(ArrayRef< CFGUpdate > Updates, DominatorTree &DT, bool UpdateDTFirst=false)
Apply CFG updates, analogous with the DT edge updates.
LLVM_ABI void moveAllAfterMergeBlocks(BasicBlock *From, BasicBlock *To, Instruction *Start)
From block was merged into To.
LLVM_ABI void moveToPlace(MemoryUseOrDef *What, BasicBlock *BB, MemorySSA::InsertionPlace Where)
LLVM_ABI void wireOldPredecessorsToNewImmediatePredecessor(BasicBlock *Old, BasicBlock *New, ArrayRef< BasicBlock * > Preds, bool IdenticalEdgesWereMerged=true)
A new empty BasicBlock (New) now branches directly to Old.
LLVM_ABI void updateExitBlocksForClonedLoop(ArrayRef< BasicBlock * > ExitBlocks, const ValueToValueMapTy &VMap, DominatorTree &DT)
Update phi nodes in exit block successors following cloning.
void removeMemoryAccess(const Instruction *I, bool OptimizePhis=false)
Remove MemoryAccess for a given instruction, if a MemoryAccess exists.
LLVM_ABI void moveBefore(MemoryUseOrDef *What, MemoryUseOrDef *Where)
Encapsulates MemorySSA, including all data associated with memory accesses.
Definition: MemorySSA.h:702
InsertionPlace
Used in various insertion functions to specify whether we are talking about the beginning or end of a...
Definition: MemorySSA.h:793
MemoryUseOrDef * getMemoryAccess(const Instruction *I) const
Given a memory Mod/Ref'ing instruction, get the MemorySSA access associated with it.
Definition: MemorySSA.h:720
Class that has the common methods + fields of memory uses/defs.
Definition: MemorySSA.h:250
Represents read-only accesses to memory.
Definition: MemorySSA.h:310
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:541
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:356
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:134
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
Value handle that tracks a Value across RAUW.
Definition: ValueHandle.h:332
A Use represents the edge between a Value definition and its users.
Definition: Use.h:35
An efficient, type-erasing, non-owning reference to a callable.
@ BasicBlock
Various leaf nodes.
Definition: ISDOpcodes.h:81
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18