Resolver: Defer building of semantic::Struct until end
This will allow us to collect up usage information of the structures in a single pass. Bug: tint:320 Bug: tint:643 Change-Id: Iaa700dc1e287f6df2717c422e66ec453b23b22dc Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/45123 Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: David Neto <dneto@google.com> Reviewed-by: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
parent
ad97343214
commit
893afdfd2c
|
@ -1242,6 +1242,15 @@ void Resolver::CreateSemanticNodes() const {
|
|||
sem.Add(expr, builder_->create<semantic::Expression>(expr, info.type,
|
||||
info.statement));
|
||||
}
|
||||
|
||||
// Create semantic nodes for all structs
|
||||
for (auto it : struct_info_) {
|
||||
auto* str = it.first;
|
||||
auto* info = it.second;
|
||||
builder_->Sem().Add(str, builder_->create<semantic::Struct>(
|
||||
str, std::move(info->members), info->align,
|
||||
info->size, info->size_no_padding));
|
||||
}
|
||||
}
|
||||
|
||||
bool Resolver::DefaultAlignAndSize(type::Type* ty,
|
||||
|
@ -1288,9 +1297,9 @@ bool Resolver::DefaultAlignAndSize(type::Type* ty,
|
|||
size = vector_align[mat->rows()] * mat->columns();
|
||||
return true;
|
||||
} else if (auto* s = ty->As<type::Struct>()) {
|
||||
if (auto* sem = Structure(s)) {
|
||||
align = sem->Align();
|
||||
size = sem->Size();
|
||||
if (auto* si = Structure(s)) {
|
||||
align = si->align;
|
||||
size = si->size;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1354,10 +1363,11 @@ const semantic::Array* Resolver::Array(type::Array* arr) {
|
|||
return create_semantic(utils::RoundUp(el_align, el_size));
|
||||
}
|
||||
|
||||
const semantic::Struct* Resolver::Structure(type::Struct* str) {
|
||||
if (auto* sem = builder_->Sem().Get(str)) {
|
||||
// Semantic info already constructed for this structure type
|
||||
return sem;
|
||||
Resolver::StructInfo* Resolver::Structure(type::Struct* str) {
|
||||
auto info_it = struct_info_.find(str);
|
||||
if (info_it != struct_info_.end()) {
|
||||
// StructInfo already resolved for this structure type
|
||||
return info_it->second;
|
||||
}
|
||||
|
||||
semantic::StructMemberList sem_members;
|
||||
|
@ -1451,10 +1461,13 @@ const semantic::Struct* Resolver::Structure(type::Struct* str) {
|
|||
auto size_no_padding = struct_size;
|
||||
struct_size = utils::RoundUp(struct_align, struct_size);
|
||||
|
||||
auto* sem = builder_->create<semantic::Struct>(
|
||||
str, std::move(sem_members), struct_align, struct_size, size_no_padding);
|
||||
builder_->Sem().Add(str, sem);
|
||||
return sem;
|
||||
auto* info = struct_infos_.Create();
|
||||
info->members = std::move(sem_members);
|
||||
info->align = struct_align;
|
||||
info->size = struct_size;
|
||||
info->size_no_padding = size_no_padding;
|
||||
struct_info_.emplace(str, info);
|
||||
return info;
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
|
@ -1470,8 +1483,10 @@ Resolver::VariableInfo::VariableInfo(ast::Variable* decl)
|
|||
Resolver::VariableInfo::~VariableInfo() = default;
|
||||
|
||||
Resolver::FunctionInfo::FunctionInfo(ast::Function* decl) : declaration(decl) {}
|
||||
|
||||
Resolver::FunctionInfo::~FunctionInfo() = default;
|
||||
|
||||
Resolver::StructInfo::StructInfo() = default;
|
||||
Resolver::StructInfo::~StructInfo() = default;
|
||||
|
||||
} // namespace resolver
|
||||
} // namespace tint
|
||||
|
|
|
@ -114,6 +114,18 @@ class Resolver {
|
|||
semantic::Statement* statement;
|
||||
};
|
||||
|
||||
/// Structure holding semantic information about a struct.
|
||||
/// Used to build the semantic::Struct nodes at the end of resolving.
|
||||
struct StructInfo {
|
||||
StructInfo();
|
||||
~StructInfo();
|
||||
|
||||
std::vector<semantic::StructMember*> members;
|
||||
uint32_t align = 0;
|
||||
uint32_t size = 0;
|
||||
uint32_t size_no_padding = 0;
|
||||
};
|
||||
|
||||
/// Structure holding semantic information about a block (i.e. scope), such as
|
||||
/// parent block and variables declared in the block.
|
||||
/// Used to validate variable scoping rules.
|
||||
|
@ -201,10 +213,9 @@ class Resolver {
|
|||
/// returned.
|
||||
const semantic::Array* Array(type::Array*);
|
||||
|
||||
/// @returns the semantic information for the structure `str`, building it if
|
||||
/// it hasn't been constructed already. If an error is raised, nullptr is
|
||||
/// returned.
|
||||
const semantic::Struct* Structure(type::Struct* str);
|
||||
/// @returns the StructInfo for the structure `str`, building it if it hasn't
|
||||
/// been constructed already. If an error is raised, nullptr is returned.
|
||||
StructInfo* Structure(type::Struct* str);
|
||||
|
||||
/// @param align the output default alignment in bytes for the type `ty`
|
||||
/// @param size the output default size in bytes for the type `ty`
|
||||
|
@ -239,10 +250,12 @@ class Resolver {
|
|||
std::unordered_map<ast::Variable*, VariableInfo*> variable_to_info_;
|
||||
std::unordered_map<ast::CallExpression*, FunctionCallInfo> function_calls_;
|
||||
std::unordered_map<ast::Expression*, ExpressionInfo> expr_info_;
|
||||
std::unordered_map<type::Struct*, StructInfo*> struct_info_;
|
||||
FunctionInfo* current_function_ = nullptr;
|
||||
semantic::Statement* current_statement_ = nullptr;
|
||||
BlockAllocator<VariableInfo> variable_infos_;
|
||||
BlockAllocator<FunctionInfo> function_infos_;
|
||||
BlockAllocator<StructInfo> struct_infos_;
|
||||
};
|
||||
|
||||
} // namespace resolver
|
||||
|
|
Loading…
Reference in New Issue