18 #include <unordered_set>
34 switch (scalar_type->kind()) {
35 #define TYPE_INFO_OPTION(tok, c, b) \
51 #undef TYPE_INFO_OPTION
54 <<
"Unhandled TC scalar type: " << scalar_type;
91 throw std::runtime_error(
"Unknown type info?");
121 if (!ta.is_float() && tb.is_float()) {
125 }
else if (ta.is_float() && !tb.is_float()) {
127 }
else if (ta.is_float() && tb.is_float()) {
129 if (ta.bits() > tb.bits())
133 }
else if (ta.is_uint() && tb.is_uint()) {
135 if (ta.bits() > tb.bits())
139 }
else if (!ta.is_float() && !tb.is_float()) {
141 int bits = std::max(ta.bits(), tb.bits());
143 TypeInfo(
TypeInfo::Int, bits).toScalarToken(), a->range(), {});
145 throw ErrorReport(b) <<
"Could not match types: "
164 <<
"INTERNAL ERROR: type not in map for expression " << ref;
170 auto inserted =
expr_to_type.emplace(expr, type).second;
176 if (typ->kind() != TK_TENSOR_TYPE) {
177 throw ErrorReport(loc) <<
"expected a tensor but found a scalar";
182 for (
auto e : list->trees()) {
186 matched_type = match_types(matched_type,
typeOfExpr(e));
192 throw ErrorReport(e) <<
" expected integral type but found "
198 if (token != TK_BOOL) {
200 <<
"expected boolean but found " <<
kindToString(token);
219 switch (exp->kind()) {
227 <<
"tensor accesses cannot be used in this context";
231 auto ident = a.name();
232 if (builtin_functions.count(ident.name()) > 0) {
233 auto nargs = builtin_functions[ident.name()];
234 if (nargs != a.arguments().size()) {
235 throw ErrorReport(exp) <<
"expected " << nargs <<
" but found "
236 << a.arguments().size();
238 auto args =
checkExp(a.arguments(), allow_access);
249 if (type.dims().size() != a.arguments().size()) {
251 <<
"expected " << type.dims().size() <<
" dimensions but found "
252 << a.arguments().size() <<
" dimensions.";
254 auto checked =
checkExp(a.arguments(), allow_access);
255 for (
auto t : checked->trees()) {
260 type.scalarTypeTree());
263 auto ident =
Ident(exp);
265 if (type->kind() == TK_TENSOR_TYPE) {
267 if (tt.dims().size() != 0) {
269 <<
"expected a scalar but found a tensor expression.";
280 auto ident =
s.name();
329 auto nexp =
checkExp(
c.value(), allow_access);
338 throw ErrorReport(exp) <<
"NYI - semantic checking for " << exp;
342 auto func =
Def(func_);
346 for (
auto r : func.returns()) {
347 if (!r.typeIsInferred()) {
352 for (
auto p : func.params())
354 for (
auto r : func.returns())
362 Def::create(func.range(), func.name(), params_, returns_, statements_);
366 return c(TK_INT32, anchor->range(), {});
372 return c(TK_FLOAT, anchor->range(), {});
375 return c(TK_BOOL, anchor->range(), {});
382 for (
const auto& d : tt.dims()) {
384 if (d->kind() == TK_IDENT)
390 auto p =
Param(param);
402 TC_ASSERT(list, list->kind() == TK_LIST);
404 for (
auto e : list->trees()) {
427 if (ref->kind() == TK_LET) {
429 }
else if (ref->kind() == TK_EXISTS) {
440 for (
const auto& index : stmt.indices()) {
441 std::string idx = index.name();
447 std::string name = stmt.ident().name();
449 int n = stmt.indices().size();
450 for (
int i = 0; i < n; ++i) {
453 output_indices.push_back(new_var);
458 auto where_clauses_ = stmt.whereClauses().map(
469 auto tt =
TensorType(output_annotation->second);
470 auto matched_type = match_types(scalar_type, tt.scalarTypeTree());
471 if (tt.scalarTypeTree()->kind() != matched_type->kind()) {
473 <<
" attempting to assign type "
474 <<
kindToString(scalar_type->kind()) <<
" to narrower type "
476 <<
" without an explicit cast";
478 if (tt.dims().size() != stmt.indices().size()) {
480 <<
" tensor defined with " << stmt.indices().size()
481 <<
" dimensions but declared as an output with " << tt.dims().size()
495 auto equivalent_statement_ = stmt.equivalent().map([&](
Equivalent eq) {
501 TreeRef assignment = stmt.assignment();
512 throw ErrorReport(stmt) <<
"this statement includes reduction variable '"
514 <<
"' but does not specify a reduction.";
516 TreeRef reduction_variable_list =
525 equivalent_statement_,
526 reduction_variable_list);
530 << stmt.ident().name()
531 <<
" is not listed as an input or output to this function. Temporaries tensors are not yet implemented";
541 switch (assignment->kind()) {
552 std::stringstream ss;
553 std::vector<std::pair<std::string, TreeRef>> elems(
env.begin(),
env.end());
557 [](
const std::pair<std::string, TreeRef>& t,
558 const std::pair<std::string, TreeRef>& t2) {
559 return t.first < t2.first;
561 for (
auto p : elems) {
562 ss << p.first <<
": " << p.second;
568 using Env = std::unordered_map<std::string, TreeRef>;
571 std::string name = ident.
name();
572 if (builtin_functions.count(name) > 0) {
574 <<
"'" << name <<
"' is a built-in function and cannot be redefined";
576 auto it = the_env.emplace(name, value);
577 if (must_be_undefined && !it.second) {
578 throw ErrorReport(ident) << name <<
" already defined";
590 std::string name = ident.
name();
591 auto it = the_env.find(name);
592 if (required && it == the_env.end()) {
594 <<
"undefined variable " << name <<
" used here.";
596 return it == the_env.end() ?
nullptr : it->second;
static TreeRef create(const SourceRange &range, TreeRef name, TreeRef paramlist, TreeRef retlist, TreeRef stmts_list)
Definition: tree_views.h:348
TreeRef lookup(Ident ident, bool required)
Definition: sema.h:581
static TreeRef create(const SourceRange &range, const std::string &name, TreeRef accesses)
Definition: tree_views.h:244
std::unordered_set< std::string > live_input_names
Definition: sema.h:615
Env let_env
Definition: sema.h:607
const std::string & name() const
Definition: tree_views.h:118
TreeRef matchAllTypes(TreeRef list, TreeRef matched_type=nullptr)
Definition: sema.h:181
TreeRef rhs() const
Definition: tree_views.h:411
bool isNotInplace(TreeRef assignment)
Definition: sema.h:540
uint8_t bits() const
Definition: sema.h:96
Ident name() const
Definition: tree_views.h:408
static TreeRef create(const SourceRange &range, const std::string &name, TreeRef arguments, TreeRef type)
Definition: tree_views.h:171
TreeRef withType(TreeRef expr, TreeRef type)
Definition: sema.h:169
Definition: tree_views.h:256
TreeRef start() const
Definition: tree_views.h:267
std::unordered_map< TreeRef, TreeRef > expr_to_type
Definition: sema.h:159
TreeRef checkExp(TreeRef exp, bool allow_access)
Definition: sema.h:218
Definition: tree_views.h:374
TreeRef typeOfExpr(TreeRef ref)
Definition: sema.h:161
TensorType expectTensorType(TreeRef loc, TreeRef typ)
Definition: sema.h:175
void checkDim(Ident dim)
Definition: sema.h:377
TypeInfo(Code code_, uint8_t bits_)
Definition: sema.h:32
TreeRef checkRangeConstraint(RangeConstraint rc)
Definition: sema.h:409
TreeRef lookup(Env &the_env, Ident ident, bool required)
Definition: sema.h:589
void expectBool(TreeRef anchor, int token)
Definition: sema.h:197
TreeRef floatType(TreeRef anchor)
Definition: sema.h:371
TreeRef checkLet(Let l)
Definition: sema.h:421
static TreeRef create(const SourceRange &range, TreeRef ident, TreeRef start, TreeRef end)
Definition: tree_views.h:261
Definition: tree_views.h:389
Definition: tree_views.h:275
TreeRef c(int kind, const SourceRange &range, TreeList &&trees)
Definition: sema.h:598
static TreeRef create(const SourceRange &range, TreeRef name, TreeRef arguments)
Definition: tree_views.h:149
Definition: tree_views.h:109
bool is_float() const
Definition: sema.h:99
TreeRef dimType(TreeRef anchor)
Definition: sema.h:368
Definition: tree_views.h:359
static TreeRef create(Args &&...args)
Definition: tree.h:100
TreeRef checkParam(TreeRef param)
Definition: sema.h:389
ApplyLike< TK_APPLY > Apply
Definition: tree_views.h:153
static TreeRef create(const SourceRange &range, TreeRef value, TreeRef type)
Definition: tree_views.h:399
static TreeRef create(const SourceRange &range, TreeRef name, TreeRef rhs)
Definition: tree_views.h:414
Definition: tree_views.h:330
void insert(Env &the_env, Ident ident, TreeRef value, bool must_be_undefined)
Definition: sema.h:570
Definition: tree_views.h:404
Code code() const
Definition: sema.h:93
std::vector< TreeRef > reduction_variables
Definition: sema.h:605
#define TYPE_INFO_OPTION(tok, c, b)
Ident ident() const
Definition: tree_views.h:264
std::unordered_map< std::string, TreeRef > Env
Definition: sema.h:568
const SourceRange & range() const
Definition: tree_views.h:29
Env annotated_output_types
Definition: sema.h:610
TreeRef checkFunction(TreeRef func_)
Definition: sema.h:341
static TreeRef create(const SourceRange &range, TreeRef ident, TreeRef indices, TreeRef assignment, TreeRef rhs, TreeRef range_constraints, TreeRef equivalent, TreeRef reduction_variables)
Definition: tree_views.h:279
TreeRef indexType(TreeRef anchor)
Definition: sema.h:365
Env index_env
Definition: sema.h:606
std::vector< TreeRef > TreeList
Definition: tree.h:45
TreeRef lookupVarOrCreateIndex(Ident ident)
Definition: sema.h:207
TreeRef checkReturn(TreeRef ret)
Definition: sema.h:396
TreeRef checkWhereClause(TreeRef ref)
Definition: sema.h:426
TreeRef s(const std::string &s)
Definition: sema.h:601
Code
Definition: sema.h:31
int toScalarToken() const
Definition: sema.h:57
static TreeRef create(const SourceRange &range, const std::string &name)
Definition: tree_views.h:127
static TreeRef create(const SourceRange &range, TreeRef scalar_type_, TreeRef dims_)
Definition: tree_views.h:191
std::string dumpEnv()
Definition: sema.h:551
TreeRef expectBool(TreeRef exp)
Definition: sema.h:203
bool is_uint() const
Definition: sema.h:102
static TreeRef create(const SourceRange &range, TreeList elements)
Definition: tree_views.h:85
std::unordered_set< std::string > nonTemporaries
Definition: sema.h:617
std::string kindToString(int kind)
TreeRef checkTensorType(TreeRef type)
Definition: sema.h:380
Definition: tree_views.h:186
TreeRef checkList(TreeRef list, std::function< TreeRef(TreeRef)> fn)
Definition: sema.h:401
ListView< TreeRef > accesses() const
Definition: tree_views.h:251
TreeRef checkStmt(TreeRef stmt_)
Definition: sema.h:436
TypeInfo(TreeRef scalar_type)
Definition: sema.h:33
Definition: tree_views.h:239
TreeRef expectIntegral(TreeRef e)
Definition: sema.h:190
Definition: error_report.h:22
Env env
Definition: sema.h:609
Definition: tree_views.h:419
static TreeRef create(int kind, const SourceRange &range_, TreeList &&trees_)
Definition: tree.h:155
Definition: tree_views.h:211
const std::string & name() const
Definition: tree_views.h:248
static TreeRef create(const SourceRange &range, TreeRef exp)
Definition: tree_views.h:426
Code code_
Definition: sema.h:107
uint8_t bits_
Definition: sema.h:108
std::shared_ptr< Tree > TreeRef
Definition: tree.h:44
TreeRef end() const
Definition: tree_views.h:270
TreeRef boolType(TreeRef anchor)
Definition: sema.h:374
#define TC_ASSERT(ctx, cond)
Definition: error_report.h:55