mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-22 03:58:16 +00:00
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
This commit is contained in:
parent
f98d8fee3c
commit
3fb2b1ede3
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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";
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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 =
|
||||
|
@ -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;
|
||||
|
||||
|
103
test/CodeGen/ARM/2009-08-31-LSDA-Name.ll
Normal file
103
test/CodeGen/ARM/2009-08-31-LSDA-Name.ll
Normal file
@ -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*)
|
Loading…
Reference in New Issue
Block a user