xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/ValueMapper.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===- ValueMapper.h - Remapping for constants and metadata -----*- 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 // This file defines the MapValue interface which is used by various parts of
10 // the Transforms/Utils library to implement cloning and linking facilities.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_TRANSFORMS_UTILS_VALUEMAPPER_H
15 #define LLVM_TRANSFORMS_UTILS_VALUEMAPPER_H
16 
17 #include "llvm/ADT/ArrayRef.h"
18 #include "llvm/ADT/simple_ilist.h"
19 #include "llvm/IR/ValueHandle.h"
20 #include "llvm/IR/ValueMap.h"
21 
22 namespace llvm {
23 
24 class Constant;
25 class DIBuilder;
26 class DbgRecord;
27 class Function;
28 class GlobalVariable;
29 class Instruction;
30 class MDNode;
31 class Metadata;
32 class Module;
33 class Type;
34 class Value;
35 
36 using ValueToValueMapTy = ValueMap<const Value *, WeakTrackingVH>;
37 using DbgRecordIterator = simple_ilist<DbgRecord>::iterator;
38 
39 /// This is a class that can be implemented by clients to remap types when
40 /// cloning constants and instructions.
41 class ValueMapTypeRemapper {
42   virtual void anchor(); // Out of line method.
43 
44 public:
45   virtual ~ValueMapTypeRemapper() = default;
46 
47   /// The client should implement this method if they want to remap types while
48   /// mapping values.
49   virtual Type *remapType(Type *SrcTy) = 0;
50 };
51 
52 /// This is a class that can be implemented by clients to materialize Values on
53 /// demand.
54 class ValueMaterializer {
55   virtual void anchor(); // Out of line method.
56 
57 protected:
58   ValueMaterializer() = default;
59   ValueMaterializer(const ValueMaterializer &) = default;
60   ValueMaterializer &operator=(const ValueMaterializer &) = default;
61   ~ValueMaterializer() = default;
62 
63 public:
64   /// This method can be implemented to generate a mapped Value on demand. For
65   /// example, if linking lazily. Returns null if the value is not materialized.
66   virtual Value *materialize(Value *V) = 0;
67 };
68 
69 /// These are flags that the value mapping APIs allow.
70 enum RemapFlags {
71   RF_None = 0,
72 
73   /// If this flag is set, the remapper knows that only local values within a
74   /// function (such as an instruction or argument) are mapped, not global
75   /// values like functions and global metadata.
76   RF_NoModuleLevelChanges = 1,
77 
78   /// If this flag is set, the remapper ignores missing function-local entries
79   /// (Argument, Instruction, BasicBlock) that are not in the value map.  If it
80   /// is unset, it aborts if an operand is asked to be remapped which doesn't
81   /// exist in the mapping.
82   ///
83   /// There are no such assertions in MapValue(), whose results are almost
84   /// unchanged by this flag.  This flag mainly changes the assertion behaviour
85   /// in RemapInstruction().
86   ///
87   /// Since an Instruction's metadata operands (even that point to SSA values)
88   /// aren't guaranteed to be dominated by their definitions, MapMetadata will
89   /// return "!{}" instead of "null" for \a LocalAsMetadata instances whose SSA
90   /// values are unmapped when this flag is set.  Otherwise, \a MapValue()
91   /// completely ignores this flag.
92   ///
93   /// \a MapMetadata() always ignores this flag.
94   RF_IgnoreMissingLocals = 2,
95 
96   /// Instruct the remapper to reuse and mutate distinct metadata (remapping
97   /// them in place) instead of cloning remapped copies. This flag has no
98   /// effect when RF_NoModuleLevelChanges, since that implies an identity
99   /// mapping.
100   RF_ReuseAndMutateDistinctMDs = 4,
101 
102   /// Any global values not in value map are mapped to null instead of mapping
103   /// to self.  Illegal if RF_IgnoreMissingLocals is also set.
104   RF_NullMapMissingGlobalValues = 8,
105 };
106 
107 inline RemapFlags operator|(RemapFlags LHS, RemapFlags RHS) {
108   return RemapFlags(unsigned(LHS) | unsigned(RHS));
109 }
110 
111 /// Context for (re-)mapping values (and metadata).
112 ///
113 /// A shared context used for mapping and remapping of Value and Metadata
114 /// instances using \a ValueToValueMapTy, \a RemapFlags, \a
115 /// ValueMapTypeRemapper, and \a ValueMaterializer.
116 ///
117 /// There are a number of top-level entry points:
118 /// - \a mapValue() (and \a mapConstant());
119 /// - \a mapMetadata() (and \a mapMDNode());
120 /// - \a remapInstruction();
121 /// - \a remapFunction(); and
122 /// - \a remapGlobalObjectMetadata().
123 ///
124 /// The \a ValueMaterializer can be used as a callback, but cannot invoke any
125 /// of these top-level functions recursively.  Instead, callbacks should use
126 /// one of the following to schedule work lazily in the \a ValueMapper
127 /// instance:
128 /// - \a scheduleMapGlobalInitializer()
129 /// - \a scheduleMapAppendingVariable()
130 /// - \a scheduleMapGlobalAlias()
131 /// - \a scheduleMapGlobalIFunc()
132 /// - \a scheduleRemapFunction()
133 ///
134 /// Sometimes a callback needs a different mapping context.  Such a context can
135 /// be registered using \a registerAlternateMappingContext(), which takes an
136 /// alternate \a ValueToValueMapTy and \a ValueMaterializer and returns a ID to
137 /// pass into the schedule*() functions.
138 ///
139 /// TODO: lib/Linker really doesn't need the \a ValueHandle in the \a
140 /// ValueToValueMapTy.  We should template \a ValueMapper (and its
141 /// implementation classes), and explicitly instantiate on two concrete
142 /// instances of \a ValueMap (one as \a ValueToValueMap, and one with raw \a
143 /// Value pointers).  It may be viable to do away with \a TrackingMDRef in the
144 /// \a Metadata side map for the lib/Linker case as well, in which case we'll
145 /// need a new template parameter on \a ValueMap.
146 ///
147 /// TODO: Update callers of \a RemapInstruction() and \a MapValue() (etc.) to
148 /// use \a ValueMapper directly.
149 class ValueMapper {
150   void *pImpl;
151 
152 public:
153   ValueMapper(ValueToValueMapTy &VM, RemapFlags Flags = RF_None,
154               ValueMapTypeRemapper *TypeMapper = nullptr,
155               ValueMaterializer *Materializer = nullptr);
156   ValueMapper(ValueMapper &&) = delete;
157   ValueMapper(const ValueMapper &) = delete;
158   ValueMapper &operator=(ValueMapper &&) = delete;
159   ValueMapper &operator=(const ValueMapper &) = delete;
160   ~ValueMapper();
161 
162   /// Register an alternate mapping context.
163   ///
164   /// Returns a MappingContextID that can be used with the various schedule*()
165   /// API to switch in a different value map on-the-fly.
166   unsigned
167   registerAlternateMappingContext(ValueToValueMapTy &VM,
168                                   ValueMaterializer *Materializer = nullptr);
169 
170   /// Add to the current \a RemapFlags.
171   ///
172   /// \note Like the top-level mapping functions, \a addFlags() must be called
173   /// at the top level, not during a callback in a \a ValueMaterializer.
174   void addFlags(RemapFlags Flags);
175 
176   Metadata *mapMetadata(const Metadata &MD);
177   MDNode *mapMDNode(const MDNode &N);
178 
179   Value *mapValue(const Value &V);
180   Constant *mapConstant(const Constant &C);
181 
182   void remapInstruction(Instruction &I);
183   void remapDbgRecord(Module *M, DbgRecord &V);
184   void remapDbgRecordRange(Module *M, iterator_range<DbgRecordIterator> Range);
185   void remapFunction(Function &F);
186   void remapGlobalObjectMetadata(GlobalObject &GO);
187 
188   void scheduleMapGlobalInitializer(GlobalVariable &GV, Constant &Init,
189                                     unsigned MappingContextID = 0);
190   void scheduleMapAppendingVariable(GlobalVariable &GV, Constant *InitPrefix,
191                                     bool IsOldCtorDtor,
192                                     ArrayRef<Constant *> NewMembers,
193                                     unsigned MappingContextID = 0);
194   void scheduleMapGlobalAlias(GlobalAlias &GA, Constant &Aliasee,
195                               unsigned MappingContextID = 0);
196   void scheduleMapGlobalIFunc(GlobalIFunc &GI, Constant &Resolver,
197                               unsigned MappingContextID = 0);
198   void scheduleRemapFunction(Function &F, unsigned MappingContextID = 0);
199 };
200 
201 /// Look up or compute a value in the value map.
202 ///
203 /// Return a mapped value for a function-local value (Argument, Instruction,
204 /// BasicBlock), or compute and memoize a value for a Constant.
205 ///
206 ///  1. If \c V is in VM, return the result.
207 ///  2. Else if \c V can be materialized with \c Materializer, do so, memoize
208 ///     it in \c VM, and return it.
209 ///  3. Else if \c V is a function-local value, return nullptr.
210 ///  4. Else if \c V is a \a GlobalValue, return \c nullptr or \c V depending
211 ///     on \a RF_NullMapMissingGlobalValues.
212 ///  5. Else if \c V is a \a MetadataAsValue wrapping a LocalAsMetadata,
213 ///     recurse on the local SSA value, and return nullptr or "metadata !{}" on
214 ///     missing depending on RF_IgnoreMissingValues.
215 ///  6. Else if \c V is a \a MetadataAsValue, rewrap the return of \a
216 ///     MapMetadata().
217 ///  7. Else, compute the equivalent constant, and return it.
218 inline Value *MapValue(const Value *V, ValueToValueMapTy &VM,
219                        RemapFlags Flags = RF_None,
220                        ValueMapTypeRemapper *TypeMapper = nullptr,
221                        ValueMaterializer *Materializer = nullptr) {
222   return ValueMapper(VM, Flags, TypeMapper, Materializer).mapValue(*V);
223 }
224 
225 /// Lookup or compute a mapping for a piece of metadata.
226 ///
227 /// Compute and memoize a mapping for \c MD.
228 ///
229 ///  1. If \c MD is mapped, return it.
230 ///  2. Else if \a RF_NoModuleLevelChanges or \c MD is an \a MDString, return
231 ///     \c MD.
232 ///  3. Else if \c MD is a \a ConstantAsMetadata, call \a MapValue() and
233 ///     re-wrap its return (returning nullptr on nullptr).
234 ///  4. Else, \c MD is an \a MDNode.  These are remapped, along with their
235 ///     transitive operands.  Distinct nodes are duplicated or moved depending
236 ///     on \a RF_MoveDistinctNodes.  Uniqued nodes are remapped like constants.
237 ///
238 /// \note \a LocalAsMetadata is completely unsupported by \a MapMetadata.
239 /// Instead, use \a MapValue() with its wrapping \a MetadataAsValue instance.
240 inline Metadata *MapMetadata(const Metadata *MD, ValueToValueMapTy &VM,
241                              RemapFlags Flags = RF_None,
242                              ValueMapTypeRemapper *TypeMapper = nullptr,
243                              ValueMaterializer *Materializer = nullptr) {
244   return ValueMapper(VM, Flags, TypeMapper, Materializer).mapMetadata(*MD);
245 }
246 
247 /// Version of MapMetadata with type safety for MDNode.
248 inline MDNode *MapMetadata(const MDNode *MD, ValueToValueMapTy &VM,
249                            RemapFlags Flags = RF_None,
250                            ValueMapTypeRemapper *TypeMapper = nullptr,
251                            ValueMaterializer *Materializer = nullptr) {
252   return ValueMapper(VM, Flags, TypeMapper, Materializer).mapMDNode(*MD);
253 }
254 
255 /// Convert the instruction operands from referencing the current values into
256 /// those specified by VM.
257 ///
258 /// If \a RF_IgnoreMissingLocals is set and an operand can't be found via \a
259 /// MapValue(), use the old value.  Otherwise assert that this doesn't happen.
260 ///
261 /// Note that \a MapValue() only returns \c nullptr for SSA values missing from
262 /// \c VM.
263 inline void RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
264                              RemapFlags Flags = RF_None,
265                              ValueMapTypeRemapper *TypeMapper = nullptr,
266                              ValueMaterializer *Materializer = nullptr) {
267   ValueMapper(VM, Flags, TypeMapper, Materializer).remapInstruction(*I);
268 }
269 
270 /// Remap the Values used in the DbgRecord \a DR using the value map \a
271 /// VM.
272 inline void RemapDbgRecord(Module *M, DbgRecord *DR, ValueToValueMapTy &VM,
273                            RemapFlags Flags = RF_None,
274                            ValueMapTypeRemapper *TypeMapper = nullptr,
275                            ValueMaterializer *Materializer = nullptr) {
276   ValueMapper(VM, Flags, TypeMapper, Materializer).remapDbgRecord(M, *DR);
277 }
278 
279 /// Remap the Values used in the DbgRecords \a Range using the value map \a
280 /// VM.
281 inline void RemapDbgRecordRange(Module *M,
282                                 iterator_range<DbgRecordIterator> Range,
283                                 ValueToValueMapTy &VM,
284                                 RemapFlags Flags = RF_None,
285                                 ValueMapTypeRemapper *TypeMapper = nullptr,
286                                 ValueMaterializer *Materializer = nullptr) {
287   ValueMapper(VM, Flags, TypeMapper, Materializer)
288       .remapDbgRecordRange(M, Range);
289 }
290 
291 /// Remap the operands, metadata, arguments, and instructions of a function.
292 ///
293 /// Calls \a MapValue() on prefix data, prologue data, and personality
294 /// function; calls \a MapMetadata() on each attached MDNode; remaps the
295 /// argument types using the provided \c TypeMapper; and calls \a
296 /// RemapInstruction() on every instruction.
297 inline void RemapFunction(Function &F, ValueToValueMapTy &VM,
298                           RemapFlags Flags = RF_None,
299                           ValueMapTypeRemapper *TypeMapper = nullptr,
300                           ValueMaterializer *Materializer = nullptr) {
301   ValueMapper(VM, Flags, TypeMapper, Materializer).remapFunction(F);
302 }
303 
304 /// Version of MapValue with type safety for Constant.
305 inline Constant *MapValue(const Constant *V, ValueToValueMapTy &VM,
306                           RemapFlags Flags = RF_None,
307                           ValueMapTypeRemapper *TypeMapper = nullptr,
308                           ValueMaterializer *Materializer = nullptr) {
309   return ValueMapper(VM, Flags, TypeMapper, Materializer).mapConstant(*V);
310 }
311 
312 } // end namespace llvm
313 
314 #endif // LLVM_TRANSFORMS_UTILS_VALUEMAPPER_H
315