[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