llvm.org GIT mirror llvm / fdc1250
Bitcode: Write the irsymtab to disk. Differential Revision: https://reviews.llvm.org/D33973 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306487 91177308-0d34-0410-b5e6-96231b3b80d8 Peter Collingbourne 2 years ago
17 changed file(s) with 138 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
2727 std::unique_ptr Stream;
2828
2929 StringTableBuilder StrtabBuilder{StringTableBuilder::RAW};
30 bool WroteStrtab = false;
30
31 // Owns any strings created by the irsymtab writer until we create the
32 // string table.
33 BumpPtrAllocator Alloc;
34
35 bool WroteStrtab = false, WroteSymtab = false;
3136
3237 void writeBlob(unsigned Block, unsigned Record, StringRef Blob);
38
39 std::vector Mods;
3340
3441 public:
3542 /// Create a BitcodeWriter that writes to Buffer.
3744
3845 ~BitcodeWriter();
3946
47 /// Attempt to write a symbol table to the bitcode file. This must be called
48 /// at most once after all modules have been written.
49 ///
50 /// A reader does not require a symbol table to interpret a bitcode file;
51 /// the symbol table is needed only to improve link-time performance. So
52 /// this function may decide not to write a symbol table. It may so decide
53 /// if, for example, the target is unregistered or the IR is malformed.
54 void writeSymtab();
55
4056 /// Write the bitcode file's string table. This must be called exactly once
41 /// after all modules have been written.
57 /// after all modules and the optional symbol table have been written.
4258 void writeStrtab();
4359
4460 /// Copy the string table for another module into this bitcode file. This
2121
2222 namespace llvm {
2323 namespace bitc {
24 // The only top-level block types are MODULE, IDENTIFICATION and STRTAB.
24 // The only top-level block types are MODULE, IDENTIFICATION, STRTAB and SYMTAB.
2525 enum BlockIDs {
2626 // Blocks
2727 MODULE_BLOCK_ID = FIRST_APPLICATION_BLOCKID,
5656 STRTAB_BLOCK_ID,
5757
5858 FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID,
59
60 SYMTAB_BLOCK_ID,
5961 };
6062
6163 /// Identification block contains a string that describes the producer details,
570572 STRTAB_BLOB = 1,
571573 };
572574
575 enum SymtabCodes {
576 SYMTAB_BLOB = 1,
577 };
578
573579 } // End bitc namespace
574580 } // End llvm namespace
575581
2828 #include "llvm/IR/UseListOrder.h"
2929 #include "llvm/IR/ValueSymbolTable.h"
3030 #include "llvm/MC/StringTableBuilder.h"
31 #include "llvm/Object/IRSymtab.h"
3132 #include "llvm/Support/ErrorHandling.h"
3233 #include "llvm/Support/MathExtras.h"
3334 #include "llvm/Support/Program.h"
3435 #include "llvm/Support/SHA1.h"
36 #include "llvm/Support/TargetRegistry.h"
3537 #include "llvm/Support/raw_ostream.h"
3638 #include
3739 #include
38193821 Stream->ExitBlock();
38203822 }
38213823
3824 void BitcodeWriter::writeSymtab() {
3825 assert(!WroteStrtab && !WroteSymtab);
3826
3827 // If any module has module-level inline asm, we will require a registered asm
3828 // parser for the target so that we can create an accurate symbol table for
3829 // the module.
3830 for (Module *M : Mods) {
3831 if (M->getModuleInlineAsm().empty())
3832 continue;
3833
3834 std::string Err;
3835 const Triple TT(M->getTargetTriple());
3836 const Target *T = TargetRegistry::lookupTarget(TT.str(), Err);
3837 if (!T || !T->hasMCAsmParser())
3838 return;
3839 }
3840
3841 WroteSymtab = true;
3842 SmallVector Symtab;
3843 // The irsymtab::build function may be unable to create a symbol table if the
3844 // module is malformed (e.g. it contains an invalid alias). Writing a symbol
3845 // table is not required for correctness, but we still want to be able to
3846 // write malformed modules to bitcode files, so swallow the error.
3847 if (Error E = irsymtab::build(Mods, Symtab, StrtabBuilder, Alloc)) {
3848 consumeError(std::move(E));
3849 return;
3850 }
3851
3852 writeBlob(bitc::SYMTAB_BLOCK_ID, bitc::SYMTAB_BLOB,
3853 {Symtab.data(), Symtab.size()});
3854 }
3855
38223856 void BitcodeWriter::writeStrtab() {
38233857 assert(!WroteStrtab);
38243858
38423876 bool ShouldPreserveUseListOrder,
38433877 const ModuleSummaryIndex *Index,
38443878 bool GenerateHash, ModuleHash *ModHash) {
3879 assert(!WroteStrtab);
3880
3881 // The Mods vector is used by irsymtab::build, which requires non-const
3882 // Modules in case it needs to materialize metadata. But the bitcode writer
3883 // requires that the module is materialized, so we can cast to non-const here,
3884 // after checking that it is in fact materialized.
3885 assert(M->isMaterialized());
3886 Mods.push_back(const_cast(M));
3887
38453888 ModuleBitcodeWriter ModuleWriter(M, Buffer, StrtabBuilder, *Stream,
38463889 ShouldPreserveUseListOrder, Index,
38473890 GenerateHash, ModHash);
38743917 BitcodeWriter Writer(Buffer);
38753918 Writer.writeModule(M, ShouldPreserveUseListOrder, Index, GenerateHash,
38763919 ModHash);
3920 Writer.writeSymtab();
38773921 Writer.writeStrtab();
38783922
38793923 if (TT.isOSDarwin() || TT.isOSBinFormatMachO())
2626
2727 DEPENDS
2828 intrinsics_gen
29 llvm_vcsrevision_h
2930 )
370370 /*GenerateHash=*/true, &ModHash);
371371 W.writeModule(MergedM.get(), /*ShouldPreserveUseListOrder=*/false,
372372 &MergedMIndex);
373 W.writeSymtab();
373374 W.writeStrtab();
374375 OS << Buffer;
375376
384385 /*GenerateHash=*/false, &ModHash);
385386 W2.writeModule(MergedM.get(), /*ShouldPreserveUseListOrder=*/false,
386387 &MergedMIndex);
388 W2.writeSymtab();
387389 W2.writeStrtab();
388390 *ThinLinkOS << Buffer;
389391 }
1717 ; CHECK-NEXT:
1818
1919 ; CHECK:
20 ; CHECK-NEXT: blob data = 'mainanalias'
20 ; CHECK-NEXT: blob data = 'mainanalias{{.*}}'
2121
2222 ; COMBINED:
2323 ; COMBINED-NEXT:
1919 ; CHECK-NEXT:
2020 ; CHECK-NEXT:
2121 ; CHECK:
22 ; CHECK-NEXT: blob data = 'mainfunc'
22 ; CHECK-NEXT: blob data = 'mainfunc{{.*}}'
2323
2424 ; COMBINED:
2525 ; COMBINED-NEXT:
3232 ; CHECK-NEXT:
3333
3434 ; CHECK:
35 ; CHECK-NEXT: blob data = 'hot_functionhot1hot2hot3hot4coldnone1none2none3'
35 ; CHECK-NEXT: blob data = 'hot_functionhot1hot2hot3hot4coldnone1none2none3{{.*}}'
3636
3737 ; COMBINED:
3838 ; COMBINED-NEXT:
3232 ; CHECK-NEXT:
3333
3434 ; CHECK:
35 ; CHECK-NEXT: blob data = 'hot_functionhot1hot2hot3hot4coldnone1none2none3'
35 ; CHECK-NEXT: blob data = 'hot_functionhot1hot2hot3hot4coldnone1none2none3{{.*}}'
3636
3737 ; COMBINED:
3838 ; COMBINED-NEXT:
2020 ; CHECK-NEXT:
2121 ; CHECK-NEXT:
2222 ; CHECK:
23 ; CHECK-NEXT: blob data = 'undefinedglobmainfunc'
23 ; CHECK-NEXT: blob data = 'undefinedglobmainfunc{{.*}}'
2424
2525
2626 ; COMBINED:
6161 ; CHECK:
6262
6363 ; CHECK:
64 ; CHECK-NEXT: blob data = 'barglobalvarfuncfunc2foofunc3WXYZllvm.ctpop.i8main'
64 ; CHECK-NEXT: blob data = 'barglobalvarfuncfunc2foofunc3WXYZllvm.ctpop.i8main{{.*}}'
6565
6666 ; ModuleID = 'thinlto-function-summary-refgraph.ll'
6767 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2323 ; BC-NEXT:
2424 ; BC-NEXT:
2525 ; BC:
26 ; BC-NEXT: blob data = 'hfoobaranon.{{................................}}.0variadicf'
26 ; BC-NEXT: blob data = 'hfoobaranon.{{................................}}.0variadicf{{.*}}'
2727
2828
2929 ; RUN: opt -name-anon-globals -module-summary < %s | llvm-dis | FileCheck %s
0 ; Check that we correctly handle the case where we have inline asm and the
1 ; target is not registered. In this case we shouldn't emit an irsymtab.
2
3 ; RUN: llvm-as -o %t %s
4 ; RUN: llvm-bcanalyzer -dump %t | FileCheck --check-prefix=AS %s
5
6 ; AS-NOT:
7
8 ; RUN: opt -o %t2 %s
9 ; RUN: llvm-bcanalyzer -dump %t2 | FileCheck --check-prefix=OPT %s
10
11 ; OPT:
12
13 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
14 target triple = "x86_64-unknown-linux-gnu"
15
16 module asm "ret"
0 ; Check that we do not create an irsymtab for modules with malformed IR.
1
2 ; RUN: opt -o %t %s
3 ; RUN: llvm-bcanalyzer -dump %t | FileCheck %s
4
5 ; CHECK-NOT:
6
7 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8 target triple = "x86_64-unknown-linux-gnu"
9
10 @g1 = global i32 1
11 @g2 = global i32 2
12
13 @a = alias i32, inttoptr(i32 sub (i32 ptrtoint (i32* @g1 to i32),
14 i32 ptrtoint (i32* @g2 to i32)) to i32*)
0 ; RUN: env LLVM_OVERRIDE_PRODUCER=producer opt -o %t %s
1 ; RUN: llvm-bcanalyzer -dump -show-binary-blobs %t | FileCheck --check-prefix=BCA %s
2
3 ; BCA:
4 ; Version stored at offset 0.
5 ; BCA-NEXT: blob data = '\x00\x00\x00\x00\x06\x00\x00\x00\x08\x00\x00\x00D\x00\x00\x00\x01\x00\x00\x00P\x00\x00\x00\x00\x00\x00\x00P\x00\x00\x00\x02\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x0E\x00\x00\x00\x18\x00\x00\x00&\x00\x00\x00\x0B\x00\x00\x001\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\xFF\xFF\xFF\xFF\x00$\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\xFF\xFF\xFF\xFF\x08$\x00\x00'
6 ; BCA-NEXT:
7 ; BCA-NEXT:
8 ; BCA-NEXT: blob data = 'foobarproducerx86_64-unknown-linux-gnuirsymtab.ll'
9 ; BCA-NEXT:
10
11 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
12 target triple = "x86_64-unknown-linux-gnu"
13 source_filename = "irsymtab.ll"
14
15 define void @foo() {
16 ret void
17 }
18
19 declare void @bar()
99 ; RUN: | llvm-bcanalyzer -dump | FileCheck %s
1010
1111 ; CHECK:
12 ; CHECK-NEXT: blob data = 'mainglobalfunc1llvm.invariant.start.p0i8'
12 ; CHECK-NEXT: blob data = 'mainglobalfunc1llvm.invariant.start.p0i8{{.*}}'
1313
1414 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
1515 target triple = "x86_64-apple-macosx10.11.0"
124124 return "FULL_LTO_GLOBALVAL_SUMMARY_BLOCK";
125125 case bitc::MODULE_STRTAB_BLOCK_ID: return "MODULE_STRTAB_BLOCK";
126126 case bitc::STRTAB_BLOCK_ID: return "STRTAB_BLOCK";
127 case bitc::SYMTAB_BLOCK_ID: return "SYMTAB_BLOCK";
127128 }
128129 }
129130
392393 default: return nullptr;
393394 case bitc::STRTAB_BLOB: return "BLOB";
394395 }
396 case bitc::SYMTAB_BLOCK_ID:
397 switch(CodeID) {
398 default: return nullptr;
399 case bitc::SYMTAB_BLOB: return "BLOB";
400 }
395401 }
396402 #undef STRINGIFY_CODE
397403 }