//===- StaticDataAnnotator - Annotate static data's section prefix --------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // To reason about module-wide data hotness in a module granularity, this file // implements a module pass StaticDataAnnotator to work coordinately with the // StaticDataSplitter pass. // // The StaticDataSplitter pass is a machine function pass. It analyzes data // hotness based on code and adds counters in StaticDataProfileInfo via its // wrapper pass StaticDataProfileInfoWrapper. // The StaticDataProfileInfoWrapper sits in the middle between the // StaticDataSplitter and StaticDataAnnotator passes. // The StaticDataAnnotator pass is a module pass. It iterates global variables // in the module, looks up counters from StaticDataProfileInfo and sets the // section prefix based on profiles. // // The three-pass structure is implemented for practical reasons, to work around // the limitation that a module pass based on legacy pass manager cannot make // use of MachineBlockFrequencyInfo analysis. In the future, we can consider // porting the StaticDataSplitter pass to a module-pass using the new pass // manager framework. That way, analysis are lazily computed as opposed to // eagerly scheduled, and a module pass can use MachineBlockFrequencyInfo. //===----------------------------------------------------------------------===// #include "llvm/CodeGen/StaticDataAnnotator.h" #include "llvm/Analysis/ProfileSummaryInfo.h" #include "llvm/Analysis/StaticDataProfileInfo.h" #include "llvm/CodeGen/Passes.h" #include "llvm/IR/Analysis.h" #include "llvm/IR/Module.h" #include "llvm/IR/PassManager.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" #define DEBUG_TYPE "static-data-annotator" using namespace llvm; /// A module pass which iterates global variables in the module and annotates /// their section prefixes based on profile-driven analysis. class StaticDataAnnotatorLegacy : public ModulePass { public: static char ID; StaticDataAnnotatorLegacy() : ModulePass(ID) {} void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired(); AU.addRequired(); AU.setPreservesAll(); ModulePass::getAnalysisUsage(AU); } StringRef getPassName() const override { return "Static Data Annotator"; } bool runOnModule(Module &M) override; }; static bool annotateModule(Module &M, StaticDataProfileInfo *SDPI, ProfileSummaryInfo *PSI) { if (!PSI || !PSI->hasProfileSummary()) return false; bool Changed = false; for (auto &GV : M.globals()) { if (!llvm::memprof::IsAnnotationOK(GV)) continue; StringRef SectionPrefix = SDPI->getConstantSectionPrefix(&GV, PSI); // setSectionPrefix returns true if the section prefix is updated. Changed |= GV.setSectionPrefix(SectionPrefix); } return Changed; } bool StaticDataAnnotatorLegacy::runOnModule(Module &M) { StaticDataProfileInfo *SDPI = &getAnalysis() .getStaticDataProfileInfo(); ProfileSummaryInfo *PSI = &getAnalysis().getPSI(); return annotateModule(M, SDPI, PSI); } char StaticDataAnnotatorLegacy::ID = 0; INITIALIZE_PASS(StaticDataAnnotatorLegacy, DEBUG_TYPE, "Static Data Annotator", false, false) ModulePass *llvm::createStaticDataAnnotatorLegacyPass() { return new StaticDataAnnotatorLegacy(); } PreservedAnalyses StaticDataAnnoatorPass::run(Module &M, ModuleAnalysisManager &MAM) { StaticDataProfileInfo *SDPI = &MAM.getResult(M) .getStaticDataProfileInfo(); ProfileSummaryInfo *PSI = &MAM.getResult(M); return annotateModule(M, SDPI, PSI) ? PreservedAnalyses::none().preserveSet() : PreservedAnalyses::all(); }