llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Anutosh Bhat (anutosh491) <details> <summary>Changes</summary> Fixes https://github.com/llvm/llvm-project/issues/166120 I could think of two approaches here 1) As per the comment https://github.com/llvm/llvm-project/issues/166120#issuecomment-3479552518 : Saying we could flush after each input line. Yes this would make sense and work too Here's an **unpolished diff** where 1) Flush after every input is parsed (through an IsFlushed var that is toggled for each input) 2) Once the flush is performed, we don't care about storing it in the list of PTUs or tracking it so we hit undo. ``` diff --git a/clang/include/clang/Interpreter/Interpreter.h b/clang/include/clang/Interpreter/Interpreter.h index 078d70b3b174..d07992a4ad02 100644 --- a/clang/include/clang/Interpreter/Interpreter.h +++ b/clang/include/clang/Interpreter/Interpreter.h @@ -234,6 +234,9 @@ private: // This function forces emission of the needed dtor. llvm::Expected<llvm::orc::ExecutorAddr> CompileDtorCall(CXXRecordDecl *CXXRD) const; + + bool IsOutOfProcess = false; + bool IsFlushing = false; }; } // namespace clang diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index a071d0312f76..9a178487dec7 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -347,6 +347,8 @@ const char *const Runtimes = R"( memcpy(Placement, Src, Size); } #endif // __cplusplus + #include <iostream> + #include <cstdio> EXTERN_C void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*); EXTERN_C void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...); )"; @@ -648,6 +650,7 @@ llvm::Error Interpreter::CreateExecutor(JITConfig Config) { bool IsWindowsTarget = TargetTriple.isOSWindows(); if (!IsWindowsTarget && Config.IsOutOfProcess) { + IsOutOfProcess = true; if (!JITBuilder) { auto ResOrErr = outOfProcessJITBuilder(Config); if (!ResOrErr) @@ -732,6 +735,25 @@ llvm::Error Interpreter::ParseAndExecute(llvm::StringRef Code, Value *V) { } else *V = std::move(LastValue); } + + if (IsOutOfProcess && !IsFlushing) { + IsFlushing = true; // prevent recursion + + static const char FlushSnippet[] = R"( + std::cout.flush(); + std::cerr.flush(); + std::fflush(stdout); + std::fflush(stderr); + )"; + + if (auto FlushErr = ParseAndExecute(FlushSnippet)) + consumeError(std::move(FlushErr)); + + if (auto E = Undo()) + consumeError(std::move(E)); + IsFlushing = false; + } + return llvm::Error::success(); } ``` Downsides of this approach is we end up parsing and executing the above block for each input and then undoing the execution too everytime. Which just looks heavy ! --- Full diff: https://github.com/llvm/llvm-project/pull/166368.diff 1 Files Affected: - (modified) clang/lib/Interpreter/Interpreter.cpp (+14) ``````````diff diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index cde354c9cd8d1..f3927fc341341 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -351,6 +351,15 @@ const char *const Runtimes = R"( EXTERN_C void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...); )"; +const char *const OOPRuntimes = R"( + #include <stdio.h> + __attribute__((constructor)) + static void __clang_repl_ioinit(void) { + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + } +)"; + llvm::Expected<std::pair<std::unique_ptr<llvm::orc::LLJITBuilder>, uint32_t>> Interpreter::outOfProcessJITBuilder(JITConfig Config) { std::unique_ptr<llvm::orc::ExecutorProcessControl> EPC; @@ -463,6 +472,11 @@ Interpreter::create(std::unique_ptr<CompilerInstance> CI, JITConfig Config) { if (auto E = Interp->ParseAndExecute(Runtimes)) return std::move(E); + if (Config.IsOutOfProcess) { + if (auto E = Interp->ParseAndExecute(OOPRuntimes)) + return std::move(E); + } + Interp->markUserCodeStart(); return std::move(Interp); `````````` </details> https://github.com/llvm/llvm-project/pull/166368 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
