Skip to content

Commit e31794f

Browse files
authored
[StackFrameLayoutAnalysis] Support more SlotTypes (#100562)
Add new SlotTypes to StackFrameLayoutAnalysis to disambiguate Fixed and Variable-Sized stack slots from Variable slots. As Offsets are unreliable for VLA-area objects, sort these to the end of the list - using the Frame Index to ensure a deterministic order when Offsets are equal.
1 parent 319d29d commit e31794f

File tree

3 files changed

+45
-19
lines changed

3 files changed

+45
-19
lines changed

llvm/lib/CodeGen/StackFrameLayoutAnalysisPass.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ struct StackFrameLayoutAnalysisPass : public MachineFunctionPass {
5151

5252
enum SlotType {
5353
Spill, // a Spill slot
54+
Fixed, // a Fixed slot (e.g. arguments passed on the stack)
55+
VariableSized, // a variable sized object
5456
StackProtector, // Stack Protector slot
5557
Variable, // a slot used to store a local data (could be a tmp)
5658
Invalid // It's an error for a slot to have this type
@@ -72,17 +74,30 @@ struct StackFrameLayoutAnalysisPass : public MachineFunctionPass {
7274
Scalable = MFI.getStackID(Idx) == TargetStackID::ScalableVector;
7375
if (MFI.isSpillSlotObjectIndex(Idx))
7476
SlotTy = SlotType::Spill;
75-
else if (Idx == MFI.getStackProtectorIndex())
77+
else if (MFI.isFixedObjectIndex(Idx))
78+
SlotTy = SlotType::Fixed;
79+
else if (MFI.isVariableSizedObjectIndex(Idx))
80+
SlotTy = SlotType::VariableSized;
81+
else if (MFI.hasStackProtectorIndex() &&
82+
Idx == MFI.getStackProtectorIndex())
7683
SlotTy = SlotType::StackProtector;
7784
else
7885
SlotTy = SlotType::Variable;
7986
}
8087

88+
bool isVarSize() const { return SlotTy == SlotType::VariableSized; }
89+
8190
// We use this to sort in reverse order, so that the layout is displayed
82-
// correctly.
91+
// correctly. Variable sized slots are sorted to the end of the list, as
92+
// offsets are currently incorrect for these but they reside at the end of
93+
// the stack frame. The Slot index is used to ensure deterministic order
94+
// when offsets are equal.
8395
bool operator<(const SlotData &Rhs) const {
84-
return (Offset.getFixed() + Offset.getScalable()) >
85-
(Rhs.Offset.getFixed() + Rhs.Offset.getScalable());
96+
return std::make_tuple(!isVarSize(),
97+
Offset.getFixed() + Offset.getScalable(), Slot) >
98+
std::make_tuple(!Rhs.isVarSize(),
99+
Rhs.Offset.getFixed() + Rhs.Offset.getScalable(),
100+
Rhs.Slot);
86101
}
87102
};
88103

@@ -121,6 +136,10 @@ struct StackFrameLayoutAnalysisPass : public MachineFunctionPass {
121136
switch (Ty) {
122137
case SlotType::Spill:
123138
return "Spill";
139+
case SlotType::Fixed:
140+
return "Fixed";
141+
case SlotType::VariableSized:
142+
return "VariableSized";
124143
case SlotType::StackProtector:
125144
return "Protector";
126145
case SlotType::Variable:

llvm/test/CodeGen/AArch64/sve-stack-frame-layout.ll

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,11 @@ entry:
147147
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP-8], Type: Spill, Align: 8, Size: 8
148148
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP-16], Type: Spill, Align: 8, Size: 8
149149
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP-24], Type: Spill, Align: 8, Size: 8
150-
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP-32], Type: Variable, Align: 1, Size: 0
151150
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP-32], Type: Spill, Align: 8, Size: 8
152151
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP-32-16 x vscale], Type: Variable, Align: 16, Size: vscale x 16
153152
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP-40-16 x vscale], Type: Variable, Align: 8, Size: 8
153+
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP-32], Type: VariableSized, Align: 1, Size: 0
154+
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP-32], Type: VariableSized, Align: 1, Size: 0
154155

