[llvm] 267b136 - MCFragment: Refactor code for MCFragment

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 12 20:29:39 PDT 2025


Author: Fangrui Song
Date: 2025-07-12T20:29:34-07:00
New Revision: 267b136359d8448c73432b4f3ceeefbf4c35e00b

URL: https://github.com/llvm/llvm-project/commit/267b136359d8448c73432b4f3ceeefbf4c35e00b
DIFF: https://github.com/llvm/llvm-project/commit/267b136359d8448c73432b4f3ceeefbf4c35e00b.diff

LOG: MCFragment: Refactor code for MCFragment

To prepare for moving content and fixup member variables from
MCEncodedFragment to MCFragment and removing
MCDataFragment/MCRelaxableFragment classes, replace dyn_cast with
getKind() tests.

Added: 
    

Modified: 
    llvm/include/llvm/MC/MCSection.h
    llvm/lib/MC/MCExpr.cpp
    llvm/lib/MC/MCObjectStreamer.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/MC/MCSection.h b/llvm/include/llvm/MC/MCSection.h
index d5bf6b97bfeae..16d57a7772a40 100644
--- a/llvm/include/llvm/MC/MCSection.h
+++ b/llvm/include/llvm/MC/MCSection.h
@@ -31,6 +31,7 @@ class MCAsmInfo;
 class MCAssembler;
 class MCContext;
 class MCExpr;
+class MCFragment;
 class MCObjectStreamer;
 class MCSymbol;
 class MCSection;
@@ -38,94 +39,13 @@ class MCSubtargetInfo;
 class raw_ostream;
 class Triple;
 
