1 //===- StaticDataAnnotator - Annotate static data's section prefix --------===// 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 // To reason about module-wide data hotness in a module granularity, this file 10 // implements a module pass StaticDataAnnotator to work coordinately with the 11 // StaticDataSplitter pass. 12 // 13 // The StaticDataSplitter pass is a machine function pass. It analyzes data 14 // hotness based on code and adds counters in StaticDataProfileInfo via its 15 // wrapper pass StaticDataProfileInfoWrapper. 16 // The StaticDataProfileInfoWrapper sits in the middle between the 17 // StaticDataSplitter and StaticDataAnnotator passes. 18 // The StaticDataAnnotator pass is a module pass. It iterates global variables 19 // in the module, looks up counters from StaticDataProfileInfo and sets the 20 // section prefix based on profiles. 21 // 22 // The three-pass structure is implemented for practical reasons, to work around 23 // the limitation that a module pass based on legacy pass manager cannot make 24 // use of MachineBlockFrequencyInfo analysis. In the future, we can consider 25 // porting the StaticDataSplitter pass to a module-pass using the new pass 26 // manager framework. That way, analysis are lazily computed as opposed to 27 // eagerly scheduled, and a module pass can use MachineBlockFrequencyInfo. 28 //===----------------------------------------------------------------------===// 29 30 #include "llvm/Analysis/ProfileSummaryInfo.h" 31 #include "llvm/Analysis/StaticDataProfileInfo.h" 32 #include "llvm/CodeGen/Passes.h" 33 #include "llvm/IR/Analysis.h" 34 #include "llvm/IR/Module.h" 35 #include "llvm/IR/PassManager.h" 36 #include "llvm/InitializePasses.h" 37 #include "llvm/Pass.h" 38 39 #define DEBUG_TYPE "static-data-annotator" 40 41 using namespace llvm; 42 43 /// A module pass which iterates global variables in the module and annotates 44 /// their section prefixes based on profile-driven analysis. 45 class StaticDataAnnotator : public ModulePass { 46 public: 47 static char ID; 48 49 StaticDataProfileInfo *SDPI = nullptr; 50 const ProfileSummaryInfo *PSI = nullptr; 51 52 StaticDataAnnotator() : ModulePass(ID) { 53 initializeStaticDataAnnotatorPass(*PassRegistry::getPassRegistry()); 54 } 55 56 void getAnalysisUsage(AnalysisUsage &AU) const override { 57 AU.addRequired<StaticDataProfileInfoWrapperPass>(); 58 AU.addRequired<ProfileSummaryInfoWrapperPass>(); 59 AU.setPreservesAll(); 60 ModulePass::getAnalysisUsage(AU); 61 } 62 63 StringRef getPassName() const override { return "Static Data Annotator"; } 64 65 bool runOnModule(Module &M) override; 66 }; 67 68 bool StaticDataAnnotator::runOnModule(Module &M) { 69 SDPI = &getAnalysis<StaticDataProfileInfoWrapperPass>() 70 .getStaticDataProfileInfo(); 71 PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI(); 72 73 if (!PSI->hasProfileSummary()) 74 return false; 75 76 bool Changed = false; 77 for (auto &GV : M.globals()) { 78 if (GV.isDeclarationForLinker()) 79 continue; 80 81 // The implementation below assumes prior passes don't set section prefixes, 82 // and specifically do 'assign' rather than 'update'. So report error if a 83 // section prefix is already set. 84 if (auto maybeSectionPrefix = GV.getSectionPrefix(); 85 maybeSectionPrefix && !maybeSectionPrefix->empty()) 86 llvm::report_fatal_error("Global variable " + GV.getName() + 87 " already has a section prefix " + 88 *maybeSectionPrefix); 89 90 StringRef SectionPrefix = SDPI->getConstantSectionPrefix(&GV, PSI); 91 if (SectionPrefix.empty()) 92 continue; 93 94 GV.setSectionPrefix(SectionPrefix); 95 Changed = true; 96 } 97 98 return Changed; 99 } 100 101 char StaticDataAnnotator::ID = 0; 102 103 INITIALIZE_PASS(StaticDataAnnotator, DEBUG_TYPE, "Static Data Annotator", false, 104 false) 105 106 ModulePass *llvm::createStaticDataAnnotatorPass() { 107 return new StaticDataAnnotator(); 108 } 109