aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2011-04-14 15:18:53 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2011-04-14 15:18:53 +0000
commit3dae6e7333b8fae7b79ddb99757ab5de73890af9 (patch)
tree7e47ed860ee48844bf17246b804d1e9ffeda5132
parent9a0bac41b3526fea1e148224e88b31439134098e (diff)
Change ELF systems to use CFI for producing the EH tables. This reduces the
size of the clang binary in Debug builds from 690MB to 679MB. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@129518 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h2
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp43
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfCFIException.cpp42
-rw-r--r--lib/Target/TargetLoweringObjectFile.cpp2
-rw-r--r--lib/Target/X86/X86FrameLowering.cpp12
-rw-r--r--lib/Target/X86/X86MCAsmInfo.cpp4
-rw-r--r--test/CodeGen/X86/2007-05-05-Personality.ll5
-rw-r--r--test/CodeGen/X86/2008-12-12-PrivateEHSymbol.ll12
-rw-r--r--test/CodeGen/X86/aliases.ll2
9 files changed, 91 insertions, 33 deletions
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index a071febb10..81e73a6798 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 3d3abc2fed..baf11a77db 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<MachineMove> &Moves = MMI.getFrameMoves();
+ const MachineMove *Move = NULL;
+ for (std::vector<MachineMove>::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 68be2eed8f..aff86bb635 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<const Function*> &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);
}
}
@@ -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<MachineMove> 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 5d34c7d7fa..7eeec5dda4 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 071fbe0cef..52ea6a847c 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 6686214e06..6295189772 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 a9b17d3b8f..e69b511f4c 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 ; <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 e97b63db14..0000000000
--- 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 3ed3bd67ce..f92027998a 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