1 | //===--- CGDeclCXX.cpp - Emit LLVM Code for C++ declarations --------------===// |
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 | // This contains code dealing with code generation of C++ declarations |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "CGCXXABI.h" |
14 | #include "CGHLSLRuntime.h" |
15 | #include "CGObjCRuntime.h" |
16 | #include "CGOpenMPRuntime.h" |
17 | #include "CodeGenFunction.h" |
18 | #include "TargetInfo.h" |
19 | #include "clang/AST/Attr.h" |
20 | #include "clang/Basic/LangOptions.h" |
21 | #include "llvm/ADT/StringExtras.h" |
22 | #include "llvm/IR/Intrinsics.h" |
23 | #include "llvm/IR/MDBuilder.h" |
24 | #include "llvm/Support/Path.h" |
25 | |
26 | using namespace clang; |
27 | using namespace CodeGen; |
28 | |
29 | static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D, |
30 | ConstantAddress DeclPtr) { |
31 | assert( |
32 | (D.hasGlobalStorage() || |
33 | (D.hasLocalStorage() && CGF.getContext().getLangOpts().OpenCLCPlusPlus)) && |
34 | "VarDecl must have global or local (in the case of OpenCL) storage!" ); |
35 | assert(!D.getType()->isReferenceType() && |
36 | "Should not call EmitDeclInit on a reference!" ); |
37 | |
38 | QualType type = D.getType(); |
39 | LValue lv = CGF.MakeAddrLValue(Addr: DeclPtr, T: type); |
40 | |
41 | const Expr *Init = D.getInit(); |
42 | switch (CGF.getEvaluationKind(T: type)) { |
43 | case TEK_Scalar: { |
44 | CodeGenModule &CGM = CGF.CGM; |
45 | if (lv.isObjCStrong()) |
46 | CGM.getObjCRuntime().EmitObjCGlobalAssign(CGF, src: CGF.EmitScalarExpr(E: Init), |
47 | dest: DeclPtr, threadlocal: D.getTLSKind()); |
48 | else if (lv.isObjCWeak()) |
49 | CGM.getObjCRuntime().EmitObjCWeakAssign(CGF, src: CGF.EmitScalarExpr(E: Init), |
50 | dest: DeclPtr); |
51 | else |
52 | CGF.EmitScalarInit(Init, &D, lv, false); |
53 | return; |
54 | } |
55 | case TEK_Complex: |
56 | CGF.EmitComplexExprIntoLValue(E: Init, dest: lv, /*isInit*/ true); |
57 | return; |
58 | case TEK_Aggregate: |
59 | CGF.EmitAggExpr(E: Init, |
60 | AS: AggValueSlot::forLValue(LV: lv, CGF, isDestructed: AggValueSlot::IsDestructed, |
61 | needsGC: AggValueSlot::DoesNotNeedGCBarriers, |
62 | isAliased: AggValueSlot::IsNotAliased, |
63 | mayOverlap: AggValueSlot::DoesNotOverlap)); |
64 | return; |
65 | } |
66 | llvm_unreachable("bad evaluation kind" ); |
67 | } |
68 | |
69 | /// Emit code to cause the destruction of the given variable with |
70 | /// static storage duration. |
71 | static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, |
72 | ConstantAddress Addr) { |
73 | // Honor __attribute__((no_destroy)) and bail instead of attempting |
74 | // to emit a reference to a possibly nonexistent destructor, which |
75 | // in turn can cause a crash. This will result in a global constructor |
76 | // that isn't balanced out by a destructor call as intended by the |
77 | // attribute. This also checks for -fno-c++-static-destructors and |
78 | // bails even if the attribute is not present. |
79 | QualType::DestructionKind DtorKind = D.needsDestruction(Ctx: CGF.getContext()); |
80 | |
81 | // FIXME: __attribute__((cleanup)) ? |
82 | |
83 | switch (DtorKind) { |
84 | case QualType::DK_none: |
85 | return; |
86 | |
87 | case QualType::DK_cxx_destructor: |
88 | break; |
89 | |
90 | case QualType::DK_objc_strong_lifetime: |
91 | case QualType::DK_objc_weak_lifetime: |
92 | case QualType::DK_nontrivial_c_struct: |
93 | // We don't care about releasing objects during process teardown. |
94 | assert(!D.getTLSKind() && "should have rejected this" ); |
95 | return; |
96 | } |
97 | |
98 | llvm::FunctionCallee Func; |
99 | llvm::Constant *Argument; |
100 | |
101 | CodeGenModule &CGM = CGF.CGM; |
102 | QualType Type = D.getType(); |
103 | |
104 | // Special-case non-array C++ destructors, if they have the right signature. |
105 | // Under some ABIs, destructors return this instead of void, and cannot be |
106 | // passed directly to __cxa_atexit if the target does not allow this |
107 | // mismatch. |
108 | const CXXRecordDecl *Record = Type->getAsCXXRecordDecl(); |
109 | bool CanRegisterDestructor = |
110 | Record && (!CGM.getCXXABI().HasThisReturn( |
111 | GD: GlobalDecl(Record->getDestructor(), Dtor_Complete)) || |
112 | CGM.getCXXABI().canCallMismatchedFunctionType()); |
113 | // If __cxa_atexit is disabled via a flag, a different helper function is |
114 | // generated elsewhere which uses atexit instead, and it takes the destructor |
115 | // directly. |
116 | bool UsingExternalHelper = !CGM.getCodeGenOpts().CXAAtExit; |
117 | if (Record && (CanRegisterDestructor || UsingExternalHelper)) { |
118 | assert(!Record->hasTrivialDestructor()); |
119 | CXXDestructorDecl *Dtor = Record->getDestructor(); |
120 | |
121 | Func = CGM.getAddrAndTypeOfCXXStructor(GD: GlobalDecl(Dtor, Dtor_Complete)); |
122 | if (CGF.getContext().getLangOpts().OpenCL) { |
123 | auto DestAS = |
124 | CGM.getTargetCodeGenInfo().getAddrSpaceOfCxaAtexitPtrParam(); |
125 | auto DestTy = llvm::PointerType::get( |
126 | C&: CGM.getLLVMContext(), AddressSpace: CGM.getContext().getTargetAddressSpace(AS: DestAS)); |
127 | auto SrcAS = D.getType().getQualifiers().getAddressSpace(); |
128 | if (DestAS == SrcAS) |
129 | Argument = Addr.getPointer(); |
130 | else |
131 | // FIXME: On addr space mismatch we are passing NULL. The generation |
132 | // of the global destructor function should be adjusted accordingly. |
133 | Argument = llvm::ConstantPointerNull::get(T: DestTy); |
134 | } else { |
135 | Argument = Addr.getPointer(); |
136 | } |
137 | // Otherwise, the standard logic requires a helper function. |
138 | } else { |
139 | Addr = Addr.withElementType(ElemTy: CGF.ConvertTypeForMem(T: Type)); |
140 | Func = CodeGenFunction(CGM) |
141 | .generateDestroyHelper(addr: Addr, type: Type, destroyer: CGF.getDestroyer(destructionKind: DtorKind), |
142 | useEHCleanupForArray: CGF.needsEHCleanup(kind: DtorKind), VD: &D); |
143 | Argument = llvm::Constant::getNullValue(Ty: CGF.Int8PtrTy); |
144 | } |
145 | |
146 | CGM.getCXXABI().registerGlobalDtor(CGF, D, Dtor: Func, Addr: Argument); |
147 | } |
148 | |
149 | /// Emit code to cause the variable at the given address to be considered as |
150 | /// constant from this point onwards. |
151 | static void EmitDeclInvariant(CodeGenFunction &CGF, const VarDecl &D, |
152 | llvm::Constant *Addr) { |
153 | return CGF.EmitInvariantStart( |
154 | Addr, Size: CGF.getContext().getTypeSizeInChars(D.getType())); |
155 | } |
156 | |
157 | void CodeGenFunction::EmitInvariantStart(llvm::Constant *Addr, CharUnits Size) { |
158 | // Do not emit the intrinsic if we're not optimizing. |
159 | if (!CGM.getCodeGenOpts().OptimizationLevel) |
160 | return; |
161 | |
162 | // Grab the llvm.invariant.start intrinsic. |
163 | llvm::Intrinsic::ID InvStartID = llvm::Intrinsic::invariant_start; |
164 | // Overloaded address space type. |
165 | llvm::Type *ObjectPtr[1] = {Int8PtrTy}; |
166 | llvm::Function *InvariantStart = CGM.getIntrinsic(IID: InvStartID, Tys: ObjectPtr); |
167 | |
168 | // Emit a call with the size in bytes of the object. |
169 | uint64_t Width = Size.getQuantity(); |
170 | llvm::Value *Args[2] = {llvm::ConstantInt::getSigned(Ty: Int64Ty, V: Width), Addr}; |
171 | Builder.CreateCall(Callee: InvariantStart, Args); |
172 | } |
173 | |
174 | void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D, |
175 | llvm::GlobalVariable *GV, |
176 | bool PerformInit) { |
177 | |
178 | const Expr *Init = D.getInit(); |
179 | QualType T = D.getType(); |
180 | |
181 | // The address space of a static local variable (DeclPtr) may be different |
182 | // from the address space of the "this" argument of the constructor. In that |
183 | // case, we need an addrspacecast before calling the constructor. |
184 | // |
185 | // struct StructWithCtor { |
186 | // __device__ StructWithCtor() {...} |
187 | // }; |
188 | // __device__ void foo() { |
189 | // __shared__ StructWithCtor s; |
190 | // ... |
191 | // } |
192 | // |
193 | // For example, in the above CUDA code, the static local variable s has a |
194 | // "shared" address space qualifier, but the constructor of StructWithCtor |
195 | // expects "this" in the "generic" address space. |
196 | unsigned ExpectedAddrSpace = getTypes().getTargetAddressSpace(T); |
197 | unsigned ActualAddrSpace = GV->getAddressSpace(); |
198 | llvm::Constant *DeclPtr = GV; |
199 | if (ActualAddrSpace != ExpectedAddrSpace) { |
200 | llvm::PointerType *PTy = |
201 | llvm::PointerType::get(C&: getLLVMContext(), AddressSpace: ExpectedAddrSpace); |
202 | DeclPtr = llvm::ConstantExpr::getAddrSpaceCast(C: DeclPtr, Ty: PTy); |
203 | } |
204 | |
205 | ConstantAddress DeclAddr( |
206 | DeclPtr, GV->getValueType(), getContext().getDeclAlign(&D)); |
207 | |
208 | if (!T->isReferenceType()) { |
209 | if (getLangOpts().OpenMP && !getLangOpts().OpenMPSimd && |
210 | D.hasAttr<OMPThreadPrivateDeclAttr>()) { |
211 | (void)CGM.getOpenMPRuntime().emitThreadPrivateVarDefinition( |
212 | &D, DeclAddr, D.getAttr<OMPThreadPrivateDeclAttr>()->getLocation(), |
213 | PerformInit, this); |
214 | } |
215 | bool NeedsDtor = |
216 | D.needsDestruction(Ctx: getContext()) == QualType::DK_cxx_destructor; |
217 | if (PerformInit) |
218 | EmitDeclInit(CGF&: *this, D, DeclPtr: DeclAddr); |
219 | if (D.getType().isConstantStorage(getContext(), true, !NeedsDtor)) |
220 | EmitDeclInvariant(CGF&: *this, D, Addr: DeclPtr); |
221 | else |
222 | EmitDeclDestroy(CGF&: *this, D, Addr: DeclAddr); |
223 | return; |
224 | } |
225 | |
226 | assert(PerformInit && "cannot have constant initializer which needs " |
227 | "destruction for reference" ); |
228 | RValue RV = EmitReferenceBindingToExpr(E: Init); |
229 | EmitStoreOfScalar(Value: RV.getScalarVal(), Addr: DeclAddr, Volatile: false, Ty: T); |
230 | } |
231 | |
232 | /// Create a stub function, suitable for being passed to atexit, |
233 | /// which passes the given address to the given destructor function. |
234 | llvm::Function *CodeGenFunction::createAtExitStub(const VarDecl &VD, |
235 | llvm::FunctionCallee dtor, |
236 | llvm::Constant *addr) { |
237 | // Get the destructor function type, void(*)(void). |
238 | llvm::FunctionType *ty = llvm::FunctionType::get(Result: CGM.VoidTy, isVarArg: false); |
239 | SmallString<256> FnName; |
240 | { |
241 | llvm::raw_svector_ostream Out(FnName); |
242 | CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(D: &VD, Out); |
243 | } |
244 | |
245 | const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction(); |
246 | llvm::Function *fn = CGM.CreateGlobalInitOrCleanUpFunction( |
247 | ty, name: FnName.str(), FI, Loc: VD.getLocation()); |
248 | |
249 | CodeGenFunction CGF(CGM); |
250 | |
251 | CGF.StartFunction(GD: GlobalDecl(&VD, DynamicInitKind::AtExit), |
252 | RetTy: CGM.getContext().VoidTy, Fn: fn, FnInfo: FI, Args: FunctionArgList(), |
253 | Loc: VD.getLocation(), StartLoc: VD.getInit()->getExprLoc()); |
254 | // Emit an artificial location for this function. |
255 | auto AL = ApplyDebugLocation::CreateArtificial(CGF); |
256 | |
257 | llvm::CallInst *call = CGF.Builder.CreateCall(Callee: dtor, Args: addr); |
258 | |
259 | // Make sure the call and the callee agree on calling convention. |
260 | if (auto *dtorFn = dyn_cast<llvm::Function>( |
261 | Val: dtor.getCallee()->stripPointerCastsAndAliases())) |
262 | call->setCallingConv(dtorFn->getCallingConv()); |
263 | |
264 | CGF.FinishFunction(); |
265 | |
266 | return fn; |
267 | } |
268 | |
269 | /// Create a stub function, suitable for being passed to __pt_atexit_np, |
270 | /// which passes the given address to the given destructor function. |
271 | llvm::Function *CodeGenFunction::createTLSAtExitStub( |
272 | const VarDecl &D, llvm::FunctionCallee Dtor, llvm::Constant *Addr, |
273 | llvm::FunctionCallee &AtExit) { |
274 | SmallString<256> FnName; |
275 | { |
276 | llvm::raw_svector_ostream Out(FnName); |
277 | CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(D: &D, Out); |
278 | } |
279 | |
280 | const CGFunctionInfo &FI = CGM.getTypes().arrangeLLVMFunctionInfo( |
281 | returnType: getContext().IntTy, opts: FnInfoOpts::None, argTypes: {getContext().IntTy}, |
282 | info: FunctionType::ExtInfo(), paramInfos: {}, args: RequiredArgs::All); |
283 | |
284 | // Get the stub function type, int(*)(int,...). |
285 | llvm::FunctionType *StubTy = |
286 | llvm::FunctionType::get(Result: CGM.IntTy, Params: {CGM.IntTy}, isVarArg: true); |
287 | |
288 | llvm::Function *DtorStub = CGM.CreateGlobalInitOrCleanUpFunction( |
289 | ty: StubTy, name: FnName.str(), FI, Loc: D.getLocation()); |
290 | |
291 | CodeGenFunction CGF(CGM); |
292 | |
293 | FunctionArgList Args; |
294 | ImplicitParamDecl IPD(CGM.getContext(), CGM.getContext().IntTy, |
295 | ImplicitParamKind::Other); |
296 | Args.push_back(&IPD); |
297 | QualType ResTy = CGM.getContext().IntTy; |
298 | |
299 | CGF.StartFunction(GD: GlobalDecl(&D, DynamicInitKind::AtExit), RetTy: ResTy, Fn: DtorStub, |
300 | FnInfo: FI, Args, Loc: D.getLocation(), StartLoc: D.getInit()->getExprLoc()); |
301 | |
302 | // Emit an artificial location for this function. |
303 | auto AL = ApplyDebugLocation::CreateArtificial(CGF); |
304 | |
305 | llvm::CallInst *call = CGF.Builder.CreateCall(Callee: Dtor, Args: Addr); |
306 | |
307 | // Make sure the call and the callee agree on calling convention. |
308 | if (auto *DtorFn = dyn_cast<llvm::Function>( |
309 | Val: Dtor.getCallee()->stripPointerCastsAndAliases())) |
310 | call->setCallingConv(DtorFn->getCallingConv()); |
311 | |
312 | // Return 0 from function |
313 | CGF.Builder.CreateStore(Val: llvm::Constant::getNullValue(Ty: CGM.IntTy), |
314 | Addr: CGF.ReturnValue); |
315 | |
316 | CGF.FinishFunction(); |
317 | |
318 | return DtorStub; |
319 | } |
320 | |
321 | /// Register a global destructor using the C atexit runtime function. |
322 | void CodeGenFunction::registerGlobalDtorWithAtExit(const VarDecl &VD, |
323 | llvm::FunctionCallee dtor, |
324 | llvm::Constant *addr) { |
325 | // Create a function which calls the destructor. |
326 | llvm::Constant *dtorStub = createAtExitStub(VD, dtor, addr); |
327 | registerGlobalDtorWithAtExit(dtorStub); |
328 | } |
329 | |
330 | /// Register a global destructor using the LLVM 'llvm.global_dtors' global. |
331 | void CodeGenFunction::registerGlobalDtorWithLLVM(const VarDecl &VD, |
332 | llvm::FunctionCallee Dtor, |
333 | llvm::Constant *Addr) { |
334 | // Create a function which calls the destructor. |
335 | llvm::Function *dtorStub = createAtExitStub(VD, dtor: Dtor, addr: Addr); |
336 | CGM.AddGlobalDtor(Dtor: dtorStub); |
337 | } |
338 | |
339 | void CodeGenFunction::registerGlobalDtorWithAtExit(llvm::Constant *dtorStub) { |
340 | // extern "C" int atexit(void (*f)(void)); |
341 | assert(dtorStub->getType() == |
342 | llvm::PointerType::get( |
343 | llvm::FunctionType::get(CGM.VoidTy, false), |
344 | dtorStub->getType()->getPointerAddressSpace()) && |
345 | "Argument to atexit has a wrong type." ); |
346 | |
347 | llvm::FunctionType *atexitTy = |
348 | llvm::FunctionType::get(Result: IntTy, Params: dtorStub->getType(), isVarArg: false); |
349 | |
350 | llvm::FunctionCallee atexit = |
351 | CGM.CreateRuntimeFunction(Ty: atexitTy, Name: "atexit" , ExtraAttrs: llvm::AttributeList(), |
352 | /*Local=*/true); |
353 | if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(Val: atexit.getCallee())) |
354 | atexitFn->setDoesNotThrow(); |
355 | |
356 | EmitNounwindRuntimeCall(callee: atexit, args: dtorStub); |
357 | } |
358 | |
359 | llvm::Value * |
360 | CodeGenFunction::unregisterGlobalDtorWithUnAtExit(llvm::Constant *dtorStub) { |
361 | // The unatexit subroutine unregisters __dtor functions that were previously |
362 | // registered by the atexit subroutine. If the referenced function is found, |
363 | // it is removed from the list of functions that are called at normal program |
364 | // termination and the unatexit returns a value of 0, otherwise a non-zero |
365 | // value is returned. |
366 | // |
367 | // extern "C" int unatexit(void (*f)(void)); |
368 | assert(dtorStub->getType() == |
369 | llvm::PointerType::get( |
370 | llvm::FunctionType::get(CGM.VoidTy, false), |
371 | dtorStub->getType()->getPointerAddressSpace()) && |
372 | "Argument to unatexit has a wrong type." ); |
373 | |
374 | llvm::FunctionType *unatexitTy = |
375 | llvm::FunctionType::get(Result: IntTy, Params: {dtorStub->getType()}, /*isVarArg=*/false); |
376 | |
377 | llvm::FunctionCallee unatexit = |
378 | CGM.CreateRuntimeFunction(Ty: unatexitTy, Name: "unatexit" , ExtraAttrs: llvm::AttributeList()); |
379 | |
380 | cast<llvm::Function>(Val: unatexit.getCallee())->setDoesNotThrow(); |
381 | |
382 | return EmitNounwindRuntimeCall(callee: unatexit, args: dtorStub); |
383 | } |
384 | |
385 | void CodeGenFunction::EmitCXXGuardedInit(const VarDecl &D, |
386 | llvm::GlobalVariable *DeclPtr, |
387 | bool PerformInit) { |
388 | // If we've been asked to forbid guard variables, emit an error now. |
389 | // This diagnostic is hard-coded for Darwin's use case; we can find |
390 | // better phrasing if someone else needs it. |
391 | if (CGM.getCodeGenOpts().ForbidGuardVariables) |
392 | CGM.Error(loc: D.getLocation(), |
393 | error: "this initialization requires a guard variable, which " |
394 | "the kernel does not support" ); |
395 | |
396 | CGM.getCXXABI().EmitGuardedInit(CGF&: *this, D, DeclPtr, PerformInit); |
397 | } |
398 | |
399 | void CodeGenFunction::EmitCXXGuardedInitBranch(llvm::Value *NeedsInit, |
400 | llvm::BasicBlock *InitBlock, |
401 | llvm::BasicBlock *NoInitBlock, |
402 | GuardKind Kind, |
403 | const VarDecl *D) { |
404 | assert((Kind == GuardKind::TlsGuard || D) && "no guarded variable" ); |
405 | |
406 | // A guess at how many times we will enter the initialization of a |
407 | // variable, depending on the kind of variable. |
408 | static const uint64_t InitsPerTLSVar = 1024; |
409 | static const uint64_t InitsPerLocalVar = 1024 * 1024; |
410 | |
411 | llvm::MDNode *Weights; |
412 | if (Kind == GuardKind::VariableGuard && !D->isLocalVarDecl()) { |
413 | // For non-local variables, don't apply any weighting for now. Due to our |
414 | // use of COMDATs, we expect there to be at most one initialization of the |
415 | // variable per DSO, but we have no way to know how many DSOs will try to |
416 | // initialize the variable. |
417 | Weights = nullptr; |
418 | } else { |
419 | uint64_t NumInits; |
420 | // FIXME: For the TLS case, collect and use profiling information to |
421 | // determine a more accurate brach weight. |
422 | if (Kind == GuardKind::TlsGuard || D->getTLSKind()) |
423 | NumInits = InitsPerTLSVar; |
424 | else |
425 | NumInits = InitsPerLocalVar; |
426 | |
427 | // The probability of us entering the initializer is |
428 | // 1 / (total number of times we attempt to initialize the variable). |
429 | llvm::MDBuilder MDHelper(CGM.getLLVMContext()); |
430 | Weights = MDHelper.createBranchWeights(TrueWeight: 1, FalseWeight: NumInits - 1); |
431 | } |
432 | |
433 | Builder.CreateCondBr(Cond: NeedsInit, True: InitBlock, False: NoInitBlock, BranchWeights: Weights); |
434 | } |
435 | |
436 | llvm::Function *CodeGenModule::CreateGlobalInitOrCleanUpFunction( |
437 | llvm::FunctionType *FTy, const Twine &Name, const CGFunctionInfo &FI, |
438 | SourceLocation Loc, bool TLS, llvm::GlobalVariable::LinkageTypes Linkage) { |
439 | llvm::Function *Fn = llvm::Function::Create(Ty: FTy, Linkage, N: Name, M: &getModule()); |
440 | |
441 | if (!getLangOpts().AppleKext && !TLS) { |
442 | // Set the section if needed. |
443 | if (const char *Section = getTarget().getStaticInitSectionSpecifier()) |
444 | Fn->setSection(Section); |
445 | } |
446 | |
447 | if (Linkage == llvm::GlobalVariable::InternalLinkage) |
448 | SetInternalFunctionAttributes(GD: GlobalDecl(), F: Fn, FI); |
449 | |
450 | Fn->setCallingConv(getRuntimeCC()); |
451 | |
452 | if (!getLangOpts().Exceptions) |
453 | Fn->setDoesNotThrow(); |
454 | |
455 | if (getLangOpts().Sanitize.has(SanitizerKind::Address) && |
456 | !isInNoSanitizeList(SanitizerKind::Address, Fn, Loc)) |
457 | Fn->addFnAttr(llvm::Attribute::SanitizeAddress); |
458 | |
459 | if (getLangOpts().Sanitize.has(SanitizerKind::KernelAddress) && |
460 | !isInNoSanitizeList(SanitizerKind::KernelAddress, Fn, Loc)) |
461 | Fn->addFnAttr(llvm::Attribute::SanitizeAddress); |
462 | |
463 | if (getLangOpts().Sanitize.has(SanitizerKind::HWAddress) && |
464 | !isInNoSanitizeList(SanitizerKind::HWAddress, Fn, Loc)) |
465 | Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress); |
466 | |
467 | if (getLangOpts().Sanitize.has(SanitizerKind::KernelHWAddress) && |
468 | !isInNoSanitizeList(SanitizerKind::KernelHWAddress, Fn, Loc)) |
469 | Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress); |
470 | |
471 | if (getLangOpts().Sanitize.has(SanitizerKind::MemtagStack) && |
472 | !isInNoSanitizeList(SanitizerKind::MemtagStack, Fn, Loc)) |
473 | Fn->addFnAttr(llvm::Attribute::SanitizeMemTag); |
474 | |
475 | if (getLangOpts().Sanitize.has(SanitizerKind::Thread) && |
476 | !isInNoSanitizeList(SanitizerKind::Thread, Fn, Loc)) |
477 | Fn->addFnAttr(llvm::Attribute::SanitizeThread); |
478 | |
479 | if (getLangOpts().Sanitize.has(SanitizerKind::Memory) && |
480 | !isInNoSanitizeList(SanitizerKind::Memory, Fn, Loc)) |
481 | Fn->addFnAttr(llvm::Attribute::SanitizeMemory); |
482 | |
483 | if (getLangOpts().Sanitize.has(SanitizerKind::KernelMemory) && |
484 | !isInNoSanitizeList(SanitizerKind::KernelMemory, Fn, Loc)) |
485 | Fn->addFnAttr(llvm::Attribute::SanitizeMemory); |
486 | |
487 | if (getLangOpts().Sanitize.has(SanitizerKind::SafeStack) && |
488 | !isInNoSanitizeList(SanitizerKind::SafeStack, Fn, Loc)) |
489 | Fn->addFnAttr(llvm::Attribute::SafeStack); |
490 | |
491 | if (getLangOpts().Sanitize.has(SanitizerKind::ShadowCallStack) && |
492 | !isInNoSanitizeList(SanitizerKind::ShadowCallStack, Fn, Loc)) |
493 | Fn->addFnAttr(llvm::Attribute::ShadowCallStack); |
494 | |
495 | return Fn; |
496 | } |
497 | |
498 | /// Create a global pointer to a function that will initialize a global |
499 | /// variable. The user has requested that this pointer be emitted in a specific |
500 | /// section. |
501 | void CodeGenModule::EmitPointerToInitFunc(const VarDecl *D, |
502 | llvm::GlobalVariable *GV, |
503 | llvm::Function *InitFunc, |
504 | InitSegAttr *ISA) { |
505 | llvm::GlobalVariable *PtrArray = new llvm::GlobalVariable( |
506 | TheModule, InitFunc->getType(), /*isConstant=*/true, |
507 | llvm::GlobalValue::PrivateLinkage, InitFunc, "__cxx_init_fn_ptr" ); |
508 | PtrArray->setSection(ISA->getSection()); |
509 | addUsedGlobal(GV: PtrArray); |
510 | |
511 | // If the GV is already in a comdat group, then we have to join it. |
512 | if (llvm::Comdat *C = GV->getComdat()) |
513 | PtrArray->setComdat(C); |
514 | } |
515 | |
516 | void |
517 | CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D, |
518 | llvm::GlobalVariable *Addr, |
519 | bool PerformInit) { |
520 | |
521 | // According to E.2.3.1 in CUDA-7.5 Programming guide: __device__, |
522 | // __constant__ and __shared__ variables defined in namespace scope, |
523 | // that are of class type, cannot have a non-empty constructor. All |
524 | // the checks have been done in Sema by now. Whatever initializers |
525 | // are allowed are empty and we just need to ignore them here. |
526 | if (getLangOpts().CUDAIsDevice && !getLangOpts().GPUAllowDeviceInit && |
527 | (D->hasAttr<CUDADeviceAttr>() || D->hasAttr<CUDAConstantAttr>() || |
528 | D->hasAttr<CUDASharedAttr>())) |
529 | return; |
530 | |
531 | // Check if we've already initialized this decl. |
532 | auto I = DelayedCXXInitPosition.find(D); |
533 | if (I != DelayedCXXInitPosition.end() && I->second == ~0U) |
534 | return; |
535 | |
536 | llvm::FunctionType *FTy = llvm::FunctionType::get(Result: VoidTy, isVarArg: false); |
537 | SmallString<256> FnName; |
538 | { |
539 | llvm::raw_svector_ostream Out(FnName); |
540 | getCXXABI().getMangleContext().mangleDynamicInitializer(D, Out); |
541 | } |
542 | |
543 | // Create a variable initialization function. |
544 | llvm::Function *Fn = CreateGlobalInitOrCleanUpFunction( |
545 | FTy, Name: FnName.str(), FI: getTypes().arrangeNullaryFunction(), Loc: D->getLocation()); |
546 | |
547 | auto *ISA = D->getAttr<InitSegAttr>(); |
548 | CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr, |
549 | PerformInit); |
550 | |
551 | llvm::GlobalVariable *COMDATKey = |
552 | supportsCOMDAT() && D->isExternallyVisible() ? Addr : nullptr; |
553 | |
554 | if (D->getTLSKind()) { |
555 | // FIXME: Should we support init_priority for thread_local? |
556 | // FIXME: We only need to register one __cxa_thread_atexit function for the |
557 | // entire TU. |
558 | CXXThreadLocalInits.push_back(x: Fn); |
559 | CXXThreadLocalInitVars.push_back(x: D); |
560 | } else if (PerformInit && ISA) { |
561 | // Contract with backend that "init_seg(compiler)" corresponds to priority |
562 | // 200 and "init_seg(lib)" corresponds to priority 400. |
563 | int Priority = -1; |
564 | if (ISA->getSection() == ".CRT$XCC" ) |
565 | Priority = 200; |
566 | else if (ISA->getSection() == ".CRT$XCL" ) |
567 | Priority = 400; |
568 | |
569 | if (Priority != -1) |
570 | AddGlobalCtor(Ctor: Fn, Priority, LexOrder: ~0U, AssociatedData: COMDATKey); |
571 | else |
572 | EmitPointerToInitFunc(D, GV: Addr, InitFunc: Fn, ISA: ISA); |
573 | } else if (auto *IPA = D->getAttr<InitPriorityAttr>()) { |
574 | OrderGlobalInitsOrStermFinalizers Key(IPA->getPriority(), |
575 | PrioritizedCXXGlobalInits.size()); |
576 | PrioritizedCXXGlobalInits.push_back(Elt: std::make_pair(x&: Key, y&: Fn)); |
577 | } else if (isTemplateInstantiation(D->getTemplateSpecializationKind()) || |
578 | getContext().GetGVALinkageForVariable(D) == GVA_DiscardableODR || |
579 | D->hasAttr<SelectAnyAttr>()) { |
580 | // C++ [basic.start.init]p2: |
581 | // Definitions of explicitly specialized class template static data |
582 | // members have ordered initialization. Other class template static data |
583 | // members (i.e., implicitly or explicitly instantiated specializations) |
584 | // have unordered initialization. |
585 | // |
586 | // As a consequence, we can put them into their own llvm.global_ctors entry. |
587 | // |
588 | // If the global is externally visible, put the initializer into a COMDAT |
589 | // group with the global being initialized. On most platforms, this is a |
590 | // minor startup time optimization. In the MS C++ ABI, there are no guard |
591 | // variables, so this COMDAT key is required for correctness. |
592 | // |
593 | // SelectAny globals will be comdat-folded. Put the initializer into a |
594 | // COMDAT group associated with the global, so the initializers get folded |
595 | // too. |
596 | I = DelayedCXXInitPosition.find(D); |
597 | // CXXGlobalInits.size() is the lex order number for the next deferred |
598 | // VarDecl. Use it when the current VarDecl is non-deferred. Although this |
599 | // lex order number is shared between current VarDecl and some following |
600 | // VarDecls, their order of insertion into `llvm.global_ctors` is the same |
601 | // as the lexing order and the following stable sort would preserve such |
602 | // order. |
603 | unsigned LexOrder = |
604 | I == DelayedCXXInitPosition.end() ? CXXGlobalInits.size() : I->second; |
605 | AddGlobalCtor(Ctor: Fn, Priority: 65535, LexOrder, AssociatedData: COMDATKey); |
606 | if (COMDATKey && (getTriple().isOSBinFormatELF() || |
607 | getTarget().getCXXABI().isMicrosoft())) { |
608 | // When COMDAT is used on ELF or in the MS C++ ABI, the key must be in |
609 | // llvm.used to prevent linker GC. |
610 | addUsedGlobal(GV: COMDATKey); |
611 | } |
612 | |
613 | // If we used a COMDAT key for the global ctor, the init function can be |
614 | // discarded if the global ctor entry is discarded. |
615 | // FIXME: Do we need to restrict this to ELF and Wasm? |
616 | llvm::Comdat *C = Addr->getComdat(); |
617 | if (COMDATKey && C && |
618 | (getTarget().getTriple().isOSBinFormatELF() || |
619 | getTarget().getTriple().isOSBinFormatWasm())) { |
620 | Fn->setComdat(C); |
621 | } |
622 | } else { |
623 | I = DelayedCXXInitPosition.find(D); // Re-do lookup in case of re-hash. |
624 | if (I == DelayedCXXInitPosition.end()) { |
625 | CXXGlobalInits.push_back(x: Fn); |
626 | } else if (I->second != ~0U) { |
627 | assert(I->second < CXXGlobalInits.size() && |
628 | CXXGlobalInits[I->second] == nullptr); |
629 | CXXGlobalInits[I->second] = Fn; |
630 | } |
631 | } |
632 | |
633 | // Remember that we already emitted the initializer for this global. |
634 | DelayedCXXInitPosition[D] = ~0U; |
635 | } |
636 | |
637 | void CodeGenModule::EmitCXXThreadLocalInitFunc() { |
638 | getCXXABI().EmitThreadLocalInitFuncs( |
639 | CGM&: *this, CXXThreadLocals, CXXThreadLocalInits, CXXThreadLocalInitVars); |
640 | |
641 | CXXThreadLocalInits.clear(); |
642 | CXXThreadLocalInitVars.clear(); |
643 | CXXThreadLocals.clear(); |
644 | } |
645 | |
646 | /* Build the initializer for a C++20 module: |
647 | This is arranged to be run only once regardless of how many times the module |
648 | might be included transitively. This arranged by using a guard variable. |
649 | |
650 | If there are no initializers at all (and also no imported modules) we reduce |
651 | this to an empty function (since the Itanium ABI requires that this function |
652 | be available to a caller, which might be produced by a different |
653 | implementation). |
654 | |
655 | First we call any initializers for imported modules. |
656 | We then call initializers for the Global Module Fragment (if present) |
657 | We then call initializers for the current module. |
658 | We then call initializers for the Private Module Fragment (if present) |
659 | */ |
660 | |
661 | void CodeGenModule::EmitCXXModuleInitFunc(Module *Primary) { |
662 | assert(Primary->isInterfaceOrPartition() && |
663 | "The function should only be called for C++20 named module interface" |
664 | " or partition." ); |
665 | |
666 | while (!CXXGlobalInits.empty() && !CXXGlobalInits.back()) |
667 | CXXGlobalInits.pop_back(); |
668 | |
669 | // As noted above, we create the function, even if it is empty. |
670 | // Module initializers for imported modules are emitted first. |
671 | |
672 | // Collect all the modules that we import |
673 | llvm::SmallSetVector<Module *, 8> AllImports; |
674 | // Ones that we export |
675 | for (auto I : Primary->Exports) |
676 | AllImports.insert(X: I.getPointer()); |
677 | // Ones that we only import. |
678 | for (Module *M : Primary->Imports) |
679 | AllImports.insert(X: M); |
680 | // Ones that we import in the global module fragment or the private module |
681 | // fragment. |
682 | for (Module *SubM : Primary->submodules()) { |
683 | assert((SubM->isGlobalModule() || SubM->isPrivateModule()) && |
684 | "The sub modules of C++20 module unit should only be global module " |
685 | "fragments or private module framents." ); |
686 | assert(SubM->Exports.empty() && |
687 | "The global mdoule fragments and the private module fragments are " |
688 | "not allowed to export import modules." ); |
689 | for (Module *M : SubM->Imports) |
690 | AllImports.insert(X: M); |
691 | } |
692 | |
693 | SmallVector<llvm::Function *, 8> ModuleInits; |
694 | for (Module *M : AllImports) { |
695 | // No Itanium initializer in header like modules. |
696 | if (M->isHeaderLikeModule()) |
697 | continue; // TODO: warn of mixed use of module map modules and C++20? |
698 | // We're allowed to skip the initialization if we are sure it doesn't |
699 | // do any thing. |
700 | if (!M->isNamedModuleInterfaceHasInit()) |
701 | continue; |
702 | llvm::FunctionType *FTy = llvm::FunctionType::get(Result: VoidTy, isVarArg: false); |
703 | SmallString<256> FnName; |
704 | { |
705 | llvm::raw_svector_ostream Out(FnName); |
706 | cast<ItaniumMangleContext>(Val&: getCXXABI().getMangleContext()) |
707 | .mangleModuleInitializer(Module: M, Out); |
708 | } |
709 | assert(!GetGlobalValue(FnName.str()) && |
710 | "We should only have one use of the initializer call" ); |
711 | llvm::Function *Fn = llvm::Function::Create( |
712 | Ty: FTy, Linkage: llvm::Function::ExternalLinkage, N: FnName.str(), M: &getModule()); |
713 | ModuleInits.push_back(Elt: Fn); |
714 | } |
715 | |
716 | // Add any initializers with specified priority; this uses the same approach |
717 | // as EmitCXXGlobalInitFunc(). |
718 | if (!PrioritizedCXXGlobalInits.empty()) { |
719 | SmallVector<llvm::Function *, 8> LocalCXXGlobalInits; |
720 | llvm::array_pod_sort(Start: PrioritizedCXXGlobalInits.begin(), |
721 | End: PrioritizedCXXGlobalInits.end()); |
722 | for (SmallVectorImpl<GlobalInitData>::iterator |
723 | I = PrioritizedCXXGlobalInits.begin(), |
724 | E = PrioritizedCXXGlobalInits.end(); |
725 | I != E;) { |
726 | SmallVectorImpl<GlobalInitData>::iterator PrioE = |
727 | std::upper_bound(first: I + 1, last: E, val: *I, comp: GlobalInitPriorityCmp()); |
728 | |
729 | for (; I < PrioE; ++I) |
730 | ModuleInits.push_back(Elt: I->second); |
731 | } |
732 | } |
733 | |
734 | // Now append the ones without specified priority. |
735 | for (auto *F : CXXGlobalInits) |
736 | ModuleInits.push_back(Elt: F); |
737 | |
738 | llvm::FunctionType *FTy = llvm::FunctionType::get(Result: VoidTy, isVarArg: false); |
739 | const CGFunctionInfo &FI = getTypes().arrangeNullaryFunction(); |
740 | |
741 | // We now build the initializer for this module, which has a mangled name |
742 | // as per the Itanium ABI . The action of the initializer is guarded so that |
743 | // each init is run just once (even though a module might be imported |
744 | // multiple times via nested use). |
745 | llvm::Function *Fn; |
746 | { |
747 | SmallString<256> InitFnName; |
748 | llvm::raw_svector_ostream Out(InitFnName); |
749 | cast<ItaniumMangleContext>(Val&: getCXXABI().getMangleContext()) |
750 | .mangleModuleInitializer(Module: Primary, Out); |
751 | Fn = CreateGlobalInitOrCleanUpFunction( |
752 | FTy, Name: llvm::Twine(InitFnName), FI, Loc: SourceLocation(), TLS: false, |
753 | Linkage: llvm::GlobalVariable::ExternalLinkage); |
754 | |
755 | // If we have a completely empty initializer then we do not want to create |
756 | // the guard variable. |
757 | ConstantAddress GuardAddr = ConstantAddress::invalid(); |
758 | if (!ModuleInits.empty()) { |
759 | // Create the guard var. |
760 | llvm::GlobalVariable *Guard = new llvm::GlobalVariable( |
761 | getModule(), Int8Ty, /*isConstant=*/false, |
762 | llvm::GlobalVariable::InternalLinkage, |
763 | llvm::ConstantInt::get(Ty: Int8Ty, V: 0), InitFnName.str() + "__in_chrg" ); |
764 | CharUnits GuardAlign = CharUnits::One(); |
765 | Guard->setAlignment(GuardAlign.getAsAlign()); |
766 | GuardAddr = ConstantAddress(Guard, Int8Ty, GuardAlign); |
767 | } |
768 | CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXThreadLocals: ModuleInits, |
769 | Guard: GuardAddr); |
770 | } |
771 | |
772 | // We allow for the case that a module object is added to a linked binary |
773 | // without a specific call to the the initializer. This also ensures that |
774 | // implementation partition initializers are called when the partition |
775 | // is not imported as an interface. |
776 | AddGlobalCtor(Ctor: Fn); |
777 | |
778 | // See the comment in EmitCXXGlobalInitFunc about OpenCL global init |
779 | // functions. |
780 | if (getLangOpts().OpenCL) { |
781 | GenKernelArgMetadata(FN: Fn); |
782 | Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL); |
783 | } |
784 | |
785 | assert(!getLangOpts().CUDA || !getLangOpts().CUDAIsDevice || |
786 | getLangOpts().GPUAllowDeviceInit); |
787 | if (getLangOpts().HIP && getLangOpts().CUDAIsDevice) { |
788 | Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL); |
789 | Fn->addFnAttr(Kind: "device-init" ); |
790 | } |
791 | |
792 | // We are done with the inits. |
793 | AllImports.clear(); |
794 | PrioritizedCXXGlobalInits.clear(); |
795 | CXXGlobalInits.clear(); |
796 | ModuleInits.clear(); |
797 | } |
798 | |
799 | static SmallString<128> getTransformedFileName(llvm::Module &M) { |
800 | SmallString<128> FileName = llvm::sys::path::filename(path: M.getName()); |
801 | |
802 | if (FileName.empty()) |
803 | FileName = "<null>" ; |
804 | |
805 | for (size_t i = 0; i < FileName.size(); ++i) { |
806 | // Replace everything that's not [a-zA-Z0-9._] with a _. This set happens |
807 | // to be the set of C preprocessing numbers. |
808 | if (!isPreprocessingNumberBody(c: FileName[i])) |
809 | FileName[i] = '_'; |
810 | } |
811 | |
812 | return FileName; |
813 | } |
814 | |
815 | static std::string getPrioritySuffix(unsigned int Priority) { |
816 | assert(Priority <= 65535 && "Priority should always be <= 65535." ); |
817 | |
818 | // Compute the function suffix from priority. Prepend with zeroes to make |
819 | // sure the function names are also ordered as priorities. |
820 | std::string PrioritySuffix = llvm::utostr(X: Priority); |
821 | PrioritySuffix = std::string(6 - PrioritySuffix.size(), '0') + PrioritySuffix; |
822 | |
823 | return PrioritySuffix; |
824 | } |
825 | |
826 | void |
827 | CodeGenModule::EmitCXXGlobalInitFunc() { |
828 | while (!CXXGlobalInits.empty() && !CXXGlobalInits.back()) |
829 | CXXGlobalInits.pop_back(); |
830 | |
831 | // When we import C++20 modules, we must run their initializers first. |
832 | SmallVector<llvm::Function *, 8> ModuleInits; |
833 | if (CXX20ModuleInits) |
834 | for (Module *M : ImportedModules) { |
835 | // No Itanium initializer in header like modules. |
836 | if (M->isHeaderLikeModule()) |
837 | continue; |
838 | llvm::FunctionType *FTy = llvm::FunctionType::get(Result: VoidTy, isVarArg: false); |
839 | SmallString<256> FnName; |
840 | { |
841 | llvm::raw_svector_ostream Out(FnName); |
842 | cast<ItaniumMangleContext>(Val&: getCXXABI().getMangleContext()) |
843 | .mangleModuleInitializer(Module: M, Out); |
844 | } |
845 | assert(!GetGlobalValue(FnName.str()) && |
846 | "We should only have one use of the initializer call" ); |
847 | llvm::Function *Fn = llvm::Function::Create( |
848 | Ty: FTy, Linkage: llvm::Function::ExternalLinkage, N: FnName.str(), M: &getModule()); |
849 | ModuleInits.push_back(Elt: Fn); |
850 | } |
851 | |
852 | if (ModuleInits.empty() && CXXGlobalInits.empty() && |
853 | PrioritizedCXXGlobalInits.empty()) |
854 | return; |
855 | |
856 | llvm::FunctionType *FTy = llvm::FunctionType::get(Result: VoidTy, isVarArg: false); |
857 | const CGFunctionInfo &FI = getTypes().arrangeNullaryFunction(); |
858 | |
859 | // Create our global prioritized initialization function. |
860 | if (!PrioritizedCXXGlobalInits.empty()) { |
861 | SmallVector<llvm::Function *, 8> LocalCXXGlobalInits; |
862 | llvm::array_pod_sort(Start: PrioritizedCXXGlobalInits.begin(), |
863 | End: PrioritizedCXXGlobalInits.end()); |
864 | // Iterate over "chunks" of ctors with same priority and emit each chunk |
865 | // into separate function. Note - everything is sorted first by priority, |
866 | // second - by lex order, so we emit ctor functions in proper order. |
867 | for (SmallVectorImpl<GlobalInitData >::iterator |
868 | I = PrioritizedCXXGlobalInits.begin(), |
869 | E = PrioritizedCXXGlobalInits.end(); I != E; ) { |
870 | SmallVectorImpl<GlobalInitData >::iterator |
871 | PrioE = std::upper_bound(first: I + 1, last: E, val: *I, comp: GlobalInitPriorityCmp()); |
872 | |
873 | LocalCXXGlobalInits.clear(); |
874 | |
875 | unsigned int Priority = I->first.priority; |
876 | llvm::Function *Fn = CreateGlobalInitOrCleanUpFunction( |
877 | FTy, Name: "_GLOBAL__I_" + getPrioritySuffix(Priority), FI); |
878 | |
879 | // Prepend the module inits to the highest priority set. |
880 | if (!ModuleInits.empty()) { |
881 | for (auto *F : ModuleInits) |
882 | LocalCXXGlobalInits.push_back(Elt: F); |
883 | ModuleInits.clear(); |
884 | } |
885 | |
886 | for (; I < PrioE; ++I) |
887 | LocalCXXGlobalInits.push_back(Elt: I->second); |
888 | |
889 | CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXThreadLocals: LocalCXXGlobalInits); |
890 | AddGlobalCtor(Ctor: Fn, Priority); |
891 | } |
892 | PrioritizedCXXGlobalInits.clear(); |
893 | } |
894 | |
895 | if (getCXXABI().useSinitAndSterm() && ModuleInits.empty() && |
896 | CXXGlobalInits.empty()) |
897 | return; |
898 | |
899 | for (auto *F : CXXGlobalInits) |
900 | ModuleInits.push_back(Elt: F); |
901 | CXXGlobalInits.clear(); |
902 | |
903 | // Include the filename in the symbol name. Including "sub_" matches gcc |
904 | // and makes sure these symbols appear lexicographically behind the symbols |
905 | // with priority emitted above. Module implementation units behave the same |
906 | // way as a non-modular TU with imports. |
907 | llvm::Function *Fn; |
908 | if (CXX20ModuleInits && getContext().getCurrentNamedModule() && |
909 | !getContext().getCurrentNamedModule()->isModuleImplementation()) { |
910 | SmallString<256> InitFnName; |
911 | llvm::raw_svector_ostream Out(InitFnName); |
912 | cast<ItaniumMangleContext>(Val&: getCXXABI().getMangleContext()) |
913 | .mangleModuleInitializer(Module: getContext().getCurrentNamedModule(), Out); |
914 | Fn = CreateGlobalInitOrCleanUpFunction( |
915 | FTy, Name: llvm::Twine(InitFnName), FI, Loc: SourceLocation(), TLS: false, |
916 | Linkage: llvm::GlobalVariable::ExternalLinkage); |
917 | } else |
918 | Fn = CreateGlobalInitOrCleanUpFunction( |
919 | FTy, |
920 | Name: llvm::Twine("_GLOBAL__sub_I_" , getTransformedFileName(M&: getModule())), |
921 | FI); |
922 | |
923 | CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXThreadLocals: ModuleInits); |
924 | AddGlobalCtor(Ctor: Fn); |
925 | |
926 | // In OpenCL global init functions must be converted to kernels in order to |
927 | // be able to launch them from the host. |
928 | // FIXME: Some more work might be needed to handle destructors correctly. |
929 | // Current initialization function makes use of function pointers callbacks. |
930 | // We can't support function pointers especially between host and device. |
931 | // However it seems global destruction has little meaning without any |
932 | // dynamic resource allocation on the device and program scope variables are |
933 | // destroyed by the runtime when program is released. |
934 | if (getLangOpts().OpenCL) { |
935 | GenKernelArgMetadata(FN: Fn); |
936 | Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL); |
937 | } |
938 | |
939 | assert(!getLangOpts().CUDA || !getLangOpts().CUDAIsDevice || |
940 | getLangOpts().GPUAllowDeviceInit); |
941 | if (getLangOpts().HIP && getLangOpts().CUDAIsDevice) { |
942 | Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL); |
943 | Fn->addFnAttr(Kind: "device-init" ); |
944 | } |
945 | |
946 | ModuleInits.clear(); |
947 | } |
948 | |
949 | void CodeGenModule::EmitCXXGlobalCleanUpFunc() { |
950 | if (CXXGlobalDtorsOrStermFinalizers.empty() && |
951 | PrioritizedCXXStermFinalizers.empty()) |
952 | return; |
953 | |
954 | llvm::FunctionType *FTy = llvm::FunctionType::get(Result: VoidTy, isVarArg: false); |
955 | const CGFunctionInfo &FI = getTypes().arrangeNullaryFunction(); |
956 | |
957 | // Create our global prioritized cleanup function. |
958 | if (!PrioritizedCXXStermFinalizers.empty()) { |
959 | SmallVector<CXXGlobalDtorsOrStermFinalizer_t, 8> LocalCXXStermFinalizers; |
960 | llvm::array_pod_sort(Start: PrioritizedCXXStermFinalizers.begin(), |
961 | End: PrioritizedCXXStermFinalizers.end()); |
962 | // Iterate over "chunks" of dtors with same priority and emit each chunk |
963 | // into separate function. Note - everything is sorted first by priority, |
964 | // second - by lex order, so we emit dtor functions in proper order. |
965 | for (SmallVectorImpl<StermFinalizerData>::iterator |
966 | I = PrioritizedCXXStermFinalizers.begin(), |
967 | E = PrioritizedCXXStermFinalizers.end(); |
968 | I != E;) { |
969 | SmallVectorImpl<StermFinalizerData>::iterator PrioE = |
970 | std::upper_bound(first: I + 1, last: E, val: *I, comp: StermFinalizerPriorityCmp()); |
971 | |
972 | LocalCXXStermFinalizers.clear(); |
973 | |
974 | unsigned int Priority = I->first.priority; |
975 | llvm::Function *Fn = CreateGlobalInitOrCleanUpFunction( |
976 | FTy, Name: "_GLOBAL__a_" + getPrioritySuffix(Priority), FI); |
977 | |
978 | for (; I < PrioE; ++I) { |
979 | llvm::FunctionCallee DtorFn = I->second; |
980 | LocalCXXStermFinalizers.emplace_back(Args: DtorFn.getFunctionType(), |
981 | Args: DtorFn.getCallee(), Args: nullptr); |
982 | } |
983 | |
984 | CodeGenFunction(*this).GenerateCXXGlobalCleanUpFunc( |
985 | Fn, DtorsOrStermFinalizers: LocalCXXStermFinalizers); |
986 | AddGlobalDtor(Dtor: Fn, Priority); |
987 | } |
988 | PrioritizedCXXStermFinalizers.clear(); |
989 | } |
990 | |
991 | if (CXXGlobalDtorsOrStermFinalizers.empty()) |
992 | return; |
993 | |
994 | // Create our global cleanup function. |
995 | llvm::Function *Fn = |
996 | CreateGlobalInitOrCleanUpFunction(FTy, Name: "_GLOBAL__D_a" , FI); |
997 | |
998 | CodeGenFunction(*this).GenerateCXXGlobalCleanUpFunc( |
999 | Fn, DtorsOrStermFinalizers: CXXGlobalDtorsOrStermFinalizers); |
1000 | AddGlobalDtor(Dtor: Fn); |
1001 | CXXGlobalDtorsOrStermFinalizers.clear(); |
1002 | } |
1003 | |
1004 | /// Emit the code necessary to initialize the given global variable. |
1005 | void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, |
1006 | const VarDecl *D, |
1007 | llvm::GlobalVariable *Addr, |
1008 | bool PerformInit) { |
1009 | // Check if we need to emit debug info for variable initializer. |
1010 | if (D->hasAttr<NoDebugAttr>()) |
1011 | DebugInfo = nullptr; // disable debug info indefinitely for this function |
1012 | |
1013 | CurEHLocation = D->getBeginLoc(); |
1014 | |
1015 | StartFunction(GD: GlobalDecl(D, DynamicInitKind::Initializer), |
1016 | RetTy: getContext().VoidTy, Fn, FnInfo: getTypes().arrangeNullaryFunction(), |
1017 | Args: FunctionArgList()); |
1018 | // Emit an artificial location for this function. |
1019 | auto AL = ApplyDebugLocation::CreateArtificial(CGF&: *this); |
1020 | |
1021 | // Use guarded initialization if the global variable is weak. This |
1022 | // occurs for, e.g., instantiated static data members and |
1023 | // definitions explicitly marked weak. |
1024 | // |
1025 | // Also use guarded initialization for a variable with dynamic TLS and |
1026 | // unordered initialization. (If the initialization is ordered, the ABI |
1027 | // layer will guard the whole-TU initialization for us.) |
1028 | if (Addr->hasWeakLinkage() || Addr->hasLinkOnceLinkage() || |
1029 | (D->getTLSKind() == VarDecl::TLS_Dynamic && |
1030 | isTemplateInstantiation(Kind: D->getTemplateSpecializationKind()))) { |
1031 | EmitCXXGuardedInit(D: *D, DeclPtr: Addr, PerformInit); |
1032 | } else { |
1033 | EmitCXXGlobalVarDeclInit(D: *D, GV: Addr, PerformInit); |
1034 | } |
1035 | |
1036 | if (getLangOpts().HLSL) |
1037 | CGM.getHLSLRuntime().annotateHLSLResource(D, GV: Addr); |
1038 | |
1039 | FinishFunction(); |
1040 | } |
1041 | |
1042 | void |
1043 | CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn, |
1044 | ArrayRef<llvm::Function *> Decls, |
1045 | ConstantAddress Guard) { |
1046 | { |
1047 | auto NL = ApplyDebugLocation::CreateEmpty(CGF&: *this); |
1048 | StartFunction(GD: GlobalDecl(), RetTy: getContext().VoidTy, Fn, |
1049 | FnInfo: getTypes().arrangeNullaryFunction(), Args: FunctionArgList()); |
1050 | // Emit an artificial location for this function. |
1051 | auto AL = ApplyDebugLocation::CreateArtificial(CGF&: *this); |
1052 | |
1053 | llvm::BasicBlock *ExitBlock = nullptr; |
1054 | if (Guard.isValid()) { |
1055 | // If we have a guard variable, check whether we've already performed |
1056 | // these initializations. This happens for TLS initialization functions. |
1057 | llvm::Value *GuardVal = Builder.CreateLoad(Addr: Guard); |
1058 | llvm::Value *Uninit = Builder.CreateIsNull(Arg: GuardVal, |
1059 | Name: "guard.uninitialized" ); |
1060 | llvm::BasicBlock *InitBlock = createBasicBlock(name: "init" ); |
1061 | ExitBlock = createBasicBlock(name: "exit" ); |
1062 | EmitCXXGuardedInitBranch(NeedsInit: Uninit, InitBlock, NoInitBlock: ExitBlock, |
1063 | Kind: GuardKind::TlsGuard, D: nullptr); |
1064 | EmitBlock(BB: InitBlock); |
1065 | // Mark as initialized before initializing anything else. If the |
1066 | // initializers use previously-initialized thread_local vars, that's |
1067 | // probably supposed to be OK, but the standard doesn't say. |
1068 | Builder.CreateStore(Val: llvm::ConstantInt::get(Ty: GuardVal->getType(),V: 1), Addr: Guard); |
1069 | |
1070 | // The guard variable can't ever change again. |
1071 | EmitInvariantStart( |
1072 | Addr: Guard.getPointer(), |
1073 | Size: CharUnits::fromQuantity( |
1074 | Quantity: CGM.getDataLayout().getTypeAllocSize(Ty: GuardVal->getType()))); |
1075 | } |
1076 | |
1077 | RunCleanupsScope Scope(*this); |
1078 | |
1079 | // When building in Objective-C++ ARC mode, create an autorelease pool |
1080 | // around the global initializers. |
1081 | if (getLangOpts().ObjCAutoRefCount && getLangOpts().CPlusPlus) { |
1082 | llvm::Value *token = EmitObjCAutoreleasePoolPush(); |
1083 | EmitObjCAutoreleasePoolCleanup(Ptr: token); |
1084 | } |
1085 | |
1086 | for (unsigned i = 0, e = Decls.size(); i != e; ++i) |
1087 | if (Decls[i]) |
1088 | EmitRuntimeCall(callee: Decls[i]); |
1089 | |
1090 | Scope.ForceCleanup(); |
1091 | |
1092 | if (ExitBlock) { |
1093 | Builder.CreateBr(Dest: ExitBlock); |
1094 | EmitBlock(BB: ExitBlock); |
1095 | } |
1096 | } |
1097 | |
1098 | FinishFunction(); |
1099 | } |
1100 | |
1101 | void CodeGenFunction::GenerateCXXGlobalCleanUpFunc( |
1102 | llvm::Function *Fn, |
1103 | ArrayRef<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH, |
1104 | llvm::Constant *>> |
1105 | DtorsOrStermFinalizers) { |
1106 | { |
1107 | auto NL = ApplyDebugLocation::CreateEmpty(CGF&: *this); |
1108 | StartFunction(GD: GlobalDecl(), RetTy: getContext().VoidTy, Fn, |
1109 | FnInfo: getTypes().arrangeNullaryFunction(), Args: FunctionArgList()); |
1110 | // Emit an artificial location for this function. |
1111 | auto AL = ApplyDebugLocation::CreateArtificial(CGF&: *this); |
1112 | |
1113 | // Emit the cleanups, in reverse order from construction. |
1114 | for (unsigned i = 0, e = DtorsOrStermFinalizers.size(); i != e; ++i) { |
1115 | llvm::FunctionType *CalleeTy; |
1116 | llvm::Value *Callee; |
1117 | llvm::Constant *Arg; |
1118 | std::tie(args&: CalleeTy, args&: Callee, args&: Arg) = DtorsOrStermFinalizers[e - i - 1]; |
1119 | |
1120 | llvm::CallInst *CI = nullptr; |
1121 | if (Arg == nullptr) { |
1122 | assert( |
1123 | CGM.getCXXABI().useSinitAndSterm() && |
1124 | "Arg could not be nullptr unless using sinit and sterm functions." ); |
1125 | CI = Builder.CreateCall(FTy: CalleeTy, Callee); |
1126 | } else |
1127 | CI = Builder.CreateCall(FTy: CalleeTy, Callee, Args: Arg); |
1128 | |
1129 | // Make sure the call and the callee agree on calling convention. |
1130 | if (llvm::Function *F = dyn_cast<llvm::Function>(Val: Callee)) |
1131 | CI->setCallingConv(F->getCallingConv()); |
1132 | } |
1133 | } |
1134 | |
1135 | FinishFunction(); |
1136 | } |
1137 | |
1138 | /// generateDestroyHelper - Generates a helper function which, when |
1139 | /// invoked, destroys the given object. The address of the object |
1140 | /// should be in global memory. |
1141 | llvm::Function *CodeGenFunction::generateDestroyHelper( |
1142 | Address addr, QualType type, Destroyer *destroyer, |
1143 | bool useEHCleanupForArray, const VarDecl *VD) { |
1144 | FunctionArgList args; |
1145 | ImplicitParamDecl Dst(getContext(), getContext().VoidPtrTy, |
1146 | ImplicitParamKind::Other); |
1147 | args.push_back(&Dst); |
1148 | |
1149 | const CGFunctionInfo &FI = |
1150 | CGM.getTypes().arrangeBuiltinFunctionDeclaration(getContext().VoidTy, args); |
1151 | llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(Info: FI); |
1152 | llvm::Function *fn = CGM.CreateGlobalInitOrCleanUpFunction( |
1153 | FTy, Name: "__cxx_global_array_dtor" , FI, Loc: VD->getLocation()); |
1154 | |
1155 | CurEHLocation = VD->getBeginLoc(); |
1156 | |
1157 | StartFunction(GD: GlobalDecl(VD, DynamicInitKind::GlobalArrayDestructor), |
1158 | RetTy: getContext().VoidTy, Fn: fn, FnInfo: FI, Args: args); |
1159 | // Emit an artificial location for this function. |
1160 | auto AL = ApplyDebugLocation::CreateArtificial(CGF&: *this); |
1161 | |
1162 | emitDestroy(addr, type, destroyer, useEHCleanupForArray); |
1163 | |
1164 | FinishFunction(); |
1165 | |
1166 | return fn; |
1167 | } |
1168 | |