41 #define DEBUG_TYPE "x86-vzeroupper" 43 STATISTIC(NumVZU,
"Number of vzeroupper instructions inserted");
58 StringRef getPassName()
const override {
return "X86 vzeroupper inserter"; }
66 using BlockExitState =
enum { PASS_THROUGH, EXITS_CLEAN, EXITS_DIRTY };
68 static const char* getBlockExitStateName(BlockExitState
ST);
89 BlockExitState ExitState = PASS_THROUGH;
90 bool AddedToDirtySuccessors =
false;
93 BlockState() =
default;
99 BlockStateMap BlockStates;
100 DirtySuccessorsWorkList DirtySuccessors;
113 return new VZeroUpperInserter();
117 const char* VZeroUpperInserter::getBlockExitStateName(BlockExitState
ST) {
119 case PASS_THROUGH:
return "Pass-through";
120 case EXITS_DIRTY:
return "Exits-dirty";
121 case EXITS_CLEAN:
return "Exits-clean";
130 return (Reg >= X86::YMM0 && Reg <= X86::YMM15) ||
131 (Reg >= X86::ZMM0 && Reg <= X86::ZMM15);
135 for (std::pair<unsigned, unsigned> LI : MRI.
liveins())
143 for (
unsigned reg = X86::YMM0; reg <= X86::YMM15; ++reg) {
147 for (
unsigned reg = X86::ZMM0; reg <= X86::ZMM15; ++reg) {
170 assert(MI.
isCall() &&
"Can only be called on call instructions.");
182 BuildMI(MBB, I, dl,
TII->get(X86::VZEROUPPER));
184 EverMadeChange =
true;
189 if (!BlockStates[MBB.
getNumber()].AddedToDirtySuccessors) {
190 DirtySuccessors.push_back(&MBB);
191 BlockStates[MBB.
getNumber()].AddedToDirtySuccessors =
true;
200 BlockExitState CurState = PASS_THROUGH;
201 BlockStates[MBB.
getNumber()].FirstUnguardedCall = MBB.
end();
204 bool IsCall =
MI.isCall();
205 bool IsReturn =
MI.isReturn();
206 bool IsControlFlow = IsCall || IsReturn;
210 if (IsX86INTR && IsReturn)
214 if (
MI.getOpcode() == X86::VZEROALL ||
MI.getOpcode() == X86::VZEROUPPER) {
215 CurState = EXITS_CLEAN;
220 if (!IsControlFlow && CurState == EXITS_DIRTY)
226 CurState = EXITS_DIRTY;
250 if (CurState == EXITS_DIRTY) {
254 insertVZeroUpper(
MI, MBB);
255 CurState = EXITS_CLEAN;
256 }
else if (CurState == PASS_THROUGH) {
262 BlockStates[MBB.getNumber()].FirstUnguardedCall =
MI;
263 CurState = EXITS_CLEAN;
267 LLVM_DEBUG(
dbgs() <<
"MBB #" << MBB.getNumber() <<
" exit state: " 268 << getBlockExitStateName(CurState) <<
'\n');
270 if (CurState == EXITS_DIRTY)
274 addDirtySuccessor(**
SI);
276 BlockStates[MBB.getNumber()].ExitState = CurState;
287 EverMadeChange =
false;
295 bool YmmOrZmmUsed = FnHasLiveInYmmOrZmm;
297 for (
auto *RC : RCs) {
312 assert(BlockStates.empty() && DirtySuccessors.empty() &&
313 "X86VZeroUpper state should be clear");
320 processBasicBlock(MBB);
324 if (FnHasLiveInYmmOrZmm)
325 addDirtySuccessor(MF.front());
330 while (!DirtySuccessors.empty()) {
332 DirtySuccessors.pop_back();
333 BlockState &BBState = BlockStates[MBB.
getNumber()];
337 if (BBState.FirstUnguardedCall != MBB.
end())
338 insertVZeroUpper(BBState.FirstUnguardedCall, MBB);
343 if (BBState.ExitState == PASS_THROUGH) {
345 <<
" was Pass-through, is now Dirty-out.\n");
347 addDirtySuccessor(*Succ);
352 return EverMadeChange;
bool reg_nodbg_empty(unsigned RegNo) const
reg_nodbg_empty - Return true if the only instructions using or defining Reg are Debug instructions...
bool isCall(QueryType Type=AnyInBundle) const
This class represents lattice values for constants.
static bool hasYmmOrZmmReg(MachineInstr &MI)
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
static bool isYmmOrZmmReg(unsigned Reg)
VZEROUPPER cleans state that is related to Y/ZMM0-15 only.
const X86InstrInfo * getInstrInfo() const override
STATISTIC(NumFunctions, "Total number of functions")
FunctionPass * createX86IssueVZeroUpperPass()
This pass inserts AVX vzeroupper instructions before each call to avoid transition penalty between fu...
iterator_range< mop_iterator > operands()
iterator_range< succ_iterator > successors()
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
TargetInstrInfo - Interface to description of machine instruction set.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static bool callHasRegMask(MachineInstr &MI)
Check if given call instruction has a RegMask operand.
FunctionPass class - This class is used to implement most global optimizations.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool hasFastPartialYMMorZMMWrite() const
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static bool clobbersPhysReg(const uint32_t *RegMask, unsigned PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
ArrayRef< std::pair< unsigned, unsigned > > liveins() const
const MCPhysReg * iterator
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
MachineFunctionProperties & set(Property P)
Representation of each machine instruction.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
static bool checkFnHasLiveInYmmOrZmm(MachineRegisterInfo &MRI)
X86_INTR - x86 hardware interrupt context.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool clobbersAllYmmAndZmmRegs(const MachineOperand &MO)
StringRef - Represent a constant reference to a string, i.e.
std::vector< MachineBasicBlock * >::iterator succ_iterator
Properties which a MachineFunction may have at a given point in time.