Index: include/llvm/BinaryFormat/Dwarf.def =================================================================== RCS file: /cvs/src/gnu/llvm/include/llvm/BinaryFormat/Dwarf.def,v retrieving revision 1.1.1.2 diff -u -p -r1.1.1.2 Dwarf.def --- include/llvm/BinaryFormat/Dwarf.def 6 Apr 2018 14:26:05 -0000 1.1.1.2 +++ include/llvm/BinaryFormat/Dwarf.def 2 Jun 2018 13:24:56 -0000 @@ -351,6 +351,8 @@ HANDLE_DW_AT(0x2133, GNU_addr_base, 0, G HANDLE_DW_AT(0x2134, GNU_pubnames, 0, GNU) HANDLE_DW_AT(0x2135, GNU_pubtypes, 0, GNU) HANDLE_DW_AT(0x2136, GNU_discriminator, 0, GNU) +// Sun Extension +HANDLE_DW_AT(0x2224, SUN_amd64_parmdump, 0, GNU) // Borland extensions. HANDLE_DW_AT(0x3b11, BORLAND_property_read, 0, BORLAND) HANDLE_DW_AT(0x3b12, BORLAND_property_write, 0, BORLAND) Index: lib/Target/X86/X86.td =================================================================== RCS file: /cvs/src/gnu/llvm/lib/Target/X86/X86.td,v retrieving revision 1.1.1.5 diff -u -p -r1.1.1.5 X86.td --- lib/Target/X86/X86.td 6 Apr 2018 14:26:11 -0000 1.1.1.5 +++ lib/Target/X86/X86.td 2 Jun 2018 13:24:57 -0000 @@ -263,6 +263,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 recent X86 (port bound) processors, its preferable to combine to a single shuffle // using a variable mask over multiple fixed shuffles. def FeatureFastVariableShuffle Index: lib/Target/X86/X86FrameLowering.cpp =================================================================== RCS file: /cvs/src/gnu/llvm/lib/Target/X86/X86FrameLowering.cpp,v retrieving revision 1.1.1.5 diff -u -p -r1.1.1.5 X86FrameLowering.cpp --- lib/Target/X86/X86FrameLowering.cpp 6 Apr 2018 14:26:11 -0000 1.1.1.5 +++ lib/Target/X86/X86FrameLowering.cpp 2 Jun 2018 13:24:57 -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) { @@ -848,6 +850,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 @@ -1130,6 +1151,43 @@ void X86FrameLowering::emitPrologue(Mach nullptr, DwarfFramePtr)); } + if (SaveArgs && !Fn.arg_empty()) { + ArrayRef GPRs = + get64BitArgumentGPRs(Fn.getCallingConv(), STI); + unsigned arg_size = Fn.arg_size(); + unsigned RI = 0; + int64_t SaveSize = 0; + + if (Fn.hasStructRetAttr()) { + GPRs = GPRs.drop_front(1); + } + + for (MCPhysReg Reg : GPRs) { + if (++RI > arg_size) + break; + + SaveSize += SlotSize; + +#if 1 + BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH64r)) + .addReg(Reg) + .setMIFlag(MachineInstr::FrameSetup); +#else + // MOV64mr Reg, -SaveSize(%rbp) + addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64mr)), + FramePtr, true, -SaveSize) + .addReg(Reg) + .setMIFlag(MachineInstr::FrameSetup); +#endif + } + + X86FI->setSaveArgSize(SaveSize); + SaveSize = alignTo(SaveSize, getStackAlignment()); + + StackSize += SaveSize % getStackAlignment(); + MFI.setStackSize(StackSize); + } + if (NeedsWinFPO) { // .cv_fpo_setframe $FramePtr HasWinCFI = true; @@ -1551,7 +1609,7 @@ void X86FrameLowering::emitEpilogue(Mach const bool Is64BitILP32 = STI.isTarget64BitILP32(); unsigned FramePtr = TRI->getFrameRegister(MF); unsigned MachineFramePtr = - Is64BitILP32 ? getX86SubSuperRegister(FramePtr, 64) : FramePtr; + Is64BitILP32 ? getX86SubSuperRegister(FramePtr, 64) : FramePtr; bool IsWin64Prologue = MF.getTarget().getMCAsmInfo()->usesWindowsCFI(); bool NeedsWin64CFI = @@ -1582,17 +1640,11 @@ void X86FrameLowering::emitEpilogue(Mach } uint64_t SEHStackAllocAmt = NumBytes; - if (HasFP) { - // Pop EBP. - BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r), - MachineFramePtr) - .setMIFlag(MachineInstr::FrameDestroy); - } - - MachineBasicBlock::iterator FirstCSPop = MBBI; + MachineBasicBlock::iterator CSI = MBBI; + MachineBasicBlock::iterator FirstCSPop = CSI; // Skip the callee-saved pop instructions. - while (MBBI != MBB.begin()) { - MachineBasicBlock::iterator PI = std::prev(MBBI); + while (CSI != MBB.begin()) { + MachineBasicBlock::iterator PI = std::prev(CSI); unsigned Opc = PI->getOpcode(); if (Opc != X86::DBG_VALUE && !PI->isTerminator()) { @@ -1602,8 +1654,33 @@ void X86FrameLowering::emitEpilogue(Mach FirstCSPop = PI; } - --MBBI; + --CSI; + } + + if (HasFP) { +#if 0 + BuildMI(MBB, MBBI, DL, TII.get(X86::LEAVE64), 0) + .setMIFlag(MachineInstr::FrameDestroy); + unsigned SaveSize = X86FI->getSaveArgSize(); + if (SaveSize) { +#if 1 + BuildMI(MBB, MBBI, DL, TII.get(X86::LEAVE64), 0) + .setMIFlag(MachineInstr::FrameDestroy); + +// emitSPUpdate(MBB, MBBI, SaveSize, /*InEpilogue=*/true); +#else + addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64rm), + MachineFramePtr), StackPtr, true, SaveSize) + .setMIFlag(MachineInstr::FrameDestroy); +#endif + } else { +#endif + // Pop EBP. + BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::LEAVE64 : X86::POP32r), + MachineFramePtr) + .setMIFlag(MachineInstr::FrameDestroy); } + MBBI = FirstCSPop; if (IsFunclet && Terminator->getOpcode() == X86::CATCHRET) @@ -1647,10 +1724,12 @@ void X86FrameLowering::emitEpilogue(Mach .addReg(FramePtr); --MBBI; } +#if 0 } else if (NumBytes) { // Adjust stack pointer back: ESP += numbytes. - emitSPUpdate(MBB, MBBI, NumBytes, /*InEpilogue=*/true); + emitSPUpdate(MBB, MBBI, NumBytes * 8, /*InEpilogue=*/true); --MBBI; +#endif } // Windows unwinder will not invoke function's exception handler if IP is Index: lib/Target/X86/X86FrameLowering.h =================================================================== RCS file: /cvs/src/gnu/llvm/lib/Target/X86/X86FrameLowering.h,v retrieving revision 1.1.1.5 diff -u -p -r1.1.1.5 X86FrameLowering.h --- lib/Target/X86/X86FrameLowering.h 6 Apr 2018 14:26:11 -0000 1.1.1.5 +++ lib/Target/X86/X86FrameLowering.h 2 Jun 2018 13:24:57 -0000 @@ -34,6 +34,8 @@ public: const X86InstrInfo &TII; const X86RegisterInfo *TRI; + bool SaveArgs; + unsigned SlotSize; /// Is64Bit implies that x86_64 instructions are available. Index: lib/Target/X86/X86MachineFunctionInfo.h =================================================================== RCS file: /cvs/src/gnu/llvm/lib/Target/X86/X86MachineFunctionInfo.h,v retrieving revision 1.1.1.2 diff -u -p -r1.1.1.2 X86MachineFunctionInfo.h --- lib/Target/X86/X86MachineFunctionInfo.h 14 Jan 2017 19:56:06 -0000 1.1.1.2 +++ lib/Target/X86/X86MachineFunctionInfo.h 2 Jun 2018 13:24:57 -0000 @@ -41,6 +41,10 @@ class X86MachineFunctionInfo : public Ma /// stack frame in bytes. unsigned CalleeSavedFrameSize = 0; + // SaveArgSize - Amount of space used on the stack to save register + // arguments. + unsigned SaveArgSize = 0; + /// BytesToPopOnReturn - Number of bytes function pops on return (in addition /// to the space used by the return address). /// Used on windows platform for stdcall & fastcall name decoration @@ -123,6 +127,9 @@ public: unsigned getCalleeSavedFrameSize() const { return CalleeSavedFrameSize; } void setCalleeSavedFrameSize(unsigned bytes) { CalleeSavedFrameSize = bytes; } + + unsigned getSaveArgSize() const { return SaveArgSize; } + void setSaveArgSize(unsigned bytes) { SaveArgSize = bytes; } unsigned getBytesToPopOnReturn() const { return BytesToPopOnReturn; } void setBytesToPopOnReturn (unsigned bytes) { BytesToPopOnReturn = bytes;} Index: lib/Target/X86/X86Subtarget.cpp =================================================================== RCS file: /cvs/src/gnu/llvm/lib/Target/X86/X86Subtarget.cpp,v retrieving revision 1.1.1.6 diff -u -p -r1.1.1.6 X86Subtarget.cpp --- lib/Target/X86/X86Subtarget.cpp 6 Apr 2018 14:26:11 -0000 1.1.1.6 +++ lib/Target/X86/X86Subtarget.cpp 2 Jun 2018 13:24:57 -0000 @@ -341,6 +341,7 @@ void X86Subtarget::initializeEnvironment Slow3OpsLEA = 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.5 diff -u -p -r1.1.1.5 X86Subtarget.h --- lib/Target/X86/X86Subtarget.h 6 Apr 2018 14:26:11 -0000 1.1.1.5 +++ lib/Target/X86/X86Subtarget.h 2 Jun 2018 13:24:57 -0000 @@ -356,6 +356,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; @@ -420,6 +423,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.6 diff -u -p -r1.6 Options.td --- tools/clang/include/clang/Driver/Options.td 6 Apr 2018 14:38:28 -0000 1.6 +++ tools/clang/include/clang/Driver/Options.td 2 Jun 2018 13:24:57 -0000 @@ -1974,6 +1974,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 mfentry : Flag<["-"], "mfentry">, HelpText<"Insert calls to fentry at function entry (x86 only)">, Flags<[CC1Option]>, Group; def mips16 : Flag<["-"], "mips16">, Group;