197579dccSMin-Yih Hsu #include "MCATestBase.h"
297579dccSMin-Yih Hsu #include "Views/SummaryView.h"
397579dccSMin-Yih Hsu #include "llvm/MCA/CustomBehaviour.h"
497579dccSMin-Yih Hsu #include "llvm/MCA/InstrBuilder.h"
597579dccSMin-Yih Hsu #include "llvm/MCA/Pipeline.h"
697579dccSMin-Yih Hsu #include "llvm/MCA/SourceMgr.h"
797579dccSMin-Yih Hsu #include "llvm/MCA/View.h"
897579dccSMin-Yih Hsu #include "llvm/Support/JSON.h"
997579dccSMin-Yih Hsu #include "llvm/Support/WithColor.h"
1097579dccSMin-Yih Hsu #include <string>
1197579dccSMin-Yih Hsu
1297579dccSMin-Yih Hsu using namespace llvm;
1397579dccSMin-Yih Hsu using namespace mca;
1497579dccSMin-Yih Hsu
getLLVMTarget() const1597579dccSMin-Yih Hsu const Target *MCATestBase::getLLVMTarget() const {
1697579dccSMin-Yih Hsu std::string Error;
1797579dccSMin-Yih Hsu return TargetRegistry::lookupTarget(TheTriple.getTriple(), Error);
1897579dccSMin-Yih Hsu }
1997579dccSMin-Yih Hsu
getDefaultPipelineOptions()2097579dccSMin-Yih Hsu mca::PipelineOptions MCATestBase::getDefaultPipelineOptions() {
2197579dccSMin-Yih Hsu mca::PipelineOptions PO(/*MicroOpQueue=*/0, /*DecoderThroughput=*/0,
2297579dccSMin-Yih Hsu /*DispatchWidth=*/0,
2397579dccSMin-Yih Hsu /*RegisterFileSize=*/0,
2497579dccSMin-Yih Hsu /*LoadQueueSize=*/0, /*StoreQueueSize=*/0,
2597579dccSMin-Yih Hsu /*AssumeNoAlias=*/true,
2697579dccSMin-Yih Hsu /*EnableBottleneckAnalysis=*/false);
2797579dccSMin-Yih Hsu return PO;
2897579dccSMin-Yih Hsu }
2997579dccSMin-Yih Hsu
SetUp()3097579dccSMin-Yih Hsu void MCATestBase::SetUp() {
3197579dccSMin-Yih Hsu TheTarget = getLLVMTarget();
3297579dccSMin-Yih Hsu ASSERT_NE(TheTarget, nullptr);
3397579dccSMin-Yih Hsu
3497579dccSMin-Yih Hsu StringRef TripleName = TheTriple.getTriple();
3597579dccSMin-Yih Hsu
3697579dccSMin-Yih Hsu STI.reset(TheTarget->createMCSubtargetInfo(TripleName, CPUName, MAttr));
3797579dccSMin-Yih Hsu ASSERT_TRUE(STI);
3897579dccSMin-Yih Hsu ASSERT_TRUE(STI->isCPUStringValid(CPUName));
3997579dccSMin-Yih Hsu
4097579dccSMin-Yih Hsu MRI.reset(TheTarget->createMCRegInfo(TripleName));
4197579dccSMin-Yih Hsu ASSERT_TRUE(MRI);
4297579dccSMin-Yih Hsu
4397579dccSMin-Yih Hsu auto MCOptions = getMCTargetOptions();
4497579dccSMin-Yih Hsu MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
4597579dccSMin-Yih Hsu ASSERT_TRUE(MAI);
4697579dccSMin-Yih Hsu
4797579dccSMin-Yih Hsu Ctx = std::make_unique<MCContext>(TheTriple, MAI.get(), MRI.get(), STI.get());
4897579dccSMin-Yih Hsu MOFI.reset(TheTarget->createMCObjectFileInfo(*Ctx, /*PIC=*/false));
4997579dccSMin-Yih Hsu Ctx->setObjectFileInfo(MOFI.get());
5097579dccSMin-Yih Hsu
5197579dccSMin-Yih Hsu MCII.reset(TheTarget->createMCInstrInfo());
5297579dccSMin-Yih Hsu ASSERT_TRUE(MCII);
5397579dccSMin-Yih Hsu
5497579dccSMin-Yih Hsu MCIA.reset(TheTarget->createMCInstrAnalysis(MCII.get()));
5597579dccSMin-Yih Hsu ASSERT_TRUE(MCIA);
5697579dccSMin-Yih Hsu
5797579dccSMin-Yih Hsu IP.reset(TheTarget->createMCInstPrinter(TheTriple, /*AssemblerDialect=*/0,
5897579dccSMin-Yih Hsu *MAI, *MCII, *MRI));
5997579dccSMin-Yih Hsu ASSERT_TRUE(IP);
6097579dccSMin-Yih Hsu }
6197579dccSMin-Yih Hsu
runBaselineMCA(json::Object & Result,ArrayRef<MCInst> Insts,ArrayRef<mca::View * > Views,const mca::PipelineOptions * PO)6297579dccSMin-Yih Hsu Error MCATestBase::runBaselineMCA(json::Object &Result, ArrayRef<MCInst> Insts,
6397579dccSMin-Yih Hsu ArrayRef<mca::View *> Views,
6497579dccSMin-Yih Hsu const mca::PipelineOptions *PO) {
6597579dccSMin-Yih Hsu mca::Context MCA(*MRI, *STI);
6697579dccSMin-Yih Hsu
6798e342dcSMichael Maitland // Default InstrumentManager
6898e342dcSMichael Maitland auto IM = std::make_unique<mca::InstrumentManager>(*STI, *MCII);
69*848bef5dSChinmay Deshpande mca::InstrBuilder IB(*STI, *MCII, *MRI, MCIA.get(), *IM, /*CallLatency=*/100);
7097579dccSMin-Yih Hsu
7156674e8eSMichael Maitland const SmallVector<mca::Instrument *> Instruments;
7297579dccSMin-Yih Hsu SmallVector<std::unique_ptr<mca::Instruction>> LoweredInsts;
7397579dccSMin-Yih Hsu for (const auto &MCI : Insts) {
7497579dccSMin-Yih Hsu Expected<std::unique_ptr<mca::Instruction>> Inst =
7598e342dcSMichael Maitland IB.createInstruction(MCI, Instruments);
7697579dccSMin-Yih Hsu if (!Inst) {
7797579dccSMin-Yih Hsu if (auto NewE =
7897579dccSMin-Yih Hsu handleErrors(Inst.takeError(),
7997579dccSMin-Yih Hsu [this](const mca::InstructionError<MCInst> &IE) {
8097579dccSMin-Yih Hsu std::string InstructionStr;
8197579dccSMin-Yih Hsu raw_string_ostream SS(InstructionStr);
8297579dccSMin-Yih Hsu WithColor::error() << IE.Message << '\n';
8397579dccSMin-Yih Hsu IP->printInst(&IE.Inst, 0, "", *STI, SS);
8497579dccSMin-Yih Hsu WithColor::note()
8597579dccSMin-Yih Hsu << "instruction: " << InstructionStr << '\n';
8697579dccSMin-Yih Hsu })) {
8797579dccSMin-Yih Hsu // Default case.
881f62e245SMin-Yih Hsu return NewE;
8997579dccSMin-Yih Hsu }
9097579dccSMin-Yih Hsu } else {
9197579dccSMin-Yih Hsu LoweredInsts.emplace_back(std::move(Inst.get()));
9297579dccSMin-Yih Hsu }
9397579dccSMin-Yih Hsu }
9497579dccSMin-Yih Hsu
9597579dccSMin-Yih Hsu mca::CircularSourceMgr SM(LoweredInsts, /*Iterations=*/1);
9697579dccSMin-Yih Hsu
9797579dccSMin-Yih Hsu // Empty CustomBehaviour.
9897579dccSMin-Yih Hsu auto CB = std::make_unique<mca::CustomBehaviour>(*STI, SM, *MCII);
9997579dccSMin-Yih Hsu
10097579dccSMin-Yih Hsu mca::PipelineOptions ThePO = PO ? *PO : getDefaultPipelineOptions();
10197579dccSMin-Yih Hsu auto P = MCA.createDefaultPipeline(ThePO, SM, *CB);
10297579dccSMin-Yih Hsu
10397579dccSMin-Yih Hsu SmallVector<std::unique_ptr<mca::View>, 1> DefaultViews;
10497579dccSMin-Yih Hsu if (Views.empty()) {
10597579dccSMin-Yih Hsu // By default, we only add SummaryView.
10697579dccSMin-Yih Hsu auto SV = std::make_unique<SummaryView>(STI->getSchedModel(), Insts,
10797579dccSMin-Yih Hsu ThePO.DispatchWidth);
10897579dccSMin-Yih Hsu P->addEventListener(SV.get());
10997579dccSMin-Yih Hsu DefaultViews.emplace_back(std::move(SV));
11097579dccSMin-Yih Hsu } else {
11197579dccSMin-Yih Hsu for (auto *V : Views)
11297579dccSMin-Yih Hsu P->addEventListener(V);
11397579dccSMin-Yih Hsu }
11497579dccSMin-Yih Hsu
11597579dccSMin-Yih Hsu // Run the pipeline.
11697579dccSMin-Yih Hsu Expected<unsigned> Cycles = P->run();
11797579dccSMin-Yih Hsu if (!Cycles)
11897579dccSMin-Yih Hsu return Cycles.takeError();
11997579dccSMin-Yih Hsu
12097579dccSMin-Yih Hsu for (const auto *V : Views)
12197579dccSMin-Yih Hsu Result[V->getNameAsString()] = V->toJSON();
12297579dccSMin-Yih Hsu for (const auto &V : DefaultViews)
12397579dccSMin-Yih Hsu Result[V->getNameAsString()] = V->toJSON();
12497579dccSMin-Yih Hsu
12597579dccSMin-Yih Hsu return Error::success();
12697579dccSMin-Yih Hsu }
127