//===-- AMDGPUCtorDtorLowering.cpp - Handle global ctors and dtors --------===// // // 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 pass creates a unified init and fini kernel with the required metadata //===----------------------------------------------------------------------===// #include "AMDGPUCtorDtorLowering.h" #include "AMDGPU.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Module.h" #include "llvm/IR/Value.h" #include "llvm/Pass.h" #include "llvm/Transforms/Utils/ModuleUtils.h" usingnamespacellvm; #define DEBUG_TYPE … namespace { static Function *createInitOrFiniKernelFunction(Module &M, bool IsCtor) { … } // The linker will provide the associated symbols to allow us to traverse the // global constructors / destructors in priority order. We create the IR // required to call each callback in this section. This is equivalent to the // following code. // // extern "C" void * __init_array_start[]; // extern "C" void * __init_array_end[]; // extern "C" void * __fini_array_start[]; // extern "C" void * __fini_array_end[]; // // using InitCallback = void(); // using FiniCallback = void(void); // // void call_init_array_callbacks() { // for (auto start = __init_array_start; start != __init_array_end; ++start) // reinterpret_cast<InitCallback *>(*start)(); // } // // void call_fini_array_callbacks() { // size_t fini_array_size = __fini_array_end - __fini_array_start; // for (size_t i = fini_array_size; i > 0; --i) // reinterpret_cast<FiniCallback *>(__fini_array_start[i - 1])(); // } static void createInitOrFiniCalls(Function &F, bool IsCtor) { … } static bool createInitOrFiniKernel(Module &M, StringRef GlobalName, bool IsCtor) { … } static bool lowerCtorsAndDtors(Module &M) { … } class AMDGPUCtorDtorLoweringLegacy final : public ModulePass { … }; } // End anonymous namespace PreservedAnalyses AMDGPUCtorDtorLoweringPass::run(Module &M, ModuleAnalysisManager &AM) { … } char AMDGPUCtorDtorLoweringLegacy::ID = …; char &llvm::AMDGPUCtorDtorLoweringLegacyPassID = …; INITIALIZE_PASS(…) ModulePass *llvm::createAMDGPUCtorDtorLoweringLegacyPass() { … }