summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/CFIFixup.cpp
AgeCommit message (Collapse)Author
2025-05-24[CodeGen] Remove unused includes (NFC) (#141320)Kazu Hirata
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-02-11[CFIFixup] Fixup CFI for split functions with synchronous uwtables (#125299)Daniel Hoekwater
- **Precommit tests for synchronous uwtable CFI fixup** - **[CFIFixup] Fixup CFI for split functions with synchronous uwtables** Commit https://github.com/llvm/llvm-project/commit/6e54fccede402c9ed0e8038aa258a99c5a2773e5 disables CFI fixup for functions with synchronous tables, breaking CFI for split functions. Instead, we can disable *block-level* CFI fixup for functions with synchronous tables. Unwind tables can be: - N/A (not present) - Asynchronous - Synchronous Functions without unwind tables don't need CFI fixup (since they don't care about CFI). Functions with asynchronous unwind tables must be accurate for each basic block, so full CFI fixup is necessary. Functions with synchronous unwind tables only need to be accurate for each function (specifically, the portion of a function in a given section). Disabling CFI fixup entirely for functions with synchronous uwtables may break CFI for a function split between two sections. The portion in the first section may have valid CFI, while the portion in the second section is missing a call frame. Ex: ``` (.text.hot) Foo (BB1): <Call frame information> ... BB2: ... (.text.split) BB3: ... BB4: <epilogue> ``` Even if `Foo` has a synchronous unwind table, we still need to insert call frame information into `BB3` so that unwinding the call stack from `BB3` or `BB4` works properly.
2025-01-31[CFIFixup] Add a default constructor to BlockFlags (NFC) (#125296)Kazu Hirata
This patch adds a default constructor to BlockFlags to initialize its members to false, placing initializers close to the member declarations. Note that once C++20 is available in our codebase, we can replace the explicit default constructor with: bool Reachable : 1 = true; :
2025-01-31Reland "[CFIFixup] Factor logic into helpers and use range-based loops (NFC) ↵Daniel Hoekwater
#125137" This patch was breaking tests due to inconsistent use of SmallVector. After consolidating SmallVector usages, everything should work as intended.
2025-01-31Revert "[CFIFixup] Factor logic into helpers and use range-based loops (NFC) ↵Daniel Hoekwater
(#125137)" This reverts commit f14f19738916572322c310e84196134545c15c49, which breaks a number of build bots: - https://lab.llvm.org/buildbot/#/builders/163/builds/12726 - https://lab.llvm.org/buildbot/#/builders/144/builds/17106 - https://lab.llvm.org/buildbot/#/builders/123/builds/12855 - https://lab.llvm.org/buildbot/#/builders/133/builds/10660 - https://lab.llvm.org/buildbot/#/builders/88/builds/7482 - https://lab.llvm.org/buildbot/#/builders/180/builds/12313 - https://lab.llvm.org/buildbot/#/builders/160/builds/12316
2025-01-31[CFIFixup] Factor logic into helpers and use range-based loops (NFC) (#125137)Daniel Hoekwater
`runOnMachineFunction` is getting long (>100 lines), and the logic for computing block info and performing block fixup can be abstracted away. Reduce nesting in the main block fixup loop and name conditions to reflect their purpose. Replace manual usage of iterators with a range-based for loop. Source: - https://llvm.org/docs/CodingStandards.html#use-early-exits-and-continue-to-simplify-code - https://llvm.org/docs/CodingStandards.html#use-range-based-for-loops-wherever-possible - https://llvm.org/docs/CodingStandards.html#don-t-evaluate-end-every-time-through-a-loop
2024-11-20[CFIFixup] Add frame info to the first block of each section (#113626)Daniel Hoekwater
Now that `-fbasic-block-sections=list` is enabled for Arm, functions may be split aross multiple sections, and CFI information must be handled independently for each section. On x86, this is handled in `llvm/lib/CodeGen/CFIInstrInserter.cpp`. However, this pass does not run on Arm, so we must add logic for it to `llvm/lib/CodeGen/CFIFixup.cpp`.
2024-11-12[CodeGen] Remove unused includes (NFC) (#115996)Kazu Hirata
Identified with misc-include-cleaner.
2024-10-24Reland "CFIFixup] Factor CFI remember/restore insertion into a helper (NFC)" ↵Daniel Hoekwater
(#113387) The original patch (ac1a01f) dereferenced an end iterator, breaking some tests (e.g. https://lab.llvm.org/buildbot/#/builders/17/builds/3116). This updated patch only accesses the iterator when it's valid.
2024-10-22Revert "Reland [CFIFixup] Factor CFI remember/restore insertion into a ↵Daniel Hoekwater
helper (NFC)" (#113340) Reverts llvm/llvm-project#113328 This change breaks a number of builds (e.g https://lab.llvm.org/buildbot/#/builders/25/builds/3504), for some reason. Reverting to do some troubleshooting.
2024-10-22Reland [CFIFixup] Factor CFI remember/restore insertion into a helper (NFC) ↵Daniel Hoekwater
(#113328) The previous submission looked like it triggered build failure https://lab.llvm.org/buildbot/#/builders/17/builds/3116, but this appears to be a spurious failure due to a flaky test.
2024-10-04Revert "[CFIFixup] Factor CFI remember/restore insertion into a helper ↵Daniel Hoekwater
(NFC)" (#111168) Reverts llvm/llvm-project#111066 This seems to be breaking some builds: - https://lab.llvm.org/buildbot/#/builders/51/builds/4732 - https://lab.llvm.org/buildbot/#/builders/41/builds/2534 - https://lab.llvm.org/buildbot/#/builders/73/builds/6601
2024-10-04[CFIFixup] Factor CFI remember/restore insertion into a helper (NFC) (#111066)Daniel Hoekwater
Inserting a remember/restore pair is a very clean abstraction, so we can split the logic out into a helper function. Additionally, cleaning this up will make it easier to add logic for handling functions that are split across multiple sections.
2023-11-14[CFIFixup] Allow function prologues to span more than one basic block (#68984)Momchil Velikov
The CFIFixup pass assumes a function prologue is contained in a single basic block. This assumption is broken with upcoming support for stack probing (`-fstack-clash-protection`) in AArch64 - the emitted probing sequence in a prologue may contain loops, i.e. more than one basic block. The generated CFG is not arbitrary though: * CFI instructions are outside of any loops * for any two CFI instructions of the function prologue one dominates and is post-dominated by the other Thus, for the prologue CFI instructions, if one is executed then all are executed, there is a total order of executions, and the last instruction in that order can be considered the end of the prologoue for the purpose of inserting the initial `.cfi_remember_state` directive. That last instruction is found by finding the first block in the post-order traversal which contains prologue CFI instructions.
2022-04-11[CodeGen] Async unwind - add a pass to fix CFI informationMomchil Velikov
This pass inserts the necessary CFI instructions to compensate for the inconsistency of the call-frame information caused by linear (non-CGA aware) nature of the unwind tables. Unlike the `CFIInstrInserer` pass, this one almost always emits only `.cfi_remember_state`/`.cfi_restore_state`, which results in smaller unwind tables and also transparently handles custom unwind info extensions like CFA offset adjustement and save locations of SVE registers. This pass takes advantage of the constraints taht LLVM imposes on the placement of save/restore points (cf. `ShrinkWrap.cpp`): * there is a single basic block, containing the function prologue * possibly multiple epilogue blocks, where each epilogue block is complete and self-contained, i.e. CSR restore instructions (and the corresponding CFI instructions are not split across two or more blocks. * prologue and epilogue blocks are outside of any loops Thus, during execution, at the beginning and at the end of each basic block the function can be in one of two states: - "has a call frame", if the function has executed the prologue, or has not executed any epilogue - "does not have a call frame", if the function has not executed the prologue, or has executed an epilogue These properties can be computed for each basic block by a single RPO traversal. From the point of view of the unwind tables, the "has/does not have call frame" state at beginning of each block is determined by the state at the end of the previous block, in layout order. Where these states differ, we insert compensating CFI instructions, which come in two flavours: - CFI instructions, which reset the unwind table state to the initial one. This is done by a target specific hook and is expected to be trivial to implement, for example it could be: ``` .cfi_def_cfa <sp>, 0 .cfi_same_value <rN> .cfi_same_value <rN-1> ... ``` where `<rN>` are the callee-saved registers. - CFI instructions, which reset the unwind table state to the one created by the function prologue. These are the sequence: ``` .cfi_restore_state .cfi_remember_state ``` In this case we also insert a `.cfi_remember_state` after the last CFI instruction in the function prologue. Reviewed By: MaskRay, danielkiss, chill Differential Revision: https://reviews.llvm.org/D114545
2022-04-05Revert "[CodeGen] Async unwind - add a pass to fix CFI information"Muhammad Omair Javaid
This reverts commit 980c3e6dd223a8e628367144b8180117950bb364. This commit had failing tests with clang crashing across various AArch64/Linux buildots. https://lab.llvm.org/buildbot/#/builders/179/builds/3346 Differential Revision: https://reviews.llvm.org/D114545
2022-04-04[CodeGen] Async unwind - add a pass to fix CFI informationMomchil Velikov
This pass inserts the necessary CFI instructions to compensate for the inconsistency of the call-frame information caused by linear (non-CFG aware) nature of the unwind tables. Unlike the `CFIInstrInserer` pass, this one almost always emits only `.cfi_remember_state`/`.cfi_restore_state`, which results in smaller unwind tables and also transparently handles custom unwind info extensions like CFA offset adjustement and save locations of SVE registers. This pass takes advantage of the constraints that LLVM imposes on the placement of save/restore points (cf. `ShrinkWrap.cpp`): * there is a single basic block, containing the function prologue * possibly multiple epilogue blocks, where each epilogue block is complete and self-contained, i.e. CSR restore instructions (and the corresponding CFI instructions are not split across two or more blocks. * prologue and epilogue blocks are outside of any loops Thus, during execution, at the beginning and at the end of each basic block the function can be in one of two states: - "has a call frame", if the function has executed the prologue, or has not executed any epilogue - "does not have a call frame", if the function has not executed the prologue, or has executed an epilogue These properties can be computed for each basic block by a single RPO traversal. In order to accommodate backends which do not generate unwind info in epilogues we compute an additional property "strong no call frame on entry" which is set for the entry point of the function and for every block reachable from the entry along a path that does not execute the prologue. If this property holds, it takes precedence over the "has a call frame" property. From the point of view of the unwind tables, the "has/does not have call frame" state at beginning of each block is determined by the state at the end of the previous block, in layout order. Where these states differ, we insert compensating CFI instructions, which come in two flavours: - CFI instructions, which reset the unwind table state to the initial one. This is done by a target specific hook and is expected to be trivial to implement, for example it could be: ``` .cfi_def_cfa <sp>, 0 .cfi_same_value <rN> .cfi_same_value <rN-1> ... ``` where `<rN>` are the callee-saved registers. - CFI instructions, which reset the unwind table state to the one created by the function prologue. These are the sequence: ``` .cfi_restore_state .cfi_remember_state ``` In this case we also insert a `.cfi_remember_state` after the last CFI instruction in the function prologue. Reviewed By: MaskRay, danielkiss, chill Differential Revision: https://reviews.llvm.org/D114545