brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.4 KiB · 3b6fce5 Raw
100 lines · cpp
1//===- CallGraphUpdater.cpp - A (lazy) call graph update helper -----------===//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/// \file9///10/// This file provides interfaces used to manipulate a call graph, regardless11/// if it is a "old style" CallGraph or an "new style" LazyCallGraph.12///13//===----------------------------------------------------------------------===//14 15#include "llvm/Transforms/Utils/CallGraphUpdater.h"16#include "llvm/IR/Constants.h"17#include "llvm/Transforms/Utils/ModuleUtils.h"18 19using namespace llvm;20 21bool CallGraphUpdater::finalize() {22  if (!DeadFunctionsInComdats.empty()) {23    filterDeadComdatFunctions(DeadFunctionsInComdats);24    DeadFunctions.append(DeadFunctionsInComdats.begin(),25                         DeadFunctionsInComdats.end());26  }27 28  // This is the code path for the new lazy call graph and for the case were29  // no call graph was provided.30  for (Function *DeadFn : DeadFunctions) {31    DeadFn->removeDeadConstantUsers();32    DeadFn->replaceAllUsesWith(PoisonValue::get(DeadFn->getType()));33 34    if (LCG && !ReplacedFunctions.count(DeadFn)) {35      // Taken mostly from the inliner:36      LazyCallGraph::Node &N = LCG->get(*DeadFn);37      auto *DeadSCC = LCG->lookupSCC(N);38      assert(DeadSCC && DeadSCC->size() == 1 &&39             &DeadSCC->begin()->getFunction() == DeadFn);40 41      FAM->clear(*DeadFn, DeadFn->getName());42      AM->clear(*DeadSCC, DeadSCC->getName());43      LCG->markDeadFunction(*DeadFn);44 45      // Mark the relevant parts of the call graph as invalid so we don't46      // visit them.47      UR->InvalidatedSCCs.insert(LCG->lookupSCC(N));48      UR->DeadFunctions.push_back(DeadFn);49    } else {50      // The CGSCC infrastructure batch deletes functions at the end of the51      // call graph walk, so only erase the function if we're not using that52      // infrastructure.53      // The function is now really dead and de-attached from everything.54      DeadFn->eraseFromParent();55    }56  }57 58  bool Changed = !DeadFunctions.empty();59  DeadFunctionsInComdats.clear();60  DeadFunctions.clear();61  return Changed;62}63 64void CallGraphUpdater::reanalyzeFunction(Function &Fn) {65  if (LCG) {66    LazyCallGraph::Node &N = LCG->get(Fn);67    LazyCallGraph::SCC *C = LCG->lookupSCC(N);68    updateCGAndAnalysisManagerForCGSCCPass(*LCG, *C, N, *AM, *UR, *FAM);69  }70}71 72void CallGraphUpdater::registerOutlinedFunction(Function &OriginalFn,73                                                Function &NewFn) {74  if (LCG)75    LCG->addSplitFunction(OriginalFn, NewFn);76}77 78void CallGraphUpdater::removeFunction(Function &DeadFn) {79  DeadFn.deleteBody();80  DeadFn.setLinkage(GlobalValue::ExternalLinkage);81  if (DeadFn.hasComdat())82    DeadFunctionsInComdats.push_back(&DeadFn);83  else84    DeadFunctions.push_back(&DeadFn);85 86  if (FAM)87    FAM->clear(DeadFn, DeadFn.getName());88}89 90void CallGraphUpdater::replaceFunctionWith(Function &OldFn, Function &NewFn) {91  OldFn.removeDeadConstantUsers();92  ReplacedFunctions.insert(&OldFn);93  if (LCG) {94    // Directly substitute the functions in the call graph.95    LazyCallGraph::Node &OldLCGN = LCG->get(OldFn);96    SCC->getOuterRefSCC().replaceNodeFunction(OldLCGN, NewFn);97  }98  removeFunction(OldFn);99}100