48 void ValueMapTypeRemapper::anchor() {}
49 void ValueMaterializer::anchor() {}
55 struct DelayedBasicBlock {
57 std::unique_ptr<BasicBlock> TempBB;
60 : OldBB(Old.getBasicBlock()),
61 TempBB(
BasicBlock::Create(Old.getContext())) {}
64 struct WorklistEntry {
68 MapGlobalIndirectSymbol,
75 struct AppendingGVTy {
79 struct GlobalIndirectSymbolTy {
86 unsigned AppendingGVIsOldCtorDtor : 1;
87 unsigned AppendingGVNumNewMembers;
90 AppendingGVTy AppendingGV;
96 struct MappingContext {
103 : VM(&VM), Materializer(Materializer) {}
107 friend class MDNodeMapper;
115 unsigned CurrentMCID = 0;
124 : Flags(Flags), TypeMapper(TypeMapper),
125 MCs(1, MappingContext(VM, Materializer)) {}
128 ~Mapper() {
assert(!hasWorkToDo() &&
"Expected to be flushed"); }
130 bool hasWorkToDo()
const {
return !Worklist.
empty(); }
135 MCs.
push_back(MappingContext(VM, Materializer));
136 return MCs.
size() - 1;
148 return cast_or_null<Constant>(mapValue(
C));
165 void scheduleRemapFunction(
Function &
F,
unsigned MCID);
191 bool HasChanged =
false;
193 TempMDNode Placeholder;
197 struct UniquedGraph {
205 void propagateChanges();
219 MDNodeMapper(Mapper &M) :
M(
M) {}
299 bool createPOT(UniquedGraph &
G,
const MDNode &FirstN);
321 void mapNodesInPOT(UniquedGraph &
G);
329 template <
class OperandMapper>
330 void remapOperands(
MDNode &
N, OperandMapper mapOperand);
339 if (
I != getVM().
end()) {
340 assert(
I->second &&
"Unexpected null mapping");
345 if (
auto *Materializer = getMaterializer()) {
346 if (
Value *NewV = Materializer->materialize(const_cast<Value *>(V))) {
354 if (isa<GlobalValue>(V)) {
357 return getVM()[V] = const_cast<Value *>(V);
360 if (
const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
364 NewTy = cast<FunctionType>(TypeMapper->
remapType(NewTy));
366 if (NewTy != IA->getFunctionType())
367 V =
InlineAsm::get(NewTy, IA->getAsmString(), IA->getConstraintString(),
368 IA->hasSideEffects(), IA->isAlignStack(),
372 return getVM()[V] = const_cast<Value *>(V);
375 if (
const auto *MDV = dyn_cast<MetadataAsValue>(V)) {
376 const Metadata *MD = MDV->getMetadata();
378 if (
auto *LAM = dyn_cast<LocalAsMetadata>(MD)) {
380 if (
Value *LV = mapValue(LAM->getValue())) {
381 if (V == LAM->getValue())
382 return const_cast<Value *>(V);
397 return getVM()[V] = const_cast<Value *>(V);
400 auto *MappedMD = mapMetadata(MD);
402 return getVM()[V] = const_cast<Value *>(V);
408 Constant *
C = const_cast<Constant*>(dyn_cast<Constant>(V));
413 return mapBlockAddress(*BA);
415 auto mapValueOrNull = [
this](
Value *V) {
416 auto Mapped = mapValue(V);
418 "Unexpected null mapping for constant operand without " 419 "NullMapMissingGlobalValues flag");
426 Value *Mapped =
nullptr;
427 for (; OpNo != NumOperands; ++OpNo) {
429 Mapped = mapValueOrNull(
Op);
443 if (OpNo == NumOperands && NewTy ==
C->
getType())
444 return getVM()[V] =
C;
450 for (
unsigned j = 0; j != OpNo; ++j)
454 if (OpNo != NumOperands) {
458 for (++OpNo; OpNo != NumOperands; ++OpNo) {
465 Type *NewSrcTy =
nullptr;
467 if (
auto *GEPO = dyn_cast<GEPOperator>(
C))
468 NewSrcTy = TypeMapper->
remapType(GEPO->getSourceElementType());
471 return getVM()[V] =
CE->getWithOperands(Ops, NewTy,
false, NewSrcTy);
472 if (isa<ConstantArray>(
C))
474 if (isa<ConstantStruct>(
C))
476 if (isa<ConstantVector>(
C))
479 if (isa<UndefValue>(
C))
481 if (isa<ConstantAggregateZero>(
C))
483 assert(isa<ConstantPointerNull>(
C));
495 DelayedBBs.
push_back(DelayedBasicBlock(BA));
496 BB = DelayedBBs.
back().TempBB.get();
505 getVM().MD()[
Key].reset(Val);
510 return mapToMetadata(MD, const_cast<Metadata *>(MD));
519 if (
auto *CMD = dyn_cast<ConstantAsMetadata>(
Op))
520 assert((!*MappedOp ||
M.getVM().count(CMD->getValue()) ||
521 M.getVM().getMappedMD(
Op)) &&
522 "Expected Value to be memoized");
524 assert((isa<MDString>(
Op) ||
M.getVM().getMappedMD(
Op)) &&
525 "Expected result to be memoized");
532 return mapDistinctNode(
N);
537 auto *CT = dyn_cast<DICompositeType>(&
N);
540 if (CT && CT->getContext().isODRUniquingDebugTypes() &&
541 CT->getIdentifier() !=
"")
542 return const_cast<DICompositeType *>(CT);
547 assert(
N.isDistinct() &&
"Expected a distinct node");
548 assert(!
M.getVM().getMappedMD(&
N) &&
"Expected an unmapped node");
549 DistinctWorklist.push_back(
553 return DistinctWorklist.back();
559 return const_cast<ConstantAsMetadata *>(&CMD);
570 if (isa<MDString>(
Op))
571 return const_cast<Metadata *>(
Op);
573 if (
auto *CMD = dyn_cast<ConstantAsMetadata>(
Op))
580 auto Where =
Info.find(&
Op);
581 assert(Where !=
Info.end() &&
"Expected a valid reference");
583 auto &OpD = Where->second;
588 if (!OpD.Placeholder)
589 OpD.Placeholder =
Op.clone();
591 return *OpD.Placeholder;
594 template <
class OperandMapper>
595 void MDNodeMapper::remapOperands(
MDNode &
N, OperandMapper mapOperand) {
596 assert(!
N.isUniqued() &&
"Expected distinct or temporary nodes");
597 for (
unsigned I = 0,
E =
N.getNumOperands();
I !=
E; ++
I) {
602 N.replaceOperandWith(
I, New);
609 struct POTWorklistEntry {
615 bool HasChanged =
false;
617 POTWorklistEntry(
MDNode &
N) :
N(&
N),
Op(
N.op_begin()) {}
622 bool MDNodeMapper::createPOT(UniquedGraph &
G,
const MDNode &FirstN) {
623 assert(
G.Info.empty() &&
"Expected a fresh traversal");
627 bool AnyChanges =
false;
629 Worklist.
push_back(POTWorklistEntry(const_cast<MDNode &>(FirstN)));
630 (void)
G.Info[&FirstN];
631 while (!Worklist.
empty()) {
633 auto &WE = Worklist.
back();
634 if (
MDNode *
N = visitOperands(
G, WE.Op, WE.N->op_end(), WE.HasChanged)) {
641 assert(WE.N->isUniqued() &&
"Expected only uniqued nodes");
642 assert(WE.Op == WE.N->op_end() &&
"Expected to visit all operands");
643 auto &
D =
G.Info[WE.N];
644 AnyChanges |=
D.HasChanged = WE.HasChanged;
646 G.POT.push_back(WE.N);
660 HasChanged |=
Op != *MappedOp;
667 "Only uniqued operands cannot be mapped immediately");
668 if (
G.Info.insert(std::make_pair(&OpN,
Data())).second)
674 void MDNodeMapper::UniquedGraph::propagateChanges() {
684 auto Where =
Info.find(
Op);
685 return Where !=
Info.end() && Where->second.HasChanged;
689 AnyChanges =
D.HasChanged =
true;
691 }
while (AnyChanges);
694 void MDNodeMapper::mapNodesInPOT(UniquedGraph &
G) {
697 for (
auto *
N :
G.POT) {
706 bool HadPlaceholder(
D.Placeholder);
709 TempMDNode ClonedN =
D.Placeholder ?
std::move(
D.Placeholder) :
N->clone();
710 remapOperands(*ClonedN, [
this, &
D, &
G](
Metadata *Old) {
714 assert(
G.Info[Old].ID >
D.ID &&
"Expected a forward reference");
715 return &
G.getFwdReference(*cast<MDNode>(Old));
719 M.mapToMetadata(
N, NewN);
728 for (
auto *
N : CyclicNodes)
729 if (!
N->isResolved())
734 assert(DistinctWorklist.empty() &&
"MDNodeMapper::map is not recursive");
736 "MDNodeMapper::map assumes module-level changes");
739 assert(
N.isResolved() &&
"Unexpected unresolved node");
742 N.isUniqued() ? mapTopLevelUniquedNode(
N) : mapDistinctNode(
N);
743 while (!DistinctWorklist.empty())
744 remapOperands(*DistinctWorklist.pop_back_val(), [
this](
Metadata *Old) {
747 return mapTopLevelUniquedNode(*cast<MDNode>(Old));
752 Metadata *MDNodeMapper::mapTopLevelUniquedNode(
const MDNode &FirstN) {
757 if (!createPOT(
G, FirstN)) {
761 return &const_cast<MDNode &>(FirstN);
765 G.propagateChanges();
779 if (isa<MDString>(MD))
780 return const_cast<Metadata *>(MD);
785 return const_cast<Metadata *>(MD);
787 if (
auto *CMD = dyn_cast<ConstantAsMetadata>(MD)) {
795 assert(isa<MDNode>(MD) &&
"Expected a metadata node");
801 assert(MD &&
"Expected valid metadata");
802 assert(!isa<LocalAsMetadata>(MD) &&
"Unexpected local metadata");
807 return MDNodeMapper(*this).map(*cast<MDNode>(MD));
810 void Mapper::flush() {
812 while (!Worklist.
empty()) {
814 CurrentMCID =
E.MCID;
816 case WorklistEntry::MapGlobalInit:
817 E.Data.GVInit.GV->setInitializer(mapConstant(
E.Data.GVInit.Init));
818 remapGlobalObjectMetadata(*
E.Data.GVInit.GV);
820 case WorklistEntry::MapAppendingVar: {
821 unsigned PrefixSize = AppendingInits.
size() -
E.AppendingGVNumNewMembers;
822 mapAppendingVariable(*
E.Data.AppendingGV.GV,
823 E.Data.AppendingGV.InitPrefix,
824 E.AppendingGVIsOldCtorDtor,
826 AppendingInits.
resize(PrefixSize);
829 case WorklistEntry::MapGlobalIndirectSymbol:
830 E.Data.GlobalIndirectSymbol.GIS->setIndirectSymbol(
831 mapConstant(
E.Data.GlobalIndirectSymbol.Target));
834 remapFunction(*
E.Data.RemapF);
842 while (!DelayedBBs.
empty()) {
844 BasicBlock *BB = cast_or_null<BasicBlock>(mapValue(DBB.OldBB));
845 DBB.TempBB->replaceAllUsesWith(BB ? BB : DBB.OldBB);
851 for (
Use &
Op :
I->operands()) {
858 "Referenced value not in value map!");
862 if (
PHINode *PN = dyn_cast<PHINode>(
I)) {
863 for (
unsigned i = 0,
e = PN->getNumIncomingValues(); i !=
e; ++i) {
864 Value *V = mapValue(PN->getIncomingBlock(i));
867 PN->setIncomingBlock(i, cast<BasicBlock>(V));
870 "Referenced block not in value map!");
876 I->getAllMetadata(MDs);
877 for (
const auto &
MI : MDs) {
879 MDNode *
New = cast_or_null<MDNode>(mapMetadata(Old));
881 I->setMetadata(
MI.first, New);
888 if (
auto *CB = dyn_cast<CallBase>(
I)) {
899 for (
unsigned i = 0; i <
Attrs.getNumAttrSets(); ++i) {
901 {Attribute::ByVal, Attribute::StructRet, Attribute::ByRef}) {
902 if (
Type *Ty =
Attrs.getAttribute(i, TypedAttr).getValueAsType()) {
903 Attrs =
Attrs.replaceAttributeType(
C, i, TypedAttr,
909 CB->setAttributes(
Attrs);
912 if (
auto *AI = dyn_cast<AllocaInst>(
I))
913 AI->setAllocatedType(TypeMapper->
remapType(AI->getAllocatedType()));
914 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(
I)) {
915 GEP->setSourceElementType(
917 GEP->setResultElementType(
920 I->mutateType(TypeMapper->
remapType(
I->getType()));
923 void Mapper::remapGlobalObjectMetadata(
GlobalObject &GO) {
927 for (
const auto &
I : MDs)
928 GO.
addMetadata(
I.first, *cast<MDNode>(mapMetadata(
I.second)));
931 void Mapper::remapFunction(
Function &
F) {
933 for (
Use &
Op :
F.operands())
938 remapGlobalObjectMetadata(
F);
948 remapInstruction(&
I);
956 unsigned NumElements =
957 cast<ArrayType>(InitPrefix->
getType())->getNumElements();
958 for (
unsigned I = 0;
I != NumElements; ++
I)
969 Type *Tys[3] = {
ST.getElementType(0),
ST.getElementType(1), VoidPtrTy};
973 for (
auto *V : NewMembers) {
976 auto *S = cast<ConstantStruct>(V);
977 auto *E1 = cast<Constant>(mapValue(S->getOperand(0)));
978 auto *E2 = cast<Constant>(mapValue(S->getOperand(1)));
982 NewV = cast_or_null<Constant>(mapValue(V));
993 assert(AlreadyScheduled.
insert(&GV).second &&
"Should not reschedule");
994 assert(MCID < MCs.
size() &&
"Invalid mapping context");
997 WE.Kind = WorklistEntry::MapGlobalInit;
999 WE.Data.GVInit.GV = &GV;
1000 WE.Data.GVInit.Init = &
Init;
1009 assert(AlreadyScheduled.
insert(&GV).second &&
"Should not reschedule");
1010 assert(MCID < MCs.
size() &&
"Invalid mapping context");
1013 WE.Kind = WorklistEntry::MapAppendingVar;
1015 WE.Data.AppendingGV.GV = &GV;
1016 WE.Data.AppendingGV.InitPrefix = InitPrefix;
1017 WE.AppendingGVIsOldCtorDtor = IsOldCtorDtor;
1018 WE.AppendingGVNumNewMembers = NewMembers.
size();
1025 assert(AlreadyScheduled.
insert(&GIS).second &&
"Should not reschedule");
1026 assert(MCID < MCs.
size() &&
"Invalid mapping context");
1029 WE.Kind = WorklistEntry::MapGlobalIndirectSymbol;
1031 WE.Data.GlobalIndirectSymbol.GIS = &GIS;
1036 void Mapper::scheduleRemapFunction(
Function &
F,
unsigned MCID) {
1037 assert(AlreadyScheduled.
insert(&
F).second &&
"Should not reschedule");
1038 assert(MCID < MCs.
size() &&
"Invalid mapping context");
1043 WE.Data.RemapF = &
F;
1048 assert(!hasWorkToDo() &&
"Expected to have flushed the worklist");
1049 this->Flags = this->Flags | Flags;
1053 return reinterpret_cast<Mapper *>(pImpl);
1058 class FlushingMapper {
1062 explicit FlushingMapper(
void *pImpl) :
M(*
getAsMapper(pImpl)) {
1063 assert(!
M.hasWorkToDo() &&
"Expected to be flushed");
1066 ~FlushingMapper() {
M.flush(); }
1068 Mapper *operator->()
const {
return &
M; }
1076 : pImpl(new Mapper(VM, Flags, TypeMapper, Materializer)) {}
1083 return getAsMapper(pImpl)->registerAlternateMappingContext(VM, Materializer);
1087 FlushingMapper(pImpl)->addFlags(Flags);
1091 return FlushingMapper(pImpl)->mapValue(&V);
1095 return cast_or_null<Constant>(
mapValue(
C));
1099 return FlushingMapper(pImpl)->mapMetadata(&MD);
1107 FlushingMapper(pImpl)->remapInstruction(&
I);
1111 FlushingMapper(pImpl)->remapFunction(
F);
1126 GV, InitPrefix, IsOldCtorDtor, NewMembers, 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.
This class represents an incoming formal argument to a Function.
This class represents lattice values for constants.
LLVM_NODISCARD bool empty() const
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)
void reserve(size_type N)
static Mapper * getAsMapper(void *pImpl)
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
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 ...
void remapInstruction(Instruction &I)
A Use represents the edge between a Value definition and its users.
Constant * mapConstant(const Constant &C)
static Constant * get(ArrayRef< Constant * > V)
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)
void clearMetadata()
Erase all metadata attached to this Value.
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.
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
BasicBlock * getBasicBlock() const
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
Value * getOperand(unsigned i) 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.
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
void getAllMetadata(SmallVectorImpl< std::pair< unsigned, MDNode * >> &MDs) const
Appends all metadata attached to this value to MDs, sorting by KindID.
static Metadata * cloneOrBuildODR(const MDNode &N)
This is a class that can be implemented by clients to materialize Values on demand.
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.
This is an important class for using LLVM in a threaded context.
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.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
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)
void addMetadata(unsigned KindID, MDNode &MD)
Add a metadata attachment.
static Constant * get(ArrayType *T, ArrayRef< Constant * > 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 Constant * get(StructType *T, ArrayRef< Constant * > V)
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.
unsigned getNumOperands() const
Align max(MaybeAlign Lhs, Align Rhs)
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 StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
void scheduleMapAppendingVariable(GlobalVariable &GV, Constant *InitPrefix, bool IsOldCtorDtor, ArrayRef< Constant * > NewMembers, unsigned MappingContextID=0)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
LLVM_NODISCARD T pop_back_val()
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
void remapFunction(Function &F)
Target - Wrapper for Target specific information.
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,...
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.
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.
Value * mapValue(const Value &V)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
GlobalIndirectSymbol(Type *Ty, ValueTy VTy, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Symbol)
unsigned registerAlternateMappingContext(ValueToValueMapTy &VM, ValueMaterializer *Materializer=nullptr)
Register an alternate mapping context.
virtual Type * remapType(Type *SrcTy)=0
The client should implement this method if they want to remap types while mapping values.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
static IntegerType * getInt8Ty(LLVMContext &C)
void scheduleMapGlobalIndirectSymbol(GlobalIndirectSymbol &GIS, Constant &Target, unsigned MappingContextID=0)
Type * getElementType() const
PointerType * getType() const
Global values are always pointers.
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
MDNode * mapMDNode(const MDNode &N)