1/**
2 * Copyright (c) Glow Contributors. See CONTRIBUTORS file.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#ifndef GLOW_PASSMANAGER_PIPELINE_H
17#define GLOW_PASSMANAGER_PIPELINE_H
18
19#include "PassConfig.h"
20#include "glow/Optimizer/GraphOptimizer/CompilationContext.h"
21#include "glow/Support/Support.h"
22
23#include <iterator>
24
25namespace glow {
26
27/// Base class for all pass pipelines providing some common functionality.
28class PassPipelineBase {
29protected:
30 /// \returns pass config at index \p i.
31 virtual const PassConfigBase &elementAt(size_t i) const = 0;
32
33public:
34 /// Constructor.
35 PassPipelineBase() = default;
36
37 /// Destructor.
38 virtual ~PassPipelineBase() = default;
39
40 /// Dump a textual representation of the pipeline to \p os.
41 virtual void dump(llvm::raw_ostream &os = llvm::outs()) const;
42
43 /// \returns size of pipeline.
44 virtual size_t size() const = 0;
45};
46
47/// Implementation of a pipeline for executing a series of passes. Each pass
48/// should be of type \p PASS or a type derived from it.
49template <typename PASS>
50class PassPipeline
51 : public PassPipelineBase,
52 private llvm::SmallVector<typename PASS::IRPassConfigTy, 16> {
53public:
54 using IRPassConfigTy = typename PASS::IRPassConfigTy;
55 using PassIDTy = typename IRPassConfigTy::PassIDTy;
56 using Base = llvm::SmallVector<IRPassConfigTy, 16>;
57 using iterator = typename Base::iterator;
58 using const_iterator = typename Base::const_iterator;
59
60private:
61 /// Removes the first instance of a pass with ID \p passID. \returns whether
62 /// an instance of the pass was successfully found and removed.
63 bool removeFirstInstanceOfPass(PassIDTy passID) {
64 for (auto it = begin(); it != end(); it++) {
65 if (static_cast<PassIDTy>(it->getID()) == passID) {
66 this->erase(it);
67 return true;
68 }
69 }
70 return false;
71 }
72
73 const PassConfigBase &elementAt(size_t i) const override { return at(i); }
74
75public:
76 /// Constructor.
77 PassPipeline() = default;
78
79 /// Constructor for a PassPipeline from an initializer_list \p configs.
80 PassPipeline(std::initializer_list<IRPassConfigTy> configs) {
81 pushBack(configs);
82 }
83
84 /// \returns size of pipeline.
85 size_t size() const override { return Base::size(); }
86
87 /// Forward iterator creation methods.
88 ///@{
89 iterator begin() { return Base::begin(); }
90 const_iterator begin() const { return Base::begin(); }
91 iterator end() { return begin() + size(); }
92 const_iterator end() const { return begin() + size(); }
93 /// @}
94
95 /// Helper to get the IRPassConfig at index \p i in the pipeline.
96 const IRPassConfigTy &at(size_t i) const {
97 const PassConfigBase &config = begin()[i];
98 return *static_cast<const IRPassConfigTy *>(&config);
99 }
100
101 /// Push a new \p IRPC to the end of the pipeline.
102 void pushBack(const IRPassConfigTy &IRPC) { Base::push_back(IRPC); }
103
104 /// Push \p configs to the end of the pipeline.
105 void pushBack(const std::initializer_list<IRPassConfigTy> &configs) {
106 for (auto &config : configs) {
107 pushBack(config);
108 }
109 }
110
111 /// Push \p configs to the end of the pipeline.
112 void pushBack(llvm::ArrayRef<IRPassConfigTy> configs) {
113 for (auto &config : configs) {
114 pushBack(config);
115 }
116 }
117
118 /// Push a new \p IRPC to the start of the pipeline.
119 void pushFront(const IRPassConfigTy &IRPC) { Base::insert(begin(), IRPC); }
120
121 /// Removes all instances of a pass with ID \p passID.
122 void removeAllInstancesOfPass(PassIDTy passID) {
123 while (removeFirstInstanceOfPass(passID)) {
124 }
125 }
126
127 /// Initialize the pipeline from a file with a name \p pipelineDefFilename.
128 virtual void initFromFile(llvm::StringRef pipelineDefFilename);
129
130 /// Dump pipeline definition into a file with a name \p pipelineDefFilename.
131 virtual void dumpToFile(llvm::StringRef pipelineDefFilename);
132
133 bool equals(const PassPipeline &other) const {
134 if (size() != other.size()) {
135 return false;
136 }
137 for (unsigned idx = 0, e = size(); idx < e; ++idx) {
138 if (!at(idx).equals(other.at(idx))) {
139 return false;
140 }
141 }
142 return true;
143 }
144};
145
146} // namespace glow
147
148#endif // GLOW_PASSMANAGER_PIPELINE_H
149