tint/PromoteInitializers: Do not hoist abstracts
Hoisting them would cause premature materialization. This will only happen in cases where we do not actually need to hoist (e.g. assigning to a phony), so we can safely skip these. Fixed: tint:1852 Change-Id: Ifcbe3e13496daa0a6aaceb58540e60cb037885ea Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/122104 Reviewed-by: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: James Price <jrprice@google.com>
This commit is contained in:
parent
dee884c925
commit
d623182c33
|
@ -52,6 +52,11 @@ Transform::ApplyResult PromoteInitializersToLet::Apply(const Program* src,
|
|||
// Follow const-chains
|
||||
auto* root_expr = expr;
|
||||
if (expr->Stage() == sem::EvaluationStage::kConstant) {
|
||||
if (expr->Type()->HoldsAbstract()) {
|
||||
// Do not hoist expressions that are not materialized, as doing so would cause
|
||||
// premature materialization.
|
||||
return false;
|
||||
}
|
||||
while (auto* user = root_expr->UnwrapMaterialize()->As<sem::VariableUser>()) {
|
||||
root_expr = user->Variable()->Initializer();
|
||||
}
|
||||
|
|
|
@ -1335,5 +1335,17 @@ fn f() {
|
|||
EXPECT_EQ(expect, str(got));
|
||||
}
|
||||
|
||||
TEST_F(PromoteInitializersToLetTest, AssignAbstractArray_ToPhony) {
|
||||
// Test that we do not try to hoist an abstract array expression that is the RHS of a phony
|
||||
// assignment, as its type will not be materialized.
|
||||
auto* src = R"(
|
||||
fn f() {
|
||||
_ = array(1, 2, 3, 4);
|
||||
}
|
||||
)";
|
||||
|
||||
EXPECT_FALSE(ShouldRun<PromoteInitializersToLet>(src));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace tint::transform
|
||||
|
|
|
@ -44,9 +44,10 @@ struct HoistToDeclBefore::State {
|
|||
|
||||
switch (kind) {
|
||||
case VariableKind::kLet: {
|
||||
auto builder = [this, expr, name] {
|
||||
return b.Decl(b.Let(
|
||||
name, Transform::CreateASTTypeFor(ctx, ctx.src->Sem().GetVal(expr)->Type()),
|
||||
auto* ty = ctx.src->Sem().GetVal(expr)->Type();
|
||||
TINT_ASSERT(Transform, !ty->HoldsAbstract());
|
||||
auto builder = [this, expr, name, ty] {
|
||||
return b.Decl(b.Let(name, Transform::CreateASTTypeFor(ctx, ty),
|
||||
ctx.CloneWithoutTransform(expr)));
|
||||
};
|
||||
if (!InsertBeforeImpl(before_expr->Stmt(), std::move(builder))) {
|
||||
|
@ -56,9 +57,10 @@ struct HoistToDeclBefore::State {
|
|||
}
|
||||
|
||||
case VariableKind::kVar: {
|
||||
auto builder = [this, expr, name] {
|
||||
return b.Decl(b.Var(
|
||||
name, Transform::CreateASTTypeFor(ctx, ctx.src->Sem().GetVal(expr)->Type()),
|
||||
auto* ty = ctx.src->Sem().GetVal(expr)->Type();
|
||||
TINT_ASSERT(Transform, !ty->HoldsAbstract());
|
||||
auto builder = [this, expr, name, ty] {
|
||||
return b.Decl(b.Var(name, Transform::CreateASTTypeFor(ctx, ty),
|
||||
ctx.CloneWithoutTransform(expr)));
|
||||
};
|
||||
if (!InsertBeforeImpl(before_expr->Stmt(), std::move(builder))) {
|
||||
|
@ -78,7 +80,7 @@ struct HoistToDeclBefore::State {
|
|||
}
|
||||
}
|
||||
|
||||
// Replace the initializer expression with a reference to the let
|
||||
// Replace the source expression with a reference to the hoisted declaration.
|
||||
ctx.Replace(expr, b.Expr(name));
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
fn foo(){
|
||||
_ = array(4);
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
[numthreads(1, 1, 1)]
|
||||
void unused_entry_point() {
|
||||
return;
|
||||
}
|
||||
|
||||
void foo() {
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
[numthreads(1, 1, 1)]
|
||||
void unused_entry_point() {
|
||||
return;
|
||||
}
|
||||
|
||||
void foo() {
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#version 310 es
|
||||
|
||||
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||
void unused_entry_point() {
|
||||
return;
|
||||
}
|
||||
void foo() {
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#include <metal_stdlib>
|
||||
|
||||
using namespace metal;
|
||||
void foo() {
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
; SPIR-V
|
||||
; Version: 1.3
|
||||
; Generator: Google Tint Compiler; 0
|
||||
; Bound: 7
|
||||
; Schema: 0
|
||||
OpCapability Shader
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint GLCompute %unused_entry_point "unused_entry_point"
|
||||
OpExecutionMode %unused_entry_point LocalSize 1 1 1
|
||||
OpName %unused_entry_point "unused_entry_point"
|
||||
OpName %foo "foo"
|
||||
%void = OpTypeVoid
|
||||
%1 = OpTypeFunction %void
|
||||
%unused_entry_point = OpFunction %void None %1
|
||||
%4 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
%foo = OpFunction %void None %1
|
||||
%6 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
|
@ -0,0 +1,3 @@
|
|||
fn foo() {
|
||||
_ = array(4);
|
||||
}
|
Loading…
Reference in New Issue