Centralize handling of the eh_begin and eh_end labels.

This removes a bit of duplicated code and more importantly, remembers the
labels so that they don't need to be looked up by name.

This in turn allows for any name to be used and avoids a crash if the name
we wanted was already taken.

llvm-svn: 230772
This commit is contained in:
Rafael Espindola 2015-02-27 18:18:39 +00:00
parent af0ff1093e
commit 629cdbae94
13 changed files with 77 additions and 40 deletions

View File

@ -103,6 +103,9 @@ public:
DenseMap<const MCSymbol *, GOTEquivUsePair> GlobalGOTEquivs; DenseMap<const MCSymbol *, GOTEquivUsePair> GlobalGOTEquivs;
private: private:
MCSymbol *CurrentFnBegin;
MCSymbol *CurrentFnEnd;
// The garbage collection metadata printer table. // The garbage collection metadata printer table.
void *GCMetadataPrinters; // Really a DenseMap. void *GCMetadataPrinters; // Really a DenseMap.
@ -146,6 +149,9 @@ public:
/// ///
unsigned getFunctionNumber() const; unsigned getFunctionNumber() const;
MCSymbol *getFunctionBegin() const { return CurrentFnBegin; }
MCSymbol *getFunctionEnd() const { return CurrentFnEnd; }
/// Return information about object file lowering. /// Return information about object file lowering.
const TargetLoweringObjectFile &getObjFileLowering() const; const TargetLoweringObjectFile &getObjFileLowering() const;
@ -331,6 +337,8 @@ public:
/// Return an assembler temporary label with the specified stem. /// Return an assembler temporary label with the specified stem.
MCSymbol *GetTempSymbol(const Twine &Name) const; MCSymbol *GetTempSymbol(const Twine &Name) const;
MCSymbol *createTempSymbol(const Twine &Name, unsigned ID) const;
/// Return the MCSymbol for a private symbol with global value name as its /// Return the MCSymbol for a private symbol with global value name as its
/// base, with the specified suffix. /// base, with the specified suffix.
MCSymbol *getSymbolWithGlobalValueBase(const GlobalValue *GV, MCSymbol *getSymbolWithGlobalValueBase(const GlobalValue *GV,

View File

@ -215,6 +215,8 @@ namespace llvm {
/// with a unique but unspecified name. /// with a unique but unspecified name.
MCSymbol *CreateTempSymbol(); MCSymbol *CreateTempSymbol();
MCSymbol *createTempSymbol(const Twine &Name);
/// getUniqueSymbolID() - Return a unique identifier for use in constructing /// getUniqueSymbolID() - Return a unique identifier for use in constructing
/// symbol names. /// symbol names.
unsigned getUniqueSymbolID() { return NextUniqueID++; } unsigned getUniqueSymbolID() { return NextUniqueID++; }

View File

@ -58,8 +58,6 @@ void ARMException::endModule() {
void ARMException::beginFunction(const MachineFunction *MF) { void ARMException::beginFunction(const MachineFunction *MF) {
if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM) if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
getTargetStreamer().emitFnStart(); getTargetStreamer().emitFnStart();
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
Asm->getFunctionNumber()));
// See if we need call frame info. // See if we need call frame info.
AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves(); AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves();
assert(MoveType != AsmPrinter::CFI_M_EH && assert(MoveType != AsmPrinter::CFI_M_EH &&
@ -84,8 +82,6 @@ void ARMException::endFunction(const MachineFunction *) {
MMI->getLandingPads().empty()) MMI->getLandingPads().empty())
ATS.emitCantUnwind(); ATS.emitCantUnwind();
else { else {
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end",
Asm->getFunctionNumber()));
if (!MMI->getLandingPads().empty()) { if (!MMI->getLandingPads().empty()) {
// Emit references to personality. // Emit references to personality.
if (const Function *Personality = MMI->getPersonality()) { if (const Function *Personality = MMI->getPersonality()) {

View File

@ -109,6 +109,8 @@ AsmPrinter::AsmPrinter(TargetMachine &tm, std::unique_ptr<MCStreamer> Streamer)
LI = nullptr; LI = nullptr;
MF = nullptr; MF = nullptr;
CurrentFnSym = CurrentFnSymForSize = nullptr; CurrentFnSym = CurrentFnSymForSize = nullptr;
CurrentFnBegin = nullptr;
CurrentFnEnd = nullptr;
GCMetadataPrinters = nullptr; GCMetadataPrinters = nullptr;
VerboseAsm = OutStreamer.isVerboseAsm(); VerboseAsm = OutStreamer.isVerboseAsm();
} }
@ -554,6 +556,19 @@ void AsmPrinter::EmitFunctionHeader() {
OutStreamer.EmitLabel(DeadBlockSyms[i]); OutStreamer.EmitLabel(DeadBlockSyms[i]);
} }
if (!MMI->getLandingPads().empty()) {
CurrentFnBegin = createTempSymbol("eh_func_begin", getFunctionNumber());
if (MAI->useAssignmentForEHBegin()) {
MCSymbol *CurPos = OutContext.CreateTempSymbol();
OutStreamer.EmitLabel(CurPos);
OutStreamer.EmitAssignment(CurrentFnBegin,
MCSymbolRefExpr::Create(CurPos, OutContext));
} else {
OutStreamer.EmitLabel(CurrentFnBegin);
}
}
// Emit pre-function debug and/or EH information. // Emit pre-function debug and/or EH information.
for (const HandlerInfo &HI : Handlers) { for (const HandlerInfo &HI : Handlers) {
NamedRegionTimer T(HI.TimerName, HI.TimerGroupName, TimePassesIsEnabled); NamedRegionTimer T(HI.TimerName, HI.TimerGroupName, TimePassesIsEnabled);
@ -867,6 +882,12 @@ void AsmPrinter::EmitFunctionBody() {
// Emit target-specific gunk after the function body. // Emit target-specific gunk after the function body.
EmitFunctionBodyEnd(); EmitFunctionBodyEnd();
if (!MMI->getLandingPads().empty()) {
// Create a symbol for the end of function.
CurrentFnEnd = createTempSymbol("eh_func_end", getFunctionNumber());
OutStreamer.EmitLabel(CurrentFnEnd);
}
// If the target wants a .size directive for the size of the function, emit // If the target wants a .size directive for the size of the function, emit
// it. // it.
if (MAI->hasDotTypeDotSizeDirective()) { if (MAI->hasDotTypeDotSizeDirective()) {
@ -2273,6 +2294,9 @@ MCSymbol *AsmPrinter::GetTempSymbol(const Twine &Name) const {
Name); Name);
} }
MCSymbol *AsmPrinter::createTempSymbol(const Twine &Name, unsigned ID) const {
return OutContext.createTempSymbol(Name + Twine(ID));
}
MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const { MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const {
return MMI->getAddrLabelSymbol(BA->getBasicBlock()); return MMI->getAddrLabelSymbol(BA->getBasicBlock());

View File

@ -113,18 +113,6 @@ void DwarfCFIException::beginFunction(const MachineFunction *MF) {
TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI); TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI);
Asm->OutStreamer.EmitCFIPersonality(Sym, PerEncoding); Asm->OutStreamer.EmitCFIPersonality(Sym, PerEncoding);
MCSymbol *EHBegin =
Asm->GetTempSymbol("eh_func_begin", Asm->getFunctionNumber());
if (Asm->MAI->useAssignmentForEHBegin()) {
MCContext &Ctx = Asm->OutContext;
MCSymbol *CurPos = Ctx.CreateTempSymbol();
Asm->OutStreamer.EmitLabel(CurPos);
Asm->OutStreamer.EmitAssignment(EHBegin,
MCSymbolRefExpr::Create(CurPos, Ctx));
} else {
Asm->OutStreamer.EmitLabel(EHBegin);
}
// Provide LSDA information. // Provide LSDA information.
if (!shouldEmitLSDA) if (!shouldEmitLSDA)
return; return;
@ -145,9 +133,6 @@ void DwarfCFIException::endFunction(const MachineFunction *) {
if (!shouldEmitPersonality) if (!shouldEmitPersonality)
return; return;
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end",
Asm->getFunctionNumber()));
// Map all labels and get rid of any dead landing pads. // Map all labels and get rid of any dead landing pads.
MMI->TidyLandingPads(); MMI->TidyLandingPads();

View File

@ -552,16 +552,14 @@ void EHStreamer::emitExceptionTable() {
I = CallSites.begin(), E = CallSites.end(); I != E; ++I) { I = CallSites.begin(), E = CallSites.end(); I != E; ++I) {
const CallSiteEntry &S = *I; const CallSiteEntry &S = *I;
MCSymbol *EHFuncBeginSym = MCSymbol *EHFuncBeginSym = Asm->getFunctionBegin();
Asm->GetTempSymbol("eh_func_begin", Asm->getFunctionNumber());
MCSymbol *BeginLabel = S.BeginLabel; MCSymbol *BeginLabel = S.BeginLabel;
if (!BeginLabel) if (!BeginLabel)
BeginLabel = EHFuncBeginSym; BeginLabel = EHFuncBeginSym;
MCSymbol *EndLabel = S.EndLabel; MCSymbol *EndLabel = S.EndLabel;
if (!EndLabel) if (!EndLabel)
EndLabel = Asm->GetTempSymbol("eh_func_end", Asm->getFunctionNumber()); EndLabel = Asm->getFunctionEnd();
// Offset of the call site relative to the previous call site, counted in // Offset of the call site relative to the previous call site, counted in
// number of 16-byte bundles. The first call site is counted relative to // number of 16-byte bundles. The first call site is counted relative to

View File

@ -80,9 +80,6 @@ void Win64Exception::beginFunction(const MachineFunction *MF) {
const MCSymbol *PersHandlerSym = const MCSymbol *PersHandlerSym =
TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI); TLOF.getCFIPersonalitySymbol(Per, *Asm->Mang, Asm->TM, MMI);
Asm->OutStreamer.EmitWinEHHandler(PersHandlerSym, true, true); Asm->OutStreamer.EmitWinEHHandler(PersHandlerSym, true, true);
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
Asm->getFunctionNumber()));
} }
/// endFunction - Gather and emit post-function exception information. /// endFunction - Gather and emit post-function exception information.
@ -91,9 +88,6 @@ void Win64Exception::endFunction(const MachineFunction *) {
if (!shouldEmitPersonality && !shouldEmitMoves) if (!shouldEmitPersonality && !shouldEmitMoves)
return; return;
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end",
Asm->getFunctionNumber()));
// Map all labels and get rid of any dead landing pads. // Map all labels and get rid of any dead landing pads.
MMI->TidyLandingPads(); MMI->TidyLandingPads();
@ -170,10 +164,8 @@ void Win64Exception::emitCSpecificHandlerTable() {
SmallVector<CallSiteEntry, 64> CallSites; SmallVector<CallSiteEntry, 64> CallSites;
computeCallSiteTable(CallSites, LandingPads, FirstActions); computeCallSiteTable(CallSites, LandingPads, FirstActions);
MCSymbol *EHFuncBeginSym = MCSymbol *EHFuncBeginSym = Asm->getFunctionBegin();
Asm->GetTempSymbol("eh_func_begin", Asm->getFunctionNumber()); MCSymbol *EHFuncEndSym = Asm->getFunctionEnd();
MCSymbol *EHFuncEndSym =
Asm->GetTempSymbol("eh_func_end", Asm->getFunctionNumber());
// Emit the number of table entries. // Emit the number of table entries.
unsigned NumEntries = 0; unsigned NumEntries = 0;

View File

@ -160,6 +160,12 @@ MCSymbol *MCContext::CreateSymbol(StringRef Name) {
return Result; return Result;
} }
MCSymbol *MCContext::createTempSymbol(const Twine &Name) {
SmallString<128> NameSV;
raw_svector_ostream(NameSV) << MAI->getPrivateGlobalPrefix() << Name;
return CreateSymbol(NameSV);
}
MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) { MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) {
SmallString<128> NameSV; SmallString<128> NameSV;
return GetOrCreateSymbol(Name.toStringRef(NameSV)); return GetOrCreateSymbol(Name.toStringRef(NameSV));

View File

@ -1,8 +1,10 @@
; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 ; RUN: llc -march=mipsel -mcpu=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16
;16: .cfi_personality ;16: main:
;16-NEXT: [[TMP:.*]]: ;16-NEXT: [[TMP:.*]]:
;16-NEXT: $eh_func_begin0 = ([[TMP]]) ;16-NEXT: $eh_func_begin0 = ([[TMP]])
;16-NEXT: .cfi_startproc
;16-NEXT: .cfi_personality
@.str = private unnamed_addr constant [7 x i8] c"hello\0A\00", align 1 @.str = private unnamed_addr constant [7 x i8] c"hello\0A\00", align 1
@_ZTIi = external constant i8* @_ZTIi = external constant i8*
@.str1 = private unnamed_addr constant [15 x i8] c"exception %i \0A\00", align 1 @.str1 = private unnamed_addr constant [15 x i8] c"exception %i \0A\00", align 1

View File

@ -0,0 +1,24 @@
; RUN: llc < %s -mtriple=x86_64-pc-linux | FileCheck %s
; Test that we don't crashe if the .Leh_func_end0 name is taken.
declare void @g()
define void @f() {
bb0:
call void asm ".Leh_func_end0:", ""()
; CHECK: #APP
; CHECK-NEXT: .Leh_func_end0:
; CHECK-NEXT: #NO_APP
invoke void @g() to label %bb2 unwind label %bb1
bb1:
landingpad { i8*, i32 } personality i8* bitcast (void ()* @g to i8*)
catch i8* null
call void @g()
ret void
bb2:
ret void
; CHECK: [[END:.Leh_func_end.*]]:
; CHECK: .long [[END]]-
}

View File

@ -84,8 +84,8 @@ bb7:
} }
; DARWIN64: _F3: ; DARWIN64: _F3:
; DARWIN64: .cfi_endproc ; DARWIN64: Leh_func_end
; DARWIN64-NEXT: Leh_func_end ; DARWIN64-NEXT: .cfi_endproc
; DARWIN64-NEXT: .section __TEXT,__gcc_except_tab ; DARWIN64-NEXT: .section __TEXT,__gcc_except_tab
; DARWIN64-NOT: .section ; DARWIN64-NOT: .section
; DARWIN64: .section __TEXT,__text,regular,pure_instructions ; DARWIN64: .section __TEXT,__text,regular,pure_instructions

View File

@ -5,8 +5,8 @@
define i64 @patchpoint_invoke(i64 %p1, i64 %p2) { define i64 @patchpoint_invoke(i64 %p1, i64 %p2) {
entry: entry:
; CHECK-LABEL: patchpoint_invoke: ; CHECK-LABEL: patchpoint_invoke:
; CHECK-NEXT: [[FUNC_BEGIN:.L.*]]:
; CHECK-NEXT: .cfi_startproc ; CHECK-NEXT: .cfi_startproc
; CHECK: [[FUNC_BEGIN:.L.*]]:
; CHECK: .cfi_lsda 3, [[EXCEPTION_LABEL:.L[^ ]*]] ; CHECK: .cfi_lsda 3, [[EXCEPTION_LABEL:.L[^ ]*]]
; CHECK: pushq %rbp ; CHECK: pushq %rbp

View File

@ -39,10 +39,10 @@ entry:
unreachable unreachable
} }
; CHECK-LABEL: fn_catch ; CHECK-LABEL: fn_catch:
; CHECK-NEXT: [[START:.L[a-zA-Z0-9_]+]]
; CHECK: .cfi_startproc ; CHECK: .cfi_startproc
; CHECK: .cfi_personality 0, __gxx_personality_v0 ; CHECK: .cfi_personality 0, __gxx_personality_v0
; CHECK: [[START:.L[a-zA-Z0-9_]+]]
; CHECK: .cfi_lsda 0, [[LSDA:.L[a-zA-Z0-9_]+]] ; CHECK: .cfi_lsda 0, [[LSDA:.L[a-zA-Z0-9_]+]]
; CHECK: entsp 4 ; CHECK: entsp 4
; CHECK: .cfi_def_cfa_offset 16 ; CHECK: .cfi_def_cfa_offset 16
@ -91,8 +91,8 @@ lpad:
; CHECK: bf r0, [[RETURN]] ; CHECK: bf r0, [[RETURN]]
; CHECK: mov r0, r4 ; CHECK: mov r0, r4
; CHECK: bl _Unwind_Resume ; CHECK: bl _Unwind_Resume
; CHECK: .cfi_endproc
; CHECK: [[END:.L[a-zA-Z0-9_]+]] ; CHECK: [[END:.L[a-zA-Z0-9_]+]]
; CHECK: .cfi_endproc
%6 = icmp eq i32 %5, %2 %6 = icmp eq i32 %5, %2
br i1 %6, label %Resume, label %Exit br i1 %6, label %Resume, label %Exit
Resume: Resume: