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"
15 const Target
*MCATestBase::getLLVMTarget() const {
17 return TargetRegistry::lookupTarget(TheTriple
.getTriple(), Error
);
20 mca::PipelineOptions
MCATestBase::getDefaultPipelineOptions() {
21 mca::PipelineOptions
PO(/*MicroOpQueue=*/0, /*DecoderThroughput=*/0,
23 /*RegisterFileSize=*/0,
24 /*LoadQueueSize=*/0, /*StoreQueueSize=*/0,
25 /*AssumeNoAlias=*/true,
26 /*EnableBottleneckAnalysis=*/false);
30 void MCATestBase::SetUp() {
31 TheTarget
= getLLVMTarget();
32 ASSERT_NE(TheTarget
, nullptr);
34 StringRef TripleName
= TheTriple
.getTriple();
36 STI
.reset(TheTarget
->createMCSubtargetInfo(TripleName
, CPUName
, MAttr
));
38 ASSERT_TRUE(STI
->isCPUStringValid(CPUName
));
40 MRI
.reset(TheTarget
->createMCRegInfo(TripleName
));
43 auto MCOptions
= getMCTargetOptions();
44 MAI
.reset(TheTarget
->createMCAsmInfo(*MRI
, TripleName
, MCOptions
));
47 Ctx
= std::make_unique
<MCContext
>(TheTriple
, MAI
.get(), MRI
.get(), STI
.get());
48 MOFI
.reset(TheTarget
->createMCObjectFileInfo(*Ctx
, /*PIC=*/false));
49 Ctx
->setObjectFileInfo(MOFI
.get());
51 MCII
.reset(TheTarget
->createMCInstrInfo());
54 MCIA
.reset(TheTarget
->createMCInstrAnalysis(MCII
.get()));
57 IP
.reset(TheTarget
->createMCInstPrinter(TheTriple
, /*AssemblerDialect=*/0,
62 Error
MCATestBase::runBaselineMCA(json::Object
&Result
, ArrayRef
<MCInst
> Insts
,
63 ArrayRef
<mca::View
*> Views
,
64 const mca::PipelineOptions
*PO
) {
65 mca::Context
MCA(*MRI
, *STI
);
67 // Default InstrumentManager
68 auto IM
= std::make_unique
<mca::InstrumentManager
>(*STI
, *MCII
);
69 mca::InstrBuilder
IB(*STI
, *MCII
, *MRI
, MCIA
.get(), *IM
, /*CallLatency=*/100);
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
, Instruments
);
78 handleErrors(Inst
.takeError(),
79 [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(&IE
.Inst
, 0, "", *STI
, SS
);
85 << "instruction: " << InstructionStr
<< '\n';
91 LoweredInsts
.emplace_back(std::move(Inst
.get()));
95 mca::CircularSourceMgr
SM(LoweredInsts
, /*Iterations=*/1);
97 // Empty CustomBehaviour.
98 auto CB
= std::make_unique
<mca::CustomBehaviour
>(*STI
, SM
, *MCII
);
100 mca::PipelineOptions ThePO
= PO
? *PO
: getDefaultPipelineOptions();
101 auto P
= MCA
.createDefaultPipeline(ThePO
, SM
, *CB
);
103 SmallVector
<std::unique_ptr
<mca::View
>, 1> DefaultViews
;
105 // By default, we only add SummaryView.
106 auto SV
= std::make_unique
<SummaryView
>(STI
->getSchedModel(), Insts
,
107 ThePO
.DispatchWidth
);
108 P
->addEventListener(SV
.get());
109 DefaultViews
.emplace_back(std::move(SV
));
111 for (auto *V
: Views
)
112 P
->addEventListener(V
);
116 Expected
<unsigned> Cycles
= P
->run();
118 return Cycles
.takeError();
120 for (const auto *V
: Views
)
121 Result
[V
->getNameAsString()] = V
->toJSON();
122 for (const auto &V
: DefaultViews
)
123 Result
[V
->getNameAsString()] = V
->toJSON();
125 return Error::success();