393 Commits

Author SHA1 Message Date
Sterling-Augustine
2e9944a03e
Generate an .sframe section with a skeleton header (#151223)
This continues the sframe implementation discussed previously.

Of note, this also adds some target dependent functions to the object
file. Additional fields will be needed later. It would be possible to do
all of this inside the sframe implementation itself if it feels a little
messy and specialized, but generally I think that target info goes with
target info.

Another question is if we want a sentinel value for unimplemented sframe
abi arches, or a std::optional. Both work.
2025-08-12 12:57:31 -07:00
Sam Elliott
9e8f7acd2b
[RISCV] Track Linker Relaxable through Assembly Relaxation (#152602)
Span-dependent instructions on RISC-V interact in a complex manner with
linker relaxation. The span-dependent assembler algorithm implemented in
LLVM has to start with the smallest version of an instruction and then
only make it larger, so we compress instructions before emitting them to
the streamer.

When the instruction is streamed, the information that the instruction
(or rather, the fixup on the instruction) is linker relaxable must be
accurate, even though the assembler relaxation process may transform a
not-linker-relaxable instruction/fixup into one that that is linker
relaxable, for instance `c.jal` becoming `qc.e.jal`, or `bne` getting
turned into `beq; jal` (the `jal` is linker relaxable).

In order for this to work, the following things have to happen:
- Any instruction/fixup which might be relaxed to a linker-relaxable
instruction/fixup, gets marked as `RelaxCandidate = true` in
RISCVMCCodeEmitter.
- In RISCVAsmBackend, when emitting the `R_RISCV_RELAX` relocation, we
have to check that the relocation/fixup kind is one that may need a
relax relocation, as well as that it is marked as linker relaxable (the
latter will not be set if relaxation is disabled).
- Linker Relaxable instructions streamed to a Relaxable fragment need to
mark the fragment and its section as linker relaxable.

I also added more debug output for Sections/Fixups which are marked
Linker Relaxable.

This results in more relocations, when these PC-relative fixups cross an
instruction with a fixup that is resolved as not linker-relaxable but
caused the fragment to be marked linker relaxable at streaming time
(i.e. `c.j`).

Fixes: #150071
2025-08-12 09:02:48 +01:00
Fangrui Song
3769ce013b
MC: Refine ALIGN relocation conditions
Each section now tracks the index of the first linker-relaxable
fragment, enabling two changes:

* Delete redundant ALIGN relocations before the first linker-relaxable
  instruction in a section. The primary example is the offset 0
  R_RISCV_ALIGN relocation for a text section aligned by 4.
* For alignments larger than the NOP size after the first
  linker-relaxable instruction, ALIGN relocations are now generated, even in
  norelax regions. This fixes the issue #150159.

The new test llvm/test/MC/RISCV/Relocations/align-after-relax.s
verifies the required ALIGN in a norelax region following
linker-relaxable instructions.
By using a fragment index within the subsection (which is less than or
equal to the section's index), the implementation may generate redundant
ALIGN relocations in lower-numbered subsections before the first
linker-relaxable instruction.

align-option-relax.s demonstrates the ALIGN optimization.
Add an initial `call` to a few tests to prevent the ALIGN optimization.

---

When the alignment exceeds 2, we insert $alignment-2 bytes of NOPs, even
in non-RVC code. This enables non-RVC code following RVC code to handle
a 2-byte adjustment without requiring an additional state in MCSection
or AsmParser.

```
.globl _start
_start:
// GNU ld can relax this to  6505          lui     a0, 0x1
// LLD hasn't implemented this transformation.
  lui a0, %hi(foo)

.option push
.option norelax
.option norvc
// Now we generate R_RISCV_ALIGN with addend 2, even if this is a norvc region.
.balign 4
b0:
  .word 0x3a393837
.option pop
foo:
```

Pull Request: https://github.com/llvm/llvm-project/pull/150816
2025-08-07 19:16:58 -07:00
Fangrui Song
e8fc808bf8 Reapply "MCFragment: Use trailing data for fixed-size part" (#150846)
The fixed-size content of the MCFragment object is now stored as
trailing data, replacing ContentStart/ContentEnd with ContentSize. The
available space for trailing data is tracked using `FragSpace`. If the
available space is insufficient, a new block is allocated within the
bump allocator `MCObjectStreamer::FragStorage`.

FragList::Tail cannot be reused when switching sections or subsections,
as it is not associated with the fragment space tracked by `FragSpace`.
Instead, allocate a new fragment, which becomes less expensive after #150574.

Data can only be appended to the tail fragment of a subsection, not to
fragments in the middle. Post-assembler-layout adjustments (such as
.llvm_addrsig and .llvm.call-graph-profile) have been updated to use the
variable-size part instead.

---

This reverts commit a2fef664c29a53bfa8a66927fcf8b2e5c9da4876,
which reverted the innocent f1aa6050bd90f8ec4273da55d362e23905ad3a81 .
Commit df71243fa885cd3db701dc35a0c8d157adaf93b3, the MCOrgFragment fix,
has fixed the root cause of https://github.com/ClangBuiltLinux/linux/issues/2116
2025-08-04 09:10:42 -07:00
Fangrui Song
a2fef664c2 Revert "MCFragment: Use trailing data for fixed-size part"
This reverts commit f1aa6050bd90f8ec4273da55d362e23905ad3a81 (reland of #150846),
fixing conflicts.

It caused https://github.com/ClangBuiltLinux/linux/issues/2116 ,
which surfaced after a subsequent commit faa931b717c02d57f0814caa9133219040e6a85b decreased sizeof(MCFragment).

```
% /tmp/Debug/bin/clang "-cc1as" "-triple" "aarch64" "-filetype" "obj" "-main-file-name" "a.s" "-o" "a.o" "a.s"
clang: /home/ray/llvm/llvm/lib/MC/MCAssembler.cpp:615: void llvm::MCAssembler::writeSectionData(raw_ostream &, const MCSection *) const: Assertion `getContext().hadError() || OS.tell() - Start == getSectionAddressSize(*Sec)' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: /tmp/Debug/bin/clang -cc1as -triple aarch64 -filetype obj -main-file-name a.s -o a.o a.s
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0  libLLVMSupport.so.22.0git 0x00007cf91eb753cd llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 61
fish: Job 1, '/tmp/Debug/bin/clang "-cc1as" "…' terminated by signal SIGABRT (Abort)
```

The test is sensitive to precise fragment offsets. Using llvm-mc
-filetype=obj -triple=aarch64 a.s does not replicate the issue. However,
clang -cc1as includes an unnecessary `initSection` (adding an extra
FT_Align), which causes the problem.
2025-08-03 23:18:51 -07:00
Fangrui Song
9591f16a5a Move FragmentAllocator from MCContext to MCObjectStreamer
In MCContext::reset, delete a stale comment as MCCodeView no longer
owns or deallocates MCFragment.
2025-08-03 12:26:02 -07:00
Fangrui Song
f1aa6050bd MCFragment: Use trailing data for fixed-size part
Reapply after #151724 switched to `char *Data`, fixing a
-fsanitize=pointer-overflow issue in MCAssembler::layout.

---

The fixed-size content of the MCFragment object is now stored as
trailing data, replacing ContentStart/ContentEnd with ContentSize. The
available space for trailing data is tracked using `FragSpace`. If the
available space is insufficient, a new block is allocated within the
bump allocator `MCObjectStreamer::FragStorage`.

FragList::Tail cannot be reused when switching sections or subsections,
as it is not associated with the fragment space tracked by `FragSpace`.
Instead, allocate a new fragment, which becomes less expensive after #150574.

Data can only be appended to the tail fragment of a subsection, not to
fragments in the middle. Post-assembler-layout adjustments (such as
.llvm_addrsig and .llvm.call-graph-profile) have been updated to use the
variable-size part instead.

Pull Request: https://github.com/llvm/llvm-project/pull/150846
2025-08-02 10:29:33 -07:00
Nikolay Panchenko
f5d49c71b4
Revert "MCFragment: Use trailing data for fixed-size part" (#151383)
Reverts llvm/llvm-project#150846 due to unsigned underflow identifier by
UBSan in several tests
2025-07-30 16:48:53 -04:00
Fangrui Song
3ecefba52d MC: Restore emitInstToData optimization
Accidentally dropped by f36ce53adf9294556c5d5f5f55c484c923f0c286
2025-07-28 23:31:39 -07:00
Fangrui Song
f36ce53adf
MCFragment: Use trailing data for fixed-size part
The fixed-size content of the MCFragment object is now stored as
trailing data, replacing ContentStart/ContentEnd with ContentSize. The
available space for trailing data is tracked using `FragSpace`. If the
available space is insufficient, a new block is allocated within the
bump allocator `MCObjectStreamer::FragStorage`.

FragList::Tail cannot be reused when switching sections or subsections,
as it is not associated with the fragment space tracked by `FragSpace`.
Instead, allocate a new fragment, which becomes less expensive after #150574.

Data can only be appended to the tail fragment of a subsection, not to
fragments in the middle. Post-assembler-layout adjustments (such as
.llvm_addrsig and .llvm.call-graph-profile) have been updated to use the
variable-size part instead.

Pull Request: https://github.com/llvm/llvm-project/pull/150846
2025-07-28 22:12:15 -07:00
Fangrui Song
2bebbe166b MCFragment: Migrate away from appendContents
The fixed-size content of the MCFragment object will be stored as
trailing data (#150846). Any post-assembler-layout adjustments must
target the variable-size tail.
2025-07-28 20:35:35 -07:00
Fangrui Song
f3bcaeac94 Optimize MCObjectStreamer::emitInstToData 2025-07-27 09:31:38 -07:00
Fangrui Song
b22e22ebfa MC: Allocate initial fragment and define section symbol in changeSection
Reland #150574 with a MCStreamer::changeSection change:
In Mach-O, DWARF sections use Begin as a temporary label, requiring a label
definition, unlike section symbols in other file formats.
(Tested by dec978036ef1037753e7de5b78c978e71c49217b)

---

13a79bbfe583e1d8cc85d241b580907260065eb8 (2017) introduced fragment
creation in MCContext for createELFSectionImpl, which was inappropriate.
Fragments should only be created when using MCSteramer, not during
`MCContext::get*Section` calls.
`initMachOMCObjectFileInfo` defines multiple sections, some of which may
not be used by the code generator. This caused symbol names matching
these sections to be incorrectly marked as undefined (see
https://reviews.llvm.org/D55173).

The fragment code was later replicated in other file formats, such as
WebAssembly (see https://reviews.llvm.org/D46561), XCOFF, and GOFF.

This patch fixes the problem by moving initial fragment allocation from
MCContext::createSection to MCStreamer::changeSection.
While MCContext still creates a section symbol, the symbol is not
attached to the initial fragment. In addition,

* Move `emitLabel`/`setFragment` from `switchSection*` and
  overridden changeSection to `MCObjectStreamer::changeSection` for
  consistency.
* De-virtualize `switchSectionNoPrint`.
* test/CodeGen/XCore/section-name.ll now passes. XCore doesn't support
  MCObjectStreamer. I don't think the MCAsmStreamer output behavior
  change matters.

Pull Request: https://github.com/llvm/llvm-project/pull/150574
2025-07-26 00:05:10 -07:00
dyung
cb37916a25
Revert "MC: Allocate initial fragment and define section symbol in changeSection" (#150736)
Reverts llvm/llvm-project#150574

This is causing a test failure on AArch64 MacOS bots:
https://lab.llvm.org/buildbot/#/builders/190/builds/24187
2025-07-25 20:21:59 -07:00
Fangrui Song
1955a01d63
MC: Allocate initial fragment and define section symbol in changeSection
13a79bbfe583e1d8cc85d241b580907260065eb8 (2017) introduced fragment
creation in MCContext for createELFSectionImpl, which was inappropriate.
Fragments should only be created when using MCSteramer, not during
`MCContext::get*Section` calls.
`initMachOMCObjectFileInfo` defines multiple sections, some of which may
not be used by the code generator. This caused symbol names matching
these sections to be incorrectly marked as undefined (see
https://reviews.llvm.org/D55173).

The fragment code was later replicated in other file formats, such as
WebAssembly (see https://reviews.llvm.org/D46561), XCOFF, and GOFF.

This patch fixes the problem by moving initial fragment allocation from
MCContext::createSection to MCStreamer::changeSection.
While MCContext still creates a section symbol, the symbol is not
attached to the initial fragment.
In addition, move `emitLabel`/`setFragment` from `switchSection*` and
overridden changeSection to `MCObjectStreamer::changeSection` for
consistency.

* test/CodeGen/XCore/section-name.ll now passes. XCore doesn't support
  MCObjectStreamer. I don't think the MCAsmStreamer output behavior
  change matters.

Pull Request: https://github.com/llvm/llvm-project/pull/150574
2025-07-24 23:37:48 -07:00
Sterling-Augustine
29e8599aa9
Reapply "Support SFrame command-line and .cfi_section syntax (#150316) (#150509)
This reverts commit ad36e4284d66c3609ef8675ef02ff1844bc1951d, fixing a
single uninitialized bit (which cannot be detected with Address
Sanitizer).

This PR adds support for the llvm-mc command-line flag "--gsframe" and
adds ".sframe" to the legal values passed ".cfi_section". It plumbs the
option through the cfi handling code a fair amount. Code to support
actual section generation follows in a future PR.

These options match the gnu-assembler's support syntax for sframes, on
both the command line and in assembly files.

First in a series of changes that will allow llvm-mc to produce sframe
.cfi sections. For more information about sframes, see
https://sourceware.org/binutils/docs-2.44/sframe-spec.html

and the llvm-RFC here:
https://discourse.llvm.org/t/rfc-adding-sframe-support-to-llvm/86900
2025-07-24 14:09:41 -07:00
Kazu Hirata
3e53d4d386
[llvm] Remove unused includes (NFC) (#150265)
These are identified by misc-include-cleaner.  I've filtered out those
that break builds.  Also, I'm staying away from llvm-config.h,
config.h, and Compiler.h, which likely cause platform- or
compiler-specific build failures.
2025-07-23 15:18:46 -07:00
Sterling-Augustine
ad36e4284d
Revert "Support SFrame command-line and .cfi_section syntax (#149935)" (#150316)
This reverts commit f9d0bd02d966e5c28aca9a6ceadd5ffec6aa9f78.
2025-07-23 14:32:14 -07:00
Sterling-Augustine
f9d0bd02d9
Support SFrame command-line and .cfi_section syntax (#149935)
This PR adds support for the llvm-mc command-line flag "--gsframe" and
adds ".sframe" to the legal values passed ".cfi_section". It plumbs the
option through the cfi handling code a fair amount. Code to support
actual section generation follows in a future PR.

These options match the gnu-assembler's support syntax for sframes, on
both the command line and in assembly files.

First in a series of changes that will allow llvm-mc to produce sframe
.cfi sections. For more information about sframes, see
https://sourceware.org/binutils/docs-2.44/sframe-spec.html

and the llvm-RFC here:
https://discourse.llvm.org/t/rfc-adding-sframe-support-to-llvm/86900
2025-07-23 10:43:38 -07:00
Fangrui Song
63b9cbd6e4 MCStreamer: Add helpers and eliminate direct MCFragment operations
To facilitate optimizing the MCFragment internals, we don't want users
to access MCFragment directly.
2025-07-20 21:57:57 -07:00
Fangrui Song
6ebc42322c MCStreamer: Move fragment-related functions to MCObjectStreamer
They are specific to MCObjectStreamer and unneeded by MCAsmStreamer.

Add isObj() so that MCTargetAsmParser can determine whether the streamer
is MCObjectStreamer and conditionally call newFragment.
2025-07-20 21:15:34 -07:00
Fangrui Song
bdbc0987ca MCObjectStreamer: Remove changeSectionImpl 2025-07-20 16:28:16 -07:00
Fangrui Song
ba6b705620 MC: Replace getOrCreateDataFragment with getCurrentFragment
Add an assert to ensure `CurFrag` is either null or an `FT_Data` fragment.

Follow-up to 39c8cfb70d203439e3296dfdfe3d41f1cb2ec551.
Extracted from #149721
2025-07-20 11:02:26 -07:00
Fangrui Song
fd6d6a7c8d
MC: Refactor FT_Align fragments when linker relaxation is enabled
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 VarContentEnd (content is ignored).
* Move setLinkerRelaxable from MCObjectStreamer::emitCodeAlignment to the backends.

Pull Request: https://github.com/llvm/llvm-project/pull/149465
2025-07-20 00:55:54 -07:00
Fangrui Song
2ba5e0ad17
MC: Encode FT_Align in fragment's variable-size tail
Follow-up to #148544

Pull Request: https://github.com/llvm/llvm-project/pull/149030
2025-07-20 00:46:51 -07:00
Fangrui Song
5ee34ff1e5 MC: Optimize emitInstruction and simplify fragment-in-BSS check
Move the FT_Relaxable-in-BSS check from frequently-called
MCObjectStreamer::emitInstruction to MCAssembler::writeSectionData,
along with existing checks for other fragment types. For the uncommon
diagnostics, losing the location information is acceptable.
2025-07-20 00:09:24 -07:00
Fangrui Song
39c8cfb70d MC: Optimize getOrCreateDataFragment
... by eagerly allocating an empty fragment when adding a fragment
with a variable-size tail.

X86AsmBackend, The JCC erratum mitigation and x86-pad-for-align set a
flag for FT_Relaxable, which needs to be moved to emitInstructionBegin.
```
  if (CF->getKind() == MCFragment::FT_Relaxable)
    CF->setAllowAutoPadding(canPadInst(Inst, OS));
```

Follow-up to #148544
2025-07-19 16:55:30 -07:00
Fangrui Song
ecf0cbda18 MCFragment: Refactor LEB
* Deduplicate creation of SLEB128/ULEB128 with makeLEB.
* Call newFragment to prepare for removing getOrCreateDataFragment.
2025-07-19 09:59:27 -07:00
Fangrui Song
73e4b589ba
MC: Simplify fragment reuse determination
First, avoid checking MCSubtargetInfo by reducing unnecessary overhead
introduced in https://reviews.llvm.org/D44928 . That change passed STI
to both FT_Data and FT_Relaxable fragments, but STI is only necessary
for FT_Relaxable.

The use of STI in FT_Data was added for:

* Bundle alignment mode, which has been removed (#148781).
* ARM, which inappropriately uses STI in `ARMAsmBackend::applyFixup` due
  to tech debt, unlike other targets. All tests passed even without the
  `copySTI` change.

To ensure safety, `copySTI` now starts a new fragment to prevent mixed
STI values.

Second, avoid checking LinkerRelaxable by eagerly starting a new
fragment when a FT_Data/FT_Align fragment is marked linker-relaxable.
There is currently an extra empty FT_Data if an alignment immediately
follows a linker-relaxable fragment, which will be improved in the
future when FT_Align information is moved to the variable-tail.

Pull Request: https://github.com/llvm/llvm-project/pull/149471
2025-07-18 09:51:21 -07:00
Fangrui Song
3cb0c7f45b MC: Rework .reloc directive and fix the offset when it evaluates to a constant
* Fix `.reloc constant` to mean section_symbol+constant instead of
  .+constant . The initial .reloc support from MIPS incorrectly
  interpreted the offset.
* Delay the evaluation of the offset expression after
  MCAssembler::layout, deleting a lot of code working with MCFragment.
* Delete many FIXME from https://reviews.llvm.org/D79625
* Some lld/ELF/Arch/LoongArch.cpp relaxation tests rely on .reloc .,
  R_LARCH_ALIGN generating ALIGN relocations at specific location.
  Sort the relocations.
2025-07-17 00:36:11 -07:00
Fangrui Song
dc3a4c0fcf
MC: Restructure MCFragment as a fixed part and a variable tail
Refactor the fragment representation of `push rax; jmp foo; nop; jmp foo`,
previously encoded as
`MCDataFragment(nop); MCRelaxableFragment(jmp foo); MCDataFragment(nop); MCRelaxableFragment(jmp foo)`,

to

```
MCFragment(fixed: push rax, variable: jmp foo)
MCFragment(fixed: nop, variable: jmp foo)
```

Changes:

* Eliminate MCEncodedFragment, moving content and fixup storage to MCFragment.
* The new MCFragment contains a fixed-size content (similar to previous
  MCDataFragment) and an optional variable-size tail.
* The variable-size tail supports FT_Relaxable, FT_LEB, FT_Dwarf, and
  FT_DwarfFrame, with plans to extend to other fragment types.
  dyn_cast/isa should be avoided for the converted fragment subclasses.
* In `setVarFixups`, source fixup offsets are relative to the variable part's start.
  Stored fixup (in `FixupStorage`) offsets are relative to the fixed part's start.
  A lot of code does `getFragmentOffset(Frag) + Fixup.getOffset()`,
  expecting the fixup offset to be relative to the fixed part's start.
* HexagonAsmBackend::fixupNeedsRelaxationAdvanced needs to know the
  associated instruction for a fixup. We have to add a `const MCFragment &` parameter.
* In MCObjectStreamer, extend `absoluteSymbolDiff` to apply to
  FT_Relaxable as otherwise there would be many more FT_DwarfFrame
  fragments in -g compilations.

https://llvm-compile-time-tracker.com/compare.php?from=28e1473e8e523150914e8c7ea50b44fb0d2a8d65&to=778d68ad1d48e7f111ea853dd249912c601bee89&stat=instructions:u

```
stage2-O0-g instructins:u geomeon (-0.07%)
stage1-ReleaseLTO-g (link only) max-rss geomean (-0.39%)
```

```
% /t/clang-old -g -c sqlite3.i -w -mllvm -debug-only=mc-dump &| awk '/^[0-9]+/{s[$2]++;tot++} END{print "Total",tot; n=asorti(s, si); for(i=1;i<=n;i++) print si[i],s[si[i]]}'
Total 59675
Align 2215
Data 29700
Dwarf 12044
DwarfCallFrame 4216
Fill 92
LEB 12
Relaxable 11396
% /t/clang-new -g -c sqlite3.i -w -mllvm -debug-only=mc-dump &| awk '/^[0-9]+/{s[$2]++;tot++} END{print "Total",tot; n=asorti(s, si); for(i=1;i<=n;i++) print si[i],s[si[i]]}'
Total 32287
Align 2215
Data 2312
Dwarf 12044
DwarfCallFrame 4216
Fill 92
LEB 12
Relaxable 11396
```

Pull Request: https://github.com/llvm/llvm-project/pull/148544
2025-07-15 21:56:55 -07:00
Fangrui Song
28e1473e8e
MC: Remove bundle alignment mode
The being-removed PNaCl has a Software Fault Isolation mechanism, which
requires that certain instructions and groups of instructions do not
cross a bundle boundary. When `.bundle_align_mode` is in effect, each
instruction is placed in its own fragment, allowing flexible NOP
padding.

This feature has significantly complicated our refactoring of MCStreamer
and MCFragment, leading to considerable effort spent untangling
it (including flushPendingLabels (75006466296ed4b0f845cbbec4bf77c21de43b40),
MCAssembler iteration improvement, and recent MCFragment refactoring).

* Make MCObjectStreamer::emitInstToData non-virtual and delete
  MCELFStreamer::emitInstTodata
* Delete MCELFStreamer::emitValueImpl and emitValueToAlignment

Minor instructions:u decrease for both -O0 -g and -O3 builds
https://llvm-compile-time-tracker.com/compare.php?from=c06d3a7b728293cbc53ff91239d6cd87c0982ffb&to=9b078c7f228bc5b6cdbfe839f751c9407f8aec3e&stat=instructions:u

Pull Request: https://github.com/llvm/llvm-project/pull/148781
2025-07-15 19:36:19 -07:00
Fangrui Song
1fbfa333f6 MCAlignFragment: Rename fields and use uint8_t FillLen
* Rename the vague `Value` to `Fill`.
* FillLen is at most 8. Making the field smaller to facilitate encoding
  MCAlignFragment as a MCFragment union member.
* Replace an unreachable report_fatal_error with assert.
2025-07-13 14:07:10 -07:00
Fangrui Song
267b136359 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.
2025-07-12 20:29:34 -07:00
Fangrui Song
0393084adc
MC: Store MCRelaxableFragment MCInst out-of-line
Follow-up to #146307

Moved MCInst storage to MCSection, enabling trivial ~MCRelaxableFragment
and eliminating the need for a fragment walk in ~MCSection.

Updated MCRelaxableFragment::getInst to construct an MCInst on demand.
Modified MCAssembler::relaxInstruction's mayNeedRelaxation to accept
opcode and operands instead of an MCInst, avoiding redundant MCInst
creation. Note that MCObjectStreamer::emitInstructionImpl calls
mayNeedRelaxation before determining the target fragment for the MCInst.

Unfortunately, we also have to encode `MCInst::Flags` to support
the EVEX prefix, e.g. `{evex} xorw $foo, %ax`

There is a small decrease in max-rss (stage1-ReleaseLTO-g (link only))
with negligible instructions:u change.
https://llvm-compile-time-tracker.com/compare.php?from=0b533f2d9f0551aaffb13dcac8e0fd0a952185b5&to=f26b57f33bc7ccae749a57dfc841de7ce2acc2ef&stat=max-rss&linkStats=on

Next: Enable MCFragment to store fixed-size data (was MCDataFragment's job)
and optional Opcode/Operands data (was MCRelaxableFragment's job),
and delete MCDataFragment/MCRelaxableFragment.
This will allow re-encoding of Data+Relax+Data+Relax sequences as
Frag+Frag. The saving should outweigh the downside of larger
MCFragment.

Pull Request: https://github.com/llvm/llvm-project/pull/147229
2025-07-08 09:44:27 -07:00
Fangrui Song
20b3ab5683 MCFixup: Remove unused Loc argument
MCFixup::Loc has been removed in favor of MCExpr::Loc through
`const MCExpr *Value` (commit 777391a2164b89d2030ca013562151ca3c3676d1).
2025-07-04 12:23:04 -07:00
Fangrui Song
9beb467d92
MC: Store fragment content and fixups out-of-line
Moved `Contents` and `Fixups` SmallVector storage to MCSection, enabling
trivial destructors for most fragment subclasses and eliminating the need
for MCFragment::destroy in ~MCSection.

For appending content to the current section, use
getContentsForAppending. During assembler relaxation, prefer
setContents/setFixups, which may involve copying and reduce the benefits
of https://reviews.llvm.org/D145791.

Moving only Contents out-of-line caused a slight performance regression
(Alexis Engelke's 2024 prototype). By also moving Fragments out-of-line,
fragment destructors become trivial, resulting in
neglgible instructions:u increase for "stage2-O0-g" and [large max-rss decrease](https://llvm-compile-time-tracker.com/compare.php?from=84e82746c3ff63ec23a8b85e9efd4f7fccf92590&to=555a28c0b2f8250a9cf86fd267a04b0460283e15&stat=max-rss&linkStats=on)
for the "stage1-ReleaseLTO-g (link only)" benchmark.
(
An older version using fewer inline functions: https://llvm-compile-time-tracker.com/compare.php?from=bb982e733cfcda7e4cfb0583544f68af65211ed1&to=f12d55f97c47717d438951ecddecf8ebd28c296b&linkStats=on
)

Now using plain SmallVector in MCSection for storage, with potential for
future allocator optimizations, such as allocating `Contents` as the
trailing object of MCDataFragment. (GNU Assembler uses gnulib's obstack
for fragment management.)

Co-authored-by: Alexis Engelke <engelke@in.tum.de>

Pull Request: https://github.com/llvm/llvm-project/pull/146307
2025-07-01 00:21:12 -07:00
Fangrui Song
2de51345fb MCFragment: Add addFixup to replace getFixups().push_back()
to not expose SmallVector to the callers. We will make fixup storage out
of line.
2025-06-29 16:26:00 -07:00
Fangrui Song
cd075a4013 MCObjectStreamer: Deduplicate emitInstToData 2025-06-29 16:12:10 -07:00
Fangrui Song
af2bf2e544 MC: Remove unneeded MCSymbolRefExpr::VariantKind calls 2025-06-27 09:47:53 -07:00
Fangrui Song
290fc1ea11
MC,AsmPrinter: Report redefinition error instead of crashing in more cases
* Fix the crash for `.equiv b, undef; b:` (.equiv equates a symbol to an expression and reports an error if the symbol was already defined).
* Remove redundant isVariable check from emitFunctionEntryLabel

Pull Request: https://github.com/llvm/llvm-project/pull/145460
2025-06-23 23:00:03 -07:00
Fangrui Song
d4c7d0be1f MCObjectStreamer: Replace getAssemblerPtr with getAssembler
In general getAssemblerPtr should only be called by MCParse.
Revert some changes from https://reviews.llvm.org/D45164?id=143128
2025-06-13 19:12:12 -07:00
Fangrui Song
ab0931b638 MC: Set MCSection::LinkerRelaxable for linker-relaxable MCAlignFragment
Commit bb03cdcb441fd68da9d1ebb7d5f39f73667cd39c caused a Linux kernel
regression https://github.com/ClangBuiltLinux/linux/issues/2091

When a section contains linker-relaxable MCAlignmentFragment but no
linker-relaxable instructions, the RISCVAsmBackend::isPCRelFixupResolved
code path should be taken as well. The #76552 condition in the fragment
walk code will make the fixup unresolvable, leading to a relocation.
2025-05-28 22:46:37 -07:00
Fangrui Song
95756e67c2 MC: Rework .weakref
Use a variable symbol without any specifier instead of VK_WEAKREF.
Add code in ELFObjectWriter::executePostLayoutBinding to check
whether the target should be made an undefined weak symbol.

This change fixes several issues:

* Unreferenced `.weakref alias, target` no longer creates an undefined `target`.
* When `alias` is already defined, report an error instead of crashing.

.weakref is specific to ELF. llvm-ml has reused the VK_WEAKREF name for
a different concept. wasm incorrectly copied the ELF implementation.
Remove it.
2025-05-25 21:09:55 -07:00
Fangrui Song
64390b9181 MC: Remove MCAssembler argument from addFileName 2025-05-25 12:52:35 -07:00
Fangrui Song
7d71a35658 MCFixup: Remove FK_PCRel_ from getKindForSize
Remove FK_PCRel_* kinds from the generic fixup list, as they are not
generic like FK_Data_*. In getRelocType, FK_PCRel_* can be replaced with
FK_Data_* by leveraging the IsPCRel argument. Their inclusion in the
generic kind list caused confusion for PowerPC, RISCV, and VE targets.

The X86/M68k uses can be implemented as target-specific fixups.
2025-05-24 12:02:18 -07:00
Jeremy Morse
26d9cb17a6
[MC][DebugInfo] Emit linetable entries with known offsets immediately (#134677)
DWARF linetable entries are usually emitted as a sequence of
MCDwarfLineAddrFragment fragments containing the line-number difference
and an MCExpr describing the instruction-range the linetable entry
covers. These then get relaxed during assembly emission.

However, a large number of these instruction-range expressions are
ranges within a fixed MCDataFragment, i.e. a range over fixed-size
instructions that are not subject to relaxation at a later stage. Thus,
we can compute the address-delta immediately, and not spend time and
memory describing that computation so it can be deferred.
2025-05-20 21:26:56 +01:00
Fangrui Song
39662922e1 MCObjectStreamer: Refine absoluteSymbolDiff condition
The function is called to test the fast path - when Lo/Hi are within the
same fragment. This is unsafe - Lo/Hi at the begin and end of a
relaxable fragment should not evaluate to a constant. However, we don't
have tests that exercise the code path.

Nevertheless, make the check safer and remove the now unnecessary
isRISCV check (from https://reviews.llvm.org/D103539).
2025-04-12 19:02:07 -07:00
Fangrui Song
b1cd3cb3f4 [MC] Replace getSymA()->getSymbol() with getAddSym. NFC
We will replace the MCSymbolRefExpr member in MCValue with MCSymbol.
This change reduces dependence on MCSymbolRefExpr.
2025-04-05 13:34:24 -07:00
Fangrui Song
086af83688 [MC] Replace getSymA()->getSymbol() with getAddSym. NFC
We will replace the MCSymbolRefExpr member in MCValue with MCSymbol.
This change reduces dependence on MCSymbolRefExpr.
2025-04-05 13:23:14 -07:00