1//===- Passes.cpp - Parsing, selection, and running of passes -------------===//
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/// \file
10///
11/// This file provides the infrastructure to parse and build a custom pass
12/// manager based on a commandline flag. It also provides helpers to aid in
13/// analyzing, debugging, and testing pass structures.
14///
15//===----------------------------------------------------------------------===//
16
17#include "Passes.h"
18#include "llvm/Analysis/CGSCCPassManager.h"
19#include "llvm/Analysis/LazyCallGraph.h"
20#include "llvm/IR/IRPrintingPasses.h"
21#include "llvm/IR/PassManager.h"
22#include "llvm/IR/Verifier.h"
23#include "llvm/Support/Debug.h"
24
25using namespace llvm;
26
27namespace {
28
29/// \brief No-op module pass which does nothing.
30struct NoOpModulePass {
31  PreservedAnalyses run(Module *M) { return PreservedAnalyses::all(); }
32  static StringRef name() { return "NoOpModulePass"; }
33};
34
35/// \brief No-op CGSCC pass which does nothing.
36struct NoOpCGSCCPass {
37  PreservedAnalyses run(LazyCallGraph::SCC *C) {
38    return PreservedAnalyses::all();
39  }
40  static StringRef name() { return "NoOpCGSCCPass"; }
41};
42
43/// \brief No-op function pass which does nothing.
44struct NoOpFunctionPass {
45  PreservedAnalyses run(Function *F) { return PreservedAnalyses::all(); }
46  static StringRef name() { return "NoOpFunctionPass"; }
47};
48
49} // End anonymous namespace.
50
51static bool isModulePassName(StringRef Name) {
52  if (Name == "no-op-module") return true;
53
54#define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
55#include "PassRegistry.def"
56
57  return false;
58}
59
60static bool isCGSCCPassName(StringRef Name) {
61  if (Name == "no-op-cgscc") return true;
62
63#define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
64#include "PassRegistry.def"
65
66  return false;
67}
68
69static bool isFunctionPassName(StringRef Name) {
70  if (Name == "no-op-function") return true;
71
72#define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
73#include "PassRegistry.def"
74
75  return false;
76}
77
78static bool parseModulePassName(ModulePassManager &MPM, StringRef Name) {
79  if (Name == "no-op-module") {
80    MPM.addPass(NoOpModulePass());
81    return true;
82  }
83
84#define MODULE_PASS(NAME, CREATE_PASS)                                         \
85  if (Name == NAME) {                                                          \
86    MPM.addPass(CREATE_PASS);                                                  \
87    return true;                                                               \
88  }
89#include "PassRegistry.def"
90
91  return false;
92}
93
94static bool parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) {
95  if (Name == "no-op-cgscc") {
96    CGPM.addPass(NoOpCGSCCPass());
97    return true;
98  }
99
100#define CGSCC_PASS(NAME, CREATE_PASS)                                          \
101  if (Name == NAME) {                                                          \
102    CGPM.addPass(CREATE_PASS);                                                 \
103    return true;                                                               \
104  }
105#include "PassRegistry.def"
106
107  return false;
108}
109
110static bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name) {
111  if (Name == "no-op-function") {
112    FPM.addPass(NoOpFunctionPass());
113    return true;
114  }
115
116#define FUNCTION_PASS(NAME, CREATE_PASS)                                       \
117  if (Name == NAME) {                                                          \
118    FPM.addPass(CREATE_PASS);                                                  \
119    return true;                                                               \
120  }
121#include "PassRegistry.def"
122
123  return false;
124}
125
126static bool parseFunctionPassPipeline(FunctionPassManager &FPM,
127                                      StringRef &PipelineText,
128                                      bool VerifyEachPass) {
129  for (;;) {
130    // Parse nested pass managers by recursing.
131    if (PipelineText.startswith("function(")) {
132      FunctionPassManager NestedFPM;
133
134      // Parse the inner pipeline inte the nested manager.
135      PipelineText = PipelineText.substr(strlen("function("));
136      if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
137          PipelineText.empty())
138        return false;
139      assert(PipelineText[0] == ')');
140      PipelineText = PipelineText.substr(1);
141
142      // Add the nested pass manager with the appropriate adaptor.
143      FPM.addPass(std::move(NestedFPM));
144    } else {
145      // Otherwise try to parse a pass name.
146      size_t End = PipelineText.find_first_of(",)");
147      if (!parseFunctionPassName(FPM, PipelineText.substr(0, End)))
148        return false;
149      if (VerifyEachPass)
150        FPM.addPass(VerifierPass());
151
152      PipelineText = PipelineText.substr(End);
153    }
154
155    if (PipelineText.empty() || PipelineText[0] == ')')
156      return true;
157
158    assert(PipelineText[0] == ',');
159    PipelineText = PipelineText.substr(1);
160  }
161}
162
163static bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
164                                      StringRef &PipelineText,
165                                      bool VerifyEachPass) {
166  for (;;) {
167    // Parse nested pass managers by recursing.
168    if (PipelineText.startswith("cgscc(")) {
169      CGSCCPassManager NestedCGPM;
170
171      // Parse the inner pipeline into the nested manager.
172      PipelineText = PipelineText.substr(strlen("cgscc("));
173      if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) ||
174          PipelineText.empty())
175        return false;
176      assert(PipelineText[0] == ')');
177      PipelineText = PipelineText.substr(1);
178
179      // Add the nested pass manager with the appropriate adaptor.
180      CGPM.addPass(std::move(NestedCGPM));
181    } else if (PipelineText.startswith("function(")) {
182      FunctionPassManager NestedFPM;
183
184      // Parse the inner pipeline inte the nested manager.
185      PipelineText = PipelineText.substr(strlen("function("));
186      if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
187          PipelineText.empty())
188        return false;
189      assert(PipelineText[0] == ')');
190      PipelineText = PipelineText.substr(1);
191
192      // Add the nested pass manager with the appropriate adaptor.
193      CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(NestedFPM)));
194    } else {
195      // Otherwise try to parse a pass name.
196      size_t End = PipelineText.find_first_of(",)");
197      if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End)))
198        return false;
199      // FIXME: No verifier support for CGSCC passes!
200
201      PipelineText = PipelineText.substr(End);
202    }
203
204    if (PipelineText.empty() || PipelineText[0] == ')')
205      return true;
206
207    assert(PipelineText[0] == ',');
208    PipelineText = PipelineText.substr(1);
209  }
210}
211
212static bool parseModulePassPipeline(ModulePassManager &MPM,
213                                    StringRef &PipelineText,
214                                    bool VerifyEachPass) {
215  for (;;) {
216    // Parse nested pass managers by recursing.
217    if (PipelineText.startswith("module(")) {
218      ModulePassManager NestedMPM;
219
220      // Parse the inner pipeline into the nested manager.
221      PipelineText = PipelineText.substr(strlen("module("));
222      if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass) ||
223          PipelineText.empty())
224        return false;
225      assert(PipelineText[0] == ')');
226      PipelineText = PipelineText.substr(1);
227
228      // Now add the nested manager as a module pass.
229      MPM.addPass(std::move(NestedMPM));
230    } else if (PipelineText.startswith("cgscc(")) {
231      CGSCCPassManager NestedCGPM;
232
233      // Parse the inner pipeline inte the nested manager.
234      PipelineText = PipelineText.substr(strlen("cgscc("));
235      if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) ||
236          PipelineText.empty())
237        return false;
238      assert(PipelineText[0] == ')');
239      PipelineText = PipelineText.substr(1);
240
241      // Add the nested pass manager with the appropriate adaptor.
242      MPM.addPass(
243          createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM)));
244    } else if (PipelineText.startswith("function(")) {
245      FunctionPassManager NestedFPM;
246
247      // Parse the inner pipeline inte the nested manager.
248      PipelineText = PipelineText.substr(strlen("function("));
249      if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
250          PipelineText.empty())
251        return false;
252      assert(PipelineText[0] == ')');
253      PipelineText = PipelineText.substr(1);
254
255      // Add the nested pass manager with the appropriate adaptor.
256      MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM)));
257    } else {
258      // Otherwise try to parse a pass name.
259      size_t End = PipelineText.find_first_of(",)");
260      if (!parseModulePassName(MPM, PipelineText.substr(0, End)))
261        return false;
262      if (VerifyEachPass)
263        MPM.addPass(VerifierPass());
264
265      PipelineText = PipelineText.substr(End);
266    }
267
268    if (PipelineText.empty() || PipelineText[0] == ')')
269      return true;
270
271    assert(PipelineText[0] == ',');
272    PipelineText = PipelineText.substr(1);
273  }
274}
275
276// Primary pass pipeline description parsing routine.
277// FIXME: Should this routine accept a TargetMachine or require the caller to
278// pre-populate the analysis managers with target-specific stuff?
279bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
280                             bool VerifyEachPass) {
281  // Look at the first entry to figure out which layer to start parsing at.
282  if (PipelineText.startswith("module("))
283    return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) &&
284           PipelineText.empty();
285  if (PipelineText.startswith("cgscc(")) {
286    CGSCCPassManager CGPM;
287    if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass) ||
288        !PipelineText.empty())
289      return false;
290    MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
291    return true;
292  }
293  if (PipelineText.startswith("function(")) {
294    FunctionPassManager FPM;
295    if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
296        !PipelineText.empty())
297      return false;
298    MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
299    return true;
300  }
301
302  // This isn't a direct pass manager name, look for the end of a pass name.
303  StringRef FirstName =
304      PipelineText.substr(0, PipelineText.find_first_of(",)"));
305  if (isModulePassName(FirstName))
306    return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) &&
307           PipelineText.empty();
308
309  if (isCGSCCPassName(FirstName)) {
310    CGSCCPassManager CGPM;
311    if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass) ||
312        !PipelineText.empty())
313      return false;
314    MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
315    return true;
316  }
317
318  if (isFunctionPassName(FirstName)) {
319    FunctionPassManager FPM;
320    if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
321        !PipelineText.empty())
322      return false;
323    MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
324    return true;
325  }
326
327  return false;
328}
329