1 //===- unittests/IR/ModuleTest.cpp - Module unit tests --------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/IR/Module.h"
10 #include "llvm/AsmParser/Parser.h"
11 #include "llvm/IR/Constants.h"
12 #include "llvm/IR/GlobalVariable.h"
13 #include "llvm/IR/ModuleSummaryIndex.h"
14 #include "llvm/Pass.h"
15 #include "llvm/Support/RandomNumberGenerator.h"
16 #include "llvm/Support/SourceMgr.h"
17 #include "gtest/gtest.h"
25 bool sortByName(const GlobalVariable
&L
, const GlobalVariable
&R
) {
26 return L
.getName() < R
.getName();
29 bool sortByNameReverse(const GlobalVariable
&L
, const GlobalVariable
&R
) {
30 return sortByName(R
, L
);
33 TEST(ModuleTest
, sortGlobalsByName
) {
35 for (auto compare
: {&sortByName
, &sortByNameReverse
}) {
36 Module
M("M", Context
);
37 Type
*T
= Type::getInt8Ty(Context
);
38 GlobalValue::LinkageTypes L
= GlobalValue::ExternalLinkage
;
39 (void)new GlobalVariable(M
, T
, false, L
, nullptr, "A");
40 (void)new GlobalVariable(M
, T
, false, L
, nullptr, "F");
41 (void)new GlobalVariable(M
, T
, false, L
, nullptr, "G");
42 (void)new GlobalVariable(M
, T
, false, L
, nullptr, "E");
43 (void)new GlobalVariable(M
, T
, false, L
, nullptr, "B");
44 (void)new GlobalVariable(M
, T
, false, L
, nullptr, "H");
45 (void)new GlobalVariable(M
, T
, false, L
, nullptr, "C");
46 (void)new GlobalVariable(M
, T
, false, L
, nullptr, "D");
48 // Sort the globals by name.
49 EXPECT_FALSE(std::is_sorted(M
.global_begin(), M
.global_end(), compare
));
53 TEST(ModuleTest
, randomNumberGenerator
) {
56 struct DummyPass
: ModulePass
{
57 DummyPass() : ModulePass(ID
) {}
58 bool runOnModule(Module
&) override
{ return true; }
61 Module
M("R", Context
);
63 std::uniform_int_distribution
<int> dist
;
64 const size_t NBCheck
= 10;
66 std::array
<int, NBCheck
> RandomStreams
[2];
67 for (auto &RandomStream
: RandomStreams
) {
68 std::unique_ptr
<RandomNumberGenerator
> RNG
= M
.createRNG(DP
.getPassName());
69 std::generate(RandomStream
.begin(), RandomStream
.end(),
70 [&]() { return dist(*RNG
); });
73 EXPECT_TRUE(std::equal(RandomStreams
[0].begin(), RandomStreams
[0].end(),
74 RandomStreams
[1].begin()));
77 TEST(ModuleTest
, setModuleFlag
) {
79 Module
M("M", Context
);
80 StringRef Key
= "Key";
81 Metadata
*Val1
= MDString::get(Context
, "Val1");
82 Metadata
*Val2
= MDString::get(Context
, "Val2");
83 EXPECT_EQ(nullptr, M
.getModuleFlag(Key
));
84 M
.setModuleFlag(Module::ModFlagBehavior::Error
, Key
, Val1
);
85 EXPECT_EQ(Val1
, M
.getModuleFlag(Key
));
86 M
.setModuleFlag(Module::ModFlagBehavior::Error
, Key
, Val2
);
87 EXPECT_EQ(Val2
, M
.getModuleFlag(Key
));
90 TEST(ModuleTest
, setModuleFlagInt
) {
92 Module
M("M", Context
);
93 StringRef Key
= "Key";
96 EXPECT_EQ(nullptr, M
.getModuleFlag(Key
));
97 M
.setModuleFlag(Module::ModFlagBehavior::Error
, Key
, Val1
);
98 auto A1
= mdconst::extract_or_null
<ConstantInt
>(M
.getModuleFlag(Key
));
99 EXPECT_EQ(Val1
, A1
->getZExtValue());
100 M
.setModuleFlag(Module::ModFlagBehavior::Error
, Key
, Val2
);
101 auto A2
= mdconst::extract_or_null
<ConstantInt
>(M
.getModuleFlag(Key
));
102 EXPECT_EQ(Val2
, A2
->getZExtValue());
105 const char *IRString
= R
"IR(
106 !llvm.module.flags = !{!0}
108 !0 = !{i32 1, !"ProfileSummary
", !1}
109 !1 = !{!2, !3, !4, !5, !6, !7, !8, !9}
110 !2 = !{!"ProfileFormat
", !"SampleProfile
"}
111 !3 = !{!"TotalCount
", i64 10000}
112 !4 = !{!"MaxCount
", i64 10}
113 !5 = !{!"MaxInternalCount
", i64 1}
114 !6 = !{!"MaxFunctionCount
", i64 1000}
115 !7 = !{!"NumCounts
", i64 200}
116 !8 = !{!"NumFunctions
", i64 3}
117 !9 = !{!"DetailedSummary
", !10}
118 !10 = !{!11, !12, !13}
119 !11 = !{i32 10000, i64 1000, i32 1}
120 !12 = !{i32 990000, i64 300, i32 10}
121 !13 = !{i32 999999, i64 5, i32 100}
124 TEST(ModuleTest
, setProfileSummary
) {
127 std::unique_ptr
<Module
> M
= parseAssemblyString(IRString
, Err
, Context
);
128 auto *PS
= ProfileSummary::getFromMD(M
->getProfileSummary(/*IsCS*/ false));
129 EXPECT_NE(nullptr, PS
);
130 EXPECT_FALSE(PS
->isPartialProfile());
131 PS
->setPartialProfile(true);
132 M
->setProfileSummary(PS
->getMD(Context
), ProfileSummary::PSK_Sample
);
134 PS
= ProfileSummary::getFromMD(M
->getProfileSummary(/*IsCS*/ false));
135 EXPECT_NE(nullptr, PS
);
136 EXPECT_EQ(true, PS
->isPartialProfile());
140 TEST(ModuleTest
, setPartialSampleProfileRatio
) {
141 const char *IRString
= R
"IR(
142 !llvm.module.flags = !{!0}
144 !0 = !{i32 1, !"ProfileSummary
", !1}
145 !1 = !{!2, !3, !4, !5, !6, !7, !8, !9, !10, !11}
146 !2 = !{!"ProfileFormat
", !"SampleProfile
"}
147 !3 = !{!"TotalCount
", i64 10000}
148 !4 = !{!"MaxCount
", i64 10}
149 !5 = !{!"MaxInternalCount
", i64 1}
150 !6 = !{!"MaxFunctionCount
", i64 1000}
151 !7 = !{!"NumCounts
", i64 200}
152 !8 = !{!"NumFunctions
", i64 3}
153 !9 = !{!"IsPartialProfile
", i64 1}
154 !10 = !{!"PartialProfileRatio
", double 0.0}
155 !11 = !{!"DetailedSummary
", !12}
156 !12 = !{!13, !14, !15}
157 !13 = !{i32 10000, i64 1000, i32 1}
158 !14 = !{i32 990000, i64 300, i32 10}
159 !15 = !{i32 999999, i64 5, i32 100}
164 std::unique_ptr
<Module
> M
= parseAssemblyString(IRString
, Err
, Context
);
165 ModuleSummaryIndex
Index(/*HaveGVs*/ false);
166 const unsigned BlockCount
= 100;
167 const unsigned NumCounts
= 200;
168 Index
.setBlockCount(BlockCount
);
169 M
->setPartialSampleProfileRatio(Index
);
170 double Ratio
= (double)BlockCount
/ NumCounts
;
171 std::unique_ptr
<ProfileSummary
> ProfileSummary(
172 ProfileSummary::getFromMD(M
->getProfileSummary(/*IsCS*/ false)));
173 EXPECT_EQ(Ratio
, ProfileSummary
->getPartialProfileRatio());
176 TEST(ModuleTest
, AliasList
) {
177 // This tests all Module's functions that interact with Module::AliasList.
181 std::unique_ptr
<Module
> M
= parseAssemblyString(R
"(
183 @GA = alias void (), ptr @Foo
186 Function
*Foo
= M
->getFunction("Foo");
187 auto *GA
= M
->getNamedAlias("GA");
188 EXPECT_EQ(M
->alias_size(), 1u);
190 GlobalAlias::create(Foo
->getType(), 0, GlobalValue::ExternalLinkage
,
191 "NewGA", Foo
, /*Parent=*/nullptr);
192 EXPECT_EQ(M
->alias_size(), 1u);
194 M
->insertAlias(NewGA
);
195 EXPECT_EQ(&*std::prev(M
->aliases().end()), NewGA
);
197 M
->removeAlias(NewGA
);
198 EXPECT_EQ(M
->alias_size(), 1u);
199 M
->insertAlias(NewGA
);
200 EXPECT_EQ(M
->alias_size(), 2u);
201 EXPECT_EQ(&*std::prev(M
->aliases().end()), NewGA
);
203 auto Range
= M
->aliases();
204 EXPECT_EQ(&*Range
.begin(), GA
);
205 EXPECT_EQ(&*std::next(Range
.begin()), NewGA
);
206 EXPECT_EQ(std::next(Range
.begin(), 2), Range
.end());
208 M
->removeAlias(NewGA
);
209 EXPECT_EQ(M
->alias_size(), 1u);
211 M
->insertAlias(NewGA
);
212 M
->eraseAlias(NewGA
);
213 EXPECT_EQ(M
->alias_size(), 1u);
216 TEST(ModuleTest
, IFuncList
) {
217 // This tests all Module's functions that interact with Module::IFuncList.
221 std::unique_ptr
<Module
> M
= parseAssemblyString(R
"(
223 @GIF = ifunc void (), ptr @Foo
226 Function
*Foo
= M
->getFunction("Foo");
227 auto *GIF
= M
->getNamedIFunc("GIF");
228 EXPECT_EQ(M
->ifunc_size(), 1u);
230 GlobalIFunc::create(Foo
->getType(), 0, GlobalValue::ExternalLinkage
,
231 "NewGIF", Foo
, /*Parent=*/nullptr);
232 EXPECT_EQ(M
->ifunc_size(), 1u);
234 M
->insertIFunc(NewGIF
);
235 EXPECT_EQ(&*std::prev(M
->ifuncs().end()), NewGIF
);
237 M
->removeIFunc(NewGIF
);
238 EXPECT_EQ(M
->ifunc_size(), 1u);
239 M
->insertIFunc(NewGIF
);
240 EXPECT_EQ(M
->ifunc_size(), 2u);
241 EXPECT_EQ(&*std::prev(M
->ifuncs().end()), NewGIF
);
243 auto Range
= M
->ifuncs();
244 EXPECT_EQ(&*Range
.begin(), GIF
);
245 EXPECT_EQ(&*std::next(Range
.begin()), NewGIF
);
246 EXPECT_EQ(std::next(Range
.begin(), 2), Range
.end());
248 M
->removeIFunc(NewGIF
);
249 EXPECT_EQ(M
->ifunc_size(), 1u);
251 M
->insertIFunc(NewGIF
);
252 M
->eraseIFunc(NewGIF
);
253 EXPECT_EQ(M
->ifunc_size(), 1u);
256 TEST(ModuleTest
, NamedMDList
) {
257 // This tests all Module's functions that interact with Module::NamedMDList.
261 auto M
= std::make_unique
<Module
>("M", C
);
262 NamedMDNode
*MDN1
= M
->getOrInsertNamedMetadata("MDN1");
263 EXPECT_EQ(M
->named_metadata_size(), 1u);
264 NamedMDNode
*MDN2
= M
->getOrInsertNamedMetadata("MDN2");
265 EXPECT_EQ(M
->named_metadata_size(), 2u);
266 auto *NewMDN
= M
->getOrInsertNamedMetadata("NewMDN");
267 EXPECT_EQ(M
->named_metadata_size(), 3u);
269 M
->removeNamedMDNode(NewMDN
);
270 EXPECT_EQ(M
->named_metadata_size(), 2u);
272 M
->insertNamedMDNode(NewMDN
);
273 EXPECT_EQ(&*std::prev(M
->named_metadata().end()), NewMDN
);
275 M
->removeNamedMDNode(NewMDN
);
276 M
->insertNamedMDNode(NewMDN
);
277 EXPECT_EQ(M
->named_metadata_size(), 3u);
278 EXPECT_EQ(&*std::prev(M
->named_metadata().end()), NewMDN
);
280 auto Range
= M
->named_metadata();
281 EXPECT_EQ(&*Range
.begin(), MDN1
);
282 EXPECT_EQ(&*std::next(Range
.begin(), 1), MDN2
);
283 EXPECT_EQ(&*std::next(Range
.begin(), 2), NewMDN
);
284 EXPECT_EQ(std::next(Range
.begin(), 3), Range
.end());
286 M
->eraseNamedMDNode(NewMDN
);
287 EXPECT_EQ(M
->named_metadata_size(), 2u);
290 TEST(ModuleTest
, GlobalList
) {
291 // This tests all Module's functions that interact with Module::GlobalList.
295 std::unique_ptr
<Module
> M
= parseAssemblyString(R
"(
296 @GV = external global i32
299 auto *GV
= cast
<GlobalVariable
>(M
->getNamedValue("GV"));
300 EXPECT_EQ(M
->global_size(), 1u);
301 GlobalVariable
*NewGV
= new GlobalVariable(
302 Type::getInt32Ty(C
), /*isConstant=*/true, GlobalValue::InternalLinkage
,
303 /*Initializer=*/nullptr, "NewGV");
304 EXPECT_EQ(M
->global_size(), 1u);
306 M
->insertGlobalVariable(M
->globals().begin(), NewGV
);
307 EXPECT_EQ(M
->global_size(), 2u);
308 EXPECT_EQ(&*M
->globals().begin(), NewGV
);
310 M
->removeGlobalVariable(NewGV
);
311 EXPECT_EQ(M
->global_size(), 1u);
312 M
->insertGlobalVariable(NewGV
);
313 EXPECT_EQ(M
->global_size(), 2u);
314 EXPECT_EQ(&*std::prev(M
->globals().end()), NewGV
);
316 auto Range
= M
->globals();
317 EXPECT_EQ(&*Range
.begin(), GV
);
318 EXPECT_EQ(&*std::next(Range
.begin()), NewGV
);
319 EXPECT_EQ(std::next(Range
.begin(), 2), Range
.end());
321 M
->removeGlobalVariable(NewGV
);
322 EXPECT_EQ(M
->global_size(), 1u);
324 M
->insertGlobalVariable(NewGV
);
325 M
->eraseGlobalVariable(NewGV
);
326 EXPECT_EQ(M
->global_size(), 1u);