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

source code of clang/lib/Interpreter/Interpreter.cpp