Linker: Remove IRMover::isMetadataUnneeded indirection; almost NFC

Instead of checking live during MapMetadata whether a subprogram is
needed, seed the ValueMap with `nullptr` up-front.

There is a small hypothetical functionality change.  Previously, calling
MapMetadataOp on a node whose "scope:" chain led to an unneeded
subprogram would return nullptr.  However, if that were ever called,
then the subprogram would be needed; a situation that the IRMover is
supposed to avoid a priori!

Besides cleaning up the code a little, this restores a nice property:
MapMetadataOp returns the same as MapMetadata.

llvm-svn: 265229
This commit is contained in:
Duncan P. N. Exon Smith 2016-04-02 17:12:00 +00:00
parent da4a56d1ab
commit 4b520e5ef6
3 changed files with 19 additions and 56 deletions

View File

@ -55,11 +55,6 @@ namespace llvm {
/// It is called after the mapping is recorded, so it doesn't need to worry /// It is called after the mapping is recorded, so it doesn't need to worry
/// about recursion. /// about recursion.
virtual void materializeInitFor(GlobalValue *New, GlobalValue *Old); virtual void materializeInitFor(GlobalValue *New, GlobalValue *Old);
/// The client should implement this method if some metadata need
/// not be mapped, for example DISubprogram metadata for functions not
/// linked into the destination module.
virtual bool isMetadataNeeded(Metadata *MD) { return true; }
}; };
/// RemapFlags - These are flags that the value mapping APIs allow. /// RemapFlags - These are flags that the value mapping APIs allow.

View File

