50 void ValueMapTypeRemapper::anchor() {}
51 void ValueMaterializer::anchor() {}
57 struct DelayedBasicBlock {
59 std::unique_ptr<BasicBlock> TempBB;
62 : OldBB(Old.getBasicBlock()),
63 TempBB(
BasicBlock::Create(Old.getContext())) {}
66 struct WorklistEntry {
77 struct AppendingGVTy {
81 struct GlobalAliaseeTy {
88 unsigned AppendingGVIsOldCtorDtor : 1;
89 unsigned AppendingGVNumNewMembers;
92 AppendingGVTy AppendingGV;
93 GlobalAliaseeTy GlobalAliasee;
98 struct MappingContext {
105 : VM(&VM), Materializer(Materializer) {}
109 friend class MDNodeMapper;
117 unsigned CurrentMCID = 0;
126 : Flags(Flags), TypeMapper(TypeMapper),
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);
196 bool HasChanged =
false;
198 TempMDNode Placeholder;
202 struct UniquedGraph {
210 void propagateChanges();
224 MDNodeMapper(Mapper &M) : M(M) {}
304 bool createPOT(UniquedGraph &
G,
const MDNode &FirstN);
326 void mapNodesInPOT(UniquedGraph &
G);
334 template <
class OperandMapper>
335 void remapOperands(
MDNode &
N, OperandMapper mapOperand);
344 if (I != getVM().
end()) {
350 if (
auto *Materializer = getMaterializer()) {
351 if (
Value *NewV = Materializer->materialize(const_cast<Value *>(V))) {
359 if (isa<GlobalValue>(V)) {
362 return getVM()[V] =
const_cast<Value *
>(V);
365 if (
const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
369 NewTy = cast<FunctionType>(TypeMapper->
remapType(NewTy));
371 if (NewTy != IA->getFunctionType())
372 V =
InlineAsm::get(NewTy, IA->getAsmString(), IA->getConstraintString(),
373 IA->hasSideEffects(), IA->isAlignStack());
376 return getVM()[V] =
const_cast<Value *
>(V);
379 if (
const auto *MDV = dyn_cast<MetadataAsValue>(V)) {
380 const Metadata *MD = MDV->getMetadata();
382 if (
auto *LAM = dyn_cast<LocalAsMetadata>(MD)) {
384 if (
Value *LV = mapValue(LAM->getValue())) {
385 if (V == LAM->getValue())
386 return const_cast<Value *>(V);
401 return getVM()[V] =
const_cast<Value *
>(V);
404 auto *MappedMD = mapMetadata(MD);
406 return getVM()[V] =
const_cast<Value *
>(V);
417 return mapBlockAddress(*BA);
419 auto mapValueOrNull = [
this](
Value *V) {
420 auto Mapped = mapValue(V);
422 "Unexpected null mapping for constant operand without " 423 "NullMapMissingGlobalValues flag");
429 unsigned OpNo = 0, NumOperands = C->getNumOperands();
430 Value *Mapped =
nullptr;
431 for (; OpNo != NumOperands; ++OpNo) {
432 Value *
Op = C->getOperand(OpNo);
433 Mapped = mapValueOrNull(Op);
441 Type *NewTy = C->getType();
447 if (OpNo == NumOperands && NewTy == C->getType())
448 return getVM()[V] =
C;
454 for (
unsigned j = 0; j != OpNo; ++j)
455 Ops.
push_back(cast<Constant>(C->getOperand(j)));
458 if (OpNo != NumOperands) {
462 for (++OpNo; OpNo != NumOperands; ++OpNo) {
463 Mapped = mapValueOrNull(C->getOperand(OpNo));
469 Type *NewSrcTy =
nullptr;
471 if (
auto *GEPO = dyn_cast<GEPOperator>(C))
472 NewSrcTy = TypeMapper->
remapType(GEPO->getSourceElementType());
475 return getVM()[V] =
CE->getWithOperands(Ops, NewTy,
false, NewSrcTy);
476 if (isa<ConstantArray>(C))
478 if (isa<ConstantStruct>(C))
480 if (isa<ConstantVector>(C))
483 if (isa<UndefValue>(C))
485 if (isa<ConstantAggregateZero>(C))
487 assert(isa<ConstantPointerNull>(C));
499 DelayedBBs.
push_back(DelayedBasicBlock(BA));
500 BB = DelayedBBs.
back().TempBB.get();
509 getVM().MD()[
Key].reset(Val);
514 return mapToMetadata(MD, const_cast<Metadata *>(MD));
523 if (
auto *CMD = dyn_cast<ConstantAsMetadata>(Op))
524 assert((!*MappedOp ||
M.getVM().count(CMD->getValue()) ||
525 M.getVM().getMappedMD(Op)) &&
526 "Expected Value to be memoized");
528 assert((isa<MDString>(Op) ||
M.getVM().getMappedMD(Op)) &&
529 "Expected result to be memoized");
536 return mapDistinctNode(N);
544 if (CT && CT->getContext().isODRUniquingDebugTypes() &&
545 CT->getIdentifier() !=
"")
546 return const_cast<DICompositeType *>(CT);
550 MDNode *MDNodeMapper::mapDistinctNode(
const MDNode &N) {
552 assert(!M.getVM().getMappedMD(&N) &&
"Expected an unmapped node");
553 DistinctWorklist.push_back(
557 return DistinctWorklist.back();
563 return const_cast<ConstantAsMetadata *>(&CMD);
574 if (isa<MDString>(Op))
575 return const_cast<Metadata *>(Op);
577 if (
auto *CMD = dyn_cast<ConstantAsMetadata>(Op))
583 Metadata &MDNodeMapper::UniquedGraph::getFwdReference(
MDNode &Op) {
584 auto Where =
Info.find(&Op);
585 assert(Where !=
Info.end() &&
"Expected a valid reference");
587 auto &OpD = Where->second;
592 if (!OpD.Placeholder)
593 OpD.Placeholder = Op.
clone();
595 return *OpD.Placeholder;
598 template <
class OperandMapper>
599 void MDNodeMapper::remapOperands(
MDNode &N, OperandMapper mapOperand) {
613 struct POTWorklistEntry {
619 bool HasChanged =
false;
626 bool MDNodeMapper::createPOT(UniquedGraph &
G,
const MDNode &FirstN) {
627 assert(G.Info.empty() &&
"Expected a fresh traversal");
631 bool AnyChanges =
false;
633 Worklist.
push_back(POTWorklistEntry(const_cast<MDNode &>(FirstN)));
634 (void)G.Info[&FirstN];
635 while (!Worklist.
empty()) {
637 auto &WE = Worklist.
back();
638 if (
MDNode *N = visitOperands(G, WE.Op, WE.N->op_end(), WE.HasChanged)) {
640 Worklist.
push_back(POTWorklistEntry(*N));
645 assert(WE.N->isUniqued() &&
"Expected only uniqued nodes");
646 assert(WE.Op == WE.N->op_end() &&
"Expected to visit all operands");
647 auto &
D = G.Info[WE.N];
648 AnyChanges |= D.HasChanged = WE.HasChanged;
650 G.POT.push_back(WE.N);
664 HasChanged |= Op != *MappedOp;
671 "Only uniqued operands cannot be mapped immediately");
672 if (G.Info.insert(std::make_pair(&OpN,
Data())).second)
678 void MDNodeMapper::UniquedGraph::propagateChanges() {
688 auto Where =
Info.find(Op);
689 return Where !=
Info.end() && Where->second.HasChanged;
693 AnyChanges =
D.HasChanged =
true;
695 }
while (AnyChanges);
698 void MDNodeMapper::mapNodesInPOT(UniquedGraph &G) {
701 for (
auto *N : G.POT) {
710 bool HadPlaceholder(
D.Placeholder);
713 TempMDNode ClonedN =
D.Placeholder ? std::move(
D.Placeholder) : N->
clone();
714 remapOperands(*ClonedN, [
this, &
D, &G](
Metadata *Old) {
718 assert(G.Info[Old].ID >
D.ID &&
"Expected a forward reference");
719 return &G.getFwdReference(*cast<MDNode>(Old));
723 M.mapToMetadata(N, NewN);
732 for (
auto *N : CyclicNodes)
738 assert(DistinctWorklist.empty() &&
"MDNodeMapper::map is not recursive");
739 assert(!(M.Flags & RF_NoModuleLevelChanges) &&
740 "MDNodeMapper::map assumes module-level changes");
746 N.
isUniqued() ? mapTopLevelUniquedNode(N) : mapDistinctNode(N);
747 while (!DistinctWorklist.empty())
748 remapOperands(*DistinctWorklist.pop_back_val(), [
this](
Metadata *Old) {
751 return mapTopLevelUniquedNode(*cast<MDNode>(Old));
756 Metadata *MDNodeMapper::mapTopLevelUniquedNode(
const MDNode &FirstN) {
761 if (!createPOT(G, FirstN)) {
763 for (
const MDNode *N : G.POT)
765 return &
const_cast<MDNode &
>(FirstN);
769 G.propagateChanges();
780 struct MapMetadataDisabler {
797 if (isa<MDString>(MD))
802 if ((Flags & RF_NoModuleLevelChanges))
803 return const_cast<Metadata *>(MD);
805 if (
auto *CMD = dyn_cast<ConstantAsMetadata>(MD)) {
807 MapMetadataDisabler MMD(getVM());
816 assert(isa<MDNode>(MD) &&
"Expected a metadata node");
822 assert(MD &&
"Expected valid metadata");
823 assert(!isa<LocalAsMetadata>(MD) &&
"Unexpected local metadata");
828 return MDNodeMapper(*this).map(*cast<MDNode>(MD));
831 void Mapper::flush() {
833 while (!Worklist.
empty()) {
835 CurrentMCID = E.MCID;
837 case WorklistEntry::MapGlobalInit:
838 E.Data.GVInit.GV->setInitializer(mapConstant(E.Data.GVInit.Init));
839 remapGlobalObjectMetadata(*E.Data.GVInit.GV);
841 case WorklistEntry::MapAppendingVar: {
842 unsigned PrefixSize = AppendingInits.
size() - E.AppendingGVNumNewMembers;
843 mapAppendingVariable(*E.Data.AppendingGV.GV,
844 E.Data.AppendingGV.InitPrefix,
845 E.AppendingGVIsOldCtorDtor,
847 AppendingInits.
resize(PrefixSize);
850 case WorklistEntry::MapGlobalAliasee:
851 E.Data.GlobalAliasee.GA->setAliasee(
852 mapConstant(E.Data.GlobalAliasee.Aliasee));
855 remapFunction(*E.Data.RemapF);
863 while (!DelayedBBs.
empty()) {
865 BasicBlock *BB = cast_or_null<BasicBlock>(mapValue(DBB.OldBB));
866 DBB.TempBB->replaceAllUsesWith(BB ? BB : DBB.OldBB);
873 Value *V = mapValue(Op);
878 assert((Flags & RF_IgnoreMissingLocals) &&
879 "Referenced value not in value map!");
883 if (
PHINode *PN = dyn_cast<PHINode>(I)) {
884 for (
unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
885 Value *V = mapValue(PN->getIncomingBlock(i));
888 PN->setIncomingBlock(i, cast<BasicBlock>(V));
890 assert((Flags & RF_IgnoreMissingLocals) &&
891 "Referenced block not in value map!");
898 for (
const auto &
MI : MDs) {
900 MDNode *New = cast_or_null<MDNode>(mapMetadata(Old));
919 if (
auto *AI = dyn_cast<AllocaInst>(I))
920 AI->setAllocatedType(TypeMapper->
remapType(AI->getAllocatedType()));
921 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(I)) {
922 GEP->setSourceElementType(
924 GEP->setResultElementType(
930 void Mapper::remapGlobalObjectMetadata(
GlobalObject &GO) {
934 for (
const auto &I : MDs)
935 GO.
addMetadata(I.first, *cast<MDNode>(mapMetadata(I.second)));
938 void Mapper::remapFunction(
Function &F) {
945 remapGlobalObjectMetadata(F);
950 A.mutateType(TypeMapper->
remapType(A.getType()));
963 unsigned NumElements =
964 cast<ArrayType>(InitPrefix->
getType())->getNumElements();
965 for (
unsigned I = 0; I != NumElements; ++
I)
976 Type *Tys[3] = {
ST.getElementType(0),
ST.getElementType(1), VoidPtrTy};
980 for (
auto *V : NewMembers) {
983 auto *S = cast<ConstantStruct>(V);
984 auto *E1 = cast<Constant>(mapValue(S->getOperand(0)));
985 auto *E2 = cast<Constant>(mapValue(S->getOperand(1)));
989 NewV = cast_or_null<Constant>(mapValue(V));
1000 assert(AlreadyScheduled.
insert(&GV).second &&
"Should not reschedule");
1001 assert(MCID < MCs.
size() &&
"Invalid mapping context");
1004 WE.Kind = WorklistEntry::MapGlobalInit;
1006 WE.Data.GVInit.GV = &GV;
1007 WE.Data.GVInit.Init = &Init;
1016 assert(AlreadyScheduled.
insert(&GV).second &&
"Should not reschedule");
1017 assert(MCID < MCs.
size() &&
"Invalid mapping context");
1020 WE.Kind = WorklistEntry::MapAppendingVar;
1022 WE.Data.AppendingGV.GV = &GV;
1023 WE.Data.AppendingGV.InitPrefix = InitPrefix;
1024 WE.AppendingGVIsOldCtorDtor = IsOldCtorDtor;
1025 WE.AppendingGVNumNewMembers = NewMembers.
size();
1032 assert(AlreadyScheduled.
insert(&GA).second &&
"Should not reschedule");
1033 assert(MCID < MCs.
size() &&
"Invalid mapping context");
1036 WE.Kind = WorklistEntry::MapGlobalAliasee;
1038 WE.Data.GlobalAliasee.GA = &GA;
1039 WE.Data.GlobalAliasee.Aliasee = &Aliasee;
1043 void Mapper::scheduleRemapFunction(
Function &F,
unsigned MCID) {
1044 assert(AlreadyScheduled.
insert(&F).second &&
"Should not reschedule");
1045 assert(MCID < MCs.
size() &&
"Invalid mapping context");
1050 WE.Data.RemapF = &
F;
1055 assert(!hasWorkToDo() &&
"Expected to have flushed the worklist");
1056 this->Flags = this->Flags | Flags;
1060 return reinterpret_cast<Mapper *
>(pImpl);
1065 class FlushingMapper {
1069 explicit FlushingMapper(
void *pImpl) : M(*
getAsMapper(pImpl)) {
1070 assert(!M.hasWorkToDo() &&
"Expected to be flushed");
1073 ~FlushingMapper() { M.flush(); }
1075 Mapper *operator->()
const {
return &M; }
1083 : pImpl(new Mapper(VM, Flags, TypeMapper, Materializer)) {}
1090 return getAsMapper(pImpl)->registerAlternateMappingContext(VM, Materializer);
1094 FlushingMapper(pImpl)->addFlags(Flags);
1098 return FlushingMapper(pImpl)->mapValue(&V);
1102 return cast_or_null<Constant>(
mapValue(C));
1106 return FlushingMapper(pImpl)->mapMetadata(&MD);
1114 FlushingMapper(pImpl)->remapInstruction(&I);
1118 FlushingMapper(pImpl)->remapFunction(F);
1124 getAsMapper(pImpl)->scheduleMapGlobalInitializer(GV, Init, MCID);
1133 GV, InitPrefix, IsOldCtorDtor, NewMembers, MCID);
1138 getAsMapper(pImpl)->scheduleMapGlobalAliasee(GA, Aliasee, MCID);
1142 getAsMapper(pImpl)->scheduleRemapFunction(F, MCID);
const T & front() const
front - Get the first element.
static unsigned getMappedOp(unsigned PseudoOp)
const_iterator end(StringRef path)
Get end iterator over path.
Tracking metadata reference owned by Metadata.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata *> MDs)
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
This class represents an incoming formal argument to a Function.
This class represents lattice values for constants.
void replaceOperandWith(unsigned I, Metadata *New)
Replace a specific operand.
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.
Implements a dense probed hash-table based set.
void push_back(const T &Elt)
Any global values not in value map are mapped to null instead of mapping to self. ...
static ConstantAggregateZero * get(Type *Ty)
LLVMContext & getContext() const
All values hold a context through their type.
void scheduleRemapFunction(Function &F, unsigned MappingContextID=0)
const MDOperand & getOperand(unsigned I) const
void getAllMetadata(SmallVectorImpl< std::pair< unsigned, MDNode *>> &MDs) const
Appends all attachments for the global to MDs, sorting by attachment ID.
void reserve(size_type N)
static Mapper * getAsMapper(void *pImpl)
static Constant * get(ArrayType *T, ArrayRef< Constant *> V)
TempMDNode clone() const
Create a (temporary) clone of this.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
static std::enable_if< std::is_base_of< MDNode, T >::value, T * >::type replaceWithDistinct(std::unique_ptr< T, TempMDNodeDeleter > N)
Replace a temporary node with a distinct one.
Function * getFunction() const
The address of a basic block.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
void setInitializer(Constant *InitVal)
setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...
bool isResolved() const
Check if node is fully resolved.
void remapInstruction(Instruction &I)
A Use represents the edge between a Value definition and its users.
Constant * mapConstant(const Constant &C)
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly...
Windows NT (Windows on ARM)
static StructType * get(LLVMContext &Context, ArrayRef< Type *> Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
void resolveCycles()
Resolve cycles.
op_iterator op_begin() const
A constant value that is initialized with an expression using other constant values.
Class to represent function types.
Metadata * mapMetadata(const Metadata &MD)
Instruct the remapper to move distinct metadata instead of duplicating it when there are module-level...
Type * getType() const
All values are typed, get the type of this value.
op_range operands() const
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
BasicBlock * getBasicBlock() const
If this flag is set, the remapper knows that only local values within a function (such as an instruct...
Analysis containing CSE Info
Class to represent pointers.
void remapInstruction(Instruction *I, ValueToValueMapTy &VMap)
Convert the instruction operands from referencing the current values into those specified by VMap...
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
static Metadata * cloneOrBuildODR(const MDNode &N)
This is a class that can be implemented by clients to materialize Values on demand.
static std::enable_if< std::is_base_of< MDNode, T >::value, T * >::type replaceWithUniqued(std::unique_ptr< T, TempMDNodeDeleter > N)
Replace a temporary node with a uniqued one.
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
static ConstantAsMetadata * wrapConstantAsMetadata(const ConstantAsMetadata &CMD, Value *MappedV)
static BlockAddress * get(Function *F, BasicBlock *BB)
Return a BlockAddress for the specified function and basic block.
size_t size() const
size - Get the array size.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
std::pair< iterator, bool > insert(const ValueT &V)
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
ArrayRef< Type * > params() const
void scheduleMapGlobalInitializer(GlobalVariable &GV, Constant &Init, unsigned MappingContextID=0)
static FunctionType * get(Type *Result, ArrayRef< Type *> Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Constant * get(StructType *T, ArrayRef< Constant *> V)
void disableMapMetadata()
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
RemapFlags
These are flags that the value mapping APIs allow.
void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
void addMetadata(unsigned KindID, MDNode &MD)
Add a metadata attachment.
LLVM_NODISCARD T pop_back_val()
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
void remapFunction(Function &F)
void scheduleMapGlobalAliasee(GlobalAlias &GA, Constant &Aliasee, unsigned MappingContextID=0)
void getAllMetadata(SmallVectorImpl< std::pair< unsigned, MDNode *>> &MDs) const
Get all metadata attached to this Instruction.
ValueMapper(ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
This is a class that can be implemented by clients to remap types when cloning constants and instruct...
If this flag is set, the remapper ignores missing function-local entries (Argument, Instruction, BasicBlock) that are not in the value map.
LLVM_NODISCARD bool empty() const
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void addFlags(RemapFlags Flags)
Add to the current RemapFlags.
static InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT)
InlineAsm::get - Return the specified uniqued inline asm string.
void mutateType(Type *Ty)
Mutate the type of this Value to be of the specified type.
Value * mapValue(const Value &V)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
unsigned registerAlternateMappingContext(ValueToValueMapTy &VM, ValueMaterializer *Materializer=nullptr)
Register an alternate mapping context.
void scheduleMapAppendingVariable(GlobalVariable &GV, Constant *InitPrefix, bool IsOldCtorDtor, ArrayRef< Constant *> NewMembers, unsigned MappingContextID=0)
virtual Type * remapType(Type *SrcTy)=0
The client should implement this method if they want to remap types while mapping values...
unsigned getNumOperands() const
Return number of MDNode operands.
static IntegerType * getInt8Ty(LLVMContext &C)
static Constant * get(ArrayRef< Constant *> V)
Type * getElementType() const
PointerType * getType() const
Global values are always pointers.
iterator_range< arg_iterator > args()
MDNode * mapMDNode(const MDNode &N)