diff options
| -rw-r--r-- | gnu/llvm/include/llvm/BinaryFormat/Dwarf.def | 2 | ||||
| -rw-r--r-- | gnu/llvm/lib/Target/X86/X86.td | 3 | ||||
| -rw-r--r-- | gnu/llvm/lib/Target/X86/X86FrameLowering.cpp | 97 | ||||
| -rw-r--r-- | gnu/llvm/lib/Target/X86/X86FrameLowering.h | 2 | ||||
| -rw-r--r-- | gnu/llvm/lib/Target/X86/X86MachineFunctionInfo.h | 6 | ||||
| -rw-r--r-- | gnu/llvm/lib/Target/X86/X86Subtarget.h | 5 | ||||
| -rw-r--r-- | gnu/llvm/tools/clang/include/clang/Driver/Options.td | 2 | ||||
| -rw-r--r-- | gnu/llvm/tools/clang/lib/Basic/Targets/X86.cpp | 3 | ||||
| -rw-r--r-- | gnu/llvm/tools/clang/lib/Basic/Targets/X86.h | 1 |
9 files changed, 106 insertions, 15 deletions
diff --git a/gnu/llvm/include/llvm/BinaryFormat/Dwarf.def b/gnu/llvm/include/llvm/BinaryFormat/Dwarf.def index 944c5dd1c15..41ed16d6f45 100644 --- a/gnu/llvm/include/llvm/BinaryFormat/Dwarf.def +++ b/gnu/llvm/include/llvm/BinaryFormat/Dwarf.def @@ -355,6 +355,8 @@ HANDLE_DW_AT(0x2133, GNU_addr_base, 0, GNU) 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) diff --git a/gnu/llvm/lib/Target/X86/X86.td b/gnu/llvm/lib/Target/X86/X86.td index 63c2dc4da6c..3ce047a4920 100644 --- a/gnu/llvm/lib/Target/X86/X86.td +++ b/gnu/llvm/lib/Target/X86/X86.td @@ -284,6 +284,9 @@ def FeatureLZCNTFalseDeps : SubtargetFeature<"false-deps-lzcnt-tzcnt", "LZCNT/TZCNT have a false dependency on dest register">; def FeaturePCONFIG : SubtargetFeature<"pconfig", "HasPCONFIG", "true", "platform configuration instruction">; +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 diff --git a/gnu/llvm/lib/Target/X86/X86FrameLowering.cpp b/gnu/llvm/lib/Target/X86/X86FrameLowering.cpp index ea076e576ef..1a8d3b03836 100644 --- a/gnu/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/gnu/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -48,6 +48,7 @@ X86FrameLowering::X86FrameLowering(const X86Subtarget &STI, // standard x86_64 and NaCl use 64-bit frame/stack pointers, x32 - 32-bit. Uses64BitFramePtr = STI.isTarget64BitLP64() || STI.isTargetNaCl64(); StackPtr = TRI->getStackRegister(); + SaveArgs = Is64Bit ? STI.getSaveArgs() : 0; } bool X86FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { @@ -91,7 +92,8 @@ bool X86FrameLowering::hasFP(const MachineFunction &MF) const { MF.getInfo<X86MachineFunctionInfo>()->getForceFramePointer() || MF.callsUnwindInit() || MF.hasEHFunclets() || MF.callsEHReturn() || MFI.hasStackMap() || MFI.hasPatchPoint() || - MFI.hasCopyImplyingStackAdjustment()); + MFI.hasCopyImplyingStackAdjustment() || + SaveArgs); } static unsigned getSUBriOpcode(unsigned IsLP64, int64_t Imm) { @@ -872,6 +874,24 @@ void X86FrameLowering::BuildStackAlignAND(MachineBasicBlock &MBB, MI->getOperand(3).setIsDead(); } +// FIXME: Get this from tablegen. +static ArrayRef<MCPhysReg> 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 @@ -1154,6 +1174,43 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF, nullptr, DwarfFramePtr)); } + if (SaveArgs && !Fn.arg_empty()) { + ArrayRef<MCPhysReg> 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); + arg_size--; + } + + for (MCPhysReg Reg : GPRs) { + if (++RI > arg_size) + break; + + SaveSize += SlotSize; + + BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH64r)) + .addReg(Reg) + .setMIFlag(MachineInstr::FrameSetup); + } + + // Realign the stack. PUSHes are the most space efficient. + while (SaveSize % getStackAlignment()) { + BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH64r)) + .addReg(GPRs.front()) + .setMIFlag(MachineInstr::FrameSetup); + + SaveSize += SlotSize; + } + + //dlg StackSize -= SaveSize; + //dlg MFI.setStackSize(StackSize); + X86FI->setSaveArgSize(SaveSize); + } + if (NeedsWinFPO) { // .cv_fpo_setframe $FramePtr HasWinCFI = true; @@ -1619,20 +1676,6 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF, } uint64_t SEHStackAllocAmt = NumBytes; - if (HasFP) { - // Pop EBP. - BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r), - MachineFramePtr) - .setMIFlag(MachineInstr::FrameDestroy); - if (NeedsDwarfCFI) { - unsigned DwarfStackPtr = - TRI->getDwarfRegNum(Is64Bit ? X86::RSP : X86::ESP, true); - BuildCFI(MBB, MBBI, DL, MCCFIInstruction::createDefCfa( - nullptr, DwarfStackPtr, -SlotSize)); - --MBBI; - } - } - MachineBasicBlock::iterator FirstCSPop = MBBI; // Skip the callee-saved pop instructions. while (MBBI != MBB.begin()) { @@ -1702,6 +1745,28 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF, --MBBI; } + if (HasFP) { + MBBI = Terminator; + + if (X86FI->getSaveArgSize()) { + // LEAVE is effectively mov rbp,rsp; pop rbp + BuildMI(MBB, MBBI, DL, TII.get(X86::LEAVE64), MachineFramePtr) + .setMIFlag(MachineInstr::FrameDestroy); + } else { + // Pop EBP. + BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r), + MachineFramePtr) + .setMIFlag(MachineInstr::FrameDestroy); + } + if (NeedsDwarfCFI) { + unsigned DwarfStackPtr = + TRI->getDwarfRegNum(Is64Bit ? X86::RSP : X86::ESP, true); + BuildCFI(MBB, MBBI, DL, MCCFIInstruction::createDefCfa( + nullptr, DwarfStackPtr, -SlotSize)); + --MBBI; + } + } + // Windows unwinder will not invoke function's exception handler if IP is // either in prologue or in epilogue. This behavior causes a problem when a // call immediately precedes an epilogue, because the return address points @@ -1790,6 +1855,8 @@ int X86FrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI, "FPDelta isn't aligned per the Win64 ABI!"); } + if (FI >= 0) + Offset -= X86FI->getSaveArgSize(); if (TRI->hasBasePointer(MF)) { assert(HasFP && "VLAs and dynamic stack realign, but no FP?!"); diff --git a/gnu/llvm/lib/Target/X86/X86FrameLowering.h b/gnu/llvm/lib/Target/X86/X86FrameLowering.h index 430848d4d1d..a301056e89b 100644 --- a/gnu/llvm/lib/Target/X86/X86FrameLowering.h +++ b/gnu/llvm/lib/Target/X86/X86FrameLowering.h @@ -37,6 +37,8 @@ public: const X86RegisterInfo *TRI; const X86ReturnProtectorLowering RPL; + bool SaveArgs; + unsigned SlotSize; /// Is64Bit implies that x86_64 instructions are available. diff --git a/gnu/llvm/lib/Target/X86/X86MachineFunctionInfo.h b/gnu/llvm/lib/Target/X86/X86MachineFunctionInfo.h index e1183bd1479..393abe698db 100644 --- a/gnu/llvm/lib/Target/X86/X86MachineFunctionInfo.h +++ b/gnu/llvm/lib/Target/X86/X86MachineFunctionInfo.h @@ -41,6 +41,9 @@ class X86MachineFunctionInfo : public MachineFunctionInfo { /// stack frame in bytes. unsigned CalleeSavedFrameSize = 0; + // SaveArgSize - Number of register arguments saved on the stack + 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 @@ -124,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;} diff --git a/gnu/llvm/lib/Target/X86/X86Subtarget.h b/gnu/llvm/lib/Target/X86/X86Subtarget.h index 34143924b44..cf5439e42cf 100644 --- a/gnu/llvm/lib/Target/X86/X86Subtarget.h +++ b/gnu/llvm/lib/Target/X86/X86Subtarget.h @@ -400,6 +400,9 @@ protected: /// entry to the function and which must be maintained by every function. unsigned stackAlignment = 4; + /// Whether function prologues should save register arguments on the stack. + unsigned SaveArgs; + /// Max. memset / memcpy size that is turned into rep/movs, rep/stos ops. /// // FIXME: this is a known good value for Yonah. How about others? @@ -478,6 +481,8 @@ public: return &getInstrInfo()->getRegisterInfo(); } + unsigned 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 /// function for this subtarget. diff --git a/gnu/llvm/tools/clang/include/clang/Driver/Options.td b/gnu/llvm/tools/clang/include/clang/Driver/Options.td index e8afeb469c5..b9b054606fb 100644 --- a/gnu/llvm/tools/clang/include/clang/Driver/Options.td +++ b/gnu/llvm/tools/clang/include/clang/Driver/Options.td @@ -2814,6 +2814,8 @@ def mretpoline : Flag<["-"], "mretpoline">, Group<m_x86_Features_Group>; def mno_retpoline : Flag<["-"], "mno-retpoline">, Group<m_x86_Features_Group>; def mretpoline_external_thunk : Flag<["-"], "mretpoline-external-thunk">, Group<m_x86_Features_Group>; def mno_retpoline_external_thunk : Flag<["-"], "mno-retpoline-external-thunk">, Group<m_x86_Features_Group>; +def msave_args : Flag<["-"], "msave-args">, Group<m_x86_Features_Group>; +def mno_save_args : Flag<["-"], "mno-save-args">, Group<m_x86_Features_Group>; // These are legacy user-facing driver-level option spellings. They are always // aliases for options that are spelled using the more common Unix / GNU flag diff --git a/gnu/llvm/tools/clang/lib/Basic/Targets/X86.cpp b/gnu/llvm/tools/clang/lib/Basic/Targets/X86.cpp index e295cff9d5d..ffa9e0d2a87 100644 --- a/gnu/llvm/tools/clang/lib/Basic/Targets/X86.cpp +++ b/gnu/llvm/tools/clang/lib/Basic/Targets/X86.cpp @@ -814,6 +814,8 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, HasPTWRITE = true; } else if (Feature == "+invpcid") { HasINVPCID = true; + } else if (Feature == "+save-args") { + HasSaveArgs = true; } X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature) @@ -1386,6 +1388,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("movdiri", HasMOVDIRI) .Case("movdir64b", HasMOVDIR64B) .Case("mpx", HasMPX) + .Case("save-args", HasSaveArgs) .Case("mwaitx", HasMWAITX) .Case("pclmul", HasPCLMUL) .Case("pconfig", HasPCONFIG) diff --git a/gnu/llvm/tools/clang/lib/Basic/Targets/X86.h b/gnu/llvm/tools/clang/lib/Basic/Targets/X86.h index 1d23b0ef693..c476326102d 100644 --- a/gnu/llvm/tools/clang/lib/Basic/Targets/X86.h +++ b/gnu/llvm/tools/clang/lib/Basic/Targets/X86.h @@ -107,6 +107,7 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo { bool HasMOVDIR64B = false; bool HasPTWRITE = false; bool HasINVPCID = false; + bool HasSaveArgs = false; protected: /// Enumeration of all of the X86 CPUs supported by Clang. |
