summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp15
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp49
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp1
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp8
-rw-r--r--llvm/lib/CodeGen/LiveDebugVariables.cpp3
-rw-r--r--llvm/lib/IR/AsmWriter.cpp1
-rw-r--r--llvm/lib/IR/DIBuilder.cpp57
-rw-r--r--llvm/lib/IR/DebugInfo.cpp22
-rw-r--r--llvm/lib/IR/DebugInfoMetadata.cpp27
-rw-r--r--llvm/lib/IR/LLVMContextImpl.h13
-rw-r--r--llvm/lib/IR/Verifier.cpp77
-rw-r--r--llvm/lib/Linker/LinkModules.cpp50
-rw-r--r--llvm/lib/Transforms/IPO/ArgumentPromotion.cpp13
-rw-r--r--llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp25
-rw-r--r--llvm/lib/Transforms/IPO/StripSymbols.cpp8
-rw-r--r--llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp8
-rw-r--r--llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp18
-rw-r--r--llvm/lib/Transforms/Utils/CloneFunction.cpp4
18 files changed, 147 insertions, 252 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index d5e5848422b..1c219ad6cd8 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -3807,8 +3807,8 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) {
/// isDefinition: true, scopeLine: 8, containingType: !3,
/// virtuality: DW_VIRTUALTIY_pure_virtual,
/// virtualIndex: 10, flags: 11,
-/// isOptimized: false, function: void ()* @_Z3foov,
-/// templateParams: !4, declaration: !5, variables: !6)
+/// isOptimized: false, templateParams: !4, declaration: !5,
+/// variables: !6)
bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) {
auto Loc = Lex.getLoc();
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
@@ -3826,7 +3826,6 @@ bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) {
OPTIONAL(virtualIndex, MDUnsignedField, (0, UINT32_MAX)); \
OPTIONAL(flags, DIFlagField, ); \
OPTIONAL(isOptimized, MDBoolField, ); \
- OPTIONAL(function, MDConstant, ); \
OPTIONAL(templateParams, MDField, ); \
OPTIONAL(declaration, MDField, ); \
OPTIONAL(variables, MDField, );
@@ -3839,11 +3838,11 @@ bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) {
"missing 'distinct', required for !DISubprogram when 'isDefinition'");
Result = GET_OR_DISTINCT(
- DISubprogram, (Context, scope.Val, name.Val, linkageName.Val, file.Val,
- line.Val, type.Val, isLocal.Val, isDefinition.Val,
- scopeLine.Val, containingType.Val, virtuality.Val,
- virtualIndex.Val, flags.Val, isOptimized.Val, function.Val,
- templateParams.Val, declaration.Val, variables.Val));
+ DISubprogram,
+ (Context, scope.Val, name.Val, linkageName.Val, file.Val, line.Val,
+ type.Val, isLocal.Val, isDefinition.Val, scopeLine.Val,
+ containingType.Val, virtuality.Val, virtualIndex.Val, flags.Val,
+ isOptimized.Val, templateParams.Val, declaration.Val, variables.Val));
return false;
}
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 522f2aa4707..7c1b208c626 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -232,6 +232,10 @@ class BitcodeReader : public GVMaterializer {
bool StripDebugInfo = false;
+ /// Functions that need to be matched with subprograms when upgrading old
+ /// metadata.
+ SmallDenseMap<Function *, DISubprogram *, 16> FunctionsWithSPs;
+
std::vector<std::string> BundleTags;
public:
@@ -2182,20 +2186,33 @@ std::error_code BitcodeReader::parseMetadata() {
break;
}
case bitc::METADATA_SUBPROGRAM: {
- if (Record.size() != 19)
- return error("Invalid record");
-
- MDValueList.assignValue(
- GET_OR_DISTINCT(
- DISubprogram,
- Record[0] || Record[8], // All definitions should be distinct.
- (Context, getMDOrNull(Record[1]), getMDString(Record[2]),
- getMDString(Record[3]), getMDOrNull(Record[4]), Record[5],
- getMDOrNull(Record[6]), Record[7], Record[8], Record[9],
- getMDOrNull(Record[10]), Record[11], Record[12], Record[13],
- Record[14], getMDOrNull(Record[15]), getMDOrNull(Record[16]),
- getMDOrNull(Record[17]), getMDOrNull(Record[18]))),
- NextMDValueNo++);
+ if (Record.size() != 18 && Record.size() != 19)
+ return error("Invalid record");
+
+ bool HasFn = Record.size() == 19;
+ DISubprogram *SP = GET_OR_DISTINCT(
+ DISubprogram,
+ Record[0] || Record[8], // All definitions should be distinct.
+ (Context, getMDOrNull(Record[1]), getMDString(Record[2]),
+ getMDString(Record[3]), getMDOrNull(Record[4]), Record[5],
+ getMDOrNull(Record[6]), Record[7], Record[8], Record[9],
+ getMDOrNull(Record[10]), Record[11], Record[12], Record[13],
+ Record[14], getMDOrNull(Record[15 + HasFn]),
+ getMDOrNull(Record[16 + HasFn]), getMDOrNull(Record[17 + HasFn])));
+ MDValueList.assignValue(SP, NextMDValueNo++);
+
+ // Upgrade sp->function mapping to function->sp mapping.
+ if (HasFn && Record[15]) {
+ if (auto *CMD = dyn_cast<ConstantAsMetadata>(getMDOrNull(Record[15])))
+ if (auto *F = dyn_cast<Function>(CMD->getValue())) {
+ if (F->isMaterializable())
+ // Defer until materialized; unmaterialized functions may not have
+ // metadata.
+ FunctionsWithSPs[F] = SP;
+ else if (!F->empty())
+ F->setSubprogram(SP);
+ }
+ }
break;
}
case bitc::METADATA_LEXICAL_BLOCK: {
@@ -5139,6 +5156,10 @@ std::error_code BitcodeReader::materialize(GlobalValue *GV) {
}
}
+ // Finish fn->subprogram upgrade for materialized functions.
+ if (DISubprogram *SP = FunctionsWithSPs.lookup(F))
+ F->setSubprogram(SP);
+
// Bring in any functions that this function forward-referenced via
// blockaddresses.
return materializeForwardReferencedFunctions();
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 755167a9636..c73b099e27f 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -1024,7 +1024,6 @@ static void WriteDISubprogram(const DISubprogram *N, const ValueEnumerator &VE,
Record.push_back(N->getVirtualIndex());
Record.push_back(N->getFlags());
Record.push_back(N->isOptimized());
- Record.push_back(VE.getMetadataOrNullID(N->getRawFunction()));
Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams().get()));
Record.push_back(VE.getMetadataOrNullID(N->getDeclaration()));
Record.push_back(VE.getMetadataOrNullID(N->getVariables().get()));
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index a9dca447980..477ebe1d638 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -476,8 +476,6 @@ void DwarfDebug::beginModule() {
const Module *M = MMI->getModule();
- FunctionDIs = makeSubprogramMap(*M);
-
NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
if (!CU_Nodes)
return;
@@ -1113,8 +1111,8 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
if (!MMI->hasDebugInfo())
return;
- auto DI = FunctionDIs.find(MF->getFunction());
- if (DI == FunctionDIs.end())
+ auto DI = MF->getFunction()->getSubprogram();
+ if (!DI)
return;
// Grab the lexical scopes for the function, if we don't have any of those
@@ -1205,7 +1203,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
"endFunction should be called with the same function as beginFunction");
if (!MMI->hasDebugInfo() || LScopes.empty() ||
- !FunctionDIs.count(MF->getFunction())) {
+ !MF->getFunction()->getSubprogram()) {
// If we don't have a lexical scope for this function then there will
// be a hole in the range information. Keep note of this by setting the
// previously used section to nullptr.
diff --git a/llvm/lib/CodeGen/LiveDebugVariables.cpp b/llvm/lib/CodeGen/LiveDebugVariables.cpp
index 6559d8df1a2..654328714bc 100644
--- a/llvm/lib/CodeGen/LiveDebugVariables.cpp
+++ b/llvm/lib/CodeGen/LiveDebugVariables.cpp
@@ -761,7 +761,7 @@ static void removeDebugValues(MachineFunction &mf) {
bool LiveDebugVariables::runOnMachineFunction(MachineFunction &mf) {
if (!EnableLDV)
return false;
- if (!FunctionDIs.count(mf.getFunction())) {
+ if (!mf.getFunction()->getSubprogram()) {
removeDebugValues(mf);
return false;
}
@@ -1045,7 +1045,6 @@ void LiveDebugVariables::emitDebugValues(VirtRegMap *VRM) {
}
bool LiveDebugVariables::doInitialization(Module &M) {
- FunctionDIs = makeSubprogramMap(M);
return Pass::doInitialization(M);
}
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 2b39f2273b3..db757508594 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1692,7 +1692,6 @@ static void writeDISubprogram(raw_ostream &Out, const DISubprogram *N,
Printer.printInt("virtualIndex", N->getVirtualIndex());
Printer.printDIFlags("flags", N->getFlags());
Printer.printBool("isOptimized", N->isOptimized());
- Printer.printMetadata("function", N->getRawFunction());
Printer.printMetadata("templateParams", N->getRawTemplateParams());
Printer.printMetadata("declaration", N->getRawDeclaration());
Printer.printMetadata("variables", N->getRawVariables());
diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp
index def72d6cf6e..7fc0652bf65 100644
--- a/llvm/lib/IR/DIBuilder.cpp
+++ b/llvm/lib/IR/DIBuilder.cpp
@@ -659,19 +659,17 @@ DIExpression *DIBuilder::createBitPieceExpression(unsigned OffsetInBytes,
return DIExpression::get(VMContext, Addr);
}
-DISubprogram *DIBuilder::createFunction(DIScopeRef Context, StringRef Name,
- StringRef LinkageName, DIFile *File,
- unsigned LineNo, DISubroutineType *Ty,
- bool isLocalToUnit, bool isDefinition,
- unsigned ScopeLine, unsigned Flags,
- bool isOptimized, Function *Fn,
- MDNode *TParams, MDNode *Decl) {
+DISubprogram *DIBuilder::createFunction(
+ DIScopeRef Context, StringRef Name, StringRef LinkageName, DIFile *File,
+ unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit,
+ bool isDefinition, unsigned ScopeLine, unsigned Flags, bool isOptimized,
+ DITemplateParameterArray TParams, DISubprogram *Decl) {
// dragonegg does not generate identifier for types, so using an empty map
// to resolve the context should be fine.
DITypeIdentifierMap EmptyMap;
return createFunction(Context.resolve(EmptyMap), Name, LinkageName, File,
LineNo, Ty, isLocalToUnit, isDefinition, ScopeLine,
- Flags, isOptimized, Fn, TParams, Decl);
+ Flags, isOptimized, TParams, Decl);
}
template <class... Ts>
@@ -681,20 +679,17 @@ static DISubprogram *getSubprogram(bool IsDistinct, Ts &&... Args) {
return DISubprogram::get(std::forward<Ts>(Args)...);
}
-DISubprogram *DIBuilder::createFunction(DIScope *Context, StringRef Name,
- StringRef LinkageName, DIFile *File,
- unsigned LineNo, DISubroutineType *Ty,
- bool isLocalToUnit, bool isDefinition,
- unsigned ScopeLine, unsigned Flags,
- bool isOptimized, Function *Fn,
- MDNode *TParams, MDNode *Decl) {
- auto *Node = getSubprogram(/* IsDistinct = */ isDefinition, VMContext,
- DIScopeRef::get(getNonCompileUnitScope(Context)),
- Name, LinkageName, File, LineNo, Ty, isLocalToUnit,
- isDefinition, ScopeLine, nullptr, 0, 0, Flags,
- isOptimized, Fn, cast_or_null<MDTuple>(TParams),
- cast_or_null<DISubprogram>(Decl),
- MDTuple::getTemporary(VMContext, None).release());
+DISubprogram *DIBuilder::createFunction(
+ DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,
+ unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit,
+ bool isDefinition, unsigned ScopeLine, unsigned Flags, bool isOptimized,
+ DITemplateParameterArray TParams, DISubprogram *Decl) {
+ auto *Node =
+ getSubprogram(/* IsDistinct = */ isDefinition, VMContext,
+ DIScopeRef::get(getNonCompileUnitScope(Context)), Name,
+ LinkageName, File, LineNo, Ty, isLocalToUnit, isDefinition,
+ ScopeLine, nullptr, 0, 0, Flags, isOptimized, TParams, Decl,
+ MDTuple::getTemporary(VMContext, None).release());
if (isDefinition)
AllSubprograms.push_back(Node);
@@ -706,12 +701,11 @@ DISubprogram *DIBuilder::createTempFunctionFwdDecl(
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,
unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit,
bool isDefinition, unsigned ScopeLine, unsigned Flags, bool isOptimized,
- Function *Fn, MDNode *TParams, MDNode *Decl) {
+ DITemplateParameterArray TParams, DISubprogram *Decl) {
return DISubprogram::getTemporary(
VMContext, DIScopeRef::get(getNonCompileUnitScope(Context)), Name,
LinkageName, File, LineNo, Ty, isLocalToUnit, isDefinition,
- ScopeLine, nullptr, 0, 0, Flags, isOptimized, Fn,
- cast_or_null<MDTuple>(TParams), cast_or_null<DISubprogram>(Decl),
+ ScopeLine, nullptr, 0, 0, Flags, isOptimized, TParams, Decl,
nullptr)
.release();
}
@@ -721,17 +715,16 @@ DIBuilder::createMethod(DIScope *Context, StringRef Name, StringRef LinkageName,
DIFile *F, unsigned LineNo, DISubroutineType *Ty,
bool isLocalToUnit, bool isDefinition, unsigned VK,
unsigned VIndex, DIType *VTableHolder, unsigned Flags,
- bool isOptimized, Function *Fn, MDNode *TParam) {
+ bool isOptimized, DITemplateParameterArray TParams) {
assert(getNonCompileUnitScope(Context) &&
"Methods should have both a Context and a context that isn't "
"the compile unit.");
// FIXME: Do we want to use different scope/lines?
- auto *SP = getSubprogram(/* IsDistinct = */ isDefinition, VMContext,
- DIScopeRef::get(cast<DIScope>(Context)), Name,
- LinkageName, F, LineNo, Ty, isLocalToUnit,
- isDefinition, LineNo, DITypeRef::get(VTableHolder),
- VK, VIndex, Flags, isOptimized, Fn,
- cast_or_null<MDTuple>(TParam), nullptr, nullptr);
+ auto *SP = getSubprogram(
+ /* IsDistinct = */ isDefinition, VMContext,
+ DIScopeRef::get(cast<DIScope>(Context)), Name, LinkageName, F, LineNo, Ty,
+ isLocalToUnit, isDefinition, LineNo, DITypeRef::get(VTableHolder), VK,
+ VIndex, Flags, isOptimized, TParams, nullptr, nullptr);
if (isDefinition)
AllSubprograms.push_back(SP);
diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp
index b22ba53645d..a2443becdd0 100644
--- a/llvm/lib/IR/DebugInfo.cpp
+++ b/llvm/lib/IR/DebugInfo.cpp
@@ -300,6 +300,10 @@ bool DebugInfoFinder::addScope(DIScope *Scope) {
bool llvm::stripDebugInfo(Function &F) {
bool Changed = false;
+ if (F.getSubprogram()) {
+ Changed = true;
+ F.setSubprogram(nullptr);
+ }
for (BasicBlock &BB : F) {
for (Instruction &I : BB) {
if (I.getDebugLoc()) {
@@ -359,21 +363,3 @@ unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) {
return Val->getZExtValue();
return 0;
}
-
-DenseMap<const llvm::Function *, DISubprogram *>
-llvm::makeSubprogramMap(const Module &M) {
- DenseMap<const Function *, DISubprogram *> R;
-
- NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu");
- if (!CU_Nodes)
- return R;
-
- for (MDNode *N : CU_Nodes->operands()) {
- auto *CUNode = cast<DICompileUnit>(N);
- for (auto *SP : CUNode->getSubprograms()) {
- if (Function *F = SP->getFunction())
- R.insert(std::make_pair(F, SP));
- }
- }
- return R;
-}
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index 7ba51f66b79..cead10652e0 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -342,34 +342,28 @@ DISubprogram *DISubprogram::getImpl(
MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type,
bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex,
- unsigned Flags, bool IsOptimized, Metadata *Function,
- Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables,
- StorageType Storage, bool ShouldCreate) {
+ unsigned Flags, bool IsOptimized, Metadata *TemplateParams,
+ Metadata *Declaration, Metadata *Variables, StorageType Storage,
+ bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
assert(isCanonical(LinkageName) && "Expected canonical MDString");
DEFINE_GETIMPL_LOOKUP(DISubprogram,
(Scope, getString(Name), getString(LinkageName), File,
Line, Type, IsLocalToUnit, IsDefinition, ScopeLine,
ContainingType, Virtuality, VirtualIndex, Flags,
- IsOptimized, Function, TemplateParams, Declaration,
- Variables));
- Metadata *Ops[] = {File, Scope, Name, Name,
- LinkageName, Type, ContainingType, Function,
- TemplateParams, Declaration, Variables};
+ IsOptimized, TemplateParams, Declaration, Variables));
+ Metadata *Ops[] = {File, Scope, Name, Name,
+ LinkageName, Type, ContainingType, TemplateParams,
+ Declaration, Variables};
DEFINE_GETIMPL_STORE(DISubprogram,
(Line, ScopeLine, Virtuality, VirtualIndex, Flags,
IsLocalToUnit, IsDefinition, IsOptimized),
Ops);
}
-Function *DISubprogram::getFunction() const {
- // FIXME: Should this be looking through bitcasts?
- return dyn_cast_or_null<Function>(getFunctionConstant());
-}
-
bool DISubprogram::describes(const Function *F) const {
assert(F && "Invalid function");
- if (F == getFunction())
+ if (F->getSubprogram() == this)
return true;
StringRef Name = getLinkageName();
if (Name.empty())
@@ -377,11 +371,6 @@ bool DISubprogram::describes(const Function *F) const {
return F->getName() == Name;
}
-void DISubprogram::replaceFunction(Function *F) {
- replaceFunction(F ? ConstantAsMetadata::get(F)
- : static_cast<ConstantAsMetadata *>(nullptr));
-}
-
DILexicalBlock *DILexicalBlock::getImpl(LLVMContext &Context, Metadata *Scope,
Metadata *File, unsigned Line,
unsigned Column, StorageType Storage,
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 2df7d04708e..24f22b43fc0 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -473,7 +473,6 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
unsigned VirtualIndex;
unsigned Flags;
bool IsOptimized;
- Metadata *Function;
Metadata *TemplateParams;
Metadata *Declaration;
Metadata *Variables;
@@ -483,15 +482,15 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine,
Metadata *ContainingType, unsigned Virtuality,
unsigned VirtualIndex, unsigned Flags, bool IsOptimized,
- Metadata *Function, Metadata *TemplateParams,
- Metadata *Declaration, Metadata *Variables)
+ Metadata *TemplateParams, Metadata *Declaration,
+ Metadata *Variables)
: Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit),
IsDefinition(IsDefinition), ScopeLine(ScopeLine),
ContainingType(ContainingType), Virtuality(Virtuality),
VirtualIndex(VirtualIndex), Flags(Flags), IsOptimized(IsOptimized),
- Function(Function), TemplateParams(TemplateParams),
- Declaration(Declaration), Variables(Variables) {}
+ TemplateParams(TemplateParams), Declaration(Declaration),
+ Variables(Variables) {}
MDNodeKeyImpl(const DISubprogram *N)
: Scope(N->getRawScope()), Name(N->getName()),
LinkageName(N->getLinkageName()), File(N->getRawFile()),
@@ -500,7 +499,6 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
ScopeLine(N->getScopeLine()), ContainingType(N->getRawContainingType()),
Virtuality(N->getVirtuality()), VirtualIndex(N->getVirtualIndex()),
Flags(N->getFlags()), IsOptimized(N->isOptimized()),
- Function(N->getRawFunction()),
TemplateParams(N->getRawTemplateParams()),
Declaration(N->getRawDeclaration()), Variables(N->getRawVariables()) {}
@@ -515,7 +513,6 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
Virtuality == RHS->getVirtuality() &&
VirtualIndex == RHS->getVirtualIndex() && Flags == RHS->getFlags() &&
IsOptimized == RHS->isOptimized() &&
- Function == RHS->getRawFunction() &&
TemplateParams == RHS->getRawTemplateParams() &&
Declaration == RHS->getRawDeclaration() &&
Variables == RHS->getRawVariables();
@@ -523,7 +520,7 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
unsigned getHashValue() const {
return hash_combine(Scope, Name, LinkageName, File, Line, Type,
IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
- Virtuality, VirtualIndex, Flags, IsOptimized, Function,
+ Virtuality, VirtualIndex, Flags, IsOptimized,
TemplateParams, Declaration, Variables);
}
};
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index f64d4e2fddc..813f9ca6744 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -937,13 +937,6 @@ void Verifier::visitDISubprogram(const DISubprogram &N) {
Assert(isa<DISubroutineType>(T), "invalid subroutine type", &N, T);
Assert(isTypeRef(N, N.getRawContainingType()), "invalid containing type", &N,
N.getRawContainingType());
- if (auto *RawF = N.getRawFunction()) {
- auto *FMD = dyn_cast<ConstantAsMetadata>(RawF);
- auto *F = FMD ? FMD->getValue() : nullptr;
- auto *FT = F ? dyn_cast<PointerType>(F->getType()) : nullptr;
- Assert(F && FT && isa<FunctionType>(FT->getElementType()),
- "invalid function", &N, F, FT);
- }
if (auto *Params = N.getRawTemplateParams())
visitTemplateParams(N, *Params);
if (auto *S = N.getRawDeclaration()) {
@@ -963,41 +956,6 @@ void Verifier::visitDISubprogram(const DISubprogram &N) {
if (N.isDefinition())
Assert(N.isDistinct(), "subprogram definitions must be distinct", &N);
-
- auto *F = N.getFunction();
- if (!F)
- return;
-
- // Check that all !dbg attachments lead to back to N (or, at least, another
- // subprogram that describes the same function).
- //
- // FIXME: Check this incrementally while visiting !dbg attachments.
- // FIXME: Only check when N is the canonical subprogram for F.
- SmallPtrSet<const MDNode *, 32> Seen;
- for (auto &BB : *F)
- for (auto &I : BB) {
- // Be careful about using DILocation here since we might be dealing with
- // broken code (this is the Verifier after all).
- DILocation *DL =
- dyn_cast_or_null<DILocation>(I.getDebugLoc().getAsMDNode());
- if (!DL)
- continue;
- if (!Seen.insert(DL).second)
- continue;
-
- DILocalScope *Scope = DL->getInlinedAtScope();
- if (Scope && !Seen.insert(Scope).second)
- continue;
-
- DISubprogram *SP = Scope ? Scope->getSubprogram() : nullptr;
- if (SP && !Seen.insert(SP).second)
- continue;
-
- // FIXME: Once N is canonical, check "SP == &N".
- Assert(SP->describes(F),
- "!dbg attachment points at wrong subprogram for function", &N, F,
- &I, DL, Scope, SP);
- }
}
void Verifier::visitDILexicalBlockBase(const DILexicalBlockBase &N) {
@@ -1812,6 +1770,41 @@ void Verifier::visitFunction(const Function &F) {
(F.isDeclaration() && F.hasExternalLinkage()) ||
F.hasAvailableExternallyLinkage(),
"Function is marked as dllimport, but not external.", &F);
+
+ auto *N = F.getSubprogram();
+ if (!N)
+ return;
+
+ // Check that all !dbg attachments lead to back to N (or, at least, another
+ // subprogram that describes the same function).
+ //
+ // FIXME: Check this incrementally while visiting !dbg attachments.
+ // FIXME: Only check when N is the canonical subprogram for F.
+ SmallPtrSet<const MDNode *, 32> Seen;
+ for (auto &BB : F)
+ for (auto &I : BB) {
+ // Be careful about using DILocation here since we might be dealing with
+ // broken code (this is the Verifier after all).
+ DILocation *DL =
+ dyn_cast_or_null<DILocation>(I.getDebugLoc().getAsMDNode());
+ if (!DL)
+ continue;
+ if (!Seen.insert(DL).second)
+ continue;
+
+ DILocalScope *Scope = DL->getInlinedAtScope();
+ if (Scope && !Seen.insert(Scope).second)
+ continue;
+
+ DISubprogram *SP = Scope ? Scope->getSubprogram() : nullptr;
+ if (SP && !Seen.insert(SP).second)
+ continue;
+
+ // FIXME: Once N is canonical, check "SP == &N".
+ Assert(SP->describes(&F),
+ "!dbg attachment points at wrong subprogram for function", N, &F,
+ &I, DL, Scope, SP);
+ }
}
// verifyBasicBlock - Verify that a basic block is well formed...
diff --git a/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp
index a855ec06d17..4a12633c305 100644
--- a/llvm/lib/Linker/LinkModules.cpp
+++ b/llvm/lib/Linker/LinkModules.cpp
@@ -421,9 +421,6 @@ class ModuleLinker {
// Vector of GlobalValues to lazily link in.
std::vector<GlobalValue *> LazilyLinkGlobalValues;
- /// Functions that have replaced other functions.
- SmallPtrSet<const Function *, 16> OverridingFunctions;
-
DiagnosticHandlerFunction DiagnosticHandler;
/// For symbol clashes, prefer those from Src.
@@ -581,7 +578,6 @@ private:
const GlobalValue *DGV = nullptr);
void linkNamedMDNodes();
- void stripReplacedSubprograms();
};
}
@@ -1416,10 +1412,6 @@ bool ModuleLinker::linkGlobalValueProto(GlobalValue *SGV) {
}
NewGV = copyGlobalValueProto(TypeMap, SGV, DGV);
-
- if (DGV && isa<Function>(DGV))
- if (auto *NewF = dyn_cast<Function>(NewGV))
- OverridingFunctions.insert(NewF);
}
NewGV->setUnnamedAddr(HasUnnamedAddr);
@@ -1603,41 +1595,6 @@ void ModuleLinker::linkNamedMDNodes() {
}
}
-/// Drop DISubprograms that have been superseded.
-///
-/// FIXME: this creates an asymmetric result: we strip functions from losing
-/// subprograms in DstM, but leave losing subprograms in SrcM.
-/// TODO: Remove this logic once the backend can correctly determine canonical
-/// subprograms.
-void ModuleLinker::stripReplacedSubprograms() {
- // Avoid quadratic runtime by returning early when there's nothing to do.
- if (OverridingFunctions.empty())
- return;
-
- // Move the functions now, so the set gets cleared even on early returns.
- auto Functions = std::move(OverridingFunctions);
- OverridingFunctions.clear();
-
- // Drop functions from subprograms if they've been overridden by the new
- // compile unit.
- NamedMDNode *CompileUnits = DstM->getNamedMetadata("llvm.dbg.cu");
- if (!CompileUnits)
- return;
- for (unsigned I = 0, E = CompileUnits->getNumOperands(); I != E; ++I) {
- auto *CU = cast<DICompileUnit>(CompileUnits->getOperand(I));
- assert(CU && "Expected valid compile unit");
-
- for (DISubprogram *SP : CU->getSubprograms()) {
- if (!SP || !SP->getFunction() || !Functions.count(SP->getFunction()))
- continue;
-
- // Prevent DebugInfoFinder from tagging this as the canonical subprogram,
- // since the canonical one is in the incoming module.
- SP->replaceFunction(nullptr);
- }
- }
-}
-
/// Merge the linker flags in Src into the Dest module.
bool ModuleLinker::linkModuleFlagsMetadata() {
// If the source module has no module flags, we are done.
@@ -1909,13 +1866,6 @@ bool ModuleLinker::run() {
MapValue(GV, ValueMap, RF_MoveDistinctMDs, &TypeMap, &ValMaterializer);
}
- // Strip replaced subprograms before mapping any metadata -- so that we're
- // not changing metadata from the source module (note that
- // linkGlobalValueBody() eventually calls RemapInstruction() and therefore
- // MapMetadata()) -- but after linking global value protocols -- so that
- // OverridingFunctions has been built.
- stripReplacedSubprograms();
-
// Link in the function bodies that are defined in the source module into
// DstM.
for (Function &SF : *SrcM) {
diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
index bdd1b61f9b2..0e05129b526 100644
--- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
+++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
@@ -95,7 +95,6 @@ namespace {
bool doInitialization(CallGraph &CG) override;
/// The maximum number of elements to expand, or 0 for unlimited.
unsigned maxElements;
- DenseMap<const Function *, DISubprogram *> FunctionDIs;
};
}
@@ -732,15 +731,8 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F,
NF->copyAttributesFrom(F);
// Patch the pointer to LLVM function in debug info descriptor.
- auto DI = FunctionDIs.find(F);
- if (DI != FunctionDIs.end()) {
- DISubprogram *SP = DI->second;
- SP->replaceFunction(NF);
- // Ensure the map is updated so it can be reused on subsequent argument
- // promotions of the same function.
- FunctionDIs.erase(DI);
- FunctionDIs[NF] = SP;
- }
+ NF->setSubprogram(F->getSubprogram());
+ F->setSubprogram(nullptr);
DEBUG(dbgs() << "ARG PROMOTION: Promoting to:" << *NF << "\n"
<< "From: " << *F);
@@ -1023,6 +1015,5 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F,
}
bool ArgPromotion::doInitialization(CallGraph &CG) {
- FunctionDIs = makeSubprogramMap(CG.getModule());
return CallGraphSCCPass::doInitialization(CG);
}
diff --git a/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp b/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
index c870b07f52e..e81c83e6b0c 100644
--- a/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
+++ b/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
@@ -122,14 +122,6 @@ namespace {
typedef SmallVector<RetOrArg, 5> UseVector;
- // Map each LLVM function to corresponding metadata with debug info. If
- // the function is replaced with another one, we should patch the pointer
- // to LLVM function in metadata.
- // As the code generation for module is finished (and DIBuilder is
- // finalized) we assume that subprogram descriptors won't be changed, and
- // they are stored in map for short duration anyway.
- DenseMap<const Function *, DISubprogram *> FunctionDIs;
-
protected:
// DAH uses this to specify a different ID.
explicit DAE(char &ID) : ModulePass(ID) {}
@@ -309,15 +301,7 @@ bool DAE::DeleteDeadVarargs(Function &Fn) {
}
// Patch the pointer to LLVM function in debug info descriptor.
- auto DI = FunctionDIs.find(&Fn);
- if (DI != FunctionDIs.end()) {
- DISubprogram *SP = DI->second;
- SP->replaceFunction(NF);
- // Ensure the map is updated so it can be reused on non-varargs argument
- // eliminations of the same function.
- FunctionDIs.erase(DI);
- FunctionDIs[NF] = SP;
- }
+ NF->setSubprogram(Fn.getSubprogram());
// Fix up any BlockAddresses that refer to the function.
Fn.replaceAllUsesWith(ConstantExpr::getBitCast(NF, Fn.getType()));
@@ -1097,9 +1081,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
}
// Patch the pointer to LLVM function in debug info descriptor.
- auto DI = FunctionDIs.find(F);
- if (DI != FunctionDIs.end())
- DI->second->replaceFunction(NF);
+ NF->setSubprogram(F->getSubprogram());
// Now that the old function is dead, delete it.
F->eraseFromParent();
@@ -1110,9 +1092,6 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
bool DAE::runOnModule(Module &M) {
bool Changed = false;
- // Collect debug info descriptors for functions.
- FunctionDIs = makeSubprogramMap(M);
-
// First pass: Do a simple check to see if any functions can have their "..."
// removed. We can do this if they never call va_start. This loop cannot be
// fused with the next loop, because deleting a function invalidates
diff --git a/llvm/lib/Transforms/IPO/StripSymbols.cpp b/llvm/lib/Transforms/IPO/StripSymbols.cpp
index 15304cca002..46f352f7f9f 100644
--- a/llvm/lib/Transforms/IPO/StripSymbols.cpp
+++ b/llvm/lib/Transforms/IPO/StripSymbols.cpp
@@ -305,6 +305,12 @@ bool StripDeadDebugInfo::runOnModule(Module &M) {
SmallVector<Metadata *, 64> LiveSubprograms;
DenseSet<const MDNode *> VisitedSet;
+ std::set<DISubprogram *> LiveSPs;
+ for (Function &F : M) {
+ if (DISubprogram *SP = F.getSubprogram())
+ LiveSPs.insert(SP);
+ }
+
for (DICompileUnit *DIC : F.compile_units()) {
// Create our live subprogram list.
bool SubprogramChange = false;
@@ -314,7 +320,7 @@ bool StripDeadDebugInfo::runOnModule(Module &M) {
continue;
// If the function referenced by DISP is not null, the function is live.
- if (DISP->getFunction())
+ if (LiveSPs.count(DISP))
LiveSubprograms.push_back(DISP);
else
SubprogramChange = true;
diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index 3b204b77f0e..21ef3207e89 100644
--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -258,7 +258,6 @@ class DataFlowSanitizer : public ModulePass {
DFSanABIList ABIList;
DenseMap<Value *, Function *> UnwrappedFnMap;
AttributeSet ReadOnlyNoneAttrs;
- DenseMap<const Function *, DISubprogram *> FunctionDIs;
Value *getShadowAddress(Value *Addr, Instruction *Pos);
bool isInstrumented(const Function *F);
@@ -610,8 +609,6 @@ bool DataFlowSanitizer::runOnModule(Module &M) {
if (ABIList.isIn(M, "skip"))
return false;
- FunctionDIs = makeSubprogramMap(M);
-
if (!GetArgTLSPtr) {
Type *ArgTLSTy = ArrayType::get(ShadowTy, 64);
ArgTLS = Mod->getOrInsertGlobal("__dfsan_arg_tls", ArgTLSTy);
@@ -768,11 +765,6 @@ bool DataFlowSanitizer::runOnModule(Module &M) {
ConstantExpr::getBitCast(NewF, PointerType::getUnqual(FT));
F.replaceAllUsesWith(WrappedFnCst);
- // Patch the pointer to LLVM function in debug info descriptor.
- auto DI = FunctionDIs.find(&F);
- if (DI != FunctionDIs.end())
- DI->second->replaceFunction(&F);
-
UnwrappedFnMap[WrappedFnCst] = &F;
*i = NewF;
diff --git a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
index d2e707e1996..fa939aee252 100644
--- a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+++ b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
@@ -138,6 +138,7 @@ namespace {
Module *M;
LLVMContext *Ctx;
SmallVector<std::unique_ptr<GCOVFunction>, 16> Funcs;
+ DenseMap<DISubprogram *, Function *> FnMap;
};
}
@@ -309,13 +310,12 @@ namespace {
// object users can construct, the blocks and lines will be rooted here.
class GCOVFunction : public GCOVRecord {
public:
- GCOVFunction(const DISubprogram *SP, raw_ostream *os, uint32_t Ident,
- bool UseCfgChecksum, bool ExitBlockBeforeBody)
+ GCOVFunction(const DISubprogram *SP, Function *F, raw_ostream *os,
+ uint32_t Ident, bool UseCfgChecksum, bool ExitBlockBeforeBody)
: SP(SP), Ident(Ident), UseCfgChecksum(UseCfgChecksum), CfgChecksum(0),
ReturnBlock(1, os) {
this->os = os;
- Function *F = SP->getFunction();
DEBUG(dbgs() << "Function: " << getFunctionName(SP) << "\n");
uint32_t i = 0;
@@ -450,6 +450,12 @@ bool GCOVProfiler::runOnModule(Module &M) {
this->M = &M;
Ctx = &M.getContext();
+ FnMap.clear();
+ for (Function &F : M) {
+ if (DISubprogram *SP = F.getSubprogram())
+ FnMap[SP] = &F;
+ }
+
if (Options.EmitNotes) emitProfileNotes();
if (Options.EmitData) return emitProfileArcs();
return false;
@@ -494,7 +500,7 @@ void GCOVProfiler::emitProfileNotes() {
unsigned FunctionIdent = 0;
for (auto *SP : CU->getSubprograms()) {
- Function *F = SP->getFunction();
+ Function *F = FnMap[SP];
if (!F) continue;
if (!functionHasLines(F)) continue;
@@ -506,7 +512,7 @@ void GCOVProfiler::emitProfileNotes() {
++It;
EntryBlock.splitBasicBlock(It);
- Funcs.push_back(make_unique<GCOVFunction>(SP, &out, FunctionIdent++,
+ Funcs.push_back(make_unique<GCOVFunction>(SP, F, &out, FunctionIdent++,
Options.UseCfgChecksum,
Options.ExitBlockBeforeBody));
GCOVFunction &Func = *Funcs.back();
@@ -573,7 +579,7 @@ bool GCOVProfiler::emitProfileArcs() {
auto *CU = cast<DICompileUnit>(CU_Nodes->getOperand(i));
SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP;
for (auto *SP : CU->getSubprograms()) {
- Function *F = SP->getFunction();
+ Function *F = FnMap[SP];
if (!F) continue;
if (!functionHasLines(F)) continue;
if (!Result) Result = true;
diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp
index 86f7068f975..bd6cd3a87b5 100644
--- a/llvm/lib/Transforms/Utils/CloneFunction.cpp
+++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp
@@ -188,11 +188,9 @@ static void CloneDebugInfoMetadata(Function *NewFunc, const Function *OldFunc,
const DISubprogram *OldSubprogramMDNode = FindSubprogram(OldFunc, Finder);
if (!OldSubprogramMDNode) return;
- // Ensure that OldFunc appears in the map.
- // (if it's already there it must point to NewFunc anyway)
- VMap[OldFunc] = NewFunc;
auto *NewSubprogram =
cast<DISubprogram>(MapMetadata(OldSubprogramMDNode, VMap));
+ NewFunc->setSubprogram(NewSubprogram);
for (auto *CU : Finder.compile_units()) {
auto Subprograms = CU->getSubprograms();
OpenPOWER on IntegriCloud