Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Analysis/RegionPass.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- RegionPass.cpp - Region Pass and Region Pass Manager ---------------===//
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-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file implements RegionPass and RGPassManager. All region optimization
10
// and transformation passes are derived from RegionPass. RGPassManager is
11
// responsible for managing RegionPasses.
12
// Most of this code has been COPIED from LoopPass.cpp
13
//
14
//===----------------------------------------------------------------------===//
15
#include "llvm/Analysis/RegionPass.h"
16
#include "llvm/IR/OptBisect.h"
17
#include "llvm/IR/PassTimingInfo.h"
18
#include "llvm/Support/Debug.h"
19
#include "llvm/Support/Timer.h"
20
#include "llvm/Support/raw_ostream.h"
21
using namespace llvm;
22
23
#define DEBUG_TYPE "regionpassmgr"
24
25
//===----------------------------------------------------------------------===//
26
// RGPassManager
27
//
28
29
char RGPassManager::ID = 0;
30
31
RGPassManager::RGPassManager()
32
3.86k
  : FunctionPass(ID), PMDataManager() {
33
3.86k
  skipThisRegion = false;
34
3.86k
  redoThisRegion = false;
35
3.86k
  RI = nullptr;
36
3.86k
  CurrentRegion = nullptr;
37
3.86k
}
38
39
// Recurse through all subregions and all regions  into RQ.
40
33.2k
static void addRegionIntoQueue(Region &R, std::deque<Region *> &RQ) {
41
33.2k
  RQ.push_back(&R);
42
33.2k
  for (const auto &E : R)
43
4.43k
    addRegionIntoQueue(*E, RQ);
44
33.2k
}
45
46
/// Pass Manager itself does not invalidate any analysis info.
47
3.86k
void RGPassManager::getAnalysisUsage(AnalysisUsage &Info) const {
48
3.86k
  Info.addRequired<RegionInfoPass>();
49
3.86k
  Info.setPreservesAll();
50
3.86k
}
51
52
/// run - Execute all of the passes scheduled for execution.  Keep track of
53
/// whether any of the passes modifies the function, and if so, return true.
54
28.8k
bool RGPassManager::runOnFunction(Function &F) {
55
28.8k
  RI = &getAnalysis<RegionInfoPass>().getRegionInfo();
56
28.8k
  bool Changed = false;
57
28.8k
58
28.8k
  // Collect inherited analysis from Module level pass manager.
59
28.8k
  populateInheritedAnalysis(TPM->activeStack);
60
28.8k
61
28.8k
  addRegionIntoQueue(*RI->getTopLevelRegion(), RQ);
62
28.8k
63
28.8k
  if (RQ.empty()) // No regions, skip calling finalizers
64
0
    return false;
65
28.8k
66
28.8k
  // Initialization
67
33.2k
  
for (Region *R : RQ)28.8k
{
68
76.8k
    for (unsigned Index = 0; Index < getNumContainedPasses(); 
++Index43.6k
) {
69
43.6k
      RegionPass *RP = (RegionPass *)getContainedPass(Index);
70
43.6k
      Changed |= RP->doInitialization(R, *this);
71
43.6k
    }
72
33.2k
  }
73
28.8k
74
28.8k
  // Walk Regions
75
62.0k
  while (!RQ.empty()) {
76
33.2k
77
33.2k
    CurrentRegion  = RQ.back();
78
33.2k
    skipThisRegion = false;
79
33.2k
    redoThisRegion = false;
80
33.2k
81
33.2k
    // Run all passes on the current Region.
82
76.7k
    for (unsigned Index = 0; Index < getNumContainedPasses(); 
++Index43.5k
) {
83
43.5k
      RegionPass *P = (RegionPass*)getContainedPass(Index);
84
43.5k
85
43.5k
      if (isPassDebuggingExecutionsOrMore()) {
86
0
        dumpPassInfo(P, EXECUTION_MSG, ON_REGION_MSG,
87
0
                     CurrentRegion->getNameStr());
88
0
        dumpRequiredSet(P);
89
0
      }
90
43.5k
91
43.5k
      initializeAnalysisImpl(P);
92
43.5k
93
43.5k
      {
94
43.5k
        PassManagerPrettyStackEntry X(P, *CurrentRegion->getEntry());
95
43.5k
96
43.5k
        TimeRegion PassTimer(getPassTimer(P));
97
43.5k
        Changed |= P->runOnRegion(CurrentRegion, *this);
98
43.5k
      }
99
43.5k
100
43.5k
      if (isPassDebuggingExecutionsOrMore()) {
101
0
        if (Changed)
102
0
          dumpPassInfo(P, MODIFICATION_MSG, ON_REGION_MSG,
103
0
                       skipThisRegion ? "<deleted>" :
104
0
                                      CurrentRegion->getNameStr());
105
0
        dumpPreservedSet(P);
106
0
      }
107
43.5k
108
43.5k
      if (!skipThisRegion) {
109
43.5k
        // Manually check that this region is still healthy. This is done
110
43.5k
        // instead of relying on RegionInfo::verifyRegion since RegionInfo
111
43.5k
        // is a function pass and it's really expensive to verify every
112
43.5k
        // Region in the function every time. That level of checking can be
113
43.5k
        // enabled with the -verify-region-info option.
114
43.5k
        {
115
43.5k
          TimeRegion PassTimer(getPassTimer(P));
116
43.5k
          CurrentRegion->verifyRegion();
117
43.5k
        }
118
43.5k
119
43.5k
        // Then call the regular verifyAnalysis functions.
120
43.5k
        verifyPreservedAnalysis(P);
121
43.5k
      }
122
43.5k
123
43.5k
      removeNotPreservedAnalysis(P);
124
43.5k
      recordAvailableAnalysis(P);
125
43.5k
      removeDeadPasses(P,
126
43.5k
                       (!isPassDebuggingExecutionsOrMore() || 
skipThisRegion0
) ?
127
43.5k
                       "<deleted>" :  
CurrentRegion->getNameStr()23
,
128
43.5k
                       ON_REGION_MSG);
129
43.5k
130
43.5k
      if (skipThisRegion)
131
0
        // Do not run other passes on this region.
132
0
        break;
133
43.5k
    }
134
33.2k
135
33.2k
    // If the region was deleted, release all the region passes. This frees up
136
33.2k
    // some memory, and avoids trouble with the pass manager trying to call
137
33.2k
    // verifyAnalysis on them.
138
33.2k
    if (skipThisRegion)
139
0
      for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
140
0
        Pass *P = getContainedPass(Index);
141
0
        freePass(P, "<deleted>", ON_REGION_MSG);
142
0
      }
143
33.2k
144
33.2k
    // Pop the region from queue after running all passes.
145
33.2k
    RQ.pop_back();
146
33.2k
147
33.2k
    if (redoThisRegion)
148
0
      RQ.push_back(CurrentRegion);
149
33.2k
150
33.2k
    // Free all region nodes created in region passes.
151
33.2k
    RI->clearNodeCache();
152
33.2k
  }
