summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/RegAllocFast.cpp
AgeCommit message (Collapse)Author
2025-05-22[LLVM][CodeGen] Add convenience accessors for MachineFunctionProperties ↵users/pcc/spr/main.elf-add-branch-to-branch-optimizationRahul Joshi
(#140002) Add per-property has<Prop>/set<Prop>/reset<Prop> functions to MachineFunctionProperties.
2025-04-18[CodeGen] Construct SmallVector with iterator ranges (NFC) (#136258)Kazu Hirata
2025-03-24[RegAllocFast] Ensure live-in vregs get reloaded after INLINEASM_BR spillsAntonio Frighetto
We have already ensured in 9cec2b246e719533723562950e56c292fe5dd5ad that `INLINEASM_BR` output operands get spilled onto the stack, both in the fallthrough path and in the indirect targets. Since reloads of live-ins values into physical registers contextually happen after all MIR instructions (and ops) have been visited, make sure such loads are placed at the start of the block, but after prologues or `INLINEASM_BR` spills, as otherwise this may cause stale values to be read from the stack. Fixes: #74483, #110251.
2025-03-02[RegAllocFast] Use Register and MCRegister. NFCCraig Topper
2025-02-26RegAllocFast: Fix 8634635d689c5a7adfb19cde4a313d7c02e95194 to not trip ↵Benjamin Kramer
assertions
2025-02-26RegAllocFast: Stop reading uninitalized memoryBenjamin Kramer
Found by msan. ==8138==WARNING: MemorySanitizer: use-of-uninitialized-value #0 0x559016395beb in allocVirtRegUndef llvm/lib/CodeGen/RegAllocFast.cpp:1010:6
2025-02-26RegAllocFast: Fix verifier errors after assigning to reserved registers ↵Matt Arsenault
(#128281)
2025-02-20Revert "[CodeGen] Remove static member function ↵Christopher Di Bella
Register::isPhysicalRegister. NFC" This reverts commit 5fadb3d680909ab30b37eb559f80046b5a17045e.
2025-02-20[CodeGen] Remove static member function Register::isPhysicalRegister. NFCCraig Topper
Prefer the nonstatic member by converting unsigned to Register instead.
2025-01-30[CodeGen] Use non-static Register::virtRegIndex() instead of static ↵Craig Topper
Register::virtReg2Index. NFC (#125031) These are the the ones where we already had a Register object being used. Some places are still using unsigned which I did not convert.
2025-01-21[CodeGen] Use MCRegister instead of MCPhysReg in RegisterMaskPair. NFC (#123688)Craig Topper
Update some other places to avoid implicit conversions this introduces, but I probably missed some.
2025-01-21[RegAllocFast] Don't convert MCRegUnit to MCRegister. NFC (#123705)Craig Topper
2024-12-17Fix-forward 'RegAllocFast: Avoid using temporary DiagnosticInfo #120184' ↵Thurston Dang
(#120268) There was a buildbot breakage (https://lab.llvm.org/buildbot/#/builders/24/builds/3329/steps/11/logs/stdio): /home/b/sanitizer-aarch64-linux-bootstrap-asan/build/llvm-project/llvm/test/CodeGen/AMDGPU/ran-out-of-registers-error-all-regs-reserved.ll:9:10: error: CHECK: expected string not found in input ; CHECK: error: <unknown>:0:0: no registers from class available to allocate in function 'no_registers_from_class_available_to_allocate' 2: ==75198==ERROR: AddressSanitizer: stack-use-after-scope on address 0xfa23f9f1c270 at pc 0xb2660dda9340 bp 0xfffffe8ab340 sp 0xfffffe8ab338 caused by https://github.com/llvm/llvm-project/pull/120184, which made a partial fix but also renabled the tests. This patch attempts to fix forward by applying the same fix to the error message highlighted in the buildbot.
2024-12-17RegAllocFast: Avoid using temporary DiagnosticInfo (#120184)Matt Arsenault
This reverts commit 1297933f35b4948b4d281259627a72094c407a75.
2024-12-16RegAlloc: Fix failure on undef use when all registers are reserved (#119647)Matt Arsenault
Greedy and fast would hit different assertions on undef uses if all registers in a class were reserved.
2024-12-16RegAlloc: Do not fatal error if there are no registers in the alloc order ↵Matt Arsenault
(#119640) Try to use DiagnosticInfo if every register in the class is reserved by forcing assignment to a reserved register. Also reduces the number of redundant errors emitted, particularly with fast. This is still broken in the case of undef uses. There are additional complications in greedy and fast, so leave it for a separate fix.
2024-12-16RegAlloc: Use DiagnosticInfo to report register allocation failures (#119492)Matt Arsenault
Improve the non-fatal cases to use DiagnosticInfo, which will now provide a location. The allocators attempt to report different errors if it happens to see inline assembly is involved (this detection is quite unreliable) using srcloc instead of dbgloc. For now, leave this behavior unchanged. I think reporting the full location and context function would be more useful.
2024-12-11Reapply "DiagnosticInfo: Clean up usage of DiagnosticInfoInlineAsm" ↵Matt Arsenault
(#119575) (#119634) This reverts commit 40986feda8b1437ed475b144d5b9a208b008782a. Reapply with fix to prevent temporary Twine from going out of scope.
2024-12-11Revert "DiagnosticInfo: Clean up usage of DiagnosticInfoInlineAsm" (#119575)Vitaly Buka
Reverts llvm/llvm-project#119485 Breaks builders, details in llvm/llvm-project#119485
2024-12-11DiagnosticInfo: Clean up usage of DiagnosticInfoInlineAsm (#119485)Matt Arsenault
Currently LLVMContext::emitError emits any error as an "inline asm" error which does not make any sense. InlineAsm appears to be special, in that it uses a "LocCookie" from srcloc metadata, which looks like a parallel mechanism to ordinary source line locations. This meant that other types of failures had degraded source information reported when available. Introduce some new generic error types, and only use inline asm in the appropriate contexts. The DiagnosticInfo types are still a bit of a mess, and I'm not sure why DiagnosticInfoWithLocationBase exists instead of just having an optional DiagnosticLocation in the base class. DK_Generic is for any error that derives from an IR level instruction, and thus can pull debug locations directly from it. DK_GenericWithLoc is functionally the generic codegen error, since it does not depend on the IR and instead can construct a DiagnosticLocation from the MI debug location.
2024-08-28Revert "[CodeGen] Use MachineInstr::{all_uses,all_defs} (NFC)" (#106451)Vitaly Buka
Reverts llvm/llvm-project#106404 Breaks: https://lab.llvm.org/buildbot/#/builders/169/builds/2590 https://lab.llvm.org/buildbot/#/builders/164/builds/2454
2024-08-28[CodeGen] Use MachineInstr::{all_uses,all_defs} (NFC) (#106404)Kazu Hirata
2024-08-26[CodeGen] Use MachineInstr::all_defs (NFC) (#106017)Kazu Hirata
2024-08-09[NFC] Use references to avoid copying (#99863)Pratyay Pande
Modifying `auto` to `auto&` to avoid unnecessary copying
2024-07-22[CodeGen] change prototype of regalloc filter function (#93525)Christudasan Devadasan
[CodeGen] Change the prototype of regalloc filter function Change the prototype of the filter function so that we can filter not just by RegClass. We need to implement more complicated filter based upon some other info associated with each register. Patch provided by: Gang Chen (gangc@amd.com)
2024-06-22[CodeGen][NewPM] Extract MachineFunctionProperties modification part to an ↵paperchalice
RAII class (#94854) Modify MachineFunctionProperties in PassModel makes `PassT P; P.run(...);` not work properly. This is a necessary compromise.
2024-06-21[RegAllocFast] Replace UsedInInstr with vector (#96323)Alexis Engelke
A SparseSet adds an avoidable layer of indirection and possibly looping control flow. Avoid this overhead by using a vector to store UsedInInstrs and PhysRegUses. To avoid clearing the vector after every instruction, use a monotonically increasing counter. The two maps are now merged and the lowest bit indicates whether the use is relevant for the livethrough handling code only.
2024-06-21[RegAlloc] Don't call always-true ShouldAllocClass (#96296)Alexis Engelke
Previously, there was at least one virtual function call for every allocated register. The only users of this feature are AMDGPU and RISC-V (RVV), other targets don't use this. To easily identify these cases, change the default functor to nullptr and don't call it for every allocated register.
2024-06-21[RegAllocFast] Handle single-vdef instrs faster (#96284)Alexis Engelke
On x86, many instructions have tied operands, so allocateInstruction uses the more complex assignment strategy, which computes the assignment order of virtual defs first. This involves iterating over all register classes (or register aliases for physical defs) to compute the possible number of defs per register class. However, this information is only used for sorting virtual defs and therefore not required when there's only one virtual def -- which is a very common case. As iterating over all register classes/aliases is not cheap, do this only when there's more than one virtual def.
2024-06-21[RegAllocFast] Use unsigned for operand indicesAlexis Engelke
MachineInstr operand indices can be up 24 bits currently. Use unsigned as consistent data type for operand indices instead of uint16_t.
2024-06-07[NewPM][CodeGen] Port `regallocfast` to new pass manager (#94426)paperchalice
This pull request port `regallocfast` to new pass manager. It exposes the parameter `filter` to handle different register classes for AMDGPU. IIUC AMDGPU need to allocate different register classes separately so it need implement its own `--<reg-class>-regalloc`. Now users can use e.g. `-passe=regallocfast<filter=sgpr>` to allocate specific register class. The command line option `--regalloc-npm` is still in work progress, plan to reuse the syntax of passes, e.g. use `--regalloc-npm=regallocfast<filter=sgpr>,greedy<filter=vgpr>` to replace `--sgpr-regalloc` and `--vgpr-regalloc`.
2024-03-11[CodeGen] Do not pass MF into MachineRegisterInfo methods. NFC. (#84770)Jay Foad
MachineRegisterInfo already knows the MF so there is no need to pass it in as an argument.
2023-12-25[RegAllocFast] Lazily initialize InstrPosIndexes for each MBB (#76275)HaohaiWen
Most basic block do not need to query dominates. Defer initialization of InstrPosIndexes to first query for each MBB.
2023-12-22[RegAllocFast] Avoid duplicate hash lookup (NFC)Nikita Popov
2023-12-22[RegAllocFast] Refactor dominates algorithm for large basic block (#72250)HaohaiWen
The original brute force dominates algorithm is O(n) complexity so it is very slow for very large machine basic block which is very common with O0. This patch added InstrPosIndexes to assign index for each instruction and use it to determine dominance. The complexity is now O(1).
2023-12-12[RegAllocFast] NFC cleanups (#74860)Nick Desaulniers
- use more range for - avoid capturing lambda - prefer Register type to unsigned - remove braces around single statement if
2023-11-14[NFC][CodeGen] clang-format RegAllocFast.cpp (#72199)HaohaiWen
2023-08-12[llvm] Remove SmallSet from MachineInstr.hElliot Goodrich
`MachineInstr.h` is a commonly included file and this includes `llvm/ADT/SmallSet.h` for one function `getUsedDebugRegs()`, which is used only in one place. According to `ClangBuildAnalyzer` (run solely on building LLVM, no other projects) the second most expensive template to instantiate is the `SmallSet::insert` method used in the `inline` implementation in `getUsedDebugRegs()`: ``` **** Templates that took longest to instantiate: 554239 ms: std::unordered_map<int, int> (2826 times, avg 196 ms) 521187 ms: llvm::SmallSet<llvm::Register, 4>::insert (930 times, avg 560 ms) ... ``` By removing this method and putting its implementation in the one call site we greatly reduce the template instantiation time and reduce the number of includes. When copying the implementation, I removed a check on `MO.getReg()` as this is checked within `MO.isVirtual()`. Differential Revision: https://reviews.llvm.org/D157720
2023-07-25[RegAlloc] Fix assertion failure caused by inline assemblyQi Hu
When inline assembly code requests more registers than available, the MachineInstr::emitError function in the RegAllocFast pass emits an error but doesn't stop the pass, and then the compiler crashes later with an assertion failure. This commit, mimicking the RegAllocGreedy pass, assigns a random physical register, and therefore avoids the crash after producing the diagnostic. This problem has been observed for both rustc and clang, while it doesn't occur in gcc.
2023-06-16[MC] Use regunits instead of MCRegUnitIterator. NFC.Jay Foad
Differential Revision: https://reviews.llvm.org/D153122
2023-06-16[MC] Add MCRegisterInfo::regunits for iteration over register unitsSergei Barannikov
Reviewed By: foad Differential Revision: https://reviews.llvm.org/D152098
2023-06-01[CodeGen] Make use of MachineInstr::all_defs and all_uses. NFCI.Jay Foad
Differential Revision: https://reviews.llvm.org/D151424
2023-05-16FastRegAlloc: Fix implicit operands not rewrittenGaëtan Bossu
This patch fixes a potential crash due to RegAllocFast not rewriting virtual registers. This essentially happens because of a call to MachineInstr::addRegisterKilled() in the process of allocating a "killed" vreg. The former can eventually delete implicit operands without RegAllocFast noticing, leading to some operands being "skipped" and not rewritten to use physical registers. Note that I noticed this crash when working on a solution for tying a register with one/multiple of its sub-registers within an instruction. (See problem description here: https://discourse.llvm.org/t/pass-to-tie-an-output-operand-to-a-subregister-of-an-input-operand/67184). Aside from this fix, I believe there could be further improvements to the RegAllocFast when it comes to instructions with multiple uses of a same virtual register. You can see it in the added test where the implicit uses have been re-written in a somewhat surprising way because of phase ordering. Ultimately, when allocating vregs for an instruction, I believe we should iterate on the vregs it uses (and then process all the operands that use this vregs), instead of directly iterating on operands and somewhat assuming each operand uses a different vreg. This would in the end be quite close to what greedy+virtregrewriter does. If that makes sense, I would probably spin off another patch (after I get more familiar with RegAllocFast). Differential Revision: https://reviews.llvm.org/D145169
2023-04-27[RegAllocFast] Use uint16_t SparseT for LiveRegMapAlexis Engelke
For functions with very large numbers of live variables, lookups into LiveRegMap previously detoriated to linear searches. This slightly increases memory usage, but that is barely measurable. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D149330
2023-04-17Fix uninitialized pointer members in CodeGenAkshay Khadse
This change initializes the members TSI, LI, DT, PSI, and ORE pointer feilds of the SelectOptimize class to nullptr. Reviewed By: LuoYuanke Differential Revision: https://reviews.llvm.org/D148303
2023-04-05RegAllocFast: Fix dropping subreg indexes on unassigned subreg defsMatt Arsenault
This was assuming all register operands were assigned to physical registers. This should ignore the operands which weren't assigned in this run. Fixes #61134
2023-03-01[RegAllocFast] insert additional spills along indirect edges of INLINEASM_BRNick Desaulniers
When generating spills (stores) for values produced by INLINEASM_BR instructions, make sure to insert one spill per indirect target. Otherwise the reload generated may load from a stack slot that has not yet been stored to (resulting in a load of an uninitialized stack slot). Link: https://github.com/llvm/llvm-project/issues/53562 Fixes: https://github.com/llvm/llvm-project/issues/60855 Reviewed By: MatzeB Differential Revision: https://reviews.llvm.org/D144907
2023-01-13[CodeGen] Remove uses of Register::isPhysicalRegister/isVirtualRegister. NFCCraig Topper
Use isPhysical/isVirtual methods. Reviewed By: foad Differential Revision: https://reviews.llvm.org/D141715
2023-01-05[RegAllocFast] Handle new debug values for spillsJosh Stone
These new debug values get inserted after the place where the spill happens, which means they won't be reached by the reverse traversal of basic block instructions. This would crash or fail assertions if they contained any virtual registers to be replaced. We can manually handle the new debug values right away to resolve this. Fixes https://github.com/llvm/llvm-project/issues/59172 Reviewed By: StephenTozer Differential Revision: https://reviews.llvm.org/D139590
2022-12-17[CodeGen] Additional Register argument to ↵Christudasan Devadasan
storeRegToStackSlot/loadRegFromStackSlot With D134950, targets get notified when a virtual register is created and/or cloned. Targets can do the needful with the delegate callback. AMDGPU propagates the virtual register flags maintained in the target file itself. They are useful to identify a certain type of machine operands while inserting spill stores and reloads. Since RegAllocFast spills the physical register itself, there is no way its virtual register can be mapped back to retrieve the flags. It can be solved by passing the virtual register as an additional argument. This argument has no use when the spill interfaces are called during the greedy allocator or even the PrologEpilogInserter and can pass a null register in such cases. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D138656