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