diff --git a/taichi/common/exceptions.h b/taichi/common/exceptions.h index d474a87e7d17c..2557cf18b8cc9 100644 --- a/taichi/common/exceptions.h +++ b/taichi/common/exceptions.h @@ -26,6 +26,10 @@ struct DebugInfo { explicit DebugInfo(const char *tb_) : tb(tb_) { } + std::string get_last_tb() const { + return tb; + } + std::string const &get_tb() const { return tb; } @@ -141,7 +145,7 @@ struct ErrorEmitter { // tb here error.msg_ = error_msg; } else { - error.msg_ = p_dbg_info->get_tb() + error_msg; + error.msg_ = p_dbg_info->get_last_tb() + error_msg; } if constexpr (std::is_base_of_v>) { diff --git a/taichi/ir/control_flow_graph.cpp b/taichi/ir/control_flow_graph.cpp index a78259e663cf2..6ca5c849761c8 100644 --- a/taichi/ir/control_flow_graph.cpp +++ b/taichi/ir/control_flow_graph.cpp @@ -3,6 +3,7 @@ #include #include +#include "taichi/common/exceptions.h" #include "taichi/ir/analysis.h" #include "taichi/ir/statements.h" #include "taichi/system/profiler.h" @@ -337,8 +338,11 @@ Stmt *CFGNode::get_store_forwarding_data(Stmt *var, int position) const { } if (!result) { // The UD-chain is empty. - TI_WARN("stmt {} loaded in stmt {} before storing.", var->id, - block->statements[position]->id); + auto offending_load = block->statements[position].get(); + ErrorEmitter( + TaichiIrWarning(), offending_load, + fmt::format("Loading variable {} before anything is stored to it.", + var->id)); return nullptr; } if (!result_visible) { diff --git a/taichi/ir/expression.h b/taichi/ir/expression.h index 1a9c6642de345..fb04b3e7fe338 100644 --- a/taichi/ir/expression.h +++ b/taichi/ir/expression.h @@ -64,6 +64,10 @@ class Expression { return stmt; } + std::string get_last_tb() const { + return dbg_info.get_last_tb(); + } + std::string const &get_tb() const { return dbg_info.tb; } diff --git a/taichi/ir/ir.cpp b/taichi/ir/ir.cpp index cd9924e827caa..c8203778033f0 100644 --- a/taichi/ir/ir.cpp +++ b/taichi/ir/ir.cpp @@ -43,6 +43,14 @@ IRNode *IRNode::get_ir_root() { return node; } +const IRNode *IRNode::get_ir_root() const { + auto node = this; + while (node->get_parent()) { + node = node->get_parent(); + } + return node; +} + std::unique_ptr IRNode::clone() { std::unique_ptr new_irnode; if (is()) @@ -139,7 +147,7 @@ Callable *Stmt::get_callable() const { } irpass::print((IRNode *)this); - TI_ASSERT_INFO(false, "Stmt is not in a kernel."); + TI_WARN("Stmt is not in a kernel."); return nullptr; } @@ -195,6 +203,39 @@ IRNode *Stmt::get_parent() const { return parent; } +std::string Stmt::get_last_tb() const { + const auto *callable = get_callable(); + const auto callable_name = callable ? callable->get_name() : ""; + + std::string prefix = + !callable_name.empty() ? "While compiling `" + callable_name + "`, " : ""; + + const auto &tb = dbg_info.tb; + if (tb.empty()) { + // If has no tb, try to find tb from the immediate previous statement + if (parent) { + auto it_this = std::find_if( + parent->statements.rbegin(), parent->statements.rend(), + [this](const pStmt &stmt) { return stmt.get() == this; }); + + while (it_this != parent->statements.rend()) { + const auto &stmt = *it_this; + if (!stmt->get_tb().empty()) { + return prefix + stmt->get_tb(); + } + ++it_this; + } + } + + const auto stmt_type_name = typeid(*this).name(); + + return fmt::format("{}Statement {} (type={});\n", prefix, name(), + cpp_demangle(stmt_type_name)); + } + + return prefix + tb; +} + std::vector Stmt::get_operands() const { std::vector ret; for (int i = 0; i < num_operands(); i++) { diff --git a/taichi/ir/ir.h b/taichi/ir/ir.h index a62b00d834762..6c5541101ff1d 100644 --- a/taichi/ir/ir.h +++ b/taichi/ir/ir.h @@ -235,6 +235,7 @@ class IRNode { virtual IRNode *get_parent() const = 0; IRNode *get_ir_root(); + const IRNode *get_ir_root() const; virtual ~IRNode() = default; @@ -441,6 +442,8 @@ class Stmt : public IRNode { return *operands[i]; } + std::string get_last_tb() const; + TI_FORCE_INLINE std::string const &get_tb() const { return dbg_info.tb; } diff --git a/taichi/program/program.cpp b/taichi/program/program.cpp index 52607b5b8ed04..52a6b51db109d 100644 --- a/taichi/program/program.cpp +++ b/taichi/program/program.cpp @@ -310,6 +310,7 @@ Kernel &Program::get_snode_writer(SNode *snode) { ASTBuilder &builder = kernel->context->builder(); auto expr = builder.expr_subscript(Expr(snode_to_fields_.at(snode)), indices); + expr.type_check(&this->compile_config()); auto argload_expr = Expr::make( std::vector{snode->num_active_indices}, snode->dt->get_compute_type()); diff --git a/taichi/system/demangling.cpp b/taichi/system/demangling.cpp index 0ab9ea47bfd75..c739eb64ff590 100644 --- a/taichi/system/demangling.cpp +++ b/taichi/system/demangling.cpp @@ -9,6 +9,10 @@ #include #endif +#if defined(TI_PLATFORM_WINDOWS) +#include +#endif + namespace taichi { // From https://en.wikipedia.org/wiki/Name_mangling @@ -22,6 +26,12 @@ std::string cpp_demangle(const std::string &mangled_name) { std::string ret(demangled_name); free(demangled_name); return ret; +#elif defined(TI_PLATFORM_WINDOWS) + PCSTR mangled = mangled_name.c_str(); + char demangled[1024]; + DWORD length = + UnDecorateSymbolName(mangled, demangled, 1024, UNDNAME_NAME_ONLY); + return std::string(demangled, size_t(length)); #else TI_NOT_IMPLEMENTED #endif @@ -33,11 +43,7 @@ class Demangling : public Task { printf("There should be at least one parameter for demangling.\n"); } for (auto p : parameters) { -#if !defined(_WIN64) printf("Demangled C++ Identifier: %s\n", cpp_demangle(p).c_str()); -#else - TI_NOT_IMPLEMENTED -#endif } return ""; } diff --git a/taichi/transforms/ir_printer.cpp b/taichi/transforms/ir_printer.cpp index 263904cfd40f9..739ef4a28e18d 100644 --- a/taichi/transforms/ir_printer.cpp +++ b/taichi/transforms/ir_printer.cpp @@ -53,9 +53,9 @@ class IRPrinter : public IRVisitor { if (print_ir_dbg_info) { dbg_info_printer_ = [this](const Stmt *stmt) { auto tb = stmt->get_tb(); - print_raw(tb.empty() ? "No DebugInfo avaliable.\n" - : tb.substr(0, tb.length()), - ""); + if (!tb.empty()) { + this->print_raw(tb.substr(0, tb.length()), ""); + } }; } }