void setModule(const Module *M) { TheModule = M; }
const Module *getModule() const { return TheModule; }
- const Function *getWinEHParent(const Function *F) const;
WinEHFuncInfo &getWinEHFuncInfo(const Function *F);
bool hasWinEHFuncInfo(const Function *F) const {
- return FuncInfoMap.count(getWinEHParent(F)) > 0;
+ return FuncInfoMap.count(F) > 0;
}
/// getInfo - Keep track of various per-function pieces of information for
// Windows-related EH personalities.
typedef PointerUnion<const BasicBlock *, MachineBasicBlock *> MBBOrBasicBlock;
-typedef PointerUnion<const Value *, const MachineBasicBlock *> ValueOrMBB;
struct CxxUnwindMapEntry {
int ToState;
- ValueOrMBB Cleanup;
+ MBBOrBasicBlock Cleanup;
};
/// Similar to CxxUnwindMapEntry, but supports SEH filters.
int FrameIndex;
} CatchObj = {};
GlobalVariable *TypeDescriptor;
- ValueOrMBB Handler;
+ MBBOrBasicBlock Handler;
};
struct WinEHTryBlockMapEntry {
bool hasEHFunclets = MMI->hasEHFunclets();
const Function *F = MF->getFunction();
- const Function *ParentF = MMI->getWinEHParent(F);
shouldEmitMoves = Asm->needsSEHMoves();
// If we're not using CFI, we don't want the CFI or the personality, but we
// might want EH tables if we had EH pads.
- // FIXME: If WinEHPrepare outlined something, we should emit the LSDA. Remove
- // this once WinEHPrepare stops doing that.
if (!Asm->MAI->usesWindowsCFI()) {
- shouldEmitLSDA =
- hasEHFunclets || (F->hasFnAttribute("wineh-parent") && F == ParentF);
+ shouldEmitLSDA = hasEHFunclets;
shouldEmitPersonality = false;
return;
}
/// Retreive the MCSymbol for a GlobalValue or MachineBasicBlock. GlobalValues
/// are used in the old WinEH scheme, and they will be removed eventually.
-static MCSymbol *getMCSymbolForMBBOrGV(AsmPrinter *Asm, ValueOrMBB Handler) {
- if (!Handler)
+static MCSymbol *getMCSymbolForMBB(AsmPrinter *Asm,
+ const MachineBasicBlock *MBB) {
+ if (!MBB)
return nullptr;
- if (Handler.is<const MachineBasicBlock *>()) {
- auto *MBB = Handler.get<const MachineBasicBlock *>();
- assert(MBB->isEHFuncletEntry());
-
- // Give catches and cleanups a name based off of their parent function and
- // their funclet entry block's number.
- const MachineFunction *MF = MBB->getParent();
- const Function *F = MF->getFunction();
- StringRef FuncLinkageName = GlobalValue::getRealLinkageName(F->getName());
- MCContext &Ctx = MF->getContext();
- StringRef HandlerPrefix = MBB->isCleanupFuncletEntry() ? "dtor" : "catch";
- return Ctx.getOrCreateSymbol("?" + HandlerPrefix + "$" +
- Twine(MBB->getNumber()) + "@?0?" +
- FuncLinkageName + "@4HA");
- }
- return Asm->getSymbol(cast<GlobalValue>(Handler.get<const Value *>()));
+
+ assert(MBB->isEHFuncletEntry());
+
+ // Give catches and cleanups a name based off of their parent function and
+ // their funclet entry block's number.
+ const MachineFunction *MF = MBB->getParent();
+ const Function *F = MF->getFunction();
+ StringRef FuncLinkageName = GlobalValue::getRealLinkageName(F->getName());
+ MCContext &Ctx = MF->getContext();
+ StringRef HandlerPrefix = MBB->isCleanupFuncletEntry() ? "dtor" : "catch";
+ return Ctx.getOrCreateSymbol("?" + HandlerPrefix + "$" +
+ Twine(MBB->getNumber()) + "@?0?" +
+ FuncLinkageName + "@4HA");
}
void WinException::beginFunclet(const MachineBasicBlock &MBB,
const Function *F = Asm->MF->getFunction();
// If a symbol was not provided for the funclet, invent one.
if (!Sym) {
- Sym = getMCSymbolForMBBOrGV(Asm, &MBB);
+ Sym = getMCSymbolForMBB(Asm, &MBB);
// Describe our funclet symbol as a function with internal linkage.
Asm->OutStreamer->BeginCOFFSymbolDef(Sym);
const MCExpr *ExceptOrNull;
auto *Handler = UME.Handler.get<MachineBasicBlock *>();
if (UME.IsFinally) {
- FilterOrFinally = create32bitRef(getMCSymbolForMBBOrGV(Asm, Handler));
+ FilterOrFinally = create32bitRef(getMCSymbolForMBB(Asm, Handler));
ExceptOrNull = MCConstantExpr::create(0, Ctx);
} else {
// For an except, the filter can be 1 (catch-all) or a function
if (UnwindMapXData) {
OS.EmitLabel(UnwindMapXData);
for (const CxxUnwindMapEntry &UME : FuncInfo.CxxUnwindMap) {
- MCSymbol *CleanupSym = getMCSymbolForMBBOrGV(Asm, UME.Cleanup);
+ MCSymbol *CleanupSym =
+ getMCSymbolForMBB(Asm, UME.Cleanup.dyn_cast<MachineBasicBlock *>());
OS.EmitIntValue(UME.ToState, 4); // ToState
OS.EmitValue(create32bitRef(CleanupSym), 4); // Action
}
FrameAllocOffsetRef = MCConstantExpr::create(0, Asm->OutContext);
}
- MCSymbol *HandlerSym = getMCSymbolForMBBOrGV(Asm, HT.Handler);
+ MCSymbol *HandlerSym =
+ getMCSymbolForMBB(Asm, HT.Handler.dyn_cast<MachineBasicBlock *>());
OS.EmitIntValue(HT.Adjectives, 4); // Adjectives
OS.EmitValue(create32bitRef(HT.TypeDescriptor), 4); // Type
return FilterID;
}
-const Function *MachineModuleInfo::getWinEHParent(const Function *F) const {
- StringRef WinEHParentName =
- F->getFnAttribute("wineh-parent").getValueAsString();
- if (WinEHParentName.empty() || WinEHParentName == F->getName())
- return F;
- return F->getParent()->getFunction(WinEHParentName);
-}
-
WinEHFuncInfo &MachineModuleInfo::getWinEHFuncInfo(const Function *F) {
- auto &Ptr = FuncInfoMap[getWinEHParent(F)];
+ auto &Ptr = FuncInfoMap[F];
if (!Ptr)
Ptr.reset(new WinEHFuncInfo);
return *Ptr;
// Calculate state numbers if we haven't already.
WinEHFuncInfo &EHInfo = MMI.getWinEHFuncInfo(&fn);
- const Function *WinEHParentFn = MMI.getWinEHParent(&fn);
if (Personality == EHPersonality::MSVC_CXX)
- calculateWinCXXEHStateNumbers(WinEHParentFn, EHInfo);
+ calculateWinCXXEHStateNumbers(&fn, EHInfo);
else if (isAsynchronousEHPersonality(Personality))
- calculateSEHStateNumbers(WinEHParentFn, EHInfo);
+ calculateSEHStateNumbers(&fn, EHInfo);
else if (Personality == EHPersonality::CoreCLR)
- calculateClrEHStateNumbers(WinEHParentFn, EHInfo);
+ calculateClrEHStateNumbers(&fn, EHInfo);
- calculateCatchReturnSuccessorColors(WinEHParentFn, EHInfo);
+ calculateCatchReturnSuccessorColors(&fn, EHInfo);
// Map all BB references in the WinEH data to MBBs.
for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap) {
} else {
H.CatchObj.FrameIndex = INT_MAX;
}
- if (const auto *BB = dyn_cast<BasicBlock>(H.Handler.get<const Value *>()))
- H.Handler = MBBMap[BB];
+ if (H.Handler)
+ H.Handler = MBBMap[H.Handler.get<const BasicBlock *>()];
}
}
for (CxxUnwindMapEntry &UME : EHInfo.CxxUnwindMap)
if (UME.Cleanup)
- if (const auto *BB = dyn_cast<BasicBlock>(UME.Cleanup.get<const Value *>()))
- UME.Cleanup = MBBMap[BB];
+ UME.Cleanup = MBBMap[UME.Cleanup.get<const BasicBlock *>()];
for (SEHUnwindMapEntry &UME : EHInfo.SEHUnwindMap) {
const BasicBlock *BB = UME.Handler.get<const BasicBlock *>();
UME.Handler = MBBMap[BB];
if (!Fn.hasPersonalityFn())
return false;
- // No need to prepare outlined handlers.
- if (Fn.hasFnAttribute("wineh-parent"))
- return false;
-
// Classify the personality to see what kind of preparation we need.
Personality = classifyEHPersonality(Fn.getPersonalityFn());
}
static int addUnwindMapEntry(WinEHFuncInfo &FuncInfo, int ToState,
- const Value *V) {
+ const BasicBlock *BB) {
CxxUnwindMapEntry UME;
UME.ToState = ToState;
- UME.Cleanup = V;
+ UME.Cleanup = BB;
FuncInfo.CxxUnwindMap.push_back(UME);
return FuncInfo.getLastStateNumber();
}
}
MachineModuleInfo &MMI = MF.getMMI();
- const Function *WinEHParent = nullptr;
- if (MMI.hasWinEHFuncInfo(Fn))
- WinEHParent = MMI.getWinEHParent(Fn);
- bool IsWinEHParent = WinEHParent && WinEHParent == Fn;
// Figure out if XMM registers are in use.
assert(!(Subtarget->useSoftFloat() &&
FuncInfo->setArgumentStackSize(StackSize);
- if (IsWinEHParent) {
+ if (MMI.hasWinEHFuncInfo(Fn)) {
if (Is64Bit) {
int UnwindHelpFI = MFI->CreateStackObject(8, 8, /*isSS=*/false);
SDValue StackSlot = DAG.getFrameIndex(UnwindHelpFI, MVT::i64);
}
bool WinEHStatePass::runOnFunction(Function &F) {
- // If this is an outlined handler, don't do anything. We'll do state insertion
- // for it in the parent.
- StringRef WinEHParentName =
- F.getFnAttribute("wineh-parent").getValueAsString();
- if (WinEHParentName != F.getName() && !WinEHParentName.empty())
- return false;
-
// Check the personality. Do nothing if this personality doesn't use funclets.
if (!F.hasPersonalityFn())
return false;
// Skip this function if there are no EH pads and we aren't using IR-level
// outlining.
- if (WinEHParentName.empty()) {
- bool HasPads = false;
- for (BasicBlock &BB : F) {
- if (BB.isEHPad()) {
- HasPads = true;
- break;
- }
+ bool HasPads = false;
+ for (BasicBlock &BB : F) {
+ if (BB.isEHPad()) {
+ HasPads = true;
+ break;
}
- if (!HasPads)
- return false;
}
+ if (!HasPads)
+ return false;
// Disable frame pointer elimination in this function.
// FIXME: Do the nested handlers need to keep the parent ebp in ebp, or can we