/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/CodeGen/CGDeclCXX.cpp
Line | Count | Source (jump to first uncovered line) |
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 "CGObjCRuntime.h" |
15 | | #include "CGOpenMPRuntime.h" |
16 | | #include "CodeGenFunction.h" |
17 | | #include "TargetInfo.h" |
18 | | #include "clang/AST/Attr.h" |
19 | | #include "clang/Basic/LangOptions.h" |
20 | | #include "llvm/ADT/StringExtras.h" |
21 | | #include "llvm/IR/Intrinsics.h" |
22 | | #include "llvm/IR/MDBuilder.h" |
23 | | #include "llvm/Support/Path.h" |
24 | | |
25 | | using namespace clang; |
26 | | using namespace CodeGen; |
27 | | |
28 | | static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D, |
29 | 14.2k | ConstantAddress DeclPtr) { |
30 | 14.2k | assert( |
31 | 14.2k | (D.hasGlobalStorage() || |
32 | 14.2k | (D.hasLocalStorage() && CGF.getContext().getLangOpts().OpenCLCPlusPlus)) && |
33 | 14.2k | "VarDecl must have global or local (in the case of OpenCL) storage!"); |
34 | 0 | assert(!D.getType()->isReferenceType() && |
35 | 14.2k | "Should not call EmitDeclInit on a reference!"); |
36 | | |
37 | 0 | QualType type = D.getType(); |
38 | 14.2k | LValue lv = CGF.MakeAddrLValue(DeclPtr, type); |
39 | | |
40 | 14.2k | const Expr *Init = D.getInit(); |
41 | 14.2k | switch (CGF.getEvaluationKind(type)) { |
42 | 9.31k | case TEK_Scalar: { |
43 | 9.31k | CodeGenModule &CGM = CGF.CGM; |
44 | 9.31k | if (lv.isObjCStrong()) |
45 | 3 | CGM.getObjCRuntime().EmitObjCGlobalAssign(CGF, CGF.EmitScalarExpr(Init), |
46 | 3 | DeclPtr, D.getTLSKind()); |
47 | 9.30k | else if (lv.isObjCWeak()) |
48 | 2 | CGM.getObjCRuntime().EmitObjCWeakAssign(CGF, CGF.EmitScalarExpr(Init), |
49 | 2 | DeclPtr); |
50 | 9.30k | else |
51 | 9.30k | CGF.EmitScalarInit(Init, &D, lv, false); |
52 | 9.31k | return; |
53 | 0 | } |
54 | 3 | case TEK_Complex: |
55 | 3 | CGF.EmitComplexExprIntoLValue(Init, lv, /*isInit*/ true); |
56 | 3 | return; |
57 | 4.91k | case TEK_Aggregate: |
58 | 4.91k | CGF.EmitAggExpr(Init, |
59 | 4.91k | AggValueSlot::forLValue(lv, CGF, AggValueSlot::IsDestructed, |
60 | 4.91k | AggValueSlot::DoesNotNeedGCBarriers, |
61 | 4.91k | AggValueSlot::IsNotAliased, |
62 | 4.91k | AggValueSlot::DoesNotOverlap)); |
63 | 4.91k | return; |
64 | 14.2k | } |
65 | 0 | llvm_unreachable("bad evaluation kind"); |
66 | 0 | } |
67 | | |
68 | | /// Emit code to cause the destruction of the given variable with |
69 | | /// static storage duration. |
70 | | static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, |
71 | 14.6k | ConstantAddress Addr) { |
72 | | // Honor __attribute__((no_destroy)) and bail instead of attempting |
73 | | // to emit a reference to a possibly nonexistent destructor, which |
74 | | // in turn can cause a crash. This will result in a global constructor |
75 | | // that isn't balanced out by a destructor call as intended by the |
76 | | // attribute. This also checks for -fno-c++-static-destructors and |
77 | | // bails even if the attribute is not present. |
78 | 14.6k | QualType::DestructionKind DtorKind = D.needsDestruction(CGF.getContext()); |
79 | | |
80 | | // FIXME: __attribute__((cleanup)) ? |
81 | | |
82 | 14.6k | switch (DtorKind) { |
83 | 9.84k | case QualType::DK_none: |
84 | 9.84k | return; |
85 | | |
86 | 4.74k | case QualType::DK_cxx_destructor: |
87 | 4.74k | break; |
88 | | |
89 | 7 | case QualType::DK_objc_strong_lifetime: |
90 | 7 | case QualType::DK_objc_weak_lifetime: |
91 | 7 | case QualType::DK_nontrivial_c_struct: |
92 | | // We don't care about releasing objects during process teardown. |
93 | 7 | assert(!D.getTLSKind() && "should have rejected this"); |
94 | 0 | return; |
95 | 14.6k | } |
96 | | |
97 | 4.74k | llvm::FunctionCallee Func; |
98 | 4.74k | llvm::Constant *Argument; |
99 | | |
100 | 4.74k | CodeGenModule &CGM = CGF.CGM; |
101 | 4.74k | QualType Type = D.getType(); |
102 | | |
103 | | // Special-case non-array C++ destructors, if they have the right signature. |
104 | | // Under some ABIs, destructors return this instead of void, and cannot be |
105 | | // passed directly to __cxa_atexit if the target does not allow this |
106 | | // mismatch. |
107 | 4.74k | const CXXRecordDecl *Record = Type->getAsCXXRecordDecl(); |
108 | 4.74k | bool CanRegisterDestructor = |
109 | 4.74k | Record && (4.41k !CGM.getCXXABI().HasThisReturn( |
110 | 4.41k | GlobalDecl(Record->getDestructor(), Dtor_Complete)) || |
111 | 4.41k | CGM.getCXXABI().canCallMismatchedFunctionType()8 ); |
112 | | // If __cxa_atexit is disabled via a flag, a different helper function is |
113 | | // generated elsewhere which uses atexit instead, and it takes the destructor |
114 | | // directly. |
115 | 4.74k | bool UsingExternalHelper = !CGM.getCodeGenOpts().CXAAtExit; |
116 | 4.74k | if (Record && (4.41k CanRegisterDestructor4.41k || UsingExternalHelper1 )) { |
117 | 4.41k | assert(!Record->hasTrivialDestructor()); |
118 | 0 | CXXDestructorDecl *Dtor = Record->getDestructor(); |
119 | | |
120 | 4.41k | Func = CGM.getAddrAndTypeOfCXXStructor(GlobalDecl(Dtor, Dtor_Complete)); |
121 | 4.41k | if (CGF.getContext().getLangOpts().OpenCL) { |
122 | 7 | auto DestAS = |
123 | 7 | CGM.getTargetCodeGenInfo().getAddrSpaceOfCxaAtexitPtrParam(); |
124 | 7 | auto DestTy = CGF.getTypes().ConvertType(Type)->getPointerTo( |
125 | 7 | CGM.getContext().getTargetAddressSpace(DestAS)); |
126 | 7 | auto SrcAS = D.getType().getQualifiers().getAddressSpace(); |
127 | 7 | if (DestAS == SrcAS) |
128 | 0 | Argument = llvm::ConstantExpr::getBitCast(Addr.getPointer(), DestTy); |
129 | 7 | else |
130 | | // FIXME: On addr space mismatch we are passing NULL. The generation |
131 | | // of the global destructor function should be adjusted accordingly. |
132 | 7 | Argument = llvm::ConstantPointerNull::get(DestTy); |
133 | 4.40k | } else { |
134 | 4.40k | Argument = llvm::ConstantExpr::getBitCast( |
135 | 4.40k | Addr.getPointer(), CGF.getTypes().ConvertType(Type)->getPointerTo()); |
136 | 4.40k | } |
137 | | // Otherwise, the standard logic requires a helper function. |
138 | 4.41k | } else { |
139 | 338 | Addr = Addr.getElementBitCast(CGF.ConvertTypeForMem(Type)); |
140 | 338 | Func = CodeGenFunction(CGM) |
141 | 338 | .generateDestroyHelper(Addr, Type, CGF.getDestroyer(DtorKind), |
142 | 338 | CGF.needsEHCleanup(DtorKind), &D); |
143 | 338 | Argument = llvm::Constant::getNullValue(CGF.Int8PtrTy); |
144 | 338 | } |
145 | | |
146 | 0 | CGM.getCXXABI().registerGlobalDtor(CGF, D, Func, Argument); |
147 | 4.74k | } |
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 | 144 | llvm::Constant *Addr) { |
153 | 144 | return CGF.EmitInvariantStart( |
154 | 144 | Addr, CGF.getContext().getTypeSizeInChars(D.getType())); |
155 | 144 | } |
156 | | |
157 | 195 | void CodeGenFunction::EmitInvariantStart(llvm::Constant *Addr, CharUnits Size) { |
158 | | // Do not emit the intrinsic if we're not optimizing. |
159 | 195 | if (!CGM.getCodeGenOpts().OptimizationLevel) |
160 | 185 | return; |
161 | | |
162 | | // Grab the llvm.invariant.start intrinsic. |
163 | 10 | llvm::Intrinsic::ID InvStartID = llvm::Intrinsic::invariant_start; |
164 | | // Overloaded address space type. |
165 | 10 | llvm::Type *ObjectPtr[1] = {Int8PtrTy}; |
166 | 10 | llvm::Function *InvariantStart = CGM.getIntrinsic(InvStartID, ObjectPtr); |
167 | | |
168 | | // Emit a call with the size in bytes of the object. |
169 | 10 | uint64_t Width = Size.getQuantity(); |
170 | 10 | llvm::Value *Args[2] = { llvm::ConstantInt::getSigned(Int64Ty, Width), |
171 | 10 | llvm::ConstantExpr::getBitCast(Addr, Int8PtrTy)}; |
172 | 10 | Builder.CreateCall(InvariantStart, Args); |
173 | 10 | } |
174 | | |
175 | | void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D, |
176 | | llvm::GlobalVariable *GV, |
177 | 14.8k | bool PerformInit) { |
178 | | |
179 | 14.8k | const Expr *Init = D.getInit(); |
180 | 14.8k | QualType T = D.getType(); |
181 | | |
182 | | // The address space of a static local variable (DeclPtr) may be different |
183 | | // from the address space of the "this" argument of the constructor. In that |
184 | | // case, we need an addrspacecast before calling the constructor. |
185 | | // |
186 | | // struct StructWithCtor { |
187 | | // __device__ StructWithCtor() {...} |
188 | | // }; |
189 | | // __device__ void foo() { |
190 | | // __shared__ StructWithCtor s; |
191 | | // ... |
192 | | // } |
193 | | // |
194 | | // For example, in the above CUDA code, the static local variable s has a |
195 | | // "shared" address space qualifier, but the constructor of StructWithCtor |
196 | | // expects "this" in the "generic" address space. |
197 | 14.8k | unsigned ExpectedAddrSpace = getContext().getTargetAddressSpace(T); |
198 | 14.8k | unsigned ActualAddrSpace = GV->getAddressSpace(); |
199 | 14.8k | llvm::Constant *DeclPtr = GV; |
200 | 14.8k | if (ActualAddrSpace != ExpectedAddrSpace) { |
201 | 11 | llvm::PointerType *PTy = llvm::PointerType::getWithSamePointeeType( |
202 | 11 | GV->getType(), ExpectedAddrSpace); |
203 | 11 | DeclPtr = llvm::ConstantExpr::getAddrSpaceCast(DeclPtr, PTy); |
204 | 11 | } |
205 | | |
206 | 14.8k | ConstantAddress DeclAddr( |
207 | 14.8k | DeclPtr, GV->getValueType(), getContext().getDeclAlign(&D)); |
208 | | |
209 | 14.8k | if (!T->isReferenceType()) { |
210 | 14.7k | if (getLangOpts().OpenMP && !getLangOpts().OpenMPSimd3.88k && |
211 | 14.7k | D.hasAttr<OMPThreadPrivateDeclAttr>()1.67k ) { |
212 | 63 | (void)CGM.getOpenMPRuntime().emitThreadPrivateVarDefinition( |
213 | 63 | &D, DeclAddr, D.getAttr<OMPThreadPrivateDeclAttr>()->getLocation(), |
214 | 63 | PerformInit, this); |
215 | 63 | } |
216 | 14.7k | if (PerformInit) |
217 | 14.2k | EmitDeclInit(*this, D, DeclAddr); |
218 | 14.7k | if (CGM.isTypeConstant(D.getType(), true)) |
219 | 144 | EmitDeclInvariant(*this, D, DeclPtr); |
220 | 14.6k | else |
221 | 14.6k | EmitDeclDestroy(*this, D, DeclAddr); |
222 | 14.7k | return; |
223 | 14.7k | } |
224 | | |
225 | 101 | assert(PerformInit && "cannot have constant initializer which needs " |
226 | 101 | "destruction for reference"); |
227 | 0 | RValue RV = EmitReferenceBindingToExpr(Init); |
228 | 101 | EmitStoreOfScalar(RV.getScalarVal(), DeclAddr, false, T); |
229 | 101 | } |
230 | | |
231 | | /// Create a stub function, suitable for being passed to atexit, |
232 | | /// which passes the given address to the given destructor function. |
233 | | llvm::Function *CodeGenFunction::createAtExitStub(const VarDecl &VD, |
234 | | llvm::FunctionCallee dtor, |
235 | 226 | llvm::Constant *addr) { |
236 | | // Get the destructor function type, void(*)(void). |
237 | 226 | llvm::FunctionType *ty = llvm::FunctionType::get(CGM.VoidTy, false); |
238 | 226 | SmallString<256> FnName; |
239 | 226 | { |
240 | 226 | llvm::raw_svector_ostream Out(FnName); |
241 | 226 | CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(&VD, Out); |
242 | 226 | } |
243 | | |
244 | 226 | const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction(); |
245 | 226 | llvm::Function *fn = CGM.CreateGlobalInitOrCleanUpFunction( |
246 | 226 | ty, FnName.str(), FI, VD.getLocation()); |
247 | | |
248 | 226 | CodeGenFunction CGF(CGM); |
249 | | |
250 | 226 | CGF.StartFunction(GlobalDecl(&VD, DynamicInitKind::AtExit), |
251 | 226 | CGM.getContext().VoidTy, fn, FI, FunctionArgList(), |
252 | 226 | VD.getLocation(), VD.getInit()->getExprLoc()); |
253 | | // Emit an artificial location for this function. |
254 | 226 | auto AL = ApplyDebugLocation::CreateArtificial(CGF); |
255 | | |
256 | 226 | llvm::CallInst *call = CGF.Builder.CreateCall(dtor, addr); |
257 | | |
258 | | // Make sure the call and the callee agree on calling convention. |
259 | 226 | if (auto *dtorFn = dyn_cast<llvm::Function>( |
260 | 226 | dtor.getCallee()->stripPointerCastsAndAliases())) |
261 | 226 | call->setCallingConv(dtorFn->getCallingConv()); |
262 | | |
263 | 226 | CGF.FinishFunction(); |
264 | | |
265 | 226 | return fn; |
266 | 226 | } |
267 | | |
268 | | /// Create a stub function, suitable for being passed to __pt_atexit_np, |
269 | | /// which passes the given address to the given destructor function. |
270 | | llvm::Function *CodeGenFunction::createTLSAtExitStub( |
271 | | const VarDecl &D, llvm::FunctionCallee Dtor, llvm::Constant *Addr, |
272 | 5 | llvm::FunctionCallee &AtExit) { |
273 | 5 | SmallString<256> FnName; |
274 | 5 | { |
275 | 5 | llvm::raw_svector_ostream Out(FnName); |
276 | 5 | CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(&D, Out); |
277 | 5 | } |
278 | | |
279 | 5 | const CGFunctionInfo &FI = CGM.getTypes().arrangeLLVMFunctionInfo( |
280 | 5 | getContext().IntTy, /*instanceMethod=*/false, /*chainCall=*/false, |
281 | 5 | {getContext().IntTy}, FunctionType::ExtInfo(), {}, RequiredArgs::All); |
282 | | |
283 | | // Get the stub function type, int(*)(int,...). |
284 | 5 | llvm::FunctionType *StubTy = |
285 | 5 | llvm::FunctionType::get(CGM.IntTy, {CGM.IntTy}, true); |
286 | | |
287 | 5 | llvm::Function *DtorStub = CGM.CreateGlobalInitOrCleanUpFunction( |
288 | 5 | StubTy, FnName.str(), FI, D.getLocation()); |
289 | | |
290 | 5 | CodeGenFunction CGF(CGM); |
291 | | |
292 | 5 | FunctionArgList Args; |
293 | 5 | ImplicitParamDecl IPD(CGM.getContext(), CGM.getContext().IntTy, |
294 | 5 | ImplicitParamDecl::Other); |
295 | 5 | Args.push_back(&IPD); |
296 | 5 | QualType ResTy = CGM.getContext().IntTy; |
297 | | |
298 | 5 | CGF.StartFunction(GlobalDecl(&D, DynamicInitKind::AtExit), ResTy, DtorStub, |
299 | 5 | FI, Args, D.getLocation(), D.getInit()->getExprLoc()); |
300 | | |
301 | | // Emit an artificial location for this function. |
302 | 5 | auto AL = ApplyDebugLocation::CreateArtificial(CGF); |
303 | | |
304 | 5 | llvm::CallInst *call = CGF.Builder.CreateCall(Dtor, Addr); |
305 | | |
306 | | // Make sure the call and the callee agree on calling convention. |
307 | 5 | if (auto *DtorFn = dyn_cast<llvm::Function>( |
308 | 5 | Dtor.getCallee()->stripPointerCastsAndAliases())) |
309 | 5 | call->setCallingConv(DtorFn->getCallingConv()); |
310 | | |
311 | | // Return 0 from function |
312 | 5 | CGF.Builder.CreateStore(llvm::Constant::getNullValue(CGM.IntTy), |
313 | 5 | CGF.ReturnValue); |
314 | | |
315 | 5 | CGF.FinishFunction(); |
316 | | |
317 | 5 | return DtorStub; |
318 | 5 | } |
319 | | |
320 | | /// Register a global destructor using the C atexit runtime function. |
321 | | void CodeGenFunction::registerGlobalDtorWithAtExit(const VarDecl &VD, |
322 | | llvm::FunctionCallee dtor, |
323 | 178 | llvm::Constant *addr) { |
324 | | // Create a function which calls the destructor. |
325 | 178 | llvm::Constant *dtorStub = createAtExitStub(VD, dtor, addr); |
326 | 178 | registerGlobalDtorWithAtExit(dtorStub); |
327 | 178 | } |
328 | | |
329 | 231 | void CodeGenFunction::registerGlobalDtorWithAtExit(llvm::Constant *dtorStub) { |
330 | | // extern "C" int atexit(void (*f)(void)); |
331 | 231 | assert(dtorStub->getType() == |
332 | 231 | llvm::PointerType::get( |
333 | 231 | llvm::FunctionType::get(CGM.VoidTy, false), |
334 | 231 | dtorStub->getType()->getPointerAddressSpace()) && |
335 | 231 | "Argument to atexit has a wrong type."); |
336 | | |
337 | 0 | llvm::FunctionType *atexitTy = |
338 | 231 | llvm::FunctionType::get(IntTy, dtorStub->getType(), false); |
339 | | |
340 | 231 | llvm::FunctionCallee atexit = |
341 | 231 | CGM.CreateRuntimeFunction(atexitTy, "atexit", llvm::AttributeList(), |
342 | 231 | /*Local=*/true); |
343 | 231 | if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atexit.getCallee())) |
344 | 231 | atexitFn->setDoesNotThrow(); |
345 | | |
346 | 231 | EmitNounwindRuntimeCall(atexit, dtorStub); |
347 | 231 | } |
348 | | |
349 | | llvm::Value * |
350 | 48 | CodeGenFunction::unregisterGlobalDtorWithUnAtExit(llvm::Constant *dtorStub) { |
351 | | // The unatexit subroutine unregisters __dtor functions that were previously |
352 | | // registered by the atexit subroutine. If the referenced function is found, |
353 | | // it is removed from the list of functions that are called at normal program |
354 | | // termination and the unatexit returns a value of 0, otherwise a non-zero |
355 | | // value is returned. |
356 | | // |
357 | | // extern "C" int unatexit(void (*f)(void)); |
358 | 48 | assert(dtorStub->getType() == |
359 | 48 | llvm::PointerType::get( |
360 | 48 | llvm::FunctionType::get(CGM.VoidTy, false), |
361 | 48 | dtorStub->getType()->getPointerAddressSpace()) && |
362 | 48 | "Argument to unatexit has a wrong type."); |
363 | | |
364 | 0 | llvm::FunctionType *unatexitTy = |
365 | 48 | llvm::FunctionType::get(IntTy, {dtorStub->getType()}, /*isVarArg=*/false); |
366 | | |
367 | 48 | llvm::FunctionCallee unatexit = |
368 | 48 | CGM.CreateRuntimeFunction(unatexitTy, "unatexit", llvm::AttributeList()); |
369 | | |
370 | 48 | cast<llvm::Function>(unatexit.getCallee())->setDoesNotThrow(); |
371 | | |
372 | 48 | return EmitNounwindRuntimeCall(unatexit, dtorStub); |
373 | 48 | } |
374 | | |
375 | | void CodeGenFunction::EmitCXXGuardedInit(const VarDecl &D, |
376 | | llvm::GlobalVariable *DeclPtr, |
377 | 9.22k | bool PerformInit) { |
378 | | // If we've been asked to forbid guard variables, emit an error now. |
379 | | // This diagnostic is hard-coded for Darwin's use case; we can find |
380 | | // better phrasing if someone else needs it. |
381 | 9.22k | if (CGM.getCodeGenOpts().ForbidGuardVariables) |
382 | 1 | CGM.Error(D.getLocation(), |
383 | 1 | "this initialization requires a guard variable, which " |
384 | 1 | "the kernel does not support"); |
385 | | |
386 | 9.22k | CGM.getCXXABI().EmitGuardedInit(*this, D, DeclPtr, PerformInit); |
387 | 9.22k | } |
388 | | |
389 | | void CodeGenFunction::EmitCXXGuardedInitBranch(llvm::Value *NeedsInit, |
390 | | llvm::BasicBlock *InitBlock, |
391 | | llvm::BasicBlock *NoInitBlock, |
392 | | GuardKind Kind, |
393 | 9.23k | const VarDecl *D) { |
394 | 9.23k | assert((Kind == GuardKind::TlsGuard || D) && "no guarded variable"); |
395 | | |
396 | | // A guess at how many times we will enter the initialization of a |
397 | | // variable, depending on the kind of variable. |
398 | 0 | static const uint64_t InitsPerTLSVar = 1024; |
399 | 9.23k | static const uint64_t InitsPerLocalVar = 1024 * 1024; |
400 | | |
401 | 9.23k | llvm::MDNode *Weights; |
402 | 9.23k | if (Kind == GuardKind::VariableGuard && !D->isLocalVarDecl()9.18k ) { |
403 | | // For non-local variables, don't apply any weighting for now. Due to our |
404 | | // use of COMDATs, we expect there to be at most one initialization of the |
405 | | // variable per DSO, but we have no way to know how many DSOs will try to |
406 | | // initialize the variable. |
407 | 183 | Weights = nullptr; |
408 | 9.05k | } else { |
409 | 9.05k | uint64_t NumInits; |
410 | | // FIXME: For the TLS case, collect and use profiling information to |
411 | | // determine a more accurate brach weight. |
412 | 9.05k | if (Kind == GuardKind::TlsGuard || D->getTLSKind()8.99k ) |
413 | 122 | NumInits = InitsPerTLSVar; |
414 | 8.92k | else |
415 | 8.92k | NumInits = InitsPerLocalVar; |
416 | | |
417 | | // The probability of us entering the initializer is |
418 | | // 1 / (total number of times we attempt to initialize the variable). |
419 | 9.05k | llvm::MDBuilder MDHelper(CGM.getLLVMContext()); |
420 | 9.05k | Weights = MDHelper.createBranchWeights(1, NumInits - 1); |
421 | 9.05k | } |
422 | | |
423 | 9.23k | Builder.CreateCondBr(NeedsInit, InitBlock, NoInitBlock, Weights); |
424 | 9.23k | } |
425 | | |
426 | | llvm::Function *CodeGenModule::CreateGlobalInitOrCleanUpFunction( |
427 | | llvm::FunctionType *FTy, const Twine &Name, const CGFunctionInfo &FI, |
428 | 10.7k | SourceLocation Loc, bool TLS, llvm::GlobalVariable::LinkageTypes Linkage) { |
429 | 10.7k | llvm::Function *Fn = llvm::Function::Create(FTy, Linkage, Name, &getModule()); |
430 | | |
431 | 10.7k | if (!getLangOpts().AppleKext && !TLS10.7k ) { |
432 | | // Set the section if needed. |
433 | 10.6k | if (const char *Section = getTarget().getStaticInitSectionSpecifier()) |
434 | 2.60k | Fn->setSection(Section); |
435 | 10.6k | } |
436 | | |
437 | 10.7k | if (Linkage == llvm::GlobalVariable::InternalLinkage) |
438 | 10.6k | SetInternalFunctionAttributes(GlobalDecl(), Fn, FI); |
439 | | |
440 | 10.7k | Fn->setCallingConv(getRuntimeCC()); |
441 | | |
442 | 10.7k | if (!getLangOpts().Exceptions) |
443 | 9.60k | Fn->setDoesNotThrow(); |
444 | | |
445 | 10.7k | if (getLangOpts().Sanitize.has(SanitizerKind::Address) && |
446 | 10.7k | !isInNoSanitizeList(SanitizerKind::Address, Fn, Loc)93 ) |
447 | 88 | Fn->addFnAttr(llvm::Attribute::SanitizeAddress); |
448 | | |
449 | 10.7k | if (getLangOpts().Sanitize.has(SanitizerKind::KernelAddress) && |
450 | 10.7k | !isInNoSanitizeList(SanitizerKind::KernelAddress, Fn, Loc)4 ) |
451 | 2 | Fn->addFnAttr(llvm::Attribute::SanitizeAddress); |
452 | | |
453 | 10.7k | if (getLangOpts().Sanitize.has(SanitizerKind::HWAddress) && |
454 | 10.7k | !isInNoSanitizeList(SanitizerKind::HWAddress, Fn, Loc)0 ) |
455 | 0 | Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress); |
456 | | |
457 | 10.7k | if (getLangOpts().Sanitize.has(SanitizerKind::KernelHWAddress) && |
458 | 10.7k | !isInNoSanitizeList(SanitizerKind::KernelHWAddress, Fn, Loc)0 ) |
459 | 0 | Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress); |
460 | | |
461 | 10.7k | if (getLangOpts().Sanitize.has(SanitizerKind::MemtagStack) && |
462 | 10.7k | !isInNoSanitizeList(SanitizerKind::MemtagStack, Fn, Loc)0 ) |
463 | 0 | Fn->addFnAttr(llvm::Attribute::SanitizeMemTag); |
464 | | |
465 | 10.7k | if (getLangOpts().Sanitize.has(SanitizerKind::Thread) && |
466 | 10.7k | !isInNoSanitizeList(SanitizerKind::Thread, Fn, Loc)6 ) |
467 | 3 | Fn->addFnAttr(llvm::Attribute::SanitizeThread); |
468 | | |
469 | 10.7k | if (getLangOpts().Sanitize.has(SanitizerKind::Memory) && |
470 | 10.7k | !isInNoSanitizeList(SanitizerKind::Memory, Fn, Loc)97 ) |
471 | 97 | Fn->addFnAttr(llvm::Attribute::SanitizeMemory); |
472 | | |
473 | 10.7k | if (getLangOpts().Sanitize.has(SanitizerKind::KernelMemory) && |
474 | 10.7k | !isInNoSanitizeList(SanitizerKind::KernelMemory, Fn, Loc)0 ) |
475 | 0 | Fn->addFnAttr(llvm::Attribute::SanitizeMemory); |
476 | | |
477 | 10.7k | if (getLangOpts().Sanitize.has(SanitizerKind::SafeStack) && |
478 | 10.7k | !isInNoSanitizeList(SanitizerKind::SafeStack, Fn, Loc)0 ) |
479 | 0 | Fn->addFnAttr(llvm::Attribute::SafeStack); |
480 | | |
481 | 10.7k | if (getLangOpts().Sanitize.has(SanitizerKind::ShadowCallStack) && |
482 | 10.7k | !isInNoSanitizeList(SanitizerKind::ShadowCallStack, Fn, Loc)0 ) |
483 | 0 | Fn->addFnAttr(llvm::Attribute::ShadowCallStack); |
484 | | |
485 | 10.7k | return Fn; |
486 | 10.7k | } |
487 | | |
488 | | /// Create a global pointer to a function that will initialize a global |
489 | | /// variable. The user has requested that this pointer be emitted in a specific |
490 | | /// section. |
491 | | void CodeGenModule::EmitPointerToInitFunc(const VarDecl *D, |
492 | | llvm::GlobalVariable *GV, |
493 | | llvm::Function *InitFunc, |
494 | 6 | InitSegAttr *ISA) { |
495 | 6 | llvm::GlobalVariable *PtrArray = new llvm::GlobalVariable( |
496 | 6 | TheModule, InitFunc->getType(), /*isConstant=*/true, |
497 | 6 | llvm::GlobalValue::PrivateLinkage, InitFunc, "__cxx_init_fn_ptr"); |
498 | 6 | PtrArray->setSection(ISA->getSection()); |
499 | 6 | addUsedGlobal(PtrArray); |
500 | | |
501 | | // If the GV is already in a comdat group, then we have to join it. |
502 | 6 | if (llvm::Comdat *C = GV->getComdat()) |
503 | 3 | PtrArray->setComdat(C); |
504 | 6 | } |
505 | | |
506 | | void |
507 | | CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D, |
508 | | llvm::GlobalVariable *Addr, |
509 | 5.94k | bool PerformInit) { |
510 | | |
511 | | // According to E.2.3.1 in CUDA-7.5 Programming guide: __device__, |
512 | | // __constant__ and __shared__ variables defined in namespace scope, |
513 | | // that are of class type, cannot have a non-empty constructor. All |
514 | | // the checks have been done in Sema by now. Whatever initializers |
515 | | // are allowed are empty and we just need to ignore them here. |
516 | 5.94k | if (getLangOpts().CUDAIsDevice && !getLangOpts().GPUAllowDeviceInit1 && |
517 | 5.94k | (0 D->hasAttr<CUDADeviceAttr>()0 || D->hasAttr<CUDAConstantAttr>()0 || |
518 | 0 | D->hasAttr<CUDASharedAttr>())) |
519 | 0 | return; |
520 | | |
521 | 5.94k | if (getLangOpts().OpenMP && |
522 | 5.94k | getOpenMPRuntime().emitDeclareTargetVarDefinition(D, Addr, PerformInit)3.90k ) |
523 | 79 | return; |
524 | | |
525 | | // Check if we've already initialized this decl. |
526 | 5.86k | auto I = DelayedCXXInitPosition.find(D); |
527 | 5.86k | if (I != DelayedCXXInitPosition.end() && I->second == ~0U1.63k ) |
528 | 22 | return; |
529 | | |
530 | 5.84k | llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); |
531 | 5.84k | SmallString<256> FnName; |
532 | 5.84k | { |
533 | 5.84k | llvm::raw_svector_ostream Out(FnName); |
534 | 5.84k | getCXXABI().getMangleContext().mangleDynamicInitializer(D, Out); |
535 | 5.84k | } |
536 | | |
537 | | // Create a variable initialization function. |
538 | 5.84k | llvm::Function *Fn = CreateGlobalInitOrCleanUpFunction( |
539 | 5.84k | FTy, FnName.str(), getTypes().arrangeNullaryFunction(), D->getLocation()); |
540 | | |
541 | 5.84k | auto *ISA = D->getAttr<InitSegAttr>(); |
542 | 5.84k | CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr, |
543 | 5.84k | PerformInit); |
544 | | |
545 | 5.84k | llvm::GlobalVariable *COMDATKey = |
546 | 5.84k | supportsCOMDAT() && D->isExternallyVisible()4.66k ? Addr3.93k : nullptr1.91k ; |
547 | | |
548 | 5.84k | if (D->getTLSKind()) { |
549 | | // FIXME: Should we support init_priority for thread_local? |
550 | | // FIXME: We only need to register one __cxa_thread_atexit function for the |
551 | | // entire TU. |
552 | 191 | CXXThreadLocalInits.push_back(Fn); |
553 | 191 | CXXThreadLocalInitVars.push_back(D); |
554 | 5.65k | } else if (PerformInit && ISA5.23k ) { |
555 | 6 | EmitPointerToInitFunc(D, Addr, Fn, ISA); |
556 | 5.65k | } else if (auto *IPA = D->getAttr<InitPriorityAttr>()) { |
557 | 929 | OrderGlobalInitsOrStermFinalizers Key(IPA->getPriority(), |
558 | 929 | PrioritizedCXXGlobalInits.size()); |
559 | 929 | PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn)); |
560 | 4.72k | } else if (isTemplateInstantiation(D->getTemplateSpecializationKind()) || |
561 | 4.72k | getContext().GetGVALinkageForVariable(D) == GVA_DiscardableODR4.61k || |
562 | 4.72k | D->hasAttr<SelectAnyAttr>()4.58k ) { |
563 | | // C++ [basic.start.init]p2: |
564 | | // Definitions of explicitly specialized class template static data |
565 | | // members have ordered initialization. Other class template static data |
566 | | // members (i.e., implicitly or explicitly instantiated specializations) |
567 | | // have unordered initialization. |
568 | | // |
569 | | // As a consequence, we can put them into their own llvm.global_ctors entry. |
570 | | // |
571 | | // If the global is externally visible, put the initializer into a COMDAT |
572 | | // group with the global being initialized. On most platforms, this is a |
573 | | // minor startup time optimization. In the MS C++ ABI, there are no guard |
574 | | // variables, so this COMDAT key is required for correctness. |
575 | | // |
576 | | // SelectAny globals will be comdat-folded. Put the initializer into a |
577 | | // COMDAT group associated with the global, so the initializers get folded |
578 | | // too. |
579 | | |
580 | 141 | AddGlobalCtor(Fn, 65535, COMDATKey); |
581 | 141 | if (COMDATKey && (106 getTriple().isOSBinFormatELF()106 || |
582 | 106 | getTarget().getCXXABI().isMicrosoft()37 )) { |
583 | | // When COMDAT is used on ELF or in the MS C++ ABI, the key must be in |
584 | | // llvm.used to prevent linker GC. |
585 | 106 | addUsedGlobal(COMDATKey); |
586 | 106 | } |
587 | | |
588 | | // If we used a COMDAT key for the global ctor, the init function can be |
589 | | // discarded if the global ctor entry is discarded. |
590 | | // FIXME: Do we need to restrict this to ELF and Wasm? |
591 | 141 | llvm::Comdat *C = Addr->getComdat(); |
592 | 141 | if (COMDATKey && C106 && |
593 | 141 | (106 getTarget().getTriple().isOSBinFormatELF()106 || |
594 | 106 | getTarget().getTriple().isOSBinFormatWasm()37 )) { |
595 | 69 | Fn->setComdat(C); |
596 | 69 | } |
597 | 4.58k | } else { |
598 | 4.58k | I = DelayedCXXInitPosition.find(D); // Re-do lookup in case of re-hash. |
599 | 4.58k | if (I == DelayedCXXInitPosition.end()) { |
600 | 3.34k | CXXGlobalInits.push_back(Fn); |
601 | 3.34k | } else if (1.23k I->second != ~0U1.23k ) { |
602 | 1.23k | assert(I->second < CXXGlobalInits.size() && |
603 | 1.23k | CXXGlobalInits[I->second] == nullptr); |
604 | 0 | CXXGlobalInits[I->second] = Fn; |
605 | 1.23k | } |
606 | 4.58k | } |
607 | | |
608 | | // Remember that we already emitted the initializer for this global. |
609 | 0 | DelayedCXXInitPosition[D] = ~0U; |
610 | 5.84k | } |
611 | | |
612 | 35.9k | void CodeGenModule::EmitCXXThreadLocalInitFunc() { |
613 | 35.9k | getCXXABI().EmitThreadLocalInitFuncs( |
614 | 35.9k | *this, CXXThreadLocals, CXXThreadLocalInits, CXXThreadLocalInitVars); |
615 | | |
616 | 35.9k | CXXThreadLocalInits.clear(); |
617 | 35.9k | CXXThreadLocalInitVars.clear(); |
618 | 35.9k | CXXThreadLocals.clear(); |
619 | 35.9k | } |
620 | | |
621 | 1.39k | static SmallString<128> getTransformedFileName(llvm::Module &M) { |
622 | 1.39k | SmallString<128> FileName = llvm::sys::path::filename(M.getName()); |
623 | | |
624 | 1.39k | if (FileName.empty()) |
625 | 0 | FileName = "<null>"; |
626 | | |
627 | 46.4k | for (size_t i = 0; i < FileName.size(); ++i45.0k ) { |
628 | | // Replace everything that's not [a-zA-Z0-9._] with a _. This set happens |
629 | | // to be the set of C preprocessing numbers. |
630 | 45.0k | if (!isPreprocessingNumberBody(FileName[i])) |
631 | 943 | FileName[i] = '_'; |
632 | 45.0k | } |
633 | | |
634 | 1.39k | return FileName; |
635 | 1.39k | } |
636 | | |
637 | 626 | static std::string getPrioritySuffix(unsigned int Priority) { |
638 | 626 | assert(Priority <= 65535 && "Priority should always be <= 65535."); |
639 | | |
640 | | // Compute the function suffix from priority. Prepend with zeroes to make |
641 | | // sure the function names are also ordered as priorities. |
642 | 0 | std::string PrioritySuffix = llvm::utostr(Priority); |
643 | 626 | PrioritySuffix = std::string(6 - PrioritySuffix.size(), '0') + PrioritySuffix; |
644 | | |
645 | 626 | return PrioritySuffix; |
646 | 626 | } |
647 | | |
648 | | void |
649 | 35.9k | CodeGenModule::EmitCXXGlobalInitFunc() { |
650 | 68.0k | while (!CXXGlobalInits.empty() && !CXXGlobalInits.back()33.5k ) |
651 | 32.1k | CXXGlobalInits.pop_back(); |
652 | | |
653 | 35.9k | if (CXXGlobalInits.empty() && PrioritizedCXXGlobalInits.empty()34.5k ) |
654 | 34.5k | return; |
655 | | |
656 | 1.39k | llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); |
657 | 1.39k | const CGFunctionInfo &FI = getTypes().arrangeNullaryFunction(); |
658 | | |
659 | | // Create our global prioritized initialization function. |
660 | 1.39k | if (!PrioritizedCXXGlobalInits.empty()) { |
661 | 309 | SmallVector<llvm::Function *, 8> LocalCXXGlobalInits; |
662 | 309 | llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(), |
663 | 309 | PrioritizedCXXGlobalInits.end()); |
664 | | // Iterate over "chunks" of ctors with same priority and emit each chunk |
665 | | // into separate function. Note - everything is sorted first by priority, |
666 | | // second - by lex order, so we emit ctor functions in proper order. |
667 | 309 | for (SmallVectorImpl<GlobalInitData >::iterator |
668 | 309 | I = PrioritizedCXXGlobalInits.begin(), |
669 | 929 | E = PrioritizedCXXGlobalInits.end(); I != E; ) { |
670 | 620 | SmallVectorImpl<GlobalInitData >::iterator |
671 | 620 | PrioE = std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp()); |
672 | | |
673 | 620 | LocalCXXGlobalInits.clear(); |
674 | | |
675 | 620 | unsigned int Priority = I->first.priority; |
676 | 620 | llvm::Function *Fn = CreateGlobalInitOrCleanUpFunction( |
677 | 620 | FTy, "_GLOBAL__I_" + getPrioritySuffix(Priority), FI); |
678 | | |
679 | 1.54k | for (; I < PrioE; ++I929 ) |
680 | 929 | LocalCXXGlobalInits.push_back(I->second); |
681 | | |
682 | 620 | CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, LocalCXXGlobalInits); |
683 | 620 | AddGlobalCtor(Fn, Priority); |
684 | 620 | } |
685 | 309 | PrioritizedCXXGlobalInits.clear(); |
686 | 309 | } |
687 | | |
688 | 1.39k | if (getCXXABI().useSinitAndSterm() && CXXGlobalInits.empty()15 ) |
689 | 0 | return; |
690 | | |
691 | | // Include the filename in the symbol name. Including "sub_" matches gcc |
692 | | // and makes sure these symbols appear lexicographically behind the symbols |
693 | | // with priority emitted above. |
694 | 1.39k | llvm::Function *Fn = CreateGlobalInitOrCleanUpFunction( |
695 | 1.39k | FTy, llvm::Twine("_GLOBAL__sub_I_", getTransformedFileName(getModule())), |
696 | 1.39k | FI); |
697 | | |
698 | 1.39k | CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXGlobalInits); |
699 | 1.39k | AddGlobalCtor(Fn); |
700 | | |
701 | | // In OpenCL global init functions must be converted to kernels in order to |
702 | | // be able to launch them from the host. |
703 | | // FIXME: Some more work might be needed to handle destructors correctly. |
704 | | // Current initialization function makes use of function pointers callbacks. |
705 | | // We can't support function pointers especially between host and device. |
706 | | // However it seems global destruction has little meaning without any |
707 | | // dynamic resource allocation on the device and program scope variables are |
708 | | // destroyed by the runtime when program is released. |
709 | 1.39k | if (getLangOpts().OpenCL) { |
710 | 9 | GenKernelArgMetadata(Fn); |
711 | 9 | Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL); |
712 | 9 | } |
713 | | |
714 | 1.39k | assert(!getLangOpts().CUDA || !getLangOpts().CUDAIsDevice || |
715 | 1.39k | getLangOpts().GPUAllowDeviceInit); |
716 | 1.39k | if (getLangOpts().HIP && getLangOpts().CUDAIsDevice1 ) { |
717 | 1 | Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL); |
718 | 1 | Fn->addFnAttr("device-init"); |
719 | 1 | } |
720 | | |
721 | 1.39k | CXXGlobalInits.clear(); |
722 | 1.39k | } |
723 | | |
724 | 35.9k | void CodeGenModule::EmitCXXGlobalCleanUpFunc() { |
725 | 35.9k | if (CXXGlobalDtorsOrStermFinalizers.empty() && |
726 | 35.9k | PrioritizedCXXStermFinalizers.empty()35.8k ) |
727 | 35.8k | return; |
728 | | |
729 | 17 | llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); |
730 | 17 | const CGFunctionInfo &FI = getTypes().arrangeNullaryFunction(); |
731 | | |
732 | | // Create our global prioritized cleanup function. |
733 | 17 | if (!PrioritizedCXXStermFinalizers.empty()) { |
734 | 2 | SmallVector<CXXGlobalDtorsOrStermFinalizer_t, 8> LocalCXXStermFinalizers; |
735 | 2 | llvm::array_pod_sort(PrioritizedCXXStermFinalizers.begin(), |
736 | 2 | PrioritizedCXXStermFinalizers.end()); |
737 | | // Iterate over "chunks" of dtors with same priority and emit each chunk |
738 | | // into separate function. Note - everything is sorted first by priority, |
739 | | // second - by lex order, so we emit dtor functions in proper order. |
740 | 2 | for (SmallVectorImpl<StermFinalizerData>::iterator |
741 | 2 | I = PrioritizedCXXStermFinalizers.begin(), |
742 | 2 | E = PrioritizedCXXStermFinalizers.end(); |
743 | 8 | I != E;) { |
744 | 6 | SmallVectorImpl<StermFinalizerData>::iterator PrioE = |
745 | 6 | std::upper_bound(I + 1, E, *I, StermFinalizerPriorityCmp()); |
746 | | |
747 | 6 | LocalCXXStermFinalizers.clear(); |
748 | | |
749 | 6 | unsigned int Priority = I->first.priority; |
750 | 6 | llvm::Function *Fn = CreateGlobalInitOrCleanUpFunction( |
751 | 6 | FTy, "_GLOBAL__a_" + getPrioritySuffix(Priority), FI); |
752 | | |
753 | 14 | for (; I < PrioE; ++I8 ) { |
754 | 8 | llvm::FunctionCallee DtorFn = I->second; |
755 | 8 | LocalCXXStermFinalizers.emplace_back(DtorFn.getFunctionType(), |
756 | 8 | DtorFn.getCallee(), nullptr); |
757 | 8 | } |
758 | | |
759 | 6 | CodeGenFunction(*this).GenerateCXXGlobalCleanUpFunc( |
760 | 6 | Fn, LocalCXXStermFinalizers); |
761 | 6 | AddGlobalDtor(Fn, Priority); |
762 | 6 | } |
763 | 2 | PrioritizedCXXStermFinalizers.clear(); |
764 | 2 | } |
765 | | |
766 | 17 | if (CXXGlobalDtorsOrStermFinalizers.empty()) |
767 | 0 | return; |
768 | | |
769 | | // Create our global cleanup function. |
770 | 17 | llvm::Function *Fn = |
771 | 17 | CreateGlobalInitOrCleanUpFunction(FTy, "_GLOBAL__D_a", FI); |
772 | | |
773 | 17 | CodeGenFunction(*this).GenerateCXXGlobalCleanUpFunc( |
774 | 17 | Fn, CXXGlobalDtorsOrStermFinalizers); |
775 | 17 | AddGlobalDtor(Fn); |
776 | 17 | CXXGlobalDtorsOrStermFinalizers.clear(); |
777 | 17 | } |
778 | | |
779 | | /// Emit the code necessary to initialize the given global variable. |
780 | | void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, |
781 | | const VarDecl *D, |
782 | | llvm::GlobalVariable *Addr, |
783 | 5.84k | bool PerformInit) { |
784 | | // Check if we need to emit debug info for variable initializer. |
785 | 5.84k | if (D->hasAttr<NoDebugAttr>()) |
786 | 1 | DebugInfo = nullptr; // disable debug info indefinitely for this function |
787 | | |
788 | 5.84k | CurEHLocation = D->getBeginLoc(); |
789 | | |
790 | 5.84k | StartFunction(GlobalDecl(D, DynamicInitKind::Initializer), |
791 | 5.84k | getContext().VoidTy, Fn, getTypes().arrangeNullaryFunction(), |
792 | 5.84k | FunctionArgList()); |
793 | | // Emit an artificial location for this function. |
794 | 5.84k | auto AL = ApplyDebugLocation::CreateArtificial(*this); |
795 | | |
796 | | // Use guarded initialization if the global variable is weak. This |
797 | | // occurs for, e.g., instantiated static data members and |
798 | | // definitions explicitly marked weak. |
799 | | // |
800 | | // Also use guarded initialization for a variable with dynamic TLS and |
801 | | // unordered initialization. (If the initialization is ordered, the ABI |
802 | | // layer will guard the whole-TU initialization for us.) |
803 | 5.84k | if (Addr->hasWeakLinkage() || Addr->hasLinkOnceLinkage()5.77k || |
804 | 5.84k | (5.61k D->getTLSKind() == VarDecl::TLS_Dynamic5.61k && |
805 | 5.61k | isTemplateInstantiation(D->getTemplateSpecializationKind())105 )) { |
806 | 230 | EmitCXXGuardedInit(*D, Addr, PerformInit); |
807 | 5.61k | } else { |
808 | 5.61k | EmitCXXGlobalVarDeclInit(*D, Addr, PerformInit); |
809 | 5.61k | } |
810 | | |
811 | 5.84k | FinishFunction(); |
812 | 5.84k | } |
813 | | |
814 | | void |
815 | | CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn, |
816 | | ArrayRef<llvm::Function *> Decls, |
817 | 2.07k | ConstantAddress Guard) { |
818 | 2.07k | { |
819 | 2.07k | auto NL = ApplyDebugLocation::CreateEmpty(*this); |
820 | 2.07k | StartFunction(GlobalDecl(), getContext().VoidTy, Fn, |
821 | 2.07k | getTypes().arrangeNullaryFunction(), FunctionArgList()); |
822 | | // Emit an artificial location for this function. |
823 | 2.07k | auto AL = ApplyDebugLocation::CreateArtificial(*this); |
824 | | |
825 | 2.07k | llvm::BasicBlock *ExitBlock = nullptr; |
826 | 2.07k | if (Guard.isValid()) { |
827 | | // If we have a guard variable, check whether we've already performed |
828 | | // these initializations. This happens for TLS initialization functions. |
829 | 51 | llvm::Value *GuardVal = Builder.CreateLoad(Guard); |
830 | 51 | llvm::Value *Uninit = Builder.CreateIsNull(GuardVal, |
831 | 51 | "guard.uninitialized"); |
832 | 51 | llvm::BasicBlock *InitBlock = createBasicBlock("init"); |
833 | 51 | ExitBlock = createBasicBlock("exit"); |
834 | 51 | EmitCXXGuardedInitBranch(Uninit, InitBlock, ExitBlock, |
835 | 51 | GuardKind::TlsGuard, nullptr); |
836 | 51 | EmitBlock(InitBlock); |
837 | | // Mark as initialized before initializing anything else. If the |
838 | | // initializers use previously-initialized thread_local vars, that's |
839 | | // probably supposed to be OK, but the standard doesn't say. |
840 | 51 | Builder.CreateStore(llvm::ConstantInt::get(GuardVal->getType(),1), Guard); |
841 | | |
842 | | // The guard variable can't ever change again. |
843 | 51 | EmitInvariantStart( |
844 | 51 | Guard.getPointer(), |
845 | 51 | CharUnits::fromQuantity( |
846 | 51 | CGM.getDataLayout().getTypeAllocSize(GuardVal->getType()))); |
847 | 51 | } |
848 | | |
849 | 2.07k | RunCleanupsScope Scope(*this); |
850 | | |
851 | | // When building in Objective-C++ ARC mode, create an autorelease pool |
852 | | // around the global initializers. |
853 | 2.07k | if (getLangOpts().ObjCAutoRefCount && getLangOpts().CPlusPlus4 ) { |
854 | 4 | llvm::Value *token = EmitObjCAutoreleasePoolPush(); |
855 | 4 | EmitObjCAutoreleasePoolCleanup(token); |
856 | 4 | } |
857 | | |
858 | 10.4k | for (unsigned i = 0, e = Decls.size(); i != e; ++i8.38k ) |
859 | 8.38k | if (Decls[i]) |
860 | 5.61k | EmitRuntimeCall(Decls[i]); |
861 | | |
862 | 2.07k | Scope.ForceCleanup(); |
863 | | |
864 | 2.07k | if (ExitBlock) { |
865 | 51 | Builder.CreateBr(ExitBlock); |
866 | 51 | EmitBlock(ExitBlock); |
867 | 51 | } |
868 | 2.07k | } |
869 | | |
870 | 2.07k | FinishFunction(); |
871 | 2.07k | } |
872 | | |
873 | | void CodeGenFunction::GenerateCXXGlobalCleanUpFunc( |
874 | | llvm::Function *Fn, |
875 | | ArrayRef<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH, |
876 | | llvm::Constant *>> |
877 | 23 | DtorsOrStermFinalizers) { |
878 | 23 | { |
879 | 23 | auto NL = ApplyDebugLocation::CreateEmpty(*this); |
880 | 23 | StartFunction(GlobalDecl(), getContext().VoidTy, Fn, |
881 | 23 | getTypes().arrangeNullaryFunction(), FunctionArgList()); |
882 | | // Emit an artificial location for this function. |
883 | 23 | auto AL = ApplyDebugLocation::CreateArtificial(*this); |
884 | | |
885 | | // Emit the cleanups, in reverse order from construction. |
886 | 59 | for (unsigned i = 0, e = DtorsOrStermFinalizers.size(); i != e; ++i36 ) { |
887 | 36 | llvm::FunctionType *CalleeTy; |
888 | 36 | llvm::Value *Callee; |
889 | 36 | llvm::Constant *Arg; |
890 | 36 | std::tie(CalleeTy, Callee, Arg) = DtorsOrStermFinalizers[e - i - 1]; |
891 | | |
892 | 36 | llvm::CallInst *CI = nullptr; |
893 | 36 | if (Arg == nullptr) { |
894 | 30 | assert( |
895 | 30 | CGM.getCXXABI().useSinitAndSterm() && |
896 | 30 | "Arg could not be nullptr unless using sinit and sterm functions."); |
897 | 0 | CI = Builder.CreateCall(CalleeTy, Callee); |
898 | 30 | } else |
899 | 6 | CI = Builder.CreateCall(CalleeTy, Callee, Arg); |
900 | | |
901 | | // Make sure the call and the callee agree on calling convention. |
902 | 36 | if (llvm::Function *F = dyn_cast<llvm::Function>(Callee)) |
903 | 36 | CI->setCallingConv(F->getCallingConv()); |
904 | 36 | } |
905 | 23 | } |
906 | | |
907 | 23 | FinishFunction(); |
908 | 23 | } |
909 | | |
910 | | /// generateDestroyHelper - Generates a helper function which, when |
911 | | /// invoked, destroys the given object. The address of the object |
912 | | /// should be in global memory. |
913 | | llvm::Function *CodeGenFunction::generateDestroyHelper( |
914 | | Address addr, QualType type, Destroyer *destroyer, |
915 | 342 | bool useEHCleanupForArray, const VarDecl *VD) { |
916 | 342 | FunctionArgList args; |
917 | 342 | ImplicitParamDecl Dst(getContext(), getContext().VoidPtrTy, |
918 | 342 | ImplicitParamDecl::Other); |
919 | 342 | args.push_back(&Dst); |
920 | | |
921 | 342 | const CGFunctionInfo &FI = |
922 | 342 | CGM.getTypes().arrangeBuiltinFunctionDeclaration(getContext().VoidTy, args); |
923 | 342 | llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI); |
924 | 342 | llvm::Function *fn = CGM.CreateGlobalInitOrCleanUpFunction( |
925 | 342 | FTy, "__cxx_global_array_dtor", FI, VD->getLocation()); |
926 | | |
927 | 342 | CurEHLocation = VD->getBeginLoc(); |
928 | | |
929 | 342 | StartFunction(GlobalDecl(VD, DynamicInitKind::GlobalArrayDestructor), |
930 | 342 | getContext().VoidTy, fn, FI, args); |
931 | | // Emit an artificial location for this function. |
932 | 342 | auto AL = ApplyDebugLocation::CreateArtificial(*this); |
933 | | |
934 | 342 | emitDestroy(addr, type, destroyer, useEHCleanupForArray); |
935 | | |
936 | 342 | FinishFunction(); |
937 | | |
938 | 342 | return fn; |
939 | 342 | } |