llvm.org GIT mirror llvm / 6058aba
[Docs] Add initial MemorySSA documentation. Patch partially by Danny. Differential Revision: https://reviews.llvm.org/D23535 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278875 91177308-0d34-0410-b5e6-96231b3b80d8 George Burgess IV 3 years ago
3 changed file(s) with 368 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
701701 Memory Dependence Analysis
702702 ==========================
703703
704 .. note::
705
706 We are currently in the process of migrating things from
707 ``MemoryDependenceAnalysis`` to :doc:`MemorySSA`. Please try to use
708 that instead.
709
704710 If you're just looking to be a client of alias analysis information, consider
705711 using the Memory Dependence Analysis interface instead. MemDep is a lazy,
706712 caching layer on top of alias analysis that is able to answer the question of
0 =========
1 MemorySSA
2 =========
3
4 .. contents::
5 :local:
6
7 Introduction
8 ============
9
10 ``MemorySSA`` is an analysis that allows us to cheaply reason about the
11 interactions between various memory operations. Its goal is to replace
12 ``MemoryDependenceAnalysis`` for most (if not all) use-cases. This is because,
13 unless you're very careful, use of ``MemoryDependenceAnalysis`` can easily
14 result in quadratic-time algorithms in LLVM. Additionally, ``MemorySSA`` doesn't
15 have as many arbitrary limits as ``MemoryDependenceAnalysis``, so you should get
16 better results, too.
17
18 At a high level, one of the goals of ``MemorySSA`` is to provide an SSA based
19 form for memory, complete with def-use and use-def chains, which
20 enables users to quickly find may-def and may-uses of memory operations.
21 It can also be thought of as a way to cheaply give versions to the complete
22 state of heap memory, and associate memory operations with those versions.
23
24 This document goes over how ``MemorySSA`` is structured, and some basic
25 intuition on how ``MemorySSA`` works.
26
27 A paper on MemorySSA (with notes about how it's implemented in GCC) `can be
28 found here `_. Though, it's
29 relatively out-of-date; the paper references multiple heap partitions, but GCC
30 eventually swapped to just using one, like we now have in LLVM. Like
31 GCC's, LLVM's MemorySSA is intraprocedural.
32
33
34 MemorySSA Structure
35 ===================
36
37 MemorySSA is a virtual IR. After it's built, ``MemorySSA`` will contain a
38 structure that maps ``Instruction`` s to ``MemoryAccess`` es, which are
39 ``MemorySSA``'s parallel to LLVM ``Instruction`` s.
40
41 Each ``MemoryAccess`` can be one of three types:
42
43 - ``MemoryPhi``
44 - ``MemoryUse``
45 - ``MemoryDef``
46
47 ``MemoryPhi`` s are ``PhiNode`` , but for memory operations. If at any
48 point we have two (or more) ``MemoryDef`` s that could flow into a
49 ``BasicBlock``, the block's top ``MemoryAccess`` will be a
50 ``MemoryPhi``. As in LLVM IR, ``MemoryPhi`` s don't correspond to any
51 concrete operation. As such, you can't look up a ``MemoryPhi`` with an
52 ``Instruction`` (though we do allow you to do so with a
53 ``BasicBlock``).
54
55 Note also that in SSA, Phi nodes merge must-reach definitions (that
56 is, definite new versions of variables). In MemorySSA, PHI nodes merge
57 may-reach definitions (that is, until disambiguated, the versions that
58 reach a phi node may or may not clobber a given variable)
59
60 ``MemoryUse`` s are operations which use but don't modify memory. An example of
61 a ``MemoryUse`` is a ``load``, or a ``readonly`` function call.
62
63 ``MemoryDef`` s are operations which may either modify memory, or which
64 otherwise clobber memory in unquantifiable ways. Examples of ``MemoryDef`` s
65 include ``store`` s, function calls, ``load`` s with ``acquire`` (or higher)
66 ordering, volatile operations, memory fences, etc.
67
68 Every function that exists has a special ``MemoryDef`` called ``liveOnEntry``.
69 It dominates every ``MemoryAccess`` in the function that ``MemorySSA`` is being
70 run on, and implies that we've hit the top of the function. It's the only
71 ``MemoryDef`` that maps to no ``Instruction`` in LLVM IR. Use of
72 ``liveOnEntry`` implies that the memory being used is either undefined or
73 defined before the function begins.
74
75 An example of all of this overlayed on LLVM IR (obtained by running ``opt
76 -passes='print' -disable-output`` on an ``.ll`` file) is below. When
77 viewing this example, it may be helpful to view it in terms of clobbers. The
78 operands of a given ``MemoryAccess`` are all (potential) clobbers of said
79 MemoryAccess, and the value produced by a ``MemoryAccess`` can act as a clobber
80 for other ``MemoryAccess`` es. Another useful way of looking at it is in
81 terms of heap versions. In that view, operands of of a given
82 ``MemoryAccess`` are the version of the heap before the operation, and
83 if the access produces a value, the value is the new version of the heap
84 after the operation.
85
86 .. code-block:: llvm
87
88 define void @foo() {
89 entry:
90 %p1 = alloca i8
91 %p2 = alloca i8
92 %p3 = alloca i8
93 ; 1 = MemoryDef(liveOnEntry)
94 store i8 0, i8* %p3
95 br label %while.cond
96
97 while.cond:
98 ; 6 = MemoryPhi({%0,1},{if.end,4})
99 br i1 undef, label %if.then, label %if.else
100
101 if.then:
102 ; 2 = MemoryDef(6)
103 store i8 0, i8* %p1
104 br label %if.end
105
106 if.else:
107 ; 3 = MemoryDef(6)
108 store i8 1, i8* %p2
109 br label %if.end
110
111 if.end:
112 ; 5 = MemoryPhi({if.then,2},{if.then,3})
113 ; MemoryUse(5)
114 %1 = load i8, i8* %p1
115 ; 4 = MemoryDef(5)
116 store i8 2, i8* %p2
117 ; MemoryUse(1)
118 %2 = load i8, i8* %p3
119 br label %while.cond
120 }
121
122 The ``MemorySSA`` IR is located comments that precede the instructions they map
123 to (if such an instruction exists). For example, ``1 = MemoryDef(liveOnEntry)``
124 is a ``MemoryAccess`` (specifically, a ``MemoryDef``), and it describes the LLVM
125 instruction ``store i8 0, i8* %p3``. Other places in ``MemorySSA`` refer to this
126 particular ``MemoryDef`` as ``1`` (much like how one can refer to ``load i8, i8*
127 %p1`` in LLVM with ``%1``). Again, ``MemoryPhi`` s don't correspond to any LLVM
128 Instruction, so the line directly below a ``MemoryPhi`` isn't special.
129
130 Going from the top down:
131
132 - ``6 = MemoryPhi({%0,1},{if.end,4})`` notes that, when entering ``while.cond``,
133 the reaching definition for it is either ``1`` or ``4``. This ``MemoryPhi`` is
134 referred to in the textual IR by the number ``6``.
135 - ``2 = MemoryDef(6)`` notes that ``store i8 0, i8* %p1`` is a definition,
136 and its reaching definition before it is ``6``, or the ``MemoryPhi`` after
137 ``while.cond``.
138 - ``3 = MemoryDef(6)`` notes that ``store i8 0, i8* %p2`` is a definition; its
139 reaching definition is also ``6``.
140 - ``5 = MemoryPhi({if.then,2},{if.then,3})`` notes that the clobber before
141 this block could either be ``2`` or ``3``.
142 - ``MemoryUse(5)`` notes that ``load i8, i8* %p1`` is a use of memory, and that
143 it's clobbered by ``5``.
144 - ``4 = MemoryDef(5)`` notes that ``store i8 2, i8* %p2`` is a definition; it's
145 reaching definition is ``5``.
146 - ``MemoryUse(1)`` notes that ``load i8, i8* %p3`` is just a user of memory,
147 and the last thing that could clobber this use is above ``while.cond`` (e.g.
148 the store to ``%p3``). In heap versioning parlance, it really
149 only depends on the heap version 1, and is unaffected by the new
150 heap versions generated since then.
151
152 As an aside, ``MemoryAccess`` is a ``Value`` mostly for convenience; it's not
153 meant to interact with LLVM IR.
154
155 Design of MemorySSA
156 ===================
157
158 ``MemorySSA`` is an analysis that can be built for any arbitrary function. When
159 it's built, it does a pass over the function's IR in order to build up its
160 mapping of ``MemoryAccess`` es. You can then query ``MemorySSA`` for things like
161 the dominance relation between ``MemoryAccess`` es, and get the ``MemoryAccess``
162 for any given ``Instruction`` .
163
164 When ``MemorySSA`` is done building, it also hands you a ``MemorySSAWalker``
165 that you can use (see below).
166
167
168 The walker
169 ----------
170
171 A structure that helps ``MemorySSA`` do its job is the ``MemorySSAWalker``, or
172 the walker, for short. The goal of the walker is to provide answers to clobber
173 queries beyond what's represented directly by ``MemoryAccess`` es. For example,
174 given:
175
176 .. code-block:: llvm
177
178 define void @foo() {
179 %a = alloca i8
180 %b = alloca i8
181
182 ; 1 = MemoryDef(liveOnEntry)
183 store i8 0, i8* %a
184 ; 2 = MemoryDef(1)
185 store i8 0, i8* %b
186 }
187
188 The store to ``%a`` is clearly not a clobber for the store to ``%b``. It would
189 be the walker's goal to figure this out, and return ``liveOnEntry`` when queried
190 for the clobber of ``MemoryAccess`` ``2``.
191
192 By default, ``MemorySSA`` provides a walker that can optimize ``MemoryDef`` s
193 and ``MemoryUse`` s by consulting alias analysis. Walkers were built to be
194 flexible, though, so it's entirely reasonable (and expected) to create more
195 specialized walkers (e.g. one that queries ``GlobalsAA``).
196
197
198 Locating clobbers yourself
199 ^^^^^^^^^^^^^^^^^^^^^^^^^^
200
201 If you choose to make your own walker, you can find the clobber for a
202 ``MemoryAccess`` by walking every ``MemoryDef`` that dominates said
203 ``MemoryAccess``. The structure of ``MemoryDef`` s makes this relatively simple;
204 they ultimately form a linked list of every clobber that dominates the
205 ``MemoryAccess`` that you're trying to optimize. In other words, the
206 ``definingAccess`` of a ``MemoryDef`` is always the nearest dominating
207 ``MemoryDef`` or ``MemoryPhi`` of said ``MemoryDef``.
208
209
210 Use optimization
211 ----------------
212
213 ``MemorySSA`` will optimize some ``MemoryAccess`` es at build-time.
214 Specifically, we optimize the operand of every ``MemoryUse`` s to point to the
215 actual clobber of said ``MemoryUse``. This can be seen in the above example; the
216 second ``MemoryUse`` in ``if.end`` has an operand of ``1``, which is a
217 ``MemoryDef`` from the entry block. This is done to make walking,
218 value numbering, etc, faster and easier.
219 It is not possible to optimize ``MemoryDef`` in the same way, as we
220 restrict ``MemorySSA`` to one heap variable and, thus, one Phi node
221 per block.
222
223
224 Invalidation and updating
225 -------------------------
226
227 Because ``MemorySSA`` keeps track of LLVM IR, it needs to be updated whenever
228 the IR is updated. "Update", in this case, includes the addition, deletion, and
229 motion of IR instructions. The update API is being made on an as-needed basis.
230
231
232 Phi placement
233 ^^^^^^^^^^^^^
234
235 ``MemorySSA`` only places ``MemoryPhi`` s where they're actually
236 needed. That is, it is a pruned SSA form, like LLVM's SSA form. For
237 example, consider:
238
239 .. code-block:: llvm
240
241 define void @foo() {
242 entry:
243 %p1 = alloca i8
244 %p2 = alloca i8
245 %p3 = alloca i8
246 ; 1 = MemoryDef(liveOnEntry)
247 store i8 0, i8* %p3
248 br label %while.cond
249
250 while.cond:
251 ; 3 = MemoryPhi({%0,1},{if.end,2})
252 br i1 undef, label %if.then, label %if.else
253
254 if.then:
255 br label %if.end
256
257 if.else:
258 br label %if.end
259
260 if.end:
261 ; MemoryUse(1)
262 %1 = load i8, i8* %p1
263 ; 2 = MemoryDef(3)
264 store i8 2, i8* %p2
265 ; MemoryUse(1)
266 %2 = load i8, i8* %p3
267 br label %while.cond
268 }
269
270 Because we removed the stores from ``if.then`` and ``if.else``, a ``MemoryPhi``
271 for ``if.end`` would be pointless, so we don't place one. So, if you need to
272 place a ``MemoryDef`` in ``if.then`` or ``if.else``, you'll need to also create
273 a ``MemoryPhi`` for ``if.end``.
274
275 If it turns out that this is a large burden, we can just place ``MemoryPhi`` s
276 everywhere. Because we have Walkers that are capable of optimizing above said
277 phis, doing so shouldn't prohibit optimizations.
278
279
280 Non-Goals
281 ---------
282
283 ``MemorySSA`` is meant to reason about the relation between memory
284 operations, and enable quicker querying.
285 It isn't meant to be the single source of truth for all potential memory-related
286 optimizations. Specifically, care must be taken when trying to use ``MemorySSA``
287 to reason about atomic or volatile operations, as in:
288
289 .. code-block:: llvm
290
291 define i8 @foo(i8* %a) {
292 entry:
293 br i1 undef, label %if.then, label %if.end
294
295 if.then:
296 ; 1 = MemoryDef(liveOnEntry)
297 %0 = load volatile i8, i8* %a
298 br label %if.end
299
300 if.end:
301 %av = phi i8 [0, %entry], [%0, %if.then]
302 ret i8 %av
303 }
304
305 Going solely by ``MemorySSA``'s analysis, hoisting the ``load`` to ``entry`` may
306 seem legal. Because it's a volatile load, though, it's not.
307
308
309 Design tradeoffs
310 ----------------
311
312 Precision
313 ^^^^^^^^^
314 ``MemorySSA`` in LLVM deliberately trades off precision for speed.
315 Let us think about memory variables as if they were disjoint partitions of the
316 heap (that is, if you have one variable, as above, it represents the entire
317 heap, and if you have multiple variables, each one represents some
318 disjoint portion of the heap)
319
320 First, because alias analysis results conflict with each other, and
321 each result may be what an analysis wants (IE
322 TBAA may say no-alias, and something else may say must-alias), it is
323 not possible to partition the heap the way every optimization wants.
324 Second, some alias analysis results are not transitive (IE A noalias B,
325 and B noalias C, does not mean A noalias C), so it is not possible to
326 come up with a precise partitioning in all cases without variables to
327 represent every pair of possible aliases. Thus, partitioning
328 precisely may require introducing at least N^2 new virtual variables,
329 phi nodes, etc.
330
331 Each of these variables may be clobbered at multiple def sites.
332
333 To give an example, if you were to split up struct fields into
334 individual variables, all aliasing operations that may-def multiple struct
335 fields, will may-def more than one of them. This is pretty common (calls,
336 copies, field stores, etc).
337
338 Experience with SSA forms for memory in other compilers has shown that
339 it is simply not possible to do this precisely, and in fact, doing it
340 precisely is not worth it, because now all the optimizations have to
341 walk tons and tons of virtual variables and phi nodes.
342
343 So we partition. At the point at which you partition, again,
344 experience has shown us there is no point in partitioning to more than
345 one variable. It simply generates more IR, and optimizations still
346 have to query something to disambiguate further anyway.
347
348 As a result, LLVM partitions to one variable.
349
350 Use Optimization
351 ^^^^^^^^^^^^^^^^
352
353 Unlike other partitioned forms, LLVM's ``MemorySSA`` does make one
354 useful guarantee - all loads are optimized to point at the thing that
355 actually clobbers them. This gives some nice properties. For example,
356 for a given store, you can find all loads actually clobbered by that
357 store by walking the immediate uses of the store.
234234 :hidden:
235235
236236 AliasAnalysis
237 MemorySSA
237238 BitCodeFormat
238239 BlockFrequencyTerminology
239240 BranchWeightMetadata
290291 Information on how to write a new alias analysis implementation or how to
291292 use existing analyses.
292293
294 :doc:`MemorySSA`
295 Information about the MemorySSA utility in LLVM, as well as how to use it.
296
293297 :doc:`GarbageCollection`
294298 The interfaces source-language compilers should use for compiling GC'd
295299 programs.