aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/InlineSpiller.cpp
diff options
context:
space:
mode:
authorSerguei Katkov <serguei.katkov@azul.com>2022-10-20 12:05:33 +0700
committerSerguei Katkov <serguei.katkov@azul.com>2023-01-09 13:30:57 +0700
commitfd64bd94eda0b93c2fb95e048e7919832f72a1cd (patch)
tree9ab25d12e477509a30bcabb647c4df854bb358de /llvm/lib/CodeGen/InlineSpiller.cpp
parent323782f6f1a7a41466714365aeeec86efe0e534c (diff)
downloadllvm-fd64bd94eda0b93c2fb95e048e7919832f72a1cd.zip
llvm-fd64bd94eda0b93c2fb95e048e7919832f72a1cd.tar.gz
llvm-fd64bd94eda0b93c2fb95e048e7919832f72a1cd.tar.bz2
[Inline Spiller] Extend the snippet by statepoint uses
Snippet is a tiny live interval which has copy or fill like def and copy or spill like use at the end (any of them might abcent). Snippet has only one use/def inside interval and interval is located in one basic block. When inline spiller spills some reg around uses it also forces the spilling of connected snippets those which got by splitting the same original reg and its def is a full copy of our reg or its last use is a full copy to our reg. The definition of snippet is extended to allow not only one use/def but more. However all other uses are statepoint instructions which will fold fill into its operand. That way we do not introduce new fills/spills. Reviewed By: qcolombet, dantrushin Differential Revision: https://reviews.llvm.org/D138093
Diffstat (limited to 'llvm/lib/CodeGen/InlineSpiller.cpp')
-rw-r--r--llvm/lib/CodeGen/InlineSpiller.cpp22
1 files changed, 20 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/InlineSpiller.cpp b/llvm/lib/CodeGen/InlineSpiller.cpp
index e80f0ab..5f582ee 100644
--- a/llvm/lib/CodeGen/InlineSpiller.cpp
+++ b/llvm/lib/CodeGen/InlineSpiller.cpp
@@ -280,13 +280,28 @@ bool InlineSpiller::isSnippet(const LiveInterval &SnipLI) {
Register Reg = Edit->getReg();
// A snippet is a tiny live range with only a single instruction using it
- // besides copies to/from Reg or spills/fills. We accept:
+ // besides copies to/from Reg or spills/fills.
+ // Exception is done for statepoint instructions which will fold fills
+ // into their operands.
+ // We accept:
//
// %snip = COPY %Reg / FILL fi#
// %snip = USE %snip
+ // %snip = STATEPOINT %snip in var arg area
// %Reg = COPY %snip / SPILL %snip, fi#
//
- if (SnipLI.getNumValNums() > 2 || !LIS.intervalIsInOneMBB(SnipLI))
+ if (!LIS.intervalIsInOneMBB(SnipLI))
+ return false;
+
+ // Number of defs should not exceed 2 not accounting defs coming from
+ // statepoint instructions.
+ unsigned NumValNums = SnipLI.getNumValNums();
+ for (auto *VNI : SnipLI.vnis()) {
+ MachineInstr *MI = LIS.getInstructionFromIndex(VNI->def);
+ if (MI->getOpcode() == TargetOpcode::STATEPOINT)
+ --NumValNums;
+ }
+ if (NumValNums > 2)
return false;
MachineInstr *UseMI = nullptr;
@@ -311,6 +326,9 @@ bool InlineSpiller::isSnippet(const LiveInterval &SnipLI) {
if (SnipLI.reg() == TII.isStoreToStackSlot(MI, FI) && FI == StackSlot)
continue;
+ if (StatepointOpers::isFoldableReg(&MI, SnipLI.reg()))
+ continue;
+
// Allow a single additional instruction.
if (UseMI && &MI != UseMI)
return false;