llvm/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp

//===- ModuleSummaryAnalysis.cpp - Module summary index builder -----------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This pass builds a ModuleSummaryIndex object for the module, to be written
// to bitcode or LLVM assembly.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/ModuleSummaryAnalysis.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/IndirectCallPromotionAnalysis.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/MemoryProfileInfo.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/Analysis/StackSafetyAnalysis.h"
#include "llvm/Analysis/TypeMetadataUtils.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ModuleSummaryIndex.h"
#include "llvm/IR/Use.h"
#include "llvm/IR/User.h"
#include "llvm/InitializePasses.h"
#include "llvm/Object/ModuleSymbolTable.h"
#include "llvm/Object/SymbolicFile.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <vector>

usingnamespacellvm;
usingnamespacellvm::memprof;

#define DEBUG_TYPE

// Option to force edges cold which will block importing when the
// -import-cold-multiplier is set to 0. Useful for debugging.
namespace llvm {
FunctionSummary::ForceSummaryHotnessType ForceSummaryEdgesCold =;
} // namespace llvm

static cl::opt<FunctionSummary::ForceSummaryHotnessType, true> FSEC(
    "force-summary-edges-cold", cl::Hidden, cl::location(ForceSummaryEdgesCold),
    cl::desc("Force all edges in the function summary to cold"),
    cl::values(clEnumValN(FunctionSummary::FSHT_None, "none", "None."),
               clEnumValN(FunctionSummary::FSHT_AllNonCritical,
                          "all-non-critical", "All non-critical edges."),
               clEnumValN(FunctionSummary::FSHT_All, "all", "All edges.")));

static cl::opt<std::string> ModuleSummaryDotFile(
    "module-summary-dot-file", cl::Hidden, cl::value_desc("filename"),
    cl::desc("File to emit dot graph of new summary into"));

extern cl::opt<bool> ScalePartialSampleProfileWorkingSetSize;

extern cl::opt<unsigned> MaxNumVTableAnnotations;

extern cl::opt<bool> MemProfReportHintedSizes;

// Walk through the operands of a given User via worklist iteration and populate
// the set of GlobalValue references encountered. Invoked either on an
// Instruction or a GlobalVariable (which walks its initializer).
// Return true if any of the operands contains blockaddress. This is important
// to know when computing summary for global var, because if global variable
// references basic block address we can't import it separately from function
// containing that basic block. For simplicity we currently don't import such
// global vars at all. When importing function we aren't interested if any
// instruction in it takes an address of any basic block, because instruction
// can only take an address of basic block located in the same function.
// Set `RefLocalLinkageIFunc` to true if the analyzed value references a
// local-linkage ifunc.
static bool
findRefEdges(ModuleSummaryIndex &Index, const User *CurUser,
             SetVector<ValueInfo, SmallVector<ValueInfo, 0>> &RefEdges,
             SmallPtrSet<const User *, 8> &Visited,
             bool &RefLocalLinkageIFunc) {}

static CalleeInfo::HotnessType getHotness(uint64_t ProfileCount,
                                          ProfileSummaryInfo *PSI) {}

static bool isNonRenamableLocal(const GlobalValue &GV) {}

/// Determine whether this call has all constant integer arguments (excluding
/// "this") and summarize it to VCalls or ConstVCalls as appropriate.
static void addVCallToSet(
    DevirtCallSite Call, GlobalValue::GUID Guid,
    SetVector<FunctionSummary::VFuncId, std::vector<FunctionSummary::VFuncId>>
        &VCalls,
    SetVector<FunctionSummary::ConstVCall,
              std::vector<FunctionSummary::ConstVCall>> &ConstVCalls) {}

/// If this intrinsic call requires that we add information to the function
/// summary, do so via the non-constant reference arguments.
static void addIntrinsicToSummary(
    const CallInst *CI,
    SetVector<GlobalValue::GUID, std::vector<GlobalValue::GUID>> &TypeTests,
    SetVector<FunctionSummary::VFuncId, std::vector<FunctionSummary::VFuncId>>
        &TypeTestAssumeVCalls,
    SetVector<FunctionSummary::VFuncId, std::vector<FunctionSummary::VFuncId>>
        &TypeCheckedLoadVCalls,
    SetVector<FunctionSummary::ConstVCall,
              std::vector<FunctionSummary::ConstVCall>>
        &TypeTestAssumeConstVCalls,
    SetVector<FunctionSummary::ConstVCall,
              std::vector<FunctionSummary::ConstVCall>>
        &TypeCheckedLoadConstVCalls,
    DominatorTree &DT) {}