@ -351,7 +351,6 @@ public:
GlobalValueMaterializer(IRLinker &TheIRLinker) : TheIRLinker(TheIRLinker) {} GlobalValueMaterializer(IRLinker &TheIRLinker) : TheIRLinker(TheIRLinker) {}
Value *materializeDeclFor(Value *V) override; Value *materializeDeclFor(Value *V) override;
void materializeInitFor(GlobalValue *New, GlobalValue *Old) override; void materializeInitFor(GlobalValue *New, GlobalValue *Old) override;
bool isMetadataNeeded(Metadata *MD) override;
}; };
class LocalValueMaterializer final : public ValueMaterializer { class LocalValueMaterializer final : public ValueMaterializer {
@ -361,7 +360,6 @@ public:
LocalValueMaterializer(IRLinker &TheIRLinker) : TheIRLinker(TheIRLinker) {} LocalValueMaterializer(IRLinker &TheIRLinker) : TheIRLinker(TheIRLinker) {}
Value *materializeDeclFor(Value *V) override; Value *materializeDeclFor(Value *V) override;
void materializeInitFor(GlobalValue *New, GlobalValue *Old) override; void materializeInitFor(GlobalValue *New, GlobalValue *Old) override;
bool isMetadataNeeded(Metadata *MD) override;
}; };
/// This is responsible for keeping track of the state used for moving data /// This is responsible for keeping track of the state used for moving data
@ -405,7 +403,7 @@ class IRLinker {
/// Set of subprogram metadata that does not need to be linked into the /// Set of subprogram metadata that does not need to be linked into the
/// destination module, because the functions were not imported directly /// destination module, because the functions were not imported directly
/// or via an inlined body in an imported function. /// or via an inlined body in an imported function.
SmallPtrSet<const Metadata *, 16> UnneededSubprograms; bool HasUnneededSPs = false;
/// Handles cloning of a global values from the source module into /// Handles cloning of a global values from the source module into
/// the destination module, including setting the attributes and visibility. /// the destination module, including setting the attributes and visibility.
@ -472,15 +470,13 @@ class IRLinker {
void linkNamedMDNodes(); void linkNamedMDNodes();
/// Populate the UnneededSubprograms set with the DISubprogram metadata /// Look for subprograms referenced from !llvm.dbg.cu that we don't want to
/// from the source module that we don't need to link into the dest module, /// link in and map it to nullptr.
/// because the functions were not imported directly or via an inlined body ///
/// in an imported function. /// \post HasUnneededSPs is true iff any unneeded subprograms were found.
void findNeededSubprograms(); void mapUnneededSubprograms();
/// The value mapper leaves nulls in the list of subprograms for any /// Remove null subprograms from !llvm.dbg.cu.
/// in the UnneededSubprograms map. Strip those out of the mapped
/// compile unit.
void stripNullSubprograms(DICompileUnit *CU); void stripNullSubprograms(DICompileUnit *CU);
public: public:
@ -496,11 +492,6 @@ public:
bool run(); bool run();
Value *materializeDeclFor(Value *V, bool ForAlias); Value *materializeDeclFor(Value *V, bool ForAlias);
void materializeInitFor(GlobalValue *New, GlobalValue *Old, bool ForAlias); void materializeInitFor(GlobalValue *New, GlobalValue *Old, bool ForAlias);
/// Indicates whether we need to map the given metadata into the destination
/// module. Used to prevent linking of metadata only needed by functions not
/// linked into the dest module.
bool isMetadataNeeded(Metadata *MD);
}; };
} }
@ -534,10 +525,6 @@ void GlobalValueMaterializer::materializeInitFor(GlobalValue *New,
TheIRLinker.materializeInitFor(New, Old, false); TheIRLinker.materializeInitFor(New, Old, false);
} }
bool GlobalValueMaterializer::isMetadataNeeded(Metadata *MD) {
return TheIRLinker.isMetadataNeeded(MD);
}
Value *LocalValueMaterializer::materializeDeclFor(Value *V) { Value *LocalValueMaterializer::materializeDeclFor(Value *V) {
return TheIRLinker.materializeDeclFor(V, true); return TheIRLinker.materializeDeclFor(V, true);
} }
@ -547,10 +534,6 @@ void LocalValueMaterializer::materializeInitFor(GlobalValue *New,
TheIRLinker.materializeInitFor(New, Old, true); TheIRLinker.materializeInitFor(New, Old, true);
} }
bool LocalValueMaterializer::isMetadataNeeded(Metadata *MD) {
return TheIRLinker.isMetadataNeeded(MD);
}
Value *IRLinker::materializeDeclFor(Value *V, bool ForAlias) { Value *IRLinker::materializeDeclFor(Value *V, bool ForAlias) {
auto *SGV = dyn_cast<GlobalValue>(V); auto *SGV = dyn_cast<GlobalValue>(V);
if (!SGV) if (!SGV)
@ -578,19 +561,6 @@ void IRLinker::materializeInitFor(GlobalValue *New, GlobalValue *Old,
linkGlobalValueBody(*New, *Old); linkGlobalValueBody(*New, *Old);
} }
bool IRLinker::isMetadataNeeded(Metadata *MD) {
// Currently only DISubprogram metadata is marked as being unneeded.
if (UnneededSubprograms.empty())
return true;
MDNode *Node = dyn_cast<MDNode>(MD);
if (!Node)
return true;
DISubprogram *SP = getDISubprogram(Node);
if (!SP)
return true;
return !UnneededSubprograms.count(SP);
}
/// Loop through the global variables in the src module and merge them into the /// Loop through the global variables in the src module and merge them into the
/// dest module. /// dest module.
GlobalVariable *IRLinker::copyGlobalVariableProto(const GlobalVariable *SGVar) { GlobalVariable *IRLinker::copyGlobalVariableProto(const GlobalVariable *SGVar) {
@ -1064,7 +1034,7 @@ bool IRLinker::linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src) {
return false; return false;
} }
void IRLinker::findNeededSubprograms() { void IRLinker::mapUnneededSubprograms() {
// Track unneeded nodes to make it simpler to handle the case // Track unneeded nodes to make it simpler to handle the case
// where we are checking if an already-mapped SP is needed. // where we are checking if an already-mapped SP is needed.
NamedMDNode *CompileUnits = SrcM->getNamedMetadata("llvm.dbg.cu"); NamedMDNode *CompileUnits = SrcM->getNamedMetadata("llvm.dbg.cu");
@ -1087,13 +1057,14 @@ void IRLinker::findNeededSubprograms() {
if (auto *SP = getDISubprogram(dyn_cast<MDNode>(IE->getScope()))) if (auto *SP = getDISubprogram(dyn_cast<MDNode>(IE->getScope())))
ImportedEntitySPs.insert(SP); ImportedEntitySPs.insert(SP);
} }
for (auto *Op : CU->getSubprograms()) {
// Any needed SPs should have been mapped as they would be reached // Try to insert nullptr into the map for any SP not referenced from
// from the function linked in (either on the function itself for linked // functions and not in the imported entities. If the insertino succeeded,
// function bodies, or from DILocation on inlined instructions). // set HasUnneededSPs.
if (!ValueMap.getMappedMD(Op) && !ImportedEntitySPs.count(Op)) for (auto *Op : CU->getSubprograms())
UnneededSubprograms.insert(Op); if (!ImportedEntitySPs.count(Op))
} if (ValueMap.MD().insert(std::make_pair(Op, TrackingMDRef())).second)
HasUnneededSPs = true;
} }
} }
@ -1101,7 +1072,7 @@ void IRLinker::findNeededSubprograms() {
void IRLinker::stripNullSubprograms(DICompileUnit *CU) { void IRLinker::stripNullSubprograms(DICompileUnit *CU) {
// There won't be any nulls if we didn't have any subprograms marked // There won't be any nulls if we didn't have any subprograms marked
// as unneeded. // as unneeded.
if (UnneededSubprograms.empty()) if (!HasUnneededSPs)
return; return;
SmallVector<Metadata *, 16> NewSPs; SmallVector<Metadata *, 16> NewSPs;
NewSPs.reserve(CU->getSubprograms().size()); NewSPs.reserve(CU->getSubprograms().size());
@ -1119,7 +1090,7 @@ void IRLinker::stripNullSubprograms(DICompileUnit *CU) {
/// Insert all of the named MDNodes in Src into the Dest module. /// Insert all of the named MDNodes in Src into the Dest module.
void IRLinker::linkNamedMDNodes() { void IRLinker::linkNamedMDNodes() {
findNeededSubprograms(); mapUnneededSubprograms();
const NamedMDNode *SrcModFlags = SrcM->getModuleFlagsMetadata(); const NamedMDNode *SrcModFlags = SrcM->getModuleFlagsMetadata();
for (const NamedMDNode &NMD : SrcM->named_metadata()) { for (const NamedMDNode &NMD : SrcM->named_metadata()) {
// Don't link module flags here. Do them separately. // Don't link module flags here. Do them separately.
@ -1132,7 +1103,7 @@ void IRLinker::linkNamedMDNodes() {
op, ValueMap, ValueMapperFlags | RF_NullMapMissingGlobalValues, op, ValueMap, ValueMapperFlags | RF_NullMapMissingGlobalValues,
&TypeMap, &GValMaterializer); &TypeMap, &GValMaterializer);
// For each newly mapped compile unit remove any null subprograms, // For each newly mapped compile unit remove any null subprograms,
// which occur when findNeededSubprograms identified any as unneeded // which occur when mapUnneededSubprograms identified any as unneeded
// in the dest module. // in the dest module.
if (auto *CU = dyn_cast<DICompileUnit>(DestMD)) if (auto *CU = dyn_cast<DICompileUnit>(DestMD))
stripNullSubprograms(CU); stripNullSubprograms(CU);

View File

@ -190,9 +190,6 @@ static Metadata *mapMetadataOp(Metadata *Op,
if (!Op) if (!Op)
return nullptr; return nullptr;
if (Materializer && !Materializer->isMetadataNeeded(Op))
return nullptr;
if (Metadata *MappedOp = MapMetadataImpl(Op, DistinctWorklist, VM, Flags, if (Metadata *MappedOp = MapMetadataImpl(Op, DistinctWorklist, VM, Flags,
TypeMapper, Materializer)) TypeMapper, Materializer))
return MappedOp; return MappedOp;