diff --git a/tools/llvm-exegesis/lib/Assembler.cpp b/tools/llvm-exegesis/lib/Assembler.cpp index 30723e584ce..05a13dbe9a1 100644 --- a/tools/llvm-exegesis/lib/Assembler.cpp +++ b/tools/llvm-exegesis/lib/Assembler.cpp @@ -9,6 +9,7 @@ #include "Assembler.h" +#include "Target.h" #include "llvm/CodeGen/GlobalISel/CallLowering.h" #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" #include "llvm/CodeGen/MachineInstrBuilder.h" @@ -139,6 +140,8 @@ void assembleToStream(std::unique_ptr TM, auto &Properties = MF.getProperties(); Properties.set(llvm::MachineFunctionProperties::Property::NoVRegs); Properties.reset(llvm::MachineFunctionProperties::Property::IsSSA); + // FIXME: Remove this when we assign all used registers as config step. This + // essentially disables checks that used registers are def'ed somewhere. Properties.reset(llvm::MachineFunctionProperties::Property::TracksLiveness); // prologue/epilogue pass needs the reserved registers to be frozen, this // is usually done by the SelectionDAGISel pass. @@ -158,6 +161,11 @@ void assembleToStream(std::unique_ptr TM, PM.add(TPC); PM.add(MMI.release()); TPC->printAndVerify("MachineFunctionGenerator::assemble"); + // Add target-specific passes. + if (const auto *ET = ExegesisTarget::lookup(TM->getTargetTriple())) { + ET->addTargetSpecificPasses(PM); + TPC->printAndVerify("After ExegesisTarget::addTargetSpecificPasses"); + } // Adding the following passes: // - machineverifier: checks that the MachineFunction is well formed. // - prologepilog: saves and restore callee saved registers. diff --git a/tools/llvm-exegesis/lib/Target.cpp b/tools/llvm-exegesis/lib/Target.cpp index 1b11f93e353..a69ab0c3225 100644 --- a/tools/llvm-exegesis/lib/Target.cpp +++ b/tools/llvm-exegesis/lib/Target.cpp @@ -14,10 +14,10 @@ ExegesisTarget::~ExegesisTarget() {} // anchor. static ExegesisTarget* FirstTarget = nullptr; -const ExegesisTarget* ExegesisTarget::lookup(llvm::StringRef TT) { - const llvm::Triple::ArchType Arch = llvm::Triple(TT).getArch(); +const ExegesisTarget *ExegesisTarget::lookup(llvm::Triple TT) { for (const ExegesisTarget* T = FirstTarget; T != nullptr; T = T->Next) { - if (T->matchesArch(Arch)) return T; + if (T->matchesArch(TT.getArch())) + return T; } return nullptr; } diff --git a/tools/llvm-exegesis/lib/Target.h b/tools/llvm-exegesis/lib/Target.h index 25b66715c94..ba91afd82d6 100644 --- a/tools/llvm-exegesis/lib/Target.h +++ b/tools/llvm-exegesis/lib/Target.h @@ -18,14 +18,19 @@ #define LLVM_TOOLS_LLVM_EXEGESIS_TARGET_H #include "llvm/ADT/Triple.h" +#include "llvm/CodeGen/TargetPassConfig.h" +#include "llvm/IR/LegacyPassManager.h" namespace exegesis { class ExegesisTarget { public: + // Targets can use this to add target-specific passes in assembleToStream(); + virtual void addTargetSpecificPasses(llvm::PassManagerBase &PM) const {} + // Returns the ExegesisTarget for the given triple or nullptr if the target // does not exist. - static const ExegesisTarget* lookup(llvm::StringRef TT); + static const ExegesisTarget *lookup(llvm::Triple TT); // Registers a target. Not thread safe. static void registerTarget(ExegesisTarget *T); diff --git a/tools/llvm-exegesis/lib/X86/CMakeLists.txt b/tools/llvm-exegesis/lib/X86/CMakeLists.txt index 28dcff50ed7..912877dd6ed 100644 --- a/tools/llvm-exegesis/lib/X86/CMakeLists.txt +++ b/tools/llvm-exegesis/lib/X86/CMakeLists.txt @@ -1,3 +1,8 @@ +include_directories( + ${LLVM_MAIN_SRC_DIR}/lib/Target/X86 + ${LLVM_BINARY_DIR}/lib/Target/X86 + ) + add_library(LLVMExegesisX86 STATIC Target.cpp diff --git a/tools/llvm-exegesis/lib/X86/Target.cpp b/tools/llvm-exegesis/lib/X86/Target.cpp index a37387bf5e7..557588b2d9b 100644 --- a/tools/llvm-exegesis/lib/X86/Target.cpp +++ b/tools/llvm-exegesis/lib/X86/Target.cpp @@ -8,12 +8,20 @@ //===----------------------------------------------------------------------===// #include "../Target.h" +#include "X86.h" + namespace exegesis { namespace { class ExegesisX86Target : public ExegesisTarget { -private: + void addTargetSpecificPasses(llvm::PassManagerBase &PM) const override { + // Lowers FP pseudo-instructions, e.g. ABS_Fp32 -> ABS_F. + // FIXME: Enable when the exegesis assembler no longer does + // Properties.reset(TracksLiveness); + // PM.add(llvm::createX86FloatingPointStackifierPass()); + } + bool matchesArch(llvm::Triple::ArchType Arch) const override { return Arch == llvm::Triple::x86_64 || Arch == llvm::Triple::x86; } diff --git a/unittests/tools/llvm-exegesis/X86/TargetTest.cpp b/unittests/tools/llvm-exegesis/X86/TargetTest.cpp index 683f2a05537..f13e40c706d 100644 --- a/unittests/tools/llvm-exegesis/X86/TargetTest.cpp +++ b/unittests/tools/llvm-exegesis/X86/TargetTest.cpp @@ -20,7 +20,8 @@ protected: }; TEST_F(X86TargetTest, Lookup) { - EXPECT_THAT(ExegesisTarget::lookup("x86_64-unknown-linux"), NotNull()); + EXPECT_THAT(ExegesisTarget::lookup(llvm::Triple("x86_64-unknown-linux")), + NotNull()); } } // namespace