Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
79849c3
pipes for redirection in oop jit
Jul 1, 2025
825f005
Merge branch 'main' into redirection
kr-2003 Jul 29, 2025
52b0902
refactoring
Jul 29, 2025
3b4fcad
refactoring
Jul 29, 2025
e174e98
commenting & refactoring
Jul 29, 2025
b744a9f
compiler-rt conditional addition
Aug 1, 2025
0c6c995
Merge branch 'main' into redirection
kr-2003 Aug 1, 2025
2cf71ed
removed compiler-rt dep
Aug 1, 2025
7c29008
Merge branch 'redirection' of https://github.com/kr-2003/llvm-project…
Aug 1, 2025
41f8e54
separate file for oop tests
Aug 1, 2025
4f1d203
separate file for oop tests
Aug 1, 2025
a6a4369
separate file for oop tests
Aug 1, 2025
63de886
test file rename
Aug 1, 2025
c24e84e
test file rename
Aug 1, 2025
b114bb8
test file rename
Aug 1, 2025
850b953
resolving comments & InterpreterRemoteTest
Aug 3, 2025
956f393
resolving comments
Aug 3, 2025
14e5afd
resolving comments
Aug 4, 2025
65afbff
Custom lambda in launchExecutor and pid retrieval
Aug 5, 2025
7dc6590
Merge branch 'main' of https://github.com/llvm/llvm-project into redi…
Aug 20, 2025
095a63b
Dynamic path resolution
Aug 24, 2025
2b6dc6c
Dynamic path resolution using IncrementalCB
Aug 25, 2025
7ad10a6
Dynamic path resolution using IncrementalCB
Aug 25, 2025
6a58d5f
Addressing reviews
Aug 26, 2025
f1b9135
Sinking JitBuilder into Interpreter
Aug 27, 2025
dd73052
RemoteJITUtils shifted to IncrementalExecutor
Aug 31, 2025
e90df55
RemoteJITUtils shifted to IncrementalExecutor
Aug 31, 2025
521be31
Removed custom fork in launchExecutor lambda
Aug 31, 2025
baaff1e
Merge branch 'main' into redirection
kr-2003 Aug 31, 2025
44cde65
refactoring changes
Aug 31, 2025
fc1f0da
Merge branch 'redirection' of https://github.com/kr-2003/llvm-project…
Aug 31, 2025
c49ec55
Refactoring
Aug 31, 2025
a6a05ea
Deleted RemoteJITUtils.h & .cpp
Aug 31, 2025
f2ca64e
Refactoring
Aug 31, 2025
0c99b67
Refactoring
Aug 31, 2025
51d6657
Refactoring
Aug 31, 2025
a71c546
formatting
Aug 31, 2025
37a9f3d
formatting
Aug 31, 2025
2cdb210
Addressing reviews
Sep 5, 2025
129a62b
Addressing reviews
Sep 5, 2025
c856255
Addressing reviews
Sep 5, 2025
3a15ddf
Fix connectTCPSocket on non-unix
Sep 6, 2025
54a0dba
Fixing ambiguity and resolving comments
Sep 7, 2025
98c59b4
Fixing ambiguity and resolving comments
Sep 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions clang/include/clang/Interpreter/Interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ class IncrementalCompilerBuilder {
void SetTargetTriple(std::string TT) { TargetTriple = TT; }

// General C++
llvm::Expected<std::unique_ptr<CompilerInstance>> CreateCpp();
llvm::Expected<std::unique_ptr<CompilerInstance>>
CreateCpp(std::string *OrcRuntimePath = nullptr);

// Offload options
void SetOffloadArch(llvm::StringRef Arch) { OffloadArch = Arch; };
Expand All @@ -69,7 +70,8 @@ class IncrementalCompilerBuilder {

private:
static llvm::Expected<std::unique_ptr<CompilerInstance>>
create(std::string TT, std::vector<const char *> &ClangArgv);
create(std::string TT, std::vector<const char *> &ClangArgv,
std::string *OrcRuntimePath = nullptr);

llvm::Expected<std::unique_ptr<CompilerInstance>> createCuda(bool device);

Expand Down
12 changes: 11 additions & 1 deletion clang/include/clang/Interpreter/RemoteJITUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@

llvm::Expected<std::unique_ptr<llvm::orc::SimpleRemoteEPC>>
launchExecutor(llvm::StringRef ExecutablePath, bool UseSharedMemory,
llvm::StringRef SlabAllocateSizeString);
llvm::StringRef SlabAllocateSizeString,
std::function<void()> CustomizeFork = nullptr);

/// Create a JITLinkExecutor that connects to the given network address
/// through a TCP socket. A valid NetworkAddress provides hostname and port,
Expand All @@ -35,4 +36,13 @@ llvm::Expected<std::unique_ptr<llvm::orc::SimpleRemoteEPC>>
connectTCPSocket(llvm::StringRef NetworkAddress, bool UseSharedMemory,
llvm::StringRef SlabAllocateSizeString);

#ifdef LLVM_ON_UNIX
/// Returns PID of last launched executor.
pid_t getLastLaunchedExecutorPID();

/// Returns PID of nth launched executor.
/// 1-based indexing.
pid_t getNthLaunchedExecutorPID(int n);
#endif

#endif // LLVM_CLANG_INTERPRETER_REMOTEJITUTILS_H
19 changes: 16 additions & 3 deletions clang/lib/Interpreter/Interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ namespace clang {

llvm::Expected<std::unique_ptr<CompilerInstance>>
IncrementalCompilerBuilder::create(std::string TT,
std::vector<const char *> &ClangArgv) {
std::vector<const char *> &ClangArgv,
std::string *OrcRuntimePath) {

// If we don't know ClangArgv0 or the address of main() at this point, try
// to guess it anyway (it's possible on some platforms).
Expand Down Expand Up @@ -190,11 +191,23 @@ IncrementalCompilerBuilder::create(std::string TT,
if (auto Err = ErrOrCC1Args.takeError())
return std::move(Err);

const driver::ToolChain &TC = Compilation->getDefaultToolChain();
std::optional<std::string> Path = TC.getCompilerRTPath();
if (Path && OrcRuntimePath) {
*OrcRuntimePath = *Path;
if(llvm::sys::fs::exists(*OrcRuntimePath + "/liborc_rt.a"))
*OrcRuntimePath = *OrcRuntimePath + "/liborc_rt.a";
else if (llvm::sys::fs::exists(*OrcRuntimePath + "/liborc_rt_osx.a"))
*OrcRuntimePath = *OrcRuntimePath + "/liborc_rt_osx.a";
else if (llvm::sys::fs::exists(*OrcRuntimePath + "/liborc_rt-x86_64.a"))
*OrcRuntimePath = *OrcRuntimePath + "/liborc_rt-x86_64.a";
}

return CreateCI(**ErrOrCC1Args);
}

llvm::Expected<std::unique_ptr<CompilerInstance>>
IncrementalCompilerBuilder::CreateCpp() {
IncrementalCompilerBuilder::CreateCpp(std::string *OrcRuntimePath) {
std::vector<const char *> Argv;
Argv.reserve(5 + 1 + UserArgs.size());
Argv.push_back("-xc++");
Expand All @@ -206,7 +219,7 @@ IncrementalCompilerBuilder::CreateCpp() {
llvm::append_range(Argv, UserArgs);

std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple();
return IncrementalCompilerBuilder::create(TT, Argv);
return IncrementalCompilerBuilder::create(TT, Argv, OrcRuntimePath);
}

llvm::Expected<std::unique_ptr<CompilerInstance>>
Expand Down
31 changes: 30 additions & 1 deletion clang/lib/Interpreter/RemoteJITUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
using namespace llvm;
using namespace llvm::orc;

#if LLVM_ON_UNIX
static std::vector<pid_t> LaunchedExecutorPID;
#endif

Expected<uint64_t> getSlabAllocSize(StringRef SizeString) {
SizeString = SizeString.trim();

Expand Down Expand Up @@ -89,9 +93,14 @@ createSharedMemoryManager(SimpleRemoteEPC &SREPC,
SlabSize, SREPC, SAs);
}

// Launches an out-of-process executor for remote JIT. The calling program can
// provide a CustomizeFork callback, which allows it to run custom code in the
// child process before exec. This enables sending custom setup or code to be
// executed in the child (out-of-process) executor.
Expected<std::unique_ptr<SimpleRemoteEPC>>
launchExecutor(StringRef ExecutablePath, bool UseSharedMemory,
llvm::StringRef SlabAllocateSizeString) {
llvm::StringRef SlabAllocateSizeString,
std::function<void()> CustomizeFork) {
#ifndef LLVM_ON_UNIX
// FIXME: Add support for Windows.
return make_error<StringError>("-" + ExecutablePath +
Expand Down Expand Up @@ -134,6 +143,9 @@ launchExecutor(StringRef ExecutablePath, bool UseSharedMemory,
close(ToExecutor[WriteEnd]);
close(FromExecutor[ReadEnd]);

if (CustomizeFork)
CustomizeFork();

// Execute the child process.
std::unique_ptr<char[]> ExecutorPath, FDSpecifier;
{
Expand All @@ -158,6 +170,8 @@ launchExecutor(StringRef ExecutablePath, bool UseSharedMemory,
}
// else we're the parent...

LaunchedExecutorPID.push_back(ChildPID);

// Close the child ends of the pipes
close(ToExecutor[ReadEnd]);
close(FromExecutor[WriteEnd]);
Expand Down Expand Up @@ -265,3 +279,18 @@ connectTCPSocket(StringRef NetworkAddress, bool UseSharedMemory,
std::move(S), *SockFD, *SockFD);
#endif
}

#if LLVM_ON_UNIX

pid_t getLastLaunchedExecutorPID() {
if (!LaunchedExecutorPID.size())
return -1;
return LaunchedExecutorPID.back();
}

pid_t getNthLaunchedExecutorPID(int n) {
if (n - 1 < 0 || n - 1 >= static_cast<int>(LaunchedExecutorPID.size()))
return -1;
return LaunchedExecutorPID.at(n - 1);
}
#endif
59 changes: 31 additions & 28 deletions clang/tools/clang-repl/ClangRepl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,25 @@
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/LineEditor/LineEditor.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h" // llvm_shutdown
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Host.h"
#include "llvm/TargetParser/Triple.h"
#include <optional>

#include <iostream>
#include <string>
#include <vector>

#include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h"

using namespace clang;

// Disable LSan for this test.
// FIXME: Re-enable once we can assume GCC 13.2 or higher.
// https://llvm.org/github.com/llvm/llvm-project/issues/67586.
Expand Down Expand Up @@ -81,7 +91,8 @@ static llvm::cl::opt<bool> OptHostSupportsJit("host-supports-jit",
static llvm::cl::list<std::string> OptInputs(llvm::cl::Positional,
llvm::cl::desc("[code to run]"));

static llvm::Error sanitizeOopArguments(const char *ArgV0) {
static llvm::Error sanitizeOopArguments(const char *ArgV0,
std::string _OrcRuntimePath) {
// Only one of -oop-executor and -oop-executor-connect can be used.
if (!!OOPExecutor.getNumOccurrences() &&
!!OOPExecutorConnect.getNumOccurrences())
Expand Down Expand Up @@ -117,21 +128,11 @@ static llvm::Error sanitizeOopArguments(const char *ArgV0) {
// Out-of-process executors require the ORC runtime.
if (OrcRuntimePath.empty() && (OOPExecutor.getNumOccurrences() ||
OOPExecutorConnect.getNumOccurrences())) {
llvm::SmallString<256> BasePath(llvm::sys::fs::getMainExecutable(
ArgV0, reinterpret_cast<void *>(&sanitizeOopArguments)));
llvm::sys::path::remove_filename(BasePath); // Remove clang-repl filename.
llvm::sys::path::remove_filename(BasePath); // Remove ./bin directory.
llvm::sys::path::append(BasePath, CLANG_INSTALL_LIBDIR_BASENAME, "clang",
CLANG_VERSION_MAJOR_STRING);
if (SystemTriple.isOSBinFormatELF())
OrcRuntimePath =
BasePath.str().str() + "/lib/x86_64-unknown-linux-gnu/liborc_rt.a";
else if (SystemTriple.isOSBinFormatMachO())
OrcRuntimePath = BasePath.str().str() + "/lib/darwin/liborc_rt_osx.a";
else
if(!llvm::sys::fs::exists(_OrcRuntimePath))
return llvm::make_error<llvm::StringError>(
"Out-of-process execution is not supported on non-unix platforms",
"The ORC runtime is required for out-of-process execution",
llvm::inconvertibleErrorCode());
OrcRuntimePath = _OrcRuntimePath;
}

// If -oop-executor was used but no value was specified then use a sensible
Expand Down Expand Up @@ -186,7 +187,7 @@ struct ReplListCompleter {
clang::Interpreter &MainInterp;
ReplListCompleter(clang::IncrementalCompilerBuilder &CB,
clang::Interpreter &Interp)
: CB(CB), MainInterp(Interp){};
: CB(CB), MainInterp(Interp) {};

std::vector<llvm::LineEditor::Completion> operator()(llvm::StringRef Buffer,
size_t Pos) const;
Expand Down Expand Up @@ -275,15 +276,26 @@ int main(int argc, const char **argv) {
if (!CudaPath.empty())
CB.SetCudaSDK(CudaPath);

if (OffloadArch.empty()) {
OffloadArch = "sm_35";
if (::OffloadArch.empty()) {
::OffloadArch = "sm_35";
}
CB.SetOffloadArch(OffloadArch);
CB.SetOffloadArch(::OffloadArch);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these changes relevant to the current PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes. if not done, it gives following error:

error: reference to 'OffloadArch' is ambiguous

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which compiler is this? Why it works upstream?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ping.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(base) llvm-project-test % clang --version       
Homebrew clang version 20.1.6
Target: arm64-apple-darwin24.5.0
Thread model: posix
InstalledDir: /opt/homebrew/Cellar/llvm/20.1.6/bin
Configuration file: /opt/homebrew/etc/clang/arm64-apple-darwin24.cfg'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what's the problem but if that does not fail upstream please remove it. What are the other declarations that make OffloadArch ambiguous?


DeviceCI = ExitOnErr(CB.CreateCudaDevice());
}

ExitOnErr(sanitizeOopArguments(argv[0]));
std::string _OrcRuntimePath;

// FIXME: Investigate if we could use runToolOnCodeWithArgs from tooling. It
// can replace the boilerplate code for creation of the compiler instance.
std::unique_ptr<clang::CompilerInstance> CI;
if (CudaEnabled) {
CI = ExitOnErr(CB.CreateCudaHost());
} else {
CI = ExitOnErr(CB.CreateCpp(&_OrcRuntimePath));
}

ExitOnErr(sanitizeOopArguments(argv[0], _OrcRuntimePath));

std::unique_ptr<llvm::orc::ExecutorProcessControl> EPC;
if (OOPExecutor.getNumOccurrences()) {
Expand All @@ -302,15 +314,6 @@ int main(int argc, const char **argv) {
clang::Interpreter::createLLJITBuilder(std::move(EPC), OrcRuntimePath));
}

// FIXME: Investigate if we could use runToolOnCodeWithArgs from tooling. It
// can replace the boilerplate code for creation of the compiler instance.
std::unique_ptr<clang::CompilerInstance> CI;
if (CudaEnabled) {
CI = ExitOnErr(CB.CreateCudaHost());
} else {
CI = ExitOnErr(CB.CreateCpp());
}

// Set an error handler, so that any LLVM backend diagnostics go through our
// error handler.
llvm::install_fatal_error_handler(LLVMErrorHandler,
Expand Down
30 changes: 29 additions & 1 deletion clang/unittests/Interpreter/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,25 @@ set(CLANG_LIBS_TO_LINK
)
endif()

add_distinct_clang_unittest(ClangReplInterpreterTests
set(CLANG_REPL_TEST_SOURCES
IncrementalCompilerBuilderTest.cpp
IncrementalProcessingTest.cpp
InterpreterTest.cpp
InterpreterExtensionsTest.cpp
CodeCompletionTest.cpp
)

if(TARGET compiler-rt)
list(APPEND CLANG_REPL_TEST_SOURCES
OutOfProcessInterpreterTests.cpp
)
message(STATUS "Compiler-RT found, enabling out of process JIT tests")
endif()

add_distinct_clang_unittest(ClangReplInterpreterTests
${CLANG_REPL_TEST_SOURCES}

PARTIAL_SOURCES_INTENDED
EXPORT_SYMBOLS

CLANG_LIBS
Expand All @@ -48,6 +60,14 @@ add_distinct_clang_unittest(ClangReplInterpreterTests
${LLVM_COMPONENTS_TO_LINK}
)

if(TARGET compiler-rt)
add_dependencies(ClangReplInterpreterTests
llvm-jitlink-executor
compiler-rt
)
message(STATUS "Adding dependency on compiler-rt for out of process JIT tests")
endif()

if(EMSCRIPTEN)
# Without the above you try to link to LLVMSupport twice, and end
# up with a duplicate symbol error when creating the main module
Expand All @@ -71,6 +91,14 @@ set_target_properties(ClangReplInterpreterTests PROPERTIES
)
endif()

if(TARGET compiler-rt)
add_dependencies(ClangReplInterpreterTests
llvm-jitlink-executor
compiler-rt
)
message(STATUS "Adding dependency on compiler-rt for out of process JIT tests")
endif()

# Exceptions on Windows are not yet supported.
if(NOT WIN32)
add_subdirectory(ExceptionTests)
Expand Down
11 changes: 11 additions & 0 deletions clang/unittests/Interpreter/InterpreterTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,17 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclGroup.h"
#include "clang/AST/Mangle.h"
#include "clang/Basic/Version.h"
#include "clang/Config/config.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Interpreter/Interpreter.h"
#include "clang/Interpreter/RemoteJITUtils.h"
#include "clang/Interpreter/Value.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Sema.h"
#include "llvm/Support/Error.h"
#include "llvm/TargetParser/Host.h"

#include "llvm/TargetParser/Host.h"

Expand All @@ -34,6 +39,12 @@ int Global = 42;
REPL_EXTERNAL_VISIBILITY int getGlobal() { return Global; }
REPL_EXTERNAL_VISIBILITY void setGlobal(int val) { Global = val; }

#ifdef _WIN32
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#endif

namespace {

class InterpreterTest : public InterpreterTestBase {
Expand Down
Loading
Loading