40#define DEBUG_TYPE "riscv-vector-peephole"
55 MachineFunctionProperties::Property::IsSSA);
73char RISCVVectorPeephole::ID = 0;
94 if (Def->getOpcode() == RISCV::SLLI) {
95 assert(Def->getOperand(2).getImm() < 64);
96 ScaleFixed <<= Def->getOperand(2).getImm();
97 Def =
MRI->getVRegDef(Def->getOperand(1).getReg());
98 }
else if (Def->getOpcode() == RISCV::SRLI) {
99 assert(Def->getOperand(2).getImm() < 64);
100 ScaleFixed >>= Def->getOperand(2).getImm();
101 Def =
MRI->getVRegDef(Def->getOperand(1).getReg());
104 if (!Def || Def->getOpcode() != RISCV::PseudoReadVLENB)
109 unsigned LMULFixed = LMUL.second ? (8 / LMUL.first) : 8 * LMUL.first;
112 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
114 assert(8 * LMULFixed / SEW > 0);
123 if (ScaleFixed != 8 * LMULFixed / SEW)
131bool RISCVVectorPeephole::isAllOnesMask(
const MachineInstr *MaskDef)
const {
137 MaskDef =
MRI->getVRegDef(SrcReg);
145 case RISCV::PseudoVMSET_M_B1:
146 case RISCV::PseudoVMSET_M_B2:
147 case RISCV::PseudoVMSET_M_B4:
148 case RISCV::PseudoVMSET_M_B8:
149 case RISCV::PseudoVMSET_M_B16:
150 case RISCV::PseudoVMSET_M_B32:
151 case RISCV::PseudoVMSET_M_B64:
160bool RISCVVectorPeephole::convertVMergeToVMv(
MachineInstr &
MI)
const {
161#define CASE_VMERGE_TO_VMV(lmul) \
162 case RISCV::PseudoVMERGE_VVM_##lmul: \
163 NewOpc = RISCV::PseudoVMV_V_V_##lmul; \
166 switch (
MI.getOpcode()) {
178 Register MergeReg =
MI.getOperand(1).getReg();
179 Register FalseReg =
MI.getOperand(2).getReg();
181 if (MergeReg != RISCV::NoRegister &&
TRI->lookThruCopyLike(MergeReg,
MRI) !=
182 TRI->lookThruCopyLike(FalseReg,
MRI))
185 assert(
MI.getOperand(4).isReg() &&
MI.getOperand(4).getReg() == RISCV::V0);
186 if (!isAllOnesMask(V0Defs.lookup(&
MI)))
189 MI.setDesc(
TII->get(NewOpc));
191 MI.tieOperands(0, 1);
198 MRI->recomputeRegClass(
MI.getOperand(0).getReg());
199 MRI->recomputeRegClass(
MI.getOperand(1).getReg());
203bool RISCVVectorPeephole::convertToUnmasked(
MachineInstr &
MI)
const {
205 RISCV::getMaskedPseudoInfo(
MI.getOpcode());
209 if (!isAllOnesMask(V0Defs.lookup(&
MI)))
214 const unsigned Opc =
I->UnmaskedPseudo;
216 [[maybe_unused]]
const bool HasPolicyOp =
223 "Masked and unmasked pseudos are inconsistent");
224 assert(HasPolicyOp == HasPassthru &&
"Unexpected pseudo structure");
231 unsigned MaskOpIdx =
I->MaskOpIdx +
MI.getNumExplicitDefs();
232 MI.removeOperand(MaskOpIdx);
236 MRI->recomputeRegClass(
MI.getOperand(0).getReg());
237 unsigned PassthruOpIdx =
MI.getNumExplicitDefs();
239 if (
MI.getOperand(PassthruOpIdx).getReg() != RISCV::NoRegister)
240 MRI->recomputeRegClass(
MI.getOperand(PassthruOpIdx).getReg());
242 MI.removeOperand(PassthruOpIdx);
253 if (!
ST.hasVInstructions())
256 TII =
ST.getInstrInfo();
258 TRI =
MRI->getTargetRegisterInfo();
260 bool Changed =
false;
272 if (
MI.readsRegister(RISCV::V0,
TRI))
273 V0Defs[&
MI] = CurrentV0Def;
275 if (
MI.definesRegister(RISCV::V0,
TRI))
282 Changed |= convertToVLMAX(
MI);
283 Changed |= convertToUnmasked(
MI);
284 Changed |= convertVMergeToVMv(
MI);
292 return new RISCVVectorPeephole();
unsigned const MachineRegisterInfo * MRI
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
#define CASE_VMERGE_TO_VMV(lmul)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
FunctionPass class - This class is used to implement most global optimizations.
Describe properties that are true of each instruction in the target description file.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
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.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
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.
void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
StringRef - Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ TAIL_UNDISTURBED_MASK_UNDISTURBED
static unsigned getVLOpNum(const MCInstrDesc &Desc)
static VLMUL getLMul(uint64_t TSFlags)
static bool hasVLOp(uint64_t TSFlags)
static bool hasVecPolicyOp(uint64_t TSFlags)
static unsigned getSEWOpNum(const MCInstrDesc &Desc)
static bool hasSEWOp(uint64_t TSFlags)
static bool isFirstDefTiedToFirstUse(const MCInstrDesc &Desc)
std::pair< unsigned, bool > decodeVLMUL(RISCVII::VLMUL VLMUL)
static bool isValidSEW(unsigned SEW)
static constexpr int64_t VLMaxSentinel
This is an optimization pass for GlobalISel generic memory operations.
unsigned M1(unsigned Val)
FunctionPass * createRISCVVectorPeepholePass()