blob: 33639bbb1c4adf172355a03818a1ad9b1d493d78 [file] [log] [blame]
Austin Engcc2516a2023-10-17 20:57:54 +00001// Copyright 2022 The Dawn & Tint Authors
dan sinclaireee8d882022-10-28 01:22:58 +00002//
Austin Engcc2516a2023-10-17 20:57:54 +00003// Redistribution and use in source and binary forms, with or without
4// modification, are permitted provided that the following conditions are met:
dan sinclaireee8d882022-10-28 01:22:58 +00005//
Austin Engcc2516a2023-10-17 20:57:54 +00006// 1. Redistributions of source code must retain the above copyright notice, this
7// list of conditions and the following disclaimer.
dan sinclaireee8d882022-10-28 01:22:58 +00008//
Austin Engcc2516a2023-10-17 20:57:54 +00009// 2. Redistributions in binary form must reproduce the above copyright notice,
10// this list of conditions and the following disclaimer in the documentation
11// and/or other materials provided with the distribution.
12//
13// 3. Neither the name of the copyright holder nor the names of its
14// contributors may be used to endorse or promote products derived from
15// this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
21// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
dan sinclaireee8d882022-10-28 01:22:58 +000027
dan sinclair97c37272023-07-24 17:11:53 +000028#ifndef SRC_TINT_LANG_CORE_IR_FUNCTION_H_
29#define SRC_TINT_LANG_CORE_IR_FUNCTION_H_
dan sinclaireee8d882022-10-28 01:22:58 +000030
James Priceb298b6a2023-05-04 11:54:19 +000031#include <array>
dan sinclair9d9a3832023-05-03 19:22:31 +000032#include <optional>
dan sinclair24cb8112023-05-18 22:16:08 +000033#include <utility>
dan sinclair9d9a3832023-05-03 19:22:31 +000034
dan sinclair97c37272023-07-24 17:11:53 +000035#include "src/tint/lang/core/ir/function_param.h"
36#include "src/tint/lang/core/ir/location.h"
37#include "src/tint/lang/core/ir/value.h"
dan sinclair352f8c82023-07-21 00:40:07 +000038#include "src/tint/lang/core/type/type.h"
Ben Claytonf848af22023-07-28 16:37:32 +000039#include "src/tint/utils/ice/ice.h"
dan sinclaireee8d882022-10-28 01:22:58 +000040
41// Forward declarations
dan sinclair6f138fe2023-08-15 21:29:34 +000042namespace tint::core::ir {
dan sinclaireee8d882022-10-28 01:22:58 +000043class Block;
dan sinclair09b02ff2023-05-03 22:13:28 +000044class FunctionTerminator;
dan sinclair6f138fe2023-08-15 21:29:34 +000045} // namespace tint::core::ir
dan sinclaireee8d882022-10-28 01:22:58 +000046
dan sinclair6f138fe2023-08-15 21:29:34 +000047namespace tint::core::ir {
dan sinclaireee8d882022-10-28 01:22:58 +000048
49/// An IR representation of a function
dan sinclairbae54e72023-07-28 15:01:54 +000050class Function : public Castable<Function, Value> {
dan sinclaireee8d882022-10-28 01:22:58 +000051 public:
dan sinclair9d9a3832023-05-03 19:22:31 +000052 /// The pipeline stage for an entry point
53 enum class PipelineStage {
54 /// Not a pipeline entry point
55 kUndefined,
56 /// Vertex
57 kCompute,
58 /// Fragment
59 kFragment,
60 /// Vertex
61 kVertex,
62 };
63
dan sinclair212959b2023-05-30 19:55:08 +000064 /// Builtin attached to return types
65 enum class ReturnBuiltin {
dan sinclair69bb5dd2023-05-03 21:31:51 +000066 /// Builtin Position attribute
67 kPosition,
68 /// Builtin FragDepth attribute
69 kFragDepth,
70 /// Builtin SampleMask
71 kSampleMask,
dan sinclair69bb5dd2023-05-03 21:31:51 +000072 };
73
dan sinclaireee8d882022-10-28 01:22:58 +000074 /// Constructor
dan sinclairc9923d22023-05-15 23:44:04 +000075 /// @param rt the function return type
dan sinclairf59547f2023-05-16 14:43:45 +000076 /// @param stage the function stage
77 /// @param wg_size the workgroup_size
dan sinclaircedcdf32023-08-10 02:39:48 +000078 Function(const core::type::Type* rt,
dan sinclairf59547f2023-05-16 14:43:45 +000079 PipelineStage stage = PipelineStage::kUndefined,
80 std::optional<std::array<uint32_t, 3>> wg_size = {});
dan sinclaireee8d882022-10-28 01:22:58 +000081 ~Function() override;
82
dan sinclair16cb4bd2023-09-21 08:52:11 +000083 /// @copydoc Instruction::Clone()
84 Function* Clone(CloneContext& ctx) override;
85
dan sinclair24cb8112023-05-18 22:16:08 +000086 /// Sets the function stage
87 /// @param stage the stage to set
88 void SetStage(PipelineStage stage) { pipeline_stage_ = stage; }
dan sinclair9d9a3832023-05-03 19:22:31 +000089
dan sinclair24cb8112023-05-18 22:16:08 +000090 /// @returns the function pipeline stage
dan sinclaira5268df2023-06-08 21:39:53 +000091 PipelineStage Stage() { return pipeline_stage_; }
dan sinclair69bb5dd2023-05-03 21:31:51 +000092
dan sinclair24cb8112023-05-18 22:16:08 +000093 /// Sets the workgroup size
94 /// @param x the x size
95 /// @param y the y size
96 /// @param z the z size
97 void SetWorkgroupSize(uint32_t x, uint32_t y, uint32_t z) { workgroup_size_ = {x, y, z}; }
dan sinclair84d750e2023-05-18 08:50:34 +000098
James Price9e819bf2023-06-28 12:13:41 +000099 /// Clears the workgroup size.
100 void ClearWorkgroupSize() { workgroup_size_ = {}; }
101
dan sinclair24cb8112023-05-18 22:16:08 +0000102 /// @returns the workgroup size information
dan sinclaira5268df2023-06-08 21:39:53 +0000103 std::optional<std::array<uint32_t, 3>> WorkgroupSize() { return workgroup_size_; }
dan sinclair24cb8112023-05-18 22:16:08 +0000104
105 /// @returns the return type for the function
dan sinclaircedcdf32023-08-10 02:39:48 +0000106 const core::type::Type* ReturnType() { return return_.type; }
dan sinclair24cb8112023-05-18 22:16:08 +0000107
108 /// Sets the return attributes
dan sinclair212959b2023-05-30 19:55:08 +0000109 /// @param builtin the builtin to set
110 void SetReturnBuiltin(ReturnBuiltin builtin) {
Ben Claytonf848af22023-07-28 16:37:32 +0000111 TINT_ASSERT(!return_.builtin.has_value());
dan sinclair212959b2023-05-30 19:55:08 +0000112 return_.builtin = builtin;
dan sinclair24cb8112023-05-18 22:16:08 +0000113 }
dan sinclair212959b2023-05-30 19:55:08 +0000114 /// @returns the return builtin attribute
dan sinclaira5268df2023-06-08 21:39:53 +0000115 std::optional<enum ReturnBuiltin> ReturnBuiltin() { return return_.builtin; }
James Price9e819bf2023-06-28 12:13:41 +0000116 /// Clears the return builtin attribute.
117 void ClearReturnBuiltin() { return_.builtin = {}; }
dan sinclair24cb8112023-05-18 22:16:08 +0000118
119 /// Sets the return location
120 /// @param loc the location to set
dan sinclair212959b2023-05-30 19:55:08 +0000121 /// @param interp the interpolation
Ben Claytoncd52f382023-08-07 13:11:08 +0000122 void SetReturnLocation(uint32_t loc, std::optional<core::Interpolation> interp) {
dan sinclair212959b2023-05-30 19:55:08 +0000123 return_.location = {loc, interp};
124 }
dan sinclair24cb8112023-05-18 22:16:08 +0000125 /// @returns the return location
dan sinclaira5268df2023-06-08 21:39:53 +0000126 std::optional<Location> ReturnLocation() { return return_.location; }
James Price9e819bf2023-06-28 12:13:41 +0000127 /// Clears the return location attribute.
128 void ClearReturnLocation() { return_.location = {}; }
dan sinclair212959b2023-05-30 19:55:08 +0000129
130 /// Sets the return as invariant
131 /// @param val the invariant value to set
132 void SetReturnInvariant(bool val) { return_.invariant = val; }
133 /// @returns the return invariant value
dan sinclaira5268df2023-06-08 21:39:53 +0000134 bool ReturnInvariant() { return return_.invariant; }
dan sinclair24cb8112023-05-18 22:16:08 +0000135
136 /// Sets the function parameters
Ben Claytonb768af42023-06-09 23:31:16 +0000137 /// @param params the function parameters
dan sinclairbae54e72023-07-28 15:01:54 +0000138 void SetParams(VectorRef<FunctionParam*> params);
Ben Claytonb768af42023-06-09 23:31:16 +0000139
140 /// Sets the function parameters
141 /// @param params the function parameters
142 void SetParams(std::initializer_list<FunctionParam*> params);
143
dan sinclair24cb8112023-05-18 22:16:08 +0000144 /// @returns the function parameters
dan sinclairbae54e72023-07-28 15:01:54 +0000145 const VectorRef<FunctionParam*> Params() { return params_; }
dan sinclair24cb8112023-05-18 22:16:08 +0000146
Ben Clayton5acd44c2023-06-22 13:38:30 +0000147 /// Sets the root block for the function
148 /// @param target the root block
149 void SetBlock(Block* target) {
Ben Claytonf848af22023-07-28 16:37:32 +0000150 TINT_ASSERT(target != nullptr);
Ben Clayton5acd44c2023-06-22 13:38:30 +0000151 block_ = target;
dan sinclaireefa7fe2023-06-05 15:16:53 +0000152 }
Ben Clayton5acd44c2023-06-22 13:38:30 +0000153 /// @returns the function root block
154 ir::Block* Block() { return block_; }
dan sinclair24cb8112023-05-18 22:16:08 +0000155
James Pricec00c5692023-10-03 14:39:27 +0000156 /// Destroys the function and all of its instructions.
157 void Destroy() override;
158
dan sinclair24cb8112023-05-18 22:16:08 +0000159 private:
dan sinclair24cb8112023-05-18 22:16:08 +0000160 PipelineStage pipeline_stage_;
161 std::optional<std::array<uint32_t, 3>> workgroup_size_;
162
dan sinclair212959b2023-05-30 19:55:08 +0000163 struct {
dan sinclaircedcdf32023-08-10 02:39:48 +0000164 const core::type::Type* type = nullptr;
dan sinclair212959b2023-05-30 19:55:08 +0000165 std::optional<enum ReturnBuiltin> builtin;
166 std::optional<Location> location;
167 bool invariant = false;
168 } return_;
dan sinclair24cb8112023-05-18 22:16:08 +0000169
dan sinclairbae54e72023-07-28 15:01:54 +0000170 Vector<FunctionParam*, 1> params_;
Ben Clayton5acd44c2023-06-22 13:38:30 +0000171 ir::Block* block_ = nullptr;
dan sinclaireee8d882022-10-28 01:22:58 +0000172};
173
Ben Clayton68919602023-07-28 22:51:18 +0000174/// @param value the enum value
175/// @returns the string for the given enum value
176std::string_view ToString(Function::PipelineStage value);
177
178/// @param out the stream to write to
179/// @param value the Function::PipelineStage
180/// @returns @p out so calls can be chained
181template <typename STREAM, typename = traits::EnableIfIsOStream<STREAM>>
182auto& operator<<(STREAM& out, Function::PipelineStage value) {
183 return out << ToString(value);
184}
185
186/// @param value the enum value
187/// @returns the string for the given enum value
188std::string_view ToString(enum Function::ReturnBuiltin value);
189
190/// @param out the stream to write to
191/// @param value the Function::ReturnBuiltin
192/// @returns @p out so calls can be chained
193template <typename STREAM, typename = traits::EnableIfIsOStream<STREAM>>
194auto& operator<<(STREAM& out, enum Function::ReturnBuiltin value) {
195 return out << ToString(value);
196}
dan sinclair9d9a3832023-05-03 19:22:31 +0000197
dan sinclair6f138fe2023-08-15 21:29:34 +0000198} // namespace tint::core::ir
dan sinclaireee8d882022-10-28 01:22:58 +0000199
dan sinclair97c37272023-07-24 17:11:53 +0000200#endif // SRC_TINT_LANG_CORE_IR_FUNCTION_H_