From 64c7aa6f923aea316e4823b5446527c97c1c8cfe Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Fri, 21 Jul 2017 02:07:33 +0000 Subject: [PATCH] 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 --- test/tools/dsymutil/Inputs/modules/1.o | Bin 2444 -> 2596 bytes test/tools/dsymutil/Inputs/modules/2.o | Bin 0 -> 1788 bytes test/tools/dsymutil/X86/modules.m | 49 +++++++++++++++++++------ tools/dsymutil/DwarfLinker.cpp | 22 ++++++++--- 4 files changed, 53 insertions(+), 18 deletions(-) create mode 100644 test/tools/dsymutil/Inputs/modules/2.o diff --git a/test/tools/dsymutil/Inputs/modules/1.o b/test/tools/dsymutil/Inputs/modules/1.o index eca930c905c47c7dd176d4cd9d1c558858739577..ef368b85d8fcaddfc27d8cdcfea2dc86bc134b20 100644 GIT binary patch literal 2596 zcmb7GO>7%g5T4!j+K!!UoEnuxAnHS*saiRfS`iCUh?Ax`QV$S9%ca_^?Mg#)Np4oHARr5r#);)2?W@XhYq_%BhzNb}~+ zym{Y#Z{Cl6`|h9r28bku&_I3An926ef2A*YW z9Ylc-(@{T{U-i|}uIp9!fdsuUK|Y*Uz37QysG=@M0qPJ@7d6 zvv=RR_?e6Pd>OmpPSExC`+Gy+jSIXjfhSxF6D@juw%&QkTegGPS-&lT_r91k3|=h1 z@4=7v&AHIMAt#TEI|%(loPQ3p4<7V9v{m>_dfFP_PyeO#`knNKb9pzX?(>ZG<$u!a zwZGDvQ@^sikz8Ni+L+q9@GX1e&}<%eE><_o6{~2+o{T5riP&(pT(d95P9&0}iP596 z;e5Vc7-@+mk5ZwStL4o~yg(y#rdXsnjljf9*#b=%Wr~lWb-aRM*<{&OGRg~CZt9d> zL`DWWkBQQN^tcvP6)p1cBifyn@PKpxkA?i0q-d)R?ezwpY~>(LM-}a<@YAT5FG`9w zh93eoNE{iA68YmmIp7~3bd!z@O-G+aMnEN5gr<=dJlW><90t%c;V>{m{rCWOV}P1e zep?y(d?N7K1pj2*hWenua9)fEjXEAt3U=q_9Ajq^&2vy5Q8v-cK;^WLR zMC?fC=D28$y>T3|IT81cf9qTfQRm!k$p6VvfWi6@gF(12q4El;Sh%xh zVoc_C{inCXiPg1mHui4gEPNeWhVnvroC|&s3gJ3)harO)joe*)%>Sa#Xly?fa5<}GDUa$fcr0O&q3#Z w7Cv?A1(%TjkgzaJ(9ge-Z25iccR2Bg6KgM&Ud)yCx>d{@RXk0kJ1+^*f1gY)4FCWD literal 2444 zcmb7GOKcle6umQJ$BrkNICa$~LZV(6k^-_LQXrHl#i1>U#DbPUD+-#79Vd0M$Cm9x zsbnb;AJK>nSs+0-NbJ}^DMErZs@fHFNxOnY1uT%dMEuY3yz#dY?v?KM-FM!d`#zfQ z|M=~nkcego1ULY`Nf8Hw#=&Rl??H|lyQ{SC15?PuYMyP^a+|dlh;1*OIJ?yHeQQD) z#Oqi#AlrTpwQZL&7qWJ~=&a@P?rO=lkEfT?tqdP0tU?EatubXq+atEUlFO{G+0|O5 z5eD9w^y!n$l$5fzl|Iyqr#F*f_;`guj!x>xux+PYF63<2DH5)y zJ|AyZVf2f~Q^P6U-+N81o=|vS-A{dGC)QZFrwThV|X^oAh3r@x0|az1P2kltCWgU?B1tROCwrst^O3&ei>LOgaIH zJO?EYH*8wrAvH`u#FkauzXEl? z99Wm5kec?VH4LdSAFL&%dH)b8mR8maxoWZqyUk&8K$pShfi!N5776d)eM=7l3@04$ jF~}Zx@1JPTK}I%pfsq6LBQc z^Hz1eI`HL8Qb#gt{S9El?z`C10{Gm`KU&#Ko0yNCTI z@ocKwAgihaAetrUN<7DV?BjYG?>!YgAiG0&pR(dyA$%xaV0pWC=OEq*PC#Vdj>xZN zH6n^>eiBc@4#%_FZPzwEtA+Fq^jjdHYsBx}P<{f>uRm#ENt)j(;ms1>j}h@Aer>Cf z#_Of<3UCf7Nu7t_7d~$v+V39WwFqQsD4w{_uH)HQlIAx~Pd`t1Z-(IEzD!|m?r2nj z<)=Wu(*61d7S}bO?;t9%+vJ8ZKN?qh|*l$M=jY#Zs|k%!NVMdul9}D&+sSSv{{R`qatOI=m>CnWES7 z*JqZrt6B!SR0^z?S9EmY3z_GNu4%$iC!p#1(3{PsqoEQ7&1zC9L|^9>bW=rs&&0{kPGr~taMR$Y<1idKGQMNAy!hv|o( zFTxr=2;*l!QR21er)&R!{7(+v1k`B+0}+3cELau#$DLpdG55Z_&`SN6+70k`K(Rrr z!%ZkKhOOs8L9k0?jBV5Vcn+o+X28h#FMSe5E_#K;mf!5UcBd#`4R#?)W?9TQhL4b9 ICawhg3)QN(ZvX%Q literal 0 HcmV?d00001 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; -- 2.50.1