36#define DEBUG_TYPE "fastpretileconfig" 
   58  DenseMap<MachineInstr *, struct PHIInfo> VisitedPHIs;
 
   61  IndexedMap<int, VirtReg2IndexFunctor> StackSlotForVirtReg;
 
   65  BitVector MayLiveAcrossBlocks;
 
   67  int getStackSpaceFor(
Register VirtReg);
 
   68  void InitializeTileConfigStackSpace();
 
   69  bool mayLiveOut(
Register VirtReg, MachineInstr *CfgMI);
 
   72              MachineOperand *RowMO, MachineOperand *ColMO);
 
   73  void canonicalizePHIs(MachineBasicBlock &MBB);
 
   74  void convertPHI(MachineBasicBlock *MBB, MachineInstr &
PHI);
 
   75  void convertPHIs(MachineBasicBlock &MBB);
 
   76  bool configBasicBlock(MachineBasicBlock &MBB);
 
   79  X86FastPreTileConfig() : MachineFunctionPass(ID), StackSlotForVirtReg(-1) {}
 
   82  StringRef getPassName()
 const override {
 
   83    return "Fast Tile Register Preconfigure";
 
   87  bool runOnMachineFunction(MachineFunction &MFunc) 
override;
 
   94char X86FastPreTileConfig::ID = 0;
 
   97                      "Fast Tile Register Preconfigure", 
false, 
false)
 
  104  auto MBBEnd = 
