| //===- 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(); |
| } |