mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-19 08:24:12 +00:00
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
This commit is contained in:
parent
0293dd1939
commit
fdc1250177
@ -28,18 +28,34 @@ namespace llvm {
|
||||
std::unique_ptr<BitstreamWriter> Stream;
|
||||
|
||||
StringTableBuilder StrtabBuilder{StringTableBuilder::RAW};
|
||||
bool WroteStrtab = false;
|
||||
|
||||
// Owns any strings created by the irsymtab writer until we create the
|
||||
// string table.
|
||||
BumpPtrAllocator Alloc;
|
||||
|
||||
bool WroteStrtab = false, WroteSymtab = false;
|
||||
|
||||
void writeBlob(unsigned Block, unsigned Record, StringRef Blob);
|
||||
|
||||
std::vector<Module *> Mods;
|
||||
|
||||
public:
|
||||
/// Create a BitcodeWriter that writes to Buffer.
|
||||
BitcodeWriter(SmallVectorImpl<char> &Buffer);
|
||||
|
||||
~BitcodeWriter();
|
||||
|
||||
/// Attempt to write a symbol table to the bitcode file. This must be called
|
||||
/// at most once after all modules have been written.
|
||||
///
|
||||
/// A reader does not require a symbol table to interpret a bitcode file;
|
||||
/// the symbol table is needed only to improve link-time performance. So
|
||||
/// this function may decide not to write a symbol table. It may so decide
|
||||
/// if, for example, the target is unregistered or the IR is malformed.
|
||||
void writeSymtab();
|
||||
|
||||
/// Write the bitcode file's string table. This must be called exactly once
|
||||
/// after all modules have been written.
|
||||
/// after all modules and the optional symbol table have been written.
|
||||
void writeStrtab();
|
||||
|
||||
/// Copy the string table for another module into this bitcode file. This
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
namespace llvm {
|
||||
namespace bitc {
|
||||
// The only top-level block types are MODULE, IDENTIFICATION and STRTAB.
|
||||
// The only top-level block types are MODULE, IDENTIFICATION, STRTAB and SYMTAB.
|
||||
enum BlockIDs {
|
||||
// Blocks
|
||||
MODULE_BLOCK_ID = FIRST_APPLICATION_BLOCKID,
|
||||
@ -57,6 +57,8 @@ enum BlockIDs {
|
||||
STRTAB_BLOCK_ID,
|
||||
|
||||
FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID,
|
||||
|
||||
SYMTAB_BLOCK_ID,
|
||||
};
|
||||
|
||||
/// Identification block contains a string that describes the producer details,
|
||||
@ -571,6 +573,10 @@ enum StrtabCodes {
|
||||
STRTAB_BLOB = 1,
|
||||
};
|
||||
|
||||
enum SymtabCodes {
|
||||
SYMTAB_BLOB = 1,
|
||||
};
|
||||
|
||||
} // End bitc namespace
|
||||
} // End llvm namespace
|
||||
|
||||
|
@ -29,10 +29,12 @@
|
||||
#include "llvm/IR/UseListOrder.h"
|
||||
#include "llvm/IR/ValueSymbolTable.h"
|
||||
#include "llvm/MC/StringTableBuilder.h"
|
||||
#include "llvm/Object/IRSymtab.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/Program.h"
|
||||
#include "llvm/Support/SHA1.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cctype>
|
||||
#include <map>
|
||||
@ -3820,6 +3822,38 @@ void BitcodeWriter::writeBlob(unsigned Block, unsigned Record, StringRef Blob) {
|
||||
Stream->ExitBlock();
|
||||
}
|
||||
|
||||
void BitcodeWriter::writeSymtab() {
|
||||
assert(!WroteStrtab && !WroteSymtab);
|
||||
|
||||
// If any module has module-level inline asm, we will require a registered asm
|
||||
// parser for the target so that we can create an accurate symbol table for
|
||||
// the module.
|
||||
for (Module *M : Mods) {
|
||||
if (M->getModuleInlineAsm().empty())
|
||||
continue;
|
||||
|
||||
std::string Err;
|
||||
const Triple TT(M->getTargetTriple());
|
||||
const Target *T = TargetRegistry::lookupTarget(TT.str(), Err);
|
||||
if (!T || !T->hasMCAsmParser())
|
||||
return;
|
||||
}
|
||||
|
||||
WroteSymtab = true;
|
||||
SmallVector<char, 0> Symtab;
|
||||
// The irsymtab::build function may be unable to create a symbol table if the
|
||||
// module is malformed (e.g. it contains an invalid alias). Writing a symbol
|
||||
// table is not required for correctness, but we still want to be able to
|
||||
// write malformed modules to bitcode files, so swallow the error.
|
||||
if (Error E = irsymtab::build(Mods, Symtab, StrtabBuilder, Alloc)) {
|
||||
consumeError(std::move(E));
|
||||
return;
|
||||
}
|
||||
|
||||
writeBlob(bitc::SYMTAB_BLOCK_ID, bitc::SYMTAB_BLOB,
|
||||
{Symtab.data(), Symtab.size()});
|
||||
}
|
||||
|
||||
void BitcodeWriter::writeStrtab() {
|
||||
assert(!WroteStrtab);
|
||||
|
||||
@ -3843,6 +3877,15 @@ void BitcodeWriter::writeModule(const Module *M,
|
||||
bool ShouldPreserveUseListOrder,
|
||||
const ModuleSummaryIndex *Index,
|
||||
bool GenerateHash, ModuleHash *ModHash) {
|
||||
assert(!WroteStrtab);
|
||||
|
||||
// The Mods vector is used by irsymtab::build, which requires non-const
|
||||
// Modules in case it needs to materialize metadata. But the bitcode writer
|
||||
// requires that the module is materialized, so we can cast to non-const here,
|
||||
// after checking that it is in fact materialized.
|
||||
assert(M->isMaterialized());
|
||||
Mods.push_back(const_cast<Module *>(M));
|
||||
|
||||
ModuleBitcodeWriter ModuleWriter(M, Buffer, StrtabBuilder, *Stream,
|
||||
ShouldPreserveUseListOrder, Index,
|
||||
GenerateHash, ModHash);
|
||||
@ -3875,6 +3918,7 @@ void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out,
|
||||
BitcodeWriter Writer(Buffer);
|
||||
Writer.writeModule(M, ShouldPreserveUseListOrder, Index, GenerateHash,
|
||||
ModHash);
|
||||
Writer.writeSymtab();
|
||||
Writer.writeStrtab();
|
||||
|
||||
if (TT.isOSDarwin() || TT.isOSBinFormatMachO())
|
||||
|
@ -27,4 +27,5 @@ add_llvm_library(LLVMObject
|
||||
|
||||
DEPENDS
|
||||
intrinsics_gen
|
||||
llvm_vcsrevision_h
|
||||
)
|
||||
|
@ -371,6 +371,7 @@ void splitAndWriteThinLTOBitcode(
|
||||
/*GenerateHash=*/true, &ModHash);
|
||||
W.writeModule(MergedM.get(), /*ShouldPreserveUseListOrder=*/false,
|
||||
&MergedMIndex);
|
||||
W.writeSymtab();
|
||||
W.writeStrtab();
|
||||
OS << Buffer;
|
||||
|
||||
@ -385,6 +386,7 @@ void splitAndWriteThinLTOBitcode(
|
||||
/*GenerateHash=*/false, &ModHash);
|
||||
W2.writeModule(MergedM.get(), /*ShouldPreserveUseListOrder=*/false,
|
||||
&MergedMIndex);
|
||||
W2.writeSymtab();
|
||||
W2.writeStrtab();
|
||||
*ThinLinkOS << Buffer;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
; CHECK-NEXT: </GLOBALVAL_SUMMARY_BLOCK>
|
||||
|
||||
; CHECK: <STRTAB_BLOCK
|
||||
; CHECK-NEXT: blob data = 'mainanalias'
|
||||
; CHECK-NEXT: blob data = 'mainanalias{{.*}}'
|
||||
|
||||
; COMBINED: <GLOBALVAL_SUMMARY_BLOCK
|
||||
; COMBINED-NEXT: <VERSION
|
||||
|
@ -20,7 +20,7 @@
|
||||
; CHECK-NEXT: <PERMODULE_PROFILE {{.*}} op4=1 op5=2/>
|
||||
; CHECK-NEXT: </GLOBALVAL_SUMMARY_BLOCK>
|
||||
; CHECK: <STRTAB_BLOCK
|
||||
; CHECK-NEXT: blob data = 'mainfunc'
|
||||
; CHECK-NEXT: blob data = 'mainfunc{{.*}}'
|
||||
|
||||
; COMBINED: <GLOBALVAL_SUMMARY_BLOCK
|
||||
; COMBINED-NEXT: <VERSION
|
||||
|
@ -33,7 +33,7 @@
|
||||
; CHECK-NEXT: </GLOBALVAL_SUMMARY_BLOCK>
|
||||
|
||||
; CHECK: <STRTAB_BLOCK
|
||||
; CHECK-NEXT: blob data = 'hot_functionhot1hot2hot3hot4coldnone1none2none3'
|
||||
; CHECK-NEXT: blob data = 'hot_functionhot1hot2hot3hot4coldnone1none2none3{{.*}}'
|
||||
|
||||
; COMBINED: <GLOBALVAL_SUMMARY_BLOCK
|
||||
; COMBINED-NEXT: <VERSION
|
||||
|
@ -33,7 +33,7 @@
|
||||
; CHECK-NEXT: </GLOBALVAL_SUMMARY_BLOCK>
|
||||
|
||||
; CHECK: <STRTAB_BLOCK
|
||||
; CHECK-NEXT: blob data = 'hot_functionhot1hot2hot3hot4coldnone1none2none3'
|
||||
; CHECK-NEXT: blob data = 'hot_functionhot1hot2hot3hot4coldnone1none2none3{{.*}}'
|
||||
|
||||
; COMBINED: <GLOBALVAL_SUMMARY_BLOCK
|
||||
; COMBINED-NEXT: <VERSION
|
||||
|
@ -21,7 +21,7 @@
|
||||
; CHECK-NEXT: <PERMODULE {{.*}} op3=1
|
||||
; CHECK-NEXT: </GLOBALVAL_SUMMARY_BLOCK>
|
||||
; CHECK: <STRTAB_BLOCK
|
||||
; CHECK-NEXT: blob data = 'undefinedglobmainfunc'
|
||||
; CHECK-NEXT: blob data = 'undefinedglobmainfunc{{.*}}'
|
||||
|
||||
|
||||
; COMBINED: <GLOBALVAL_SUMMARY_BLOCK
|
||||
|
@ -62,7 +62,7 @@
|
||||
; CHECK: </GLOBALVAL_SUMMARY_BLOCK>
|
||||
|
||||
; CHECK: <STRTAB_BLOCK
|
||||
; CHECK-NEXT: blob data = 'barglobalvarfuncfunc2foofunc3WXYZllvm.ctpop.i8main'
|
||||
; CHECK-NEXT: blob data = 'barglobalvarfuncfunc2foofunc3WXYZllvm.ctpop.i8main{{.*}}'
|
||||
|
||||
; ModuleID = 'thinlto-function-summary-refgraph.ll'
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
@ -24,7 +24,7 @@
|
||||
; BC-NEXT: <ALIAS {{.*}} op0=5 op1=0 op2=3
|
||||
; BC-NEXT: </GLOBALVAL_SUMMARY_BLOCK
|
||||
; BC: <STRTAB_BLOCK
|
||||
; BC-NEXT: blob data = 'hfoobaranon.{{................................}}.0variadicf'
|
||||
; BC-NEXT: blob data = 'hfoobaranon.{{................................}}.0variadicf{{.*}}'
|
||||
|
||||
|
||||
; RUN: opt -name-anon-globals -module-summary < %s | llvm-dis | FileCheck %s
|
||||
|
17
test/Object/X86/irsymtab-asm.ll
Normal file
17
test/Object/X86/irsymtab-asm.ll
Normal file
@ -0,0 +1,17 @@
|
||||
; Check that we correctly handle the case where we have inline asm and the
|
||||
; target is not registered. In this case we shouldn't emit an irsymtab.
|
||||
|
||||
; RUN: llvm-as -o %t %s
|
||||
; RUN: llvm-bcanalyzer -dump %t | FileCheck --check-prefix=AS %s
|
||||
|
||||
; AS-NOT: <SYMTAB_BLOCK
|
||||
|
||||
; RUN: opt -o %t2 %s
|
||||
; RUN: llvm-bcanalyzer -dump %t2 | FileCheck --check-prefix=OPT %s
|
||||
|
||||
; OPT: <SYMTAB_BLOCK
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
module asm "ret"
|
15
test/Object/X86/irsymtab-bad-alias.ll
Normal file
15
test/Object/X86/irsymtab-bad-alias.ll
Normal file
@ -0,0 +1,15 @@
|
||||
; Check that we do not create an irsymtab for modules with malformed IR.
|
||||
|
||||
; RUN: opt -o %t %s
|
||||
; RUN: llvm-bcanalyzer -dump %t | FileCheck %s
|
||||
|
||||
; CHECK-NOT: <SYMTAB_BLOCK
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
@g1 = global i32 1
|
||||
@g2 = global i32 2
|
||||
|
||||
@a = alias i32, inttoptr(i32 sub (i32 ptrtoint (i32* @g1 to i32),
|
||||
i32 ptrtoint (i32* @g2 to i32)) to i32*)
|
20
test/Object/X86/irsymtab.ll
Normal file
20
test/Object/X86/irsymtab.ll
Normal file
@ -0,0 +1,20 @@
|
||||
; RUN: env LLVM_OVERRIDE_PRODUCER=producer opt -o %t %s
|
||||
; RUN: llvm-bcanalyzer -dump -show-binary-blobs %t | FileCheck --check-prefix=BCA %s
|
||||
|
||||
; BCA: <SYMTAB_BLOCK
|
||||
; Version stored at offset 0.
|
||||
; BCA-NEXT: <BLOB abbrevid=4/> 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'
|
||||
; BCA-NEXT: </SYMTAB_BLOCK>
|
||||
; BCA-NEXT: <STRTAB_BLOCK
|
||||
; BCA-NEXT: <BLOB abbrevid=4/> blob data = 'foobarproducerx86_64-unknown-linux-gnuirsymtab.ll'
|
||||
; BCA-NEXT: </STRTAB_BLOCK>
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
source_filename = "irsymtab.ll"
|
||||
|
||||
define void @foo() {
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @bar()
|
@ -10,7 +10,7 @@
|
||||
; RUN: | llvm-bcanalyzer -dump | FileCheck %s
|
||||
|
||||
; CHECK: <STRTAB_BLOCK
|
||||
; CHECK-NEXT: blob data = 'mainglobalfunc1llvm.invariant.start.p0i8'
|
||||
; CHECK-NEXT: blob data = 'mainglobalfunc1llvm.invariant.start.p0i8{{.*}}'
|
||||
|
||||
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-apple-macosx10.11.0"
|
||||
|
@ -125,6 +125,7 @@ static const char *GetBlockName(unsigned BlockID,
|
||||
return "FULL_LTO_GLOBALVAL_SUMMARY_BLOCK";
|
||||
case bitc::MODULE_STRTAB_BLOCK_ID: return "MODULE_STRTAB_BLOCK";
|
||||
case bitc::STRTAB_BLOCK_ID: return "STRTAB_BLOCK";
|
||||
case bitc::SYMTAB_BLOCK_ID: return "SYMTAB_BLOCK";
|
||||
}
|
||||
}
|
||||
|
||||
@ -393,6 +394,11 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
|
||||
default: return nullptr;
|
||||
case bitc::STRTAB_BLOB: return "BLOB";
|
||||
}
|
||||
case bitc::SYMTAB_BLOCK_ID:
|
||||
switch(CodeID) {
|
||||
default: return nullptr;
|
||||
case bitc::SYMTAB_BLOB: return "BLOB";
|
||||
}
|
||||
}
|
||||
#undef STRINGIFY_CODE
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user