155156
define i32 @csr_d8_allocnxv4i32i32f64_vla(double %d, i32 %i) "aarch64_pstate_sm_compatible" {
156157
; CHECK-LABEL: csr_d8_allocnxv4i32i32f64_vla:
@@ -172,7 +173,10 @@ define i32 @csr_d8_allocnxv4i32i32f64_vla(double %d, i32 %i) "aarch64_pstate_sm_
172173
; CHECK-NEXT: mov x9, sp
173174
; CHECK-NEXT: add x8, x8, #15
174175
; CHECK-NEXT: and x8, x8, #0x7fffffff0
175-
; CHECK-NEXT: sub x8, x9, x8
176+
; CHECK-NEXT: sub x9, x9, x8
177+
; CHECK-NEXT: mov sp, x9
178+
; CHECK-NEXT: mov x10, sp
179+
; CHECK-NEXT: sub x8, x10, x8
176180
; CHECK-NEXT: mov sp, x8
177181
; CHECK-NEXT: mov z1.s, #0 // =0x0
178182
; CHECK-NEXT: ptrue p0.s
@@ -181,8 +185,9 @@ define i32 @csr_d8_allocnxv4i32i32f64_vla(double %d, i32 %i) "aarch64_pstate_sm_
181185
; CHECK-NEXT: str wzr, [x8]
182186
; CHECK-NEXT: sub x8, x29, #8
183187
; CHECK-NEXT: mov w0, wzr
184-
; CHECK-NEXT: str d0, [x19, #8]
188+
; CHECK-NEXT: str wzr, [x9]
185189
; CHECK-NEXT: st1w { z1.s }, p0, [x8, #-1, mul vl]
190+
; CHECK-NEXT: str d0, [x19, #8]
186191
; CHECK-NEXT: sub sp, x29, #8
187192
; CHECK-NEXT: ldp x29, x30, [sp, #8] // 16-byte Folded Reload
188193
; CHECK-NEXT: ldr x19, [sp, #24] // 8-byte Folded Reload
@@ -191,18 +196,20 @@ define i32 @csr_d8_allocnxv4i32i32f64_vla(double %d, i32 %i) "aarch64_pstate_sm_
191196
entry:
192197
%a = alloca <vscale x 4 x i32>
193198
%0 = zext i32 %i to i64
194-
%b = alloca i32, i64 %0
199+
%vla0 = alloca i32, i64 %0
200+
%vla1 = alloca i32, i64 %0
195201
%c = alloca double
196202
tail call void asm sideeffect "", "~{d8}"() #1
197203
store <vscale x 4 x i32> zeroinitializer, ptr %a
198-
store i32 zeroinitializer, ptr %b
204+
store i32 zeroinitializer, ptr %vla0
205+
store i32 zeroinitializer, ptr %vla1
199206
store double %d, ptr %c
200207
ret i32 0
201208
}
202209

203210
; CHECK-FRAMELAYOUT-LABEL: Function: csr_d8_allocnxv4i32i32f64_stackargsi32f64
204-
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP+8], Type: Variable, Align: 8, Size: 4
205-
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP+0], Type: Protector, Align: 16, Size: 8
211+
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP+8], Type: Fixed, Align: 8, Size: 4
212+
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP+0], Type: Fixed, Align: 16, Size: 8
206213
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP-8], Type: Spill, Align: 8, Size: 8
207214
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP-16], Type: Spill, Align: 8, Size: 8
208215
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP-16-16 x vscale], Type: Variable, Align: 16, Size: vscale x 16
@@ -289,7 +296,7 @@ entry:
289296
}
290297

