diff options
Diffstat (limited to 'llvm/lib/Target/X86/X86TileConfig.cpp')
| -rw-r--r-- | llvm/lib/Target/X86/X86TileConfig.cpp | 270 |
1 files changed, 109 insertions, 161 deletions
diff --git a/llvm/lib/Target/X86/X86TileConfig.cpp b/llvm/lib/Target/X86/X86TileConfig.cpp index ef010bcd38b7..8114a0b2d423 100644 --- a/llvm/lib/Target/X86/X86TileConfig.cpp +++ b/llvm/lib/Target/X86/X86TileConfig.cpp @@ -23,7 +23,6 @@ #include "X86RegisterInfo.h" #include "X86Subtarget.h" #include "llvm/CodeGen/LiveIntervals.h" -#include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" @@ -41,28 +40,20 @@ using namespace llvm; namespace { -class X86TileConfig : public MachineFunctionPass { - // context - MachineFunction *MF = nullptr; - const X86Subtarget *ST = nullptr; - const TargetRegisterInfo *TRI; - const TargetInstrInfo *TII; - MachineDominatorTree *DomTree = nullptr; - MachineRegisterInfo *MRI = nullptr; - VirtRegMap *VRM = nullptr; - LiveIntervals *LIS = nullptr; +struct X86TileConfig : public MachineFunctionPass { - MachineInstr *getTileConfigPoint(); - void tileConfig(); - -public: X86TileConfig() : MachineFunctionPass(ID) {} /// Return the pass name. StringRef getPassName() const override { return "Tile Register Configure"; } /// X86TileConfig analysis usage. - void getAnalysisUsage(AnalysisUsage &AU) const override; + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + AU.addRequired<VirtRegMap>(); + AU.addRequired<LiveIntervals>(); + MachineFunctionPass::getAnalysisUsage(AU); + } /// Perform register allocation. bool runOnMachineFunction(MachineFunction &mf) override; @@ -81,167 +72,124 @@ char X86TileConfig::ID = 0; INITIALIZE_PASS_BEGIN(X86TileConfig, "tileconfig", "Tile Register Configure", false, false) -INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) INITIALIZE_PASS_DEPENDENCY(VirtRegMap) INITIALIZE_PASS_END(X86TileConfig, "tileconfig", "Tile Register Configure", false, false) -void X86TileConfig::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired<MachineDominatorTree>(); - AU.addRequired<LiveIntervals>(); - AU.addPreserved<SlotIndexes>(); - AU.addRequired<VirtRegMap>(); - AU.setPreservesAll(); - MachineFunctionPass::getAnalysisUsage(AU); -} - -static unsigned getTilePhysRegIndex(Register PhysReg) { - assert((PhysReg >= X86::TMM0 && X86::TMM0 <= X86::TMM7) && - "Tile register number is invalid"); - return (PhysReg - X86::TMM0); -} - -static MachineInstr * -storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - Register SrcReg, unsigned BitSize, int FrameIdx, int Offset, - const TargetInstrInfo *TII, const TargetRegisterClass *RC, - const TargetRegisterInfo *TRI) { - - unsigned SubIdx = (BitSize == 8) ? X86::sub_8bit : X86::sub_16bit; - unsigned Opc = (BitSize == 8) ? X86::MOV8mr : X86::MOV16mr; - if (BitSize == TRI->getRegSizeInBits(*RC)) - SubIdx = 0; - MachineInstr *NewMI = - addFrameReference(BuildMI(MBB, MI, DebugLoc(), TII->get(Opc)), FrameIdx, - Offset) - .addReg(SrcReg, 0, SubIdx); - return NewMI; -} +bool X86TileConfig::runOnMachineFunction(MachineFunction &MF) { + const X86Subtarget &ST = MF.getSubtarget<X86Subtarget>(); + const TargetRegisterInfo *TRI = ST.getRegisterInfo(); + const TargetInstrInfo *TII = ST.getInstrInfo(); + MachineRegisterInfo &MRI = MF.getRegInfo(); + LiveIntervals &LIS = getAnalysis<LiveIntervals>(); + VirtRegMap &VRM = getAnalysis<VirtRegMap>(); -static MachineInstr *storeImmToStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - int64_t Imm, unsigned BitSize, - int FrameIdx, int Offset, - const TargetInstrInfo *TII) { - unsigned Opc = (BitSize == 8) ? X86::MOV8mi : X86::MOV16mi; - return addFrameReference(BuildMI(MBB, MI, DebugLoc(), TII->get(Opc)), - FrameIdx, Offset) - .addImm(Imm); -} - -MachineInstr *X86TileConfig::getTileConfigPoint() { - for (MachineBasicBlock &MBB : *MF) { + if (VRM.isShapeMapEmpty()) + return false; - // Traverse the basic block. - for (MachineInstr &MI : MBB) - // Refer X86PreTileConfig.cpp. - // We only support one tile config for now. - if (MI.getOpcode() == X86::PLDTILECFG) - return &MI; + int SS = INT_MAX; + for (MachineBasicBlock &MBB : MF) { + for (MachineInstr &MI : MBB) { + if (MI.getOpcode() == X86::LDTILECFG) { + SS = MI.getOperand(0).getIndex(); + break; + } + } + if (SS != INT_MAX) + break; } - return nullptr; -} - -void X86TileConfig::tileConfig() { - MachineInstr *MI = getTileConfigPoint(); - if (!MI) - return; - MachineBasicBlock *MBB = MI->getParent(); - int SS = MI->getOperand(1).getIndex(); - BitVector PhysRegs(TRI->getNumRegs()); + // Try to find a point to insert MIs for constant shapes. + // Here we are leveraging the palette id inserted in PreRA pass. + unsigned ConstPos = 0; + MachineInstr *ConstMI = nullptr; + for (MachineInstr &MI : MF.front()) { + if (MI.getOpcode() == X86::MOV8mi && SS == MI.getOperand(0).getIndex()) { + ConstMI = &MI; + break; + } + ++ConstPos; + } + assert(ConstMI && "Cannot find an insertion point"); - // Fill in the palette first. - auto *NewMI = storeImmToStackSlot(*MBB, *MI, 1, 8, SS, 0, TII); - LIS->InsertMachineInstrInMaps(*NewMI); - // Fill in the shape of each tile physical register. - for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) { - Register VirtReg = Register::index2VirtReg(i); - if (MRI->reg_nodbg_empty(VirtReg)) - continue; - const TargetRegisterClass &RC = *MRI->getRegClass(VirtReg); - if (RC.getID() != X86::TILERegClassID) + unsigned AMXRegNum = TRI->getRegClass(X86::TILERegClassID)->getNumRegs(); + SmallVector<Register, 8> Phys2Virt(AMXRegNum, 0); + for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) { + Register VirtReg = Register::index2VirtReg(I); + if (MRI.reg_nodbg_empty(VirtReg)) continue; - Register PhysReg = VRM->getPhys(VirtReg); - if (PhysRegs.test(PhysReg)) + if (MRI.getRegClass(VirtReg)->getID() != X86::TILERegClassID) continue; - PhysRegs.set(PhysReg); - ShapeT Shape = VRM->getShape(VirtReg); - Register RowReg = Shape.getRow()->getReg(); - Register ColReg = Shape.getCol()->getReg(); - - // Here is the data format for the tile config. - // 0 palette - // 1 start_row - // 2-15 reserved, must be zero - // 16-17 tile0.colsb Tile 0 bytes per row. - // 18-19 tile1.colsb Tile 1 bytes per row. - // 20-21 tile2.colsb Tile 2 bytes per row. - // ... (sequence continues) - // 30-31 tile7.colsb Tile 7 bytes per row. - // 32-47 reserved, must be zero - // 48 tile0.rows Tile 0 rows. - // 49 tile1.rows Tile 1 rows. - // 50 tile2.rows Tile 2 rows. - // ... (sequence continues) - // 55 tile7.rows Tile 7 rows. - // 56-63 reserved, must be zero - unsigned Index = getTilePhysRegIndex(PhysReg); - int RowOffset = 48 + Index; - int ColOffset = 16 + Index * 2; + unsigned Index = VRM.getPhys(VirtReg) - X86::TMM0; + if (!Phys2Virt[Index]) + Phys2Virt[Index] = VirtReg; + } - unsigned BitSize = 8; - for (const auto &Pair : {std::make_pair(RowReg, RowOffset), - std::make_pair(ColReg, ColOffset)}) { - int64_t Imm; - int ImmCount = 0; - // All def must be the same value, otherwise it is invalid MIs. - // Immediate is prefered. - for (const MachineOperand &MO : MRI->def_operands(Pair.first)) { - const auto *Inst = MO.getParent(); - if (Inst->isMoveImmediate()) { - ImmCount++; - Imm = Inst->getOperand(1).getImm(); - break; + // Fill in the shape of each tile physical register. + for (unsigned I = 0; I < AMXRegNum; ++I) { + if (!Phys2Virt[I]) + continue; + DebugLoc DL; + bool IsRow = true; + MachineInstr *NewMI = nullptr; + ShapeT Shape = VRM.getShape(Phys2Virt[I]); + for (auto &R : {Shape.getRow()->getReg(), Shape.getCol()->getReg()}) { + // Here is the data format for the tile config. + // 0 palette + // 1 start_row + // 2-15 reserved, must be zero + // 16-17 tile0.colsb Tile 0 bytes per row. + // 18-19 tile1.colsb Tile 1 bytes per row. + // 20-21 tile2.colsb Tile 2 bytes per row. + // ... (sequence continues) + // 30-31 tile7.colsb Tile 7 bytes per row. + // 32-47 reserved, must be zero + // 48 tile0.rows Tile 0 rows. + // 49 tile1.rows Tile 1 rows. + // 50 tile2.rows Tile 2 rows. + // ... (sequence continues) + // 55 tile7.rows Tile 7 rows. + // 56-63 reserved, must be zero + int64_t Imm = INT64_MAX; + int Offset = IsRow ? 48 + I : 16 + I * 2; + for (auto &DefMI : MRI.def_instructions(R)) { + MachineBasicBlock &MBB = *DefMI.getParent(); + if (DefMI.isMoveImmediate()) { + if (Imm != INT64_MAX) { + // FIXME: We should handle this case in future. + assert(Imm == DefMI.getOperand(1).getImm() && + "Cannot initialize with different shapes"); + continue; + } + Imm = DefMI.getOperand(1).getImm(); + NewMI = addFrameReference( + BuildMI(MF.front(), ++ConstMI->getIterator(), DL, + TII->get(IsRow ? X86::MOV8mi : X86::MOV16mi)), + SS, Offset) + .addImm(Imm); + ConstMI = NewMI; + LIS.InsertMachineInstrInMaps(*NewMI); + } else { + unsigned SubIdx = IsRow ? X86::sub_8bit : X86::sub_16bit; + unsigned RegSize = TRI->getRegSizeInBits(*MRI.getRegClass(R)); + if ((IsRow && RegSize == 8) || (!IsRow && RegSize == 16)) + SubIdx = 0; + auto Iter = DefMI.getIterator(); + if (&MBB == &MF.front() && + (unsigned)std::distance(MBB.instr_begin(), Iter) < ConstPos) + Iter = ConstMI->getIterator(); + NewMI = addFrameReference( + BuildMI(MBB, ++Iter, DL, + TII->get(IsRow ? X86::MOV8mr : X86::MOV16mr)), + SS, Offset) + .addReg(R, 0, SubIdx); + SlotIndex SIdx = LIS.InsertMachineInstrInMaps(*NewMI); + LIS.extendToIndices(LIS.getInterval(R), {SIdx.getRegSlot()}); } } - auto StoreConfig = [&](int Offset) { - MachineInstr *NewMI = nullptr; - if (ImmCount) - NewMI = storeImmToStackSlot(*MBB, *MI, Imm, BitSize, SS, Offset, TII); - else { - const TargetRegisterClass *RC = MRI->getRegClass(Pair.first); - NewMI = storeRegToStackSlot(*MBB, *MI, Pair.first, BitSize, SS, - Offset, TII, RC, TRI); - } - SlotIndex SIdx = LIS->InsertMachineInstrInMaps(*NewMI); - if (!ImmCount) { - // Extend the live interval. - SmallVector<SlotIndex, 8> EndPoints = {SIdx.getRegSlot()}; - LiveInterval &Int = LIS->getInterval(Pair.first); - LIS->extendToIndices(Int, EndPoints); - } - }; - StoreConfig(Pair.second); - BitSize += 8; + IsRow = false; } } -} - -bool X86TileConfig::runOnMachineFunction(MachineFunction &mf) { - MF = &mf; - MRI = &mf.getRegInfo(); - ST = &mf.getSubtarget<X86Subtarget>(); - TRI = ST->getRegisterInfo(); - TII = mf.getSubtarget().getInstrInfo(); - DomTree = &getAnalysis<MachineDominatorTree>(); - VRM = &getAnalysis<VirtRegMap>(); - LIS = &getAnalysis<LiveIntervals>(); - - if (VRM->isShapeMapEmpty()) - return false; - - tileConfig(); return true; } |
