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