static bool isNonVolatileLoad(const Instruction *I) {}

static bool isNonVolatileStore(const Instruction *I) {}

// Returns true if the function definition must be unreachable.
//
// Note if this helper function returns true, `F` is guaranteed
// to be unreachable; if it returns false, `F` might still
// be unreachable but not covered by this helper function.
static bool mustBeUnreachableFunction(const Function &F) {}

static void computeFunctionSummary(
    ModuleSummaryIndex &Index, const Module &M, const Function &F,
    BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI, DominatorTree &DT,
    bool HasLocalsInUsedOrAsm, DenseSet<GlobalValue::GUID> &CantBePromoted,
    bool IsThinLTO,
    std::function<const StackSafetyInfo *(const Function &F)> GetSSICallback) {}

/// Find function pointers referenced within the given vtable initializer
/// (or subset of an initializer) \p I. The starting offset of \p I within
/// the vtable initializer is \p StartingOffset. Any discovered function
/// pointers are added to \p VTableFuncs along with their cumulative offset
/// within the initializer.
static void findFuncPointers(const Constant *I, uint64_t StartingOffset,
                             const Module &M, ModuleSummaryIndex &Index,
                             VTableFuncList &VTableFuncs,
                             const GlobalVariable &OrigGV) {}

// Identify the function pointers referenced by vtable definition \p V.
static void computeVTableFuncs(ModuleSummaryIndex &Index,
                               const GlobalVariable &V, const Module &M,
                               VTableFuncList &VTableFuncs) {}

/// Record vtable definition \p V for each type metadata it references.
static void
recordTypeIdCompatibleVtableReferences(ModuleSummaryIndex &Index,
                                       const GlobalVariable &V,
                                       SmallVectorImpl<MDNode *> &Types) {}

static void computeVariableSummary(ModuleSummaryIndex &Index,
                                   const GlobalVariable &V,
                                   DenseSet<GlobalValue::GUID> &CantBePromoted,
                                   const Module &M,
                                   SmallVectorImpl<MDNode *> &Types) {}

static void computeAliasSummary(ModuleSummaryIndex &Index, const GlobalAlias &A,
                                DenseSet<GlobalValue::GUID> &CantBePromoted) {}

// Set LiveRoot flag on entries matching the given value name.
static void setLiveRoot(ModuleSummaryIndex &Index, StringRef Name) {}

ModuleSummaryIndex llvm::buildModuleSummaryIndex(
    const Module &M,
    std::function<BlockFrequencyInfo *(const Function &F)> GetBFICallback,
    ProfileSummaryInfo *PSI,
    std::function<const StackSafetyInfo *(const Function &F)> GetSSICallback) {}

AnalysisKey ModuleSummaryIndexAnalysis::Key;

ModuleSummaryIndex
ModuleSummaryIndexAnalysis::run(Module &M, ModuleAnalysisManager &AM) {}

char ModuleSummaryIndexWrapperPass::ID =;

INITIALIZE_PASS_BEGIN(ModuleSummaryIndexWrapperPass, "module-summary-analysis",
                      "Module Summary Analysis", false, true)
INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass)
INITIALIZE_PASS_DEPENDENCY(StackSafetyInfoWrapperPass)
INITIALIZE_PASS_END(ModuleSummaryIndexWrapperPass, "module-summary-analysis",
                    "Module Summary Analysis", false, true)

ModulePass *llvm::createModuleSummaryIndexWrapperPass() {}

ModuleSummaryIndexWrapperPass::ModuleSummaryIndexWrapperPass()
    :{}

bool ModuleSummaryIndexWrapperPass::runOnModule(Module &M) {}

bool ModuleSummaryIndexWrapperPass::doFinalization(Module &M) {}

void ModuleSummaryIndexWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {}

char ImmutableModuleSummaryIndexWrapperPass::ID =;

ImmutableModuleSummaryIndexWrapperPass::ImmutableModuleSummaryIndexWrapperPass(
    const ModuleSummaryIndex *Index)
    :{}

void ImmutableModuleSummaryIndexWrapperPass::getAnalysisUsage(
    AnalysisUsage &AU) const {}

ImmutablePass *llvm::createImmutableModuleSummaryIndexWrapperPass(
    const ModuleSummaryIndex *Index) {}

INITIALIZE_PASS()

bool llvm::mayHaveMemprofSummary(const CallBase *CB) {}