1 //===- LegalizerHelperTest.h
2 //-----------------------------------------------===//
4 // The LLVM Compiler Infrastructure
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
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"
32 using namespace MIPatternMatch
;
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--");
50 const Target
*T
= TargetRegistry::lookupTarget("", TargetTriple
, Error
);
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
);
69 std::unique_ptr
<Module
> M
= MIR
->parseIRModule();
73 M
->setDataLayout(TM
.createDataLayout());
75 if (MIR
->parseMachineFunctions(*M
, MMI
))
81 std::pair
<std::unique_ptr
<Module
>, std::unique_ptr
<MachineModuleInfo
>>
82 createDummyModule(LLVMContext
&Context
, const TargetMachine
&TM
,
85 StringRef MIRString
= (Twine(R
"MIR(
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
);
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
{
126 LegalizerHelperTest() : ::testing::Test() {
127 TM
= createTargetMachine();
130 ModuleMMIPair
= createDummyModule(Context
, *TM
, "");
131 MF
= getMFFromMMI(ModuleMMIPair
.first
.get(), ModuleMMIPair
.second
.get());
132 collectCopies(Copies
, MF
);
133 EntryMBB
= &*MF
->begin();
135 MRI
= &MF
->getRegInfo();
136 B
.setInsertPt(*EntryMBB
, EntryMBB
->end());
139 std::unique_ptr
<TargetMachine
> TM
;
141 std::pair
<std::unique_ptr
<Module
>, std::unique_ptr
<MachineModuleInfo
>>
143 SmallVector
<unsigned, 4> Copies
;
144 MachineBasicBlock
*EntryMBB
;
146 MachineRegisterInfo
*MRI
;
149 #define DefineLegalizerInfo(Name, SettingUpActionsBlock) \
150 class Name##Info : public LegalizerInfo { \
152 Name##Info(const TargetSubtargetInfo &ST) { \
153 using namespace TargetOpcode; \
154 const LLT s8 = LLT::scalar(8); \
156 const LLT s16 = LLT::scalar(16); \
158 const LLT s32 = LLT::scalar(32); \
160 const LLT s64 = LLT::scalar(64); \
163 SettingUpActionsBlock while (0); \
165 verify(*ST.getInstrInfo()); \
169 static bool CheckMachineFunction(const MachineFunction
&MF
,
170 StringRef CheckStr
) {
171 SmallString
<512> Msg
;
172 raw_svector_ostream
OS(Msg
);
174 auto OutputBuf
= MemoryBuffer::getMemBuffer(Msg
, "Output", false);
175 auto CheckBuf
= MemoryBuffer::getMemBuffer(CheckStr
, "");
176 SmallString
<4096> CheckFileBuffer
;
177 FileCheckRequest Req
;
179 StringRef CheckFileText
=
180 FC
.CanonicalizeFile(*CheckBuf
.get(), CheckFileBuffer
);
182 SM
.AddNewSourceBuffer(MemoryBuffer::getMemBuffer(CheckFileText
, "CheckFile"),
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
);