Skip to content

Commit

Permalink
Revert "Cleanup unwind table emission code a bit."
Browse files Browse the repository at this point in the history
This reverts commit 648ce3d.

rdar://113994760
llvm#64826
(cherry picked from commit 1c7f71c)
  • Loading branch information
jroelofs authored and bnbarham committed May 20, 2024
1 parent 23ba989 commit ff76102
Show file tree
Hide file tree
Showing 13 changed files with 171 additions and 45 deletions.
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

0 comments on commit ff76102

Please sign in to comment.