[llvm] 6c42d0d - [MC,CodeView] Postpone MCDataFragment creation to finish time

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sat Dec 21 21:13:08 PST 2024


Author: Fangrui Song
Date: 2024-12-21T21:13:02-08:00
New Revision: 6c42d0d7df55f28084e41b482dd7c25d4e7bcd10

URL: https://github.com/llvm/llvm-project/commit/6c42d0d7df55f28084e41b482dd7c25d4e7bcd10
DIFF: https://github.com/llvm/llvm-project/commit/6c42d0d7df55f28084e41b482dd7c25d4e7bcd10.diff

LOG: [MC,CodeView] Postpone MCDataFragment creation to finish time

`StrTabFragment` created due to `.cv_stringtable` is not placed directly
into a section. This requires a funky ~CodeViewContext and does not fit
well with the future that moves MCFragment storage out-of-line.

Added: 
    

Modified: 
    llvm/include/llvm/MC/MCCodeView.h
    llvm/lib/MC/MCCodeView.cpp
    llvm/lib/MC/MCWinCOFFStreamer.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/MC/MCCodeView.h b/llvm/include/llvm/MC/MCCodeView.h
index 30923274ea72d4..2a57e04b2c88c5 100644
--- a/llvm/include/llvm/MC/MCCodeView.h
+++ b/llvm/include/llvm/MC/MCCodeView.h
@@ -144,11 +144,12 @@ struct MCCVFunctionInfo {
 class CodeViewContext {
 public:
   CodeViewContext(MCContext *MCCtx) : MCCtx(MCCtx) {}
-  ~CodeViewContext();
 
   CodeViewContext &operator=(const CodeViewContext &other) = delete;
   CodeViewContext(const CodeViewContext &other) = delete;
 
+  void finish();
+
   bool isValidFileNumber(unsigned FileNumber) const;
   bool addFile(MCStreamer &OS, unsigned FileNumber, StringRef Filename,
                ArrayRef<uint8_t> ChecksumBytes, uint8_t ChecksumKind);
@@ -230,9 +231,7 @@ class CodeViewContext {
 
   /// The fragment that ultimately holds our strings.
   MCDataFragment *StrTabFragment = nullptr;
-  bool InsertedStrTabFragment = false;
-
-  MCDataFragment *getStringTableFragment();
+  SmallVector<char, 0> StrTab = {'\0'};
 
   /// Get a string table offset.
   unsigned getStringTableOffset(StringRef S);

diff  --git a/llvm/lib/MC/MCCodeView.cpp b/llvm/lib/MC/MCCodeView.cpp
index 9e4a69ea18559c..e78f5a082925d3 100644
--- a/llvm/lib/MC/MCCodeView.cpp
+++ b/llvm/lib/MC/MCCodeView.cpp
@@ -25,11 +25,9 @@
 using namespace llvm;
 using namespace llvm::codeview;
 
-CodeViewContext::~CodeViewContext() {
-  // If someone inserted strings into the string table but never actually
-  // emitted them somewhere, clean up the fragment.
-  if (!InsertedStrTabFragment && StrTabFragment)
-    StrTabFragment->destroy();
+void CodeViewContext::finish() {
+  if (StrTabFragment)
+    StrTabFragment->setContents(StrTab);
 }
 
 /// This is a valid number for use with .cv_loc if we've already seen a .cv_file
@@ -133,26 +131,15 @@ void CodeViewContext::recordCVLoc(MCContext &Ctx, const MCSymbol *Label,
       Label, FunctionId, FileNo, Line, Column, PrologueEnd, IsStmt});
 }
 
-MCDataFragment *CodeViewContext::getStringTableFragment() {
-  if (!StrTabFragment) {
-    StrTabFragment = MCCtx->allocFragment<MCDataFragment>();
-    // Start a new string table out with a null byte.
-    StrTabFragment->appendContents(1, '\0');
-  }
-  return StrTabFragment;
-}
-
 std::pair<StringRef, unsigned> CodeViewContext::addToStringTable(StringRef S) {
-  SmallVectorImpl<char> &Contents = getStringTableFragment()->getContents();
   auto Insertion =
-      StringTable.insert(std::make_pair(S, unsigned(Contents.size())));
+      StringTable.insert(std::make_pair(S, unsigned(StrTab.size())));
   // Return the string from the table, since it is stable.
   std::pair<StringRef, unsigned> Ret =
       std::make_pair(Insertion.first->first(), Insertion.first->second);
   if (Insertion.second) {
     // The string map key is always null terminated.
-    StrTabFragment->appendContents(
-        ArrayRef(Ret.first.begin(), Ret.first.end() + 1));
+    StrTab.append(Ret.first.begin(), Ret.first.end() + 1);
   }
   return Ret;
 }
@@ -178,9 +165,9 @@ void CodeViewContext::emitStringTable(MCObjectStreamer &OS) {
   // Put the string table data fragment here, if we haven't already put it
   // somewhere else. If somebody wants two string tables in their .s file, one
   // will just be empty.
-  if (!InsertedStrTabFragment) {
-    OS.insert(getStringTableFragment());
-    InsertedStrTabFragment = true;
+  if (!StrTabFragment) {
+    StrTabFragment = Ctx.allocFragment<MCDataFragment>();
+    OS.insert(StrTabFragment);
   }
 
   OS.emitValueToAlignment(Align(4), 0);
@@ -375,11 +362,9 @@ void CodeViewContext::emitLineTableForFunction(MCObjectStreamer &OS,
           return Loc.getFileNum() != CurFileNum;
         });
     unsigned EntryCount = FileSegEnd - I;
-    OS.AddComment(
-        "Segment for file '" +
-        Twine(getStringTableFragment()
-                  ->getContents()[Files[CurFileNum - 1].StringTableOffset]) +
-        "' begins");
+    OS.AddComment("Segment for file '" +
+                  Twine(StrTab[Files[CurFileNum - 1].StringTableOffset]) +
+                  "' begins");
     OS.emitCVFileChecksumOffsetDirective(CurFileNum);
     OS.emitInt32(EntryCount);
     uint32_t SegmentSize = 12;

diff  --git a/llvm/lib/MC/MCWinCOFFStreamer.cpp b/llvm/lib/MC/MCWinCOFFStreamer.cpp
index fcd6c24d0778bd..395d4db3103d78 100644
--- a/llvm/lib/MC/MCWinCOFFStreamer.cpp
+++ b/llvm/lib/MC/MCWinCOFFStreamer.cpp
@@ -18,6 +18,7 @@
 #include "llvm/MC/MCAsmBackend.h"
 #include "llvm/MC/MCAssembler.h"
 #include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCCodeView.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCFixup.h"
@@ -370,6 +371,7 @@ void MCWinCOFFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE) {
 }
 
 void MCWinCOFFStreamer::finishImpl() {
+  getContext().getCVContext().finish();
   MCAssembler &Asm = getAssembler();
   if (Asm.getWriter().getEmitAddrsigSection()) {
     // Register the section.


        


More information about the llvm-commits mailing list