Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit b4420ea

Browse files
author
Marcin Koscielnicki
committed
[SystemZ] Implement backchain attribute.
This introduces a SystemZ-specific "backchain" attribute on function, which enables writing the frame backchain link as specified by the ABI. This will be used to implement -mbackchain option in clang. Differential Revision: http://reviews.llvm.org/D19889 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268571 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 252a6d1 commit b4420ea

File tree

3 files changed

+130
-4
lines changed

3 files changed

+130
-4
lines changed

lib/Target/SystemZ/SystemZFrameLowering.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,15 @@ void SystemZFrameLowering::emitPrologue(MachineFunction &MF,
354354

355355
uint64_t StackSize = getAllocatedStackSize(MF);
356356
if (StackSize) {
357+
// Determine if we want to store a backchain.
358+
bool StoreBackchain = MF.getFunction()->hasFnAttribute("backchain");
359+
360+
// If we need backchain, save current stack pointer. R1 is free at this
361+
// point.
362+
if (StoreBackchain)
363+
BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::LGR))
364+
.addReg(SystemZ::R1D).addReg(SystemZ::R15D);
365+
357366
// Allocate StackSize bytes.
358367
int64_t Delta = -int64_t(StackSize);
359368
emitIncrement(MBB, MBBI, DL, SystemZ::R15D, Delta, ZII);
@@ -364,6 +373,10 @@ void SystemZFrameLowering::emitPrologue(MachineFunction &MF,
364373
BuildMI(MBB, MBBI, DL, ZII->get(TargetOpcode::CFI_INSTRUCTION))
365374
.addCFIIndex(CFIIndex);
366375
SPOffsetFromCFA += Delta;
376+
377+
if (StoreBackchain)
378+
BuildMI(MBB, MBBI, DL, ZII->get(SystemZ::STG))
379+
.addReg(SystemZ::R1D).addReg(SystemZ::R15D).addImm(0).addReg(0);
367380
}
368381

