tint/resolver: Add ConstEval class
Extract out the methods of Resolver::EvaluateXXXValue() to a new
tint::resolver::ConstEval class.
Removes more bloat from Resolver, and creates a centralized class for
constant evaluation, which can be referred to by the IntrinsicTable.
Change-Id: I3b58882ef293fe07f019ad2138a7e9dbbac8de53
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/95951
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index 0df9a8f..e364fa6 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -91,6 +91,7 @@
Resolver::Resolver(ProgramBuilder* builder)
: builder_(builder),
diagnostics_(builder->Diagnostics()),
+ const_eval_(*builder),
intrinsic_table_(IntrinsicTable::Create(*builder)),
sem_(builder, dependencies_),
validator_(builder, sem_) {}
@@ -1313,7 +1314,7 @@
<< ") called on expression with no constant value";
return nullptr;
}
- auto materialized_val = ConvertValue(expr_val, target_ty, decl->source);
+ 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;
@@ -1422,7 +1423,7 @@
ty = builder_->create<sem::Reference>(ty, ref->StorageClass(), ref->Access());
}
- auto val = EvaluateIndexValue(obj, idx);
+ auto val = const_eval_.Index(obj, idx);
bool has_side_effects = idx->HasSideEffects() || obj->HasSideEffects();
auto* sem = builder_->create<sem::IndexAccessorExpression>(
expr, ty, obj, idx, current_statement_, std::move(val), has_side_effects,
@@ -1441,7 +1442,7 @@
return nullptr;
}
- auto val = EvaluateBitcastValue(inner, ty);
+ auto val = const_eval_.Bitcast(ty, inner);
auto* sem = builder_->create<sem::Expression>(expr, ty, current_statement_, std::move(val),
inner->HasSideEffects());
@@ -1489,7 +1490,7 @@
if (!MaterializeArguments(args, call_target)) {
return nullptr;
}
- auto val = EvaluateCtorOrConvValue(args, call_target->ReturnType());
+ auto val = const_eval_.CtorOrConv(call_target->ReturnType(), args);
return builder_->create<sem::Call>(expr, call_target, std::move(args), current_statement_,
val, has_side_effects);
};
@@ -1528,7 +1529,7 @@
if (!MaterializeArguments(args, call_target)) {
return nullptr;
}
- auto val = EvaluateCtorOrConvValue(args, arr);
+ auto val = const_eval_.CtorOrConv(arr, args);
return builder_->create<sem::Call>(expr, call_target, std::move(args),
current_statement_, val, has_side_effects);
},
@@ -1550,7 +1551,7 @@
if (!MaterializeArguments(args, call_target)) {
return nullptr;
}
- auto val = EvaluateCtorOrConvValue(args, str);
+ auto val = const_eval_.CtorOrConv(str, args);
return builder_->create<sem::Call>(expr, call_target, std::move(args),
current_statement_, std::move(val),
has_side_effects);
@@ -1682,28 +1683,17 @@
}
// If the builtin is @const, and all arguments have constant values, evaluate the builtin now.
- const sem::Constant* constant = nullptr;
+ const sem::Constant* value = nullptr;
if (builtin.const_eval_fn) {
- std::vector<const sem::Constant*> values(args.size());
- bool is_const = true; // all arguments have constant values
- for (size_t i = 0; i < values.size(); i++) {
- if (auto v = args[i]->ConstantValue()) {
- values[i] = std::move(v);
- } else {
- is_const = false;
- break;
- }
- }
- if (is_const) {
- constant = builtin.const_eval_fn(*builder_, values.data(), args.size());
- }
+ value = (const_eval_.*builtin.const_eval_fn)(builtin.sem->ReturnType(), args.data(),
+ args.size());
}
bool has_side_effects =
builtin.sem->HasSideEffects() ||
std::any_of(args.begin(), args.end(), [](auto* e) { return e->HasSideEffects(); });
auto* call = builder_->create<sem::Call>(expr, builtin.sem, std::move(args), current_statement_,
- constant, has_side_effects);
+ value, has_side_effects);
if (current_function_) {
current_function_->AddDirectlyCalledBuiltin(builtin.sem);
@@ -1856,7 +1846,7 @@
return nullptr;
}
- auto val = EvaluateLiteralValue(literal, ty);
+ auto val = const_eval_.Literal(ty, literal);
return builder_->create<sem::Expression>(literal, ty, current_statement_, std::move(val),
/* has_side_effects */ false);
}
@@ -1976,7 +1966,7 @@
ret = builder_->create<sem::Reference>(ret, ref->StorageClass(), ref->Access());
}
- auto* val = EvaluateMemberAccessValue(object, member);
+ auto* val = const_eval_.MemberAccess(object, member);
return builder_->create<sem::StructMemberAccess>(expr, ret, current_statement_, val, object,
member, has_side_effects, source_var);
}
@@ -2044,7 +2034,7 @@
// the swizzle.
ret = builder_->create<sem::Vector>(vec->type(), static_cast<uint32_t>(size));
}
- auto* val = EvaluateSwizzleValue(object, ret, swizzle);
+ auto* val = const_eval_.Swizzle(ret, object, swizzle);
return builder_->create<sem::Swizzle>(expr, ret, current_statement_, val, object,
std::move(swizzle), has_side_effects, source_var);
}
@@ -2078,9 +2068,14 @@
}
}
- auto* val = EvaluateBinaryValue(lhs, rhs, op);
+ const sem::Constant* value = nullptr;
+ if (op.const_eval_fn) {
+ const sem::Expression* args[] = {lhs, rhs};
+ value = (const_eval_.*op.const_eval_fn)(op.result, args, 2u);
+ }
+
bool has_side_effects = lhs->HasSideEffects() || rhs->HasSideEffects();
- auto* sem = builder_->create<sem::Expression>(expr, op.result, current_statement_, val,
+ auto* sem = builder_->create<sem::Expression>(expr, op.result, current_statement_, value,
has_side_effects);
sem->Behaviors() = lhs->Behaviors() + rhs->Behaviors();
@@ -2096,7 +2091,7 @@
const sem::Type* ty = nullptr;
const sem::Variable* source_var = nullptr;
- const sem::Constant* val = nullptr;
+ const sem::Constant* value = nullptr;
switch (unary->op) {
case ast::UnaryOp::kAddressOf:
@@ -2149,12 +2144,14 @@
}
}
ty = op.result;
- val = EvaluateUnaryValue(expr, op);
+ if (op.const_eval_fn) {
+ value = (const_eval_.*op.const_eval_fn)(ty, &expr, 1u);
+ }
break;
}
}
- auto* sem = builder_->create<sem::Expression>(unary, ty, current_statement_, val,
+ auto* sem = builder_->create<sem::Expression>(unary, ty, current_statement_, value,
expr->HasSideEffects(), source_var);
sem->Behaviors() = expr->Behaviors();
return sem;