Index: lib/Target/X86/X86.td =================================================================== RCS file: /cvs/src/gnu/llvm/lib/Target/X86/X86.td,v retrieving revision 1.1.1.3 diff -u -p -r1.1.1.3 X86.td --- lib/Target/X86/X86.td 24 Jan 2017 08:33:28 -0000 1.1.1.3 +++ lib/Target/X86/X86.td 26 Apr 2017 07:32:18 -0000 @@ -246,6 +246,9 @@ def FeatureSlowIncDec : SubtargetFeature def FeatureSoftFloat : SubtargetFeature<"soft-float", "UseSoftFloat", "true", "Use software floating point features.">; +def FeatureSaveArgs + : SubtargetFeature<"save-args", "SaveArgs", "true", + "Save register arguments on the stack.">; // On at least some AMD processors, there is no performance hazard to writing // only the lower parts of a YMM register without clearing the upper part. def FeatureFastPartialYMMWrite Index: lib/Target/X86/X86FrameLowering.cpp =================================================================== RCS file: /cvs/src/gnu/llvm/lib/Target/X86/X86FrameLowering.cpp,v retrieving revision 1.1.1.3 diff -u -p -r1.1.1.3 X86FrameLowering.cpp --- lib/Target/X86/X86FrameLowering.cpp 24 Jan 2017 08:33:28 -0000 1.1.1.3 +++ lib/Target/X86/X86FrameLowering.cpp 26 Apr 2017 07:32:18 -0000 @@ -47,6 +47,7 @@ X86FrameLowering::X86FrameLowering(const // standard x86_64 and NaCl use 64-bit frame/stack pointers, x32 - 32-bit. Uses64BitFramePtr = STI.isTarget64BitLP64() || STI.isTargetNaCl64(); StackPtr = TRI->getStackRegister(); + SaveArgs = STI.getSaveArgs(); } bool X86FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { @@ -90,7 +91,8 @@ bool X86FrameLowering::hasFP(const Machi MF.getInfo()->getForceFramePointer() || MF.callsUnwindInit() || MF.hasEHFunclets() || MF.callsEHReturn() || MFI.hasStackMap() || MFI.hasPatchPoint() || - MFI.hasCopyImplyingStackAdjustment()); + MFI.hasCopyImplyingStackAdjustment() || + SaveArgs); } static unsigned getSUBriOpcode(unsigned IsLP64, int64_t Imm) { @@ -821,6 +823,25 @@ void X86FrameLowering::BuildStackAlignAN MI->getOperand(3).setIsDead(); } +// FIXME: Get this from tablegen. +static ArrayRef get64BitArgumentGPRs(CallingConv::ID CallConv, + const X86Subtarget &Subtarget) { + assert(Subtarget.is64Bit()); + + if (Subtarget.isCallingConvWin64(CallConv)) { + static const MCPhysReg GPR64ArgRegsWin64[] = { + X86::RCX, X86::RDX, X86::R8, X86::R9 + }; + return makeArrayRef(std::begin(GPR64ArgRegsWin64), std::end(GPR64ArgRegsWin64)); + } + + static const MCPhysReg GPR64ArgRegs64Bit[] = { + X86::RDI, X86::RSI, X86::RDX, X86::RCX, X86::R8, X86::R9 + }; + return makeArrayRef(std::begin(GPR64ArgRegs64Bit), std::end(GPR64ArgRegs64Bit)); +} + + /// emitPrologue - Push callee-saved registers onto the stack, which /// automatically adjust the stack pointer. Adjust the stack pointer to allocate /// space for local variables. Also emit labels used by the exception handler to @@ -1083,6 +1104,32 @@ void X86FrameLowering::emitPrologue(Mach unsigned DwarfFramePtr = TRI->getDwarfRegNum(MachineFramePtr, true); BuildCFI(MBB, MBBI, DL, MCCFIInstruction::createDefCfaRegister( nullptr, DwarfFramePtr)); + } + + /* XXX dlg */ + if (SaveArgs) { + ArrayRef GPRs = + get64BitArgumentGPRs(Fn->getCallingConv(), STI); + unsigned arg_size = Fn->arg_size(); + unsigned RI = 0; + int64_t SaveSize = 0; + + for (MCPhysReg Reg : GPRs) { + if (++RI > arg_size) + break; + + SaveSize += 8; + + // MOV64mr Reg, -SaveSize(%rbp) + addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64mr)), + FramePtr, true, -SaveSize) + .addReg(Reg) + //.setMIFlag(MachineInstr::FrameSetup) + ; + } + + MFI.setStackSize(StackSize + SaveSize); + NumBytes += SaveSize; } } Index: lib/Target/X86/X86FrameLowering.h =================================================================== RCS file: /cvs/src/gnu/llvm/lib/Target/X86/X86FrameLowering.h,v retrieving revision 1.1.1.3 diff -u -p -r1.1.1.3 X86FrameLowering.h --- lib/Target/X86/X86FrameLowering.h 24 Jan 2017 08:33:27 -0000 1.1.1.3 +++ lib/Target/X86/X86FrameLowering.h 26 Apr 2017 07:32:18 -0000 @@ -33,6 +33,8 @@ public: const TargetInstrInfo &TII; const X86RegisterInfo *TRI; + bool SaveArgs; + unsigned SlotSize; /// Is64Bit implies that x86_64 instructions are available. Index: lib/Target/X86/X86Subtarget.cpp =================================================================== RCS file: /cvs/src/gnu/llvm/lib/Target/X86/X86Subtarget.cpp,v retrieving revision 1.1.1.4 diff -u -p -r1.1.1.4 X86Subtarget.cpp --- lib/Target/X86/X86Subtarget.cpp 14 Mar 2017 08:08:07 -0000 1.1.1.4 +++ lib/Target/X86/X86Subtarget.cpp 26 Apr 2017 07:32:18 -0000 @@ -298,6 +298,7 @@ void X86Subtarget::initializeEnvironment SlowLEA = false; SlowIncDec = false; stackAlignment = 4; + SaveArgs = false; // FIXME: this is a known good value for Yonah. How about others? MaxInlineSizeThreshold = 128; UseSoftFloat = false; Index: lib/Target/X86/X86Subtarget.h =================================================================== RCS file: /cvs/src/gnu/llvm/lib/Target/X86/X86Subtarget.h,v retrieving revision 1.1.1.3 diff -u -p -r1.1.1.3 X86Subtarget.h --- lib/Target/X86/X86Subtarget.h 24 Jan 2017 08:33:27 -0000 1.1.1.3 +++ lib/Target/X86/X86Subtarget.h 26 Apr 2017 07:32:18 -0000 @@ -293,6 +293,9 @@ protected: /// entry to the function and which must be maintained by every function. unsigned stackAlignment; + /// Whether function prologues should save register arguments on the stack. + bool SaveArgs; + /// Max. memset / memcpy size that is turned into rep/movs, rep/stos ops. /// unsigned MaxInlineSizeThreshold; @@ -351,6 +354,8 @@ public: const X86RegisterInfo *getRegisterInfo() const override { return &getInstrInfo()->getRegisterInfo(); } + + bool getSaveArgs() const { return SaveArgs; } /// Returns the minimum alignment known to hold of the /// stack frame on entry to the function and which must be maintained by every Index: tools/clang/include/clang/Driver/Options.td =================================================================== RCS file: /cvs/src/gnu/llvm/tools/clang/include/clang/Driver/Options.td,v retrieving revision 1.4 diff -u -p -r1.4 Options.td --- tools/clang/include/clang/Driver/Options.td 24 Jan 2017 08:39:08 -0000 1.4 +++ tools/clang/include/clang/Driver/Options.td 26 Apr 2017 07:32:18 -0000 @@ -1747,6 +1747,7 @@ def mpie_copy_relocations : Flag<["-"], Flags<[CC1Option]>, HelpText<"Use copy relocations support for PIE builds">; def mno_pie_copy_relocations : Flag<["-"], "mno-pie-copy-relocations">, Group; +def msave_args : Flag<["-"], "msave-args">, Group; def mx87 : Flag<["-"], "mx87">, Group; def m80387 : Flag<["-"], "m80387">, Alias; def msse2 : Flag<["-"], "msse2">, Group;