[llvm] 7e2c298 - [SystemZ][z/OS] Implement llvm.frameaddr for XPLINK (#89284)

via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 19 05:09:53 PDT 2024


Author: Kai Nacke
Date: 2024-04-19T08:09:49-04:00
New Revision: 7e2c2981fbb9e609886cfbe6c95644ed58b03d08

URL: https://github.com/llvm/llvm-project/commit/7e2c2981fbb9e609886cfbe6c95644ed58b03d08
DIFF: https://github.com/llvm/llvm-project/commit/7e2c2981fbb9e609886cfbe6c95644ed58b03d08.diff

LOG: [SystemZ][z/OS] Implement llvm.frameaddr for XPLINK (#89284)

The implementation follows the ELF implementation.

Added: 
    llvm/test/CodeGen/SystemZ/zos-frameaddr.ll

Modified: 
    llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
    llvm/lib/Target/SystemZ/SystemZFrameLowering.h
    llvm/lib/Target/SystemZ/SystemZISelLowering.cpp

Removed: 
    


################################################################################
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


        


More information about the llvm-commits mailing list