Index: tools/llvm-exegesis/CMakeLists.txt =================================================================== --- tools/llvm-exegesis/CMakeLists.txt +++ tools/llvm-exegesis/CMakeLists.txt @@ -1,3 +1,4 @@ + set(LLVM_LINK_COMPONENTS Support native @@ -8,4 +9,18 @@ ) add_subdirectory(lib) -target_link_libraries(llvm-exegesis PRIVATE LLVMExegesis) + +# Link the native exegesis target if compiled and on the right host. +if ((LLVM_TARGETS_TO_BUILD MATCHES "X86") AND ("${LLVM_NATIVE_ARCH}" STREQUAL "X86")) + set(LLVM_NATIVE_ARCH "X86") +endif() + +if (LLVM_NATIVE_ARCH) + set(LLVM_EXEGESIS_NATIVE_TARGET "LLVMExegesis${LLVM_NATIVE_ARCH}") + set_source_files_properties(llvm-exegesis.cpp PROPERTIES COMPILE_FLAGS "-DLLVM_EXEGESIS_INITIALIZE_NATIVE_TARGET=Initialize${LLVM_NATIVE_ARCH}ExegesisTarget") +endif() + +target_link_libraries(llvm-exegesis PRIVATE + LLVMExegesis + ${LLVM_EXEGESIS_NATIVE_TARGET} + ) Index: tools/llvm-exegesis/lib/CMakeLists.txt =================================================================== --- tools/llvm-exegesis/lib/CMakeLists.txt +++ tools/llvm-exegesis/lib/CMakeLists.txt @@ -1,3 +1,7 @@ +if (LLVM_TARGETS_TO_BUILD MATCHES "X86") + add_subdirectory(X86) +endif() + add_library(LLVMExegesis STATIC Analysis.cpp @@ -10,6 +14,7 @@ MCInstrDescView.cpp PerfHelper.cpp RegisterAliasing.cpp + Target.cpp Uops.cpp X86.cpp ) Index: tools/llvm-exegesis/lib/Target.h =================================================================== --- /dev/null +++ tools/llvm-exegesis/lib/Target.h @@ -0,0 +1,41 @@ +//===-- Target.h ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// +/// Classes that handle the creation of target-specific objects. This is +/// similar to llvm::Target/TargetRegistry. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLVM_EXEGESIS_TARGET_H +#define LLVM_TOOLS_LLVM_EXEGESIS_TARGET_H + +#include "llvm/ADT/Triple.h" + +namespace exegesis { + +class ExegesisTarget { +public: + // Returns the ExegesisTarget for the given triple or nullptr if the target + // does not exist. + static const ExegesisTarget* lookup(llvm::StringRef TT); + // Registers a target. Not thread safe. + static void registerTarget(ExegesisTarget *T); + + ~ExegesisTarget(); + +private: + virtual bool matchesArch(llvm::Triple::ArchType Arch) const = 0; + const ExegesisTarget* Next = nullptr; +}; + +} // namespace exegesis + +#endif // LLVM_TOOLS_LLVM_EXEGESIS_TARGET_H Index: tools/llvm-exegesis/lib/Target.cpp =================================================================== --- /dev/null +++ tools/llvm-exegesis/lib/Target.cpp @@ -0,0 +1,36 @@ +//===-- Target.cpp ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include "Target.h" + +namespace exegesis { + +ExegesisTarget::~ExegesisTarget() {} // anchor. + +static ExegesisTarget* FirstTarget = nullptr; + +const ExegesisTarget* ExegesisTarget::lookup(llvm::StringRef TT) { + const llvm::Triple::ArchType Arch = llvm::Triple(TT).getArch(); + for (const ExegesisTarget* T = FirstTarget; T != nullptr; T = T->Next) { + if (T->matchesArch(Arch)) return T; + } + return nullptr; +} + +void ExegesisTarget::registerTarget(ExegesisTarget *Target){ + if (FirstTarget == nullptr) { + FirstTarget = Target; + return; + } + assert(Target->Next == nullptr && "target has already been registered"); + if (Target->Next != nullptr) + return; + Target->Next = FirstTarget; + FirstTarget = Target; +} +} // namespace exegesis Index: tools/llvm-exegesis/lib/Uops.cpp =================================================================== --- tools/llvm-exegesis/lib/Uops.cpp +++ tools/llvm-exegesis/lib/Uops.cpp @@ -97,8 +97,7 @@ return llvm::make_error( "Infeasible : has unknown operands"); if (llvm::any_of(MCInstrDesc.operands(), hasMemoryOperand)) - return llvm::make_error( - "Infeasible : has memory operands"); + return llvm::make_error("Infeasible : has memory operands"); return llvm::Error::success(); } Index: tools/llvm-exegesis/lib/X86/CMakeLists.txt =================================================================== --- /dev/null +++ tools/llvm-exegesis/lib/X86/CMakeLists.txt @@ -0,0 +1,13 @@ +add_library(LLVMExegesisX86 + STATIC + Target.cpp + ) + +llvm_update_compile_flags(LLVMExegesisX86) +llvm_map_components_to_libnames(libs + X86 + Exegesis + ) + +target_link_libraries(LLVMExegesisX86 ${libs}) +set_target_properties(LLVMExegesisX86 PROPERTIES FOLDER "Libraries") Index: tools/llvm-exegesis/lib/X86/LLVMBuild.txt =================================================================== --- /dev/null +++ tools/llvm-exegesis/lib/X86/LLVMBuild.txt @@ -0,0 +1,22 @@ +;===- ./tools/llvm-exegesis/lib/X86LLVMBuild.txt ---------------*- Conf -*--===; +; +; The LLVM Compiler Infrastructure +; +; This file is distributed under the University of Illinois Open Source +; License. See LICENSE.TXT for details. +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Library +name = ExegesisX86 +parent = Libraries +required_libraries = X86 Index: tools/llvm-exegesis/lib/X86/Target.cpp =================================================================== --- /dev/null +++ tools/llvm-exegesis/lib/X86/Target.cpp @@ -0,0 +1,33 @@ +//===-- Target.cpp ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include "../Target.h" + +namespace exegesis { + +namespace { + +class ExegesisX86Target : public ExegesisTarget { +private: + bool matchesArch(llvm::Triple::ArchType Arch) const override { + return Arch == llvm::Triple::x86_64 || Arch == llvm::Triple::x86; + } +}; + +} // namespace + +static ExegesisTarget* getTheExegesisX86Target() { + static ExegesisX86Target Target; + return &Target; +} + +void InitializeX86ExegesisTarget() { + ExegesisTarget::registerTarget(getTheExegesisX86Target()); +} + +} // namespace exegesis Index: tools/llvm-exegesis/llvm-exegesis.cpp =================================================================== --- tools/llvm-exegesis/llvm-exegesis.cpp +++ tools/llvm-exegesis/llvm-exegesis.cpp @@ -86,6 +86,10 @@ static llvm::ExitOnError ExitOnErr; +#ifdef LLVM_EXEGESIS_INITIALIZE_NATIVE_TARGET +void LLVM_EXEGESIS_INITIALIZE_NATIVE_TARGET(); +#endif + static unsigned GetOpcodeOrDie(const llvm::MCInstrInfo &MCInstrInfo) { if (OpcodeName.empty() && (OpcodeIndex == 0)) llvm::report_fatal_error( @@ -120,6 +124,9 @@ llvm::InitializeNativeTarget(); llvm::InitializeNativeTargetAsmPrinter(); +#ifdef LLVM_EXEGESIS_INITIALIZE_NATIVE_TARGET + LLVM_EXEGESIS_INITIALIZE_NATIVE_TARGET(); +#endif // FIXME: Target-specific filter. X86Filter Filter; Index: unittests/tools/llvm-exegesis/X86/CMakeLists.txt =================================================================== --- unittests/tools/llvm-exegesis/X86/CMakeLists.txt +++ unittests/tools/llvm-exegesis/X86/CMakeLists.txt @@ -18,5 +18,8 @@ AnalysisTest.cpp SnippetGeneratorTest.cpp RegisterAliasingTest.cpp + TargetTest.cpp ) -target_link_libraries(LLVMExegesisX86Tests PRIVATE LLVMExegesis) +target_link_libraries(LLVMExegesisX86Tests PRIVATE + LLVMExegesis + LLVMExegesisX86) Index: unittests/tools/llvm-exegesis/X86/TargetTest.cpp =================================================================== --- /dev/null +++ unittests/tools/llvm-exegesis/X86/TargetTest.cpp @@ -0,0 +1,27 @@ +#include "Target.h" + +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace exegesis { + +void InitializeX86ExegesisTarget(); + +namespace { + +using testing::NotNull; + +class X86TargetTest : public ::testing::Test { +protected: + static void SetUpTestCase() { InitializeX86ExegesisTarget(); } +}; + +TEST_F(X86TargetTest, Lookup) { + EXPECT_THAT(ExegesisTarget::lookup("x86_64-unknown-linux"), NotNull()); +} + +} // namespace +} // namespace exegesis