Skip to content

Commit 654cf77

Browse files
committed
[AIX] Add -msave-reg-params to save arguments to stack
In PowerPC ABI, a few initial arguments are passed through registers, but their places in parameter save area are reserved, arguments passed by memory goes after the reserved location. For debugging purpose, we may want to save copy of the pass-by-reg arguments into correct places on stack. The new option achieves by adding new function level attribute and make argument lowering part aware of it.
1 parent 0cfd03a commit 654cf77

File tree

9 files changed

+888
-8
lines changed

9 files changed

+888
-8
lines changed

clang/include/clang/Basic/CodeGenOptions.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,9 @@ CODEGENOPT(ForceAAPCSBitfieldLoad, 1, 0)
425425
/// Assume that by-value parameters do not alias any other values.
426426
CODEGENOPT(PassByValueIsNoAlias, 1, 0)
427427

428+
/// Whether to store register parameters to stack.
429+
CODEGENOPT(SaveRegParams, 1, 0)
430+
428431
/// Whether to not follow the AAPCS that enforces volatile bit-field access width to be
429432
/// according to the field declaring type width.
430433
CODEGENOPT(AAPCSBitfieldWidth, 1, 1)

clang/include/clang/Driver/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5040,6 +5040,10 @@ def mspe : Flag<["-"], "mspe">, Group<m_ppc_Features_Group>;
50405040
def mno_spe : Flag<["-"], "mno-spe">, Group<m_ppc_Features_Group>;
50415041
def mefpu2 : Flag<["-"], "mefpu2">, Group<m_ppc_Features_Group>;
50425042
} // let Flags = [TargetSpecific]
5043+
def msave_reg_params : Flag<["-"], "msave-reg-params">, Group<m_Group>,
5044+
Visibility<[ClangOption, CC1Option]>,
5045+
HelpText<"Save arguments passed by registers to stack">,
5046+
MarshallingInfoFlag<CodeGenOpts<"SaveRegParams">>;
50435047
def mabi_EQ_quadword_atomics : Flag<["-"], "mabi=quadword-atomics">,
50445048
Group<m_Group>, Visibility<[ClangOption, CC1Option]>,
50455049
HelpText<"Enable quadword atomics ABI on AIX (AIX PPC64 only). Uses lqarx/stqcx. instructions.">,

clang/lib/CodeGen/CGCall.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1931,6 +1931,9 @@ static void getTrivialDefaultFunctionAttributes(
19311931
if (CodeGenOpts.NullPointerIsValid)
19321932
FuncAttrs.addAttribute(llvm::Attribute::NullPointerIsValid);
19331933

1934+
if (CodeGenOpts.SaveRegParams)
1935+
FuncAttrs.addAttribute("save-reg-params");
1936+
19341937
if (LangOpts.getDefaultExceptionMode() == LangOptions::FPE_Ignore)
19351938
FuncAttrs.addAttribute("no-trapping-math", "true");
19361939

clang/lib/Driver/ToolChains/AIX.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,9 @@ void AIX::addClangTargetOptions(
548548
options::OPT_mtocdata))
549549
addTocDataOptions(Args, CC1Args, getDriver());
550550

551+
if (Args.hasArg(options::OPT_msave_reg_params))
552+
CC1Args.push_back("-msave-reg-params");
553+
551554
if (Args.hasFlag(options::OPT_fxl_pragma_pack,
552555
options::OPT_fno_xl_pragma_pack, true))
553556
CC1Args.push_back("-fxl-pragma-pack");
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu -emit-llvm -o - %s -msave-reg-params | FileCheck -check-prefix=SAVE %s
2+
// RUN: %clang_cc1 -triple powerpc64-ibm-aix -emit-llvm -o - %s -msave-reg-params | FileCheck -check-prefix=SAVE %s
3+
// RUN: %clang_cc1 -triple powerpc-ibm-aix -emit-llvm -o - %s -msave-reg-params | FileCheck -check-prefix=SAVE %s
4+
// RUN: %clang_cc1 -triple powerpc64le-unknown-linux-gnu -emit-llvm -o - %s | FileCheck -check-prefix=NOSAVE %s
5+
// RUN: %clang_cc1 -triple powerpc64-ibm-aix -emit-llvm -o - %s | FileCheck -check-prefix=NOSAVE %s
6+
// RUN: %clang_cc1 -triple powerpc-ibm-aix -emit-llvm -o - %s | FileCheck -check-prefix=NOSAVE %s
7+
8+
void bar(int);
9+
void foo(int x) { bar(x); }
10+
11+
// SAVE: attributes #{{[0-9]+}} = { {{.+}} "save-reg-params" {{.+}} }
12+
// NOSAVE-NOT: "save-reg-params"···

llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2496,15 +2496,19 @@ void PPCAIXAsmPrinter::emitTracebackTable() {
24962496

24972497
uint32_t GPRSaved = 0;
24982498

2499-
// X13 is reserved under 64-bit environment.
2500-
unsigned GPRBegin = Subtarget->isPPC64() ? PPC::X14 : PPC::R13;
2501-
unsigned GPREnd = Subtarget->isPPC64() ? PPC::X31 : PPC::R31;
2502-
2503-
for (unsigned Reg = GPRBegin; Reg <= GPREnd; ++Reg) {
2504-
if (MRI.isPhysRegModified(Reg)) {
2505-
GPRSaved = GPREnd - Reg + 1;
2506-
break;
2499+
if (FI->getForceGPRSaveCount() < 0) {
2500+
// X13 is reserved under 64-bit environment.
2501+
unsigned GPRBegin = Subtarget->isPPC64() ? PPC::X14 : PPC::R13;
2502+
unsigned GPREnd = Subtarget->isPPC64() ? PPC::X31 : PPC::R31;
2503+
2504+
for (unsigned Reg = GPRBegin; Reg <= GPREnd; ++Reg) {
2505+
if (MRI.isPhysRegModified(Reg)) {
2506+
GPRSaved = GPREnd - Reg + 1;
2507+
break;
2508+
}
25072509
}
2510+
} else {
2511+
GPRSaved = FI->getForceGPRSaveCount();
25082512
}
25092513

25102514
SecondHalfOfMandatoryField |= (GPRSaved << TracebackTable::GPRSavedShift) &

llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7224,6 +7224,8 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX(
72247224
// Reserve space for the linkage area on the stack.
72257225
const unsigned LinkageSize = Subtarget.getFrameLowering()->getLinkageSize();
72267226
CCInfo.AllocateStack(LinkageSize, Align(PtrByteSize));
7227+
uint64_t SaveStackPos = CCInfo.getStackSize();
7228+
bool SaveParams = MF.getFunction().hasFnAttribute("save-reg-params");
72277229
CCInfo.AnalyzeFormalArguments(Ins, CC_AIX);
72287230

72297231
SmallVector<SDValue, 8> MemOps;
@@ -7242,6 +7244,28 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX(
72427244
if (VA.isMemLoc() && VA.needsCustom() && ValVT.isFloatingPoint())
72437245
continue;
72447246

7247+
if (SaveParams && VA.isRegLoc() && !Flags.isByVal()) {
7248+
const TargetRegisterClass *RegClass = getRegClassForSVT(
7249+
LocVT.SimpleTy, IsPPC64, Subtarget.hasP8Vector(), Subtarget.hasVSX());
7250+
// On PPC64, we need to use std instead of stw for GPR.
7251+
MVT SaveVT = RegClass == &PPC::G8RCRegClass ? MVT::i64 : LocVT;
7252+
const Register VReg = MF.addLiveIn(VA.getLocReg(), RegClass);
7253+
SDValue Parm = DAG.getRegister(VReg, SaveVT);
7254+
int FI = MFI.CreateFixedObject(SaveVT.getStoreSize(), SaveStackPos, true);
7255+
SDValue FIN = DAG.getFrameIndex(FI, PtrVT);
7256+
SDValue StoreReg = DAG.getStore(Chain, dl, Parm, FIN,
7257+
MachinePointerInfo(), Align(PtrByteSize));
7258+
SaveStackPos = alignTo(SaveStackPos + SaveVT.getStoreSize(), PtrByteSize);
7259+
MemOps.push_back(StoreReg);
7260+
Chain = StoreReg;
7261+
}
7262+
7263+
if (SaveParams && (VA.isMemLoc() || Flags.isByVal())) {
7264+
unsigned StoreSize =
7265+
Flags.isByVal() ? Flags.getByValSize() : LocVT.getStoreSize();
7266+
SaveStackPos = alignTo(SaveStackPos + StoreSize, PtrByteSize);
7267+
}
7268+
72457269
auto HandleMemLoc = [&]() {
72467270
const unsigned LocSize = LocVT.getStoreSize();
72477271
const unsigned ValSize = ValVT.getStoreSize();
@@ -7454,6 +7478,11 @@ SDValue PPCTargetLowering::LowerFormalArguments_AIX(
74547478
FuncInfo->setMinReservedArea(CallerReservedArea);
74557479

74567480
if (isVarArg) {
7481+
// Maximum number of saved GPR in traceback table is 8, for varargs,
7482+
// assuming eight GPRs matches XL behavior.
7483+
if (SaveParams)
7484+
FuncInfo->setForceGPRSaveCount(8);
7485+
74577486
FuncInfo->setVarArgsFrameIndex(
74587487
MFI.CreateFixedObject(PtrByteSize, CCInfo.getStackSize(), true));
74597488
SDValue FIN = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);

llvm/lib/Target/PowerPC/PPCMachineFunctionInfo.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ class PPCFunctionInfo : public MachineFunctionInfo {
150150
/// to use SExt/ZExt flags in later optimization.
151151
std::vector<std::pair<Register, ISD::ArgFlagsTy>> LiveInAttrs;
152152

153+
/// Set a fixed number of saved GPRs, negative if it's non-fixed.
154+
int ForceGPRSaveCount = -1;
155+
153156
/// Flags for aix-shared-lib-tls-model-opt, will be lazily initialized for
154157
/// each function.
155158
bool AIXFuncUseTLSIEForLD = false;
@@ -163,6 +166,9 @@ class PPCFunctionInfo : public MachineFunctionInfo {
163166
const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB)
164167
const override;
165168

169+
int getForceGPRSaveCount() const { return ForceGPRSaveCount; }
170+
void setForceGPRSaveCount(int Num) { ForceGPRSaveCount = Num; }
171+
166172
int getFramePointerSaveIndex() const { return FramePointerSaveIndex; }
167173
void setFramePointerSaveIndex(int Idx) { FramePointerSaveIndex = Idx; }
168174

0 commit comments

Comments
 (0)