Skip to content

[SystemZ][z/OS] Implement llvm.frameaddr for XPLINK #89284

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 31 additions & 11 deletions llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,19 @@ SystemZXPLINKFrameLowering::SystemZXPLINKFrameLowering()
RegSpillOffsets[Entry.Reg] = Entry.Offset;
}

int SystemZXPLINKFrameLowering::getOrCreateFramePointerSaveIndex(
MachineFunction &MF) const {
SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>();
int FI = ZFI->getFramePointerSaveIndex();
if (!FI) {
MachineFrameInfo &MFFrame = MF.getFrameInfo();
FI = MFFrame.CreateFixedObject(8, 0, false);
MFFrame.setStackID(FI, TargetStackID::NoAlloc);
ZFI->setFramePointerSaveIndex(FI);
}
return FI;
}

// Checks if the function is a potential candidate for being a XPLeaf routine.
static bool isXPLeafCandidate(const MachineFunction &MF) {
const MachineFrameInfo &MFFrame = MF.getFrameInfo();
Expand Down Expand Up @@ -991,6 +1004,9 @@ bool SystemZXPLINKFrameLowering::assignCalleeSavedSpillSlots(
Register HighGPR = 0;
int HighOffset = -1;

// Query index of the saved frame pointer.
int FPSI = MFI->getFramePointerSaveIndex();

for (auto &CS : CSI) {
Register Reg = CS.getReg();
int Offset = RegSpillOffsets[Reg];
Expand All @@ -1013,7 +1029,10 @@ bool SystemZXPLINKFrameLowering::assignCalleeSavedSpillSlots(
// the bottom of the stack and are not truly part of the "normal" stack
// frame. Mark the frame index as NoAlloc to indicate it as such.
unsigned RegSize = 8;
int FrameIdx = MFFrame.CreateFixedSpillStackObject(RegSize, Offset);
int FrameIdx =
(FPSI && Offset == 0)
? FPSI
: MFFrame.CreateFixedSpillStackObject(RegSize, Offset);
CS.setFrameIdx(FrameIdx);
MFFrame.setStackID(FrameIdx, TargetStackID::NoAlloc);
}
Expand Down Expand Up @@ -1467,15 +1486,16 @@ void SystemZXPLINKFrameLowering::determineFrameLayout(
StackSize += Regs->getCallFrameSize();
MFFrame.setStackSize(StackSize);

// We now know the stack size. Create the fixed spill stack objects for the
// register save area now. This has no impact on the stack frame layout, as
// this is already computed. However, it makes sure that all callee saved
// registers have a valid frame index assigned.
const unsigned RegSize = MF.getDataLayout().getPointerSize();
for (auto &CS : MFFrame.getCalleeSavedInfo()) {
int Offset = RegSpillOffsets[CS.getReg()];
if (Offset >= 0)
CS.setFrameIdx(
MFFrame.CreateFixedSpillStackObject(RegSize, Offset - StackSize));
// We now know the stack size. Update the stack objects for the register save
// area now. This has no impact on the stack frame layout, as this is already
// computed. However, it makes sure that all callee saved registers have a
// valid offset assigned.
for (int FrameIdx = MFFrame.getObjectIndexBegin(); FrameIdx != 0;
++FrameIdx) {
if (MFFrame.getStackID(FrameIdx) == TargetStackID::NoAlloc) {
int64_t SPOffset = MFFrame.getObjectOffset(FrameIdx);
SPOffset -= StackSize;
MFFrame.setObjectOffset(FrameIdx, SPOffset);
}
}
}
19 changes: 17 additions & 2 deletions llvm/lib/Target/SystemZ/SystemZFrameLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ class SystemZFrameLowering : public TargetFrameLowering {
}

bool hasReservedCallFrame(const MachineFunction &MF) const override;

// Return the offset of the backchain.
virtual unsigned getBackchainOffset(MachineFunction &MF) const = 0;

// Get or create the frame index of where the old frame pointer is stored.
virtual int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const = 0;
};

class SystemZELFFrameLowering : public SystemZFrameLowering {
Expand Down Expand Up @@ -86,13 +92,13 @@ class SystemZELFFrameLowering : public SystemZFrameLowering {
bool usePackedStack(MachineFunction &MF) const;

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

// Get or create the frame index of where the old frame pointer is stored.
int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const;
int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const override;
};

class SystemZXPLINKFrameLowering : public SystemZFrameLowering {
Expand Down Expand Up @@ -133,6 +139,15 @@ class SystemZXPLINKFrameLowering : public SystemZFrameLowering {
RegScavenger *RS) const override;

void determineFrameLayout(MachineFunction &MF) const;

// Return the offset of the backchain.
unsigned getBackchainOffset(MachineFunction &MF) const override {
// The back chain is always the first element of the frame.
return 0;
}

// Get or create the frame index of where the old frame pointer is stored.
int getOrCreateFramePointerSaveIndex(MachineFunction &MF) const override;
};
} // end namespace llvm

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3765,7 +3765,7 @@ SDValue SystemZTargetLowering::lowerConstantPool(ConstantPoolSDNode *CP,

SDValue SystemZTargetLowering::lowerFRAMEADDR(SDValue Op,
SelectionDAG &DAG) const {
auto *TFL = Subtarget.getFrameLowering<SystemZELFFrameLowering>();
auto *TFL = Subtarget.getFrameLowering<SystemZFrameLowering>();
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo &MFI = MF.getFrameInfo();
MFI.setFrameAddressIsTaken(true);
Expand Down
56 changes: 56 additions & 0 deletions llvm/test/CodeGen/SystemZ/zos-frameaddr.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
; RUN: llc < %s -mtriple=s390x-ibm-zos | FileCheck --check-prefix=CHECK %s

; The current function's frame address is the address of
; the optional back chain slot.
define ptr @fp0() nounwind {
; CHECK-LABEL: fp0:
; CHECK: la 3, 2048(4)
; CHECK-NEXT: b 2(7)
entry:
%0 = tail call ptr @llvm.frameaddress(i32 0)
ret ptr %0
}

; Check that the frame address is correct in a presence
; of a stack frame.
define ptr @fp0f() nounwind {
; CHECK-LABEL: fp0f:
; CHECK: stmg 6, 7, 1904(4)
; CHECK-NEXT: aghi 4, -160
; CHECK-NEXT: la 3, 2048(4)
; CHECK-NEXT: lg 7, 2072(4)
; CHECK-NEXT: aghi 4, 160
; CHECK-NEXT: b 2(7)
entry:
%0 = alloca i64, align 8
%1 = tail call ptr @llvm.frameaddress(i32 0)
ret ptr %1
}

; Check the caller's frame address.
define ptr @fpcaller() nounwind "backchain" {
; CHECK-LABEL: fpcaller:
; CHECK: stmg 4, 7, 2048(4)
; CHECK-NEXT: lg 3, 2048(4)
; CHECK-NEXT: lmg 4, 7, 2048(4)
; CHECK-NEXT: b 2(7)
entry:
%0 = tail call ptr @llvm.frameaddress(i32 1)
ret ptr %0
}

; Check the caller's frame address.
define ptr @fpcallercaller() nounwind "backchain" {
; CHECK-LABEL: fpcallercaller:
; CHECK: stmg 4, 7, 2048(4)
; CHECK-NEXT: lg 1, 2048(4)
; CHECK-NEXT: lg 3, 0(1)
; CHECK-NEXT: lmg 4, 7, 2048(4)
; CHECK-NEXT: b 2(7)
entry:
%0 = tail call ptr @llvm.frameaddress(i32 2)
ret ptr %0
}

declare ptr @llvm.frameaddress(i32) nounwind readnone