LLVM 22.0.0git
X86FastTileConfig.cpp
Go to the documentation of this file.
1//===-- X86FastTileConfig.cpp - Fast Tile Register Configure---------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file Pass to config the shape of AMX physical registers
10/// AMX register need to be configured before use. Before FastRegAllocation pass
11/// the ldtilecfg instruction is inserted, however at that time we don't
12/// know the shape of each physical tile registers, because the register
13/// allocation is not done yet. This pass runs after register allocation
14/// pass. It collects the shape information of each physical tile register
15/// and store the shape in the stack slot that is allocated for load config
16/// to tile config register.
17//
18//===----------------------------------------------------------------------===//
19
20#include "X86.h"
21#include "X86InstrBuilder.h"
23#include "X86Subtarget.h"
28#include "llvm/CodeGen/Passes.h"
31
32using namespace llvm;
33
34#define DEBUG_TYPE "fasttileconfig"
35
36namespace {
37
38class X86FastTileConfig : public MachineFunctionPass {
39 // context
40 MachineFunction *MF = nullptr;
41 const TargetInstrInfo *TII = nullptr;
42 MachineRegisterInfo *MRI = nullptr;
43 const TargetRegisterInfo *TRI = nullptr;
44 X86MachineFunctionInfo *X86FI = nullptr;
45
46 bool configBasicBlock(MachineBasicBlock &MBB);
47
48public:
49 X86FastTileConfig() : MachineFunctionPass(ID) {}
50
51 /// Return the pass name.
52 StringRef getPassName() const override {
53 return "Fast Tile Register Configure";
54 }
55
56 void getAnalysisUsage(AnalysisUsage &AU) const override {
57 AU.setPreservesAll();
59 }
60
61 /// Perform register allocation.
62 bool runOnMachineFunction(MachineFunction &MFunc) override;
63
64 MachineFunctionProperties getRequiredProperties() const override {
65 return MachineFunctionProperties().setNoPHIs();
66 }
67
68 static char ID;
69};
70
71} // end anonymous namespace
72
73char X86FastTileConfig::ID = 0;
74
76 "Fast Tile Register Configure", false, false)
78 "Fast Tile Register Configure", false, false)
79
81 // There is no phi instruction after register allocation.
82 assert(MI.isPHI() == false);
83 // The instruction must have 3 operands: tile def, row, col.
84 // It should be AMX pseudo instruction that have shape operand.
85 if (MI.isDebugInstr() || MI.isCopy() || MI.getNumOperands() < 3 ||
86 !MI.isPseudo())
87 return false;
88 MachineOperand &MO = MI.getOperand(0);
89
90 if (MO.isReg()) {
91 Register Reg = MO.getReg();
92 // FIXME: It may be used after Greedy RA and the physical
93 // register is not rewritten yet.
94 if (Reg.isVirtual()) {
95 if (MRI->getRegClass(Reg)->getID() == X86::TILERegClassID)
96 return true;
97 }
98 if (Reg >= X86::TMM0 && Reg <= X86::TMM7)
99 return true;
100 }
101
102 return false;
103}
104
105static unsigned getTMMIndex(Register Reg) {
106 if (Reg >= X86::TMM0 && Reg <= X86::TMM7)
107 return Reg - X86::TMM0;
108 llvm_unreachable("Invalid Tmm Reg!");
109}
110
111// PreTileConfig should configure the tile registers based on basic
112// block.
113bool X86FastTileConfig::configBasicBlock(MachineBasicBlock &MBB) {
114 bool Change = false;
116 for (MachineInstr &MI : reverse(MBB)) {
117 if (!isTileDef(MRI, MI) && MI.getOpcode() != X86::PLDTILECFGV)
118 continue;
119 // AMX instructions that define tile register.
120 if (MI.getOpcode() != X86::PLDTILECFGV) {
121 MachineOperand &Row = MI.getOperand(1);
122 unsigned TMMIdx = getTMMIndex(MI.getOperand(0).getReg());
123 MachineOperand &Col = MI.getOperand(2);
124 ShapeInfos.push_back({TMMIdx, ShapeT(&Row, &Col)});
125 } else { // PLDTILECFGV
126 // Rewrite the shape information to memory. Stack slot should have
127 // been initialized to zero in pre config.
128 int SS = MI.getOperand(0).getIndex(); // tile config stack slot.
129 for (auto &ShapeInfo : ShapeInfos) {
130 DebugLoc DL;
131 unsigned TMMIdx = ShapeInfo.first;
132 Register RowReg = ShapeInfo.second.getRow()->getReg();
133 Register ColReg = ShapeInfo.second.getCol()->getReg();
134 // Here is the data format for the tile config.
135 // 0 palette
136 // 1 start_row
137 // 2-15 reserved, must be zero
138 // 16-17 tile0.colsb Tile 0 bytes per row.
139 // 18-19 tile1.colsb Tile 1 bytes per row.
140 // 20-21 tile2.colsb Tile 2 bytes per row.
141 // ... (sequence continues)
142 // 30-31 tile7.colsb Tile 7 bytes per row.
143 // 32-47 reserved, must be zero
144 // 48 tile0.rows Tile 0 rows.
145 // 49 tile1.rows Tile 1 rows.
146 // 50 tile2.rows Tile 2 rows.
147 // ... (sequence continues)
148 // 55 tile7.rows Tile 7 rows.
149 // 56-63 reserved, must be zero
150 int RowOffset = 48 + TMMIdx;
151 int ColOffset = 16 + TMMIdx * 2;
152
153 Register SubRowReg = TRI->getSubReg(RowReg, X86::sub_8bit);
154 BuildMI(MBB, MI, DL, TII->get(X86::IMPLICIT_DEF), SubRowReg);
155 MachineInstrBuilder StoreRow =
156 BuildMI(MBB, MI, DL, TII->get(X86::MOV8mr));
157 addFrameReference(StoreRow, SS, RowOffset).addReg(SubRowReg);
158
159 MachineInstrBuilder StoreCol =
160 BuildMI(MBB, MI, DL, TII->get(X86::MOV16mr));
161 addFrameReference(StoreCol, SS, ColOffset).addReg(ColReg);
162 }
163 ShapeInfos.clear();
164 Change = true;
165 }
166 }
167
168 return Change;
169}
170
171bool X86FastTileConfig::runOnMachineFunction(MachineFunction &MFunc) {
172 X86FI = MFunc.getInfo<X86MachineFunctionInfo>();
173 // Early exit in the common case of non-AMX code.
174 if (X86FI->getAMXProgModel() != AMXProgModelEnum::ManagedRA)
175 return false;
176
177 MF = &MFunc;
178 MRI = &MFunc.getRegInfo();
179 const TargetSubtargetInfo *ST = &MFunc.getSubtarget<X86Subtarget>();
180 TRI = ST->getRegisterInfo();
181 TII = MFunc.getSubtarget().getInstrInfo();
182 bool Change = false;
183
184 // Loop over all of the basic blocks, eliminating virtual register references
185 for (MachineBasicBlock &MBB : MFunc)
186 Change |= configBasicBlock(MBB);
187
188 return Change;
189}
190
192 return new X86FastTileConfig();
193}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define DEBUG_TYPE
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
static bool isTileDef(MachineRegisterInfo *MRI, MachineInstr &MI)
static unsigned getTMMIndex(Register Reg)
Represent the analysis usage information of a pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Properties which a MachineFunction may have at a given point in time.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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 & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
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.
Definition Register.h:19
void push_back(const T &Elt)
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetInstrInfo * getInstrInfo() const
X86MachineFunctionInfo - This class is derived from MachineFunction and contains private X86 target-s...
AMXProgModelEnum getAMXProgModel() const
#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.
Definition CallingConv.h:24
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...
auto reverse(ContainerTy &&C)
Definition STLExtras.h:406
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
FunctionPass * createX86FastTileConfigPass()
Return a pass that config the tile registers after fast reg allocation.