From fc2bb8c4448fa884d79e437cc2d2627a7d7740a8 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 25 May 2011 03:44:17 +0000 Subject: [PATCH] Replace the -unwind-tables option with a per function flag. This is more LTO friendly as we can now correctly merge files compiled with or without -fasynchronous-unwind-tables. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132033 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Attributes.h | 16 +++++++++++++++- include/llvm/Function.h | 16 ++++++++++++++++ include/llvm/Target/TargetOptions.h | 4 ---- lib/AsmParser/LLLexer.cpp | 1 + lib/AsmParser/LLParser.cpp | 1 + lib/AsmParser/LLToken.h | 1 + lib/CodeGen/AsmPrinter/ARMException.cpp | 4 ++-- lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 10 +++------- lib/Target/PowerPC/PPCFrameLowering.cpp | 3 +-- lib/Target/TargetMachine.cpp | 6 ------ lib/Target/X86/X86FrameLowering.cpp | 2 +- lib/Target/XCore/XCoreRegisterInfo.cpp | 4 ++-- lib/VMCore/Attributes.cpp | 2 ++ test/CodeGen/X86/hidden-vis-pic.ll | 6 +++--- 14 files changed, 48 insertions(+), 28 deletions(-) diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h index da6188b1a8e..57c84357aeb 100644 --- a/include/llvm/Attributes.h +++ b/include/llvm/Attributes.h @@ -67,6 +67,20 @@ const Attributes StackAlignment = 7<<26; ///< Alignment of stack for ///alignstack(1)) const Attributes Hotpatch = 1<<29; ///< Function should have special ///'hotpatch' sequence in prologue +const Attributes UWTable = 1<<30; ///< Function must be in a unwind + ///table + +/// Note that uwtable is about the ABI or the user mandating an entry in the +/// unwind table. The nounwind attribute is about an exception passing by the +/// function. +/// In a theoretical system that uses tables for profiling and sjlj for +/// exceptions, they would be fully independent. In a normal system that +/// uses tables for both, the semantics are: +/// nil = Needs an entry because an exception might pass by. +/// nounwind = No need for an entry +/// ehframe = Needs an entry because the ABI says so and because +/// an exception might pass by. +/// ehframe + nounwind = Needs an entry because the ABI says so. /// @brief Attributes that only apply to function parameters. const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; @@ -76,7 +90,7 @@ const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly | NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq | NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment | - Hotpatch; + Hotpatch | UWTable; /// @brief Parameter attributes that do not apply to vararg call arguments. const Attributes VarArgsIncompatible = StructRet; diff --git a/include/llvm/Function.h b/include/llvm/Function.h index b34a6b25421..9319a5b39e8 100644 --- a/include/llvm/Function.h +++ b/include/llvm/Function.h @@ -253,6 +253,22 @@ public: else removeFnAttr(Attribute::NoUnwind); } + /// @brief True if the ABI mandates this function be in a unwind table. + bool hasUWTable() const { + return hasFnAttr(Attribute::UWTable); + } + void setHasUWTable(bool HasUWTable = true) { + if (HasUWTable) + addFnAttr(Attribute::UWTable); + else + removeFnAttr(Attribute::UWTable); + } + + /// @brief True if this function needs in a unwind table. + bool needsUnwindTableEntry() const { + return hasUWTable() || !doesNotThrow(); + } + /// @brief Determine if the function returns a structure through first /// pointer argument. bool hasStructRetAttr() const { diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index 62190c166e3..beed039d1da 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -125,10 +125,6 @@ namespace llvm { /// flag is hidden and is only for debugging the debug info. extern bool JITEmitDebugInfoToDisk; - /// UnwindTablesMandatory - This flag indicates that unwind tables should - /// be emitted for all functions. - extern bool UnwindTablesMandatory; - /// GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is /// specified on the commandline. When the flag is on, participating targets /// will perform tail call optimization on all calls which use the fastcc diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index 857fa1ef626..48a0eaf9360 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -565,6 +565,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(nest); KEYWORD(readnone); KEYWORD(readonly); + KEYWORD(uwtable); KEYWORD(inlinehint); KEYWORD(noinline); diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 9df98b127bc..81e0747266f 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -972,6 +972,7 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) { case lltok::kw_noreturn: Attrs |= Attribute::NoReturn; break; case lltok::kw_nounwind: Attrs |= Attribute::NoUnwind; break; + case lltok::kw_uwtable: Attrs |= Attribute::UWTable; break; case lltok::kw_noinline: Attrs |= Attribute::NoInline; break; case lltok::kw_readnone: Attrs |= Attribute::ReadNone; break; case lltok::kw_readonly: Attrs |= Attribute::ReadOnly; break; diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index 576da191aec..02f97a3d3d2 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -87,6 +87,7 @@ namespace lltok { kw_nest, kw_readnone, kw_readonly, + kw_uwtable, kw_inlinehint, kw_noinline, diff --git a/lib/CodeGen/AsmPrinter/ARMException.cpp b/lib/CodeGen/AsmPrinter/ARMException.cpp index 0db28a636ad..5861fa4817f 100644 --- a/lib/CodeGen/AsmPrinter/ARMException.cpp +++ b/lib/CodeGen/AsmPrinter/ARMException.cpp @@ -52,7 +52,7 @@ void ARMException::EndModule() { /// being emitted immediately after the function entry point. void ARMException::BeginFunction(const MachineFunction *MF) { Asm->OutStreamer.EmitFnStart(); - if (!Asm->MF->getFunction()->doesNotThrow() || UnwindTablesMandatory) + if (Asm->MF->getFunction()->needsUnwindTableEntry()) Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin", Asm->getFunctionNumber())); } @@ -60,7 +60,7 @@ void ARMException::BeginFunction(const MachineFunction *MF) { /// EndFunction - Gather and emit post-function exception information. /// void ARMException::EndFunction() { - if (Asm->MF->getFunction()->doesNotThrow() && !UnwindTablesMandatory) + if (!Asm->MF->getFunction()->needsUnwindTableEntry()) Asm->OutStreamer.EmitCantUnwind(); else { Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end", diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 5a913410970..b1aa8d244c3 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -591,13 +591,9 @@ static bool EmitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) { } AsmPrinter::CFIMoveType AsmPrinter::needsCFIMoves() { - if (MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI) { - if (UnwindTablesMandatory) - return CFI_M_EH; - - if (!MF->getFunction()->doesNotThrow()) - return CFI_M_EH; - } + if (MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI && + MF->getFunction()->needsUnwindTableEntry()) + return CFI_M_EH; if (MMI->hasDebugInfo()) return CFI_M_Debug; diff --git a/lib/Target/PowerPC/PPCFrameLowering.cpp b/lib/Target/PowerPC/PPCFrameLowering.cpp index 6aca6b00a06..9d8ef5feef3 100644 --- a/lib/Target/PowerPC/PPCFrameLowering.cpp +++ b/lib/Target/PowerPC/PPCFrameLowering.cpp @@ -259,8 +259,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const { MachineModuleInfo &MMI = MF.getMMI(); DebugLoc dl; bool needsFrameMoves = MMI.hasDebugInfo() || - !MF.getFunction()->doesNotThrow() || - UnwindTablesMandatory; + MF.getFunction()->needsUnwindTableEntry(); // Prepare for frame info. MCSymbol *FrameLabel = 0; diff --git a/lib/Target/TargetMachine.cpp b/lib/Target/TargetMachine.cpp index 76ccc09195a..863b8114dc3 100644 --- a/lib/Target/TargetMachine.cpp +++ b/lib/Target/TargetMachine.cpp @@ -40,7 +40,6 @@ namespace llvm { bool JITExceptionHandling; bool JITEmitDebugInfo; bool JITEmitDebugInfoToDisk; - bool UnwindTablesMandatory; Reloc::Model RelocationModel; CodeModel::Model CMModel; bool GuaranteedTailCallOpt; @@ -143,11 +142,6 @@ EmitJitDebugInfoToDisk("jit-emit-debug-to-disk", cl::desc("Emit debug info objfiles to disk"), cl::location(JITEmitDebugInfoToDisk), cl::init(false)); -static cl::opt -EnableUnwindTables("unwind-tables", - cl::desc("Generate unwinding tables for all functions"), - cl::location(UnwindTablesMandatory), - cl::init(false)); static cl::opt DefRelocationModel("relocation-model", diff --git a/lib/Target/X86/X86FrameLowering.cpp b/lib/Target/X86/X86FrameLowering.cpp index 06d12fc04a3..2e95300160d 100644 --- a/lib/Target/X86/X86FrameLowering.cpp +++ b/lib/Target/X86/X86FrameLowering.cpp @@ -355,7 +355,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF) const { MachineModuleInfo &MMI = MF.getMMI(); X86MachineFunctionInfo *X86FI = MF.getInfo(); bool needsFrameMoves = MMI.hasDebugInfo() || - !Fn->doesNotThrow() || UnwindTablesMandatory; + Fn->needsUnwindTableEntry(); uint64_t MaxAlign = MFI->getMaxAlignment(); // Desired stack alignment. uint64_t StackSize = MFI->getStackSize(); // Number of bytes to allocate. bool HasFP = hasFP(MF); diff --git a/lib/Target/XCore/XCoreRegisterInfo.cpp b/lib/Target/XCore/XCoreRegisterInfo.cpp index 0287a513583..00b8b75c9b9 100644 --- a/lib/Target/XCore/XCoreRegisterInfo.cpp +++ b/lib/Target/XCore/XCoreRegisterInfo.cpp @@ -68,8 +68,8 @@ unsigned XCoreRegisterInfo::getNumArgRegs(const MachineFunction *MF) } bool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF) { - return MF.getMMI().hasDebugInfo() || !MF.getFunction()->doesNotThrow() || - UnwindTablesMandatory; + return MF.getMMI().hasDebugInfo() || + MF.getFunction()->needsUnwindTableEntry(); } const unsigned* XCoreRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp index 92152a3b90a..ee257dbde5f 100644 --- a/lib/VMCore/Attributes.cpp +++ b/lib/VMCore/Attributes.cpp @@ -36,6 +36,8 @@ std::string Attribute::getAsString(Attributes Attrs) { Result += "noreturn "; if (Attrs & Attribute::NoUnwind) Result += "nounwind "; + if (Attrs & Attribute::UWTable) + Result += "uwtable "; if (Attrs & Attribute::InReg) Result += "inreg "; if (Attrs & Attribute::NoAlias) diff --git a/test/CodeGen/X86/hidden-vis-pic.ll b/test/CodeGen/X86/hidden-vis-pic.ll index 217dba6944b..67be3d0ffca 100644 --- a/test/CodeGen/X86/hidden-vis-pic.ll +++ b/test/CodeGen/X86/hidden-vis-pic.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -disable-cfi -mtriple=i386-apple-darwin9 -relocation-model=pic -disable-fp-elim -unwind-tables | FileCheck %s +; RUN: llc < %s -disable-cfi -mtriple=i386-apple-darwin9 -relocation-model=pic -disable-fp-elim | FileCheck %s @@ -26,7 +26,7 @@ entry: @.str = private constant [12 x i8] c"hello world\00", align 1 ; <[12 x i8]*> [#uses=1] -define hidden void @func() nounwind ssp { +define hidden void @func() nounwind ssp uwtable { entry: %0 = call i32 @puts(i8* getelementptr inbounds ([12 x i8]* @.str, i64 0, i64 0)) nounwind ; [#uses=0] br label %return @@ -37,7 +37,7 @@ return: ; preds = %entry declare i32 @puts(i8*) -define hidden i32 @main() nounwind ssp { +define hidden i32 @main() nounwind ssp uwtable { entry: %retval = alloca i32 ; [#uses=1] %"alloca point" = bitcast i32 0 to i32 ; [#uses=0]