diff --git a/src/tint/inspector/inspector.cc b/src/tint/inspector/inspector.cc index 9a2afb8eee..569a1042e6 100644 --- a/src/tint/inspector/inspector.cc +++ b/src/tint/inspector/inspector.cc @@ -777,7 +777,7 @@ void Inspector::GenerateSamplerTargets() { continue; } - auto* call = sem.Get(c); + auto* call = sem.Get(c)->UnwrapMaterialize()->As(); if (!call) { continue; } diff --git a/src/tint/reader/spirv/parser_impl_barrier_test.cc b/src/tint/reader/spirv/parser_impl_barrier_test.cc index 0549bd1898..fdfa3bf681 100644 --- a/src/tint/reader/spirv/parser_impl_barrier_test.cc +++ b/src/tint/reader/spirv/parser_impl_barrier_test.cc @@ -69,7 +69,7 @@ TEST_F(SpvParserTest, WorkgroupBarrier) { auto* call = helper->body->statements[0]->As(); ASSERT_NE(call, nullptr); EXPECT_EQ(call->expr->args.size(), 0u); - auto* sem_call = program.Sem().Get(call->expr); + auto* sem_call = program.Sem().Get(call->expr); ASSERT_NE(sem_call, nullptr); auto* builtin = sem_call->Target()->As(); ASSERT_NE(builtin, nullptr); @@ -102,7 +102,7 @@ TEST_F(SpvParserTest, StorageBarrier) { auto* call = helper->body->statements[0]->As(); ASSERT_NE(call, nullptr); EXPECT_EQ(call->expr->args.size(), 0u); - auto* sem_call = program.Sem().Get(call->expr); + auto* sem_call = program.Sem().Get(call->expr); ASSERT_NE(sem_call, nullptr); auto* builtin = sem_call->Target()->As(); ASSERT_NE(builtin, nullptr); diff --git a/src/tint/resolver/builtin_test.cc b/src/tint/resolver/builtin_test.cc index 6020eae9af..74a898ca70 100644 --- a/src/tint/resolver/builtin_test.cc +++ b/src/tint/resolver/builtin_test.cc @@ -1924,7 +1924,7 @@ TEST_P(ResolverBuiltinTest_Texture, Call) { } } - auto* call_sem = Sem().Get(call); + auto* call_sem = Sem().Get(call); ASSERT_NE(call_sem, nullptr); auto* target = call_sem->Target(); ASSERT_NE(target, nullptr); diff --git a/src/tint/resolver/call_test.cc b/src/tint/resolver/call_test.cc index d84f300075..39a6eb490c 100644 --- a/src/tint/resolver/call_test.cc +++ b/src/tint/resolver/call_test.cc @@ -94,7 +94,7 @@ TEST_F(ResolverCallTest, Valid) { EXPECT_TRUE(r()->Resolve()) << r()->error(); - auto* call = Sem().Get(call_expr); + auto* call = Sem().Get(call_expr); EXPECT_NE(call, nullptr); EXPECT_EQ(call->Target(), Sem().Get(func)); } @@ -106,7 +106,7 @@ TEST_F(ResolverCallTest, OutOfOrder) { EXPECT_TRUE(r()->Resolve()) << r()->error(); - auto* call = Sem().Get(call_expr); + auto* call = Sem().Get(call_expr); EXPECT_NE(call, nullptr); EXPECT_EQ(call->Target(), Sem().Get(b)); } diff --git a/src/tint/resolver/type_constructor_validation_test.cc b/src/tint/resolver/type_constructor_validation_test.cc index 83978afab8..3277ee854d 100644 --- a/src/tint/resolver/type_constructor_validation_test.cc +++ b/src/tint/resolver/type_constructor_validation_test.cc @@ -318,7 +318,7 @@ TEST_P(ConversionConstructorValidTest, All) { ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* call = Sem().Get(tc); + auto* call = Sem().Get(tc); ASSERT_NE(call, nullptr); switch (params.kind) { case Kind::Construct: { @@ -440,7 +440,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Array_ZeroValue_P ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* call = Sem().Get(tc); + auto* call = Sem().Get(tc); ASSERT_NE(call, nullptr); EXPECT_TRUE(call->Type()->Is()); auto* ctor = call->Target()->As(); @@ -456,7 +456,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Array_type_match) ASSERT_TRUE(r()->Resolve()) << r()->error(); - auto* call = Sem().Get(tc); + auto* call = Sem().Get(tc); ASSERT_NE(call, nullptr); EXPECT_TRUE(call->Type()->Is()); auto* ctor = call->Target()->As(); @@ -629,7 +629,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Construct_i32_Success) { ASSERT_NE(TypeOf(expr), nullptr); ASSERT_TRUE(TypeOf(expr)->Is()); - auto* call = Sem().Get(expr); + auto* call = Sem().Get(expr); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); @@ -647,7 +647,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Construct_u32_Success) { ASSERT_NE(TypeOf(expr), nullptr); ASSERT_TRUE(TypeOf(expr)->Is()); - auto* call = Sem().Get(expr); + auto* call = Sem().Get(expr); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); @@ -665,7 +665,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Construct_f32_Success) { ASSERT_NE(TypeOf(expr), nullptr); ASSERT_TRUE(TypeOf(expr)->Is()); - auto* call = Sem().Get(expr); + auto* call = Sem().Get(expr); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); @@ -683,7 +683,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Convert_f32_to_i32_Success) { ASSERT_NE(TypeOf(expr), nullptr); ASSERT_TRUE(TypeOf(expr)->Is()); - auto* call = Sem().Get(expr); + auto* call = Sem().Get(expr); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); @@ -701,7 +701,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Convert_i32_to_u32_Success) { ASSERT_NE(TypeOf(expr), nullptr); ASSERT_TRUE(TypeOf(expr)->Is()); - auto* call = Sem().Get(expr); + auto* call = Sem().Get(expr); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); @@ -719,7 +719,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Convert_u32_to_f32_Success) { ASSERT_NE(TypeOf(expr), nullptr); ASSERT_TRUE(TypeOf(expr)->Is()); - auto* call = Sem().Get(expr); + auto* call = Sem().Get(expr); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); @@ -831,7 +831,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec2_Success_Zero EXPECT_TRUE(TypeOf(tc)->As()->type()->Is()); EXPECT_EQ(TypeOf(tc)->As()->Width(), 2u); - auto* call = Sem().Get(tc); + auto* call = Sem().Get(tc); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); @@ -850,7 +850,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec2F32_Success_S EXPECT_TRUE(TypeOf(tc)->As()->type()->Is()); EXPECT_EQ(TypeOf(tc)->As()->Width(), 2u); - auto* call = Sem().Get(tc); + auto* call = Sem().Get(tc); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); @@ -871,7 +871,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec2U32_Success_S EXPECT_TRUE(TypeOf(tc)->As()->type()->Is()); EXPECT_EQ(TypeOf(tc)->As()->Width(), 2u); - auto* call = Sem().Get(tc); + auto* call = Sem().Get(tc); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); @@ -892,7 +892,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec2I32_Success_S EXPECT_TRUE(TypeOf(tc)->As()->type()->Is()); EXPECT_EQ(TypeOf(tc)->As()->Width(), 2u); - auto* call = Sem().Get(tc); + auto* call = Sem().Get(tc); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); @@ -913,7 +913,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec2Bool_Success_ EXPECT_TRUE(TypeOf(tc)->As()->type()->Is()); EXPECT_EQ(TypeOf(tc)->As()->Width(), 2u); - auto* call = Sem().Get(tc); + auto* call = Sem().Get(tc); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); @@ -934,7 +934,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec2_Success_Iden EXPECT_TRUE(TypeOf(tc)->As()->type()->Is()); EXPECT_EQ(TypeOf(tc)->As()->Width(), 2u); - auto* call = Sem().Get(tc); + auto* call = Sem().Get(tc); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); @@ -954,7 +954,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec2_Success_Vec2 EXPECT_TRUE(TypeOf(tc)->As()->type()->Is()); EXPECT_EQ(TypeOf(tc)->As()->Width(), 2u); - auto* call = Sem().Get(tc); + auto* call = Sem().Get(tc); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); @@ -1079,7 +1079,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec3_Success_Zero EXPECT_TRUE(TypeOf(tc)->As()->type()->Is()); EXPECT_EQ(TypeOf(tc)->As()->Width(), 3u); - auto* call = Sem().Get(tc); + auto* call = Sem().Get(tc); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); @@ -1098,7 +1098,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec3F32_Success_S EXPECT_TRUE(TypeOf(tc)->As()->type()->Is()); EXPECT_EQ(TypeOf(tc)->As()->Width(), 3u); - auto* call = Sem().Get(tc); + auto* call = Sem().Get(tc); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); @@ -1120,7 +1120,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec3U32_Success_S EXPECT_TRUE(TypeOf(tc)->As()->type()->Is()); EXPECT_EQ(TypeOf(tc)->As()->Width(), 3u); - auto* call = Sem().Get(tc); + auto* call = Sem().Get(tc); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); @@ -1142,7 +1142,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec3I32_Success_S EXPECT_TRUE(TypeOf(tc)->As()->type()->Is()); EXPECT_EQ(TypeOf(tc)->As()->Width(), 3u); - auto* call = Sem().Get(tc); + auto* call = Sem().Get(tc); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); @@ -1164,7 +1164,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec3Bool_Success_ EXPECT_TRUE(TypeOf(tc)->As()->type()->Is()); EXPECT_EQ(TypeOf(tc)->As()->Width(), 3u); - auto* call = Sem().Get(tc); + auto* call = Sem().Get(tc); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); @@ -1186,7 +1186,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec3_Success_Vec2 EXPECT_TRUE(TypeOf(tc)->As()->type()->Is()); EXPECT_EQ(TypeOf(tc)->As()->Width(), 3u); - auto* call = Sem().Get(tc); + auto* call = Sem().Get(tc); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); @@ -1207,7 +1207,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec3_Success_Scal EXPECT_TRUE(TypeOf(tc)->As()->type()->Is()); EXPECT_EQ(TypeOf(tc)->As()->Width(), 3u); - auto* call = Sem().Get(tc); + auto* call = Sem().Get(tc); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); @@ -1228,7 +1228,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec3_Success_Iden EXPECT_TRUE(TypeOf(tc)->As()->type()->Is()); EXPECT_EQ(TypeOf(tc)->As()->Width(), 3u); - auto* call = Sem().Get(tc); + auto* call = Sem().Get(tc); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); @@ -1248,7 +1248,7 @@ TEST_F(ResolverTypeConstructorValidationTest, Expr_Constructor_Vec3_Success_Vec3 EXPECT_TRUE(TypeOf(tc)->As()->type()->Is()); EXPECT_EQ(TypeOf(tc)->As()->Width(), 3u); - auto* call = Sem().Get(tc); + auto* call = Sem().Get(tc); ASSERT_NE(call, nullptr); auto* ctor = call->Target()->As(); ASSERT_NE(ctor, nullptr); diff --git a/src/tint/resolver/uniformity.cc b/src/tint/resolver/uniformity.cc index 273a07e44e..6188521808 100644 --- a/src/tint/resolver/uniformity.cc +++ b/src/tint/resolver/uniformity.cc @@ -1162,7 +1162,7 @@ class UniformityGraph { // Get tags for the callee. CallSiteTag callsite_tag = CallSiteNoRestriction; FunctionTag function_tag = NoRestriction; - auto* sem = sem_.Get(call); + auto* sem = SemCall(call); const FunctionInfo* func_info = nullptr; Switch( sem->Target(), @@ -1313,7 +1313,7 @@ class UniformityGraph { /// Recursively descend through the function called by `call` and the functions that it calls in /// order to find a call to a builtin function that requires uniformity. const ast::CallExpression* FindBuiltinThatRequiresUniformity(const ast::CallExpression* call) { - auto* target = sem_.Get(call)->Target(); + auto* target = SemCall(call)->Target(); if (target->Is()) { // This is a call to a builtin, so we must be done. return call; @@ -1362,7 +1362,7 @@ class UniformityGraph { call->args[idx]->source); // Recurse into the target function. - if (auto* user = sem_.Get(call)->Target()->As()) { + if (auto* user = SemCall(call)->Target()->As()) { auto& callee = functions_.at(user->Declaration()); ShowCauseOfNonUniformity(callee, callee.cf_return, callee.parameters[idx].init_value); @@ -1427,7 +1427,7 @@ class UniformityGraph { c->source); // Recurse into the target function. - if (auto* user = sem_.Get(c)->Target()->As()) { + if (auto* user = SemCall(c)->Target()->As()) { auto& callee = functions_.at(user->Declaration()); ShowCauseOfNonUniformity(callee, callee.cf_return, callee.may_be_non_uniform); @@ -1489,7 +1489,7 @@ class UniformityGraph { // The node will always have a corresponding call expression. auto* call = cause->ast->As(); TINT_ASSERT(Resolver, call); - auto* target = sem_.Get(call)->Target(); + auto* target = SemCall(call)->Target(); std::string func_name; if (auto* builtin = target->As()) { @@ -1521,14 +1521,17 @@ class UniformityGraph { // causes the uniformity requirement. auto* innermost_call = FindBuiltinThatRequiresUniformity(call); if (innermost_call != call) { + auto* sem_call = SemCall(call); + auto* sem_innermost_call = SemCall(innermost_call); + // Determine whether the builtin is being called directly or indirectly. bool indirect = false; - if (sem_.Get(call)->Target()->As() != - sem_.Get(innermost_call)->Stmt()->Function()) { + if (sem_call->Target()->As() != + sem_innermost_call->Stmt()->Function()) { indirect = true; } - auto* builtin = sem_.Get(innermost_call)->Target()->As(); + auto* builtin = sem_innermost_call->Target()->As(); diagnostics_.add_note(diag::System::Resolver, "'" + func_name + "' requires uniformity because it " + (indirect ? "indirectly " : "") + "calls " + @@ -1543,6 +1546,11 @@ class UniformityGraph { function.may_be_non_uniform); } } + + // Helper for obtaining the sem::Call node for the ast::CallExpression + const sem::Call* SemCall(const ast::CallExpression* expr) const { + return sem_.Get(expr)->UnwrapMaterialize()->As(); + } }; } // namespace diff --git a/src/tint/sem/type_mappings.h b/src/tint/sem/type_mappings.h index 8425f149f7..e66acdd0bb 100644 --- a/src/tint/sem/type_mappings.h +++ b/src/tint/sem/type_mappings.h @@ -59,7 +59,6 @@ namespace tint::sem { struct TypeMappings { //! @cond Doxygen_Suppress Array* operator()(ast::Array*); - Call* operator()(ast::CallExpression*); Expression* operator()(ast::Expression*); ForLoopStatement* operator()(ast::ForLoopStatement*); Function* operator()(ast::Function*); diff --git a/src/tint/transform/array_length_from_uniform.cc b/src/tint/transform/array_length_from_uniform.cc index dc19c5c6ae..86c45345d8 100644 --- a/src/tint/transform/array_length_from_uniform.cc +++ b/src/tint/transform/array_length_from_uniform.cc @@ -52,7 +52,7 @@ static void IterateArrayLengthOnStorageVar(CloneContext& ctx, F&& functor) { continue; } - auto* call = sem.Get(call_expr); + auto* call = sem.Get(call_expr)->UnwrapMaterialize()->As(); auto* builtin = call->Target()->As(); if (!builtin || builtin->Type() != sem::BuiltinType::kArrayLength) { continue; diff --git a/src/tint/transform/calculate_array_length.cc b/src/tint/transform/calculate_array_length.cc index 42a212c8c1..bdda1cd43b 100644 --- a/src/tint/transform/calculate_array_length.cc +++ b/src/tint/transform/calculate_array_length.cc @@ -123,7 +123,7 @@ void CalculateArrayLength::Run(CloneContext& ctx, const DataMap&, DataMap&) cons // Find all the arrayLength() calls... for (auto* node : ctx.src->ASTNodes().Objects()) { if (auto* call_expr = node->As()) { - auto* call = sem.Get(call_expr); + auto* call = sem.Get(call_expr)->UnwrapMaterialize()->As(); if (auto* builtin = call->Target()->As()) { if (builtin->Type() == sem::BuiltinType::kArrayLength) { // We're dealing with an arrayLength() call diff --git a/src/tint/transform/combine_samplers.cc b/src/tint/transform/combine_samplers.cc index 66b5b93768..c9d4913b99 100644 --- a/src/tint/transform/combine_samplers.cc +++ b/src/tint/transform/combine_samplers.cc @@ -220,7 +220,7 @@ struct CombineSamplers::State { // sampler parameters to use the current function's combined samplers or // the combined global samplers, as appropriate. ctx.ReplaceAll([&](const ast::CallExpression* expr) -> const ast::Expression* { - if (auto* call = sem.Get(expr)) { + if (auto* call = sem.Get(expr)->UnwrapMaterialize()->As()) { ast::ExpressionList args; // Replace all texture builtin calls. if (auto* builtin = call->Target()->As()) { diff --git a/src/tint/transform/decompose_memory_access.cc b/src/tint/transform/decompose_memory_access.cc index 66c60737ab..775cc05f63 100644 --- a/src/tint/transform/decompose_memory_access.cc +++ b/src/tint/transform/decompose_memory_access.cc @@ -882,7 +882,7 @@ void DecomposeMemoryAccess::Run(CloneContext& ctx, const DataMap&, DataMap&) con } if (auto* call_expr = node->As()) { - auto* call = sem.Get(call_expr); + auto* call = sem.Get(call_expr)->UnwrapMaterialize()->As(); if (auto* builtin = call->Target()->As()) { if (builtin->Type() == sem::BuiltinType::kArrayLength) { // arrayLength(X) diff --git a/src/tint/transform/decompose_strided_array.cc b/src/tint/transform/decompose_strided_array.cc index bf36c06fd2..ba6252b025 100644 --- a/src/tint/transform/decompose_strided_array.cc +++ b/src/tint/transform/decompose_strided_array.cc @@ -115,7 +115,7 @@ void DecomposeStridedArray::Run(CloneContext& ctx, const DataMap&, DataMap&) con // `array(strided_arr(1), strided_arr(2), strided_arr(3))` ctx.ReplaceAll([&](const ast::CallExpression* expr) -> const ast::Expression* { if (!expr->args.empty()) { - if (auto* call = sem.Get(expr)) { + if (auto* call = sem.Get(expr)->UnwrapMaterialize()->As()) { if (auto* ctor = call->Target()->As()) { if (auto* arr = ctor->ReturnType()->As()) { // Begin by cloning the array constructor type or name diff --git a/src/tint/transform/multiplanar_external_texture.cc b/src/tint/transform/multiplanar_external_texture.cc index 0bc507e0fc..2a9e20e9a0 100644 --- a/src/tint/transform/multiplanar_external_texture.cc +++ b/src/tint/transform/multiplanar_external_texture.cc @@ -184,7 +184,8 @@ struct MultiplanarExternalTexture::State { // Transform the original textureLoad and textureSampleLevel calls into // textureLoadExternal and textureSampleExternal calls. ctx.ReplaceAll([&](const ast::CallExpression* expr) -> const ast::CallExpression* { - auto* builtin = sem.Get(expr)->Target()->As(); + auto* call = sem.Get(expr)->UnwrapMaterialize()->As(); + auto* builtin = call->Target()->As(); if (builtin && !builtin->Parameters().empty() && builtin->Parameters()[0]->Type()->Is() && @@ -209,7 +210,7 @@ struct MultiplanarExternalTexture::State { } } - } else if (sem.Get(expr)->Target()->Is()) { + } else if (call->Target()->Is()) { // The call expression may be to a user-defined function that // contains a texture_external parameter. These need to be expanded // out to multiple plane textures and the texture parameters diff --git a/src/tint/transform/promote_initializers_to_const_var.cc b/src/tint/transform/promote_initializers_to_const_var.cc index 81b5603373..6e0ba55ccc 100644 --- a/src/tint/transform/promote_initializers_to_const_var.cc +++ b/src/tint/transform/promote_initializers_to_const_var.cc @@ -33,7 +33,7 @@ void PromoteInitializersToConstVar::Run(CloneContext& ctx, const DataMap&, DataM // Hoists array and structure initializers to a constant variable, declared // just before the statement of usage. auto type_ctor_to_let = [&](const ast::CallExpression* expr) { - auto* ctor = ctx.src->Sem().Get(expr); + auto* ctor = ctx.src->Sem().Get(expr)->UnwrapMaterialize()->As(); if (!ctor->Target()->Is()) { return true; } diff --git a/src/tint/transform/remove_phonies.cc b/src/tint/transform/remove_phonies.cc index dc5c092012..7ca1194487 100644 --- a/src/tint/transform/remove_phonies.cc +++ b/src/tint/transform/remove_phonies.cc @@ -86,12 +86,19 @@ void RemovePhonies::Run(CloneContext& ctx, const DataMap&, DataMap&) const { if (stmt->lhs->Is()) { std::vector side_effects; if (!ast::TraverseExpressions( - stmt->rhs, ctx.dst->Diagnostics(), [&](const ast::CallExpression* call) { + stmt->rhs, ctx.dst->Diagnostics(), [&](const ast::CallExpression* expr) { // ast::CallExpression may map to a function or builtin call // (both may have side-effects), or a type constructor or // type conversion (both do not have side effects). - if (sem.Get(call)->Target()->IsAnyOf()) { - side_effects.push_back(call); + auto* call = sem.Get(expr); + if (!call) { + // Semantic node must be a Materialize, in which case the expression + // was creation-time (compile time), so could not have side effects. + // Just skip. + return ast::TraverseAction::Skip; + } + if (call->Target()->IsAnyOf()) { + side_effects.push_back(expr); return ast::TraverseAction::Skip; } return ast::TraverseAction::Descend; diff --git a/src/tint/transform/renamer.cc b/src/tint/transform/renamer.cc index 50cd781a6a..562a52fc7f 100644 --- a/src/tint/transform/renamer.cc +++ b/src/tint/transform/renamer.cc @@ -1278,7 +1278,7 @@ Output Renamer::Run(const Program* in, const DataMap& inputs) const { } } } else if (auto* call = node->As()) { - auto* sem = in->Sem().Get(call); + auto* sem = in->Sem().Get(call)->UnwrapMaterialize()->As(); if (!sem) { TINT_ICE(Transform, out.Diagnostics()) << "CallExpression has no semantic info"; continue; diff --git a/src/tint/transform/robustness.cc b/src/tint/transform/robustness.cc index 46624b609a..aab1e0cc00 100644 --- a/src/tint/transform/robustness.cc +++ b/src/tint/transform/robustness.cc @@ -206,7 +206,7 @@ struct Robustness::State { /// @return the clamped replacement call expression, or nullptr if `expr` /// should be cloned without changes. const ast::CallExpression* Transform(const ast::CallExpression* expr) { - auto* call = ctx.src->Sem().Get(expr); + auto* call = ctx.src->Sem().Get(expr)->UnwrapMaterialize()->As(); auto* call_target = call->Target(); auto* builtin = call_target->As(); if (!builtin || !TextureBuiltinNeedsClamping(builtin->Type())) { diff --git a/src/tint/transform/vectorize_scalar_matrix_constructors.cc b/src/tint/transform/vectorize_scalar_matrix_constructors.cc index c22506e949..9cd9757bbb 100644 --- a/src/tint/transform/vectorize_scalar_matrix_constructors.cc +++ b/src/tint/transform/vectorize_scalar_matrix_constructors.cc @@ -49,7 +49,7 @@ void VectorizeScalarMatrixConstructors::Run(CloneContext& ctx, const DataMap&, D std::unordered_map scalar_ctors; ctx.ReplaceAll([&](const ast::CallExpression* expr) -> const ast::CallExpression* { - auto* call = ctx.src->Sem().Get(expr); + auto* call = ctx.src->Sem().Get(expr)->UnwrapMaterialize()->As(); auto* ty_ctor = call->Target()->As(); if (!ty_ctor) { return nullptr; diff --git a/src/tint/transform/wrap_arrays_in_structs.cc b/src/tint/transform/wrap_arrays_in_structs.cc index b1dc5e8ab4..eb133d784e 100644 --- a/src/tint/transform/wrap_arrays_in_structs.cc +++ b/src/tint/transform/wrap_arrays_in_structs.cc @@ -83,7 +83,7 @@ void WrapArraysInStructs::Run(CloneContext& ctx, const DataMap&, DataMap&) const // Fix up array constructors so `A(1,2)` becomes `tint_array_wrapper(A(1,2))` ctx.ReplaceAll([&](const ast::CallExpression* expr) -> const ast::Expression* { - if (auto* call = sem.Get(expr)) { + if (auto* call = sem.Get(expr)->UnwrapMaterialize()->As()) { if (auto* ctor = call->Target()->As()) { if (auto* array = ctor->ReturnType()->As()) { if (auto w = wrapper(array)) { diff --git a/src/tint/writer/append_vector_test.cc b/src/tint/writer/append_vector_test.cc index 46a135f291..8169039210 100644 --- a/src/tint/writer/append_vector_test.cc +++ b/src/tint/writer/append_vector_test.cc @@ -46,7 +46,7 @@ TEST_F(AppendVectorTest, Vec2i32_i32) { EXPECT_EQ(vec_123->args[1], scalar_2); EXPECT_EQ(vec_123->args[2], scalar_3); - auto* call = Sem().Get(vec_123); + auto* call = Sem().Get(vec_123); ASSERT_NE(call, nullptr); ASSERT_EQ(call->Arguments().size(), 3u); EXPECT_EQ(call->Arguments()[0], Sem().Get(scalar_1)); @@ -90,7 +90,7 @@ TEST_F(AppendVectorTest, Vec2i32_u32) { ASSERT_EQ(u32_to_i32->args.size(), 1u); EXPECT_EQ(u32_to_i32->args[0], scalar_3); - auto* call = Sem().Get(vec_123); + auto* call = Sem().Get(vec_123); ASSERT_NE(call, nullptr); ASSERT_EQ(call->Arguments().size(), 3u); EXPECT_EQ(call->Arguments()[0], Sem().Get(scalar_1)); @@ -142,7 +142,7 @@ TEST_F(AppendVectorTest, Vec2i32FromVec2u32_u32) { ASSERT_EQ(u32_to_i32->args.size(), 1u); EXPECT_EQ(u32_to_i32->args[0], scalar_3); - auto* call = Sem().Get(vec_123); + auto* call = Sem().Get(vec_123); ASSERT_NE(call, nullptr); ASSERT_EQ(call->Arguments().size(), 2u); EXPECT_EQ(call->Arguments()[0], Sem().Get(vec_12)); @@ -184,7 +184,7 @@ TEST_F(AppendVectorTest, Vec2i32_f32) { ASSERT_EQ(f32_to_i32->args.size(), 1u); EXPECT_EQ(f32_to_i32->args[0], scalar_3); - auto* call = Sem().Get(vec_123); + auto* call = Sem().Get(vec_123); ASSERT_NE(call, nullptr); ASSERT_EQ(call->Arguments().size(), 3u); EXPECT_EQ(call->Arguments()[0], Sem().Get(scalar_1)); @@ -226,7 +226,7 @@ TEST_F(AppendVectorTest, Vec3i32_i32) { EXPECT_EQ(vec_1234->args[2], scalar_3); EXPECT_EQ(vec_1234->args[3], scalar_4); - auto* call = Sem().Get(vec_1234); + auto* call = Sem().Get(vec_1234); ASSERT_NE(call, nullptr); ASSERT_EQ(call->Arguments().size(), 4u); EXPECT_EQ(call->Arguments()[0], Sem().Get(scalar_1)); @@ -266,7 +266,7 @@ TEST_F(AppendVectorTest, Vec2i32Var_i32) { EXPECT_EQ(vec_123->args[0], vec_12); EXPECT_EQ(vec_123->args[1], scalar_3); - auto* call = Sem().Get(vec_123); + auto* call = Sem().Get(vec_123); ASSERT_NE(call, nullptr); ASSERT_EQ(call->Arguments().size(), 2u); EXPECT_EQ(call->Arguments()[0], Sem().Get(vec_12)); @@ -305,7 +305,7 @@ TEST_F(AppendVectorTest, Vec2i32_i32Var) { EXPECT_EQ(vec_123->args[1], scalar_2); EXPECT_EQ(vec_123->args[2], scalar_3); - auto* call = Sem().Get(vec_123); + auto* call = Sem().Get(vec_123); ASSERT_NE(call, nullptr); ASSERT_EQ(call->Arguments().size(), 3u); EXPECT_EQ(call->Arguments()[0], Sem().Get(scalar_1)); @@ -344,7 +344,7 @@ TEST_F(AppendVectorTest, Vec2i32Var_i32Var) { EXPECT_EQ(vec_123->args[0], vec_12); EXPECT_EQ(vec_123->args[1], scalar_3); - auto* call = Sem().Get(vec_123); + auto* call = Sem().Get(vec_123); ASSERT_NE(call, nullptr); ASSERT_EQ(call->Arguments().size(), 2u); EXPECT_EQ(call->Arguments()[0], Sem().Get(vec_12)); @@ -385,7 +385,7 @@ TEST_F(AppendVectorTest, Vec2i32Var_f32Var) { ASSERT_EQ(f32_to_i32->args.size(), 1u); EXPECT_EQ(f32_to_i32->args[0], scalar_3); - auto* call = Sem().Get(vec_123); + auto* call = Sem().Get(vec_123); ASSERT_NE(call, nullptr); ASSERT_EQ(call->Arguments().size(), 2u); EXPECT_EQ(call->Arguments()[0], Sem().Get(vec_12)); @@ -422,7 +422,7 @@ TEST_F(AppendVectorTest, Vec2boolVar_boolVar) { EXPECT_EQ(vec_123->args[0], vec_12); EXPECT_EQ(vec_123->args[1], scalar_3); - auto* call = Sem().Get(vec_123); + auto* call = Sem().Get(vec_123); ASSERT_NE(call, nullptr); ASSERT_EQ(call->Arguments().size(), 2u); EXPECT_EQ(call->Arguments()[0], Sem().Get(vec_12)); @@ -461,7 +461,7 @@ TEST_F(AppendVectorTest, ZeroVec3i32_i32) { } EXPECT_EQ(vec_0004->args[3], scalar); - auto* call = Sem().Get(vec_0004); + auto* call = Sem().Get(vec_0004); ASSERT_NE(call, nullptr); ASSERT_EQ(call->Arguments().size(), 4u); EXPECT_EQ(call->Arguments()[0], Sem().Get(vec_0004->args[0])); diff --git a/src/tint/writer/glsl/generator_impl.cc b/src/tint/writer/glsl/generator_impl.cc index 40b43da863..1cf74807d1 100644 --- a/src/tint/writer/glsl/generator_impl.cc +++ b/src/tint/writer/glsl/generator_impl.cc @@ -35,6 +35,7 @@ #include "src/tint/sem/depth_multisampled_texture.h" #include "src/tint/sem/depth_texture.h" #include "src/tint/sem/function.h" +#include "src/tint/sem/materialize.h" #include "src/tint/sem/member_accessor_expression.h" #include "src/tint/sem/module.h" #include "src/tint/sem/multisampled_texture.h" @@ -690,7 +691,12 @@ bool GeneratorImpl::EmitBreak(const ast::BreakStatement*) { } bool GeneratorImpl::EmitCall(std::ostream& out, const ast::CallExpression* expr) { - auto* call = builder_.Sem().Get(expr); + auto* sem = builder_.Sem().Get(expr); + if (auto* m = sem->As()) { + // TODO(crbug.com/tint/1504): Just emit the constant value. + sem = m->Expr(); + } + auto* call = sem->As(); auto* target = call->Target(); if (target->Is()) { diff --git a/src/tint/writer/glsl/generator_impl_builtin_test.cc b/src/tint/writer/glsl/generator_impl_builtin_test.cc index 1d80e6a831..7942ed5868 100644 --- a/src/tint/writer/glsl/generator_impl_builtin_test.cc +++ b/src/tint/writer/glsl/generator_impl_builtin_test.cc @@ -169,7 +169,7 @@ TEST_P(GlslBuiltinTest, Emit) { GeneratorImpl& gen = Build(); - auto* sem = program->Sem().Get(call); + auto* sem = program->Sem().Get(call); ASSERT_NE(sem, nullptr); auto* target = sem->Target(); ASSERT_NE(target, nullptr); diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc index bf67ff1530..6ee986ab5d 100644 --- a/src/tint/writer/hlsl/generator_impl.cc +++ b/src/tint/writer/hlsl/generator_impl.cc @@ -36,6 +36,7 @@ #include "src/tint/sem/depth_multisampled_texture.h" #include "src/tint/sem/depth_texture.h" #include "src/tint/sem/function.h" +#include "src/tint/sem/materialize.h" #include "src/tint/sem/member_accessor_expression.h" #include "src/tint/sem/module.h" #include "src/tint/sem/multisampled_texture.h" @@ -924,7 +925,12 @@ bool GeneratorImpl::EmitBreak(const ast::BreakStatement*) { } bool GeneratorImpl::EmitCall(std::ostream& out, const ast::CallExpression* expr) { - auto* call = builder_.Sem().Get(expr); + auto* sem = builder_.Sem().Get(expr); + if (auto* m = sem->As()) { + // TODO(crbug.com/tint/1504): Just emit the constant value. + sem = m->Expr(); + } + auto* call = sem->As(); auto* target = call->Target(); return Switch( target, [&](const sem::Function* func) { return EmitFunctionCall(out, call, func); }, diff --git a/src/tint/writer/hlsl/generator_impl_builtin_test.cc b/src/tint/writer/hlsl/generator_impl_builtin_test.cc index f6e0d987ec..532b82cf5f 100644 --- a/src/tint/writer/hlsl/generator_impl_builtin_test.cc +++ b/src/tint/writer/hlsl/generator_impl_builtin_test.cc @@ -168,7 +168,7 @@ TEST_P(HlslBuiltinTest, Emit) { GeneratorImpl& gen = Build(); - auto* sem = program->Sem().Get(call); + auto* sem = program->Sem().Get(call); ASSERT_NE(sem, nullptr); auto* target = sem->Target(); ASSERT_NE(target, nullptr); diff --git a/src/tint/writer/msl/generator_impl.cc b/src/tint/writer/msl/generator_impl.cc index 3cbd963b7d..be94e2c9fe 100644 --- a/src/tint/writer/msl/generator_impl.cc +++ b/src/tint/writer/msl/generator_impl.cc @@ -41,6 +41,7 @@ #include "src/tint/sem/f32.h" #include "src/tint/sem/function.h" #include "src/tint/sem/i32.h" +#include "src/tint/sem/materialize.h" #include "src/tint/sem/matrix.h" #include "src/tint/sem/member_accessor_expression.h" #include "src/tint/sem/module.h" @@ -550,7 +551,12 @@ bool GeneratorImpl::EmitBreak(const ast::BreakStatement*) { } bool GeneratorImpl::EmitCall(std::ostream& out, const ast::CallExpression* expr) { - auto* call = program_->Sem().Get(expr); + auto* sem = program_->Sem().Get(expr); + if (auto* m = sem->As()) { + // TODO(crbug.com/tint/1504): Just emit the constant value. + sem = m->Expr(); + } + auto* call = sem->As(); auto* target = call->Target(); return Switch( target, [&](const sem::Function* func) { return EmitFunctionCall(out, call, func); }, diff --git a/src/tint/writer/msl/generator_impl_builtin_test.cc b/src/tint/writer/msl/generator_impl_builtin_test.cc index 752fc73eec..0c1f2a4bd2 100644 --- a/src/tint/writer/msl/generator_impl_builtin_test.cc +++ b/src/tint/writer/msl/generator_impl_builtin_test.cc @@ -189,7 +189,7 @@ TEST_P(MslBuiltinTest, Emit) { GeneratorImpl& gen = Build(); - auto* sem = program->Sem().Get(call); + auto* sem = program->Sem().Get(call); ASSERT_NE(sem, nullptr); auto* target = sem->Target(); ASSERT_NE(target, nullptr); diff --git a/src/tint/writer/msl/generator_impl_import_test.cc b/src/tint/writer/msl/generator_impl_import_test.cc index 8a6d2d0d6e..de9353ea44 100644 --- a/src/tint/writer/msl/generator_impl_import_test.cc +++ b/src/tint/writer/msl/generator_impl_import_test.cc @@ -40,7 +40,7 @@ TEST_P(MslImportData_SingleParamTest, FloatScalar) { GeneratorImpl& gen = Build(); - auto* sem = program->Sem().Get(call); + auto* sem = program->Sem().Get(call); ASSERT_NE(sem, nullptr); auto* target = sem->Target(); ASSERT_NE(target, nullptr); diff --git a/src/tint/writer/spirv/builder.cc b/src/tint/writer/spirv/builder.cc index 41eb6594bc..5f8072bb05 100644 --- a/src/tint/writer/spirv/builder.cc +++ b/src/tint/writer/spirv/builder.cc @@ -30,6 +30,7 @@ #include "src/tint/sem/depth_multisampled_texture.h" #include "src/tint/sem/depth_texture.h" #include "src/tint/sem/function.h" +#include "src/tint/sem/materialize.h" #include "src/tint/sem/member_accessor_expression.h" #include "src/tint/sem/module.h" #include "src/tint/sem/multisampled_texture.h" @@ -1273,7 +1274,13 @@ bool Builder::IsConstructorConst(const ast::Expression* expr) { return ast::TraverseAction::Descend; } if (auto* ce = e->As()) { - auto* call = builder_.Sem().Get(ce); + auto* sem = builder_.Sem().Get(ce); + if (sem->Is()) { + // Materialize can only occur on compile time expressions, so this sub-tree must be + // constant. + return ast::TraverseAction::Skip; + } + auto* call = sem->As(); if (call->Target()->Is()) { return ast::TraverseAction::Descend; } @@ -2154,7 +2161,12 @@ bool Builder::GenerateBlockStatementWithoutScoping(const ast::BlockStatement* st } uint32_t Builder::GenerateCallExpression(const ast::CallExpression* expr) { - auto* call = builder_.Sem().Get(expr); + auto* sem = builder_.Sem().Get(expr); + if (auto* m = sem->As()) { + // TODO(crbug.com/tint/1504): Just emit the constant value. + sem = m->Expr(); + } + auto* call = sem->As(); auto* target = call->Target(); return Switch( target, [&](const sem::Function* func) { return GenerateFunctionCall(call, func); },