diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h index a071febb102..81e73a6798b 100644 --- a/include/llvm/CodeGen/AsmPrinter.h +++ b/include/llvm/CodeGen/AsmPrinter.h @@ -183,6 +183,8 @@ namespace llvm { /// function. void EmitFunctionBody(); + void emitPrologLabel(const MachineInstr &MI); + /// EmitConstantPool - Print to the current output stream assembly /// representations of the constants in the constant pool MCP. This is /// used to print out constants which have been "spilled to memory" by diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 3d3abc2fed2..baf11a77db3 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -33,6 +33,7 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Target/Mangler.h" +#include "llvm/Target/TargetAsmInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetLowering.h" @@ -624,6 +625,45 @@ static bool EmitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) { return true; } +void AsmPrinter::emitPrologLabel(const MachineInstr &MI) { + MCSymbol *Label = MI.getOperand(0).getMCSymbol(); + if (MAI->getExceptionHandlingType() != ExceptionHandling::DwarfCFI) { + OutStreamer.EmitLabel(Label); + return; + } + + const MachineFunction &MF = *MI.getParent()->getParent(); + MachineModuleInfo &MMI = MF.getMMI(); + std::vector &Moves = MMI.getFrameMoves(); + const MachineMove *Move = NULL; + for (std::vector::iterator I = Moves.begin(), + E = Moves.end(); I != E; ++I) { + if (I->getLabel() == Label) { + Move = &*I; + break; + } + } + assert(Move); + + const MachineLocation &Dst = Move->getDestination(); + const MachineLocation &Src = Move->getSource(); + const TargetAsmInfo &AsmInfo = OutContext.getTargetAsmInfo(); + if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) { + if (Src.getReg() == MachineLocation::VirtualFP) + OutStreamer.EmitCFIDefCfaOffset(-Src.getOffset()); + else { + unsigned Reg = AsmInfo.getDwarfRegNum(Src.getReg(), true); + OutStreamer.EmitCFIDefCfa(Reg, -Src.getOffset()); + } + } else if (Src.isReg() && Src.getReg() == MachineLocation::VirtualFP) { + unsigned Reg = AsmInfo.getDwarfRegNum(Dst.getReg(), true); + OutStreamer.EmitCFIDefCfaRegister(Reg); + } else { + unsigned Reg = AsmInfo.getDwarfRegNum(Src.getReg(), true); + OutStreamer.EmitCFIOffset(Reg, -Dst.getOffset()); + } +} + /// EmitFunctionBody - This method emits the body and trailer for a /// function. void AsmPrinter::EmitFunctionBody() { @@ -660,6 +700,9 @@ void AsmPrinter::EmitFunctionBody() { switch (II->getOpcode()) { case TargetOpcode::PROLOG_LABEL: + emitPrologLabel(*II); + break; + case TargetOpcode::EH_LABEL: case TargetOpcode::GC_LABEL: OutStreamer.EmitLabel(II->getOperand(0).getMCSymbol()); diff --git a/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp b/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp index 68be2eed8f0..8e4cf467b40 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp @@ -32,6 +32,7 @@ #include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Support/Dwarf.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" @@ -60,11 +61,16 @@ void DwarfCFIException::EndModule() { // Begin eh frame section. Asm->OutStreamer.SwitchSection(TLOF.getEHFrameSection()); + if ((PerEncoding & 0x70) != dwarf::DW_EH_PE_pcrel) + return; + // Emit references to all used personality functions const std::vector &Personalities = MMI->getPersonalities(); for (size_t i = 0, e = Personalities.size(); i != e; ++i) { Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("personality", i)); - Asm->EmitReference(Personalities[i], PerEncoding); + const MCSymbol *Sym = Asm->Mang->getSymbol(Personalities[i]); + unsigned Size = Asm->TM.getTargetData()->getPointerSize(); + Asm->OutStreamer.EmitSymbolValue(Sym, Size); } } @@ -77,7 +83,7 @@ void DwarfCFIException::BeginFunction(const MachineFunction *MF) { shouldEmitTable = !MMI->getLandingPads().empty(); // See if we need frame move info. - shouldEmitMoves = + shouldEmitMoves = MMI->hasDebugInfo() || !Asm->MF->getFunction()->doesNotThrow() || UnwindTablesMandatory; if (shouldEmitMoves || shouldEmitTable) @@ -87,17 +93,9 @@ void DwarfCFIException::BeginFunction(const MachineFunction *MF) { shouldEmitTableModule |= shouldEmitTable; - if (shouldEmitMoves) { - const TargetFrameLowering *TFL = Asm->TM.getFrameLowering(); + if (shouldEmitMoves || shouldEmitTable) Asm->OutStreamer.EmitCFIStartProc(); - // Indicate locations of general callee saved registers in frame. - std::vector Moves; - TFL->getInitialFrameState(Moves); - Asm->EmitCFIFrameMoves(Moves); - Asm->EmitCFIFrameMoves(MMI->getFrameMoves()); - } - if (!shouldEmitTable) return; @@ -112,11 +110,25 @@ void DwarfCFIException::BeginFunction(const MachineFunction *MF) { // Indicate personality routine, if any. unsigned PerEncoding = TLOF.getPersonalityEncoding(); - if (PerEncoding != dwarf::DW_EH_PE_omit && - MMI->getPersonalities()[MMI->getPersonalityIndex()]) - Asm->OutStreamer.EmitCFIPersonality(Asm->GetTempSymbol("personality", - MMI->getPersonalityIndex()), - PerEncoding); + const Function *Per = MMI->getPersonalities()[MMI->getPersonalityIndex()]; + if (PerEncoding == dwarf::DW_EH_PE_omit || !Per) + return; + + const MCSymbol *Sym; + switch (PerEncoding & 0x70) { + default: + report_fatal_error("We do not support this DWARF encoding yet!"); + case dwarf::DW_EH_PE_absptr: { + Sym = Asm->Mang->getSymbol(Per); + break; + } + case dwarf::DW_EH_PE_pcrel: { + Sym = Asm->GetTempSymbol("personality", + MMI->getPersonalityIndex()); + break; + } + } + Asm->OutStreamer.EmitCFIPersonality(Sym, PerEncoding); } /// EndFunction - Gather and emit post-function exception information. diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp index 5d34c7d7fa3..7eeec5dda46 100644 --- a/lib/Target/TargetLoweringObjectFile.cpp +++ b/lib/Target/TargetLoweringObjectFile.cpp @@ -314,7 +314,7 @@ getExprForDwarfReference(const MCSymbol *Sym, Mangler *Mang, MCStreamer &Streamer) const { const MCExpr *Res = MCSymbolRefExpr::Create(Sym, getContext()); - switch (Encoding & 0xF0) { + switch (Encoding & 0x70) { default: report_fatal_error("We do not support this DWARF encoding yet!"); case dwarf::DW_EH_PE_absptr: diff --git a/lib/Target/X86/X86FrameLowering.cpp b/lib/Target/X86/X86FrameLowering.cpp index dee27a0336d..df20429bcc7 100644 --- a/lib/Target/X86/X86FrameLowering.cpp +++ b/lib/Target/X86/X86FrameLowering.cpp @@ -22,6 +22,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Support/CommandLine.h" @@ -476,6 +477,15 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF) const { .addReg(StackPtr); if (needsFrameMoves) { + const MCAsmInfo &MAI = MMI.getContext().getAsmInfo(); + if (MAI.getExceptionHandlingType() == ExceptionHandling::DwarfCFI) { + MCSymbol *FrameLabel0 = MMI.getContext().CreateTempSymbol(); + BuildMI(MBB, MBBI, DL, TII.get(X86::PROLOG_LABEL)).addSym(FrameLabel0); + MachineLocation FPSrc0(FramePtr); + MachineLocation FPDst0(FramePtr, -2 * stackGrowth); + Moves.push_back(MachineMove(FrameLabel0, FPDst0, FPSrc0)); + } + // Mark effective beginning of when frame pointer becomes valid. MCSymbol *FrameLabel = MMI.getContext().CreateTempSymbol(); BuildMI(MBB, MBBI, DL, TII.get(X86::PROLOG_LABEL)).addSym(FrameLabel); @@ -615,7 +625,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF) const { emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, TII, *RegInfo); - if ((NumBytes || PushedRegs) && needsFrameMoves) { + if (( (!HasFP && NumBytes) || PushedRegs) && needsFrameMoves) { // Mark end of stack pointer adjustment. MCSymbol *Label = MMI.getContext().CreateTempSymbol(); BuildMI(MBB, MBBI, DL, TII.get(X86::PROLOG_LABEL)).addSym(Label); diff --git a/lib/Target/X86/X86MCAsmInfo.cpp b/lib/Target/X86/X86MCAsmInfo.cpp index 6686214e06f..62951897724 100644 --- a/lib/Target/X86/X86MCAsmInfo.cpp +++ b/lib/Target/X86/X86MCAsmInfo.cpp @@ -89,7 +89,9 @@ X86ELFMCAsmInfo::X86ELFMCAsmInfo(const Triple &T) { SupportsDebugInformation = true; // Exceptions handling - ExceptionsType = ExceptionHandling::DwarfTable; + ExceptionsType = ExceptionHandling::DwarfCFI; + + DwarfRequiresFrameSection = false; // OpenBSD has buggy support for .quad in 32-bit mode, just split into two // .words. diff --git a/test/CodeGen/X86/2007-05-05-Personality.ll b/test/CodeGen/X86/2007-05-05-Personality.ll index a9b17d3b8f3..e69b511f4c5 100644 --- a/test/CodeGen/X86/2007-05-05-Personality.ll +++ b/test/CodeGen/X86/2007-05-05-Personality.ll @@ -1,4 +1,7 @@ -; RUN: llc < %s -mtriple=i686-pc-linux-gnu -o - | grep zPL +; RUN: llc < %s -mtriple=i686-pc-linux-gnu -o - | FileCheck %s + +; CHECK: .cfi_lsda 0, .Lexception0 +; CHECK: .cfi_personality 0, __gnat_eh_personality @error = external global i8 ; [#uses=2] diff --git a/test/CodeGen/X86/2008-12-12-PrivateEHSymbol.ll b/test/CodeGen/X86/2008-12-12-PrivateEHSymbol.ll deleted file mode 100644 index e97b63db14d..00000000000 --- a/test/CodeGen/X86/2008-12-12-PrivateEHSymbol.ll +++ /dev/null @@ -1,12 +0,0 @@ -; RUN: llc < %s -march=x86-64 -mtriple=x86_64-unknown-linux-gnu | grep ^.L_Z1fv.eh -; RUN: llc < %s -march=x86 -mtriple=i686-unknown-linux-gnu | grep ^.L_Z1fv.eh -; RUN: llc < %s -march=x86-64 -mtriple=x86_64-apple-darwin9 | grep ^__Z1fv.eh -; RUN: llc < %s -march=x86 -mtriple=i386-apple-darwin9 | grep ^__Z1fv.eh - -define void @_Z1fv() { -entry: - br label %return - -return: - ret void -} diff --git a/test/CodeGen/X86/aliases.ll b/test/CodeGen/X86/aliases.ll index 3ed3bd67cef..f92027998a4 100644 --- a/test/CodeGen/X86/aliases.ll +++ b/test/CodeGen/X86/aliases.ll @@ -1,6 +1,4 @@ ; RUN: llc < %s -mtriple=i686-pc-linux-gnu -asm-verbose=false -o %t -; RUN: grep { = } %t | count 16 -; RUN: grep set %t | count 18 ; RUN: grep globl %t | count 6 ; RUN: grep weak %t | count 1 ; RUN: grep hidden %t | count 1