-// Represents a contiguous piece of code or data within a section. Its size is
-// determined by MCAssembler::layout. All subclasses must have trivial
-// destructors.
-//
-// Declaration order: MCFragment, MCSection, then MCFragment's derived classes.
-// This allows MCSection's inline functions to access MCFragment members and
-// allows MCFragment's derived classes to access MCSection.
-class MCFragment {
-  friend class MCAssembler;
-  friend class MCObjectStreamer;
-  friend class MCSection;
-
-public:
-  enum FragmentType : uint8_t {
-    FT_Data,
-    FT_Relaxable,
-    FT_Align,
-    FT_Fill,
-    FT_LEB,
-    FT_Nops,
-    FT_Org,
-    FT_Dwarf,
-    FT_DwarfFrame,
-    FT_BoundaryAlign,
-    FT_SymbolId,
-    FT_CVInlineLines,
-    FT_CVDefRange,
-    FT_PseudoProbe,
-  };
-
-private:
-  // The next fragment within the section.
-  MCFragment *Next = nullptr;
-
-  /// The data for the section this fragment is in.
-  MCSection *Parent = nullptr;
-
-  /// The offset of this fragment in its section.
-  uint64_t Offset = 0;
-
-  /// The layout order of this fragment.
-  unsigned LayoutOrder = 0;
-
-  FragmentType Kind;
-
-protected:
-  /// Used by subclasses for better packing.
-  ///
-  /// MCEncodedFragment
-  bool HasInstructions : 1;
-  bool AlignToBundleEnd : 1;
-  /// MCDataFragment
-  bool LinkerRelaxable : 1;
-  /// MCRelaxableFragment: x86-specific
-  bool AllowAutoPadding : 1;
-
-  LLVM_ABI MCFragment(FragmentType Kind, bool HasInstructions);
-
-public:
-  MCFragment() = delete;
-  MCFragment(const MCFragment &) = delete;
-  MCFragment &operator=(const MCFragment &) = delete;
-
-  MCFragment *getNext() const { return Next; }
-
-  FragmentType getKind() const { return Kind; }
-
-  MCSection *getParent() const { return Parent; }
-  void setParent(MCSection *Value) { Parent = Value; }
-
-  LLVM_ABI const MCSymbol *getAtom() const;
-
-  unsigned getLayoutOrder() const { return LayoutOrder; }
-  void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
-
-  /// Does this fragment have instructions emitted into it? By default
-  /// this is false, but specific fragment types may set it to true.
-  bool hasInstructions() const { return HasInstructions; }
-
-  LLVM_ABI void dump() const;
-};
-
 /// Instances of this class represent a uniqued identifier for a section in the
 /// current translation unit.  The MCContext class uniques and creates these.
 class LLVM_ABI MCSection {
 public:
   friend MCAssembler;
   friend MCObjectStreamer;
+  friend class MCFragment;
   friend class MCEncodedFragment;
   friend class MCRelaxableFragment;
   static constexpr unsigned NonUniqueID = ~0U;
@@ -155,10 +75,7 @@ class LLVM_ABI MCSection {
     MCFragment &operator*() const { return *F; }
     bool operator==(const iterator &O) const { return F == O.F; }
     bool operator!=(const iterator &O) const { return F != O.F; }
-    iterator &operator++() {
-      F = F->Next;
-      return *this;
-    }
+    iterator &operator++();
   };
 
   struct FragList {
@@ -296,6 +213,87 @@ class LLVM_ABI MCSection {
   virtual StringRef getVirtualSectionKind() const;
 };
 
+// Represents a contiguous piece of code or data within a section. Its size is
+// determined by MCAssembler::layout. All subclasses must have trivial
+// destructors.
+class MCFragment {
+  friend class MCAssembler;
+  friend class MCObjectStreamer;
+  friend class MCSection;
+
+public:
+  enum FragmentType : uint8_t {
+    FT_Data,
+    FT_Relaxable,
+    FT_Align,
+    FT_Fill,
+    FT_LEB,
+    FT_Nops,
+    FT_Org,
+    FT_Dwarf,
+    FT_DwarfFrame,
+    FT_BoundaryAlign,
+    FT_SymbolId,
+    FT_CVInlineLines,
+    FT_CVDefRange,
+    FT_PseudoProbe,
+  };
+
+private:
+  // The next fragment within the section.
+  MCFragment *Next = nullptr;
+
+  /// The data for the section this fragment is in.
+  MCSection *Parent = nullptr;
+
+  /// The offset of this fragment in its section.
+  uint64_t Offset = 0;
+
+  /// The layout order of this fragment.
+  unsigned LayoutOrder = 0;
+
+  FragmentType Kind;
+
+protected:
+  /// Used by subclasses for better packing.
+  ///
+  /// MCEncodedFragment
+  bool HasInstructions : 1;
+  bool AlignToBundleEnd : 1;
+  /// MCDataFragment
+  bool LinkerRelaxable : 1;
+  /// MCRelaxableFragment: x86-specific
+  bool AllowAutoPadding : 1;
+
+  LLVM_ABI MCFragment(FragmentType Kind, bool HasInstructions);
+
+public:
+  MCFragment() = delete;
+  MCFragment(const MCFragment &) = delete;
+  MCFragment &operator=(const MCFragment &) = delete;
+
+  MCFragment *getNext() const { return Next; }
+
+  FragmentType getKind() const { return Kind; }
+
+  MCSection *getParent() const { return Parent; }
+  void setParent(MCSection *Value) { Parent = Value; }
+
+  LLVM_ABI const MCSymbol *getAtom() const;
+
+  unsigned getLayoutOrder() const { return LayoutOrder; }
+  void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
+
+  /// Does this fragment have instructions emitted into it? By default
+  /// this is false, but specific fragment types may set it to true.
+  bool hasInstructions() const { return HasInstructions; }
+
+  bool isLinkerRelaxable() const { return LinkerRelaxable; }
+  void setLinkerRelaxable() { LinkerRelaxable = true; }
+
+  LLVM_ABI void dump() const;
+};
+
 /// Interface implemented by fragments that contain encoded instructions and/or
 /// data.
 class MCEncodedFragment : public MCFragment {
@@ -357,6 +355,9 @@ class MCEncodedFragment : public MCFragment {
     this->STI = &STI;
   }
 
+  bool getAllowAutoPadding() const { return AllowAutoPadding; }
+  void setAllowAutoPadding(bool V) { AllowAutoPadding = V; }
+
   // Content-related functions manage parent's storage using ContentStart and
   // ContentSize.
   void clearContents() { ContentEnd = ContentStart; }
@@ -407,6 +408,8 @@ class MCEncodedFragment : public MCFragment {
     return ArrayRef(getParent()->FixupStorage)
         .slice(FixupStart, FixupEnd - FixupStart);
   }
+
+  size_t getSize() const { return ContentEnd - ContentStart; }
 };
 
 /// Fragment for data and encoded instructions.
@@ -418,9 +421,6 @@ class MCDataFragment : public MCEncodedFragment {
   static bool classof(const MCFragment *F) {
     return F->getKind() == MCFragment::FT_Data;
   }
-
-  bool isLinkerRelaxable() const { return LinkerRelaxable; }
-  void setLinkerRelaxable() { LinkerRelaxable = true; }
 };
 
 /// A relaxable fragment holds on to its MCInst, since it may need to be
@@ -463,9 +463,6 @@ class MCRelaxableFragment : public MCEncodedFragment {
     llvm::copy(Inst, S.begin() + OperandStart);
   }
 
-  bool getAllowAutoPadding() const { return AllowAutoPadding; }
-  void setAllowAutoPadding(bool V) { AllowAutoPadding = V; }
-
   static bool classof(const MCFragment *F) {
     return F->getKind() == MCFragment::FT_Relaxable;
   }
@@ -794,6 +791,11 @@ class MCPseudoProbeAddrFragment : public MCEncodedFragment {
   }
 };
 
+inline MCSection::iterator &MCSection::iterator::operator++() {
+  F = F->Next;
+  return *this;
+}
+
 } // end namespace llvm
 
 #endif // LLVM_MC_MCSECTION_H

