aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/RISCV/MCA/RISCVCustomBehaviour.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/RISCV/MCA/RISCVCustomBehaviour.cpp')
-rw-r--r--llvm/lib/Target/RISCV/MCA/RISCVCustomBehaviour.cpp202
1 files changed, 159 insertions, 43 deletions
diff --git a/llvm/lib/Target/RISCV/MCA/RISCVCustomBehaviour.cpp b/llvm/lib/Target/RISCV/MCA/RISCVCustomBehaviour.cpp
index 277b976b313a..8f8684e30b3a 100644
--- a/llvm/lib/Target/RISCV/MCA/RISCVCustomBehaviour.cpp
+++ b/llvm/lib/Target/RISCV/MCA/RISCVCustomBehaviour.cpp
@@ -13,6 +13,7 @@
#include "RISCVCustomBehaviour.h"
#include "MCTargetDesc/RISCVMCTargetDesc.h"
+#include "RISCV.h"
#include "RISCVInstrInfo.h"
#include "TargetInfo/RISCVTargetInfo.h"
#include "llvm/MC/TargetRegistry.h"
@@ -31,6 +32,7 @@ struct PseudoInfo {
uint16_t Pseudo;
uint16_t BaseInstr;
uint8_t VLMul;
+ uint8_t SEW;
};
#define GET_RISCVVInversePseudosTable_IMPL
@@ -56,7 +58,7 @@ uint8_t RISCVLMULInstrument::getLMUL() const {
// below
assert(isDataValid(getData()) &&
"Cannot get LMUL because invalid Data value");
- // These are the LMUL values that are used in RISCV tablegen
+ // These are the LMUL values that are used in RISC-V tablegen
return StringSwitch<uint8_t>(getData())
.Case("M1", 0b000)
.Case("M2", 0b001)
@@ -67,64 +69,178 @@ uint8_t RISCVLMULInstrument::getLMUL() const {
.Case("MF8", 0b111);
}
+const llvm::StringRef RISCVSEWInstrument::DESC_NAME = "RISCV-SEW";
+
+bool RISCVSEWInstrument::isDataValid(llvm::StringRef Data) {
+ // Return true if not one of the valid SEW strings
+ return StringSwitch<bool>(Data)
+ .Cases("E8", "E16", "E32", "E64", true)
+ .Default(false);
+}
+
+uint8_t RISCVSEWInstrument::getSEW() const {
+ // assertion prevents us from needing llvm_unreachable in the StringSwitch
+ // below
+ assert(isDataValid(getData()) && "Cannot get SEW because invalid Data value");
+ // These are the LMUL values that are used in RISC-V tablegen
+ return StringSwitch<uint8_t>(getData())
+ .Case("E8", 8)
+ .Case("E16", 16)
+ .Case("E32", 32)
+ .Case("E64", 64);
+}
+
bool RISCVInstrumentManager::supportsInstrumentType(
llvm::StringRef Type) const {
- // Currently, only support for RISCVLMULInstrument type
- return Type == RISCVLMULInstrument::DESC_NAME;
+ return Type == RISCVLMULInstrument::DESC_NAME ||
+ Type == RISCVSEWInstrument::DESC_NAME;
}
-SharedInstrument
+UniqueInstrument
RISCVInstrumentManager::createInstrument(llvm::StringRef Desc,
llvm::StringRef Data) {
- if (Desc != RISCVLMULInstrument::DESC_NAME) {
- LLVM_DEBUG(dbgs() << "RVCB: Unknown instrumentation Desc: " << Desc
- << '\n');
- return nullptr;
+ if (Desc == RISCVLMULInstrument::DESC_NAME) {
+ if (!RISCVLMULInstrument::isDataValid(Data)) {
+ LLVM_DEBUG(dbgs() << "RVCB: Bad data for instrument kind " << Desc << ": "
+ << Data << '\n');
+ return nullptr;
+ }
+ return std::make_unique<RISCVLMULInstrument>(Data);
+ }
+
+ if (Desc == RISCVSEWInstrument::DESC_NAME) {
+ if (!RISCVSEWInstrument::isDataValid(Data)) {
+ LLVM_DEBUG(dbgs() << "RVCB: Bad data for instrument kind " << Desc << ": "
+ << Data << '\n');
+ return nullptr;
+ }
+ return std::make_unique<RISCVSEWInstrument>(Data);
}
- if (RISCVLMULInstrument::isDataValid(Data)) {
- LLVM_DEBUG(dbgs() << "RVCB: Bad data for instrument kind " << Desc << ": "
- << Data << '\n');
- return nullptr;
+
+ LLVM_DEBUG(dbgs() << "RVCB: Unknown instrumentation Desc: " << Desc << '\n');
+ return nullptr;
+}
+
+SmallVector<UniqueInstrument>
+RISCVInstrumentManager::createInstruments(const MCInst &Inst) {
+ if (Inst.getOpcode() == RISCV::VSETVLI ||
+ Inst.getOpcode() == RISCV::VSETIVLI) {
+ LLVM_DEBUG(dbgs() << "RVCB: Found VSETVLI and creating instrument for it: "
+ << Inst << "\n");
+ unsigned VTypeI = Inst.getOperand(2).getImm();
+ RISCVII::VLMUL VLMUL = RISCVVType::getVLMUL(VTypeI);
+
+ StringRef LMUL;
+ switch (VLMUL) {
+ case RISCVII::LMUL_1:
+ LMUL = "M1";
+ break;
+ case RISCVII::LMUL_2:
+ LMUL = "M2";
+ break;
+ case RISCVII::LMUL_4:
+ LMUL = "M4";
+ break;
+ case RISCVII::LMUL_8:
+ LMUL = "M8";
+ break;
+ case RISCVII::LMUL_F2:
+ LMUL = "MF2";
+ break;
+ case RISCVII::LMUL_F4:
+ LMUL = "MF4";
+ break;
+ case RISCVII::LMUL_F8:
+ LMUL = "MF8";
+ break;
+ case RISCVII::LMUL_RESERVED:
+ llvm_unreachable("Cannot create instrument for LMUL_RESERVED");
+ }
+ SmallVector<UniqueInstrument> Instruments;
+ Instruments.emplace_back(
+ createInstrument(RISCVLMULInstrument::DESC_NAME, LMUL));
+
+ unsigned SEW = RISCVVType::getSEW(VTypeI);
+ StringRef SEWStr;
+ switch (SEW) {
+ case 8:
+ SEWStr = "E8";
+ break;
+ case 16:
+ SEWStr = "E16";
+ break;
+ case 32:
+ SEWStr = "E32";
+ break;
+ case 64:
+ SEWStr = "E64";
+ break;
+ default:
+ llvm_unreachable("Cannot create instrument for SEW");
+ }
+ Instruments.emplace_back(
+ createInstrument(RISCVSEWInstrument::DESC_NAME, SEWStr));
+
+ return Instruments;
}
- return std::make_shared<RISCVLMULInstrument>(Data);
+ return SmallVector<UniqueInstrument>();
}
unsigned RISCVInstrumentManager::getSchedClassID(
const MCInstrInfo &MCII, const MCInst &MCI,
- const llvm::SmallVector<SharedInstrument> &IVec) const {
+ const llvm::SmallVector<Instrument *> &IVec) const {
unsigned short Opcode = MCI.getOpcode();
unsigned SchedClassID = MCII.get(Opcode).getSchedClass();
- for (const auto &I : IVec) {
- // Unknown Instrument kind
- if (I->getDesc() == RISCVLMULInstrument::DESC_NAME) {
- uint8_t LMUL = static_cast<RISCVLMULInstrument *>(I.get())->getLMUL();
- const RISCVVInversePseudosTable::PseudoInfo *RVV =
- RISCVVInversePseudosTable::getBaseInfo(Opcode, LMUL);
- // Not a RVV instr
- if (!RVV) {
- LLVM_DEBUG(
- dbgs()
- << "RVCB: Could not find PseudoInstruction for Opcode "
- << MCII.getName(Opcode) << ", LMUL=" << I->getData()
- << ". Ignoring instrumentation and using original SchedClassID="
- << SchedClassID << '\n');
- return SchedClassID;
- }
-
- // Override using pseudo
- LLVM_DEBUG(dbgs() << "RVCB: Found Pseudo Instruction for Opcode "
- << MCII.getName(Opcode) << ", LMUL=" << I->getData()
- << ". Overriding original SchedClassID=" << SchedClassID
- << " with " << MCII.getName(RVV->Pseudo) << '\n');
- return MCII.get(RVV->Pseudo).getSchedClass();
- }
+ // Unpack all possible RISCV instruments from IVec.
+ RISCVLMULInstrument *LI = nullptr;
+ RISCVSEWInstrument *SI = nullptr;
+ for (auto &I : IVec) {
+ if (I->getDesc() == RISCVLMULInstrument::DESC_NAME)
+ LI = static_cast<RISCVLMULInstrument *>(I);
+ else if (I->getDesc() == RISCVSEWInstrument::DESC_NAME)
+ SI = static_cast<RISCVSEWInstrument *>(I);
+ }
+
+ // Need LMUL or LMUL, SEW in order to override opcode. If no LMUL is provided,
+ // then no option to override.
+ if (!LI) {
+ LLVM_DEBUG(
+ dbgs() << "RVCB: Did not use instrumentation to override Opcode.\n");
+ return SchedClassID;
+ }
+ uint8_t LMUL = LI->getLMUL();
+
+ // getBaseInfo works with (Opcode, LMUL, 0) if no SEW instrument,
+ // or (Opcode, LMUL, SEW) if SEW instrument is active, and depends on LMUL
+ // and SEW, or (Opcode, LMUL, 0) if does not depend on SEW.
+ uint8_t SEW = SI ? SI->getSEW() : 0;
+ // Check if it depends on LMUL and SEW
+ const RISCVVInversePseudosTable::PseudoInfo *RVV =
+ RISCVVInversePseudosTable::getBaseInfo(Opcode, LMUL, SEW);
+ // Check if it depends only on LMUL
+ if (!RVV)
+ RVV = RISCVVInversePseudosTable::getBaseInfo(Opcode, LMUL, 0);
+
+ // Not a RVV instr
+ if (!RVV) {
+ LLVM_DEBUG(
+ dbgs() << "RVCB: Could not find PseudoInstruction for Opcode "
+ << MCII.getName(Opcode)
+ << ", LMUL=" << (LI ? LI->getData() : "Unspecified")
+ << ", SEW=" << (SI ? SI->getData() : "Unspecified")
+ << ". Ignoring instrumentation and using original SchedClassID="
+ << SchedClassID << '\n');
+ return SchedClassID;
}
- // Unknown Instrument kind
- LLVM_DEBUG(
- dbgs() << "RVCB: Did not use instrumentation to override Opcode.\n");
- return SchedClassID;
+ // Override using pseudo
+ LLVM_DEBUG(dbgs() << "RVCB: Found Pseudo Instruction for Opcode "
+ << MCII.getName(Opcode) << ", LMUL=" << LI->getData()
+ << ", SEW=" << (SI ? SI->getData() : "Unspecified")
+ << ". Overriding original SchedClassID=" << SchedClassID
+ << " with " << MCII.getName(RVV->Pseudo) << '\n');
+ return MCII.get(RVV->Pseudo).getSchedClass();
}
} // namespace mca
@@ -139,7 +255,7 @@ createRISCVInstrumentManager(const MCSubtargetInfo &STI,
return new RISCVInstrumentManager(STI, MCII);
}
-/// Extern function to initialize the targets for the RISCV backend
+/// Extern function to initialize the targets for the RISC-V backend
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTargetMCA() {
TargetRegistry::RegisterInstrumentManager(getTheRISCV32Target(),
createRISCVInstrumentManager);