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,
|
sem.Add(expr, builder_->create<semantic::Expression>(expr, info.type,
|
||||||
info.statement));
|
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,
|
bool Resolver::DefaultAlignAndSize(type::Type* ty,
|
||||||
|
@ -1288,9 +1297,9 @@ bool Resolver::DefaultAlignAndSize(type::Type* ty,
|
||||||
size = vector_align[mat->rows()] * mat->columns();
|
size = vector_align[mat->rows()] * mat->columns();
|
||||||
return true;
|
return true;
|
||||||
} else if (auto* s = ty->As<type::Struct>()) {
|
} else if (auto* s = ty->As<type::Struct>()) {
|
||||||
if (auto* sem = Structure(s)) {
|
if (auto* si = Structure(s)) {
|
||||||
align = sem->Align();
|
align = si->align;
|
||||||
size = sem->Size();
|
size = si->size;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -1354,10 +1363,11 @@ const semantic::Array* Resolver::Array(type::Array* arr) {
|
||||||
return create_semantic(utils::RoundUp(el_align, el_size));
|
return create_semantic(utils::RoundUp(el_align, el_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
const semantic::Struct* Resolver::Structure(type::Struct* str) {
|
Resolver::StructInfo* Resolver::Structure(type::Struct* str) {
|
||||||
if (auto* sem = builder_->Sem().Get(str)) {
|
auto info_it = struct_info_.find(str);
|
||||||
// Semantic info already constructed for this structure type
|
if (info_it != struct_info_.end()) {
|
||||||
return sem;
|
// StructInfo already resolved for this structure type
|
||||||
|
return info_it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
semantic::StructMemberList sem_members;
|
semantic::StructMemberList sem_members;
|
||||||
|
@ -1451,10 +1461,13 @@ const semantic::Struct* Resolver::Structure(type::Struct* str) {
|
||||||
auto size_no_padding = struct_size;
|
auto size_no_padding = struct_size;
|
||||||
struct_size = utils::RoundUp(struct_align, struct_size);
|
struct_size = utils::RoundUp(struct_align, struct_size);
|
||||||
|
|
||||||
auto* sem = builder_->create<semantic::Struct>(
|
auto* info = struct_infos_.Create();
|
||||||
str, std::move(sem_members), struct_align, struct_size, size_no_padding);
|
info->members = std::move(sem_members);
|
||||||
builder_->Sem().Add(str, sem);
|
info->align = struct_align;
|
||||||
return sem;
|
info->size = struct_size;
|
||||||
|
info->size_no_padding = size_no_padding;
|
||||||
|
struct_info_.emplace(str, info);
|
||||||
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
|
@ -1470,8 +1483,10 @@ Resolver::VariableInfo::VariableInfo(ast::Variable* decl)
|
||||||
Resolver::VariableInfo::~VariableInfo() = default;
|
Resolver::VariableInfo::~VariableInfo() = default;
|
||||||
|
|
||||||
Resolver::FunctionInfo::FunctionInfo(ast::Function* decl) : declaration(decl) {}
|
Resolver::FunctionInfo::FunctionInfo(ast::Function* decl) : declaration(decl) {}
|
||||||
|
|
||||||
Resolver::FunctionInfo::~FunctionInfo() = default;
|
Resolver::FunctionInfo::~FunctionInfo() = default;
|
||||||
|
|
||||||
|
Resolver::StructInfo::StructInfo() = default;
|
||||||
|
Resolver::StructInfo::~StructInfo() = default;
|
||||||
|
|
||||||
} // namespace resolver
|
} // namespace resolver
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
|
@ -114,6 +114,18 @@ class Resolver {
|
||||||
semantic::Statement* statement;
|
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
|
/// Structure holding semantic information about a block (i.e. scope), such as
|
||||||
/// parent block and variables declared in the block.
|
/// parent block and variables declared in the block.
|
||||||
/// Used to validate variable scoping rules.
|
/// Used to validate variable scoping rules.
|
||||||
|
@ -201,10 +213,9 @@ class Resolver {
|
||||||
/// returned.
|
/// returned.
|
||||||
const semantic::Array* Array(type::Array*);
|
const semantic::Array* Array(type::Array*);
|
||||||
|
|
||||||
/// @returns the semantic information for the structure `str`, building it if
|
/// @returns the StructInfo for the structure `str`, building it if it hasn't
|
||||||
/// it hasn't been constructed already. If an error is raised, nullptr is
|
/// been constructed already. If an error is raised, nullptr is returned.
|
||||||
/// returned.
|
StructInfo* Structure(type::Struct* str);
|
||||||
const semantic::Struct* Structure(type::Struct* str);
|
|
||||||
|
|
||||||
/// @param align the output default alignment in bytes for the type `ty`
|
/// @param align the output default alignment in bytes for the type `ty`
|
||||||
/// @param size the output default size 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::Variable*, VariableInfo*> variable_to_info_;
|
||||||
std::unordered_map<ast::CallExpression*, FunctionCallInfo> function_calls_;
|
std::unordered_map<ast::CallExpression*, FunctionCallInfo> function_calls_;
|
||||||
std::unordered_map<ast::Expression*, ExpressionInfo> expr_info_;
|
std::unordered_map<ast::Expression*, ExpressionInfo> expr_info_;
|
||||||
|
std::unordered_map<type::Struct*, StructInfo*> struct_info_;
|
||||||
FunctionInfo* current_function_ = nullptr;
|
FunctionInfo* current_function_ = nullptr;
|
||||||
semantic::Statement* current_statement_ = nullptr;
|
semantic::Statement* current_statement_ = nullptr;
|
||||||
BlockAllocator<VariableInfo> variable_infos_;
|
BlockAllocator<VariableInfo> variable_infos_;
|
||||||
BlockAllocator<FunctionInfo> function_infos_;
|
BlockAllocator<FunctionInfo> function_infos_;
|
||||||
|
BlockAllocator<StructInfo> struct_infos_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace resolver
|
} // namespace resolver
|
||||||
|
|
Loading…
Reference in New Issue