1 //==-SummaryBasedOptimizations.cpp - Optimizations based on ThinLTO summary-==// 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 // This file implements optimizations that are based on the module summaries. 11 // These optimizations are performed during the thinlink phase of the 12 // compilation. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "llvm/LTO/SummaryBasedOptimizations.h" 17 #include "llvm/Analysis/SyntheticCountsUtils.h" 18 #include "llvm/IR/ModuleSummaryIndex.h" 19 20 using namespace llvm; 21 22 cl::opt<bool> ThinLTOSynthesizeEntryCounts( 23 "thinlto-synthesize-entry-counts", cl::init(false), cl::Hidden, 24 cl::desc("Synthesize entry counts based on the summary")); 25 26 extern cl::opt<int> InitialSyntheticCount; 27 28 static void initializeCounts(ModuleSummaryIndex &Index) { 29 auto Root = Index.calculateCallGraphRoot(); 30 // Root is a fake node. All its successors are the actual roots of the 31 // callgraph. 32 // FIXME: This initializes the entry counts of only the root nodes. This makes 33 // sense when compiling a binary with ThinLTO, but for libraries any of the 34 // non-root nodes could be called from outside. 35 for (auto &C : Root.calls()) { 36 auto &V = C.first; 37 for (auto &GVS : V.getSummaryList()) { 38 auto S = GVS.get()->getBaseObject(); 39 auto *F = cast<FunctionSummary>(S); 40 F->setEntryCount(InitialSyntheticCount); 41 } 42 } 43 } 44 45 void llvm::computeSyntheticCounts(ModuleSummaryIndex &Index) { 46 if (!ThinLTOSynthesizeEntryCounts) 47 return; 48 49 using Scaled64 = ScaledNumber<uint64_t>; 50 initializeCounts(Index); 51 auto GetCallSiteRelFreq = [](FunctionSummary::EdgeTy &Edge) { 52 return Scaled64(Edge.second.RelBlockFreq, -CalleeInfo::ScaleShift); 53 }; 54 auto GetEntryCount = [](ValueInfo V) { 55 if (V.getSummaryList().size()) { 56 auto S = V.getSummaryList().front().get()->getBaseObject(); 57 auto *F = cast<FunctionSummary>(S); 58 return F->entryCount(); 59 } else { 60 return UINT64_C(0); 61 } 62 }; 63 auto AddToEntryCount = [](ValueInfo V, uint64_t New) { 64 if (!V.getSummaryList().size()) 65 return; 66 for (auto &GVS : V.getSummaryList()) { 67 auto S = GVS.get()->getBaseObject(); 68 auto *F = cast<FunctionSummary>(S); 69 F->setEntryCount(SaturatingAdd(F->entryCount(), New)); 70 } 71 }; 72 73 // After initializing the counts in initializeCounts above, the counts have to 74 // be propagated across the combined callgraph. 75 // SyntheticCountsUtils::propagate takes care of this propagation on any 76 // callgraph that specialized GraphTraits. 77 SyntheticCountsUtils<ModuleSummaryIndex *>::propagate( 78 &Index, GetCallSiteRelFreq, GetEntryCount, AddToEntryCount); 79 Index.setHasSyntheticEntryCounts(); 80 } 81