From: Adrian Prantl Date: Fri, 21 Jul 2017 02:07:33 +0000 (+0000) Subject: dsymutil: strip unused types from imported DW_TAG_modules X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=64c7aa6f923aea316e4823b5446527c97c1c8cfe;p=llvm dsymutil: strip unused types from imported DW_TAG_modules This patch teaches dsymutil to strip types from the imported DW_TAG_module inside of an object file (not inside the PCM) if they can be resolved to the full definition inside the PCM. This reduces the size of the .dSYM from WebCore from webkit.org by almost 2/3. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@308710 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/tools/dsymutil/Inputs/modules/1.o b/test/tools/dsymutil/Inputs/modules/1.o index eca930c905c..ef368b85d8f 100644 Binary files a/test/tools/dsymutil/Inputs/modules/1.o and b/test/tools/dsymutil/Inputs/modules/1.o differ diff --git a/test/tools/dsymutil/Inputs/modules/2.o b/test/tools/dsymutil/Inputs/modules/2.o new file mode 100644 index 00000000000..0a7100f4651 Binary files /dev/null and b/test/tools/dsymutil/Inputs/modules/2.o differ diff --git a/test/tools/dsymutil/X86/modules.m b/test/tools/dsymutil/X86/modules.m index 046a8c1304a..f693ef9019b 100644 --- a/test/tools/dsymutil/X86/modules.m +++ b/test/tools/dsymutil/X86/modules.m @@ -11,9 +11,11 @@ EOF clang -D BAR_H -E -o Bar.h modules.m clang -D FOO_H -E -o Foo.h modules.m - clang -cc1 -emit-obj -fmodules -fmodule-map-file=modules.modulemap \ - -fmodule-format=obj -g -dwarf-ext-refs -fmodules-cache-path=. \ - -fdisable-module-hash modules.m -o 1.o + clang -D ODR_VIOLATION_C -E -o odr_violation.c modules.m + clang -c -fmodules -fmodule-map-file=modules.modulemap \ + -g -gmodules -fmodules-cache-path=. \ + -Xclang -fdisable-module-hash modules.m -o 1.o + clang -c -g odr_violation.c -o 2.o */ // RUN: llvm-dsymutil -f -oso-prepend-path=%p/../Inputs/modules \ @@ -57,7 +59,7 @@ struct PruneMeNot; // CHECK: 0x0[[FOO:.*]]: DW_TAG_module // CHECK-NEXT: DW_AT_name{{.*}}"Foo" // CHECK-NOT: DW_TAG -// CHECK: DW_TAG_typedef +// CHECK: 0x0[[BARTD:.*]]: DW_TAG_typedef // CHECK-NOT: DW_TAG // CHECK: DW_AT_type [DW_FORM_ref_addr] (0x{{0*}}[[BAR]]) // CHECK: DW_TAG_structure_type @@ -75,19 +77,25 @@ struct S {}; } @end +#else +// --------------------------------------------------------------------- +#ifdef ODR_VIOLATION_C +// --------------------------------------------------------------------- + +struct Bar { + int i; +}; +typedef struct Bar Bar; +Bar odr_violation = { 42 }; + // --------------------------------------------------------------------- #else // --------------------------------------------------------------------- // CHECK: DW_TAG_compile_unit // CHECK: DW_AT_low_pc -// CHECK-NOT:DW_TAG -// CHECK: DW_TAG_module -// CHECK-NEXT: DW_AT_name{{.*}}"Foo" -// CHECK-NOT: DW_TAG -// CHECK: DW_TAG_typedef -// CHECK-NOT: DW_TAG -// CHECK: NULL +// CHECK-NOT: DW_TAG_module +// CHECK-NOT: DW_TAG_typedef // // CHECK: DW_TAG_imported_declaration // CHECK-NOT: DW_TAG @@ -97,6 +105,10 @@ struct S {}; // CHECK: DW_AT_name {{.*}}"main" // // CHECK: DW_TAG_variable +// CHECK-NOT: DW_TAG +// CHECK: DW_AT_name{{.*}}"bar" +// CHECK-NOT: DW_TAG +// CHECK: DW_AT_type [DW_FORM_ref_addr] (0x{{0*}}[[BARTD]] // CHECK: DW_TAG_variable // CHECK-NOT: DW_TAG // CHECK: DW_AT_name{{.*}}"foo" @@ -105,13 +117,26 @@ struct S {}; // // CHECK: 0x{{0*}}[[PTR]]: DW_TAG_pointer_type // CHECK-NEXT DW_AT_type [DW_FORM_ref_addr] {0x{{0*}}[[INTERFACE]]) +extern int odr_violation; @import Foo; int main(int argc, char **argv) { Bar bar; Foo *foo = 0; - bar.value = 42; + bar.value = odr_violation; return bar.value; } #endif #endif +#endif + +// CHECK: DW_TAG_compile_unit +// CHECK: DW_AT_name {{.*}}"odr_violation.c" +// CHECK: DW_TAG_variable +// CHECK: DW_AT_name {{.*}}"odr_violation" +// CHECK: DW_AT_type [DW_FORM_ref4] ({{.*}}{0x{{0*}}[[BAR2:.*]]}) +// CHECK: 0x{{0*}}[[BAR2]]: DW_TAG_typedef +// CHECK: DW_AT_type [DW_FORM_ref4] ({{.*}}{0x{{0*}}[[BAR3:.*]]}) +// CHECK: DW_AT_name {{.*}}"Bar" +// CHECK: 0x{{0*}}[[BAR3]]: DW_TAG_structure_type +// CHECK-NEXT: DW_AT_name {{.*}}"Bar" diff --git a/tools/dsymutil/DwarfLinker.cpp b/tools/dsymutil/DwarfLinker.cpp index 94428bcab51..d82149e50b4 100644 --- a/tools/dsymutil/DwarfLinker.cpp +++ b/tools/dsymutil/DwarfLinker.cpp @@ -98,6 +98,7 @@ class DeclContext { uint32_t Line; uint32_t ByteSize; uint16_t Tag; + unsigned DefinedInClangModule : 1; StringRef Name; StringRef File; const DeclContext &Parent; @@ -112,15 +113,17 @@ public: DeclContext() : QualifiedNameHash(0), Line(0), ByteSize(0), - Tag(dwarf::DW_TAG_compile_unit), Name(), File(), Parent(*this), - LastSeenDIE(), LastSeenCompileUnitID(0), CanonicalDIEOffset(0) {} + Tag(dwarf::DW_TAG_compile_unit), DefinedInClangModule(0), Name(), + File(), Parent(*this), LastSeenDIE(), LastSeenCompileUnitID(0), + CanonicalDIEOffset(0) {} DeclContext(unsigned Hash, uint32_t Line, uint32_t ByteSize, uint16_t Tag, StringRef Name, StringRef File, const DeclContext &Parent, DWARFDie LastSeenDIE = DWARFDie(), unsigned CUId = 0) : QualifiedNameHash(Hash), Line(Line), ByteSize(ByteSize), Tag(Tag), - Name(Name), File(File), Parent(Parent), LastSeenDIE(LastSeenDIE), - LastSeenCompileUnitID(CUId), CanonicalDIEOffset(0) {} + DefinedInClangModule(0), Name(Name), File(File), Parent(Parent), + LastSeenDIE(LastSeenDIE), LastSeenCompileUnitID(CUId), + CanonicalDIEOffset(0) {} uint32_t getQualifiedNameHash() const { return QualifiedNameHash; } @@ -129,6 +132,9 @@ public: uint32_t getCanonicalDIEOffset() const { return CanonicalDIEOffset; } void setCanonicalDIEOffset(uint32_t Offset) { CanonicalDIEOffset = Offset; } + bool isDefinedInClangModule() const { return DefinedInClangModule; } + void setDefinedInClangModule(bool Val) { DefinedInClangModule = Val; } + uint16_t getTag() const { return Tag; } StringRef getName() const { return Name; } }; @@ -1801,6 +1807,8 @@ static bool analyzeContextInfo(const DWARFDie &DIE, CurrentDeclContext = PtrInvalidPair.getPointer(); Info.Ctxt = PtrInvalidPair.getInt() ? nullptr : PtrInvalidPair.getPointer(); + if (Info.Ctxt) + Info.Ctxt->setDefinedInClangModule(InClangModule); } else Info.Ctxt = CurrentDeclContext = nullptr; } @@ -2172,7 +2180,6 @@ unsigned DwarfLinker::shouldKeepDIE(RelocationManager &RelocMgr, return shouldKeepVariableDIE(RelocMgr, DIE, Unit, MyInfo, Flags); case dwarf::DW_TAG_subprogram: return shouldKeepSubprogramDIE(RelocMgr, DIE, Unit, MyInfo, Flags); - case dwarf::DW_TAG_module: case dwarf::DW_TAG_imported_module: case dwarf::DW_TAG_imported_declaration: case dwarf::DW_TAG_imported_unit: @@ -2232,6 +2239,8 @@ void DwarfLinker::keepDIEAndDependencies(RelocationManager &RelocMgr, resolveDIEReference(*this, Units, Val, Unit, Die, ReferencedCU)) { uint32_t RefIdx = ReferencedCU->getOrigUnit().getDIEIndex(RefDIE); CompileUnit::DIEInfo &Info = ReferencedCU->getInfo(RefIdx); + bool IsModuleRef = Info.Ctxt && Info.Ctxt->getCanonicalDIEOffset() && + Info.Ctxt->isDefinedInClangModule(); // If the referenced DIE has a DeclContext that has already been // emitted, then do not keep the one in this CU. We'll link to // the canonical DIE in cloneDieReferenceAttribute. @@ -2240,7 +2249,8 @@ void DwarfLinker::keepDIEAndDependencies(RelocationManager &RelocMgr, // ReferencedCU->hasODR() && CU.hasODR(). // FIXME: compatibility with dsymutil-classic. There is no // reason not to unique ref_addr references. - if (AttrSpec.Form != dwarf::DW_FORM_ref_addr && UseODR && Info.Ctxt && + if (AttrSpec.Form != dwarf::DW_FORM_ref_addr && (UseODR || IsModuleRef) && + Info.Ctxt && Info.Ctxt != ReferencedCU->getInfo(Info.ParentIdx).Ctxt && Info.Ctxt->getCanonicalDIEOffset() && isODRAttribute(AttrSpec.Attr)) continue;