diff --git a/examples/OrcV2Examples/CMakeLists.txt b/examples/OrcV2Examples/CMakeLists.txt index 761da008f5d..2c737296ae1 100644 --- a/examples/OrcV2Examples/CMakeLists.txt +++ b/examples/OrcV2Examples/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(LLJITDumpObjects) add_subdirectory(LLJITWithCustomObjectLinkingLayer) add_subdirectory(LLJITWithGDBRegistrationListener) +add_subdirectory(LLJITWithInitializers) add_subdirectory(LLJITWithLazyReexports) add_subdirectory(LLJITWithObjectCache) add_subdirectory(LLJITWithObjectLinkingLayerPlugin) diff --git a/examples/OrcV2Examples/LLJITWithInitializers/CMakeLists.txt b/examples/OrcV2Examples/LLJITWithInitializers/CMakeLists.txt new file mode 100644 index 00000000000..302647564ab --- /dev/null +++ b/examples/OrcV2Examples/LLJITWithInitializers/CMakeLists.txt @@ -0,0 +1,13 @@ +set(LLVM_LINK_COMPONENTS + Core + ExecutionEngine + IRReader + JITLink + OrcJIT + Support + nativecodegen + ) + +add_llvm_example(LLJITWithInitializers + LLJITWithInitializers.cpp + ) diff --git a/examples/OrcV2Examples/LLJITWithInitializers/LLJITWithInitializers.cpp b/examples/OrcV2Examples/LLJITWithInitializers/LLJITWithInitializers.cpp new file mode 100644 index 00000000000..063b9f6060e --- /dev/null +++ b/examples/OrcV2Examples/LLJITWithInitializers/LLJITWithInitializers.cpp @@ -0,0 +1,97 @@ +//===----- LLJITDumpObjects.cpp - How to dump JIT'd objects with LLJIT ----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// +/// This example demonstrates how to use LLJIT to: +/// - Add absolute symbol definitions. +/// - Run static constructors for a JITDylib. +/// - Run static destructors for a JITDylib. +/// +/// This example does not call any functions (e.g. main or equivalent) between +/// running the static constructors and running the static destructors. +/// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/StringMap.h" +#include "llvm/ExecutionEngine/Orc/LLJIT.h" +#include "llvm/Support/InitLLVM.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Support/raw_ostream.h" + +#include "../ExampleModules.h" + +using namespace llvm; +using namespace llvm::orc; + +ExitOnError ExitOnErr; + +const llvm::StringRef ModuleWithInitializer = + R"( + + @InitializersRunFlag = external global i32 + @DeinitializersRunFlag = external global i32 + + declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*) + @__dso_handle = external hidden global i8 + + @llvm.global_ctors = + appending global [1 x { i32, void ()*, i8* }] + [{ i32, void ()*, i8* } { i32 65535, void ()* @init_func, i8* null }] + + define internal void @init_func() { + entry: + store i32 1, i32* @InitializersRunFlag + %0 = call i32 @__cxa_atexit(void (i8*)* @deinit_func, i8* null, + i8* @__dso_handle) + ret void + } + + define internal void @deinit_func(i8* %0) { + store i32 1, i32* @DeinitializersRunFlag + ret void + } + +)"; + +int main(int argc, char *argv[]) { + // Initialize LLVM. + InitLLVM X(argc, argv); + + InitializeNativeTarget(); + InitializeNativeTargetAsmPrinter(); + + cl::ParseCommandLineOptions(argc, argv, "LLJITWithInitializers"); + ExitOnErr.setBanner(std::string(argv[0]) + ": "); + + auto J = ExitOnErr(LLJITBuilder().create()); + auto M = ExitOnErr(parseExampleModule(ModuleWithInitializer, "M")); + + // Load the module. + ExitOnErr(J->addIRModule(std::move(M))); + + int32_t InitializersRunFlag = 0; + int32_t DeinitializersRunFlag = 0; + + ExitOnErr(J->define(absoluteSymbols( + {{J->mangleAndIntern("InitializersRunFlag"), + JITEvaluatedSymbol::fromPointer(&InitializersRunFlag)}, + {J->mangleAndIntern("DeinitializersRunFlag"), + JITEvaluatedSymbol::fromPointer(&DeinitializersRunFlag)}}))); + + // Run static initializers. + ExitOnErr(J->initialize(J->getMainJITDylib())); + + // Run deinitializers. + ExitOnErr(J->deinitialize(J->getMainJITDylib())); + + outs() << "InitializerRanFlag = " << InitializersRunFlag << "\n" + << "DeinitializersRunFlag = " << DeinitializersRunFlag << "\n"; + + return 0; +}