mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-14 17:16:01 +00:00
tint/resolver: Add builtin_structs.h / .cc
Contains the builtin structure creation logic moved out from intrinsic_table.cc. Bug: chromium:1430309 Change-Id: I2207f9ae42c6d7343c2f2ffa81effde59e6023fe Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/129481 Reviewed-by: Dan Sinclair <dsinclair@chromium.org> Commit-Queue: Ben Clayton <bclayton@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
aae9f6bc5f
commit
d3b09b90e3
@ -281,6 +281,8 @@ libtint_source_set("libtint_program_src") {
|
||||
"clone_context.cc",
|
||||
"program.cc",
|
||||
"program_builder.cc",
|
||||
"resolver/builtin_structs.cc",
|
||||
"resolver/builtin_structs.h",
|
||||
"resolver/const_eval.cc",
|
||||
"resolver/const_eval.h",
|
||||
"resolver/ctor_conv_intrinsic.cc",
|
||||
|
@ -264,6 +264,8 @@ list(APPEND TINT_LIB_SRCS
|
||||
reflection.h
|
||||
reader/reader.cc
|
||||
reader/reader.h
|
||||
resolver/builtin_structs.cc
|
||||
resolver/builtin_structs.h
|
||||
resolver/const_eval.cc
|
||||
resolver/const_eval.h
|
||||
resolver/dependency_graph.cc
|
||||
|
194
src/tint/resolver/builtin_structs.cc
Normal file
194
src/tint/resolver/builtin_structs.cc
Normal file
@ -0,0 +1,194 @@
|
||||
// Copyright 2023 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/tint/resolver/builtin_structs.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "src/tint/program_builder.h"
|
||||
#include "src/tint/switch.h"
|
||||
#include "src/tint/type/abstract_float.h"
|
||||
#include "src/tint/type/abstract_int.h"
|
||||
#include "src/tint/type/vector.h"
|
||||
|
||||
namespace tint::resolver {
|
||||
|
||||
namespace {
|
||||
|
||||
struct NameAndType {
|
||||
std::string name;
|
||||
const type::Type* type;
|
||||
};
|
||||
|
||||
sem::Struct* BuildStruct(ProgramBuilder& b,
|
||||
std::string name,
|
||||
std::initializer_list<NameAndType> member_names_and_types) {
|
||||
uint32_t offset = 0;
|
||||
uint32_t max_align = 0;
|
||||
utils::Vector<const sem::StructMember*, 4> members;
|
||||
for (auto& m : member_names_and_types) {
|
||||
uint32_t align = std::max<uint32_t>(m.type->Align(), 1);
|
||||
uint32_t size = m.type->Size();
|
||||
offset = utils::RoundUp(align, offset);
|
||||
max_align = std::max(max_align, align);
|
||||
members.Push(b.create<sem::StructMember>(
|
||||
/* declaration */ nullptr,
|
||||
/* source */ Source{},
|
||||
/* name */ b.Sym(m.name),
|
||||
/* type */ m.type,
|
||||
/* index */ static_cast<uint32_t>(members.Length()),
|
||||
/* offset */ offset,
|
||||
/* align */ align,
|
||||
/* size */ size,
|
||||
/* location */ std::nullopt));
|
||||
offset += size;
|
||||
}
|
||||
uint32_t size_without_padding = offset;
|
||||
uint32_t size_with_padding = utils::RoundUp(max_align, offset);
|
||||
return b.create<sem::Struct>(
|
||||
/* declaration */ nullptr,
|
||||
/* source */ Source{},
|
||||
/* name */ b.Sym(name),
|
||||
/* members */ std::move(members),
|
||||
/* align */ max_align,
|
||||
/* size */ size_with_padding,
|
||||
/* size_no_padding */ size_without_padding);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
sem::Struct* CreateModfResult(ProgramBuilder& b, const type::Type* ty) {
|
||||
return Switch(
|
||||
ty,
|
||||
[&](const type::F32*) {
|
||||
return BuildStruct(b, "__modf_result_f32", {{"fract", ty}, {"whole", ty}});
|
||||
}, //
|
||||
[&](const type::F16*) {
|
||||
return BuildStruct(b, "__modf_result_f16", {{"fract", ty}, {"whole", ty}});
|
||||
},
|
||||
[&](const type::AbstractFloat*) {
|
||||
auto* abstract =
|
||||
BuildStruct(b, "__modf_result_abstract", {{"fract", ty}, {"whole", ty}});
|
||||
auto* f32 = b.create<type::F32>();
|
||||
auto* f16 = b.create<type::F16>();
|
||||
abstract->SetConcreteTypes(utils::Vector{
|
||||
BuildStruct(b, "__modf_result_f32", {{"fract", f32}, {"whole", f32}}),
|
||||
BuildStruct(b, "__modf_result_f16", {{"fract", f16}, {"whole", f16}}),
|
||||
});
|
||||
return abstract;
|
||||
},
|
||||
[&](const type::Vector* vec) {
|
||||
auto width = vec->Width();
|
||||
auto prefix = "__modf_result_vec" + std::to_string(width);
|
||||
return Switch(
|
||||
vec->type(), //
|
||||
[&](const type::F32*) {
|
||||
return BuildStruct(b, prefix + "_f32", {{"fract", vec}, {"whole", vec}});
|
||||
},
|
||||
[&](const type::F16*) {
|
||||
return BuildStruct(b, prefix + "_f16", {{"fract", vec}, {"whole", vec}});
|
||||
},
|
||||
[&](const type::AbstractFloat*) {
|
||||
auto* vec_f32 = b.create<type::Vector>(b.create<type::F32>(), width);
|
||||
auto* vec_f16 = b.create<type::Vector>(b.create<type::F16>(), width);
|
||||
auto* abstract =
|
||||
BuildStruct(b, prefix + "_abstract", {{"fract", vec}, {"whole", vec}});
|
||||
abstract->SetConcreteTypes(utils::Vector{
|
||||
BuildStruct(b, prefix + "_f32", {{"fract", vec_f32}, {"whole", vec_f32}}),
|
||||
BuildStruct(b, prefix + "_f16", {{"fract", vec_f16}, {"whole", vec_f16}}),
|
||||
});
|
||||
return abstract;
|
||||
},
|
||||
[&](Default) {
|
||||
TINT_ICE(Resolver, b.Diagnostics())
|
||||
<< "unhandled modf type: " << b.FriendlyName(ty);
|
||||
return nullptr;
|
||||
});
|
||||
},
|
||||
[&](Default) {
|
||||
TINT_ICE(Resolver, b.Diagnostics()) << "unhandled modf type: " << b.FriendlyName(ty);
|
||||
return nullptr;
|
||||
});
|
||||
}
|
||||
|
||||
sem::Struct* CreateFrexpResult(ProgramBuilder& b, const type::Type* ty) {
|
||||
return Switch(
|
||||
ty, //
|
||||
[&](const type::F32*) {
|
||||
auto* i32 = b.create<type::I32>();
|
||||
return BuildStruct(b, "__frexp_result_f32", {{"fract", ty}, {"exp", i32}});
|
||||
},
|
||||
[&](const type::F16*) {
|
||||
auto* i32 = b.create<type::I32>();
|
||||
return BuildStruct(b, "__frexp_result_f16", {{"fract", ty}, {"exp", i32}});
|
||||
},
|
||||
[&](const type::AbstractFloat*) {
|
||||
auto* f32 = b.create<type::F32>();
|
||||
auto* f16 = b.create<type::F16>();
|
||||
auto* i32 = b.create<type::I32>();
|
||||
auto* ai = b.create<type::AbstractInt>();
|
||||
auto* abstract =
|
||||
BuildStruct(b, "__frexp_result_abstract", {{"fract", ty}, {"exp", ai}});
|
||||
abstract->SetConcreteTypes(utils::Vector{
|
||||
BuildStruct(b, "__frexp_result_f32", {{"fract", f32}, {"exp", i32}}),
|
||||
BuildStruct(b, "__frexp_result_f16", {{"fract", f16}, {"exp", i32}}),
|
||||
});
|
||||
return abstract;
|
||||
},
|
||||
[&](const type::Vector* vec) {
|
||||
auto width = vec->Width();
|
||||
auto prefix = "__frexp_result_vec" + std::to_string(width);
|
||||
return Switch(
|
||||
vec->type(), //
|
||||
[&](const type::F32*) {
|
||||
auto* vec_i32 = b.create<type::Vector>(b.create<type::I32>(), width);
|
||||
return BuildStruct(b, prefix + "_f32", {{"fract", ty}, {"exp", vec_i32}});
|
||||
},
|
||||
[&](const type::F16*) {
|
||||
auto* vec_i32 = b.create<type::Vector>(b.create<type::I32>(), width);
|
||||
return BuildStruct(b, prefix + "_f16", {{"fract", ty}, {"exp", vec_i32}});
|
||||
},
|
||||
[&](const type::AbstractFloat*) {
|
||||
auto* vec_f32 = b.create<type::Vector>(b.create<type::F32>(), width);
|
||||
auto* vec_f16 = b.create<type::Vector>(b.create<type::F16>(), width);
|
||||
auto* vec_i32 = b.create<type::Vector>(b.create<type::I32>(), width);
|
||||
auto* vec_ai = b.create<type::Vector>(b.create<type::AbstractInt>(), width);
|
||||
auto* abstract =
|
||||
BuildStruct(b, prefix + "_abstract", {{"fract", ty}, {"exp", vec_ai}});
|
||||
abstract->SetConcreteTypes(utils::Vector{
|
||||
BuildStruct(b, prefix + "_f32", {{"fract", vec_f32}, {"exp", vec_i32}}),
|
||||
BuildStruct(b, prefix + "_f16", {{"fract", vec_f16}, {"exp", vec_i32}}),
|
||||
});
|
||||
return abstract;
|
||||
},
|
||||
[&](Default) {
|
||||
TINT_ICE(Resolver, b.Diagnostics())
|
||||
<< "unhandled frexp type: " << b.FriendlyName(ty);
|
||||
return nullptr;
|
||||
});
|
||||
},
|
||||
[&](Default) {
|
||||
TINT_ICE(Resolver, b.Diagnostics()) << "unhandled frexp type: " << b.FriendlyName(ty);
|
||||
return nullptr;
|
||||
});
|
||||
}
|
||||
|
||||
sem::Struct* CreateAtomicCompareExchangeResult(ProgramBuilder& b, const type::Type* ty) {
|
||||
return BuildStruct(
|
||||
b, "__atomic_compare_exchange_result" + ty->FriendlyName(),
|
||||
{{"old_value", const_cast<type::Type*>(ty)}, {"exchanged", b.create<type::Bool>()}});
|
||||
}
|
||||
|
||||
} // namespace tint::resolver
|
51
src/tint/resolver/builtin_structs.h
Normal file
51
src/tint/resolver/builtin_structs.h
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright 2023 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_TINT_RESOLVER_BUILTIN_STRUCTS_H_
|
||||
#define SRC_TINT_RESOLVER_BUILTIN_STRUCTS_H_
|
||||
|
||||
// Forward declarations
|
||||
namespace tint {
|
||||
class ProgramBuilder;
|
||||
} // namespace tint
|
||||
namespace tint::sem {
|
||||
class Struct;
|
||||
} // namespace tint::sem
|
||||
namespace tint::type {
|
||||
class Type;
|
||||
} // namespace tint::type
|
||||
|
||||
namespace tint::resolver {
|
||||
|
||||
/**
|
||||
* @param ty the type of the `fract` and `whole` struct members.
|
||||
* @return the builtin struct type for a modf() builtin call.
|
||||
*/
|
||||
sem::Struct* CreateModfResult(ProgramBuilder& b, const type::Type* ty);
|
||||
|
||||
/**
|
||||
* @param fract the type of the `fract` struct member.
|
||||
* @return the builtin struct type for a frexp() builtin call.
|
||||
*/
|
||||
sem::Struct* CreateFrexpResult(ProgramBuilder& b, const type::Type* fract);
|
||||
|
||||
/**
|
||||
* @param ty the type of the `old_value` struct member.
|
||||
* @return the builtin struct type for a atomic_compare_exchange() builtin call.
|
||||
*/
|
||||
sem::Struct* CreateAtomicCompareExchangeResult(ProgramBuilder& b, const type::Type* ty);
|
||||
|
||||
} // namespace tint::resolver
|
||||
|
||||
#endif // SRC_TINT_RESOLVER_BUILTIN_STRUCTS_H_
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "src/tint/ast/binary_expression.h"
|
||||
#include "src/tint/program_builder.h"
|
||||
#include "src/tint/resolver/builtin_structs.h"
|
||||
#include "src/tint/sem/evaluation_stage.h"
|
||||
#include "src/tint/sem/pipeline_stage_set.h"
|
||||
#include "src/tint/sem/value_constructor.h"
|
||||
@ -819,170 +820,26 @@ bool match_atomic_compare_exchange_result(MatchState&, const type::Type* ty, con
|
||||
return false;
|
||||
}
|
||||
|
||||
struct NameAndType {
|
||||
std::string name;
|
||||
const type::Type* type;
|
||||
};
|
||||
sem::Struct* build_struct(ProgramBuilder& b,
|
||||
std::string name,
|
||||
std::initializer_list<NameAndType> member_names_and_types) {
|
||||
uint32_t offset = 0;
|
||||
uint32_t max_align = 0;
|
||||
utils::Vector<const sem::StructMember*, 4> members;
|
||||
for (auto& m : member_names_and_types) {
|
||||
uint32_t align = std::max<uint32_t>(m.type->Align(), 1);
|
||||
uint32_t size = m.type->Size();
|
||||
offset = utils::RoundUp(align, offset);
|
||||
max_align = std::max(max_align, align);
|
||||
members.Push(b.create<sem::StructMember>(
|
||||
/* declaration */ nullptr,
|
||||
/* source */ Source{},
|
||||
/* name */ b.Sym(m.name),
|
||||
/* type */ m.type,
|
||||
/* index */ static_cast<uint32_t>(members.Length()),
|
||||
/* offset */ offset,
|
||||
/* align */ align,
|
||||
/* size */ size,
|
||||
/* location */ std::nullopt));
|
||||
offset += size;
|
||||
}
|
||||
uint32_t size_without_padding = offset;
|
||||
uint32_t size_with_padding = utils::RoundUp(max_align, offset);
|
||||
return b.create<sem::Struct>(
|
||||
/* declaration */ nullptr,
|
||||
/* source */ Source{},
|
||||
/* name */ b.Sym(name),
|
||||
/* members */ std::move(members),
|
||||
/* align */ max_align,
|
||||
/* size */ size_with_padding,
|
||||
/* size_no_padding */ size_without_padding);
|
||||
}
|
||||
|
||||
const sem::Struct* build_modf_result(MatchState& state, const type::Type* el) {
|
||||
auto build_f32 = [&] {
|
||||
auto* ty = state.builder.create<type::F32>();
|
||||
return build_struct(state.builder, "__modf_result_f32", {{"fract", ty}, {"whole", ty}});
|
||||
};
|
||||
auto build_f16 = [&] {
|
||||
auto* ty = state.builder.create<type::F16>();
|
||||
return build_struct(state.builder, "__modf_result_f16", {{"fract", ty}, {"whole", ty}});
|
||||
};
|
||||
|
||||
return Switch(
|
||||
el, //
|
||||
[&](const type::F32*) { return build_f32(); }, //
|
||||
[&](const type::F16*) { return build_f16(); }, //
|
||||
[&](const type::AbstractFloat*) {
|
||||
auto* abstract = build_struct(state.builder, "__modf_result_abstract",
|
||||
{{"fract", el}, {"whole", el}});
|
||||
abstract->SetConcreteTypes(utils::Vector{build_f32(), build_f16()});
|
||||
return abstract;
|
||||
},
|
||||
[&](Default) {
|
||||
TINT_ICE(Resolver, state.builder.Diagnostics())
|
||||
<< "unhandled modf type: " << state.builder.FriendlyName(el);
|
||||
return nullptr;
|
||||
});
|
||||
return CreateModfResult(state.builder, el);
|
||||
}
|
||||
|
||||
const sem::Struct* build_modf_result_vec(MatchState& state, Number& n, const type::Type* el) {
|
||||
auto prefix = "__modf_result_vec" + std::to_string(n.Value());
|
||||
auto build_f32 = [&] {
|
||||
auto* vec =
|
||||
state.builder.create<type::Vector>(state.builder.create<type::F32>(), n.Value());
|
||||
return build_struct(state.builder, prefix + "_f32", {{"fract", vec}, {"whole", vec}});
|
||||
};
|
||||
auto build_f16 = [&] {
|
||||
auto* vec =
|
||||
state.builder.create<type::Vector>(state.builder.create<type::F16>(), n.Value());
|
||||
return build_struct(state.builder, prefix + "_f16", {{"fract", vec}, {"whole", vec}});
|
||||
};
|
||||
|
||||
return Switch(
|
||||
el, //
|
||||
[&](const type::F32*) { return build_f32(); }, //
|
||||
[&](const type::F16*) { return build_f16(); }, //
|
||||
[&](const type::AbstractFloat*) {
|
||||
auto* vec = state.builder.create<type::Vector>(el, n.Value());
|
||||
auto* abstract =
|
||||
build_struct(state.builder, prefix + "_abstract", {{"fract", vec}, {"whole", vec}});
|
||||
abstract->SetConcreteTypes(utils::Vector{build_f32(), build_f16()});
|
||||
return abstract;
|
||||
},
|
||||
[&](Default) {
|
||||
TINT_ICE(Resolver, state.builder.Diagnostics())
|
||||
<< "unhandled modf type: " << state.builder.FriendlyName(el);
|
||||
return nullptr;
|
||||
});
|
||||
auto* vec = state.builder.create<type::Vector>(el, n.Value());
|
||||
return CreateModfResult(state.builder, vec);
|
||||
}
|
||||
|
||||
const sem::Struct* build_frexp_result(MatchState& state, const type::Type* el) {
|
||||
auto build_f32 = [&] {
|
||||
auto* f = state.builder.create<type::F32>();
|
||||
auto* i = state.builder.create<type::I32>();
|
||||
return build_struct(state.builder, "__frexp_result_f32", {{"fract", f}, {"exp", i}});
|
||||
};
|
||||
auto build_f16 = [&] {
|
||||
auto* f = state.builder.create<type::F16>();
|
||||
auto* i = state.builder.create<type::I32>();
|
||||
return build_struct(state.builder, "__frexp_result_f16", {{"fract", f}, {"exp", i}});
|
||||
};
|
||||
|
||||
return Switch(
|
||||
el, //
|
||||
[&](const type::F32*) { return build_f32(); }, //
|
||||
[&](const type::F16*) { return build_f16(); }, //
|
||||
[&](const type::AbstractFloat*) {
|
||||
auto* i = state.builder.create<type::AbstractInt>();
|
||||
auto* abstract =
|
||||
build_struct(state.builder, "__frexp_result_abstract", {{"fract", el}, {"exp", i}});
|
||||
abstract->SetConcreteTypes(utils::Vector{build_f32(), build_f16()});
|
||||
return abstract;
|
||||
},
|
||||
[&](Default) {
|
||||
TINT_ICE(Resolver, state.builder.Diagnostics())
|
||||
<< "unhandled frexp type: " << state.builder.FriendlyName(el);
|
||||
return nullptr;
|
||||
});
|
||||
return CreateFrexpResult(state.builder, el);
|
||||
}
|
||||
|
||||
const sem::Struct* build_frexp_result_vec(MatchState& state, Number& n, const type::Type* el) {
|
||||
auto prefix = "__frexp_result_vec" + std::to_string(n.Value());
|
||||
auto build_f32 = [&] {
|
||||
auto* f = state.builder.create<type::Vector>(state.builder.create<type::F32>(), n.Value());
|
||||
auto* e = state.builder.create<type::Vector>(state.builder.create<type::I32>(), n.Value());
|
||||
return build_struct(state.builder, prefix + "_f32", {{"fract", f}, {"exp", e}});
|
||||
};
|
||||
auto build_f16 = [&] {
|
||||
auto* f = state.builder.create<type::Vector>(state.builder.create<type::F16>(), n.Value());
|
||||
auto* e = state.builder.create<type::Vector>(state.builder.create<type::I32>(), n.Value());
|
||||
return build_struct(state.builder, prefix + "_f16", {{"fract", f}, {"exp", e}});
|
||||
};
|
||||
|
||||
return Switch(
|
||||
el, //
|
||||
[&](const type::F32*) { return build_f32(); }, //
|
||||
[&](const type::F16*) { return build_f16(); }, //
|
||||
[&](const type::AbstractFloat*) {
|
||||
auto* f = state.builder.create<type::Vector>(el, n.Value());
|
||||
auto* e = state.builder.create<type::Vector>(state.builder.create<type::AbstractInt>(),
|
||||
n.Value());
|
||||
auto* abstract =
|
||||
build_struct(state.builder, prefix + "_abstract", {{"fract", f}, {"exp", e}});
|
||||
abstract->SetConcreteTypes(utils::Vector{build_f32(), build_f16()});
|
||||
return abstract;
|
||||
},
|
||||
[&](Default) {
|
||||
TINT_ICE(Resolver, state.builder.Diagnostics())
|
||||
<< "unhandled frexp type: " << state.builder.FriendlyName(el);
|
||||
return nullptr;
|
||||
});
|
||||
auto* vec = state.builder.create<type::Vector>(el, n.Value());
|
||||
return CreateFrexpResult(state.builder, vec);
|
||||
}
|
||||
|
||||
const sem::Struct* build_atomic_compare_exchange_result(MatchState& state, const type::Type* ty) {
|
||||
return build_struct(state.builder, "__atomic_compare_exchange_result" + ty->FriendlyName(),
|
||||
{{"old_value", const_cast<type::Type*>(ty)},
|
||||
{"exchanged", state.builder.create<type::Bool>()}});
|
||||
return CreateAtomicCompareExchangeResult(state.builder, ty);
|
||||
}
|
||||
|
||||
/// ParameterInfo describes a parameter
|
||||
|
Loading…
x
Reference in New Issue
Block a user