36#define DEBUG_TYPE "fastpretileconfig"
67 int getStackSpaceFor(
Register VirtReg);
68 void InitializeTileConfigStackSpace();
83 return "Fast Tile Register Preconfigure";
94char X86FastPreTileConfig::ID = 0;
97 "Fast Tile Register Preconfigure",
false,
false)
109 for (; &*
I !=
A && &*
I !=
B; ++
I)
117int X86FastPreTileConfig::getStackSpaceFor(
Register VirtReg) {
119 int SS = StackSlotForVirtReg[VirtReg];
126 unsigned Size =
TRI->getSpillSize(RC);
127 Align Alignment =
TRI->getSpillAlign(RC);
128 int FrameIdx = MFI->CreateSpillStackObject(
Size, Alignment);
131 StackSlotForVirtReg[VirtReg] = FrameIdx;
142 for (
const MachineInstr &UseInst :
MRI->use_nodbg_instructions(VirtReg)) {
143 if (UseInst.getParent() !=
MBB) {
162void X86FastPreTileConfig::InitializeTileConfigStackSpace() {
166 if (
ST->hasAVX512()) {
167 Register Zmm =
MRI->createVirtualRegister(&X86::VR512RegClass);
171 }
else if (
ST->hasAVX2()) {
172 Register Ymm =
MRI->createVirtualRegister(&X86::VR256RegClass);
180 assert(
ST->hasSSE2() &&
"AMX should assume SSE2 enabled");
181 unsigned StoreOpc =
ST->hasAVX() ? X86::VMOVUPSmr : X86::MOVUPSmr;
182 Register Xmm =
MRI->createVirtualRegister(&X86::VR128RegClass);
203 int FI = getStackSpaceFor(VirtReg);
220 int FI = getStackSpaceFor(OrigReg);
234 TileReg =
MRI->createVirtualRegister(&RC);
238 unsigned Opc = X86::PTILELOADDV;
239 Register StrideReg =
MRI->createVirtualRegister(&X86::GR64_NOSPRegClass);
242 TII->get(X86::MOV64ri), StrideReg)
271 if (Reg.isVirtual()) {
272 unsigned RegClassID =
MRI->getRegClass(Reg)->getID();
273 if (RegClassID == X86::TILERegClassID)
275 if (RegClassID == X86::TILEPAIRRegClassID)
278 if (Reg >= X86::TMM0 && Reg <= X86::TMM7)
280 if (Reg >= X86::TMM0_TMM1 && Reg <= X86::TMM6_TMM7)
292 if (
MI.isDebugInstr() ||
MI.getNumOperands() < 3 || !
MI.isPseudo())
308 }
else if (
MI->isCopy()) {
309 TileReg =
MI->getOperand(1).getReg();
315 assert(
MI->isPHI() &&
"Unexpected PHI when get shape.");
340 Register StackAddrReg =
MRI->createVirtualRegister(&X86::GR64_NOSPRegClass);
342 TII->get(X86::PHI), StackAddrReg);
343 Register RowReg =
MRI->createVirtualRegister(&X86::GR16RegClass);
345 TII->get(X86::PHI), RowReg);
346 Register ColReg =
MRI->createVirtualRegister(&X86::GR16RegClass);
348 TII->get(X86::PHI), ColReg);
350 VisitedPHIs[&
PHI] = {RowReg, ColReg, StackAddrReg};
352 for (
unsigned I = 1, E =
PHI.getNumOperands();
I != E;
I += 2) {
363 if (TileDefMI->
isPHI()) {
365 if (VisitedPHIs.count(TileDefMI)) {
375 Register InRowReg = VisitedPHIs[TileDefMI].Row;
376 Register InColReg = VisitedPHIs[TileDefMI].Col;
377 Register InStackAddrReg = VisitedPHIs[TileDefMI].StackAddr;
384 convertPHI(TileDefMI->
getParent(), *TileDefMI);
408 int FI = getStackSpaceFor(InTileReg);
410 MRI->createVirtualRegister(&X86::GR64_NOSPRegClass);
412 TII->get(X86::LEA64r), InStackAddrReg)
420 Register StrideReg =
MRI->createVirtualRegister(&X86::GR64_NOSPRegClass);
432 PHI.eraseFromParent();
433 VisitedPHIs.erase(&
PHI);
463 while (!PHIs.
empty()) {
470 for (
unsigned I = 1, E =
PHI->getNumOperands();
I != E;
I += 2) {
477 InMO = &
PHI->getOperand(
I);
507 while (!PHIs.
empty()) {
510 convertPHI(&
MBB, *
MI);
521 bool HasUnconfigTile =
false;
525 CfgSS = MFI->CreateStackObject(
ST->getTileConfigSize(),
526 ST->getTileConfigAlignment(),
false);
529 LastShapeMI =
nullptr;
558 if (HasTileOperand(
MRI,
MI))
559 HasUnconfigTile =
true;
562 if (
MI.isCall() && HasUnconfigTile) {
567 I = ++
MI.getIterator();
569 HasUnconfigTile =
false;
630 if (TileDefNum > 1) {
631 for (
unsigned I = 1;
I < TileDefNum;
I++) {
636 LastShapeMI = ColxMI;
638 LastShapeMI = ColxMI;
645 if (mayLiveOut(TileReg, LastTileCfg))
646 spill(++
MI.getIterator(), TileReg,
false);
653 reload(
UseMI.getIterator(), TileReg, RowMO, ColMO);
658 reload(
UseMI.getIterator(), TileReg, RowMO, ColMO);
664 if (HasUnconfigTile) {
666 if (LastShapeMI ==
nullptr || LastShapeMI->
isPHI())
677bool X86FastPreTileConfig::runOnMachineFunction(
MachineFunction &MFunc) {
680 if (X86FI->getAMXProgModel() != AMXProgModelEnum::ManagedRA)
686 TII =
ST->getInstrInfo();
688 TRI =
ST->getRegisterInfo();
691 unsigned NumVirtRegs =
MRI->getNumVirtRegs();
693 StackSlotForVirtReg.resize(NumVirtRegs);
694 MayLiveAcrossBlocks.clear();
698 MayLiveAcrossBlocks.resize(NumVirtRegs * 3);
704 canonicalizePHIs(
MBB);
712 Change |= configBasicBlock(*
MBB);
716 InitializeTileConfigStackSpace();
718 StackSlotForVirtReg.clear();
723 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")
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)
static unsigned getTileDefNum(MachineRegisterInfo *MRI, Register Reg)
Fast Tile Register static false bool dominates(MachineBasicBlock &MBB, MachineBasicBlock::const_iterator A, MachineBasicBlock::const_iterator B)
static bool isTileRegDef(MachineRegisterInfo *MRI, MachineInstr &MI)
static bool isTileRegister(MachineRegisterInfo *MRI, Register VirtReg)
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 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(unsigned I=0) const
MachineOperand * getCol(unsigned I=0) 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.
@ Fast
Attempts to make calls as fast as possible (e.g.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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.