| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| //===-------------------- IncrementalSourceMgr.cpp ------------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| /// | ||
| /// \file | ||
| /// This file defines some implementations for IncrementalSourceMgr. | ||
| /// | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "llvm/MCA/IncrementalSourceMgr.h" | ||
| #ifndef NDEBUG | ||
| #include "llvm/Support/Format.h" | ||
| #endif | ||
|
|
||
| using namespace llvm; | ||
| using namespace llvm::mca; | ||
|
|
||
| void IncrementalSourceMgr::clear() { | ||
| Staging.clear(); | ||
| InstStorage.clear(); | ||
| TotalCounter = 0U; | ||
| EOS = false; | ||
| } | ||
|
|
||
| void IncrementalSourceMgr::updateNext() { | ||
| ++TotalCounter; | ||
| Instruction *I = Staging.front(); | ||
| Staging.pop_front(); | ||
| I->reset(); | ||
|
|
||
| if (InstFreedCB) | ||
| InstFreedCB(I); | ||
| } | ||
|
|
||
| #ifndef NDEBUG | ||
| void IncrementalSourceMgr::printStatistic(raw_ostream &OS) { | ||
| unsigned MaxInstStorageSize = InstStorage.size(); | ||
| if (MaxInstStorageSize <= TotalCounter) { | ||
| auto Ratio = double(MaxInstStorageSize) / double(TotalCounter); | ||
| OS << "Cache ratio = " << MaxInstStorageSize << " / " << TotalCounter | ||
| << llvm::format(" (%.2f%%)", (1.0 - Ratio) * 100.0) << "\n"; | ||
| } else { | ||
| OS << "Error: Number of created instructions " | ||
| << "are larger than the number of issued instructions\n"; | ||
| } | ||
| } | ||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,3 +8,4 @@ add_subdirectory( | |
| llvm-exegesis | ||
| ) | ||
| add_subdirectory(llvm-profgen) | ||
| add_subdirectory(llvm-mca) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| set(LLVM_LINK_COMPONENTS | ||
| MC | ||
| MCA | ||
| Object | ||
| Support | ||
| ) | ||
|
|
||
| set(mca_root ${LLVM_MAIN_SRC_DIR}/tools/llvm-mca) | ||
|
|
||
| set(mca_includes | ||
| ${CMAKE_CURRENT_SOURCE_DIR} | ||
| ${mca_root} | ||
| ) | ||
|
|
||
| # Right now we only need SummaryView. | ||
| set(mca_views_sources | ||
| SummaryView.cpp | ||
| ) | ||
| list(TRANSFORM mca_views_sources PREPEND "${mca_root}/Views/") | ||
|
|
||
| set(mca_sources | ||
| MCATestBase.cpp | ||
| ${mca_views_sources} | ||
| ) | ||
|
|
||
| function(add_llvm_mca_unittest_includes) | ||
| set(mca_includes ${mca_includes} ${ARGV} PARENT_SCOPE) | ||
| endfunction() | ||
|
|
||
| function(add_llvm_mca_unittest_sources) | ||
| set(sources ${ARGV}) | ||
| list(TRANSFORM sources PREPEND "${CMAKE_CURRENT_LIST_DIR}/") | ||
| set(mca_sources ${mca_sources} ${sources} PARENT_SCOPE) | ||
| endfunction() | ||
|
|
||
| function(add_llvm_mca_unittest_link_components comps) | ||
| set(LLVM_LINK_COMPONENTS ${LLVM_LINK_COMPONENTS} ${ARGV} PARENT_SCOPE) | ||
| endfunction() | ||
|
|
||
| if(LLVM_TARGETS_TO_BUILD MATCHES "X86") | ||
| include(X86/CMakeLists.txt) | ||
| endif() | ||
|
|
||
| list(REMOVE_DUPLICATES LLVM_LINK_COMPONENTS) | ||
|
|
||
| include_directories(${mca_includes}) | ||
|
|
||
| add_llvm_target_unittest(LLVMMCATests | ||
| ${mca_sources} | ||
| ) | ||
|
|
||
| set_property(TARGET LLVMMCATests PROPERTY FOLDER "Tests/UnitTests/ToolTests") |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| #include "MCATestBase.h" | ||
| #include "Views/SummaryView.h" | ||
| #include "llvm/MCA/CustomBehaviour.h" | ||
| #include "llvm/MCA/InstrBuilder.h" | ||
| #include "llvm/MCA/Pipeline.h" | ||
| #include "llvm/MCA/SourceMgr.h" | ||
| #include "llvm/MCA/View.h" | ||
| #include "llvm/Support/JSON.h" | ||
| #include "llvm/Support/WithColor.h" | ||
| #include <string> | ||
|
|
||
| using namespace llvm; | ||
| using namespace mca; | ||
|
|
||
| const Target *MCATestBase::getLLVMTarget() const { | ||
| std::string Error; | ||
| return TargetRegistry::lookupTarget(TheTriple.getTriple(), Error); | ||
| } | ||
|
|
||
| mca::PipelineOptions MCATestBase::getDefaultPipelineOptions() { | ||
| mca::PipelineOptions PO(/*MicroOpQueue=*/0, /*DecoderThroughput=*/0, | ||
| /*DispatchWidth=*/0, | ||
| /*RegisterFileSize=*/0, | ||
| /*LoadQueueSize=*/0, /*StoreQueueSize=*/0, | ||
| /*AssumeNoAlias=*/true, | ||
| /*EnableBottleneckAnalysis=*/false); | ||
| return PO; | ||
| } | ||
|
|
||
| void MCATestBase::SetUp() { | ||
| TheTarget = getLLVMTarget(); | ||
| ASSERT_NE(TheTarget, nullptr); | ||
|
|
||
| StringRef TripleName = TheTriple.getTriple(); | ||
|
|
||
| STI.reset(TheTarget->createMCSubtargetInfo(TripleName, CPUName, MAttr)); | ||
| ASSERT_TRUE(STI); | ||
| ASSERT_TRUE(STI->isCPUStringValid(CPUName)); | ||
|
|
||
| MRI.reset(TheTarget->createMCRegInfo(TripleName)); | ||
| ASSERT_TRUE(MRI); | ||
|
|
||
| auto MCOptions = getMCTargetOptions(); | ||
| MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions)); | ||
| ASSERT_TRUE(MAI); | ||
|
|
||
| Ctx = std::make_unique<MCContext>(TheTriple, MAI.get(), MRI.get(), STI.get()); | ||
| MOFI.reset(TheTarget->createMCObjectFileInfo(*Ctx, /*PIC=*/false)); | ||
| Ctx->setObjectFileInfo(MOFI.get()); | ||
|
|
||
| MCII.reset(TheTarget->createMCInstrInfo()); | ||
| ASSERT_TRUE(MCII); | ||
|
|
||
| MCIA.reset(TheTarget->createMCInstrAnalysis(MCII.get())); | ||
| ASSERT_TRUE(MCIA); | ||
|
|
||
| IP.reset(TheTarget->createMCInstPrinter(TheTriple, /*AssemblerDialect=*/0, | ||
| *MAI, *MCII, *MRI)); | ||
| ASSERT_TRUE(IP); | ||
| } | ||
|
|
||
| Error MCATestBase::runBaselineMCA(json::Object &Result, ArrayRef<MCInst> Insts, | ||
| ArrayRef<mca::View *> Views, | ||
| const mca::PipelineOptions *PO) { | ||
| mca::Context MCA(*MRI, *STI); | ||
|
|
||
| mca::InstrBuilder IB(*STI, *MCII, *MRI, MCIA.get()); | ||
|
|
||
| SmallVector<std::unique_ptr<mca::Instruction>> LoweredInsts; | ||
| for (const auto &MCI : Insts) { | ||
| Expected<std::unique_ptr<mca::Instruction>> Inst = | ||
| IB.createInstruction(MCI); | ||
| if (!Inst) { | ||
| if (auto NewE = | ||
| handleErrors(Inst.takeError(), | ||
| [this](const mca::InstructionError<MCInst> &IE) { | ||
| std::string InstructionStr; | ||
| raw_string_ostream SS(InstructionStr); | ||
| WithColor::error() << IE.Message << '\n'; | ||
| IP->printInst(&IE.Inst, 0, "", *STI, SS); | ||
| WithColor::note() | ||
| << "instruction: " << InstructionStr << '\n'; | ||
| })) { | ||
| // Default case. | ||
| return std::move(NewE); | ||
| } | ||
| } else { | ||
| LoweredInsts.emplace_back(std::move(Inst.get())); | ||
| } | ||
| } | ||
|
|
||
| mca::CircularSourceMgr SM(LoweredInsts, /*Iterations=*/1); | ||
|
|
||
| // Empty CustomBehaviour. | ||
| auto CB = std::make_unique<mca::CustomBehaviour>(*STI, SM, *MCII); | ||
|
|
||
| mca::PipelineOptions ThePO = PO ? *PO : getDefaultPipelineOptions(); | ||
| auto P = MCA.createDefaultPipeline(ThePO, SM, *CB); | ||
|
|
||
| SmallVector<std::unique_ptr<mca::View>, 1> DefaultViews; | ||
| if (Views.empty()) { | ||
| // By default, we only add SummaryView. | ||
| auto SV = std::make_unique<SummaryView>(STI->getSchedModel(), Insts, | ||
| ThePO.DispatchWidth); | ||
| P->addEventListener(SV.get()); | ||
| DefaultViews.emplace_back(std::move(SV)); | ||
| } else { | ||
| for (auto *V : Views) | ||
| P->addEventListener(V); | ||
| } | ||
|
|
||
| // Run the pipeline. | ||
| Expected<unsigned> Cycles = P->run(); | ||
| if (!Cycles) | ||
| return Cycles.takeError(); | ||
|
|
||
| for (const auto *V : Views) | ||
| Result[V->getNameAsString()] = V->toJSON(); | ||
| for (const auto &V : DefaultViews) | ||
| Result[V->getNameAsString()] = V->toJSON(); | ||
|
|
||
| return Error::success(); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| //===---- MCATestBase.h -----------------------------------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // Test fixture common to all MCA tests. | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_UNITTESTS_TOOLS_LLVMMCA_MCATESTBASE_H | ||
| #define LLVM_UNITTESTS_TOOLS_LLVMMCA_MCATESTBASE_H | ||
|
|
||
| #include "llvm/ADT/StringRef.h" | ||
| #include "llvm/ADT/Triple.h" | ||
| #include "llvm/MC/MCAsmInfo.h" | ||
| #include "llvm/MC/MCContext.h" | ||
| #include "llvm/MC/MCInst.h" | ||
| #include "llvm/MC/MCInstPrinter.h" | ||
| #include "llvm/MC/MCInstrAnalysis.h" | ||
| #include "llvm/MC/MCInstrInfo.h" | ||
| #include "llvm/MC/MCObjectFileInfo.h" | ||
| #include "llvm/MC/MCRegisterInfo.h" | ||
| #include "llvm/MC/MCSubtargetInfo.h" | ||
| #include "llvm/MC/MCTargetOptions.h" | ||
| #include "llvm/MC/SubtargetFeature.h" | ||
| #include "llvm/MC/TargetRegistry.h" | ||
| #include "llvm/MCA/Context.h" | ||
|
|
||
| #include "gtest/gtest.h" | ||
|
|
||
| namespace llvm { | ||
| namespace json { | ||
| class Object; | ||
| } // end namespace json | ||
|
|
||
| namespace mca { | ||
| class View; | ||
|
|
||
| class MCATestBase : public ::testing::Test { | ||
| protected: | ||
| // Note: Subclass ctors are expected to perform target-specific | ||
| // initializations. | ||
| MCATestBase(StringRef TripleStr, StringRef CPUName, StringRef MAttr = "") | ||
| : TheTriple(TripleStr), CPUName(CPUName), MAttr(MAttr) {} | ||
|
|
||
| /// Factory function to create a Target. | ||
| virtual const Target *getLLVMTarget() const; | ||
|
|
||
| /// Factory function to create a MCTargetOptions instance. Returns an | ||
| /// empty one by default. | ||
| virtual MCTargetOptions getMCTargetOptions() { return MCTargetOptions(); } | ||
|
|
||
| const Target *TheTarget; | ||
| const Triple TheTriple; | ||
| StringRef CPUName; | ||
| StringRef MAttr; | ||
|
|
||
| // MC components. | ||
| std::unique_ptr<MCSubtargetInfo> STI; | ||
| std::unique_ptr<MCRegisterInfo> MRI; | ||
| std::unique_ptr<MCAsmInfo> MAI; | ||
| std::unique_ptr<MCObjectFileInfo> MOFI; | ||
| std::unique_ptr<MCContext> Ctx; | ||
| std::unique_ptr<MCInstrInfo> MCII; | ||
| std::unique_ptr<MCInstrAnalysis> MCIA; | ||
| std::unique_ptr<MCInstPrinter> IP; | ||
|
|
||
| static mca::PipelineOptions getDefaultPipelineOptions(); | ||
|
|
||
| void SetUp() override; | ||
|
|
||
| /// Utility function to run MCA with (nearly) the same configuration as the | ||
| /// `llvm-mca` tool to verify result correctness. | ||
| /// This function only displays on SummaryView by default. | ||
| virtual Error runBaselineMCA(json::Object &Result, ArrayRef<MCInst> Insts, | ||
| ArrayRef<mca::View *> Views = None, | ||
| const mca::PipelineOptions *PO = nullptr); | ||
| }; | ||
|
|
||
| } // end namespace mca | ||
| } // end namespace llvm | ||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| add_llvm_mca_unittest_includes( | ||
| ${LLVM_MAIN_SRC_DIR}/lib/Target/X86 | ||
| ${LLVM_BINARY_DIR}/lib/Target/X86 | ||
| ) | ||
|
|
||
| add_llvm_mca_unittest_sources( | ||
| TestIncrementalMCA.cpp | ||
| X86TestBase.cpp | ||
| ) | ||
|
|
||
| add_llvm_mca_unittest_link_components( | ||
| X86 | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,181 @@ | ||
| #include "Views/SummaryView.h" | ||
| #include "X86TestBase.h" | ||
| #include "llvm/ADT/SmallPtrSet.h" | ||
| #include "llvm/MCA/CustomBehaviour.h" | ||
| #include "llvm/MCA/IncrementalSourceMgr.h" | ||
| #include "llvm/MCA/InstrBuilder.h" | ||
| #include "llvm/MCA/Pipeline.h" | ||
| #include "llvm/Support/Format.h" | ||
| #include "llvm/Support/JSON.h" | ||
| #include "llvm/Support/raw_ostream.h" | ||
| #include <unordered_map> | ||
|
|
||
| using namespace llvm; | ||
| using namespace mca; | ||
|
|
||
| TEST_F(X86TestBase, TestResumablePipeline) { | ||
| mca::Context MCA(*MRI, *STI); | ||
|
|
||
| mca::IncrementalSourceMgr ISM; | ||
| // Empty CustomBehaviour. | ||
| auto CB = std::make_unique<mca::CustomBehaviour>(*STI, ISM, *MCII); | ||
|
|
||
| auto PO = getDefaultPipelineOptions(); | ||
| auto P = MCA.createDefaultPipeline(PO, ISM, *CB); | ||
| ASSERT_TRUE(P); | ||
|
|
||
| SmallVector<MCInst> MCIs; | ||
| getSimpleInsts(MCIs, /*Repeats=*/100); | ||
|
|
||
| // Add views. | ||
| auto SV = std::make_unique<SummaryView>(STI->getSchedModel(), MCIs, | ||
| PO.DispatchWidth); | ||
| P->addEventListener(SV.get()); | ||
|
|
||
| mca::InstrBuilder IB(*STI, *MCII, *MRI, MCIA.get()); | ||
|
|
||
| // Tile size = 7 | ||
| for (unsigned i = 0U, E = MCIs.size(); i < E;) { | ||
| for (unsigned TE = i + 7; i < TE && i < E; ++i) { | ||
| Expected<std::unique_ptr<mca::Instruction>> InstOrErr = | ||
| IB.createInstruction(MCIs[i]); | ||
| ASSERT_TRUE(bool(InstOrErr)); | ||
| ISM.addInst(std::move(InstOrErr.get())); | ||
| } | ||
|
|
||
| // Run the pipeline. | ||
| Expected<unsigned> Cycles = P->run(); | ||
| if (!Cycles) { | ||
| // Should be a stream pause error. | ||
| ASSERT_TRUE(Cycles.errorIsA<mca::InstStreamPause>()); | ||
| llvm::consumeError(Cycles.takeError()); | ||
| } | ||
| } | ||
|
|
||
| ISM.endOfStream(); | ||
| // Has to terminate properly. | ||
| Expected<unsigned> Cycles = P->run(); | ||
| ASSERT_TRUE(bool(Cycles)); | ||
|
|
||
| json::Value Result = SV->toJSON(); | ||
| auto *ResultObj = Result.getAsObject(); | ||
| ASSERT_TRUE(ResultObj); | ||
|
|
||
| // Run the baseline. | ||
| json::Object BaselineResult; | ||
| auto E = runBaselineMCA(BaselineResult, MCIs); | ||
| ASSERT_FALSE(bool(E)) << "Failed to run baseline"; | ||
| auto *BaselineObj = BaselineResult.getObject(SV->getNameAsString()); | ||
| ASSERT_TRUE(BaselineObj) << "Does not contain SummaryView result"; | ||
|
|
||
| // Compare the results. | ||
| constexpr const char *Fields[] = {"Instructions", "TotalCycles", "TotaluOps", | ||
| "BlockRThroughput"}; | ||
| for (const auto *F : Fields) { | ||
| auto V = ResultObj->getInteger(F); | ||
| auto BV = BaselineObj->getInteger(F); | ||
| ASSERT_TRUE(V && BV); | ||
| ASSERT_EQ(*BV, *V) << "Value of '" << F << "' does not match"; | ||
| } | ||
| } | ||
|
|
||
| TEST_F(X86TestBase, TestInstructionRecycling) { | ||
| mca::Context MCA(*MRI, *STI); | ||
|
|
||
| std::unordered_map<const mca::InstrDesc *, SmallPtrSet<mca::Instruction *, 2>> | ||
| RecycledInsts; | ||
| auto GetRecycledInst = [&](const mca::InstrDesc &Desc) -> mca::Instruction * { | ||
| auto It = RecycledInsts.find(&Desc); | ||
| if (It != RecycledInsts.end()) { | ||
| auto &Insts = It->second; | ||
| if (Insts.size()) { | ||
| mca::Instruction *I = *Insts.begin(); | ||
| Insts.erase(I); | ||
| return I; | ||
| } | ||
| } | ||
| return nullptr; | ||
| }; | ||
| auto AddRecycledInst = [&](mca::Instruction *I) { | ||
| const mca::InstrDesc &D = I->getDesc(); | ||
| RecycledInsts[&D].insert(I); | ||
| }; | ||
|
|
||
| mca::IncrementalSourceMgr ISM; | ||
| ISM.setOnInstFreedCallback(AddRecycledInst); | ||
|
|
||
| // Empty CustomBehaviour. | ||
| auto CB = std::make_unique<mca::CustomBehaviour>(*STI, ISM, *MCII); | ||
|
|
||
| auto PO = getDefaultPipelineOptions(); | ||
| auto P = MCA.createDefaultPipeline(PO, ISM, *CB); | ||
| ASSERT_TRUE(P); | ||
|
|
||
| SmallVector<MCInst> MCIs; | ||
| getSimpleInsts(MCIs, /*Repeats=*/100); | ||
|
|
||
| // Add views. | ||
| auto SV = std::make_unique<SummaryView>(STI->getSchedModel(), MCIs, | ||
| PO.DispatchWidth); | ||
| P->addEventListener(SV.get()); | ||
|
|
||
| mca::InstrBuilder IB(*STI, *MCII, *MRI, MCIA.get()); | ||
| IB.setInstRecycleCallback(GetRecycledInst); | ||
|
|
||
| // Tile size = 7 | ||
| for (unsigned i = 0U, E = MCIs.size(); i < E;) { | ||
| for (unsigned TE = i + 7; i < TE && i < E; ++i) { | ||
| Expected<std::unique_ptr<mca::Instruction>> InstOrErr = | ||
| IB.createInstruction(MCIs[i]); | ||
|
|
||
| if (!InstOrErr) { | ||
| mca::Instruction *RecycledInst = nullptr; | ||
| // Check if the returned instruction is a recycled | ||
| // one. | ||
| auto RemainingE = handleErrors(InstOrErr.takeError(), | ||
| [&](const mca::RecycledInstErr &RC) { | ||
| RecycledInst = RC.getInst(); | ||
| }); | ||
| ASSERT_FALSE(bool(RemainingE)); | ||
| ASSERT_TRUE(RecycledInst); | ||
| ISM.addRecycledInst(RecycledInst); | ||
| } else { | ||
| ISM.addInst(std::move(InstOrErr.get())); | ||
| } | ||
| } | ||
|
|
||
| // Run the pipeline. | ||
| Expected<unsigned> Cycles = P->run(); | ||
| if (!Cycles) { | ||
| // Should be a stream pause error. | ||
| ASSERT_TRUE(Cycles.errorIsA<mca::InstStreamPause>()); | ||
| llvm::consumeError(Cycles.takeError()); | ||
| } | ||
| } | ||
|
|
||
| ISM.endOfStream(); | ||
| // Has to terminate properly. | ||
| Expected<unsigned> Cycles = P->run(); | ||
| ASSERT_TRUE(bool(Cycles)); | ||
|
|
||
| json::Value Result = SV->toJSON(); | ||
| auto *ResultObj = Result.getAsObject(); | ||
| ASSERT_TRUE(ResultObj); | ||
|
|
||
| // Run the baseline. | ||
| json::Object BaselineResult; | ||
| auto E = runBaselineMCA(BaselineResult, MCIs); | ||
| ASSERT_FALSE(bool(E)) << "Failed to run baseline"; | ||
| auto *BaselineObj = BaselineResult.getObject(SV->getNameAsString()); | ||
| ASSERT_TRUE(BaselineObj) << "Does not contain SummaryView result"; | ||
|
|
||
| // Compare the results. | ||
| constexpr const char *Fields[] = {"Instructions", "TotalCycles", "TotaluOps", | ||
| "BlockRThroughput"}; | ||
| for (const auto *F : Fields) { | ||
| auto V = ResultObj->getInteger(F); | ||
| auto BV = BaselineObj->getInteger(F); | ||
| ASSERT_TRUE(V && BV); | ||
| ASSERT_EQ(*BV, *V) << "Value of '" << F << "' does not match"; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| #include "X86TestBase.h" | ||
| #include "MCTargetDesc/X86MCTargetDesc.h" | ||
| #include "llvm/MC/MCInstBuilder.h" | ||
| #include "llvm/Support/TargetSelect.h" | ||
|
|
||
| using namespace llvm; | ||
| using namespace mca; | ||
|
|
||
| X86TestBase::X86TestBase() : MCATestBase("x86_64-unknown-linux", "skylake") { | ||
| LLVMInitializeX86TargetInfo(); | ||
| LLVMInitializeX86TargetMC(); | ||
| LLVMInitializeX86Target(); | ||
| LLVMInitializeX86AsmPrinter(); | ||
| } | ||
|
|
||
| void X86TestBase::getSimpleInsts(SmallVectorImpl<MCInst> &Insts, | ||
| unsigned Repeats) { | ||
| for (unsigned i = 0U; i < Repeats; ++i) { | ||
| // vmulps %xmm0, %xmm1, %xmm2 | ||
| Insts.push_back(MCInstBuilder(X86::VMULPSrr) | ||
| .addReg(X86::XMM2) | ||
| .addReg(X86::XMM1) | ||
| .addReg(X86::XMM0)); | ||
| // vhaddps %xmm2, %xmm2, %xmm3 | ||
| Insts.push_back(MCInstBuilder(X86::VHADDPSrr) | ||
| .addReg(X86::XMM3) | ||
| .addReg(X86::XMM2) | ||
| .addReg(X86::XMM2)); | ||
| // vhaddps %xmm3, %xmm3, %xmm4 | ||
| Insts.push_back(MCInstBuilder(X86::VHADDPSrr) | ||
| .addReg(X86::XMM4) | ||
| .addReg(X86::XMM3) | ||
| .addReg(X86::XMM3)); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| //===---- X86TestBase.h -----------------------------------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // Test fixture common to all X86 MCA tests. | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_UNITTESTS_TOOLS_LLVMMCA_X86_X86TESTBASE_H | ||
| #define LLVM_UNITTESTS_TOOLS_LLVMMCA_X86_X86TESTBASE_H | ||
|
|
||
| #include "MCATestBase.h" | ||
| #include "llvm/ADT/SmallVector.h" | ||
|
|
||
| namespace llvm { | ||
| namespace mca { | ||
|
|
||
| class X86TestBase : public MCATestBase { | ||
| protected: | ||
| X86TestBase(); | ||
|
|
||
| void getSimpleInsts(SmallVectorImpl<MCInst> &Insts, unsigned Repeats = 1); | ||
| }; | ||
|
|
||
| } // end namespace mca | ||
| } // end namespace llvm | ||
|
|
||
| #endif |