[llvm] r337503 - [ThinLTO] Only emit referenced type id records in index files

Teresa Johnson via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 19 15:25:56 PDT 2018


Author: tejohnson
Date: Thu Jul 19 15:25:56 2018
New Revision: 337503

URL: http://llvm.org/viewvc/llvm-project?rev=337503&view=rev
Log:
[ThinLTO] Only emit referenced type id records in index files

Summary:
Currently all type ids are emitted into the index file when it is
written. For distributed ThinLTO, that meant that all type ids were
being duplicated into every single distributed index file, regardless of
whether they were referenced, leading to huge amounts of unnecessary
duplication and size bloat.

Keep track of the type id GUIDs actually referenced by the GV summary
records being emitted, and only emit those type IDs.

Add a new test, and fix test/Assembler/thinlto-summary.ll so that all
type ids are referenced to prevent deletion in that test.

Reviewers: pcc

Subscribers: mehdi_amini, inglorion, eraman, steven_wu, dexonsmith, vitalybuka, llvm-commits

Differential Revision: https://reviews.llvm.org/D49565

Added:
    llvm/trunk/test/ThinLTO/X86/Inputs/cfi-distributed.ll
    llvm/trunk/test/ThinLTO/X86/cfi-distributed.ll
Modified:
    llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
    llvm/trunk/test/Assembler/thinlto-summary.ll

Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=337503&r1=337502&r2=337503&view=diff
==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Thu Jul 19 15:25:56 2018
@@ -3353,10 +3353,14 @@ void IndexBitcodeWriter::writeModStrings
 
 /// Write the function type metadata related records that need to appear before
 /// a function summary entry (whether per-module or combined).
-static void writeFunctionTypeMetadataRecords(BitstreamWriter &Stream,
-                                             FunctionSummary *FS) {
-  if (!FS->type_tests().empty())
+static void writeFunctionTypeMetadataRecords(
+    BitstreamWriter &Stream, FunctionSummary *FS,
+    std::set<GlobalValue::GUID> &ReferencedTypeIds) {
+  if (!FS->type_tests().empty()) {
     Stream.EmitRecord(bitc::FS_TYPE_TESTS, FS->type_tests());
+    for (auto &TT : FS->type_tests())
+      ReferencedTypeIds.insert(TT);
+  }
 
   SmallVector<uint64_t, 64> Record;
 
@@ -3368,6 +3372,7 @@ static void writeFunctionTypeMetadataRec
     for (auto &VF : VFs) {
       Record.push_back(VF.GUID);
       Record.push_back(VF.Offset);
+      ReferencedTypeIds.insert(VF.GUID);
     }
     Stream.EmitRecord(Ty, Record);
   };
@@ -3382,6 +3387,7 @@ static void writeFunctionTypeMetadataRec
     for (auto &VC : VCs) {
       Record.clear();
       Record.push_back(VC.VFunc.GUID);
+      ReferencedTypeIds.insert(VC.VFunc.GUID);
       Record.push_back(VC.VFunc.Offset);
       Record.insert(Record.end(), VC.Args.begin(), VC.Args.end());
       Stream.EmitRecord(Ty, Record);
@@ -3447,7 +3453,8 @@ void ModuleBitcodeWriterBase::writePerMo
   NameVals.push_back(ValueID);
 
   FunctionSummary *FS = cast<FunctionSummary>(Summary);
-  writeFunctionTypeMetadataRecords(Stream, FS);
+  std::set<GlobalValue::GUID> ReferencedTypeIds;
+  writeFunctionTypeMetadataRecords(Stream, FS, ReferencedTypeIds);
 
   NameVals.push_back(getEncodedGVSummaryFlags(FS->flags()));
   NameVals.push_back(FS->instCount());
@@ -3702,6 +3709,10 @@ void IndexBitcodeWriter::writeCombinedGl
 
   SmallVector<uint64_t, 64> NameVals;
 
+  // Set that will be populated during call to writeFunctionTypeMetadataRecords
+  // with the type ids referenced by this index file.
+  std::set<GlobalValue::GUID> ReferencedTypeIds;
+
   // For local linkage, we also emit the original name separately
   // immediately after the record.
   auto MaybeEmitOriginalName = [&](GlobalValueSummary &S) {
@@ -3753,7 +3764,7 @@ void IndexBitcodeWriter::writeCombinedGl
     }
 
     auto *FS = cast<FunctionSummary>(S);
-    writeFunctionTypeMetadataRecords(Stream, FS);
+    writeFunctionTypeMetadataRecords(Stream, FS, ReferencedTypeIds);
 
     NameVals.push_back(*ValueId);
     NameVals.push_back(Index.getModuleId(FS->modulePath()));
@@ -3862,6 +3873,9 @@ void IndexBitcodeWriter::writeCombinedGl
 
   if (!Index.typeIds().empty()) {
     for (auto &S : Index.typeIds()) {
+      // Skip if not referenced in any GV summary within this index file.
+      if (!ReferencedTypeIds.count(GlobalValue::getGUID(S.first)))
+        continue;
       writeTypeIdSummaryRecord(NameVals, StrtabBuilder, S.first, S.second);
       Stream.EmitRecord(bitc::FS_TYPE_ID, NameVals);
       NameVals.clear();

Modified: llvm/trunk/test/Assembler/thinlto-summary.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Assembler/thinlto-summary.ll?rev=337503&r1=337502&r2=337503&view=diff
==============================================================================
--- llvm/trunk/test/Assembler/thinlto-summary.ll (original)
+++ llvm/trunk/test/Assembler/thinlto-summary.ll Thu Jul 19 15:25:56 2018
@@ -50,7 +50,7 @@
 ^20 = gv: (guid: 19, summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 8, typeIdInfo: (typeTestAssumeVCalls: (vFuncId: (^27, offset: 16))))))
 ^21 = gv: (guid: 20, summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 5, typeIdInfo: (typeCheckedLoadVCalls: (vFuncId: (^25, offset: 16))))))
 ^22 = gv: (guid: 21, summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 15, typeIdInfo: (typeTestAssumeConstVCalls: (vFuncId: (^27, offset: 16), args: (42), vFuncId: (^27, offset: 24), args: (43))))))
