Skip to content

Commit d79fff0

Browse files
authored
[SystemZ] Add backchain target-feature (llvm#71668)
GCC supports building individual functions with backchain using the __attribute__((target("backchain"))) syntax, and Clang should too. Clang translates this into the "target-features"="+backchain" attribute, and the -mbackchain command-line option into the "backchain" attribute. The backend currently checks only the latter; furthermore, the backchain target feature is not defined. Handle backchain like soft-float. Define a target feature, convert function attribute into it in getSubtargetImpl(), and check for target feature instead of function attribute everywhere. Add an end-to-end test to the Clang testsuite.
1 parent 0d48a46 commit d79fff0

File tree

5 files changed

+36
-16
lines changed

5 files changed

+36
-16
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %clang --target=s390x-linux -O1 -S -o - %s | FileCheck %s
2+
3+
__attribute__((target("backchain")))
4+
void *foo(void) {
5+
return __builtin_return_address(1);
6+
}
7+
8+
// CHECK-LABEL: foo:
9+
// CHECK: lg %r1, 0(%r15)
10+
// CHECK: lg %r2, 112(%r1)
11+
// CHECK: br %r14

llvm/lib/Target/SystemZ/SystemZFeatures.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ def FeatureSoftFloat : SystemZFeature<
3232
"Use software emulation for floating point"
3333
>;
3434

35+
def FeatureBackChain : SystemZFeature<
36+
"backchain", "BackChain", (all_of FeatureBackChain),
37+
"Store the address of the caller's frame into the callee's stack frame"
38+
>;
39+
3540
//===----------------------------------------------------------------------===//
3641
//
3742
// New features added in the Ninth Edition of the z/Architecture

llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ void SystemZELFFrameLowering::processFunctionBeforeFrameFinalized(
443443
MachineFrameInfo &MFFrame = MF.getFrameInfo();
444444
SystemZMachineFunctionInfo *ZFI = MF.getInfo<SystemZMachineFunctionInfo>();
445445
MachineRegisterInfo *MRI = &MF.getRegInfo();
446-
bool BackChain = MF.getFunction().hasFnAttribute("backchain");
446+
bool BackChain = MF.getSubtarget<SystemZSubtarget>().hasBackChain();
447447

448448
if (!usePackedStack(MF) || BackChain)
449449
// Create the incoming register save area.
@@ -628,7 +628,7 @@ void SystemZELFFrameLowering::emitPrologue(MachineFunction &MF,
628628
.addImm(StackSize);
629629
}
630630
else {
631-
bool StoreBackchain = MF.getFunction().hasFnAttribute("backchain");
631+
bool StoreBackchain = MF.getSubtarget<SystemZSubtarget>().hasBackChain();
632632
// If we need backchain, save current stack pointer. R1 is free at
633633
// this point.
634634
if (StoreBackchain)
@@ -786,7 +786,7 @@ void SystemZELFFrameLowering::inlineStackProbe(
786786
.addMemOperand(MMO);
787787
};
788788

789-
bool StoreBackchain = MF.getFunction().hasFnAttribute("backchain");
789+
bool StoreBackchain = MF.getSubtarget<SystemZSubtarget>().hasBackChain();
790790
if (StoreBackchain)
791791
BuildMI(*MBB, MBBI, DL, ZII->get(SystemZ::LGR))
792792
.addReg(SystemZ::R1D, RegState::Define).addReg(SystemZ::R15D);
@@ -861,8 +861,9 @@ StackOffset SystemZELFFrameLowering::getFrameIndexReference(
861861
unsigned SystemZELFFrameLowering::getRegSpillOffset(MachineFunction &MF,
862862
Register Reg) const {
863863
bool IsVarArg = MF.getFunction().isVarArg();
864-
bool BackChain = MF.getFunction().hasFnAttribute("backchain");
865-
bool SoftFloat = MF.getSubtarget<SystemZSubtarget>().hasSoftFloat();
864+
const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>();
865+
bool BackChain = Subtarget.hasBackChain();
866+
bool SoftFloat = Subtarget.hasSoftFloat();
866867
unsigned Offset = RegSpillOffsets[Reg];
867868
if (usePackedStack(MF) && !(IsVarArg && !SoftFloat)) {
868869
if (SystemZ::GR64BitRegClass.contains(Reg))
@@ -890,8 +891,9 @@ int SystemZELFFrameLowering::getOrCreateFramePointerSaveIndex(
890891

891892
bool SystemZELFFrameLowering::usePackedStack(MachineFunction &MF) const {
892893
bool HasPackedStackAttr = MF.getFunction().hasFnAttribute("packed-stack");
893-
bool BackChain = MF.getFunction().hasFnAttribute("backchain");
894-
bool SoftFloat = MF.getSubtarget<SystemZSubtarget>().hasSoftFloat();
894+
const SystemZSubtarget &Subtarget = MF.getSubtarget<SystemZSubtarget>();
895+
bool BackChain = Subtarget.hasBackChain();
896+
bool SoftFloat = Subtarget.hasSoftFloat();
895897
if (HasPackedStackAttr && BackChain && !SoftFloat)
896898
report_fatal_error("packed-stack + backchain + hard-float is unsupported.");
897899
bool CallConv = MF.getFunction().getCallingConv() != CallingConv::GHC;
@@ -946,7 +948,7 @@ static bool isXPLeafCandidate(const MachineFunction &MF) {
946948
return false;
947949

948950
// If the backchain pointer should be stored, then it is not a XPLeaf routine.
949-
if (MF.getFunction().hasFnAttribute("backchain"))
951+
if (MF.getSubtarget<SystemZSubtarget>().hasBackChain())
950952
return false;
951953

952954
// If function acquires its own stack frame, then it is not a XPLeaf routine.
@@ -989,7 +991,7 @@ bool SystemZXPLINKFrameLowering::assignCalleeSavedSpillSlots(
989991

990992
// If the function needs a frame pointer, or if the backchain pointer should
991993
// be stored, then save the stack pointer register R4.
992-
if (hasFP(MF) || MF.getFunction().hasFnAttribute("backchain"))
994+
if (hasFP(MF) || Subtarget.hasBackChain())
993995
CSI.push_back(CalleeSavedInfo(Regs.getStackPointerRegister()));
994996

995997
// Scan the call-saved GPRs and find the bounds of the register spill area.

llvm/lib/Target/SystemZ/SystemZISelLowering.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3631,7 +3631,7 @@ SDValue SystemZTargetLowering::lowerFRAMEADDR(SDValue Op,
36313631

36323632
if (Depth > 0) {
36333633
// FIXME The frontend should detect this case.
3634-
if (!MF.getFunction().hasFnAttribute("backchain"))
3634+
if (!MF.getSubtarget<SystemZSubtarget>().hasBackChain())
36353635
report_fatal_error("Unsupported stack frame traversal count");
36363636

36373637
SDValue Offset = DAG.getConstant(TFL->getBackchainOffset(MF), DL, PtrVT);
@@ -3660,7 +3660,7 @@ SDValue SystemZTargetLowering::lowerRETURNADDR(SDValue Op,
36603660

36613661
if (Depth > 0) {
36623662
// FIXME The frontend should detect this case.
3663-
if (!MF.getFunction().hasFnAttribute("backchain"))
3663+
if (!MF.getSubtarget<SystemZSubtarget>().hasBackChain())
36643664
report_fatal_error("Unsupported stack frame traversal count");
36653665

36663666
SDValue FrameAddr = lowerFRAMEADDR(Op, DAG);
@@ -3886,7 +3886,7 @@ SystemZTargetLowering::lowerDYNAMIC_STACKALLOC_ELF(SDValue Op,
38863886
const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
38873887
MachineFunction &MF = DAG.getMachineFunction();
38883888
bool RealignOpt = !MF.getFunction().hasFnAttribute("no-realign-stack");
3889-
bool StoreBackchain = MF.getFunction().hasFnAttribute("backchain");
3889+
bool StoreBackchain = MF.getSubtarget<SystemZSubtarget>().hasBackChain();
38903890

38913891
SDValue Chain = Op.getOperand(0);
38923892
SDValue Size = Op.getOperand(1);
@@ -4563,7 +4563,7 @@ SDValue SystemZTargetLowering::lowerSTACKRESTORE(SDValue Op,
45634563
SelectionDAG &DAG) const {
45644564
MachineFunction &MF = DAG.getMachineFunction();
45654565
auto *Regs = Subtarget.getSpecialRegisters();
4566-
bool StoreBackchain = MF.getFunction().hasFnAttribute("backchain");
4566+
bool StoreBackchain = MF.getSubtarget<SystemZSubtarget>().hasBackChain();
45674567

45684568
if (MF.getFunction().getCallingConv() == CallingConv::GHC)
45694569
report_fatal_error("Variable-sized stack allocations are not supported "

llvm/lib/Target/SystemZ/SystemZTargetMachine.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,14 @@ SystemZTargetMachine::getSubtargetImpl(const Function &F) const {
169169
FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS;
170170

171171
// FIXME: This is related to the code below to reset the target options,
172-
// we need to know whether or not the soft float flag is set on the
173-
// function, so we can enable it as a subtarget feature.
172+
// we need to know whether the soft float and backchain flags are set on the
173+
// function, so we can enable them as subtarget features.
174174
bool SoftFloat = F.getFnAttribute("use-soft-float").getValueAsBool();
175-
176175
if (SoftFloat)
177176
FS += FS.empty() ? "+soft-float" : ",+soft-float";
177+
bool BackChain = F.hasFnAttribute("backchain");
178+
if (BackChain)
179+
FS += FS.empty() ? "+backchain" : ",+backchain";
178180

179181
auto &I = SubtargetMap[CPU + TuneCPU + FS];
180182
if (!I) {

0 commit comments

Comments
 (0)