xref: /llvm-project/llvm/examples/OrcV2Examples/LLJITWithInitializers/LLJITWithInitializers.cpp (revision dc11c0601577afb8f67513d041ee25dabe3555b9)
1a7a03d64SLang Hames //===----- LLJITDumpObjects.cpp - How to dump JIT'd objects with LLJIT ----===//
2a7a03d64SLang Hames //
3a7a03d64SLang Hames // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4a7a03d64SLang Hames // See https://llvm.org/LICENSE.txt for license information.
5a7a03d64SLang Hames // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a7a03d64SLang Hames //
7a7a03d64SLang Hames //===----------------------------------------------------------------------===//
8a7a03d64SLang Hames ///
9a7a03d64SLang Hames /// \file
10a7a03d64SLang Hames ///
11a7a03d64SLang Hames /// This example demonstrates how to use LLJIT to:
12a7a03d64SLang Hames ///   - Add absolute symbol definitions.
13a7a03d64SLang Hames ///   - Run static constructors for a JITDylib.
14a7a03d64SLang Hames ///   - Run static destructors for a JITDylib.
15a7a03d64SLang Hames ///
16a7a03d64SLang Hames /// This example does not call any functions (e.g. main or equivalent)  between
17a7a03d64SLang Hames /// running the static constructors and running the static destructors.
18a7a03d64SLang Hames ///
19a7a03d64SLang Hames //===----------------------------------------------------------------------===//
20a7a03d64SLang Hames 
21a7a03d64SLang Hames #include "llvm/ADT/StringMap.h"
22*dc11c060SLang Hames #include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h"
23a7a03d64SLang Hames #include "llvm/ExecutionEngine/Orc/LLJIT.h"
24a7a03d64SLang Hames #include "llvm/Support/InitLLVM.h"
25a7a03d64SLang Hames #include "llvm/Support/TargetSelect.h"
26a7a03d64SLang Hames #include "llvm/Support/raw_ostream.h"
27a7a03d64SLang Hames 
28a7a03d64SLang Hames #include "../ExampleModules.h"
29a7a03d64SLang Hames 
30a7a03d64SLang Hames using namespace llvm;
31a7a03d64SLang Hames using namespace llvm::orc;
32a7a03d64SLang Hames 
33a7a03d64SLang Hames ExitOnError ExitOnErr;
34a7a03d64SLang Hames 
35a7a03d64SLang Hames const llvm::StringRef ModuleWithInitializer =
36a7a03d64SLang Hames     R"(
37a7a03d64SLang Hames 
38a7a03d64SLang Hames   @InitializersRunFlag = external global i32
39a7a03d64SLang Hames   @DeinitializersRunFlag = external global i32
40a7a03d64SLang Hames 
41a7a03d64SLang Hames   declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*)
42a7a03d64SLang Hames   @__dso_handle = external hidden global i8
43a7a03d64SLang Hames 
44a7a03d64SLang Hames   @llvm.global_ctors =
45a7a03d64SLang Hames     appending global [1 x { i32, void ()*, i8* }]
46a7a03d64SLang Hames       [{ i32, void ()*, i8* } { i32 65535, void ()* @init_func, i8* null }]
47a7a03d64SLang Hames 
48a7a03d64SLang Hames   define internal void @init_func() {
49a7a03d64SLang Hames   entry:
50a7a03d64SLang Hames     store i32 1, i32* @InitializersRunFlag
51a7a03d64SLang Hames     %0 = call i32 @__cxa_atexit(void (i8*)* @deinit_func, i8* null,
52a7a03d64SLang Hames                                 i8* @__dso_handle)
53a7a03d64SLang Hames     ret void
54a7a03d64SLang Hames   }
55a7a03d64SLang Hames 
56a7a03d64SLang Hames   define internal void @deinit_func(i8* %0) {
57a7a03d64SLang Hames     store i32 1, i32* @DeinitializersRunFlag
58a7a03d64SLang Hames     ret void
59a7a03d64SLang Hames   }
60a7a03d64SLang Hames 
61a7a03d64SLang Hames )";
62a7a03d64SLang Hames 
63a7a03d64SLang Hames int main(int argc, char *argv[]) {
64a7a03d64SLang Hames   // Initialize LLVM.
65a7a03d64SLang Hames   InitLLVM X(argc, argv);
66a7a03d64SLang Hames 
67a7a03d64SLang Hames   InitializeNativeTarget();
68a7a03d64SLang Hames   InitializeNativeTargetAsmPrinter();
69a7a03d64SLang Hames 
70a7a03d64SLang Hames   cl::ParseCommandLineOptions(argc, argv, "LLJITWithInitializers");
71a7a03d64SLang Hames   ExitOnErr.setBanner(std::string(argv[0]) + ": ");
72a7a03d64SLang Hames 
73a7a03d64SLang Hames   auto J = ExitOnErr(LLJITBuilder().create());
74a7a03d64SLang Hames   auto M = ExitOnErr(parseExampleModule(ModuleWithInitializer, "M"));
75a7a03d64SLang Hames 
76a7a03d64SLang Hames   // Load the module.
77a7a03d64SLang Hames   ExitOnErr(J->addIRModule(std::move(M)));
78a7a03d64SLang Hames 
79a7a03d64SLang Hames   int32_t InitializersRunFlag = 0;
80a7a03d64SLang Hames   int32_t DeinitializersRunFlag = 0;
81a7a03d64SLang Hames 
828b1771bdSLang Hames   ExitOnErr(J->getMainJITDylib().define(
838b1771bdSLang Hames       absoluteSymbols({{J->mangleAndIntern("InitializersRunFlag"),
848b1771bdSLang Hames                         {ExecutorAddr::fromPtr(&InitializersRunFlag),
858b1771bdSLang Hames                          JITSymbolFlags::Exported}},
86a7a03d64SLang Hames                        {J->mangleAndIntern("DeinitializersRunFlag"),
878b1771bdSLang Hames                         {ExecutorAddr::fromPtr(&DeinitializersRunFlag),
888b1771bdSLang Hames                          JITSymbolFlags::Exported}}})));
89a7a03d64SLang Hames 
90a7a03d64SLang Hames   // Run static initializers.
91a7a03d64SLang Hames   ExitOnErr(J->initialize(J->getMainJITDylib()));
92a7a03d64SLang Hames 
93a7a03d64SLang Hames   // Run deinitializers.
94a7a03d64SLang Hames   ExitOnErr(J->deinitialize(J->getMainJITDylib()));
95a7a03d64SLang Hames 
96a7a03d64SLang Hames   outs() << "InitializerRanFlag = " << InitializersRunFlag << "\n"
97a7a03d64SLang Hames          << "DeinitializersRunFlag = " << DeinitializersRunFlag << "\n";
98a7a03d64SLang Hames 
99a7a03d64SLang Hames   return 0;
100a7a03d64SLang Hames }
101