1
0
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:
Reid Kleckner 2017-07-17 20:31:38 +00:00
parent 3ab9e840a9
commit b44e270a45

View File

@ -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) {