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 | |
25 | namespace glow { |
26 | |
27 | /// Base class for all pass pipelines providing some common functionality. |
28 | class PassPipelineBase { |
29 | protected: |
30 | /// \returns pass config at index \p i. |
31 | virtual const PassConfigBase &elementAt(size_t i) const = 0; |
32 | |
33 | public: |
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. |
49 | template <typename PASS> |
50 | class PassPipeline |
51 | : public PassPipelineBase, |
52 | private llvm::SmallVector<typename PASS::IRPassConfigTy, 16> { |
53 | public: |
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 | |
60 | private: |
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 | |
75 | public: |
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 | |