diff --git a/dlpack b/dlpack
index a6e09b58dc00ee0065f5b7879800e646fbb01d1e..36e573893fc39d324ccf2f2962300da6da5898a2 160000
--- a/dlpack
+++ b/dlpack
@@ -1 +1 @@
-Subproject commit a6e09b58dc00ee0065f5b7879800e646fbb01d1e
+Subproject commit 36e573893fc39d324ccf2f2962300da6da5898a2
diff --git a/include/tvm/runtime/c_runtime_api.h b/include/tvm/runtime/c_runtime_api.h
index a3a1693f61a4c2ac42471e8ddb9e452fdc05b467..7c1724e4b4740e597bc1332e5abc864e5f59ae6f 100644
--- a/include/tvm/runtime/c_runtime_api.h
+++ b/include/tvm/runtime/c_runtime_api.h
@@ -182,21 +182,6 @@ TVM_DLL int TVMModGetFunction(TVMModuleHandle mod,
                               int query_imports,
                               TVMFunctionHandle *out);
 
-/*!
- * \brief Precompile the function under given context.
- *  Many TVMFunctionHandle is initialized lazily,
- *  This call eagerly prepares the resources under given context.
- *  Useful for benchmarking purposes.
- *
- * \param mod The module handle.
- * \param func_name The name of the function.
- * \param ctx The context to be precompiled on.
- * \return 0 when no error is thrown, -1 when failure happens
- */
-TVM_DLL int TVMModPreCompile(TVMModuleHandle mod,
-                             const char* func_name,
-                             TVMContext ctx);
-
 /*!
  * \brief Free the Module
  * \param mod The module to be freed.
diff --git a/include/tvm/runtime/module.h b/include/tvm/runtime/module.h
index ca6244835beb00b195dfab43e511d7a499ecc061..81dce558792c1595cfb7a529d993226c48cfbc9b 100644
--- a/include/tvm/runtime/module.h
+++ b/include/tvm/runtime/module.h
@@ -76,17 +76,6 @@ class ModuleNode {
   virtual ~ModuleNode() {}
   /*! \return The module type key */
   virtual const char* type_key() const = 0;
-  /*!
-   * \brief Eagerly compile the function under certain context,
-   *  assuming that it is used by the current thread.
-   *
-   *  This is useful for benchmarking to eliminate lazy compilation
-   *  overhead during the first execution of the kernel.
-   *
-   * \param name The name of the function.
-   * \param ctx The context to be executed.
-   */
-  virtual void PreCompile(const std::string& name, TVMContext ctx) = 0;
   /*!
    * \brief Get a PackedFunc from module.
    *
@@ -113,7 +102,7 @@ class ModuleNode {
    * \param format The format of the file.
    */
   virtual void SaveToFile(const std::string& file_name,
-                          const std::string& format) = 0;
+                          const std::string& format);
   /*!
    * \brief Save the module to binary stream.
    * \param stream The binary stream to save to.
@@ -121,14 +110,13 @@ class ModuleNode {
    *   but not necessarily host modules.
    *   We can use this to do AOT loading of bundled device functions.
    */
-  virtual void SaveToBinary(dmlc::Stream* stream) = 0;
+  virtual void SaveToBinary(dmlc::Stream* stream);
   /*!
    * \brief Get the source code of module, when available.
    * \param format Format of the source code, can be empty by default.
    * \return Possible source code when available.
    */
