Skip to content

Commit abdf644

Browse files
redstaraniplcc
authored andcommitted
[SystemZ][z/OS] Implement llvm.frameaddr for XPLINK (llvm#89284)
The implementation follows the ELF implementation.
1 parent ed65291 commit abdf644

File tree

4 files changed

+105
-14
lines changed

4 files changed

+105
-14
lines changed

llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,19 @@ SystemZXPLINKFrameLowering::SystemZXPLINKFrameLowering()
896896
RegSpillOffsets[Entry.Reg] = Entry.Offset;
897897
}
898898

899+
int SystemZXPLINKFrameLowering::getOrCreateFramePointerSaveIndex(
900+
MachineFunction &MF) const {
901+
SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>();
902+
int FI = ZFI->getFramePointerSaveIndex();
903+
if (!FI) {
904+
MachineFrameInfo &MFFrame = MF.getFrameInfo();
905+
FI = MFFrame.CreateFixedObject(8, 0, false);
906+
MFFrame.setStackID(FI, TargetStackID::NoAlloc);
907+
ZFI->setFramePointerSaveIndex(FI);
908+
}
909+
return FI;
910+
}
911+
899912
// Checks if the function is a potential candidate for being a XPLeaf routine.
900913
static bool isXPLeafCandidate(const MachineFunction &MF) {
901914
const MachineFrameInfo &MFFrame = MF.getFrameInfo();
@@ -991,6 +1004,9 @@ bool SystemZXPLINKFrameLowering::assignCalleeSavedSpillSlots(
9911004
Register HighGPR = 0;
9921005
int HighOffset = -1;
9931006

1007+
// Query index of the saved frame pointer.
1008+
int FPSI = MFI->getFramePointerSaveIndex();
1009+
9941010
for (auto &CS : CSI) {
9951011
Register Reg = CS.getReg();
9961012
int Offset = RegSpillOffsets[Reg];
@@ -1013,7 +1029,10 @@ bool SystemZXPLINKFrameLowering::assignCalleeSavedSpillSlots(
10131029
// the bottom of the stack and are not truly part of the "normal" stack
10141030
// frame. Mark the frame index as NoAlloc to indicate it as such.
10151031
unsigned RegSize = 8;
1016-
int FrameIdx = MFFrame.CreateFixedSpillStackObject(RegSize, Offset);
1032+
int FrameIdx =
1033+
(FPSI && Offset == 0)
1034+
? FPSI
1035+
: MFFrame.CreateFixedSpillStackObject(RegSize, Offset);
10171036
CS.setFrameIdx(FrameIdx);
10181037
MFFrame.setStackID(FrameIdx, TargetStackID::NoAlloc);
10191038
}
@@ -1467,15 +1486,16 @@ void SystemZXPLINKFrameLowering::determineFrameLayout(
14671486
StackSize += Regs->getCallFrameSize();
14681487
MFFrame.setStackSize(StackSize);
14691488

1470-
// We now know the stack size. Create the fixed spill stack objects for the
1471-
// register save area now. This has no impact on the stack frame layout, as
1472-
// this is already computed. However, it makes sure that all callee saved
1473-
// registers have a valid frame index assigned.
1474-
const unsigned RegSize = MF.getDataLayout().getPointerSize();
1475-
for (auto &CS : MFFrame.getCalleeSavedInfo()) {
1476-
int Offset = RegSpillOffsets[CS.getReg()];
1477-
if (Offset >= 0)
1478-
CS.setFrameIdx(
1479-
MFFrame.CreateFixedSpillStackObject(RegSize, Offset - StackSize));
1489+
// We now know the stack size. Update the stack objects for the register save
1490+
// area now. This has no impact on the stack frame layout, as this is already
1491+
// computed. However, it makes sure that all callee saved registers have a
1492+
// valid offset assigned.
1493+
for (int FrameIdx = MFFrame.getObjectIndexBegin(); FrameIdx != 0;
1494+
++FrameIdx) {
1495+
if (MFFrame.getStackID(FrameIdx) == TargetStackID::NoAlloc) {
1496+
int64_t SPOffset = MFFrame.getObjectOffset(FrameIdx);
1497+
SPOffset -= StackSize;
1498+
MFFrame.setObjectOffset(FrameIdx, SPOffset);
1499+
}
14801500
}
14811501
}

llvm/lib/Target/SystemZ/SystemZFrameLowering.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ class SystemZFrameLowering : public TargetFrameLowering {
4141
}
4242

4343
bool hasReservedCallFrame(const MachineFunction &MF) const override;
44+
45+
// Return the offset of the backchain.
46+
virtual unsigned getBackchainOffset(MachineFunction &MF) const = 0;
47+
48+
// Get or create the frame index of where the old frame pointer is stored.
49+
virtual int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const = 0;
4450
};
4551

4652
class SystemZELFFrameLowering : public SystemZFrameLowering {
@@ -86,13 +92,13 @@ class SystemZELFFrameLowering : public SystemZFrameLowering {
8692
bool usePackedStack(MachineFunction &MF) const;
8793

8894
// Return the offset of the backchain.
89-
unsigned getBackchainOffset(MachineFunction &MF) const {
95+
unsigned getBackchainOffset(MachineFunction &MF) const override {
9096
// The back chain is stored topmost with packed-stack.
9197
return usePackedStack(MF) ? SystemZMC::ELFCallFrameSize - 8 : 0;
9298
}
9399

94100
// Get or create the frame index of where the old frame pointer is stored.
95-
int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const;
101+
int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const override;
96102
};
97103

98104
class SystemZXPLINKFrameLowering : public SystemZFrameLowering {
@@ -133,6 +139,15 @@ class SystemZXPLINKFrameLowering : public SystemZFrameLowering {
133139
RegScavenger *RS) const override;
134140

135141
void determineFrameLayout(MachineFunction &MF) const;
142+
143+
// Return the offset of the backchain.
144+
unsigned getBackchainOffset(MachineFunction &MF) const override {
145+
// The back chain is always the first element of the frame.
146+
return 0;
147+
}
148+
149+
// Get or create the frame index of where the old frame pointer is stored.
150+
int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const override;
136151
};
137152
} // end namespace llvm
138153

llvm/lib/Target/SystemZ/SystemZISelLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3765,7 +3765,7 @@ SDValue SystemZTargetLowering::lowerConstantPool(ConstantPoolSDNode *CP,
37653765

37663766
SDValue SystemZTargetLowering::lowerFRAMEADDR(SDValue Op,
37673767
SelectionDAG &DAG) const {
3768-
auto *TFL = Subtarget.getFrameLowering<SystemZELFFrameLowering>();
3768+
auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
37693769
MachineFunction &MF = DAG.getMachineFunction();
37703770
MachineFrameInfo &MFI = MF.getFrameInfo();
37713771
MFI.setFrameAddressIsTaken(true);
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
2+
; RUN: llc < %s -mtriple=s390x-ibm-zos | FileCheck --check-prefix=CHECK %s
3+
4+
; The current function's frame address is the address of
5+
; the optional back chain slot.
6+
define ptr @fp0() nounwind {
7+
; CHECK-LABEL: fp0:
8+
; CHECK: la 3, 2048(4)
9+
; CHECK-NEXT: b 2(7)
10+
entry:
11+
%0 = tail call ptr @llvm.frameaddress(i32 0)
12+
ret ptr %0
13+
}
14+
15+
; Check that the frame address is correct in a presence
16+
; of a stack frame.
17+
define ptr @fp0f() nounwind {
18+
; CHECK-LABEL: fp0f:
19+
; CHECK: stmg 6, 7, 1904(4)
20+
; CHECK-NEXT: aghi 4, -160
21+
; CHECK-NEXT: la 3, 2048(4)
22+
; CHECK-NEXT: lg 7, 2072(4)
23+
; CHECK-NEXT: aghi 4, 160
24+
; CHECK-NEXT: b 2(7)
25+
entry:
26+
%0 = alloca i64, align 8
27+
%1 = tail call ptr @llvm.frameaddress(i32 0)
28+
ret ptr %1
29+
}
30+
31+
; Check the caller's frame address.
32+
define ptr @fpcaller() nounwind "backchain" {
33+
; CHECK-LABEL: fpcaller:
34+
; CHECK: stmg 4, 7, 2048(4)
35+
; CHECK-NEXT: lg 3, 2048(4)
36+
; CHECK-NEXT: lmg 4, 7, 2048(4)
37+
; CHECK-NEXT: b 2(7)
38+
entry:
39+
%0 = tail call ptr @llvm.frameaddress(i32 1)
40+
ret ptr %0
41+
}
42+
43+
; Check the caller's frame address.
44+
define ptr @fpcallercaller() nounwind "backchain" {
45+
; CHECK-LABEL: fpcallercaller:
46+
; CHECK: stmg 4, 7, 2048(4)
47+
; CHECK-NEXT: lg 1, 2048(4)
48+
; CHECK-NEXT: lg 3, 0(1)
49+
; CHECK-NEXT: lmg 4, 7, 2048(4)
50+
; CHECK-NEXT: b 2(7)
51+
entry:
52+
%0 = tail call ptr @llvm.frameaddress(i32 2)
53+
ret ptr %0
54+
}
55+
56+
declare ptr @llvm.frameaddress(i32) nounwind readnone

0 commit comments

Comments
 (0)