97 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// To reason about module-wide data hotness in a module granularity, this file10// implements a module pass StaticDataAnnotator to work coordinately with the11// StaticDataSplitter pass.12//13// The StaticDataSplitter pass is a machine function pass. It analyzes data14// hotness based on code and adds counters in StaticDataProfileInfo via its15// wrapper pass StaticDataProfileInfoWrapper.16// The StaticDataProfileInfoWrapper sits in the middle between the17// StaticDataSplitter and StaticDataAnnotator passes.18// The StaticDataAnnotator pass is a module pass. It iterates global variables19// in the module, looks up counters from StaticDataProfileInfo and sets the20// section prefix based on profiles.21//22// The three-pass structure is implemented for practical reasons, to work around23// the limitation that a module pass based on legacy pass manager cannot make24// use of MachineBlockFrequencyInfo analysis. In the future, we can consider25// porting the StaticDataSplitter pass to a module-pass using the new pass26// manager framework. That way, analysis are lazily computed as opposed to27// 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 41using namespace llvm;42 43/// A module pass which iterates global variables in the module and annotates44/// their section prefixes based on profile-driven analysis.45class StaticDataAnnotator : public ModulePass {46public: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 68bool 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 (!llvm::memprof::IsAnnotationOK(GV))79 continue;80 81 StringRef SectionPrefix = SDPI->getConstantSectionPrefix(&GV, PSI);82 // setSectionPrefix returns true if the section prefix is updated.83 Changed |= GV.setSectionPrefix(SectionPrefix);84 }85 86 return Changed;87}88 89char StaticDataAnnotator::ID = 0;90 91INITIALIZE_PASS(StaticDataAnnotator, DEBUG_TYPE, "Static Data Annotator", false,92 false)93 94ModulePass *llvm::createStaticDataAnnotatorPass() {95 return new StaticDataAnnotator();96}97