#include "X86.h"
#include "X86InstrInfo.h"
#include "X86Subtarget.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
usingnamespacellvm;
#define DEBUG_TYPE …
static cl::opt<bool>
UseVZeroUpper("x86-use-vzeroupper", cl::Hidden,
cl::desc("Minimize AVX to SSE transition penalty"),
cl::init(true));
STATISTIC(NumVZU, "Number of vzeroupper instructions inserted");
namespace {
class VZeroUpperInserter : public MachineFunctionPass { … };
}
char VZeroUpperInserter::ID = …;
FunctionPass *llvm::createX86IssueVZeroUpperPass() { … }
#ifndef NDEBUG
const char* VZeroUpperInserter::getBlockExitStateName(BlockExitState ST) {
switch (ST) {
case PASS_THROUGH: return "Pass-through";
case EXITS_DIRTY: return "Exits-dirty";
case EXITS_CLEAN: return "Exits-clean";
}
llvm_unreachable("Invalid block exit state.");
}
#endif
static bool isYmmOrZmmReg(unsigned Reg) { … }
static bool checkFnHasLiveInYmmOrZmm(MachineRegisterInfo &MRI) { … }
static bool clobbersAllYmmAndZmmRegs(const MachineOperand &MO) { … }
static bool hasYmmOrZmmReg(MachineInstr &MI) { … }
static bool callHasRegMask(MachineInstr &MI) { … }
void VZeroUpperInserter::insertVZeroUpper(MachineBasicBlock::iterator I,
MachineBasicBlock &MBB) { … }
void VZeroUpperInserter::addDirtySuccessor(MachineBasicBlock &MBB) { … }
void VZeroUpperInserter::processBasicBlock(MachineBasicBlock &MBB) { … }
bool VZeroUpperInserter::runOnMachineFunction(MachineFunction &MF) { … }