mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-17 04:24:00 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214125 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -1620,9 +1620,8 @@ std::error_code BitcodeReader::ParseUseLists() {
|
||||
if (Stream.EnterSubBlock(bitc::USELIST_BLOCK_ID))
|
||||
return Error(InvalidRecord);
|
||||
|
||||
SmallVector<uint64_t, 64> Record;
|
||||
|
||||
// Read all the records.
|
||||
SmallVector<uint64_t, 64> 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)
|
||||
if (RecordLength < 3)
|
||||
// Records should have at least an ID and two indexes.
|
||||
return Error(InvalidRecord);
|
||||
UseListRecords.push_back(Record);
|
||||
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<const Use *, unsigned, 16> 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;
|
||||
|
||||
|
Reference in New Issue
Block a user