diff  --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp
index 79c3ec625cb7a..a196591744099 100644
--- a/llvm/lib/MC/MCExpr.cpp
+++ b/llvm/lib/MC/MCExpr.cpp
@@ -351,17 +351,17 @@ static void attemptToFoldSymbolOffsetDifference(const MCAssembler *Asm,
     // instruction, the 
diff erence cannot be resolved as it may be changed by
     // the linker.
     bool BBeforeRelax = false, AAfterRelax = false;
-    for (auto FI = FB; FI; FI = FI->getNext()) {
-      auto DF = dyn_cast<MCDataFragment>(FI);
+    for (auto F = FB; F; F = F->getNext()) {
+      auto DF = dyn_cast<MCDataFragment>(F);
       if (DF && DF->isLinkerRelaxable()) {
-        if (&*FI != FB || SBOffset != DF->getContents().size())
+        if (&*F != FB || SBOffset != DF->getContents().size())
           BBeforeRelax = true;
-        if (&*FI != FA || SAOffset == DF->getContents().size())
+        if (&*F != FA || SAOffset == DF->getContents().size())
           AAfterRelax = true;
         if (BBeforeRelax && AAfterRelax)
           return;
       }
-      if (&*FI == FA) {
+      if (&*F == FA) {
         // If FA and FB belong to the same subsection, the loop will find FA and
         // we can resolve the 
diff erence.
         Addend += Reverse ? -Displacement : Displacement;
@@ -373,18 +373,18 @@ static void attemptToFoldSymbolOffsetDifference(const MCAssembler *Asm,
       unsigned Count;
       if (DF) {
         Displacement += DF->getContents().size();
-      } else if (auto *RF = dyn_cast<MCRelaxableFragment>(FI);
+      } else if (auto *RF = dyn_cast<MCRelaxableFragment>(F);
                  RF && Asm->hasFinalLayout()) {
         // Before finishLayout, a relaxable fragment's size is indeterminate.
         // After layout, during relocation generation, it can be treated as a
         // data fragment.
         Displacement += RF->getContents().size();
-      } else if (auto *AF = dyn_cast<MCAlignFragment>(FI);
+      } else if (auto *AF = dyn_cast<MCAlignFragment>(F);
                  AF && Layout && AF->hasEmitNops() &&
                  !Asm->getBackend().shouldInsertExtraNopBytesForCodeAlign(
                      *AF, Count)) {
         Displacement += Asm->computeFragmentSize(*AF);
-      } else if (auto *FF = dyn_cast<MCFillFragment>(FI);
+      } else if (auto *FF = dyn_cast<MCFillFragment>(F);
                  FF && FF->getNumValues().evaluateAsAbsolute(Num)) {
         Displacement += Num * FF->getValueSize();
       } else {

diff  --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index 5cc9bed2669d4..b03c2283cdf4d 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -84,8 +84,9 @@ static std::optional<uint64_t> absoluteSymbolDiff(const MCSymbol *Hi,
     return 0;
   if (Hi->isVariable() || Lo->isVariable())
     return std::nullopt;
-  auto *LoF = dyn_cast_or_null<MCDataFragment>(Lo->getFragment());
-  if (!LoF || Hi->getFragment() != LoF || LoF->isLinkerRelaxable())
+  auto *LoF = Lo->getFragment();
+  if (!LoF || LoF->getKind() != MCFragment::FT_Data ||
+      Hi->getFragment() != LoF || LoF->isLinkerRelaxable())
     return std::nullopt;
 
   return Hi->getOffset() - Lo->getOffset();


        


More information about the llvm-commits mailing list