diff options
Diffstat (limited to 'llvm/unittests/CodeGen/GlobalISel/GISelMITest.h')
-rw-r--r-- | llvm/unittests/CodeGen/GlobalISel/GISelMITest.h | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h b/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h new file mode 100644 index 00000000000..91b8e818dee --- /dev/null +++ b/llvm/unittests/CodeGen/GlobalISel/GISelMITest.h @@ -0,0 +1,196 @@ +//===- GISelMITest.h +//-----------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_UNITTEST_CODEGEN_GLOBALISEL_GISELMI_H +#define LLVM_UNITTEST_CODEGEN_GLOBALISEL_GISELMI_H + +#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h" +#include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" +#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" +#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" +#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" +#include "llvm/CodeGen/GlobalISel/Utils.h" +#include "llvm/CodeGen/MIRParser/MIRParser.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/TargetFrameLowering.h" +#include "llvm/CodeGen/TargetInstrInfo.h" +#include "llvm/CodeGen/TargetLowering.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" +#include "llvm/Support/FileCheck.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace MIPatternMatch; + +static inline void initLLVM() { + InitializeAllTargets(); + InitializeAllTargetMCs(); + InitializeAllAsmPrinters(); + InitializeAllAsmParsers(); + + PassRegistry *Registry = PassRegistry::getPassRegistry(); + initializeCore(*Registry); + initializeCodeGen(*Registry); +} + +/// Create a TargetMachine. As we lack a dedicated always available target for +/// unittests, we go for "AArch64". +static std::unique_ptr<LLVMTargetMachine> createTargetMachine() { + Triple TargetTriple("aarch64--"); + std::string Error; + const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error); + if (!T) + return nullptr; + + TargetOptions Options; + return std::unique_ptr<LLVMTargetMachine>( + static_cast<LLVMTargetMachine *>(T->createTargetMachine( + "AArch64", "", "", Options, None, None, CodeGenOpt::Aggressive))); +} + +static std::unique_ptr<Module> parseMIR(LLVMContext &Context, + std::unique_ptr<MIRParser> &MIR, + const TargetMachine &TM, + StringRef MIRCode, const char *FuncName, + MachineModuleInfo &MMI) { + SMDiagnostic Diagnostic; + std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode); + MIR = createMIRParser(std::move(MBuffer), Context); + if (!MIR) + return nullptr; + + std::unique_ptr<Module> M = MIR->parseIRModule(); + if (!M) + return nullptr; + + M->setDataLayout(TM.createDataLayout()); + + if (MIR->parseMachineFunctions(*M, MMI)) + return nullptr; + + return M; +} + +static std::pair<std::unique_ptr<Module>, std::unique_ptr<MachineModuleInfo>> +createDummyModule(LLVMContext &Context, const LLVMTargetMachine &TM, + StringRef MIRFunc) { + SmallString<512> S; + StringRef MIRString = (Twine(R"MIR( +--- +... +name: func +registers: + - { id: 0, class: _ } + - { id: 1, class: _ } + - { id: 2, class: _ } + - { id: 3, class: _ } +body: | + bb.1: + %0(s64) = COPY $x0 + %1(s64) = COPY $x1 + %2(s64) = COPY $x2 +)MIR") + Twine(MIRFunc) + Twine("...\n")) + .toNullTerminatedStringRef(S); + std::unique_ptr<MIRParser> MIR; + auto MMI = make_unique<MachineModuleInfo>(&TM); + std::unique_ptr<Module> M = + parseMIR(Context, MIR, TM, MIRString, "func", *MMI); + return make_pair(std::move(M), std::move(MMI)); +} + +static MachineFunction *getMFFromMMI(const Module *M, + const MachineModuleInfo *MMI) { + Function *F = M->getFunction("func"); + auto *MF = MMI->getMachineFunction(*F); + return MF; +} + +static void collectCopies(SmallVectorImpl<unsigned> &Copies, + MachineFunction *MF) { + for (auto &MBB : *MF) + for (MachineInstr &MI : MBB) { + if (MI.getOpcode() == TargetOpcode::COPY) + Copies.push_back(MI.getOperand(0).getReg()); + } +} + +class GISelMITest : public ::testing::Test { +protected: + GISelMITest() : ::testing::Test() { + TM = createTargetMachine(); + if (!TM) + return; + ModuleMMIPair = createDummyModule(Context, *TM, ""); + MF = getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get()); + collectCopies(Copies, MF); + EntryMBB = &*MF->begin(); + B.setMF(*MF); + MRI = &MF->getRegInfo(); + B.setInsertPt(*EntryMBB, EntryMBB->end()); + } + LLVMContext Context; + std::unique_ptr<LLVMTargetMachine> TM; + MachineFunction *MF; + std::pair<std::unique_ptr<Module>, std::unique_ptr<MachineModuleInfo>> + ModuleMMIPair; + SmallVector<unsigned, 4> Copies; + MachineBasicBlock *EntryMBB; + MachineIRBuilder B; + MachineRegisterInfo *MRI; +}; + +#define DefineLegalizerInfo(Name, SettingUpActionsBlock) \ + class Name##Info : public LegalizerInfo { \ + public: \ + Name##Info(const TargetSubtargetInfo &ST) { \ + using namespace TargetOpcode; \ + const LLT s8 = LLT::scalar(8); \ + (void)s8; \ + const LLT s16 = LLT::scalar(16); \ + (void)s16; \ + const LLT s32 = LLT::scalar(32); \ + (void)s32; \ + const LLT s64 = LLT::scalar(64); \ + (void)s64; \ + do \ + SettingUpActionsBlock while (0); \ + computeTables(); \ + verify(*ST.getInstrInfo()); \ + } \ + }; + +static inline bool CheckMachineFunction(const MachineFunction &MF, + StringRef CheckStr) { + SmallString<512> Msg; + raw_svector_ostream OS(Msg); + MF.print(OS); + auto OutputBuf = MemoryBuffer::getMemBuffer(Msg, "Output", false); + auto CheckBuf = MemoryBuffer::getMemBuffer(CheckStr, ""); + SmallString<4096> CheckFileBuffer; + FileCheckRequest Req; + FileCheck FC(Req); + StringRef CheckFileText = + FC.CanonicalizeFile(*CheckBuf.get(), CheckFileBuffer); + SourceMgr SM; + SM.AddNewSourceBuffer(MemoryBuffer::getMemBuffer(CheckFileText, "CheckFile"), + SMLoc()); + Regex PrefixRE = FC.buildCheckPrefixRegex(); + std::vector<FileCheckString> CheckStrings; + FC.ReadCheckFile(SM, CheckFileText, PrefixRE, CheckStrings); + auto OutBuffer = OutputBuf->getBuffer(); + SM.AddNewSourceBuffer(std::move(OutputBuf), SMLoc()); + return FC.CheckInput(SM, OutBuffer, CheckStrings); +} +#endif |