From 1f66c856b54e32e6590d1333fc8a60d56979edb8 Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Mon, 28 Jul 2014 21:19:41 +0000 Subject: Bitcode: Serialize (and recover) use-list order Predict and serialize use-list order in bitcode. This makes the option `-preserve-bc-use-list-order` work *most* of the time, but this is still experimental. - Builds a full value-table up front in the writer, sets up a list of use-list orders to write out, and discards the table. This is a simpler first step than determining the order from the various overlapping IDs of values on-the-fly. - The shuffles stored in the use-list order list have an unnecessarily large memory footprint. - `blockaddress` expressions cause functions to be materialized out-of-order. For now I've ignored this problem, so use-list orders will be wrong for constants used by functions that have block addresses taken. There are a couple of ways to fix this, but I don't have a concrete plan yet. - When materializing functions lazily, the use-lists for constants will not be correct. This use case is out of scope: what should the use-list order be, if it's incomplete? This is part of PR5680. llvm-svn: 214125 --- llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 43 ++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 6 deletions(-) (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp') diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 47a3953..806a8a9 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1620,9 +1620,8 @@ std::error_code BitcodeReader::ParseUseLists() { if (Stream.EnterSubBlock(bitc::USELIST_BLOCK_ID)) return Error(InvalidRecord); - SmallVector Record; - // Read all the records. + SmallVector Record; while (1) { BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); @@ -1639,14 +1638,42 @@ std::error_code BitcodeReader::ParseUseLists() { // Read a use list record. Record.clear(); + bool IsBB = false; switch (Stream.readRecord(Entry.ID, Record)) { default: // Default behavior: unknown type. break; - case bitc::USELIST_CODE_ENTRY: { // USELIST_CODE_ENTRY: TBD. + case bitc::USELIST_CODE_BB: + IsBB = true; + // fallthrough + case bitc::USELIST_CODE_DEFAULT: { unsigned RecordLength = Record.size(); - if (RecordLength < 1) - return Error(InvalidRecord); - UseListRecords.push_back(Record); + if (RecordLength < 3) + // Records should have at least an ID and two indexes. + return Error(InvalidRecord); + unsigned ID = Record.back(); + Record.pop_back(); + + Value *V; + if (IsBB) { + assert(ID < FunctionBBs.size() && "Basic block not found"); + V = FunctionBBs[ID]; + } else + V = ValueList[ID]; + unsigned NumUses = 0; + SmallDenseMap Order; + for (const Use &U : V->uses()) { + if (NumUses > Record.size()) + break; + Order[&U] = Record[NumUses++]; + } + if (Order.size() != Record.size() || NumUses > Record.size()) + // Mismatches can happen if the functions are being materialized lazily + // (out-of-order), or a value has been upgraded. + break; + + V->sortUseList([&](const Use &L, const Use &R) { + return Order.lookup(&L) < Order.lookup(&R); + }); break; } } @@ -2298,6 +2325,10 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { if (std::error_code EC = ParseMetadata()) return EC; break; + case bitc::USELIST_BLOCK_ID: + if (std::error_code EC = ParseUseLists()) + return EC; + break; } continue; -- cgit v1.1