mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-07 13:45:51 +00:00
[sem] Move TransitivelyReferencedOverrides to sem::Info.
This CL pulls the TransitivelyReferencedOverrides from sem::Array and sem::GlobalVariable up to the sem::Info. Moving this data outside of sem::Array removes one of the references to non-Type sem content. Bug: tint:1718 Change-Id: I40c1c8b2d5ec60dc2723b56cc30cd436e9b7e997 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/112324 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ben Clayton <bclayton@google.com> Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
331a3b7980
commit
527e38b68b
@ -142,7 +142,9 @@ TEST_F(ResolverOverrideTest, TransitiveReferences_ViaOverrideInit) {
|
|||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
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);
|
ASSERT_EQ(refs.Length(), 1u);
|
||||||
EXPECT_EQ(refs[0], Sem().Get(a));
|
EXPECT_EQ(refs[0], Sem().Get(a));
|
||||||
}
|
}
|
||||||
@ -167,7 +169,9 @@ TEST_F(ResolverOverrideTest, TransitiveReferences_ViaPrivateInit) {
|
|||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
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);
|
ASSERT_EQ(refs.Length(), 1u);
|
||||||
EXPECT_EQ(refs[0], Sem().Get(a));
|
EXPECT_EQ(refs[0], Sem().Get(a));
|
||||||
}
|
}
|
||||||
@ -215,14 +219,18 @@ TEST_F(ResolverOverrideTest, TransitiveReferences_ViaArraySize) {
|
|||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
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);
|
ASSERT_EQ(refs.Length(), 2u);
|
||||||
EXPECT_EQ(refs[0], Sem().Get(b));
|
EXPECT_EQ(refs[0], Sem().Get(b));
|
||||||
EXPECT_EQ(refs[1], Sem().Get(a));
|
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);
|
ASSERT_EQ(refs.Length(), 2u);
|
||||||
EXPECT_EQ(refs[0], Sem().Get(b));
|
EXPECT_EQ(refs[0], Sem().Get(b));
|
||||||
EXPECT_EQ(refs[1], Sem().Get(a));
|
EXPECT_EQ(refs[1], Sem().Get(a));
|
||||||
@ -251,14 +259,18 @@ TEST_F(ResolverOverrideTest, TransitiveReferences_ViaArraySize_Alias) {
|
|||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
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);
|
ASSERT_EQ(refs.Length(), 2u);
|
||||||
EXPECT_EQ(refs[0], Sem().Get(b));
|
EXPECT_EQ(refs[0], Sem().Get(b));
|
||||||
EXPECT_EQ(refs[1], Sem().Get(a));
|
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);
|
ASSERT_EQ(refs.Length(), 2u);
|
||||||
EXPECT_EQ(refs[0], Sem().Get(b));
|
EXPECT_EQ(refs[0], Sem().Get(b));
|
||||||
EXPECT_EQ(refs[1], Sem().Get(a));
|
EXPECT_EQ(refs[1], Sem().Get(a));
|
||||||
|
@ -917,11 +917,14 @@ sem::GlobalVariable* Resolver::GlobalVariable(const ast::Variable* v) {
|
|||||||
|
|
||||||
// Track the pipeline-overridable constants that are transitively referenced by this variable.
|
// Track the pipeline-overridable constants that are transitively referenced by this variable.
|
||||||
for (auto* var : transitively_referenced_overrides) {
|
for (auto* var : transitively_referenced_overrides) {
|
||||||
sem->AddTransitivelyReferencedOverride(var);
|
builder_->Sem().AddTransitivelyReferencedOverride(sem, var);
|
||||||
}
|
}
|
||||||
if (auto* arr = sem->Type()->UnwrapRef()->As<sem::Array>()) {
|
if (auto* arr = sem->Type()->UnwrapRef()->As<sem::Array>()) {
|
||||||
for (auto* var : arr->TransitivelyReferencedOverrides()) {
|
auto* refs = builder_->Sem().TransitivelyReferencedOverrides(arr);
|
||||||
sem->AddTransitivelyReferencedOverride(var);
|
if (refs) {
|
||||||
|
for (auto* var : *refs) {
|
||||||
|
builder_->Sem().AddTransitivelyReferencedOverride(sem, var);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2553,19 +2556,25 @@ sem::Expression* Resolver::Identifier(const ast::IdentifierExpression* expr) {
|
|||||||
if (current_function_) {
|
if (current_function_) {
|
||||||
if (global) {
|
if (global) {
|
||||||
current_function_->AddDirectlyReferencedGlobal(global);
|
current_function_->AddDirectlyReferencedGlobal(global);
|
||||||
for (auto* var : global->TransitivelyReferencedOverrides()) {
|
auto* refs = builder_->Sem().TransitivelyReferencedOverrides(global);
|
||||||
|
if (refs) {
|
||||||
|
for (auto* var : *refs) {
|
||||||
current_function_->AddTransitivelyReferencedGlobal(var);
|
current_function_->AddTransitivelyReferencedGlobal(var);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (variable->Declaration()->Is<ast::Override>()) {
|
} else if (variable->Declaration()->Is<ast::Override>()) {
|
||||||
if (resolved_overrides_) {
|
if (resolved_overrides_) {
|
||||||
// Track the reference to this pipeline-overridable constant and any other
|
// Track the reference to this pipeline-overridable constant and any other
|
||||||
// pipeline-overridable constants that it references.
|
// pipeline-overridable constants that it references.
|
||||||
resolved_overrides_->Add(global);
|
resolved_overrides_->Add(global);
|
||||||
for (auto* var : global->TransitivelyReferencedOverrides()) {
|
auto* refs = builder_->Sem().TransitivelyReferencedOverrides(global);
|
||||||
|
if (refs) {
|
||||||
|
for (auto* var : *refs) {
|
||||||
resolved_overrides_->Add(var);
|
resolved_overrides_->Add(var);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if (variable->Declaration()->Is<ast::Var>()) {
|
} else if (variable->Declaration()->Is<ast::Var>()) {
|
||||||
// Use of a module-scope 'var' outside of a function.
|
// Use of a module-scope 'var' outside of a function.
|
||||||
// Note: The spec is currently vague around the rules here. See
|
// Note: The spec is currently vague around the rules here. See
|
||||||
@ -2956,7 +2965,7 @@ sem::Array* Resolver::Array(const ast::Array* arr) {
|
|||||||
// Track the pipeline-overridable constants that are transitively referenced by this array
|
// Track the pipeline-overridable constants that are transitively referenced by this array
|
||||||
// type.
|
// type.
|
||||||
for (auto* var : transitively_referenced_overrides) {
|
for (auto* var : transitively_referenced_overrides) {
|
||||||
out->AddTransitivelyReferencedOverride(var);
|
builder_->Sem().AddTransitivelyReferencedOverride(out, var);
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
|
@ -230,17 +230,6 @@ class Array final : public Castable<Array, Type> {
|
|||||||
/// @returns true if this array is runtime sized
|
/// @returns true if this array is runtime sized
|
||||||
bool IsRuntimeSized() const { return std::holds_alternative<RuntimeArrayCount>(count_); }
|
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
|
/// @param symbols the program's symbol table
|
||||||
/// @returns the name for this type that closely resembles how it would be
|
/// @returns the name for this type that closely resembles how it would be
|
||||||
/// declared in WGSL.
|
/// declared in WGSL.
|
||||||
@ -253,7 +242,6 @@ class Array final : public Castable<Array, Type> {
|
|||||||
const uint32_t size_;
|
const uint32_t size_;
|
||||||
const uint32_t stride_;
|
const uint32_t stride_;
|
||||||
const uint32_t implicit_stride_;
|
const uint32_t implicit_stride_;
|
||||||
utils::UniqueVector<const GlobalVariable*, 4> referenced_overrides_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tint::sem
|
} // namespace tint::sem
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "src/tint/debug.h"
|
#include "src/tint/debug.h"
|
||||||
#include "src/tint/sem/node.h"
|
#include "src/tint/sem/node.h"
|
||||||
#include "src/tint/sem/type_mappings.h"
|
#include "src/tint/sem/type_mappings.h"
|
||||||
|
#include "src/tint/utils/unique_vector.h"
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
namespace tint::sem {
|
namespace tint::sem {
|
||||||
@ -44,6 +45,9 @@ class Info {
|
|||||||
using GetResultType =
|
using GetResultType =
|
||||||
std::conditional_t<std::is_same<SEM, InferFromAST>::value, SemanticNodeTypeFor<AST>, SEM>;
|
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
|
/// Constructor
|
||||||
Info();
|
Info();
|
||||||
|
|
||||||
@ -117,9 +121,30 @@ class Info {
|
|||||||
/// @returns the semantic module.
|
/// @returns the semantic module.
|
||||||
const sem::Module* Module() const { return 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:
|
private:
|
||||||
// AST node index to semantic node
|
// AST node index to semantic node
|
||||||
std::vector<const sem::Node*> nodes_;
|
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
|
// The semantic module
|
||||||
sem::Module* module_ = nullptr;
|
sem::Module* module_ = nullptr;
|
||||||
};
|
};
|
||||||
|
@ -183,23 +183,11 @@ class GlobalVariable final : public Castable<GlobalVariable, Variable> {
|
|||||||
/// @returns the location value for the parameter, if set
|
/// @returns the location value for the parameter, if set
|
||||||
std::optional<uint32_t> Location() const { return location_; }
|
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:
|
private:
|
||||||
const sem::BindingPoint binding_point_;
|
const sem::BindingPoint binding_point_;
|
||||||
|
|
||||||
tint::OverrideId override_id_;
|
tint::OverrideId override_id_;
|
||||||
std::optional<uint32_t> location_;
|
std::optional<uint32_t> location_;
|
||||||
utils::UniqueVector<const GlobalVariable*, 4> referenced_overrides_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Parameter is a function parameter
|
/// Parameter is a function parameter
|
||||||
|
@ -71,12 +71,15 @@ Transform::ApplyResult SingleEntryPoint::Apply(const Program* src,
|
|||||||
[&](const ast::TypeDecl* ty) {
|
[&](const ast::TypeDecl* ty) {
|
||||||
// Strip aliases that reference unused override declarations.
|
// Strip aliases that reference unused override declarations.
|
||||||
if (auto* arr = sem.Get(ty)->As<sem::Array>()) {
|
if (auto* arr = sem.Get(ty)->As<sem::Array>()) {
|
||||||
for (auto* o : arr->TransitivelyReferencedOverrides()) {
|
auto* refs = sem.TransitivelyReferencedOverrides(arr);
|
||||||
|
if (refs) {
|
||||||
|
for (auto* o : *refs) {
|
||||||
if (!referenced_vars.Contains(o)) {
|
if (!referenced_vars.Contains(o)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(jrprice): Strip other unused types.
|
// TODO(jrprice): Strip other unused types.
|
||||||
b.AST().AddTypeDecl(ctx.Clone(ty));
|
b.AST().AddTypeDecl(ctx.Clone(ty));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user