mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-29 00:21:14 +00:00
919382004f
Fixes createInstrument to return instrument when LMUL data is valid, and return nullptr when LMUL data is not valid for RISCV target. Differential Revision: https://reviews.llvm.org/D149068
149 lines
5.0 KiB
C++
149 lines
5.0 KiB
C++
//===------------------- RISCVCustomBehaviour.cpp ---------------*-C++ -* -===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
/// \file
|
|
///
|
|
/// This file implements methods from the RISCVCustomBehaviour class.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "RISCVCustomBehaviour.h"
|
|
#include "MCTargetDesc/RISCVMCTargetDesc.h"
|
|
#include "RISCVInstrInfo.h"
|
|
#include "TargetInfo/RISCVTargetInfo.h"
|
|
#include "llvm/MC/TargetRegistry.h"
|
|
#include "llvm/Support/Debug.h"
|
|
|
|
#define DEBUG_TYPE "llvm-mca-riscv-custombehaviour"
|
|
|
|
// This brings in a table with primary key of
|
|
// base instruction opcode and lmul and maps
|
|
// to the opcode of the pseudo instruction.
|
|
namespace RISCVVInversePseudosTable {
|
|
using namespace llvm;
|
|
using namespace llvm::RISCV;
|
|
|
|
struct PseudoInfo {
|
|
uint16_t Pseudo;
|
|
uint16_t BaseInstr;
|
|
uint8_t VLMul;
|
|
};
|
|
|
|
#define GET_RISCVVInversePseudosTable_IMPL
|
|
#define GET_RISCVVInversePseudosTable_DECL
|
|
#include "RISCVGenSearchableTables.inc"
|
|
|
|
} // end namespace RISCVVInversePseudosTable
|
|
|
|
namespace llvm {
|
|
namespace mca {
|
|
|
|
const llvm::StringRef RISCVLMULInstrument::DESC_NAME = "RISCV-LMUL";
|
|
|
|
bool RISCVLMULInstrument::isDataValid(llvm::StringRef Data) {
|
|
// Return true if not one of the valid LMUL strings
|
|
return StringSwitch<bool>(Data)
|
|
.Cases("M1", "M2", "M4", "M8", "MF2", "MF4", "MF8", true)
|
|
.Default(false);
|
|
}
|
|
|
|
uint8_t RISCVLMULInstrument::getLMUL() const {
|
|
// assertion prevents us from needing llvm_unreachable in the StringSwitch
|
|
// below
|
|
assert(isDataValid(getData()) &&
|
|
"Cannot get LMUL because invalid Data value");
|
|
// These are the LMUL values that are used in RISC-V tablegen
|
|
return StringSwitch<uint8_t>(getData())
|
|
.Case("M1", 0b000)
|
|
.Case("M2", 0b001)
|
|
.Case("M4", 0b010)
|
|
.Case("M8", 0b011)
|
|
.Case("MF2", 0b101)
|
|
.Case("MF4", 0b110)
|
|
.Case("MF8", 0b111);
|
|
}
|
|
|
|
bool RISCVInstrumentManager::supportsInstrumentType(
|
|
llvm::StringRef Type) const {
|
|
// Currently, only support for RISCVLMULInstrument type
|
|
return Type == RISCVLMULInstrument::DESC_NAME;
|
|
}
|
|
|
|
SharedInstrument
|
|
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 (!RISCVLMULInstrument::isDataValid(Data)) {
|
|
LLVM_DEBUG(dbgs() << "RVCB: Bad data for instrument kind " << Desc << ": "
|
|
<< Data << '\n');
|
|
return nullptr;
|
|
}
|
|
return std::make_shared<RISCVLMULInstrument>(Data);
|
|
}
|
|
|
|
unsigned RISCVInstrumentManager::getSchedClassID(
|
|
const MCInstrInfo &MCII, const MCInst &MCI,
|
|
const llvm::SmallVector<SharedInstrument> &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();
|
|
}
|
|
}
|
|
|
|
// Unknown Instrument kind
|
|
LLVM_DEBUG(
|
|
dbgs() << "RVCB: Did not use instrumentation to override Opcode.\n");
|
|
return SchedClassID;
|
|
}
|
|
|
|
} // namespace mca
|
|
} // namespace llvm
|
|
|
|
using namespace llvm;
|
|
using namespace mca;
|
|
|
|
static InstrumentManager *
|
|
createRISCVInstrumentManager(const MCSubtargetInfo &STI,
|
|
const MCInstrInfo &MCII) {
|
|
return new RISCVInstrumentManager(STI, MCII);
|
|
}
|
|
|
|
/// Extern function to initialize the targets for the RISC-V backend
|
|
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTargetMCA() {
|
|
TargetRegistry::RegisterInstrumentManager(getTheRISCV32Target(),
|
|
createRISCVInstrumentManager);
|
|
TargetRegistry::RegisterInstrumentManager(getTheRISCV64Target(),
|
|
createRISCVInstrumentManager);
|
|
}
|