291298
; CHECK-FRAMELAYOUT-LABEL: Function: svecc_z8_allocnxv4i32i32f64_stackargsi32_fp
292-
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP+0], Type: Protector, Align: 16, Size: 4
299+
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP+0], Type: Fixed, Align: 16, Size: 4
293300
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP-8], Type: Spill, Align: 8, Size: 8
294301
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP-16], Type: Spill, Align: 8, Size: 8
295302
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP-16-16 x vscale], Type: Spill, Align: 16, Size: vscale x 16
@@ -514,7 +521,7 @@ declare ptr @memset(ptr, i32, i32)
514521
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP-104], Type: Spill, Align: 8, Size: 8
515522
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP-112], Type: Spill, Align: 8, Size: 8
516523
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP-128], Type: Variable, Align: 16, Size: 16
517-
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP-128], Type: Variable, Align: 16, Size: 0
524+
; CHECK-FRAMELAYOUT-NEXT: Offset: [SP-128], Type: VariableSized, Align: 16, Size: 0
518525

519526
define i32 @vastate(i32 %x) "aarch64_inout_za" "aarch64_pstate_sm_enabled" "target-features"="+sme" {
520527
; CHECK-LABEL: vastate:

llvm/test/CodeGen/X86/stack-frame-layout-remarks.ll

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ entry:
3535
declare void @llvm.dbg.declare(metadata, metadata, metadata) #0
3636

3737
; BOTH: Function: cleanup_array
38-
; BOTH-NEXT: Offset: [SP+4], Type: Protector, Align: 16, Size: 4
38+
; BOTH-NEXT: Offset: [SP+4], Type: Fixed, Align: 16, Size: 4
3939
; DEBUG: a @ dot.c:13
4040
; STRIPPED-NOT: a @ dot.c:13
4141
; BOTH: Offset: [SP-4], Type: Spill, Align: 8, Size: 4
@@ -47,7 +47,7 @@ define void @cleanup_array(ptr %0) #1 {
4747
}
4848

4949
; BOTH: Function: cleanup_result
50-
; BOTH: Offset: [SP+4], Type: Protector, Align: 16, Size: 4
50+
; BOTH: Offset: [SP+4], Type: Fixed, Align: 16, Size: 4
5151
; DEBUG: res @ dot.c:21
5252
; STRIPPED-NOT: res @ dot.c:21
5353
; BOTH: Offset: [SP-4], Type: Spill, Align: 8, Size: 4
@@ -59,11 +59,11 @@ define void @cleanup_result(ptr %0) #1 {
5959
}
6060

6161
; BOTH: Function: do_work
62-
; BOTH: Offset: [SP+12], Type: Variable, Align: 8, Size: 4
62+
; BOTH: Offset: [SP+12], Type: Fixed, Align: 8, Size: 4
6363
; DEBUG: out @ dot.c:32
6464
; STRIPPED-NOT: out @ dot.c:32
65-
; BOTH: Offset: [SP+8], Type: Variable, Align: 4, Size: 4
66-
; BOTH: Offset: [SP+4], Type: Protector, Align: 16, Size: 4
65+
; BOTH: Offset: [SP+8], Type: Fixed, Align: 4, Size: 4
66+
; BOTH: Offset: [SP+4], Type: Fixed, Align: 16, Size: 4
6767
; DEBUG: A @ dot.c:32
6868
; STRIPPED-NOT: A @ dot.c:32
6969
; BOTH: Offset: [SP-4], Type: Spill, Align: 8, Size: 4
@@ -125,7 +125,7 @@ define i32 @do_work(ptr %0, ptr %1, ptr %2) #2 {
125125
}
126126

127127
; BOTH: Function: gen_array
128-
; BOTH: Offset: [SP+4], Type: Protector, Align: 16, Size: 4
128+
; BOTH: Offset: [SP+4], Type: Fixed, Align: 16, Size: 4
129129
; DEBUG: size @ dot.c:62
130130
; STRIPPED-NOT: size @ dot.c:62
131131
; BOTH: Offset: [SP-4], Type: Spill, Align: 8, Size: 4

0 commit comments

Comments
 (0)