mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 03:33:20 +01:00
Temporarily Revert "Move most EH from MachineModuleInfo to MachineFunction"
This apprears to have broken the global isel bot: http://lab.llvm.org:8080/green/job/clang-stage1-cmake-RA-globalisel_build/5174/console This reverts commit r288293. llvm-svn: 288322
This commit is contained in:
parent
9d56ed9660
commit
4e57c02b4a
@ -21,13 +21,11 @@
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/ilist.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/Analysis/EHPersonalities.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineMemOperand.h"
|
||||
#include "llvm/IR/DebugLoc.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#include "llvm/MC/MCDwarf.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/ArrayRecycler.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
@ -172,28 +170,6 @@ private:
|
||||
BitVector(static_cast<unsigned>(Property::LastProperty)+1);
|
||||
};
|
||||
|
||||
struct SEHHandler {
|
||||
/// Filter or finally function. Null indicates a catch-all.
|
||||
const Function *FilterOrFinally;
|
||||
|
||||
/// Address of block to recover at. Null for a finally handler.
|
||||
const BlockAddress *RecoverBA;
|
||||
};
|
||||
|
||||
|
||||
/// This structure is used to retain landing pad info for the current function.
|
||||
struct LandingPadInfo {
|
||||
MachineBasicBlock *LandingPadBlock; // Landing pad block.
|
||||
SmallVector<MCSymbol *, 1> BeginLabels; // Labels prior to invoke.
|
||||
SmallVector<MCSymbol *, 1> EndLabels; // Labels after invoke.
|
||||
SmallVector<SEHHandler, 1> SEHHandlers; // SEH handlers active at this lpad.
|
||||
MCSymbol *LandingPadLabel; // Label at beginning of landing pad.
|
||||
std::vector<int> TypeIds; // List of type ids (filters negative).
|
||||
|
||||
explicit LandingPadInfo(MachineBasicBlock *MBB)
|
||||
: LandingPadBlock(MBB), LandingPadLabel(nullptr) {}
|
||||
};
|
||||
|
||||
class MachineFunction {
|
||||
const Function *Fn;
|
||||
const TargetMachine &Target;
|
||||
@ -274,35 +250,6 @@ class MachineFunction {
|
||||
/// by debug and exception handling consumers.
|
||||
std::vector<MCCFIInstruction> FrameInstructions;
|
||||
|
||||
/// \name Exception Handling
|
||||
/// \{
|
||||
|
||||
/// List of LandingPadInfo describing the landing pad information.
|
||||
std::vector<LandingPadInfo> LandingPads;
|
||||
|
||||
/// Map a landing pad's EH symbol to the call site indexes.
|
||||
DenseMap<MCSymbol*, SmallVector<unsigned, 4> > LPadToCallSiteMap;
|
||||
|
||||
/// Map of invoke call site index values to associated begin EH_LABEL.
|
||||
DenseMap<MCSymbol*, unsigned> CallSiteMap;
|
||||
|
||||
bool CallsEHReturn = false;
|
||||
bool CallsUnwindInit = false;
|
||||
bool HasEHFunclets = false;
|
||||
|
||||
/// List of C++ TypeInfo used.
|
||||
std::vector<const GlobalValue *> TypeInfos;
|
||||
|
||||
/// List of typeids encoding filters used.
|
||||
std::vector<unsigned> FilterIds;
|
||||
|
||||
/// List of the indices in FilterIds corresponding to filter terminators.
|
||||
std::vector<unsigned> FilterEnds;
|
||||
|
||||
EHPersonality PersonalityTypeCache = EHPersonality::Unknown;
|
||||
|
||||
/// \}
|
||||
|
||||
MachineFunction(const MachineFunction &) = delete;
|
||||
void operator=(const MachineFunction&) = delete;
|
||||
|
||||
@ -725,105 +672,6 @@ public:
|
||||
return FrameInstructions.size() - 1;
|
||||
}
|
||||
|
||||
/// \name Exception Handling
|
||||
/// \{
|
||||
|
||||
bool callsEHReturn() const { return CallsEHReturn; }
|
||||
void setCallsEHReturn(bool b) { CallsEHReturn = b; }
|
||||
|
||||
bool callsUnwindInit() const { return CallsUnwindInit; }
|
||||
void setCallsUnwindInit(bool b) { CallsUnwindInit = b; }
|
||||
|
||||
bool hasEHFunclets() const { return HasEHFunclets; }
|
||||
void setHasEHFunclets(bool V) { HasEHFunclets = V; }
|
||||
|
||||
/// 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);
|
||||
|
||||
/// Return a reference to the landing pad info for the current function.
|
||||
const std::vector<LandingPadInfo> &getLandingPads() const {
|
||||
return LandingPads;
|
||||
}
|
||||
|
||||
/// Provide the begin and end labels of an invoke style call and associate it
|
||||
/// with a try landing pad block.
|
||||
void addInvoke(MachineBasicBlock *LandingPad,
|
||||
MCSymbol *BeginLabel, MCSymbol *EndLabel);
|
||||
|
||||
/// Add a new panding pad. Returns the label ID for the landing pad 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);
|
||||
|
||||
void addSEHCatchHandler(MachineBasicBlock *LandingPad, const Function *Filter,
|
||||
const BlockAddress *RecoverLabel);
|
||||
|
||||
void addSEHCleanupHandler(MachineBasicBlock *LandingPad,
|
||||
const Function *Cleanup);
|
||||
|
||||
/// 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);
|
||||
|
||||
/// Map the landing pad's EH symbol to the call site indexes.
|
||||
void setCallSiteLandingPad(MCSymbol *Sym, ArrayRef<unsigned> Sites);
|
||||
|
||||
/// Get the call site indexes for a landing pad EH symbol.
|
||||
SmallVectorImpl<unsigned> &getCallSiteLandingPad(MCSymbol *Sym) {
|
||||
assert(hasCallSiteLandingPad(Sym) &&
|
||||
"missing call site number for landing pad!");
|
||||
return LPadToCallSiteMap[Sym];
|
||||
}
|
||||
|
||||
/// Return true if the landing pad Eh symbol has an associated call site.
|
||||
bool hasCallSiteLandingPad(MCSymbol *Sym) {
|
||||
return !LPadToCallSiteMap[Sym].empty();
|
||||
}
|
||||
|
||||
/// Map the begin label for a call site.
|
||||
void setCallSiteBeginLabel(MCSymbol *BeginLabel, unsigned Site) {
|
||||
CallSiteMap[BeginLabel] = Site;
|
||||
}
|
||||
|
||||
/// Get the call site number for a begin label.
|
||||
unsigned getCallSiteBeginLabel(MCSymbol *BeginLabel) const {
|
||||
assert(hasCallSiteBeginLabel(BeginLabel) &&
|
||||
"Missing call site number for EH_LABEL!");
|
||||
return CallSiteMap.lookup(BeginLabel);
|
||||
}
|
||||
|
||||
/// Return true if the begin label has a call site number associated with it.
|
||||
bool hasCallSiteBeginLabel(MCSymbol *BeginLabel) const {
|
||||
return CallSiteMap.count(BeginLabel);
|
||||
}
|
||||
|
||||
/// Return a reference to the C++ typeinfo for the current function.
|
||||
const std::vector<const GlobalValue *> &getTypeInfos() const {
|
||||
return TypeInfos;
|
||||
}
|
||||
|
||||
/// Return a reference to the typeids encoding filters used in the current
|
||||
/// function.
|
||||
const std::vector<unsigned> &getFilterIds() const {
|
||||
return FilterIds;
|
||||
}
|
||||
|
||||
/// \}
|
||||
|
||||
/// Collect information used to emit debugging information of a variable.
|
||||
void setVariableDbgInfo(const DILocalVariable *Var, const DIExpression *Expr,
|
||||
unsigned Slot, const DILocation *Loc) {
|
||||
@ -836,15 +684,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// \name Exception Handling
|
||||
/// \{
|
||||
|
||||
/// Extract the exception handling information from the landingpad instruction
|
||||
/// and add them to the specified machine module info.
|
||||
void addLandingPadInfo(const LandingPadInst &I, MachineBasicBlock &MBB);
|
||||
|
||||
/// \}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// GraphTraits specializations for function basic block graphs (CFGs)
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Analysis/EHPersonalities.h"
|
||||
#include "llvm/IR/DebugLoc.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
@ -61,6 +62,29 @@ class Module;
|
||||
class PointerType;
|
||||
class StructType;
|
||||
|
||||
struct SEHHandler {
|
||||
// Filter or finally function. Null indicates a catch-all.
|
||||
const Function *FilterOrFinally;
|
||||
|
||||
// Address of block to recover at. Null for a finally handler.
|
||||
const BlockAddress *RecoverBA;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// This structure is used to retain landing pad info for the current function.
|
||||
///
|
||||
struct LandingPadInfo {
|
||||
MachineBasicBlock *LandingPadBlock; // Landing pad block.
|
||||
SmallVector<MCSymbol *, 1> BeginLabels; // Labels prior to invoke.
|
||||
SmallVector<MCSymbol *, 1> EndLabels; // Labels after invoke.
|
||||
SmallVector<SEHHandler, 1> SEHHandlers; // SEH handlers active at this lpad.
|
||||
MCSymbol *LandingPadLabel; // Label at beginning of landing pad.
|
||||
std::vector<int> TypeIds; // List of type ids (filters negative).
|
||||
|
||||
explicit LandingPadInfo(MachineBasicBlock *MBB)
|
||||
: LandingPadBlock(MBB), LandingPadLabel(nullptr) {}
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// This class can be derived from and used by targets to hold private
|
||||
/// target-specific information for each Module. Objects of type are
|
||||
@ -98,22 +122,41 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
/// want.
|
||||
MachineModuleInfoImpl *ObjFileMMI;
|
||||
|
||||
/// \name Exception Handling
|
||||
/// \{
|
||||
/// List of LandingPadInfo describing the landing pad information in the
|
||||
/// current function.
|
||||
std::vector<LandingPadInfo> LandingPads;
|
||||
|
||||
/// Map a landing pad's EH symbol to the call site indexes.
|
||||
DenseMap<MCSymbol*, SmallVector<unsigned, 4> > LPadToCallSiteMap;
|
||||
|
||||
/// Map of invoke call site index values to associated begin EH_LABEL for the
|
||||
/// current function.
|
||||
DenseMap<MCSymbol*, unsigned> CallSiteMap;
|
||||
|
||||
/// The current call site index being processed, if any. 0 if none.
|
||||
unsigned CurCallSite;
|
||||
|
||||
/// List of C++ TypeInfo used in the current function.
|
||||
std::vector<const GlobalValue *> TypeInfos;
|
||||
|
||||
/// List of typeids encoding filters used in the current function.
|
||||
std::vector<unsigned> FilterIds;
|
||||
|
||||
/// List of the indices in FilterIds corresponding to filter terminators.
|
||||
std::vector<unsigned> FilterEnds;
|
||||
|
||||
/// Vector of all personality functions ever seen. Used to emit common EH
|
||||
/// frames.
|
||||
std::vector<const Function *> Personalities;
|
||||
|
||||
/// The current call site index being processed, if any. 0 if none.
|
||||
unsigned CurCallSite;
|
||||
|
||||
/// \}
|
||||
|
||||
/// This map keeps track of which symbol is being used for the specified
|
||||
/// basic block's address of label.
|
||||
MMIAddrLabelMap *AddrLabelSymbols;
|
||||
|
||||
bool CallsEHReturn;
|
||||
bool CallsUnwindInit;
|
||||
bool HasEHFunclets;
|
||||
|
||||
// TODO: Ideally, what we'd like is to have a switch that allows emitting
|
||||
// synchronous (precise at call-sites only) CFA into .eh_frame. However,
|
||||
// even under this switch, we'd like .debug_frame to be precise when using.
|
||||
@ -134,6 +177,8 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
/// comments in lib/Target/X86/X86FrameLowering.cpp for more details.
|
||||
bool UsesMorestackAddr;
|
||||
|
||||
EHPersonality PersonalityTypeCache;
|
||||
|
||||
MachineFunctionInitializer *MFInitializer;
|
||||
/// Maps IR Functions to their corresponding MachineFunctions.
|
||||
DenseMap<const Function*, std::unique_ptr<MachineFunction>> MachineFunctions;
|
||||
@ -152,6 +197,9 @@ public:
|
||||
bool doInitialization(Module &) override;
|
||||
bool doFinalization(Module &) override;
|
||||
|
||||
/// Discard function meta information.
|
||||
void EndFunction();
|
||||
|
||||
const MCContext &getContext() const { return Context; }
|
||||
MCContext &getContext() { return Context; }
|
||||
|
||||
@ -189,6 +237,15 @@ public:
|
||||
bool hasDebugInfo() const { return DbgInfoAvailable; }
|
||||
void setDebugInfoAvailability(bool avail) { DbgInfoAvailable = avail; }
|
||||
|
||||
bool callsEHReturn() const { return CallsEHReturn; }
|
||||
void setCallsEHReturn(bool b) { CallsEHReturn = b; }
|
||||
|
||||
bool callsUnwindInit() const { return CallsUnwindInit; }
|
||||
void setCallsUnwindInit(bool b) { CallsUnwindInit = b; }
|
||||
|
||||
bool hasEHFunclets() const { return HasEHFunclets; }
|
||||
void setHasEHFunclets(bool V) { HasEHFunclets = V; }
|
||||
|
||||
bool usesVAFloatArgument() const {
|
||||
return UsesVAFloatArgument;
|
||||
}
|
||||
@ -224,15 +281,19 @@ public:
|
||||
void takeDeletedSymbolsForFunction(const Function *F,
|
||||
std::vector<MCSymbol*> &Result);
|
||||
|
||||
/// \name Exception Handling
|
||||
/// \{
|
||||
|
||||
/// Set the call site currently being processed.
|
||||
void setCurrentCallSite(unsigned Site) { CurCallSite = Site; }
|
||||
//===- EH ---------------------------------------------------------------===//
|
||||
|
||||
/// Get the call site currently being processed, if any. return zero if
|
||||
/// none.
|
||||
unsigned getCurrentCallSite() { return CurCallSite; }
|
||||
/// Find or create an LandingPadInfo for the specified MachineBasicBlock.
|
||||
LandingPadInfo &getOrCreateLandingPadInfo(MachineBasicBlock *LandingPad);
|
||||
|
||||
/// Provide the begin and end labels of an invoke style call and associate it
|
||||
/// with a try landing pad block.
|
||||
void addInvoke(MachineBasicBlock *LandingPad,
|
||||
MCSymbol *BeginLabel, MCSymbol *EndLabel);
|
||||
|
||||
/// Add a new panding pad. Returns the label ID for the landing pad entry.
|
||||
MCSymbol *addLandingPad(MachineBasicBlock *LandingPad);
|
||||
|
||||
/// Provide the personality function for the exception information.
|
||||
void addPersonality(const Function *Personality);
|
||||
@ -241,7 +302,87 @@ public:
|
||||
const std::vector<const Function *>& getPersonalities() const {
|
||||
return Personalities;
|
||||
}
|
||||
/// \}
|
||||
|
||||
/// 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);
|
||||
|
||||
void addSEHCatchHandler(MachineBasicBlock *LandingPad, const Function *Filter,
|
||||
const BlockAddress *RecoverLabel);
|
||||
|
||||
void addSEHCleanupHandler(MachineBasicBlock *LandingPad,
|
||||
const Function *Cleanup);
|
||||
|
||||
/// 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);
|
||||
|
||||
/// Remap landing pad labels and remove any deleted landing pads.
|
||||
void TidyLandingPads(DenseMap<MCSymbol*, uintptr_t> *LPMap = nullptr);
|
||||
|
||||
/// Return a reference to the landing pad info for the current function.
|
||||
const std::vector<LandingPadInfo> &getLandingPads() const {
|
||||
return LandingPads;
|
||||
}
|
||||
|
||||
/// Map the landing pad's EH symbol to the call site indexes.
|
||||
void setCallSiteLandingPad(MCSymbol *Sym, ArrayRef<unsigned> Sites);
|
||||
|
||||
/// Get the call site indexes for a landing pad EH symbol.
|
||||
SmallVectorImpl<unsigned> &getCallSiteLandingPad(MCSymbol *Sym) {
|
||||
assert(hasCallSiteLandingPad(Sym) &&
|
||||
"missing call site number for landing pad!");
|
||||
return LPadToCallSiteMap[Sym];
|
||||
}
|
||||
|
||||
/// Return true if the landing pad Eh symbol has an associated call site.
|
||||
bool hasCallSiteLandingPad(MCSymbol *Sym) {
|
||||
return !LPadToCallSiteMap[Sym].empty();
|
||||
}
|
||||
|
||||
/// Map the begin label for a call site.
|
||||
void setCallSiteBeginLabel(MCSymbol *BeginLabel, unsigned Site) {
|
||||
CallSiteMap[BeginLabel] = Site;
|
||||
}
|
||||
|
||||
/// Get the call site number for a begin label.
|
||||
unsigned getCallSiteBeginLabel(MCSymbol *BeginLabel) {
|
||||
assert(hasCallSiteBeginLabel(BeginLabel) &&
|
||||
"Missing call site number for EH_LABEL!");
|
||||
return CallSiteMap[BeginLabel];
|
||||
}
|
||||
|
||||
/// Return true if the begin label has a call site number associated with it.
|
||||
bool hasCallSiteBeginLabel(MCSymbol *BeginLabel) {
|
||||
return CallSiteMap[BeginLabel] != 0;
|
||||
}
|
||||
|
||||
/// Set the call site currently being processed.
|
||||
void setCurrentCallSite(unsigned Site) { CurCallSite = Site; }
|
||||
|
||||
/// Get the call site currently being processed, if any. return zero if
|
||||
/// none.
|
||||
unsigned getCurrentCallSite() { return CurCallSite; }
|
||||
|
||||
/// Return a reference to the C++ typeinfo for the current function.
|
||||
const std::vector<const GlobalValue *> &getTypeInfos() const {
|
||||
return TypeInfos;
|
||||
}
|
||||
|
||||
/// Return a reference to the typeids encoding filters used in the current
|
||||
/// function.
|
||||
const std::vector<unsigned> &getFilterIds() const {
|
||||
return FilterIds;
|
||||
}
|
||||
}; // End class MachineModuleInfo
|
||||
|
||||
//===- MMI building helpers -----------------------------------------------===//
|
||||
@ -252,6 +393,12 @@ public:
|
||||
/// which will link in MSVCRT's floating-point support.
|
||||
void computeUsesVAFloatArgument(const CallInst &I, MachineModuleInfo &MMI);
|
||||
|
||||
/// Extract the exception handling information from the landingpad instruction
|
||||
/// and add them to the specified machine module info.
|
||||
void addLandingPadInfo(const LandingPadInst &I, MachineModuleInfo &MMI,
|
||||
MachineBasicBlock &MBB);
|
||||
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -684,7 +684,7 @@ llvm::getFuncletMembership(const MachineFunction &MF) {
|
||||
DenseMap<const MachineBasicBlock *, int> FuncletMembership;
|
||||
|
||||
// We don't have anything to do if there aren't any EH pads.
|
||||
if (!MF.hasEHFunclets())
|
||||
if (!MF.getMMI().hasEHFunclets())
|
||||
return FuncletMembership;
|
||||
|
||||
int EntryBBNumber = MF.front().getNumber();
|
||||
|
@ -75,7 +75,7 @@ void ARMException::endFunction(const MachineFunction *MF) {
|
||||
F->hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
|
||||
F->needsUnwindTableEntry();
|
||||
bool shouldEmitPersonality = forceEmitPersonality ||
|
||||
!MF->getLandingPads().empty();
|
||||
!MMI->getLandingPads().empty();
|
||||
if (!Asm->MF->getFunction()->needsUnwindTableEntry() &&
|
||||
!shouldEmitPersonality)
|
||||
ATS.emitCantUnwind();
|
||||
@ -99,9 +99,8 @@ void ARMException::endFunction(const MachineFunction *MF) {
|
||||
}
|
||||
|
||||
void ARMException::emitTypeInfos(unsigned TTypeEncoding) {
|
||||
const MachineFunction *MF = Asm->MF;
|
||||
const std::vector<const GlobalValue *> &TypeInfos = MF->getTypeInfos();
|
||||
const std::vector<unsigned> &FilterIds = MF->getFilterIds();
|
||||
const std::vector<const GlobalValue *> &TypeInfos = MMI->getTypeInfos();
|
||||
const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
|
||||
|
||||
bool VerboseAsm = Asm->OutStreamer->isVerboseAsm();
|
||||
|
||||
|
@ -947,8 +947,8 @@ void AsmPrinter::EmitFunctionBody() {
|
||||
// Emit target-specific gunk after the function body.
|
||||
EmitFunctionBodyEnd();
|
||||
|
||||
if (!MF->getLandingPads().empty() || MMI->hasDebugInfo() ||
|
||||
MF->hasEHFunclets() || MAI->hasDotTypeDotSizeDirective()) {
|
||||
if (!MMI->getLandingPads().empty() || MMI->hasDebugInfo() ||
|
||||
MMI->hasEHFunclets() || MAI->hasDotTypeDotSizeDirective()) {
|
||||
// Create a symbol for the end of function.
|
||||
CurrentFnEnd = createTempSymbol("func_end");
|
||||
OutStreamer->EmitLabel(CurrentFnEnd);
|
||||
@ -981,6 +981,7 @@ void AsmPrinter::EmitFunctionBody() {
|
||||
HI.TimerGroupDescription, TimePassesIsEnabled);
|
||||
HI.Handler->endFunction(MF);
|
||||
}
|
||||
MMI->EndFunction();
|
||||
|
||||
OutStreamer->AddBlankLine();
|
||||
}
|
||||
@ -1272,8 +1273,8 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
|
||||
CurrentFnBegin = nullptr;
|
||||
CurExceptionSym = nullptr;
|
||||
bool NeedsLocalForSize = MAI->needsLocalForSize();
|
||||
if (!MF.getLandingPads().empty() || MMI->hasDebugInfo() ||
|
||||
MF.hasEHFunclets() || NeedsLocalForSize) {
|
||||
if (!MMI->getLandingPads().empty() || MMI->hasDebugInfo() ||
|
||||
MMI->hasEHFunclets() || NeedsLocalForSize) {
|
||||
CurrentFnBegin = createTempSymbol("func_begin");
|
||||
if (NeedsLocalForSize)
|
||||
CurrentFnSymForSize = CurrentFnBegin;
|
||||
|
@ -44,11 +44,11 @@ DwarfCFIExceptionBase::DwarfCFIExceptionBase(AsmPrinter *A)
|
||||
void DwarfCFIExceptionBase::markFunctionEnd() {
|
||||
endFragment();
|
||||
|
||||
if (MMI->getLandingPads().empty())
|
||||
return;
|
||||
|
||||
// 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();
|
||||
}
|
||||
MMI->TidyLandingPads();
|
||||
}
|
||||
|
||||
void DwarfCFIExceptionBase::endFragment() {
|
||||
@ -98,7 +98,7 @@ void DwarfCFIException::beginFunction(const MachineFunction *MF) {
|
||||
const Function *F = MF->getFunction();
|
||||
|
||||
// If any landing pads survive, we need an EH table.
|
||||
bool hasLandingPads = !MF->getLandingPads().empty();
|
||||
bool hasLandingPads = !MMI->getLandingPads().empty();
|
||||
|
||||
// See if we need frame move info.
|
||||
AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves();
|
||||
@ -170,7 +170,7 @@ void DwarfCFIException::beginFragment(const MachineBasicBlock *MBB,
|
||||
|
||||
/// endFunction - Gather and emit post-function exception information.
|
||||
///
|
||||
void DwarfCFIException::endFunction(const MachineFunction *MF) {
|
||||
void DwarfCFIException::endFunction(const MachineFunction *) {
|
||||
if (!shouldEmitPersonality)
|
||||
return;
|
||||
|
||||
|
@ -74,7 +74,7 @@ computeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads,
|
||||
// output using a fixed width encoding. FilterOffsets[i] holds the byte
|
||||
// offset corresponding to FilterIds[i].
|
||||
|
||||
const std::vector<unsigned> &FilterIds = Asm->MF->getFilterIds();
|
||||
const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
|
||||
SmallVector<int, 16> FilterOffsets;
|
||||
FilterOffsets.reserve(FilterIds.size());
|
||||
int Offset = -1;
|
||||
@ -296,7 +296,7 @@ computeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
|
||||
else {
|
||||
// SjLj EH must maintain the call sites in the order assigned
|
||||
// to them by the SjLjPrepare pass.
|
||||
unsigned SiteNo = Asm->MF->getCallSiteBeginLabel(BeginLabel);
|
||||
unsigned SiteNo = MMI->getCallSiteBeginLabel(BeginLabel);
|
||||
if (CallSites.size() < SiteNo)
|
||||
CallSites.resize(SiteNo);
|
||||
CallSites[SiteNo - 1] = Site;
|
||||
@ -336,10 +336,9 @@ computeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
|
||||
/// 3. Type ID table contains references to all the C++ typeinfo for all
|
||||
/// catches in the function. This tables is reverse indexed base 1.
|
||||
void EHStreamer::emitExceptionTable() {
|
||||
const MachineFunction *MF = Asm->MF;
|
||||
const std::vector<const GlobalValue *> &TypeInfos = MF->getTypeInfos();
|
||||
const std::vector<unsigned> &FilterIds = MF->getFilterIds();
|
||||
const std::vector<LandingPadInfo> &PadInfos = MF->getLandingPads();
|
||||
const std::vector<const GlobalValue *> &TypeInfos = MMI->getTypeInfos();
|
||||
const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
|
||||
const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
|
||||
|
||||
// Sort the landing pads in order of their type ids. This is used to fold
|
||||
// duplicate actions.
|
||||
@ -650,9 +649,8 @@ void EHStreamer::emitExceptionTable() {
|
||||
}
|
||||
|
||||
void EHStreamer::emitTypeInfos(unsigned TTypeEncoding) {
|
||||
const MachineFunction *MF = Asm->MF;
|
||||
const std::vector<const GlobalValue *> &TypeInfos = MF->getTypeInfos();
|
||||
const std::vector<unsigned> &FilterIds = MF->getFilterIds();
|
||||
const std::vector<const GlobalValue *> &TypeInfos = MMI->getTypeInfos();
|
||||
const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
|
||||
|
||||
bool VerboseAsm = Asm->OutStreamer->isVerboseAsm();
|
||||
|
||||
|
@ -63,8 +63,8 @@ void WinException::beginFunction(const MachineFunction *MF) {
|
||||
shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false;
|
||||
|
||||
// If any landing pads survive, we need an EH table.
|
||||
bool hasLandingPads = !MF->getLandingPads().empty();
|
||||
bool hasEHFunclets = MF->hasEHFunclets();
|
||||
bool hasLandingPads = !MMI->getLandingPads().empty();
|
||||
bool hasEHFunclets = MMI->hasEHFunclets();
|
||||
|
||||
const Function *F = MF->getFunction();
|
||||
|
||||
@ -126,15 +126,13 @@ void WinException::endFunction(const MachineFunction *MF) {
|
||||
// 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();
|
||||
}
|
||||
if (!isFuncletEHPersonality(Per))
|
||||
MMI->TidyLandingPads();
|
||||
|
||||
endFunclet();
|
||||
|
||||
// endFunclet will emit the necessary .xdata tables for x64 SEH.
|
||||
if (Per == EHPersonality::MSVC_Win64SEH && MF->hasEHFunclets())
|
||||
if (Per == EHPersonality::MSVC_Win64SEH && MMI->hasEHFunclets())
|
||||
return;
|
||||
|
||||
if (shouldEmitPersonality || shouldEmitLSDA) {
|
||||
@ -236,9 +234,8 @@ void WinException::endFunclet() {
|
||||
if (!CurrentFuncletEntry)
|
||||
return;
|
||||
|
||||
const MachineFunction *MF = Asm->MF;
|
||||
if (shouldEmitMoves || shouldEmitPersonality) {
|
||||
const Function *F = MF->getFunction();
|
||||
const Function *F = Asm->MF->getFunction();
|
||||
EHPersonality Per = EHPersonality::Unknown;
|
||||
if (F->hasPersonalityFn())
|
||||
Per = classifyEHPersonality(F->getPersonalityFn()->stripPointerCasts());
|
||||
@ -258,11 +255,11 @@ void WinException::endFunclet() {
|
||||
MCSymbol *FuncInfoXData = Asm->OutContext.getOrCreateSymbol(
|
||||
Twine("$cppxdata$", FuncLinkageName));
|
||||
Asm->OutStreamer->EmitValue(create32bitRef(FuncInfoXData), 4);
|
||||
} else if (Per == EHPersonality::MSVC_Win64SEH && MF->hasEHFunclets() &&
|
||||
} else if (Per == EHPersonality::MSVC_Win64SEH && MMI->hasEHFunclets() &&
|
||||
!CurrentFuncletEntry->isEHFuncletEntry()) {
|
||||
// If this is the parent function in Win64 SEH, emit the LSDA immediately
|
||||
// following .seh_handlerdata.
|
||||
emitCSpecificHandlerTable(MF);
|
||||
emitCSpecificHandlerTable(Asm->MF);
|
||||
}
|
||||
|
||||
// Switch back to the previous section now that we are done writing to
|
||||
|
@ -568,193 +568,6 @@ MCSymbol *MachineFunction::getPICBaseSymbol() const {
|
||||
Twine(getFunctionNumber()) + "$pb");
|
||||
}
|
||||
|
||||
/// \name Exception Handling
|
||||
/// \{
|
||||
|
||||
LandingPadInfo &
|
||||
MachineFunction::getOrCreateLandingPadInfo(MachineBasicBlock *LandingPad) {
|
||||
unsigned N = LandingPads.size();
|
||||
for (unsigned i = 0; i < N; ++i) {
|
||||
LandingPadInfo &LP = LandingPads[i];
|
||||
if (LP.LandingPadBlock == LandingPad)
|
||||
return LP;
|
||||
}
|
||||
|
||||
LandingPads.push_back(LandingPadInfo(LandingPad));
|
||||
return LandingPads[N];
|
||||
}
|
||||
|
||||
void MachineFunction::addInvoke(MachineBasicBlock *LandingPad,
|
||||
MCSymbol *BeginLabel, MCSymbol *EndLabel) {
|
||||
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
|
||||
LP.BeginLabels.push_back(BeginLabel);
|
||||
LP.EndLabels.push_back(EndLabel);
|
||||
}
|
||||
|
||||
MCSymbol *MachineFunction::addLandingPad(MachineBasicBlock *LandingPad) {
|
||||
MCSymbol *LandingPadLabel = Ctx.createTempSymbol();
|
||||
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
|
||||
LP.LandingPadLabel = LandingPadLabel;
|
||||
return LandingPadLabel;
|
||||
}
|
||||
|
||||
void MachineFunction::addCatchTypeInfo(MachineBasicBlock *LandingPad,
|
||||
ArrayRef<const GlobalValue *> TyInfo) {
|
||||
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
|
||||
for (unsigned N = TyInfo.size(); N; --N)
|
||||
LP.TypeIds.push_back(getTypeIDFor(TyInfo[N - 1]));
|
||||
}
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
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::addSEHCatchHandler(MachineBasicBlock *LandingPad,
|
||||
const Function *Filter,
|
||||
const BlockAddress *RecoverBA) {
|
||||
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
|
||||
SEHHandler Handler;
|
||||
Handler.FilterOrFinally = Filter;
|
||||
Handler.RecoverBA = RecoverBA;
|
||||
LP.SEHHandlers.push_back(Handler);
|
||||
}
|
||||
|
||||
void MachineFunction::addSEHCleanupHandler(MachineBasicBlock *LandingPad,
|
||||
const Function *Cleanup) {
|
||||
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
|
||||
SEHHandler Handler;
|
||||
Handler.FilterOrFinally = Cleanup;
|
||||
Handler.RecoverBA = nullptr;
|
||||
LP.SEHHandlers.push_back(Handler);
|
||||
}
|
||||
|
||||
void MachineFunction::setCallSiteLandingPad(MCSymbol *Sym,
|
||||
ArrayRef<unsigned> Sites) {
|
||||
LPadToCallSiteMap[Sym].append(Sites.begin(), Sites.end());
|
||||
}
|
||||
|
||||
unsigned MachineFunction::getTypeIDFor(const GlobalValue *TI) {
|
||||
for (unsigned i = 0, N = TypeInfos.size(); i != N; ++i)
|
||||
if (TypeInfos[i] == TI) return i + 1;
|
||||
|
||||
TypeInfos.push_back(TI);
|
||||
return TypeInfos.size();
|
||||
}
|
||||
|
||||
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.
|
||||
for (std::vector<unsigned>::iterator I = FilterEnds.begin(),
|
||||
E = FilterEnds.end(); I != E; ++I) {
|
||||
unsigned i = *I, j = TyIds.size();
|
||||
|
||||
while (i && j)
|
||||
if (FilterIds[--i] != TyIds[--j])
|
||||
goto try_next;
|
||||
|
||||
if (!j)
|
||||
// The new filter coincides with range [i, end) of the existing filter.
|
||||
return -(1 + i);
|
||||
|
||||
try_next:;
|
||||
}
|
||||
|
||||
// Add the new filter.
|
||||
int FilterID = -(1 + FilterIds.size());
|
||||
FilterIds.reserve(FilterIds.size() + TyIds.size() + 1);
|
||||
FilterIds.insert(FilterIds.end(), TyIds.begin(), TyIds.end());
|
||||
FilterEnds.push_back(FilterIds.size());
|
||||
FilterIds.push_back(0); // terminator
|
||||
return FilterID;
|
||||
}
|
||||
|
||||
void llvm::addLandingPadInfo(const LandingPadInst &I, MachineBasicBlock &MBB) {
|
||||
MachineFunction &MF = *MBB.getParent();
|
||||
if (const auto *PF = dyn_cast<Function>(
|
||||
I.getParent()->getParent()->getPersonalityFn()->stripPointerCasts()))
|
||||
MF.getMMI().addPersonality(PF);
|
||||
|
||||
if (I.isCleanup())
|
||||
MF.addCleanup(&MBB);
|
||||
|
||||
// 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 = I.getNumClauses(); i != 0; --i) {
|
||||
Value *Val = I.getClause(i - 1);
|
||||
if (I.isCatch(i - 1)) {
|
||||
MF.addCatchTypeInfo(&MBB,
|
||||
dyn_cast<GlobalValue>(Val->stripPointerCasts()));
|
||||
} else {
|
||||
// Add filters in a list.
|
||||
Constant *CVal = cast<Constant>(Val);
|
||||
SmallVector<const GlobalValue *, 4> FilterList;
|
||||
for (User::op_iterator II = CVal->op_begin(), IE = CVal->op_end();
|
||||
II != IE; ++II)
|
||||
FilterList.push_back(cast<GlobalValue>((*II)->stripPointerCasts()));
|
||||
|
||||
MF.addFilterTypeInfo(&MBB, FilterList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// \}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MachineFrameInfo implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -203,7 +203,11 @@ bool MachineModuleInfo::doInitialization(Module &M) {
|
||||
|
||||
ObjFileMMI = nullptr;
|
||||
CurCallSite = 0;
|
||||
CallsEHReturn = false;
|
||||
CallsUnwindInit = false;
|
||||
HasEHFunclets = false;
|
||||
DbgInfoAvailable = UsesVAFloatArgument = UsesMorestackAddr = false;
|
||||
PersonalityTypeCache = EHPersonality::Unknown;
|
||||
AddrLabelSymbols = nullptr;
|
||||
TheModule = &M;
|
||||
|
||||
@ -225,6 +229,19 @@ bool MachineModuleInfo::doFinalization(Module &M) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void MachineModuleInfo::EndFunction() {
|
||||
// Clean up exception info.
|
||||
LandingPads.clear();
|
||||
PersonalityTypeCache = EHPersonality::Unknown;
|
||||
CallSiteMap.clear();
|
||||
TypeInfos.clear();
|
||||
FilterIds.clear();
|
||||
FilterEnds.clear();
|
||||
CallsEHReturn = false;
|
||||
CallsUnwindInit = false;
|
||||
HasEHFunclets = false;
|
||||
}
|
||||
|
||||
//===- Address of Block Management ----------------------------------------===//
|
||||
|
||||
ArrayRef<MCSymbol *>
|
||||
@ -244,8 +261,34 @@ takeDeletedSymbolsForFunction(const Function *F,
|
||||
takeDeletedSymbolsForFunction(const_cast<Function*>(F), Result);
|
||||
}
|
||||
|
||||
/// \name Exception Handling
|
||||
/// \{
|
||||
//===- EH -----------------------------------------------------------------===//
|
||||
|
||||
LandingPadInfo &MachineModuleInfo::getOrCreateLandingPadInfo
|
||||
(MachineBasicBlock *LandingPad) {
|
||||
unsigned N = LandingPads.size();
|
||||
for (unsigned i = 0; i < N; ++i) {
|
||||
LandingPadInfo &LP = LandingPads[i];
|
||||
if (LP.LandingPadBlock == LandingPad)
|
||||
return LP;
|
||||
}
|
||||
|
||||
LandingPads.push_back(LandingPadInfo(LandingPad));
|
||||
return LandingPads[N];
|
||||
}
|
||||
|
||||
void MachineModuleInfo::addInvoke(MachineBasicBlock *LandingPad,
|
||||
MCSymbol *BeginLabel, MCSymbol *EndLabel) {
|
||||
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
|
||||
LP.BeginLabels.push_back(BeginLabel);
|
||||
LP.EndLabels.push_back(EndLabel);
|
||||
}
|
||||
|
||||
MCSymbol *MachineModuleInfo::addLandingPad(MachineBasicBlock *LandingPad) {
|
||||
MCSymbol *LandingPadLabel = Context.createTempSymbol();
|
||||
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
|
||||
LP.LandingPadLabel = LandingPadLabel;
|
||||
return LandingPadLabel;
|
||||
}
|
||||
|
||||
void MachineModuleInfo::addPersonality(const Function *Personality) {
|
||||
for (unsigned i = 0; i < Personalities.size(); ++i)
|
||||
@ -254,7 +297,132 @@ void MachineModuleInfo::addPersonality(const Function *Personality) {
|
||||
Personalities.push_back(Personality);
|
||||
}
|
||||
|
||||
/// \}
|
||||
void MachineModuleInfo::
|
||||
addCatchTypeInfo(MachineBasicBlock *LandingPad,
|
||||
ArrayRef<const GlobalValue *> TyInfo) {
|
||||
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
|
||||
for (unsigned N = TyInfo.size(); N; --N)
|
||||
LP.TypeIds.push_back(getTypeIDFor(TyInfo[N - 1]));
|
||||
}
|
||||
|
||||
void MachineModuleInfo::
|
||||
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 MachineModuleInfo::addCleanup(MachineBasicBlock *LandingPad) {
|
||||
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
|
||||
LP.TypeIds.push_back(0);
|
||||
}
|
||||
|
||||
void MachineModuleInfo::addSEHCatchHandler(MachineBasicBlock *LandingPad,
|
||||
const Function *Filter,
|
||||
const BlockAddress *RecoverBA) {
|
||||
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
|
||||
SEHHandler Handler;
|
||||
Handler.FilterOrFinally = Filter;
|
||||
Handler.RecoverBA = RecoverBA;
|
||||
LP.SEHHandlers.push_back(Handler);
|
||||
}
|
||||
|
||||
void MachineModuleInfo::addSEHCleanupHandler(MachineBasicBlock *LandingPad,
|
||||
const Function *Cleanup) {
|
||||
LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
|
||||
SEHHandler Handler;
|
||||
Handler.FilterOrFinally = Cleanup;
|
||||
Handler.RecoverBA = nullptr;
|
||||
LP.SEHHandlers.push_back(Handler);
|
||||
}
|
||||
|
||||
void MachineModuleInfo::TidyLandingPads(DenseMap<MCSymbol*, uintptr_t> *LPMap) {
|
||||
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;
|
||||
}
|
||||
|
||||
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 MachineModuleInfo::setCallSiteLandingPad(MCSymbol *Sym,
|
||||
ArrayRef<unsigned> Sites) {
|
||||
LPadToCallSiteMap[Sym].append(Sites.begin(), Sites.end());
|
||||
}
|
||||
|
||||
unsigned MachineModuleInfo::getTypeIDFor(const GlobalValue *TI) {
|
||||
for (unsigned i = 0, N = TypeInfos.size(); i != N; ++i)
|
||||
if (TypeInfos[i] == TI) return i + 1;
|
||||
|
||||
TypeInfos.push_back(TI);
|
||||
return TypeInfos.size();
|
||||
}
|
||||
|
||||
int MachineModuleInfo::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.
|
||||
for (std::vector<unsigned>::iterator I = FilterEnds.begin(),
|
||||
E = FilterEnds.end(); I != E; ++I) {
|
||||
unsigned i = *I, j = TyIds.size();
|
||||
|
||||
while (i && j)
|
||||
if (FilterIds[--i] != TyIds[--j])
|
||||
goto try_next;
|
||||
|
||||
if (!j)
|
||||
// The new filter coincides with range [i, end) of the existing filter.
|
||||
return -(1 + i);
|
||||
|
||||
try_next:;
|
||||
}
|
||||
|
||||
// Add the new filter.
|
||||
int FilterID = -(1 + FilterIds.size());
|
||||
FilterIds.reserve(FilterIds.size() + TyIds.size() + 1);
|
||||
FilterIds.insert(FilterIds.end(), TyIds.begin(), TyIds.end());
|
||||
FilterEnds.push_back(FilterIds.size());
|
||||
FilterIds.push_back(0); // terminator
|
||||
return FilterID;
|
||||
}
|
||||
|
||||
MachineFunction &MachineModuleInfo::getMachineFunction(const Function &F) {
|
||||
// Shortcut for the common case where a sequence of MachineFunctionPasses
|
||||
@ -334,3 +502,33 @@ void llvm::computeUsesVAFloatArgument(const CallInst &I,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void llvm::addLandingPadInfo(const LandingPadInst &I, MachineModuleInfo &MMI,
|
||||
MachineBasicBlock &MBB) {
|
||||
if (const auto *PF = dyn_cast<Function>(
|
||||
I.getParent()->getParent()->getPersonalityFn()->stripPointerCasts()))
|
||||
MMI.addPersonality(PF);
|
||||
|
||||
if (I.isCleanup())
|
||||
MMI.addCleanup(&MBB);
|
||||
|
||||
// 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 = I.getNumClauses(); i != 0; --i) {
|
||||
Value *Val = I.getClause(i - 1);
|
||||
if (I.isCatch(i - 1)) {
|
||||
MMI.addCatchTypeInfo(&MBB,
|
||||
dyn_cast<GlobalValue>(Val->stripPointerCasts()));
|
||||
} else {
|
||||
// Add filters in a list.
|
||||
Constant *CVal = cast<Constant>(Val);
|
||||
SmallVector<const GlobalValue *, 4> FilterList;
|
||||
for (User::op_iterator II = CVal->op_begin(), IE = CVal->op_end();
|
||||
II != IE; ++II)
|
||||
FilterList.push_back(cast<GlobalValue>((*II)->stripPointerCasts()));
|
||||
|
||||
MMI.addFilterTypeInfo(&MBB, FilterList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -261,7 +261,7 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
|
||||
// FIXME: SEH catchpads do not create funclets, so we could avoid setting
|
||||
// this in such cases in order to improve frame layout.
|
||||
if (!isa<LandingPadInst>(I)) {
|
||||
MF->setHasEHFunclets(true);
|
||||
MMI.setHasEHFunclets(true);
|
||||
MF->getFrameInfo().setHasOpaqueSPAdjustment(true);
|
||||
}
|
||||
if (isa<CatchSwitchInst>(I)) {
|
||||
|
@ -2293,7 +2293,8 @@ void SelectionDAGBuilder::visitLandingPad(const LandingPadInst &LP) {
|
||||
"Call to landingpad not in landing pad!");
|
||||
|
||||
MachineBasicBlock *MBB = FuncInfo.MBB;
|
||||
addLandingPadInfo(LP, *MBB);
|
||||
MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
|
||||
addLandingPadInfo(LP, MMI, *MBB);
|
||||
|
||||
// If there aren't registers to copy the values into (e.g., during SjLj
|
||||
// exceptions), then don't bother to create these DAG nodes.
|
||||
@ -5026,7 +5027,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
|
||||
case Intrinsic::eh_typeid_for: {
|
||||
// Find the type id for the given typeinfo.
|
||||
GlobalValue *GV = ExtractTypeInfo(I.getArgOperand(0));
|
||||
unsigned TypeID = DAG.getMachineFunction().getTypeIDFor(GV);
|
||||
unsigned TypeID = DAG.getMachineFunction().getMMI().getTypeIDFor(GV);
|
||||
Res = DAG.getConstant(TypeID, sdl, MVT::i32);
|
||||
setValue(&I, Res);
|
||||
return nullptr;
|
||||
@ -5034,7 +5035,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
|
||||
|
||||
case Intrinsic::eh_return_i32:
|
||||
case Intrinsic::eh_return_i64:
|
||||
DAG.getMachineFunction().setCallsEHReturn(true);
|
||||
DAG.getMachineFunction().getMMI().setCallsEHReturn(true);
|
||||
DAG.setRoot(DAG.getNode(ISD::EH_RETURN, sdl,
|
||||
MVT::Other,
|
||||
getControlRoot(),
|
||||
@ -5042,7 +5043,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
|
||||
getValue(I.getArgOperand(1))));
|
||||
return nullptr;
|
||||
case Intrinsic::eh_unwind_init:
|
||||
DAG.getMachineFunction().setCallsUnwindInit(true);
|
||||
DAG.getMachineFunction().getMMI().setCallsUnwindInit(true);
|
||||
return nullptr;
|
||||
case Intrinsic::eh_dwarf_cfa: {
|
||||
setValue(&I, DAG.getNode(ISD::EH_DWARF_CFA, sdl,
|
||||
@ -5740,8 +5741,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
|
||||
std::pair<SDValue, SDValue>
|
||||
SelectionDAGBuilder::lowerInvokable(TargetLowering::CallLoweringInfo &CLI,
|
||||
const BasicBlock *EHPadBB) {
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
MachineModuleInfo &MMI = MF.getMMI();
|
||||
MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
|
||||
MCSymbol *BeginLabel = nullptr;
|
||||
|
||||
if (EHPadBB) {
|
||||
@ -5753,7 +5753,7 @@ SelectionDAGBuilder::lowerInvokable(TargetLowering::CallLoweringInfo &CLI,
|
||||
// so as to maintain the ordering of pads in the LSDA.
|
||||
unsigned CallSiteIndex = MMI.getCurrentCallSite();
|
||||
if (CallSiteIndex) {
|
||||
MF.setCallSiteBeginLabel(BeginLabel, CallSiteIndex);
|
||||
MMI.setCallSiteBeginLabel(BeginLabel, CallSiteIndex);
|
||||
LPadToCallSiteMap[FuncInfo.MBBMap[EHPadBB]].push_back(CallSiteIndex);
|
||||
|
||||
// Now that the call site is handled, stop tracking it.
|
||||
@ -5794,13 +5794,13 @@ SelectionDAGBuilder::lowerInvokable(TargetLowering::CallLoweringInfo &CLI,
|
||||
DAG.setRoot(DAG.getEHLabel(getCurSDLoc(), getRoot(), EndLabel));
|
||||
|
||||
// Inform MachineModuleInfo of range.
|
||||
if (MF.hasEHFunclets()) {
|
||||
if (MMI.hasEHFunclets()) {
|
||||
assert(CLI.CS);
|
||||
WinEHFuncInfo *EHInfo = DAG.getMachineFunction().getWinEHFuncInfo();
|
||||
EHInfo->addIPToStateRange(cast<InvokeInst>(CLI.CS->getInstruction()),
|
||||
BeginLabel, EndLabel);
|
||||
} else {
|
||||
MF.addInvoke(FuncInfo.MBBMap[EHPadBB], BeginLabel, EndLabel);
|
||||
MMI.addInvoke(FuncInfo.MBBMap[EHPadBB], BeginLabel, EndLabel);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1014,10 +1014,10 @@ bool SelectionDAGISel::PrepareEHLandingPad() {
|
||||
|
||||
// Add a label to mark the beginning of the landing pad. Deletion of the
|
||||
// landing pad can thus be detected via the MachineModuleInfo.
|
||||
MCSymbol *Label = MF->addLandingPad(MBB);
|
||||
MCSymbol *Label = MF->getMMI().addLandingPad(MBB);
|
||||
|
||||
// Assign the call site to the landing pad's begin label.
|
||||
MF->setCallSiteLandingPad(Label, SDB->LPadToCallSiteMap[MBB]);
|
||||
MF->getMMI().setCallSiteLandingPad(Label, SDB->LPadToCallSiteMap[MBB]);
|
||||
|
||||
const MCInstrDesc &II = TII->get(TargetOpcode::EH_LABEL);
|
||||
BuildMI(*MBB, FuncInfo->InsertPt, SDB->getCurDebugLoc(), II)
|
||||
|
@ -84,7 +84,7 @@ void TargetFrameLowering::determineCalleeSaves(MachineFunction &MF,
|
||||
return;
|
||||
|
||||
// Functions which call __builtin_unwind_init get all their registers saved.
|
||||
bool CallsUnwindInit = MF.callsUnwindInit();
|
||||
bool CallsUnwindInit = MF.getMMI().callsUnwindInit();
|
||||
const MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
for (unsigned i = 0; CSRegs[i]; ++i) {
|
||||
unsigned Reg = CSRegs[i];
|
||||
|
@ -7867,6 +7867,7 @@ void ARMTargetLowering::EmitSjLjDispatchBlock(MachineInstr &MI,
|
||||
// associated with.
|
||||
DenseMap<unsigned, SmallVector<MachineBasicBlock*, 2> > CallSiteNumToLPad;
|
||||
unsigned MaxCSNum = 0;
|
||||
MachineModuleInfo &MMI = MF->getMMI();
|
||||
for (MachineFunction::iterator BB = MF->begin(), E = MF->end(); BB != E;
|
||||
++BB) {
|
||||
if (!BB->isEHPad()) continue;
|
||||
@ -7878,9 +7879,9 @@ void ARMTargetLowering::EmitSjLjDispatchBlock(MachineInstr &MI,
|
||||
if (!II->isEHLabel()) continue;
|
||||
|
||||
MCSymbol *Sym = II->getOperand(0).getMCSymbol();
|
||||
if (!MF->hasCallSiteLandingPad(Sym)) continue;
|
||||
if (!MMI.hasCallSiteLandingPad(Sym)) continue;
|
||||
|
||||
SmallVectorImpl<unsigned> &CallSiteIdxs = MF->getCallSiteLandingPad(Sym);
|
||||
SmallVectorImpl<unsigned> &CallSiteIdxs = MMI.getCallSiteLandingPad(Sym);
|
||||
for (SmallVectorImpl<unsigned>::iterator
|
||||
CSI = CallSiteIdxs.begin(), CSE = CallSiteIdxs.end();
|
||||
CSI != CSE; ++CSI) {
|
||||
|
@ -82,7 +82,7 @@ void SystemZFrameLowering::determineCalleeSaves(MachineFunction &MF,
|
||||
SavedRegs.set(SystemZ::ArgGPRs[I]);
|
||||
|
||||
// If there are any landing pads, entering them will modify r6/r7.
|
||||
if (!MF.getLandingPads().empty()) {
|
||||
if (!MF.getMMI().getLandingPads().empty()) {
|
||||
SavedRegs.set(SystemZ::R6D);
|
||||
SavedRegs.set(SystemZ::R7D);
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ bool X86CallFrameOptimization::isLegal(MachineFunction &MF) {
|
||||
// in the compact unwind encoding that Darwin uses. So, bail if there
|
||||
// is a danger of that being generated.
|
||||
if (STI->isTargetDarwin() &&
|
||||
(!MF.getLandingPads().empty() ||
|
||||
(!MF.getMMI().getLandingPads().empty() ||
|
||||
(MF.getFunction()->needsUnwindTableEntry() && !TFL->hasFP(MF))))
|
||||
return false;
|
||||
|
||||
|
@ -83,12 +83,14 @@ X86FrameLowering::needsFrameIndexResolution(const MachineFunction &MF) const {
|
||||
/// or if frame pointer elimination is disabled.
|
||||
bool X86FrameLowering::hasFP(const MachineFunction &MF) const {
|
||||
const MachineFrameInfo &MFI = MF.getFrameInfo();
|
||||
const MachineModuleInfo &MMI = MF.getMMI();
|
||||
|
||||
return (MF.getTarget().Options.DisableFramePointerElim(MF) ||
|
||||
TRI->needsStackRealignment(MF) ||
|
||||
MFI.hasVarSizedObjects() ||
|
||||
MFI.isFrameAddressTaken() || MFI.hasOpaqueSPAdjustment() ||
|
||||
MF.getInfo<X86MachineFunctionInfo>()->getForceFramePointer() ||
|
||||
MF.callsUnwindInit() || MF.hasEHFunclets() || MF.callsEHReturn() ||
|
||||
MMI.callsUnwindInit() || MMI.hasEHFunclets() || MMI.callsEHReturn() ||
|
||||
MFI.hasStackMap() || MFI.hasPatchPoint() ||
|
||||
MFI.hasCopyImplyingStackAdjustment());
|
||||
}
|
||||
@ -149,7 +151,7 @@ static unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB,
|
||||
bool Is64Bit) {
|
||||
const MachineFunction *MF = MBB.getParent();
|
||||
const Function *F = MF->getFunction();
|
||||
if (!F || MF->callsEHReturn())
|
||||
if (!F || MF->getMMI().callsEHReturn())
|
||||
return 0;
|
||||
|
||||
const TargetRegisterClass &AvailableRegs = *TRI->getGPRsForTailCall(*MF);
|
||||
@ -917,7 +919,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
|
||||
if (Fn->hasPersonalityFn())
|
||||
Personality = classifyEHPersonality(Fn->getPersonalityFn());
|
||||
bool FnHasClrFunclet =
|
||||
MF.hasEHFunclets() && Personality == EHPersonality::CoreCLR;
|
||||
MMI.hasEHFunclets() && Personality == EHPersonality::CoreCLR;
|
||||
bool IsClrFunclet = IsFunclet && FnHasClrFunclet;
|
||||
bool HasFP = hasFP(MF);
|
||||
bool IsWin64CC = STI.isCallingConvWin64(Fn->getCallingConv());
|
||||
@ -2038,7 +2040,7 @@ void X86FrameLowering::determineCalleeSaves(MachineFunction &MF,
|
||||
SavedRegs.set(TRI->getBaseRegister());
|
||||
|
||||
// Allocate a spill slot for EBP if we have a base pointer and EH funclets.
|
||||
if (MF.hasEHFunclets()) {
|
||||
if (MF.getMMI().hasEHFunclets()) {
|
||||
int FI = MFI.CreateSpillStackObject(SlotSize, SlotSize);
|
||||
X86FI->setHasSEHFramePtrSave(true);
|
||||
X86FI->setSEHFramePtrSaveIndex(FI);
|
||||
@ -2608,7 +2610,8 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
|
||||
// GNU_ARGS_SIZE.
|
||||
// TODO: We don't need to reset this between subsequent functions,
|
||||
// if it didn't change.
|
||||
bool HasDwarfEHHandlers = !WindowsCFI && !MF.getLandingPads().empty();
|
||||
bool HasDwarfEHHandlers = !WindowsCFI &&
|
||||
!MF.getMMI().getLandingPads().empty();
|
||||
|
||||
if (HasDwarfEHHandlers && !isDestroy &&
|
||||
MF.getInfo<X86MachineFunctionInfo>()->getHasPushSequences())
|
||||
@ -2946,7 +2949,7 @@ void X86FrameLowering::processFunctionBeforeFrameFinalized(
|
||||
// If this function isn't doing Win64-style C++ EH, we don't need to do
|
||||
// anything.
|
||||
const Function *Fn = MF.getFunction();
|
||||
if (!STI.is64Bit() || !MF.hasEHFunclets() ||
|
||||
if (!STI.is64Bit() || !MF.getMMI().hasEHFunclets() ||
|
||||
classifyEHPersonality(Fn->getPersonalityFn()) != EHPersonality::MSVC_CXX)
|
||||
return;
|
||||
|
||||
|
@ -24980,6 +24980,7 @@ X86TargetLowering::EmitSjLjDispatchBlock(MachineInstr &MI,
|
||||
MachineBasicBlock *BB) const {
|
||||
DebugLoc DL = MI.getDebugLoc();
|
||||
MachineFunction *MF = BB->getParent();
|
||||
MachineModuleInfo *MMI = &MF->getMMI();
|
||||
MachineFrameInfo &MFI = MF->getFrameInfo();
|
||||
MachineRegisterInfo *MRI = &MF->getRegInfo();
|
||||
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
|
||||
@ -25003,10 +25004,10 @@ X86TargetLowering::EmitSjLjDispatchBlock(MachineInstr &MI,
|
||||
break;
|
||||
}
|
||||
|
||||
if (!MF->hasCallSiteLandingPad(Sym))
|
||||
if (!MMI->hasCallSiteLandingPad(Sym))
|
||||
continue;
|
||||
|
||||
for (unsigned CSI : MF->getCallSiteLandingPad(Sym)) {
|
||||
for (unsigned CSI : MMI->getCallSiteLandingPad(Sym)) {
|
||||
CallSiteNumToLPad[CSI].push_back(&MBB);
|
||||
MaxCSNum = std::max(MaxCSNum, CSI);
|
||||
}
|
||||
|
@ -270,7 +270,7 @@ X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
|
||||
bool HasSSE = Subtarget.hasSSE1();
|
||||
bool HasAVX = Subtarget.hasAVX();
|
||||
bool HasAVX512 = Subtarget.hasAVX512();
|
||||
bool CallsEHReturn = MF->callsEHReturn();
|
||||
bool CallsEHReturn = MF->getMMI().callsEHReturn();
|
||||
|
||||
switch (MF->getFunction()->getCallingConv()) {
|
||||
case CallingConv::GHC:
|
||||
|
@ -548,7 +548,7 @@ void XCoreFrameLowering::determineCalleeSaves(MachineFunction &MF,
|
||||
// We force the LR to be saved so these instructions are used.
|
||||
LRUsed = true;
|
||||
|
||||
if (MF.callsUnwindInit() || MF.callsEHReturn()) {
|
||||
if (MF.getMMI().callsUnwindInit() || MF.getMMI().callsEHReturn()) {
|
||||
// The unwinder expects to find spill slots for the exception info regs R0
|
||||
// & R1. These are used during llvm.eh.return() to 'restore' the exception
|
||||
// info. N.B. we do not spill or restore R0, R1 during normal operation.
|
||||
|
Loading…
Reference in New Issue
Block a user