Import Tint changes from Dawn
Changes:
- 15e7f94b762e86dec964bd040230271c39134df3 Remove ArrayCount helpers. by dan sinclair <dsinclair@chromium.org>
- 4b1d79e29281c403e9a24c99dfde0b8e60b38487 Moved sem::ArrayCount to an inherited structure by dan sinclair <dsinclair@chromium.org>
- 847cfa07c57e10f200329ac2c6eca16a8c2d93bb Move allocator into TypeManager by dan sinclair <dsinclair@chromium.org>
- 2939c4531e84b22f49900b606cf56f0af4351d10 Fix stack-overflow in `lhs_expression`. by dan sinclair <dsinclair@chromium.org>
- 6992f51ebd3feefb50b03e72cfc9170e5dd46793 tint: Add DirectVariableAccess transform by Ben Clayton <bclayton@google.com>
- d257e287929813fae395a2d6766fe305d883ce1e tint: Don't override alignment with @offset by Ben Clayton <bclayton@google.com>
- efb17b02543fb52c0b2e21d6082c0c9fbc2168a9 tint/writer/wgsl: Print @offset attributes as comment by Ben Clayton <bclayton@google.com>
- f745e4e2bfacedfd6e127888c0ea55177a078ecf Add Source to sem::Struct by dan sinclair <dsinclair@chromium.org>
- 8954189545af1423f7885afc7b9bee5778c49253 tint_common_fuzzer: Don't attempt to use an invalid program by Ben Clayton <bclayton@google.com>
- 527e38b68bb2615a4277a6efae9271ba7291d8ea [sem] Move TransitivelyReferencedOverrides to sem::Info. by dan sinclair <dsinclair@chromium.org>
- 331a3b7980ccd21ec06888acf6acbba934cddde0 Add Source to sem::StructMember by dan sinclair <dsinclair@chromium.org>
- c5b1b5c77ad375f0706f9db305618f69274e6cb6 Access struct member name through sem. by dan sinclair <dsinclair@chromium.org>
- d5d207ba9f5c44a578b6d790f28eada38687fab6 tint: Add builtin type aliases (vec3f, etc) by Ben Clayton <bclayton@google.com>
- f62aec2dc86e41c6b5b61b891f2cb4909cac1fa4 tint: Add missing tests / benchmarks by Ben Clayton <bclayton@google.com>
- f1f6e6fbea4e0fb0744f9300d6e1fbe25a595e1d tint: merge const eval shift left definitions by Antonio Maiorano <amaiorano@google.com>
- a54df5eca5dcc90bc36d4fe3ece4bce8a036faa0 Tint: Fix extractBits polyfill by Zhaoming Jiang <zhaoming.jiang@intel.com>
- 85ceb08d5ca7896605878551ad164d293dcc16d7 Add ExternalTexture Rotate and FlipY Functionality by Brandon Jones <brandon1.jones@intel.com>
- 94706ecba727e2917e1a3104edaa4a755f39a816 tint: Add 'chromium_experimental_full_ptr_parameters' ext... by Ben Clayton <bclayton@google.com>
- 53f646c55c973be64daf54b3deced5bf2e5ee29a [ir] Split Binary from Instruction by dan sinclair <dsinclair@chromium.org>
- babc21f9316878f04a8968bef870453dabd8ee3c tint: const eval of modulo operator by Antonio Maiorano <amaiorano@google.com>
- 171c542bf791f57400f3211180a94c671c6d58dd tint: improve compile error when calling builder::Val wit... by Antonio Maiorano <amaiorano@google.com>
- 6e306d34b5067ee01144bb83bf2330c7a32beb40 [ir] Remove operator<< by dan sinclair <dsinclair@chromium.org>
- a160ccb8c3f309064ba9e14656c4c958454ea2cd tint/ir: Fix build by Ben Clayton <bclayton@google.com>
- cfea22092700ac50f0d5d314c8aad959dc8728bc tint/number: add CheckedMod functions by Antonio Maiorano <amaiorano@google.com>
- 4c593c356b165b604396937839f6aba3aa592b0a tint/sem: Minor cleanup by Ben Clayton <bclayton@google.com>
GitOrigin-RevId: 15e7f94b762e86dec964bd040230271c39134df3
Change-Id: I0da9b543283ca4c662dd1f13537bedc5c07ffee5
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/112540
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn
index 3741764..6a0e70d 100644
--- a/src/tint/BUILD.gn
+++ b/src/tint/BUILD.gn
@@ -408,6 +408,8 @@
"resolver/resolver.h",
"resolver/sem_helper.cc",
"resolver/sem_helper.h",
+ "resolver/type_alias.cc",
+ "resolver/type_alias.h",
"resolver/uniformity.cc",
"resolver/uniformity.h",
"resolver/validator.cc",
@@ -417,6 +419,7 @@
"sem/abstract_int.h",
"sem/abstract_numeric.h",
"sem/array.h",
+ "sem/array_count.h",
"sem/atomic.h",
"sem/behavior.h",
"sem/binding_point.h",
@@ -500,6 +503,8 @@
"transform/decompose_strided_matrix.h",
"transform/demote_to_helper.cc",
"transform/demote_to_helper.h",
+ "transform/direct_variable_access.cc",
+ "transform/direct_variable_access.h",
"transform/disable_uniformity_analysis.cc",
"transform/disable_uniformity_analysis.h",
"transform/expand_compound_assignment.cc",
@@ -631,6 +636,8 @@
"sem/abstract_numeric.h",
"sem/array.cc",
"sem/array.h",
+ "sem/array_count.cc",
+ "sem/array_count.h",
"sem/atomic.cc",
"sem/atomic.h",
"sem/behavior.cc",
@@ -1016,6 +1023,7 @@
tint_unittests_source_set("tint_unittests_ast_src") {
sources = [
+ "ast/access_test.cc",
"ast/address_space_test.cc",
"ast/alias_test.cc",
"ast/array_test.cc",
@@ -1224,6 +1232,7 @@
"transform/decompose_strided_array_test.cc",
"transform/decompose_strided_matrix_test.cc",
"transform/demote_to_helper_test.cc",
+ "transform/direct_variable_access_test.cc",
"transform/disable_uniformity_analysis_test.cc",
"transform/expand_compound_assignment_test.cc",
"transform/first_index_offset_test.cc",
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index 15532b2..72cec7b 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -299,6 +299,8 @@
sem/abstract_numeric.h
sem/array.cc
sem/array.h
+ sem/array_count.cc
+ sem/array_count.h
sem/atomic.cc
sem/atomic.h
sem/behavior.cc
@@ -425,6 +427,8 @@
transform/decompose_strided_matrix.h
transform/demote_to_helper.cc
transform/demote_to_helper.h
+ transform/direct_variable_access.cc
+ transform/direct_variable_access.h
transform/disable_uniformity_analysis.cc
transform/disable_uniformity_analysis.h
transform/expand_compound_assignment.cc
@@ -535,13 +539,14 @@
writer/writer.h
)
-tint_generated(ast/access)
+tint_generated(ast/access BENCH TEST)
tint_generated(ast/address_space BENCH TEST)
tint_generated(ast/builtin_value BENCH TEST)
tint_generated(ast/extension BENCH TEST)
-tint_generated(ast/interpolate_attribute)
+tint_generated(ast/interpolate_attribute BENCH TEST)
tint_generated(ast/texel_format BENCH TEST)
tint_generated(resolver/init_conv_intrinsic)
+tint_generated(resolver/type_alias BENCH TEST)
tint_generated(sem/builtin_type)
tint_generated(sem/parameter_usage)
@@ -650,6 +655,8 @@
if(${TINT_BUILD_IR})
list(APPEND TINT_LIB_SRCS
+ ir/binary.cc
+ ir/binary.h
ir/block.cc
ir/block.h
ir/builder.cc
@@ -807,7 +814,6 @@
ast/increment_decrement_statement_test.cc
ast/index_accessor_expression_test.cc
ast/int_literal_expression_test.cc
- ast/interpolate_attribute_test.cc
ast/invariant_attribute_test.cc
ast/location_attribute_test.cc
ast/loop_statement_test.cc
@@ -1193,6 +1199,7 @@
transform/decompose_strided_array_test.cc
transform/decompose_strided_matrix_test.cc
transform/demote_to_helper_test.cc
+ transform/direct_variable_access_test.cc
transform/disable_uniformity_analysis_test.cc
transform/expand_compound_assignment_test.cc
transform/first_index_offset_test.cc
@@ -1344,9 +1351,9 @@
if (${TINT_BUILD_IR})
list(APPEND TINT_TEST_SRCS
+ ir/binary_test.cc
ir/builder_impl_test.cc
ir/constant_test.cc
- ir/instruction_test.cc
ir/temp_test.cc
ir/test_helper.h
)
diff --git a/src/tint/ast/access_bench.cc b/src/tint/ast/access_bench.cc
new file mode 100644
index 0000000..46b4f93
--- /dev/null
+++ b/src/tint/ast/access_bench.cc
@@ -0,0 +1,51 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+// src/tint/ast/access_bench.cc.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+#include "src/tint/ast/access.h"
+
+#include <array>
+
+#include "benchmark/benchmark.h"
+
+namespace tint::ast {
+namespace {
+
+void AccessParser(::benchmark::State& state) {
+ std::array kStrings{
+ "ccad", "3", "rVad", "read", "1ead",
+ "rqaJ", "rlla77", "reqqdppriHHe", "rv_wcit", "reabGwrte",
+ "read_write", "read_vriite", "re8d_wriWWe", "Meadxxrite", "wggte",
+ "VtX", "writ3", "write", "writE", "TTrPte",
+ "wxxidd",
+ };
+ for (auto _ : state) {
+ for (auto& str : kStrings) {
+ auto result = ParseAccess(str);
+ benchmark::DoNotOptimize(result);
+ }
+ }
+}
+
+BENCHMARK(AccessParser);
+
+} // namespace
+} // namespace tint::ast
diff --git a/src/tint/ast/access_bench.cc.tmpl b/src/tint/ast/access_bench.cc.tmpl
new file mode 100644
index 0000000..e4ef341
--- /dev/null
+++ b/src/tint/ast/access_bench.cc.tmpl
@@ -0,0 +1,29 @@
+{{- /*
+--------------------------------------------------------------------------------
+Template file for use with tools/src/cmd/gen to generate access_bench.cc
+
+To update the generated file, run:
+ ./tools/run gen
+
+See:
+* tools/src/cmd/gen for structures used by this template
+* https://golang.org/pkg/text/template/ for documentation on the template syntax
+--------------------------------------------------------------------------------
+*/ -}}
+
+{{- Import "src/tint/templates/enums.tmpl.inc" -}}
+{{- $enum := (Sem.Enum "access") -}}
+
+#include "src/tint/ast/access.h"
+
+#include <array>
+
+#include "benchmark/benchmark.h"
+
+namespace tint::ast {
+namespace {
+
+{{ Eval "BenchmarkParseEnum" $enum }}
+
+} // namespace
+} // namespace tint::ast
diff --git a/src/tint/ast/access_test.cc b/src/tint/ast/access_test.cc
new file mode 100644
index 0000000..017915d
--- /dev/null
+++ b/src/tint/ast/access_test.cc
@@ -0,0 +1,82 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+// src/tint/ast/access_test.cc.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+#include "src/tint/ast/access.h"
+
+#include <string>
+
+#include "src/tint/ast/test_helper.h"
+#include "src/tint/utils/string.h"
+
+namespace tint::ast {
+namespace {
+
+namespace parse_print_tests {
+
+struct Case {
+ const char* string;
+ Access value;
+};
+
+inline std::ostream& operator<<(std::ostream& out, Case c) {
+ return out << "'" << std::string(c.string) << "'";
+}
+
+static constexpr Case kValidCases[] = {
+ {"read", Access::kRead},
+ {"read_write", Access::kReadWrite},
+ {"write", Access::kWrite},
+};
+
+static constexpr Case kInvalidCases[] = {
+ {"ccad", Access::kUndefined}, {"3", Access::kUndefined},
+ {"rVad", Access::kUndefined}, {"read1write", Access::kUndefined},
+ {"reaJqqrite", Access::kUndefined}, {"rea7ll_write", Access::kUndefined},
+ {"wrqHtpp", Access::kUndefined}, {"ve", Access::kUndefined},
+ {"Grbe", Access::kUndefined},
+};
+
+using AccessParseTest = testing::TestWithParam<Case>;
+
+TEST_P(AccessParseTest, Parse) {
+ const char* string = GetParam().string;
+ Access expect = GetParam().value;
+ EXPECT_EQ(expect, ParseAccess(string));
+}
+
+INSTANTIATE_TEST_SUITE_P(ValidCases, AccessParseTest, testing::ValuesIn(kValidCases));
+INSTANTIATE_TEST_SUITE_P(InvalidCases, AccessParseTest, testing::ValuesIn(kInvalidCases));
+
+using AccessPrintTest = testing::TestWithParam<Case>;
+
+TEST_P(AccessPrintTest, Print) {
+ Access value = GetParam().value;
+ const char* expect = GetParam().string;
+ EXPECT_EQ(expect, utils::ToString(value));
+}
+
+INSTANTIATE_TEST_SUITE_P(ValidCases, AccessPrintTest, testing::ValuesIn(kValidCases));
+
+} // namespace parse_print_tests
+
+} // namespace
+} // namespace tint::ast
diff --git a/src/tint/ast/access_test.cc.tmpl b/src/tint/ast/access_test.cc.tmpl
new file mode 100644
index 0000000..9b4b71a
--- /dev/null
+++ b/src/tint/ast/access_test.cc.tmpl
@@ -0,0 +1,30 @@
+{{- /*
+--------------------------------------------------------------------------------
+Template file for use with tools/src/cmd/gen to generate access_test.cc
+
+To update the generated file, run:
+ ./tools/run gen
+
+See:
+* tools/src/cmd/gen for structures used by this template
+* https://golang.org/pkg/text/template/ for documentation on the template syntax
+--------------------------------------------------------------------------------
+*/ -}}
+
+{{- Import "src/tint/templates/enums.tmpl.inc" -}}
+{{- $enum := (Sem.Enum "access") -}}
+
+#include "src/tint/ast/access.h"
+
+#include <string>
+
+#include "src/tint/ast/test_helper.h"
+#include "src/tint/utils/string.h"
+
+namespace tint::ast {
+namespace {
+
+{{ Eval "TestParsePrintEnum" $enum}}
+
+} // namespace
+} // namespace tint::ast
diff --git a/src/tint/ast/extension.cc b/src/tint/ast/extension.cc
index be16806..31a8083 100644
--- a/src/tint/ast/extension.cc
+++ b/src/tint/ast/extension.cc
@@ -34,6 +34,9 @@
if (str == "chromium_experimental_dp4a") {
return Extension::kChromiumExperimentalDp4A;
}
+ if (str == "chromium_experimental_full_ptr_parameters") {
+ return Extension::kChromiumExperimentalFullPtrParameters;
+ }
if (str == "chromium_experimental_push_constant") {
return Extension::kChromiumExperimentalPushConstant;
}
@@ -51,6 +54,8 @@
return out << "chromium_disable_uniformity_analysis";
case Extension::kChromiumExperimentalDp4A:
return out << "chromium_experimental_dp4a";
+ case Extension::kChromiumExperimentalFullPtrParameters:
+ return out << "chromium_experimental_full_ptr_parameters";
case Extension::kChromiumExperimentalPushConstant:
return out << "chromium_experimental_push_constant";
case Extension::kF16:
diff --git a/src/tint/ast/extension.h b/src/tint/ast/extension.h
index f6fa03f..062e3fc 100644
--- a/src/tint/ast/extension.h
+++ b/src/tint/ast/extension.h
@@ -35,6 +35,7 @@
kUndefined,
kChromiumDisableUniformityAnalysis,
kChromiumExperimentalDp4A,
+ kChromiumExperimentalFullPtrParameters,
kChromiumExperimentalPushConstant,
kF16,
};
@@ -52,6 +53,7 @@
constexpr const char* kExtensionStrings[] = {
"chromium_disable_uniformity_analysis",
"chromium_experimental_dp4a",
+ "chromium_experimental_full_ptr_parameters",
"chromium_experimental_push_constant",
"f16",
};
diff --git a/src/tint/ast/extension_bench.cc b/src/tint/ast/extension_bench.cc
index 94b5216..5f175cc 100644
--- a/src/tint/ast/extension_bench.cc
+++ b/src/tint/ast/extension_bench.cc
@@ -45,20 +45,27 @@
"chromium_exverimentiil_dp4a",
"chro8ium_experimenWWal_dp4a",
"chromiMm_eperimxxntal_dp4a",
- "chrXmium_experimeggtal_ush_constant",
- "chromiu_experVmentalpusX_constant",
- "chro3ium_experimental_push_constant",
+ "chromium_expeggimeXtal_full_ptr_paraeters",
+ "chromium_expVrimental_full_ptr_puraXeer",
+ "chromium_experimental_full_ptr3parameters",
+ "chromium_experimental_full_ptr_parameters",
+ "chromium_experimentalEfull_ptr_parameters",
+ "chromium_experimentalfull_ptr_PPaTTameters",
+ "chromium_ddxperimental_fullptrxxparameters",
+ "c44romium_experimental_push_constant",
+ "chromium_experimental_pSSsVV_constant",
+ "chrom22Rm_experimental_pushRonstant",
"chromium_experimental_push_constant",
- "chromium_experEmental_push_constant",
- "chPPomiumexperimental_push_conTTtant",
- "chromixxm_experimentddl_push_constnt",
- "4416",
- "fSVV6",
- "RR2",
+ "chromium_exp9rimFntal_ush_constant",
+ "chrmium_experimental_push_constant",
+ "cOOromium_experiVeHtal_puh_conRRtant",
+ "y1",
+ "l77rrn6",
+ "4016",
"f16",
- "96",
- "f1",
- "VOR6",
+ "5",
+ "u16",
+ "f",
};
for (auto _ : state) {
for (auto& str : kStrings) {
diff --git a/src/tint/ast/extension_test.cc b/src/tint/ast/extension_test.cc
index 2879bf8..ea08dcc 100644
--- a/src/tint/ast/extension_test.cc
+++ b/src/tint/ast/extension_test.cc
@@ -44,6 +44,8 @@
static constexpr Case kValidCases[] = {
{"chromium_disable_uniformity_analysis", Extension::kChromiumDisableUniformityAnalysis},
{"chromium_experimental_dp4a", Extension::kChromiumExperimentalDp4A},
+ {"chromium_experimental_full_ptr_parameters",
+ Extension::kChromiumExperimentalFullPtrParameters},
{"chromium_experimental_push_constant", Extension::kChromiumExperimentalPushConstant},
{"f16", Extension::kF16},
};
@@ -55,12 +57,15 @@
{"chro1ium_experimental_dp4a", Extension::kUndefined},
{"chrJmium_experiqqetal_dp4a", Extension::kUndefined},
{"chromium_experimenll77l_dp4a", Extension::kUndefined},
- {"cppromium_experiHHenal_qqush_constant", Extension::kUndefined},
- {"chromium_xpericental_sh_vonstant", Extension::kUndefined},
- {"chromium_experimental_Gsh_cbnstant", Extension::kUndefined},
- {"f1vi", Extension::kUndefined},
- {"f8WW", Extension::kUndefined},
- {"fxx", Extension::kUndefined},
+ {"chroium_experimental_full_ptr_paqqppmetHHrs", Extension::kUndefined},
+ {"chrium_evperiental_full_ptr_paraceters", Extension::kUndefined},
+ {"chromium_expGimental_fullbptr_parameters", Extension::kUndefined},
+ {"chvomium_experimental_push_constiint", Extension::kUndefined},
+ {"chromiu8WWexperimental_push_constant", Extension::kUndefined},
+ {"chromium_experiMental_push_costanxx", Extension::kUndefined},
+ {"fgg", Extension::kUndefined},
+ {"X", Extension::kUndefined},
+ {"316", Extension::kUndefined},
};
using ExtensionParseTest = testing::TestWithParam<Case>;
diff --git a/src/tint/ast/interpolate_attribute_bench.cc b/src/tint/ast/interpolate_attribute_bench.cc
new file mode 100644
index 0000000..6382139
--- /dev/null
+++ b/src/tint/ast/interpolate_attribute_bench.cc
@@ -0,0 +1,67 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+// src/tint/ast/interpolate_attribute_bench.cc.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+#include "src/tint/ast/interpolate_attribute.h"
+
+#include <array>
+
+#include "benchmark/benchmark.h"
+
+namespace tint::ast {
+namespace {
+
+void InterpolationTypeParser(::benchmark::State& state) {
+ std::array kStrings{
+ "ccat", "3", "fVat", "flat", "1lat",
+ "fqaJ", "flla77", "lippeHHr", "cin", "lbGea",
+ "linear", "liveaii", "liWWe8r", "xxiner", "perggpctXve",
+ "ueVspXtve", "3erspective", "perspective", "perspectivE", "peTTspectiPe",
+ "pxxdrspectve",
+ };
+ for (auto _ : state) {
+ for (auto& str : kStrings) {
+ auto result = ParseInterpolationType(str);
+ benchmark::DoNotOptimize(result);
+ }
+ }
+}
+
+BENCHMARK(InterpolationTypeParser);
+
+void InterpolationSamplingParser(::benchmark::State& state) {
+ std::array kStrings{
+ "44enter", "cSSVVter", "centRr", "center", "ent9r", "cente", "VentORr",
+ "cenyroi", "77errtrllnid", "04entroid", "centroid", "enooid", "centzzd", "ceiippr1i",
+ "saXXple", "55IImpnn99", "aHHrrmplSS", "sample", "kkle", "jagRR", "smbe",
+ };
+ for (auto _ : state) {
+ for (auto& str : kStrings) {
+ auto result = ParseInterpolationSampling(str);
+ benchmark::DoNotOptimize(result);
+ }
+ }
+}
+
+BENCHMARK(InterpolationSamplingParser);
+
+} // namespace
+} // namespace tint::ast
diff --git a/src/tint/ast/interpolate_attribute_bench.cc.tmpl b/src/tint/ast/interpolate_attribute_bench.cc.tmpl
new file mode 100644
index 0000000..b75fe44
--- /dev/null
+++ b/src/tint/ast/interpolate_attribute_bench.cc.tmpl
@@ -0,0 +1,27 @@
+{{- /*
+--------------------------------------------------------------------------------
+Template file for use with tools/src/cmd/gen to generate interpolate_attribute_bench.cc
+
+See:
+* tools/src/cmd/gen for structures used by this template
+* https://golang.org/pkg/text/template/ for documentation on the template syntax
+--------------------------------------------------------------------------------
+*/ -}}
+
+{{- Import "src/tint/templates/enums.tmpl.inc" -}}
+
+#include "src/tint/ast/interpolate_attribute.h"
+
+#include <array>
+
+#include "benchmark/benchmark.h"
+
+namespace tint::ast {
+namespace {
+
+{{ Eval "BenchmarkParseEnum" (Sem.Enum "interpolation_type")}}
+
+{{ Eval "BenchmarkParseEnum" (Sem.Enum "interpolation_sampling")}}
+
+} // namespace
+} // namespace tint::ast
diff --git a/src/tint/ast/interpolate_attribute_test.cc b/src/tint/ast/interpolate_attribute_test.cc
index d8b6601..6c1204f 100644
--- a/src/tint/ast/interpolate_attribute_test.cc
+++ b/src/tint/ast/interpolate_attribute_test.cc
@@ -12,9 +12,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+// src/tint/ast/interpolate_attribute_test.cc.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
#include "src/tint/ast/interpolate_attribute.h"
+#include <string>
+
#include "src/tint/ast/test_helper.h"
+#include "src/tint/utils/string.h"
namespace tint::ast {
namespace {
@@ -28,5 +39,117 @@
EXPECT_EQ(InterpolationSampling::kCenter, d->sampling);
}
+namespace interpolation_type_tests {
+
+namespace parse_print_tests {
+
+struct Case {
+ const char* string;
+ InterpolationType value;
+};
+
+inline std::ostream& operator<<(std::ostream& out, Case c) {
+ return out << "'" << std::string(c.string) << "'";
+}
+
+static constexpr Case kValidCases[] = {
+ {"flat", InterpolationType::kFlat},
+ {"linear", InterpolationType::kLinear},
+ {"perspective", InterpolationType::kPerspective},
+};
+
+static constexpr Case kInvalidCases[] = {
+ {"ccat", InterpolationType::kUndefined}, {"3", InterpolationType::kUndefined},
+ {"fVat", InterpolationType::kUndefined}, {"1inear", InterpolationType::kUndefined},
+ {"lnqqar", InterpolationType::kUndefined}, {"linell77", InterpolationType::kUndefined},
+ {"perppHqective", InterpolationType::kUndefined}, {"cespctve", InterpolationType::kUndefined},
+ {"ebGpective", InterpolationType::kUndefined},
+};
+
+using InterpolationTypeParseTest = testing::TestWithParam<Case>;
+
+TEST_P(InterpolationTypeParseTest, Parse) {
+ const char* string = GetParam().string;
+ InterpolationType expect = GetParam().value;
+ EXPECT_EQ(expect, ParseInterpolationType(string));
+}
+
+INSTANTIATE_TEST_SUITE_P(ValidCases, InterpolationTypeParseTest, testing::ValuesIn(kValidCases));
+INSTANTIATE_TEST_SUITE_P(InvalidCases,
+ InterpolationTypeParseTest,
+ testing::ValuesIn(kInvalidCases));
+
+using InterpolationTypePrintTest = testing::TestWithParam<Case>;
+
+TEST_P(InterpolationTypePrintTest, Print) {
+ InterpolationType value = GetParam().value;
+ const char* expect = GetParam().string;
+ EXPECT_EQ(expect, utils::ToString(value));
+}
+
+INSTANTIATE_TEST_SUITE_P(ValidCases, InterpolationTypePrintTest, testing::ValuesIn(kValidCases));
+
+} // namespace parse_print_tests
+
+} // namespace interpolation_type_tests
+
+namespace interpolation_sampling_tests {
+
+namespace parse_print_tests {
+
+struct Case {
+ const char* string;
+ InterpolationSampling value;
+};
+
+inline std::ostream& operator<<(std::ostream& out, Case c) {
+ return out << "'" << std::string(c.string) << "'";
+}
+
+static constexpr Case kValidCases[] = {
+ {"center", InterpolationSampling::kCenter},
+ {"centroid", InterpolationSampling::kCentroid},
+ {"sample", InterpolationSampling::kSample},
+};
+
+static constexpr Case kInvalidCases[] = {
+ {"cevteii", InterpolationSampling::kUndefined}, {"ceWWt8r", InterpolationSampling::kUndefined},
+ {"xxentr", InterpolationSampling::kUndefined}, {"ceXggrid", InterpolationSampling::kUndefined},
+ {"ceXriu", InterpolationSampling::kUndefined}, {"centr3id", InterpolationSampling::kUndefined},
+ {"sEmple", InterpolationSampling::kUndefined}, {"amTTlPP", InterpolationSampling::kUndefined},
+ {"ddamxxl", InterpolationSampling::kUndefined},
+};
+
+using InterpolationSamplingParseTest = testing::TestWithParam<Case>;
+
+TEST_P(InterpolationSamplingParseTest, Parse) {
+ const char* string = GetParam().string;
+ InterpolationSampling expect = GetParam().value;
+ EXPECT_EQ(expect, ParseInterpolationSampling(string));
+}
+
+INSTANTIATE_TEST_SUITE_P(ValidCases,
+ InterpolationSamplingParseTest,
+ testing::ValuesIn(kValidCases));
+INSTANTIATE_TEST_SUITE_P(InvalidCases,
+ InterpolationSamplingParseTest,
+ testing::ValuesIn(kInvalidCases));
+
+using InterpolationSamplingPrintTest = testing::TestWithParam<Case>;
+
+TEST_P(InterpolationSamplingPrintTest, Print) {
+ InterpolationSampling value = GetParam().value;
+ const char* expect = GetParam().string;
+ EXPECT_EQ(expect, utils::ToString(value));
+}
+
+INSTANTIATE_TEST_SUITE_P(ValidCases,
+ InterpolationSamplingPrintTest,
+ testing::ValuesIn(kValidCases));
+
+} // namespace parse_print_tests
+
+} // namespace interpolation_sampling_tests
+
} // namespace
} // namespace tint::ast
diff --git a/src/tint/ast/interpolate_attribute_test.cc.tmpl b/src/tint/ast/interpolate_attribute_test.cc.tmpl
new file mode 100644
index 0000000..1adc9ab
--- /dev/null
+++ b/src/tint/ast/interpolate_attribute_test.cc.tmpl
@@ -0,0 +1,45 @@
+{{- /*
+--------------------------------------------------------------------------------
+Template file for use with tools/src/cmd/gen to generate interpolate_attribute_test.cc
+
+See:
+* tools/src/cmd/gen for structures used by this template
+* https://golang.org/pkg/text/template/ for documentation on the template syntax
+--------------------------------------------------------------------------------
+*/ -}}
+
+{{- Import "src/tint/templates/enums.tmpl.inc" -}}
+
+#include "src/tint/ast/interpolate_attribute.h"
+
+#include <string>
+
+#include "src/tint/ast/test_helper.h"
+#include "src/tint/utils/string.h"
+
+namespace tint::ast {
+namespace {
+
+using InterpolateAttributeTest = TestHelper;
+
+TEST_F(InterpolateAttributeTest, Creation) {
+ auto* d =
+ create<InterpolateAttribute>(InterpolationType::kLinear, InterpolationSampling::kCenter);
+ EXPECT_EQ(InterpolationType::kLinear, d->type);
+ EXPECT_EQ(InterpolationSampling::kCenter, d->sampling);
+}
+
+namespace interpolation_type_tests {
+
+{{ Eval "TestParsePrintEnum" (Sem.Enum "interpolation_type")}}
+
+} // namespace interpolation_type_tests
+
+namespace interpolation_sampling_tests {
+
+{{ Eval "TestParsePrintEnum" (Sem.Enum "interpolation_sampling")}}
+
+} // namespace interpolation_sampling_tests
+
+} // namespace
+} // namespace tint::ast
diff --git a/src/tint/fuzzers/tint_common_fuzzer.cc b/src/tint/fuzzers/tint_common_fuzzer.cc
index 1c24f35..15ab7d8 100644
--- a/src/tint/fuzzers/tint_common_fuzzer.cc
+++ b/src/tint/fuzzers/tint_common_fuzzer.cc
@@ -209,11 +209,11 @@
"transformed into an invalid output program");
}
}
+ return 0;
}
program = std::move(out.program);
RunInspector(&program);
-
return 1;
};
diff --git a/src/tint/inspector/inspector.cc b/src/tint/inspector/inspector.cc
index b641f53..25cde92 100644
--- a/src/tint/inspector/inspector.cc
+++ b/src/tint/inspector/inspector.cc
@@ -648,9 +648,9 @@
if (auto* struct_ty = unwrapped_type->As<sem::Struct>()) {
// Recurse into members.
for (auto* member : struct_ty->Members()) {
- AddEntryPointInOutVariables(
- name + "." + program_->Symbols().NameFor(member->Declaration()->symbol),
- member->Type(), member->Declaration()->attributes, member->Location(), variables);
+ AddEntryPointInOutVariables(name + "." + program_->Symbols().NameFor(member->Name()),
+ member->Type(), member->Declaration()->attributes,
+ member->Location(), variables);
}
return;
}
diff --git a/src/tint/intrinsics.def b/src/tint/intrinsics.def
index fb75c97..179cf88 100644
--- a/src/tint/intrinsics.def
+++ b/src/tint/intrinsics.def
@@ -51,6 +51,9 @@
chromium_disable_uniformity_analysis
// A Chromium-specific extension for push constants
chromium_experimental_push_constant
+ // A Chromium-specific extension that enables passing of uniform, storage and workgroup
+ // address-spaced pointers as parameters, as well as pointers into sub-objects.
+ chromium_experimental_full_ptr_parameters
}
// https://gpuweb.github.io/gpuweb/wgsl/#storage-class
@@ -108,6 +111,22 @@
sample
}
+// https://www.w3.org/TR/WGSL/#vector-types
+enum type_alias {
+ vec2f
+ vec2h
+ vec2i
+ vec2u
+ vec3f
+ vec3h
+ vec3i
+ vec3u
+ vec4f
+ vec4h
+ vec4i
+ vec4u
+}
+
////////////////////////////////////////////////////////////////////////////////
// WGSL primitive types //
// Types may be decorated with @precedence(N) to prioritize which type //
@@ -932,10 +951,10 @@
@const op / <T: fia_fiu32_f16, N: num> (vec<N, T>, T) -> vec<N, T>
@const op / <T: fia_fiu32_f16, N: num> (T, vec<N, T>) -> vec<N, T>
-op % <T: fiu32_f16>(T, T) -> T
-op % <T: fiu32_f16, N: num> (vec<N, T>, vec<N, T>) -> vec<N, T>
-op % <T: fiu32_f16, N: num> (vec<N, T>, T) -> vec<N, T>
-op % <T: fiu32_f16, N: num> (T, vec<N, T>) -> vec<N, T>
+@const op % <T: fia_fiu32_f16>(T, T) -> T
+@const op % <T: fia_fiu32_f16, N: num> (vec<N, T>, vec<N, T>) -> vec<N, T>
+@const op % <T: fia_fiu32_f16, N: num> (vec<N, T>, T) -> vec<N, T>
+@const op % <T: fia_fiu32_f16, N: num> (T, vec<N, T>) -> vec<N, T>
@const op ^ <T: ia_iu32>(T, T) -> T
@const op ^ <T: ia_iu32, N: num> (vec<N, T>, vec<N, T>) -> vec<N, T>
@@ -971,10 +990,8 @@
@const op >= <T: fia_fiu32_f16>(T, T) -> bool
@const op >= <T: fiu32_f16, N: num> (vec<N, T>, vec<N, T>) -> vec<N, bool>
-@const op << <T: iu32>(T, u32) -> T
-@const op << <T: iu32, N: num> (vec<N, T>, vec<N, u32>) -> vec<N, T>
-@const op << <T: ia>(T, u32) -> T
-@const op << <T: ia, N: num> (vec<N, T>, vec<N, u32>) -> vec<N, T>
+@const op << <T: ia_iu32>(T, u32) -> T
+@const op << <T: ia_iu32, N: num> (vec<N, T>, vec<N, u32>) -> vec<N, T>
op >> <T: iu32>(T, u32) -> T
op >> <T: iu32, N: num> (vec<N, T>, vec<N, u32>) -> vec<N, T>
diff --git a/src/tint/ir/binary.cc b/src/tint/ir/binary.cc
new file mode 100644
index 0000000..1a35b61
--- /dev/null
+++ b/src/tint/ir/binary.cc
@@ -0,0 +1,97 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/ir/binary.h"
+#include "src/tint/debug.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::ir::Binary);
+
+namespace tint::ir {
+
+Binary::Binary(Kind kind, const Value* result, const Value* lhs, const Value* rhs)
+ : kind_(kind), result_(result), lhs_(lhs), rhs_(rhs) {
+ TINT_ASSERT(IR, result_);
+ TINT_ASSERT(IR, lhs_);
+ TINT_ASSERT(IR, rhs_);
+}
+
+Binary::~Binary() = default;
+
+std::ostream& Binary::ToString(std::ostream& out) const {
+ Result()->ToString(out) << " = ";
+ lhs_->ToString(out) << " ";
+
+ switch (GetKind()) {
+ case Binary::Kind::kAdd:
+ out << "+";
+ break;
+ case Binary::Kind::kSubtract:
+ out << "-";
+ break;
+ case Binary::Kind::kMultiply:
+ out << "*";
+ break;
+ case Binary::Kind::kDivide:
+ out << "/";
+ break;
+ case Binary::Kind::kModulo:
+ out << "%";
+ break;
+ case Binary::Kind::kAnd:
+ out << "&";
+ break;
+ case Binary::Kind::kOr:
+ out << "|";
+ break;
+ case Binary::Kind::kXor:
+ out << "^";
+ break;
+ case Binary::Kind::kLogicalAnd:
+ out << "&&";
+ break;
+ case Binary::Kind::kLogicalOr:
+ out << "||";
+ break;
+ case Binary::Kind::kEqual:
+ out << "==";
+ break;
+ case Binary::Kind::kNotEqual:
+ out << "!=";
+ break;
+ case Binary::Kind::kLessThan:
+ out << "<";
+ break;
+ case Binary::Kind::kGreaterThan:
+ out << ">";
+ break;
+ case Binary::Kind::kLessThanEqual:
+ out << "<=";
+ break;
+ case Binary::Kind::kGreaterThanEqual:
+ out << ">=";
+ break;
+ case Binary::Kind::kShiftLeft:
+ out << "<<";
+ break;
+ case Binary::Kind::kShiftRight:
+ out << ">>";
+ break;
+ }
+ out << " ";
+ rhs_->ToString(out);
+
+ return out;
+}
+
+} // namespace tint::ir
diff --git a/src/tint/ir/binary.h b/src/tint/ir/binary.h
new file mode 100644
index 0000000..755dd9c
--- /dev/null
+++ b/src/tint/ir/binary.h
@@ -0,0 +1,96 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_TINT_IR_BINARY_H_
+#define SRC_TINT_IR_BINARY_H_
+
+#include <ostream>
+
+#include "src/tint/castable.h"
+#include "src/tint/ir/instruction.h"
+#include "src/tint/ir/value.h"
+
+namespace tint::ir {
+
+/// An instruction in the IR.
+class Binary : public Castable<Binary, Instruction> {
+ public:
+ /// The kind of instruction.
+ enum class Kind {
+ kAdd,
+ kSubtract,
+ kMultiply,
+ kDivide,
+ kModulo,
+
+ kAnd,
+ kOr,
+ kXor,
+
+ kLogicalAnd,
+ kLogicalOr,
+
+ kEqual,
+ kNotEqual,
+ kLessThan,
+ kGreaterThan,
+ kLessThanEqual,
+ kGreaterThanEqual,
+
+ kShiftLeft,
+ kShiftRight
+ };
+
+ /// Constructor
+ /// @param kind the kind of binary instruction
+ /// @param result the result value
+ /// @param lhs the lhs of the instruction
+ /// @param rhs the rhs of the instruction
+ Binary(Kind kind, const Value* result, const Value* lhs, const Value* rhs);
+ Binary(const Binary& instr) = delete;
+ Binary(Binary&& instr) = delete;
+ ~Binary() override;
+
+ Binary& operator=(const Binary& instr) = delete;
+ Binary& operator=(Binary&& instr) = delete;
+
+ /// @returns the kind of instruction
+ Kind GetKind() const { return kind_; }
+
+ /// @returns the result value for the instruction
+ const Value* Result() const { return result_; }
+
+ /// @returns the left-hand-side value for the instruction
+ const Value* LHS() const { return lhs_; }
+
+ /// @returns the right-hand-side value for the instruction
+ const Value* RHS() const { return rhs_; }
+
+ /// Write the instruction to the given stream
+ /// @param out the stream to write to
+ /// @returns the stream
+ std::ostream& ToString(std::ostream& out) const override;
+
+ private:
+ Kind kind_;
+ const Value* result_ = nullptr;
+ const Value* lhs_ = nullptr;
+ const Value* rhs_ = nullptr;
+};
+
+std::ostream& operator<<(std::ostream& out, const Binary&);
+
+} // namespace tint::ir
+
+#endif // SRC_TINT_IR_BINARY_H_
diff --git a/src/tint/ir/binary_test.cc b/src/tint/ir/binary_test.cc
new file mode 100644
index 0000000..81d0ada
--- /dev/null
+++ b/src/tint/ir/binary_test.cc
@@ -0,0 +1,499 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <sstream>
+
+#include "src/tint/ir/instruction.h"
+#include "src/tint/ir/test_helper.h"
+
+namespace tint::ir {
+namespace {
+
+using IR_InstructionTest = TestHelper;
+
+TEST_F(IR_InstructionTest, CreateAnd) {
+ auto& b = CreateEmptyBuilder();
+
+ b.builder.next_temp_id = Temp::Id(42);
+ const auto* instr = b.builder.And(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
+
+ EXPECT_EQ(instr->GetKind(), Binary::Kind::kAnd);
+
+ ASSERT_TRUE(instr->Result()->Is<Temp>());
+ EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
+
+ ASSERT_TRUE(instr->LHS()->Is<Constant>());
+ auto lhs = instr->LHS()->As<Constant>();
+ ASSERT_TRUE(lhs->IsI32());
+ EXPECT_EQ(i32(4), lhs->AsI32());
+
+ ASSERT_TRUE(instr->RHS()->Is<Constant>());
+ auto rhs = instr->RHS()->As<Constant>();
+ ASSERT_TRUE(rhs->IsI32());
+ EXPECT_EQ(i32(2), rhs->AsI32());
+
+ std::stringstream str;
+ instr->ToString(str);
+ EXPECT_EQ(str.str(), "%42 = 4 & 2");
+}
+
+TEST_F(IR_InstructionTest, CreateOr) {
+ auto& b = CreateEmptyBuilder();
+
+ b.builder.next_temp_id = Temp::Id(42);
+ const auto* instr = b.builder.Or(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
+
+ EXPECT_EQ(instr->GetKind(), Binary::Kind::kOr);
+
+ ASSERT_TRUE(instr->Result()->Is<Temp>());
+ EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
+
+ ASSERT_TRUE(instr->LHS()->Is<Constant>());
+ auto lhs = instr->LHS()->As<Constant>();
+ ASSERT_TRUE(lhs->IsI32());
+ EXPECT_EQ(i32(4), lhs->AsI32());
+
+ ASSERT_TRUE(instr->RHS()->Is<Constant>());
+ auto rhs = instr->RHS()->As<Constant>();
+ ASSERT_TRUE(rhs->IsI32());
+ EXPECT_EQ(i32(2), rhs->AsI32());
+
+ std::stringstream str;
+ instr->ToString(str);
+ EXPECT_EQ(str.str(), "%42 = 4 | 2");
+}
+
+TEST_F(IR_InstructionTest, CreateXor) {
+ auto& b = CreateEmptyBuilder();
+
+ b.builder.next_temp_id = Temp::Id(42);
+ const auto* instr = b.builder.Xor(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
+
+ EXPECT_EQ(instr->GetKind(), Binary::Kind::kXor);
+
+ ASSERT_TRUE(instr->Result()->Is<Temp>());
+ EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
+
+ ASSERT_TRUE(instr->LHS()->Is<Constant>());
+ auto lhs = instr->LHS()->As<Constant>();
+ ASSERT_TRUE(lhs->IsI32());
+ EXPECT_EQ(i32(4), lhs->AsI32());
+
+ ASSERT_TRUE(instr->RHS()->Is<Constant>());
+ auto rhs = instr->RHS()->As<Constant>();
+ ASSERT_TRUE(rhs->IsI32());
+ EXPECT_EQ(i32(2), rhs->AsI32());
+
+ std::stringstream str;
+ instr->ToString(str);
+ EXPECT_EQ(str.str(), "%42 = 4 ^ 2");
+}
+
+TEST_F(IR_InstructionTest, CreateLogicalAnd) {
+ auto& b = CreateEmptyBuilder();
+
+ b.builder.next_temp_id = Temp::Id(42);
+ const auto* instr =
+ b.builder.LogicalAnd(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
+
+ EXPECT_EQ(instr->GetKind(), Binary::Kind::kLogicalAnd);
+
+ ASSERT_TRUE(instr->Result()->Is<Temp>());
+ EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
+
+ ASSERT_TRUE(instr->LHS()->Is<Constant>());
+ auto lhs = instr->LHS()->As<Constant>();
+ ASSERT_TRUE(lhs->IsI32());
+ EXPECT_EQ(i32(4), lhs->AsI32());
+
+ ASSERT_TRUE(instr->RHS()->Is<Constant>());
+ auto rhs = instr->RHS()->As<Constant>();
+ ASSERT_TRUE(rhs->IsI32());
+ EXPECT_EQ(i32(2), rhs->AsI32());
+
+ std::stringstream str;
+ instr->ToString(str);
+ EXPECT_EQ(str.str(), "%42 = 4 && 2");
+}
+
+TEST_F(IR_InstructionTest, CreateLogicalOr) {
+ auto& b = CreateEmptyBuilder();
+
+ b.builder.next_temp_id = Temp::Id(42);
+ const auto* instr = b.builder.LogicalOr(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
+
+ EXPECT_EQ(instr->GetKind(), Binary::Kind::kLogicalOr);
+
+ ASSERT_TRUE(instr->Result()->Is<Temp>());
+ EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
+
+ ASSERT_TRUE(instr->LHS()->Is<Constant>());
+ auto lhs = instr->LHS()->As<Constant>();
+ ASSERT_TRUE(lhs->IsI32());
+ EXPECT_EQ(i32(4), lhs->AsI32());
+
+ ASSERT_TRUE(instr->RHS()->Is<Constant>());
+ auto rhs = instr->RHS()->As<Constant>();
+ ASSERT_TRUE(rhs->IsI32());
+ EXPECT_EQ(i32(2), rhs->AsI32());
+
+ std::stringstream str;
+ instr->ToString(str);
+ EXPECT_EQ(str.str(), "%42 = 4 || 2");
+}
+
+TEST_F(IR_InstructionTest, CreateEqual) {
+ auto& b = CreateEmptyBuilder();
+
+ b.builder.next_temp_id = Temp::Id(42);
+ const auto* instr = b.builder.Equal(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
+
+ EXPECT_EQ(instr->GetKind(), Binary::Kind::kEqual);
+
+ ASSERT_TRUE(instr->Result()->Is<Temp>());
+ EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
+
+ ASSERT_TRUE(instr->LHS()->Is<Constant>());
+ auto lhs = instr->LHS()->As<Constant>();
+ ASSERT_TRUE(lhs->IsI32());
+ EXPECT_EQ(i32(4), lhs->AsI32());
+
+ ASSERT_TRUE(instr->RHS()->Is<Constant>());
+ auto rhs = instr->RHS()->As<Constant>();
+ ASSERT_TRUE(rhs->IsI32());
+ EXPECT_EQ(i32(2), rhs->AsI32());
+
+ std::stringstream str;
+ instr->ToString(str);
+ EXPECT_EQ(str.str(), "%42 = 4 == 2");
+}
+
+TEST_F(IR_InstructionTest, CreateNotEqual) {
+ auto& b = CreateEmptyBuilder();
+
+ b.builder.next_temp_id = Temp::Id(42);
+ const auto* instr = b.builder.NotEqual(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
+
+ EXPECT_EQ(instr->GetKind(), Binary::Kind::kNotEqual);
+
+ ASSERT_TRUE(instr->Result()->Is<Temp>());
+ EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
+
+ ASSERT_TRUE(instr->LHS()->Is<Constant>());
+ auto lhs = instr->LHS()->As<Constant>();
+ ASSERT_TRUE(lhs->IsI32());
+ EXPECT_EQ(i32(4), lhs->AsI32());
+
+ ASSERT_TRUE(instr->RHS()->Is<Constant>());
+ auto rhs = instr->RHS()->As<Constant>();
+ ASSERT_TRUE(rhs->IsI32());
+ EXPECT_EQ(i32(2), rhs->AsI32());
+
+ std::stringstream str;
+ instr->ToString(str);
+ EXPECT_EQ(str.str(), "%42 = 4 != 2");
+}
+
+TEST_F(IR_InstructionTest, CreateLessThan) {
+ auto& b = CreateEmptyBuilder();
+
+ b.builder.next_temp_id = Temp::Id(42);
+ const auto* instr = b.builder.LessThan(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
+
+ EXPECT_EQ(instr->GetKind(), Binary::Kind::kLessThan);
+
+ ASSERT_TRUE(instr->Result()->Is<Temp>());
+ EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
+
+ ASSERT_TRUE(instr->LHS()->Is<Constant>());
+ auto lhs = instr->LHS()->As<Constant>();
+ ASSERT_TRUE(lhs->IsI32());
+ EXPECT_EQ(i32(4), lhs->AsI32());
+
+ ASSERT_TRUE(instr->RHS()->Is<Constant>());
+ auto rhs = instr->RHS()->As<Constant>();
+ ASSERT_TRUE(rhs->IsI32());
+ EXPECT_EQ(i32(2), rhs->AsI32());
+
+ std::stringstream str;
+ instr->ToString(str);
+ EXPECT_EQ(str.str(), "%42 = 4 < 2");
+}
+
+TEST_F(IR_InstructionTest, CreateGreaterThan) {
+ auto& b = CreateEmptyBuilder();
+
+ b.builder.next_temp_id = Temp::Id(42);
+ const auto* instr =
+ b.builder.GreaterThan(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
+
+ EXPECT_EQ(instr->GetKind(), Binary::Kind::kGreaterThan);
+
+ ASSERT_TRUE(instr->Result()->Is<Temp>());
+ EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
+
+ ASSERT_TRUE(instr->LHS()->Is<Constant>());
+ auto lhs = instr->LHS()->As<Constant>();
+ ASSERT_TRUE(lhs->IsI32());
+ EXPECT_EQ(i32(4), lhs->AsI32());
+
+ ASSERT_TRUE(instr->RHS()->Is<Constant>());
+ auto rhs = instr->RHS()->As<Constant>();
+ ASSERT_TRUE(rhs->IsI32());
+ EXPECT_EQ(i32(2), rhs->AsI32());
+
+ std::stringstream str;
+ instr->ToString(str);
+ EXPECT_EQ(str.str(), "%42 = 4 > 2");
+}
+
+TEST_F(IR_InstructionTest, CreateLessThanEqual) {
+ auto& b = CreateEmptyBuilder();
+
+ b.builder.next_temp_id = Temp::Id(42);
+ const auto* instr =
+ b.builder.LessThanEqual(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
+
+ EXPECT_EQ(instr->GetKind(), Binary::Kind::kLessThanEqual);
+
+ ASSERT_TRUE(instr->Result()->Is<Temp>());
+ EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
+
+ ASSERT_TRUE(instr->LHS()->Is<Constant>());
+ auto lhs = instr->LHS()->As<Constant>();
+ ASSERT_TRUE(lhs->IsI32());
+ EXPECT_EQ(i32(4), lhs->AsI32());
+
+ ASSERT_TRUE(instr->RHS()->Is<Constant>());
+ auto rhs = instr->RHS()->As<Constant>();
+ ASSERT_TRUE(rhs->IsI32());
+ EXPECT_EQ(i32(2), rhs->AsI32());
+
+ std::stringstream str;
+ instr->ToString(str);
+ EXPECT_EQ(str.str(), "%42 = 4 <= 2");
+}
+
+TEST_F(IR_InstructionTest, CreateGreaterThanEqual) {
+ auto& b = CreateEmptyBuilder();
+
+ b.builder.next_temp_id = Temp::Id(42);
+ const auto* instr =
+ b.builder.GreaterThanEqual(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
+
+ EXPECT_EQ(instr->GetKind(), Binary::Kind::kGreaterThanEqual);
+
+ ASSERT_TRUE(instr->Result()->Is<Temp>());
+ EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
+
+ ASSERT_TRUE(instr->LHS()->Is<Constant>());
+ auto lhs = instr->LHS()->As<Constant>();
+ ASSERT_TRUE(lhs->IsI32());
+ EXPECT_EQ(i32(4), lhs->AsI32());
+
+ ASSERT_TRUE(instr->RHS()->Is<Constant>());
+ auto rhs = instr->RHS()->As<Constant>();
+ ASSERT_TRUE(rhs->IsI32());
+ EXPECT_EQ(i32(2), rhs->AsI32());
+
+ std::stringstream str;
+ instr->ToString(str);
+ EXPECT_EQ(str.str(), "%42 = 4 >= 2");
+}
+
+TEST_F(IR_InstructionTest, CreateShiftLeft) {
+ auto& b = CreateEmptyBuilder();
+
+ b.builder.next_temp_id = Temp::Id(42);
+ const auto* instr = b.builder.ShiftLeft(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
+
+ EXPECT_EQ(instr->GetKind(), Binary::Kind::kShiftLeft);
+
+ ASSERT_TRUE(instr->Result()->Is<Temp>());
+ EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
+
+ ASSERT_TRUE(instr->LHS()->Is<Constant>());
+ auto lhs = instr->LHS()->As<Constant>();
+ ASSERT_TRUE(lhs->IsI32());
+ EXPECT_EQ(i32(4), lhs->AsI32());
+
+ ASSERT_TRUE(instr->RHS()->Is<Constant>());
+ auto rhs = instr->RHS()->As<Constant>();
+ ASSERT_TRUE(rhs->IsI32());
+ EXPECT_EQ(i32(2), rhs->AsI32());
+
+ std::stringstream str;
+ instr->ToString(str);
+ EXPECT_EQ(str.str(), "%42 = 4 << 2");
+}
+
+TEST_F(IR_InstructionTest, CreateShiftRight) {
+ auto& b = CreateEmptyBuilder();
+
+ b.builder.next_temp_id = Temp::Id(42);
+ const auto* instr =
+ b.builder.ShiftRight(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
+
+ EXPECT_EQ(instr->GetKind(), Binary::Kind::kShiftRight);
+
+ ASSERT_TRUE(instr->Result()->Is<Temp>());
+ EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
+
+ ASSERT_TRUE(instr->LHS()->Is<Constant>());
+ auto lhs = instr->LHS()->As<Constant>();
+ ASSERT_TRUE(lhs->IsI32());
+ EXPECT_EQ(i32(4), lhs->AsI32());
+
+ ASSERT_TRUE(instr->RHS()->Is<Constant>());
+ auto rhs = instr->RHS()->As<Constant>();
+ ASSERT_TRUE(rhs->IsI32());
+ EXPECT_EQ(i32(2), rhs->AsI32());
+
+ std::stringstream str;
+ instr->ToString(str);
+ EXPECT_EQ(str.str(), "%42 = 4 >> 2");
+}
+
+TEST_F(IR_InstructionTest, CreateAdd) {
+ auto& b = CreateEmptyBuilder();
+
+ b.builder.next_temp_id = Temp::Id(42);
+ const auto* instr = b.builder.Add(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
+
+ EXPECT_EQ(instr->GetKind(), Binary::Kind::kAdd);
+
+ ASSERT_TRUE(instr->Result()->Is<Temp>());
+ EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
+
+ ASSERT_TRUE(instr->LHS()->Is<Constant>());
+ auto lhs = instr->LHS()->As<Constant>();
+ ASSERT_TRUE(lhs->IsI32());
+ EXPECT_EQ(i32(4), lhs->AsI32());
+
+ ASSERT_TRUE(instr->RHS()->Is<Constant>());
+ auto rhs = instr->RHS()->As<Constant>();
+ ASSERT_TRUE(rhs->IsI32());
+ EXPECT_EQ(i32(2), rhs->AsI32());
+
+ std::stringstream str;
+ instr->ToString(str);
+ EXPECT_EQ(str.str(), "%42 = 4 + 2");
+}
+
+TEST_F(IR_InstructionTest, CreateSubtract) {
+ auto& b = CreateEmptyBuilder();
+
+ b.builder.next_temp_id = Temp::Id(42);
+ const auto* instr = b.builder.Subtract(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
+
+ EXPECT_EQ(instr->GetKind(), Binary::Kind::kSubtract);
+
+ ASSERT_TRUE(instr->Result()->Is<Temp>());
+ EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
+
+ ASSERT_TRUE(instr->LHS()->Is<Constant>());
+ auto lhs = instr->LHS()->As<Constant>();
+ ASSERT_TRUE(lhs->IsI32());
+ EXPECT_EQ(i32(4), lhs->AsI32());
+
+ ASSERT_TRUE(instr->RHS()->Is<Constant>());
+ auto rhs = instr->RHS()->As<Constant>();
+ ASSERT_TRUE(rhs->IsI32());
+ EXPECT_EQ(i32(2), rhs->AsI32());
+
+ std::stringstream str;
+ instr->ToString(str);
+ EXPECT_EQ(str.str(), "%42 = 4 - 2");
+}
+
+TEST_F(IR_InstructionTest, CreateMultiply) {
+ auto& b = CreateEmptyBuilder();
+
+ b.builder.next_temp_id = Temp::Id(42);
+ const auto* instr = b.builder.Multiply(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
+
+ EXPECT_EQ(instr->GetKind(), Binary::Kind::kMultiply);
+
+ ASSERT_TRUE(instr->Result()->Is<Temp>());
+ EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
+
+ ASSERT_TRUE(instr->LHS()->Is<Constant>());
+ auto lhs = instr->LHS()->As<Constant>();
+ ASSERT_TRUE(lhs->IsI32());
+ EXPECT_EQ(i32(4), lhs->AsI32());
+
+ ASSERT_TRUE(instr->RHS()->Is<Constant>());
+ auto rhs = instr->RHS()->As<Constant>();
+ ASSERT_TRUE(rhs->IsI32());
+ EXPECT_EQ(i32(2), rhs->AsI32());
+
+ std::stringstream str;
+ instr->ToString(str);
+ EXPECT_EQ(str.str(), "%42 = 4 * 2");
+}
+
+TEST_F(IR_InstructionTest, CreateDivide) {
+ auto& b = CreateEmptyBuilder();
+
+ b.builder.next_temp_id = Temp::Id(42);
+ const auto* instr = b.builder.Divide(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
+
+ EXPECT_EQ(instr->GetKind(), Binary::Kind::kDivide);
+
+ ASSERT_TRUE(instr->Result()->Is<Temp>());
+ EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
+
+ ASSERT_TRUE(instr->LHS()->Is<Constant>());
+ auto lhs = instr->LHS()->As<Constant>();
+ ASSERT_TRUE(lhs->IsI32());
+ EXPECT_EQ(i32(4), lhs->AsI32());
+
+ ASSERT_TRUE(instr->RHS()->Is<Constant>());
+ auto rhs = instr->RHS()->As<Constant>();
+ ASSERT_TRUE(rhs->IsI32());
+ EXPECT_EQ(i32(2), rhs->AsI32());
+
+ std::stringstream str;
+ instr->ToString(str);
+ EXPECT_EQ(str.str(), "%42 = 4 / 2");
+}
+
+TEST_F(IR_InstructionTest, CreateModulo) {
+ auto& b = CreateEmptyBuilder();
+
+ b.builder.next_temp_id = Temp::Id(42);
+ const auto* instr = b.builder.Modulo(b.builder.Constant(i32(4)), b.builder.Constant(i32(2)));
+
+ EXPECT_EQ(instr->GetKind(), Binary::Kind::kModulo);
+
+ ASSERT_TRUE(instr->Result()->Is<Temp>());
+ EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
+
+ ASSERT_TRUE(instr->LHS()->Is<Constant>());
+ auto lhs = instr->LHS()->As<Constant>();
+ ASSERT_TRUE(lhs->IsI32());
+ EXPECT_EQ(i32(4), lhs->AsI32());
+
+ ASSERT_TRUE(instr->RHS()->Is<Constant>());
+ auto rhs = instr->RHS()->As<Constant>();
+ ASSERT_TRUE(rhs->IsI32());
+ EXPECT_EQ(i32(2), rhs->AsI32());
+
+ std::stringstream str;
+ instr->ToString(str);
+ EXPECT_EQ(str.str(), "%42 = 4 % 2");
+}
+
+} // namespace
+} // namespace tint::ir
diff --git a/src/tint/ir/builder.cc b/src/tint/ir/builder.cc
index 5c55b91..0f0200d 100644
--- a/src/tint/ir/builder.cc
+++ b/src/tint/ir/builder.cc
@@ -97,82 +97,80 @@
return next_temp_id++;
}
-const Instruction* Builder::CreateInstruction(Instruction::Kind kind,
- const Value* lhs,
- const Value* rhs) {
- return ir.instructions.Create<ir::Instruction>(kind, Temp(), lhs, rhs);
+const Binary* Builder::CreateBinary(Binary::Kind kind, const Value* lhs, const Value* rhs) {
+ return ir.instructions.Create<ir::Binary>(kind, Temp(), lhs, rhs);
}
-const Instruction* Builder::And(const Value* lhs, const Value* rhs) {
- return CreateInstruction(Instruction::Kind::kAnd, lhs, rhs);
+const Binary* Builder::And(const Value* lhs, const Value* rhs) {
+ return CreateBinary(Binary::Kind::kAnd, lhs, rhs);
}
-const Instruction* Builder::Or(const Value* lhs, const Value* rhs) {
- return CreateInstruction(Instruction::Kind::kOr, lhs, rhs);
+const Binary* Builder::Or(const Value* lhs, const Value* rhs) {
+ return CreateBinary(Binary::Kind::kOr, lhs, rhs);
}
-const Instruction* Builder::Xor(const Value* lhs, const Value* rhs) {
- return CreateInstruction(Instruction::Kind::kXor, lhs, rhs);
+const Binary* Builder::Xor(const Value* lhs, const Value* rhs) {
+ return CreateBinary(Binary::Kind::kXor, lhs, rhs);
}
-const Instruction* Builder::LogicalAnd(const Value* lhs, const Value* rhs) {
- return CreateInstruction(Instruction::Kind::kLogicalAnd, lhs, rhs);
+const Binary* Builder::LogicalAnd(const Value* lhs, const Value* rhs) {
+ return CreateBinary(Binary::Kind::kLogicalAnd, lhs, rhs);
}
-const Instruction* Builder::LogicalOr(const Value* lhs, const Value* rhs) {
- return CreateInstruction(Instruction::Kind::kLogicalOr, lhs, rhs);
+const Binary* Builder::LogicalOr(const Value* lhs, const Value* rhs) {
+ return CreateBinary(Binary::Kind::kLogicalOr, lhs, rhs);
}
-const Instruction* Builder::Equal(const Value* lhs, const Value* rhs) {
- return CreateInstruction(Instruction::Kind::kEqual, lhs, rhs);
+const Binary* Builder::Equal(const Value* lhs, const Value* rhs) {
+ return CreateBinary(Binary::Kind::kEqual, lhs, rhs);
}
-const Instruction* Builder::NotEqual(const Value* lhs, const Value* rhs) {
- return CreateInstruction(Instruction::Kind::kNotEqual, lhs, rhs);
+const Binary* Builder::NotEqual(const Value* lhs, const Value* rhs) {
+ return CreateBinary(Binary::Kind::kNotEqual, lhs, rhs);
}
-const Instruction* Builder::LessThan(const Value* lhs, const Value* rhs) {
- return CreateInstruction(Instruction::Kind::kLessThan, lhs, rhs);
+const Binary* Builder::LessThan(const Value* lhs, const Value* rhs) {
+ return CreateBinary(Binary::Kind::kLessThan, lhs, rhs);
}
-const Instruction* Builder::GreaterThan(const Value* lhs, const Value* rhs) {
- return CreateInstruction(Instruction::Kind::kGreaterThan, lhs, rhs);
+const Binary* Builder::GreaterThan(const Value* lhs, const Value* rhs) {
+ return CreateBinary(Binary::Kind::kGreaterThan, lhs, rhs);
}
-const Instruction* Builder::LessThanEqual(const Value* lhs, const Value* rhs) {
- return CreateInstruction(Instruction::Kind::kLessThanEqual, lhs, rhs);
+const Binary* Builder::LessThanEqual(const Value* lhs, const Value* rhs) {
+ return CreateBinary(Binary::Kind::kLessThanEqual, lhs, rhs);
}
-const Instruction* Builder::GreaterThanEqual(const Value* lhs, const Value* rhs) {
- return CreateInstruction(Instruction::Kind::kGreaterThanEqual, lhs, rhs);
+const Binary* Builder::GreaterThanEqual(const Value* lhs, const Value* rhs) {
+ return CreateBinary(Binary::Kind::kGreaterThanEqual, lhs, rhs);
}
-const Instruction* Builder::ShiftLeft(const Value* lhs, const Value* rhs) {
- return CreateInstruction(Instruction::Kind::kShiftLeft, lhs, rhs);
+const Binary* Builder::ShiftLeft(const Value* lhs, const Value* rhs) {
+ return CreateBinary(Binary::Kind::kShiftLeft, lhs, rhs);
}
-const Instruction* Builder::ShiftRight(const Value* lhs, const Value* rhs) {
- return CreateInstruction(Instruction::Kind::kShiftRight, lhs, rhs);
+const Binary* Builder::ShiftRight(const Value* lhs, const Value* rhs) {
+ return CreateBinary(Binary::Kind::kShiftRight, lhs, rhs);
}
-const Instruction* Builder::Add(const Value* lhs, const Value* rhs) {
- return CreateInstruction(Instruction::Kind::kAdd, lhs, rhs);
+const Binary* Builder::Add(const Value* lhs, const Value* rhs) {
+ return CreateBinary(Binary::Kind::kAdd, lhs, rhs);
}
-const Instruction* Builder::Subtract(const Value* lhs, const Value* rhs) {
- return CreateInstruction(Instruction::Kind::kSubtract, lhs, rhs);
+const Binary* Builder::Subtract(const Value* lhs, const Value* rhs) {
+ return CreateBinary(Binary::Kind::kSubtract, lhs, rhs);
}
-const Instruction* Builder::Multiply(const Value* lhs, const Value* rhs) {
- return CreateInstruction(Instruction::Kind::kMultiply, lhs, rhs);
+const Binary* Builder::Multiply(const Value* lhs, const Value* rhs) {
+ return CreateBinary(Binary::Kind::kMultiply, lhs, rhs);
}
-const Instruction* Builder::Divide(const Value* lhs, const Value* rhs) {
- return CreateInstruction(Instruction::Kind::kDivide, lhs, rhs);
+const Binary* Builder::Divide(const Value* lhs, const Value* rhs) {
+ return CreateBinary(Binary::Kind::kDivide, lhs, rhs);
}
-const Instruction* Builder::Modulo(const Value* lhs, const Value* rhs) {
- return CreateInstruction(Instruction::Kind::kModulo, lhs, rhs);
+const Binary* Builder::Modulo(const Value* lhs, const Value* rhs) {
+ return CreateBinary(Binary::Kind::kModulo, lhs, rhs);
}
} // namespace tint::ir
diff --git a/src/tint/ir/builder.h b/src/tint/ir/builder.h
index d5065b8..3f2e011 100644
--- a/src/tint/ir/builder.h
+++ b/src/tint/ir/builder.h
@@ -15,10 +15,10 @@
#ifndef SRC_TINT_IR_BUILDER_H_
#define SRC_TINT_IR_BUILDER_H_
+#include "src/tint/ir/binary.h"
#include "src/tint/ir/constant.h"
#include "src/tint/ir/function.h"
#include "src/tint/ir/if.h"
-#include "src/tint/ir/instruction.h"
#include "src/tint/ir/loop.h"
#include "src/tint/ir/module.h"
#include "src/tint/ir/switch.h"
@@ -102,117 +102,115 @@
/// @param lhs the left-hand-side of the operation
/// @param rhs the right-hand-side of the operation
/// @returns the operation
- const Instruction* CreateInstruction(Instruction::Kind kind,
- const Value* lhs,
- const Value* rhs);
+ const Binary* CreateBinary(Binary::Kind kind, const Value* lhs, const Value* rhs);
/// Creates an And operation
/// @param lhs the lhs of the add
/// @param rhs the rhs of the add
/// @returns the operation
- const Instruction* And(const Value* lhs, const Value* rhs);
+ const Binary* And(const Value* lhs, const Value* rhs);
/// Creates an Or operation
/// @param lhs the lhs of the add
/// @param rhs the rhs of the add
/// @returns the operation
- const Instruction* Or(const Value* lhs, const Value* rhs);
+ const Binary* Or(const Value* lhs, const Value* rhs);
/// Creates an Xor operation
/// @param lhs the lhs of the add
/// @param rhs the rhs of the add
/// @returns the operation
- const Instruction* Xor(const Value* lhs, const Value* rhs);
+ const Binary* Xor(const Value* lhs, const Value* rhs);
/// Creates an LogicalAnd operation
/// @param lhs the lhs of the add
/// @param rhs the rhs of the add
/// @returns the operation
- const Instruction* LogicalAnd(const Value* lhs, const Value* rhs);
+ const Binary* LogicalAnd(const Value* lhs, const Value* rhs);
/// Creates an LogicalOr operation
/// @param lhs the lhs of the add
/// @param rhs the rhs of the add
/// @returns the operation
- const Instruction* LogicalOr(const Value* lhs, const Value* rhs);
+ const Binary* LogicalOr(const Value* lhs, const Value* rhs);
/// Creates an Equal operation
/// @param lhs the lhs of the add
/// @param rhs the rhs of the add
/// @returns the operation
- const Instruction* Equal(const Value* lhs, const Value* rhs);
+ const Binary* Equal(const Value* lhs, const Value* rhs);
/// Creates an NotEqual operation
/// @param lhs the lhs of the add
/// @param rhs the rhs of the add
/// @returns the operation
- const Instruction* NotEqual(const Value* lhs, const Value* rhs);
+ const Binary* NotEqual(const Value* lhs, const Value* rhs);
/// Creates an LessThan operation
/// @param lhs the lhs of the add
/// @param rhs the rhs of the add
/// @returns the operation
- const Instruction* LessThan(const Value* lhs, const Value* rhs);
+ const Binary* LessThan(const Value* lhs, const Value* rhs);
/// Creates an GreaterThan operation
/// @param lhs the lhs of the add
/// @param rhs the rhs of the add
/// @returns the operation
- const Instruction* GreaterThan(const Value* lhs, const Value* rhs);
+ const Binary* GreaterThan(const Value* lhs, const Value* rhs);
/// Creates an LessThanEqual operation
/// @param lhs the lhs of the add
/// @param rhs the rhs of the add
/// @returns the operation
- const Instruction* LessThanEqual(const Value* lhs, const Value* rhs);
+ const Binary* LessThanEqual(const Value* lhs, const Value* rhs);
/// Creates an GreaterThanEqual operation
/// @param lhs the lhs of the add
/// @param rhs the rhs of the add
/// @returns the operation
- const Instruction* GreaterThanEqual(const Value* lhs, const Value* rhs);
+ const Binary* GreaterThanEqual(const Value* lhs, const Value* rhs);
/// Creates an ShiftLeft operation
/// @param lhs the lhs of the add
/// @param rhs the rhs of the add
/// @returns the operation
- const Instruction* ShiftLeft(const Value* lhs, const Value* rhs);
+ const Binary* ShiftLeft(const Value* lhs, const Value* rhs);
/// Creates an ShiftRight operation
/// @param lhs the lhs of the add
/// @param rhs the rhs of the add
/// @returns the operation
- const Instruction* ShiftRight(const Value* lhs, const Value* rhs);
+ const Binary* ShiftRight(const Value* lhs, const Value* rhs);
/// Creates an Add operation
/// @param lhs the lhs of the add
/// @param rhs the rhs of the add
/// @returns the operation
- const Instruction* Add(const Value* lhs, const Value* rhs);
+ const Binary* Add(const Value* lhs, const Value* rhs);
/// Creates an Subtract operation
/// @param lhs the lhs of the add
/// @param rhs the rhs of the add
/// @returns the operation
- const Instruction* Subtract(const Value* lhs, const Value* rhs);
+ const Binary* Subtract(const Value* lhs, const Value* rhs);
/// Creates an Multiply operation
/// @param lhs the lhs of the add
/// @param rhs the rhs of the add
/// @returns the operation
- const Instruction* Multiply(const Value* lhs, const Value* rhs);
+ const Binary* Multiply(const Value* lhs, const Value* rhs);
/// Creates an Divide operation
/// @param lhs the lhs of the add
/// @param rhs the rhs of the add
/// @returns the operation
- const Instruction* Divide(const Value* lhs, const Value* rhs);
+ const Binary* Divide(const Value* lhs, const Value* rhs);
/// Creates an Modulo operation
/// @param lhs the lhs of the add
/// @param rhs the rhs of the add
/// @returns the operation
- const Instruction* Modulo(const Value* lhs, const Value* rhs);
+ const Binary* Modulo(const Value* lhs, const Value* rhs);
/// @returns a unique temp id
Temp::Id AllocateTempId();
diff --git a/src/tint/ir/builder_impl.cc b/src/tint/ir/builder_impl.cc
index 2286bf4..042a7d5 100644
--- a/src/tint/ir/builder_impl.cc
+++ b/src/tint/ir/builder_impl.cc
@@ -562,7 +562,7 @@
return utils::Failure;
}
- const Instruction* instr = nullptr;
+ const Binary* instr = nullptr;
switch (expr->op) {
case ast::BinaryOp::kAnd:
instr = builder.And(lhs.Get(), rhs.Get());
diff --git a/src/tint/ir/constant.cc b/src/tint/ir/constant.cc
index 78895bf..0138190 100644
--- a/src/tint/ir/constant.cc
+++ b/src/tint/ir/constant.cc
@@ -32,22 +32,22 @@
Constant::~Constant() = default;
-std::ostream& operator<<(std::ostream& out, const Constant& r) {
- switch (r.GetKind()) {
+std::ostream& Constant::ToString(std::ostream& out) const {
+ switch (GetKind()) {
case Constant::Kind::kF32:
- out << std::to_string(r.AsF32().value);
+ out << std::to_string(AsF32().value);
break;
case Constant::Kind::kF16:
- out << std::to_string(r.AsF16().value);
+ out << std::to_string(AsF16().value);
break;
case Constant::Kind::kI32:
- out << std::to_string(r.AsI32().value);
+ out << std::to_string(AsI32().value);
break;
case Constant::Kind::kU32:
- out << std::to_string(r.AsU32().value);
+ out << std::to_string(AsU32().value);
break;
case Constant::Kind::kBool:
- out << (r.AsBool() ? "true" : "false");
+ out << (AsBool() ? "true" : "false");
break;
}
return out;
diff --git a/src/tint/ir/constant.h b/src/tint/ir/constant.h
index c06e121..23eeb02 100644
--- a/src/tint/ir/constant.h
+++ b/src/tint/ir/constant.h
@@ -100,6 +100,11 @@
/// @note, must only be called if `IsBool()` is true
bool AsBool() const { return std::get<bool>(data_); }
+ /// Write the constant to the given stream
+ /// @param out the stream to write to
+ /// @returns the stream
+ std::ostream& ToString(std::ostream& out) const override;
+
private:
/// The type of data stored in this constant
Kind kind_;
@@ -107,8 +112,6 @@
std::variant<f32, f16, u32, i32, bool> data_;
};
-std::ostream& operator<<(std::ostream& out, const Constant& r);
-
} // namespace tint::ir
#endif // SRC_TINT_IR_CONSTANT_H_
diff --git a/src/tint/ir/constant_test.cc b/src/tint/ir/constant_test.cc
index 7b4e224..b20b424 100644
--- a/src/tint/ir/constant_test.cc
+++ b/src/tint/ir/constant_test.cc
@@ -32,7 +32,7 @@
auto* val = b.builder.Constant(1.2_f);
EXPECT_EQ(1.2_f, val->AsF32());
- str << *val;
+ val->ToString(str);
EXPECT_EQ("1.200000", str.str());
EXPECT_TRUE(val->IsF32());
@@ -50,7 +50,7 @@
auto* val = b.builder.Constant(1.1_h);
EXPECT_EQ(1.1_h, val->AsF16());
- str << *val;
+ val->ToString(str);
EXPECT_EQ("1.099609", str.str());
EXPECT_FALSE(val->IsF32());
@@ -68,7 +68,7 @@
auto* val = b.builder.Constant(1_i);
EXPECT_EQ(1_i, val->AsI32());
- str << *val;
+ val->ToString(str);
EXPECT_EQ("1", str.str());
EXPECT_FALSE(val->IsF32());
@@ -86,7 +86,7 @@
auto* val = b.builder.Constant(2_u);
EXPECT_EQ(2_u, val->AsU32());
- str << *val;
+ val->ToString(str);
EXPECT_EQ("2", str.str());
EXPECT_FALSE(val->IsF32());
@@ -104,14 +104,14 @@
auto* val = b.builder.Constant(false);
EXPECT_FALSE(val->AsBool());
- str << *val;
+ val->ToString(str);
EXPECT_EQ("false", str.str());
str.str("");
val = b.builder.Constant(true);
EXPECT_TRUE(val->AsBool());
- str << *val;
+ val->ToString(str);
EXPECT_EQ("true", str.str());
EXPECT_FALSE(val->IsF32());
diff --git a/src/tint/ir/disassembler.cc b/src/tint/ir/disassembler.cc
index e2749a1..d8ee4ba 100644
--- a/src/tint/ir/disassembler.cc
+++ b/src/tint/ir/disassembler.cc
@@ -63,7 +63,7 @@
void Disassembler::EmitBlockInstructions(const Block* b) {
for (const auto* instr : b->instructions) {
- out_ << *instr << std::endl;
+ instr->ToString(out_) << std::endl;
}
}
diff --git a/src/tint/ir/instruction.cc b/src/tint/ir/instruction.cc
index 6c0f176..e54b13f 100644
--- a/src/tint/ir/instruction.cc
+++ b/src/tint/ir/instruction.cc
@@ -18,90 +18,8 @@
namespace tint::ir {
-Instruction::Instruction() {}
-
-Instruction::Instruction(Kind kind, const Value* result, const Value* lhs, const Value* rhs)
- : kind_(kind), result_(result), args_({lhs, rhs}) {}
-
-Instruction::Instruction(const Instruction&) = default;
-
-Instruction::Instruction(Instruction&& instr) = default;
+Instruction::Instruction() = default;
Instruction::~Instruction() = default;
-Instruction& Instruction::operator=(const Instruction& instr) = default;
-
-Instruction& Instruction::operator=(Instruction&& instr) = default;
-
-std::ostream& operator<<(std::ostream& out, const Instruction& instr) {
- out << *(instr.Result()) << " = ";
- if (instr.HasLHS()) {
- out << *(instr.LHS());
- }
- out << " ";
-
- switch (instr.GetKind()) {
- case Instruction::Kind::kAdd:
- out << "+";
- break;
- case Instruction::Kind::kSubtract:
- out << "-";
- break;
- case Instruction::Kind::kMultiply:
- out << "*";
- break;
- case Instruction::Kind::kDivide:
- out << "/";
- break;
- case Instruction::Kind::kModulo:
- out << "%";
- break;
- case Instruction::Kind::kAnd:
- out << "&";
- break;
- case Instruction::Kind::kOr:
- out << "|";
- break;
- case Instruction::Kind::kXor:
- out << "^";
- break;
- case Instruction::Kind::kLogicalAnd:
- out << "&&";
- break;
- case Instruction::Kind::kLogicalOr:
- out << "||";
- break;
- case Instruction::Kind::kEqual:
- out << "==";
- break;
- case Instruction::Kind::kNotEqual:
- out << "!=";
- break;
- case Instruction::Kind::kLessThan:
- out << "<";
- break;
- case Instruction::Kind::kGreaterThan:
- out << ">";
- break;
- case Instruction::Kind::kLessThanEqual:
- out << "<=";
- break;
- case Instruction::Kind::kGreaterThanEqual:
- out << ">=";
- break;
- case Instruction::Kind::kShiftLeft:
- out << "<<";
- break;
- case Instruction::Kind::kShiftRight:
- out << ">>";
- break;
- }
-
- if (instr.HasRHS()) {
- out << " " << *(instr.RHS());
- }
-
- return out;
-}
-
} // namespace tint::ir
diff --git a/src/tint/ir/instruction.h b/src/tint/ir/instruction.h
index 461b1f7..8b68465 100644
--- a/src/tint/ir/instruction.h
+++ b/src/tint/ir/instruction.h
@@ -18,98 +18,30 @@
#include <ostream>
#include "src/tint/castable.h"
-#include "src/tint/debug.h"
-#include "src/tint/ir/value.h"
-#include "src/tint/utils/vector.h"
namespace tint::ir {
/// An instruction in the IR.
class Instruction : public Castable<Instruction> {
public:
- /// The kind of instruction.
- enum class Kind {
- kAdd,
- kSubtract,
- kMultiply,
- kDivide,
- kModulo,
+ Instruction(const Instruction& instr) = delete;
+ Instruction(Instruction&& instr) = delete;
+ /// Destructor
+ ~Instruction() override;
- kAnd,
- kOr,
- kXor,
+ Instruction& operator=(const Instruction& instr) = delete;
+ Instruction& operator=(Instruction&& instr) = delete;
- kLogicalAnd,
- kLogicalOr,
+ /// Write the instruction to the given stream
+ /// @param out the stream to write to
+ /// @returns the stream
+ virtual std::ostream& ToString(std::ostream& out) const = 0;
- kEqual,
- kNotEqual,
- kLessThan,
- kGreaterThan,
- kLessThanEqual,
- kGreaterThanEqual,
-
- kShiftLeft,
- kShiftRight
- };
-
+ protected:
/// Constructor
Instruction();
- /// Constructor
- /// @param kind the kind of instruction
- /// @param result the result value
- /// @param lhs the lhs of the instruction
- /// @param rhs the rhs of the instruction
- Instruction(Kind kind, const Value* result, const Value* lhs, const Value* rhs);
- /// Copy constructor
- /// @param instr the instruction to copy from
- Instruction(const Instruction& instr);
- /// Move constructor
- /// @param instr the instruction to move from
- Instruction(Instruction&& instr);
- /// Destructor
- ~Instruction();
-
- /// Copy assign
- /// @param instr the instruction to copy from
- /// @returns a reference to this
- Instruction& operator=(const Instruction& instr);
- /// Move assign
- /// @param instr the instruction to move from
- /// @returns a reference to this
- Instruction& operator=(Instruction&& instr);
-
- /// @returns the kind of instruction
- Kind GetKind() const { return kind_; }
-
- /// @returns the result value for the instruction
- const Value* Result() const { return result_; }
-
- /// @returns true if the instruction has a LHS
- bool HasLHS() const { return args_.Length() >= 1; }
- /// @returns the left-hand-side value for the instruction
- const Value* LHS() const {
- TINT_ASSERT(IR, HasLHS());
- return args_[0];
- }
-
- /// @returns true if the instruction has a RHS
- bool HasRHS() const { return args_.Length() >= 2; }
- /// @returns the right-hand-side value for the instruction
- const Value* RHS() const {
- TINT_ASSERT(IR, HasRHS());
- return args_[1];
- }
-
- private:
- Kind kind_;
-
- const Value* result_;
- utils::Vector<const Value*, 2> args_;
};
-std::ostream& operator<<(std::ostream& out, const Instruction&);
-
} // namespace tint::ir
#endif // SRC_TINT_IR_INSTRUCTION_H_
diff --git a/src/tint/ir/instruction_test.cc b/src/tint/ir/instruction_test.cc
index 0957903..08302ed 100644
--- a/src/tint/ir/instruction_test.cc
+++ b/src/tint/ir/instruction_test.cc
@@ -20,9 +20,9 @@
namespace tint::ir {
namespace {
-using IR_InstructionTest = TestHelper;
+using IR_BinaryTest = TestHelper;
-TEST_F(IR_InstructionTest, CreateAnd) {
+TEST_F(IR_BinaryTest, CreateAnd) {
auto& b = CreateEmptyBuilder();
b.builder.next_temp_id = Temp::Id(42);
@@ -33,24 +33,22 @@
ASSERT_TRUE(instr->Result()->Is<Temp>());
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
- ASSERT_TRUE(instr->HasLHS());
ASSERT_TRUE(instr->LHS()->Is<Constant>());
auto lhs = instr->LHS()->As<Constant>();
ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs->AsI32());
- ASSERT_TRUE(instr->HasRHS());
ASSERT_TRUE(instr->RHS()->Is<Constant>());
auto rhs = instr->RHS()->As<Constant>();
ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str;
- str << *instr;
+ instr->ToString(str);
EXPECT_EQ(str.str(), "%42 = 4 & 2");
}
-TEST_F(IR_InstructionTest, CreateOr) {
+TEST_F(IR_BinaryTest, CreateOr) {
auto& b = CreateEmptyBuilder();
b.builder.next_temp_id = Temp::Id(42);
@@ -61,24 +59,22 @@
ASSERT_TRUE(instr->Result()->Is<Temp>());
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
- ASSERT_TRUE(instr->HasLHS());
ASSERT_TRUE(instr->LHS()->Is<Constant>());
auto lhs = instr->LHS()->As<Constant>();
ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs->AsI32());
- ASSERT_TRUE(instr->HasRHS());
ASSERT_TRUE(instr->RHS()->Is<Constant>());
auto rhs = instr->RHS()->As<Constant>();
ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str;
- str << *instr;
+ instr->ToString(str);
EXPECT_EQ(str.str(), "%42 = 4 | 2");
}
-TEST_F(IR_InstructionTest, CreateXor) {
+TEST_F(IR_BinaryTest, CreateXor) {
auto& b = CreateEmptyBuilder();
b.builder.next_temp_id = Temp::Id(42);
@@ -89,24 +85,22 @@
ASSERT_TRUE(instr->Result()->Is<Temp>());
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
- ASSERT_TRUE(instr->HasLHS());
ASSERT_TRUE(instr->LHS()->Is<Constant>());
auto lhs = instr->LHS()->As<Constant>();
ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs->AsI32());
- ASSERT_TRUE(instr->HasRHS());
ASSERT_TRUE(instr->RHS()->Is<Constant>());
auto rhs = instr->RHS()->As<Constant>();
ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str;
- str << *instr;
+ instr->ToString(str);
EXPECT_EQ(str.str(), "%42 = 4 ^ 2");
}
-TEST_F(IR_InstructionTest, CreateLogicalAnd) {
+TEST_F(IR_BinaryTest, CreateLogicalAnd) {
auto& b = CreateEmptyBuilder();
b.builder.next_temp_id = Temp::Id(42);
@@ -118,24 +112,22 @@
ASSERT_TRUE(instr->Result()->Is<Temp>());
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
- ASSERT_TRUE(instr->HasLHS());
ASSERT_TRUE(instr->LHS()->Is<Constant>());
auto lhs = instr->LHS()->As<Constant>();
ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs->AsI32());
- ASSERT_TRUE(instr->HasRHS());
ASSERT_TRUE(instr->RHS()->Is<Constant>());
auto rhs = instr->RHS()->As<Constant>();
ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str;
- str << *instr;
+ instr->ToString(str);
EXPECT_EQ(str.str(), "%42 = 4 && 2");
}
-TEST_F(IR_InstructionTest, CreateLogicalOr) {
+TEST_F(IR_BinaryTest, CreateLogicalOr) {
auto& b = CreateEmptyBuilder();
b.builder.next_temp_id = Temp::Id(42);
@@ -146,24 +138,22 @@
ASSERT_TRUE(instr->Result()->Is<Temp>());
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
- ASSERT_TRUE(instr->HasLHS());
ASSERT_TRUE(instr->LHS()->Is<Constant>());
auto lhs = instr->LHS()->As<Constant>();
ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs->AsI32());
- ASSERT_TRUE(instr->HasRHS());
ASSERT_TRUE(instr->RHS()->Is<Constant>());
auto rhs = instr->RHS()->As<Constant>();
ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str;
- str << *instr;
+ instr->ToString(str);
EXPECT_EQ(str.str(), "%42 = 4 || 2");
}
-TEST_F(IR_InstructionTest, CreateEqual) {
+TEST_F(IR_BinaryTest, CreateEqual) {
auto& b = CreateEmptyBuilder();
b.builder.next_temp_id = Temp::Id(42);
@@ -174,24 +164,22 @@
ASSERT_TRUE(instr->Result()->Is<Temp>());
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
- ASSERT_TRUE(instr->HasLHS());
ASSERT_TRUE(instr->LHS()->Is<Constant>());
auto lhs = instr->LHS()->As<Constant>();
ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs->AsI32());
- ASSERT_TRUE(instr->HasRHS());
ASSERT_TRUE(instr->RHS()->Is<Constant>());
auto rhs = instr->RHS()->As<Constant>();
ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str;
- str << *instr;
+ instr->ToString(str);
EXPECT_EQ(str.str(), "%42 = 4 == 2");
}
-TEST_F(IR_InstructionTest, CreateNotEqual) {
+TEST_F(IR_BinaryTest, CreateNotEqual) {
auto& b = CreateEmptyBuilder();
b.builder.next_temp_id = Temp::Id(42);
@@ -202,24 +190,22 @@
ASSERT_TRUE(instr->Result()->Is<Temp>());
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
- ASSERT_TRUE(instr->HasLHS());
ASSERT_TRUE(instr->LHS()->Is<Constant>());
auto lhs = instr->LHS()->As<Constant>();
ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs->AsI32());
- ASSERT_TRUE(instr->HasRHS());
ASSERT_TRUE(instr->RHS()->Is<Constant>());
auto rhs = instr->RHS()->As<Constant>();
ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str;
- str << *instr;
+ instr->ToString(str);
EXPECT_EQ(str.str(), "%42 = 4 != 2");
}
-TEST_F(IR_InstructionTest, CreateLessThan) {
+TEST_F(IR_BinaryTest, CreateLessThan) {
auto& b = CreateEmptyBuilder();
b.builder.next_temp_id = Temp::Id(42);
@@ -230,24 +216,22 @@
ASSERT_TRUE(instr->Result()->Is<Temp>());
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
- ASSERT_TRUE(instr->HasLHS());
ASSERT_TRUE(instr->LHS()->Is<Constant>());
auto lhs = instr->LHS()->As<Constant>();
ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs->AsI32());
- ASSERT_TRUE(instr->HasRHS());
ASSERT_TRUE(instr->RHS()->Is<Constant>());
auto rhs = instr->RHS()->As<Constant>();
ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str;
- str << *instr;
+ instr->ToString(str);
EXPECT_EQ(str.str(), "%42 = 4 < 2");
}
-TEST_F(IR_InstructionTest, CreateGreaterThan) {
+TEST_F(IR_BinaryTest, CreateGreaterThan) {
auto& b = CreateEmptyBuilder();
b.builder.next_temp_id = Temp::Id(42);
@@ -259,24 +243,22 @@
ASSERT_TRUE(instr->Result()->Is<Temp>());
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
- ASSERT_TRUE(instr->HasLHS());
ASSERT_TRUE(instr->LHS()->Is<Constant>());
auto lhs = instr->LHS()->As<Constant>();
ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs->AsI32());
- ASSERT_TRUE(instr->HasRHS());
ASSERT_TRUE(instr->RHS()->Is<Constant>());
auto rhs = instr->RHS()->As<Constant>();
ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str;
- str << *instr;
+ instr->ToString(str);
EXPECT_EQ(str.str(), "%42 = 4 > 2");
}
-TEST_F(IR_InstructionTest, CreateLessThanEqual) {
+TEST_F(IR_BinaryTest, CreateLessThanEqual) {
auto& b = CreateEmptyBuilder();
b.builder.next_temp_id = Temp::Id(42);
@@ -288,24 +270,22 @@
ASSERT_TRUE(instr->Result()->Is<Temp>());
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
- ASSERT_TRUE(instr->HasLHS());
ASSERT_TRUE(instr->LHS()->Is<Constant>());
auto lhs = instr->LHS()->As<Constant>();
ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs->AsI32());
- ASSERT_TRUE(instr->HasRHS());
ASSERT_TRUE(instr->RHS()->Is<Constant>());
auto rhs = instr->RHS()->As<Constant>();
ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str;
- str << *instr;
+ instr->ToString(str);
EXPECT_EQ(str.str(), "%42 = 4 <= 2");
}
-TEST_F(IR_InstructionTest, CreateGreaterThanEqual) {
+TEST_F(IR_BinaryTest, CreateGreaterThanEqual) {
auto& b = CreateEmptyBuilder();
b.builder.next_temp_id = Temp::Id(42);
@@ -317,24 +297,22 @@
ASSERT_TRUE(instr->Result()->Is<Temp>());
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
- ASSERT_TRUE(instr->HasLHS());
ASSERT_TRUE(instr->LHS()->Is<Constant>());
auto lhs = instr->LHS()->As<Constant>();
ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs->AsI32());
- ASSERT_TRUE(instr->HasRHS());
ASSERT_TRUE(instr->RHS()->Is<Constant>());
auto rhs = instr->RHS()->As<Constant>();
ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str;
- str << *instr;
+ instr->ToString(str);
EXPECT_EQ(str.str(), "%42 = 4 >= 2");
}
-TEST_F(IR_InstructionTest, CreateShiftLeft) {
+TEST_F(IR_BinaryTest, CreateShiftLeft) {
auto& b = CreateEmptyBuilder();
b.builder.next_temp_id = Temp::Id(42);
@@ -345,24 +323,22 @@
ASSERT_TRUE(instr->Result()->Is<Temp>());
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
- ASSERT_TRUE(instr->HasLHS());
ASSERT_TRUE(instr->LHS()->Is<Constant>());
auto lhs = instr->LHS()->As<Constant>();
ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs->AsI32());
- ASSERT_TRUE(instr->HasRHS());
ASSERT_TRUE(instr->RHS()->Is<Constant>());
auto rhs = instr->RHS()->As<Constant>();
ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str;
- str << *instr;
+ instr->ToString(str);
EXPECT_EQ(str.str(), "%42 = 4 << 2");
}
-TEST_F(IR_InstructionTest, CreateShiftRight) {
+TEST_F(IR_BinaryTest, CreateShiftRight) {
auto& b = CreateEmptyBuilder();
b.builder.next_temp_id = Temp::Id(42);
@@ -374,24 +350,22 @@
ASSERT_TRUE(instr->Result()->Is<Temp>());
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
- ASSERT_TRUE(instr->HasLHS());
ASSERT_TRUE(instr->LHS()->Is<Constant>());
auto lhs = instr->LHS()->As<Constant>();
ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs->AsI32());
- ASSERT_TRUE(instr->HasRHS());
ASSERT_TRUE(instr->RHS()->Is<Constant>());
auto rhs = instr->RHS()->As<Constant>();
ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str;
- str << *instr;
+ instr->ToString(str);
EXPECT_EQ(str.str(), "%42 = 4 >> 2");
}
-TEST_F(IR_InstructionTest, CreateAdd) {
+TEST_F(IR_BinaryTest, CreateAdd) {
auto& b = CreateEmptyBuilder();
b.builder.next_temp_id = Temp::Id(42);
@@ -402,24 +376,22 @@
ASSERT_TRUE(instr->Result()->Is<Temp>());
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
- ASSERT_TRUE(instr->HasLHS());
ASSERT_TRUE(instr->LHS()->Is<Constant>());
auto lhs = instr->LHS()->As<Constant>();
ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs->AsI32());
- ASSERT_TRUE(instr->HasRHS());
ASSERT_TRUE(instr->RHS()->Is<Constant>());
auto rhs = instr->RHS()->As<Constant>();
ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str;
- str << *instr;
+ instr->ToString(str);
EXPECT_EQ(str.str(), "%42 = 4 + 2");
}
-TEST_F(IR_InstructionTest, CreateSubtract) {
+TEST_F(IR_BinaryTest, CreateSubtract) {
auto& b = CreateEmptyBuilder();
b.builder.next_temp_id = Temp::Id(42);
@@ -430,24 +402,22 @@
ASSERT_TRUE(instr->Result()->Is<Temp>());
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
- ASSERT_TRUE(instr->HasLHS());
ASSERT_TRUE(instr->LHS()->Is<Constant>());
auto lhs = instr->LHS()->As<Constant>();
ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs->AsI32());
- ASSERT_TRUE(instr->HasRHS());
ASSERT_TRUE(instr->RHS()->Is<Constant>());
auto rhs = instr->RHS()->As<Constant>();
ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str;
- str << *instr;
+ instr->ToString(str);
EXPECT_EQ(str.str(), "%42 = 4 - 2");
}
-TEST_F(IR_InstructionTest, CreateMultiply) {
+TEST_F(IR_BinaryTest, CreateMultiply) {
auto& b = CreateEmptyBuilder();
b.builder.next_temp_id = Temp::Id(42);
@@ -458,24 +428,22 @@
ASSERT_TRUE(instr->Result()->Is<Temp>());
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
- ASSERT_TRUE(instr->HasLHS());
ASSERT_TRUE(instr->LHS()->Is<Constant>());
auto lhs = instr->LHS()->As<Constant>();
ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs->AsI32());
- ASSERT_TRUE(instr->HasRHS());
ASSERT_TRUE(instr->RHS()->Is<Constant>());
auto rhs = instr->RHS()->As<Constant>();
ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str;
- str << *instr;
+ instr->ToString(str);
EXPECT_EQ(str.str(), "%42 = 4 * 2");
}
-TEST_F(IR_InstructionTest, CreateDivide) {
+TEST_F(IR_BinaryTest, CreateDivide) {
auto& b = CreateEmptyBuilder();
b.builder.next_temp_id = Temp::Id(42);
@@ -486,24 +454,22 @@
ASSERT_TRUE(instr->Result()->Is<Temp>());
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
- ASSERT_TRUE(instr->HasLHS());
ASSERT_TRUE(instr->LHS()->Is<Constant>());
auto lhs = instr->LHS()->As<Constant>();
ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs->AsI32());
- ASSERT_TRUE(instr->HasRHS());
ASSERT_TRUE(instr->RHS()->Is<Constant>());
auto rhs = instr->RHS()->As<Constant>();
ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str;
- str << *instr;
+ instr->ToString(str);
EXPECT_EQ(str.str(), "%42 = 4 / 2");
}
-TEST_F(IR_InstructionTest, CreateModulo) {
+TEST_F(IR_BinaryTest, CreateModulo) {
auto& b = CreateEmptyBuilder();
b.builder.next_temp_id = Temp::Id(42);
@@ -514,20 +480,18 @@
ASSERT_TRUE(instr->Result()->Is<Temp>());
EXPECT_EQ(Temp::Id(42), instr->Result()->As<Temp>()->AsId());
- ASSERT_TRUE(instr->HasLHS());
ASSERT_TRUE(instr->LHS()->Is<Constant>());
auto lhs = instr->LHS()->As<Constant>();
ASSERT_TRUE(lhs->IsI32());
EXPECT_EQ(i32(4), lhs->AsI32());
- ASSERT_TRUE(instr->HasRHS());
ASSERT_TRUE(instr->RHS()->Is<Constant>());
auto rhs = instr->RHS()->As<Constant>();
ASSERT_TRUE(rhs->IsI32());
EXPECT_EQ(i32(2), rhs->AsI32());
std::stringstream str;
- str << *instr;
+ instr->ToString(str);
EXPECT_EQ(str.str(), "%42 = 4 % 2");
}
diff --git a/src/tint/ir/temp.cc b/src/tint/ir/temp.cc
index de227ee..30efb86 100644
--- a/src/tint/ir/temp.cc
+++ b/src/tint/ir/temp.cc
@@ -24,8 +24,8 @@
Temp::~Temp() = default;
-std::ostream& operator<<(std::ostream& out, const Temp& r) {
- out << "%" << std::to_string(r.AsId());
+std::ostream& Temp::ToString(std::ostream& out) const {
+ out << "%" << std::to_string(AsId());
return out;
}
diff --git a/src/tint/ir/temp.h b/src/tint/ir/temp.h
index b16baf2..c621b5c 100644
--- a/src/tint/ir/temp.h
+++ b/src/tint/ir/temp.h
@@ -43,12 +43,15 @@
/// @returns the value data as an `Id`.
Id AsId() const { return id_; }
+ /// Write the temp to the given stream
+ /// @param out the stream to write to
+ /// @returns the stream
+ std::ostream& ToString(std::ostream& out) const override;
+
private:
Id id_ = 0;
};
-std::ostream& operator<<(std::ostream& out, const Temp& r);
-
} // namespace tint::ir
#endif // SRC_TINT_IR_TEMP_H_
diff --git a/src/tint/ir/temp_test.cc b/src/tint/ir/temp_test.cc
index b5d817b..1dcae13 100644
--- a/src/tint/ir/temp_test.cc
+++ b/src/tint/ir/temp_test.cc
@@ -33,7 +33,7 @@
auto* val = b.builder.Temp();
EXPECT_EQ(4u, val->AsId());
- str << *val;
+ val->ToString(str);
EXPECT_EQ("%4", str.str());
}
diff --git a/src/tint/ir/value.cc b/src/tint/ir/value.cc
index a1431e3..93040cf 100644
--- a/src/tint/ir/value.cc
+++ b/src/tint/ir/value.cc
@@ -25,17 +25,4 @@
Value::~Value() = default;
-std::ostream& operator<<(std::ostream& out, const Value& v) {
- const auto* ptr = &v;
-
- if (auto* c = ptr->As<Constant>()) {
- out << *c;
- } else if (auto* t = ptr->As<Temp>()) {
- out << *t;
- } else {
- out << "Unknown value";
- }
- return out;
-}
-
} // namespace tint::ir
diff --git a/src/tint/ir/value.h b/src/tint/ir/value.h
index 326931f..9c41f52 100644
--- a/src/tint/ir/value.h
+++ b/src/tint/ir/value.h
@@ -25,7 +25,7 @@
class Value : public Castable<Value> {
public:
/// Destructor
- virtual ~Value();
+ ~Value() override;
Value(const Value&) = delete;
Value(Value&&) = delete;
@@ -33,13 +33,16 @@
Value& operator=(const Value&) = delete;
Value& operator=(Value&&) = delete;
+ /// Write the value to the given stream
+ /// @param out the stream to write to
+ /// @returns the stream
+ virtual std::ostream& ToString(std::ostream& out) const = 0;
+
protected:
/// Constructor
Value();
};
-std::ostream& operator<<(std::ostream& out, const Value& v);
-
} // namespace tint::ir
#endif // SRC_TINT_IR_VALUE_H_
diff --git a/src/tint/number.h b/src/tint/number.h
index dc66689..9b7ce43 100644
--- a/src/tint/number.h
+++ b/src/tint/number.h
@@ -543,6 +543,38 @@
return result;
}
+namespace detail {
+/// @returns the remainder of e1 / e2
+template <typename T>
+inline T Mod(T e1, T e2) {
+ return e1 - e2 * static_cast<T>(std::trunc(e1 / e2));
+}
+} // namespace detail
+
+/// @returns the remainder of a / b, or an empty optional if the resulting value overflowed the AInt
+inline std::optional<AInt> CheckedMod(AInt a, AInt b) {
+ if (b == 0) {
+ return {};
+ }
+
+ if (b == -1 && a == AInt::Lowest()) {
+ return {};
+ }
+
+ return AInt{detail::Mod(a.value, b.value)};
+}
+
+/// @returns the remainder of a / b, or an empty optional if the resulting value overflowed the
+/// float value
+template <typename FloatingPointT, typename = traits::EnableIf<IsFloatingPoint<FloatingPointT>>>
+inline std::optional<FloatingPointT> CheckedMod(FloatingPointT a, FloatingPointT b) {
+ auto result = FloatingPointT{detail::Mod(a.value, b.value)};
+ if (!std::isfinite(result.value)) {
+ return {};
+ }
+ return result;
+}
+
/// @returns a * b + c, or an empty optional if the value overflowed the AInt
inline std::optional<AInt> CheckedMadd(AInt a, AInt b, AInt c) {
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635
diff --git a/src/tint/number_test.cc b/src/tint/number_test.cc
index f21e531..040fd76 100644
--- a/src/tint/number_test.cc
+++ b/src/tint/number_test.cc
@@ -687,6 +687,58 @@
CheckedDivTest_FloatCases<f32>(),
CheckedDivTest_FloatCases<f16>())));
+using CheckedModTest_AInt = testing::TestWithParam<BinaryCheckedCase_AInt>;
+TEST_P(CheckedModTest_AInt, Test) {
+ auto expect = std::get<0>(GetParam());
+ auto a = std::get<1>(GetParam());
+ auto b = std::get<2>(GetParam());
+ EXPECT_TRUE(CheckedMod(a, b) == expect) << std::hex << "0x" << a << " - 0x" << b;
+}
+INSTANTIATE_TEST_SUITE_P(
+ CheckedModTest_AInt,
+ CheckedModTest_AInt,
+ testing::ValuesIn(std::vector<BinaryCheckedCase_AInt>{
+ {AInt(0), AInt(0), AInt(1)},
+ {AInt(0), AInt(1), AInt(1)},
+ {AInt(1), AInt(10), AInt(3)},
+ {AInt(2), AInt(10), AInt(4)},
+ {AInt(0), AInt::Highest(), AInt::Highest()},
+ {AInt(0), AInt::Lowest(), AInt::Lowest()},
+ {OVERFLOW, AInt::Highest(), AInt(0)},
+ {OVERFLOW, AInt::Lowest(), AInt(0)},
+ ////////////////////////////////////////////////////////////////////////
+ }));
+
+using CheckedModTest_Float = testing::TestWithParam<BinaryCheckedCase_Float>;
+TEST_P(CheckedModTest_Float, Test) {
+ auto& p = GetParam();
+ std::visit(
+ [&](auto&& lhs) {
+ using T = std::decay_t<decltype(lhs)>;
+ auto rhs = std::get<T>(std::get<2>(p));
+ auto expect = std::get<std::optional<T>>(std::get<0>(p));
+ EXPECT_TRUE(CheckedMod(lhs, rhs) == expect)
+ << std::hex << "0x" << lhs << " / 0x" << rhs;
+ },
+ std::get<1>(p));
+}
+template <typename T>
+std::vector<BinaryCheckedCase_Float> CheckedModTest_FloatCases() {
+ return {
+ {T(0.5), T(10.5), T(1)}, {T(0.5), T(10.5), T(2)},
+ {T(1.5), T(10.5), T(3)}, {T(2.5), T(10.5), T(4)},
+ {T(0.5), T(10.5), T(5)}, {T(0), T::Highest(), T::Highest()},
+ {T(0), T::Lowest(), T::Lowest()}, {Overflow<T>, T(123), T(0)},
+ {Overflow<T>, T(123), T(-0)}, {Overflow<T>, T(-123), T(0)},
+ {Overflow<T>, T(-123), T(-0)},
+ };
+}
+INSTANTIATE_TEST_SUITE_P(CheckedModTest_Float,
+ CheckedModTest_Float,
+ testing::ValuesIn(Concat(CheckedModTest_FloatCases<AFloat>(),
+ CheckedModTest_FloatCases<f32>(),
+ CheckedModTest_FloatCases<f16>())));
+
using TernaryCheckedCase = std::tuple<std::optional<AInt>, AInt, AInt, AInt>;
using CheckedMaddTest_AInt = testing::TestWithParam<TernaryCheckedCase>;
diff --git a/src/tint/program_builder.h b/src/tint/program_builder.h
index d6d1f00..4677009 100644
--- a/src/tint/program_builder.h
+++ b/src/tint/program_builder.h
@@ -91,6 +91,7 @@
#include "src/tint/program.h"
#include "src/tint/program_id.h"
#include "src/tint/sem/array.h"
+#include "src/tint/sem/array_count.h"
#include "src/tint/sem/bool.h"
#include "src/tint/sem/constant.h"
#include "src/tint/sem/depth_texture.h"
@@ -457,7 +458,8 @@
/// @returns the node pointer
template <typename T, typename... ARGS>
traits::EnableIf<traits::IsTypeOrDerived<T, sem::Node> &&
- !traits::IsTypeOrDerived<T, sem::Type>,
+ !traits::IsTypeOrDerived<T, sem::Type> &&
+ !traits::IsTypeOrDerived<T, sem::ArrayCount>,
T>*
create(ARGS&&... args) {
AssertNotMoved();
@@ -476,17 +478,28 @@
/// Creates a new sem::Type owned by the ProgramBuilder.
/// When the ProgramBuilder is destructed, owned ProgramBuilder and the
- /// returned`Type` will also be destructed.
+ /// returned `Type` will also be destructed.
/// Types are unique (de-aliased), and so calling create() for the same `T`
/// and arguments will return the same pointer.
/// @param args the arguments to pass to the type constructor
/// @returns the de-aliased type pointer
template <typename T, typename... ARGS>
traits::EnableIfIsType<T, sem::Type>* create(ARGS&&... args) {
- static_assert(std::is_base_of<sem::Type, T>::value, "T does not derive from sem::Type");
AssertNotMoved();
return types_.Get<T>(std::forward<ARGS>(args)...);
}
+ /// Creates a new sem::ArrayCount owned by the ProgramBuilder.
+ /// When the ProgramBuilder is destructed, owned ProgramBuilder and the
+ /// returned `ArrayCount` will also be destructed.
+ /// ArrayCounts are unique (de-aliased), and so calling create() for the same `T`
+ /// and arguments will return the same pointer.
+ /// @param args the arguments to pass to the array count constructor
+ /// @returns the de-aliased array count pointer
+ template <typename T, typename... ARGS>
+ traits::EnableIfIsType<T, sem::ArrayCount>* create(ARGS&&... args) {
+ AssertNotMoved();
+ return types_.GetArrayCount<T>(std::forward<ARGS>(args)...);
+ }
/// Marks this builder as moved, preventing any further use of the builder.
void MarkAsMoved();
diff --git a/src/tint/reader/spirv/function_memory_test.cc b/src/tint/reader/spirv/function_memory_test.cc
index 66979ae..0ff9ba5 100644
--- a/src/tint/reader/spirv/function_memory_test.cc
+++ b/src/tint/reader/spirv/function_memory_test.cc
@@ -953,7 +953,9 @@
EXPECT_THAT(module_str, HasSubstr(R"(type RTArr = @stride(4) array<u32>;
struct S {
+ /* @offset(0) */
field0 : u32,
+ /* @offset(4) */
field1 : RTArr,
}
diff --git a/src/tint/reader/spirv/parser_impl_module_var_test.cc b/src/tint/reader/spirv/parser_impl_module_var_test.cc
index be931a6..7543792 100644
--- a/src/tint/reader/spirv/parser_impl_module_var_test.cc
+++ b/src/tint/reader/spirv/parser_impl_module_var_test.cc
@@ -1254,8 +1254,11 @@
EXPECT_THAT(module_str, HasSubstr(R"(type Arr = @stride(4) array<u32, 2u>;
struct S {
+ /* @offset(0) */
field0 : u32,
+ /* @offset(4) */
field1 : f32,
+ /* @offset(8) */
field2 : Arr,
}
@@ -1286,6 +1289,7 @@
EXPECT_TRUE(p->error().empty());
const auto module_str = test::ToString(p->program());
EXPECT_THAT(module_str, HasSubstr(R"(struct S {
+ /* @offset(0) */
field0 : mat3x2<f32>,
}
@@ -1316,6 +1320,7 @@
EXPECT_TRUE(p->error().empty());
const auto module_str = test::ToString(p->program());
EXPECT_THAT(module_str, HasSubstr(R"(struct S {
+ /* @offset(0) */
field0 : mat3x2<f32>,
}
@@ -1346,6 +1351,7 @@
EXPECT_TRUE(p->error().empty());
const auto module_str = test::ToString(p->program());
EXPECT_THAT(module_str, HasSubstr(R"(struct S {
+ /* @offset(0) */
@stride(64) @internal(disable_validation__ignore_stride)
field0 : mat3x2<f32>,
}
@@ -1399,7 +1405,9 @@
EXPECT_TRUE(p->error().empty());
const auto module_str = test::ToString(p->program());
EXPECT_THAT(module_str, HasSubstr(R"(struct S {
+ /* @offset(0) */
field0 : f32,
+ /* @offset(4) */
field1 : f32,
}
@@ -1428,7 +1436,9 @@
EXPECT_TRUE(p->error().empty());
const auto module_str = test::ToString(p->program());
EXPECT_THAT(module_str, HasSubstr(R"(struct S {
+ /* @offset(0) */
field0 : f32,
+ /* @offset(4) */
field1 : f32,
}
@@ -1459,7 +1469,9 @@
EXPECT_TRUE(p->error().empty());
const auto module_str = test::ToString(p->program());
EXPECT_THAT(module_str, HasSubstr(R"(struct S {
+ /* @offset(0) */
field0 : f32,
+ /* @offset(4) */
field1 : f32,
}
diff --git a/src/tint/reader/wgsl/parser_impl.cc b/src/tint/reader/wgsl/parser_impl.cc
index 49e266f..a04e548 100644
--- a/src/tint/reader/wgsl/parser_impl.cc
+++ b/src/tint/reader/wgsl/parser_impl.cc
@@ -43,6 +43,7 @@
#include "src/tint/sem/external_texture.h"
#include "src/tint/sem/multisampled_texture.h"
#include "src/tint/sem/sampled_texture.h"
+#include "src/tint/utils/reverse.h"
#include "src/tint/utils/string.h"
namespace tint::reader::wgsl {
@@ -3239,34 +3240,50 @@
return component_or_swizzle_specifier(core_expr.value);
}
- auto check_lhs = [&](ast::UnaryOp op) -> Maybe<const ast::Expression*> {
- auto& t = peek();
- auto expr = lhs_expression();
- if (expr.errored) {
- return Failure::kErrored;
- }
- if (!expr.matched) {
- return add_error(t, "missing expression");
- }
- return create<ast::UnaryOpExpression>(t.source(), op, expr.value);
+ // Gather up all the `*`, `&` and `&&` tokens into a list and create all of the unary ops at
+ // once instead of recursing. This handles the case where the fuzzer decides >8k `*`s would be
+ // fun.
+ struct LHSData {
+ Source source;
+ ast::UnaryOp op;
};
+ utils::Vector<LHSData, 4> ops;
+ while (true) {
+ auto& t = peek();
+ if (!t.Is(Token::Type::kAndAnd) && !t.Is(Token::Type::kAnd) && !t.Is(Token::Type::kStar)) {
+ break;
+ }
+ next(); // consume the peek
- // If an `&&` is encountered, split it into two `&`'s
- if (match(Token::Type::kAndAnd)) {
- // The first `&` is consumed as part of the `&&`, so this needs to run the check itself.
- split_token(Token::Type::kAnd, Token::Type::kAnd);
- return check_lhs(ast::UnaryOp::kAddressOf);
+ if (t.Is(Token::Type::kAndAnd)) {
+ // The first `&` is consumed as part of the `&&`, so we only push one of the two `&`s.
+ split_token(Token::Type::kAnd, Token::Type::kAnd);
+ ops.Push({t.source(), ast::UnaryOp::kAddressOf});
+ } else if (t.Is(Token::Type::kAnd)) {
+ ops.Push({t.source(), ast::UnaryOp::kAddressOf});
+ } else if (t.Is(Token::Type::kStar)) {
+ ops.Push({t.source(), ast::UnaryOp::kIndirection});
+ }
+ }
+ if (ops.IsEmpty()) {
+ return Failure::kNoMatch;
}
- if (match(Token::Type::kAnd)) {
- return check_lhs(ast::UnaryOp::kAddressOf);
+ auto& t = peek();
+ auto expr = lhs_expression();
+ if (expr.errored) {
+ return Failure::kErrored;
+ }
+ if (!expr.matched) {
+ return add_error(t, "missing expression");
}
- if (match(Token::Type::kStar)) {
- return check_lhs(ast::UnaryOp::kIndirection);
+ const ast::Expression* ret = expr.value;
+ // Consume the ops in reverse order so we have the correct AST ordering.
+ for (auto& info : utils::Reverse(ops)) {
+ ret = create<ast::UnaryOpExpression>(info.source, info.op, ret);
}
-
- return Failure::kNoMatch;
+ return ret;
}
// variable_updating_statement
diff --git a/src/tint/reader/wgsl/parser_impl_enable_directive_test.cc b/src/tint/reader/wgsl/parser_impl_enable_directive_test.cc
index aad8eb6..392f0dd 100644
--- a/src/tint/reader/wgsl/parser_impl_enable_directive_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_enable_directive_test.cc
@@ -62,7 +62,7 @@
// Error when unknown extension found
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension
-Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_push_constant', 'f16')");
+Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'f16')");
auto program = p->program();
auto& ast = program.AST();
EXPECT_EQ(ast.Enables().Length(), 0u);
@@ -75,7 +75,7 @@
// Error when unknown extension found
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension. Did you mean 'f16'?
-Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_push_constant', 'f16')");
+Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'f16')");
auto program = p->program();
auto& ast = program.AST();
EXPECT_EQ(ast.Enables().Length(), 0u);
@@ -123,7 +123,7 @@
p->translation_unit();
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension
-Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_push_constant', 'f16')");
+Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'f16')");
auto program = p->program();
auto& ast = program.AST();
EXPECT_EQ(ast.Enables().Length(), 0u);
@@ -134,7 +134,7 @@
p->translation_unit();
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension
-Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_push_constant', 'f16')");
+Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'f16')");
auto program = p->program();
auto& ast = program.AST();
EXPECT_EQ(ast.Enables().Length(), 0u);
@@ -145,7 +145,7 @@
p->translation_unit();
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension
-Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_push_constant', 'f16')");
+Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_push_constant', 'f16')");
auto program = p->program();
auto& ast = program.AST();
EXPECT_EQ(ast.Enables().Length(), 0u);
diff --git a/src/tint/reader/wgsl/parser_impl_lhs_expression_test.cc b/src/tint/reader/wgsl/parser_impl_lhs_expression_test.cc
index 4e1e0db..a8a476b 100644
--- a/src/tint/reader/wgsl/parser_impl_lhs_expression_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_lhs_expression_test.cc
@@ -75,17 +75,20 @@
}
TEST_F(ParserImplTest, LHSExpression_Multiple) {
- auto p = parser("*&**&&*a");
+ auto p = parser("*&********&&&&&&*a");
auto e = p->lhs_expression();
ASSERT_FALSE(p->has_error()) << p->error();
ASSERT_FALSE(e.errored);
EXPECT_TRUE(e.matched);
ASSERT_NE(e.value, nullptr);
- std::vector<ast::UnaryOp> results = {ast::UnaryOp::kIndirection, ast::UnaryOp::kAddressOf,
- ast::UnaryOp::kIndirection, ast::UnaryOp::kIndirection,
- ast::UnaryOp::kAddressOf, ast::UnaryOp::kAddressOf,
- ast::UnaryOp::kIndirection};
+ std::vector<ast::UnaryOp> results = {
+ ast::UnaryOp::kIndirection, ast::UnaryOp::kAddressOf, ast::UnaryOp::kIndirection,
+ ast::UnaryOp::kIndirection, ast::UnaryOp::kIndirection, ast::UnaryOp::kIndirection,
+ ast::UnaryOp::kIndirection, ast::UnaryOp::kIndirection, ast::UnaryOp::kIndirection,
+ ast::UnaryOp::kIndirection, ast::UnaryOp::kAddressOf, ast::UnaryOp::kAddressOf,
+ ast::UnaryOp::kAddressOf, ast::UnaryOp::kAddressOf, ast::UnaryOp::kAddressOf,
+ ast::UnaryOp::kAddressOf, ast::UnaryOp::kIndirection};
auto* expr = e.value;
for (auto op : results) {
diff --git a/src/tint/resolver/call_validation_test.cc b/src/tint/resolver/call_validation_test.cc
index 82037af..e94e7b8 100644
--- a/src/tint/resolver/call_validation_test.cc
+++ b/src/tint/resolver/call_validation_test.cc
@@ -114,11 +114,29 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
-TEST_F(ResolverCallValidationTest, PointerArgument_NotWholeVar) {
+TEST_F(ResolverCallValidationTest, PointerArgument_LetIdentExpr) {
+ // fn foo(p: ptr<function, i32>) {}
+ // fn main() {
+ // let z: i32 = 1i;
+ // foo(&z);
+ // }
+ auto* param = Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction));
+ Func("foo", utils::Vector{param}, ty.void_(), utils::Empty);
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Let("z", ty.i32(), Expr(1_i))),
+ CallStmt(Call("foo", AddressOf(Expr(Source{{12, 34}}, "z")))),
+ });
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: cannot take the address of expression");
+}
+
+TEST_F(ResolverCallValidationTest, PointerArgument_AddressOfFunctionMember) {
// struct S { m: i32; };
// fn foo(p: ptr<function, i32>) {}
// fn main() {
- // var v: S;
+ // var v : S;
// foo(&v.m);
// }
auto* S = Structure("S", utils::Vector{
@@ -138,6 +156,51 @@
"originating variable");
}
+TEST_F(ResolverCallValidationTest,
+ PointerArgument_AddressOfFunctionMember_WithFullPtrParametersExt) {
+ // enable chromium_experimental_full_ptr_parameters;
+ // struct S { m: i32; };
+ // fn foo(p: ptr<function, i32>) {}
+ // fn main() {
+ // var v : S;
+ // foo(&v.m);
+ // }
+ Enable(ast::Extension::kChromiumExperimentalFullPtrParameters);
+ auto* S = Structure("S", utils::Vector{
+ Member("m", ty.i32()),
+ });
+ auto* param = Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction));
+ Func("foo", utils::Vector{param}, ty.void_(), utils::Empty);
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Var("v", ty.Of(S))),
+ CallStmt(Call("foo", AddressOf(Source{{12, 34}}, MemberAccessor("v", "m")))),
+ });
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+}
+TEST_F(ResolverCallValidationTest, PointerArgument_AddressOfLetMember) {
+ // struct S { m: i32; };
+ // fn foo(p: ptr<function, i32>) {}
+ // fn main() {
+ // let v: S = S();
+ // foo(&v.m);
+ // }
+ auto* S = Structure("S", utils::Vector{
+ Member("m", ty.i32()),
+ });
+ auto* param = Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction));
+ Func("foo", utils::Vector{param}, ty.void_(), utils::Empty);
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Let("v", ty.Of(S), Construct(ty.Of(S)))),
+ CallStmt(Call("foo", AddressOf(MemberAccessor(Source{{12, 34}}, "v", "m")))),
+ });
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: cannot take the address of expression");
+}
+
TEST_F(ResolverCallValidationTest, PointerArgument_FunctionParam) {
// fn foo(p: ptr<function, i32>) {}
// fn bar(p: ptr<function, i32>) {
@@ -181,12 +244,12 @@
},
ty.void_(),
utils::Vector{
- CallStmt(Call("foo", Expr("p"))),
+ CallStmt(Call("foo", "p")),
});
Func("main", utils::Empty, ty.void_(),
utils::Vector{
Decl(Var("v", ty.i32(), Expr(1_i))),
- CallStmt(Call("foo", AddressOf(Expr("v")))),
+ CallStmt(Call("foo", AddressOf("v"))),
},
utils::Vector{
Stage(ast::PipelineStage::kFragment),
@@ -195,40 +258,15 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
-TEST_F(ResolverCallValidationTest, PointerArgument_FunctionParam_NotWholeVar) {
- // fn foo(p: ptr<function, i32>) {}
- // fn bar(p: ptr<function, array<i32, 4>>) {
- // foo(&(*p)[0]);
- // }
- Func("foo",
- utils::Vector{
- Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
- },
- ty.void_(), utils::Empty);
- Func("bar",
- utils::Vector{
- Param("p", ty.pointer(ty.array<i32, 4>(), ast::AddressSpace::kFunction)),
- },
- ty.void_(),
- utils::Vector{
- CallStmt(Call("foo", AddressOf(Source{{12, 34}}, IndexAccessor(Deref("p"), 0_a)))),
- });
-
- EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(),
- "12:34 error: arguments of pointer type must not point to a subset of the "
- "originating variable");
-}
-
TEST_F(ResolverCallValidationTest, LetPointer) {
// fn foo(p : ptr<function, i32>) {}
// @fragment
// fn main() {
// var v: i32;
// let p: ptr<function, i32> = &v;
- // foo(p);
+ // x(p);
// }
- Func("foo",
+ Func("x",
utils::Vector{
Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
},
@@ -237,7 +275,7 @@
utils::Vector{
Decl(Var("v", ty.i32())),
Decl(Let("p", ty.pointer(ty.i32(), ast::AddressSpace::kFunction), AddressOf("v"))),
- CallStmt(Call("foo", Expr(Source{{12, 34}}, "p"))),
+ CallStmt(Call("x", "p")),
},
utils::Vector{
Stage(ast::PipelineStage::kFragment),
@@ -247,10 +285,10 @@
TEST_F(ResolverCallValidationTest, LetPointerPrivate) {
// fn foo(p : ptr<private, i32>) {}
- // var<private> v: i32;
+ // var v : i32;
// @fragment
// fn main() {
- // let p: ptr<private, i32> = &v;
+ // let p : ptr<private, i32> = &v;
// foo(p);
// }
Func("foo",
@@ -299,6 +337,34 @@
"originating variable");
}
+TEST_F(ResolverCallValidationTest, LetPointer_NotWholeVar_WithFullPtrParametersExt) {
+ // enable chromium_experimental_full_ptr_parameters;
+ // fn foo(p : ptr<function, i32>) {}
+ // @fragment
+ // fn main() {
+ // var v: array<i32, 4>;
+ // let p: ptr<function, i32> = &(v[0]);
+ // x(p);
+ // }
+ Enable(ast::Extension::kChromiumExperimentalFullPtrParameters);
+ Func("foo",
+ utils::Vector{
+ Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
+ },
+ ty.void_(), utils::Empty);
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Var("v", ty.array<i32, 4>())),
+ Decl(Let("p", ty.pointer(ty.i32(), ast::AddressSpace::kFunction),
+ AddressOf(IndexAccessor("v", 0_a)))),
+ CallStmt(Call("foo", Expr(Source{{12, 34}}, "p"))),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
+ EXPECT_TRUE(r()->Resolve());
+}
+
TEST_F(ResolverCallValidationTest, ComplexPointerChain) {
// fn foo(p : ptr<function, array<i32, 4>>) {}
// @fragment
@@ -360,6 +426,37 @@
"originating variable");
}
+TEST_F(ResolverCallValidationTest, ComplexPointerChain_NotWholeVar_WithFullPtrParametersExt) {
+ // enable chromium_experimental_full_ptr_parameters;
+ // fn foo(p : ptr<function, i32>) {}
+ // @fragment
+ // fn main() {
+ // var v: array<i32, 4>;
+ // let p1 = &v;
+ // let p2 = p1;
+ // let p3 = &(*p2)[0];
+ // foo(&*p);
+ // }
+ Enable(ast::Extension::kChromiumExperimentalFullPtrParameters);
+ Func("foo",
+ utils::Vector{
+ Param("p", ty.pointer<i32>(ast::AddressSpace::kFunction)),
+ },
+ ty.void_(), utils::Empty);
+ Func("main", utils::Empty, ty.void_(),
+ utils::Vector{
+ Decl(Var("v", ty.array<i32, 4>())),
+ Decl(Let("p1", AddressOf("v"))),
+ Decl(Let("p2", Expr("p1"))),
+ Decl(Let("p3", AddressOf(IndexAccessor(Deref("p2"), 0_a)))),
+ CallStmt(Call("foo", AddressOf(Source{{12, 34}}, Deref("p3")))),
+ },
+ utils::Vector{
+ Stage(ast::PipelineStage::kFragment),
+ });
+ EXPECT_TRUE(r()->Resolve());
+}
+
TEST_F(ResolverCallValidationTest, CallVariable) {
// var v : i32;
// fn f() {
diff --git a/src/tint/resolver/const_eval.cc b/src/tint/resolver/const_eval.cc
index 7195824..8170adb 100644
--- a/src/tint/resolver/const_eval.cc
+++ b/src/tint/resolver/const_eval.cc
@@ -744,7 +744,6 @@
using T = UnwrapNumber<NumberT>;
NumberT result;
if constexpr (IsAbstract<NumberT> || IsFloatingPoint<NumberT>) {
- // Check for over/underflow for abstract values
if (auto r = CheckedMul(a, b)) {
result = r->value;
} else {
@@ -770,7 +769,6 @@
utils::Result<NumberT> ConstEval::Div(const Source& source, NumberT a, NumberT b) {
NumberT result;
if constexpr (IsAbstract<NumberT> || IsFloatingPoint<NumberT>) {
- // Check for over/underflow for abstract values
if (auto r = CheckedDiv(a, b)) {
result = r->value;
} else {
@@ -800,6 +798,38 @@
}
template <typename NumberT>
+utils::Result<NumberT> ConstEval::Mod(const Source& source, NumberT a, NumberT b) {
+ NumberT result;
+ if constexpr (IsAbstract<NumberT> || IsFloatingPoint<NumberT>) {
+ if (auto r = CheckedMod(a, b)) {
+ result = r->value;
+ } else {
+ AddError(OverflowErrorMessage(a, "%", b), source);
+ return utils::Failure;
+ }
+ } else {
+ using T = UnwrapNumber<NumberT>;
+ auto lhs = a.value;
+ auto rhs = b.value;
+ if (rhs == 0) {
+ // lhs % 0 is an error
+ AddError(OverflowErrorMessage(a, "%", b), source);
+ return utils::Failure;
+ }
+ if constexpr (std::is_signed_v<T>) {
+ // For signed integers, lhs % -1 where lhs is the
+ // most negative value is an error
+ if (rhs == -1 && lhs == std::numeric_limits<T>::min()) {
+ AddError(OverflowErrorMessage(a, "%", b), source);
+ return utils::Failure;
+ }
+ }
+ result = lhs % rhs;
+ }
+ return result;
+}
+
+template <typename NumberT>
utils::Result<NumberT> ConstEval::Dot2(const Source& source,
NumberT a1,
NumberT a2,
@@ -1111,6 +1141,15 @@
};
}
+auto ConstEval::ModFunc(const Source& source, const sem::Type* elem_ty) {
+ return [=](auto a1, auto a2) -> ImplResult {
+ if (auto r = Mod(source, a1, a2)) {
+ return CreateElement(builder, source, elem_ty, r.Get());
+ }
+ return utils::Failure;
+ };
+}
+
auto ConstEval::Dot2Func(const Source& source, const sem::Type* elem_ty) {
return [=](auto a1, auto a2, auto b1, auto b2) -> ImplResult {
if (auto r = Dot2(source, a1, a2, b1, b2)) {
@@ -1683,6 +1722,16 @@
return TransformBinaryElements(builder, ty, transform, args[0], args[1]);
}
+ConstEval::Result ConstEval::OpModulo(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source) {
+ auto transform = [&](const sem::Constant* c0, const sem::Constant* c1) {
+ return Dispatch_fia_fiu32_f16(ModFunc(source, c0->Type()), c0, c1);
+ };
+
+ return TransformBinaryElements(builder, ty, transform, args[0], args[1]);
+}
+
ConstEval::Result ConstEval::OpEqual(const sem::Type* ty,
utils::VectorRef<const sem::Constant*> args,
const Source& source) {
diff --git a/src/tint/resolver/const_eval.h b/src/tint/resolver/const_eval.h
index d92dc3f..9905036 100644
--- a/src/tint/resolver/const_eval.h
+++ b/src/tint/resolver/const_eval.h
@@ -283,6 +283,15 @@
utils::VectorRef<const sem::Constant*> args,
const Source& source);
+ /// Modulo operator '%'
+ /// @param ty the expression type
+ /// @param args the input arguments
+ /// @param source the source location
+ /// @return the result value, or null if the value cannot be calculated
+ Result OpModulo(const sem::Type* ty,
+ utils::VectorRef<const sem::Constant*> args,
+ const Source& source);
+
/// Equality operator '=='
/// @param ty the expression type
/// @param args the input arguments
@@ -1040,6 +1049,14 @@
template <typename NumberT>
utils::Result<NumberT> Div(const Source& source, NumberT a, NumberT b);
+ /// Returns the (signed) remainder of the division of two Number<T>s
+ /// @param source the source location
+ /// @param a the lhs number
+ /// @param b the rhs number
+ /// @returns the result number on success, or logs an error and returns Failure
+ template <typename NumberT>
+ utils::Result<NumberT> Mod(const Source& source, NumberT a, NumberT b);
+
/// Returns the dot product of (a1,a2) with (b1,b2)
/// @param source the source location
/// @param a1 component 1 of lhs vector
@@ -1216,6 +1233,13 @@
/// @returns the callable function
auto DivFunc(const Source& source, const sem::Type* elem_ty);
+ /// Returns a callable that calls Mod, and creates a Constant with its result of type `elem_ty`
+ /// if successful, or returns Failure otherwise.
+ /// @param source the source location
+ /// @param elem_ty the element type of the Constant to create on success
+ /// @returns the callable function
+ auto ModFunc(const Source& source, const sem::Type* elem_ty);
+
/// Returns a callable that calls Dot2, and creates a Constant with its result of type `elem_ty`
/// if successful, or returns Failure otherwise.
/// @param source the source location
diff --git a/src/tint/resolver/const_eval_binary_op_test.cc b/src/tint/resolver/const_eval_binary_op_test.cc
index 2a13360..2590466 100644
--- a/src/tint/resolver/const_eval_binary_op_test.cc
+++ b/src/tint/resolver/const_eval_binary_op_test.cc
@@ -485,6 +485,161 @@
OpDivFloatCases<f32>(),
OpDivFloatCases<f16>()))));
+template <typename T>
+std::vector<Case> OpModCases() {
+ auto error_msg = [](auto a, auto b) {
+ return "12:34 error: " + OverflowErrorMessage(a, "%", b);
+ };
+
+ // Common cases for all types
+ std::vector<Case> r = {
+ C(T{0}, T{1}, T{0}), //
+ C(T{1}, T{1}, T{0}), //
+ C(T{10}, T{1}, T{0}), //
+ C(T{10}, T{2}, T{0}), //
+ C(T{10}, T{3}, T{1}), //
+ C(T{10}, T{4}, T{2}), //
+ C(T{10}, T{5}, T{0}), //
+ C(T{10}, T{6}, T{4}), //
+ C(T{10}, T{5}, T{0}), //
+ C(T{10}, T{8}, T{2}), //
+ C(T{10}, T{9}, T{1}), //
+ C(T{10}, T{10}, T{0}), //
+
+ // Error on divide by zero
+ E(T{123}, T{0}, error_msg(T{123}, T{0})),
+ E(T::Highest(), T{0}, error_msg(T::Highest(), T{0})),
+ E(T::Lowest(), T{0}, error_msg(T::Lowest(), T{0})),
+ };
+
+ if constexpr (IsIntegral<T>) {
+ ConcatInto( //
+ r, std::vector<Case>{
+ C(T::Highest(), T{T::Highest() - T{1}}, T{1}),
+ });
+ }
+
+ if constexpr (IsSignedIntegral<T>) {
+ ConcatInto( //
+ r, std::vector<Case>{
+ C(T::Lowest(), T{T::Lowest() + T{1}}, -T(1)),
+
+ // Error on most negative integer divided by -1
+ E(T::Lowest(), T{-1}, error_msg(T::Lowest(), T{-1})),
+ });
+ }
+
+ // Negative values (both signed integrals and floating point)
+ if constexpr (IsSignedIntegral<T> || IsFloatingPoint<T>) {
+ ConcatInto( //
+ r, std::vector<Case>{
+ C(-T{1}, T{1}, T{0}), //
+
+ // lhs negative, rhs positive
+ C(-T{10}, T{1}, T{0}), //
+ C(-T{10}, T{2}, T{0}), //
+ C(-T{10}, T{3}, -T{1}), //
+ C(-T{10}, T{4}, -T{2}), //
+ C(-T{10}, T{5}, T{0}), //
+ C(-T{10}, T{6}, -T{4}), //
+ C(-T{10}, T{5}, T{0}), //
+ C(-T{10}, T{8}, -T{2}), //
+ C(-T{10}, T{9}, -T{1}), //
+ C(-T{10}, T{10}, T{0}), //
+
+ // lhs positive, rhs negative
+ C(T{10}, -T{1}, T{0}), //
+ C(T{10}, -T{2}, T{0}), //
+ C(T{10}, -T{3}, T{1}), //
+ C(T{10}, -T{4}, T{2}), //
+ C(T{10}, -T{5}, T{0}), //
+ C(T{10}, -T{6}, T{4}), //
+ C(T{10}, -T{5}, T{0}), //
+ C(T{10}, -T{8}, T{2}), //
+ C(T{10}, -T{9}, T{1}), //
+ C(T{10}, -T{10}, T{0}), //
+
+ // lhs negative, rhs negative
+ C(-T{10}, -T{1}, T{0}), //
+ C(-T{10}, -T{2}, T{0}), //
+ C(-T{10}, -T{3}, -T{1}), //
+ C(-T{10}, -T{4}, -T{2}), //
+ C(-T{10}, -T{5}, T{0}), //
+ C(-T{10}, -T{6}, -T{4}), //
+ C(-T{10}, -T{5}, T{0}), //
+ C(-T{10}, -T{8}, -T{2}), //
+ C(-T{10}, -T{9}, -T{1}), //
+ C(-T{10}, -T{10}, T{0}), //
+ });
+ }
+
+ // Float values
+ if constexpr (IsFloatingPoint<T>) {
+ ConcatInto( //
+ r, std::vector<Case>{
+ C(T{10.5}, T{1}, T{0.5}), //
+ C(T{10.5}, T{2}, T{0.5}), //
+ C(T{10.5}, T{3}, T{1.5}), //
+ C(T{10.5}, T{4}, T{2.5}), //
+ C(T{10.5}, T{5}, T{0.5}), //
+ C(T{10.5}, T{6}, T{4.5}), //
+ C(T{10.5}, T{5}, T{0.5}), //
+ C(T{10.5}, T{8}, T{2.5}), //
+ C(T{10.5}, T{9}, T{1.5}), //
+ C(T{10.5}, T{10}, T{0.5}), //
+
+ // lhs negative, rhs positive
+ C(-T{10.5}, T{1}, -T{0.5}), //
+ C(-T{10.5}, T{2}, -T{0.5}), //
+ C(-T{10.5}, T{3}, -T{1.5}), //
+ C(-T{10.5}, T{4}, -T{2.5}), //
+ C(-T{10.5}, T{5}, -T{0.5}), //
+ C(-T{10.5}, T{6}, -T{4.5}), //
+ C(-T{10.5}, T{5}, -T{0.5}), //
+ C(-T{10.5}, T{8}, -T{2.5}), //
+ C(-T{10.5}, T{9}, -T{1.5}), //
+ C(-T{10.5}, T{10}, -T{0.5}), //
+
+ // lhs positive, rhs negative
+ C(T{10.5}, -T{1}, T{0.5}), //
+ C(T{10.5}, -T{2}, T{0.5}), //
+ C(T{10.5}, -T{3}, T{1.5}), //
+ C(T{10.5}, -T{4}, T{2.5}), //
+ C(T{10.5}, -T{5}, T{0.5}), //
+ C(T{10.5}, -T{6}, T{4.5}), //
+ C(T{10.5}, -T{5}, T{0.5}), //
+ C(T{10.5}, -T{8}, T{2.5}), //
+ C(T{10.5}, -T{9}, T{1.5}), //
+ C(T{10.5}, -T{10}, T{0.5}), //
+
+ // lhs negative, rhs negative
+ C(-T{10.5}, -T{1}, -T{0.5}), //
+ C(-T{10.5}, -T{2}, -T{0.5}), //
+ C(-T{10.5}, -T{3}, -T{1.5}), //
+ C(-T{10.5}, -T{4}, -T{2.5}), //
+ C(-T{10.5}, -T{5}, -T{0.5}), //
+ C(-T{10.5}, -T{6}, -T{4.5}), //
+ C(-T{10.5}, -T{5}, -T{0.5}), //
+ C(-T{10.5}, -T{8}, -T{2.5}), //
+ C(-T{10.5}, -T{9}, -T{1.5}), //
+ C(-T{10.5}, -T{10}, -T{0.5}), //
+ });
+ }
+
+ return r;
+}
+INSTANTIATE_TEST_SUITE_P(Mod,
+ ResolverConstEvalBinaryOpTest,
+ testing::Combine( //
+ testing::Values(ast::BinaryOp::kModulo),
+ testing::ValuesIn(Concat( //
+ OpModCases<AInt>(),
+ OpModCases<i32>(),
+ OpModCases<u32>(),
+ OpModCases<AFloat>(),
+ OpModCases<f32>(),
+ OpModCases<f16>()))));
+
template <typename T, bool equals>
std::vector<Case> OpEqualCases() {
return {
diff --git a/src/tint/resolver/const_eval_construction_test.cc b/src/tint/resolver/const_eval_construction_test.cc
index 9df9807..cabc4ab 100644
--- a/src/tint/resolver/const_eval_construction_test.cc
+++ b/src/tint/resolver/const_eval_construction_test.cc
@@ -1321,7 +1321,6 @@
auto* arr = sem->Type()->As<sem::Array>();
ASSERT_NE(arr, nullptr);
EXPECT_TRUE(arr->ElemType()->Is<sem::I32>());
- EXPECT_EQ(arr->Count(), sem::ConstantArrayCount{4u});
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue()->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->AnyZero());
@@ -1359,7 +1358,6 @@
auto* arr = sem->Type()->As<sem::Array>();
ASSERT_NE(arr, nullptr);
EXPECT_TRUE(arr->ElemType()->Is<sem::F32>());
- EXPECT_EQ(arr->Count(), sem::ConstantArrayCount{4u});
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue()->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->AnyZero());
@@ -1397,7 +1395,6 @@
auto* arr = sem->Type()->As<sem::Array>();
ASSERT_NE(arr, nullptr);
EXPECT_TRUE(arr->ElemType()->Is<sem::Vector>());
- EXPECT_EQ(arr->Count(), sem::ConstantArrayCount{2u});
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue()->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->AnyZero());
@@ -1449,7 +1446,6 @@
auto* arr = sem->Type()->As<sem::Array>();
ASSERT_NE(arr, nullptr);
EXPECT_TRUE(arr->ElemType()->Is<sem::Struct>());
- EXPECT_EQ(arr->Count(), sem::ConstantArrayCount{2u});
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
EXPECT_TRUE(sem->ConstantValue()->AllEqual());
EXPECT_TRUE(sem->ConstantValue()->AnyZero());
@@ -1487,7 +1483,6 @@
auto* arr = sem->Type()->As<sem::Array>();
ASSERT_NE(arr, nullptr);
EXPECT_TRUE(arr->ElemType()->Is<sem::I32>());
- EXPECT_EQ(arr->Count(), sem::ConstantArrayCount{4u});
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
EXPECT_FALSE(sem->ConstantValue()->AllEqual());
EXPECT_FALSE(sem->ConstantValue()->AnyZero());
@@ -1525,7 +1520,6 @@
auto* arr = sem->Type()->As<sem::Array>();
ASSERT_NE(arr, nullptr);
EXPECT_TRUE(arr->ElemType()->Is<sem::F32>());
- EXPECT_EQ(arr->Count(), sem::ConstantArrayCount{4u});
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
EXPECT_FALSE(sem->ConstantValue()->AllEqual());
EXPECT_FALSE(sem->ConstantValue()->AnyZero());
@@ -1564,7 +1558,6 @@
auto* arr = sem->Type()->As<sem::Array>();
ASSERT_NE(arr, nullptr);
EXPECT_TRUE(arr->ElemType()->Is<sem::Vector>());
- EXPECT_EQ(arr->Count(), sem::ConstantArrayCount{2u});
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
EXPECT_FALSE(sem->ConstantValue()->AllEqual());
EXPECT_FALSE(sem->ConstantValue()->AnyZero());
@@ -1594,7 +1587,6 @@
auto* arr = sem->Type()->As<sem::Array>();
ASSERT_NE(arr, nullptr);
EXPECT_TRUE(arr->ElemType()->Is<sem::Struct>());
- EXPECT_EQ(arr->Count(), sem::ConstantArrayCount{2u});
EXPECT_TYPE(sem->ConstantValue()->Type(), sem->Type());
EXPECT_FALSE(sem->ConstantValue()->AllEqual());
EXPECT_FALSE(sem->ConstantValue()->AnyZero());
diff --git a/src/tint/resolver/dependency_graph.cc b/src/tint/resolver/dependency_graph.cc
index 796412b..29f88a7 100644
--- a/src/tint/resolver/dependency_graph.cc
+++ b/src/tint/resolver/dependency_graph.cc
@@ -66,6 +66,7 @@
#include "src/tint/ast/void.h"
#include "src/tint/ast/while_statement.h"
#include "src/tint/ast/workgroup_attribute.h"
+#include "src/tint/resolver/type_alias.h"
#include "src/tint/scope_stack.h"
#include "src/tint/sem/builtin.h"
#include "src/tint/symbol_table.h"
@@ -481,9 +482,14 @@
graph_.resolved_symbols.Add(from, resolved);
}
- /// @returns true if `name` is the name of a builtin function
+ /// @returns true if `name` is the name of a builtin function, or builtin type alias
bool IsBuiltin(Symbol name) const {
- return sem::ParseBuiltinType(symbols_.NameFor(name)) != sem::BuiltinType::kNone;
+ auto s = symbols_.NameFor(name);
+ if (sem::ParseBuiltinType(s) != sem::BuiltinType::kNone ||
+ ParseTypeAlias(s) != TypeAlias::kUndefined) {
+ return true;
+ }
+ return false;
}
/// Appends an error to the diagnostics that the given symbol cannot be
diff --git a/src/tint/resolver/function_validation_test.cc b/src/tint/resolver/function_validation_test.cc
index 808f556..922a1dc 100644
--- a/src/tint/resolver/function_validation_test.cc
+++ b/src/tint/resolver/function_validation_test.cc
@@ -1041,21 +1041,26 @@
EXPECT_EQ(r()->error(), "12:34 error: missing matrix element type");
}
+enum class Expectation {
+ kAlwaysPass,
+ kPassWithFullPtrParameterExtension,
+ kAlwaysFail,
+};
struct TestParams {
ast::AddressSpace address_space;
- bool should_pass;
+ Expectation expectation;
};
struct TestWithParams : ResolverTestWithParam<TestParams> {};
using ResolverFunctionParameterValidationTest = TestWithParams;
-TEST_P(ResolverFunctionParameterValidationTest, AddressSpace) {
+TEST_P(ResolverFunctionParameterValidationTest, AddressSpaceNoExtension) {
auto& param = GetParam();
auto* ptr_type = ty.pointer(Source{{12, 34}}, ty.i32(), param.address_space);
auto* arg = Param(Source{{12, 34}}, "p", ptr_type);
Func("f", utils::Vector{arg}, ty.void_(), utils::Empty);
- if (param.should_pass) {
+ if (param.expectation == Expectation::kAlwaysPass) {
ASSERT_TRUE(r()->Resolve()) << r()->error();
} else {
std::stringstream ss;
@@ -1065,17 +1070,36 @@
ss.str() + "' address space");
}
}
-INSTANTIATE_TEST_SUITE_P(ResolverTest,
- ResolverFunctionParameterValidationTest,
- testing::Values(TestParams{ast::AddressSpace::kNone, false},
- TestParams{ast::AddressSpace::kIn, false},
- TestParams{ast::AddressSpace::kOut, false},
- TestParams{ast::AddressSpace::kUniform, false},
- TestParams{ast::AddressSpace::kWorkgroup, false},
- TestParams{ast::AddressSpace::kHandle, false},
- TestParams{ast::AddressSpace::kStorage, false},
- TestParams{ast::AddressSpace::kPrivate, true},
- TestParams{ast::AddressSpace::kFunction, true}));
+TEST_P(ResolverFunctionParameterValidationTest, AddressSpaceWithExtension) {
+ auto& param = GetParam();
+ auto* ptr_type = ty.pointer(Source{{12, 34}}, ty.i32(), param.address_space);
+ auto* arg = Param(Source{{12, 34}}, "p", ptr_type);
+ Enable(ast::Extension::kChromiumExperimentalFullPtrParameters);
+ Func("f", utils::Vector{arg}, ty.void_(), utils::Empty);
+
+ if (param.expectation != Expectation::kAlwaysFail) {
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+ } else {
+ std::stringstream ss;
+ ss << param.address_space;
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: function parameter of pointer type cannot be in '" +
+ ss.str() + "' address space");
+ }
+}
+INSTANTIATE_TEST_SUITE_P(
+ ResolverTest,
+ ResolverFunctionParameterValidationTest,
+ testing::Values(
+ TestParams{ast::AddressSpace::kNone, Expectation::kAlwaysFail},
+ TestParams{ast::AddressSpace::kIn, Expectation::kAlwaysFail},
+ TestParams{ast::AddressSpace::kOut, Expectation::kAlwaysFail},
+ TestParams{ast::AddressSpace::kUniform, Expectation::kPassWithFullPtrParameterExtension},
+ TestParams{ast::AddressSpace::kWorkgroup, Expectation::kPassWithFullPtrParameterExtension},
+ TestParams{ast::AddressSpace::kHandle, Expectation::kAlwaysFail},
+ TestParams{ast::AddressSpace::kStorage, Expectation::kPassWithFullPtrParameterExtension},
+ TestParams{ast::AddressSpace::kPrivate, Expectation::kAlwaysPass},
+ TestParams{ast::AddressSpace::kFunction, Expectation::kAlwaysPass}));
} // namespace
} // namespace tint::resolver
diff --git a/src/tint/resolver/inferred_type_test.cc b/src/tint/resolver/inferred_type_test.cc
index d2f649b..ddbc8f8 100644
--- a/src/tint/resolver/inferred_type_test.cc
+++ b/src/tint/resolver/inferred_type_test.cc
@@ -135,8 +135,8 @@
TEST_F(ResolverInferredTypeTest, InferArray_Pass) {
auto* type = ty.array(ty.u32(), 10_u);
- auto* expected_type =
- create<sem::Array>(create<sem::U32>(), sem::ConstantArrayCount{10u}, 4u, 4u * 10u, 4u, 4u);
+ auto* expected_type = create<sem::Array>(
+ create<sem::U32>(), create<sem::ConstantArrayCount>(10u), 4u, 4u * 10u, 4u, 4u);
auto* ctor_expr = Construct(type);
auto* var = Var("a", ast::AddressSpace::kFunction, ctor_expr);
@@ -150,11 +150,12 @@
auto* member = Member("x", ty.i32());
auto* str = Structure("S", utils::Vector{member});
- auto* expected_type = create<sem::Struct>(
- str, str->name,
- sem::StructMemberList{create<sem::StructMember>(member, member->symbol, create<sem::I32>(),
- 0u, 0u, 0u, 4u, std::nullopt)},
- 0u, 4u, 4u);
+ auto* expected_type =
+ create<sem::Struct>(str, str->source, str->name,
+ sem::StructMemberList{create<sem::StructMember>(
+ member, member->source, member->symbol, create<sem::I32>(), 0u, 0u,
+ 0u, 4u, std::nullopt)},
+ 0u, 4u, 4u);
auto* ctor_expr = Construct(ty.Of(str));
diff --git a/src/tint/resolver/intrinsic_table.cc b/src/tint/resolver/intrinsic_table.cc
index a04eca4..ebd5043 100644
--- a/src/tint/resolver/intrinsic_table.cc
+++ b/src/tint/resolver/intrinsic_table.cc
@@ -523,7 +523,7 @@
}
if (auto* a = ty->As<sem::Array>()) {
- if (a->IsRuntimeSized()) {
+ if (a->Count()->Is<sem::RuntimeArrayCount>()) {
T = a->ElemType();
return true;
}
@@ -532,12 +532,13 @@
}
const sem::Array* build_array(MatchState& state, const sem::Type* el) {
- return state.builder.create<sem::Array>(el,
- /* count */ sem::RuntimeArrayCount{},
- /* align */ 0u,
- /* size */ 0u,
- /* stride */ 0u,
- /* stride_implicit */ 0u);
+ return state.builder.create<sem::Array>(
+ el,
+ /* count */ state.builder.create<sem::RuntimeArrayCount>(),
+ /* align */ 0u,
+ /* size */ 0u,
+ /* stride */ 0u,
+ /* stride_implicit */ 0u);
}
bool match_ptr(MatchState&, const sem::Type* ty, Number& S, const sem::Type*& T, Number& A) {
@@ -809,6 +810,7 @@
max_align = std::max(max_align, align);
members.emplace_back(b.create<sem::StructMember>(
/* declaration */ nullptr,
+ /* source */ Source{},
/* name */ b.Sym(m.name),
/* type */ m.type,
/* index */ static_cast<uint32_t>(members.size()),
@@ -822,6 +824,7 @@
uint32_t size_with_padding = utils::RoundUp(max_align, offset);
return b.create<sem::Struct>(
/* declaration */ nullptr,
+ /* source */ Source{},
/* name */ b.Sym(name),
/* members */ members,
/* align */ max_align,
diff --git a/src/tint/resolver/intrinsic_table.inl b/src/tint/resolver/intrinsic_table.inl
index d0752da..00b7557 100644
--- a/src/tint/resolver/intrinsic_table.inl
+++ b/src/tint/resolver/intrinsic_table.inl
@@ -6900,23 +6900,23 @@
},
{
/* [782] */
- /* usage */ ParameterUsage::kNone,
+ /* usage */ ParameterUsage::kX,
/* matcher indices */ &kMatcherIndices[3],
},
{
/* [783] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[101],
+ /* usage */ ParameterUsage::kY,
+ /* matcher indices */ &kMatcherIndices[3],
},
{
/* [784] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* usage */ ParameterUsage::kXy,
+ /* matcher indices */ &kMatcherIndices[150],
},
{
/* [785] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[99],
+ /* usage */ ParameterUsage::kZ,
+ /* matcher indices */ &kMatcherIndices[3],
},
{
/* [786] */
@@ -6925,8 +6925,8 @@
},
{
/* [787] */
- /* usage */ ParameterUsage::kY,
- /* matcher indices */ &kMatcherIndices[3],
+ /* usage */ ParameterUsage::kYz,
+ /* matcher indices */ &kMatcherIndices[150],
},
{
/* [788] */
@@ -6935,78 +6935,78 @@
},
{
/* [789] */
- /* usage */ ParameterUsage::kZ,
- /* matcher indices */ &kMatcherIndices[3],
- },
- {
- /* [790] */
- /* usage */ ParameterUsage::kX,
- /* matcher indices */ &kMatcherIndices[3],
- },
- {
- /* [791] */
- /* usage */ ParameterUsage::kYz,
- /* matcher indices */ &kMatcherIndices[150],
- },
- {
- /* [792] */
- /* usage */ ParameterUsage::kXy,
- /* matcher indices */ &kMatcherIndices[150],
- },
- {
- /* [793] */
/* usage */ ParameterUsage::kZw,
/* matcher indices */ &kMatcherIndices[150],
},
{
- /* [794] */
+ /* [790] */
/* usage */ ParameterUsage::kXyz,
/* matcher indices */ &kMatcherIndices[102],
},
{
- /* [795] */
+ /* [791] */
/* usage */ ParameterUsage::kW,
/* matcher indices */ &kMatcherIndices[3],
},
{
- /* [796] */
+ /* [792] */
/* usage */ ParameterUsage::kX,
/* matcher indices */ &kMatcherIndices[3],
},
{
- /* [797] */
+ /* [793] */
/* usage */ ParameterUsage::kZyw,
/* matcher indices */ &kMatcherIndices[102],
},
{
+ /* [794] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[150],
+ },
+ {
+ /* [795] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[150],
+ },
+ {
+ /* [796] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[102],
+ },
+ {
+ /* [797] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[102],
+ },
+ {
/* [798] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[150],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [799] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[150],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [800] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[3],
},
{
/* [801] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [802] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[130],
+ /* matcher indices */ &kMatcherIndices[3],
},
{
/* [803] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[130],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [804] */
@@ -7021,47 +7021,47 @@
{
/* [806] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[35],
},
{
/* [807] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[33],
},
{
/* [808] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[35],
},
{
/* [809] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[33],
},
{
/* [810] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[35],
+ /* matcher indices */ &kMatcherIndices[0],
},
{
/* [811] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[33],
+ /* matcher indices */ &kMatcherIndices[3],
},
{
/* [812] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[35],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [813] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[33],
+ /* matcher indices */ &kMatcherIndices[3],
},
{
/* [814] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[0],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [815] */
@@ -7156,27 +7156,27 @@
{
/* [833] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[10],
},
{
/* [834] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [835] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[36],
},
{
/* [836] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [837] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[10],
+ /* matcher indices */ &kMatcherIndices[36],
},
{
/* [838] */
@@ -7221,22 +7221,22 @@
{
/* [846] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[3],
},
{
/* [847] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[36],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [848] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[3],
},
{
/* [849] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[36],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [850] */
@@ -7291,22 +7291,22 @@
{
/* [860] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [861] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[36],
},
{
/* [862] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [863] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[36],
},
{
/* [864] */
@@ -7321,22 +7321,22 @@
{
/* [866] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[3],
},
{
/* [867] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[36],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [868] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[3],
},
{
/* [869] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[36],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [870] */
@@ -7371,62 +7371,62 @@
{
/* [876] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [877] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [878] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [879] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[108],
},
{
/* [880] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[110],
},
{
/* [881] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[108],
+ /* matcher indices */ &kMatcherIndices[110],
},
{
/* [882] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[108],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [883] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[108],
+ /* matcher indices */ &kMatcherIndices[36],
},
{
/* [884] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[110],
+ /* matcher indices */ &kMatcherIndices[3],
},
{
/* [885] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[110],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [886] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[3],
},
{
/* [887] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[36],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [888] */
@@ -7511,37 +7511,37 @@
{
/* [904] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[14],
},
{
/* [905] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[3],
},
{
/* [906] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[30],
},
{
/* [907] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[101],
},
{
/* [908] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[14],
+ /* matcher indices */ &kMatcherIndices[101],
},
{
/* [909] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[101],
},
{
/* [910] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[101],
},
{
/* [911] */
@@ -7550,238 +7550,238 @@
},
{
/* [912] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[101],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [913] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[101],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[114],
},
{
/* [914] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[101],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[118],
},
{
/* [915] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[101],
+ /* usage */ ParameterUsage::kTexture,
+ /* matcher indices */ &kMatcherIndices[120],
},
{
/* [916] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[112],
+ /* matcher indices */ &kMatcherIndices[124],
},
{
/* [917] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[114],
+ /* matcher indices */ &kMatcherIndices[126],
},
{
/* [918] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[118],
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [919] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[120],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [920] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [921] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[126],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [922] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[128],
+ /* matcher indices */ &kMatcherIndices[233],
},
{
/* [923] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[230],
+ /* matcher indices */ &kMatcherIndices[234],
},
{
/* [924] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[231],
+ /* matcher indices */ &kMatcherIndices[48],
},
{
/* [925] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[232],
+ /* matcher indices */ &kMatcherIndices[51],
},
{
/* [926] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[233],
+ /* matcher indices */ &kMatcherIndices[54],
},
{
/* [927] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[234],
+ /* matcher indices */ &kMatcherIndices[57],
},
{
/* [928] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[48],
+ /* matcher indices */ &kMatcherIndices[235],
},
{
/* [929] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[51],
+ /* matcher indices */ &kMatcherIndices[118],
},
{
/* [930] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[54],
+ /* matcher indices */ &kMatcherIndices[126],
},
{
/* [931] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[57],
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [932] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[235],
+ /* matcher indices */ &kMatcherIndices[233],
},
{
/* [933] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[118],
+ /* matcher indices */ &kMatcherIndices[54],
},
{
/* [934] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[126],
+ /* matcher indices */ &kMatcherIndices[112],
},
{
/* [935] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[231],
+ /* matcher indices */ &kMatcherIndices[114],
},
{
/* [936] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[233],
+ /* matcher indices */ &kMatcherIndices[118],
},
{
/* [937] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[54],
+ /* matcher indices */ &kMatcherIndices[120],
},
{
/* [938] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[112],
+ /* matcher indices */ &kMatcherIndices[124],
},
{
/* [939] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[114],
+ /* matcher indices */ &kMatcherIndices[126],
},
{
/* [940] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[118],
+ /* matcher indices */ &kMatcherIndices[230],
},
{
/* [941] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[120],
+ /* matcher indices */ &kMatcherIndices[231],
},
{
/* [942] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[124],
+ /* matcher indices */ &kMatcherIndices[232],
},
{
/* [943] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[126],
+ /* matcher indices */ &kMatcherIndices[233],
},
{
/* [944] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[230],
+ /* matcher indices */ &kMatcherIndices[128],
},
{
/* [945] */
/* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[231],
- },
- {
- /* [946] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[232],
- },
- {
- /* [947] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[233],
- },
- {
- /* [948] */
- /* usage */ ParameterUsage::kTexture,
- /* matcher indices */ &kMatcherIndices[128],
- },
- {
- /* [949] */
- /* usage */ ParameterUsage::kTexture,
/* matcher indices */ &kMatcherIndices[234],
},
{
- /* [950] */
+ /* [946] */
/* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[5],
},
{
- /* [951] */
+ /* [947] */
/* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[3],
},
{
- /* [952] */
+ /* [948] */
/* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[35],
},
{
- /* [953] */
+ /* [949] */
/* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[33],
},
{
- /* [954] */
+ /* [950] */
/* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[3],
},
{
+ /* [951] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[30],
+ },
+ {
+ /* [952] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[3],
+ },
+ {
+ /* [953] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[30],
+ },
+ {
+ /* [954] */
+ /* usage */ ParameterUsage::kNone,
+ /* matcher indices */ &kMatcherIndices[9],
+ },
+ {
/* [955] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[3],
},
{
/* [956] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[101],
},
{
/* [957] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[30],
+ /* matcher indices */ &kMatcherIndices[3],
},
{
/* [958] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[9],
+ /* matcher indices */ &kMatcherIndices[38],
},
{
/* [959] */
@@ -7791,7 +7791,7 @@
{
/* [960] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[101],
+ /* matcher indices */ &kMatcherIndices[1],
},
{
/* [961] */
@@ -7801,7 +7801,7 @@
{
/* [962] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[38],
+ /* matcher indices */ &kMatcherIndices[35],
},
{
/* [963] */
@@ -7811,7 +7811,7 @@
{
/* [964] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[1],
+ /* matcher indices */ &kMatcherIndices[150],
},
{
/* [965] */
@@ -7821,22 +7821,22 @@
{
/* [966] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[35],
+ /* matcher indices */ &kMatcherIndices[156],
},
{
/* [967] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[156],
},
{
/* [968] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[150],
+ /* matcher indices */ &kMatcherIndices[156],
},
{
/* [969] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[156],
},
{
/* [970] */
@@ -7846,32 +7846,32 @@
{
/* [971] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[156],
+ /* matcher indices */ &kMatcherIndices[102],
},
{
/* [972] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[156],
+ /* matcher indices */ &kMatcherIndices[3],
},
{
/* [973] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[156],
+ /* matcher indices */ &kMatcherIndices[158],
},
{
/* [974] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[156],
+ /* matcher indices */ &kMatcherIndices[158],
},
{
/* [975] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[102],
+ /* matcher indices */ &kMatcherIndices[158],
},
{
/* [976] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[158],
},
{
/* [977] */
@@ -7881,32 +7881,32 @@
{
/* [978] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[158],
+ /* matcher indices */ &kMatcherIndices[130],
},
{
/* [979] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[158],
+ /* matcher indices */ &kMatcherIndices[3],
},
{
/* [980] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[158],
+ /* matcher indices */ &kMatcherIndices[170],
},
{
/* [981] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[158],
+ /* matcher indices */ &kMatcherIndices[170],
},
{
/* [982] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[130],
+ /* matcher indices */ &kMatcherIndices[170],
},
{
/* [983] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[3],
+ /* matcher indices */ &kMatcherIndices[170],
},
{
/* [984] */
@@ -7916,155 +7916,135 @@
{
/* [985] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[170],
+ /* matcher indices */ &kMatcherIndices[176],
},
{
/* [986] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[170],
+ /* matcher indices */ &kMatcherIndices[178],
},
{
/* [987] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[170],
+ /* matcher indices */ &kMatcherIndices[180],
},
{
/* [988] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[170],
+ /* matcher indices */ &kMatcherIndices[182],
},
{
/* [989] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[176],
+ /* matcher indices */ &kMatcherIndices[184],
},
{
/* [990] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[178],
+ /* matcher indices */ &kMatcherIndices[186],
},
{
/* [991] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[180],
+ /* matcher indices */ &kMatcherIndices[188],
},
{
/* [992] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[182],
+ /* matcher indices */ &kMatcherIndices[190],
},
{
/* [993] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[184],
+ /* matcher indices */ &kMatcherIndices[192],
},
{
/* [994] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[186],
+ /* matcher indices */ &kMatcherIndices[194],
},
{
/* [995] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[188],
+ /* matcher indices */ &kMatcherIndices[196],
},
{
/* [996] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[190],
+ /* matcher indices */ &kMatcherIndices[198],
},
{
/* [997] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[192],
+ /* matcher indices */ &kMatcherIndices[200],
},
{
/* [998] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[194],
+ /* matcher indices */ &kMatcherIndices[202],
},
{
/* [999] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[196],
+ /* matcher indices */ &kMatcherIndices[204],
},
{
/* [1000] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[198],
+ /* matcher indices */ &kMatcherIndices[206],
},
{
/* [1001] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[200],
+ /* matcher indices */ &kMatcherIndices[208],
},
{
/* [1002] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[202],
+ /* matcher indices */ &kMatcherIndices[210],
},
{
/* [1003] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[204],
+ /* matcher indices */ &kMatcherIndices[212],
},
{
/* [1004] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[206],
+ /* matcher indices */ &kMatcherIndices[214],
},
{
/* [1005] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[208],
+ /* matcher indices */ &kMatcherIndices[216],
},
{
/* [1006] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[210],
+ /* matcher indices */ &kMatcherIndices[218],
},
{
/* [1007] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[212],
+ /* matcher indices */ &kMatcherIndices[220],
},
{
/* [1008] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[214],
+ /* matcher indices */ &kMatcherIndices[222],
},
{
/* [1009] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[216],
+ /* matcher indices */ &kMatcherIndices[224],
},
{
/* [1010] */
/* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[218],
- },
- {
- /* [1011] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[220],
- },
- {
- /* [1012] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[222],
- },
- {
- /* [1013] */
- /* usage */ ParameterUsage::kNone,
- /* matcher indices */ &kMatcherIndices[224],
- },
- {
- /* [1014] */
- /* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[226],
},
{
- /* [1015] */
+ /* [1011] */
/* usage */ ParameterUsage::kNone,
/* matcher indices */ &kMatcherIndices[228],
},
@@ -8229,35 +8209,30 @@
{
/* [31] */
/* name */ "T",
- /* matcher index */ 5,
+ /* matcher index */ 56,
},
{
/* [32] */
/* name */ "T",
- /* matcher index */ 56,
+ /* matcher index */ 57,
},
{
/* [33] */
/* name */ "T",
- /* matcher index */ 57,
+ /* matcher index */ 54,
},
{
/* [34] */
/* name */ "T",
- /* matcher index */ 54,
+ /* matcher index */ 55,
},
{
/* [35] */
/* name */ "T",
- /* matcher index */ 55,
- },
- {
- /* [36] */
- /* name */ "T",
/* matcher index */ 58,
},
{
- /* [37] */
+ /* [36] */
/* name */ "T",
/* matcher index */ 53,
},
@@ -8324,7 +8299,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[916],
+ /* parameters */ &kParameters[912],
/* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8348,7 +8323,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[917],
+ /* parameters */ &kParameters[913],
/* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8372,7 +8347,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[918],
+ /* parameters */ &kParameters[914],
/* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8396,7 +8371,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[919],
+ /* parameters */ &kParameters[915],
/* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8420,7 +8395,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[920],
+ /* parameters */ &kParameters[916],
/* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8444,7 +8419,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[921],
+ /* parameters */ &kParameters[917],
/* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8468,7 +8443,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[922],
+ /* parameters */ &kParameters[918],
/* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8478,9 +8453,9 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[923],
+ /* parameters */ &kParameters[919],
/* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8502,9 +8477,9 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[924],
+ /* parameters */ &kParameters[920],
/* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8526,9 +8501,9 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[925],
+ /* parameters */ &kParameters[921],
/* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8550,9 +8525,9 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[926],
+ /* parameters */ &kParameters[922],
/* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8574,9 +8549,9 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[927],
+ /* parameters */ &kParameters[923],
/* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8586,9 +8561,9 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 2,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[928],
+ /* parameters */ &kParameters[924],
/* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8598,9 +8573,9 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 2,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[929],
+ /* parameters */ &kParameters[925],
/* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8610,9 +8585,9 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 2,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[930],
+ /* parameters */ &kParameters[926],
/* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8622,9 +8597,9 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 2,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[931],
+ /* parameters */ &kParameters[927],
/* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8634,9 +8609,9 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[932],
+ /* parameters */ &kParameters[928],
/* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -8646,7 +8621,7 @@
/* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[501],
/* return matcher indices */ &kMatcherIndices[110],
@@ -8658,7 +8633,7 @@
/* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[504],
/* return matcher indices */ &kMatcherIndices[110],
@@ -8670,7 +8645,7 @@
/* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[331],
/* return matcher indices */ &kMatcherIndices[110],
@@ -8706,7 +8681,7 @@
/* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[507],
/* return matcher indices */ &kMatcherIndices[110],
@@ -8718,7 +8693,7 @@
/* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[339],
/* return matcher indices */ &kMatcherIndices[110],
@@ -8730,7 +8705,7 @@
/* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[510],
/* return matcher indices */ &kMatcherIndices[110],
@@ -8754,7 +8729,7 @@
/* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[513],
/* return matcher indices */ &kMatcherIndices[38],
@@ -8766,7 +8741,7 @@
/* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[347],
/* return matcher indices */ &kMatcherIndices[38],
@@ -8802,7 +8777,7 @@
/* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[516],
/* return matcher indices */ &kMatcherIndices[38],
@@ -8826,9 +8801,9 @@
/* num parameters */ 0,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[37],
+ /* template types */ &kTemplateTypes[36],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1016],
+ /* parameters */ &kParameters[1012],
/* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -8840,7 +8815,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[27],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[982],
+ /* parameters */ &kParameters[978],
/* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -8852,7 +8827,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[27],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[983],
+ /* parameters */ &kParameters[979],
/* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecSplat,
@@ -8912,7 +8887,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[27],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[792],
+ /* parameters */ &kParameters[788],
/* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecInitM,
@@ -8924,7 +8899,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[27],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[794],
+ /* parameters */ &kParameters[790],
/* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecInitM,
@@ -8936,7 +8911,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[27],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[796],
+ /* parameters */ &kParameters[792],
/* return matcher indices */ &kMatcherIndices[130],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecInitM,
@@ -8948,7 +8923,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[984],
+ /* parameters */ &kParameters[980],
/* return matcher indices */ &kMatcherIndices[110],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -8960,7 +8935,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[985],
+ /* parameters */ &kParameters[981],
/* return matcher indices */ &kMatcherIndices[172],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -8972,7 +8947,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[986],
+ /* parameters */ &kParameters[982],
/* return matcher indices */ &kMatcherIndices[152],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -8984,7 +8959,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[18],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[987],
+ /* parameters */ &kParameters[983],
/* return matcher indices */ &kMatcherIndices[154],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -8996,7 +8971,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[20],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[988],
+ /* parameters */ &kParameters[984],
/* return matcher indices */ &kMatcherIndices[174],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -9006,7 +8981,7 @@
/* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[387],
/* return matcher indices */ &kMatcherIndices[110],
@@ -9018,7 +8993,7 @@
/* num parameters */ 5,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[260],
/* return matcher indices */ &kMatcherIndices[110],
@@ -9054,7 +9029,7 @@
/* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[391],
/* return matcher indices */ &kMatcherIndices[110],
@@ -9066,7 +9041,7 @@
/* num parameters */ 5,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[270],
/* return matcher indices */ &kMatcherIndices[110],
@@ -9078,7 +9053,7 @@
/* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[395],
/* return matcher indices */ &kMatcherIndices[110],
@@ -9246,7 +9221,7 @@
/* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[495],
/* return matcher indices */ &kMatcherIndices[110],
@@ -9258,7 +9233,7 @@
/* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[311],
/* return matcher indices */ &kMatcherIndices[110],
@@ -9294,7 +9269,7 @@
/* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[498],
/* return matcher indices */ &kMatcherIndices[110],
@@ -9450,7 +9425,7 @@
/* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[549],
/* return matcher indices */ nullptr,
@@ -9462,9 +9437,9 @@
/* num parameters */ 0,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[37],
+ /* template types */ &kTemplateTypes[36],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1016],
+ /* parameters */ &kParameters[1012],
/* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -9476,7 +9451,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[27],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[975],
+ /* parameters */ &kParameters[971],
/* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -9488,7 +9463,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[27],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[976],
+ /* parameters */ &kParameters[972],
/* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecSplat,
@@ -9512,7 +9487,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[27],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[788],
+ /* parameters */ &kParameters[784],
/* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecInitM,
@@ -9524,7 +9499,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[27],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[790],
+ /* parameters */ &kParameters[786],
/* return matcher indices */ &kMatcherIndices[102],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecInitM,
@@ -9536,7 +9511,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[977],
+ /* parameters */ &kParameters[973],
/* return matcher indices */ &kMatcherIndices[134],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -9548,7 +9523,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[978],
+ /* parameters */ &kParameters[974],
/* return matcher indices */ &kMatcherIndices[166],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -9560,7 +9535,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[979],
+ /* parameters */ &kParameters[975],
/* return matcher indices */ &kMatcherIndices[144],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -9572,7 +9547,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[18],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[980],
+ /* parameters */ &kParameters[976],
/* return matcher indices */ &kMatcherIndices[122],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -9584,7 +9559,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[20],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[981],
+ /* parameters */ &kParameters[977],
/* return matcher indices */ &kMatcherIndices[168],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -9596,7 +9571,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[938],
+ /* parameters */ &kParameters[934],
/* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -9608,7 +9583,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[939],
+ /* parameters */ &kParameters[935],
/* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -9620,7 +9595,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[940],
+ /* parameters */ &kParameters[936],
/* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -9632,7 +9607,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[941],
+ /* parameters */ &kParameters[937],
/* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -9644,7 +9619,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[942],
+ /* parameters */ &kParameters[938],
/* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -9656,7 +9631,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[943],
+ /* parameters */ &kParameters[939],
/* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -9666,9 +9641,9 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[944],
+ /* parameters */ &kParameters[940],
/* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -9678,9 +9653,9 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[945],
+ /* parameters */ &kParameters[941],
/* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -9690,9 +9665,9 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[946],
+ /* parameters */ &kParameters[942],
/* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -9702,9 +9677,9 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[947],
+ /* parameters */ &kParameters[943],
/* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -9930,9 +9905,9 @@
/* num parameters */ 0,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[37],
+ /* template types */ &kTemplateTypes[36],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1016],
+ /* parameters */ &kParameters[1012],
/* return matcher indices */ &kMatcherIndices[150],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -9944,7 +9919,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[27],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[968],
+ /* parameters */ &kParameters[964],
/* return matcher indices */ &kMatcherIndices[150],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -9956,7 +9931,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[27],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[969],
+ /* parameters */ &kParameters[965],
/* return matcher indices */ &kMatcherIndices[150],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecSplat,
@@ -9968,7 +9943,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[27],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[786],
+ /* parameters */ &kParameters[782],
/* return matcher indices */ &kMatcherIndices[150],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::VecInitS,
@@ -9980,7 +9955,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[970],
+ /* parameters */ &kParameters[966],
/* return matcher indices */ &kMatcherIndices[108],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -9992,7 +9967,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[971],
+ /* parameters */ &kParameters[967],
/* return matcher indices */ &kMatcherIndices[162],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10004,7 +9979,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[16],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[972],
+ /* parameters */ &kParameters[968],
/* return matcher indices */ &kMatcherIndices[132],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10016,7 +9991,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[18],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[973],
+ /* parameters */ &kParameters[969],
/* return matcher indices */ &kMatcherIndices[116],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10028,7 +10003,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[20],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[974],
+ /* parameters */ &kParameters[970],
/* return matcher indices */ &kMatcherIndices[164],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10038,7 +10013,7 @@
/* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[359],
/* return matcher indices */ &kMatcherIndices[110],
@@ -10050,7 +10025,7 @@
/* num parameters */ 5,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[195],
/* return matcher indices */ &kMatcherIndices[110],
@@ -10086,7 +10061,7 @@
/* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[363],
/* return matcher indices */ &kMatcherIndices[110],
@@ -10098,7 +10073,7 @@
/* num parameters */ 5,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[205],
/* return matcher indices */ &kMatcherIndices[110],
@@ -10110,7 +10085,7 @@
/* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[367],
/* return matcher indices */ &kMatcherIndices[110],
@@ -10134,7 +10109,7 @@
/* num parameters */ 5,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[245],
/* return matcher indices */ &kMatcherIndices[110],
@@ -10146,7 +10121,7 @@
/* num parameters */ 6,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[102],
/* return matcher indices */ &kMatcherIndices[110],
@@ -10182,7 +10157,7 @@
/* num parameters */ 5,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[250],
/* return matcher indices */ &kMatcherIndices[110],
@@ -10194,7 +10169,7 @@
/* num parameters */ 6,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[114],
/* return matcher indices */ &kMatcherIndices[110],
@@ -10206,7 +10181,7 @@
/* num parameters */ 5,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[255],
/* return matcher indices */ &kMatcherIndices[110],
@@ -10230,7 +10205,7 @@
/* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[323],
/* return matcher indices */ &kMatcherIndices[110],
@@ -10242,7 +10217,7 @@
/* num parameters */ 5,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[170],
/* return matcher indices */ &kMatcherIndices[110],
@@ -10278,7 +10253,7 @@
/* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[327],
/* return matcher indices */ &kMatcherIndices[110],
@@ -10302,7 +10277,7 @@
/* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[371],
/* return matcher indices */ &kMatcherIndices[38],
@@ -10314,7 +10289,7 @@
/* num parameters */ 5,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[215],
/* return matcher indices */ &kMatcherIndices[38],
@@ -10350,7 +10325,7 @@
/* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[375],
/* return matcher indices */ &kMatcherIndices[38],
@@ -10374,7 +10349,7 @@
/* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[379],
/* return matcher indices */ &kMatcherIndices[38],
@@ -10386,7 +10361,7 @@
/* num parameters */ 5,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[230],
/* return matcher indices */ &kMatcherIndices[38],
@@ -10422,7 +10397,7 @@
/* num parameters */ 4,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[383],
/* return matcher indices */ &kMatcherIndices[38],
@@ -10448,7 +10423,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1016],
+ /* parameters */ &kParameters[1012],
/* return matcher indices */ &kMatcherIndices[176],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -10460,7 +10435,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[989],
+ /* parameters */ &kParameters[985],
/* return matcher indices */ &kMatcherIndices[176],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -10484,7 +10459,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[798],
+ /* parameters */ &kParameters[794],
/* return matcher indices */ &kMatcherIndices[176],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatInitV,
@@ -10496,7 +10471,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[990],
+ /* parameters */ &kParameters[986],
/* return matcher indices */ &kMatcherIndices[180],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10508,7 +10483,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[991],
+ /* parameters */ &kParameters[987],
/* return matcher indices */ &kMatcherIndices[178],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10520,7 +10495,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1016],
+ /* parameters */ &kParameters[1012],
/* return matcher indices */ &kMatcherIndices[182],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -10532,7 +10507,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[992],
+ /* parameters */ &kParameters[988],
/* return matcher indices */ &kMatcherIndices[182],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -10556,7 +10531,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[800],
+ /* parameters */ &kParameters[796],
/* return matcher indices */ &kMatcherIndices[182],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatInitV,
@@ -10568,7 +10543,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[993],
+ /* parameters */ &kParameters[989],
/* return matcher indices */ &kMatcherIndices[186],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10580,7 +10555,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[994],
+ /* parameters */ &kParameters[990],
/* return matcher indices */ &kMatcherIndices[184],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10592,7 +10567,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1016],
+ /* parameters */ &kParameters[1012],
/* return matcher indices */ &kMatcherIndices[188],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -10604,7 +10579,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[995],
+ /* parameters */ &kParameters[991],
/* return matcher indices */ &kMatcherIndices[188],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -10628,7 +10603,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[802],
+ /* parameters */ &kParameters[798],
/* return matcher indices */ &kMatcherIndices[188],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::MatInitV,
@@ -10640,7 +10615,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[996],
+ /* parameters */ &kParameters[992],
/* return matcher indices */ &kMatcherIndices[192],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10652,7 +10627,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[997],
+ /* parameters */ &kParameters[993],
/* return matcher indices */ &kMatcherIndices[190],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10664,7 +10639,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1016],
+ /* parameters */ &kParameters[1012],
/* return matcher indices */ &kMatcherIndices[194],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -10676,7 +10651,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[998],
+ /* parameters */ &kParameters[994],
/* return matcher indices */ &kMatcherIndices[194],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -10712,7 +10687,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[999],
+ /* parameters */ &kParameters[995],
/* return matcher indices */ &kMatcherIndices[198],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10724,7 +10699,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1000],
+ /* parameters */ &kParameters[996],
/* return matcher indices */ &kMatcherIndices[196],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10736,7 +10711,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1016],
+ /* parameters */ &kParameters[1012],
/* return matcher indices */ &kMatcherIndices[200],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -10748,7 +10723,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1001],
+ /* parameters */ &kParameters[997],
/* return matcher indices */ &kMatcherIndices[200],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -10784,7 +10759,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1002],
+ /* parameters */ &kParameters[998],
/* return matcher indices */ &kMatcherIndices[204],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10796,7 +10771,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1003],
+ /* parameters */ &kParameters[999],
/* return matcher indices */ &kMatcherIndices[202],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10808,7 +10783,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1016],
+ /* parameters */ &kParameters[1012],
/* return matcher indices */ &kMatcherIndices[206],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -10820,7 +10795,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1004],
+ /* parameters */ &kParameters[1000],
/* return matcher indices */ &kMatcherIndices[206],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -10856,7 +10831,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1005],
+ /* parameters */ &kParameters[1001],
/* return matcher indices */ &kMatcherIndices[210],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10868,7 +10843,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1006],
+ /* parameters */ &kParameters[1002],
/* return matcher indices */ &kMatcherIndices[208],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10880,7 +10855,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1016],
+ /* parameters */ &kParameters[1012],
/* return matcher indices */ &kMatcherIndices[212],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -10892,7 +10867,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1007],
+ /* parameters */ &kParameters[1003],
/* return matcher indices */ &kMatcherIndices[212],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -10928,7 +10903,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1008],
+ /* parameters */ &kParameters[1004],
/* return matcher indices */ &kMatcherIndices[216],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10940,7 +10915,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1009],
+ /* parameters */ &kParameters[1005],
/* return matcher indices */ &kMatcherIndices[214],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -10952,7 +10927,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1016],
+ /* parameters */ &kParameters[1012],
/* return matcher indices */ &kMatcherIndices[218],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -10964,7 +10939,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1010],
+ /* parameters */ &kParameters[1006],
/* return matcher indices */ &kMatcherIndices[218],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -11000,7 +10975,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1011],
+ /* parameters */ &kParameters[1007],
/* return matcher indices */ &kMatcherIndices[222],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -11012,7 +10987,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1012],
+ /* parameters */ &kParameters[1008],
/* return matcher indices */ &kMatcherIndices[220],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -11024,7 +10999,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1016],
+ /* parameters */ &kParameters[1012],
/* return matcher indices */ &kMatcherIndices[224],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
@@ -11036,7 +11011,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1013],
+ /* parameters */ &kParameters[1009],
/* return matcher indices */ &kMatcherIndices[224],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
@@ -11072,7 +11047,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[14],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1014],
+ /* parameters */ &kParameters[1010],
/* return matcher indices */ &kMatcherIndices[228],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -11084,7 +11059,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[12],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1015],
+ /* parameters */ &kParameters[1011],
/* return matcher indices */ &kMatcherIndices[226],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
@@ -11096,7 +11071,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[933],
+ /* parameters */ &kParameters[929],
/* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11108,7 +11083,7 @@
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[934],
+ /* parameters */ &kParameters[930],
/* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11118,9 +11093,9 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[935],
+ /* parameters */ &kParameters[931],
/* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11130,9 +11105,9 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[936],
+ /* parameters */ &kParameters[932],
/* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11142,9 +11117,9 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 2,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[6],
- /* parameters */ &kParameters[937],
+ /* parameters */ &kParameters[933],
/* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
@@ -11322,55 +11297,55 @@
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[30],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[718],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::OpModulo,
},
{
/* [251] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[30],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[4],
/* parameters */ &kParameters[720],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::OpModulo,
},
{
/* [252] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[30],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[4],
/* parameters */ &kParameters[722],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::OpModulo,
},
{
/* [253] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[30],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[4],
/* parameters */ &kParameters[724],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
+ /* const eval */ &ConstEval::OpModulo,
},
{
/* [254] */
/* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[730],
/* return matcher indices */ &kMatcherIndices[35],
@@ -11382,7 +11357,7 @@
/* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[4],
/* parameters */ &kParameters[732],
/* return matcher indices */ &kMatcherIndices[33],
@@ -11418,7 +11393,7 @@
/* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[738],
/* return matcher indices */ &kMatcherIndices[35],
@@ -11430,7 +11405,7 @@
/* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[4],
/* parameters */ &kParameters[740],
/* return matcher indices */ &kMatcherIndices[33],
@@ -11463,54 +11438,6 @@
},
{
/* [262] */
- /* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[25],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[774],
- /* return matcher indices */ &kMatcherIndices[3],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpShiftLeft,
- },
- {
- /* [263] */
- /* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[776],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpShiftLeft,
- },
- {
- /* [264] */
- /* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[31],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[778],
- /* return matcher indices */ &kMatcherIndices[3],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpShiftLeft,
- },
- {
- /* [265] */
- /* num parameters */ 2,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[31],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[780],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpShiftLeft,
- },
- {
- /* [266] */
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -11522,7 +11449,7 @@
/* const eval */ nullptr,
},
{
- /* [267] */
+ /* [263] */
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -11534,7 +11461,7 @@
/* const eval */ nullptr,
},
{
- /* [268] */
+ /* [264] */
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -11546,7 +11473,7 @@
/* const eval */ nullptr,
},
{
- /* [269] */
+ /* [265] */
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -11558,7 +11485,7 @@
/* const eval */ &ConstEval::select_bool,
},
{
- /* [270] */
+ /* [266] */
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -11570,7 +11497,7 @@
/* const eval */ &ConstEval::select_bool,
},
{
- /* [271] */
+ /* [267] */
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -11582,304 +11509,352 @@
/* const eval */ &ConstEval::select_boolvec,
},
{
- /* [272] */
+ /* [268] */
/* num parameters */ 0,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1016],
+ /* parameters */ &kParameters[1012],
/* return matcher indices */ &kMatcherIndices[9],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
},
{
- /* [273] */
+ /* [269] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[958],
+ /* parameters */ &kParameters[954],
/* return matcher indices */ &kMatcherIndices[9],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
},
{
- /* [274] */
+ /* [270] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[31],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[955],
+ /* return matcher indices */ &kMatcherIndices[9],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::Conv,
+ },
+ {
+ /* [271] */
+ /* num parameters */ 0,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[37],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[1012],
+ /* return matcher indices */ &kMatcherIndices[101],
+ /* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::Zero,
+ },
+ {
+ /* [272] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[37],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[956],
+ /* return matcher indices */ &kMatcherIndices[101],
+ /* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::Identity,
+ },
+ {
+ /* [273] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[32],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[959],
- /* return matcher indices */ &kMatcherIndices[9],
+ /* parameters */ &kParameters[957],
+ /* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
{
- /* [275] */
+ /* [274] */
/* num parameters */ 0,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1016],
- /* return matcher indices */ &kMatcherIndices[101],
+ /* parameters */ &kParameters[1012],
+ /* return matcher indices */ &kMatcherIndices[38],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
},
{
- /* [276] */
+ /* [275] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[960],
- /* return matcher indices */ &kMatcherIndices[101],
+ /* parameters */ &kParameters[958],
+ /* return matcher indices */ &kMatcherIndices[38],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
},
{
- /* [277] */
+ /* [276] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[33],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[961],
- /* return matcher indices */ &kMatcherIndices[101],
+ /* parameters */ &kParameters[959],
+ /* return matcher indices */ &kMatcherIndices[38],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
{
- /* [278] */
+ /* [277] */
/* num parameters */ 0,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1016],
- /* return matcher indices */ &kMatcherIndices[38],
+ /* parameters */ &kParameters[1012],
+ /* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
},
{
- /* [279] */
+ /* [278] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[962],
- /* return matcher indices */ &kMatcherIndices[38],
+ /* parameters */ &kParameters[960],
+ /* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
},
{
- /* [280] */
+ /* [279] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[34],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[963],
- /* return matcher indices */ &kMatcherIndices[38],
+ /* parameters */ &kParameters[961],
+ /* return matcher indices */ &kMatcherIndices[1],
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Conv,
},
{
- /* [281] */
+ /* [280] */
/* num parameters */ 0,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1016],
- /* return matcher indices */ &kMatcherIndices[1],
+ /* parameters */ &kParameters[1012],
+ /* return matcher indices */ &kMatcherIndices[35],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Zero,
},
{
- /* [282] */
+ /* [281] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[964],
- /* return matcher indices */ &kMatcherIndices[1],
+ /* parameters */ &kParameters[962],
+ /* return matcher indices */ &kMatcherIndices[35],
/* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
},
{
+ /* [282] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[35],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[963],
+ /* return matcher indices */ &kMatcherIndices[35],
+ /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::Conv,
+ },
+ {
/* [283] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[35],
+ /* template types */ &kTemplateTypes[22],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[965],
- /* return matcher indices */ &kMatcherIndices[1],
- /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::Conv,
+ /* parameters */ &kParameters[800],
+ /* return matcher indices */ &kMatcherIndices[3],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::abs,
},
{
/* [284] */
- /* num parameters */ 0,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1016],
- /* return matcher indices */ &kMatcherIndices[35],
- /* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::Zero,
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[22],
+ /* template numbers */ &kTemplateNumbers[4],
+ /* parameters */ &kParameters[801],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::abs,
},
{
/* [285] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[966],
- /* return matcher indices */ &kMatcherIndices[35],
- /* flags */ OverloadFlags(OverloadFlag::kIsInitializer, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::Identity,
+ /* parameters */ &kParameters[802],
+ /* return matcher indices */ &kMatcherIndices[3],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::acos,
},
{
/* [286] */
/* num parameters */ 1,
/* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[36],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[967],
- /* return matcher indices */ &kMatcherIndices[35],
- /* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::Conv,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[4],
+ /* parameters */ &kParameters[803],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::acos,
},
{
/* [287] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[22],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[804],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::abs,
+ /* const eval */ &ConstEval::acosh,
},
{
/* [288] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[22],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[4],
/* parameters */ &kParameters[805],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::abs,
+ /* const eval */ &ConstEval::acosh,
},
{
/* [289] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[806],
- /* return matcher indices */ &kMatcherIndices[3],
+ /* return matcher indices */ &kMatcherIndices[35],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::acos,
+ /* const eval */ &ConstEval::all,
},
{
/* [290] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[4],
/* parameters */ &kParameters[807],
- /* return matcher indices */ &kMatcherIndices[30],
+ /* return matcher indices */ &kMatcherIndices[35],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::acos,
+ /* const eval */ &ConstEval::all,
},
{
/* [291] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[808],
- /* return matcher indices */ &kMatcherIndices[3],
+ /* return matcher indices */ &kMatcherIndices[35],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::acosh,
+ /* const eval */ &ConstEval::any,
},
{
/* [292] */
/* num parameters */ 1,
- /* num template types */ 1,
+ /* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[4],
/* parameters */ &kParameters[809],
- /* return matcher indices */ &kMatcherIndices[30],
+ /* return matcher indices */ &kMatcherIndices[35],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::acosh,
+ /* const eval */ &ConstEval::any,
},
{
/* [293] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[810],
- /* return matcher indices */ &kMatcherIndices[35],
+ /* parameters */ &kParameters[811],
+ /* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::all,
+ /* const eval */ &ConstEval::asin,
},
{
/* [294] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[811],
- /* return matcher indices */ &kMatcherIndices[35],
+ /* parameters */ &kParameters[812],
+ /* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::all,
+ /* const eval */ &ConstEval::asin,
},
{
/* [295] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[812],
- /* return matcher indices */ &kMatcherIndices[35],
+ /* parameters */ &kParameters[813],
+ /* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::any,
+ /* const eval */ &ConstEval::asinh,
},
{
/* [296] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[813],
- /* return matcher indices */ &kMatcherIndices[35],
+ /* parameters */ &kParameters[814],
+ /* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::any,
+ /* const eval */ &ConstEval::asinh,
},
{
/* [297] */
@@ -11891,7 +11866,7 @@
/* parameters */ &kParameters[815],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::asin,
+ /* const eval */ &ConstEval::atan,
},
{
/* [298] */
@@ -11903,58 +11878,10 @@
/* parameters */ &kParameters[816],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::asin,
+ /* const eval */ &ConstEval::atan,
},
{
/* [299] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[817],
- /* return matcher indices */ &kMatcherIndices[3],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::asinh,
- },
- {
- /* [300] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[818],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::asinh,
- },
- {
- /* [301] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[819],
- /* return matcher indices */ &kMatcherIndices[3],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::atan,
- },
- {
- /* [302] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[820],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::atan,
- },
- {
- /* [303] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -11966,7 +11893,7 @@
/* const eval */ &ConstEval::atan2,
},
{
- /* [304] */
+ /* [300] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -11978,55 +11905,55 @@
/* const eval */ &ConstEval::atan2,
},
{
+ /* [301] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[817],
+ /* return matcher indices */ &kMatcherIndices[3],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::atanh,
+ },
+ {
+ /* [302] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[4],
+ /* parameters */ &kParameters[818],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::atanh,
+ },
+ {
+ /* [303] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[819],
+ /* return matcher indices */ &kMatcherIndices[3],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::ceil,
+ },
+ {
+ /* [304] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[4],
+ /* parameters */ &kParameters[820],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::ceil,
+ },
+ {
/* [305] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[821],
- /* return matcher indices */ &kMatcherIndices[3],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::atanh,
- },
- {
- /* [306] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[822],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::atanh,
- },
- {
- /* [307] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[823],
- /* return matcher indices */ &kMatcherIndices[3],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::ceil,
- },
- {
- /* [308] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[824],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::ceil,
- },
- {
- /* [309] */
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -12038,7 +11965,7 @@
/* const eval */ &ConstEval::clamp,
},
{
- /* [310] */
+ /* [306] */
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -12050,52 +11977,100 @@
/* const eval */ &ConstEval::clamp,
},
{
- /* [311] */
+ /* [307] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[825],
+ /* parameters */ &kParameters[821],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::cos,
},
{
+ /* [308] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[4],
+ /* parameters */ &kParameters[822],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::cos,
+ },
+ {
+ /* [309] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[823],
+ /* return matcher indices */ &kMatcherIndices[3],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::cosh,
+ },
+ {
+ /* [310] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[4],
+ /* parameters */ &kParameters[824],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::cosh,
+ },
+ {
+ /* [311] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[25],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[825],
+ /* return matcher indices */ &kMatcherIndices[3],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::countLeadingZeros,
+ },
+ {
/* [312] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[25],
/* template numbers */ &kTemplateNumbers[4],
/* parameters */ &kParameters[826],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::cos,
+ /* const eval */ &ConstEval::countLeadingZeros,
},
{
/* [313] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[25],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[827],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::cosh,
+ /* const eval */ &ConstEval::countOneBits,
},
{
/* [314] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[25],
/* template numbers */ &kTemplateNumbers[4],
/* parameters */ &kParameters[828],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::cosh,
+ /* const eval */ &ConstEval::countOneBits,
},
{
/* [315] */
@@ -12107,7 +12082,7 @@
/* parameters */ &kParameters[829],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::countLeadingZeros,
+ /* const eval */ &ConstEval::countTrailingZeros,
},
{
/* [316] */
@@ -12119,82 +12094,34 @@
/* parameters */ &kParameters[830],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::countLeadingZeros,
+ /* const eval */ &ConstEval::countTrailingZeros,
},
{
/* [317] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[831],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::countOneBits,
+ /* const eval */ &ConstEval::degrees,
},
{
/* [318] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[4],
/* parameters */ &kParameters[832],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::countOneBits,
+ /* const eval */ &ConstEval::degrees,
},
{
/* [319] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[25],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[833],
- /* return matcher indices */ &kMatcherIndices[3],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::countTrailingZeros,
- },
- {
- /* [320] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[834],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::countTrailingZeros,
- },
- {
- /* [321] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[835],
- /* return matcher indices */ &kMatcherIndices[3],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::degrees,
- },
- {
- /* [322] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[836],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::degrees,
- },
- {
- /* [323] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -12206,7 +12133,7 @@
/* const eval */ &ConstEval::distance,
},
{
- /* [324] */
+ /* [320] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -12218,11 +12145,59 @@
/* const eval */ &ConstEval::distance,
},
{
+ /* [321] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[37],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[834],
+ /* return matcher indices */ &kMatcherIndices[38],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [322] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[37],
+ /* template numbers */ &kTemplateNumbers[4],
+ /* parameters */ &kParameters[835],
+ /* return matcher indices */ &kMatcherIndices[36],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [323] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[37],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[836],
+ /* return matcher indices */ &kMatcherIndices[38],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [324] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[37],
+ /* template numbers */ &kTemplateNumbers[4],
+ /* parameters */ &kParameters[837],
+ /* return matcher indices */ &kMatcherIndices[36],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* const eval */ nullptr,
+ },
+ {
/* [325] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[838],
/* return matcher indices */ &kMatcherIndices[38],
@@ -12234,7 +12209,7 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[4],
/* parameters */ &kParameters[839],
/* return matcher indices */ &kMatcherIndices[36],
@@ -12246,7 +12221,7 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[840],
/* return matcher indices */ &kMatcherIndices[38],
@@ -12258,7 +12233,7 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[4],
/* parameters */ &kParameters[841],
/* return matcher indices */ &kMatcherIndices[36],
@@ -12270,7 +12245,7 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[842],
/* return matcher indices */ &kMatcherIndices[38],
@@ -12282,7 +12257,7 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[4],
/* parameters */ &kParameters[843],
/* return matcher indices */ &kMatcherIndices[36],
@@ -12294,7 +12269,7 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[844],
/* return matcher indices */ &kMatcherIndices[38],
@@ -12306,7 +12281,7 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[4],
/* parameters */ &kParameters[845],
/* return matcher indices */ &kMatcherIndices[36],
@@ -12316,101 +12291,53 @@
{
/* [333] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[846],
- /* return matcher indices */ &kMatcherIndices[38],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
- /* const eval */ nullptr,
+ /* return matcher indices */ &kMatcherIndices[3],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::exp,
},
{
/* [334] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[4],
/* parameters */ &kParameters[847],
- /* return matcher indices */ &kMatcherIndices[36],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
- /* const eval */ nullptr,
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::exp,
},
{
/* [335] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[848],
- /* return matcher indices */ &kMatcherIndices[38],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
- /* const eval */ nullptr,
+ /* return matcher indices */ &kMatcherIndices[3],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::exp2,
},
{
/* [336] */
/* num parameters */ 1,
- /* num template types */ 0,
+ /* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[4],
/* parameters */ &kParameters[849],
- /* return matcher indices */ &kMatcherIndices[36],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
- /* const eval */ nullptr,
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::exp2,
},
{
/* [337] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[850],
- /* return matcher indices */ &kMatcherIndices[3],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::exp,
- },
- {
- /* [338] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[851],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::exp,
- },
- {
- /* [339] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[852],
- /* return matcher indices */ &kMatcherIndices[3],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::exp2,
- },
- {
- /* [340] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[853],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::exp2,
- },
- {
- /* [341] */
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -12422,7 +12349,7 @@
/* const eval */ &ConstEval::extractBits,
},
{
- /* [342] */
+ /* [338] */
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -12434,79 +12361,79 @@
/* const eval */ &ConstEval::extractBits,
},
{
- /* [343] */
+ /* [339] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[25],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[854],
+ /* parameters */ &kParameters[850],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::firstLeadingBit,
},
{
+ /* [340] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[25],
+ /* template numbers */ &kTemplateNumbers[4],
+ /* parameters */ &kParameters[851],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::firstLeadingBit,
+ },
+ {
+ /* [341] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[25],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[852],
+ /* return matcher indices */ &kMatcherIndices[3],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::firstTrailingBit,
+ },
+ {
+ /* [342] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[25],
+ /* template numbers */ &kTemplateNumbers[4],
+ /* parameters */ &kParameters[853],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::firstTrailingBit,
+ },
+ {
+ /* [343] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[854],
+ /* return matcher indices */ &kMatcherIndices[3],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::floor,
+ },
+ {
/* [344] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[4],
/* parameters */ &kParameters[855],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::firstLeadingBit,
+ /* const eval */ &ConstEval::floor,
},
{
/* [345] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[25],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[856],
- /* return matcher indices */ &kMatcherIndices[3],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::firstTrailingBit,
- },
- {
- /* [346] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[857],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::firstTrailingBit,
- },
- {
- /* [347] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[858],
- /* return matcher indices */ &kMatcherIndices[3],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::floor,
- },
- {
- /* [348] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[859],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::floor,
- },
- {
- /* [349] */
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -12518,7 +12445,7 @@
/* const eval */ &ConstEval::fma,
},
{
- /* [350] */
+ /* [346] */
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -12530,59 +12457,107 @@
/* const eval */ &ConstEval::fma,
},
{
- /* [351] */
+ /* [347] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[860],
+ /* parameters */ &kParameters[856],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
- /* [352] */
+ /* [348] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[26],
/* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[861],
+ /* parameters */ &kParameters[857],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
- /* [353] */
+ /* [349] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[862],
+ /* parameters */ &kParameters[858],
/* return matcher indices */ &kMatcherIndices[104],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::frexp,
},
{
- /* [354] */
+ /* [350] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[863],
+ /* parameters */ &kParameters[859],
/* return matcher indices */ &kMatcherIndices[39],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::frexp,
},
{
+ /* [351] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[37],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[860],
+ /* return matcher indices */ &kMatcherIndices[38],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [352] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[37],
+ /* template numbers */ &kTemplateNumbers[4],
+ /* parameters */ &kParameters[861],
+ /* return matcher indices */ &kMatcherIndices[36],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [353] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[37],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[862],
+ /* return matcher indices */ &kMatcherIndices[38],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* const eval */ nullptr,
+ },
+ {
+ /* [354] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[37],
+ /* template numbers */ &kTemplateNumbers[4],
+ /* parameters */ &kParameters[863],
+ /* return matcher indices */ &kMatcherIndices[36],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
+ /* const eval */ nullptr,
+ },
+ {
/* [355] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[864],
/* return matcher indices */ &kMatcherIndices[38],
@@ -12594,7 +12569,7 @@
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[4],
/* parameters */ &kParameters[865],
/* return matcher indices */ &kMatcherIndices[36],
@@ -12603,54 +12578,6 @@
},
{
/* [357] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[866],
- /* return matcher indices */ &kMatcherIndices[38],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
- /* const eval */ nullptr,
- },
- {
- /* [358] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[867],
- /* return matcher indices */ &kMatcherIndices[36],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
- /* const eval */ nullptr,
- },
- {
- /* [359] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[868],
- /* return matcher indices */ &kMatcherIndices[38],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
- /* const eval */ nullptr,
- },
- {
- /* [360] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[869],
- /* return matcher indices */ &kMatcherIndices[36],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline),
- /* const eval */ nullptr,
- },
- {
- /* [361] */
/* num parameters */ 4,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -12662,7 +12589,7 @@
/* const eval */ &ConstEval::insertBits,
},
{
- /* [362] */
+ /* [358] */
/* num parameters */ 4,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -12674,31 +12601,31 @@
/* const eval */ &ConstEval::insertBits,
},
{
- /* [363] */
+ /* [359] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[870],
+ /* parameters */ &kParameters[866],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::inverseSqrt,
},
{
- /* [364] */
+ /* [360] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[871],
+ /* parameters */ &kParameters[867],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::inverseSqrt,
},
{
- /* [365] */
+ /* [361] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -12710,7 +12637,7 @@
/* const eval */ nullptr,
},
{
- /* [366] */
+ /* [362] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -12722,6 +12649,54 @@
/* const eval */ nullptr,
},
{
+ /* [363] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[868],
+ /* return matcher indices */ &kMatcherIndices[3],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::length,
+ },
+ {
+ /* [364] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[4],
+ /* parameters */ &kParameters[869],
+ /* return matcher indices */ &kMatcherIndices[3],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::length,
+ },
+ {
+ /* [365] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[870],
+ /* return matcher indices */ &kMatcherIndices[3],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::log,
+ },
+ {
+ /* [366] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[4],
+ /* parameters */ &kParameters[871],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::log,
+ },
+ {
/* [367] */
/* num parameters */ 1,
/* num template types */ 1,
@@ -12731,7 +12706,7 @@
/* parameters */ &kParameters[872],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::length,
+ /* const eval */ &ConstEval::log2,
},
{
/* [368] */
@@ -12741,60 +12716,12 @@
/* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[4],
/* parameters */ &kParameters[873],
- /* return matcher indices */ &kMatcherIndices[3],
+ /* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::length,
+ /* const eval */ &ConstEval::log2,
},
{
/* [369] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[874],
- /* return matcher indices */ &kMatcherIndices[3],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::log,
- },
- {
- /* [370] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[875],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::log,
- },
- {
- /* [371] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[876],
- /* return matcher indices */ &kMatcherIndices[3],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::log2,
- },
- {
- /* [372] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[877],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::log2,
- },
- {
- /* [373] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -12806,7 +12733,7 @@
/* const eval */ &ConstEval::max,
},
{
- /* [374] */
+ /* [370] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -12818,7 +12745,7 @@
/* const eval */ &ConstEval::max,
},
{
- /* [375] */
+ /* [371] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -12830,7 +12757,7 @@
/* const eval */ &ConstEval::min,
},
{
- /* [376] */
+ /* [372] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -12842,31 +12769,31 @@
/* const eval */ &ConstEval::min,
},
{
- /* [377] */
+ /* [373] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[878],
+ /* parameters */ &kParameters[874],
/* return matcher indices */ &kMatcherIndices[106],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::modf,
},
{
- /* [378] */
+ /* [374] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[879],
+ /* parameters */ &kParameters[875],
/* return matcher indices */ &kMatcherIndices[45],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::modf,
},
{
- /* [379] */
+ /* [375] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -12878,7 +12805,7 @@
/* const eval */ nullptr,
},
{
- /* [380] */
+ /* [376] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -12890,30 +12817,78 @@
/* const eval */ nullptr,
},
{
- /* [381] */
+ /* [377] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[886],
+ /* parameters */ &kParameters[882],
/* return matcher indices */ &kMatcherIndices[38],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::quantizeToF16,
},
{
- /* [382] */
+ /* [378] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[887],
+ /* parameters */ &kParameters[883],
/* return matcher indices */ &kMatcherIndices[36],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::quantizeToF16,
},
{
+ /* [379] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[884],
+ /* return matcher indices */ &kMatcherIndices[3],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::radians,
+ },
+ {
+ /* [380] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[4],
+ /* parameters */ &kParameters[885],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::radians,
+ },
+ {
+ /* [381] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[25],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[886],
+ /* return matcher indices */ &kMatcherIndices[3],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::reverseBits,
+ },
+ {
+ /* [382] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[25],
+ /* template numbers */ &kTemplateNumbers[4],
+ /* parameters */ &kParameters[887],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::reverseBits,
+ },
+ {
/* [383] */
/* num parameters */ 1,
/* num template types */ 1,
@@ -12923,7 +12898,7 @@
/* parameters */ &kParameters[888],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::radians,
+ /* const eval */ &ConstEval::round,
},
{
/* [384] */
@@ -12935,31 +12910,31 @@
/* parameters */ &kParameters[889],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::radians,
+ /* const eval */ &ConstEval::round,
},
{
/* [385] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[890],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::reverseBits,
+ /* const eval */ &ConstEval::saturate,
},
{
/* [386] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[25],
+ /* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[4],
/* parameters */ &kParameters[891],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::reverseBits,
+ /* const eval */ &ConstEval::saturate,
},
{
/* [387] */
@@ -12971,7 +12946,7 @@
/* parameters */ &kParameters[892],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::round,
+ /* const eval */ &ConstEval::sign,
},
{
/* [388] */
@@ -12983,7 +12958,7 @@
/* parameters */ &kParameters[893],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::round,
+ /* const eval */ &ConstEval::sign,
},
{
/* [389] */
@@ -12995,7 +12970,7 @@
/* parameters */ &kParameters[894],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::saturate,
+ /* const eval */ &ConstEval::sin,
},
{
/* [390] */
@@ -13007,7 +12982,7 @@
/* parameters */ &kParameters[895],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::saturate,
+ /* const eval */ &ConstEval::sin,
},
{
/* [391] */
@@ -13019,7 +12994,7 @@
/* parameters */ &kParameters[896],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::sign,
+ /* const eval */ &ConstEval::sinh,
},
{
/* [392] */
@@ -13031,58 +13006,10 @@
/* parameters */ &kParameters[897],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::sign,
+ /* const eval */ &ConstEval::sinh,
},
{
/* [393] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[898],
- /* return matcher indices */ &kMatcherIndices[3],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::sin,
- },
- {
- /* [394] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[899],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::sin,
- },
- {
- /* [395] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[900],
- /* return matcher indices */ &kMatcherIndices[3],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::sinh,
- },
- {
- /* [396] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[901],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::sinh,
- },
- {
- /* [397] */
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -13094,7 +13021,7 @@
/* const eval */ &ConstEval::smoothstep,
},
{
- /* [398] */
+ /* [394] */
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13106,31 +13033,31 @@
/* const eval */ &ConstEval::smoothstep,
},
{
- /* [399] */
+ /* [395] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[902],
+ /* parameters */ &kParameters[898],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::sqrt,
},
{
- /* [400] */
+ /* [396] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[903],
+ /* parameters */ &kParameters[899],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::sqrt,
},
{
- /* [401] */
+ /* [397] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -13142,7 +13069,7 @@
/* const eval */ &ConstEval::step,
},
{
- /* [402] */
+ /* [398] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13154,16 +13081,64 @@
/* const eval */ &ConstEval::step,
},
{
+ /* [399] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[900],
+ /* return matcher indices */ &kMatcherIndices[3],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::tan,
+ },
+ {
+ /* [400] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[4],
+ /* parameters */ &kParameters[901],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::tan,
+ },
+ {
+ /* [401] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[902],
+ /* return matcher indices */ &kMatcherIndices[3],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::tanh,
+ },
+ {
+ /* [402] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[23],
+ /* template numbers */ &kTemplateNumbers[4],
+ /* parameters */ &kParameters[903],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::tanh,
+ },
+ {
/* [403] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[904],
+ /* parameters */ &kParameters[905],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::tan,
+ /* const eval */ &ConstEval::trunc,
},
{
/* [404] */
@@ -13172,89 +13147,41 @@
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[905],
+ /* parameters */ &kParameters[906],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::tan,
+ /* const eval */ &ConstEval::trunc,
},
{
/* [405] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
+ /* template types */ &kTemplateTypes[0],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[906],
- /* return matcher indices */ &kMatcherIndices[3],
+ /* parameters */ &kParameters[944],
+ /* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::tanh,
+ /* const eval */ nullptr,
},
{
/* [406] */
/* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[907],
- /* return matcher indices */ &kMatcherIndices[30],
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[37],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[945],
+ /* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::tanh,
+ /* const eval */ nullptr,
},
{
/* [407] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[909],
- /* return matcher indices */ &kMatcherIndices[3],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::trunc,
- },
- {
- /* [408] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[23],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[910],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::trunc,
- },
- {
- /* [409] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[0],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[948],
- /* return matcher indices */ &kMatcherIndices[101],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [410] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[949],
- /* return matcher indices */ &kMatcherIndices[101],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ nullptr,
- },
- {
- /* [411] */
/* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[519],
/* return matcher indices */ &kMatcherIndices[110],
@@ -13262,11 +13189,11 @@
/* const eval */ nullptr,
},
{
- /* [412] */
+ /* [408] */
/* num parameters */ 3,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[522],
/* return matcher indices */ &kMatcherIndices[110],
@@ -13274,79 +13201,79 @@
/* const eval */ nullptr,
},
{
- /* [413] */
+ /* [409] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[952],
+ /* parameters */ &kParameters[948],
/* return matcher indices */ &kMatcherIndices[35],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpNot,
},
{
- /* [414] */
+ /* [410] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 1,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[953],
+ /* parameters */ &kParameters[949],
/* return matcher indices */ &kMatcherIndices[33],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::OpNot,
},
{
+ /* [411] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[28],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[950],
+ /* return matcher indices */ &kMatcherIndices[3],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::OpComplement,
+ },
+ {
+ /* [412] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[28],
+ /* template numbers */ &kTemplateNumbers[4],
+ /* parameters */ &kParameters[951],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::OpComplement,
+ },
+ {
+ /* [413] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[29],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[952],
+ /* return matcher indices */ &kMatcherIndices[3],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::OpUnaryMinus,
+ },
+ {
+ /* [414] */
+ /* num parameters */ 1,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[29],
+ /* template numbers */ &kTemplateNumbers[4],
+ /* parameters */ &kParameters[953],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::OpUnaryMinus,
+ },
+ {
/* [415] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[28],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[954],
- /* return matcher indices */ &kMatcherIndices[3],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpComplement,
- },
- {
- /* [416] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[28],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[955],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpComplement,
- },
- {
- /* [417] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[29],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[956],
- /* return matcher indices */ &kMatcherIndices[3],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpUnaryMinus,
- },
- {
- /* [418] */
- /* num parameters */ 1,
- /* num template types */ 1,
- /* num template numbers */ 1,
- /* template types */ &kTemplateTypes[29],
- /* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[957],
- /* return matcher indices */ &kMatcherIndices[30],
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::OpUnaryMinus,
- },
- {
- /* [419] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -13358,7 +13285,7 @@
/* const eval */ &ConstEval::OpXor,
},
{
- /* [420] */
+ /* [416] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13370,7 +13297,7 @@
/* const eval */ &ConstEval::OpXor,
},
{
- /* [421] */
+ /* [417] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -13382,7 +13309,7 @@
/* const eval */ &ConstEval::OpEqual,
},
{
- /* [422] */
+ /* [418] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13394,7 +13321,7 @@
/* const eval */ &ConstEval::OpEqual,
},
{
- /* [423] */
+ /* [419] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -13406,7 +13333,7 @@
/* const eval */ &ConstEval::OpNotEqual,
},
{
- /* [424] */
+ /* [420] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13418,7 +13345,7 @@
/* const eval */ &ConstEval::OpNotEqual,
},
{
- /* [425] */
+ /* [421] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -13430,7 +13357,7 @@
/* const eval */ &ConstEval::OpLessThan,
},
{
- /* [426] */
+ /* [422] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13442,7 +13369,7 @@
/* const eval */ &ConstEval::OpLessThan,
},
{
- /* [427] */
+ /* [423] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -13454,7 +13381,7 @@
/* const eval */ &ConstEval::OpGreaterThan,
},
{
- /* [428] */
+ /* [424] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13466,7 +13393,7 @@
/* const eval */ &ConstEval::OpGreaterThan,
},
{
- /* [429] */
+ /* [425] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -13478,7 +13405,7 @@
/* const eval */ &ConstEval::OpLessThanEqual,
},
{
- /* [430] */
+ /* [426] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13490,7 +13417,7 @@
/* const eval */ &ConstEval::OpLessThanEqual,
},
{
- /* [431] */
+ /* [427] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -13502,7 +13429,7 @@
/* const eval */ &ConstEval::OpGreaterThanEqual,
},
{
- /* [432] */
+ /* [428] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13514,43 +13441,67 @@
/* const eval */ &ConstEval::OpGreaterThanEqual,
},
{
- /* [433] */
+ /* [429] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[28],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[774],
+ /* return matcher indices */ &kMatcherIndices[3],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::OpShiftLeft,
+ },
+ {
+ /* [430] */
+ /* num parameters */ 2,
+ /* num template types */ 1,
+ /* num template numbers */ 1,
+ /* template types */ &kTemplateTypes[28],
+ /* template numbers */ &kTemplateNumbers[4],
+ /* parameters */ &kParameters[776],
+ /* return matcher indices */ &kMatcherIndices[30],
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::OpShiftLeft,
+ },
+ {
+ /* [431] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[25],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[782],
+ /* parameters */ &kParameters[778],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
- /* [434] */
+ /* [432] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[25],
/* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[784],
+ /* parameters */ &kParameters[780],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
- /* [435] */
+ /* [433] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[8],
- /* parameters */ &kParameters[814],
+ /* parameters */ &kParameters[810],
/* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
- /* [436] */
+ /* [434] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 0,
@@ -13562,19 +13513,19 @@
/* const eval */ &ConstEval::cross,
},
{
- /* [437] */
+ /* [435] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[837],
+ /* parameters */ &kParameters[833],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::determinant,
},
{
- /* [438] */
+ /* [436] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13586,11 +13537,11 @@
/* const eval */ &ConstEval::dot,
},
{
- /* [439] */
+ /* [437] */
/* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[606],
/* return matcher indices */ &kMatcherIndices[9],
@@ -13598,11 +13549,11 @@
/* const eval */ nullptr,
},
{
- /* [440] */
+ /* [438] */
/* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[608],
/* return matcher indices */ &kMatcherIndices[101],
@@ -13610,7 +13561,7 @@
/* const eval */ nullptr,
},
{
- /* [441] */
+ /* [439] */
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13622,79 +13573,79 @@
/* const eval */ &ConstEval::faceForward,
},
{
- /* [442] */
+ /* [440] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[4],
- /* parameters */ &kParameters[880],
+ /* parameters */ &kParameters[876],
/* return matcher indices */ &kMatcherIndices[30],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::normalize,
},
{
+ /* [441] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[37],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[877],
+ /* return matcher indices */ &kMatcherIndices[101],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::pack2x16float,
+ },
+ {
+ /* [442] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[37],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[878],
+ /* return matcher indices */ &kMatcherIndices[101],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::pack2x16snorm,
+ },
+ {
/* [443] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[881],
+ /* parameters */ &kParameters[879],
/* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::pack2x16float,
+ /* const eval */ &ConstEval::pack2x16unorm,
},
{
/* [444] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[882],
+ /* parameters */ &kParameters[880],
/* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::pack2x16snorm,
+ /* const eval */ &ConstEval::pack4x8snorm,
},
{
/* [445] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[883],
- /* return matcher indices */ &kMatcherIndices[101],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::pack2x16unorm,
- },
- {
- /* [446] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[884],
- /* return matcher indices */ &kMatcherIndices[101],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::pack4x8snorm,
- },
- {
- /* [447] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[885],
+ /* parameters */ &kParameters[881],
/* return matcher indices */ &kMatcherIndices[101],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::pack4x8unorm,
},
{
- /* [448] */
+ /* [446] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13706,7 +13657,7 @@
/* const eval */ &ConstEval::reflect,
},
{
- /* [449] */
+ /* [447] */
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13718,115 +13669,115 @@
/* const eval */ &ConstEval::refract,
},
{
- /* [450] */
+ /* [448] */
/* num parameters */ 0,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1016],
+ /* parameters */ &kParameters[1012],
/* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
- /* [451] */
+ /* [449] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 2,
/* template types */ &kTemplateTypes[23],
/* template numbers */ &kTemplateNumbers[3],
- /* parameters */ &kParameters[908],
+ /* parameters */ &kParameters[904],
/* return matcher indices */ &kMatcherIndices[18],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::transpose,
},
{
+ /* [450] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[37],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[907],
+ /* return matcher indices */ &kMatcherIndices[108],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::unpack2x16float,
+ },
+ {
+ /* [451] */
+ /* num parameters */ 1,
+ /* num template types */ 0,
+ /* num template numbers */ 0,
+ /* template types */ &kTemplateTypes[37],
+ /* template numbers */ &kTemplateNumbers[10],
+ /* parameters */ &kParameters[908],
+ /* return matcher indices */ &kMatcherIndices[108],
+ /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
+ /* const eval */ &ConstEval::unpack2x16snorm,
+ },
+ {
/* [452] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[911],
+ /* parameters */ &kParameters[909],
/* return matcher indices */ &kMatcherIndices[108],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::unpack2x16float,
+ /* const eval */ &ConstEval::unpack2x16unorm,
},
{
/* [453] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[912],
- /* return matcher indices */ &kMatcherIndices[108],
+ /* parameters */ &kParameters[910],
+ /* return matcher indices */ &kMatcherIndices[110],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::unpack2x16snorm,
+ /* const eval */ &ConstEval::unpack4x8snorm,
},
{
/* [454] */
/* num parameters */ 1,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[913],
- /* return matcher indices */ &kMatcherIndices[108],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::unpack2x16unorm,
- },
- {
- /* [455] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[914],
- /* return matcher indices */ &kMatcherIndices[110],
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* const eval */ &ConstEval::unpack4x8snorm,
- },
- {
- /* [456] */
- /* num parameters */ 1,
- /* num template types */ 0,
- /* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
- /* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[915],
+ /* parameters */ &kParameters[911],
/* return matcher indices */ &kMatcherIndices[110],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::unpack4x8unorm,
},
{
- /* [457] */
+ /* [455] */
/* num parameters */ 0,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[1016],
+ /* parameters */ &kParameters[1012],
/* return matcher indices */ nullptr,
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
- /* [458] */
+ /* [456] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 1,
/* template types */ &kTemplateTypes[25],
/* template numbers */ &kTemplateNumbers[9],
- /* parameters */ &kParameters[950],
+ /* parameters */ &kParameters[946],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ nullptr,
},
{
- /* [459] */
+ /* [457] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13838,7 +13789,7 @@
/* const eval */ nullptr,
},
{
- /* [460] */
+ /* [458] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13850,7 +13801,7 @@
/* const eval */ nullptr,
},
{
- /* [461] */
+ /* [459] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13862,7 +13813,7 @@
/* const eval */ nullptr,
},
{
- /* [462] */
+ /* [460] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13874,7 +13825,7 @@
/* const eval */ nullptr,
},
{
- /* [463] */
+ /* [461] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13886,7 +13837,7 @@
/* const eval */ nullptr,
},
{
- /* [464] */
+ /* [462] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13898,7 +13849,7 @@
/* const eval */ nullptr,
},
{
- /* [465] */
+ /* [463] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13910,7 +13861,7 @@
/* const eval */ nullptr,
},
{
- /* [466] */
+ /* [464] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13922,7 +13873,7 @@
/* const eval */ nullptr,
},
{
- /* [467] */
+ /* [465] */
/* num parameters */ 2,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13934,7 +13885,7 @@
/* const eval */ nullptr,
},
{
- /* [468] */
+ /* [466] */
/* num parameters */ 3,
/* num template types */ 1,
/* num template numbers */ 1,
@@ -13946,23 +13897,23 @@
/* const eval */ nullptr,
},
{
- /* [469] */
+ /* [467] */
/* num parameters */ 1,
/* num template types */ 1,
/* num template numbers */ 0,
/* template types */ &kTemplateTypes[24],
/* template numbers */ &kTemplateNumbers[10],
- /* parameters */ &kParameters[951],
+ /* parameters */ &kParameters[947],
/* return matcher indices */ &kMatcherIndices[3],
/* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
/* const eval */ &ConstEval::Identity,
},
{
- /* [470] */
+ /* [468] */
/* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[746],
/* return matcher indices */ &kMatcherIndices[35],
@@ -13970,11 +13921,11 @@
/* const eval */ nullptr,
},
{
- /* [471] */
+ /* [469] */
/* num parameters */ 2,
/* num template types */ 0,
/* num template numbers */ 0,
- /* template types */ &kTemplateTypes[38],
+ /* template types */ &kTemplateTypes[37],
/* template numbers */ &kTemplateNumbers[10],
/* parameters */ &kParameters[748],
/* return matcher indices */ &kMatcherIndices[35],
@@ -13989,357 +13940,357 @@
/* fn abs<T : fia_fiu32_f16>(T) -> T */
/* fn abs<N : num, T : fia_fiu32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[287],
+ /* overloads */ &kOverloads[283],
},
{
/* [1] */
/* fn acos<T : fa_f32_f16>(@test_value(0.96891242171) T) -> T */
/* fn acos<N : num, T : fa_f32_f16>(@test_value(0.96891242171) vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[289],
+ /* overloads */ &kOverloads[285],
},
{
/* [2] */
/* fn acosh<T : fa_f32_f16>(@test_value(2) T) -> T */
/* fn acosh<N : num, T : fa_f32_f16>(@test_value(2) vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[291],
+ /* overloads */ &kOverloads[287],
},
{
/* [3] */
/* fn all(bool) -> bool */
/* fn all<N : num>(vec<N, bool>) -> bool */
/* num overloads */ 2,
- /* overloads */ &kOverloads[293],
+ /* overloads */ &kOverloads[289],
},
{
/* [4] */
/* fn any(bool) -> bool */
/* fn any<N : num>(vec<N, bool>) -> bool */
/* num overloads */ 2,
- /* overloads */ &kOverloads[295],
+ /* overloads */ &kOverloads[291],
},
{
/* [5] */
/* fn arrayLength<T, A : access>(ptr<storage, array<T>, A>) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[435],
+ /* overloads */ &kOverloads[433],
},
{
/* [6] */
/* fn asin<T : fa_f32_f16>(@test_value(0.479425538604) T) -> T */
/* fn asin<N : num, T : fa_f32_f16>(@test_value(0.479425538604) vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[297],
+ /* overloads */ &kOverloads[293],
},
{
/* [7] */
/* fn asinh<T : fa_f32_f16>(T) -> T */
/* fn asinh<N : num, T : fa_f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[299],
+ /* overloads */ &kOverloads[295],
},
{
/* [8] */
/* fn atan<T : fa_f32_f16>(T) -> T */
/* fn atan<N : num, T : fa_f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[301],
+ /* overloads */ &kOverloads[297],
},
{
/* [9] */
/* fn atan2<T : fa_f32_f16>(T, T) -> T */
/* fn atan2<T : fa_f32_f16, N : num>(vec<N, T>, vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[303],
+ /* overloads */ &kOverloads[299],
},
{
/* [10] */
/* fn atanh<T : fa_f32_f16>(@test_value(0.5) T) -> T */
/* fn atanh<N : num, T : fa_f32_f16>(@test_value(0.5) vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[305],
+ /* overloads */ &kOverloads[301],
},
{
/* [11] */
/* fn ceil<T : fa_f32_f16>(@test_value(1.5) T) -> T */
/* fn ceil<N : num, T : fa_f32_f16>(@test_value(1.5) vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[307],
+ /* overloads */ &kOverloads[303],
},
{
/* [12] */
/* fn clamp<T : fia_fiu32_f16>(T, T, T) -> T */
/* fn clamp<T : fia_fiu32_f16, N : num>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[309],
+ /* overloads */ &kOverloads[305],
},
{
/* [13] */
/* fn cos<T : fa_f32_f16>(@test_value(0) T) -> T */
/* fn cos<N : num, T : fa_f32_f16>(@test_value(0) vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[311],
+ /* overloads */ &kOverloads[307],
},
{
/* [14] */
/* fn cosh<T : fa_f32_f16>(@test_value(0) T) -> T */
/* fn cosh<N : num, T : fa_f32_f16>(@test_value(0) vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[313],
+ /* overloads */ &kOverloads[309],
},
{
/* [15] */
/* fn countLeadingZeros<T : iu32>(T) -> T */
/* fn countLeadingZeros<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[315],
+ /* overloads */ &kOverloads[311],
},
{
/* [16] */
/* fn countOneBits<T : iu32>(T) -> T */
/* fn countOneBits<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[317],
+ /* overloads */ &kOverloads[313],
},
{
/* [17] */
/* fn countTrailingZeros<T : iu32>(T) -> T */
/* fn countTrailingZeros<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[319],
+ /* overloads */ &kOverloads[315],
},
{
/* [18] */
/* fn cross<T : fa_f32_f16>(vec3<T>, vec3<T>) -> vec3<T> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[436],
+ /* overloads */ &kOverloads[434],
},
{
/* [19] */
/* fn degrees<T : fa_f32_f16>(T) -> T */
/* fn degrees<N : num, T : fa_f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[321],
+ /* overloads */ &kOverloads[317],
},
{
/* [20] */
/* fn determinant<N : num, T : fa_f32_f16>(mat<N, N, T>) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[437],
+ /* overloads */ &kOverloads[435],
},
{
/* [21] */
/* fn distance<T : fa_f32_f16>(T, T) -> T */
/* fn distance<N : num, T : fa_f32_f16>(vec<N, T>, vec<N, T>) -> T */
/* num overloads */ 2,
- /* overloads */ &kOverloads[323],
+ /* overloads */ &kOverloads[319],
},
{
/* [22] */
/* fn dot<N : num, T : fia_fiu32_f16>(vec<N, T>, vec<N, T>) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[438],
+ /* overloads */ &kOverloads[436],
},
{
/* [23] */
/* fn dot4I8Packed(u32, u32) -> i32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[439],
+ /* overloads */ &kOverloads[437],
},
{
/* [24] */
/* fn dot4U8Packed(u32, u32) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[440],
+ /* overloads */ &kOverloads[438],
},
{
/* [25] */
/* fn dpdx(f32) -> f32 */
/* fn dpdx<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[325],
+ /* overloads */ &kOverloads[321],
},
{
/* [26] */
/* fn dpdxCoarse(f32) -> f32 */
/* fn dpdxCoarse<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[327],
+ /* overloads */ &kOverloads[323],
},
{
/* [27] */
/* fn dpdxFine(f32) -> f32 */
/* fn dpdxFine<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[329],
+ /* overloads */ &kOverloads[325],
},
{
/* [28] */
/* fn dpdy(f32) -> f32 */
/* fn dpdy<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[331],
+ /* overloads */ &kOverloads[327],
},
{
/* [29] */
/* fn dpdyCoarse(f32) -> f32 */
/* fn dpdyCoarse<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[333],
+ /* overloads */ &kOverloads[329],
},
{
/* [30] */
/* fn dpdyFine(f32) -> f32 */
/* fn dpdyFine<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[335],
+ /* overloads */ &kOverloads[331],
},
{
/* [31] */
/* fn exp<T : fa_f32_f16>(T) -> T */
/* fn exp<N : num, T : fa_f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[337],
+ /* overloads */ &kOverloads[333],
},
{
/* [32] */
/* fn exp2<T : fa_f32_f16>(T) -> T */
/* fn exp2<N : num, T : fa_f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[339],
+ /* overloads */ &kOverloads[335],
},
{
/* [33] */
/* fn extractBits<T : iu32>(T, u32, u32) -> T */
/* fn extractBits<N : num, T : iu32>(vec<N, T>, u32, u32) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[341],
+ /* overloads */ &kOverloads[337],
},
{
/* [34] */
/* fn faceForward<N : num, T : fa_f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[441],
+ /* overloads */ &kOverloads[439],
},
{
/* [35] */
/* fn firstLeadingBit<T : iu32>(T) -> T */
/* fn firstLeadingBit<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[343],
+ /* overloads */ &kOverloads[339],
},
{
/* [36] */
/* fn firstTrailingBit<T : iu32>(T) -> T */
/* fn firstTrailingBit<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[345],
+ /* overloads */ &kOverloads[341],
},
{
/* [37] */
/* fn floor<T : fa_f32_f16>(@test_value(1.5) T) -> T */
/* fn floor<N : num, T : fa_f32_f16>(@test_value(1.5) vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[347],
+ /* overloads */ &kOverloads[343],
},
{
/* [38] */
/* fn fma<T : fa_f32_f16>(T, T, T) -> T */
/* fn fma<N : num, T : fa_f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[349],
+ /* overloads */ &kOverloads[345],
},
{
/* [39] */
/* fn fract<T : f32_f16>(T) -> T */
/* fn fract<N : num, T : f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[351],
+ /* overloads */ &kOverloads[347],
},
{
/* [40] */
/* fn frexp<T : fa_f32_f16>(T) -> __frexp_result<T> */
/* fn frexp<N : num, T : fa_f32_f16>(vec<N, T>) -> __frexp_result_vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[353],
+ /* overloads */ &kOverloads[349],
},
{
/* [41] */
/* fn fwidth(f32) -> f32 */
/* fn fwidth<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[355],
+ /* overloads */ &kOverloads[351],
},
{
/* [42] */
/* fn fwidthCoarse(f32) -> f32 */
/* fn fwidthCoarse<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[357],
+ /* overloads */ &kOverloads[353],
},
{
/* [43] */
/* fn fwidthFine(f32) -> f32 */
/* fn fwidthFine<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[359],
+ /* overloads */ &kOverloads[355],
},
{
/* [44] */
/* fn insertBits<T : iu32>(T, T, u32, u32) -> T */
/* fn insertBits<N : num, T : iu32>(vec<N, T>, vec<N, T>, u32, u32) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[361],
+ /* overloads */ &kOverloads[357],
},
{
/* [45] */
/* fn inverseSqrt<T : fa_f32_f16>(T) -> T */
/* fn inverseSqrt<N : num, T : fa_f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[363],
+ /* overloads */ &kOverloads[359],
},
{
/* [46] */
/* fn ldexp<T : f32_f16>(T, i32) -> T */
/* fn ldexp<N : num, T : f32_f16>(vec<N, T>, vec<N, i32>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[365],
+ /* overloads */ &kOverloads[361],
},
{
/* [47] */
/* fn length<T : fa_f32_f16>(@test_value(0) T) -> T */
/* fn length<N : num, T : fa_f32_f16>(@test_value(0) vec<N, T>) -> T */
/* num overloads */ 2,
- /* overloads */ &kOverloads[367],
+ /* overloads */ &kOverloads[363],
},
{
/* [48] */
/* fn log<T : fa_f32_f16>(T) -> T */
/* fn log<N : num, T : fa_f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[369],
+ /* overloads */ &kOverloads[365],
},
{
/* [49] */
/* fn log2<T : fa_f32_f16>(T) -> T */
/* fn log2<N : num, T : fa_f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[371],
+ /* overloads */ &kOverloads[367],
},
{
/* [50] */
/* fn max<T : fia_fiu32_f16>(T, T) -> T */
/* fn max<N : num, T : fia_fiu32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[373],
+ /* overloads */ &kOverloads[369],
},
{
/* [51] */
/* fn min<T : fia_fiu32_f16>(T, T) -> T */
/* fn min<N : num, T : fia_fiu32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[375],
+ /* overloads */ &kOverloads[371],
},
{
/* [52] */
@@ -14347,104 +14298,104 @@
/* fn mix<N : num, T : f32_f16>(vec<N, T>, vec<N, T>, vec<N, T>) -> vec<N, T> */
/* fn mix<N : num, T : f32_f16>(vec<N, T>, vec<N, T>, T) -> vec<N, T> */
/* num overloads */ 3,
- /* overloads */ &kOverloads[266],
+ /* overloads */ &kOverloads[262],
},
{
/* [53] */
/* fn modf<T : fa_f32_f16>(@test_value(-1.5) T) -> __modf_result<T> */
/* fn modf<N : num, T : fa_f32_f16>(@test_value(-1.5) vec<N, T>) -> __modf_result_vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[377],
+ /* overloads */ &kOverloads[373],
},
{
/* [54] */
/* fn normalize<N : num, T : fa_f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[442],
+ /* overloads */ &kOverloads[440],
},
{
/* [55] */
/* fn pack2x16float(vec2<f32>) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[443],
+ /* overloads */ &kOverloads[441],
},
{
/* [56] */
/* fn pack2x16snorm(vec2<f32>) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[444],
+ /* overloads */ &kOverloads[442],
},
{
/* [57] */
/* fn pack2x16unorm(vec2<f32>) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[445],
+ /* overloads */ &kOverloads[443],
},
{
/* [58] */
/* fn pack4x8snorm(vec4<f32>) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[446],
+ /* overloads */ &kOverloads[444],
},
{
/* [59] */
/* fn pack4x8unorm(vec4<f32>) -> u32 */
/* num overloads */ 1,
- /* overloads */ &kOverloads[447],
+ /* overloads */ &kOverloads[445],
},
{
/* [60] */
/* fn pow<T : f32_f16>(T, T) -> T */
/* fn pow<N : num, T : f32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[379],
+ /* overloads */ &kOverloads[375],
},
{
/* [61] */
/* fn quantizeToF16(f32) -> f32 */
/* fn quantizeToF16<N : num>(vec<N, f32>) -> vec<N, f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[381],
+ /* overloads */ &kOverloads[377],
},
{
/* [62] */
/* fn radians<T : fa_f32_f16>(T) -> T */
/* fn radians<N : num, T : fa_f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[383],
+ /* overloads */ &kOverloads[379],
},
{
/* [63] */
/* fn reflect<N : num, T : fa_f32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[448],
+ /* overloads */ &kOverloads[446],
},
{
/* [64] */
/* fn refract<N : num, T : fa_f32_f16>(vec<N, T>, vec<N, T>, T) -> vec<N, T> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[449],
+ /* overloads */ &kOverloads[447],
},
{
/* [65] */
/* fn reverseBits<T : iu32>(T) -> T */
/* fn reverseBits<N : num, T : iu32>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[385],
+ /* overloads */ &kOverloads[381],
},
{
/* [66] */
/* fn round<T : fa_f32_f16>(@test_value(3.4) T) -> T */
/* fn round<N : num, T : fa_f32_f16>(@test_value(3.4) vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[387],
+ /* overloads */ &kOverloads[383],
},
{
/* [67] */
/* fn saturate<T : fa_f32_f16>(@test_value(2) T) -> T */
/* fn saturate<T : fa_f32_f16, N : num>(@test_value(2) vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[389],
+ /* overloads */ &kOverloads[385],
},
{
/* [68] */
@@ -14452,118 +14403,118 @@
/* fn select<T : scalar, N : num>(vec<N, T>, vec<N, T>, bool) -> vec<N, T> */
/* fn select<N : num, T : scalar>(vec<N, T>, vec<N, T>, vec<N, bool>) -> vec<N, T> */
/* num overloads */ 3,
- /* overloads */ &kOverloads[269],
+ /* overloads */ &kOverloads[265],
},
{
/* [69] */
/* fn sign<T : fa_f32_f16>(T) -> T */
/* fn sign<N : num, T : fa_f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[391],
+ /* overloads */ &kOverloads[387],
},
{
/* [70] */
/* fn sin<T : fa_f32_f16>(T) -> T */
/* fn sin<N : num, T : fa_f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[393],
+ /* overloads */ &kOverloads[389],
},
{
/* [71] */
/* fn sinh<T : fa_f32_f16>(T) -> T */
/* fn sinh<N : num, T : fa_f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[395],
+ /* overloads */ &kOverloads[391],
},
{
/* [72] */
/* fn smoothstep<T : fa_f32_f16>(@test_value(2) T, @test_value(4) T, @test_value(3) T) -> T */
/* fn smoothstep<N : num, T : fa_f32_f16>(@test_value(2) vec<N, T>, @test_value(4) vec<N, T>, @test_value(3) vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[397],
+ /* overloads */ &kOverloads[393],
},
{
/* [73] */
/* fn sqrt<T : fa_f32_f16>(T) -> T */
/* fn sqrt<N : num, T : fa_f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[399],
+ /* overloads */ &kOverloads[395],
},
{
/* [74] */
/* fn step<T : fa_f32_f16>(T, T) -> T */
/* fn step<N : num, T : fa_f32_f16>(vec<N, T>, vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[401],
+ /* overloads */ &kOverloads[397],
},
{
/* [75] */
/* fn storageBarrier() */
/* num overloads */ 1,
- /* overloads */ &kOverloads[450],
+ /* overloads */ &kOverloads[448],
},
{
/* [76] */
/* fn tan<T : fa_f32_f16>(T) -> T */
/* fn tan<N : num, T : fa_f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[403],
+ /* overloads */ &kOverloads[399],
},
{
/* [77] */
/* fn tanh<T : fa_f32_f16>(T) -> T */
/* fn tanh<N : num, T : fa_f32_f16>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[405],
+ /* overloads */ &kOverloads[401],
},
{
/* [78] */
/* fn transpose<M : num, N : num, T : fa_f32_f16>(mat<M, N, T>) -> mat<N, M, T> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[451],
+ /* overloads */ &kOverloads[449],
},
{
/* [79] */
/* fn trunc<T : fa_f32_f16>(@test_value(1.5) T) -> T */
/* fn trunc<N : num, T : fa_f32_f16>(@test_value(1.5) vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[407],
+ /* overloads */ &kOverloads[403],
},
{
/* [80] */
/* fn unpack2x16float(u32) -> vec2<f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[452],
+ /* overloads */ &kOverloads[450],
},
{
/* [81] */
/* fn unpack2x16snorm(u32) -> vec2<f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[453],
+ /* overloads */ &kOverloads[451],
},
{
/* [82] */
/* fn unpack2x16unorm(u32) -> vec2<f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[454],
+ /* overloads */ &kOverloads[452],
},
{
/* [83] */
/* fn unpack4x8snorm(u32) -> vec4<f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[455],
+ /* overloads */ &kOverloads[453],
},
{
/* [84] */
/* fn unpack4x8unorm(u32) -> vec4<f32> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[456],
+ /* overloads */ &kOverloads[454],
},
{
/* [85] */
/* fn workgroupBarrier() */
/* num overloads */ 1,
- /* overloads */ &kOverloads[457],
+ /* overloads */ &kOverloads[455],
},
{
/* [86] */
@@ -14655,7 +14606,7 @@
/* fn textureNumSamples<T : fiu32>(texture: texture_multisampled_2d<T>) -> u32 */
/* fn textureNumSamples(texture: texture_depth_multisampled_2d) -> u32 */
/* num overloads */ 2,
- /* overloads */ &kOverloads[409],
+ /* overloads */ &kOverloads[405],
},
{
/* [92] */
@@ -14749,7 +14700,7 @@
/* fn textureSampleBaseClampToEdge(texture: texture_2d<f32>, sampler: sampler, coords: vec2<f32>) -> vec4<f32> */
/* fn textureSampleBaseClampToEdge(texture: texture_external, sampler: sampler, coords: vec2<f32>) -> vec4<f32> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[411],
+ /* overloads */ &kOverloads[407],
},
{
/* [99] */
@@ -14786,73 +14737,73 @@
/* [101] */
/* fn atomicLoad<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[458],
+ /* overloads */ &kOverloads[456],
},
{
/* [102] */
/* fn atomicStore<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) */
/* num overloads */ 1,
- /* overloads */ &kOverloads[459],
+ /* overloads */ &kOverloads[457],
},
{
/* [103] */
/* fn atomicAdd<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[460],
+ /* overloads */ &kOverloads[458],
},
{
/* [104] */
/* fn atomicSub<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[461],
+ /* overloads */ &kOverloads[459],
},
{
/* [105] */
/* fn atomicMax<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[462],
+ /* overloads */ &kOverloads[460],
},
{
/* [106] */
/* fn atomicMin<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[463],
+ /* overloads */ &kOverloads[461],
},
{
/* [107] */
/* fn atomicAnd<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[464],
+ /* overloads */ &kOverloads[462],
},
{
/* [108] */
/* fn atomicOr<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[465],
+ /* overloads */ &kOverloads[463],
},
{
/* [109] */
/* fn atomicXor<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[466],
+ /* overloads */ &kOverloads[464],
},
{
/* [110] */
/* fn atomicExchange<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[467],
+ /* overloads */ &kOverloads[465],
},
{
/* [111] */
/* fn atomicCompareExchangeWeak<T : iu32, S : workgroup_or_storage>(ptr<S, atomic<T>, read_write>, T, T) -> __atomic_compare_exchange_result<T> */
/* num overloads */ 1,
- /* overloads */ &kOverloads[468],
+ /* overloads */ &kOverloads[466],
},
{
/* [112] */
/* fn _tint_materialize<T>(T) -> T */
/* num overloads */ 1,
- /* overloads */ &kOverloads[469],
+ /* overloads */ &kOverloads[467],
},
};
@@ -14862,21 +14813,21 @@
/* op !(bool) -> bool */
/* op !<N : num>(vec<N, bool>) -> vec<N, bool> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[413],
+ /* overloads */ &kOverloads[409],
},
{
/* [1] */
/* op ~<T : ia_iu32>(T) -> T */
/* op ~<T : ia_iu32, N : num>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[415],
+ /* overloads */ &kOverloads[411],
},
{
/* [2] */
/* op -<T : fia_fi32_f16>(T) -> T */
/* op -<T : fia_fi32_f16, N : num>(vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[417],
+ /* overloads */ &kOverloads[413],
},
};
constexpr uint8_t kUnaryOperatorNot = 0;
@@ -14929,10 +14880,10 @@
},
{
/* [4] */
- /* op %<T : fiu32_f16>(T, T) -> T */
- /* op %<T : fiu32_f16, N : num>(vec<N, T>, vec<N, T>) -> vec<N, T> */
- /* op %<T : fiu32_f16, N : num>(vec<N, T>, T) -> vec<N, T> */
- /* op %<T : fiu32_f16, N : num>(T, vec<N, T>) -> vec<N, T> */
+ /* op %<T : fia_fiu32_f16>(T, T) -> T */
+ /* op %<T : fia_fiu32_f16, N : num>(vec<N, T>, vec<N, T>) -> vec<N, T> */
+ /* op %<T : fia_fiu32_f16, N : num>(vec<N, T>, T) -> vec<N, T> */
+ /* op %<T : fia_fiu32_f16, N : num>(T, vec<N, T>) -> vec<N, T> */
/* num overloads */ 4,
/* overloads */ &kOverloads[250],
},
@@ -14941,7 +14892,7 @@
/* op ^<T : ia_iu32>(T, T) -> T */
/* op ^<T : ia_iu32, N : num>(vec<N, T>, vec<N, T>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[419],
+ /* overloads */ &kOverloads[415],
},
{
/* [6] */
@@ -14965,71 +14916,69 @@
/* [8] */
/* op &&(bool, bool) -> bool */
/* num overloads */ 1,
- /* overloads */ &kOverloads[470],
+ /* overloads */ &kOverloads[468],
},
{
/* [9] */
/* op ||(bool, bool) -> bool */
/* num overloads */ 1,
- /* overloads */ &kOverloads[471],
+ /* overloads */ &kOverloads[469],
},
{
/* [10] */
/* op ==<T : scalar>(T, T) -> bool */
/* op ==<T : scalar, N : num>(vec<N, T>, vec<N, T>) -> vec<N, bool> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[421],
+ /* overloads */ &kOverloads[417],
},
{
/* [11] */
/* op !=<T : scalar>(T, T) -> bool */
/* op !=<T : scalar, N : num>(vec<N, T>, vec<N, T>) -> vec<N, bool> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[423],
+ /* overloads */ &kOverloads[419],
},
{
/* [12] */
/* op <<T : fia_fiu32_f16>(T, T) -> bool */
/* op <<T : fia_fiu32_f16, N : num>(vec<N, T>, vec<N, T>) -> vec<N, bool> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[425],
+ /* overloads */ &kOverloads[421],
},
{
/* [13] */
/* op ><T : fia_fiu32_f16>(T, T) -> bool */
/* op ><T : fia_fiu32_f16, N : num>(vec<N, T>, vec<N, T>) -> vec<N, bool> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[427],
+ /* overloads */ &kOverloads[423],
},
{
/* [14] */
/* op <=<T : fia_fiu32_f16>(T, T) -> bool */
/* op <=<T : fia_fiu32_f16, N : num>(vec<N, T>, vec<N, T>) -> vec<N, bool> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[429],
+ /* overloads */ &kOverloads[425],
},
{
/* [15] */
/* op >=<T : fia_fiu32_f16>(T, T) -> bool */
/* op >=<T : fiu32_f16, N : num>(vec<N, T>, vec<N, T>) -> vec<N, bool> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[431],
+ /* overloads */ &kOverloads[427],
},
{
/* [16] */
- /* op <<<T : iu32>(T, u32) -> T */
- /* op <<<T : iu32, N : num>(vec<N, T>, vec<N, u32>) -> vec<N, T> */
- /* op <<<T : ia>(T, u32) -> T */
- /* op <<<T : ia, N : num>(vec<N, T>, vec<N, u32>) -> vec<N, T> */
- /* num overloads */ 4,
- /* overloads */ &kOverloads[262],
+ /* op <<<T : ia_iu32>(T, u32) -> T */
+ /* op <<<T : ia_iu32, N : num>(vec<N, T>, vec<N, u32>) -> vec<N, T> */
+ /* num overloads */ 2,
+ /* overloads */ &kOverloads[429],
},
{
/* [17] */
/* op >><T : iu32>(T, u32) -> T */
/* op >><T : iu32, N : num>(vec<N, T>, vec<N, u32>) -> vec<N, T> */
/* num overloads */ 2,
- /* overloads */ &kOverloads[433],
+ /* overloads */ &kOverloads[431],
},
};
constexpr uint8_t kBinaryOperatorPlus = 0;
@@ -15058,7 +15007,7 @@
/* init i32(i32) -> i32 */
/* conv i32<T : scalar_no_i32>(T) -> i32 */
/* num overloads */ 3,
- /* overloads */ &kOverloads[272],
+ /* overloads */ &kOverloads[268],
},
{
/* [1] */
@@ -15066,7 +15015,7 @@
/* init u32(u32) -> u32 */
/* conv u32<T : scalar_no_u32>(T) -> u32 */
/* num overloads */ 3,
- /* overloads */ &kOverloads[275],
+ /* overloads */ &kOverloads[271],
},
{
/* [2] */
@@ -15074,7 +15023,7 @@
/* init f32(f32) -> f32 */
/* conv f32<T : scalar_no_f32>(T) -> f32 */
/* num overloads */ 3,
- /* overloads */ &kOverloads[278],
+ /* overloads */ &kOverloads[274],
},
{
/* [3] */
@@ -15082,7 +15031,7 @@
/* init f16(f16) -> f16 */
/* conv f16<T : scalar_no_f16>(T) -> f16 */
/* num overloads */ 3,
- /* overloads */ &kOverloads[281],
+ /* overloads */ &kOverloads[277],
},
{
/* [4] */
@@ -15090,7 +15039,7 @@
/* init bool(bool) -> bool */
/* conv bool<T : scalar_no_bool>(T) -> bool */
/* num overloads */ 3,
- /* overloads */ &kOverloads[284],
+ /* overloads */ &kOverloads[280],
},
{
/* [5] */
diff --git a/src/tint/resolver/intrinsic_table_test.cc b/src/tint/resolver/intrinsic_table_test.cc
index 1608aa2..03255df 100644
--- a/src/tint/resolver/intrinsic_table_test.cc
+++ b/src/tint/resolver/intrinsic_table_test.cc
@@ -252,7 +252,8 @@
}
TEST_F(IntrinsicTableTest, MatchArray) {
- auto* arr = create<sem::Array>(create<sem::U32>(), sem::RuntimeArrayCount{}, 4u, 4u, 4u, 4u);
+ auto* arr =
+ create<sem::Array>(create<sem::U32>(), create<sem::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
auto* arr_ptr = create<sem::Pointer>(arr, ast::AddressSpace::kStorage, ast::Access::kReadWrite);
auto result = table->Lookup(BuiltinType::kArrayLength, utils::Vector{arr_ptr},
sem::EvaluationStage::kConstant, Source{});
@@ -955,7 +956,8 @@
}
TEST_F(IntrinsicTableTest, MismatchTypeConversion) {
- auto* arr = create<sem::Array>(create<sem::U32>(), sem::RuntimeArrayCount{}, 4u, 4u, 4u, 4u);
+ auto* arr =
+ create<sem::Array>(create<sem::U32>(), create<sem::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
auto* f32 = create<sem::F32>();
auto result = table->Lookup(InitConvIntrinsic::kVec3, f32, utils::Vector{arr},
sem::EvaluationStage::kConstant, Source{{12, 34}});
diff --git a/src/tint/resolver/is_host_shareable_test.cc b/src/tint/resolver/is_host_shareable_test.cc
index ab969fa..5e1555b 100644
--- a/src/tint/resolver/is_host_shareable_test.cc
+++ b/src/tint/resolver/is_host_shareable_test.cc
@@ -106,13 +106,14 @@
}
TEST_F(ResolverIsHostShareable, ArraySizedOfHostShareable) {
- auto* arr =
- create<sem::Array>(create<sem::I32>(), sem::ConstantArrayCount{5u}, 4u, 20u, 4u, 4u);
+ auto* arr = create<sem::Array>(create<sem::I32>(), create<sem::ConstantArrayCount>(5u), 4u, 20u,
+ 4u, 4u);
EXPECT_TRUE(r()->IsHostShareable(arr));
}
TEST_F(ResolverIsHostShareable, ArrayUnsizedOfHostShareable) {
- auto* arr = create<sem::Array>(create<sem::I32>(), sem::RuntimeArrayCount{}, 4u, 4u, 4u, 4u);
+ auto* arr =
+ create<sem::Array>(create<sem::I32>(), create<sem::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
EXPECT_TRUE(r()->IsHostShareable(arr));
}
diff --git a/src/tint/resolver/is_storeable_test.cc b/src/tint/resolver/is_storeable_test.cc
index 61cf33b..6618199 100644
--- a/src/tint/resolver/is_storeable_test.cc
+++ b/src/tint/resolver/is_storeable_test.cc
@@ -89,13 +89,14 @@
}
TEST_F(ResolverIsStorableTest, ArraySizedOfStorable) {
- auto* arr =
- create<sem::Array>(create<sem::I32>(), sem::ConstantArrayCount{5u}, 4u, 20u, 4u, 4u);
+ auto* arr = create<sem::Array>(create<sem::I32>(), create<sem::ConstantArrayCount>(5u), 4u, 20u,
+ 4u, 4u);
EXPECT_TRUE(r()->IsStorable(arr));
}
TEST_F(ResolverIsStorableTest, ArrayUnsizedOfStorable) {
- auto* arr = create<sem::Array>(create<sem::I32>(), sem::RuntimeArrayCount{}, 4u, 4u, 4u, 4u);
+ auto* arr =
+ create<sem::Array>(create<sem::I32>(), create<sem::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
EXPECT_TRUE(r()->IsStorable(arr));
}
diff --git a/src/tint/resolver/override_test.cc b/src/tint/resolver/override_test.cc
index 132bd55..a97c92d 100644
--- a/src/tint/resolver/override_test.cc
+++ b/src/tint/resolver/override_test.cc
@@ -142,7 +142,9 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
{
- auto& refs = Sem().Get(b)->TransitivelyReferencedOverrides();
+ auto* r = Sem().TransitivelyReferencedOverrides(Sem().Get(b));
+ ASSERT_NE(r, nullptr);
+ auto& refs = *r;
ASSERT_EQ(refs.Length(), 1u);
EXPECT_EQ(refs[0], Sem().Get(a));
}
@@ -167,7 +169,9 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
{
- auto& refs = Sem().Get<sem::GlobalVariable>(b)->TransitivelyReferencedOverrides();
+ auto* r = Sem().TransitivelyReferencedOverrides(Sem().Get<sem::GlobalVariable>(b));
+ ASSERT_NE(r, nullptr);
+ auto& refs = *r;
ASSERT_EQ(refs.Length(), 1u);
EXPECT_EQ(refs[0], Sem().Get(a));
}
@@ -215,14 +219,18 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
{
- auto& refs = Sem().Get(arr_ty)->TransitivelyReferencedOverrides();
+ auto* r = Sem().TransitivelyReferencedOverrides(Sem().Get(arr_ty));
+ ASSERT_NE(r, nullptr);
+ auto& refs = *r;
ASSERT_EQ(refs.Length(), 2u);
EXPECT_EQ(refs[0], Sem().Get(b));
EXPECT_EQ(refs[1], Sem().Get(a));
}
{
- auto& refs = Sem().Get<sem::GlobalVariable>(arr)->TransitivelyReferencedOverrides();
+ auto* r = Sem().TransitivelyReferencedOverrides(Sem().Get<sem::GlobalVariable>(arr));
+ ASSERT_NE(r, nullptr);
+ auto& refs = *r;
ASSERT_EQ(refs.Length(), 2u);
EXPECT_EQ(refs[0], Sem().Get(b));
EXPECT_EQ(refs[1], Sem().Get(a));
@@ -251,14 +259,18 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
{
- auto& refs = Sem().Get<sem::Array>(arr_ty->type)->TransitivelyReferencedOverrides();
+ auto* r = Sem().TransitivelyReferencedOverrides(Sem().Get<sem::Array>(arr_ty->type));
+ ASSERT_NE(r, nullptr);
+ auto& refs = *r;
ASSERT_EQ(refs.Length(), 2u);
EXPECT_EQ(refs[0], Sem().Get(b));
EXPECT_EQ(refs[1], Sem().Get(a));
}
{
- auto& refs = Sem().Get<sem::GlobalVariable>(arr)->TransitivelyReferencedOverrides();
+ auto* r = Sem().TransitivelyReferencedOverrides(Sem().Get<sem::GlobalVariable>(arr));
+ ASSERT_NE(r, nullptr);
+ auto& refs = *r;
ASSERT_EQ(refs.Length(), 2u);
EXPECT_EQ(refs[0], Sem().Get(b));
EXPECT_EQ(refs[1], Sem().Get(a));
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index cf55a1d..ca66ac2 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -51,6 +51,7 @@
#include "src/tint/ast/vector.h"
#include "src/tint/ast/while_statement.h"
#include "src/tint/ast/workgroup_attribute.h"
+#include "src/tint/resolver/type_alias.h"
#include "src/tint/resolver/uniformity.h"
#include "src/tint/sem/abstract_float.h"
#include "src/tint/sem/abstract_int.h"
@@ -329,13 +330,16 @@
AddNote("'" + name + "' declared here", func->Declaration()->source);
return nullptr;
},
- [&](Default) {
+ [&](Default) -> sem::Type* {
if (auto* tn = ty->As<ast::TypeName>()) {
if (IsBuiltin(tn->name)) {
auto name = builder_->Symbols().NameFor(tn->name);
AddError("cannot use builtin '" + name + "' as type", ty->source);
return nullptr;
}
+ if (auto* t = BuiltinTypeAlias(tn->name)) {
+ return t;
+ }
}
TINT_UNREACHABLE(Resolver, diagnostics_)
<< "Unhandled resolved type '"
@@ -913,11 +917,14 @@
// Track the pipeline-overridable constants that are transitively referenced by this variable.
for (auto* var : transitively_referenced_overrides) {
- sem->AddTransitivelyReferencedOverride(var);
+ builder_->Sem().AddTransitivelyReferencedOverride(sem, var);
}
if (auto* arr = sem->Type()->UnwrapRef()->As<sem::Array>()) {
- for (auto* var : arr->TransitivelyReferencedOverrides()) {
- sem->AddTransitivelyReferencedOverride(var);
+ auto* refs = builder_->Sem().TransitivelyReferencedOverrides(arr);
+ if (refs) {
+ for (auto* var : *refs) {
+ builder_->Sem().AddTransitivelyReferencedOverride(sem, var);
+ }
}
}
@@ -2136,8 +2143,7 @@
[&](const ast::Array* a) -> sem::Call* {
Mark(a);
// array element type must be inferred if it was not specified.
- sem::ArrayCount el_count =
- sem::ConstantArrayCount{static_cast<uint32_t>(args.Length())};
+ const sem::ArrayCount* el_count = nullptr;
const sem::Type* el_ty = nullptr;
if (a->type) {
el_ty = Type(a->type);
@@ -2148,14 +2154,15 @@
AddError("cannot construct a runtime-sized array", expr->source);
return nullptr;
}
- if (auto count = ArrayCount(a->count)) {
- el_count = count.Get();
- } else {
+ el_count = ArrayCount(a->count);
+ if (!el_count) {
return nullptr;
}
// Note: validation later will detect any mismatches between explicit array
// size and number of initializer expressions.
} else {
+ el_count = builder_->create<sem::ConstantArrayCount>(
+ static_cast<uint32_t>(args.Length()));
auto arg_tys =
utils::Transform(args, [](auto* arg) { return arg->Type()->UnwrapRef(); });
el_ty = sem::Type::Common(arg_tys);
@@ -2228,11 +2235,13 @@
},
[&](Default) -> sem::Call* {
auto name = builder_->Symbols().NameFor(ident->symbol);
- auto builtin_type = sem::ParseBuiltinType(name);
- if (builtin_type != sem::BuiltinType::kNone) {
+ if (auto* alias = BuiltinTypeAlias(ident->symbol)) {
+ return ty_init_or_conv(alias);
+ }
+ if (auto builtin_type = sem::ParseBuiltinType(name);
+ builtin_type != sem::BuiltinType::kNone) {
return BuiltinCall(expr, builtin_type, args);
}
-
TINT_ICE(Resolver, diagnostics_)
<< expr->source << " unhandled CallExpression target:\n"
<< "resolved: " << (resolved ? resolved->TypeInfo().name : "<null>") << "\n"
@@ -2328,6 +2337,40 @@
return call;
}
+sem::Type* Resolver::BuiltinTypeAlias(Symbol sym) const {
+ auto name = builder_->Symbols().NameFor(sym);
+ auto& b = *builder_;
+ switch (ParseTypeAlias(name)) {
+ case TypeAlias::kVec2F:
+ return b.create<sem::Vector>(b.create<sem::F32>(), 2u);
+ case TypeAlias::kVec3F:
+ return b.create<sem::Vector>(b.create<sem::F32>(), 3u);
+ case TypeAlias::kVec4F:
+ return b.create<sem::Vector>(b.create<sem::F32>(), 4u);
+ case TypeAlias::kVec2H:
+ return b.create<sem::Vector>(b.create<sem::F16>(), 2u);
+ case TypeAlias::kVec3H:
+ return b.create<sem::Vector>(b.create<sem::F16>(), 3u);
+ case TypeAlias::kVec4H:
+ return b.create<sem::Vector>(b.create<sem::F16>(), 4u);
+ case TypeAlias::kVec2I:
+ return b.create<sem::Vector>(b.create<sem::I32>(), 2u);
+ case TypeAlias::kVec3I:
+ return b.create<sem::Vector>(b.create<sem::I32>(), 3u);
+ case TypeAlias::kVec4I:
+ return b.create<sem::Vector>(b.create<sem::I32>(), 4u);
+ case TypeAlias::kVec2U:
+ return b.create<sem::Vector>(b.create<sem::U32>(), 2u);
+ case TypeAlias::kVec3U:
+ return b.create<sem::Vector>(b.create<sem::U32>(), 3u);
+ case TypeAlias::kVec4U:
+ return b.create<sem::Vector>(b.create<sem::U32>(), 4u);
+ case TypeAlias::kUndefined:
+ break;
+ }
+ return nullptr;
+}
+
void Resolver::CollectTextureSamplerPairs(const sem::Builtin* builtin,
utils::VectorRef<const sem::Expression*> args) const {
// Collect a texture/sampler pair for this builtin.
@@ -2513,8 +2556,11 @@
if (current_function_) {
if (global) {
current_function_->AddDirectlyReferencedGlobal(global);
- for (auto* var : global->TransitivelyReferencedOverrides()) {
- current_function_->AddTransitivelyReferencedGlobal(var);
+ auto* refs = builder_->Sem().TransitivelyReferencedOverrides(global);
+ if (refs) {
+ for (auto* var : *refs) {
+ current_function_->AddTransitivelyReferencedGlobal(var);
+ }
}
}
} else if (variable->Declaration()->Is<ast::Override>()) {
@@ -2522,8 +2568,11 @@
// Track the reference to this pipeline-overridable constant and any other
// pipeline-overridable constants that it references.
resolved_overrides_->Add(global);
- for (auto* var : global->TransitivelyReferencedOverrides()) {
- resolved_overrides_->Add(var);
+ auto* refs = builder_->Sem().TransitivelyReferencedOverrides(global);
+ if (refs) {
+ for (auto* var : *refs) {
+ resolved_overrides_->Add(var);
+ }
}
}
} else if (variable->Declaration()->Is<ast::Var>()) {
@@ -2550,7 +2599,7 @@
return nullptr;
}
- if (resolved->Is<sem::Type>()) {
+ if (resolved->Is<sem::Type>() || BuiltinTypeAlias(symbol)) {
AddError("missing '(' for type initializer or cast", expr->source.End());
return nullptr;
}
@@ -2887,15 +2936,16 @@
return nullptr;
}
- sem::ArrayCount el_count = sem::RuntimeArrayCount{};
+ const sem::ArrayCount* el_count = nullptr;
// Evaluate the constant array count expression.
if (auto* count_expr = arr->count) {
- if (auto count = ArrayCount(count_expr)) {
- el_count = count.Get();
- } else {
+ el_count = ArrayCount(count_expr);
+ if (!el_count) {
return nullptr;
}
+ } else {
+ el_count = builder_->create<sem::RuntimeArrayCount>();
}
auto* out = Array(arr->type->source, //
@@ -2916,17 +2966,17 @@
// Track the pipeline-overridable constants that are transitively referenced by this array
// type.
for (auto* var : transitively_referenced_overrides) {
- out->AddTransitivelyReferencedOverride(var);
+ builder_->Sem().AddTransitivelyReferencedOverride(out, var);
}
return out;
}
-utils::Result<sem::ArrayCount> Resolver::ArrayCount(const ast::Expression* count_expr) {
+const sem::ArrayCount* Resolver::ArrayCount(const ast::Expression* count_expr) {
// Evaluate the constant array count expression.
const auto* count_sem = Materialize(Expression(count_expr));
if (!count_sem) {
- return utils::Failure;
+ return nullptr;
}
if (count_sem->Stage() == sem::EvaluationStage::kOverride) {
@@ -2934,34 +2984,34 @@
// Is the count a named 'override'?
if (auto* user = count_sem->UnwrapMaterialize()->As<sem::VariableUser>()) {
if (auto* global = user->Variable()->As<sem::GlobalVariable>()) {
- return sem::ArrayCount{sem::NamedOverrideArrayCount{global}};
+ return builder_->create<sem::NamedOverrideArrayCount>(global);
}
}
- return sem::ArrayCount{sem::UnnamedOverrideArrayCount{count_sem}};
+ return builder_->create<sem::UnnamedOverrideArrayCount>(count_sem);
}
auto* count_val = count_sem->ConstantValue();
if (!count_val) {
AddError("array count must evaluate to a constant integer expression or override variable",
count_expr->source);
- return utils::Failure;
+ return nullptr;
}
if (auto* ty = count_val->Type(); !ty->is_integer_scalar()) {
AddError("array count must evaluate to a constant integer expression, but is type '" +
builder_->FriendlyName(ty) + "'",
count_expr->source);
- return utils::Failure;
+ return nullptr;
}
int64_t count = count_val->As<AInt>();
if (count < 1) {
AddError("array count (" + std::to_string(count) + ") must be greater than 0",
count_expr->source);
- return utils::Failure;
+ return nullptr;
}
- return sem::ArrayCount{sem::ConstantArrayCount{static_cast<uint32_t>(count)}};
+ return builder_->create<sem::ConstantArrayCount>(static_cast<uint32_t>(count));
}
bool Resolver::ArrayAttributes(utils::VectorRef<const ast::Attribute*> attributes,
@@ -2997,7 +3047,7 @@
sem::Array* Resolver::Array(const Source& el_source,
const Source& count_source,
const sem::Type* el_ty,
- sem::ArrayCount el_count,
+ const sem::ArrayCount* el_count,
uint32_t explicit_stride) {
uint32_t el_align = el_ty->Align();
uint32_t el_size = el_ty->Size();
@@ -3005,7 +3055,7 @@
uint64_t stride = explicit_stride ? explicit_stride : implicit_stride;
uint64_t size = 0;
- if (auto const_count = std::get_if<sem::ConstantArrayCount>(&el_count)) {
+ if (auto const_count = el_count->As<sem::ConstantArrayCount>()) {
size = const_count->value * stride;
if (size > std::numeric_limits<uint32_t>::max()) {
std::stringstream msg;
@@ -3014,7 +3064,7 @@
AddError(msg.str(), count_source);
return nullptr;
}
- } else if (std::holds_alternative<sem::RuntimeArrayCount>(el_count)) {
+ } else if (el_count->Is<sem::RuntimeArrayCount>()) {
size = stride;
}
auto* out = builder_->create<sem::Array>(el_ty, el_count, el_align, static_cast<uint32_t>(size),
@@ -3124,7 +3174,6 @@
AddError("offsets must be in ascending order", o->source);
return false;
}
- align = 1;
has_offset_attr = true;
return true;
},
@@ -3225,7 +3274,7 @@
}
auto* sem_member = builder_->create<sem::StructMember>(
- member, member->symbol, type, static_cast<uint32_t>(sem_members.size()),
+ member, member->source, member->symbol, type, static_cast<uint32_t>(sem_members.size()),
static_cast<uint32_t>(offset), static_cast<uint32_t>(align),
static_cast<uint32_t>(size), location);
builder_->Sem().Add(member, sem_member);
@@ -3250,13 +3299,13 @@
}
auto* out = builder_->create<sem::Struct>(
- str, str->name, sem_members, static_cast<uint32_t>(struct_align),
+ str, str->source, str->name, sem_members, static_cast<uint32_t>(struct_align),
static_cast<uint32_t>(struct_size), static_cast<uint32_t>(size_no_padding));
for (size_t i = 0; i < sem_members.size(); i++) {
auto* mem_type = sem_members[i]->Type();
if (mem_type->Is<sem::Atomic>()) {
- atomic_composite_info_.Add(out, &sem_members[i]->Declaration()->source);
+ atomic_composite_info_.Add(out, &sem_members[i]->Source());
break;
} else {
if (auto found = atomic_composite_info_.Get(mem_type)) {
@@ -3580,8 +3629,8 @@
decl->type->source)) {
std::stringstream err;
err << "while analyzing structure member " << sem_.TypeNameOf(str) << "."
- << builder_->Symbols().NameFor(decl->symbol);
- AddNote(err.str(), decl->source);
+ << builder_->Symbols().NameFor(member->Name());
+ AddNote(err.str(), member->Source());
return false;
}
}
@@ -3590,7 +3639,7 @@
if (auto* arr = ty->As<sem::Array>()) {
if (address_space != ast::AddressSpace::kStorage) {
- if (arr->IsRuntimeSized()) {
+ if (arr->Count()->Is<sem::RuntimeArrayCount>()) {
AddError("runtime-sized arrays can only be used in the <storage> address space",
usage);
return false;
diff --git a/src/tint/resolver/resolver.h b/src/tint/resolver/resolver.h
index abc7633..0deef5f 100644
--- a/src/tint/resolver/resolver.h
+++ b/src/tint/resolver/resolver.h
@@ -273,7 +273,7 @@
/// Resolves and validates the expression used as the count parameter of an array.
/// @param count_expr the expression used as the second template parameter to an array<>.
/// @returns the number of elements in the array.
- utils::Result<sem::ArrayCount> ArrayCount(const ast::Expression* count_expr);
+ const sem::ArrayCount* ArrayCount(const ast::Expression* count_expr);
/// Resolves and validates the attributes on an array.
/// @param attributes the attributes on the array type.
@@ -296,7 +296,7 @@
sem::Array* Array(const Source& el_source,
const Source& count_source,
const sem::Type* el_ty,
- sem::ArrayCount el_count,
+ const sem::ArrayCount* el_count,
uint32_t explicit_stride);
/// Builds and returns the semantic information for the alias `alias`.
@@ -384,6 +384,7 @@
/// Set the shadowing information on variable declarations.
/// @note this method must only be called after all semantic nodes are built.
void SetShadows();
+
/// StatementScope() does the following:
/// * Creates the AST -> SEM mapping.
/// * Assigns `sem` to #current_statement_
@@ -415,6 +416,9 @@
/// @returns true if the symbol is the name of a builtin function.
bool IsBuiltin(Symbol) const;
+ /// @returns the builtin type alias for the given symbol
+ sem::Type* BuiltinTypeAlias(Symbol) const;
+
// ArrayInitializerSig represents a unique array initializer signature.
// It is a tuple of the array type, number of arguments provided and earliest evaluation stage.
using ArrayInitializerSig =
diff --git a/src/tint/resolver/resolver_test.cc b/src/tint/resolver/resolver_test.cc
index 13b1da1..2a88249 100644
--- a/src/tint/resolver/resolver_test.cc
+++ b/src/tint/resolver/resolver_test.cc
@@ -440,7 +440,7 @@
auto* ref = TypeOf(a)->As<sem::Reference>();
ASSERT_NE(ref, nullptr);
auto* ary = ref->StoreType()->As<sem::Array>();
- EXPECT_EQ(ary->Count(), sem::ConstantArrayCount{10u});
+ EXPECT_EQ(ary->Count(), create<sem::ConstantArrayCount>(10u));
}
TEST_F(ResolverTest, ArraySize_SignedLiteral) {
@@ -453,7 +453,7 @@
auto* ref = TypeOf(a)->As<sem::Reference>();
ASSERT_NE(ref, nullptr);
auto* ary = ref->StoreType()->As<sem::Array>();
- EXPECT_EQ(ary->Count(), sem::ConstantArrayCount{10u});
+ EXPECT_EQ(ary->Count(), create<sem::ConstantArrayCount>(10u));
}
TEST_F(ResolverTest, ArraySize_UnsignedConst) {
@@ -468,7 +468,7 @@
auto* ref = TypeOf(a)->As<sem::Reference>();
ASSERT_NE(ref, nullptr);
auto* ary = ref->StoreType()->As<sem::Array>();
- EXPECT_EQ(ary->Count(), sem::ConstantArrayCount{10u});
+ EXPECT_EQ(ary->Count(), create<sem::ConstantArrayCount>(10u));
}
TEST_F(ResolverTest, ArraySize_SignedConst) {
@@ -483,7 +483,7 @@
auto* ref = TypeOf(a)->As<sem::Reference>();
ASSERT_NE(ref, nullptr);
auto* ary = ref->StoreType()->As<sem::Array>();
- EXPECT_EQ(ary->Count(), sem::ConstantArrayCount{10u});
+ EXPECT_EQ(ary->Count(), create<sem::ConstantArrayCount>(10u));
}
TEST_F(ResolverTest, ArraySize_NamedOverride) {
@@ -500,7 +500,7 @@
auto* ary = ref->StoreType()->As<sem::Array>();
auto* sem_override = Sem().Get<sem::GlobalVariable>(override);
ASSERT_NE(sem_override, nullptr);
- EXPECT_EQ(ary->Count(), sem::NamedOverrideArrayCount{sem_override});
+ EXPECT_EQ(ary->Count(), create<sem::NamedOverrideArrayCount>(sem_override));
}
TEST_F(ResolverTest, ArraySize_NamedOverride_Equivalence) {
@@ -525,8 +525,8 @@
auto* sem_override = Sem().Get<sem::GlobalVariable>(override);
ASSERT_NE(sem_override, nullptr);
- EXPECT_EQ(ary_a->Count(), sem::NamedOverrideArrayCount{sem_override});
- EXPECT_EQ(ary_b->Count(), sem::NamedOverrideArrayCount{sem_override});
+ EXPECT_EQ(ary_a->Count(), create<sem::NamedOverrideArrayCount>(sem_override));
+ EXPECT_EQ(ary_b->Count(), create<sem::NamedOverrideArrayCount>(sem_override));
EXPECT_EQ(ary_a, ary_b);
}
@@ -545,7 +545,7 @@
auto* ary = ref->StoreType()->As<sem::Array>();
auto* sem_override = Sem().Get<sem::GlobalVariable>(override);
ASSERT_NE(sem_override, nullptr);
- EXPECT_EQ(ary->Count(), sem::UnnamedOverrideArrayCount{Sem().Get(cnt)});
+ EXPECT_EQ(ary->Count(), create<sem::UnnamedOverrideArrayCount>(Sem().Get(cnt)));
}
TEST_F(ResolverTest, ArraySize_UnamedOverride_Equivalence) {
@@ -572,8 +572,8 @@
auto* sem_override = Sem().Get<sem::GlobalVariable>(override);
ASSERT_NE(sem_override, nullptr);
- EXPECT_EQ(ary_a->Count(), sem::UnnamedOverrideArrayCount{Sem().Get(a_cnt)});
- EXPECT_EQ(ary_b->Count(), sem::UnnamedOverrideArrayCount{Sem().Get(b_cnt)});
+ EXPECT_EQ(ary_a->Count(), create<sem::UnnamedOverrideArrayCount>(Sem().Get(a_cnt)));
+ EXPECT_EQ(ary_b->Count(), create<sem::UnnamedOverrideArrayCount>(Sem().Get(b_cnt)));
EXPECT_NE(ary_a, ary_b);
}
diff --git a/src/tint/resolver/resolver_test_helper.h b/src/tint/resolver/resolver_test_helper.h
index 68a7017..f2567c8 100644
--- a/src/tint/resolver/resolver_test_helper.h
+++ b/src/tint/resolver/resolver_test_helper.h
@@ -31,6 +31,7 @@
#include "src/tint/sem/expression.h"
#include "src/tint/sem/statement.h"
#include "src/tint/sem/variable.h"
+#include "src/tint/traits.h"
#include "src/tint/utils/vector.h"
namespace tint::resolver {
@@ -658,9 +659,11 @@
/// @return the semantic array type
static inline const sem::Type* Sem(ProgramBuilder& b) {
auto* el = DataType<T>::Sem(b);
- sem::ArrayCount count = sem::ConstantArrayCount{N};
+ const sem::ArrayCount* count = nullptr;
if (N == 0) {
- count = sem::RuntimeArrayCount{};
+ count = b.create<sem::RuntimeArrayCount>();
+ } else {
+ count = b.create<sem::ConstantArrayCount>(N);
}
return b.create<sem::Array>(
/* element */ el,
@@ -793,6 +796,7 @@
/// Creates a Value of DataType<T> from a scalar `v`
template <typename T>
Value Val(T v) {
+ static_assert(traits::IsTypeIn<T, Scalar>, "v must be a Number of bool");
return Value::Create<T>(utils::Vector<Scalar, 1>{v});
}
diff --git a/src/tint/resolver/struct_layout_test.cc b/src/tint/resolver/struct_layout_test.cc
index 1e5ec45..acfe691 100644
--- a/src/tint/resolver/struct_layout_test.cc
+++ b/src/tint/resolver/struct_layout_test.cc
@@ -555,5 +555,47 @@
}
}
+TEST_F(ResolverStructLayoutTest, OffsetAttributes) {
+ auto* inner = Structure("Inner", utils::Vector{
+ Member("a", ty.f32(), utils::Vector{MemberOffset(8_i)}),
+ Member("b", ty.f32(), utils::Vector{MemberOffset(16_i)}),
+ Member("c", ty.f32(), utils::Vector{MemberOffset(32_i)}),
+ });
+ auto* s = Structure("S", utils::Vector{
+ Member("a", ty.f32(), utils::Vector{MemberOffset(4_i)}),
+ Member("b", ty.u32(), utils::Vector{MemberOffset(8_i)}),
+ Member("c", ty.Of(inner), utils::Vector{MemberOffset(32_i)}),
+ Member("d", ty.i32()),
+ Member("e", ty.i32(), utils::Vector{MemberOffset(128_i)}),
+ });
+
+ ASSERT_TRUE(r()->Resolve()) << r()->error();
+
+ auto* sem = TypeOf(s)->As<sem::Struct>();
+ ASSERT_NE(sem, nullptr);
+ EXPECT_EQ(sem->Size(), 132u);
+ EXPECT_EQ(sem->SizeNoPadding(), 132u);
+ EXPECT_EQ(sem->Align(), 4u);
+ ASSERT_EQ(sem->Members().size(), 5u);
+ EXPECT_EQ(sem->Members()[0]->Offset(), 4u);
+ EXPECT_EQ(sem->Members()[0]->Align(), 4u);
+ EXPECT_EQ(sem->Members()[0]->Size(), 4u);
+ EXPECT_EQ(sem->Members()[1]->Offset(), 8u);
+ EXPECT_EQ(sem->Members()[1]->Align(), 4u);
+ EXPECT_EQ(sem->Members()[1]->Size(), 4u);
+ EXPECT_EQ(sem->Members()[2]->Offset(), 32u);
+ EXPECT_EQ(sem->Members()[2]->Align(), 4u);
+ EXPECT_EQ(sem->Members()[2]->Size(), 36u);
+ EXPECT_EQ(sem->Members()[3]->Offset(), 68u);
+ EXPECT_EQ(sem->Members()[3]->Align(), 4u);
+ EXPECT_EQ(sem->Members()[3]->Size(), 4u);
+ EXPECT_EQ(sem->Members()[4]->Offset(), 128u);
+ EXPECT_EQ(sem->Members()[4]->Align(), 4u);
+ EXPECT_EQ(sem->Members()[4]->Size(), 4u);
+ for (auto& m : sem->Members()) {
+ EXPECT_EQ(m->Struct()->Declaration(), s);
+ }
+}
+
} // namespace
} // namespace tint::resolver
diff --git a/src/tint/resolver/type_alias.cc b/src/tint/resolver/type_alias.cc
new file mode 100644
index 0000000..124fc8c
--- /dev/null
+++ b/src/tint/resolver/type_alias.cc
@@ -0,0 +1,102 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+// src/tint/resolver/type_alias.cc.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+#include "src/tint/resolver/type_alias.h"
+
+namespace tint::resolver {
+
+/// ParseTypeAlias parses a TypeAlias from a string.
+/// @param str the string to parse
+/// @returns the parsed enum, or TypeAlias::kUndefined if the string could not be parsed.
+TypeAlias ParseTypeAlias(std::string_view str) {
+ if (str == "vec2f") {
+ return TypeAlias::kVec2F;
+ }
+ if (str == "vec2h") {
+ return TypeAlias::kVec2H;
+ }
+ if (str == "vec2i") {
+ return TypeAlias::kVec2I;
+ }
+ if (str == "vec2u") {
+ return TypeAlias::kVec2U;
+ }
+ if (str == "vec3f") {
+ return TypeAlias::kVec3F;
+ }
+ if (str == "vec3h") {
+ return TypeAlias::kVec3H;
+ }
+ if (str == "vec3i") {
+ return TypeAlias::kVec3I;
+ }
+ if (str == "vec3u") {
+ return TypeAlias::kVec3U;
+ }
+ if (str == "vec4f") {
+ return TypeAlias::kVec4F;
+ }
+ if (str == "vec4h") {
+ return TypeAlias::kVec4H;
+ }
+ if (str == "vec4i") {
+ return TypeAlias::kVec4I;
+ }
+ if (str == "vec4u") {
+ return TypeAlias::kVec4U;
+ }
+ return TypeAlias::kUndefined;
+}
+
+std::ostream& operator<<(std::ostream& out, TypeAlias value) {
+ switch (value) {
+ case TypeAlias::kUndefined:
+ return out << "undefined";
+ case TypeAlias::kVec2F:
+ return out << "vec2f";
+ case TypeAlias::kVec2H:
+ return out << "vec2h";
+ case TypeAlias::kVec2I:
+ return out << "vec2i";
+ case TypeAlias::kVec2U:
+ return out << "vec2u";
+ case TypeAlias::kVec3F:
+ return out << "vec3f";
+ case TypeAlias::kVec3H:
+ return out << "vec3h";
+ case TypeAlias::kVec3I:
+ return out << "vec3i";
+ case TypeAlias::kVec3U:
+ return out << "vec3u";
+ case TypeAlias::kVec4F:
+ return out << "vec4f";
+ case TypeAlias::kVec4H:
+ return out << "vec4h";
+ case TypeAlias::kVec4I:
+ return out << "vec4i";
+ case TypeAlias::kVec4U:
+ return out << "vec4u";
+ }
+ return out << "<unknown>";
+}
+
+} // namespace tint::resolver
diff --git a/src/tint/resolver/type_alias.cc.tmpl b/src/tint/resolver/type_alias.cc.tmpl
new file mode 100644
index 0000000..3843864
--- /dev/null
+++ b/src/tint/resolver/type_alias.cc.tmpl
@@ -0,0 +1,25 @@
+{{- /*
+--------------------------------------------------------------------------------
+Template file for use with tools/src/cmd/gen to generate type_alias.cc
+
+To update the generated file, run:
+ ./tools/run gen
+
+See:
+* tools/src/cmd/gen for structures used by this template
+* https://golang.org/pkg/text/template/ for documentation on the template syntax
+--------------------------------------------------------------------------------
+*/ -}}
+
+{{- Import "src/tint/templates/enums.tmpl.inc" -}}
+{{- $enum := (Sem.Enum "type_alias") -}}
+
+#include "src/tint/resolver/type_alias.h"
+
+namespace tint::resolver {
+
+{{ Eval "ParseEnum" $enum}}
+
+{{ Eval "EnumOStream" $enum}}
+
+} // namespace tint::resolver
diff --git a/src/tint/resolver/type_alias.h b/src/tint/resolver/type_alias.h
new file mode 100644
index 0000000..40083a3
--- /dev/null
+++ b/src/tint/resolver/type_alias.h
@@ -0,0 +1,64 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+// src/tint/resolver/type_alias.h.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef SRC_TINT_RESOLVER_TYPE_ALIAS_H_
+#define SRC_TINT_RESOLVER_TYPE_ALIAS_H_
+
+#include <ostream>
+
+namespace tint::resolver {
+
+/// An enumerator of builtin type aliases.
+enum class TypeAlias {
+ kUndefined,
+ kVec2F,
+ kVec2H,
+ kVec2I,
+ kVec2U,
+ kVec3F,
+ kVec3H,
+ kVec3I,
+ kVec3U,
+ kVec4F,
+ kVec4H,
+ kVec4I,
+ kVec4U,
+};
+
+/// @param out the std::ostream to write to
+/// @param value the TypeAlias
+/// @returns `out` so calls can be chained
+std::ostream& operator<<(std::ostream& out, TypeAlias value);
+
+/// ParseTypeAlias parses a TypeAlias from a string.
+/// @param str the string to parse
+/// @returns the parsed enum, or TypeAlias::kUndefined if the string could not be parsed.
+TypeAlias ParseTypeAlias(std::string_view str);
+
+constexpr const char* kTypeAliasStrings[] = {
+ "vec2f", "vec2h", "vec2i", "vec2u", "vec3f", "vec3h",
+ "vec3i", "vec3u", "vec4f", "vec4h", "vec4i", "vec4u",
+};
+
+} // namespace tint::resolver
+
+#endif // SRC_TINT_RESOLVER_TYPE_ALIAS_H_
diff --git a/src/tint/resolver/type_alias.h.tmpl b/src/tint/resolver/type_alias.h.tmpl
new file mode 100644
index 0000000..0a9b2d4
--- /dev/null
+++ b/src/tint/resolver/type_alias.h.tmpl
@@ -0,0 +1,29 @@
+{{- /*
+--------------------------------------------------------------------------------
+Template file for use with tools/src/cmd/gen to generate type_alias.h
+
+To update the generated file, run:
+ ./tools/run gen
+
+See:
+* tools/src/cmd/gen for structures used by this template
+* https://golang.org/pkg/text/template/ for documentation on the template syntax
+--------------------------------------------------------------------------------
+*/ -}}
+
+{{- Import "src/tint/templates/enums.tmpl.inc" -}}
+{{- $enum := (Sem.Enum "type_alias") -}}
+
+#ifndef SRC_TINT_RESOLVER_TYPE_ALIAS_H_
+#define SRC_TINT_RESOLVER_TYPE_ALIAS_H_
+
+#include <ostream>
+
+namespace tint::resolver {
+
+/// An enumerator of builtin type aliases.
+{{ Eval "DeclareEnum" $enum}}
+
+} // namespace tint::resolver
+
+#endif // SRC_TINT_RESOLVER_TYPE_ALIAS_H_
diff --git a/src/tint/resolver/type_alias_bench.cc b/src/tint/resolver/type_alias_bench.cc
new file mode 100644
index 0000000..2510352
--- /dev/null
+++ b/src/tint/resolver/type_alias_bench.cc
@@ -0,0 +1,57 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+// src/tint/resolver/type_alias_bench.cc.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+#include "src/tint/resolver/type_alias.h"
+
+#include <array>
+
+#include "benchmark/benchmark.h"
+
+namespace tint::resolver {
+namespace {
+
+void TypeAliasParser(::benchmark::State& state) {
+ std::array kStrings{
+ "veccf", "32", "vVc2f", "vec2f", "vec21", "qqeJf", "vecll7f", "veqH2pp",
+ "vh", "Gebh", "vec2h", "vevi2h", "ve8WWh", "Mxxc2", "vgg2i", "V2X",
+ "vec23", "vec2i", "vec2E", "TTeP2i", "vxxcdd", "v44c2u", "veVVSSu", "22RRu",
+ "vec2u", "vF2u", "vecu", "ROOHVu", "ecyf", "n77rrlcGf", "vec340", "vec3f",
+ "oof", "vezz", "1ipp3f", "XXec3h", "ve9IInn5h", "HHreSSaYh", "vec3h", "kk3",
+ "jgRR", "veb", "vjc3i", "vc3i", "vcq", "vec3i", "Nec3i", "vcvv",
+ "ve3QQ", "vrcf", "vecju", "NNew23", "vec3u", "ve3u", "vrrc3u", "Gec3u",
+ "veFF4f", "vE", "verrf", "vec4f", "vef", "veJJD", "v4", "e4k",
+ "vech", "Jech", "vec4h", "ec4h", "_KKttcH", "vexxh", "__qcF", "vc4qq",
+ "33e64i", "vec4i", "6QQott4i", "v6c4i", "zzc4O6", "vyyc4u", "vcZZ", "ecWq4u",
+ "vec4u", "vOO4u", "oYe4", "v4",
+ };
+ for (auto _ : state) {
+ for (auto& str : kStrings) {
+ auto result = ParseTypeAlias(str);
+ benchmark::DoNotOptimize(result);
+ }
+ }
+}
+
+BENCHMARK(TypeAliasParser);
+
+} // namespace
+} // namespace tint::resolver
diff --git a/src/tint/resolver/type_alias_bench.cc.tmpl b/src/tint/resolver/type_alias_bench.cc.tmpl
new file mode 100644
index 0000000..3a48226
--- /dev/null
+++ b/src/tint/resolver/type_alias_bench.cc.tmpl
@@ -0,0 +1,29 @@
+{{- /*
+--------------------------------------------------------------------------------
+Template file for use with tools/src/cmd/gen to generate type_alias_bench.cc
+
+To update the generated file, run:
+ ./tools/run gen
+
+See:
+* tools/src/cmd/gen for structures used by this template
+* https://golang.org/pkg/text/template/ for documentation on the template syntax
+--------------------------------------------------------------------------------
+*/ -}}
+
+{{- Import "src/tint/templates/enums.tmpl.inc" -}}
+{{- $enum := (Sem.Enum "type_alias") -}}
+
+#include "src/tint/resolver/type_alias.h"
+
+#include <array>
+
+#include "benchmark/benchmark.h"
+
+namespace tint::resolver {
+namespace {
+
+{{ Eval "BenchmarkParseEnum" $enum }}
+
+} // namespace
+} // namespace tint::resolver
diff --git a/src/tint/resolver/type_alias_test.cc b/src/tint/resolver/type_alias_test.cc
new file mode 100644
index 0000000..c52d44c
--- /dev/null
+++ b/src/tint/resolver/type_alias_test.cc
@@ -0,0 +1,97 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+// src/tint/resolver/type_alias_test.cc.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+#include "src/tint/resolver/type_alias.h"
+
+#include <string>
+
+#include "gtest/gtest.h"
+
+#include "src/tint/utils/string.h"
+
+namespace tint::resolver {
+namespace {
+
+namespace parse_print_tests {
+
+struct Case {
+ const char* string;
+ TypeAlias value;
+};
+
+inline std::ostream& operator<<(std::ostream& out, Case c) {
+ return out << "'" << std::string(c.string) << "'";
+}
+
+static constexpr Case kValidCases[] = {
+ {"vec2f", TypeAlias::kVec2F}, {"vec2h", TypeAlias::kVec2H}, {"vec2i", TypeAlias::kVec2I},
+ {"vec2u", TypeAlias::kVec2U}, {"vec3f", TypeAlias::kVec3F}, {"vec3h", TypeAlias::kVec3H},
+ {"vec3i", TypeAlias::kVec3I}, {"vec3u", TypeAlias::kVec3U}, {"vec4f", TypeAlias::kVec4F},
+ {"vec4h", TypeAlias::kVec4H}, {"vec4i", TypeAlias::kVec4I}, {"vec4u", TypeAlias::kVec4U},
+};
+
+static constexpr Case kInvalidCases[] = {
+ {"veccf", TypeAlias::kUndefined}, {"32", TypeAlias::kUndefined},
+ {"vVc2f", TypeAlias::kUndefined}, {"vec21", TypeAlias::kUndefined},
+ {"qqeJh", TypeAlias::kUndefined}, {"vecll7h", TypeAlias::kUndefined},
+ {"veqH2pp", TypeAlias::kUndefined}, {"vi", TypeAlias::kUndefined},
+ {"Gebi", TypeAlias::kUndefined}, {"vevi2u", TypeAlias::kUndefined},
+ {"ve8WWu", TypeAlias::kUndefined}, {"Mxxc2", TypeAlias::kUndefined},
+ {"vgg3f", TypeAlias::kUndefined}, {"V3X", TypeAlias::kUndefined},
+ {"vec33", TypeAlias::kUndefined}, {"vec3E", TypeAlias::kUndefined},
+ {"TTeP3h", TypeAlias::kUndefined}, {"vxxcdd", TypeAlias::kUndefined},
+ {"v44c3i", TypeAlias::kUndefined}, {"veVVSSi", TypeAlias::kUndefined},
+ {"22RRi", TypeAlias::kUndefined}, {"vF3u", TypeAlias::kUndefined},
+ {"vecu", TypeAlias::kUndefined}, {"ROOHVu", TypeAlias::kUndefined},
+ {"ecyf", TypeAlias::kUndefined}, {"n77rrlcGf", TypeAlias::kUndefined},
+ {"vec440", TypeAlias::kUndefined}, {"ooh", TypeAlias::kUndefined},
+ {"vezz", TypeAlias::kUndefined}, {"1ipp4h", TypeAlias::kUndefined},
+ {"XXec4i", TypeAlias::kUndefined}, {"ve9IInn5i", TypeAlias::kUndefined},
+ {"HHreSSaYi", TypeAlias::kUndefined}, {"kk4", TypeAlias::kUndefined},
+ {"jgRR", TypeAlias::kUndefined}, {"veb", TypeAlias::kUndefined},
+};
+
+using TypeAliasParseTest = testing::TestWithParam<Case>;
+
+TEST_P(TypeAliasParseTest, Parse) {
+ const char* string = GetParam().string;
+ TypeAlias expect = GetParam().value;
+ EXPECT_EQ(expect, ParseTypeAlias(string));
+}
+
+INSTANTIATE_TEST_SUITE_P(ValidCases, TypeAliasParseTest, testing::ValuesIn(kValidCases));
+INSTANTIATE_TEST_SUITE_P(InvalidCases, TypeAliasParseTest, testing::ValuesIn(kInvalidCases));
+
+using TypeAliasPrintTest = testing::TestWithParam<Case>;
+
+TEST_P(TypeAliasPrintTest, Print) {
+ TypeAlias value = GetParam().value;
+ const char* expect = GetParam().string;
+ EXPECT_EQ(expect, utils::ToString(value));
+}
+
+INSTANTIATE_TEST_SUITE_P(ValidCases, TypeAliasPrintTest, testing::ValuesIn(kValidCases));
+
+} // namespace parse_print_tests
+
+} // namespace
+} // namespace tint::resolver
diff --git a/src/tint/resolver/type_alias_test.cc.tmpl b/src/tint/resolver/type_alias_test.cc.tmpl
new file mode 100644
index 0000000..2f37251
--- /dev/null
+++ b/src/tint/resolver/type_alias_test.cc.tmpl
@@ -0,0 +1,31 @@
+{{- /*
+--------------------------------------------------------------------------------
+Template file for use with tools/src/cmd/gen to generate type_alias_test.cc
+
+To update the generated file, run:
+ ./tools/run gen
+
+See:
+* tools/src/cmd/gen for structures used by this template
+* https://golang.org/pkg/text/template/ for documentation on the template syntax
+--------------------------------------------------------------------------------
+*/ -}}
+
+{{- Import "src/tint/templates/enums.tmpl.inc" -}}
+{{- $enum := (Sem.Enum "type_alias") -}}
+
+#include "src/tint/resolver/type_alias.h"
+
+#include <string>
+
+#include "gtest/gtest.h"
+
+#include "src/tint/utils/string.h"
+
+namespace tint::resolver {
+namespace {
+
+{{ Eval "TestParsePrintEnum" $enum}}
+
+} // namespace
+} // namespace tint::resolver
diff --git a/src/tint/resolver/type_validation_test.cc b/src/tint/resolver/type_validation_test.cc
index fe1aa05..b389fc1 100644
--- a/src/tint/resolver/type_validation_test.cc
+++ b/src/tint/resolver/type_validation_test.cc
@@ -1395,5 +1395,56 @@
ParamsFor<array<2, f32>>(2)));
} // namespace VectorTests
+namespace BuiltinTypeAliasTests {
+struct Params {
+ const char* alias;
+ builder::ast_type_func_ptr type;
+};
+
+template <typename T>
+constexpr Params Case(const char* alias) {
+ return Params{alias, DataType<T>::AST};
+}
+
+using BuiltinTypeAliasTest = ResolverTestWithParam<Params>;
+TEST_P(BuiltinTypeAliasTest, CheckEquivalent) {
+ // var aliased : vecTN;
+ // var explicit : vecN<T>;
+ // explicit = aliased;
+ auto& params = GetParam();
+
+ Enable(ast::Extension::kF16);
+
+ WrapInFunction(Decl(Var("aliased", ty.type_name(params.alias))),
+ Decl(Var("explicit", params.type(*this))), //
+ Assign("explicit", "aliased"));
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+}
+TEST_P(BuiltinTypeAliasTest, Construct) {
+ // var v : vecN<T> = vecTN();
+ auto& params = GetParam();
+
+ Enable(ast::Extension::kF16);
+
+ WrapInFunction(Decl(Var("v", params.type(*this), Construct(ty.type_name(params.alias)))));
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+}
+INSTANTIATE_TEST_SUITE_P(ResolverTypeValidationTest,
+ BuiltinTypeAliasTest,
+ testing::Values(Case<vec2<f32>>("vec2f"),
+ Case<vec3<f32>>("vec3f"),
+ Case<vec4<f32>>("vec4f"),
+ Case<vec2<f16>>("vec2h"),
+ Case<vec3<f16>>("vec3h"),
+ Case<vec4<f16>>("vec4h"),
+ Case<vec2<i32>>("vec2i"),
+ Case<vec3<i32>>("vec3i"),
+ Case<vec4<i32>>("vec4i"),
+ Case<vec2<u32>>("vec2u"),
+ Case<vec3<u32>>("vec3u"),
+ Case<vec4<u32>>("vec4u")));
+
+} // namespace BuiltinTypeAliasTests
+
} // namespace
} // namespace tint::resolver
diff --git a/src/tint/resolver/uniformity.h b/src/tint/resolver/uniformity.h
index 7980801..1139980 100644
--- a/src/tint/resolver/uniformity.h
+++ b/src/tint/resolver/uniformity.h
@@ -16,10 +16,10 @@
#define SRC_TINT_RESOLVER_UNIFORMITY_H_
// Forward declarations.
-namespace tint {
-namespace resolver {
+namespace tint::resolver {
struct DependencyGraph;
-} // namespace resolver
+} // namespace tint::resolver
+namespace tint {
class ProgramBuilder;
} // namespace tint
diff --git a/src/tint/resolver/validator.cc b/src/tint/resolver/validator.cc
index 70e1de1..e5c7c1a 100644
--- a/src/tint/resolver/validator.cc
+++ b/src/tint/resolver/validator.cc
@@ -194,7 +194,7 @@
[&](const sem::Matrix*) { return true; }, //
[&](const sem::Atomic*) { return true; },
[&](const sem::Array* arr) {
- return !arr->IsRuntimeSized() && IsFixedFootprint(arr->ElemType());
+ return !arr->Count()->Is<sem::RuntimeArrayCount>() && IsFixedFootprint(arr->ElemType());
},
[&](const sem::Struct* str) {
for (auto* member : str->Members()) {
@@ -413,7 +413,7 @@
};
auto member_name_of = [this](const sem::StructMember* sm) {
- return symbols_.NameFor(sm->Declaration()->symbol);
+ return symbols_.NameFor(sm->Name());
};
// Only validate the [type + address space] once
@@ -446,8 +446,7 @@
// Recurse into the member type.
if (!AddressSpaceLayout(m->Type(), address_space, m->Declaration()->type->source)) {
- AddNote("see layout of struct:\n" + str->Layout(symbols_),
- str->Declaration()->source);
+ AddNote("see layout of struct:\n" + str->Layout(symbols_), str->Source());
note_usage();
return false;
}
@@ -461,14 +460,13 @@
" bytes, but '" + member_name_of(m) + "' is currently at offset " +
std::to_string(m->Offset()) + ". Consider setting @align(" +
std::to_string(required_align) + ") on this member",
- m->Declaration()->source);
+ m->Source());
- AddNote("see layout of struct:\n" + str->Layout(symbols_),
- str->Declaration()->source);
+ AddNote("see layout of struct:\n" + str->Layout(symbols_), str->Source());
if (auto* member_str = m->Type()->As<sem::Struct>()) {
AddNote("and layout of struct member:\n" + member_str->Layout(symbols_),
- member_str->Declaration()->source);
+ member_str->Source());
}
note_usage();
@@ -488,15 +486,14 @@
std::to_string(prev_to_curr_offset) + " bytes between '" +
member_name_of(prev_member) + "' and '" + member_name_of(m) +
"'. Consider setting @align(16) on this member",
- m->Declaration()->source);
+ m->Source());
- AddNote("see layout of struct:\n" + str->Layout(symbols_),
- str->Declaration()->source);
+ AddNote("see layout of struct:\n" + str->Layout(symbols_), str->Source());
auto* prev_member_str = prev_member->Type()->As<sem::Struct>();
AddNote("and layout of previous member struct:\n" +
prev_member_str->Layout(symbols_),
- prev_member_str->Declaration()->source);
+ prev_member_str->Source());
note_usage();
return false;
}
@@ -800,15 +797,31 @@
}
if (auto* ref = var->Type()->As<sem::Pointer>()) {
- auto address_space = ref->AddressSpace();
- if (!(address_space == ast::AddressSpace::kFunction ||
- address_space == ast::AddressSpace::kPrivate) &&
- IsValidationEnabled(decl->attributes, ast::DisabledValidation::kIgnoreAddressSpace)) {
- std::stringstream ss;
- ss << "function parameter of pointer type cannot be in '" << address_space
- << "' address space";
- AddError(ss.str(), decl->source);
- return false;
+ if (IsValidationEnabled(decl->attributes, ast::DisabledValidation::kIgnoreAddressSpace)) {
+ bool ok = false;
+
+ auto sc = ref->AddressSpace();
+ switch (sc) {
+ case ast::AddressSpace::kFunction:
+ case ast::AddressSpace::kPrivate:
+ ok = true;
+ break;
+ case ast::AddressSpace::kStorage:
+ case ast::AddressSpace::kUniform:
+ case ast::AddressSpace::kWorkgroup:
+ ok = enabled_extensions_.Contains(
+ ast::Extension::kChromiumExperimentalFullPtrParameters);
+ break;
+ default:
+ break;
+ }
+ if (!ok) {
+ std::stringstream ss;
+ ss << "function parameter of pointer type cannot be in '" << sc
+ << "' address space";
+ AddError(ss.str(), decl->source);
+ return false;
+ }
}
}
@@ -1212,8 +1225,8 @@
if (auto* str = ty->As<sem::Struct>()) {
for (auto* member : str->Members()) {
if (!validate_entry_point_attributes_inner(
- member->Declaration()->attributes, member->Type(),
- member->Declaration()->source, param_or_ret,
+ member->Declaration()->attributes, member->Type(), member->Source(),
+ param_or_ret,
/*is_struct_member*/ true, member->Location())) {
AddNote("while analyzing entry point '" + symbols_.NameFor(decl->symbol) + "'",
decl->source);
@@ -1654,7 +1667,8 @@
return false;
}
- if (param_type->Is<sem::Pointer>()) {
+ if (param_type->Is<sem::Pointer>() &&
+ !enabled_extensions_.Contains(ast::Extension::kChromiumExperimentalFullPtrParameters)) {
// https://gpuweb.github.io/gpuweb/wgsl/#function-restriction
// Each argument of pointer type to a user-defined function must have the same memory
// view as its root identifier.
@@ -1749,12 +1763,13 @@
}
}
- if (array_type->IsRuntimeSized()) {
+ auto* c = array_type->Count();
+ if (c->Is<sem::RuntimeArrayCount>()) {
AddError("cannot construct a runtime-sized array", ctor->source);
return false;
}
- if (array_type->IsOverrideSized()) {
+ if (c->IsAnyOf<sem::NamedOverrideArrayCount, sem::UnnamedOverrideArrayCount>()) {
AddError("cannot construct an array that has an override-expression count", ctor->source);
return false;
}
@@ -1764,7 +1779,12 @@
return false;
}
- const auto count = std::get<sem::ConstantArrayCount>(array_type->Count()).value;
+ if (!c->Is<sem::ConstantArrayCount>()) {
+ TINT_ICE(Resolver, diagnostics_) << "Invalid ArrayCount found";
+ return false;
+ }
+
+ const auto count = c->As<sem::ConstantArrayCount>()->value;
if (!values.IsEmpty() && (values.Length() != count)) {
std::string fm = values.Length() < count ? "few" : "many";
AddError("array initializer has too " + fm + " elements: expected " +
@@ -2000,17 +2020,17 @@
bool Validator::Structure(const sem::Struct* str, ast::PipelineStage stage) const {
if (str->Members().empty()) {
- AddError("structures must have at least one member", str->Declaration()->source);
+ AddError("structures must have at least one member", str->Source());
return false;
}
utils::Hashset<uint32_t, 8> locations;
for (auto* member : str->Members()) {
if (auto* r = member->Type()->As<sem::Array>()) {
- if (r->IsRuntimeSized()) {
+ if (r->Count()->Is<sem::RuntimeArrayCount>()) {
if (member != str->Members().back()) {
AddError("runtime arrays may only appear as the last member of a struct",
- member->Declaration()->source);
+ member->Source());
return false;
}
}
@@ -2022,7 +2042,7 @@
} else if (!IsFixedFootprint(member->Type())) {
AddError(
"a struct that contains a runtime array cannot be nested inside another struct",
- member->Declaration()->source);
+ member->Source());
return false;
}
@@ -2041,7 +2061,7 @@
has_location = true;
TINT_ASSERT(Resolver, member->Location().has_value());
if (!LocationAttribute(location, member->Location().value(), member->Type(),
- locations, stage, member->Declaration()->source)) {
+ locations, stage, member->Source())) {
return false;
}
return true;
@@ -2379,7 +2399,7 @@
bool Validator::IsArrayWithOverrideCount(const sem::Type* ty) const {
if (auto* arr = ty->UnwrapRef()->As<sem::Array>()) {
- if (arr->IsOverrideSized()) {
+ if (arr->Count()->IsAnyOf<sem::NamedOverrideArrayCount, sem::UnnamedOverrideArrayCount>()) {
return true;
}
}
diff --git a/src/tint/resolver/validator_is_storeable_test.cc b/src/tint/resolver/validator_is_storeable_test.cc
index 9fa064a..cd079ce 100644
--- a/src/tint/resolver/validator_is_storeable_test.cc
+++ b/src/tint/resolver/validator_is_storeable_test.cc
@@ -89,13 +89,14 @@
}
TEST_F(ValidatorIsStorableTest, ArraySizedOfStorable) {
- auto* arr =
- create<sem::Array>(create<sem::I32>(), sem::ConstantArrayCount{5u}, 4u, 20u, 4u, 4u);
+ auto* arr = create<sem::Array>(create<sem::I32>(), create<sem::ConstantArrayCount>(5u), 4u, 20u,
+ 4u, 4u);
EXPECT_TRUE(v()->IsStorable(arr));
}
TEST_F(ValidatorIsStorableTest, ArrayUnsizedOfStorable) {
- auto* arr = create<sem::Array>(create<sem::I32>(), sem::RuntimeArrayCount{}, 4u, 4u, 4u, 4u);
+ auto* arr =
+ create<sem::Array>(create<sem::I32>(), create<sem::RuntimeArrayCount>(), 4u, 4u, 4u, 4u);
EXPECT_TRUE(v()->IsStorable(arr));
}
diff --git a/src/tint/sem/array.cc b/src/tint/sem/array.cc
index d61d430..207a627 100644
--- a/src/tint/sem/array.cc
+++ b/src/tint/sem/array.cc
@@ -28,10 +28,10 @@
namespace {
-TypeFlags FlagsFrom(const Type* element, ArrayCount count) {
+TypeFlags FlagsFrom(const Type* element, const ArrayCount* count) {
TypeFlags flags;
// Only constant-expression sized arrays are constructible
- if (std::holds_alternative<ConstantArrayCount>(count)) {
+ if (count->Is<ConstantArrayCount>()) {
if (element->IsConstructible()) {
flags.Add(TypeFlag::kConstructable);
}
@@ -39,9 +39,7 @@
flags.Add(TypeFlag::kCreationFixedFootprint);
}
}
- if (std::holds_alternative<ConstantArrayCount>(count) ||
- std::holds_alternative<NamedOverrideArrayCount>(count) ||
- std::holds_alternative<UnnamedOverrideArrayCount>(count)) {
+ if (count->IsAnyOf<ConstantArrayCount, NamedOverrideArrayCount, UnnamedOverrideArrayCount>()) {
if (element->HasFixedFootprint()) {
flags.Add(TypeFlag::kFixedFootprint);
}
@@ -56,7 +54,7 @@
"Was the SubstituteOverride transform run?";
Array::Array(const Type* element,
- ArrayCount count,
+ const ArrayCount* count,
uint32_t align,
uint32_t size,
uint32_t stride,
@@ -91,11 +89,11 @@
out << "@stride(" << stride_ << ") ";
}
out << "array<" << element_->FriendlyName(symbols);
- if (auto* const_count = std::get_if<ConstantArrayCount>(&count_)) {
+ if (auto* const_count = count_->As<ConstantArrayCount>()) {
out << ", " << const_count->value;
- } else if (auto* named_override_count = std::get_if<NamedOverrideArrayCount>(&count_)) {
+ } else if (auto* named_override_count = count_->As<NamedOverrideArrayCount>()) {
out << ", " << symbols.NameFor(named_override_count->variable->Declaration()->symbol);
- } else if (std::holds_alternative<UnnamedOverrideArrayCount>(count_)) {
+ } else if (count_->Is<UnnamedOverrideArrayCount>()) {
out << ", [unnamed override-expression]";
}
out << ">";
diff --git a/src/tint/sem/array.h b/src/tint/sem/array.h
index 4047ae4..7a484e5 100644
--- a/src/tint/sem/array.h
+++ b/src/tint/sem/array.h
@@ -20,6 +20,7 @@
#include <string>
#include <variant>
+#include "src/tint/sem/array_count.h"
#include "src/tint/sem/node.h"
#include "src/tint/sem/type.h"
#include "src/tint/utils/compiler_macros.h"
@@ -33,115 +34,6 @@
namespace tint::sem {
-/// The variant of an ArrayCount when the array is a const-expression.
-/// Example:
-/// ```
-/// const N = 123;
-/// type arr = array<i32, N>
-/// ```
-struct ConstantArrayCount {
- /// The array count constant-expression value.
- uint32_t value;
-};
-
-/// The variant of an ArrayCount when the count is a named override variable.
-/// Example:
-/// ```
-/// override N : i32;
-/// type arr = array<i32, N>
-/// ```
-struct NamedOverrideArrayCount {
- /// The `override` variable.
- const GlobalVariable* variable;
-};
-
-/// The variant of an ArrayCount when the count is an unnamed override variable.
-/// Example:
-/// ```
-/// override N : i32;
-/// type arr = array<i32, N*2>
-/// ```
-struct UnnamedOverrideArrayCount {
- /// The unnamed override expression.
- /// Note: Each AST expression gets a unique semantic expression node, so two equivalent AST
- /// expressions will not result in the same `expr` pointer. This property is important to ensure
- /// that two array declarations with equivalent AST expressions do not compare equal.
- /// For example, consider:
- /// ```
- /// override size : u32;
- /// var<workgroup> a : array<f32, size * 2>;
- /// var<workgroup> b : array<f32, size * 2>;
- /// ```
- // The array count for `a` and `b` have equivalent AST expressions, but the types for `a` and
- // `b` must not compare equal.
- const Expression* expr;
-};
-
-/// The variant of an ArrayCount when the array is is runtime-sized.
-/// Example:
-/// ```
-/// type arr = array<i32>
-/// ```
-struct RuntimeArrayCount {};
-
-/// An array count is either a constant-expression value, a named override identifier, an unnamed
-/// override identifier, or runtime-sized.
-using ArrayCount = std::variant<ConstantArrayCount,
- NamedOverrideArrayCount,
- UnnamedOverrideArrayCount,
- RuntimeArrayCount>;
-
-/// Equality operator
-/// @param a the LHS ConstantArrayCount
-/// @param b the RHS ConstantArrayCount
-/// @returns true if @p a is equal to @p b
-inline bool operator==(const ConstantArrayCount& a, const ConstantArrayCount& b) {
- return a.value == b.value;
-}
-
-/// Equality operator
-/// @param a the LHS OverrideArrayCount
-/// @param b the RHS OverrideArrayCount
-/// @returns true if @p a is equal to @p b
-inline bool operator==(const NamedOverrideArrayCount& a, const NamedOverrideArrayCount& b) {
- return a.variable == b.variable;
-}
-
-/// Equality operator
-/// @param a the LHS OverrideArrayCount
-/// @param b the RHS OverrideArrayCount
-/// @returns true if @p a is equal to @p b
-inline bool operator==(const UnnamedOverrideArrayCount& a, const UnnamedOverrideArrayCount& b) {
- return a.expr == b.expr;
-}
-
-/// Equality operator
-/// @returns true
-inline bool operator==(const RuntimeArrayCount&, const RuntimeArrayCount&) {
- return true;
-}
-
-/// Equality operator
-/// @param a the LHS ArrayCount
-/// @param b the RHS count
-/// @returns true if @p a is equal to @p b
-template <typename T,
- typename = std::enable_if_t<
- std::is_same_v<T, ConstantArrayCount> || std::is_same_v<T, NamedOverrideArrayCount> ||
- std::is_same_v<T, UnnamedOverrideArrayCount> || std::is_same_v<T, RuntimeArrayCount>>>
-inline bool operator==(const ArrayCount& a, const T& b) {
- TINT_BEGIN_DISABLE_WARNING(UNREACHABLE_CODE);
- return std::visit(
- [&](auto count) {
- if constexpr (std::is_same_v<std::decay_t<decltype(count)>, T>) {
- return count == b;
- }
- return false;
- },
- a);
- TINT_END_DISABLE_WARNING(UNREACHABLE_CODE);
-}
-
/// Array holds the semantic information for Array nodes.
class Array final : public Castable<Array, Type> {
public:
@@ -161,7 +53,7 @@
/// of the array to the start of the next element, if there was no `@stride`
/// attribute applied.
Array(Type const* element,
- ArrayCount count,
+ const ArrayCount* count,
uint32_t align,
uint32_t size,
uint32_t stride,
@@ -178,11 +70,11 @@
Type const* ElemType() const { return element_; }
/// @returns the number of elements in the array.
- const ArrayCount& Count() const { return count_; }
+ const ArrayCount* Count() const { return count_; }
/// @returns the array count if the count is a const-expression, otherwise returns nullopt.
inline std::optional<uint32_t> ConstantCount() const {
- if (auto* count = std::get_if<ConstantArrayCount>(&count_)) {
+ if (auto* count = count_->As<ConstantArrayCount>()) {
return count->value;
}
return std::nullopt;
@@ -211,36 +103,6 @@
/// natural stride
bool IsStrideImplicit() const { return stride_ == implicit_stride_; }
- /// @returns true if this array is sized using an const-expression
- bool IsConstantSized() const { return std::holds_alternative<ConstantArrayCount>(count_); }
-
- /// @returns true if this array is sized using a named override variable
- bool IsNamedOverrideSized() const {
- return std::holds_alternative<NamedOverrideArrayCount>(count_);
- }
-
- /// @returns true if this array is sized using an unnamed override variable
- bool IsUnnamedOverrideSized() const {
- return std::holds_alternative<UnnamedOverrideArrayCount>(count_);
- }
-
- /// @returns true if this array is sized using a named or unnamed override variable
- bool IsOverrideSized() const { return IsNamedOverrideSized() || IsUnnamedOverrideSized(); }
-
- /// @returns true if this array is runtime sized
- bool IsRuntimeSized() const { return std::holds_alternative<RuntimeArrayCount>(count_); }
-
- /// Records that this array type (transitively) references the given override variable.
- /// @param var the module-scope override variable
- void AddTransitivelyReferencedOverride(const GlobalVariable* var) {
- referenced_overrides_.Add(var);
- }
-
- /// @returns all transitively referenced override variables
- const utils::UniqueVector<const GlobalVariable*, 4>& TransitivelyReferencedOverrides() const {
- return referenced_overrides_;
- }
-
/// @param symbols the program's symbol table
/// @returns the name for this type that closely resembles how it would be
/// declared in WGSL.
@@ -248,59 +110,13 @@
private:
Type const* const element_;
- const ArrayCount count_;
+ const ArrayCount* count_;
const uint32_t align_;
const uint32_t size_;
const uint32_t stride_;
const uint32_t implicit_stride_;
- utils::UniqueVector<const GlobalVariable*, 4> referenced_overrides_;
};
} // namespace tint::sem
-namespace std {
-
-/// Custom std::hash specialization for tint::sem::ConstantArrayCount.
-template <>
-class hash<tint::sem::ConstantArrayCount> {
- public:
- /// @param count the count to hash
- /// @return the hash value
- inline std::size_t operator()(const tint::sem::ConstantArrayCount& count) const {
- return std::hash<decltype(count.value)>()(count.value);
- }
-};
-
-/// Custom std::hash specialization for tint::sem::NamedOverrideArrayCount.
-template <>
-class hash<tint::sem::NamedOverrideArrayCount> {
- public:
- /// @param count the count to hash
- /// @return the hash value
- inline std::size_t operator()(const tint::sem::NamedOverrideArrayCount& count) const {
- return std::hash<decltype(count.variable)>()(count.variable);
- }
-};
-
-/// Custom std::hash specialization for tint::sem::UnnamedOverrideArrayCount.
-template <>
-class hash<tint::sem::UnnamedOverrideArrayCount> {
- public:
- /// @param count the count to hash
- /// @return the hash value
- inline std::size_t operator()(const tint::sem::UnnamedOverrideArrayCount& count) const {
- return std::hash<decltype(count.expr)>()(count.expr);
- }
-};
-
-/// Custom std::hash specialization for tint::sem::RuntimeArrayCount.
-template <>
-class hash<tint::sem::RuntimeArrayCount> {
- public:
- /// @return the hash value
- inline std::size_t operator()(const tint::sem::RuntimeArrayCount&) const { return 42; }
-};
-
-} // namespace std
-
#endif // SRC_TINT_SEM_ARRAY_H_
diff --git a/src/tint/sem/array_count.cc b/src/tint/sem/array_count.cc
new file mode 100644
index 0000000..fa16639
--- /dev/null
+++ b/src/tint/sem/array_count.cc
@@ -0,0 +1,82 @@
+// Copyright 2021 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/sem/array_count.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::sem::ArrayCount);
+TINT_INSTANTIATE_TYPEINFO(tint::sem::ConstantArrayCount);
+TINT_INSTANTIATE_TYPEINFO(tint::sem::RuntimeArrayCount);
+TINT_INSTANTIATE_TYPEINFO(tint::sem::NamedOverrideArrayCount);
+TINT_INSTANTIATE_TYPEINFO(tint::sem::UnnamedOverrideArrayCount);
+
+namespace tint::sem {
+
+ArrayCount::ArrayCount() : Base() {}
+ArrayCount::~ArrayCount() = default;
+
+ConstantArrayCount::ConstantArrayCount(uint32_t val) : Base(), value(val) {}
+ConstantArrayCount::~ConstantArrayCount() = default;
+
+size_t ConstantArrayCount::Hash() const {
+ return static_cast<size_t>(TypeInfo::Of<ConstantArrayCount>().full_hashcode);
+}
+
+bool ConstantArrayCount::Equals(const ArrayCount& other) const {
+ if (auto* v = other.As<ConstantArrayCount>()) {
+ return value == v->value;
+ }
+ return false;
+}
+
+RuntimeArrayCount::RuntimeArrayCount() : Base() {}
+RuntimeArrayCount::~RuntimeArrayCount() = default;
+
+size_t RuntimeArrayCount::Hash() const {
+ return static_cast<size_t>(TypeInfo::Of<RuntimeArrayCount>().full_hashcode);
+}
+
+bool RuntimeArrayCount::Equals(const ArrayCount& other) const {
+ return other.Is<RuntimeArrayCount>();
+}
+
+NamedOverrideArrayCount::NamedOverrideArrayCount(const GlobalVariable* var)
+ : Base(), variable(var) {}
+NamedOverrideArrayCount::~NamedOverrideArrayCount() = default;
+
+size_t NamedOverrideArrayCount::Hash() const {
+ return static_cast<size_t>(TypeInfo::Of<NamedOverrideArrayCount>().full_hashcode);
+}
+
+bool NamedOverrideArrayCount::Equals(const ArrayCount& other) const {
+ if (auto* v = other.As<NamedOverrideArrayCount>()) {
+ return variable == v->variable;
+ }
+ return false;
+}
+
+UnnamedOverrideArrayCount::UnnamedOverrideArrayCount(const Expression* e) : Base(), expr(e) {}
+UnnamedOverrideArrayCount::~UnnamedOverrideArrayCount() = default;
+
+size_t UnnamedOverrideArrayCount::Hash() const {
+ return static_cast<size_t>(TypeInfo::Of<UnnamedOverrideArrayCount>().full_hashcode);
+}
+
+bool UnnamedOverrideArrayCount::Equals(const ArrayCount& other) const {
+ if (auto* v = other.As<UnnamedOverrideArrayCount>()) {
+ return expr == v->expr;
+ }
+ return false;
+}
+
+} // namespace tint::sem
diff --git a/src/tint/sem/array_count.h b/src/tint/sem/array_count.h
new file mode 100644
index 0000000..eb1a001
--- /dev/null
+++ b/src/tint/sem/array_count.h
@@ -0,0 +1,170 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_TINT_SEM_ARRAY_COUNT_H_
+#define SRC_TINT_SEM_ARRAY_COUNT_H_
+
+#include <functional>
+#include <string>
+
+#include "src/tint/sem/expression.h"
+#include "src/tint/sem/node.h"
+#include "src/tint/sem/variable.h"
+
+namespace tint::sem {
+
+/// An array count
+class ArrayCount : public Castable<ArrayCount, Node> {
+ public:
+ ~ArrayCount() override;
+
+ /// @returns a hash of the array count.
+ virtual size_t Hash() const = 0;
+
+ /// @param t other array count
+ /// @returns true if this array count is equal to the given array count
+ virtual bool Equals(const ArrayCount& t) const = 0;
+
+ protected:
+ ArrayCount();
+};
+
+/// The variant of an ArrayCount when the array is a const-expression.
+/// Example:
+/// ```
+/// const N = 123;
+/// type arr = array<i32, N>
+/// ```
+class ConstantArrayCount final : public Castable<ConstantArrayCount, ArrayCount> {
+ public:
+ /// Constructor
+ /// @param val the constant-expression value
+ explicit ConstantArrayCount(uint32_t val);
+ ~ConstantArrayCount() override;
+
+ /// @returns a hash of the array count.
+ size_t Hash() const override;
+
+ /// @param t other array count
+ /// @returns true if this array count is equal to the given array count
+ bool Equals(const ArrayCount& t) const override;
+
+ /// The array count constant-expression value.
+ uint32_t value;
+};
+
+/// The variant of an ArrayCount when the array is is runtime-sized.
+/// Example:
+/// ```
+/// type arr = array<i32>
+/// ```
+class RuntimeArrayCount final : public Castable<RuntimeArrayCount, ArrayCount> {
+ public:
+ /// Constructor
+ RuntimeArrayCount();
+ ~RuntimeArrayCount() override;
+
+ /// @returns a hash of the array count.
+ size_t Hash() const override;
+
+ /// @param t other array count
+ /// @returns true if this array count is equal to the given array count
+ bool Equals(const ArrayCount& t) const override;
+};
+
+/// The variant of an ArrayCount when the count is a named override variable.
+/// Example:
+/// ```
+/// override N : i32;
+/// type arr = array<i32, N>
+/// ```
+class NamedOverrideArrayCount final : public Castable<NamedOverrideArrayCount, ArrayCount> {
+ public:
+ /// Constructor
+ /// @param var the `override` variable
+ explicit NamedOverrideArrayCount(const GlobalVariable* var);
+ ~NamedOverrideArrayCount() override;
+
+ /// @returns a hash of the array count.
+ size_t Hash() const override;
+
+ /// @param t other array count
+ /// @returns true if this array count is equal to the given array count
+ bool Equals(const ArrayCount& t) const override;
+
+ /// The `override` variable.
+ const GlobalVariable* variable;
+};
+
+/// The variant of an ArrayCount when the count is an unnamed override variable.
+/// Example:
+/// ```
+/// override N : i32;
+/// type arr = array<i32, N*2>
+/// ```
+class UnnamedOverrideArrayCount final : public Castable<UnnamedOverrideArrayCount, ArrayCount> {
+ public:
+ /// Constructor
+ /// @param e the override expression
+ explicit UnnamedOverrideArrayCount(const Expression* e);
+ ~UnnamedOverrideArrayCount() override;
+
+ /// @returns a hash of the array count.
+ size_t Hash() const override;
+
+ /// @param t other array count
+ /// @returns true if this array count is equal to the given array count
+ bool Equals(const ArrayCount& t) const override;
+
+ /// The unnamed override expression.
+ /// Note: Each AST expression gets a unique semantic expression node, so two equivalent AST
+ /// expressions will not result in the same `expr` pointer. This property is important to ensure
+ /// that two array declarations with equivalent AST expressions do not compare equal.
+ /// For example, consider:
+ /// ```
+ /// override size : u32;
+ /// var<workgroup> a : array<f32, size * 2>;
+ /// var<workgroup> b : array<f32, size * 2>;
+ /// ```
+ // The array count for `a` and `b` have equivalent AST expressions, but the types for `a` and
+ // `b` must not compare equal.
+ const Expression* expr;
+};
+
+} // namespace tint::sem
+
+namespace std {
+
+/// std::hash specialization for tint::sem::ArrayCount
+template <>
+struct hash<tint::sem::ArrayCount> {
+ /// @param a the array count to obtain a hash from
+ /// @returns the hash of the array count
+ size_t operator()(const tint::sem::ArrayCount& a) const { return a.Hash(); }
+};
+
+/// std::equal_to specialization for tint::sem::ArrayCount
+template <>
+struct equal_to<tint::sem::ArrayCount> {
+ /// @param a the first array count to compare
+ /// @param b the second array count to compare
+ /// @returns true if the two array counts are equal
+ bool operator()(const tint::sem::ArrayCount& a, const tint::sem::ArrayCount& b) const {
+ return a.Equals(b);
+ }
+};
+
+} // namespace std
+
+#endif // SRC_TINT_SEM_ARRAY_COUNT_H_
diff --git a/src/tint/sem/array_test.cc b/src/tint/sem/array_test.cc
index a51b492..a2bc3d3 100644
--- a/src/tint/sem/array_test.cc
+++ b/src/tint/sem/array_test.cc
@@ -21,22 +21,22 @@
using ArrayTest = TestHelper;
TEST_F(ArrayTest, CreateSizedArray) {
- auto* a = create<Array>(create<U32>(), ConstantArrayCount{2u}, 4u, 8u, 32u, 16u);
- auto* b = create<Array>(create<U32>(), ConstantArrayCount{2u}, 4u, 8u, 32u, 16u);
- auto* c = create<Array>(create<U32>(), ConstantArrayCount{3u}, 4u, 8u, 32u, 16u);
- auto* d = create<Array>(create<U32>(), ConstantArrayCount{2u}, 5u, 8u, 32u, 16u);
- auto* e = create<Array>(create<U32>(), ConstantArrayCount{2u}, 4u, 9u, 32u, 16u);
- auto* f = create<Array>(create<U32>(), ConstantArrayCount{2u}, 4u, 8u, 33u, 16u);
- auto* g = create<Array>(create<U32>(), ConstantArrayCount{2u}, 4u, 8u, 33u, 17u);
+ auto* a = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
+ auto* b = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
+ auto* c = create<Array>(create<U32>(), create<ConstantArrayCount>(3u), 4u, 8u, 32u, 16u);
+ auto* d = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 5u, 8u, 32u, 16u);
+ auto* e = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 9u, 32u, 16u);
+ auto* f = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 33u, 16u);
+ auto* g = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 33u, 17u);
EXPECT_EQ(a->ElemType(), create<U32>());
- EXPECT_EQ(a->Count(), ConstantArrayCount{2u});
+ EXPECT_EQ(a->Count(), create<ConstantArrayCount>(2u));
EXPECT_EQ(a->Align(), 4u);
EXPECT_EQ(a->Size(), 8u);
EXPECT_EQ(a->Stride(), 32u);
EXPECT_EQ(a->ImplicitStride(), 16u);
EXPECT_FALSE(a->IsStrideImplicit());
- EXPECT_FALSE(a->IsRuntimeSized());
+ EXPECT_FALSE(a->Count()->Is<RuntimeArrayCount>());
EXPECT_EQ(a, b);
EXPECT_NE(a, c);
@@ -47,21 +47,21 @@
}
TEST_F(ArrayTest, CreateRuntimeArray) {
- auto* a = create<Array>(create<U32>(), RuntimeArrayCount{}, 4u, 8u, 32u, 32u);
- auto* b = create<Array>(create<U32>(), RuntimeArrayCount{}, 4u, 8u, 32u, 32u);
- auto* c = create<Array>(create<U32>(), RuntimeArrayCount{}, 5u, 8u, 32u, 32u);
- auto* d = create<Array>(create<U32>(), RuntimeArrayCount{}, 4u, 9u, 32u, 32u);
- auto* e = create<Array>(create<U32>(), RuntimeArrayCount{}, 4u, 8u, 33u, 32u);
- auto* f = create<Array>(create<U32>(), RuntimeArrayCount{}, 4u, 8u, 33u, 17u);
+ auto* a = create<Array>(create<U32>(), create<RuntimeArrayCount>(), 4u, 8u, 32u, 32u);
+ auto* b = create<Array>(create<U32>(), create<RuntimeArrayCount>(), 4u, 8u, 32u, 32u);
+ auto* c = create<Array>(create<U32>(), create<RuntimeArrayCount>(), 5u, 8u, 32u, 32u);
+ auto* d = create<Array>(create<U32>(), create<RuntimeArrayCount>(), 4u, 9u, 32u, 32u);
+ auto* e = create<Array>(create<U32>(), create<RuntimeArrayCount>(), 4u, 8u, 33u, 32u);
+ auto* f = create<Array>(create<U32>(), create<RuntimeArrayCount>(), 4u, 8u, 33u, 17u);
EXPECT_EQ(a->ElemType(), create<U32>());
- EXPECT_EQ(a->Count(), sem::RuntimeArrayCount{});
+ EXPECT_EQ(a->Count(), create<sem::RuntimeArrayCount>());
EXPECT_EQ(a->Align(), 4u);
EXPECT_EQ(a->Size(), 8u);
EXPECT_EQ(a->Stride(), 32u);
EXPECT_EQ(a->ImplicitStride(), 32u);
EXPECT_TRUE(a->IsStrideImplicit());
- EXPECT_TRUE(a->IsRuntimeSized());
+ EXPECT_TRUE(a->Count()->Is<RuntimeArrayCount>());
EXPECT_EQ(a, b);
EXPECT_NE(a, c);
@@ -71,13 +71,13 @@
}
TEST_F(ArrayTest, Hash) {
- auto* a = create<Array>(create<U32>(), ConstantArrayCount{2u}, 4u, 8u, 32u, 16u);
- auto* b = create<Array>(create<U32>(), ConstantArrayCount{2u}, 4u, 8u, 32u, 16u);
- auto* c = create<Array>(create<U32>(), ConstantArrayCount{3u}, 4u, 8u, 32u, 16u);
- auto* d = create<Array>(create<U32>(), ConstantArrayCount{2u}, 5u, 8u, 32u, 16u);
- auto* e = create<Array>(create<U32>(), ConstantArrayCount{2u}, 4u, 9u, 32u, 16u);
- auto* f = create<Array>(create<U32>(), ConstantArrayCount{2u}, 4u, 8u, 33u, 16u);
- auto* g = create<Array>(create<U32>(), ConstantArrayCount{2u}, 4u, 8u, 33u, 17u);
+ auto* a = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
+ auto* b = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
+ auto* c = create<Array>(create<U32>(), create<ConstantArrayCount>(3u), 4u, 8u, 32u, 16u);
+ auto* d = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 5u, 8u, 32u, 16u);
+ auto* e = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 9u, 32u, 16u);
+ auto* f = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 33u, 16u);
+ auto* g = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 33u, 17u);
EXPECT_EQ(a->Hash(), b->Hash());
EXPECT_NE(a->Hash(), c->Hash());
@@ -88,13 +88,13 @@
}
TEST_F(ArrayTest, Equals) {
- auto* a = create<Array>(create<U32>(), ConstantArrayCount{2u}, 4u, 8u, 32u, 16u);
- auto* b = create<Array>(create<U32>(), ConstantArrayCount{2u}, 4u, 8u, 32u, 16u);
- auto* c = create<Array>(create<U32>(), ConstantArrayCount{3u}, 4u, 8u, 32u, 16u);
- auto* d = create<Array>(create<U32>(), ConstantArrayCount{2u}, 5u, 8u, 32u, 16u);
- auto* e = create<Array>(create<U32>(), ConstantArrayCount{2u}, 4u, 9u, 32u, 16u);
- auto* f = create<Array>(create<U32>(), ConstantArrayCount{2u}, 4u, 8u, 33u, 16u);
- auto* g = create<Array>(create<U32>(), ConstantArrayCount{2u}, 4u, 8u, 33u, 17u);
+ auto* a = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
+ auto* b = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
+ auto* c = create<Array>(create<U32>(), create<ConstantArrayCount>(3u), 4u, 8u, 32u, 16u);
+ auto* d = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 5u, 8u, 32u, 16u);
+ auto* e = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 9u, 32u, 16u);
+ auto* f = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 33u, 16u);
+ auto* g = create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 33u, 17u);
EXPECT_TRUE(a->Equals(*b));
EXPECT_FALSE(a->Equals(*c));
@@ -106,32 +106,34 @@
}
TEST_F(ArrayTest, FriendlyNameRuntimeSized) {
- auto* arr = create<Array>(create<I32>(), RuntimeArrayCount{}, 0u, 4u, 4u, 4u);
+ auto* arr = create<Array>(create<I32>(), create<RuntimeArrayCount>(), 0u, 4u, 4u, 4u);
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32>");
}
TEST_F(ArrayTest, FriendlyNameStaticSized) {
- auto* arr = create<Array>(create<I32>(), ConstantArrayCount{5u}, 4u, 20u, 4u, 4u);
+ auto* arr = create<Array>(create<I32>(), create<ConstantArrayCount>(5u), 4u, 20u, 4u, 4u);
EXPECT_EQ(arr->FriendlyName(Symbols()), "array<i32, 5>");
}
TEST_F(ArrayTest, FriendlyNameRuntimeSizedNonImplicitStride) {
- auto* arr = create<Array>(create<I32>(), RuntimeArrayCount{}, 0u, 4u, 8u, 4u);
+ auto* arr = create<Array>(create<I32>(), create<RuntimeArrayCount>(), 0u, 4u, 8u, 4u);
EXPECT_EQ(arr->FriendlyName(Symbols()), "@stride(8) array<i32>");
}
TEST_F(ArrayTest, FriendlyNameStaticSizedNonImplicitStride) {
- auto* arr = create<Array>(create<I32>(), ConstantArrayCount{5u}, 4u, 20u, 8u, 4u);
+ auto* arr = create<Array>(create<I32>(), create<ConstantArrayCount>(5u), 4u, 20u, 8u, 4u);
EXPECT_EQ(arr->FriendlyName(Symbols()), "@stride(8) array<i32, 5>");
}
TEST_F(ArrayTest, IsConstructable) {
- auto* fixed_sized = create<Array>(create<U32>(), ConstantArrayCount{2u}, 4u, 8u, 32u, 16u);
+ auto* fixed_sized =
+ create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
auto* named_override_sized =
- create<Array>(create<U32>(), NamedOverrideArrayCount{}, 4u, 8u, 32u, 16u);
+ create<Array>(create<U32>(), create<NamedOverrideArrayCount>(nullptr), 4u, 8u, 32u, 16u);
auto* unnamed_override_sized =
- create<Array>(create<U32>(), UnnamedOverrideArrayCount{}, 4u, 8u, 32u, 16u);
- auto* runtime_sized = create<Array>(create<U32>(), RuntimeArrayCount{}, 4u, 8u, 32u, 16u);
+ create<Array>(create<U32>(), create<UnnamedOverrideArrayCount>(nullptr), 4u, 8u, 32u, 16u);
+ auto* runtime_sized =
+ create<Array>(create<U32>(), create<RuntimeArrayCount>(), 4u, 8u, 32u, 16u);
EXPECT_TRUE(fixed_sized->IsConstructible());
EXPECT_FALSE(named_override_sized->IsConstructible());
@@ -140,12 +142,14 @@
}
TEST_F(ArrayTest, HasCreationFixedFootprint) {
- auto* fixed_sized = create<Array>(create<U32>(), ConstantArrayCount{2u}, 4u, 8u, 32u, 16u);
+ auto* fixed_sized =
+ create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
auto* named_override_sized =
- create<Array>(create<U32>(), NamedOverrideArrayCount{}, 4u, 8u, 32u, 16u);
+ create<Array>(create<U32>(), create<NamedOverrideArrayCount>(nullptr), 4u, 8u, 32u, 16u);
auto* unnamed_override_sized =
- create<Array>(create<U32>(), UnnamedOverrideArrayCount{}, 4u, 8u, 32u, 16u);
- auto* runtime_sized = create<Array>(create<U32>(), RuntimeArrayCount{}, 4u, 8u, 32u, 16u);
+ create<Array>(create<U32>(), create<UnnamedOverrideArrayCount>(nullptr), 4u, 8u, 32u, 16u);
+ auto* runtime_sized =
+ create<Array>(create<U32>(), create<RuntimeArrayCount>(), 4u, 8u, 32u, 16u);
EXPECT_TRUE(fixed_sized->HasCreationFixedFootprint());
EXPECT_FALSE(named_override_sized->HasCreationFixedFootprint());
@@ -154,12 +158,14 @@
}
TEST_F(ArrayTest, HasFixedFootprint) {
- auto* fixed_sized = create<Array>(create<U32>(), ConstantArrayCount{2u}, 4u, 8u, 32u, 16u);
+ auto* fixed_sized =
+ create<Array>(create<U32>(), create<ConstantArrayCount>(2u), 4u, 8u, 32u, 16u);
auto* named_override_sized =
- create<Array>(create<U32>(), NamedOverrideArrayCount{}, 4u, 8u, 32u, 16u);
+ create<Array>(create<U32>(), create<NamedOverrideArrayCount>(nullptr), 4u, 8u, 32u, 16u);
auto* unnamed_override_sized =
- create<Array>(create<U32>(), UnnamedOverrideArrayCount{}, 4u, 8u, 32u, 16u);
- auto* runtime_sized = create<Array>(create<U32>(), RuntimeArrayCount{}, 4u, 8u, 32u, 16u);
+ create<Array>(create<U32>(), create<UnnamedOverrideArrayCount>(nullptr), 4u, 8u, 32u, 16u);
+ auto* runtime_sized =
+ create<Array>(create<U32>(), create<RuntimeArrayCount>(), 4u, 8u, 32u, 16u);
EXPECT_TRUE(fixed_sized->HasFixedFootprint());
EXPECT_TRUE(named_override_sized->HasFixedFootprint());
diff --git a/src/tint/sem/function.h b/src/tint/sem/function.h
index 973aa43..8f21f74 100644
--- a/src/tint/sem/function.h
+++ b/src/tint/sem/function.h
@@ -141,7 +141,7 @@
/// @returns the list of direct calls to functions / builtins made by this
/// function
- std::vector<const Call*> DirectCallStatements() const { return direct_calls_; }
+ std::vector<const Call*> DirectCalls() const { return direct_calls_; }
/// Adds a record of the direct function / builtin calls made by this
/// function
@@ -160,7 +160,7 @@
return nullptr;
}
- /// @returns the list of callsites of this function
+ /// @returns the list of callsites to this function
std::vector<const Call*> CallSites() const { return callsites_; }
/// Adds a record of a callsite to this function
diff --git a/src/tint/sem/info.h b/src/tint/sem/info.h
index 894b408..28b41a6 100644
--- a/src/tint/sem/info.h
+++ b/src/tint/sem/info.h
@@ -24,6 +24,7 @@
#include "src/tint/debug.h"
#include "src/tint/sem/node.h"
#include "src/tint/sem/type_mappings.h"
+#include "src/tint/utils/unique_vector.h"
// Forward declarations
namespace tint::sem {
@@ -44,6 +45,9 @@
using GetResultType =
std::conditional_t<std::is_same<SEM, InferFromAST>::value, SemanticNodeTypeFor<AST>, SEM>;
+ /// Alias to a unique vector of transitively referenced global variables
+ using TransitivelyReferenced = utils::UniqueVector<const GlobalVariable*, 4>;
+
/// Constructor
Info();
@@ -117,9 +121,30 @@
/// @returns the semantic module.
const sem::Module* Module() const { return module_; }
+ /// Records that this variable (transitively) references the given override variable.
+ /// @param from the item the variable is referenced from
+ /// @param var the module-scope override variable
+ void AddTransitivelyReferencedOverride(const CastableBase* from, const GlobalVariable* var) {
+ if (referenced_overrides_.count(from) == 0) {
+ referenced_overrides_.insert({from, TransitivelyReferenced{}});
+ }
+ referenced_overrides_[from].Add(var);
+ }
+
+ /// @param from the key to look up
+ /// @returns all transitively referenced override variables or nullptr if none set
+ const TransitivelyReferenced* TransitivelyReferencedOverrides(const CastableBase* from) const {
+ if (referenced_overrides_.count(from) == 0) {
+ return nullptr;
+ }
+ return &referenced_overrides_.at(from);
+ }
+
private:
// AST node index to semantic node
std::vector<const sem::Node*> nodes_;
+ // Lists transitively referenced overrides for the given item
+ std::unordered_map<const CastableBase*, TransitivelyReferenced> referenced_overrides_;
// The semantic module
sem::Module* module_ = nullptr;
};
diff --git a/src/tint/sem/struct.cc b/src/tint/sem/struct.cc
index d80a04a..c46e310 100644
--- a/src/tint/sem/struct.cc
+++ b/src/tint/sem/struct.cc
@@ -52,6 +52,7 @@
} // namespace
Struct::Struct(const ast::Struct* declaration,
+ tint::Source source,
Symbol name,
StructMemberList members,
uint32_t align,
@@ -59,6 +60,7 @@
uint32_t size_no_padding)
: Base(FlagsFrom(members)),
declaration_(declaration),
+ source_(source),
name_(name),
members_(std::move(members)),
align_(align),
@@ -80,7 +82,7 @@
const StructMember* Struct::FindMember(Symbol name) const {
for (auto* member : members_) {
- if (member->Declaration()->symbol == name) {
+ if (member->Name() == name) {
return member;
}
}
@@ -102,9 +104,7 @@
std::string Struct::Layout(const tint::SymbolTable& symbols) const {
std::stringstream ss;
- auto member_name_of = [&](const sem::StructMember* sm) {
- return symbols.NameFor(sm->Declaration()->symbol);
- };
+ auto member_name_of = [&](const sem::StructMember* sm) { return symbols.NameFor(sm->Name()); };
if (Members().empty()) {
return {};
@@ -168,6 +168,7 @@
}
StructMember::StructMember(const ast::StructMember* declaration,
+ tint::Source source,
Symbol name,
const sem::Type* type,
uint32_t index,
@@ -176,6 +177,7 @@
uint32_t size,
std::optional<uint32_t> location)
: declaration_(declaration),
+ source_(source),
name_(name),
type_(type),
index_(index),
diff --git a/src/tint/sem/struct.h b/src/tint/sem/struct.h
index 0ddfa23..831cf3e 100644
--- a/src/tint/sem/struct.h
+++ b/src/tint/sem/struct.h
@@ -57,6 +57,7 @@
public:
/// Constructor
/// @param declaration the AST structure declaration
+ /// @param source the source of the structure
/// @param name the name of the structure
/// @param members the structure members
/// @param align the byte alignment of the structure
@@ -64,6 +65,7 @@
/// @param size_no_padding size of the members without the end of structure
/// alignment padding
Struct(const ast::Struct* declaration,
+ tint::Source source,
Symbol name,
StructMemberList members,
uint32_t align,
@@ -83,6 +85,9 @@
/// @returns the struct
const ast::Struct* Declaration() const { return declaration_; }
+ /// @returns the source of the structure
+ tint::Source Source() const { return source_; }
+
/// @returns the name of the structure
Symbol Name() const { return name_; }
@@ -162,6 +167,7 @@
private:
ast::Struct const* const declaration_;
+ const tint::Source source_;
const Symbol name_;
const StructMemberList members_;
const uint32_t align_;
@@ -177,7 +183,8 @@
public:
/// Constructor
/// @param declaration the AST declaration node
- /// @param name the name of the structure
+ /// @param source the source of the struct member
+ /// @param name the name of the structure member
/// @param type the type of the member
/// @param index the index of the member in the structure
/// @param offset the byte offset from the base of the structure
@@ -185,6 +192,7 @@
/// @param size the byte size of the member
/// @param location the location attribute, if present
StructMember(const ast::StructMember* declaration,
+ tint::Source source,
Symbol name,
const sem::Type* type,
uint32_t index,
@@ -199,6 +207,9 @@
/// @returns the AST declaration node
const ast::StructMember* Declaration() const { return declaration_; }
+ /// @returns the source the struct member
+ const tint::Source& Source() const { return source_; }
+
/// @returns the name of the structure member
Symbol Name() const { return name_; }
@@ -229,6 +240,7 @@
private:
const ast::StructMember* const declaration_;
+ const tint::Source source_;
const Symbol name_;
const sem::Struct* struct_;
const sem::Type* type_;
diff --git a/src/tint/sem/struct_test.cc b/src/tint/sem/struct_test.cc
index a8b36ca..6a88307 100644
--- a/src/tint/sem/struct_test.cc
+++ b/src/tint/sem/struct_test.cc
@@ -26,8 +26,8 @@
auto name = Sym("S");
auto* impl = create<ast::Struct>(name, utils::Empty, utils::Empty);
auto* ptr = impl;
- auto* s = create<sem::Struct>(impl, impl->name, StructMemberList{}, 4u /* align */,
- 8u /* size */, 16u /* size_no_padding */);
+ auto* s = create<sem::Struct>(impl, impl->source, impl->name, StructMemberList{},
+ 4u /* align */, 8u /* size */, 16u /* size_no_padding */);
EXPECT_EQ(s->Declaration(), ptr);
EXPECT_EQ(s->Align(), 4u);
EXPECT_EQ(s->Size(), 8u);
@@ -36,22 +36,22 @@
TEST_F(StructTest, Hash) {
auto* a_impl = create<ast::Struct>(Sym("a"), utils::Empty, utils::Empty);
- auto* a = create<sem::Struct>(a_impl, a_impl->name, StructMemberList{}, 4u /* align */,
- 4u /* size */, 4u /* size_no_padding */);
+ auto* a = create<sem::Struct>(a_impl, a_impl->source, a_impl->name, StructMemberList{},
+ 4u /* align */, 4u /* size */, 4u /* size_no_padding */);
auto* b_impl = create<ast::Struct>(Sym("b"), utils::Empty, utils::Empty);
- auto* b = create<sem::Struct>(b_impl, b_impl->name, StructMemberList{}, 4u /* align */,
- 4u /* size */, 4u /* size_no_padding */);
+ auto* b = create<sem::Struct>(b_impl, b_impl->source, b_impl->name, StructMemberList{},
+ 4u /* align */, 4u /* size */, 4u /* size_no_padding */);
EXPECT_NE(a->Hash(), b->Hash());
}
TEST_F(StructTest, Equals) {
auto* a_impl = create<ast::Struct>(Sym("a"), utils::Empty, utils::Empty);
- auto* a = create<sem::Struct>(a_impl, a_impl->name, StructMemberList{}, 4u /* align */,
- 4u /* size */, 4u /* size_no_padding */);
+ auto* a = create<sem::Struct>(a_impl, a_impl->source, a_impl->name, StructMemberList{},
+ 4u /* align */, 4u /* size */, 4u /* size_no_padding */);
auto* b_impl = create<ast::Struct>(Sym("b"), utils::Empty, utils::Empty);
- auto* b = create<sem::Struct>(b_impl, b_impl->name, StructMemberList{}, 4u /* align */,
- 4u /* size */, 4u /* size_no_padding */);
+ auto* b = create<sem::Struct>(b_impl, b_impl->source, b_impl->name, StructMemberList{},
+ 4u /* align */, 4u /* size */, 4u /* size_no_padding */);
EXPECT_TRUE(a->Equals(*a));
EXPECT_FALSE(a->Equals(*b));
@@ -61,8 +61,8 @@
TEST_F(StructTest, FriendlyName) {
auto name = Sym("my_struct");
auto* impl = create<ast::Struct>(name, utils::Empty, utils::Empty);
- auto* s = create<sem::Struct>(impl, impl->name, StructMemberList{}, 4u /* align */,
- 4u /* size */, 4u /* size_no_padding */);
+ auto* s = create<sem::Struct>(impl, impl->source, impl->name, StructMemberList{},
+ 4u /* align */, 4u /* size */, 4u /* size_no_padding */);
EXPECT_EQ(s->FriendlyName(Symbols()), "my_struct");
}
diff --git a/src/tint/sem/type.cc b/src/tint/sem/type.cc
index f9db53b..3d25e7e 100644
--- a/src/tint/sem/type.cc
+++ b/src/tint/sem/type.cc
@@ -273,7 +273,7 @@
},
[&](const Array* a) {
if (count) {
- if (auto* const_count = std::get_if<ConstantArrayCount>(&a->Count())) {
+ if (auto* const_count = a->Count()->As<ConstantArrayCount>()) {
*count = const_count->value;
}
}
diff --git a/src/tint/sem/type_manager.h b/src/tint/sem/type_manager.h
index 636b7a0..33c42b3 100644
--- a/src/tint/sem/type_manager.h
+++ b/src/tint/sem/type_manager.h
@@ -19,16 +19,17 @@
#include <unordered_map>
#include <utility>
+#include "src/tint/sem/array_count.h"
#include "src/tint/sem/type.h"
#include "src/tint/utils/unique_allocator.h"
namespace tint::sem {
/// The type manager holds all the pointers to the known types.
-class TypeManager final : public utils::UniqueAllocator<Type> {
+class TypeManager final {
public:
/// Iterator is the type returned by begin() and end()
- using Iterator = utils::BlockAllocator<Type>::ConstIterator;
+ using TypeIterator = utils::BlockAllocator<Type>::ConstIterator;
/// Constructor
TypeManager();
@@ -55,30 +56,51 @@
/// @return the Manager that wraps `inner`
static TypeManager Wrap(const TypeManager& inner) {
TypeManager out;
- out.items = inner.items;
+ out.types_.Wrap(inner.types_);
+ out.array_counts_.Wrap(inner.array_counts_);
return out;
}
- /// @param args the arguments used to create the temporary type used for the search.
- /// @return a pointer to an instance of `T` with the provided arguments, or nullptr if the type
+ /// @param args the arguments used to construct the object.
+ /// @return a pointer to an instance of `T` with the provided arguments.
+ /// If an existing instance of `T` has been constructed, then the same
+ /// pointer is returned.
+ template <typename TYPE,
+ typename _ = std::enable_if<traits::IsTypeOrDerived<TYPE, sem::Type>>,
+ typename... ARGS>
+ TYPE* Get(ARGS&&... args) {
+ return types_.Get<TYPE>(std::forward<ARGS>(args)...);
+ }
+
+ /// @param args the arguments used to create the temporary used for the search.
+ /// @return a pointer to an instance of `T` with the provided arguments, or nullptr if the item
/// was not found.
- template <typename TYPE, typename... ARGS>
+ template <typename TYPE,
+ typename _ = std::enable_if<traits::IsTypeOrDerived<TYPE, sem::Type>>,
+ typename... ARGS>
TYPE* Find(ARGS&&... args) const {
- // Create a temporary T instance on the stack so that we can hash it, and
- // use it for equality lookup for the std::unordered_set.
- TYPE key{args...};
- auto hash = Hasher{}(key);
- auto it = items.find(Entry{hash, &key});
- if (it != items.end()) {
- return static_cast<TYPE*>(it->ptr);
- }
- return nullptr;
+ return types_.Find<TYPE>(std::forward<ARGS>(args)...);
+ }
+
+ /// @param args the arguments used to construct the object.
+ /// @return a pointer to an instance of `T` with the provided arguments.
+ /// If an existing instance of `T` has been constructed, then the same
+ /// pointer is returned.
+ template <typename TYPE,
+ typename _ = std::enable_if<traits::IsTypeOrDerived<TYPE, sem::ArrayCount>>,
+ typename... ARGS>
+ TYPE* GetArrayCount(ARGS&&... args) {
+ return array_counts_.Get<TYPE>(std::forward<ARGS>(args)...);
}
/// @returns an iterator to the beginning of the types
- Iterator begin() const { return allocator.Objects().begin(); }
+ TypeIterator begin() const { return types_.begin(); }
/// @returns an iterator to the end of the types
- Iterator end() const { return allocator.Objects().end(); }
+ TypeIterator end() const { return types_.end(); }
+
+ private:
+ utils::UniqueAllocator<Type> types_;
+ utils::UniqueAllocator<ArrayCount> array_counts_;
};
} // namespace tint::sem
diff --git a/src/tint/sem/type_test.cc b/src/tint/sem/type_test.cc
index aec9bde..9148322 100644
--- a/src/tint/sem/type_test.cc
+++ b/src/tint/sem/type_test.cc
@@ -45,10 +45,12 @@
const sem::Reference* ref_u32 =
create<Reference>(u32, ast::AddressSpace::kPrivate, ast::Access::kReadWrite);
const sem::Struct* str_f32 = create<Struct>(nullptr,
+ Source{},
Sym("str_f32"),
StructMemberList{
create<StructMember>(
/* declaration */ nullptr,
+ /* source */ Source{},
/* name */ Sym("x"),
/* type */ f32,
/* index */ 0u,
@@ -61,10 +63,12 @@
/* size*/ 4u,
/* size_no_padding*/ 4u);
const sem::Struct* str_f16 = create<Struct>(nullptr,
+ Source{},
Sym("str_f16"),
StructMemberList{
create<StructMember>(
/* declaration */ nullptr,
+ /* source */ Source{},
/* name */ Sym("x"),
/* type */ f16,
/* index */ 0u,
@@ -77,10 +81,12 @@
/* size*/ 4u,
/* size_no_padding*/ 4u);
sem::Struct* str_af = create<Struct>(nullptr,
+ Source{},
Sym("str_af"),
StructMemberList{
create<StructMember>(
/* declaration */ nullptr,
+ /* source */ Source{},
/* name */ Sym("x"),
/* type */ af,
/* index */ 0u,
@@ -94,63 +100,63 @@
/* size_no_padding*/ 4u);
const sem::Array* arr_i32 = create<Array>(
/* element */ i32,
- /* count */ ConstantArrayCount{5u},
+ /* count */ create<ConstantArrayCount>(5u),
/* align */ 4u,
/* size */ 5u * 4u,
/* stride */ 5u * 4u,
/* implicit_stride */ 5u * 4u);
const sem::Array* arr_ai = create<Array>(
/* element */ ai,
- /* count */ ConstantArrayCount{5u},
+ /* count */ create<ConstantArrayCount>(5u),
/* align */ 4u,
/* size */ 5u * 4u,
/* stride */ 5u * 4u,
/* implicit_stride */ 5u * 4u);
const sem::Array* arr_vec3_i32 = create<Array>(
/* element */ vec3_i32,
- /* count */ ConstantArrayCount{5u},
+ /* count */ create<ConstantArrayCount>(5u),
/* align */ 16u,
/* size */ 5u * 16u,
/* stride */ 5u * 16u,
/* implicit_stride */ 5u * 16u);
const sem::Array* arr_vec3_ai = create<Array>(
/* element */ vec3_ai,
- /* count */ ConstantArrayCount{5u},
+ /* count */ create<ConstantArrayCount>(5u),
/* align */ 16u,
/* size */ 5u * 16u,
/* stride */ 5u * 16u,
/* implicit_stride */ 5u * 16u);
const sem::Array* arr_mat4x3_f16 = create<Array>(
/* element */ mat4x3_f16,
- /* count */ ConstantArrayCount{5u},
+ /* count */ create<ConstantArrayCount>(5u),
/* align */ 32u,
/* size */ 5u * 32u,
/* stride */ 5u * 32u,
/* implicit_stride */ 5u * 32u);
const sem::Array* arr_mat4x3_f32 = create<Array>(
/* element */ mat4x3_f32,
- /* count */ ConstantArrayCount{5u},
+ /* count */ create<ConstantArrayCount>(5u),
/* align */ 64u,
/* size */ 5u * 64u,
/* stride */ 5u * 64u,
/* implicit_stride */ 5u * 64u);
const sem::Array* arr_mat4x3_af = create<Array>(
/* element */ mat4x3_af,
- /* count */ ConstantArrayCount{5u},
+ /* count */ create<ConstantArrayCount>(5u),
/* align */ 64u,
/* size */ 5u * 64u,
/* stride */ 5u * 64u,
/* implicit_stride */ 5u * 64u);
const sem::Array* arr_str_f16 = create<Array>(
/* element */ str_f16,
- /* count */ ConstantArrayCount{5u},
+ /* count */ create<ConstantArrayCount>(5u),
/* align */ 4u,
/* size */ 5u * 4u,
/* stride */ 5u * 4u,
/* implicit_stride */ 5u * 4u);
const sem::Array* arr_str_af = create<Array>(
/* element */ str_af,
- /* count */ ConstantArrayCount{5u},
+ /* count */ create<ConstantArrayCount>(5u),
/* align */ 4u,
/* size */ 5u * 4u,
/* stride */ 5u * 4u,
diff --git a/src/tint/sem/variable.h b/src/tint/sem/variable.h
index 08ffe99..b977797 100644
--- a/src/tint/sem/variable.h
+++ b/src/tint/sem/variable.h
@@ -183,23 +183,11 @@
/// @returns the location value for the parameter, if set
std::optional<uint32_t> Location() const { return location_; }
- /// Records that this variable (transitively) references the given override variable.
- /// @param var the module-scope override variable
- void AddTransitivelyReferencedOverride(const GlobalVariable* var) {
- referenced_overrides_.Add(var);
- }
-
- /// @returns all transitively referenced override variables
- const utils::UniqueVector<const GlobalVariable*, 4>& TransitivelyReferencedOverrides() const {
- return referenced_overrides_;
- }
-
private:
const sem::BindingPoint binding_point_;
tint::OverrideId override_id_;
std::optional<uint32_t> location_;
- utils::UniqueVector<const GlobalVariable*, 4> referenced_overrides_;
};
/// Parameter is a function parameter
@@ -231,7 +219,7 @@
return static_cast<const ast::Parameter*>(Variable::Declaration());
}
- /// @return the index of the parmeter in the function
+ /// @return the index of the parameter in the function
uint32_t Index() const { return index_; }
/// @returns the semantic usage for the parameter
diff --git a/src/tint/traits.h b/src/tint/traits.h
index 8dcc65b..441067e 100644
--- a/src/tint/traits.h
+++ b/src/tint/traits.h
@@ -160,6 +160,22 @@
using SliceTuple =
std::remove_pointer_t<decltype(detail::SwizzlePtrTy<TUPLE>(Range<OFFSET, COUNT>()))>;
+namespace detail {
+/// Base template for IsTypeIn
+template <class T, class TypeList>
+struct IsTypeIn;
+
+/// Specialization for IsTypeIn
+template <class T, template <class...> class TypeContainer, class... Ts>
+struct IsTypeIn<T, TypeContainer<Ts...>> : std::disjunction<std::is_same<T, Ts>...> {};
+} // namespace detail
+
+/// Evaluates to true if T is one of the types in the TypeContainer's template arguments.
+/// Works for std::variant, std::tuple, std::pair, or any class template where all parameters are
+/// types.
+template <typename T, typename TypeContainer>
+static constexpr bool IsTypeIn = detail::IsTypeIn<T, TypeContainer>::value;
+
} // namespace tint::traits
#endif // SRC_TINT_TRAITS_H_
diff --git a/src/tint/transform/builtin_polyfill.cc b/src/tint/transform/builtin_polyfill.cc
index 15aa233..62f8f4c 100644
--- a/src/tint/transform/builtin_polyfill.cc
+++ b/src/tint/transform/builtin_polyfill.cc
@@ -301,8 +301,18 @@
case Level::kFull:
body.Push(b.Decl(b.Let("shl", b.Sub(u32(W), "e"))));
body.Push(b.Decl(b.Let("shr", b.Add("shl", "s"))));
- body.Push(
- b.Return(b.Shr(b.Shl("v", vecN_u32(b.Expr("shl"))), vecN_u32(b.Expr("shr")))));
+ // Here we don't want the shl and shr modulos the rhs, so handle the `rhs >= 32u`
+ // cases using `select`. In order to handle the signed shr `lhs >> rhs` corrently,
+ // use `(lhs >> 31u) >> 1u` if `rhs >= 32u`.
+ body.Push(b.Decl(b.Let("shl_result", b.Call("select", b.Construct(T(ty)),
+ b.Shl("v", vecN_u32(b.Expr("shl"))),
+ b.LessThan("shl", 32_u)))));
+ body.Push(b.Return(b.Call(
+ "select",
+ b.Shr(b.Shr("shl_result", vecN_u32(b.Expr(31_u))), vecN_u32(b.Expr(1_u))),
+ b.Shr("shl_result", vecN_u32(b.Expr("shr"))), b.LessThan("shr", 32_u))
+
+ ));
break;
case Level::kClampParameters:
body.Push(b.Return(b.Call("extractBits", "v", "s", b.Sub("e", "s"))));
diff --git a/src/tint/transform/builtin_polyfill_test.cc b/src/tint/transform/builtin_polyfill_test.cc
index 87fd9d5..1fbea9c 100644
--- a/src/tint/transform/builtin_polyfill_test.cc
+++ b/src/tint/transform/builtin_polyfill_test.cc
@@ -1109,7 +1109,8 @@
let e = min(32u, (s + count));
let shl = (32u - e);
let shr = (shl + s);
- return ((v << shl) >> shr);
+ let shl_result = select(i32(), (v << shl), (shl < 32u));
+ return select(((shl_result >> 31u) >> 1u), (shl_result >> shr), (shr < 32u));
}
fn f() {
@@ -1137,7 +1138,8 @@
let e = min(32u, (s + count));
let shl = (32u - e);
let shr = (shl + s);
- return ((v << shl) >> shr);
+ let shl_result = select(u32(), (v << shl), (shl < 32u));
+ return select(((shl_result >> 31u) >> 1u), (shl_result >> shr), (shr < 32u));
}
fn f() {
@@ -1165,7 +1167,8 @@
let e = min(32u, (s + count));
let shl = (32u - e);
let shr = (shl + s);
- return ((v << vec3<u32>(shl)) >> vec3<u32>(shr));
+ let shl_result = select(vec3<i32>(), (v << vec3<u32>(shl)), (shl < 32u));
+ return select(((shl_result >> vec3<u32>(31u)) >> vec3<u32>(1u)), (shl_result >> vec3<u32>(shr)), (shr < 32u));
}
fn f() {
@@ -1193,7 +1196,8 @@
let e = min(32u, (s + count));
let shl = (32u - e);
let shr = (shl + s);
- return ((v << vec3<u32>(shl)) >> vec3<u32>(shr));
+ let shl_result = select(vec3<u32>(), (v << vec3<u32>(shl)), (shl < 32u));
+ return select(((shl_result >> vec3<u32>(31u)) >> vec3<u32>(1u)), (shl_result >> vec3<u32>(shr)), (shr < 32u));
}
fn f() {
diff --git a/src/tint/transform/canonicalize_entry_point_io.cc b/src/tint/transform/canonicalize_entry_point_io.cc
index 8a14fb7..b41529a 100644
--- a/src/tint/transform/canonicalize_entry_point_io.cc
+++ b/src/tint/transform/canonicalize_entry_point_io.cc
@@ -359,10 +359,10 @@
continue;
}
- auto* member_ast = member->Declaration();
- auto name = ctx.src->Symbols().NameFor(member_ast->symbol);
+ auto name = ctx.src->Symbols().NameFor(member->Name());
- auto attributes = CloneShaderIOAttributes(member_ast->attributes, do_interpolate);
+ auto attributes =
+ CloneShaderIOAttributes(member->Declaration()->attributes, do_interpolate);
auto* input_expr =
AddInput(name, member->Type(), member->Location(), std::move(attributes));
inner_struct_values.Push(input_expr);
@@ -388,9 +388,9 @@
continue;
}
- auto* member_ast = member->Declaration();
- auto name = ctx.src->Symbols().NameFor(member_ast->symbol);
- auto attributes = CloneShaderIOAttributes(member_ast->attributes, do_interpolate);
+ auto name = ctx.src->Symbols().NameFor(member->Name());
+ auto attributes =
+ CloneShaderIOAttributes(member->Declaration()->attributes, do_interpolate);
// Extract the original structure member.
AddOutput(name, member->Type(), member->Location(), std::move(attributes),
diff --git a/src/tint/transform/decompose_memory_access.cc b/src/tint/transform/decompose_memory_access.cc
index 944797a..671ebc4 100644
--- a/src/tint/transform/decompose_memory_access.cc
+++ b/src/tint/transform/decompose_memory_access.cc
@@ -645,8 +645,8 @@
utils::Vector<const ast::Statement*, 8> stmts;
for (auto* member : str->Members()) {
auto* offset = b.Add("offset", u32(member->Offset()));
- auto* element = b.MemberAccessor(
- "value", ctx.Clone(member->Declaration()->symbol));
+ auto* element =
+ b.MemberAccessor("value", ctx.Clone(member->Name()));
Symbol store =
StoreFunc(buf_ty, member->Type()->UnwrapRef(), var_user);
auto* call = b.Call(store, "buffer", offset, element);
diff --git a/src/tint/transform/decompose_strided_matrix_test.cc b/src/tint/transform/decompose_strided_matrix_test.cc
index bd202c9..e3ba4bb 100644
--- a/src/tint/transform/decompose_strided_matrix_test.cc
+++ b/src/tint/transform/decompose_strided_matrix_test.cc
@@ -90,6 +90,7 @@
struct S {
@size(16)
padding : u32,
+ /* @offset(16) */
m : @stride(32) array<vec2<f32>, 2u>,
}
@@ -147,6 +148,7 @@
struct S {
@size(16)
padding : u32,
+ /* @offset(16) */
m : @stride(32) array<vec2<f32>, 2u>,
}
@@ -199,6 +201,7 @@
struct S {
@size(16)
padding : u32,
+ /* @offset(16u) */
@stride(8) @internal(disable_validation__ignore_stride)
m : mat2x2<f32>,
}
@@ -253,6 +256,7 @@
struct S {
@size(8)
padding : u32,
+ /* @offset(8) */
m : @stride(32) array<vec2<f32>, 2u>,
}
@@ -311,6 +315,7 @@
struct S {
@size(16)
padding : u32,
+ /* @offset(16) */
m : @stride(32) array<vec2<f32>, 2u>,
}
@@ -365,6 +370,7 @@
struct S {
@size(8)
padding : u32,
+ /* @offset(8) */
m : @stride(32) array<vec2<f32>, 2u>,
}
@@ -422,6 +428,7 @@
struct S {
@size(8)
padding : u32,
+ /* @offset(8) */
m : @stride(32) array<vec2<f32>, 2u>,
}
@@ -487,6 +494,7 @@
struct S {
@size(8)
padding : u32,
+ /* @offset(8) */
m : @stride(32) array<vec2<f32>, 2u>,
}
@@ -551,6 +559,7 @@
struct S {
@size(8)
padding : u32,
+ /* @offset(8u) */
@stride(32) @internal(disable_validation__ignore_stride)
m : mat2x2<f32>,
}
@@ -605,6 +614,7 @@
struct S {
@size(8)
padding : u32,
+ /* @offset(8u) */
@stride(32) @internal(disable_validation__ignore_stride)
m : mat2x2<f32>,
}
diff --git a/src/tint/transform/direct_variable_access.cc b/src/tint/transform/direct_variable_access.cc
new file mode 100644
index 0000000..d1c1339
--- /dev/null
+++ b/src/tint/transform/direct_variable_access.cc
@@ -0,0 +1,1216 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/transform/direct_variable_access.h"
+
+#include <algorithm>
+#include <string>
+#include <utility>
+
+#include "src/tint/ast/traverse_expressions.h"
+#include "src/tint/program_builder.h"
+#include "src/tint/sem/abstract_int.h"
+#include "src/tint/sem/call.h"
+#include "src/tint/sem/function.h"
+#include "src/tint/sem/index_accessor_expression.h"
+#include "src/tint/sem/member_accessor_expression.h"
+#include "src/tint/sem/module.h"
+#include "src/tint/sem/statement.h"
+#include "src/tint/sem/struct.h"
+#include "src/tint/sem/variable.h"
+#include "src/tint/transform/utils/hoist_to_decl_before.h"
+#include "src/tint/utils/reverse.h"
+#include "src/tint/utils/scoped_assignment.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::transform::DirectVariableAccess);
+TINT_INSTANTIATE_TYPEINFO(tint::transform::DirectVariableAccess::Config);
+
+using namespace tint::number_suffixes; // NOLINT
+
+namespace {
+
+/// AccessRoot describes the root of an AccessShape.
+struct AccessRoot {
+ /// The pointer-unwrapped type of the *transformed* variable.
+ /// This may be different for pointers in 'private' and 'function' address space, as the pointer
+ /// parameter type is to the *base object* instead of the input pointer type.
+ tint::sem::Type const* type = nullptr;
+ /// The originating module-scope variable ('private', 'storage', 'uniform', 'workgroup'),
+ /// function-scope variable ('function'), or pointer parameter in the source program.
+ tint::sem::Variable const* variable = nullptr;
+ /// The address space of the variable or pointer type.
+ tint::ast::AddressSpace address_space = tint::ast::AddressSpace::kUndefined;
+};
+
+/// Inequality operator for AccessRoot
+bool operator!=(const AccessRoot& a, const AccessRoot& b) {
+ return a.type != b.type || a.variable != b.variable;
+}
+
+/// DynamicIndex is used by DirectVariableAccess::State::AccessOp to indicate an array, matrix or
+/// vector index.
+struct DynamicIndex {
+ /// The index of the expression in DirectVariableAccess::State::AccessChain::dynamic_indices
+ size_t slot = 0;
+};
+
+/// Inequality operator for DynamicIndex
+bool operator!=(const DynamicIndex& a, const DynamicIndex& b) {
+ return a.slot != b.slot;
+}
+
+/// AccessOp describes a single access in an access chain.
+/// The access is one of:
+/// Symbol - a struct member access.
+/// DynamicIndex - a runtime index on an array, matrix column, or vector element.
+using AccessOp = std::variant<tint::Symbol, DynamicIndex>;
+
+/// A vector of AccessOp. Describes the static "path" from a root variable to an element
+/// within the variable. Array accessors index expressions are held externally to the
+/// AccessShape, so AccessShape will be considered equal even if the array, matrix or vector
+/// index values differ.
+///
+/// For example, consider the following:
+///
+/// ```
+/// struct A {
+/// x : array<i32, 8>,
+/// y : u32,
+/// };
+/// struct B {
+/// x : i32,
+/// y : array<A, 4>
+/// };
+/// var<workgroup> C : B;
+/// ```
+///
+/// The following AccessShape would describe the following:
+///
+/// +==============================+===============+=================================+
+/// | AccessShape | Type | Expression |
+/// +==============================+===============+=================================+
+/// | [ Variable 'C', Symbol 'x' ] | i32 | C.x |
+/// +------------------------------+---------------+---------------------------------+
+/// | [ Variable 'C', Symbol 'y' ] | array<A, 4> | C.y |
+/// +------------------------------+---------------+---------------------------------+
+/// | [ Variable 'C', Symbol 'y', | A | C.y[dyn_idx[0]] |
+/// | DynamicIndex ] | | |
+/// +------------------------------+---------------+---------------------------------+
+/// | [ Variable 'C', Symbol 'y', | array<i32, 8> | C.y[dyn_idx[0]].x |
+/// | DynamicIndex, Symbol 'x' ] | | |
+/// +------------------------------+---------------+---------------------------------+
+/// | [ Variable 'C', Symbol 'y', | i32 | C.y[dyn_idx[0]].x[dyn_idx[1]] |
+/// | DynamicIndex, Symbol 'x', | | |
+/// | DynamicIndex ] | | |
+/// +------------------------------+---------------+---------------------------------+
+/// | [ Variable 'C', Symbol 'y', | u32 | C.y[dyn_idx[0]].y |
+/// | DynamicIndex, Symbol 'y' ] | | |
+/// +------------------------------+---------------+---------------------------------+
+///
+/// Where: `dyn_idx` is the AccessChain::dynamic_indices.
+struct AccessShape {
+ // The originating variable.
+ AccessRoot root;
+ /// The chain of access ops.
+ tint::utils::Vector<AccessOp, 8> ops;
+
+ /// @returns the number of DynamicIndex operations in #ops.
+ uint32_t NumDynamicIndices() const {
+ uint32_t count = 0;
+ for (auto& op : ops) {
+ if (std::holds_alternative<DynamicIndex>(op)) {
+ count++;
+ }
+ }
+ return count;
+ }
+};
+
+/// Equality operator for AccessShape
+bool operator==(const AccessShape& a, const AccessShape& b) {
+ return !(a.root != b.root) && a.ops == b.ops;
+}
+
+/// Inequality operator for AccessShape
+bool operator!=(const AccessShape& a, const AccessShape& b) {
+ return !(a == b);
+}
+
+/// AccessChain describes a chain of access expressions originating from a variable.
+struct AccessChain : AccessShape {
+ /// The array accessor index expressions. This vector is indexed by the `DynamicIndex`s in
+ /// #indices.
+ tint::utils::Vector<const tint::sem::Expression*, 8> dynamic_indices;
+ /// If true, then this access chain is used as an argument to call a variant.
+ bool used_in_call = false;
+};
+
+} // namespace
+
+namespace tint::utils {
+
+/// Hasher specialization for AccessRoot
+template <>
+struct Hasher<AccessRoot> {
+ /// The hash function for the AccessRoot
+ /// @param d the AccessRoot to hash
+ /// @return the hash for the given AccessRoot
+ size_t operator()(const AccessRoot& d) const { return utils::Hash(d.type, d.variable); }
+};
+
+/// Hasher specialization for DynamicIndex
+template <>
+struct Hasher<DynamicIndex> {
+ /// The hash function for the DynamicIndex
+ /// @param d the DynamicIndex to hash
+ /// @return the hash for the given DynamicIndex
+ size_t operator()(const DynamicIndex& d) const { return utils::Hash(d.slot); }
+};
+
+/// Hasher specialization for AccessShape
+template <>
+struct Hasher<AccessShape> {
+ /// The hash function for the AccessShape
+ /// @param s the AccessShape to hash
+ /// @return the hash for the given AccessShape
+ size_t operator()(const AccessShape& s) const { return utils::Hash(s.root, s.ops); }
+};
+
+} // namespace tint::utils
+
+namespace tint::transform {
+
+/// The PIMPL state for the DirectVariableAccess transform
+struct DirectVariableAccess::State {
+ /// Constructor
+ /// @param src the source Program
+ /// @param options the transform options
+ State(const Program* src, const Options& options)
+ : ctx{&b, src, /* auto_clone_symbols */ true}, opts(options) {}
+
+ /// The main function for the transform.
+ /// @returns the ApplyResult
+ ApplyResult Run() {
+ if (!ctx.src->Sem().Module()->Extensions().Contains(
+ ast::Extension::kChromiumExperimentalFullPtrParameters)) {
+ // If the 'chromium_experimental_full_ptr_parameters' extension is not enabled, then
+ // there's nothing for this transform to do.
+ return SkipTransform;
+ }
+
+ // Stage 1:
+ // Walk all the expressions of the program, starting with the expression leaves.
+ // Whenever we find an identifier resolving to a var, pointer parameter or pointer let to
+ // another chain, start constructing an access chain. When chains are accessed, these chains
+ // are grown and moved up the expression tree. After this stage, we are left with all the
+ // expression access chains to variables that we may need to transform.
+ for (auto* node : ctx.src->ASTNodes().Objects()) {
+ if (auto* expr = sem.Get<sem::Expression>(node)) {
+ AppendAccessChain(expr);
+ }
+ }
+
+ // Stage 2:
+ // Walk the functions in dependency order, starting with the entry points.
+ // Construct the set of function 'variants' by examining the calls made by each function to
+ // their call target. Each variant holds a map of pointer parameter to access chains, and
+ // will have the pointer parameters replaced with an array of u32s, used to perform the
+ // pointer indexing in the variant.
+ // Function call pointer arguments are replaced with an array of these dynamic indices.
+ for (auto* decl : utils::Reverse(sem.Module()->DependencyOrderedDeclarations())) {
+ if (auto* fn = sem.Get<sem::Function>(decl)) {
+ auto* fn_info = FnInfoFor(fn);
+ ProcessFunction(fn, fn_info);
+ TransformFunction(fn, fn_info);
+ }
+ }
+
+ // Stage 3:
+ // Filter out access chains that do not need transforming.
+ // Ensure that chain dynamic index expressions are evaluated once at the correct place
+ ProcessAccessChains();
+
+ // Stage 4:
+ // Replace all the access chain expressions in all functions with reconstructed expression
+ // using the originating global variable, and any dynamic indices passed in to the function
+ // variant.
+ TransformAccessChainExpressions();
+
+ // Stage 5:
+ // Actually kick the clone.
+ CloneState state;
+ clone_state = &state;
+ ctx.Clone();
+ return Program(std::move(*ctx.dst));
+ }
+
+ private:
+ /// Holds symbols of the transformed pointer parameter.
+ /// If both symbols are valid, then #base_ptr and #indices are both program-unique symbols
+ /// derived from the original parameter name.
+ /// If only one symbol is valid, then this is the original parameter symbol.
+ struct PtrParamSymbols {
+ /// The symbol of the base pointer parameter.
+ Symbol base_ptr;
+ /// The symbol of the dynamic indicies parameter.
+ Symbol indices;
+ };
+
+ /// FnVariant describes a unique variant of a function, specialized by the AccessShape of the
+ /// pointer arguments - also known as the variant's "signature".
+ ///
+ /// To help understand what a variant is, consider the following WGSL:
+ ///
+ /// ```
+ /// fn F(a : ptr<storage, u32>, b : u32, c : ptr<storage, u32>) {
+ /// return *a + b + *c;
+ /// }
+ ///
+ /// @group(0) @binding(0) var<storage> S0 : u32;
+ /// @group(0) @binding(0) var<storage> S1 : array<u32, 64>;
+ ///
+ /// fn x() {
+ /// F(&S0, 0, &S0); // (A)
+ /// F(&S0, 0, &S0); // (B)
+ /// F(&S1[0], 1, &S0); // (C)
+ /// F(&S1[5], 2, &S0); // (D)
+ /// F(&S1[5], 3, &S1[3]); // (E)
+ /// F(&S1[7], 4, &S1[2]); // (F)
+ /// }
+ /// ```
+ ///
+ /// Given the calls in x(), function F() will have 3 variants:
+ /// (1) F<S0,S0> - called by (A) and (B).
+ /// Note that only 'uniform', 'storage' and 'workgroup' pointer
+ /// parameters are considered for a variant signature, and so
+ /// the argument for parameter 'b' is not included in the
+ /// signature.
+ /// (2) F<S1[dyn_idx],S0> - called by (C) and (D).
+ /// Note that the array index value is external to the
+ /// AccessShape, and so is not part of the variant signature.
+ /// (3) F<S1[dyn_idx],S1[dyn_idx]> - called by (E) and (F).
+ ///
+ /// Each variant of the function will be emitted as a separate function by the transform, and
+ /// would look something like:
+ ///
+ /// ```
+ /// // variant F<S0,S0> (1)
+ /// fn F_S0_S0(b : u32) {
+ /// return S0 + b + S0;
+ /// }
+ ///
+ /// type S1_X = array<u32, 1>;
+ ///
+ /// // variant F<S1[dyn_idx],S0> (2)
+ /// fn F_S1_X_S0(a : S1_X, b : u32) {
+ /// return S1[a[0]] + b + S0;
+ /// }
+ ///
+ /// // variant F<S1[dyn_idx],S1[dyn_idx]> (3)
+ /// fn F_S1_X_S1_X(a : S1_X, b : u32, c : S1_X) {
+ /// return S1[a[0]] + b + S1[c[0]];
+ /// }
+ ///
+ /// @group(0) @binding(0) var<storage> S0 : u32;
+ /// @group(0) @binding(0) var<storage> S1 : array<u32, 64>;
+ ///
+ /// fn x() {
+ /// F_S0_S0(0); // (A)
+ /// F(&S0, 0, &S0); // (B)
+ /// F_S1_X_S0(S1_X(0), 1); // (C)
+ /// F_S1_X_S0(S1_X(5), 2); // (D)
+ /// F_S1_X_S1_X(S1_X(5), 3, S1_X(3)); // (E)
+ /// F_S1_X_S1_X(S1_X(7), 4, S1_X(2)); // (F)
+ /// }
+ /// ```
+ struct FnVariant {
+ /// The signature of the variant is a map of each of the function's 'uniform', 'storage' and
+ /// 'workgroup' pointer parameters to the caller's AccessShape.
+ using Signature = utils::Hashmap<const sem::Parameter*, AccessShape, 4>;
+
+ /// The unique name of the variant.
+ /// The symbol is in the `ctx.dst` program namespace.
+ Symbol name;
+
+ /// A map of direct calls made by this variant to the name of other function variants.
+ utils::Hashmap<const sem::Call*, Symbol, 4> calls;
+
+ /// A map of input program parameter to output parameter symbols.
+ utils::Hashmap<const sem::Parameter*, PtrParamSymbols, 4> ptr_param_symbols;
+
+ /// The declaration order of the variant, in relation to other variants of the same
+ /// function. Used to ensure deterministic ordering of the transform, as map iteration is
+ /// not deterministic between compilers.
+ size_t order = 0;
+ };
+
+ /// FnInfo holds information about a function in the input program.
+ struct FnInfo {
+ /// A map of variant signature to the variant data.
+ utils::Hashmap<FnVariant::Signature, FnVariant, 8> variants;
+ /// A map of expressions that have been hoisted to a 'let' declaration in the function.
+ utils::Hashmap<const sem::Expression*, Symbol, 8> hoisted_exprs;
+
+ /// @returns the variants of the function in a deterministically ordered vector.
+ utils::Vector<std::pair<const FnVariant::Signature*, FnVariant*>, 8> SortedVariants() {
+ utils::Vector<std::pair<const FnVariant::Signature*, FnVariant*>, 8> out;
+ out.Reserve(variants.Count());
+ for (auto it : variants) {
+ out.Push({&it.key, &it.value});
+ }
+ out.Sort([&](auto& va, auto& vb) { return va.second->order < vb.second->order; });
+ return out;
+ }
+ };
+
+ /// The program builder
+ ProgramBuilder b;
+ /// The clone context
+ CloneContext ctx;
+ /// The transform options
+ const Options& opts;
+ /// Alias to the semantic info in ctx.src
+ const sem::Info& sem = ctx.src->Sem();
+ /// Alias to the symbols in ctx.src
+ const SymbolTable& sym = ctx.src->Symbols();
+ /// Map of semantic function to the function info
+ utils::Hashmap<const sem::Function*, FnInfo*, 8> fns;
+ /// Map of AccessShape to the name of a type alias for the an array<u32, N> used for the
+ /// dynamic indices of an access chain, passed down as the transformed type of a variant's
+ /// pointer parameter.
+ utils::Hashmap<AccessShape, Symbol, 8> dynamic_index_array_aliases;
+ /// Map of semantic expression to AccessChain
+ utils::Hashmap<const sem::Expression*, AccessChain*, 32> access_chains;
+ /// Allocator for FnInfo
+ utils::BlockAllocator<FnInfo> fn_info_allocator;
+ /// Allocator for AccessChain
+ utils::BlockAllocator<AccessChain> access_chain_allocator;
+ /// Helper used for hoisting expressions to lets
+ HoistToDeclBefore hoist{ctx};
+ /// Map of string to unique symbol (no collisions in output program).
+ utils::Hashmap<std::string, Symbol, 8> unique_symbols;
+
+ /// CloneState holds pointers to the current function, variant and variant's parameters.
+ struct CloneState {
+ /// The current function being cloned
+ FnInfo* current_function = nullptr;
+ /// The current function variant being built
+ FnVariant* current_variant = nullptr;
+ /// The signature of the current function variant being built
+ const FnVariant::Signature* current_variant_sig = nullptr;
+ };
+
+ /// The clone state.
+ /// Only valid during the lifetime of the CloneContext::Clone().
+ CloneState* clone_state = nullptr;
+
+ /// AppendAccessChain creates or extends an existing AccessChain for the given expression,
+ /// modifying the #access_chains map.
+ void AppendAccessChain(const sem::Expression* expr) {
+ // take_chain moves the AccessChain from the expression `from` to the expression `expr`.
+ // Returns nullptr if `from` did not hold an access chain.
+ auto take_chain = [&](const sem::Expression* from) -> AccessChain* {
+ if (auto* chain = AccessChainFor(from)) {
+ access_chains.Remove(from);
+ access_chains.Add(expr, chain);
+ return chain;
+ }
+ return nullptr;
+ };
+
+ Switch(
+ expr,
+ [&](const sem::VariableUser* user) {
+ // Expression resolves to a variable.
+ auto* variable = user->Variable();
+
+ auto create_new_chain = [&] {
+ auto* chain = access_chain_allocator.Create();
+ chain->root.variable = variable;
+ chain->root.type = variable->Type();
+ chain->root.address_space = variable->AddressSpace();
+ if (auto* ptr = chain->root.type->As<sem::Pointer>()) {
+ chain->root.address_space = ptr->AddressSpace();
+ }
+ access_chains.Add(expr, chain);
+ };
+
+ Switch(
+ variable->Declaration(),
+ [&](const ast::Var*) {
+ if (variable->AddressSpace() != ast::AddressSpace::kHandle) {
+ // Start a new access chain for the non-handle 'var' access
+ create_new_chain();
+ }
+ },
+ [&](const ast::Parameter*) {
+ if (variable->Type()->Is<sem::Pointer>()) {
+ // Start a new access chain for the pointer parameter access
+ create_new_chain();
+ }
+ },
+ [&](const ast::Let*) {
+ if (variable->Type()->Is<sem::Pointer>()) {
+ // variable is a pointer-let.
+ auto* init = sem.Get(variable->Declaration()->initializer);
+ // Note: We do not use take_chain() here, as we need to preserve the
+ // AccessChain on the let's initializer, as the let needs its
+ // initializer updated, and the let may be used multiple times. Instead
+ // we copy the let's AccessChain into a a new AccessChain.
+ if (auto* init_chain = AccessChainFor(init)) {
+ access_chains.Add(expr, access_chain_allocator.Create(*init_chain));
+ }
+ }
+ });
+ },
+ [&](const sem::StructMemberAccess* a) {
+ // Structure member access.
+ // Append the Symbol of the member name to the chain, and move the chain to the
+ // member access expression.
+ if (auto* chain = take_chain(a->Object())) {
+ chain->ops.Push(a->Member()->Name());
+ }
+ },
+ [&](const sem::IndexAccessorExpression* a) {
+ // Array, matrix or vector index.
+ // Store the index expression into AccessChain::dynamic_indices, append a
+ // DynamicIndex to the chain, and move the chain to the index accessor expression.
+ if (auto* chain = take_chain(a->Object())) {
+ chain->ops.Push(DynamicIndex{chain->dynamic_indices.Length()});
+ chain->dynamic_indices.Push(a->Index());
+ }
+ },
+ [&](const sem::Expression* e) {
+ if (auto* unary = e->Declaration()->As<ast::UnaryOpExpression>()) {
+ // Unary op.
+ // If this is a '&' or '*', simply move the chain to the unary op expression.
+ if (unary->op == ast::UnaryOp::kAddressOf ||
+ unary->op == ast::UnaryOp::kIndirection) {
+ take_chain(sem.Get(unary->expr));
+ }
+ }
+ });
+ }
+
+ /// MaybeHoistDynamicIndices examines the AccessChain::dynamic_indices member of @p chain,
+ /// hoisting all expressions to their own uniquely named 'let' if none of the following are
+ /// true:
+ /// 1. The index expression is a constant value.
+ /// 2. The index expression's statement is the same as @p usage.
+ /// 3. The index expression is an identifier resolving to a 'let', 'const' or parameter, AND
+ /// that identifier resolves to the same variable at @p usage.
+ ///
+ /// A dynamic index will only be hoisted once. The hoisting applies to all variants of the
+ /// function that holds the dynamic index expression.
+ void MaybeHoistDynamicIndices(AccessChain* chain, const sem::Statement* usage) {
+ for (auto& idx : chain->dynamic_indices) {
+ if (idx->ConstantValue()) {
+ // Dynamic index is constant.
+ continue; // Hoisting not required.
+ }
+
+ if (idx->Stmt() == usage) {
+ // The index expression is owned by the statement of usage.
+ continue; // Hoisting not required
+ }
+
+ if (auto* idx_variable_user = idx->UnwrapMaterialize()->As<sem::VariableUser>()) {
+ auto* idx_variable = idx_variable_user->Variable();
+ if (idx_variable->Declaration()->IsAnyOf<ast::Let, ast::Parameter>()) {
+ // Dynamic index is an immutable variable
+ continue; // Hoisting not required.
+ }
+ }
+
+ // The dynamic index needs to be hoisted (if it hasn't been already).
+ auto fn = FnInfoFor(idx->Stmt()->Function());
+ fn->hoisted_exprs.GetOrCreate(idx, [=] {
+ // Create a name for the new 'let'
+ auto name = b.Symbols().New("ptr_index_save");
+ // Insert a new 'let' just above the dynamic index statement.
+ hoist.InsertBefore(idx->Stmt(), [this, idx, name] {
+ return b.Decl(b.Let(name, ctx.CloneWithoutTransform(idx->Declaration())));
+ });
+ return name;
+ });
+ }
+ }
+
+ /// BuildDynamicIndex builds the AST expression node for the dynamic index expression used in an
+ /// AccessChain. This is similar to just cloning the expression, but BuildDynamicIndex()
+ /// also:
+ /// * Collapses constant value index expressions down to the computed value. This acts as an
+ /// constant folding optimization and reduces noise from the transform.
+ /// * Casts the resulting expression to a u32 if @p cast_to_u32 is true, and the expression type
+ /// isn't implicitly usable as a u32. This is to help feed the expression into a
+ /// `array<u32, N>` argument passed to a callee variant function.
+ const ast::Expression* BuildDynamicIndex(const sem::Expression* idx, bool cast_to_u32) {
+ if (auto* val = idx->ConstantValue()) {
+ // Expression evaluated to a constant value. Just emit that constant.
+ return b.Expr(val->As<AInt>());
+ }
+
+ // Expression is not a constant, clone the expression.
+ // Note: If the dynamic index expression was hoisted to a let, then cloning will return an
+ // identifier expression to the hoisted let.
+ auto* expr = ctx.Clone(idx->Declaration());
+
+ if (cast_to_u32) {
+ // The index may be fed to a dynamic index array<u32, N> argument, so the index
+ // expression may need casting to u32.
+ if (!idx->UnwrapMaterialize()
+ ->Type()
+ ->UnwrapRef()
+ ->IsAnyOf<sem::U32, sem::AbstractInt>()) {
+ expr = b.Construct(b.ty.u32(), expr);
+ }
+ }
+
+ return expr;
+ }
+
+ /// ProcessFunction scans the direct calls made by the function @p fn, adding new variants to
+ /// the callee functions and transforming the call expression to pass dynamic indices instead of
+ /// true pointers.
+ /// If the function @p fn has pointer parameters that must be transformed to a caller variant,
+ /// and the function is not called, then the function is dropped from the output of the
+ /// transform, as it cannot be generated.
+ /// @note ProcessFunction must be called in dependency order for the program, starting with the
+ /// entry points.
+ void ProcessFunction(const sem::Function* fn, FnInfo* fn_info) {
+ if (fn_info->variants.IsEmpty()) {
+ // Function has no variants pre-generated by callers.
+ if (MustBeCalled(fn)) {
+ // Drop the function, as it wasn't called and cannot be generated.
+ ctx.Remove(ctx.src->AST().GlobalDeclarations(), fn->Declaration());
+ return;
+ }
+
+ // Function was not called. Create a single variant with an empty signature.
+ FnVariant variant;
+ variant.name = ctx.Clone(fn->Declaration()->symbol);
+ variant.order = 0; // Unaltered comes first.
+ fn_info->variants.Add(FnVariant::Signature{}, std::move(variant));
+ }
+
+ // Process each of the direct calls made by this function.
+ for (auto* call : fn->DirectCalls()) {
+ ProcessCall(fn_info, call);
+ }
+ }
+
+ /// ProcessCall creates new variants of the callee function by permuting the call for each of
+ /// the variants of @p caller. ProcessCall also registers the clone callback to transform the
+ /// call expression to pass dynamic indices instead of true pointers.
+ void ProcessCall(FnInfo* caller, const sem::Call* call) {
+ auto* target = call->Target()->As<sem::Function>();
+ if (!target) {
+ // Call target is not a user-declared function.
+ return; // Not interested in this call.
+ }
+
+ if (!HasPointerParameter(target)) {
+ return; // Not interested in this call.
+ }
+
+ bool call_needs_transforming = false;
+
+ // Build the call target function variant for each variant of the caller.
+ for (auto caller_variant_it : caller->SortedVariants()) {
+ auto& caller_signature = *caller_variant_it.first;
+ auto& caller_variant = *caller_variant_it.second;
+
+ // Build the target variant's signature.
+ FnVariant::Signature target_signature;
+ for (size_t i = 0; i < call->Arguments().Length(); i++) {
+ const auto* arg = call->Arguments()[i];
+ const auto* param = target->Parameters()[i];
+ const auto* param_ty = param->Type()->As<sem::Pointer>();
+ if (!param_ty) {
+ continue; // Parameter type is not a pointer.
+ }
+
+ // Fetch the access chain for the argument.
+ auto* arg_chain = AccessChainFor(arg);
+ if (!arg_chain) {
+ continue; // Argument does not have an access chain
+ }
+
+ // Construct the absolute AccessShape by considering the AccessShape of the caller
+ // variant's argument. This will propagate back through pointer parameters, to the
+ // outermost caller.
+ auto absolute = AbsoluteAccessShape(caller_signature, *arg_chain);
+
+ // If the address space of the root variable of the access chain does not require
+ // transformation, then there's nothing to do.
+ if (!AddressSpaceRequiresTransform(absolute.root.address_space)) {
+ continue;
+ }
+
+ // Record that this chain was used in a function call.
+ // This preserves the chain during the access chain filtering stage.
+ arg_chain->used_in_call = true;
+
+ if (IsPrivateOrFunction(absolute.root.address_space)) {
+ // Pointers in 'private' and 'function' address spaces need to be passed by
+ // pointer argument.
+ absolute.root.variable = param;
+ }
+
+ // Add the parameter's absolute AccessShape to the target's signature.
+ target_signature.Add(param, std::move(absolute));
+ }
+
+ // Construct a new FnVariant if this is the first caller of the target signature
+ auto* target_info = FnInfoFor(target);
+ auto& target_variant = target_info->variants.GetOrCreate(target_signature, [&] {
+ if (target_signature.IsEmpty()) {
+ // Call target does not require any argument changes.
+ FnVariant variant;
+ variant.name = ctx.Clone(target->Declaration()->symbol);
+ variant.order = 0; // Unaltered comes first.
+ return variant;
+ }
+
+ // Build an appropriate variant function name.
+ // This is derived from the original function name and the pointer parameter
+ // chains.
+ std::stringstream ss;
+ ss << ctx.src->Symbols().NameFor(target->Declaration()->symbol);
+ for (auto* param : target->Parameters()) {
+ if (auto indices = target_signature.Find(param)) {
+ ss << "_" << AccessShapeName(*indices);
+ }
+ }
+
+ // Build the pointer parameter symbols.
+ utils::Hashmap<const sem::Parameter*, PtrParamSymbols, 4> ptr_param_symbols;
+ for (auto param_it : target_signature) {
+ auto* param = param_it.key;
+ auto& shape = param_it.value;
+
+ // Parameter needs replacing with either zero, one or two parameters:
+ // If the parameter is in the 'private' or 'function' address space, then the
+ // originating pointer is always passed down. This always comes first.
+ // If the access chain has dynamic indices, then we create an array<u32, N>
+ // parameter to hold the dynamic indices.
+ bool requires_base_ptr_param = IsPrivateOrFunction(shape.root.address_space);
+ bool requires_indices_param = shape.NumDynamicIndices() > 0;
+
+ PtrParamSymbols symbols;
+ if (requires_base_ptr_param && requires_indices_param) {
+ auto original_name = param->Declaration()->symbol;
+ symbols.base_ptr = UniqueSymbolWithSuffix(original_name, "_base");
+ symbols.indices = UniqueSymbolWithSuffix(original_name, "_indices");
+ } else if (requires_base_ptr_param) {
+ symbols.base_ptr = ctx.Clone(param->Declaration()->symbol);
+ } else if (requires_indices_param) {
+ symbols.indices = ctx.Clone(param->Declaration()->symbol);
+ }
+
+ // Remember this base pointer name.
+ ptr_param_symbols.Add(param, symbols);
+ }
+
+ // Build the variant.
+ FnVariant variant;
+ variant.name = b.Symbols().New(ss.str());
+ variant.order = target_info->variants.Count() + 1;
+ variant.ptr_param_symbols = std::move(ptr_param_symbols);
+ return variant;
+ });
+
+ // Record the call made by caller variant to the target variant.
+ caller_variant.calls.Add(call, target_variant.name);
+ if (!target_signature.IsEmpty()) {
+ // The call expression will need transforming for at least one caller variant.
+ call_needs_transforming = true;
+ }
+ }
+
+ if (call_needs_transforming) {
+ // Register the clone callback to correctly transform the call expression into the
+ // appropriate variant calls.
+ TransformCall(call);
+ }
+ }
+
+ /// @returns true if the address space @p address_space requires transforming given the
+ /// transform's options.
+ bool AddressSpaceRequiresTransform(ast::AddressSpace address_space) const {
+ switch (address_space) {
+ case ast::AddressSpace::kUniform:
+ case ast::AddressSpace::kStorage:
+ case ast::AddressSpace::kWorkgroup:
+ return true;
+ case ast::AddressSpace::kPrivate:
+ return opts.transform_private;
+ case ast::AddressSpace::kFunction:
+ return opts.transform_function;
+ default:
+ return false;
+ }
+ }
+
+ /// @returns the AccessChain for the expression @p expr, or nullptr if the expression does
+ /// not hold an access chain.
+ AccessChain* AccessChainFor(const sem::Expression* expr) const {
+ if (auto chain = access_chains.Find(expr)) {
+ return *chain;
+ }
+ return nullptr;
+ }
+
+ /// @returns the absolute AccessShape for @p indices, by replacing the originating pointer
+ /// parameter with the AccessChain of variant's signature.
+ AccessShape AbsoluteAccessShape(const FnVariant::Signature& signature,
+ const AccessShape& shape) const {
+ if (auto* root_param = shape.root.variable->As<sem::Parameter>()) {
+ if (auto incoming_chain = signature.Find(root_param)) {
+ // Access chain originates from a parameter, which will be transformed into an array
+ // of dynamic indices. Concatenate the signature's AccessShape for the parameter
+ // to the chain's indices, skipping over the chain's initial parameter index.
+ auto absolute = *incoming_chain;
+ for (auto& op : shape.ops) {
+ absolute.ops.Push(op);
+ }
+ return absolute;
+ }
+ }
+
+ // Chain does not originate from a parameter, so is already absolute.
+ return shape;
+ }
+
+ /// TransformFunction registers the clone callback to transform the function @p fn into the
+ /// (potentially multiple) function's variants. TransformFunction will assign the current
+ /// function and variant to #clone_state, which can be used by the other clone callbacks.
+ void TransformFunction(const sem::Function* fn, FnInfo* fn_info) {
+ // Register a custom handler for the specific function
+ ctx.Replace(fn->Declaration(), [this, fn, fn_info] {
+ // For the scope of this lambda, assign current_function to fn_info.
+ TINT_SCOPED_ASSIGNMENT(clone_state->current_function, fn_info);
+
+ // This callback expects a single function returned. As we're generating potentially
+ // many variant functions, keep a record of the last created variant, and explicitly add
+ // this to the module if it isn't the last. We'll return the last created variant,
+ // taking the place of the original function.
+ const ast::Function* pending_variant = nullptr;
+
+ // For each variant of fn...
+ for (auto variant_it : fn_info->SortedVariants()) {
+ if (pending_variant) {
+ b.AST().AddFunction(pending_variant);
+ }
+
+ auto& variant_sig = *variant_it.first;
+ auto& variant = *variant_it.second;
+
+ // For the rest of this scope, assign the current variant and variant signature.
+ TINT_SCOPED_ASSIGNMENT(clone_state->current_variant_sig, &variant_sig);
+ TINT_SCOPED_ASSIGNMENT(clone_state->current_variant, &variant);
+
+ // Build the variant's parameters.
+ // Pointer parameters in the 'uniform', 'storage' or 'workgroup' address space are
+ // either replaced with an array of dynamic indices, or are dropped (if there are no
+ // dynamic indices).
+ utils::Vector<const ast::Parameter*, 8> params;
+ for (auto* param : fn->Parameters()) {
+ if (auto incoming_shape = variant_sig.Find(param)) {
+ auto& symbols = *variant.ptr_param_symbols.Find(param);
+ if (symbols.base_ptr.IsValid()) {
+ auto* base_ptr_ty =
+ b.ty.pointer(CreateASTTypeFor(ctx, incoming_shape->root.type),
+ incoming_shape->root.address_space);
+ params.Push(b.Param(symbols.base_ptr, base_ptr_ty));
+ }
+ if (symbols.indices.IsValid()) {
+ // Variant has dynamic indices for this variant, replace it.
+ auto* dyn_idx_arr_type = DynamicIndexArrayType(*incoming_shape);
+ params.Push(b.Param(symbols.indices, dyn_idx_arr_type));
+ }
+ } else {
+ // Just a regular parameter. Just clone the original parameter.
+ params.Push(ctx.Clone(param->Declaration()));
+ }
+ }
+
+ // Build the variant by cloning the source function. The other clone callbacks will
+ // use clone_state->current_variant and clone_state->current_variant_sig to produce
+ // the variant.
+ auto* ret_ty = ctx.Clone(fn->Declaration()->return_type);
+ auto body = ctx.Clone(fn->Declaration()->body);
+ auto attrs = ctx.Clone(fn->Declaration()->attributes);
+ auto ret_attrs = ctx.Clone(fn->Declaration()->return_type_attributes);
+ pending_variant =
+ b.create<ast::Function>(variant.name, std::move(params), ret_ty, body,
+ std::move(attrs), std::move(ret_attrs));
+ }
+
+ return pending_variant;
+ });
+ }
+
+ /// TransformCall registers the clone callback to transform the call expression @p call to call
+ /// the correct target variant, and to replace pointers arguments with an array of dynamic
+ /// indices.
+ void TransformCall(const sem::Call* call) {
+ // Register a custom handler for the specific call expression
+ ctx.Replace(call->Declaration(), [this, call]() {
+ auto target_variant = clone_state->current_variant->calls.Find(call);
+ if (!target_variant) {
+ // The current variant does not need to transform this call.
+ return ctx.CloneWithoutTransform(call->Declaration());
+ }
+
+ // Build the new call expressions's arguments.
+ utils::Vector<const ast::Expression*, 8> new_args;
+ for (size_t arg_idx = 0; arg_idx < call->Arguments().Length(); arg_idx++) {
+ auto* arg = call->Arguments()[arg_idx];
+ auto* param = call->Target()->Parameters()[arg_idx];
+ auto* param_ty = param->Type()->As<sem::Pointer>();
+ if (!param_ty) {
+ // Parameter is not a pointer.
+ // Just clone the unaltered argument.
+ new_args.Push(ctx.Clone(arg->Declaration()));
+ continue; // Parameter is not a pointer
+ }
+
+ auto* chain = AccessChainFor(arg);
+ if (!chain) {
+ // No access chain means the argument is not a pointer that needs transforming.
+ // Just clone the unaltered argument.
+ new_args.Push(ctx.Clone(arg->Declaration()));
+ continue;
+ }
+
+ // Construct the absolute AccessShape by considering the AccessShape of the caller
+ // variant's argument. This will propagate back through pointer parameters, to the
+ // outermost caller.
+ auto full_indices = AbsoluteAccessShape(*clone_state->current_variant_sig, *chain);
+
+ // If the parameter is a pointer in the 'private' or 'function' address space, then
+ // we need to pass an additional pointer argument to the base object.
+ if (IsPrivateOrFunction(param_ty->AddressSpace())) {
+ auto* root_expr = BuildAccessRootExpr(chain->root, /* deref */ false);
+ if (!chain->root.variable->Is<sem::Parameter>()) {
+ root_expr = b.AddressOf(root_expr);
+ }
+ new_args.Push(root_expr);
+ }
+
+ // Get or create the dynamic indices array.
+ if (auto* dyn_idx_arr_ty = DynamicIndexArrayType(full_indices)) {
+ // Build an array of dynamic indices to pass as the replacement for the pointer.
+ utils::Vector<const ast::Expression*, 8> dyn_idx_args;
+ if (auto* root_param = chain->root.variable->As<sem::Parameter>()) {
+ // Access chain originates from a pointer parameter.
+ if (auto incoming_chain =
+ clone_state->current_variant_sig->Find(root_param)) {
+ auto indices =
+ clone_state->current_variant->ptr_param_symbols.Find(root_param)
+ ->indices;
+
+ // This pointer parameter will have been replaced with a array<u32, N>
+ // holding the variant's dynamic indices for the pointer. Unpack these
+ // directly into the array constructor's arguments.
+ auto N = incoming_chain->NumDynamicIndices();
+ for (uint32_t i = 0; i < N; i++) {
+ dyn_idx_args.Push(b.IndexAccessor(indices, u32(i)));
+ }
+ }
+ }
+ // Pass the dynamic indices of the access chain into the array constructor.
+ for (auto& dyn_idx : chain->dynamic_indices) {
+ dyn_idx_args.Push(BuildDynamicIndex(dyn_idx, /* cast_to_u32 */ true));
+ }
+ // Construct the dynamic index array, and push as an argument.
+ new_args.Push(b.Construct(dyn_idx_arr_ty, std::move(dyn_idx_args)));
+ }
+ }
+
+ // Make the call to the target's variant.
+ return b.Call(*target_variant, std::move(new_args));
+ });
+ }
+
+ /// ProcessAccessChains performs the following:
+ /// * Removes all AccessChains from expressions that are not either used as a pointer argument
+ /// in a call, or originates from a pointer parameter.
+ /// * Hoists the dynamic index expressions of AccessChains to 'let' statements, to prevent
+ /// multiple evaluation of the expressions, and avoid expressions resolving to different
+ /// variables based on lexical scope.
+ void ProcessAccessChains() {
+ auto chain_exprs = access_chains.Keys();
+ chain_exprs.Sort([](const auto& expr_a, const auto& expr_b) {
+ return expr_a->Declaration()->node_id.value < expr_b->Declaration()->node_id.value;
+ });
+
+ for (auto* expr : chain_exprs) {
+ auto* chain = *access_chains.Get(expr);
+ if (!chain->used_in_call && !chain->root.variable->Is<sem::Parameter>()) {
+ // Chain was not used in a function call, and does not originate from a
+ // parameter. This chain does not need transforming. Drop it.
+ access_chains.Remove(expr);
+ continue;
+ }
+
+ // Chain requires transforming.
+
+ // We need to be careful that the chain does not use expressions with side-effects which
+ // cannot be repeatedly evaluated. In this situation we can hoist the dynamic index
+ // expressions to their own uniquely named lets (if required).
+ MaybeHoistDynamicIndices(chain, expr->Stmt());
+ }
+ }
+
+ /// TransformAccessChainExpressions registers the clone callback to:
+ /// * Transform all expressions that have an AccessChain (which aren't arguments to function
+ /// calls, these are handled by TransformCall()), into the equivalent expression using a
+ /// module-scope variable.
+ /// * Replace expressions that have been hoisted to a let, with an identifier expression to that
+ /// let.
+ void TransformAccessChainExpressions() {
+ // Register a custom handler for all non-function call expressions
+ ctx.ReplaceAll([this](const ast::Expression* ast_expr) -> const ast::Expression* {
+ if (!clone_state->current_variant) {
+ // Expression does not belong to a function variant.
+ return nullptr; // Just clone the expression.
+ }
+
+ auto* expr = sem.Get<sem::Expression>(ast_expr);
+ if (!expr) {
+ // No semantic node for the expression.
+ return nullptr; // Just clone the expression.
+ }
+
+ // If the expression has been hoisted to a 'let', then replace the expression with an
+ // identifier to the hoisted let.
+ if (auto hoisted = clone_state->current_function->hoisted_exprs.Find(expr)) {
+ return b.Expr(*hoisted);
+ }
+
+ auto* chain = AccessChainFor(expr);
+ if (!chain) {
+ // The expression does not have an AccessChain.
+ return nullptr; // Just clone the expression.
+ }
+
+ auto* root_param = chain->root.variable->As<sem::Parameter>();
+ if (!root_param) {
+ // The expression has an access chain, but does not originate with a pointer
+ // parameter. We don't need to change anything here.
+ return nullptr; // Just clone the expression.
+ }
+
+ auto incoming_shape = clone_state->current_variant_sig->Find(root_param);
+ if (!incoming_shape) {
+ // The root parameter of the access chain is not part of the variant's signature.
+ return nullptr; // Just clone the expression.
+ }
+
+ // Expression holds an access chain to a pointer parameter that needs transforming.
+ // Reconstruct the expression using the variant's incoming shape.
+
+ auto* chain_expr = BuildAccessRootExpr(incoming_shape->root, /* deref */ true);
+
+ // Chain starts with a pointer parameter.
+ // Replace this with the variant's incoming shape. This will bring the expression up to
+ // the incoming pointer.
+ auto indices =
+ clone_state->current_variant->ptr_param_symbols.Find(root_param)->indices;
+ for (auto param_access : incoming_shape->ops) {
+ chain_expr = BuildAccessExpr(chain_expr, param_access, [&](size_t i) {
+ return b.IndexAccessor(indices, AInt(i));
+ });
+ }
+
+ // Now build the expression chain within the function.
+
+ // For each access in the chain (excluding the pointer parameter)...
+ for (auto& op : chain->ops) {
+ chain_expr = BuildAccessExpr(chain_expr, op, [&](size_t i) {
+ return BuildDynamicIndex(chain->dynamic_indices[i], false);
+ });
+ }
+
+ // BuildAccessExpr() always returns a non-pointer.
+ // If the expression we're replacing is a pointer, take the address.
+ if (expr->Type()->Is<sem::Pointer>()) {
+ chain_expr = b.AddressOf(chain_expr);
+ }
+
+ return chain_expr;
+ });
+ }
+
+ /// @returns the FnInfo for the given function, constructing a new FnInfo if @p fn doesn't
+ /// already have one.
+ FnInfo* FnInfoFor(const sem::Function* fn) {
+ return fns.GetOrCreate(fn, [this] { return fn_info_allocator.Create(); });
+ }
+
+ /// @returns the type alias used to hold the dynamic indices for @p shape, declaring a new alias
+ /// if this is the first call for the given shape.
+ const ast::TypeName* DynamicIndexArrayType(const AccessShape& shape) {
+ auto name = dynamic_index_array_aliases.GetOrCreate(shape, [&] {
+ // Count the number of dynamic indices
+ uint32_t num_dyn_indices = shape.NumDynamicIndices();
+ if (num_dyn_indices == 0) {
+ return Symbol{};
+ }
+ auto symbol = b.Symbols().New(AccessShapeName(shape));
+ b.Alias(symbol, b.ty.array(b.ty.u32(), u32(num_dyn_indices)));
+ return symbol;
+ });
+ return name.IsValid() ? b.ty.type_name(name) : nullptr;
+ }
+
+ /// @returns a name describing the given shape
+ std::string AccessShapeName(const AccessShape& shape) {
+ std::stringstream ss;
+
+ if (IsPrivateOrFunction(shape.root.address_space)) {
+ ss << "F";
+ } else {
+ ss << ctx.src->Symbols().NameFor(shape.root.variable->Declaration()->symbol);
+ }
+
+ for (auto& op : shape.ops) {
+ ss << "_";
+
+ if (std::holds_alternative<DynamicIndex>(op)) {
+ /// The op uses a dynamic (runtime-expression) index.
+ ss << "X";
+ continue;
+ }
+
+ if (auto* member = std::get_if<Symbol>(&op)) {
+ ss << sym.NameFor(*member);
+ continue;
+ }
+
+ TINT_ICE(Transform, b.Diagnostics()) << "unhandled variant for access chain";
+ break;
+ }
+ return ss.str();
+ }
+
+ /// Builds an expresion to the root of an access, returning the new expression.
+ /// @param root the AccessRoot
+ /// @param deref if true, the returned expression will always be a reference type.
+ const ast::Expression* BuildAccessRootExpr(const AccessRoot& root, bool deref) {
+ if (auto* param = root.variable->As<sem::Parameter>()) {
+ if (auto symbols = clone_state->current_variant->ptr_param_symbols.Find(param)) {
+ if (deref) {
+ return b.Deref(b.Expr(symbols->base_ptr));
+ }
+ return b.Expr(symbols->base_ptr);
+ }
+ }
+
+ const ast::Expression* expr = b.Expr(ctx.Clone(root.variable->Declaration()->symbol));
+ if (deref) {
+ if (root.variable->Type()->Is<sem::Pointer>()) {
+ expr = b.Deref(expr);
+ }
+ }
+ return expr;
+ }
+
+ /// Builds a single access in an access chain, returning the new expression.
+ /// The returned expression will always be of a reference type.
+ /// @param expr the input expression
+ /// @param access the access to perform on the current expression
+ /// @param dynamic_index a function that obtains the i'th dynamic index
+ const ast::Expression* BuildAccessExpr(
+ const ast::Expression* expr,
+ const AccessOp& access,
+ std::function<const ast::Expression*(size_t)> dynamic_index) {
+ if (auto* dyn_idx = std::get_if<DynamicIndex>(&access)) {
+ /// The access uses a dynamic (runtime-expression) index.
+ auto* idx = dynamic_index(dyn_idx->slot);
+ return b.IndexAccessor(expr, idx);
+ }
+
+ if (auto* member = std::get_if<Symbol>(&access)) {
+ /// The access is a member access.
+ return b.MemberAccessor(expr, ctx.Clone(*member));
+ }
+
+ TINT_ICE(Transform, b.Diagnostics()) << "unhandled variant type for access chain";
+ return nullptr;
+ }
+
+ /// @returns a new Symbol starting with @p symbol concatenated with @p suffix, and possibly an
+ /// underscore and number, if the symbol is already taken.
+ Symbol UniqueSymbolWithSuffix(Symbol symbol, const std::string& suffix) {
+ auto str = ctx.src->Symbols().NameFor(symbol) + suffix;
+ return unique_symbols.GetOrCreate(str, [&] { return b.Symbols().New(str); });
+ }
+
+ /// @returns true if the function @p fn has at least one pointer parameter.
+ static bool HasPointerParameter(const sem::Function* fn) {
+ for (auto* param : fn->Parameters()) {
+ if (param->Type()->Is<sem::Pointer>()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /// @returns true if the function @p fn has at least one pointer parameter in an address space
+ /// that must be replaced. If this function is not called, then the function cannot be sensibly
+ /// generated, and must be stripped.
+ static bool MustBeCalled(const sem::Function* fn) {
+ for (auto* param : fn->Parameters()) {
+ if (auto* ptr = param->Type()->As<sem::Pointer>()) {
+ switch (ptr->AddressSpace()) {
+ case ast::AddressSpace::kUniform:
+ case ast::AddressSpace::kStorage:
+ case ast::AddressSpace::kWorkgroup:
+ return true;
+ default:
+ return false;
+ }
+ }
+ }
+ return false;
+ }
+
+ /// @returns true if the given address space is 'private' or 'function'.
+ static bool IsPrivateOrFunction(const ast::AddressSpace sc) {
+ return sc == ast::AddressSpace::kPrivate || sc == ast::AddressSpace::kFunction;
+ }
+};
+
+DirectVariableAccess::Config::Config(const Options& opt) : options(opt) {}
+
+DirectVariableAccess::Config::~Config() = default;
+
+DirectVariableAccess::DirectVariableAccess() = default;
+
+DirectVariableAccess::~DirectVariableAccess() = default;
+
+Transform::ApplyResult DirectVariableAccess::Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap&) const {
+ Options options;
+ if (auto* cfg = inputs.Get<Config>()) {
+ options = cfg->options;
+ }
+ return State(program, options).Run();
+}
+
+} // namespace tint::transform
diff --git a/src/tint/transform/direct_variable_access.h b/src/tint/transform/direct_variable_access.h
new file mode 100644
index 0000000..34b6e91
--- /dev/null
+++ b/src/tint/transform/direct_variable_access.h
@@ -0,0 +1,74 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_TINT_TRANSFORM_DIRECT_VARIABLE_ACCESS_H_
+#define SRC_TINT_TRANSFORM_DIRECT_VARIABLE_ACCESS_H_
+
+#include "src/tint/transform/transform.h"
+
+namespace tint::transform {
+
+/// DirectVariableAccess is a transform that allows usage of pointer parameters in the 'storage',
+/// 'uniform' and 'workgroup' address space, and passing of pointers to sub-objects. These pointers
+/// are only allowed by the resolver when the `chromium_experimental_full_ptr_parameters` extension
+/// is enabled.
+///
+/// DirectVariableAccess works by creating specializations of functions that have pointer
+/// parameters, one specialization for each pointer argument's unique access chain 'shape' from a
+/// unique variable. Calls to specialized functions are transformed so that the pointer arguments
+/// are replaced with an array of access-chain indicies, and if the pointer is in the 'function' or
+/// 'private' address space, also with a pointer to the root object. For more information, see the
+/// comments in src/tint/transform/direct_variable_access.cc.
+///
+/// @note DirectVariableAccess requires the transform::Unshadow transform to have been run first.
+class DirectVariableAccess final : public Castable<DirectVariableAccess, Transform> {
+ public:
+ /// Constructor
+ DirectVariableAccess();
+ /// Destructor
+ ~DirectVariableAccess() override;
+
+ /// Options adjusts the behaviour of the transform.
+ struct Options {
+ /// If true, then 'private' sub-object pointer arguments will be transformed.
+ bool transform_private = false;
+ /// If true, then 'function' sub-object pointer arguments will be transformed.
+ bool transform_function = false;
+ };
+
+ /// Config is consumed by the DirectVariableAccess transform.
+ /// Config specifies the behavior of the transform.
+ struct Config final : public Castable<Data, transform::Data> {
+ /// Constructor
+ /// @param options behavior of the transform
+ explicit Config(const Options& options);
+ /// Destructor
+ ~Config() override;
+
+ /// The transform behavior options
+ const Options options;
+ };
+
+ /// @copydoc Transform::Apply
+ ApplyResult Apply(const Program* program,
+ const DataMap& inputs,
+ DataMap& outputs) const override;
+
+ private:
+ struct State;
+};
+
+} // namespace tint::transform
+
+#endif // SRC_TINT_TRANSFORM_DIRECT_VARIABLE_ACCESS_H_
diff --git a/src/tint/transform/direct_variable_access_test.cc b/src/tint/transform/direct_variable_access_test.cc
new file mode 100644
index 0000000..4c112d4
--- /dev/null
+++ b/src/tint/transform/direct_variable_access_test.cc
@@ -0,0 +1,2697 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/transform/direct_variable_access.h"
+
+#include <memory>
+#include <utility>
+
+#include "src/tint/transform/test_helper.h"
+#include "src/tint/utils/string.h"
+
+namespace tint::transform {
+namespace {
+
+/// @returns a DataMap with DirectVariableAccess::Config::transform_private enabled.
+static DataMap EnablePrivate() {
+ DirectVariableAccess::Options opts;
+ opts.transform_private = true;
+
+ DataMap inputs;
+ inputs.Add<DirectVariableAccess::Config>(opts);
+ return inputs;
+}
+
+/// @returns a DataMap with DirectVariableAccess::Config::transform_function enabled.
+static DataMap EnableFunction() {
+ DirectVariableAccess::Options opts;
+ opts.transform_function = true;
+
+ DataMap inputs;
+ inputs.Add<DirectVariableAccess::Config>(opts);
+ return inputs;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// ShouldRun tests
+////////////////////////////////////////////////////////////////////////////////
+namespace should_run {
+
+using DirectVariableAccessShouldRunTest = TransformTest;
+
+TEST_F(DirectVariableAccessShouldRunTest, EmptyModule) {
+ auto* src = R"()";
+
+ EXPECT_FALSE(ShouldRun<DirectVariableAccess>(src));
+}
+
+} // namespace should_run
+
+////////////////////////////////////////////////////////////////////////////////
+// remove uncalled
+////////////////////////////////////////////////////////////////////////////////
+namespace remove_uncalled {
+
+using DirectVariableAccessRemoveUncalledTest = TransformTest;
+
+TEST_F(DirectVariableAccessRemoveUncalledTest, PtrUniform) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+var<private> keep_me = 42;
+
+fn u(pre : i32, p : ptr<uniform, i32>, post : i32) -> i32 {
+ return *(p);
+}
+
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+var<private> keep_me = 42;
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessRemoveUncalledTest, PtrStorage) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+var<private> keep_me = 42;
+
+fn s(pre : i32, p : ptr<storage, i32>, post : i32) -> i32 {
+ return *(p);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+var<private> keep_me = 42;
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessRemoveUncalledTest, PtrWorkgroup) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+var<private> keep_me = 42;
+
+fn w(pre : i32, p : ptr<workgroup, i32>, post : i32) -> i32 {
+ return *(p);
+}
+
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+var<private> keep_me = 42;
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessRemoveUncalledTest, PtrPrivate_Disabled) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+var<private> keep_me = 42;
+
+fn f(pre : i32, p : ptr<private, i32>, post : i32) -> i32 {
+ return *(p);
+}
+)";
+
+ auto* expect = src;
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessRemoveUncalledTest, PtrPrivate_Enabled) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+var<private> keep_me = 42;
+)";
+
+ auto* expect = src;
+
+ auto got = Run<DirectVariableAccess>(src, EnablePrivate());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessRemoveUncalledTest, PtrFunction_Disabled) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+var<private> keep_me = 42;
+
+fn f(pre : i32, p : ptr<function, i32>, post : i32) -> i32 {
+ return *(p);
+}
+)";
+
+ auto* expect = src;
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessRemoveUncalledTest, PtrFunction_Enabled) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+var<private> keep_me = 42;
+)";
+
+ auto* expect = src;
+
+ auto got = Run<DirectVariableAccess>(src, EnableFunction());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+} // namespace remove_uncalled
+
+////////////////////////////////////////////////////////////////////////////////
+// pointer chains
+////////////////////////////////////////////////////////////////////////////////
+namespace pointer_chains_tests {
+
+using DirectVariableAccessPtrChainsTest = TransformTest;
+
+TEST_F(DirectVariableAccessPtrChainsTest, ConstantIndices) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<uniform> U : array<array<array<vec4<i32>, 8>, 8>, 8>;
+
+fn a(pre : i32, p : ptr<uniform, vec4<i32>>, post : i32) -> vec4<i32> {
+ return *p;
+}
+
+fn b() {
+ let p0 = &U;
+ let p1 = &(*p0)[1];
+ let p2 = &(*p1)[1+1];
+ let p3 = &(*p2)[2*2 - 1];
+ a(10, p3, 20);
+}
+
+fn c(p : ptr<uniform, array<array<array<vec4<i32>, 8>, 8>, 8>>) {
+ let p0 = p;
+ let p1 = &(*p0)[1];
+ let p2 = &(*p1)[1+1];
+ let p3 = &(*p2)[2*2 - 1];
+ a(10, p3, 20);
+}
+
+fn d() {
+ c(&U);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<uniform> U : array<array<array<vec4<i32>, 8>, 8>, 8>;
+
+type U_X_X_X = array<u32, 3u>;
+
+fn a_U_X_X_X(pre : i32, p : U_X_X_X, post : i32) -> vec4<i32> {
+ return U[p[0]][p[1]][p[2]];
+}
+
+fn b() {
+ let p0 = &(U);
+ let p1 = &((*(p0))[1]);
+ let p2 = &((*(p1))[(1 + 1)]);
+ let p3 = &((*(p2))[((2 * 2) - 1)]);
+ a_U_X_X_X(10, U_X_X_X(1, 2, 3), 20);
+}
+
+fn c_U() {
+ let p0 = &(U);
+ let p1 = &(U[1]);
+ let p2 = &(U[1][2]);
+ let p3 = &(U[1][2][3]);
+ a_U_X_X_X(10, U_X_X_X(1, 2, 3), 20);
+}
+
+fn d() {
+ c_U();
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessPtrChainsTest, HoistIndices) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<uniform> U : array<array<array<vec4<i32>, 8>, 8>, 8>;
+
+var<private> i : i32;
+fn first() -> i32 {
+ i++;
+ return i;
+}
+fn second() -> i32 {
+ i++;
+ return i;
+}
+fn third() -> i32 {
+ i++;
+ return i;
+}
+
+fn a(pre : i32, p : ptr<uniform, vec4<i32>>, post : i32) -> vec4<i32> {
+ return *p;
+}
+
+fn b() {
+ let p0 = &U;
+ let p1 = &(*p0)[first()];
+ let p2 = &(*p1)[second()][third()];
+ a(10, p2, 20);
+}
+
+fn c(p : ptr<uniform, array<array<array<vec4<i32>, 8>, 8>, 8>>) {
+ let p0 = &U;
+ let p1 = &(*p0)[first()];
+ let p2 = &(*p1)[second()][third()];
+ a(10, p2, 20);
+}
+
+fn d() {
+ c(&U);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<uniform> U : array<array<array<vec4<i32>, 8>, 8>, 8>;
+
+var<private> i : i32;
+
+fn first() -> i32 {
+ i++;
+ return i;
+}
+
+fn second() -> i32 {
+ i++;
+ return i;
+}
+
+fn third() -> i32 {
+ i++;
+ return i;
+}
+
+type U_X_X_X = array<u32, 3u>;
+
+fn a_U_X_X_X(pre : i32, p : U_X_X_X, post : i32) -> vec4<i32> {
+ return U[p[0]][p[1]][p[2]];
+}
+
+fn b() {
+ let p0 = &(U);
+ let ptr_index_save = first();
+ let p1 = &((*(p0))[ptr_index_save]);
+ let ptr_index_save_1 = second();
+ let ptr_index_save_2 = third();
+ let p2 = &((*(p1))[ptr_index_save_1][ptr_index_save_2]);
+ a_U_X_X_X(10, U_X_X_X(u32(ptr_index_save), u32(ptr_index_save_1), u32(ptr_index_save_2)), 20);
+}
+
+fn c_U() {
+ let p0 = &(U);
+ let ptr_index_save_3 = first();
+ let p1 = &((*(p0))[ptr_index_save_3]);
+ let ptr_index_save_4 = second();
+ let ptr_index_save_5 = third();
+ let p2 = &((*(p1))[ptr_index_save_4][ptr_index_save_5]);
+ a_U_X_X_X(10, U_X_X_X(u32(ptr_index_save_3), u32(ptr_index_save_4), u32(ptr_index_save_5)), 20);
+}
+
+fn d() {
+ c_U();
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessPtrChainsTest, HoistInForLoopInit) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<uniform> U : array<array<vec4<i32>, 8>, 8>;
+
+var<private> i : i32;
+fn first() -> i32 {
+ i++;
+ return i;
+}
+fn second() -> i32 {
+ i++;
+ return i;
+}
+
+fn a(pre : i32, p : ptr<uniform, vec4<i32>>, post : i32) -> vec4<i32> {
+ return *p;
+}
+
+fn b() {
+ for (let p1 = &U[first()]; true; ) {
+ a(10, &(*p1)[second()], 20);
+ }
+}
+
+fn c(p : ptr<uniform, array<array<vec4<i32>, 8>, 8>>) {
+ for (let p1 = &(*p)[first()]; true; ) {
+ a(10, &(*p1)[second()], 20);
+ }
+}
+
+fn d() {
+ c(&U);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<uniform> U : array<array<vec4<i32>, 8>, 8>;
+
+var<private> i : i32;
+
+fn first() -> i32 {
+ i++;
+ return i;
+}
+
+fn second() -> i32 {
+ i++;
+ return i;
+}
+
+type U_X_X = array<u32, 2u>;
+
+fn a_U_X_X(pre : i32, p : U_X_X, post : i32) -> vec4<i32> {
+ return U[p[0]][p[1]];
+}
+
+fn b() {
+ let ptr_index_save = first();
+ for(let p1 = &(U[ptr_index_save]); true; ) {
+ a_U_X_X(10, U_X_X(u32(ptr_index_save), u32(second())), 20);
+ }
+}
+
+fn c_U() {
+ let ptr_index_save_1 = first();
+ for(let p1 = &(U[ptr_index_save_1]); true; ) {
+ a_U_X_X(10, U_X_X(u32(ptr_index_save_1), u32(second())), 20);
+ }
+}
+
+fn d() {
+ c_U();
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessPtrChainsTest, HoistInForLoopCond) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<uniform> U : array<array<vec4<i32>, 8>, 8>;
+
+var<private> i : i32;
+fn first() -> i32 {
+ i++;
+ return i;
+}
+fn second() -> i32 {
+ i++;
+ return i;
+}
+
+fn a(pre : i32, p : ptr<uniform, vec4<i32>>, post : i32) -> vec4<i32> {
+ return *p;
+}
+
+fn b() {
+ let p = &U[first()][second()];
+ for (; a(10, p, 20).x < 4; ) {
+ let body = 1;
+ }
+}
+
+fn c(p : ptr<uniform, array<array<vec4<i32>, 8>, 8>>) {
+ let p2 = &(*p)[first()][second()];
+ for (; a(10, p2, 20).x < 4; ) {
+ let body = 1;
+ }
+}
+
+fn d() {
+ c(&U);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<uniform> U : array<array<vec4<i32>, 8>, 8>;
+
+var<private> i : i32;
+
+fn first() -> i32 {
+ i++;
+ return i;
+}
+
+fn second() -> i32 {
+ i++;
+ return i;
+}
+
+type U_X_X = array<u32, 2u>;
+
+fn a_U_X_X(pre : i32, p : U_X_X, post : i32) -> vec4<i32> {
+ return U[p[0]][p[1]];
+}
+
+fn b() {
+ let ptr_index_save = first();
+ let ptr_index_save_1 = second();
+ let p = &(U[ptr_index_save][ptr_index_save_1]);
+ for(; (a_U_X_X(10, U_X_X(u32(ptr_index_save), u32(ptr_index_save_1)), 20).x < 4); ) {
+ let body = 1;
+ }
+}
+
+fn c_U() {
+ let ptr_index_save_2 = first();
+ let ptr_index_save_3 = second();
+ let p2 = &(U[ptr_index_save_2][ptr_index_save_3]);
+ for(; (a_U_X_X(10, U_X_X(u32(ptr_index_save_2), u32(ptr_index_save_3)), 20).x < 4); ) {
+ let body = 1;
+ }
+}
+
+fn d() {
+ c_U();
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessPtrChainsTest, HoistInForLoopCont) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<uniform> U : array<array<vec4<i32>, 8>, 8>;
+
+var<private> i : i32;
+fn first() -> i32 {
+ i++;
+ return i;
+}
+fn second() -> i32 {
+ i++;
+ return i;
+}
+
+fn a(pre : i32, p : ptr<uniform, vec4<i32>>, post : i32) -> vec4<i32> {
+ return *p;
+}
+
+fn b() {
+ let p = &U[first()][second()];
+ for (var i = 0; i < 3; a(10, p, 20)) {
+ i++;
+ }
+}
+
+fn c(p : ptr<uniform, array<array<vec4<i32>, 8>, 8>>) {
+ let p2 = &(*p)[first()][second()];
+ for (var i = 0; i < 3; a(10, p2, 20)) {
+ i++;
+ }
+}
+
+fn d() {
+ c(&U);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<uniform> U : array<array<vec4<i32>, 8>, 8>;
+
+var<private> i : i32;
+
+fn first() -> i32 {
+ i++;
+ return i;
+}
+
+fn second() -> i32 {
+ i++;
+ return i;
+}
+
+type U_X_X = array<u32, 2u>;
+
+fn a_U_X_X(pre : i32, p : U_X_X, post : i32) -> vec4<i32> {
+ return U[p[0]][p[1]];
+}
+
+fn b() {
+ let ptr_index_save = first();
+ let ptr_index_save_1 = second();
+ let p = &(U[ptr_index_save][ptr_index_save_1]);
+ for(var i = 0; (i < 3); a_U_X_X(10, U_X_X(u32(ptr_index_save), u32(ptr_index_save_1)), 20)) {
+ i++;
+ }
+}
+
+fn c_U() {
+ let ptr_index_save_2 = first();
+ let ptr_index_save_3 = second();
+ let p2 = &(U[ptr_index_save_2][ptr_index_save_3]);
+ for(var i = 0; (i < 3); a_U_X_X(10, U_X_X(u32(ptr_index_save_2), u32(ptr_index_save_3)), 20)) {
+ i++;
+ }
+}
+
+fn d() {
+ c_U();
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessPtrChainsTest, HoistInWhileCond) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<uniform> U : array<array<vec4<i32>, 8>, 8>;
+
+var<private> i : i32;
+fn first() -> i32 {
+ i++;
+ return i;
+}
+fn second() -> i32 {
+ i++;
+ return i;
+}
+
+fn a(pre : i32, p : ptr<uniform, vec4<i32>>, post : i32) -> vec4<i32> {
+ return *p;
+}
+
+fn b() {
+ let p = &U[first()][second()];
+ while (a(10, p, 20).x < 4) {
+ let body = 1;
+ }
+}
+
+fn c(p : ptr<uniform, array<array<vec4<i32>, 8>, 8>>) {
+ let p2 = &(*p)[first()][second()];
+ while (a(10, p2, 20).x < 4) {
+ let body = 1;
+ }
+}
+
+fn d() {
+ c(&U);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<uniform> U : array<array<vec4<i32>, 8>, 8>;
+
+var<private> i : i32;
+
+fn first() -> i32 {
+ i++;
+ return i;
+}
+
+fn second() -> i32 {
+ i++;
+ return i;
+}
+
+type U_X_X = array<u32, 2u>;
+
+fn a_U_X_X(pre : i32, p : U_X_X, post : i32) -> vec4<i32> {
+ return U[p[0]][p[1]];
+}
+
+fn b() {
+ let ptr_index_save = first();
+ let ptr_index_save_1 = second();
+ let p = &(U[ptr_index_save][ptr_index_save_1]);
+ while((a_U_X_X(10, U_X_X(u32(ptr_index_save), u32(ptr_index_save_1)), 20).x < 4)) {
+ let body = 1;
+ }
+}
+
+fn c_U() {
+ let ptr_index_save_2 = first();
+ let ptr_index_save_3 = second();
+ let p2 = &(U[ptr_index_save_2][ptr_index_save_3]);
+ while((a_U_X_X(10, U_X_X(u32(ptr_index_save_2), u32(ptr_index_save_3)), 20).x < 4)) {
+ let body = 1;
+ }
+}
+
+fn d() {
+ c_U();
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+} // namespace pointer_chains_tests
+
+////////////////////////////////////////////////////////////////////////////////
+// 'uniform' address space
+////////////////////////////////////////////////////////////////////////////////
+namespace uniform_as_tests {
+
+using DirectVariableAccessUniformASTest = TransformTest;
+
+TEST_F(DirectVariableAccessUniformASTest, Param_ptr_i32_read) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<uniform> U : i32;
+
+fn a(pre : i32, p : ptr<uniform, i32>, post : i32) -> i32 {
+ return *p;
+}
+
+fn b() {
+ a(10, &U, 20);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<uniform> U : i32;
+
+fn a_U(pre : i32, post : i32) -> i32 {
+ return U;
+}
+
+fn b() {
+ a_U(10, 20);
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessUniformASTest, Param_ptr_vec4i32_Via_array_DynamicRead) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<uniform> U : array<vec4<i32>, 8>;
+
+fn a(pre : i32, p : ptr<uniform, vec4<i32>>, post : i32) -> vec4<i32> {
+ return *p;
+}
+
+fn b() {
+ let I = 3;
+ a(10, &U[I], 20);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<uniform> U : array<vec4<i32>, 8>;
+
+type U_X = array<u32, 1u>;
+
+fn a_U_X(pre : i32, p : U_X, post : i32) -> vec4<i32> {
+ return U[p[0]];
+}
+
+fn b() {
+ let I = 3;
+ a_U_X(10, U_X(u32(I)), 20);
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessUniformASTest, CallChaining) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct Inner {
+ mat : mat3x4<f32>,
+};
+
+type InnerArr = array<Inner, 4>;
+
+struct Outer {
+ arr : InnerArr,
+ mat : mat3x4<f32>,
+};
+
+@group(0) @binding(0) var<uniform> U : Outer;
+
+fn f0(p : ptr<uniform, vec4<f32>>) -> f32 {
+ return (*p).x;
+}
+
+fn f1(p : ptr<uniform, mat3x4<f32>>) -> f32 {
+ var res : f32;
+ {
+ // call f0() with inline usage of p
+ res += f0(&(*p)[1]);
+ }
+ {
+ // call f0() with pointer-let usage of p
+ let p_vec = &(*p)[1];
+ res += f0(p_vec);
+ }
+ {
+ // call f0() with inline usage of U
+ res += f0(&U.arr[2].mat[1]);
+ }
+ {
+ // call f0() with pointer-let usage of U
+ let p_vec = &U.arr[2].mat[1];
+ res += f0(p_vec);
+ }
+ return res;
+}
+
+fn f2(p : ptr<uniform, Inner>) -> f32 {
+ let p_mat = &(*p).mat;
+ return f1(p_mat);
+}
+
+fn f3(p0 : ptr<uniform, InnerArr>, p1 : ptr<uniform, mat3x4<f32>>) -> f32 {
+ let p0_inner = &(*p0)[3];
+ return f2(p0_inner) + f1(p1);
+}
+
+fn f4(p : ptr<uniform, Outer>) -> f32 {
+ return f3(&(*p).arr, &U.mat);
+}
+
+fn b() {
+ f4(&U);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct Inner {
+ mat : mat3x4<f32>,
+}
+
+type InnerArr = array<Inner, 4>;
+
+struct Outer {
+ arr : InnerArr,
+ mat : mat3x4<f32>,
+}
+
+@group(0) @binding(0) var<uniform> U : Outer;
+
+type U_mat_X = array<u32, 1u>;
+
+fn f0_U_mat_X(p : U_mat_X) -> f32 {
+ return U.mat[p[0]].x;
+}
+
+type U_arr_X_mat_X = array<u32, 2u>;
+
+fn f0_U_arr_X_mat_X(p : U_arr_X_mat_X) -> f32 {
+ return U.arr[p[0]].mat[p[0]].x;
+}
+
+type U_arr_X_mat_X_1 = array<u32, 2u>;
+
+fn f0_U_arr_X_mat_X_1(p : U_arr_X_mat_X_1) -> f32 {
+ return U.arr[p[0]].mat[p[1]].x;
+}
+
+fn f1_U_mat() -> f32 {
+ var res : f32;
+ {
+ res += f0_U_mat_X(U_mat_X(1));
+ }
+ {
+ let p_vec = &(U.mat[1]);
+ res += f0_U_mat_X(U_mat_X(1));
+ }
+ {
+ res += f0_U_arr_X_mat_X_1(U_arr_X_mat_X_1(2, 1));
+ }
+ {
+ let p_vec = &(U.arr[2].mat[1]);
+ res += f0_U_arr_X_mat_X_1(U_arr_X_mat_X_1(2, 1));
+ }
+ return res;
+}
+
+type U_arr_X_mat = array<u32, 1u>;
+
+fn f1_U_arr_X_mat(p : U_arr_X_mat) -> f32 {
+ var res : f32;
+ {
+ res += f0_U_arr_X_mat_X(U_arr_X_mat_X(p[0u], 1));
+ }
+ {
+ let p_vec = &(U.arr[p[0]].mat[1]);
+ res += f0_U_arr_X_mat_X(U_arr_X_mat_X(p[0u], 1));
+ }
+ {
+ res += f0_U_arr_X_mat_X_1(U_arr_X_mat_X_1(2, 1));
+ }
+ {
+ let p_vec = &(U.arr[2].mat[1]);
+ res += f0_U_arr_X_mat_X_1(U_arr_X_mat_X_1(2, 1));
+ }
+ return res;
+}
+
+type U_arr_X = array<u32, 1u>;
+
+fn f2_U_arr_X(p : U_arr_X) -> f32 {
+ let p_mat = &(U.arr[p[0]].mat);
+ return f1_U_arr_X_mat(U_arr_X_mat(p[0u]));
+}
+
+fn f3_U_arr_U_mat() -> f32 {
+ let p0_inner = &(U.arr[3]);
+ return (f2_U_arr_X(U_arr_X(3)) + f1_U_mat());
+}
+
+fn f4_U() -> f32 {
+ return f3_U_arr_U_mat();
+}
+
+fn b() {
+ f4_U();
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+} // namespace uniform_as_tests
+
+////////////////////////////////////////////////////////////////////////////////
+// 'storage' address space
+////////////////////////////////////////////////////////////////////////////////
+namespace storage_as_tests {
+
+using DirectVariableAccessStorageASTest = TransformTest;
+
+TEST_F(DirectVariableAccessStorageASTest, Param_ptr_i32_Via_struct_read) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ i : i32,
+};
+
+@group(0) @binding(0) var<storage> S : str;
+
+fn a(pre : i32, p : ptr<storage, i32>, post : i32) -> i32 {
+ return *p;
+}
+
+fn b() {
+ a(10, &S.i, 20);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ i : i32,
+}
+
+@group(0) @binding(0) var<storage> S : str;
+
+fn a_S_i(pre : i32, post : i32) -> i32 {
+ return S.i;
+}
+
+fn b() {
+ a_S_i(10, 20);
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessStorageASTest, Param_ptr_arr_i32_Via_struct_write) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ arr : array<i32, 4>,
+};
+
+@group(0) @binding(0) var<storage, read_write> S : str;
+
+fn a(pre : i32, p : ptr<storage, array<i32, 4>, read_write>, post : i32) {
+ *p = array<i32, 4>();
+}
+
+fn b() {
+ a(10, &S.arr, 20);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ arr : array<i32, 4>,
+}
+
+@group(0) @binding(0) var<storage, read_write> S : str;
+
+fn a_S_arr(pre : i32, post : i32) {
+ S.arr = array<i32, 4>();
+}
+
+fn b() {
+ a_S_arr(10, 20);
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessStorageASTest, Param_ptr_vec4i32_Via_array_DynamicWrite) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<storage, read_write> S : array<vec4<i32>, 8>;
+
+fn a(pre : i32, p : ptr<storage, vec4<i32>, read_write>, post : i32) {
+ *p = vec4<i32>();
+}
+
+fn b() {
+ let I = 3;
+ a(10, &S[I], 20);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<storage, read_write> S : array<vec4<i32>, 8>;
+
+type S_X = array<u32, 1u>;
+
+fn a_S_X(pre : i32, p : S_X, post : i32) {
+ S[p[0]] = vec4<i32>();
+}
+
+fn b() {
+ let I = 3;
+ a_S_X(10, S_X(u32(I)), 20);
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessStorageASTest, CallChaining) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct Inner {
+ mat : mat3x4<f32>,
+};
+
+type InnerArr = array<Inner, 4>;
+
+struct Outer {
+ arr : InnerArr,
+ mat : mat3x4<f32>,
+};
+
+@group(0) @binding(0) var<storage> S : Outer;
+
+fn f0(p : ptr<storage, vec4<f32>>) -> f32 {
+ return (*p).x;
+}
+
+fn f1(p : ptr<storage, mat3x4<f32>>) -> f32 {
+ var res : f32;
+ {
+ // call f0() with inline usage of p
+ res += f0(&(*p)[1]);
+ }
+ {
+ // call f0() with pointer-let usage of p
+ let p_vec = &(*p)[1];
+ res += f0(p_vec);
+ }
+ {
+ // call f0() with inline usage of S
+ res += f0(&S.arr[2].mat[1]);
+ }
+ {
+ // call f0() with pointer-let usage of S
+ let p_vec = &S.arr[2].mat[1];
+ res += f0(p_vec);
+ }
+ return res;
+}
+
+fn f2(p : ptr<storage, Inner>) -> f32 {
+ let p_mat = &(*p).mat;
+ return f1(p_mat);
+}
+
+fn f3(p0 : ptr<storage, InnerArr>, p1 : ptr<storage, mat3x4<f32>>) -> f32 {
+ let p0_inner = &(*p0)[3];
+ return f2(p0_inner) + f1(p1);
+}
+
+fn f4(p : ptr<storage, Outer>) -> f32 {
+ return f3(&(*p).arr, &S.mat);
+}
+
+fn b() {
+ f4(&S);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct Inner {
+ mat : mat3x4<f32>,
+}
+
+type InnerArr = array<Inner, 4>;
+
+struct Outer {
+ arr : InnerArr,
+ mat : mat3x4<f32>,
+}
+
+@group(0) @binding(0) var<storage> S : Outer;
+
+type S_mat_X = array<u32, 1u>;
+
+fn f0_S_mat_X(p : S_mat_X) -> f32 {
+ return S.mat[p[0]].x;
+}
+
+type S_arr_X_mat_X = array<u32, 2u>;
+
+fn f0_S_arr_X_mat_X(p : S_arr_X_mat_X) -> f32 {
+ return S.arr[p[0]].mat[p[0]].x;
+}
+
+type S_arr_X_mat_X_1 = array<u32, 2u>;
+
+fn f0_S_arr_X_mat_X_1(p : S_arr_X_mat_X_1) -> f32 {
+ return S.arr[p[0]].mat[p[1]].x;
+}
+
+fn f1_S_mat() -> f32 {
+ var res : f32;
+ {
+ res += f0_S_mat_X(S_mat_X(1));
+ }
+ {
+ let p_vec = &(S.mat[1]);
+ res += f0_S_mat_X(S_mat_X(1));
+ }
+ {
+ res += f0_S_arr_X_mat_X_1(S_arr_X_mat_X_1(2, 1));
+ }
+ {
+ let p_vec = &(S.arr[2].mat[1]);
+ res += f0_S_arr_X_mat_X_1(S_arr_X_mat_X_1(2, 1));
+ }
+ return res;
+}
+
+type S_arr_X_mat = array<u32, 1u>;
+
+fn f1_S_arr_X_mat(p : S_arr_X_mat) -> f32 {
+ var res : f32;
+ {
+ res += f0_S_arr_X_mat_X(S_arr_X_mat_X(p[0u], 1));
+ }
+ {
+ let p_vec = &(S.arr[p[0]].mat[1]);
+ res += f0_S_arr_X_mat_X(S_arr_X_mat_X(p[0u], 1));
+ }
+ {
+ res += f0_S_arr_X_mat_X_1(S_arr_X_mat_X_1(2, 1));
+ }
+ {
+ let p_vec = &(S.arr[2].mat[1]);
+ res += f0_S_arr_X_mat_X_1(S_arr_X_mat_X_1(2, 1));
+ }
+ return res;
+}
+
+type S_arr_X = array<u32, 1u>;
+
+fn f2_S_arr_X(p : S_arr_X) -> f32 {
+ let p_mat = &(S.arr[p[0]].mat);
+ return f1_S_arr_X_mat(S_arr_X_mat(p[0u]));
+}
+
+fn f3_S_arr_S_mat() -> f32 {
+ let p0_inner = &(S.arr[3]);
+ return (f2_S_arr_X(S_arr_X(3)) + f1_S_mat());
+}
+
+fn f4_S() -> f32 {
+ return f3_S_arr_S_mat();
+}
+
+fn b() {
+ f4_S();
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+} // namespace storage_as_tests
+
+////////////////////////////////////////////////////////////////////////////////
+// 'workgroup' address space
+////////////////////////////////////////////////////////////////////////////////
+namespace workgroup_as_tests {
+
+using DirectVariableAccessWorkgroupASTest = TransformTest;
+
+TEST_F(DirectVariableAccessWorkgroupASTest, Param_ptr_vec4i32_Via_array_StaticRead) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+var<workgroup> W : array<vec4<i32>, 8>;
+
+fn a(pre : i32, p : ptr<workgroup, vec4<i32>>, post : i32) -> vec4<i32> {
+ return *p;
+}
+
+fn b() {
+ a(10, &W[3], 20);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+var<workgroup> W : array<vec4<i32>, 8>;
+
+type W_X = array<u32, 1u>;
+
+fn a_W_X(pre : i32, p : W_X, post : i32) -> vec4<i32> {
+ return W[p[0]];
+}
+
+fn b() {
+ a_W_X(10, W_X(3), 20);
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessWorkgroupASTest, Param_ptr_vec4i32_Via_array_StaticWrite) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+var<workgroup> W : array<vec4<i32>, 8>;
+
+fn a(pre : i32, p : ptr<workgroup, vec4<i32>>, post : i32) {
+ *p = vec4<i32>();
+}
+
+fn b() {
+ a(10, &W[3], 20);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+var<workgroup> W : array<vec4<i32>, 8>;
+
+type W_X = array<u32, 1u>;
+
+fn a_W_X(pre : i32, p : W_X, post : i32) {
+ W[p[0]] = vec4<i32>();
+}
+
+fn b() {
+ a_W_X(10, W_X(3), 20);
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessWorkgroupASTest, CallChaining) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct Inner {
+ mat : mat3x4<f32>,
+};
+
+type InnerArr = array<Inner, 4>;
+
+struct Outer {
+ arr : InnerArr,
+ mat : mat3x4<f32>,
+};
+
+var<workgroup> W : Outer;
+
+fn f0(p : ptr<workgroup, vec4<f32>>) -> f32 {
+ return (*p).x;
+}
+
+fn f1(p : ptr<workgroup, mat3x4<f32>>) -> f32 {
+ var res : f32;
+ {
+ // call f0() with inline usage of p
+ res += f0(&(*p)[1]);
+ }
+ {
+ // call f0() with pointer-let usage of p
+ let p_vec = &(*p)[1];
+ res += f0(p_vec);
+ }
+ {
+ // call f0() with inline usage of W
+ res += f0(&W.arr[2].mat[1]);
+ }
+ {
+ // call f0() with pointer-let usage of W
+ let p_vec = &W.arr[2].mat[1];
+ res += f0(p_vec);
+ }
+ return res;
+}
+
+fn f2(p : ptr<workgroup, Inner>) -> f32 {
+ let p_mat = &(*p).mat;
+ return f1(p_mat);
+}
+
+fn f3(p0 : ptr<workgroup, InnerArr>, p1 : ptr<workgroup, mat3x4<f32>>) -> f32 {
+ let p0_inner = &(*p0)[3];
+ return f2(p0_inner) + f1(p1);
+}
+
+fn f4(p : ptr<workgroup, Outer>) -> f32 {
+ return f3(&(*p).arr, &W.mat);
+}
+
+fn b() {
+ f4(&W);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct Inner {
+ mat : mat3x4<f32>,
+}
+
+type InnerArr = array<Inner, 4>;
+
+struct Outer {
+ arr : InnerArr,
+ mat : mat3x4<f32>,
+}
+
+var<workgroup> W : Outer;
+
+type W_mat_X = array<u32, 1u>;
+
+fn f0_W_mat_X(p : W_mat_X) -> f32 {
+ return W.mat[p[0]].x;
+}
+
+type W_arr_X_mat_X = array<u32, 2u>;
+
+fn f0_W_arr_X_mat_X(p : W_arr_X_mat_X) -> f32 {
+ return W.arr[p[0]].mat[p[0]].x;
+}
+
+type W_arr_X_mat_X_1 = array<u32, 2u>;
+
+fn f0_W_arr_X_mat_X_1(p : W_arr_X_mat_X_1) -> f32 {
+ return W.arr[p[0]].mat[p[1]].x;
+}
+
+fn f1_W_mat() -> f32 {
+ var res : f32;
+ {
+ res += f0_W_mat_X(W_mat_X(1));
+ }
+ {
+ let p_vec = &(W.mat[1]);
+ res += f0_W_mat_X(W_mat_X(1));
+ }
+ {
+ res += f0_W_arr_X_mat_X_1(W_arr_X_mat_X_1(2, 1));
+ }
+ {
+ let p_vec = &(W.arr[2].mat[1]);
+ res += f0_W_arr_X_mat_X_1(W_arr_X_mat_X_1(2, 1));
+ }
+ return res;
+}
+
+type W_arr_X_mat = array<u32, 1u>;
+
+fn f1_W_arr_X_mat(p : W_arr_X_mat) -> f32 {
+ var res : f32;
+ {
+ res += f0_W_arr_X_mat_X(W_arr_X_mat_X(p[0u], 1));
+ }
+ {
+ let p_vec = &(W.arr[p[0]].mat[1]);
+ res += f0_W_arr_X_mat_X(W_arr_X_mat_X(p[0u], 1));
+ }
+ {
+ res += f0_W_arr_X_mat_X_1(W_arr_X_mat_X_1(2, 1));
+ }
+ {
+ let p_vec = &(W.arr[2].mat[1]);
+ res += f0_W_arr_X_mat_X_1(W_arr_X_mat_X_1(2, 1));
+ }
+ return res;
+}
+
+type W_arr_X = array<u32, 1u>;
+
+fn f2_W_arr_X(p : W_arr_X) -> f32 {
+ let p_mat = &(W.arr[p[0]].mat);
+ return f1_W_arr_X_mat(W_arr_X_mat(p[0u]));
+}
+
+fn f3_W_arr_W_mat() -> f32 {
+ let p0_inner = &(W.arr[3]);
+ return (f2_W_arr_X(W_arr_X(3)) + f1_W_mat());
+}
+
+fn f4_W() -> f32 {
+ return f3_W_arr_W_mat();
+}
+
+fn b() {
+ f4_W();
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+} // namespace workgroup_as_tests
+
+////////////////////////////////////////////////////////////////////////////////
+// 'private' address space
+////////////////////////////////////////////////////////////////////////////////
+namespace private_as_tests {
+
+using DirectVariableAccessPrivateASTest = TransformTest;
+
+TEST_F(DirectVariableAccessPrivateASTest, Enabled_Param_ptr_i32_read) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+fn a(pre : i32, p : ptr<private, i32>, post : i32) -> i32 {
+ return *(p);
+}
+
+var<private> P : i32;
+
+fn b() {
+ a(10, &(P), 20);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+fn a_F(pre : i32, p : ptr<private, i32>, post : i32) -> i32 {
+ return *(p);
+}
+
+var<private> P : i32;
+
+fn b() {
+ a_F(10, &(P), 20);
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src, EnablePrivate());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessPrivateASTest, Enabled_Param_ptr_i32_write) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+fn a(pre : i32, p : ptr<private, i32>, post : i32) {
+ *(p) = 42;
+}
+
+var<private> P : i32;
+
+fn b() {
+ a(10, &(P), 20);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+fn a_F(pre : i32, p : ptr<private, i32>, post : i32) {
+ *(p) = 42;
+}
+
+var<private> P : i32;
+
+fn b() {
+ a_F(10, &(P), 20);
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src, EnablePrivate());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessPrivateASTest, Enabled_Param_ptr_i32_Via_struct_read) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ i : i32,
+};
+
+fn a(pre : i32, p : ptr<private, i32>, post : i32) -> i32 {
+ return *p;
+}
+
+var<private> P : str;
+
+fn b() {
+ a(10, &P.i, 20);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ i : i32,
+}
+
+fn a_F_i(pre : i32, p : ptr<private, str>, post : i32) -> i32 {
+ return (*(p)).i;
+}
+
+var<private> P : str;
+
+fn b() {
+ a_F_i(10, &(P), 20);
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src, EnablePrivate());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessPrivateASTest, Disabled_Param_ptr_i32_Via_struct_read) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ i : i32,
+}
+
+fn a(pre : i32, p : ptr<private, i32>, post : i32) -> i32 {
+ return *(p);
+}
+
+var<private> P : str;
+
+fn b() {
+ a(10, &(P.i), 20);
+}
+)";
+
+ auto* expect = src;
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessPrivateASTest, Enabled_Param_ptr_arr_i32_Via_struct_write) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ arr : array<i32, 4>,
+};
+
+fn a(pre : i32, p : ptr<private, array<i32, 4>>, post : i32) {
+ *p = array<i32, 4>();
+}
+
+var<private> P : str;
+
+fn b() {
+ a(10, &P.arr, 20);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ arr : array<i32, 4>,
+}
+
+fn a_F_arr(pre : i32, p : ptr<private, str>, post : i32) {
+ (*(p)).arr = array<i32, 4>();
+}
+
+var<private> P : str;
+
+fn b() {
+ a_F_arr(10, &(P), 20);
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src, EnablePrivate());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessPrivateASTest, Disabled_Param_ptr_arr_i32_Via_struct_write) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ arr : array<i32, 4>,
+}
+
+fn a(pre : i32, p : ptr<private, array<i32, 4>>, post : i32) {
+ *(p) = array<i32, 4>();
+}
+
+var<private> P : str;
+
+fn b() {
+ a(10, &(P.arr), 20);
+}
+)";
+
+ auto* expect = src;
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessPrivateASTest, Enabled_Param_ptr_i32_mixed) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ i : i32,
+};
+
+fn a(pre : i32, p : ptr<private, i32>, post : i32) -> i32 {
+ return *p;
+}
+
+var<private> Pi : i32;
+var<private> Ps : str;
+var<private> Pa : array<i32, 4>;
+
+fn b() {
+ a(10, &Pi, 20);
+ a(30, &Ps.i, 40);
+ a(50, &Pa[2], 60);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ i : i32,
+}
+
+fn a_F(pre : i32, p : ptr<private, i32>, post : i32) -> i32 {
+ return *(p);
+}
+
+fn a_F_i(pre : i32, p : ptr<private, str>, post : i32) -> i32 {
+ return (*(p)).i;
+}
+
+type F_X = array<u32, 1u>;
+
+fn a_F_X(pre : i32, p_base : ptr<private, array<i32, 4u>>, p_indices : F_X, post : i32) -> i32 {
+ return (*(p_base))[p_indices[0]];
+}
+
+var<private> Pi : i32;
+
+var<private> Ps : str;
+
+var<private> Pa : array<i32, 4>;
+
+type F_X_1 = array<u32, 1u>;
+
+fn b() {
+ a_F(10, &(Pi), 20);
+ a_F_i(30, &(Ps), 40);
+ a_F_X(50, &(Pa), F_X_1(2), 60);
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src, EnablePrivate());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessPrivateASTest, Disabled_Param_ptr_i32_mixed) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ i : i32,
+}
+
+fn a(pre : i32, p : ptr<private, i32>, post : i32) -> i32 {
+ return *(p);
+}
+
+var<private> Pi : i32;
+
+var<private> Ps : str;
+
+var<private> Pa : array<i32, 4>;
+
+fn b() {
+ a(10, &(Pi), 20);
+ a(10, &(Ps.i), 20);
+ a(10, &(Pa[2]), 20);
+}
+)";
+
+ auto* expect = src;
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessPrivateASTest, Enabled_CallChaining) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct Inner {
+ mat : mat3x4<f32>,
+};
+
+type InnerArr = array<Inner, 4>;
+
+struct Outer {
+ arr : InnerArr,
+ mat : mat3x4<f32>,
+};
+
+var<private> P : Outer;
+
+fn f0(p : ptr<private, vec4<f32>>) -> f32 {
+ return (*p).x;
+}
+
+fn f1(p : ptr<private, mat3x4<f32>>) -> f32 {
+ var res : f32;
+ {
+ // call f0() with inline usage of p
+ res += f0(&(*p)[1]);
+ }
+ {
+ // call f0() with pointer-let usage of p
+ let p_vec = &(*p)[1];
+ res += f0(p_vec);
+ }
+ {
+ // call f0() with inline usage of P
+ res += f0(&P.arr[2].mat[1]);
+ }
+ {
+ // call f0() with pointer-let usage of P
+ let p_vec = &P.arr[2].mat[1];
+ res += f0(p_vec);
+ }
+ return res;
+}
+
+fn f2(p : ptr<private, Inner>) -> f32 {
+ let p_mat = &(*p).mat;
+ return f1(p_mat);
+}
+
+fn f3(p0 : ptr<private, InnerArr>, p1 : ptr<private, mat3x4<f32>>) -> f32 {
+ let p0_inner = &(*p0)[3];
+ return f2(p0_inner) + f1(p1);
+}
+
+fn f4(p : ptr<private, Outer>) -> f32 {
+ return f3(&(*p).arr, &P.mat);
+}
+
+fn b() {
+ f4(&P);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct Inner {
+ mat : mat3x4<f32>,
+}
+
+type InnerArr = array<Inner, 4>;
+
+struct Outer {
+ arr : InnerArr,
+ mat : mat3x4<f32>,
+}
+
+var<private> P : Outer;
+
+type F_mat_X = array<u32, 1u>;
+
+fn f0_F_mat_X(p_base : ptr<private, Outer>, p_indices : F_mat_X) -> f32 {
+ return (*(p_base)).mat[p_indices[0]].x;
+}
+
+type F_arr_X_mat_X = array<u32, 2u>;
+
+fn f0_F_arr_X_mat_X(p_base : ptr<private, Outer>, p_indices : F_arr_X_mat_X) -> f32 {
+ return (*(p_base)).arr[p_indices[0]].mat[p_indices[0]].x;
+}
+
+type F_arr_X_mat_X_1 = array<u32, 2u>;
+
+fn f0_F_arr_X_mat_X_1(p_base : ptr<private, Outer>, p_indices : F_arr_X_mat_X_1) -> f32 {
+ return (*(p_base)).arr[p_indices[0]].mat[p_indices[1]].x;
+}
+
+type F_mat_X_1 = array<u32, 1u>;
+
+type F_arr_X_mat_X_2 = array<u32, 2u>;
+
+fn f1_F_mat(p : ptr<private, Outer>) -> f32 {
+ var res : f32;
+ {
+ res += f0_F_mat_X(p, F_mat_X_1(1));
+ }
+ {
+ let p_vec = &((*(p)).mat[1]);
+ res += f0_F_mat_X(p, F_mat_X_1(1));
+ }
+ {
+ res += f0_F_arr_X_mat_X_1(&(P), F_arr_X_mat_X_2(2, 1));
+ }
+ {
+ let p_vec = &(P.arr[2].mat[1]);
+ res += f0_F_arr_X_mat_X_1(&(P), F_arr_X_mat_X_2(2, 1));
+ }
+ return res;
+}
+
+type F_arr_X_mat = array<u32, 1u>;
+
+type F_arr_X_mat_X_3 = array<u32, 2u>;
+
+fn f1_F_arr_X_mat(p_base : ptr<private, Outer>, p_indices : F_arr_X_mat) -> f32 {
+ var res : f32;
+ {
+ res += f0_F_arr_X_mat_X(p_base, F_arr_X_mat_X_3(p_indices[0u], 1));
+ }
+ {
+ let p_vec = &((*(p_base)).arr[p_indices[0]].mat[1]);
+ res += f0_F_arr_X_mat_X(p_base, F_arr_X_mat_X_3(p_indices[0u], 1));
+ }
+ {
+ res += f0_F_arr_X_mat_X_1(&(P), F_arr_X_mat_X_2(2, 1));
+ }
+ {
+ let p_vec = &(P.arr[2].mat[1]);
+ res += f0_F_arr_X_mat_X_1(&(P), F_arr_X_mat_X_2(2, 1));
+ }
+ return res;
+}
+
+type F_arr_X = array<u32, 1u>;
+
+type F_arr_X_mat_1 = array<u32, 1u>;
+
+fn f2_F_arr_X(p_base : ptr<private, Outer>, p_indices : F_arr_X) -> f32 {
+ let p_mat = &((*(p_base)).arr[p_indices[0]].mat);
+ return f1_F_arr_X_mat(p_base, F_arr_X_mat_1(p_indices[0u]));
+}
+
+type F_arr_X_1 = array<u32, 1u>;
+
+fn f3_F_arr_F_mat(p0 : ptr<private, Outer>, p1 : ptr<private, Outer>) -> f32 {
+ let p0_inner = &((*(p0)).arr[3]);
+ return (f2_F_arr_X(p0, F_arr_X_1(3)) + f1_F_mat(p1));
+}
+
+fn f4_F(p : ptr<private, Outer>) -> f32 {
+ return f3_F_arr_F_mat(p, &(P));
+}
+
+fn b() {
+ f4_F(&(P));
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src, EnablePrivate());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessPrivateASTest, Disabled_CallChaining) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct Inner {
+ mat : mat3x4<f32>,
+}
+
+type InnerArr = array<Inner, 4>;
+
+struct Outer {
+ arr : InnerArr,
+ mat : mat3x4<f32>,
+}
+
+var<private> P : Outer;
+
+fn f0(p : ptr<private, vec4<f32>>) -> f32 {
+ return (*(p)).x;
+}
+
+fn f1(p : ptr<private, mat3x4<f32>>) -> f32 {
+ var res : f32;
+ {
+ res += f0(&((*(p))[1]));
+ }
+ {
+ let p_vec = &((*(p))[1]);
+ res += f0(p_vec);
+ }
+ {
+ res += f0(&(P.arr[2].mat[1]));
+ }
+ {
+ let p_vec = &(P.arr[2].mat[1]);
+ res += f0(p_vec);
+ }
+ return res;
+}
+
+fn f2(p : ptr<private, Inner>) -> f32 {
+ let p_mat = &((*(p)).mat);
+ return f1(p_mat);
+}
+
+fn f3(p0 : ptr<private, InnerArr>, p1 : ptr<private, mat3x4<f32>>) -> f32 {
+ let p0_inner = &((*(p0))[3]);
+ return (f2(p0_inner) + f1(p1));
+}
+
+fn f4(p : ptr<private, Outer>) -> f32 {
+ return f3(&((*(p)).arr), &(P.mat));
+}
+
+fn b() {
+ f4(&(P));
+}
+)";
+
+ auto* expect = src;
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+} // namespace private_as_tests
+
+////////////////////////////////////////////////////////////////////////////////
+// 'function' address space
+////////////////////////////////////////////////////////////////////////////////
+namespace function_as_tests {
+
+using DirectVariableAccessFunctionASTest = TransformTest;
+
+TEST_F(DirectVariableAccessFunctionASTest, Enabled_LocalPtr) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+fn f() {
+ var v : i32;
+ let p : ptr<function, i32> = &(v);
+ var x : i32 = *(p);
+}
+)";
+
+ auto* expect = src; // Nothing changes
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessFunctionASTest, Enabled_Param_ptr_i32_read) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+fn a(pre : i32, p : ptr<function, i32>, post : i32) -> i32 {
+ return *(p);
+}
+
+fn b() {
+ var F : i32;
+ a(10, &(F), 20);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+fn a_F(pre : i32, p : ptr<function, i32>, post : i32) -> i32 {
+ return *(p);
+}
+
+fn b() {
+ var F : i32;
+ a_F(10, &(F), 20);
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src, EnableFunction());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessFunctionASTest, Enabled_Param_ptr_i32_write) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+fn a(pre : i32, p : ptr<function, i32>, post : i32) {
+ *(p) = 42;
+}
+
+fn b() {
+ var F : i32;
+ a(10, &(F), 20);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+fn a_F(pre : i32, p : ptr<function, i32>, post : i32) {
+ *(p) = 42;
+}
+
+fn b() {
+ var F : i32;
+ a_F(10, &(F), 20);
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src, EnableFunction());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessFunctionASTest, Enabled_Param_ptr_i32_Via_struct_read) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ i : i32,
+};
+
+fn a(pre : i32, p : ptr<function, i32>, post : i32) -> i32 {
+ return *p;
+}
+
+fn b() {
+ var F : str;
+ a(10, &F.i, 20);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ i : i32,
+}
+
+fn a_F_i(pre : i32, p : ptr<function, str>, post : i32) -> i32 {
+ return (*(p)).i;
+}
+
+fn b() {
+ var F : str;
+ a_F_i(10, &(F), 20);
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src, EnableFunction());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessFunctionASTest, Enabled_Param_ptr_arr_i32_Via_struct_write) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ arr : array<i32, 4>,
+};
+
+fn a(pre : i32, p : ptr<function, array<i32, 4>>, post : i32) {
+ *p = array<i32, 4>();
+}
+
+fn b() {
+ var F : str;
+ a(10, &F.arr, 20);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ arr : array<i32, 4>,
+}
+
+fn a_F_arr(pre : i32, p : ptr<function, str>, post : i32) {
+ (*(p)).arr = array<i32, 4>();
+}
+
+fn b() {
+ var F : str;
+ a_F_arr(10, &(F), 20);
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src, EnableFunction());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessFunctionASTest, Enabled_Param_ptr_i32_mixed) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ i : i32,
+};
+
+fn a(pre : i32, p : ptr<function, i32>, post : i32) -> i32 {
+ return *p;
+}
+
+fn b() {
+ var Fi : i32;
+ var Fs : str;
+ var Fa : array<i32, 4>;
+
+ a(10, &Fi, 20);
+ a(30, &Fs.i, 40);
+ a(50, &Fa[2], 60);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ i : i32,
+}
+
+fn a_F(pre : i32, p : ptr<function, i32>, post : i32) -> i32 {
+ return *(p);
+}
+
+fn a_F_i(pre : i32, p : ptr<function, str>, post : i32) -> i32 {
+ return (*(p)).i;
+}
+
+type F_X = array<u32, 1u>;
+
+fn a_F_X(pre : i32, p_base : ptr<function, array<i32, 4u>>, p_indices : F_X, post : i32) -> i32 {
+ return (*(p_base))[p_indices[0]];
+}
+
+type F_X_1 = array<u32, 1u>;
+
+fn b() {
+ var Fi : i32;
+ var Fs : str;
+ var Fa : array<i32, 4>;
+ a_F(10, &(Fi), 20);
+ a_F_i(30, &(Fs), 40);
+ a_F_X(50, &(Fa), F_X_1(2), 60);
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src, EnableFunction());
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessFunctionASTest, Disabled_Param_ptr_i32_Via_struct_read) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ i : i32,
+}
+
+fn a(pre : i32, p : ptr<function, i32>, post : i32) -> i32 {
+ return *(p);
+}
+
+fn b() {
+ var F : str;
+ a(10, &(F.i), 20);
+}
+)";
+
+ auto* expect = src;
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessFunctionASTest, Disabled_Param_ptr_arr_i32_Via_struct_write) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ arr : array<i32, 4>,
+}
+
+fn a(pre : i32, p : ptr<function, array<i32, 4>>, post : i32) {
+ *(p) = array<i32, 4>();
+}
+
+fn b() {
+ var F : str;
+ a(10, &(F.arr), 20);
+}
+)";
+
+ auto* expect = src;
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+} // namespace function_as_tests
+
+////////////////////////////////////////////////////////////////////////////////
+// complex tests
+////////////////////////////////////////////////////////////////////////////////
+namespace complex_tests {
+
+using DirectVariableAccessComplexTest = TransformTest;
+
+TEST_F(DirectVariableAccessComplexTest, Param_ptr_mixed_vec4i32_ViaMultiple) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ i : vec4<i32>,
+};
+
+@group(0) @binding(0) var<uniform> U : vec4<i32>;
+@group(0) @binding(1) var<uniform> U_str : str;
+@group(0) @binding(2) var<uniform> U_arr : array<vec4<i32>, 8>;
+@group(0) @binding(3) var<uniform> U_arr_arr : array<array<vec4<i32>, 8>, 4>;
+
+@group(1) @binding(0) var<storage> S : vec4<i32>;
+@group(1) @binding(1) var<storage> S_str : str;
+@group(1) @binding(2) var<storage> S_arr : array<vec4<i32>, 8>;
+@group(1) @binding(3) var<storage> S_arr_arr : array<array<vec4<i32>, 8>, 4>;
+
+ var<workgroup> W : vec4<i32>;
+ var<workgroup> W_str : str;
+ var<workgroup> W_arr : array<vec4<i32>, 8>;
+ var<workgroup> W_arr_arr : array<array<vec4<i32>, 8>, 4>;
+
+fn fn_u(p : ptr<uniform, vec4<i32>>) -> vec4<i32> {
+ return *p;
+}
+
+fn fn_s(p : ptr<storage, vec4<i32>>) -> vec4<i32> {
+ return *p;
+}
+
+fn fn_w(p : ptr<workgroup, vec4<i32>>) -> vec4<i32> {
+ return *p;
+}
+
+fn b() {
+ let I = 3;
+ let J = 4;
+
+ let u = fn_u(&U);
+ let u_str = fn_u(&U_str.i);
+ let u_arr0 = fn_u(&U_arr[0]);
+ let u_arr1 = fn_u(&U_arr[1]);
+ let u_arrI = fn_u(&U_arr[I]);
+ let u_arr1_arr0 = fn_u(&U_arr_arr[1][0]);
+ let u_arr2_arrI = fn_u(&U_arr_arr[2][I]);
+ let u_arrI_arr2 = fn_u(&U_arr_arr[I][2]);
+ let u_arrI_arrJ = fn_u(&U_arr_arr[I][J]);
+
+ let s = fn_s(&S);
+ let s_str = fn_s(&S_str.i);
+ let s_arr0 = fn_s(&S_arr[0]);
+ let s_arr1 = fn_s(&S_arr[1]);
+ let s_arrI = fn_s(&S_arr[I]);
+ let s_arr1_arr0 = fn_s(&S_arr_arr[1][0]);
+ let s_arr2_arrI = fn_s(&S_arr_arr[2][I]);
+ let s_arrI_arr2 = fn_s(&S_arr_arr[I][2]);
+ let s_arrI_arrJ = fn_s(&S_arr_arr[I][J]);
+
+ let w = fn_w(&W);
+ let w_str = fn_w(&W_str.i);
+ let w_arr0 = fn_w(&W_arr[0]);
+ let w_arr1 = fn_w(&W_arr[1]);
+ let w_arrI = fn_w(&W_arr[I]);
+ let w_arr1_arr0 = fn_w(&W_arr_arr[1][0]);
+ let w_arr2_arrI = fn_w(&W_arr_arr[2][I]);
+ let w_arrI_arr2 = fn_w(&W_arr_arr[I][2]);
+ let w_arrI_arrJ = fn_w(&W_arr_arr[I][J]);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+struct str {
+ i : vec4<i32>,
+}
+
+@group(0) @binding(0) var<uniform> U : vec4<i32>;
+
+@group(0) @binding(1) var<uniform> U_str : str;
+
+@group(0) @binding(2) var<uniform> U_arr : array<vec4<i32>, 8>;
+
+@group(0) @binding(3) var<uniform> U_arr_arr : array<array<vec4<i32>, 8>, 4>;
+
+@group(1) @binding(0) var<storage> S : vec4<i32>;
+
+@group(1) @binding(1) var<storage> S_str : str;
+
+@group(1) @binding(2) var<storage> S_arr : array<vec4<i32>, 8>;
+
+@group(1) @binding(3) var<storage> S_arr_arr : array<array<vec4<i32>, 8>, 4>;
+
+var<workgroup> W : vec4<i32>;
+
+var<workgroup> W_str : str;
+
+var<workgroup> W_arr : array<vec4<i32>, 8>;
+
+var<workgroup> W_arr_arr : array<array<vec4<i32>, 8>, 4>;
+
+fn fn_u_U() -> vec4<i32> {
+ return U;
+}
+
+fn fn_u_U_str_i() -> vec4<i32> {
+ return U_str.i;
+}
+
+type U_arr_X = array<u32, 1u>;
+
+fn fn_u_U_arr_X(p : U_arr_X) -> vec4<i32> {
+ return U_arr[p[0]];
+}
+
+type U_arr_arr_X_X = array<u32, 2u>;
+
+fn fn_u_U_arr_arr_X_X(p : U_arr_arr_X_X) -> vec4<i32> {
+ return U_arr_arr[p[0]][p[1]];
+}
+
+fn fn_s_S() -> vec4<i32> {
+ return S;
+}
+
+fn fn_s_S_str_i() -> vec4<i32> {
+ return S_str.i;
+}
+
+type S_arr_X = array<u32, 1u>;
+
+fn fn_s_S_arr_X(p : S_arr_X) -> vec4<i32> {
+ return S_arr[p[0]];
+}
+
+type S_arr_arr_X_X = array<u32, 2u>;
+
+fn fn_s_S_arr_arr_X_X(p : S_arr_arr_X_X) -> vec4<i32> {
+ return S_arr_arr[p[0]][p[1]];
+}
+
+fn fn_w_W() -> vec4<i32> {
+ return W;
+}
+
+fn fn_w_W_str_i() -> vec4<i32> {
+ return W_str.i;
+}
+
+type W_arr_X = array<u32, 1u>;
+
+fn fn_w_W_arr_X(p : W_arr_X) -> vec4<i32> {
+ return W_arr[p[0]];
+}
+
+type W_arr_arr_X_X = array<u32, 2u>;
+
+fn fn_w_W_arr_arr_X_X(p : W_arr_arr_X_X) -> vec4<i32> {
+ return W_arr_arr[p[0]][p[1]];
+}
+
+fn b() {
+ let I = 3;
+ let J = 4;
+ let u = fn_u_U();
+ let u_str = fn_u_U_str_i();
+ let u_arr0 = fn_u_U_arr_X(U_arr_X(0));
+ let u_arr1 = fn_u_U_arr_X(U_arr_X(1));
+ let u_arrI = fn_u_U_arr_X(U_arr_X(u32(I)));
+ let u_arr1_arr0 = fn_u_U_arr_arr_X_X(U_arr_arr_X_X(1, 0));
+ let u_arr2_arrI = fn_u_U_arr_arr_X_X(U_arr_arr_X_X(2, u32(I)));
+ let u_arrI_arr2 = fn_u_U_arr_arr_X_X(U_arr_arr_X_X(u32(I), 2));
+ let u_arrI_arrJ = fn_u_U_arr_arr_X_X(U_arr_arr_X_X(u32(I), u32(J)));
+ let s = fn_s_S();
+ let s_str = fn_s_S_str_i();
+ let s_arr0 = fn_s_S_arr_X(S_arr_X(0));
+ let s_arr1 = fn_s_S_arr_X(S_arr_X(1));
+ let s_arrI = fn_s_S_arr_X(S_arr_X(u32(I)));
+ let s_arr1_arr0 = fn_s_S_arr_arr_X_X(S_arr_arr_X_X(1, 0));
+ let s_arr2_arrI = fn_s_S_arr_arr_X_X(S_arr_arr_X_X(2, u32(I)));
+ let s_arrI_arr2 = fn_s_S_arr_arr_X_X(S_arr_arr_X_X(u32(I), 2));
+ let s_arrI_arrJ = fn_s_S_arr_arr_X_X(S_arr_arr_X_X(u32(I), u32(J)));
+ let w = fn_w_W();
+ let w_str = fn_w_W_str_i();
+ let w_arr0 = fn_w_W_arr_X(W_arr_X(0));
+ let w_arr1 = fn_w_W_arr_X(W_arr_X(1));
+ let w_arrI = fn_w_W_arr_X(W_arr_X(u32(I)));
+ let w_arr1_arr0 = fn_w_W_arr_arr_X_X(W_arr_arr_X_X(1, 0));
+ let w_arr2_arrI = fn_w_W_arr_arr_X_X(W_arr_arr_X_X(2, u32(I)));
+ let w_arrI_arr2 = fn_w_W_arr_arr_X_X(W_arr_arr_X_X(u32(I), 2));
+ let w_arrI_arrJ = fn_w_W_arr_arr_X_X(W_arr_arr_X_X(u32(I), u32(J)));
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessComplexTest, Indexing) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<storage> S : array<array<array<array<i32, 9>, 9>, 9>, 50>;
+
+fn a(i : i32) -> i32 { return i; }
+
+fn b(p : ptr<storage, array<array<array<i32, 9>, 9>, 9>>) -> i32 {
+ return (*p) [ a( (*p)[0][1][2] )]
+ [ a( (*p)[a(3)][4][5] )]
+ [ a( (*p)[6][a(7)][8] )];
+}
+
+fn c() {
+ let v = b(&S[42]);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<storage> S : array<array<array<array<i32, 9>, 9>, 9>, 50>;
+
+fn a(i : i32) -> i32 {
+ return i;
+}
+
+type S_X = array<u32, 1u>;
+
+fn b_S_X(p : S_X) -> i32 {
+ return S[p[0]][a(S[p[0]][0][1][2])][a(S[p[0]][a(3)][4][5])][a(S[p[0]][6][a(7)][8])];
+}
+
+fn c() {
+ let v = b_S_X(S_X(42));
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessComplexTest, IndexingInPtrCall) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<storage> S : array<array<array<array<i32, 9>, 9>, 9>, 50>;
+
+fn a(pre : i32, i : ptr<storage, i32>, post : i32) -> i32 {
+ return *i;
+}
+
+fn b(p : ptr<storage, array<array<array<i32, 9>, 9>, 9>>) -> i32 {
+ return a(10, &(*p)[ a( 20, &(*p)[0][1][2], 30 )]
+ [ a( 40, &(*p)[3][4][5], 50 )]
+ [ a( 60, &(*p)[6][7][8], 70 )], 80);
+}
+
+fn c() {
+ let v = b(&S[42]);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<storage> S : array<array<array<array<i32, 9>, 9>, 9>, 50>;
+
+type S_X_X_X_X = array<u32, 4u>;
+
+fn a_S_X_X_X_X(pre : i32, i : S_X_X_X_X, post : i32) -> i32 {
+ return S[i[0]][i[0]][i[1]][i[2]];
+}
+
+type S_X = array<u32, 1u>;
+
+fn b_S_X(p : S_X) -> i32 {
+ return a_S_X_X_X_X(10, S_X_X_X_X(p[0u], u32(a_S_X_X_X_X(20, S_X_X_X_X(p[0u], 0, 1, 2), 30)), u32(a_S_X_X_X_X(40, S_X_X_X_X(p[0u], 3, 4, 5), 50)), u32(a_S_X_X_X_X(60, S_X_X_X_X(p[0u], 6, 7, 8), 70))), 80);
+}
+
+fn c() {
+ let v = b_S_X(S_X(42));
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+TEST_F(DirectVariableAccessComplexTest, IndexingDualPointers) {
+ auto* src = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<storage> S : array<array<array<i32, 9>, 9>, 50>;
+@group(0) @binding(0) var<uniform> U : array<array<array<vec4<i32>, 9>, 9>, 50>;
+
+fn a(i : i32) -> i32 { return i; }
+
+fn b(s : ptr<storage, array<array<i32, 9>, 9>>,
+ u : ptr<uniform, array<array<vec4<i32>, 9>, 9>>) -> i32 {
+ return (*s) [ a( (*u)[0][1].x )]
+ [ a( (*u)[a(3)][4].y )];
+}
+
+fn c() {
+ let v = b(&S[42], &U[24]);
+}
+)";
+
+ auto* expect = R"(
+enable chromium_experimental_full_ptr_parameters;
+
+@group(0) @binding(0) var<storage> S : array<array<array<i32, 9>, 9>, 50>;
+
+@group(0) @binding(0) var<uniform> U : array<array<array<vec4<i32>, 9>, 9>, 50>;
+
+fn a(i : i32) -> i32 {
+ return i;
+}
+
+type S_X = array<u32, 1u>;
+
+type U_X = array<u32, 1u>;
+
+fn b_S_X_U_X(s : S_X, u : U_X) -> i32 {
+ return S[s[0]][a(U[u[0]][0][1].x)][a(U[u[0]][a(3)][4].y)];
+}
+
+fn c() {
+ let v = b_S_X_U_X(S_X(42), U_X(24));
+}
+)";
+
+ auto got = Run<DirectVariableAccess>(src);
+
+ EXPECT_EQ(expect, str(got));
+}
+
+} // namespace complex_tests
+
+} // namespace
+} // namespace tint::transform
diff --git a/src/tint/transform/module_scope_var_to_entry_point_param.cc b/src/tint/transform/module_scope_var_to_entry_point_param.cc
index 9c9c42f..9156205 100644
--- a/src/tint/transform/module_scope_var_to_entry_point_param.cc
+++ b/src/tint/transform/module_scope_var_to_entry_point_param.cc
@@ -146,7 +146,8 @@
attributes.Push(ctx.dst->Disable(ast::DisabledValidation::kIgnoreAddressSpace));
auto* param_type = store_type();
- if (auto* arr = ty->As<sem::Array>(); arr && arr->IsRuntimeSized()) {
+ if (auto* arr = ty->As<sem::Array>();
+ arr && arr->Count()->Is<sem::RuntimeArrayCount>()) {
// Wrap runtime-sized arrays in structures, so that we can declare pointers to
// them. Ideally we'd just emit the array itself as a pointer, but this is not
// representable in Tint's AST.
diff --git a/src/tint/transform/multiplanar_external_texture.cc b/src/tint/transform/multiplanar_external_texture.cc
index 0667ae9..63de1f4 100644
--- a/src/tint/transform/multiplanar_external_texture.cc
+++ b/src/tint/transform/multiplanar_external_texture.cc
@@ -258,10 +258,11 @@
utils::Vector ext_tex_params_member_list{
b.Member("numPlanes", b.ty.u32()),
b.Member("doYuvToRgbConversionOnly", b.ty.u32()),
- b.Member("yuvToRgbConversionMatrix", b.ty.mat3x4(b.ty.f32())),
+ b.Member("yuvToRgbConversionMatrix", b.ty.mat3x4<f32>()),
b.Member("gammaDecodeParams", b.ty.type_name("GammaTransferParams")),
b.Member("gammaEncodeParams", b.ty.type_name("GammaTransferParams")),
- b.Member("gamutConversionMatrix", b.ty.mat3x3(b.ty.f32()))};
+ b.Member("gamutConversionMatrix", b.ty.mat3x3<f32>()),
+ b.Member("rotationMatrix", b.ty.mat2x2<f32>())};
params_struct_sym = b.Symbols().New("ExternalTextureParams");
@@ -314,22 +315,27 @@
const ast::CallExpression* plane_1_call = nullptr;
switch (call_type) {
case sem::BuiltinType::kTextureSampleBaseClampToEdge:
+ stmts.Push(b.Decl(b.Let("modifiedCoords",
+ b.Add(b.Mul(b.Sub("coord", f32(0.5)),
+ b.MemberAccessor("params", "rotationMatrix")),
+ f32(0.5)))));
+
stmts.Push(b.Decl(b.Let(
"plane0_dims",
b.Construct(b.ty.vec2<f32>(), b.Call("textureDimensions", "plane0", 0_a)))));
stmts.Push(
b.Decl(b.Let("plane0_half_texel", b.Div(b.vec2<f32>(0.5_a), "plane0_dims"))));
- stmts.Push(
- b.Decl(b.Let("plane0_clamped", b.Call("clamp", "coord", "plane0_half_texel",
- b.Sub(1_a, "plane0_half_texel")))));
+ stmts.Push(b.Decl(
+ b.Let("plane0_clamped", b.Call("clamp", "modifiedCoords", "plane0_half_texel",
+ b.Sub(1_a, "plane0_half_texel")))));
stmts.Push(b.Decl(b.Let(
"plane1_dims",
b.Construct(b.ty.vec2<f32>(), b.Call("textureDimensions", "plane1", 0_a)))));
stmts.Push(
b.Decl(b.Let("plane1_half_texel", b.Div(b.vec2<f32>(0.5_a), "plane1_dims"))));
- stmts.Push(
- b.Decl(b.Let("plane1_clamped", b.Call("clamp", "coord", "plane1_half_texel",
- b.Sub(1_a, "plane1_half_texel")))));
+ stmts.Push(b.Decl(
+ b.Let("plane1_clamped", b.Call("clamp", "modifiedCoords", "plane1_half_texel",
+ b.Sub(1_a, "plane1_half_texel")))));
// textureSampleLevel(plane0, smp, plane0_clamped, 0.0);
single_plane_call =
diff --git a/src/tint/transform/multiplanar_external_texture_test.cc b/src/tint/transform/multiplanar_external_texture_test.cc
index dbfbc8d..b220447 100644
--- a/src/tint/transform/multiplanar_external_texture_test.cc
+++ b/src/tint/transform/multiplanar_external_texture_test.cc
@@ -138,6 +138,7 @@
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
gamutConversionMatrix : mat3x3<f32>,
+ rotationMatrix : mat2x2<f32>,
}
@group(0) @binding(1) var ext_tex_plane_1 : texture_2d<f32>;
@@ -193,6 +194,7 @@
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
gamutConversionMatrix : mat3x3<f32>,
+ rotationMatrix : mat2x2<f32>,
}
@group(0) @binding(1) var ext_tex_plane_1 : texture_2d<f32>;
@@ -247,6 +249,7 @@
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
gamutConversionMatrix : mat3x3<f32>,
+ rotationMatrix : mat2x2<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@@ -265,12 +268,13 @@
}
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
+ let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
- let plane0_clamped = clamp(coord, plane0_half_texel, (1 - plane0_half_texel));
+ let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
let plane1_dims = vec2<f32>(textureDimensions(plane1, 0));
let plane1_half_texel = (vec2<f32>(0.5) / plane1_dims);
- let plane1_clamped = clamp(coord, plane1_half_texel, (1 - plane1_half_texel));
+ let plane1_clamped = clamp(modifiedCoords, plane1_half_texel, (1 - plane1_half_texel));
var color : vec3<f32>;
if ((params.numPlanes == 1)) {
color = textureSampleLevel(plane0, smp, plane0_clamped, 0).rgb;
@@ -329,6 +333,7 @@
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
gamutConversionMatrix : mat3x3<f32>,
+ rotationMatrix : mat2x2<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@@ -343,12 +348,13 @@
}
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
+ let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
- let plane0_clamped = clamp(coord, plane0_half_texel, (1 - plane0_half_texel));
+ let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
let plane1_dims = vec2<f32>(textureDimensions(plane1, 0));
let plane1_half_texel = (vec2<f32>(0.5) / plane1_dims);
- let plane1_clamped = clamp(coord, plane1_half_texel, (1 - plane1_half_texel));
+ let plane1_clamped = clamp(modifiedCoords, plane1_half_texel, (1 - plane1_half_texel));
var color : vec3<f32>;
if ((params.numPlanes == 1)) {
color = textureSampleLevel(plane0, smp, plane0_clamped, 0).rgb;
@@ -412,6 +418,7 @@
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
gamutConversionMatrix : mat3x3<f32>,
+ rotationMatrix : mat2x2<f32>,
}
@group(0) @binding(1) var ext_tex_plane_1 : texture_2d<f32>;
@@ -504,6 +511,7 @@
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
gamutConversionMatrix : mat3x3<f32>,
+ rotationMatrix : mat2x2<f32>,
}
@group(0) @binding(1) var ext_tex_plane_1 : texture_2d<f32>;
@@ -595,6 +603,7 @@
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
gamutConversionMatrix : mat3x3<f32>,
+ rotationMatrix : mat2x2<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@@ -613,12 +622,13 @@
}
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
+ let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
- let plane0_clamped = clamp(coord, plane0_half_texel, (1 - plane0_half_texel));
+ let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
let plane1_dims = vec2<f32>(textureDimensions(plane1, 0));
let plane1_half_texel = (vec2<f32>(0.5) / plane1_dims);
- let plane1_clamped = clamp(coord, plane1_half_texel, (1 - plane1_half_texel));
+ let plane1_clamped = clamp(modifiedCoords, plane1_half_texel, (1 - plane1_half_texel));
var color : vec3<f32>;
if ((params.numPlanes == 1)) {
color = textureSampleLevel(plane0, smp, plane0_clamped, 0).rgb;
@@ -692,6 +702,7 @@
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
gamutConversionMatrix : mat3x3<f32>,
+ rotationMatrix : mat2x2<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@@ -706,12 +717,13 @@
}
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
+ let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
- let plane0_clamped = clamp(coord, plane0_half_texel, (1 - plane0_half_texel));
+ let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
let plane1_dims = vec2<f32>(textureDimensions(plane1, 0));
let plane1_half_texel = (vec2<f32>(0.5) / plane1_dims);
- let plane1_clamped = clamp(coord, plane1_half_texel, (1 - plane1_half_texel));
+ let plane1_clamped = clamp(modifiedCoords, plane1_half_texel, (1 - plane1_half_texel));
var color : vec3<f32>;
if ((params.numPlanes == 1)) {
color = textureSampleLevel(plane0, smp, plane0_clamped, 0).rgb;
@@ -795,6 +807,7 @@
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
gamutConversionMatrix : mat3x3<f32>,
+ rotationMatrix : mat2x2<f32>,
}
@group(0) @binding(4) var ext_tex_plane_1 : texture_2d<f32>;
@@ -831,12 +844,13 @@
}
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
+ let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
- let plane0_clamped = clamp(coord, plane0_half_texel, (1 - plane0_half_texel));
+ let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
let plane1_dims = vec2<f32>(textureDimensions(plane1, 0));
let plane1_half_texel = (vec2<f32>(0.5) / plane1_dims);
- let plane1_clamped = clamp(coord, plane1_half_texel, (1 - plane1_half_texel));
+ let plane1_clamped = clamp(modifiedCoords, plane1_half_texel, (1 - plane1_half_texel));
var color : vec3<f32>;
if ((params.numPlanes == 1)) {
color = textureSampleLevel(plane0, smp, plane0_clamped, 0).rgb;
@@ -904,6 +918,7 @@
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
gamutConversionMatrix : mat3x3<f32>,
+ rotationMatrix : mat2x2<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@@ -918,12 +933,13 @@
}
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
+ let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
- let plane0_clamped = clamp(coord, plane0_half_texel, (1 - plane0_half_texel));
+ let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
let plane1_dims = vec2<f32>(textureDimensions(plane1, 0));
let plane1_half_texel = (vec2<f32>(0.5) / plane1_dims);
- let plane1_clamped = clamp(coord, plane1_half_texel, (1 - plane1_half_texel));
+ let plane1_clamped = clamp(modifiedCoords, plane1_half_texel, (1 - plane1_half_texel));
var color : vec3<f32>;
if ((params.numPlanes == 1)) {
color = textureSampleLevel(plane0, smp, plane0_clamped, 0).rgb;
@@ -995,6 +1011,7 @@
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
gamutConversionMatrix : mat3x3<f32>,
+ rotationMatrix : mat2x2<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@@ -1014,12 +1031,13 @@
}
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
+ let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
- let plane0_clamped = clamp(coord, plane0_half_texel, (1 - plane0_half_texel));
+ let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
let plane1_dims = vec2<f32>(textureDimensions(plane1, 0));
let plane1_half_texel = (vec2<f32>(0.5) / plane1_dims);
- let plane1_clamped = clamp(coord, plane1_half_texel, (1 - plane1_half_texel));
+ let plane1_clamped = clamp(modifiedCoords, plane1_half_texel, (1 - plane1_half_texel));
var color : vec3<f32>;
if ((params.numPlanes == 1)) {
color = textureSampleLevel(plane0, smp, plane0_clamped, 0).rgb;
@@ -1086,6 +1104,7 @@
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
gamutConversionMatrix : mat3x3<f32>,
+ rotationMatrix : mat2x2<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@@ -1100,12 +1119,13 @@
}
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
+ let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
- let plane0_clamped = clamp(coord, plane0_half_texel, (1 - plane0_half_texel));
+ let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
let plane1_dims = vec2<f32>(textureDimensions(plane1, 0));
let plane1_half_texel = (vec2<f32>(0.5) / plane1_dims);
- let plane1_clamped = clamp(coord, plane1_half_texel, (1 - plane1_half_texel));
+ let plane1_clamped = clamp(modifiedCoords, plane1_half_texel, (1 - plane1_half_texel));
var color : vec3<f32>;
if ((params.numPlanes == 1)) {
color = textureSampleLevel(plane0, smp, plane0_clamped, 0).rgb;
@@ -1179,6 +1199,7 @@
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
gamutConversionMatrix : mat3x3<f32>,
+ rotationMatrix : mat2x2<f32>,
}
@group(0) @binding(3) var ext_tex_plane_1 : texture_2d<f32>;
@@ -1197,12 +1218,13 @@
}
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
+ let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
- let plane0_clamped = clamp(coord, plane0_half_texel, (1 - plane0_half_texel));
+ let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
let plane1_dims = vec2<f32>(textureDimensions(plane1, 0));
let plane1_half_texel = (vec2<f32>(0.5) / plane1_dims);
- let plane1_clamped = clamp(coord, plane1_half_texel, (1 - plane1_half_texel));
+ let plane1_clamped = clamp(modifiedCoords, plane1_half_texel, (1 - plane1_half_texel));
var color : vec3<f32>;
if ((params.numPlanes == 1)) {
color = textureSampleLevel(plane0, smp, plane0_clamped, 0).rgb;
@@ -1281,6 +1303,7 @@
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
gamutConversionMatrix : mat3x3<f32>,
+ rotationMatrix : mat2x2<f32>,
}
@group(0) @binding(3) var ext_tex_plane_1 : texture_2d<f32>;
@@ -1304,12 +1327,13 @@
}
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
+ let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
- let plane0_clamped = clamp(coord, plane0_half_texel, (1 - plane0_half_texel));
+ let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
let plane1_dims = vec2<f32>(textureDimensions(plane1, 0));
let plane1_half_texel = (vec2<f32>(0.5) / plane1_dims);
- let plane1_clamped = clamp(coord, plane1_half_texel, (1 - plane1_half_texel));
+ let plane1_clamped = clamp(modifiedCoords, plane1_half_texel, (1 - plane1_half_texel));
var color : vec3<f32>;
if ((params.numPlanes == 1)) {
color = textureSampleLevel(plane0, smp, plane0_clamped, 0).rgb;
@@ -1384,6 +1408,7 @@
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
gamutConversionMatrix : mat3x3<f32>,
+ rotationMatrix : mat2x2<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@@ -1398,12 +1423,13 @@
}
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
+ let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
- let plane0_clamped = clamp(coord, plane0_half_texel, (1 - plane0_half_texel));
+ let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
let plane1_dims = vec2<f32>(textureDimensions(plane1, 0));
let plane1_half_texel = (vec2<f32>(0.5) / plane1_dims);
- let plane1_clamped = clamp(coord, plane1_half_texel, (1 - plane1_half_texel));
+ let plane1_clamped = clamp(modifiedCoords, plane1_half_texel, (1 - plane1_half_texel));
var color : vec3<f32>;
if ((params.numPlanes == 1)) {
color = textureSampleLevel(plane0, smp, plane0_clamped, 0).rgb;
@@ -1483,6 +1509,7 @@
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
gamutConversionMatrix : mat3x3<f32>,
+ rotationMatrix : mat2x2<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@@ -1497,12 +1524,13 @@
}
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
+ let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
- let plane0_clamped = clamp(coord, plane0_half_texel, (1 - plane0_half_texel));
+ let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
let plane1_dims = vec2<f32>(textureDimensions(plane1, 0));
let plane1_half_texel = (vec2<f32>(0.5) / plane1_dims);
- let plane1_clamped = clamp(coord, plane1_half_texel, (1 - plane1_half_texel));
+ let plane1_clamped = clamp(modifiedCoords, plane1_half_texel, (1 - plane1_half_texel));
var color : vec3<f32>;
if ((params.numPlanes == 1)) {
color = textureSampleLevel(plane0, smp, plane0_clamped, 0).rgb;
@@ -1570,6 +1598,7 @@
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
gamutConversionMatrix : mat3x3<f32>,
+ rotationMatrix : mat2x2<f32>,
}
fn f(ext_tex : texture_2d<f32>, ext_tex_plane_1 : texture_2d<f32>, ext_tex_params : ExternalTextureParams) -> vec2<u32> {
@@ -1621,6 +1650,7 @@
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
gamutConversionMatrix : mat3x3<f32>,
+ rotationMatrix : mat2x2<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@@ -1637,12 +1667,13 @@
}
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
+ let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
- let plane0_clamped = clamp(coord, plane0_half_texel, (1 - plane0_half_texel));
+ let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
let plane1_dims = vec2<f32>(textureDimensions(plane1, 0));
let plane1_half_texel = (vec2<f32>(0.5) / plane1_dims);
- let plane1_clamped = clamp(coord, plane1_half_texel, (1 - plane1_half_texel));
+ let plane1_clamped = clamp(modifiedCoords, plane1_half_texel, (1 - plane1_half_texel));
var color : vec3<f32>;
if ((params.numPlanes == 1)) {
color = textureSampleLevel(plane0, smp, plane0_clamped, 0).rgb;
@@ -1715,6 +1746,7 @@
gammaDecodeParams : GammaTransferParams,
gammaEncodeParams : GammaTransferParams,
gamutConversionMatrix : mat3x3<f32>,
+ rotationMatrix : mat2x2<f32>,
}
@group(0) @binding(2) var ext_tex_plane_1 : texture_2d<f32>;
@@ -1734,12 +1766,13 @@
}
fn textureSampleExternal(plane0 : texture_2d<f32>, plane1 : texture_2d<f32>, smp : sampler, coord : vec2<f32>, params : ExternalTextureParams) -> vec4<f32> {
+ let modifiedCoords = (((coord - 0.5f) * params.rotationMatrix) + 0.5f);
let plane0_dims = vec2<f32>(textureDimensions(plane0, 0));
let plane0_half_texel = (vec2<f32>(0.5) / plane0_dims);
- let plane0_clamped = clamp(coord, plane0_half_texel, (1 - plane0_half_texel));
+ let plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1 - plane0_half_texel));
let plane1_dims = vec2<f32>(textureDimensions(plane1, 0));
let plane1_half_texel = (vec2<f32>(0.5) / plane1_dims);
- let plane1_clamped = clamp(coord, plane1_half_texel, (1 - plane1_half_texel));
+ let plane1_clamped = clamp(modifiedCoords, plane1_half_texel, (1 - plane1_half_texel));
var color : vec3<f32>;
if ((params.numPlanes == 1)) {
color = textureSampleLevel(plane0, smp, plane0_clamped, 0).rgb;
diff --git a/src/tint/transform/num_workgroups_from_uniform.cc b/src/tint/transform/num_workgroups_from_uniform.cc
index e6681ca..b6c93b2 100644
--- a/src/tint/transform/num_workgroups_from_uniform.cc
+++ b/src/tint/transform/num_workgroups_from_uniform.cc
@@ -107,7 +107,7 @@
// Capture the symbols that would be used to access this member, which
// we will replace later. We currently have no way to get from the
// parameter directly to the member accessor expressions that use it.
- to_replace.insert({param->Declaration()->symbol, member->Declaration()->symbol});
+ to_replace.insert({param->Declaration()->symbol, member->Name()});
// Remove the struct member.
// The CanonicalizeEntryPointIO transform will have generated this
diff --git a/src/tint/transform/packed_vec3.cc b/src/tint/transform/packed_vec3.cc
index e947a53..f4ceb76 100644
--- a/src/tint/transform/packed_vec3.cc
+++ b/src/tint/transform/packed_vec3.cc
@@ -57,7 +57,7 @@
// Apply the PackedVec3::Attribute to the member
auto* member_decl = member->Declaration();
- auto name = ctx.Clone(member_decl->symbol);
+ auto name = ctx.Clone(member->Name());
auto* type = ctx.Clone(member_decl->type);
utils::Vector<const ast::Attribute*, 4> attrs{
b.ASTNodes().Create<Attribute>(b.ID(), b.AllocateNodeID()),
diff --git a/src/tint/transform/pad_structs.cc b/src/tint/transform/pad_structs.cc
index 4ceb39d..e8c21a7 100644
--- a/src/tint/transform/pad_structs.cc
+++ b/src/tint/transform/pad_structs.cc
@@ -84,7 +84,7 @@
// std140 structs should be padded out to 16 bytes.
size = utils::RoundUp(16u, size);
} else if (auto* array_ty = ty->As<sem::Array>()) {
- if (array_ty->IsRuntimeSized()) {
+ if (array_ty->Count()->Is<sem::RuntimeArrayCount>()) {
has_runtime_sized_array = true;
}
}
diff --git a/src/tint/transform/robustness.cc b/src/tint/transform/robustness.cc
index 75d63f2..c9f6292 100644
--- a/src/tint/transform/robustness.cc
+++ b/src/tint/transform/robustness.cc
@@ -106,7 +106,7 @@
},
[&](const sem::Array* arr) -> const ast::Expression* {
const ast::Expression* max = nullptr;
- if (arr->IsRuntimeSized()) {
+ if (arr->Count()->Is<sem::RuntimeArrayCount>()) {
// Size is unknown until runtime.
// Must clamp, even if the index is constant.
auto* arr_ptr = b.AddressOf(ctx.Clone(expr->object));
diff --git a/src/tint/transform/single_entry_point.cc b/src/tint/transform/single_entry_point.cc
index 386631e..694cd2d 100644
--- a/src/tint/transform/single_entry_point.cc
+++ b/src/tint/transform/single_entry_point.cc
@@ -71,9 +71,12 @@
[&](const ast::TypeDecl* ty) {
// Strip aliases that reference unused override declarations.
if (auto* arr = sem.Get(ty)->As<sem::Array>()) {
- for (auto* o : arr->TransitivelyReferencedOverrides()) {
- if (!referenced_vars.Contains(o)) {
- return;
+ auto* refs = sem.TransitivelyReferencedOverrides(arr);
+ if (refs) {
+ for (auto* o : *refs) {
+ if (!referenced_vars.Contains(o)) {
+ return;
+ }
}
}
}
diff --git a/src/tint/transform/spirv_atomic.cc b/src/tint/transform/spirv_atomic.cc
index 319975a..de3cdab 100644
--- a/src/tint/transform/spirv_atomic.cc
+++ b/src/tint/transform/spirv_atomic.cc
@@ -202,7 +202,7 @@
[&](const sem::U32*) { return b.ty.atomic(CreateASTTypeFor(ctx, ty)); },
[&](const sem::Struct* str) { return b.ty.type_name(Fork(str->Declaration()).name); },
[&](const sem::Array* arr) -> const ast::Type* {
- if (arr->IsRuntimeSized()) {
+ if (arr->Count()->Is<sem::RuntimeArrayCount>()) {
return b.ty.array(AtomicTypeFor(arr->ElemType()));
}
auto count = arr->ConstantCount();
diff --git a/src/tint/transform/transform.cc b/src/tint/transform/transform.cc
index 5c8357c..cbfb90a 100644
--- a/src/tint/transform/transform.cc
+++ b/src/tint/transform/transform.cc
@@ -106,14 +106,14 @@
if (!a->IsStrideImplicit()) {
attrs.Push(ctx.dst->create<ast::StrideAttribute>(a->Stride()));
}
- if (a->IsRuntimeSized()) {
+ if (a->Count()->Is<sem::RuntimeArrayCount>()) {
return ctx.dst->ty.array(el, nullptr, std::move(attrs));
}
- if (auto* override = std::get_if<sem::NamedOverrideArrayCount>(&a->Count())) {
+ if (auto* override = a->Count()->As<sem::NamedOverrideArrayCount>()) {
auto* count = ctx.Clone(override->variable->Declaration());
return ctx.dst->ty.array(el, count, std::move(attrs));
}
- if (auto* override = std::get_if<sem::UnnamedOverrideArrayCount>(&a->Count())) {
+ if (auto* override = a->Count()->As<sem::UnnamedOverrideArrayCount>()) {
// If the array count is an unnamed (complex) override expression, then its not safe to
// redeclare this type as we'd end up with two types that would not compare equal.
// See crbug.com/tint/1764.
diff --git a/src/tint/transform/transform_test.cc b/src/tint/transform/transform_test.cc
index 4b8ad53..29a21e1 100644
--- a/src/tint/transform/transform_test.cc
+++ b/src/tint/transform/transform_test.cc
@@ -69,8 +69,8 @@
TEST_F(CreateASTTypeForTest, ArrayImplicitStride) {
auto* arr = create([](ProgramBuilder& b) {
- return b.create<sem::Array>(b.create<sem::F32>(), sem::ConstantArrayCount{2u}, 4u, 4u, 32u,
- 32u);
+ return b.create<sem::Array>(b.create<sem::F32>(), b.create<sem::ConstantArrayCount>(2u), 4u,
+ 4u, 32u, 32u);
});
ASSERT_TRUE(arr->Is<ast::Array>());
ASSERT_TRUE(arr->As<ast::Array>()->type->Is<ast::F32>());
@@ -83,8 +83,8 @@
TEST_F(CreateASTTypeForTest, ArrayNonImplicitStride) {
auto* arr = create([](ProgramBuilder& b) {
- return b.create<sem::Array>(b.create<sem::F32>(), sem::ConstantArrayCount{2u}, 4u, 4u, 64u,
- 32u);
+ return b.create<sem::Array>(b.create<sem::F32>(), b.create<sem::ConstantArrayCount>(2u), 4u,
+ 4u, 64u, 32u);
});
ASSERT_TRUE(arr->Is<ast::Array>());
ASSERT_TRUE(arr->As<ast::Array>()->type->Is<ast::F32>());
@@ -122,8 +122,8 @@
TEST_F(CreateASTTypeForTest, Struct) {
auto* str = create([](ProgramBuilder& b) {
auto* decl = b.Structure("S", {});
- return b.create<sem::Struct>(decl, decl->name, sem::StructMemberList{}, 4u /* align */,
- 4u /* size */, 4u /* size_no_padding */);
+ return b.create<sem::Struct>(decl, decl->source, decl->name, sem::StructMemberList{},
+ 4u /* align */, 4u /* size */, 4u /* size_no_padding */);
});
ASSERT_TRUE(str->Is<ast::TypeName>());
EXPECT_EQ(ast_type_builder.Symbols().NameFor(str->As<ast::TypeName>()->name), "S");
diff --git a/src/tint/transform/truncate_interstage_variables.cc b/src/tint/transform/truncate_interstage_variables.cc
index 30237bc..bbb27fd 100644
--- a/src/tint/transform/truncate_interstage_variables.cc
+++ b/src/tint/transform/truncate_interstage_variables.cc
@@ -131,8 +131,7 @@
}
truncated_members.Push(ctx.Clone(member->Declaration()));
- initializer_exprs.Push(
- b.MemberAccessor("io", ctx.Clone(member->Declaration()->symbol)));
+ initializer_exprs.Push(b.MemberAccessor("io", ctx.Clone(member->Name())));
}
// Create the new shader io struct.
diff --git a/src/tint/transform/unshadow.h b/src/tint/transform/unshadow.h
index 8ebf105..9030006 100644
--- a/src/tint/transform/unshadow.h
+++ b/src/tint/transform/unshadow.h
@@ -19,8 +19,7 @@
namespace tint::transform {
-/// Unshadow is a Transform that renames any variables that shadow another
-/// variable.
+/// Unshadow is a Transform that renames any variables that shadow another variable.
class Unshadow final : public Castable<Unshadow, Transform> {
public:
/// Constructor
diff --git a/src/tint/utils/block_allocator.h b/src/tint/utils/block_allocator.h
index 91a8a53..e75a0c6 100644
--- a/src/tint/utils/block_allocator.h
+++ b/src/tint/utils/block_allocator.h
@@ -39,6 +39,7 @@
static constexpr size_t kMax = 32;
std::array<T*, kMax> ptrs;
Pointers* next;
+ Pointers* prev;
};
/// Block is linked list of memory blocks.
@@ -55,7 +56,7 @@
class TView;
/// An iterator for the objects owned by the BlockAllocator.
- template <bool IS_CONST>
+ template <bool IS_CONST, bool FORWARD>
class TIterator {
using PointerTy = std::conditional_t<IS_CONST, const T*, T*>;
@@ -72,15 +73,24 @@
/// @returns true if this iterator is not equal to other
bool operator!=(const TIterator& other) const { return !(*this == other); }
- /// Advances the iterator
+ /// Progress the iterator forward one element
/// @returns this iterator
TIterator& operator++() {
- if (ptrs != nullptr) {
- ++idx;
- if (idx == Pointers::kMax) {
- idx = 0;
- ptrs = ptrs->next;
- }
+ if (FORWARD) {
+ ProgressForward();
+ } else {
+ ProgressBackwards();
+ }
+ return *this;
+ }
+
+ /// Progress the iterator backwards one element
+ /// @returns this iterator
+ TIterator& operator--() {
+ if (FORWARD) {
+ ProgressBackwards();
+ } else {
+ ProgressForward();
}
return *this;
}
@@ -92,6 +102,27 @@
friend TView<IS_CONST>; // Keep internal iterator impl private.
explicit TIterator(const Pointers* p, size_t i) : ptrs(p), idx(i) {}
+ /// Progresses the iterator forwards
+ void ProgressForward() {
+ if (ptrs != nullptr) {
+ ++idx;
+ if (idx == Pointers::kMax) {
+ idx = 0;
+ ptrs = ptrs->next;
+ }
+ }
+ }
+ /// Progresses the iterator backwards
+ void ProgressBackwards() {
+ if (ptrs != nullptr) {
+ if (idx == 0) {
+ idx = Pointers::kMax - 1;
+ ptrs = ptrs->prev;
+ }
+ --idx;
+ }
+ }
+
const Pointers* ptrs;
size_t idx;
};
@@ -102,16 +133,25 @@
class TView {
public:
/// @returns an iterator to the beginning of the view
- TIterator<IS_CONST> begin() const {
- return TIterator<IS_CONST>{allocator_->data.pointers.root, 0};
+ TIterator<IS_CONST, true> begin() const {
+ return TIterator<IS_CONST, true>{allocator_->data.pointers.root, 0};
}
/// @returns an iterator to the end of the view
- TIterator<IS_CONST> end() const {
+ TIterator<IS_CONST, true> end() const {
return allocator_->data.pointers.current_index >= Pointers::kMax
- ? TIterator<IS_CONST>(nullptr, 0)
- : TIterator<IS_CONST>(allocator_->data.pointers.current,
- allocator_->data.pointers.current_index);
+ ? TIterator<IS_CONST, true>{nullptr, 0}
+ : TIterator<IS_CONST, true>{allocator_->data.pointers.current,
+ allocator_->data.pointers.current_index};
+ }
+
+ /// @returns an iterator to the beginning of the view
+ TIterator<IS_CONST, false> rbegin() const { return TIterator<IS_CONST, false>{nullptr, 0}; }
+
+ /// @returns an iterator to the end of the view
+ TIterator<IS_CONST, false> rend() const {
+ return TIterator<IS_CONST, false>{allocator_->data.pointers.current,
+ allocator_->data.pointers.current_index};
}
private:
@@ -121,11 +161,17 @@
};
public:
- /// An iterator type over the objects of the BlockAllocator
- using Iterator = TIterator<false>;
+ /// A forward-iterator type over the objects of the BlockAllocator
+ using Iterator = TIterator</* const */ false, /* forward */ true>;
- /// An immutable iterator type over the objects of the BlockAllocator
- using ConstIterator = TIterator<true>;
+ /// An immutable forward-iterator type over the objects of the BlockAllocator
+ using ConstIterator = TIterator</* const */ true, /* forward */ true>;
+
+ /// A reverse-iterator type over the objects of the BlockAllocator
+ using ReverseIterator = TIterator</* const */ false, /* forward */ false>;
+
+ /// An immutable reverse-iterator type over the objects of the BlockAllocator
+ using ReverseConstIterator = TIterator</* const */ true, /* forward */ false>;
/// View provides begin() and end() methods for looping over the objects owned by the
/// BlockAllocator.
@@ -248,6 +294,7 @@
return; // out of memory
}
pointers.current->next = nullptr;
+ pointers.current->prev = prev_pointers;
pointers.current_index = 0;
if (prev_pointers) {
diff --git a/src/tint/utils/unique_allocator.h b/src/tint/utils/unique_allocator.h
index 1297701..7ba5909 100644
--- a/src/tint/utils/unique_allocator.h
+++ b/src/tint/utils/unique_allocator.h
@@ -28,6 +28,9 @@
template <typename T, typename HASH = std::hash<T>, typename EQUAL = std::equal_to<T>>
class UniqueAllocator {
public:
+ /// Iterator is the type returned by begin() and end()
+ using Iterator = typename BlockAllocator<T>::ConstIterator;
+
/// @param args the arguments used to construct the object.
/// @return a pointer to an instance of `T` with the provided arguments.
/// If an existing instance of `T` has been constructed, then the same
@@ -49,7 +52,36 @@
return ptr;
}
- protected:
+ /// @param args the arguments used to create the temporary used for the search.
+ /// @return a pointer to an instance of `T` with the provided arguments, or nullptr if the item
+ /// was not found.
+ template <typename TYPE = T, typename... ARGS>
+ TYPE* Find(ARGS&&... args) const {
+ // Create a temporary T instance on the stack so that we can hash it, and
+ // use it for equality lookup for the std::unordered_set.
+ TYPE key{args...};
+ auto hash = Hasher{}(key);
+ auto it = items.find(Entry{hash, &key});
+ if (it != items.end()) {
+ return static_cast<TYPE*>(it->ptr);
+ }
+ return nullptr;
+ }
+
+ /// Wrap sets this allocator to the objects created with the content of `inner`.
+ /// The allocator after Wrap is intended to temporarily extend the objects
+ /// of an existing immutable UniqueAllocator.
+ /// As the copied objects are owned by `inner`, `inner` must not be destructed
+ /// or assigned while using this allocator.
+ /// @param o the immutable UniqueAlllocator to extend
+ void Wrap(const UniqueAllocator<T, HASH, EQUAL>& o) { items = o.items; }
+
+ /// @returns an iterator to the beginning of the types
+ Iterator begin() const { return allocator.Objects().begin(); }
+ /// @returns an iterator to the end of the types
+ Iterator end() const { return allocator.Objects().end(); }
+
+ private:
/// The hash function
using Hasher = HASH;
/// The equality function
@@ -59,7 +91,7 @@
struct Entry {
/// The pre-calculated hash of the entry
size_t hash;
- /// Tge pointer to the unique object
+ /// The pointer to the unique object
T* ptr;
};
/// Comparator is the hashing and equality function used by the unordered_set
diff --git a/src/tint/writer/glsl/generator_impl.cc b/src/tint/writer/glsl/generator_impl.cc
index 86ba657..c9ca429 100644
--- a/src/tint/writer/glsl/generator_impl.cc
+++ b/src/tint/writer/glsl/generator_impl.cc
@@ -54,6 +54,7 @@
#include "src/tint/transform/combine_samplers.h"
#include "src/tint/transform/decompose_memory_access.h"
#include "src/tint/transform/demote_to_helper.h"
+#include "src/tint/transform/direct_variable_access.h"
#include "src/tint/transform/disable_uniformity_analysis.h"
#include "src/tint/transform/expand_compound_assignment.h"
#include "src/tint/transform/manager.h"
@@ -209,7 +210,8 @@
manager.Add<transform::Renamer>();
data.Add<transform::Renamer::Config>(transform::Renamer::Target::kGlslKeywords,
/* preserve_unicode */ false);
- manager.Add<transform::Unshadow>();
+ manager.Add<transform::Unshadow>(); // Must come before DirectVariableAccess
+ manager.Add<transform::DirectVariableAccess>();
if (!options.disable_workgroup_init) {
// ZeroInitWorkgroupMemory must come before CanonicalizeEntryPointIO as
@@ -290,7 +292,7 @@
auto* sem = builder_.Sem().Get(str);
bool has_rt_arr = false;
if (auto* arr = sem->Members().back()->Type()->As<sem::Array>()) {
- has_rt_arr = arr->IsRuntimeSized();
+ has_rt_arr = arr->Count()->Is<sem::RuntimeArrayCount>();
}
bool is_block =
ast::HasAttribute<transform::AddBlockAttribute::BlockAttribute>(str->attributes);
@@ -2832,7 +2834,7 @@
const sem::Type* base_type = ary;
std::vector<uint32_t> sizes;
while (auto* arr = base_type->As<sem::Array>()) {
- if (arr->IsRuntimeSized()) {
+ if (arr->Count()->Is<sem::RuntimeArrayCount>()) {
sizes.push_back(0);
} else {
auto count = arr->ConstantCount();
diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc
index 1e786da..0c3856a 100644
--- a/src/tint/writer/hlsl/generator_impl.cc
+++ b/src/tint/writer/hlsl/generator_impl.cc
@@ -54,6 +54,7 @@
#include "src/tint/transform/canonicalize_entry_point_io.h"
#include "src/tint/transform/decompose_memory_access.h"
#include "src/tint/transform/demote_to_helper.h"
+#include "src/tint/transform/direct_variable_access.h"
#include "src/tint/transform/disable_uniformity_analysis.h"
#include "src/tint/transform/expand_compound_assignment.h"
#include "src/tint/transform/localize_struct_array_assignment.h"
@@ -194,7 +195,9 @@
}
manager.Add<transform::MultiplanarExternalTexture>();
- manager.Add<transform::Unshadow>();
+ manager.Add<transform::Unshadow>(); // Must come before DirectVariableAccess
+
+ manager.Add<transform::DirectVariableAccess>();
// LocalizeStructArrayAssignment must come after:
// * SimplifyPointers, because it assumes assignment to arrays in structs are
@@ -291,6 +294,7 @@
utils::Vector{
ast::Extension::kChromiumDisableUniformityAnalysis,
ast::Extension::kChromiumExperimentalDp4A,
+ ast::Extension::kChromiumExperimentalFullPtrParameters,
ast::Extension::kChromiumExperimentalPushConstant,
ast::Extension::kF16,
})) {
@@ -3920,7 +3924,7 @@
const sem::Type* base_type = ary;
std::vector<uint32_t> sizes;
while (auto* arr = base_type->As<sem::Array>()) {
- if (arr->IsRuntimeSized()) {
+ if (arr->Count()->Is<sem::RuntimeArrayCount>()) {
TINT_ICE(Writer, diagnostics_)
<< "runtime arrays may only exist in storage buffers, which should have "
"been transformed into a ByteAddressBuffer";
diff --git a/src/tint/writer/msl/generator_impl.cc b/src/tint/writer/msl/generator_impl.cc
index 10efd59..c7354f0 100644
--- a/src/tint/writer/msl/generator_impl.cc
+++ b/src/tint/writer/msl/generator_impl.cc
@@ -266,6 +266,7 @@
if (!CheckSupportedExtensions("MSL", program_->AST(), diagnostics_,
utils::Vector{
ast::Extension::kChromiumDisableUniformityAnalysis,
+ ast::Extension::kChromiumExperimentalFullPtrParameters,
ast::Extension::kChromiumExperimentalPushConstant,
ast::Extension::kF16,
})) {
@@ -2536,7 +2537,7 @@
return false;
}
out << ", ";
- if (arr->IsRuntimeSized()) {
+ if (arr->Count()->Is<sem::RuntimeArrayCount>()) {
out << "1";
} else {
auto count = arr->ConstantCount();
@@ -3164,7 +3165,7 @@
<< "arrays with explicit strides should not exist past the SPIR-V reader";
return SizeAndAlign{};
}
- if (arr->IsRuntimeSized()) {
+ if (arr->Count()->Is<sem::RuntimeArrayCount>()) {
return SizeAndAlign{arr->Stride(), arr->Align()};
}
if (auto count = arr->ConstantCount()) {
diff --git a/src/tint/writer/spirv/builder.cc b/src/tint/writer/spirv/builder.cc
index c5e4a38..f2b8f85 100644
--- a/src/tint/writer/spirv/builder.cc
+++ b/src/tint/writer/spirv/builder.cc
@@ -260,6 +260,7 @@
utils::Vector{
ast::Extension::kChromiumDisableUniformityAnalysis,
ast::Extension::kChromiumExperimentalDp4A,
+ ast::Extension::kChromiumExperimentalFullPtrParameters,
ast::Extension::kChromiumExperimentalPushConstant,
ast::Extension::kF16,
})) {
@@ -3838,7 +3839,7 @@
}
auto result_id = std::get<uint32_t>(result);
- if (arr->IsRuntimeSized()) {
+ if (arr->Count()->Is<sem::RuntimeArrayCount>()) {
push_type(spv::Op::OpTypeRuntimeArray, {result, Operand(elem_type)});
} else {
auto count = arr->ConstantCount();
diff --git a/src/tint/writer/spirv/generator_impl.cc b/src/tint/writer/spirv/generator_impl.cc
index 18c7511..b6bb0ff 100644
--- a/src/tint/writer/spirv/generator_impl.cc
+++ b/src/tint/writer/spirv/generator_impl.cc
@@ -22,6 +22,7 @@
#include "src/tint/transform/builtin_polyfill.h"
#include "src/tint/transform/canonicalize_entry_point_io.h"
#include "src/tint/transform/demote_to_helper.h"
+#include "src/tint/transform/direct_variable_access.h"
#include "src/tint/transform/disable_uniformity_analysis.h"
#include "src/tint/transform/expand_compound_assignment.h"
#include "src/tint/transform/for_loop_to_loop.h"
@@ -77,12 +78,21 @@
}
manager.Add<transform::MultiplanarExternalTexture>();
- manager.Add<transform::Unshadow>();
+ manager.Add<transform::Unshadow>(); // Must come before DirectVariableAccess
bool disable_workgroup_init_in_sanitizer =
options.disable_workgroup_init || options.use_zero_initialize_workgroup_memory_extension;
if (!disable_workgroup_init_in_sanitizer) {
manager.Add<transform::ZeroInitWorkgroupMemory>();
}
+
+ {
+ transform::DirectVariableAccess::Options opts;
+ opts.transform_private = true;
+ opts.transform_function = true;
+ data.Add<transform::DirectVariableAccess::Config>(opts);
+ manager.Add<transform::DirectVariableAccess>();
+ }
+
manager.Add<transform::RemoveUnreachableStatements>();
manager.Add<transform::PromoteSideEffectsToDecl>();
manager.Add<transform::SimplifyPointers>(); // Required for arrayLength()
diff --git a/src/tint/writer/wgsl/generator_impl.cc b/src/tint/writer/wgsl/generator_impl.cc
index 6327c6c..cfd512b 100644
--- a/src/tint/writer/wgsl/generator_impl.cc
+++ b/src/tint/writer/wgsl/generator_impl.cc
@@ -606,8 +606,8 @@
increment_indent();
uint32_t offset = 0;
for (auto* mem : str->members) {
- // TODO(crbug.com/tint/798) move the @offset attribute handling to the
- // transform::Wgsl sanitizer.
+ // TODO(crbug.com/tint/798) move the @offset attribute handling to the transform::Wgsl
+ // sanitizer.
if (auto* mem_sem = program_->Sem().Get(mem)) {
offset = utils::RoundUp(mem_sem->Align(), offset);
if (uint32_t padding = mem_sem->Offset() - offset) {
@@ -623,7 +623,14 @@
utils::Vector<const ast::Attribute*, 4> attributes_sanitized;
attributes_sanitized.Reserve(mem->attributes.Length());
for (auto* attr : mem->attributes) {
- if (!attr->Is<ast::StructMemberOffsetAttribute>()) {
+ if (attr->Is<ast::StructMemberOffsetAttribute>()) {
+ auto l = line();
+ l << "/* ";
+ if (!EmitAttributes(l, utils::Vector{attr})) {
+ return false;
+ }
+ l << " */";
+ } else {
attributes_sanitized.Push(attr);
}
}
@@ -792,6 +799,14 @@
out << ")";
return true;
},
+ [&](const ast::StructMemberOffsetAttribute* offset) {
+ out << "offset(";
+ if (!EmitExpression(out, offset->expr)) {
+ return false;
+ }
+ out << ")";
+ return true;
+ },
[&](const ast::StructMemberSizeAttribute* size) {
out << "size(";
if (!EmitExpression(out, size->expr)) {
diff --git a/src/tint/writer/wgsl/generator_impl_type_test.cc b/src/tint/writer/wgsl/generator_impl_type_test.cc
index 13c8411..50bc7df 100644
--- a/src/tint/writer/wgsl/generator_impl_type_test.cc
+++ b/src/tint/writer/wgsl/generator_impl_type_test.cc
@@ -188,9 +188,11 @@
EXPECT_EQ(gen.result(), R"(struct S {
@size(8)
padding : u32,
+ /* @offset(8) */
a : i32,
@size(4)
padding_1 : u32,
+ /* @offset(16) */
b : f32,
}
)");
@@ -209,9 +211,11 @@
EXPECT_EQ(gen.result(), R"(struct S {
@size(8)
padding : u32,
+ /* @offset(8) */
tint_0_padding : i32,
@size(4)
padding_1 : u32,
+ /* @offset(16) */
tint_2_padding : f32,
}
)");