1212793Sdim//===- ValueMapper.h - Remapping for constants and metadata -----*- C++ -*-===//
2212793Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6212793Sdim//
7212793Sdim//===----------------------------------------------------------------------===//
8212793Sdim//
9212793Sdim// This file defines the MapValue interface which is used by various parts of
10212793Sdim// the Transforms/Utils library to implement cloning and linking facilities.
11212793Sdim//
12212793Sdim//===----------------------------------------------------------------------===//
13212793Sdim
14212793Sdim#ifndef LLVM_TRANSFORMS_UTILS_VALUEMAPPER_H
15212793Sdim#define LLVM_TRANSFORMS_UTILS_VALUEMAPPER_H
16212793Sdim
17321369Sdim#include "llvm/ADT/ArrayRef.h"
18321369Sdim#include "llvm/IR/ValueHandle.h"
19276479Sdim#include "llvm/IR/ValueMap.h"
20212793Sdim
21212793Sdimnamespace llvm {
22212793Sdim
23327952Sdimclass Constant;
24327952Sdimclass Function;
25360784Sdimclass GlobalIndirectSymbol;
26327952Sdimclass GlobalVariable;
27327952Sdimclass Instruction;
28327952Sdimclass MDNode;
29327952Sdimclass Metadata;
30327952Sdimclass Type;
31309124Sdimclass Value;
32276479Sdim
33327952Sdimusing ValueToValueMapTy = ValueMap<const Value *, WeakTrackingVH>;
34327952Sdim
35309124Sdim/// This is a class that can be implemented by clients to remap types when
36309124Sdim/// cloning constants and instructions.
37309124Sdimclass ValueMapTypeRemapper {
38309124Sdim  virtual void anchor(); // Out of line method.
39321369Sdim
40309124Sdimpublic:
41321369Sdim  virtual ~ValueMapTypeRemapper() = default;
42261991Sdim
43309124Sdim  /// The client should implement this method if they want to remap types while
44309124Sdim  /// mapping values.
45309124Sdim  virtual Type *remapType(Type *SrcTy) = 0;
46309124Sdim};
47296417Sdim
48309124Sdim/// This is a class that can be implemented by clients to materialize Values on
49309124Sdim/// demand.
50309124Sdimclass ValueMaterializer {
51309124Sdim  virtual void anchor(); // Out of line method.
52296417Sdim
53309124Sdimprotected:
54309124Sdim  ValueMaterializer() = default;
55309124Sdim  ValueMaterializer(const ValueMaterializer &) = default;
56309124Sdim  ValueMaterializer &operator=(const ValueMaterializer &) = default;
57327952Sdim  ~ValueMaterializer() = default;
58261991Sdim
59309124Sdimpublic:
60309124Sdim  /// This method can be implemented to generate a mapped Value on demand. For
61309124Sdim  /// example, if linking lazily. Returns null if the value is not materialized.
62309124Sdim  virtual Value *materialize(Value *V) = 0;
63309124Sdim};
64296417Sdim
65309124Sdim/// These are flags that the value mapping APIs allow.
66309124Sdimenum RemapFlags {
67309124Sdim  RF_None = 0,
68296417Sdim
69309124Sdim  /// If this flag is set, the remapper knows that only local values within a
70309124Sdim  /// function (such as an instruction or argument) are mapped, not global
71309124Sdim  /// values like functions and global metadata.
72309124Sdim  RF_NoModuleLevelChanges = 1,
73276479Sdim
74309124Sdim  /// If this flag is set, the remapper ignores missing function-local entries
75309124Sdim  /// (Argument, Instruction, BasicBlock) that are not in the value map.  If it
76309124Sdim  /// is unset, it aborts if an operand is asked to be remapped which doesn't
77309124Sdim  /// exist in the mapping.
78309124Sdim  ///
79309124Sdim  /// There are no such assertions in MapValue(), whose results are almost
80309124Sdim  /// unchanged by this flag.  This flag mainly changes the assertion behaviour
81309124Sdim  /// in RemapInstruction().
82309124Sdim  ///
83309124Sdim  /// Since an Instruction's metadata operands (even that point to SSA values)
84309124Sdim  /// aren't guaranteed to be dominated by their definitions, MapMetadata will
85309124Sdim  /// return "!{}" instead of "null" for \a LocalAsMetadata instances whose SSA
86309124Sdim  /// values are unmapped when this flag is set.  Otherwise, \a MapValue()
87309124Sdim  /// completely ignores this flag.
88309124Sdim  ///
89309124Sdim  /// \a MapMetadata() always ignores this flag.
90309124Sdim  RF_IgnoreMissingLocals = 2,
91276479Sdim
92309124Sdim  /// Instruct the remapper to move distinct metadata instead of duplicating it
93309124Sdim  /// when there are module-level changes.
94309124Sdim  RF_MoveDistinctMDs = 4,
95276479Sdim
96309124Sdim  /// Any global values not in value map are mapped to null instead of mapping
97309124Sdim  /// to self.  Illegal if RF_IgnoreMissingLocals is also set.
98309124Sdim  RF_NullMapMissingGlobalValues = 8,
99309124Sdim};
100296417Sdim
101327952Sdiminline RemapFlags operator|(RemapFlags LHS, RemapFlags RHS) {
102309124Sdim  return RemapFlags(unsigned(LHS) | unsigned(RHS));
103309124Sdim}
104296417Sdim
105309124Sdim/// Context for (re-)mapping values (and metadata).
106309124Sdim///
107309124Sdim/// A shared context used for mapping and remapping of Value and Metadata
108309124Sdim/// instances using \a ValueToValueMapTy, \a RemapFlags, \a
109309124Sdim/// ValueMapTypeRemapper, and \a ValueMaterializer.
110309124Sdim///
111309124Sdim/// There are a number of top-level entry points:
112309124Sdim/// - \a mapValue() (and \a mapConstant());
113309124Sdim/// - \a mapMetadata() (and \a mapMDNode());
114309124Sdim/// - \a remapInstruction(); and
115309124Sdim/// - \a remapFunction().
116309124Sdim///
117309124Sdim/// The \a ValueMaterializer can be used as a callback, but cannot invoke any
118309124Sdim/// of these top-level functions recursively.  Instead, callbacks should use
119309124Sdim/// one of the following to schedule work lazily in the \a ValueMapper
120309124Sdim/// instance:
121309124Sdim/// - \a scheduleMapGlobalInitializer()
122309124Sdim/// - \a scheduleMapAppendingVariable()
123360784Sdim/// - \a scheduleMapGlobalIndirectSymbol()
124309124Sdim/// - \a scheduleRemapFunction()
125309124Sdim///
126321369Sdim/// Sometimes a callback needs a different mapping context.  Such a context can
127309124Sdim/// be registered using \a registerAlternateMappingContext(), which takes an
128309124Sdim/// alternate \a ValueToValueMapTy and \a ValueMaterializer and returns a ID to
129309124Sdim/// pass into the schedule*() functions.
130309124Sdim///
131309124Sdim/// TODO: lib/Linker really doesn't need the \a ValueHandle in the \a
132309124Sdim/// ValueToValueMapTy.  We should template \a ValueMapper (and its
133309124Sdim/// implementation classes), and explicitly instantiate on two concrete
134309124Sdim/// instances of \a ValueMap (one as \a ValueToValueMap, and one with raw \a
135309124Sdim/// Value pointers).  It may be viable to do away with \a TrackingMDRef in the
136309124Sdim/// \a Metadata side map for the lib/Linker case as well, in which case we'll
137309124Sdim/// need a new template parameter on \a ValueMap.
138309124Sdim///
139309124Sdim/// TODO: Update callers of \a RemapInstruction() and \a MapValue() (etc.) to
140309124Sdim/// use \a ValueMapper directly.
141309124Sdimclass ValueMapper {
142309124Sdim  void *pImpl;
143276479Sdim
144321369Sdimpublic:
145321369Sdim  ValueMapper(ValueToValueMapTy &VM, RemapFlags Flags = RF_None,
146321369Sdim              ValueMapTypeRemapper *TypeMapper = nullptr,
147321369Sdim              ValueMaterializer *Materializer = nullptr);
148309124Sdim  ValueMapper(ValueMapper &&) = delete;
149309124Sdim  ValueMapper(const ValueMapper &) = delete;
150309124Sdim  ValueMapper &operator=(ValueMapper &&) = delete;
151309124Sdim  ValueMapper &operator=(const ValueMapper &) = delete;
152309124Sdim  ~ValueMapper();
153224145Sdim
154309124Sdim  /// Register an alternate mapping context.
155309124Sdim  ///
156309124Sdim  /// Returns a MappingContextID that can be used with the various schedule*()
157309124Sdim  /// API to switch in a different value map on-the-fly.
158309124Sdim  unsigned
159309124Sdim  registerAlternateMappingContext(ValueToValueMapTy &VM,
160309124Sdim                                  ValueMaterializer *Materializer = nullptr);
161280031Sdim
162309124Sdim  /// Add to the current \a RemapFlags.
163309124Sdim  ///
164309124Sdim  /// \note Like the top-level mapping functions, \a addFlags() must be called
165309124Sdim  /// at the top level, not during a callback in a \a ValueMaterializer.
166309124Sdim  void addFlags(RemapFlags Flags);
167280031Sdim
168309124Sdim  Metadata *mapMetadata(const Metadata &MD);
169309124Sdim  MDNode *mapMDNode(const MDNode &N);
170276479Sdim
171309124Sdim  Value *mapValue(const Value &V);
172309124Sdim  Constant *mapConstant(const Constant &C);
173224145Sdim
174309124Sdim  void remapInstruction(Instruction &I);
175309124Sdim  void remapFunction(Function &F);
176309124Sdim
177309124Sdim  void scheduleMapGlobalInitializer(GlobalVariable &GV, Constant &Init,
178309124Sdim                                    unsigned MappingContextID = 0);
179309124Sdim  void scheduleMapAppendingVariable(GlobalVariable &GV, Constant *InitPrefix,
180309124Sdim                                    bool IsOldCtorDtor,
181309124Sdim                                    ArrayRef<Constant *> NewMembers,
182309124Sdim                                    unsigned MappingContextID = 0);
183360784Sdim  void scheduleMapGlobalIndirectSymbol(GlobalIndirectSymbol &GIS,
184360784Sdim                                       Constant &Target,
185360784Sdim                                       unsigned MappingContextID = 0);
186309124Sdim  void scheduleRemapFunction(Function &F, unsigned MappingContextID = 0);
187309124Sdim};
188309124Sdim
189309124Sdim/// Look up or compute a value in the value map.
190309124Sdim///
191309124Sdim/// Return a mapped value for a function-local value (Argument, Instruction,
192309124Sdim/// BasicBlock), or compute and memoize a value for a Constant.
193309124Sdim///
194309124Sdim///  1. If \c V is in VM, return the result.
195309124Sdim///  2. Else if \c V can be materialized with \c Materializer, do so, memoize
196309124Sdim///     it in \c VM, and return it.
197309124Sdim///  3. Else if \c V is a function-local value, return nullptr.
198309124Sdim///  4. Else if \c V is a \a GlobalValue, return \c nullptr or \c V depending
199309124Sdim///     on \a RF_NullMapMissingGlobalValues.
200309124Sdim///  5. Else if \c V is a \a MetadataAsValue wrapping a LocalAsMetadata,
201309124Sdim///     recurse on the local SSA value, and return nullptr or "metadata !{}" on
202309124Sdim///     missing depending on RF_IgnoreMissingValues.
203309124Sdim///  6. Else if \c V is a \a MetadataAsValue, rewrap the return of \a
204309124Sdim///     MapMetadata().
205309124Sdim///  7. Else, compute the equivalent constant, and return it.
206309124Sdiminline Value *MapValue(const Value *V, ValueToValueMapTy &VM,
207309124Sdim                       RemapFlags Flags = RF_None,
208309124Sdim                       ValueMapTypeRemapper *TypeMapper = nullptr,
209309124Sdim                       ValueMaterializer *Materializer = nullptr) {
210309124Sdim  return ValueMapper(VM, Flags, TypeMapper, Materializer).mapValue(*V);
211309124Sdim}
212309124Sdim
213309124Sdim/// Lookup or compute a mapping for a piece of metadata.
214309124Sdim///
215309124Sdim/// Compute and memoize a mapping for \c MD.
216309124Sdim///
217309124Sdim///  1. If \c MD is mapped, return it.
218309124Sdim///  2. Else if \a RF_NoModuleLevelChanges or \c MD is an \a MDString, return
219309124Sdim///     \c MD.
220309124Sdim///  3. Else if \c MD is a \a ConstantAsMetadata, call \a MapValue() and
221309124Sdim///     re-wrap its return (returning nullptr on nullptr).
222309124Sdim///  4. Else, \c MD is an \a MDNode.  These are remapped, along with their
223309124Sdim///     transitive operands.  Distinct nodes are duplicated or moved depending
224309124Sdim///     on \a RF_MoveDistinctNodes.  Uniqued nodes are remapped like constants.
225309124Sdim///
226309124Sdim/// \note \a LocalAsMetadata is completely unsupported by \a MapMetadata.
227309124Sdim/// Instead, use \a MapValue() with its wrapping \a MetadataAsValue instance.
228309124Sdiminline Metadata *MapMetadata(const Metadata *MD, ValueToValueMapTy &VM,
229309124Sdim                             RemapFlags Flags = RF_None,
230309124Sdim                             ValueMapTypeRemapper *TypeMapper = nullptr,
231309124Sdim                             ValueMaterializer *Materializer = nullptr) {
232309124Sdim  return ValueMapper(VM, Flags, TypeMapper, Materializer).mapMetadata(*MD);
233309124Sdim}
234309124Sdim
235309124Sdim/// Version of MapMetadata with type safety for MDNode.
236309124Sdiminline MDNode *MapMetadata(const MDNode *MD, ValueToValueMapTy &VM,
237309124Sdim                           RemapFlags Flags = RF_None,
238309124Sdim                           ValueMapTypeRemapper *TypeMapper = nullptr,
239309124Sdim                           ValueMaterializer *Materializer = nullptr) {
240309124Sdim  return ValueMapper(VM, Flags, TypeMapper, Materializer).mapMDNode(*MD);
241309124Sdim}
242309124Sdim
243309124Sdim/// Convert the instruction operands from referencing the current values into
244309124Sdim/// those specified by VM.
245309124Sdim///
246309124Sdim/// If \a RF_IgnoreMissingLocals is set and an operand can't be found via \a
247309124Sdim/// MapValue(), use the old value.  Otherwise assert that this doesn't happen.
248309124Sdim///
249309124Sdim/// Note that \a MapValue() only returns \c nullptr for SSA values missing from
250309124Sdim/// \c VM.
251309124Sdiminline void RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
252309124Sdim                             RemapFlags Flags = RF_None,
253309124Sdim                             ValueMapTypeRemapper *TypeMapper = nullptr,
254309124Sdim                             ValueMaterializer *Materializer = nullptr) {
255309124Sdim  ValueMapper(VM, Flags, TypeMapper, Materializer).remapInstruction(*I);
256309124Sdim}
257309124Sdim
258309124Sdim/// Remap the operands, metadata, arguments, and instructions of a function.
259309124Sdim///
260309124Sdim/// Calls \a MapValue() on prefix data, prologue data, and personality
261309124Sdim/// function; calls \a MapMetadata() on each attached MDNode; remaps the
262309124Sdim/// argument types using the provided \c TypeMapper; and calls \a
263309124Sdim/// RemapInstruction() on every instruction.
264309124Sdiminline void RemapFunction(Function &F, ValueToValueMapTy &VM,
265309124Sdim                          RemapFlags Flags = RF_None,
266309124Sdim                          ValueMapTypeRemapper *TypeMapper = nullptr,
267309124Sdim                          ValueMaterializer *Materializer = nullptr) {
268309124Sdim  ValueMapper(VM, Flags, TypeMapper, Materializer).remapFunction(F);
269309124Sdim}
270309124Sdim
271309124Sdim/// Version of MapValue with type safety for Constant.
272309124Sdiminline Constant *MapValue(const Constant *V, ValueToValueMapTy &VM,
273309124Sdim                          RemapFlags Flags = RF_None,
274309124Sdim                          ValueMapTypeRemapper *TypeMapper = nullptr,
275309124Sdim                          ValueMaterializer *Materializer = nullptr) {
276309124Sdim  return ValueMapper(VM, Flags, TypeMapper, Materializer).mapConstant(*V);
277309124Sdim}
278309124Sdim
279321369Sdim} // end namespace llvm
280212793Sdim
281321369Sdim#endif // LLVM_TRANSFORMS_UTILS_VALUEMAPPER_H
282