gemini-code-assist[bot] commented on code in PR #660:
URL: https://github.com/apache/tvm-ffi/pull/660#discussion_r3561641313


##########
addons/tvm_ffi_orcjit/src/ffi/orcjit_session.cc:
##########
@@ -71,7 +71,48 @@ struct LLVMInitializer {
 
 static LLVMInitializer llvm_initializer;
 
-ORCJITExecutionSessionObj::ORCJITExecutionSessionObj(const std::string& 
orc_rt_path,
+#ifdef TVM_FFI_ORCJIT_EMBED_ORC_RT
+// liborc_rt.a embedded in .rodata by orc_rt_embed.S.in. C linkage binds to the
+// assembler symbols; the linkage spec must be at namespace scope, not in-fn.
+extern "C" const char orc_rt_archive_start[];
+extern "C" const char orc_rt_archive_end[];
+#endif
+
+namespace {
+#ifdef TVM_FFI_ORCJIT_EMBED_ORC_RT
+// Zero-copy view of the embedded archive; its bytes live for the image 
lifetime.
+std::unique_ptr<llvm::MemoryBuffer> GetEmbeddedOrcRuntimeBuffer() {
+  return llvm::MemoryBuffer::getMemBuffer(
+      llvm::StringRef(orc_rt_archive_start,
+                      static_cast<size_t>(orc_rt_archive_end - 
orc_rt_archive_start)),
+      "liborc_rt.a", /*RequiresNullTerminator=*/false);
+}
+#endif
+
+// Install ExecutorNativePlatform per the `orc_rt` selector (see the ctor doc).
+// Linux/ELF only: the sole caller is under `#ifndef __APPLE__`.
+void SetUpOrcPlatform(llvm::orc::LLJITBuilder& builder,
+                      const Optional<Variant<String, Bytes>>& orc_rt) {
+  if (!orc_rt.has_value()) return;  // None -> no platform
+  const Variant<String, Bytes>& sel = orc_rt.value();
+  if (auto opt_path = sel.as<String>()) {
+    const String& path = *opt_path;
+    if (path.empty()) {  // "auto" -> embedded (or nothing if compiled out)
+#ifdef TVM_FFI_ORCJIT_EMBED_ORC_RT
+      
builder.setPlatformSetUp(llvm::orc::ExecutorNativePlatform(GetEmbeddedOrcRuntimeBuffer()));
+#endif
+    } else {
+      builder.setPlatformSetUp(llvm::orc::ExecutorNativePlatform(path.operator 
std::string()));
+    }
+  } else {  // Bytes: ExecutorNativePlatform takes ownership of the copy.
+    const Bytes& bytes = sel.get<Bytes>();
+    
builder.setPlatformSetUp(llvm::orc::ExecutorNativePlatform(llvm::MemoryBuffer::getMemBufferCopy(
+        llvm::StringRef(bytes.data(), bytes.size()), "liborc_rt.a")));
+  }
+}

Review Comment:
   ![high](https://www.gstatic.com/codereviewagent/high-priority.svg)
   
   The `SetUpOrcPlatform` function is called on Windows because the caller uses 
`#ifndef __APPLE__` (which is true on Windows). However, Windows does not 
support the ORC platform in this codebase (COFFPlatform is not hooked up, and 
`liborc_rt` is unused). If a user passes a custom path or bytes on Windows, 
`SetUpOrcPlatform` will attempt to set up `ExecutorNativePlatform`, which 
violates the documented behavior that Windows ignores the selector and can 
cause runtime errors.
   
   We should make `SetUpOrcPlatform` a no-op on Windows (and macOS) to ensure 
the selector is correctly ignored as documented.
   
   ```c
   void SetUpOrcPlatform(llvm::orc::LLJITBuilder& builder,
                         const Optional<Variant<String, Bytes>>& orc_rt) {
   #if defined(__APPLE__) || defined(_WIN32)
     (void)builder;
     (void)orc_rt;
   #else
     if (!orc_rt.has_value()) return;  // None -> no platform
     const Variant<String, Bytes>& sel = orc_rt.value();
     if (auto opt_path = sel.as<String>()) {
       const String& path = *opt_path;
       if (path.empty()) {  // "auto" -> embedded (or nothing if compiled out)
   #ifdef TVM_FFI_ORCJIT_EMBED_ORC_RT
         
builder.setPlatformSetUp(llvm::orc::ExecutorNativePlatform(GetEmbeddedOrcRuntimeBuffer()));
   #endif
       } else {
         
builder.setPlatformSetUp(llvm::orc::ExecutorNativePlatform(path.operator 
std::string()));
       }
     } else {  // Bytes: ExecutorNativePlatform takes ownership of the copy.
       const Bytes& bytes = sel.get<Bytes>();
       
builder.setPlatformSetUp(llvm::orc::ExecutorNativePlatform(llvm::MemoryBuffer::getMemBufferCopy(
           llvm::StringRef(bytes.data(), bytes.size()), "liborc_rt.a")));
     }
   #endif
   }
   ```



##########
addons/tvm_ffi_orcjit/src/ffi/orcjit_session.cc:
##########
@@ -71,7 +71,48 @@ struct LLVMInitializer {
 
 static LLVMInitializer llvm_initializer;
 
-ORCJITExecutionSessionObj::ORCJITExecutionSessionObj(const std::string& 
orc_rt_path,
+#ifdef TVM_FFI_ORCJIT_EMBED_ORC_RT
+// liborc_rt.a embedded in .rodata by orc_rt_embed.S.in. C linkage binds to the
+// assembler symbols; the linkage spec must be at namespace scope, not in-fn.
+extern "C" const char orc_rt_archive_start[];
+extern "C" const char orc_rt_archive_end[];
+#endif
+
+namespace {
+#ifdef TVM_FFI_ORCJIT_EMBED_ORC_RT
+// Zero-copy view of the embedded archive; its bytes live for the image 
lifetime.
+std::unique_ptr<llvm::MemoryBuffer> GetEmbeddedOrcRuntimeBuffer() {
+  return llvm::MemoryBuffer::getMemBuffer(
+      llvm::StringRef(orc_rt_archive_start,
+                      static_cast<size_t>(orc_rt_archive_end - 
orc_rt_archive_start)),
+      "liborc_rt.a", /*RequiresNullTerminator=*/false);
+}

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   Subtracting two unrelated pointers (pointers that do not point to elements 
of the same array object) is undefined behavior in C++. Since 
`orc_rt_archive_start` and `orc_rt_archive_end` are distinct extern symbols, 
subtracting them directly can be optimized unexpectedly by compilers. Casting 
them to `std::uintptr_t` before subtraction avoids this undefined behavior.
   
   ```suggestion
   std::unique_ptr<llvm::MemoryBuffer> GetEmbeddedOrcRuntimeBuffer() {
     return llvm::MemoryBuffer::getMemBuffer(
         llvm::StringRef(orc_rt_archive_start,
                         reinterpret_cast<std::uintptr_t>(orc_rt_archive_end) -
                             
reinterpret_cast<std::uintptr_t>(orc_rt_archive_start)),
         "liborc_rt.a", /*RequiresNullTerminator=*/false);
   }
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to