/// 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;
/// 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(std::vector<unsigned> &TyIds);
+ int getFilterIDFor(ArrayRef<unsigned> TyIds);
/// Map the landing pad's EH symbol to the call site indexes.
void setCallSiteLandingPad(MCSymbol *Sym, ArrayRef<unsigned> Sites);
namespace llvm {
-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() {}
+AIXException::AIXException(AsmPrinter *A) : EHStreamer(A) {}
void AIXException::emitExceptionInfoTable(const MCSymbol *LSDA,
const MCSymbol *PerSym) {
#include "llvm/MC/MCStreamer.h"
using namespace llvm;
-ARMException::ARMException(AsmPrinter *A) : DwarfCFIExceptionBase(A) {}
+ARMException::ARMException(AsmPrinter *A) : EHStreamer(A) {}
ARMException::~ARMException() = default;
void ARMException::markFunctionEnd() {
if (shouldEmitCFI)
Asm->OutStreamer->emitCFIEndProc();
- DwarfCFIExceptionBase::markFunctionEnd();
}
/// endFunction - Gather and emit post-function exception information.
#include "llvm/Target/TargetOptions.h"
using namespace llvm;
-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(AsmPrinter *A) : EHStreamer(A) {}
DwarfCFIException::~DwarfCFIException() = default;
class MachineFunction;
class ARMTargetStreamer;
-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 {
+class LLVM_LIBRARY_VISIBILITY DwarfCFIException : public EHStreamer {
/// Per-function flag to indicate if .cfi_personality should be emitted.
bool shouldEmitPersonality = false;
/// Per-function flag to indicate if .cfi_lsda should be emitted.
bool shouldEmitLSDA = false;
+ /// 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;
+
public:
//===--------------------------------------------------------------------===//
// Main entry points.
void endBasicBlockSection(const MachineBasicBlock &MBB) override;
};
-class LLVM_LIBRARY_VISIBILITY ARMException : public DwarfCFIExceptionBase {
+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;
+
void emitTypeInfos(unsigned TTypeEncoding, MCSymbol *TTBaseLabel) override;
ARMTargetStreamer &getTargetStreamer();
void markFunctionEnd() override;
};
-class LLVM_LIBRARY_VISIBILITY AIXException : public DwarfCFIExceptionBase {
+class LLVM_LIBRARY_VISIBILITY AIXException : public EHStreamer {
/// 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;
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;
SmallVector<const LandingPadInfo *, 64> LandingPads;
LandingPads.reserve(PadInfos.size());
- for (const LandingPadInfo &LPI : PadInfos)
+ 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;
LandingPads.push_back(&LPI);
+ }
// Order landing pads lexicographically by type id.
llvm::sort(LandingPads, [](const LandingPadInfo *L, const LandingPadInfo *R) {
}
}
-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()) {
void endModule() override;
void beginFunction(const MachineFunction *MF) override {}
- void markFunctionEnd() override;
void endFunction(const MachineFunction *MF) override;
protected:
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.
dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts()))
getMMI().addPersonality(PF);
- if (LPI->isCleanup())
- addCleanup(LandingPad);
+ // If there's no typeid list specified, then "cleanup" is implicit.
+ // Otherwise, id 0 is reserved for the cleanup action.
+ if (LPI->isCleanup() && LPI->getNumClauses() != 0)
+ LP.TypeIds.push_back(0);
// 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
for (unsigned I = LPI->getNumClauses(); I != 0; --I) {
Value *Val = LPI->getClause(I - 1);
if (LPI->isCatch(I - 1)) {
- addCatchTypeInfo(LandingPad,
- dyn_cast<GlobalValue>(Val->stripPointerCasts()));
+ LP.TypeIds.push_back(
+ getTypeIDFor(dyn_cast<GlobalValue>(Val->stripPointerCasts())));
} else {
// Add filters in a list.
auto *CVal = cast<Constant>(Val);
- SmallVector<const GlobalValue *, 4> FilterList;
+ SmallVector<unsigned, 4> FilterList;
for (const Use &U : CVal->operands())
- FilterList.push_back(cast<GlobalValue>(U->stripPointerCasts()));
+ FilterList.push_back(
+ getTypeIDFor(cast<GlobalValue>(U->stripPointerCasts())));
- addFilterTypeInfo(LandingPad, FilterList);
+ LP.TypeIds.push_back(getFilterIDFor(FilterList));
}
}
} else if (const auto *CPI = dyn_cast<CatchPadInst>(FirstI)) {
for (unsigned I = CPI->arg_size(); I != 0; --I) {
- Value *TypeInfo = CPI->getArgOperand(I - 1)->stripPointerCasts();
- addCatchTypeInfo(LandingPad, dyn_cast<GlobalValue>(TypeInfo));
+ auto *TypeInfo =
+ dyn_cast<GlobalValue>(CPI->getArgOperand(I - 1)->stripPointerCasts());
+ LP.TypeIds.push_back(getTypeIDFor(TypeInfo));
}
} else {
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());
return TypeInfos.size();
}
-int MachineFunction::getFilterIDFor(std::vector<unsigned> &TyIds) {
+int MachineFunction::getFilterIDFor(ArrayRef<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.