aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/MCSection.cpp
AgeCommit message (Collapse)AuthorFilesLines
2025-08-12[RISCV] Track Linker Relaxable through Assembly Relaxation (#152602)Sam Elliott1-0/+2
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-07MC: Refine ALIGN relocation conditionsFangrui Song1-1/+1
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-02MCFragment: Store the number of variable-size tail fixups as uint8_tFangrui Song1-2/+4
Decrease sizeof(MCFragment) by 8 on 64-bit machines.
2025-07-26MCSection: Remove SectionVariantFangrui Song1-3/+2
The object file format specific derived classes are used in context like MCStreamer and MCObjectTargetWriter where the type is statically known. We don't use isa/dyn_cast.
2025-07-26MC: Allocate initial fragment and define section symbol in changeSectionFangrui Song1-2/+1
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-25Revert "MC: Allocate initial fragment and define section symbol in ↵dyung1-1/+2
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-24MC: Allocate initial fragment and define section symbol in changeSectionFangrui Song1-2/+1
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-20MCFragment: Remove setContents/setFixupsFangrui Song1-20/+0
Make the fixed-size part of MCFragment append-only to support allocating content as trailing data. Update CodeView callers to use setVarContents instead of setContents. Remove unused setFixups.
2025-07-20MC: Fix fragment-in-BSS checkFangrui Song1-5/+3
* Handle non-zero fill values for `.fill` and `.org` directives. * Restore the fragment type check (5ee34ff1e5cc952116f0da943ddaeb1a71db2940 removed a reachable `llvm_unreachable`) to detect unintended API usage. Remove virtual functions `getVirtualSectionKind` (added in https://reviews.llvm.org/D78138) as they are unnecessary in diagnostics. The a.out object file format has the BSS concept, which has been inherited by COFF, XCOFF, Mach-O, and ELF object file formats. Pull Request: https://github.com/llvm/llvm-project/pull/149721
2025-07-20MC: Rename isVirtualSection to isBssSectionFangrui Song1-1/+1
The term BSS (Block Started by Symbol) is a standard, widely recognized term, available in the a.out object file format and adopted by formats like COFF, XCOFF, Mach-O (called S_ZEROFILL while `__bss` is also used), and ELF. To avoid introducing unfamiliar terms, we should use isBSSSection instead of isVirtualSection.
2025-07-15MC: Restructure MCFragment as a fixed part and a variable tailFangrui Song1-4/+30
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-15MC: Remove bundle alignment modeFangrui Song1-22/+2
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-14[llvm] Remove unused includes (NFC) (#148768)Kazu Hirata1-1/+0
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-08MC: Store MCRelaxableFragment MCInst out-of-lineFangrui Song1-12/+0
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-01MC: Store fragment content and fixups out-of-lineFangrui Song1-1/+41
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-06-30MC: Merge MCFragment.h into MCSection.hFangrui Song1-1/+0
... 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
2025-06-29MC: Enhance mc-dump outputFangrui Song1-1/+13
* 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.
2025-06-28MC: Make mc-dump output compactFangrui Song1-8/+2
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.
2025-06-02[MC] Relax MCFillFragment and compute fragment offsets eagerlyFangrui Song1-2/+2
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.
2025-06-01MCSection: Replace DummyFragment with the Subsections[0] head fragmentFangrui Song1-1/+0
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
2025-05-23RISCV: Remove shouldForceRelocation and unneeded relocationsFangrui Song1-1/+1
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
2024-11-15[MC] Remove unused includes (NFC) (#116317)Kazu Hirata1-1/+0
Identified with misc-include-cleaner.
2024-07-31Revert "[MC] Compute fragment offsets eagerly"Nikita Popov1-2/+2
This reverts commit be5a845e4c29aadb513ae6e5e2879dccf37efdbb. This causes large code size regressions, which were not present in the initial version of this change.
2024-07-30[MC] Compute fragment offsets eagerlyFangrui Song1-2/+2
This builds on top of commit 9d0754ada5dbbc0c009bcc2f7824488419cc5530 ("[MC] Relax fragments eagerly") and relaxes fragments eagerly to eliminate MCSection::HasLayout and `getFragmentOffset` overhead. The approach is slightly different from 1a47f3f3db66589c11f8ddacfeaecc03fb80c510 and has less performance benefit. The new layout algorithm also addresses the following problems: * Size change of MCFillFragment/MCOrgFragment did not influence the fixed-point iteration, which could be problematic for contrived cases. * The `invalid number of bytes` error was reported too early. Since `.zero A-B` might have temporary negative values in the first few iterations. * X86AsmBackend::finishLayout performed only one iteration, which might not converge. In addition, the removed `#ifndef NDEBUG` code (disabled by default) in X86AsmBackend::finishLayout was problematic, as !NDEBUG and NDEBUG builds evaluated fragment offsets at different times before this patch. * The computed layout for relax-recompute-align.s is optimal now. Builds with many text sections (e.g. full LTO) shall observe a decrease in compile time while the new algorithm could be slightly slower for some -O0 -g projects. Aligned bundling from the deprecated PNaCl placed constraints how we can perform iteration.
2024-07-30Revert "[MC] Compute fragment offsets eagerly"Fangrui Song1-2/+2
This reverts commit 1a47f3f3db66589c11f8ddacfeaecc03fb80c510. Fix #100283 This commit is actually a trigger of other preexisting problems: * Size change of fill fragments does not influence the fixed-point iteration. * The `invalid number of bytes` error is reported too early. Since `.zero A-B` might have temporary negative values in the first few iterations. However, the problems appeared at least "benign" (did not affect the Linux kernel builds) before this commit.
2024-07-21[MC] Compute fragment offsets eagerlyFangrui Song1-2/+2
This builds on top of commit 9d0754ada5dbbc0c009bcc2f7824488419cc5530 ("[MC] Relax fragments eagerly") and relaxes fragments eagerly to eliminate MCSection::HasLayout and `getFragmentOffset` overhead. Note: The removed `#ifndef NDEBUG` code (disabled by default) in X86AsmBackend::finishLayout was problematic, as (a) !NDEBUG and NDEBUG builds evaluated fragment offsets at different times before this patch (b) one iteration might not be sufficient to converge. There might be some edge cases that it did not handle. Anyhow, this patch probably makes it work for more cases.
2024-06-27[MC] Ensure subsections have a MCDataFragmentFangrui Song1-11/+0
Similar to 21fac2d1d060b0f9b11a746718e58d4cd1ee97e5 for sections. This makes it feasible to cache the current fragment in MCStreamer.
2024-06-27[MC] Make MCSection::isVirtualSection non-virtual (#96920)Alexis Engelke1-3/+3
This method is called once per encoded instruction, but never changes throughout the lifetime of a section. Store this information as a bit flag in the MCSection instead.
2024-06-22[MC] Remove remnant code related to pending labelsFangrui Song1-3/+0
2024-06-22[MC] Remove pending labelsFangrui Song1-27/+0
This commit removes the complexity introduced by pending labels in https://reviews.llvm.org/D5915 by using a simpler approach. D5915 aimed to ensure padding placement before `.Ltmp0` for the following code, but at the cost of expensive per-instruction `flushPendingLabels`. ``` // similar to llvm/test/MC/X86/AlignedBundling/labeloffset.s .bundle_lock align_to_end calll .L0$pb .bundle_unlock .L0$pb: popl %eax .Ltmp0: //// padding should be inserted before this label instead of after addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp0-.L0$pb), %eax ``` (D5915 was adjusted by https://reviews.llvm.org/D8072 and https://reviews.llvm.org/D71368) This patch achieves the same goal by setting the offset of the empty MCDataFragment (`Prev`) in `layoutBundle`. This eliminates the need for pending labels and simplifies the code. llvm/test/MC/MachO/pending-labels.s (D71368): relocation symbols are changed, but the result is still supported by linkers.
2024-06-21[MC] Remove the Parent parameter from MCFragment ctor callers. NFCFangrui Song1-2/+3
2024-06-20[MC] Remove SectionKind from MCSection (#96067)aengelke1-3/+3
There are only three actual uses of the section kind in MCSection: isText(), XCOFF, and WebAssembly. Store isText() in the MCSection, and store other info in the actual section variants where required. ELF and COFF flags also encode all relevant information, so for these two section variants, remove the SectionKind parameter entirely. This allows to remove the string switch (which is unnecessary and inaccurate) from createELFSectionImpl. This was introduced in [D133456](https://reviews.llvm.org/D133456), but apparently, it was never hit for non-writable sections anyway and the resulting kind was never used.
2024-06-14[MC] Aligned bundling: remove special handling for RelaxAllFangrui Song1-4/+3
When both aligned bundling and RelaxAll are enabled, bundle padding is directly written into fragments (https://reviews.llvm.org/D8072). (The original motivation was memory usage, which has been achieved from different angles with recent assembler improvement). The code presents challenges with the work to replace fragment representation (e.g. #94950 #95077). This patch removes the special handling. RelaxAll still works but the behavior seems slightly different as revealed by 2 changed tests. However, most `-mc-relax-all` tests are unchanged. RelaxAll used to be the default for clang -O0. This mode has significant code size drawbacks and newer Clang doesn't use it (#90013). --- flushPendingLabels: The FOffset parameter can be removed: pending labels will be assigned to the incoming fragment at offset 0. Pull Request: https://github.com/llvm/llvm-project/pull/95188
2024-06-13[MC] flushPendingLabels: revert setAtom changeFangrui Song1-3/+0
The setAtom call introduced by e17bc023f4e5b79f08bfc7f624f8ff0f0cf17ce4 was due to my misunderstanding of flushPendingLabels (see https://discourse.llvm.org/t/mc-removing-aligned-bundling-support/79518). When evaluating `.quad x-y`, MCExpr.cpp:AttemptToFoldSymbolOffsetDifference gives different results at parse time and layout time because the `if (FA->getAtom() == FB.getAtom())` condition in isSymbolRefDifferenceFullyResolvedImpl only works when `setAtom` with a non-null pointer has been called. Calling setAtom in flushPendingLabels does not help anything.
2024-06-11[MC] Replace fragment ilist with singly-linked listsFangrui Song1-37/+25
Fragments are allocated with `operator new` and stored in an ilist with Prev/Next/Parent pointers. A more efficient representation would be an array of fragments without the overhead of Prev/Next pointers. As the first step, replace ilist with singly-linked lists. * `getPrevNode` uses have been eliminated by previous changes. * The last use of the `Prev` pointer remains: for each subsection, there is an insertion point and the current insertion point is stored at `CurInsertionPoint`. * `HexagonAsmBackend::finishLayout` needs a backward iterator. Save all fragments within `Frags`. Hexagon programs are usually small, and the performance does not matter that much. To eliminate `Prev`, change the subsection representation to singly-linked lists for subsections and a pointer to the active singly-linked list. The fragments from all subsections will be chained together at layout time. Since fragment lists are disconnected before layout time, we can remove `MCFragment::SubsectionNumber` (https://reviews.llvm.org/D69411). The current implementation of `AttemptToFoldSymbolOffsetDifference` requires future improvement for robustness. Pull Request: https://github.com/llvm/llvm-project/pull/95077
2024-06-10[MC] Remove getFragmentList uses. NFCFangrui Song1-3/+6
2024-06-09[MC] Relax fragments eagerlyFangrui Song1-2/+2
Lazy relaxation caused hash table lookups (`getFragmentOffset`) and complex use/compute interdependencies. Some expressions involding forward declared symbols (e.g. `subsection-if.s`) cannot be computed. Recursion detection requires complex `IsBeingLaidOut` (https://reviews.llvm.org/D79570). D76114's `invalidateFragmentsFrom` makes lazy relaxation even less useful. Switch to eager relaxation to greatly simplify code and resolve these issues. This change also removes a `getPrevNode` use, which makes it more feasible to replace the fragment representation, which might yield a large peak RSS win. Minor downsides: The number of section relaxations may increase (offset by avoiding the hash table lookup). For relax-recompute-align.s, the computed layout is not optimal.
2024-06-06[MC] MCSection::dump: print section nameFangrui Song1-1/+1
2023-06-18[MC] flushPendingLabels: set Atom for new fragment after D71368Fangrui Song1-2/+4
Fixes: c26c5e47ab9ca60835f191c90fa751e9a7dd0f3d (essentially a no-op) The newly created MCDataFragment should inherit Atom (see MCMachOStreamer::finishImpl). To the best of my knowledge, this change cannot be tested at present, but this is important to ensure MCExpr.cpp:AttemptToFoldSymbolOffsetDifference gives the same result in case we evaluate the expression again with a MCAsmLayout. In the following case, ``` .section __DATA,xray_instr_map lxray_sleds_start1: .space 16 Lxray_sleds_end1: .section __DATA,xray_fn_idx .quad (Lxray_sleds_end1-lxray_sleds_start1)>>4 // can be folded without a MCAsmLayout ``` When we have a MCAsmLayout, without this change, evaluating (Lxray_sleds_end1-lxray_sleds_start1)>>4 again will fail due to `FA->getAtom() == nullptr && FB.getAtom() != nullptr` in MachObjectWriter::isSymbolRefDifferenceFullyResolvedImpl, called by AttemptToFoldSymbolOffsetDifference.
2023-06-18[MC] flushPendingLabels: set Atom for new fragment after D71368Fangrui Song1-0/+2
The newly created MCDataFragment should inherit Atom (see MCMachOStreamer::finishImpl). I cannot think of a case to test the behavior, but this is one step towards folding the Mach-O label difference below and making Mach-O more similar to ELF. ``` .section __DATA,xray_instr_map lxray_sleds_start1: .space 16 Lxray_sleds_end1: .section __DATA,xray_fn_idx .quad (Lxray_sleds_end1-lxray_sleds_start1)>>4 // error: expected relocatable expression // Mach-O ```
2023-05-05[MC] Simplify flushPendingLabels. NFCFangrui Song1-3/+0
2022-02-09Cleanup LLVMMC headersserge-sans-paille1-1/+1
There's a few relevant forward declarations in there that may require downstream adding explicit includes: llvm/MC/MCContext.h no longer includes llvm/BinaryFormat/ELF.h, llvm/MC/MCSubtargetInfo.h, llvm/MC/MCTargetOptions.h llvm/MC/MCObjectStreamer.h no longer include llvm/MC/MCAssembler.h llvm/MC/MCAssembler.h no longer includes llvm/MC/MCFixup.h, llvm/MC/MCFragment.h Counting preprocessed lines required to rebuild llvm-project on my setup: before: 1052436830 after: 1049293745 Which is significant and backs up the change in addition to the usual benefits of decreasing coupling between headers and compilation units. Discourse thread: https://discourse.llvm.org/t/include-what-you-use-include-cleanup Differential Revision: https://reviews.llvm.org/D119244
2021-01-29[llvm] Use llvm::lower_bound and llvm::upper_bound (NFC)Kazu Hirata1-4/+2
2020-12-21[MC] Split MCContext::createTempSymbol, default AlwaysAddSuffix to true, and ↵Fangrui Song1-1/+1
add comments CanBeUnnamed is rarely false. Splitting to a createNamedTempSymbol makes the intention clearer and matches the direction of reverted r240130 (to drop the unneeded parameters). No behavior change.
2020-09-09[MC] Resolve the difference of symbols in consecutive MCDataFragementsJian Cai1-0/+1
Try to resolve the difference of two symbols in consecutive MCDataFragments. This is important for an idiom like "foo:instr; .if . - foo; instr; .endif" (https://bugs.llvm.org/show_bug.cgi?id=43795). Reviewed By: nickdesaulniers Differential Revision: https://reviews.llvm.org/D69411
2020-04-15[MC][COFF][ELF] Reject instructions in ↵Fangrui Song1-1/+3
IMAGE_SCN_CNT_UNINITIALIZED_DATA/SHT_NOBITS sections For `.bss; nop`, MC inappropriately calls abort() (via report_fatal_error()) with a message `cannot have fixups in virtual section!` It is a bug to crash for invalid user input. Fix it by erroring out early in EmitInstToData(). Similarly, emitIntValue() in a virtual section (SHT_NOBITS in ELF) can crash with the mssage `non-zero initializer found in section '.bss'` (see D4199) It'd be nice to report the location but so many directives can call emitIntValue() and it is difficult to track every location. Note, COFF does not crash because MCAssembler::writeSectionData() is not called for an IMAGE_SCN_CNT_UNINITIALIZED_DATA section. Note, GNU as' arm64 backend reports ``Error: attempt to store non-zero value in section `.bss'`` for a non-zero .inst but fails to do so for other instructions. We simply reject all instructions, even if the encoding is all zeros. The Mach-O counterpart is D48517 (see `test/MC/MachO/zerofill-text.s`) Reviewed By: rnk, skan Differential Revision: https://reviews.llvm.org/D78138
2020-04-15[MC] Replace MCSection*::getName() with MCSection::getName(). NFCFangrui Song1-2/+4
I plan to use MCSection::getName() in D78138. Having the function in the base class is also convenient for debugging. Reviewed By: rnk Differential Revision: https://reviews.llvm.org/D78251
2020-03-21Revert rGd5d8569df14e95e2c53d167bd1b37995bcbec565 "Fix static analysis ↵Simon Pilgrim1-0/+2
warnings about classes with virtual methods not having virtual destructors" This reverts commit d5d8569df14e95e2c53d167bd1b37995bcbec565.
2020-03-21Fix static analysis warnings about classes with virtual methods not having ↵Simon Pilgrim1-2/+0
virtual destructors
2020-01-05[MC][ARM] Delete MCSection::HasData and move SHF_ARM_PURECODE logic to ↵Fangrui Song1-2/+1
ARMELFObjectWriter::addTargetSectionFlags This simplifies the generic interface and also makes SHF_ARM_PURECODE more robust (fixes a TODO). Inspecting MCDataFragment contents covers more cases than MCObjectStreamer::EmitBytes.