summaryrefslogtreecommitdiff
path: root/lib/Bitcode
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2010-10-06 01:22:42 +0000
committerBill Wendling <isanbard@gmail.com>2010-10-06 01:22:42 +0000
commit34711747a1d2c8713e69333bacef1c880810e371 (patch)
tree0dc76a5863ab9848365c88c02692d7b730104c94 /lib/Bitcode
parent417b54354b3fcccb4f5919b8d2d9dcd8bba50069 (diff)
downloadllvm-34711747a1d2c8713e69333bacef1c880810e371.tar.gz
llvm-34711747a1d2c8713e69333bacef1c880810e371.tar.bz2
llvm-34711747a1d2c8713e69333bacef1c880810e371.tar.xz
Provide a fast "get me the target triple from the module" API. This can
drastically reduce the linking time during LTO. Patch by Shantonu Sen! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115728 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Bitcode')
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp125
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.h5
2 files changed, 129 insertions, 1 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index 2e4eab8f05..5f6ce5e03c 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1600,6 +1600,112 @@ bool BitcodeReader::ParseBitcodeInto(Module *M) {
return false;
}
+bool BitcodeReader::ParseModuleTriple(std::string &Triple) {
+ if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID))
+ return Error("Malformed block record");
+
+ SmallVector<uint64_t, 64> Record;
+
+ // Read all the records for this module.
+ while (!Stream.AtEndOfStream()) {
+ unsigned Code = Stream.ReadCode();
+ if (Code == bitc::END_BLOCK) {
+ if (Stream.ReadBlockEnd())
+ return Error("Error at end of module block");
+
+ return false;
+ }
+
+ if (Code == bitc::ENTER_SUBBLOCK) {
+ switch (Stream.ReadSubBlockID()) {
+ default: // Skip unknown content.
+ if (Stream.SkipBlock())
+ return Error("Malformed block record");
+ break;
+ }
+ continue;
+ }
+
+ if (Code == bitc::DEFINE_ABBREV) {
+ Stream.ReadAbbrevRecord();
+ continue;
+ }
+
+ // Read a record.
+ switch (Stream.ReadRecord(Code, Record)) {
+ default: break; // Default behavior, ignore unknown content.
+ case bitc::MODULE_CODE_VERSION: // VERSION: [version#]
+ if (Record.size() < 1)
+ return Error("Malformed MODULE_CODE_VERSION");
+ // Only version #0 is supported so far.
+ if (Record[0] != 0)
+ return Error("Unknown bitstream version!");
+ break;
+ case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N]
+ std::string S;
+ if (ConvertToString(Record, 0, S))
+ return Error("Invalid MODULE_CODE_TRIPLE record");
+ Triple = S;
+ break;
+ }
+ }
+ Record.clear();
+ }
+
+ return Error("Premature end of bitstream");
+}
+
+bool BitcodeReader::ParseTriple(std::string &Triple) {
+ if (Buffer->getBufferSize() & 3)
+ return Error("Bitcode stream should be a multiple of 4 bytes in length");
+
+ unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
+ unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
+
+ // If we have a wrapper header, parse it and ignore the non-bc file contents.
+ // The magic number is 0x0B17C0DE stored in little endian.
+ if (isBitcodeWrapper(BufPtr, BufEnd))
+ if (SkipBitcodeWrapperHeader(BufPtr, BufEnd))
+ return Error("Invalid bitcode wrapper header");
+
+ StreamFile.init(BufPtr, BufEnd);
+ Stream.init(StreamFile);
+
+ // Sniff for the signature.
+ if (Stream.Read(8) != 'B' ||
+ Stream.Read(8) != 'C' ||
+ Stream.Read(4) != 0x0 ||
+ Stream.Read(4) != 0xC ||
+ Stream.Read(4) != 0xE ||
+ Stream.Read(4) != 0xD)
+ return Error("Invalid bitcode signature");
+
+ // We expect a number of well-defined blocks, though we don't necessarily
+ // need to understand them all.
+ while (!Stream.AtEndOfStream()) {
+ unsigned Code = Stream.ReadCode();
+
+ if (Code != bitc::ENTER_SUBBLOCK)
+ return Error("Invalid record at top-level");
+
+ unsigned BlockID = Stream.ReadSubBlockID();
+
+ // We only know the MODULE subblock ID.
+ switch (BlockID) {
+ case bitc::MODULE_BLOCK_ID:
+ if (ParseModuleTriple(Triple))
+ return true;
+ break;
+ default:
+ if (Stream.SkipBlock())
+ return Error("Malformed block record");
+ break;
+ }
+ }
+
+ return false;
+}
+
/// ParseMetadataAttachment - Parse metadata attachments.
bool BitcodeReader::ParseMetadataAttachment() {
if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID))
@@ -2537,7 +2643,24 @@ Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context,
// Read in the entire module, and destroy the BitcodeReader.
if (M->MaterializeAllPermanently(ErrMsg)) {
delete M;
- return NULL;
+ return 0;
}
+
return M;
}
+
+std::string llvm::getBitcodeTargetTriple(MemoryBuffer *Buffer,
+ LLVMContext& Context,
+ std::string *ErrMsg) {
+ BitcodeReader *R = new BitcodeReader(Buffer, Context);
+ // Don't let the BitcodeReader dtor delete 'Buffer'.
+ R->setBufferOwned(false);
+
+ std::string Triple("");
+ if (R->ParseTriple(Triple))
+ if (ErrMsg)
+ *ErrMsg = R->getErrorString();
+
+ delete R;
+ return Triple;
+}
diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h
index 053121bdad..f8fc079c73 100644
--- a/lib/Bitcode/Reader/BitcodeReader.h
+++ b/lib/Bitcode/Reader/BitcodeReader.h
@@ -212,6 +212,10 @@ public:
/// @brief Main interface to parsing a bitcode buffer.
/// @returns true if an error occurred.
bool ParseBitcodeInto(Module *M);
+
+ /// @brief Cheap mechanism to just extract module triple
+ /// @returns true if an error occurred.
+ bool ParseTriple(std::string &Triple);
private:
const Type *getTypeByID(unsigned ID, bool isTypeTable = false);
Value *getFnValueByID(unsigned ID, const Type *Ty) {
@@ -270,6 +274,7 @@ private:
bool ResolveGlobalAndAliasInits();
bool ParseMetadata();
bool ParseMetadataAttachment();
+ bool ParseModuleTriple(std::string &Triple);
};
} // End llvm namespace