1ac798970SDuncan P. N. Exon Smith //===- unittests/IR/ModuleTest.cpp - Module unit tests --------------------===//
2ac798970SDuncan P. N. Exon Smith //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ac798970SDuncan P. N. Exon Smith //
7ac798970SDuncan P. N. Exon Smith //===----------------------------------------------------------------------===//
8ac798970SDuncan P. N. Exon Smith 
9ac798970SDuncan P. N. Exon Smith #include "llvm/IR/Module.h"
1001909b4eSHiroshi Yamauchi #include "llvm/AsmParser/Parser.h"
119a67b073SChandler Carruth #include "llvm/IR/GlobalVariable.h"
126c27c61dSHiroshi Yamauchi #include "llvm/IR/ModuleSummaryIndex.h"
131f43ea41SBjorn Pettersson #include "llvm/Pass.h"
14ea8e9795SMehdi Amini #include "llvm/Support/RandomNumberGenerator.h"
152013be48SSimon Pilgrim #include "llvm/Support/SourceMgr.h"
16ac798970SDuncan P. N. Exon Smith #include "gtest/gtest.h"
17ac798970SDuncan P. N. Exon Smith 
18ea8e9795SMehdi Amini #include <random>
19ea8e9795SMehdi Amini 
20ac798970SDuncan P. N. Exon Smith using namespace llvm;
21ac798970SDuncan P. N. Exon Smith 
22ac798970SDuncan P. N. Exon Smith namespace {
23ac798970SDuncan P. N. Exon Smith 
sortByName(const GlobalVariable & L,const GlobalVariable & R)24ac798970SDuncan P. N. Exon Smith bool sortByName(const GlobalVariable &L, const GlobalVariable &R) {
25ac798970SDuncan P. N. Exon Smith   return L.getName() < R.getName();
26ac798970SDuncan P. N. Exon Smith }
27ac798970SDuncan P. N. Exon Smith 
sortByNameReverse(const GlobalVariable & L,const GlobalVariable & R)28ac798970SDuncan P. N. Exon Smith bool sortByNameReverse(const GlobalVariable &L, const GlobalVariable &R) {
29ac798970SDuncan P. N. Exon Smith   return sortByName(R, L);
30ac798970SDuncan P. N. Exon Smith }
31ac798970SDuncan P. N. Exon Smith 
TEST(ModuleTest,sortGlobalsByName)32ac798970SDuncan P. N. Exon Smith TEST(ModuleTest, sortGlobalsByName) {
33ac798970SDuncan P. N. Exon Smith   LLVMContext Context;
34d0c61994SDuncan P. N. Exon Smith   for (auto compare : {&sortByName, &sortByNameReverse}) {
35ac798970SDuncan P. N. Exon Smith     Module M("M", Context);
36ac798970SDuncan P. N. Exon Smith     Type *T = Type::getInt8Ty(Context);
37ac798970SDuncan P. N. Exon Smith     GlobalValue::LinkageTypes L = GlobalValue::ExternalLinkage;
38ac798970SDuncan P. N. Exon Smith     (void)new GlobalVariable(M, T, false, L, nullptr, "A");
39ac798970SDuncan P. N. Exon Smith     (void)new GlobalVariable(M, T, false, L, nullptr, "F");
40ac798970SDuncan P. N. Exon Smith     (void)new GlobalVariable(M, T, false, L, nullptr, "G");
41ac798970SDuncan P. N. Exon Smith     (void)new GlobalVariable(M, T, false, L, nullptr, "E");
42ac798970SDuncan P. N. Exon Smith     (void)new GlobalVariable(M, T, false, L, nullptr, "B");
43ac798970SDuncan P. N. Exon Smith     (void)new GlobalVariable(M, T, false, L, nullptr, "H");
44ac798970SDuncan P. N. Exon Smith     (void)new GlobalVariable(M, T, false, L, nullptr, "C");
45ac798970SDuncan P. N. Exon Smith     (void)new GlobalVariable(M, T, false, L, nullptr, "D");
46ac798970SDuncan P. N. Exon Smith 
47ac798970SDuncan P. N. Exon Smith     // Sort the globals by name.
48ac798970SDuncan P. N. Exon Smith     EXPECT_FALSE(std::is_sorted(M.global_begin(), M.global_end(), compare));
49ac798970SDuncan P. N. Exon Smith     M.getGlobalList().sort(compare);
50ac798970SDuncan P. N. Exon Smith     EXPECT_TRUE(std::is_sorted(M.global_begin(), M.global_end(), compare));
51ac798970SDuncan P. N. Exon Smith   }
52ac798970SDuncan P. N. Exon Smith }
53ac798970SDuncan P. N. Exon Smith 
TEST(ModuleTest,randomNumberGenerator)54ea8e9795SMehdi Amini TEST(ModuleTest, randomNumberGenerator) {
55ea8e9795SMehdi Amini   LLVMContext Context;
56ea8e9795SMehdi Amini   static char ID;
57ea8e9795SMehdi Amini   struct DummyPass : ModulePass {
58ea8e9795SMehdi Amini     DummyPass() : ModulePass(ID) {}
59*31eb8349SLogan Smith     bool runOnModule(Module &) override { return true; }
60ea8e9795SMehdi Amini   } DP;
61ea8e9795SMehdi Amini 
62ea8e9795SMehdi Amini   Module M("R", Context);
63ea8e9795SMehdi Amini 
64ea8e9795SMehdi Amini   std::uniform_int_distribution<int> dist;
65a012dac9SReid Kleckner   const size_t NBCheck = 10;
66ea8e9795SMehdi Amini 
67ea8e9795SMehdi Amini   std::array<int, NBCheck> RandomStreams[2];
68ea8e9795SMehdi Amini   for (auto &RandomStream : RandomStreams) {
69562a19e0SDominic Chen     std::unique_ptr<RandomNumberGenerator> RNG = M.createRNG(DP.getPassName());
70ea8e9795SMehdi Amini     std::generate(RandomStream.begin(), RandomStream.end(),
71ea8e9795SMehdi Amini                   [&]() { return dist(*RNG); });
72ea8e9795SMehdi Amini   }
73ea8e9795SMehdi Amini 
74ea8e9795SMehdi Amini   EXPECT_TRUE(std::equal(RandomStreams[0].begin(), RandomStreams[0].end(),
75ea8e9795SMehdi Amini                          RandomStreams[1].begin()));
76ea8e9795SMehdi Amini }
77ea8e9795SMehdi Amini 
TEST(ModuleTest,setModuleFlag)7801909b4eSHiroshi Yamauchi TEST(ModuleTest, setModuleFlag) {
7901909b4eSHiroshi Yamauchi   LLVMContext Context;
8001909b4eSHiroshi Yamauchi   Module M("M", Context);
8101909b4eSHiroshi Yamauchi   StringRef Key = "Key";
8201909b4eSHiroshi Yamauchi   Metadata *Val1 = MDString::get(Context, "Val1");
8301909b4eSHiroshi Yamauchi   Metadata *Val2 = MDString::get(Context, "Val2");
8401909b4eSHiroshi Yamauchi   EXPECT_EQ(nullptr, M.getModuleFlag(Key));
8501909b4eSHiroshi Yamauchi   M.setModuleFlag(Module::ModFlagBehavior::Error, Key, Val1);
8601909b4eSHiroshi Yamauchi   EXPECT_EQ(Val1, M.getModuleFlag(Key));
8701909b4eSHiroshi Yamauchi   M.setModuleFlag(Module::ModFlagBehavior::Error, Key, Val2);
8801909b4eSHiroshi Yamauchi   EXPECT_EQ(Val2, M.getModuleFlag(Key));
8901909b4eSHiroshi Yamauchi }
9001909b4eSHiroshi Yamauchi 
9101909b4eSHiroshi Yamauchi const char *IRString = R"IR(
9201909b4eSHiroshi Yamauchi   !llvm.module.flags = !{!0}
9301909b4eSHiroshi Yamauchi 
9401909b4eSHiroshi Yamauchi   !0 = !{i32 1, !"ProfileSummary", !1}
9501909b4eSHiroshi Yamauchi   !1 = !{!2, !3, !4, !5, !6, !7, !8, !9}
9601909b4eSHiroshi Yamauchi   !2 = !{!"ProfileFormat", !"SampleProfile"}
9701909b4eSHiroshi Yamauchi   !3 = !{!"TotalCount", i64 10000}
9801909b4eSHiroshi Yamauchi   !4 = !{!"MaxCount", i64 10}
9901909b4eSHiroshi Yamauchi   !5 = !{!"MaxInternalCount", i64 1}
10001909b4eSHiroshi Yamauchi   !6 = !{!"MaxFunctionCount", i64 1000}
10101909b4eSHiroshi Yamauchi   !7 = !{!"NumCounts", i64 200}
10201909b4eSHiroshi Yamauchi   !8 = !{!"NumFunctions", i64 3}
10301909b4eSHiroshi Yamauchi   !9 = !{!"DetailedSummary", !10}
10401909b4eSHiroshi Yamauchi   !10 = !{!11, !12, !13}
10501909b4eSHiroshi Yamauchi   !11 = !{i32 10000, i64 1000, i32 1}
10601909b4eSHiroshi Yamauchi   !12 = !{i32 990000, i64 300, i32 10}
10701909b4eSHiroshi Yamauchi   !13 = !{i32 999999, i64 5, i32 100}
10801909b4eSHiroshi Yamauchi )IR";
10901909b4eSHiroshi Yamauchi 
TEST(ModuleTest,setProfileSummary)11001909b4eSHiroshi Yamauchi TEST(ModuleTest, setProfileSummary) {
11101909b4eSHiroshi Yamauchi   SMDiagnostic Err;
11201909b4eSHiroshi Yamauchi   LLVMContext Context;
11301909b4eSHiroshi Yamauchi   std::unique_ptr<Module> M = parseAssemblyString(IRString, Err, Context);
11401909b4eSHiroshi Yamauchi   auto *PS = ProfileSummary::getFromMD(M->getProfileSummary(/*IsCS*/ false));
11501909b4eSHiroshi Yamauchi   EXPECT_NE(nullptr, PS);
1161a1849c9SChristopher Tetreault   EXPECT_FALSE(PS->isPartialProfile());
11701909b4eSHiroshi Yamauchi   PS->setPartialProfile(true);
11801909b4eSHiroshi Yamauchi   M->setProfileSummary(PS->getMD(Context), ProfileSummary::PSK_Sample);
11901909b4eSHiroshi Yamauchi   delete PS;
12001909b4eSHiroshi Yamauchi   PS = ProfileSummary::getFromMD(M->getProfileSummary(/*IsCS*/ false));
12101909b4eSHiroshi Yamauchi   EXPECT_NE(nullptr, PS);
12201909b4eSHiroshi Yamauchi   EXPECT_EQ(true, PS->isPartialProfile());
12301909b4eSHiroshi Yamauchi   delete PS;
12401909b4eSHiroshi Yamauchi }
12501909b4eSHiroshi Yamauchi 
TEST(ModuleTest,setPartialSampleProfileRatio)1266c27c61dSHiroshi Yamauchi TEST(ModuleTest, setPartialSampleProfileRatio) {
1276c27c61dSHiroshi Yamauchi   const char *IRString = R"IR(
1286c27c61dSHiroshi Yamauchi   !llvm.module.flags = !{!0}
1296c27c61dSHiroshi Yamauchi 
1306c27c61dSHiroshi Yamauchi   !0 = !{i32 1, !"ProfileSummary", !1}
1316c27c61dSHiroshi Yamauchi   !1 = !{!2, !3, !4, !5, !6, !7, !8, !9, !10, !11}
1326c27c61dSHiroshi Yamauchi   !2 = !{!"ProfileFormat", !"SampleProfile"}
1336c27c61dSHiroshi Yamauchi   !3 = !{!"TotalCount", i64 10000}
1346c27c61dSHiroshi Yamauchi   !4 = !{!"MaxCount", i64 10}
1356c27c61dSHiroshi Yamauchi   !5 = !{!"MaxInternalCount", i64 1}
1366c27c61dSHiroshi Yamauchi   !6 = !{!"MaxFunctionCount", i64 1000}
1376c27c61dSHiroshi Yamauchi   !7 = !{!"NumCounts", i64 200}
1386c27c61dSHiroshi Yamauchi   !8 = !{!"NumFunctions", i64 3}
1396c27c61dSHiroshi Yamauchi   !9 = !{!"IsPartialProfile", i64 1}
1406c27c61dSHiroshi Yamauchi   !10 = !{!"PartialProfileRatio", double 0.0}
1416c27c61dSHiroshi Yamauchi   !11 = !{!"DetailedSummary", !12}
1426c27c61dSHiroshi Yamauchi   !12 = !{!13, !14, !15}
1436c27c61dSHiroshi Yamauchi   !13 = !{i32 10000, i64 1000, i32 1}
1446c27c61dSHiroshi Yamauchi   !14 = !{i32 990000, i64 300, i32 10}
1456c27c61dSHiroshi Yamauchi   !15 = !{i32 999999, i64 5, i32 100}
1466c27c61dSHiroshi Yamauchi   )IR";
1476c27c61dSHiroshi Yamauchi 
1486c27c61dSHiroshi Yamauchi   SMDiagnostic Err;
1496c27c61dSHiroshi Yamauchi   LLVMContext Context;
1506c27c61dSHiroshi Yamauchi   std::unique_ptr<Module> M = parseAssemblyString(IRString, Err, Context);
1516c27c61dSHiroshi Yamauchi   ModuleSummaryIndex Index(/*HaveGVs*/ false);
1526c27c61dSHiroshi Yamauchi   const unsigned BlockCount = 100;
1536c27c61dSHiroshi Yamauchi   const unsigned NumCounts = 200;
1546c27c61dSHiroshi Yamauchi   Index.setBlockCount(BlockCount);
1556c27c61dSHiroshi Yamauchi   M->setPartialSampleProfileRatio(Index);
1566c27c61dSHiroshi Yamauchi   double Ratio = (double)BlockCount / NumCounts;
1576c27c61dSHiroshi Yamauchi   std::unique_ptr<ProfileSummary> ProfileSummary(
1586c27c61dSHiroshi Yamauchi       ProfileSummary::getFromMD(M->getProfileSummary(/*IsCS*/ false)));
1596c27c61dSHiroshi Yamauchi   EXPECT_EQ(Ratio, ProfileSummary->getPartialProfileRatio());
1606c27c61dSHiroshi Yamauchi }
1616c27c61dSHiroshi Yamauchi 
162ac798970SDuncan P. N. Exon Smith } // end namespace
163