#include "X86.h"
#include "X86InstrBuilder.h"
#include "X86MachineFunctionInfo.h"
#include "X86RegisterInfo.h"
#include "X86Subtarget.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/InitializePasses.h"
using namespace llvm;
#define DEBUG_TYPE "fasttileconfig"
namespace {
class X86FastTileConfig : public MachineFunctionPass {
MachineFunction *MF = nullptr;
const TargetInstrInfo *TII = nullptr;
MachineRegisterInfo *MRI = nullptr;
const TargetRegisterInfo *TRI = nullptr;
X86MachineFunctionInfo *X86FI = nullptr;
bool configBasicBlock(MachineBasicBlock &MBB);
public:
X86FastTileConfig() : MachineFunctionPass(ID) {}
StringRef getPassName() const override {
return "Fast Tile Register Configure";
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
MachineFunctionPass::getAnalysisUsage(AU);
}
bool runOnMachineFunction(MachineFunction &MFunc) override;
MachineFunctionProperties getRequiredProperties() const override {
return MachineFunctionProperties().set(
MachineFunctionProperties::Property::NoPHIs);
}
static char ID;
};
}
char X86FastTileConfig::ID = 0;
INITIALIZE_PASS_BEGIN(X86FastTileConfig, DEBUG_TYPE,
"Fast Tile Register Configure", false, false)
INITIALIZE_PASS_END(X86FastTileConfig, DEBUG_TYPE,
"Fast Tile Register Configure", false, false)
static bool isTileDef(MachineRegisterInfo *MRI, MachineInstr &MI) {
assert(MI.isPHI() == false);
if (MI.isDebugInstr() || MI.isCopy() || MI.getNumOperands() < 3 ||
!MI.isPseudo())
return false;
MachineOperand &MO = MI.getOperand(0);
if (MO.isReg()) {
Register Reg = MO.getReg();
if (Reg.isVirtual() &&
MRI->getRegClass(Reg)->getID() == X86::TILERegClassID)
return true;
if (Reg >= X86::TMM0 && Reg <= X86::TMM7)
return true;
}
return false;
}
bool X86FastTileConfig::configBasicBlock(MachineBasicBlock &MBB) {
bool Change = false;
SmallVector<std::pair<unsigned, ShapeT>, 6> ShapeInfos;
for (MachineInstr &MI : reverse(MBB)) {
if (!isTileDef(MRI, MI) && MI.getOpcode() != X86::PLDTILECFGV)
continue;
if (MI.getOpcode() != X86::PLDTILECFGV) {
MachineOperand &Row = MI.getOperand(1);
MachineOperand &Col = MI.getOperand(2);
unsigned TMMIdx = MI.getOperand(0).getReg() - X86::TMM0;
ShapeInfos.push_back({TMMIdx, ShapeT(&Row, &Col)});
} else { int SS = MI.getOperand(0).getIndex(); for (auto &ShapeInfo : ShapeInfos) {
DebugLoc DL;
unsigned TMMIdx = ShapeInfo.first;
Register RowReg = ShapeInfo.second.getRow()->getReg();
Register ColReg = ShapeInfo.second.getCol()->getReg();
int RowOffset = 48 + TMMIdx;
int ColOffset = 16 + TMMIdx * 2;
Register SubRowReg = TRI->getSubReg(RowReg, X86::sub_8bit);
BuildMI(MBB, MI, DL, TII->get(X86::IMPLICIT_DEF), SubRowReg);
MachineInstrBuilder StoreRow =
BuildMI(MBB, MI, DL, TII->get(X86::MOV8mr));
addFrameReference(StoreRow, SS, RowOffset).addReg(SubRowReg);
MachineInstrBuilder StoreCol =
BuildMI(MBB, MI, DL, TII->get(X86::MOV16mr));
addFrameReference(StoreCol, SS, ColOffset).addReg(ColReg);
}
ShapeInfos.clear();
Change = true;
}
}
if (Change)
X86FI->setHasVirtualTileReg(true);
return Change;
}
bool X86FastTileConfig::runOnMachineFunction(MachineFunction &MFunc) {
MF = &MFunc;
MRI = &MFunc.getRegInfo();
const TargetSubtargetInfo *ST = &MFunc.getSubtarget<X86Subtarget>();
TRI = ST->getRegisterInfo();
TII = MFunc.getSubtarget().getInstrInfo();
X86FI = MFunc.getInfo<X86MachineFunctionInfo>();
bool Change = false;
for (MachineBasicBlock &MBB : MFunc)
Change |= configBasicBlock(MBB);
return Change;
}
FunctionPass *llvm::createX86FastTileConfigPass() {
return new X86FastTileConfig();
}