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