[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-20 Thread Fangrui Song via llvm-branch-commits

https://github.com/MaskRay updated 
https://github.com/llvm/llvm-project/pull/149465


___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-20 Thread Fangrui Song via llvm-branch-commits

https://github.com/MaskRay edited 
https://github.com/llvm/llvm-project/pull/149465
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-20 Thread Fangrui Song via llvm-branch-commits

https://github.com/MaskRay updated 
https://github.com/llvm/llvm-project/pull/149465


___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-20 Thread Fangrui Song via llvm-branch-commits

MaskRay wrote:

Next steps:

* Allocate the fixed content as trailing data of the MCFragment by utilizing a 
special bump allocator (gnulib obstack)
* Delete MCFixup member variables from MCFragment. Instead, add a MCFragment 
pointer to MCFixup.

https://github.com/llvm/llvm-project/pull/149465
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-20 Thread Fangrui Song via llvm-branch-commits


@@ -992,7 +965,30 @@ void MCAssembler::layoutSection(MCSection &Sec) {
   uint64_t Offset = 0;
   for (MCFragment &F : Sec) {
 F.Offset = Offset;
-Offset += computeFragmentSize(F);
+if (F.getKind() == MCFragment::FT_Align) {
+  Offset += F.getFixedSize();
+  unsigned Size = offsetToAlignment(Offset, F.getAlignment());
+  // In the nops mode, RISC-V style linker relaxation might adjust the size
+  // and add a fixup, even if `Size` is originally 0.
+  bool AlignFixup = false;
+  if (F.hasAlignEmitNops()) {
+AlignFixup = getBackend().relaxAlign(F, Size);
+// If the backend does not handle the fragment specially, pad with 
nops,
+// but ensure that the padding is larger than the minimum nop size.
+if (!AlignFixup)
+  while (Size % getBackend().getMinimumNopSize())
+Size += F.getAlignment().value();
+  }
+  if (!AlignFixup && Size > F.getAlignMaxBytesToEmit())
+Size = 0;
+  // Update the variable tail size. The content is ignored.
+  F.VarContentEnd = F.VarContentStart + Size;

MaskRay wrote:

Agree! Let me try `assert(F.VarContentStart == 0);`

https://github.com/llvm/llvm-project/pull/149465
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-19 Thread Alexis Engelke via llvm-branch-commits

https://github.com/aengelke edited 
https://github.com/llvm/llvm-project/pull/149465
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-19 Thread Alexis Engelke via llvm-branch-commits


@@ -992,7 +965,30 @@ void MCAssembler::layoutSection(MCSection &Sec) {
   uint64_t Offset = 0;
   for (MCFragment &F : Sec) {
 F.Offset = Offset;
-Offset += computeFragmentSize(F);
+if (F.getKind() == MCFragment::FT_Align) {
+  Offset += F.getFixedSize();
+  unsigned Size = offsetToAlignment(Offset, F.getAlignment());
+  // In the nops mode, RISC-V style linker relaxation might adjust the size
+  // and add a fixup, even if `Size` is originally 0.
+  bool AlignFixup = false;
+  if (F.hasAlignEmitNops()) {
+AlignFixup = getBackend().relaxAlign(F, Size);
+// If the backend does not handle the fragment specially, pad with 
nops,
+// but ensure that the padding is larger than the minimum nop size.
+if (!AlignFixup)
+  while (Size % getBackend().getMinimumNopSize())
+Size += F.getAlignment().value();
+  }
+  if (!AlignFixup && Size > F.getAlignMaxBytesToEmit())
+Size = 0;
+  // Update the variable tail size. The content is ignored.
+  F.VarContentEnd = F.VarContentStart + Size;

aengelke wrote:

NB: VarContentStart should be zero here, it is never set for FT_Align. For 
clarity, I'd suggest:
```suggestion
  F.VarContentStart = 0;
  F.VarContentEnd = Size;
```

https://github.com/llvm/llvm-project/pull/149465
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-19 Thread Alexis Engelke via llvm-branch-commits

https://github.com/aengelke approved this pull request.

LGTM

https://github.com/llvm/llvm-project/pull/149465
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-19 Thread Fangrui Song via llvm-branch-commits


@@ -433,42 +434,44 @@ static void writeFragment(raw_ostream &OS, const 
MCAssembler &Asm,
 const auto &EF = cast(F);
 OS << StringRef(EF.getContents().data(), EF.getContents().size());
 OS << StringRef(EF.getVarContents().data(), EF.getVarContents().size());
-if (F.getKind() == MCFragment::FT_Align) {
-  ++stats::EmittedAlignFragments;
-  assert(F.getAlignFillLen() &&
- "Invalid virtual align in concrete fragment!");
-
-  uint64_t Count = (FragmentSize - F.getFixedSize()) / F.getAlignFillLen();
-  assert((FragmentSize - F.getFixedSize()) % F.getAlignFillLen() == 0 &&
- "computeFragmentSize computed size is incorrect");
-
-  // See if we are aligning with nops, and if so do that first to try to
-  // fill the Count bytes.  Then if that did not fill any bytes or there 
are
-  // any bytes left to fill use the Value and ValueSize to fill the rest. 
If
-  // we are aligning with nops, ask that target to emit the right data.
-  if (F.hasAlignEmitNops()) {
-if (!Asm.getBackend().writeNopData(OS, Count, F.getSubtargetInfo()))
-  report_fatal_error("unable to write nop sequence of " + Twine(Count) 
+
- " bytes");
-  } else {
-// Otherwise, write out in multiples of the value size.
-for (uint64_t i = 0; i != Count; ++i) {
-  switch (F.getAlignFillLen()) {
-  default:
-llvm_unreachable("Invalid size!");
-  case 1:
-OS << char(F.getAlignFill());
-break;
-  case 2:
-support::endian::write(OS, F.getAlignFill(), Endian);
-break;
-  case 4:
-support::endian::write(OS, F.getAlignFill(), Endian);
-break;
-  case 8:
-support::endian::write(OS, F.getAlignFill(), Endian);
-break;
-  }
+  } break;
+
+  case MCFragment::FT_Align: {
+++stats::EmittedAlignFragments;
+OS << StringRef(F.getContents().data(), F.getContents().size());
+assert(F.getAlignFillLen() &&
+   "Invalid virtual align in concrete fragment!");
+
+uint64_t Count = (FragmentSize - F.getFixedSize()) / F.getAlignFillLen();
+assert((FragmentSize - F.getFixedSize()) % F.getAlignFillLen() == 0 &&
+   "computeFragmentSize computed size is incorrect");
+
+// See if we are aligning with nops, and if so do that first to try to
+// fill the Count bytes.  Then if that did not fill any bytes or there are
+// any bytes left to fill use the Value and ValueSize to fill the rest. If
+// we are aligning with nops, ask that target to emit the right data.

MaskRay wrote:

I think we can simplify the comment. Updated it to "// In the nops mode, call 
the backend hook to write `Count` nops."

https://github.com/llvm/llvm-project/pull/149465
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-19 Thread Fangrui Song via llvm-branch-commits


@@ -230,22 +230,24 @@ uint64_t MCAssembler::computeFragmentSize(const 
MCFragment &F) const {
   case MCFragment::FT_Align: {
 unsigned Offset = F.Offset + F.getFixedSize();
 unsigned Size = offsetToAlignment(Offset, F.getAlignment());
-
-// Insert extra Nops for code alignment if the target define
-// shouldInsertExtraNopBytesForCodeAlign target hook.
-if (F.getParent()->useCodeAlign() && F.hasAlignEmitNops() &&
-getBackend().shouldInsertExtraNopBytesForCodeAlign(F, Size))
-  return F.getFixedSize() + Size;
-
-// If we are padding with nops, force the padding to be larger than the
-// minimum nop size.
-if (Size > 0 && F.hasAlignEmitNops()) {
-  while (Size % getBackend().getMinimumNopSize())
-Size += F.getAlignment().value();
+auto &Frag = const_cast(F);
+// In the nops mode, RISC-V style linker relaxation might adjust the size
+// and add a fixup, even if `Size` is originally 0.
+bool AlignFixup = false;
+if (F.hasAlignEmitNops()) {
+  AlignFixup = getBackend().relaxAlign(Frag, Size);
+  // If the backend does not handle the fragment specially, pad with nops,
+  // but ensure that the padding is larger than the minimum nop size.
+  if (!AlignFixup)
+while (Size % getBackend().getMinimumNopSize())
+  Size += F.getAlignment().value();
 }
-if (Size > F.getAlignMaxBytesToEmit())
+if (!AlignFixup && Size > F.getAlignMaxBytesToEmit())
   Size = 0;
-return F.getFixedSize() + Size;
+Frag.VarContentEnd = F.VarContentStart + Size;
+if (Frag.VarContentEnd > Frag.getParent()->ContentStorage.size())
+  Frag.getParent()->ContentStorage.resize(Frag.VarContentEnd);

MaskRay wrote:

Added comment "// Update the variable tail size. The content is ignored."

https://github.com/llvm/llvm-project/pull/149465
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-19 Thread Fangrui Song via llvm-branch-commits

https://github.com/MaskRay updated 
https://github.com/llvm/llvm-project/pull/149465


___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-19 Thread Fangrui Song via llvm-branch-commits

https://github.com/MaskRay updated 
https://github.com/llvm/llvm-project/pull/149465


___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-18 Thread Fangrui Song via llvm-branch-commits

https://github.com/MaskRay updated 
https://github.com/llvm/llvm-project/pull/149465


___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-18 Thread Fangrui Song via llvm-branch-commits

https://github.com/MaskRay updated 
https://github.com/llvm/llvm-project/pull/149465


___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-18 Thread Fangrui Song via llvm-branch-commits

https://github.com/MaskRay updated 
https://github.com/llvm/llvm-project/pull/149465


___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-18 Thread Fangrui Song via llvm-branch-commits

https://github.com/MaskRay updated 
https://github.com/llvm/llvm-project/pull/149465


___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-18 Thread Fangrui Song via llvm-branch-commits


@@ -230,22 +230,24 @@ uint64_t MCAssembler::computeFragmentSize(const 
MCFragment &F) const {
   case MCFragment::FT_Align: {
 unsigned Offset = F.Offset + F.getFixedSize();
 unsigned Size = offsetToAlignment(Offset, F.getAlignment());
-
-// Insert extra Nops for code alignment if the target define
-// shouldInsertExtraNopBytesForCodeAlign target hook.
-if (F.getParent()->useCodeAlign() && F.hasAlignEmitNops() &&
-getBackend().shouldInsertExtraNopBytesForCodeAlign(F, Size))
-  return F.getFixedSize() + Size;
-
-// If we are padding with nops, force the padding to be larger than the
-// minimum nop size.
-if (Size > 0 && F.hasAlignEmitNops()) {
-  while (Size % getBackend().getMinimumNopSize())
-Size += F.getAlignment().value();
+auto &Frag = const_cast(F);
+// In the nops mode, RISC-V style linker relaxation might adjust the size
+// and add a fixup, even if `Size` is originally 0.
+bool AlignFixup = false;
+if (F.hasAlignEmitNops()) {
+  AlignFixup = getBackend().relaxAlign(Frag, Size);

MaskRay wrote:

Thanks for the feedback! There is currently an oddity in the layout algorithm

* 
https://github.com/llvm/llvm-project/blob/a9147e64aa751caaa106953fded2d0f7223bb167/llvm/lib/MC/MCAssembler.cpp#L676
 This `layoutSection` assigns offsets to fragments, including FT_Align (using 
`computeFragmentSize`)
* `relaxOnce` checks FT_Relaxable (which should probably be renamed to FT_Insn) 
but not FT_Align

Future `computeFragmentSize` calls should not modify the member variable. I 
should perhaps move this FT_Align handling to `layoutSection` so that 
`computeFragmentSize` can simply return `getSize()`.

https://github.com/llvm/llvm-project/pull/149465
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-18 Thread Fangrui Song via llvm-branch-commits

https://github.com/MaskRay edited 
https://github.com/llvm/llvm-project/pull/149465
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-18 Thread Alexis Engelke via llvm-branch-commits

https://github.com/aengelke edited 
https://github.com/llvm/llvm-project/pull/149465
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-18 Thread Alexis Engelke via llvm-branch-commits


@@ -433,42 +434,44 @@ static void writeFragment(raw_ostream &OS, const 
MCAssembler &Asm,
 const auto &EF = cast(F);
 OS << StringRef(EF.getContents().data(), EF.getContents().size());
 OS << StringRef(EF.getVarContents().data(), EF.getVarContents().size());
-if (F.getKind() == MCFragment::FT_Align) {
-  ++stats::EmittedAlignFragments;
-  assert(F.getAlignFillLen() &&
- "Invalid virtual align in concrete fragment!");
-
-  uint64_t Count = (FragmentSize - F.getFixedSize()) / F.getAlignFillLen();
-  assert((FragmentSize - F.getFixedSize()) % F.getAlignFillLen() == 0 &&
- "computeFragmentSize computed size is incorrect");
-
-  // See if we are aligning with nops, and if so do that first to try to
-  // fill the Count bytes.  Then if that did not fill any bytes or there 
are
-  // any bytes left to fill use the Value and ValueSize to fill the rest. 
If
-  // we are aligning with nops, ask that target to emit the right data.
-  if (F.hasAlignEmitNops()) {
-if (!Asm.getBackend().writeNopData(OS, Count, F.getSubtargetInfo()))
-  report_fatal_error("unable to write nop sequence of " + Twine(Count) 
+
- " bytes");
-  } else {
-// Otherwise, write out in multiples of the value size.
-for (uint64_t i = 0; i != Count; ++i) {
-  switch (F.getAlignFillLen()) {
-  default:
-llvm_unreachable("Invalid size!");
-  case 1:
-OS << char(F.getAlignFill());
-break;
-  case 2:
-support::endian::write(OS, F.getAlignFill(), Endian);
-break;
-  case 4:
-support::endian::write(OS, F.getAlignFill(), Endian);
-break;
-  case 8:
-support::endian::write(OS, F.getAlignFill(), Endian);
-break;
-  }
+  } break;
+
+  case MCFragment::FT_Align: {
+++stats::EmittedAlignFragments;
+OS << StringRef(F.getContents().data(), F.getContents().size());
+assert(F.getAlignFillLen() &&
+   "Invalid virtual align in concrete fragment!");
+
+uint64_t Count = (FragmentSize - F.getFixedSize()) / F.getAlignFillLen();
+assert((FragmentSize - F.getFixedSize()) % F.getAlignFillLen() == 0 &&
+   "computeFragmentSize computed size is incorrect");
+
+// See if we are aligning with nops, and if so do that first to try to
+// fill the Count bytes.  Then if that did not fill any bytes or there are
+// any bytes left to fill use the Value and ValueSize to fill the rest. If
+// we are aligning with nops, ask that target to emit the right data.

aengelke wrote:

Comment outdated?

https://github.com/llvm/llvm-project/pull/149465
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-18 Thread Alexis Engelke via llvm-branch-commits

https://github.com/aengelke commented:

I like reducing the number of hooks, but the const_cast feels to hacky.

https://github.com/llvm/llvm-project/pull/149465
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-18 Thread Alexis Engelke via llvm-branch-commits


@@ -230,22 +230,24 @@ uint64_t MCAssembler::computeFragmentSize(const 
MCFragment &F) const {
   case MCFragment::FT_Align: {
 unsigned Offset = F.Offset + F.getFixedSize();
 unsigned Size = offsetToAlignment(Offset, F.getAlignment());
-
-// Insert extra Nops for code alignment if the target define
-// shouldInsertExtraNopBytesForCodeAlign target hook.
-if (F.getParent()->useCodeAlign() && F.hasAlignEmitNops() &&
-getBackend().shouldInsertExtraNopBytesForCodeAlign(F, Size))
-  return F.getFixedSize() + Size;
-
-// If we are padding with nops, force the padding to be larger than the
-// minimum nop size.
-if (Size > 0 && F.hasAlignEmitNops()) {
-  while (Size % getBackend().getMinimumNopSize())
-Size += F.getAlignment().value();
+auto &Frag = const_cast(F);
+// In the nops mode, RISC-V style linker relaxation might adjust the size
+// and add a fixup, even if `Size` is originally 0.
+bool AlignFixup = false;
+if (F.hasAlignEmitNops()) {
+  AlignFixup = getBackend().relaxAlign(Frag, Size);
+  // If the backend does not handle the fragment specially, pad with nops,
+  // but ensure that the padding is larger than the minimum nop size.
+  if (!AlignFixup)
+while (Size % getBackend().getMinimumNopSize())
+  Size += F.getAlignment().value();
 }
-if (Size > F.getAlignMaxBytesToEmit())
+if (!AlignFixup && Size > F.getAlignMaxBytesToEmit())
   Size = 0;
-return F.getFixedSize() + Size;
+Frag.VarContentEnd = F.VarContentStart + Size;
+if (Frag.VarContentEnd > Frag.getParent()->ContentStorage.size())
+  Frag.getParent()->ContentStorage.resize(Frag.VarContentEnd);

aengelke wrote:

Also add comment here that actual content is ignored and that this is only for 
tracking the size?

https://github.com/llvm/llvm-project/pull/149465
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-18 Thread via llvm-branch-commits

llvmbot wrote:



@llvm/pr-subscribers-mc

@llvm/pr-subscribers-backend-risc-v

Author: Fangrui Song (MaskRay)


Changes

Previously, two MCAsmBackend hooks were used, with
shouldInsertFixupForCodeAlign calling getWriter().recordRelocation
directly, bypassing generic code.

This patch:

* Introduces MCAsmBackend::relaxAlign to replace the two hooks.
* Tracks padding size using VarContentStart and VarContentEnd (content is 
arbitrary).
* Move setLinkerRelaxable from MCObjectStreamer::emitCodeAlignment to the 
backends.


---

Patch is 23.35 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/149465.diff


10 Files Affected:

- (modified) llvm/include/llvm/MC/MCAsmBackend.h (+4-14) 
- (modified) llvm/lib/MC/MCAssembler.cpp (+54-56) 
- (modified) llvm/lib/MC/MCExpr.cpp (+1-4) 
- (modified) llvm/lib/MC/MCFragment.cpp (+6-1) 
- (modified) llvm/lib/MC/MCObjectStreamer.cpp (-6) 
- (modified) llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp 
(+55-68) 
- (modified) llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h 
(+1-7) 
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp (+19-49) 
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h (+1-7) 
- (modified) llvm/test/MC/RISCV/Relocations/mc-dump.s (+4-2) 


``diff
diff --git a/llvm/include/llvm/MC/MCAsmBackend.h 
b/llvm/include/llvm/MC/MCAsmBackend.h
index 93259b0ea6d74..e476b76e0ab08 100644
--- a/llvm/include/llvm/MC/MCAsmBackend.h
+++ b/llvm/include/llvm/MC/MCAsmBackend.h
@@ -103,20 +103,6 @@ class LLVM_ABI MCAsmBackend {
   /// Get information on a fixup kind.
   virtual MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const;
 
-  /// Hook to check if extra nop bytes must be inserted for alignment 
directive.
-  /// For some targets this may be necessary in order to support linker
-  /// relaxation. The number of bytes to insert are returned in Size.
-  virtual bool shouldInsertExtraNopBytesForCodeAlign(const MCFragment &AF,
- unsigned &Size) {
-return false;
-  }
-
-  /// Hook which indicates if the target requires a fixup to be generated when
-  /// handling an align directive in an executable section
-  virtual bool shouldInsertFixupForCodeAlign(MCAssembler &Asm, MCFragment &AF) 
{
-return false;
-  }
-
   // Evaluate a fixup, returning std::nullopt to use default handling for
   // `Value` and `IsResolved`. Otherwise, returns `IsResolved` with the
   // expectation that the hook updates `Value`.
@@ -174,6 +160,10 @@ class LLVM_ABI MCAsmBackend {
   }
 
   // Defined by linker relaxation targets.
+
+  // Return false to use default handling. Otherwise, set `Size` to the number
+  // of padding bytes.
+  virtual bool relaxAlign(MCFragment &F, unsigned &Size) { return false; }
   virtual bool relaxDwarfLineAddr(MCFragment &, bool &WasRelaxed) const {
 return false;
   }
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index f18ca38a27cad..cc6817fc62a24 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -230,22 +230,24 @@ uint64_t MCAssembler::computeFragmentSize(const 
MCFragment &F) const {
   case MCFragment::FT_Align: {
 unsigned Offset = F.Offset + F.getFixedSize();
 unsigned Size = offsetToAlignment(Offset, F.getAlignment());
-
-// Insert extra Nops for code alignment if the target define
-// shouldInsertExtraNopBytesForCodeAlign target hook.
-if (F.getParent()->useCodeAlign() && F.hasAlignEmitNops() &&
-getBackend().shouldInsertExtraNopBytesForCodeAlign(F, Size))
-  return F.getFixedSize() + Size;
-
-// If we are padding with nops, force the padding to be larger than the
-// minimum nop size.
-if (Size > 0 && F.hasAlignEmitNops()) {
-  while (Size % getBackend().getMinimumNopSize())
-Size += F.getAlignment().value();
+auto &Frag = const_cast(F);
+// In the nops mode, RISC-V style linker relaxation might adjust the size
+// and add a fixup, even if `Size` is originally 0.
+bool AlignFixup = false;
+if (F.hasAlignEmitNops()) {
+  AlignFixup = getBackend().relaxAlign(Frag, Size);
+  // If the backend does not handle the fragment specially, pad with nops,
+  // but ensure that the padding is larger than the minimum nop size.
+  if (!AlignFixup)
+while (Size % getBackend().getMinimumNopSize())
+  Size += F.getAlignment().value();
 }
-if (Size > F.getAlignMaxBytesToEmit())
+if (!AlignFixup && Size > F.getAlignMaxBytesToEmit())
   Size = 0;
-return F.getFixedSize() + Size;
+Frag.VarContentEnd = F.VarContentStart + Size;
+if (Frag.VarContentEnd > Frag.getParent()->ContentStorage.size())
+  Frag.getParent()->ContentStorage.resize(Frag.VarContentEnd);
+return F.getSize();
   }
 
   case MCFragment::FT_Org: {
@@ -419,7 +421,6 @@ static void writeFragment(raw_ostream &OS, const 
MCAssembler &Asm,
   switch (F.get

[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-18 Thread via llvm-branch-commits

llvmbot wrote:




@llvm/pr-subscribers-backend-loongarch

Author: Fangrui Song (MaskRay)


Changes

Previously, two MCAsmBackend hooks were used, with
shouldInsertFixupForCodeAlign calling getWriter().recordRelocation
directly, bypassing generic code.

This patch:

* Introduces MCAsmBackend::relaxAlign to replace the two hooks.
* Tracks padding size using VarContentStart and VarContentEnd (content is 
arbitrary).
* Move setLinkerRelaxable from MCObjectStreamer::emitCodeAlignment to the 
backends.


---

Patch is 23.35 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/149465.diff


10 Files Affected:

- (modified) llvm/include/llvm/MC/MCAsmBackend.h (+4-14) 
- (modified) llvm/lib/MC/MCAssembler.cpp (+54-56) 
- (modified) llvm/lib/MC/MCExpr.cpp (+1-4) 
- (modified) llvm/lib/MC/MCFragment.cpp (+6-1) 
- (modified) llvm/lib/MC/MCObjectStreamer.cpp (-6) 
- (modified) llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp 
(+55-68) 
- (modified) llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h 
(+1-7) 
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp (+19-49) 
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h (+1-7) 
- (modified) llvm/test/MC/RISCV/Relocations/mc-dump.s (+4-2) 


``diff
diff --git a/llvm/include/llvm/MC/MCAsmBackend.h 
b/llvm/include/llvm/MC/MCAsmBackend.h
index 93259b0ea6d74..e476b76e0ab08 100644
--- a/llvm/include/llvm/MC/MCAsmBackend.h
+++ b/llvm/include/llvm/MC/MCAsmBackend.h
@@ -103,20 +103,6 @@ class LLVM_ABI MCAsmBackend {
   /// Get information on a fixup kind.
   virtual MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const;
 
-  /// Hook to check if extra nop bytes must be inserted for alignment 
directive.
-  /// For some targets this may be necessary in order to support linker
-  /// relaxation. The number of bytes to insert are returned in Size.
-  virtual bool shouldInsertExtraNopBytesForCodeAlign(const MCFragment &AF,
- unsigned &Size) {
-return false;
-  }
-
-  /// Hook which indicates if the target requires a fixup to be generated when
-  /// handling an align directive in an executable section
-  virtual bool shouldInsertFixupForCodeAlign(MCAssembler &Asm, MCFragment &AF) 
{
-return false;
-  }
-
   // Evaluate a fixup, returning std::nullopt to use default handling for
   // `Value` and `IsResolved`. Otherwise, returns `IsResolved` with the
   // expectation that the hook updates `Value`.
@@ -174,6 +160,10 @@ class LLVM_ABI MCAsmBackend {
   }
 
   // Defined by linker relaxation targets.
+
+  // Return false to use default handling. Otherwise, set `Size` to the number
+  // of padding bytes.
+  virtual bool relaxAlign(MCFragment &F, unsigned &Size) { return false; }
   virtual bool relaxDwarfLineAddr(MCFragment &, bool &WasRelaxed) const {
 return false;
   }
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index f18ca38a27cad..cc6817fc62a24 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -230,22 +230,24 @@ uint64_t MCAssembler::computeFragmentSize(const 
MCFragment &F) const {
   case MCFragment::FT_Align: {
 unsigned Offset = F.Offset + F.getFixedSize();
 unsigned Size = offsetToAlignment(Offset, F.getAlignment());
-
-// Insert extra Nops for code alignment if the target define
-// shouldInsertExtraNopBytesForCodeAlign target hook.
-if (F.getParent()->useCodeAlign() && F.hasAlignEmitNops() &&
-getBackend().shouldInsertExtraNopBytesForCodeAlign(F, Size))
-  return F.getFixedSize() + Size;
-
-// If we are padding with nops, force the padding to be larger than the
-// minimum nop size.
-if (Size > 0 && F.hasAlignEmitNops()) {
-  while (Size % getBackend().getMinimumNopSize())
-Size += F.getAlignment().value();
+auto &Frag = const_cast(F);
+// In the nops mode, RISC-V style linker relaxation might adjust the size
+// and add a fixup, even if `Size` is originally 0.
+bool AlignFixup = false;
+if (F.hasAlignEmitNops()) {
+  AlignFixup = getBackend().relaxAlign(Frag, Size);
+  // If the backend does not handle the fragment specially, pad with nops,
+  // but ensure that the padding is larger than the minimum nop size.
+  if (!AlignFixup)
+while (Size % getBackend().getMinimumNopSize())
+  Size += F.getAlignment().value();
 }
-if (Size > F.getAlignMaxBytesToEmit())
+if (!AlignFixup && Size > F.getAlignMaxBytesToEmit())
   Size = 0;
-return F.getFixedSize() + Size;
+Frag.VarContentEnd = F.VarContentStart + Size;
+if (Frag.VarContentEnd > Frag.getParent()->ContentStorage.size())
+  Frag.getParent()->ContentStorage.resize(Frag.VarContentEnd);
+return F.getSize();
   }
 
   case MCFragment::FT_Org: {
@@ -419,7 +421,6 @@ static void writeFragment(raw_ostream &OS, const 
MCAssembler &Asm,
   switch (F.getKind()) {
   case MCF

[llvm-branch-commits] MC: Refactor FT_Align fragments when linker relaxation is enabled (PR #149465)

2025-07-18 Thread Fangrui Song via llvm-branch-commits

https://github.com/MaskRay created 
https://github.com/llvm/llvm-project/pull/149465

Previously, two MCAsmBackend hooks were used, with
shouldInsertFixupForCodeAlign calling getWriter().recordRelocation
directly, bypassing generic code.

This patch:

* Introduces MCAsmBackend::relaxAlign to replace the two hooks.
* Tracks padding size using VarContentStart and VarContentEnd (content is 
arbitrary).
* Move setLinkerRelaxable from MCObjectStreamer::emitCodeAlignment to the 
backends.



___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits