LLVM 22.0.0git
PassManager.h
Go to the documentation of this file.
1//===- PassManager.h --------------------------------------------*- C++ -*-===//
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// Registers and executes the Sandbox IR passes.
10//
11// The pass manager contains an ordered sequence of passes that it runs in
12// order. The passes are owned by the PassRegistry, not by the PassManager.
13//
14// Note that in this design a pass manager is also a pass. So a pass manager
15// runs when it is it's turn to run in its parent pass-manager pass pipeline.
16//
17
18#ifndef LLVM_SANDBOXIR_PASSMANAGER_H
19#define LLVM_SANDBOXIR_PASSMANAGER_H
20
22#include <memory>
23
24#include "llvm/ADT/DenseMap.h"
25#include "llvm/ADT/STLExtras.h"
26#include "llvm/SandboxIR/Pass.h"
27#include "llvm/Support/Debug.h"
28
29namespace llvm::sandboxir {
30
31class Value;
32
33/// Base class.
34template <typename ParentPass, typename ContainedPass>
35class PassManager : public ParentPass {
36public:
37 // CreatePassFunc(StringRef PassName, StringRef PassArgs).
39 std::function<std::unique_ptr<ContainedPass>(StringRef, StringRef)>;
40
41protected:
42 /// The list of passes that this pass manager will run.
44
47 : ParentPass(Name) {
48 setPassPipeline(Pipeline, CreatePass);
49 }
50 PassManager(const PassManager &) = delete;
51 PassManager(PassManager &&) = default;
52 virtual ~PassManager() = default;
53 PassManager &operator=(const PassManager &) = delete;
54
55public:
56 /// Adds \p Pass to the pass pipeline.
57 void addPass(std::unique_ptr<ContainedPass> Pass) {
58 // TODO: Check that Pass's class type works with this PassManager type.
59 Passes.push_back(std::move(Pass));
60 }
61
62 static constexpr const char EndToken = '\0';
63 static constexpr const char BeginArgsToken = '<';
64 static constexpr const char EndArgsToken = '>';
65 static constexpr const char PassDelimToken = ',';
66
67 /// Parses \p Pipeline as a comma-separated sequence of pass names and sets
68 /// the pass pipeline, using \p CreatePass to instantiate passes by name.
69 ///
70 /// Passes can have arguments, for example:
71 /// "pass1<arg1,arg2>,pass2,pass3<arg3,arg4>"
72 ///
73 /// The arguments between angle brackets are treated as a mostly opaque string
74 /// and each pass is responsible for parsing its arguments. The exception to
75 /// this are nested angle brackets, which must match pair-wise to allow
76 /// arguments to contain nested pipelines, like:
77 ///
78 /// "pass1<subpass1,subpass2<arg1,arg2>,subpass3>"
79 ///
80 /// An empty args string is treated the same as no args, so "pass" and
81 /// "pass<>" are equivalent.
82 void setPassPipeline(StringRef Pipeline, CreatePassFunc CreatePass) {
84 "setPassPipeline called on a non-empty sandboxir::PassManager");
85
86 // Accept an empty pipeline as a special case. This can be useful, for
87 // example, to test conversion to SandboxIR without running any passes on
88 // it.
89 if (Pipeline.empty())
90 return;
91
92 // Add EndToken to the end to ease parsing.
93 std::string PipelineStr = std::string(Pipeline) + EndToken;
94 Pipeline = StringRef(PipelineStr);
95
96 auto AddPass = [this, CreatePass](StringRef PassName, StringRef PassArgs) {
97 if (PassName.empty()) {
98 errs() << "Found empty pass name.\n";
99 exit(1);
100 }
101 // Get the pass that corresponds to PassName and add it to the pass
102 // manager.
103 auto Pass = CreatePass(PassName, PassArgs);
104 if (Pass == nullptr) {
105 errs() << "Pass '" << PassName << "' not registered!\n";
106 exit(1);
107 }
108 addPass(std::move(Pass));
109 };
110
111 enum class State {
112 ScanName, // reading a pass name
113 ScanArgs, // reading a list of args
114 ArgsEnded, // read the last '>' in an args list, must read delimiter next
115 } CurrentState = State::ScanName;
116 int PassBeginIdx = 0;
117 int ArgsBeginIdx;
119 int NestedArgs = 0;
120 for (auto [Idx, C] : enumerate(Pipeline)) {
121 switch (CurrentState) {
122 case State::ScanName:
123 if (C == BeginArgsToken) {
124 // Save pass name for later and begin scanning args.
125 PassName = Pipeline.slice(PassBeginIdx, Idx);
126 ArgsBeginIdx = Idx + 1;
127 ++NestedArgs;
128 CurrentState = State::ScanArgs;
129 break;
130 }
131 if (C == EndArgsToken) {
132 errs() << "Unexpected '>' in pass pipeline.\n";
133 exit(1);
134 }
135 if (C == EndToken || C == PassDelimToken) {
136 // Delimiter found, add the pass (with empty args), stay in the
137 // ScanName state.
138 AddPass(Pipeline.slice(PassBeginIdx, Idx), StringRef());
139 PassBeginIdx = Idx + 1;
140 }
141 break;
142 case State::ScanArgs:
143 // While scanning args, we only care about making sure nesting of angle
144 // brackets is correct.
145 if (C == BeginArgsToken) {
146 ++NestedArgs;
147 break;
148 }
149 if (C == EndArgsToken) {
150 --NestedArgs;
151 if (NestedArgs == 0) {
152 // Done scanning args.
153 AddPass(PassName, Pipeline.slice(ArgsBeginIdx, Idx));
154 CurrentState = State::ArgsEnded;
155 } else if (NestedArgs < 0) {
156 errs() << "Unexpected '>' in pass pipeline.\n";
157 exit(1);
158 }
159 break;
160 }
161 if (C == EndToken) {
162 errs() << "Missing '>' in pass pipeline. End-of-string reached while "
163 "reading arguments for pass '"
164 << PassName << "'.\n";
165 exit(1);
166 }
167 break;
168 case State::ArgsEnded:
169 // Once we're done scanning args, only a delimiter is valid. This avoids
170 // accepting strings like "foo<args><more-args>" or "foo<args>bar".
171 if (C == EndToken || C == PassDelimToken) {
172 PassBeginIdx = Idx + 1;
173 CurrentState = State::ScanName;
174 } else {
175 errs() << "Expected delimiter or end-of-string after pass "
176 "arguments.\n";
177 exit(1);
178 }
179 break;
180 }
181 }
182 }
183
184#ifndef NDEBUG
185 void print(raw_ostream &OS) const override {
186 OS << this->getName();
187 OS << BeginArgsToken;
188 std::string Delim(1, PassDelimToken);
189 interleave(Passes, OS, [&OS](auto &Pass) { Pass->print(OS); }, Delim);
190 OS << EndArgsToken;
191 }
192 LLVM_DUMP_METHOD void dump() const override {
193 print(dbgs());
194 dbgs() << "\n";
195 }
196#endif
197 /// Similar to print() but prints one pass per line. Used for testing.
198 void printPipeline(raw_ostream &OS) const override {
199 OS << this->getName() << "\n";
200 for (const auto &PassPtr : Passes)
201 PassPtr->printPipeline(OS);
202 }
203};
204
206 : public PassManager<FunctionPass, FunctionPass> {
207public:
210 CreatePassFunc CreatePass)
211 : PassManager(Name, Pipeline, CreatePass) {}
212 bool runOnFunction(Function &F, const Analyses &A) final;
213};
214
216 : public PassManager<RegionPass, RegionPass> {
217public:
220 CreatePassFunc CreatePass)
221 : PassManager(Name, Pipeline, CreatePass) {}
222 bool runOnRegion(Region &R, const Analyses &A) final;
223};
224
225} // namespace llvm::sandboxir
226
227#endif // LLVM_SANDBOXIR_PASSMANAGER_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_ABI
Definition: Compiler.h:213
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:638
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
std::string Name
static bool runOnFunction(Function &F, bool PostInlining)
#define F(x, y, z)
Definition: MD5.cpp:55
static StringRef getName(Value *V)
This file contains some templates that are useful if you are working with the STL at all.
raw_pwrite_stream & OS
static const char PassName[]
bool empty() const
Definition: SmallVector.h:82
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:151
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition: StringRef.h:694
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
FunctionPassManager(StringRef Name, StringRef Pipeline, CreatePassFunc CreatePass)
Definition: PassManager.h:209
PassManager(const PassManager &)=delete
static constexpr const char PassDelimToken
Definition: PassManager.h:65
void addPass(std::unique_ptr< ContainedPass > Pass)
Adds Pass to the pass pipeline.
Definition: PassManager.h:57
void printPipeline(raw_ostream &OS) const override
Similar to print() but prints one pass per line. Used for testing.
Definition: PassManager.h:198
std::function< std::unique_ptr< ContainedPass >(StringRef, StringRef)> CreatePassFunc
Definition: PassManager.h:39
static constexpr const char EndToken
Definition: PassManager.h:62
PassManager(StringRef Name)
Definition: PassManager.h:45
void setPassPipeline(StringRef Pipeline, CreatePassFunc CreatePass)
Parses Pipeline as a comma-separated sequence of pass names and sets the pass pipeline,...
Definition: PassManager.h:82
PassManager(PassManager &&)=default
void print(raw_ostream &OS) const override
Definition: PassManager.h:185
PassManager(StringRef Name, StringRef Pipeline, CreatePassFunc CreatePass)
Definition: PassManager.h:46
PassManager & operator=(const PassManager &)=delete
LLVM_DUMP_METHOD void dump() const override
Definition: PassManager.h:192
static constexpr const char EndArgsToken
Definition: PassManager.h:64
virtual ~PassManager()=default
static constexpr const char BeginArgsToken
Definition: PassManager.h:63
SmallVector< std::unique_ptr< ContainedPass > > Passes
The list of passes that this pass manager will run.
Definition: PassManager.h:43
The base class of a Sandbox IR Pass.
Definition: Pass.h:46
virtual void print(raw_ostream &OS) const
Definition: Pass.h:67
RegionPassManager(StringRef Name, StringRef Pipeline, CreatePassFunc CreatePass)
Definition: PassManager.h:219
The main job of the Region is to point to new instructions generated by vectorization passes.
Definition: Region.h:96
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition: STLExtras.h:2491
void interleave(ForwardIterator begin, ForwardIterator end, UnaryFunctor each_fn, NullaryFunctor between_fn)
An STL-style algorithm similar to std::for_each that applies a second functor between every pair of e...
Definition: STLExtras.h:2212
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.