Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/polly/lib/Transform/ScopInliner.cpp
Line
Count
Source (jump to first uncovered line)
1
//===---- ScopInliner.cpp - Polyhedral based inliner ----------------------===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
/// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
//
10
// Take a SCC and:
11
// 1. If it has more than one component, bail out (contains cycles)
12
// 2. If it has just one component, and if the function is entirely a scop,
13
//    inline it.
14
//
15
//===----------------------------------------------------------------------===//
16
17
#include "polly/LinkAllPasses.h"
18
#include "polly/RegisterPasses.h"
19
#include "polly/ScopDetection.h"
20
#include "llvm/Analysis/CallGraphSCCPass.h"
21
#include "llvm/IR/LLVMContext.h"
22
#include "llvm/IR/PassManager.h"
23
#include "llvm/Passes/PassBuilder.h"
24
#include "llvm/Transforms/IPO/AlwaysInliner.h"
25
26
#define DEBUG_TYPE "polly-scop-inliner"
27
28
using namespace polly;
29
extern bool polly::PollyAllowFullFunction;
30
31
namespace {
32
class ScopInliner : public CallGraphSCCPass {
33
  using llvm::Pass::doInitialization;
34
35
public:
36
  static char ID;
37
38
2
  ScopInliner() : CallGraphSCCPass(ID) {}
39
40
2
  bool doInitialization(CallGraph &CG) override {
41
2
    if (
!polly::PollyAllowFullFunction2
) {
42
0
      report_fatal_error(
43
0
          "Aborting from ScopInliner because it only makes sense to run with "
44
0
          "-polly-allow-full-function. "
45
0
          "The heurtistic for ScopInliner checks that the full function is a "
46
0
          "Scop, which happens if and only if polly-allow-full-function is "
47
0
          " enabled. "
48
0
          " If not, the entry block is not included in the Scop");
49
0
    }
50
2
    return true;
51
2
  }
52
53
6
  bool runOnSCC(CallGraphSCC &SCC) override {
54
6
    // We do not try to inline non-trivial SCCs because this would lead to
55
6
    // "infinite" inlining if we are not careful.
56
6
    if (SCC.size() > 1)
57
0
      return false;
58
6
    assert(SCC.size() == 1 && "found empty SCC");
59
6
    Function *F = (*SCC.begin())->getFunction();
60
6
61
6
    // If the function is a nullptr, or the function is a declaration.
62
6
    if (!F)
63
3
      return false;
64
3
    
if (3
F->isDeclaration()3
) {
65
1
      DEBUG(dbgs() << "Skipping " << F->getName()
66
1
                   << "because it is a declaration.\n");
67
1
      return false;
68
1
    }
69
2
70
2
    PassBuilder PB;
71
2
    FunctionAnalysisManager FAM;
72
2
    FAM.registerPass([] { return ScopAnalysis(); });
73
2
    PB.registerFunctionAnalyses(FAM);
74
2
75
2
    RegionInfo &RI = FAM.getResult<RegionInfoAnalysis>(*F);
76
2
    ScopDetection &SD = FAM.getResult<ScopAnalysis>(*F);
77
2
78
2
    const bool HasScopAsTopLevelRegion =
79
2
        SD.ValidRegions.count(RI.getTopLevelRegion()) > 0;
80
2
81
2
    if (
HasScopAsTopLevelRegion2
) {
82
2
      DEBUG(dbgs() << "Skipping " << F->getName()
83
2
                   << " has scop as top level region");
84
2
      F->addFnAttr(llvm::Attribute::AlwaysInline);
85
2
86
2
      ModuleAnalysisManager MAM;
87
2
      PB.registerModuleAnalyses(MAM);
88
2
      ModulePassManager MPM;
89
2
      MPM.addPass(AlwaysInlinerPass());
90
2
      Module *M = F->getParent();
91
2
      assert(M && "Function has illegal module");
92
2
      MPM.run(*M, MAM);
93
0
    } else {
94
0
      DEBUG(dbgs() << F->getName()
95
0
                   << " does NOT have scop as top level region\n");
96
0
    }
97
6
98
6
    return false;
99
6
  };
100
101
2
  void getAnalysisUsage(AnalysisUsage &AU) const override {
102
2
    CallGraphSCCPass::getAnalysisUsage(AU);
103
2
  }
104
};
105
106
} // namespace
107
char ScopInliner::ID;
108
109
0
Pass *polly::createScopInlinerPass() {
110
0
  ScopInliner *pass = new ScopInliner();
111
0
  return pass;
112
0
}
113
114
41.7k
INITIALIZE_PASS_BEGIN41.7k
(
115
41.7k
    ScopInliner, "polly-scop-inliner",
116
41.7k
    "inline functions based on how much of the function is a scop.", false,
117
41.7k
    false)
118
41.7k
INITIALIZE_PASS_END(
119
    ScopInliner, "polly-scop-inliner",
120
    "inline functions based on how much of the function is a scop.", false,
121
    false)