1 //===- unittests/IR/ModuleTest.cpp - Module unit tests --------------------===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/IR/Module.h" 10 #include "llvm/AsmParser/Parser.h" 11 #include "llvm/IR/GlobalVariable.h" 12 #include "llvm/IR/ModuleSummaryIndex.h" 13 #include "llvm/Pass.h" 14 #include "llvm/Support/RandomNumberGenerator.h" 15 #include "llvm/Support/SourceMgr.h" 16 #include "gtest/gtest.h" 17 18 #include <random> 19 20 using namespace llvm; 21 22 namespace { 23 24 bool sortByName(const GlobalVariable &L, const GlobalVariable &R) { 25 return L.getName() < R.getName(); 26 } 27 28 bool sortByNameReverse(const GlobalVariable &L, const GlobalVariable &R) { 29 return sortByName(R, L); 30 } 31 32 TEST(ModuleTest, sortGlobalsByName) { 33 LLVMContext Context; 34 for (auto compare : {&sortByName, &sortByNameReverse}) { 35 Module M("M", Context); 36 Type *T = Type::getInt8Ty(Context); 37 GlobalValue::LinkageTypes L = GlobalValue::ExternalLinkage; 38 (void)new GlobalVariable(M, T, false, L, nullptr, "A"); 39 (void)new GlobalVariable(M, T, false, L, nullptr, "F"); 40 (void)new GlobalVariable(M, T, false, L, nullptr, "G"); 41 (void)new GlobalVariable(M, T, false, L, nullptr, "E"); 42 (void)new GlobalVariable(M, T, false, L, nullptr, "B"); 43 (void)new GlobalVariable(M, T, false, L, nullptr, "H"); 44 (void)new GlobalVariable(M, T, false, L, nullptr, "C"); 45 (void)new GlobalVariable(M, T, false, L, nullptr, "D"); 46 47 // Sort the globals by name. 48 EXPECT_FALSE(std::is_sorted(M.global_begin(), M.global_end(), compare)); 49 M.getGlobalList().sort(compare); 50 EXPECT_TRUE(std::is_sorted(M.global_begin(), M.global_end(), compare)); 51 } 52 } 53 54 TEST(ModuleTest, randomNumberGenerator) { 55 LLVMContext Context; 56 static char ID; 57 struct DummyPass : ModulePass { 58 DummyPass() : ModulePass(ID) {} 59 bool runOnModule(Module &) override { return true; } 60 } DP; 61 62 Module M("R", Context); 63 64 std::uniform_int_distribution<int> dist; 65 const size_t NBCheck = 10; 66 67 std::array<int, NBCheck> RandomStreams[2]; 68 for (auto &RandomStream : RandomStreams) { 69 std::unique_ptr<RandomNumberGenerator> RNG = M.createRNG(DP.getPassName()); 70 std::generate(RandomStream.begin(), RandomStream.end(), 71 [&]() { return dist(*RNG); }); 72 } 73 74 EXPECT_TRUE(std::equal(RandomStreams[0].begin(), RandomStreams[0].end(), 75 RandomStreams[1].begin())); 76 } 77 78 TEST(ModuleTest, setModuleFlag) { 79 LLVMContext Context; 80 Module M("M", Context); 81 StringRef Key = "Key"; 82 Metadata *Val1 = MDString::get(Context, "Val1"); 83 Metadata *Val2 = MDString::get(Context, "Val2"); 84 EXPECT_EQ(nullptr, M.getModuleFlag(Key)); 85 M.setModuleFlag(Module::ModFlagBehavior::Error, Key, Val1); 86 EXPECT_EQ(Val1, M.getModuleFlag(Key)); 87 M.setModuleFlag(Module::ModFlagBehavior::Error, Key, Val2); 88 EXPECT_EQ(Val2, M.getModuleFlag(Key)); 89 } 90 91 const char *IRString = R"IR( 92 !llvm.module.flags = !{!0} 93 94 !0 = !{i32 1, !"ProfileSummary", !1} 95 !1 = !{!2, !3, !4, !5, !6, !7, !8, !9} 96 !2 = !{!"ProfileFormat", !"SampleProfile"} 97 !3 = !{!"TotalCount", i64 10000} 98 !4 = !{!"MaxCount", i64 10} 99 !5 = !{!"MaxInternalCount", i64 1} 100 !6 = !{!"MaxFunctionCount", i64 1000} 101 !7 = !{!"NumCounts", i64 200} 102 !8 = !{!"NumFunctions", i64 3} 103 !9 = !{!"DetailedSummary", !10} 104 !10 = !{!11, !12, !13} 105 !11 = !{i32 10000, i64 1000, i32 1} 106 !12 = !{i32 990000, i64 300, i32 10} 107 !13 = !{i32 999999, i64 5, i32 100} 108 )IR"; 109 110 TEST(ModuleTest, setProfileSummary) { 111 SMDiagnostic Err; 112 LLVMContext Context; 113 std::unique_ptr<Module> M = parseAssemblyString(IRString, Err, Context); 114 auto *PS = ProfileSummary::getFromMD(M->getProfileSummary(/*IsCS*/ false)); 115 EXPECT_NE(nullptr, PS); 116 EXPECT_FALSE(PS->isPartialProfile()); 117 PS->setPartialProfile(true); 118 M->setProfileSummary(PS->getMD(Context), ProfileSummary::PSK_Sample); 119 delete PS; 120 PS = ProfileSummary::getFromMD(M->getProfileSummary(/*IsCS*/ false)); 121 EXPECT_NE(nullptr, PS); 122 EXPECT_EQ(true, PS->isPartialProfile()); 123 delete PS; 124 } 125 126 TEST(ModuleTest, setPartialSampleProfileRatio) { 127 const char *IRString = R"IR( 128 !llvm.module.flags = !{!0} 129 130 !0 = !{i32 1, !"ProfileSummary", !1} 131 !1 = !{!2, !3, !4, !5, !6, !7, !8, !9, !10, !11} 132 !2 = !{!"ProfileFormat", !"SampleProfile"} 133 !3 = !{!"TotalCount", i64 10000} 134 !4 = !{!"MaxCount", i64 10} 135 !5 = !{!"MaxInternalCount", i64 1} 136 !6 = !{!"MaxFunctionCount", i64 1000} 137 !7 = !{!"NumCounts", i64 200} 138 !8 = !{!"NumFunctions", i64 3} 139 !9 = !{!"IsPartialProfile", i64 1} 140 !10 = !{!"PartialProfileRatio", double 0.0} 141 !11 = !{!"DetailedSummary", !12} 142 !12 = !{!13, !14, !15} 143 !13 = !{i32 10000, i64 1000, i32 1} 144 !14 = !{i32 990000, i64 300, i32 10} 145 !15 = !{i32 999999, i64 5, i32 100} 146 )IR"; 147 148 SMDiagnostic Err; 149 LLVMContext Context; 150 std::unique_ptr<Module> M = parseAssemblyString(IRString, Err, Context); 151 ModuleSummaryIndex Index(/*HaveGVs*/ false); 152 const unsigned BlockCount = 100; 153 const unsigned NumCounts = 200; 154 Index.setBlockCount(BlockCount); 155 M->setPartialSampleProfileRatio(Index); 156 double Ratio = (double)BlockCount / NumCounts; 157 std::unique_ptr<ProfileSummary> ProfileSummary( 158 ProfileSummary::getFromMD(M->getProfileSummary(/*IsCS*/ false))); 159 EXPECT_EQ(Ratio, ProfileSummary->getPartialProfileRatio()); 160 } 161 162 } // end namespace 163