#include "src/tint/lang/core/constant/eval.h"
#include <algorithm>
#include <iomanip>
#include <limits>
#include <optional>
#include <string>
#include <type_traits>
#include <utility>
#include "src/tint/lang/core/constant/composite.h"
#include "src/tint/lang/core/constant/scalar.h"
#include "src/tint/lang/core/constant/splat.h"
#include "src/tint/lang/core/constant/value.h"
#include "src/tint/lang/core/fluent_types.h"
#include "src/tint/lang/core/number.h"
#include "src/tint/lang/core/type/abstract_float.h"
#include "src/tint/lang/core/type/abstract_int.h"
#include "src/tint/lang/core/type/bool.h"
#include "src/tint/lang/core/type/f16.h"
#include "src/tint/lang/core/type/f32.h"
#include "src/tint/lang/core/type/i32.h"
#include "src/tint/lang/core/type/matrix.h"
#include "src/tint/lang/core/type/struct.h"
#include "src/tint/lang/core/type/u32.h"
#include "src/tint/lang/core/type/vector.h"
#include "src/tint/utils/containers/map.h"
#include "src/tint/utils/containers/transform.h"
#include "src/tint/utils/diagnostic/diagnostic.h"
#include "src/tint/utils/macros/compiler.h"
#include "src/tint/utils/memory/bitcast.h"
#include "src/tint/utils/rtti/switch.h"
#include "src/tint/utils/text/string_stream.h"
usingnamespacetint::core::fluent_types;
usingnamespacetint::core::number_suffixes;
namespace tint::core::constant {
namespace {
template <typename T>
T First(T&& first, ...) { … }
template <typename F, typename... CONSTANTS>
auto Dispatch_iu32(F&& f, CONSTANTS&&... cs) { … }
template <typename F, typename... CONSTANTS>
auto Dispatch_ia_iu32(F&& f, CONSTANTS&&... cs) { … }
template <typename F, typename... CONSTANTS>
auto Dispatch_ia_iu32_bool(F&& f, CONSTANTS&&... cs) { … }
template <typename F, typename... CONSTANTS>
auto Dispatch_fia_fi32_f16(F&& f, CONSTANTS&&... cs) { … }
template <typename F, typename... CONSTANTS>
auto Dispatch_fia_fiu32_f16(F&& f, CONSTANTS&&... cs) { … }
template <typename F, typename... CONSTANTS>
auto Dispatch_fia_fiu32_f16_bool(F&& f, CONSTANTS&&... cs) { … }
template <typename F, typename... CONSTANTS>
auto Dispatch_fa_f32_f16(F&& f, CONSTANTS&&... cs) { … }
template <typename F, typename... CONSTANTS>
auto Dispatch_bool(F&& f, CONSTANTS&&... cs) { … }
template <typename F>
auto ZeroTypeDispatch(const core::type::Type* type, F&& f) { … }
template <typename NumberT>
std::string OverflowErrorMessage(NumberT lhs, const char* op, NumberT rhs) { … }
template <typename VALUE_TY>
std::string OverflowErrorMessage(VALUE_TY value, std::string_view target_ty) { … }
template <typename NumberT>
std::string OverflowExpErrorMessage(std::string_view base, NumberT exp) { … }
template <typename T>
std::make_unsigned_t<T> CountLeadingBits(T e, T bit_value_to_count) { … }
template <typename T>
std::make_unsigned_t<T> CountTrailingBits(T e, T bit_value_to_count) { … }
struct ConvertContext { … };
template <typename T>
const ScalarBase* ScalarConvert(const Scalar<T>* scalar,
const core::type::Type* target_ty,
ConvertContext& ctx) { … }
const Value* ConvertInternal(const Value* root_value,
const core::type::Type* root_target_ty,
ConvertContext& ctx) { … }
template <typename F, typename... CONSTANTS>
tint::traits::EnableIf<tint::traits::IsType<size_t, tint::traits::LastParameterType<F>>,
Eval::Result>
TransformElements(Manager& mgr,
const core::type::Type* composite_ty,
const F& f,
size_t index,
CONSTANTS&&... cs) { … }
UnaryTransform;
Eval::Result TransformUnaryElements(Manager& mgr,
const core::type::Type* composite_ty,
const UnaryTransform& f,
const Value* c0) { … }
BinaryTransform;
Eval::Result TransformBinaryElements(Manager& mgr,
const core::type::Type* composite_ty,
const BinaryTransform& f,
const Value* c0,
const Value* c1) { … }
Eval::Result TransformBinaryDifferingArityElements(Manager& mgr,
const core::type::Type* composite_ty,
const BinaryTransform& f,
const Value* c0,
const Value* c1) { … }
TernaryTransform;
Eval::Result TransformTernaryElements(Manager& mgr,
const core::type::Type* composite_ty,
const TernaryTransform& f,
const Value* c0,
const Value* c1,
const Value* c2) { … }
}
Eval::Eval(Manager& manager, diag::List& diagnostics, bool use_runtime_semantics )
: … { … }
template <typename T>
Eval::Result Eval::CreateScalar(const Source& source, const core::type::Type* t, T v) { … }
template <typename NumberT>
tint::Result<NumberT, Eval::Error> Eval::Add(const Source& source, NumberT a, NumberT b) { … }
template <typename NumberT>
tint::Result<NumberT, Eval::Error> Eval::Sub(const Source& source, NumberT a, NumberT b) { … }
template <typename NumberT>
tint::Result<NumberT, Eval::Error> Eval::Mul(const Source& source, NumberT a, NumberT b) { … }
template <typename NumberT>
tint::Result<NumberT, Eval::Error> Eval::Div(const Source& source, NumberT a, NumberT b) { … }
template <typename NumberT>
tint::Result<NumberT, Eval::Error> Eval::Mod(const Source& source, NumberT a, NumberT b) { … }
template <typename NumberT>
tint::Result<NumberT, Eval::Error> Eval::Dot2(const Source& source,
NumberT a1,
NumberT a2,
NumberT b1,
NumberT b2) { … }
template <typename NumberT>
tint::Result<NumberT, Eval::Error> Eval::Dot3(const Source& source,
NumberT a1,
NumberT a2,
NumberT a3,
NumberT b1,
NumberT b2,
NumberT b3) { … }
template <typename NumberT>
tint::Result<NumberT, Eval::Error> Eval::Dot4(const Source& source,
NumberT a1,
NumberT a2,
NumberT a3,
NumberT a4,
NumberT b1,
NumberT b2,
NumberT b3,
NumberT b4) { … }
template <typename NumberT>
tint::Result<NumberT, Eval::Error> Eval::Det2(const Source& source,
NumberT a,
NumberT b,
NumberT c,
NumberT d) { … }
template <typename NumberT>
tint::Result<NumberT, Eval::Error> Eval::Det3(const Source& source,
NumberT a,
NumberT b,
NumberT c,
NumberT d,
NumberT e,
NumberT f,
NumberT g,
NumberT h,
NumberT i) { … }
template <typename NumberT>
tint::Result<NumberT, Eval::Error> Eval::Det4(const Source& source,
NumberT a,
NumberT b,
NumberT c,
NumberT d,
NumberT e,
NumberT f,
NumberT g,
NumberT h,
NumberT i,
NumberT j,
NumberT k,
NumberT l,
NumberT m,
NumberT n,
NumberT o,
NumberT p) { … }
template <typename NumberT>
tint::Result<NumberT, Eval::Error> Eval::Sqrt(const Source& source, NumberT v) { … }
auto Eval::SqrtFunc(const Source& source, const core::type::Type* elem_ty) { … }
template <typename NumberT>
tint::Result<NumberT, Eval::Error> Eval::Clamp(const Source& source,
NumberT e,
NumberT low,
NumberT high) { … }
auto Eval::ClampFunc(const Source& source, const core::type::Type* elem_ty) { … }
auto Eval::AddFunc(const Source& source, const core::type::Type* elem_ty) { … }
auto Eval::SubFunc(const Source& source, const core::type::Type* elem_ty) { … }
auto Eval::MulFunc(const Source& source, const core::type::Type* elem_ty) { … }
auto Eval::DivFunc(const Source& source, const core::type::Type* elem_ty) { … }
auto Eval::ModFunc(const Source& source, const core::type::Type* elem_ty) { … }
auto Eval::Dot2Func(const Source& source, const core::type::Type* elem_ty) { … }
auto Eval::Dot3Func(const Source& source, const core::type::Type* elem_ty) { … }
auto Eval::Dot4Func(const Source& source, const core::type::Type* elem_ty) { … }
Eval::Result Eval::Dot(const Source& source, const Value* v1, const Value* v2) { … }
Eval::Result Eval::Length(const Source& source, const core::type::Type* ty, const Value* c0) { … }
Eval::Result Eval::Mul(const Source& source,
const core::type::Type* ty,
const Value* v1,
const Value* v2) { … }
Eval::Result Eval::Sub(const Source& source,
const core::type::Type* ty,
const Value* v1,
const Value* v2) { … }
auto Eval::Det2Func(const Source& source, const core::type::Type* elem_ty) { … }
auto Eval::Det3Func(const Source& source, const core::type::Type* elem_ty) { … }
auto Eval::Det4Func(const Source& source, const core::type::Type* elem_ty) { … }
Eval::Result Eval::ArrayOrStructCtor(const core::type::Type* ty, VectorRef<const Value*> args) { … }
Eval::Result Eval::Conv(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::Zero(const core::type::Type* ty, VectorRef<const Value*>, const Source&) { … }
Eval::Result Eval::Identity(const core::type::Type*, VectorRef<const Value*> args, const Source&) { … }
Eval::Result Eval::VecSplat(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source&) { … }
Eval::Result Eval::VecInitS(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source&) { … }
Eval::Result Eval::VecInitM(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source&) { … }
Eval::Result Eval::MatInitS(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source&) { … }
Eval::Result Eval::MatInitV(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source&) { … }
Eval::Result Eval::Index(const Value* obj_val,
const core::type::Type* obj_ty,
const Value* idx_val,
const Source& idx_source) { … }
Eval::Result Eval::Swizzle(const core::type::Type* ty,
const Value* object,
VectorRef<uint32_t> indices) { … }
Eval::Result Eval::bitcast(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::Complement(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::UnaryMinus(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::Not(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::Plus(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::Minus(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::Multiply(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::MultiplyMatVec(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::MultiplyVecMat(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::MultiplyMatMat(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::Divide(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::Modulo(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::Equal(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::NotEqual(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::LessThan(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::GreaterThan(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::LessThanEqual(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::GreaterThanEqual(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::LogicalAnd(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::LogicalOr(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::And(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::Or(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::Xor(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::ShiftLeft(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::ShiftRight(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::abs(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::acos(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::acosh(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::all(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::any(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::asin(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::asinh(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::atan(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::atanh(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::atan2(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::ceil(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::clamp(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::cos(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::cosh(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::countLeadingZeros(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::countOneBits(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::countTrailingZeros(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::cross(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::degrees(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::determinant(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::distance(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::dot(const core::type::Type*,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::dot4I8Packed(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::dot4U8Packed(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::exp(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::exp2(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::extractBits(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::faceForward(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::firstLeadingBit(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::firstTrailingBit(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::floor(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::fma(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::fract(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::frexp(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::insertBits(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::inverseSqrt(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::ldexp(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::length(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::log(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::log2(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::max(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::min(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::mix(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::modf(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::normalize(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::pack2x16float(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::pack2x16snorm(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::pack2x16unorm(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::pack4x8snorm(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::pack4x8unorm(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::pack4xI8(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::pack4xU8(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::pack4xI8Clamp(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::pack4xU8Clamp(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::pow(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::radians(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::reflect(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::refract(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::reverseBits(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::round(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::saturate(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::select_bool(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::select_boolvec(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::sign(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::sin(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::sinh(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::smoothstep(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::step(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::sqrt(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::tan(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::tanh(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::transpose(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source&) { … }
Eval::Result Eval::trunc(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::unpack2x16float(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::unpack2x16snorm(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::unpack2x16unorm(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::unpack4x8snorm(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::unpack4x8unorm(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::unpack4xI8(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::unpack4xU8(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::quantizeToF16(const core::type::Type* ty,
VectorRef<const Value*> args,
const Source& source) { … }
Eval::Result Eval::Convert(const core::type::Type* target_ty,
const Value* value,
const Source& source) { … }
diag::Diagnostic& Eval::AddError(const Source& source) const { … }
diag::Diagnostic& Eval::AddWarning(const Source& source) const { … }
diag::Diagnostic& Eval::AddNote(const Source& source) const { … }
}