MBB.end();
 
  109  for (; &*
I != 
A && &*
I != 
B; ++
I)
 
 
  117int X86FastPreTileConfig::getStackSpaceFor(
Register VirtReg) {
 
  119  int SS = StackSlotForVirtReg[VirtReg];
 
  125  const TargetRegisterClass &RC = *
MRI->getRegClass(VirtReg);
 
  126  unsigned Size = 
TRI->getSpillSize(RC);
 
  127  Align Alignment = 
TRI->getSpillAlign(RC);
 
  131  StackSlotForVirtReg[VirtReg] = FrameIdx;
 
  138bool X86FastPreTileConfig::mayLiveOut(
Register VirtReg, MachineInstr *CfgMI) {
 
  142  for (
const MachineInstr &UseInst : 
MRI->use_nodbg_instructions(VirtReg)) {
 
  143    if (UseInst.getParent() != 
MBB) {
 
  162void X86FastPreTileConfig::InitializeTileConfigStackSpace() {
 
  163  MachineBasicBlock &
MBB = MF->
front();
 
  167    Register Zmm = 
MRI->createVirtualRegister(&X86::VR512RegClass);
 
  172    Register Ymm = 
MRI->createVirtualRegister(&X86::VR256RegClass);
 
  181    unsigned StoreOpc = ST->
hasAVX() ? X86::VMOVUPSmr : X86::MOVUPSmr;
 
  182    Register Xmm = 
MRI->createVirtualRegister(&X86::VR128RegClass);
 
  203  int FI = getStackSpaceFor(VirtReg);
 
  206  const TargetRegisterClass &RC = *
MRI->getRegClass(VirtReg);
 
  218                                  Register OrigReg, MachineOperand *RowMO,
 
  219                                  MachineOperand *ColMO) {
 
  220  int FI = getStackSpaceFor(OrigReg);
 
  221  const TargetRegisterClass &RC = *
MRI->getRegClass(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.");
 
 
  333void X86FastPreTileConfig::convertPHI(MachineBasicBlock *
MBB,
 
  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) {
 
  359    MachineBasicBlock *InMBB = 
PHI.getOperand(
I + 1).getMBB();
 
  361    MachineInstr *TileDefMI = 
MRI->getVRegDef(InTileReg);
 
  363    if (TileDefMI->
isPHI()) {
 
  365      if (
auto It = VisitedPHIs.find(TileDefMI);
 
  366          It != VisitedPHIs.end()) { 
 
  378        Register InStackAddrReg = It->second.StackAddr;
 
  385        convertPHI(TileDefMI->
getParent(), *TileDefMI);
 
  388        MachineInstr *TileLoad = 
MRI->getVRegDef(InTileReg);
 
  409      int FI = getStackSpaceFor(InTileReg);
 
  411          MRI->createVirtualRegister(&X86::GR64_NOSPRegClass);
 
  413                        TII->get(X86::LEA64r), InStackAddrReg)
 
  421  Register StrideReg = 
MRI->createVirtualRegister(&X86::GR64_NOSPRegClass);
 
  433  PHI.eraseFromParent();
 
  434  VisitedPHIs.erase(&
PHI);
 
  444void X86FastPreTileConfig::canonicalizePHIs(MachineBasicBlock &
MBB) {
 
  445  SmallVector<MachineInstr *, 8> PHIs;
 
  447  for (MachineInstr &
MI : 
MBB) {
 
  464  while (!PHIs.
empty()) {
 
  469    MachineOperand *InMO = 
nullptr;
 
  470    MachineInstr *
DefMI = 
nullptr;
 
  471    for (
unsigned I = 1, 
E = 
PHI->getNumOperands(); 
I != 
E; 
I += 2) {
 
  473      MachineBasicBlock *InMBB = 
PHI->getOperand(
I + 1).getMBB();
 
  478      InMO = &
PHI->getOperand(
I);
 
  489      MachineBasicBlock *InMBB = 
PHI->getOperand(
I + 1).getMBB();
 
  499void X86FastPreTileConfig::convertPHIs(MachineBasicBlock &
MBB) {
 
  500  SmallVector<MachineInstr *, 8> PHIs;
 
  501  for (MachineInstr &
MI : 
MBB) {
 
  508  while (!PHIs.
empty()) {
 
  511    convertPHI(&
MBB, *
MI);
 
  517bool X86FastPreTileConfig::configBasicBlock(MachineBasicBlock &
MBB) {
 
  520  MachineInstr *LastShapeMI = 
nullptr;
 
  521  MachineInstr *LastTileCfg = 
nullptr;
 
  522  bool HasUnconfigTile = 
false;
 
  524  auto Config = [&](MachineInstr &Before) {
 
  530    LastShapeMI = 
nullptr;
 
  533  auto HasTileOperand = [](MachineRegisterInfo *
MRI, MachineInstr &
MI) {
 
  534    for (
const MachineOperand &MO : 
MI.operands()) {
 
  559    if (HasTileOperand(
MRI, 
MI))
 
  560      HasUnconfigTile = 
true;
 
  563    if (
MI.isCall() && HasUnconfigTile) {
 
  570        auto UseIt = 
MI.getIterator();
 
  571        while (UseIt != 
MBB.
end()) {
 
  572          if (HasTileOperand(
MRI, *UseIt))
 
  579      HasUnconfigTile = 
false;
 
  621    MachineOperand *RowMO = &
MI.getOperand(1);
 
  622    MachineOperand *ColMO = &
MI.getOperand(2);
 
  623    MachineInstr *RowMI = 
MRI->getVRegDef(RowMO->
getReg());
 
  624    MachineInstr *ColMI = 
MRI->getVRegDef(ColMO->
getReg());
 
  640    if (TileDefNum > 1) {
 
  641      for (
unsigned I = 1; 
I < TileDefNum; 
I++) {
 
  642        MachineOperand *ColxMO = &
MI.getOperand(2 + 
I);
 
  643        MachineInstr *ColxMI = 
MRI->getVRegDef(ColxMO->
getReg());
 
  646            LastShapeMI = ColxMI;
 
  648            LastShapeMI = ColxMI;
 
  655    if (mayLiveOut(TileReg, LastTileCfg))
 
  656      spill(++
MI.getIterator(), TileReg, 
false);
 
  657    for (MachineInstr &
UseMI : 
MRI->use_instructions(TileReg)) {
 
  663        reload(
UseMI.getIterator(), TileReg, RowMO, ColMO);
 
  668          reload(
UseMI.getIterator(), TileReg, RowMO, ColMO);
 
  674  if (HasUnconfigTile) {
 
  675    MachineInstr *Before;
 
  676    if (LastShapeMI == 
nullptr || LastShapeMI->
isPHI())
 
  687bool X86FastPreTileConfig::runOnMachineFunction(MachineFunction &MFunc) {
 
  688  X86FI = MFunc.
getInfo<X86MachineFunctionInfo>();
 
  701  unsigned NumVirtRegs = 
MRI->getNumVirtRegs();
 
  703  StackSlotForVirtReg.resize(NumVirtRegs);
 
  704  MayLiveAcrossBlocks.
clear();
 
  708  MayLiveAcrossBlocks.
resize(NumVirtRegs * 3);
 
  713  for (MachineBasicBlock &
MBB : MFunc)
 
  714    canonicalizePHIs(
MBB);
 
  719  ReversePostOrderTraversal<MachineFunction *> RPOT(MF);
 
  720  for (MachineBasicBlock *
MBB : RPOT) {
 
  722    Change |= configBasicBlock(*
MBB);
 
  726    InitializeTileConfigStackSpace();
 
  728  StackSlotForVirtReg.clear();
 
  733  return new X86FastPreTileConfig();
 
 
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#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.
static bool dominates(InstrPosIndexes &PosIndexes, const MachineInstr &A, const MachineInstr &B)
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)
static bool isTileRegDef(MachineRegisterInfo *MRI, MachineInstr &MI)
static bool isTileRegister(MachineRegisterInfo *MRI, Register VirtReg)
static ShapeT getShape(MachineRegisterInfo *MRI, Register TileReg)
static bool isTileDef(MachineRegisterInfo *MRI, MachineInstr &MI)
bool test(unsigned Idx) const
void resize(unsigned N, bool t=false)
resize - Grow or shrink the bitvector.
void clear()
clear - Removes all bits from the bitvector.
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, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Store the specified register of the given register class to the specified stack frame index.
MachineInstrBundleIterator< const MachineInstr > const_iterator
LLVM_ABI iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
LLVM_ABI int CreateSpillStackObject(uint64_t Size, Align Alignment)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
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 MachineBasicBlock & front() const
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.
LLVM_ABI 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.
LLVM_ABI 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,...
Wrapper class representing virtual and physical registers.
unsigned virtRegIndex() const
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)
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...
AMXProgModelEnum getAMXProgModel() const
unsigned getTileConfigSize() const
Align getTileConfigAlignment() const
const X86InstrInfo * getInstrInfo() const override
const X86RegisterInfo * getRegisterInfo() const override
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
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)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static const MachineInstrBuilder & addOffset(const MachineInstrBuilder &MIB, int Offset)
static const MachineInstrBuilder & addDirectMem(const MachineInstrBuilder &MIB, Register Reg)
addDirectMem - This function is used to add a direct memory reference to the current instruction – th...
LLVM_ABI 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.