[llvm] r190290 - Generate compact unwind encoding from CFI directives.
Rafael EspĂndola
rafael.espindola at gmail.com
Sat Nov 2 08:13:03 PDT 2013
Nice! Thanks for doing this.
One nit, can the "llc -filetype=obj" be converted to use llvm-mc?
After all, this is exactly what this patch made possible, no?
On 8 September 2013 22:37, Bill Wendling <isanbard at gmail.com> wrote:
> Author: void
> Date: Sun Sep 8 21:37:14 2013
> New Revision: 190290
>
> URL: http://llvm.org/viewvc/llvm-project?rev=190290&view=rev
> Log:
> Generate compact unwind encoding from CFI directives.
>
> We used to generate the compact unwind encoding from the machine
> instructions. However, this had the problem that if the user used `-save-temps'
> or compiled their hand-written `.s' file (with CFI directives), we wouldn't
> generate the compact unwind encoding.
>
> Move the algorithm that generates the compact unwind encoding into the
> MCAsmBackend. This way we can generate the encoding whether the code is from a
> `.ll' or `.s' file.
>
> <rdar://problem/13623355>
>
> Modified:
> llvm/trunk/include/llvm/MC/MCAsmBackend.h
> llvm/trunk/include/llvm/MC/MCStreamer.h
> llvm/trunk/include/llvm/Support/TargetRegistry.h
> llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp
> llvm/trunk/lib/MC/MCMachOStreamer.cpp
> llvm/trunk/lib/MC/MCStreamer.cpp
> llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
> llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h
> llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
> llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h
> llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
> llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h
> llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
> llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h
> llvm/trunk/lib/Target/R600/MCTargetDesc/AMDGPUAsmBackend.cpp
> llvm/trunk/lib/Target/R600/MCTargetDesc/AMDGPUMCTargetDesc.h
> llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp
> llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.h
> llvm/trunk/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
> llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h
> llvm/trunk/lib/Target/X86/X86FrameLowering.cpp
> llvm/trunk/lib/Target/X86/X86FrameLowering.h
> llvm/trunk/test/CodeGen/X86/compact-unwind.ll
> llvm/trunk/test/CodeGen/X86/no-compact-unwind.ll
> llvm/trunk/tools/llvm-mc/llvm-mc.cpp
>
> Modified: llvm/trunk/include/llvm/MC/MCAsmBackend.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAsmBackend.h?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/MC/MCAsmBackend.h (original)
> +++ llvm/trunk/include/llvm/MC/MCAsmBackend.h Sun Sep 8 21:37:14 2013
> @@ -10,7 +10,9 @@
> #ifndef LLVM_MC_MCASMBACKEND_H
> #define LLVM_MC_MCASMBACKEND_H
>
> +#include "llvm/ADT/ArrayRef.h"
> #include "llvm/MC/MCDirectives.h"
> +#include "llvm/MC/MCDwarf.h"
> #include "llvm/MC/MCFixup.h"
> #include "llvm/Support/DataTypes.h"
> #include "llvm/Support/ErrorHandling.h"
> @@ -158,6 +160,12 @@ public:
> /// handleAssemblerFlag - Handle any target-specific assembler flags.
> /// By default, do nothing.
> virtual void handleAssemblerFlag(MCAssemblerFlag Flag) {}
> +
> + /// \brief Generate the compact unwind encoding for the CFI instructions.
> + virtual unsigned
> + generateCompactUnwindEncoding(ArrayRef<MCCFIInstruction>) const {
> + return 0;
> + }
> };
>
> } // End llvm namespace
>
> Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
> +++ llvm/trunk/include/llvm/MC/MCStreamer.h Sun Sep 8 21:37:14 2013
> @@ -134,6 +134,8 @@ public:
> return *W64UnwindInfos[i];
> }
>
> + void generateCompactUnwindEncodings(MCAsmBackend &MAB);
> +
> /// @name Assembly File Formatting.
> /// @{
>
>
> Modified: llvm/trunk/include/llvm/Support/TargetRegistry.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/TargetRegistry.h?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Support/TargetRegistry.h (original)
> +++ llvm/trunk/include/llvm/Support/TargetRegistry.h Sun Sep 8 21:37:14 2013
> @@ -104,6 +104,7 @@ namespace llvm {
> typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM,
> MCStreamer &Streamer);
> typedef MCAsmBackend *(*MCAsmBackendCtorTy)(const Target &T,
> + const MCRegisterInfo &MRI,
> StringRef TT,
> StringRef CPU);
> typedef MCTargetAsmParser *(*MCAsmParserCtorTy)(MCSubtargetInfo &STI,
> @@ -373,10 +374,11 @@ namespace llvm {
> /// createMCAsmBackend - Create a target specific assembly parser.
> ///
> /// \param Triple The target triple string.
> - MCAsmBackend *createMCAsmBackend(StringRef Triple, StringRef CPU) const {
> + MCAsmBackend *createMCAsmBackend(const MCRegisterInfo &MRI,
> + StringRef Triple, StringRef CPU) const {
> if (!MCAsmBackendCtorFn)
> return 0;
> - return MCAsmBackendCtorFn(*this, Triple, CPU);
> + return MCAsmBackendCtorFn(*this, MRI, Triple, CPU);
> }
>
> /// createMCAsmParser - Create a target specific assembly parser.
> @@ -1118,9 +1120,10 @@ namespace llvm {
> }
>
> private:
> - static MCAsmBackend *Allocator(const Target &T, StringRef Triple,
> - StringRef CPU) {
> - return new MCAsmBackendImpl(T, Triple, CPU);
> + static MCAsmBackend *Allocator(const Target &T,
> + const MCRegisterInfo &MRI,
> + StringRef Triple, StringRef CPU) {
> + return new MCAsmBackendImpl(T, MRI, Triple, CPU);
> }
> };
>
>
> Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original)
> +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Sun Sep 8 21:37:14 2013
> @@ -178,7 +178,7 @@ bool LLVMTargetMachine::addPassesToEmitF
> MCAsmBackend *MAB = 0;
> if (ShowMCEncoding) {
> MCE = getTarget().createMCCodeEmitter(MII, MRI, STI, *Context);
> - MAB = getTarget().createMCAsmBackend(getTargetTriple(), TargetCPU);
> + MAB = getTarget().createMCAsmBackend(MRI, getTargetTriple(), TargetCPU);
> }
>
> MCStreamer *S = getTarget().createAsmStreamer(*Context, Out,
> @@ -197,7 +197,7 @@ bool LLVMTargetMachine::addPassesToEmitF
> // emission fails.
> MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, MRI, STI,
> *Context);
> - MCAsmBackend *MAB = getTarget().createMCAsmBackend(getTargetTriple(),
> + MCAsmBackend *MAB = getTarget().createMCAsmBackend(MRI, getTargetTriple(),
> TargetCPU);
> if (MCE == 0 || MAB == 0)
> return true;
> @@ -271,7 +271,8 @@ bool LLVMTargetMachine::addPassesToEmitM
> const MCSubtargetInfo &STI = getSubtarget<MCSubtargetInfo>();
> MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(), MRI,
> STI, *Ctx);
> - MCAsmBackend *MAB = getTarget().createMCAsmBackend(getTargetTriple(), TargetCPU);
> + MCAsmBackend *MAB = getTarget().createMCAsmBackend(MRI, getTargetTriple(),
> + TargetCPU);
> if (MCE == 0 || MAB == 0)
> return true;
>
>
> Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCMachOStreamer.cpp?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/lib/MC/MCMachOStreamer.cpp (original)
> +++ llvm/trunk/lib/MC/MCMachOStreamer.cpp Sun Sep 8 21:37:14 2013
> @@ -396,6 +396,7 @@ void MCMachOStreamer::EmitInstToData(con
> }
>
> void MCMachOStreamer::FinishImpl() {
> + generateCompactUnwindEncodings(getAssembler().getBackend());
> EmitFrames(true);
>
> // We have to set the fragment atom associations so we can relax properly for
>
> Modified: llvm/trunk/lib/MC/MCStreamer.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/lib/MC/MCStreamer.cpp (original)
> +++ llvm/trunk/lib/MC/MCStreamer.cpp Sun Sep 8 21:37:14 2013
> @@ -10,6 +10,7 @@
> #include "llvm/MC/MCStreamer.h"
> #include "llvm/ADT/SmallString.h"
> #include "llvm/ADT/Twine.h"
> +#include "llvm/MC/MCAsmBackend.h"
> #include "llvm/MC/MCAsmInfo.h"
> #include "llvm/MC/MCContext.h"
> #include "llvm/MC/MCExpr.h"
> @@ -72,6 +73,14 @@ raw_ostream &MCStreamer::GetCommentOS()
> return nulls();
> }
>
> +void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend &MAB) {
> + for (std::vector<MCDwarfFrameInfo>::iterator I = FrameInfos.begin(),
> + E = FrameInfos.end(); I != E; ++I)
> + if (!I->CompactUnwindEncoding)
> + I->CompactUnwindEncoding =
> + MAB.generateCompactUnwindEncoding(I->Instructions);
> +}
> +
> void MCStreamer::EmitDwarfSetLineAddr(int64_t LineDelta,
> const MCSymbol *Label, int PointerSize) {
> // emit the sequence to set the address
>
> Modified: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp (original)
> +++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp Sun Sep 8 21:37:14 2013
> @@ -578,8 +578,8 @@ static uint64_t adjustFixupValue(unsigne
> }
>
> MCAsmBackend *
> -llvm::createAArch64AsmBackend(const Target &T, StringRef TT, StringRef CPU) {
> +llvm::createAArch64AsmBackend(const Target &T, const MCRegisterInfo &MRI,
> + StringRef TT, StringRef CPU) {
> Triple TheTriple(TT);
> -
> return new ELFAArch64AsmBackend(T, TT, TheTriple.getOS());
> }
>
> Modified: llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h (original)
> +++ llvm/trunk/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h Sun Sep 8 21:37:14 2013
> @@ -43,8 +43,9 @@ MCCodeEmitter *createAArch64MCCodeEmitte
> MCObjectWriter *createAArch64ELFObjectWriter(raw_ostream &OS,
> uint8_t OSABI);
>
> -MCAsmBackend *createAArch64AsmBackend(const Target &T, StringRef TT,
> - StringRef CPU);
> +MCAsmBackend *createAArch64AsmBackend(const Target &T,
> + const MCRegisterInfo &MRI,
> + StringRef TT, StringRef CPU);
>
> } // End llvm namespace
>
>
> Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp Sun Sep 8 21:37:14 2013
> @@ -660,7 +660,9 @@ public:
>
> } // end anonymous namespace
>
> -MCAsmBackend *llvm::createARMAsmBackend(const Target &T, StringRef TT, StringRef CPU) {
> +MCAsmBackend *llvm::createARMAsmBackend(const Target &T,
> + const MCRegisterInfo &MRI,
> + StringRef TT, StringRef CPU) {
> Triple TheTriple(TT);
>
> if (TheTriple.isOSDarwin()) {
>
> Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h (original)
> +++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.h Sun Sep 8 21:37:14 2013
> @@ -47,7 +47,8 @@ MCCodeEmitter *createARMMCCodeEmitter(co
> const MCSubtargetInfo &STI,
> MCContext &Ctx);
>
> -MCAsmBackend *createARMAsmBackend(const Target &T, StringRef TT, StringRef CPU);
> +MCAsmBackend *createARMAsmBackend(const Target &T, const MCRegisterInfo &MRI,
> + StringRef TT, StringRef CPU);
>
> /// createARMELFObjectWriter - Construct an ELF Mach-O object writer.
> MCObjectWriter *createARMELFObjectWriter(raw_ostream &OS,
>
> Modified: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp (original)
> +++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp Sun Sep 8 21:37:14 2013
> @@ -253,25 +253,33 @@ public:
> } // namespace
>
> // MCAsmBackend
> -MCAsmBackend *llvm::createMipsAsmBackendEL32(const Target &T, StringRef TT,
> +MCAsmBackend *llvm::createMipsAsmBackendEL32(const Target &T,
> + const MCRegisterInfo &MRI,
> + StringRef TT,
> StringRef CPU) {
> return new MipsAsmBackend(T, Triple(TT).getOS(),
> /*IsLittle*/true, /*Is64Bit*/false);
> }
>
> -MCAsmBackend *llvm::createMipsAsmBackendEB32(const Target &T, StringRef TT,
> +MCAsmBackend *llvm::createMipsAsmBackendEB32(const Target &T,
> + const MCRegisterInfo &MRI,
> + StringRef TT,
> StringRef CPU) {
> return new MipsAsmBackend(T, Triple(TT).getOS(),
> /*IsLittle*/false, /*Is64Bit*/false);
> }
>
> -MCAsmBackend *llvm::createMipsAsmBackendEL64(const Target &T, StringRef TT,
> +MCAsmBackend *llvm::createMipsAsmBackendEL64(const Target &T,
> + const MCRegisterInfo &MRI,
> + StringRef TT,
> StringRef CPU) {
> return new MipsAsmBackend(T, Triple(TT).getOS(),
> /*IsLittle*/true, /*Is64Bit*/true);
> }
>
> -MCAsmBackend *llvm::createMipsAsmBackendEB64(const Target &T, StringRef TT,
> +MCAsmBackend *llvm::createMipsAsmBackendEB64(const Target &T,
> + const MCRegisterInfo &MRI,
> + StringRef TT,
> StringRef CPU) {
> return new MipsAsmBackend(T, Triple(TT).getOS(),
> /*IsLittle*/false, /*Is64Bit*/true);
>
> Modified: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h (original)
> +++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.h Sun Sep 8 21:37:14 2013
> @@ -42,14 +42,14 @@ MCCodeEmitter *createMipsMCCodeEmitterEL
> const MCSubtargetInfo &STI,
> MCContext &Ctx);
>
> -MCAsmBackend *createMipsAsmBackendEB32(const Target &T, StringRef TT,
> - StringRef CPU);
> -MCAsmBackend *createMipsAsmBackendEL32(const Target &T, StringRef TT,
> - StringRef CPU);
> -MCAsmBackend *createMipsAsmBackendEB64(const Target &T, StringRef TT,
> - StringRef CPU);
> -MCAsmBackend *createMipsAsmBackendEL64(const Target &T, StringRef TT,
> - StringRef CPU);
> +MCAsmBackend *createMipsAsmBackendEB32(const Target &T, const MCRegisterInfo &MRI,
> + StringRef TT, StringRef CPU);
> +MCAsmBackend *createMipsAsmBackendEL32(const Target &T, const MCRegisterInfo &MRI,
> + StringRef TT, StringRef CPU);
> +MCAsmBackend *createMipsAsmBackendEB64(const Target &T, const MCRegisterInfo &MRI,
> + StringRef TT, StringRef CPU);
> +MCAsmBackend *createMipsAsmBackendEL64(const Target &T, const MCRegisterInfo &MRI,
> + StringRef TT, StringRef CPU);
>
> MCObjectWriter *createMipsELFObjectWriter(raw_ostream &OS,
> uint8_t OSABI,
>
> Modified: llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp (original)
> +++ llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp Sun Sep 8 21:37:14 2013
> @@ -192,10 +192,9 @@ namespace {
>
> } // end anonymous namespace
>
> -
> -
> -
> -MCAsmBackend *llvm::createPPCAsmBackend(const Target &T, StringRef TT, StringRef CPU) {
> +MCAsmBackend *llvm::createPPCAsmBackend(const Target &T,
> + const MCRegisterInfo &MRI,
> + StringRef TT, StringRef CPU) {
> if (Triple(TT).isOSDarwin())
> return new DarwinPPCAsmBackend(T);
>
>
> Modified: llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h (original)
> +++ llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h Sun Sep 8 21:37:14 2013
> @@ -40,7 +40,8 @@ MCCodeEmitter *createPPCMCCodeEmitter(co
> const MCSubtargetInfo &STI,
> MCContext &Ctx);
>
> -MCAsmBackend *createPPCAsmBackend(const Target &T, StringRef TT, StringRef CPU);
> +MCAsmBackend *createPPCAsmBackend(const Target &T, const MCRegisterInfo &MRI,
> + StringRef TT, StringRef CPU);
>
> /// createPPCELFObjectWriter - Construct an PPC ELF object writer.
> MCObjectWriter *createPPCELFObjectWriter(raw_ostream &OS,
>
> Modified: llvm/trunk/lib/Target/R600/MCTargetDesc/AMDGPUAsmBackend.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/MCTargetDesc/AMDGPUAsmBackend.cpp?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/MCTargetDesc/AMDGPUAsmBackend.cpp (original)
> +++ llvm/trunk/lib/Target/R600/MCTargetDesc/AMDGPUAsmBackend.cpp Sun Sep 8 21:37:14 2013
> @@ -95,7 +95,9 @@ public:
>
> } // end anonymous namespace
>
> -MCAsmBackend *llvm::createAMDGPUAsmBackend(const Target &T, StringRef TT,
> +MCAsmBackend *llvm::createAMDGPUAsmBackend(const Target &T,
> + const MCRegisterInfo &MRI,
> + StringRef TT,
> StringRef CPU) {
> return new ELFAMDGPUAsmBackend(T);
> }
>
> Modified: llvm/trunk/lib/Target/R600/MCTargetDesc/AMDGPUMCTargetDesc.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/MCTargetDesc/AMDGPUMCTargetDesc.h?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/R600/MCTargetDesc/AMDGPUMCTargetDesc.h (original)
> +++ llvm/trunk/lib/Target/R600/MCTargetDesc/AMDGPUMCTargetDesc.h Sun Sep 8 21:37:14 2013
> @@ -40,8 +40,8 @@ MCCodeEmitter *createSIMCCodeEmitter(con
> const MCSubtargetInfo &STI,
> MCContext &Ctx);
>
> -MCAsmBackend *createAMDGPUAsmBackend(const Target &T, StringRef TT,
> - StringRef CPU);
> +MCAsmBackend *createAMDGPUAsmBackend(const Target &T, const MCRegisterInfo &MRI,
> + StringRef TT, StringRef CPU);
>
> MCObjectWriter *createAMDGPUELFObjectWriter(raw_ostream &OS);
> } // End llvm namespace
>
> Modified: llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp (original)
> +++ llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp Sun Sep 8 21:37:14 2013
> @@ -143,8 +143,9 @@ bool SystemZMCAsmBackend::writeNopData(u
> return true;
> }
>
> -MCAsmBackend *llvm::createSystemZMCAsmBackend(const Target &T, StringRef TT,
> - StringRef CPU) {
> +MCAsmBackend *llvm::createSystemZMCAsmBackend(const Target &T,
> + const MCRegisterInfo &MRI,
> + StringRef TT, StringRef CPU) {
> uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(Triple(TT).getOS());
> return new SystemZMCAsmBackend(OSABI);
> }
>
> Modified: llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.h?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.h (original)
> +++ llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCTargetDesc.h Sun Sep 8 21:37:14 2013
> @@ -54,8 +54,9 @@ MCCodeEmitter *createSystemZMCCodeEmitte
> const MCSubtargetInfo &STI,
> MCContext &Ctx);
>
> -MCAsmBackend *createSystemZMCAsmBackend(const Target &T, StringRef TT,
> - StringRef CPU);
> +MCAsmBackend *createSystemZMCAsmBackend(const Target &T,
> + const MCRegisterInfo &MRI,
> + StringRef TT, StringRef CPU);
>
> MCObjectWriter *createSystemZObjectWriter(raw_ostream &OS, uint8_t OSABI);
> } // end namespace llvm
>
> Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp (original)
> +++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp Sun Sep 8 21:37:14 2013
> @@ -27,6 +27,32 @@
> #include "llvm/Support/raw_ostream.h"
> using namespace llvm;
>
> +namespace CU {
> +
> + /// Compact unwind encoding values.
> + enum CompactUnwindEncodings {
> + /// [RE]BP based frame where [RE]BP is pused on the stack immediately after
> + /// the return address, then [RE]SP is moved to [RE]BP.
> + UNWIND_MODE_BP_FRAME = 0x01000000,
> +
> + /// A frameless function with a small constant stack size.
> + UNWIND_MODE_STACK_IMMD = 0x02000000,
> +
> + /// A frameless function with a large constant stack size.
> + UNWIND_MODE_STACK_IND = 0x03000000,
> +
> + /// No compact unwind encoding is available.
> + UNWIND_MODE_DWARF = 0x04000000,
> +
> + /// Mask for encoding the frame registers.
> + UNWIND_BP_FRAME_REGISTERS = 0x00007FFF,
> +
> + /// Mask for encoding the frameless registers.
> + UNWIND_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF
> + };
> +
> +} // end CU namespace
> +
> // Option to allow disabling arithmetic relaxation to workaround PR9807, which
> // is useful when running bitwise comparison experiments on Darwin. We should be
> // able to remove this once PR9807 is resolved.
> @@ -383,27 +409,330 @@ public:
> };
>
> class DarwinX86AsmBackend : public X86AsmBackend {
> + const MCRegisterInfo &MRI;
> +
> + /// \brief Number of registers that can be saved in a compact unwind encoding.
> + enum { CU_NUM_SAVED_REGS = 6 };
> +
> + mutable unsigned SavedRegs[CU_NUM_SAVED_REGS];
> + bool Is64Bit;
> +
> + unsigned OffsetSize; ///< Offset of a "push" instruction.
> + unsigned PushInstrSize; ///< Size of a "push" instruction.
> + unsigned MoveInstrSize; ///< Size of a "move" instruction.
> + unsigned StackDivide; ///< Amount to adjust stack stize by.
> +protected:
> + /// \brief Implementation of algorithm to generate the compact unwind encoding
> + /// for the CFI instructions.
> + uint32_t
> + generateCompactUnwindEncodingImpl(ArrayRef<MCCFIInstruction> Instrs) const {
> + if (Instrs.empty()) return 0;
> +
> + // Reset the saved registers.
> + unsigned SavedRegIdx = 0;
> + memset(SavedRegs, 0, sizeof(SavedRegs));
> +
> + bool HasFP = false;
> +
> + // Encode that we are using EBP/RBP as the frame pointer.
> + uint32_t CompactUnwindEncoding = 0;
> +
> + unsigned SubtractInstrIdx = Is64Bit ? 3 : 2;
> + unsigned InstrOffset = 0;
> + unsigned StackAdjust = 0;
> + unsigned StackSize = 0;
> + unsigned PrevStackSize = 0;
> + unsigned NumDefCFAOffsets = 0;
> +
> + for (unsigned i = 0, e = Instrs.size(); i != e; ++i) {
> + const MCCFIInstruction &Inst = Instrs[i];
> +
> + switch (Inst.getOperation()) {
> + default:
> + llvm_unreachable("cannot handle CFI directive for compact unwind!");
> + case MCCFIInstruction::OpDefCfaRegister: {
> + // Defines a frame pointer. E.g.
> + //
> + // movq %rsp, %rbp
> + // L0:
> + // .cfi_def_cfa_register %rbp
> + //
> + HasFP = true;
> + assert(MRI.getLLVMRegNum(Inst.getRegister(), true) ==
> + (Is64Bit ? X86::RBP : X86::EBP) && "Invalid frame pointer!");
> +
> + // Reset the counts.
> + memset(SavedRegs, 0, sizeof(SavedRegs));
> + StackAdjust = 0;
> + SavedRegIdx = 0;
> + InstrOffset += MoveInstrSize;
> + break;
> + }
> + case MCCFIInstruction::OpDefCfaOffset: {
> + // Defines a new offset for the CFA. E.g.
> + //
> + // With frame:
> + //
> + // pushq %rbp
> + // L0:
> + // .cfi_def_cfa_offset 16
> + //
> + // Without frame:
> + //
> + // subq $72, %rsp
> + // L0:
> + // .cfi_def_cfa_offset 80
> + //
> + PrevStackSize = StackSize;
> + StackSize = std::abs(Inst.getOffset()) / StackDivide;
> + ++NumDefCFAOffsets;
> + break;
> + }
> + case MCCFIInstruction::OpOffset: {
> + // Defines a "push" of a callee-saved register. E.g.
> + //
> + // pushq %r15
> + // pushq %r14
> + // pushq %rbx
> + // L0:
> + // subq $120, %rsp
> + // L1:
> + // .cfi_offset %rbx, -40
> + // .cfi_offset %r14, -32
> + // .cfi_offset %r15, -24
> + //
> + if (SavedRegIdx == CU_NUM_SAVED_REGS)
> + // If there are too many saved registers, we cannot use a compact
> + // unwind encoding.
> + return CU::UNWIND_MODE_DWARF;
> +
> + unsigned Reg = MRI.getLLVMRegNum(Inst.getRegister(), true);
> + SavedRegs[SavedRegIdx++] = Reg;
> + StackAdjust += OffsetSize;
> + InstrOffset += PushInstrSize;
> + break;
> + }
> + }
> + }
> +
> + StackAdjust /= StackDivide;
> +
> + if (HasFP) {
> + if ((StackAdjust & 0xFF) != StackAdjust)
> + // Offset was too big for a compact unwind encoding.
> + return CU::UNWIND_MODE_DWARF;
> +
> + // Get the encoding of the saved registers when we have a frame pointer.
> + uint32_t RegEnc = encodeCompactUnwindRegistersWithFrame();
> + if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF;
> +
> + CompactUnwindEncoding |= CU::UNWIND_MODE_BP_FRAME;
> + CompactUnwindEncoding |= (StackAdjust & 0xFF) << 16;
> + CompactUnwindEncoding |= RegEnc & CU::UNWIND_BP_FRAME_REGISTERS;
> + } else {
> + // If the amount of the stack allocation is the size of a register, then
> + // we "push" the RAX/EAX register onto the stack instead of adjusting the
> + // stack pointer with a SUB instruction. We don't support the push of the
> + // RAX/EAX register with compact unwind. So we check for that situation
> + // here.
> + if ((NumDefCFAOffsets == SavedRegIdx + 1 &&
> + StackSize - PrevStackSize == 1) ||
> + (Instrs.size() == 1 && NumDefCFAOffsets == 1 && StackSize == 2))
> + return CU::UNWIND_MODE_DWARF;
> +
> + SubtractInstrIdx += InstrOffset;
> + ++StackAdjust;
> +
> + if ((StackSize & 0xFF) == StackSize) {
> + // Frameless stack with a small stack size.
> + CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IMMD;
> +
> + // Encode the stack size.
> + CompactUnwindEncoding |= (StackSize & 0xFF) << 16;
> + } else {
> + if ((StackAdjust & 0x7) != StackAdjust)
> + // The extra stack adjustments are too big for us to handle.
> + return CU::UNWIND_MODE_DWARF;
> +
> + // Frameless stack with an offset too large for us to encode compactly.
> + CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IND;
> +
> + // Encode the offset to the nnnnnn value in the 'subl $nnnnnn, ESP'
> + // instruction.
> + CompactUnwindEncoding |= (SubtractInstrIdx & 0xFF) << 16;
> +
> + // Encode any extra stack stack adjustments (done via push
> + // instructions).
> + CompactUnwindEncoding |= (StackAdjust & 0x7) << 13;
> + }
> +
> + // Encode the number of registers saved. (Reverse the list first.)
> + std::reverse(&SavedRegs[0], &SavedRegs[SavedRegIdx]);
> + CompactUnwindEncoding |= (SavedRegIdx & 0x7) << 10;
> +
> + // Get the encoding of the saved registers when we don't have a frame
> + // pointer.
> + uint32_t RegEnc = encodeCompactUnwindRegistersWithoutFrame(SavedRegIdx);
> + if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF;
> +
> + // Encode the register encoding.
> + CompactUnwindEncoding |=
> + RegEnc & CU::UNWIND_FRAMELESS_STACK_REG_PERMUTATION;
> + }
> +
> + return CompactUnwindEncoding;
> + }
> +
> +private:
> + /// \brief Get the compact unwind number for a given register. The number
> + /// corresponds to the enum lists in compact_unwind_encoding.h.
> + int getCompactUnwindRegNum(unsigned Reg) const {
> + static const uint16_t CU32BitRegs[7] = {
> + X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0
> + };
> + static const uint16_t CU64BitRegs[] = {
> + X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0
> + };
> + const uint16_t *CURegs = Is64Bit ? CU64BitRegs : CU32BitRegs;
> + for (int Idx = 1; *CURegs; ++CURegs, ++Idx)
> + if (*CURegs == Reg)
> + return Idx;
> +
> + return -1;
> + }
> +
> + /// \brief Return the registers encoded for a compact encoding with a frame
> + /// pointer.
> + uint32_t encodeCompactUnwindRegistersWithFrame() const {
> + // Encode the registers in the order they were saved --- 3-bits per
> + // register. The list of saved registers is assumed to be in reverse
> + // order. The registers are numbered from 1 to CU_NUM_SAVED_REGS.
> + uint32_t RegEnc = 0;
> + for (int i = 0, Idx = 0; i != CU_NUM_SAVED_REGS; ++i) {
> + unsigned Reg = SavedRegs[i];
> + if (Reg == 0) break;
> +
> + int CURegNum = getCompactUnwindRegNum(Reg);
> + if (CURegNum == -1) return ~0U;
> +
> + // Encode the 3-bit register number in order, skipping over 3-bits for
> + // each register.
> + RegEnc |= (CURegNum & 0x7) << (Idx++ * 3);
> + }
> +
> + assert((RegEnc & 0x3FFFF) == RegEnc &&
> + "Invalid compact register encoding!");
> + return RegEnc;
> + }
> +
> + /// \brief Create the permutation encoding used with frameless stacks. It is
> + /// passed the number of registers to be saved and an array of the registers
> + /// saved.
> + uint32_t encodeCompactUnwindRegistersWithoutFrame(unsigned RegCount) const {
> + // The saved registers are numbered from 1 to 6. In order to encode the
> + // order in which they were saved, we re-number them according to their
> + // place in the register order. The re-numbering is relative to the last
> + // re-numbered register. E.g., if we have registers {6, 2, 4, 5} saved in
> + // that order:
> + //
> + // Orig Re-Num
> + // ---- ------
> + // 6 6
> + // 2 2
> + // 4 3
> + // 5 3
> + //
> + for (unsigned i = 0; i != CU_NUM_SAVED_REGS; ++i) {
> + int CUReg = getCompactUnwindRegNum(SavedRegs[i]);
> + if (CUReg == -1) return ~0U;
> + SavedRegs[i] = CUReg;
> + }
> +
> + // Reverse the list.
> + std::reverse(&SavedRegs[0], &SavedRegs[CU_NUM_SAVED_REGS]);
> +
> + uint32_t RenumRegs[CU_NUM_SAVED_REGS];
> + for (unsigned i = CU_NUM_SAVED_REGS - RegCount; i < CU_NUM_SAVED_REGS; ++i){
> + unsigned Countless = 0;
> + for (unsigned j = CU_NUM_SAVED_REGS - RegCount; j < i; ++j)
> + if (SavedRegs[j] < SavedRegs[i])
> + ++Countless;
> +
> + RenumRegs[i] = SavedRegs[i] - Countless - 1;
> + }
> +
> + // Take the renumbered values and encode them into a 10-bit number.
> + uint32_t permutationEncoding = 0;
> + switch (RegCount) {
> + case 6:
> + permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1]
> + + 6 * RenumRegs[2] + 2 * RenumRegs[3]
> + + RenumRegs[4];
> + break;
> + case 5:
> + permutationEncoding |= 120 * RenumRegs[1] + 24 * RenumRegs[2]
> + + 6 * RenumRegs[3] + 2 * RenumRegs[4]
> + + RenumRegs[5];
> + break;
> + case 4:
> + permutationEncoding |= 60 * RenumRegs[2] + 12 * RenumRegs[3]
> + + 3 * RenumRegs[4] + RenumRegs[5];
> + break;
> + case 3:
> + permutationEncoding |= 20 * RenumRegs[3] + 4 * RenumRegs[4]
> + + RenumRegs[5];
> + break;
> + case 2:
> + permutationEncoding |= 5 * RenumRegs[4] + RenumRegs[5];
> + break;
> + case 1:
> + permutationEncoding |= RenumRegs[5];
> + break;
> + }
> +
> + assert((permutationEncoding & 0x3FF) == permutationEncoding &&
> + "Invalid compact register encoding!");
> + return permutationEncoding;
> + }
> +
> public:
> - DarwinX86AsmBackend(const Target &T, StringRef CPU)
> - : X86AsmBackend(T, CPU) { }
> + DarwinX86AsmBackend(const Target &T, const MCRegisterInfo &MRI, StringRef CPU,
> + bool Is64Bit)
> + : X86AsmBackend(T, CPU), MRI(MRI), Is64Bit(Is64Bit) {
> + memset(SavedRegs, 0, sizeof(SavedRegs));
> + OffsetSize = Is64Bit ? 8 : 4;
> + MoveInstrSize = Is64Bit ? 3 : 2;
> + StackDivide = Is64Bit ? 8 : 4;
> + PushInstrSize = 1;
> + }
> };
>
> class DarwinX86_32AsmBackend : public DarwinX86AsmBackend {
> + bool SupportsCU;
> public:
> - DarwinX86_32AsmBackend(const Target &T, StringRef CPU)
> - : DarwinX86AsmBackend(T, CPU) {}
> + DarwinX86_32AsmBackend(const Target &T, const MCRegisterInfo &MRI,
> + StringRef CPU, bool SupportsCU)
> + : DarwinX86AsmBackend(T, MRI, CPU, false), SupportsCU(SupportsCU) {}
>
> MCObjectWriter *createObjectWriter(raw_ostream &OS) const {
> return createX86MachObjectWriter(OS, /*Is64Bit=*/false,
> MachO::CPU_TYPE_I386,
> MachO::CPU_SUBTYPE_I386_ALL);
> }
> +
> + /// \brief Generate the compact unwind encoding for the CFI instructions.
> + virtual unsigned
> + generateCompactUnwindEncoding(ArrayRef<MCCFIInstruction> Instrs) const {
> + return SupportsCU ? generateCompactUnwindEncodingImpl(Instrs) : 0;
> + }
> };
>
> class DarwinX86_64AsmBackend : public DarwinX86AsmBackend {
> + bool SupportsCU;
> public:
> - DarwinX86_64AsmBackend(const Target &T, StringRef CPU)
> - : DarwinX86AsmBackend(T, CPU) {
> + DarwinX86_64AsmBackend(const Target &T, const MCRegisterInfo &MRI,
> + StringRef CPU, bool SupportsCU)
> + : DarwinX86AsmBackend(T, MRI, CPU, true), SupportsCU(SupportsCU) {
> HasReliableSymbolDifference = true;
> }
>
> @@ -445,15 +774,26 @@ public:
> return false;
> }
> }
> +
> + /// \brief Generate the compact unwind encoding for the CFI instructions.
> + virtual unsigned
> + generateCompactUnwindEncoding(ArrayRef<MCCFIInstruction> Instrs) const {
> + return SupportsCU ? generateCompactUnwindEncodingImpl(Instrs) : 0;
> + }
> };
>
> } // end anonymous namespace
>
> -MCAsmBackend *llvm::createX86_32AsmBackend(const Target &T, StringRef TT, StringRef CPU) {
> +MCAsmBackend *llvm::createX86_32AsmBackend(const Target &T,
> + const MCRegisterInfo &MRI,
> + StringRef TT,
> + StringRef CPU) {
> Triple TheTriple(TT);
>
> if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO)
> - return new DarwinX86_32AsmBackend(T, CPU);
> + return new DarwinX86_32AsmBackend(T, MRI, CPU,
> + TheTriple.isMacOSX() &&
> + !TheTriple.isMacOSXVersionLT(10, 7));
>
> if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF)
> return new WindowsX86AsmBackend(T, false, CPU);
> @@ -462,11 +802,16 @@ MCAsmBackend *llvm::createX86_32AsmBacke
> return new ELFX86_32AsmBackend(T, OSABI, CPU);
> }
>
> -MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T, StringRef TT, StringRef CPU) {
> +MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T,
> + const MCRegisterInfo &MRI,
> + StringRef TT,
> + StringRef CPU) {
> Triple TheTriple(TT);
>
> if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO)
> - return new DarwinX86_64AsmBackend(T, CPU);
> + return new DarwinX86_64AsmBackend(T, MRI, CPU,
> + TheTriple.isMacOSX() &&
> + !TheTriple.isMacOSXVersionLT(10, 7));
>
> if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF)
> return new WindowsX86AsmBackend(T, true, CPU);
>
> Modified: llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h (original)
> +++ llvm/trunk/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.h Sun Sep 8 21:37:14 2013
> @@ -79,8 +79,10 @@ MCCodeEmitter *createX86MCCodeEmitter(co
> const MCSubtargetInfo &STI,
> MCContext &Ctx);
>
> -MCAsmBackend *createX86_32AsmBackend(const Target &T, StringRef TT, StringRef CPU);
> -MCAsmBackend *createX86_64AsmBackend(const Target &T, StringRef TT, StringRef CPU);
> +MCAsmBackend *createX86_32AsmBackend(const Target &T, const MCRegisterInfo &MRI,
> + StringRef TT, StringRef CPU);
> +MCAsmBackend *createX86_64AsmBackend(const Target &T, const MCRegisterInfo &MRI,
> + StringRef TT, StringRef CPU);
>
> /// createX86MachObjectWriter - Construct an X86 Mach-O object writer.
> MCObjectWriter *createX86MachObjectWriter(raw_ostream &OS,
>
> Modified: llvm/trunk/lib/Target/X86/X86FrameLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FrameLowering.cpp?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86FrameLowering.cpp (original)
> +++ llvm/trunk/lib/Target/X86/X86FrameLowering.cpp Sun Sep 8 21:37:14 2013
> @@ -365,274 +365,6 @@ void X86FrameLowering::emitCalleeSavedFr
> }
> }
>
> -/// getCompactUnwindRegNum - Get the compact unwind number for a given
> -/// register. The number corresponds to the enum lists in
> -/// compact_unwind_encoding.h.
> -static int getCompactUnwindRegNum(unsigned Reg, bool is64Bit) {
> - static const uint16_t CU32BitRegs[] = {
> - X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0
> - };
> - static const uint16_t CU64BitRegs[] = {
> - X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0
> - };
> - const uint16_t *CURegs = is64Bit ? CU64BitRegs : CU32BitRegs;
> - for (int Idx = 1; *CURegs; ++CURegs, ++Idx)
> - if (*CURegs == Reg)
> - return Idx;
> -
> - return -1;
> -}
> -
> -// Number of registers that can be saved in a compact unwind encoding.
> -#define CU_NUM_SAVED_REGS 6
> -
> -/// encodeCompactUnwindRegistersWithoutFrame - Create the permutation encoding
> -/// used with frameless stacks. It is passed the number of registers to be saved
> -/// and an array of the registers saved.
> -static uint32_t
> -encodeCompactUnwindRegistersWithoutFrame(unsigned SavedRegs[CU_NUM_SAVED_REGS],
> - unsigned RegCount, bool Is64Bit) {
> - // The saved registers are numbered from 1 to 6. In order to encode the order
> - // in which they were saved, we re-number them according to their place in the
> - // register order. The re-numbering is relative to the last re-numbered
> - // register. E.g., if we have registers {6, 2, 4, 5} saved in that order:
> - //
> - // Orig Re-Num
> - // ---- ------
> - // 6 6
> - // 2 2
> - // 4 3
> - // 5 3
> - //
> - for (unsigned i = 0; i != CU_NUM_SAVED_REGS; ++i) {
> - int CUReg = getCompactUnwindRegNum(SavedRegs[i], Is64Bit);
> - if (CUReg == -1) return ~0U;
> - SavedRegs[i] = CUReg;
> - }
> -
> - // Reverse the list.
> - std::swap(SavedRegs[0], SavedRegs[5]);
> - std::swap(SavedRegs[1], SavedRegs[4]);
> - std::swap(SavedRegs[2], SavedRegs[3]);
> -
> - uint32_t RenumRegs[CU_NUM_SAVED_REGS];
> - for (unsigned i = CU_NUM_SAVED_REGS - RegCount; i < CU_NUM_SAVED_REGS; ++i) {
> - unsigned Countless = 0;
> - for (unsigned j = CU_NUM_SAVED_REGS - RegCount; j < i; ++j)
> - if (SavedRegs[j] < SavedRegs[i])
> - ++Countless;
> -
> - RenumRegs[i] = SavedRegs[i] - Countless - 1;
> - }
> -
> - // Take the renumbered values and encode them into a 10-bit number.
> - uint32_t permutationEncoding = 0;
> - switch (RegCount) {
> - case 6:
> - permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1]
> - + 6 * RenumRegs[2] + 2 * RenumRegs[3]
> - + RenumRegs[4];
> - break;
> - case 5:
> - permutationEncoding |= 120 * RenumRegs[1] + 24 * RenumRegs[2]
> - + 6 * RenumRegs[3] + 2 * RenumRegs[4]
> - + RenumRegs[5];
> - break;
> - case 4:
> - permutationEncoding |= 60 * RenumRegs[2] + 12 * RenumRegs[3]
> - + 3 * RenumRegs[4] + RenumRegs[5];
> - break;
> - case 3:
> - permutationEncoding |= 20 * RenumRegs[3] + 4 * RenumRegs[4]
> - + RenumRegs[5];
> - break;
> - case 2:
> - permutationEncoding |= 5 * RenumRegs[4] + RenumRegs[5];
> - break;
> - case 1:
> - permutationEncoding |= RenumRegs[5];
> - break;
> - }
> -
> - assert((permutationEncoding & 0x3FF) == permutationEncoding &&
> - "Invalid compact register encoding!");
> - return permutationEncoding;
> -}
> -
> -/// encodeCompactUnwindRegistersWithFrame - Return the registers encoded for a
> -/// compact encoding with a frame pointer.
> -static uint32_t
> -encodeCompactUnwindRegistersWithFrame(unsigned SavedRegs[CU_NUM_SAVED_REGS],
> - bool Is64Bit) {
> - // Encode the registers in the order they were saved, 3-bits per register. The
> - // registers are numbered from 1 to CU_NUM_SAVED_REGS.
> - uint32_t RegEnc = 0;
> - for (int I = CU_NUM_SAVED_REGS - 1, Idx = 0; I != -1; --I) {
> - unsigned Reg = SavedRegs[I];
> - if (Reg == 0) continue;
> -
> - int CURegNum = getCompactUnwindRegNum(Reg, Is64Bit);
> - if (CURegNum == -1) return ~0U;
> -
> - // Encode the 3-bit register number in order, skipping over 3-bits for each
> - // register.
> - RegEnc |= (CURegNum & 0x7) << (Idx++ * 3);
> - }
> -
> - assert((RegEnc & 0x3FFFF) == RegEnc && "Invalid compact register encoding!");
> - return RegEnc;
> -}
> -
> -static uint32_t
> -doCompactUnwindEncoding(unsigned SavedRegs[CU_NUM_SAVED_REGS],
> - unsigned StackSize, unsigned StackAdjust,
> - unsigned SubtractInstrIdx, unsigned SavedRegIdx,
> - bool Is64Bit, bool HasFP) {
> - // Encode that we are using EBP/RBP as the frame pointer.
> - unsigned StackDivide = (Is64Bit ? 8 : 4);
> - uint32_t CompactUnwindEncoding = 0;
> -
> - StackAdjust /= StackDivide;
> -
> - if (HasFP) {
> - if ((StackAdjust & 0xFF) != StackAdjust)
> - // Offset was too big for compact encoding.
> - return CU::UNWIND_MODE_DWARF;
> -
> - // Get the encoding of the saved registers when we have a frame pointer.
> - uint32_t RegEnc = encodeCompactUnwindRegistersWithFrame(SavedRegs, Is64Bit);
> - if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF;
> -
> - CompactUnwindEncoding |= CU::UNWIND_MODE_BP_FRAME;
> - CompactUnwindEncoding |= (StackAdjust & 0xFF) << 16;
> - CompactUnwindEncoding |= RegEnc & CU::UNWIND_BP_FRAME_REGISTERS;
> - } else {
> - ++StackAdjust;
> - uint32_t TotalStackSize = StackAdjust + StackSize;
> - if ((TotalStackSize & 0xFF) == TotalStackSize) {
> - // Frameless stack with a small stack size.
> - CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IMMD;
> -
> - // Encode the stack size.
> - CompactUnwindEncoding |= (TotalStackSize & 0xFF) << 16;
> - } else {
> - if ((StackAdjust & 0x7) != StackAdjust)
> - // The extra stack adjustments are too big for us to handle.
> - return CU::UNWIND_MODE_DWARF;
> -
> - // Frameless stack with an offset too large for us to encode compactly.
> - CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IND;
> -
> - // Encode the offset to the nnnnnn value in the 'subl $nnnnnn, ESP'
> - // instruction.
> - CompactUnwindEncoding |= (SubtractInstrIdx & 0xFF) << 16;
> -
> - // Encode any extra stack stack adjustments (done via push instructions).
> - CompactUnwindEncoding |= (StackAdjust & 0x7) << 13;
> - }
> -
> - // Encode the number of registers saved.
> - CompactUnwindEncoding |= (SavedRegIdx & 0x7) << 10;
> -
> - // Get the encoding of the saved registers when we don't have a frame
> - // pointer.
> - uint32_t RegEnc =
> - encodeCompactUnwindRegistersWithoutFrame(SavedRegs, SavedRegIdx,
> - Is64Bit);
> - if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF;
> -
> - // Encode the register encoding.
> - CompactUnwindEncoding |=
> - RegEnc & CU::UNWIND_FRAMELESS_STACK_REG_PERMUTATION;
> - }
> -
> - return CompactUnwindEncoding;
> -}
> -
> -uint32_t X86FrameLowering::getCompactUnwindEncoding(MachineFunction &MF) const {
> - const X86RegisterInfo *RegInfo = TM.getRegisterInfo();
> - unsigned FramePtr = RegInfo->getFrameRegister(MF);
> - unsigned StackPtr = RegInfo->getStackRegister();
> -
> - bool Is64Bit = STI.is64Bit();
> -
> - unsigned SavedRegs[CU_NUM_SAVED_REGS] = { 0, 0, 0, 0, 0, 0 };
> - unsigned SavedRegIdx = 0;
> -
> - unsigned OffsetSize = (Is64Bit ? 8 : 4);
> -
> - unsigned PushInstr = (Is64Bit ? X86::PUSH64r : X86::PUSH32r);
> - unsigned PushInstrSize = 1;
> - unsigned MoveInstr = (Is64Bit ? X86::MOV64rr : X86::MOV32rr);
> - unsigned MoveInstrSize = (Is64Bit ? 3 : 2);
> - unsigned SubtractInstrIdx = (Is64Bit ? 3 : 2);
> -
> - unsigned StackDivide = (Is64Bit ? 8 : 4);
> -
> - unsigned InstrOffset = 0;
> - unsigned StackAdjust = 0;
> - unsigned StackSize = 0;
> -
> - bool ExpectEnd = false;
> - for (MachineBasicBlock::iterator MBBI = MF.front().begin(),
> - MBBE = MF.front().end(); MBBI != MBBE; ++MBBI) {
> - MachineInstr &MI = *MBBI;
> - unsigned Opc = MI.getOpcode();
> - if (Opc == X86::PROLOG_LABEL) continue;
> - if (!MI.getFlag(MachineInstr::FrameSetup)) break;
> -
> - // We don't exect any more prolog instructions.
> - if (ExpectEnd) return CU::UNWIND_MODE_DWARF;
> -
> - if (Opc == PushInstr) {
> - // If there are too many saved registers, we cannot use compact encoding.
> - if (SavedRegIdx >= CU_NUM_SAVED_REGS) return CU::UNWIND_MODE_DWARF;
> -
> - unsigned Reg = MI.getOperand(0).getReg();
> - if (Reg == (Is64Bit ? X86::RAX : X86::EAX)) {
> - ExpectEnd = true;
> - continue;
> - }
> -
> - SavedRegs[SavedRegIdx++] = MI.getOperand(0).getReg();
> - StackAdjust += OffsetSize;
> - InstrOffset += PushInstrSize;
> - } else if (Opc == MoveInstr) {
> - unsigned SrcReg = MI.getOperand(1).getReg();
> - unsigned DstReg = MI.getOperand(0).getReg();
> -
> - if (DstReg != FramePtr || SrcReg != StackPtr)
> - return CU::UNWIND_MODE_DWARF;
> -
> - StackAdjust = 0;
> - memset(SavedRegs, 0, sizeof(SavedRegs));
> - SavedRegIdx = 0;
> - InstrOffset += MoveInstrSize;
> - } else if (Opc == X86::SUB64ri32 || Opc == X86::SUB64ri8 ||
> - Opc == X86::SUB32ri || Opc == X86::SUB32ri8) {
> - if (StackSize)
> - // We already have a stack size.
> - return CU::UNWIND_MODE_DWARF;
> -
> - if (!MI.getOperand(0).isReg() ||
> - MI.getOperand(0).getReg() != MI.getOperand(1).getReg() ||
> - MI.getOperand(0).getReg() != StackPtr || !MI.getOperand(2).isImm())
> - // We need this to be a stack adjustment pointer. Something like:
> - //
> - // %RSP<def> = SUB64ri8 %RSP, 48
> - return CU::UNWIND_MODE_DWARF;
> -
> - StackSize = MI.getOperand(2).getImm() / StackDivide;
> - SubtractInstrIdx += InstrOffset;
> - ExpectEnd = true;
> - }
> - }
> -
> - return doCompactUnwindEncoding(SavedRegs, StackSize, StackAdjust,
> - SubtractInstrIdx, SavedRegIdx,
> - Is64Bit, hasFP(MF));
> -}
> -
> /// usesTheStack - This function checks if any of the users of EFLAGS
> /// copies the EFLAGS. We know that the code that lowers COPY of EFLAGS has
> /// to use the stack, and if we don't adjust the stack we clobber the first
> @@ -975,11 +707,6 @@ void X86FrameLowering::emitPrologue(Mach
> if (PushedRegs)
> emitCalleeSavedFrameMoves(MF, Label, HasFP ? FramePtr : StackPtr);
> }
> -
> - // Darwin 10.7 and greater has support for compact unwind encoding.
> - if (STI.getTargetTriple().isMacOSX() &&
> - !STI.getTargetTriple().isMacOSXVersionLT(10, 7))
> - MMI.setCompactUnwindEncoding(getCompactUnwindEncoding(MF));
> }
>
> void X86FrameLowering::emitEpilogue(MachineFunction &MF,
>
> Modified: llvm/trunk/lib/Target/X86/X86FrameLowering.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FrameLowering.h?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Target/X86/X86FrameLowering.h (original)
> +++ llvm/trunk/lib/Target/X86/X86FrameLowering.h Sun Sep 8 21:37:14 2013
> @@ -20,32 +20,6 @@
>
> namespace llvm {
>
> -namespace CU {
> -
> - /// Compact unwind encoding values.
> - enum CompactUnwindEncodings {
> - /// [RE]BP based frame where [RE]BP is pused on the stack immediately after
> - /// the return address, then [RE]SP is moved to [RE]BP.
> - UNWIND_MODE_BP_FRAME = 0x01000000,
> -
> - /// A frameless function with a small constant stack size.
> - UNWIND_MODE_STACK_IMMD = 0x02000000,
> -
> - /// A frameless function with a large constant stack size.
> - UNWIND_MODE_STACK_IND = 0x03000000,
> -
> - /// No compact unwind encoding is available.
> - UNWIND_MODE_DWARF = 0x04000000,
> -
> - /// Mask for encoding the frame registers.
> - UNWIND_BP_FRAME_REGISTERS = 0x00007FFF,
> -
> - /// Mask for encoding the frameless registers.
> - UNWIND_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF
> - };
> -
> -} // end CU namespace
> -
> class MCSymbol;
> class X86TargetMachine;
>
> @@ -91,7 +65,6 @@ public:
> int getFrameIndexOffset(const MachineFunction &MF, int FI) const;
> int getFrameIndexReference(const MachineFunction &MF, int FI,
> unsigned &FrameReg) const;
> - uint32_t getCompactUnwindEncoding(MachineFunction &MF) const;
>
> void eliminateCallFramePseudoInstr(MachineFunction &MF,
> MachineBasicBlock &MBB,
>
> Modified: llvm/trunk/test/CodeGen/X86/compact-unwind.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/compact-unwind.ll?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/compact-unwind.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/compact-unwind.ll Sun Sep 8 21:37:14 2013
> @@ -1,18 +1,21 @@
> -; RUN: llc < %s -disable-cfi -disable-fp-elim -mtriple x86_64-apple-darwin11 | FileCheck %s
> +; RUN: llc < %s -disable-fp-elim -mtriple x86_64-apple-darwin11 | FileCheck -check-prefix=ASM %s
> +; RUN: llc < %s -disable-fp-elim -mtriple x86_64-apple-darwin11 -filetype=obj -o - \
> +; RUN: | llvm-objdump -triple x86_64-apple-darwin11 -s - \
> +; RUN: | FileCheck -check-prefix=CU %s
>
> %ty = type { i8* }
>
> @gv = external global i32
>
> ; This is aligning the stack with a push of a random register.
> -; CHECK: pushq %rax
> +; ASM: pushq %rax
>
> ; Even though we can't encode %rax into the compact unwind, We still want to be
> ; able to generate a compact unwind encoding in this particular case.
> ;
> -; CHECK: __LD,__compact_unwind
> -; CHECK: _foo ## Range Start
> -; CHECK: 16842753 ## Compact Unwind Encoding: 0x1010001
> +; CU: Contents of section __compact_unwind:
> +; CU-NEXT: 0020 00000000 00000000 1e000000 01000101
> +; CU-NEXT: 0030 00000000 00000000 00000000 00000000
>
> define i8* @foo(i64 %size) {
> %addr = alloca i64, align 8
>
> Modified: llvm/trunk/test/CodeGen/X86/no-compact-unwind.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/no-compact-unwind.ll?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/test/CodeGen/X86/no-compact-unwind.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/no-compact-unwind.ll Sun Sep 8 21:37:14 2013
> @@ -1,4 +1,6 @@
> -; RUN: llc < %s -mtriple x86_64-apple-macosx10.8.0 -disable-cfi | FileCheck %s
> +; RUN: llc < %s -mtriple x86_64-apple-macosx10.8.0 -filetype=obj -o - \
> +; RUN: | llvm-objdump -triple x86_64-apple-macosx10.8.0 -s - \
> +; RUN: | FileCheck %s
>
> %"struct.dyld::MappedRanges" = type { [400 x %struct.anon], %"struct.dyld::MappedRanges"* }
> %struct.anon = type { %class.ImageLoader*, i64, i64 }
> @@ -13,12 +15,11 @@ declare void @OSMemoryBarrier() optsize
> ; compact unwind encodings for this function. This then defaults to using the
> ; DWARF EH frame.
> ;
> -; CHECK: .section __LD,__compact_unwind,regular,debug
> -; CHECK: .quad _func
> -; CHECK: .long 67108864 ## Compact Unwind Encoding: 0x4000000
> -; CHECK: .quad 0 ## Personality Function
> -; CHECK: .quad 0 ## LSDA
> +; CHECK: Contents of section __compact_unwind:
> +; CHECK-NEXT: 0048 00000000 00000000 42000000 00000004
> +; CHECK-NEXT: 0058 00000000 00000000 00000000 00000000
> ;
> +
> define void @func(%class.ImageLoader* %image) optsize ssp uwtable {
> entry:
> br label %for.cond1.preheader
>
> Modified: llvm/trunk/tools/llvm-mc/llvm-mc.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc/llvm-mc.cpp?rev=190290&r1=190289&r2=190290&view=diff
> ==============================================================================
> --- llvm/trunk/tools/llvm-mc/llvm-mc.cpp (original)
> +++ llvm/trunk/tools/llvm-mc/llvm-mc.cpp Sun Sep 8 21:37:14 2013
> @@ -432,7 +432,7 @@ int main(int argc, char **argv) {
> MCAsmBackend *MAB = 0;
> if (ShowEncoding) {
> CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
> - MAB = TheTarget->createMCAsmBackend(TripleName, MCPU);
> + MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
> }
> bool UseCFI = !DisableCFI;
> Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/true,
> @@ -446,7 +446,7 @@ int main(int argc, char **argv) {
> } else {
> assert(FileType == OFT_ObjectFile && "Invalid file type!");
> MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
> - MCAsmBackend *MAB = TheTarget->createMCAsmBackend(TripleName, MCPU);
> + MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
> Str.reset(TheTarget->createMCObjectStreamer(TripleName, Ctx, *MAB,
> FOS, CE, RelaxAll,
> NoExecStack));
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list