[llvm] r322871 - Speed up iteration of CodeView record streams.
Zachary Turner via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 18 10:35:02 PST 2018
Author: zturner
Date: Thu Jan 18 10:35:01 2018
New Revision: 322871
URL: http://llvm.org/viewvc/llvm-project?rev=322871&view=rev
Log:
Speed up iteration of CodeView record streams.
There's some abstraction overhead in the underlying
mechanisms that were being used, and it was leading to an
abundance of small but not-free copies being made. This
showed up on a profile. Eliminating this and going back to
a low-level byte-based implementation speeds up lld with
/DEBUG between 10 and 15%.
Differential Revision: https://reviews.llvm.org/D42148
Modified:
llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h
llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h?rev=322871&r1=322870&r2=322871&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CVRecord.h Thu Jan 18 10:35:01 2018
@@ -61,6 +61,30 @@ template <typename Kind> struct Remapped
SmallVector<std::pair<uint32_t, TypeIndex>, 8> Mappings;
};
+template <typename Record, typename Func>
+Error forEachCodeViewRecord(ArrayRef<uint8_t> StreamBuffer, Func F) {
+ while (!StreamBuffer.empty()) {
+ if (StreamBuffer.size() < sizeof(RecordPrefix))
+ return make_error<CodeViewError>(cv_error_code::corrupt_record);
+
+ const RecordPrefix *Prefix =
+ reinterpret_cast<const RecordPrefix *>(StreamBuffer.data());
+
+ uint16_t RealLen = Prefix->RecordLen + 2;
+ if (StreamBuffer.size() < RealLen)
+ return make_error<CodeViewError>(cv_error_code::corrupt_record);
+
+ ArrayRef<uint8_t> Data = StreamBuffer.take_front(RealLen);
+ StreamBuffer = StreamBuffer.drop_front(RealLen);
+
+ Record R(static_cast<decltype(Record::Type)>((uint16_t)Prefix->RecordKind),
+ Data);
+ if (auto EC = F(R))
+ return EC;
+ }
+ return Error::success();
+}
+
/// Read a complete record from a stream at a random offset.
template <typename Kind>
inline Expected<CVRecord<Kind>> readCVRecordFromStream(BinaryStreamRef Stream,
Modified: llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp?rev=322871&r1=322870&r2=322871&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp (original)
+++ llvm/trunk/lib/DebugInfo/CodeView/TypeStreamMerger.cpp Thu Jan 18 10:35:01 2018
@@ -346,10 +346,12 @@ Error TypeStreamMerger::doit(const CVTyp
}
Error TypeStreamMerger::remapAllTypes(const CVTypeArray &Types) {
- for (const CVType &Type : Types)
- if (auto EC = remapType(Type))
- return EC;
- return Error::success();
+ BinaryStreamRef Stream = Types.getUnderlyingStream();
+ ArrayRef<uint8_t> Buffer;
+ cantFail(Stream.readBytes(0, Stream.getLength(), Buffer));
+
+ return forEachCodeViewRecord<CVType>(
+ Buffer, [this](const CVType &T) { return remapType(T); });
}
Error TypeStreamMerger::remapType(const CVType &Type) {
More information about the llvm-commits
mailing list