aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2009-09-01 01:57:56 +0000
committerJim Grosbach <grosbach@apple.com>2009-09-01 01:57:56 +0000
commit3fb2b1ede30193b59a651328a946174196b20610 (patch)
treea24c457792ad0101ac817f963c62327ebf1d6135
parentf98d8fee3c5367622cf03e52f1e1b2251ac6cf3f (diff)
Clean up LSDA name generation and use for SJLJ exception handling. This
makes an eggregious hack somewhat more palatable. Bringing the LSDA forward and making it a GV available for reference would be even better, but is beyond the scope of what I'm looking to solve at this point. Objective C++ code could generate function names that broke the previous scheme. This fixes that. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80649 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h8
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.cpp11
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfPrinter.cpp18
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfPrinter.h8
-rw-r--r--lib/Target/ARM/ARMConstantPoolValue.cpp7
-rw-r--r--lib/Target/ARM/ARMConstantPoolValue.h10
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp22
-rw-r--r--lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp14
-rw-r--r--test/CodeGen/ARM/2009-08-31-LSDA-Name.ll103
9 files changed, 163 insertions, 38 deletions
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index 621b47d21e..c7d2f54e85 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -172,6 +172,10 @@ namespace llvm {
///
std::string getCurrentFunctionEHName(const MachineFunction *MF) const;
+ /// getFunctionNumber - Return a unique ID for the current function.
+ ///
+ unsigned getFunctionNumber() const { return FunctionNumber; }
+
protected:
/// getAnalysisUsage - Record analysis usage.
///
@@ -217,10 +221,6 @@ namespace llvm {
/// is being processed from runOnMachineFunction.
void SetupMachineFunction(MachineFunction &MF);
- /// getFunctionNumber - Return a unique ID for the current function.
- ///
- unsigned getFunctionNumber() const { return FunctionNumber; }
-
/// IncrementFunctionNumber - Increase Function Number. AsmPrinters should
/// not normally call this, as the counter is automatically bumped by
/// SetupMachineFunction.
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp
index f6feccdac8..2fcee3e285 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp
@@ -25,9 +25,11 @@
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/Mangler.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/StringExtras.h"
+#include <sstream>
using namespace llvm;
static TimerGroup &getDwarfTimerGroup() {
@@ -599,9 +601,12 @@ void DwarfException::EmitExceptionTable() {
EmitLabel("exception", SubprogramCount);
if (MAI->getExceptionHandlingType() == ExceptionHandling::SjLj) {
- std::string SjLjName = "_lsda_";
- SjLjName += MF->getFunction()->getName().str();
- EmitLabel(SjLjName.c_str(), 0);
+ std::stringstream out;
+ out << Asm->getFunctionNumber();
+ std::string LSDAName =
+ Asm->Mang->makeNameProper(std::string("LSDA_") + out.str(),
+ Mangler::Private);
+ EmitLabel(LSDAName.c_str(), 0, false);
}
// Emit the header.
diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
index 20b959b914..60ff2c57cd 100644
--- a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
@@ -43,21 +43,27 @@ void Dwarf::PrintRelDirective(bool Force32Bit, bool isInSection) const {
/// PrintLabelName - Print label name in form used by Dwarf writer.
///
-void Dwarf::PrintLabelName(const char *Tag, unsigned Number) const {
- O << MAI->getPrivateGlobalPrefix() << Tag;
+void Dwarf::PrintLabelName(const char *Tag, unsigned Number,
+ bool ForcePrivate) const {
+ if (ForcePrivate)
+ O << MAI->getPrivateGlobalPrefix();
+ O << Tag;
if (Number) O << Number;
}
void Dwarf::PrintLabelName(const char *Tag, unsigned Number,
- const char *Suffix) const {
- O << MAI->getPrivateGlobalPrefix() << Tag;
+ const char *Suffix, bool ForcePrivate) const {
+ if (ForcePrivate)
+ O << MAI->getPrivateGlobalPrefix();
+ O << Tag;
if (Number) O << Number;
O << Suffix;
}
/// EmitLabel - Emit location label for internal use by Dwarf.
///
-void Dwarf::EmitLabel(const char *Tag, unsigned Number) const {
- PrintLabelName(Tag, Number);
+void Dwarf::EmitLabel(const char *Tag, unsigned Number,
+ bool ForcePrivate) const {
+ PrintLabelName(Tag, Number, ForcePrivate);
O << ":\n";
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.h b/lib/CodeGen/AsmPrinter/DwarfPrinter.h
index 33ebb3bd0e..01aa775ebe 100644
--- a/lib/CodeGen/AsmPrinter/DwarfPrinter.h
+++ b/lib/CodeGen/AsmPrinter/DwarfPrinter.h
@@ -100,16 +100,18 @@ namespace llvm {
void PrintLabelName(const DWLabel &Label) const {
PrintLabelName(Label.getTag(), Label.getNumber());
}
- void PrintLabelName(const char *Tag, unsigned Number) const;
void PrintLabelName(const char *Tag, unsigned Number,
- const char *Suffix) const;
+ bool ForcePrivate = true) const;
+ void PrintLabelName(const char *Tag, unsigned Number,
+ const char *Suffix, bool ForcePrivate = true) const;
/// EmitLabel - Emit location label for internal use by Dwarf.
///
void EmitLabel(const DWLabel &Label) const {
EmitLabel(Label.getTag(), Label.getNumber());
}
- void EmitLabel(const char *Tag, unsigned Number) const;
+ void EmitLabel(const char *Tag, unsigned Number,
+ bool ForcePrivate = true) const;
/// EmitReference - Emit a reference to a label.
///
diff --git a/lib/Target/ARM/ARMConstantPoolValue.cpp b/lib/Target/ARM/ARMConstantPoolValue.cpp
index 6c8c39f6fa..e44574b55c 100644
--- a/lib/Target/ARM/ARMConstantPoolValue.cpp
+++ b/lib/Target/ARM/ARMConstantPoolValue.cpp
@@ -20,11 +20,12 @@
using namespace llvm;
ARMConstantPoolValue::ARMConstantPoolValue(GlobalValue *gv, unsigned id,
+ ARMCP::ARMCPKind K,
unsigned char PCAdj,
const char *Modif,
bool AddCA)
: MachineConstantPoolValue((const Type*)gv->getType()),
- GV(gv), S(NULL), LabelId(id), PCAdjust(PCAdj),
+ GV(gv), S(NULL), LabelId(id), Kind(K), PCAdjust(PCAdj),
Modifier(Modif), AddCurrentAddress(AddCA) {}
ARMConstantPoolValue::ARMConstantPoolValue(LLVMContext &C,
@@ -33,12 +34,12 @@ ARMConstantPoolValue::ARMConstantPoolValue(LLVMContext &C,
const char *Modif,
bool AddCA)
: MachineConstantPoolValue((const Type*)Type::getInt32Ty(C)),
- GV(NULL), S(strdup(s)), LabelId(id), PCAdjust(PCAdj),
+ GV(NULL), S(strdup(s)), LabelId(id), Kind(ARMCP::CPValue), PCAdjust(PCAdj),
Modifier(Modif), AddCurrentAddress(AddCA) {}
ARMConstantPoolValue::ARMConstantPoolValue(GlobalValue *gv, const char *Modif)
: MachineConstantPoolValue((const Type*)Type::getInt32Ty(gv->getContext())),
- GV(gv), S(NULL), LabelId(0), PCAdjust(0),
+ GV(gv), S(NULL), Kind(ARMCP::CPValue), LabelId(0), PCAdjust(0),
Modifier(Modif) {}
int ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
diff --git a/lib/Target/ARM/ARMConstantPoolValue.h b/lib/Target/ARM/ARMConstantPoolValue.h
index 8a0348b797..525346dd41 100644
--- a/lib/Target/ARM/ARMConstantPoolValue.h
+++ b/lib/Target/ARM/ARMConstantPoolValue.h
@@ -21,12 +21,20 @@ namespace llvm {
class GlobalValue;
class LLVMContext;
+namespace ARMCP {
+ enum ARMCPKind {
+ CPValue,
+ CPLSDA
+ };
+}
+
/// ARMConstantPoolValue - ARM specific constantpool value. This is used to
/// represent PC relative displacement between the address of the load
/// instruction and the global value being loaded, i.e. (&GV-(LPIC+8)).
class ARMConstantPoolValue : public MachineConstantPoolValue {
GlobalValue *GV; // GlobalValue being loaded.
const char *S; // ExtSymbol being loaded.
+ ARMCP::ARMCPKind Kind; // Value or LSDA?
unsigned LabelId; // Label id of the load.
unsigned char PCAdjust; // Extra adjustment if constantpool is pc relative.
// 8 for ARM, 4 for Thumb.
@@ -35,6 +43,7 @@ class ARMConstantPoolValue : public MachineConstantPoolValue {
public:
ARMConstantPoolValue(GlobalValue *gv, unsigned id,
+ ARMCP::ARMCPKind Kind = ARMCP::CPValue,
unsigned char PCAdj = 0, const char *Modifier = NULL,
bool AddCurrentAddress = false);
ARMConstantPoolValue(LLVMContext &C, const char *s, unsigned id,
@@ -52,6 +61,7 @@ public:
bool mustAddCurrentAddress() const { return AddCurrentAddress; }
unsigned getLabelId() const { return LabelId; }
unsigned char getPCAdjustment() const { return PCAdjust; }
+ bool isLSDA() { return Kind == ARMCP::CPLSDA; }
virtual unsigned getRelocationInfo() const {
// FIXME: This is conservatively claiming that these entries require a
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 0484fd01d5..10a39a7167 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -40,6 +40,7 @@
#include "llvm/ADT/VectorExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
+#include <sstream>
using namespace llvm;
static bool CC_ARM_APCS_Custom_f64(unsigned &ValNo, EVT &ValVT, EVT &LocVT,
@@ -969,7 +970,8 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
// tBX takes a register source operand.
if (isARMFunc && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) {
ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV,
- ARMPCLabelIndex, 4);
+ ARMPCLabelIndex,
+ ARMCP::CPValue, 4);
SDValue CPAddr = DAG.getTargetConstantPool(CPV, getPointerTy(), 4);
CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
Callee = DAG.getLoad(getPointerTy(), dl,
@@ -1166,7 +1168,7 @@ ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
ARMConstantPoolValue *CPV =
new ARMConstantPoolValue(GA->getGlobal(), ARMPCLabelIndex,
- PCAdj, "tlsgd", true);
+ ARMCP::CPValue, PCAdj, "tlsgd", true);
SDValue Argument = DAG.getTargetConstantPool(CPV, PtrVT, 4);
Argument = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Argument);
Argument = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Argument, NULL, 0);
@@ -1208,7 +1210,7 @@ ARMTargetLowering::LowerToTLSExecModels(GlobalAddressSDNode *GA,
unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
ARMConstantPoolValue *CPV =
new ARMConstantPoolValue(GA->getGlobal(), ARMPCLabelIndex,
- PCAdj, "gottpoff", true);
+ ARMCP::CPValue, PCAdj, "gottpoff", true);
Offset = DAG.getTargetConstantPool(CPV, PtrVT, 4);
Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset);
Offset = DAG.getLoad(PtrVT, dl, Chain, Offset, NULL, 0);
@@ -1284,7 +1286,7 @@ SDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op,
else {
unsigned PCAdj = (RelocM != Reloc::PIC_) ? 0 : (Subtarget->isThumb()?4:8);
ARMConstantPoolValue *CPV =
- new ARMConstantPoolValue(GV, ARMPCLabelIndex, PCAdj);
+ new ARMConstantPoolValue(GV, ARMPCLabelIndex, ARMCP::CPValue, PCAdj);
CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4);
}
CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
@@ -1375,10 +1377,6 @@ ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) {
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();
@@ -1386,13 +1384,9 @@ ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) {
SDValue CPAddr;
unsigned PCAdj = (RelocM != Reloc::PIC_)
? 0 : (Subtarget->isThumb() ? 4 : 8);
- // 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(*DAG.getContext(), LSDAName.c_str(),
- ARMPCLabelIndex, PCAdj);
+ new ARMConstantPoolValue(MF.getFunction(), ARMPCLabelIndex,
+ ARMCP::CPLSDA, PCAdj);
CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4);
CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr);
SDValue Result =
diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
index d782cdedc1..49e2490cf3 100644
--- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
@@ -44,6 +44,7 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/FormattedStream.h"
#include <cctype>
+#include <sstream>
using namespace llvm;
STATISTIC(EmittedInsts, "Number of machine instrs printed");
@@ -159,8 +160,13 @@ namespace {
ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
GlobalValue *GV = ACPV->getGV();
std::string Name;
-
- if (GV) {
+
+ if (ACPV->isLSDA()) {
+ std::stringstream out;
+ out << getFunctionNumber();
+ Name = Mang->makeNameProper(std::string("LSDA_") + out.str(),
+ Mangler::Private);
+ } else if (GV) {
bool isIndirect = Subtarget->isTargetDarwin() &&
Subtarget->GVIsIndirectSymbol(GV,
TM.getRelocationModel() == Reloc::Static);
@@ -175,9 +181,7 @@ namespace {
else
GVNonLazyPtrs[SymName] = Name;
}
- } else if (!strncmp(ACPV->getSymbol(), "L_lsda_", 7))
- Name = ACPV->getSymbol();
- else
+ } else
Name = Mang->makeNameProper(ACPV->getSymbol());
O << Name;
diff --git a/test/CodeGen/ARM/2009-08-31-LSDA-Name.ll b/test/CodeGen/ARM/2009-08-31-LSDA-Name.ll
new file mode 100644
index 0000000000..ca669e1d0e
--- /dev/null
+++ b/test/CodeGen/ARM/2009-08-31-LSDA-Name.ll
@@ -0,0 +1,103 @@
+; RUN: llvm-as < %s | llc -march=arm -f | FileCheck %s
+
+%struct.A = type { i32* }
+
+define arm_apcscc void @"\01-[MyFunction Name:]"() {
+entry:
+ %save_filt.1 = alloca i32 ; <i32*> [#uses=2]
+ %save_eptr.0 = alloca i8* ; <i8**> [#uses=2]
+ %a = alloca %struct.A ; <%struct.A*> [#uses=3]
+ %eh_exception = alloca i8* ; <i8**> [#uses=5]
+ %eh_selector = alloca i32 ; <i32*> [#uses=3]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ call arm_apcscc void @_ZN1AC1Ev(%struct.A* %a)
+ invoke arm_apcscc void @_Z3barv()
+ to label %invcont unwind label %lpad
+
+invcont: ; preds = %entry
+ call arm_apcscc void @_ZN1AD1Ev(%struct.A* %a) nounwind
+ br label %return
+
+bb: ; preds = %ppad
+ %eh_select = load i32* %eh_selector ; <i32> [#uses=1]
+ store i32 %eh_select, i32* %save_filt.1, align 4
+ %eh_value = load i8** %eh_exception ; <i8*> [#uses=1]
+ store i8* %eh_value, i8** %save_eptr.0, align 4
+ call arm_apcscc void @_ZN1AD1Ev(%struct.A* %a) nounwind
+ %0 = load i8** %save_eptr.0, align 4 ; <i8*> [#uses=1]
+ store i8* %0, i8** %eh_exception, align 4
+ %1 = load i32* %save_filt.1, align 4 ; <i32> [#uses=1]
+ store i32 %1, i32* %eh_selector, align 4
+ br label %Unwind
+
+return: ; preds = %invcont
+ ret void
+
+lpad: ; preds = %entry
+ %eh_ptr = call i8* @llvm.eh.exception() ; <i8*> [#uses=1]
+ store i8* %eh_ptr, i8** %eh_exception
+ %eh_ptr1 = load i8** %eh_exception ; <i8*> [#uses=1]
+ %eh_select2 = call i32 (i8*, i8*, ...)* @llvm.eh.selector.i32(i8* %eh_ptr1, i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*), i32 0) ; <i32> [#uses=1]
+ store i32 %eh_select2, i32* %eh_selector
+ br label %ppad
+
+ppad: ; preds = %lpad
+ br label %bb
+
+Unwind: ; preds = %bb
+ %eh_ptr3 = load i8** %eh_exception ; <i8*> [#uses=1]
+ call arm_apcscc void @_Unwind_SjLj_Resume(i8* %eh_ptr3)
+ unreachable
+}
+
+define linkonce_odr arm_apcscc void @_ZN1AC1Ev(%struct.A* %this) {
+entry:
+ %this_addr = alloca %struct.A* ; <%struct.A**> [#uses=2]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ store %struct.A* %this, %struct.A** %this_addr
+ %0 = call arm_apcscc i8* @_Znwm(i32 4) ; <i8*> [#uses=1]
+ %1 = bitcast i8* %0 to i32* ; <i32*> [#uses=1]
+ %2 = load %struct.A** %this_addr, align 4 ; <%struct.A*> [#uses=1]
+ %3 = getelementptr inbounds %struct.A* %2, i32 0, i32 0 ; <i32**> [#uses=1]
+ store i32* %1, i32** %3, align 4
+ br label %return
+
+return: ; preds = %entry
+ ret void
+}
+
+declare arm_apcscc i8* @_Znwm(i32)
+
+define linkonce_odr arm_apcscc void @_ZN1AD1Ev(%struct.A* %this) nounwind {
+entry:
+ %this_addr = alloca %struct.A* ; <%struct.A**> [#uses=2]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ store %struct.A* %this, %struct.A** %this_addr
+ %0 = load %struct.A** %this_addr, align 4 ; <%struct.A*> [#uses=1]
+ %1 = getelementptr inbounds %struct.A* %0, i32 0, i32 0 ; <i32**> [#uses=1]
+ %2 = load i32** %1, align 4 ; <i32*> [#uses=1]
+ %3 = bitcast i32* %2 to i8* ; <i8*> [#uses=1]
+ call arm_apcscc void @_ZdlPv(i8* %3) nounwind
+ br label %bb
+
+bb: ; preds = %entry
+ br label %return
+
+return: ; preds = %bb
+ ret void
+}
+;CHECK: L_LSDA_1:
+
+declare arm_apcscc void @_ZdlPv(i8*) nounwind
+
+declare arm_apcscc void @_Z3barv()
+
+declare i8* @llvm.eh.exception() nounwind
+
+declare i32 @llvm.eh.selector.i32(i8*, i8*, ...) nounwind
+
+declare i32 @llvm.eh.typeid.for.i32(i8*) nounwind
+
+declare arm_apcscc i32 @__gxx_personality_sj0(...)
+
+declare arm_apcscc void @_Unwind_SjLj_Resume(i8*)