[PATCH] D77749: [PowerPC][Future] Remove redundant r2 save and restore for indirect call
Victor Huang via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 8 12:30:33 PDT 2020
NeHuang created this revision.
NeHuang added reviewers: nemanjai, stefanp, lei, hfinkel, power-llvm-team.
NeHuang added projects: LLVM, PowerPC.
Herald added subscribers: llvm-commits, shchenz, kbarton, hiraditya.
Currently an indirect call produces the following sequence on PCRelative mode:
extern void function( );
extern void (*ptrfunc) ( );
void g() {
ptrfunc=function;
}
void f() {
(*ptrfunc) ( );
}
Produce
paddi 3, 0, .LC0 at PCREL, 1
ld 3, 0(3)
std 2, 24(1)
ld 12, 0(3)
mtctr 12
bctrl
ld 2, 24(1)
Though the caller does not use or preserve r2, it is still saved and restored across a function call.
This patch is added to remove these redundant save and restores for indirect call.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D77749
Files:
llvm/lib/Target/PowerPC/PPCISelLowering.cpp
llvm/test/CodeGen/PowerPC/pcrel-got-indirect.ll
Index: llvm/test/CodeGen/PowerPC/pcrel-got-indirect.ll
===================================================================
--- llvm/test/CodeGen/PowerPC/pcrel-got-indirect.ll
+++ llvm/test/CodeGen/PowerPC/pcrel-got-indirect.ll
@@ -219,14 +219,12 @@
; CHECK-NEXT: mflr r0
; CHECK-NEXT: std r0, 16(r1)
; CHECK-NEXT: stdu r1, -32(r1)
-; CHECK-NEXT: std r2, 24(r1)
; CHECK-NEXT: .cfi_def_cfa_offset 32
; CHECK-NEXT: .cfi_offset lr, 16
; CHECK-NEXT: pld r3, ptrfunc at got@pcrel(0), 1
; CHECK-NEXT: ld r12, 0(r3)
; CHECK-NEXT: mtctr r12
; CHECK-NEXT: bctrl
-; CHECK-NEXT: ld 2, 24(r1)
; CHECK-NEXT: addi r1, r1, 32
; CHECK-NEXT: ld r0, 16(r1)
; CHECK-NEXT: mtlr r0
Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp
===================================================================
--- llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -5143,19 +5143,15 @@
// represents the 2 instruction sequence of an indirect branch and link,
// immediately followed by a load of the TOC pointer from the the stack save
// slot into gpr2.
- if (Subtarget.isAIXABI() || Subtarget.is64BitELFABI())
+ // For 64-bit ELF ABI PCREL, a indirect call does not need a TOC restore.
+ if (Subtarget.isAIXABI() ||
+ (Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls()))
return PPCISD::BCTRL_LOAD_TOC;
// An indirect call that does not need a TOC restore.
return PPCISD::BCTRL;
}
- // FIXME: At this moment indirect calls are treated ahead of the
- // PC Relative condition because binaries can still contain a possible
- // mix of functions that use a TOC and functions that do not use a TOC.
- // Once the PC Relative feature is complete this condition should be moved
- // up ahead of the indirect calls and should return a PPCISD::BCTRL for
- // that case.
if (Subtarget.isUsingPCRelativeCalls()) {
assert(Subtarget.is64BitELFABI() && "PC Relative is only on ELF ABI.");
return PPCISD::CALL_NOTOC;
@@ -5426,7 +5422,9 @@
// pointer from the linkage area. The operand for the TOC restore is an add
// of the TOC save offset to the stack pointer. This must be the second
// operand: after the chain input but before any other variadic arguments.
- if (Subtarget.is64BitELFABI() || Subtarget.isAIXABI()) {
+ // For 64-bit ELFv2 ABI PCRel, disable the code as TOC is not used.
+ if ((Subtarget.is64BitELFABI() && !Subtarget.isUsingPCRelativeCalls()) ||
+ Subtarget.isAIXABI()) {
const MCRegister StackPtrReg = Subtarget.getStackPointerRegister();
SDValue StackPtr = DAG.getRegister(StackPtrReg, RegVT);
@@ -6497,17 +6495,21 @@
// See prepareDescriptorIndirectCall and buildCallOperands for more
// information about calls through function pointers in the 64-bit SVR4 ABI.
if (CFlags.IsIndirect) {
- assert(!CFlags.IsTailCall && "Indirect tails calls not supported");
- // Load r2 into a virtual register and store it to the TOC save area.
- setUsesTOCBasePtr(DAG);
- SDValue Val = DAG.getCopyFromReg(Chain, dl, PPC::X2, MVT::i64);
- // TOC save area offset.
- unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
- SDValue PtrOff = DAG.getIntPtrConstant(TOCSaveOffset, dl);
- SDValue AddPtr = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr, PtrOff);
- Chain = DAG.getStore(
- Val.getValue(1), dl, Val, AddPtr,
- MachinePointerInfo::getStack(DAG.getMachineFunction(), TOCSaveOffset));
+ // When PCRel is enabled for 64-bit ELFv2 ABI, do not save the TOC of the
+ // caller in the TOC save area
+ if (!Subtarget.isUsingPCRelativeCalls()) {
+ assert(!CFlags.IsTailCall && "Indirect tails calls not supported");
+ // Load r2 into a virtual register and store it to the TOC save area.
+ setUsesTOCBasePtr(DAG);
+ SDValue Val = DAG.getCopyFromReg(Chain, dl, PPC::X2, MVT::i64);
+ // TOC save area offset.
+ unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();
+ SDValue PtrOff = DAG.getIntPtrConstant(TOCSaveOffset, dl);
+ SDValue AddPtr = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr, PtrOff);
+ Chain = DAG.getStore(Val.getValue(1), dl, Val, AddPtr,
+ MachinePointerInfo::getStack(
+ DAG.getMachineFunction(), TOCSaveOffset));
+ }
// In the ELFv2 ABI, R12 must contain the address of an indirect callee.
// This does not mean the MTCTR instruction must use R12; it's easier
// to model this as an extra parameter, so do that.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D77749.256082.patch
Type: text/x-patch
Size: 4638 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200408/bdfdfc47/attachment.bin>
More information about the llvm-commits
mailing list