| //===- 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<StaticDataProfileInfoWrapperPass>(); | |
| AU.addRequired<ProfileSummaryInfoWrapperPass>(); | |
| 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<StaticDataProfileInfoWrapperPass>() | |
| .getStaticDataProfileInfo(); | |
| ProfileSummaryInfo *PSI = | |
| &getAnalysis<ProfileSummaryInfoWrapperPass>().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<StaticDataProfileInfoAnalysis>(M) | |
| .getStaticDataProfileInfo(); | |
| ProfileSummaryInfo *PSI = &MAM.getResult<ProfileSummaryAnalysis>(M); | |
| return annotateModule(M, SDPI, PSI) | |
| ? PreservedAnalyses::none().preserveSet<CFGAnalyses>() | |
| : PreservedAnalyses::all(); | |
| } |