[llvm] r190290 - Generate compact unwind encoding from CFI directives.
Bill Wendling
isanbard at gmail.com
Sun Nov 3 00:22:04 PDT 2013
On Nov 2, 2013, at 8:13 AM, Rafael EspĂndola <rafael.espindola at gmail.com> wrote:
> Nice! Thanks for doing this.
>
Sure! :-)
> One nit, can the "llc -filetype=obj" be converted to use llvm-mc?
> After all, this is exactly what this patch made possible, no?
>
I'm not sure I understand how it would use llvm-mc...?
-bw
> 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