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