mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
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. llvm-svn: 132033
This commit is contained in:
parent
a5b11ee449
commit
70213c7c5f
@ -67,6 +67,20 @@ const Attributes StackAlignment = 7<<26; ///< Alignment of stack for
|
|||||||
///alignstack(1))
|
///alignstack(1))
|
||||||
const Attributes Hotpatch = 1<<29; ///< Function should have special
|
const Attributes Hotpatch = 1<<29; ///< Function should have special
|
||||||
///'hotpatch' sequence in prologue
|
///'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.
|
/// @brief Attributes that only apply to function parameters.
|
||||||
const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture;
|
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 |
|
const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly |
|
||||||
NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq |
|
NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq |
|
||||||
NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment |
|
NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment |
|
||||||
Hotpatch;
|
Hotpatch | UWTable;
|
||||||
|
|
||||||
/// @brief Parameter attributes that do not apply to vararg call arguments.
|
/// @brief Parameter attributes that do not apply to vararg call arguments.
|
||||||
const Attributes VarArgsIncompatible = StructRet;
|
const Attributes VarArgsIncompatible = StructRet;
|
||||||
|
@ -253,6 +253,22 @@ public:
|
|||||||
else removeFnAttr(Attribute::NoUnwind);
|
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
|
/// @brief Determine if the function returns a structure through first
|
||||||
/// pointer argument.
|
/// pointer argument.
|
||||||
bool hasStructRetAttr() const {
|
bool hasStructRetAttr() const {
|
||||||
|
@ -125,10 +125,6 @@ namespace llvm {
|
|||||||
/// flag is hidden and is only for debugging the debug info.
|
/// flag is hidden and is only for debugging the debug info.
|
||||||
extern bool JITEmitDebugInfoToDisk;
|
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
|
/// GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is
|
||||||
/// specified on the commandline. When the flag is on, participating targets
|
/// specified on the commandline. When the flag is on, participating targets
|
||||||
/// will perform tail call optimization on all calls which use the fastcc
|
/// will perform tail call optimization on all calls which use the fastcc
|
||||||
|
@ -565,6 +565,7 @@ lltok::Kind LLLexer::LexIdentifier() {
|
|||||||
KEYWORD(nest);
|
KEYWORD(nest);
|
||||||
KEYWORD(readnone);
|
KEYWORD(readnone);
|
||||||
KEYWORD(readonly);
|
KEYWORD(readonly);
|
||||||
|
KEYWORD(uwtable);
|
||||||
|
|
||||||
KEYWORD(inlinehint);
|
KEYWORD(inlinehint);
|
||||||
KEYWORD(noinline);
|
KEYWORD(noinline);
|
||||||
|
@ -972,6 +972,7 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) {
|
|||||||
|
|
||||||
case lltok::kw_noreturn: Attrs |= Attribute::NoReturn; break;
|
case lltok::kw_noreturn: Attrs |= Attribute::NoReturn; break;
|
||||||
case lltok::kw_nounwind: Attrs |= Attribute::NoUnwind; 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_noinline: Attrs |= Attribute::NoInline; break;
|
||||||
case lltok::kw_readnone: Attrs |= Attribute::ReadNone; break;
|
case lltok::kw_readnone: Attrs |= Attribute::ReadNone; break;
|
||||||
case lltok::kw_readonly: Attrs |= Attribute::ReadOnly; break;
|
case lltok::kw_readonly: Attrs |= Attribute::ReadOnly; break;
|
||||||
|
@ -87,6 +87,7 @@ namespace lltok {
|
|||||||
kw_nest,
|
kw_nest,
|
||||||
kw_readnone,
|
kw_readnone,
|
||||||
kw_readonly,
|
kw_readonly,
|
||||||
|
kw_uwtable,
|
||||||
|
|
||||||
kw_inlinehint,
|
kw_inlinehint,
|
||||||
kw_noinline,
|
kw_noinline,
|
||||||
|
@ -52,7 +52,7 @@ void ARMException::EndModule() {
|
|||||||
/// being emitted immediately after the function entry point.
|
/// being emitted immediately after the function entry point.
|
||||||
void ARMException::BeginFunction(const MachineFunction *MF) {
|
void ARMException::BeginFunction(const MachineFunction *MF) {
|
||||||
Asm->OutStreamer.EmitFnStart();
|
Asm->OutStreamer.EmitFnStart();
|
||||||
if (!Asm->MF->getFunction()->doesNotThrow() || UnwindTablesMandatory)
|
if (Asm->MF->getFunction()->needsUnwindTableEntry())
|
||||||
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
|
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
|
||||||
Asm->getFunctionNumber()));
|
Asm->getFunctionNumber()));
|
||||||
}
|
}
|
||||||
@ -60,7 +60,7 @@ void ARMException::BeginFunction(const MachineFunction *MF) {
|
|||||||
/// EndFunction - Gather and emit post-function exception information.
|
/// EndFunction - Gather and emit post-function exception information.
|
||||||
///
|
///
|
||||||
void ARMException::EndFunction() {
|
void ARMException::EndFunction() {
|
||||||
if (Asm->MF->getFunction()->doesNotThrow() && !UnwindTablesMandatory)
|
if (!Asm->MF->getFunction()->needsUnwindTableEntry())
|
||||||
Asm->OutStreamer.EmitCantUnwind();
|
Asm->OutStreamer.EmitCantUnwind();
|
||||||
else {
|
else {
|
||||||
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end",
|
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end",
|
||||||
|
@ -591,13 +591,9 @@ static bool EmitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AsmPrinter::CFIMoveType AsmPrinter::needsCFIMoves() {
|
AsmPrinter::CFIMoveType AsmPrinter::needsCFIMoves() {
|
||||||
if (MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI) {
|
if (MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI &&
|
||||||
if (UnwindTablesMandatory)
|
MF->getFunction()->needsUnwindTableEntry())
|
||||||
return CFI_M_EH;
|
return CFI_M_EH;
|
||||||
|
|
||||||
if (!MF->getFunction()->doesNotThrow())
|
|
||||||
return CFI_M_EH;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MMI->hasDebugInfo())
|
if (MMI->hasDebugInfo())
|
||||||
return CFI_M_Debug;
|
return CFI_M_Debug;
|
||||||
|
@ -259,8 +259,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
|
|||||||
MachineModuleInfo &MMI = MF.getMMI();
|
MachineModuleInfo &MMI = MF.getMMI();
|
||||||
DebugLoc dl;
|
DebugLoc dl;
|
||||||
bool needsFrameMoves = MMI.hasDebugInfo() ||
|
bool needsFrameMoves = MMI.hasDebugInfo() ||
|
||||||
!MF.getFunction()->doesNotThrow() ||
|
MF.getFunction()->needsUnwindTableEntry();
|
||||||
UnwindTablesMandatory;
|
|
||||||
|
|
||||||
// Prepare for frame info.
|
// Prepare for frame info.
|
||||||
MCSymbol *FrameLabel = 0;
|
MCSymbol *FrameLabel = 0;
|
||||||
|
@ -40,7 +40,6 @@ namespace llvm {
|
|||||||
bool JITExceptionHandling;
|
bool JITExceptionHandling;
|
||||||
bool JITEmitDebugInfo;
|
bool JITEmitDebugInfo;
|
||||||
bool JITEmitDebugInfoToDisk;
|
bool JITEmitDebugInfoToDisk;
|
||||||
bool UnwindTablesMandatory;
|
|
||||||
Reloc::Model RelocationModel;
|
Reloc::Model RelocationModel;
|
||||||
CodeModel::Model CMModel;
|
CodeModel::Model CMModel;
|
||||||
bool GuaranteedTailCallOpt;
|
bool GuaranteedTailCallOpt;
|
||||||
@ -143,11 +142,6 @@ EmitJitDebugInfoToDisk("jit-emit-debug-to-disk",
|
|||||||
cl::desc("Emit debug info objfiles to disk"),
|
cl::desc("Emit debug info objfiles to disk"),
|
||||||
cl::location(JITEmitDebugInfoToDisk),
|
cl::location(JITEmitDebugInfoToDisk),
|
||||||
cl::init(false));
|
cl::init(false));
|
||||||
static cl::opt<bool, true>
|
|
||||||
EnableUnwindTables("unwind-tables",
|
|
||||||
cl::desc("Generate unwinding tables for all functions"),
|
|
||||||
cl::location(UnwindTablesMandatory),
|
|
||||||
cl::init(false));
|
|
||||||
|
|
||||||
static cl::opt<llvm::Reloc::Model, true>
|
static cl::opt<llvm::Reloc::Model, true>
|
||||||
DefRelocationModel("relocation-model",
|
DefRelocationModel("relocation-model",
|
||||||
|
@ -355,7 +355,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF) const {
|
|||||||
MachineModuleInfo &MMI = MF.getMMI();
|
MachineModuleInfo &MMI = MF.getMMI();
|
||||||
X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
|
X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
|
||||||
bool needsFrameMoves = MMI.hasDebugInfo() ||
|
bool needsFrameMoves = MMI.hasDebugInfo() ||
|
||||||
!Fn->doesNotThrow() || UnwindTablesMandatory;
|
Fn->needsUnwindTableEntry();
|
||||||
uint64_t MaxAlign = MFI->getMaxAlignment(); // Desired stack alignment.
|
uint64_t MaxAlign = MFI->getMaxAlignment(); // Desired stack alignment.
|
||||||
uint64_t StackSize = MFI->getStackSize(); // Number of bytes to allocate.
|
uint64_t StackSize = MFI->getStackSize(); // Number of bytes to allocate.
|
||||||
bool HasFP = hasFP(MF);
|
bool HasFP = hasFP(MF);
|
||||||
|
@ -68,8 +68,8 @@ unsigned XCoreRegisterInfo::getNumArgRegs(const MachineFunction *MF)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF) {
|
bool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF) {
|
||||||
return MF.getMMI().hasDebugInfo() || !MF.getFunction()->doesNotThrow() ||
|
return MF.getMMI().hasDebugInfo() ||
|
||||||
UnwindTablesMandatory;
|
MF.getFunction()->needsUnwindTableEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned* XCoreRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF)
|
const unsigned* XCoreRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF)
|
||||||
|
@ -36,6 +36,8 @@ std::string Attribute::getAsString(Attributes Attrs) {
|
|||||||
Result += "noreturn ";
|
Result += "noreturn ";
|
||||||
if (Attrs & Attribute::NoUnwind)
|
if (Attrs & Attribute::NoUnwind)
|
||||||
Result += "nounwind ";
|
Result += "nounwind ";
|
||||||
|
if (Attrs & Attribute::UWTable)
|
||||||
|
Result += "uwtable ";
|
||||||
if (Attrs & Attribute::InReg)
|
if (Attrs & Attribute::InReg)
|
||||||
Result += "inreg ";
|
Result += "inreg ";
|
||||||
if (Attrs & Attribute::NoAlias)
|
if (Attrs & Attribute::NoAlias)
|
||||||
|
@ -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]
|
@.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:
|
entry:
|
||||||
%0 = call i32 @puts(i8* getelementptr inbounds ([12 x i8]* @.str, i64 0, i64 0)) nounwind ; <i32> [#uses=0]
|
%0 = call i32 @puts(i8* getelementptr inbounds ([12 x i8]* @.str, i64 0, i64 0)) nounwind ; <i32> [#uses=0]
|
||||||
br label %return
|
br label %return
|
||||||
@ -37,7 +37,7 @@ return: ; preds = %entry
|
|||||||
|
|
||||||
declare i32 @puts(i8*)
|
declare i32 @puts(i8*)
|
||||||
|
|
||||||
define hidden i32 @main() nounwind ssp {
|
define hidden i32 @main() nounwind ssp uwtable {
|
||||||
entry:
|
entry:
|
||||||
%retval = alloca i32 ; <i32*> [#uses=1]
|
%retval = alloca i32 ; <i32*> [#uses=1]
|
||||||
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
|
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user