xref: /llvm-project/llvm/unittests/tools/llvm-mca/MCATestBase.cpp (revision 848bef5d8549cdc79bb0eb3c5a8e0495e432b577)
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