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