38#define DEBUG_TYPE "x86-wineh-unwindv3"
41 "Number of functions processed by Unwind v3 pass");
43 "Number of sub-fragment splits inserted for Unwind v3");
58 switch (
MI.getOpcode()) {
59 case X86::SEH_PushReg:
60 case X86::SEH_Push2Regs:
61 case X86::SEH_SaveReg:
62 case X86::SEH_SaveXMM:
63 case X86::SEH_StackAlloc:
64 case X86::SEH_StackAlign:
65 case X86::SEH_SetFrame:
66 case X86::SEH_PushFrame:
67 case X86::SEH_EndPrologue:
68 case X86::SEH_BeginEpilogue:
69 case X86::SEH_EndEpilogue:
70 case X86::SEH_SplitChained:
71 case X86::SEH_SplitChainedAtEndOfBlock:
86 unsigned PrologOpCount = 0;
87 unsigned EpilogCount = 0;
88 unsigned MaxEpilogOpCount = 0;
90 SmallVector<MachineInstr *, 8> EpilogBegins;
97 X86WinEHUnwindV3() : MachineFunctionPass(ID) {
101 StringRef getPassName()
const override {
return "WinEH Unwind V3"; }
103 bool runOnMachineFunction(MachineFunction &MF)
override;
109 static FuncletInfo analyzeFunclet(MachineFunction &MF,
115char X86WinEHUnwindV3::ID = 0;
118 "Capacity check and sub-fragment splitting for Win64 Unwind v3",
122 return new X86WinEHUnwindV3();
128 bool InEpilog =
false;
129 bool SeenProlog =
false;
130 unsigned CurrentEpilogOpCount = 0;
132 for (; Iter != MF.
end(); ++Iter) {
133 MachineBasicBlock &
MBB = *Iter;
140 for (MachineInstr &
MI :
MBB) {
141 switch (
MI.getOpcode()) {
142 case X86::SEH_PushReg:
143 case X86::SEH_Push2Regs:
144 case X86::SEH_StackAlloc:
145 case X86::SEH_SetFrame:
146 case X86::SEH_SaveReg:
147 case X86::SEH_SaveXMM:
148 case X86::SEH_PushFrame:
150 CurrentEpilogOpCount++;
152 Info.PrologOpCount++;
154 case X86::SEH_EndPrologue:
157 case X86::SEH_BeginEpilogue:
159 CurrentEpilogOpCount = 0;
161 Info.EpilogBegins.push_back(&
MI);
163 case X86::SEH_EndEpilogue:
165 Info.MaxEpilogOpCount =
166 std::max(
Info.MaxEpilogOpCount, CurrentEpilogOpCount);
177bool X86WinEHUnwindV3::runOnMachineFunction(MachineFunction &MF) {
189 if (
Mode != WinX64EHUnwindMode::V3) {
190 if (!
F.needsUnwindTableEntry())
194 Ctx.
diagnose(DiagnosticInfoUnsupported(
195 F,
"EGPR (R16-R31) requires V3 unwind info on Windows x64"));
208 while (Iter != MF.
end()) {
209 FuncletInfo
Info = analyzeFunclet(MF, Iter);
212 Ctx.
diagnose(DiagnosticInfoResourceLimit(
213 F,
"number of unwind v3 prolog operations required",
215 Ctx.
diagnose(DiagnosticInfoGenericWithLoc(
216 "sub-fragment splitting for prolog overflow is not yet implemented",
224 Ctx.
diagnose(DiagnosticInfoResourceLimit(
225 F,
"number of unwind v3 epilog operations required",
227 Ctx.
diagnose(DiagnosticInfoGenericWithLoc(
228 "sub-fragment splitting for epilog overflow is not yet implemented",
238 for (MachineInstr *BeginEpilog :
Info.EpilogBegins) {
243 TII->get(X86::SEH_SplitChained));
245 TII->get(X86::SEH_EndPrologue));
255 FunctionsProcessed++;
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static constexpr unsigned MaxV3PrologOps
V3 limits from the format specification.
static constexpr unsigned MaxV3Epilogs
static constexpr unsigned MaxV3EpilogOps
static void suppressWinCFI(MachineFunction &MF)
After reporting a recoverable error for MF, erase all SEH pseudo- instructions and clear the WinCFI f...
FunctionPass class - This class is used to implement most global optimizations.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Module * getParent()
Get the module that this global value is contained inside of...
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
bool isEHFuncletEntry() const
Returns true if this is the entry block of an EH funclet.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void setHasWinCFI(bool v)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
WinX64EHUnwindMode getWinX64EHUnwindMode() const
Get how unwind information should be generated for x64 Windows.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual const TargetInstrInfo * getInstrInfo() const
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createX86WinEHUnwindV3Pass()
Capacity check and sub-fragment splitting for Win x64 Unwind V3.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
FunctionAddr VTableAddr Count
void initializeX86WinEHUnwindV3Pass(PassRegistry &)