Add helpers for referenced variables.
This CL adds a helper to get referenced builtins and referenced
locations from the ast::Function.
Change-Id: I95cf7efd6b0fe9569c5e514d3245112e78147ffe
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/24783
Reviewed-by: David Neto <dneto@google.com>
diff --git a/src/ast/function.cc b/src/ast/function.cc
index 546a27b..3ca975e 100644
--- a/src/ast/function.cc
+++ b/src/ast/function.cc
@@ -16,6 +16,8 @@
#include <sstream>
+#include "src/ast/decorated_variable.h"
+
namespace tint {
namespace ast {
@@ -51,6 +53,42 @@
referenced_module_vars_.push_back(var);
}
+const std::vector<std::pair<Variable*, LocationDecoration*>>
+Function::referenced_location_variables() const {
+ std::vector<std::pair<Variable*, LocationDecoration*>> ret;
+
+ for (auto* var : referenced_module_variables()) {
+ if (!var->IsDecorated()) {
+ continue;
+ }
+ for (auto& deco : var->AsDecorated()->decorations()) {
+ if (deco->IsLocation()) {
+ ret.push_back({var, deco.get()->AsLocation()});
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
+const std::vector<std::pair<Variable*, BuiltinDecoration*>>
+Function::referenced_builtin_variables() const {
+ std::vector<std::pair<Variable*, BuiltinDecoration*>> ret;
+
+ for (auto* var : referenced_module_variables()) {
+ if (!var->IsDecorated()) {
+ continue;
+ }
+ for (auto& deco : var->AsDecorated()->decorations()) {
+ if (deco->IsBuiltin()) {
+ ret.push_back({var, deco.get()->AsBuiltin()});
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
void Function::add_ancestor_entry_point(const std::string& ep) {
for (const auto& point : ancestor_entry_points_) {
if (point == ep) {
diff --git a/src/ast/function.h b/src/ast/function.h
index bc804a3..a3722e1 100644
--- a/src/ast/function.h
+++ b/src/ast/function.h
@@ -21,7 +21,9 @@
#include <utility>
#include <vector>
+#include "src/ast/builtin_decoration.h"
#include "src/ast/expression.h"
+#include "src/ast/location_decoration.h"
#include "src/ast/node.h"
#include "src/ast/statement.h"
#include "src/ast/type/type.h"
@@ -76,6 +78,14 @@
const std::vector<Variable*>& referenced_module_variables() const {
return referenced_module_vars_;
}
+ /// Retrieves any referenced location variables
+ /// @returns the <variable, decoration> pair.
+ const std::vector<std::pair<Variable*, LocationDecoration*>>
+ referenced_location_variables() const;
+ /// Retrieves any referenced builtin variables
+ /// @returns the <variable, decoration> pair.
+ const std::vector<std::pair<Variable*, BuiltinDecoration*>>
+ referenced_builtin_variables() const;
/// Adds an ancestor entry point
/// @param ep the entry point ancestor
diff --git a/src/ast/function_test.cc b/src/ast/function_test.cc
index 71222fd..127719c 100644
--- a/src/ast/function_test.cc
+++ b/src/ast/function_test.cc
@@ -15,7 +15,10 @@
#include "src/ast/function.h"
#include "gtest/gtest.h"
+#include "src/ast/builtin_decoration.h"
+#include "src/ast/decorated_variable.h"
#include "src/ast/kill_statement.h"
+#include "src/ast/location_decoration.h"
#include "src/ast/pipeline_stage.h"
#include "src/ast/type/f32_type.h"
#include "src/ast/type/i32_type.h"
@@ -78,6 +81,92 @@
EXPECT_EQ(f.referenced_module_variables()[1], &v2);
}
+TEST_F(FunctionTest, GetReferenceLocations) {
+ type::VoidType void_type;
+ type::I32Type i32;
+
+ VariableDecorationList decos;
+ DecoratedVariable loc1(
+ std::make_unique<ast::Variable>("loc1", StorageClass::kInput, &i32));
+ decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+ loc1.set_decorations(std::move(decos));
+
+ DecoratedVariable loc2(
+ std::make_unique<ast::Variable>("loc2", StorageClass::kInput, &i32));
+ decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+ loc2.set_decorations(std::move(decos));
+
+ DecoratedVariable builtin1(
+ std::make_unique<ast::Variable>("builtin1", StorageClass::kInput, &i32));
+ decos.push_back(
+ std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kPosition));
+ builtin1.set_decorations(std::move(decos));
+
+ DecoratedVariable builtin2(
+ std::make_unique<ast::Variable>("builtin2", StorageClass::kInput, &i32));
+ decos.push_back(
+ std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragDepth));
+ builtin2.set_decorations(std::move(decos));
+
+ Function f("func", VariableList{}, &void_type);
+
+ f.add_referenced_module_variable(&loc1);
+ f.add_referenced_module_variable(&builtin1);
+ f.add_referenced_module_variable(&loc2);
+ f.add_referenced_module_variable(&builtin2);
+ ASSERT_EQ(f.referenced_module_variables().size(), 4u);
+
+ auto ref_locs = f.referenced_location_variables();
+ ASSERT_EQ(ref_locs.size(), 2u);
+ EXPECT_EQ(ref_locs[0].first, &loc1);
+ EXPECT_EQ(ref_locs[0].second->value(), 0);
+ EXPECT_EQ(ref_locs[1].first, &loc2);
+ EXPECT_EQ(ref_locs[1].second->value(), 1);
+}
+
+TEST_F(FunctionTest, GetReferenceBuiltins) {
+ type::VoidType void_type;
+ type::I32Type i32;
+
+ VariableDecorationList decos;
+ DecoratedVariable loc1(
+ std::make_unique<ast::Variable>("loc1", StorageClass::kInput, &i32));
+ decos.push_back(std::make_unique<ast::LocationDecoration>(0));
+ loc1.set_decorations(std::move(decos));
+
+ DecoratedVariable loc2(
+ std::make_unique<ast::Variable>("loc2", StorageClass::kInput, &i32));
+ decos.push_back(std::make_unique<ast::LocationDecoration>(1));
+ loc2.set_decorations(std::move(decos));
+
+ DecoratedVariable builtin1(
+ std::make_unique<ast::Variable>("builtin1", StorageClass::kInput, &i32));
+ decos.push_back(
+ std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kPosition));
+ builtin1.set_decorations(std::move(decos));
+
+ DecoratedVariable builtin2(
+ std::make_unique<ast::Variable>("builtin2", StorageClass::kInput, &i32));
+ decos.push_back(
+ std::make_unique<ast::BuiltinDecoration>(ast::Builtin::kFragDepth));
+ builtin2.set_decorations(std::move(decos));
+
+ Function f("func", VariableList{}, &void_type);
+
+ f.add_referenced_module_variable(&loc1);
+ f.add_referenced_module_variable(&builtin1);
+ f.add_referenced_module_variable(&loc2);
+ f.add_referenced_module_variable(&builtin2);
+ ASSERT_EQ(f.referenced_module_variables().size(), 4u);
+
+ auto ref_locs = f.referenced_builtin_variables();
+ ASSERT_EQ(ref_locs.size(), 2u);
+ EXPECT_EQ(ref_locs[0].first, &builtin1);
+ EXPECT_EQ(ref_locs[0].second->value(), ast::Builtin::kPosition);
+ EXPECT_EQ(ref_locs[1].first, &builtin2);
+ EXPECT_EQ(ref_locs[1].second->value(), ast::Builtin::kFragDepth);
+}
+
TEST_F(FunctionTest, AddDuplicateEntryPoints) {
ast::type::VoidType void_type;
Function f("func", VariableList{}, &void_type);
diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc
index 260d6fc..fbb9c84 100644
--- a/src/writer/msl/generator_impl.cc
+++ b/src/writer/msl/generator_impl.cc
@@ -518,21 +518,9 @@
std::vector<std::pair<ast::Variable*, uint32_t>> in_locations;
std::vector<std::pair<ast::Variable*, uint32_t>> out_locations;
- for (auto* var : func->referenced_module_variables()) {
- if (!var->IsDecorated()) {
- continue;
- }
- auto* decorated = var->AsDecorated();
- ast::LocationDecoration* locn_deco = nullptr;
- for (auto& deco : decorated->decorations()) {
- if (deco->IsLocation()) {
- locn_deco = deco.get()->AsLocation();
- break;
- }
- }
- if (locn_deco == nullptr) {
- continue;
- }
+ for (auto data : func->referenced_location_variables()) {
+ auto var = data.first;
+ auto locn_deco = data.second;
if (var->storage_class() == ast::StorageClass::kInput) {
in_locations.push_back({var, locn_deco->value()});
@@ -753,6 +741,8 @@
// TODO(dsinclair): Handle any entry point builtin params used here
+ // TODO(dsinclair): Binding/Set inputs
+
for (const auto& v : func->params()) {
if (!first) {
out_ << ", ";
@@ -816,6 +806,9 @@
}
// TODO(dsinclair): Output other builtin inputs
+
+ // TODO(dsinclair): Binding/Set inputs
+
out_ << ") {" << std::endl;
increment_indent();