This is an automated email from the ASF dual-hosted git repository.
tqchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git
The following commit(s) were added to refs/heads/main by this push:
new ded6ad8dd2 [Cleanup] Remove macOS Clang warnings (#19954)
ded6ad8dd2 is described below
commit ded6ad8dd212869c881efb5590f8a33fc972728e
Author: Tianqi Chen <[email protected]>
AuthorDate: Mon Jul 6 09:22:43 2026 +0800
[Cleanup] Remove macOS Clang warnings (#19954)
## Summary
- remove redundant parentheses from four VM dtype comparisons
- clean up pessimizing moves, missing overrides, unused state, and
hidden virtual overloads reported by macOS Clang
- preserve `PrimType` across source-codegen type-bearing paths and
remove transitional raw dtype adapters
- retain raw `DLDataType` only for explicit runtime launch metadata and
runtime-helper boundaries
- leave the deferred LLVM and CMake compatibility paths unchanged
`PrimType::operator==` already compares the represented dtype by code,
bits, and lanes, so no backend-specific non-identity equality regression
is needed.
## Validation
- compiled all original warning-producing translation units with Clang
22 and the relevant warning families promoted to errors
- built `tvm_runtime` and `tvm_compiler` with LLVM 15 after the codegen
migration
- passed 14 focused C-host, bool, OpenCL, Metal, device, and Vulkan
codegen tests, with 70 hardware-dependent skips
- generated OpenCL C, Metal, WGSL, and CUDA source from the same typed
kernel
- compiled the changed Hexagon and Vulkan translation units
independently
- passed pre-commit, Git whitespace/log checks, and a static audit
leaving raw codegen `DLDataType` declarations only at the WebGPU runtime
ABI boundary
---
src/backend/cuda/codegen/codegen_cuda.cc | 17 +++---
src/backend/cuda/codegen/codegen_cuda.h | 3 -
.../hexagon/codegen/llvm/codegen_hexagon.cc | 3 +-
src/backend/metal/codegen/codegen_metal.cc | 29 ++++------
src/backend/opencl/codegen/codegen_opencl.cc | 61 ++++++++++----------
src/backend/opencl/codegen/codegen_opencl.h | 11 ++--
src/backend/trn/codegen/codegen_trn.h | 1 +
src/backend/vulkan/codegen/codegen_spirv.cc | 66 ++++++++++------------
src/backend/webgpu/codegen/codegen_webgpu.cc | 63 ++++++++++-----------
src/relax/ir/expr.cc | 4 +-
src/relax/ir/py_expr_functor.cc | 42 +++++++-------
src/relax/op/tensor/create.cc | 6 +-
src/relax/op/tensor/manipulate.cc | 2 +-
src/relax/transform/attach_global_symbol.cc | 1 +
src/relax/transform/compute_prim_value.cc | 2 +
src/relax/transform/dead_code_elimination.cc | 1 +
src/relax/transform/fuse_tir.cc | 5 +-
src/runtime/vm/builtin.cc | 8 +--
src/target/source/codegen_c.cc | 6 +-
src/target/source/codegen_c.h | 3 -
src/target/source/codegen_c_host.cc | 25 ++++----
src/target/source/codegen_source_base.h | 1 -
src/tirx/transform/storage_rewrite.cc | 2 +
src/tirx/transform/tile_primitive_dispatch.cc | 2 +
24 files changed, 171 insertions(+), 193 deletions(-)
diff --git a/src/backend/cuda/codegen/codegen_cuda.cc
b/src/backend/cuda/codegen/codegen_cuda.cc
index 8cc95bacae..5e65eaa034 100644
--- a/src/backend/cuda/codegen/codegen_cuda.cc
+++ b/src/backend/cuda/codegen/codegen_cuda.cc
@@ -418,7 +418,7 @@ void CodeGenCUDA::PrintType(const PrimType& t,
std::ostream& os) { // NOLINT(*)
fail = true;
}
return;
- } else if (t->dtype == DLDataType{kDLBool, 8, 1}) {
+ } else if (t == PrimType::Bool()) {
os << "bool";
return;
} else if (t.MatchesCode(DLDataTypeCode::kDLBool) && lanes > 1) {
@@ -1641,11 +1641,9 @@ void CodeGenCUDA::VisitStmt_(const AllocBufferNode* op) {
if (scope.find("wmma.") == 0) {
if (scope == "wmma.matrix_a" || scope == "wmma.matrix_b") {
bool supported_wmma_input_dtype = dtype == PrimType::Float(16) || dtype
== PrimType::Int(8) ||
- dtype == PrimType::UInt(8) ||
- dtype == PrimType(DLDataType{kDLInt,
4, 1}) ||
- dtype == PrimType(DLDataType{kDLUInt,
4, 1}) ||
- dtype == PrimType(DLDataType{kDLInt,
1, 1}) ||
- dtype ==
PrimType(DLDataType{kDLBfloat, 16, 1});
+ dtype == PrimType::UInt(8) || dtype ==
PrimType::Int(4) ||
+ dtype == PrimType::UInt(4) || dtype ==
PrimType::Int(1) ||
+ dtype == PrimType::BFloat(16);
TVM_FFI_ICHECK(supported_wmma_input_dtype)
<< "Matrix_a and matrix_b only support half or char or unsigned char
"
<< "or uint4 or int4 or int1 type for now";
@@ -1689,9 +1687,8 @@ void CodeGenCUDA::VisitStmt_(const AllocBufferNode* op) {
if (scope.find("wmma.") == 0) {
constant_size = GetWmmaFragmentSize(scope, buffer, constant_size);
}
- bool is_packed_integer_dtype = dtype == PrimType(DLDataType{kDLInt, 4, 1})
||
- dtype == PrimType(DLDataType{kDLUInt, 4,
1}) ||
- dtype == PrimType(DLDataType{kDLInt, 1, 1});
+ bool is_packed_integer_dtype =
+ dtype == PrimType::Int(4) || dtype == PrimType::UInt(4) || dtype ==
PrimType::Int(1);
if (is_packed_integer_dtype && scope == "shared") {
constant_size = constant_size / (32 / dtype.bits());
}
@@ -1902,7 +1899,7 @@ void CodeGenCUDA::VisitExpr_(const SelectNode* op,
std::ostream& os) {
// The condition is stored as an ushort vector.
int lanes = op_ty.lanes();
- PrimType memory_ty(DLDataType{kDLUInt, 16, static_cast<uint16_t>(lanes)});
+ PrimType memory_ty = PrimType::UInt(16, lanes);
for (int i = 0; i < lanes; ++i) {
std::ostringstream item;
diff --git a/src/backend/cuda/codegen/codegen_cuda.h
b/src/backend/cuda/codegen/codegen_cuda.h
index ce5f24e8e4..3435f0dc9c 100644
--- a/src/backend/cuda/codegen/codegen_cuda.h
+++ b/src/backend/cuda/codegen/codegen_cuda.h
@@ -118,9 +118,6 @@ class CodeGenCUDA final : public CodeGenC {
const std::string barrier_name_ = "barrier";
// The size of the barrier array in shared memory
std::unordered_map<int, int> barrier_count_;
- // The alignment of the barrier array in shared memory
- // Set to 16 to maintain minimum alignment requirements for async bulk copy
- const int barrier_alignment_bytes_ = 16;
// Functions to be added to the util functions during codegen
std::unordered_map<std::string, std::string> util_funcs_;
diff --git a/src/backend/hexagon/codegen/llvm/codegen_hexagon.cc
b/src/backend/hexagon/codegen/llvm/codegen_hexagon.cc
index e7389f84c5..665067ea3a 100644
--- a/src/backend/hexagon/codegen/llvm/codegen_hexagon.cc
+++ b/src/backend/hexagon/codegen/llvm/codegen_hexagon.cc
@@ -202,8 +202,7 @@ llvm::Value* CodeGenHexagon::VisitExpr_(const
BufferLoadNode* op) {
if (!op->buffer.same_as(op->buffer->data)) {
// Check if we can generate a vector lookup.
if (!op->indices[0].as<RampNode>()) {
- if (auto* vlut = VectorLookupLoad(op->buffer,
PrimType(op->ty.as_or_throw<PrimType>()->dtype),
- op->indices)) {
+ if (auto* vlut = VectorLookupLoad(op->buffer,
op->ty.as_or_throw<PrimType>(), op->indices)) {
return vlut;
}
}
diff --git a/src/backend/metal/codegen/codegen_metal.cc
b/src/backend/metal/codegen/codegen_metal.cc
index 607b04ce21..af914f6821 100644
--- a/src/backend/metal/codegen/codegen_metal.cc
+++ b/src/backend/metal/codegen/codegen_metal.cc
@@ -166,14 +166,10 @@ void CodeGenMetal::AddFunction(const GlobalVar& gvar,
const PrimFunc& func) {
if (work_dim != 0) {
// use ushort by default for now
stream << " ";
- PrintType(DLDataType{kDLUInt, static_cast<uint8_t>(thread_index_bits_),
- static_cast<uint16_t>(work_dim)},
- stream);
+ PrintType(PrimType::UInt(thread_index_bits_, work_dim), stream);
stream << " blockIdx [[threadgroup_position_in_grid]],\n";
stream << " ";
- PrintType(DLDataType{kDLUInt, static_cast<uint8_t>(thread_index_bits_),
- static_cast<uint16_t>(work_dim)},
- stream);
+ PrintType(PrimType::UInt(thread_index_bits_, work_dim), stream);
stream << " threadIdx [[thread_position_in_threadgroup]]\n";
}
thread_work_dim_ = work_dim;
@@ -195,18 +191,16 @@ void CodeGenMetal::BindThreadIndex(const IterVar& iv) {
if (thread_work_dim_ <= 1) {
vname = vname.substr(0, iv->thread_tag.length() - 2);
}
- var_idmap_[iv->var.get()] = CastFromTo(
- vname, DLDataType{kDLUInt, static_cast<uint8_t>(thread_index_bits_), 1},
iv->var.ty()->dtype);
+ var_idmap_[iv->var.get()] = CastFromTo(vname,
PrimType::UInt(thread_index_bits_), iv->var.ty());
}
void CodeGenMetal::PrintType(const PrimType& t, std::ostream& os) { //
NOLINT(*)
- const DLDataType& raw_t = t->dtype;
int lanes = t.lanes();
if (t.IsVoid()) {
os << "void";
return;
}
- if (raw_t == DLDataType{kDLBool, 8, 1}) {
+ if (t == PrimType::Bool()) {
os << "bool";
return;
}
@@ -272,7 +266,7 @@ void CodeGenMetal::PrintType(const PrimType& t,
std::ostream& os) { // NOLINT(*
os << "bfloat";
return;
}
- TVM_FFI_THROW(InternalError) << "Cannot convert type " <<
ffi::DLDataTypeToString(raw_t)
+ TVM_FFI_THROW(InternalError) << "Cannot convert type " <<
ffi::DLDataTypeToString(t->dtype)
<< " to Metal type";
}
@@ -329,14 +323,13 @@ void CodeGenMetal::VisitStmt_(const AllocBufferNode* op) {
auto scope = GetPtrStorageScope(op->buffer->data);
alloc_storage_scope_[op->buffer->data.get()] = scope;
- DLDataType dtype = op->buffer->dtype->dtype;
+ const PrimType& dtype = op->buffer->dtype;
if (scope == "metal.simdgroup") {
- bool supported_simdgroup_dtype = dtype == DLDataType{kDLFloat, 16, 1} ||
- dtype == DLDataType{kDLFloat, 32, 1} ||
- dtype == DLDataType{kDLBfloat, 16, 1};
+ bool supported_simdgroup_dtype = dtype == PrimType::Float(16) || dtype ==
PrimType::Float(32) ||
+ dtype == PrimType::BFloat(16);
TVM_FFI_ICHECK(supported_simdgroup_dtype)
<< "Only float16, float32, and bfloat16 are supported, but got "
- << ffi::DLDataTypeToString(dtype);
+ << ffi::DLDataTypeToString(dtype->dtype);
TVM_FFI_ICHECK(constant_size % 64 == 0)
<< "Only 8x8 matrix is supported, but got " << constant_size << "
bytes\n";
@@ -365,7 +358,7 @@ void CodeGenMetal::VisitExpr_(const SelectNode* op,
std::ostream& os) { // NOLI
void CodeGenMetal::VisitExpr_(const BroadcastNode* op, std::ostream& os) { //
NOLINT(*)
std::string v = PrintExpr(op->value);
int lanes = op->ty.as_or_throw<PrimType>().lanes();
- PrintType(op->ty.as_or_throw<PrimType>()->dtype, os);
+ PrintType(op->ty.as_or_throw<PrimType>(), os);
os << "(";
for (int i = 0; i < lanes; ++i) {
if (i != 0) os << ", ";
@@ -432,7 +425,7 @@ void CodeGenMetal::VisitExpr_(const CallNode* op,
std::ostream& os) { // NOLINT
}
// generate as_type<TYPE>(ARG)
os << "(as_type<";
- this->PrintType(op->ty.as_or_throw<PrimType>()->dtype, os);
+ this->PrintType(op->ty.as_or_throw<PrimType>(), os);
os << ">(";
this->PrintExpr(op->args[0], os);
os << "))";
diff --git a/src/backend/opencl/codegen/codegen_opencl.cc
b/src/backend/opencl/codegen/codegen_opencl.cc
index 93e925a6b4..d1d19a2fe4 100644
--- a/src/backend/opencl/codegen/codegen_opencl.cc
+++ b/src/backend/opencl/codegen/codegen_opencl.cc
@@ -43,6 +43,7 @@ class InferTextureAccess : public StmtExprVisitor {
static constexpr const uint8_t kWriteAccess = 2;
InferTextureAccess() {}
+ using StmtExprVisitor::VisitExpr_;
std::unordered_map<const VarNode*, std::string> Infer(const Stmt& n) {
StmtExprVisitor::VisitStmt(n);
std::unordered_map<const VarNode*, std::string> storage_scope_qualifiers;
@@ -57,7 +58,7 @@ class InferTextureAccess : public StmtExprVisitor {
}
return storage_scope_qualifiers;
}
- void VisitExpr_(const CallNode* op) {
+ void VisitExpr_(const CallNode* op) final {
if (op->op.same_as(builtin::texture2d_load())) {
var_access_map_[op->args[0].as<VarNode>()] |= kReadAccess;
} else if (op->op.same_as(builtin::texture2d_store())) {
@@ -190,17 +191,16 @@ void CodeGenOpenCL::BindThreadIndex(const IterVar& iv) {
} else {
os << "get_group_id(" << ts.dim_index << ")";
}
- var_idmap_[iv->var.get()] = CastFromTo(os.str(), DLDataType{kDLUInt, 64, 1},
iv->var.ty()->dtype);
+ var_idmap_[iv->var.get()] = CastFromTo(os.str(), PrimType::UInt(64),
iv->var.ty());
}
void CodeGenOpenCL::PrintType(const PrimType& t, std::ostream& os) { //
NOLINT(*)
- const DLDataType& raw_t = t->dtype;
int lanes = t.lanes();
if (t.IsVoid()) {
os << "void";
return;
}
- if (raw_t == DLDataType{kDLBool, 8, 1}) {
+ if (t == PrimType::Bool()) {
os << "bool";
return;
}
@@ -263,7 +263,7 @@ void CodeGenOpenCL::PrintType(const PrimType& t,
std::ostream& os) { // NOLINT(
return;
}
}
- TVM_FFI_THROW(InternalError) << "Cannot convert type " <<
ffi::DLDataTypeToString(raw_t)
+ TVM_FFI_THROW(InternalError) << "Cannot convert type " <<
ffi::DLDataTypeToString(t->dtype)
<< " to OpenCL type";
}
@@ -376,14 +376,15 @@ void CodeGenOpenCL::PrintRestrict(const Var& v,
std::ostream& os) {
}
}
-std::string CodeGenOpenCL::CastFromTo(std::string value, DLDataType from,
DLDataType target) {
+std::string CodeGenOpenCL::CastFromTo(std::string value, const PrimType& from,
+ const PrimType& target) {
if (from == target) return value;
return CastTo(value, target);
}
-std::string CodeGenOpenCL::CastTo(std::string value, DLDataType target) {
+std::string CodeGenOpenCL::CastTo(std::string value, const PrimType& target) {
std::ostringstream os;
- if (target == DLDataType{kDLBool, 8, 1}) {
+ if (target == PrimType::Bool()) {
os << "(";
os << "(";
this->PrintType(target, os);
@@ -422,9 +423,7 @@ void CodeGenOpenCL::VisitExpr_(const CallNode* op,
std::ostream& os) {
if (it != alloc_storage_scope_.end()) {
PrintStorageScope(it->second, os);
}
- this->PrintType(DLDataType{load->ty.as_or_throw<PrimType>()->dtype.code,
- load->ty.as_or_throw<PrimType>()->dtype.bits,
1},
- os);
+ this->PrintType(load->ty.as_or_throw<PrimType>().WithLanes(1), os);
os << " *)" << this->GetVarID(load->buffer->data.get()) << " + ";
this->PrintExpr(load->indices[0], os);
os << ')';
@@ -436,14 +435,13 @@ void CodeGenOpenCL::VisitExpr_(const CallNode* op,
std::ostream& os) {
const int channel_size = op->args[4].as_or_throw<IntImm>()->value;
TVM_FFI_ICHECK(channel_size == 64 || channel_size == 128)
<< "Unsupported Channel Size: " << channel_size;
- DLDataType channel_type = runtime::GetChannelType(channel_size);
+ PrimType channel_type(runtime::GetChannelType(channel_size));
- DLDataType buffer_type = ptr_type->element_type.as<PrimTypeNode>()->dtype;
+ PrimType buffer_type = ptr_type->element_type.as_or_throw<PrimType>();
std::stringstream ss;
this->PrintExpr(op->args[5].as_or_throw<PrimExpr>(), ss);
std::string value;
- value =
- this->SSAGetID(ss.str(), PrimType(buffer_type).WithLanes(channel_size
/ buffer_type.bits));
+ value = this->SSAGetID(ss.str(), buffer_type.WithLanes(channel_size /
buffer_type.bits()));
if (channel_size == 64) {
os << "write_imageh(";
} else if (channel_size == 128) {
@@ -475,7 +473,7 @@ void CodeGenOpenCL::VisitExpr_(const CallNode* op,
std::ostream& os) {
TVM_FFI_ICHECK(channel_size == 64 || channel_size == 128)
<< "Unsupported Channel Size: " << channel_size;
ss << "as_";
- this->PrintType(op_ty.WithLanes(data_lanes)->dtype, ss);
+ this->PrintType(op_ty.WithLanes(data_lanes), ss);
ss << "(";
if (channel_size == 64) {
ss << "READ_IMAGEH(";
@@ -505,10 +503,10 @@ void CodeGenOpenCL::VisitExpr_(const CallNode* op,
std::ostream& os) {
os << rhs;
} else if (*tirx::as_const_int(ramp->stride) == 1) {
os << "(*(";
-
this->PrintType(op_ty.WithLanes(*tirx::as_const_int(ramp->lanes))->dtype, os);
+ this->PrintType(op_ty.WithLanes(*tirx::as_const_int(ramp->lanes)), os);
os << "*)";
os << "((";
- this->PrintType(op_ty.WithLanes(1)->dtype, os);
+ this->PrintType(op_ty.WithLanes(1), os);
os << "*)&" << rhs << " + ";
this->PrintExpr(ramp->base, os);
os << "))";
@@ -517,7 +515,7 @@ void CodeGenOpenCL::VisitExpr_(const CallNode* op,
std::ostream& os) {
}
} else {
os << "((";
- this->PrintType(op_ty.WithLanes(1)->dtype, os);
+ this->PrintType(op_ty.WithLanes(1), os);
os << "*)&" << rhs << ")[";
this->PrintExpr(op->args.back().as_or_throw<PrimExpr>(), os);
os << "]";
@@ -548,7 +546,7 @@ void CodeGenOpenCL::VisitExpr_(const BroadcastNode* op,
std::ostream& os) { //
std::string v = PrintExpr(op->value);
int lanes = op->ty.as_or_throw<PrimType>().lanes();
os << "((";
- PrintType(op->ty.as_or_throw<PrimType>()->dtype, os);
+ PrintType(op->ty.as_or_throw<PrimType>(), os);
os << ")(";
for (int i = 0; i < lanes; ++i) {
if (i != 0) os << ", ";
@@ -559,7 +557,7 @@ void CodeGenOpenCL::VisitExpr_(const BroadcastNode* op,
std::ostream& os) { //
void CodeGenOpenCL::VisitExpr_(const RampNode* op, std::ostream& os) { //
NOLINT(*)
os << "((";
- PrintType(op->ty.as_or_throw<PrimType>()->dtype, os);
+ PrintType(op->ty.as_or_throw<PrimType>(), os);
os << ")(";
int lanes = op->ty.as_or_throw<PrimType>().lanes();
for (int i = 0; i < lanes; i++) {
@@ -642,11 +640,11 @@ void CodeGenOpenCL::VisitExpr_(const AndNode* op,
std::ostream& os) {
std::ostringstream oss;
os << "(";
this->PrintExpr(op->a, oss);
- os << CastTo(oss.str(), op->ty.as_or_throw<PrimType>()->dtype);
+ os << CastTo(oss.str(), op->ty.as_or_throw<PrimType>());
oss.str("");
os << " && ";
this->PrintExpr(op->b, oss);
- os << CastTo(oss.str(), op->ty.as_or_throw<PrimType>()->dtype);
+ os << CastTo(oss.str(), op->ty.as_or_throw<PrimType>());
os << ")";
}
@@ -654,32 +652,31 @@ void CodeGenOpenCL::VisitExpr_(const OrNode* op,
std::ostream& os) {
std::ostringstream oss;
os << "(";
this->PrintExpr(op->a, oss);
- os << CastTo(oss.str(), op->ty.as_or_throw<PrimType>()->dtype);
+ os << CastTo(oss.str(), op->ty.as_or_throw<PrimType>());
oss.str("");
os << " || ";
this->PrintExpr(op->b, oss);
- os << CastTo(oss.str(), op->ty.as_or_throw<PrimType>()->dtype);
+ os << CastTo(oss.str(), op->ty.as_or_throw<PrimType>());
os << ")";
}
void CodeGenOpenCL::VisitExpr_(const SelectNode* op, std::ostream& os) {
+ PrimType op_ty = op->ty.as_or_throw<PrimType>();
std::ostringstream oss;
os << "select(";
PrintExpr(op->false_value, oss);
- os << CastFromTo(oss.str(), op->false_value.ty()->dtype,
op->ty.as_or_throw<PrimType>()->dtype);
+ os << CastFromTo(oss.str(), op->false_value.ty(), op_ty);
oss.str("");
os << ", ";
PrintExpr(op->true_value, oss);
- os << CastFromTo(oss.str(), op->true_value.ty()->dtype,
op->ty.as_or_throw<PrimType>()->dtype);
+ os << CastFromTo(oss.str(), op->true_value.ty(), op_ty);
oss.str("");
os << ", ";
PrintExpr(op->condition, oss);
- if (op->ty.as_or_throw<PrimType>().code() == DLDataTypeCode::kDLFloat) {
- os << CastTo(oss.str(),
- DLDataType{kDLInt,
static_cast<uint8_t>(op->ty.as_or_throw<PrimType>().bits()),
-
static_cast<uint16_t>(op->ty.as_or_throw<PrimType>().lanes())});
+ if (op_ty.code() == DLDataTypeCode::kDLFloat) {
+ os << CastTo(oss.str(), PrimType::Int(op_ty.bits(), op_ty.lanes()));
} else {
- os << CastFromTo(oss.str(), op->condition.ty()->dtype,
op->ty.as_or_throw<PrimType>()->dtype);
+ os << CastFromTo(oss.str(), op->condition.ty(), op_ty);
}
os << ")";
}
diff --git a/src/backend/opencl/codegen/codegen_opencl.h
b/src/backend/opencl/codegen/codegen_opencl.h
index 362409fa79..a537a2ede6 100644
--- a/src/backend/opencl/codegen/codegen_opencl.h
+++ b/src/backend/opencl/codegen/codegen_opencl.h
@@ -56,11 +56,12 @@ class CodeGenOpenCL final : public CodeGenC {
std::ostream& os) final; // NOLINT(*)
// the address of load/store
void PrintVecAddr(const BufferNode* buffer, const PrimType& t, PrimExpr base,
- std::ostream& os);
// NOLINT(*)
- void PrintRestrict(const Var& v, std::ostream& os) final;
// NOLINT(*)
- std::string CastFromTo(std::string value, DLDataType from, DLDataType
target); // NOLINT(*)
- std::string CastTo(std::string value, DLDataType target);
// NOLINT(*)
- void SetTextureScope(const std::unordered_map<const VarNode*,
std::string>&); // NOLINT(*)
+ std::ostream& os); // NOLINT(*)
+ void PrintRestrict(const Var& v, std::ostream& os) final; // NOLINT(*)
+ std::string CastFromTo(std::string value, const PrimType& from,
+ const PrimType& target) final;
// NOLINT(*)
+ std::string CastTo(std::string value, const PrimType& target);
// NOLINT(*)
+ void SetTextureScope(const std::unordered_map<const VarNode*,
std::string>&); // NOLINT(*)
// overload visitor
void VisitStmt_(const AllocBufferNode* op) final; //
NOLINT(*)
diff --git a/src/backend/trn/codegen/codegen_trn.h
b/src/backend/trn/codegen/codegen_trn.h
index 853a915faf..bcfd9451b2 100644
--- a/src/backend/trn/codegen/codegen_trn.h
+++ b/src/backend/trn/codegen/codegen_trn.h
@@ -49,6 +49,7 @@ struct NKIInstructionCtx {
class CodeGenTrainium final : public CodeGenC {
public:
explicit CodeGenTrainium(Target target);
+ using CodeGenC::PrintType;
using CodeGenC::VisitExpr_;
using CodeGenC::VisitStmt_;
// override print thread tag.
diff --git a/src/backend/vulkan/codegen/codegen_spirv.cc
b/src/backend/vulkan/codegen/codegen_spirv.cc
index 75ca467872..1165dbd78d 100644
--- a/src/backend/vulkan/codegen/codegen_spirv.cc
+++ b/src/backend/vulkan/codegen/codegen_spirv.cc
@@ -80,7 +80,7 @@ runtime::SPIRVShader CodeGenSPIRV::BuildFunction(const
PrimFunc& f, const std::s
<< "All handles passed to the Vulkan codegen must have a
type_annotation as a "
"PointerType, "
<< "and must point to a PrimType";
- PrimType value_storage_type(prim->dtype);
+ PrimType value_storage_type = ffi::GetRef<PrimType>(prim);
if (value_storage_type == PrimType::Bool()) {
// We need a physically addressable buffer type to support boolean
tensors.
// The loaded byte is cast to bool inside the LoadNode visitor below.
@@ -168,7 +168,7 @@ spirv::Value CodeGenSPIRV::GetThreadIndex(const IterVar&
iv, const PrimExpr& ext
} else {
v = builder_->GetWorkgroupID(ts.dim_index);
}
- return builder_->Cast(builder_->GetSType(PrimType(iv->var.ty()->dtype)), v);
+ return builder_->Cast(builder_->GetSType(iv->var.ty()), v);
}
spirv::Value CodeGenSPIRV::CreateStorageSync(const CallNode* op) {
@@ -212,13 +212,11 @@ spirv::Value CodeGenSPIRV::VisitExpr_(const VarNode* op) {
}
spirv::Value CodeGenSPIRV::VisitExpr_(const IntImmNode* op) {
- return
builder_->IntImm(builder_->GetSType(PrimType(op->ty.as_or_throw<PrimType>()->dtype)),
- op->value);
+ return builder_->IntImm(builder_->GetSType(op->ty.as_or_throw<PrimType>()),
op->value);
}
spirv::Value CodeGenSPIRV::VisitExpr_(const FloatImmNode* op) {
- return
builder_->FloatImm(builder_->GetSType(PrimType(op->ty.as_or_throw<PrimType>()->dtype)),
- op->value);
+ return
builder_->FloatImm(builder_->GetSType(op->ty.as_or_throw<PrimType>()),
op->value);
}
spirv::Value CodeGenSPIRV::VisitExpr_(const StringImmNode* op) {
@@ -227,8 +225,7 @@ spirv::Value CodeGenSPIRV::VisitExpr_(const StringImmNode*
op) {
}
spirv::Value CodeGenSPIRV::VisitExpr_(const CastNode* op) {
- return
builder_->Cast(builder_->GetSType(PrimType(op->ty.as_or_throw<PrimType>()->dtype)),
- MakeValue(op->value));
+ return builder_->Cast(builder_->GetSType(op->ty.as_or_throw<PrimType>()),
MakeValue(op->value));
}
spirv::Value CodeGenSPIRV::VisitExpr_(const AddNode* op) {
@@ -330,8 +327,8 @@ spirv::Value CodeGenSPIRV::VisitExpr_(const CallNode* op) {
for (size_t i = 1; i < op->args.size(); ++i) {
values.push_back(MakeValue(op->args[i]));
}
- return builder_->CallGLSL450(
- builder_->GetSType(PrimType(op->ty.as_or_throw<PrimType>()->dtype)),
inst_id, values);
+ return
builder_->CallGLSL450(builder_->GetSType(op->ty.as_or_throw<PrimType>()),
inst_id,
+ values);
} else if (op->op.same_as(builtin::bitwise_and())) {
TVM_FFI_ICHECK_EQ(op->args.size(), 2U);
spirv::Value a = MakeValue(op->args[0]);
@@ -360,23 +357,20 @@ spirv::Value CodeGenSPIRV::VisitExpr_(const CallNode* op)
{
TVM_FFI_ICHECK_EQ(op->args.size(), 2U);
spirv::Value a = MakeValue(op->args[0]);
spirv::Value b = MakeValue(op->args[1]);
- if (PrimType(op->args[0].as_or_throw<PrimExpr>().ty()->dtype)
- .MatchesCode(DLDataTypeCode::kDLInt)) {
+ if
(op->args[0].as_or_throw<PrimExpr>().ty().MatchesCode(DLDataTypeCode::kDLInt)) {
return builder_->MakeValue(spv::OpShiftRightArithmetic, a.stype, a, b);
} else {
return builder_->MakeValue(spv::OpShiftRightLogical, a.stype, a, b);
}
} else if (op->op.same_as(builtin::reinterpret())) {
- return builder_->MakeValue(spv::OpBitcast,
-
builder_->GetSType(PrimType(op->ty.as_or_throw<PrimType>()->dtype)),
+ return builder_->MakeValue(spv::OpBitcast,
builder_->GetSType(op->ty.as_or_throw<PrimType>()),
MakeValue(op->args[0]));
} else if (op->op.same_as(builtin::large_uint_imm())) {
TVM_FFI_ICHECK_EQ(op->args.size(), 2U);
uint64_t low = static_cast<uint64_t>(AsIntImmNode(op->args[0])->value);
uint64_t high = static_cast<uint64_t>(AsIntImmNode(op->args[1])->value);
uint64_t val = (high << 32U) | low;
- return
builder_->UIntImm(builder_->GetSType(PrimType(op->ty.as_or_throw<PrimType>()->dtype)),
- val);
+ return
builder_->UIntImm(builder_->GetSType(op->ty.as_or_throw<PrimType>()), val);
} else if (op->op.same_as(builtin::tvm_storage_sync())) {
return this->CreateStorageSync(op);
} else if (op->op.same_as(builtin::if_then_else())) {
@@ -404,8 +398,7 @@ spirv::Value CodeGenSPIRV::VisitExpr_(const CallNode* op) {
phi.SetIncoming(1, else_value, else_value_label);
return phi;
} else if (op->op.same_as(builtin::popcount())) {
- return builder_->MakeValue(spv::OpBitCount,
-
builder_->GetSType(PrimType(op->ty.as_or_throw<PrimType>()->dtype)),
+ return builder_->MakeValue(spv::OpBitCount,
builder_->GetSType(op->ty.as_or_throw<PrimType>()),
MakeValue(op->args[0]));
} else if (op->op.same_as(builtin::call_pure_extern())) {
TVM_FFI_ICHECK_GE(op->args.size(), 1U);
@@ -415,7 +408,7 @@ spirv::Value CodeGenSPIRV::VisitExpr_(const CallNode* op) {
for (size_t i = 1; i < op->args.size(); ++i) {
values.push_back(MakeValue(op->args[i]));
}
- PrimType op_dtype(op->ty.as_or_throw<PrimType>()->dtype);
+ PrimType op_dtype = op->ty.as_or_throw<PrimType>();
return builder_->CallKHRIntegerDotProduct(builder_->GetSType(op_dtype),
values, op_dtype);
} else {
TVM_FFI_THROW(InternalError)
@@ -588,7 +581,7 @@ spirv::Value CodeGenSPIRV::VisitExpr_(const BufferLoadNode*
op) {
Var buffer_var = op->buffer->data;
PrimExpr prim_index = op->indices[0];
- PrimType desired_read_type(op->ty.as_or_throw<PrimType>()->dtype);
+ PrimType desired_read_type = op->ty.as_or_throw<PrimType>();
if (desired_read_type == PrimType::Bool()) {
desired_read_type =
boolean_storage_type_.WithLanes(desired_read_type.lanes());
}
@@ -596,7 +589,7 @@ spirv::Value CodeGenSPIRV::VisitExpr_(const BufferLoadNode*
op) {
auto it = storage_info_.find(buffer_var.get());
TVM_FFI_ICHECK(it != storage_info_.end());
StorageInfo& info = it->second;
- info.CheckContentType(desired_read_type,
PrimType(prim_index.ty()->dtype).lanes());
+ info.CheckContentType(desired_read_type, prim_index.ty().lanes());
spirv::SType content_type = builder_->GetSType(info.element_type);
spirv::Value buffer = MakeValue(buffer_var);
@@ -616,7 +609,7 @@ spirv::Value CodeGenSPIRV::VisitExpr_(const BufferLoadNode*
op) {
spirv::Value loaded = builder_->MakeValue(spv::OpLoad, content_type, ptr,
mask);
// OpTypeBool have no physical address/storage. Here, cast from
// the storage type to an OpTypeBool.
- if (PrimType(op->ty.as_or_throw<PrimType>()->dtype) == PrimType::Bool()) {
+ if (op->ty.as_or_throw<PrimType>() == PrimType::Bool()) {
auto spirv_bool = builder_->GetSType(PrimType::Bool());
loaded = builder_->Cast(spirv_bool, loaded);
}
@@ -636,10 +629,8 @@ spirv::Value CodeGenSPIRV::VisitExpr_(const
BufferLoadNode* op) {
} else {
TVM_FFI_THROW(InternalError) << "Cannot perform buffer access of buffer
variable '"
<< buffer_var->name_hint << "' with element
type "
- << info.element_type << " using index of type
"
- << PrimType(prim_index.ty()->dtype)
- << " to produce output of type "
- <<
PrimType(op->ty.as_or_throw<PrimType>()->dtype);
+ << info.element_type << " using index of type
" << prim_index.ty()
+ << " to produce output of type " <<
op->ty.as_or_throw<PrimType>();
return spirv::Value();
}
}
@@ -651,9 +642,10 @@ void CodeGenSPIRV::Scalarize(const PrimExpr& e,
std::function<void(int i, spirv:
f(i, MakeValue(offset));
}
} else {
- spirv::SType etype =
builder_->GetSType(PrimType(e.ty()->dtype).WithLanes(1));
+ PrimType e_type = e.ty();
+ spirv::SType etype = builder_->GetSType(e_type.WithLanes(1));
spirv::Value value = MakeValue(e);
- for (int i = 0; i < PrimType(e.ty()->dtype).lanes(); ++i) {
+ for (int i = 0; i < e_type.lanes(); ++i) {
f(i, builder_->MakeValue(spv::OpCompositeExtract, etype, value, i));
}
}
@@ -665,7 +657,7 @@ spirv::Value CodeGenSPIRV::VisitExpr_(const ShuffleNode*
op) {
<< "of one vector with one index";
spirv::Value vector = MakeValue(op->vectors[0]);
int index = AsIntImmNode(op->indices[0])->value;
- spirv::SType etype =
builder_->GetSType(PrimType(op->ty.as_or_throw<PrimType>()->dtype));
+ spirv::SType etype = builder_->GetSType(op->ty.as_or_throw<PrimType>());
spirv::Value element = builder_->MakeValue(spv::OpCompositeExtract, etype,
vector, index);
return element;
}
@@ -679,7 +671,9 @@ void CodeGenSPIRV::VisitStmt_(const BufferStoreNode* op) {
auto it = storage_info_.find(buffer_var.get());
TVM_FFI_ICHECK(it != storage_info_.end());
StorageInfo& info = it->second;
- info.CheckContentType(PrimType(op->value.ty()->dtype),
PrimType(prim_index.ty()->dtype).lanes());
+ PrimType value_type = op->value.ty();
+ PrimType index_type = prim_index.ty();
+ info.CheckContentType(value_type, index_type.lanes());
spirv::SType content_type = builder_->GetSType(info.element_type);
spirv::Value buffer = MakeValue(buffer_var);
@@ -691,16 +685,16 @@ void CodeGenSPIRV::VisitStmt_(const BufferStoreNode* op) {
mask |= spv::MemoryAccessVolatileMask;
}
- if (PrimType(op->value.ty()->dtype) == info.element_type) {
+ if (value_type == info.element_type) {
// Requested store of a single value. This may be a scalar store
// or a vectorized store, based on the array element type.
- TVM_FFI_ICHECK_EQ(info.element_type, PrimType(op->value.ty()->dtype))
+ TVM_FFI_ICHECK_EQ(info.element_type, value_type)
<< "Vulkan only allow one type access to the same buffer";
spirv::Value index = MakeValue(prim_index);
spirv::Value ptr = builder_->StructArrayAccess(ptr_type, buffer, index);
builder_->MakeInst(spv::OpStore, ptr, value, mask);
- } else if (PrimType(op->value.ty()->dtype).WithLanes(1) ==
info.element_type) {
+ } else if (value_type.WithLanes(1) == info.element_type) {
// Requested store of several arbitrarily located values. Extract
// each value from the composite, then assign to the buffer.
auto f = [&](int i, spirv::Value index) {
@@ -711,10 +705,10 @@ void CodeGenSPIRV::VisitStmt_(const BufferStoreNode* op) {
this->Scalarize(prim_index, f);
} else {
- TVM_FFI_THROW(InternalError) << "Cannot store value of type " <<
PrimType(op->value.ty()->dtype)
+ TVM_FFI_THROW(InternalError) << "Cannot store value of type " << value_type
<< " into buffer variable '" <<
buffer_var->name_hint
<< "' with element type " << info.element_type
- << " using index of type " <<
PrimType(prim_index.ty()->dtype);
+ << " using index of type " << index_type;
}
}
@@ -727,7 +721,7 @@ void CodeGenSPIRV::VisitStmt_(const ForNode* op) {
// loop step
spirv::Value step;
if (op->HasTrivialStep()) {
- step =
PrimType(op->loop_var.ty()->dtype).MatchesCode(DLDataTypeCode::kDLInt)
+ step = op->loop_var.ty().MatchesCode(DLDataTypeCode::kDLInt)
? builder_->IntImm(init_value.stype, 1)
: builder_->UIntImm(init_value.stype, 1);
} else {
diff --git a/src/backend/webgpu/codegen/codegen_webgpu.cc
b/src/backend/webgpu/codegen/codegen_webgpu.cc
index c93d5e3780..cadd169b41 100644
--- a/src/backend/webgpu/codegen/codegen_webgpu.cc
+++ b/src/backend/webgpu/codegen/codegen_webgpu.cc
@@ -65,6 +65,8 @@ class WebGPUWorkgroupInfoCollector : public StmtExprVisitor {
}
private:
+ using StmtExprVisitor::VisitExpr_;
+
void VisitExpr_(const VarNode* op) final {
StmtExprVisitor::VisitExpr_(op);
Var buffer_var = ffi::GetRef<Var>(op);
@@ -292,7 +294,7 @@ runtime::FunctionInfo CodeGenWebGPU::AddFunction(const
PrimFunc& f, bool skip_re
void CodeGenWebGPU::BindThreadIndex(const IterVar& iv) {
TVM_FFI_ICHECK(!var_idmap_.count(iv->var.get()));
std::ostringstream os;
- PrintType(iv->var.ty()->dtype, os);
+ PrintType(iv->var.ty(), os);
if (iv->thread_tag == "blockIdx.x") {
// WebGPU have restriction to limit the maximum size of blockId.x to be
65535
// We allow runtime to spread the load out to blockIdx.z so it can be a
large number.
@@ -309,13 +311,12 @@ void CodeGenWebGPU::BindThreadIndex(const IterVar& iv) {
}
void CodeGenWebGPU::PrintType(const PrimType& t, std::ostream& os) { //
NOLINT(*)
- const DLDataType& raw_t = t->dtype;
int lanes = t.lanes();
if (t.IsVoid()) {
os << "void";
return;
}
- if (raw_t == DLDataType{kDLBool, 8, 1}) {
+ if (t == PrimType::Bool()) {
os << "bool";
return;
}
@@ -346,7 +347,7 @@ void CodeGenWebGPU::PrintType(const PrimType& t,
std::ostream& os) { // NOLINT(
os << "i" << t.bits();
} else {
TVM_FFI_THROW(InternalError) << "CodeGenWebGPU: Cannot convert type "
- << ffi::DLDataTypeToString(raw_t) << " to
WebGPU type";
+ << ffi::DLDataTypeToString(t->dtype) << " to
WebGPU type";
}
if (lanes != 1) {
os << ">";
@@ -389,7 +390,7 @@ void CodeGenWebGPU::PrintVecElemStore(const std::string&
vec, const PrimType& t,
void CodeGenWebGPU::VisitExpr_(const BroadcastNode* op, std::ostream& os) {
// NOLINT(*)
std::string v = PrintExpr(op->value);
int lanes = op->ty.as_or_throw<PrimType>().lanes();
- PrintType(op->ty.as_or_throw<PrimType>()->dtype, os);
+ PrintType(op->ty.as_or_throw<PrimType>(), os);
os << "(";
for (int i = 0; i < lanes; ++i) {
if (i != 0) os << ", ";
@@ -406,7 +407,7 @@ void CodeGenWebGPU::VisitExpr_(const CallNode* op,
std::ostream& os) { // NOLIN
if (op->op.same_as(builtin::reinterpret())) {
// generate bitcast<TYPE>(ARG)
os << "bitcast<";
- this->PrintType(op->ty.as_or_throw<PrimType>()->dtype, os);
+ this->PrintType(op->ty.as_or_throw<PrimType>(), os);
os << ">(";
this->PrintExpr(op->args[0], os);
os << ")";
@@ -430,7 +431,7 @@ void CodeGenWebGPU::VisitExpr_(const CallNode* op,
std::ostream& os) { // NOLIN
std::string cond = PrintExpr(op->args[0]);
this->PrintIndent();
this->stream << "var " << result << " : ";
- PrintType(op->ty.as_or_throw<PrimType>()->dtype, this->stream);
+ PrintType(op->ty.as_or_throw<PrimType>(), this->stream);
this->stream << ";\n";
this->PrintIndent();
this->stream << "if (" << cond << ") {\n";
@@ -463,7 +464,7 @@ void CodeGenWebGPU::VisitExpr_(const CallNode* op,
std::ostream& os) { // NOLIN
}
void CodeGenWebGPU::VisitExpr_(const CastNode* op, std::ostream& os) { //
NOLINT(*)
- PrintType(op->ty.as_or_throw<PrimType>()->dtype, os);
+ PrintType(op->ty.as_or_throw<PrimType>(), os);
os << "(" << PrintExpr(op->value) << ")";
}
@@ -505,7 +506,7 @@ void CodeGenWebGPU::VisitExpr_(const IntImmNode* op,
std::ostream& os) { // NOL
this->MarkConst(temp.str());
os << temp.str();
} else {
- this->PrintType(op->ty.as_or_throw<PrimType>()->dtype, os);
+ this->PrintType(op->ty.as_or_throw<PrimType>(), os);
os << "(" << op->value << ")";
}
}
@@ -535,12 +536,10 @@ void CodeGenWebGPU::VisitExpr_(const BufferLoadNode* op,
std::ostream& os) { //
TVM_FFI_ICHECK_EQ(op->indices.size(), 1) << "Load from non-flat memory not
supported.";
TVM_FFI_ICHECK(!op->predicate.defined()) << "Predicated buffer load is not
supported.";
- DLDataType value_dtype = op->ty.as_or_throw<PrimType>()->dtype;
- PrimType value_ty(value_dtype);
+ PrimType value_ty = op->ty.as_or_throw<PrimType>();
PrimExpr index = op->indices[0];
Var buffer_var = op->buffer->data;
- DLDataType element_dtype = op->buffer->dtype->dtype;
- PrimType element_ty(element_dtype);
+ const PrimType& element_ty = op->buffer->dtype;
int lanes = value_ty.lanes();
std::string buffer_vid = GetVarID(buffer_var.get());
@@ -548,29 +547,28 @@ void CodeGenWebGPU::VisitExpr_(const BufferLoadNode* op,
std::ostream& os) { //
if (value_ty.lanes() == element_ty.lanes()) {
// Direct buffer loading
// Special handle bool loading
- if (value_dtype == DLDataType{kDLBool, 8, 1}) {
- this->PrintType(value_dtype, os);
+ if (value_ty == PrimType::Bool()) {
+ this->PrintType(value_ty, os);
os << "(";
} else {
- TVM_FFI_ICHECK(value_dtype == element_dtype);
+ TVM_FFI_ICHECK(value_ty == element_ty);
}
TVM_FFI_ICHECK_EQ(index.ty().lanes(), 1);
os << buffer_vid << "[" << this->PrintExpr(index) << "]";
// Special handle bool loading
- if (value_dtype == DLDataType{kDLBool, 8, 1}) {
+ if (value_ty == PrimType::Bool()) {
os << ")";
}
} else {
// Vector load from scalar buffer
TVM_FFI_ICHECK_EQ(element_ty.lanes(), 1) << "Can only vector load scalar
array";
- DLDataType value_element_dtype{value_dtype.code, value_dtype.bits, 1};
- TVM_FFI_ICHECK(value_element_dtype == element_dtype)
+ TVM_FFI_ICHECK(value_ty.WithLanes(1) == element_ty)
<< "WebGPU vector loading requires base type to match";
arith::PVar<PrimExpr> base;
if (arith::ramp(base, 1, value_ty.lanes()).Match(index)) {
// vec3<f32>(buf[base + 0], buf[base + 1], buf[base + 2]);
std::string base_vid = SSAGetID(PrintExpr(base.Eval()),
base.Eval().ty());
- PrintType(element_ty.WithLanes(value_ty.lanes())->dtype, os);
+ PrintType(element_ty.WithLanes(value_ty.lanes()), os);
os << "(";
for (int i = 0; i < lanes; ++i) {
if (i != 0) os << ", ";
@@ -580,7 +578,7 @@ void CodeGenWebGPU::VisitExpr_(const BufferLoadNode* op,
std::ostream& os) { //
} else {
// vec3<f32>(buf[index[0]], buf[index[1]], buf[index[2]]);
std::string index_vid = SSAGetID(PrintExpr(index), index.ty());
- PrintType(element_ty.WithLanes(value_ty.lanes())->dtype, os);
+ PrintType(element_ty.WithLanes(value_ty.lanes()), os);
os << "(";
for (int i = 0; i < lanes; ++i) {
if (i != 0) os << ", ";
@@ -610,10 +608,8 @@ void CodeGenWebGPU::VisitStmt_(const BufferStoreNode* op) {
TVM_FFI_ICHECK_EQ(op->indices.size(), 1) << "Store to non-flat memory not
supported.";
TVM_FFI_ICHECK(!op->predicate.defined()) << "Predicated buffer store is not
supported.";
- DLDataType value_dtype = op->value.ty()->dtype;
- PrimType value_ty(value_dtype);
- DLDataType element_dtype = op->buffer->dtype->dtype;
- PrimType element_ty(element_dtype);
+ PrimType value_ty = op->value.ty();
+ const PrimType& element_ty = op->buffer->dtype;
PrimExpr index = op->indices[0];
Var buffer_var = op->buffer->data;
@@ -628,23 +624,22 @@ void CodeGenWebGPU::VisitStmt_(const BufferStoreNode* op)
{
this->PrintIndent();
stream << buffer_vid << "[" << index_vid << "] = ";
// special explicit conversion of bool
- if (value_dtype == DLDataType{kDLBool, 8, 1}) {
- PrintType(element_dtype, stream);
+ if (value_ty == PrimType::Bool()) {
+ PrintType(element_ty, stream);
stream << "(";
} else {
- TVM_FFI_ICHECK(value_dtype == element_dtype);
+ TVM_FFI_ICHECK(value_ty == element_ty);
}
stream << value_vid;
// Special handle bool store
- if (value_dtype == DLDataType{kDLBool, 8, 1}) {
+ if (value_ty == PrimType::Bool()) {
stream << ")";
}
stream << ";\n";
} else {
// Vector store into scalar buffer
TVM_FFI_ICHECK_EQ(element_ty.lanes(), 1) << "Can only vector load scalar
array";
- DLDataType value_element_dtype{value_dtype.code, value_dtype.bits, 1};
- TVM_FFI_ICHECK(value_element_dtype == element_dtype)
+ TVM_FFI_ICHECK(value_ty.WithLanes(1) == element_ty)
<< "WebGPU vector stire requires base type to match";
std::string value_vid = PrintExpr(op->value);
arith::PVar<PrimExpr> base;
@@ -684,12 +679,12 @@ void CodeGenWebGPU::VisitStmt_(const AllocBufferNode* op)
{
if (storage_scope.rank == runtime::StorageRank::kShared) {
this->decl_stream << "var<workgroup> " << vid << " : array<";
- PrintType(op->buffer->dtype->dtype, this->decl_stream);
+ PrintType(op->buffer->dtype, this->decl_stream);
this->decl_stream << ", " << constant_size << ">;\n";
} else if (storage_scope.rank == runtime::StorageRank::kLocal) {
this->PrintIndent();
this->stream << "var " << vid << " : array<";
- PrintType(op->buffer->dtype->dtype, this->stream);
+ PrintType(op->buffer->dtype, this->stream);
this->stream << ", " << constant_size << ">;\n";
} else {
TVM_FFI_THROW(InternalError) << "WebGPU: Do not support storage scope: "
@@ -705,7 +700,7 @@ void CodeGenWebGPU::VisitStmt_(const ForNode* op) {
std::string vid = AllocVarID(op->loop_var.get());
PrintIndent();
stream << "for (var " << vid << " : ";
- PrintType(op->loop_var.ty()->dtype, stream);
+ PrintType(op->loop_var.ty(), stream);
stream << " = " << begin_str << "; " << vid << " < " << end_str << "; " <<
vid;
if (step_str.empty()) {
stream << "++";
diff --git a/src/relax/ir/expr.cc b/src/relax/ir/expr.cc
index 798f149c3c..0f35d34ba9 100644
--- a/src/relax/ir/expr.cc
+++ b/src/relax/ir/expr.cc
@@ -150,7 +150,7 @@ Var::Var(Id vid, ffi::Optional<Type> ty_annotation, Span
span) {
ffi::ObjectPtr<VarNode> n = ffi::make_object<VarNode>();
n->vid = std::move(vid);
if (ty_annotation.defined()) {
- n->ty = std::move(ty_annotation.value());
+ n->ty = ty_annotation.value();
}
n->span = std::move(span);
data_ = std::move(n);
@@ -189,7 +189,7 @@ DataflowVar::DataflowVar(Id vid, ffi::Optional<Type>
ty_annotation, Span span) {
ffi::ObjectPtr<DataflowVarNode> n = ffi::make_object<DataflowVarNode>();
n->vid = std::move(vid);
if (ty_annotation.defined()) {
- n->ty = std::move(ty_annotation.value());
+ n->ty = ty_annotation.value();
}
n->span = std::move(span);
data_ = std::move(n);
diff --git a/src/relax/ir/py_expr_functor.cc b/src/relax/ir/py_expr_functor.cc
index 30f90eddc2..1257948663 100644
--- a/src/relax/ir/py_expr_functor.cc
+++ b/src/relax/ir/py_expr_functor.cc
@@ -97,7 +97,7 @@ class PyExprVisitorNode : public ffi::Object, public
ExprVisitor {
/*! \brief The packed function to the `VisitSpan(const Span& span)`
function. */
ffi::Function f_visit_span{nullptr};
- void VisitExpr(const Expr& expr) {
+ void VisitExpr(const Expr& expr) override {
if (f_visit_expr != nullptr) {
f_visit_expr(expr);
} else {
@@ -115,36 +115,36 @@ class PyExprVisitorNode : public ffi::Object, public
ExprVisitor {
PY_EXPR_VISITOR_DEFAULT(ffi::GetRef<Expr>(op), f_visit_expr_fallback_,
ExprVisitor::VisitExprFallback_(op));
- void VisitBinding(const Binding& binding)
+ void VisitBinding(const Binding& binding) override
PY_EXPR_VISITOR_DEFAULT(binding, f_visit_binding,
ExprVisitor::VisitBinding(binding));
- void VisitBinding_(const VarBindingNode* binding)
+ void VisitBinding_(const VarBindingNode* binding) override
PY_EXPR_VISITOR_DEFAULT(ffi::GetRef<VarBinding>(binding),
f_visit_var_binding_,
ExprVisitor::VisitBinding_(binding));
- void VisitBinding_(const MatchCastNode* binding)
+ void VisitBinding_(const MatchCastNode* binding) override
PY_EXPR_VISITOR_DEFAULT(ffi::GetRef<MatchCast>(binding),
f_visit_match_cast_,
ExprVisitor::VisitBinding_(binding));
- void VisitBindingBlock(const BindingBlock& block)
+ void VisitBindingBlock(const BindingBlock& block) override
PY_EXPR_VISITOR_DEFAULT(block, f_visit_binding_block,
ExprVisitor::VisitBindingBlock(block));
- void VisitBindingBlock_(const BindingBlockNode* block)
+ void VisitBindingBlock_(const BindingBlockNode* block) override
PY_EXPR_VISITOR_DEFAULT(ffi::GetRef<BindingBlock>(block),
f_visit_binding_block_,
ExprVisitor::VisitBindingBlock_(block));
- void VisitBindingBlock_(const DataflowBlockNode* block)
+ void VisitBindingBlock_(const DataflowBlockNode* block) override
PY_EXPR_VISITOR_DEFAULT(ffi::GetRef<DataflowBlock>(block),
f_visit_dataflow_block_,
ExprVisitor::VisitBindingBlock_(block));
- void VisitVarDef(const Var& var)
+ void VisitVarDef(const Var& var) override
PY_EXPR_VISITOR_DEFAULT(var, f_visit_var_def,
ExprVisitor::VisitVarDef(var));
- void VisitVarDef_(const VarNode* var)
+ void VisitVarDef_(const VarNode* var) override
PY_EXPR_VISITOR_DEFAULT(ffi::GetRef<Var>(var), f_visit_var_def_,
ExprVisitor::VisitVarDef_(var));
- void VisitVarDef_(const DataflowVarNode* var)
+ void VisitVarDef_(const DataflowVarNode* var) override
PY_EXPR_VISITOR_DEFAULT(ffi::GetRef<DataflowVar>(var),
f_visit_dataflow_var_def_,
ExprVisitor::VisitVarDef_(var));
- void VisitSpan(const Span& span)
+ void VisitSpan(const Span& span) override
PY_EXPR_VISITOR_DEFAULT(span, f_visit_span,
ExprVisitor::VisitSpan(span));
static void RegisterReflection() {
@@ -342,7 +342,7 @@ class PyExprMutatorNode : public ffi::Object, public
ExprMutator {
/*! \brief The packed function to the `VisitSpan(const Span& span)`
function. */
ffi::Function f_visit_span{nullptr};
- Expr VisitExpr(const Expr& expr) {
+ Expr VisitExpr(const Expr& expr) override {
if (f_visit_expr != nullptr) {
return builder_->Normalize(f_visit_expr(expr).cast<Expr>());
} else {
@@ -358,44 +358,44 @@ class PyExprMutatorNode : public ffi::Object, public
ExprMutator {
PY_EXPR_MUTATOR_DEFAULT(ffi::GetRef<Expr>(op), f_visit_expr_fallback_,
ExprMutator::VisitExprFallback_(op), Expr);
- void VisitBinding(const Binding& binding) {
+ void VisitBinding(const Binding& binding) override {
if (f_visit_binding != nullptr)
f_visit_binding(binding);
else
ExprMutator::VisitBinding(binding);
}
- void VisitBinding_(const VarBindingNode* binding) {
+ void VisitBinding_(const VarBindingNode* binding) override {
if (f_visit_var_binding_ != nullptr)
f_visit_var_binding_(ffi::GetRef<VarBinding>(binding));
else
ExprMutator::VisitBinding_(binding);
}
- void VisitBinding_(const MatchCastNode* binding) {
+ void VisitBinding_(const MatchCastNode* binding) override {
if (f_visit_match_cast_ != nullptr)
f_visit_match_cast_(ffi::GetRef<MatchCast>(binding));
else
ExprMutator::VisitBinding_(binding);
}
- BindingBlock VisitBindingBlock(const BindingBlock& block)
+ BindingBlock VisitBindingBlock(const BindingBlock& block) override
PY_EXPR_MUTATOR_DEFAULT(block, f_visit_binding_block,
ExprMutator::VisitBindingBlock(block),
BindingBlock);
- BindingBlock VisitBindingBlock_(const BindingBlockNode* block)
+ BindingBlock VisitBindingBlock_(const BindingBlockNode* block) override
PY_EXPR_MUTATOR_DEFAULT(ffi::GetRef<BindingBlock>(block),
f_visit_binding_block_,
ExprMutator::VisitBindingBlock_(block),
BindingBlock);
- BindingBlock VisitBindingBlock_(const DataflowBlockNode* block)
+ BindingBlock VisitBindingBlock_(const DataflowBlockNode* block) override
PY_EXPR_MUTATOR_DEFAULT(ffi::GetRef<DataflowBlock>(block),
f_visit_dataflow_block_,
ExprMutator::VisitBindingBlock_(block),
BindingBlock);
- Var VisitVarDef(const Var& var)
+ Var VisitVarDef(const Var& var) override
PY_EXPR_MUTATOR_DEFAULT(var, f_visit_var_def,
ExprMutator::VisitVarDef(var), Var);
- Var VisitVarDef_(const VarNode* var)
+ Var VisitVarDef_(const VarNode* var) override
PY_EXPR_MUTATOR_DEFAULT(ffi::GetRef<Var>(var), f_visit_var_def_,
ExprMutator::VisitVarDef_(var), Var);
- Var VisitVarDef_(const DataflowVarNode* var)
+ Var VisitVarDef_(const DataflowVarNode* var) override
PY_EXPR_MUTATOR_DEFAULT(ffi::GetRef<DataflowVar>(var),
f_visit_dataflow_var_def_,
ExprMutator::VisitVarDef_(var), Var);
diff --git a/src/relax/op/tensor/create.cc b/src/relax/op/tensor/create.cc
index d257852413..09f842e9d8 100644
--- a/src/relax/op/tensor/create.cc
+++ b/src/relax/op/tensor/create.cc
@@ -276,7 +276,7 @@ Type InferTypeEye(const Call& call, const BlockBuilder&
ctx) {
<< call->args.size() << " arguments";
}
- auto get_prim_value = [&ctx](const Expr& expr, std::string key) {
+ auto get_prim_value = [](const Expr& expr, std::string key) {
auto prim_value = expr.as<PrimExpr>();
if (!prim_value) {
TVM_FFI_VISIT_THROW(TypeError, expr)
@@ -360,7 +360,7 @@ Type InferTypeArange(const Call& call, const BlockBuilder&
ctx) {
<< call->args.size() << " arguments";
}
// TODO(Siyuan): Support indirect prim_values
- auto get_prim_value = [&ctx](const Expr& expr, std::string key) {
+ auto get_prim_value = [](const Expr& expr, std::string key) {
auto prim_value = expr.as<PrimExpr>();
if (!prim_value) {
TVM_FFI_VISIT_THROW(TypeError, expr)
@@ -421,7 +421,7 @@ Type InferTypeHammingWindow(const Call& call, const
BlockBuilder& ctx) {
TVM_FFI_VISIT_THROW(TypeError, call)
<< "Hamming Window expects the datatype to be float but got " << dtype;
}
- auto get_prim_value = [&ctx](const Expr& expr, std::string key) {
+ auto get_prim_value = [](const Expr& expr, std::string key) {
auto prim_value = expr.as<PrimExpr>();
if (!prim_value) {
TVM_FFI_VISIT_THROW(TypeError, expr) << "Hamming_window expects the `"
<< key
diff --git a/src/relax/op/tensor/manipulate.cc
b/src/relax/op/tensor/manipulate.cc
index 74727ac9a3..d9c1b35931 100644
--- a/src/relax/op/tensor/manipulate.cc
+++ b/src/relax/op/tensor/manipulate.cc
@@ -3016,7 +3016,7 @@ Type InferTypeSliceScatter(const Call& call, const
BlockBuilder& ctx) {
}
}
- auto get_prim_expr_from_arg = [&ctx, &call](const Expr& arg_expr,
std::string key) -> PrimExpr {
+ auto get_prim_expr_from_arg = [&call](const Expr& arg_expr, std::string key)
-> PrimExpr {
auto prim_value = arg_expr.as<PrimExpr>();
if (!prim_value) {
TVM_FFI_VISIT_THROW(TypeError, call)
diff --git a/src/relax/transform/attach_global_symbol.cc
b/src/relax/transform/attach_global_symbol.cc
index e8f5d368d0..cdefafb7f7 100644
--- a/src/relax/transform/attach_global_symbol.cc
+++ b/src/relax/transform/attach_global_symbol.cc
@@ -57,6 +57,7 @@ struct TirxGvarMutator : tirx::StmtExprMutator {
explicit TirxGvarMutator(ffi::Map<GlobalVar, GlobalVar> replacements)
: replacements(replacements) {}
+ using tirx::StmtExprMutator::VisitExpr_;
Expr VisitExpr_(const CallNode* node) override {
auto call =
tirx::StmtExprMutator::VisitExpr_(node).as_or_throw<tvm::Call>();
if (auto old_gvar = call->op.as<GlobalVar>()) {
diff --git a/src/relax/transform/compute_prim_value.cc
b/src/relax/transform/compute_prim_value.cc
index f82721cb9c..49beccc88f 100644
--- a/src/relax/transform/compute_prim_value.cc
+++ b/src/relax/transform/compute_prim_value.cc
@@ -44,6 +44,8 @@ class PrimExprComputeInjector : public ExprMutator {
IRModule Finalize() const { return builder_->Finalize(); }
private:
+ using ExprMutator::VisitExpr_;
+
Expr VisitExpr_(const CallNode* op) final {
Call call = ffi::GetRef<Call>(op);
if (auto prim_expr = call.as<PrimExpr>()) {
diff --git a/src/relax/transform/dead_code_elimination.cc
b/src/relax/transform/dead_code_elimination.cc
index e80ac2fbac..10b6a1d7c0 100644
--- a/src/relax/transform/dead_code_elimination.cc
+++ b/src/relax/transform/dead_code_elimination.cc
@@ -61,6 +61,7 @@ struct RelaxCalleeCollector : relax::ExprVisitor {
struct TIRxCalleeCollector : tirx::StmtExprVisitor {
std::vector<GlobalVar>* callees;
explicit TIRxCalleeCollector(std::vector<GlobalVar>* out) : callees(out) {}
+ using tirx::StmtExprVisitor::VisitExpr_;
void VisitExpr_(const CallNode* node) final {
tirx::StmtExprVisitor::VisitExpr_(node);
if (auto opt_gvar = node->op.as<GlobalVar>()) {
diff --git a/src/relax/transform/fuse_tir.cc b/src/relax/transform/fuse_tir.cc
index d28a0e0ea7..e3b00defe6 100644
--- a/src/relax/transform/fuse_tir.cc
+++ b/src/relax/transform/fuse_tir.cc
@@ -57,7 +57,8 @@ class SymbolicMatcher : ExprFunctor<void(const Expr& n, const
PrimExpr& other)>
}
private:
- void VisitExpr(const PrimExpr& node, const PrimExpr& other) {
+ void VisitExpr(const Expr& expr, const PrimExpr& other) final {
+ PrimExpr node = expr.as_or_throw<PrimExpr>();
if (node.same_as(other)) {
return;
} else if (node.ty().code() != other.ty().code()) {
@@ -65,7 +66,7 @@ class SymbolicMatcher : ExprFunctor<void(const Expr& n, const
PrimExpr& other)>
<< "Parameter expression " << node << " with dtype " <<
node.ty()->dtype
<< " cannot match to argument " << other << " with dtype " <<
other.ty()->dtype;
} else {
- ExprFunctor::VisitExpr(node, other);
+ ExprFunctor::VisitExpr(expr, other);
}
}
diff --git a/src/runtime/vm/builtin.cc b/src/runtime/vm/builtin.cc
index c23fbd868f..162cc59ba9 100644
--- a/src/runtime/vm/builtin.cc
+++ b/src/runtime/vm/builtin.cc
@@ -310,13 +310,13 @@ void CheckPrimValueInfo(ffi::AnyView arg, DLDataType
dtype, ffi::Optional<ffi::S
TVM_FFI_THROW(TypeError) << err_ctx.value_or("") << ", expected dtype " <<
dtype
<< ", but received ObjectRef of type "
<< opt_obj.value()->GetTypeKey();
- } else if (((dtype).code == kDLBool)) {
+ } else if (dtype.code == kDLBool) {
arg.cast<bool>();
- } else if (((dtype).code == kDLInt)) {
+ } else if (dtype.code == kDLInt) {
arg.cast<int64_t>();
- } else if (((dtype).code == kDLUInt)) {
+ } else if (dtype.code == kDLUInt) {
arg.cast<uint64_t>();
- } else if (((dtype).code == kDLFloat)) {
+ } else if (dtype.code == kDLFloat) {
arg.cast<double>();
} else if (dtype.code == kDLOpaqueHandle && !(dtype.bits == 0 && dtype.lanes
== 0)) {
arg.cast<void*>();
diff --git a/src/target/source/codegen_c.cc b/src/target/source/codegen_c.cc
index abec9a6b1a..8bf390a508 100644
--- a/src/target/source/codegen_c.cc
+++ b/src/target/source/codegen_c.cc
@@ -485,9 +485,9 @@ inline void PrintConst(const IntImmNode* op, std::ostream&
os, CodeGenC* p) { /
}
}
-inline void PrintUIntConst(DLDataType dtype, uint64_t val, std::ostream& os,
+inline void PrintUIntConst(const PrimType& dtype, uint64_t val, std::ostream&
os,
CodeGenC* p) { // NOLINT(*)
- if (dtype == DLDataType{kDLUInt, 32, 1}) {
+ if (dtype == PrimType::UInt(32)) {
std::ostringstream temp;
temp << val << "U";
p->MarkConst(temp.str());
@@ -704,7 +704,7 @@ void CodeGenC::VisitExpr_(const CallNode* op, std::ostream&
os) { // NOLINT(*)
uint64_t low =
static_cast<uint64_t>(op->args[0].as_or_throw<IntImm>()->value);
uint64_t high =
static_cast<uint64_t>(op->args[1].as_or_throw<IntImm>()->value);
uint64_t val = (high << 32U) | low;
- PrintUIntConst(op->ty.as_or_throw<PrimType>()->dtype, val, os, this);
+ PrintUIntConst(op->ty.as_or_throw<PrimType>(), val, os, this);
} else if (op->op.same_as(builtin::bitwise_xor())) {
PrintBinaryIntrinsic(op, " ^ ", os, this);
} else if (op->op.same_as(builtin::bitwise_or())) {
diff --git a/src/target/source/codegen_c.h b/src/target/source/codegen_c.h
index 5b8ae8c185..a937a96a99 100644
--- a/src/target/source/codegen_c.h
+++ b/src/target/source/codegen_c.h
@@ -233,9 +233,6 @@ class CodeGenC : public ExprFunctor<void(const Expr&,
std::ostream&)>,
virtual void PrintVecConstructor(const PrimType& t, std::ostream& os);
// Get a cast type from to
virtual std::string CastFromTo(std::string value, const PrimType& from,
const PrimType& target);
- std::string CastFromTo(std::string value, DLDataType from, DLDataType
target) {
- return CastFromTo(std::move(value), PrimType(from), PrimType(target));
- }
// Get load of single element with expression
virtual void PrintVecElemLoadExpr(const PrimType& t, int i, const
std::string& value,
std::ostream& os);
diff --git a/src/target/source/codegen_c_host.cc
b/src/target/source/codegen_c_host.cc
index c37dee2957..709b3ec4a9 100644
--- a/src/target/source/codegen_c_host.cc
+++ b/src/target/source/codegen_c_host.cc
@@ -122,24 +122,23 @@ void CodeGenCHost::PrintFuncPrefix(std::ostream& os) {
// NOLINT(*)
}
void CodeGenCHost::PrintType(const PrimType& type, std::ostream& os) { //
NOLINT(*)
- const DLDataType& t = type->dtype;
- int lanes = static_cast<int16_t>(t.lanes);
- if (t.code == kDLOpaqueHandle && !(t.bits == 0 && lanes == 0)) {
+ int lanes = type.lanes();
+ if (type.MatchesCode(DLDataTypeCode::kDLOpaqueHandle) && !type.IsVoid()) {
TVM_FFI_ICHECK_EQ(lanes, 1) << "does not support vector types";
os << "void*";
return;
}
- if (t.code == kDLOpaqueHandle && t.bits == 0 && lanes == 0) {
+ if (type.IsVoid()) {
os << "void";
return;
}
- if (t.code == kDLBool && lanes == 1) {
+ if (type.MatchesCode(DLDataTypeCode::kDLBool) && lanes == 1) {
os << "bool";
return;
}
bool fail = false;
- if (t.code == kDLFloat) {
- switch (t.bits) {
+ if (type.MatchesCode(DLDataTypeCode::kDLFloat)) {
+ switch (type.bits()) {
case 16:
os << "half";
break;
@@ -158,11 +157,11 @@ void CodeGenCHost::PrintType(const PrimType& type,
std::ostream& os) { // NOLIN
os << lanes;
return;
}
- } else if (t.code == kDLUInt || t.code == kDLInt) {
- if (t.code == kDLUInt) {
+ } else if (type.MatchesCode(DLDataTypeCode::kDLUInt,
DLDataTypeCode::kDLInt)) {
+ if (type.MatchesCode(DLDataTypeCode::kDLUInt)) {
os << 'u';
}
- switch (t.bits) {
+ switch (type.bits()) {
case 8:
os << "int8_t";
break;
@@ -188,14 +187,14 @@ void CodeGenCHost::PrintType(const PrimType& type,
std::ostream& os) { // NOLIN
return;
}
}
- TVM_FFI_THROW(InternalError) << "Cannot convert type " << t << " to C type";
+ TVM_FFI_THROW(InternalError) << "Cannot convert type " << type->dtype << "
to C type";
}
void CodeGenCHost::VisitExpr_(const BroadcastNode* op, std::ostream& os) { //
NOLINT(*)
std::string v = PrintExpr(op->value);
- int lanes =
static_cast<int16_t>(op->ty.as_or_throw<PrimType>()->dtype.lanes);
+ int lanes = op->ty.as_or_throw<PrimType>().lanes();
os << "((";
- PrintType(op->ty.as_or_throw<PrimType>()->dtype, os);
+ PrintType(op->ty.as_or_throw<PrimType>(), os);
os << ")(";
for (int i = 0; i < lanes; ++i) {
if (i != 0) os << ", ";
diff --git a/src/target/source/codegen_source_base.h
b/src/target/source/codegen_source_base.h
index 0dbeb91325..95b6c00e70 100644
--- a/src/target/source/codegen_source_base.h
+++ b/src/target/source/codegen_source_base.h
@@ -59,7 +59,6 @@ class CodeGenSourceBase {
* \param os The stream to print the ctype into
*/
virtual void PrintType(const PrimType& type, std::ostream& os); // NOLINT(*)
- void PrintType(DLDataType type, std::ostream& os) {
PrintType(PrimType(type), os); }
/*!
* Print Type representation of type type.
* \param type The type representation.
diff --git a/src/tirx/transform/storage_rewrite.cc
b/src/tirx/transform/storage_rewrite.cc
index 425c2a979a..d1b137ca3d 100644
--- a/src/tirx/transform/storage_rewrite.cc
+++ b/src/tirx/transform/storage_rewrite.cc
@@ -1714,6 +1714,8 @@ class VectorTypeRewriter : public StmtExprMutator {
: var_remap_(var_remap) {}
private:
+ using StmtExprMutator::VisitExpr_;
+
Expr VisitExpr_(const VarNode* op) final {
if (auto it = var_remap_.find(op); it != var_remap_.end()) {
return it->second;
diff --git a/src/tirx/transform/tile_primitive_dispatch.cc
b/src/tirx/transform/tile_primitive_dispatch.cc
index 1f3cf77feb..37a0dfae6a 100644
--- a/src/tirx/transform/tile_primitive_dispatch.cc
+++ b/src/tirx/transform/tile_primitive_dispatch.cc
@@ -121,6 +121,7 @@ class ElectSyncFinder : public StmtExprVisitor {
}
private:
+ using StmtExprVisitor::VisitExpr_;
using StmtExprVisitor::VisitStmt_;
void VisitExpr_(const CallNode* op) final {
@@ -149,6 +150,7 @@ class ScopeIdVarFinder : public StmtExprVisitor {
private:
explicit ScopeIdVarFinder(const std::vector<Var>& vars) : vars_(vars) {}
+ using StmtExprVisitor::VisitExpr_;
using StmtExprVisitor::VisitStmt_;
void VisitExpr_(const VarNode* op) final {