brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.2 KiB · 794ba98 Raw
119 lines · cpp
1//===---- ScopInliner.cpp - Polyhedral based inliner ----------------------===//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// Take a SCC and:10// 1. If it has more than one component, bail out (contains cycles)11// 2. If it has just one component, and if the function is entirely a scop,12//    inline it.13//14//===----------------------------------------------------------------------===//15 16#include "polly/ScopInliner.h"17#include "polly/ScopDetection.h"18#include "polly/ScopInliner.h"19#include "llvm/Analysis/CallGraph.h"20#include "llvm/Analysis/CallGraphSCCPass.h"21#include "llvm/Analysis/OptimizationRemarkEmitter.h"22#include "llvm/Analysis/RegionInfo.h"23#include "llvm/IR/Dominators.h"24#include "llvm/Passes/PassBuilder.h"25#include "llvm/Transforms/IPO/AlwaysInliner.h"26 27#include "polly/Support/PollyDebug.h"28#define DEBUG_TYPE "polly-scop-inliner"29 30using namespace llvm;31using namespace polly;32 33namespace {34 35/// Inliner implementation that works with both, LPM (using SCC_t=CallGraph) and36/// NPM (using SCC_t=LazyCallGraph::SCC)37template <typename SCC_t> bool runScopInlinerImpl(Function *F, SCC_t &SCC) {38  // We do not try to inline non-trivial SCCs because this would lead to39  // "infinite" inlining if we are not careful.40  if (SCC.size() > 1)41    return false;42  assert(SCC.size() == 1 && "found empty SCC");43 44  // If the function is a nullptr, or the function is a declaration.45  if (!F)46    return false;47  if (F->isDeclaration()) {48    POLLY_DEBUG(dbgs() << "Skipping " << F->getName()49                       << "because it is a declaration.\n");50    return false;51  }52 53  PassBuilder PB;54  // Populate analysis managers and register Polly-specific analyses.55  LoopAnalysisManager LAM;56  FunctionAnalysisManager FAM;57  CGSCCAnalysisManager CGAM;58  ModuleAnalysisManager MAM;59  PB.registerModuleAnalyses(MAM);60  PB.registerCGSCCAnalyses(CGAM);61  PB.registerFunctionAnalyses(FAM);62  PB.registerLoopAnalyses(LAM);63  PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);64 65  auto &DT = FAM.getResult<DominatorTreeAnalysis>(*F);66  auto &SE = FAM.getResult<ScalarEvolutionAnalysis>(*F);67  auto &LI = FAM.getResult<LoopAnalysis>(*F);68  auto &RI = FAM.getResult<RegionInfoAnalysis>(*F);69  auto &AA = FAM.getResult<AAManager>(*F);70  auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(*F);71  ScopDetection SD(DT, SE, LI, RI, AA, ORE);72  SD.detect(*F);73 74  const bool HasScopAsTopLevelRegion =75      SD.ValidRegions.contains(RI.getTopLevelRegion());76 77  bool Changed = false;78  if (HasScopAsTopLevelRegion) {79    POLLY_DEBUG(dbgs() << "Skipping " << F->getName()80                       << " has scop as top level region");81    F->addFnAttr(llvm::Attribute::AlwaysInline);82 83    ModulePassManager MPM;84    MPM.addPass(AlwaysInlinerPass());85    Module *M = F->getParent();86    assert(M && "Function has illegal module");87    PreservedAnalyses PA = MPM.run(*M, MAM);88    if (!PA.areAllPreserved())89      Changed = true;90  } else {91    POLLY_DEBUG(dbgs() << F->getName()92                       << " does NOT have scop as top level region\n");93  }94 95  return Changed;96}97} // namespace98 99polly::ScopInlinerPass::ScopInlinerPass() {100  if (!polly::PollyAllowFullFunction) {101    report_fatal_error(102        "Aborting from ScopInliner because it only makes sense to run with "103        "-polly-allow-full-function. "104        "The heurtistic for ScopInliner checks that the full function is a "105        "Scop, which happens if and only if polly-allow-full-function is "106        " enabled. "107        " If not, the entry block is not included in the Scop");108  }109}110 111PreservedAnalyses polly::ScopInlinerPass::run(llvm::LazyCallGraph::SCC &SCC,112                                              llvm::CGSCCAnalysisManager &AM,113                                              llvm::LazyCallGraph &CG,114                                              llvm::CGSCCUpdateResult &UR) {115  Function *F = &SCC.begin()->getFunction();116  bool Changed = runScopInlinerImpl(F, SCC);117  return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();118}119