[PATCH] D149340: [AMDGPU] Place global constructors in .init_array and .fini_array
Joseph Huber via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 27 06:07:47 PDT 2023
jhuber6 created this revision.
jhuber6 added reviewers: jdoerfert, JonChesterfield, arsenm, yaxunl, sivachandra, michaelrj, MaskRay, rampitec.
Herald added subscribers: kosarev, foad, kerbowa, hiraditya, tpr, dstuttard, jvesely, kzhuravl.
Herald added a project: All.
jhuber6 requested review of this revision.
Herald added subscribers: llvm-commits, wdng.
Herald added a project: LLVM.
For the GPU, we emit external kernels that call the initializers and
constructors, however if we had a persistent kernel like in the `_start`
kernel for the `libc` project, we could initialize the standard way of
calling constructors. This patch adds new global variables containing
pointers to the constructors to be called. If these are placed in the
`.init_array` and `.fini_array` sections, then the backend will handle
them specially. The linker will then provide the `__init_array_` and
`__fini_array_` sections to traverse them. An implementation would look
like this.
extern uintptr_t __init_array_start[];
extern uintptr_t __init_array_end[];
extern uintptr_t __fini_array_start[];
extern uintptr_t __fini_array_end[];
using InitCallback = void(int, char **, char **);
using FiniCallback = void(void);
extern "C" [[gnu::visibility("protected"), clang::amdgpu_kernel]] void
_start(int argc, char **argv, char **envp) {
uint64_t init_array_size = __init_array_end - __init_array_start;
for (uint64_t i = 0; i < init_array_size; ++i)
reinterpret_cast<InitCallback *>(__init_array_start[i])(argc, argv, env);
uint64_t fini_array_size = __fini_array_end - __fini_array_start;
for (uint64_t i = 0; i < fini_array_size; ++i)
reinterpret_cast<FiniCallback *>(__fini_array_start[i])();
}
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D149340
Files:
llvm/lib/Target/AMDGPU/AMDGPUCtorDtorLowering.cpp
llvm/test/CodeGen/AMDGPU/lower-ctor-dtor.ll
Index: llvm/test/CodeGen/AMDGPU/lower-ctor-dtor.ll
===================================================================
--- llvm/test/CodeGen/AMDGPU/lower-ctor-dtor.ll
+++ llvm/test/CodeGen/AMDGPU/lower-ctor-dtor.ll
@@ -10,6 +10,9 @@
; CHECK-NOT: @llvm.global_ctors
; CHECK-NOT: @llvm.global_dtors
+; CHECK: @foo.init = internal constant ptr @foo, section ".init_array"
+; CHECK: @bar.fini = internal constant ptr @bar, section ".fini_array"
+; CHECK: @llvm.used = appending global [4 x ptr] [ptr @foo.init, ptr @amdgcn.device.init, ptr @bar.fini, ptr @amdgcn.device.fini]
; CHECK-LABEL: amdgpu_kernel void @amdgcn.device.init() #0
; CHECK-NEXT: call void @foo
Index: llvm/lib/Target/AMDGPU/AMDGPUCtorDtorLowering.cpp
===================================================================
--- llvm/lib/Target/AMDGPU/AMDGPUCtorDtorLowering.cpp
+++ llvm/lib/Target/AMDGPU/AMDGPUCtorDtorLowering.cpp
@@ -63,6 +63,13 @@
for (Value *V : GA->operands()) {
auto *CS = cast<ConstantStruct>(V);
+ if (auto *F = dyn_cast<Function>(CS->getOperand(1))) {
+ auto *GV = new GlobalVariable(
+ M, F->getType(), /*IsConstant=*/true, GlobalValue::InternalLinkage, F,
+ F->getName() + (IsCtor ? ".init" : ".fini"));
+ GV->setSection(IsCtor ? ".init_array" : ".fini_array");
+ appendToUsed(M, {GV});
+ }
IRB.CreateCall(ConstructorTy, CS->getOperand(1));
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D149340.517531.patch
Type: text/x-patch
Size: 1399 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230427/ed6e5569/attachment.bin>
More information about the llvm-commits
mailing list