1 //===- ProfileSummaryInfoTest.cpp - ProfileSummaryInfo unit tests ---------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/Analysis/ProfileSummaryInfo.h" 11 #include "llvm/Analysis/BlockFrequencyInfo.h" 12 #include "llvm/Analysis/BranchProbabilityInfo.h" 13 #include "llvm/Analysis/LoopInfo.h" 14 #include "llvm/AsmParser/Parser.h" 15 #include "llvm/IR/BasicBlock.h" 16 #include "llvm/IR/CallSite.h" 17 #include "llvm/IR/Dominators.h" 18 #include "llvm/IR/Function.h" 19 #include "llvm/IR/LLVMContext.h" 20 #include "llvm/IR/MDBuilder.h" 21 #include "llvm/IR/Module.h" 22 #include "llvm/Support/DataTypes.h" 23 #include "llvm/Support/FormatVariadic.h" 24 #include "llvm/Support/SourceMgr.h" 25 #include "llvm/Support/raw_ostream.h" 26 #include "gtest/gtest.h" 27 28 namespace llvm { 29 namespace { 30 31 class ProfileSummaryInfoTest : public testing::Test { 32 protected: 33 LLVMContext C; 34 std::unique_ptr<BranchProbabilityInfo> BPI; 35 std::unique_ptr<DominatorTree> DT; 36 std::unique_ptr<LoopInfo> LI; 37 38 ProfileSummaryInfo buildPSI(Module *M) { 39 return ProfileSummaryInfo(*M); 40 } 41 BlockFrequencyInfo buildBFI(Function &F) { 42 DT.reset(new DominatorTree(F)); 43 LI.reset(new LoopInfo(*DT)); 44 BPI.reset(new BranchProbabilityInfo(F, *LI)); 45 return BlockFrequencyInfo(F, *BPI, *LI); 46 } 47 std::unique_ptr<Module> makeLLVMModule(const char *ProfKind = nullptr) { 48 const char *ModuleString = 49 "define i32 @g(i32 %x) !prof !21 {{\n" 50 " ret i32 0\n" 51 "}\n" 52 "define i32 @h(i32 %x) !prof !22 {{\n" 53 " ret i32 0\n" 54 "}\n" 55 "define i32 @f(i32 %x) !prof !20 {{\n" 56 "bb0:\n" 57 " %y1 = icmp eq i32 %x, 0 \n" 58 " br i1 %y1, label %bb1, label %bb2, !prof !23 \n" 59 "bb1:\n" 60 " %z1 = call i32 @g(i32 %x)\n" 61 " br label %bb3\n" 62 "bb2:\n" 63 " %z2 = call i32 @h(i32 %x)\n" 64 " br label %bb3\n" 65 "bb3:\n" 66 " %y2 = phi i32 [0, %bb1], [1, %bb2] \n" 67 " ret i32 %y2\n" 68 "}\n" 69 "!20 = !{{!\"function_entry_count\", i64 400}\n" 70 "!21 = !{{!\"function_entry_count\", i64 1}\n" 71 "!22 = !{{!\"function_entry_count\", i64 100}\n" 72 "!23 = !{{!\"branch_weights\", i32 64, i32 4}\n" 73 "{0}"; 74 const char *SummaryString = "!llvm.module.flags = !{{!1}" 75 "!1 = !{{i32 1, !\"ProfileSummary\", !2}" 76 "!2 = !{{!3, !4, !5, !6, !7, !8, !9, !10}" 77 "!3 = !{{!\"ProfileFormat\", !\"{0}\"}" 78 "!4 = !{{!\"TotalCount\", i64 10000}" 79 "!5 = !{{!\"MaxCount\", i64 10}" 80 "!6 = !{{!\"MaxInternalCount\", i64 1}" 81 "!7 = !{{!\"MaxFunctionCount\", i64 1000}" 82 "!8 = !{{!\"NumCounts\", i64 3}" 83 "!9 = !{{!\"NumFunctions\", i64 3}" 84 "!10 = !{{!\"DetailedSummary\", !11}" 85 "!11 = !{{!12, !13, !14}" 86 "!12 = !{{i32 10000, i64 1000, i32 1}" 87 "!13 = !{{i32 999000, i64 300, i32 3}" 88 "!14 = !{{i32 999999, i64 5, i32 10}"; 89 SMDiagnostic Err; 90 if (ProfKind) 91 return parseAssemblyString( 92 formatv(ModuleString, formatv(SummaryString, ProfKind).str()).str(), 93 Err, C); 94 else 95 return parseAssemblyString(formatv(ModuleString, "").str(), Err, C); 96 } 97 }; 98 99 TEST_F(ProfileSummaryInfoTest, TestNoProfile) { 100 auto M = makeLLVMModule(/*ProfKind=*/nullptr); 101 Function *F = M->getFunction("f"); 102 103 ProfileSummaryInfo PSI = buildPSI(M.get()); 104 EXPECT_FALSE(PSI.hasProfileSummary()); 105 EXPECT_FALSE(PSI.hasSampleProfile()); 106 EXPECT_FALSE(PSI.hasInstrumentationProfile()); 107 // In the absence of profiles, is{Hot|Cold}X methods should always return 108 // false. 109 EXPECT_FALSE(PSI.isHotCount(1000)); 110 EXPECT_FALSE(PSI.isHotCount(0)); 111 EXPECT_FALSE(PSI.isColdCount(1000)); 112 EXPECT_FALSE(PSI.isColdCount(0)); 113 114 EXPECT_FALSE(PSI.isFunctionEntryHot(F)); 115 EXPECT_FALSE(PSI.isFunctionEntryCold(F)); 116 117 BasicBlock &BB0 = F->getEntryBlock(); 118 BasicBlock *BB1 = BB0.getTerminator()->getSuccessor(0); 119 120 BlockFrequencyInfo BFI = buildBFI(*F); 121 EXPECT_FALSE(PSI.isHotBlock(&BB0, &BFI)); 122 EXPECT_FALSE(PSI.isColdBlock(&BB0, &BFI)); 123 124 CallSite CS1(BB1->getFirstNonPHI()); 125 EXPECT_FALSE(PSI.isHotCallSite(CS1, &BFI)); 126 EXPECT_FALSE(PSI.isColdCallSite(CS1, &BFI)); 127 } 128 TEST_F(ProfileSummaryInfoTest, TestCommon) { 129 auto M = makeLLVMModule("InstrProf"); 130 Function *F = M->getFunction("f"); 131 Function *G = M->getFunction("g"); 132 Function *H = M->getFunction("h"); 133 134 ProfileSummaryInfo PSI = buildPSI(M.get()); 135 EXPECT_TRUE(PSI.hasProfileSummary()); 136 EXPECT_TRUE(PSI.isHotCount(400)); 137 EXPECT_TRUE(PSI.isColdCount(2)); 138 EXPECT_FALSE(PSI.isColdCount(100)); 139 EXPECT_FALSE(PSI.isHotCount(100)); 140 141 EXPECT_TRUE(PSI.isFunctionEntryHot(F)); 142 EXPECT_FALSE(PSI.isFunctionEntryHot(G)); 143 EXPECT_FALSE(PSI.isFunctionEntryHot(H)); 144 } 145 146 TEST_F(ProfileSummaryInfoTest, InstrProf) { 147 auto M = makeLLVMModule("InstrProf"); 148 Function *F = M->getFunction("f"); 149 ProfileSummaryInfo PSI = buildPSI(M.get()); 150 EXPECT_TRUE(PSI.hasProfileSummary()); 151 EXPECT_TRUE(PSI.hasInstrumentationProfile()); 152 153 BasicBlock &BB0 = F->getEntryBlock(); 154 BasicBlock *BB1 = BB0.getTerminator()->getSuccessor(0); 155 BasicBlock *BB2 = BB0.getTerminator()->getSuccessor(1); 156 BasicBlock *BB3 = BB1->getSingleSuccessor(); 157 158 BlockFrequencyInfo BFI = buildBFI(*F); 159 EXPECT_TRUE(PSI.isHotBlock(&BB0, &BFI)); 160 EXPECT_TRUE(PSI.isHotBlock(BB1, &BFI)); 161 EXPECT_FALSE(PSI.isHotBlock(BB2, &BFI)); 162 EXPECT_TRUE(PSI.isHotBlock(BB3, &BFI)); 163 164 CallSite CS1(BB1->getFirstNonPHI()); 165 auto *CI2 = BB2->getFirstNonPHI(); 166 CallSite CS2(CI2); 167 168 EXPECT_TRUE(PSI.isHotCallSite(CS1, &BFI)); 169 EXPECT_FALSE(PSI.isHotCallSite(CS2, &BFI)); 170 171 // Test that adding an MD_prof metadata with a hot count on CS2 does not 172 // change its hotness as it has no effect in instrumented profiling. 173 MDBuilder MDB(M->getContext()); 174 CI2->setMetadata(llvm::LLVMContext::MD_prof, MDB.createBranchWeights({400})); 175 EXPECT_FALSE(PSI.isHotCallSite(CS2, &BFI)); 176 } 177 178 TEST_F(ProfileSummaryInfoTest, SampleProf) { 179 auto M = makeLLVMModule("SampleProfile"); 180 Function *F = M->getFunction("f"); 181 ProfileSummaryInfo PSI = buildPSI(M.get()); 182 EXPECT_TRUE(PSI.hasProfileSummary()); 183 EXPECT_TRUE(PSI.hasSampleProfile()); 184 185 BasicBlock &BB0 = F->getEntryBlock(); 186 BasicBlock *BB1 = BB0.getTerminator()->getSuccessor(0); 187 BasicBlock *BB2 = BB0.getTerminator()->getSuccessor(1); 188 BasicBlock *BB3 = BB1->getSingleSuccessor(); 189 190 BlockFrequencyInfo BFI = buildBFI(*F); 191 EXPECT_TRUE(PSI.isHotBlock(&BB0, &BFI)); 192 EXPECT_TRUE(PSI.isHotBlock(BB1, &BFI)); 193 EXPECT_FALSE(PSI.isHotBlock(BB2, &BFI)); 194 EXPECT_TRUE(PSI.isHotBlock(BB3, &BFI)); 195 196 CallSite CS1(BB1->getFirstNonPHI()); 197 auto *CI2 = BB2->getFirstNonPHI(); 198 // Manually attach branch weights metadata to the call instruction. 199 SmallVector<uint32_t, 1> Weights; 200 Weights.push_back(1000); 201 MDBuilder MDB(M->getContext()); 202 CI2->setMetadata(LLVMContext::MD_prof, MDB.createBranchWeights(Weights)); 203 CallSite CS2(CI2); 204 205 EXPECT_FALSE(PSI.isHotCallSite(CS1, &BFI)); 206 EXPECT_TRUE(PSI.isHotCallSite(CS2, &BFI)); 207 208 // Test that CS2 is considered hot when it gets an MD_prof metadata with 209 // weights that exceed the hot count threshold. 210 CI2->setMetadata(llvm::LLVMContext::MD_prof, MDB.createBranchWeights({400})); 211 EXPECT_TRUE(PSI.isHotCallSite(CS2, &BFI)); 212 } 213 214 } // end anonymous namespace 215 } // end namespace llvm 216