47#define DEBUG_TYPE "value-mapper"
50void ValueMapTypeRemapper::anchor() {}
51void ValueMaterializer::anchor() {}
57struct DelayedBasicBlock {
59 std::unique_ptr<BasicBlock> TempBB;
62 : OldBB(Old.getBasicBlock()),
63 TempBB(
BasicBlock::Create(Old.getContext())) {}
77 struct AppendingGVTy {
81 struct AliasOrIFuncTy {
88 unsigned AppendingGVIsOldCtorDtor : 1;
89 unsigned AppendingGVNumNewMembers;
92 AppendingGVTy AppendingGV;
93 AliasOrIFuncTy AliasOrIFunc;
98struct MappingContext {
105 : VM(&VM), Materializer(Materializer) {}
109 friend class MDNodeMapper;
117 unsigned CurrentMCID = 0;
127 MCs(1, MappingContext(VM, Materializer)) {}
130 ~Mapper() {
assert(!hasWorkToDo() &&
"Expected to be flushed"); }
132 bool hasWorkToDo()
const {
return !Worklist.
empty(); }
137 MCs.
push_back(MappingContext(VM, Materializer));
138 return MCs.
size() - 1;
150 return cast_or_null<Constant>(mapValue(
C));
167 void scheduleRemapFunction(
Function &
F,
unsigned MCID);
182 std::optional<Metadata *> mapSimpleMetadata(
const Metadata *MD);
193 bool HasChanged =
false;
194 unsigned ID = std::numeric_limits<unsigned>::max();
195 TempMDNode Placeholder;
199 struct UniquedGraph {
207 void propagateChanges();
221 MDNodeMapper(Mapper &M) :
M(
M) {}
274 std::optional<Metadata *> tryToMapOperand(
const Metadata *Op);
302 bool createPOT(UniquedGraph &
G,
const MDNode &FirstN);
323 void mapNodesInPOT(UniquedGraph &
G);
331 template <
class OperandMapper>
332 void remapOperands(
MDNode &
N, OperandMapper mapOperand);
341 if (
I != getVM().
end()) {
342 assert(
I->second &&
"Unexpected null mapping");
347 if (
auto *Materializer = getMaterializer()) {
348 if (
Value *NewV = Materializer->materialize(
const_cast<Value *
>(V))) {
356 if (isa<GlobalValue>(V)) {
359 return getVM()[
V] =
const_cast<Value *
>(
V);
362 if (
const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
366 NewTy = cast<FunctionType>(TypeMapper->
remapType(NewTy));
368 if (NewTy !=
IA->getFunctionType())
370 IA->hasSideEffects(),
IA->isAlignStack(),
371 IA->getDialect(),
IA->canThrow());
374 return getVM()[
V] =
const_cast<Value *
>(
V);
377 if (
const auto *MDV = dyn_cast<MetadataAsValue>(V)) {
378 const Metadata *MD = MDV->getMetadata();
380 if (
auto *
LAM = dyn_cast<LocalAsMetadata>(MD)) {
382 if (
Value *LV = mapValue(
LAM->getValue())) {
383 if (V ==
LAM->getValue())
384 return const_cast<Value *
>(V);
396 if (
auto *AL = dyn_cast<DIArgList>(MD)) {
398 for (
auto *VAM :
AL->getArgs()) {
406 }
else if (
Value *LV = mapValue(VAM->getValue())) {
424 return getVM()[
V] =
const_cast<Value *
>(
V);
427 auto *MappedMD = mapMetadata(MD);
429 return getVM()[
V] =
const_cast<Value *
>(
V);
440 return mapBlockAddress(*BA);
442 if (
const auto *
E = dyn_cast<DSOLocalEquivalent>(
C)) {
443 auto *Val = mapValue(
E->getGlobalValue());
448 auto *
Func = cast<Function>(Val->stripPointerCastsAndAliases());
449 Type *NewTy =
E->getType();
456 if (
const auto *
NC = dyn_cast<NoCFIValue>(
C)) {
457 auto *Val = mapValue(
NC->getGlobalValue());
462 auto mapValueOrNull = [
this](
Value *
V) {
463 auto Mapped = mapValue(V);
465 "Unexpected null mapping for constant operand without "
466 "NullMapMissingGlobalValues flag");
472 unsigned OpNo = 0, NumOperands =
C->getNumOperands();
473 Value *Mapped =
nullptr;
474 for (; OpNo != NumOperands; ++OpNo) {
476 Mapped = mapValueOrNull(Op);
484 Type *NewTy =
C->getType();
490 if (OpNo == NumOperands && NewTy ==
C->getType())
491 return getVM()[
V] =
C;
497 for (
unsigned j = 0;
j != OpNo; ++
j)
498 Ops.
push_back(cast<Constant>(
C->getOperand(j)));
501 if (OpNo != NumOperands) {
505 for (++OpNo; OpNo != NumOperands; ++OpNo) {
506 Mapped = mapValueOrNull(
C->getOperand(OpNo));
512 Type *NewSrcTy =
nullptr;
514 if (
auto *GEPO = dyn_cast<GEPOperator>(
C))
515 NewSrcTy = TypeMapper->
remapType(GEPO->getSourceElementType());
518 return getVM()[
V] =
CE->getWithOperands(Ops, NewTy,
false, NewSrcTy);
519 if (isa<ConstantArray>(
C))
521 if (isa<ConstantStruct>(
C))
523 if (isa<ConstantVector>(
C))
526 if (isa<PoisonValue>(
C))
528 if (isa<UndefValue>(
C))
530 if (isa<ConstantAggregateZero>(
C))
532 if (isa<ConstantTargetNone>(
C))
534 assert(isa<ConstantPointerNull>(
C));
546 DelayedBBs.
push_back(DelayedBasicBlock(BA));
547 BB = DelayedBBs.
back().TempBB.get();
556 getVM().MD()[
Key].reset(Val);
561 return mapToMetadata(MD,
const_cast<Metadata *
>(MD));
564std::optional<Metadata *> MDNodeMapper::tryToMapOperand(
const Metadata *Op) {
568 if (std::optional<Metadata *> MappedOp =
M.mapSimpleMetadata(Op)) {
570 if (
auto *CMD = dyn_cast<ConstantAsMetadata>(Op))
571 assert((!*MappedOp ||
M.getVM().count(CMD->getValue()) ||
572 M.getVM().getMappedMD(Op)) &&
573 "Expected Value to be memoized");
575 assert((isa<MDString>(Op) ||
M.getVM().getMappedMD(Op)) &&
576 "Expected result to be memoized");
581 const MDNode &
N = *cast<MDNode>(Op);
583 return mapDistinctNode(
N);
588 assert(
N.isDistinct() &&
"Expected a distinct node");
589 assert(!
M.getVM().getMappedMD(&
N) &&
"Expected an unmapped node");
593 NewM =
M.mapToSelf(&
N);
597 <<
"To " << *NewM <<
"\n\n");
598 M.mapToMetadata(&
N, NewM);
600 DistinctWorklist.push_back(cast<MDNode>(NewM));
602 return DistinctWorklist.back();
612std::optional<Metadata *> MDNodeMapper::getMappedOp(
const Metadata *Op)
const {
616 if (std::optional<Metadata *> MappedOp =
M.getVM().getMappedMD(Op))
619 if (isa<MDString>(Op))
622 if (
auto *CMD = dyn_cast<ConstantAsMetadata>(Op))
628Metadata &MDNodeMapper::UniquedGraph::getFwdReference(
MDNode &Op) {
629 auto Where =
Info.find(&Op);
630 assert(Where !=
Info.end() &&
"Expected a valid reference");
632 auto &OpD = Where->second;
637 if (!OpD.Placeholder)
638 OpD.Placeholder =
Op.clone();
640 return *OpD.Placeholder;
643template <
class OperandMapper>
644void MDNodeMapper::remapOperands(
MDNode &
N, OperandMapper mapOperand) {
645 assert(!
N.isUniqued() &&
"Expected distinct or temporary nodes");
646 for (
unsigned I = 0,
E =
N.getNumOperands();
I !=
E; ++
I) {
650 LLVM_DEBUG(
dbgs() <<
"Replacing Op " << Old <<
" with " << New <<
" in "
654 N.replaceOperandWith(
I, New);
661struct POTWorklistEntry {
667 bool HasChanged =
false;
669 POTWorklistEntry(
MDNode &
N) :
N(&
N),
Op(
N.op_begin()) {}
674bool MDNodeMapper::createPOT(UniquedGraph &
G,
const MDNode &FirstN) {
675 assert(
G.Info.empty() &&
"Expected a fresh traversal");
679 bool AnyChanges =
false;
682 (void)
G.Info[&FirstN];
683 while (!Worklist.
empty()) {
685 auto &WE = Worklist.
back();
686 if (
MDNode *
N = visitOperands(
G, WE.Op, WE.N->op_end(), WE.HasChanged)) {
693 assert(WE.N->isUniqued() &&
"Expected only uniqued nodes");
694 assert(WE.Op == WE.N->op_end() &&
"Expected to visit all operands");
695 auto &
D =
G.Info[WE.N];
696 AnyChanges |=
D.HasChanged = WE.HasChanged;
698 G.POT.push_back(WE.N);
710 if (std::optional<Metadata *> MappedOp = tryToMapOperand(Op)) {
712 HasChanged |=
Op != *MappedOp;
717 MDNode &OpN = *cast<MDNode>(Op);
719 "Only uniqued operands cannot be mapped immediately");
720 if (
G.Info.insert(std::make_pair(&OpN,
Data())).second)
726void MDNodeMapper::UniquedGraph::propagateChanges() {
736 auto Where = Info.find(Op);
737 return Where != Info.end() && Where->second.HasChanged;
741 AnyChanges =
D.HasChanged =
true;
743 }
while (AnyChanges);
746void MDNodeMapper::mapNodesInPOT(UniquedGraph &
G) {
749 for (
auto *
N :
G.POT) {
758 bool HadPlaceholder(
D.Placeholder);
761 TempMDNode ClonedN =
D.Placeholder ? std::move(
D.Placeholder) :
N->clone();
762 remapOperands(*ClonedN, [
this, &
D, &
G](
Metadata *Old) {
763 if (std::optional<Metadata *> MappedOp =
getMappedOp(Old))
766 assert(
G.Info[Old].ID >
D.ID &&
"Expected a forward reference");
767 return &
G.getFwdReference(*cast<MDNode>(Old));
771 if (
N && NewN &&
N != NewN) {
773 <<
"To " << *NewN <<
"\n\n");
776 M.mapToMetadata(
N, NewN);
785 for (
auto *
N : CyclicNodes)
786 if (!
N->isResolved())
791 assert(DistinctWorklist.empty() &&
"MDNodeMapper::map is not recursive");
793 "MDNodeMapper::map assumes module-level changes");
796 assert(
N.isResolved() &&
"Unexpected unresolved node");
799 N.isUniqued() ? mapTopLevelUniquedNode(
N) : mapDistinctNode(
N);
800 while (!DistinctWorklist.empty())
801 remapOperands(*DistinctWorklist.pop_back_val(), [
this](
Metadata *Old) {
802 if (std::optional<Metadata *> MappedOp = tryToMapOperand(Old))
804 return mapTopLevelUniquedNode(*cast<MDNode>(Old));
809Metadata *MDNodeMapper::mapTopLevelUniquedNode(
const MDNode &FirstN) {
814 if (!createPOT(
G, FirstN)) {
818 return &
const_cast<MDNode &
>(FirstN);
822 G.propagateChanges();
831std::optional<Metadata *> Mapper::mapSimpleMetadata(
const Metadata *MD) {
833 if (std::optional<Metadata *> NewMD = getVM().getMappedMD(MD))
836 if (isa<MDString>(MD))
844 if (
auto *CMD = dyn_cast<ConstantAsMetadata>(MD)) {
852 assert(isa<MDNode>(MD) &&
"Expected a metadata node");
858 assert(MD &&
"Expected valid metadata");
859 assert(!isa<LocalAsMetadata>(MD) &&
"Unexpected local metadata");
861 if (std::optional<Metadata *> NewMD = mapSimpleMetadata(MD))
864 return MDNodeMapper(*this).map(*cast<MDNode>(MD));
867void Mapper::flush() {
869 while (!Worklist.
empty()) {
871 CurrentMCID =
E.MCID;
873 case WorklistEntry::MapGlobalInit:
874 E.Data.GVInit.GV->setInitializer(mapConstant(
E.Data.GVInit.Init));
875 remapGlobalObjectMetadata(*
E.Data.GVInit.GV);
877 case WorklistEntry::MapAppendingVar: {
878 unsigned PrefixSize = AppendingInits.
size() -
E.AppendingGVNumNewMembers;
884 AppendingInits.
resize(PrefixSize);
885 mapAppendingVariable(*
E.Data.AppendingGV.GV,
886 E.Data.AppendingGV.InitPrefix,
887 E.AppendingGVIsOldCtorDtor,
ArrayRef(NewInits));
890 case WorklistEntry::MapAliasOrIFunc: {
893 if (
auto *GA = dyn_cast<GlobalAlias>(GV))
895 else if (
auto *GI = dyn_cast<GlobalIFunc>(GV))
901 case WorklistEntry::RemapFunction:
902 remapFunction(*
E.Data.RemapF);
910 while (!DelayedBBs.
empty()) {
912 BasicBlock *BB = cast_or_null<BasicBlock>(mapValue(DBB.OldBB));
913 DBB.TempBB->replaceAllUsesWith(BB ? BB : DBB.OldBB);
919 for (
Use &Op :
I->operands()) {
926 "Referenced value not in value map!");
930 if (
PHINode *PN = dyn_cast<PHINode>(
I)) {
931 for (
unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
932 Value *
V = mapValue(PN->getIncomingBlock(i));
935 PN->setIncomingBlock(i, cast<BasicBlock>(V));
938 "Referenced block not in value map!");
944 I->getAllMetadata(MDs);
945 for (
const auto &
MI : MDs) {
947 MDNode *
New = cast_or_null<MDNode>(mapMetadata(Old));
949 I->setMetadata(
MI.first, New);
956 if (
auto *CB = dyn_cast<CallBase>(
I)) {
959 Tys.
reserve(FTy->getNumParams());
960 for (
Type *Ty : FTy->params())
963 TypeMapper->
remapType(
I->getType()), Tys, FTy->isVarArg()));
967 for (
unsigned i = 0; i <
Attrs.getNumAttrSets(); ++i) {
968 for (
int AttrIdx = Attribute::FirstTypeAttr;
969 AttrIdx <= Attribute::LastTypeAttr; AttrIdx++) {
972 Attrs.getAttributeAtIndex(i, TypedAttr).getValueAsType()) {
973 Attrs =
Attrs.replaceAttributeTypeAtIndex(
C, i, TypedAttr,
979 CB->setAttributes(Attrs);
982 if (
auto *AI = dyn_cast<AllocaInst>(
I))
983 AI->setAllocatedType(TypeMapper->
remapType(AI->getAllocatedType()));
984 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(
I)) {
985 GEP->setSourceElementType(
987 GEP->setResultElementType(
990 I->mutateType(TypeMapper->
remapType(
I->getType()));
993void Mapper::remapGlobalObjectMetadata(
GlobalObject &GO) {
997 for (
const auto &
I : MDs)
998 GO.
addMetadata(
I.first, *cast<MDNode>(mapMetadata(
I.second)));
1001void Mapper::remapFunction(
Function &
F) {
1003 for (
Use &Op :
F.operands())
1008 remapGlobalObjectMetadata(
F);
1018 remapInstruction(&
I);
1026 unsigned NumElements =
1027 cast<ArrayType>(InitPrefix->
getType())->getNumElements();
1028 for (
unsigned I = 0;
I != NumElements; ++
I)
1034 if (IsOldCtorDtor) {
1038 auto &
ST = *cast<StructType>(NewMembers.
front()->getType());
1039 Type *Tys[3] = {
ST.getElementType(0),
ST.getElementType(1), VoidPtrTy};
1043 for (
auto *V : NewMembers) {
1045 if (IsOldCtorDtor) {
1046 auto *S = cast<ConstantStruct>(V);
1047 auto *E1 = cast<Constant>(mapValue(S->getOperand(0)));
1048 auto *E2 = cast<Constant>(mapValue(S->getOperand(1)));
1052 NewV = cast_or_null<Constant>(mapValue(V));
1063 assert(AlreadyScheduled.
insert(&GV).second &&
"Should not reschedule");
1064 assert(MCID < MCs.
size() &&
"Invalid mapping context");
1067 WE.Kind = WorklistEntry::MapGlobalInit;
1069 WE.Data.GVInit.GV = &GV;
1070 WE.Data.GVInit.Init = &
Init;
1079 assert(AlreadyScheduled.
insert(&GV).second &&
"Should not reschedule");
1080 assert(MCID < MCs.
size() &&
"Invalid mapping context");
1083 WE.Kind = WorklistEntry::MapAppendingVar;
1085 WE.Data.AppendingGV.GV = &GV;
1086 WE.Data.AppendingGV.InitPrefix = InitPrefix;
1087 WE.AppendingGVIsOldCtorDtor = IsOldCtorDtor;
1088 WE.AppendingGVNumNewMembers = NewMembers.
size();
1095 assert(AlreadyScheduled.
insert(&GV).second &&
"Should not reschedule");
1096 assert((isa<GlobalAlias>(GV) || isa<GlobalIFunc>(GV)) &&
1097 "Should be alias or ifunc");
1098 assert(MCID < MCs.
size() &&
"Invalid mapping context");
1101 WE.Kind = WorklistEntry::MapAliasOrIFunc;
1103 WE.Data.AliasOrIFunc.GV = &GV;
1104 WE.Data.AliasOrIFunc.Target = &
Target;
1108void Mapper::scheduleRemapFunction(
Function &
F,
unsigned MCID) {
1109 assert(AlreadyScheduled.
insert(&
F).second &&
"Should not reschedule");
1110 assert(MCID < MCs.
size() &&
"Invalid mapping context");
1113 WE.Kind = WorklistEntry::RemapFunction;
1115 WE.Data.RemapF = &
F;
1120 assert(!hasWorkToDo() &&
"Expected to have flushed the worklist");
1121 this->Flags = this->Flags |
Flags;
1125 return reinterpret_cast<Mapper *
>(pImpl);
1130class FlushingMapper {
1134 explicit FlushingMapper(
void *pImpl) :
M(*
getAsMapper(pImpl)) {
1135 assert(!
M.hasWorkToDo() &&
"Expected to be flushed");
1138 ~FlushingMapper() {
M.flush(); }
1140 Mapper *operator->()
const {
return &
M; }
1148 : pImpl(new Mapper(VM,
Flags, TypeMapper, Materializer)) {}
1155 return getAsMapper(pImpl)->registerAlternateMappingContext(VM, Materializer);
1159 FlushingMapper(pImpl)->addFlags(
Flags);
1163 return FlushingMapper(pImpl)->mapValue(&V);
1167 return cast_or_null<Constant>(
mapValue(
C));
1171 return FlushingMapper(pImpl)->mapMetadata(&MD);
1179 FlushingMapper(pImpl)->remapInstruction(&
I);
1183 FlushingMapper(pImpl)->remapFunction(
F);
1187 FlushingMapper(pImpl)->remapGlobalObjectMetadata(GO);
1202 GV, InitPrefix, IsOldCtorDtor, NewMembers, MCID);
1207 getAsMapper(pImpl)->scheduleMapAliasOrIFunc(GA, Aliasee, MCID);
static unsigned getMappedOp(unsigned PseudoOp)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
This file contains the declaration of the GlobalIFunc class, which represents a single indirect funct...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
static Mapper * getAsMapper(void *pImpl)
static ConstantAsMetadata * wrapConstantAsMetadata(const ConstantAsMetadata &CMD, Value *MappedV)
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
front - Get the first element.
size_t size() const
size - Get the array size.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
LLVM Basic Block Representation.
The address of a basic block.
Function * getFunction() const
BasicBlock * getBasicBlock() const
static BlockAddress * get(Function *F, BasicBlock *BB)
Return a BlockAddress for the specified function and basic block.
static ConstantAggregateZero * get(Type *Ty)
static Constant * get(ArrayType *T, ArrayRef< Constant * > V)
A constant value that is initialized with an expression using other constant values.
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
static Constant * get(StructType *T, ArrayRef< Constant * > V)
static Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
static DSOLocalEquivalent * get(GlobalValue *GV)
Return a DSOLocalEquivalent for the specified global value.
Implements a dense probed hash-table based set.
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
void getAllMetadata(SmallVectorImpl< std::pair< unsigned, MDNode * > > &MDs) const
Appends all metadata attached to this value to MDs, sorting by KindID.
void addMetadata(unsigned KindID, MDNode &MD)
Add a metadata attachment.
void clearMetadata()
Erase all metadata attached to this Value.
Type * getValueType() const
void setInitializer(Constant *InitVal)
setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...
static InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT, bool canThrow=false)
InlineAsm::get - Return the specified uniqued inline asm string.
This is an important class for using LLVM in a threaded context.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static std::enable_if_t< std::is_base_of< MDNode, T >::value, T * > replaceWithDistinct(std::unique_ptr< T, TempMDNodeDeleter > N)
Replace a temporary node with a distinct one.
static std::enable_if_t< std::is_base_of< MDNode, T >::value, T * > replaceWithUniqued(std::unique_ptr< T, TempMDNodeDeleter > N)
Replace a temporary node with a uniqued one.
Tracking metadata reference owned by Metadata.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static NoCFIValue * get(GlobalValue *GV)
Return a NoCFIValue for the specified function.
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
static IntegerType * getInt8Ty(LLVMContext &C)
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
This is a class that can be implemented by clients to remap types when cloning constants and instruct...
virtual Type * remapType(Type *SrcTy)=0
The client should implement this method if they want to remap types while mapping values.
MDNode * mapMDNode(const MDNode &N)
Metadata * mapMetadata(const Metadata &MD)
void remapInstruction(Instruction &I)
void scheduleMapGlobalInitializer(GlobalVariable &GV, Constant &Init, unsigned MappingContextID=0)
void scheduleRemapFunction(Function &F, unsigned MappingContextID=0)
void scheduleMapGlobalIFunc(GlobalIFunc &GI, Constant &Resolver, unsigned MappingContextID=0)
unsigned registerAlternateMappingContext(ValueToValueMapTy &VM, ValueMaterializer *Materializer=nullptr)
Register an alternate mapping context.
void remapFunction(Function &F)
Constant * mapConstant(const Constant &C)
ValueMapper(ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
void scheduleMapAppendingVariable(GlobalVariable &GV, Constant *InitPrefix, bool IsOldCtorDtor, ArrayRef< Constant * > NewMembers, unsigned MappingContextID=0)
void scheduleMapGlobalAlias(GlobalAlias &GA, Constant &Aliasee, unsigned MappingContextID=0)
void remapGlobalObjectMetadata(GlobalObject &GO)
Value * mapValue(const Value &V)
void addFlags(RemapFlags Flags)
Add to the current RemapFlags.
This is a class that can be implemented by clients to materialize Values on demand.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVMContext & getContext() const
All values hold a context through their type.
std::pair< iterator, bool > insert(const ValueT &V)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
@ C
The default llvm calling convention, compatible with C.
@ CE
Windows NT (Windows on ARM)
const_iterator end(StringRef path)
Get end iterator over path.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
RemapFlags
These are flags that the value mapping APIs allow.
@ RF_IgnoreMissingLocals
If this flag is set, the remapper ignores missing function-local entries (Argument,...
@ RF_NullMapMissingGlobalValues
Any global values not in value map are mapped to null instead of mapping to self.
@ RF_NoModuleLevelChanges
If this flag is set, the remapper knows that only local values within a function (such as an instruct...
@ RF_ReuseAndMutateDistinctMDs
Instruct the remapper to reuse and mutate distinct metadata (remapping them in place) instead of clon...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
void RemapFunction(Function &F, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
Remap the operands, metadata, arguments, and instructions of a function.