Skip to content
Merged
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
65 changes: 31 additions & 34 deletions llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,6 @@ static bool isVectorRegClass(Register R, const MachineRegisterInfo *MRI) {

/// Represents the EMUL and EEW of a MachineOperand.
struct OperandInfo {
enum class State {
Unknown,
Known,
} S;

// Represent as 1,2,4,8, ... and fractional indicator. This is because
// EMUL can take on values that don't map to RISCVII::VLMUL values exactly.
// For example, a mask operand can have an EMUL less than MF8.
Expand All @@ -92,41 +87,32 @@ struct OperandInfo {
unsigned Log2EEW;

OperandInfo(RISCVII::VLMUL EMUL, unsigned Log2EEW)
: S(State::Known), EMUL(RISCVVType::decodeVLMUL(EMUL)), Log2EEW(Log2EEW) {
}
: EMUL(RISCVVType::decodeVLMUL(EMUL)), Log2EEW(Log2EEW) {}

OperandInfo(std::pair<unsigned, bool> EMUL, unsigned Log2EEW)
: S(State::Known), EMUL(EMUL), Log2EEW(Log2EEW) {}

OperandInfo(unsigned Log2EEW) : S(State::Known), Log2EEW(Log2EEW) {}
: EMUL(EMUL), Log2EEW(Log2EEW) {}

OperandInfo() : S(State::Unknown) {}
OperandInfo(unsigned Log2EEW) : Log2EEW(Log2EEW) {}

bool isUnknown() const { return S == State::Unknown; }
bool isKnown() const { return S == State::Known; }
OperandInfo() = delete;

static bool EMULAndEEWAreEqual(const OperandInfo &A, const OperandInfo &B) {
assert(A.isKnown() && B.isKnown() && "Both operands must be known");

return A.Log2EEW == B.Log2EEW && A.EMUL->first == B.EMUL->first &&
A.EMUL->second == B.EMUL->second;
}

static bool EEWAreEqual(const OperandInfo &A, const OperandInfo &B) {
assert(A.isKnown() && B.isKnown() && "Both operands must be known");
return A.Log2EEW == B.Log2EEW;
}

void print(raw_ostream &OS) const {
if (isUnknown()) {
OS << "Unknown";
return;
}
assert(EMUL && "Expected EMUL to have value");
OS << "EMUL: m";
if (EMUL->second)
OS << "f";
OS << EMUL->first;
if (EMUL) {
OS << "EMUL: m";
if (EMUL->second)
OS << "f";
OS << EMUL->first;
} else
OS << "EMUL: unknown\n";
OS << ", EEW: " << (1 << Log2EEW);
}
};
Expand All @@ -137,6 +123,16 @@ static raw_ostream &operator<<(raw_ostream &OS, const OperandInfo &OI) {
return OS;
}

LLVM_ATTRIBUTE_UNUSED
static raw_ostream &operator<<(raw_ostream &OS,
const std::optional<OperandInfo> &OI) {
if (OI)
OI->print(OS);
else
OS << "nullopt";
return OS;
}

namespace llvm {
namespace RISCVVType {
/// Return EMUL = (EEW / SEW) * LMUL where EEW comes from Log2EEW and LMUL and
Expand Down Expand Up @@ -715,20 +711,20 @@ getOperandLog2EEW(const MachineOperand &MO, const MachineRegisterInfo *MRI) {
}

default:
return {};
return std::nullopt;
}
}

static OperandInfo getOperandInfo(const MachineOperand &MO,
const MachineRegisterInfo *MRI) {
static std::optional<OperandInfo>
getOperandInfo(const MachineOperand &MO, const MachineRegisterInfo *MRI) {
const MachineInstr &MI = *MO.getParent();
const RISCVVPseudosTable::PseudoInfo *RVV =
RISCVVPseudosTable::getPseudoInfo(MI.getOpcode());
assert(RVV && "Could not find MI in PseudoTable");

std::optional<unsigned> Log2EEW = getOperandLog2EEW(MO, MRI);
if (!Log2EEW)
return {};
return std::nullopt;

switch (RVV->BaseInstr) {
// Vector Reduction Operations
Expand Down Expand Up @@ -1185,9 +1181,10 @@ std::optional<MachineOperand> RISCVVLOptimizer::checkUsers(MachineInstr &MI) {
return std::nullopt;
}

OperandInfo ConsumerInfo = getOperandInfo(UserOp, MRI);
OperandInfo ProducerInfo = getOperandInfo(MI.getOperand(0), MRI);
if (ConsumerInfo.isUnknown() || ProducerInfo.isUnknown()) {
std::optional<OperandInfo> ConsumerInfo = getOperandInfo(UserOp, MRI);
std::optional<OperandInfo> ProducerInfo =
getOperandInfo(MI.getOperand(0), MRI);
if (!ConsumerInfo || !ProducerInfo) {
LLVM_DEBUG(dbgs() << " Abort due to unknown operand information.\n");
LLVM_DEBUG(dbgs() << " ConsumerInfo is: " << ConsumerInfo << "\n");
LLVM_DEBUG(dbgs() << " ProducerInfo is: " << ProducerInfo << "\n");
Expand All @@ -1198,9 +1195,9 @@ std::optional<MachineOperand> RISCVVLOptimizer::checkUsers(MachineInstr &MI) {
// compatible. Otherwise, the EMUL *and* EEW must be compatible.
bool IsVectorOpUsedAsScalarOp = isVectorOpUsedAsScalarOp(UserOp);
if ((IsVectorOpUsedAsScalarOp &&
!OperandInfo::EEWAreEqual(ConsumerInfo, ProducerInfo)) ||
!OperandInfo::EEWAreEqual(*ConsumerInfo, *ProducerInfo)) ||
(!IsVectorOpUsedAsScalarOp &&
!OperandInfo::EMULAndEEWAreEqual(ConsumerInfo, ProducerInfo))) {
!OperandInfo::EMULAndEEWAreEqual(*ConsumerInfo, *ProducerInfo))) {
LLVM_DEBUG(
dbgs()
<< " Abort due to incompatible information for EMUL or EEW.\n");
Expand Down
Loading