#ifndef LLVM_CODEGEN_WINEHFUNCINFO_H
#define LLVM_CODEGEN_WINEHFUNCINFO_H
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/TinyPtrVector.h"
-#include "llvm/ADT/DenseMap.h"
namespace llvm {
+class AllocaInst;
class BasicBlock;
class Constant;
class Function;
-class GlobalValue;
+class GlobalVariable;
+class InvokeInst;
class IntrinsicInst;
class LandingPadInst;
class MCSymbol;
+class MachineBasicBlock;
class Value;
enum ActionType { Catch, Cleanup };
void setExceptionVar(const Value *Val) { ExceptionObjectVar = Val; }
void setExceptionVarIndex(int Index) { ExceptionObjectIndex = Index; }
+ int getExceptionVarIndex() const { return ExceptionObjectIndex; }
void setReturnTargets(TinyPtrVector<BasicBlock *> &Targets) {
ReturnTargets = Targets;
}
// When the parseEHActions function is called to populate a vector of
// instances of this class, the ExceptionObjectVar field will be nullptr
// and the ExceptionObjectIndex will be the index of the exception object in
- // the parent function's frameescape block.
+ // the parent function's localescape block.
const Value *ExceptionObjectVar;
int ExceptionObjectIndex;
TinyPtrVector<BasicBlock *> ReturnTargets;
};
void parseEHActions(const IntrinsicInst *II,
- SmallVectorImpl<ActionHandler *> &Actions);
-
+ SmallVectorImpl<std::unique_ptr<ActionHandler>> &Actions);
// The following structs respresent the .xdata for functions using C++
// exceptions on Windows.
+typedef PointerUnion<const BasicBlock *, MachineBasicBlock *> MBBOrBasicBlock;
+typedef PointerUnion<const Value *, MachineBasicBlock *> ValueOrMBB;
+
struct WinEHUnwindMapEntry {
int ToState;
- Function *Cleanup;
+ ValueOrMBB Cleanup;
+};
+
+/// Similar to WinEHUnwindMapEntry, but supports SEH filters.
+struct SEHUnwindMapEntry {
+ /// If unwinding continues through this handler, transition to the handler at
+ /// this state. This indexes into SEHUnwindMap.
+ int ToState = -1;
+
+ /// Holds the filter expression function.
+ const Function *Filter = nullptr;
+
+ /// Holds the __except or __finally basic block.
+ MBBOrBasicBlock Handler;
};
struct WinEHHandlerType {
int Adjectives;
GlobalVariable *TypeDescriptor;
- int CatchObjIdx;
- int CatchObjOffset;
- Function *Handler;
+ int CatchObjRecoverIdx;
+ ValueOrMBB Handler;
};
struct WinEHTryBlockMapEntry {
- int TryLow;
- int TryHigh;
- int CatchHigh;
+ int TryLow = -1;
+ int TryHigh = -1;
+ int CatchHigh = -1;
SmallVector<WinEHHandlerType, 1> HandlerArray;
};
struct WinEHFuncInfo {
- DenseMap<const LandingPadInst *, int> LandingPadStateMap;
+ DenseMap<const Function *, const LandingPadInst *> RootLPad;
+ DenseMap<const Function *, const InvokeInst *> LastInvoke;
+ DenseMap<const Function *, int> HandlerEnclosedState;
+ DenseMap<const Function *, bool> LastInvokeVisited;
+ DenseMap<const Instruction *, int> EHPadStateMap;
DenseMap<const Function *, int> CatchHandlerParentFrameObjIdx;
DenseMap<const Function *, int> CatchHandlerParentFrameObjOffset;
+ DenseMap<const Function *, int> CatchHandlerMaxState;
+ DenseMap<const Function *, int> HandlerBaseState;
SmallVector<WinEHUnwindMapEntry, 4> UnwindMap;
SmallVector<WinEHTryBlockMapEntry, 4> TryBlockMap;
+ SmallVector<SEHUnwindMapEntry, 4> SEHUnwindMap;
SmallVector<std::pair<MCSymbol *, int>, 4> IPToStateList;
- int UnwindHelpFrameIdx;
- int UnwindHelpFrameOffset;
+ int UnwindHelpFrameIdx = INT_MAX;
+ int UnwindHelpFrameOffset = -1;
+ unsigned NumIPToStateFuncsVisited = 0;
+
+ int getLastStateNumber() const { return UnwindMap.size() - 1; }
- WinEHFuncInfo() : UnwindHelpFrameIdx(INT_MAX), UnwindHelpFrameOffset(-1) {}
+ /// localescape index of the 32-bit EH registration node. Set by
+ /// WinEHStatePass and used indirectly by SEH filter functions of the parent.
+ int EHRegNodeEscapeIndex = INT_MAX;
+ const AllocaInst *EHRegNode = nullptr;
+ int EHRegNodeFrameIndex = INT_MAX;
+
+ WinEHFuncInfo() {}
};
+/// Analyze the IR in ParentFn and it's handlers to build WinEHFuncInfo, which
+/// describes the state numbers and tables used by __CxxFrameHandler3. This
+/// analysis assumes that WinEHPrepare has already been run.
+void calculateWinCXXEHStateNumbers(const Function *ParentFn,
+ WinEHFuncInfo &FuncInfo);
+
+void calculateSEHStateNumbers(const Function *ParentFn,
+ WinEHFuncInfo &FuncInfo);
}
#endif // LLVM_CODEGEN_WINEHFUNCINFO_H