diff --git a/include/tvm/runtime/relax_vm/bytecode.h b/include/tvm/runtime/relax_vm/bytecode.h index fdafaac1e0bd..4526c6fffa1d 100644 --- a/include/tvm/runtime/relax_vm/bytecode.h +++ b/include/tvm/runtime/relax_vm/bytecode.h @@ -90,6 +90,28 @@ struct Instruction { * \brief The kind of instruction's argument. */ enum class ArgKind : int { kRegister = 0, kImmediate = 1, kConstIdx = 2, kFuncIdx = 3 }; + + friend std::ostream& operator<<(std::ostream& os, const ArgKind& kind) { + switch (kind) { + case ArgKind::kRegister: + os << "kRegister"; + break; + case ArgKind::kImmediate: + os << "kImmediate"; + break; + case ArgKind::kConstIdx: + os << "kConstIdx"; + break; + case ArgKind::kFuncIdx: + os << "kFuncIdx"; + break; + default: + LOG(FATAL) << "Internal error: " + << "Invalid ArgKind with integer value " << static_cast(kind); + } + return os; + } + /*! * \brief The auxiliary data structure for instruction argument. */ diff --git a/src/relax/backend/vm/codegen_vm.cc b/src/relax/backend/vm/codegen_vm.cc index 711b2d4ba52b..caee0a0c13d6 100644 --- a/src/relax/backend/vm/codegen_vm.cc +++ b/src/relax/backend/vm/codegen_vm.cc @@ -357,7 +357,10 @@ class CodeGenVM : public ExprFunctor { RegName EmitKillObject(const Call& call_node) { ICHECK_EQ(call_node->args.size(), 1); Instruction::Arg arg = this->VisitExpr(call_node->args[0]); - ICHECK(arg.kind() == Instruction::ArgKind::kRegister); + ICHECK(arg.kind() == Instruction::ArgKind::kRegister) + << "Expected the object to be killed to be stored in a register, " + << "but argument " << call_node->args[0] << " produced VM instruction of type " + << arg.kind(); RegName dst_reg = arg.value(); builder_->EmitCall("vm.builtin.null_value", {}, dst_reg); return dst_reg;