blob: bc3d856942fd19155e3e9c20cde5aa0b144da04f [file]
//===- 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();
}