tint: Split Resolver::Materialize()
Add Resolver::ConcreteType() to determine the concrete type for an abstract-numeric (or composite of abstract). Will be used to recursively infer the concrete types of abstract arrays. Bug: tint:1628 Change-Id: Ia26b778abc827b531848b346f3e36938ad1a0470 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/97582 Commit-Queue: Ben Clayton <bclayton@chromium.org> Reviewed-by: Dan Sinclair <dsinclair@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
ea84b9b072
commit
05a76183e0
|
@ -1318,46 +1318,7 @@ sem::Expression* Resolver::Expression(const ast::Expression* root) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Expression* Resolver::Materialize(const sem::Expression* expr,
|
const sem::Type* Resolver::ConcreteType(const sem::Type* ty, const sem::Type* target_ty) {
|
||||||
const sem::Type* target_type /* = nullptr */) {
|
|
||||||
if (!expr) {
|
|
||||||
return nullptr; // Allow for Materialize(Expression(blah))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper for actually creating the the materialize node, performing the constant cast, updating
|
|
||||||
// the ast -> sem binding, and performing validation.
|
|
||||||
auto materialize = [&](const sem::Type* target_ty) -> sem::Materialize* {
|
|
||||||
auto* src_ty = expr->Type();
|
|
||||||
auto* decl = expr->Declaration();
|
|
||||||
if (!validator_.Materialize(target_ty, src_ty, decl->source)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
auto expr_val = expr->ConstantValue();
|
|
||||||
if (!expr_val) {
|
|
||||||
TINT_ICE(Resolver, builder_->Diagnostics())
|
|
||||||
<< decl->source << "Materialize(" << decl->TypeInfo().name
|
|
||||||
<< ") called on expression with no constant value";
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
auto materialized_val = const_eval_.Convert(target_ty, expr_val, decl->source);
|
|
||||||
if (!materialized_val) {
|
|
||||||
// ConvertValue() has already failed and raised an diagnostic error.
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
if (!materialized_val.Get()) {
|
|
||||||
TINT_ICE(Resolver, builder_->Diagnostics())
|
|
||||||
<< decl->source << "ConvertValue(" << builder_->FriendlyName(expr_val->Type())
|
|
||||||
<< " -> " << builder_->FriendlyName(target_ty) << ") returned invalid value";
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
auto* m =
|
|
||||||
builder_->create<sem::Materialize>(expr, current_statement_, materialized_val.Get());
|
|
||||||
m->Behaviors() = expr->Behaviors();
|
|
||||||
builder_->Sem().Replace(decl, m);
|
|
||||||
return m;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Helpers for constructing semantic types
|
|
||||||
auto i32 = [&] { return builder_->create<sem::I32>(); };
|
auto i32 = [&] { return builder_->create<sem::I32>(); };
|
||||||
auto f32 = [&] { return builder_->create<sem::F32>(); };
|
auto f32 = [&] { return builder_->create<sem::F32>(); };
|
||||||
auto i32v = [&](uint32_t width) { return builder_->create<sem::Vector>(i32(), width); };
|
auto i32v = [&](uint32_t width) { return builder_->create<sem::Vector>(i32(), width); };
|
||||||
|
@ -1366,31 +1327,69 @@ const sem::Expression* Resolver::Materialize(const sem::Expression* expr,
|
||||||
return builder_->create<sem::Matrix>(f32v(rows), columns);
|
return builder_->create<sem::Matrix>(f32v(rows), columns);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Type dispatch based on the expression type
|
return Switch(
|
||||||
return Switch<sem::Expression*>(
|
ty, //
|
||||||
expr->Type(), //
|
[&](const sem::AbstractInt*) { return target_ty ? target_ty : i32(); },
|
||||||
[&](const sem::AbstractInt*) { return materialize(target_type ? target_type : i32()); },
|
[&](const sem::AbstractFloat*) { return target_ty ? target_ty : f32(); },
|
||||||
[&](const sem::AbstractFloat*) { return materialize(target_type ? target_type : f32()); },
|
|
||||||
[&](const sem::Vector* v) {
|
[&](const sem::Vector* v) {
|
||||||
return Switch(
|
return Switch(
|
||||||
v->type(), //
|
v->type(), //
|
||||||
[&](const sem::AbstractInt*) {
|
[&](const sem::AbstractInt*) { return target_ty ? target_ty : i32v(v->Width()); },
|
||||||
return materialize(target_type ? target_type : i32v(v->Width()));
|
|
||||||
},
|
|
||||||
[&](const sem::AbstractFloat*) {
|
[&](const sem::AbstractFloat*) {
|
||||||
return materialize(target_type ? target_type : f32v(v->Width()));
|
return target_ty ? target_ty : f32v(v->Width());
|
||||||
},
|
});
|
||||||
[&](Default) { return expr; });
|
|
||||||
},
|
},
|
||||||
[&](const sem::Matrix* m) {
|
[&](const sem::Matrix* m) {
|
||||||
return Switch(
|
return Switch(m->type(), //
|
||||||
m->type(), //
|
[&](const sem::AbstractFloat*) {
|
||||||
[&](const sem::AbstractFloat*) {
|
return target_ty ? target_ty : f32m(m->columns(), m->rows());
|
||||||
return materialize(target_type ? target_type : f32m(m->columns(), m->rows()));
|
});
|
||||||
},
|
});
|
||||||
[&](Default) { return expr; });
|
}
|
||||||
},
|
|
||||||
[&](Default) { return expr; });
|
const sem::Expression* Resolver::Materialize(const sem::Expression* expr,
|
||||||
|
const sem::Type* target_type /* = nullptr */) {
|
||||||
|
if (!expr) {
|
||||||
|
// Allow for Materialize(Expression(blah)), where failures pass through Materialize()
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* decl = expr->Declaration();
|
||||||
|
|
||||||
|
auto* concrete_ty = ConcreteType(expr->Type(), target_type);
|
||||||
|
if (!concrete_ty) {
|
||||||
|
return expr; // Does not require materialization
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* src_ty = expr->Type();
|
||||||
|
if (!validator_.Materialize(concrete_ty, src_ty, decl->source)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto expr_val = expr->ConstantValue();
|
||||||
|
if (!expr_val) {
|
||||||
|
TINT_ICE(Resolver, builder_->Diagnostics())
|
||||||
|
<< decl->source << "Materialize(" << decl->TypeInfo().name
|
||||||
|
<< ") called on expression with no constant value";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto materialized_val = const_eval_.Convert(concrete_ty, expr_val, decl->source);
|
||||||
|
if (!materialized_val) {
|
||||||
|
// ConvertValue() has already failed and raised an diagnostic error.
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!materialized_val.Get()) {
|
||||||
|
TINT_ICE(Resolver, builder_->Diagnostics())
|
||||||
|
<< decl->source << "ConvertValue(" << builder_->FriendlyName(expr_val->Type()) << " -> "
|
||||||
|
<< builder_->FriendlyName(concrete_ty) << ") returned invalid value";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto* m = builder_->create<sem::Materialize>(expr, current_statement_, materialized_val.Get());
|
||||||
|
m->Behaviors() = expr->Behaviors();
|
||||||
|
builder_->Sem().Replace(decl, m);
|
||||||
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Resolver::MaterializeArguments(utils::VectorRef<const sem::Expression*> args,
|
bool Resolver::MaterializeArguments(utils::VectorRef<const sem::Expression*> args,
|
||||||
|
|
|
@ -230,6 +230,13 @@ class Resolver {
|
||||||
/// `parameter_ty` should be materialized.
|
/// `parameter_ty` should be materialized.
|
||||||
bool ShouldMaterializeArgument(const sem::Type* parameter_ty) const;
|
bool ShouldMaterializeArgument(const sem::Type* parameter_ty) const;
|
||||||
|
|
||||||
|
/// @param ty the type that may hold abstract numeric types
|
||||||
|
/// @param target_ty the target type for the expression (variable type, parameter type, etc).
|
||||||
|
/// May be nullptr.
|
||||||
|
/// @returns the concrete (materialized) type for the given type, or nullptr if the type is
|
||||||
|
/// already concrete.
|
||||||
|
const sem::Type* ConcreteType(const sem::Type* ty, const sem::Type* target_ty);
|
||||||
|
|
||||||
// Statement resolving methods
|
// Statement resolving methods
|
||||||
// Each return true on success, false on failure.
|
// Each return true on success, false on failure.
|
||||||
sem::Statement* AssignmentStatement(const ast::AssignmentStatement*);
|
sem::Statement* AssignmentStatement(const ast::AssignmentStatement*);
|
||||||
|
|
Loading…
Reference in New Issue