blob: 3f4ef0614ca998a384edbfcd4e3f8216f3a94299 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- MemorySSAUpdater.h - Memory SSA Updater-------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// \file
11// \brief An automatic updater for MemorySSA that handles arbitrary insertion,
12// deletion, and moves. It performs phi insertion where necessary, and
13// automatically updates the MemorySSA IR to be correct.
14// While updating loads or removing instructions is often easy enough to not
15// need this, updating stores should generally not be attemped outside this
16// API.
17//
18// Basic API usage:
19// Create the memory access you want for the instruction (this is mainly so
20// we know where it is, without having to duplicate the entire set of create
21// functions MemorySSA supports).
22// Call insertDef or insertUse depending on whether it's a MemoryUse or a
23// MemoryDef.
24// That's it.
25//
26// For moving, first, move the instruction itself using the normal SSA
27// instruction moving API, then just call moveBefore, moveAfter,or moveTo with
28// the right arguments.
29//
30//===----------------------------------------------------------------------===//
31
32#ifndef LLVM_ANALYSIS_MEMORYSSAUPDATER_H
33#define LLVM_ANALYSIS_MEMORYSSAUPDATER_H
34
35#include "llvm/ADT/SmallPtrSet.h"
36#include "llvm/ADT/SmallVector.h"
37#include "llvm/Analysis/MemorySSA.h"
38#include "llvm/IR/BasicBlock.h"
39#include "llvm/IR/Dominators.h"
40#include "llvm/IR/Module.h"
41#include "llvm/IR/OperandTraits.h"
42#include "llvm/IR/Type.h"
43#include "llvm/IR/Use.h"
44#include "llvm/IR/User.h"
45#include "llvm/IR/Value.h"
46#include "llvm/IR/ValueHandle.h"
47#include "llvm/Pass.h"
48#include "llvm/Support/Casting.h"
49#include "llvm/Support/ErrorHandling.h"
50
51namespace llvm {
52
53class Function;
54class Instruction;
55class MemoryAccess;
56class LLVMContext;
57class raw_ostream;
58
59class MemorySSAUpdater {
60private:
61 MemorySSA *MSSA;
62 SmallVector<MemoryPhi *, 8> InsertedPHIs;
63 SmallPtrSet<BasicBlock *, 8> VisitedBlocks;
64
65public:
66 MemorySSAUpdater(MemorySSA *MSSA) : MSSA(MSSA) {}
67 /// Insert a definition into the MemorySSA IR. RenameUses will rename any use
68 /// below the new def block (and any inserted phis). RenameUses should be set
69 /// to true if the definition may cause new aliases for loads below it. This
70 /// is not the case for hoisting or sinking or other forms of code *movement*.
71 /// It *is* the case for straight code insertion.
72 /// For example:
73 /// store a
74 /// if (foo) { }
75 /// load a
76 ///
77 /// Moving the store into the if block, and calling insertDef, does not
78 /// require RenameUses.
79 /// However, changing it to:
80 /// store a
81 /// if (foo) { store b }
82 /// load a
83 /// Where a mayalias b, *does* require RenameUses be set to true.
84 void insertDef(MemoryDef *Def, bool RenameUses = false);
85 void insertUse(MemoryUse *Use);
86 void moveBefore(MemoryUseOrDef *What, MemoryUseOrDef *Where);
87 void moveAfter(MemoryUseOrDef *What, MemoryUseOrDef *Where);
88 void moveToPlace(MemoryUseOrDef *What, BasicBlock *BB,
89 MemorySSA::InsertionPlace Where);
90
91 // The below are utility functions. Other than creation of accesses to pass
92 // to insertDef, and removeAccess to remove accesses, you should generally
93 // not attempt to update memoryssa yourself. It is very non-trivial to get
94 // the edge cases right, and the above calls already operate in near-optimal
95 // time bounds.
96
97 /// \brief Create a MemoryAccess in MemorySSA at a specified point in a block,
98 /// with a specified clobbering definition.
99 ///
100 /// Returns the new MemoryAccess.
101 /// This should be called when a memory instruction is created that is being
102 /// used to replace an existing memory instruction. It will *not* create PHI
103 /// nodes, or verify the clobbering definition. The insertion place is used
104 /// solely to determine where in the memoryssa access lists the instruction
105 /// will be placed. The caller is expected to keep ordering the same as
106 /// instructions.
107 /// It will return the new MemoryAccess.
108 /// Note: If a MemoryAccess already exists for I, this function will make it
109 /// inaccessible and it *must* have removeMemoryAccess called on it.
110 MemoryAccess *createMemoryAccessInBB(Instruction *I, MemoryAccess *Definition,
111 const BasicBlock *BB,
112 MemorySSA::InsertionPlace Point);
113
114 /// \brief Create a MemoryAccess in MemorySSA before or after an existing
115 /// MemoryAccess.
116 ///
117 /// Returns the new MemoryAccess.
118 /// This should be called when a memory instruction is created that is being
119 /// used to replace an existing memory instruction. It will *not* create PHI
120 /// nodes, or verify the clobbering definition.
121 ///
122 /// Note: If a MemoryAccess already exists for I, this function will make it
123 /// inaccessible and it *must* have removeMemoryAccess called on it.
124 MemoryUseOrDef *createMemoryAccessBefore(Instruction *I,
125 MemoryAccess *Definition,
126 MemoryUseOrDef *InsertPt);
127 MemoryUseOrDef *createMemoryAccessAfter(Instruction *I,
128 MemoryAccess *Definition,
129 MemoryAccess *InsertPt);
130
131 /// \brief Remove a MemoryAccess from MemorySSA, including updating all
132 /// definitions and uses.
133 /// This should be called when a memory instruction that has a MemoryAccess
134 /// associated with it is erased from the program. For example, if a store or
135 /// load is simply erased (not replaced), removeMemoryAccess should be called
136 /// on the MemoryAccess for that store/load.
137 void removeMemoryAccess(MemoryAccess *);
138
139private:
140 // Move What before Where in the MemorySSA IR.
141 template <class WhereType>
142 void moveTo(MemoryUseOrDef *What, BasicBlock *BB, WhereType Where);
143 MemoryAccess *getPreviousDef(MemoryAccess *);
144 MemoryAccess *getPreviousDefInBlock(MemoryAccess *);
145 MemoryAccess *
146 getPreviousDefFromEnd(BasicBlock *,
147 DenseMap<BasicBlock *, TrackingVH<MemoryAccess>> &);
148 MemoryAccess *
149 getPreviousDefRecursive(BasicBlock *,
150 DenseMap<BasicBlock *, TrackingVH<MemoryAccess>> &);
151 MemoryAccess *recursePhi(MemoryAccess *Phi);
152 template <class RangeType>
153 MemoryAccess *tryRemoveTrivialPhi(MemoryPhi *Phi, RangeType &Operands);
154 void fixupDefs(const SmallVectorImpl<MemoryAccess *> &);
155};
156} // end namespace llvm
157
158#endif // LLVM_ANALYSIS_MEMORYSSAUPDATER_H