Skip to content

Commit

Permalink
[WinEH] Move WinEHFuncInfo from MachineModuleInfo to MachineFunction
Browse files Browse the repository at this point in the history
Summary:
Now that there is a one-to-one mapping from MachineFunction to
WinEHFuncInfo, we don't need to use a DenseMap to select the right
WinEHFuncInfo for the current funclet.

The main challenge here is that X86WinEHStatePass is an IR pass that
doesn't have access to the MachineFunction. I gave it its own
WinEHFuncInfo object that it uses to calculate state numbers, which it
then throws away. As long as nobody creates or removes EH pads between
this pass and SDAG construction, we will get the same state numbers.

The other thing X86WinEHStatePass does is to mark the EH registration
node. Instead of communicating which alloca was the registration through
WinEHFuncInfo, I added the llvm.x86.seh.ehregnode intrinsic.  This
intrinsic generates no code and simply marks the alloca in use.

Reviewers: JCTremoulet

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D14668

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253378 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
rnk committed Nov 17, 2015
1 parent e6878eb commit 595419d
Show file tree
Hide file tree
Showing 15 changed files with 120 additions and 193 deletions.
11 changes: 11 additions & 0 deletions include/llvm/CodeGen/MachineFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class TargetMachine;
class TargetSubtargetInfo;
class TargetRegisterClass;
struct MachinePointerInfo;
struct WinEHFuncInfo;

