mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-23 11:49:50 +00:00
Move most EH from MachineModuleInfo to MachineFunction
Most of the exception handling members in MachineModuleInfo is actually per function data (talks about the "current function") so it is better to keep it at the function instead of the module. This is a necessary step to have machine module passes work properly. Also: - Rename TidyLandingPads() to tidyLandingPads() - Use doxygen member groups instead of "//===- EH ---"... so it is clear where a group ends. - I had to add an ugly const_cast at two places in the AsmPrinter because the available MachineFunction pointers are const, but the code wants to call tidyLandingPads() in between (markFunctionEnd()/endFunction()). Differential Revision: https://reviews.llvm.org/D27227 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288293 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
40485c228c
commit
29c7b3a03e
@ -21,11 +21,13 @@
|
||||
#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"
|
||||
@ -170,6 +172,28 @@ 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;
|
||||
@ -250,6 +274,35 @@ 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;
|
||||
|
||||
@ -672,6 +725,105 @@ 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) {
|
||||
@ -684,6 +836,15 @@ 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,7 +35,6 @@
|
||||
#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"
|
||||
@ -62,29 +61,6 @@ 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
|
||||
@ -122,41 +98,22 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
/// want.
|
||||
MachineModuleInfoImpl *ObjFileMMI;
|
||||
|
||||
/// 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;
|
||||
/// \name Exception Handling
|
||||
/// \{
|
||||
|
||||
/// 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.
|
||||
@ -177,8 +134,6 @@ 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;
|
||||
@ -197,9 +152,6 @@ 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; }
|
||||
|
||||
@ -237,15 +189,6 @@ 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;
|
||||
}
|
||||
@ -281,90 +224,8 @@ public:
|
||||
void takeDeletedSymbolsForFunction(const Function *F,
|
||||
std::vector<MCSymbol*> &Result);
|
||||
|
||||
|
||||
//===- EH ---------------------------------------------------------------===//
|
||||
|
||||
/// 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);
|
||||
|
||||
/// Return array of personality functions ever seen.
|
||||
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;
|
||||
}
|
||||
/// \name Exception Handling
|
||||
/// \{
|
||||
|
||||
/// Set the call site currently being processed.
|
||||
void setCurrentCallSite(unsigned Site) { CurCallSite = Site; }
|
||||
@ -373,16 +234,14 @@ public:
|
||||
/// 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;
|
||||
}
|
||||
/// Provide the personality function for the exception information.
|
||||
void addPersonality(const Function *Personality);
|
||||
|
||||
/// Return a reference to the typeids encoding filters used in the current
|
||||
/// function.
|
||||
const std::vector<unsigned> &getFilterIds() const {
|
||||
return FilterIds;
|
||||
/// Return array of personality functions ever seen.
|
||||
const std::vector<const Function *>& getPersonalities() const {
|
||||
return Personalities;
|
||||
}
|
||||
/// \}
|
||||
}; // End class MachineModuleInfo
|
||||
|
||||
//===- MMI building helpers -----------------------------------------------===//
|
||||
@ -393,12 +252,6 @@ 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.getMMI().hasEHFunclets())
|
||||
if (!MF.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 ||
|
||||
!MMI->getLandingPads().empty();
|
||||
!MF->getLandingPads().empty();
|
||||
if (!Asm->MF->getFunction()->needsUnwindTableEntry() &&
|
||||
!shouldEmitPersonality)
|
||||
ATS.emitCantUnwind();
|
||||
@ -99,8 +99,9 @@ void ARMException::endFunction(const MachineFunction *MF) {
|
||||
}
|
||||
|
||||
void ARMException::emitTypeInfos(unsigned TTypeEncoding) {
|
||||
const std::vector<const GlobalValue *> &TypeInfos = MMI->getTypeInfos();
|
||||
const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
|
||||
const MachineFunction *MF = Asm->MF;
|
||||
const std::vector<const GlobalValue *> &TypeInfos = MF->getTypeInfos();
|
||||
const std::vector<unsigned> &FilterIds = MF->getFilterIds();
|
||||
|
||||
bool VerboseAsm = Asm->OutStreamer->isVerboseAsm();
|
||||
|
||||
|
@ -947,8 +947,8 @@ void AsmPrinter::EmitFunctionBody() {
|
||||
// Emit target-specific gunk after the function body.
|
||||
EmitFunctionBodyEnd();
|
||||
|
||||
if (!MMI->getLandingPads().empty() || MMI->hasDebugInfo() ||
|
||||
MMI->hasEHFunclets() || MAI->hasDotTypeDotSizeDirective()) {
|
||||
if (!MF->getLandingPads().empty() || MMI->hasDebugInfo() ||
|
||||
MF->hasEHFunclets() || MAI->hasDotTypeDotSizeDirective()) {
|
||||
// Create a symbol for the end of function.
|
||||
CurrentFnEnd = createTempSymbol("func_end");
|
||||
OutStreamer->EmitLabel(CurrentFnEnd);
|
||||
@ -981,7 +981,6 @@ void AsmPrinter::EmitFunctionBody() {
|
||||
HI.TimerGroupDescription, TimePassesIsEnabled);
|
||||
HI.Handler->endFunction(MF);
|
||||
}
|
||||
MMI->EndFunction();
|
||||
|
||||
OutStreamer->AddBlankLine();
|
||||
}
|
||||
@ -1273,8 +1272,8 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
|
||||
CurrentFnBegin = nullptr;
|
||||
CurExceptionSym = nullptr;
|
||||
bool NeedsLocalForSize = MAI->needsLocalForSize();
|
||||
if (!MMI->getLandingPads().empty() || MMI->hasDebugInfo() ||
|
||||
MMI->hasEHFunclets() || NeedsLocalForSize) {
|
||||
if (!MF.getLandingPads().empty() || MMI->hasDebugInfo() ||
|
||||
MF.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.
|
||||
MMI->TidyLandingPads();
|
||||
if (!Asm->MF->getLandingPads().empty()) {
|
||||
MachineFunction *NonConstMF = const_cast<MachineFunction*>(Asm->MF);
|
||||
NonConstMF->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 = !MMI->getLandingPads().empty();
|
||||
bool hasLandingPads = !MF->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 *) {
|
||||
void DwarfCFIException::endFunction(const MachineFunction *MF) {
|
||||
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 = MMI->getFilterIds();
|
||||
const std::vector<unsigned> &FilterIds = Asm->MF->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 = MMI->getCallSiteBeginLabel(BeginLabel);
|
||||
unsigned SiteNo = Asm->MF->getCallSiteBeginLabel(BeginLabel);
|
||||
if (CallSites.size() < SiteNo)
|
||||
CallSites.resize(SiteNo);
|
||||
CallSites[SiteNo - 1] = Site;
|
||||
@ -336,9 +336,10 @@ 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 std::vector<const GlobalValue *> &TypeInfos = MMI->getTypeInfos();
|
||||
const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
|
||||
const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
|
||||
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();
|
||||
|
||||
// Sort the landing pads in order of their type ids. This is used to fold
|
||||
// duplicate actions.
|
||||
@ -649,8 +650,9 @@ void EHStreamer::emitExceptionTable() {
|
||||
}
|
||||
|
||||
void EHStreamer::emitTypeInfos(unsigned TTypeEncoding) {
|
||||
const std::vector<const GlobalValue *> &TypeInfos = MMI->getTypeInfos();
|
||||
const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
|
||||
const MachineFunction *MF = Asm->MF;
|
||||
const std::vector<const GlobalValue *> &TypeInfos = MF->getTypeInfos();
|
||||
const std::vector<unsigned> &FilterIds = MF->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 = !MMI->getLandingPads().empty();
|
||||
bool hasEHFunclets = MMI->hasEHFunclets();
|
||||
bool hasLandingPads = !MF->getLandingPads().empty();
|
||||
bool hasEHFunclets = MF->hasEHFunclets();
|
||||
|
||||
const Function *F = MF->getFunction();
|
||||
|
||||
@ -126,13 +126,15 @@ 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))
|
||||
MMI->TidyLandingPads();
|
||||
if (!isFuncletEHPersonality(Per)) {
|
||||
MachineFunction *NonConstMF = const_cast<MachineFunction*>(MF);
|
||||
NonConstMF->tidyLandingPads();
|
||||
}
|
||||
|
||||
endFunclet();
|
||||
|
||||
// endFunclet will emit the necessary .xdata tables for x64 SEH.
|
||||
if (Per == EHPersonality::MSVC_Win64SEH && MMI->hasEHFunclets())
|
||||
if (Per == EHPersonality::MSVC_Win64SEH && MF->hasEHFunclets())
|
||||
return;
|
||||
|
||||
if (shouldEmitPersonality || shouldEmitLSDA) {
|
||||
@ -234,8 +236,9 @@ void WinException::endFunclet() {
|
||||
if (!CurrentFuncletEntry)
|
||||
return;
|
||||
|
||||
const MachineFunction *MF = Asm->MF;
|
||||
if (shouldEmitMoves || shouldEmitPersonality) {
|
||||
const Function *F = Asm->MF->getFunction();
|
||||
const Function *F = MF->getFunction();
|
||||
EHPersonality Per = EHPersonality::Unknown;
|
||||
if (F->hasPersonalityFn())
|
||||
Per = classifyEHPersonality(F->getPersonalityFn()->stripPointerCasts());
|
||||
@ -255,11 +258,11 @@ void WinException::endFunclet() {
|
||||
MCSymbol *FuncInfoXData = Asm->OutContext.getOrCreateSymbol(
|
||||
Twine("$cppxdata$", FuncLinkageName));
|
||||
Asm->OutStreamer->EmitValue(create32bitRef(FuncInfoXData), 4);
|
||||
} else if (Per == EHPersonality::MSVC_Win64SEH && MMI->hasEHFunclets() &&
|
||||
} else if (Per == EHPersonality::MSVC_Win64SEH && MF->hasEHFunclets() &&
|
||||
!CurrentFuncletEntry->isEHFuncletEntry()) {
|
||||
// If this is the parent function in Win64 SEH, emit the LSDA immediately
|
||||
// following .seh_handlerdata.
|
||||
emitCSpecificHandlerTable(Asm->MF);
|
||||
emitCSpecificHandlerTable(MF);
|
||||
}
|
||||
|
||||
// Switch back to the previous section now that we are done writing to
|
||||
|
@ -568,6 +568,193 @@ 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,11 +203,7 @@ 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;
|
||||
|
||||
@ -229,19 +225,6 @@ 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 *>
|
||||
@ -261,34 +244,8 @@ takeDeletedSymbolsForFunction(const Function *F,
|
||||
takeDeletedSymbolsForFunction(const_cast<Function*>(F), Result);
|
||||
}
|
||||
|
||||
//===- 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;
|
||||
}
|
||||
/// \name Exception Handling
|
||||
/// \{
|
||||
|
||||
void MachineModuleInfo::addPersonality(const Function *Personality) {
|
||||
for (unsigned i = 0; i < Personalities.size(); ++i)
|
||||
@ -297,132 +254,7 @@ 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
|
||||
@ -502,33 +334,3 @@ 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)) {
|
||||
MMI.setHasEHFunclets(true);
|
||||
MF->setHasEHFunclets(true);
|
||||
MF->getFrameInfo().setHasOpaqueSPAdjustment(true);
|
||||
}
|
||||
if (isa<CatchSwitchInst>(I)) {
|
||||
|
@ -2293,8 +2293,7 @@ void SelectionDAGBuilder::visitLandingPad(const LandingPadInst &LP) {
|
||||
"Call to landingpad not in landing pad!");
|
||||
|
||||
MachineBasicBlock *MBB = FuncInfo.MBB;
|
||||
MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
|
||||
addLandingPadInfo(LP, MMI, *MBB);
|
||||
addLandingPadInfo(LP, *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.
|
||||
@ -5027,7 +5026,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().getMMI().getTypeIDFor(GV);
|
||||
unsigned TypeID = DAG.getMachineFunction().getTypeIDFor(GV);
|
||||
Res = DAG.getConstant(TypeID, sdl, MVT::i32);
|
||||
setValue(&I, Res);
|
||||
return nullptr;
|
||||
@ -5035,7 +5034,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
|
||||
|
||||
case Intrinsic::eh_return_i32:
|
||||
case Intrinsic::eh_return_i64:
|
||||
DAG.getMachineFunction().getMMI().setCallsEHReturn(true);
|
||||
DAG.getMachineFunction().setCallsEHReturn(true);
|
||||
DAG.setRoot(DAG.getNode(ISD::EH_RETURN, sdl,
|
||||
MVT::Other,
|
||||
getControlRoot(),
|
||||
@ -5043,7 +5042,7 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
|
||||
getValue(I.getArgOperand(1))));
|
||||
return nullptr;
|
||||
case Intrinsic::eh_unwind_init:
|
||||
DAG.getMachineFunction().getMMI().setCallsUnwindInit(true);
|
||||
DAG.getMachineFunction().setCallsUnwindInit(true);
|
||||
return nullptr;
|
||||
case Intrinsic::eh_dwarf_cfa: {
|
||||
setValue(&I, DAG.getNode(ISD::EH_DWARF_CFA, sdl,
|
||||
@ -5741,7 +5740,8 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
|
||||
std::pair<SDValue, SDValue>
|
||||
SelectionDAGBuilder::lowerInvokable(TargetLowering::CallLoweringInfo &CLI,
|
||||
const BasicBlock *EHPadBB) {
|
||||
MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
MachineModuleInfo &MMI = MF.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) {
|
||||
MMI.setCallSiteBeginLabel(BeginLabel, CallSiteIndex);
|
||||
MF.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 (MMI.hasEHFunclets()) {
|
||||
if (MF.hasEHFunclets()) {
|
||||
assert(CLI.CS);
|
||||
WinEHFuncInfo *EHInfo = DAG.getMachineFunction().getWinEHFuncInfo();
|
||||
EHInfo->addIPToStateRange(cast<InvokeInst>(CLI.CS->getInstruction()),
|
||||
BeginLabel, EndLabel);
|
||||
} else {
|
||||
MMI.addInvoke(FuncInfo.MBBMap[EHPadBB], BeginLabel, EndLabel);
|
||||
MF.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->getMMI().addLandingPad(MBB);
|
||||
MCSymbol *Label = MF->addLandingPad(MBB);
|
||||
|
||||
// Assign the call site to the landing pad's begin label.
|
||||
MF->getMMI().setCallSiteLandingPad(Label, SDB->LPadToCallSiteMap[MBB]);
|
||||
MF->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.getMMI().callsUnwindInit();
|
||||
bool CallsUnwindInit = MF.callsUnwindInit();
|
||||
const MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
for (unsigned i = 0; CSRegs[i]; ++i) {
|
||||
unsigned Reg = CSRegs[i];
|
||||
|
@ -7867,7 +7867,6 @@ 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;
|
||||
@ -7879,9 +7878,9 @@ void ARMTargetLowering::EmitSjLjDispatchBlock(MachineInstr &MI,
|
||||
if (!II->isEHLabel()) continue;
|
||||
|
||||
MCSymbol *Sym = II->getOperand(0).getMCSymbol();
|
||||
if (!MMI.hasCallSiteLandingPad(Sym)) continue;
|
||||
if (!MF->hasCallSiteLandingPad(Sym)) continue;
|
||||
|
||||
SmallVectorImpl<unsigned> &CallSiteIdxs = MMI.getCallSiteLandingPad(Sym);
|
||||
SmallVectorImpl<unsigned> &CallSiteIdxs = MF->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.getMMI().getLandingPads().empty()) {
|
||||
if (!MF.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.getMMI().getLandingPads().empty() ||
|
||||
(!MF.getLandingPads().empty() ||
|
||||
(MF.getFunction()->needsUnwindTableEntry() && !TFL->hasFP(MF))))
|
||||
return false;
|
||||
|
||||
|
@ -83,14 +83,12 @@ 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() ||
|
||||
MMI.callsUnwindInit() || MMI.hasEHFunclets() || MMI.callsEHReturn() ||
|
||||
MF.callsUnwindInit() || MF.hasEHFunclets() || MF.callsEHReturn() ||
|
||||
MFI.hasStackMap() || MFI.hasPatchPoint() ||
|
||||
MFI.hasCopyImplyingStackAdjustment());
|
||||
}
|
||||
@ -151,7 +149,7 @@ static unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB,
|
||||
bool Is64Bit) {
|
||||
const MachineFunction *MF = MBB.getParent();
|
||||
const Function *F = MF->getFunction();
|
||||
if (!F || MF->getMMI().callsEHReturn())
|
||||
if (!F || MF->callsEHReturn())
|
||||
return 0;
|
||||
|
||||
const TargetRegisterClass &AvailableRegs = *TRI->getGPRsForTailCall(*MF);
|
||||
@ -919,7 +917,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
|
||||
if (Fn->hasPersonalityFn())
|
||||
Personality = classifyEHPersonality(Fn->getPersonalityFn());
|
||||
bool FnHasClrFunclet =
|
||||
MMI.hasEHFunclets() && Personality == EHPersonality::CoreCLR;
|
||||
MF.hasEHFunclets() && Personality == EHPersonality::CoreCLR;
|
||||
bool IsClrFunclet = IsFunclet && FnHasClrFunclet;
|
||||
bool HasFP = hasFP(MF);
|
||||
bool IsWin64CC = STI.isCallingConvWin64(Fn->getCallingConv());
|
||||
@ -2040,7 +2038,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.getMMI().hasEHFunclets()) {
|
||||
if (MF.hasEHFunclets()) {
|
||||
int FI = MFI.CreateSpillStackObject(SlotSize, SlotSize);
|
||||
X86FI->setHasSEHFramePtrSave(true);
|
||||
X86FI->setSEHFramePtrSaveIndex(FI);
|
||||
@ -2610,8 +2608,7 @@ 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.getMMI().getLandingPads().empty();
|
||||
bool HasDwarfEHHandlers = !WindowsCFI && !MF.getLandingPads().empty();
|
||||
|
||||
if (HasDwarfEHHandlers && !isDestroy &&
|
||||
MF.getInfo<X86MachineFunctionInfo>()->getHasPushSequences())
|
||||
@ -2949,7 +2946,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.getMMI().hasEHFunclets() ||
|
||||
if (!STI.is64Bit() || !MF.hasEHFunclets() ||
|
||||
classifyEHPersonality(Fn->getPersonalityFn()) != EHPersonality::MSVC_CXX)
|
||||
return;
|
||||
|
||||
|
@ -24980,7 +24980,6 @@ 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();
|
||||
@ -25004,10 +25003,10 @@ X86TargetLowering::EmitSjLjDispatchBlock(MachineInstr &MI,
|
||||
break;
|
||||
}
|
||||
|
||||
if (!MMI->hasCallSiteLandingPad(Sym))
|
||||
if (!MF->hasCallSiteLandingPad(Sym))
|
||||
continue;
|
||||
|
||||
for (unsigned CSI : MMI->getCallSiteLandingPad(Sym)) {
|
||||
for (unsigned CSI : MF->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->getMMI().callsEHReturn();
|
||||
bool CallsEHReturn = MF->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.getMMI().callsUnwindInit() || MF.getMMI().callsEHReturn()) {
|
||||
if (MF.callsUnwindInit() || MF.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