38#define DEBUG_TYPE "fastpretileconfig"
69 int getStackSpaceFor(
Register VirtReg);
70 void InitializeTileConfigStackSpace();
85 return "Fast Tile Register Preconfigure";
96char X86FastPreTileConfig::ID = 0;
99 "Fast Tile Register Preconfigure",
false,
false)
111 for (; &*
I !=
A && &*
I !=
B; ++
I)
119int X86FastPreTileConfig::getStackSpaceFor(
Register VirtReg) {
121 int SS = StackSlotForVirtReg[VirtReg];
128 unsigned Size =
TRI->getSpillSize(RC);
129 Align Alignment =
TRI->getSpillAlign(RC);
130 int FrameIdx = MFI->CreateSpillStackObject(
Size, Alignment);
133 StackSlotForVirtReg[VirtReg] = FrameIdx;
144 for (
const MachineInstr &UseInst :
MRI->use_nodbg_instructions(VirtReg)) {
145 if (UseInst.getParent() !=
MBB) {
164void X86FastPreTileConfig::InitializeTileConfigStackSpace() {
168 if (
ST->hasAVX512()) {
169 Register Zmm =
MRI->createVirtualRegister(&X86::VR512RegClass);
173 }
else if (
ST->hasAVX2()) {
174 Register Ymm =
MRI->createVirtualRegister(&X86::VR256RegClass);
182 assert(
ST->hasSSE2() &&
"AMX should assume SSE2 enabled");
183 unsigned StoreOpc =
ST->hasAVX() ? X86::VMOVUPSmr : X86::MOVUPSmr;
184 Register Xmm =
MRI->createVirtualRegister(&X86::VR128RegClass);
205 int FI = getStackSpaceFor(VirtReg);
222 int FI = getStackSpaceFor(OrigReg);
236 TileReg =
MRI->createVirtualRegister(&RC);
240 unsigned Opc = X86::PTILELOADDV;
241 Register StrideReg =
MRI->createVirtualRegister(&X86::GR64_NOSPRegClass);
244 TII->get(X86::MOV64ri), StrideReg)
274 if (
MI.isDebugInstr() ||
MI.getNumOperands() < 3 || !
MI.isPseudo())
282 if (Reg.isVirtual() &&
283 MRI->getRegClass(Reg)->getID() == X86::TILERegClassID)
285 if (Reg >= X86::TMM0 && Reg <= X86::TMM7)
298 }
else if (
MI->isCopy()) {
299 TileReg =
MI->getOperand(1).getReg();
305 assert(
MI->isPHI() &&
"Unexpected PHI when get shape.");
330 Register StackAddrReg =
MRI->createVirtualRegister(&X86::GR64_NOSPRegClass);
332 TII->get(X86::PHI), StackAddrReg);
333 Register RowReg =
MRI->createVirtualRegister(&X86::GR16RegClass);
335 TII->get(X86::PHI), RowReg);
336 Register ColReg =
MRI->createVirtualRegister(&X86::GR16RegClass);
338 TII->get(X86::PHI), ColReg);
340 VisitedPHIs[&
PHI] = {RowReg, ColReg, StackAddrReg};
342 for (
unsigned I = 1,
E =
PHI.getNumOperands();
I !=
E;
I += 2) {
353 if (TileDefMI->
isPHI()) {
355 if (VisitedPHIs.count(TileDefMI)) {
365 Register InRowReg = VisitedPHIs[TileDefMI].Row;
366 Register InColReg = VisitedPHIs[TileDefMI].Col;
367 Register InStackAddrReg = VisitedPHIs[TileDefMI].StackAddr;
374 convertPHI(TileDefMI->
getParent(), *TileDefMI);
398 int FI = getStackSpaceFor(InTileReg);
400 MRI->createVirtualRegister(&X86::GR64_NOSPRegClass);
402 TII->get(X86::LEA64r), InStackAddrReg)
410 Register StrideReg =
MRI->createVirtualRegister(&X86::GR64_NOSPRegClass);
422 PHI.eraseFromParent();
423 VisitedPHIs.erase(&
PHI);
429 MRI->getRegClass(MO.
getReg())->getID() == X86::TILERegClassID)
454 while (!PHIs.
empty()) {
461 for (
unsigned I = 1,
E =
PHI->getNumOperands();
I !=
E;
I += 2) {
468 InMO = &
PHI->getOperand(
I);
498 while (!PHIs.
empty()) {
501 convertPHI(&
MBB, *
MI);
512 bool HasUnconfigTile =
false;
516 CfgSS = MFI->CreateStackObject(
ST->getTileConfigSize(),
517 ST->getTileConfigAlignment(),
false);
520 LastShapeMI =
nullptr;
528 if (
Reg.isVirtual() &&
529 MRI->getRegClass(Reg)->getID() == X86::TILERegClassID)
550 if (HasTileOperand(
MRI,
MI))
551 HasUnconfigTile =
true;
554 if (
MI.isCall() && HasUnconfigTile) {
559 I = ++
MI.getIterator();
561 HasUnconfigTile =
false;
624 if (mayLiveOut(TileReg, LastTileCfg))
625 spill(++
MI.getIterator(), TileReg,
false);
632 reload(
UseMI.getIterator(), TileReg, RowMO, ColMO);
637 reload(
UseMI.getIterator(), TileReg, RowMO, ColMO);
643 if (HasUnconfigTile) {
645 if (LastShapeMI ==
nullptr || LastShapeMI->
isPHI())
656bool X86FastPreTileConfig::runOnMachineFunction(
MachineFunction &MFunc) {
660 TII =
ST->getInstrInfo();
663 TRI =
ST->getRegisterInfo();
666 unsigned NumVirtRegs =
MRI->getNumVirtRegs();
668 bool HasVirtTileReg =
false;
669 for (
unsigned I = 0,
E = NumVirtRegs;
I !=
E; ++
I) {
671 if (
MRI->getRegClass(VirtReg)->getID() == X86::TILERegClassID) {
672 HasVirtTileReg =
true;
679 StackSlotForVirtReg.resize(NumVirtRegs);
680 MayLiveAcrossBlocks.clear();
684 MayLiveAcrossBlocks.resize(NumVirtRegs * 3);
690 canonicalizePHIs(
MBB);
698 Change |= configBasicBlock(*
MBB);
702 InitializeTileConfigStackSpace();
704 StackSlotForVirtReg.clear();
709 return new X86FastPreTileConfig();
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Fast Tile Register static false bool dominates(MachineBasicBlock &MBB, MachineBasicBlock::const_iterator A, MachineBasicBlock::const_iterator B)
static bool isTileRegDef(MachineRegisterInfo *MRI, MachineInstr &MI)
Fast Tile Register Preconfigure
static ShapeT getShape(MachineRegisterInfo *MRI, Register TileReg)
static bool isTileDef(MachineRegisterInfo *MRI, MachineInstr &MI)
FunctionPass class - This class is used to implement most global optimizations.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
Store the specified register of the given register class to the specified stack frame index.
iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
unsigned getNumOperands() const
Retuns the total number of operands.
iterator_range< mop_iterator > operands()
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setReg(Register Reg)
Change the register this operand corresponds to.
void setIsKill(bool Val=true)
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
static unsigned virtReg2Index(Register Reg)
Convert a virtual register number to a 0-based index.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
MachineOperand * getRow() const
MachineOperand * getCol() const
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
X86MachineFunctionInfo - This class is derived from MachineFunction and contains private X86 target-s...
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Fast
Attempts to make calls as fast as possible (e.g.
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0, bool mem=true)
addFrameReference - This function is used to add a reference to the base of an abstract object on the...
FunctionPass * createX86FastPreTileConfigPass()
Return a pass that preconfig the tile registers before fast reg allocation.
auto reverse(ContainerTy &&C)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static const MachineInstrBuilder & addOffset(const MachineInstrBuilder &MIB, int Offset)
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
static const MachineInstrBuilder & addDirectMem(const MachineInstrBuilder &MIB, unsigned Reg)
addDirectMem - This function is used to add a direct memory reference to the current instruction – th...
This struct is a compact representation of a valid (non-zero power of two) alignment.