template <>
struct ilist_traits<MachineBasicBlock>
Expand Down Expand Up @@ -107,6 +108,10 @@ class MachineFunction {
// Keep track of jump tables for switch instructions
MachineJumpTableInfo *JumpTableInfo;

// Keeps track of Windows exception handling related data. This will be null
// for functions that aren't using a funclet-based EH personality.
WinEHFuncInfo *WinEHInfo = nullptr;

// Function-level unique numbering for MachineBasicBlocks. When a
// MachineBasicBlock is inserted into a MachineFunction is it automatically
// numbered and this vector keeps track of the mapping from ID's to MBB's.
Expand Down Expand Up @@ -221,6 +226,12 @@ class MachineFunction {
MachineConstantPool *getConstantPool() { return ConstantPool; }
const MachineConstantPool *getConstantPool() const { return ConstantPool; }

/// getWinEHFuncInfo - Return information about how the current function uses
/// Windows exception handling. Returns null for functions that don't use
/// funclets for exception handling.
const WinEHFuncInfo *getWinEHFuncInfo() const { return WinEHInfo; }
WinEHFuncInfo *getWinEHFuncInfo() { return WinEHInfo; }

/// getAlignment - Return the alignment (log2, not bytes) of the function.
///
unsigned getAlignment() const { return Alignment; }
Expand Down
14 changes: 1 addition & 13 deletions include/llvm/CodeGen/MachineModuleInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ class MachineFunction;
class Module;
class PointerType;
class StructType;
struct WinEHFuncInfo;

struct SEHHandler {
// Filter or finally function. Null indicates a catch-all.
Expand All @@ -80,11 +79,9 @@ struct LandingPadInfo {
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).
int WinEHState; // WinEH specific state number.

explicit LandingPadInfo(MachineBasicBlock *MBB)
: LandingPadBlock(MBB), LandingPadLabel(nullptr),
WinEHState(-1) {}
: LandingPadBlock(MBB), LandingPadLabel(nullptr) {}
};

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -182,8 +179,6 @@ class MachineModuleInfo : public ImmutablePass {

EHPersonality PersonalityTypeCache;

DenseMap<const Function *, std::unique_ptr<WinEHFuncInfo>> FuncInfoMap;

public:
static char ID; // Pass identification, replacement for typeid

Expand Down Expand Up @@ -220,11 +215,6 @@ class MachineModuleInfo : public ImmutablePass {
void setModule(const Module *M) { TheModule = M; }
const Module *getModule() const { return TheModule; }

WinEHFuncInfo &getWinEHFuncInfo(const Function *F);
bool hasWinEHFuncInfo(const Function *F) const {
return FuncInfoMap.count(F) > 0;
}

/// getInfo - Keep track of various per-function pieces of information for
/// backends that would like to do so.
///
Expand Down Expand Up @@ -327,8 +317,6 @@ class MachineModuleInfo : public ImmutablePass {
/// information.
void addPersonality(const Function *Personality);

void addWinEHState(MachineBasicBlock *LandingPad, int State);

/// getPersonalities - Return array of personality functions ever seen.
const std::vector<const Function *>& getPersonalities() const {
return Personalities;
Expand Down
8 changes: 2 additions & 6 deletions include/llvm/CodeGen/WinEHFuncInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ struct SEHUnwindMapEntry {

struct WinEHHandlerType {
int Adjectives;
/// The CatchObj starts out life as an LLVM alloca, is turned into a frame
/// index, and after PEI, becomes a raw offset.
/// The CatchObj starts out life as an LLVM alloca and is eventually turned
/// frame index.
union {
const AllocaInst *Alloca;
int FrameIndex;
Expand Down Expand Up @@ -103,10 +103,6 @@ struct WinEHFuncInfo {
void addIPToStateRange(const BasicBlock *PadBB, MCSymbol *InvokeBegin,
MCSymbol *InvokeEnd);

/// 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;
int EHRegNodeEndOffset = INT_MAX;

Expand Down
3 changes: 3 additions & 0 deletions include/llvm/IR/IntrinsicsX86.td
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
let TargetPrefix = "x86" in {
def int_x86_seh_lsda : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty], [IntrNoMem]>;

// Marks the EH registration node created in LLVM IR prior to code generation.
def int_x86_seh_ehregnode : Intrinsic<[], [llvm_ptr_ty], []>;

// Restores the frame, base, and stack pointers as necessary after recovering
// from an exception. Any block resuming control flow in the parent function
// should call this before accessing any stack memory.
Expand Down
54 changes: 27 additions & 27 deletions lib/CodeGen/AsmPrinter/WinException.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,8 @@ const MCExpr *WinException::getOffsetPlusOne(const MCSymbol *OffsetOf,
Asm->OutContext);
}

int WinException::getFrameIndexOffset(int FrameIndex, WinEHFuncInfo &FuncInfo) {
int WinException::getFrameIndexOffset(int FrameIndex,
const WinEHFuncInfo &FuncInfo) {
const TargetFrameLowering &TFI = *Asm->MF->getSubtarget().getFrameLowering();
unsigned UnusedReg;
if (Asm->MAI->usesWindowsCFI())
Expand Down Expand Up @@ -340,7 +341,7 @@ struct InvokeStateChange {
/// reported is the first change to something other than NullState, and a
/// change back to NullState is always reported at the end of iteration).
class InvokeStateChangeIterator {
InvokeStateChangeIterator(WinEHFuncInfo &EHInfo,
InvokeStateChangeIterator(const WinEHFuncInfo &EHInfo,
MachineFunction::const_iterator MFI,
MachineFunction::const_iterator MFE,
MachineBasicBlock::const_iterator MBBI)
Expand All @@ -353,7 +354,7 @@ class InvokeStateChangeIterator {

public:
static iterator_range<InvokeStateChangeIterator>
range(WinEHFuncInfo &EHInfo, const MachineFunction &MF) {
range(const WinEHFuncInfo &EHInfo, const MachineFunction &MF) {
// Reject empty MFs to simplify bookkeeping by ensuring that we can get the
// end of the last block.
assert(!MF.empty());
Expand All @@ -366,7 +367,7 @@ class InvokeStateChangeIterator {
InvokeStateChangeIterator(EHInfo, FuncEnd, FuncEnd, BlockEnd));
}
static iterator_range<InvokeStateChangeIterator>
range(WinEHFuncInfo &EHInfo, MachineFunction::const_iterator Begin,
range(const WinEHFuncInfo &EHInfo, MachineFunction::const_iterator Begin,
MachineFunction::const_iterator End) {
// Reject empty ranges to simplify bookkeeping by ensuring that we can get
// the end of the last block.
Expand Down Expand Up @@ -402,7 +403,7 @@ class InvokeStateChangeIterator {
private:
InvokeStateChangeIterator &scan();

WinEHFuncInfo &EHInfo;
const WinEHFuncInfo &EHInfo;
const MCSymbol *CurrentEndLabel = nullptr;
MachineFunction::const_iterator MFI;
MachineFunction::const_iterator MFE;
Expand Down Expand Up @@ -521,7 +522,7 @@ void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) {
auto &OS = *Asm->OutStreamer;
MCContext &Ctx = Asm->OutContext;

WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(MF->getFunction());
const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
// Use the assembler to compute the number of table entries through label
// difference and division.
MCSymbol *TableBegin =
Expand Down Expand Up @@ -564,15 +565,15 @@ void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) {
OS.EmitLabel(TableEnd);
}

void WinException::emitSEHActionsForRange(WinEHFuncInfo &FuncInfo,
void WinException::emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo,
const MCSymbol *BeginLabel,
const MCSymbol *EndLabel, int State) {
auto &OS = *Asm->OutStreamer;
MCContext &Ctx = Asm->OutContext;

assert(BeginLabel && EndLabel);
while (State != -1) {
SEHUnwindMapEntry &UME = FuncInfo.SEHUnwindMap[State];
const SEHUnwindMapEntry &UME = FuncInfo.SEHUnwindMap[State];
const MCExpr *FilterOrFinally;
const MCExpr *ExceptOrNull;
auto *Handler = UME.Handler.get<MachineBasicBlock *>();
Expand Down Expand Up @@ -600,7 +601,7 @@ void WinException::emitSEHActionsForRange(WinEHFuncInfo &FuncInfo,
void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
const Function *F = MF->getFunction();
auto &OS = *Asm->OutStreamer;
WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(F);
const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();

StringRef FuncLinkageName = GlobalValue::getRealLinkageName(F->getName());

Expand Down Expand Up @@ -688,7 +689,7 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
OS.EmitLabel(TryBlockMapXData);
SmallVector<MCSymbol *, 1> HandlerMaps;
for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
const WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];

MCSymbol *HandlerMapXData = nullptr;
if (!TBME.HandlerArray.empty())
Expand Down Expand Up @@ -721,7 +722,7 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
}

for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
const WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
MCSymbol *HandlerMapXData = HandlerMaps[I];
if (!HandlerMapXData)
continue;
Expand Down Expand Up @@ -772,7 +773,7 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
}

void WinException::computeIP2StateTable(
const MachineFunction *MF, WinEHFuncInfo &FuncInfo,
const MachineFunction *MF, const WinEHFuncInfo &FuncInfo,
SmallVectorImpl<std::pair<const MCExpr *, int>> &IPToStateTable) {
// Indicate that all calls from the prologue to the first invoke unwind to
// caller. We handle this as a special case since other ranges starting at end
Expand Down Expand Up @@ -803,15 +804,15 @@ void WinException::emitEHRegistrationOffsetLabel(const WinEHFuncInfo &FuncInfo,
// registration in order to recover the parent frame pointer. Now that we know
// we've code generated the parent, we can emit the label assignment that
// those helpers use to get the offset of the registration node.
assert(FuncInfo.EHRegNodeEscapeIndex != INT_MAX &&
"no EH reg node localescape index");
MCContext &Ctx = Asm->OutContext;
MCSymbol *ParentFrameOffset =
Asm->OutContext.getOrCreateParentFrameOffsetSymbol(FLinkageName);
MCSymbol *RegistrationOffsetSym = Asm->OutContext.getOrCreateFrameAllocSymbol(
FLinkageName, FuncInfo.EHRegNodeEscapeIndex);
const MCExpr *RegistrationOffsetSymRef =
MCSymbolRefExpr::create(RegistrationOffsetSym, Asm->OutContext);
Asm->OutStreamer->EmitAssignment(ParentFrameOffset, RegistrationOffsetSymRef);
Ctx.getOrCreateParentFrameOffsetSymbol(FLinkageName);
unsigned UnusedReg;
const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
int64_t Offset = TFI->getFrameIndexReference(
*Asm->MF, FuncInfo.EHRegNodeFrameIndex, UnusedReg);
const MCExpr *MCOffset = MCConstantExpr::create(Offset, Ctx);
Asm->OutStreamer->EmitAssignment(ParentFrameOffset, MCOffset);
}

/// Emit the language-specific data that _except_handler3 and 4 expect. This is
Expand All @@ -822,7 +823,7 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
const Function *F = MF->getFunction();
StringRef FLinkageName = GlobalValue::getRealLinkageName(F->getName());

WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(F);
const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName);

// Emit the __ehtable label that we use for llvm.x86.seh.lsda.
Expand Down Expand Up @@ -857,7 +858,7 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
}

assert(!FuncInfo.SEHUnwindMap.empty());
for (SEHUnwindMapEntry &UME : FuncInfo.SEHUnwindMap) {
for (const SEHUnwindMapEntry &UME : FuncInfo.SEHUnwindMap) {
MCSymbol *ExceptOrFinally =
UME.Handler.get<MachineBasicBlock *>()->getSymbol();
// -1 is usually the base state for "unwind to caller", but for
Expand All @@ -869,7 +870,7 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
}
}

static int getRank(WinEHFuncInfo &FuncInfo, int State) {
static int getRank(const WinEHFuncInfo &FuncInfo, int State) {
int Rank = 0;
while (State != -1) {
++Rank;
Expand All @@ -878,7 +879,7 @@ static int getRank(WinEHFuncInfo &FuncInfo, int State) {
return Rank;
}

static int getAncestor(WinEHFuncInfo &FuncInfo, int Left, int Right) {
static int getAncestor(const WinEHFuncInfo &FuncInfo, int Left, int Right) {
int LeftRank = getRank(FuncInfo, Left);
int RightRank = getRank(FuncInfo, Right);

Expand All @@ -905,8 +906,7 @@ void WinException::emitCLRExceptionTable(const MachineFunction *MF) {
// states, handlers, and funclets all have 1:1 mappings between them, and a
// handler/funclet's "state" is its index in the ClrEHUnwindMap.
MCStreamer &OS = *Asm->OutStreamer;
const Function *F = MF->getFunction();
WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(F);
const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
MCSymbol *FuncBeginSym = Asm->getFunctionBegin();
MCSymbol *FuncEndSym = Asm->getFunctionEnd();

Expand Down Expand Up @@ -1085,7 +1085,7 @@ void WinException::emitCLRExceptionTable(const MachineFunction *MF) {
getOffsetPlusOne(Clause.StartLabel, FuncBeginSym);
const MCExpr *ClauseEnd = getOffsetPlusOne(Clause.EndLabel, FuncBeginSym);

ClrEHUnwindMapEntry &Entry = FuncInfo.ClrEHUnwindMap[Clause.State];
const ClrEHUnwindMapEntry &Entry = FuncInfo.ClrEHUnwindMap[Clause.State];
MachineBasicBlock *HandlerBlock = Entry.Handler.get<MachineBasicBlock *>();
MCSymbol *BeginSym = getMCSymbolForMBB(Asm, HandlerBlock);
const MCExpr *HandlerBegin = getOffset(BeginSym, FuncBeginSym);
Expand Down
6 changes: 3 additions & 3 deletions lib/CodeGen/AsmPrinter/WinException.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer {

void emitCSpecificHandlerTable(const MachineFunction *MF);

void emitSEHActionsForRange(WinEHFuncInfo &FuncInfo,
void emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo,
const MCSymbol *BeginLabel,
const MCSymbol *EndLabel, int State);

Expand All @@ -58,7 +58,7 @@ class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer {
void emitCLRExceptionTable(const MachineFunction *MF);

void computeIP2StateTable(
const MachineFunction *MF, WinEHFuncInfo &FuncInfo,
const MachineFunction *MF, const WinEHFuncInfo &FuncInfo,
SmallVectorImpl<std::pair<const MCExpr *, int>> &IPToStateTable);

/// Emits the label used with llvm.x86.seh.recoverfp, which is used by
Expand All @@ -77,7 +77,7 @@ class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer {
/// given index. For targets using CFI (Win64, etc), this is relative to the
/// established SP at the end of the prologue. For targets without CFI (Win32
/// only), it is relative to the frame pointer.
int getFrameIndexOffset(int FrameIndex, WinEHFuncInfo &FuncInfo);
int getFrameIndexOffset(int FrameIndex, const WinEHFuncInfo &FuncInfo);

public:
//===--------------------------------------------------------------------===//
Expand Down
12 changes: 12 additions & 0 deletions lib/CodeGen/MachineFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/LibCallSemantics.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunctionInitializer.h"
Expand All @@ -27,6 +28,7 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/WinEHFuncInfo.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/Function.h"
Expand Down Expand Up @@ -88,6 +90,11 @@ MachineFunction::MachineFunction(const Function *F, const TargetMachine &TM,
FunctionNumber = FunctionNum;
JumpTableInfo = nullptr;

if (isFuncletEHPersonality(classifyEHPersonality(
F->hasPersonalityFn() ? F->getPersonalityFn() : nullptr))) {
WinEHInfo = new (Allocator) WinEHFuncInfo();
}

assert(TM.isCompatibleDataLayout(getDataLayout()) &&
"Can't create a MachineFunction using a Module with a "
"Target-incompatible DataLayout attached\n");
Expand Down Expand Up @@ -125,6 +132,11 @@ MachineFunction::~MachineFunction() {
JumpTableInfo->~MachineJumpTableInfo();
Allocator.Deallocate(JumpTableInfo);
}

if (WinEHInfo) {
WinEHInfo->~WinEHFuncInfo();
Allocator.Deallocate(WinEHInfo);
}
}

const DataLayout &MachineFunction::getDataLayout() const {
Expand Down
Loading

0 comments on commit 595419d

Please sign in to comment.