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 c9a3c2f442 [CMAKE] Upgrade TVM build baseline to C++20 (#19734)
c9a3c2f442 is described below

commit c9a3c2f442e219e989b5c7377cd2d05adcf140ee
Author: Yixin Dong <[email protected]>
AuthorDate: Mon Jun 15 07:53:17 2026 -0400

    [CMAKE] Upgrade TVM build baseline to C++20 (#19734)
    
    ## Summary
    
    This PR upgrades TVM's core CMake build baseline from C++17 to C++20.
    
    It updates the top-level CMake C++/CUDA standards and the LLVM compile
    probe fallback flags. Downstream app, JVM, web, Python helper, and
    vendored third-party build surfaces are intentionally left unchanged so
    they can migrate separately.
    
    ## Verification
    
    - Configured a minimal local build with GCC 13.3 and NVCC 13.2:
    `cmake -S . -B build/cxx20-check -GNinja -DBUILD_TESTING=OFF
    -DUSE_LLVM=OFF -DUSE_CUDA=OFF -DTVM_BUILD_PYTHON_MODULE=OFF`
---
 CMakeLists.txt                                        |  4 ++--
 cmake/utils/FindLLVM.cmake                            |  4 ++--
 docs/install/from_source.rst                          | 14 +++++++++-----
 include/tvm/tirx/op.h                                 |  3 ++-
 src/relax/transform/run_codegen.cc                    |  2 +-
 src/runtime/extra/contrib/cudnn/cudnn_json_runtime.cc |  4 ++--
 src/runtime/extra/disco/protocol.h                    |  4 +++-
 src/runtime/rpc/rpc_endpoint.cc                       |  4 +++-
 src/s_tir/transform/compact_buffer_region.cc          |  2 ++
 src/s_tir/transform/inject_software_pipeline.cc       |  2 +-
 src/target/llvm/codegen_params.cc                     |  3 ++-
 11 files changed, 29 insertions(+), 17 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index f1bd57b215..99a2569b14 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -440,9 +440,9 @@ include(cmake/utils/CCache.cmake)
 
 include(CheckCXXCompilerFlag)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
-set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD 20)
 set(CMAKE_CUDA_STANDARD_REQUIRED ON)
-set(CMAKE_CUDA_STANDARD 17)
+set(CMAKE_CUDA_STANDARD 20)
 
 # Module rules
 include(cmake/modules/CUDA.cmake)
diff --git a/cmake/utils/FindLLVM.cmake b/cmake/utils/FindLLVM.cmake
index 2bf229eca7..1f54ded1d5 100644
--- a/cmake/utils/FindLLVM.cmake
+++ b/cmake/utils/FindLLVM.cmake
@@ -254,9 +254,9 @@ macro(find_llvm use_llvm)
     # compiler-appropriate form so the probe works under MSVC as well.
     if(NOT CMAKE_CXX_STANDARD)
       if(MSVC)
-        set(CMAKE_REQUIRED_FLAGS "/std:c++17")
+        set(CMAKE_REQUIRED_FLAGS "/std:c++20")
       else()
-        set(CMAKE_REQUIRED_FLAGS "-std=c++17")
+        set(CMAKE_REQUIRED_FLAGS "-std=c++20")
       endif()
     endif()
     check_cxx_source_compiles("
diff --git a/docs/install/from_source.rst b/docs/install/from_source.rst
index 65e4f87e9e..1234c7c006 100644
--- a/docs/install/from_source.rst
+++ b/docs/install/from_source.rst
@@ -35,11 +35,15 @@ Apache TVM requires the following dependencies:
 - CMake (>= 3.24.0)
 - LLVM (recommended >= 15)
 - Git
-- A recent C++ compiler supporting C++ 17, at the minimum
-    - GCC 7.1
-    - Clang 5.0
-    - Apple Clang 9.3
-    - Visual Studio 2019 (v16.7)
+- A recent C++ compiler supporting C++ 20, at the minimum
+    - GCC 10
+    - Clang 10
+    - Apple Clang 14
+    - Visual Studio 2022
+
+  Optional dependencies that use newer C++20 standard library facilities, such
+  as ``std::format``, may require a newer standard library (for example GCC 13
+  or newer on Linux).
 - Python (>= 3.10)
 - (Optional) Conda (Strongly Recommended)
 
diff --git a/include/tvm/tirx/op.h b/include/tvm/tirx/op.h
index 7a7584aff2..a92ca7dc52 100644
--- a/include/tvm/tirx/op.h
+++ b/include/tvm/tirx/op.h
@@ -823,7 +823,8 @@ inline bool IsPointerType(const Type& type, const DataType& 
element_type) {
  * \param span The location of this operation in the source.
  */
 template <typename ValueType,
-          typename = typename 
std::enable_if<std::is_pod<ValueType>::value>::type>
+          typename = typename 
std::enable_if<std::is_standard_layout<ValueType>::value &&
+                                             
std::is_trivial<ValueType>::value>::type>
 inline PrimExpr make_const(DataType t, ValueType value, Span span = Span());
 /*!
  * \brief Make a const zero expr.
diff --git a/src/relax/transform/run_codegen.cc 
b/src/relax/transform/run_codegen.cc
index bc99196169..efd90d6696 100644
--- a/src/relax/transform/run_codegen.cc
+++ b/src/relax/transform/run_codegen.cc
@@ -155,7 +155,7 @@ class CodeGenRunner : ExprMutator {
     if (opt_codegen) {
       auto ext_symbol = GetExtSymbol(func);
       size_t count = 0;
-      PostOrderVisit(func->body, [=, &count](Expr e) {
+      PostOrderVisit(func->body, [=, this, &count](Expr e) {
         if (e->IsInstance<ConstantNode>()) {
           // Make sure to pick a unique name
           auto name = ext_symbol + "_" + opt_codegen.value() + "_const_" + 
std::to_string(count++);
diff --git a/src/runtime/extra/contrib/cudnn/cudnn_json_runtime.cc 
b/src/runtime/extra/contrib/cudnn/cudnn_json_runtime.cc
index df38f960d2..a7cf1ec2b3 100644
--- a/src/runtime/extra/contrib/cudnn/cudnn_json_runtime.cc
+++ b/src/runtime/extra/contrib/cudnn/cudnn_json_runtime.cc
@@ -162,7 +162,7 @@ class cuDNNJSONRuntime : public JSONRuntimeBase {
                            conv_dtype, false, &best_algo);
 
     int algo = best_algo.cast<int>();
-    std::function<void()> op_exec = [=]() {
+    std::function<void()> op_exec = [=, this]() {
       int device_id;
       CUDA_CALL(cudaGetDevice(&device_id));
       cudaStream_t stream = 
static_cast<cudaStream_t>(TVMFFIEnvGetStream(kDLCUDA, device_id));
@@ -223,7 +223,7 @@ class cuDNNJSONRuntime : public JSONRuntimeBase {
     auto runner = tvm::contrib::CuDNNSDPARunner::Create();
     runner->Init(batch, seq_len, num_heads, num_kv_heads, head_size, 
head_size_v, scale, dtype,
                  layout);
-    return [=]() {
+    return [=, this]() {
       auto qkv = GetInput(node, 0);
       auto workspace = const_cast<DLTensor*>(GetInput(node, 1));
       auto out = const_cast<DLTensor*>(data_entry_[EntryID(outputs_[0])]);
diff --git a/src/runtime/extra/disco/protocol.h 
b/src/runtime/extra/disco/protocol.h
index 25662051dc..a26b3060bc 100644
--- a/src/runtime/extra/disco/protocol.h
+++ b/src/runtime/extra/disco/protocol.h
@@ -28,6 +28,7 @@
 
 #include <memory>
 #include <string>
+#include <type_traits>
 #include <utility>
 #include <vector>
 
@@ -78,7 +79,8 @@ struct DiscoProtocol {
   /*!\ brief Arena used by RPCReference to allocate POD memory */
   template <typename T>
   T* ArenaAlloc(int count) {
-    static_assert(std::is_pod<T>::value, "need to be trival");
+    static_assert(std::is_standard_layout<T>::value && 
std::is_trivial<T>::value,
+                  "need to be trivial");
     return arena_.template allocate_<T>(count);
   }
 
diff --git a/src/runtime/rpc/rpc_endpoint.cc b/src/runtime/rpc/rpc_endpoint.cc
index a6950117d6..0402430251 100644
--- a/src/runtime/rpc/rpc_endpoint.cc
+++ b/src/runtime/rpc/rpc_endpoint.cc
@@ -34,6 +34,7 @@
 #include <cmath>
 #include <memory>
 #include <string>
+#include <type_traits>
 #include <utility>
 #include <vector>
 
@@ -312,7 +313,8 @@ class RPCEndpoint::EventHandler : public support::Stream {
 
   template <typename T>
   T* ArenaAlloc(int count) {
-    static_assert(std::is_pod<T>::value, "need to be trival");
+    static_assert(std::is_standard_layout<T>::value && 
std::is_trivial<T>::value,
+                  "need to be trivial");
     return arena_.template allocate_<T>(count);
   }
 
diff --git a/src/s_tir/transform/compact_buffer_region.cc 
b/src/s_tir/transform/compact_buffer_region.cc
index d02e907016..640a18d594 100644
--- a/src/s_tir/transform/compact_buffer_region.cc
+++ b/src/s_tir/transform/compact_buffer_region.cc
@@ -129,6 +129,8 @@ class BufferAccessRegionCollector : public StmtExprVisitor {
   }
 
  private:
+  using StmtExprVisitor::VisitBufferDef;
+
   struct BufferAccessInfo {
     /*! \brief The buffer. */
     Buffer buffer;
diff --git a/src/s_tir/transform/inject_software_pipeline.cc 
b/src/s_tir/transform/inject_software_pipeline.cc
index 8064f7b164..6a486ca768 100644
--- a/src/s_tir/transform/inject_software_pipeline.cc
+++ b/src/s_tir/transform/inject_software_pipeline.cc
@@ -708,7 +708,7 @@ class PipelineRewriter : public StmtExprMutator {
         }
       }
 
-      auto wait_count = [=, &ana_normalized]() {
+      auto wait_count = [=, this, &ana_normalized]() {
         auto sum = PrimExpr(0);
         for (auto producer_head : producer_head_per_commit) {
           if (producer_head && ana_normalized->CanProve(producer_head.value() 
>= 0)) {
diff --git a/src/target/llvm/codegen_params.cc 
b/src/target/llvm/codegen_params.cc
index fccc92a228..6d8684a87e 100644
--- a/src/target/llvm/codegen_params.cc
+++ b/src/target/llvm/codegen_params.cc
@@ -61,7 +61,8 @@ struct LLVMConstantGetter<T, 
std::enable_if_t<std::is_floating_point<T>::value>>
   static llvm::Constant* getElement(llvm::Type* ty, T t) { return 
llvm::ConstantFP::get(ty, t); }
 };
 
-template <typename T, typename = std::enable_if<std::is_pod<T>::value>>
+template <typename T,
+          typename = std::enable_if_t<std::is_standard_layout<T>::value && 
std::is_trivial<T>::value>>
 void BuildLLVMVector(llvm::Type* element_type, void* tensor_data, size_t 
num_elements,
                      std::vector<llvm::Constant*>* elements) {
   elements->resize(num_elements, nullptr);

Reply via email to