369382
if (HasFP) {

lib/Target/SystemZ/SystemZISelLowering.cpp

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2835,8 +2835,9 @@ SDValue SystemZTargetLowering::lowerVACOPY(SDValue Op,
28352835
SDValue SystemZTargetLowering::
28362836
lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const {
28372837
const TargetFrameLowering *TFI = Subtarget.getFrameLowering();
2838-
bool RealignOpt = !DAG.getMachineFunction().getFunction()->
2839-
hasFnAttribute("no-realign-stack");
2838+
MachineFunction &MF = DAG.getMachineFunction();
2839+
bool RealignOpt = !MF.getFunction()-> hasFnAttribute("no-realign-stack");
2840+
bool StoreBackchain = MF.getFunction()->hasFnAttribute("backchain");
28402841

28412842
SDValue Chain = Op.getOperand(0);
28422843
SDValue Size = Op.getOperand(1);
@@ -2858,6 +2859,12 @@ lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const {
28582859
// Get a reference to the stack pointer.
28592860
SDValue OldSP = DAG.getCopyFromReg(Chain, DL, SPReg, MVT::i64);
28602861

2862+
// If we need a backchain, save it now.
2863+
SDValue Backchain;
2864+
if (StoreBackchain)
2865+
Backchain = DAG.getLoad(MVT::i64, DL, Chain, OldSP, MachinePointerInfo(),
2866+
false, false, false, 0);
2867+
28612868
// Add extra space for alignment if needed.
28622869
if (ExtraAlignSpace)
28632870
NeededSpace = DAG.getNode(ISD::ADD, DL, MVT::i64, NeededSpace,
@@ -2885,6 +2892,10 @@ lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const {
28852892
DAG.getConstant(~(RequiredAlign - 1), DL, MVT::i64));
28862893
}
28872894

2895+
if (StoreBackchain)
2896+
Chain = DAG.getStore(Chain, DL, Backchain, NewSP, MachinePointerInfo(),
2897+
false, false, 0);
2898+
28882899
SDValue Ops[2] = { Result, Chain };
28892900
return DAG.getMergeValues(Ops, DL);
28902901
}
@@ -3336,8 +3347,26 @@ SDValue SystemZTargetLowering::lowerSTACKRESTORE(SDValue Op,
33363347
SelectionDAG &DAG) const {
33373348
MachineFunction &MF = DAG.getMachineFunction();
33383349
MF.getInfo<SystemZMachineFunctionInfo>()->setManipulatesSP(true);
3339-
return DAG.getCopyToReg(Op.getOperand(0), SDLoc(Op),
3340-
SystemZ::R15D, Op.getOperand(1));
3350+
bool StoreBackchain = MF.getFunction()->hasFnAttribute("backchain");
3351+
3352+
SDValue Chain = Op.getOperand(0);
3353+
SDValue NewSP = Op.getOperand(1);
3354+
SDValue Backchain;
3355+
SDLoc DL(Op);
3356+
3357+
if (StoreBackchain) {
3358+
SDValue OldSP = DAG.getCopyFromReg(Chain, DL, SystemZ::R15D, MVT::i64);
3359+
Backchain = DAG.getLoad(MVT::i64, DL, Chain, OldSP, MachinePointerInfo(),
3360+
false, false, false, 0);
3361+
}
3362+
3363+
Chain = DAG.getCopyToReg(Chain, DL, SystemZ::R15D, NewSP);
3364+
3365+
if (StoreBackchain)
3366+
Chain = DAG.getStore(Chain, DL, Backchain, NewSP, MachinePointerInfo(),
3367+
false, false, 0);
3368+
3369+
return Chain;
33413370
}
33423371

33433372
SDValue SystemZTargetLowering::lowerPREFETCH(SDValue Op,

test/CodeGen/SystemZ/backchain.ll

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
; Test the backchain attribute.
2+
;
3+
; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4+
5+
declare i8 *@llvm.stacksave()
6+
declare void @llvm.stackrestore(i8 *)
7+
declare void @g()
8+
9+
; nothing should happen if no stack frame is needed.
10+
define void @f1() "backchain" {
11+
; CHECK-LABEL: f1:
12+
; CHECK-NOT: stg
13+
ret void
14+
}
15+
16+
; check that backchain is saved if we call someone
17+
define void @f2() "backchain" {
18+
; CHECK-LABEL: f2:
19+
; CHECK: stmg %r14, %r15, 112(%r15)
20+
; CHECK: lgr %r1, %r15
21+
; CHECK: aghi %r15, -160
22+
; CHECK: stg %r1, 0(%r15)
23+
call void @g()
24+
call void @g()
25+
ret void
26+
}
27+
28+
; check that backchain is saved if we have an alloca
29+
define void @f3() "backchain" {
30+
; CHECK-LABEL: f3:
31+
; CHECK-NOT: stmg
32+
; CHECK: lgr %r1, %r15
33+
; CHECK: aghi %r15, -168
34+
; CHECK: stg %r1, 0(%r15)
35+
%ign = alloca i8, i32 4
36+
ret void
37+
}
38+
39+
; check that alloca copies the backchain
40+
define void @f4(i32 %len) "backchain" {
41+
; CHECK-LABEL: f4:
42+
; CHECK: stmg %r11, %r15, 88(%r15)
43+
; CHECK: lgr %r1, %r15
44+
; CHECK: aghi %r15, -160
45+
; CHECK: stg %r1, 0(%r15)
46+
; CHECK: lgr %r11, %r15
47+
; CHECK: lg [[BC:%r[0-9]+]], 0(%r15)
48+
; CHECK: lgr [[NEWSP:%r[0-9]+]], %r15
49+
; CHECK: lgr %r15, [[NEWSP]]
50+
; CHECK: stg [[BC]], 0([[NEWSP]])
51+
%ign = alloca i8, i32 %len
52+
ret void
53+
}
54+
55+
; check that llvm.stackrestore restores the backchain
56+
define void @f5(i32 %count1, i32 %count2) "backchain" {
57+
; CHECK-LABEL: f5:
58+
; CHECK: stmg %r11, %r15, 88(%r15)
59+
; CHECK: lgr %r1, %r15
60+
; CHECK: aghi %r15, -160
61+
; CHECK: stg %r1, 0(%r15)
62+
; CHECK: lgr %r11, %r15
63+
; CHECK: lgr [[SAVESP:%r[0-9]+]], %r15
64+
; CHECK: lg [[BC:%r[0-9]+]], 0(%r15)
65+
; CHECK: lgr [[NEWSP:%r[0-9]+]], %r15
66+
; CHECK: lgr %r15, [[NEWSP]]
67+
; CHECK: stg [[BC]], 0([[NEWSP]])
68+
; CHECK: lg [[BC2:%r[0-9]+]], 0(%r15)
69+
; CHECK: lgr %r15, [[SAVESP]]
70+
; CHECK: stg [[BC2]], 0([[SAVESP]])
71+
; CHECK: lg [[BC3:%r[0-9]+]], 0(%r15)
72+
; CHECK: lgr [[NEWSP2:%r[0-9]+]], %r15
73+
; CHECK: lgr %r15, [[NEWSP2]]
74+
; CHECK: stg [[BC3]], 0([[NEWSP2]])
75+
; CHECK: lmg %r11, %r15, 248(%r11)
76+
; CHECK: br %r14
77+
%src = call i8 *@llvm.stacksave()
78+
%array1 = alloca i8, i32 %count1
79+
store volatile i8 0, i8 *%array1
80+
call void @llvm.stackrestore(i8 *%src)
81+
%array2 = alloca i8, i32 %count2
82+
store volatile i8 0, i8 *%array2
83+
ret void
84+
}

0 commit comments

Comments
 (0)