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 c962198100 [REFACTOR] Phase out StackVM (#17784)
c962198100 is described below

commit c962198100ca33d7b29ac7d278fafd087f855dec
Author: Tianqi Chen <[email protected]>
AuthorDate: Wed Mar 26 13:15:27 2025 -0400

    [REFACTOR] Phase out StackVM (#17784)
    
    This PR phases out the stackvm implementation.
    StackVM historically was used for some host codegen.
    As we move towards more comprehensive host codegen support,
    we can leverage LLVM and C for that purpose, so it can be helpful
    to phase it out to simplify maintainace.
---
 CMakeLists.txt                                     |  10 -
 python/tvm/contrib/stackvm.py                      |  45 --
 python/tvm/runtime/module.py                       |   9 -
 rust/tvm-sys/src/device.rs                         |   3 +-
 rust/tvm-sys/src/value.rs                          |   2 +-
 src/runtime/module.cc                              |   2 -
 src/runtime/stackvm/stackvm.cc                     | 615 ---------------------
 src/runtime/stackvm/stackvm.h                      | 459 ---------------
 src/runtime/stackvm/stackvm_module.cc              | 149 -----
 src/runtime/stackvm/stackvm_module.h               |  47 --
 src/support/libinfo.cc                             |   4 -
 src/target/stackvm/codegen_stackvm.cc              | 555 -------------------
 src/target/stackvm/codegen_stackvm.h               | 165 ------
 src/target/target_kind.cc                          |   3 -
 tests/python/codegen/test_target_codegen_device.py |   2 +-
 tests/python/codegen/test_target_codegen_extern.py |   1 -
 .../python/codegen/test_target_codegen_vm_basic.py | 143 -----
 .../test_tir_transform_lower_tvm_builtin.py        |   1 -
 tests/scripts/task_config_build_gpu.sh             |   1 -
 19 files changed, 3 insertions(+), 2213 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index a86bc4cc33..caad7fb02b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -370,16 +370,6 @@ if(USE_RPC)
   list(APPEND RUNTIME_SRCS ${RUNTIME_RPC_SRCS})
 endif(USE_RPC)
 
-tvm_file_glob(GLOB STACKVM_RUNTIME_SRCS src/runtime/stackvm/*.cc)
-tvm_file_glob(GLOB STACKVM_CODEGEN_SRCS src/target/stackvm/*.cc)
-list(APPEND COMPILER_SRCS ${STACKVM_CODEGEN_SRCS})
-if(USE_STACKVM_RUNTIME)
-  message(STATUS "Build with stackvm support in runtime...")
-  list(APPEND RUNTIME_SRCS ${STACKVM_RUNTIME_SRCS})
-else()
-  list(APPEND COMPILER_SRCS ${STACKVM_RUNTIME_SRCS})
-endif(USE_STACKVM_RUNTIME)
-
 if(USE_CUDA AND USE_NCCL)
   message(STATUS "Build with NCCL...")
   find_nccl(${USE_NCCL})
diff --git a/python/tvm/contrib/stackvm.py b/python/tvm/contrib/stackvm.py
deleted file mode 100644
index 458d69235d..0000000000
--- a/python/tvm/contrib/stackvm.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-"""Dummy StackVM build function."""
-# pylint: disable=invalid-name
-from __future__ import absolute_import as _abs
-import shutil
-
-
-def build(output, files):
-    """Simply copy StackVM output to the destination.
-
-    Parameters
-    ----------
-    output : str
-        The target StackVM file.
-
-    files : list
-        A single self-contained StackVM module file.
-    """
-
-    if len(files) == 0:
-        raise RuntimeError("StackVM artifact must be provided")
-    if len(files) > 1:
-        raise RuntimeError("Unexpected multiple StackVM artifacts")
-
-    shutil.copy(files[0], output)
-
-
-# assign output format
-build.output_format = "stackvm"
diff --git a/python/tvm/runtime/module.py b/python/tvm/runtime/module.py
index ca151293bb..79e8535630 100644
--- a/python/tvm/runtime/module.py
+++ b/python/tvm/runtime/module.py
@@ -517,15 +517,6 @@ class Module(object):
         if isinstance(file_name, Path):
             file_name = str(file_name)
 
-        if self.type_key == "stackvm":
-            if not file_name.endswith(".stackvm"):
-                raise ValueError(
-                    f"Module[{self.type_key}]: can only be saved as stackvm 
format."
-                    "did you build with LLVM enabled?"
-                )
-            self.save(file_name)
-            return
-
         modules = self._collect_dso_modules()
         if workspace_dir is None:
             temp = _utils.tempdir()
diff --git a/rust/tvm-sys/src/device.rs b/rust/tvm-sys/src/device.rs
index 1ebac09bf6..0344983c16 100644
--- a/rust/tvm-sys/src/device.rs
+++ b/rust/tvm-sys/src/device.rs
@@ -120,7 +120,6 @@ impl<'a> From<&'a str> for DeviceType {
         match type_str {
             "cpu" => DeviceType::CPU,
             "llvm" => DeviceType::CPU,
-            "stackvm" => DeviceType::CPU,
             "cuda" => DeviceType::CUDA,
             "nvptx" => DeviceType::CUDA,
             "cl" => DeviceType::OpenCL,
@@ -208,7 +207,7 @@ macro_rules! impl_tvm_device {
 }
 
 impl_tvm_device!(
-    DLDeviceType_kDLCPU: [cpu, llvm, stackvm],
+    DLDeviceType_kDLCPU: [cpu, llvm],
     DLDeviceType_kDLCUDA: [cuda, nvptx],
     DLDeviceType_kDLOpenCL: [cl],
     DLDeviceType_kDLMetal: [metal],
diff --git a/rust/tvm-sys/src/value.rs b/rust/tvm-sys/src/value.rs
index f69172f412..9c987af4ce 100644
--- a/rust/tvm-sys/src/value.rs
+++ b/rust/tvm-sys/src/value.rs
@@ -85,7 +85,7 @@ macro_rules! impl_tvm_device {
 }
 
 impl_tvm_device!(
-    DLDeviceType_kDLCPU: [cpu, llvm, stackvm],
+    DLDeviceType_kDLCPU: [cpu, llvm],
     DLDeviceType_kDLCUDA: [cuda, nvptx],
     DLDeviceType_kDLOpenCL: [cl],
     DLDeviceType_kDLMetal: [metal],
diff --git a/src/runtime/module.cc b/src/runtime/module.cc
index 4e60a0d0a2..a21223f142 100644
--- a/src/runtime/module.cc
+++ b/src/runtime/module.cc
@@ -151,8 +151,6 @@ bool RuntimeEnabled(const String& target_str) {
     f_name = "target.runtime.tflite";
   } else if (target == "vulkan") {
     f_name = "device_api.vulkan";
-  } else if (target == "stackvm") {
-    f_name = "target.build.stackvm";
   } else if (target == "rpc") {
     f_name = "device_api.rpc";
   } else if (target == "hexagon") {
diff --git a/src/runtime/stackvm/stackvm.cc b/src/runtime/stackvm/stackvm.cc
deleted file mode 100644
index 5a4af57b5e..0000000000
--- a/src/runtime/stackvm/stackvm.cc
+++ /dev/null
@@ -1,615 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*!
- * Implementation stack VM.
- * \file stackvm.cc
- */
-#include "stackvm.h"
-
-#include <dmlc/thread_local.h>
-#include <tvm/runtime/c_backend_api.h>
-
-#include <algorithm>
-
-namespace tvm {
-namespace runtime {
-
-typedef dmlc::ThreadLocalStore<StackVM::State> StackVMStateStore;
-
-StackVM::State* StackVM::ThreadLocalState() { return StackVMStateStore::Get(); 
}
-
-#define STACK_VM_BINOP(OP, FIELD)                                 \
-  {                                                               \
-    stack[sp - 1].FIELD = stack[sp - 1].FIELD OP stack[sp].FIELD; \
-    sp -= 1;                                                      \
-    pc += 1;                                                      \
-  }
-
-#define STACK_VM_CMPOP(OP, FIELD)                                   \
-  {                                                                 \
-    stack[sp - 1].v_int64 = stack[sp - 1].FIELD OP stack[sp].FIELD; \
-    sp -= 1;                                                        \
-    pc += 1;                                                        \
-  }
-
-#define STACK_VM_LOAD(FIELD, DST_TYPE, SRC_TYPE)                               
                 \
-  {                                                                            
                 \
-    int index = code[pc + 1].v_int;                                            
                 \
-    stack[sp] FIELD = 
static_cast<DST_TYPE>(static_cast<SRC_TYPE*>(stack[sp].v_handle)[index]); \
-    pc += 2;                                                                   
                 \
-  }
-
-#define STACK_VM_STORE(FIELD, DST_TYPE)                     \
-  {                                                         \
-    int index = code[pc + 1].v_int;                         \
-    static_cast<DST_TYPE*>(stack[sp - 1].v_handle)[index] = \
-        static_cast<DST_TYPE>(stack[sp] FIELD);             \
-    sp -= 2;                                                \
-    pc += 2;                                                \
-  }
-
-#define STACK_VM_PRINT_CODE0(CODE)                  \
-  case CODE: {                                      \
-    os << "[" << pc << "]\t" << #CODE << std::endl; \
-    return pc + 1;                                  \
-  }
-
-#define STACK_VM_PRINT_CODE1(CODE)                                         \
-  case CODE: {                                                             \
-    os << "[" << pc << "]\t" << #CODE << " " << code[pc + 1].v_int << "\n" \
-       << "[" << pc + 1 << "]" << std::endl;                               \
-    return pc + 2;                                                         \
-  }
-
-#define STACK_VM_PRINT_CODE2(CODE)                                             
                 \
-  case CODE: {                                                                 
                 \
-    os << "[" << pc << "]\t" << #CODE << " " << code[pc + 1].v_int << " " << 
code[pc + 2].v_int \
-       << "\n"                                                                 
                 \
-       << "[" << pc + 1 << "]" << std::endl                                    
                 \
-       << "[" << pc + 2 << "]" << std::endl;                                   
                 \
-    return pc + 3;                                                             
                 \
-  }
-
-#define STACK_VM_PRINT_HEAP_ACCESS(CODE)                                  \
-  case CODE: {                                                            \
-    os << "[" << pc << "]\t" << #CODE << " " << code[pc + 1].v_int << " " \
-       << heap_id_name[code[pc + 1].v_int] << "\n"                        \
-       << "[" << pc + 1 << "]" << std::endl;                              \
-    return pc + 2;                                                        \
-  }
-
-#define STACK_VM_PRINT_JUMP(CODE)                                              
  \
-  case CODE: {                                                                 
  \
-    os << "[" << pc << "]\t" << #CODE << " rel=" << code[pc + 1].v_int << " to 
" \
-       << pc + code[pc + 1].v_int << '\n'                                      
  \
-       << "[" << pc + 1 << "]" << std::endl;                                   
  \
-    return pc + 2;                                                             
  \
-  }
-
-int64_t StackVM::PrintCode(std::ostream& os, int64_t pc) const {
-  switch (code[pc].op_code) {
-    // int
-    STACK_VM_PRINT_CODE0(ADD_I64);
-    STACK_VM_PRINT_CODE0(SUB_I64);
-    STACK_VM_PRINT_CODE0(MUL_I64);
-    STACK_VM_PRINT_CODE0(MOD_I64);
-    STACK_VM_PRINT_CODE0(DIV_I64);
-    STACK_VM_PRINT_CODE0(EQ_I64);
-    STACK_VM_PRINT_CODE0(LT_I64);
-    STACK_VM_PRINT_CODE0(LE_I64);
-    // floats
-    STACK_VM_PRINT_CODE0(ADD_F64);
-    STACK_VM_PRINT_CODE0(SUB_F64);
-    STACK_VM_PRINT_CODE0(MUL_F64);
-    STACK_VM_PRINT_CODE0(DIV_F64);
-    STACK_VM_PRINT_CODE0(EQ_F64);
-    STACK_VM_PRINT_CODE0(LT_F64);
-    STACK_VM_PRINT_CODE0(LE_F64);
-    // handle.
-    STACK_VM_PRINT_CODE0(EQ_HANDLE);
-    // addressing load
-    STACK_VM_PRINT_CODE1(ARRAY_LOAD_UINT32);
-    STACK_VM_PRINT_CODE1(ARRAY_LOAD_INT32);
-    STACK_VM_PRINT_CODE1(ARRAY_LOAD_INT64);
-    STACK_VM_PRINT_CODE1(ARRAY_LOAD_FP64);
-    STACK_VM_PRINT_CODE1(ARRAY_LOAD_HANDLE);
-    STACK_VM_PRINT_CODE1(ARRAY_LOAD_TVMVALUE);
-    STACK_VM_PRINT_CODE1(ARRAY_STORE_UINT32);
-    STACK_VM_PRINT_CODE1(ARRAY_STORE_INT32);
-    STACK_VM_PRINT_CODE1(ARRAY_STORE_INT64);
-    STACK_VM_PRINT_CODE1(ARRAY_STORE_FP64);
-    STACK_VM_PRINT_CODE1(ARRAY_STORE_HANDLE);
-    STACK_VM_PRINT_CODE1(ARRAY_STORE_TVMVALUE);
-    STACK_VM_PRINT_CODE0(NOT);
-    STACK_VM_PRINT_CODE0(ADDR_ADD);
-    // stack ops
-    STACK_VM_PRINT_CODE1(PUSH_I64);
-    STACK_VM_PRINT_CODE1(PUSH_VALUE);
-    STACK_VM_PRINT_CODE0(POP);
-    STACK_VM_PRINT_CODE0(SELECT);
-    STACK_VM_PRINT_HEAP_ACCESS(STORE_HEAP);
-    STACK_VM_PRINT_HEAP_ACCESS(LOAD_HEAP);
-    STACK_VM_PRINT_CODE1(ASSERT);
-    STACK_VM_PRINT_JUMP(RJUMP_IF_TRUE);
-    STACK_VM_PRINT_JUMP(RJUMP_IF_FALSE);
-    STACK_VM_PRINT_JUMP(RJUMP);
-    STACK_VM_PRINT_CODE1(ASSERT_SP);
-    // Intrinsics
-    STACK_VM_PRINT_CODE2(TVM_STRUCT_GET);
-    STACK_VM_PRINT_CODE2(TVM_STRUCT_SET);
-    // Allocate data by 8 bytes.
-    STACK_VM_PRINT_CODE1(TVM_STACK_ALLOCA_BY_8BYTE);
-    STACK_VM_PRINT_CODE0(TVM_DEVICE_ALLOCA);
-    STACK_VM_PRINT_CODE0(TVM_DEVICE_FREE);
-    STACK_VM_PRINT_CODE0(TVM_THROW_LAST_ERROR);
-    // packed function.
-    case CALL_PACKED_LOWERED: {
-      int call_fid = code[pc + 1].v_int;
-      int begin = code[pc + 2].v_int;
-      int end = code[pc + 3].v_int;
-      os << "[" << pc << "]\tCALL_PACKED_FUNC "
-         << " fid=" << call_fid << " begin=" << begin << " end=" << end;
-      os << '\n';
-      for (int i = 0; i < 3; ++i) {
-        os << "[" << pc + 1 + i << "]" << std::endl;
-      }
-      return pc + 4;
-    }
-  }
-  LOG(FATAL) << "unknown op code " << code[pc].op_code;
-}
-
-std::ostream& operator<<(std::ostream& os, const StackVM& vm) {  // NOLINT(*)
-  int64_t pc = 0;
-  const int64_t code_size = static_cast<int64_t>(vm.code.size());
-  os << "Program dump: code-size=" << code_size << '\n' << 
"----------begin-----------------\n";
-  while (pc < code_size) {
-    pc = vm.PrintCode(os, pc);
-  }
-  os << "----------end--------------------\n";
-  return os;
-}
-
-void StackVM::Run(const runtime::TVMArgs& args, runtime::ModuleNode* mod_ctx) 
const {
-  StackVM::State* s = StackVM::ThreadLocalState();
-  if (s->heap.size() < heap_size) {
-    s->heap.resize(heap_size);
-  }
-  s->sp = 0;
-  s->pc = 0;
-  s->mod_ctx = mod_ctx;
-  s->heap[0].v_handle = (void*)args.values;      // NOLINT(*)
-  s->heap[1].v_handle = (void*)args.type_codes;  // NOLINT(*)
-  s->heap[2].v_int64 = args.num_args;
-  this->Run(s);
-}
-
-void StackVM::InitCache() {
-  extern_func_cache_.clear();
-  extern_func_cache_.resize(extern_func_name.size(), PackedFunc(nullptr));
-}
-
-void StackVM::Save(dmlc::Stream* strm) const {
-  // to be endian invariant.
-  std::vector<int32_t> code_copy(code.size());
-  std::transform(code.begin(), code.end(), code_copy.begin(), [](Code c) { 
return c.v_int; });
-  strm->Write(code_copy);
-  strm->Write(str_data);
-  strm->Write(extern_func_name);
-  strm->Write(heap_id_name);
-  strm->Write(heap_size);
-  strm->Write(stack_size);
-}
-
-bool StackVM::Load(dmlc::Stream* strm) {
-  // to be endian invariant.
-  std::vector<int32_t> code_copy;
-  if (!strm->Read(&code_copy)) return false;
-  code.resize(code_copy.size());
-  std::transform(code_copy.begin(), code_copy.end(), code.begin(), [](int v) {
-    Code code;
-    code.v_int = v;
-    return code;
-  });
-  if (!strm->Read(&str_data)) return false;
-  if (!strm->Read(&extern_func_name)) return false;
-  if (!strm->Read(&heap_id_name)) return false;
-  if (!strm->Read(&heap_size)) return false;
-  if (!strm->Read(&stack_size)) return false;
-  this->InitCache();
-  return true;
-}
-
-void StackVM::Run(State* s) const {
-  int64_t sp = s->sp;
-  int64_t pc = s->pc;
-  int64_t alloca_sp = s->sp;
-  std::vector<TVMValue>& stack = s->stack;
-  std::vector<TVMValue>& heap = s->heap;
-  if (stack.size() < stack_size) {
-    stack.resize(stack_size);
-  }
-  int64_t stack_cap = static_cast<int64_t>(stack_size - 4);
-  if (heap.size() < heap_size) {
-    heap.resize(heap_size);
-  }
-  const int64_t code_size = static_cast<int64_t>(code.size());
-  while (pc < code_size) {
-    switch (code[pc].op_code) {
-      case ADD_I64:
-        STACK_VM_BINOP(+, v_int64);
-        break;
-      case SUB_I64:
-        STACK_VM_BINOP(-, v_int64);
-        break;
-      case MUL_I64:
-        STACK_VM_BINOP(*, v_int64);
-        break;
-      case DIV_I64:
-        STACK_VM_BINOP(/, v_int64);
-        break;
-      case MOD_I64:
-        STACK_VM_BINOP(%, v_int64);
-        break;
-      case EQ_I64:
-        STACK_VM_CMPOP(==, v_int64);
-        break;
-      case LT_I64:
-        STACK_VM_CMPOP(<, v_int64);
-        break;
-      case LE_I64:
-        STACK_VM_CMPOP(<=, v_int64);
-        break;
-      case ADD_F64:
-        STACK_VM_BINOP(+, v_float64);
-        break;
-      case SUB_F64:
-        STACK_VM_BINOP(-, v_float64);
-        break;
-      case MUL_F64:
-        STACK_VM_BINOP(*, v_float64);
-        break;
-      case DIV_F64:
-        STACK_VM_BINOP(/, v_float64);
-        break;
-      case EQ_F64:
-        STACK_VM_CMPOP(==, v_float64);
-        break;
-      case LT_F64:
-        STACK_VM_CMPOP(<, v_float64);
-        break;
-      case LE_F64:
-        STACK_VM_CMPOP(<=, v_float64);
-        break;
-      case EQ_HANDLE:
-        STACK_VM_CMPOP(==, v_handle);
-        break;
-      // addressing
-      case ARRAY_LOAD_UINT32:
-        STACK_VM_LOAD(.v_int64, int64_t, uint32_t);
-        break;
-      case ARRAY_LOAD_INT32:
-        STACK_VM_LOAD(.v_int64, int64_t, int32_t);
-        break;
-      case ARRAY_LOAD_INT64:
-        STACK_VM_LOAD(.v_int64, int64_t, int64_t);
-        break;
-      case ARRAY_LOAD_FP64:
-        STACK_VM_LOAD(.v_float64, double, double);
-        break;
-      case ARRAY_LOAD_HANDLE:
-        STACK_VM_LOAD(.v_handle, void*, void*);
-        break;
-      case ARRAY_LOAD_TVMVALUE:
-        STACK_VM_LOAD(, TVMValue, TVMValue);
-        break;
-      // store
-      case ARRAY_STORE_UINT32:
-        STACK_VM_STORE(.v_int64, uint32_t);
-        break;
-      case ARRAY_STORE_INT32:
-        STACK_VM_STORE(.v_int64, int32_t);
-        break;
-      case ARRAY_STORE_INT64:
-        STACK_VM_STORE(.v_int64, int64_t);
-        break;
-      case ARRAY_STORE_FP64:
-        STACK_VM_STORE(.v_float64, double);
-        break;
-      case ARRAY_STORE_HANDLE:
-        STACK_VM_STORE(.v_handle, void*);
-        break;
-      case ARRAY_STORE_TVMVALUE:
-        STACK_VM_STORE(, TVMValue);
-        break;
-      // add
-      case ADDR_ADD: {
-        stack[sp - 1].v_handle = (char*)(stack[sp - 1].v_handle) + 
stack[sp].v_int64;  // NOLINT(*)
-        sp = sp - 1;
-        pc = pc + 1;
-        break;
-      }
-      case NOT: {
-        stack[sp].v_int64 = !stack[sp].v_int64;
-        pc += 1;
-        break;
-      }
-      case PUSH_I64: {
-        stack[sp + 1].v_int64 = code[pc + 1].v_int;
-        sp += 1;
-        pc += 2;
-        break;
-      }
-      case PUSH_VALUE: {
-        int relpos = code[pc + 1].v_int;
-        ICHECK_LE(relpos, 0);
-        stack[sp + 1] = stack[sp + relpos];
-        sp += 1;
-        pc += 2;
-        break;
-      }
-      case POP: {
-        sp -= 1;
-        pc += 1;
-        break;
-      }
-      case SELECT: {
-        stack[sp - 2] = (stack[sp].v_int64 ? stack[sp - 2] : stack[sp - 1]);
-        sp -= 2;
-        pc += 1;
-        break;
-      }
-      case LOAD_HEAP: {
-        stack[sp + 1] = heap[code[pc + 1].v_int];
-        sp += 1;
-        pc += 2;
-        break;
-      }
-      case STORE_HEAP: {
-        heap[code[pc + 1].v_int] = stack[sp];
-        sp -= 1;
-        pc += 2;
-        break;
-      }
-      case ASSERT: {
-        ICHECK(stack[sp].v_int64) << str_data[code[pc + 1].v_int];
-        sp -= 1;
-        pc += 2;
-        break;
-      }
-      case RJUMP_IF_TRUE: {
-        if (stack[sp].v_int64) {
-          pc += code[pc + 1].v_int;
-        } else {
-          pc += 2;
-        }
-        break;
-      }
-      case RJUMP_IF_FALSE: {
-        if (!stack[sp].v_int64) {
-          pc += code[pc + 1].v_int;
-        } else {
-          pc += 2;
-        }
-        break;
-      }
-      case RJUMP: {
-        pc += code[pc + 1].v_int;
-        break;
-      }
-      case ASSERT_SP: {
-        int64_t expected = code[pc + 1].v_int;
-        ICHECK_EQ(sp, expected) << "sp assertion failed, expected=" << 
expected << " now=" << sp
-                                << ", pc=" << pc;
-        pc += 2;
-        break;
-      }
-      case CALL_PACKED_LOWERED: {
-        // call packed function.
-        TVMValue* value_stack = static_cast<TVMValue*>(stack[sp - 1].v_handle);
-        int* type_stack = static_cast<int*>(stack[sp].v_handle);
-        int call_fid = code[pc + 1].v_int;
-        int begin = code[pc + 2].v_int;
-        int end = code[pc + 3].v_int;
-        int num_args = end - begin;
-        static_assert(sizeof(Code) == sizeof(int) && alignof(Code) == 
alignof(int), "asusmption");
-        runtime::TVMRetValue rv;
-        GetExtern(s, call_fid)
-            .CallPacked(runtime::TVMArgs(value_stack + begin, type_stack + 
begin, num_args), &rv);
-        sp = sp - 1;
-        stack[sp] = rv.value();
-        pc += 4;
-        break;
-      }
-      // intrinsics
-      case TVM_STRUCT_GET: {
-        int index = code[pc + 1].v_int;
-        int kind = code[pc + 2].v_int;
-        DLTensor* arr = static_cast<DLTensor*>(stack[sp].v_handle);
-        switch (kind) {
-          case StackVM::kArrData: {
-            stack[sp].v_handle = arr[index].data;
-            break;
-          }
-          case StackVM::kArrShape: {
-            stack[sp].v_handle = arr[index].shape;
-            break;
-          }
-          case StackVM::kArrStrides: {
-            stack[sp].v_handle = arr[index].strides;
-            break;
-          }
-          case StackVM::kArrNDim: {
-            stack[sp].v_int64 = arr[index].ndim;
-            break;
-          }
-          case StackVM::kArrTypeCode: {
-            stack[sp].v_int64 = static_cast<int64_t>(arr[index].dtype.code);
-            break;
-          }
-          case StackVM::kArrTypeBits: {
-            stack[sp].v_int64 = static_cast<int64_t>(arr[index].dtype.bits);
-            break;
-          }
-          case StackVM::kArrTypeLanes: {
-            stack[sp].v_int64 = static_cast<int64_t>(arr[index].dtype.lanes);
-            break;
-          }
-          case StackVM::kArrByteOffset: {
-            stack[sp].v_int64 = static_cast<int64_t>(arr[index].byte_offset);
-            break;
-          }
-          case StackVM::kArrDeviceId: {
-            stack[sp].v_int64 = arr[index].device.device_id;
-            break;
-          }
-          case StackVM::kArrDeviceType: {
-            stack[sp].v_int64 = 
static_cast<int64_t>(arr[index].device.device_type);
-            break;
-          }
-          case StackVM::kArrAddr: {
-            stack[sp].v_handle = arr + index;
-            break;
-          }
-          case StackVM::kTVMValueContent: {
-            stack[sp] = static_cast<TVMValue*>(stack[sp].v_handle)[index];
-            break;
-          }
-          default:
-            LOG(FATAL) << "unhandled get " << kind;
-        }
-        pc = pc + 3;
-        break;
-      }
-      case TVM_STRUCT_SET: {
-        int index = code[pc + 1].v_int;
-        int kind = code[pc + 2].v_int;
-        DLTensor* arr = static_cast<DLTensor*>(stack[sp - 1].v_handle);
-        switch (kind) {
-          case StackVM::kArrData: {
-            arr[index].data = stack[sp].v_handle;
-            break;
-          }
-          case StackVM::kArrShape: {
-            arr[index].shape = static_cast<int64_t*>(stack[sp].v_handle);
-            break;
-          }
-          case StackVM::kArrStrides: {
-            arr[index].strides = static_cast<int64_t*>(stack[sp].v_handle);
-            break;
-          }
-          case StackVM::kArrNDim: {
-            arr[index].ndim = static_cast<int>(stack[sp].v_int64);
-            break;
-          }
-          case StackVM::kArrTypeCode: {
-            arr[index].dtype.code = static_cast<uint8_t>(stack[sp].v_int64);
-            break;
-          }
-          case StackVM::kArrTypeBits: {
-            arr[index].dtype.bits = static_cast<uint8_t>(stack[sp].v_int64);
-            break;
-          }
-          case StackVM::kArrTypeLanes: {
-            arr[index].dtype.lanes = static_cast<uint16_t>(stack[sp].v_int64);
-            break;
-          }
-          case StackVM::kArrByteOffset: {
-            arr[index].byte_offset = static_cast<uint64_t>(stack[sp].v_int64);
-            break;
-          }
-          case StackVM::kArrDeviceId: {
-            arr[index].device.device_id = static_cast<int>(stack[sp].v_int64);
-            break;
-          }
-          case StackVM::kArrDeviceType: {
-            arr[index].device.device_type = 
static_cast<DLDeviceType>(stack[sp].v_int64);
-            break;
-          }
-          case StackVM::kTVMValueContent: {
-            static_cast<TVMValue*>(stack[sp - 1].v_handle)[index] = stack[sp];
-            break;
-          }
-          default:
-            LOG(FATAL) << "unhandled tvm_struct_set " << kind;
-        }
-        sp -= 2;
-        pc += 3;
-        break;
-      }
-      // alloca
-      case TVM_STACK_ALLOCA_BY_8BYTE: {
-        static_assert(sizeof(TVMValue) == 8, "invariance");
-        int num = code[pc + 1].v_int;
-        void* addr = &stack[sp] + 1;
-        sp = sp + num + 1;
-        alloca_sp = sp - 1;
-        stack[sp].v_handle = addr;
-        pc = pc + 2;
-        break;
-      }
-      case TVM_DEVICE_ALLOCA: {
-        int device_type = static_cast<int>(stack[sp - 4].v_int64);
-        int device_id = static_cast<int>(stack[sp - 3].v_int64);
-        size_t nbytes = static_cast<size_t>(stack[sp - 2].v_int64);
-        int dtype_code_hint = static_cast<int>(stack[sp - 1].v_int64);
-        int dtype_bits_hint = static_cast<int>(stack[sp].v_int64);
-        void* ptr = TVMBackendAllocWorkspace(device_type, device_id, nbytes, 
dtype_code_hint,
-                                             dtype_bits_hint);
-        stack[sp - 4].v_handle = ptr;
-        sp = sp - 4;
-        pc = pc + 1;
-        break;
-      }
-      case TVM_DEVICE_FREE: {
-        int device_type = static_cast<int>(stack[sp - 2].v_int64);
-        int device_id = static_cast<int>(stack[sp - 1].v_int64);
-        void* ptr = stack[sp].v_handle;
-        int ret = TVMBackendFreeWorkspace(device_type, device_id, ptr);
-        stack[sp - 2].v_int64 = ret;
-        sp = sp - 2;
-        pc = pc + 1;
-        break;
-      }
-      case TVM_THROW_LAST_ERROR: {
-        LOG(FATAL) << TVMGetLastError();
-        break;
-      }
-    }
-    ICHECK_GE(sp, alloca_sp) << "touch allocated space";
-    ICHECK_LT(sp, stack_cap) << "Stack overflow";
-  }
-}
-
-const PackedFunc& StackVM::GetExtern(State* s, int fid) const {
-  ICHECK_LT(static_cast<size_t>(fid), extern_func_cache_.size());
-  // allow race write in this, since write is idempotent
-  PackedFunc& f = extern_func_cache_[fid];
-  if (f == nullptr) {
-    ICHECK(s->mod_ctx != nullptr) << "No local context is set in stackvm";
-    const PackedFunc* pf = s->mod_ctx->GetFuncFromEnv(extern_func_name[fid]);
-    ICHECK(pf != nullptr);
-    f = *pf;
-  }
-  return f;
-}
-
-}  // namespace runtime
-}  // namespace tvm
diff --git a/src/runtime/stackvm/stackvm.h b/src/runtime/stackvm/stackvm.h
deleted file mode 100644
index c967e99dbe..0000000000
--- a/src/runtime/stackvm/stackvm.h
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*!
- * \file stackvm.h
- * \brief A simple stack-based virtual machine.
- *
- *  This can be used to interepret host side code
- *  to setup calls into device functions
- *  when only Runtime compilation for device is available(via NVRTC or OpenCL).
- */
-#ifndef TVM_RUNTIME_STACKVM_STACKVM_H_
-#define TVM_RUNTIME_STACKVM_STACKVM_H_
-
-#include <tvm/runtime/c_runtime_api.h>
-#include <tvm/runtime/module.h>
-#include <tvm/runtime/packed_func.h>
-
-#include <string>
-#include <vector>
-
-namespace tvm {
-namespace runtime {
-
-using runtime::operator<<;
-
-/*!
- * \brief A simple stack-based virtual machine program.
- */
-class StackVM {
- public:
-  /*!
-   * \brief Invoke the StackVM program.
-   * \param args The arguments to the StackVM.
-   * \param mod_ctx The module context used in running.
-   */
-  void Run(const TVMArgs& args, runtime::ModuleNode* mod_ctx) const;
-  /*!
-   * \brief The opcode of stack vm
-   * \note Notation
-   *  - sp Stack pointer
-   *  - pc Program pointer
-   */
-  enum OpCode {
-    // integer ops
-    ADD_I64,
-    SUB_I64,
-    MUL_I64,
-    DIV_I64,
-    MOD_I64,
-    EQ_I64,
-    LT_I64,
-    LE_I64,
-    // floating ops
-    ADD_F64,
-    SUB_F64,
-    MUL_F64,
-    DIV_F64,
-    EQ_F64,
-    LT_F64,
-    LE_F64,
-    // Pointer comparison
-    EQ_HANDLE,
-    /*!
-     * \brief Routine to load data from address with const offset.
-     * \code
-     *  stack[sp].v_int64 = ((DType*)stack[sp].v_handle)[code[pc + 1].v_int];
-     *  pc = pc + 2;
-     * \endcode
-     */
-    ARRAY_LOAD_UINT32,
-    ARRAY_LOAD_INT32,
-    ARRAY_LOAD_INT64,
-    ARRAY_LOAD_FP64,
-    ARRAY_LOAD_HANDLE,
-    ARRAY_LOAD_TVMVALUE,
-    /*!
-     * \brief Routine to store data from constant offset.
-     * \code
-     *  ((DType*)stack[sp - 1].v_handle)[code[pc + 1].v_int] = stack[sp];
-     *  pc = pc + 2;
-     *  sp = sp - 2;
-     * \endcode
-     */
-    ARRAY_STORE_UINT32,
-    ARRAY_STORE_INT32,
-    ARRAY_STORE_INT64,
-    ARRAY_STORE_FP64,
-    ARRAY_STORE_HANDLE,
-    ARRAY_STORE_TVMVALUE,
-    // logical ops
-    NOT,
-    /*!
-     * \brief Add address by an offset.
-     * \code
-     *  stack[sp - 1].v_handle = ((char*)stack[sp - 1].v_handle + 
stack[sp].v_int64);
-     *  sp = sp - 1;
-     * \endcode
-     */
-    ADDR_ADD,
-    /*!
-     * \brief push integer fetched from next pc position into stack
-     * \code
-     *  stack[sp + 1].v_int64 = code[pc + 1].v_int;
-     *  pc = pc + 2;
-     *  sp = sp + 1;
-     * \endcode
-     */
-    PUSH_I64,
-    /*!
-     * \brief push a value given relative index on the stack
-     * \code
-     *  stack[sp + 1] = stack[sp + code[pc + 1].v_int];
-     *  pc = pc + 2;
-     *  sp = sp + 1;
-     * \endcode
-     */
-    PUSH_VALUE,
-    /*!
-     * \brief Load data from heap to top of stack
-     * \code
-     *  stack[sp + 1] = heap[code[pc + 1].v_int];
-     *  pc = pc + 2;
-     *  sp = sp + 1;
-     * \endcode
-     */
-    LOAD_HEAP,
-    /*!
-     * \brief Store data to heap
-     * \code
-     *  heap[code[pc + 1].v_int] = stack[sp];
-     *  sp = sp - 1;
-     * \endcode
-     */
-    STORE_HEAP,
-    /*! \brief pop value from top of the stack */
-    POP,
-    /*!
-     * \brief select based on operands.
-     * \code
-     *  stack[sp - 2] = stack[sp].v_int64 ? stack[sp - 2] : stack[sp - 1]
-     *  sp = sp - 2;
-     * \endcode
-     */
-    SELECT,
-    /*!
-     * \brief Assert condition is true.
-     * \code
-     *  ICHECK(stack[sp]) << str_data[code[pc + 1].v_int];
-     *  sp = sp - 1;
-     * \endcode
-     */
-    ASSERT,
-    /*!
-     * \brief Relative Jump if the condition is true,
-     *  Does not change the stack status.
-     * \code
-     *  if (stack[sp]) {
-     *    pc += code[pc + 1].v_int
-     *  } else {
-     *    pc = pc + 2;
-     *  }
-     * \endcode
-     */
-    RJUMP_IF_TRUE,
-    /*!
-     * \brief Relative Jump if the condition is true,
-     *  Does not change the stack status.
-     * \code
-     *  if (stack[sp]) {
-     *    pc += code[pc + 1].v_int
-     *  } else {
-     *    pc = pc + 2;
-     *  }
-     * \endcode
-     */
-    RJUMP_IF_FALSE,
-    /*!
-     * \brief Relative jump to a location.
-     * \code
-     *  pc += code[pc + 1].v_int;
-     * \endcode
-     */
-    RJUMP,
-    /*!
-     * \brief debug instruction.
-     * \code
-     *  ICHECK_EQ(sp, code[pc + 1]).v_int;
-     *  pc += 2;
-     * \code
-     */
-    ASSERT_SP,
-    /*!
-     * \brief call an extern packed function
-     * \code
-     *  value_stack = stack[sp - 1].v_handle;
-     *  type_stack = stack[sp - 0].v_handle;
-     *  call_fid = code[pc + 1].v_int;
-     *  begin = code[pc + 2].v_int;
-     *  end = code[pc + 3].v_int;
-     *  num_args = end - begin - 1;
-     *  f = extern_func[call_fid];
-     *  stack[sp - 1] = f(&value_stack[begin:end-1], type_stack[begin:end-1], 
num_args);
-     *  sp = sp - 1;
-     *  // The type codes are hidden in the code space.
-     *  pc = pc + 4
-     * \endcode
-     */
-    CALL_PACKED_LOWERED,
-    // Allocate things on stack
-    /*!
-     * \brief allocate data from stack.
-     * \code
-     *  num = code[pc + 1].v_int;
-     *  void* addr = &stack[sp];
-     *  sp = sp + num;
-     *  stack[sp].v_handle = addr;
-     *  pc = pc + 1;
-     * \endcode
-     */
-    TVM_STACK_ALLOCA_BY_8BYTE,
-    /*!
-     * \brief allocate data from device.
-     * \code
-     *  device_type = stack[sp - 2].v_int64;
-     *  device_id = stack[sp - 1].v_int64;
-     *  nbytes = stack[sp].v_int64;
-     *  stack[sp - 2].v_handle = device_alloca(device_type, device_id, nbytes);
-     *  sp = sp - 2;
-     *  pc = pc + 1;
-     * \endcode
-     */
-    TVM_DEVICE_ALLOCA,
-    /*!
-     * \brief free data into device.
-     * \code
-     *  device_type = stack[sp - 2].v_int64;
-     *  device_id = stack[sp - 1].v_int64;
-     *  ptr = stack[sp].v_handle;
-     *  stack[sp - 2].v_int64 = device_free(device_type, device_id, ptr);
-     *  sp = sp - 2;
-     *  pc = pc + 1;
-     * \endcode
-     */
-    TVM_DEVICE_FREE,
-    /*!
-     * \brief throw last error
-     */
-    TVM_THROW_LAST_ERROR,
-    /*!
-     * \brief get data from structure.
-     * \code
-     *  index = code[pc + 1].v_int;
-     *  field = code[pc + 2].v_int;
-     *  stack[sp] = ((StructType*)stack[sp].v_handle)[index]->field;
-     *  pc = pc + 3
-     * \endcode
-     */
-    TVM_STRUCT_GET,
-    /*!
-     * \brief set data into structure.
-     * \code
-     *  index = code[pc + 1].v_int;
-     *  field = code[pc + 2].v_int;
-     *  ((StructType*)stack[sp - 1].v_handle)[index]->field = stack[sp];
-     *  pc = pc + 3
-     *  sp = sp - 1
-     * \endcode
-     */
-    TVM_STRUCT_SET
-  };
-  /*! \brief The kind of structure field info */
-  enum StructFieldKind : int {
-    // array head address
-    kArrAddr,
-    kArrData,
-    kArrShape,
-    kArrStrides,
-    kArrNDim,
-    kArrTypeCode,
-    kArrTypeBits,
-    kArrTypeLanes,
-    kArrByteOffset,
-    kArrDeviceId,
-    kArrDeviceType,
-    kArrKindBound_,
-    // TVMValue field
-    kTVMValueContent,
-    kTVMValueKindBound_
-  };
-  /*! \brief The code structure */
-  union Code {
-    OpCode op_code;
-    int v_int;
-  };
-  /*! \brief The state object of StackVM */
-  struct State {
-    /*! \brief The execution stack */
-    std::vector<TVMValue> stack;
-    /*! \brief The global heap space */
-    std::vector<TVMValue> heap;
-    /*! \brief stack pointer  */
-    int64_t sp{0};
-    /*! \brief program counter */
-    int64_t pc{0};
-    /*! \brief The current module context of stackvm */
-    runtime::ModuleNode* mod_ctx{nullptr};
-  };
-  /*! \brief Initialize local cache*/
-  void InitCache();
-  /*!
-   * \brief Save stackvm program to an output stream
-   * \param strm The output stream
-   */
-  void Save(dmlc::Stream* strm) const;
-  /*!
-   * \brief Load stackvm program from output stream
-   * \param strm The output stream
-   */
-  bool Load(dmlc::Stream* strm);
-  /*!
-   * \brief Print instruction at location pc
-   * \param os The ostream
-   * \param pc The pc
-   * \return the pc to next instruction.
-   */
-  int64_t PrintCode(std::ostream& os, int64_t pc) const;  // NOLINT(*)
-  /*! \brief Get thread local state of the stack VM */
-  static State* ThreadLocalState();
-  // The code below are programs
-  /*! \brief The instructions */
-  std::vector<Code> code;
-  /*! \brief constant error messages */
-  std::vector<std::string> str_data;
-  /*! \brief Extern functions */
-  std::vector<std::string> extern_func_name;
-  /*! \brief name of each heap id */
-  std::vector<std::string> heap_id_name;
-  /*! \brief The memory size needed */
-  size_t heap_size{0};
-  /*! \brief The stack size required */
-  size_t stack_size{1024};
-  /*!
-   * \brief Convert I64 opcode to F64 Ones
-   * \param code The op code.
-   * \return the F64 op code.
-   */
-  static OpCode CodeI64ToF64(OpCode code) {
-    switch (code) {
-      case ADD_I64:
-        return ADD_F64;
-      case SUB_I64:
-        return SUB_F64;
-      case MUL_I64:
-        return MUL_F64;
-      case DIV_I64:
-        return DIV_F64;
-      case EQ_I64:
-        return EQ_F64;
-      case LT_I64:
-        return LT_F64;
-      case LE_I64:
-        return LE_F64;
-      case MOD_I64:
-        LOG(FATAL) << "cannot handle mod for float";
-      default:
-        LOG(FATAL) << "cannot handle op " << code;
-    }
-  }
-  /*!
-   * \brief Get load opcode for type t
-   * \param t the type code.
-   * \return The load opcode
-   */
-  static OpCode GetLoad(DLDataType t) {
-    ICHECK_EQ(t.lanes, 1U);
-    if (t.code == kTVMOpaqueHandle) return ARRAY_LOAD_HANDLE;
-    if (t.code == kDLInt) {
-      switch (t.bits) {
-        case 32:
-          return ARRAY_LOAD_INT32;
-        case 64:
-          return ARRAY_LOAD_INT64;
-      }
-    } else if (t.code == kDLUInt) {
-      switch (t.bits) {
-        case 32:
-          return ARRAY_LOAD_UINT32;
-      }
-    } else if (t.code == kDLFloat) {
-      switch (t.bits) {
-        case 64:
-          return ARRAY_LOAD_FP64;
-      }
-    }
-    LOG(FATAL) << "Cannot load type " << t;
-  }
-  /*!
-   * \brief Get store opcode for type t
-   * \param t the type code.
-   * \return The load opcode
-   */
-  static OpCode GetStore(DLDataType t) {
-    ICHECK_EQ(t.lanes, 1U);
-    if (t.code == kTVMOpaqueHandle) return ARRAY_STORE_HANDLE;
-    if (t.code == kDLInt) {
-      switch (t.bits) {
-        case 32:
-          return ARRAY_STORE_INT32;
-        case 64:
-          return ARRAY_STORE_INT64;
-      }
-    } else if (t.code == kDLUInt) {
-      switch (t.bits) {
-        case 32:
-          return ARRAY_STORE_UINT32;
-      }
-    } else if (t.code == kDLFloat) {
-      switch (t.bits) {
-        case 64:
-          return ARRAY_STORE_FP64;
-      }
-    }
-    LOG(FATAL) << "Cannot store type " << t;
-  }
-  friend std::ostream& operator<<(std::ostream& os, const StackVM& vm);  // 
NOLINT(*)
-
- private:
-  //  execute the stack vm with given state
-  void Run(State* state) const;
-  // get extern function.
-  const PackedFunc& GetExtern(State* s, int fid) const;
-  // cached extern function
-  mutable std::vector<PackedFunc> extern_func_cache_;
-};
-
-}  // namespace runtime
-}  // namespace tvm
-
-namespace dmlc {
-DMLC_DECLARE_TRAITS(has_saveload, ::tvm::runtime::StackVM, true);
-}
-#endif  // TVM_RUNTIME_STACKVM_STACKVM_H_
diff --git a/src/runtime/stackvm/stackvm_module.cc 
b/src/runtime/stackvm/stackvm_module.cc
deleted file mode 100644
index 867ccc8ed0..0000000000
--- a/src/runtime/stackvm/stackvm_module.cc
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*!
- * \file stackvm_module.cc
- */
-#include "stackvm_module.h"
-
-#include <dmlc/memory_io.h>
-#include <tvm/runtime/module.h>
-#include <tvm/runtime/registry.h>
-
-#include <memory>
-#include <unordered_map>
-#include <utility>
-
-#include "../file_utils.h"
-
-namespace tvm {
-namespace runtime {
-
-class StackVMModuleNode : public runtime::ModuleNode {
- public:
-  const char* type_key() const final { return "stackvm"; }
-
-  PackedFunc GetFunction(const String& name, const ObjectPtr<Object>& 
sptr_to_self) final {
-    if (name == runtime::symbol::tvm_module_main) {
-      return GetFunction(entry_func_, sptr_to_self);
-    }
-    auto it = fmap_.find(name);
-    if (it == fmap_.end()) return PackedFunc();
-    const StackVM& vm = it->second;
-    // capture sptr_to_self to keep module node alive.
-    return PackedFunc(
-        [vm, sptr_to_self, this](TVMArgs args, TVMRetValue* rv) { vm.Run(args, 
this); });
-  }
-
-  String GetSource(const String& format) final {
-    std::ostringstream os;
-    for (const auto& kv : fmap_) {
-      os << "Function: " << kv.first << '\n';
-      os << kv.second;
-    }
-    return os.str();
-  }
-
-  void SaveToFile(const String& file_name, const String& format) final {
-    std::string data, mblob;
-    dmlc::MemoryStringStream writer(&data);
-    dmlc::Stream* strm = &writer;
-    strm->Write(fmap_);
-    strm->Write(entry_func_);
-    // also save imports
-    uint64_t num_imports = static_cast<uint64_t>(imports_.size());
-    strm->Write(num_imports);
-
-    for (runtime::Module im : imports_) {
-      ICHECK_EQ(im->imports().size(), 0U) << "Only support simply one-level 
hierarchy";
-      std::string tkey = im->type_key();
-      strm->Write(tkey);
-      im->SaveToBinary(strm);
-    }
-    SaveBinaryToFile(file_name, data);
-  }
-
-  static Module Create(std::unordered_map<std::string, StackVM> fmap, 
std::string entry_func) {
-    auto n = make_object<StackVMModuleNode>();
-    n->fmap_ = std::move(fmap);
-    n->entry_func_ = std::move(entry_func);
-    return Module(n);
-  }
-
-  static Module Load(dmlc::Stream* strm) {
-    std::unordered_map<std::string, StackVM> fmap;
-    std::string entry_func, data;
-    strm->Read(&fmap);
-    strm->Read(&entry_func);
-    auto n = make_object<StackVMModuleNode>();
-    n->fmap_ = std::move(fmap);
-    n->entry_func_ = std::move(entry_func);
-    uint64_t num_imports;
-    strm->Read(&num_imports);
-    for (uint64_t i = 0; i < num_imports; ++i) {
-      std::string tkey;
-      ICHECK(strm->Read(&tkey));
-      std::string loadkey = "runtime.module.loadbinary_";
-      std::string fkey = loadkey + tkey;
-      const PackedFunc* f = Registry::Get(fkey);
-      if (f == nullptr) {
-        std::string loaders = "";
-        for (auto reg_name : Registry::ListNames()) {
-          std::string name = reg_name;
-          if (name.rfind(loadkey, 0) == 0) {
-            if (loaders.size() > 0) {
-              loaders += ", ";
-            }
-            loaders += name.substr(loadkey.size());
-          }
-        }
-        ICHECK(f != nullptr)
-            << "Binary was created using " << tkey
-            << " but a loader of that name is not registered. Available 
loaders are " << loaders
-            << ". Perhaps you need to recompile with this runtime enabled.";
-      }
-      Module m = (*f)(static_cast<void*>(strm));
-      n->imports_.emplace_back(std::move(m));
-    }
-    return Module(n);
-  }
-
-  static Module LoadFromFile(std::string file_name, std::string format) {
-    std::string data;
-    LoadBinaryFromFile(file_name, &data);
-    dmlc::MemoryStringStream reader(&data);
-    return Load(&reader);
-  }
-
- private:
-  // internal function map
-  std::unordered_map<std::string, StackVM> fmap_;
-  // entry function.
-  std::string entry_func_;
-};
-
-Module StackVMModuleCreate(std::unordered_map<std::string, StackVM> fmap, 
std::string entry_func) {
-  return StackVMModuleNode::Create(fmap, entry_func);
-}
-
-TVM_REGISTER_GLOBAL("runtime.module.loadfile_stackvm")
-    .set_body_typed(StackVMModuleNode::LoadFromFile);
-
-}  // namespace runtime
-}  // namespace tvm
diff --git a/src/runtime/stackvm/stackvm_module.h 
b/src/runtime/stackvm/stackvm_module.h
deleted file mode 100644
index 6ae4ae47a9..0000000000
--- a/src/runtime/stackvm/stackvm_module.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*!
- * \file stackvm_module.h
- * \brief StackVM module
- */
-#ifndef TVM_RUNTIME_STACKVM_STACKVM_MODULE_H_
-#define TVM_RUNTIME_STACKVM_STACKVM_MODULE_H_
-
-#include <tvm/runtime/packed_func.h>
-
-#include <string>
-#include <unordered_map>
-
-#include "stackvm.h"
-
-namespace tvm {
-namespace runtime {
-/*!
- * \brief create a stackvm module
- *
- * \param fmap The map from name to function
- * \param entry_func The entry function name.
- * \return The created module
- */
-Module StackVMModuleCreate(std::unordered_map<std::string, StackVM> fmap, 
std::string entry_func);
-
-}  // namespace runtime
-}  // namespace tvm
-#endif  // TVM_RUNTIME_STACKVM_STACKVM_MODULE_H_
diff --git a/src/support/libinfo.cc b/src/support/libinfo.cc
index b981fcd6d7..40213e37b6 100644
--- a/src/support/libinfo.cc
+++ b/src/support/libinfo.cc
@@ -115,10 +115,6 @@
 #define TVM_INFO_USE_LLVM "NOT-FOUND"
 #endif
 
-#ifndef TVM_INFO_USE_STACKVM_RUNTIME
-#define TVM_INFO_USE_STACKVM_RUNTIME "NOT-FOUND"
-#endif
-
 #ifndef TVM_INFO_USE_OPENMP
 #define TVM_INFO_USE_OPENMP "NOT-FOUND"
 #endif
diff --git a/src/target/stackvm/codegen_stackvm.cc 
b/src/target/stackvm/codegen_stackvm.cc
deleted file mode 100644
index 36638576d3..0000000000
--- a/src/target/stackvm/codegen_stackvm.cc
+++ /dev/null
@@ -1,555 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*!
- * \file codegen_stackvm.cc
- */
-#include "codegen_stackvm.h"
-
-#include <tvm/ir/module.h>
-#include <tvm/runtime/registry.h>
-#include <tvm/tir/builtin.h>
-#include <tvm/tir/function.h>
-#include <tvm/tir/op.h>
-
-#include <limits>
-#include <utility>
-
-#include "../../runtime/stackvm/stackvm_module.h"
-
-namespace tvm {
-namespace codegen {
-
-using namespace tir;
-
-// map struct field kind to runtime variants
-// We keep two separate enums to ensure runtime/compiler isolation.
-StackVM::StructFieldKind MapFieldKind(int64_t kind) {
-  auto val = static_cast<builtin::TVMStructFieldKind>(kind);
-  switch (val) {
-    case builtin::kArrData:
-      return StackVM::kArrData;
-    case builtin::kArrShape:
-      return StackVM::kArrShape;
-    case builtin::kArrAddr:
-      return StackVM::kArrAddr;
-    case builtin::kArrStrides:
-      return StackVM::kArrStrides;
-    case builtin::kArrNDim:
-      return StackVM::kArrNDim;
-    case builtin::kArrTypeCode:
-      return StackVM::kArrTypeCode;
-    case builtin::kArrTypeBits:
-      return StackVM::kArrTypeBits;
-    case builtin::kArrTypeLanes:
-      return StackVM::kArrTypeLanes;
-    case builtin::kArrByteOffset:
-      return StackVM::kArrByteOffset;
-    case builtin::kArrDeviceId:
-      return StackVM::kArrDeviceId;
-    case builtin::kArrDeviceType:
-      return StackVM::kArrDeviceType;
-    case builtin::kTVMValueContent:
-      return StackVM::kTVMValueContent;
-    default:
-      LOG(FATAL) << "Do not know how to map field " << kind;
-  }
-  return StackVM::kArrData;
-}
-
-StackVM CodeGenStackVM::Compile(const PrimFunc& f) {
-  ICHECK_EQ(f->buffer_map.size(), 0U)
-      << "Cannot codegen function with buffer_map, please lower them first";
-  for (size_t i = 0; i < f->params.size(); ++i) {
-    Var v = f->params[i];
-    int vid = AllocVarID(v.get());
-    ICHECK_EQ(static_cast<size_t>(vid), i);
-  }
-  this->Push(f->body);
-  vm_.InitCache();
-  return std::move(vm_);
-}
-
-void CodeGenStackVM::Push(const Stmt& n) {
-  VisitStmt(n);
-  if (debug_) {
-    this->PushOp(StackVM::ASSERT_SP, 0);
-  }
-}
-
-void CodeGenStackVM::PushOp(StackVM::OpCode opcode) {
-  StackVM::Code code;
-  code.op_code = opcode;
-  vm_.code.push_back(code);
-}
-
-void CodeGenStackVM::SetOperand(int64_t operand_index, int64_t operand) {
-  ICHECK(operand >= std::numeric_limits<int>::min() && operand <= 
std::numeric_limits<int>::max());
-  vm_.code.at(operand_index).v_int = static_cast<int>(operand);
-}
-
-int64_t CodeGenStackVM::PushOp(StackVM::OpCode opcode, int operand) {
-  int64_t pc = static_cast<int64_t>(vm_.code.size());
-  StackVM::Code code;
-  code.op_code = opcode;
-  vm_.code.push_back(code);
-  code.v_int = operand;
-  vm_.code.push_back(code);
-  return pc + 1;
-}
-
-int CodeGenStackVM::GetStrID(const std::string& key) {
-  auto it = str_idmap_.find(key);
-  if (it != str_idmap_.end()) return it->second;
-  int sid = static_cast<int>(vm_.str_data.size());
-  vm_.str_data.push_back(key);
-  str_idmap_[key] = sid;
-  return sid;
-}
-
-int CodeGenStackVM::AllocVarID(const VarNode* v) {
-  ICHECK(!var_idmap_.count(v));
-  int vid = static_cast<int>(vm_.heap_size);
-  ICHECK_EQ(vm_.heap_size, var_idmap_.size());
-  vm_.heap_id_name.push_back(v->name_hint);
-  ++vm_.heap_size;
-  var_idmap_[v] = vid;
-  return vid;
-}
-
-int CodeGenStackVM::GetVarID(const VarNode* v) const {
-  auto it = var_idmap_.find(v);
-  ICHECK(it != var_idmap_.end()) << "Find undefined Variable " << v->name_hint;
-  return it->second;
-}
-
-void CodeGenStackVM::VisitExpr_(const BufferLoadNode* op) {
-  ICHECK_EQ(op->indices.size(), 1) << "StackVM expects flat 1-d buffers.  "
-                                   << "Has FlattenBuffer  been run?";
-  auto index = op->indices[0];
-
-  this->Push(op->buffer->data);
-  StackVM::OpCode code = StackVM::GetLoad(op->dtype);
-  if (const IntImmNode* int_index = index.as<IntImmNode>()) {
-    this->PushOp(code, int_index->value);
-  } else {
-    this->Push(index);
-    this->PushOp(StackVM::PUSH_I64, op->dtype.element_of().bytes());
-    this->PushOp(StackVM::MUL_I64);
-    this->PushOp(StackVM::ADDR_ADD);
-    this->PushOp(code, 0);
-  }
-}
-
-void CodeGenStackVM::VisitStmt_(const BufferStoreNode* op) {
-  ICHECK_EQ(op->indices.size(), 1) << "StackVM expects flat 1-d buffers.  "
-                                   << "Has FlattenBuffer been run?";
-  auto index = op->indices[0];
-
-  this->Push(op->buffer->data);
-  StackVM::OpCode code = StackVM::GetStore(op->value.dtype());
-  if (const IntImmNode* int_index = index.as<IntImmNode>()) {
-    this->Push(op->value);
-    this->PushOp(code, int_index->value);
-  } else {
-    this->Push(index);
-    this->PushOp(StackVM::PUSH_I64, op->value.dtype().element_of().bytes());
-    this->PushOp(StackVM::MUL_I64);
-    this->PushOp(StackVM::ADDR_ADD);
-    this->Push(op->value);
-    this->PushOp(code, 0);
-  }
-}
-
-void CodeGenStackVM::VisitStmt_(const AllocateNode* op) {
-  LOG(FATAL) << "Dynamic allocation not supported";
-}
-
-void CodeGenStackVM::VisitStmt_(const DeclBufferNode* op) { 
VisitStmt(op->body); }
-
-void CodeGenStackVM::VisitExpr_(const CallNode* op) {
-  if (op->op.same_as(builtin::address_of())) {
-    const BufferLoadNode* load = op->args[0].as<BufferLoadNode>();
-    ICHECK(op->args.size() == 1 && load);
-    ICHECK_EQ(load->indices.size(), 1) << "CodeGenStackVM only supports flat 
memory allocations.";
-
-    this->PushOp(StackVM::LOAD_HEAP, GetVarID(load->buffer->data.get()));
-    this->Push(load->indices[0]);
-    this->PushOp(StackVM::PUSH_I64, load->dtype.element_of().bytes());
-    this->PushOp(StackVM::MUL_I64);
-    this->PushOp(StackVM::ADDR_ADD);
-  } else if (op->op.same_as(builtin::reinterpret())) {
-    this->Push(op->args[0]);
-  } else if (op->op.same_as(builtin::tvm_struct_get())) {
-    ICHECK_EQ(op->args.size(), 3U);
-    int kind = op->args[2].as<IntImmNode>()->value;
-    this->Push(op->args[0]);
-    const IntImmNode* index = op->args[1].as<IntImmNode>();
-    ICHECK(index != nullptr);
-    StackVM::Code code;
-    code.op_code = StackVM::TVM_STRUCT_GET;
-    vm_.code.push_back(code);
-    code.v_int = index->value;
-    vm_.code.push_back(code);
-    code.v_int = MapFieldKind(kind);
-    vm_.code.push_back(code);
-  } else if (op->op.same_as(builtin::tvm_call_packed_lowered())) {
-    ICHECK_GE(op->args.size(), 5U);
-    const StringImmNode* s = op->args[0].as<StringImmNode>();
-    ICHECK(s != nullptr) << "tvm_call_global expect first argument as function 
name";
-    this->Push(op->args[1]);
-    this->Push(op->args[2]);
-    int begin = op->args[3].as<IntImmNode>()->value;
-    int end = op->args[4].as<IntImmNode>()->value;
-    // find the fuction id.
-    const std::string& func_name = s->value;
-    auto it = extern_fun_idmap_.find(func_name);
-    int fid;
-    if (it != extern_fun_idmap_.end()) {
-      fid = it->second;
-    } else {
-      fid = static_cast<int>(vm_.extern_func_name.size());
-      vm_.extern_func_name.push_back(func_name);
-      extern_fun_idmap_[func_name] = fid;
-    }
-    // CALL_PACKED_FUNC
-    StackVM::Code code;
-    code.op_code = StackVM::CALL_PACKED_LOWERED;
-    vm_.code.push_back(code);
-    code.v_int = fid;
-    vm_.code.push_back(code);
-    code.v_int = begin;
-    vm_.code.push_back(code);
-    code.v_int = end;
-    vm_.code.push_back(code);
-  } else if (op->op.same_as(builtin::tvm_stack_alloca())) {
-    ICHECK_EQ(op->args.size(), 2U);
-    const std::string& type = op->args[0].as<StringImmNode>()->value;
-    const IntImmNode* num = op->args[1].as<IntImmNode>();
-    ICHECK(num != nullptr);
-    static_assert(alignof(TVMValue) % alignof(DLTensor) == 0, "invariant");
-    // static_assert(alignof(TVMValue) % alignof(tvm_index_t) == 0, 
"invariant");
-    size_t unit = sizeof(TVMValue);
-    size_t size = 0;
-    if (type == "shape") {
-      size = (num->value * sizeof(tvm_index_t) + unit - 1) / unit;
-    } else if (type == "arg_value") {
-      size = (num->value * sizeof(TVMValue) + unit - 1) / unit;
-    } else if (type == "arg_tcode") {
-      size = (num->value * sizeof(int) + unit - 1) / unit;
-    } else if (type == "array") {
-      size = (num->value * sizeof(DLTensor) + unit - 1) / unit;
-    } else {
-      LOG(FATAL) << "Unknown stack alloca type " << type;
-    }
-    // add stack size to be safe.
-    vm_.stack_size += size;
-    this->PushOp(StackVM::TVM_STACK_ALLOCA_BY_8BYTE, static_cast<int>(size));
-  } else if (op->op.same_as(backend_alloc_workspace_op_)) {
-    ICHECK_EQ(op->args.size(), 5U);
-    this->Push(op->args[0]);
-    this->Push(op->args[1]);
-    this->Push(op->args[2]);
-    this->Push(op->args[3]);
-    this->Push(op->args[4]);
-    this->PushOp(StackVM::TVM_DEVICE_ALLOCA);
-  } else if (op->op.same_as(backend_free_workspace_op_)) {
-    ICHECK_EQ(op->args.size(), 3U);
-    this->Push(op->args[0]);
-    this->Push(op->args[1]);
-    this->Push(op->args[2]);
-    this->PushOp(StackVM::TVM_DEVICE_FREE);
-  } else if (op->op.same_as(builtin::tvm_throw_last_error())) {
-    this->PushOp(StackVM::TVM_THROW_LAST_ERROR);
-  } else if (op->op.same_as(builtin::isnullptr())) {
-    ICHECK_EQ(op->args.size(), 1U);
-    this->Push(op->args[0]);
-    this->PushOp(StackVM::PUSH_I64, 0);
-    this->PushOp(StackVM::EQ_HANDLE);
-  } else if (op->op.same_as(builtin::ret())) {
-    CHECK(op->args.size() == 1 && op->args[0]->IsInstance<IntImmNode>() &&
-          op->args[0].as<IntImmNode>()->value == 0)
-        << "StackVM does not support return values, "
-        << "and the return value " << op->args
-        << " is not special case of returning an error code of zero.";
-  } else {
-    LOG(FATAL) << "unknown function call " << op->op;
-  }
-}
-
-void CodeGenStackVM::PushBinary(StackVM::OpCode op_int64, const PrimExpr& a, 
const PrimExpr& b) {
-  this->Push(a);
-  this->Push(b);
-  DataType t = a.dtype();
-  if (t.is_int()) {
-    this->PushOp(op_int64);
-  } else if (t.is_uint()) {
-    this->PushOp(op_int64);
-  } else {
-    this->PushOp(StackVM::CodeI64ToF64(op_int64));
-  }
-}
-
-void CodeGenStackVM::PushCast(DataType dst, DataType src) {
-  if (dst.is_int()) {
-    if (src.is_int() || src.is_uint()) return;
-  } else if (dst.is_uint()) {
-    if (src.is_int() || src.is_uint()) return;
-  } else if (dst.is_float()) {
-    if (src.is_float()) return;
-  }
-}
-
-void CodeGenStackVM::VisitExpr_(const StringImmNode* op) {
-  int sid = this->GetStrID(op->value);
-  this->PushOp(StackVM::PUSH_I64, sid);
-}
-
-void CodeGenStackVM::VisitExpr_(const IntImmNode* op) {
-  ICHECK(op->value >= std::numeric_limits<int>::min() &&
-         op->value <= std::numeric_limits<int>::max())
-      << "Int constant exceed bound";
-  this->PushOp(StackVM::PUSH_I64, static_cast<int>(op->value));
-}
-
-void CodeGenStackVM::VisitExpr_(const FloatImmNode* op) {
-  LOG(FATAL) << "Float Imm is not supported";
-}
-
-void CodeGenStackVM::VisitExpr_(const VarNode* op) {
-  int vid = this->GetVarID(op);
-  this->PushOp(StackVM::LOAD_HEAP, vid);
-}
-
-void CodeGenStackVM::VisitExpr_(const CastNode* op) {
-  this->Push(op->value);
-  PushCast(op->dtype, op->value.dtype());
-}
-
-void CodeGenStackVM::VisitExpr_(const AddNode* op) { 
PushBinary(StackVM::ADD_I64, op->a, op->b); }
-
-void CodeGenStackVM::VisitExpr_(const SubNode* op) { 
PushBinary(StackVM::SUB_I64, op->a, op->b); }
-
-void CodeGenStackVM::VisitExpr_(const MulNode* op) { 
PushBinary(StackVM::MUL_I64, op->a, op->b); }
-
-void CodeGenStackVM::VisitExpr_(const DivNode* op) { 
PushBinary(StackVM::DIV_I64, op->a, op->b); }
-
-void CodeGenStackVM::VisitExpr_(const ModNode* op) { 
PushBinary(StackVM::MOD_I64, op->a, op->b); }
-
-void CodeGenStackVM::VisitExpr_(const MinNode* op) {
-  this->Push(op->a);
-  this->Push(op->b);
-  this->PushOp(StackVM::PUSH_VALUE, -1);
-  this->PushOp(StackVM::PUSH_VALUE, -1);
-  this->PushOp(StackVM::LT_I64);
-  this->PushOp(StackVM::SELECT);
-}
-
-void CodeGenStackVM::VisitExpr_(const MaxNode* op) {
-  this->Push(op->a);
-  this->Push(op->b);
-  this->PushOp(StackVM::PUSH_VALUE, 0);
-  this->PushOp(StackVM::PUSH_VALUE, -2);
-  this->PushOp(StackVM::LT_I64);
-  this->PushOp(StackVM::SELECT);
-}
-
-void CodeGenStackVM::VisitExpr_(const EQNode* op) { 
PushBinary(StackVM::EQ_I64, op->a, op->b); }
-
-void CodeGenStackVM::VisitExpr_(const LENode* op) { 
PushBinary(StackVM::LE_I64, op->a, op->b); }
-
-void CodeGenStackVM::VisitExpr_(const NENode* op) {
-  PushBinary(StackVM::EQ_I64, op->a, op->b);
-  this->PushOp(StackVM::NOT);
-}
-
-void CodeGenStackVM::VisitExpr_(const LTNode* op) { 
PushBinary(StackVM::LT_I64, op->a, op->b); }
-
-void CodeGenStackVM::VisitExpr_(const GENode* op) {
-  PushBinary(StackVM::LT_I64, op->a, op->b);
-  this->PushOp(StackVM::NOT);
-}
-
-void CodeGenStackVM::VisitExpr_(const GTNode* op) {
-  PushBinary(StackVM::LE_I64, op->a, op->b);
-  this->PushOp(StackVM::NOT);
-}
-
-void CodeGenStackVM::VisitExpr_(const AndNode* op) {
-  this->Push(op->a);
-  int64_t pc_jump = this->GetPC();
-  int64_t opr_index = this->PushOp(StackVM::RJUMP_IF_FALSE, 0);
-  this->PushOp(StackVM::POP);
-  this->Push(op->b);
-  int64_t diff = this->GetPC() - pc_jump;
-  this->SetOperand(opr_index, diff);
-}
-
-void CodeGenStackVM::VisitExpr_(const OrNode* op) {
-  this->Push(op->a);
-  int64_t pc_jump = this->GetPC();
-  int64_t opr_index = this->PushOp(StackVM::RJUMP_IF_TRUE, 0);
-  this->Push(op->b);
-  int64_t diff = this->GetPC() - pc_jump;
-  this->SetOperand(opr_index, diff);
-}
-
-void CodeGenStackVM::VisitExpr_(const NotNode* op) {
-  this->Push(op->a);
-  this->PushOp(StackVM::NOT);
-}
-
-void CodeGenStackVM::VisitStmt_(const ForNode* op) {
-  ICHECK(is_zero(op->min));
-  int vid = this->AllocVarID(op->loop_var.get());
-  this->PushOp(StackVM::PUSH_I64, 0);
-  int64_t loop_head = this->GetPC();
-  this->PushOp(StackVM::STORE_HEAP, vid);
-  this->PushOp(StackVM::LOAD_HEAP, vid);
-  this->Push(op->extent);
-  this->PushOp(StackVM::LT_I64);
-  int64_t label_fjump = this->GetPC();
-  int64_t foward_jump = this->PushOp(StackVM::RJUMP_IF_FALSE, 0);
-  this->PushOp(StackVM::POP);
-  this->Push(op->body);
-  this->PushOp(StackVM::LOAD_HEAP, vid);
-  this->PushOp(StackVM::PUSH_I64, 1);
-  this->PushOp(StackVM::ADD_I64);
-  int64_t label_bjump = this->GetPC();
-  int64_t backward_jump = this->PushOp(StackVM::RJUMP, 0);
-  int64_t loop_end = this->GetPC();
-  this->PushOp(StackVM::POP);
-  this->SetOperand(foward_jump, loop_end - label_fjump);
-  this->SetOperand(backward_jump, loop_head - label_bjump);
-}
-
-void CodeGenStackVM::VisitStmt_(const SeqStmtNode* op) {
-  for (Stmt stmt : op->seq) {
-    this->Push(stmt);
-  }
-}
-
-void CodeGenStackVM::VisitStmt_(const EvaluateNode* ev) {
-  if (is_const_int(ev->value)) return;
-  const CallNode* op = ev->value.as<CallNode>();
-  if (op && op->op.same_as(builtin::tvm_struct_set())) {
-    ICHECK_EQ(op->args.size(), 4U);
-    this->Push(op->args[0]);
-    this->Push(op->args[3]);
-    const IntImmNode* index = op->args[1].as<IntImmNode>();
-    ICHECK(index != nullptr);
-    StackVM::Code code;
-    code.op_code = StackVM::TVM_STRUCT_SET;
-    vm_.code.push_back(code);
-    code.v_int = index->value;
-    vm_.code.push_back(code);
-    code.v_int = MapFieldKind(op->args[2].as<IntImmNode>()->value);
-    vm_.code.push_back(code);
-  } else {
-    this->Push(ev->value);
-    this->PushOp(StackVM::POP);
-  }
-}
-
-void CodeGenStackVM::VisitStmt_(const IfThenElseNode* op) {
-  this->Push(op->condition);
-  int64_t label_ejump = this->GetPC();
-  int64_t else_jump = this->PushOp(StackVM::RJUMP_IF_FALSE, 0);
-  this->PushOp(StackVM::POP);
-  this->Push(op->then_case);
-  if (op->else_case) {
-    int64_t label_then_jump = this->GetPC();
-    int64_t then_jump = this->PushOp(StackVM::RJUMP, 0);
-    int64_t else_begin = this->GetPC();
-    this->SetOperand(else_jump, else_begin - label_ejump);
-    this->PushOp(StackVM::POP);
-    this->Push(op->else_case.value());
-    int64_t if_end = this->GetPC();
-    this->SetOperand(then_jump, if_end - label_then_jump);
-  } else {
-    int64_t if_end = this->GetPC();
-    this->SetOperand(else_jump, if_end - label_ejump);
-    this->PushOp(StackVM::POP);
-  }
-}
-
-void CodeGenStackVM::VisitStmt_(const LetStmtNode* op) {
-  this->Push(op->value);
-  int64_t vid = this->AllocVarID(op->var.get());
-  this->PushOp(StackVM::STORE_HEAP, static_cast<int>(vid));
-  this->Push(op->body);
-}
-
-void CodeGenStackVM::VisitExpr_(const RampNode* op) { LOG(FATAL) << "Ramp is 
not supported"; }
-
-void CodeGenStackVM::VisitExpr_(const BroadcastNode* op) {
-  LOG(FATAL) << "Broadcast is not supported";
-}
-
-void CodeGenStackVM::VisitExpr_(const SelectNode* op) {
-  this->Push(op->true_value);
-  this->Push(op->false_value);
-  this->Push(op->condition);
-  this->PushOp(StackVM::SELECT);
-}
-
-void CodeGenStackVM::VisitStmt_(const AssertStmtNode* op) {
-  if (const auto* str = op->message.as<StringImmNode>()) {
-    int sid = this->GetStrID(str->value);
-    this->Push(op->condition);
-    this->PushOp(StackVM::ASSERT, sid);
-  }
-  this->Push(op->body);
-}
-
-void CodeGenStackVM::VisitStmt_(const AttrStmtNode* op) { 
this->Push(op->body); }
-
-void CodeGenStackVM::VisitExpr_(const LetNode* op) {
-  this->Push(op->value);
-  int64_t vid = this->AllocVarID(op->var.get());
-  this->PushOp(StackVM::STORE_HEAP, static_cast<int>(vid));
-  this->Push(op->body);
-}
-
-runtime::Module BuildStackVM(IRModule mod, Target target) {
-  std::unordered_map<std::string, StackVM> fmap;
-  std::string entry_func;
-
-  for (auto kv : mod->functions) {
-    ICHECK(kv.second->IsInstance<PrimFuncNode>()) << "CodeGenStackVM: Can only 
take PrimFunc";
-    auto f = Downcast<PrimFunc>(kv.second);
-    auto global_symbol = f->GetAttr<String>(tvm::attr::kGlobalSymbol);
-    ICHECK(global_symbol.defined())
-        << "CodeGenStackVM: Expect PrimFunc to have the global_symbol 
attribute";
-    std::string f_name = global_symbol.value();
-    StackVM vm = codegen::CodeGenStackVM().Compile(f);
-    ICHECK(!fmap.count(f_name)) << "Function name " << f_name << "already 
exist in list";
-    fmap[f_name] = std::move(vm);
-
-    if (f->HasNonzeroAttr(tir::attr::kIsEntryFunc)) {
-      entry_func = f_name;
-    }
-  }
-
-  return runtime::StackVMModuleCreate(fmap, entry_func);
-}
-
-TVM_REGISTER_GLOBAL("target.build.stackvm").set_body_typed(BuildStackVM);
-}  // namespace codegen
-}  // namespace tvm
diff --git a/src/target/stackvm/codegen_stackvm.h 
b/src/target/stackvm/codegen_stackvm.h
deleted file mode 100644
index 0bac55e3b2..0000000000
--- a/src/target/stackvm/codegen_stackvm.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/*!
- * \file codegen_stack_vm.h
- * \brief Codegen into Simple Stack VM.
- */
-#ifndef TVM_TARGET_STACKVM_CODEGEN_STACKVM_H_
-#define TVM_TARGET_STACKVM_CODEGEN_STACKVM_H_
-
-#include <tvm/target/codegen.h>
-#include <tvm/tir/expr.h>
-#include <tvm/tir/function.h>
-#include <tvm/tir/op.h>
-#include <tvm/tir/stmt_functor.h>
-
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include "../../runtime/stackvm/stackvm.h"
-
-namespace tvm {
-namespace codegen {
-
-using namespace tir;
-using runtime::StackVM;
-
-/*!
- * \brief A base class to generate a stack VM.
- *  This module is used to generate host wrapper
- *  into device function when only device JIT is available.
- */
-class CodeGenStackVM : public ExprFunctor<void(const PrimExpr&)>,
-                       public StmtFunctor<void(const Stmt&)> {
- public:
-  /*!
-   * \brief Generate a stack VM representing
-   * \param f The function to be compiled
-   * \param device_funcs The extern device functions to be linked.
-   * \note Only call compile once,
-   *  create a new codegen object each time.
-   */
-  StackVM Compile(const PrimFunc& f);
-  /*! \brief Push stmt to generate new code */
-  void Push(const Stmt& n);
-  /*! \brief Push expr to generate new code */
-  void Push(const PrimExpr& n) { VisitExpr(n); }
-  /*!
-   * \brief Push the opcode to the code.
-   * \param opcode The code to be pushed.
-   */
-  void PushOp(StackVM::OpCode opcode);
-  /*!
-   * \brief Push the opcode and operand to the code.
-   * \param opcode The opcode.
-   * \param operand The operand to be pushed.
-   * \return operand_index, indicating location of operand
-   */
-  int64_t PushOp(StackVM::OpCode opcode, int operand);
-  /*!
-   * \brief Set the relative jump offset to be offset.
-   * \param operand_index The indexed returned by PushOp.
-   * \param operand The operand to be set.
-   */
-  void SetOperand(int64_t operand_index, int64_t operand);
-  /*! \return The current program pointer */
-  int64_t GetPC() const { return static_cast<int64_t>(vm_.code.size()); }
-  /*!
-   * \brief Get string id in vm
-   * \param key The string to get id.
-   * \return the id of the string.
-   */
-  int GetStrID(const std::string& key);
-  /*!
-   * \brief Allocate a variable name for a newly defined var.
-   * \param v The variable.
-   * \return the heap index of the var.
-   */
-  int AllocVarID(const VarNode* v);
-  /*!
-   * \brief Get a variable name.
-   * \param v The variable.
-   * \return the heap index of the var.
-   */
-  int GetVarID(const VarNode* v) const;
-  // Push binary operator
-  void PushBinary(StackVM::OpCode op_int64, const PrimExpr& a, const PrimExpr& 
b);
-  // push cast;
-  void PushCast(DataType dst, DataType src);
-  // overloadable functions
-  // expression
-  void VisitExpr_(const VarNode* op) final;
-  void VisitExpr_(const BufferLoadNode* op) final;
-  void VisitExpr_(const LetNode* op) final;
-  void VisitExpr_(const CallNode* op) final;
-  void VisitExpr_(const AddNode* op) final;
-  void VisitExpr_(const SubNode* op) final;
-  void VisitExpr_(const MulNode* op) final;
-  void VisitExpr_(const DivNode* op) final;
-  void VisitExpr_(const ModNode* op) final;
-  void VisitExpr_(const MinNode* op) final;
-  void VisitExpr_(const MaxNode* op) final;
-  void VisitExpr_(const EQNode* op) final;
-  void VisitExpr_(const NENode* op) final;
-  void VisitExpr_(const LTNode* op) final;
-  void VisitExpr_(const LENode* op) final;
-  void VisitExpr_(const GTNode* op) final;
-  void VisitExpr_(const GENode* op) final;
-  void VisitExpr_(const AndNode* op) final;
-  void VisitExpr_(const OrNode* op) final;
-  void VisitExpr_(const CastNode* op) final;
-  void VisitExpr_(const NotNode* op) final;
-  void VisitExpr_(const SelectNode* op) final;
-  void VisitExpr_(const RampNode* op) final;
-  void VisitExpr_(const BroadcastNode* op) final;
-  void VisitExpr_(const IntImmNode* op) final;
-  void VisitExpr_(const FloatImmNode* op) final;
-  void VisitExpr_(const StringImmNode* op) final;
-  // statment
-  void VisitStmt_(const LetStmtNode* op) final;
-  void VisitStmt_(const BufferStoreNode* op) final;
-  void VisitStmt_(const ForNode* op) final;
-  void VisitStmt_(const IfThenElseNode* op) final;
-  void VisitStmt_(const AllocateNode* op) final;
-  void VisitStmt_(const DeclBufferNode* op) final;
-  void VisitStmt_(const AttrStmtNode* op) final;
-  void VisitStmt_(const AssertStmtNode* op) final;
-  void VisitStmt_(const EvaluateNode* op) final;
-  void VisitStmt_(const SeqStmtNode* op) final;
-
- private:
-  bool debug_{false};
-  /*! \brief The vm to be generated */
-  StackVM vm_;
-  /*! \brief id of each variable */
-  std::unordered_map<const VarNode*, int> var_idmap_;
-  /*! \brief id of each string */
-  std::unordered_map<std::string, int> str_idmap_;
-  /*! \brief id of each global function */
-  std::unordered_map<std::string, int> extern_fun_idmap_;
-
-  Op backend_alloc_workspace_op_ = Op::Get("tir.TVMBackendAllocWorkspace");
-  Op backend_free_workspace_op_ = Op::Get("tir.TVMBackendFreeWorkspace");
-};
-
-}  // namespace codegen
-}  // namespace tvm
-#endif  // TVM_TARGET_STACKVM_CODEGEN_STACKVM_H_
diff --git a/src/target/target_kind.cc b/src/target/target_kind.cc
index 62ba2787a3..a60f63dc21 100644
--- a/src/target/target_kind.cc
+++ b/src/target/target_kind.cc
@@ -434,9 +434,6 @@ TVM_REGISTER_TARGET_KIND("hexagon", kDLHexagon)
     .add_attr_option<runtime::Int>("vtcm-capacity")
     .set_default_keys({"hexagon", "cpu"});
 
-TVM_REGISTER_TARGET_KIND("stackvm", kDLCPU)  // line break
-    .set_default_keys({"cpu"});
-
 TVM_REGISTER_TARGET_KIND("ext_dev", kDLExtDev);
 
 TVM_REGISTER_TARGET_KIND("hybrid", kDLCPU);
diff --git a/tests/python/codegen/test_target_codegen_device.py 
b/tests/python/codegen/test_target_codegen_device.py
index 1adb337de0..4dad03d700 100644
--- a/tests/python/codegen/test_target_codegen_device.py
+++ b/tests/python/codegen/test_target_codegen_device.py
@@ -89,7 +89,7 @@ def test_add_pipeline():
     sch.bind(d_xi, "threadIdx.x")
     sch.bind(d_xo, "blockIdx.x")
 
-    def check_target(device, host="stackvm"):
+    def check_target(device, host):
         if not tvm.testing.device_enabled(device) or not 
tvm.testing.device_enabled(host):
             return
         dev = tvm.device(device, 0)
diff --git a/tests/python/codegen/test_target_codegen_extern.py 
b/tests/python/codegen/test_target_codegen_extern.py
index 99069b1bd1..35227baaff 100644
--- a/tests/python/codegen/test_target_codegen_extern.py
+++ b/tests/python/codegen/test_target_codegen_extern.py
@@ -115,7 +115,6 @@ def test_pack_buffer_simple():
         f(a, c)
         tvm.testing.assert_allclose(c.numpy(), a.numpy())
 
-    check_target("stackvm")
     check_target("llvm")
 
 
diff --git a/tests/python/codegen/test_target_codegen_vm_basic.py 
b/tests/python/codegen/test_target_codegen_vm_basic.py
deleted file mode 100644
index d1a3c7217a..0000000000
--- a/tests/python/codegen/test_target_codegen_vm_basic.py
+++ /dev/null
@@ -1,143 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-import tvm
-import tvm.testing
-from tvm import te
-from tvm.script import tir as T, ir as I
-
-import numpy as np
-
-
-def run_jit(fapi, check):
-    for target in ["llvm", "stackvm"]:
-        if not tvm.testing.device_enabled(target):
-            continue
-        f = tvm.driver.build(fapi, target=target)
-        s = f.get_source()
-        check(f)
-
-
-def test_stack_vm_basic():
-    a = tvm.nd.array(np.zeros(10, dtype="float32"))
-
-    @tvm.register_func
-    def tvm_call_back_get_shape(shape0):
-        print(shape0)
-        assert shape0 == a.shape[0]
-
-    n = te.size_var("n")
-    Ab = tvm.tir.decl_buffer((n,), "float32")
-    stmt = tvm.tir.Evaluate(tvm.tir.call_packed("tvm_call_back_get_shape", 
Ab.shape[0]))
-
-    mod = tvm.IRModule.from_expr(
-        tvm.tir.PrimFunc([Ab], stmt).with_attr("global_symbol", "print_shape")
-    )
-
-    run_jit(mod, lambda f: f(a))
-
-
[email protected]_func
-def tvm_stack_vm_print(*x):
-    print(x)
-
-
-def test_stack_vm_loop():
-    dtype = "int64"
-    n = te.size_var("n")
-    Ab = tvm.tir.decl_buffer((n,), dtype)
-    i = te.size_var("i")
-
-    ib = tvm.tir.ir_builder.create()
-    A = ib.buffer_ptr(Ab)
-    with ib.for_range(0, n - 1, "i") as i:
-        A[i + 1] = A[i] + 1
-        ib.emit(tvm.tir.call_packed("tvm_stack_vm_print", i))
-
-    stmt = ib.get()
-    mod = tvm.IRModule.from_expr(tvm.tir.PrimFunc([Ab], 
stmt).with_attr("global_symbol", "ramp"))
-    a = tvm.nd.array(np.zeros(10, dtype=dtype))
-
-    def check(f):
-        f(a)
-        np.testing.assert_equal(a.numpy(), np.arange(a.shape[0]))
-
-    run_jit(mod, check)
-
-
-def test_stack_vm_cond():
-    dtype = "int64"
-    n = te.size_var("n")
-    Ab = tvm.tir.decl_buffer((n,), dtype)
-
-    ib = tvm.tir.ir_builder.create()
-    A = ib.buffer_ptr(Ab)
-    with ib.for_range(0, n - 1, "i") as i:
-        with ib.if_scope(tvm.tir.EQ(i, 4)):
-            A[i + 1] = A[i] + 1
-        with ib.else_scope():
-            A[i + 1] = A[i] + 2
-
-    stmt = ib.get()
-    mod = tvm.IRModule.from_expr(tvm.tir.PrimFunc([Ab], 
stmt).with_attr("global_symbol", "test"))
-
-    def check(f):
-        a = tvm.nd.array(np.zeros(10, dtype=dtype))
-        f(a)
-        y = np.arange(a.shape[0]) * 2
-        y[5:] -= 1
-        np.testing.assert_equal(a.numpy(), y)
-
-    run_jit(mod, check)
-
-
-def test_vm_parallel():
-    dtype = "int64"
-    n = te.size_var("n")
-    Ab = tvm.tir.decl_buffer((n,), dtype)
-    i = te.size_var("i")
-    ib = tvm.tir.ir_builder.create()
-    A = ib.buffer_ptr(Ab)
-    with ib.for_range(0, n, "i", kind="parallel") as i:
-        A[i] = A[i] + 1
-    stmt = ib.get()
-    mod = tvm.IRModule.from_expr(tvm.tir.PrimFunc([Ab], 
stmt).with_attr("global_symbol", "test"))
-
-    def check(f):
-        a = tvm.nd.array(np.zeros(10, dtype=dtype))
-        f(a)
-        np.testing.assert_equal(a.numpy(), np.ones(a.shape[0]))
-
-    run_jit(mod, check)
-
-
-def test_codegen_decl_buffer():
-    """The codegen should accept DeclBuffer nodes in its input"""
-
-    @I.ir_module
-    class mod:
-        @T.prim_func
-        def kernel(A_data: T.handle("float32")):
-            T.func_attr({"global_symbol": "kernel"})
-            A_buf = T.decl_buffer([256], dtype="float32", scope="global", 
data=A_data)
-
-    target = tvm.target.Target("stackvm")
-    stackvm_codegen = tvm.get_global_func("target.build.stackvm")
-    stackvm_codegen(mod, target)
-
-
-if __name__ == "__main__":
-    tvm.testing.main()
diff --git a/tests/python/tir-transform/test_tir_transform_lower_tvm_builtin.py 
b/tests/python/tir-transform/test_tir_transform_lower_tvm_builtin.py
index 7d7f610123..89e8b9e350 100644
--- a/tests/python/tir-transform/test_tir_transform_lower_tvm_builtin.py
+++ b/tests/python/tir-transform/test_tir_transform_lower_tvm_builtin.py
@@ -148,7 +148,6 @@ def check_packed_func(target="llvm"):
 
 def test_lower_packed_func():
     check_packed_func("llvm")
-    check_packed_func("stackvm")
 
 
 @tvm.testing.requires_llvm
diff --git a/tests/scripts/task_config_build_gpu.sh 
b/tests/scripts/task_config_build_gpu.sh
index 74bb702a8b..f306bdf8bf 100755
--- a/tests/scripts/task_config_build_gpu.sh
+++ b/tests/scripts/task_config_build_gpu.sh
@@ -32,7 +32,6 @@ echo set\(USE_OPENCL_GTEST \"/googletest\"\) >> config.cmake
 echo set\(USE_LLVM \"/usr/bin/llvm-config-15 --link-static\"\) >> config.cmake
 echo set\(USE_RPC ON\) >> config.cmake
 echo set\(USE_SORT ON\) >> config.cmake
-echo set\(USE_STACKVM_RUNTIME ON\) >> config.cmake
 echo set\(USE_BLAS openblas\) >> config.cmake
 echo set\(CMAKE_CXX_FLAGS -Werror\) >> config.cmake
 echo set\(USE_TENSORRT_CODEGEN ON\) >> config.cmake

Reply via email to