Skip to content

[rebranch] Revert "Cleanup unwind table emission code a bit." #8771

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion llvm/include/llvm/CodeGen/MachineFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -1199,6 +1199,10 @@ class LLVM_EXTERNAL_VISIBILITY MachineFunction {
/// Find or create an LandingPadInfo for the specified MachineBasicBlock.
LandingPadInfo &getOrCreateLandingPadInfo(MachineBasicBlock *LandingPad);

/// Remap landing pad labels and remove any deleted landing pads.
void tidyLandingPads(DenseMap<MCSymbol *, uintptr_t> *LPMap = nullptr,
bool TidyIfNoBeginLabels = true);

/// Return a reference to the landing pad info for the current function.
const std::vector<LandingPadInfo> &getLandingPads() const {
return LandingPads;
Expand All @@ -1214,11 +1218,22 @@ class LLVM_EXTERNAL_VISIBILITY MachineFunction {
/// entry.
MCSymbol *addLandingPad(MachineBasicBlock *LandingPad);

/// Provide the catch typeinfo for a landing pad.
void addCatchTypeInfo(MachineBasicBlock *LandingPad,
ArrayRef<const GlobalValue *> TyInfo);

/// Provide the filter typeinfo for a landing pad.
void addFilterTypeInfo(MachineBasicBlock *LandingPad,
ArrayRef<const GlobalValue *> TyInfo);

/// Add a cleanup action for a landing pad.
void addCleanup(MachineBasicBlock *LandingPad);

/// Return the type id for the specified typeinfo. This is function wide.
unsigned getTypeIDFor(const GlobalValue *TI);

/// Return the id of the filter encoded by TyIds. This is function wide.
int getFilterIDFor(ArrayRef<unsigned> TyIds);
int getFilterIDFor(std::vector<unsigned> &TyIds);

/// Map the landing pad's EH symbol to the call site indexes.
void setCallSiteLandingPad(MCSymbol *Sym, ArrayRef<unsigned> Sites);
Expand Down
11 changes: 10 additions & 1 deletion llvm/lib/CodeGen/AsmPrinter/AIXException.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,16 @@

namespace llvm {

AIXException::AIXException(AsmPrinter *A) : EHStreamer(A) {}
AIXException::AIXException(AsmPrinter *A) : DwarfCFIExceptionBase(A) {}

// This overrides 'DwarfCFIExceptionBase::markFunctionEnd', to avoid the call to
// tidyLandingPads. This is necessary, because the
// 'PPCAIXAsmPrinter::emitFunctionBodyEnd' function already checked whether we
// need ehinfo, and emitted a traceback table with the bits set to indicate that
// we will be emitting it, if so. Thus, if we remove it now -- so late in the
// process -- we'll end up having emitted a reference to __ehinfo.N symbol, but
// not emitting a definition for said symbol.
void AIXException::markFunctionEnd() {}

void AIXException::emitExceptionInfoTable(const MCSymbol *LSDA,
const MCSymbol *PerSym) {
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/CodeGen/AsmPrinter/ARMException.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include "llvm/MC/MCStreamer.h"
using namespace llvm;

ARMException::ARMException(AsmPrinter *A) : EHStreamer(A) {}
ARMException::ARMException(AsmPrinter *A) : DwarfCFIExceptionBase(A) {}

ARMException::~ARMException() = default;

Expand Down Expand Up @@ -51,6 +51,7 @@ void ARMException::beginFunction(const MachineFunction *MF) {
void ARMException::markFunctionEnd() {
if (shouldEmitCFI)
Asm->OutStreamer->emitCFIEndProc();
DwarfCFIExceptionBase::markFunctionEnd();
}

/// endFunction - Gather and emit post-function exception information.
Expand Down
13 changes: 12 additions & 1 deletion llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,18 @@
#include "llvm/Target/TargetOptions.h"
using namespace llvm;

DwarfCFIException::DwarfCFIException(AsmPrinter *A) : EHStreamer(A) {}
DwarfCFIExceptionBase::DwarfCFIExceptionBase(AsmPrinter *A) : EHStreamer(A) {}

void DwarfCFIExceptionBase::markFunctionEnd() {
// Map all labels and get rid of any dead landing pads.
if (!Asm->MF->getLandingPads().empty()) {
MachineFunction *NonConstMF = const_cast<MachineFunction*>(Asm->MF);
NonConstMF->tidyLandingPads();
}
}

DwarfCFIException::DwarfCFIException(AsmPrinter *A)
: DwarfCFIExceptionBase(A) {}

DwarfCFIException::~DwarfCFIException() = default;

Expand Down
26 changes: 17 additions & 9 deletions llvm/lib/CodeGen/AsmPrinter/DwarfException.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,19 @@ namespace llvm {
class MachineFunction;
class ARMTargetStreamer;

class LLVM_LIBRARY_VISIBILITY DwarfCFIException : public EHStreamer {
class LLVM_LIBRARY_VISIBILITY DwarfCFIExceptionBase : public EHStreamer {
protected:
DwarfCFIExceptionBase(AsmPrinter *A);

/// Per-function flag to indicate if frame CFI info should be emitted.
bool shouldEmitCFI = false;
/// Per-module flag to indicate if .cfi_section has beeen emitted.
bool hasEmittedCFISections = false;

void markFunctionEnd() override;
};

class LLVM_LIBRARY_VISIBILITY DwarfCFIException : public DwarfCFIExceptionBase {
/// Per-function flag to indicate if .cfi_personality should be emitted.
bool shouldEmitPersonality = false;

Expand Down Expand Up @@ -63,13 +75,7 @@ class LLVM_LIBRARY_VISIBILITY DwarfCFIException : public EHStreamer {
void endBasicBlockSection(const MachineBasicBlock &MBB) override;
};

class LLVM_LIBRARY_VISIBILITY ARMException : public EHStreamer {
/// Per-function flag to indicate if frame CFI info should be emitted.
bool shouldEmitCFI = false;

/// Per-module flag to indicate if .cfi_section has beeen emitted.
bool hasEmittedCFISections = false;

class LLVM_LIBRARY_VISIBILITY ARMException : public DwarfCFIExceptionBase {
void emitTypeInfos(unsigned TTypeEncoding, MCSymbol *TTBaseLabel) override;
ARMTargetStreamer &getTargetStreamer();

Expand All @@ -93,14 +99,16 @@ class LLVM_LIBRARY_VISIBILITY ARMException : public EHStreamer {
void markFunctionEnd() override;
};

class LLVM_LIBRARY_VISIBILITY AIXException : public EHStreamer {
class LLVM_LIBRARY_VISIBILITY AIXException : public DwarfCFIExceptionBase {
/// This is AIX's compat unwind section, which unwinder would use
/// to find the location of LSDA area and personality rountine.
void emitExceptionInfoTable(const MCSymbol *LSDA, const MCSymbol *PerSym);

public:
AIXException(AsmPrinter *A);

void markFunctionEnd() override;

void endModule() override {}
void beginFunction(const MachineFunction *MF) override {}
void endFunction(const MachineFunction *MF) override;
Expand Down
14 changes: 1 addition & 13 deletions llvm/lib/CodeGen/AsmPrinter/EHStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,6 @@ void EHStreamer::computePadMap(
const LandingPadInfo *LandingPad = LandingPads[i];
for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
MCSymbol *BeginLabel = LandingPad->BeginLabels[j];
MCSymbol *EndLabel = LandingPad->BeginLabels[j];
// If we have deleted the code for a given invoke after registering it in
// the LandingPad label list, the associated symbols will not have been
// emitted. In that case, ignore this callsite entry.
if (!BeginLabel->isDefined() || !EndLabel->isDefined())
continue;
assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
PadRange P = { i, j };
PadMap[BeginLabel] = P;
Expand Down Expand Up @@ -388,14 +382,8 @@ MCSymbol *EHStreamer::emitExceptionTable() {
SmallVector<const LandingPadInfo *, 64> LandingPads;
LandingPads.reserve(PadInfos.size());

for (const LandingPadInfo &LPI : PadInfos) {
// If a landing-pad has an associated label, but the label wasn't ever
// emitted, then skip it. (This can occur if the landingpad's MBB was
// deleted).
if (LPI.LandingPadLabel && !LPI.LandingPadLabel->isDefined())
continue;
for (const LandingPadInfo &LPI : PadInfos)
LandingPads.push_back(&LPI);
}

// Order landing pads lexicographically by type id.
llvm::sort(LandingPads, [](const LandingPadInfo *L, const LandingPadInfo *R) {
Expand Down
10 changes: 10 additions & 0 deletions llvm/lib/CodeGen/AsmPrinter/WasmException.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ void WasmException::endModule() {
}
}

void WasmException::markFunctionEnd() {
// Get rid of any dead landing pads.
if (!Asm->MF->getLandingPads().empty()) {
auto *NonConstMF = const_cast<MachineFunction *>(Asm->MF);
// Wasm does not set BeginLabel and EndLabel information for landing pads,
// so we should set the second argument false.
NonConstMF->tidyLandingPads(nullptr, /* TidyIfNoBeginLabels */ false);
}
}

void WasmException::endFunction(const MachineFunction *MF) {
bool ShouldEmitExceptionTable = false;
for (const LandingPadInfo &Info : MF->getLandingPads()) {
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/AsmPrinter/WasmException.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class LLVM_LIBRARY_VISIBILITY WasmException : public EHStreamer {

void endModule() override;
void beginFunction(const MachineFunction *MF) override {}
void markFunctionEnd() override;
void endFunction(const MachineFunction *MF) override;

protected:
Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/CodeGen/AsmPrinter/WinException.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,14 @@ void WinException::endFunction(const MachineFunction *MF) {
if (F.hasPersonalityFn())
Per = classifyEHPersonality(F.getPersonalityFn()->stripPointerCasts());

// Get rid of any dead landing pads if we're not using funclets. In funclet
// schemes, the landing pad is not actually reachable. It only exists so
// that we can emit the right table data.
if (!isFuncletEHPersonality(Per)) {
MachineFunction *NonConstMF = const_cast<MachineFunction*>(MF);
NonConstMF->tidyLandingPads();
}

endFuncletImpl();

// endFunclet will emit the necessary .xdata tables for table-based SEH.
Expand Down
88 changes: 78 additions & 10 deletions llvm/lib/CodeGen/MachineFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -799,31 +799,32 @@ MCSymbol *MachineFunction::addLandingPad(MachineBasicBlock *LandingPad) {
if (LPI->isCleanup() && LPI->getNumClauses() != 0)
LP.TypeIds.push_back(0);

if (LPI->isCleanup())
addCleanup(LandingPad);

// FIXME: New EH - Add the clauses in reverse order. This isn't 100%
// correct, but we need to do it this way because of how the DWARF EH
// emitter processes the clauses.
for (unsigned I = LPI->getNumClauses(); I != 0; --I) {
Value *Val = LPI->getClause(I - 1);
if (LPI->isCatch(I - 1)) {
LP.TypeIds.push_back(
getTypeIDFor(dyn_cast<GlobalValue>(Val->stripPointerCasts())));
addCatchTypeInfo(LandingPad,
dyn_cast<GlobalValue>(Val->stripPointerCasts()));
} else {
// Add filters in a list.
auto *CVal = cast<Constant>(Val);
SmallVector<unsigned, 4> FilterList;
SmallVector<const GlobalValue *, 4> FilterList;
for (const Use &U : CVal->operands())
FilterList.push_back(
getTypeIDFor(cast<GlobalValue>(U->stripPointerCasts())));
FilterList.push_back(cast<GlobalValue>(U->stripPointerCasts()));

LP.TypeIds.push_back(getFilterIDFor(FilterList));
addFilterTypeInfo(LandingPad, FilterList);
}
}

} else if (const auto *CPI = dyn_cast<CatchPadInst>(FirstI)) {
for (unsigned I = CPI->arg_size(); I != 0; --I) {
auto *TypeInfo =
dyn_cast<GlobalValue>(CPI->getArgOperand(I - 1)->stripPointerCasts());
LP.TypeIds.push_back(getTypeIDFor(TypeInfo));
Value *TypeInfo = CPI->getArgOperand(I - 1)->stripPointerCasts();
addCatchTypeInfo(LandingPad, dyn_cast<GlobalValue>(TypeInfo));
}

} else {
Expand All @@ -833,6 +834,73 @@ MCSymbol *MachineFunction::addLandingPad(MachineBasicBlock *LandingPad) {
return LandingPadLabel;
}

void MachineFunction::addCatchTypeInfo(MachineBasicBlock *LandingPad,
ArrayRef<const GlobalValue *> TyInfo) {
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
for (const GlobalValue *GV : llvm::reverse(TyInfo))
LP.TypeIds.push_back(getTypeIDFor(GV));
}

void MachineFunction::addFilterTypeInfo(MachineBasicBlock *LandingPad,
ArrayRef<const GlobalValue *> TyInfo) {
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
std::vector<unsigned> IdsInFilter(TyInfo.size());
for (unsigned I = 0, E = TyInfo.size(); I != E; ++I)
IdsInFilter[I] = getTypeIDFor(TyInfo[I]);
LP.TypeIds.push_back(getFilterIDFor(IdsInFilter));
}

void MachineFunction::tidyLandingPads(DenseMap<MCSymbol *, uintptr_t> *LPMap,
bool TidyIfNoBeginLabels) {
for (unsigned i = 0; i != LandingPads.size(); ) {
LandingPadInfo &LandingPad = LandingPads[i];
if (LandingPad.LandingPadLabel &&
!LandingPad.LandingPadLabel->isDefined() &&
(!LPMap || (*LPMap)[LandingPad.LandingPadLabel] == 0))
LandingPad.LandingPadLabel = nullptr;

// Special case: we *should* emit LPs with null LP MBB. This indicates
// "nounwind" case.
if (!LandingPad.LandingPadLabel && LandingPad.LandingPadBlock) {
LandingPads.erase(LandingPads.begin() + i);
continue;
}

if (TidyIfNoBeginLabels) {
for (unsigned j = 0, e = LandingPads[i].BeginLabels.size(); j != e; ++j) {
MCSymbol *BeginLabel = LandingPad.BeginLabels[j];
MCSymbol *EndLabel = LandingPad.EndLabels[j];
if ((BeginLabel->isDefined() || (LPMap && (*LPMap)[BeginLabel] != 0)) &&
(EndLabel->isDefined() || (LPMap && (*LPMap)[EndLabel] != 0)))
continue;

LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j);
LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j);
--j;
--e;
}

// Remove landing pads with no try-ranges.
if (LandingPads[i].BeginLabels.empty()) {
LandingPads.erase(LandingPads.begin() + i);
continue;
}
}

// If there is no landing pad, ensure that the list of typeids is empty.
// If the only typeid is a cleanup, this is the same as having no typeids.
if (!LandingPad.LandingPadBlock ||
(LandingPad.TypeIds.size() == 1 && !LandingPad.TypeIds[0]))
LandingPad.TypeIds.clear();
++i;
}
}

void MachineFunction::addCleanup(MachineBasicBlock *LandingPad) {
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
LP.TypeIds.push_back(0);
}

void MachineFunction::setCallSiteLandingPad(MCSymbol *Sym,
ArrayRef<unsigned> Sites) {
LPadToCallSiteMap[Sym].append(Sites.begin(), Sites.end());
Expand All @@ -846,7 +914,7 @@ unsigned MachineFunction::getTypeIDFor(const GlobalValue *TI) {
return TypeInfos.size();
}

int MachineFunction::getFilterIDFor(ArrayRef<unsigned> TyIds) {
int MachineFunction::getFilterIDFor(std::vector<unsigned> &TyIds) {
// If the new filter coincides with the tail of an existing filter, then
// re-use the existing filter. Folding filters more than this requires
// re-ordering filters and/or their elements - probably not worth it.
Expand Down
11 changes: 7 additions & 4 deletions llvm/test/CodeGen/X86/gcc_except_table_bb_sections.ll
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ declare i32 @__gxx_personality_v0(...)
; CHECK-NEXT: .uleb128 .Ltmp0-.Lfunc_begin0 # >> Call Site 1 <<
; CHECK-NEXT: .uleb128 .Ltmp1-.Ltmp0 # Call between .Ltmp0 and .Ltmp1
; CHECK-NEXT: .uleb128 .Ltmp2-main.__part.2 # jumps to .Ltmp2
; CHECK-NEXT: .byte 3 # On action: 2
; CHECK-NEXT: .byte 5 # On action: 3
; CHECK-NEXT: .p2align 2
; CHECK-NEXT: .Lexception1:

Expand Down Expand Up @@ -207,9 +207,12 @@ declare i32 @__gxx_personality_v0(...)
; CHECK-NEXT: .byte 0 # >> Action Record 1 <<
; CHECK-NEXT: # Cleanup
; CHECK-NEXT: .byte 0 # No further actions
; CHECK-NEXT: .byte 1 # >> Action Record 2 <<
; CHECK-NEXT: # Catch TypeInfo 1
; CHECK-NEXT: .byte 125 # Continue to action 1
; CHECK-NEXT: .byte 0 # >> Action Record 2 <<
; CHECK-NEXT: # Cleanup
; CHECK-NEXT: .byte 125 # Continue to action 1
; CHECK-NEXT: .byte 1 # >> Action Record 3 <<
; CHECK-NEXT: # Catch TypeInfo 1
; CHECK-NEXT: .byte 125 # Continue to action 2
; CHECK-NEXT: .p2align 2
; CHECK-NEXT: # >> Catch TypeInfos <<

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ declare i32 @__gxx_personality_v0(...)
; CHECK-NEXT: .uleb128 .Ltmp0-.Lfunc_begin0 # >> Call Site 1 <<
; CHECK-NEXT: .uleb128 .Ltmp1-.Ltmp0 # Call between .Ltmp0 and .Ltmp1
; CHECK-NEXT: .uleb128 .Ltmp2-main.cold # jumps to .Ltmp2
; CHECK-NEXT: .byte 3 # On action: 2
; CHECK-NEXT: .byte 5 # On action: 3
; CHECK-NEXT: .p2align 2
; CHECK-NEXT: .Lexception1:
; CHECK-NEXT: .byte 0 # @LPStart Encoding = absptr
Expand All @@ -85,9 +85,12 @@ declare i32 @__gxx_personality_v0(...)
; CHECK-NEXT: .byte 0 # >> Action Record 1 <<
; CHECK-NEXT: # Cleanup
; CHECK-NEXT: .byte 0 # No further actions
; CHECK-NEXT: .byte 1 # >> Action Record 2 <<
; CHECK-NEXT: # Catch TypeInfo 1
; CHECK-NEXT: .byte 0 # >> Action Record 2 <<
; CHECK-NEXT: # Cleanup
; CHECK-NEXT: .byte 125 # Continue to action 1
; CHECK-NEXT: .byte 1 # >> Action Record 3 <<
; CHECK-NEXT: # Catch TypeInfo 1
; CHECK-NEXT: .byte 125 # Continue to action 2
; CHECK-NEXT: .p2align 2
; CHECK-NEXT: # >> Catch TypeInfos <<
; CHECK-NEXT: .long _ZTIi # TypeInfo 1
Expand Down
Loading