mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-20 19:42:54 +02:00
[codeview] Don't use the type visitor to merge types
Summary: This didn't do much to speed things up, but it implements a FIXME, and I think it's a nice simplification. We don't need the record kind switch. We're doing that ourselves. Reviewers: ruiu, inglorion Subscribers: llvm-commits, hiraditya Differential Revision: https://reviews.llvm.org/D35496 llvm-svn: 308213
This commit is contained in:
parent
3ab9e840a9
commit
b44e270a45
@ -10,13 +10,11 @@
|
||||
#include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/ScopedPrinter.h"
|
||||
|
||||
@ -57,7 +55,7 @@ namespace {
|
||||
/// streams: an item (or IPI) stream and a type stream, as this is what is
|
||||
/// actually stored in the final PDB. We choose which records go where by
|
||||
/// looking at the record kind.
|
||||
class TypeStreamMerger : public TypeVisitorCallbacks {
|
||||
class TypeStreamMerger {
|
||||
public:
|
||||
explicit TypeStreamMerger(SmallVectorImpl<TypeIndex> &SourceToDest)
|
||||
: IndexMap(SourceToDest) {
|
||||
@ -66,9 +64,6 @@ public:
|
||||
|
||||
static const TypeIndex Untranslated;
|
||||
|
||||
Error visitTypeBegin(CVType &Record) override;
|
||||
Error visitTypeEnd(CVType &Record) override;
|
||||
|
||||
Error mergeTypesAndIds(TypeTableBuilder &DestIds, TypeTableBuilder &DestTypes,
|
||||
const CVTypeArray &IdsAndTypes);
|
||||
Error mergeIdRecords(TypeTableBuilder &Dest,
|
||||
@ -79,33 +74,16 @@ public:
|
||||
private:
|
||||
Error doit(const CVTypeArray &Types);
|
||||
|
||||
Error remapAllTypes(const CVTypeArray &Types);
|
||||
|
||||
Error remapType(const CVType &Type);
|
||||
|
||||
void addMapping(TypeIndex Idx);
|
||||
|
||||
bool remapTypeIndex(TypeIndex &Idx);
|
||||
bool remapItemIndex(TypeIndex &Idx);
|
||||
|
||||
bool remapIndices(RemappedType &Record, ArrayRef<TiReference> Refs) {
|
||||
auto OriginalData = Record.OriginalRecord.content();
|
||||
bool Success = true;
|
||||
for (auto &Ref : Refs) {
|
||||
uint32_t Offset = Ref.Offset;
|
||||
ArrayRef<uint8_t> Bytes =
|
||||
OriginalData.slice(Ref.Offset, sizeof(TypeIndex));
|
||||
ArrayRef<TypeIndex> TIs(reinterpret_cast<const TypeIndex *>(Bytes.data()),
|
||||
Ref.Count);
|
||||
for (auto TI : TIs) {
|
||||
TypeIndex NewTI = TI;
|
||||
bool ThisSuccess = (Ref.Kind == TiRefKind::IndexRef)
|
||||
? remapItemIndex(NewTI)
|
||||
: remapTypeIndex(NewTI);
|
||||
if (ThisSuccess && NewTI != TI)
|
||||
Record.Mappings.emplace_back(Offset, NewTI);
|
||||
Offset += sizeof(TypeIndex);
|
||||
Success &= ThisSuccess;
|
||||
}
|
||||
}
|
||||
return Success;
|
||||
}
|
||||
bool remapIndices(RemappedType &Record, ArrayRef<TiReference> Refs);
|
||||
|
||||
bool remapIndex(TypeIndex &Idx, ArrayRef<TypeIndex> Map);
|
||||
|
||||
@ -127,21 +105,6 @@ private:
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error writeTypeRecord(const CVType &Record) {
|
||||
TypeIndex DestIdx =
|
||||
DestTypeStream->writeSerializedRecord(Record.RecordData);
|
||||
addMapping(DestIdx);
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error writeTypeRecord(const RemappedType &Record, bool RemapSuccess) {
|
||||
return writeRecord(*DestTypeStream, Record, RemapSuccess);
|
||||
}
|
||||
|
||||
Error writeIdRecord(const RemappedType &Record, bool RemapSuccess) {
|
||||
return writeRecord(*DestIdStream, Record, RemapSuccess);
|
||||
}
|
||||
|
||||
Optional<Error> LastError;
|
||||
|
||||
bool IsSecondPass = false;
|
||||
@ -166,12 +129,8 @@ private:
|
||||
|
||||
const TypeIndex TypeStreamMerger::Untranslated(SimpleTypeKind::NotTranslated);
|
||||
|
||||
Error TypeStreamMerger::visitTypeBegin(CVType &Rec) {
|
||||
RemappedType R(Rec);
|
||||
SmallVector<TiReference, 32> Refs;
|
||||
discoverTypeIndices(Rec.RecordData, Refs);
|
||||
bool Success = remapIndices(R, Refs);
|
||||
switch (Rec.kind()) {
|
||||
static bool isIdRecord(TypeLeafKind K) {
|
||||
switch (K) {
|
||||
case TypeLeafKind::LF_FUNC_ID:
|
||||
case TypeLeafKind::LF_MFUNC_ID:
|
||||
case TypeLeafKind::LF_STRING_ID:
|
||||
@ -179,19 +138,10 @@ Error TypeStreamMerger::visitTypeBegin(CVType &Rec) {
|
||||
case TypeLeafKind::LF_BUILDINFO:
|
||||
case TypeLeafKind::LF_UDT_SRC_LINE:
|
||||
case TypeLeafKind::LF_UDT_MOD_SRC_LINE:
|
||||
return writeIdRecord(R, Success);
|
||||
return true;
|
||||
default:
|
||||
return writeTypeRecord(R, Success);
|
||||
return false;
|
||||
}
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error TypeStreamMerger::visitTypeEnd(CVType &Rec) {
|
||||
++CurIndex;
|
||||
if (!IsSecondPass)
|
||||
assert(IndexMap.size() == slotForIndex(CurIndex) &&
|
||||
"visitKnownRecord should add one index map entry");
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
void TypeStreamMerger::addMapping(TypeIndex Idx) {
|
||||
@ -278,15 +228,7 @@ Error TypeStreamMerger::mergeTypesAndIds(TypeTableBuilder &DestIds,
|
||||
}
|
||||
|
||||
Error TypeStreamMerger::doit(const CVTypeArray &Types) {
|
||||
// We don't want to deserialize records. I guess this flag is poorly named,
|
||||
// but it really means "Don't deserialize records before switching on the
|
||||
// concrete type.
|
||||
// FIXME: We can probably get even more speed here if we don't use the visitor
|
||||
// pipeline here, but instead write the switch ourselves. I don't think it
|
||||
// would buy us much since it's already pretty fast, but it's probably worth
|
||||
// a few cycles.
|
||||
if (auto EC =
|
||||
codeview::visitTypeStream(Types, *this, VDS_BytesExternal))
|
||||
if (auto EC = remapAllTypes(Types))
|
||||
return EC;
|
||||
|
||||
// If we found bad indices but no other errors, try doing another pass and see
|
||||
@ -302,8 +244,7 @@ Error TypeStreamMerger::doit(const CVTypeArray &Types) {
|
||||
NumBadIndices = 0;
|
||||
CurIndex = TypeIndex(TypeIndex::FirstNonSimpleIndex);
|
||||
|
||||
if (auto EC =
|
||||
codeview::visitTypeStream(Types, *this, VDS_BytesExternal))
|
||||
if (auto EC = remapAllTypes(Types))
|
||||
return EC;
|
||||
|
||||
assert(NumBadIndices <= BadIndicesRemaining &&
|
||||
@ -319,6 +260,52 @@ Error TypeStreamMerger::doit(const CVTypeArray &Types) {
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error TypeStreamMerger::remapAllTypes(const CVTypeArray &Types) {
|
||||
for (const CVType &Type : Types)
|
||||
if (auto EC = remapType(Type))
|
||||
return EC;
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error TypeStreamMerger::remapType(const CVType &Type) {
|
||||
RemappedType R(Type);
|
||||
SmallVector<TiReference, 32> Refs;
|
||||
discoverTypeIndices(Type.RecordData, Refs);
|
||||
bool MappedAllIndices = remapIndices(R, Refs);
|
||||
TypeTableBuilder &Dest =
|
||||
isIdRecord(Type.kind()) ? *DestIdStream : *DestTypeStream;
|
||||
if (auto EC = writeRecord(Dest, R, MappedAllIndices))
|
||||
return EC;
|
||||
|
||||
++CurIndex;
|
||||
assert((IsSecondPass || IndexMap.size() == slotForIndex(CurIndex)) &&
|
||||
"visitKnownRecord should add one index map entry");
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
bool TypeStreamMerger::remapIndices(RemappedType &Record,
|
||||
ArrayRef<TiReference> Refs) {
|
||||
ArrayRef<uint8_t> OriginalData = Record.OriginalRecord.content();
|
||||
bool Success = true;
|
||||
for (auto &Ref : Refs) {
|
||||
uint32_t Offset = Ref.Offset;
|
||||
ArrayRef<uint8_t> Bytes = OriginalData.slice(Ref.Offset, sizeof(TypeIndex));
|
||||
ArrayRef<TypeIndex> TIs(reinterpret_cast<const TypeIndex *>(Bytes.data()),
|
||||
Ref.Count);
|
||||
for (auto TI : TIs) {
|
||||
TypeIndex NewTI = TI;
|
||||
bool ThisSuccess = (Ref.Kind == TiRefKind::IndexRef)
|
||||
? remapItemIndex(NewTI)
|
||||
: remapTypeIndex(NewTI);
|
||||
if (ThisSuccess && NewTI != TI)
|
||||
Record.Mappings.emplace_back(Offset, NewTI);
|
||||
Offset += sizeof(TypeIndex);
|
||||
Success &= ThisSuccess;
|
||||
}
|
||||
}
|
||||
return Success;
|
||||
}
|
||||
|
||||
Error llvm::codeview::mergeTypeRecords(TypeTableBuilder &Dest,
|
||||
SmallVectorImpl<TypeIndex> &SourceToDest,
|
||||
const CVTypeArray &Types) {
|
||||
|
Loading…
Reference in New Issue
Block a user