tint: intrinsics.def Support [[precedence]] decoration

Add support for a [[precedence(N)]] decoration on intrinsic table type
declarations. This will be used to ensure the type with the lowest
conversion rank is matched when a matcher could match multiple types
for a given abstract numeric argument type.

Bug: tint:1504
Change-Id: I96475b000c0917bbfa4e2873b1731ce048b96a7d
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/90664
Reviewed-by: David Neto <dneto@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Ben Clayton 2022-05-18 18:56:58 +00:00 committed by Dawn LUCI CQ
parent aed7eb4b4c
commit c670018aea
7 changed files with 311 additions and 275 deletions

View File

@ -62,13 +62,18 @@ enum texel_format {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// WGSL primitive types // // WGSL primitive types //
// Types may be decorated with [[precedence(N)]] to prioritize which type //
// will be picked when multiple types of a matcher match. //
// This is used to ensure that abstract numerical types materialize to the //
// concrete type with the lowest conversion rank. //
// Types with higher the precedence values will be matched first. //
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// https://gpuweb.github.io/gpuweb/wgsl/#plain-types-section // https://gpuweb.github.io/gpuweb/wgsl/#plain-types-section
type bool type bool
type f32 [[precedence(2)]] type i32
type i32 [[precedence(1)]] type u32
type u32 [[precedence(0)]] type f32
type vec2<T> type vec2<T>
type vec3<T> type vec3<T>
type vec4<T> type vec4<T>

File diff suppressed because it is too large Load Diff

View File

@ -248,7 +248,7 @@ class {{$class}} : public TypeMatcher {
}; };
const sem::Type* {{$class}}::Match(MatchState& state, const sem::Type* ty) const { const sem::Type* {{$class}}::Match(MatchState& state, const sem::Type* ty) const {
{{- range .Types }} {{- range .PrecedenceSortedTypes }}
if (match_{{.Name}}(ty)) { if (match_{{.Name}}(ty)) {
return build_{{.Name}}(state); return build_{{.Name}}(state);
} }

View File

@ -142,7 +142,7 @@ func (p *parser) decorations() ast.Decorations {
values := []string{} values := []string{}
if p.match(tok.Lparen) != nil { if p.match(tok.Lparen) != nil {
for p.err == nil { for p.err == nil {
values = append(values, p.string()) values = append(values, string(p.next().Runes))
if p.match(tok.Comma) == nil { if p.match(tok.Comma) == nil {
break break
} }

View File

@ -100,6 +100,16 @@ func TestParser(t *testing.T) {
Name: "T", Name: "T",
}}, }},
}, },
}, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(),
`[[deco(1, "x")]] type T`, ast.AST{
Types: []ast.TypeDecl{{
Decorations: ast.Decorations{
{Name: "deco", Values: []string{"1", "x"}},
},
Name: "T",
}},
},
}, { /////////////////////////////////////////////////////////////////// }, { ///////////////////////////////////////////////////////////////////
utils.ThisLine(), utils.ThisLine(),
"match M : A", "match M : A",

View File

@ -17,6 +17,7 @@ package resolver
import ( import (
"fmt" "fmt"
"sort" "sort"
"strconv"
"dawn.googlesource.com/dawn/tools/src/cmd/intrinsic-gen/ast" "dawn.googlesource.com/dawn/tools/src/cmd/intrinsic-gen/ast"
"dawn.googlesource.com/dawn/tools/src/cmd/intrinsic-gen/sem" "dawn.googlesource.com/dawn/tools/src/cmd/intrinsic-gen/sem"
@ -179,6 +180,17 @@ func (r *resolver) ty(a ast.TypeDecl) error {
} }
t.DisplayName = d.Values[0] t.DisplayName = d.Values[0]
} }
if d := a.Decorations.Take("precedence"); d != nil {
if len(d.Values) != 1 {
return fmt.Errorf("%v expected a single integer value for 'precedence' decoration", d.Source)
}
n, err := strconv.Atoi(d.Values[0])
if err != nil {
return fmt.Errorf("%v %v", d.Source, err)
}
t.Precedence = n
}
if len(a.Decorations) != 0 { if len(a.Decorations) != 0 {
return fmt.Errorf("%v unknown decoration", a.Decorations[0].Source) return fmt.Errorf("%v unknown decoration", a.Decorations[0].Source)
} }

View File

@ -16,6 +16,7 @@ package sem
import ( import (
"fmt" "fmt"
"sort"
"dawn.googlesource.com/dawn/tools/src/cmd/intrinsic-gen/ast" "dawn.googlesource.com/dawn/tools/src/cmd/intrinsic-gen/ast"
) )
@ -89,6 +90,7 @@ type Type struct {
Decl ast.TypeDecl Decl ast.TypeDecl
Name string Name string
DisplayName string DisplayName string
Precedence int
} }
// TypeMatcher declares a type matcher // TypeMatcher declares a type matcher
@ -99,6 +101,13 @@ type TypeMatcher struct {
Types []*Type Types []*Type
} }
func (t TypeMatcher) PrecedenceSortedTypes() []*Type {
out := make([]*Type, len(t.Types))
copy(out, t.Types)
sort.Slice(out, func(i, j int) bool { return out[i].Precedence > out[j].Precedence })
return out
}
// EnumMatcher declares a enum matcher // EnumMatcher declares a enum matcher
type EnumMatcher struct { type EnumMatcher struct {
TemplateParams []TemplateParam TemplateParams []TemplateParam