|
@@ -35,6 +35,7 @@
|
|
#include "llvm/ADT/PointerIntPair.h"
|
|
#include "llvm/ADT/PointerIntPair.h"
|
|
#include "llvm/ADT/SmallPtrSet.h"
|
|
#include "llvm/ADT/SmallPtrSet.h"
|
|
#include "llvm/ADT/SmallVector.h"
|
|
#include "llvm/ADT/SmallVector.h"
|
|
|
|
+#include "llvm/Analysis/EHPersonalities.h"
|
|
#include "llvm/IR/DebugLoc.h"
|
|
#include "llvm/IR/DebugLoc.h"
|
|
#include "llvm/IR/ValueHandle.h"
|
|
#include "llvm/IR/ValueHandle.h"
|
|
#include "llvm/MC/MCContext.h"
|
|
#include "llvm/MC/MCContext.h"
|
|
@@ -61,6 +62,29 @@ class Module;
|
|
class PointerType;
|
|
class PointerType;
|
|
class StructType;
|
|
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
|
|
/// This class can be derived from and used by targets to hold private
|
|
/// target-specific information for each Module. Objects of type are
|
|
/// target-specific information for each Module. Objects of type are
|
|
@@ -98,22 +122,41 @@ class MachineModuleInfo : public ImmutablePass {
|
|
/// want.
|
|
/// want.
|
|
MachineModuleInfoImpl *ObjFileMMI;
|
|
MachineModuleInfoImpl *ObjFileMMI;
|
|
|
|
|
|
- /// \name Exception Handling
|
|
|
|
- /// \{
|
|
|
|
|
|
+ /// List of LandingPadInfo describing the landing pad information in the
|
|
|
|
+ /// current function.
|
|
|
|
+ std::vector<LandingPadInfo> LandingPads;
|
|
|
|
|
|
- /// Vector of all personality functions ever seen. Used to emit common EH
|
|
|
|
- /// frames.
|
|
|
|
- std::vector<const Function *> Personalities;
|
|
|
|
|
|
+ /// 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.
|
|
/// The current call site index being processed, if any. 0 if none.
|
|
unsigned CurCallSite;
|
|
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;
|
|
|
|
|
|
/// This map keeps track of which symbol is being used for the specified
|
|
/// This map keeps track of which symbol is being used for the specified
|
|
/// basic block's address of label.
|
|
/// basic block's address of label.
|
|
MMIAddrLabelMap *AddrLabelSymbols;
|
|
MMIAddrLabelMap *AddrLabelSymbols;
|
|
|
|
|
|
|
|
+ bool CallsEHReturn;
|
|
|
|
+ bool CallsUnwindInit;
|
|
|
|
+ bool HasEHFunclets;
|
|
|
|
+
|
|
// TODO: Ideally, what we'd like is to have a switch that allows emitting
|
|
// 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,
|
|
// 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.
|
|
// 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.
|
|
/// comments in lib/Target/X86/X86FrameLowering.cpp for more details.
|
|
bool UsesMorestackAddr;
|
|
bool UsesMorestackAddr;
|
|
|
|
|
|
|
|
+ EHPersonality PersonalityTypeCache;
|
|
|
|
+
|
|
MachineFunctionInitializer *MFInitializer;
|
|
MachineFunctionInitializer *MFInitializer;
|
|
/// Maps IR Functions to their corresponding MachineFunctions.
|
|
/// Maps IR Functions to their corresponding MachineFunctions.
|
|
DenseMap<const Function*, std::unique_ptr<MachineFunction>> MachineFunctions;
|
|
DenseMap<const Function*, std::unique_ptr<MachineFunction>> MachineFunctions;
|
|
@@ -152,6 +197,9 @@ public:
|
|
bool doInitialization(Module &) override;
|
|
bool doInitialization(Module &) override;
|
|
bool doFinalization(Module &) override;
|
|
bool doFinalization(Module &) override;
|
|
|
|
|
|
|
|
+ /// Discard function meta information.
|
|
|
|
+ void EndFunction();
|
|
|
|
+
|
|
const MCContext &getContext() const { return Context; }
|
|
const MCContext &getContext() const { return Context; }
|
|
MCContext &getContext() { return Context; }
|
|
MCContext &getContext() { return Context; }
|
|
|
|
|
|
@@ -189,6 +237,15 @@ public:
|
|
bool hasDebugInfo() const { return DbgInfoAvailable; }
|
|
bool hasDebugInfo() const { return DbgInfoAvailable; }
|
|
void setDebugInfoAvailability(bool avail) { DbgInfoAvailable = avail; }
|
|
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 {
|
|
bool usesVAFloatArgument() const {
|
|
return UsesVAFloatArgument;
|
|
return UsesVAFloatArgument;
|
|
}
|
|
}
|
|
@@ -224,15 +281,19 @@ public:
|
|
void takeDeletedSymbolsForFunction(const Function *F,
|
|
void takeDeletedSymbolsForFunction(const Function *F,
|
|
std::vector<MCSymbol*> &Result);
|
|
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.
|
|
/// Provide the personality function for the exception information.
|
|
void addPersonality(const Function *Personality);
|
|
void addPersonality(const Function *Personality);
|
|
@@ -241,7 +302,87 @@ public:
|
|
const std::vector<const Function *>& getPersonalities() const {
|
|
const std::vector<const Function *>& getPersonalities() const {
|
|
return Personalities;
|
|
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
|
|
}; // End class MachineModuleInfo
|
|
|
|
|
|
//===- MMI building helpers -----------------------------------------------===//
|
|
//===- MMI building helpers -----------------------------------------------===//
|
|
@@ -252,6 +393,12 @@ public:
|
|
/// which will link in MSVCRT's floating-point support.
|
|
/// which will link in MSVCRT's floating-point support.
|
|
void computeUsesVAFloatArgument(const CallInst &I, MachineModuleInfo &MMI);
|
|
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
|
|
} // End llvm namespace
|
|
|
|
|
|
#endif
|
|
#endif
|