[llvm-exegesis][NFC] Return many CodeTemplates instead of one.
[llvm-complete.git] / unittests / CodeGen / GlobalISel / LegalizerHelperTest.h
blobca1aed544d20b63bd4556218f1235145d1b03e03
1 //===- LegalizerHelperTest.h
2 //-----------------------------------------------===//
3 //
4 // The LLVM Compiler Infrastructure
5 //
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
11 #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h"
12 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
13 #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
14 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
15 #include "llvm/CodeGen/GlobalISel/Utils.h"
16 #include "llvm/CodeGen/MIRParser/MIRParser.h"
17 #include "llvm/CodeGen/MachineFunction.h"
18 #include "llvm/CodeGen/MachineModuleInfo.h"
19 #include "llvm/CodeGen/TargetFrameLowering.h"
20 #include "llvm/CodeGen/TargetInstrInfo.h"
21 #include "llvm/CodeGen/TargetLowering.h"
22 #include "llvm/CodeGen/TargetSubtargetInfo.h"
23 #include "llvm/Support/FileCheck.h"
24 #include "llvm/Support/SourceMgr.h"
25 #include "llvm/Support/TargetRegistry.h"
26 #include "llvm/Support/TargetSelect.h"
27 #include "llvm/Target/TargetMachine.h"
28 #include "llvm/Target/TargetOptions.h"
29 #include "gtest/gtest.h"
31 using namespace llvm;
32 using namespace MIPatternMatch;
34 void initLLVM() {
35 InitializeAllTargets();
36 InitializeAllTargetMCs();
37 InitializeAllAsmPrinters();
38 InitializeAllAsmParsers();
40 PassRegistry *Registry = PassRegistry::getPassRegistry();
41 initializeCore(*Registry);
42 initializeCodeGen(*Registry);
45 /// Create a TargetMachine. As we lack a dedicated always available target for
46 /// unittests, we go for "AArch64".
47 std::unique_ptr<TargetMachine> createTargetMachine() {
48 Triple TargetTriple("aarch64--");
49 std::string Error;
50 const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
51 if (!T)
52 return nullptr;
54 TargetOptions Options;
55 return std::unique_ptr<TargetMachine>(T->createTargetMachine(
56 "AArch64", "", "", Options, None, None, CodeGenOpt::Aggressive));
59 std::unique_ptr<Module> parseMIR(LLVMContext &Context,
60 std::unique_ptr<MIRParser> &MIR,
61 const TargetMachine &TM, StringRef MIRCode,
62 const char *FuncName, MachineModuleInfo &MMI) {
63 SMDiagnostic Diagnostic;
64 std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode);
65 MIR = createMIRParser(std::move(MBuffer), Context);
66 if (!MIR)
67 return nullptr;
69 std::unique_ptr<Module> M = MIR->parseIRModule();
70 if (!M)
71 return nullptr;
73 M->setDataLayout(TM.createDataLayout());
75 if (MIR->parseMachineFunctions(*M, MMI))
76 return nullptr;
78 return M;
81 std::pair<std::unique_ptr<Module>, std::unique_ptr<MachineModuleInfo>>
82 createDummyModule(LLVMContext &Context, const TargetMachine &TM,
83 StringRef MIRFunc) {
84 SmallString<512> S;
85 StringRef MIRString = (Twine(R"MIR(
86 ---
87 ...
88 name: func
89 registers:
90 - { id: 0, class: _ }
91 - { id: 1, class: _ }
92 - { id: 2, class: _ }
93 - { id: 3, class: _ }
94 body: |
95 bb.1:
96 %0(s64) = COPY $x0
97 %1(s64) = COPY $x1
98 %2(s64) = COPY $x2
99 )MIR") + Twine(MIRFunc) + Twine("...\n"))
100 .toNullTerminatedStringRef(S);
101 std::unique_ptr<MIRParser> MIR;
102 auto MMI = make_unique<MachineModuleInfo>(&TM);
103 std::unique_ptr<Module> M =
104 parseMIR(Context, MIR, TM, MIRString, "func", *MMI);
105 return make_pair(std::move(M), std::move(MMI));
108 static MachineFunction *getMFFromMMI(const Module *M,
109 const MachineModuleInfo *MMI) {
110 Function *F = M->getFunction("func");
111 auto *MF = MMI->getMachineFunction(*F);
112 return MF;
115 static void collectCopies(SmallVectorImpl<unsigned> &Copies,
116 MachineFunction *MF) {
117 for (auto &MBB : *MF)
118 for (MachineInstr &MI : MBB) {
119 if (MI.getOpcode() == TargetOpcode::COPY)
120 Copies.push_back(MI.getOperand(0).getReg());
124 class LegalizerHelperTest : public ::testing::Test {
125 protected:
126 LegalizerHelperTest() : ::testing::Test() {
127 TM = createTargetMachine();
128 if (!TM)
129 return;
130 ModuleMMIPair = createDummyModule(Context, *TM, "");
131 MF = getMFFromMMI(ModuleMMIPair.first.get(), ModuleMMIPair.second.get());
132 collectCopies(Copies, MF);
133 EntryMBB = &*MF->begin();
134 B.setMF(*MF);
135 MRI = &MF->getRegInfo();
136 B.setInsertPt(*EntryMBB, EntryMBB->end());
138 LLVMContext Context;
139 std::unique_ptr<TargetMachine> TM;
140 MachineFunction *MF;
141 std::pair<std::unique_ptr<Module>, std::unique_ptr<MachineModuleInfo>>
142 ModuleMMIPair;
143 SmallVector<unsigned, 4> Copies;
144 MachineBasicBlock *EntryMBB;
145 MachineIRBuilder B;
146 MachineRegisterInfo *MRI;
149 #define DefineLegalizerInfo(Name, SettingUpActionsBlock) \
150 class Name##Info : public LegalizerInfo { \
151 public: \
152 Name##Info(const TargetSubtargetInfo &ST) { \
153 using namespace TargetOpcode; \
154 const LLT s8 = LLT::scalar(8); \
155 (void)s8; \
156 const LLT s16 = LLT::scalar(16); \
157 (void)s16; \
158 const LLT s32 = LLT::scalar(32); \
159 (void)s32; \
160 const LLT s64 = LLT::scalar(64); \
161 (void)s64; \
162 do \
163 SettingUpActionsBlock while (0); \
164 computeTables(); \
165 verify(*ST.getInstrInfo()); \
169 static bool CheckMachineFunction(const MachineFunction &MF,
170 StringRef CheckStr) {
171 SmallString<512> Msg;
172 raw_svector_ostream OS(Msg);
173 MF.print(OS);
174 auto OutputBuf = MemoryBuffer::getMemBuffer(Msg, "Output", false);
175 auto CheckBuf = MemoryBuffer::getMemBuffer(CheckStr, "");
176 SmallString<4096> CheckFileBuffer;
177 FileCheckRequest Req;
178 FileCheck FC(Req);
179 StringRef CheckFileText =
180 FC.CanonicalizeFile(*CheckBuf.get(), CheckFileBuffer);
181 SourceMgr SM;
182 SM.AddNewSourceBuffer(MemoryBuffer::getMemBuffer(CheckFileText, "CheckFile"),
183 SMLoc());
184 Regex PrefixRE = FC.buildCheckPrefixRegex();
185 std::vector<FileCheckString> CheckStrings;
186 FC.ReadCheckFile(SM, CheckFileText, PrefixRE, CheckStrings);
187 auto OutBuffer = OutputBuf->getBuffer();
188 SM.AddNewSourceBuffer(std::move(OutputBuf), SMLoc());
189 return FC.CheckInput(SM, OutBuffer, CheckStrings);