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(Triple: TheTriple.getTriple(), 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 StringRef TripleName = TheTriple.getTriple();
35
36 STI.reset(p: TheTarget->createMCSubtargetInfo(TheTriple: TripleName, CPU: CPUName, Features: MAttr));
37 ASSERT_TRUE(STI);
38 ASSERT_TRUE(STI->isCPUStringValid(CPUName));
39
40 MRI.reset(p: TheTarget->createMCRegInfo(TT: TripleName));
41 ASSERT_TRUE(MRI);
42
43 auto MCOptions = getMCTargetOptions();
44 MAI.reset(p: TheTarget->createMCAsmInfo(MRI: *MRI, TheTriple: TripleName, Options: MCOptions));
45 ASSERT_TRUE(MAI);
46
47 Ctx = std::make_unique<MCContext>(args: TheTriple, args: MAI.get(), args: MRI.get(), args: STI.get());
48 MOFI.reset(p: TheTarget->createMCObjectFileInfo(Ctx&: *Ctx, /*PIC=*/false));
49 Ctx->setObjectFileInfo(MOFI.get());
50
51 MCII.reset(p: TheTarget->createMCInstrInfo());
52 ASSERT_TRUE(MCII);
53
54 MCIA.reset(p: TheTarget->createMCInstrAnalysis(Info: MCII.get()));
55 ASSERT_TRUE(MCIA);
56
57 IP.reset(p: TheTarget->createMCInstPrinter(T: TheTriple, /*AssemblerDialect=*/SyntaxVariant: 0,
58 MAI: *MAI, MII: *MCII, MRI: *MRI));
59 ASSERT_TRUE(IP);
60}
61
62Error MCATestBase::runBaselineMCA(json::Object &Result, ArrayRef<MCInst> Insts,
63 ArrayRef<mca::View *> Views,
64 const mca::PipelineOptions *PO) {
65 mca::Context MCA(*MRI, *STI);
66
67 // Default InstrumentManager
68 auto IM = std::make_unique<mca::InstrumentManager>(args&: *STI, args&: *MCII);
69 mca::InstrBuilder IB(*STI, *MCII, *MRI, MCIA.get(), *IM);
70
71 const SmallVector<mca::Instrument *> Instruments;
72 SmallVector<std::unique_ptr<mca::Instruction>> LoweredInsts;
73 for (const auto &MCI : Insts) {
74 Expected<std::unique_ptr<mca::Instruction>> Inst =
75 IB.createInstruction(MCI, IVec: Instruments);
76 if (!Inst) {
77 if (auto NewE =
78 handleErrors(E: Inst.takeError(),
79 Hs: [this](const mca::InstructionError<MCInst> &IE) {
80 std::string InstructionStr;
81 raw_string_ostream SS(InstructionStr);
82 WithColor::error() << IE.Message << '\n';
83 IP->printInst(MI: &IE.Inst, Address: 0, Annot: "", STI: *STI, OS&: SS);
84 WithColor::note()
85 << "instruction: " << InstructionStr << '\n';
86 })) {
87 // Default case.
88 return NewE;
89 }
90 } else {
91 LoweredInsts.emplace_back(Args: std::move(Inst.get()));
92 }
93 }
94
95 mca::CircularSourceMgr SM(LoweredInsts, /*Iterations=*/1);
96
97 // Empty CustomBehaviour.
98 auto CB = std::make_unique<mca::CustomBehaviour>(args&: *STI, args&: SM, args&: *MCII);
99
100 mca::PipelineOptions ThePO = PO ? *PO : getDefaultPipelineOptions();
101 auto P = MCA.createDefaultPipeline(Opts: ThePO, SrcMgr&: SM, CB&: *CB);
102
103 SmallVector<std::unique_ptr<mca::View>, 1> DefaultViews;
104 if (Views.empty()) {
105 // By default, we only add SummaryView.
106 auto SV = std::make_unique<SummaryView>(args: STI->getSchedModel(), args&: Insts,
107 args&: ThePO.DispatchWidth);
108 P->addEventListener(Listener: SV.get());
109 DefaultViews.emplace_back(Args: std::move(SV));
110 } else {
111 for (auto *V : Views)
112 P->addEventListener(Listener: V);
113 }
114
115 // Run the pipeline.
116 Expected<unsigned> Cycles = P->run();
117 if (!Cycles)
118 return Cycles.takeError();
119
120 for (const auto *V : Views)
121 Result[V->getNameAsString()] = V->toJSON();
122 for (const auto &V : DefaultViews)
123 Result[V->getNameAsString()] = V->toJSON();
124
125 return Error::success();
126}
127

source code of llvm/unittests/tools/llvm-mca/MCATestBase.cpp