-^23 = gv: (guid: 22, summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 5, typeIdInfo: (typeCheckedLoadConstVCalls: (vFuncId: (^27, offset: 16), args: (42))))))
+^23 = gv: (guid: 22, summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 5, typeIdInfo: (typeCheckedLoadConstVCalls: (vFuncId: (^28, offset: 16), args: (42))))))
 
 ; Test TypeId summaries:
 
@@ -88,7 +88,7 @@
 ; CHECK: ^20 = gv: (guid: 19, summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 8, typeIdInfo: (typeTestAssumeVCalls: (vFuncId: (^27, offset: 16))))))
 ; CHECK: ^21 = gv: (guid: 20, summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 5, typeIdInfo: (typeCheckedLoadVCalls: (vFuncId: (^25, offset: 16))))))
 ; CHECK: ^22 = gv: (guid: 21, summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 15, typeIdInfo: (typeTestAssumeConstVCalls: (vFuncId: (^27, offset: 16), args: (42), vFuncId: (^27, offset: 24), args: (43))))))
-; CHECK: ^23 = gv: (guid: 22, summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 5, typeIdInfo: (typeCheckedLoadConstVCalls: (vFuncId: (^27, offset: 16), args: (42))))))
+; CHECK: ^23 = gv: (guid: 22, summaries: (function: (module: ^0, flags: (linkage: external, notEligibleToImport: 0, live: 0, dsoLocal: 0), insts: 5, typeIdInfo: (typeCheckedLoadConstVCalls: (vFuncId: (^28, offset: 16), args: (42))))))
 ; CHECK: ^24 = typeid: (name: "_ZTS1A", summary: (typeTestRes: (kind: allOnes, sizeM1BitWidth: 7), wpdResolutions: ((offset: 0, wpdRes: (kind: branchFunnel)), (offset: 8, wpdRes: (kind: singleImpl, singleImplName: "_ZN1A1nEi")), (offset: 16, wpdRes: (kind: indir, resByArg: (args: (1, 2), byArg: (kind: indir, byte: 2, bit: 3), args: (3), byArg: (kind: uniformRetVal, info: 1), args: (4), byArg: (kind: uniqueRetVal, info: 1), args: (5), byArg: (kind: virtualConstProp))))))) ; guid = 7004155349499253778
 ; CHECK: ^25 = typeid: (name: "_ZTS1B", summary: (typeTestRes: (kind: inline, sizeM1BitWidth: 0, alignLog2: 1, sizeM1: 2, bitMask: 3, inlineBits: 4))) ; guid = 6203814149063363976
 ; CHECK: ^26 = typeid: (name: "_ZTS1C", summary: (typeTestRes: (kind: single, sizeM1BitWidth: 0))) ; guid = 1884921850105019584

