Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/Utils/CallGraphUpdater.cpp
35271 views
//===- CallGraphUpdater.cpp - A (lazy) call graph update helper -----------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7/// \file8///9/// This file provides interfaces used to manipulate a call graph, regardless10/// if it is a "old style" CallGraph or an "new style" LazyCallGraph.11///12//===----------------------------------------------------------------------===//1314#include "llvm/Transforms/Utils/CallGraphUpdater.h"15#include "llvm/IR/Constants.h"16#include "llvm/Transforms/Utils/ModuleUtils.h"1718using namespace llvm;1920bool CallGraphUpdater::finalize() {21if (!DeadFunctionsInComdats.empty()) {22filterDeadComdatFunctions(DeadFunctionsInComdats);23DeadFunctions.append(DeadFunctionsInComdats.begin(),24DeadFunctionsInComdats.end());25}2627// This is the code path for the new lazy call graph and for the case were28// no call graph was provided.29for (Function *DeadFn : DeadFunctions) {30DeadFn->removeDeadConstantUsers();31DeadFn->replaceAllUsesWith(PoisonValue::get(DeadFn->getType()));3233if (LCG && !ReplacedFunctions.count(DeadFn)) {34// Taken mostly from the inliner:35LazyCallGraph::Node &N = LCG->get(*DeadFn);36auto *DeadSCC = LCG->lookupSCC(N);37assert(DeadSCC && DeadSCC->size() == 1 &&38&DeadSCC->begin()->getFunction() == DeadFn);3940FAM->clear(*DeadFn, DeadFn->getName());41AM->clear(*DeadSCC, DeadSCC->getName());42LCG->markDeadFunction(*DeadFn);4344// Mark the relevant parts of the call graph as invalid so we don't45// visit them.46UR->InvalidatedSCCs.insert(LCG->lookupSCC(N));47UR->DeadFunctions.push_back(DeadFn);48} else {49// The CGSCC infrastructure batch deletes functions at the end of the50// call graph walk, so only erase the function if we're not using that51// infrastructure.52// The function is now really dead and de-attached from everything.53DeadFn->eraseFromParent();54}55}5657bool Changed = !DeadFunctions.empty();58DeadFunctionsInComdats.clear();59DeadFunctions.clear();60return Changed;61}6263void CallGraphUpdater::reanalyzeFunction(Function &Fn) {64if (LCG) {65LazyCallGraph::Node &N = LCG->get(Fn);66LazyCallGraph::SCC *C = LCG->lookupSCC(N);67updateCGAndAnalysisManagerForCGSCCPass(*LCG, *C, N, *AM, *UR, *FAM);68}69}7071void CallGraphUpdater::registerOutlinedFunction(Function &OriginalFn,72Function &NewFn) {73if (LCG)74LCG->addSplitFunction(OriginalFn, NewFn);75}7677void CallGraphUpdater::removeFunction(Function &DeadFn) {78DeadFn.deleteBody();79DeadFn.setLinkage(GlobalValue::ExternalLinkage);80if (DeadFn.hasComdat())81DeadFunctionsInComdats.push_back(&DeadFn);82else83DeadFunctions.push_back(&DeadFn);8485if (FAM)86FAM->clear(DeadFn, DeadFn.getName());87}8889void CallGraphUpdater::replaceFunctionWith(Function &OldFn, Function &NewFn) {90OldFn.removeDeadConstantUsers();91ReplacedFunctions.insert(&OldFn);92if (LCG) {93// Directly substitute the functions in the call graph.94LazyCallGraph::Node &OldLCGN = LCG->get(OldFn);95SCC->getOuterRefSCC().replaceNodeFunction(OldLCGN, NewFn);96}97removeFunction(OldFn);98}99100101