133 lines · cpp
1#include "MCATestBase.h"2#include "Views/SummaryView.h"3#include "llvm/MCA/CustomBehaviour.h"4#include "llvm/MCA/InstrBuilder.h"5#include "llvm/MCA/Pipeline.h"6#include "llvm/MCA/SourceMgr.h"7#include "llvm/MCA/View.h"8#include "llvm/Support/JSON.h"9#include "llvm/Support/WithColor.h"10#include <string>11 12using namespace llvm;13using namespace mca;14 15const Target *MCATestBase::getLLVMTarget() const {16 std::string Error;17 return TargetRegistry::lookupTarget(TheTriple, Error);18}19 20mca::PipelineOptions MCATestBase::getDefaultPipelineOptions() {21 mca::PipelineOptions PO(/*MicroOpQueue=*/0, /*DecoderThroughput=*/0,22 /*DispatchWidth=*/0,23 /*RegisterFileSize=*/0,24 /*LoadQueueSize=*/0, /*StoreQueueSize=*/0,25 /*AssumeNoAlias=*/true,26 /*EnableBottleneckAnalysis=*/false);27 return PO;28}29 30void MCATestBase::SetUp() {31 TheTarget = getLLVMTarget();32 ASSERT_NE(TheTarget, nullptr);33 34 STI.reset(TheTarget->createMCSubtargetInfo(TheTriple, CPUName, MAttr));35 ASSERT_TRUE(STI);36 ASSERT_TRUE(STI->isCPUStringValid(CPUName));37 38 MRI.reset(TheTarget->createMCRegInfo(TheTriple));39 ASSERT_TRUE(MRI);40 41 auto MCOptions = getMCTargetOptions();42 MAI.reset(TheTarget->createMCAsmInfo(*MRI, TheTriple, MCOptions));43 ASSERT_TRUE(MAI);44 45 Ctx = std::make_unique<MCContext>(TheTriple, MAI.get(), MRI.get(), STI.get());46 MOFI.reset(TheTarget->createMCObjectFileInfo(*Ctx, /*PIC=*/false));47 Ctx->setObjectFileInfo(MOFI.get());48 49 MCII.reset(TheTarget->createMCInstrInfo());50 ASSERT_TRUE(MCII);51 52 MCIA.reset(TheTarget->createMCInstrAnalysis(MCII.get()));53 ASSERT_TRUE(MCIA);54 55 IP.reset(TheTarget->createMCInstPrinter(TheTriple, /*AssemblerDialect=*/0,56 *MAI, *MCII, *MRI));57 ASSERT_TRUE(IP);58}59 60Error MCATestBase::runBaselineMCA(61 json::Object &Result, ArrayRef<MCInst> Insts, ArrayRef<mca::View *> Views,62 const mca::PipelineOptions *PO,63 ArrayRef<std::pair<StringRef, StringRef>> Descs) {64 mca::Context MCA(*MRI, *STI);65 66 // Enable instruments when descriptions are provided67 auto IM =68 std::make_unique<mca::InstrumentManager>(*STI, *MCII, !Descs.empty());69 mca::InstrBuilder IB(*STI, *MCII, *MRI, MCIA.get(), *IM, /*CallLatency=*/100);70 71 SmallVector<mca::Instrument *> Instruments;72 SmallVector<mca::UniqueInstrument> InstrumentsOwner;73 for (const auto &Desc : Descs) {74 auto I = IM->createInstrument(Desc.first, Desc.second);75 Instruments.push_back(I.get());76 InstrumentsOwner.push_back(std::move(I));77 }78 SmallVector<std::unique_ptr<mca::Instruction>> LoweredInsts;79 for (const auto &MCI : Insts) {80 Expected<std::unique_ptr<mca::Instruction>> Inst =81 IB.createInstruction(MCI, Instruments);82 if (!Inst) {83 if (auto NewE =84 handleErrors(Inst.takeError(),85 [this](const mca::InstructionError<MCInst> &IE) {86 std::string InstructionStr;87 raw_string_ostream SS(InstructionStr);88 WithColor::error() << IE.Message << '\n';89 IP->printInst(&IE.Inst, 0, "", *STI, SS);90 WithColor::note()91 << "instruction: " << InstructionStr << '\n';92 })) {93 // Default case.94 return NewE;95 }96 } else {97 LoweredInsts.emplace_back(std::move(Inst.get()));98 }99 }100 101 mca::CircularSourceMgr SM(LoweredInsts, /*Iterations=*/1);102 103 // Empty CustomBehaviour.104 auto CB = std::make_unique<mca::CustomBehaviour>(*STI, SM, *MCII);105 106 mca::PipelineOptions ThePO = PO ? *PO : getDefaultPipelineOptions();107 auto P = MCA.createDefaultPipeline(ThePO, SM, *CB);108 109 SmallVector<std::unique_ptr<mca::View>, 1> DefaultViews;110 if (Views.empty()) {111 // By default, we only add SummaryView.112 auto SV = std::make_unique<SummaryView>(STI->getSchedModel(), Insts,113 ThePO.DispatchWidth);114 P->addEventListener(SV.get());115 DefaultViews.emplace_back(std::move(SV));116 } else {117 for (auto *V : Views)118 P->addEventListener(V);119 }120 121 // Run the pipeline.122 Expected<unsigned> Cycles = P->run();123 if (!Cycles)124 return Cycles.takeError();125 126 for (const auto *V : Views)127 Result[V->getNameAsString()] = V->toJSON();128 for (const auto &V : DefaultViews)129 Result[V->getNameAsString()] = V->toJSON();130 131 return Error::success();132}133