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