[PR27284] Reverse the ownership between DICompileUnit and DISubprogram.
Currently each Function points to a DISubprogram and DISubprogram has a
scope field. For member functions the scope is a DICompositeType. DIScopes
point to the DICompileUnit to facilitate type uniquing.
Distinct DISubprograms (with isDefinition: true) are not part of the type
hierarchy and cannot be uniqued. This change removes the subprograms
list from DICompileUnit and instead adds a pointer to the owning compile
unit to distinct DISubprograms. This would make it easy for ThinLTO to
strip unneeded DISubprograms and their transitively referenced debug info.
Motivation
----------
Materializing DISubprograms is currently the most expensive operation when
doing a ThinLTO build of clang.
We want the DISubprogram to be stored in a separate Bitcode block (or the
same block as the function body) so we can avoid having to expensively
deserialize all DISubprograms together with the global metadata. If a
function has been inlined into another subprogram we need to store a
reference the block containing the inlined subprogram.
Attached to https://llvm.org/bugs/show_bug.cgi?id=27284 is a python script
that updates LLVM IR testcases to the new format.
http://reviews.llvm.org/D19034
<rdar://problem/25256815>
llvm-svn: 266446
diff --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp
index ba60364..1159616 100644
--- a/llvm/unittests/IR/MetadataTest.cpp
+++ b/llvm/unittests/IR/MetadataTest.cpp
@@ -84,13 +84,19 @@
}
DISubprogram *getSubprogram() {
return DISubprogram::getDistinct(Context, nullptr, "", "", nullptr, 0,
- nullptr, false, false, 0, nullptr, 0, 0, 0,
- 0);
+ nullptr, false, false, 0, nullptr,
+ 0, 0, 0, false, nullptr);
}
DIScopeRef getSubprogramRef() { return getSubprogram()->getRef(); }
DIFile *getFile() {
return DIFile::getDistinct(Context, "file.c", "/path/to/dir");
}
+ DICompileUnit *getUnit() {
+ return DICompileUnit::getDistinct(Context, 1, getFile(), "clang", false,
+ "-g", 2, "", DICompileUnit::FullDebug,
+ getTuple(), getTuple(), getTuple(),
+ getTuple(), getTuple(), 0);
+ }
DITypeRef getBasicType(StringRef Name) {
return DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, Name)
->getRef();
@@ -1308,7 +1314,6 @@
auto EmissionKind = DICompileUnit::FullDebug;
MDTuple *EnumTypes = getTuple();
MDTuple *RetainedTypes = getTuple();
- MDTuple *Subprograms = getTuple();
MDTuple *GlobalVariables = getTuple();
MDTuple *ImportedEntities = getTuple();
uint64_t DWOId = 0x10000000c0ffee;
@@ -1316,7 +1321,7 @@
auto *N = DICompileUnit::getDistinct(
Context, SourceLanguage, File, Producer, IsOptimized, Flags,
RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
- RetainedTypes, Subprograms, GlobalVariables, ImportedEntities, Macros,
+ RetainedTypes, GlobalVariables, ImportedEntities, Macros,
DWOId);
EXPECT_EQ(dwarf::DW_TAG_compile_unit, N->getTag());
@@ -1330,7 +1335,6 @@
EXPECT_EQ(EmissionKind, N->getEmissionKind());
EXPECT_EQ(EnumTypes, N->getEnumTypes().get());
EXPECT_EQ(RetainedTypes, N->getRetainedTypes().get());
- EXPECT_EQ(Subprograms, N->getSubprograms().get());
EXPECT_EQ(GlobalVariables, N->getGlobalVariables().get());
EXPECT_EQ(ImportedEntities, N->getImportedEntities().get());
EXPECT_EQ(Macros, N->getMacros().get());
@@ -1348,7 +1352,6 @@
EXPECT_EQ(EmissionKind, Temp->getEmissionKind());
EXPECT_EQ(EnumTypes, Temp->getEnumTypes().get());
EXPECT_EQ(RetainedTypes, Temp->getRetainedTypes().get());
- EXPECT_EQ(Subprograms, Temp->getSubprograms().get());
EXPECT_EQ(GlobalVariables, Temp->getGlobalVariables().get());
EXPECT_EQ(ImportedEntities, Temp->getImportedEntities().get());
EXPECT_EQ(Macros, Temp->getMacros().get());
@@ -1376,14 +1379,7 @@
auto *N = DICompileUnit::getDistinct(
Context, SourceLanguage, File, Producer, IsOptimized, Flags,
RuntimeVersion, SplitDebugFilename, EmissionKind, EnumTypes,
- RetainedTypes, nullptr, nullptr, ImportedEntities, nullptr, DWOId);
-
- auto *Subprograms = MDTuple::getDistinct(Context, None);
- EXPECT_EQ(nullptr, N->getSubprograms().get());
- N->replaceSubprograms(Subprograms);
- EXPECT_EQ(Subprograms, N->getSubprograms().get());
- N->replaceSubprograms(nullptr);
- EXPECT_EQ(nullptr, N->getSubprograms().get());
+ RetainedTypes, nullptr, ImportedEntities, nullptr, DWOId);
auto *GlobalVariables = MDTuple::getDistinct(Context, None);
EXPECT_EQ(nullptr, N->getGlobalVariables().get());
@@ -1421,11 +1417,12 @@
MDTuple *TemplateParams = getTuple();
DISubprogram *Declaration = getSubprogram();
MDTuple *Variables = getTuple();
+ DICompileUnit *Unit = getUnit();
auto *N = DISubprogram::get(
Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, Flags,
- IsOptimized, TemplateParams, Declaration, Variables);
+ IsOptimized, Unit, TemplateParams, Declaration, Variables);
EXPECT_EQ(dwarf::DW_TAG_subprogram, N->getTag());
EXPECT_EQ(Scope, N->getScope());
@@ -1442,99 +1439,105 @@
EXPECT_EQ(VirtualIndex, N->getVirtualIndex());
EXPECT_EQ(Flags, N->getFlags());
EXPECT_EQ(IsOptimized, N->isOptimized());
+ EXPECT_EQ(Unit, N->getUnit());
EXPECT_EQ(TemplateParams, N->getTemplateParams().get());
EXPECT_EQ(Declaration, N->getDeclaration());
EXPECT_EQ(Variables, N->getVariables().get());
EXPECT_EQ(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
Type, IsLocalToUnit, IsDefinition, ScopeLine,
ContainingType, Virtuality, VirtualIndex,
- Flags, IsOptimized, TemplateParams,
+ Flags, IsOptimized, Unit, TemplateParams,
Declaration, Variables));
EXPECT_NE(N, DISubprogram::get(Context, getCompositeType(), Name, LinkageName,
File, Line, Type, IsLocalToUnit, IsDefinition,
ScopeLine, ContainingType, Virtuality,
- VirtualIndex, Flags, IsOptimized,
+ VirtualIndex, Flags, IsOptimized, Unit,
TemplateParams, Declaration, Variables));
EXPECT_NE(N, DISubprogram::get(Context, Scope, "other", LinkageName, File,
Line, Type, IsLocalToUnit, IsDefinition,
ScopeLine, ContainingType, Virtuality,
- VirtualIndex, Flags, IsOptimized,
+ VirtualIndex, Flags, IsOptimized, Unit,
TemplateParams, Declaration, Variables));
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, "other", File, Line,
Type, IsLocalToUnit, IsDefinition, ScopeLine,
ContainingType, Virtuality, VirtualIndex,
- Flags, IsOptimized, TemplateParams,
+ Flags, IsOptimized, Unit, TemplateParams,
Declaration, Variables));
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, getFile(),
Line, Type, IsLocalToUnit, IsDefinition,
ScopeLine, ContainingType, Virtuality,
- VirtualIndex, Flags, IsOptimized,
+ VirtualIndex, Flags, IsOptimized, Unit,
TemplateParams, Declaration, Variables));
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File,
Line + 1, Type, IsLocalToUnit, IsDefinition,
ScopeLine, ContainingType, Virtuality,
- VirtualIndex, Flags, IsOptimized,
+ VirtualIndex, Flags, IsOptimized, Unit,
TemplateParams, Declaration, Variables));
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
getSubroutineType(), IsLocalToUnit,
IsDefinition, ScopeLine, ContainingType,
Virtuality, VirtualIndex, Flags, IsOptimized,
- TemplateParams, Declaration, Variables));
+ Unit, TemplateParams, Declaration, Variables));
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
Type, !IsLocalToUnit, IsDefinition, ScopeLine,
ContainingType, Virtuality, VirtualIndex,
- Flags, IsOptimized, TemplateParams,
+ Flags, IsOptimized, Unit, TemplateParams,
Declaration, Variables));
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
Type, IsLocalToUnit, !IsDefinition, ScopeLine,
ContainingType, Virtuality, VirtualIndex,
- Flags, IsOptimized, TemplateParams,
+ Flags, IsOptimized, Unit, TemplateParams,
Declaration, Variables));
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
Type, IsLocalToUnit, IsDefinition,
ScopeLine + 1, ContainingType, Virtuality,
- VirtualIndex, Flags, IsOptimized,
+ VirtualIndex, Flags, IsOptimized, Unit,
TemplateParams, Declaration, Variables));
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
Type, IsLocalToUnit, IsDefinition, ScopeLine,
getCompositeType(), Virtuality, VirtualIndex,
- Flags, IsOptimized, TemplateParams,
+ Flags, IsOptimized, Unit, TemplateParams,
Declaration, Variables));
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
Type, IsLocalToUnit, IsDefinition, ScopeLine,
ContainingType, Virtuality + 1, VirtualIndex,
- Flags, IsOptimized, TemplateParams,
+ Flags, IsOptimized, Unit, TemplateParams,
Declaration, Variables));
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
Type, IsLocalToUnit, IsDefinition, ScopeLine,
ContainingType, Virtuality, VirtualIndex + 1,
- Flags, IsOptimized, TemplateParams,
+ Flags, IsOptimized, Unit, TemplateParams,
Declaration, Variables));
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
Type, IsLocalToUnit, IsDefinition, ScopeLine,
ContainingType, Virtuality, VirtualIndex,
- NotFlags, IsOptimized, TemplateParams,
+ NotFlags, IsOptimized, Unit, TemplateParams,
Declaration, Variables));
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
Type, IsLocalToUnit, IsDefinition, ScopeLine,
ContainingType, Virtuality, VirtualIndex,
- Flags, !IsOptimized, TemplateParams,
+ Flags, !IsOptimized, Unit, TemplateParams,
Declaration, Variables));
- EXPECT_NE(N,
- DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
- Type, IsLocalToUnit, IsDefinition, ScopeLine,
- ContainingType, Virtuality, VirtualIndex, Flags,
- IsOptimized, getTuple(), Declaration, Variables));
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
Type, IsLocalToUnit, IsDefinition, ScopeLine,
ContainingType, Virtuality, VirtualIndex,
- Flags, IsOptimized, TemplateParams,
+ Flags, IsOptimized, nullptr, TemplateParams,
+ Declaration, Variables));
+ EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Unit, getTuple(),
+ Declaration, Variables));
+ EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
+ Type, IsLocalToUnit, IsDefinition, ScopeLine,
+ ContainingType, Virtuality, VirtualIndex,
+ Flags, IsOptimized, Unit, TemplateParams,
getSubprogram(), Variables));
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
Type, IsLocalToUnit, IsDefinition, ScopeLine,
ContainingType, Virtuality, VirtualIndex,
- Flags, IsOptimized, TemplateParams,
+ Flags, IsOptimized, Unit, TemplateParams,
Declaration, getTuple()));
TempDISubprogram Temp = N->clone();