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:
Ben Clayton
2021-07-22 13:24:59 +00:00
parent 66b979d7fb
commit 0f2d95dea3
36 changed files with 435 additions and 277 deletions

View File

@@ -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

View File

@@ -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_

View File

@@ -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)),

View File

@@ -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_;

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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,

View File

@@ -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> {