When there is no VarFixup, VarContentStart is zero.
`slice(F.VarContentStart - Contents.size(), F.getSize())`
might lead to "runtime error: addition of unsigned offset to" in ubsan builds after #148544
* 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.
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
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
* 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.
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
Utilize the generalized MCAsmBackend::evaluateFixup hook. This reduces
overhead for other targets (e.g., x86).
Now MCAsmBackend::getFixupKindInfo is only used by MCAsmStreamer
-show-encoding in the generic code.
Generalize evaluateTargetFixup to be called by all targets,
making FKF_IsTarget unneeded.
Next: Update targets that use FKF_IsAlignedDownTo32Bits to define
`evaluateFixup` and remove FKF_IsAlignedDownTo32Bits from the generic
code.
PC-relative fixups compute their values as
`sym_a - current_location + offset` (S - P + A).
Now that targets have set PCRel at fixup creation time, we can remove
some overhead from MCAssembler::evaluateFixup.
Remove the redundant MCFixup::Loc member and instead use MCExpr::Loc to
determine the location for fixups. Previously, many target MCCodeEmitter would
use the beginning of an instruction for fixup locations, which often
resulted in inaccurate column information.
```
// RISCVMCCodeEmitter::getImmOpValue
Fixups.push_back(MCFixup::create(0, Expr, FixupKind, MI.getLoc()));
// X86MCCodeEmitter::emitImmediate
Fixups.push_back(MCFixup::create(static_cast<uint32_t>(CB.size() - StartByte), Expr, FixupKind, Loc));
```
While MCExpr::Loc generally provides more meaningful location data,
tests should avoid over-relying on it. For instance, MCBinaryExpr's
location refers to its operator, and for operands with sigils (like
`$foo`), the location often omits the sigils.
https://llvm-compile-time-tracker.com/compare.php?from=8740ff822d462844506134bb7c425e1778518b95&to=831a11f75d22d64982b13dba132d656ac8567612&stat=instructions%3Au
I've also considered removing MCExpr::Loc (revert
https://reviews.llvm.org/D28861), but we'd lose too much information.
It's also difficult to carry location information to improve location
tracking in target MCCodeEmitter.
This change utilizes previous MCExpr::Loc improvement like
7e3e2e1b8c6ff21e68782a56164139cca334fcf3
7b517cf743f112f980cf6a4d6e6190c2a5b3e451
Follow-up to #141333. Relocation generation called both addReloc and
applyFixup, with the default addReloc invoking shouldForceRelocation,
resulting in three virtual calls. This approach was also inflexible, as
targets needing additional data required extending
`shouldForceRelocation` (see #73721, resolved by #141311).
This change integrates relocation handling into applyFixup, eliminating
two virtual calls. The prior default addReloc is renamed to
maybeAddReloc. Targets overriding addReloc now call their customized
addReloc implementation.
... due to their close relationship. MCSection's inline functions (e.g.
iterator) access MCFragment, and we want MCFragment's inline functions
to access MCSection similarly (#146307).
Pull Request: https://github.com/llvm/llvm-project/pull/146315
* Make pre-layout to -debug-only=mc-dump-pre. This output is not useful
for most debugging needs.
* Print fragment-associated symbols. Make it easier to locate relevant
fragments.
* Print the LinkerRelaxable flag.
The "Symbol" stanza includes symbol names with all zero indexes. which
are not useful.
The "assembler backend - post-relaxation" part is not useful. Only
Hexagon (and X86 when x86-pad-for-align is set) might change the layout
between "post-relaxation" and "final-layout". From my experience
debugging the two passes requires more dumping code not served by the
output.
Remove unneeded details like "<" and ">". Reduce indentation.
Omit `this` address to simplify output comparison.
Add a -debug-only=mc-dump test.
While here, add fixup printing for MCRelaxableFragment.
This builds on top of commit 9d0754ada5dbbc0c009bcc2f7824488419cc5530
("[MC] Relax fragments eagerly") and relaxes fragments eagerly to
eliminate MCSection::HasLayout and `getFragmentOffset` overhead.
Relands 1a47f3f3db66589c11f8ddacfeaecc03fb80c510
Builds with many text sections (e.g. full LTO) shall observe a decrease
in compile time.
---
In addition, ensure `.fill` and `.space` directives with expressions are
re-evaluated during fragment relaxation, as their sizes may change.
Continue iteration to prevent stale, incorrect sizes.
This change has to be coupled with the fragment algorithm change
as otherwise the test test/MC/ELF/layout-interdependency.s would not
converge.
Fixes#123402 and resolves the root cause of #100283, building on error
postponing from commit 38b12d4a7c219b46d1cb52580cbacbdb931262f2.
For AArch64/label-arithmetic-diags-elf.s, the extra iteration
reports a .fill error early and suppresses the fixup/relocation errors.
Just split the tests.
The dummy fragment is primarily used by MCAsmStreamer::emitLabel to
track the defined state. We can replace it with an arbitrary fragment.
Remove MCDummyFragment introduced for https://github.com/llvm/llvm-project/issues/24860
Currently, the code path is likely only reachable with super edge-case scenario,
but will be more reachable with the upcoming parseAssignmentExpression improvement
to address a pile of hacks.
Remove the MCSubtargetInfo argument from applyFixup, introduced in
https://reviews.llvm.org/D45962 , as it's only required by ARM. Instead,
add const MCFragment & so that ARMAsmBackend can retrieve
MCSubtargetInfo via a static member function.
Additionally, remove the MCAssembler argument, which is also only
required by ARM.
Additionally, make applyReloc non-const. Its arguments now fully cover
addReloc's functionality.
After #141311 removed the MCSubtargetInfo argument from
shouldForceRelocation, addReloc does not need this argument, either.
In a rare scenario that the information is needed, the target should
check the MCFragment subclass and get it from
MCDataFragment/MCRelaxableFragment.
This reverts the code change in commit
e87f33d9ce785668223c3bcc4e06956985cccda1 (#73721) but keeps its test.
There have been many changes to lib/MC and AsmBackend.cpp files, so this
is not a pure revert.
#73721, a workaround to generate necessary relocations in mixed
non-relax/relax code,
is no longer necessary after #140692 fixed the root issue (whether two
locations are separated by a fragment with indeterminate size due to
linker relaxation).
Follow-up to #140494
`shouldForceRelocation` is conservative and produces redundant
relocations.
For example, RISCVAsmBackend::ForceRelocs (introduced to support mixed
relax/norelax code) leads to redundant relocations in the following
example adapted from #77436
```
.option norelax
j label
// For assembly input, RISCVAsmParser::ParseInstruction sets ForceRelocs (https://reviews.llvm.org/D46423).
// For direct object emission, RISCVELFStreamer sets ForceRelocs (#77436)
.option relax
call foo // linker-relaxable
.option norelax
j label // redundant relocation due to ForceRelocs
.option relax
label:
```
Root problem: The `isSymbolRefDifferenceFullyResolvedImpl` condition in
MCAssembler::evaluateFixup does not check whether two locations are
separated by a fragment whose size can be indeterminate due to linker
instruction (e.g. MCDataFragment with relaxation, or MCAlignFragment
due to indeterminate start offst).
This patch
* Updates the fragment walk code in
`attemptToFoldSymbolOffsetDifference` to treat MCRelaxableFragment
(for --riscv-asm-relax-branches) as fixed size after finishLayout.
* Adds a condition in `addReloc` to complement
`isSymbolRefDifferenceFullyResolvedImpl`.
* Removes the no longer needed `shouldForceRelocation`.
This fragment walk code path handles nicely handles
mixed relax/norelax case from
https://discourse.llvm.org/t/possible-problem-related-to-subtarget-usage/75283
and allows us to remove `MCSubtargetInfo` argument (#73721) as a follow-up.
This fragment walk code should be avoided in the absence of
linker-relaxable fragments within the current section.
Adjust two bolt/test/RISCV tests (#141310)
Pull Request: https://github.com/llvm/llvm-project/pull/140692
Introduce MCAsmBackend::addReloc to manage relocation appending.
The default implementation uses shouldForceRelocation to check
unresolved fixups and calls recordRelocation to append a relocation when
needed.
RISCV and LoongArch override addReloc to handle ADD/SUB relocations,
with potential support for RELAX relocations in the future.
AVR overrides addReloc to customize shouldForceRelocation behavior
(#121498).
applyFixup is moved into evaluateFixup.
The simm13 format OR instruction should use one single fixup kind, while
it currently uses a lot more, including %m44/%l44.
This change refactors R_SPARC_H44/R_SPARC_M44/R_SPARC_M44 handling to
remove fixup kinds and specifiers. We utilize the [0,
FirstLiteralRelocationKind) MCFixupKind range to encode raw relocation
types that may be resolved (see the MCAssembler.cpp change).
The `evaluateAsRelocatableImpl` implementation resembles
PPCMCExpr::evaluateAsRelocatableImpl.
For RELA targets, fixup kinds that force relocations (GOT, TLS, ALIGN,
RELAX, etc) can bypass `applyFixup` and be encoded as
`FirstRelocationKind+i`, as seen in LoongArch. This patch removes
redundant fixup kinds and adopts the `FirstRelocationKind+i` encoding.
The `llvm-mc -show-encoding` output no longer displays descriptive fixup
names, as this information is removed from
`RISCVAsmBackend::getFixupKindInfo`. While a backend hook could be added
to call `llvm::object::getELFRelocationTypeName`, it's unnecessary since
the relocation in `-filetype=obj` output is what truly matters.
Pull Request: https://github.com/llvm/llvm-project/pull/136088
Among fixupNeedsRelaxationAdvanced (introduced by
https://reviews.llvm.org/D8217) targets, only Hexagon needs the
`MCRelaxableFragment` parameter (commit
86f218e7ec5d941b7785eaebcb8f4cad76db8a64) to get the instruction packet
(MCInst with sub-instruction operands).
As fixupNeedsRelaxationAdvanced follows mayNeedRelaxation, we can store
the MCInst in mayNeedRelaxation and eliminate the MCRelaxableFragment
parameter.
Follow-up to 7c83b7ef1796210451b839f4c58f2815f4aedfe5 that eliminates
the MCRelaxableFragment parameter from fixupNeedsRelaxation.