-
Notifications
You must be signed in to change notification settings - Fork 10.8k
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
[SystemZ][z/OS] Implement llvm.frameaddr for XPLINK #89284
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The implementation follows the ELF implementation.
@llvm/pr-subscribers-backend-systemz Author: Kai Nacke (redstar) ChangesThe implementation follows the ELF implementation. Full diff: https://github.com/llvm/llvm-project/pull/89284.diff 4 Files Affected:
diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
index 50ecd6e0744147..6ec46bddb5dc2d 100644
--- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
@@ -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();
@@ -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];
@@ -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);
}
@@ -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);
+ }
}
}
diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.h b/llvm/lib/Target/SystemZ/SystemZFrameLowering.h
index 03ce8882c4de5d..46131819230702 100644
--- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.h
+++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.h
@@ -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 {
@@ -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 {
@@ -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
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index 5c2579f3bf1878..b3f93e334a9bd3 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -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);
diff --git a/llvm/test/CodeGen/SystemZ/zos-frameaddr.ll b/llvm/test/CodeGen/SystemZ/zos-frameaddr.ll
new file mode 100644
index 00000000000000..597731780676e9
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/zos-frameaddr.ll
@@ -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
|
uweigand
approved these changes
Apr 18, 2024
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
aniplcc
pushed a commit
to aniplcc/llvm-project
that referenced
this pull request
Apr 21, 2024
The implementation follows the ELF implementation.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The implementation follows the ELF implementation.