blob: 59a04e7e7f7c736c62d33a67b22a1606ad044904 [file] [log] [blame]
Ben Clayton00b77a82020-12-04 09:06:09 +00001// Copyright 2020 The Tint Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef SRC_TRANSFORM_TRANSFORM_H_
16#define SRC_TRANSFORM_TRANSFORM_H_
17
18#include <memory>
Ben Claytoneb496d02021-02-24 15:55:24 +000019#include <unordered_map>
Ben Clayton00b77a82020-12-04 09:06:09 +000020#include <utility>
21
Ben Claytonb5cd10c2021-06-25 10:26:26 +000022#include "src/castable.h"
Ben Claytond59cedb2021-01-25 18:14:08 +000023#include "src/program.h"
Ben Clayton00b77a82020-12-04 09:06:09 +000024
25namespace tint {
26namespace transform {
27
Ben Claytonaf8a8ac2021-03-29 21:03:59 +000028/// Data is the base class for transforms that accept extra input or emit extra
29/// output information along with a Program.
Ben Claytoneb496d02021-02-24 15:55:24 +000030class Data : public Castable<Data> {
31 public:
32 /// Constructor
33 Data();
34
35 /// Copy constructor
36 Data(const Data&);
37
38 /// Destructor
39 ~Data() override;
Ben Clayton12ac6e52021-04-13 18:46:47 +000040
41 /// Assignment operator
42 /// @returns this Data
43 Data& operator=(const Data&);
Ben Claytoneb496d02021-02-24 15:55:24 +000044};
45
46/// DataMap is a map of Data unique pointers keyed by the Data's ClassID.
47class DataMap {
48 public:
49 /// Constructor
50 DataMap();
51
52 /// Move constructor
53 DataMap(DataMap&&);
54
55 /// Constructor
56 /// @param data_unique_ptrs a variadic list of additional data unique_ptrs
57 /// produced by the transform
58 template <typename... DATA>
59 explicit DataMap(DATA... data_unique_ptrs) {
60 PutAll(std::forward<DATA>(data_unique_ptrs)...);
61 }
62
63 /// Destructor
64 ~DataMap();
65
Ben Clayton856a3682021-04-16 08:35:24 +000066 /// Move assignment operator
67 /// @param rhs the DataMap to move into this DataMap
68 /// @return this DataMap
69 DataMap& operator=(DataMap&& rhs);
70
Ben Claytoneb496d02021-02-24 15:55:24 +000071 /// Adds the data into DataMap keyed by the ClassID of type T.
72 /// @param data the data to add to the DataMap
73 template <typename T>
74 void Put(std::unique_ptr<T>&& data) {
75 static_assert(std::is_base_of<Data, T>::value,
76 "T does not derive from Data");
Ben Claytone8791432021-03-02 20:30:08 +000077 map_[&TypeInfo::Of<T>()] = std::move(data);
Ben Claytoneb496d02021-02-24 15:55:24 +000078 }
79
Ben Claytonaf8a8ac2021-03-29 21:03:59 +000080 /// Creates the data of type `T` with the provided arguments and adds it into
81 /// DataMap keyed by the ClassID of type T.
82 /// @param args the arguments forwarded to the constructor for type T
83 template <typename T, typename... ARGS>
84 void Add(ARGS&&... args) {
85 Put(std::make_unique<T>(std::forward<ARGS>(args)...));
86 }
87
Ben Claytoneb496d02021-02-24 15:55:24 +000088 /// @returns a pointer to the Data placed into the DataMap with a call to
89 /// Put()
90 template <typename T>
91 T const* Get() const {
Ben Claytone8791432021-03-02 20:30:08 +000092 auto it = map_.find(&TypeInfo::Of<T>());
Ben Claytoneb496d02021-02-24 15:55:24 +000093 if (it == map_.end()) {
94 return nullptr;
95 }
96 return static_cast<T*>(it->second.get());
97 }
98
99 /// Add moves all the data from other into this DataMap
100 /// @param other the DataMap to move into this DataMap
101 void Add(DataMap&& other) {
102 for (auto& it : other.map_) {
103 map_.emplace(it.first, std::move(it.second));
104 }
105 other.map_.clear();
106 }
107
108 private:
109 template <typename T0>
110 void PutAll(T0&& first) {
111 Put(std::forward<T0>(first));
112 }
113
114 template <typename T0, typename... Tn>
115 void PutAll(T0&& first, Tn&&... remainder) {
116 Put(std::forward<T0>(first));
117 PutAll(std::forward<Tn>(remainder)...);
118 }
119
Ben Claytone8791432021-03-02 20:30:08 +0000120 std::unordered_map<const TypeInfo*, std::unique_ptr<Data>> map_;
Ben Claytoneb496d02021-02-24 15:55:24 +0000121};
122
Ben Clayton856a3682021-04-16 08:35:24 +0000123/// The return type of Run()
124class Output {
125 public:
126 /// Constructor
127 Output();
128
129 /// Constructor
130 /// @param program the program to move into this Output
131 explicit Output(Program&& program);
132
133 /// Constructor
134 /// @param program_ the program to move into this Output
135 /// @param data_ a variadic list of additional data unique_ptrs produced by
136 /// the transform
137 template <typename... DATA>
138 Output(Program&& program_, DATA... data_)
139 : program(std::move(program_)), data(std::forward<DATA>(data_)...) {}
140
141 /// The transformed program. May be empty on error.
142 Program program;
143
144 /// Extra output generated by the transforms.
145 DataMap data;
146};
147
Ben Claytonc40f6272021-01-26 16:57:10 +0000148/// Interface for Program transforms
Ben Claytonb5cd10c2021-06-25 10:26:26 +0000149class Transform : public Castable<Transform> {
Ben Clayton00b77a82020-12-04 09:06:09 +0000150 public:
151 /// Constructor
152 Transform();
153 /// Destructor
Ben Claytonb5cd10c2021-06-25 10:26:26 +0000154 ~Transform() override;
Ben Clayton00b77a82020-12-04 09:06:09 +0000155
Ben Claytond59cedb2021-01-25 18:14:08 +0000156 /// Runs the transform on `program`, returning the transformation result.
Ben Claytond59cedb2021-01-25 18:14:08 +0000157 /// @param program the source program to transform
Ben Claytonaf8a8ac2021-03-29 21:03:59 +0000158 /// @param data optional extra transform-specific input data
Ben Claytond59cedb2021-01-25 18:14:08 +0000159 /// @returns the transformation result
Ben Claytonb5cd10c2021-06-25 10:26:26 +0000160 virtual Output Run(const Program* program, const DataMap& data = {});
Ben Claytond59cedb2021-01-25 18:14:08 +0000161
Ben Claytond408f242020-12-14 20:31:17 +0000162 protected:
Ben Claytonb5cd10c2021-06-25 10:26:26 +0000163 /// Runs the transform using the CloneContext built for transforming a
164 /// program. Run() is responsible for calling Clone() on the CloneContext.
165 /// @param ctx the CloneContext primed with the input program and
166 /// ProgramBuilder
167 /// @param inputs optional extra transform-specific input data
168 /// @param outputs optional extra transform-specific output data
169 virtual void Run(CloneContext& ctx, const DataMap& inputs, DataMap& outputs);
170
171 /// Requires appends an error diagnostic to `ctx.dst` if the template type
172 /// transforms were not already run on `ctx.src`.
173 /// @param ctx the CloneContext
174 /// @returns true if all dependency transforms have been run
175 template <typename... TRANSFORMS>
176 bool Requires(CloneContext& ctx) {
177 return Requires(ctx, {&::tint::TypeInfo::Of<TRANSFORMS>()...});
178 }
179
180 /// Requires appends an error diagnostic to `ctx.dst` if the list of
181 /// Transforms were not already run on `ctx.src`.
182 /// @param ctx the CloneContext
183 /// @param deps the list of Transform TypeInfos
184 /// @returns true if all dependency transforms have been run
185 bool Requires(CloneContext& ctx,
186 std::initializer_list<const ::tint::TypeInfo*> deps);
187
Ben Clayton8e38fad2021-07-15 22:20:29 +0000188 /// Removes the statement `stmt` from the transformed program.
189 /// RemoveStatement handles edge cases, like statements in the initializer and
190 /// continuing of for-loops.
191 /// @param ctx the clone context
192 /// @param stmt the statement to remove when the program is cloned
Ben Clayton1aa98e62021-10-21 23:04:44 +0000193 static void RemoveStatement(CloneContext& ctx, const ast::Statement* stmt);
Ben Clayton8e38fad2021-07-15 22:20:29 +0000194
Ben Clayton02ada292021-05-04 18:13:21 +0000195 /// CreateASTTypeFor constructs new ast::Type nodes that reconstructs the
196 /// semantic type `ty`.
197 /// @param ctx the clone context
198 /// @param ty the semantic type to reconstruct
199 /// @returns a ast::Type that when resolved, will produce the semantic type
200 /// `ty`.
Ben Clayton86481202021-10-19 18:38:54 +0000201 static const ast::Type* CreateASTTypeFor(CloneContext& ctx,
202 const sem::Type* ty);
Ben Clayton00b77a82020-12-04 09:06:09 +0000203};
204
205} // namespace transform
206} // namespace tint
207
208#endif // SRC_TRANSFORM_TRANSFORM_H_