1//===------ Interpreter.cpp - Incremental Compilation and Execution -------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the component which performs incremental code
10// compilation and execution.
11//
12//===----------------------------------------------------------------------===//
13
14#include "DeviceOffload.h"
15#include "IncrementalExecutor.h"
16#include "IncrementalParser.h"
17#include "InterpreterUtils.h"
18#include "llvm/Support/VirtualFileSystem.h"
19#ifdef __EMSCRIPTEN__
20#include "Wasm.h"
21#include <dlfcn.h>
22#endif // __EMSCRIPTEN__
23
24#include "clang/AST/ASTConsumer.h"
25#include "clang/AST/ASTContext.h"
26#include "clang/AST/Mangle.h"
27#include "clang/AST/TypeVisitor.h"
28#include "clang/Basic/DiagnosticSema.h"
29#include "clang/Basic/TargetInfo.h"
30#include "clang/CodeGen/CodeGenAction.h"
31#include "clang/CodeGen/ModuleBuilder.h"
32#include "clang/CodeGen/ObjectFilePCHContainerWriter.h"
33#include "clang/Driver/Compilation.h"
34#include "clang/Driver/Driver.h"
35#include "clang/Driver/Job.h"
36#include "clang/Driver/Options.h"
37#include "clang/Driver/Tool.h"
38#include "clang/Frontend/CompilerInstance.h"
39#include "clang/Frontend/FrontendAction.h"
40#include "clang/Frontend/MultiplexConsumer.h"
41#include "clang/Frontend/TextDiagnosticBuffer.h"
42#include "clang/FrontendTool/Utils.h"
43#include "clang/Interpreter/Interpreter.h"
44#include "clang/Interpreter/Value.h"
45#include "clang/Lex/PreprocessorOptions.h"
46#include "clang/Sema/Lookup.h"
47#include "clang/Serialization/ObjectFilePCHContainerReader.h"
48#include "llvm/ExecutionEngine/JITSymbol.h"
49#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
50#include "llvm/ExecutionEngine/Orc/LLJIT.h"
51#include "llvm/IR/Module.h"
52#include "llvm/Support/Errc.h"
53#include "llvm/Support/ErrorHandling.h"
54#include "llvm/Support/raw_ostream.h"
55#include "llvm/TargetParser/Host.h"
56#include "llvm/Transforms/Utils/Cloning.h" // for CloneModule
57
58#define DEBUG_TYPE "clang-repl"
59
60using namespace clang;
61// FIXME: Figure out how to unify with namespace init_convenience from
62// tools/clang-import-test/clang-import-test.cpp
63namespace {
64/// Retrieves the clang CC1 specific flags out of the compilation's jobs.
65/// \returns NULL on error.
66static llvm::Expected<const llvm::opt::ArgStringList *>
67GetCC1Arguments(DiagnosticsEngine *Diagnostics,
68 driver::Compilation *Compilation) {
69 // We expect to get back exactly one Command job, if we didn't something
70 // failed. Extract that job from the Compilation.
71 const driver::JobList &Jobs = Compilation->getJobs();
72 if (!Jobs.size() || !isa<driver::Command>(Val: *Jobs.begin()))
73 return llvm::createStringError(EC: llvm::errc::not_supported,
74 S: "Driver initialization failed. "
75 "Unable to create a driver job");
76
77 // The one job we find should be to invoke clang again.
78 const driver::Command *Cmd = cast<driver::Command>(Val: &(*Jobs.begin()));
79 if (llvm::StringRef(Cmd->getCreator().getName()) != "clang")
80 return llvm::createStringError(EC: llvm::errc::not_supported,
81 S: "Driver initialization failed");
82
83 return &Cmd->getArguments();
84}
85
86static llvm::Expected<std::unique_ptr<CompilerInstance>>
87CreateCI(const llvm::opt::ArgStringList &Argv) {
88 std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
89 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
90
91 // Register the support for object-file-wrapped Clang modules.
92 // FIXME: Clang should register these container operations automatically.
93 auto PCHOps = Clang->getPCHContainerOperations();
94 PCHOps->registerWriter(Writer: std::make_unique<ObjectFilePCHContainerWriter>());
95 PCHOps->registerReader(Reader: std::make_unique<ObjectFilePCHContainerReader>());
96
97 // Buffer diagnostics from argument parsing so that we can output them using
98 // a well formed diagnostic object.
99 DiagnosticOptions DiagOpts;
100 TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
101 DiagnosticsEngine Diags(DiagID, DiagOpts, DiagsBuffer);
102 bool Success = CompilerInvocation::CreateFromArgs(
103 Res&: Clang->getInvocation(), CommandLineArgs: llvm::ArrayRef(Argv.begin(), Argv.size()), Diags);
104
105 // Infer the builtin include path if unspecified.
106 if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
107 Clang->getHeaderSearchOpts().ResourceDir.empty())
108 Clang->getHeaderSearchOpts().ResourceDir =
109 CompilerInvocation::GetResourcesPath(Argv0: Argv[0], MainAddr: nullptr);
110
111 // Create the actual diagnostics engine.
112 Clang->createDiagnostics(VFS&: *llvm::vfs::getRealFileSystem());
113 if (!Clang->hasDiagnostics())
114 return llvm::createStringError(EC: llvm::errc::not_supported,
115 S: "Initialization failed. "
116 "Unable to create diagnostics engine");
117
118 DiagsBuffer->FlushDiagnostics(Diags&: Clang->getDiagnostics());
119 if (!Success)
120 return llvm::createStringError(EC: llvm::errc::not_supported,
121 S: "Initialization failed. "
122 "Unable to flush diagnostics");
123
124 // FIXME: Merge with CompilerInstance::ExecuteAction.
125 llvm::MemoryBuffer *MB = llvm::MemoryBuffer::getMemBuffer(InputData: "").release();
126 Clang->getPreprocessorOpts().addRemappedFile(From: "<<< inputs >>>", To: MB);
127
128 Clang->setTarget(TargetInfo::CreateTargetInfo(
129 Diags&: Clang->getDiagnostics(), Opts&: Clang->getInvocation().getTargetOpts()));
130 if (!Clang->hasTarget())
131 return llvm::createStringError(EC: llvm::errc::not_supported,
132 S: "Initialization failed. "
133 "Target is missing");
134
135 Clang->getTarget().adjust(Diags&: Clang->getDiagnostics(), Opts&: Clang->getLangOpts());
136
137 // Don't clear the AST before backend codegen since we do codegen multiple
138 // times, reusing the same AST.
139 Clang->getCodeGenOpts().ClearASTBeforeBackend = false;
140
141 Clang->getFrontendOpts().DisableFree = false;
142 Clang->getCodeGenOpts().DisableFree = false;
143 return std::move(Clang);
144}
145
146} // anonymous namespace
147
148namespace clang {
149
150llvm::Expected<std::unique_ptr<CompilerInstance>>
151IncrementalCompilerBuilder::create(std::string TT,
152 std::vector<const char *> &ClangArgv) {
153
154 // If we don't know ClangArgv0 or the address of main() at this point, try
155 // to guess it anyway (it's possible on some platforms).
156 std::string MainExecutableName =
157 llvm::sys::fs::getMainExecutable(argv0: nullptr, MainExecAddr: nullptr);
158
159 ClangArgv.insert(position: ClangArgv.begin(), x: MainExecutableName.c_str());
160
161 // Prepending -c to force the driver to do something if no action was
162 // specified. By prepending we allow users to override the default
163 // action and use other actions in incremental mode.
164 // FIXME: Print proper driver diagnostics if the driver flags are wrong.
165 // We do C++ by default; append right after argv[0] if no "-x" given
166 ClangArgv.insert(position: ClangArgv.end(), x: "-Xclang");
167 ClangArgv.insert(position: ClangArgv.end(), x: "-fincremental-extensions");
168 ClangArgv.insert(position: ClangArgv.end(), x: "-c");
169
170 // Put a dummy C++ file on to ensure there's at least one compile job for the
171 // driver to construct.
172 ClangArgv.push_back(x: "<<< inputs >>>");
173
174 // Buffer diagnostics from argument parsing so that we can output them using a
175 // well formed diagnostic object.
176 IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
177 std::unique_ptr<DiagnosticOptions> DiagOpts =
178 CreateAndPopulateDiagOpts(Argv: ClangArgv);
179 TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
180 DiagnosticsEngine Diags(DiagID, *DiagOpts, DiagsBuffer);
181
182 driver::Driver Driver(/*MainBinaryName=*/ClangArgv[0], TT, Diags);
183 Driver.setCheckInputsExist(false); // the input comes from mem buffers
184 llvm::ArrayRef<const char *> RF = llvm::ArrayRef(ClangArgv);
185 std::unique_ptr<driver::Compilation> Compilation(Driver.BuildCompilation(Args: RF));
186
187 if (Compilation->getArgs().hasArg(Ids: driver::options::OPT_v))
188 Compilation->getJobs().Print(OS&: llvm::errs(), Terminator: "\n", /*Quote=*/false);
189
190 auto ErrOrCC1Args = GetCC1Arguments(Diagnostics: &Diags, Compilation: Compilation.get());
191 if (auto Err = ErrOrCC1Args.takeError())
192 return std::move(Err);
193
194 return CreateCI(Argv: **ErrOrCC1Args);
195}
196
197llvm::Expected<std::unique_ptr<CompilerInstance>>
198IncrementalCompilerBuilder::CreateCpp() {
199 std::vector<const char *> Argv;
200 Argv.reserve(n: 5 + 1 + UserArgs.size());
201 Argv.push_back(x: "-xc++");
202#ifdef __EMSCRIPTEN__
203 Argv.push_back("-target");
204 Argv.push_back("wasm32-unknown-emscripten");
205 Argv.push_back("-fvisibility=default");
206#endif
207 llvm::append_range(C&: Argv, R&: UserArgs);
208
209 std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple();
210 return IncrementalCompilerBuilder::create(TT, ClangArgv&: Argv);
211}
212
213llvm::Expected<std::unique_ptr<CompilerInstance>>
214IncrementalCompilerBuilder::createCuda(bool device) {
215 std::vector<const char *> Argv;
216 Argv.reserve(n: 5 + 4 + UserArgs.size());
217
218 Argv.push_back(x: "-xcuda");
219 if (device)
220 Argv.push_back(x: "--cuda-device-only");
221 else
222 Argv.push_back(x: "--cuda-host-only");
223
224 std::string SDKPathArg = "--cuda-path=";
225 if (!CudaSDKPath.empty()) {
226 SDKPathArg += CudaSDKPath;
227 Argv.push_back(x: SDKPathArg.c_str());
228 }
229
230 std::string ArchArg = "--offload-arch=";
231 if (!OffloadArch.empty()) {
232 ArchArg += OffloadArch;
233 Argv.push_back(x: ArchArg.c_str());
234 }
235
236 llvm::append_range(C&: Argv, R&: UserArgs);
237
238 std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple();
239 return IncrementalCompilerBuilder::create(TT, ClangArgv&: Argv);
240}
241
242llvm::Expected<std::unique_ptr<CompilerInstance>>
243IncrementalCompilerBuilder::CreateCudaDevice() {
244 return IncrementalCompilerBuilder::createCuda(device: true);
245}
246
247llvm::Expected<std::unique_ptr<CompilerInstance>>
248IncrementalCompilerBuilder::CreateCudaHost() {
249 return IncrementalCompilerBuilder::createCuda(device: false);
250}
251
252class InProcessPrintingASTConsumer final : public MultiplexConsumer {
253 Interpreter &Interp;
254
255public:
256 InProcessPrintingASTConsumer(std::unique_ptr<ASTConsumer> C, Interpreter &I)
257 : MultiplexConsumer(std::move(C)), Interp(I) {}
258 bool HandleTopLevelDecl(DeclGroupRef DGR) override final {
259 if (DGR.isNull())
260 return true;
261
262 for (Decl *D : DGR)
263 if (auto *TLSD = llvm::dyn_cast<TopLevelStmtDecl>(Val: D))
264 if (TLSD && TLSD->isSemiMissing()) {
265 auto ExprOrErr =
266 Interp.ExtractValueFromExpr(E: cast<Expr>(Val: TLSD->getStmt()));
267 if (llvm::Error E = ExprOrErr.takeError()) {
268 llvm::logAllUnhandledErrors(E: std::move(E), OS&: llvm::errs(),
269 ErrorBanner: "Value printing failed: ");
270 return false; // abort parsing
271 }
272 TLSD->setStmt(*ExprOrErr);
273 }
274
275 return MultiplexConsumer::HandleTopLevelDecl(D: DGR);
276 }
277};
278
279/// A custom action enabling the incremental processing functionality.
280///
281/// The usual \p FrontendAction expects one call to ExecuteAction and once it
282/// sees a call to \p EndSourceFile it deletes some of the important objects
283/// such as \p Preprocessor and \p Sema assuming no further input will come.
284///
285/// \p IncrementalAction ensures it keep its underlying action's objects alive
286/// as long as the \p IncrementalParser needs them.
287///
288class IncrementalAction : public WrapperFrontendAction {
289private:
290 bool IsTerminating = false;
291 Interpreter &Interp;
292 std::unique_ptr<ASTConsumer> Consumer;
293
294public:
295 IncrementalAction(CompilerInstance &CI, llvm::LLVMContext &LLVMCtx,
296 llvm::Error &Err, Interpreter &I,
297 std::unique_ptr<ASTConsumer> Consumer = nullptr)
298 : WrapperFrontendAction([&]() {
299 llvm::ErrorAsOutParameter EAO(&Err);
300 std::unique_ptr<FrontendAction> Act;
301 switch (CI.getFrontendOpts().ProgramAction) {
302 default:
303 Err = llvm::createStringError(
304 EC: std::errc::state_not_recoverable,
305 Fmt: "Driver initialization failed. "
306 "Incremental mode for action %d is not supported",
307 Vals: CI.getFrontendOpts().ProgramAction);
308 return Act;
309 case frontend::ASTDump:
310 case frontend::ASTPrint:
311 case frontend::ParseSyntaxOnly:
312 Act = CreateFrontendAction(CI);
313 break;
314 case frontend::PluginAction:
315 case frontend::EmitAssembly:
316 case frontend::EmitBC:
317 case frontend::EmitObj:
318 case frontend::PrintPreprocessedInput:
319 case frontend::EmitLLVMOnly:
320 Act.reset(p: new EmitLLVMOnlyAction(&LLVMCtx));
321 break;
322 }
323 return Act;
324 }()),
325 Interp(I), Consumer(std::move(Consumer)) {}
326 FrontendAction *getWrapped() const { return WrappedAction.get(); }
327 TranslationUnitKind getTranslationUnitKind() override {
328 return TU_Incremental;
329 }
330
331 std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
332 StringRef InFile) override {
333 std::unique_ptr<ASTConsumer> C =
334 WrapperFrontendAction::CreateASTConsumer(CI, InFile);
335
336 if (Consumer) {
337 std::vector<std::unique_ptr<ASTConsumer>> Cs;
338 Cs.push_back(x: std::move(Consumer));
339 Cs.push_back(x: std::move(C));
340 return std::make_unique<MultiplexConsumer>(args: std::move(Cs));
341 }
342
343 return std::make_unique<InProcessPrintingASTConsumer>(args: std::move(C), args&: Interp);
344 }
345
346 void ExecuteAction() override {
347 WrapperFrontendAction::ExecuteAction();
348 getCompilerInstance().getSema().CurContext = nullptr;
349 }
350
351 // Do not terminate after processing the input. This allows us to keep various
352 // clang objects alive and to incrementally grow the current TU.
353 void EndSourceFile() override {
354 // The WrappedAction can be nullptr if we issued an error in the ctor.
355 if (IsTerminating && getWrapped())
356 WrapperFrontendAction::EndSourceFile();
357 }
358
359 void FinalizeAction() {
360 assert(!IsTerminating && "Already finalized!");
361 IsTerminating = true;
362 EndSourceFile();
363 }
364};
365
366Interpreter::Interpreter(std::unique_ptr<CompilerInstance> Instance,
367 llvm::Error &ErrOut,
368 std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder,
369 std::unique_ptr<clang::ASTConsumer> Consumer)
370 : JITBuilder(std::move(JITBuilder)) {
371 CI = std::move(Instance);
372 llvm::ErrorAsOutParameter EAO(&ErrOut);
373 auto LLVMCtx = std::make_unique<llvm::LLVMContext>();
374 TSCtx = std::make_unique<llvm::orc::ThreadSafeContext>(args: std::move(LLVMCtx));
375
376 Act = TSCtx->withContextDo(F: [&](llvm::LLVMContext *Ctx) {
377 return std::make_unique<IncrementalAction>(args&: *CI, args&: *Ctx, args&: ErrOut, args&: *this,
378 args: std::move(Consumer));
379 });
380
381 if (ErrOut)
382 return;
383 CI->ExecuteAction(Act&: *Act);
384
385 IncrParser = std::make_unique<IncrementalParser>(args&: *CI, args&: ErrOut);
386
387 if (ErrOut)
388 return;
389
390 if (getCodeGen()) {
391 CachedInCodeGenModule = GenModule();
392 // The initial PTU is filled by `-include` or by CUDA includes
393 // automatically.
394 if (!CI->getPreprocessorOpts().Includes.empty()) {
395 // We can't really directly pass the CachedInCodeGenModule to the Jit
396 // because it will steal it, causing dangling references as explained in
397 // Interpreter::Execute
398 auto M = llvm::CloneModule(M: *CachedInCodeGenModule);
399 ASTContext &C = CI->getASTContext();
400 RegisterPTU(TU: C.getTranslationUnitDecl(), M: std::move(M));
401 }
402 if (llvm::Error Err = CreateExecutor()) {
403 ErrOut = joinErrors(E1: std::move(ErrOut), E2: std::move(Err));
404 return;
405 }
406 }
407
408 // Not all frontends support code-generation, e.g. ast-dump actions don't
409 if (getCodeGen()) {
410 // Process the PTUs that came from initialization. For example -include will
411 // give us a header that's processed at initialization of the preprocessor.
412 for (PartialTranslationUnit &PTU : PTUs)
413 if (llvm::Error Err = Execute(T&: PTU)) {
414 ErrOut = joinErrors(E1: std::move(ErrOut), E2: std::move(Err));
415 return;
416 }
417 }
418}
419
420Interpreter::~Interpreter() {
421 IncrParser.reset();
422 Act->FinalizeAction();
423 if (DeviceParser)
424 DeviceParser.reset();
425 if (DeviceAct)
426 DeviceAct->FinalizeAction();
427 if (IncrExecutor) {
428 if (llvm::Error Err = IncrExecutor->cleanUp())
429 llvm::report_fatal_error(
430 reason: llvm::Twine("Failed to clean up IncrementalExecutor: ") +
431 toString(E: std::move(Err)));
432 }
433}
434
435// These better to put in a runtime header but we can't. This is because we
436// can't find the precise resource directory in unittests so we have to hard
437// code them.
438const char *const Runtimes = R"(
439 #define __CLANG_REPL__ 1
440#ifdef __cplusplus
441 #define EXTERN_C extern "C"
442 void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*);
443 struct __clang_Interpreter_NewTag{} __ci_newtag;
444 void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) noexcept;
445 template <class T, class = T (*)() /*disable for arrays*/>
446 void __clang_Interpreter_SetValueCopyArr(T* Src, void* Placement, unsigned long Size) {
447 for (auto Idx = 0; Idx < Size; ++Idx)
448 new ((void*)(((T*)Placement) + Idx), __ci_newtag) T(Src[Idx]);
449 }
450 template <class T, unsigned long N>
451 void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* Placement, unsigned long Size) {
452 __clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size);
453 }
454#else
455 #define EXTERN_C extern
456#endif // __cplusplus
457
458 EXTERN_C void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...);
459)";
460
461llvm::Expected<std::unique_ptr<Interpreter>>
462Interpreter::create(std::unique_ptr<CompilerInstance> CI,
463 std::unique_ptr<llvm::orc::LLJITBuilder> JB) {
464 llvm::Error Err = llvm::Error::success();
465 auto Interp = std::unique_ptr<Interpreter>(
466 new Interpreter(std::move(CI), Err, JB ? std::move(JB) : nullptr));
467 if (Err)
468 return std::move(Err);
469
470 // Add runtime code and set a marker to hide it from user code. Undo will not
471 // go through that.
472 auto PTU = Interp->Parse(Code: Runtimes);
473 if (!PTU)
474 return PTU.takeError();
475 Interp->markUserCodeStart();
476
477 Interp->ValuePrintingInfo.resize(N: 4);
478 return std::move(Interp);
479}
480
481llvm::Expected<std::unique_ptr<Interpreter>>
482Interpreter::createWithCUDA(std::unique_ptr<CompilerInstance> CI,
483 std::unique_ptr<CompilerInstance> DCI) {
484 // avoid writing fat binary to disk using an in-memory virtual file system
485 llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> IMVFS =
486 std::make_unique<llvm::vfs::InMemoryFileSystem>();
487 llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayVFS =
488 std::make_unique<llvm::vfs::OverlayFileSystem>(
489 args: llvm::vfs::getRealFileSystem());
490 OverlayVFS->pushOverlay(FS: IMVFS);
491 CI->createFileManager(VFS: OverlayVFS);
492
493 llvm::Expected<std::unique_ptr<Interpreter>> InterpOrErr =
494 Interpreter::create(CI: std::move(CI));
495 if (!InterpOrErr)
496 return InterpOrErr;
497
498 std::unique_ptr<Interpreter> Interp = std::move(*InterpOrErr);
499
500 llvm::Error Err = llvm::Error::success();
501
502 auto DeviceAct = Interp->TSCtx->withContextDo(F: [&](llvm::LLVMContext *Ctx) {
503 return std::make_unique<IncrementalAction>(args&: *DCI, args&: *Ctx, args&: Err, args&: *Interp);
504 });
505
506 if (Err)
507 return std::move(Err);
508
509 Interp->DeviceAct = std::move(DeviceAct);
510
511 DCI->ExecuteAction(Act&: *Interp->DeviceAct);
512
513 Interp->DeviceCI = std::move(DCI);
514
515 auto DeviceParser = std::make_unique<IncrementalCUDADeviceParser>(
516 args&: *Interp->DeviceCI, args&: *Interp->getCompilerInstance(), args&: IMVFS, args&: Err,
517 args&: Interp->PTUs);
518
519 if (Err)
520 return std::move(Err);
521
522 Interp->DeviceParser = std::move(DeviceParser);
523 return std::move(Interp);
524}
525
526const CompilerInstance *Interpreter::getCompilerInstance() const {
527 return CI.get();
528}
529
530CompilerInstance *Interpreter::getCompilerInstance() { return CI.get(); }
531
532llvm::Expected<llvm::orc::LLJIT &> Interpreter::getExecutionEngine() {
533 if (!IncrExecutor) {
534 if (auto Err = CreateExecutor())
535 return std::move(Err);
536 }
537
538 return IncrExecutor->GetExecutionEngine();
539}
540
541ASTContext &Interpreter::getASTContext() {
542 return getCompilerInstance()->getASTContext();
543}
544
545const ASTContext &Interpreter::getASTContext() const {
546 return getCompilerInstance()->getASTContext();
547}
548
549void Interpreter::markUserCodeStart() {
550 assert(!InitPTUSize && "We only do this once");
551 InitPTUSize = PTUs.size();
552}
553
554size_t Interpreter::getEffectivePTUSize() const {
555 assert(PTUs.size() >= InitPTUSize && "empty PTU list?");
556 return PTUs.size() - InitPTUSize;
557}
558
559PartialTranslationUnit &
560Interpreter::RegisterPTU(TranslationUnitDecl *TU,
561 std::unique_ptr<llvm::Module> M /*={}*/,
562 IncrementalAction *Action) {
563 PTUs.emplace_back(args: PartialTranslationUnit());
564 PartialTranslationUnit &LastPTU = PTUs.back();
565 LastPTU.TUPart = TU;
566
567 if (!M)
568 M = GenModule(Action);
569
570 assert((!getCodeGen(Action) || M) &&
571 "Must have a llvm::Module at this point");
572
573 LastPTU.TheModule = std::move(M);
574 LLVM_DEBUG(llvm::dbgs() << "compile-ptu " << PTUs.size() - 1
575 << ": [TU=" << LastPTU.TUPart);
576 if (LastPTU.TheModule)
577 LLVM_DEBUG(llvm::dbgs() << ", M=" << LastPTU.TheModule.get() << " ("
578 << LastPTU.TheModule->getName() << ")");
579 LLVM_DEBUG(llvm::dbgs() << "]\n");
580 return LastPTU;
581}
582
583llvm::Expected<PartialTranslationUnit &>
584Interpreter::Parse(llvm::StringRef Code) {
585 // If we have a device parser, parse it first. The generated code will be
586 // included in the host compilation
587 if (DeviceParser) {
588 llvm::Expected<TranslationUnitDecl *> DeviceTU = DeviceParser->Parse(Input: Code);
589 if (auto E = DeviceTU.takeError())
590 return std::move(E);
591
592 RegisterPTU(TU: *DeviceTU, M: nullptr, Action: DeviceAct.get());
593
594 llvm::Expected<llvm::StringRef> PTX = DeviceParser->GeneratePTX();
595 if (!PTX)
596 return PTX.takeError();
597
598 llvm::Error Err = DeviceParser->GenerateFatbinary();
599 if (Err)
600 return std::move(Err);
601 }
602
603 // Tell the interpreter sliently ignore unused expressions since value
604 // printing could cause it.
605 getCompilerInstance()->getDiagnostics().setSeverity(
606 Diag: clang::diag::warn_unused_expr, Map: diag::Severity::Ignored, Loc: SourceLocation());
607
608 llvm::Expected<TranslationUnitDecl *> TuOrErr = IncrParser->Parse(Input: Code);
609 if (!TuOrErr)
610 return TuOrErr.takeError();
611
612 return RegisterPTU(TU: *TuOrErr);
613}
614
615static llvm::Expected<llvm::orc::JITTargetMachineBuilder>
616createJITTargetMachineBuilder(const std::string &TT) {
617 if (TT == llvm::sys::getProcessTriple())
618 // This fails immediately if the target backend is not registered
619 return llvm::orc::JITTargetMachineBuilder::detectHost();
620
621 // If the target backend is not registered, LLJITBuilder::create() will fail
622 return llvm::orc::JITTargetMachineBuilder(llvm::Triple(TT));
623}
624
625llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
626Interpreter::createLLJITBuilder(
627 std::unique_ptr<llvm::orc::ExecutorProcessControl> EPC,
628 llvm::StringRef OrcRuntimePath) {
629 const std::string &TT = EPC->getTargetTriple().getTriple();
630 auto JTMB = createJITTargetMachineBuilder(TT);
631 if (!JTMB)
632 return JTMB.takeError();
633 auto JB = IncrementalExecutor::createDefaultJITBuilder(JTMB: std::move(*JTMB));
634 if (!JB)
635 return JB.takeError();
636
637 (*JB)->setExecutorProcessControl(std::move(EPC));
638 (*JB)->setPlatformSetUp(
639 llvm::orc::ExecutorNativePlatform(OrcRuntimePath.str()));
640
641 return std::move(*JB);
642}
643
644llvm::Error Interpreter::CreateExecutor() {
645 if (IncrExecutor)
646 return llvm::make_error<llvm::StringError>(Args: "Operation failed. "
647 "Execution engine exists",
648 Args: std::error_code());
649 if (!getCodeGen())
650 return llvm::make_error<llvm::StringError>(Args: "Operation failed. "
651 "No code generator available",
652 Args: std::error_code());
653 if (!JITBuilder) {
654 const std::string &TT = getCompilerInstance()->getTargetOpts().Triple;
655 auto JTMB = createJITTargetMachineBuilder(TT);
656 if (!JTMB)
657 return JTMB.takeError();
658 auto JB = IncrementalExecutor::createDefaultJITBuilder(JTMB: std::move(*JTMB));
659 if (!JB)
660 return JB.takeError();
661 JITBuilder = std::move(*JB);
662 }
663
664 llvm::Error Err = llvm::Error::success();
665#ifdef __EMSCRIPTEN__
666 auto Executor = std::make_unique<WasmIncrementalExecutor>(*TSCtx);
667#else
668 auto Executor =
669 std::make_unique<IncrementalExecutor>(args&: *TSCtx, args&: *JITBuilder, args&: Err);
670#endif
671 if (!Err)
672 IncrExecutor = std::move(Executor);
673
674 return Err;
675}
676
677void Interpreter::ResetExecutor() { IncrExecutor.reset(); }
678
679llvm::Error Interpreter::Execute(PartialTranslationUnit &T) {
680 assert(T.TheModule);
681 LLVM_DEBUG(
682 llvm::dbgs() << "execute-ptu "
683 << (llvm::is_contained(PTUs, T)
684 ? std::distance(PTUs.begin(), llvm::find(PTUs, T))
685 : -1)
686 << ": [TU=" << T.TUPart << ", M=" << T.TheModule.get()
687 << " (" << T.TheModule->getName() << ")]\n");
688 if (!IncrExecutor) {
689 auto Err = CreateExecutor();
690 if (Err)
691 return Err;
692 }
693 // FIXME: Add a callback to retain the llvm::Module once the JIT is done.
694 if (auto Err = IncrExecutor->addModule(PTU&: T))
695 return Err;
696
697 if (auto Err = IncrExecutor->runCtors())
698 return Err;
699
700 return llvm::Error::success();
701}
702
703llvm::Error Interpreter::ParseAndExecute(llvm::StringRef Code, Value *V) {
704
705 auto PTU = Parse(Code);
706 if (!PTU)
707 return PTU.takeError();
708 if (PTU->TheModule)
709 if (llvm::Error Err = Execute(T&: *PTU))
710 return Err;
711
712 if (LastValue.isValid()) {
713 if (!V) {
714 LastValue.dump();
715 LastValue.clear();
716 } else
717 *V = std::move(LastValue);
718 }
719 return llvm::Error::success();
720}
721
722llvm::Expected<llvm::orc::ExecutorAddr>
723Interpreter::getSymbolAddress(GlobalDecl GD) const {
724 if (!IncrExecutor)
725 return llvm::make_error<llvm::StringError>(Args: "Operation failed. "
726 "No execution engine",
727 Args: std::error_code());
728 llvm::StringRef MangledName = getCodeGen()->GetMangledName(GD);
729 return getSymbolAddress(IRName: MangledName);
730}
731
732llvm::Expected<llvm::orc::ExecutorAddr>
733Interpreter::getSymbolAddress(llvm::StringRef IRName) const {
734 if (!IncrExecutor)
735 return llvm::make_error<llvm::StringError>(Args: "Operation failed. "
736 "No execution engine",
737 Args: std::error_code());
738
739 return IncrExecutor->getSymbolAddress(Name: IRName, NameKind: IncrementalExecutor::IRName);
740}
741
742llvm::Expected<llvm::orc::ExecutorAddr>
743Interpreter::getSymbolAddressFromLinkerName(llvm::StringRef Name) const {
744 if (!IncrExecutor)
745 return llvm::make_error<llvm::StringError>(Args: "Operation failed. "
746 "No execution engine",
747 Args: std::error_code());
748
749 return IncrExecutor->getSymbolAddress(Name, NameKind: IncrementalExecutor::LinkerName);
750}
751
752llvm::Error Interpreter::Undo(unsigned N) {
753
754 if (N > getEffectivePTUSize())
755 return llvm::make_error<llvm::StringError>(Args: "Operation failed. "
756 "Too many undos",
757 Args: std::error_code());
758 for (unsigned I = 0; I < N; I++) {
759 if (IncrExecutor) {
760 if (llvm::Error Err = IncrExecutor->removeModule(PTU&: PTUs.back()))
761 return Err;
762 }
763
764 IncrParser->CleanUpPTU(MostRecentTU: PTUs.back().TUPart);
765 PTUs.pop_back();
766 }
767 return llvm::Error::success();
768}
769
770llvm::Error Interpreter::LoadDynamicLibrary(const char *name) {
771#ifdef __EMSCRIPTEN__
772 void *handle = dlopen(name, RTLD_NOW | RTLD_GLOBAL);
773 if (!handle) {
774 llvm::errs() << dlerror() << '\n';
775 return llvm::make_error<llvm::StringError>("Failed to load dynamic library",
776 llvm::inconvertibleErrorCode());
777 }
778#else
779 auto EE = getExecutionEngine();
780 if (!EE)
781 return EE.takeError();
782
783 if (llvm::Expected<
784 std::unique_ptr<llvm::orc::EPCDynamicLibrarySearchGenerator>>
785 DLSG = llvm::orc::EPCDynamicLibrarySearchGenerator::Load(
786 ES&: EE->getExecutionSession(), LibraryPath: name))
787 // FIXME: Eventually we should put each library in its own JITDylib and
788 // turn off process symbols by default.
789 EE->getProcessSymbolsJITDylib()->addGenerator(DefGenerator: std::move(*DLSG));
790 else
791 return DLSG.takeError();
792#endif
793
794 return llvm::Error::success();
795}
796
797std::unique_ptr<llvm::Module>
798Interpreter::GenModule(IncrementalAction *Action) {
799 static unsigned ID = 0;
800 if (CodeGenerator *CG = getCodeGen(Action)) {
801 // Clang's CodeGen is designed to work with a single llvm::Module. In many
802 // cases for convenience various CodeGen parts have a reference to the
803 // llvm::Module (TheModule or Module) which does not change when a new
804 // module is pushed. However, the execution engine wants to take ownership
805 // of the module which does not map well to CodeGen's design. To work this
806 // around we created an empty module to make CodeGen happy. We should make
807 // sure it always stays empty.
808 assert(((!CachedInCodeGenModule ||
809 !getCompilerInstance()->getPreprocessorOpts().Includes.empty()) ||
810 (CachedInCodeGenModule->empty() &&
811 CachedInCodeGenModule->global_empty() &&
812 CachedInCodeGenModule->alias_empty() &&
813 CachedInCodeGenModule->ifunc_empty())) &&
814 "CodeGen wrote to a readonly module");
815 std::unique_ptr<llvm::Module> M(CG->ReleaseModule());
816 CG->StartModule(ModuleName: "incr_module_" + std::to_string(val: ID++), C&: M->getContext());
817 return M;
818 }
819 return nullptr;
820}
821
822CodeGenerator *Interpreter::getCodeGen(IncrementalAction *Action) const {
823 if (!Action)
824 Action = Act.get();
825 FrontendAction *WrappedAct = Action->getWrapped();
826 if (!WrappedAct->hasIRSupport())
827 return nullptr;
828 return static_cast<CodeGenAction *>(WrappedAct)->getCodeGenerator();
829}
830} // namespace clang
831