Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions llvm/lib/Target/AIE/AIE2InstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,9 @@ unsigned AIE2InstrInfo::getOpCode(MachineInstr &I) const {
Register AIE2InstrInfo::getVaddSignControlRegister() const {
return AIE2::crVaddSign;
}
Register AIE2InstrInfo::getUPSSignControlRegister() const {
return AIE2::crUPSSign;
}

// Implement CopyToReg/CopyFromReg
void AIE2InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/AIE/AIE2InstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class AIE2InstrInfo : public AIE2GenInstrInfo {
TypeSize Size) const override;
unsigned getOpCode(MachineInstr &MI) const override;
Register getVaddSignControlRegister() const override;
Register getUPSSignControlRegister() const override;

virtual std::optional<ZOLSupport> getZOLSupport() const override;
virtual std::optional<JNZDSupport> getJNZDSupport() const override;
Expand Down
116 changes: 5 additions & 111 deletions llvm/lib/Target/AIE/AIE2InstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,7 @@ class AIE2InstructionSelector : public AIEBaseInstructionSelector {
bool selectG_GLOBAL_VALUE(MachineInstr &I, MachineRegisterInfo &MRI);
bool selectG_LOAD(MachineInstr &I, MachineRegisterInfo &MRI);
bool selectG_STORE(MachineInstr &I, MachineRegisterInfo &MRI);
bool selectGetControlRegister(MachineInstr &I, MachineRegisterInfo &MRI);
bool selectReadTM(MachineInstr &I, MachineRegisterInfo &MRI);
bool selectSetControlRegister(MachineInstr &I, MachineRegisterInfo &MRI);
bool selectVEXTRACT(MachineInstr &I, MachineRegisterInfo &MRI);
bool selectVSRS(MachineInstr &I, MachineRegisterInfo &MRI);
bool selectVUNPACK(MachineInstr &I, MachineRegisterInfo &MRI);
Expand All @@ -72,12 +70,12 @@ class AIE2InstructionSelector : public AIEBaseInstructionSelector {
getOrDefineAddressingRegister(MachineInstr &MemI,
MachineRegisterInfo &MRI) final;
bool selectG_AIE_LOAD_UNPACK(MachineInstr &StoreI, MachineRegisterInfo &MRI);
bool selectG_AIE_LOAD_UPS(MachineInstr &StoreI, MachineRegisterInfo &MRI);
bool selectG_AIE_LOAD_UPS(MachineInstr &StoreI, MachineRegisterInfo &MRI,
std::optional<unsigned> crUPSModeVal) override;
bool select512BitG_AIE_LOAD_UPS(MachineInstr &UPSI, LoadStoreOpcodes &LSO,
AddressingModeInfo &AMI, Register DstReg,
Register ShftReg, Register SignReg,
bool ConstantSign, MachineRegisterInfo &MRI);
bool selectVUPS(MachineInstr &I, MachineRegisterInfo &MRI);
bool selectWriteTM(MachineInstr &I, MachineRegisterInfo &MRI);
LoadStoreOpcodes getLoadStoreOpcode(const MachineInstr &I,
const MachineRegisterInfo &MRI,
Expand Down Expand Up @@ -1835,8 +1833,9 @@ bool AIE2InstructionSelector::select512BitG_AIE_LOAD_UPS(
}
}

bool AIE2InstructionSelector::selectG_AIE_LOAD_UPS(MachineInstr &UPSI,
MachineRegisterInfo &MRI) {
bool AIE2InstructionSelector::selectG_AIE_LOAD_UPS(
MachineInstr &UPSI, MachineRegisterInfo &MRI,
std::optional<unsigned> crUPSModeVal) {

// First use is the G_INTRINSIC_W_SIDE_EFFECTS ID
Register LoadResult = (std::next(UPSI.uses().begin()))->getReg();
Expand Down Expand Up @@ -1905,33 +1904,6 @@ bool AIE2InstructionSelector::selectG_AIE_LOAD_UPS(MachineInstr &UPSI,
return constrainSelectedInstRegOperands(*NewInstr.getInstr(), TII, TRI, RBI);
}

bool AIE2InstructionSelector::selectVUPS(MachineInstr &I,
MachineRegisterInfo &MRI) {
// First try to match UPS combine
if (selectG_AIE_LOAD_UPS(I, MRI))
return true;

Register DstReg = I.getOperand(0).getReg();
// In this case of G_INTRINSIC_W_SIDE_EFFECTS operand 1 is target intrinsic
Register SrcReg = I.getOperand(2).getReg();
Register ShftReg = I.getOperand(3).getReg();
Register SignReg = I.getOperand(4).getReg();

if (auto SignVal = getIConstantVRegValWithLookThrough(SignReg, MRI)) {
// Handle constant sign through instruction patterns
return selectImpl(I, *CoverageInfo);
}

unsigned OpCode = TII.getOpCode(I);
MachineInstrBuilder MI =
MIB.buildInstr(OpCode, {DstReg}, {}).addReg(SrcReg).addReg(ShftReg);

setUnsetCtrlRegister(MIB, *MI, MRI, AIE2::crUPSSign, SignReg);

I.eraseFromParent();
return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
}

bool AIE2InstructionSelector::selectVSRS(MachineInstr &I,
MachineRegisterInfo &MRI) {

Expand Down Expand Up @@ -2090,84 +2062,6 @@ Register AIE2InstructionSelector::createDSRegSequence(
return MI.getReg(0);
}

// Build Instruction to get control register
bool AIE2InstructionSelector::selectGetControlRegister(
MachineInstr &I, MachineRegisterInfo &MRI) {

Register DstReg = I.getOperand(0).getReg();
// In this case of G_INTRINSIC operand 1 is target intrinsic
Register IdxReg = I.getOperand(2).getReg();
Register CtrlReg;

// Check if the argument is constant for register map index.
if (auto Idx = getIConstantVRegValWithLookThrough(IdxReg, MRI))
CtrlReg = TRI.getControlRegister(Idx->Value.getZExtValue());
else
llvm_unreachable("Expected const value for control register map index.");

if (!RBI.constrainGenericRegister(DstReg, AIE2::eRRegClass, MRI))
return false;

auto CopyInstr =
MIB.buildInstr(TargetOpcode::COPY, {DstReg}, {}).addReg(CtrlReg);
if (!selectCopy(*CopyInstr, MRI)) {
return false;
}
I.eraseFromParent();
return true;
}

// Build Instruction to set control register
bool AIE2InstructionSelector::selectSetControlRegister(
MachineInstr &I, MachineRegisterInfo &MRI) {

Register IdxReg = I.getOperand(1).getReg();
Register SrcReg = I.getOperand(2).getReg();
Register CtrlReg;

// Check if the argument is constant for register map index.
if (auto Idx = getIConstantVRegValWithLookThrough(IdxReg, MRI))
CtrlReg = TRI.getControlRegister(Idx->Value.getZExtValue());
else
llvm_unreachable("Expected const value for control register map index.");

// Handle const input val for control regs.
if (auto Src = getIConstantVRegValWithLookThrough(SrcReg, MRI)) {
unsigned SrcConstVal = Src->Value.getZExtValue();
/* Modulo by width of control regs.
To constrain the max possible value in the register
according to register width.
*/
switch (CtrlReg) {
case AIE2::crSat:
SrcConstVal = SrcConstVal % (1 << 2);
break;
case AIE2::crRnd:
SrcConstVal = SrcConstVal % (1 << 4);
break;
case AIE2::crF2FMask:
case AIE2::crF2IMask:
case AIE2::crFPMask:
SrcConstVal = SrcConstVal % (1 << 5);
break;
default:
break;
}

MachineInstrBuilder MI = setCtrlRegister(MIB, CtrlReg, SrcConstVal);
I.eraseFromParent();
return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
}

auto CopyInstr =
MIB.buildInstr(TargetOpcode::COPY, {CtrlReg}, {}).addReg(SrcReg);
if (!selectCopy(*CopyInstr, MRI))
return false;

I.eraseFromParent();
return true;
}

bool AIE2InstructionSelector::selectWriteTM(MachineInstr &I,
MachineRegisterInfo &MRI) {
Register Value = I.getOperand(1).getReg();
Expand Down
19 changes: 19 additions & 0 deletions llvm/lib/Target/AIE/AIE2RegisterInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,3 +539,22 @@ bool AIE2RegisterInfo::isVecOrAccRegClass(const TargetRegisterClass &RC) const {

return false;
}

unsigned
AIE2RegisterInfo::matchControlRegisterBitwidth(Register CtrlReg,
unsigned SrcConstVal) const {
// Modulo by width of control regs. To constrain the max possible value in
// the register according to register width.
switch (CtrlReg) {
case AIE2::crSat:
return SrcConstVal % (1 << 2);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CHECK: this is mimicking the hardware when it would move it from a register source. To be frank, I would prefer a frontend error on writing an out of bound constant value.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where should the valid range constraints for control registers be enforced, at the intrinsic definition in headers?

case AIE2::crRnd:
return SrcConstVal % (1 << 4);
case AIE2::crF2FMask:
case AIE2::crF2IMask:
case AIE2::crFPMask:
return SrcConstVal % (1 << 5);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we can generalize this using getRegSizeInBits(Reg, MRI)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. It looks as if their size is 32 bit...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right getRegSizeInBits would return 32. However, this function needs the semantic bit width.

default:
llvm_unreachable("Unknown control register.");
}
}
4 changes: 3 additions & 1 deletion llvm/lib/Target/AIE/AIE2RegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ struct AIE2RegisterInfo : public AIE2GenRegisterInfo {
const MachineOperand &MO, const MachineRegisterInfo &MRI) const override;

Register getStackPointerRegister() const override;
Register getControlRegister(unsigned Idx) const;
Register getControlRegister(unsigned Idx) const override;

const TargetRegisterClass *
getLargestLegalSuperClass(const TargetRegisterClass *RC,
Expand Down Expand Up @@ -101,6 +101,8 @@ struct AIE2RegisterInfo : public AIE2GenRegisterInfo {
const TargetRegisterClass *getAddrCountRegClass() const override {
return &AIE2::eDCRegClass;
}
unsigned matchControlRegisterBitwidth(Register CtrlReg,
unsigned SrcConstVal) const override;
};
} // namespace llvm

Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/AIE/AIEBaseInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,12 @@ struct AIEBaseInstrInfo : public TargetInstrInfo {
virtual Register getVaddSignControlRegister() const {
llvm_unreachable("Target didn't implement vaddSign control register");
}
virtual Register getUPSModeControlRegister() const {
llvm_unreachable("Target didn't implement UPSMode control register");
}
virtual Register getUPSSignControlRegister() const {
llvm_unreachable("Target didn't implement UPSSign control register");
}
// Opcodes related to hardware loop handling
virtual bool isHardwareLoopDec(unsigned Opcode) const;
virtual bool isHardwareLoopJNZ(unsigned Opcode) const;
Expand Down
98 changes: 98 additions & 0 deletions llvm/lib/Target/AIE/AIEBaseInstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1046,3 +1046,101 @@ bool AIEBaseInstructionSelector::selectWriteTM(MachineInstr &I,
I.eraseFromParent();
return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
}

// Build Instruction to set control register
bool AIEBaseInstructionSelector::selectSetControlRegister(
MachineInstr &I, MachineRegisterInfo &MRI) {

const Register IdxReg = I.getOperand(1).getReg();
const Register SrcReg = I.getOperand(2).getReg();

// Check if the argument is constant for register map index.
const auto Idx = getIConstantVRegValWithLookThrough(IdxReg, MRI);
if (!Idx)
llvm_unreachable("Expected const value for control register map index.");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getIConstantVRegValWithLookThroughOrFail() could encapsulate the llvm_unreachable.


const Register CtrlReg = TRI.getControlRegister(Idx->Value.getZExtValue());

// Handle const input val for control regs.
if (const auto Src = getIConstantVRegValWithLookThrough(SrcReg, MRI)) {
const unsigned SrcConstVal =
TRI.matchControlRegisterBitwidth(CtrlReg, Src->Value.getZExtValue());

MachineInstrBuilder MI = setCtrlRegister(MIB, CtrlReg, SrcConstVal);
I.eraseFromParent();
return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
}

auto CopyInstr =
MIB.buildInstr(TargetOpcode::COPY, {CtrlReg}, {}).addReg(SrcReg);
if (!selectCopy(*CopyInstr, MRI))
return false;

I.eraseFromParent();
return true;
}

// Build Instruction to get control register
bool AIEBaseInstructionSelector::selectGetControlRegister(
MachineInstr &I, MachineRegisterInfo &MRI) {

const Register DstReg = I.getOperand(0).getReg();
// In this case of G_INTRINSIC operand 1 is target intrinsic
const Register IdxReg = I.getOperand(2).getReg();

// Check if the argument is constant for register map index.
const auto Idx = getIConstantVRegValWithLookThrough(IdxReg, MRI);
if (!Idx)
llvm_unreachable("Expected const value for control register map index.");

const Register CtrlReg = TRI.getControlRegister(Idx->Value.getZExtValue());
const MachineFunction &MF = *I.getParent()->getParent();

if (!RBI.constrainGenericRegister(DstReg, *TRI.getGPRRegClass(MF), MRI))
return false;

auto CopyInstr =
MIB.buildInstr(TargetOpcode::COPY, {DstReg}, {}).addReg(CtrlReg);
if (!selectCopy(*CopyInstr, MRI))
return false;

I.eraseFromParent();
return true;
}

bool AIEBaseInstructionSelector::selectVUPS(
MachineInstr &I, MachineRegisterInfo &MRI,
std::optional<unsigned> crUPSModeVal) {
// First try to match UPS combine
if (selectG_AIE_LOAD_UPS(I, MRI, crUPSModeVal))
return true;

// TODO Match UPS combine
const Register DstReg = I.getOperand(0).getReg();
// In this case of G_INTRINSIC_W_SIDE_EFFECTS operand 1 is target intrinsic
const Register SrcReg = I.getOperand(2).getReg();
const Register ShftReg = I.getOperand(3).getReg();
const Register SignReg = I.getOperand(4).getReg();

if (crUPSModeVal.has_value()) {
// Selects the mode of the accumulator for UPS instructions
// 0 – 32-bit accumulator lane
// 1 – 64-bit accumulator lane
MIB.setInstr(I);
setCtrlRegister(MIB, TII.getUPSModeControlRegister(), *crUPSModeVal);
}

if (const auto SignVal = getIConstantVRegValWithLookThrough(SignReg, MRI)) {
// Handle constant sign through instruction patterns
return selectImpl(I, *CoverageInfo);
}

const unsigned OpCode = TII.getOpCode(I);
MachineInstrBuilder MI =
MIB.buildInstr(OpCode, {DstReg}, {}).addReg(SrcReg).addReg(ShftReg);

setUnsetCtrlRegister(MIB, *MI, MRI, TII.getUPSSignControlRegister(), SignReg);

I.eraseFromParent();
return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
}
9 changes: 9 additions & 0 deletions llvm/lib/Target/AIE/AIEBaseInstructionSelector.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,15 @@ class AIEBaseInstructionSelector : public InstructionSelector {
bool selectG_AIE_LOAD_CONV(MachineInstr &CONVI, MachineRegisterInfo &MRI);
bool selectVCONV(MachineInstr &I, MachineRegisterInfo &MRI);
bool selectStartLoop(MachineInstr &I, MachineRegisterInfo &MRI);
bool selectSetControlRegister(MachineInstr &I, MachineRegisterInfo &MRI);
bool selectGetControlRegister(MachineInstr &I, MachineRegisterInfo &MRI);
bool selectVUPS(MachineInstr &I, MachineRegisterInfo &MRI,
std::optional<unsigned> crUPSModeVal = std::nullopt);
virtual bool selectG_AIE_LOAD_UPS(MachineInstr &StoreI,
MachineRegisterInfo &MRI,
std::optional<unsigned> crUPSModeVal) {
return false;
}

protected:
MachineIRBuilder MIB;
Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/Target/AIE/AIEBaseRegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,14 @@ struct AIEBaseRegisterInfo : public TargetRegisterInfo {
unsigned SubReg, const TargetRegisterClass *DstRC,
unsigned DstSubReg, const TargetRegisterClass *NewRC,
LiveIntervals &LIS) const override;

virtual unsigned matchControlRegisterBitwidth(Register CtrlReg,
unsigned SrcConstVal) const {
llvm_unreachable("Target didn't implement matchControlRegisterBitwidth!");
}
virtual Register getControlRegister(unsigned Idx) const {
llvm_unreachable("Target didn't implement getControlRegister!");
}
};

template <int N, unsigned step> bool isEncodableAsNegativeInt(int Value) {
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/AIE/aie2p/AIE2PInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,12 @@ unsigned AIE2PInstrInfo::getOpCode(MachineInstr &I) const {
Register AIE2PInstrInfo::getVaddSignControlRegister() const {
return AIE2P::vaddSign0;
}
Register AIE2PInstrInfo::getUPSModeControlRegister() const {
return AIE2P::crUPSMode;
}
Register AIE2PInstrInfo::getUPSSignControlRegister() const {
return AIE2P::upsSign0;
}

// Implement CopyToReg/CopyFromReg
void AIE2PInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/AIE/aie2p/AIE2PInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ class AIE2PInstrInfo : public AIE2PGenInstrInfo {
getStoreFlushConvOpcode(unsigned StoreFlushOpcode) const override;
unsigned getOpCode(MachineInstr &MI) const override;
Register getVaddSignControlRegister() const override;
Register getUPSModeControlRegister() const override;
Register getUPSSignControlRegister() const override;

virtual std::optional<ZOLSupport> getZOLSupport() const override;
virtual std::optional<JNZDSupport> getJNZDSupport() const override;
Expand Down
Loading