summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/CalcSpillWeights.cpp
AgeCommit message (Collapse)Author
2025-09-26[RegAlloc] Account for use availability when applying rematerializable ↵Luke Lau
weight discount (#159180) This aims to fix the issue that caused https://reviews.llvm.org/D106408 to be reverted. CalcSpillWeights will reduce the weight of an interval by half if it's considered rematerializable, so it will be evicted before others. It does this by checking TII.isTriviallyReMaterializable. However rematerialization may still fail if any of the defining MI's uses aren't available at the locations it needs to be rematerialized. LiveRangeEdit::canRematerializeAt calls allUsesAvailableAt to check this but CalcSpillWeights doesn't, so the two diverge. This fixes it by also checking allUsesAvailableAt in CalcSpillWeights. In practice this has zero change AArch64/X86-64/RISC-V as measured on llvm-test-suite, but prevents weights from being perturbed in an upcoming patch which enables more rematerialization by re-attempting https://reviews.llvm.org/D106408
2025-09-24[TII] Split isTrivialReMaterializable into two versions [nfc] (#160377)Philip Reames
This change builds on https://github.com/llvm/llvm-project/pull/160319 which tries to clarify which *callers* (not backends) assume that the result is actually trivial. This change itself should be NFC. Essentially, I'm just renaming the existing isTrivialRematerializable to the non-trivial version and then adding a new trivial version (with the same name as the prior function) and simplifying a few callers which want that semantic. This change does *not* enable non-trivial remat any more broadly than was already done for our targets which were lying through the old APIs; that will come separately. The goal here is simply to make the code easier to follow in terms of what assumptions are being made where. --------- Co-authored-by: Luke Lau <luke_lau@icloud.com>
2025-04-14[RegAlloc] Sort CopyHint by IsCSR (#131046)Michael Maitland
`weightCalcHelper` is responsible for adding hints to MRI. Prior to this PR, we fell back on register ID as the last tie breaker for sorting hints. However, there is an opportunity to add an additional sorting characteristic: whether or not a register is a callee-saved-register. I thought of this idea because I saw that `AllocationOrder::create` calls `RegisterClassInfo::getOrder`, which returns a list of registers such that the registers which alias callee-saved-registers come last. From this, I conclude that the register allocator prefers an order such that callee-saved-registers are allocated after non-callee-saved-registers to avoid having to spill the CSR. This sorting characteristic occurs only as a tie breaker to the Weight calculation. This is a good idea since the weight calculation is pretty complex and I'm sure it is a pretty stable metric. I think its pretty reasonable to agree that whether a register is callee-saved or not is a better tie breaker than register ID. I think this is evident by the test diff, since the changes all seem to have no impact or improve the register allocation.
2025-03-13[RegAlloc] Scale the spill weight by target factor (#113675)Pengcheng Wang
Currently, the spill weight is only determined by isDef/isUse and block frequency. However, for registers with different register classes, the costs of spilling them are different. For example, for `LMUL>1` registers (in which, several physical registers compound a bigger logical register), the costs are larger than `LMUL=1` case (in which, there is only one physical register). To solve this problem, a new target hook `getSpillWeightScaleFactor` is added. Targets can override the default factor (which is `1.0`) according to the register class. For RISC-V, the factors are set to the `RegClassWeight` which is used to track register pressure. The values of `RegClassWeight` happen to be the number of register units. I believe all of the targets with compounded registers can benefit from this change, but only RISC-V is customized in this patch since it has widely been agreed to do so. The other targets need more performance data to go further. Partially fixes #113489.
2025-03-02[CalcSpillWeights] Use Register. NFCCraig Topper
2024-11-12[CodeGen] Remove unused includes (NFC) (#115996)Kazu Hirata
Identified with misc-include-cleaner.
2024-11-07[CalcSpillWeights] Simplify copy hint register collection. NFC. (#114236)Valery Pykhtin
CopyHints set has been collecting duplicates of a register with increasing weight and then deduplicated with HintedRegs set. Let's stop collecting duplicates at the first place.
2024-10-21[regalloc][basic] Change spill weight for optsize funcs (#112960)Ellis Hoag
Change the spill weight calculations for `optsize` functions to remove the block frequency multiplier. For those functions, we do not want to consider the runtime cost of spilling, only the codesize cost. I built a large app with the basic and greedy (default) register allocator enabled. | Regalloc Type | Uncompressed Size Delta | Compressed Size Delta | | - | - | - | | Basic | -303.8 KiB (-0.23%) | -232.0 KiB (-0.39%) | | Greedy | 159.1 KiB (0.12%) | 130.1 KiB (0.22%) | Since I only saw a size win with the basic register allocator, I decided to only change the behavior for that type.
2024-09-26[NFC] Reapply 3f37c517f, SmallDenseMap speedupsJeremy Morse
This time with 100% more building unit tests. Original commit message follows. [NFC] Switch a number of DenseMaps to SmallDenseMaps for speedup (#109417) If we use SmallDenseMaps instead of DenseMaps at these locations, we get a substantial speedup because there's less spurious malloc traffic. Discovered by instrumenting DenseMap with some accounting code, then selecting sites where we'll get the most bang for our buck.
2024-09-25Revert "[NFC] Switch a number of DenseMaps to SmallDenseMaps for speedup ↵Jeremy Morse
(#109417)" This reverts commit 3f37c517fbc40531571f8b9f951a8610b4789cd6. Lo and behold, I missed a unit test
2024-09-25[NFC] Switch a number of DenseMaps to SmallDenseMaps for speedup (#109417)Jeremy Morse
If we use SmallDenseMaps instead of DenseMaps at these locations, we get a substantial speedup because there's less spurious malloc traffic. Discovered by instrumenting DenseMap with some accounting code, then selecting sites where we'll get the most bang for our buck.
2024-07-26[CalcSpillWeights] Avoid x87 excess precision influencing weight resultDimitry Andric
Fixes #99396 The result of `VirtRegAuxInfo::weightCalcHelper` can be influenced by x87 excess precision, which can result in slightly different register choices when the compiler is hosted on x86_64 or i386. This leads to different object file output when cross-compiling to i386, or native. Similar to 7af3432e22b0, we need to add a `volatile` qualifier to the local `Weight` variable to force it onto the stack, and avoid the excess precision. Define `stack_float_t` in `MathExtras.h` for this purpose, and use it.
2024-04-24[CodeGen] Make the parameter TRI required in some functions. (#85968)Xu Zhang
Fixes #82659 There are some functions, such as `findRegisterDefOperandIdx` and `findRegisterDefOperand`, that have too many default parameters. As a result, we have encountered some issues due to the lack of TRI parameters, as shown in issue #82411. Following @RKSimon 's suggestion, this patch refactors 9 functions, including `{reads, kills, defines, modifies}Register`, `registerDefIsDead`, and `findRegister{UseOperandIdx, UseOperand, DefOperandIdx, DefOperand}`, adjusting the order of the TRI parameter and making it required. In addition, all the places that call these functions have also been updated correctly to ensure no additional impact. After this, the caller of these functions should explicitly know whether to pass the `TargetRegisterInfo` or just a `nullptr`.
2023-11-16Remove unused LoopInfo from InlineSpiller and SpillPlacement (NFC) (#71874)Matthias Braun
2023-11-03[CalcSpillWeights] don't mark live intervals with spillable inlineasm ops as ↵Nick Desaulniers
having infinite spill weight (#70747) This is necessary for RegAllocGreedy support for memory folding inline asm that uses "rm" constraints. Thanks to @qcolombet for the suggestion. Link: https://github.com/llvm/llvm-project/issues/20571
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-31Reapply "[CodeGen]Allow targets to use target specific COPY instructions for ↵Matt Arsenault
live range splitting" This reverts commit a496c8be6e638ae58bb45f13113dbe3a4b7b23fd. The workaround in c26dfc81e254c78dc23579cf3d1336f77249e1f6 should work around the underlying problem with SUBREG_TO_REG.
2023-07-26Revert "[CodeGen]Allow targets to use target specific COPY instructions for ↵Vitaly Buka
live range splitting" And dependent commits. Details in D150388. This reverts commit 825b7f0ca5f2211ec3c93139f98d1e24048c225c. This reverts commit 7a98f084c4d121244ef7286bc6503b6a181d446e. This reverts commit b4a62b1fa546312d882fa12dfdcd015177d66826. This reverts commit b7836d856206ec39509d42529f958c920368166b. No conflicts in the code, few tests had conflicts in autogenerated CHECKs: llvm/test/CodeGen/Thumb2/mve-float32regloops.ll llvm/test/CodeGen/AMDGPU/fix-frame-reg-in-custom-csr-spills.ll Reviewed By: alexfh Differential Revision: https://reviews.llvm.org/D156381
2023-07-07[CodeGen]Allow targets to use target specific COPY instructions for live ↵Yashwant Singh
range splitting Replacing D143754. Right now the LiveRangeSplitting during register allocation uses TargetOpcode::COPY instruction for splitting. For AMDGPU target that creates a problem as we have both vector and scalar copies. Vector copies perform a copy over a vector register but only on the lanes(threads) that are active. This is mostly sufficient however we do run into cases when we have to copy the entire vector register and not just active lane data. One major place where we need that is live range splitting. Allowing targets to use their own copy instructions(if defined) will provide a lot of flexibility and ease to lower these pseudo instructions to correct MIR. - Introduce getTargetCopyOpcode() virtual function and use if to generate copy in Live range splitting. - Replace necessary MI.isCopy() checks with TII.isCopyInstr() in register allocator pipeline. Reviewed By: arsenm, cdevadas, kparzysz Differential Revision: https://reviews.llvm.org/D150388
2023-03-22[CodeGen] Fix type of MachineRegisterInfo::RegAllocHints. NFC.Jay Foad
The first member of the pair should be unsigned instead of Register because it is the hint type, 0 for simple (target independent) hints and other values for target dependent hints. Differential Revision: https://reviews.llvm.org/D146646
2023-02-07[CodeGen] Define and use MachineOperand::getOperandNoJay Foad
This is a helper function to very slightly simplify many calls to MachineInstruction::getOperandNo. Differential Revision: https://reviews.llvm.org/D143250
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
2022-09-12RegAlloc: Use SmallSet instead of std::setMatt Arsenault
There shouldn't be more than a small handful of hints at most.
2022-07-18CodeGen: Remove AliasAnalysis from regallocMatt Arsenault
This was stored in LiveIntervals, but not actually used for anything related to LiveIntervals. It was only used in one check for if a load instruction is rematerializable. I also don't think this was entirely correct, since it was implicitly assuming constant loads are also dereferenceable. Remove this and rely only on the invariant+dereferenceable flags in the memory operand. Set the flag based on the AA query upfront. This should have the same net benefit, but has the possible disadvantage of making this AA query nonlazy. Preserve the behavior of assuming pointsToConstantMemory implying dereferenceable for now, but maybe this should be changed.
2022-07-17[CodeGen] Qualify auto variables in for loops (NFC)Kazu Hirata
2022-06-13[CodeGen] Remove futureWeight (NFC)Kazu Hirata
The last use was removed on Jun 5, 2022 in commit 5c06f7168fd1bd589b831cacd5f1cb8a928446fb, which itself was a patch to remove unused code.
2022-01-04[NFC] Expose isRematerializable and copyHint from CalcSpillWeightsMircea Trofin
We need to reuse them for the ML regalloc eviction advisor, as we 'explode' the weight calculation into sub-features. Differential Revision: https://reviews.llvm.org/D116074
2021-12-20[NFC] Fix clang-tidy issues in CalcSpillWeights.cppMircea Trofin
2021-03-24[RegAlloc] Fix "ran out of regs" with uses in statepointSerguei Katkov
Statepoint instruction is known to have a variable and big number of operands. It is possible that Register Allocator will split live intervals in the way that all physical registers are occupied by "zero-length" live intervals which are marked as not-spillable. While intervals are marked as not-spillable in the moment of creation when they are really zero-length it is possible that in future as part of re-materialization there will need for physical register between def and use of such tiny interval (the use is not related to this interval at all). As all physical registers are assigned to not-spillable intervals there is not avaialbe registers and RA reports an error. The idea of the fix is avoid marking tiny live intervals where there is a use in statepoint instruction in var args section. Such interval may be perfectly spilled and folded to operand of statepoint. Reviewers: reames, dantrushin, qcolombet, dsanders, dmgreen Reviewed By: reames Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D98766
2020-12-10[ARM][RegAlloc] Add t2LoopEndDecDavid Green
We currently have problems with the way that low overhead loops are specified, with LR being spilled between the t2LoopDec and the t2LoopEnd forcing the entire loop to be reverted late in the backend. As they will eventually become a single instruction, this patch introduces a t2LoopEndDec which is the combination of the two, combined before registry allocation to make sure this does not fail. Unfortunately this instruction is a terminator that produces a value (and also branches - it only produces the value around the branching edge). So this needs some adjustment to phi elimination and the register allocator to make sure that we do not spill this LR def around the loop (needing to put a spill after the terminator). We treat the loop very carefully, making sure that there is nothing else like calls that would break it's ability to use LR. For that, this adds a isUnspillableTerminator to opt in the new behaviour. There is a chance that this could cause problems, and so I have added an escape option incase. But I have not seen any problems in the testing that I've tried, and not reverting Low overhead loops is important for our performance. If this does work then we can hopefully do the same for t2WhileLoopStart and t2DoLoopStart instructions. This patch also contains the code needed to convert or revert the t2LoopEndDec in the backend (which just needs a subs; bne) and the code pre-ra to create them. Differential Revision: https://reviews.llvm.org/D91358
2020-12-02[NFC][MC] TargetRegisterInfo::getSubReg is a MCRegister.Mircea Trofin
Typing the API appropriately. Differential Revision: https://reviews.llvm.org/D92341
2020-10-12[NFC][Regalloc] Pass VirtRegMap by reference.Mircea Trofin
It's never null - the reason it's modeled as a pointer is because the pass can't init it in its ctor. Passing by ref simplifies the code, too, as the null checks were unnecessary complexity. Differential Revision: https://reviews.llvm.org/D89171
2020-10-09[NFC][Regalloc] VirtRegAuxInfo::Hint does not need to be a fieldMircea Trofin
It is only used in weightCalcHelper, and cleared upon its finishing its job there. The patch further cleans up style guide discrepancies, and simplifies CopyHint by removing duplicate 'IsPhys' information (it's what the Reg field would report).
2020-10-09[NFC][Regalloc] Fix coding style in CalcSpillWeightsMircea Trofin
2020-09-30[NFC][regalloc] Make VirtRegAuxInfo part of allocator stateMircea Trofin
All the state of VRAI is allocator-wide, so we can avoid creating it every time we need it. In addition, the normalization function is allocator-specific. In a next change, we can simplify that design in favor of just having it as a virtual member. Differential Revision: https://reviews.llvm.org/D88499
2020-09-16[NFC][Regalloc] accessors for 'reg' and 'weight'Mircea Trofin
Also renamed the fields to follow style guidelines. Accessors help with readability - weight mutation, in particular, is easier to follow this way. Differential Revision: https://reviews.llvm.org/D87725
2020-07-15[CalcSpillWeights] Propagate the fact that a live-interval is not spillableQuentin Colombet
When we calculate the weight of a live-interval, add some code to check if the original live-interval was markied as not spillable and if so, progagate that information down to the new interval. Previously we would just recompute a weight for the new interval, thus, we could in theory just spill live-intervals marked as not spillable by just splitting them. That goes against the spirit of a non-spillable live-interval. E.g., previously we could do: v1 = // v1 must not be spilled ... = v1 Split: v1 = // v1 must not be spilled ... v2 = v1 // v2 can be spilled ... v3 = v2 // v3 can be spilled = v3 There's no test case for that one as we would need to split a non-spillable live-interval without using LiveRangeEdit to see this happening. RegAlloc inserts non-spillable intervals only as part of the spilling mechanism, thus at this point the intervals are not splittable anymore. On top of that, RegAlloc uses the LiveRangeEdit API, which already properly propagate that information. In other words, this could only happen if a target was to mark a live-interval as not spillable before register allocation and split it without using LRE, e.g., through LiveIntervals::splitSeparateComponent.
2020-03-18Fix possible assertion when using PBQP with debug infoDanila Malyutin
Skip debug instructions before calling functions not expecting them. In particular, LIS.getInstructionIndex(*mi) would fail if mi was a debg instr. Differential Revision: https://reviews.llvm.org/D76129
2019-08-15Apply llvm-prefer-register-over-unsigned from clang-tidy to LLVMDaniel Sanders
Summary: This clang-tidy check is looking for unsigned integer variables whose initializer starts with an implicit cast from llvm::Register and changes the type of the variable to llvm::Register (dropping the llvm:: where possible). Partial reverts in: X86FrameLowering.cpp - Some functions return unsigned and arguably should be MCRegister X86FixupLEAs.cpp - Some functions return unsigned and arguably should be MCRegister X86FrameLowering.cpp - Some functions return unsigned and arguably should be MCRegister HexagonBitSimplify.cpp - Function takes BitTracker::RegisterRef which appears to be unsigned& MachineVerifier.cpp - Ambiguous operator==() given MCRegister and const Register PPCFastISel.cpp - No Register::operator-=() PeepholeOptimizer.cpp - TargetInstrInfo::optimizeLoadInstr() takes an unsigned& MachineTraceMetrics.cpp - MachineTraceMetrics lacks a suitable constructor Manual fixups in: ARMFastISel.cpp - ARMEmitLoad() now takes a Register& instead of unsigned& HexagonSplitDouble.cpp - Ternary operator was ambiguous between unsigned/Register HexagonConstExtenders.cpp - Has a local class named Register, used llvm::Register instead of Register. PPCFastISel.cpp - PPCEmitLoad() now takes a Register& instead of unsigned& Depends on D65919 Reviewers: arsenm, bogner, craig.topper, RKSimon Reviewed By: arsenm Subscribers: RKSimon, craig.topper, lenary, aemerson, wuzish, jholewinski, MatzeB, qcolombet, dschuff, jyknight, dylanmckay, sdardis, nemanjai, jvesely, wdng, nhaehnle, sbc100, jgravelle-google, kristof.beyls, hiraditya, aheejin, kbarton, fedor.sergeev, javed.absar, asb, rbar, johnrusso, simoncook, apazos, sabuasal, niosHD, jrtc27, MaskRay, zzheng, edward-jones, atanasyan, rogfer01, MartinMosbeck, brucehoult, the_o, tpr, PkmX, jocewei, jsji, Petar.Avramovic, asbirlea, Jim, s.egerton, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D65962 llvm-svn: 369041
2019-08-02Use MCRegister in MCRegisterInfo's interfacesDaniel Sanders
Summary: As part of this, define DenseMapInfo for MCRegister (and Register while I'm at it) Depends on D65599 Reviewers: arsenm Subscribers: MatzeB, qcolombet, jvesely, wdng, nhaehnle, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D65605 llvm-svn: 367719
2019-08-01Finish moving TargetRegisterInfo::isVirtualRegister() and friends to ↵Daniel Sanders
llvm::Register as started by r367614. NFC llvm-svn: 367633
2019-01-19Update the file headers across all of the LLVM projects in the monorepoChandler Carruth
to reflect the new license. We understand that people may be surprised that we're moving the header entirely to discuss the new license. We checked this carefully with the Foundation's lawyer and we believe this is the correct approach. Essentially, all code in the project is now made available by the LLVM project under our new license, so you will see that the license headers include that license only. Some of our contributors have contributed code under our old license, and accordingly, we have retained a copy of our old license notice in the top-level files in each project and repository. llvm-svn: 351636
2018-10-05[TargetRegisterInfo] Remove temporary hook enableMultipleCopyHints()Jonas Paulsson
Finally all targets are enabling multiple regalloc hints, so the hook to disable this can now be removed. NFC. Review: Simon Pilgrim https://reviews.llvm.org/D52316 llvm-svn: 343851
2018-10-03[RA CopyHints] Fix compile-time regressionJonas Paulsson
This patch makes sure that a register is only hinted once to RA. In extreme cases the same register can otherwise be hinted numerous times and cause a compile time slowdown. Review: Simon Pilgrim https://reviews.llvm.org/D52826 llvm-svn: 343686
2018-05-14Rename DEBUG macro to LLVM_DEBUG.Nicola Zaghen
The DEBUG() macro is very generic so it might clash with other projects. The renaming was done as follows: - git grep -l 'DEBUG' | xargs sed -i 's/\bDEBUG\s\?(/LLVM_DEBUG(/g' - git diff -U0 master | ../clang/tools/clang-format/clang-format-diff.py -i -p1 -style LLVM - Manual change to APInt - Manually chage DOCS as regex doesn't match it. In the transition period the DEBUG() macro is still present and aliased to the LLVM_DEBUG() one. Differential Revision: https://reviews.llvm.org/D43624 llvm-svn: 332240
2018-05-09[DebugInfo] Examine all uses of isDebugValue() for debug instructions.Shiva Chen
Because we create a new kind of debug instruction, DBG_LABEL, we need to check all passes which use isDebugValue() to check MachineInstr is debug instruction or not. When expelling debug instructions, we should expel both DBG_VALUE and DBG_LABEL. So, I create a new function, isDebugInstr(), in MachineInstr to check whether the MachineInstr is debug instruction or not. This patch has no new test case. I have run regression test and there is no difference in regression test. Differential Revision: https://reviews.llvm.org/D45342 Patch by Hsiangkai Wang. llvm-svn: 331844
2017-12-13Rename LiveIntervalAnalysis.h to LiveIntervals.hMatthias Braun
Headers/Implementation files should be named after the class they declare/define. Also eliminated an `#include "llvm/CodeGen/LiveIntervalAnalysis.h"` in favor of `class LiveIntarvals;` llvm-svn: 320546
2017-12-05[Regalloc] Generate and store multiple regalloc hints.Jonas Paulsson
MachineRegisterInfo used to allow just one regalloc hint per virtual register. This patch extends this to a vector of regalloc hints, which is filled in by common code with sorted copy hints. Such hints will make for more ID copies that can be removed. NB! This improvement is currently (and hopefully temporarily) *disabled* by default, except for SystemZ. The only reason for this is the big impact this has on tests, which has unfortunately proven unmanageable. It was a long while since all the tests were updated and just waiting for review (which didn't happen), but now targets have to enable this themselves instead. Several targets could get a head-start by downloading the tests updates from the Phabricator review. Thanks to those who helped, and sorry you now have to do this step yourselves. This should be an improvement generally for any target! The target may still create its own hint, in which case this has highest priority and is stored first in the vector. If it has target-type, it will not be recomputed, as per the previous behaviour. The temporary hook enableMultipleCopyHints() will be removed as soon as all targets return true. Review: Quentin Colombet, Ulrich Weigand. https://reviews.llvm.org/D38128 llvm-svn: 319754
2017-11-17Fix a bunch more layering of CodeGen headers that are in TargetDavid Blaikie
All these headers already depend on CodeGen headers so moving them into CodeGen fixes the layering (since CodeGen depends on Target, not the other way around). llvm-svn: 318490
2017-11-08Target/TargetInstrInfo.h -> CodeGen/TargetInstrInfo.h to match layeringDavid Blaikie
This header includes CodeGen headers, and is not, itself, included by any Target headers, so move it into CodeGen to match the layering of its implementation. llvm-svn: 317647