mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-18 17:35:30 +00:00
sem: Split sem::Variable into global, local and parameter
Each of these may contain information specific to their kind. Change-Id: Ic8ac808088132b7bc2e43da6ce46a06571e0fed5 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/59200 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ryan Harrison <rharrison@chromium.org> Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
@@ -32,18 +32,12 @@ CallTarget::~CallTarget() = default;
|
||||
|
||||
int IndexOf(const ParameterList& parameters, ParameterUsage usage) {
|
||||
for (size_t i = 0; i < parameters.size(); i++) {
|
||||
if (parameters[i].usage == usage) {
|
||||
if (parameters[i]->Usage() == usage) {
|
||||
return static_cast<int>(i);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, Parameter parameter) {
|
||||
out << "[type: " << parameter.type->FriendlyName(SymbolTable{ProgramID{}})
|
||||
<< ", usage: " << str(parameter.usage) << "]";
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace sem
|
||||
} // namespace tint
|
||||
|
||||
@@ -18,39 +18,15 @@
|
||||
#include <vector>
|
||||
|
||||
#include "src/sem/node.h"
|
||||
#include "src/sem/parameter_usage.h"
|
||||
#include "src/sem/sampler_type.h"
|
||||
#include "src/sem/variable.h"
|
||||
#include "src/utils/hash.h"
|
||||
|
||||
namespace tint {
|
||||
|
||||
namespace sem {
|
||||
// Forward declarations
|
||||
class Type;
|
||||
|
||||
/// Parameter describes a single parameter of a call target
|
||||
struct Parameter {
|
||||
/// Parameter type
|
||||
sem::Type* const type;
|
||||
/// Parameter usage
|
||||
ParameterUsage const usage = ParameterUsage::kNone;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, Parameter parameter);
|
||||
|
||||
/// Equality operator for Parameters
|
||||
static inline bool operator==(const Parameter& a, const Parameter& b) {
|
||||
return a.type == b.type && a.usage == b.usage;
|
||||
}
|
||||
|
||||
/// Inequality operator for Parameters
|
||||
static inline bool operator!=(const Parameter& a, const Parameter& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
/// ParameterList is a list of Parameter
|
||||
using ParameterList = std::vector<Parameter>;
|
||||
|
||||
/// @param parameters the list of parameters
|
||||
/// @param usage the parameter usage to find
|
||||
/// @returns the index of the parameter with the given usage, or -1 if no
|
||||
@@ -85,19 +61,4 @@ class CallTarget : public Castable<CallTarget, Node> {
|
||||
} // namespace sem
|
||||
} // namespace tint
|
||||
|
||||
namespace std {
|
||||
|
||||
/// Custom std::hash specialization for tint::sem::Parameter
|
||||
template <>
|
||||
class hash<tint::sem::Parameter> {
|
||||
public:
|
||||
/// @param p the tint::sem::Parameter to create a hash for
|
||||
/// @return the hash value
|
||||
inline std::size_t operator()(const tint::sem::Parameter& p) const {
|
||||
return tint::utils::Hash(p.type, p.usage);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif // SRC_SEM_CALL_TARGET_H_
|
||||
|
||||
@@ -27,31 +27,17 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::Function);
|
||||
namespace tint {
|
||||
namespace sem {
|
||||
|
||||
namespace {
|
||||
|
||||
ParameterList GetParameters(const std::vector<const Variable*>& params) {
|
||||
ParameterList parameters;
|
||||
parameters.reserve(params.size());
|
||||
for (auto* param : params) {
|
||||
parameters.emplace_back(Parameter{param->Type(), ParameterUsage::kNone});
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Function::Function(ast::Function* declaration,
|
||||
Type* return_type,
|
||||
std::vector<const Variable*> parameters,
|
||||
ParameterList parameters,
|
||||
std::vector<const Variable*> referenced_module_vars,
|
||||
std::vector<const Variable*> local_referenced_module_vars,
|
||||
std::vector<const ast::ReturnStatement*> return_statements,
|
||||
std::vector<const ast::CallExpression*> callsites,
|
||||
std::vector<Symbol> ancestor_entry_points,
|
||||
std::array<WorkgroupDimension, 3> workgroup_size)
|
||||
: Base(return_type, GetParameters(parameters)),
|
||||
: Base(return_type, std::move(parameters)),
|
||||
declaration_(declaration),
|
||||
parameters_(std::move(parameters)),
|
||||
referenced_module_vars_(std::move(referenced_module_vars)),
|
||||
local_referenced_module_vars_(std::move(local_referenced_module_vars)),
|
||||
return_statements_(std::move(return_statements)),
|
||||
|
||||
@@ -68,7 +68,7 @@ class Function : public Castable<Function, CallTarget> {
|
||||
/// @param workgroup_size the workgroup size
|
||||
Function(ast::Function* declaration,
|
||||
Type* return_type,
|
||||
std::vector<const Variable*> parameters,
|
||||
ParameterList parameters,
|
||||
std::vector<const Variable*> referenced_module_vars,
|
||||
std::vector<const Variable*> local_referenced_module_vars,
|
||||
std::vector<const ast::ReturnStatement*> return_statements,
|
||||
@@ -82,9 +82,6 @@ class Function : public Castable<Function, CallTarget> {
|
||||
/// @returns the ast::Function declaration
|
||||
ast::Function* Declaration() const { return declaration_; }
|
||||
|
||||
/// @return the parameters to the function
|
||||
const std::vector<const Variable*> Parameters() const { return parameters_; }
|
||||
|
||||
/// Note: If this function calls other functions, the return will also include
|
||||
/// all of the referenced variables from the callees.
|
||||
/// @returns the referenced module variables
|
||||
@@ -178,7 +175,6 @@ class Function : public Castable<Function, CallTarget> {
|
||||
bool multisampled) const;
|
||||
|
||||
ast::Function* const declaration_;
|
||||
std::vector<const Variable*> const parameters_;
|
||||
std::vector<const Variable*> const referenced_module_vars_;
|
||||
std::vector<const Variable*> const local_referenced_module_vars_;
|
||||
std::vector<const ast::ReturnStatement*> const return_statements_;
|
||||
|
||||
@@ -19,11 +19,6 @@ TINT_INSTANTIATE_TYPEINFO(tint::sem::Intrinsic);
|
||||
namespace tint {
|
||||
namespace sem {
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, IntrinsicType i) {
|
||||
out << str(i);
|
||||
return out;
|
||||
}
|
||||
|
||||
const char* Intrinsic::str() const {
|
||||
return sem::str(type_);
|
||||
}
|
||||
@@ -103,7 +98,7 @@ bool IsAtomicIntrinsic(IntrinsicType i) {
|
||||
|
||||
Intrinsic::Intrinsic(IntrinsicType type,
|
||||
sem::Type* return_type,
|
||||
const ParameterList& parameters,
|
||||
ParameterList parameters,
|
||||
PipelineStageSet supported_stages,
|
||||
bool is_deprecated)
|
||||
: Base(return_type, parameters),
|
||||
@@ -111,8 +106,6 @@ Intrinsic::Intrinsic(IntrinsicType type,
|
||||
supported_stages_(supported_stages),
|
||||
is_deprecated_(is_deprecated) {}
|
||||
|
||||
Intrinsic::Intrinsic(const Intrinsic&) = default;
|
||||
|
||||
Intrinsic::~Intrinsic() = default;
|
||||
|
||||
bool Intrinsic::IsCoarseDerivative() const {
|
||||
@@ -155,25 +148,5 @@ bool Intrinsic::IsAtomic() const {
|
||||
return IsAtomicIntrinsic(type_);
|
||||
}
|
||||
|
||||
bool operator==(const Intrinsic& a, const Intrinsic& b) {
|
||||
static_assert(sizeof(Intrinsic(IntrinsicType::kNone, nullptr, ParameterList{},
|
||||
PipelineStageSet{}, false)) > 0,
|
||||
"don't forget to update the comparison below if you change the "
|
||||
"constructor of Intrinsic!");
|
||||
|
||||
if (a.Type() != b.Type() || a.SupportedStages() != b.SupportedStages() ||
|
||||
a.ReturnType() != b.ReturnType() ||
|
||||
a.IsDeprecated() != b.IsDeprecated() ||
|
||||
a.Parameters().size() != b.Parameters().size()) {
|
||||
return false;
|
||||
}
|
||||
for (size_t i = 0; i < a.Parameters().size(); i++) {
|
||||
if (a.Parameters()[i] != b.Parameters()[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace sem
|
||||
} // namespace tint
|
||||
|
||||
@@ -88,13 +88,10 @@ class Intrinsic : public Castable<Intrinsic, CallTarget> {
|
||||
/// deprecated
|
||||
Intrinsic(IntrinsicType type,
|
||||
sem::Type* return_type,
|
||||
const ParameterList& parameters,
|
||||
ParameterList parameters,
|
||||
PipelineStageSet supported_stages,
|
||||
bool is_deprecated);
|
||||
|
||||
/// Copy constructor
|
||||
Intrinsic(const Intrinsic&);
|
||||
|
||||
/// Destructor
|
||||
~Intrinsic() override;
|
||||
|
||||
@@ -147,18 +144,6 @@ class Intrinsic : public Castable<Intrinsic, CallTarget> {
|
||||
bool const is_deprecated_;
|
||||
};
|
||||
|
||||
/// Emits the name of the intrinsic function type. The spelling, including case,
|
||||
/// matches the name in the WGSL spec.
|
||||
std::ostream& operator<<(std::ostream& out, IntrinsicType i);
|
||||
|
||||
/// Equality operator for Intrinsics
|
||||
bool operator==(const Intrinsic& a, const Intrinsic& b);
|
||||
|
||||
/// Inequality operator for Intrinsics
|
||||
static inline bool operator!=(const Intrinsic& a, const Intrinsic& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
} // namespace sem
|
||||
} // namespace tint
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
#include "src/sem/intrinsic_type.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace tint {
|
||||
namespace sem {
|
||||
|
||||
@@ -529,5 +531,10 @@ const char* str(IntrinsicType i) {
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, IntrinsicType i) {
|
||||
out << str(i);
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace sem
|
||||
} // namespace tint
|
||||
|
||||
@@ -10,6 +10,8 @@ See:
|
||||
|
||||
#include "src/sem/intrinsic_type.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace tint {
|
||||
namespace sem {
|
||||
|
||||
@@ -34,5 +36,10 @@ const char* str(IntrinsicType i) {
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, IntrinsicType i) {
|
||||
out << str(i);
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace sem
|
||||
} // namespace tint
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define SRC_SEM_INTRINSIC_TYPE_H_
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace tint {
|
||||
namespace sem {
|
||||
@@ -143,6 +144,10 @@ IntrinsicType ParseIntrinsicType(const std::string& name);
|
||||
/// case, matches the name in the WGSL spec.
|
||||
const char* str(IntrinsicType i);
|
||||
|
||||
/// Emits the name of the intrinsic function type. The spelling, including case,
|
||||
/// matches the name in the WGSL spec.
|
||||
std::ostream& operator<<(std::ostream& out, IntrinsicType i);
|
||||
|
||||
} // namespace sem
|
||||
} // namespace tint
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ See:
|
||||
#define SRC_SEM_INTRINSIC_TYPE_H_
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace tint {
|
||||
namespace sem {
|
||||
@@ -34,6 +35,10 @@ IntrinsicType ParseIntrinsicType(const std::string& name);
|
||||
/// case, matches the name in the WGSL spec.
|
||||
const char* str(IntrinsicType i);
|
||||
|
||||
/// Emits the name of the intrinsic function type. The spelling, including case,
|
||||
/// matches the name in the WGSL spec.
|
||||
std::ostream& operator<<(std::ostream& out, IntrinsicType i);
|
||||
|
||||
} // namespace sem
|
||||
} // namespace tint
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/sem/sampler_type.h"
|
||||
#include "src/sem/test_helper.h"
|
||||
#include "src/sem/texture_type.h"
|
||||
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
#include "src/ast/variable.h"
|
||||
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::Variable);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::GlobalVariable);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::LocalVariable);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::Parameter);
|
||||
TINT_INSTANTIATE_TYPEINFO(tint::sem::VariableUser);
|
||||
|
||||
namespace tint {
|
||||
@@ -28,26 +31,51 @@ namespace sem {
|
||||
Variable::Variable(const ast::Variable* declaration,
|
||||
const sem::Type* type,
|
||||
ast::StorageClass storage_class,
|
||||
ast::Access access,
|
||||
sem::BindingPoint binding_point)
|
||||
ast::Access access)
|
||||
: declaration_(declaration),
|
||||
type_(type),
|
||||
storage_class_(storage_class),
|
||||
access_(access),
|
||||
access_(access) {}
|
||||
|
||||
Variable::~Variable() = default;
|
||||
|
||||
LocalVariable::LocalVariable(const ast::Variable* declaration,
|
||||
const sem::Type* type,
|
||||
ast::StorageClass storage_class,
|
||||
ast::Access access)
|
||||
: Base(declaration, type, storage_class, access) {}
|
||||
|
||||
LocalVariable::~LocalVariable() = default;
|
||||
|
||||
GlobalVariable::GlobalVariable(const ast::Variable* declaration,
|
||||
const sem::Type* type,
|
||||
ast::StorageClass storage_class,
|
||||
ast::Access access,
|
||||
sem::BindingPoint binding_point)
|
||||
: Base(declaration, type, storage_class, access),
|
||||
binding_point_(binding_point),
|
||||
is_pipeline_constant_(false) {}
|
||||
|
||||
Variable::Variable(const ast::Variable* declaration,
|
||||
const sem::Type* type,
|
||||
uint16_t constant_id)
|
||||
: declaration_(declaration),
|
||||
type_(type),
|
||||
storage_class_(ast::StorageClass::kNone),
|
||||
access_(ast::Access::kReadWrite),
|
||||
GlobalVariable::GlobalVariable(const ast::Variable* declaration,
|
||||
const sem::Type* type,
|
||||
uint16_t constant_id)
|
||||
: Base(declaration,
|
||||
type,
|
||||
ast::StorageClass::kNone,
|
||||
ast::Access::kReadWrite),
|
||||
is_pipeline_constant_(true),
|
||||
constant_id_(constant_id) {}
|
||||
|
||||
Variable::~Variable() = default;
|
||||
GlobalVariable::~GlobalVariable() = default;
|
||||
|
||||
Parameter::Parameter(const ast::Variable* declaration,
|
||||
const sem::Type* type,
|
||||
ast::StorageClass storage_class,
|
||||
ast::Access access,
|
||||
const ParameterUsage usage /* = ParameterUsage::kNone */)
|
||||
: Base(declaration, type, storage_class, access), usage_(usage) {}
|
||||
|
||||
Parameter::~Parameter() = default;
|
||||
|
||||
VariableUser::VariableUser(ast::IdentifierExpression* declaration,
|
||||
const sem::Type* type,
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "src/ast/storage_class.h"
|
||||
#include "src/sem/binding_point.h"
|
||||
#include "src/sem/expression.h"
|
||||
#include "src/sem/parameter_usage.h"
|
||||
|
||||
namespace tint {
|
||||
|
||||
@@ -36,28 +37,19 @@ namespace sem {
|
||||
class Type;
|
||||
class VariableUser;
|
||||
|
||||
/// Variable holds the semantic information for variables.
|
||||
/// Variable is the base class for local variables, global variables and
|
||||
/// parameters.
|
||||
class Variable : public Castable<Variable, Node> {
|
||||
public:
|
||||
/// Constructor for variables and non-overridable constants
|
||||
/// Constructor
|
||||
/// @param declaration the AST declaration node
|
||||
/// @param type the variable type
|
||||
/// @param storage_class the variable storage class
|
||||
/// @param access the variable access control type
|
||||
/// @param binding_point the optional resource binding point of the variable
|
||||
Variable(const ast::Variable* declaration,
|
||||
const sem::Type* type,
|
||||
ast::StorageClass storage_class,
|
||||
ast::Access access,
|
||||
sem::BindingPoint binding_point = {});
|
||||
|
||||
/// Constructor for overridable pipeline constants
|
||||
/// @param declaration the AST declaration node
|
||||
/// @param type the variable type
|
||||
/// @param constant_id the pipeline constant ID
|
||||
Variable(const ast::Variable* declaration,
|
||||
const sem::Type* type,
|
||||
uint16_t constant_id);
|
||||
ast::Access access);
|
||||
|
||||
/// Destructor
|
||||
~Variable() override;
|
||||
@@ -74,32 +66,109 @@ class Variable : public Castable<Variable, Node> {
|
||||
/// @returns the access control for the variable
|
||||
ast::Access Access() const { return access_; }
|
||||
|
||||
/// @returns the resource binding point for the variable
|
||||
sem::BindingPoint BindingPoint() const { return binding_point_; }
|
||||
|
||||
/// @returns the expressions that use the variable
|
||||
const std::vector<const VariableUser*>& Users() const { return users_; }
|
||||
|
||||
/// @param user the user to add
|
||||
void AddUser(const VariableUser* user) { users_.emplace_back(user); }
|
||||
|
||||
/// @returns true if this variable is an overridable pipeline constant
|
||||
bool IsPipelineConstant() const { return is_pipeline_constant_; }
|
||||
|
||||
/// @returns the pipeline constant ID associated with the variable
|
||||
uint16_t ConstantId() const { return constant_id_; }
|
||||
|
||||
private:
|
||||
const ast::Variable* const declaration_;
|
||||
const sem::Type* const type_;
|
||||
ast::StorageClass const storage_class_;
|
||||
ast::Access const access_;
|
||||
sem::BindingPoint binding_point_;
|
||||
std::vector<const VariableUser*> users_;
|
||||
const bool is_pipeline_constant_;
|
||||
const uint16_t constant_id_ = 0;
|
||||
};
|
||||
|
||||
/// LocalVariable is a function-scope variable
|
||||
class LocalVariable : public Castable<LocalVariable, Variable> {
|
||||
public:
|
||||
/// Constructor
|
||||
/// @param declaration the AST declaration node
|
||||
/// @param type the variable type
|
||||
/// @param storage_class the variable storage class
|
||||
/// @param access the variable access control type
|
||||
LocalVariable(const ast::Variable* declaration,
|
||||
const sem::Type* type,
|
||||
ast::StorageClass storage_class,
|
||||
ast::Access access);
|
||||
|
||||
/// Destructor
|
||||
~LocalVariable() override;
|
||||
};
|
||||
|
||||
/// GlobalVariable is a module-scope variable
|
||||
class GlobalVariable : public Castable<GlobalVariable, Variable> {
|
||||
public:
|
||||
/// Constructor for non-overridable constants
|
||||
/// @param declaration the AST declaration node
|
||||
/// @param type the variable type
|
||||
/// @param storage_class the variable storage class
|
||||
/// @param access the variable access control type
|
||||
/// @param binding_point the optional resource binding point of the variable
|
||||
GlobalVariable(const ast::Variable* declaration,
|
||||
const sem::Type* type,
|
||||
ast::StorageClass storage_class,
|
||||
ast::Access access,
|
||||
sem::BindingPoint binding_point = {});
|
||||
|
||||
/// Constructor for overridable pipeline constants
|
||||
/// @param declaration the AST declaration node
|
||||
/// @param type the variable type
|
||||
/// @param constant_id the pipeline constant ID
|
||||
GlobalVariable(const ast::Variable* declaration,
|
||||
const sem::Type* type,
|
||||
uint16_t constant_id);
|
||||
|
||||
/// Destructor
|
||||
~GlobalVariable() override;
|
||||
|
||||
/// @returns the resource binding point for the variable
|
||||
sem::BindingPoint BindingPoint() const { return binding_point_; }
|
||||
|
||||
/// @returns the pipeline constant ID associated with the variable
|
||||
uint16_t ConstantId() const { return constant_id_; }
|
||||
|
||||
/// @returns true if this variable is an overridable pipeline constant
|
||||
bool IsPipelineConstant() const { return is_pipeline_constant_; }
|
||||
|
||||
private:
|
||||
sem::BindingPoint binding_point_;
|
||||
bool const is_pipeline_constant_;
|
||||
uint16_t const constant_id_ = 0;
|
||||
};
|
||||
|
||||
/// Parameter is a function parameter
|
||||
class Parameter : public Castable<Parameter, Variable> {
|
||||
public:
|
||||
/// Constructor for function parameters
|
||||
/// @param declaration the AST declaration node
|
||||
/// @param type the variable type
|
||||
/// @param storage_class the variable storage class
|
||||
/// @param access the variable access control type
|
||||
/// @param usage the semantic usage for the parameter
|
||||
Parameter(const ast::Variable* declaration,
|
||||
const sem::Type* type,
|
||||
ast::StorageClass storage_class,
|
||||
ast::Access access,
|
||||
const ParameterUsage usage = ParameterUsage::kNone);
|
||||
|
||||
/// Copy constructor
|
||||
Parameter(const Parameter&);
|
||||
|
||||
/// Destructor
|
||||
~Parameter() override;
|
||||
|
||||
/// @returns the semantic usage for the parameter
|
||||
ParameterUsage Usage() const { return usage_; }
|
||||
|
||||
private:
|
||||
ParameterUsage const usage_;
|
||||
};
|
||||
|
||||
/// ParameterList is a list of Parameter
|
||||
using ParameterList = std::vector<const Parameter*>;
|
||||
|
||||
/// VariableUser holds the semantic information for an identifier expression
|
||||
/// node that resolves to a variable.
|
||||
class VariableUser : public Castable<VariableUser, Expression> {
|
||||
|
||||
Reference in New Issue
Block a user