summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/ExceptionHandling.html39
-rw-r--r--include/llvm/CodeGen/MachineFunction.h45
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h4
-rw-r--r--include/llvm/Intrinsics.td6
-rw-r--r--include/llvm/Target/TargetAsmInfo.h10
-rw-r--r--include/llvm/Target/TargetOptions.h12
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.cpp166
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.h1
-rw-r--r--lib/CodeGen/LLVMTargetMachine.cpp13
-rw-r--r--lib/CodeGen/MachineFunction.cpp3
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp1
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp11
-rw-r--r--lib/ExecutionEngine/JIT/JITEmitter.cpp8
-rw-r--r--lib/Target/ARM/ARMConstantPoolValue.cpp2
-rw-r--r--lib/Target/ARM/ARMConstantPoolValue.h2
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp31
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td9
-rw-r--r--lib/Target/ARM/ARMTargetAsmInfo.cpp6
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp2
-rw-r--r--lib/Target/CellSPU/SPUTargetAsmInfo.cpp2
-rw-r--r--lib/Target/PowerPC/PPCTargetAsmInfo.cpp6
-rw-r--r--lib/Target/TargetAsmInfo.cpp2
-rw-r--r--lib/Target/TargetMachine.cpp12
-rw-r--r--lib/Target/X86/X86TargetAsmInfo.cpp4
-rw-r--r--tools/lto/LTOCodeGenerator.cpp16
25 files changed, 333 insertions, 80 deletions
diff --git a/docs/ExceptionHandling.html b/docs/ExceptionHandling.html
index 6ec6ab8233..851ed1238b 100644
--- a/docs/ExceptionHandling.html
+++ b/docs/ExceptionHandling.html
@@ -33,6 +33,8 @@
<li><a href="#llvm_eh_typeid_for"><tt>llvm.eh.typeid.for</tt></a></li>
<li><a href="#llvm_eh_sjlj_setjmp"><tt>llvm.eh.sjlj.setjmp</tt></a></li>
<li><a href="#llvm_eh_sjlj_longjmp"><tt>llvm.eh.sjlj.longjmp</tt></a></li>
+ <li><a href="#llvm_eh_sjlj_lsda"><tt>llvm.eh.sjlj.lsda</tt></a></li>
+ <li><a href="#llvm_eh_sjlj_callsite"><tt>llvm.eh.sjlj.callsite</tt></a></li>
</ol></li>
<li><a href="#asm">Asm Table Formats</a>
<ol>
@@ -414,7 +416,7 @@ a reference to a type info.</p>
<p>The SJLJ exception handling uses this intrinsic to force register saving
for the current function and to store the address of the following instruction
-for use as a destination address by <a href="#llvm_eh_sjlj_setjmp">
+for use as a destination address by <a href="#llvm_eh_sjlj_longjmp">
<tt>llvm.eh.sjlj.longjmp</tt></a>. The buffer format and the overall functioning
of this intrinsic is compatible with the GCC <tt>__builtin_setjmp</tt>
implementation, allowing code built with the two compilers to interoperate.</p>
@@ -429,6 +431,41 @@ are available for use in a target-specific manner.</p>
</div>
<!-- ======================================================================= -->
+<div class="doc_subsubsection">
+ <a name="llvm_eh_sjlj_lsda">llvm.eh.sjlj.lsda</a>
+</div>
+
+<div class="doc_text">
+<pre>
+ i8* %<a href="#llvm_eh_sjlj_lsda">llvm.eh.sjlj.lsda</a>( )
+</pre>
+
+<p>Used for SJLJ based exception handling, the <a href="#llvm_eh_sjlj_lsda">
+ <tt>llvm.eh.sjlj.lsda</tt></a> intrinsic returns the address of the Language
+Specific Data Area (LSDA) for the current function. The SJLJ front-end code
+stores this address in the exception handling function context for use by
+the runtime.</p>
+
+</div>
+
+<!-- ======================================================================= -->
+<div class="doc_subsubsection">
+ <a name="llvm_eh_sjlj_callsite">llvm.eh.sjlj.callsite</a>
+</div>
+
+<div class="doc_text">
+<pre>
+ void %<a href="#llvm_eh_sjlj_callsite">llvm.eh.sjlj.callsite</a>(i32)
+</pre>
+
+<p>The SJLJ front-end allocates call site indices for invoke instrucitons.
+These values are passed to the back-end via the
+<a href="#llvm_eh_sjlj_callsite"><tt>llvm.eh.sjlj.callsite</tt></a>
+intrinsic, where they are used to build the LSDA call-site table.</p>
+
+</div>
+
+<!-- ======================================================================= -->
<div class="doc_section">
<a name="asm">Asm Table Formats</a>
</div>
diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h
index 57c946c789..f30cb821c1 100644
--- a/include/llvm/CodeGen/MachineFunction.h
+++ b/include/llvm/CodeGen/MachineFunction.h
@@ -18,6 +18,7 @@
#ifndef LLVM_CODEGEN_MACHINEFUNCTION_H
#define LLVM_CODEGEN_MACHINEFUNCTION_H
+#include <map>
#include "llvm/ADT/ilist.h"
#include "llvm/Support/DebugLoc.h"
#include "llvm/CodeGen/Dump.h"
@@ -114,6 +115,15 @@ class MachineFunction {
// The alignment of the function.
unsigned Alignment;
+ // The currently active call_site value
+ unsigned CallSiteIndex;
+
+ // The largest call_site value encountered
+ unsigned MaxCallSiteIndex;
+
+ // Call sites mapped to corresponding landing pads
+ std::map<MachineBasicBlock*, unsigned> LandingPadCallSiteIndexMap;
+
public:
MachineFunction(Function *Fn, const TargetMachine &TM);
~MachineFunction();
@@ -159,6 +169,41 @@ public:
///
void setAlignment(unsigned A) { Alignment = A; }
+ /// getCallSiteIndex() - Get the current call site index
+ ///
+ unsigned getCallSiteIndex() { return CallSiteIndex; }
+
+ /// setCallSiteIndex() - Set the current call site index
+ ///
+ void setCallSiteIndex(unsigned Idx) {
+ CallSiteIndex = Idx;
+ if (CallSiteIndex > MaxCallSiteIndex)
+ MaxCallSiteIndex = CallSiteIndex;
+ }
+
+ /// getMaxCallSiteIndex() - Get the largest call site index issued
+ ///
+ unsigned getMaxCallSiteIndex() { return MaxCallSiteIndex; }
+
+ /// setCallSiteIndexLandingPad() - Map the call site to a landing pad
+ ///
+ void setLandingPadCallSiteIndex(MachineBasicBlock *LandingPad,
+ unsigned CallSite) {
+ LandingPadCallSiteIndexMap[LandingPad] = CallSite;
+ }
+
+ /// getCallSiteIndexLandingPad() - Get landing pad for the call site index
+ ///
+ unsigned getLandingPadCallSiteIndex(MachineBasicBlock *LandingPad) {
+ return LandingPadCallSiteIndexMap[LandingPad];
+ }
+
+ /// getCallSiteCount() - Get the count of call site entries
+ ///
+ unsigned getCallSiteCount() {
+ return LandingPadCallSiteIndexMap.size();
+ }
+
/// MachineFunctionInfo - Keep track of various per-function pieces of
/// information for backends that would like to do so.
///
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index bbb1f3bd90..7229463d4e 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -121,6 +121,10 @@ namespace ISD {
// address of the exception block on entry to an landing pad block.
EXCEPTIONADDR,
+ // RESULT, OUTCHAIN = LSDAADDR(INCHAIN) - This node represents the
+ // address of the Language Specific Data Area for the enclosing function.
+ LSDAADDR,
+
// RESULT, OUTCHAIN = EHSELECTION(INCHAIN, EXCEPTION) - This node represents
// the selection index of the exception thrown.
EHSELECTION,
diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td
index fa21dc0682..25f6604afa 100644
--- a/include/llvm/Intrinsics.td
+++ b/include/llvm/Intrinsics.td
@@ -305,8 +305,10 @@ def int_eh_unwind_init: Intrinsic<[llvm_void_ty]>,
def int_eh_dwarf_cfa : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty]>;
let Properties = [IntrNoMem] in {
-def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>;
-def int_eh_sjlj_longjmp : Intrinsic<[llvm_void_ty], [llvm_ptr_ty, llvm_i32_ty]>;
+ def int_eh_sjlj_setjmp : Intrinsic<[llvm_i32_ty], [llvm_ptr_ty]>;
+ def int_eh_sjlj_longjmp : Intrinsic<[llvm_void_ty], [llvm_ptr_ty]>;
+ def int_eh_sjlj_lsda : Intrinsic<[llvm_ptr_ty]>;
+ def int_eh_sjlj_callsite: Intrinsic<[llvm_void_ty], [llvm_i32_ty]>;
}
//===---------------- Generic Variable Attribute Intrinsics----------------===//
diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h
index aa39c90c5a..2dd644c089 100644
--- a/include/llvm/Target/TargetAsmInfo.h
+++ b/include/llvm/Target/TargetAsmInfo.h
@@ -25,6 +25,8 @@ namespace llvm {
/// TargetAsmInfo - This class is intended to be used as a base class for asm
/// properties and features specific to the target.
+ namespace ExceptionHandling { enum ExceptionsType { None, Dwarf, SjLj }; }
+
class TargetAsmInfo {
protected:
//===------------------------------------------------------------------===//
@@ -269,7 +271,8 @@ namespace llvm {
/// SupportsExceptionHandling - True if target supports
/// exception handling.
///
- bool SupportsExceptionHandling; // Defaults to false.
+ // Defaults to None
+ ExceptionHandling::ExceptionsType ExceptionsType;
/// RequiresFrameSection - true if the Dwarf2 output needs a frame section
///
@@ -482,7 +485,10 @@ namespace llvm {
return SupportsDebugInformation;
}
bool doesSupportExceptionHandling() const {
- return SupportsExceptionHandling;
+ return ExceptionsType != ExceptionHandling::None;
+ }
+ ExceptionHandling::ExceptionsType getExceptionHandlingType() const {
+ return ExceptionsType;
}
bool doesDwarfRequireFrameSection() const {
return DwarfRequiresFrameSection;
diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h
index ccce2f0de8..b27d49630a 100644
--- a/include/llvm/Target/TargetOptions.h
+++ b/include/llvm/Target/TargetOptions.h
@@ -94,10 +94,14 @@ namespace llvm {
/// .bss section. This flag disables such behaviour (necessary, e.g. for
/// crt*.o compiling).
extern bool NoZerosInBSS;
-
- /// ExceptionHandling - This flag indicates that exception information should
- /// be emitted.
- extern bool ExceptionHandling;
+
+ /// DwarfExceptionHandling - This flag indicates that Dwarf exception
+ /// information should be emitted.
+ extern bool DwarfExceptionHandling;
+
+ /// SjLjExceptionHandling - This flag indicates that SJLJ exception
+ /// information should be emitted.
+ extern bool SjLjExceptionHandling;
/// UnwindTablesMandatory - This flag indicates that unwind tables should
/// be emitted for all functions.
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp
index fec1ad7557..a0cd456d37 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp
@@ -364,6 +364,7 @@ ComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads,
/// try-range address.
void DwarfException::
ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
+ std::map<unsigned,CallSiteEntry*> &CallSiteIndexMap,
const RangeMapType &PadMap,
const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
const SmallVectorImpl<unsigned> &FirstActions) {
@@ -405,10 +406,12 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
"Inconsistent landing pad map!");
+ // For Dwarf exception handling (SjLj handling doesn't use this)
// If some instruction between the previous try-range and this one may
// throw, create a call-site entry with no landing pad for the region
// between the try-ranges.
- if (SawPotentiallyThrowing) {
+ if (SawPotentiallyThrowing &&
+ TAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) {
CallSiteEntry Site = {LastLabel, BeginLabel, 0, 0};
CallSites.push_back(Site);
PreviousIsInvoke = false;
@@ -435,6 +438,12 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
// Otherwise, create a new call-site.
CallSites.push_back(Site);
+ // For SjLj handling, map the call site entry to its index
+ if (TAI->getExceptionHandlingType() == ExceptionHandling::SjLj) {
+ unsigned Index =
+ MF->getLandingPadCallSiteIndex(LandingPad->LandingPadBlock);
+ CallSiteIndexMap[Index] = &CallSites.back();
+ }
PreviousIsInvoke = true;
} else {
// Create a gap.
@@ -446,7 +455,8 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
// If some instruction between the previous try-range and the end of the
// function may throw, create a call-site entry with no landing pad for the
// region following the try-range.
- if (SawPotentiallyThrowing) {
+ if (SawPotentiallyThrowing &&
+ TAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) {
CallSiteEntry Site = {LastLabel, 0, 0, 0};
CallSites.push_back(Site);
}
@@ -496,7 +506,7 @@ void DwarfException::EmitExceptionTable() {
// Invokes and nounwind calls have entries in PadMap (due to being bracketed
// by try-range labels when lowered). Ordinary calls do not, so appropriate
- // try-ranges for them need be deduced.
+ // try-ranges for them need be deduced when using Dwarf exception handling.
RangeMapType PadMap;
for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
const LandingPadInfo *LandingPad = LandingPads[i];
@@ -510,7 +520,9 @@ void DwarfException::EmitExceptionTable() {
// Compute the call-site table.
SmallVector<CallSiteEntry, 64> CallSites;
- ComputeCallSiteTable(CallSites, PadMap, LandingPads, FirstActions);
+ std::map<unsigned,CallSiteEntry*> CallSiteIndexMap;
+ ComputeCallSiteTable(CallSites, CallSiteIndexMap, PadMap,
+ LandingPads, FirstActions);
// Final tallies.
@@ -518,12 +530,19 @@ void DwarfException::EmitExceptionTable() {
const unsigned SiteStartSize = sizeof(int32_t); // DW_EH_PE_udata4
const unsigned SiteLengthSize = sizeof(int32_t); // DW_EH_PE_udata4
const unsigned LandingPadSize = sizeof(int32_t); // DW_EH_PE_udata4
- unsigned SizeSites = CallSites.size() * (SiteStartSize +
- SiteLengthSize +
- LandingPadSize);
- for (unsigned i = 0, e = CallSites.size(); i < e; ++i)
+ unsigned SizeSites;
+ if (TAI->getExceptionHandlingType() == ExceptionHandling::SjLj) {
+ SizeSites = (MF->getMaxCallSiteIndex() - CallSites.size()) *
+ TargetAsmInfo::getULEB128Size(0) * 2;
+ } else
+ SizeSites = CallSites.size() *
+ (SiteStartSize + SiteLengthSize + LandingPadSize);
+ for (unsigned i = 0, e = CallSites.size(); i < e; ++i) {
SizeSites += TargetAsmInfo::getULEB128Size(CallSites[i].Action);
-
+ if (TAI->getExceptionHandlingType() == ExceptionHandling::SjLj)
+ SizeSites += TargetAsmInfo::getULEB128Size(i);
+ // FIXME: 'i' above should be the landing pad index
+ }
// Type infos.
const unsigned TypeInfoSize = TD->getPointerSize(); // DW_EH_PE_absptr
unsigned SizeTypes = TypeInfos.size() * TypeInfoSize;
@@ -551,6 +570,11 @@ void DwarfException::EmitExceptionTable() {
}
EmitLabel("exception", SubprogramCount);
+ if (TAI->getExceptionHandlingType() == ExceptionHandling::SjLj) {
+ std::string SjLjName = "_lsda_";
+ SjLjName += MF->getFunction()->getName().str();
+ EmitLabel(SjLjName.c_str(), 0);
+ }
// Emit the header.
Asm->EmitInt8(dwarf::DW_EH_PE_omit);
@@ -600,54 +624,102 @@ void DwarfException::EmitExceptionTable() {
Asm->EOL("TType base offset");
}
#else
- Asm->EmitInt8(dwarf::DW_EH_PE_absptr);
- Asm->EOL("TType format (DW_EH_PE_absptr)");
- Asm->EmitULEB128Bytes(TypeOffset);
- Asm->EOL("TType base offset");
+ // For SjLj exceptions, is there is no TypeInfo, then we just explicitly
+ // say that we're omitting that bit.
+ // FIXME: does this apply to Dwarf also? The above #if 0 implies yes?
+ if (TAI->getExceptionHandlingType() == ExceptionHandling::SjLj
+ && (TypeInfos.empty() || FilterIds.empty())) {
+ Asm->EmitInt8(dwarf::DW_EH_PE_omit);
+ Asm->EOL("TType format (DW_EH_PE_omit)");
+ } else {
+ Asm->EmitInt8(dwarf::DW_EH_PE_absptr);
+ Asm->EOL("TType format (DW_EH_PE_absptr)");
+ Asm->EmitULEB128Bytes(TypeOffset);
+ Asm->EOL("TType base offset");
+ }
#endif
- Asm->EmitInt8(dwarf::DW_EH_PE_udata4);
- Asm->EOL("Call site format (DW_EH_PE_udata4)");
- Asm->EmitULEB128Bytes(SizeSites);
- Asm->EOL("Call-site table length");
+ // SjLj Exception handilng
+ if (TAI->getExceptionHandlingType() == ExceptionHandling::SjLj) {
+ Asm->EmitInt8(dwarf::DW_EH_PE_udata4);
+ Asm->EOL("Call site format (DW_EH_PE_udata4)");
+ Asm->EmitULEB128Bytes(SizeSites);
+ Asm->EOL("Call-site table length");
+
+
+ assert(MF->getCallSiteCount() == CallSites.size());
+
+ // Emit the landing pad site information.
+ // SjLj handling assigned the call site indices in the front end, so
+ // we need to make sure the table here lines up with that. That's pretty
+ // horrible, and should be fixed ASAP to do that stuff in the back end
+ // instead.
+ std::map<unsigned, CallSiteEntry*>::const_iterator I, E;
+ I = CallSiteIndexMap.begin();
+ E = CallSiteIndexMap.end();
+ for (unsigned CurrIdx = 1; I != E; ++I) {
+ // paranoia.
+ assert(CurrIdx <= I->first);
+ // Fill in any gaps in the table
+ while (CurrIdx++ < I->first) {
+ Asm->EmitULEB128Bytes(0);
+ Asm->EOL("Filler landing pad");
+ Asm->EmitULEB128Bytes(0);
+ Asm->EOL("Filler action");
+ }
+ const CallSiteEntry &S = *(I->second);
+ Asm->EmitULEB128Bytes(I->first - 1);
+ Asm->EOL("Landing pad");
+ Asm->EmitULEB128Bytes(S.Action);
+ Asm->EOL("Action");
+ }
+ } else {
+ // DWARF Exception handling
+ assert(TAI->getExceptionHandlingType() == ExceptionHandling::Dwarf);
+
+ Asm->EmitInt8(dwarf::DW_EH_PE_udata4);
+ Asm->EOL("Call site format (DW_EH_PE_udata4)");
+ Asm->EmitULEB128Bytes(SizeSites);
+ Asm->EOL("Call-site table length");
- // Emit the landing pad site information.
- for (SmallVectorImpl<CallSiteEntry>::const_iterator
+ // Emit the landing pad site information.
+ for (SmallVectorImpl<CallSiteEntry>::const_iterator
I = CallSites.begin(), E = CallSites.end(); I != E; ++I) {
- const CallSiteEntry &S = *I;
- const char *BeginTag;
- unsigned BeginNumber;
+ const CallSiteEntry &S = *I;
+ const char *BeginTag;
+ unsigned BeginNumber;
- if (!S.BeginLabel) {
- BeginTag = "eh_func_begin";
- BeginNumber = SubprogramCount;
- } else {
- BeginTag = "label";
- BeginNumber = S.BeginLabel;
- }
+ if (!S.BeginLabel) {
+ BeginTag = "eh_func_begin";
+ BeginNumber = SubprogramCount;
+ } else {
+ BeginTag = "label";
+ BeginNumber = S.BeginLabel;
+ }
- EmitSectionOffset(BeginTag, "eh_func_begin", BeginNumber, SubprogramCount,
- true, true);
- Asm->EOL("Region start");
+ EmitSectionOffset(BeginTag, "eh_func_begin", BeginNumber, SubprogramCount,
+ true, true);
+ Asm->EOL("Region start");
- if (!S.EndLabel)
- EmitDifference("eh_func_end", SubprogramCount, BeginTag, BeginNumber,
- true);
- else
- EmitDifference("label", S.EndLabel, BeginTag, BeginNumber, true);
+ if (!S.EndLabel)
+ EmitDifference("eh_func_end", SubprogramCount, BeginTag, BeginNumber,
+ true);
+ else
+ EmitDifference("label", S.EndLabel, BeginTag, BeginNumber, true);
- Asm->EOL("Region length");
+ Asm->EOL("Region length");
- if (!S.PadLabel)
- Asm->EmitInt32(0);
- else
- EmitSectionOffset("label", "eh_func_begin", S.PadLabel, SubprogramCount,
- true, true);
+ if (!S.PadLabel)
+ Asm->EmitInt32(0);
+ else
+ EmitSectionOffset("label", "eh_func_begin", S.PadLabel, SubprogramCount,
+ true, true);
- Asm->EOL("Landing pad");
+ Asm->EOL("Landing pad");
- Asm->EmitULEB128Bytes(S.Action);
- Asm->EOL("Action");
+ Asm->EmitULEB128Bytes(S.Action);
+ Asm->EOL("Action");
+ }
}
// Emit the actions.
@@ -690,6 +762,8 @@ void DwarfException::EmitExceptionTable() {
/// EndModule - Emit all exception information that should come after the
/// content.
void DwarfException::EndModule() {
+ if (TAI->getExceptionHandlingType() != ExceptionHandling::Dwarf)
+ return;
if (TimePassesIsEnabled)
ExceptionTimer->startTimer();
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.h b/lib/CodeGen/AsmPrinter/DwarfException.h
index e165df4693..ee390cff01 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.h
+++ b/lib/CodeGen/AsmPrinter/DwarfException.h
@@ -155,6 +155,7 @@ class VISIBILITY_HIDDEN DwarfException : public Dwarf {
/// of any entry - they form gaps in the table. Entries must be ordered by
/// try-range address.
void ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
+ std::map<unsigned,CallSiteEntry*> &CallSiteIndexMap,
const RangeMapType &PadMap,
const SmallVectorImpl<const LandingPadInfo *> &LPs,
const SmallVectorImpl<unsigned> &FirstActions);
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp
index 8249501dc1..c60f9c7e41 100644
--- a/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/lib/CodeGen/LLVMTargetMachine.cpp
@@ -229,10 +229,17 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
// Turn exception handling constructs into something the code generators can
// handle.
- if (!getTargetAsmInfo()->doesSupportExceptionHandling())
- PM.add(createLowerInvokePass(getTargetLowering()));
- else
+ switch (getTargetAsmInfo()->getExceptionHandlingType())
+ {
+ // SjLj piggy-backs on dwarf for this bit
+ case ExceptionHandling::SjLj:
+ case ExceptionHandling::Dwarf:
PM.add(createDwarfEHPass(getTargetLowering(), OptLevel==CodeGenOpt::None));
+ break;
+ case ExceptionHandling::None:
+ PM.add(createLowerInvokePass(getTargetLowering()));
+ break;
+ }
PM.add(createGCLoweringPass());
diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp
index 2e9303aeef..ab037c243a 100644
--- a/lib/CodeGen/MachineFunction.cpp
+++ b/lib/CodeGen/MachineFunction.cpp
@@ -93,6 +93,9 @@ MachineFunction::MachineFunction(Function *F,
MachineConstantPool(TM.getTargetData());
Alignment = TM.getTargetLowering()->getFunctionAlignment(F);
+ CallSiteIndex = 0;
+ MaxCallSiteIndex = 0;
+
// Set up jump table.
const TargetData &TD = *TM.getTargetData();
bool IsPic = TM.getRelocationModel() == Reloc::PIC_;
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 712fedad4d..7297d60d34 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -5198,6 +5198,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::FRAMEADDR: return "FRAMEADDR";
case ISD::FRAME_TO_ARGS_OFFSET: return "FRAME_TO_ARGS_OFFSET";
case ISD::EXCEPTIONADDR: return "EXCEPTIONADDR";
+ case ISD::LSDAADDR: return "LSDAADDR";
case ISD::EHSELECTION: return "EHSELECTION";
case ISD::EH_RETURN: return "EH_RETURN";
case ISD::ConstantPool: return "ConstantPool";
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
index 0180069623..1d02bffb61 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
@@ -4087,7 +4087,11 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
Offset));
return 0;
}
-
+ case Intrinsic::eh_sjlj_callsite: {
+ MachineFunction &MF = DAG.getMachineFunction();
+ MF.setCallSiteIndex(cast<ConstantSDNode>(getValue(I.getOperand(1)))->getZExtValue());
+ return 0;
+ }
case Intrinsic::convertff:
case Intrinsic::convertfsi:
case Intrinsic::convertfui:
@@ -4451,9 +4455,14 @@ void SelectionDAGLowering::LowerCallTo(CallSite CS, SDValue Callee,
}
if (LandingPad && MMI) {
+ MachineFunction &MF = DAG.getMachineFunction();
// Insert a label before the invoke call to mark the try range. This can be
// used to detect deletion of the invoke via the MachineModuleInfo.
BeginLabel = MMI->NextLabelID();
+
+ // Map this landing pad to the current call site entry
+ MF.setLandingPadCallSiteIndex(LandingPad, MF.getCallSiteIndex());
+
// Both PendingLoads and PendingExports must be flushed here;
// this call might not return.
(void)getRoot();
diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp
index af69ddffd2..c3e16510b4 100644
--- a/lib/ExecutionEngine/JIT/JITEmitter.cpp
+++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp
@@ -511,11 +511,11 @@ namespace {
DOUT << "JIT is managing a GOT\n";
}
- if (ExceptionHandling) DE = new JITDwarfEmitter(jit);
+ if (DwarfExceptionHandling) DE = new JITDwarfEmitter(jit);
}
~JITEmitter() {
delete MemMgr;
- if (ExceptionHandling) delete DE;
+ if (DwarfExceptionHandling) delete DE;
}
/// classof - Methods for support type inquiry through isa, cast, and
@@ -603,7 +603,7 @@ namespace {
virtual void setModuleInfo(MachineModuleInfo* Info) {
MMI = Info;
- if (ExceptionHandling) DE->setModuleInfo(Info);
+ if (DwarfExceptionHandling) DE->setModuleInfo(Info);
}
void setMemoryExecutable(void) {
@@ -1125,7 +1125,7 @@ bool JITEmitter::finishFunction(MachineFunction &F) {
}
}
#endif
- if (ExceptionHandling) {
+ if (DwarfExceptionHandling) {
uintptr_t ActualSize = 0;
SavedBufferBegin = BufferBegin;
SavedBufferEnd = BufferEnd;
diff --git a/lib/Target/ARM/ARMConstantPoolValue.cpp b/lib/Target/ARM/ARMConstantPoolValue.cpp
index a75ed3bd53..adf03e04b8 100644
--- a/lib/Target/ARM/ARMConstantPoolValue.cpp
+++ b/lib/Target/ARM/ARMConstantPoolValue.cpp
@@ -34,7 +34,7 @@ ARMConstantPoolValue::ARMConstantPoolValue(const char *s, unsigned id,
const char *Modif,
bool AddCA)
: MachineConstantPoolValue((const Type*)Type::Int32Ty),
- GV(NULL), S(s), LabelId(id), Kind(k), PCAdjust(PCAdj),
+ GV(NULL), S(strdup(s)), LabelId(id), Kind(k), PCAdjust(PCAdj),
Modifier(Modif), AddCurrentAddress(AddCA) {}
ARMConstantPoolValue::ARMConstantPoolValue(GlobalValue *gv,
diff --git a/lib/Target/ARM/ARMConstantPoolValue.h b/lib/Target/ARM/ARMConstantPoolValue.h
index fcaf2e6885..37a2c80478 100644
--- a/lib/Target/ARM/ARMConstantPoolValue.h
+++ b/lib/Target/ARM/ARMConstantPoolValue.h
@@ -53,6 +53,8 @@ public:
bool AddCurrentAddress = false);
ARMConstantPoolValue(GlobalValue *GV, ARMCP::ARMCPKind Kind,
const char *Modifier);
+ ARMConstantPoolValue();
+ ~ARMConstantPoolValue() {free((void*)S);}
GlobalValue *getGV() const { return GV; }
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index aedddaa20b..61722d44fa 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -1392,6 +1392,37 @@ ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) {
EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
return DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT);
}
+ case Intrinsic::eh_sjlj_lsda: {
+ // blah. horrible, horrible hack with the forced magic name.
+ // really need to clean this up. It belongs in the target-independent
+ // layer somehow that doesn't require the coupling with the asm
+ // printer.
+ MachineFunction &MF = DAG.getMachineFunction();
+ EVT PtrVT = getPointerTy();
+ DebugLoc dl = Op.getDebugLoc();
+ Reloc::Model RelocM = getTargetMachine().getRelocationModel();
+ SDValue CPAddr;
+ unsigned PCAdj = (RelocM != Reloc::PIC_)
+ ? 0 : (Subtarget->isThumb() ? 4 : 8);
+ ARMCP::ARMCPKind Kind = ARMCP::CPValue;
+ // Save off the LSDA name for the AsmPrinter to use when it's time
+ // to emit the table
+ std::string LSDAName = "L_lsda_";
+ LSDAName += MF.getFunction()->getName();
+ ARMConstantPoolValue *CPV =
+ new ARMConstantPoolValue(LSDAName.c_str(), ARMPCLabelIndex, Kind, PCAdj);
+ CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4);
+ CPAddr = DAG.getNode(ARMISD::Wrapper, dl, EVT::i32, CPAddr);
+ SDValue Result =
+ DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, NULL, 0);
+ SDValue Chain = Result.getValue(1);
+
+ if (RelocM == Reloc::PIC_) {
+ SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex++, EVT::i32);
+ Result = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel);
+ }
+ return Result;
+ }
case Intrinsic::eh_sjlj_setjmp:
return DAG.getNode(ARMISD::EH_SJLJ_SETJMP, dl, EVT::i32, Op.getOperand(1));
}
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index 5190492b64..4a2ce4be78 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -1427,9 +1427,12 @@ let Defs =
def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src),
AddrModeNone, SizeSpecial, IndexModeNone,
Pseudo, NoItinerary,
- "add r0, pc, #4\n\t"
- "str r0, [$src, #+4]\n\t"
- "mov r0, #0 @ eh_setjmp", "",
+ "str sp, [$src, #+8] @ eh_setjmp begin\n\t"
+ "add ip, pc, #8\n\t"
+ "str ip, [$src, #+4]\n\t"
+ "mov r0, #0\n\t"
+ "add pc, pc, #0\n\t"
+ "mov r0, #1 @ eh_setjmp end\n\t", "",
[(set R0, (ARMeh_sjlj_setjmp GPR:$src))]>;
}
diff --git a/lib/Target/ARM/ARMTargetAsmInfo.cpp b/lib/Target/ARM/ARMTargetAsmInfo.cpp
index e3348a90d4..653219bf74 100644
--- a/lib/Target/ARM/ARMTargetAsmInfo.cpp
+++ b/lib/Target/ARM/ARMTargetAsmInfo.cpp
@@ -47,6 +47,12 @@ ARMDarwinTargetAsmInfo::ARMDarwinTargetAsmInfo() {
ProtectedDirective = NULL;
HasDotTypeDotSizeDirective = false;
SupportsDebugInformation = true;
+
+ // Exceptions handling
+ ExceptionsType = ExceptionHandling::SjLj;
+ GlobalEHDirective = "\t.globl\t";
+ SupportsWeakOmittedEHFrame = false;
+ AbsoluteEHSectionOffsets = false;
}
ARMELFTargetAsmInfo::ARMELFTargetAsmInfo() {
diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
index a909b66413..9de9af60e6 100644
--- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
@@ -208,6 +208,8 @@ namespace {
} else {
if (GV)
Name = Mang->getMangledName(GV);
+ else if (!strncmp(ACPV->getSymbol(), "L_lsda_", 7))
+ Name = ACPV->getSymbol();
else
Name = Mang->makeNameProper(ACPV->getSymbol());
}
diff --git a/lib/Target/CellSPU/SPUTargetAsmInfo.cpp b/lib/Target/CellSPU/SPUTargetAsmInfo.cpp
index 2dcb1135c5..991afa0e0b 100644
--- a/lib/Target/CellSPU/SPUTargetAsmInfo.cpp
+++ b/lib/Target/CellSPU/SPUTargetAsmInfo.cpp
@@ -37,6 +37,6 @@ SPULinuxTargetAsmInfo::SPULinuxTargetAsmInfo() {
// Exception handling is not supported on CellSPU (think about it: you only
// have 256K for code+data. Would you support exception handling?)
- SupportsExceptionHandling = false;
+ ExceptionsType = ExceptionHandling::None;
}
diff --git a/lib/Target/PowerPC/PPCTargetAsmInfo.cpp b/lib/Target/PowerPC/PPCTargetAsmInfo.cpp
index 26120175fb..52e29865fa 100644
--- a/lib/Target/PowerPC/PPCTargetAsmInfo.cpp
+++ b/lib/Target/PowerPC/PPCTargetAsmInfo.cpp
@@ -24,8 +24,8 @@ PPCDarwinTargetAsmInfo::PPCDarwinTargetAsmInfo(const PPCTargetMachine &TM) :
PCSymbol = ".";
CommentString = ";";
UsedDirective = "\t.no_dead_strip\t";
- SupportsExceptionHandling = true;
-
+ ExceptionsType = ExceptionHandling::Dwarf;
+
GlobalEHDirective = "\t.globl\t";
SupportsWeakOmittedEHFrame = false;
}
@@ -49,7 +49,7 @@ PPCLinuxTargetAsmInfo::PPCLinuxTargetAsmInfo(const PPCTargetMachine &TM) :
// Exceptions handling
if (!TM.getSubtargetImpl()->isPPC64())
- SupportsExceptionHandling = true;
+ ExceptionsType = ExceptionHandling::Dwarf;
AbsoluteEHSectionOffsets = false;
}
diff --git a/lib/Target/TargetAsmInfo.cpp b/lib/Target/TargetAsmInfo.cpp
index 6ac54e0bf0..84a97710d6 100644
--- a/lib/Target/TargetAsmInfo.cpp
+++ b/lib/Target/TargetAsmInfo.cpp
@@ -72,7 +72,7 @@ TargetAsmInfo::TargetAsmInfo() {
HasLEB128 = false;
HasDotLocAndDotFile = false;
SupportsDebugInformation = false;
- SupportsExceptionHandling = false;
+ ExceptionsType = ExceptionHandling::None;
DwarfRequiresFrameSection = true;
DwarfUsesInlineInfoSection = false;
Is_EHSymbolPrivate = true;
diff --git a/lib/Target/TargetMachine.cpp b/lib/Target/TargetMachine.cpp
index fb95c52a99..b94fa68be9 100644
--- a/lib/Target/TargetMachine.cpp
+++ b/lib/Target/TargetMachine.cpp
@@ -33,7 +33,8 @@ namespace llvm {
FloatABI::ABIType FloatABIType;
bool NoImplicitFloat;
bool NoZerosInBSS;
- bool ExceptionHandling;
+ bool DwarfExceptionHandling;
+ bool SjLjExceptionHandling;
bool UnwindTablesMandatory;
Reloc::Model RelocationModel;
CodeModel::Model CMModel;
@@ -104,9 +105,14 @@ DontPlaceZerosInBSS("nozero-initialized-in-bss",
cl::location(NoZerosInBSS),
cl::init(false));
static cl::opt<bool, true>
-EnableExceptionHandling("enable-eh",
+EnableDwarfExceptionHandling("enable-eh",
cl::desc("Emit DWARF exception handling (default if target supports)"),
- cl::location(ExceptionHandling),
+ cl::location(DwarfExceptionHandling),
+ cl::init(false));
+static cl::opt<bool, true>
+EnableSjLjExceptionHandling("enable-sjlj-eh",
+ cl::desc("Emit SJLJ exception handling (default if target supports)"),
+ cl::location(SjLjExceptionHandling),
cl::init(false));
static cl::opt<bool, true>
EnableUnwindTables("unwind-tables",
diff --git a/lib/Target/X86/X86TargetAsmInfo.cpp b/lib/Target/X86/X86TargetAsmInfo.cpp
index 297ebf594b..b702cbfc44 100644
--- a/lib/Target/X86/X86TargetAsmInfo.cpp
+++ b/lib/Target/X86/X86TargetAsmInfo.cpp
@@ -77,7 +77,7 @@ X86DarwinTargetAsmInfo::X86DarwinTargetAsmInfo(const X86TargetMachine &TM):
DwarfUsesInlineInfoSection = true;
// Exceptions handling
- SupportsExceptionHandling = true;
+ ExceptionsType = ExceptionHandling::Dwarf;
GlobalEHDirective = "\t.globl\t";
SupportsWeakOmittedEHFrame = false;
AbsoluteEHSectionOffsets = false;
@@ -99,7 +99,7 @@ X86ELFTargetAsmInfo::X86ELFTargetAsmInfo(const X86TargetMachine &TM) :
SupportsDebugInformation = true;
// Exceptions handling
- SupportsExceptionHandling = true;
+ ExceptionsType = ExceptionHandling::Dwarf;
AbsoluteEHSectionOffsets = false;
// On Linux we must declare when we can use a non-executable stack.
diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp
index 598da7fa66..dacf483563 100644
--- a/tools/lto/LTOCodeGenerator.cpp
+++ b/tools/lto/LTOCodeGenerator.cpp
@@ -394,9 +394,19 @@ bool LTOCodeGenerator::generateAssemblyCode(formatted_raw_ostream& out,
Module* mergedModule = _linker.getModule();
- // If target supports exception handling then enable it now.
- if ( _target->getTargetAsmInfo()->doesSupportExceptionHandling() )
- llvm::ExceptionHandling = true;
+ // If target supports exception handling then enable it now.
+ switch (_target->getTargetAsmInfo()->getExceptionHandlingType()) {
+ case ExceptionHandling::Dwarf:
+ llvm::DwarfExceptionHandling = true;
+ break;
+ case ExceptionHandling::SjLj:
+ llvm::SjLjExceptionHandling = true;
+ break;
+ case ExceptionHandling::None:
+ break;
+ default:
+ assert (0 && "Unknown exception handling model!");
+ }
// if options were requested, set them
if ( !_codegenOptions.empty() )