[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