-  virtual std::string GetSource(
-      const std::string& format = "") = 0;
+  virtual std::string GetSource(const std::string& format = "");
   /*!
    * \brief Get a function from current environment
    *  The environment includes all the imports as well as Global functions.
diff --git a/python/tvm/_ffi/function.py b/python/tvm/_ffi/function.py
index 6dfe5f122fd0b9e5cdd782d9dae02567617a400c..b89da713a1adaea3719e834851931b639d73d378 100644
--- a/python/tvm/_ffi/function.py
+++ b/python/tvm/_ffi/function.py
@@ -116,20 +116,6 @@ class ModuleBase(object):
         """
         check_call(_LIB.TVMModImport(self.handle, module.handle))
 
-    def precompile(self, func_name, ctx):
-        """Add module to the import list of current one.
-
-        Parameters
-        ----------
-        func_name : str
-            The name of function to be precompiled.
-
-        ctx : Context
-            The context to be precompiled.
-        """
-        check_call(_LIB.TVMModPreCompile(
-            self.handle, c_str(func_name), ctx))
-
     def __getitem__(self, name):
         if not isinstance(name, string_types):
             raise ValueError("Can only take string as function name")
diff --git a/src/codegen/llvm/llvm_module.cc b/src/codegen/llvm/llvm_module.cc
index 74e62f2fd3df44ca8c054f2e8a313017d75d3ea9..8ccbc892f3961623a6002e606d86141fcdecef4a 100644
--- a/src/codegen/llvm/llvm_module.cc
+++ b/src/codegen/llvm/llvm_module.cc
@@ -33,17 +33,6 @@ class LLVMModuleNode final : public runtime::ModuleNode {
     return "llvm";
   }
 
-  void PreCompile(const std::string& name, TVMContext ctx) final {
-    if (ee_ == nullptr) LazyInitJIT();
-    std::lock_guard<std::mutex> lock(mutex_);
-    const std::string& fname = (name == runtime::symbol::tvm_module_main ?
-                                entry_func_ : name);
-    BackendPackedCFunc faddr =
-        reinterpret_cast<BackendPackedCFunc>(ee_->getFunctionAddress(fname));
-    CHECK(faddr != nullptr)
-        << "Failed to Precompile function " << name;
-  }
-
   PackedFunc GetFunction(
       const std::string& name,
       const std::shared_ptr<ModuleNode>& sptr_to_self) final {
diff --git a/src/codegen/source_module.cc b/src/codegen/source_module.cc
index 3a4be4929536f577cd73641ba8e644a1a2b0acf7..1ad2168ae06ee8fa7f5833fbfbf1a6e36e14bb0b 100644
--- a/src/codegen/source_module.cc
+++ b/src/codegen/source_module.cc
@@ -21,8 +21,6 @@ class SourceModuleNode final : public runtime::ModuleNode {
   const char* type_key() const {
     return "source";
   }
-  void PreCompile(const std::string& name, TVMContext ctx) final {
-  }
   PackedFunc GetFunction(
       const std::string& name,
       const std::shared_ptr<ModuleNode>& sptr_to_self) final {
@@ -31,15 +29,6 @@ class SourceModuleNode final : public runtime::ModuleNode {
     return PackedFunc();
   }
 
-  void SaveToFile(const std::string& file_name,
-                  const std::string& format) final {
-    LOG(FATAL) << "SourceModule: SaveToFile not supported";
-  }
-
-  void SaveToBinary(dmlc::Stream* stream) final {
-    LOG(FATAL) << "SourceModule: SaveToBinary not supported";
-  }
-
   std::string GetSource(const std::string& format) final {
     return code_;
   }
diff --git a/src/codegen/stack_vm/stack_vm_module.cc b/src/codegen/stack_vm/stack_vm_module.cc
index 42680fcaace6d18f0ffb7e7e706aa74376540c21..731663deb4488700d90619172e46e4abcd9c9746 100644
--- a/src/codegen/stack_vm/stack_vm_module.cc
+++ b/src/codegen/stack_vm/stack_vm_module.cc
@@ -16,8 +16,6 @@ class StackVMModuleNode : public runtime::ModuleNode {
     return "stackvm";
   }
 
-  void PreCompile(const std::string& name, TVMContext ctx) final {}
-
   PackedFunc GetFunction(
       const std::string& name,
       const std::shared_ptr<ModuleNode>& sptr_to_self) final {
@@ -33,15 +31,6 @@ class StackVMModuleNode : public runtime::ModuleNode {
       });
   }
 
-  void SaveToFile(const std::string& file_name,
-                  const std::string& format) final {
-    LOG(FATAL) << "StackVMModule: SaveToFile not supported";
-  }
-
-  void SaveToBinary(dmlc::Stream* stream) final {
-    LOG(FATAL) << "StackVMModule: SaveToBinary not supported";
-  }
-
   std::string GetSource(const std::string& format) final {
     std::ostringstream os;
     for (const auto& kv : fmap_) {
diff --git a/src/codegen/verilog/verilog_module.cc b/src/codegen/verilog/verilog_module.cc
index 15e96731ae9d1640bf4e20028dc0d843ae4b2077..0319d6e6556c632d0562384d5e37037aac86c602 100644
--- a/src/codegen/verilog/verilog_module.cc
+++ b/src/codegen/verilog/verilog_module.cc
@@ -24,8 +24,6 @@ class VerilogModuleNode : public runtime::ModuleNode {
   const char* type_key() const {
     return "verilog";
   }
-  void PreCompile(const std::string& name, TVMContext ctx) final {
-  }
 
   PackedFunc GetFunction(
       const std::string& name,
@@ -57,15 +55,6 @@ class VerilogModuleNode : public runtime::ModuleNode {
     return PackedFunc(f);
   }
 
-  void SaveToFile(const std::string& file_name,
-                  const std::string& format) final {
-    LOG(FATAL) << "VerilogModule: SaveToFile not supported";
-  }
-
-  void SaveToBinary(dmlc::Stream* stream) final {
-    LOG(FATAL) << "VerilogModule: SaveToBinary not supported";
-  }
-
   std::string GetSource(const std::string& format) final {
     return m_.code;
   }
diff --git a/src/runtime/c_runtime_api.cc b/src/runtime/c_runtime_api.cc
index a14dd9e421064230da9000f2ee129f1b288a7adb..d8dd53d318fd5eea746d17359d1f67dbdbd5e6bf 100644
--- a/src/runtime/c_runtime_api.cc
+++ b/src/runtime/c_runtime_api.cc
@@ -196,14 +196,6 @@ int TVMModGetFunction(TVMModuleHandle mod,
   API_END();
 }
 
-int TVMModPreCompile(TVMModuleHandle mod,
-                     const char* func_name,
-                     TVMContext ctx) {
-  API_BEGIN();
-  (*static_cast<Module*>(mod))->PreCompile(func_name, ctx);
-  API_END();
-}
-
 int TVMModFree(TVMModuleHandle mod) {
   API_BEGIN();
   delete static_cast<Module*>(mod);
diff --git a/src/runtime/cuda/cuda_module.cc b/src/runtime/cuda/cuda_module.cc
index 9092a012773313451696182fb65a2d739f33d388..28a36078fefefc81426a4eb1c259652ea9131a9a 100644
--- a/src/runtime/cuda/cuda_module.cc
+++ b/src/runtime/cuda/cuda_module.cc
@@ -49,12 +49,6 @@ class CUDAModuleNode : public runtime::ModuleNode {
     return "cuda";
   }
 
-  void PreCompile(const std::string& name, TVMContext ctx) final {
-    CUDA_CALL(cudaSetDevice(ctx.device_id));
-    cudaFree(nullptr);
-    this->GetFunc(ctx.device_id, name);
-  }
-
   PackedFunc GetFunction(
       const std::string& name,
       const std::shared_ptr<ModuleNode>& sptr_to_self) final;
diff --git a/src/runtime/dso_module.cc b/src/runtime/dso_module.cc
index 645b1b42dacc3a8e910cf06df4761f9566ac82c6..6eae75773061f058506f3dbfdf7c4dd464ed3d6d 100644
--- a/src/runtime/dso_module.cc
+++ b/src/runtime/dso_module.cc
@@ -30,10 +30,6 @@ class DSOModuleNode final : public ModuleNode {
     return "dso";
   }
 
-  void PreCompile(const std::string& name, TVMContext ctx) final {
-    GetFuncPtr(name);
-  }
-
   PackedFunc GetFunction(
       const std::string& name,
       const std::shared_ptr<ModuleNode>& sptr_to_self) final {
@@ -48,19 +44,6 @@ class DSOModuleNode final : public ModuleNode {
       });
   }
 
-  void SaveToFile(const std::string& file_name,
-                  const std::string& format) final {
-    LOG(FATAL) << "DSOModule: SaveToFile not supported";
-  }
-
-  void SaveToBinary(dmlc::Stream* stream) final {
-    LOG(FATAL) << "DSOModule: SaveToBinary not supported";
-  }
-
-  std::string GetSource(const std::string& format) final {
-    return "";
-  }
-
   void Init(const std::string& name) {
     Load(name);
     CHECK(lib_handle_ != nullptr)
diff --git a/src/runtime/metal/metal_module.mm b/src/runtime/metal/metal_module.mm
index 4d8b231f30f330dfc10b5599a1b988c057840485..39b9d7bd8029d01285358a0e900ed67107b6ca48 100644
--- a/src/runtime/metal/metal_module.mm
+++ b/src/runtime/metal/metal_module.mm
@@ -37,10 +37,6 @@ class MetalModuleNode final :public runtime::ModuleNode {
     return "metal";
   }
 
-  void PreCompile(const std::string& name, TVMContext ctx) final {
-    GetPipelineState(ctx.device_id, name);
-  }
-
   PackedFunc GetFunction(
       const std::string& name,
       const std::shared_ptr<ModuleNode>& sptr_to_self) final;
diff --git a/src/runtime/module.cc b/src/runtime/module.cc
index e4078b6fac6cc4a0800fafb946d650f7b01cc67a..45f969b4114752ae08c0120c588cef4428cbf8a9 100644
--- a/src/runtime/module.cc
+++ b/src/runtime/module.cc
@@ -62,6 +62,20 @@ Module Module::LoadFromFile(const std::string& file_name,
   return m;
 }
 
+void ModuleNode::SaveToFile(const std::string& file_name,
+                            const std::string& format) {
+  LOG(FATAL) << "Module[" << type_key() << "] does not support SaveToFile";
+}
+
+void ModuleNode::SaveToBinary(dmlc::Stream* stream) {
+  LOG(FATAL) << "Module[" << type_key() << "] does not support SaveToBinary";
+}
+
+std::string ModuleNode::GetSource(const std::string& format) {
+  LOG(FATAL) << "Module[" << type_key() << "] does not support GetSource";
+  return "";
+}
+
 const PackedFunc* ModuleNode::GetFuncFromEnv(const std::string& name) {
   auto it = import_cache_.find(name);
   if (it != import_cache_.end()) return it->second.get();
diff --git a/src/runtime/opencl/opencl_module.cc b/src/runtime/opencl/opencl_module.cc
index d0965d9fecaf85112fde874e2da6021fc957c8d6..c193e093ce4bcf6ae4c52bdd6bc9a3e6887a2b65 100644
--- a/src/runtime/opencl/opencl_module.cc
+++ b/src/runtime/opencl/opencl_module.cc
@@ -59,12 +59,6 @@ class OpenCLModuleNode : public ModuleNode {
     return "opencl";
   }
 
-  void PreCompile(const std::string& name, TVMContext ctx) final {
-    InstallKernel(cl::OpenCLWorkspace::Global(),
-                  cl::OpenCLThreadEntry::ThreadLocal(),
-                  name, kid_map_.at(name));
-  }
-
   PackedFunc GetFunction(
       const std::string& name,
       const std::shared_ptr<ModuleNode>& sptr_to_self) final;
diff --git a/src/runtime/rpc/rpc_module.cc b/src/runtime/rpc/rpc_module.cc
index d3606f0a2366be091190f657e4489ee84f0e7256..af855cef060d5a9282b42922c5541d04a712614c 100644
--- a/src/runtime/rpc/rpc_module.cc
+++ b/src/runtime/rpc/rpc_module.cc
@@ -45,9 +45,6 @@ class RPCModuleNode final : public ModuleNode {
     return "rpc";
   }
 
-  void PreCompile(const std::string& name, TVMContext ctx) final {
-  }
-
   PackedFunc GetFunction(
       const std::string& name,
       const std::shared_ptr<ModuleNode>& sptr_to_self) final {
@@ -55,15 +52,6 @@ class RPCModuleNode final : public ModuleNode {
     return WrapRemote(handle);
   }
 
-  void SaveToFile(const std::string& file_name,
-                  const std::string& format) final {
-    LOG(FATAL) << "RPCModule: SaveToFile not supported";
-  }
-
-  void SaveToBinary(dmlc::Stream* stream) final {
-    LOG(FATAL) << "RPCModule: SaveToBinary not supported";
-  }
-
   std::string GetSource(const std::string& format) final {
     if (module_handle_ != nullptr) {
       std::string ret =  sess_->CallRemote(