153
28.8k
154
28.8k
  // Finalization
155
60.4k
  for (unsigned Index = 0; Index < getNumContainedPasses(); 
++Index31.6k
) {
156
31.6k
    RegionPass *P = (RegionPass*)getContainedPass(Index);
157
31.6k
    Changed |= P->doFinalization();
158
31.6k
  }
159
28.8k
160
28.8k
  // Print the region tree after all pass.
161
28.8k
  LLVM_DEBUG(dbgs() << "\nRegion tree of function " << F.getName()
162
28.8k
                    << " after all region Pass:\n";
163
28.8k
             RI->dump(); dbgs() << "\n";);
164
28.8k
165
28.8k
  return Changed;
166
28.8k
}
167
168
/// Print passes managed by this manager
169
0
void RGPassManager::dumpPassStructure(unsigned Offset) {
170
0
  errs().indent(Offset*2) << "Region Pass Manager\n";
171
0
  for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
172
0
    Pass *P = getContainedPass(Index);
173
0
    P->dumpPassStructure(Offset + 1);
174
0
    dumpLastUses(P, Offset+1);
175
0
  }
176
0
}
177
178
namespace {
179
//===----------------------------------------------------------------------===//
180
// PrintRegionPass
181
class PrintRegionPass : public RegionPass {
182
private:
183
  std::string Banner;
184
  raw_ostream &Out;       // raw_ostream to print on.
185
186
public:
187
  static char ID;
188
  PrintRegionPass(const std::string &B, raw_ostream &o)
189
0
      : RegionPass(ID), Banner(B), Out(o) {}
190
191
0
  void getAnalysisUsage(AnalysisUsage &AU) const override {
192
0
    AU.setPreservesAll();
193
0
  }
194
195
0
  bool runOnRegion(Region *R, RGPassManager &RGM) override {
196
0
    Out << Banner;
197
0
    for (const auto *BB : R->blocks()) {
198
0
      if (BB)
199
0
        BB->print(Out);
200
0
      else
201
0
        Out << "Printing <null> Block";
202
0
    }
203
0
204
0
    return false;
205
0
  }
206
207
0
  StringRef getPassName() const override { return "Print Region IR"; }
208
};
209
210
char PrintRegionPass::ID = 0;
211
}  //end anonymous namespace
212
213
//===----------------------------------------------------------------------===//
214
// RegionPass
215
216
// Check if this pass is suitable for the current RGPassManager, if
217
// available. This pass P is not suitable for a RGPassManager if P
218
// is not preserving higher level analysis info used by other
219
// RGPassManager passes. In such case, pop RGPassManager from the
220
// stack. This will force assignPassManager() to create new
221
// LPPassManger as expected.
222
6.49k
void RegionPass::preparePassManager(PMStack &PMS) {
223
6.49k
224
6.49k
  // Find RGPassManager
225
6.49k
  while (!PMS.empty() &&
226
6.49k
         PMS.top()->getPassManagerType() > PMT_RegionPassManager)
227
0
    PMS.pop();
228
6.49k
229
6.49k
230
6.49k
  // If this pass is destroying high level information that is used
231
6.49k
  // by other passes that are managed by LPM then do not insert
232
6.49k
  // this pass in current LPM. Use new RGPassManager.
233
6.49k
  if (PMS.top()->getPassManagerType() == PMT_RegionPassManager &&
234
6.49k
    
!PMS.top()->preserveHigherLevelAnalysis(this)1.95k
)
235
0
    PMS.pop();
236
6.49k
}
237
238
/// Assign pass manager to manage this pass.
239
void RegionPass::assignPassManager(PMStack &PMS,
240
6.49k
                                 PassManagerType PreferredType) {
241
6.49k
  // Find RGPassManager
242
6.49k
  while (!PMS.empty() &&
243
6.49k
         PMS.top()->getPassManagerType() > PMT_RegionPassManager)
244
0
    PMS.pop();
245
6.49k
246
6.49k
  RGPassManager *RGPM;
247
6.49k
248
6.49k
  // Create new Region Pass Manager if it does not exist.
249
6.49k
  if (PMS.top()->getPassManagerType() == PMT_RegionPassManager)
250
2.63k
    RGPM = (RGPassManager*)PMS.top();
251
3.86k
  else {
252
3.86k
253
3.86k
    assert (!PMS.empty() && "Unable to create Region Pass Manager");
254
3.86k
    PMDataManager *PMD = PMS.top();
255
3.86k
256
3.86k
    // [1] Create new Region Pass Manager
257
3.86k
    RGPM = new RGPassManager();
258
3.86k
    RGPM->populateInheritedAnalysis(PMS);
259
3.86k
260
3.86k
    // [2] Set up new manager's top level manager
261
3.86k
    PMTopLevelManager *TPM = PMD->getTopLevelManager();
262
3.86k
    TPM->addIndirectPassManager(RGPM);
263
3.86k
264
3.86k
    // [3] Assign manager to manage this new manager. This may create
265
3.86k
    // and push new managers into PMS
266
3.86k
    TPM->schedulePass(RGPM);
267
3.86k
268
3.86k
    // [4] Push new manager into PMS
269
3.86k
    PMS.push(RGPM);
270
3.86k
  }
271
6.49k
272
6.49k
  RGPM->add(this);
273
6.49k
}
274
275
/// Get the printer pass
276
Pass *RegionPass::createPrinterPass(raw_ostream &O,
277
0
                                  const std::string &Banner) const {
278
0
  return new PrintRegionPass(Banner, O);
279
0
}
280
281
0
static std::string getDescription(const Region &R) {
282
0
  return "region";
283
0
}
284
285
6.82k
bool RegionPass::skipRegion(Region &R) const {
286
6.82k
  Function &F = *R.getEntry()->getParent();
287
6.82k
  OptPassGate &Gate = F.getContext().getOptPassGate();
288
6.82k
  if (Gate.isEnabled() && 
!Gate.shouldRunPass(this, getDescription(R))0
)
289
0
    return true;
290
6.82k
291
6.82k
  if (F.hasOptNone()) {
292
0
    // Report this only once per function.
293
0
    if (R.getEntry() == &F.getEntryBlock())
294
0
      LLVM_DEBUG(dbgs() << "Skipping pass '" << getPassName()
295
0
                        << "' on function " << F.getName() << "\n");
296
0
    return true;
297
0
  }
298
6.82k
  return false;
299
6.82k
}