Added: llvm/trunk/test/ThinLTO/X86/Inputs/cfi-distributed.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/Inputs/cfi-distributed.ll?rev=337503&view=auto
==============================================================================
--- llvm/trunk/test/ThinLTO/X86/Inputs/cfi-distributed.ll (added)
+++ llvm/trunk/test/ThinLTO/X86/Inputs/cfi-distributed.ll Thu Jul 19 15:25:56 2018
@@ -0,0 +1,28 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-grtev4-linux-gnu"
+
+%struct.B2 = type { %struct.A2 }
+%struct.A2 = type { i32 (...)** }
+
+ at _ZTV1B2 = constant { [3 x i8*] } { [3 x i8*] [i8* undef, i8* undef, i8* undef] }, !type !0
+
+define void @test2(i8* %b) {
+entry:
+  %0 = bitcast i8* %b to i8**
+  %vtable2 = load i8*, i8** %0
+  %1 = tail call i1 @llvm.type.test(i8* %vtable2, metadata !"_ZTS1A2")
+  br i1 %1, label %cont, label %trap
+
+trap:
+  tail call void @llvm.trap()
+  unreachable
+
+cont:
+  ret void
+}
+
+declare i1 @llvm.type.test(i8*, metadata)
+declare void @llvm.trap()
+
+!0 = !{i64 16, !"_ZTS1A2"}
+!1 = !{i64 16, !"_ZTS1B2"}

Added: llvm/trunk/test/ThinLTO/X86/cfi-distributed.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ThinLTO/X86/cfi-distributed.ll?rev=337503&view=auto
==============================================================================
--- llvm/trunk/test/ThinLTO/X86/cfi-distributed.ll (added)
+++ llvm/trunk/test/ThinLTO/X86/cfi-distributed.ll Thu Jul 19 15:25:56 2018
@@ -0,0 +1,60 @@
+; REQUIRES: x86-registered-target
+
+; Test to ensure that only referenced type ID records are emitted into
+; each distributed index file.
+
+; RUN: opt -thinlto-bc -o %t1.o %s
+; RUN: opt -thinlto-bc -o %t2.o %p/Inputs/cfi-distributed.ll
+
+; RUN: llvm-lto2 run -thinlto-distributed-indexes %t1.o %t2.o \
+; RUN:   -o %t3 \
+; RUN:   -r=%t1.o,test,px \
+; RUN:   -r=%t1.o,_ZTV1B, \
+; RUN:   -r=%t1.o,_ZTV1B,px \
+; RUN:   -r=%t1.o,test2, \
+; RUN:   -r=%t2.o,test2,px \
+; RUN:   -r=%t2.o,_ZTV1B2, \
+; RUN:   -r=%t2.o,_ZTV1B2,px
+
+; Since @test calls @test2, the latter should be imported here and the
+; first index file should reference both type ids.
+; RUN: llvm-dis %t1.o.thinlto.bc -o - | FileCheck %s --check-prefix=INDEX1
+; INDEX1: typeid: (name: "_ZTS1A"
+; INDEX1: typeid: (name: "_ZTS1A2"
+
+; The second index file, corresponding to @test2, should only contain the
+; typeid for _ZTS1A.
+; RUN: llvm-dis %t2.o.thinlto.bc -o - | FileCheck %s --check-prefix=INDEX2
+; INDEX2-NOT: typeid: (name: "_ZTS1A"
+; INDEX2: typeid: (name: "_ZTS1A2"
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-grtev4-linux-gnu"
+
+%struct.B = type { %struct.A }
+%struct.A = type { i32 (...)** }
+
+ at _ZTV1B = constant { [3 x i8*] } { [3 x i8*] [i8* undef, i8* undef, i8* undef] }, !type !0
+
+define void @test(i8* %b) {
+entry:
+  tail call void @test2(i8* %b)
+  %0 = bitcast i8* %b to i8**
+  %vtable2 = load i8*, i8** %0
+  %1 = tail call i1 @llvm.type.test(i8* %vtable2, metadata !"_ZTS1A")
+  br i1 %1, label %cont, label %trap
+
+trap:
+  tail call void @llvm.trap()
+  unreachable
+
+cont:
+  ret void
+}
+
+declare void @test2(i8*)
+declare i1 @llvm.type.test(i8*, metadata)
+declare void @llvm.trap()
+
+!0 = !{i64 16, !"_ZTS1A"}
+!1 = !{i64 16, !"_ZTS1B"}




More information about the llvm-commits mailing list