Bug Summary

File:clang/lib/CodeGen/CGOpenMPRuntime.cpp
Warning:line 11547, column 58
Division by zero

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name CGOpenMPRuntime.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/clang/lib/CodeGen -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/clang/lib/CodeGen -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/clang/lib/CodeGen -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/clang/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/include -I /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/include -D NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/build-llvm/tools/clang/lib/CodeGen -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e=. -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2021-09-04-040900-46481-1 -x c++ /build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/clang/lib/CodeGen/CGOpenMPRuntime.cpp

/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/clang/lib/CodeGen/CGOpenMPRuntime.cpp

1//===----- CGOpenMPRuntime.cpp - Interface to OpenMP Runtimes -------------===//
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 provides a class for OpenMP runtime code generation.
10//
11//===----------------------------------------------------------------------===//
12
13#include "CGOpenMPRuntime.h"
14#include "CGCXXABI.h"
15#include "CGCleanup.h"
16#include "CGRecordLayout.h"
17#include "CodeGenFunction.h"
18#include "clang/AST/APValue.h"
19#include "clang/AST/Attr.h"
20#include "clang/AST/Decl.h"
21#include "clang/AST/OpenMPClause.h"
22#include "clang/AST/StmtOpenMP.h"
23#include "clang/AST/StmtVisitor.h"
24#include "clang/Basic/BitmaskEnum.h"
25#include "clang/Basic/FileManager.h"
26#include "clang/Basic/OpenMPKinds.h"
27#include "clang/Basic/SourceManager.h"
28#include "clang/CodeGen/ConstantInitBuilder.h"
29#include "llvm/ADT/ArrayRef.h"
30#include "llvm/ADT/SetOperations.h"
31#include "llvm/ADT/StringExtras.h"
32#include "llvm/Bitcode/BitcodeReader.h"
33#include "llvm/IR/Constants.h"
34#include "llvm/IR/DerivedTypes.h"
35#include "llvm/IR/GlobalValue.h"
36#include "llvm/IR/Value.h"
37#include "llvm/Support/AtomicOrdering.h"
38#include "llvm/Support/Format.h"
39#include "llvm/Support/raw_ostream.h"
40#include <cassert>
41#include <numeric>
42
43using namespace clang;
44using namespace CodeGen;
45using namespace llvm::omp;
46
47namespace {
48/// Base class for handling code generation inside OpenMP regions.
49class CGOpenMPRegionInfo : public CodeGenFunction::CGCapturedStmtInfo {
50public:
51 /// Kinds of OpenMP regions used in codegen.
52 enum CGOpenMPRegionKind {
53 /// Region with outlined function for standalone 'parallel'
54 /// directive.
55 ParallelOutlinedRegion,
56 /// Region with outlined function for standalone 'task' directive.
57 TaskOutlinedRegion,
58 /// Region for constructs that do not require function outlining,
59 /// like 'for', 'sections', 'atomic' etc. directives.
60 InlinedRegion,
61 /// Region with outlined function for standalone 'target' directive.
62 TargetRegion,
63 };
64
65 CGOpenMPRegionInfo(const CapturedStmt &CS,
66 const CGOpenMPRegionKind RegionKind,
67 const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind,
68 bool HasCancel)
69 : CGCapturedStmtInfo(CS, CR_OpenMP), RegionKind(RegionKind),
70 CodeGen(CodeGen), Kind(Kind), HasCancel(HasCancel) {}
71
72 CGOpenMPRegionInfo(const CGOpenMPRegionKind RegionKind,
73 const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind,
74 bool HasCancel)
75 : CGCapturedStmtInfo(CR_OpenMP), RegionKind(RegionKind), CodeGen(CodeGen),
76 Kind(Kind), HasCancel(HasCancel) {}
77
78 /// Get a variable or parameter for storing global thread id
79 /// inside OpenMP construct.
80 virtual const VarDecl *getThreadIDVariable() const = 0;
81
82 /// Emit the captured statement body.
83 void EmitBody(CodeGenFunction &CGF, const Stmt *S) override;
84
85 /// Get an LValue for the current ThreadID variable.
86 /// \return LValue for thread id variable. This LValue always has type int32*.
87 virtual LValue getThreadIDVariableLValue(CodeGenFunction &CGF);
88
89 virtual void emitUntiedSwitch(CodeGenFunction & /*CGF*/) {}
90
91 CGOpenMPRegionKind getRegionKind() const { return RegionKind; }
92
93 OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
94
95 bool hasCancel() const { return HasCancel; }
96
97 static bool classof(const CGCapturedStmtInfo *Info) {
98 return Info->getKind() == CR_OpenMP;
99 }
100
101 ~CGOpenMPRegionInfo() override = default;
102
103protected:
104 CGOpenMPRegionKind RegionKind;
105 RegionCodeGenTy CodeGen;
106 OpenMPDirectiveKind Kind;
107 bool HasCancel;
108};
109
110/// API for captured statement code generation in OpenMP constructs.
111class CGOpenMPOutlinedRegionInfo final : public CGOpenMPRegionInfo {
112public:
113 CGOpenMPOutlinedRegionInfo(const CapturedStmt &CS, const VarDecl *ThreadIDVar,
114 const RegionCodeGenTy &CodeGen,
115 OpenMPDirectiveKind Kind, bool HasCancel,
116 StringRef HelperName)
117 : CGOpenMPRegionInfo(CS, ParallelOutlinedRegion, CodeGen, Kind,
118 HasCancel),
119 ThreadIDVar(ThreadIDVar), HelperName(HelperName) {
120 assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region.")(static_cast<void> (0));
121 }
122
123 /// Get a variable or parameter for storing global thread id
124 /// inside OpenMP construct.
125 const VarDecl *getThreadIDVariable() const override { return ThreadIDVar; }
126
127 /// Get the name of the capture helper.
128 StringRef getHelperName() const override { return HelperName; }
129
130 static bool classof(const CGCapturedStmtInfo *Info) {
131 return CGOpenMPRegionInfo::classof(Info) &&
132 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() ==
133 ParallelOutlinedRegion;
134 }
135
136private:
137 /// A variable or parameter storing global thread id for OpenMP
138 /// constructs.
139 const VarDecl *ThreadIDVar;
140 StringRef HelperName;
141};
142
143/// API for captured statement code generation in OpenMP constructs.
144class CGOpenMPTaskOutlinedRegionInfo final : public CGOpenMPRegionInfo {
145public:
146 class UntiedTaskActionTy final : public PrePostActionTy {
147 bool Untied;
148 const VarDecl *PartIDVar;
149 const RegionCodeGenTy UntiedCodeGen;
150 llvm::SwitchInst *UntiedSwitch = nullptr;
151
152 public:
153 UntiedTaskActionTy(bool Tied, const VarDecl *PartIDVar,
154 const RegionCodeGenTy &UntiedCodeGen)
155 : Untied(!Tied), PartIDVar(PartIDVar), UntiedCodeGen(UntiedCodeGen) {}
156 void Enter(CodeGenFunction &CGF) override {
157 if (Untied) {
158 // Emit task switching point.
159 LValue PartIdLVal = CGF.EmitLoadOfPointerLValue(
160 CGF.GetAddrOfLocalVar(PartIDVar),
161 PartIDVar->getType()->castAs<PointerType>());
162 llvm::Value *Res =
163 CGF.EmitLoadOfScalar(PartIdLVal, PartIDVar->getLocation());
164 llvm::BasicBlock *DoneBB = CGF.createBasicBlock(".untied.done.");
165 UntiedSwitch = CGF.Builder.CreateSwitch(Res, DoneBB);
166 CGF.EmitBlock(DoneBB);
167 CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);
168 CGF.EmitBlock(CGF.createBasicBlock(".untied.jmp."));
169 UntiedSwitch->addCase(CGF.Builder.getInt32(0),
170 CGF.Builder.GetInsertBlock());
171 emitUntiedSwitch(CGF);
172 }
173 }
174 void emitUntiedSwitch(CodeGenFunction &CGF) const {
175 if (Untied) {
176 LValue PartIdLVal = CGF.EmitLoadOfPointerLValue(
177 CGF.GetAddrOfLocalVar(PartIDVar),
178 PartIDVar->getType()->castAs<PointerType>());
179 CGF.EmitStoreOfScalar(CGF.Builder.getInt32(UntiedSwitch->getNumCases()),
180 PartIdLVal);
181 UntiedCodeGen(CGF);
182 CodeGenFunction::JumpDest CurPoint =
183 CGF.getJumpDestInCurrentScope(".untied.next.");
184 CGF.EmitBranch(CGF.ReturnBlock.getBlock());
185 CGF.EmitBlock(CGF.createBasicBlock(".untied.jmp."));
186 UntiedSwitch->addCase(CGF.Builder.getInt32(UntiedSwitch->getNumCases()),
187 CGF.Builder.GetInsertBlock());
188 CGF.EmitBranchThroughCleanup(CurPoint);
189 CGF.EmitBlock(CurPoint.getBlock());
190 }
191 }
192 unsigned getNumberOfParts() const { return UntiedSwitch->getNumCases(); }
193 };
194 CGOpenMPTaskOutlinedRegionInfo(const CapturedStmt &CS,
195 const VarDecl *ThreadIDVar,
196 const RegionCodeGenTy &CodeGen,
197 OpenMPDirectiveKind Kind, bool HasCancel,
198 const UntiedTaskActionTy &Action)
199 : CGOpenMPRegionInfo(CS, TaskOutlinedRegion, CodeGen, Kind, HasCancel),
200 ThreadIDVar(ThreadIDVar), Action(Action) {
201 assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region.")(static_cast<void> (0));
202 }
203
204 /// Get a variable or parameter for storing global thread id
205 /// inside OpenMP construct.
206 const VarDecl *getThreadIDVariable() const override { return ThreadIDVar; }
207
208 /// Get an LValue for the current ThreadID variable.
209 LValue getThreadIDVariableLValue(CodeGenFunction &CGF) override;
210
211 /// Get the name of the capture helper.
212 StringRef getHelperName() const override { return ".omp_outlined."; }
213
214 void emitUntiedSwitch(CodeGenFunction &CGF) override {
215 Action.emitUntiedSwitch(CGF);
216 }
217
218 static bool classof(const CGCapturedStmtInfo *Info) {
219 return CGOpenMPRegionInfo::classof(Info) &&
220 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() ==
221 TaskOutlinedRegion;
222 }
223
224private:
225 /// A variable or parameter storing global thread id for OpenMP
226 /// constructs.
227 const VarDecl *ThreadIDVar;
228 /// Action for emitting code for untied tasks.
229 const UntiedTaskActionTy &Action;
230};
231
232/// API for inlined captured statement code generation in OpenMP
233/// constructs.
234class CGOpenMPInlinedRegionInfo : public CGOpenMPRegionInfo {
235public:
236 CGOpenMPInlinedRegionInfo(CodeGenFunction::CGCapturedStmtInfo *OldCSI,
237 const RegionCodeGenTy &CodeGen,
238 OpenMPDirectiveKind Kind, bool HasCancel)
239 : CGOpenMPRegionInfo(InlinedRegion, CodeGen, Kind, HasCancel),
240 OldCSI(OldCSI),
241 OuterRegionInfo(dyn_cast_or_null<CGOpenMPRegionInfo>(OldCSI)) {}
242
243 // Retrieve the value of the context parameter.
244 llvm::Value *getContextValue() const override {
245 if (OuterRegionInfo)
246 return OuterRegionInfo->getContextValue();
247 llvm_unreachable("No context value for inlined OpenMP region")__builtin_unreachable();
248 }
249
250 void setContextValue(llvm::Value *V) override {
251 if (OuterRegionInfo) {
252 OuterRegionInfo->setContextValue(V);
253 return;
254 }
255 llvm_unreachable("No context value for inlined OpenMP region")__builtin_unreachable();
256 }
257
258 /// Lookup the captured field decl for a variable.
259 const FieldDecl *lookup(const VarDecl *VD) const override {
260 if (OuterRegionInfo)
261 return OuterRegionInfo->lookup(VD);
262 // If there is no outer outlined region,no need to lookup in a list of
263 // captured variables, we can use the original one.
264 return nullptr;
265 }
266
267 FieldDecl *getThisFieldDecl() const override {
268 if (OuterRegionInfo)
269 return OuterRegionInfo->getThisFieldDecl();
270 return nullptr;
271 }
272
273 /// Get a variable or parameter for storing global thread id
274 /// inside OpenMP construct.
275 const VarDecl *getThreadIDVariable() const override {
276 if (OuterRegionInfo)
277 return OuterRegionInfo->getThreadIDVariable();
278 return nullptr;
279 }
280
281 /// Get an LValue for the current ThreadID variable.
282 LValue getThreadIDVariableLValue(CodeGenFunction &CGF) override {
283 if (OuterRegionInfo)
284 return OuterRegionInfo->getThreadIDVariableLValue(CGF);
285 llvm_unreachable("No LValue for inlined OpenMP construct")__builtin_unreachable();
286 }
287
288 /// Get the name of the capture helper.
289 StringRef getHelperName() const override {
290 if (auto *OuterRegionInfo = getOldCSI())
291 return OuterRegionInfo->getHelperName();
292 llvm_unreachable("No helper name for inlined OpenMP construct")__builtin_unreachable();
293 }
294
295 void emitUntiedSwitch(CodeGenFunction &CGF) override {
296 if (OuterRegionInfo)
297 OuterRegionInfo->emitUntiedSwitch(CGF);
298 }
299
300 CodeGenFunction::CGCapturedStmtInfo *getOldCSI() const { return OldCSI; }
301
302 static bool classof(const CGCapturedStmtInfo *Info) {
303 return CGOpenMPRegionInfo::classof(Info) &&
304 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() == InlinedRegion;
305 }
306
307 ~CGOpenMPInlinedRegionInfo() override = default;
308
309private:
310 /// CodeGen info about outer OpenMP region.
311 CodeGenFunction::CGCapturedStmtInfo *OldCSI;
312 CGOpenMPRegionInfo *OuterRegionInfo;
313};
314
315/// API for captured statement code generation in OpenMP target
316/// constructs. For this captures, implicit parameters are used instead of the
317/// captured fields. The name of the target region has to be unique in a given
318/// application so it is provided by the client, because only the client has
319/// the information to generate that.
320class CGOpenMPTargetRegionInfo final : public CGOpenMPRegionInfo {
321public:
322 CGOpenMPTargetRegionInfo(const CapturedStmt &CS,
323 const RegionCodeGenTy &CodeGen, StringRef HelperName)
324 : CGOpenMPRegionInfo(CS, TargetRegion, CodeGen, OMPD_target,
325 /*HasCancel=*/false),
326 HelperName(HelperName) {}
327
328 /// This is unused for target regions because each starts executing
329 /// with a single thread.
330 const VarDecl *getThreadIDVariable() const override { return nullptr; }
331
332 /// Get the name of the capture helper.
333 StringRef getHelperName() const override { return HelperName; }
334
335 static bool classof(const CGCapturedStmtInfo *Info) {
336 return CGOpenMPRegionInfo::classof(Info) &&
337 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() == TargetRegion;
338 }
339
340private:
341 StringRef HelperName;
342};
343
344static void EmptyCodeGen(CodeGenFunction &, PrePostActionTy &) {
345 llvm_unreachable("No codegen for expressions")__builtin_unreachable();
346}
347/// API for generation of expressions captured in a innermost OpenMP
348/// region.
349class CGOpenMPInnerExprInfo final : public CGOpenMPInlinedRegionInfo {
350public:
351 CGOpenMPInnerExprInfo(CodeGenFunction &CGF, const CapturedStmt &CS)
352 : CGOpenMPInlinedRegionInfo(CGF.CapturedStmtInfo, EmptyCodeGen,
353 OMPD_unknown,
354 /*HasCancel=*/false),
355 PrivScope(CGF) {
356 // Make sure the globals captured in the provided statement are local by
357 // using the privatization logic. We assume the same variable is not
358 // captured more than once.
359 for (const auto &C : CS.captures()) {
360 if (!C.capturesVariable() && !C.capturesVariableByCopy())
361 continue;
362
363 const VarDecl *VD = C.getCapturedVar();
364 if (VD->isLocalVarDeclOrParm())
365 continue;
366
367 DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(VD),
368 /*RefersToEnclosingVariableOrCapture=*/false,
369 VD->getType().getNonReferenceType(), VK_LValue,
370 C.getLocation());
371 PrivScope.addPrivate(
372 VD, [&CGF, &DRE]() { return CGF.EmitLValue(&DRE).getAddress(CGF); });
373 }
374 (void)PrivScope.Privatize();
375 }
376
377 /// Lookup the captured field decl for a variable.
378 const FieldDecl *lookup(const VarDecl *VD) const override {
379 if (const FieldDecl *FD = CGOpenMPInlinedRegionInfo::lookup(VD))
380 return FD;
381 return nullptr;
382 }
383
384 /// Emit the captured statement body.
385 void EmitBody(CodeGenFunction &CGF, const Stmt *S) override {
386 llvm_unreachable("No body for expressions")__builtin_unreachable();
387 }
388
389 /// Get a variable or parameter for storing global thread id
390 /// inside OpenMP construct.
391 const VarDecl *getThreadIDVariable() const override {
392 llvm_unreachable("No thread id for expressions")__builtin_unreachable();
393 }
394
395 /// Get the name of the capture helper.
396 StringRef getHelperName() const override {
397 llvm_unreachable("No helper name for expressions")__builtin_unreachable();
398 }
399
400 static bool classof(const CGCapturedStmtInfo *Info) { return false; }
401
402private:
403 /// Private scope to capture global variables.
404 CodeGenFunction::OMPPrivateScope PrivScope;
405};
406
407/// RAII for emitting code of OpenMP constructs.
408class InlinedOpenMPRegionRAII {
409 CodeGenFunction &CGF;
410 llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
411 FieldDecl *LambdaThisCaptureField = nullptr;
412 const CodeGen::CGBlockInfo *BlockInfo = nullptr;
413 bool NoInheritance = false;
414
415public:
416 /// Constructs region for combined constructs.
417 /// \param CodeGen Code generation sequence for combined directives. Includes
418 /// a list of functions used for code generation of implicitly inlined
419 /// regions.
420 InlinedOpenMPRegionRAII(CodeGenFunction &CGF, const RegionCodeGenTy &CodeGen,
421 OpenMPDirectiveKind Kind, bool HasCancel,
422 bool NoInheritance = true)
423 : CGF(CGF), NoInheritance(NoInheritance) {
424 // Start emission for the construct.
425 CGF.CapturedStmtInfo = new CGOpenMPInlinedRegionInfo(
426 CGF.CapturedStmtInfo, CodeGen, Kind, HasCancel);
427 if (NoInheritance) {
428 std::swap(CGF.LambdaCaptureFields, LambdaCaptureFields);
429 LambdaThisCaptureField = CGF.LambdaThisCaptureField;
430 CGF.LambdaThisCaptureField = nullptr;
431 BlockInfo = CGF.BlockInfo;
432 CGF.BlockInfo = nullptr;
433 }
434 }
435
436 ~InlinedOpenMPRegionRAII() {
437 // Restore original CapturedStmtInfo only if we're done with code emission.
438 auto *OldCSI =
439 cast<CGOpenMPInlinedRegionInfo>(CGF.CapturedStmtInfo)->getOldCSI();
440 delete CGF.CapturedStmtInfo;
441 CGF.CapturedStmtInfo = OldCSI;
442 if (NoInheritance) {
443 std::swap(CGF.LambdaCaptureFields, LambdaCaptureFields);
444 CGF.LambdaThisCaptureField = LambdaThisCaptureField;
445 CGF.BlockInfo = BlockInfo;
446 }
447 }
448};
449
450/// Values for bit flags used in the ident_t to describe the fields.
451/// All enumeric elements are named and described in accordance with the code
452/// from https://github.com/llvm/llvm-project/blob/main/openmp/runtime/src/kmp.h
453enum OpenMPLocationFlags : unsigned {
454 /// Use trampoline for internal microtask.
455 OMP_IDENT_IMD = 0x01,
456 /// Use c-style ident structure.
457 OMP_IDENT_KMPC = 0x02,
458 /// Atomic reduction option for kmpc_reduce.
459 OMP_ATOMIC_REDUCE = 0x10,
460 /// Explicit 'barrier' directive.
461 OMP_IDENT_BARRIER_EXPL = 0x20,
462 /// Implicit barrier in code.
463 OMP_IDENT_BARRIER_IMPL = 0x40,
464 /// Implicit barrier in 'for' directive.
465 OMP_IDENT_BARRIER_IMPL_FOR = 0x40,
466 /// Implicit barrier in 'sections' directive.
467 OMP_IDENT_BARRIER_IMPL_SECTIONS = 0xC0,
468 /// Implicit barrier in 'single' directive.
469 OMP_IDENT_BARRIER_IMPL_SINGLE = 0x140,
470 /// Call of __kmp_for_static_init for static loop.
471 OMP_IDENT_WORK_LOOP = 0x200,
472 /// Call of __kmp_for_static_init for sections.
473 OMP_IDENT_WORK_SECTIONS = 0x400,
474 /// Call of __kmp_for_static_init for distribute.
475 OMP_IDENT_WORK_DISTRIBUTE = 0x800,
476 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/OMP_IDENT_WORK_DISTRIBUTE)LLVM_BITMASK_LARGEST_ENUMERATOR = OMP_IDENT_WORK_DISTRIBUTE
477};
478
479namespace {
480LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE()using ::llvm::BitmaskEnumDetail::operator~; using ::llvm::BitmaskEnumDetail
::operator|; using ::llvm::BitmaskEnumDetail::operator&; using
::llvm::BitmaskEnumDetail::operator^; using ::llvm::BitmaskEnumDetail
::operator|=; using ::llvm::BitmaskEnumDetail::operator&=
; using ::llvm::BitmaskEnumDetail::operator^=
;
481/// Values for bit flags for marking which requires clauses have been used.
482enum OpenMPOffloadingRequiresDirFlags : int64_t {
483 /// flag undefined.
484 OMP_REQ_UNDEFINED = 0x000,
485 /// no requires clause present.
486 OMP_REQ_NONE = 0x001,
487 /// reverse_offload clause.
488 OMP_REQ_REVERSE_OFFLOAD = 0x002,
489 /// unified_address clause.
490 OMP_REQ_UNIFIED_ADDRESS = 0x004,
491 /// unified_shared_memory clause.
492 OMP_REQ_UNIFIED_SHARED_MEMORY = 0x008,
493 /// dynamic_allocators clause.
494 OMP_REQ_DYNAMIC_ALLOCATORS = 0x010,
495 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/OMP_REQ_DYNAMIC_ALLOCATORS)LLVM_BITMASK_LARGEST_ENUMERATOR = OMP_REQ_DYNAMIC_ALLOCATORS
496};
497
498enum OpenMPOffloadingReservedDeviceIDs {
499 /// Device ID if the device was not defined, runtime should get it
500 /// from environment variables in the spec.
501 OMP_DEVICEID_UNDEF = -1,
502};
503} // anonymous namespace
504
505/// Describes ident structure that describes a source location.
506/// All descriptions are taken from
507/// https://github.com/llvm/llvm-project/blob/main/openmp/runtime/src/kmp.h
508/// Original structure:
509/// typedef struct ident {
510/// kmp_int32 reserved_1; /**< might be used in Fortran;
511/// see above */
512/// kmp_int32 flags; /**< also f.flags; KMP_IDENT_xxx flags;
513/// KMP_IDENT_KMPC identifies this union
514/// member */
515/// kmp_int32 reserved_2; /**< not really used in Fortran any more;
516/// see above */
517///#if USE_ITT_BUILD
518/// /* but currently used for storing
519/// region-specific ITT */
520/// /* contextual information. */
521///#endif /* USE_ITT_BUILD */
522/// kmp_int32 reserved_3; /**< source[4] in Fortran, do not use for
523/// C++ */
524/// char const *psource; /**< String describing the source location.
525/// The string is composed of semi-colon separated
526// fields which describe the source file,
527/// the function and a pair of line numbers that
528/// delimit the construct.
529/// */
530/// } ident_t;
531enum IdentFieldIndex {
532 /// might be used in Fortran
533 IdentField_Reserved_1,
534 /// OMP_IDENT_xxx flags; OMP_IDENT_KMPC identifies this union member.
535 IdentField_Flags,
536 /// Not really used in Fortran any more
537 IdentField_Reserved_2,
538 /// Source[4] in Fortran, do not use for C++
539 IdentField_Reserved_3,
540 /// String describing the source location. The string is composed of
541 /// semi-colon separated fields which describe the source file, the function
542 /// and a pair of line numbers that delimit the construct.
543 IdentField_PSource
544};
545
546/// Schedule types for 'omp for' loops (these enumerators are taken from
547/// the enum sched_type in kmp.h).
548enum OpenMPSchedType {
549 /// Lower bound for default (unordered) versions.
550 OMP_sch_lower = 32,
551 OMP_sch_static_chunked = 33,
552 OMP_sch_static = 34,
553 OMP_sch_dynamic_chunked = 35,
554 OMP_sch_guided_chunked = 36,
555 OMP_sch_runtime = 37,
556 OMP_sch_auto = 38,
557 /// static with chunk adjustment (e.g., simd)
558 OMP_sch_static_balanced_chunked = 45,
559 /// Lower bound for 'ordered' versions.
560 OMP_ord_lower = 64,
561 OMP_ord_static_chunked = 65,
562 OMP_ord_static = 66,
563 OMP_ord_dynamic_chunked = 67,
564 OMP_ord_guided_chunked = 68,
565 OMP_ord_runtime = 69,
566 OMP_ord_auto = 70,
567 OMP_sch_default = OMP_sch_static,
568 /// dist_schedule types
569 OMP_dist_sch_static_chunked = 91,
570 OMP_dist_sch_static = 92,
571 /// Support for OpenMP 4.5 monotonic and nonmonotonic schedule modifiers.
572 /// Set if the monotonic schedule modifier was present.
573 OMP_sch_modifier_monotonic = (1 << 29),
574 /// Set if the nonmonotonic schedule modifier was present.
575 OMP_sch_modifier_nonmonotonic = (1 << 30),
576};
577
578/// A basic class for pre|post-action for advanced codegen sequence for OpenMP
579/// region.
580class CleanupTy final : public EHScopeStack::Cleanup {
581 PrePostActionTy *Action;
582
583public:
584 explicit CleanupTy(PrePostActionTy *Action) : Action(Action) {}
585 void Emit(CodeGenFunction &CGF, Flags /*flags*/) override {
586 if (!CGF.HaveInsertPoint())
587 return;
588 Action->Exit(CGF);
589 }
590};
591
592} // anonymous namespace
593
594void RegionCodeGenTy::operator()(CodeGenFunction &CGF) const {
595 CodeGenFunction::RunCleanupsScope Scope(CGF);
596 if (PrePostAction) {
597 CGF.EHStack.pushCleanup<CleanupTy>(NormalAndEHCleanup, PrePostAction);
598 Callback(CodeGen, CGF, *PrePostAction);
599 } else {
600 PrePostActionTy Action;
601 Callback(CodeGen, CGF, Action);
602 }
603}
604
605/// Check if the combiner is a call to UDR combiner and if it is so return the
606/// UDR decl used for reduction.
607static const OMPDeclareReductionDecl *
608getReductionInit(const Expr *ReductionOp) {
609 if (const auto *CE = dyn_cast<CallExpr>(ReductionOp))
610 if (const auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee()))
611 if (const auto *DRE =
612 dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts()))
613 if (const auto *DRD = dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl()))
614 return DRD;
615 return nullptr;
616}
617
618static void emitInitWithReductionInitializer(CodeGenFunction &CGF,
619 const OMPDeclareReductionDecl *DRD,
620 const Expr *InitOp,
621 Address Private, Address Original,
622 QualType Ty) {
623 if (DRD->getInitializer()) {
624 std::pair<llvm::Function *, llvm::Function *> Reduction =
625 CGF.CGM.getOpenMPRuntime().getUserDefinedReduction(DRD);
626 const auto *CE = cast<CallExpr>(InitOp);
627 const auto *OVE = cast<OpaqueValueExpr>(CE->getCallee());
628 const Expr *LHS = CE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
629 const Expr *RHS = CE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
630 const auto *LHSDRE =
631 cast<DeclRefExpr>(cast<UnaryOperator>(LHS)->getSubExpr());
632 const auto *RHSDRE =
633 cast<DeclRefExpr>(cast<UnaryOperator>(RHS)->getSubExpr());
634 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
635 PrivateScope.addPrivate(cast<VarDecl>(LHSDRE->getDecl()),
636 [=]() { return Private; });
637 PrivateScope.addPrivate(cast<VarDecl>(RHSDRE->getDecl()),
638 [=]() { return Original; });
639 (void)PrivateScope.Privatize();
640 RValue Func = RValue::get(Reduction.second);
641 CodeGenFunction::OpaqueValueMapping Map(CGF, OVE, Func);
642 CGF.EmitIgnoredExpr(InitOp);
643 } else {
644 llvm::Constant *Init = CGF.CGM.EmitNullConstant(Ty);
645 std::string Name = CGF.CGM.getOpenMPRuntime().getName({"init"});
646 auto *GV = new llvm::GlobalVariable(
647 CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true,
648 llvm::GlobalValue::PrivateLinkage, Init, Name);
649 LValue LV = CGF.MakeNaturalAlignAddrLValue(GV, Ty);
650 RValue InitRVal;
651 switch (CGF.getEvaluationKind(Ty)) {
652 case TEK_Scalar:
653 InitRVal = CGF.EmitLoadOfLValue(LV, DRD->getLocation());
654 break;
655 case TEK_Complex:
656 InitRVal =
657 RValue::getComplex(CGF.EmitLoadOfComplex(LV, DRD->getLocation()));
658 break;
659 case TEK_Aggregate: {
660 OpaqueValueExpr OVE(DRD->getLocation(), Ty, VK_LValue);
661 CodeGenFunction::OpaqueValueMapping OpaqueMap(CGF, &OVE, LV);
662 CGF.EmitAnyExprToMem(&OVE, Private, Ty.getQualifiers(),
663 /*IsInitializer=*/false);
664 return;
665 }
666 }
667 OpaqueValueExpr OVE(DRD->getLocation(), Ty, VK_PRValue);
668 CodeGenFunction::OpaqueValueMapping OpaqueMap(CGF, &OVE, InitRVal);
669 CGF.EmitAnyExprToMem(&OVE, Private, Ty.getQualifiers(),
670 /*IsInitializer=*/false);
671 }
672}
673
674/// Emit initialization of arrays of complex types.
675/// \param DestAddr Address of the array.
676/// \param Type Type of array.
677/// \param Init Initial expression of array.
678/// \param SrcAddr Address of the original array.
679static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr,
680 QualType Type, bool EmitDeclareReductionInit,
681 const Expr *Init,
682 const OMPDeclareReductionDecl *DRD,
683 Address SrcAddr = Address::invalid()) {
684 // Perform element-by-element initialization.
685 QualType ElementTy;
686
687 // Drill down to the base element type on both arrays.
688 const ArrayType *ArrayTy = Type->getAsArrayTypeUnsafe();
689 llvm::Value *NumElements = CGF.emitArrayLength(ArrayTy, ElementTy, DestAddr);
690 DestAddr =
691 CGF.Builder.CreateElementBitCast(DestAddr, DestAddr.getElementType());
692 if (DRD)
693 SrcAddr =
694 CGF.Builder.CreateElementBitCast(SrcAddr, DestAddr.getElementType());
695
696 llvm::Value *SrcBegin = nullptr;
697 if (DRD)
698 SrcBegin = SrcAddr.getPointer();
699 llvm::Value *DestBegin = DestAddr.getPointer();
700 // Cast from pointer to array type to pointer to single element.
701 llvm::Value *DestEnd =
702 CGF.Builder.CreateGEP(DestAddr.getElementType(), DestBegin, NumElements);
703 // The basic structure here is a while-do loop.
704 llvm::BasicBlock *BodyBB = CGF.createBasicBlock("omp.arrayinit.body");
705 llvm::BasicBlock *DoneBB = CGF.createBasicBlock("omp.arrayinit.done");
706 llvm::Value *IsEmpty =
707 CGF.Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arrayinit.isempty");
708 CGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
709
710 // Enter the loop body, making that address the current address.
711 llvm::BasicBlock *EntryBB = CGF.Builder.GetInsertBlock();
712 CGF.EmitBlock(BodyBB);
713
714 CharUnits ElementSize = CGF.getContext().getTypeSizeInChars(ElementTy);
715
716 llvm::PHINode *SrcElementPHI = nullptr;
717 Address SrcElementCurrent = Address::invalid();
718 if (DRD) {
719 SrcElementPHI = CGF.Builder.CreatePHI(SrcBegin->getType(), 2,
720 "omp.arraycpy.srcElementPast");
721 SrcElementPHI->addIncoming(SrcBegin, EntryBB);
722 SrcElementCurrent =
723 Address(SrcElementPHI,
724 SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize));
725 }
726 llvm::PHINode *DestElementPHI = CGF.Builder.CreatePHI(
727 DestBegin->getType(), 2, "omp.arraycpy.destElementPast");
728 DestElementPHI->addIncoming(DestBegin, EntryBB);
729 Address DestElementCurrent =
730 Address(DestElementPHI,
731 DestAddr.getAlignment().alignmentOfArrayElement(ElementSize));
732
733 // Emit copy.
734 {
735 CodeGenFunction::RunCleanupsScope InitScope(CGF);
736 if (EmitDeclareReductionInit) {
737 emitInitWithReductionInitializer(CGF, DRD, Init, DestElementCurrent,
738 SrcElementCurrent, ElementTy);
739 } else
740 CGF.EmitAnyExprToMem(Init, DestElementCurrent, ElementTy.getQualifiers(),
741 /*IsInitializer=*/false);
742 }
743
744 if (DRD) {
745 // Shift the address forward by one element.
746 llvm::Value *SrcElementNext = CGF.Builder.CreateConstGEP1_32(
747 SrcAddr.getElementType(), SrcElementPHI, /*Idx0=*/1,
748 "omp.arraycpy.dest.element");
749 SrcElementPHI->addIncoming(SrcElementNext, CGF.Builder.GetInsertBlock());
750 }
751
752 // Shift the address forward by one element.
753 llvm::Value *DestElementNext = CGF.Builder.CreateConstGEP1_32(
754 DestAddr.getElementType(), DestElementPHI, /*Idx0=*/1,
755 "omp.arraycpy.dest.element");
756 // Check whether we've reached the end.
757 llvm::Value *Done =
758 CGF.Builder.CreateICmpEQ(DestElementNext, DestEnd, "omp.arraycpy.done");
759 CGF.Builder.CreateCondBr(Done, DoneBB, BodyBB);
760 DestElementPHI->addIncoming(DestElementNext, CGF.Builder.GetInsertBlock());
761
762 // Done.
763 CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
764}
765
766LValue ReductionCodeGen::emitSharedLValue(CodeGenFunction &CGF, const Expr *E) {
767 return CGF.EmitOMPSharedLValue(E);
768}
769
770LValue ReductionCodeGen::emitSharedLValueUB(CodeGenFunction &CGF,
771 const Expr *E) {
772 if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(E))
773 return CGF.EmitOMPArraySectionExpr(OASE, /*IsLowerBound=*/false);
774 return LValue();
775}
776
777void ReductionCodeGen::emitAggregateInitialization(
778 CodeGenFunction &CGF, unsigned N, Address PrivateAddr, LValue SharedLVal,
779 const OMPDeclareReductionDecl *DRD) {
780 // Emit VarDecl with copy init for arrays.
781 // Get the address of the original variable captured in current
782 // captured region.
783 const auto *PrivateVD =
784 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
785 bool EmitDeclareReductionInit =
786 DRD && (DRD->getInitializer() || !PrivateVD->hasInit());
787 EmitOMPAggregateInit(CGF, PrivateAddr, PrivateVD->getType(),
788 EmitDeclareReductionInit,
789 EmitDeclareReductionInit ? ClausesData[N].ReductionOp
790 : PrivateVD->getInit(),
791 DRD, SharedLVal.getAddress(CGF));
792}
793
794ReductionCodeGen::ReductionCodeGen(ArrayRef<const Expr *> Shareds,
795 ArrayRef<const Expr *> Origs,
796 ArrayRef<const Expr *> Privates,
797 ArrayRef<const Expr *> ReductionOps) {
798 ClausesData.reserve(Shareds.size());
799 SharedAddresses.reserve(Shareds.size());
800 Sizes.reserve(Shareds.size());
801 BaseDecls.reserve(Shareds.size());
802 const auto *IOrig = Origs.begin();
803 const auto *IPriv = Privates.begin();
804 const auto *IRed = ReductionOps.begin();
805 for (const Expr *Ref : Shareds) {
806 ClausesData.emplace_back(Ref, *IOrig, *IPriv, *IRed);
807 std::advance(IOrig, 1);
808 std::advance(IPriv, 1);
809 std::advance(IRed, 1);
810 }
811}
812
813void ReductionCodeGen::emitSharedOrigLValue(CodeGenFunction &CGF, unsigned N) {
814 assert(SharedAddresses.size() == N && OrigAddresses.size() == N &&(static_cast<void> (0))
815 "Number of generated lvalues must be exactly N.")(static_cast<void> (0));
816 LValue First = emitSharedLValue(CGF, ClausesData[N].Shared);
817 LValue Second = emitSharedLValueUB(CGF, ClausesData[N].Shared);
818 SharedAddresses.emplace_back(First, Second);
819 if (ClausesData[N].Shared == ClausesData[N].Ref) {
820 OrigAddresses.emplace_back(First, Second);
821 } else {
822 LValue First = emitSharedLValue(CGF, ClausesData[N].Ref);
823 LValue Second = emitSharedLValueUB(CGF, ClausesData[N].Ref);
824 OrigAddresses.emplace_back(First, Second);
825 }
826}
827
828void ReductionCodeGen::emitAggregateType(CodeGenFunction &CGF, unsigned N) {
829 const auto *PrivateVD =
830 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
831 QualType PrivateType = PrivateVD->getType();
832 bool AsArraySection = isa<OMPArraySectionExpr>(ClausesData[N].Ref);
833 if (!PrivateType->isVariablyModifiedType()) {
834 Sizes.emplace_back(
835 CGF.getTypeSize(OrigAddresses[N].first.getType().getNonReferenceType()),
836 nullptr);
837 return;
838 }
839 llvm::Value *Size;
840 llvm::Value *SizeInChars;
841 auto *ElemType =
842 cast<llvm::PointerType>(OrigAddresses[N].first.getPointer(CGF)->getType())
843 ->getElementType();
844 auto *ElemSizeOf = llvm::ConstantExpr::getSizeOf(ElemType);
845 if (AsArraySection) {
846 Size = CGF.Builder.CreatePtrDiff(OrigAddresses[N].second.getPointer(CGF),
847 OrigAddresses[N].first.getPointer(CGF));
848 Size = CGF.Builder.CreateNUWAdd(
849 Size, llvm::ConstantInt::get(Size->getType(), /*V=*/1));
850 SizeInChars = CGF.Builder.CreateNUWMul(Size, ElemSizeOf);
851 } else {
852 SizeInChars =
853 CGF.getTypeSize(OrigAddresses[N].first.getType().getNonReferenceType());
854 Size = CGF.Builder.CreateExactUDiv(SizeInChars, ElemSizeOf);
855 }
856 Sizes.emplace_back(SizeInChars, Size);
857 CodeGenFunction::OpaqueValueMapping OpaqueMap(
858 CGF,
859 cast<OpaqueValueExpr>(
860 CGF.getContext().getAsVariableArrayType(PrivateType)->getSizeExpr()),
861 RValue::get(Size));
862 CGF.EmitVariablyModifiedType(PrivateType);
863}
864
865void ReductionCodeGen::emitAggregateType(CodeGenFunction &CGF, unsigned N,
866 llvm::Value *Size) {
867 const auto *PrivateVD =
868 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
869 QualType PrivateType = PrivateVD->getType();
870 if (!PrivateType->isVariablyModifiedType()) {
871 assert(!Size && !Sizes[N].second &&(static_cast<void> (0))
872 "Size should be nullptr for non-variably modified reduction "(static_cast<void> (0))
873 "items.")(static_cast<void> (0));
874 return;
875 }
876 CodeGenFunction::OpaqueValueMapping OpaqueMap(
877 CGF,
878 cast<OpaqueValueExpr>(
879 CGF.getContext().getAsVariableArrayType(PrivateType)->getSizeExpr()),
880 RValue::get(Size));
881 CGF.EmitVariablyModifiedType(PrivateType);
882}
883
884void ReductionCodeGen::emitInitialization(
885 CodeGenFunction &CGF, unsigned N, Address PrivateAddr, LValue SharedLVal,
886 llvm::function_ref<bool(CodeGenFunction &)> DefaultInit) {
887 assert(SharedAddresses.size() > N && "No variable was generated")(static_cast<void> (0));
888 const auto *PrivateVD =
889 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
890 const OMPDeclareReductionDecl *DRD =
891 getReductionInit(ClausesData[N].ReductionOp);
892 QualType PrivateType = PrivateVD->getType();
893 PrivateAddr = CGF.Builder.CreateElementBitCast(
894 PrivateAddr, CGF.ConvertTypeForMem(PrivateType));
895 QualType SharedType = SharedAddresses[N].first.getType();
896 SharedLVal = CGF.MakeAddrLValue(
897 CGF.Builder.CreateElementBitCast(SharedLVal.getAddress(CGF),
898 CGF.ConvertTypeForMem(SharedType)),
899 SharedType, SharedAddresses[N].first.getBaseInfo(),
900 CGF.CGM.getTBAAInfoForSubobject(SharedAddresses[N].first, SharedType));
901 if (CGF.getContext().getAsArrayType(PrivateVD->getType())) {
902 if (DRD && DRD->getInitializer())
903 (void)DefaultInit(CGF);
904 emitAggregateInitialization(CGF, N, PrivateAddr, SharedLVal, DRD);
905 } else if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) {
906 (void)DefaultInit(CGF);
907 emitInitWithReductionInitializer(CGF, DRD, ClausesData[N].ReductionOp,
908 PrivateAddr, SharedLVal.getAddress(CGF),
909 SharedLVal.getType());
910 } else if (!DefaultInit(CGF) && PrivateVD->hasInit() &&
911 !CGF.isTrivialInitializer(PrivateVD->getInit())) {
912 CGF.EmitAnyExprToMem(PrivateVD->getInit(), PrivateAddr,
913 PrivateVD->getType().getQualifiers(),
914 /*IsInitializer=*/false);
915 }
916}
917
918bool ReductionCodeGen::needCleanups(unsigned N) {
919 const auto *PrivateVD =
920 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
921 QualType PrivateType = PrivateVD->getType();
922 QualType::DestructionKind DTorKind = PrivateType.isDestructedType();
923 return DTorKind != QualType::DK_none;
924}
925
926void ReductionCodeGen::emitCleanups(CodeGenFunction &CGF, unsigned N,
927 Address PrivateAddr) {
928 const auto *PrivateVD =
929 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
930 QualType PrivateType = PrivateVD->getType();
931 QualType::DestructionKind DTorKind = PrivateType.isDestructedType();
932 if (needCleanups(N)) {
933 PrivateAddr = CGF.Builder.CreateElementBitCast(
934 PrivateAddr, CGF.ConvertTypeForMem(PrivateType));
935 CGF.pushDestroy(DTorKind, PrivateAddr, PrivateType);
936 }
937}
938
939static LValue loadToBegin(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,
940 LValue BaseLV) {
941 BaseTy = BaseTy.getNonReferenceType();
942 while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&
943 !CGF.getContext().hasSameType(BaseTy, ElTy)) {
944 if (const auto *PtrTy = BaseTy->getAs<PointerType>()) {
945 BaseLV = CGF.EmitLoadOfPointerLValue(BaseLV.getAddress(CGF), PtrTy);
946 } else {
947 LValue RefLVal = CGF.MakeAddrLValue(BaseLV.getAddress(CGF), BaseTy);
948 BaseLV = CGF.EmitLoadOfReferenceLValue(RefLVal);
949 }
950 BaseTy = BaseTy->getPointeeType();
951 }
952 return CGF.MakeAddrLValue(
953 CGF.Builder.CreateElementBitCast(BaseLV.getAddress(CGF),
954 CGF.ConvertTypeForMem(ElTy)),
955 BaseLV.getType(), BaseLV.getBaseInfo(),
956 CGF.CGM.getTBAAInfoForSubobject(BaseLV, BaseLV.getType()));
957}
958
959static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,
960 llvm::Type *BaseLVType, CharUnits BaseLVAlignment,
961 llvm::Value *Addr) {
962 Address Tmp = Address::invalid();
963 Address TopTmp = Address::invalid();
964 Address MostTopTmp = Address::invalid();
965 BaseTy = BaseTy.getNonReferenceType();
966 while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&
967 !CGF.getContext().hasSameType(BaseTy, ElTy)) {
968 Tmp = CGF.CreateMemTemp(BaseTy);
969 if (TopTmp.isValid())
970 CGF.Builder.CreateStore(Tmp.getPointer(), TopTmp);
971 else
972 MostTopTmp = Tmp;
973 TopTmp = Tmp;
974 BaseTy = BaseTy->getPointeeType();
975 }
976 llvm::Type *Ty = BaseLVType;
977 if (Tmp.isValid())
978 Ty = Tmp.getElementType();
979 Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Addr, Ty);
980 if (Tmp.isValid()) {
981 CGF.Builder.CreateStore(Addr, Tmp);
982 return MostTopTmp;
983 }
984 return Address(Addr, BaseLVAlignment);
985}
986
987static const VarDecl *getBaseDecl(const Expr *Ref, const DeclRefExpr *&DE) {
988 const VarDecl *OrigVD = nullptr;
989 if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(Ref)) {
990 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
991 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
992 Base = TempOASE->getBase()->IgnoreParenImpCasts();
993 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
994 Base = TempASE->getBase()->IgnoreParenImpCasts();
995 DE = cast<DeclRefExpr>(Base);
996 OrigVD = cast<VarDecl>(DE->getDecl());
997 } else if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(Ref)) {
998 const Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
999 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
1000 Base = TempASE->getBase()->IgnoreParenImpCasts();
1001 DE = cast<DeclRefExpr>(Base);
1002 OrigVD = cast<VarDecl>(DE->getDecl());
1003 }
1004 return OrigVD;
1005}
1006
1007Address ReductionCodeGen::adjustPrivateAddress(CodeGenFunction &CGF, unsigned N,
1008 Address PrivateAddr) {
1009 const DeclRefExpr *DE;
1010 if (const VarDecl *OrigVD = ::getBaseDecl(ClausesData[N].Ref, DE)) {
1011 BaseDecls.emplace_back(OrigVD);
1012 LValue OriginalBaseLValue = CGF.EmitLValue(DE);
1013 LValue BaseLValue =
1014 loadToBegin(CGF, OrigVD->getType(), SharedAddresses[N].first.getType(),
1015 OriginalBaseLValue);
1016 Address SharedAddr = SharedAddresses[N].first.getAddress(CGF);
1017 llvm::Value *Adjustment = CGF.Builder.CreatePtrDiff(
1018 BaseLValue.getPointer(CGF), SharedAddr.getPointer());
1019 llvm::Value *PrivatePointer =
1020 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
1021 PrivateAddr.getPointer(), SharedAddr.getType());
1022 llvm::Value *Ptr = CGF.Builder.CreateGEP(
1023 SharedAddr.getElementType(), PrivatePointer, Adjustment);
1024 return castToBase(CGF, OrigVD->getType(),
1025 SharedAddresses[N].first.getType(),
1026 OriginalBaseLValue.getAddress(CGF).getType(),
1027 OriginalBaseLValue.getAlignment(), Ptr);
1028 }
1029 BaseDecls.emplace_back(
1030 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Ref)->getDecl()));
1031 return PrivateAddr;
1032}
1033
1034bool ReductionCodeGen::usesReductionInitializer(unsigned N) const {
1035 const OMPDeclareReductionDecl *DRD =
1036 getReductionInit(ClausesData[N].ReductionOp);
1037 return DRD && DRD->getInitializer();
1038}
1039
1040LValue CGOpenMPRegionInfo::getThreadIDVariableLValue(CodeGenFunction &CGF) {
1041 return CGF.EmitLoadOfPointerLValue(
1042 CGF.GetAddrOfLocalVar(getThreadIDVariable()),
1043 getThreadIDVariable()->getType()->castAs<PointerType>());
1044}
1045
1046void CGOpenMPRegionInfo::EmitBody(CodeGenFunction &CGF, const Stmt *S) {
1047 if (!CGF.HaveInsertPoint())
1048 return;
1049 // 1.2.2 OpenMP Language Terminology
1050 // Structured block - An executable statement with a single entry at the
1051 // top and a single exit at the bottom.
1052 // The point of exit cannot be a branch out of the structured block.
1053 // longjmp() and throw() must not violate the entry/exit criteria.
1054 CGF.EHStack.pushTerminate();
1055 if (S)
1056 CGF.incrementProfileCounter(S);
1057 CodeGen(CGF);
1058 CGF.EHStack.popTerminate();
1059}
1060
1061LValue CGOpenMPTaskOutlinedRegionInfo::getThreadIDVariableLValue(
1062 CodeGenFunction &CGF) {
1063 return CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(getThreadIDVariable()),
1064 getThreadIDVariable()->getType(),
1065 AlignmentSource::Decl);
1066}
1067
1068static FieldDecl *addFieldToRecordDecl(ASTContext &C, DeclContext *DC,
1069 QualType FieldTy) {
1070 auto *Field = FieldDecl::Create(
1071 C, DC, SourceLocation(), SourceLocation(), /*Id=*/nullptr, FieldTy,
1072 C.getTrivialTypeSourceInfo(FieldTy, SourceLocation()),
1073 /*BW=*/nullptr, /*Mutable=*/false, /*InitStyle=*/ICIS_NoInit);
1074 Field->setAccess(AS_public);
1075 DC->addDecl(Field);
1076 return Field;
1077}
1078
1079CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM, StringRef FirstSeparator,
1080 StringRef Separator)
1081 : CGM(CGM), FirstSeparator(FirstSeparator), Separator(Separator),
1082 OMPBuilder(CGM.getModule()), OffloadEntriesInfoManager(CGM) {
1083 KmpCriticalNameTy = llvm::ArrayType::get(CGM.Int32Ty, /*NumElements*/ 8);
1084
1085 // Initialize Types used in OpenMPIRBuilder from OMPKinds.def
1086 OMPBuilder.initialize();
1087 loadOffloadInfoMetadata();
1088}
1089
1090void CGOpenMPRuntime::clear() {
1091 InternalVars.clear();
1092 // Clean non-target variable declarations possibly used only in debug info.
1093 for (const auto &Data : EmittedNonTargetVariables) {
1094 if (!Data.getValue().pointsToAliveValue())
1095 continue;
1096 auto *GV = dyn_cast<llvm::GlobalVariable>(Data.getValue());
1097 if (!GV)
1098 continue;
1099 if (!GV->isDeclaration() || GV->getNumUses() > 0)
1100 continue;
1101 GV->eraseFromParent();
1102 }
1103}
1104
1105std::string CGOpenMPRuntime::getName(ArrayRef<StringRef> Parts) const {
1106 SmallString<128> Buffer;
1107 llvm::raw_svector_ostream OS(Buffer);
1108 StringRef Sep = FirstSeparator;
1109 for (StringRef Part : Parts) {
1110 OS << Sep << Part;
1111 Sep = Separator;
1112 }
1113 return std::string(OS.str());
1114}
1115
1116static llvm::Function *
1117emitCombinerOrInitializer(CodeGenModule &CGM, QualType Ty,
1118 const Expr *CombinerInitializer, const VarDecl *In,
1119 const VarDecl *Out, bool IsCombiner) {
1120 // void .omp_combiner.(Ty *in, Ty *out);
1121 ASTContext &C = CGM.getContext();
1122 QualType PtrTy = C.getPointerType(Ty).withRestrict();
1123 FunctionArgList Args;
1124 ImplicitParamDecl OmpOutParm(C, /*DC=*/nullptr, Out->getLocation(),
1125 /*Id=*/nullptr, PtrTy, ImplicitParamDecl::Other);
1126 ImplicitParamDecl OmpInParm(C, /*DC=*/nullptr, In->getLocation(),
1127 /*Id=*/nullptr, PtrTy, ImplicitParamDecl::Other);
1128 Args.push_back(&OmpOutParm);
1129 Args.push_back(&OmpInParm);
1130 const CGFunctionInfo &FnInfo =
1131 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
1132 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
1133 std::string Name = CGM.getOpenMPRuntime().getName(
1134 {IsCombiner ? "omp_combiner" : "omp_initializer", ""});
1135 auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
1136 Name, &CGM.getModule());
1137 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo);
1138 if (CGM.getLangOpts().Optimize) {
1139 Fn->removeFnAttr(llvm::Attribute::NoInline);
1140 Fn->removeFnAttr(llvm::Attribute::OptimizeNone);
1141 Fn->addFnAttr(llvm::Attribute::AlwaysInline);
1142 }
1143 CodeGenFunction CGF(CGM);
1144 // Map "T omp_in;" variable to "*omp_in_parm" value in all expressions.
1145 // Map "T omp_out;" variable to "*omp_out_parm" value in all expressions.
1146 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, In->getLocation(),
1147 Out->getLocation());
1148 CodeGenFunction::OMPPrivateScope Scope(CGF);
1149 Address AddrIn = CGF.GetAddrOfLocalVar(&OmpInParm);
1150 Scope.addPrivate(In, [&CGF, AddrIn, PtrTy]() {
1151 return CGF.EmitLoadOfPointerLValue(AddrIn, PtrTy->castAs<PointerType>())
1152 .getAddress(CGF);
1153 });
1154 Address AddrOut = CGF.GetAddrOfLocalVar(&OmpOutParm);
1155 Scope.addPrivate(Out, [&CGF, AddrOut, PtrTy]() {
1156 return CGF.EmitLoadOfPointerLValue(AddrOut, PtrTy->castAs<PointerType>())
1157 .getAddress(CGF);
1158 });
1159 (void)Scope.Privatize();
1160 if (!IsCombiner && Out->hasInit() &&
1161 !CGF.isTrivialInitializer(Out->getInit())) {
1162 CGF.EmitAnyExprToMem(Out->getInit(), CGF.GetAddrOfLocalVar(Out),
1163 Out->getType().getQualifiers(),
1164 /*IsInitializer=*/true);
1165 }
1166 if (CombinerInitializer)
1167 CGF.EmitIgnoredExpr(CombinerInitializer);
1168 Scope.ForceCleanup();
1169 CGF.FinishFunction();
1170 return Fn;
1171}
1172
1173void CGOpenMPRuntime::emitUserDefinedReduction(
1174 CodeGenFunction *CGF, const OMPDeclareReductionDecl *D) {
1175 if (UDRMap.count(D) > 0)
1176 return;
1177 llvm::Function *Combiner = emitCombinerOrInitializer(
1178 CGM, D->getType(), D->getCombiner(),
1179 cast<VarDecl>(cast<DeclRefExpr>(D->getCombinerIn())->getDecl()),
1180 cast<VarDecl>(cast<DeclRefExpr>(D->getCombinerOut())->getDecl()),
1181 /*IsCombiner=*/true);
1182 llvm::Function *Initializer = nullptr;
1183 if (const Expr *Init = D->getInitializer()) {
1184 Initializer = emitCombinerOrInitializer(
1185 CGM, D->getType(),
1186 D->getInitializerKind() == OMPDeclareReductionDecl::CallInit ? Init
1187 : nullptr,
1188 cast<VarDecl>(cast<DeclRefExpr>(D->getInitOrig())->getDecl()),
1189 cast<VarDecl>(cast<DeclRefExpr>(D->getInitPriv())->getDecl()),
1190 /*IsCombiner=*/false);
1191 }
1192 UDRMap.try_emplace(D, Combiner, Initializer);
1193 if (CGF) {
1194 auto &Decls = FunctionUDRMap.FindAndConstruct(CGF->CurFn);
1195 Decls.second.push_back(D);
1196 }
1197}
1198
1199std::pair<llvm::Function *, llvm::Function *>
1200CGOpenMPRuntime::getUserDefinedReduction(const OMPDeclareReductionDecl *D) {
1201 auto I = UDRMap.find(D);
1202 if (I != UDRMap.end())
1203 return I->second;
1204 emitUserDefinedReduction(/*CGF=*/nullptr, D);
1205 return UDRMap.lookup(D);
1206}
1207
1208namespace {
1209// Temporary RAII solution to perform a push/pop stack event on the OpenMP IR
1210// Builder if one is present.
1211struct PushAndPopStackRAII {
1212 PushAndPopStackRAII(llvm::OpenMPIRBuilder *OMPBuilder, CodeGenFunction &CGF,
1213 bool HasCancel, llvm::omp::Directive Kind)
1214 : OMPBuilder(OMPBuilder) {
1215 if (!OMPBuilder)
1216 return;
1217
1218 // The following callback is the crucial part of clangs cleanup process.
1219 //
1220 // NOTE:
1221 // Once the OpenMPIRBuilder is used to create parallel regions (and
1222 // similar), the cancellation destination (Dest below) is determined via
1223 // IP. That means if we have variables to finalize we split the block at IP,
1224 // use the new block (=BB) as destination to build a JumpDest (via
1225 // getJumpDestInCurrentScope(BB)) which then is fed to
1226 // EmitBranchThroughCleanup. Furthermore, there will not be the need
1227 // to push & pop an FinalizationInfo object.
1228 // The FiniCB will still be needed but at the point where the
1229 // OpenMPIRBuilder is asked to construct a parallel (or similar) construct.
1230 auto FiniCB = [&CGF](llvm::OpenMPIRBuilder::InsertPointTy IP) {
1231 assert(IP.getBlock()->end() == IP.getPoint() &&(static_cast<void> (0))
1232 "Clang CG should cause non-terminated block!")(static_cast<void> (0));
1233 CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
1234 CGF.Builder.restoreIP(IP);
1235 CodeGenFunction::JumpDest Dest =
1236 CGF.getOMPCancelDestination(OMPD_parallel);
1237 CGF.EmitBranchThroughCleanup(Dest);
1238 };
1239
1240 // TODO: Remove this once we emit parallel regions through the
1241 // OpenMPIRBuilder as it can do this setup internally.
1242 llvm::OpenMPIRBuilder::FinalizationInfo FI({FiniCB, Kind, HasCancel});
1243 OMPBuilder->pushFinalizationCB(std::move(FI));
1244 }
1245 ~PushAndPopStackRAII() {
1246 if (OMPBuilder)
1247 OMPBuilder->popFinalizationCB();
1248 }
1249 llvm::OpenMPIRBuilder *OMPBuilder;
1250};
1251} // namespace
1252
1253static llvm::Function *emitParallelOrTeamsOutlinedFunction(
1254 CodeGenModule &CGM, const OMPExecutableDirective &D, const CapturedStmt *CS,
1255 const VarDecl *ThreadIDVar, OpenMPDirectiveKind InnermostKind,
1256 const StringRef OutlinedHelperName, const RegionCodeGenTy &CodeGen) {
1257 assert(ThreadIDVar->getType()->isPointerType() &&(static_cast<void> (0))
1258 "thread id variable must be of type kmp_int32 *")(static_cast<void> (0));
1259 CodeGenFunction CGF(CGM, true);
1260 bool HasCancel = false;
1261 if (const auto *OPD = dyn_cast<OMPParallelDirective>(&D))
1262 HasCancel = OPD->hasCancel();
1263 else if (const auto *OPD = dyn_cast<OMPTargetParallelDirective>(&D))
1264 HasCancel = OPD->hasCancel();
1265 else if (const auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&D))
1266 HasCancel = OPSD->hasCancel();
1267 else if (const auto *OPFD = dyn_cast<OMPParallelForDirective>(&D))
1268 HasCancel = OPFD->hasCancel();
1269 else if (const auto *OPFD = dyn_cast<OMPTargetParallelForDirective>(&D))
1270 HasCancel = OPFD->hasCancel();
1271 else if (const auto *OPFD = dyn_cast<OMPDistributeParallelForDirective>(&D))
1272 HasCancel = OPFD->hasCancel();
1273 else if (const auto *OPFD =
1274 dyn_cast<OMPTeamsDistributeParallelForDirective>(&D))
1275 HasCancel = OPFD->hasCancel();
1276 else if (const auto *OPFD =
1277 dyn_cast<OMPTargetTeamsDistributeParallelForDirective>(&D))
1278 HasCancel = OPFD->hasCancel();
1279
1280 // TODO: Temporarily inform the OpenMPIRBuilder, if any, about the new
1281 // parallel region to make cancellation barriers work properly.
1282 llvm::OpenMPIRBuilder &OMPBuilder = CGM.getOpenMPRuntime().getOMPBuilder();
1283 PushAndPopStackRAII PSR(&OMPBuilder, CGF, HasCancel, InnermostKind);
1284 CGOpenMPOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen, InnermostKind,
1285 HasCancel, OutlinedHelperName);
1286 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
1287 return CGF.GenerateOpenMPCapturedStmtFunction(*CS, D.getBeginLoc());
1288}
1289
1290llvm::Function *CGOpenMPRuntime::emitParallelOutlinedFunction(
1291 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
1292 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
1293 const CapturedStmt *CS = D.getCapturedStmt(OMPD_parallel);
1294 return emitParallelOrTeamsOutlinedFunction(
1295 CGM, D, CS, ThreadIDVar, InnermostKind, getOutlinedHelperName(), CodeGen);
1296}
1297
1298llvm::Function *CGOpenMPRuntime::emitTeamsOutlinedFunction(
1299 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
1300 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
1301 const CapturedStmt *CS = D.getCapturedStmt(OMPD_teams);
1302 return emitParallelOrTeamsOutlinedFunction(
1303 CGM, D, CS, ThreadIDVar, InnermostKind, getOutlinedHelperName(), CodeGen);
1304}
1305
1306llvm::Function *CGOpenMPRuntime::emitTaskOutlinedFunction(
1307 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
1308 const VarDecl *PartIDVar, const VarDecl *TaskTVar,
1309 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
1310 bool Tied, unsigned &NumberOfParts) {
1311 auto &&UntiedCodeGen = [this, &D, TaskTVar](CodeGenFunction &CGF,
1312 PrePostActionTy &) {
1313 llvm::Value *ThreadID = getThreadID(CGF, D.getBeginLoc());
1314 llvm::Value *UpLoc = emitUpdateLocation(CGF, D.getBeginLoc());
1315 llvm::Value *TaskArgs[] = {
1316 UpLoc, ThreadID,
1317 CGF.EmitLoadOfPointerLValue(CGF.GetAddrOfLocalVar(TaskTVar),
1318 TaskTVar->getType()->castAs<PointerType>())
1319 .getPointer(CGF)};
1320 CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
1321 CGM.getModule(), OMPRTL___kmpc_omp_task),
1322 TaskArgs);
1323 };
1324 CGOpenMPTaskOutlinedRegionInfo::UntiedTaskActionTy Action(Tied, PartIDVar,
1325 UntiedCodeGen);
1326 CodeGen.setAction(Action);
1327 assert(!ThreadIDVar->getType()->isPointerType() &&(static_cast<void> (0))
1328 "thread id variable must be of type kmp_int32 for tasks")(static_cast<void> (0));
1329 const OpenMPDirectiveKind Region =
1330 isOpenMPTaskLoopDirective(D.getDirectiveKind()) ? OMPD_taskloop
1331 : OMPD_task;
1332 const CapturedStmt *CS = D.getCapturedStmt(Region);
1333 bool HasCancel = false;
1334 if (const auto *TD = dyn_cast<OMPTaskDirective>(&D))
1335 HasCancel = TD->hasCancel();
1336 else if (const auto *TD = dyn_cast<OMPTaskLoopDirective>(&D))
1337 HasCancel = TD->hasCancel();
1338 else if (const auto *TD = dyn_cast<OMPMasterTaskLoopDirective>(&D))
1339 HasCancel = TD->hasCancel();
1340 else if (const auto *TD = dyn_cast<OMPParallelMasterTaskLoopDirective>(&D))
1341 HasCancel = TD->hasCancel();
1342
1343 CodeGenFunction CGF(CGM, true);
1344 CGOpenMPTaskOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen,
1345 InnermostKind, HasCancel, Action);
1346 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
1347 llvm::Function *Res = CGF.GenerateCapturedStmtFunction(*CS);
1348 if (!Tied)
1349 NumberOfParts = Action.getNumberOfParts();
1350 return Res;
1351}
1352
1353static void buildStructValue(ConstantStructBuilder &Fields, CodeGenModule &CGM,
1354 const RecordDecl *RD, const CGRecordLayout &RL,
1355 ArrayRef<llvm::Constant *> Data) {
1356 llvm::StructType *StructTy = RL.getLLVMType();
1357 unsigned PrevIdx = 0;
1358 ConstantInitBuilder CIBuilder(CGM);
1359 auto DI = Data.begin();
1360 for (const FieldDecl *FD : RD->fields()) {
1361 unsigned Idx = RL.getLLVMFieldNo(FD);
1362 // Fill the alignment.
1363 for (unsigned I = PrevIdx; I < Idx; ++I)
1364 Fields.add(llvm::Constant::getNullValue(StructTy->getElementType(I)));
1365 PrevIdx = Idx + 1;
1366 Fields.add(*DI);
1367 ++DI;
1368 }
1369}
1370
1371template <class... As>
1372static llvm::GlobalVariable *
1373createGlobalStruct(CodeGenModule &CGM, QualType Ty, bool IsConstant,
1374 ArrayRef<llvm::Constant *> Data, const Twine &Name,
1375 As &&... Args) {
1376 const auto *RD = cast<RecordDecl>(Ty->getAsTagDecl());
1377 const CGRecordLayout &RL = CGM.getTypes().getCGRecordLayout(RD);
1378 ConstantInitBuilder CIBuilder(CGM);
1379 ConstantStructBuilder Fields = CIBuilder.beginStruct(RL.getLLVMType());
1380 buildStructValue(Fields, CGM, RD, RL, Data);
1381 return Fields.finishAndCreateGlobal(
1382 Name, CGM.getContext().getAlignOfGlobalVarInChars(Ty), IsConstant,
1383 std::forward<As>(Args)...);
1384}
1385
1386template <typename T>
1387static void
1388createConstantGlobalStructAndAddToParent(CodeGenModule &CGM, QualType Ty,
1389 ArrayRef<llvm::Constant *> Data,
1390 T &Parent) {
1391 const auto *RD = cast<RecordDecl>(Ty->getAsTagDecl());
1392 const CGRecordLayout &RL = CGM.getTypes().getCGRecordLayout(RD);
1393 ConstantStructBuilder Fields = Parent.beginStruct(RL.getLLVMType());
1394 buildStructValue(Fields, CGM, RD, RL, Data);
1395 Fields.finishAndAddTo(Parent);
1396}
1397
1398void CGOpenMPRuntime::setLocThreadIdInsertPt(CodeGenFunction &CGF,
1399 bool AtCurrentPoint) {
1400 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
1401 assert(!Elem.second.ServiceInsertPt && "Insert point is set already.")(static_cast<void> (0));
1402
1403 llvm::Value *Undef = llvm::UndefValue::get(CGF.Int32Ty);
1404 if (AtCurrentPoint) {
1405 Elem.second.ServiceInsertPt = new llvm::BitCastInst(
1406 Undef, CGF.Int32Ty, "svcpt", CGF.Builder.GetInsertBlock());
1407 } else {
1408 Elem.second.ServiceInsertPt =
1409 new llvm::BitCastInst(Undef, CGF.Int32Ty, "svcpt");
1410 Elem.second.ServiceInsertPt->insertAfter(CGF.AllocaInsertPt);
1411 }
1412}
1413
1414void CGOpenMPRuntime::clearLocThreadIdInsertPt(CodeGenFunction &CGF) {
1415 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
1416 if (Elem.second.ServiceInsertPt) {
1417 llvm::Instruction *Ptr = Elem.second.ServiceInsertPt;
1418 Elem.second.ServiceInsertPt = nullptr;
1419 Ptr->eraseFromParent();
1420 }
1421}
1422
1423static StringRef getIdentStringFromSourceLocation(CodeGenFunction &CGF,
1424 SourceLocation Loc,
1425 SmallString<128> &Buffer) {
1426 llvm::raw_svector_ostream OS(Buffer);
1427 // Build debug location
1428 PresumedLoc PLoc = CGF.getContext().getSourceManager().getPresumedLoc(Loc);
1429 OS << ";" << PLoc.getFilename() << ";";
1430 if (const auto *FD = dyn_cast_or_null<FunctionDecl>(CGF.CurFuncDecl))
1431 OS << FD->getQualifiedNameAsString();
1432 OS << ";" << PLoc.getLine() << ";" << PLoc.getColumn() << ";;";
1433 return OS.str();
1434}
1435
1436llvm::Value *CGOpenMPRuntime::emitUpdateLocation(CodeGenFunction &CGF,
1437 SourceLocation Loc,
1438 unsigned Flags) {
1439 llvm::Constant *SrcLocStr;
1440 if (CGM.getCodeGenOpts().getDebugInfo() == codegenoptions::NoDebugInfo ||
1441 Loc.isInvalid()) {
1442 SrcLocStr = OMPBuilder.getOrCreateDefaultSrcLocStr();
1443 } else {
1444 std::string FunctionName = "";
1445 if (const auto *FD = dyn_cast_or_null<FunctionDecl>(CGF.CurFuncDecl))
1446 FunctionName = FD->getQualifiedNameAsString();
1447 PresumedLoc PLoc = CGF.getContext().getSourceManager().getPresumedLoc(Loc);
1448 const char *FileName = PLoc.getFilename();
1449 unsigned Line = PLoc.getLine();
1450 unsigned Column = PLoc.getColumn();
1451 SrcLocStr =
1452 OMPBuilder.getOrCreateSrcLocStr(FunctionName, FileName, Line, Column);
1453 }
1454 unsigned Reserved2Flags = getDefaultLocationReserved2Flags();
1455 return OMPBuilder.getOrCreateIdent(SrcLocStr, llvm::omp::IdentFlag(Flags),
1456 Reserved2Flags);
1457}
1458
1459llvm::Value *CGOpenMPRuntime::getThreadID(CodeGenFunction &CGF,
1460 SourceLocation Loc) {
1461 assert(CGF.CurFn && "No function in current CodeGenFunction.")(static_cast<void> (0));
1462 // If the OpenMPIRBuilder is used we need to use it for all thread id calls as
1463 // the clang invariants used below might be broken.
1464 if (CGM.getLangOpts().OpenMPIRBuilder) {
1465 SmallString<128> Buffer;
1466 OMPBuilder.updateToLocation(CGF.Builder.saveIP());
1467 auto *SrcLocStr = OMPBuilder.getOrCreateSrcLocStr(
1468 getIdentStringFromSourceLocation(CGF, Loc, Buffer));
1469 return OMPBuilder.getOrCreateThreadID(
1470 OMPBuilder.getOrCreateIdent(SrcLocStr));
1471 }
1472
1473 llvm::Value *ThreadID = nullptr;
1474 // Check whether we've already cached a load of the thread id in this
1475 // function.
1476 auto I = OpenMPLocThreadIDMap.find(CGF.CurFn);
1477 if (I != OpenMPLocThreadIDMap.end()) {
1478 ThreadID = I->second.ThreadID;
1479 if (ThreadID != nullptr)
1480 return ThreadID;
1481 }
1482 // If exceptions are enabled, do not use parameter to avoid possible crash.
1483 if (auto *OMPRegionInfo =
1484 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
1485 if (OMPRegionInfo->getThreadIDVariable()) {
1486 // Check if this an outlined function with thread id passed as argument.
1487 LValue LVal = OMPRegionInfo->getThreadIDVariableLValue(CGF);
1488 llvm::BasicBlock *TopBlock = CGF.AllocaInsertPt->getParent();
1489 if (!CGF.EHStack.requiresLandingPad() || !CGF.getLangOpts().Exceptions ||
1490 !CGF.getLangOpts().CXXExceptions ||
1491 CGF.Builder.GetInsertBlock() == TopBlock ||
1492 !isa<llvm::Instruction>(LVal.getPointer(CGF)) ||
1493 cast<llvm::Instruction>(LVal.getPointer(CGF))->getParent() ==
1494 TopBlock ||
1495 cast<llvm::Instruction>(LVal.getPointer(CGF))->getParent() ==
1496 CGF.Builder.GetInsertBlock()) {
1497 ThreadID = CGF.EmitLoadOfScalar(LVal, Loc);
1498 // If value loaded in entry block, cache it and use it everywhere in
1499 // function.
1500 if (CGF.Builder.GetInsertBlock() == TopBlock) {
1501 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
1502 Elem.second.ThreadID = ThreadID;
1503 }
1504 return ThreadID;
1505 }
1506 }
1507 }
1508
1509 // This is not an outlined function region - need to call __kmpc_int32
1510 // kmpc_global_thread_num(ident_t *loc).
1511 // Generate thread id value and cache this value for use across the
1512 // function.
1513 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
1514 if (!Elem.second.ServiceInsertPt)
1515 setLocThreadIdInsertPt(CGF);
1516 CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
1517 CGF.Builder.SetInsertPoint(Elem.second.ServiceInsertPt);
1518 llvm::CallInst *Call = CGF.Builder.CreateCall(
1519 OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(),
1520 OMPRTL___kmpc_global_thread_num),
1521 emitUpdateLocation(CGF, Loc));
1522 Call->setCallingConv(CGF.getRuntimeCC());
1523 Elem.second.ThreadID = Call;
1524 return Call;
1525}
1526
1527void CGOpenMPRuntime::functionFinished(CodeGenFunction &CGF) {
1528 assert(CGF.CurFn && "No function in current CodeGenFunction.")(static_cast<void> (0));
1529 if (OpenMPLocThreadIDMap.count(CGF.CurFn)) {
1530 clearLocThreadIdInsertPt(CGF);
1531 OpenMPLocThreadIDMap.erase(CGF.CurFn);
1532 }
1533 if (FunctionUDRMap.count(CGF.CurFn) > 0) {
1534 for(const auto *D : FunctionUDRMap[CGF.CurFn])
1535 UDRMap.erase(D);
1536 FunctionUDRMap.erase(CGF.CurFn);
1537 }
1538 auto I = FunctionUDMMap.find(CGF.CurFn);
1539 if (I != FunctionUDMMap.end()) {
1540 for(const auto *D : I->second)
1541 UDMMap.erase(D);
1542 FunctionUDMMap.erase(I);
1543 }
1544 LastprivateConditionalToTypes.erase(CGF.CurFn);
1545 FunctionToUntiedTaskStackMap.erase(CGF.CurFn);
1546}
1547
1548llvm::Type *CGOpenMPRuntime::getIdentTyPointerTy() {
1549 return OMPBuilder.IdentPtr;
1550}
1551
1552llvm::Type *CGOpenMPRuntime::getKmpc_MicroPointerTy() {
1553 if (!Kmpc_MicroTy) {
1554 // Build void (*kmpc_micro)(kmp_int32 *global_tid, kmp_int32 *bound_tid,...)
1555 llvm::Type *MicroParams[] = {llvm::PointerType::getUnqual(CGM.Int32Ty),
1556 llvm::PointerType::getUnqual(CGM.Int32Ty)};
1557 Kmpc_MicroTy = llvm::FunctionType::get(CGM.VoidTy, MicroParams, true);
1558 }
1559 return llvm::PointerType::getUnqual(Kmpc_MicroTy);
1560}
1561
1562llvm::FunctionCallee
1563CGOpenMPRuntime::createForStaticInitFunction(unsigned IVSize, bool IVSigned) {
1564 assert((IVSize == 32 || IVSize == 64) &&(static_cast<void> (0))
1565 "IV size is not compatible with the omp runtime")(static_cast<void> (0));
1566 StringRef Name = IVSize == 32 ? (IVSigned ? "__kmpc_for_static_init_4"
1567 : "__kmpc_for_static_init_4u")
1568 : (IVSigned ? "__kmpc_for_static_init_8"
1569 : "__kmpc_for_static_init_8u");
1570 llvm::Type *ITy = IVSize == 32 ? CGM.Int32Ty : CGM.Int64Ty;
1571 auto *PtrTy = llvm::PointerType::getUnqual(ITy);
1572 llvm::Type *TypeParams[] = {
1573 getIdentTyPointerTy(), // loc
1574 CGM.Int32Ty, // tid
1575 CGM.Int32Ty, // schedtype
1576 llvm::PointerType::getUnqual(CGM.Int32Ty), // p_lastiter
1577 PtrTy, // p_lower
1578 PtrTy, // p_upper
1579 PtrTy, // p_stride
1580 ITy, // incr
1581 ITy // chunk
1582 };
1583 auto *FnTy =
1584 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1585 return CGM.CreateRuntimeFunction(FnTy, Name);
1586}
1587
1588llvm::FunctionCallee
1589CGOpenMPRuntime::createDispatchInitFunction(unsigned IVSize, bool IVSigned) {
1590 assert((IVSize == 32 || IVSize == 64) &&(static_cast<void> (0))
1591 "IV size is not compatible with the omp runtime")(static_cast<void> (0));
1592 StringRef Name =
1593 IVSize == 32
1594 ? (IVSigned ? "__kmpc_dispatch_init_4" : "__kmpc_dispatch_init_4u")
1595 : (IVSigned ? "__kmpc_dispatch_init_8" : "__kmpc_dispatch_init_8u");
1596 llvm::Type *ITy = IVSize == 32 ? CGM.Int32Ty : CGM.Int64Ty;
1597 llvm::Type *TypeParams[] = { getIdentTyPointerTy(), // loc
1598 CGM.Int32Ty, // tid
1599 CGM.Int32Ty, // schedtype
1600 ITy, // lower
1601 ITy, // upper
1602 ITy, // stride
1603 ITy // chunk
1604 };
1605 auto *FnTy =
1606 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1607 return CGM.CreateRuntimeFunction(FnTy, Name);
1608}
1609
1610llvm::FunctionCallee
1611CGOpenMPRuntime::createDispatchFiniFunction(unsigned IVSize, bool IVSigned) {
1612 assert((IVSize == 32 || IVSize == 64) &&(static_cast<void> (0))
1613 "IV size is not compatible with the omp runtime")(static_cast<void> (0));
1614 StringRef Name =
1615 IVSize == 32
1616 ? (IVSigned ? "__kmpc_dispatch_fini_4" : "__kmpc_dispatch_fini_4u")
1617 : (IVSigned ? "__kmpc_dispatch_fini_8" : "__kmpc_dispatch_fini_8u");
1618 llvm::Type *TypeParams[] = {
1619 getIdentTyPointerTy(), // loc
1620 CGM.Int32Ty, // tid
1621 };
1622 auto *FnTy =
1623 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
1624 return CGM.CreateRuntimeFunction(FnTy, Name);
1625}
1626
1627llvm::FunctionCallee
1628CGOpenMPRuntime::createDispatchNextFunction(unsigned IVSize, bool IVSigned) {
1629 assert((IVSize == 32 || IVSize == 64) &&(static_cast<void> (0))
1630 "IV size is not compatible with the omp runtime")(static_cast<void> (0));
1631 StringRef Name =
1632 IVSize == 32
1633 ? (IVSigned ? "__kmpc_dispatch_next_4" : "__kmpc_dispatch_next_4u")
1634 : (IVSigned ? "__kmpc_dispatch_next_8" : "__kmpc_dispatch_next_8u");
1635 llvm::Type *ITy = IVSize == 32 ? CGM.Int32Ty : CGM.Int64Ty;
1636 auto *PtrTy = llvm::PointerType::getUnqual(ITy);
1637 llvm::Type *TypeParams[] = {
1638 getIdentTyPointerTy(), // loc
1639 CGM.Int32Ty, // tid
1640 llvm::PointerType::getUnqual(CGM.Int32Ty), // p_lastiter
1641 PtrTy, // p_lower
1642 PtrTy, // p_upper
1643 PtrTy // p_stride
1644 };
1645 auto *FnTy =
1646 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
1647 return CGM.CreateRuntimeFunction(FnTy, Name);
1648}
1649
1650/// Obtain information that uniquely identifies a target entry. This
1651/// consists of the file and device IDs as well as line number associated with
1652/// the relevant entry source location.
1653static void getTargetEntryUniqueInfo(ASTContext &C, SourceLocation Loc,
1654 unsigned &DeviceID, unsigned &FileID,
1655 unsigned &LineNum) {
1656 SourceManager &SM = C.getSourceManager();
1657
1658 // The loc should be always valid and have a file ID (the user cannot use
1659 // #pragma directives in macros)
1660
1661 assert(Loc.isValid() && "Source location is expected to be always valid.")(static_cast<void> (0));
1662
1663 PresumedLoc PLoc = SM.getPresumedLoc(Loc);
1664 assert(PLoc.isValid() && "Source location is expected to be always valid.")(static_cast<void> (0));
1665
1666 llvm::sys::fs::UniqueID ID;
1667 if (auto EC = llvm::sys::fs::getUniqueID(PLoc.getFilename(), ID)) {
1668 PLoc = SM.getPresumedLoc(Loc, /*UseLineDirectives=*/false);
1669 assert(PLoc.isValid() && "Source location is expected to be always valid.")(static_cast<void> (0));
1670 if (auto EC = llvm::sys::fs::getUniqueID(PLoc.getFilename(), ID))
1671 SM.getDiagnostics().Report(diag::err_cannot_open_file)
1672 << PLoc.getFilename() << EC.message();
1673 }
1674
1675 DeviceID = ID.getDevice();
1676 FileID = ID.getFile();
1677 LineNum = PLoc.getLine();
1678}
1679
1680Address CGOpenMPRuntime::getAddrOfDeclareTargetVar(const VarDecl *VD) {
1681 if (CGM.getLangOpts().OpenMPSimd)
1682 return Address::invalid();
1683 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
1684 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
1685 if (Res && (*Res == OMPDeclareTargetDeclAttr::MT_Link ||
1686 (*Res == OMPDeclareTargetDeclAttr::MT_To &&
1687 HasRequiresUnifiedSharedMemory))) {
1688 SmallString<64> PtrName;
1689 {
1690 llvm::raw_svector_ostream OS(PtrName);
1691 OS << CGM.getMangledName(GlobalDecl(VD));
1692 if (!VD->isExternallyVisible()) {
1693 unsigned DeviceID, FileID, Line;
1694 getTargetEntryUniqueInfo(CGM.getContext(),
1695 VD->getCanonicalDecl()->getBeginLoc(),
1696 DeviceID, FileID, Line);
1697 OS << llvm::format("_%x", FileID);
1698 }
1699 OS << "_decl_tgt_ref_ptr";
1700 }
1701 llvm::Value *Ptr = CGM.getModule().getNamedValue(PtrName);
1702 if (!Ptr) {
1703 QualType PtrTy = CGM.getContext().getPointerType(VD->getType());
1704 Ptr = getOrCreateInternalVariable(CGM.getTypes().ConvertTypeForMem(PtrTy),
1705 PtrName);
1706
1707 auto *GV = cast<llvm::GlobalVariable>(Ptr);
1708 GV->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
1709
1710 if (!CGM.getLangOpts().OpenMPIsDevice)
1711 GV->setInitializer(CGM.GetAddrOfGlobal(VD));
1712 registerTargetGlobalVariable(VD, cast<llvm::Constant>(Ptr));
1713 }
1714 return Address(Ptr, CGM.getContext().getDeclAlign(VD));
1715 }
1716 return Address::invalid();
1717}
1718
1719llvm::Constant *
1720CGOpenMPRuntime::getOrCreateThreadPrivateCache(const VarDecl *VD) {
1721 assert(!CGM.getLangOpts().OpenMPUseTLS ||(static_cast<void> (0))
1722 !CGM.getContext().getTargetInfo().isTLSSupported())(static_cast<void> (0));
1723 // Lookup the entry, lazily creating it if necessary.
1724 std::string Suffix = getName({"cache", ""});
1725 return getOrCreateInternalVariable(
1726 CGM.Int8PtrPtrTy, Twine(CGM.getMangledName(VD)).concat(Suffix));
1727}
1728
1729Address CGOpenMPRuntime::getAddrOfThreadPrivate(CodeGenFunction &CGF,
1730 const VarDecl *VD,
1731 Address VDAddr,
1732 SourceLocation Loc) {
1733 if (CGM.getLangOpts().OpenMPUseTLS &&
1734 CGM.getContext().getTargetInfo().isTLSSupported())
1735 return VDAddr;
1736
1737 llvm::Type *VarTy = VDAddr.getElementType();
1738 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
1739 CGF.Builder.CreatePointerCast(VDAddr.getPointer(),
1740 CGM.Int8PtrTy),
1741 CGM.getSize(CGM.GetTargetTypeStoreSize(VarTy)),
1742 getOrCreateThreadPrivateCache(VD)};
1743 return Address(CGF.EmitRuntimeCall(
1744 OMPBuilder.getOrCreateRuntimeFunction(
1745 CGM.getModule(), OMPRTL___kmpc_threadprivate_cached),
1746 Args),
1747 VDAddr.getAlignment());
1748}
1749
1750void CGOpenMPRuntime::emitThreadPrivateVarInit(
1751 CodeGenFunction &CGF, Address VDAddr, llvm::Value *Ctor,
1752 llvm::Value *CopyCtor, llvm::Value *Dtor, SourceLocation Loc) {
1753 // Call kmp_int32 __kmpc_global_thread_num(&loc) to init OpenMP runtime
1754 // library.
1755 llvm::Value *OMPLoc = emitUpdateLocation(CGF, Loc);
1756 CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
1757 CGM.getModule(), OMPRTL___kmpc_global_thread_num),
1758 OMPLoc);
1759 // Call __kmpc_threadprivate_register(&loc, &var, ctor, cctor/*NULL*/, dtor)
1760 // to register constructor/destructor for variable.
1761 llvm::Value *Args[] = {
1762 OMPLoc, CGF.Builder.CreatePointerCast(VDAddr.getPointer(), CGM.VoidPtrTy),
1763 Ctor, CopyCtor, Dtor};
1764 CGF.EmitRuntimeCall(
1765 OMPBuilder.getOrCreateRuntimeFunction(
1766 CGM.getModule(), OMPRTL___kmpc_threadprivate_register),
1767 Args);
1768}
1769
1770llvm::Function *CGOpenMPRuntime::emitThreadPrivateVarDefinition(
1771 const VarDecl *VD, Address VDAddr, SourceLocation Loc,
1772 bool PerformInit, CodeGenFunction *CGF) {
1773 if (CGM.getLangOpts().OpenMPUseTLS &&
1774 CGM.getContext().getTargetInfo().isTLSSupported())
1775 return nullptr;
1776
1777 VD = VD->getDefinition(CGM.getContext());
1778 if (VD && ThreadPrivateWithDefinition.insert(CGM.getMangledName(VD)).second) {
1779 QualType ASTTy = VD->getType();
1780
1781 llvm::Value *Ctor = nullptr, *CopyCtor = nullptr, *Dtor = nullptr;
1782 const Expr *Init = VD->getAnyInitializer();
1783 if (CGM.getLangOpts().CPlusPlus && PerformInit) {
1784 // Generate function that re-emits the declaration's initializer into the
1785 // threadprivate copy of the variable VD
1786 CodeGenFunction CtorCGF(CGM);
1787 FunctionArgList Args;
1788 ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr, Loc,
1789 /*Id=*/nullptr, CGM.getContext().VoidPtrTy,
1790 ImplicitParamDecl::Other);
1791 Args.push_back(&Dst);
1792
1793 const auto &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
1794 CGM.getContext().VoidPtrTy, Args);
1795 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
1796 std::string Name = getName({"__kmpc_global_ctor_", ""});
1797 llvm::Function *Fn =
1798 CGM.CreateGlobalInitOrCleanUpFunction(FTy, Name, FI, Loc);
1799 CtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidPtrTy, Fn, FI,
1800 Args, Loc, Loc);
1801 llvm::Value *ArgVal = CtorCGF.EmitLoadOfScalar(
1802 CtorCGF.GetAddrOfLocalVar(&Dst), /*Volatile=*/false,
1803 CGM.getContext().VoidPtrTy, Dst.getLocation());
1804 Address Arg = Address(ArgVal, VDAddr.getAlignment());
1805 Arg = CtorCGF.Builder.CreateElementBitCast(
1806 Arg, CtorCGF.ConvertTypeForMem(ASTTy));
1807 CtorCGF.EmitAnyExprToMem(Init, Arg, Init->getType().getQualifiers(),
1808 /*IsInitializer=*/true);
1809 ArgVal = CtorCGF.EmitLoadOfScalar(
1810 CtorCGF.GetAddrOfLocalVar(&Dst), /*Volatile=*/false,
1811 CGM.getContext().VoidPtrTy, Dst.getLocation());
1812 CtorCGF.Builder.CreateStore(ArgVal, CtorCGF.ReturnValue);
1813 CtorCGF.FinishFunction();
1814 Ctor = Fn;
1815 }
1816 if (VD->getType().isDestructedType() != QualType::DK_none) {
1817 // Generate function that emits destructor call for the threadprivate copy
1818 // of the variable VD
1819 CodeGenFunction DtorCGF(CGM);
1820 FunctionArgList Args;
1821 ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr, Loc,
1822 /*Id=*/nullptr, CGM.getContext().VoidPtrTy,
1823 ImplicitParamDecl::Other);
1824 Args.push_back(&Dst);
1825
1826 const auto &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
1827 CGM.getContext().VoidTy, Args);
1828 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
1829 std::string Name = getName({"__kmpc_global_dtor_", ""});
1830 llvm::Function *Fn =
1831 CGM.CreateGlobalInitOrCleanUpFunction(FTy, Name, FI, Loc);
1832 auto NL = ApplyDebugLocation::CreateEmpty(DtorCGF);
1833 DtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, Fn, FI, Args,
1834 Loc, Loc);
1835 // Create a scope with an artificial location for the body of this function.
1836 auto AL = ApplyDebugLocation::CreateArtificial(DtorCGF);
1837 llvm::Value *ArgVal = DtorCGF.EmitLoadOfScalar(
1838 DtorCGF.GetAddrOfLocalVar(&Dst),
1839 /*Volatile=*/false, CGM.getContext().VoidPtrTy, Dst.getLocation());
1840 DtorCGF.emitDestroy(Address(ArgVal, VDAddr.getAlignment()), ASTTy,
1841 DtorCGF.getDestroyer(ASTTy.isDestructedType()),
1842 DtorCGF.needsEHCleanup(ASTTy.isDestructedType()));
1843 DtorCGF.FinishFunction();
1844 Dtor = Fn;
1845 }
1846 // Do not emit init function if it is not required.
1847 if (!Ctor && !Dtor)
1848 return nullptr;
1849
1850 llvm::Type *CopyCtorTyArgs[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
1851 auto *CopyCtorTy = llvm::FunctionType::get(CGM.VoidPtrTy, CopyCtorTyArgs,
1852 /*isVarArg=*/false)
1853 ->getPointerTo();
1854 // Copying constructor for the threadprivate variable.
1855 // Must be NULL - reserved by runtime, but currently it requires that this
1856 // parameter is always NULL. Otherwise it fires assertion.
1857 CopyCtor = llvm::Constant::getNullValue(CopyCtorTy);
1858 if (Ctor == nullptr) {
1859 auto *CtorTy = llvm::FunctionType::get(CGM.VoidPtrTy, CGM.VoidPtrTy,
1860 /*isVarArg=*/false)
1861 ->getPointerTo();
1862 Ctor = llvm::Constant::getNullValue(CtorTy);
1863 }
1864 if (Dtor == nullptr) {
1865 auto *DtorTy = llvm::FunctionType::get(CGM.VoidTy, CGM.VoidPtrTy,
1866 /*isVarArg=*/false)
1867 ->getPointerTo();
1868 Dtor = llvm::Constant::getNullValue(DtorTy);
1869 }
1870 if (!CGF) {
1871 auto *InitFunctionTy =
1872 llvm::FunctionType::get(CGM.VoidTy, /*isVarArg*/ false);
1873 std::string Name = getName({"__omp_threadprivate_init_", ""});
1874 llvm::Function *InitFunction = CGM.CreateGlobalInitOrCleanUpFunction(
1875 InitFunctionTy, Name, CGM.getTypes().arrangeNullaryFunction());
1876 CodeGenFunction InitCGF(CGM);
1877 FunctionArgList ArgList;
1878 InitCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, InitFunction,
1879 CGM.getTypes().arrangeNullaryFunction(), ArgList,
1880 Loc, Loc);
1881 emitThreadPrivateVarInit(InitCGF, VDAddr, Ctor, CopyCtor, Dtor, Loc);
1882 InitCGF.FinishFunction();
1883 return InitFunction;
1884 }
1885 emitThreadPrivateVarInit(*CGF, VDAddr, Ctor, CopyCtor, Dtor, Loc);
1886 }
1887 return nullptr;
1888}
1889
1890bool CGOpenMPRuntime::emitDeclareTargetVarDefinition(const VarDecl *VD,
1891 llvm::GlobalVariable *Addr,
1892 bool PerformInit) {
1893 if (CGM.getLangOpts().OMPTargetTriples.empty() &&
1894 !CGM.getLangOpts().OpenMPIsDevice)
1895 return false;
1896 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
1897 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
1898 if (!Res || *Res == OMPDeclareTargetDeclAttr::MT_Link ||
1899 (*Res == OMPDeclareTargetDeclAttr::MT_To &&
1900 HasRequiresUnifiedSharedMemory))
1901 return CGM.getLangOpts().OpenMPIsDevice;
1902 VD = VD->getDefinition(CGM.getContext());
1903 assert(VD && "Unknown VarDecl")(static_cast<void> (0));
1904
1905 if (!DeclareTargetWithDefinition.insert(CGM.getMangledName(VD)).second)
1906 return CGM.getLangOpts().OpenMPIsDevice;
1907
1908 QualType ASTTy = VD->getType();
1909 SourceLocation Loc = VD->getCanonicalDecl()->getBeginLoc();
1910
1911 // Produce the unique prefix to identify the new target regions. We use
1912 // the source location of the variable declaration which we know to not
1913 // conflict with any target region.
1914 unsigned DeviceID;
1915 unsigned FileID;
1916 unsigned Line;
1917 getTargetEntryUniqueInfo(CGM.getContext(), Loc, DeviceID, FileID, Line);
1918 SmallString<128> Buffer, Out;
1919 {
1920 llvm::raw_svector_ostream OS(Buffer);
1921 OS << "__omp_offloading_" << llvm::format("_%x", DeviceID)
1922 << llvm::format("_%x_", FileID) << VD->getName() << "_l" << Line;
1923 }
1924
1925 const Expr *Init = VD->getAnyInitializer();
1926 if (CGM.getLangOpts().CPlusPlus && PerformInit) {
1927 llvm::Constant *Ctor;
1928 llvm::Constant *ID;
1929 if (CGM.getLangOpts().OpenMPIsDevice) {
1930 // Generate function that re-emits the declaration's initializer into
1931 // the threadprivate copy of the variable VD
1932 CodeGenFunction CtorCGF(CGM);
1933
1934 const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();
1935 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
1936 llvm::Function *Fn = CGM.CreateGlobalInitOrCleanUpFunction(
1937 FTy, Twine(Buffer, "_ctor"), FI, Loc);
1938 auto NL = ApplyDebugLocation::CreateEmpty(CtorCGF);
1939 CtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, Fn, FI,
1940 FunctionArgList(), Loc, Loc);
1941 auto AL = ApplyDebugLocation::CreateArtificial(CtorCGF);
1942 CtorCGF.EmitAnyExprToMem(Init,
1943 Address(Addr, CGM.getContext().getDeclAlign(VD)),
1944 Init->getType().getQualifiers(),
1945 /*IsInitializer=*/true);
1946 CtorCGF.FinishFunction();
1947 Ctor = Fn;
1948 ID = llvm::ConstantExpr::getBitCast(Fn, CGM.Int8PtrTy);
1949 CGM.addUsedGlobal(cast<llvm::GlobalValue>(Ctor));
1950 } else {
1951 Ctor = new llvm::GlobalVariable(
1952 CGM.getModule(), CGM.Int8Ty, /*isConstant=*/true,
1953 llvm::GlobalValue::PrivateLinkage,
1954 llvm::Constant::getNullValue(CGM.Int8Ty), Twine(Buffer, "_ctor"));
1955 ID = Ctor;
1956 }
1957
1958 // Register the information for the entry associated with the constructor.
1959 Out.clear();
1960 OffloadEntriesInfoManager.registerTargetRegionEntryInfo(
1961 DeviceID, FileID, Twine(Buffer, "_ctor").toStringRef(Out), Line, Ctor,
1962 ID, OffloadEntriesInfoManagerTy::OMPTargetRegionEntryCtor);
1963 }
1964 if (VD->getType().isDestructedType() != QualType::DK_none) {
1965 llvm::Constant *Dtor;
1966 llvm::Constant *ID;
1967 if (CGM.getLangOpts().OpenMPIsDevice) {
1968 // Generate function that emits destructor call for the threadprivate
1969 // copy of the variable VD
1970 CodeGenFunction DtorCGF(CGM);
1971
1972 const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();
1973 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
1974 llvm::Function *Fn = CGM.CreateGlobalInitOrCleanUpFunction(
1975 FTy, Twine(Buffer, "_dtor"), FI, Loc);
1976 auto NL = ApplyDebugLocation::CreateEmpty(DtorCGF);
1977 DtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, Fn, FI,
1978 FunctionArgList(), Loc, Loc);
1979 // Create a scope with an artificial location for the body of this
1980 // function.
1981 auto AL = ApplyDebugLocation::CreateArtificial(DtorCGF);
1982 DtorCGF.emitDestroy(Address(Addr, CGM.getContext().getDeclAlign(VD)),
1983 ASTTy, DtorCGF.getDestroyer(ASTTy.isDestructedType()),
1984 DtorCGF.needsEHCleanup(ASTTy.isDestructedType()));
1985 DtorCGF.FinishFunction();
1986 Dtor = Fn;
1987 ID = llvm::ConstantExpr::getBitCast(Fn, CGM.Int8PtrTy);
1988 CGM.addUsedGlobal(cast<llvm::GlobalValue>(Dtor));
1989 } else {
1990 Dtor = new llvm::GlobalVariable(
1991 CGM.getModule(), CGM.Int8Ty, /*isConstant=*/true,
1992 llvm::GlobalValue::PrivateLinkage,
1993 llvm::Constant::getNullValue(CGM.Int8Ty), Twine(Buffer, "_dtor"));
1994 ID = Dtor;
1995 }
1996 // Register the information for the entry associated with the destructor.
1997 Out.clear();
1998 OffloadEntriesInfoManager.registerTargetRegionEntryInfo(
1999 DeviceID, FileID, Twine(Buffer, "_dtor").toStringRef(Out), Line, Dtor,
2000 ID, OffloadEntriesInfoManagerTy::OMPTargetRegionEntryDtor);
2001 }
2002 return CGM.getLangOpts().OpenMPIsDevice;
2003}
2004
2005Address CGOpenMPRuntime::getAddrOfArtificialThreadPrivate(CodeGenFunction &CGF,
2006 QualType VarType,
2007 StringRef Name) {
2008 std::string Suffix = getName({"artificial", ""});
2009 llvm::Type *VarLVType = CGF.ConvertTypeForMem(VarType);
2010 llvm::Value *GAddr =
2011 getOrCreateInternalVariable(VarLVType, Twine(Name).concat(Suffix));
2012 if (CGM.getLangOpts().OpenMP && CGM.getLangOpts().OpenMPUseTLS &&
2013 CGM.getTarget().isTLSSupported()) {
2014 cast<llvm::GlobalVariable>(GAddr)->setThreadLocal(/*Val=*/true);
2015 return Address(GAddr, CGM.getContext().getTypeAlignInChars(VarType));
2016 }
2017 std::string CacheSuffix = getName({"cache", ""});
2018 llvm::Value *Args[] = {
2019 emitUpdateLocation(CGF, SourceLocation()),
2020 getThreadID(CGF, SourceLocation()),
2021 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(GAddr, CGM.VoidPtrTy),
2022 CGF.Builder.CreateIntCast(CGF.getTypeSize(VarType), CGM.SizeTy,
2023 /*isSigned=*/false),
2024 getOrCreateInternalVariable(
2025 CGM.VoidPtrPtrTy, Twine(Name).concat(Suffix).concat(CacheSuffix))};
2026 return Address(
2027 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
2028 CGF.EmitRuntimeCall(
2029 OMPBuilder.getOrCreateRuntimeFunction(
2030 CGM.getModule(), OMPRTL___kmpc_threadprivate_cached),
2031 Args),
2032 VarLVType->getPointerTo(/*AddrSpace=*/0)),
2033 CGM.getContext().getTypeAlignInChars(VarType));
2034}
2035
2036void CGOpenMPRuntime::emitIfClause(CodeGenFunction &CGF, const Expr *Cond,
2037 const RegionCodeGenTy &ThenGen,
2038 const RegionCodeGenTy &ElseGen) {
2039 CodeGenFunction::LexicalScope ConditionScope(CGF, Cond->getSourceRange());
2040
2041 // If the condition constant folds and can be elided, try to avoid emitting
2042 // the condition and the dead arm of the if/else.
2043 bool CondConstant;
2044 if (CGF.ConstantFoldsToSimpleInteger(Cond, CondConstant)) {
2045 if (CondConstant)
2046 ThenGen(CGF);
2047 else
2048 ElseGen(CGF);
2049 return;
2050 }
2051
2052 // Otherwise, the condition did not fold, or we couldn't elide it. Just
2053 // emit the conditional branch.
2054 llvm::BasicBlock *ThenBlock = CGF.createBasicBlock("omp_if.then");
2055 llvm::BasicBlock *ElseBlock = CGF.createBasicBlock("omp_if.else");
2056 llvm::BasicBlock *ContBlock = CGF.createBasicBlock("omp_if.end");
2057 CGF.EmitBranchOnBoolExpr(Cond, ThenBlock, ElseBlock, /*TrueCount=*/0);
2058
2059 // Emit the 'then' code.
2060 CGF.EmitBlock(ThenBlock);
2061 ThenGen(CGF);
2062 CGF.EmitBranch(ContBlock);
2063 // Emit the 'else' code if present.
2064 // There is no need to emit line number for unconditional branch.
2065 (void)ApplyDebugLocation::CreateEmpty(CGF);
2066 CGF.EmitBlock(ElseBlock);
2067 ElseGen(CGF);
2068 // There is no need to emit line number for unconditional branch.
2069 (void)ApplyDebugLocation::CreateEmpty(CGF);
2070 CGF.EmitBranch(ContBlock);
2071 // Emit the continuation block for code after the if.
2072 CGF.EmitBlock(ContBlock, /*IsFinished=*/true);
2073}
2074
2075void CGOpenMPRuntime::emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
2076 llvm::Function *OutlinedFn,
2077 ArrayRef<llvm::Value *> CapturedVars,
2078 const Expr *IfCond) {
2079 if (!CGF.HaveInsertPoint())
2080 return;
2081 llvm::Value *RTLoc = emitUpdateLocation(CGF, Loc);
2082 auto &M = CGM.getModule();
2083 auto &&ThenGen = [&M, OutlinedFn, CapturedVars, RTLoc,
2084 this](CodeGenFunction &CGF, PrePostActionTy &) {
2085 // Build call __kmpc_fork_call(loc, n, microtask, var1, .., varn);
2086 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
2087 llvm::Value *Args[] = {
2088 RTLoc,
2089 CGF.Builder.getInt32(CapturedVars.size()), // Number of captured vars
2090 CGF.Builder.CreateBitCast(OutlinedFn, RT.getKmpc_MicroPointerTy())};
2091 llvm::SmallVector<llvm::Value *, 16> RealArgs;
2092 RealArgs.append(std::begin(Args), std::end(Args));
2093 RealArgs.append(CapturedVars.begin(), CapturedVars.end());
2094
2095 llvm::FunctionCallee RTLFn =
2096 OMPBuilder.getOrCreateRuntimeFunction(M, OMPRTL___kmpc_fork_call);
2097 CGF.EmitRuntimeCall(RTLFn, RealArgs);
2098 };
2099 auto &&ElseGen = [&M, OutlinedFn, CapturedVars, RTLoc, Loc,
2100 this](CodeGenFunction &CGF, PrePostActionTy &) {
2101 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
2102 llvm::Value *ThreadID = RT.getThreadID(CGF, Loc);
2103 // Build calls:
2104 // __kmpc_serialized_parallel(&Loc, GTid);
2105 llvm::Value *Args[] = {RTLoc, ThreadID};
2106 CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
2107 M, OMPRTL___kmpc_serialized_parallel),
2108 Args);
2109
2110 // OutlinedFn(&GTid, &zero_bound, CapturedStruct);
2111 Address ThreadIDAddr = RT.emitThreadIDAddress(CGF, Loc);
2112 Address ZeroAddrBound =
2113 CGF.CreateDefaultAlignTempAlloca(CGF.Int32Ty,
2114 /*Name=*/".bound.zero.addr");
2115 CGF.InitTempAlloca(ZeroAddrBound, CGF.Builder.getInt32(/*C*/ 0));
2116 llvm::SmallVector<llvm::Value *, 16> OutlinedFnArgs;
2117 // ThreadId for serialized parallels is 0.
2118 OutlinedFnArgs.push_back(ThreadIDAddr.getPointer());
2119 OutlinedFnArgs.push_back(ZeroAddrBound.getPointer());
2120 OutlinedFnArgs.append(CapturedVars.begin(), CapturedVars.end());
2121
2122 // Ensure we do not inline the function. This is trivially true for the ones
2123 // passed to __kmpc_fork_call but the ones called in serialized regions
2124 // could be inlined. This is not a perfect but it is closer to the invariant
2125 // we want, namely, every data environment starts with a new function.
2126 // TODO: We should pass the if condition to the runtime function and do the
2127 // handling there. Much cleaner code.
2128 OutlinedFn->removeFnAttr(llvm::Attribute::AlwaysInline);
2129 OutlinedFn->addFnAttr(llvm::Attribute::NoInline);
2130 RT.emitOutlinedFunctionCall(CGF, Loc, OutlinedFn, OutlinedFnArgs);
2131
2132 // __kmpc_end_serialized_parallel(&Loc, GTid);
2133 llvm::Value *EndArgs[] = {RT.emitUpdateLocation(CGF, Loc), ThreadID};
2134 CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
2135 M, OMPRTL___kmpc_end_serialized_parallel),
2136 EndArgs);
2137 };
2138 if (IfCond) {
2139 emitIfClause(CGF, IfCond, ThenGen, ElseGen);
2140 } else {
2141 RegionCodeGenTy ThenRCG(ThenGen);
2142 ThenRCG(CGF);
2143 }
2144}
2145
2146// If we're inside an (outlined) parallel region, use the region info's
2147// thread-ID variable (it is passed in a first argument of the outlined function
2148// as "kmp_int32 *gtid"). Otherwise, if we're not inside parallel region, but in
2149// regular serial code region, get thread ID by calling kmp_int32
2150// kmpc_global_thread_num(ident_t *loc), stash this thread ID in a temporary and
2151// return the address of that temp.
2152Address CGOpenMPRuntime::emitThreadIDAddress(CodeGenFunction &CGF,
2153 SourceLocation Loc) {
2154 if (auto *OMPRegionInfo =
2155 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
2156 if (OMPRegionInfo->getThreadIDVariable())
2157 return OMPRegionInfo->getThreadIDVariableLValue(CGF).getAddress(CGF);
2158
2159 llvm::Value *ThreadID = getThreadID(CGF, Loc);
2160 QualType Int32Ty =
2161 CGF.getContext().getIntTypeForBitwidth(/*DestWidth*/ 32, /*Signed*/ true);
2162 Address ThreadIDTemp = CGF.CreateMemTemp(Int32Ty, /*Name*/ ".threadid_temp.");
2163 CGF.EmitStoreOfScalar(ThreadID,
2164 CGF.MakeAddrLValue(ThreadIDTemp, Int32Ty));
2165
2166 return ThreadIDTemp;
2167}
2168
2169llvm::Constant *CGOpenMPRuntime::getOrCreateInternalVariable(
2170 llvm::Type *Ty, const llvm::Twine &Name, unsigned AddressSpace) {
2171 SmallString<256> Buffer;
2172 llvm::raw_svector_ostream Out(Buffer);
2173 Out << Name;
2174 StringRef RuntimeName = Out.str();
2175 auto &Elem = *InternalVars.try_emplace(RuntimeName, nullptr).first;
2176 if (Elem.second) {
2177 assert(Elem.second->getType()->getPointerElementType() == Ty &&(static_cast<void> (0))
2178 "OMP internal variable has different type than requested")(static_cast<void> (0));
2179 return &*Elem.second;
2180 }
2181
2182 return Elem.second = new llvm::GlobalVariable(
2183 CGM.getModule(), Ty, /*IsConstant*/ false,
2184 llvm::GlobalValue::CommonLinkage, llvm::Constant::getNullValue(Ty),
2185 Elem.first(), /*InsertBefore=*/nullptr,
2186 llvm::GlobalValue::NotThreadLocal, AddressSpace);
2187}
2188
2189llvm::Value *CGOpenMPRuntime::getCriticalRegionLock(StringRef CriticalName) {
2190 std::string Prefix = Twine("gomp_critical_user_", CriticalName).str();
2191 std::string Name = getName({Prefix, "var"});
2192 return getOrCreateInternalVariable(KmpCriticalNameTy, Name);
2193}
2194
2195namespace {
2196/// Common pre(post)-action for different OpenMP constructs.
2197class CommonActionTy final : public PrePostActionTy {
2198 llvm::FunctionCallee EnterCallee;
2199 ArrayRef<llvm::Value *> EnterArgs;
2200 llvm::FunctionCallee ExitCallee;
2201 ArrayRef<llvm::Value *> ExitArgs;
2202 bool Conditional;
2203 llvm::BasicBlock *ContBlock = nullptr;
2204
2205public:
2206 CommonActionTy(llvm::FunctionCallee EnterCallee,
2207 ArrayRef<llvm::Value *> EnterArgs,
2208 llvm::FunctionCallee ExitCallee,
2209 ArrayRef<llvm::Value *> ExitArgs, bool Conditional = false)
2210 : EnterCallee(EnterCallee), EnterArgs(EnterArgs), ExitCallee(ExitCallee),
2211 ExitArgs(ExitArgs), Conditional(Conditional) {}
2212 void Enter(CodeGenFunction &CGF) override {
2213 llvm::Value *EnterRes = CGF.EmitRuntimeCall(EnterCallee, EnterArgs);
2214 if (Conditional) {
2215 llvm::Value *CallBool = CGF.Builder.CreateIsNotNull(EnterRes);
2216 auto *ThenBlock = CGF.createBasicBlock("omp_if.then");
2217 ContBlock = CGF.createBasicBlock("omp_if.end");
2218 // Generate the branch (If-stmt)
2219 CGF.Builder.CreateCondBr(CallBool, ThenBlock, ContBlock);
2220 CGF.EmitBlock(ThenBlock);
2221 }
2222 }
2223 void Done(CodeGenFunction &CGF) {
2224 // Emit the rest of blocks/branches
2225 CGF.EmitBranch(ContBlock);
2226 CGF.EmitBlock(ContBlock, true);
2227 }
2228 void Exit(CodeGenFunction &CGF) override {
2229 CGF.EmitRuntimeCall(ExitCallee, ExitArgs);
2230 }
2231};
2232} // anonymous namespace
2233
2234void CGOpenMPRuntime::emitCriticalRegion(CodeGenFunction &CGF,
2235 StringRef CriticalName,
2236 const RegionCodeGenTy &CriticalOpGen,
2237 SourceLocation Loc, const Expr *Hint) {
2238 // __kmpc_critical[_with_hint](ident_t *, gtid, Lock[, hint]);
2239 // CriticalOpGen();
2240 // __kmpc_end_critical(ident_t *, gtid, Lock);
2241 // Prepare arguments and build a call to __kmpc_critical
2242 if (!CGF.HaveInsertPoint())
2243 return;
2244 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
2245 getCriticalRegionLock(CriticalName)};
2246 llvm::SmallVector<llvm::Value *, 4> EnterArgs(std::begin(Args),
2247 std::end(Args));
2248 if (Hint) {
2249 EnterArgs.push_back(CGF.Builder.CreateIntCast(
2250 CGF.EmitScalarExpr(Hint), CGM.Int32Ty, /*isSigned=*/false));
2251 }
2252 CommonActionTy Action(
2253 OMPBuilder.getOrCreateRuntimeFunction(
2254 CGM.getModule(),
2255 Hint ? OMPRTL___kmpc_critical_with_hint : OMPRTL___kmpc_critical),
2256 EnterArgs,
2257 OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(),
2258 OMPRTL___kmpc_end_critical),
2259 Args);
2260 CriticalOpGen.setAction(Action);
2261 emitInlinedDirective(CGF, OMPD_critical, CriticalOpGen);
2262}
2263
2264void CGOpenMPRuntime::emitMasterRegion(CodeGenFunction &CGF,
2265 const RegionCodeGenTy &MasterOpGen,
2266 SourceLocation Loc) {
2267 if (!CGF.HaveInsertPoint())
2268 return;
2269 // if(__kmpc_master(ident_t *, gtid)) {
2270 // MasterOpGen();
2271 // __kmpc_end_master(ident_t *, gtid);
2272 // }
2273 // Prepare arguments and build a call to __kmpc_master
2274 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
2275 CommonActionTy Action(OMPBuilder.getOrCreateRuntimeFunction(
2276 CGM.getModule(), OMPRTL___kmpc_master),
2277 Args,
2278 OMPBuilder.getOrCreateRuntimeFunction(
2279 CGM.getModule(), OMPRTL___kmpc_end_master),
2280 Args,
2281 /*Conditional=*/true);
2282 MasterOpGen.setAction(Action);
2283 emitInlinedDirective(CGF, OMPD_master, MasterOpGen);
2284 Action.Done(CGF);
2285}
2286
2287void CGOpenMPRuntime::emitMaskedRegion(CodeGenFunction &CGF,
2288 const RegionCodeGenTy &MaskedOpGen,
2289 SourceLocation Loc, const Expr *Filter) {
2290 if (!CGF.HaveInsertPoint())
2291 return;
2292 // if(__kmpc_masked(ident_t *, gtid, filter)) {
2293 // MaskedOpGen();
2294 // __kmpc_end_masked(iden_t *, gtid);
2295 // }
2296 // Prepare arguments and build a call to __kmpc_masked
2297 llvm::Value *FilterVal = Filter
2298 ? CGF.EmitScalarExpr(Filter, CGF.Int32Ty)
2299 : llvm::ConstantInt::get(CGM.Int32Ty, /*V=*/0);
2300 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
2301 FilterVal};
2302 llvm::Value *ArgsEnd[] = {emitUpdateLocation(CGF, Loc),
2303 getThreadID(CGF, Loc)};
2304 CommonActionTy Action(OMPBuilder.getOrCreateRuntimeFunction(
2305 CGM.getModule(), OMPRTL___kmpc_masked),
2306 Args,
2307 OMPBuilder.getOrCreateRuntimeFunction(
2308 CGM.getModule(), OMPRTL___kmpc_end_masked),
2309 ArgsEnd,
2310 /*Conditional=*/true);
2311 MaskedOpGen.setAction(Action);
2312 emitInlinedDirective(CGF, OMPD_masked, MaskedOpGen);
2313 Action.Done(CGF);
2314}
2315
2316void CGOpenMPRuntime::emitTaskyieldCall(CodeGenFunction &CGF,
2317 SourceLocation Loc) {
2318 if (!CGF.HaveInsertPoint())
2319 return;
2320 if (CGF.CGM.getLangOpts().OpenMPIRBuilder) {
2321 OMPBuilder.createTaskyield(CGF.Builder);
2322 } else {
2323 // Build call __kmpc_omp_taskyield(loc, thread_id, 0);
2324 llvm::Value *Args[] = {
2325 emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
2326 llvm::ConstantInt::get(CGM.IntTy, /*V=*/0, /*isSigned=*/true)};
2327 CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
2328 CGM.getModule(), OMPRTL___kmpc_omp_taskyield),
2329 Args);
2330 }
2331
2332 if (auto *Region = dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
2333 Region->emitUntiedSwitch(CGF);
2334}
2335
2336void CGOpenMPRuntime::emitTaskgroupRegion(CodeGenFunction &CGF,
2337 const RegionCodeGenTy &TaskgroupOpGen,
2338 SourceLocation Loc) {
2339 if (!CGF.HaveInsertPoint())
2340 return;
2341 // __kmpc_taskgroup(ident_t *, gtid);
2342 // TaskgroupOpGen();
2343 // __kmpc_end_taskgroup(ident_t *, gtid);
2344 // Prepare arguments and build a call to __kmpc_taskgroup
2345 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
2346 CommonActionTy Action(OMPBuilder.getOrCreateRuntimeFunction(
2347 CGM.getModule(), OMPRTL___kmpc_taskgroup),
2348 Args,
2349 OMPBuilder.getOrCreateRuntimeFunction(
2350 CGM.getModule(), OMPRTL___kmpc_end_taskgroup),
2351 Args);
2352 TaskgroupOpGen.setAction(Action);
2353 emitInlinedDirective(CGF, OMPD_taskgroup, TaskgroupOpGen);
2354}
2355
2356/// Given an array of pointers to variables, project the address of a
2357/// given variable.
2358static Address emitAddrOfVarFromArray(CodeGenFunction &CGF, Address Array,
2359 unsigned Index, const VarDecl *Var) {
2360 // Pull out the pointer to the variable.
2361 Address PtrAddr = CGF.Builder.CreateConstArrayGEP(Array, Index);
2362 llvm::Value *Ptr = CGF.Builder.CreateLoad(PtrAddr);
2363
2364 Address Addr = Address(Ptr, CGF.getContext().getDeclAlign(Var));
2365 Addr = CGF.Builder.CreateElementBitCast(
2366 Addr, CGF.ConvertTypeForMem(Var->getType()));
2367 return Addr;
2368}
2369
2370static llvm::Value *emitCopyprivateCopyFunction(
2371 CodeGenModule &CGM, llvm::Type *ArgsType,
2372 ArrayRef<const Expr *> CopyprivateVars, ArrayRef<const Expr *> DestExprs,
2373 ArrayRef<const Expr *> SrcExprs, ArrayRef<const Expr *> AssignmentOps,
2374 SourceLocation Loc) {
2375 ASTContext &C = CGM.getContext();
2376 // void copy_func(void *LHSArg, void *RHSArg);
2377 FunctionArgList Args;
2378 ImplicitParamDecl LHSArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
2379 ImplicitParamDecl::Other);
2380 ImplicitParamDecl RHSArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
2381 ImplicitParamDecl::Other);
2382 Args.push_back(&LHSArg);
2383 Args.push_back(&RHSArg);
2384 const auto &CGFI =
2385 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
2386 std::string Name =
2387 CGM.getOpenMPRuntime().getName({"omp", "copyprivate", "copy_func"});
2388 auto *Fn = llvm::Function::Create(CGM.getTypes().GetFunctionType(CGFI),
2389 llvm::GlobalValue::InternalLinkage, Name,
2390 &CGM.getModule());
2391 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, CGFI);
2392 Fn->setDoesNotRecurse();
2393 CodeGenFunction CGF(CGM);
2394 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args, Loc, Loc);
2395 // Dest = (void*[n])(LHSArg);
2396 // Src = (void*[n])(RHSArg);
2397 Address LHS(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
2398 CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&LHSArg)),
2399 ArgsType), CGF.getPointerAlign());
2400 Address RHS(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
2401 CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&RHSArg)),
2402 ArgsType), CGF.getPointerAlign());
2403 // *(Type0*)Dst[0] = *(Type0*)Src[0];
2404 // *(Type1*)Dst[1] = *(Type1*)Src[1];
2405 // ...
2406 // *(Typen*)Dst[n] = *(Typen*)Src[n];
2407 for (unsigned I = 0, E = AssignmentOps.size(); I < E; ++I) {
2408 const auto *DestVar =
2409 cast<VarDecl>(cast<DeclRefExpr>(DestExprs[I])->getDecl());
2410 Address DestAddr = emitAddrOfVarFromArray(CGF, LHS, I, DestVar);
2411
2412 const auto *SrcVar =
2413 cast<VarDecl>(cast<DeclRefExpr>(SrcExprs[I])->getDecl());
2414 Address SrcAddr = emitAddrOfVarFromArray(CGF, RHS, I, SrcVar);
2415
2416 const auto *VD = cast<DeclRefExpr>(CopyprivateVars[I])->getDecl();
2417 QualType Type = VD->getType();
2418 CGF.EmitOMPCopy(Type, DestAddr, SrcAddr, DestVar, SrcVar, AssignmentOps[I]);
2419 }
2420 CGF.FinishFunction();
2421 return Fn;
2422}
2423
2424void CGOpenMPRuntime::emitSingleRegion(CodeGenFunction &CGF,
2425 const RegionCodeGenTy &SingleOpGen,
2426 SourceLocation Loc,
2427 ArrayRef<const Expr *> CopyprivateVars,
2428 ArrayRef<const Expr *> SrcExprs,
2429 ArrayRef<const Expr *> DstExprs,
2430 ArrayRef<const Expr *> AssignmentOps) {
2431 if (!CGF.HaveInsertPoint())
2432 return;
2433 assert(CopyprivateVars.size() == SrcExprs.size() &&(static_cast<void> (0))
2434 CopyprivateVars.size() == DstExprs.size() &&(static_cast<void> (0))
2435 CopyprivateVars.size() == AssignmentOps.size())(static_cast<void> (0));
2436 ASTContext &C = CGM.getContext();
2437 // int32 did_it = 0;
2438 // if(__kmpc_single(ident_t *, gtid)) {
2439 // SingleOpGen();
2440 // __kmpc_end_single(ident_t *, gtid);
2441 // did_it = 1;
2442 // }
2443 // call __kmpc_copyprivate(ident_t *, gtid, <buf_size>, <copyprivate list>,
2444 // <copy_func>, did_it);
2445
2446 Address DidIt = Address::invalid();
2447 if (!CopyprivateVars.empty()) {
2448 // int32 did_it = 0;
2449 QualType KmpInt32Ty =
2450 C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
2451 DidIt = CGF.CreateMemTemp(KmpInt32Ty, ".omp.copyprivate.did_it");
2452 CGF.Builder.CreateStore(CGF.Builder.getInt32(0), DidIt);
2453 }
2454 // Prepare arguments and build a call to __kmpc_single
2455 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
2456 CommonActionTy Action(OMPBuilder.getOrCreateRuntimeFunction(
2457 CGM.getModule(), OMPRTL___kmpc_single),
2458 Args,
2459 OMPBuilder.getOrCreateRuntimeFunction(
2460 CGM.getModule(), OMPRTL___kmpc_end_single),
2461 Args,
2462 /*Conditional=*/true);
2463 SingleOpGen.setAction(Action);
2464 emitInlinedDirective(CGF, OMPD_single, SingleOpGen);
2465 if (DidIt.isValid()) {
2466 // did_it = 1;
2467 CGF.Builder.CreateStore(CGF.Builder.getInt32(1), DidIt);
2468 }
2469 Action.Done(CGF);
2470 // call __kmpc_copyprivate(ident_t *, gtid, <buf_size>, <copyprivate list>,
2471 // <copy_func>, did_it);
2472 if (DidIt.isValid()) {
2473 llvm::APInt ArraySize(/*unsigned int numBits=*/32, CopyprivateVars.size());
2474 QualType CopyprivateArrayTy = C.getConstantArrayType(
2475 C.VoidPtrTy, ArraySize, nullptr, ArrayType::Normal,
2476 /*IndexTypeQuals=*/0);
2477 // Create a list of all private variables for copyprivate.
2478 Address CopyprivateList =
2479 CGF.CreateMemTemp(CopyprivateArrayTy, ".omp.copyprivate.cpr_list");
2480 for (unsigned I = 0, E = CopyprivateVars.size(); I < E; ++I) {
2481 Address Elem = CGF.Builder.CreateConstArrayGEP(CopyprivateList, I);
2482 CGF.Builder.CreateStore(
2483 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
2484 CGF.EmitLValue(CopyprivateVars[I]).getPointer(CGF),
2485 CGF.VoidPtrTy),
2486 Elem);
2487 }
2488 // Build function that copies private values from single region to all other
2489 // threads in the corresponding parallel region.
2490 llvm::Value *CpyFn = emitCopyprivateCopyFunction(
2491 CGM, CGF.ConvertTypeForMem(CopyprivateArrayTy)->getPointerTo(),
2492 CopyprivateVars, SrcExprs, DstExprs, AssignmentOps, Loc);
2493 llvm::Value *BufSize = CGF.getTypeSize(CopyprivateArrayTy);
2494 Address CL =
2495 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(CopyprivateList,
2496 CGF.VoidPtrTy);
2497 llvm::Value *DidItVal = CGF.Builder.CreateLoad(DidIt);
2498 llvm::Value *Args[] = {
2499 emitUpdateLocation(CGF, Loc), // ident_t *<loc>
2500 getThreadID(CGF, Loc), // i32 <gtid>
2501 BufSize, // size_t <buf_size>
2502 CL.getPointer(), // void *<copyprivate list>
2503 CpyFn, // void (*) (void *, void *) <copy_func>
2504 DidItVal // i32 did_it
2505 };
2506 CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
2507 CGM.getModule(), OMPRTL___kmpc_copyprivate),
2508 Args);
2509 }
2510}
2511
2512void CGOpenMPRuntime::emitOrderedRegion(CodeGenFunction &CGF,
2513 const RegionCodeGenTy &OrderedOpGen,
2514 SourceLocation Loc, bool IsThreads) {
2515 if (!CGF.HaveInsertPoint())
2516 return;
2517 // __kmpc_ordered(ident_t *, gtid);
2518 // OrderedOpGen();
2519 // __kmpc_end_ordered(ident_t *, gtid);
2520 // Prepare arguments and build a call to __kmpc_ordered
2521 if (IsThreads) {
2522 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
2523 CommonActionTy Action(OMPBuilder.getOrCreateRuntimeFunction(
2524 CGM.getModule(), OMPRTL___kmpc_ordered),
2525 Args,
2526 OMPBuilder.getOrCreateRuntimeFunction(
2527 CGM.getModule(), OMPRTL___kmpc_end_ordered),
2528 Args);
2529 OrderedOpGen.setAction(Action);
2530 emitInlinedDirective(CGF, OMPD_ordered, OrderedOpGen);
2531 return;
2532 }
2533 emitInlinedDirective(CGF, OMPD_ordered, OrderedOpGen);
2534}
2535
2536unsigned CGOpenMPRuntime::getDefaultFlagsForBarriers(OpenMPDirectiveKind Kind) {
2537 unsigned Flags;
2538 if (Kind == OMPD_for)
2539 Flags = OMP_IDENT_BARRIER_IMPL_FOR;
2540 else if (Kind == OMPD_sections)
2541 Flags = OMP_IDENT_BARRIER_IMPL_SECTIONS;
2542 else if (Kind == OMPD_single)
2543 Flags = OMP_IDENT_BARRIER_IMPL_SINGLE;
2544 else if (Kind == OMPD_barrier)
2545 Flags = OMP_IDENT_BARRIER_EXPL;
2546 else
2547 Flags = OMP_IDENT_BARRIER_IMPL;
2548 return Flags;
2549}
2550
2551void CGOpenMPRuntime::getDefaultScheduleAndChunk(
2552 CodeGenFunction &CGF, const OMPLoopDirective &S,
2553 OpenMPScheduleClauseKind &ScheduleKind, const Expr *&ChunkExpr) const {
2554 // Check if the loop directive is actually a doacross loop directive. In this
2555 // case choose static, 1 schedule.
2556 if (llvm::any_of(
2557 S.getClausesOfKind<OMPOrderedClause>(),
2558 [](const OMPOrderedClause *C) { return C->getNumForLoops(); })) {
2559 ScheduleKind = OMPC_SCHEDULE_static;
2560 // Chunk size is 1 in this case.
2561 llvm::APInt ChunkSize(32, 1);
2562 ChunkExpr = IntegerLiteral::Create(
2563 CGF.getContext(), ChunkSize,
2564 CGF.getContext().getIntTypeForBitwidth(32, /*Signed=*/0),
2565 SourceLocation());
2566 }
2567}
2568
2569void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
2570 OpenMPDirectiveKind Kind, bool EmitChecks,
2571 bool ForceSimpleCall) {
2572 // Check if we should use the OMPBuilder
2573 auto *OMPRegionInfo =
2574 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo);
2575 if (CGF.CGM.getLangOpts().OpenMPIRBuilder) {
2576 CGF.Builder.restoreIP(OMPBuilder.createBarrier(
2577 CGF.Builder, Kind, ForceSimpleCall, EmitChecks));
2578 return;
2579 }
2580
2581 if (!CGF.HaveInsertPoint())
2582 return;
2583 // Build call __kmpc_cancel_barrier(loc, thread_id);
2584 // Build call __kmpc_barrier(loc, thread_id);
2585 unsigned Flags = getDefaultFlagsForBarriers(Kind);
2586 // Build call __kmpc_cancel_barrier(loc, thread_id) or __kmpc_barrier(loc,
2587 // thread_id);
2588 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc, Flags),
2589 getThreadID(CGF, Loc)};
2590 if (OMPRegionInfo) {
2591 if (!ForceSimpleCall && OMPRegionInfo->hasCancel()) {
2592 llvm::Value *Result = CGF.EmitRuntimeCall(
2593 OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(),
2594 OMPRTL___kmpc_cancel_barrier),
2595 Args);
2596 if (EmitChecks) {
2597 // if (__kmpc_cancel_barrier()) {
2598 // exit from construct;
2599 // }
2600 llvm::BasicBlock *ExitBB = CGF.createBasicBlock(".cancel.exit");
2601 llvm::BasicBlock *ContBB = CGF.createBasicBlock(".cancel.continue");
2602 llvm::Value *Cmp = CGF.Builder.CreateIsNotNull(Result);
2603 CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
2604 CGF.EmitBlock(ExitBB);
2605 // exit from construct;
2606 CodeGenFunction::JumpDest CancelDestination =
2607 CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
2608 CGF.EmitBranchThroughCleanup(CancelDestination);
2609 CGF.EmitBlock(ContBB, /*IsFinished=*/true);
2610 }
2611 return;
2612 }
2613 }
2614 CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
2615 CGM.getModule(), OMPRTL___kmpc_barrier),
2616 Args);
2617}
2618
2619/// Map the OpenMP loop schedule to the runtime enumeration.
2620static OpenMPSchedType getRuntimeSchedule(OpenMPScheduleClauseKind ScheduleKind,
2621 bool Chunked, bool Ordered) {
2622 switch (ScheduleKind) {
2623 case OMPC_SCHEDULE_static:
2624 return Chunked ? (Ordered ? OMP_ord_static_chunked : OMP_sch_static_chunked)
2625 : (Ordered ? OMP_ord_static : OMP_sch_static);
2626 case OMPC_SCHEDULE_dynamic:
2627 return Ordered ? OMP_ord_dynamic_chunked : OMP_sch_dynamic_chunked;
2628 case OMPC_SCHEDULE_guided:
2629 return Ordered ? OMP_ord_guided_chunked : OMP_sch_guided_chunked;
2630 case OMPC_SCHEDULE_runtime:
2631 return Ordered ? OMP_ord_runtime : OMP_sch_runtime;
2632 case OMPC_SCHEDULE_auto:
2633 return Ordered ? OMP_ord_auto : OMP_sch_auto;
2634 case OMPC_SCHEDULE_unknown:
2635 assert(!Chunked && "chunk was specified but schedule kind not known")(static_cast<void> (0));
2636 return Ordered ? OMP_ord_static : OMP_sch_static;
2637 }
2638 llvm_unreachable("Unexpected runtime schedule")__builtin_unreachable();
2639}
2640
2641/// Map the OpenMP distribute schedule to the runtime enumeration.
2642static OpenMPSchedType
2643getRuntimeSchedule(OpenMPDistScheduleClauseKind ScheduleKind, bool Chunked) {
2644 // only static is allowed for dist_schedule
2645 return Chunked ? OMP_dist_sch_static_chunked : OMP_dist_sch_static;
2646}
2647
2648bool CGOpenMPRuntime::isStaticNonchunked(OpenMPScheduleClauseKind ScheduleKind,
2649 bool Chunked) const {
2650 OpenMPSchedType Schedule =
2651 getRuntimeSchedule(ScheduleKind, Chunked, /*Ordered=*/false);
2652 return Schedule == OMP_sch_static;
2653}
2654
2655bool CGOpenMPRuntime::isStaticNonchunked(
2656 OpenMPDistScheduleClauseKind ScheduleKind, bool Chunked) const {
2657 OpenMPSchedType Schedule = getRuntimeSchedule(ScheduleKind, Chunked);
2658 return Schedule == OMP_dist_sch_static;
2659}
2660
2661bool CGOpenMPRuntime::isStaticChunked(OpenMPScheduleClauseKind ScheduleKind,
2662 bool Chunked) const {
2663 OpenMPSchedType Schedule =
2664 getRuntimeSchedule(ScheduleKind, Chunked, /*Ordered=*/false);
2665 return Schedule == OMP_sch_static_chunked;
2666}
2667
2668bool CGOpenMPRuntime::isStaticChunked(
2669 OpenMPDistScheduleClauseKind ScheduleKind, bool Chunked) const {
2670 OpenMPSchedType Schedule = getRuntimeSchedule(ScheduleKind, Chunked);
2671 return Schedule == OMP_dist_sch_static_chunked;
2672}
2673
2674bool CGOpenMPRuntime::isDynamic(OpenMPScheduleClauseKind ScheduleKind) const {
2675 OpenMPSchedType Schedule =
2676 getRuntimeSchedule(ScheduleKind, /*Chunked=*/false, /*Ordered=*/false);
2677 assert(Schedule != OMP_sch_static_chunked && "cannot be chunked here")(static_cast<void> (0));
2678 return Schedule != OMP_sch_static;
2679}
2680
2681static int addMonoNonMonoModifier(CodeGenModule &CGM, OpenMPSchedType Schedule,
2682 OpenMPScheduleClauseModifier M1,
2683 OpenMPScheduleClauseModifier M2) {
2684 int Modifier = 0;
2685 switch (M1) {
2686 case OMPC_SCHEDULE_MODIFIER_monotonic:
2687 Modifier = OMP_sch_modifier_monotonic;
2688 break;
2689 case OMPC_SCHEDULE_MODIFIER_nonmonotonic:
2690 Modifier = OMP_sch_modifier_nonmonotonic;
2691 break;
2692 case OMPC_SCHEDULE_MODIFIER_simd:
2693 if (Schedule == OMP_sch_static_chunked)
2694 Schedule = OMP_sch_static_balanced_chunked;
2695 break;
2696 case OMPC_SCHEDULE_MODIFIER_last:
2697 case OMPC_SCHEDULE_MODIFIER_unknown:
2698 break;
2699 }
2700 switch (M2) {
2701 case OMPC_SCHEDULE_MODIFIER_monotonic:
2702 Modifier = OMP_sch_modifier_monotonic;
2703 break;
2704 case OMPC_SCHEDULE_MODIFIER_nonmonotonic:
2705 Modifier = OMP_sch_modifier_nonmonotonic;
2706 break;
2707 case OMPC_SCHEDULE_MODIFIER_simd:
2708 if (Schedule == OMP_sch_static_chunked)
2709 Schedule = OMP_sch_static_balanced_chunked;
2710 break;
2711 case OMPC_SCHEDULE_MODIFIER_last:
2712 case OMPC_SCHEDULE_MODIFIER_unknown:
2713 break;
2714 }
2715 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Desription.
2716 // If the static schedule kind is specified or if the ordered clause is
2717 // specified, and if the nonmonotonic modifier is not specified, the effect is
2718 // as if the monotonic modifier is specified. Otherwise, unless the monotonic
2719 // modifier is specified, the effect is as if the nonmonotonic modifier is
2720 // specified.
2721 if (CGM.getLangOpts().OpenMP >= 50 && Modifier == 0) {
2722 if (!(Schedule == OMP_sch_static_chunked || Schedule == OMP_sch_static ||
2723 Schedule == OMP_sch_static_balanced_chunked ||
2724 Schedule == OMP_ord_static_chunked || Schedule == OMP_ord_static ||
2725 Schedule == OMP_dist_sch_static_chunked ||
2726 Schedule == OMP_dist_sch_static))
2727 Modifier = OMP_sch_modifier_nonmonotonic;
2728 }
2729 return Schedule | Modifier;
2730}
2731
2732void CGOpenMPRuntime::emitForDispatchInit(
2733 CodeGenFunction &CGF, SourceLocation Loc,
2734 const OpenMPScheduleTy &ScheduleKind, unsigned IVSize, bool IVSigned,
2735 bool Ordered, const DispatchRTInput &DispatchValues) {
2736 if (!CGF.HaveInsertPoint())
2737 return;
2738 OpenMPSchedType Schedule = getRuntimeSchedule(
2739 ScheduleKind.Schedule, DispatchValues.Chunk != nullptr, Ordered);
2740 assert(Ordered ||(static_cast<void> (0))
2741 (Schedule != OMP_sch_static && Schedule != OMP_sch_static_chunked &&(static_cast<void> (0))
2742 Schedule != OMP_ord_static && Schedule != OMP_ord_static_chunked &&(static_cast<void> (0))
2743 Schedule != OMP_sch_static_balanced_chunked))(static_cast<void> (0));
2744 // Call __kmpc_dispatch_init(
2745 // ident_t *loc, kmp_int32 tid, kmp_int32 schedule,
2746 // kmp_int[32|64] lower, kmp_int[32|64] upper,
2747 // kmp_int[32|64] stride, kmp_int[32|64] chunk);
2748
2749 // If the Chunk was not specified in the clause - use default value 1.
2750 llvm::Value *Chunk = DispatchValues.Chunk ? DispatchValues.Chunk
2751 : CGF.Builder.getIntN(IVSize, 1);
2752 llvm::Value *Args[] = {
2753 emitUpdateLocation(CGF, Loc),
2754 getThreadID(CGF, Loc),
2755 CGF.Builder.getInt32(addMonoNonMonoModifier(
2756 CGM, Schedule, ScheduleKind.M1, ScheduleKind.M2)), // Schedule type
2757 DispatchValues.LB, // Lower
2758 DispatchValues.UB, // Upper
2759 CGF.Builder.getIntN(IVSize, 1), // Stride
2760 Chunk // Chunk
2761 };
2762 CGF.EmitRuntimeCall(createDispatchInitFunction(IVSize, IVSigned), Args);
2763}
2764
2765static void emitForStaticInitCall(
2766 CodeGenFunction &CGF, llvm::Value *UpdateLocation, llvm::Value *ThreadId,
2767 llvm::FunctionCallee ForStaticInitFunction, OpenMPSchedType Schedule,
2768 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
2769 const CGOpenMPRuntime::StaticRTInput &Values) {
2770 if (!CGF.HaveInsertPoint())
2771 return;
2772
2773 assert(!Values.Ordered)(static_cast<void> (0));
2774 assert(Schedule == OMP_sch_static || Schedule == OMP_sch_static_chunked ||(static_cast<void> (0))
2775 Schedule == OMP_sch_static_balanced_chunked ||(static_cast<void> (0))
2776 Schedule == OMP_ord_static || Schedule == OMP_ord_static_chunked ||(static_cast<void> (0))
2777 Schedule == OMP_dist_sch_static ||(static_cast<void> (0))
2778 Schedule == OMP_dist_sch_static_chunked)(static_cast<void> (0));
2779
2780 // Call __kmpc_for_static_init(
2781 // ident_t *loc, kmp_int32 tid, kmp_int32 schedtype,
2782 // kmp_int32 *p_lastiter, kmp_int[32|64] *p_lower,
2783 // kmp_int[32|64] *p_upper, kmp_int[32|64] *p_stride,
2784 // kmp_int[32|64] incr, kmp_int[32|64] chunk);
2785 llvm::Value *Chunk = Values.Chunk;
2786 if (Chunk == nullptr) {
2787 assert((Schedule == OMP_sch_static || Schedule == OMP_ord_static ||(static_cast<void> (0))
2788 Schedule == OMP_dist_sch_static) &&(static_cast<void> (0))
2789 "expected static non-chunked schedule")(static_cast<void> (0));
2790 // If the Chunk was not specified in the clause - use default value 1.
2791 Chunk = CGF.Builder.getIntN(Values.IVSize, 1);
2792 } else {
2793 assert((Schedule == OMP_sch_static_chunked ||(static_cast<void> (0))
2794 Schedule == OMP_sch_static_balanced_chunked ||(static_cast<void> (0))
2795 Schedule == OMP_ord_static_chunked ||(static_cast<void> (0))
2796 Schedule == OMP_dist_sch_static_chunked) &&(static_cast<void> (0))
2797 "expected static chunked schedule")(static_cast<void> (0));
2798 }
2799 llvm::Value *Args[] = {
2800 UpdateLocation,
2801 ThreadId,
2802 CGF.Builder.getInt32(addMonoNonMonoModifier(CGF.CGM, Schedule, M1,
2803 M2)), // Schedule type
2804 Values.IL.getPointer(), // &isLastIter
2805 Values.LB.getPointer(), // &LB
2806 Values.UB.getPointer(), // &UB
2807 Values.ST.getPointer(), // &Stride
2808 CGF.Builder.getIntN(Values.IVSize, 1), // Incr
2809 Chunk // Chunk
2810 };
2811 CGF.EmitRuntimeCall(ForStaticInitFunction, Args);
2812}
2813
2814void CGOpenMPRuntime::emitForStaticInit(CodeGenFunction &CGF,
2815 SourceLocation Loc,
2816 OpenMPDirectiveKind DKind,
2817 const OpenMPScheduleTy &ScheduleKind,
2818 const StaticRTInput &Values) {
2819 OpenMPSchedType ScheduleNum = getRuntimeSchedule(
2820 ScheduleKind.Schedule, Values.Chunk != nullptr, Values.Ordered);
2821 assert(isOpenMPWorksharingDirective(DKind) &&(static_cast<void> (0))
2822 "Expected loop-based or sections-based directive.")(static_cast<void> (0));
2823 llvm::Value *UpdatedLocation = emitUpdateLocation(CGF, Loc,
2824 isOpenMPLoopDirective(DKind)
2825 ? OMP_IDENT_WORK_LOOP
2826 : OMP_IDENT_WORK_SECTIONS);
2827 llvm::Value *ThreadId = getThreadID(CGF, Loc);
2828 llvm::FunctionCallee StaticInitFunction =
2829 createForStaticInitFunction(Values.IVSize, Values.IVSigned);
2830 auto DL = ApplyDebugLocation::CreateDefaultArtificial(CGF, Loc);
2831 emitForStaticInitCall(CGF, UpdatedLocation, ThreadId, StaticInitFunction,
2832 ScheduleNum, ScheduleKind.M1, ScheduleKind.M2, Values);
2833}
2834
2835void CGOpenMPRuntime::emitDistributeStaticInit(
2836 CodeGenFunction &CGF, SourceLocation Loc,
2837 OpenMPDistScheduleClauseKind SchedKind,
2838 const CGOpenMPRuntime::StaticRTInput &Values) {
2839 OpenMPSchedType ScheduleNum =
2840 getRuntimeSchedule(SchedKind, Values.Chunk != nullptr);
2841 llvm::Value *UpdatedLocation =
2842 emitUpdateLocation(CGF, Loc, OMP_IDENT_WORK_DISTRIBUTE);
2843 llvm::Value *ThreadId = getThreadID(CGF, Loc);
2844 llvm::FunctionCallee StaticInitFunction =
2845 createForStaticInitFunction(Values.IVSize, Values.IVSigned);
2846 emitForStaticInitCall(CGF, UpdatedLocation, ThreadId, StaticInitFunction,
2847 ScheduleNum, OMPC_SCHEDULE_MODIFIER_unknown,
2848 OMPC_SCHEDULE_MODIFIER_unknown, Values);
2849}
2850
2851void CGOpenMPRuntime::emitForStaticFinish(CodeGenFunction &CGF,
2852 SourceLocation Loc,
2853 OpenMPDirectiveKind DKind) {
2854 if (!CGF.HaveInsertPoint())
2855 return;
2856 // Call __kmpc_for_static_fini(ident_t *loc, kmp_int32 tid);
2857 llvm::Value *Args[] = {
2858 emitUpdateLocation(CGF, Loc,
2859 isOpenMPDistributeDirective(DKind)
2860 ? OMP_IDENT_WORK_DISTRIBUTE
2861 : isOpenMPLoopDirective(DKind)
2862 ? OMP_IDENT_WORK_LOOP
2863 : OMP_IDENT_WORK_SECTIONS),
2864 getThreadID(CGF, Loc)};
2865 auto DL = ApplyDebugLocation::CreateDefaultArtificial(CGF, Loc);
2866 CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
2867 CGM.getModule(), OMPRTL___kmpc_for_static_fini),
2868 Args);
2869}
2870
2871void CGOpenMPRuntime::emitForOrderedIterationEnd(CodeGenFunction &CGF,
2872 SourceLocation Loc,
2873 unsigned IVSize,
2874 bool IVSigned) {
2875 if (!CGF.HaveInsertPoint())
2876 return;
2877 // Call __kmpc_for_dynamic_fini_(4|8)[u](ident_t *loc, kmp_int32 tid);
2878 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
2879 CGF.EmitRuntimeCall(createDispatchFiniFunction(IVSize, IVSigned), Args);
2880}
2881
2882llvm::Value *CGOpenMPRuntime::emitForNext(CodeGenFunction &CGF,
2883 SourceLocation Loc, unsigned IVSize,
2884 bool IVSigned, Address IL,
2885 Address LB, Address UB,
2886 Address ST) {
2887 // Call __kmpc_dispatch_next(
2888 // ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter,
2889 // kmp_int[32|64] *p_lower, kmp_int[32|64] *p_upper,
2890 // kmp_int[32|64] *p_stride);
2891 llvm::Value *Args[] = {
2892 emitUpdateLocation(CGF, Loc),
2893 getThreadID(CGF, Loc),
2894 IL.getPointer(), // &isLastIter
2895 LB.getPointer(), // &Lower
2896 UB.getPointer(), // &Upper
2897 ST.getPointer() // &Stride
2898 };
2899 llvm::Value *Call =
2900 CGF.EmitRuntimeCall(createDispatchNextFunction(IVSize, IVSigned), Args);
2901 return CGF.EmitScalarConversion(
2902 Call, CGF.getContext().getIntTypeForBitwidth(32, /*Signed=*/1),
2903 CGF.getContext().BoolTy, Loc);
2904}
2905
2906void CGOpenMPRuntime::emitNumThreadsClause(CodeGenFunction &CGF,
2907 llvm::Value *NumThreads,
2908 SourceLocation Loc) {
2909 if (!CGF.HaveInsertPoint())
2910 return;
2911 // Build call __kmpc_push_num_threads(&loc, global_tid, num_threads)
2912 llvm::Value *Args[] = {
2913 emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
2914 CGF.Builder.CreateIntCast(NumThreads, CGF.Int32Ty, /*isSigned*/ true)};
2915 CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
2916 CGM.getModule(), OMPRTL___kmpc_push_num_threads),
2917 Args);
2918}
2919
2920void CGOpenMPRuntime::emitProcBindClause(CodeGenFunction &CGF,
2921 ProcBindKind ProcBind,
2922 SourceLocation Loc) {
2923 if (!CGF.HaveInsertPoint())
2924 return;
2925 assert(ProcBind != OMP_PROC_BIND_unknown && "Unsupported proc_bind value.")(static_cast<void> (0));
2926 // Build call __kmpc_push_proc_bind(&loc, global_tid, proc_bind)
2927 llvm::Value *Args[] = {
2928 emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
2929 llvm::ConstantInt::get(CGM.IntTy, unsigned(ProcBind), /*isSigned=*/true)};
2930 CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
2931 CGM.getModule(), OMPRTL___kmpc_push_proc_bind),
2932 Args);
2933}
2934
2935void CGOpenMPRuntime::emitFlush(CodeGenFunction &CGF, ArrayRef<const Expr *>,
2936 SourceLocation Loc, llvm::AtomicOrdering AO) {
2937 if (CGF.CGM.getLangOpts().OpenMPIRBuilder) {
2938 OMPBuilder.createFlush(CGF.Builder);
2939 } else {
2940 if (!CGF.HaveInsertPoint())
2941 return;
2942 // Build call void __kmpc_flush(ident_t *loc)
2943 CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
2944 CGM.getModule(), OMPRTL___kmpc_flush),
2945 emitUpdateLocation(CGF, Loc));
2946 }
2947}
2948
2949namespace {
2950/// Indexes of fields for type kmp_task_t.
2951enum KmpTaskTFields {
2952 /// List of shared variables.
2953 KmpTaskTShareds,
2954 /// Task routine.
2955 KmpTaskTRoutine,
2956 /// Partition id for the untied tasks.
2957 KmpTaskTPartId,
2958 /// Function with call of destructors for private variables.
2959 Data1,
2960 /// Task priority.
2961 Data2,
2962 /// (Taskloops only) Lower bound.
2963 KmpTaskTLowerBound,
2964 /// (Taskloops only) Upper bound.
2965 KmpTaskTUpperBound,
2966 /// (Taskloops only) Stride.
2967 KmpTaskTStride,
2968 /// (Taskloops only) Is last iteration flag.
2969 KmpTaskTLastIter,
2970 /// (Taskloops only) Reduction data.
2971 KmpTaskTReductions,
2972};
2973} // anonymous namespace
2974
2975bool CGOpenMPRuntime::OffloadEntriesInfoManagerTy::empty() const {
2976 return OffloadEntriesTargetRegion.empty() &&
2977 OffloadEntriesDeviceGlobalVar.empty();
2978}
2979
2980/// Initialize target region entry.
2981void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
2982 initializeTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
2983 StringRef ParentName, unsigned LineNum,
2984 unsigned Order) {
2985 assert(CGM.getLangOpts().OpenMPIsDevice && "Initialization of entries is "(static_cast<void> (0))
2986 "only required for the device "(static_cast<void> (0))
2987 "code generation.")(static_cast<void> (0));
2988 OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum] =
2989 OffloadEntryInfoTargetRegion(Order, /*Addr=*/nullptr, /*ID=*/nullptr,
2990 OMPTargetRegionEntryTargetRegion);
2991 ++OffloadingEntriesNum;
2992}
2993
2994void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
2995 registerTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
2996 StringRef ParentName, unsigned LineNum,
2997 llvm::Constant *Addr, llvm::Constant *ID,
2998 OMPTargetRegionEntryKind Flags) {
2999 // If we are emitting code for a target, the entry is already initialized,
3000 // only has to be registered.
3001 if (CGM.getLangOpts().OpenMPIsDevice) {
3002 // This could happen if the device compilation is invoked standalone.
3003 if (!hasTargetRegionEntryInfo(DeviceID, FileID, ParentName, LineNum))
3004 return;
3005 auto &Entry =
3006 OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum];
3007 Entry.setAddress(Addr);
3008 Entry.setID(ID);
3009 Entry.setFlags(Flags);
3010 } else {
3011 if (Flags ==
3012 OffloadEntriesInfoManagerTy::OMPTargetRegionEntryTargetRegion &&
3013 hasTargetRegionEntryInfo(DeviceID, FileID, ParentName, LineNum,
3014 /*IgnoreAddressId*/ true))
3015 return;
3016 assert(!hasTargetRegionEntryInfo(DeviceID, FileID, ParentName, LineNum) &&(static_cast<void> (0))
3017 "Target region entry already registered!")(static_cast<void> (0));
3018 OffloadEntryInfoTargetRegion Entry(OffloadingEntriesNum, Addr, ID, Flags);
3019 OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum] = Entry;
3020 ++OffloadingEntriesNum;
3021 }
3022}
3023
3024bool CGOpenMPRuntime::OffloadEntriesInfoManagerTy::hasTargetRegionEntryInfo(
3025 unsigned DeviceID, unsigned FileID, StringRef ParentName, unsigned LineNum,
3026 bool IgnoreAddressId) const {
3027 auto PerDevice = OffloadEntriesTargetRegion.find(DeviceID);
3028 if (PerDevice == OffloadEntriesTargetRegion.end())
3029 return false;
3030 auto PerFile = PerDevice->second.find(FileID);
3031 if (PerFile == PerDevice->second.end())
3032 return false;
3033 auto PerParentName = PerFile->second.find(ParentName);
3034 if (PerParentName == PerFile->second.end())
3035 return false;
3036 auto PerLine = PerParentName->second.find(LineNum);
3037 if (PerLine == PerParentName->second.end())
3038 return false;
3039 // Fail if this entry is already registered.
3040 if (!IgnoreAddressId &&
3041 (PerLine->second.getAddress() || PerLine->second.getID()))
3042 return false;
3043 return true;
3044}
3045
3046void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::actOnTargetRegionEntriesInfo(
3047 const OffloadTargetRegionEntryInfoActTy &Action) {
3048 // Scan all target region entries and perform the provided action.
3049 for (const auto &D : OffloadEntriesTargetRegion)
3050 for (const auto &F : D.second)
3051 for (const auto &P : F.second)
3052 for (const auto &L : P.second)
3053 Action(D.first, F.first, P.first(), L.first, L.second);
3054}
3055
3056void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3057 initializeDeviceGlobalVarEntryInfo(StringRef Name,
3058 OMPTargetGlobalVarEntryKind Flags,
3059 unsigned Order) {
3060 assert(CGM.getLangOpts().OpenMPIsDevice && "Initialization of entries is "(static_cast<void> (0))
3061 "only required for the device "(static_cast<void> (0))
3062 "code generation.")(static_cast<void> (0));
3063 OffloadEntriesDeviceGlobalVar.try_emplace(Name, Order, Flags);
3064 ++OffloadingEntriesNum;
3065}
3066
3067void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3068 registerDeviceGlobalVarEntryInfo(StringRef VarName, llvm::Constant *Addr,
3069 CharUnits VarSize,
3070 OMPTargetGlobalVarEntryKind Flags,
3071 llvm::GlobalValue::LinkageTypes Linkage) {
3072 if (CGM.getLangOpts().OpenMPIsDevice) {
3073 // This could happen if the device compilation is invoked standalone.
3074 if (!hasDeviceGlobalVarEntryInfo(VarName))
3075 return;
3076 auto &Entry = OffloadEntriesDeviceGlobalVar[VarName];
3077 if (Entry.getAddress() && hasDeviceGlobalVarEntryInfo(VarName)) {
3078 if (Entry.getVarSize().isZero()) {
3079 Entry.setVarSize(VarSize);
3080 Entry.setLinkage(Linkage);
3081 }
3082 return;
3083 }
3084 Entry.setVarSize(VarSize);
3085 Entry.setLinkage(Linkage);
3086 Entry.setAddress(Addr);
3087 } else {
3088 if (hasDeviceGlobalVarEntryInfo(VarName)) {
3089 auto &Entry = OffloadEntriesDeviceGlobalVar[VarName];
3090 assert(Entry.isValid() && Entry.getFlags() == Flags &&(static_cast<void> (0))
3091 "Entry not initialized!")(static_cast<void> (0));
3092 if (Entry.getVarSize().isZero()) {
3093 Entry.setVarSize(VarSize);
3094 Entry.setLinkage(Linkage);
3095 }
3096 return;
3097 }
3098 OffloadEntriesDeviceGlobalVar.try_emplace(
3099 VarName, OffloadingEntriesNum, Addr, VarSize, Flags, Linkage);
3100 ++OffloadingEntriesNum;
3101 }
3102}
3103
3104void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3105 actOnDeviceGlobalVarEntriesInfo(
3106 const OffloadDeviceGlobalVarEntryInfoActTy &Action) {
3107 // Scan all target region entries and perform the provided action.
3108 for (const auto &E : OffloadEntriesDeviceGlobalVar)
3109 Action(E.getKey(), E.getValue());
3110}
3111
3112void CGOpenMPRuntime::createOffloadEntry(
3113 llvm::Constant *ID, llvm::Constant *Addr, uint64_t Size, int32_t Flags,
3114 llvm::GlobalValue::LinkageTypes Linkage) {
3115 StringRef Name = Addr->getName();
3116 llvm::Module &M = CGM.getModule();
3117 llvm::LLVMContext &C = M.getContext();
3118
3119 // Create constant string with the name.
3120 llvm::Constant *StrPtrInit = llvm::ConstantDataArray::getString(C, Name);
3121
3122 std::string StringName = getName({"omp_offloading", "entry_name"});
3123 auto *Str = new llvm::GlobalVariable(
3124 M, StrPtrInit->getType(), /*isConstant=*/true,
3125 llvm::GlobalValue::InternalLinkage, StrPtrInit, StringName);
3126 Str->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
3127
3128 llvm::Constant *Data[] = {
3129 llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(ID, CGM.VoidPtrTy),
3130 llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(Str, CGM.Int8PtrTy),
3131 llvm::ConstantInt::get(CGM.SizeTy, Size),
3132 llvm::ConstantInt::get(CGM.Int32Ty, Flags),
3133 llvm::ConstantInt::get(CGM.Int32Ty, 0)};
3134 std::string EntryName = getName({"omp_offloading", "entry", ""});
3135 llvm::GlobalVariable *Entry = createGlobalStruct(
3136 CGM, getTgtOffloadEntryQTy(), /*IsConstant=*/true, Data,
3137 Twine(EntryName).concat(Name), llvm::GlobalValue::WeakAnyLinkage);
3138
3139 // The entry has to be created in the section the linker expects it to be.
3140 Entry->setSection("omp_offloading_entries");
3141}
3142
3143void CGOpenMPRuntime::createOffloadEntriesAndInfoMetadata() {
3144 // Emit the offloading entries and metadata so that the device codegen side
3145 // can easily figure out what to emit. The produced metadata looks like
3146 // this:
3147 //
3148 // !omp_offload.info = !{!1, ...}
3149 //
3150 // Right now we only generate metadata for function that contain target
3151 // regions.
3152
3153 // If we are in simd mode or there are no entries, we don't need to do
3154 // anything.
3155 if (CGM.getLangOpts().OpenMPSimd || OffloadEntriesInfoManager.empty())
3156 return;
3157
3158 llvm::Module &M = CGM.getModule();
3159 llvm::LLVMContext &C = M.getContext();
3160 SmallVector<std::tuple<const OffloadEntriesInfoManagerTy::OffloadEntryInfo *,
3161 SourceLocation, StringRef>,
3162 16>
3163 OrderedEntries(OffloadEntriesInfoManager.size());
3164 llvm::SmallVector<StringRef, 16> ParentFunctions(
3165 OffloadEntriesInfoManager.size());
3166
3167 // Auxiliary methods to create metadata values and strings.
3168 auto &&GetMDInt = [this](unsigned V) {
3169 return llvm::ConstantAsMetadata::get(
3170 llvm::ConstantInt::get(CGM.Int32Ty, V));
3171 };
3172
3173 auto &&GetMDString = [&C](StringRef V) { return llvm::MDString::get(C, V); };
3174
3175 // Create the offloading info metadata node.
3176 llvm::NamedMDNode *MD = M.getOrInsertNamedMetadata("omp_offload.info");
3177
3178 // Create function that emits metadata for each target region entry;
3179 auto &&TargetRegionMetadataEmitter =
3180 [this, &C, MD, &OrderedEntries, &ParentFunctions, &GetMDInt,
3181 &GetMDString](
3182 unsigned DeviceID, unsigned FileID, StringRef ParentName,
3183 unsigned Line,
3184 const OffloadEntriesInfoManagerTy::OffloadEntryInfoTargetRegion &E) {
3185 // Generate metadata for target regions. Each entry of this metadata
3186 // contains:
3187 // - Entry 0 -> Kind of this type of metadata (0).
3188 // - Entry 1 -> Device ID of the file where the entry was identified.
3189 // - Entry 2 -> File ID of the file where the entry was identified.
3190 // - Entry 3 -> Mangled name of the function where the entry was
3191 // identified.
3192 // - Entry 4 -> Line in the file where the entry was identified.
3193 // - Entry 5 -> Order the entry was created.
3194 // The first element of the metadata node is the kind.
3195 llvm::Metadata *Ops[] = {GetMDInt(E.getKind()), GetMDInt(DeviceID),
3196 GetMDInt(FileID), GetMDString(ParentName),
3197 GetMDInt(Line), GetMDInt(E.getOrder())};
3198
3199 SourceLocation Loc;
3200 for (auto I = CGM.getContext().getSourceManager().fileinfo_begin(),
3201 E = CGM.getContext().getSourceManager().fileinfo_end();
3202 I != E; ++I) {
3203 if (I->getFirst()->getUniqueID().getDevice() == DeviceID &&
3204 I->getFirst()->getUniqueID().getFile() == FileID) {
3205 Loc = CGM.getContext().getSourceManager().translateFileLineCol(
3206 I->getFirst(), Line, 1);
3207 break;
3208 }
3209 }
3210 // Save this entry in the right position of the ordered entries array.
3211 OrderedEntries[E.getOrder()] = std::make_tuple(&E, Loc, ParentName);
3212 ParentFunctions[E.getOrder()] = ParentName;
3213
3214 // Add metadata to the named metadata node.
3215 MD->addOperand(llvm::MDNode::get(C, Ops));
3216 };
3217
3218 OffloadEntriesInfoManager.actOnTargetRegionEntriesInfo(
3219 TargetRegionMetadataEmitter);
3220
3221 // Create function that emits metadata for each device global variable entry;
3222 auto &&DeviceGlobalVarMetadataEmitter =
3223 [&C, &OrderedEntries, &GetMDInt, &GetMDString,
3224 MD](StringRef MangledName,
3225 const OffloadEntriesInfoManagerTy::OffloadEntryInfoDeviceGlobalVar
3226 &E) {
3227 // Generate metadata for global variables. Each entry of this metadata
3228 // contains:
3229 // - Entry 0 -> Kind of this type of metadata (1).
3230 // - Entry 1 -> Mangled name of the variable.
3231 // - Entry 2 -> Declare target kind.
3232 // - Entry 3 -> Order the entry was created.
3233 // The first element of the metadata node is the kind.
3234 llvm::Metadata *Ops[] = {
3235 GetMDInt(E.getKind()), GetMDString(MangledName),
3236 GetMDInt(E.getFlags()), GetMDInt(E.getOrder())};
3237
3238 // Save this entry in the right position of the ordered entries array.
3239 OrderedEntries[E.getOrder()] =
3240 std::make_tuple(&E, SourceLocation(), MangledName);
3241
3242 // Add metadata to the named metadata node.
3243 MD->addOperand(llvm::MDNode::get(C, Ops));
3244 };
3245
3246 OffloadEntriesInfoManager.actOnDeviceGlobalVarEntriesInfo(
3247 DeviceGlobalVarMetadataEmitter);
3248
3249 for (const auto &E : OrderedEntries) {
3250 assert(std::get<0>(E) && "All ordered entries must exist!")(static_cast<void> (0));
3251 if (const auto *CE =
3252 dyn_cast<OffloadEntriesInfoManagerTy::OffloadEntryInfoTargetRegion>(
3253 std::get<0>(E))) {
3254 if (!CE->getID() || !CE->getAddress()) {
3255 // Do not blame the entry if the parent funtion is not emitted.
3256 StringRef FnName = ParentFunctions[CE->getOrder()];
3257 if (!CGM.GetGlobalValue(FnName))
3258 continue;
3259 unsigned DiagID = CGM.getDiags().getCustomDiagID(
3260 DiagnosticsEngine::Error,
3261 "Offloading entry for target region in %0 is incorrect: either the "
3262 "address or the ID is invalid.");
3263 CGM.getDiags().Report(std::get<1>(E), DiagID) << FnName;
3264 continue;
3265 }
3266 createOffloadEntry(CE->getID(), CE->getAddress(), /*Size=*/0,
3267 CE->getFlags(), llvm::GlobalValue::WeakAnyLinkage);
3268 } else if (const auto *CE = dyn_cast<OffloadEntriesInfoManagerTy::
3269 OffloadEntryInfoDeviceGlobalVar>(
3270 std::get<0>(E))) {
3271 OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind Flags =
3272 static_cast<OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind>(
3273 CE->getFlags());
3274 switch (Flags) {
3275 case OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryTo: {
3276 if (CGM.getLangOpts().OpenMPIsDevice &&
3277 CGM.getOpenMPRuntime().hasRequiresUnifiedSharedMemory())
3278 continue;
3279 if (!CE->getAddress()) {
3280 unsigned DiagID = CGM.getDiags().getCustomDiagID(
3281 DiagnosticsEngine::Error, "Offloading entry for declare target "
3282 "variable %0 is incorrect: the "
3283 "address is invalid.");
3284 CGM.getDiags().Report(std::get<1>(E), DiagID) << std::get<2>(E);
3285 continue;
3286 }
3287 // The vaiable has no definition - no need to add the entry.
3288 if (CE->getVarSize().isZero())
3289 continue;
3290 break;
3291 }
3292 case OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryLink:
3293 assert(((CGM.getLangOpts().OpenMPIsDevice && !CE->getAddress()) ||(static_cast<void> (0))
3294 (!CGM.getLangOpts().OpenMPIsDevice && CE->getAddress())) &&(static_cast<void> (0))
3295 "Declaret target link address is set.")(static_cast<void> (0));
3296 if (CGM.getLangOpts().OpenMPIsDevice)
3297 continue;
3298 if (!CE->getAddress()) {
3299 unsigned DiagID = CGM.getDiags().getCustomDiagID(
3300 DiagnosticsEngine::Error,
3301 "Offloading entry for declare target variable is incorrect: the "
3302 "address is invalid.");
3303 CGM.getDiags().Report(DiagID);
3304 continue;
3305 }
3306 break;
3307 }
3308 createOffloadEntry(CE->getAddress(), CE->getAddress(),
3309 CE->getVarSize().getQuantity(), Flags,
3310 CE->getLinkage());
3311 } else {
3312 llvm_unreachable("Unsupported entry kind.")__builtin_unreachable();
3313 }
3314 }
3315}
3316
3317/// Loads all the offload entries information from the host IR
3318/// metadata.
3319void CGOpenMPRuntime::loadOffloadInfoMetadata() {
3320 // If we are in target mode, load the metadata from the host IR. This code has
3321 // to match the metadaata creation in createOffloadEntriesAndInfoMetadata().
3322
3323 if (!CGM.getLangOpts().OpenMPIsDevice)
3324 return;
3325
3326 if (CGM.getLangOpts().OMPHostIRFile.empty())
3327 return;
3328
3329 auto Buf = llvm::MemoryBuffer::getFile(CGM.getLangOpts().OMPHostIRFile);
3330 if (auto EC = Buf.getError()) {
3331 CGM.getDiags().Report(diag::err_cannot_open_file)
3332 << CGM.getLangOpts().OMPHostIRFile << EC.message();
3333 return;
3334 }
3335
3336 llvm::LLVMContext C;
3337 auto ME = expectedToErrorOrAndEmitErrors(
3338 C, llvm::parseBitcodeFile(Buf.get()->getMemBufferRef(), C));
3339
3340 if (auto EC = ME.getError()) {
3341 unsigned DiagID = CGM.getDiags().getCustomDiagID(
3342 DiagnosticsEngine::Error, "Unable to parse host IR file '%0':'%1'");
3343 CGM.getDiags().Report(DiagID)
3344 << CGM.getLangOpts().OMPHostIRFile << EC.message();
3345 return;
3346 }
3347
3348 llvm::NamedMDNode *MD = ME.get()->getNamedMetadata("omp_offload.info");
3349 if (!MD)
3350 return;
3351
3352 for (llvm::MDNode *MN : MD->operands()) {
3353 auto &&GetMDInt = [MN](unsigned Idx) {
3354 auto *V = cast<llvm::ConstantAsMetadata>(MN->getOperand(Idx));
3355 return cast<llvm::ConstantInt>(V->getValue())->getZExtValue();
3356 };
3357
3358 auto &&GetMDString = [MN](unsigned Idx) {
3359 auto *V = cast<llvm::MDString>(MN->getOperand(Idx));
3360 return V->getString();
3361 };
3362
3363 switch (GetMDInt(0)) {
3364 default:
3365 llvm_unreachable("Unexpected metadata!")__builtin_unreachable();
3366 break;
3367 case OffloadEntriesInfoManagerTy::OffloadEntryInfo::
3368 OffloadingEntryInfoTargetRegion:
3369 OffloadEntriesInfoManager.initializeTargetRegionEntryInfo(
3370 /*DeviceID=*/GetMDInt(1), /*FileID=*/GetMDInt(2),
3371 /*ParentName=*/GetMDString(3), /*Line=*/GetMDInt(4),
3372 /*Order=*/GetMDInt(5));
3373 break;
3374 case OffloadEntriesInfoManagerTy::OffloadEntryInfo::
3375 OffloadingEntryInfoDeviceGlobalVar:
3376 OffloadEntriesInfoManager.initializeDeviceGlobalVarEntryInfo(
3377 /*MangledName=*/GetMDString(1),
3378 static_cast<OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind>(
3379 /*Flags=*/GetMDInt(2)),
3380 /*Order=*/GetMDInt(3));
3381 break;
3382 }
3383 }
3384}
3385
3386void CGOpenMPRuntime::emitKmpRoutineEntryT(QualType KmpInt32Ty) {
3387 if (!KmpRoutineEntryPtrTy) {
3388 // Build typedef kmp_int32 (* kmp_routine_entry_t)(kmp_int32, void *); type.
3389 ASTContext &C = CGM.getContext();
3390 QualType KmpRoutineEntryTyArgs[] = {KmpInt32Ty, C.VoidPtrTy};
3391 FunctionProtoType::ExtProtoInfo EPI;
3392 KmpRoutineEntryPtrQTy = C.getPointerType(
3393 C.getFunctionType(KmpInt32Ty, KmpRoutineEntryTyArgs, EPI));
3394 KmpRoutineEntryPtrTy = CGM.getTypes().ConvertType(KmpRoutineEntryPtrQTy);
3395 }
3396}
3397
3398QualType CGOpenMPRuntime::getTgtOffloadEntryQTy() {
3399 // Make sure the type of the entry is already created. This is the type we
3400 // have to create:
3401 // struct __tgt_offload_entry{
3402 // void *addr; // Pointer to the offload entry info.
3403 // // (function or global)
3404 // char *name; // Name of the function or global.
3405 // size_t size; // Size of the entry info (0 if it a function).
3406 // int32_t flags; // Flags associated with the entry, e.g. 'link'.
3407 // int32_t reserved; // Reserved, to use by the runtime library.
3408 // };
3409 if (TgtOffloadEntryQTy.isNull()) {
3410 ASTContext &C = CGM.getContext();
3411 RecordDecl *RD = C.buildImplicitRecord("__tgt_offload_entry");
3412 RD->startDefinition();
3413 addFieldToRecordDecl(C, RD, C.VoidPtrTy);
3414 addFieldToRecordDecl(C, RD, C.getPointerType(C.CharTy));
3415 addFieldToRecordDecl(C, RD, C.getSizeType());
3416 addFieldToRecordDecl(
3417 C, RD, C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/true));
3418 addFieldToRecordDecl(
3419 C, RD, C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/true));
3420 RD->completeDefinition();
3421 RD->addAttr(PackedAttr::CreateImplicit(C));
3422 TgtOffloadEntryQTy = C.getRecordType(RD);
3423 }
3424 return TgtOffloadEntryQTy;
3425}
3426
3427namespace {
3428struct PrivateHelpersTy {
3429 PrivateHelpersTy(const Expr *OriginalRef, const VarDecl *Original,
3430 const VarDecl *PrivateCopy, const VarDecl *PrivateElemInit)
3431 : OriginalRef(OriginalRef), Original(Original), PrivateCopy(PrivateCopy),
3432 PrivateElemInit(PrivateElemInit) {}
3433 PrivateHelpersTy(const VarDecl *Original) : Original(Original) {}
3434 const Expr *OriginalRef = nullptr;
3435 const VarDecl *Original = nullptr;
3436 const VarDecl *PrivateCopy = nullptr;
3437 const VarDecl *PrivateElemInit = nullptr;
3438 bool isLocalPrivate() const {
3439 return !OriginalRef && !PrivateCopy && !PrivateElemInit;
3440 }
3441};
3442typedef std::pair<CharUnits /*Align*/, PrivateHelpersTy> PrivateDataTy;
3443} // anonymous namespace
3444
3445static bool isAllocatableDecl(const VarDecl *VD) {
3446 const VarDecl *CVD = VD->getCanonicalDecl();
3447 if (!CVD->hasAttr<OMPAllocateDeclAttr>())
3448 return false;
3449 const auto *AA = CVD->getAttr<OMPAllocateDeclAttr>();
3450 // Use the default allocation.
3451 return !((AA->getAllocatorType() == OMPAllocateDeclAttr::OMPDefaultMemAlloc ||
3452 AA->getAllocatorType() == OMPAllocateDeclAttr::OMPNullMemAlloc) &&
3453 !AA->getAllocator());
3454}
3455
3456static RecordDecl *
3457createPrivatesRecordDecl(CodeGenModule &CGM, ArrayRef<PrivateDataTy> Privates) {
3458 if (!Privates.empty()) {
3459 ASTContext &C = CGM.getContext();
3460 // Build struct .kmp_privates_t. {
3461 // /* private vars */
3462 // };
3463 RecordDecl *RD = C.buildImplicitRecord(".kmp_privates.t");
3464 RD->startDefinition();
3465 for (const auto &Pair : Privates) {
3466 const VarDecl *VD = Pair.second.Original;
3467 QualType Type = VD->getType().getNonReferenceType();
3468 // If the private variable is a local variable with lvalue ref type,
3469 // allocate the pointer instead of the pointee type.
3470 if (Pair.second.isLocalPrivate()) {
3471 if (VD->getType()->isLValueReferenceType())
3472 Type = C.getPointerType(Type);
3473 if (isAllocatableDecl(VD))
3474 Type = C.getPointerType(Type);
3475 }
3476 FieldDecl *FD = addFieldToRecordDecl(C, RD, Type);
3477 if (VD->hasAttrs()) {
3478 for (specific_attr_iterator<AlignedAttr> I(VD->getAttrs().begin()),
3479 E(VD->getAttrs().end());
3480 I != E; ++I)
3481 FD->addAttr(*I);
3482 }
3483 }
3484 RD->completeDefinition();
3485 return RD;
3486 }
3487 return nullptr;
3488}
3489
3490static RecordDecl *
3491createKmpTaskTRecordDecl(CodeGenModule &CGM, OpenMPDirectiveKind Kind,
3492 QualType KmpInt32Ty,
3493 QualType KmpRoutineEntryPointerQTy) {
3494 ASTContext &C = CGM.getContext();
3495 // Build struct kmp_task_t {
3496 // void * shareds;
3497 // kmp_routine_entry_t routine;
3498 // kmp_int32 part_id;
3499 // kmp_cmplrdata_t data1;
3500 // kmp_cmplrdata_t data2;
3501 // For taskloops additional fields:
3502 // kmp_uint64 lb;
3503 // kmp_uint64 ub;
3504 // kmp_int64 st;
3505 // kmp_int32 liter;
3506 // void * reductions;
3507 // };
3508 RecordDecl *UD = C.buildImplicitRecord("kmp_cmplrdata_t", TTK_Union);
3509 UD->startDefinition();
3510 addFieldToRecordDecl(C, UD, KmpInt32Ty);
3511 addFieldToRecordDecl(C, UD, KmpRoutineEntryPointerQTy);
3512 UD->completeDefinition();
3513 QualType KmpCmplrdataTy = C.getRecordType(UD);
3514 RecordDecl *RD = C.buildImplicitRecord("kmp_task_t");
3515 RD->startDefinition();
3516 addFieldToRecordDecl(C, RD, C.VoidPtrTy);
3517 addFieldToRecordDecl(C, RD, KmpRoutineEntryPointerQTy);
3518 addFieldToRecordDecl(C, RD, KmpInt32Ty);
3519 addFieldToRecordDecl(C, RD, KmpCmplrdataTy);
3520 addFieldToRecordDecl(C, RD, KmpCmplrdataTy);
3521 if (isOpenMPTaskLoopDirective(Kind)) {
3522 QualType KmpUInt64Ty =
3523 CGM.getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
3524 QualType KmpInt64Ty =
3525 CGM.getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
3526 addFieldToRecordDecl(C, RD, KmpUInt64Ty);
3527 addFieldToRecordDecl(C, RD, KmpUInt64Ty);
3528 addFieldToRecordDecl(C, RD, KmpInt64Ty);
3529 addFieldToRecordDecl(C, RD, KmpInt32Ty);
3530 addFieldToRecordDecl(C, RD, C.VoidPtrTy);
3531 }
3532 RD->completeDefinition();
3533 return RD;
3534}
3535
3536static RecordDecl *
3537createKmpTaskTWithPrivatesRecordDecl(CodeGenModule &CGM, QualType KmpTaskTQTy,
3538 ArrayRef<PrivateDataTy> Privates) {
3539 ASTContext &C = CGM.getContext();
3540 // Build struct kmp_task_t_with_privates {
3541 // kmp_task_t task_data;
3542 // .kmp_privates_t. privates;
3543 // };
3544 RecordDecl *RD = C.buildImplicitRecord("kmp_task_t_with_privates");
3545 RD->startDefinition();
3546 addFieldToRecordDecl(C, RD, KmpTaskTQTy);
3547 if (const RecordDecl *PrivateRD = createPrivatesRecordDecl(CGM, Privates))
3548 addFieldToRecordDecl(C, RD, C.getRecordType(PrivateRD));
3549 RD->completeDefinition();
3550 return RD;
3551}
3552
3553/// Emit a proxy function which accepts kmp_task_t as the second
3554/// argument.
3555/// \code
3556/// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
3557/// TaskFunction(gtid, tt->part_id, &tt->privates, task_privates_map, tt,
3558/// For taskloops:
3559/// tt->task_data.lb, tt->task_data.ub, tt->task_data.st, tt->task_data.liter,
3560/// tt->reductions, tt->shareds);
3561/// return 0;
3562/// }
3563/// \endcode
3564static llvm::Function *
3565emitProxyTaskFunction(CodeGenModule &CGM, SourceLocation Loc,
3566 OpenMPDirectiveKind Kind, QualType KmpInt32Ty,
3567 QualType KmpTaskTWithPrivatesPtrQTy,
3568 QualType KmpTaskTWithPrivatesQTy, QualType KmpTaskTQTy,
3569 QualType SharedsPtrTy, llvm::Function *TaskFunction,
3570 llvm::Value *TaskPrivatesMap) {
3571 ASTContext &C = CGM.getContext();
3572 FunctionArgList Args;
3573 ImplicitParamDecl GtidArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, KmpInt32Ty,
3574 ImplicitParamDecl::Other);
3575 ImplicitParamDecl TaskTypeArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
3576 KmpTaskTWithPrivatesPtrQTy.withRestrict(),
3577 ImplicitParamDecl::Other);
3578 Args.push_back(&GtidArg);
3579 Args.push_back(&TaskTypeArg);
3580 const auto &TaskEntryFnInfo =
3581 CGM.getTypes().arrangeBuiltinFunctionDeclaration(KmpInt32Ty, Args);
3582 llvm::FunctionType *TaskEntryTy =
3583 CGM.getTypes().GetFunctionType(TaskEntryFnInfo);
3584 std::string Name = CGM.getOpenMPRuntime().getName({"omp_task_entry", ""});
3585 auto *TaskEntry = llvm::Function::Create(
3586 TaskEntryTy, llvm::GlobalValue::InternalLinkage, Name, &CGM.getModule());
3587 CGM.SetInternalFunctionAttributes(GlobalDecl(), TaskEntry, TaskEntryFnInfo);
3588 TaskEntry->setDoesNotRecurse();
3589 CodeGenFunction CGF(CGM);
3590 CGF.StartFunction(GlobalDecl(), KmpInt32Ty, TaskEntry, TaskEntryFnInfo, Args,
3591 Loc, Loc);
3592
3593 // TaskFunction(gtid, tt->task_data.part_id, &tt->privates, task_privates_map,
3594 // tt,
3595 // For taskloops:
3596 // tt->task_data.lb, tt->task_data.ub, tt->task_data.st, tt->task_data.liter,
3597 // tt->task_data.shareds);
3598 llvm::Value *GtidParam = CGF.EmitLoadOfScalar(
3599 CGF.GetAddrOfLocalVar(&GtidArg), /*Volatile=*/false, KmpInt32Ty, Loc);
3600 LValue TDBase = CGF.EmitLoadOfPointerLValue(
3601 CGF.GetAddrOfLocalVar(&TaskTypeArg),
3602 KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
3603 const auto *KmpTaskTWithPrivatesQTyRD =
3604 cast<RecordDecl>(KmpTaskTWithPrivatesQTy->getAsTagDecl());
3605 LValue Base =
3606 CGF.EmitLValueForField(TDBase, *KmpTaskTWithPrivatesQTyRD->field_begin());
3607 const auto *KmpTaskTQTyRD = cast<RecordDecl>(KmpTaskTQTy->getAsTagDecl());
3608 auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
3609 LValue PartIdLVal = CGF.EmitLValueForField(Base, *PartIdFI);
3610 llvm::Value *PartidParam = PartIdLVal.getPointer(CGF);
3611
3612 auto SharedsFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTShareds);
3613 LValue SharedsLVal = CGF.EmitLValueForField(Base, *SharedsFI);
3614 llvm::Value *SharedsParam = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
3615 CGF.EmitLoadOfScalar(SharedsLVal, Loc),
3616 CGF.ConvertTypeForMem(SharedsPtrTy));
3617
3618 auto PrivatesFI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin(), 1);
3619 llvm::Value *PrivatesParam;
3620 if (PrivatesFI != KmpTaskTWithPrivatesQTyRD->field_end()) {
3621 LValue PrivatesLVal = CGF.EmitLValueForField(TDBase, *PrivatesFI);
3622 PrivatesParam = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
3623 PrivatesLVal.getPointer(CGF), CGF.VoidPtrTy);
3624 } else {
3625 PrivatesParam = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
3626 }
3627
3628 llvm::Value *CommonArgs[] = {GtidParam, PartidParam, PrivatesParam,
3629 TaskPrivatesMap,
3630 CGF.Builder
3631 .CreatePointerBitCastOrAddrSpaceCast(
3632 TDBase.getAddress(CGF), CGF.VoidPtrTy)
3633 .getPointer()};
3634 SmallVector<llvm::Value *, 16> CallArgs(std::begin(CommonArgs),
3635 std::end(CommonArgs));
3636 if (isOpenMPTaskLoopDirective(Kind)) {
3637 auto LBFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLowerBound);
3638 LValue LBLVal = CGF.EmitLValueForField(Base, *LBFI);
3639 llvm::Value *LBParam = CGF.EmitLoadOfScalar(LBLVal, Loc);
3640 auto UBFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTUpperBound);
3641 LValue UBLVal = CGF.EmitLValueForField(Base, *UBFI);
3642 llvm::Value *UBParam = CGF.EmitLoadOfScalar(UBLVal, Loc);
3643 auto StFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTStride);
3644 LValue StLVal = CGF.EmitLValueForField(Base, *StFI);
3645 llvm::Value *StParam = CGF.EmitLoadOfScalar(StLVal, Loc);
3646 auto LIFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLastIter);
3647 LValue LILVal = CGF.EmitLValueForField(Base, *LIFI);
3648 llvm::Value *LIParam = CGF.EmitLoadOfScalar(LILVal, Loc);
3649 auto RFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTReductions);
3650 LValue RLVal = CGF.EmitLValueForField(Base, *RFI);
3651 llvm::Value *RParam = CGF.EmitLoadOfScalar(RLVal, Loc);
3652 CallArgs.push_back(LBParam);
3653 CallArgs.push_back(UBParam);
3654 CallArgs.push_back(StParam);
3655 CallArgs.push_back(LIParam);
3656 CallArgs.push_back(RParam);
3657 }
3658 CallArgs.push_back(SharedsParam);
3659
3660 CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, Loc, TaskFunction,
3661 CallArgs);
3662 CGF.EmitStoreThroughLValue(RValue::get(CGF.Builder.getInt32(/*C=*/0)),
3663 CGF.MakeAddrLValue(CGF.ReturnValue, KmpInt32Ty));
3664 CGF.FinishFunction();
3665 return TaskEntry;
3666}
3667
3668static llvm::Value *emitDestructorsFunction(CodeGenModule &CGM,
3669 SourceLocation Loc,
3670 QualType KmpInt32Ty,
3671 QualType KmpTaskTWithPrivatesPtrQTy,
3672 QualType KmpTaskTWithPrivatesQTy) {
3673 ASTContext &C = CGM.getContext();
3674 FunctionArgList Args;
3675 ImplicitParamDecl GtidArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, KmpInt32Ty,
3676 ImplicitParamDecl::Other);
3677 ImplicitParamDecl TaskTypeArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
3678 KmpTaskTWithPrivatesPtrQTy.withRestrict(),
3679 ImplicitParamDecl::Other);
3680 Args.push_back(&GtidArg);
3681 Args.push_back(&TaskTypeArg);
3682 const auto &DestructorFnInfo =
3683 CGM.getTypes().arrangeBuiltinFunctionDeclaration(KmpInt32Ty, Args);
3684 llvm::FunctionType *DestructorFnTy =
3685 CGM.getTypes().GetFunctionType(DestructorFnInfo);
3686 std::string Name =
3687 CGM.getOpenMPRuntime().getName({"omp_task_destructor", ""});
3688 auto *DestructorFn =
3689 llvm::Function::Create(DestructorFnTy, llvm::GlobalValue::InternalLinkage,
3690 Name, &CGM.getModule());
3691 CGM.SetInternalFunctionAttributes(GlobalDecl(), DestructorFn,
3692 DestructorFnInfo);
3693 DestructorFn->setDoesNotRecurse();
3694 CodeGenFunction CGF(CGM);
3695 CGF.StartFunction(GlobalDecl(), KmpInt32Ty, DestructorFn, DestructorFnInfo,
3696 Args, Loc, Loc);
3697
3698 LValue Base = CGF.EmitLoadOfPointerLValue(
3699 CGF.GetAddrOfLocalVar(&TaskTypeArg),
3700 KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
3701 const auto *KmpTaskTWithPrivatesQTyRD =
3702 cast<RecordDecl>(KmpTaskTWithPrivatesQTy->getAsTagDecl());
3703 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
3704 Base = CGF.EmitLValueForField(Base, *FI);
3705 for (const auto *Field :
3706 cast<RecordDecl>(FI->getType()->getAsTagDecl())->fields()) {
3707 if (QualType::DestructionKind DtorKind =
3708 Field->getType().isDestructedType()) {
3709 LValue FieldLValue = CGF.EmitLValueForField(Base, Field);
3710 CGF.pushDestroy(DtorKind, FieldLValue.getAddress(CGF), Field->getType());
3711 }
3712 }
3713 CGF.FinishFunction();
3714 return DestructorFn;
3715}
3716
3717/// Emit a privates mapping function for correct handling of private and
3718/// firstprivate variables.
3719/// \code
3720/// void .omp_task_privates_map.(const .privates. *noalias privs, <ty1>
3721/// **noalias priv1,..., <tyn> **noalias privn) {
3722/// *priv1 = &.privates.priv1;
3723/// ...;
3724/// *privn = &.privates.privn;
3725/// }
3726/// \endcode
3727static llvm::Value *
3728emitTaskPrivateMappingFunction(CodeGenModule &CGM, SourceLocation Loc,
3729 const OMPTaskDataTy &Data, QualType PrivatesQTy,
3730 ArrayRef<PrivateDataTy> Privates) {
3731 ASTContext &C = CGM.getContext();
3732 FunctionArgList Args;
3733 ImplicitParamDecl TaskPrivatesArg(
3734 C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
3735 C.getPointerType(PrivatesQTy).withConst().withRestrict(),
3736 ImplicitParamDecl::Other);
3737 Args.push_back(&TaskPrivatesArg);
3738 llvm::DenseMap<CanonicalDeclPtr<const VarDecl>, unsigned> PrivateVarsPos;
3739 unsigned Counter = 1;
3740 for (const Expr *E : Data.PrivateVars) {
3741 Args.push_back(ImplicitParamDecl::Create(
3742 C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
3743 C.getPointerType(C.getPointerType(E->getType()))
3744 .withConst()
3745 .withRestrict(),
3746 ImplicitParamDecl::Other));
3747 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
3748 PrivateVarsPos[VD] = Counter;
3749 ++Counter;
3750 }
3751 for (const Expr *E : Data.FirstprivateVars) {
3752 Args.push_back(ImplicitParamDecl::Create(
3753 C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
3754 C.getPointerType(C.getPointerType(E->getType()))
3755 .withConst()
3756 .withRestrict(),
3757 ImplicitParamDecl::Other));
3758 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
3759 PrivateVarsPos[VD] = Counter;
3760 ++Counter;
3761 }
3762 for (const Expr *E : Data.LastprivateVars) {
3763 Args.push_back(ImplicitParamDecl::Create(
3764 C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
3765 C.getPointerType(C.getPointerType(E->getType()))
3766 .withConst()
3767 .withRestrict(),
3768 ImplicitParamDecl::Other));
3769 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
3770 PrivateVarsPos[VD] = Counter;
3771 ++Counter;
3772 }
3773 for (const VarDecl *VD : Data.PrivateLocals) {
3774 QualType Ty = VD->getType().getNonReferenceType();
3775 if (VD->getType()->isLValueReferenceType())
3776 Ty = C.getPointerType(Ty);
3777 if (isAllocatableDecl(VD))
3778 Ty = C.getPointerType(Ty);
3779 Args.push_back(ImplicitParamDecl::Create(
3780 C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
3781 C.getPointerType(C.getPointerType(Ty)).withConst().withRestrict(),
3782 ImplicitParamDecl::Other));
3783 PrivateVarsPos[VD] = Counter;
3784 ++Counter;
3785 }
3786 const auto &TaskPrivatesMapFnInfo =
3787 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
3788 llvm::FunctionType *TaskPrivatesMapTy =
3789 CGM.getTypes().GetFunctionType(TaskPrivatesMapFnInfo);
3790 std::string Name =
3791 CGM.getOpenMPRuntime().getName({"omp_task_privates_map", ""});
3792 auto *TaskPrivatesMap = llvm::Function::Create(
3793 TaskPrivatesMapTy, llvm::GlobalValue::InternalLinkage, Name,
3794 &CGM.getModule());
3795 CGM.SetInternalFunctionAttributes(GlobalDecl(), TaskPrivatesMap,
3796 TaskPrivatesMapFnInfo);
3797 if (CGM.getLangOpts().Optimize) {
3798 TaskPrivatesMap->removeFnAttr(llvm::Attribute::NoInline);
3799 TaskPrivatesMap->removeFnAttr(llvm::Attribute::OptimizeNone);
3800 TaskPrivatesMap->addFnAttr(llvm::Attribute::AlwaysInline);
3801 }
3802 CodeGenFunction CGF(CGM);
3803 CGF.StartFunction(GlobalDecl(), C.VoidTy, TaskPrivatesMap,
3804 TaskPrivatesMapFnInfo, Args, Loc, Loc);
3805
3806 // *privi = &.privates.privi;
3807 LValue Base = CGF.EmitLoadOfPointerLValue(
3808 CGF.GetAddrOfLocalVar(&TaskPrivatesArg),
3809 TaskPrivatesArg.getType()->castAs<PointerType>());
3810 const auto *PrivatesQTyRD = cast<RecordDecl>(PrivatesQTy->getAsTagDecl());
3811 Counter = 0;
3812 for (const FieldDecl *Field : PrivatesQTyRD->fields()) {
3813 LValue FieldLVal = CGF.EmitLValueForField(Base, Field);
3814 const VarDecl *VD = Args[PrivateVarsPos[Privates[Counter].second.Original]];
3815 LValue RefLVal =
3816 CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(VD), VD->getType());
3817 LValue RefLoadLVal = CGF.EmitLoadOfPointerLValue(
3818 RefLVal.getAddress(CGF), RefLVal.getType()->castAs<PointerType>());
3819 CGF.EmitStoreOfScalar(FieldLVal.getPointer(CGF), RefLoadLVal);
3820 ++Counter;
3821 }
3822 CGF.FinishFunction();
3823 return TaskPrivatesMap;
3824}
3825
3826/// Emit initialization for private variables in task-based directives.
3827static void emitPrivatesInit(CodeGenFunction &CGF,
3828 const OMPExecutableDirective &D,
3829 Address KmpTaskSharedsPtr, LValue TDBase,
3830 const RecordDecl *KmpTaskTWithPrivatesQTyRD,
3831 QualType SharedsTy, QualType SharedsPtrTy,
3832 const OMPTaskDataTy &Data,
3833 ArrayRef<PrivateDataTy> Privates, bool ForDup) {
3834 ASTContext &C = CGF.getContext();
3835 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
3836 LValue PrivatesBase = CGF.EmitLValueForField(TDBase, *FI);
3837 OpenMPDirectiveKind Kind = isOpenMPTaskLoopDirective(D.getDirectiveKind())
3838 ? OMPD_taskloop
3839 : OMPD_task;
3840 const CapturedStmt &CS = *D.getCapturedStmt(Kind);
3841 CodeGenFunction::CGCapturedStmtInfo CapturesInfo(CS);
3842 LValue SrcBase;
3843 bool IsTargetTask =
3844 isOpenMPTargetDataManagementDirective(D.getDirectiveKind()) ||
3845 isOpenMPTargetExecutionDirective(D.getDirectiveKind());
3846 // For target-based directives skip 4 firstprivate arrays BasePointersArray,
3847 // PointersArray, SizesArray, and MappersArray. The original variables for
3848 // these arrays are not captured and we get their addresses explicitly.
3849 if ((!IsTargetTask && !Data.FirstprivateVars.empty() && ForDup) ||
3850 (IsTargetTask && KmpTaskSharedsPtr.isValid())) {
3851 SrcBase = CGF.MakeAddrLValue(
3852 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
3853 KmpTaskSharedsPtr, CGF.ConvertTypeForMem(SharedsPtrTy)),
3854 SharedsTy);
3855 }
3856 FI = cast<RecordDecl>(FI->getType()->getAsTagDecl())->field_begin();
3857 for (const PrivateDataTy &Pair : Privates) {
3858 // Do not initialize private locals.
3859 if (Pair.second.isLocalPrivate()) {
3860 ++FI;
3861 continue;
3862 }
3863 const VarDecl *VD = Pair.second.PrivateCopy;
3864 const Expr *Init = VD->getAnyInitializer();
3865 if (Init && (!ForDup || (isa<CXXConstructExpr>(Init) &&
3866 !CGF.isTrivialInitializer(Init)))) {
3867 LValue PrivateLValue = CGF.EmitLValueForField(PrivatesBase, *FI);
3868 if (const VarDecl *Elem = Pair.second.PrivateElemInit) {
3869 const VarDecl *OriginalVD = Pair.second.Original;
3870 // Check if the variable is the target-based BasePointersArray,
3871 // PointersArray, SizesArray, or MappersArray.
3872 LValue SharedRefLValue;
3873 QualType Type = PrivateLValue.getType();
3874 const FieldDecl *SharedField = CapturesInfo.lookup(OriginalVD);
3875 if (IsTargetTask && !SharedField) {
3876 assert(isa<ImplicitParamDecl>(OriginalVD) &&(static_cast<void> (0))
3877 isa<CapturedDecl>(OriginalVD->getDeclContext()) &&(static_cast<void> (0))
3878 cast<CapturedDecl>(OriginalVD->getDeclContext())(static_cast<void> (0))
3879 ->getNumParams() == 0 &&(static_cast<void> (0))
3880 isa<TranslationUnitDecl>((static_cast<void> (0))
3881 cast<CapturedDecl>(OriginalVD->getDeclContext())(static_cast<void> (0))
3882 ->getDeclContext()) &&(static_cast<void> (0))
3883 "Expected artificial target data variable.")(static_cast<void> (0));
3884 SharedRefLValue =
3885 CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(OriginalVD), Type);
3886 } else if (ForDup) {
3887 SharedRefLValue = CGF.EmitLValueForField(SrcBase, SharedField);
3888 SharedRefLValue = CGF.MakeAddrLValue(
3889 Address(SharedRefLValue.getPointer(CGF),
3890 C.getDeclAlign(OriginalVD)),
3891 SharedRefLValue.getType(), LValueBaseInfo(AlignmentSource::Decl),
3892 SharedRefLValue.getTBAAInfo());
3893 } else if (CGF.LambdaCaptureFields.count(
3894 Pair.second.Original->getCanonicalDecl()) > 0 ||
3895 dyn_cast_or_null<BlockDecl>(CGF.CurCodeDecl)) {
3896 SharedRefLValue = CGF.EmitLValue(Pair.second.OriginalRef);
3897 } else {
3898 // Processing for implicitly captured variables.
3899 InlinedOpenMPRegionRAII Region(
3900 CGF, [](CodeGenFunction &, PrePostActionTy &) {}, OMPD_unknown,
3901 /*HasCancel=*/false, /*NoInheritance=*/true);
3902 SharedRefLValue = CGF.EmitLValue(Pair.second.OriginalRef);
3903 }
3904 if (Type->isArrayType()) {
3905 // Initialize firstprivate array.
3906 if (!isa<CXXConstructExpr>(Init) || CGF.isTrivialInitializer(Init)) {
3907 // Perform simple memcpy.
3908 CGF.EmitAggregateAssign(PrivateLValue, SharedRefLValue, Type);
3909 } else {
3910 // Initialize firstprivate array using element-by-element
3911 // initialization.
3912 CGF.EmitOMPAggregateAssign(
3913 PrivateLValue.getAddress(CGF), SharedRefLValue.getAddress(CGF),
3914 Type,
3915 [&CGF, Elem, Init, &CapturesInfo](Address DestElement,
3916 Address SrcElement) {
3917 // Clean up any temporaries needed by the initialization.
3918 CodeGenFunction::OMPPrivateScope InitScope(CGF);
3919 InitScope.addPrivate(
3920 Elem, [SrcElement]() -> Address { return SrcElement; });
3921 (void)InitScope.Privatize();
3922 // Emit initialization for single element.
3923 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(
3924 CGF, &CapturesInfo);
3925 CGF.EmitAnyExprToMem(Init, DestElement,
3926 Init->getType().getQualifiers(),
3927 /*IsInitializer=*/false);
3928 });
3929 }
3930 } else {
3931 CodeGenFunction::OMPPrivateScope InitScope(CGF);
3932 InitScope.addPrivate(Elem, [SharedRefLValue, &CGF]() -> Address {
3933 return SharedRefLValue.getAddress(CGF);
3934 });
3935 (void)InitScope.Privatize();
3936 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CapturesInfo);
3937 CGF.EmitExprAsInit(Init, VD, PrivateLValue,
3938 /*capturedByInit=*/false);
3939 }
3940 } else {
3941 CGF.EmitExprAsInit(Init, VD, PrivateLValue, /*capturedByInit=*/false);
3942 }
3943 }
3944 ++FI;
3945 }
3946}
3947
3948/// Check if duplication function is required for taskloops.
3949static bool checkInitIsRequired(CodeGenFunction &CGF,
3950 ArrayRef<PrivateDataTy> Privates) {
3951 bool InitRequired = false;
3952 for (const PrivateDataTy &Pair : Privates) {
3953 if (Pair.second.isLocalPrivate())
3954 continue;
3955 const VarDecl *VD = Pair.second.PrivateCopy;
3956 const Expr *Init = VD->getAnyInitializer();
3957 InitRequired = InitRequired || (Init && isa<CXXConstructExpr>(Init) &&
3958 !CGF.isTrivialInitializer(Init));
3959 if (InitRequired)
3960 break;
3961 }
3962 return InitRequired;
3963}
3964
3965
3966/// Emit task_dup function (for initialization of
3967/// private/firstprivate/lastprivate vars and last_iter flag)
3968/// \code
3969/// void __task_dup_entry(kmp_task_t *task_dst, const kmp_task_t *task_src, int
3970/// lastpriv) {
3971/// // setup lastprivate flag
3972/// task_dst->last = lastpriv;
3973/// // could be constructor calls here...
3974/// }
3975/// \endcode
3976static llvm::Value *
3977emitTaskDupFunction(CodeGenModule &CGM, SourceLocation Loc,
3978 const OMPExecutableDirective &D,
3979 QualType KmpTaskTWithPrivatesPtrQTy,
3980 const RecordDecl *KmpTaskTWithPrivatesQTyRD,
3981 const RecordDecl *KmpTaskTQTyRD, QualType SharedsTy,
3982 QualType SharedsPtrTy, const OMPTaskDataTy &Data,
3983 ArrayRef<PrivateDataTy> Privates, bool WithLastIter) {
3984 ASTContext &C = CGM.getContext();
3985 FunctionArgList Args;
3986 ImplicitParamDecl DstArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
3987 KmpTaskTWithPrivatesPtrQTy,
3988 ImplicitParamDecl::Other);
3989 ImplicitParamDecl SrcArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
3990 KmpTaskTWithPrivatesPtrQTy,
3991 ImplicitParamDecl::Other);
3992 ImplicitParamDecl LastprivArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.IntTy,
3993 ImplicitParamDecl::Other);
3994 Args.push_back(&DstArg);
3995 Args.push_back(&SrcArg);
3996 Args.push_back(&LastprivArg);
3997 const auto &TaskDupFnInfo =
3998 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
3999 llvm::FunctionType *TaskDupTy = CGM.getTypes().GetFunctionType(TaskDupFnInfo);
4000 std::string Name = CGM.getOpenMPRuntime().getName({"omp_task_dup", ""});
4001 auto *TaskDup = llvm::Function::Create(
4002 TaskDupTy, llvm::GlobalValue::InternalLinkage, Name, &CGM.getModule());
4003 CGM.SetInternalFunctionAttributes(GlobalDecl(), TaskDup, TaskDupFnInfo);
4004 TaskDup->setDoesNotRecurse();
4005 CodeGenFunction CGF(CGM);
4006 CGF.StartFunction(GlobalDecl(), C.VoidTy, TaskDup, TaskDupFnInfo, Args, Loc,
4007 Loc);
4008
4009 LValue TDBase = CGF.EmitLoadOfPointerLValue(
4010 CGF.GetAddrOfLocalVar(&DstArg),
4011 KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
4012 // task_dst->liter = lastpriv;
4013 if (WithLastIter) {
4014 auto LIFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLastIter);
4015 LValue Base = CGF.EmitLValueForField(
4016 TDBase, *KmpTaskTWithPrivatesQTyRD->field_begin());
4017 LValue LILVal = CGF.EmitLValueForField(Base, *LIFI);
4018 llvm::Value *Lastpriv = CGF.EmitLoadOfScalar(
4019 CGF.GetAddrOfLocalVar(&LastprivArg), /*Volatile=*/false, C.IntTy, Loc);
4020 CGF.EmitStoreOfScalar(Lastpriv, LILVal);
4021 }
4022
4023 // Emit initial values for private copies (if any).
4024 assert(!Privates.empty())(static_cast<void> (0));
4025 Address KmpTaskSharedsPtr = Address::invalid();
4026 if (!Data.FirstprivateVars.empty()) {
4027 LValue TDBase = CGF.EmitLoadOfPointerLValue(
4028 CGF.GetAddrOfLocalVar(&SrcArg),
4029 KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
4030 LValue Base = CGF.EmitLValueForField(
4031 TDBase, *KmpTaskTWithPrivatesQTyRD->field_begin());
4032 KmpTaskSharedsPtr = Address(
4033 CGF.EmitLoadOfScalar(CGF.EmitLValueForField(
4034 Base, *std::next(KmpTaskTQTyRD->field_begin(),
4035 KmpTaskTShareds)),
4036 Loc),
4037 CGM.getNaturalTypeAlignment(SharedsTy));
4038 }
4039 emitPrivatesInit(CGF, D, KmpTaskSharedsPtr, TDBase, KmpTaskTWithPrivatesQTyRD,
4040 SharedsTy, SharedsPtrTy, Data, Privates, /*ForDup=*/true);
4041 CGF.FinishFunction();
4042 return TaskDup;
4043}
4044
4045/// Checks if destructor function is required to be generated.
4046/// \return true if cleanups are required, false otherwise.
4047static bool
4048checkDestructorsRequired(const RecordDecl *KmpTaskTWithPrivatesQTyRD,
4049 ArrayRef<PrivateDataTy> Privates) {
4050 for (const PrivateDataTy &P : Privates) {
4051 if (P.second.isLocalPrivate())
4052 continue;
4053 QualType Ty = P.second.Original->getType().getNonReferenceType();
4054 if (Ty.isDestructedType())
4055 return true;
4056 }
4057 return false;
4058}
4059
4060namespace {
4061/// Loop generator for OpenMP iterator expression.
4062class OMPIteratorGeneratorScope final
4063 : public CodeGenFunction::OMPPrivateScope {
4064 CodeGenFunction &CGF;
4065 const OMPIteratorExpr *E = nullptr;
4066 SmallVector<CodeGenFunction::JumpDest, 4> ContDests;
4067 SmallVector<CodeGenFunction::JumpDest, 4> ExitDests;
4068 OMPIteratorGeneratorScope() = delete;
4069 OMPIteratorGeneratorScope(OMPIteratorGeneratorScope &) = delete;
4070
4071public:
4072 OMPIteratorGeneratorScope(CodeGenFunction &CGF, const OMPIteratorExpr *E)
4073 : CodeGenFunction::OMPPrivateScope(CGF), CGF(CGF), E(E) {
4074 if (!E)
4075 return;
4076 SmallVector<llvm::Value *, 4> Uppers;
4077 for (unsigned I = 0, End = E->numOfIterators(); I < End; ++I) {
4078 Uppers.push_back(CGF.EmitScalarExpr(E->getHelper(I).Upper));
4079 const auto *VD = cast<VarDecl>(E->getIteratorDecl(I));
4080 addPrivate(VD, [&CGF, VD]() {
4081 return CGF.CreateMemTemp(VD->getType(), VD->getName());
4082 });
4083 const OMPIteratorHelperData &HelperData = E->getHelper(I);
4084 addPrivate(HelperData.CounterVD, [&CGF, &HelperData]() {
4085 return CGF.CreateMemTemp(HelperData.CounterVD->getType(),
4086 "counter.addr");
4087 });
4088 }
4089 Privatize();
4090
4091 for (unsigned I = 0, End = E->numOfIterators(); I < End; ++I) {
4092 const OMPIteratorHelperData &HelperData = E->getHelper(I);
4093 LValue CLVal =
4094 CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(HelperData.CounterVD),
4095 HelperData.CounterVD->getType());
4096 // Counter = 0;
4097 CGF.EmitStoreOfScalar(
4098 llvm::ConstantInt::get(CLVal.getAddress(CGF).getElementType(), 0),
4099 CLVal);
4100 CodeGenFunction::JumpDest &ContDest =
4101 ContDests.emplace_back(CGF.getJumpDestInCurrentScope("iter.cont"));
4102 CodeGenFunction::JumpDest &ExitDest =
4103 ExitDests.emplace_back(CGF.getJumpDestInCurrentScope("iter.exit"));
4104 // N = <number-of_iterations>;
4105 llvm::Value *N = Uppers[I];
4106 // cont:
4107 // if (Counter < N) goto body; else goto exit;
4108 CGF.EmitBlock(ContDest.getBlock());
4109 auto *CVal =
4110 CGF.EmitLoadOfScalar(CLVal, HelperData.CounterVD->getLocation());
4111 llvm::Value *Cmp =
4112 HelperData.CounterVD->getType()->isSignedIntegerOrEnumerationType()
4113 ? CGF.Builder.CreateICmpSLT(CVal, N)
4114 : CGF.Builder.CreateICmpULT(CVal, N);
4115 llvm::BasicBlock *BodyBB = CGF.createBasicBlock("iter.body");
4116 CGF.Builder.CreateCondBr(Cmp, BodyBB, ExitDest.getBlock());
4117 // body:
4118 CGF.EmitBlock(BodyBB);
4119 // Iteri = Begini + Counter * Stepi;
4120 CGF.EmitIgnoredExpr(HelperData.Update);
4121 }
4122 }
4123 ~OMPIteratorGeneratorScope() {
4124 if (!E)
4125 return;
4126 for (unsigned I = E->numOfIterators(); I > 0; --I) {
4127 // Counter = Counter + 1;
4128 const OMPIteratorHelperData &HelperData = E->getHelper(I - 1);
4129 CGF.EmitIgnoredExpr(HelperData.CounterUpdate);
4130 // goto cont;
4131 CGF.EmitBranchThroughCleanup(ContDests[I - 1]);
4132 // exit:
4133 CGF.EmitBlock(ExitDests[I - 1].getBlock(), /*IsFinished=*/I == 1);
4134 }
4135 }
4136};
4137} // namespace
4138
4139static std::pair<llvm::Value *, llvm::Value *>
4140getPointerAndSize(CodeGenFunction &CGF, const Expr *E) {
4141 const auto *OASE = dyn_cast<OMPArrayShapingExpr>(E);
4142 llvm::Value *Addr;
4143 if (OASE) {
4144 const Expr *Base = OASE->getBase();
4145 Addr = CGF.EmitScalarExpr(Base);
4146 } else {
4147 Addr = CGF.EmitLValue(E).getPointer(CGF);
4148 }
4149 llvm::Value *SizeVal;
4150 QualType Ty = E->getType();
4151 if (OASE) {
4152 SizeVal = CGF.getTypeSize(OASE->getBase()->getType()->getPointeeType());
4153 for (const Expr *SE : OASE->getDimensions()) {
4154 llvm::Value *Sz = CGF.EmitScalarExpr(SE);
4155 Sz = CGF.EmitScalarConversion(
4156 Sz, SE->getType(), CGF.getContext().getSizeType(), SE->getExprLoc());
4157 SizeVal = CGF.Builder.CreateNUWMul(SizeVal, Sz);
4158 }
4159 } else if (const auto *ASE =
4160 dyn_cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts())) {
4161 LValue UpAddrLVal =
4162 CGF.EmitOMPArraySectionExpr(ASE, /*IsLowerBound=*/false);
4163 Address UpAddrAddress = UpAddrLVal.getAddress(CGF);
4164 llvm::Value *UpAddr = CGF.Builder.CreateConstGEP1_32(
4165 UpAddrAddress.getElementType(), UpAddrAddress.getPointer(), /*Idx0=*/1);
4166 llvm::Value *LowIntPtr = CGF.Builder.CreatePtrToInt(Addr, CGF.SizeTy);
4167 llvm::Value *UpIntPtr = CGF.Builder.CreatePtrToInt(UpAddr, CGF.SizeTy);
4168 SizeVal = CGF.Builder.CreateNUWSub(UpIntPtr, LowIntPtr);
4169 } else {
4170 SizeVal = CGF.getTypeSize(Ty);
4171 }
4172 return std::make_pair(Addr, SizeVal);
4173}
4174
4175/// Builds kmp_depend_info, if it is not built yet, and builds flags type.
4176static void getKmpAffinityType(ASTContext &C, QualType &KmpTaskAffinityInfoTy) {
4177 QualType FlagsTy = C.getIntTypeForBitwidth(32, /*Signed=*/false);
4178 if (KmpTaskAffinityInfoTy.isNull()) {
4179 RecordDecl *KmpAffinityInfoRD =
4180 C.buildImplicitRecord("kmp_task_affinity_info_t");
4181 KmpAffinityInfoRD->startDefinition();
4182 addFieldToRecordDecl(C, KmpAffinityInfoRD, C.getIntPtrType());
4183 addFieldToRecordDecl(C, KmpAffinityInfoRD, C.getSizeType());
4184 addFieldToRecordDecl(C, KmpAffinityInfoRD, FlagsTy);
4185 KmpAffinityInfoRD->completeDefinition();
4186 KmpTaskAffinityInfoTy = C.getRecordType(KmpAffinityInfoRD);
4187 }
4188}
4189
4190CGOpenMPRuntime::TaskResultTy
4191CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
4192 const OMPExecutableDirective &D,
4193 llvm::Function *TaskFunction, QualType SharedsTy,
4194 Address Shareds, const OMPTaskDataTy &Data) {
4195 ASTContext &C = CGM.getContext();
4196 llvm::SmallVector<PrivateDataTy, 4> Privates;
4197 // Aggregate privates and sort them by the alignment.
4198 const auto *I = Data.PrivateCopies.begin();
4199 for (const Expr *E : Data.PrivateVars) {
4200 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4201 Privates.emplace_back(
4202 C.getDeclAlign(VD),
4203 PrivateHelpersTy(E, VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
4204 /*PrivateElemInit=*/nullptr));
4205 ++I;
4206 }
4207 I = Data.FirstprivateCopies.begin();
4208 const auto *IElemInitRef = Data.FirstprivateInits.begin();
4209 for (const Expr *E : Data.FirstprivateVars) {
4210 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4211 Privates.emplace_back(
4212 C.getDeclAlign(VD),
4213 PrivateHelpersTy(
4214 E, VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
4215 cast<VarDecl>(cast<DeclRefExpr>(*IElemInitRef)->getDecl())));
4216 ++I;
4217 ++IElemInitRef;
4218 }
4219 I = Data.LastprivateCopies.begin();
4220 for (const Expr *E : Data.LastprivateVars) {
4221 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
4222 Privates.emplace_back(
4223 C.getDeclAlign(VD),
4224 PrivateHelpersTy(E, VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
4225 /*PrivateElemInit=*/nullptr));
4226 ++I;
4227 }
4228 for (const VarDecl *VD : Data.PrivateLocals) {
4229 if (isAllocatableDecl(VD))
4230 Privates.emplace_back(CGM.getPointerAlign(), PrivateHelpersTy(VD));
4231 else
4232 Privates.emplace_back(C.getDeclAlign(VD), PrivateHelpersTy(VD));
4233 }
4234 llvm::stable_sort(Privates,
4235 [](const PrivateDataTy &L, const PrivateDataTy &R) {
4236 return L.first > R.first;
4237 });
4238 QualType KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
4239 // Build type kmp_routine_entry_t (if not built yet).
4240 emitKmpRoutineEntryT(KmpInt32Ty);
4241 // Build type kmp_task_t (if not built yet).
4242 if (isOpenMPTaskLoopDirective(D.getDirectiveKind())) {
4243 if (SavedKmpTaskloopTQTy.isNull()) {
4244 SavedKmpTaskloopTQTy = C.getRecordType(createKmpTaskTRecordDecl(
4245 CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy));
4246 }
4247 KmpTaskTQTy = SavedKmpTaskloopTQTy;
4248 } else {
4249 assert((D.getDirectiveKind() == OMPD_task ||(static_cast<void> (0))
4250 isOpenMPTargetExecutionDirective(D.getDirectiveKind()) ||(static_cast<void> (0))
4251 isOpenMPTargetDataManagementDirective(D.getDirectiveKind())) &&(static_cast<void> (0))
4252 "Expected taskloop, task or target directive")(static_cast<void> (0));
4253 if (SavedKmpTaskTQTy.isNull()) {
4254 SavedKmpTaskTQTy = C.getRecordType(createKmpTaskTRecordDecl(
4255 CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy));
4256 }
4257 KmpTaskTQTy = SavedKmpTaskTQTy;
4258 }
4259 const auto *KmpTaskTQTyRD = cast<RecordDecl>(KmpTaskTQTy->getAsTagDecl());
4260 // Build particular struct kmp_task_t for the given task.
4261 const RecordDecl *KmpTaskTWithPrivatesQTyRD =
4262 createKmpTaskTWithPrivatesRecordDecl(CGM, KmpTaskTQTy, Privates);
4263 QualType KmpTaskTWithPrivatesQTy = C.getRecordType(KmpTaskTWithPrivatesQTyRD);
4264 QualType KmpTaskTWithPrivatesPtrQTy =
4265 C.getPointerType(KmpTaskTWithPrivatesQTy);
4266 llvm::Type *KmpTaskTWithPrivatesTy = CGF.ConvertType(KmpTaskTWithPrivatesQTy);
4267 llvm::Type *KmpTaskTWithPrivatesPtrTy =
4268 KmpTaskTWithPrivatesTy->getPointerTo();
4269 llvm::Value *KmpTaskTWithPrivatesTySize =
4270 CGF.getTypeSize(KmpTaskTWithPrivatesQTy);
4271 QualType SharedsPtrTy = C.getPointerType(SharedsTy);
4272
4273 // Emit initial values for private copies (if any).
4274 llvm::Value *TaskPrivatesMap = nullptr;
4275 llvm::Type *TaskPrivatesMapTy =
4276 std::next(TaskFunction->arg_begin(), 3)->getType();
4277 if (!Privates.empty()) {
4278 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
4279 TaskPrivatesMap =
4280 emitTaskPrivateMappingFunction(CGM, Loc, Data, FI->getType(), Privates);
4281 TaskPrivatesMap = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
4282 TaskPrivatesMap, TaskPrivatesMapTy);
4283 } else {
4284 TaskPrivatesMap = llvm::ConstantPointerNull::get(
4285 cast<llvm::PointerType>(TaskPrivatesMapTy));
4286 }
4287 // Build a proxy function kmp_int32 .omp_task_entry.(kmp_int32 gtid,
4288 // kmp_task_t *tt);
4289 llvm::Function *TaskEntry = emitProxyTaskFunction(
4290 CGM, Loc, D.getDirectiveKind(), KmpInt32Ty, KmpTaskTWithPrivatesPtrQTy,
4291 KmpTaskTWithPrivatesQTy, KmpTaskTQTy, SharedsPtrTy, TaskFunction,
4292 TaskPrivatesMap);
4293
4294 // Build call kmp_task_t * __kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid,
4295 // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
4296 // kmp_routine_entry_t *task_entry);
4297 // Task flags. Format is taken from
4298 // https://github.com/llvm/llvm-project/blob/main/openmp/runtime/src/kmp.h,
4299 // description of kmp_tasking_flags struct.
4300 enum {
4301 TiedFlag = 0x1,
4302 FinalFlag = 0x2,
4303 DestructorsFlag = 0x8,
4304 PriorityFlag = 0x20,
4305 DetachableFlag = 0x40,
4306 };
4307 unsigned Flags = Data.Tied ? TiedFlag : 0;
4308 bool NeedsCleanup = false;
4309 if (!Privates.empty()) {
4310 NeedsCleanup =
4311 checkDestructorsRequired(KmpTaskTWithPrivatesQTyRD, Privates);
4312 if (NeedsCleanup)
4313 Flags = Flags | DestructorsFlag;
4314 }
4315 if (Data.Priority.getInt())
4316 Flags = Flags | PriorityFlag;
4317 if (D.hasClausesOfKind<OMPDetachClause>())
4318 Flags = Flags | DetachableFlag;
4319 llvm::Value *TaskFlags =
4320 Data.Final.getPointer()
4321 ? CGF.Builder.CreateSelect(Data.Final.getPointer(),
4322 CGF.Builder.getInt32(FinalFlag),
4323 CGF.Builder.getInt32(/*C=*/0))
4324 : CGF.Builder.getInt32(Data.Final.getInt() ? FinalFlag : 0);
4325 TaskFlags = CGF.Builder.CreateOr(TaskFlags, CGF.Builder.getInt32(Flags));
4326 llvm::Value *SharedsSize = CGM.getSize(C.getTypeSizeInChars(SharedsTy));
4327 SmallVector<llvm::Value *, 8> AllocArgs = {emitUpdateLocation(CGF, Loc),
4328 getThreadID(CGF, Loc), TaskFlags, KmpTaskTWithPrivatesTySize,
4329 SharedsSize, CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
4330 TaskEntry, KmpRoutineEntryPtrTy)};
4331 llvm::Value *NewTask;
4332 if (D.hasClausesOfKind<OMPNowaitClause>()) {
4333 // Check if we have any device clause associated with the directive.
4334 const Expr *Device = nullptr;
4335 if (auto *C = D.getSingleClause<OMPDeviceClause>())
4336 Device = C->getDevice();
4337 // Emit device ID if any otherwise use default value.
4338 llvm::Value *DeviceID;
4339 if (Device)
4340 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
4341 CGF.Int64Ty, /*isSigned=*/true);
4342 else
4343 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
4344 AllocArgs.push_back(DeviceID);
4345 NewTask = CGF.EmitRuntimeCall(
4346 OMPBuilder.getOrCreateRuntimeFunction(
4347 CGM.getModule(), OMPRTL___kmpc_omp_target_task_alloc),
4348 AllocArgs);
4349 } else {
4350 NewTask =
4351 CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
4352 CGM.getModule(), OMPRTL___kmpc_omp_task_alloc),
4353 AllocArgs);
4354 }
4355 // Emit detach clause initialization.
4356 // evt = (typeof(evt))__kmpc_task_allow_completion_event(loc, tid,
4357 // task_descriptor);
4358 if (const auto *DC = D.getSingleClause<OMPDetachClause>()) {
4359 const Expr *Evt = DC->getEventHandler()->IgnoreParenImpCasts();
4360 LValue EvtLVal = CGF.EmitLValue(Evt);
4361
4362 // Build kmp_event_t *__kmpc_task_allow_completion_event(ident_t *loc_ref,
4363 // int gtid, kmp_task_t *task);
4364 llvm::Value *Loc = emitUpdateLocation(CGF, DC->getBeginLoc());
4365 llvm::Value *Tid = getThreadID(CGF, DC->getBeginLoc());
4366 Tid = CGF.Builder.CreateIntCast(Tid, CGF.IntTy, /*isSigned=*/false);
4367 llvm::Value *EvtVal = CGF.EmitRuntimeCall(
4368 OMPBuilder.getOrCreateRuntimeFunction(
4369 CGM.getModule(), OMPRTL___kmpc_task_allow_completion_event),
4370 {Loc, Tid, NewTask});
4371 EvtVal = CGF.EmitScalarConversion(EvtVal, C.VoidPtrTy, Evt->getType(),
4372 Evt->getExprLoc());
4373 CGF.EmitStoreOfScalar(EvtVal, EvtLVal);
4374 }
4375 // Process affinity clauses.
4376 if (D.hasClausesOfKind<OMPAffinityClause>()) {
4377 // Process list of affinity data.
4378 ASTContext &C = CGM.getContext();
4379 Address AffinitiesArray = Address::invalid();
4380 // Calculate number of elements to form the array of affinity data.
4381 llvm::Value *NumOfElements = nullptr;
4382 unsigned NumAffinities = 0;
4383 for (const auto *C : D.getClausesOfKind<OMPAffinityClause>()) {
4384 if (const Expr *Modifier = C->getModifier()) {
4385 const auto *IE = cast<OMPIteratorExpr>(Modifier->IgnoreParenImpCasts());
4386 for (unsigned I = 0, E = IE->numOfIterators(); I < E; ++I) {
4387 llvm::Value *Sz = CGF.EmitScalarExpr(IE->getHelper(I).Upper);
4388 Sz = CGF.Builder.CreateIntCast(Sz, CGF.SizeTy, /*isSigned=*/false);
4389 NumOfElements =
4390 NumOfElements ? CGF.Builder.CreateNUWMul(NumOfElements, Sz) : Sz;
4391 }
4392 } else {
4393 NumAffinities += C->varlist_size();
4394 }
4395 }
4396 getKmpAffinityType(CGM.getContext(), KmpTaskAffinityInfoTy);
4397 // Fields ids in kmp_task_affinity_info record.
4398 enum RTLAffinityInfoFieldsTy { BaseAddr, Len, Flags };
4399
4400 QualType KmpTaskAffinityInfoArrayTy;
4401 if (NumOfElements) {
4402 NumOfElements = CGF.Builder.CreateNUWAdd(
4403 llvm::ConstantInt::get(CGF.SizeTy, NumAffinities), NumOfElements);
4404 auto *OVE = new (C) OpaqueValueExpr(
4405 Loc,
4406 C.getIntTypeForBitwidth(C.getTypeSize(C.getSizeType()), /*Signed=*/0),
4407 VK_PRValue);
4408 CodeGenFunction::OpaqueValueMapping OpaqueMap(CGF, OVE,
4409 RValue::get(NumOfElements));
4410 KmpTaskAffinityInfoArrayTy =
4411 C.getVariableArrayType(KmpTaskAffinityInfoTy, OVE, ArrayType::Normal,
4412 /*IndexTypeQuals=*/0, SourceRange(Loc, Loc));
4413 // Properly emit variable-sized array.
4414 auto *PD = ImplicitParamDecl::Create(C, KmpTaskAffinityInfoArrayTy,
4415 ImplicitParamDecl::Other);
4416 CGF.EmitVarDecl(*PD);
4417 AffinitiesArray = CGF.GetAddrOfLocalVar(PD);
4418 NumOfElements = CGF.Builder.CreateIntCast(NumOfElements, CGF.Int32Ty,
4419 /*isSigned=*/false);
4420 } else {
4421 KmpTaskAffinityInfoArrayTy = C.getConstantArrayType(
4422 KmpTaskAffinityInfoTy,
4423 llvm::APInt(C.getTypeSize(C.getSizeType()), NumAffinities), nullptr,
4424 ArrayType::Normal, /*IndexTypeQuals=*/0);
4425 AffinitiesArray =
4426 CGF.CreateMemTemp(KmpTaskAffinityInfoArrayTy, ".affs.arr.addr");
4427 AffinitiesArray = CGF.Builder.CreateConstArrayGEP(AffinitiesArray, 0);
4428 NumOfElements = llvm::ConstantInt::get(CGM.Int32Ty, NumAffinities,
4429 /*isSigned=*/false);
4430 }
4431
4432 const auto *KmpAffinityInfoRD = KmpTaskAffinityInfoTy->getAsRecordDecl();
4433 // Fill array by elements without iterators.
4434 unsigned Pos = 0;
4435 bool HasIterator = false;
4436 for (const auto *C : D.getClausesOfKind<OMPAffinityClause>()) {
4437 if (C->getModifier()) {
4438 HasIterator = true;
4439 continue;
4440 }
4441 for (const Expr *E : C->varlists()) {
4442 llvm::Value *Addr;
4443 llvm::Value *Size;
4444 std::tie(Addr, Size) = getPointerAndSize(CGF, E);
4445 LValue Base =
4446 CGF.MakeAddrLValue(CGF.Builder.CreateConstGEP(AffinitiesArray, Pos),
4447 KmpTaskAffinityInfoTy);
4448 // affs[i].base_addr = &<Affinities[i].second>;
4449 LValue BaseAddrLVal = CGF.EmitLValueForField(
4450 Base, *std::next(KmpAffinityInfoRD->field_begin(), BaseAddr));
4451 CGF.EmitStoreOfScalar(CGF.Builder.CreatePtrToInt(Addr, CGF.IntPtrTy),
4452 BaseAddrLVal);
4453 // affs[i].len = sizeof(<Affinities[i].second>);
4454 LValue LenLVal = CGF.EmitLValueForField(
4455 Base, *std::next(KmpAffinityInfoRD->field_begin(), Len));
4456 CGF.EmitStoreOfScalar(Size, LenLVal);
4457 ++Pos;
4458 }
4459 }
4460 LValue PosLVal;
4461 if (HasIterator) {
4462 PosLVal = CGF.MakeAddrLValue(
4463 CGF.CreateMemTemp(C.getSizeType(), "affs.counter.addr"),
4464 C.getSizeType());
4465 CGF.EmitStoreOfScalar(llvm::ConstantInt::get(CGF.SizeTy, Pos), PosLVal);
4466 }
4467 // Process elements with iterators.
4468 for (const auto *C : D.getClausesOfKind<OMPAffinityClause>()) {
4469 const Expr *Modifier = C->getModifier();
4470 if (!Modifier)
4471 continue;
4472 OMPIteratorGeneratorScope IteratorScope(
4473 CGF, cast_or_null<OMPIteratorExpr>(Modifier->IgnoreParenImpCasts()));
4474 for (const Expr *E : C->varlists()) {
4475 llvm::Value *Addr;
4476 llvm::Value *Size;
4477 std::tie(Addr, Size) = getPointerAndSize(CGF, E);
4478 llvm::Value *Idx = CGF.EmitLoadOfScalar(PosLVal, E->getExprLoc());
4479 LValue Base = CGF.MakeAddrLValue(
4480 Address(CGF.Builder.CreateGEP(AffinitiesArray.getElementType(),
4481 AffinitiesArray.getPointer(), Idx),
4482 AffinitiesArray.getAlignment()),
4483 KmpTaskAffinityInfoTy);
4484 // affs[i].base_addr = &<Affinities[i].second>;
4485 LValue BaseAddrLVal = CGF.EmitLValueForField(
4486 Base, *std::next(KmpAffinityInfoRD->field_begin(), BaseAddr));
4487 CGF.EmitStoreOfScalar(CGF.Builder.CreatePtrToInt(Addr, CGF.IntPtrTy),
4488 BaseAddrLVal);
4489 // affs[i].len = sizeof(<Affinities[i].second>);
4490 LValue LenLVal = CGF.EmitLValueForField(
4491 Base, *std::next(KmpAffinityInfoRD->field_begin(), Len));
4492 CGF.EmitStoreOfScalar(Size, LenLVal);
4493 Idx = CGF.Builder.CreateNUWAdd(
4494 Idx, llvm::ConstantInt::get(Idx->getType(), 1));
4495 CGF.EmitStoreOfScalar(Idx, PosLVal);
4496 }
4497 }
4498 // Call to kmp_int32 __kmpc_omp_reg_task_with_affinity(ident_t *loc_ref,
4499 // kmp_int32 gtid, kmp_task_t *new_task, kmp_int32
4500 // naffins, kmp_task_affinity_info_t *affin_list);
4501 llvm::Value *LocRef = emitUpdateLocation(CGF, Loc);
4502 llvm::Value *GTid = getThreadID(CGF, Loc);
4503 llvm::Value *AffinListPtr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
4504 AffinitiesArray.getPointer(), CGM.VoidPtrTy);
4505 // FIXME: Emit the function and ignore its result for now unless the
4506 // runtime function is properly implemented.
4507 (void)CGF.EmitRuntimeCall(
4508 OMPBuilder.getOrCreateRuntimeFunction(
4509 CGM.getModule(), OMPRTL___kmpc_omp_reg_task_with_affinity),
4510 {LocRef, GTid, NewTask, NumOfElements, AffinListPtr});
4511 }
4512 llvm::Value *NewTaskNewTaskTTy =
4513 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
4514 NewTask, KmpTaskTWithPrivatesPtrTy);
4515 LValue Base = CGF.MakeNaturalAlignAddrLValue(NewTaskNewTaskTTy,
4516 KmpTaskTWithPrivatesQTy);
4517 LValue TDBase =
4518 CGF.EmitLValueForField(Base, *KmpTaskTWithPrivatesQTyRD->field_begin());
4519 // Fill the data in the resulting kmp_task_t record.
4520 // Copy shareds if there are any.
4521 Address KmpTaskSharedsPtr = Address::invalid();
4522 if (!SharedsTy->getAsStructureType()->getDecl()->field_empty()) {
4523 KmpTaskSharedsPtr =
4524 Address(CGF.EmitLoadOfScalar(
4525 CGF.EmitLValueForField(
4526 TDBase, *std::next(KmpTaskTQTyRD->field_begin(),
4527 KmpTaskTShareds)),
4528 Loc),
4529 CGM.getNaturalTypeAlignment(SharedsTy));
4530 LValue Dest = CGF.MakeAddrLValue(KmpTaskSharedsPtr, SharedsTy);
4531 LValue Src = CGF.MakeAddrLValue(Shareds, SharedsTy);
4532 CGF.EmitAggregateCopy(Dest, Src, SharedsTy, AggValueSlot::DoesNotOverlap);
4533 }
4534 // Emit initial values for private copies (if any).
4535 TaskResultTy Result;
4536 if (!Privates.empty()) {
4537 emitPrivatesInit(CGF, D, KmpTaskSharedsPtr, Base, KmpTaskTWithPrivatesQTyRD,
4538 SharedsTy, SharedsPtrTy, Data, Privates,
4539 /*ForDup=*/false);
4540 if (isOpenMPTaskLoopDirective(D.getDirectiveKind()) &&
4541 (!Data.LastprivateVars.empty() || checkInitIsRequired(CGF, Privates))) {
4542 Result.TaskDupFn = emitTaskDupFunction(
4543 CGM, Loc, D, KmpTaskTWithPrivatesPtrQTy, KmpTaskTWithPrivatesQTyRD,
4544 KmpTaskTQTyRD, SharedsTy, SharedsPtrTy, Data, Privates,
4545 /*WithLastIter=*/!Data.LastprivateVars.empty());
4546 }
4547 }
4548 // Fields of union "kmp_cmplrdata_t" for destructors and priority.
4549 enum { Priority = 0, Destructors = 1 };
4550 // Provide pointer to function with destructors for privates.
4551 auto FI = std::next(KmpTaskTQTyRD->field_begin(), Data1);
4552 const RecordDecl *KmpCmplrdataUD =
4553 (*FI)->getType()->getAsUnionType()->getDecl();
4554 if (NeedsCleanup) {
4555 llvm::Value *DestructorFn = emitDestructorsFunction(
4556 CGM, Loc, KmpInt32Ty, KmpTaskTWithPrivatesPtrQTy,
4557 KmpTaskTWithPrivatesQTy);
4558 LValue Data1LV = CGF.EmitLValueForField(TDBase, *FI);
4559 LValue DestructorsLV = CGF.EmitLValueForField(
4560 Data1LV, *std::next(KmpCmplrdataUD->field_begin(), Destructors));
4561 CGF.EmitStoreOfScalar(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
4562 DestructorFn, KmpRoutineEntryPtrTy),
4563 DestructorsLV);
4564 }
4565 // Set priority.
4566 if (Data.Priority.getInt()) {
4567 LValue Data2LV = CGF.EmitLValueForField(
4568 TDBase, *std::next(KmpTaskTQTyRD->field_begin(), Data2));
4569 LValue PriorityLV = CGF.EmitLValueForField(
4570 Data2LV, *std::next(KmpCmplrdataUD->field_begin(), Priority));
4571 CGF.EmitStoreOfScalar(Data.Priority.getPointer(), PriorityLV);
4572 }
4573 Result.NewTask = NewTask;
4574 Result.TaskEntry = TaskEntry;
4575 Result.NewTaskNewTaskTTy = NewTaskNewTaskTTy;
4576 Result.TDBase = TDBase;
4577 Result.KmpTaskTQTyRD = KmpTaskTQTyRD;
4578 return Result;
4579}
4580
4581namespace {
4582/// Dependence kind for RTL.
4583enum RTLDependenceKindTy {
4584 DepIn = 0x01,
4585 DepInOut = 0x3,
4586 DepMutexInOutSet = 0x4
4587};
4588/// Fields ids in kmp_depend_info record.
4589enum RTLDependInfoFieldsTy { BaseAddr, Len, Flags };
4590} // namespace
4591
4592/// Translates internal dependency kind into the runtime kind.
4593static RTLDependenceKindTy translateDependencyKind(OpenMPDependClauseKind K) {
4594 RTLDependenceKindTy DepKind;
4595 switch (K) {
4596 case OMPC_DEPEND_in:
4597 DepKind = DepIn;
4598 break;
4599 // Out and InOut dependencies must use the same code.
4600 case OMPC_DEPEND_out:
4601 case OMPC_DEPEND_inout:
4602 DepKind = DepInOut;
4603 break;
4604 case OMPC_DEPEND_mutexinoutset:
4605 DepKind = DepMutexInOutSet;
4606 break;
4607 case OMPC_DEPEND_source:
4608 case OMPC_DEPEND_sink:
4609 case OMPC_DEPEND_depobj:
4610 case OMPC_DEPEND_unknown:
4611 llvm_unreachable("Unknown task dependence type")__builtin_unreachable();
4612 }
4613 return DepKind;
4614}
4615
4616/// Builds kmp_depend_info, if it is not built yet, and builds flags type.
4617static void getDependTypes(ASTContext &C, QualType &KmpDependInfoTy,
4618 QualType &FlagsTy) {
4619 FlagsTy = C.getIntTypeForBitwidth(C.getTypeSize(C.BoolTy), /*Signed=*/false);
4620 if (KmpDependInfoTy.isNull()) {
4621 RecordDecl *KmpDependInfoRD = C.buildImplicitRecord("kmp_depend_info");
4622 KmpDependInfoRD->startDefinition();
4623 addFieldToRecordDecl(C, KmpDependInfoRD, C.getIntPtrType());
4624 addFieldToRecordDecl(C, KmpDependInfoRD, C.getSizeType());
4625 addFieldToRecordDecl(C, KmpDependInfoRD, FlagsTy);
4626 KmpDependInfoRD->completeDefinition();
4627 KmpDependInfoTy = C.getRecordType(KmpDependInfoRD);
4628 }
4629}
4630
4631std::pair<llvm::Value *, LValue>
4632CGOpenMPRuntime::getDepobjElements(CodeGenFunction &CGF, LValue DepobjLVal,
4633 SourceLocation Loc) {
4634 ASTContext &C = CGM.getContext();
4635 QualType FlagsTy;
4636 getDependTypes(C, KmpDependInfoTy, FlagsTy);
4637 RecordDecl *KmpDependInfoRD =
4638 cast<RecordDecl>(KmpDependInfoTy->getAsTagDecl());
4639 LValue Base = CGF.EmitLoadOfPointerLValue(
4640 DepobjLVal.getAddress(CGF),
4641 C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
4642 QualType KmpDependInfoPtrTy = C.getPointerType(KmpDependInfoTy);
4643 Address Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
4644 Base.getAddress(CGF), CGF.ConvertTypeForMem(KmpDependInfoPtrTy));
4645 Base = CGF.MakeAddrLValue(Addr, KmpDependInfoTy, Base.getBaseInfo(),
4646 Base.getTBAAInfo());
4647 llvm::Value *DepObjAddr = CGF.Builder.CreateGEP(
4648 Addr.getElementType(), Addr.getPointer(),
4649 llvm::ConstantInt::get(CGF.IntPtrTy, -1, /*isSigned=*/true));
4650 LValue NumDepsBase = CGF.MakeAddrLValue(
4651 Address(DepObjAddr, Addr.getAlignment()), KmpDependInfoTy,
4652 Base.getBaseInfo(), Base.getTBAAInfo());
4653 // NumDeps = deps[i].base_addr;
4654 LValue BaseAddrLVal = CGF.EmitLValueForField(
4655 NumDepsBase, *std::next(KmpDependInfoRD->field_begin(), BaseAddr));
4656 llvm::Value *NumDeps = CGF.EmitLoadOfScalar(BaseAddrLVal, Loc);
4657 return std::make_pair(NumDeps, Base);
4658}
4659
4660static void emitDependData(CodeGenFunction &CGF, QualType &KmpDependInfoTy,
4661 llvm::PointerUnion<unsigned *, LValue *> Pos,
4662 const OMPTaskDataTy::DependData &Data,
4663 Address DependenciesArray) {
4664 CodeGenModule &CGM = CGF.CGM;
4665 ASTContext &C = CGM.getContext();
4666 QualType FlagsTy;
4667 getDependTypes(C, KmpDependInfoTy, FlagsTy);
4668 RecordDecl *KmpDependInfoRD =
4669 cast<RecordDecl>(KmpDependInfoTy->getAsTagDecl());
4670 llvm::Type *LLVMFlagsTy = CGF.ConvertTypeForMem(FlagsTy);
4671
4672 OMPIteratorGeneratorScope IteratorScope(
4673 CGF, cast_or_null<OMPIteratorExpr>(
4674 Data.IteratorExpr ? Data.IteratorExpr->IgnoreParenImpCasts()
4675 : nullptr));
4676 for (const Expr *E : Data.DepExprs) {
4677 llvm::Value *Addr;
4678 llvm::Value *Size;
4679 std::tie(Addr, Size) = getPointerAndSize(CGF, E);
4680 LValue Base;
4681 if (unsigned *P = Pos.dyn_cast<unsigned *>()) {
4682 Base = CGF.MakeAddrLValue(
4683 CGF.Builder.CreateConstGEP(DependenciesArray, *P), KmpDependInfoTy);
4684 } else {
4685 LValue &PosLVal = *Pos.get<LValue *>();
4686 llvm::Value *Idx = CGF.EmitLoadOfScalar(PosLVal, E->getExprLoc());
4687 Base = CGF.MakeAddrLValue(
4688 Address(CGF.Builder.CreateGEP(DependenciesArray.getElementType(),
4689 DependenciesArray.getPointer(), Idx),
4690 DependenciesArray.getAlignment()),
4691 KmpDependInfoTy);
4692 }
4693 // deps[i].base_addr = &<Dependencies[i].second>;
4694 LValue BaseAddrLVal = CGF.EmitLValueForField(
4695 Base, *std::next(KmpDependInfoRD->field_begin(), BaseAddr));
4696 CGF.EmitStoreOfScalar(CGF.Builder.CreatePtrToInt(Addr, CGF.IntPtrTy),
4697 BaseAddrLVal);
4698 // deps[i].len = sizeof(<Dependencies[i].second>);
4699 LValue LenLVal = CGF.EmitLValueForField(
4700 Base, *std::next(KmpDependInfoRD->field_begin(), Len));
4701 CGF.EmitStoreOfScalar(Size, LenLVal);
4702 // deps[i].flags = <Dependencies[i].first>;
4703 RTLDependenceKindTy DepKind = translateDependencyKind(Data.DepKind);
4704 LValue FlagsLVal = CGF.EmitLValueForField(
4705 Base, *std::next(KmpDependInfoRD->field_begin(), Flags));
4706 CGF.EmitStoreOfScalar(llvm::ConstantInt::get(LLVMFlagsTy, DepKind),
4707 FlagsLVal);
4708 if (unsigned *P = Pos.dyn_cast<unsigned *>()) {
4709 ++(*P);
4710 } else {
4711 LValue &PosLVal = *Pos.get<LValue *>();
4712 llvm::Value *Idx = CGF.EmitLoadOfScalar(PosLVal, E->getExprLoc());
4713 Idx = CGF.Builder.CreateNUWAdd(Idx,
4714 llvm::ConstantInt::get(Idx->getType(), 1));
4715 CGF.EmitStoreOfScalar(Idx, PosLVal);
4716 }
4717 }
4718}
4719
4720static SmallVector<llvm::Value *, 4>
4721emitDepobjElementsSizes(CodeGenFunction &CGF, QualType &KmpDependInfoTy,
4722 const OMPTaskDataTy::DependData &Data) {
4723 assert(Data.DepKind == OMPC_DEPEND_depobj &&(static_cast<void> (0))
4724 "Expected depobj dependecy kind.")(static_cast<void> (0));
4725 SmallVector<llvm::Value *, 4> Sizes;
4726 SmallVector<LValue, 4> SizeLVals;
4727 ASTContext &C = CGF.getContext();
4728 QualType FlagsTy;
4729 getDependTypes(C, KmpDependInfoTy, FlagsTy);
4730 RecordDecl *KmpDependInfoRD =
4731 cast<RecordDecl>(KmpDependInfoTy->getAsTagDecl());
4732 QualType KmpDependInfoPtrTy = C.getPointerType(KmpDependInfoTy);
4733 llvm::Type *KmpDependInfoPtrT = CGF.ConvertTypeForMem(KmpDependInfoPtrTy);
4734 {
4735 OMPIteratorGeneratorScope IteratorScope(
4736 CGF, cast_or_null<OMPIteratorExpr>(
4737 Data.IteratorExpr ? Data.IteratorExpr->IgnoreParenImpCasts()
4738 : nullptr));
4739 for (const Expr *E : Data.DepExprs) {
4740 LValue DepobjLVal = CGF.EmitLValue(E->IgnoreParenImpCasts());
4741 LValue Base = CGF.EmitLoadOfPointerLValue(
4742 DepobjLVal.getAddress(CGF),
4743 C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
4744 Address Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
4745 Base.getAddress(CGF), KmpDependInfoPtrT);
4746 Base = CGF.MakeAddrLValue(Addr, KmpDependInfoTy, Base.getBaseInfo(),
4747 Base.getTBAAInfo());
4748 llvm::Value *DepObjAddr = CGF.Builder.CreateGEP(
4749 Addr.getElementType(), Addr.getPointer(),
4750 llvm::ConstantInt::get(CGF.IntPtrTy, -1, /*isSigned=*/true));
4751 LValue NumDepsBase = CGF.MakeAddrLValue(
4752 Address(DepObjAddr, Addr.getAlignment()), KmpDependInfoTy,
4753 Base.getBaseInfo(), Base.getTBAAInfo());
4754 // NumDeps = deps[i].base_addr;
4755 LValue BaseAddrLVal = CGF.EmitLValueForField(
4756 NumDepsBase, *std::next(KmpDependInfoRD->field_begin(), BaseAddr));
4757 llvm::Value *NumDeps =
4758 CGF.EmitLoadOfScalar(BaseAddrLVal, E->getExprLoc());
4759 LValue NumLVal = CGF.MakeAddrLValue(
4760 CGF.CreateMemTemp(C.getUIntPtrType(), "depobj.size.addr"),
4761 C.getUIntPtrType());
4762 CGF.InitTempAlloca(NumLVal.getAddress(CGF),
4763 llvm::ConstantInt::get(CGF.IntPtrTy, 0));
4764 llvm::Value *PrevVal = CGF.EmitLoadOfScalar(NumLVal, E->getExprLoc());
4765 llvm::Value *Add = CGF.Builder.CreateNUWAdd(PrevVal, NumDeps);
4766 CGF.EmitStoreOfScalar(Add, NumLVal);
4767 SizeLVals.push_back(NumLVal);
4768 }
4769 }
4770 for (unsigned I = 0, E = SizeLVals.size(); I < E; ++I) {
4771 llvm::Value *Size =
4772 CGF.EmitLoadOfScalar(SizeLVals[I], Data.DepExprs[I]->getExprLoc());
4773 Sizes.push_back(Size);
4774 }
4775 return Sizes;
4776}
4777
4778static void emitDepobjElements(CodeGenFunction &CGF, QualType &KmpDependInfoTy,
4779 LValue PosLVal,
4780 const OMPTaskDataTy::DependData &Data,
4781 Address DependenciesArray) {
4782 assert(Data.DepKind == OMPC_DEPEND_depobj &&(static_cast<void> (0))
4783 "Expected depobj dependecy kind.")(static_cast<void> (0));
4784 ASTContext &C = CGF.getContext();
4785 QualType FlagsTy;
4786 getDependTypes(C, KmpDependInfoTy, FlagsTy);
4787 RecordDecl *KmpDependInfoRD =
4788 cast<RecordDecl>(KmpDependInfoTy->getAsTagDecl());
4789 QualType KmpDependInfoPtrTy = C.getPointerType(KmpDependInfoTy);
4790 llvm::Type *KmpDependInfoPtrT = CGF.ConvertTypeForMem(KmpDependInfoPtrTy);
4791 llvm::Value *ElSize = CGF.getTypeSize(KmpDependInfoTy);
4792 {
4793 OMPIteratorGeneratorScope IteratorScope(
4794 CGF, cast_or_null<OMPIteratorExpr>(
4795 Data.IteratorExpr ? Data.IteratorExpr->IgnoreParenImpCasts()
4796 : nullptr));
4797 for (unsigned I = 0, End = Data.DepExprs.size(); I < End; ++I) {
4798 const Expr *E = Data.DepExprs[I];
4799 LValue DepobjLVal = CGF.EmitLValue(E->IgnoreParenImpCasts());
4800 LValue Base = CGF.EmitLoadOfPointerLValue(
4801 DepobjLVal.getAddress(CGF),
4802 C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
4803 Address Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
4804 Base.getAddress(CGF), KmpDependInfoPtrT);
4805 Base = CGF.MakeAddrLValue(Addr, KmpDependInfoTy, Base.getBaseInfo(),
4806 Base.getTBAAInfo());
4807
4808 // Get number of elements in a single depobj.
4809 llvm::Value *DepObjAddr = CGF.Builder.CreateGEP(
4810 Addr.getElementType(), Addr.getPointer(),
4811 llvm::ConstantInt::get(CGF.IntPtrTy, -1, /*isSigned=*/true));
4812 LValue NumDepsBase = CGF.MakeAddrLValue(
4813 Address(DepObjAddr, Addr.getAlignment()), KmpDependInfoTy,
4814 Base.getBaseInfo(), Base.getTBAAInfo());
4815 // NumDeps = deps[i].base_addr;
4816 LValue BaseAddrLVal = CGF.EmitLValueForField(
4817 NumDepsBase, *std::next(KmpDependInfoRD->field_begin(), BaseAddr));
4818 llvm::Value *NumDeps =
4819 CGF.EmitLoadOfScalar(BaseAddrLVal, E->getExprLoc());
4820
4821 // memcopy dependency data.
4822 llvm::Value *Size = CGF.Builder.CreateNUWMul(
4823 ElSize,
4824 CGF.Builder.CreateIntCast(NumDeps, CGF.SizeTy, /*isSigned=*/false));
4825 llvm::Value *Pos = CGF.EmitLoadOfScalar(PosLVal, E->getExprLoc());
4826 Address DepAddr =
4827 Address(CGF.Builder.CreateGEP(DependenciesArray.getElementType(),
4828 DependenciesArray.getPointer(), Pos),
4829 DependenciesArray.getAlignment());
4830 CGF.Builder.CreateMemCpy(DepAddr, Base.getAddress(CGF), Size);
4831
4832 // Increase pos.
4833 // pos += size;
4834 llvm::Value *Add = CGF.Builder.CreateNUWAdd(Pos, NumDeps);
4835 CGF.EmitStoreOfScalar(Add, PosLVal);
4836 }
4837 }
4838}
4839
4840std::pair<llvm::Value *, Address> CGOpenMPRuntime::emitDependClause(
4841 CodeGenFunction &CGF, ArrayRef<OMPTaskDataTy::DependData> Dependencies,
4842 SourceLocation Loc) {
4843 if (llvm::all_of(Dependencies, [](const OMPTaskDataTy::DependData &D) {
4844 return D.DepExprs.empty();
4845 }))
4846 return std::make_pair(nullptr, Address::invalid());
4847 // Process list of dependencies.
4848 ASTContext &C = CGM.getContext();
4849 Address DependenciesArray = Address::invalid();
4850 llvm::Value *NumOfElements = nullptr;
4851 unsigned NumDependencies = std::accumulate(
4852 Dependencies.begin(), Dependencies.end(), 0,
4853 [](unsigned V, const OMPTaskDataTy::DependData &D) {
4854 return D.DepKind == OMPC_DEPEND_depobj
4855 ? V
4856 : (V + (D.IteratorExpr ? 0 : D.DepExprs.size()));
4857 });
4858 QualType FlagsTy;
4859 getDependTypes(C, KmpDependInfoTy, FlagsTy);
4860 bool HasDepobjDeps = false;
4861 bool HasRegularWithIterators = false;
4862 llvm::Value *NumOfDepobjElements = llvm::ConstantInt::get(CGF.IntPtrTy, 0);
4863 llvm::Value *NumOfRegularWithIterators =
4864 llvm::ConstantInt::get(CGF.IntPtrTy, 1);
4865 // Calculate number of depobj dependecies and regular deps with the iterators.
4866 for (const OMPTaskDataTy::DependData &D : Dependencies) {
4867 if (D.DepKind == OMPC_DEPEND_depobj) {
4868 SmallVector<llvm::Value *, 4> Sizes =
4869 emitDepobjElementsSizes(CGF, KmpDependInfoTy, D);
4870 for (llvm::Value *Size : Sizes) {
4871 NumOfDepobjElements =
4872 CGF.Builder.CreateNUWAdd(NumOfDepobjElements, Size);
4873 }
4874 HasDepobjDeps = true;
4875 continue;
4876 }
4877 // Include number of iterations, if any.
4878 if (const auto *IE = cast_or_null<OMPIteratorExpr>(D.IteratorExpr)) {
4879 for (unsigned I = 0, E = IE->numOfIterators(); I < E; ++I) {
4880 llvm::Value *Sz = CGF.EmitScalarExpr(IE->getHelper(I).Upper);
4881 Sz = CGF.Builder.CreateIntCast(Sz, CGF.IntPtrTy, /*isSigned=*/false);
4882 NumOfRegularWithIterators =
4883 CGF.Builder.CreateNUWMul(NumOfRegularWithIterators, Sz);
4884 }
4885 HasRegularWithIterators = true;
4886 continue;
4887 }
4888 }
4889
4890 QualType KmpDependInfoArrayTy;
4891 if (HasDepobjDeps || HasRegularWithIterators) {
4892 NumOfElements = llvm::ConstantInt::get(CGM.IntPtrTy, NumDependencies,
4893 /*isSigned=*/false);
4894 if (HasDepobjDeps) {
4895 NumOfElements =
4896 CGF.Builder.CreateNUWAdd(NumOfDepobjElements, NumOfElements);
4897 }
4898 if (HasRegularWithIterators) {
4899 NumOfElements =
4900 CGF.Builder.CreateNUWAdd(NumOfRegularWithIterators, NumOfElements);
4901 }
4902 auto *OVE = new (C) OpaqueValueExpr(
4903 Loc, C.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0),
4904 VK_PRValue);
4905 CodeGenFunction::OpaqueValueMapping OpaqueMap(CGF, OVE,
4906 RValue::get(NumOfElements));
4907 KmpDependInfoArrayTy =
4908 C.getVariableArrayType(KmpDependInfoTy, OVE, ArrayType::Normal,
4909 /*IndexTypeQuals=*/0, SourceRange(Loc, Loc));
4910 // CGF.EmitVariablyModifiedType(KmpDependInfoArrayTy);
4911 // Properly emit variable-sized array.
4912 auto *PD = ImplicitParamDecl::Create(C, KmpDependInfoArrayTy,
4913 ImplicitParamDecl::Other);
4914 CGF.EmitVarDecl(*PD);
4915 DependenciesArray = CGF.GetAddrOfLocalVar(PD);
4916 NumOfElements = CGF.Builder.CreateIntCast(NumOfElements, CGF.Int32Ty,
4917 /*isSigned=*/false);
4918 } else {
4919 KmpDependInfoArrayTy = C.getConstantArrayType(
4920 KmpDependInfoTy, llvm::APInt(/*numBits=*/64, NumDependencies), nullptr,
4921 ArrayType::Normal, /*IndexTypeQuals=*/0);
4922 DependenciesArray =
4923 CGF.CreateMemTemp(KmpDependInfoArrayTy, ".dep.arr.addr");
4924 DependenciesArray = CGF.Builder.CreateConstArrayGEP(DependenciesArray, 0);
4925 NumOfElements = llvm::ConstantInt::get(CGM.Int32Ty, NumDependencies,
4926 /*isSigned=*/false);
4927 }
4928 unsigned Pos = 0;
4929 for (unsigned I = 0, End = Dependencies.size(); I < End; ++I) {
4930 if (Dependencies[I].DepKind == OMPC_DEPEND_depobj ||
4931 Dependencies[I].IteratorExpr)
4932 continue;
4933 emitDependData(CGF, KmpDependInfoTy, &Pos, Dependencies[I],
4934 DependenciesArray);
4935 }
4936 // Copy regular dependecies with iterators.
4937 LValue PosLVal = CGF.MakeAddrLValue(
4938 CGF.CreateMemTemp(C.getSizeType(), "dep.counter.addr"), C.getSizeType());
4939 CGF.EmitStoreOfScalar(llvm::ConstantInt::get(CGF.SizeTy, Pos), PosLVal);
4940 for (unsigned I = 0, End = Dependencies.size(); I < End; ++I) {
4941 if (Dependencies[I].DepKind == OMPC_DEPEND_depobj ||
4942 !Dependencies[I].IteratorExpr)
4943 continue;
4944 emitDependData(CGF, KmpDependInfoTy, &PosLVal, Dependencies[I],
4945 DependenciesArray);
4946 }
4947 // Copy final depobj arrays without iterators.
4948 if (HasDepobjDeps) {
4949 for (unsigned I = 0, End = Dependencies.size(); I < End; ++I) {
4950 if (Dependencies[I].DepKind != OMPC_DEPEND_depobj)
4951 continue;
4952 emitDepobjElements(CGF, KmpDependInfoTy, PosLVal, Dependencies[I],
4953 DependenciesArray);
4954 }
4955 }
4956 DependenciesArray = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
4957 DependenciesArray, CGF.VoidPtrTy);
4958 return std::make_pair(NumOfElements, DependenciesArray);
4959}
4960
4961Address CGOpenMPRuntime::emitDepobjDependClause(
4962 CodeGenFunction &CGF, const OMPTaskDataTy::DependData &Dependencies,
4963 SourceLocation Loc) {
4964 if (Dependencies.DepExprs.empty())
4965 return Address::invalid();
4966 // Process list of dependencies.
4967 ASTContext &C = CGM.getContext();
4968 Address DependenciesArray = Address::invalid();
4969 unsigned NumDependencies = Dependencies.DepExprs.size();
4970 QualType FlagsTy;
4971 getDependTypes(C, KmpDependInfoTy, FlagsTy);
4972 RecordDecl *KmpDependInfoRD =
4973 cast<RecordDecl>(KmpDependInfoTy->getAsTagDecl());
4974
4975 llvm::Value *Size;
4976 // Define type kmp_depend_info[<Dependencies.size()>];
4977 // For depobj reserve one extra element to store the number of elements.
4978 // It is required to handle depobj(x) update(in) construct.
4979 // kmp_depend_info[<Dependencies.size()>] deps;
4980 llvm::Value *NumDepsVal;
4981 CharUnits Align = C.getTypeAlignInChars(KmpDependInfoTy);
4982 if (const auto *IE =
4983 cast_or_null<OMPIteratorExpr>(Dependencies.IteratorExpr)) {
4984 NumDepsVal = llvm::ConstantInt::get(CGF.SizeTy, 1);
4985 for (unsigned I = 0, E = IE->numOfIterators(); I < E; ++I) {
4986 llvm::Value *Sz = CGF.EmitScalarExpr(IE->getHelper(I).Upper);
4987 Sz = CGF.Builder.CreateIntCast(Sz, CGF.SizeTy, /*isSigned=*/false);
4988 NumDepsVal = CGF.Builder.CreateNUWMul(NumDepsVal, Sz);
4989 }
4990 Size = CGF.Builder.CreateNUWAdd(llvm::ConstantInt::get(CGF.SizeTy, 1),
4991 NumDepsVal);
4992 CharUnits SizeInBytes =
4993 C.getTypeSizeInChars(KmpDependInfoTy).alignTo(Align);
4994 llvm::Value *RecSize = CGM.getSize(SizeInBytes);
4995 Size = CGF.Builder.CreateNUWMul(Size, RecSize);
4996 NumDepsVal =
4997 CGF.Builder.CreateIntCast(NumDepsVal, CGF.IntPtrTy, /*isSigned=*/false);
4998 } else {
4999 QualType KmpDependInfoArrayTy = C.getConstantArrayType(
5000 KmpDependInfoTy, llvm::APInt(/*numBits=*/64, NumDependencies + 1),
5001 nullptr, ArrayType::Normal, /*IndexTypeQuals=*/0);
5002 CharUnits Sz = C.getTypeSizeInChars(KmpDependInfoArrayTy);
5003 Size = CGM.getSize(Sz.alignTo(Align));
5004 NumDepsVal = llvm::ConstantInt::get(CGF.IntPtrTy, NumDependencies);
5005 }
5006 // Need to allocate on the dynamic memory.
5007 llvm::Value *ThreadID = getThreadID(CGF, Loc);
5008 // Use default allocator.
5009 llvm::Value *Allocator = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
5010 llvm::Value *Args[] = {ThreadID, Size, Allocator};
5011
5012 llvm::Value *Addr =
5013 CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
5014 CGM.getModule(), OMPRTL___kmpc_alloc),
5015 Args, ".dep.arr.addr");
5016 Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5017 Addr, CGF.ConvertTypeForMem(KmpDependInfoTy)->getPointerTo());
5018 DependenciesArray = Address(Addr, Align);
5019 // Write number of elements in the first element of array for depobj.
5020 LValue Base = CGF.MakeAddrLValue(DependenciesArray, KmpDependInfoTy);
5021 // deps[i].base_addr = NumDependencies;
5022 LValue BaseAddrLVal = CGF.EmitLValueForField(
5023 Base, *std::next(KmpDependInfoRD->field_begin(), BaseAddr));
5024 CGF.EmitStoreOfScalar(NumDepsVal, BaseAddrLVal);
5025 llvm::PointerUnion<unsigned *, LValue *> Pos;
5026 unsigned Idx = 1;
5027 LValue PosLVal;
5028 if (Dependencies.IteratorExpr) {
5029 PosLVal = CGF.MakeAddrLValue(
5030 CGF.CreateMemTemp(C.getSizeType(), "iterator.counter.addr"),
5031 C.getSizeType());
5032 CGF.EmitStoreOfScalar(llvm::ConstantInt::get(CGF.SizeTy, Idx), PosLVal,
5033 /*IsInit=*/true);
5034 Pos = &PosLVal;
5035 } else {
5036 Pos = &Idx;
5037 }
5038 emitDependData(CGF, KmpDependInfoTy, Pos, Dependencies, DependenciesArray);
5039 DependenciesArray = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5040 CGF.Builder.CreateConstGEP(DependenciesArray, 1), CGF.VoidPtrTy);
5041 return DependenciesArray;
5042}
5043
5044void CGOpenMPRuntime::emitDestroyClause(CodeGenFunction &CGF, LValue DepobjLVal,
5045 SourceLocation Loc) {
5046 ASTContext &C = CGM.getContext();
5047 QualType FlagsTy;
5048 getDependTypes(C, KmpDependInfoTy, FlagsTy);
5049 LValue Base = CGF.EmitLoadOfPointerLValue(
5050 DepobjLVal.getAddress(CGF),
5051 C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
5052 QualType KmpDependInfoPtrTy = C.getPointerType(KmpDependInfoTy);
5053 Address Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5054 Base.getAddress(CGF), CGF.ConvertTypeForMem(KmpDependInfoPtrTy));
5055 llvm::Value *DepObjAddr = CGF.Builder.CreateGEP(
5056 Addr.getElementType(), Addr.getPointer(),
5057 llvm::ConstantInt::get(CGF.IntPtrTy, -1, /*isSigned=*/true));
5058 DepObjAddr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(DepObjAddr,
5059 CGF.VoidPtrTy);
5060 llvm::Value *ThreadID = getThreadID(CGF, Loc);
5061 // Use default allocator.
5062 llvm::Value *Allocator = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
5063 llvm::Value *Args[] = {ThreadID, DepObjAddr, Allocator};
5064
5065 // _kmpc_free(gtid, addr, nullptr);
5066 (void)CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
5067 CGM.getModule(), OMPRTL___kmpc_free),
5068 Args);
5069}
5070
5071void CGOpenMPRuntime::emitUpdateClause(CodeGenFunction &CGF, LValue DepobjLVal,
5072 OpenMPDependClauseKind NewDepKind,
5073 SourceLocation Loc) {
5074 ASTContext &C = CGM.getContext();
5075 QualType FlagsTy;
5076 getDependTypes(C, KmpDependInfoTy, FlagsTy);
5077 RecordDecl *KmpDependInfoRD =
5078 cast<RecordDecl>(KmpDependInfoTy->getAsTagDecl());
5079 llvm::Type *LLVMFlagsTy = CGF.ConvertTypeForMem(FlagsTy);
5080 llvm::Value *NumDeps;
5081 LValue Base;
5082 std::tie(NumDeps, Base) = getDepobjElements(CGF, DepobjLVal, Loc);
5083
5084 Address Begin = Base.getAddress(CGF);
5085 // Cast from pointer to array type to pointer to single element.
5086 llvm::Value *End = CGF.Builder.CreateGEP(
5087 Begin.getElementType(), Begin.getPointer(), NumDeps);
5088 // The basic structure here is a while-do loop.
5089 llvm::BasicBlock *BodyBB = CGF.createBasicBlock("omp.body");
5090 llvm::BasicBlock *DoneBB = CGF.createBasicBlock("omp.done");
5091 llvm::BasicBlock *EntryBB = CGF.Builder.GetInsertBlock();
5092 CGF.EmitBlock(BodyBB);
5093 llvm::PHINode *ElementPHI =
5094 CGF.Builder.CreatePHI(Begin.getType(), 2, "omp.elementPast");
5095 ElementPHI->addIncoming(Begin.getPointer(), EntryBB);
5096 Begin = Address(ElementPHI, Begin.getAlignment());
5097 Base = CGF.MakeAddrLValue(Begin, KmpDependInfoTy, Base.getBaseInfo(),
5098 Base.getTBAAInfo());
5099 // deps[i].flags = NewDepKind;
5100 RTLDependenceKindTy DepKind = translateDependencyKind(NewDepKind);
5101 LValue FlagsLVal = CGF.EmitLValueForField(
5102 Base, *std::next(KmpDependInfoRD->field_begin(), Flags));
5103 CGF.EmitStoreOfScalar(llvm::ConstantInt::get(LLVMFlagsTy, DepKind),
5104 FlagsLVal);
5105
5106 // Shift the address forward by one element.
5107 Address ElementNext =
5108 CGF.Builder.CreateConstGEP(Begin, /*Index=*/1, "omp.elementNext");
5109 ElementPHI->addIncoming(ElementNext.getPointer(),
5110 CGF.Builder.GetInsertBlock());
5111 llvm::Value *IsEmpty =
5112 CGF.Builder.CreateICmpEQ(ElementNext.getPointer(), End, "omp.isempty");
5113 CGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
5114 // Done.
5115 CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
5116}
5117
5118void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
5119 const OMPExecutableDirective &D,
5120 llvm::Function *TaskFunction,
5121 QualType SharedsTy, Address Shareds,
5122 const Expr *IfCond,
5123 const OMPTaskDataTy &Data) {
5124 if (!CGF.HaveInsertPoint())
5125 return;
5126
5127 TaskResultTy Result =
5128 emitTaskInit(CGF, Loc, D, TaskFunction, SharedsTy, Shareds, Data);
5129 llvm::Value *NewTask = Result.NewTask;
5130 llvm::Function *TaskEntry = Result.TaskEntry;
5131 llvm::Value *NewTaskNewTaskTTy = Result.NewTaskNewTaskTTy;
5132 LValue TDBase = Result.TDBase;
5133 const RecordDecl *KmpTaskTQTyRD = Result.KmpTaskTQTyRD;
5134 // Process list of dependences.
5135 Address DependenciesArray = Address::invalid();
5136 llvm::Value *NumOfElements;
5137 std::tie(NumOfElements, DependenciesArray) =
5138 emitDependClause(CGF, Data.Dependences, Loc);
5139
5140 // NOTE: routine and part_id fields are initialized by __kmpc_omp_task_alloc()
5141 // libcall.
5142 // Build kmp_int32 __kmpc_omp_task_with_deps(ident_t *, kmp_int32 gtid,
5143 // kmp_task_t *new_task, kmp_int32 ndeps, kmp_depend_info_t *dep_list,
5144 // kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list) if dependence
5145 // list is not empty
5146 llvm::Value *ThreadID = getThreadID(CGF, Loc);
5147 llvm::Value *UpLoc = emitUpdateLocation(CGF, Loc);
5148 llvm::Value *TaskArgs[] = { UpLoc, ThreadID, NewTask };
5149 llvm::Value *DepTaskArgs[7];
5150 if (!Data.Dependences.empty()) {
5151 DepTaskArgs[0] = UpLoc;
5152 DepTaskArgs[1] = ThreadID;
5153 DepTaskArgs[2] = NewTask;
5154 DepTaskArgs[3] = NumOfElements;
5155 DepTaskArgs[4] = DependenciesArray.getPointer();
5156 DepTaskArgs[5] = CGF.Builder.getInt32(0);
5157 DepTaskArgs[6] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
5158 }
5159 auto &&ThenCodeGen = [this, &Data, TDBase, KmpTaskTQTyRD, &TaskArgs,
5160 &DepTaskArgs](CodeGenFunction &CGF, PrePostActionTy &) {
5161 if (!Data.Tied) {
5162 auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
5163 LValue PartIdLVal = CGF.EmitLValueForField(TDBase, *PartIdFI);
5164 CGF.EmitStoreOfScalar(CGF.Builder.getInt32(0), PartIdLVal);
5165 }
5166 if (!Data.Dependences.empty()) {
5167 CGF.EmitRuntimeCall(
5168 OMPBuilder.getOrCreateRuntimeFunction(
5169 CGM.getModule(), OMPRTL___kmpc_omp_task_with_deps),
5170 DepTaskArgs);
5171 } else {
5172 CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
5173 CGM.getModule(), OMPRTL___kmpc_omp_task),
5174 TaskArgs);
5175 }
5176 // Check if parent region is untied and build return for untied task;
5177 if (auto *Region =
5178 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
5179 Region->emitUntiedSwitch(CGF);
5180 };
5181
5182 llvm::Value *DepWaitTaskArgs[6];
5183 if (!Data.Dependences.empty()) {
5184 DepWaitTaskArgs[0] = UpLoc;
5185 DepWaitTaskArgs[1] = ThreadID;
5186 DepWaitTaskArgs[2] = NumOfElements;
5187 DepWaitTaskArgs[3] = DependenciesArray.getPointer();
5188 DepWaitTaskArgs[4] = CGF.Builder.getInt32(0);
5189 DepWaitTaskArgs[5] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
5190 }
5191 auto &M = CGM.getModule();
5192 auto &&ElseCodeGen = [this, &M, &TaskArgs, ThreadID, NewTaskNewTaskTTy,
5193 TaskEntry, &Data, &DepWaitTaskArgs,
5194 Loc](CodeGenFunction &CGF, PrePostActionTy &) {
5195 CodeGenFunction::RunCleanupsScope LocalScope(CGF);
5196 // Build void __kmpc_omp_wait_deps(ident_t *, kmp_int32 gtid,
5197 // kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32
5198 // ndeps_noalias, kmp_depend_info_t *noalias_dep_list); if dependence info
5199 // is specified.
5200 if (!Data.Dependences.empty())
5201 CGF.EmitRuntimeCall(
5202 OMPBuilder.getOrCreateRuntimeFunction(M, OMPRTL___kmpc_omp_wait_deps),
5203 DepWaitTaskArgs);
5204 // Call proxy_task_entry(gtid, new_task);
5205 auto &&CodeGen = [TaskEntry, ThreadID, NewTaskNewTaskTTy,
5206 Loc](CodeGenFunction &CGF, PrePostActionTy &Action) {
5207 Action.Enter(CGF);
5208 llvm::Value *OutlinedFnArgs[] = {ThreadID, NewTaskNewTaskTTy};
5209 CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, Loc, TaskEntry,
5210 OutlinedFnArgs);
5211 };
5212
5213 // Build void __kmpc_omp_task_begin_if0(ident_t *, kmp_int32 gtid,
5214 // kmp_task_t *new_task);
5215 // Build void __kmpc_omp_task_complete_if0(ident_t *, kmp_int32 gtid,
5216 // kmp_task_t *new_task);
5217 RegionCodeGenTy RCG(CodeGen);
5218 CommonActionTy Action(OMPBuilder.getOrCreateRuntimeFunction(
5219 M, OMPRTL___kmpc_omp_task_begin_if0),
5220 TaskArgs,
5221 OMPBuilder.getOrCreateRuntimeFunction(
5222 M, OMPRTL___kmpc_omp_task_complete_if0),
5223 TaskArgs);
5224 RCG.setAction(Action);
5225 RCG(CGF);
5226 };
5227
5228 if (IfCond) {
5229 emitIfClause(CGF, IfCond, ThenCodeGen, ElseCodeGen);
5230 } else {
5231 RegionCodeGenTy ThenRCG(ThenCodeGen);
5232 ThenRCG(CGF);
5233 }
5234}
5235
5236void CGOpenMPRuntime::emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc,
5237 const OMPLoopDirective &D,
5238 llvm::Function *TaskFunction,
5239 QualType SharedsTy, Address Shareds,
5240 const Expr *IfCond,
5241 const OMPTaskDataTy &Data) {
5242 if (!CGF.HaveInsertPoint())
5243 return;
5244 TaskResultTy Result =
5245 emitTaskInit(CGF, Loc, D, TaskFunction, SharedsTy, Shareds, Data);
5246 // NOTE: routine and part_id fields are initialized by __kmpc_omp_task_alloc()
5247 // libcall.
5248 // Call to void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t *task, int
5249 // if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int nogroup, int
5250 // sched, kmp_uint64 grainsize, void *task_dup);
5251 llvm::Value *ThreadID = getThreadID(CGF, Loc);
5252 llvm::Value *UpLoc = emitUpdateLocation(CGF, Loc);
5253 llvm::Value *IfVal;
5254 if (IfCond) {
5255 IfVal = CGF.Builder.CreateIntCast(CGF.EvaluateExprAsBool(IfCond), CGF.IntTy,
5256 /*isSigned=*/true);
5257 } else {
5258 IfVal = llvm::ConstantInt::getSigned(CGF.IntTy, /*V=*/1);
5259 }
5260
5261 LValue LBLVal = CGF.EmitLValueForField(
5262 Result.TDBase,
5263 *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTLowerBound));
5264 const auto *LBVar =
5265 cast<VarDecl>(cast<DeclRefExpr>(D.getLowerBoundVariable())->getDecl());
5266 CGF.EmitAnyExprToMem(LBVar->getInit(), LBLVal.getAddress(CGF),
5267 LBLVal.getQuals(),
5268 /*IsInitializer=*/true);
5269 LValue UBLVal = CGF.EmitLValueForField(
5270 Result.TDBase,
5271 *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTUpperBound));
5272 const auto *UBVar =
5273 cast<VarDecl>(cast<DeclRefExpr>(D.getUpperBoundVariable())->getDecl());
5274 CGF.EmitAnyExprToMem(UBVar->getInit(), UBLVal.getAddress(CGF),
5275 UBLVal.getQuals(),
5276 /*IsInitializer=*/true);
5277 LValue StLVal = CGF.EmitLValueForField(
5278 Result.TDBase,
5279 *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTStride));
5280 const auto *StVar =
5281 cast<VarDecl>(cast<DeclRefExpr>(D.getStrideVariable())->getDecl());
5282 CGF.EmitAnyExprToMem(StVar->getInit(), StLVal.getAddress(CGF),
5283 StLVal.getQuals(),
5284 /*IsInitializer=*/true);
5285 // Store reductions address.
5286 LValue RedLVal = CGF.EmitLValueForField(
5287 Result.TDBase,
5288 *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTReductions));
5289 if (Data.Reductions) {
5290 CGF.EmitStoreOfScalar(Data.Reductions, RedLVal);
5291 } else {
5292 CGF.EmitNullInitialization(RedLVal.getAddress(CGF),
5293 CGF.getContext().VoidPtrTy);
5294 }
5295 enum { NoSchedule = 0, Grainsize = 1, NumTasks = 2 };
5296 llvm::Value *TaskArgs[] = {
5297 UpLoc,
5298 ThreadID,
5299 Result.NewTask,
5300 IfVal,
5301 LBLVal.getPointer(CGF),
5302 UBLVal.getPointer(CGF),
5303 CGF.EmitLoadOfScalar(StLVal, Loc),
5304 llvm::ConstantInt::getSigned(
5305 CGF.IntTy, 1), // Always 1 because taskgroup emitted by the compiler
5306 llvm::ConstantInt::getSigned(
5307 CGF.IntTy, Data.Schedule.getPointer()
5308 ? Data.Schedule.getInt() ? NumTasks : Grainsize
5309 : NoSchedule),
5310 Data.Schedule.getPointer()
5311 ? CGF.Builder.CreateIntCast(Data.Schedule.getPointer(), CGF.Int64Ty,
5312 /*isSigned=*/false)
5313 : llvm::ConstantInt::get(CGF.Int64Ty, /*V=*/0),
5314 Result.TaskDupFn ? CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5315 Result.TaskDupFn, CGF.VoidPtrTy)
5316 : llvm::ConstantPointerNull::get(CGF.VoidPtrTy)};
5317 CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
5318 CGM.getModule(), OMPRTL___kmpc_taskloop),
5319 TaskArgs);
5320}
5321
5322/// Emit reduction operation for each element of array (required for
5323/// array sections) LHS op = RHS.
5324/// \param Type Type of array.
5325/// \param LHSVar Variable on the left side of the reduction operation
5326/// (references element of array in original variable).
5327/// \param RHSVar Variable on the right side of the reduction operation
5328/// (references element of array in original variable).
5329/// \param RedOpGen Generator of reduction operation with use of LHSVar and
5330/// RHSVar.
5331static void EmitOMPAggregateReduction(
5332 CodeGenFunction &CGF, QualType Type, const VarDecl *LHSVar,
5333 const VarDecl *RHSVar,
5334 const llvm::function_ref<void(CodeGenFunction &CGF, const Expr *,
5335 const Expr *, const Expr *)> &RedOpGen,
5336 const Expr *XExpr = nullptr, const Expr *EExpr = nullptr,
5337 const Expr *UpExpr = nullptr) {
5338 // Perform element-by-element initialization.
5339 QualType ElementTy;
5340 Address LHSAddr = CGF.GetAddrOfLocalVar(LHSVar);
5341 Address RHSAddr = CGF.GetAddrOfLocalVar(RHSVar);
5342
5343 // Drill down to the base element type on both arrays.
5344 const ArrayType *ArrayTy = Type->getAsArrayTypeUnsafe();
5345 llvm::Value *NumElements = CGF.emitArrayLength(ArrayTy, ElementTy, LHSAddr);
5346
5347 llvm::Value *RHSBegin = RHSAddr.getPointer();
5348 llvm::Value *LHSBegin = LHSAddr.getPointer();
5349 // Cast from pointer to array type to pointer to single element.
5350 llvm::Value *LHSEnd =
5351 CGF.Builder.CreateGEP(LHSAddr.getElementType(), LHSBegin, NumElements);
5352 // The basic structure here is a while-do loop.
5353 llvm::BasicBlock *BodyBB = CGF.createBasicBlock("omp.arraycpy.body");
5354 llvm::BasicBlock *DoneBB = CGF.createBasicBlock("omp.arraycpy.done");
5355 llvm::Value *IsEmpty =
5356 CGF.Builder.CreateICmpEQ(LHSBegin, LHSEnd, "omp.arraycpy.isempty");
5357 CGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
5358
5359 // Enter the loop body, making that address the current address.
5360 llvm::BasicBlock *EntryBB = CGF.Builder.GetInsertBlock();
5361 CGF.EmitBlock(BodyBB);
5362
5363 CharUnits ElementSize = CGF.getContext().getTypeSizeInChars(ElementTy);
5364
5365 llvm::PHINode *RHSElementPHI = CGF.Builder.CreatePHI(
5366 RHSBegin->getType(), 2, "omp.arraycpy.srcElementPast");
5367 RHSElementPHI->addIncoming(RHSBegin, EntryBB);
5368 Address RHSElementCurrent =
5369 Address(RHSElementPHI,
5370 RHSAddr.getAlignment().alignmentOfArrayElement(ElementSize));
5371
5372 llvm::PHINode *LHSElementPHI = CGF.Builder.CreatePHI(
5373 LHSBegin->getType(), 2, "omp.arraycpy.destElementPast");
5374 LHSElementPHI->addIncoming(LHSBegin, EntryBB);
5375 Address LHSElementCurrent =
5376 Address(LHSElementPHI,
5377 LHSAddr.getAlignment().alignmentOfArrayElement(ElementSize));
5378
5379 // Emit copy.
5380 CodeGenFunction::OMPPrivateScope Scope(CGF);
5381 Scope.addPrivate(LHSVar, [=]() { return LHSElementCurrent; });
5382 Scope.addPrivate(RHSVar, [=]() { return RHSElementCurrent; });
5383 Scope.Privatize();
5384 RedOpGen(CGF, XExpr, EExpr, UpExpr);
5385 Scope.ForceCleanup();
5386
5387 // Shift the address forward by one element.
5388 llvm::Value *LHSElementNext = CGF.Builder.CreateConstGEP1_32(
5389 LHSAddr.getElementType(), LHSElementPHI, /*Idx0=*/1,
5390 "omp.arraycpy.dest.element");
5391 llvm::Value *RHSElementNext = CGF.Builder.CreateConstGEP1_32(
5392 RHSAddr.getElementType(), RHSElementPHI, /*Idx0=*/1,
5393 "omp.arraycpy.src.element");
5394 // Check whether we've reached the end.
5395 llvm::Value *Done =
5396 CGF.Builder.CreateICmpEQ(LHSElementNext, LHSEnd, "omp.arraycpy.done");
5397 CGF.Builder.CreateCondBr(Done, DoneBB, BodyBB);
5398 LHSElementPHI->addIncoming(LHSElementNext, CGF.Builder.GetInsertBlock());
5399 RHSElementPHI->addIncoming(RHSElementNext, CGF.Builder.GetInsertBlock());
5400
5401 // Done.
5402 CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
5403}
5404
5405/// Emit reduction combiner. If the combiner is a simple expression emit it as
5406/// is, otherwise consider it as combiner of UDR decl and emit it as a call of
5407/// UDR combiner function.
5408static void emitReductionCombiner(CodeGenFunction &CGF,
5409 const Expr *ReductionOp) {
5410 if (const auto *CE = dyn_cast<CallExpr>(ReductionOp))
5411 if (const auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee()))
5412 if (const auto *DRE =
5413 dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts()))
5414 if (const auto *DRD =
5415 dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl())) {
5416 std::pair<llvm::Function *, llvm::Function *> Reduction =
5417 CGF.CGM.getOpenMPRuntime().getUserDefinedReduction(DRD);
5418 RValue Func = RValue::get(Reduction.first);
5419 CodeGenFunction::OpaqueValueMapping Map(CGF, OVE, Func);
5420 CGF.EmitIgnoredExpr(ReductionOp);
5421 return;
5422 }
5423 CGF.EmitIgnoredExpr(ReductionOp);
5424}
5425
5426llvm::Function *CGOpenMPRuntime::emitReductionFunction(
5427 SourceLocation Loc, llvm::Type *ArgsType, ArrayRef<const Expr *> Privates,
5428 ArrayRef<const Expr *> LHSExprs, ArrayRef<const Expr *> RHSExprs,
5429 ArrayRef<const Expr *> ReductionOps) {
5430 ASTContext &C = CGM.getContext();
5431
5432 // void reduction_func(void *LHSArg, void *RHSArg);
5433 FunctionArgList Args;
5434 ImplicitParamDecl LHSArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
5435 ImplicitParamDecl::Other);
5436 ImplicitParamDecl RHSArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
5437 ImplicitParamDecl::Other);
5438 Args.push_back(&LHSArg);
5439 Args.push_back(&RHSArg);
5440 const auto &CGFI =
5441 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
5442 std::string Name = getName({"omp", "reduction", "reduction_func"});
5443 auto *Fn = llvm::Function::Create(CGM.getTypes().GetFunctionType(CGFI),
5444 llvm::GlobalValue::InternalLinkage, Name,
5445 &CGM.getModule());
5446 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, CGFI);
5447 Fn->setDoesNotRecurse();
5448 CodeGenFunction CGF(CGM);
5449 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args, Loc, Loc);
5450
5451 // Dst = (void*[n])(LHSArg);
5452 // Src = (void*[n])(RHSArg);
5453 Address LHS(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5454 CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&LHSArg)),
5455 ArgsType), CGF.getPointerAlign());
5456 Address RHS(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5457 CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&RHSArg)),
5458 ArgsType), CGF.getPointerAlign());
5459
5460 // ...
5461 // *(Type<i>*)lhs[i] = RedOp<i>(*(Type<i>*)lhs[i], *(Type<i>*)rhs[i]);
5462 // ...
5463 CodeGenFunction::OMPPrivateScope Scope(CGF);
5464 auto IPriv = Privates.begin();
5465 unsigned Idx = 0;
5466 for (unsigned I = 0, E = ReductionOps.size(); I < E; ++I, ++IPriv, ++Idx) {
5467 const auto *RHSVar =
5468 cast<VarDecl>(cast<DeclRefExpr>(RHSExprs[I])->getDecl());
5469 Scope.addPrivate(RHSVar, [&CGF, RHS, Idx, RHSVar]() {
5470 return emitAddrOfVarFromArray(CGF, RHS, Idx, RHSVar);
5471 });
5472 const auto *LHSVar =
5473 cast<VarDecl>(cast<DeclRefExpr>(LHSExprs[I])->getDecl());
5474 Scope.addPrivate(LHSVar, [&CGF, LHS, Idx, LHSVar]() {
5475 return emitAddrOfVarFromArray(CGF, LHS, Idx, LHSVar);
5476 });
5477 QualType PrivTy = (*IPriv)->getType();
5478 if (PrivTy->isVariablyModifiedType()) {
5479 // Get array size and emit VLA type.
5480 ++Idx;
5481 Address Elem = CGF.Builder.CreateConstArrayGEP(LHS, Idx);
5482 llvm::Value *Ptr = CGF.Builder.CreateLoad(Elem);
5483 const VariableArrayType *VLA =
5484 CGF.getContext().getAsVariableArrayType(PrivTy);
5485 const auto *OVE = cast<OpaqueValueExpr>(VLA->getSizeExpr());
5486 CodeGenFunction::OpaqueValueMapping OpaqueMap(
5487 CGF, OVE, RValue::get(CGF.Builder.CreatePtrToInt(Ptr, CGF.SizeTy)));
5488 CGF.EmitVariablyModifiedType(PrivTy);
5489 }
5490 }
5491 Scope.Privatize();
5492 IPriv = Privates.begin();
5493 auto ILHS = LHSExprs.begin();
5494 auto IRHS = RHSExprs.begin();
5495 for (const Expr *E : ReductionOps) {
5496 if ((*IPriv)->getType()->isArrayType()) {
5497 // Emit reduction for array section.
5498 const auto *LHSVar = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
5499 const auto *RHSVar = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
5500 EmitOMPAggregateReduction(
5501 CGF, (*IPriv)->getType(), LHSVar, RHSVar,
5502 [=](CodeGenFunction &CGF, const Expr *, const Expr *, const Expr *) {
5503 emitReductionCombiner(CGF, E);
5504 });
5505 } else {
5506 // Emit reduction for array subscript or single variable.
5507 emitReductionCombiner(CGF, E);
5508 }
5509 ++IPriv;
5510 ++ILHS;
5511 ++IRHS;
5512 }
5513 Scope.ForceCleanup();
5514 CGF.FinishFunction();
5515 return Fn;
5516}
5517
5518void CGOpenMPRuntime::emitSingleReductionCombiner(CodeGenFunction &CGF,
5519 const Expr *ReductionOp,
5520 const Expr *PrivateRef,
5521 const DeclRefExpr *LHS,
5522 const DeclRefExpr *RHS) {
5523 if (PrivateRef->getType()->isArrayType()) {
5524 // Emit reduction for array section.
5525 const auto *LHSVar = cast<VarDecl>(LHS->getDecl());
5526 const auto *RHSVar = cast<VarDecl>(RHS->getDecl());
5527 EmitOMPAggregateReduction(
5528 CGF, PrivateRef->getType(), LHSVar, RHSVar,
5529 [=](CodeGenFunction &CGF, const Expr *, const Expr *, const Expr *) {
5530 emitReductionCombiner(CGF, ReductionOp);
5531 });
5532 } else {
5533 // Emit reduction for array subscript or single variable.
5534 emitReductionCombiner(CGF, ReductionOp);
5535 }
5536}
5537
5538void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
5539 ArrayRef<const Expr *> Privates,
5540 ArrayRef<const Expr *> LHSExprs,
5541 ArrayRef<const Expr *> RHSExprs,
5542 ArrayRef<const Expr *> ReductionOps,
5543 ReductionOptionsTy Options) {
5544 if (!CGF.HaveInsertPoint())
5545 return;
5546
5547 bool WithNowait = Options.WithNowait;
5548 bool SimpleReduction = Options.SimpleReduction;
5549
5550 // Next code should be emitted for reduction:
5551 //
5552 // static kmp_critical_name lock = { 0 };
5553 //
5554 // void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
5555 // *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
5556 // ...
5557 // *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
5558 // *(Type<n>-1*)rhs[<n>-1]);
5559 // }
5560 //
5561 // ...
5562 // void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n>-1]};
5563 // switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList),
5564 // RedList, reduce_func, &<lock>)) {
5565 // case 1:
5566 // ...
5567 // <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
5568 // ...
5569 // __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
5570 // break;
5571 // case 2:
5572 // ...
5573 // Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
5574 // ...
5575 // [__kmpc_end_reduce(<loc>, <gtid>, &<lock>);]
5576 // break;
5577 // default:;
5578 // }
5579 //
5580 // if SimpleReduction is true, only the next code is generated:
5581 // ...
5582 // <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
5583 // ...
5584
5585 ASTContext &C = CGM.getContext();
5586
5587 if (SimpleReduction) {
5588 CodeGenFunction::RunCleanupsScope Scope(CGF);
5589 auto IPriv = Privates.begin();
5590 auto ILHS = LHSExprs.begin();
5591 auto IRHS = RHSExprs.begin();
5592 for (const Expr *E : ReductionOps) {
5593 emitSingleReductionCombiner(CGF, E, *IPriv, cast<DeclRefExpr>(*ILHS),
5594 cast<DeclRefExpr>(*IRHS));
5595 ++IPriv;
5596 ++ILHS;
5597 ++IRHS;
5598 }
5599 return;
5600 }
5601
5602 // 1. Build a list of reduction variables.
5603 // void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
5604 auto Size = RHSExprs.size();
5605 for (const Expr *E : Privates) {
5606 if (E->getType()->isVariablyModifiedType())
5607 // Reserve place for array size.
5608 ++Size;
5609 }
5610 llvm::APInt ArraySize(/*unsigned int numBits=*/32, Size);
5611 QualType ReductionArrayTy =
5612 C.getConstantArrayType(C.VoidPtrTy, ArraySize, nullptr, ArrayType::Normal,
5613 /*IndexTypeQuals=*/0);
5614 Address ReductionList =
5615 CGF.CreateMemTemp(ReductionArrayTy, ".omp.reduction.red_list");
5616 auto IPriv = Privates.begin();
5617 unsigned Idx = 0;
5618 for (unsigned I = 0, E = RHSExprs.size(); I < E; ++I, ++IPriv, ++Idx) {
5619 Address Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx);
5620 CGF.Builder.CreateStore(
5621 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5622 CGF.EmitLValue(RHSExprs[I]).getPointer(CGF), CGF.VoidPtrTy),
5623 Elem);
5624 if ((*IPriv)->getType()->isVariablyModifiedType()) {
5625 // Store array size.
5626 ++Idx;
5627 Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx);
5628 llvm::Value *Size = CGF.Builder.CreateIntCast(
5629 CGF.getVLASize(
5630 CGF.getContext().getAsVariableArrayType((*IPriv)->getType()))
5631 .NumElts,
5632 CGF.SizeTy, /*isSigned=*/false);
5633 CGF.Builder.CreateStore(CGF.Builder.CreateIntToPtr(Size, CGF.VoidPtrTy),
5634 Elem);
5635 }
5636 }
5637
5638 // 2. Emit reduce_func().
5639 llvm::Function *ReductionFn = emitReductionFunction(
5640 Loc, CGF.ConvertTypeForMem(ReductionArrayTy)->getPointerTo(), Privates,
5641 LHSExprs, RHSExprs, ReductionOps);
5642
5643 // 3. Create static kmp_critical_name lock = { 0 };
5644 std::string Name = getName({"reduction"});
5645 llvm::Value *Lock = getCriticalRegionLock(Name);
5646
5647 // 4. Build res = __kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList),
5648 // RedList, reduce_func, &<lock>);
5649 llvm::Value *IdentTLoc = emitUpdateLocation(CGF, Loc, OMP_ATOMIC_REDUCE);
5650 llvm::Value *ThreadId = getThreadID(CGF, Loc);
5651 llvm::Value *ReductionArrayTySize = CGF.getTypeSize(ReductionArrayTy);
5652 llvm::Value *RL = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5653 ReductionList.getPointer(), CGF.VoidPtrTy);
5654 llvm::Value *Args[] = {
5655 IdentTLoc, // ident_t *<loc>
5656 ThreadId, // i32 <gtid>
5657 CGF.Builder.getInt32(RHSExprs.size()), // i32 <n>
5658 ReductionArrayTySize, // size_type sizeof(RedList)
5659 RL, // void *RedList
5660 ReductionFn, // void (*) (void *, void *) <reduce_func>
5661 Lock // kmp_critical_name *&<lock>
5662 };
5663 llvm::Value *Res = CGF.EmitRuntimeCall(
5664 OMPBuilder.getOrCreateRuntimeFunction(
5665 CGM.getModule(),
5666 WithNowait ? OMPRTL___kmpc_reduce_nowait : OMPRTL___kmpc_reduce),
5667 Args);
5668
5669 // 5. Build switch(res)
5670 llvm::BasicBlock *DefaultBB = CGF.createBasicBlock(".omp.reduction.default");
5671 llvm::SwitchInst *SwInst =
5672 CGF.Builder.CreateSwitch(Res, DefaultBB, /*NumCases=*/2);
5673
5674 // 6. Build case 1:
5675 // ...
5676 // <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
5677 // ...
5678 // __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
5679 // break;
5680 llvm::BasicBlock *Case1BB = CGF.createBasicBlock(".omp.reduction.case1");
5681 SwInst->addCase(CGF.Builder.getInt32(1), Case1BB);
5682 CGF.EmitBlock(Case1BB);
5683
5684 // Add emission of __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
5685 llvm::Value *EndArgs[] = {
5686 IdentTLoc, // ident_t *<loc>
5687 ThreadId, // i32 <gtid>
5688 Lock // kmp_critical_name *&<lock>
5689 };
5690 auto &&CodeGen = [Privates, LHSExprs, RHSExprs, ReductionOps](
5691 CodeGenFunction &CGF, PrePostActionTy &Action) {
5692 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
5693 auto IPriv = Privates.begin();
5694 auto ILHS = LHSExprs.begin();
5695 auto IRHS = RHSExprs.begin();
5696 for (const Expr *E : ReductionOps) {
5697 RT.emitSingleReductionCombiner(CGF, E, *IPriv, cast<DeclRefExpr>(*ILHS),
5698 cast<DeclRefExpr>(*IRHS));
5699 ++IPriv;
5700 ++ILHS;
5701 ++IRHS;
5702 }
5703 };
5704 RegionCodeGenTy RCG(CodeGen);
5705 CommonActionTy Action(
5706 nullptr, llvm::None,
5707 OMPBuilder.getOrCreateRuntimeFunction(
5708 CGM.getModule(), WithNowait ? OMPRTL___kmpc_end_reduce_nowait
5709 : OMPRTL___kmpc_end_reduce),
5710 EndArgs);
5711 RCG.setAction(Action);
5712 RCG(CGF);
5713
5714 CGF.EmitBranch(DefaultBB);
5715
5716 // 7. Build case 2:
5717 // ...
5718 // Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
5719 // ...
5720 // break;
5721 llvm::BasicBlock *Case2BB = CGF.createBasicBlock(".omp.reduction.case2");
5722 SwInst->addCase(CGF.Builder.getInt32(2), Case2BB);
5723 CGF.EmitBlock(Case2BB);
5724
5725 auto &&AtomicCodeGen = [Loc, Privates, LHSExprs, RHSExprs, ReductionOps](
5726 CodeGenFunction &CGF, PrePostActionTy &Action) {
5727 auto ILHS = LHSExprs.begin();
5728 auto IRHS = RHSExprs.begin();
5729 auto IPriv = Privates.begin();
5730 for (const Expr *E : ReductionOps) {
5731 const Expr *XExpr = nullptr;
5732 const Expr *EExpr = nullptr;
5733 const Expr *UpExpr = nullptr;
5734 BinaryOperatorKind BO = BO_Comma;
5735 if (const auto *BO = dyn_cast<BinaryOperator>(E)) {
5736 if (BO->getOpcode() == BO_Assign) {
5737 XExpr = BO->getLHS();
5738 UpExpr = BO->getRHS();
5739 }
5740 }
5741 // Try to emit update expression as a simple atomic.
5742 const Expr *RHSExpr = UpExpr;
5743 if (RHSExpr) {
5744 // Analyze RHS part of the whole expression.
5745 if (const auto *ACO = dyn_cast<AbstractConditionalOperator>(
5746 RHSExpr->IgnoreParenImpCasts())) {
5747 // If this is a conditional operator, analyze its condition for
5748 // min/max reduction operator.
5749 RHSExpr = ACO->getCond();
5750 }
5751 if (const auto *BORHS =
5752 dyn_cast<BinaryOperator>(RHSExpr->IgnoreParenImpCasts())) {
5753 EExpr = BORHS->getRHS();
5754 BO = BORHS->getOpcode();
5755 }
5756 }
5757 if (XExpr) {
5758 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
5759 auto &&AtomicRedGen = [BO, VD,
5760 Loc](CodeGenFunction &CGF, const Expr *XExpr,
5761 const Expr *EExpr, const Expr *UpExpr) {
5762 LValue X = CGF.EmitLValue(XExpr);
5763 RValue E;
5764 if (EExpr)
5765 E = CGF.EmitAnyExpr(EExpr);
5766 CGF.EmitOMPAtomicSimpleUpdateExpr(
5767 X, E, BO, /*IsXLHSInRHSPart=*/true,
5768 llvm::AtomicOrdering::Monotonic, Loc,
5769 [&CGF, UpExpr, VD, Loc](RValue XRValue) {
5770 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
5771 PrivateScope.addPrivate(
5772 VD, [&CGF, VD, XRValue, Loc]() {
5773 Address LHSTemp = CGF.CreateMemTemp(VD->getType());
5774 CGF.emitOMPSimpleStore(
5775 CGF.MakeAddrLValue(LHSTemp, VD->getType()), XRValue,
5776 VD->getType().getNonReferenceType(), Loc);
5777 return LHSTemp;
5778 });
5779 (void)PrivateScope.Privatize();
5780 return CGF.EmitAnyExpr(UpExpr);
5781 });
5782 };
5783 if ((*IPriv)->getType()->isArrayType()) {
5784 // Emit atomic reduction for array section.
5785 const auto *RHSVar =
5786 cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
5787 EmitOMPAggregateReduction(CGF, (*IPriv)->getType(), VD, RHSVar,
5788 AtomicRedGen, XExpr, EExpr, UpExpr);
5789 } else {
5790 // Emit atomic reduction for array subscript or single variable.
5791 AtomicRedGen(CGF, XExpr, EExpr, UpExpr);
5792 }
5793 } else {
5794 // Emit as a critical region.
5795 auto &&CritRedGen = [E, Loc](CodeGenFunction &CGF, const Expr *,
5796 const Expr *, const Expr *) {
5797 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
5798 std::string Name = RT.getName({"atomic_reduction"});
5799 RT.emitCriticalRegion(
5800 CGF, Name,
5801 [=](CodeGenFunction &CGF, PrePostActionTy &Action) {
5802 Action.Enter(CGF);
5803 emitReductionCombiner(CGF, E);
5804 },
5805 Loc);
5806 };
5807 if ((*IPriv)->getType()->isArrayType()) {
5808 const auto *LHSVar =
5809 cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
5810 const auto *RHSVar =
5811 cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
5812 EmitOMPAggregateReduction(CGF, (*IPriv)->getType(), LHSVar, RHSVar,
5813 CritRedGen);
5814 } else {
5815 CritRedGen(CGF, nullptr, nullptr, nullptr);
5816 }
5817 }
5818 ++ILHS;
5819 ++IRHS;
5820 ++IPriv;
5821 }
5822 };
5823 RegionCodeGenTy AtomicRCG(AtomicCodeGen);
5824 if (!WithNowait) {
5825 // Add emission of __kmpc_end_reduce(<loc>, <gtid>, &<lock>);
5826 llvm::Value *EndArgs[] = {
5827 IdentTLoc, // ident_t *<loc>
5828 ThreadId, // i32 <gtid>
5829 Lock // kmp_critical_name *&<lock>
5830 };
5831 CommonActionTy Action(nullptr, llvm::None,
5832 OMPBuilder.getOrCreateRuntimeFunction(
5833 CGM.getModule(), OMPRTL___kmpc_end_reduce),
5834 EndArgs);
5835 AtomicRCG.setAction(Action);
5836 AtomicRCG(CGF);
5837 } else {
5838 AtomicRCG(CGF);
5839 }
5840
5841 CGF.EmitBranch(DefaultBB);
5842 CGF.EmitBlock(DefaultBB, /*IsFinished=*/true);
5843}
5844
5845/// Generates unique name for artificial threadprivate variables.
5846/// Format is: <Prefix> "." <Decl_mangled_name> "_" "<Decl_start_loc_raw_enc>"
5847static std::string generateUniqueName(CodeGenModule &CGM, StringRef Prefix,
5848 const Expr *Ref) {
5849 SmallString<256> Buffer;
5850 llvm::raw_svector_ostream Out(Buffer);
5851 const clang::DeclRefExpr *DE;
5852 const VarDecl *D = ::getBaseDecl(Ref, DE);
5853 if (!D)
5854 D = cast<VarDecl>(cast<DeclRefExpr>(Ref)->getDecl());
5855 D = D->getCanonicalDecl();
5856 std::string Name = CGM.getOpenMPRuntime().getName(
5857 {D->isLocalVarDeclOrParm() ? D->getName() : CGM.getMangledName(D)});
5858 Out << Prefix << Name << "_"
5859 << D->getCanonicalDecl()->getBeginLoc().getRawEncoding();
5860 return std::string(Out.str());
5861}
5862
5863/// Emits reduction initializer function:
5864/// \code
5865/// void @.red_init(void* %arg, void* %orig) {
5866/// %0 = bitcast void* %arg to <type>*
5867/// store <type> <init>, <type>* %0
5868/// ret void
5869/// }
5870/// \endcode
5871static llvm::Value *emitReduceInitFunction(CodeGenModule &CGM,
5872 SourceLocation Loc,
5873 ReductionCodeGen &RCG, unsigned N) {
5874 ASTContext &C = CGM.getContext();
5875 QualType VoidPtrTy = C.VoidPtrTy;
5876 VoidPtrTy.addRestrict();
5877 FunctionArgList Args;
5878 ImplicitParamDecl Param(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, VoidPtrTy,
5879 ImplicitParamDecl::Other);
5880 ImplicitParamDecl ParamOrig(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, VoidPtrTy,
5881 ImplicitParamDecl::Other);
5882 Args.emplace_back(&Param);
5883 Args.emplace_back(&ParamOrig);
5884 const auto &FnInfo =
5885 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
5886 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
5887 std::string Name = CGM.getOpenMPRuntime().getName({"red_init", ""});
5888 auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
5889 Name, &CGM.getModule());
5890 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo);
5891 Fn->setDoesNotRecurse();
5892 CodeGenFunction CGF(CGM);
5893 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, Loc, Loc);
5894 Address PrivateAddr = CGF.EmitLoadOfPointer(
5895 CGF.GetAddrOfLocalVar(&Param),
5896 C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
5897 llvm::Value *Size = nullptr;
5898 // If the size of the reduction item is non-constant, load it from global
5899 // threadprivate variable.
5900 if (RCG.getSizes(N).second) {
5901 Address SizeAddr = CGM.getOpenMPRuntime().getAddrOfArtificialThreadPrivate(
5902 CGF, CGM.getContext().getSizeType(),
5903 generateUniqueName(CGM, "reduction_size", RCG.getRefExpr(N)));
5904 Size = CGF.EmitLoadOfScalar(SizeAddr, /*Volatile=*/false,
5905 CGM.getContext().getSizeType(), Loc);
5906 }
5907 RCG.emitAggregateType(CGF, N, Size);
5908 LValue OrigLVal;
5909 // If initializer uses initializer from declare reduction construct, emit a
5910 // pointer to the address of the original reduction item (reuired by reduction
5911 // initializer)
5912 if (RCG.usesReductionInitializer(N)) {
5913 Address SharedAddr = CGF.GetAddrOfLocalVar(&ParamOrig);
5914 SharedAddr = CGF.EmitLoadOfPointer(
5915 SharedAddr,
5916 CGM.getContext().VoidPtrTy.castAs<PointerType>()->getTypePtr());
5917 OrigLVal = CGF.MakeAddrLValue(SharedAddr, CGM.getContext().VoidPtrTy);
5918 } else {
5919 OrigLVal = CGF.MakeNaturalAlignAddrLValue(
5920 llvm::ConstantPointerNull::get(CGM.VoidPtrTy),
5921 CGM.getContext().VoidPtrTy);
5922 }
5923 // Emit the initializer:
5924 // %0 = bitcast void* %arg to <type>*
5925 // store <type> <init>, <type>* %0
5926 RCG.emitInitialization(CGF, N, PrivateAddr, OrigLVal,
5927 [](CodeGenFunction &) { return false; });
5928 CGF.FinishFunction();
5929 return Fn;
5930}
5931
5932/// Emits reduction combiner function:
5933/// \code
5934/// void @.red_comb(void* %arg0, void* %arg1) {
5935/// %lhs = bitcast void* %arg0 to <type>*
5936/// %rhs = bitcast void* %arg1 to <type>*
5937/// %2 = <ReductionOp>(<type>* %lhs, <type>* %rhs)
5938/// store <type> %2, <type>* %lhs
5939/// ret void
5940/// }
5941/// \endcode
5942static llvm::Value *emitReduceCombFunction(CodeGenModule &CGM,
5943 SourceLocation Loc,
5944 ReductionCodeGen &RCG, unsigned N,
5945 const Expr *ReductionOp,
5946 const Expr *LHS, const Expr *RHS,
5947 const Expr *PrivateRef) {
5948 ASTContext &C = CGM.getContext();
5949 const auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(LHS)->getDecl());
5950 const auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(RHS)->getDecl());
5951 FunctionArgList Args;
5952 ImplicitParamDecl ParamInOut(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
5953 C.VoidPtrTy, ImplicitParamDecl::Other);
5954 ImplicitParamDecl ParamIn(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
5955 ImplicitParamDecl::Other);
5956 Args.emplace_back(&ParamInOut);
5957 Args.emplace_back(&ParamIn);
5958 const auto &FnInfo =
5959 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
5960 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
5961 std::string Name = CGM.getOpenMPRuntime().getName({"red_comb", ""});
5962 auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
5963 Name, &CGM.getModule());
5964 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo);
5965 Fn->setDoesNotRecurse();
5966 CodeGenFunction CGF(CGM);
5967 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, Loc, Loc);
5968 llvm::Value *Size = nullptr;
5969 // If the size of the reduction item is non-constant, load it from global
5970 // threadprivate variable.
5971 if (RCG.getSizes(N).second) {
5972 Address SizeAddr = CGM.getOpenMPRuntime().getAddrOfArtificialThreadPrivate(
5973 CGF, CGM.getContext().getSizeType(),
5974 generateUniqueName(CGM, "reduction_size", RCG.getRefExpr(N)));
5975 Size = CGF.EmitLoadOfScalar(SizeAddr, /*Volatile=*/false,
5976 CGM.getContext().getSizeType(), Loc);
5977 }
5978 RCG.emitAggregateType(CGF, N, Size);
5979 // Remap lhs and rhs variables to the addresses of the function arguments.
5980 // %lhs = bitcast void* %arg0 to <type>*
5981 // %rhs = bitcast void* %arg1 to <type>*
5982 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
5983 PrivateScope.addPrivate(LHSVD, [&C, &CGF, &ParamInOut, LHSVD]() {
5984 // Pull out the pointer to the variable.
5985 Address PtrAddr = CGF.EmitLoadOfPointer(
5986 CGF.GetAddrOfLocalVar(&ParamInOut),
5987 C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
5988 return CGF.Builder.CreateElementBitCast(
5989 PtrAddr, CGF.ConvertTypeForMem(LHSVD->getType()));
5990 });
5991 PrivateScope.addPrivate(RHSVD, [&C, &CGF, &ParamIn, RHSVD]() {
5992 // Pull out the pointer to the variable.
5993 Address PtrAddr = CGF.EmitLoadOfPointer(
5994 CGF.GetAddrOfLocalVar(&ParamIn),
5995 C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
5996 return CGF.Builder.CreateElementBitCast(
5997 PtrAddr, CGF.ConvertTypeForMem(RHSVD->getType()));
5998 });
5999 PrivateScope.Privatize();
6000 // Emit the combiner body:
6001 // %2 = <ReductionOp>(<type> *%lhs, <type> *%rhs)
6002 // store <type> %2, <type>* %lhs
6003 CGM.getOpenMPRuntime().emitSingleReductionCombiner(
6004 CGF, ReductionOp, PrivateRef, cast<DeclRefExpr>(LHS),
6005 cast<DeclRefExpr>(RHS));
6006 CGF.FinishFunction();
6007 return Fn;
6008}
6009
6010/// Emits reduction finalizer function:
6011/// \code
6012/// void @.red_fini(void* %arg) {
6013/// %0 = bitcast void* %arg to <type>*
6014/// <destroy>(<type>* %0)
6015/// ret void
6016/// }
6017/// \endcode
6018static llvm::Value *emitReduceFiniFunction(CodeGenModule &CGM,
6019 SourceLocation Loc,
6020 ReductionCodeGen &RCG, unsigned N) {
6021 if (!RCG.needCleanups(N))
6022 return nullptr;
6023 ASTContext &C = CGM.getContext();
6024 FunctionArgList Args;
6025 ImplicitParamDecl Param(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
6026 ImplicitParamDecl::Other);
6027 Args.emplace_back(&Param);
6028 const auto &FnInfo =
6029 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
6030 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
6031 std::string Name = CGM.getOpenMPRuntime().getName({"red_fini", ""});
6032 auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
6033 Name, &CGM.getModule());
6034 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo);
6035 Fn->setDoesNotRecurse();
6036 CodeGenFunction CGF(CGM);
6037 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, Loc, Loc);
6038 Address PrivateAddr = CGF.EmitLoadOfPointer(
6039 CGF.GetAddrOfLocalVar(&Param),
6040 C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
6041 llvm::Value *Size = nullptr;
6042 // If the size of the reduction item is non-constant, load it from global
6043 // threadprivate variable.
6044 if (RCG.getSizes(N).second) {
6045 Address SizeAddr = CGM.getOpenMPRuntime().getAddrOfArtificialThreadPrivate(
6046 CGF, CGM.getContext().getSizeType(),
6047 generateUniqueName(CGM, "reduction_size", RCG.getRefExpr(N)));
6048 Size = CGF.EmitLoadOfScalar(SizeAddr, /*Volatile=*/false,
6049 CGM.getContext().getSizeType(), Loc);
6050 }
6051 RCG.emitAggregateType(CGF, N, Size);
6052 // Emit the finalizer body:
6053 // <destroy>(<type>* %0)
6054 RCG.emitCleanups(CGF, N, PrivateAddr);
6055 CGF.FinishFunction(Loc);
6056 return Fn;
6057}
6058
6059llvm::Value *CGOpenMPRuntime::emitTaskReductionInit(
6060 CodeGenFunction &CGF, SourceLocation Loc, ArrayRef<const Expr *> LHSExprs,
6061 ArrayRef<const Expr *> RHSExprs, const OMPTaskDataTy &Data) {
6062 if (!CGF.HaveInsertPoint() || Data.ReductionVars.empty())
6063 return nullptr;
6064
6065 // Build typedef struct:
6066 // kmp_taskred_input {
6067 // void *reduce_shar; // shared reduction item
6068 // void *reduce_orig; // original reduction item used for initialization
6069 // size_t reduce_size; // size of data item
6070 // void *reduce_init; // data initialization routine
6071 // void *reduce_fini; // data finalization routine
6072 // void *reduce_comb; // data combiner routine
6073 // kmp_task_red_flags_t flags; // flags for additional info from compiler
6074 // } kmp_taskred_input_t;
6075 ASTContext &C = CGM.getContext();
6076 RecordDecl *RD = C.buildImplicitRecord("kmp_taskred_input_t");
6077 RD->startDefinition();
6078 const FieldDecl *SharedFD = addFieldToRecordDecl(C, RD, C.VoidPtrTy);
6079 const FieldDecl *OrigFD = addFieldToRecordDecl(C, RD, C.VoidPtrTy);
6080 const FieldDecl *SizeFD = addFieldToRecordDecl(C, RD, C.getSizeType());
6081 const FieldDecl *InitFD = addFieldToRecordDecl(C, RD, C.VoidPtrTy);
6082 const FieldDecl *FiniFD = addFieldToRecordDecl(C, RD, C.VoidPtrTy);
6083 const FieldDecl *CombFD = addFieldToRecordDecl(C, RD, C.VoidPtrTy);
6084 const FieldDecl *FlagsFD = addFieldToRecordDecl(
6085 C, RD, C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/false));
6086 RD->completeDefinition();
6087 QualType RDType = C.getRecordType(RD);
6088 unsigned Size = Data.ReductionVars.size();
6089 llvm::APInt ArraySize(/*numBits=*/64, Size);
6090 QualType ArrayRDType = C.getConstantArrayType(
6091 RDType, ArraySize, nullptr, ArrayType::Normal, /*IndexTypeQuals=*/0);
6092 // kmp_task_red_input_t .rd_input.[Size];
6093 Address TaskRedInput = CGF.CreateMemTemp(ArrayRDType, ".rd_input.");
6094 ReductionCodeGen RCG(Data.ReductionVars, Data.ReductionOrigs,
6095 Data.ReductionCopies, Data.ReductionOps);
6096 for (unsigned Cnt = 0; Cnt < Size; ++Cnt) {
6097 // kmp_task_red_input_t &ElemLVal = .rd_input.[Cnt];
6098 llvm::Value *Idxs[] = {llvm::ConstantInt::get(CGM.SizeTy, /*V=*/0),
6099 llvm::ConstantInt::get(CGM.SizeTy, Cnt)};
6100 llvm::Value *GEP = CGF.EmitCheckedInBoundsGEP(
6101 TaskRedInput.getPointer(), Idxs,
6102 /*SignedIndices=*/false, /*IsSubtraction=*/false, Loc,
6103 ".rd_input.gep.");
6104 LValue ElemLVal = CGF.MakeNaturalAlignAddrLValue(GEP, RDType);
6105 // ElemLVal.reduce_shar = &Shareds[Cnt];
6106 LValue SharedLVal = CGF.EmitLValueForField(ElemLVal, SharedFD);
6107 RCG.emitSharedOrigLValue(CGF, Cnt);
6108 llvm::Value *CastedShared =
6109 CGF.EmitCastToVoidPtr(RCG.getSharedLValue(Cnt).getPointer(CGF));
6110 CGF.EmitStoreOfScalar(CastedShared, SharedLVal);
6111 // ElemLVal.reduce_orig = &Origs[Cnt];
6112 LValue OrigLVal = CGF.EmitLValueForField(ElemLVal, OrigFD);
6113 llvm::Value *CastedOrig =
6114 CGF.EmitCastToVoidPtr(RCG.getOrigLValue(Cnt).getPointer(CGF));
6115 CGF.EmitStoreOfScalar(CastedOrig, OrigLVal);
6116 RCG.emitAggregateType(CGF, Cnt);
6117 llvm::Value *SizeValInChars;
6118 llvm::Value *SizeVal;
6119 std::tie(SizeValInChars, SizeVal) = RCG.getSizes(Cnt);
6120 // We use delayed creation/initialization for VLAs and array sections. It is
6121 // required because runtime does not provide the way to pass the sizes of
6122 // VLAs/array sections to initializer/combiner/finalizer functions. Instead
6123 // threadprivate global variables are used to store these values and use
6124 // them in the functions.
6125 bool DelayedCreation = !!SizeVal;
6126 SizeValInChars = CGF.Builder.CreateIntCast(SizeValInChars, CGM.SizeTy,
6127 /*isSigned=*/false);
6128 LValue SizeLVal = CGF.EmitLValueForField(ElemLVal, SizeFD);
6129 CGF.EmitStoreOfScalar(SizeValInChars, SizeLVal);
6130 // ElemLVal.reduce_init = init;
6131 LValue InitLVal = CGF.EmitLValueForField(ElemLVal, InitFD);
6132 llvm::Value *InitAddr =
6133 CGF.EmitCastToVoidPtr(emitReduceInitFunction(CGM, Loc, RCG, Cnt));
6134 CGF.EmitStoreOfScalar(InitAddr, InitLVal);
6135 // ElemLVal.reduce_fini = fini;
6136 LValue FiniLVal = CGF.EmitLValueForField(ElemLVal, FiniFD);
6137 llvm::Value *Fini = emitReduceFiniFunction(CGM, Loc, RCG, Cnt);
6138 llvm::Value *FiniAddr = Fini
6139 ? CGF.EmitCastToVoidPtr(Fini)
6140 : llvm::ConstantPointerNull::get(CGM.VoidPtrTy);
6141 CGF.EmitStoreOfScalar(FiniAddr, FiniLVal);
6142 // ElemLVal.reduce_comb = comb;
6143 LValue CombLVal = CGF.EmitLValueForField(ElemLVal, CombFD);
6144 llvm::Value *CombAddr = CGF.EmitCastToVoidPtr(emitReduceCombFunction(
6145 CGM, Loc, RCG, Cnt, Data.ReductionOps[Cnt], LHSExprs[Cnt],
6146 RHSExprs[Cnt], Data.ReductionCopies[Cnt]));
6147 CGF.EmitStoreOfScalar(CombAddr, CombLVal);
6148 // ElemLVal.flags = 0;
6149 LValue FlagsLVal = CGF.EmitLValueForField(ElemLVal, FlagsFD);
6150 if (DelayedCreation) {
6151 CGF.EmitStoreOfScalar(
6152 llvm::ConstantInt::get(CGM.Int32Ty, /*V=*/1, /*isSigned=*/true),
6153 FlagsLVal);
6154 } else
6155 CGF.EmitNullInitialization(FlagsLVal.getAddress(CGF),
6156 FlagsLVal.getType());
6157 }
6158 if (Data.IsReductionWithTaskMod) {
6159 // Build call void *__kmpc_taskred_modifier_init(ident_t *loc, int gtid, int
6160 // is_ws, int num, void *data);
6161 llvm::Value *IdentTLoc = emitUpdateLocation(CGF, Loc);
6162 llvm::Value *GTid = CGF.Builder.CreateIntCast(getThreadID(CGF, Loc),
6163 CGM.IntTy, /*isSigned=*/true);
6164 llvm::Value *Args[] = {
6165 IdentTLoc, GTid,
6166 llvm::ConstantInt::get(CGM.IntTy, Data.IsWorksharingReduction ? 1 : 0,
6167 /*isSigned=*/true),
6168 llvm::ConstantInt::get(CGM.IntTy, Size, /*isSigned=*/true),
6169 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
6170 TaskRedInput.getPointer(), CGM.VoidPtrTy)};
6171 return CGF.EmitRuntimeCall(
6172 OMPBuilder.getOrCreateRuntimeFunction(
6173 CGM.getModule(), OMPRTL___kmpc_taskred_modifier_init),
6174 Args);
6175 }
6176 // Build call void *__kmpc_taskred_init(int gtid, int num_data, void *data);
6177 llvm::Value *Args[] = {
6178 CGF.Builder.CreateIntCast(getThreadID(CGF, Loc), CGM.IntTy,
6179 /*isSigned=*/true),
6180 llvm::ConstantInt::get(CGM.IntTy, Size, /*isSigned=*/true),
6181 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(TaskRedInput.getPointer(),
6182 CGM.VoidPtrTy)};
6183 return CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
6184 CGM.getModule(), OMPRTL___kmpc_taskred_init),
6185 Args);
6186}
6187
6188void CGOpenMPRuntime::emitTaskReductionFini(CodeGenFunction &CGF,
6189 SourceLocation Loc,
6190 bool IsWorksharingReduction) {
6191 // Build call void *__kmpc_taskred_modifier_init(ident_t *loc, int gtid, int
6192 // is_ws, int num, void *data);
6193 llvm::Value *IdentTLoc = emitUpdateLocation(CGF, Loc);
6194 llvm::Value *GTid = CGF.Builder.CreateIntCast(getThreadID(CGF, Loc),
6195 CGM.IntTy, /*isSigned=*/true);
6196 llvm::Value *Args[] = {IdentTLoc, GTid,
6197 llvm::ConstantInt::get(CGM.IntTy,
6198 IsWorksharingReduction ? 1 : 0,
6199 /*isSigned=*/true)};
6200 (void)CGF.EmitRuntimeCall(
6201 OMPBuilder.getOrCreateRuntimeFunction(
6202 CGM.getModule(), OMPRTL___kmpc_task_reduction_modifier_fini),
6203 Args);
6204}
6205
6206void CGOpenMPRuntime::emitTaskReductionFixups(CodeGenFunction &CGF,
6207 SourceLocation Loc,
6208 ReductionCodeGen &RCG,
6209 unsigned N) {
6210 auto Sizes = RCG.getSizes(N);
6211 // Emit threadprivate global variable if the type is non-constant
6212 // (Sizes.second = nullptr).
6213 if (Sizes.second) {
6214 llvm::Value *SizeVal = CGF.Builder.CreateIntCast(Sizes.second, CGM.SizeTy,
6215 /*isSigned=*/false);
6216 Address SizeAddr = getAddrOfArtificialThreadPrivate(
6217 CGF, CGM.getContext().getSizeType(),
6218 generateUniqueName(CGM, "reduction_size", RCG.getRefExpr(N)));
6219 CGF.Builder.CreateStore(SizeVal, SizeAddr, /*IsVolatile=*/false);
6220 }
6221}
6222
6223Address CGOpenMPRuntime::getTaskReductionItem(CodeGenFunction &CGF,
6224 SourceLocation Loc,
6225 llvm::Value *ReductionsPtr,
6226 LValue SharedLVal) {
6227 // Build call void *__kmpc_task_reduction_get_th_data(int gtid, void *tg, void
6228 // *d);
6229 llvm::Value *Args[] = {CGF.Builder.CreateIntCast(getThreadID(CGF, Loc),
6230 CGM.IntTy,
6231 /*isSigned=*/true),
6232 ReductionsPtr,
6233 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
6234 SharedLVal.getPointer(CGF), CGM.VoidPtrTy)};
6235 return Address(
6236 CGF.EmitRuntimeCall(
6237 OMPBuilder.getOrCreateRuntimeFunction(
6238 CGM.getModule(), OMPRTL___kmpc_task_reduction_get_th_data),
6239 Args),
6240 SharedLVal.getAlignment());
6241}
6242
6243void CGOpenMPRuntime::emitTaskwaitCall(CodeGenFunction &CGF,
6244 SourceLocation Loc) {
6245 if (!CGF.HaveInsertPoint())
6246 return;
6247
6248 if (CGF.CGM.getLangOpts().OpenMPIRBuilder) {
6249 OMPBuilder.createTaskwait(CGF.Builder);
6250 } else {
6251 // Build call kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32
6252 // global_tid);
6253 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
6254 // Ignore return result until untied tasks are supported.
6255 CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
6256 CGM.getModule(), OMPRTL___kmpc_omp_taskwait),
6257 Args);
6258 }
6259
6260 if (auto *Region = dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
6261 Region->emitUntiedSwitch(CGF);
6262}
6263
6264void CGOpenMPRuntime::emitInlinedDirective(CodeGenFunction &CGF,
6265 OpenMPDirectiveKind InnerKind,
6266 const RegionCodeGenTy &CodeGen,
6267 bool HasCancel) {
6268 if (!CGF.HaveInsertPoint())
6269 return;
6270 InlinedOpenMPRegionRAII Region(CGF, CodeGen, InnerKind, HasCancel,
6271 InnerKind != OMPD_critical &&
6272 InnerKind != OMPD_master &&
6273 InnerKind != OMPD_masked);
6274 CGF.CapturedStmtInfo->EmitBody(CGF, /*S=*/nullptr);
6275}
6276
6277namespace {
6278enum RTCancelKind {
6279 CancelNoreq = 0,
6280 CancelParallel = 1,
6281 CancelLoop = 2,
6282 CancelSections = 3,
6283 CancelTaskgroup = 4
6284};
6285} // anonymous namespace
6286
6287static RTCancelKind getCancellationKind(OpenMPDirectiveKind CancelRegion) {
6288 RTCancelKind CancelKind = CancelNoreq;
6289 if (CancelRegion == OMPD_parallel)
6290 CancelKind = CancelParallel;
6291 else if (CancelRegion == OMPD_for)
6292 CancelKind = CancelLoop;
6293 else if (CancelRegion == OMPD_sections)
6294 CancelKind = CancelSections;
6295 else {
6296 assert(CancelRegion == OMPD_taskgroup)(static_cast<void> (0));
6297 CancelKind = CancelTaskgroup;
6298 }
6299 return CancelKind;
6300}
6301
6302void CGOpenMPRuntime::emitCancellationPointCall(
6303 CodeGenFunction &CGF, SourceLocation Loc,
6304 OpenMPDirectiveKind CancelRegion) {
6305 if (!CGF.HaveInsertPoint())
6306 return;
6307 // Build call kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32
6308 // global_tid, kmp_int32 cncl_kind);
6309 if (auto *OMPRegionInfo =
6310 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
6311 // For 'cancellation point taskgroup', the task region info may not have a
6312 // cancel. This may instead happen in another adjacent task.
6313 if (CancelRegion == OMPD_taskgroup || OMPRegionInfo->hasCancel()) {
6314 llvm::Value *Args[] = {
6315 emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
6316 CGF.Builder.getInt32(getCancellationKind(CancelRegion))};
6317 // Ignore return result until untied tasks are supported.
6318 llvm::Value *Result = CGF.EmitRuntimeCall(
6319 OMPBuilder.getOrCreateRuntimeFunction(
6320 CGM.getModule(), OMPRTL___kmpc_cancellationpoint),
6321 Args);
6322 // if (__kmpc_cancellationpoint()) {
6323 // call i32 @__kmpc_cancel_barrier( // for parallel cancellation only
6324 // exit from construct;
6325 // }
6326 llvm::BasicBlock *ExitBB = CGF.createBasicBlock(".cancel.exit");
6327 llvm::BasicBlock *ContBB = CGF.createBasicBlock(".cancel.continue");
6328 llvm::Value *Cmp = CGF.Builder.CreateIsNotNull(Result);
6329 CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
6330 CGF.EmitBlock(ExitBB);
6331 if (CancelRegion == OMPD_parallel)
6332 emitBarrierCall(CGF, Loc, OMPD_unknown, /*EmitChecks=*/false);
6333 // exit from construct;
6334 CodeGenFunction::JumpDest CancelDest =
6335 CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
6336 CGF.EmitBranchThroughCleanup(CancelDest);
6337 CGF.EmitBlock(ContBB, /*IsFinished=*/true);
6338 }
6339 }
6340}
6341
6342void CGOpenMPRuntime::emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
6343 const Expr *IfCond,
6344 OpenMPDirectiveKind CancelRegion) {
6345 if (!CGF.HaveInsertPoint())
6346 return;
6347 // Build call kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid,
6348 // kmp_int32 cncl_kind);
6349 auto &M = CGM.getModule();
6350 if (auto *OMPRegionInfo =
6351 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
6352 auto &&ThenGen = [this, &M, Loc, CancelRegion,
6353 OMPRegionInfo](CodeGenFunction &CGF, PrePostActionTy &) {
6354 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
6355 llvm::Value *Args[] = {
6356 RT.emitUpdateLocation(CGF, Loc), RT.getThreadID(CGF, Loc),
6357 CGF.Builder.getInt32(getCancellationKind(CancelRegion))};
6358 // Ignore return result until untied tasks are supported.
6359 llvm::Value *Result = CGF.EmitRuntimeCall(
6360 OMPBuilder.getOrCreateRuntimeFunction(M, OMPRTL___kmpc_cancel), Args);
6361 // if (__kmpc_cancel()) {
6362 // call i32 @__kmpc_cancel_barrier( // for parallel cancellation only
6363 // exit from construct;
6364 // }
6365 llvm::BasicBlock *ExitBB = CGF.createBasicBlock(".cancel.exit");
6366 llvm::BasicBlock *ContBB = CGF.createBasicBlock(".cancel.continue");
6367 llvm::Value *Cmp = CGF.Builder.CreateIsNotNull(Result);
6368 CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
6369 CGF.EmitBlock(ExitBB);
6370 if (CancelRegion == OMPD_parallel)
6371 RT.emitBarrierCall(CGF, Loc, OMPD_unknown, /*EmitChecks=*/false);
6372 // exit from construct;
6373 CodeGenFunction::JumpDest CancelDest =
6374 CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
6375 CGF.EmitBranchThroughCleanup(CancelDest);
6376 CGF.EmitBlock(ContBB, /*IsFinished=*/true);
6377 };
6378 if (IfCond) {
6379 emitIfClause(CGF, IfCond, ThenGen,
6380 [](CodeGenFunction &, PrePostActionTy &) {});
6381 } else {
6382 RegionCodeGenTy ThenRCG(ThenGen);
6383 ThenRCG(CGF);
6384 }
6385 }
6386}
6387
6388namespace {
6389/// Cleanup action for uses_allocators support.
6390class OMPUsesAllocatorsActionTy final : public PrePostActionTy {
6391 ArrayRef<std::pair<const Expr *, const Expr *>> Allocators;
6392
6393public:
6394 OMPUsesAllocatorsActionTy(
6395 ArrayRef<std::pair<const Expr *, const Expr *>> Allocators)
6396 : Allocators(Allocators) {}
6397 void Enter(CodeGenFunction &CGF) override {
6398 if (!CGF.HaveInsertPoint())
6399 return;
6400 for (const auto &AllocatorData : Allocators) {
6401 CGF.CGM.getOpenMPRuntime().emitUsesAllocatorsInit(
6402 CGF, AllocatorData.first, AllocatorData.second);
6403 }
6404 }
6405 void Exit(CodeGenFunction &CGF) override {
6406 if (!CGF.HaveInsertPoint())
6407 return;
6408 for (const auto &AllocatorData : Allocators) {
6409 CGF.CGM.getOpenMPRuntime().emitUsesAllocatorsFini(CGF,
6410 AllocatorData.first);
6411 }
6412 }
6413};
6414} // namespace
6415
6416void CGOpenMPRuntime::emitTargetOutlinedFunction(
6417 const OMPExecutableDirective &D, StringRef ParentName,
6418 llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
6419 bool IsOffloadEntry, const RegionCodeGenTy &CodeGen) {
6420 assert(!ParentName.empty() && "Invalid target region parent name!")(static_cast<void> (0));
6421 HasEmittedTargetRegion = true;
6422 SmallVector<std::pair<const Expr *, const Expr *>, 4> Allocators;
6423 for (const auto *C : D.getClausesOfKind<OMPUsesAllocatorsClause>()) {
6424 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
6425 const OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
6426 if (!D.AllocatorTraits)
6427 continue;
6428 Allocators.emplace_back(D.Allocator, D.AllocatorTraits);
6429 }
6430 }
6431 OMPUsesAllocatorsActionTy UsesAllocatorAction(Allocators);
6432 CodeGen.setAction(UsesAllocatorAction);
6433 emitTargetOutlinedFunctionHelper(D, ParentName, OutlinedFn, OutlinedFnID,
6434 IsOffloadEntry, CodeGen);
6435}
6436
6437void CGOpenMPRuntime::emitUsesAllocatorsInit(CodeGenFunction &CGF,
6438 const Expr *Allocator,
6439 const Expr *AllocatorTraits) {
6440 llvm::Value *ThreadId = getThreadID(CGF, Allocator->getExprLoc());
6441 ThreadId = CGF.Builder.CreateIntCast(ThreadId, CGF.IntTy, /*isSigned=*/true);
6442 // Use default memspace handle.
6443 llvm::Value *MemSpaceHandle = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
6444 llvm::Value *NumTraits = llvm::ConstantInt::get(
6445 CGF.IntTy, cast<ConstantArrayType>(
6446 AllocatorTraits->getType()->getAsArrayTypeUnsafe())
6447 ->getSize()
6448 .getLimitedValue());
6449 LValue AllocatorTraitsLVal = CGF.EmitLValue(AllocatorTraits);
6450 Address Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
6451 AllocatorTraitsLVal.getAddress(CGF), CGF.VoidPtrPtrTy);
6452 AllocatorTraitsLVal = CGF.MakeAddrLValue(Addr, CGF.getContext().VoidPtrTy,
6453 AllocatorTraitsLVal.getBaseInfo(),
6454 AllocatorTraitsLVal.getTBAAInfo());
6455 llvm::Value *Traits =
6456 CGF.EmitLoadOfScalar(AllocatorTraitsLVal, AllocatorTraits->getExprLoc());
6457
6458 llvm::Value *AllocatorVal =
6459 CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
6460 CGM.getModule(), OMPRTL___kmpc_init_allocator),
6461 {ThreadId, MemSpaceHandle, NumTraits, Traits});
6462 // Store to allocator.
6463 CGF.EmitVarDecl(*cast<VarDecl>(
6464 cast<DeclRefExpr>(Allocator->IgnoreParenImpCasts())->getDecl()));
6465 LValue AllocatorLVal = CGF.EmitLValue(Allocator->IgnoreParenImpCasts());
6466 AllocatorVal =
6467 CGF.EmitScalarConversion(AllocatorVal, CGF.getContext().VoidPtrTy,
6468 Allocator->getType(), Allocator->getExprLoc());
6469 CGF.EmitStoreOfScalar(AllocatorVal, AllocatorLVal);
6470}
6471
6472void CGOpenMPRuntime::emitUsesAllocatorsFini(CodeGenFunction &CGF,
6473 const Expr *Allocator) {
6474 llvm::Value *ThreadId = getThreadID(CGF, Allocator->getExprLoc());
6475 ThreadId = CGF.Builder.CreateIntCast(ThreadId, CGF.IntTy, /*isSigned=*/true);
6476 LValue AllocatorLVal = CGF.EmitLValue(Allocator->IgnoreParenImpCasts());
6477 llvm::Value *AllocatorVal =
6478 CGF.EmitLoadOfScalar(AllocatorLVal, Allocator->getExprLoc());
6479 AllocatorVal = CGF.EmitScalarConversion(AllocatorVal, Allocator->getType(),
6480 CGF.getContext().VoidPtrTy,
6481 Allocator->getExprLoc());
6482 (void)CGF.EmitRuntimeCall(
6483 OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(),
6484 OMPRTL___kmpc_destroy_allocator),
6485 {ThreadId, AllocatorVal});
6486}
6487
6488void CGOpenMPRuntime::emitTargetOutlinedFunctionHelper(
6489 const OMPExecutableDirective &D, StringRef ParentName,
6490 llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
6491 bool IsOffloadEntry, const RegionCodeGenTy &CodeGen) {
6492 // Create a unique name for the entry function using the source location
6493 // information of the current target region. The name will be something like:
6494 //
6495 // __omp_offloading_DD_FFFF_PP_lBB
6496 //
6497 // where DD_FFFF is an ID unique to the file (device and file IDs), PP is the
6498 // mangled name of the function that encloses the target region and BB is the
6499 // line number of the target region.
6500
6501 unsigned DeviceID;
6502 unsigned FileID;
6503 unsigned Line;
6504 getTargetEntryUniqueInfo(CGM.getContext(), D.getBeginLoc(), DeviceID, FileID,
6505 Line);
6506 SmallString<64> EntryFnName;
6507 {
6508 llvm::raw_svector_ostream OS(EntryFnName);
6509 OS << "__omp_offloading" << llvm::format("_%x", DeviceID)
6510 << llvm::format("_%x_", FileID) << ParentName << "_l" << Line;
6511 }
6512
6513 const CapturedStmt &CS = *D.getCapturedStmt(OMPD_target);
6514
6515 CodeGenFunction CGF(CGM, true);
6516 CGOpenMPTargetRegionInfo CGInfo(CS, CodeGen, EntryFnName);
6517 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
6518
6519 OutlinedFn = CGF.GenerateOpenMPCapturedStmtFunction(CS, D.getBeginLoc());
6520
6521 // If this target outline function is not an offload entry, we don't need to
6522 // register it.
6523 if (!IsOffloadEntry)
6524 return;
6525
6526 // The target region ID is used by the runtime library to identify the current
6527 // target region, so it only has to be unique and not necessarily point to
6528 // anything. It could be the pointer to the outlined function that implements
6529 // the target region, but we aren't using that so that the compiler doesn't
6530 // need to keep that, and could therefore inline the host function if proven
6531 // worthwhile during optimization. In the other hand, if emitting code for the
6532 // device, the ID has to be the function address so that it can retrieved from
6533 // the offloading entry and launched by the runtime library. We also mark the
6534 // outlined function to have external linkage in case we are emitting code for
6535 // the device, because these functions will be entry points to the device.
6536
6537 if (CGM.getLangOpts().OpenMPIsDevice) {
6538 OutlinedFnID = llvm::ConstantExpr::getBitCast(OutlinedFn, CGM.Int8PtrTy);
6539 OutlinedFn->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
6540 OutlinedFn->setDSOLocal(false);
6541 if (CGM.getTriple().isAMDGCN())
6542 OutlinedFn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL);
6543 } else {
6544 std::string Name = getName({EntryFnName, "region_id"});
6545 OutlinedFnID = new llvm::GlobalVariable(
6546 CGM.getModule(), CGM.Int8Ty, /*isConstant=*/true,
6547 llvm::GlobalValue::WeakAnyLinkage,
6548 llvm::Constant::getNullValue(CGM.Int8Ty), Name);
6549 }
6550
6551 // Register the information for the entry associated with this target region.
6552 OffloadEntriesInfoManager.registerTargetRegionEntryInfo(
6553 DeviceID, FileID, ParentName, Line, OutlinedFn, OutlinedFnID,
6554 OffloadEntriesInfoManagerTy::OMPTargetRegionEntryTargetRegion);
6555
6556 // Add NumTeams and ThreadLimit attributes to the outlined GPU function
6557 int32_t DefaultValTeams = -1;
6558 getNumTeamsExprForTargetDirective(CGF, D, DefaultValTeams);
6559 if (DefaultValTeams > 0) {
6560 OutlinedFn->addFnAttr("omp_target_num_teams",
6561 std::to_string(DefaultValTeams));
6562 }
6563 int32_t DefaultValThreads = -1;
6564 getNumThreadsExprForTargetDirective(CGF, D, DefaultValThreads);
6565 if (DefaultValThreads > 0) {
6566 OutlinedFn->addFnAttr("omp_target_thread_limit",
6567 std::to_string(DefaultValThreads));
6568 }
6569}
6570
6571/// Checks if the expression is constant or does not have non-trivial function
6572/// calls.
6573static bool isTrivial(ASTContext &Ctx, const Expr * E) {
6574 // We can skip constant expressions.
6575 // We can skip expressions with trivial calls or simple expressions.
6576 return (E->isEvaluatable(Ctx, Expr::SE_AllowUndefinedBehavior) ||
6577 !E->hasNonTrivialCall(Ctx)) &&
6578 !E->HasSideEffects(Ctx, /*IncludePossibleEffects=*/true);
6579}
6580
6581const Stmt *CGOpenMPRuntime::getSingleCompoundChild(ASTContext &Ctx,
6582 const Stmt *Body) {
6583 const Stmt *Child = Body->IgnoreContainers();
6584 while (const auto *C = dyn_cast_or_null<CompoundStmt>(Child)) {
6585 Child = nullptr;
6586 for (const Stmt *S : C->body()) {
6587 if (const auto *E = dyn_cast<Expr>(S)) {
6588 if (isTrivial(Ctx, E))
6589 continue;
6590 }
6591 // Some of the statements can be ignored.
6592 if (isa<AsmStmt>(S) || isa<NullStmt>(S) || isa<OMPFlushDirective>(S) ||
6593 isa<OMPBarrierDirective>(S) || isa<OMPTaskyieldDirective>(S))
6594 continue;
6595 // Analyze declarations.
6596 if (const auto *DS = dyn_cast<DeclStmt>(S)) {
6597 if (llvm::all_of(DS->decls(), [](const Decl *D) {
6598 if (isa<EmptyDecl>(D) || isa<DeclContext>(D) ||
6599 isa<TypeDecl>(D) || isa<PragmaCommentDecl>(D) ||
6600 isa<PragmaDetectMismatchDecl>(D) || isa<UsingDecl>(D) ||
6601 isa<UsingDirectiveDecl>(D) ||
6602 isa<OMPDeclareReductionDecl>(D) ||
6603 isa<OMPThreadPrivateDecl>(D) || isa<OMPAllocateDecl>(D))
6604 return true;
6605 const auto *VD = dyn_cast<VarDecl>(D);
6606 if (!VD)
6607 return false;
6608 return VD->hasGlobalStorage() || !VD->isUsed();
6609 }))
6610 continue;
6611 }
6612 // Found multiple children - cannot get the one child only.
6613 if (Child)
6614 return nullptr;
6615 Child = S;
6616 }
6617 if (Child)
6618 Child = Child->IgnoreContainers();
6619 }
6620 return Child;
6621}
6622
6623const Expr *CGOpenMPRuntime::getNumTeamsExprForTargetDirective(
6624 CodeGenFunction &CGF, const OMPExecutableDirective &D,
6625 int32_t &DefaultVal) {
6626
6627 OpenMPDirectiveKind DirectiveKind = D.getDirectiveKind();
6628 assert(isOpenMPTargetExecutionDirective(DirectiveKind) &&(static_cast<void> (0))
6629 "Expected target-based executable directive.")(static_cast<void> (0));
6630 switch (DirectiveKind) {
6631 case OMPD_target: {
6632 const auto *CS = D.getInnermostCapturedStmt();
6633 const auto *Body =
6634 CS->getCapturedStmt()->IgnoreContainers(/*IgnoreCaptured=*/true);
6635 const Stmt *ChildStmt =
6636 CGOpenMPRuntime::getSingleCompoundChild(CGF.getContext(), Body);
6637 if (const auto *NestedDir =
6638 dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
6639 if (isOpenMPTeamsDirective(NestedDir->getDirectiveKind())) {
6640 if (NestedDir->hasClausesOfKind<OMPNumTeamsClause>()) {
6641 const Expr *NumTeams =
6642 NestedDir->getSingleClause<OMPNumTeamsClause>()->getNumTeams();
6643 if (NumTeams->isIntegerConstantExpr(CGF.getContext()))
6644 if (auto Constant =
6645 NumTeams->getIntegerConstantExpr(CGF.getContext()))
6646 DefaultVal = Constant->getExtValue();
6647 return NumTeams;
6648 }
6649 DefaultVal = 0;
6650 return nullptr;
6651 }
6652 if (isOpenMPParallelDirective(NestedDir->getDirectiveKind()) ||
6653 isOpenMPSimdDirective(NestedDir->getDirectiveKind())) {
6654 DefaultVal = 1;
6655 return nullptr;
6656 }
6657 DefaultVal = 1;
6658 return nullptr;
6659 }
6660 // A value of -1 is used to check if we need to emit no teams region
6661 DefaultVal = -1;
6662 return nullptr;
6663 }
6664 case OMPD_target_teams:
6665 case OMPD_target_teams_distribute:
6666 case OMPD_target_teams_distribute_simd:
6667 case OMPD_target_teams_distribute_parallel_for:
6668 case OMPD_target_teams_distribute_parallel_for_simd: {
6669 if (D.hasClausesOfKind<OMPNumTeamsClause>()) {
6670 const Expr *NumTeams =
6671 D.getSingleClause<OMPNumTeamsClause>()->getNumTeams();
6672 if (NumTeams->isIntegerConstantExpr(CGF.getContext()))
6673 if (auto Constant = NumTeams->getIntegerConstantExpr(CGF.getContext()))
6674 DefaultVal = Constant->getExtValue();
6675 return NumTeams;
6676 }
6677 DefaultVal = 0;
6678 return nullptr;
6679 }
6680 case OMPD_target_parallel:
6681 case OMPD_target_parallel_for:
6682 case OMPD_target_parallel_for_simd:
6683 case OMPD_target_simd:
6684 DefaultVal = 1;
6685 return nullptr;
6686 case OMPD_parallel:
6687 case OMPD_for:
6688 case OMPD_parallel_for:
6689 case OMPD_parallel_master:
6690 case OMPD_parallel_sections:
6691 case OMPD_for_simd:
6692 case OMPD_parallel_for_simd:
6693 case OMPD_cancel:
6694 case OMPD_cancellation_point:
6695 case OMPD_ordered:
6696 case OMPD_threadprivate:
6697 case OMPD_allocate:
6698 case OMPD_task:
6699 case OMPD_simd:
6700 case OMPD_tile:
6701 case OMPD_unroll:
6702 case OMPD_sections:
6703 case OMPD_section:
6704 case OMPD_single:
6705 case OMPD_master:
6706 case OMPD_critical:
6707 case OMPD_taskyield:
6708 case OMPD_barrier:
6709 case OMPD_taskwait:
6710 case OMPD_taskgroup:
6711 case OMPD_atomic:
6712 case OMPD_flush:
6713 case OMPD_depobj:
6714 case OMPD_scan:
6715 case OMPD_teams:
6716 case OMPD_target_data:
6717 case OMPD_target_exit_data:
6718 case OMPD_target_enter_data:
6719 case OMPD_distribute:
6720 case OMPD_distribute_simd:
6721 case OMPD_distribute_parallel_for:
6722 case OMPD_distribute_parallel_for_simd:
6723 case OMPD_teams_distribute:
6724 case OMPD_teams_distribute_simd:
6725 case OMPD_teams_distribute_parallel_for:
6726 case OMPD_teams_distribute_parallel_for_simd:
6727 case OMPD_target_update:
6728 case OMPD_declare_simd:
6729 case OMPD_declare_variant:
6730 case OMPD_begin_declare_variant:
6731 case OMPD_end_declare_variant:
6732 case OMPD_declare_target:
6733 case OMPD_end_declare_target:
6734 case OMPD_declare_reduction:
6735 case OMPD_declare_mapper:
6736 case OMPD_taskloop:
6737 case OMPD_taskloop_simd:
6738 case OMPD_master_taskloop:
6739 case OMPD_master_taskloop_simd:
6740 case OMPD_parallel_master_taskloop:
6741 case OMPD_parallel_master_taskloop_simd:
6742 case OMPD_requires:
6743 case OMPD_unknown:
6744 break;
6745 default:
6746 break;
6747 }
6748 llvm_unreachable("Unexpected directive kind.")__builtin_unreachable();
6749}
6750
6751llvm::Value *CGOpenMPRuntime::emitNumTeamsForTargetDirective(
6752 CodeGenFunction &CGF, const OMPExecutableDirective &D) {
6753 assert(!CGF.getLangOpts().OpenMPIsDevice &&(static_cast<void> (0))
6754 "Clauses associated with the teams directive expected to be emitted "(static_cast<void> (0))
6755 "only for the host!")(static_cast<void> (0));
6756 CGBuilderTy &Bld = CGF.Builder;
6757 int32_t DefaultNT = -1;
6758 const Expr *NumTeams = getNumTeamsExprForTargetDirective(CGF, D, DefaultNT);
6759 if (NumTeams != nullptr) {
6760 OpenMPDirectiveKind DirectiveKind = D.getDirectiveKind();
6761
6762 switch (DirectiveKind) {
6763 case OMPD_target: {
6764 const auto *CS = D.getInnermostCapturedStmt();
6765 CGOpenMPInnerExprInfo CGInfo(CGF, *CS);
6766 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
6767 llvm::Value *NumTeamsVal = CGF.EmitScalarExpr(NumTeams,
6768 /*IgnoreResultAssign*/ true);
6769 return Bld.CreateIntCast(NumTeamsVal, CGF.Int32Ty,
6770 /*isSigned=*/true);
6771 }
6772 case OMPD_target_teams:
6773 case OMPD_target_teams_distribute:
6774 case OMPD_target_teams_distribute_simd:
6775 case OMPD_target_teams_distribute_parallel_for:
6776 case OMPD_target_teams_distribute_parallel_for_simd: {
6777 CodeGenFunction::RunCleanupsScope NumTeamsScope(CGF);
6778 llvm::Value *NumTeamsVal = CGF.EmitScalarExpr(NumTeams,
6779 /*IgnoreResultAssign*/ true);
6780 return Bld.CreateIntCast(NumTeamsVal, CGF.Int32Ty,
6781 /*isSigned=*/true);
6782 }
6783 default:
6784 break;
6785 }
6786 } else if (DefaultNT == -1) {
6787 return nullptr;
6788 }
6789
6790 return Bld.getInt32(DefaultNT);
6791}
6792
6793static llvm::Value *getNumThreads(CodeGenFunction &CGF, const CapturedStmt *CS,
6794 llvm::Value *DefaultThreadLimitVal) {
6795 const Stmt *Child = CGOpenMPRuntime::getSingleCompoundChild(
6796 CGF.getContext(), CS->getCapturedStmt());
6797 if (const auto *Dir = dyn_cast_or_null<OMPExecutableDirective>(Child)) {
6798 if (isOpenMPParallelDirective(Dir->getDirectiveKind())) {
6799 llvm::Value *NumThreads = nullptr;
6800 llvm::Value *CondVal = nullptr;
6801 // Handle if clause. If if clause present, the number of threads is
6802 // calculated as <cond> ? (<numthreads> ? <numthreads> : 0 ) : 1.
6803 if (Dir->hasClausesOfKind<OMPIfClause>()) {
6804 CGOpenMPInnerExprInfo CGInfo(CGF, *CS);
6805 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
6806 const OMPIfClause *IfClause = nullptr;
6807 for (const auto *C : Dir->getClausesOfKind<OMPIfClause>()) {
6808 if (C->getNameModifier() == OMPD_unknown ||
6809 C->getNameModifier() == OMPD_parallel) {
6810 IfClause = C;
6811 break;
6812 }
6813 }
6814 if (IfClause) {
6815 const Expr *Cond = IfClause->getCondition();
6816 bool Result;
6817 if (Cond->EvaluateAsBooleanCondition(Result, CGF.getContext())) {
6818 if (!Result)
6819 return CGF.Builder.getInt32(1);
6820 } else {
6821 CodeGenFunction::LexicalScope Scope(CGF, Cond->getSourceRange());
6822 if (const auto *PreInit =
6823 cast_or_null<DeclStmt>(IfClause->getPreInitStmt())) {
6824 for (const auto *I : PreInit->decls()) {
6825 if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
6826 CGF.EmitVarDecl(cast<VarDecl>(*I));
6827 } else {
6828 CodeGenFunction::AutoVarEmission Emission =
6829 CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
6830 CGF.EmitAutoVarCleanups(Emission);
6831 }
6832 }
6833 }
6834 CondVal = CGF.EvaluateExprAsBool(Cond);
6835 }
6836 }
6837 }
6838 // Check the value of num_threads clause iff if clause was not specified
6839 // or is not evaluated to false.
6840 if (Dir->hasClausesOfKind<OMPNumThreadsClause>()) {
6841 CGOpenMPInnerExprInfo CGInfo(CGF, *CS);
6842 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
6843 const auto *NumThreadsClause =
6844 Dir->getSingleClause<OMPNumThreadsClause>();
6845 CodeGenFunction::LexicalScope Scope(
6846 CGF, NumThreadsClause->getNumThreads()->getSourceRange());
6847 if (const auto *PreInit =
6848 cast_or_null<DeclStmt>(NumThreadsClause->getPreInitStmt())) {
6849 for (const auto *I : PreInit->decls()) {
6850 if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
6851 CGF.EmitVarDecl(cast<VarDecl>(*I));
6852 } else {
6853 CodeGenFunction::AutoVarEmission Emission =
6854 CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
6855 CGF.EmitAutoVarCleanups(Emission);
6856 }
6857 }
6858 }
6859 NumThreads = CGF.EmitScalarExpr(NumThreadsClause->getNumThreads());
6860 NumThreads = CGF.Builder.CreateIntCast(NumThreads, CGF.Int32Ty,
6861 /*isSigned=*/false);
6862 if (DefaultThreadLimitVal)
6863 NumThreads = CGF.Builder.CreateSelect(
6864 CGF.Builder.CreateICmpULT(DefaultThreadLimitVal, NumThreads),
6865 DefaultThreadLimitVal, NumThreads);
6866 } else {
6867 NumThreads = DefaultThreadLimitVal ? DefaultThreadLimitVal
6868 : CGF.Builder.getInt32(0);
6869 }
6870 // Process condition of the if clause.
6871 if (CondVal) {
6872 NumThreads = CGF.Builder.CreateSelect(CondVal, NumThreads,
6873 CGF.Builder.getInt32(1));
6874 }
6875 return NumThreads;
6876 }
6877 if (isOpenMPSimdDirective(Dir->getDirectiveKind()))
6878 return CGF.Builder.getInt32(1);
6879 return DefaultThreadLimitVal;
6880 }
6881 return DefaultThreadLimitVal ? DefaultThreadLimitVal
6882 : CGF.Builder.getInt32(0);
6883}
6884
6885const Expr *CGOpenMPRuntime::getNumThreadsExprForTargetDirective(
6886 CodeGenFunction &CGF, const OMPExecutableDirective &D,
6887 int32_t &DefaultVal) {
6888 OpenMPDirectiveKind DirectiveKind = D.getDirectiveKind();
6889 assert(isOpenMPTargetExecutionDirective(DirectiveKind) &&(static_cast<void> (0))
6890 "Expected target-based executable directive.")(static_cast<void> (0));
6891
6892 switch (DirectiveKind) {
6893 case OMPD_target:
6894 // Teams have no clause thread_limit
6895 return nullptr;
6896 case OMPD_target_teams:
6897 case OMPD_target_teams_distribute:
6898 if (D.hasClausesOfKind<OMPThreadLimitClause>()) {
6899 const auto *ThreadLimitClause = D.getSingleClause<OMPThreadLimitClause>();
6900 const Expr *ThreadLimit = ThreadLimitClause->getThreadLimit();
6901 if (ThreadLimit->isIntegerConstantExpr(CGF.getContext()))
6902 if (auto Constant =
6903 ThreadLimit->getIntegerConstantExpr(CGF.getContext()))
6904 DefaultVal = Constant->getExtValue();
6905 return ThreadLimit;
6906 }
6907 return nullptr;
6908 case OMPD_target_parallel:
6909 case OMPD_target_parallel_for:
6910 case OMPD_target_parallel_for_simd:
6911 case OMPD_target_teams_distribute_parallel_for:
6912 case OMPD_target_teams_distribute_parallel_for_simd: {
6913 Expr *ThreadLimit = nullptr;
6914 Expr *NumThreads = nullptr;
6915 if (D.hasClausesOfKind<OMPThreadLimitClause>()) {
6916 const auto *ThreadLimitClause = D.getSingleClause<OMPThreadLimitClause>();
6917 ThreadLimit = ThreadLimitClause->getThreadLimit();
6918 if (ThreadLimit->isIntegerConstantExpr(CGF.getContext()))
6919 if (auto Constant =
6920 ThreadLimit->getIntegerConstantExpr(CGF.getContext()))
6921 DefaultVal = Constant->getExtValue();
6922 }
6923 if (D.hasClausesOfKind<OMPNumThreadsClause>()) {
6924 const auto *NumThreadsClause = D.getSingleClause<OMPNumThreadsClause>();
6925 NumThreads = NumThreadsClause->getNumThreads();
6926 if (NumThreads->isIntegerConstantExpr(CGF.getContext())) {
6927 if (auto Constant =
6928 NumThreads->getIntegerConstantExpr(CGF.getContext())) {
6929 if (Constant->getExtValue() < DefaultVal) {
6930 DefaultVal = Constant->getExtValue();
6931 ThreadLimit = NumThreads;
6932 }
6933 }
6934 }
6935 }
6936 return ThreadLimit;
6937 }
6938 case OMPD_target_teams_distribute_simd:
6939 case OMPD_target_simd:
6940 DefaultVal = 1;
6941 return nullptr;
6942 case OMPD_parallel:
6943 case OMPD_for:
6944 case OMPD_parallel_for:
6945 case OMPD_parallel_master:
6946 case OMPD_parallel_sections:
6947 case OMPD_for_simd:
6948 case OMPD_parallel_for_simd:
6949 case OMPD_cancel:
6950 case OMPD_cancellation_point:
6951 case OMPD_ordered:
6952 case OMPD_threadprivate:
6953 case OMPD_allocate:
6954 case OMPD_task:
6955 case OMPD_simd:
6956 case OMPD_tile:
6957 case OMPD_unroll:
6958 case OMPD_sections:
6959 case OMPD_section:
6960 case OMPD_single:
6961 case OMPD_master:
6962 case OMPD_critical:
6963 case OMPD_taskyield:
6964 case OMPD_barrier:
6965 case OMPD_taskwait:
6966 case OMPD_taskgroup:
6967 case OMPD_atomic:
6968 case OMPD_flush:
6969 case OMPD_depobj:
6970 case OMPD_scan:
6971 case OMPD_teams:
6972 case OMPD_target_data:
6973 case OMPD_target_exit_data:
6974 case OMPD_target_enter_data:
6975 case OMPD_distribute:
6976 case OMPD_distribute_simd:
6977 case OMPD_distribute_parallel_for:
6978 case OMPD_distribute_parallel_for_simd:
6979 case OMPD_teams_distribute:
6980 case OMPD_teams_distribute_simd:
6981 case OMPD_teams_distribute_parallel_for:
6982 case OMPD_teams_distribute_parallel_for_simd:
6983 case OMPD_target_update:
6984 case OMPD_declare_simd:
6985 case OMPD_declare_variant:
6986 case OMPD_begin_declare_variant:
6987 case OMPD_end_declare_variant:
6988 case OMPD_declare_target:
6989 case OMPD_end_declare_target:
6990 case OMPD_declare_reduction:
6991 case OMPD_declare_mapper:
6992 case OMPD_taskloop:
6993 case OMPD_taskloop_simd:
6994 case OMPD_master_taskloop:
6995 case OMPD_master_taskloop_simd:
6996 case OMPD_parallel_master_taskloop:
6997 case OMPD_parallel_master_taskloop_simd:
6998 case OMPD_requires:
6999 case OMPD_unknown:
7000 break;
7001 default:
7002 break;
7003 }
7004 llvm_unreachable("Unsupported directive kind.")__builtin_unreachable();
7005}
7006
7007llvm::Value *CGOpenMPRuntime::emitNumThreadsForTargetDirective(
7008 CodeGenFunction &CGF, const OMPExecutableDirective &D) {
7009 assert(!CGF.getLangOpts().OpenMPIsDevice &&(static_cast<void> (0))
7010 "Clauses associated with the teams directive expected to be emitted "(static_cast<void> (0))
7011 "only for the host!")(static_cast<void> (0));
7012 OpenMPDirectiveKind DirectiveKind = D.getDirectiveKind();
7013 assert(isOpenMPTargetExecutionDirective(DirectiveKind) &&(static_cast<void> (0))
7014 "Expected target-based executable directive.")(static_cast<void> (0));
7015 CGBuilderTy &Bld = CGF.Builder;
7016 llvm::Value *ThreadLimitVal = nullptr;
7017 llvm::Value *NumThreadsVal = nullptr;
7018 switch (DirectiveKind) {
7019 case OMPD_target: {
7020 const CapturedStmt *CS = D.getInnermostCapturedStmt();
7021 if (llvm::Value *NumThreads = getNumThreads(CGF, CS, ThreadLimitVal))
7022 return NumThreads;
7023 const Stmt *Child = CGOpenMPRuntime::getSingleCompoundChild(
7024 CGF.getContext(), CS->getCapturedStmt());
7025 if (const auto *Dir = dyn_cast_or_null<OMPExecutableDirective>(Child)) {
7026 if (Dir->hasClausesOfKind<OMPThreadLimitClause>()) {
7027 CGOpenMPInnerExprInfo CGInfo(CGF, *CS);
7028 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
7029 const auto *ThreadLimitClause =
7030 Dir->getSingleClause<OMPThreadLimitClause>();
7031 CodeGenFunction::LexicalScope Scope(
7032 CGF, ThreadLimitClause->getThreadLimit()->getSourceRange());
7033 if (const auto *PreInit =
7034 cast_or_null<DeclStmt>(ThreadLimitClause->getPreInitStmt())) {
7035 for (const auto *I : PreInit->decls()) {
7036 if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
7037 CGF.EmitVarDecl(cast<VarDecl>(*I));
7038 } else {
7039 CodeGenFunction::AutoVarEmission Emission =
7040 CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
7041 CGF.EmitAutoVarCleanups(Emission);
7042 }
7043 }
7044 }
7045 llvm::Value *ThreadLimit = CGF.EmitScalarExpr(
7046 ThreadLimitClause->getThreadLimit(), /*IgnoreResultAssign=*/true);
7047 ThreadLimitVal =
7048 Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty, /*isSigned=*/false);
7049 }
7050 if (isOpenMPTeamsDirective(Dir->getDirectiveKind()) &&
7051 !isOpenMPDistributeDirective(Dir->getDirectiveKind())) {
7052 CS = Dir->getInnermostCapturedStmt();
7053 const Stmt *Child = CGOpenMPRuntime::getSingleCompoundChild(
7054 CGF.getContext(), CS->getCapturedStmt());
7055 Dir = dyn_cast_or_null<OMPExecutableDirective>(Child);
7056 }
7057 if (Dir && isOpenMPDistributeDirective(Dir->getDirectiveKind()) &&
7058 !isOpenMPSimdDirective(Dir->getDirectiveKind())) {
7059 CS = Dir->getInnermostCapturedStmt();
7060 if (llvm::Value *NumThreads = getNumThreads(CGF, CS, ThreadLimitVal))
7061 return NumThreads;
7062 }
7063 if (Dir && isOpenMPSimdDirective(Dir->getDirectiveKind()))
7064 return Bld.getInt32(1);
7065 }
7066 return ThreadLimitVal ? ThreadLimitVal : Bld.getInt32(0);
7067 }
7068 case OMPD_target_teams: {
7069 if (D.hasClausesOfKind<OMPThreadLimitClause>()) {
7070 CodeGenFunction::RunCleanupsScope ThreadLimitScope(CGF);
7071 const auto *ThreadLimitClause = D.getSingleClause<OMPThreadLimitClause>();
7072 llvm::Value *ThreadLimit = CGF.EmitScalarExpr(
7073 ThreadLimitClause->getThreadLimit(), /*IgnoreResultAssign=*/true);
7074 ThreadLimitVal =
7075 Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty, /*isSigned=*/false);
7076 }
7077 const CapturedStmt *CS = D.getInnermostCapturedStmt();
7078 if (llvm::Value *NumThreads = getNumThreads(CGF, CS, ThreadLimitVal))
7079 return NumThreads;
7080 const Stmt *Child = CGOpenMPRuntime::getSingleCompoundChild(
7081 CGF.getContext(), CS->getCapturedStmt());
7082 if (const auto *Dir = dyn_cast_or_null<OMPExecutableDirective>(Child)) {
7083 if (Dir->getDirectiveKind() == OMPD_distribute) {
7084 CS = Dir->getInnermostCapturedStmt();
7085 if (llvm::Value *NumThreads = getNumThreads(CGF, CS, ThreadLimitVal))
7086 return NumThreads;
7087 }
7088 }
7089 return ThreadLimitVal ? ThreadLimitVal : Bld.getInt32(0);
7090 }
7091 case OMPD_target_teams_distribute:
7092 if (D.hasClausesOfKind<OMPThreadLimitClause>()) {
7093 CodeGenFunction::RunCleanupsScope ThreadLimitScope(CGF);
7094 const auto *ThreadLimitClause = D.getSingleClause<OMPThreadLimitClause>();
7095 llvm::Value *ThreadLimit = CGF.EmitScalarExpr(
7096 ThreadLimitClause->getThreadLimit(), /*IgnoreResultAssign=*/true);
7097 ThreadLimitVal =
7098 Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty, /*isSigned=*/false);
7099 }
7100 return getNumThreads(CGF, D.getInnermostCapturedStmt(), ThreadLimitVal);
7101 case OMPD_target_parallel:
7102 case OMPD_target_parallel_for:
7103 case OMPD_target_parallel_for_simd:
7104 case OMPD_target_teams_distribute_parallel_for:
7105 case OMPD_target_teams_distribute_parallel_for_simd: {
7106 llvm::Value *CondVal = nullptr;
7107 // Handle if clause. If if clause present, the number of threads is
7108 // calculated as <cond> ? (<numthreads> ? <numthreads> : 0 ) : 1.
7109 if (D.hasClausesOfKind<OMPIfClause>()) {
7110 const OMPIfClause *IfClause = nullptr;
7111 for (const auto *C : D.getClausesOfKind<OMPIfClause>()) {
7112 if (C->getNameModifier() == OMPD_unknown ||
7113 C->getNameModifier() == OMPD_parallel) {
7114 IfClause = C;
7115 break;
7116 }
7117 }
7118 if (IfClause) {
7119 const Expr *Cond = IfClause->getCondition();
7120 bool Result;
7121 if (Cond->EvaluateAsBooleanCondition(Result, CGF.getContext())) {
7122 if (!Result)
7123 return Bld.getInt32(1);
7124 } else {
7125 CodeGenFunction::RunCleanupsScope Scope(CGF);
7126 CondVal = CGF.EvaluateExprAsBool(Cond);
7127 }
7128 }
7129 }
7130 if (D.hasClausesOfKind<OMPThreadLimitClause>()) {
7131 CodeGenFunction::RunCleanupsScope ThreadLimitScope(CGF);
7132 const auto *ThreadLimitClause = D.getSingleClause<OMPThreadLimitClause>();
7133 llvm::Value *ThreadLimit = CGF.EmitScalarExpr(
7134 ThreadLimitClause->getThreadLimit(), /*IgnoreResultAssign=*/true);
7135 ThreadLimitVal =
7136 Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty, /*isSigned=*/false);
7137 }
7138 if (D.hasClausesOfKind<OMPNumThreadsClause>()) {
7139 CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
7140 const auto *NumThreadsClause = D.getSingleClause<OMPNumThreadsClause>();
7141 llvm::Value *NumThreads = CGF.EmitScalarExpr(
7142 NumThreadsClause->getNumThreads(), /*IgnoreResultAssign=*/true);
7143 NumThreadsVal =
7144 Bld.CreateIntCast(NumThreads, CGF.Int32Ty, /*isSigned=*/false);
7145 ThreadLimitVal = ThreadLimitVal
7146 ? Bld.CreateSelect(Bld.CreateICmpULT(NumThreadsVal,
7147 ThreadLimitVal),
7148 NumThreadsVal, ThreadLimitVal)
7149 : NumThreadsVal;
7150 }
7151 if (!ThreadLimitVal)
7152 ThreadLimitVal = Bld.getInt32(0);
7153 if (CondVal)
7154 return Bld.CreateSelect(CondVal, ThreadLimitVal, Bld.getInt32(1));
7155 return ThreadLimitVal;
7156 }
7157 case OMPD_target_teams_distribute_simd:
7158 case OMPD_target_simd:
7159 return Bld.getInt32(1);
7160 case OMPD_parallel:
7161 case OMPD_for:
7162 case OMPD_parallel_for:
7163 case OMPD_parallel_master:
7164 case OMPD_parallel_sections:
7165 case OMPD_for_simd:
7166 case OMPD_parallel_for_simd:
7167 case OMPD_cancel:
7168 case OMPD_cancellation_point:
7169 case OMPD_ordered:
7170 case OMPD_threadprivate:
7171 case OMPD_allocate:
7172 case OMPD_task:
7173 case OMPD_simd:
7174 case OMPD_tile:
7175 case OMPD_unroll:
7176 case OMPD_sections:
7177 case OMPD_section:
7178 case OMPD_single:
7179 case OMPD_master:
7180 case OMPD_critical:
7181 case OMPD_taskyield:
7182 case OMPD_barrier:
7183 case OMPD_taskwait:
7184 case OMPD_taskgroup:
7185 case OMPD_atomic:
7186 case OMPD_flush:
7187 case OMPD_depobj:
7188 case OMPD_scan:
7189 case OMPD_teams:
7190 case OMPD_target_data:
7191 case OMPD_target_exit_data:
7192 case OMPD_target_enter_data:
7193 case OMPD_distribute:
7194 case OMPD_distribute_simd:
7195 case OMPD_distribute_parallel_for:
7196 case OMPD_distribute_parallel_for_simd:
7197 case OMPD_teams_distribute:
7198 case OMPD_teams_distribute_simd:
7199 case OMPD_teams_distribute_parallel_for:
7200 case OMPD_teams_distribute_parallel_for_simd:
7201 case OMPD_target_update:
7202 case OMPD_declare_simd:
7203 case OMPD_declare_variant:
7204 case OMPD_begin_declare_variant:
7205 case OMPD_end_declare_variant:
7206 case OMPD_declare_target:
7207 case OMPD_end_declare_target:
7208 case OMPD_declare_reduction:
7209 case OMPD_declare_mapper:
7210 case OMPD_taskloop:
7211 case OMPD_taskloop_simd:
7212 case OMPD_master_taskloop:
7213 case OMPD_master_taskloop_simd:
7214 case OMPD_parallel_master_taskloop:
7215 case OMPD_parallel_master_taskloop_simd:
7216 case OMPD_requires:
7217 case OMPD_unknown:
7218 break;
7219 default:
7220 break;
7221 }
7222 llvm_unreachable("Unsupported directive kind.")__builtin_unreachable();
7223}
7224
7225namespace {
7226LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE()using ::llvm::BitmaskEnumDetail::operator~; using ::llvm::BitmaskEnumDetail
::operator|; using ::llvm::BitmaskEnumDetail::operator&; using
::llvm::BitmaskEnumDetail::operator^; using ::llvm::BitmaskEnumDetail
::operator|=; using ::llvm::BitmaskEnumDetail::operator&=
; using ::llvm::BitmaskEnumDetail::operator^=
;
7227
7228// Utility to handle information from clauses associated with a given
7229// construct that use mappable expressions (e.g. 'map' clause, 'to' clause).
7230// It provides a convenient interface to obtain the information and generate
7231// code for that information.
7232class MappableExprsHandler {
7233public:
7234 /// Values for bit flags used to specify the mapping type for
7235 /// offloading.
7236 enum OpenMPOffloadMappingFlags : uint64_t {
7237 /// No flags
7238 OMP_MAP_NONE = 0x0,
7239 /// Allocate memory on the device and move data from host to device.
7240 OMP_MAP_TO = 0x01,
7241 /// Allocate memory on the device and move data from device to host.
7242 OMP_MAP_FROM = 0x02,
7243 /// Always perform the requested mapping action on the element, even
7244 /// if it was already mapped before.
7245 OMP_MAP_ALWAYS = 0x04,
7246 /// Delete the element from the device environment, ignoring the
7247 /// current reference count associated with the element.
7248 OMP_MAP_DELETE = 0x08,
7249 /// The element being mapped is a pointer-pointee pair; both the
7250 /// pointer and the pointee should be mapped.
7251 OMP_MAP_PTR_AND_OBJ = 0x10,
7252 /// This flags signals that the base address of an entry should be
7253 /// passed to the target kernel as an argument.
7254 OMP_MAP_TARGET_PARAM = 0x20,
7255 /// Signal that the runtime library has to return the device pointer
7256 /// in the current position for the data being mapped. Used when we have the
7257 /// use_device_ptr or use_device_addr clause.
7258 OMP_MAP_RETURN_PARAM = 0x40,
7259 /// This flag signals that the reference being passed is a pointer to
7260 /// private data.
7261 OMP_MAP_PRIVATE = 0x80,
7262 /// Pass the element to the device by value.
7263 OMP_MAP_LITERAL = 0x100,
7264 /// Implicit map
7265 OMP_MAP_IMPLICIT = 0x200,
7266 /// Close is a hint to the runtime to allocate memory close to
7267 /// the target device.
7268 OMP_MAP_CLOSE = 0x400,
7269 /// 0x800 is reserved for compatibility with XLC.
7270 /// Produce a runtime error if the data is not already allocated.
7271 OMP_MAP_PRESENT = 0x1000,
7272 // Increment and decrement a separate reference counter so that the data
7273 // cannot be unmapped within the associated region. Thus, this flag is
7274 // intended to be used on 'target' and 'target data' directives because they
7275 // are inherently structured. It is not intended to be used on 'target
7276 // enter data' and 'target exit data' directives because they are inherently
7277 // dynamic.
7278 // This is an OpenMP extension for the sake of OpenACC support.
7279 OMP_MAP_OMPX_HOLD = 0x2000,
7280 /// Signal that the runtime library should use args as an array of
7281 /// descriptor_dim pointers and use args_size as dims. Used when we have
7282 /// non-contiguous list items in target update directive
7283 OMP_MAP_NON_CONTIG = 0x100000000000,
7284 /// The 16 MSBs of the flags indicate whether the entry is member of some
7285 /// struct/class.
7286 OMP_MAP_MEMBER_OF = 0xffff000000000000,
7287 LLVM_MARK_AS_BITMASK_ENUM(/* LargestFlag = */ OMP_MAP_MEMBER_OF)LLVM_BITMASK_LARGEST_ENUMERATOR = OMP_MAP_MEMBER_OF,
7288 };
7289
7290 /// Get the offset of the OMP_MAP_MEMBER_OF field.
7291 static unsigned getFlagMemberOffset() {
7292 unsigned Offset = 0;
7293 for (uint64_t Remain = OMP_MAP_MEMBER_OF; !(Remain & 1);
7294 Remain = Remain >> 1)
7295 Offset++;
7296 return Offset;
7297 }
7298
7299 /// Class that holds debugging information for a data mapping to be passed to
7300 /// the runtime library.
7301 class MappingExprInfo {
7302 /// The variable declaration used for the data mapping.
7303 const ValueDecl *MapDecl = nullptr;
7304 /// The original expression used in the map clause, or null if there is
7305 /// none.
7306 const Expr *MapExpr = nullptr;
7307
7308 public:
7309 MappingExprInfo(const ValueDecl *MapDecl, const Expr *MapExpr = nullptr)
7310 : MapDecl(MapDecl), MapExpr(MapExpr) {}
7311
7312 const ValueDecl *getMapDecl() const { return MapDecl; }
7313 const Expr *getMapExpr() const { return MapExpr; }
7314 };
7315
7316 /// Class that associates information with a base pointer to be passed to the
7317 /// runtime library.
7318 class BasePointerInfo {
7319 /// The base pointer.
7320 llvm::Value *Ptr = nullptr;
7321 /// The base declaration that refers to this device pointer, or null if
7322 /// there is none.
7323 const ValueDecl *DevPtrDecl = nullptr;
7324
7325 public:
7326 BasePointerInfo(llvm::Value *Ptr, const ValueDecl *DevPtrDecl = nullptr)
7327 : Ptr(Ptr), DevPtrDecl(DevPtrDecl) {}
7328 llvm::Value *operator*() const { return Ptr; }
7329 const ValueDecl *getDevicePtrDecl() const { return DevPtrDecl; }
7330 void setDevicePtrDecl(const ValueDecl *D) { DevPtrDecl = D; }
7331 };
7332
7333 using MapExprsArrayTy = SmallVector<MappingExprInfo, 4>;
7334 using MapBaseValuesArrayTy = SmallVector<BasePointerInfo, 4>;
7335 using MapValuesArrayTy = SmallVector<llvm::Value *, 4>;
7336 using MapFlagsArrayTy = SmallVector<OpenMPOffloadMappingFlags, 4>;
7337 using MapMappersArrayTy = SmallVector<const ValueDecl *, 4>;
7338 using MapDimArrayTy = SmallVector<uint64_t, 4>;
7339 using MapNonContiguousArrayTy = SmallVector<MapValuesArrayTy, 4>;
7340
7341 /// This structure contains combined information generated for mappable
7342 /// clauses, including base pointers, pointers, sizes, map types, user-defined
7343 /// mappers, and non-contiguous information.
7344 struct MapCombinedInfoTy {
7345 struct StructNonContiguousInfo {
7346 bool IsNonContiguous = false;
7347 MapDimArrayTy Dims;
7348 MapNonContiguousArrayTy Offsets;
7349 MapNonContiguousArrayTy Counts;
7350 MapNonContiguousArrayTy Strides;
7351 };
7352 MapExprsArrayTy Exprs;
7353 MapBaseValuesArrayTy BasePointers;
7354 MapValuesArrayTy Pointers;
7355 MapValuesArrayTy Sizes;
7356 MapFlagsArrayTy Types;
7357 MapMappersArrayTy Mappers;
7358 StructNonContiguousInfo NonContigInfo;
7359
7360 /// Append arrays in \a CurInfo.
7361 void append(MapCombinedInfoTy &CurInfo) {
7362 Exprs.append(CurInfo.Exprs.begin(), CurInfo.Exprs.end());
7363 BasePointers.append(CurInfo.BasePointers.begin(),
7364 CurInfo.BasePointers.end());
7365 Pointers.append(CurInfo.Pointers.begin(), CurInfo.Pointers.end());
7366 Sizes.append(CurInfo.Sizes.begin(), CurInfo.Sizes.end());
7367 Types.append(CurInfo.Types.begin(), CurInfo.Types.end());
7368 Mappers.append(CurInfo.Mappers.begin(), CurInfo.Mappers.end());
7369 NonContigInfo.Dims.append(CurInfo.NonContigInfo.Dims.begin(),
7370 CurInfo.NonContigInfo.Dims.end());
7371 NonContigInfo.Offsets.append(CurInfo.NonContigInfo.Offsets.begin(),
7372 CurInfo.NonContigInfo.Offsets.end());
7373 NonContigInfo.Counts.append(CurInfo.NonContigInfo.Counts.begin(),
7374 CurInfo.NonContigInfo.Counts.end());
7375 NonContigInfo.Strides.append(CurInfo.NonContigInfo.Strides.begin(),
7376 CurInfo.NonContigInfo.Strides.end());
7377 }
7378 };
7379
7380 /// Map between a struct and the its lowest & highest elements which have been
7381 /// mapped.
7382 /// [ValueDecl *] --> {LE(FieldIndex, Pointer),
7383 /// HE(FieldIndex, Pointer)}
7384 struct StructRangeInfoTy {
7385 MapCombinedInfoTy PreliminaryMapData;
7386 std::pair<unsigned /*FieldIndex*/, Address /*Pointer*/> LowestElem = {
7387 0, Address::invalid()};
7388 std::pair<unsigned /*FieldIndex*/, Address /*Pointer*/> HighestElem = {
7389 0, Address::invalid()};
7390 Address Base = Address::invalid();
7391 Address LB = Address::invalid();
7392 bool IsArraySection = false;
7393 bool HasCompleteRecord = false;
7394 };
7395
7396private:
7397 /// Kind that defines how a device pointer has to be returned.
7398 struct MapInfo {
7399 OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
7400 OpenMPMapClauseKind MapType = OMPC_MAP_unknown;
7401 ArrayRef<OpenMPMapModifierKind> MapModifiers;
7402 ArrayRef<OpenMPMotionModifierKind> MotionModifiers;
7403 bool ReturnDevicePointer = false;
7404 bool IsImplicit = false;
7405 const ValueDecl *Mapper = nullptr;
7406 const Expr *VarRef = nullptr;
7407 bool ForDeviceAddr = false;
7408
7409 MapInfo() = default;
7410 MapInfo(
7411 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
7412 OpenMPMapClauseKind MapType,
7413 ArrayRef<OpenMPMapModifierKind> MapModifiers,
7414 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
7415 bool ReturnDevicePointer, bool IsImplicit,
7416 const ValueDecl *Mapper = nullptr, const Expr *VarRef = nullptr,
7417 bool ForDeviceAddr = false)
7418 : Components(Components), MapType(MapType), MapModifiers(MapModifiers),
7419 MotionModifiers(MotionModifiers),
7420 ReturnDevicePointer(ReturnDevicePointer), IsImplicit(IsImplicit),
7421 Mapper(Mapper), VarRef(VarRef), ForDeviceAddr(ForDeviceAddr) {}
7422 };
7423
7424 /// If use_device_ptr or use_device_addr is used on a decl which is a struct
7425 /// member and there is no map information about it, then emission of that
7426 /// entry is deferred until the whole struct has been processed.
7427 struct DeferredDevicePtrEntryTy {
7428 const Expr *IE = nullptr;
7429 const ValueDecl *VD = nullptr;
7430 bool ForDeviceAddr = false;
7431
7432 DeferredDevicePtrEntryTy(const Expr *IE, const ValueDecl *VD,
7433 bool ForDeviceAddr)
7434 : IE(IE), VD(VD), ForDeviceAddr(ForDeviceAddr) {}
7435 };
7436
7437 /// The target directive from where the mappable clauses were extracted. It
7438 /// is either a executable directive or a user-defined mapper directive.
7439 llvm::PointerUnion<const OMPExecutableDirective *,
7440 const OMPDeclareMapperDecl *>
7441 CurDir;
7442
7443 /// Function the directive is being generated for.
7444 CodeGenFunction &CGF;
7445
7446 /// Set of all first private variables in the current directive.
7447 /// bool data is set to true if the variable is implicitly marked as
7448 /// firstprivate, false otherwise.
7449 llvm::DenseMap<CanonicalDeclPtr<const VarDecl>, bool> FirstPrivateDecls;
7450
7451 /// Map between device pointer declarations and their expression components.
7452 /// The key value for declarations in 'this' is null.
7453 llvm::DenseMap<
7454 const ValueDecl *,
7455 SmallVector<OMPClauseMappableExprCommon::MappableExprComponentListRef, 4>>
7456 DevPointersMap;
7457
7458 llvm::Value *getExprTypeSize(const Expr *E) const {
7459 QualType ExprTy = E->getType().getCanonicalType();
7460
7461 // Calculate the size for array shaping expression.
7462 if (const auto *OAE = dyn_cast<OMPArrayShapingExpr>(E)) {
7463 llvm::Value *Size =
7464 CGF.getTypeSize(OAE->getBase()->getType()->getPointeeType());
7465 for (const Expr *SE : OAE->getDimensions()) {
7466 llvm::Value *Sz = CGF.EmitScalarExpr(SE);
7467 Sz = CGF.EmitScalarConversion(Sz, SE->getType(),
7468 CGF.getContext().getSizeType(),
7469 SE->getExprLoc());
7470 Size = CGF.Builder.CreateNUWMul(Size, Sz);
7471 }
7472 return Size;
7473 }
7474
7475 // Reference types are ignored for mapping purposes.
7476 if (const auto *RefTy = ExprTy->getAs<ReferenceType>())
7477 ExprTy = RefTy->getPointeeType().getCanonicalType();
7478
7479 // Given that an array section is considered a built-in type, we need to
7480 // do the calculation based on the length of the section instead of relying
7481 // on CGF.getTypeSize(E->getType()).
7482 if (const auto *OAE = dyn_cast<OMPArraySectionExpr>(E)) {
7483 QualType BaseTy = OMPArraySectionExpr::getBaseOriginalType(
7484 OAE->getBase()->IgnoreParenImpCasts())
7485 .getCanonicalType();
7486
7487 // If there is no length associated with the expression and lower bound is
7488 // not specified too, that means we are using the whole length of the
7489 // base.
7490 if (!OAE->getLength() && OAE->getColonLocFirst().isValid() &&
7491 !OAE->getLowerBound())
7492 return CGF.getTypeSize(BaseTy);
7493
7494 llvm::Value *ElemSize;
7495 if (const auto *PTy = BaseTy->getAs<PointerType>()) {
7496 ElemSize = CGF.getTypeSize(PTy->getPointeeType().getCanonicalType());
7497 } else {
7498 const auto *ATy = cast<ArrayType>(BaseTy.getTypePtr());
7499 assert(ATy && "Expecting array type if not a pointer type.")(static_cast<void> (0));
7500 ElemSize = CGF.getTypeSize(ATy->getElementType().getCanonicalType());
7501 }
7502
7503 // If we don't have a length at this point, that is because we have an
7504 // array section with a single element.
7505 if (!OAE->getLength() && OAE->getColonLocFirst().isInvalid())
7506 return ElemSize;
7507
7508 if (const Expr *LenExpr = OAE->getLength()) {
7509 llvm::Value *LengthVal = CGF.EmitScalarExpr(LenExpr);
7510 LengthVal = CGF.EmitScalarConversion(LengthVal, LenExpr->getType(),
7511 CGF.getContext().getSizeType(),
7512 LenExpr->getExprLoc());
7513 return CGF.Builder.CreateNUWMul(LengthVal, ElemSize);
7514 }
7515 assert(!OAE->getLength() && OAE->getColonLocFirst().isValid() &&(static_cast<void> (0))
7516 OAE->getLowerBound() && "expected array_section[lb:].")(static_cast<void> (0));
7517 // Size = sizetype - lb * elemtype;
7518 llvm::Value *LengthVal = CGF.getTypeSize(BaseTy);
7519 llvm::Value *LBVal = CGF.EmitScalarExpr(OAE->getLowerBound());
7520 LBVal = CGF.EmitScalarConversion(LBVal, OAE->getLowerBound()->getType(),
7521 CGF.getContext().getSizeType(),
7522 OAE->getLowerBound()->getExprLoc());
7523 LBVal = CGF.Builder.CreateNUWMul(LBVal, ElemSize);
7524 llvm::Value *Cmp = CGF.Builder.CreateICmpUGT(LengthVal, LBVal);
7525 llvm::Value *TrueVal = CGF.Builder.CreateNUWSub(LengthVal, LBVal);
7526 LengthVal = CGF.Builder.CreateSelect(
7527 Cmp, TrueVal, llvm::ConstantInt::get(CGF.SizeTy, 0));
7528 return LengthVal;
7529 }
7530 return CGF.getTypeSize(ExprTy);
7531 }
7532
7533 /// Return the corresponding bits for a given map clause modifier. Add
7534 /// a flag marking the map as a pointer if requested. Add a flag marking the
7535 /// map as the first one of a series of maps that relate to the same map
7536 /// expression.
7537 OpenMPOffloadMappingFlags getMapTypeBits(
7538 OpenMPMapClauseKind MapType, ArrayRef<OpenMPMapModifierKind> MapModifiers,
7539 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, bool IsImplicit,
7540 bool AddPtrFlag, bool AddIsTargetParamFlag, bool IsNonContiguous) const {
7541 OpenMPOffloadMappingFlags Bits =
7542 IsImplicit ? OMP_MAP_IMPLICIT : OMP_MAP_NONE;
7543 switch (MapType) {
7544 case OMPC_MAP_alloc:
7545 case OMPC_MAP_release:
7546 // alloc and release is the default behavior in the runtime library, i.e.
7547 // if we don't pass any bits alloc/release that is what the runtime is
7548 // going to do. Therefore, we don't need to signal anything for these two
7549 // type modifiers.
7550 break;
7551 case OMPC_MAP_to:
7552 Bits |= OMP_MAP_TO;
7553 break;
7554 case OMPC_MAP_from:
7555 Bits |= OMP_MAP_FROM;
7556 break;
7557 case OMPC_MAP_tofrom:
7558 Bits |= OMP_MAP_TO | OMP_MAP_FROM;
7559 break;
7560 case OMPC_MAP_delete:
7561 Bits |= OMP_MAP_DELETE;
7562 break;
7563 case OMPC_MAP_unknown:
7564 llvm_unreachable("Unexpected map type!")__builtin_unreachable();
7565 }
7566 if (AddPtrFlag)
7567 Bits |= OMP_MAP_PTR_AND_OBJ;
7568 if (AddIsTargetParamFlag)
7569 Bits |= OMP_MAP_TARGET_PARAM;
7570 if (llvm::find(MapModifiers, OMPC_MAP_MODIFIER_always)
7571 != MapModifiers.end())
7572 Bits |= OMP_MAP_ALWAYS;
7573 if (llvm::find(MapModifiers, OMPC_MAP_MODIFIER_close)
7574 != MapModifiers.end())
7575 Bits |= OMP_MAP_CLOSE;
7576 if (llvm::find(MapModifiers, OMPC_MAP_MODIFIER_present) !=
7577 MapModifiers.end() ||
7578 llvm::find(MotionModifiers, OMPC_MOTION_MODIFIER_present) !=
7579 MotionModifiers.end())
7580 Bits |= OMP_MAP_PRESENT;
7581 if (llvm::find(MapModifiers, OMPC_MAP_MODIFIER_ompx_hold) !=
7582 MapModifiers.end())
7583 Bits |= OMP_MAP_OMPX_HOLD;
7584 if (IsNonContiguous)
7585 Bits |= OMP_MAP_NON_CONTIG;
7586 return Bits;
7587 }
7588
7589 /// Return true if the provided expression is a final array section. A
7590 /// final array section, is one whose length can't be proved to be one.
7591 bool isFinalArraySectionExpression(const Expr *E) const {
7592 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
7593
7594 // It is not an array section and therefore not a unity-size one.
7595 if (!OASE)
7596 return false;
7597
7598 // An array section with no colon always refer to a single element.
7599 if (OASE->getColonLocFirst().isInvalid())
7600 return false;
7601
7602 const Expr *Length = OASE->getLength();
7603
7604 // If we don't have a length we have to check if the array has size 1
7605 // for this dimension. Also, we should always expect a length if the
7606 // base type is pointer.
7607 if (!Length) {
7608 QualType BaseQTy = OMPArraySectionExpr::getBaseOriginalType(
7609 OASE->getBase()->IgnoreParenImpCasts())
7610 .getCanonicalType();
7611 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
7612 return ATy->getSize().getSExtValue() != 1;
7613 // If we don't have a constant dimension length, we have to consider
7614 // the current section as having any size, so it is not necessarily
7615 // unitary. If it happen to be unity size, that's user fault.
7616 return true;
7617 }
7618
7619 // Check if the length evaluates to 1.
7620 Expr::EvalResult Result;
7621 if (!Length->EvaluateAsInt(Result, CGF.getContext()))
7622 return true; // Can have more that size 1.
7623
7624 llvm::APSInt ConstLength = Result.Val.getInt();
7625 return ConstLength.getSExtValue() != 1;
7626 }
7627
7628 /// Generate the base pointers, section pointers, sizes, map type bits, and
7629 /// user-defined mappers (all included in \a CombinedInfo) for the provided
7630 /// map type, map or motion modifiers, and expression components.
7631 /// \a IsFirstComponent should be set to true if the provided set of
7632 /// components is the first associated with a capture.
7633 void generateInfoForComponentList(
7634 OpenMPMapClauseKind MapType, ArrayRef<OpenMPMapModifierKind> MapModifiers,
7635 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
7636 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
7637 MapCombinedInfoTy &CombinedInfo, StructRangeInfoTy &PartialStruct,
7638 bool IsFirstComponentList, bool IsImplicit,
7639 const ValueDecl *Mapper = nullptr, bool ForDeviceAddr = false,
7640 const ValueDecl *BaseDecl = nullptr, const Expr *MapExpr = nullptr,
7641 ArrayRef<OMPClauseMappableExprCommon::MappableExprComponentListRef>
7642 OverlappedElements = llvm::None) const {
7643 // The following summarizes what has to be generated for each map and the
7644 // types below. The generated information is expressed in this order:
7645 // base pointer, section pointer, size, flags
7646 // (to add to the ones that come from the map type and modifier).
7647 //
7648 // double d;
7649 // int i[100];
7650 // float *p;
7651 //
7652 // struct S1 {
7653 // int i;
7654 // float f[50];
7655 // }
7656 // struct S2 {
7657 // int i;
7658 // float f[50];
7659 // S1 s;
7660 // double *p;
7661 // struct S2 *ps;
7662 // int &ref;
7663 // }
7664 // S2 s;
7665 // S2 *ps;
7666 //
7667 // map(d)
7668 // &d, &d, sizeof(double), TARGET_PARAM | TO | FROM
7669 //
7670 // map(i)
7671 // &i, &i, 100*sizeof(int), TARGET_PARAM | TO | FROM
7672 //
7673 // map(i[1:23])
7674 // &i(=&i[0]), &i[1], 23*sizeof(int), TARGET_PARAM | TO | FROM
7675 //
7676 // map(p)
7677 // &p, &p, sizeof(float*), TARGET_PARAM | TO | FROM
7678 //
7679 // map(p[1:24])
7680 // &p, &p[1], 24*sizeof(float), TARGET_PARAM | TO | FROM | PTR_AND_OBJ
7681 // in unified shared memory mode or for local pointers
7682 // p, &p[1], 24*sizeof(float), TARGET_PARAM | TO | FROM
7683 //
7684 // map(s)
7685 // &s, &s, sizeof(S2), TARGET_PARAM | TO | FROM
7686 //
7687 // map(s.i)
7688 // &s, &(s.i), sizeof(int), TARGET_PARAM | TO | FROM
7689 //
7690 // map(s.s.f)
7691 // &s, &(s.s.f[0]), 50*sizeof(float), TARGET_PARAM | TO | FROM
7692 //
7693 // map(s.p)
7694 // &s, &(s.p), sizeof(double*), TARGET_PARAM | TO | FROM
7695 //
7696 // map(to: s.p[:22])
7697 // &s, &(s.p), sizeof(double*), TARGET_PARAM (*)
7698 // &s, &(s.p), sizeof(double*), MEMBER_OF(1) (**)
7699 // &(s.p), &(s.p[0]), 22*sizeof(double),
7700 // MEMBER_OF(1) | PTR_AND_OBJ | TO (***)
7701 // (*) alloc space for struct members, only this is a target parameter
7702 // (**) map the pointer (nothing to be mapped in this example) (the compiler
7703 // optimizes this entry out, same in the examples below)
7704 // (***) map the pointee (map: to)
7705 //
7706 // map(to: s.ref)
7707 // &s, &(s.ref), sizeof(int*), TARGET_PARAM (*)
7708 // &s, &(s.ref), sizeof(int), MEMBER_OF(1) | PTR_AND_OBJ | TO (***)
7709 // (*) alloc space for struct members, only this is a target parameter
7710 // (**) map the pointer (nothing to be mapped in this example) (the compiler
7711 // optimizes this entry out, same in the examples below)
7712 // (***) map the pointee (map: to)
7713 //
7714 // map(s.ps)
7715 // &s, &(s.ps), sizeof(S2*), TARGET_PARAM | TO | FROM
7716 //
7717 // map(from: s.ps->s.i)
7718 // &s, &(s.ps), sizeof(S2*), TARGET_PARAM
7719 // &s, &(s.ps), sizeof(S2*), MEMBER_OF(1)
7720 // &(s.ps), &(s.ps->s.i), sizeof(int), MEMBER_OF(1) | PTR_AND_OBJ | FROM
7721 //
7722 // map(to: s.ps->ps)
7723 // &s, &(s.ps), sizeof(S2*), TARGET_PARAM
7724 // &s, &(s.ps), sizeof(S2*), MEMBER_OF(1)
7725 // &(s.ps), &(s.ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ | TO
7726 //
7727 // map(s.ps->ps->ps)
7728 // &s, &(s.ps), sizeof(S2*), TARGET_PARAM
7729 // &s, &(s.ps), sizeof(S2*), MEMBER_OF(1)
7730 // &(s.ps), &(s.ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ
7731 // &(s.ps->ps), &(s.ps->ps->ps), sizeof(S2*), PTR_AND_OBJ | TO | FROM
7732 //
7733 // map(to: s.ps->ps->s.f[:22])
7734 // &s, &(s.ps), sizeof(S2*), TARGET_PARAM
7735 // &s, &(s.ps), sizeof(S2*), MEMBER_OF(1)
7736 // &(s.ps), &(s.ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ
7737 // &(s.ps->ps), &(s.ps->ps->s.f[0]), 22*sizeof(float), PTR_AND_OBJ | TO
7738 //
7739 // map(ps)
7740 // &ps, &ps, sizeof(S2*), TARGET_PARAM | TO | FROM
7741 //
7742 // map(ps->i)
7743 // ps, &(ps->i), sizeof(int), TARGET_PARAM | TO | FROM
7744 //
7745 // map(ps->s.f)
7746 // ps, &(ps->s.f[0]), 50*sizeof(float), TARGET_PARAM | TO | FROM
7747 //
7748 // map(from: ps->p)
7749 // ps, &(ps->p), sizeof(double*), TARGET_PARAM | FROM
7750 //
7751 // map(to: ps->p[:22])
7752 // ps, &(ps->p), sizeof(double*), TARGET_PARAM
7753 // ps, &(ps->p), sizeof(double*), MEMBER_OF(1)
7754 // &(ps->p), &(ps->p[0]), 22*sizeof(double), MEMBER_OF(1) | PTR_AND_OBJ | TO
7755 //
7756 // map(ps->ps)
7757 // ps, &(ps->ps), sizeof(S2*), TARGET_PARAM | TO | FROM
7758 //
7759 // map(from: ps->ps->s.i)
7760 // ps, &(ps->ps), sizeof(S2*), TARGET_PARAM
7761 // ps, &(ps->ps), sizeof(S2*), MEMBER_OF(1)
7762 // &(ps->ps), &(ps->ps->s.i), sizeof(int), MEMBER_OF(1) | PTR_AND_OBJ | FROM
7763 //
7764 // map(from: ps->ps->ps)
7765 // ps, &(ps->ps), sizeof(S2*), TARGET_PARAM
7766 // ps, &(ps->ps), sizeof(S2*), MEMBER_OF(1)
7767 // &(ps->ps), &(ps->ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ | FROM
7768 //
7769 // map(ps->ps->ps->ps)
7770 // ps, &(ps->ps), sizeof(S2*), TARGET_PARAM
7771 // ps, &(ps->ps), sizeof(S2*), MEMBER_OF(1)
7772 // &(ps->ps), &(ps->ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ
7773 // &(ps->ps->ps), &(ps->ps->ps->ps), sizeof(S2*), PTR_AND_OBJ | TO | FROM
7774 //
7775 // map(to: ps->ps->ps->s.f[:22])
7776 // ps, &(ps->ps), sizeof(S2*), TARGET_PARAM
7777 // ps, &(ps->ps), sizeof(S2*), MEMBER_OF(1)
7778 // &(ps->ps), &(ps->ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ
7779 // &(ps->ps->ps), &(ps->ps->ps->s.f[0]), 22*sizeof(float), PTR_AND_OBJ | TO
7780 //
7781 // map(to: s.f[:22]) map(from: s.p[:33])
7782 // &s, &(s.f[0]), 50*sizeof(float) + sizeof(struct S1) +
7783 // sizeof(double*) (**), TARGET_PARAM
7784 // &s, &(s.f[0]), 22*sizeof(float), MEMBER_OF(1) | TO
7785 // &s, &(s.p), sizeof(double*), MEMBER_OF(1)
7786 // &(s.p), &(s.p[0]), 33*sizeof(double), MEMBER_OF(1) | PTR_AND_OBJ | FROM
7787 // (*) allocate contiguous space needed to fit all mapped members even if
7788 // we allocate space for members not mapped (in this example,
7789 // s.f[22..49] and s.s are not mapped, yet we must allocate space for
7790 // them as well because they fall between &s.f[0] and &s.p)
7791 //
7792 // map(from: s.f[:22]) map(to: ps->p[:33])
7793 // &s, &(s.f[0]), 22*sizeof(float), TARGET_PARAM | FROM
7794 // ps, &(ps->p), sizeof(S2*), TARGET_PARAM
7795 // ps, &(ps->p), sizeof(double*), MEMBER_OF(2) (*)
7796 // &(ps->p), &(ps->p[0]), 33*sizeof(double), MEMBER_OF(2) | PTR_AND_OBJ | TO
7797 // (*) the struct this entry pertains to is the 2nd element in the list of
7798 // arguments, hence MEMBER_OF(2)
7799 //
7800 // map(from: s.f[:22], s.s) map(to: ps->p[:33])
7801 // &s, &(s.f[0]), 50*sizeof(float) + sizeof(struct S1), TARGET_PARAM
7802 // &s, &(s.f[0]), 22*sizeof(float), MEMBER_OF(1) | FROM
7803 // &s, &(s.s), sizeof(struct S1), MEMBER_OF(1) | FROM
7804 // ps, &(ps->p), sizeof(S2*), TARGET_PARAM
7805 // ps, &(ps->p), sizeof(double*), MEMBER_OF(4) (*)
7806 // &(ps->p), &(ps->p[0]), 33*sizeof(double), MEMBER_OF(4) | PTR_AND_OBJ | TO
7807 // (*) the struct this entry pertains to is the 4th element in the list
7808 // of arguments, hence MEMBER_OF(4)
7809
7810 // Track if the map information being generated is the first for a capture.
7811 bool IsCaptureFirstInfo = IsFirstComponentList;
7812 // When the variable is on a declare target link or in a to clause with
7813 // unified memory, a reference is needed to hold the host/device address
7814 // of the variable.
7815 bool RequiresReference = false;
7816
7817 // Scan the components from the base to the complete expression.
7818 auto CI = Components.rbegin();
7819 auto CE = Components.rend();
7820 auto I = CI;
7821
7822 // Track if the map information being generated is the first for a list of
7823 // components.
7824 bool IsExpressionFirstInfo = true;
7825 bool FirstPointerInComplexData = false;
7826 Address BP = Address::invalid();
7827 const Expr *AssocExpr = I->getAssociatedExpression();
7828 const auto *AE = dyn_cast<ArraySubscriptExpr>(AssocExpr);
7829 const auto *OASE = dyn_cast<OMPArraySectionExpr>(AssocExpr);
7830 const auto *OAShE = dyn_cast<OMPArrayShapingExpr>(AssocExpr);
7831
7832 if (isa<MemberExpr>(AssocExpr)) {
7833 // The base is the 'this' pointer. The content of the pointer is going
7834 // to be the base of the field being mapped.
7835 BP = CGF.LoadCXXThisAddress();
7836 } else if ((AE && isa<CXXThisExpr>(AE->getBase()->IgnoreParenImpCasts())) ||
7837 (OASE &&
7838 isa<CXXThisExpr>(OASE->getBase()->IgnoreParenImpCasts()))) {
7839 BP = CGF.EmitOMPSharedLValue(AssocExpr).getAddress(CGF);
7840 } else if (OAShE &&
7841 isa<CXXThisExpr>(OAShE->getBase()->IgnoreParenCasts())) {
7842 BP = Address(
7843 CGF.EmitScalarExpr(OAShE->getBase()),
7844 CGF.getContext().getTypeAlignInChars(OAShE->getBase()->getType()));
7845 } else {
7846 // The base is the reference to the variable.
7847 // BP = &Var.
7848 BP = CGF.EmitOMPSharedLValue(AssocExpr).getAddress(CGF);
7849 if (const auto *VD =
7850 dyn_cast_or_null<VarDecl>(I->getAssociatedDeclaration())) {
7851 if (llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
7852 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
7853 if ((*Res == OMPDeclareTargetDeclAttr::MT_Link) ||
7854 (*Res == OMPDeclareTargetDeclAttr::MT_To &&
7855 CGF.CGM.getOpenMPRuntime().hasRequiresUnifiedSharedMemory())) {
7856 RequiresReference = true;
7857 BP = CGF.CGM.getOpenMPRuntime().getAddrOfDeclareTargetVar(VD);
7858 }
7859 }
7860 }
7861
7862 // If the variable is a pointer and is being dereferenced (i.e. is not
7863 // the last component), the base has to be the pointer itself, not its
7864 // reference. References are ignored for mapping purposes.
7865 QualType Ty =
7866 I->getAssociatedDeclaration()->getType().getNonReferenceType();
7867 if (Ty->isAnyPointerType() && std::next(I) != CE) {
7868 // No need to generate individual map information for the pointer, it
7869 // can be associated with the combined storage if shared memory mode is
7870 // active or the base declaration is not global variable.
7871 const auto *VD = dyn_cast<VarDecl>(I->getAssociatedDeclaration());
7872 if (CGF.CGM.getOpenMPRuntime().hasRequiresUnifiedSharedMemory() ||
7873 !VD || VD->hasLocalStorage())
7874 BP = CGF.EmitLoadOfPointer(BP, Ty->castAs<PointerType>());
7875 else
7876 FirstPointerInComplexData = true;
7877 ++I;
7878 }
7879 }
7880
7881 // Track whether a component of the list should be marked as MEMBER_OF some
7882 // combined entry (for partial structs). Only the first PTR_AND_OBJ entry
7883 // in a component list should be marked as MEMBER_OF, all subsequent entries
7884 // do not belong to the base struct. E.g.
7885 // struct S2 s;
7886 // s.ps->ps->ps->f[:]
7887 // (1) (2) (3) (4)
7888 // ps(1) is a member pointer, ps(2) is a pointee of ps(1), so it is a
7889 // PTR_AND_OBJ entry; the PTR is ps(1), so MEMBER_OF the base struct. ps(3)
7890 // is the pointee of ps(2) which is not member of struct s, so it should not
7891 // be marked as such (it is still PTR_AND_OBJ).
7892 // The variable is initialized to false so that PTR_AND_OBJ entries which
7893 // are not struct members are not considered (e.g. array of pointers to
7894 // data).
7895 bool ShouldBeMemberOf = false;
7896
7897 // Variable keeping track of whether or not we have encountered a component
7898 // in the component list which is a member expression. Useful when we have a
7899 // pointer or a final array section, in which case it is the previous
7900 // component in the list which tells us whether we have a member expression.
7901 // E.g. X.f[:]
7902 // While processing the final array section "[:]" it is "f" which tells us
7903 // whether we are dealing with a member of a declared struct.
7904 const MemberExpr *EncounteredME = nullptr;
7905
7906 // Track for the total number of dimension. Start from one for the dummy
7907 // dimension.
7908 uint64_t DimSize = 1;
7909
7910 bool IsNonContiguous = CombinedInfo.NonContigInfo.IsNonContiguous;
7911 bool IsPrevMemberReference = false;
7912
7913 for (; I != CE; ++I) {
7914 // If the current component is member of a struct (parent struct) mark it.
7915 if (!EncounteredME) {
7916 EncounteredME = dyn_cast<MemberExpr>(I->getAssociatedExpression());
7917 // If we encounter a PTR_AND_OBJ entry from now on it should be marked
7918 // as MEMBER_OF the parent struct.
7919 if (EncounteredME) {
7920 ShouldBeMemberOf = true;
7921 // Do not emit as complex pointer if this is actually not array-like
7922 // expression.
7923 if (FirstPointerInComplexData) {
7924 QualType Ty = std::prev(I)
7925 ->getAssociatedDeclaration()
7926 ->getType()
7927 .getNonReferenceType();
7928 BP = CGF.EmitLoadOfPointer(BP, Ty->castAs<PointerType>());
7929 FirstPointerInComplexData = false;
7930 }
7931 }
7932 }
7933
7934 auto Next = std::next(I);
7935
7936 // We need to generate the addresses and sizes if this is the last
7937 // component, if the component is a pointer or if it is an array section
7938 // whose length can't be proved to be one. If this is a pointer, it
7939 // becomes the base address for the following components.
7940
7941 // A final array section, is one whose length can't be proved to be one.
7942 // If the map item is non-contiguous then we don't treat any array section
7943 // as final array section.
7944 bool IsFinalArraySection =
7945 !IsNonContiguous &&
7946 isFinalArraySectionExpression(I->getAssociatedExpression());
7947
7948 // If we have a declaration for the mapping use that, otherwise use
7949 // the base declaration of the map clause.
7950 const ValueDecl *MapDecl = (I->getAssociatedDeclaration())
7951 ? I->getAssociatedDeclaration()
7952 : BaseDecl;
7953 MapExpr = (I->getAssociatedExpression()) ? I->getAssociatedExpression()
7954 : MapExpr;
7955
7956 // Get information on whether the element is a pointer. Have to do a
7957 // special treatment for array sections given that they are built-in
7958 // types.
7959 const auto *OASE =
7960 dyn_cast<OMPArraySectionExpr>(I->getAssociatedExpression());
7961 const auto *OAShE =
7962 dyn_cast<OMPArrayShapingExpr>(I->getAssociatedExpression());
7963 const auto *UO = dyn_cast<UnaryOperator>(I->getAssociatedExpression());
7964 const auto *BO = dyn_cast<BinaryOperator>(I->getAssociatedExpression());
7965 bool IsPointer =
7966 OAShE ||
7967 (OASE && OMPArraySectionExpr::getBaseOriginalType(OASE)
7968 .getCanonicalType()
7969 ->isAnyPointerType()) ||
7970 I->getAssociatedExpression()->getType()->isAnyPointerType();
7971 bool IsMemberReference = isa<MemberExpr>(I->getAssociatedExpression()) &&
7972 MapDecl &&
7973 MapDecl->getType()->isLValueReferenceType();
7974 bool IsNonDerefPointer = IsPointer && !UO && !BO && !IsNonContiguous;
7975
7976 if (OASE)
7977 ++DimSize;
7978
7979 if (Next == CE || IsMemberReference || IsNonDerefPointer ||
7980 IsFinalArraySection) {
7981 // If this is not the last component, we expect the pointer to be
7982 // associated with an array expression or member expression.
7983 assert((Next == CE ||(static_cast<void> (0))
7984 isa<MemberExpr>(Next->getAssociatedExpression()) ||(static_cast<void> (0))
7985 isa<ArraySubscriptExpr>(Next->getAssociatedExpression()) ||(static_cast<void> (0))
7986 isa<OMPArraySectionExpr>(Next->getAssociatedExpression()) ||(static_cast<void> (0))
7987 isa<OMPArrayShapingExpr>(Next->getAssociatedExpression()) ||(static_cast<void> (0))
7988 isa<UnaryOperator>(Next->getAssociatedExpression()) ||(static_cast<void> (0))
7989 isa<BinaryOperator>(Next->getAssociatedExpression())) &&(static_cast<void> (0))
7990 "Unexpected expression")(static_cast<void> (0));
7991
7992 Address LB = Address::invalid();
7993 Address LowestElem = Address::invalid();
7994 auto &&EmitMemberExprBase = [](CodeGenFunction &CGF,
7995 const MemberExpr *E) {
7996 const Expr *BaseExpr = E->getBase();
7997 // If this is s.x, emit s as an lvalue. If it is s->x, emit s as a
7998 // scalar.
7999 LValue BaseLV;
8000 if (E->isArrow()) {
8001 LValueBaseInfo BaseInfo;
8002 TBAAAccessInfo TBAAInfo;
8003 Address Addr =
8004 CGF.EmitPointerWithAlignment(BaseExpr, &BaseInfo, &TBAAInfo);
8005 QualType PtrTy = BaseExpr->getType()->getPointeeType();
8006 BaseLV = CGF.MakeAddrLValue(Addr, PtrTy, BaseInfo, TBAAInfo);
8007 } else {
8008 BaseLV = CGF.EmitOMPSharedLValue(BaseExpr);
8009 }
8010 return BaseLV;
8011 };
8012 if (OAShE) {
8013 LowestElem = LB = Address(CGF.EmitScalarExpr(OAShE->getBase()),
8014 CGF.getContext().getTypeAlignInChars(
8015 OAShE->getBase()->getType()));
8016 } else if (IsMemberReference) {
8017 const auto *ME = cast<MemberExpr>(I->getAssociatedExpression());
8018 LValue BaseLVal = EmitMemberExprBase(CGF, ME);
8019 LowestElem = CGF.EmitLValueForFieldInitialization(
8020 BaseLVal, cast<FieldDecl>(MapDecl))
8021 .getAddress(CGF);
8022 LB = CGF.EmitLoadOfReferenceLValue(LowestElem, MapDecl->getType())
8023 .getAddress(CGF);
8024 } else {
8025 LowestElem = LB =
8026 CGF.EmitOMPSharedLValue(I->getAssociatedExpression())
8027 .getAddress(CGF);
8028 }
8029
8030 // If this component is a pointer inside the base struct then we don't
8031 // need to create any entry for it - it will be combined with the object
8032 // it is pointing to into a single PTR_AND_OBJ entry.
8033 bool IsMemberPointerOrAddr =
8034 EncounteredME &&
8035 (((IsPointer || ForDeviceAddr) &&
8036 I->getAssociatedExpression() == EncounteredME) ||
8037 (IsPrevMemberReference && !IsPointer) ||
8038 (IsMemberReference && Next != CE &&
8039 !Next->getAssociatedExpression()->getType()->isPointerType()));
8040 if (!OverlappedElements.empty() && Next == CE) {
8041 // Handle base element with the info for overlapped elements.
8042 assert(!PartialStruct.Base.isValid() && "The base element is set.")(static_cast<void> (0));
8043 assert(!IsPointer &&(static_cast<void> (0))
8044 "Unexpected base element with the pointer type.")(static_cast<void> (0));
8045 // Mark the whole struct as the struct that requires allocation on the
8046 // device.
8047 PartialStruct.LowestElem = {0, LowestElem};
8048 CharUnits TypeSize = CGF.getContext().getTypeSizeInChars(
8049 I->getAssociatedExpression()->getType());
8050 Address HB = CGF.Builder.CreateConstGEP(
8051 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(LowestElem,
8052 CGF.VoidPtrTy),
8053 TypeSize.getQuantity() - 1);
8054 PartialStruct.HighestElem = {
8055 std::numeric_limits<decltype(
8056 PartialStruct.HighestElem.first)>::max(),
8057 HB};
8058 PartialStruct.Base = BP;
8059 PartialStruct.LB = LB;
8060 assert((static_cast<void> (0))
8061 PartialStruct.PreliminaryMapData.BasePointers.empty() &&(static_cast<void> (0))
8062 "Overlapped elements must be used only once for the variable.")(static_cast<void> (0));
8063 std::swap(PartialStruct.PreliminaryMapData, CombinedInfo);
8064 // Emit data for non-overlapped data.
8065 OpenMPOffloadMappingFlags Flags =
8066 OMP_MAP_MEMBER_OF |
8067 getMapTypeBits(MapType, MapModifiers, MotionModifiers, IsImplicit,
8068 /*AddPtrFlag=*/false,
8069 /*AddIsTargetParamFlag=*/false, IsNonContiguous);
8070 llvm::Value *Size = nullptr;
8071 // Do bitcopy of all non-overlapped structure elements.
8072 for (OMPClauseMappableExprCommon::MappableExprComponentListRef
8073 Component : OverlappedElements) {
8074 Address ComponentLB = Address::invalid();
8075 for (const OMPClauseMappableExprCommon::MappableComponent &MC :
8076 Component) {
8077 if (const ValueDecl *VD = MC.getAssociatedDeclaration()) {
8078 const auto *FD = dyn_cast<FieldDecl>(VD);
8079 if (FD && FD->getType()->isLValueReferenceType()) {
8080 const auto *ME =
8081 cast<MemberExpr>(MC.getAssociatedExpression());
8082 LValue BaseLVal = EmitMemberExprBase(CGF, ME);
8083 ComponentLB =
8084 CGF.EmitLValueForFieldInitialization(BaseLVal, FD)
8085 .getAddress(CGF);
8086 } else {
8087 ComponentLB =
8088 CGF.EmitOMPSharedLValue(MC.getAssociatedExpression())
8089 .getAddress(CGF);
8090 }
8091 Size = CGF.Builder.CreatePtrDiff(
8092 CGF.EmitCastToVoidPtr(ComponentLB.getPointer()),
8093 CGF.EmitCastToVoidPtr(LB.getPointer()));
8094 break;
8095 }
8096 }
8097 assert(Size && "Failed to determine structure size")(static_cast<void> (0));
8098 CombinedInfo.Exprs.emplace_back(MapDecl, MapExpr);
8099 CombinedInfo.BasePointers.push_back(BP.getPointer());
8100 CombinedInfo.Pointers.push_back(LB.getPointer());
8101 CombinedInfo.Sizes.push_back(CGF.Builder.CreateIntCast(
8102 Size, CGF.Int64Ty, /*isSigned=*/true));
8103 CombinedInfo.Types.push_back(Flags);
8104 CombinedInfo.Mappers.push_back(nullptr);
8105 CombinedInfo.NonContigInfo.Dims.push_back(IsNonContiguous ? DimSize
8106 : 1);
8107 LB = CGF.Builder.CreateConstGEP(ComponentLB, 1);
8108 }
8109 CombinedInfo.Exprs.emplace_back(MapDecl, MapExpr);
8110 CombinedInfo.BasePointers.push_back(BP.getPointer());
8111 CombinedInfo.Pointers.push_back(LB.getPointer());
8112 Size = CGF.Builder.CreatePtrDiff(
8113 CGF.Builder.CreateConstGEP(HB, 1).getPointer(),
8114 CGF.EmitCastToVoidPtr(LB.getPointer()));
8115 CombinedInfo.Sizes.push_back(
8116 CGF.Builder.CreateIntCast(Size, CGF.Int64Ty, /*isSigned=*/true));
8117 CombinedInfo.Types.push_back(Flags);
8118 CombinedInfo.Mappers.push_back(nullptr);
8119 CombinedInfo.NonContigInfo.Dims.push_back(IsNonContiguous ? DimSize
8120 : 1);
8121 break;
8122 }
8123 llvm::Value *Size = getExprTypeSize(I->getAssociatedExpression());
8124 if (!IsMemberPointerOrAddr ||
8125 (Next == CE && MapType != OMPC_MAP_unknown)) {
8126 CombinedInfo.Exprs.emplace_back(MapDecl, MapExpr);
8127 CombinedInfo.BasePointers.push_back(BP.getPointer());
8128 CombinedInfo.Pointers.push_back(LB.getPointer());
8129 CombinedInfo.Sizes.push_back(
8130 CGF.Builder.CreateIntCast(Size, CGF.Int64Ty, /*isSigned=*/true));
8131 CombinedInfo.NonContigInfo.Dims.push_back(IsNonContiguous ? DimSize
8132 : 1);
8133
8134 // If Mapper is valid, the last component inherits the mapper.
8135 bool HasMapper = Mapper && Next == CE;
8136 CombinedInfo.Mappers.push_back(HasMapper ? Mapper : nullptr);
8137
8138 // We need to add a pointer flag for each map that comes from the
8139 // same expression except for the first one. We also need to signal
8140 // this map is the first one that relates with the current capture
8141 // (there is a set of entries for each capture).
8142 OpenMPOffloadMappingFlags Flags = getMapTypeBits(
8143 MapType, MapModifiers, MotionModifiers, IsImplicit,
8144 !IsExpressionFirstInfo || RequiresReference ||
8145 FirstPointerInComplexData || IsMemberReference,
8146 IsCaptureFirstInfo && !RequiresReference, IsNonContiguous);
8147
8148 if (!IsExpressionFirstInfo || IsMemberReference) {
8149 // If we have a PTR_AND_OBJ pair where the OBJ is a pointer as well,
8150 // then we reset the TO/FROM/ALWAYS/DELETE/CLOSE flags.
8151 if (IsPointer || (IsMemberReference && Next != CE))
8152 Flags &= ~(OMP_MAP_TO | OMP_MAP_FROM | OMP_MAP_ALWAYS |
8153 OMP_MAP_DELETE | OMP_MAP_CLOSE);
8154
8155 if (ShouldBeMemberOf) {
8156 // Set placeholder value MEMBER_OF=FFFF to indicate that the flag
8157 // should be later updated with the correct value of MEMBER_OF.
8158 Flags |= OMP_MAP_MEMBER_OF;
8159 // From now on, all subsequent PTR_AND_OBJ entries should not be
8160 // marked as MEMBER_OF.
8161 ShouldBeMemberOf = false;
8162 }
8163 }
8164
8165 CombinedInfo.Types.push_back(Flags);
8166 }
8167
8168 // If we have encountered a member expression so far, keep track of the
8169 // mapped member. If the parent is "*this", then the value declaration
8170 // is nullptr.
8171 if (EncounteredME) {
8172 const auto *FD = cast<FieldDecl>(EncounteredME->getMemberDecl());
8173 unsigned FieldIndex = FD->getFieldIndex();
8174
8175 // Update info about the lowest and highest elements for this struct
8176 if (!PartialStruct.Base.isValid()) {
8177 PartialStruct.LowestElem = {FieldIndex, LowestElem};
8178 if (IsFinalArraySection) {
8179 Address HB =
8180 CGF.EmitOMPArraySectionExpr(OASE, /*IsLowerBound=*/false)
8181 .getAddress(CGF);
8182 PartialStruct.HighestElem = {FieldIndex, HB};
8183 } else {
8184 PartialStruct.HighestElem = {FieldIndex, LowestElem};
8185 }
8186 PartialStruct.Base = BP;
8187 PartialStruct.LB = BP;
8188 } else if (FieldIndex < PartialStruct.LowestElem.first) {
8189 PartialStruct.LowestElem = {FieldIndex, LowestElem};
8190 } else if (FieldIndex > PartialStruct.HighestElem.first) {
8191 PartialStruct.HighestElem = {FieldIndex, LowestElem};
8192 }
8193 }
8194
8195 // Need to emit combined struct for array sections.
8196 if (IsFinalArraySection || IsNonContiguous)
8197 PartialStruct.IsArraySection = true;
8198
8199 // If we have a final array section, we are done with this expression.
8200 if (IsFinalArraySection)
8201 break;
8202
8203 // The pointer becomes the base for the next element.
8204 if (Next != CE)
8205 BP = IsMemberReference ? LowestElem : LB;
8206
8207 IsExpressionFirstInfo = false;
8208 IsCaptureFirstInfo = false;
8209 FirstPointerInComplexData = false;
8210 IsPrevMemberReference = IsMemberReference;
8211 } else if (FirstPointerInComplexData) {
8212 QualType Ty = Components.rbegin()
8213 ->getAssociatedDeclaration()
8214 ->getType()
8215 .getNonReferenceType();
8216 BP = CGF.EmitLoadOfPointer(BP, Ty->castAs<PointerType>());
8217 FirstPointerInComplexData = false;
8218 }
8219 }
8220 // If ran into the whole component - allocate the space for the whole
8221 // record.
8222 if (!EncounteredME)
8223 PartialStruct.HasCompleteRecord = true;
8224
8225 if (!IsNonContiguous)
8226 return;
8227
8228 const ASTContext &Context = CGF.getContext();
8229
8230 // For supporting stride in array section, we need to initialize the first
8231 // dimension size as 1, first offset as 0, and first count as 1
8232 MapValuesArrayTy CurOffsets = {llvm::ConstantInt::get(CGF.CGM.Int64Ty, 0)};
8233 MapValuesArrayTy CurCounts = {llvm::ConstantInt::get(CGF.CGM.Int64Ty, 1)};
8234 MapValuesArrayTy CurStrides;
8235 MapValuesArrayTy DimSizes{llvm::ConstantInt::get(CGF.CGM.Int64Ty, 1)};
8236 uint64_t ElementTypeSize;
8237
8238 // Collect Size information for each dimension and get the element size as
8239 // the first Stride. For example, for `int arr[10][10]`, the DimSizes
8240 // should be [10, 10] and the first stride is 4 btyes.
8241 for (const OMPClauseMappableExprCommon::MappableComponent &Component :
8242 Components) {
8243 const Expr *AssocExpr = Component.getAssociatedExpression();
8244 const auto *OASE = dyn_cast<OMPArraySectionExpr>(AssocExpr);
8245
8246 if (!OASE)
8247 continue;
8248
8249 QualType Ty = OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
8250 auto *CAT = Context.getAsConstantArrayType(Ty);
8251 auto *VAT = Context.getAsVariableArrayType(Ty);
8252
8253 // We need all the dimension size except for the last dimension.
8254 assert((VAT || CAT || &Component == &*Components.begin()) &&(static_cast<void> (0))
8255 "Should be either ConstantArray or VariableArray if not the "(static_cast<void> (0))
8256 "first Component")(static_cast<void> (0));
8257
8258 // Get element size if CurStrides is empty.
8259 if (CurStrides.empty()) {
8260 const Type *ElementType = nullptr;
8261 if (CAT)
8262 ElementType = CAT->getElementType().getTypePtr();
8263 else if (VAT)
8264 ElementType = VAT->getElementType().getTypePtr();
8265 else
8266 assert(&Component == &*Components.begin() &&(static_cast<void> (0))
8267 "Only expect pointer (non CAT or VAT) when this is the "(static_cast<void> (0))
8268 "first Component")(static_cast<void> (0));
8269 // If ElementType is null, then it means the base is a pointer
8270 // (neither CAT nor VAT) and we'll attempt to get ElementType again
8271 // for next iteration.
8272 if (ElementType) {
8273 // For the case that having pointer as base, we need to remove one
8274 // level of indirection.
8275 if (&Component != &*Components.begin())
8276 ElementType = ElementType->getPointeeOrArrayElementType();
8277 ElementTypeSize =
8278 Context.getTypeSizeInChars(ElementType).getQuantity();
8279 CurStrides.push_back(
8280 llvm::ConstantInt::get(CGF.Int64Ty, ElementTypeSize));
8281 }
8282 }
8283 // Get dimension value except for the last dimension since we don't need
8284 // it.
8285 if (DimSizes.size() < Components.size() - 1) {
8286 if (CAT)
8287 DimSizes.push_back(llvm::ConstantInt::get(
8288 CGF.Int64Ty, CAT->getSize().getZExtValue()));
8289 else if (VAT)
8290 DimSizes.push_back(CGF.Builder.CreateIntCast(
8291 CGF.EmitScalarExpr(VAT->getSizeExpr()), CGF.Int64Ty,
8292 /*IsSigned=*/false));
8293 }
8294 }
8295
8296 // Skip the dummy dimension since we have already have its information.
8297 auto DI = DimSizes.begin() + 1;
8298 // Product of dimension.
8299 llvm::Value *DimProd =
8300 llvm::ConstantInt::get(CGF.CGM.Int64Ty, ElementTypeSize);
8301
8302 // Collect info for non-contiguous. Notice that offset, count, and stride
8303 // are only meaningful for array-section, so we insert a null for anything
8304 // other than array-section.
8305 // Also, the size of offset, count, and stride are not the same as
8306 // pointers, base_pointers, sizes, or dims. Instead, the size of offset,
8307 // count, and stride are the same as the number of non-contiguous
8308 // declaration in target update to/from clause.
8309 for (const OMPClauseMappableExprCommon::MappableComponent &Component :
8310 Components) {
8311 const Expr *AssocExpr = Component.getAssociatedExpression();
8312
8313 if (const auto *AE = dyn_cast<ArraySubscriptExpr>(AssocExpr)) {
8314 llvm::Value *Offset = CGF.Builder.CreateIntCast(
8315 CGF.EmitScalarExpr(AE->getIdx()), CGF.Int64Ty,
8316 /*isSigned=*/false);
8317 CurOffsets.push_back(Offset);
8318 CurCounts.push_back(llvm::ConstantInt::get(CGF.Int64Ty, /*V=*/1));
8319 CurStrides.push_back(CurStrides.back());
8320 continue;
8321 }
8322
8323 const auto *OASE = dyn_cast<OMPArraySectionExpr>(AssocExpr);
8324
8325 if (!OASE)
8326 continue;
8327
8328 // Offset
8329 const Expr *OffsetExpr = OASE->getLowerBound();
8330 llvm::Value *Offset = nullptr;
8331 if (!OffsetExpr) {
8332 // If offset is absent, then we just set it to zero.
8333 Offset = llvm::ConstantInt::get(CGF.Int64Ty, 0);
8334 } else {
8335 Offset = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(OffsetExpr),
8336 CGF.Int64Ty,
8337 /*isSigned=*/false);
8338 }
8339 CurOffsets.push_back(Offset);
8340
8341 // Count
8342 const Expr *CountExpr = OASE->getLength();
8343 llvm::Value *Count = nullptr;
8344 if (!CountExpr) {
8345 // In Clang, once a high dimension is an array section, we construct all
8346 // the lower dimension as array section, however, for case like
8347 // arr[0:2][2], Clang construct the inner dimension as an array section
8348 // but it actually is not in an array section form according to spec.
8349 if (!OASE->getColonLocFirst().isValid() &&
8350 !OASE->getColonLocSecond().isValid()) {
8351 Count = llvm::ConstantInt::get(CGF.Int64Ty, 1);
8352 } else {
8353 // OpenMP 5.0, 2.1.5 Array Sections, Description.
8354 // When the length is absent it defaults to ⌈(size −
8355 // lower-bound)/stride⌉, where size is the size of the array
8356 // dimension.
8357 const Expr *StrideExpr = OASE->getStride();
8358 llvm::Value *Stride =
8359 StrideExpr
8360 ? CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(StrideExpr),
8361 CGF.Int64Ty, /*isSigned=*/false)
8362 : nullptr;
8363 if (Stride)
8364 Count = CGF.Builder.CreateUDiv(
8365 CGF.Builder.CreateNUWSub(*DI, Offset), Stride);
8366 else
8367 Count = CGF.Builder.CreateNUWSub(*DI, Offset);
8368 }
8369 } else {
8370 Count = CGF.EmitScalarExpr(CountExpr);
8371 }
8372 Count = CGF.Builder.CreateIntCast(Count, CGF.Int64Ty, /*isSigned=*/false);
8373 CurCounts.push_back(Count);
8374
8375 // Stride_n' = Stride_n * (D_0 * D_1 ... * D_n-1) * Unit size
8376 // Take `int arr[5][5][5]` and `arr[0:2:2][1:2:1][0:2:2]` as an example:
8377 // Offset Count Stride
8378 // D0 0 1 4 (int) <- dummy dimension
8379 // D1 0 2 8 (2 * (1) * 4)
8380 // D2 1 2 20 (1 * (1 * 5) * 4)
8381 // D3 0 2 200 (2 * (1 * 5 * 4) * 4)
8382 const Expr *StrideExpr = OASE->getStride();
8383 llvm::Value *Stride =
8384 StrideExpr
8385 ? CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(StrideExpr),
8386 CGF.Int64Ty, /*isSigned=*/false)
8387 : nullptr;
8388 DimProd = CGF.Builder.CreateNUWMul(DimProd, *(DI - 1));
8389 if (Stride)
8390 CurStrides.push_back(CGF.Builder.CreateNUWMul(DimProd, Stride));
8391 else
8392 CurStrides.push_back(DimProd);
8393 if (DI != DimSizes.end())
8394 ++DI;
8395 }
8396
8397 CombinedInfo.NonContigInfo.Offsets.push_back(CurOffsets);
8398 CombinedInfo.NonContigInfo.Counts.push_back(CurCounts);
8399 CombinedInfo.NonContigInfo.Strides.push_back(CurStrides);
8400 }
8401
8402 /// Return the adjusted map modifiers if the declaration a capture refers to
8403 /// appears in a first-private clause. This is expected to be used only with
8404 /// directives that start with 'target'.
8405 MappableExprsHandler::OpenMPOffloadMappingFlags
8406 getMapModifiersForPrivateClauses(const CapturedStmt::Capture &Cap) const {
8407 assert(Cap.capturesVariable() && "Expected capture by reference only!")(static_cast<void> (0));
8408
8409 // A first private variable captured by reference will use only the
8410 // 'private ptr' and 'map to' flag. Return the right flags if the captured
8411 // declaration is known as first-private in this handler.
8412 if (FirstPrivateDecls.count(Cap.getCapturedVar())) {
8413 if (Cap.getCapturedVar()->getType()->isAnyPointerType())
8414 return MappableExprsHandler::OMP_MAP_TO |
8415 MappableExprsHandler::OMP_MAP_PTR_AND_OBJ;
8416 return MappableExprsHandler::OMP_MAP_PRIVATE |
8417 MappableExprsHandler::OMP_MAP_TO;
8418 }
8419 return MappableExprsHandler::OMP_MAP_TO |
8420 MappableExprsHandler::OMP_MAP_FROM;
8421 }
8422
8423 static OpenMPOffloadMappingFlags getMemberOfFlag(unsigned Position) {
8424 // Rotate by getFlagMemberOffset() bits.
8425 return static_cast<OpenMPOffloadMappingFlags>(((uint64_t)Position + 1)
8426 << getFlagMemberOffset());
8427 }
8428
8429 static void setCorrectMemberOfFlag(OpenMPOffloadMappingFlags &Flags,
8430 OpenMPOffloadMappingFlags MemberOfFlag) {
8431 // If the entry is PTR_AND_OBJ but has not been marked with the special
8432 // placeholder value 0xFFFF in the MEMBER_OF field, then it should not be
8433 // marked as MEMBER_OF.
8434 if ((Flags & OMP_MAP_PTR_AND_OBJ) &&
8435 ((Flags & OMP_MAP_MEMBER_OF) != OMP_MAP_MEMBER_OF))
8436 return;
8437
8438 // Reset the placeholder value to prepare the flag for the assignment of the
8439 // proper MEMBER_OF value.
8440 Flags &= ~OMP_MAP_MEMBER_OF;
8441 Flags |= MemberOfFlag;
8442 }
8443
8444 void getPlainLayout(const CXXRecordDecl *RD,
8445 llvm::SmallVectorImpl<const FieldDecl *> &Layout,
8446 bool AsBase) const {
8447 const CGRecordLayout &RL = CGF.getTypes().getCGRecordLayout(RD);
8448
8449 llvm::StructType *St =
8450 AsBase ? RL.getBaseSubobjectLLVMType() : RL.getLLVMType();
8451
8452 unsigned NumElements = St->getNumElements();
8453 llvm::SmallVector<
8454 llvm::PointerUnion<const CXXRecordDecl *, const FieldDecl *>, 4>
8455 RecordLayout(NumElements);
8456
8457 // Fill bases.
8458 for (const auto &I : RD->bases()) {
8459 if (I.isVirtual())
8460 continue;
8461 const auto *Base = I.getType()->getAsCXXRecordDecl();
8462 // Ignore empty bases.
8463 if (Base->isEmpty() || CGF.getContext()
8464 .getASTRecordLayout(Base)
8465 .getNonVirtualSize()
8466 .isZero())
8467 continue;
8468
8469 unsigned FieldIndex = RL.getNonVirtualBaseLLVMFieldNo(Base);
8470 RecordLayout[FieldIndex] = Base;
8471 }
8472 // Fill in virtual bases.
8473 for (const auto &I : RD->vbases()) {
8474 const auto *Base = I.getType()->getAsCXXRecordDecl();
8475 // Ignore empty bases.
8476 if (Base->isEmpty())
8477 continue;
8478 unsigned FieldIndex = RL.getVirtualBaseIndex(Base);
8479 if (RecordLayout[FieldIndex])
8480 continue;
8481 RecordLayout[FieldIndex] = Base;
8482 }
8483 // Fill in all the fields.
8484 assert(!RD->isUnion() && "Unexpected union.")(static_cast<void> (0));
8485 for (const auto *Field : RD->fields()) {
8486 // Fill in non-bitfields. (Bitfields always use a zero pattern, which we
8487 // will fill in later.)
8488 if (!Field->isBitField() && !Field->isZeroSize(CGF.getContext())) {
8489 unsigned FieldIndex = RL.getLLVMFieldNo(Field);
8490 RecordLayout[FieldIndex] = Field;
8491 }
8492 }
8493 for (const llvm::PointerUnion<const CXXRecordDecl *, const FieldDecl *>
8494 &Data : RecordLayout) {
8495 if (Data.isNull())
8496 continue;
8497 if (const auto *Base = Data.dyn_cast<const CXXRecordDecl *>())
8498 getPlainLayout(Base, Layout, /*AsBase=*/true);
8499 else
8500 Layout.push_back(Data.get<const FieldDecl *>());
8501 }
8502 }
8503
8504 /// Generate all the base pointers, section pointers, sizes, map types, and
8505 /// mappers for the extracted mappable expressions (all included in \a
8506 /// CombinedInfo). Also, for each item that relates with a device pointer, a
8507 /// pair of the relevant declaration and index where it occurs is appended to
8508 /// the device pointers info array.
8509 void generateAllInfoForClauses(
8510 ArrayRef<const OMPClause *> Clauses, MapCombinedInfoTy &CombinedInfo,
8511 const llvm::DenseSet<CanonicalDeclPtr<const Decl>> &SkipVarSet =
8512 llvm::DenseSet<CanonicalDeclPtr<const Decl>>()) const {
8513 // We have to process the component lists that relate with the same
8514 // declaration in a single chunk so that we can generate the map flags
8515 // correctly. Therefore, we organize all lists in a map.
8516 enum MapKind { Present, Allocs, Other, Total };
8517 llvm::MapVector<CanonicalDeclPtr<const Decl>,
8518 SmallVector<SmallVector<MapInfo, 8>, 4>>
8519 Info;
8520
8521 // Helper function to fill the information map for the different supported
8522 // clauses.
8523 auto &&InfoGen =
8524 [&Info, &SkipVarSet](
8525 const ValueDecl *D, MapKind Kind,
8526 OMPClauseMappableExprCommon::MappableExprComponentListRef L,
8527 OpenMPMapClauseKind MapType,
8528 ArrayRef<OpenMPMapModifierKind> MapModifiers,
8529 ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
8530 bool ReturnDevicePointer, bool IsImplicit, const ValueDecl *Mapper,
8531 const Expr *VarRef = nullptr, bool ForDeviceAddr = false) {
8532 if (SkipVarSet.contains(D))
8533 return;
8534 auto It = Info.find(D);
8535 if (It == Info.end())
8536 It = Info
8537 .insert(std::make_pair(
8538 D, SmallVector<SmallVector<MapInfo, 8>, 4>(Total)))
8539 .first;
8540 It->second[Kind].emplace_back(
8541 L, MapType, MapModifiers, MotionModifiers, ReturnDevicePointer,
8542 IsImplicit, Mapper, VarRef, ForDeviceAddr);
8543 };
8544
8545 for (const auto *Cl : Clauses) {
8546 const auto *C = dyn_cast<OMPMapClause>(Cl);
8547 if (!C)
8548 continue;
8549 MapKind Kind = Other;
8550 if (!C->getMapTypeModifiers().empty() &&
8551 llvm::any_of(C->getMapTypeModifiers(), [](OpenMPMapModifierKind K) {
8552 return K == OMPC_MAP_MODIFIER_present;
8553 }))
8554 Kind = Present;
8555 else if (C->getMapType() == OMPC_MAP_alloc)
8556 Kind = Allocs;
8557 const auto *EI = C->getVarRefs().begin();
8558 for (const auto L : C->component_lists()) {
8559 const Expr *E = (C->getMapLoc().isValid()) ? *EI : nullptr;
8560 InfoGen(std::get<0>(L), Kind, std::get<1>(L), C->getMapType(),
8561 C->getMapTypeModifiers(), llvm::None,
8562 /*ReturnDevicePointer=*/false, C->isImplicit(), std::get<2>(L),
8563 E);
8564 ++EI;
8565 }
8566 }
8567 for (const auto *Cl : Clauses) {
8568 const auto *C = dyn_cast<OMPToClause>(Cl);
8569 if (!C)
8570 continue;
8571 MapKind Kind = Other;
8572 if (!C->getMotionModifiers().empty() &&
8573 llvm::any_of(C->getMotionModifiers(), [](OpenMPMotionModifierKind K) {
8574 return K == OMPC_MOTION_MODIFIER_present;
8575 }))
8576 Kind = Present;
8577 const auto *EI = C->getVarRefs().begin();
8578 for (const auto L : C->component_lists()) {
8579 InfoGen(std::get<0>(L), Kind, std::get<1>(L), OMPC_MAP_to, llvm::None,
8580 C->getMotionModifiers(), /*ReturnDevicePointer=*/false,
8581 C->isImplicit(), std::get<2>(L), *EI);
8582 ++EI;
8583 }
8584 }
8585 for (const auto *Cl : Clauses) {
8586 const auto *C = dyn_cast<OMPFromClause>(Cl);
8587 if (!C)
8588 continue;
8589 MapKind Kind = Other;
8590 if (!C->getMotionModifiers().empty() &&
8591 llvm::any_of(C->getMotionModifiers(), [](OpenMPMotionModifierKind K) {
8592 return K == OMPC_MOTION_MODIFIER_present;
8593 }))
8594 Kind = Present;
8595 const auto *EI = C->getVarRefs().begin();
8596 for (const auto L : C->component_lists()) {
8597 InfoGen(std::get<0>(L), Kind, std::get<1>(L), OMPC_MAP_from, llvm::None,
8598 C->getMotionModifiers(), /*ReturnDevicePointer=*/false,
8599 C->isImplicit(), std::get<2>(L), *EI);
8600 ++EI;
8601 }
8602 }
8603
8604 // Look at the use_device_ptr clause information and mark the existing map
8605 // entries as such. If there is no map information for an entry in the
8606 // use_device_ptr list, we create one with map type 'alloc' and zero size
8607 // section. It is the user fault if that was not mapped before. If there is
8608 // no map information and the pointer is a struct member, then we defer the
8609 // emission of that entry until the whole struct has been processed.
8610 llvm::MapVector<CanonicalDeclPtr<const Decl>,
8611 SmallVector<DeferredDevicePtrEntryTy, 4>>
8612 DeferredInfo;
8613 MapCombinedInfoTy UseDevicePtrCombinedInfo;
8614
8615 for (const auto *Cl : Clauses) {
8616 const auto *C = dyn_cast<OMPUseDevicePtrClause>(Cl);
8617 if (!C)
8618 continue;
8619 for (const auto L : C->component_lists()) {
8620 OMPClauseMappableExprCommon::MappableExprComponentListRef Components =
8621 std::get<1>(L);
8622 assert(!Components.empty() &&(static_cast<void> (0))
8623 "Not expecting empty list of components!")(static_cast<void> (0));
8624 const ValueDecl *VD = Components.back().getAssociatedDeclaration();
8625 VD = cast<ValueDecl>(VD->getCanonicalDecl());
8626 const Expr *IE = Components.back().getAssociatedExpression();
8627 // If the first component is a member expression, we have to look into
8628 // 'this', which maps to null in the map of map information. Otherwise
8629 // look directly for the information.
8630 auto It = Info.find(isa<MemberExpr>(IE) ? nullptr : VD);
8631
8632 // We potentially have map information for this declaration already.
8633 // Look for the first set of components that refer to it.
8634 if (It != Info.end()) {
8635 bool Found = false;
8636 for (auto &Data : It->second) {
8637 auto *CI = llvm::find_if(Data, [VD](const MapInfo &MI) {
8638 return MI.Components.back().getAssociatedDeclaration() == VD;
8639 });
8640 // If we found a map entry, signal that the pointer has to be
8641 // returned and move on to the next declaration. Exclude cases where
8642 // the base pointer is mapped as array subscript, array section or
8643 // array shaping. The base address is passed as a pointer to base in
8644 // this case and cannot be used as a base for use_device_ptr list
8645 // item.
8646 if (CI != Data.end()) {
8647 auto PrevCI = std::next(CI->Components.rbegin());
8648 const auto *VarD = dyn_cast<VarDecl>(VD);
8649 if (CGF.CGM.getOpenMPRuntime().hasRequiresUnifiedSharedMemory() ||
8650 isa<MemberExpr>(IE) ||
8651 !VD->getType().getNonReferenceType()->isPointerType() ||
8652 PrevCI == CI->Components.rend() ||
8653 isa<MemberExpr>(PrevCI->getAssociatedExpression()) || !VarD ||
8654 VarD->hasLocalStorage()) {
8655 CI->ReturnDevicePointer = true;
8656 Found = true;
8657 break;
8658 }
8659 }
8660 }
8661 if (Found)
8662 continue;
8663 }
8664
8665 // We didn't find any match in our map information - generate a zero
8666 // size array section - if the pointer is a struct member we defer this
8667 // action until the whole struct has been processed.
8668 if (isa<MemberExpr>(IE)) {
8669 // Insert the pointer into Info to be processed by
8670 // generateInfoForComponentList. Because it is a member pointer
8671 // without a pointee, no entry will be generated for it, therefore
8672 // we need to generate one after the whole struct has been processed.
8673 // Nonetheless, generateInfoForComponentList must be called to take
8674 // the pointer into account for the calculation of the range of the
8675 // partial struct.
8676 InfoGen(nullptr, Other, Components, OMPC_MAP_unknown, llvm::None,
8677 llvm::None, /*ReturnDevicePointer=*/false, C->isImplicit(),
8678 nullptr);
8679 DeferredInfo[nullptr].emplace_back(IE, VD, /*ForDeviceAddr=*/false);
8680 } else {
8681 llvm::Value *Ptr =
8682 CGF.EmitLoadOfScalar(CGF.EmitLValue(IE), IE->getExprLoc());
8683 UseDevicePtrCombinedInfo.Exprs.push_back(VD);
8684 UseDevicePtrCombinedInfo.BasePointers.emplace_back(Ptr, VD);
8685 UseDevicePtrCombinedInfo.Pointers.push_back(Ptr);
8686 UseDevicePtrCombinedInfo.Sizes.push_back(
8687 llvm::Constant::getNullValue(CGF.Int64Ty));
8688 UseDevicePtrCombinedInfo.Types.push_back(OMP_MAP_RETURN_PARAM);
8689 UseDevicePtrCombinedInfo.Mappers.push_back(nullptr);
8690 }
8691 }
8692 }
8693
8694 // Look at the use_device_addr clause information and mark the existing map
8695 // entries as such. If there is no map information for an entry in the
8696 // use_device_addr list, we create one with map type 'alloc' and zero size
8697 // section. It is the user fault if that was not mapped before. If there is
8698 // no map information and the pointer is a struct member, then we defer the
8699 // emission of that entry until the whole struct has been processed.
8700 llvm::SmallDenseSet<CanonicalDeclPtr<const Decl>, 4> Processed;
8701 for (const auto *Cl : Clauses) {
8702 const auto *C = dyn_cast<OMPUseDeviceAddrClause>(Cl);
8703 if (!C)
8704 continue;
8705 for (const auto L : C->component_lists()) {
8706 assert(!std::get<1>(L).empty() &&(static_cast<void> (0))
8707 "Not expecting empty list of components!")(static_cast<void> (0));
8708 const ValueDecl *VD = std::get<1>(L).back().getAssociatedDeclaration();
8709 if (!Processed.insert(VD).second)
8710 continue;
8711 VD = cast<ValueDecl>(VD->getCanonicalDecl());
8712 const Expr *IE = std::get<1>(L).back().getAssociatedExpression();
8713 // If the first component is a member expression, we have to look into
8714 // 'this', which maps to null in the map of map information. Otherwise
8715 // look directly for the information.
8716 auto It = Info.find(isa<MemberExpr>(IE) ? nullptr : VD);
8717
8718 // We potentially have map information for this declaration already.
8719 // Look for the first set of components that refer to it.
8720 if (It != Info.end()) {
8721 bool Found = false;
8722 for (auto &Data : It->second) {
8723 auto *CI = llvm::find_if(Data, [VD](const MapInfo &MI) {
8724 return MI.Components.back().getAssociatedDeclaration() == VD;
8725 });
8726 // If we found a map entry, signal that the pointer has to be
8727 // returned and move on to the next declaration.
8728 if (CI != Data.end()) {
8729 CI->ReturnDevicePointer = true;
8730 Found = true;
8731 break;
8732 }
8733 }
8734 if (Found)
8735 continue;
8736 }
8737
8738 // We didn't find any match in our map information - generate a zero
8739 // size array section - if the pointer is a struct member we defer this
8740 // action until the whole struct has been processed.
8741 if (isa<MemberExpr>(IE)) {
8742 // Insert the pointer into Info to be processed by
8743 // generateInfoForComponentList. Because it is a member pointer
8744 // without a pointee, no entry will be generated for it, therefore
8745 // we need to generate one after the whole struct has been processed.
8746 // Nonetheless, generateInfoForComponentList must be called to take
8747 // the pointer into account for the calculation of the range of the
8748 // partial struct.
8749 InfoGen(nullptr, Other, std::get<1>(L), OMPC_MAP_unknown, llvm::None,
8750 llvm::None, /*ReturnDevicePointer=*/false, C->isImplicit(),
8751 nullptr, nullptr, /*ForDeviceAddr=*/true);
8752 DeferredInfo[nullptr].emplace_back(IE, VD, /*ForDeviceAddr=*/true);
8753 } else {
8754 llvm::Value *Ptr;
8755 if (IE->isGLValue())
8756 Ptr = CGF.EmitLValue(IE).getPointer(CGF);
8757 else
8758 Ptr = CGF.EmitScalarExpr(IE);
8759 CombinedInfo.Exprs.push_back(VD);
8760 CombinedInfo.BasePointers.emplace_back(Ptr, VD);
8761 CombinedInfo.Pointers.push_back(Ptr);
8762 CombinedInfo.Sizes.push_back(
8763 llvm::Constant::getNullValue(CGF.Int64Ty));
8764 CombinedInfo.Types.push_back(OMP_MAP_RETURN_PARAM);
8765 CombinedInfo.Mappers.push_back(nullptr);
8766 }
8767 }
8768 }
8769
8770 for (const auto &Data : Info) {
8771 StructRangeInfoTy PartialStruct;
8772 // Temporary generated information.
8773 MapCombinedInfoTy CurInfo;
8774 const Decl *D = Data.first;
8775 const ValueDecl *VD = cast_or_null<ValueDecl>(D);
8776 for (const auto &M : Data.second) {
8777 for (const MapInfo &L : M) {
8778 assert(!L.Components.empty() &&(static_cast<void> (0))
8779 "Not expecting declaration with no component lists.")(static_cast<void> (0));
8780
8781 // Remember the current base pointer index.
8782 unsigned CurrentBasePointersIdx = CurInfo.BasePointers.size();
8783 CurInfo.NonContigInfo.IsNonContiguous =
8784 L.Components.back().isNonContiguous();
8785 generateInfoForComponentList(
8786 L.MapType, L.MapModifiers, L.MotionModifiers, L.Components,
8787 CurInfo, PartialStruct, /*IsFirstComponentList=*/false,
8788 L.IsImplicit, L.Mapper, L.ForDeviceAddr, VD, L.VarRef);
8789
8790 // If this entry relates with a device pointer, set the relevant
8791 // declaration and add the 'return pointer' flag.
8792 if (L.ReturnDevicePointer) {
8793 assert(CurInfo.BasePointers.size() > CurrentBasePointersIdx &&(static_cast<void> (0))
8794 "Unexpected number of mapped base pointers.")(static_cast<void> (0));
8795
8796 const ValueDecl *RelevantVD =
8797 L.Components.back().getAssociatedDeclaration();
8798 assert(RelevantVD &&(static_cast<void> (0))
8799 "No relevant declaration related with device pointer??")(static_cast<void> (0));
8800
8801 CurInfo.BasePointers[CurrentBasePointersIdx].setDevicePtrDecl(
8802 RelevantVD);
8803 CurInfo.Types[CurrentBasePointersIdx] |= OMP_MAP_RETURN_PARAM;
8804 }
8805 }
8806 }
8807
8808 // Append any pending zero-length pointers which are struct members and
8809 // used with use_device_ptr or use_device_addr.
8810 auto CI = DeferredInfo.find(Data.first);
8811 if (CI != DeferredInfo.end()) {
8812 for (const DeferredDevicePtrEntryTy &L : CI->second) {
8813 llvm::Value *BasePtr;
8814 llvm::Value *Ptr;
8815 if (L.ForDeviceAddr) {
8816 if (L.IE->isGLValue())
8817 Ptr = this->CGF.EmitLValue(L.IE).getPointer(CGF);
8818 else
8819 Ptr = this->CGF.EmitScalarExpr(L.IE);
8820 BasePtr = Ptr;
8821 // Entry is RETURN_PARAM. Also, set the placeholder value
8822 // MEMBER_OF=FFFF so that the entry is later updated with the
8823 // correct value of MEMBER_OF.
8824 CurInfo.Types.push_back(OMP_MAP_RETURN_PARAM | OMP_MAP_MEMBER_OF);
8825 } else {
8826 BasePtr = this->CGF.EmitLValue(L.IE).getPointer(CGF);
8827 Ptr = this->CGF.EmitLoadOfScalar(this->CGF.EmitLValue(L.IE),
8828 L.IE->getExprLoc());
8829 // Entry is PTR_AND_OBJ and RETURN_PARAM. Also, set the
8830 // placeholder value MEMBER_OF=FFFF so that the entry is later
8831 // updated with the correct value of MEMBER_OF.
8832 CurInfo.Types.push_back(OMP_MAP_PTR_AND_OBJ | OMP_MAP_RETURN_PARAM |
8833 OMP_MAP_MEMBER_OF);
8834 }
8835 CurInfo.Exprs.push_back(L.VD);
8836 CurInfo.BasePointers.emplace_back(BasePtr, L.VD);
8837 CurInfo.Pointers.push_back(Ptr);
8838 CurInfo.Sizes.push_back(
8839 llvm::Constant::getNullValue(this->CGF.Int64Ty));
8840 CurInfo.Mappers.push_back(nullptr);
8841 }
8842 }
8843 // If there is an entry in PartialStruct it means we have a struct with
8844 // individual members mapped. Emit an extra combined entry.
8845 if (PartialStruct.Base.isValid()) {
8846 CurInfo.NonContigInfo.Dims.push_back(0);
8847 emitCombinedEntry(CombinedInfo, CurInfo.Types, PartialStruct, VD);
8848 }
8849
8850 // We need to append the results of this capture to what we already
8851 // have.
8852 CombinedInfo.append(CurInfo);
8853 }
8854 // Append data for use_device_ptr clauses.
8855 CombinedInfo.append(UseDevicePtrCombinedInfo);
8856 }
8857
8858public:
8859 MappableExprsHandler(const OMPExecutableDirective &Dir, CodeGenFunction &CGF)
8860 : CurDir(&Dir), CGF(CGF) {
8861 // Extract firstprivate clause information.
8862 for (const auto *C : Dir.getClausesOfKind<OMPFirstprivateClause>())
8863 for (const auto *D : C->varlists())
8864 FirstPrivateDecls.try_emplace(
8865 cast<VarDecl>(cast<DeclRefExpr>(D)->getDecl()), C->isImplicit());
8866 // Extract implicit firstprivates from uses_allocators clauses.
8867 for (const auto *C : Dir.getClausesOfKind<OMPUsesAllocatorsClause>()) {
8868 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
8869 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
8870 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(D.AllocatorTraits))
8871 FirstPrivateDecls.try_emplace(cast<VarDecl>(DRE->getDecl()),
8872 /*Implicit=*/true);
8873 else if (const auto *VD = dyn_cast<VarDecl>(
8874 cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts())
8875 ->getDecl()))
8876 FirstPrivateDecls.try_emplace(VD, /*Implicit=*/true);
8877 }
8878 }
8879 // Extract device pointer clause information.
8880 for (const auto *C : Dir.getClausesOfKind<OMPIsDevicePtrClause>())
8881 for (auto L : C->component_lists())
8882 DevPointersMap[std::get<0>(L)].push_back(std::get<1>(L));
8883 }
8884
8885 /// Constructor for the declare mapper directive.
8886 MappableExprsHandler(const OMPDeclareMapperDecl &Dir, CodeGenFunction &CGF)
8887 : CurDir(&Dir), CGF(CGF) {}
8888
8889 /// Generate code for the combined entry if we have a partially mapped struct
8890 /// and take care of the mapping flags of the arguments corresponding to
8891 /// individual struct members.
8892 void emitCombinedEntry(MapCombinedInfoTy &CombinedInfo,
8893 MapFlagsArrayTy &CurTypes,
8894 const StructRangeInfoTy &PartialStruct,
8895 const ValueDecl *VD = nullptr,
8896 bool NotTargetParams = true) const {
8897 if (CurTypes.size() == 1 &&
8898 ((CurTypes.back() & OMP_MAP_MEMBER_OF) != OMP_MAP_MEMBER_OF) &&
8899 !PartialStruct.IsArraySection)
8900 return;
8901 Address LBAddr = PartialStruct.LowestElem.second;
8902 Address HBAddr = PartialStruct.HighestElem.second;
8903 if (PartialStruct.HasCompleteRecord) {
8904 LBAddr = PartialStruct.LB;
8905 HBAddr = PartialStruct.LB;
8906 }
8907 CombinedInfo.Exprs.push_back(VD);
8908 // Base is the base of the struct
8909 CombinedInfo.BasePointers.push_back(PartialStruct.Base.getPointer());
8910 // Pointer is the address of the lowest element
8911 llvm::Value *LB = LBAddr.getPointer();
8912 CombinedInfo.Pointers.push_back(LB);
8913 // There should not be a mapper for a combined entry.
8914 CombinedInfo.Mappers.push_back(nullptr);
8915 // Size is (addr of {highest+1} element) - (addr of lowest element)
8916 llvm::Value *HB = HBAddr.getPointer();
8917 llvm::Value *HAddr =
8918 CGF.Builder.CreateConstGEP1_32(HBAddr.getElementType(), HB, /*Idx0=*/1);
8919 llvm::Value *CLAddr = CGF.Builder.CreatePointerCast(LB, CGF.VoidPtrTy);
8920 llvm::Value *CHAddr = CGF.Builder.CreatePointerCast(HAddr, CGF.VoidPtrTy);
8921 llvm::Value *Diff = CGF.Builder.CreatePtrDiff(CHAddr, CLAddr);
8922 llvm::Value *Size = CGF.Builder.CreateIntCast(Diff, CGF.Int64Ty,
8923 /*isSigned=*/false);
8924 CombinedInfo.Sizes.push_back(Size);
8925 // Map type is always TARGET_PARAM, if generate info for captures.
8926 CombinedInfo.Types.push_back(NotTargetParams ? OMP_MAP_NONE
8927 : OMP_MAP_TARGET_PARAM);
8928 // If any element has the present modifier, then make sure the runtime
8929 // doesn't attempt to allocate the struct.
8930 if (CurTypes.end() !=
8931 llvm::find_if(CurTypes, [](OpenMPOffloadMappingFlags Type) {
8932 return Type & OMP_MAP_PRESENT;
8933 }))
8934 CombinedInfo.Types.back() |= OMP_MAP_PRESENT;
8935 // Remove TARGET_PARAM flag from the first element
8936 (*CurTypes.begin()) &= ~OMP_MAP_TARGET_PARAM;
8937 // If any element has the ompx_hold modifier, then make sure the runtime
8938 // uses the hold reference count for the struct as a whole so that it won't
8939 // be unmapped by an extra dynamic reference count decrement. Add it to all
8940 // elements as well so the runtime knows which reference count to check
8941 // when determining whether it's time for device-to-host transfers of
8942 // individual elements.
8943 if (CurTypes.end() !=
8944 llvm::find_if(CurTypes, [](OpenMPOffloadMappingFlags Type) {
8945 return Type & OMP_MAP_OMPX_HOLD;
8946 })) {
8947 CombinedInfo.Types.back() |= OMP_MAP_OMPX_HOLD;
8948 for (auto &M : CurTypes)
8949 M |= OMP_MAP_OMPX_HOLD;
8950 }
8951
8952 // All other current entries will be MEMBER_OF the combined entry
8953 // (except for PTR_AND_OBJ entries which do not have a placeholder value
8954 // 0xFFFF in the MEMBER_OF field).
8955 OpenMPOffloadMappingFlags MemberOfFlag =
8956 getMemberOfFlag(CombinedInfo.BasePointers.size() - 1);
8957 for (auto &M : CurTypes)
8958 setCorrectMemberOfFlag(M, MemberOfFlag);
8959 }
8960
8961 /// Generate all the base pointers, section pointers, sizes, map types, and
8962 /// mappers for the extracted mappable expressions (all included in \a
8963 /// CombinedInfo). Also, for each item that relates with a device pointer, a
8964 /// pair of the relevant declaration and index where it occurs is appended to
8965 /// the device pointers info array.
8966 void generateAllInfo(
8967 MapCombinedInfoTy &CombinedInfo,
8968 const llvm::DenseSet<CanonicalDeclPtr<const Decl>> &SkipVarSet =
8969 llvm::DenseSet<CanonicalDeclPtr<const Decl>>()) const {
8970 assert(CurDir.is<const OMPExecutableDirective *>() &&(static_cast<void> (0))
8971 "Expect a executable directive")(static_cast<void> (0));
8972 const auto *CurExecDir = CurDir.get<const OMPExecutableDirective *>();
8973 generateAllInfoForClauses(CurExecDir->clauses(), CombinedInfo, SkipVarSet);
8974 }
8975
8976 /// Generate all the base pointers, section pointers, sizes, map types, and
8977 /// mappers for the extracted map clauses of user-defined mapper (all included
8978 /// in \a CombinedInfo).
8979 void generateAllInfoForMapper(MapCombinedInfoTy &CombinedInfo) const {
8980 assert(CurDir.is<const OMPDeclareMapperDecl *>() &&(static_cast<void> (0))
8981 "Expect a declare mapper directive")(static_cast<void> (0));
8982 const auto *CurMapperDir = CurDir.get<const OMPDeclareMapperDecl *>();
8983 generateAllInfoForClauses(CurMapperDir->clauses(), CombinedInfo);
8984 }
8985
8986 /// Emit capture info for lambdas for variables captured by reference.
8987 void generateInfoForLambdaCaptures(
8988 const ValueDecl *VD, llvm::Value *Arg, MapCombinedInfoTy &CombinedInfo,
8989 llvm::DenseMap<llvm::Value *, llvm::Value *> &LambdaPointers) const {
8990 const auto *RD = VD->getType()
8991 .getCanonicalType()
8992 .getNonReferenceType()
8993 ->getAsCXXRecordDecl();
8994 if (!RD || !RD->isLambda())
8995 return;
8996 Address VDAddr = Address(Arg, CGF.getContext().getDeclAlign(VD));
8997 LValue VDLVal = CGF.MakeAddrLValue(
8998 VDAddr, VD->getType().getCanonicalType().getNonReferenceType());
8999 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
9000 FieldDecl *ThisCapture = nullptr;
9001 RD->getCaptureFields(Captures, ThisCapture);
9002 if (ThisCapture) {
9003 LValue ThisLVal =
9004 CGF.EmitLValueForFieldInitialization(VDLVal, ThisCapture);
9005 LValue ThisLValVal = CGF.EmitLValueForField(VDLVal, ThisCapture);
9006 LambdaPointers.try_emplace(ThisLVal.getPointer(CGF),
9007 VDLVal.getPointer(CGF));
9008 CombinedInfo.Exprs.push_back(VD);
9009 CombinedInfo.BasePointers.push_back(ThisLVal.getPointer(CGF));
9010 CombinedInfo.Pointers.push_back(ThisLValVal.getPointer(CGF));
9011 CombinedInfo.Sizes.push_back(
9012 CGF.Builder.CreateIntCast(CGF.getTypeSize(CGF.getContext().VoidPtrTy),
9013 CGF.Int64Ty, /*isSigned=*/true));
9014 CombinedInfo.Types.push_back(OMP_MAP_PTR_AND_OBJ | OMP_MAP_LITERAL |
9015 OMP_MAP_MEMBER_OF | OMP_MAP_IMPLICIT);
9016 CombinedInfo.Mappers.push_back(nullptr);
9017 }
9018 for (const LambdaCapture &LC : RD->captures()) {
9019 if (!LC.capturesVariable())
9020 continue;
9021 const VarDecl *VD = LC.getCapturedVar();
9022 if (LC.getCaptureKind() != LCK_ByRef && !VD->getType()->isPointerType())
9023 continue;
9024 auto It = Captures.find(VD);
9025 assert(It != Captures.end() && "Found lambda capture without field.")(static_cast<void> (0));
9026 LValue VarLVal = CGF.EmitLValueForFieldInitialization(VDLVal, It->second);
9027 if (LC.getCaptureKind() == LCK_ByRef) {
9028 LValue VarLValVal = CGF.EmitLValueForField(VDLVal, It->second);
9029 LambdaPointers.try_emplace(VarLVal.getPointer(CGF),
9030 VDLVal.getPointer(CGF));
9031 CombinedInfo.Exprs.push_back(VD);
9032 CombinedInfo.BasePointers.push_back(VarLVal.getPointer(CGF));
9033 CombinedInfo.Pointers.push_back(VarLValVal.getPointer(CGF));
9034 CombinedInfo.Sizes.push_back(CGF.Builder.CreateIntCast(
9035 CGF.getTypeSize(
9036 VD->getType().getCanonicalType().getNonReferenceType()),
9037 CGF.Int64Ty, /*isSigned=*/true));
9038 } else {
9039 RValue VarRVal = CGF.EmitLoadOfLValue(VarLVal, RD->getLocation());
9040 LambdaPointers.try_emplace(VarLVal.getPointer(CGF),
9041 VDLVal.getPointer(CGF));
9042 CombinedInfo.Exprs.push_back(VD);
9043 CombinedInfo.BasePointers.push_back(VarLVal.getPointer(CGF));
9044 CombinedInfo.Pointers.push_back(VarRVal.getScalarVal());
9045 CombinedInfo.Sizes.push_back(llvm::ConstantInt::get(CGF.Int64Ty, 0));
9046 }
9047 CombinedInfo.Types.push_back(OMP_MAP_PTR_AND_OBJ | OMP_MAP_LITERAL |
9048 OMP_MAP_MEMBER_OF | OMP_MAP_IMPLICIT);
9049 CombinedInfo.Mappers.push_back(nullptr);
9050 }
9051 }
9052
9053 /// Set correct indices for lambdas captures.
9054 void adjustMemberOfForLambdaCaptures(
9055 const llvm::DenseMap<llvm::Value *, llvm::Value *> &LambdaPointers,
9056 MapBaseValuesArrayTy &BasePointers, MapValuesArrayTy &Pointers,
9057 MapFlagsArrayTy &Types) const {
9058 for (unsigned I = 0, E = Types.size(); I < E; ++I) {
9059 // Set correct member_of idx for all implicit lambda captures.
9060 if (Types[I] != (OMP_MAP_PTR_AND_OBJ | OMP_MAP_LITERAL |
9061 OMP_MAP_MEMBER_OF | OMP_MAP_IMPLICIT))
9062 continue;
9063 llvm::Value *BasePtr = LambdaPointers.lookup(*BasePointers[I]);
9064 assert(BasePtr && "Unable to find base lambda address.")(static_cast<void> (0));
9065 int TgtIdx = -1;
9066 for (unsigned J = I; J > 0; --J) {
9067 unsigned Idx = J - 1;
9068 if (Pointers[Idx] != BasePtr)
9069 continue;
9070 TgtIdx = Idx;
9071 break;
9072 }
9073 assert(TgtIdx != -1 && "Unable to find parent lambda.")(static_cast<void> (0));
9074 // All other current entries will be MEMBER_OF the combined entry
9075 // (except for PTR_AND_OBJ entries which do not have a placeholder value
9076 // 0xFFFF in the MEMBER_OF field).
9077 OpenMPOffloadMappingFlags MemberOfFlag = getMemberOfFlag(TgtIdx);
9078 setCorrectMemberOfFlag(Types[I], MemberOfFlag);
9079 }
9080 }
9081
9082 /// Generate the base pointers, section pointers, sizes, map types, and
9083 /// mappers associated to a given capture (all included in \a CombinedInfo).
9084 void generateInfoForCapture(const CapturedStmt::Capture *Cap,
9085 llvm::Value *Arg, MapCombinedInfoTy &CombinedInfo,
9086 StructRangeInfoTy &PartialStruct) const {
9087 assert(!Cap->capturesVariableArrayType() &&(static_cast<void> (0))
9088 "Not expecting to generate map info for a variable array type!")(static_cast<void> (0));
9089
9090 // We need to know when we generating information for the first component
9091 const ValueDecl *VD = Cap->capturesThis()
9092 ? nullptr
9093 : Cap->getCapturedVar()->getCanonicalDecl();
9094
9095 // If this declaration appears in a is_device_ptr clause we just have to
9096 // pass the pointer by value. If it is a reference to a declaration, we just
9097 // pass its value.
9098 if (DevPointersMap.count(VD)) {
9099 CombinedInfo.Exprs.push_back(VD);
9100 CombinedInfo.BasePointers.emplace_back(Arg, VD);
9101 CombinedInfo.Pointers.push_back(Arg);
9102 CombinedInfo.Sizes.push_back(CGF.Builder.CreateIntCast(
9103 CGF.getTypeSize(CGF.getContext().VoidPtrTy), CGF.Int64Ty,
9104 /*isSigned=*/true));
9105 CombinedInfo.Types.push_back(
9106 (Cap->capturesVariable() ? OMP_MAP_TO : OMP_MAP_LITERAL) |
9107 OMP_MAP_TARGET_PARAM);
9108 CombinedInfo.Mappers.push_back(nullptr);
9109 return;
9110 }
9111
9112 using MapData =
9113 std::tuple<OMPClauseMappableExprCommon::MappableExprComponentListRef,
9114 OpenMPMapClauseKind, ArrayRef<OpenMPMapModifierKind>, bool,
9115 const ValueDecl *, const Expr *>;
9116 SmallVector<MapData, 4> DeclComponentLists;
9117 assert(CurDir.is<const OMPExecutableDirective *>() &&(static_cast<void> (0))
9118 "Expect a executable directive")(static_cast<void> (0));
9119 const auto *CurExecDir = CurDir.get<const OMPExecutableDirective *>();
9120 for (const auto *C : CurExecDir->getClausesOfKind<OMPMapClause>()) {
9121 const auto *EI = C->getVarRefs().begin();
9122 for (const auto L : C->decl_component_lists(VD)) {
9123 const ValueDecl *VDecl, *Mapper;
9124 // The Expression is not correct if the mapping is implicit
9125 const Expr *E = (C->getMapLoc().isValid()) ? *EI : nullptr;
9126 OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
9127 std::tie(VDecl, Components, Mapper) = L;
9128 assert(VDecl == VD && "We got information for the wrong declaration??")(static_cast<void> (0));
9129 assert(!Components.empty() &&(static_cast<void> (0))
9130 "Not expecting declaration with no component lists.")(static_cast<void> (0));
9131 DeclComponentLists.emplace_back(Components, C->getMapType(),
9132 C->getMapTypeModifiers(),
9133 C->isImplicit(), Mapper, E);
9134 ++EI;
9135 }
9136 }
9137 llvm::stable_sort(DeclComponentLists, [](const MapData &LHS,
9138 const MapData &RHS) {
9139 ArrayRef<OpenMPMapModifierKind> MapModifiers = std::get<2>(LHS);
9140 OpenMPMapClauseKind MapType = std::get<1>(RHS);
9141 bool HasPresent = !MapModifiers.empty() &&
9142 llvm::any_of(MapModifiers, [](OpenMPMapModifierKind K) {
9143 return K == clang::OMPC_MAP_MODIFIER_present;
9144 });
9145 bool HasAllocs = MapType == OMPC_MAP_alloc;
9146 MapModifiers = std::get<2>(RHS);
9147 MapType = std::get<1>(LHS);
9148 bool HasPresentR =
9149 !MapModifiers.empty() &&
9150 llvm::any_of(MapModifiers, [](OpenMPMapModifierKind K) {
9151 return K == clang::OMPC_MAP_MODIFIER_present;
9152 });
9153 bool HasAllocsR = MapType == OMPC_MAP_alloc;
9154 return (HasPresent && !HasPresentR) || (HasAllocs && !HasAllocsR);
9155 });
9156
9157 // Find overlapping elements (including the offset from the base element).
9158 llvm::SmallDenseMap<
9159 const MapData *,
9160 llvm::SmallVector<
9161 OMPClauseMappableExprCommon::MappableExprComponentListRef, 4>,
9162 4>
9163 OverlappedData;
9164 size_t Count = 0;
9165 for (const MapData &L : DeclComponentLists) {
9166 OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
9167 OpenMPMapClauseKind MapType;
9168 ArrayRef<OpenMPMapModifierKind> MapModifiers;
9169 bool IsImplicit;
9170 const ValueDecl *Mapper;
9171 const Expr *VarRef;
9172 std::tie(Components, MapType, MapModifiers, IsImplicit, Mapper, VarRef) =
9173 L;
9174 ++Count;
9175 for (const MapData &L1 : makeArrayRef(DeclComponentLists).slice(Count)) {
9176 OMPClauseMappableExprCommon::MappableExprComponentListRef Components1;
9177 std::tie(Components1, MapType, MapModifiers, IsImplicit, Mapper,
9178 VarRef) = L1;
9179 auto CI = Components.rbegin();
9180 auto CE = Components.rend();
9181 auto SI = Components1.rbegin();
9182 auto SE = Components1.rend();
9183 for (; CI != CE && SI != SE; ++CI, ++SI) {
9184 if (CI->getAssociatedExpression()->getStmtClass() !=
9185 SI->getAssociatedExpression()->getStmtClass())
9186 break;
9187 // Are we dealing with different variables/fields?
9188 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
9189 break;
9190 }
9191 // Found overlapping if, at least for one component, reached the head
9192 // of the components list.
9193 if (CI == CE || SI == SE) {
9194 // Ignore it if it is the same component.
9195 if (CI == CE && SI == SE)
9196 continue;
9197 const auto It = (SI == SE) ? CI : SI;
9198 // If one component is a pointer and another one is a kind of
9199 // dereference of this pointer (array subscript, section, dereference,
9200 // etc.), it is not an overlapping.
9201 // Same, if one component is a base and another component is a
9202 // dereferenced pointer memberexpr with the same base.
9203 if (!isa<MemberExpr>(It->getAssociatedExpression()) ||
9204 (std::prev(It)->getAssociatedDeclaration() &&
9205 std::prev(It)
9206 ->getAssociatedDeclaration()
9207 ->getType()
9208 ->isPointerType()) ||
9209 (It->getAssociatedDeclaration() &&
9210 It->getAssociatedDeclaration()->getType()->isPointerType() &&
9211 std::next(It) != CE && std::next(It) != SE))
9212 continue;
9213 const MapData &BaseData = CI == CE ? L : L1;
9214 OMPClauseMappableExprCommon::MappableExprComponentListRef SubData =
9215 SI == SE ? Components : Components1;
9216 auto &OverlappedElements = OverlappedData.FindAndConstruct(&BaseData);
9217 OverlappedElements.getSecond().push_back(SubData);
9218 }
9219 }
9220 }
9221 // Sort the overlapped elements for each item.
9222 llvm::SmallVector<const FieldDecl *, 4> Layout;
9223 if (!OverlappedData.empty()) {
9224 const Type *BaseType = VD->getType().getCanonicalType().getTypePtr();
9225 const Type *OrigType = BaseType->getPointeeOrArrayElementType();
9226 while (BaseType != OrigType) {
9227 BaseType = OrigType->getCanonicalTypeInternal().getTypePtr();
9228 OrigType = BaseType->getPointeeOrArrayElementType();
9229 }
9230
9231 if (const auto *CRD = BaseType->getAsCXXRecordDecl())
9232 getPlainLayout(CRD, Layout, /*AsBase=*/false);
9233 else {
9234 const auto *RD = BaseType->getAsRecordDecl();
9235 Layout.append(RD->field_begin(), RD->field_end());
9236 }
9237 }
9238 for (auto &Pair : OverlappedData) {
9239 llvm::stable_sort(
9240 Pair.getSecond(),
9241 [&Layout](
9242 OMPClauseMappableExprCommon::MappableExprComponentListRef First,
9243 OMPClauseMappableExprCommon::MappableExprComponentListRef
9244 Second) {
9245 auto CI = First.rbegin();
9246 auto CE = First.rend();
9247 auto SI = Second.rbegin();
9248 auto SE = Second.rend();
9249 for (; CI != CE && SI != SE; ++CI, ++SI) {
9250 if (CI->getAssociatedExpression()->getStmtClass() !=
9251 SI->getAssociatedExpression()->getStmtClass())
9252 break;
9253 // Are we dealing with different variables/fields?
9254 if (CI->getAssociatedDeclaration() !=
9255 SI->getAssociatedDeclaration())
9256 break;
9257 }
9258
9259 // Lists contain the same elements.
9260 if (CI == CE && SI == SE)
9261 return false;
9262
9263 // List with less elements is less than list with more elements.
9264 if (CI == CE || SI == SE)
9265 return CI == CE;
9266
9267 const auto *FD1 = cast<FieldDecl>(CI->getAssociatedDeclaration());
9268 const auto *FD2 = cast<FieldDecl>(SI->getAssociatedDeclaration());
9269 if (FD1->getParent() == FD2->getParent())
9270 return FD1->getFieldIndex() < FD2->getFieldIndex();
9271 const auto *It =
9272 llvm::find_if(Layout, [FD1, FD2](const FieldDecl *FD) {
9273 return FD == FD1 || FD == FD2;
9274 });
9275 return *It == FD1;
9276 });
9277 }
9278
9279 // Associated with a capture, because the mapping flags depend on it.
9280 // Go through all of the elements with the overlapped elements.
9281 bool IsFirstComponentList = true;
9282 for (const auto &Pair : OverlappedData) {
9283 const MapData &L = *Pair.getFirst();
9284 OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
9285 OpenMPMapClauseKind MapType;
9286 ArrayRef<OpenMPMapModifierKind> MapModifiers;
9287 bool IsImplicit;
9288 const ValueDecl *Mapper;
9289 const Expr *VarRef;
9290 std::tie(Components, MapType, MapModifiers, IsImplicit, Mapper, VarRef) =
9291 L;
9292 ArrayRef<OMPClauseMappableExprCommon::MappableExprComponentListRef>
9293 OverlappedComponents = Pair.getSecond();
9294 generateInfoForComponentList(
9295 MapType, MapModifiers, llvm::None, Components, CombinedInfo,
9296 PartialStruct, IsFirstComponentList, IsImplicit, Mapper,
9297 /*ForDeviceAddr=*/false, VD, VarRef, OverlappedComponents);
9298 IsFirstComponentList = false;
9299 }
9300 // Go through other elements without overlapped elements.
9301 for (const MapData &L : DeclComponentLists) {
9302 OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
9303 OpenMPMapClauseKind MapType;
9304 ArrayRef<OpenMPMapModifierKind> MapModifiers;
9305 bool IsImplicit;
9306 const ValueDecl *Mapper;
9307 const Expr *VarRef;
9308 std::tie(Components, MapType, MapModifiers, IsImplicit, Mapper, VarRef) =
9309 L;
9310 auto It = OverlappedData.find(&L);
9311 if (It == OverlappedData.end())
9312 generateInfoForComponentList(MapType, MapModifiers, llvm::None,
9313 Components, CombinedInfo, PartialStruct,
9314 IsFirstComponentList, IsImplicit, Mapper,
9315 /*ForDeviceAddr=*/false, VD, VarRef);
9316 IsFirstComponentList = false;
9317 }
9318 }
9319
9320 /// Generate the default map information for a given capture \a CI,
9321 /// record field declaration \a RI and captured value \a CV.
9322 void generateDefaultMapInfo(const CapturedStmt::Capture &CI,
9323 const FieldDecl &RI, llvm::Value *CV,
9324 MapCombinedInfoTy &CombinedInfo) const {
9325 bool IsImplicit = true;
9326 // Do the default mapping.
9327 if (CI.capturesThis()) {
9328 CombinedInfo.Exprs.push_back(nullptr);
9329 CombinedInfo.BasePointers.push_back(CV);
9330 CombinedInfo.Pointers.push_back(CV);
9331 const auto *PtrTy = cast<PointerType>(RI.getType().getTypePtr());
9332 CombinedInfo.Sizes.push_back(
9333 CGF.Builder.CreateIntCast(CGF.getTypeSize(PtrTy->getPointeeType()),
9334 CGF.Int64Ty, /*isSigned=*/true));
9335 // Default map type.
9336 CombinedInfo.Types.push_back(OMP_MAP_TO | OMP_MAP_FROM);
9337 } else if (CI.capturesVariableByCopy()) {
9338 const VarDecl *VD = CI.getCapturedVar();
9339 CombinedInfo.Exprs.push_back(VD->getCanonicalDecl());
9340 CombinedInfo.BasePointers.push_back(CV);
9341 CombinedInfo.Pointers.push_back(CV);
9342 if (!RI.getType()->isAnyPointerType()) {
9343 // We have to signal to the runtime captures passed by value that are
9344 // not pointers.
9345 CombinedInfo.Types.push_back(OMP_MAP_LITERAL);
9346 CombinedInfo.Sizes.push_back(CGF.Builder.CreateIntCast(
9347 CGF.getTypeSize(RI.getType()), CGF.Int64Ty, /*isSigned=*/true));
9348 } else {
9349 // Pointers are implicitly mapped with a zero size and no flags
9350 // (other than first map that is added for all implicit maps).
9351 CombinedInfo.Types.push_back(OMP_MAP_NONE);
9352 CombinedInfo.Sizes.push_back(llvm::Constant::getNullValue(CGF.Int64Ty));
9353 }
9354 auto I = FirstPrivateDecls.find(VD);
9355 if (I != FirstPrivateDecls.end())
9356 IsImplicit = I->getSecond();
9357 } else {
9358 assert(CI.capturesVariable() && "Expected captured reference.")(static_cast<void> (0));
9359 const auto *PtrTy = cast<ReferenceType>(RI.getType().getTypePtr());
9360 QualType ElementType = PtrTy->getPointeeType();
9361 CombinedInfo.Sizes.push_back(CGF.Builder.CreateIntCast(
9362 CGF.getTypeSize(ElementType), CGF.Int64Ty, /*isSigned=*/true));
9363 // The default map type for a scalar/complex type is 'to' because by
9364 // default the value doesn't have to be retrieved. For an aggregate
9365 // type, the default is 'tofrom'.
9366 CombinedInfo.Types.push_back(getMapModifiersForPrivateClauses(CI));
9367 const VarDecl *VD = CI.getCapturedVar();
9368 auto I = FirstPrivateDecls.find(VD);
9369 CombinedInfo.Exprs.push_back(VD->getCanonicalDecl());
9370 CombinedInfo.BasePointers.push_back(CV);
9371 if (I != FirstPrivateDecls.end() && ElementType->isAnyPointerType()) {
9372 Address PtrAddr = CGF.EmitLoadOfReference(CGF.MakeAddrLValue(
9373 CV, ElementType, CGF.getContext().getDeclAlign(VD),
9374 AlignmentSource::Decl));
9375 CombinedInfo.Pointers.push_back(PtrAddr.getPointer());
9376 } else {
9377 CombinedInfo.Pointers.push_back(CV);
9378 }
9379 if (I != FirstPrivateDecls.end())
9380 IsImplicit = I->getSecond();
9381 }
9382 // Every default map produces a single argument which is a target parameter.
9383 CombinedInfo.Types.back() |= OMP_MAP_TARGET_PARAM;
9384
9385 // Add flag stating this is an implicit map.
9386 if (IsImplicit)
9387 CombinedInfo.Types.back() |= OMP_MAP_IMPLICIT;
9388
9389 // No user-defined mapper for default mapping.
9390 CombinedInfo.Mappers.push_back(nullptr);
9391 }
9392};
9393} // anonymous namespace
9394
9395static void emitNonContiguousDescriptor(
9396 CodeGenFunction &CGF, MappableExprsHandler::MapCombinedInfoTy &CombinedInfo,
9397 CGOpenMPRuntime::TargetDataInfo &Info) {
9398 CodeGenModule &CGM = CGF.CGM;
9399 MappableExprsHandler::MapCombinedInfoTy::StructNonContiguousInfo
9400 &NonContigInfo = CombinedInfo.NonContigInfo;
9401
9402 // Build an array of struct descriptor_dim and then assign it to
9403 // offload_args.
9404 //
9405 // struct descriptor_dim {
9406 // uint64_t offset;
9407 // uint64_t count;
9408 // uint64_t stride
9409 // };
9410 ASTContext &C = CGF.getContext();
9411 QualType Int64Ty = C.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
9412 RecordDecl *RD;
9413 RD = C.buildImplicitRecord("descriptor_dim");
9414 RD->startDefinition();
9415 addFieldToRecordDecl(C, RD, Int64Ty);
9416 addFieldToRecordDecl(C, RD, Int64Ty);
9417 addFieldToRecordDecl(C, RD, Int64Ty);
9418 RD->completeDefinition();
9419 QualType DimTy = C.getRecordType(RD);
9420
9421 enum { OffsetFD = 0, CountFD, StrideFD };
9422 // We need two index variable here since the size of "Dims" is the same as the
9423 // size of Components, however, the size of offset, count, and stride is equal
9424 // to the size of base declaration that is non-contiguous.
9425 for (unsigned I = 0, L = 0, E = NonContigInfo.Dims.size(); I < E; ++I) {
9426 // Skip emitting ir if dimension size is 1 since it cannot be
9427 // non-contiguous.
9428 if (NonContigInfo.Dims[I] == 1)
9429 continue;
9430 llvm::APInt Size(/*numBits=*/32, NonContigInfo.Dims[I]);
9431 QualType ArrayTy =
9432 C.getConstantArrayType(DimTy, Size, nullptr, ArrayType::Normal, 0);
9433 Address DimsAddr = CGF.CreateMemTemp(ArrayTy, "dims");
9434 for (unsigned II = 0, EE = NonContigInfo.Dims[I]; II < EE; ++II) {
9435 unsigned RevIdx = EE - II - 1;
9436 LValue DimsLVal = CGF.MakeAddrLValue(
9437 CGF.Builder.CreateConstArrayGEP(DimsAddr, II), DimTy);
9438 // Offset
9439 LValue OffsetLVal = CGF.EmitLValueForField(
9440 DimsLVal, *std::next(RD->field_begin(), OffsetFD));
9441 CGF.EmitStoreOfScalar(NonContigInfo.Offsets[L][RevIdx], OffsetLVal);
9442 // Count
9443 LValue CountLVal = CGF.EmitLValueForField(
9444 DimsLVal, *std::next(RD->field_begin(), CountFD));
9445 CGF.EmitStoreOfScalar(NonContigInfo.Counts[L][RevIdx], CountLVal);
9446 // Stride
9447 LValue StrideLVal = CGF.EmitLValueForField(
9448 DimsLVal, *std::next(RD->field_begin(), StrideFD));
9449 CGF.EmitStoreOfScalar(NonContigInfo.Strides[L][RevIdx], StrideLVal);
9450 }
9451 // args[I] = &dims
9452 Address DAddr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
9453 DimsAddr, CGM.Int8PtrTy);
9454 llvm::Value *P = CGF.Builder.CreateConstInBoundsGEP2_32(
9455 llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),
9456 Info.PointersArray, 0, I);
9457 Address PAddr(P, CGF.getPointerAlign());
9458 CGF.Builder.CreateStore(DAddr.getPointer(), PAddr);
9459 ++L;
9460 }
9461}
9462
9463// Try to extract the base declaration from a `this->x` expression if possible.
9464static ValueDecl *getDeclFromThisExpr(const Expr *E) {
9465 if (!E)
9466 return nullptr;
9467
9468 if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(E->IgnoreParenCasts()))
9469 if (const MemberExpr *ME =
9470 dyn_cast<MemberExpr>(OASE->getBase()->IgnoreParenImpCasts()))
9471 return ME->getMemberDecl();
9472 return nullptr;
9473}
9474
9475/// Emit a string constant containing the names of the values mapped to the
9476/// offloading runtime library.
9477llvm::Constant *
9478emitMappingInformation(CodeGenFunction &CGF, llvm::OpenMPIRBuilder &OMPBuilder,
9479 MappableExprsHandler::MappingExprInfo &MapExprs) {
9480
9481 if (!MapExprs.getMapDecl() && !MapExprs.getMapExpr())
9482 return OMPBuilder.getOrCreateDefaultSrcLocStr();
9483
9484 SourceLocation Loc;
9485 if (!MapExprs.getMapDecl() && MapExprs.getMapExpr()) {
9486 if (const ValueDecl *VD = getDeclFromThisExpr(MapExprs.getMapExpr()))
9487 Loc = VD->getLocation();
9488 else
9489 Loc = MapExprs.getMapExpr()->getExprLoc();
9490 } else {
9491 Loc = MapExprs.getMapDecl()->getLocation();
9492 }
9493
9494 std::string ExprName = "";
9495 if (MapExprs.getMapExpr()) {
9496 PrintingPolicy P(CGF.getContext().getLangOpts());
9497 llvm::raw_string_ostream OS(ExprName);
9498 MapExprs.getMapExpr()->printPretty(OS, nullptr, P);
9499 OS.flush();
9500 } else {
9501 ExprName = MapExprs.getMapDecl()->getNameAsString();
9502 }
9503
9504 PresumedLoc PLoc = CGF.getContext().getSourceManager().getPresumedLoc(Loc);
9505 return OMPBuilder.getOrCreateSrcLocStr(PLoc.getFilename(), ExprName.c_str(),
9506 PLoc.getLine(), PLoc.getColumn());
9507}
9508
9509/// Emit the arrays used to pass the captures and map information to the
9510/// offloading runtime library. If there is no map or capture information,
9511/// return nullptr by reference.
9512static void emitOffloadingArrays(
9513 CodeGenFunction &CGF, MappableExprsHandler::MapCombinedInfoTy &CombinedInfo,
9514 CGOpenMPRuntime::TargetDataInfo &Info, llvm::OpenMPIRBuilder &OMPBuilder,
9515 bool IsNonContiguous = false) {
9516 CodeGenModule &CGM = CGF.CGM;
9517 ASTContext &Ctx = CGF.getContext();
9518
9519 // Reset the array information.
9520 Info.clearArrayInfo();
9521 Info.NumberOfPtrs = CombinedInfo.BasePointers.size();
9522
9523 if (Info.NumberOfPtrs) {
9524 // Detect if we have any capture size requiring runtime evaluation of the
9525 // size so that a constant array could be eventually used.
9526 bool hasRuntimeEvaluationCaptureSize = false;
9527 for (llvm::Value *S : CombinedInfo.Sizes)
9528 if (!isa<llvm::Constant>(S)) {
9529 hasRuntimeEvaluationCaptureSize = true;
9530 break;
9531 }
9532
9533 llvm::APInt PointerNumAP(32, Info.NumberOfPtrs, /*isSigned=*/true);
9534 QualType PointerArrayType = Ctx.getConstantArrayType(
9535 Ctx.VoidPtrTy, PointerNumAP, nullptr, ArrayType::Normal,
9536 /*IndexTypeQuals=*/0);
9537
9538 Info.BasePointersArray =
9539 CGF.CreateMemTemp(PointerArrayType, ".offload_baseptrs").getPointer();
9540 Info.PointersArray =
9541 CGF.CreateMemTemp(PointerArrayType, ".offload_ptrs").getPointer();
9542 Address MappersArray =
9543 CGF.CreateMemTemp(PointerArrayType, ".offload_mappers");
9544 Info.MappersArray = MappersArray.getPointer();
9545
9546 // If we don't have any VLA types or other types that require runtime
9547 // evaluation, we can use a constant array for the map sizes, otherwise we
9548 // need to fill up the arrays as we do for the pointers.
9549 QualType Int64Ty =
9550 Ctx.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
9551 if (hasRuntimeEvaluationCaptureSize) {
9552 QualType SizeArrayType = Ctx.getConstantArrayType(
9553 Int64Ty, PointerNumAP, nullptr, ArrayType::Normal,
9554 /*IndexTypeQuals=*/0);
9555 Info.SizesArray =
9556 CGF.CreateMemTemp(SizeArrayType, ".offload_sizes").getPointer();
9557 } else {
9558 // We expect all the sizes to be constant, so we collect them to create
9559 // a constant array.
9560 SmallVector<llvm::Constant *, 16> ConstSizes;
9561 for (unsigned I = 0, E = CombinedInfo.Sizes.size(); I < E; ++I) {
9562 if (IsNonContiguous &&
9563 (CombinedInfo.Types[I] & MappableExprsHandler::OMP_MAP_NON_CONTIG)) {
9564 ConstSizes.push_back(llvm::ConstantInt::get(
9565 CGF.Int64Ty, CombinedInfo.NonContigInfo.Dims[I]));
9566 } else {
9567 ConstSizes.push_back(cast<llvm::Constant>(CombinedInfo.Sizes[I]));
9568 }
9569 }
9570
9571 auto *SizesArrayInit = llvm::ConstantArray::get(
9572 llvm::ArrayType::get(CGM.Int64Ty, ConstSizes.size()), ConstSizes);
9573 std::string Name = CGM.getOpenMPRuntime().getName({"offload_sizes"});
9574 auto *SizesArrayGbl = new llvm::GlobalVariable(
9575 CGM.getModule(), SizesArrayInit->getType(),
9576 /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage,
9577 SizesArrayInit, Name);
9578 SizesArrayGbl->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
9579 Info.SizesArray = SizesArrayGbl;
9580 }
9581
9582 // The map types are always constant so we don't need to generate code to
9583 // fill arrays. Instead, we create an array constant.
9584 SmallVector<uint64_t, 4> Mapping(CombinedInfo.Types.size(), 0);
9585 llvm::copy(CombinedInfo.Types, Mapping.begin());
9586 std::string MaptypesName =
9587 CGM.getOpenMPRuntime().getName({"offload_maptypes"});
9588 auto *MapTypesArrayGbl =
9589 OMPBuilder.createOffloadMaptypes(Mapping, MaptypesName);
9590 Info.MapTypesArray = MapTypesArrayGbl;
9591
9592 // The information types are only built if there is debug information
9593 // requested.
9594 if (CGM.getCodeGenOpts().getDebugInfo() == codegenoptions::NoDebugInfo) {
9595 Info.MapNamesArray = llvm::Constant::getNullValue(
9596 llvm::Type::getInt8Ty(CGF.Builder.getContext())->getPointerTo());
9597 } else {
9598 auto fillInfoMap = [&](MappableExprsHandler::MappingExprInfo &MapExpr) {
9599 return emitMappingInformation(CGF, OMPBuilder, MapExpr);
9600 };
9601 SmallVector<llvm::Constant *, 4> InfoMap(CombinedInfo.Exprs.size());
9602 llvm::transform(CombinedInfo.Exprs, InfoMap.begin(), fillInfoMap);
9603 std::string MapnamesName =
9604 CGM.getOpenMPRuntime().getName({"offload_mapnames"});
9605 auto *MapNamesArrayGbl =
9606 OMPBuilder.createOffloadMapnames(InfoMap, MapnamesName);
9607 Info.MapNamesArray = MapNamesArrayGbl;
9608 }
9609
9610 // If there's a present map type modifier, it must not be applied to the end
9611 // of a region, so generate a separate map type array in that case.
9612 if (Info.separateBeginEndCalls()) {
9613 bool EndMapTypesDiffer = false;
9614 for (uint64_t &Type : Mapping) {
9615 if (Type & MappableExprsHandler::OMP_MAP_PRESENT) {
9616 Type &= ~MappableExprsHandler::OMP_MAP_PRESENT;
9617 EndMapTypesDiffer = true;
9618 }
9619 }
9620 if (EndMapTypesDiffer) {
9621 MapTypesArrayGbl =
9622 OMPBuilder.createOffloadMaptypes(Mapping, MaptypesName);
9623 Info.MapTypesArrayEnd = MapTypesArrayGbl;
9624 }
9625 }
9626
9627 for (unsigned I = 0; I < Info.NumberOfPtrs; ++I) {
9628 llvm::Value *BPVal = *CombinedInfo.BasePointers[I];
9629 llvm::Value *BP = CGF.Builder.CreateConstInBoundsGEP2_32(
9630 llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),
9631 Info.BasePointersArray, 0, I);
9632 BP = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
9633 BP, BPVal->getType()->getPointerTo(/*AddrSpace=*/0));
9634 Address BPAddr(BP, Ctx.getTypeAlignInChars(Ctx.VoidPtrTy));
9635 CGF.Builder.CreateStore(BPVal, BPAddr);
9636
9637 if (Info.requiresDevicePointerInfo())
9638 if (const ValueDecl *DevVD =
9639 CombinedInfo.BasePointers[I].getDevicePtrDecl())
9640 Info.CaptureDeviceAddrMap.try_emplace(DevVD, BPAddr);
9641
9642 llvm::Value *PVal = CombinedInfo.Pointers[I];
9643 llvm::Value *P = CGF.Builder.CreateConstInBoundsGEP2_32(
9644 llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),
9645 Info.PointersArray, 0, I);
9646 P = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
9647 P, PVal->getType()->getPointerTo(/*AddrSpace=*/0));
9648 Address PAddr(P, Ctx.getTypeAlignInChars(Ctx.VoidPtrTy));
9649 CGF.Builder.CreateStore(PVal, PAddr);
9650
9651 if (hasRuntimeEvaluationCaptureSize) {
9652 llvm::Value *S = CGF.Builder.CreateConstInBoundsGEP2_32(
9653 llvm::ArrayType::get(CGM.Int64Ty, Info.NumberOfPtrs),
9654 Info.SizesArray,
9655 /*Idx0=*/0,
9656 /*Idx1=*/I);
9657 Address SAddr(S, Ctx.getTypeAlignInChars(Int64Ty));
9658 CGF.Builder.CreateStore(CGF.Builder.CreateIntCast(CombinedInfo.Sizes[I],
9659 CGM.Int64Ty,
9660 /*isSigned=*/true),
9661 SAddr);
9662 }
9663
9664 // Fill up the mapper array.
9665 llvm::Value *MFunc = llvm::ConstantPointerNull::get(CGM.VoidPtrTy);
9666 if (CombinedInfo.Mappers[I]) {
9667 MFunc = CGM.getOpenMPRuntime().getOrCreateUserDefinedMapperFunc(
9668 cast<OMPDeclareMapperDecl>(CombinedInfo.Mappers[I]));
9669 MFunc = CGF.Builder.CreatePointerCast(MFunc, CGM.VoidPtrTy);
9670 Info.HasMapper = true;
9671 }
9672 Address MAddr = CGF.Builder.CreateConstArrayGEP(MappersArray, I);
9673 CGF.Builder.CreateStore(MFunc, MAddr);
9674 }
9675 }
9676
9677 if (!IsNonContiguous || CombinedInfo.NonContigInfo.Offsets.empty() ||
9678 Info.NumberOfPtrs == 0)
9679 return;
9680
9681 emitNonContiguousDescriptor(CGF, CombinedInfo, Info);
9682}
9683
9684namespace {
9685/// Additional arguments for emitOffloadingArraysArgument function.
9686struct ArgumentsOptions {
9687 bool ForEndCall = false;
9688 ArgumentsOptions() = default;
9689 ArgumentsOptions(bool ForEndCall) : ForEndCall(ForEndCall) {}
9690};
9691} // namespace
9692
9693/// Emit the arguments to be passed to the runtime library based on the
9694/// arrays of base pointers, pointers, sizes, map types, and mappers. If
9695/// ForEndCall, emit map types to be passed for the end of the region instead of
9696/// the beginning.
9697static void emitOffloadingArraysArgument(
9698 CodeGenFunction &CGF, llvm::Value *&BasePointersArrayArg,
9699 llvm::Value *&PointersArrayArg, llvm::Value *&SizesArrayArg,
9700 llvm::Value *&MapTypesArrayArg, llvm::Value *&MapNamesArrayArg,
9701 llvm::Value *&MappersArrayArg, CGOpenMPRuntime::TargetDataInfo &Info,
9702 const ArgumentsOptions &Options = ArgumentsOptions()) {
9703 assert((!Options.ForEndCall || Info.separateBeginEndCalls()) &&(static_cast<void> (0))
9704 "expected region end call to runtime only when end call is separate")(static_cast<void> (0));
9705 CodeGenModule &CGM = CGF.CGM;
9706 if (Info.NumberOfPtrs) {
9707 BasePointersArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(
9708 llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),
9709 Info.BasePointersArray,
9710 /*Idx0=*/0, /*Idx1=*/0);
9711 PointersArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(
9712 llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),
9713 Info.PointersArray,
9714 /*Idx0=*/0,
9715 /*Idx1=*/0);
9716 SizesArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(
9717 llvm::ArrayType::get(CGM.Int64Ty, Info.NumberOfPtrs), Info.SizesArray,
9718 /*Idx0=*/0, /*Idx1=*/0);
9719 MapTypesArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(
9720 llvm::ArrayType::get(CGM.Int64Ty, Info.NumberOfPtrs),
9721 Options.ForEndCall && Info.MapTypesArrayEnd ? Info.MapTypesArrayEnd
9722 : Info.MapTypesArray,
9723 /*Idx0=*/0,
9724 /*Idx1=*/0);
9725
9726 // Only emit the mapper information arrays if debug information is
9727 // requested.
9728 if (CGF.CGM.getCodeGenOpts().getDebugInfo() == codegenoptions::NoDebugInfo)
9729 MapNamesArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy);
9730 else
9731 MapNamesArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(
9732 llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),
9733 Info.MapNamesArray,
9734 /*Idx0=*/0,
9735 /*Idx1=*/0);
9736 // If there is no user-defined mapper, set the mapper array to nullptr to
9737 // avoid an unnecessary data privatization
9738 if (!Info.HasMapper)
9739 MappersArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy);
9740 else
9741 MappersArrayArg =
9742 CGF.Builder.CreatePointerCast(Info.MappersArray, CGM.VoidPtrPtrTy);
9743 } else {
9744 BasePointersArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy);
9745 PointersArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy);
9746 SizesArrayArg = llvm::ConstantPointerNull::get(CGM.Int64Ty->getPointerTo());
9747 MapTypesArrayArg =
9748 llvm::ConstantPointerNull::get(CGM.Int64Ty->getPointerTo());
9749 MapNamesArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy);
9750 MappersArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy);
9751 }
9752}
9753
9754/// Check for inner distribute directive.
9755static const OMPExecutableDirective *
9756getNestedDistributeDirective(ASTContext &Ctx, const OMPExecutableDirective &D) {
9757 const auto *CS = D.getInnermostCapturedStmt();
9758 const auto *Body =
9759 CS->getCapturedStmt()->IgnoreContainers(/*IgnoreCaptured=*/true);
9760 const Stmt *ChildStmt =
9761 CGOpenMPSIMDRuntime::getSingleCompoundChild(Ctx, Body);
9762
9763 if (const auto *NestedDir =
9764 dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
9765 OpenMPDirectiveKind DKind = NestedDir->getDirectiveKind();
9766 switch (D.getDirectiveKind()) {
9767 case OMPD_target:
9768 if (isOpenMPDistributeDirective(DKind))
9769 return NestedDir;
9770 if (DKind == OMPD_teams) {
9771 Body = NestedDir->getInnermostCapturedStmt()->IgnoreContainers(
9772 /*IgnoreCaptured=*/true);
9773 if (!Body)
9774 return nullptr;
9775 ChildStmt = CGOpenMPSIMDRuntime::getSingleCompoundChild(Ctx, Body);
9776 if (const auto *NND =
9777 dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
9778 DKind = NND->getDirectiveKind();
9779 if (isOpenMPDistributeDirective(DKind))
9780 return NND;
9781 }
9782 }
9783 return nullptr;
9784 case OMPD_target_teams:
9785 if (isOpenMPDistributeDirective(DKind))
9786 return NestedDir;
9787 return nullptr;
9788 case OMPD_target_parallel:
9789 case OMPD_target_simd:
9790 case OMPD_target_parallel_for:
9791 case OMPD_target_parallel_for_simd:
9792 return nullptr;
9793 case OMPD_target_teams_distribute:
9794 case OMPD_target_teams_distribute_simd:
9795 case OMPD_target_teams_distribute_parallel_for:
9796 case OMPD_target_teams_distribute_parallel_for_simd:
9797 case OMPD_parallel:
9798 case OMPD_for:
9799 case OMPD_parallel_for:
9800 case OMPD_parallel_master:
9801 case OMPD_parallel_sections:
9802 case OMPD_for_simd:
9803 case OMPD_parallel_for_simd:
9804 case OMPD_cancel:
9805 case OMPD_cancellation_point:
9806 case OMPD_ordered:
9807 case OMPD_threadprivate:
9808 case OMPD_allocate:
9809 case OMPD_task:
9810 case OMPD_simd:
9811 case OMPD_tile:
9812 case OMPD_unroll:
9813 case OMPD_sections:
9814 case OMPD_section:
9815 case OMPD_single:
9816 case OMPD_master:
9817 case OMPD_critical:
9818 case OMPD_taskyield:
9819 case OMPD_barrier:
9820 case OMPD_taskwait:
9821 case OMPD_taskgroup:
9822 case OMPD_atomic:
9823 case OMPD_flush:
9824 case OMPD_depobj:
9825 case OMPD_scan:
9826 case OMPD_teams:
9827 case OMPD_target_data:
9828 case OMPD_target_exit_data:
9829 case OMPD_target_enter_data:
9830 case OMPD_distribute:
9831 case OMPD_distribute_simd:
9832 case OMPD_distribute_parallel_for:
9833 case OMPD_distribute_parallel_for_simd:
9834 case OMPD_teams_distribute:
9835 case OMPD_teams_distribute_simd:
9836 case OMPD_teams_distribute_parallel_for:
9837 case OMPD_teams_distribute_parallel_for_simd:
9838 case OMPD_target_update:
9839 case OMPD_declare_simd:
9840 case OMPD_declare_variant:
9841 case OMPD_begin_declare_variant:
9842 case OMPD_end_declare_variant:
9843 case OMPD_declare_target:
9844 case OMPD_end_declare_target:
9845 case OMPD_declare_reduction:
9846 case OMPD_declare_mapper:
9847 case OMPD_taskloop:
9848 case OMPD_taskloop_simd:
9849 case OMPD_master_taskloop:
9850 case OMPD_master_taskloop_simd:
9851 case OMPD_parallel_master_taskloop:
9852 case OMPD_parallel_master_taskloop_simd:
9853 case OMPD_requires:
9854 case OMPD_unknown:
9855 default:
9856 llvm_unreachable("Unexpected directive.")__builtin_unreachable();
9857 }
9858 }
9859
9860 return nullptr;
9861}
9862
9863/// Emit the user-defined mapper function. The code generation follows the
9864/// pattern in the example below.
9865/// \code
9866/// void .omp_mapper.<type_name>.<mapper_id>.(void *rt_mapper_handle,
9867/// void *base, void *begin,
9868/// int64_t size, int64_t type,
9869/// void *name = nullptr) {
9870/// // Allocate space for an array section first or add a base/begin for
9871/// // pointer dereference.
9872/// if ((size > 1 || (base != begin && maptype.IsPtrAndObj)) &&
9873/// !maptype.IsDelete)
9874/// __tgt_push_mapper_component(rt_mapper_handle, base, begin,
9875/// size*sizeof(Ty), clearToFromMember(type));
9876/// // Map members.
9877/// for (unsigned i = 0; i < size; i++) {
9878/// // For each component specified by this mapper:
9879/// for (auto c : begin[i]->all_components) {
9880/// if (c.hasMapper())
9881/// (*c.Mapper())(rt_mapper_handle, c.arg_base, c.arg_begin, c.arg_size,
9882/// c.arg_type, c.arg_name);
9883/// else
9884/// __tgt_push_mapper_component(rt_mapper_handle, c.arg_base,
9885/// c.arg_begin, c.arg_size, c.arg_type,
9886/// c.arg_name);
9887/// }
9888/// }
9889/// // Delete the array section.
9890/// if (size > 1 && maptype.IsDelete)
9891/// __tgt_push_mapper_component(rt_mapper_handle, base, begin,
9892/// size*sizeof(Ty), clearToFromMember(type));
9893/// }
9894/// \endcode
9895void CGOpenMPRuntime::emitUserDefinedMapper(const OMPDeclareMapperDecl *D,
9896 CodeGenFunction *CGF) {
9897 if (UDMMap.count(D) > 0)
9898 return;
9899 ASTContext &C = CGM.getContext();
9900 QualType Ty = D->getType();
9901 QualType PtrTy = C.getPointerType(Ty).withRestrict();
9902 QualType Int64Ty = C.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/true);
9903 auto *MapperVarDecl =
9904 cast<VarDecl>(cast<DeclRefExpr>(D->getMapperVarRef())->getDecl());
9905 SourceLocation Loc = D->getLocation();
9906 CharUnits ElementSize = C.getTypeSizeInChars(Ty);
9907
9908 // Prepare mapper function arguments and attributes.
9909 ImplicitParamDecl HandleArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
9910 C.VoidPtrTy, ImplicitParamDecl::Other);
9911 ImplicitParamDecl BaseArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
9912 ImplicitParamDecl::Other);
9913 ImplicitParamDecl BeginArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
9914 C.VoidPtrTy, ImplicitParamDecl::Other);
9915 ImplicitParamDecl SizeArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, Int64Ty,
9916 ImplicitParamDecl::Other);
9917 ImplicitParamDecl TypeArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, Int64Ty,
9918 ImplicitParamDecl::Other);
9919 ImplicitParamDecl NameArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
9920 ImplicitParamDecl::Other);
9921 FunctionArgList Args;
9922 Args.push_back(&HandleArg);
9923 Args.push_back(&BaseArg);
9924 Args.push_back(&BeginArg);
9925 Args.push_back(&SizeArg);
9926 Args.push_back(&TypeArg);
9927 Args.push_back(&NameArg);
9928 const CGFunctionInfo &FnInfo =
9929 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
9930 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
9931 SmallString<64> TyStr;
9932 llvm::raw_svector_ostream Out(TyStr);
9933 CGM.getCXXABI().getMangleContext().mangleTypeName(Ty, Out);
9934 std::string Name = getName({"omp_mapper", TyStr, D->getName()});
9935 auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
9936 Name, &CGM.getModule());
9937 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo);
9938 Fn->removeFnAttr(llvm::Attribute::OptimizeNone);
9939 // Start the mapper function code generation.
9940 CodeGenFunction MapperCGF(CGM);
9941 MapperCGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, Loc, Loc);
9942 // Compute the starting and end addresses of array elements.
9943 llvm::Value *Size = MapperCGF.EmitLoadOfScalar(
9944 MapperCGF.GetAddrOfLocalVar(&SizeArg), /*Volatile=*/false,
9945 C.getPointerType(Int64Ty), Loc);
9946 // Prepare common arguments for array initiation and deletion.
9947 llvm::Value *Handle = MapperCGF.EmitLoadOfScalar(
9948 MapperCGF.GetAddrOfLocalVar(&HandleArg),
9949 /*Volatile=*/false, C.getPointerType(C.VoidPtrTy), Loc);
9950 llvm::Value *BaseIn = MapperCGF.EmitLoadOfScalar(
9951 MapperCGF.GetAddrOfLocalVar(&BaseArg),
9952 /*Volatile=*/false, C.getPointerType(C.VoidPtrTy), Loc);
9953 llvm::Value *BeginIn = MapperCGF.EmitLoadOfScalar(
9954 MapperCGF.GetAddrOfLocalVar(&BeginArg),
9955 /*Volatile=*/false, C.getPointerType(C.VoidPtrTy), Loc);
9956 // Convert the size in bytes into the number of array elements.
9957 Size = MapperCGF.Builder.CreateExactUDiv(
9958 Size, MapperCGF.Builder.getInt64(ElementSize.getQuantity()));
9959 llvm::Value *PtrBegin = MapperCGF.Builder.CreateBitCast(
9960 BeginIn, CGM.getTypes().ConvertTypeForMem(PtrTy));
9961 llvm::Value *PtrEnd = MapperCGF.Builder.CreateGEP(
9962 PtrBegin->getType()->getPointerElementType(), PtrBegin, Size);
9963 llvm::Value *MapType = MapperCGF.EmitLoadOfScalar(
9964 MapperCGF.GetAddrOfLocalVar(&TypeArg), /*Volatile=*/false,
9965 C.getPointerType(Int64Ty), Loc);
9966 llvm::Value *MapName = MapperCGF.EmitLoadOfScalar(
9967 MapperCGF.GetAddrOfLocalVar(&NameArg),
9968 /*Volatile=*/false, C.getPointerType(C.VoidPtrTy), Loc);
9969
9970 // Emit array initiation if this is an array section and \p MapType indicates
9971 // that memory allocation is required.
9972 llvm::BasicBlock *HeadBB = MapperCGF.createBasicBlock("omp.arraymap.head");
9973 emitUDMapperArrayInitOrDel(MapperCGF, Handle, BaseIn, BeginIn, Size, MapType,
9974 MapName, ElementSize, HeadBB, /*IsInit=*/true);
9975
9976 // Emit a for loop to iterate through SizeArg of elements and map all of them.
9977
9978 // Emit the loop header block.
9979 MapperCGF.EmitBlock(HeadBB);
9980 llvm::BasicBlock *BodyBB = MapperCGF.createBasicBlock("omp.arraymap.body");
9981 llvm::BasicBlock *DoneBB = MapperCGF.createBasicBlock("omp.done");
9982 // Evaluate whether the initial condition is satisfied.
9983 llvm::Value *IsEmpty =
9984 MapperCGF.Builder.CreateICmpEQ(PtrBegin, PtrEnd, "omp.arraymap.isempty");
9985 MapperCGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
9986 llvm::BasicBlock *EntryBB = MapperCGF.Builder.GetInsertBlock();
9987
9988 // Emit the loop body block.
9989 MapperCGF.EmitBlock(BodyBB);
9990 llvm::BasicBlock *LastBB = BodyBB;
9991 llvm::PHINode *PtrPHI = MapperCGF.Builder.CreatePHI(
9992 PtrBegin->getType(), 2, "omp.arraymap.ptrcurrent");
9993 PtrPHI->addIncoming(PtrBegin, EntryBB);
9994 Address PtrCurrent =
9995 Address(PtrPHI, MapperCGF.GetAddrOfLocalVar(&BeginArg)
9996 .getAlignment()
9997 .alignmentOfArrayElement(ElementSize));
9998 // Privatize the declared variable of mapper to be the current array element.
9999 CodeGenFunction::OMPPrivateScope Scope(MapperCGF);
10000 Scope.addPrivate(MapperVarDecl, [PtrCurrent]() { return PtrCurrent; });
10001 (void)Scope.Privatize();
10002
10003 // Get map clause information. Fill up the arrays with all mapped variables.
10004 MappableExprsHandler::MapCombinedInfoTy Info;
10005 MappableExprsHandler MEHandler(*D, MapperCGF);
10006 MEHandler.generateAllInfoForMapper(Info);
10007
10008 // Call the runtime API __tgt_mapper_num_components to get the number of
10009 // pre-existing components.
10010 llvm::Value *OffloadingArgs[] = {Handle};
10011 llvm::Value *PreviousSize = MapperCGF.EmitRuntimeCall(
10012 OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(),
10013 OMPRTL___tgt_mapper_num_components),
10014 OffloadingArgs);
10015 llvm::Value *ShiftedPreviousSize = MapperCGF.Builder.CreateShl(
10016 PreviousSize,
10017 MapperCGF.Builder.getInt64(MappableExprsHandler::getFlagMemberOffset()));
10018
10019 // Fill up the runtime mapper handle for all components.
10020 for (unsigned I = 0; I < Info.BasePointers.size(); ++I) {
10021 llvm::Value *CurBaseArg = MapperCGF.Builder.CreateBitCast(
10022 *Info.BasePointers[I], CGM.getTypes().ConvertTypeForMem(C.VoidPtrTy));
10023 llvm::Value *CurBeginArg = MapperCGF.Builder.CreateBitCast(
10024 Info.Pointers[I], CGM.getTypes().ConvertTypeForMem(C.VoidPtrTy));
10025 llvm::Value *CurSizeArg = Info.Sizes[I];
10026 llvm::Value *CurNameArg =
10027 (CGM.getCodeGenOpts().getDebugInfo() == codegenoptions::NoDebugInfo)
10028 ? llvm::ConstantPointerNull::get(CGM.VoidPtrTy)
10029 : emitMappingInformation(MapperCGF, OMPBuilder, Info.Exprs[I]);
10030
10031 // Extract the MEMBER_OF field from the map type.
10032 llvm::Value *OriMapType = MapperCGF.Builder.getInt64(Info.Types[I]);
10033 llvm::Value *MemberMapType =
10034 MapperCGF.Builder.CreateNUWAdd(OriMapType, ShiftedPreviousSize);
10035
10036 // Combine the map type inherited from user-defined mapper with that
10037 // specified in the program. According to the OMP_MAP_TO and OMP_MAP_FROM
10038 // bits of the \a MapType, which is the input argument of the mapper
10039 // function, the following code will set the OMP_MAP_TO and OMP_MAP_FROM
10040 // bits of MemberMapType.
10041 // [OpenMP 5.0], 1.2.6. map-type decay.
10042 // | alloc | to | from | tofrom | release | delete
10043 // ----------------------------------------------------------
10044 // alloc | alloc | alloc | alloc | alloc | release | delete
10045 // to | alloc | to | alloc | to | release | delete
10046 // from | alloc | alloc | from | from | release | delete
10047 // tofrom | alloc | to | from | tofrom | release | delete
10048 llvm::Value *LeftToFrom = MapperCGF.Builder.CreateAnd(
10049 MapType,
10050 MapperCGF.Builder.getInt64(MappableExprsHandler::OMP_MAP_TO |
10051 MappableExprsHandler::OMP_MAP_FROM));
10052 llvm::BasicBlock *AllocBB = MapperCGF.createBasicBlock("omp.type.alloc");
10053 llvm::BasicBlock *AllocElseBB =
10054 MapperCGF.createBasicBlock("omp.type.alloc.else");
10055 llvm::BasicBlock *ToBB = MapperCGF.createBasicBlock("omp.type.to");
10056 llvm::BasicBlock *ToElseBB = MapperCGF.createBasicBlock("omp.type.to.else");
10057 llvm::BasicBlock *FromBB = MapperCGF.createBasicBlock("omp.type.from");
10058 llvm::BasicBlock *EndBB = MapperCGF.createBasicBlock("omp.type.end");
10059 llvm::Value *IsAlloc = MapperCGF.Builder.CreateIsNull(LeftToFrom);
10060 MapperCGF.Builder.CreateCondBr(IsAlloc, AllocBB, AllocElseBB);
10061 // In case of alloc, clear OMP_MAP_TO and OMP_MAP_FROM.
10062 MapperCGF.EmitBlock(AllocBB);
10063 llvm::Value *AllocMapType = MapperCGF.Builder.CreateAnd(
10064 MemberMapType,
10065 MapperCGF.Builder.getInt64(~(MappableExprsHandler::OMP_MAP_TO |
10066 MappableExprsHandler::OMP_MAP_FROM)));
10067 MapperCGF.Builder.CreateBr(EndBB);
10068 MapperCGF.EmitBlock(AllocElseBB);
10069 llvm::Value *IsTo = MapperCGF.Builder.CreateICmpEQ(
10070 LeftToFrom,
10071 MapperCGF.Builder.getInt64(MappableExprsHandler::OMP_MAP_TO));
10072 MapperCGF.Builder.CreateCondBr(IsTo, ToBB, ToElseBB);
10073 // In case of to, clear OMP_MAP_FROM.
10074 MapperCGF.EmitBlock(ToBB);
10075 llvm::Value *ToMapType = MapperCGF.Builder.CreateAnd(
10076 MemberMapType,
10077 MapperCGF.Builder.getInt64(~MappableExprsHandler::OMP_MAP_FROM));
10078 MapperCGF.Builder.CreateBr(EndBB);
10079 MapperCGF.EmitBlock(ToElseBB);
10080 llvm::Value *IsFrom = MapperCGF.Builder.CreateICmpEQ(
10081 LeftToFrom,
10082 MapperCGF.Builder.getInt64(MappableExprsHandler::OMP_MAP_FROM));
10083 MapperCGF.Builder.CreateCondBr(IsFrom, FromBB, EndBB);
10084 // In case of from, clear OMP_MAP_TO.
10085 MapperCGF.EmitBlock(FromBB);
10086 llvm::Value *FromMapType = MapperCGF.Builder.CreateAnd(
10087 MemberMapType,
10088 MapperCGF.Builder.getInt64(~MappableExprsHandler::OMP_MAP_TO));
10089 // In case of tofrom, do nothing.
10090 MapperCGF.EmitBlock(EndBB);
10091 LastBB = EndBB;
10092 llvm::PHINode *CurMapType =
10093 MapperCGF.Builder.CreatePHI(CGM.Int64Ty, 4, "omp.maptype");
10094 CurMapType->addIncoming(AllocMapType, AllocBB);
10095 CurMapType->addIncoming(ToMapType, ToBB);
10096 CurMapType->addIncoming(FromMapType, FromBB);
10097 CurMapType->addIncoming(MemberMapType, ToElseBB);
10098
10099 llvm::Value *OffloadingArgs[] = {Handle, CurBaseArg, CurBeginArg,
10100 CurSizeArg, CurMapType, CurNameArg};
10101 if (Info.Mappers[I]) {
10102 // Call the corresponding mapper function.
10103 llvm::Function *MapperFunc = getOrCreateUserDefinedMapperFunc(
10104 cast<OMPDeclareMapperDecl>(Info.Mappers[I]));
10105 assert(MapperFunc && "Expect a valid mapper function is available.")(static_cast<void> (0));
10106 MapperCGF.EmitNounwindRuntimeCall(MapperFunc, OffloadingArgs);
10107 } else {
10108 // Call the runtime API __tgt_push_mapper_component to fill up the runtime
10109 // data structure.
10110 MapperCGF.EmitRuntimeCall(
10111 OMPBuilder.getOrCreateRuntimeFunction(
10112 CGM.getModule(), OMPRTL___tgt_push_mapper_component),
10113 OffloadingArgs);
10114 }
10115 }
10116
10117 // Update the pointer to point to the next element that needs to be mapped,
10118 // and check whether we have mapped all elements.
10119 llvm::Type *ElemTy = PtrPHI->getType()->getPointerElementType();
10120 llvm::Value *PtrNext = MapperCGF.Builder.CreateConstGEP1_32(
10121 ElemTy, PtrPHI, /*Idx0=*/1, "omp.arraymap.next");
10122 PtrPHI->addIncoming(PtrNext, LastBB);
10123 llvm::Value *IsDone =
10124 MapperCGF.Builder.CreateICmpEQ(PtrNext, PtrEnd, "omp.arraymap.isdone");
10125 llvm::BasicBlock *ExitBB = MapperCGF.createBasicBlock("omp.arraymap.exit");
10126 MapperCGF.Builder.CreateCondBr(IsDone, ExitBB, BodyBB);
10127
10128 MapperCGF.EmitBlock(ExitBB);
10129 // Emit array deletion if this is an array section and \p MapType indicates
10130 // that deletion is required.
10131 emitUDMapperArrayInitOrDel(MapperCGF, Handle, BaseIn, BeginIn, Size, MapType,
10132 MapName, ElementSize, DoneBB, /*IsInit=*/false);
10133
10134 // Emit the function exit block.
10135 MapperCGF.EmitBlock(DoneBB, /*IsFinished=*/true);
10136 MapperCGF.FinishFunction();
10137 UDMMap.try_emplace(D, Fn);
10138 if (CGF) {
10139 auto &Decls = FunctionUDMMap.FindAndConstruct(CGF->CurFn);
10140 Decls.second.push_back(D);
10141 }
10142}
10143
10144/// Emit the array initialization or deletion portion for user-defined mapper
10145/// code generation. First, it evaluates whether an array section is mapped and
10146/// whether the \a MapType instructs to delete this section. If \a IsInit is
10147/// true, and \a MapType indicates to not delete this array, array
10148/// initialization code is generated. If \a IsInit is false, and \a MapType
10149/// indicates to not this array, array deletion code is generated.
10150void CGOpenMPRuntime::emitUDMapperArrayInitOrDel(
10151 CodeGenFunction &MapperCGF, llvm::Value *Handle, llvm::Value *Base,
10152 llvm::Value *Begin, llvm::Value *Size, llvm::Value *MapType,
10153 llvm::Value *MapName, CharUnits ElementSize, llvm::BasicBlock *ExitBB,
10154 bool IsInit) {
10155 StringRef Prefix = IsInit ? ".init" : ".del";
10156
10157 // Evaluate if this is an array section.
10158 llvm::BasicBlock *BodyBB =
10159 MapperCGF.createBasicBlock(getName({"omp.array", Prefix}));
10160 llvm::Value *IsArray = MapperCGF.Builder.CreateICmpSGT(
10161 Size, MapperCGF.Builder.getInt64(1), "omp.arrayinit.isarray");
10162 llvm::Value *DeleteBit = MapperCGF.Builder.CreateAnd(
10163 MapType,
10164 MapperCGF.Builder.getInt64(MappableExprsHandler::OMP_MAP_DELETE));
10165 llvm::Value *DeleteCond;
10166 llvm::Value *Cond;
10167 if (IsInit) {
10168 // base != begin?
10169 llvm::Value *BaseIsBegin = MapperCGF.Builder.CreateIsNotNull(
10170 MapperCGF.Builder.CreatePtrDiff(Base, Begin));
10171 // IsPtrAndObj?
10172 llvm::Value *PtrAndObjBit = MapperCGF.Builder.CreateAnd(
10173 MapType,
10174 MapperCGF.Builder.getInt64(MappableExprsHandler::OMP_MAP_PTR_AND_OBJ));
10175 PtrAndObjBit = MapperCGF.Builder.CreateIsNotNull(PtrAndObjBit);
10176 BaseIsBegin = MapperCGF.Builder.CreateAnd(BaseIsBegin, PtrAndObjBit);
10177 Cond = MapperCGF.Builder.CreateOr(IsArray, BaseIsBegin);
10178 DeleteCond = MapperCGF.Builder.CreateIsNull(
10179 DeleteBit, getName({"omp.array", Prefix, ".delete"}));
10180 } else {
10181 Cond = IsArray;
10182 DeleteCond = MapperCGF.Builder.CreateIsNotNull(
10183 DeleteBit, getName({"omp.array", Prefix, ".delete"}));
10184 }
10185 Cond = MapperCGF.Builder.CreateAnd(Cond, DeleteCond);
10186 MapperCGF.Builder.CreateCondBr(Cond, BodyBB, ExitBB);
10187
10188 MapperCGF.EmitBlock(BodyBB);
10189 // Get the array size by multiplying element size and element number (i.e., \p
10190 // Size).
10191 llvm::Value *ArraySize = MapperCGF.Builder.CreateNUWMul(
10192 Size, MapperCGF.Builder.getInt64(ElementSize.getQuantity()));
10193 // Remove OMP_MAP_TO and OMP_MAP_FROM from the map type, so that it achieves
10194 // memory allocation/deletion purpose only.
10195 llvm::Value *MapTypeArg = MapperCGF.Builder.CreateAnd(
10196 MapType,
10197 MapperCGF.Builder.getInt64(~(MappableExprsHandler::OMP_MAP_TO |
10198 MappableExprsHandler::OMP_MAP_FROM)));
10199 MapTypeArg = MapperCGF.Builder.CreateOr(
10200 MapTypeArg,
10201 MapperCGF.Builder.getInt64(MappableExprsHandler::OMP_MAP_IMPLICIT));
10202
10203 // Call the runtime API __tgt_push_mapper_component to fill up the runtime
10204 // data structure.
10205 llvm::Value *OffloadingArgs[] = {Handle, Base, Begin,
10206 ArraySize, MapTypeArg, MapName};
10207 MapperCGF.EmitRuntimeCall(
10208 OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(),
10209 OMPRTL___tgt_push_mapper_component),
10210 OffloadingArgs);
10211}
10212
10213llvm::Function *CGOpenMPRuntime::getOrCreateUserDefinedMapperFunc(
10214 const OMPDeclareMapperDecl *D) {
10215 auto I = UDMMap.find(D);
10216 if (I != UDMMap.end())
10217 return I->second;
10218 emitUserDefinedMapper(D);
10219 return UDMMap.lookup(D);
10220}
10221
10222void CGOpenMPRuntime::emitTargetNumIterationsCall(
10223 CodeGenFunction &CGF, const OMPExecutableDirective &D,
10224 llvm::Value *DeviceID,
10225 llvm::function_ref<llvm::Value *(CodeGenFunction &CGF,
10226 const OMPLoopDirective &D)>
10227 SizeEmitter) {
10228 OpenMPDirectiveKind Kind = D.getDirectiveKind();
10229 const OMPExecutableDirective *TD = &D;
10230 // Get nested teams distribute kind directive, if any.
10231 if (!isOpenMPDistributeDirective(Kind) || !isOpenMPTeamsDirective(Kind))
10232 TD = getNestedDistributeDirective(CGM.getContext(), D);
10233 if (!TD)
10234 return;
10235 const auto *LD = cast<OMPLoopDirective>(TD);
10236 auto &&CodeGen = [LD, DeviceID, SizeEmitter, &D, this](CodeGenFunction &CGF,
10237 PrePostActionTy &) {
10238 if (llvm::Value *NumIterations = SizeEmitter(CGF, *LD)) {
10239 llvm::Value *RTLoc = emitUpdateLocation(CGF, D.getBeginLoc());
10240 llvm::Value *Args[] = {RTLoc, DeviceID, NumIterations};
10241 CGF.EmitRuntimeCall(
10242 OMPBuilder.getOrCreateRuntimeFunction(
10243 CGM.getModule(), OMPRTL___kmpc_push_target_tripcount_mapper),
10244 Args);
10245 }
10246 };
10247 emitInlinedDirective(CGF, OMPD_unknown, CodeGen);
10248}
10249
10250void CGOpenMPRuntime::emitTargetCall(
10251 CodeGenFunction &CGF, const OMPExecutableDirective &D,
10252 llvm::Function *OutlinedFn, llvm::Value *OutlinedFnID, const Expr *IfCond,
10253 llvm::PointerIntPair<const Expr *, 2, OpenMPDeviceClauseModifier> Device,
10254 llvm::function_ref<llvm::Value *(CodeGenFunction &CGF,
10255 const OMPLoopDirective &D)>
10256 SizeEmitter) {
10257 if (!CGF.HaveInsertPoint())
10258 return;
10259
10260 assert(OutlinedFn && "Invalid outlined function!")(static_cast<void> (0));
10261
10262 const bool RequiresOuterTask = D.hasClausesOfKind<OMPDependClause>() ||
10263 D.hasClausesOfKind<OMPNowaitClause>();
10264 llvm::SmallVector<llvm::Value *, 16> CapturedVars;
10265 const CapturedStmt &CS = *D.getCapturedStmt(OMPD_target);
10266 auto &&ArgsCodegen = [&CS, &CapturedVars](CodeGenFunction &CGF,
10267 PrePostActionTy &) {
10268 CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
10269 };
10270 emitInlinedDirective(CGF, OMPD_unknown, ArgsCodegen);
10271
10272 CodeGenFunction::OMPTargetDataInfo InputInfo;
10273 llvm::Value *MapTypesArray = nullptr;
10274 llvm::Value *MapNamesArray = nullptr;
10275 // Fill up the pointer arrays and transfer execution to the device.
10276 auto &&ThenGen = [this, Device, OutlinedFn, OutlinedFnID, &D, &InputInfo,
10277 &MapTypesArray, &MapNamesArray, &CS, RequiresOuterTask,
10278 &CapturedVars,
10279 SizeEmitter](CodeGenFunction &CGF, PrePostActionTy &) {
10280 if (Device.getInt() == OMPC_DEVICE_ancestor) {
10281 // Reverse offloading is not supported, so just execute on the host.
10282 if (RequiresOuterTask) {
10283 CapturedVars.clear();
10284 CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
10285 }
10286 emitOutlinedFunctionCall(CGF, D.getBeginLoc(), OutlinedFn, CapturedVars);
10287 return;
10288 }
10289
10290 // On top of the arrays that were filled up, the target offloading call
10291 // takes as arguments the device id as well as the host pointer. The host
10292 // pointer is used by the runtime library to identify the current target
10293 // region, so it only has to be unique and not necessarily point to
10294 // anything. It could be the pointer to the outlined function that
10295 // implements the target region, but we aren't using that so that the
10296 // compiler doesn't need to keep that, and could therefore inline the host
10297 // function if proven worthwhile during optimization.
10298
10299 // From this point on, we need to have an ID of the target region defined.
10300 assert(OutlinedFnID && "Invalid outlined function ID!")(static_cast<void> (0));
10301
10302 // Emit device ID if any.
10303 llvm::Value *DeviceID;
10304 if (Device.getPointer()) {
10305 assert((Device.getInt() == OMPC_DEVICE_unknown ||(static_cast<void> (0))
10306 Device.getInt() == OMPC_DEVICE_device_num) &&(static_cast<void> (0))
10307 "Expected device_num modifier.")(static_cast<void> (0));
10308 llvm::Value *DevVal = CGF.EmitScalarExpr(Device.getPointer());
10309 DeviceID =
10310 CGF.Builder.CreateIntCast(DevVal, CGF.Int64Ty, /*isSigned=*/true);
10311 } else {
10312 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
10313 }
10314
10315 // Emit the number of elements in the offloading arrays.
10316 llvm::Value *PointerNum =
10317 CGF.Builder.getInt32(InputInfo.NumberOfTargetItems);
10318
10319 // Return value of the runtime offloading call.
10320 llvm::Value *Return;
10321
10322 llvm::Value *NumTeams = emitNumTeamsForTargetDirective(CGF, D);
10323 llvm::Value *NumThreads = emitNumThreadsForTargetDirective(CGF, D);
10324
10325 // Source location for the ident struct
10326 llvm::Value *RTLoc = emitUpdateLocation(CGF, D.getBeginLoc());
10327
10328 // Emit tripcount for the target loop-based directive.
10329 emitTargetNumIterationsCall(CGF, D, DeviceID, SizeEmitter);
10330
10331 bool HasNowait = D.hasClausesOfKind<OMPNowaitClause>();
10332 // The target region is an outlined function launched by the runtime
10333 // via calls __tgt_target() or __tgt_target_teams().
10334 //
10335 // __tgt_target() launches a target region with one team and one thread,
10336 // executing a serial region. This master thread may in turn launch
10337 // more threads within its team upon encountering a parallel region,
10338 // however, no additional teams can be launched on the device.
10339 //
10340 // __tgt_target_teams() launches a target region with one or more teams,
10341 // each with one or more threads. This call is required for target
10342 // constructs such as:
10343 // 'target teams'
10344 // 'target' / 'teams'
10345 // 'target teams distribute parallel for'
10346 // 'target parallel'
10347 // and so on.
10348 //
10349 // Note that on the host and CPU targets, the runtime implementation of
10350 // these calls simply call the outlined function without forking threads.
10351 // The outlined functions themselves have runtime calls to
10352 // __kmpc_fork_teams() and __kmpc_fork() for this purpose, codegen'd by
10353 // the compiler in emitTeamsCall() and emitParallelCall().
10354 //
10355 // In contrast, on the NVPTX target, the implementation of
10356 // __tgt_target_teams() launches a GPU kernel with the requested number
10357 // of teams and threads so no additional calls to the runtime are required.
10358 if (NumTeams) {
10359 // If we have NumTeams defined this means that we have an enclosed teams
10360 // region. Therefore we also expect to have NumThreads defined. These two
10361 // values should be defined in the presence of a teams directive,
10362 // regardless of having any clauses associated. If the user is using teams
10363 // but no clauses, these two values will be the default that should be
10364 // passed to the runtime library - a 32-bit integer with the value zero.
10365 assert(NumThreads && "Thread limit expression should be available along "(static_cast<void> (0))
10366 "with number of teams.")(static_cast<void> (0));
10367 SmallVector<llvm::Value *> OffloadingArgs = {
10368 RTLoc,
10369 DeviceID,
10370 OutlinedFnID,
10371 PointerNum,
10372 InputInfo.BasePointersArray.getPointer(),
10373 InputInfo.PointersArray.getPointer(),
10374 InputInfo.SizesArray.getPointer(),
10375 MapTypesArray,
10376 MapNamesArray,
10377 InputInfo.MappersArray.getPointer(),
10378 NumTeams,
10379 NumThreads};
10380 if (HasNowait) {
10381 // Add int32_t depNum = 0, void *depList = nullptr, int32_t
10382 // noAliasDepNum = 0, void *noAliasDepList = nullptr.
10383 OffloadingArgs.push_back(CGF.Builder.getInt32(0));
10384 OffloadingArgs.push_back(llvm::ConstantPointerNull::get(CGM.VoidPtrTy));
10385 OffloadingArgs.push_back(CGF.Builder.getInt32(0));
10386 OffloadingArgs.push_back(llvm::ConstantPointerNull::get(CGM.VoidPtrTy));
10387 }
10388 Return = CGF.EmitRuntimeCall(
10389 OMPBuilder.getOrCreateRuntimeFunction(
10390 CGM.getModule(), HasNowait
10391 ? OMPRTL___tgt_target_teams_nowait_mapper
10392 : OMPRTL___tgt_target_teams_mapper),
10393 OffloadingArgs);
10394 } else {
10395 SmallVector<llvm::Value *> OffloadingArgs = {
10396 RTLoc,
10397 DeviceID,
10398 OutlinedFnID,
10399 PointerNum,
10400 InputInfo.BasePointersArray.getPointer(),
10401 InputInfo.PointersArray.getPointer(),
10402 InputInfo.SizesArray.getPointer(),
10403 MapTypesArray,
10404 MapNamesArray,
10405 InputInfo.MappersArray.getPointer()};
10406 if (HasNowait) {
10407 // Add int32_t depNum = 0, void *depList = nullptr, int32_t
10408 // noAliasDepNum = 0, void *noAliasDepList = nullptr.
10409 OffloadingArgs.push_back(CGF.Builder.getInt32(0));
10410 OffloadingArgs.push_back(llvm::ConstantPointerNull::get(CGM.VoidPtrTy));
10411 OffloadingArgs.push_back(CGF.Builder.getInt32(0));
10412 OffloadingArgs.push_back(llvm::ConstantPointerNull::get(CGM.VoidPtrTy));
10413 }
10414 Return = CGF.EmitRuntimeCall(
10415 OMPBuilder.getOrCreateRuntimeFunction(
10416 CGM.getModule(), HasNowait ? OMPRTL___tgt_target_nowait_mapper
10417 : OMPRTL___tgt_target_mapper),
10418 OffloadingArgs);
10419 }
10420
10421 // Check the error code and execute the host version if required.
10422 llvm::BasicBlock *OffloadFailedBlock =
10423 CGF.createBasicBlock("omp_offload.failed");
10424 llvm::BasicBlock *OffloadContBlock =
10425 CGF.createBasicBlock("omp_offload.cont");
10426 llvm::Value *Failed = CGF.Builder.CreateIsNotNull(Return);
10427 CGF.Builder.CreateCondBr(Failed, OffloadFailedBlock, OffloadContBlock);
10428
10429 CGF.EmitBlock(OffloadFailedBlock);
10430 if (RequiresOuterTask) {
10431 CapturedVars.clear();
10432 CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
10433 }
10434 emitOutlinedFunctionCall(CGF, D.getBeginLoc(), OutlinedFn, CapturedVars);
10435 CGF.EmitBranch(OffloadContBlock);
10436
10437 CGF.EmitBlock(OffloadContBlock, /*IsFinished=*/true);
10438 };
10439
10440 // Notify that the host version must be executed.
10441 auto &&ElseGen = [this, &D, OutlinedFn, &CS, &CapturedVars,
10442 RequiresOuterTask](CodeGenFunction &CGF,
10443 PrePostActionTy &) {
10444 if (RequiresOuterTask) {
10445 CapturedVars.clear();
10446 CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
10447 }
10448 emitOutlinedFunctionCall(CGF, D.getBeginLoc(), OutlinedFn, CapturedVars);
10449 };
10450
10451 auto &&TargetThenGen = [this, &ThenGen, &D, &InputInfo, &MapTypesArray,
10452 &MapNamesArray, &CapturedVars, RequiresOuterTask,
10453 &CS](CodeGenFunction &CGF, PrePostActionTy &) {
10454 // Fill up the arrays with all the captured variables.
10455 MappableExprsHandler::MapCombinedInfoTy CombinedInfo;
10456
10457 // Get mappable expression information.
10458 MappableExprsHandler MEHandler(D, CGF);
10459 llvm::DenseMap<llvm::Value *, llvm::Value *> LambdaPointers;
10460 llvm::DenseSet<CanonicalDeclPtr<const Decl>> MappedVarSet;
10461
10462 auto RI = CS.getCapturedRecordDecl()->field_begin();
10463 auto *CV = CapturedVars.begin();
10464 for (CapturedStmt::const_capture_iterator CI = CS.capture_begin(),
10465 CE = CS.capture_end();
10466 CI != CE; ++CI, ++RI, ++CV) {
10467 MappableExprsHandler::MapCombinedInfoTy CurInfo;
10468 MappableExprsHandler::StructRangeInfoTy PartialStruct;
10469
10470 // VLA sizes are passed to the outlined region by copy and do not have map
10471 // information associated.
10472 if (CI->capturesVariableArrayType()) {
10473 CurInfo.Exprs.push_back(nullptr);
10474 CurInfo.BasePointers.push_back(*CV);
10475 CurInfo.Pointers.push_back(*CV);
10476 CurInfo.Sizes.push_back(CGF.Builder.CreateIntCast(
10477 CGF.getTypeSize(RI->getType()), CGF.Int64Ty, /*isSigned=*/true));
10478 // Copy to the device as an argument. No need to retrieve it.
10479 CurInfo.Types.push_back(MappableExprsHandler::OMP_MAP_LITERAL |
10480 MappableExprsHandler::OMP_MAP_TARGET_PARAM |
10481 MappableExprsHandler::OMP_MAP_IMPLICIT);
10482 CurInfo.Mappers.push_back(nullptr);
10483 } else {
10484 // If we have any information in the map clause, we use it, otherwise we
10485 // just do a default mapping.
10486 MEHandler.generateInfoForCapture(CI, *CV, CurInfo, PartialStruct);
10487 if (!CI->capturesThis())
10488 MappedVarSet.insert(CI->getCapturedVar());
10489 else
10490 MappedVarSet.insert(nullptr);
10491 if (CurInfo.BasePointers.empty() && !PartialStruct.Base.isValid())
10492 MEHandler.generateDefaultMapInfo(*CI, **RI, *CV, CurInfo);
10493 // Generate correct mapping for variables captured by reference in
10494 // lambdas.
10495 if (CI->capturesVariable())
10496 MEHandler.generateInfoForLambdaCaptures(CI->getCapturedVar(), *CV,
10497 CurInfo, LambdaPointers);
10498 }
10499 // We expect to have at least an element of information for this capture.
10500 assert((!CurInfo.BasePointers.empty() || PartialStruct.Base.isValid()) &&(static_cast<void> (0))
10501 "Non-existing map pointer for capture!")(static_cast<void> (0));
10502 assert(CurInfo.BasePointers.size() == CurInfo.Pointers.size() &&(static_cast<void> (0))
10503 CurInfo.BasePointers.size() == CurInfo.Sizes.size() &&(static_cast<void> (0))
10504 CurInfo.BasePointers.size() == CurInfo.Types.size() &&(static_cast<void> (0))
10505 CurInfo.BasePointers.size() == CurInfo.Mappers.size() &&(static_cast<void> (0))
10506 "Inconsistent map information sizes!")(static_cast<void> (0));
10507
10508 // If there is an entry in PartialStruct it means we have a struct with
10509 // individual members mapped. Emit an extra combined entry.
10510 if (PartialStruct.Base.isValid()) {
10511 CombinedInfo.append(PartialStruct.PreliminaryMapData);
10512 MEHandler.emitCombinedEntry(
10513 CombinedInfo, CurInfo.Types, PartialStruct, nullptr,
10514 !PartialStruct.PreliminaryMapData.BasePointers.empty());
10515 }
10516
10517 // We need to append the results of this capture to what we already have.
10518 CombinedInfo.append(CurInfo);
10519 }
10520 // Adjust MEMBER_OF flags for the lambdas captures.
10521 MEHandler.adjustMemberOfForLambdaCaptures(
10522 LambdaPointers, CombinedInfo.BasePointers, CombinedInfo.Pointers,
10523 CombinedInfo.Types);
10524 // Map any list items in a map clause that were not captures because they
10525 // weren't referenced within the construct.
10526 MEHandler.generateAllInfo(CombinedInfo, MappedVarSet);
10527
10528 TargetDataInfo Info;
10529 // Fill up the arrays and create the arguments.
10530 emitOffloadingArrays(CGF, CombinedInfo, Info, OMPBuilder);
10531 emitOffloadingArraysArgument(
10532 CGF, Info.BasePointersArray, Info.PointersArray, Info.SizesArray,
10533 Info.MapTypesArray, Info.MapNamesArray, Info.MappersArray, Info,
10534 {/*ForEndTask=*/false});
10535
10536 InputInfo.NumberOfTargetItems = Info.NumberOfPtrs;
10537 InputInfo.BasePointersArray =
10538 Address(Info.BasePointersArray, CGM.getPointerAlign());
10539 InputInfo.PointersArray =
10540 Address(Info.PointersArray, CGM.getPointerAlign());
10541 InputInfo.SizesArray = Address(Info.SizesArray, CGM.getPointerAlign());
10542 InputInfo.MappersArray = Address(Info.MappersArray, CGM.getPointerAlign());
10543 MapTypesArray = Info.MapTypesArray;
10544 MapNamesArray = Info.MapNamesArray;
10545 if (RequiresOuterTask)
10546 CGF.EmitOMPTargetTaskBasedDirective(D, ThenGen, InputInfo);
10547 else
10548 emitInlinedDirective(CGF, D.getDirectiveKind(), ThenGen);
10549 };
10550
10551 auto &&TargetElseGen = [this, &ElseGen, &D, RequiresOuterTask](
10552 CodeGenFunction &CGF, PrePostActionTy &) {
10553 if (RequiresOuterTask) {
10554 CodeGenFunction::OMPTargetDataInfo InputInfo;
10555 CGF.EmitOMPTargetTaskBasedDirective(D, ElseGen, InputInfo);
10556 } else {
10557 emitInlinedDirective(CGF, D.getDirectiveKind(), ElseGen);
10558 }
10559 };
10560
10561 // If we have a target function ID it means that we need to support
10562 // offloading, otherwise, just execute on the host. We need to execute on host
10563 // regardless of the conditional in the if clause if, e.g., the user do not
10564 // specify target triples.
10565 if (OutlinedFnID) {
10566 if (IfCond) {
10567 emitIfClause(CGF, IfCond, TargetThenGen, TargetElseGen);
10568 } else {
10569 RegionCodeGenTy ThenRCG(TargetThenGen);
10570 ThenRCG(CGF);
10571 }
10572 } else {
10573 RegionCodeGenTy ElseRCG(TargetElseGen);
10574 ElseRCG(CGF);
10575 }
10576}
10577
10578void CGOpenMPRuntime::scanForTargetRegionsFunctions(const Stmt *S,
10579 StringRef ParentName) {
10580 if (!S)
10581 return;
10582
10583 // Codegen OMP target directives that offload compute to the device.
10584 bool RequiresDeviceCodegen =
10585 isa<OMPExecutableDirective>(S) &&
10586 isOpenMPTargetExecutionDirective(
10587 cast<OMPExecutableDirective>(S)->getDirectiveKind());
10588
10589 if (RequiresDeviceCodegen) {
10590 const auto &E = *cast<OMPExecutableDirective>(S);
10591 unsigned DeviceID;
10592 unsigned FileID;
10593 unsigned Line;
10594 getTargetEntryUniqueInfo(CGM.getContext(), E.getBeginLoc(), DeviceID,
10595 FileID, Line);
10596
10597 // Is this a target region that should not be emitted as an entry point? If
10598 // so just signal we are done with this target region.
10599 if (!OffloadEntriesInfoManager.hasTargetRegionEntryInfo(DeviceID, FileID,
10600 ParentName, Line))
10601 return;
10602
10603 switch (E.getDirectiveKind()) {
10604 case OMPD_target:
10605 CodeGenFunction::EmitOMPTargetDeviceFunction(CGM, ParentName,
10606 cast<OMPTargetDirective>(E));
10607 break;
10608 case OMPD_target_parallel:
10609 CodeGenFunction::EmitOMPTargetParallelDeviceFunction(
10610 CGM, ParentName, cast<OMPTargetParallelDirective>(E));
10611 break;
10612 case OMPD_target_teams:
10613 CodeGenFunction::EmitOMPTargetTeamsDeviceFunction(
10614 CGM, ParentName, cast<OMPTargetTeamsDirective>(E));
10615 break;
10616 case OMPD_target_teams_distribute:
10617 CodeGenFunction::EmitOMPTargetTeamsDistributeDeviceFunction(
10618 CGM, ParentName, cast<OMPTargetTeamsDistributeDirective>(E));
10619 break;
10620 case OMPD_target_teams_distribute_simd:
10621 CodeGenFunction::EmitOMPTargetTeamsDistributeSimdDeviceFunction(
10622 CGM, ParentName, cast<OMPTargetTeamsDistributeSimdDirective>(E));
10623 break;
10624 case OMPD_target_parallel_for:
10625 CodeGenFunction::EmitOMPTargetParallelForDeviceFunction(
10626 CGM, ParentName, cast<OMPTargetParallelForDirective>(E));
10627 break;
10628 case OMPD_target_parallel_for_simd:
10629 CodeGenFunction::EmitOMPTargetParallelForSimdDeviceFunction(
10630 CGM, ParentName, cast<OMPTargetParallelForSimdDirective>(E));
10631 break;
10632 case OMPD_target_simd:
10633 CodeGenFunction::EmitOMPTargetSimdDeviceFunction(
10634 CGM, ParentName, cast<OMPTargetSimdDirective>(E));
10635 break;
10636 case OMPD_target_teams_distribute_parallel_for:
10637 CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForDeviceFunction(
10638 CGM, ParentName,
10639 cast<OMPTargetTeamsDistributeParallelForDirective>(E));
10640 break;
10641 case OMPD_target_teams_distribute_parallel_for_simd:
10642 CodeGenFunction::
10643 EmitOMPTargetTeamsDistributeParallelForSimdDeviceFunction(
10644 CGM, ParentName,
10645 cast<OMPTargetTeamsDistributeParallelForSimdDirective>(E));
10646 break;
10647 case OMPD_parallel:
10648 case OMPD_for:
10649 case OMPD_parallel_for:
10650 case OMPD_parallel_master:
10651 case OMPD_parallel_sections:
10652 case OMPD_for_simd:
10653 case OMPD_parallel_for_simd:
10654 case OMPD_cancel:
10655 case OMPD_cancellation_point:
10656 case OMPD_ordered:
10657 case OMPD_threadprivate:
10658 case OMPD_allocate:
10659 case OMPD_task:
10660 case OMPD_simd:
10661 case OMPD_tile:
10662 case OMPD_unroll:
10663 case OMPD_sections:
10664 case OMPD_section:
10665 case OMPD_single:
10666 case OMPD_master:
10667 case OMPD_critical:
10668 case OMPD_taskyield:
10669 case OMPD_barrier:
10670 case OMPD_taskwait:
10671 case OMPD_taskgroup:
10672 case OMPD_atomic:
10673 case OMPD_flush:
10674 case OMPD_depobj:
10675 case OMPD_scan:
10676 case OMPD_teams:
10677 case OMPD_target_data:
10678 case OMPD_target_exit_data:
10679 case OMPD_target_enter_data:
10680 case OMPD_distribute:
10681 case OMPD_distribute_simd:
10682 case OMPD_distribute_parallel_for:
10683 case OMPD_distribute_parallel_for_simd:
10684 case OMPD_teams_distribute:
10685 case OMPD_teams_distribute_simd:
10686 case OMPD_teams_distribute_parallel_for:
10687 case OMPD_teams_distribute_parallel_for_simd:
10688 case OMPD_target_update:
10689 case OMPD_declare_simd:
10690 case OMPD_declare_variant:
10691 case OMPD_begin_declare_variant:
10692 case OMPD_end_declare_variant:
10693 case OMPD_declare_target:
10694 case OMPD_end_declare_target:
10695 case OMPD_declare_reduction:
10696 case OMPD_declare_mapper:
10697 case OMPD_taskloop:
10698 case OMPD_taskloop_simd:
10699 case OMPD_master_taskloop:
10700 case OMPD_master_taskloop_simd:
10701 case OMPD_parallel_master_taskloop:
10702 case OMPD_parallel_master_taskloop_simd:
10703 case OMPD_requires:
10704 case OMPD_unknown:
10705 default:
10706 llvm_unreachable("Unknown target directive for OpenMP device codegen.")__builtin_unreachable();
10707 }
10708 return;
10709 }
10710
10711 if (const auto *E = dyn_cast<OMPExecutableDirective>(S)) {
10712 if (!E->hasAssociatedStmt() || !E->getAssociatedStmt())
10713 return;
10714
10715 scanForTargetRegionsFunctions(E->getRawStmt(), ParentName);
10716 return;
10717 }
10718
10719 // If this is a lambda function, look into its body.
10720 if (const auto *L = dyn_cast<LambdaExpr>(S))
10721 S = L->getBody();
10722
10723 // Keep looking for target regions recursively.
10724 for (const Stmt *II : S->children())
10725 scanForTargetRegionsFunctions(II, ParentName);
10726}
10727
10728static bool isAssumedToBeNotEmitted(const ValueDecl *VD, bool IsDevice) {
10729 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
10730 OMPDeclareTargetDeclAttr::getDeviceType(VD);
10731 if (!DevTy)
10732 return false;
10733 // Do not emit device_type(nohost) functions for the host.
10734 if (!IsDevice && DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
10735 return true;
10736 // Do not emit device_type(host) functions for the device.
10737 if (IsDevice && DevTy == OMPDeclareTargetDeclAttr::DT_Host)
10738 return true;
10739 return false;
10740}
10741
10742bool CGOpenMPRuntime::emitTargetFunctions(GlobalDecl GD) {
10743 // If emitting code for the host, we do not process FD here. Instead we do
10744 // the normal code generation.
10745 if (!CGM.getLangOpts().OpenMPIsDevice) {
10746 if (const auto *FD = dyn_cast<FunctionDecl>(GD.getDecl()))
10747 if (isAssumedToBeNotEmitted(cast<ValueDecl>(FD),
10748 CGM.getLangOpts().OpenMPIsDevice))
10749 return true;
10750 return false;
10751 }
10752
10753 const ValueDecl *VD = cast<ValueDecl>(GD.getDecl());
10754 // Try to detect target regions in the function.
10755 if (const auto *FD = dyn_cast<FunctionDecl>(VD)) {
10756 StringRef Name = CGM.getMangledName(GD);
10757 scanForTargetRegionsFunctions(FD->getBody(), Name);
10758 if (isAssumedToBeNotEmitted(cast<ValueDecl>(FD),
10759 CGM.getLangOpts().OpenMPIsDevice))
10760 return true;
10761 }
10762
10763 // Do not to emit function if it is not marked as declare target.
10764 return !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) &&
10765 AlreadyEmittedTargetDecls.count(VD) == 0;
10766}
10767
10768bool CGOpenMPRuntime::emitTargetGlobalVariable(GlobalDecl GD) {
10769 if (isAssumedToBeNotEmitted(cast<ValueDecl>(GD.getDecl()),
10770 CGM.getLangOpts().OpenMPIsDevice))
10771 return true;
10772
10773 if (!CGM.getLangOpts().OpenMPIsDevice)
10774 return false;
10775
10776 // Check if there are Ctors/Dtors in this declaration and look for target
10777 // regions in it. We use the complete variant to produce the kernel name
10778 // mangling.
10779 QualType RDTy = cast<VarDecl>(GD.getDecl())->getType();
10780 if (const auto *RD = RDTy->getBaseElementTypeUnsafe()->getAsCXXRecordDecl()) {
10781 for (const CXXConstructorDecl *Ctor : RD->ctors()) {
10782 StringRef ParentName =
10783 CGM.getMangledName(GlobalDecl(Ctor, Ctor_Complete));
10784 scanForTargetRegionsFunctions(Ctor->getBody(), ParentName);
10785 }
10786 if (const CXXDestructorDecl *Dtor = RD->getDestructor()) {
10787 StringRef ParentName =
10788 CGM.getMangledName(GlobalDecl(Dtor, Dtor_Complete));
10789 scanForTargetRegionsFunctions(Dtor->getBody(), ParentName);
10790 }
10791 }
10792
10793 // Do not to emit variable if it is not marked as declare target.
10794 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
10795 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
10796 cast<VarDecl>(GD.getDecl()));
10797 if (!Res || *Res == OMPDeclareTargetDeclAttr::MT_Link ||
10798 (*Res == OMPDeclareTargetDeclAttr::MT_To &&
10799 HasRequiresUnifiedSharedMemory)) {
10800 DeferredGlobalVariables.insert(cast<VarDecl>(GD.getDecl()));
10801 return true;
10802 }
10803 return false;
10804}
10805
10806void CGOpenMPRuntime::registerTargetGlobalVariable(const VarDecl *VD,
10807 llvm::Constant *Addr) {
10808 if (CGM.getLangOpts().OMPTargetTriples.empty() &&
10809 !CGM.getLangOpts().OpenMPIsDevice)
10810 return;
10811
10812 // If we have host/nohost variables, they do not need to be registered.
10813 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
10814 OMPDeclareTargetDeclAttr::getDeviceType(VD);
10815 if (DevTy && DevTy.getValue() != OMPDeclareTargetDeclAttr::DT_Any)
10816 return;
10817
10818 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
10819 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
10820 if (!Res) {
10821 if (CGM.getLangOpts().OpenMPIsDevice) {
10822 // Register non-target variables being emitted in device code (debug info
10823 // may cause this).
10824 StringRef VarName = CGM.getMangledName(VD);
10825 EmittedNonTargetVariables.try_emplace(VarName, Addr);
10826 }
10827 return;
10828 }
10829 // Register declare target variables.
10830 OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind Flags;
10831 StringRef VarName;
10832 CharUnits VarSize;
10833 llvm::GlobalValue::LinkageTypes Linkage;
10834
10835 if (*Res == OMPDeclareTargetDeclAttr::MT_To &&
10836 !HasRequiresUnifiedSharedMemory) {
10837 Flags = OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryTo;
10838 VarName = CGM.getMangledName(VD);
10839 if (VD->hasDefinition(CGM.getContext()) != VarDecl::DeclarationOnly) {
10840 VarSize = CGM.getContext().getTypeSizeInChars(VD->getType());
10841 assert(!VarSize.isZero() && "Expected non-zero size of the variable")(static_cast<void> (0));
10842 } else {
10843 VarSize = CharUnits::Zero();
10844 }
10845 Linkage = CGM.getLLVMLinkageVarDefinition(VD, /*IsConstant=*/false);
10846 // Temp solution to prevent optimizations of the internal variables.
10847 if (CGM.getLangOpts().OpenMPIsDevice && !VD->isExternallyVisible()) {
10848 // Do not create a "ref-variable" if the original is not also available
10849 // on the host.
10850 if (!OffloadEntriesInfoManager.hasDeviceGlobalVarEntryInfo(VarName))
10851 return;
10852 std::string RefName = getName({VarName, "ref"});
10853 if (!CGM.GetGlobalValue(RefName)) {
10854 llvm::Constant *AddrRef =
10855 getOrCreateInternalVariable(Addr->getType(), RefName);
10856 auto *GVAddrRef = cast<llvm::GlobalVariable>(AddrRef);
10857 GVAddrRef->setConstant(/*Val=*/true);
10858 GVAddrRef->setLinkage(llvm::GlobalValue::InternalLinkage);
10859 GVAddrRef->setInitializer(Addr);
10860 CGM.addCompilerUsedGlobal(GVAddrRef);
10861 }
10862 }
10863 } else {
10864 assert(((*Res == OMPDeclareTargetDeclAttr::MT_Link) ||(static_cast<void> (0))
10865 (*Res == OMPDeclareTargetDeclAttr::MT_To &&(static_cast<void> (0))
10866 HasRequiresUnifiedSharedMemory)) &&(static_cast<void> (0))
10867 "Declare target attribute must link or to with unified memory.")(static_cast<void> (0));
10868 if (*Res == OMPDeclareTargetDeclAttr::MT_Link)
10869 Flags = OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryLink;
10870 else
10871 Flags = OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryTo;
10872
10873 if (CGM.getLangOpts().OpenMPIsDevice) {
10874 VarName = Addr->getName();
10875 Addr = nullptr;
10876 } else {
10877 VarName = getAddrOfDeclareTargetVar(VD).getName();
10878 Addr = cast<llvm::Constant>(getAddrOfDeclareTargetVar(VD).getPointer());
10879 }
10880 VarSize = CGM.getPointerSize();
10881 Linkage = llvm::GlobalValue::WeakAnyLinkage;
10882 }
10883
10884 OffloadEntriesInfoManager.registerDeviceGlobalVarEntryInfo(
10885 VarName, Addr, VarSize, Flags, Linkage);
10886}
10887
10888bool CGOpenMPRuntime::emitTargetGlobal(GlobalDecl GD) {
10889 if (isa<FunctionDecl>(GD.getDecl()) ||
10890 isa<OMPDeclareReductionDecl>(GD.getDecl()))
10891 return emitTargetFunctions(GD);
10892
10893 return emitTargetGlobalVariable(GD);
10894}
10895
10896void CGOpenMPRuntime::emitDeferredTargetDecls() const {
10897 for (const VarDecl *VD : DeferredGlobalVariables) {
10898 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
10899 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
10900 if (!Res)
10901 continue;
10902 if (*Res == OMPDeclareTargetDeclAttr::MT_To &&
10903 !HasRequiresUnifiedSharedMemory) {
10904 CGM.EmitGlobal(VD);
10905 } else {
10906 assert((*Res == OMPDeclareTargetDeclAttr::MT_Link ||(static_cast<void> (0))
10907 (*Res == OMPDeclareTargetDeclAttr::MT_To &&(static_cast<void> (0))
10908 HasRequiresUnifiedSharedMemory)) &&(static_cast<void> (0))
10909 "Expected link clause or to clause with unified memory.")(static_cast<void> (0));
10910 (void)CGM.getOpenMPRuntime().getAddrOfDeclareTargetVar(VD);
10911 }
10912 }
10913}
10914
10915void CGOpenMPRuntime::adjustTargetSpecificDataForLambdas(
10916 CodeGenFunction &CGF, const OMPExecutableDirective &D) const {
10917 assert(isOpenMPTargetExecutionDirective(D.getDirectiveKind()) &&(static_cast<void> (0))
10918 " Expected target-based directive.")(static_cast<void> (0));
10919}
10920
10921void CGOpenMPRuntime::processRequiresDirective(const OMPRequiresDecl *D) {
10922 for (const OMPClause *Clause : D->clauselists()) {
10923 if (Clause->getClauseKind() == OMPC_unified_shared_memory) {
10924 HasRequiresUnifiedSharedMemory = true;
10925 } else if (const auto *AC =
10926 dyn_cast<OMPAtomicDefaultMemOrderClause>(Clause)) {
10927 switch (AC->getAtomicDefaultMemOrderKind()) {
10928 case OMPC_ATOMIC_DEFAULT_MEM_ORDER_acq_rel:
10929 RequiresAtomicOrdering = llvm::AtomicOrdering::AcquireRelease;
10930 break;
10931 case OMPC_ATOMIC_DEFAULT_MEM_ORDER_seq_cst:
10932 RequiresAtomicOrdering = llvm::AtomicOrdering::SequentiallyConsistent;
10933 break;
10934 case OMPC_ATOMIC_DEFAULT_MEM_ORDER_relaxed:
10935 RequiresAtomicOrdering = llvm::AtomicOrdering::Monotonic;
10936 break;
10937 case OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown:
10938 break;
10939 }
10940 }
10941 }
10942}
10943
10944llvm::AtomicOrdering CGOpenMPRuntime::getDefaultMemoryOrdering() const {
10945 return RequiresAtomicOrdering;
10946}
10947
10948bool CGOpenMPRuntime::hasAllocateAttributeForGlobalVar(const VarDecl *VD,
10949 LangAS &AS) {
10950 if (!VD || !VD->hasAttr<OMPAllocateDeclAttr>())
10951 return false;
10952 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
10953 switch(A->getAllocatorType()) {
10954 case OMPAllocateDeclAttr::OMPNullMemAlloc:
10955 case OMPAllocateDeclAttr::OMPDefaultMemAlloc:
10956 // Not supported, fallback to the default mem space.
10957 case OMPAllocateDeclAttr::OMPLargeCapMemAlloc:
10958 case OMPAllocateDeclAttr::OMPCGroupMemAlloc:
10959 case OMPAllocateDeclAttr::OMPHighBWMemAlloc:
10960 case OMPAllocateDeclAttr::OMPLowLatMemAlloc:
10961 case OMPAllocateDeclAttr::OMPThreadMemAlloc:
10962 case OMPAllocateDeclAttr::OMPConstMemAlloc:
10963 case OMPAllocateDeclAttr::OMPPTeamMemAlloc:
10964 AS = LangAS::Default;
10965 return true;
10966 case OMPAllocateDeclAttr::OMPUserDefinedMemAlloc:
10967 llvm_unreachable("Expected predefined allocator for the variables with the "__builtin_unreachable()
10968 "static storage.")__builtin_unreachable();
10969 }
10970 return false;
10971}
10972
10973bool CGOpenMPRuntime::hasRequiresUnifiedSharedMemory() const {
10974 return HasRequiresUnifiedSharedMemory;
10975}
10976
10977CGOpenMPRuntime::DisableAutoDeclareTargetRAII::DisableAutoDeclareTargetRAII(
10978 CodeGenModule &CGM)
10979 : CGM(CGM) {
10980 if (CGM.getLangOpts().OpenMPIsDevice) {
10981 SavedShouldMarkAsGlobal = CGM.getOpenMPRuntime().ShouldMarkAsGlobal;
10982 CGM.getOpenMPRuntime().ShouldMarkAsGlobal = false;
10983 }
10984}
10985
10986CGOpenMPRuntime::DisableAutoDeclareTargetRAII::~DisableAutoDeclareTargetRAII() {
10987 if (CGM.getLangOpts().OpenMPIsDevice)
10988 CGM.getOpenMPRuntime().ShouldMarkAsGlobal = SavedShouldMarkAsGlobal;
10989}
10990
10991bool CGOpenMPRuntime::markAsGlobalTarget(GlobalDecl GD) {
10992 if (!CGM.getLangOpts().OpenMPIsDevice || !ShouldMarkAsGlobal)
10993 return true;
10994
10995 const auto *D = cast<FunctionDecl>(GD.getDecl());
10996 // Do not to emit function if it is marked as declare target as it was already
10997 // emitted.
10998 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(D)) {
10999 if (D->hasBody() && AlreadyEmittedTargetDecls.count(D) == 0) {
11000 if (auto *F = dyn_cast_or_null<llvm::Function>(
11001 CGM.GetGlobalValue(CGM.getMangledName(GD))))
11002 return !F->isDeclaration();
11003 return false;
11004 }
11005 return true;
11006 }
11007
11008 return !AlreadyEmittedTargetDecls.insert(D).second;
11009}
11010
11011llvm::Function *CGOpenMPRuntime::emitRequiresDirectiveRegFun() {
11012 // If we don't have entries or if we are emitting code for the device, we
11013 // don't need to do anything.
11014 if (CGM.getLangOpts().OMPTargetTriples.empty() ||
11015 CGM.getLangOpts().OpenMPSimd || CGM.getLangOpts().OpenMPIsDevice ||
11016 (OffloadEntriesInfoManager.empty() &&
11017 !HasEmittedDeclareTargetRegion &&
11018 !HasEmittedTargetRegion))
11019 return nullptr;
11020
11021 // Create and register the function that handles the requires directives.
11022 ASTContext &C = CGM.getContext();
11023
11024 llvm::Function *RequiresRegFn;
11025 {
11026 CodeGenFunction CGF(CGM);
11027 const auto &FI = CGM.getTypes().arrangeNullaryFunction();
11028 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
11029 std::string ReqName = getName({"omp_offloading", "requires_reg"});
11030 RequiresRegFn = CGM.CreateGlobalInitOrCleanUpFunction(FTy, ReqName, FI);
11031 CGF.StartFunction(GlobalDecl(), C.VoidTy, RequiresRegFn, FI, {});
11032 OpenMPOffloadingRequiresDirFlags Flags = OMP_REQ_NONE;
11033 // TODO: check for other requires clauses.
11034 // The requires directive takes effect only when a target region is
11035 // present in the compilation unit. Otherwise it is ignored and not
11036 // passed to the runtime. This avoids the runtime from throwing an error
11037 // for mismatching requires clauses across compilation units that don't
11038 // contain at least 1 target region.
11039 assert((HasEmittedTargetRegion ||(static_cast<void> (0))
11040 HasEmittedDeclareTargetRegion ||(static_cast<void> (0))
11041 !OffloadEntriesInfoManager.empty()) &&(static_cast<void> (0))
11042 "Target or declare target region expected.")(static_cast<void> (0));
11043 if (HasRequiresUnifiedSharedMemory)
11044 Flags = OMP_REQ_UNIFIED_SHARED_MEMORY;
11045 CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
11046 CGM.getModule(), OMPRTL___tgt_register_requires),
11047 llvm::ConstantInt::get(CGM.Int64Ty, Flags));
11048 CGF.FinishFunction();
11049 }
11050 return RequiresRegFn;
11051}
11052
11053void CGOpenMPRuntime::emitTeamsCall(CodeGenFunction &CGF,
11054 const OMPExecutableDirective &D,
11055 SourceLocation Loc,
11056 llvm::Function *OutlinedFn,
11057 ArrayRef<llvm::Value *> CapturedVars) {
11058 if (!CGF.HaveInsertPoint())
11059 return;
11060
11061 llvm::Value *RTLoc = emitUpdateLocation(CGF, Loc);
11062 CodeGenFunction::RunCleanupsScope Scope(CGF);
11063
11064 // Build call __kmpc_fork_teams(loc, n, microtask, var1, .., varn);
11065 llvm::Value *Args[] = {
11066 RTLoc,
11067 CGF.Builder.getInt32(CapturedVars.size()), // Number of captured vars
11068 CGF.Builder.CreateBitCast(OutlinedFn, getKmpc_MicroPointerTy())};
11069 llvm::SmallVector<llvm::Value *, 16> RealArgs;
11070 RealArgs.append(std::begin(Args), std::end(Args));
11071 RealArgs.append(CapturedVars.begin(), CapturedVars.end());
11072
11073 llvm::FunctionCallee RTLFn = OMPBuilder.getOrCreateRuntimeFunction(
11074 CGM.getModule(), OMPRTL___kmpc_fork_teams);
11075 CGF.EmitRuntimeCall(RTLFn, RealArgs);
11076}
11077
11078void CGOpenMPRuntime::emitNumTeamsClause(CodeGenFunction &CGF,
11079 const Expr *NumTeams,
11080 const Expr *ThreadLimit,
11081 SourceLocation Loc) {
11082 if (!CGF.HaveInsertPoint())
11083 return;
11084
11085 llvm::Value *RTLoc = emitUpdateLocation(CGF, Loc);
11086
11087 llvm::Value *NumTeamsVal =
11088 NumTeams
11089 ? CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(NumTeams),
11090 CGF.CGM.Int32Ty, /* isSigned = */ true)
11091 : CGF.Builder.getInt32(0);
11092
11093 llvm::Value *ThreadLimitVal =
11094 ThreadLimit
11095 ? CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(ThreadLimit),
11096 CGF.CGM.Int32Ty, /* isSigned = */ true)
11097 : CGF.Builder.getInt32(0);
11098
11099 // Build call __kmpc_push_num_teamss(&loc, global_tid, num_teams, thread_limit)
11100 llvm::Value *PushNumTeamsArgs[] = {RTLoc, getThreadID(CGF, Loc), NumTeamsVal,
11101 ThreadLimitVal};
11102 CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
11103 CGM.getModule(), OMPRTL___kmpc_push_num_teams),
11104 PushNumTeamsArgs);
11105}
11106
11107void CGOpenMPRuntime::emitTargetDataCalls(
11108 CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond,
11109 const Expr *Device, const RegionCodeGenTy &CodeGen, TargetDataInfo &Info) {
11110 if (!CGF.HaveInsertPoint())
11111 return;
11112
11113 // Action used to replace the default codegen action and turn privatization
11114 // off.
11115 PrePostActionTy NoPrivAction;
11116
11117 // Generate the code for the opening of the data environment. Capture all the
11118 // arguments of the runtime call by reference because they are used in the
11119 // closing of the region.
11120 auto &&BeginThenGen = [this, &D, Device, &Info,
11121 &CodeGen](CodeGenFunction &CGF, PrePostActionTy &) {
11122 // Fill up the arrays with all the mapped variables.
11123 MappableExprsHandler::MapCombinedInfoTy CombinedInfo;
11124
11125 // Get map clause information.
11126 MappableExprsHandler MEHandler(D, CGF);
11127 MEHandler.generateAllInfo(CombinedInfo);
11128
11129 // Fill up the arrays and create the arguments.
11130 emitOffloadingArrays(CGF, CombinedInfo, Info, OMPBuilder,
11131 /*IsNonContiguous=*/true);
11132
11133 llvm::Value *BasePointersArrayArg = nullptr;
11134 llvm::Value *PointersArrayArg = nullptr;
11135 llvm::Value *SizesArrayArg = nullptr;
11136 llvm::Value *MapTypesArrayArg = nullptr;
11137 llvm::Value *MapNamesArrayArg = nullptr;
11138 llvm::Value *MappersArrayArg = nullptr;
11139 emitOffloadingArraysArgument(CGF, BasePointersArrayArg, PointersArrayArg,
11140 SizesArrayArg, MapTypesArrayArg,
11141 MapNamesArrayArg, MappersArrayArg, Info);
11142
11143 // Emit device ID if any.
11144 llvm::Value *DeviceID = nullptr;
11145 if (Device) {
11146 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
11147 CGF.Int64Ty, /*isSigned=*/true);
11148 } else {
11149 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
11150 }
11151
11152 // Emit the number of elements in the offloading arrays.
11153 llvm::Value *PointerNum = CGF.Builder.getInt32(Info.NumberOfPtrs);
11154 //
11155 // Source location for the ident struct
11156 llvm::Value *RTLoc = emitUpdateLocation(CGF, D.getBeginLoc());
11157
11158 llvm::Value *OffloadingArgs[] = {RTLoc,
11159 DeviceID,
11160 PointerNum,
11161 BasePointersArrayArg,
11162 PointersArrayArg,
11163 SizesArrayArg,
11164 MapTypesArrayArg,
11165 MapNamesArrayArg,
11166 MappersArrayArg};
11167 CGF.EmitRuntimeCall(
11168 OMPBuilder.getOrCreateRuntimeFunction(
11169 CGM.getModule(), OMPRTL___tgt_target_data_begin_mapper),
11170 OffloadingArgs);
11171
11172 // If device pointer privatization is required, emit the body of the region
11173 // here. It will have to be duplicated: with and without privatization.
11174 if (!Info.CaptureDeviceAddrMap.empty())
11175 CodeGen(CGF);
11176 };
11177
11178 // Generate code for the closing of the data region.
11179 auto &&EndThenGen = [this, Device, &Info, &D](CodeGenFunction &CGF,
11180 PrePostActionTy &) {
11181 assert(Info.isValid() && "Invalid data environment closing arguments.")(static_cast<void> (0));
11182
11183 llvm::Value *BasePointersArrayArg = nullptr;
11184 llvm::Value *PointersArrayArg = nullptr;
11185 llvm::Value *SizesArrayArg = nullptr;
11186 llvm::Value *MapTypesArrayArg = nullptr;
11187 llvm::Value *MapNamesArrayArg = nullptr;
11188 llvm::Value *MappersArrayArg = nullptr;
11189 emitOffloadingArraysArgument(CGF, BasePointersArrayArg, PointersArrayArg,
11190 SizesArrayArg, MapTypesArrayArg,
11191 MapNamesArrayArg, MappersArrayArg, Info,
11192 {/*ForEndCall=*/true});
11193
11194 // Emit device ID if any.
11195 llvm::Value *DeviceID = nullptr;
11196 if (Device) {
11197 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
11198 CGF.Int64Ty, /*isSigned=*/true);
11199 } else {
11200 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
11201 }
11202
11203 // Emit the number of elements in the offloading arrays.
11204 llvm::Value *PointerNum = CGF.Builder.getInt32(Info.NumberOfPtrs);
11205
11206 // Source location for the ident struct
11207 llvm::Value *RTLoc = emitUpdateLocation(CGF, D.getBeginLoc());
11208
11209 llvm::Value *OffloadingArgs[] = {RTLoc,
11210 DeviceID,
11211 PointerNum,
11212 BasePointersArrayArg,
11213 PointersArrayArg,
11214 SizesArrayArg,
11215 MapTypesArrayArg,
11216 MapNamesArrayArg,
11217 MappersArrayArg};
11218 CGF.EmitRuntimeCall(
11219 OMPBuilder.getOrCreateRuntimeFunction(
11220 CGM.getModule(), OMPRTL___tgt_target_data_end_mapper),
11221 OffloadingArgs);
11222 };
11223
11224 // If we need device pointer privatization, we need to emit the body of the
11225 // region with no privatization in the 'else' branch of the conditional.
11226 // Otherwise, we don't have to do anything.
11227 auto &&BeginElseGen = [&Info, &CodeGen, &NoPrivAction](CodeGenFunction &CGF,
11228 PrePostActionTy &) {
11229 if (!Info.CaptureDeviceAddrMap.empty()) {
11230 CodeGen.setAction(NoPrivAction);
11231 CodeGen(CGF);
11232 }
11233 };
11234
11235 // We don't have to do anything to close the region if the if clause evaluates
11236 // to false.
11237 auto &&EndElseGen = [](CodeGenFunction &CGF, PrePostActionTy &) {};
11238
11239 if (IfCond) {
11240 emitIfClause(CGF, IfCond, BeginThenGen, BeginElseGen);
11241 } else {
11242 RegionCodeGenTy RCG(BeginThenGen);
11243 RCG(CGF);
11244 }
11245
11246 // If we don't require privatization of device pointers, we emit the body in
11247 // between the runtime calls. This avoids duplicating the body code.
11248 if (Info.CaptureDeviceAddrMap.empty()) {
11249 CodeGen.setAction(NoPrivAction);
11250 CodeGen(CGF);
11251 }
11252
11253 if (IfCond) {
11254 emitIfClause(CGF, IfCond, EndThenGen, EndElseGen);
11255 } else {
11256 RegionCodeGenTy RCG(EndThenGen);
11257 RCG(CGF);
11258 }
11259}
11260
11261void CGOpenMPRuntime::emitTargetDataStandAloneCall(
11262 CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond,
11263 const Expr *Device) {
11264 if (!CGF.HaveInsertPoint())
11265 return;
11266
11267 assert((isa<OMPTargetEnterDataDirective>(D) ||(static_cast<void> (0))
11268 isa<OMPTargetExitDataDirective>(D) ||(static_cast<void> (0))
11269 isa<OMPTargetUpdateDirective>(D)) &&(static_cast<void> (0))
11270 "Expecting either target enter, exit data, or update directives.")(static_cast<void> (0));
11271
11272 CodeGenFunction::OMPTargetDataInfo InputInfo;
11273 llvm::Value *MapTypesArray = nullptr;
11274 llvm::Value *MapNamesArray = nullptr;
11275 // Generate the code for the opening of the data environment.
11276 auto &&ThenGen = [this, &D, Device, &InputInfo, &MapTypesArray,
11277 &MapNamesArray](CodeGenFunction &CGF, PrePostActionTy &) {
11278 // Emit device ID if any.
11279 llvm::Value *DeviceID = nullptr;
11280 if (Device) {
11281 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
11282 CGF.Int64Ty, /*isSigned=*/true);
11283 } else {
11284 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
11285 }
11286
11287 // Emit the number of elements in the offloading arrays.
11288 llvm::Constant *PointerNum =
11289 CGF.Builder.getInt32(InputInfo.NumberOfTargetItems);
11290
11291 // Source location for the ident struct
11292 llvm::Value *RTLoc = emitUpdateLocation(CGF, D.getBeginLoc());
11293
11294 llvm::Value *OffloadingArgs[] = {RTLoc,
11295 DeviceID,
11296 PointerNum,
11297 InputInfo.BasePointersArray.getPointer(),
11298 InputInfo.PointersArray.getPointer(),
11299 InputInfo.SizesArray.getPointer(),
11300 MapTypesArray,
11301 MapNamesArray,
11302 InputInfo.MappersArray.getPointer()};
11303
11304 // Select the right runtime function call for each standalone
11305 // directive.
11306 const bool HasNowait = D.hasClausesOfKind<OMPNowaitClause>();
11307 RuntimeFunction RTLFn;
11308 switch (D.getDirectiveKind()) {
11309 case OMPD_target_enter_data:
11310 RTLFn = HasNowait ? OMPRTL___tgt_target_data_begin_nowait_mapper
11311 : OMPRTL___tgt_target_data_begin_mapper;
11312 break;
11313 case OMPD_target_exit_data:
11314 RTLFn = HasNowait ? OMPRTL___tgt_target_data_end_nowait_mapper
11315 : OMPRTL___tgt_target_data_end_mapper;
11316 break;
11317 case OMPD_target_update:
11318 RTLFn = HasNowait ? OMPRTL___tgt_target_data_update_nowait_mapper
11319 : OMPRTL___tgt_target_data_update_mapper;
11320 break;
11321 case OMPD_parallel:
11322 case OMPD_for:
11323 case OMPD_parallel_for:
11324 case OMPD_parallel_master:
11325 case OMPD_parallel_sections:
11326 case OMPD_for_simd:
11327 case OMPD_parallel_for_simd:
11328 case OMPD_cancel:
11329 case OMPD_cancellation_point:
11330 case OMPD_ordered:
11331 case OMPD_threadprivate:
11332 case OMPD_allocate:
11333 case OMPD_task:
11334 case OMPD_simd:
11335 case OMPD_tile:
11336 case OMPD_unroll:
11337 case OMPD_sections:
11338 case OMPD_section:
11339 case OMPD_single:
11340 case OMPD_master:
11341 case OMPD_critical:
11342 case OMPD_taskyield:
11343 case OMPD_barrier:
11344 case OMPD_taskwait:
11345 case OMPD_taskgroup:
11346 case OMPD_atomic:
11347 case OMPD_flush:
11348 case OMPD_depobj:
11349 case OMPD_scan:
11350 case OMPD_teams:
11351 case OMPD_target_data:
11352 case OMPD_distribute:
11353 case OMPD_distribute_simd:
11354 case OMPD_distribute_parallel_for:
11355 case OMPD_distribute_parallel_for_simd:
11356 case OMPD_teams_distribute:
11357 case OMPD_teams_distribute_simd:
11358 case OMPD_teams_distribute_parallel_for:
11359 case OMPD_teams_distribute_parallel_for_simd:
11360 case OMPD_declare_simd:
11361 case OMPD_declare_variant:
11362 case OMPD_begin_declare_variant:
11363 case OMPD_end_declare_variant:
11364 case OMPD_declare_target:
11365 case OMPD_end_declare_target:
11366 case OMPD_declare_reduction:
11367 case OMPD_declare_mapper:
11368 case OMPD_taskloop:
11369 case OMPD_taskloop_simd:
11370 case OMPD_master_taskloop:
11371 case OMPD_master_taskloop_simd:
11372 case OMPD_parallel_master_taskloop:
11373 case OMPD_parallel_master_taskloop_simd:
11374 case OMPD_target:
11375 case OMPD_target_simd:
11376 case OMPD_target_teams_distribute:
11377 case OMPD_target_teams_distribute_simd:
11378 case OMPD_target_teams_distribute_parallel_for:
11379 case OMPD_target_teams_distribute_parallel_for_simd:
11380 case OMPD_target_teams:
11381 case OMPD_target_parallel:
11382 case OMPD_target_parallel_for:
11383 case OMPD_target_parallel_for_simd:
11384 case OMPD_requires:
11385 case OMPD_unknown:
11386 default:
11387 llvm_unreachable("Unexpected standalone target data directive.")__builtin_unreachable();
11388 break;
11389 }
11390 CGF.EmitRuntimeCall(
11391 OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(), RTLFn),
11392 OffloadingArgs);
11393 };
11394
11395 auto &&TargetThenGen = [this, &ThenGen, &D, &InputInfo, &MapTypesArray,
11396 &MapNamesArray](CodeGenFunction &CGF,
11397 PrePostActionTy &) {
11398 // Fill up the arrays with all the mapped variables.
11399 MappableExprsHandler::MapCombinedInfoTy CombinedInfo;
11400
11401 // Get map clause information.
11402 MappableExprsHandler MEHandler(D, CGF);
11403 MEHandler.generateAllInfo(CombinedInfo);
11404
11405 TargetDataInfo Info;
11406 // Fill up the arrays and create the arguments.
11407 emitOffloadingArrays(CGF, CombinedInfo, Info, OMPBuilder,
11408 /*IsNonContiguous=*/true);
11409 bool RequiresOuterTask = D.hasClausesOfKind<OMPDependClause>() ||
11410 D.hasClausesOfKind<OMPNowaitClause>();
11411 emitOffloadingArraysArgument(
11412 CGF, Info.BasePointersArray, Info.PointersArray, Info.SizesArray,
11413 Info.MapTypesArray, Info.MapNamesArray, Info.MappersArray, Info,
11414 {/*ForEndTask=*/false});
11415 InputInfo.NumberOfTargetItems = Info.NumberOfPtrs;
11416 InputInfo.BasePointersArray =
11417 Address(Info.BasePointersArray, CGM.getPointerAlign());
11418 InputInfo.PointersArray =
11419 Address(Info.PointersArray, CGM.getPointerAlign());
11420 InputInfo.SizesArray =
11421 Address(Info.SizesArray, CGM.getPointerAlign());
11422 InputInfo.MappersArray = Address(Info.MappersArray, CGM.getPointerAlign());
11423 MapTypesArray = Info.MapTypesArray;
11424 MapNamesArray = Info.MapNamesArray;
11425 if (RequiresOuterTask)
11426 CGF.EmitOMPTargetTaskBasedDirective(D, ThenGen, InputInfo);
11427 else
11428 emitInlinedDirective(CGF, D.getDirectiveKind(), ThenGen);
11429 };
11430
11431 if (IfCond) {
11432 emitIfClause(CGF, IfCond, TargetThenGen,
11433 [](CodeGenFunction &CGF, PrePostActionTy &) {});
11434 } else {
11435 RegionCodeGenTy ThenRCG(TargetThenGen);
11436 ThenRCG(CGF);
11437 }
11438}
11439
11440namespace {
11441 /// Kind of parameter in a function with 'declare simd' directive.
11442 enum ParamKindTy { LinearWithVarStride, Linear, Uniform, Vector };
11443 /// Attribute set of the parameter.
11444 struct ParamAttrTy {
11445 ParamKindTy Kind = Vector;
11446 llvm::APSInt StrideOrArg;
11447 llvm::APSInt Alignment;
11448 };
11449} // namespace
11450
11451static unsigned evaluateCDTSize(const FunctionDecl *FD,
11452 ArrayRef<ParamAttrTy> ParamAttrs) {
11453 // Every vector variant of a SIMD-enabled function has a vector length (VLEN).
11454 // If OpenMP clause "simdlen" is used, the VLEN is the value of the argument
11455 // of that clause. The VLEN value must be power of 2.
11456 // In other case the notion of the function`s "characteristic data type" (CDT)
11457 // is used to compute the vector length.
11458 // CDT is defined in the following order:
11459 // a) For non-void function, the CDT is the return type.
11460 // b) If the function has any non-uniform, non-linear parameters, then the
11461 // CDT is the type of the first such parameter.
11462 // c) If the CDT determined by a) or b) above is struct, union, or class
11463 // type which is pass-by-value (except for the type that maps to the
11464 // built-in complex data type), the characteristic data type is int.
11465 // d) If none of the above three cases is applicable, the CDT is int.
11466 // The VLEN is then determined based on the CDT and the size of vector
11467 // register of that ISA for which current vector version is generated. The
11468 // VLEN is computed using the formula below:
11469 // VLEN = sizeof(vector_register) / sizeof(CDT),
11470 // where vector register size specified in section 3.2.1 Registers and the
11471 // Stack Frame of original AMD64 ABI document.
11472 QualType RetType = FD->getReturnType();
11473 if (RetType.isNull())
21
Calling 'QualType::isNull'
27
Returning from 'QualType::isNull'
28
Taking true branch
11474 return 0;
29
Returning zero
11475 ASTContext &C = FD->getASTContext();
11476 QualType CDT;
11477 if (!RetType.isNull() && !RetType->isVoidType()) {
11478 CDT = RetType;
11479 } else {
11480 unsigned Offset = 0;
11481 if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
11482 if (ParamAttrs[Offset].Kind == Vector)
11483 CDT = C.getPointerType(C.getRecordType(MD->getParent()));
11484 ++Offset;
11485 }
11486 if (CDT.isNull()) {
11487 for (unsigned I = 0, E = FD->getNumParams(); I < E; ++I) {
11488 if (ParamAttrs[I + Offset].Kind == Vector) {
11489 CDT = FD->getParamDecl(I)->getType();
11490 break;
11491 }
11492 }
11493 }
11494 }
11495 if (CDT.isNull())
11496 CDT = C.IntTy;
11497 CDT = CDT->getCanonicalTypeUnqualified();
11498 if (CDT->isRecordType() || CDT->isUnionType())
11499 CDT = C.IntTy;
11500 return C.getTypeSize(CDT);
11501}
11502
11503static void
11504emitX86DeclareSimdFunction(const FunctionDecl *FD, llvm::Function *Fn,
11505 const llvm::APSInt &VLENVal,
11506 ArrayRef<ParamAttrTy> ParamAttrs,
11507 OMPDeclareSimdDeclAttr::BranchStateTy State) {
11508 struct ISADataTy {
11509 char ISA;
11510 unsigned VecRegSize;
11511 };
11512 ISADataTy ISAData[] = {
11513 {
11514 'b', 128
11515 }, // SSE
11516 {
11517 'c', 256
11518 }, // AVX
11519 {
11520 'd', 256
11521 }, // AVX2
11522 {
11523 'e', 512
11524 }, // AVX512
11525 };
11526 llvm::SmallVector<char, 2> Masked;
11527 switch (State) {
12
Control jumps to 'case BS_Inbranch:' at line 11535
11528 case OMPDeclareSimdDeclAttr::BS_Undefined:
11529 Masked.push_back('N');
11530 Masked.push_back('M');
11531 break;
11532 case OMPDeclareSimdDeclAttr::BS_Notinbranch:
11533 Masked.push_back('N');
11534 break;
11535 case OMPDeclareSimdDeclAttr::BS_Inbranch:
11536 Masked.push_back('M');
11537 break;
11538 }
11539 for (char Mask : Masked) {
13
Execution continues on line 11539
14
Assuming '__begin1' is not equal to '__end1'
11540 for (const ISADataTy &Data : ISAData) {
11541 SmallString<256> Buffer;
11542 llvm::raw_svector_ostream Out(Buffer);
11543 Out << "_ZGV" << Data.ISA << Mask;
11544 if (!VLENVal) {
15
Calling 'APInt::operator!'
18
Returning from 'APInt::operator!'
19
Taking true branch
11545 unsigned NumElts = evaluateCDTSize(FD, ParamAttrs);
20
Calling 'evaluateCDTSize'
30
Returning from 'evaluateCDTSize'
31
'NumElts' initialized to 0
11546 assert(NumElts && "Non-zero simdlen/cdtsize expected")(static_cast<void> (0));
11547 Out << llvm::APSInt::getUnsigned(Data.VecRegSize / NumElts);
32
Division by zero
11548 } else {
11549 Out << VLENVal;
11550 }
11551 for (const ParamAttrTy &ParamAttr : ParamAttrs) {
11552 switch (ParamAttr.Kind){
11553 case LinearWithVarStride:
11554 Out << 's' << ParamAttr.StrideOrArg;
11555 break;
11556 case Linear:
11557 Out << 'l';
11558 if (ParamAttr.StrideOrArg != 1)
11559 Out << ParamAttr.StrideOrArg;
11560 break;
11561 case Uniform:
11562 Out << 'u';
11563 break;
11564 case Vector:
11565 Out << 'v';
11566 break;
11567 }
11568 if (!!ParamAttr.Alignment)
11569 Out << 'a' << ParamAttr.Alignment;
11570 }
11571 Out << '_' << Fn->getName();
11572 Fn->addFnAttr(Out.str());
11573 }
11574 }
11575}
11576
11577// This are the Functions that are needed to mangle the name of the
11578// vector functions generated by the compiler, according to the rules
11579// defined in the "Vector Function ABI specifications for AArch64",
11580// available at
11581// https://developer.arm.com/products/software-development-tools/hpc/arm-compiler-for-hpc/vector-function-abi.
11582
11583/// Maps To Vector (MTV), as defined in 3.1.1 of the AAVFABI.
11584///
11585/// TODO: Need to implement the behavior for reference marked with a
11586/// var or no linear modifiers (1.b in the section). For this, we
11587/// need to extend ParamKindTy to support the linear modifiers.
11588static bool getAArch64MTV(QualType QT, ParamKindTy Kind) {
11589 QT = QT.getCanonicalType();
11590
11591 if (QT->isVoidType())
11592 return false;
11593
11594 if (Kind == ParamKindTy::Uniform)
11595 return false;
11596
11597 if (Kind == ParamKindTy::Linear)
11598 return false;
11599
11600 // TODO: Handle linear references with modifiers
11601
11602 if (Kind == ParamKindTy::LinearWithVarStride)
11603 return false;
11604
11605 return true;
11606}
11607
11608/// Pass By Value (PBV), as defined in 3.1.2 of the AAVFABI.
11609static bool getAArch64PBV(QualType QT, ASTContext &C) {
11610 QT = QT.getCanonicalType();
11611 unsigned Size = C.getTypeSize(QT);
11612
11613 // Only scalars and complex within 16 bytes wide set PVB to true.
11614 if (Size != 8 && Size != 16 && Size != 32 && Size != 64 && Size != 128)
11615 return false;
11616
11617 if (QT->isFloatingType())
11618 return true;
11619
11620 if (QT->isIntegerType())
11621 return true;
11622
11623 if (QT->isPointerType())
11624 return true;
11625
11626 // TODO: Add support for complex types (section 3.1.2, item 2).
11627
11628 return false;
11629}
11630
11631/// Computes the lane size (LS) of a return type or of an input parameter,
11632/// as defined by `LS(P)` in 3.2.1 of the AAVFABI.
11633/// TODO: Add support for references, section 3.2.1, item 1.
11634static unsigned getAArch64LS(QualType QT, ParamKindTy Kind, ASTContext &C) {
11635 if (!getAArch64MTV(QT, Kind) && QT.getCanonicalType()->isPointerType()) {
11636 QualType PTy = QT.getCanonicalType()->getPointeeType();
11637 if (getAArch64PBV(PTy, C))
11638 return C.getTypeSize(PTy);
11639 }
11640 if (getAArch64PBV(QT, C))
11641 return C.getTypeSize(QT);
11642
11643 return C.getTypeSize(C.getUIntPtrType());
11644}
11645
11646// Get Narrowest Data Size (NDS) and Widest Data Size (WDS) from the
11647// signature of the scalar function, as defined in 3.2.2 of the
11648// AAVFABI.
11649static std::tuple<unsigned, unsigned, bool>
11650getNDSWDS(const FunctionDecl *FD, ArrayRef<ParamAttrTy> ParamAttrs) {
11651 QualType RetType = FD->getReturnType().getCanonicalType();
11652
11653 ASTContext &C = FD->getASTContext();
11654
11655 bool OutputBecomesInput = false;
11656
11657 llvm::SmallVector<unsigned, 8> Sizes;
11658 if (!RetType->isVoidType()) {
11659 Sizes.push_back(getAArch64LS(RetType, ParamKindTy::Vector, C));
11660 if (!getAArch64PBV(RetType, C) && getAArch64MTV(RetType, {}))
11661 OutputBecomesInput = true;
11662 }
11663 for (unsigned I = 0, E = FD->getNumParams(); I < E; ++I) {
11664 QualType QT = FD->getParamDecl(I)->getType().getCanonicalType();
11665 Sizes.push_back(getAArch64LS(QT, ParamAttrs[I].Kind, C));
11666 }
11667
11668 assert(!Sizes.empty() && "Unable to determine NDS and WDS.")(static_cast<void> (0));
11669 // The LS of a function parameter / return value can only be a power
11670 // of 2, starting from 8 bits, up to 128.
11671 assert(std::all_of(Sizes.begin(), Sizes.end(),(static_cast<void> (0))
11672 [](unsigned Size) {(static_cast<void> (0))
11673 return Size == 8 || Size == 16 || Size == 32 ||(static_cast<void> (0))
11674 Size == 64 || Size == 128;(static_cast<void> (0))
11675 }) &&(static_cast<void> (0))
11676 "Invalid size")(static_cast<void> (0));
11677
11678 return std::make_tuple(*std::min_element(std::begin(Sizes), std::end(Sizes)),
11679 *std::max_element(std::begin(Sizes), std::end(Sizes)),
11680 OutputBecomesInput);
11681}
11682
11683/// Mangle the parameter part of the vector function name according to
11684/// their OpenMP classification. The mangling function is defined in
11685/// section 3.5 of the AAVFABI.
11686static std::string mangleVectorParameters(ArrayRef<ParamAttrTy> ParamAttrs) {
11687 SmallString<256> Buffer;
11688 llvm::raw_svector_ostream Out(Buffer);
11689 for (const auto &ParamAttr : ParamAttrs) {
11690 switch (ParamAttr.Kind) {
11691 case LinearWithVarStride:
11692 Out << "ls" << ParamAttr.StrideOrArg;
11693 break;
11694 case Linear:
11695 Out << 'l';
11696 // Don't print the step value if it is not present or if it is
11697 // equal to 1.
11698 if (ParamAttr.StrideOrArg != 1)
11699 Out << ParamAttr.StrideOrArg;
11700 break;
11701 case Uniform:
11702 Out << 'u';
11703 break;
11704 case Vector:
11705 Out << 'v';
11706 break;
11707 }
11708
11709 if (!!ParamAttr.Alignment)
11710 Out << 'a' << ParamAttr.Alignment;
11711 }
11712
11713 return std::string(Out.str());
11714}
11715
11716// Function used to add the attribute. The parameter `VLEN` is
11717// templated to allow the use of "x" when targeting scalable functions
11718// for SVE.
11719template <typename T>
11720static void addAArch64VectorName(T VLEN, StringRef LMask, StringRef Prefix,
11721 char ISA, StringRef ParSeq,
11722 StringRef MangledName, bool OutputBecomesInput,
11723 llvm::Function *Fn) {
11724 SmallString<256> Buffer;
11725 llvm::raw_svector_ostream Out(Buffer);
11726 Out << Prefix << ISA << LMask << VLEN;
11727 if (OutputBecomesInput)
11728 Out << "v";
11729 Out << ParSeq << "_" << MangledName;
11730 Fn->addFnAttr(Out.str());
11731}
11732
11733// Helper function to generate the Advanced SIMD names depending on
11734// the value of the NDS when simdlen is not present.
11735static void addAArch64AdvSIMDNDSNames(unsigned NDS, StringRef Mask,
11736 StringRef Prefix, char ISA,
11737 StringRef ParSeq, StringRef MangledName,
11738 bool OutputBecomesInput,
11739 llvm::Function *Fn) {
11740 switch (NDS) {
11741 case 8:
11742 addAArch64VectorName(8, Mask, Prefix, ISA, ParSeq, MangledName,
11743 OutputBecomesInput, Fn);
11744 addAArch64VectorName(16, Mask, Prefix, ISA, ParSeq, MangledName,
11745 OutputBecomesInput, Fn);
11746 break;
11747 case 16:
11748 addAArch64VectorName(4, Mask, Prefix, ISA, ParSeq, MangledName,
11749 OutputBecomesInput, Fn);
11750 addAArch64VectorName(8, Mask, Prefix, ISA, ParSeq, MangledName,
11751 OutputBecomesInput, Fn);
11752 break;
11753 case 32:
11754 addAArch64VectorName(2, Mask, Prefix, ISA, ParSeq, MangledName,
11755 OutputBecomesInput, Fn);
11756 addAArch64VectorName(4, Mask, Prefix, ISA, ParSeq, MangledName,
11757 OutputBecomesInput, Fn);
11758 break;
11759 case 64:
11760 case 128:
11761 addAArch64VectorName(2, Mask, Prefix, ISA, ParSeq, MangledName,
11762 OutputBecomesInput, Fn);
11763 break;
11764 default:
11765 llvm_unreachable("Scalar type is too wide.")__builtin_unreachable();
11766 }
11767}
11768
11769/// Emit vector function attributes for AArch64, as defined in the AAVFABI.
11770static void emitAArch64DeclareSimdFunction(
11771 CodeGenModule &CGM, const FunctionDecl *FD, unsigned UserVLEN,
11772 ArrayRef<ParamAttrTy> ParamAttrs,
11773 OMPDeclareSimdDeclAttr::BranchStateTy State, StringRef MangledName,
11774 char ISA, unsigned VecRegSize, llvm::Function *Fn, SourceLocation SLoc) {
11775
11776 // Get basic data for building the vector signature.
11777 const auto Data = getNDSWDS(FD, ParamAttrs);
11778 const unsigned NDS = std::get<0>(Data);
11779 const unsigned WDS = std::get<1>(Data);
11780 const bool OutputBecomesInput = std::get<2>(Data);
11781
11782 // Check the values provided via `simdlen` by the user.
11783 // 1. A `simdlen(1)` doesn't produce vector signatures,
11784 if (UserVLEN == 1) {
11785 unsigned DiagID = CGM.getDiags().getCustomDiagID(
11786 DiagnosticsEngine::Warning,
11787 "The clause simdlen(1) has no effect when targeting aarch64.");
11788 CGM.getDiags().Report(SLoc, DiagID);
11789 return;
11790 }
11791
11792 // 2. Section 3.3.1, item 1: user input must be a power of 2 for
11793 // Advanced SIMD output.
11794 if (ISA == 'n' && UserVLEN && !llvm::isPowerOf2_32(UserVLEN)) {
11795 unsigned DiagID = CGM.getDiags().getCustomDiagID(
11796 DiagnosticsEngine::Warning, "The value specified in simdlen must be a "
11797 "power of 2 when targeting Advanced SIMD.");
11798 CGM.getDiags().Report(SLoc, DiagID);
11799 return;
11800 }
11801
11802 // 3. Section 3.4.1. SVE fixed lengh must obey the architectural
11803 // limits.
11804 if (ISA == 's' && UserVLEN != 0) {
11805 if ((UserVLEN * WDS > 2048) || (UserVLEN * WDS % 128 != 0)) {
11806 unsigned DiagID = CGM.getDiags().getCustomDiagID(
11807 DiagnosticsEngine::Warning, "The clause simdlen must fit the %0-bit "
11808 "lanes in the architectural constraints "
11809 "for SVE (min is 128-bit, max is "
11810 "2048-bit, by steps of 128-bit)");
11811 CGM.getDiags().Report(SLoc, DiagID) << WDS;
11812 return;
11813 }
11814 }
11815
11816 // Sort out parameter sequence.
11817 const std::string ParSeq = mangleVectorParameters(ParamAttrs);
11818 StringRef Prefix = "_ZGV";
11819 // Generate simdlen from user input (if any).
11820 if (UserVLEN) {
11821 if (ISA == 's') {
11822 // SVE generates only a masked function.
11823 addAArch64VectorName(UserVLEN, "M", Prefix, ISA, ParSeq, MangledName,
11824 OutputBecomesInput, Fn);
11825 } else {
11826 assert(ISA == 'n' && "Expected ISA either 's' or 'n'.")(static_cast<void> (0));
11827 // Advanced SIMD generates one or two functions, depending on
11828 // the `[not]inbranch` clause.
11829 switch (State) {
11830 case OMPDeclareSimdDeclAttr::BS_Undefined:
11831 addAArch64VectorName(UserVLEN, "N", Prefix, ISA, ParSeq, MangledName,
11832 OutputBecomesInput, Fn);
11833 addAArch64VectorName(UserVLEN, "M", Prefix, ISA, ParSeq, MangledName,
11834 OutputBecomesInput, Fn);
11835 break;
11836 case OMPDeclareSimdDeclAttr::BS_Notinbranch:
11837 addAArch64VectorName(UserVLEN, "N", Prefix, ISA, ParSeq, MangledName,
11838 OutputBecomesInput, Fn);
11839 break;
11840 case OMPDeclareSimdDeclAttr::BS_Inbranch:
11841 addAArch64VectorName(UserVLEN, "M", Prefix, ISA, ParSeq, MangledName,
11842 OutputBecomesInput, Fn);
11843 break;
11844 }
11845 }
11846 } else {
11847 // If no user simdlen is provided, follow the AAVFABI rules for
11848 // generating the vector length.
11849 if (ISA == 's') {
11850 // SVE, section 3.4.1, item 1.
11851 addAArch64VectorName("x", "M", Prefix, ISA, ParSeq, MangledName,
11852 OutputBecomesInput, Fn);
11853 } else {
11854 assert(ISA == 'n' && "Expected ISA either 's' or 'n'.")(static_cast<void> (0));
11855 // Advanced SIMD, Section 3.3.1 of the AAVFABI, generates one or
11856 // two vector names depending on the use of the clause
11857 // `[not]inbranch`.
11858 switch (State) {
11859 case OMPDeclareSimdDeclAttr::BS_Undefined:
11860 addAArch64AdvSIMDNDSNames(NDS, "N", Prefix, ISA, ParSeq, MangledName,
11861 OutputBecomesInput, Fn);
11862 addAArch64AdvSIMDNDSNames(NDS, "M", Prefix, ISA, ParSeq, MangledName,
11863 OutputBecomesInput, Fn);
11864 break;
11865 case OMPDeclareSimdDeclAttr::BS_Notinbranch:
11866 addAArch64AdvSIMDNDSNames(NDS, "N", Prefix, ISA, ParSeq, MangledName,
11867 OutputBecomesInput, Fn);
11868 break;
11869 case OMPDeclareSimdDeclAttr::BS_Inbranch:
11870 addAArch64AdvSIMDNDSNames(NDS, "M", Prefix, ISA, ParSeq, MangledName,
11871 OutputBecomesInput, Fn);
11872 break;
11873 }
11874 }
11875 }
11876}
11877
11878void CGOpenMPRuntime::emitDeclareSimdFunction(const FunctionDecl *FD,
11879 llvm::Function *Fn) {
11880 ASTContext &C = CGM.getContext();
11881 FD = FD->getMostRecentDecl();
11882 // Map params to their positions in function decl.
11883 llvm::DenseMap<const Decl *, unsigned> ParamPositions;
11884 if (isa<CXXMethodDecl>(FD))
1
Assuming 'FD' is not a 'CXXMethodDecl'
2
Taking false branch
11885 ParamPositions.try_emplace(FD, 0);
11886 unsigned ParamPos = ParamPositions.size();
11887 for (const ParmVarDecl *P : FD->parameters()) {
3
Assuming '__begin1' is equal to '__end1'
11888 ParamPositions.try_emplace(P->getCanonicalDecl(), ParamPos);
11889 ++ParamPos;
11890 }
11891 while (FD) {
4
Loop condition is true. Entering loop body
11892 for (const auto *Attr : FD->specific_attrs<OMPDeclareSimdDeclAttr>()) {
11893 llvm::SmallVector<ParamAttrTy, 8> ParamAttrs(ParamPositions.size());
11894 // Mark uniform parameters.
11895 for (const Expr *E : Attr->uniforms()) {
5
Assuming '__begin3' is equal to '__end3'
11896 E = E->IgnoreParenImpCasts();
11897 unsigned Pos;
11898 if (isa<CXXThisExpr>(E)) {
11899 Pos = ParamPositions[FD];
11900 } else {
11901 const auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
11902 ->getCanonicalDecl();
11903 Pos = ParamPositions[PVD];
11904 }
11905 ParamAttrs[Pos].Kind = Uniform;
11906 }
11907 // Get alignment info.
11908 auto NI = Attr->alignments_begin();
11909 for (const Expr *E : Attr->aligneds()) {
6
Assuming '__begin3' is equal to '__end3'
11910 E = E->IgnoreParenImpCasts();
11911 unsigned Pos;
11912 QualType ParmTy;
11913 if (isa<CXXThisExpr>(E)) {
11914 Pos = ParamPositions[FD];
11915 ParmTy = E->getType();
11916 } else {
11917 const auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
11918 ->getCanonicalDecl();
11919 Pos = ParamPositions[PVD];
11920 ParmTy = PVD->getType();
11921 }
11922 ParamAttrs[Pos].Alignment =
11923 (*NI)
11924 ? (*NI)->EvaluateKnownConstInt(C)
11925 : llvm::APSInt::getUnsigned(
11926 C.toCharUnitsFromBits(C.getOpenMPDefaultSimdAlign(ParmTy))
11927 .getQuantity());
11928 ++NI;
11929 }
11930 // Mark linear parameters.
11931 auto SI = Attr->steps_begin();
11932 auto MI = Attr->modifiers_begin();
11933 for (const Expr *E : Attr->linears()) {
7
Assuming '__begin3' is equal to '__end3'
11934 E = E->IgnoreParenImpCasts();
11935 unsigned Pos;
11936 // Rescaling factor needed to compute the linear parameter
11937 // value in the mangled name.
11938 unsigned PtrRescalingFactor = 1;
11939 if (isa<CXXThisExpr>(E)) {
11940 Pos = ParamPositions[FD];
11941 } else {
11942 const auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
11943 ->getCanonicalDecl();
11944 Pos = ParamPositions[PVD];
11945 if (auto *P = dyn_cast<PointerType>(PVD->getType()))
11946 PtrRescalingFactor = CGM.getContext()
11947 .getTypeSizeInChars(P->getPointeeType())
11948 .getQuantity();
11949 }
11950 ParamAttrTy &ParamAttr = ParamAttrs[Pos];
11951 ParamAttr.Kind = Linear;
11952 // Assuming a stride of 1, for `linear` without modifiers.
11953 ParamAttr.StrideOrArg = llvm::APSInt::getUnsigned(1);
11954 if (*SI) {
11955 Expr::EvalResult Result;
11956 if (!(*SI)->EvaluateAsInt(Result, C, Expr::SE_AllowSideEffects)) {
11957 if (const auto *DRE =
11958 cast<DeclRefExpr>((*SI)->IgnoreParenImpCasts())) {
11959 if (const auto *StridePVD = cast<ParmVarDecl>(DRE->getDecl())) {
11960 ParamAttr.Kind = LinearWithVarStride;
11961 ParamAttr.StrideOrArg = llvm::APSInt::getUnsigned(
11962 ParamPositions[StridePVD->getCanonicalDecl()]);
11963 }
11964 }
11965 } else {
11966 ParamAttr.StrideOrArg = Result.Val.getInt();
11967 }
11968 }
11969 // If we are using a linear clause on a pointer, we need to
11970 // rescale the value of linear_step with the byte size of the
11971 // pointee type.
11972 if (Linear == ParamAttr.Kind)
11973 ParamAttr.StrideOrArg = ParamAttr.StrideOrArg * PtrRescalingFactor;
11974 ++SI;
11975 ++MI;
11976 }
11977 llvm::APSInt VLENVal;
11978 SourceLocation ExprLoc;
11979 const Expr *VLENExpr = Attr->getSimdlen();
11980 if (VLENExpr) {
8
Assuming 'VLENExpr' is null
9
Taking false branch
11981 VLENVal = VLENExpr->EvaluateKnownConstInt(C);
11982 ExprLoc = VLENExpr->getExprLoc();
11983 }
11984 OMPDeclareSimdDeclAttr::BranchStateTy State = Attr->getBranchState();
11985 if (CGM.getTriple().isX86()) {
10
Taking true branch
11986 emitX86DeclareSimdFunction(FD, Fn, VLENVal, ParamAttrs, State);
11
Calling 'emitX86DeclareSimdFunction'
11987 } else if (CGM.getTriple().getArch() == llvm::Triple::aarch64) {
11988 unsigned VLEN = VLENVal.getExtValue();
11989 StringRef MangledName = Fn->getName();
11990 if (CGM.getTarget().hasFeature("sve"))
11991 emitAArch64DeclareSimdFunction(CGM, FD, VLEN, ParamAttrs, State,
11992 MangledName, 's', 128, Fn, ExprLoc);
11993 if (CGM.getTarget().hasFeature("neon"))
11994 emitAArch64DeclareSimdFunction(CGM, FD, VLEN, ParamAttrs, State,
11995 MangledName, 'n', 128, Fn, ExprLoc);
11996 }
11997 }
11998 FD = FD->getPreviousDecl();
11999 }
12000}
12001
12002namespace {
12003/// Cleanup action for doacross support.
12004class DoacrossCleanupTy final : public EHScopeStack::Cleanup {
12005public:
12006 static const int DoacrossFinArgs = 2;
12007
12008private:
12009 llvm::FunctionCallee RTLFn;
12010 llvm::Value *Args[DoacrossFinArgs];
12011
12012public:
12013 DoacrossCleanupTy(llvm::FunctionCallee RTLFn,
12014 ArrayRef<llvm::Value *> CallArgs)
12015 : RTLFn(RTLFn) {
12016 assert(CallArgs.size() == DoacrossFinArgs)(static_cast<void> (0));
12017 std::copy(CallArgs.begin(), CallArgs.end(), std::begin(Args));
12018 }
12019 void Emit(CodeGenFunction &CGF, Flags /*flags*/) override {
12020 if (!CGF.HaveInsertPoint())
12021 return;
12022 CGF.EmitRuntimeCall(RTLFn, Args);
12023 }
12024};
12025} // namespace
12026
12027void CGOpenMPRuntime::emitDoacrossInit(CodeGenFunction &CGF,
12028 const OMPLoopDirective &D,
12029 ArrayRef<Expr *> NumIterations) {
12030 if (!CGF.HaveInsertPoint())
12031 return;
12032
12033 ASTContext &C = CGM.getContext();
12034 QualType Int64Ty = C.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/true);
12035 RecordDecl *RD;
12036 if (KmpDimTy.isNull()) {
12037 // Build struct kmp_dim { // loop bounds info casted to kmp_int64
12038 // kmp_int64 lo; // lower
12039 // kmp_int64 up; // upper
12040 // kmp_int64 st; // stride
12041 // };
12042 RD = C.buildImplicitRecord("kmp_dim");
12043 RD->startDefinition();
12044 addFieldToRecordDecl(C, RD, Int64Ty);
12045 addFieldToRecordDecl(C, RD, Int64Ty);
12046 addFieldToRecordDecl(C, RD, Int64Ty);
12047 RD->completeDefinition();
12048 KmpDimTy = C.getRecordType(RD);
12049 } else {
12050 RD = cast<RecordDecl>(KmpDimTy->getAsTagDecl());
12051 }
12052 llvm::APInt Size(/*numBits=*/32, NumIterations.size());
12053 QualType ArrayTy =
12054 C.getConstantArrayType(KmpDimTy, Size, nullptr, ArrayType::Normal, 0);
12055
12056 Address DimsAddr = CGF.CreateMemTemp(ArrayTy, "dims");
12057 CGF.EmitNullInitialization(DimsAddr, ArrayTy);
12058 enum { LowerFD = 0, UpperFD, StrideFD };
12059 // Fill dims with data.
12060 for (unsigned I = 0, E = NumIterations.size(); I < E; ++I) {
12061 LValue DimsLVal = CGF.MakeAddrLValue(
12062 CGF.Builder.CreateConstArrayGEP(DimsAddr, I), KmpDimTy);
12063 // dims.upper = num_iterations;
12064 LValue UpperLVal = CGF.EmitLValueForField(
12065 DimsLVal, *std::next(RD->field_begin(), UpperFD));
12066 llvm::Value *NumIterVal = CGF.EmitScalarConversion(
12067 CGF.EmitScalarExpr(NumIterations[I]), NumIterations[I]->getType(),
12068 Int64Ty, NumIterations[I]->getExprLoc());
12069 CGF.EmitStoreOfScalar(NumIterVal, UpperLVal);
12070 // dims.stride = 1;
12071 LValue StrideLVal = CGF.EmitLValueForField(
12072 DimsLVal, *std::next(RD->field_begin(), StrideFD));
12073 CGF.EmitStoreOfScalar(llvm::ConstantInt::getSigned(CGM.Int64Ty, /*V=*/1),
12074 StrideLVal);
12075 }
12076
12077 // Build call void __kmpc_doacross_init(ident_t *loc, kmp_int32 gtid,
12078 // kmp_int32 num_dims, struct kmp_dim * dims);
12079 llvm::Value *Args[] = {
12080 emitUpdateLocation(CGF, D.getBeginLoc()),
12081 getThreadID(CGF, D.getBeginLoc()),
12082 llvm::ConstantInt::getSigned(CGM.Int32Ty, NumIterations.size()),
12083 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
12084 CGF.Builder.CreateConstArrayGEP(DimsAddr, 0).getPointer(),
12085 CGM.VoidPtrTy)};
12086
12087 llvm::FunctionCallee RTLFn = OMPBuilder.getOrCreateRuntimeFunction(
12088 CGM.getModule(), OMPRTL___kmpc_doacross_init);
12089 CGF.EmitRuntimeCall(RTLFn, Args);
12090 llvm::Value *FiniArgs[DoacrossCleanupTy::DoacrossFinArgs] = {
12091 emitUpdateLocation(CGF, D.getEndLoc()), getThreadID(CGF, D.getEndLoc())};
12092 llvm::FunctionCallee FiniRTLFn = OMPBuilder.getOrCreateRuntimeFunction(
12093 CGM.getModule(), OMPRTL___kmpc_doacross_fini);
12094 CGF.EHStack.pushCleanup<DoacrossCleanupTy>(NormalAndEHCleanup, FiniRTLFn,
12095 llvm::makeArrayRef(FiniArgs));
12096}
12097
12098void CGOpenMPRuntime::emitDoacrossOrdered(CodeGenFunction &CGF,
12099 const OMPDependClause *C) {
12100 QualType Int64Ty =
12101 CGM.getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
12102 llvm::APInt Size(/*numBits=*/32, C->getNumLoops());
12103 QualType ArrayTy = CGM.getContext().getConstantArrayType(
12104 Int64Ty, Size, nullptr, ArrayType::Normal, 0);
12105 Address CntAddr = CGF.CreateMemTemp(ArrayTy, ".cnt.addr");
12106 for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I) {
12107 const Expr *CounterVal = C->getLoopData(I);
12108 assert(CounterVal)(static_cast<void> (0));
12109 llvm::Value *CntVal = CGF.EmitScalarConversion(
12110 CGF.EmitScalarExpr(CounterVal), CounterVal->getType(), Int64Ty,
12111 CounterVal->getExprLoc());
12112 CGF.EmitStoreOfScalar(CntVal, CGF.Builder.CreateConstArrayGEP(CntAddr, I),
12113 /*Volatile=*/false, Int64Ty);
12114 }
12115 llvm::Value *Args[] = {
12116 emitUpdateLocation(CGF, C->getBeginLoc()),
12117 getThreadID(CGF, C->getBeginLoc()),
12118 CGF.Builder.CreateConstArrayGEP(CntAddr, 0).getPointer()};
12119 llvm::FunctionCallee RTLFn;
12120 if (C->getDependencyKind() == OMPC_DEPEND_source) {
12121 RTLFn = OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(),
12122 OMPRTL___kmpc_doacross_post);
12123 } else {
12124 assert(C->getDependencyKind() == OMPC_DEPEND_sink)(static_cast<void> (0));
12125 RTLFn = OMPBuilder.getOrCreateRuntimeFunction(CGM.getModule(),
12126 OMPRTL___kmpc_doacross_wait);
12127 }
12128 CGF.EmitRuntimeCall(RTLFn, Args);
12129}
12130
12131void CGOpenMPRuntime::emitCall(CodeGenFunction &CGF, SourceLocation Loc,
12132 llvm::FunctionCallee Callee,
12133 ArrayRef<llvm::Value *> Args) const {
12134 assert(Loc.isValid() && "Outlined function call location must be valid.")(static_cast<void> (0));
12135 auto DL = ApplyDebugLocation::CreateDefaultArtificial(CGF, Loc);
12136
12137 if (auto *Fn = dyn_cast<llvm::Function>(Callee.getCallee())) {
12138 if (Fn->doesNotThrow()) {
12139 CGF.EmitNounwindRuntimeCall(Fn, Args);
12140 return;
12141 }
12142 }
12143 CGF.EmitRuntimeCall(Callee, Args);
12144}
12145
12146void CGOpenMPRuntime::emitOutlinedFunctionCall(
12147 CodeGenFunction &CGF, SourceLocation Loc, llvm::FunctionCallee OutlinedFn,
12148 ArrayRef<llvm::Value *> Args) const {
12149 emitCall(CGF, Loc, OutlinedFn, Args);
12150}
12151
12152void CGOpenMPRuntime::emitFunctionProlog(CodeGenFunction &CGF, const Decl *D) {
12153 if (const auto *FD = dyn_cast<FunctionDecl>(D))
12154 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD))
12155 HasEmittedDeclareTargetRegion = true;
12156}
12157
12158Address CGOpenMPRuntime::getParameterAddress(CodeGenFunction &CGF,
12159 const VarDecl *NativeParam,
12160 const VarDecl *TargetParam) const {
12161 return CGF.GetAddrOfLocalVar(NativeParam);
12162}
12163
12164Address CGOpenMPRuntime::getAddressOfLocalVariable(CodeGenFunction &CGF,
12165 const VarDecl *VD) {
12166 if (!VD)
12167 return Address::invalid();
12168 Address UntiedAddr = Address::invalid();
12169 Address UntiedRealAddr = Address::invalid();
12170 auto It = FunctionToUntiedTaskStackMap.find(CGF.CurFn);
12171 if (It != FunctionToUntiedTaskStackMap.end()) {
12172 const UntiedLocalVarsAddressesMap &UntiedData =
12173 UntiedLocalVarsStack[It->second];
12174 auto I = UntiedData.find(VD);
12175 if (I != UntiedData.end()) {
12176 UntiedAddr = I->second.first;
12177 UntiedRealAddr = I->second.second;
12178 }
12179 }
12180 const VarDecl *CVD = VD->getCanonicalDecl();
12181 if (CVD->hasAttr<OMPAllocateDeclAttr>()) {
12182 // Use the default allocation.
12183 if (!isAllocatableDecl(VD))
12184 return UntiedAddr;
12185 llvm::Value *Size;
12186 CharUnits Align = CGM.getContext().getDeclAlign(CVD);
12187 if (CVD->getType()->isVariablyModifiedType()) {
12188 Size = CGF.getTypeSize(CVD->getType());
12189 // Align the size: ((size + align - 1) / align) * align
12190 Size = CGF.Builder.CreateNUWAdd(
12191 Size, CGM.getSize(Align - CharUnits::fromQuantity(1)));
12192 Size = CGF.Builder.CreateUDiv(Size, CGM.getSize(Align));
12193 Size = CGF.Builder.CreateNUWMul(Size, CGM.getSize(Align));
12194 } else {
12195 CharUnits Sz = CGM.getContext().getTypeSizeInChars(CVD->getType());
12196 Size = CGM.getSize(Sz.alignTo(Align));
12197 }
12198 llvm::Value *ThreadID = getThreadID(CGF, CVD->getBeginLoc());
12199 const auto *AA = CVD->getAttr<OMPAllocateDeclAttr>();
12200 assert(AA->getAllocator() &&(static_cast<void> (0))
12201 "Expected allocator expression for non-default allocator.")(static_cast<void> (0));
12202 llvm::Value *Allocator = CGF.EmitScalarExpr(AA->getAllocator());
12203 // According to the standard, the original allocator type is a enum
12204 // (integer). Convert to pointer type, if required.
12205 Allocator = CGF.EmitScalarConversion(
12206 Allocator, AA->getAllocator()->getType(), CGF.getContext().VoidPtrTy,
12207 AA->getAllocator()->getExprLoc());
12208 llvm::Value *Args[] = {ThreadID, Size, Allocator};
12209
12210 llvm::Value *Addr =
12211 CGF.EmitRuntimeCall(OMPBuilder.getOrCreateRuntimeFunction(
12212 CGM.getModule(), OMPRTL___kmpc_alloc),
12213 Args, getName({CVD->getName(), ".void.addr"}));
12214 llvm::FunctionCallee FiniRTLFn = OMPBuilder.getOrCreateRuntimeFunction(
12215 CGM.getModule(), OMPRTL___kmpc_free);
12216 QualType Ty = CGM.getContext().getPointerType(CVD->getType());
12217 Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
12218 Addr, CGF.ConvertTypeForMem(Ty), getName({CVD->getName(), ".addr"}));
12219 if (UntiedAddr.isValid())
12220 CGF.EmitStoreOfScalar(Addr, UntiedAddr, /*Volatile=*/false, Ty);
12221
12222 // Cleanup action for allocate support.
12223 class OMPAllocateCleanupTy final : public EHScopeStack::Cleanup {
12224 llvm::FunctionCallee RTLFn;
12225 SourceLocation::UIntTy LocEncoding;
12226 Address Addr;
12227 const Expr *Allocator;
12228
12229 public:
12230 OMPAllocateCleanupTy(llvm::FunctionCallee RTLFn,
12231 SourceLocation::UIntTy LocEncoding, Address Addr,
12232 const Expr *Allocator)
12233 : RTLFn(RTLFn), LocEncoding(LocEncoding), Addr(Addr),
12234 Allocator(Allocator) {}
12235 void Emit(CodeGenFunction &CGF, Flags /*flags*/) override {
12236 if (!CGF.HaveInsertPoint())
12237 return;
12238 llvm::Value *Args[3];
12239 Args[0] = CGF.CGM.getOpenMPRuntime().getThreadID(
12240 CGF, SourceLocation::getFromRawEncoding(LocEncoding));
12241 Args[1] = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
12242 Addr.getPointer(), CGF.VoidPtrTy);
12243 llvm::Value *AllocVal = CGF.EmitScalarExpr(Allocator);
12244 // According to the standard, the original allocator type is a enum
12245 // (integer). Convert to pointer type, if required.
12246 AllocVal = CGF.EmitScalarConversion(AllocVal, Allocator->getType(),
12247 CGF.getContext().VoidPtrTy,
12248 Allocator->getExprLoc());
12249 Args[2] = AllocVal;
12250
12251 CGF.EmitRuntimeCall(RTLFn, Args);
12252 }
12253 };
12254 Address VDAddr =
12255 UntiedRealAddr.isValid() ? UntiedRealAddr : Address(Addr, Align);
12256 CGF.EHStack.pushCleanup<OMPAllocateCleanupTy>(
12257 NormalAndEHCleanup, FiniRTLFn, CVD->getLocation().getRawEncoding(),
12258 VDAddr, AA->getAllocator());
12259 if (UntiedRealAddr.isValid())
12260 if (auto *Region =
12261 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
12262 Region->emitUntiedSwitch(CGF);
12263 return VDAddr;
12264 }
12265 return UntiedAddr;
12266}
12267
12268bool CGOpenMPRuntime::isLocalVarInUntiedTask(CodeGenFunction &CGF,
12269 const VarDecl *VD) const {
12270 auto It = FunctionToUntiedTaskStackMap.find(CGF.CurFn);
12271 if (It == FunctionToUntiedTaskStackMap.end())
12272 return false;
12273 return UntiedLocalVarsStack[It->second].count(VD) > 0;
12274}
12275
12276CGOpenMPRuntime::NontemporalDeclsRAII::NontemporalDeclsRAII(
12277 CodeGenModule &CGM, const OMPLoopDirective &S)
12278 : CGM(CGM), NeedToPush(S.hasClausesOfKind<OMPNontemporalClause>()) {
12279 assert(CGM.getLangOpts().OpenMP && "Not in OpenMP mode.")(static_cast<void> (0));
12280 if (!NeedToPush)
12281 return;
12282 NontemporalDeclsSet &DS =
12283 CGM.getOpenMPRuntime().NontemporalDeclsStack.emplace_back();
12284 for (const auto *C : S.getClausesOfKind<OMPNontemporalClause>()) {
12285 for (const Stmt *Ref : C->private_refs()) {
12286 const auto *SimpleRefExpr = cast<Expr>(Ref)->IgnoreParenImpCasts();
12287 const ValueDecl *VD;
12288 if (const auto *DRE = dyn_cast<DeclRefExpr>(SimpleRefExpr)) {
12289 VD = DRE->getDecl();
12290 } else {
12291 const auto *ME = cast<MemberExpr>(SimpleRefExpr);
12292 assert((ME->isImplicitCXXThis() ||(static_cast<void> (0))
12293 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) &&(static_cast<void> (0))
12294 "Expected member of current class.")(static_cast<void> (0));
12295 VD = ME->getMemberDecl();
12296 }
12297 DS.insert(VD);
12298 }
12299 }
12300}
12301
12302CGOpenMPRuntime::NontemporalDeclsRAII::~NontemporalDeclsRAII() {
12303 if (!NeedToPush)
12304 return;
12305 CGM.getOpenMPRuntime().NontemporalDeclsStack.pop_back();
12306}
12307
12308CGOpenMPRuntime::UntiedTaskLocalDeclsRAII::UntiedTaskLocalDeclsRAII(
12309 CodeGenFunction &CGF,
12310 const llvm::MapVector<CanonicalDeclPtr<const VarDecl>,
12311 std::pair<Address, Address>> &LocalVars)
12312 : CGM(CGF.CGM), NeedToPush(!LocalVars.empty()) {
12313 if (!NeedToPush)
12314 return;
12315 CGM.getOpenMPRuntime().FunctionToUntiedTaskStackMap.try_emplace(
12316 CGF.CurFn, CGM.getOpenMPRuntime().UntiedLocalVarsStack.size());
12317 CGM.getOpenMPRuntime().UntiedLocalVarsStack.push_back(LocalVars);
12318}
12319
12320CGOpenMPRuntime::UntiedTaskLocalDeclsRAII::~UntiedTaskLocalDeclsRAII() {
12321 if (!NeedToPush)
12322 return;
12323 CGM.getOpenMPRuntime().UntiedLocalVarsStack.pop_back();
12324}
12325
12326bool CGOpenMPRuntime::isNontemporalDecl(const ValueDecl *VD) const {
12327 assert(CGM.getLangOpts().OpenMP && "Not in OpenMP mode.")(static_cast<void> (0));
12328
12329 return llvm::any_of(
12330 CGM.getOpenMPRuntime().NontemporalDeclsStack,
12331 [VD](const NontemporalDeclsSet &Set) { return Set.count(VD) > 0; });
12332}
12333
12334void CGOpenMPRuntime::LastprivateConditionalRAII::tryToDisableInnerAnalysis(
12335 const OMPExecutableDirective &S,
12336 llvm::DenseSet<CanonicalDeclPtr<const Decl>> &NeedToAddForLPCsAsDisabled)
12337 const {
12338 llvm::DenseSet<CanonicalDeclPtr<const Decl>> NeedToCheckForLPCs;
12339 // Vars in target/task regions must be excluded completely.
12340 if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()) ||
12341 isOpenMPTaskingDirective(S.getDirectiveKind())) {
12342 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
12343 getOpenMPCaptureRegions(CaptureRegions, S.getDirectiveKind());
12344 const CapturedStmt *CS = S.getCapturedStmt(CaptureRegions.front());
12345 for (const CapturedStmt::Capture &Cap : CS->captures()) {
12346 if (Cap.capturesVariable() || Cap.capturesVariableByCopy())
12347 NeedToCheckForLPCs.insert(Cap.getCapturedVar());
12348 }
12349 }
12350 // Exclude vars in private clauses.
12351 for (const auto *C : S.getClausesOfKind<OMPPrivateClause>()) {
12352 for (const Expr *Ref : C->varlists()) {
12353 if (!Ref->getType()->isScalarType())
12354 continue;
12355 const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
12356 if (!DRE)
12357 continue;
12358 NeedToCheckForLPCs.insert(DRE->getDecl());
12359 }
12360 }
12361 for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) {
12362 for (const Expr *Ref : C->varlists()) {
12363 if (!Ref->getType()->isScalarType())
12364 continue;
12365 const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
12366 if (!DRE)
12367 continue;
12368 NeedToCheckForLPCs.insert(DRE->getDecl());
12369 }
12370 }
12371 for (const auto *C : S.getClausesOfKind<OMPLastprivateClause>()) {
12372 for (const Expr *Ref : C->varlists()) {
12373 if (!Ref->getType()->isScalarType())
12374 continue;
12375 const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
12376 if (!DRE)
12377 continue;
12378 NeedToCheckForLPCs.insert(DRE->getDecl());
12379 }
12380 }
12381 for (const auto *C : S.getClausesOfKind<OMPReductionClause>()) {
12382 for (const Expr *Ref : C->varlists()) {
12383 if (!Ref->getType()->isScalarType())
12384 continue;
12385 const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
12386 if (!DRE)
12387 continue;
12388 NeedToCheckForLPCs.insert(DRE->getDecl());
12389 }
12390 }
12391 for (const auto *C : S.getClausesOfKind<OMPLinearClause>()) {
12392 for (const Expr *Ref : C->varlists()) {
12393 if (!Ref->getType()->isScalarType())
12394 continue;
12395 const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
12396 if (!DRE)
12397 continue;
12398 NeedToCheckForLPCs.insert(DRE->getDecl());
12399 }
12400 }
12401 for (const Decl *VD : NeedToCheckForLPCs) {
12402 for (const LastprivateConditionalData &Data :
12403 llvm::reverse(CGM.getOpenMPRuntime().LastprivateConditionalStack)) {
12404 if (Data.DeclToUniqueName.count(VD) > 0) {
12405 if (!Data.Disabled)
12406 NeedToAddForLPCsAsDisabled.insert(VD);
12407 break;
12408 }
12409 }
12410 }
12411}
12412
12413CGOpenMPRuntime::LastprivateConditionalRAII::LastprivateConditionalRAII(
12414 CodeGenFunction &CGF, const OMPExecutableDirective &S, LValue IVLVal)
12415 : CGM(CGF.CGM),
12416 Action((CGM.getLangOpts().OpenMP >= 50 &&
12417 llvm::any_of(S.getClausesOfKind<OMPLastprivateClause>(),
12418 [](const OMPLastprivateClause *C) {
12419 return C->getKind() ==
12420 OMPC_LASTPRIVATE_conditional;
12421 }))
12422 ? ActionToDo::PushAsLastprivateConditional
12423 : ActionToDo::DoNotPush) {
12424 assert(CGM.getLangOpts().OpenMP && "Not in OpenMP mode.")(static_cast<void> (0));
12425 if (CGM.getLangOpts().OpenMP < 50 || Action == ActionToDo::DoNotPush)
12426 return;
12427 assert(Action == ActionToDo::PushAsLastprivateConditional &&(static_cast<void> (0))
12428 "Expected a push action.")(static_cast<void> (0));
12429 LastprivateConditionalData &Data =
12430 CGM.getOpenMPRuntime().LastprivateConditionalStack.emplace_back();
12431 for (const auto *C : S.getClausesOfKind<OMPLastprivateClause>()) {
12432 if (C->getKind() != OMPC_LASTPRIVATE_conditional)
12433 continue;
12434
12435 for (const Expr *Ref : C->varlists()) {
12436 Data.DeclToUniqueName.insert(std::make_pair(
12437 cast<DeclRefExpr>(Ref->IgnoreParenImpCasts())->getDecl(),
12438 SmallString<16>(generateUniqueName(CGM, "pl_cond", Ref))));
12439 }
12440 }
12441 Data.IVLVal = IVLVal;
12442 Data.Fn = CGF.CurFn;
12443}
12444
12445CGOpenMPRuntime::LastprivateConditionalRAII::LastprivateConditionalRAII(
12446 CodeGenFunction &CGF, const OMPExecutableDirective &S)
12447 : CGM(CGF.CGM), Action(ActionToDo::DoNotPush) {
12448 assert(CGM.getLangOpts().OpenMP && "Not in OpenMP mode.")(static_cast<void> (0));
12449 if (CGM.getLangOpts().OpenMP < 50)
12450 return;
12451 llvm::DenseSet<CanonicalDeclPtr<const Decl>> NeedToAddForLPCsAsDisabled;
12452 tryToDisableInnerAnalysis(S, NeedToAddForLPCsAsDisabled);
12453 if (!NeedToAddForLPCsAsDisabled.empty()) {
12454 Action = ActionToDo::DisableLastprivateConditional;
12455 LastprivateConditionalData &Data =
12456 CGM.getOpenMPRuntime().LastprivateConditionalStack.emplace_back();
12457 for (const Decl *VD : NeedToAddForLPCsAsDisabled)
12458 Data.DeclToUniqueName.insert(std::make_pair(VD, SmallString<16>()));
12459 Data.Fn = CGF.CurFn;
12460 Data.Disabled = true;
12461 }
12462}
12463
12464CGOpenMPRuntime::LastprivateConditionalRAII
12465CGOpenMPRuntime::LastprivateConditionalRAII::disable(
12466 CodeGenFunction &CGF, const OMPExecutableDirective &S) {
12467 return LastprivateConditionalRAII(CGF, S);
12468}
12469
12470CGOpenMPRuntime::LastprivateConditionalRAII::~LastprivateConditionalRAII() {
12471 if (CGM.getLangOpts().OpenMP < 50)
12472 return;
12473 if (Action == ActionToDo::DisableLastprivateConditional) {
12474 assert(CGM.getOpenMPRuntime().LastprivateConditionalStack.back().Disabled &&(static_cast<void> (0))
12475 "Expected list of disabled private vars.")(static_cast<void> (0));
12476 CGM.getOpenMPRuntime().LastprivateConditionalStack.pop_back();
12477 }
12478 if (Action == ActionToDo::PushAsLastprivateConditional) {
12479 assert((static_cast<void> (0))
12480 !CGM.getOpenMPRuntime().LastprivateConditionalStack.back().Disabled &&(static_cast<void> (0))
12481 "Expected list of lastprivate conditional vars.")(static_cast<void> (0));
12482 CGM.getOpenMPRuntime().LastprivateConditionalStack.pop_back();
12483 }
12484}
12485
12486Address CGOpenMPRuntime::emitLastprivateConditionalInit(CodeGenFunction &CGF,
12487 const VarDecl *VD) {
12488 ASTContext &C = CGM.getContext();
12489 auto I = LastprivateConditionalToTypes.find(CGF.CurFn);
12490 if (I == LastprivateConditionalToTypes.end())
12491 I = LastprivateConditionalToTypes.try_emplace(CGF.CurFn).first;
12492 QualType NewType;
12493 const FieldDecl *VDField;
12494 const FieldDecl *FiredField;
12495 LValue BaseLVal;
12496 auto VI = I->getSecond().find(VD);
12497 if (VI == I->getSecond().end()) {
12498 RecordDecl *RD = C.buildImplicitRecord("lasprivate.conditional");
12499 RD->startDefinition();
12500 VDField = addFieldToRecordDecl(C, RD, VD->getType().getNonReferenceType());
12501 FiredField = addFieldToRecordDecl(C, RD, C.CharTy);
12502 RD->completeDefinition();
12503 NewType = C.getRecordType(RD);
12504 Address Addr = CGF.CreateMemTemp(NewType, C.getDeclAlign(VD), VD->getName());
12505 BaseLVal = CGF.MakeAddrLValue(Addr, NewType, AlignmentSource::Decl);
12506 I->getSecond().try_emplace(VD, NewType, VDField, FiredField, BaseLVal);
12507 } else {
12508 NewType = std::get<0>(VI->getSecond());
12509 VDField = std::get<1>(VI->getSecond());
12510 FiredField = std::get<2>(VI->getSecond());
12511 BaseLVal = std::get<3>(VI->getSecond());
12512 }
12513 LValue FiredLVal =
12514 CGF.EmitLValueForField(BaseLVal, FiredField);
12515 CGF.EmitStoreOfScalar(
12516 llvm::ConstantInt::getNullValue(CGF.ConvertTypeForMem(C.CharTy)),
12517 FiredLVal);
12518 return CGF.EmitLValueForField(BaseLVal, VDField).getAddress(CGF);
12519}
12520
12521namespace {
12522/// Checks if the lastprivate conditional variable is referenced in LHS.
12523class LastprivateConditionalRefChecker final
12524 : public ConstStmtVisitor<LastprivateConditionalRefChecker, bool> {
12525 ArrayRef<CGOpenMPRuntime::LastprivateConditionalData> LPM;
12526 const Expr *FoundE = nullptr;
12527 const Decl *FoundD = nullptr;
12528 StringRef UniqueDeclName;
12529 LValue IVLVal;
12530 llvm::Function *FoundFn = nullptr;
12531 SourceLocation Loc;
12532
12533public:
12534 bool VisitDeclRefExpr(const DeclRefExpr *E) {
12535 for (const CGOpenMPRuntime::LastprivateConditionalData &D :
12536 llvm::reverse(LPM)) {
12537 auto It = D.DeclToUniqueName.find(E->getDecl());
12538 if (It == D.DeclToUniqueName.end())
12539 continue;
12540 if (D.Disabled)
12541 return false;
12542 FoundE = E;
12543 FoundD = E->getDecl()->getCanonicalDecl();
12544 UniqueDeclName = It->second;
12545 IVLVal = D.IVLVal;
12546 FoundFn = D.Fn;
12547 break;
12548 }
12549 return FoundE == E;
12550 }
12551 bool VisitMemberExpr(const MemberExpr *E) {
12552 if (!CodeGenFunction::IsWrappedCXXThis(E->getBase()))
12553 return false;
12554 for (const CGOpenMPRuntime::LastprivateConditionalData &D :
12555 llvm::reverse(LPM)) {
12556 auto It = D.DeclToUniqueName.find(E->getMemberDecl());
12557 if (It == D.DeclToUniqueName.end())
12558 continue;
12559 if (D.Disabled)
12560 return false;
12561 FoundE = E;
12562 FoundD = E->getMemberDecl()->getCanonicalDecl();
12563 UniqueDeclName = It->second;
12564 IVLVal = D.IVLVal;
12565 FoundFn = D.Fn;
12566 break;
12567 }
12568 return FoundE == E;
12569 }
12570 bool VisitStmt(const Stmt *S) {
12571 for (const Stmt *Child : S->children()) {
12572 if (!Child)
12573 continue;
12574 if (const auto *E = dyn_cast<Expr>(Child))
12575 if (!E->isGLValue())
12576 continue;
12577 if (Visit(Child))
12578 return true;
12579 }
12580 return false;
12581 }
12582 explicit LastprivateConditionalRefChecker(
12583 ArrayRef<CGOpenMPRuntime::LastprivateConditionalData> LPM)
12584 : LPM(LPM) {}
12585 std::tuple<const Expr *, const Decl *, StringRef, LValue, llvm::Function *>
12586 getFoundData() const {
12587 return std::make_tuple(FoundE, FoundD, UniqueDeclName, IVLVal, FoundFn);
12588 }
12589};
12590} // namespace
12591
12592void CGOpenMPRuntime::emitLastprivateConditionalUpdate(CodeGenFunction &CGF,
12593 LValue IVLVal,
12594 StringRef UniqueDeclName,
12595 LValue LVal,
12596 SourceLocation Loc) {
12597 // Last updated loop counter for the lastprivate conditional var.
12598 // int<xx> last_iv = 0;
12599 llvm::Type *LLIVTy = CGF.ConvertTypeForMem(IVLVal.getType());
12600 llvm::Constant *LastIV =
12601 getOrCreateInternalVariable(LLIVTy, getName({UniqueDeclName, "iv"}));
12602 cast<llvm::GlobalVariable>(LastIV)->setAlignment(
12603 IVLVal.getAlignment().getAsAlign());
12604 LValue LastIVLVal = CGF.MakeNaturalAlignAddrLValue(LastIV, IVLVal.getType());
12605
12606 // Last value of the lastprivate conditional.
12607 // decltype(priv_a) last_a;
12608 llvm::Constant *Last = getOrCreateInternalVariable(
12609 CGF.ConvertTypeForMem(LVal.getType()), UniqueDeclName);
12610 cast<llvm::GlobalVariable>(Last)->setAlignment(
12611 LVal.getAlignment().getAsAlign());
12612 LValue LastLVal =
12613 CGF.MakeAddrLValue(Last, LVal.getType(), LVal.getAlignment());
12614
12615 // Global loop counter. Required to handle inner parallel-for regions.
12616 // iv
12617 llvm::Value *IVVal = CGF.EmitLoadOfScalar(IVLVal, Loc);
12618
12619 // #pragma omp critical(a)
12620 // if (last_iv <= iv) {
12621 // last_iv = iv;
12622 // last_a = priv_a;
12623 // }
12624 auto &&CodeGen = [&LastIVLVal, &IVLVal, IVVal, &LVal, &LastLVal,
12625 Loc](CodeGenFunction &CGF, PrePostActionTy &Action) {
12626 Action.Enter(CGF);
12627 llvm::Value *LastIVVal = CGF.EmitLoadOfScalar(LastIVLVal, Loc);
12628 // (last_iv <= iv) ? Check if the variable is updated and store new
12629 // value in global var.
12630 llvm::Value *CmpRes;
12631 if (IVLVal.getType()->isSignedIntegerType()) {
12632 CmpRes = CGF.Builder.CreateICmpSLE(LastIVVal, IVVal);
12633 } else {
12634 assert(IVLVal.getType()->isUnsignedIntegerType() &&(static_cast<void> (0))
12635 "Loop iteration variable must be integer.")(static_cast<void> (0));
12636 CmpRes = CGF.Builder.CreateICmpULE(LastIVVal, IVVal);
12637 }
12638 llvm::BasicBlock *ThenBB = CGF.createBasicBlock("lp_cond_then");
12639 llvm::BasicBlock *ExitBB = CGF.createBasicBlock("lp_cond_exit");
12640 CGF.Builder.CreateCondBr(CmpRes, ThenBB, ExitBB);
12641 // {
12642 CGF.EmitBlock(ThenBB);
12643
12644 // last_iv = iv;
12645 CGF.EmitStoreOfScalar(IVVal, LastIVLVal);
12646
12647 // last_a = priv_a;
12648 switch (CGF.getEvaluationKind(LVal.getType())) {
12649 case TEK_Scalar: {
12650 llvm::Value *PrivVal = CGF.EmitLoadOfScalar(LVal, Loc);
12651 CGF.EmitStoreOfScalar(PrivVal, LastLVal);
12652 break;
12653 }
12654 case TEK_Complex: {
12655 CodeGenFunction::ComplexPairTy PrivVal = CGF.EmitLoadOfComplex(LVal, Loc);
12656 CGF.EmitStoreOfComplex(PrivVal, LastLVal, /*isInit=*/false);
12657 break;
12658 }
12659 case TEK_Aggregate:
12660 llvm_unreachable(__builtin_unreachable()
12661 "Aggregates are not supported in lastprivate conditional.")__builtin_unreachable();
12662 }
12663 // }
12664 CGF.EmitBranch(ExitBB);
12665 // There is no need to emit line number for unconditional branch.
12666 (void)ApplyDebugLocation::CreateEmpty(CGF);
12667 CGF.EmitBlock(ExitBB, /*IsFinished=*/true);
12668 };
12669
12670 if (CGM.getLangOpts().OpenMPSimd) {
12671 // Do not emit as a critical region as no parallel region could be emitted.
12672 RegionCodeGenTy ThenRCG(CodeGen);
12673 ThenRCG(CGF);
12674 } else {
12675 emitCriticalRegion(CGF, UniqueDeclName, CodeGen, Loc);
12676 }
12677}
12678
12679void CGOpenMPRuntime::checkAndEmitLastprivateConditional(CodeGenFunction &CGF,
12680 const Expr *LHS) {
12681 if (CGF.getLangOpts().OpenMP < 50 || LastprivateConditionalStack.empty())
12682 return;
12683 LastprivateConditionalRefChecker Checker(LastprivateConditionalStack);
12684 if (!Checker.Visit(LHS))
12685 return;
12686 const Expr *FoundE;
12687 const Decl *FoundD;
12688 StringRef UniqueDeclName;
12689 LValue IVLVal;
12690 llvm::Function *FoundFn;
12691 std::tie(FoundE, FoundD, UniqueDeclName, IVLVal, FoundFn) =
12692 Checker.getFoundData();
12693 if (FoundFn != CGF.CurFn) {
12694 // Special codegen for inner parallel regions.
12695 // ((struct.lastprivate.conditional*)&priv_a)->Fired = 1;
12696 auto It = LastprivateConditionalToTypes[FoundFn].find(FoundD);
12697 assert(It != LastprivateConditionalToTypes[FoundFn].end() &&(static_cast<void> (0))
12698 "Lastprivate conditional is not found in outer region.")(static_cast<void> (0));
12699 QualType StructTy = std::get<0>(It->getSecond());
12700 const FieldDecl* FiredDecl = std::get<2>(It->getSecond());
12701 LValue PrivLVal = CGF.EmitLValue(FoundE);
12702 Address StructAddr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
12703 PrivLVal.getAddress(CGF),
12704 CGF.ConvertTypeForMem(CGF.getContext().getPointerType(StructTy)));
12705 LValue BaseLVal =
12706 CGF.MakeAddrLValue(StructAddr, StructTy, AlignmentSource::Decl);
12707 LValue FiredLVal = CGF.EmitLValueForField(BaseLVal, FiredDecl);
12708 CGF.EmitAtomicStore(RValue::get(llvm::ConstantInt::get(
12709 CGF.ConvertTypeForMem(FiredDecl->getType()), 1)),
12710 FiredLVal, llvm::AtomicOrdering::Unordered,
12711 /*IsVolatile=*/true, /*isInit=*/false);
12712 return;
12713 }
12714
12715 // Private address of the lastprivate conditional in the current context.
12716 // priv_a
12717 LValue LVal = CGF.EmitLValue(FoundE);
12718 emitLastprivateConditionalUpdate(CGF, IVLVal, UniqueDeclName, LVal,
12719 FoundE->getExprLoc());
12720}
12721
12722void CGOpenMPRuntime::checkAndEmitSharedLastprivateConditional(
12723 CodeGenFunction &CGF, const OMPExecutableDirective &D,
12724 const llvm::DenseSet<CanonicalDeclPtr<const VarDecl>> &IgnoredDecls) {
12725 if (CGF.getLangOpts().OpenMP < 50 || LastprivateConditionalStack.empty())
12726 return;
12727 auto Range = llvm::reverse(LastprivateConditionalStack);
12728 auto It = llvm::find_if(
12729 Range, [](const LastprivateConditionalData &D) { return !D.Disabled; });
12730 if (It == Range.end() || It->Fn != CGF.CurFn)
12731 return;
12732 auto LPCI = LastprivateConditionalToTypes.find(It->Fn);
12733 assert(LPCI != LastprivateConditionalToTypes.end() &&(static_cast<void> (0))
12734 "Lastprivates must be registered already.")(static_cast<void> (0));
12735 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
12736 getOpenMPCaptureRegions(CaptureRegions, D.getDirectiveKind());
12737 const CapturedStmt *CS = D.getCapturedStmt(CaptureRegions.back());
12738 for (const auto &Pair : It->DeclToUniqueName) {
12739 const auto *VD = cast<VarDecl>(Pair.first->getCanonicalDecl());
12740 if (!CS->capturesVariable(VD) || IgnoredDecls.count(VD) > 0)
12741 continue;
12742 auto I = LPCI->getSecond().find(Pair.first);
12743 assert(I != LPCI->getSecond().end() &&(static_cast<void> (0))
12744 "Lastprivate must be rehistered already.")(static_cast<void> (0));
12745 // bool Cmp = priv_a.Fired != 0;
12746 LValue BaseLVal = std::get<3>(I->getSecond());
12747 LValue FiredLVal =
12748 CGF.EmitLValueForField(BaseLVal, std::get<2>(I->getSecond()));
12749 llvm::Value *Res = CGF.EmitLoadOfScalar(FiredLVal, D.getBeginLoc());
12750 llvm::Value *Cmp = CGF.Builder.CreateIsNotNull(Res);
12751 llvm::BasicBlock *ThenBB = CGF.createBasicBlock("lpc.then");
12752 llvm::BasicBlock *DoneBB = CGF.createBasicBlock("lpc.done");
12753 // if (Cmp) {
12754 CGF.Builder.CreateCondBr(Cmp, ThenBB, DoneBB);
12755 CGF.EmitBlock(ThenBB);
12756 Address Addr = CGF.GetAddrOfLocalVar(VD);
12757 LValue LVal;
12758 if (VD->getType()->isReferenceType())
12759 LVal = CGF.EmitLoadOfReferenceLValue(Addr, VD->getType(),
12760 AlignmentSource::Decl);
12761 else
12762 LVal = CGF.MakeAddrLValue(Addr, VD->getType().getNonReferenceType(),
12763 AlignmentSource::Decl);
12764 emitLastprivateConditionalUpdate(CGF, It->IVLVal, Pair.second, LVal,
12765 D.getBeginLoc());
12766 auto AL = ApplyDebugLocation::CreateArtificial(CGF);
12767 CGF.EmitBlock(DoneBB, /*IsFinal=*/true);
12768 // }
12769 }
12770}
12771
12772void CGOpenMPRuntime::emitLastprivateConditionalFinalUpdate(
12773 CodeGenFunction &CGF, LValue PrivLVal, const VarDecl *VD,
12774 SourceLocation Loc) {
12775 if (CGF.getLangOpts().OpenMP < 50)
12776 return;
12777 auto It = LastprivateConditionalStack.back().DeclToUniqueName.find(VD);
12778 assert(It != LastprivateConditionalStack.back().DeclToUniqueName.end() &&(static_cast<void> (0))
12779 "Unknown lastprivate conditional variable.")(static_cast<void> (0));
12780 StringRef UniqueName = It->second;
12781 llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(UniqueName);
12782 // The variable was not updated in the region - exit.
12783 if (!GV)
12784 return;
12785 LValue LPLVal = CGF.MakeAddrLValue(
12786 GV, PrivLVal.getType().getNonReferenceType(), PrivLVal.getAlignment());
12787 llvm::Value *Res = CGF.EmitLoadOfScalar(LPLVal, Loc);
12788 CGF.EmitStoreOfScalar(Res, PrivLVal);
12789}
12790
12791llvm::Function *CGOpenMPSIMDRuntime::emitParallelOutlinedFunction(
12792 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
12793 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
12794 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12795}
12796
12797llvm::Function *CGOpenMPSIMDRuntime::emitTeamsOutlinedFunction(
12798 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
12799 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
12800 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12801}
12802
12803llvm::Function *CGOpenMPSIMDRuntime::emitTaskOutlinedFunction(
12804 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
12805 const VarDecl *PartIDVar, const VarDecl *TaskTVar,
12806 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
12807 bool Tied, unsigned &NumberOfParts) {
12808 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12809}
12810
12811void CGOpenMPSIMDRuntime::emitParallelCall(CodeGenFunction &CGF,
12812 SourceLocation Loc,
12813 llvm::Function *OutlinedFn,
12814 ArrayRef<llvm::Value *> CapturedVars,
12815 const Expr *IfCond) {
12816 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12817}
12818
12819void CGOpenMPSIMDRuntime::emitCriticalRegion(
12820 CodeGenFunction &CGF, StringRef CriticalName,
12821 const RegionCodeGenTy &CriticalOpGen, SourceLocation Loc,
12822 const Expr *Hint) {
12823 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12824}
12825
12826void CGOpenMPSIMDRuntime::emitMasterRegion(CodeGenFunction &CGF,
12827 const RegionCodeGenTy &MasterOpGen,
12828 SourceLocation Loc) {
12829 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12830}
12831
12832void CGOpenMPSIMDRuntime::emitMaskedRegion(CodeGenFunction &CGF,
12833 const RegionCodeGenTy &MasterOpGen,
12834 SourceLocation Loc,
12835 const Expr *Filter) {
12836 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12837}
12838
12839void CGOpenMPSIMDRuntime::emitTaskyieldCall(CodeGenFunction &CGF,
12840 SourceLocation Loc) {
12841 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12842}
12843
12844void CGOpenMPSIMDRuntime::emitTaskgroupRegion(
12845 CodeGenFunction &CGF, const RegionCodeGenTy &TaskgroupOpGen,
12846 SourceLocation Loc) {
12847 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12848}
12849
12850void CGOpenMPSIMDRuntime::emitSingleRegion(
12851 CodeGenFunction &CGF, const RegionCodeGenTy &SingleOpGen,
12852 SourceLocation Loc, ArrayRef<const Expr *> CopyprivateVars,
12853 ArrayRef<const Expr *> DestExprs, ArrayRef<const Expr *> SrcExprs,
12854 ArrayRef<const Expr *> AssignmentOps) {
12855 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12856}
12857
12858void CGOpenMPSIMDRuntime::emitOrderedRegion(CodeGenFunction &CGF,
12859 const RegionCodeGenTy &OrderedOpGen,
12860 SourceLocation Loc,
12861 bool IsThreads) {
12862 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12863}
12864
12865void CGOpenMPSIMDRuntime::emitBarrierCall(CodeGenFunction &CGF,
12866 SourceLocation Loc,
12867 OpenMPDirectiveKind Kind,
12868 bool EmitChecks,
12869 bool ForceSimpleCall) {
12870 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12871}
12872
12873void CGOpenMPSIMDRuntime::emitForDispatchInit(
12874 CodeGenFunction &CGF, SourceLocation Loc,
12875 const OpenMPScheduleTy &ScheduleKind, unsigned IVSize, bool IVSigned,
12876 bool Ordered, const DispatchRTInput &DispatchValues) {
12877 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12878}
12879
12880void CGOpenMPSIMDRuntime::emitForStaticInit(
12881 CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind DKind,
12882 const OpenMPScheduleTy &ScheduleKind, const StaticRTInput &Values) {
12883 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12884}
12885
12886void CGOpenMPSIMDRuntime::emitDistributeStaticInit(
12887 CodeGenFunction &CGF, SourceLocation Loc,
12888 OpenMPDistScheduleClauseKind SchedKind, const StaticRTInput &Values) {
12889 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12890}
12891
12892void CGOpenMPSIMDRuntime::emitForOrderedIterationEnd(CodeGenFunction &CGF,
12893 SourceLocation Loc,
12894 unsigned IVSize,
12895 bool IVSigned) {
12896 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12897}
12898
12899void CGOpenMPSIMDRuntime::emitForStaticFinish(CodeGenFunction &CGF,
12900 SourceLocation Loc,
12901 OpenMPDirectiveKind DKind) {
12902 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12903}
12904
12905llvm::Value *CGOpenMPSIMDRuntime::emitForNext(CodeGenFunction &CGF,
12906 SourceLocation Loc,
12907 unsigned IVSize, bool IVSigned,
12908 Address IL, Address LB,
12909 Address UB, Address ST) {
12910 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12911}
12912
12913void CGOpenMPSIMDRuntime::emitNumThreadsClause(CodeGenFunction &CGF,
12914 llvm::Value *NumThreads,
12915 SourceLocation Loc) {
12916 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12917}
12918
12919void CGOpenMPSIMDRuntime::emitProcBindClause(CodeGenFunction &CGF,
12920 ProcBindKind ProcBind,
12921 SourceLocation Loc) {
12922 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12923}
12924
12925Address CGOpenMPSIMDRuntime::getAddrOfThreadPrivate(CodeGenFunction &CGF,
12926 const VarDecl *VD,
12927 Address VDAddr,
12928 SourceLocation Loc) {
12929 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12930}
12931
12932llvm::Function *CGOpenMPSIMDRuntime::emitThreadPrivateVarDefinition(
12933 const VarDecl *VD, Address VDAddr, SourceLocation Loc, bool PerformInit,
12934 CodeGenFunction *CGF) {
12935 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12936}
12937
12938Address CGOpenMPSIMDRuntime::getAddrOfArtificialThreadPrivate(
12939 CodeGenFunction &CGF, QualType VarType, StringRef Name) {
12940 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12941}
12942
12943void CGOpenMPSIMDRuntime::emitFlush(CodeGenFunction &CGF,
12944 ArrayRef<const Expr *> Vars,
12945 SourceLocation Loc,
12946 llvm::AtomicOrdering AO) {
12947 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12948}
12949
12950void CGOpenMPSIMDRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
12951 const OMPExecutableDirective &D,
12952 llvm::Function *TaskFunction,
12953 QualType SharedsTy, Address Shareds,
12954 const Expr *IfCond,
12955 const OMPTaskDataTy &Data) {
12956 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12957}
12958
12959void CGOpenMPSIMDRuntime::emitTaskLoopCall(
12960 CodeGenFunction &CGF, SourceLocation Loc, const OMPLoopDirective &D,
12961 llvm::Function *TaskFunction, QualType SharedsTy, Address Shareds,
12962 const Expr *IfCond, const OMPTaskDataTy &Data) {
12963 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12964}
12965
12966void CGOpenMPSIMDRuntime::emitReduction(
12967 CodeGenFunction &CGF, SourceLocation Loc, ArrayRef<const Expr *> Privates,
12968 ArrayRef<const Expr *> LHSExprs, ArrayRef<const Expr *> RHSExprs,
12969 ArrayRef<const Expr *> ReductionOps, ReductionOptionsTy Options) {
12970 assert(Options.SimpleReduction && "Only simple reduction is expected.")(static_cast<void> (0));
12971 CGOpenMPRuntime::emitReduction(CGF, Loc, Privates, LHSExprs, RHSExprs,
12972 ReductionOps, Options);
12973}
12974
12975llvm::Value *CGOpenMPSIMDRuntime::emitTaskReductionInit(
12976 CodeGenFunction &CGF, SourceLocation Loc, ArrayRef<const Expr *> LHSExprs,
12977 ArrayRef<const Expr *> RHSExprs, const OMPTaskDataTy &Data) {
12978 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12979}
12980
12981void CGOpenMPSIMDRuntime::emitTaskReductionFini(CodeGenFunction &CGF,
12982 SourceLocation Loc,
12983 bool IsWorksharingReduction) {
12984 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12985}
12986
12987void CGOpenMPSIMDRuntime::emitTaskReductionFixups(CodeGenFunction &CGF,
12988 SourceLocation Loc,
12989 ReductionCodeGen &RCG,
12990 unsigned N) {
12991 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12992}
12993
12994Address CGOpenMPSIMDRuntime::getTaskReductionItem(CodeGenFunction &CGF,
12995 SourceLocation Loc,
12996 llvm::Value *ReductionsPtr,
12997 LValue SharedLVal) {
12998 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
12999}
13000
13001void CGOpenMPSIMDRuntime::emitTaskwaitCall(CodeGenFunction &CGF,
13002 SourceLocation Loc) {
13003 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
13004}
13005
13006void CGOpenMPSIMDRuntime::emitCancellationPointCall(
13007 CodeGenFunction &CGF, SourceLocation Loc,
13008 OpenMPDirectiveKind CancelRegion) {
13009 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
13010}
13011
13012void CGOpenMPSIMDRuntime::emitCancelCall(CodeGenFunction &CGF,
13013 SourceLocation Loc, const Expr *IfCond,
13014 OpenMPDirectiveKind CancelRegion) {
13015 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
13016}
13017
13018void CGOpenMPSIMDRuntime::emitTargetOutlinedFunction(
13019 const OMPExecutableDirective &D, StringRef ParentName,
13020 llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
13021 bool IsOffloadEntry, const RegionCodeGenTy &CodeGen) {
13022 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
13023}
13024
13025void CGOpenMPSIMDRuntime::emitTargetCall(
13026 CodeGenFunction &CGF, const OMPExecutableDirective &D,
13027 llvm::Function *OutlinedFn, llvm::Value *OutlinedFnID, const Expr *IfCond,
13028 llvm::PointerIntPair<const Expr *, 2, OpenMPDeviceClauseModifier> Device,
13029 llvm::function_ref<llvm::Value *(CodeGenFunction &CGF,
13030 const OMPLoopDirective &D)>
13031 SizeEmitter) {
13032 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
13033}
13034
13035bool CGOpenMPSIMDRuntime::emitTargetFunctions(GlobalDecl GD) {
13036 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
13037}
13038
13039bool CGOpenMPSIMDRuntime::emitTargetGlobalVariable(GlobalDecl GD) {
13040 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
13041}
13042
13043bool CGOpenMPSIMDRuntime::emitTargetGlobal(GlobalDecl GD) {
13044 return false;
13045}
13046
13047void CGOpenMPSIMDRuntime::emitTeamsCall(CodeGenFunction &CGF,
13048 const OMPExecutableDirective &D,
13049 SourceLocation Loc,
13050 llvm::Function *OutlinedFn,
13051 ArrayRef<llvm::Value *> CapturedVars) {
13052 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
13053}
13054
13055void CGOpenMPSIMDRuntime::emitNumTeamsClause(CodeGenFunction &CGF,
13056 const Expr *NumTeams,
13057 const Expr *ThreadLimit,
13058 SourceLocation Loc) {
13059 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
13060}
13061
13062void CGOpenMPSIMDRuntime::emitTargetDataCalls(
13063 CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond,
13064 const Expr *Device, const RegionCodeGenTy &CodeGen, TargetDataInfo &Info) {
13065 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
13066}
13067
13068void CGOpenMPSIMDRuntime::emitTargetDataStandAloneCall(
13069 CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond,
13070 const Expr *Device) {
13071 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
13072}
13073
13074void CGOpenMPSIMDRuntime::emitDoacrossInit(CodeGenFunction &CGF,
13075 const OMPLoopDirective &D,
13076 ArrayRef<Expr *> NumIterations) {
13077 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
13078}
13079
13080void CGOpenMPSIMDRuntime::emitDoacrossOrdered(CodeGenFunction &CGF,
13081 const OMPDependClause *C) {
13082 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
13083}
13084
13085const VarDecl *
13086CGOpenMPSIMDRuntime::translateParameter(const FieldDecl *FD,
13087 const VarDecl *NativeParam) const {
13088 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
13089}
13090
13091Address
13092CGOpenMPSIMDRuntime::getParameterAddress(CodeGenFunction &CGF,
13093 const VarDecl *NativeParam,
13094 const VarDecl *TargetParam) const {
13095 llvm_unreachable("Not supported in SIMD-only mode")__builtin_unreachable();
13096}

/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/include/llvm/ADT/APInt.h

1//===-- llvm/ADT/APInt.h - For Arbitrary Precision Integer -----*- C++ -*--===//
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/// \file
10/// This file implements a class to represent arbitrary precision
11/// integral constant values and operations on them.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_ADT_APINT_H
16#define LLVM_ADT_APINT_H
17
18#include "llvm/Support/Compiler.h"
19#include "llvm/Support/MathExtras.h"
20#include <cassert>
21#include <climits>
22#include <cstring>
23#include <utility>
24
25namespace llvm {
26class FoldingSetNodeID;
27class StringRef;
28class hash_code;
29class raw_ostream;
30
31template <typename T> class SmallVectorImpl;
32template <typename T> class ArrayRef;
33template <typename T> class Optional;
34template <typename T> struct DenseMapInfo;
35
36class APInt;
37
38inline APInt operator-(APInt);
39
40//===----------------------------------------------------------------------===//
41// APInt Class
42//===----------------------------------------------------------------------===//
43
44/// Class for arbitrary precision integers.
45///
46/// APInt is a functional replacement for common case unsigned integer type like
47/// "unsigned", "unsigned long" or "uint64_t", but also allows non-byte-width
48/// integer sizes and large integer value types such as 3-bits, 15-bits, or more
49/// than 64-bits of precision. APInt provides a variety of arithmetic operators
50/// and methods to manipulate integer values of any bit-width. It supports both
51/// the typical integer arithmetic and comparison operations as well as bitwise
52/// manipulation.
53///
54/// The class has several invariants worth noting:
55/// * All bit, byte, and word positions are zero-based.
56/// * Once the bit width is set, it doesn't change except by the Truncate,
57/// SignExtend, or ZeroExtend operations.
58/// * All binary operators must be on APInt instances of the same bit width.
59/// Attempting to use these operators on instances with different bit
60/// widths will yield an assertion.
61/// * The value is stored canonically as an unsigned value. For operations
62/// where it makes a difference, there are both signed and unsigned variants
63/// of the operation. For example, sdiv and udiv. However, because the bit
64/// widths must be the same, operations such as Mul and Add produce the same
65/// results regardless of whether the values are interpreted as signed or
66/// not.
67/// * In general, the class tries to follow the style of computation that LLVM
68/// uses in its IR. This simplifies its use for LLVM.
69///
70class LLVM_NODISCARD[[clang::warn_unused_result]] APInt {
71public:
72 typedef uint64_t WordType;
73
74 /// This enum is used to hold the constants we needed for APInt.
75 enum : unsigned {
76 /// Byte size of a word.
77 APINT_WORD_SIZE = sizeof(WordType),
78 /// Bits in a word.
79 APINT_BITS_PER_WORD = APINT_WORD_SIZE * CHAR_BIT8
80 };
81
82 enum class Rounding {
83 DOWN,
84 TOWARD_ZERO,
85 UP,
86 };
87
88 static constexpr WordType WORDTYPE_MAX = ~WordType(0);
89
90private:
91 /// This union is used to store the integer value. When the
92 /// integer bit-width <= 64, it uses VAL, otherwise it uses pVal.
93 union {
94 uint64_t VAL; ///< Used to store the <= 64 bits integer value.
95 uint64_t *pVal; ///< Used to store the >64 bits integer value.
96 } U;
97
98 unsigned BitWidth; ///< The number of bits in this APInt.
99
100 friend struct DenseMapInfo<APInt>;
101
102 friend class APSInt;
103
104 /// Fast internal constructor
105 ///
106 /// This constructor is used only internally for speed of construction of
107 /// temporaries. It is unsafe for general use so it is not public.
108 APInt(uint64_t *val, unsigned bits) : BitWidth(bits) {
109 U.pVal = val;
110 }
111
112 /// Determine which word a bit is in.
113 ///
114 /// \returns the word position for the specified bit position.
115 static unsigned whichWord(unsigned bitPosition) {
116 return bitPosition / APINT_BITS_PER_WORD;
117 }
118
119 /// Determine which bit in a word a bit is in.
120 ///
121 /// \returns the bit position in a word for the specified bit position
122 /// in the APInt.
123 static unsigned whichBit(unsigned bitPosition) {
124 return bitPosition % APINT_BITS_PER_WORD;
125 }
126
127 /// Get a single bit mask.
128 ///
129 /// \returns a uint64_t with only bit at "whichBit(bitPosition)" set
130 /// This method generates and returns a uint64_t (word) mask for a single
131 /// bit at a specific bit position. This is used to mask the bit in the
132 /// corresponding word.
133 static uint64_t maskBit(unsigned bitPosition) {
134 return 1ULL << whichBit(bitPosition);
135 }
136
137 /// Clear unused high order bits
138 ///
139 /// This method is used internally to clear the top "N" bits in the high order
140 /// word that are not used by the APInt. This is needed after the most
141 /// significant word is assigned a value to ensure that those bits are
142 /// zero'd out.
143 APInt &clearUnusedBits() {
144 // Compute how many bits are used in the final word
145 unsigned WordBits = ((BitWidth-1) % APINT_BITS_PER_WORD) + 1;
146
147 // Mask out the high bits.
148 uint64_t mask = WORDTYPE_MAX >> (APINT_BITS_PER_WORD - WordBits);
149 if (isSingleWord())
150 U.VAL &= mask;
151 else
152 U.pVal[getNumWords() - 1] &= mask;
153 return *this;
154 }
155
156 /// Get the word corresponding to a bit position
157 /// \returns the corresponding word for the specified bit position.
158 uint64_t getWord(unsigned bitPosition) const {
159 return isSingleWord() ? U.VAL : U.pVal[whichWord(bitPosition)];
160 }
161
162 /// Utility method to change the bit width of this APInt to new bit width,
163 /// allocating and/or deallocating as necessary. There is no guarantee on the
164 /// value of any bits upon return. Caller should populate the bits after.
165 void reallocate(unsigned NewBitWidth);
166
167 /// Convert a char array into an APInt
168 ///
169 /// \param radix 2, 8, 10, 16, or 36
170 /// Converts a string into a number. The string must be non-empty
171 /// and well-formed as a number of the given base. The bit-width
172 /// must be sufficient to hold the result.
173 ///
174 /// This is used by the constructors that take string arguments.
175 ///
176 /// StringRef::getAsInteger is superficially similar but (1) does
177 /// not assume that the string is well-formed and (2) grows the
178 /// result to hold the input.
179 void fromString(unsigned numBits, StringRef str, uint8_t radix);
180
181 /// An internal division function for dividing APInts.
182 ///
183 /// This is used by the toString method to divide by the radix. It simply
184 /// provides a more convenient form of divide for internal use since KnuthDiv
185 /// has specific constraints on its inputs. If those constraints are not met
186 /// then it provides a simpler form of divide.
187 static void divide(const WordType *LHS, unsigned lhsWords,
188 const WordType *RHS, unsigned rhsWords, WordType *Quotient,
189 WordType *Remainder);
190
191 /// out-of-line slow case for inline constructor
192 void initSlowCase(uint64_t val, bool isSigned);
193
194 /// shared code between two array constructors
195 void initFromArray(ArrayRef<uint64_t> array);
196
197 /// out-of-line slow case for inline copy constructor
198 void initSlowCase(const APInt &that);
199
200 /// out-of-line slow case for shl
201 void shlSlowCase(unsigned ShiftAmt);
202
203 /// out-of-line slow case for lshr.
204 void lshrSlowCase(unsigned ShiftAmt);
205
206 /// out-of-line slow case for ashr.
207 void ashrSlowCase(unsigned ShiftAmt);
208
209 /// out-of-line slow case for operator=
210 void AssignSlowCase(const APInt &RHS);
211
212 /// out-of-line slow case for operator==
213 bool EqualSlowCase(const APInt &RHS) const LLVM_READONLY__attribute__((__pure__));
214
215 /// out-of-line slow case for countLeadingZeros
216 unsigned countLeadingZerosSlowCase() const LLVM_READONLY__attribute__((__pure__));
217
218 /// out-of-line slow case for countLeadingOnes.
219 unsigned countLeadingOnesSlowCase() const LLVM_READONLY__attribute__((__pure__));
220
221 /// out-of-line slow case for countTrailingZeros.
222 unsigned countTrailingZerosSlowCase() const LLVM_READONLY__attribute__((__pure__));
223
224 /// out-of-line slow case for countTrailingOnes
225 unsigned countTrailingOnesSlowCase() const LLVM_READONLY__attribute__((__pure__));
226
227 /// out-of-line slow case for countPopulation
228 unsigned countPopulationSlowCase() const LLVM_READONLY__attribute__((__pure__));
229
230 /// out-of-line slow case for intersects.
231 bool intersectsSlowCase(const APInt &RHS) const LLVM_READONLY__attribute__((__pure__));
232
233 /// out-of-line slow case for isSubsetOf.
234 bool isSubsetOfSlowCase(const APInt &RHS) const LLVM_READONLY__attribute__((__pure__));
235
236 /// out-of-line slow case for setBits.
237 void setBitsSlowCase(unsigned loBit, unsigned hiBit);
238
239 /// out-of-line slow case for flipAllBits.
240 void flipAllBitsSlowCase();
241
242 /// out-of-line slow case for operator&=.
243 void AndAssignSlowCase(const APInt& RHS);
244
245 /// out-of-line slow case for operator|=.
246 void OrAssignSlowCase(const APInt& RHS);
247
248 /// out-of-line slow case for operator^=.
249 void XorAssignSlowCase(const APInt& RHS);
250
251 /// Unsigned comparison. Returns -1, 0, or 1 if this APInt is less than, equal
252 /// to, or greater than RHS.
253 int compare(const APInt &RHS) const LLVM_READONLY__attribute__((__pure__));
254
255 /// Signed comparison. Returns -1, 0, or 1 if this APInt is less than, equal
256 /// to, or greater than RHS.
257 int compareSigned(const APInt &RHS) const LLVM_READONLY__attribute__((__pure__));
258
259public:
260 /// \name Constructors
261 /// @{
262
263 /// Create a new APInt of numBits width, initialized as val.
264 ///
265 /// If isSigned is true then val is treated as if it were a signed value
266 /// (i.e. as an int64_t) and the appropriate sign extension to the bit width
267 /// will be done. Otherwise, no sign extension occurs (high order bits beyond
268 /// the range of val are zero filled).
269 ///
270 /// \param numBits the bit width of the constructed APInt
271 /// \param val the initial value of the APInt
272 /// \param isSigned how to treat signedness of val
273 APInt(unsigned numBits, uint64_t val, bool isSigned = false)
274 : BitWidth(numBits) {
275 assert(BitWidth && "bitwidth too small")(static_cast<void> (0));
276 if (isSingleWord()) {
277 U.VAL = val;
278 clearUnusedBits();
279 } else {
280 initSlowCase(val, isSigned);
281 }
282 }
283
284 /// Construct an APInt of numBits width, initialized as bigVal[].
285 ///
286 /// Note that bigVal.size() can be smaller or larger than the corresponding
287 /// bit width but any extraneous bits will be dropped.
288 ///
289 /// \param numBits the bit width of the constructed APInt
290 /// \param bigVal a sequence of words to form the initial value of the APInt
291 APInt(unsigned numBits, ArrayRef<uint64_t> bigVal);
292
293 /// Equivalent to APInt(numBits, ArrayRef<uint64_t>(bigVal, numWords)), but
294 /// deprecated because this constructor is prone to ambiguity with the
295 /// APInt(unsigned, uint64_t, bool) constructor.
296 ///
297 /// If this overload is ever deleted, care should be taken to prevent calls
298 /// from being incorrectly captured by the APInt(unsigned, uint64_t, bool)
299 /// constructor.
300 APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]);
301
302 /// Construct an APInt from a string representation.
303 ///
304 /// This constructor interprets the string \p str in the given radix. The
305 /// interpretation stops when the first character that is not suitable for the
306 /// radix is encountered, or the end of the string. Acceptable radix values
307 /// are 2, 8, 10, 16, and 36. It is an error for the value implied by the
308 /// string to require more bits than numBits.
309 ///
310 /// \param numBits the bit width of the constructed APInt
311 /// \param str the string to be interpreted
312 /// \param radix the radix to use for the conversion
313 APInt(unsigned numBits, StringRef str, uint8_t radix);
314
315 /// Simply makes *this a copy of that.
316 /// Copy Constructor.
317 APInt(const APInt &that) : BitWidth(that.BitWidth) {
318 if (isSingleWord())
319 U.VAL = that.U.VAL;
320 else
321 initSlowCase(that);
322 }
323
324 /// Move Constructor.
325 APInt(APInt &&that) : BitWidth(that.BitWidth) {
326 memcpy(&U, &that.U, sizeof(U));
327 that.BitWidth = 0;
328 }
329
330 /// Destructor.
331 ~APInt() {
332 if (needsCleanup())
333 delete[] U.pVal;
334 }
335
336 /// Default constructor that creates an uninteresting APInt
337 /// representing a 1-bit zero value.
338 ///
339 /// This is useful for object deserialization (pair this with the static
340 /// method Read).
341 explicit APInt() : BitWidth(1) { U.VAL = 0; }
342
343 /// Returns whether this instance allocated memory.
344 bool needsCleanup() const { return !isSingleWord(); }
345
346 /// Used to insert APInt objects, or objects that contain APInt objects, into
347 /// FoldingSets.
348 void Profile(FoldingSetNodeID &id) const;
349
350 /// @}
351 /// \name Value Tests
352 /// @{
353
354 /// Determine if this APInt just has one word to store value.
355 ///
356 /// \returns true if the number of bits <= 64, false otherwise.
357 bool isSingleWord() const { return BitWidth <= APINT_BITS_PER_WORD; }
358
359 /// Determine sign of this APInt.
360 ///
361 /// This tests the high bit of this APInt to determine if it is set.
362 ///
363 /// \returns true if this APInt is negative, false otherwise
364 bool isNegative() const { return (*this)[BitWidth - 1]; }
365
366 /// Determine if this APInt Value is non-negative (>= 0)
367 ///
368 /// This tests the high bit of the APInt to determine if it is unset.
369 bool isNonNegative() const { return !isNegative(); }
370
371 /// Determine if sign bit of this APInt is set.
372 ///
373 /// This tests the high bit of this APInt to determine if it is set.
374 ///
375 /// \returns true if this APInt has its sign bit set, false otherwise.
376 bool isSignBitSet() const { return (*this)[BitWidth-1]; }
377
378 /// Determine if sign bit of this APInt is clear.
379 ///
380 /// This tests the high bit of this APInt to determine if it is clear.
381 ///
382 /// \returns true if this APInt has its sign bit clear, false otherwise.
383 bool isSignBitClear() const { return !isSignBitSet(); }
384
385 /// Determine if this APInt Value is positive.
386 ///
387 /// This tests if the value of this APInt is positive (> 0). Note
388 /// that 0 is not a positive value.
389 ///
390 /// \returns true if this APInt is positive.
391 bool isStrictlyPositive() const { return isNonNegative() && !isNullValue(); }
392
393 /// Determine if this APInt Value is non-positive (<= 0).
394 ///
395 /// \returns true if this APInt is non-positive.
396 bool isNonPositive() const { return !isStrictlyPositive(); }
397
398 /// Determine if all bits are set
399 ///
400 /// This checks to see if the value has all bits of the APInt are set or not.
401 bool isAllOnesValue() const {
402 if (isSingleWord())
403 return U.VAL == WORDTYPE_MAX >> (APINT_BITS_PER_WORD - BitWidth);
404 return countTrailingOnesSlowCase() == BitWidth;
405 }
406
407 /// Determine if all bits are clear
408 ///
409 /// This checks to see if the value has all bits of the APInt are clear or
410 /// not.
411 bool isNullValue() const { return !*this; }
412
413 /// Determine if this is a value of 1.
414 ///
415 /// This checks to see if the value of this APInt is one.
416 bool isOneValue() const {
417 if (isSingleWord())
418 return U.VAL == 1;
419 return countLeadingZerosSlowCase() == BitWidth - 1;
420 }
421
422 /// Determine if this is the largest unsigned value.
423 ///
424 /// This checks to see if the value of this APInt is the maximum unsigned
425 /// value for the APInt's bit width.
426 bool isMaxValue() const { return isAllOnesValue(); }
427
428 /// Determine if this is the largest signed value.
429 ///
430 /// This checks to see if the value of this APInt is the maximum signed
431 /// value for the APInt's bit width.
432 bool isMaxSignedValue() const {
433 if (isSingleWord())
434 return U.VAL == ((WordType(1) << (BitWidth - 1)) - 1);
435 return !isNegative() && countTrailingOnesSlowCase() == BitWidth - 1;
436 }
437
438 /// Determine if this is the smallest unsigned value.
439 ///
440 /// This checks to see if the value of this APInt is the minimum unsigned
441 /// value for the APInt's bit width.
442 bool isMinValue() const { return isNullValue(); }
443
444 /// Determine if this is the smallest signed value.
445 ///
446 /// This checks to see if the value of this APInt is the minimum signed
447 /// value for the APInt's bit width.
448 bool isMinSignedValue() const {
449 if (isSingleWord())
450 return U.VAL == (WordType(1) << (BitWidth - 1));
451 return isNegative() && countTrailingZerosSlowCase() == BitWidth - 1;
452 }
453
454 /// Check if this APInt has an N-bits unsigned integer value.
455 bool isIntN(unsigned N) const {
456 assert(N && "N == 0 ???")(static_cast<void> (0));
457 return getActiveBits() <= N;
458 }
459
460 /// Check if this APInt has an N-bits signed integer value.
461 bool isSignedIntN(unsigned N) const {
462 assert(N && "N == 0 ???")(static_cast<void> (0));
463 return getMinSignedBits() <= N;
464 }
465
466 /// Check if this APInt's value is a power of two greater than zero.
467 ///
468 /// \returns true if the argument APInt value is a power of two > 0.
469 bool isPowerOf2() const {
470 if (isSingleWord())
471 return isPowerOf2_64(U.VAL);
472 return countPopulationSlowCase() == 1;
473 }
474
475 /// Check if the APInt's value is returned by getSignMask.
476 ///
477 /// \returns true if this is the value returned by getSignMask.
478 bool isSignMask() const { return isMinSignedValue(); }
479
480 /// Convert APInt to a boolean value.
481 ///
482 /// This converts the APInt to a boolean value as a test against zero.
483 bool getBoolValue() const { return !!*this; }
484
485 /// If this value is smaller than the specified limit, return it, otherwise
486 /// return the limit value. This causes the value to saturate to the limit.
487 uint64_t getLimitedValue(uint64_t Limit = UINT64_MAX(18446744073709551615UL)) const {
488 return ugt(Limit) ? Limit : getZExtValue();
489 }
490
491 /// Check if the APInt consists of a repeated bit pattern.
492 ///
493 /// e.g. 0x01010101 satisfies isSplat(8).
494 /// \param SplatSizeInBits The size of the pattern in bits. Must divide bit
495 /// width without remainder.
496 bool isSplat(unsigned SplatSizeInBits) const;
497
498 /// \returns true if this APInt value is a sequence of \param numBits ones
499 /// starting at the least significant bit with the remainder zero.
500 bool isMask(unsigned numBits) const {
501 assert(numBits != 0 && "numBits must be non-zero")(static_cast<void> (0));
502 assert(numBits <= BitWidth && "numBits out of range")(static_cast<void> (0));
503 if (isSingleWord())
504 return U.VAL == (WORDTYPE_MAX >> (APINT_BITS_PER_WORD - numBits));
505 unsigned Ones = countTrailingOnesSlowCase();
506 return (numBits == Ones) &&
507 ((Ones + countLeadingZerosSlowCase()) == BitWidth);
508 }
509
510 /// \returns true if this APInt is a non-empty sequence of ones starting at
511 /// the least significant bit with the remainder zero.
512 /// Ex. isMask(0x0000FFFFU) == true.
513 bool isMask() const {
514 if (isSingleWord())
515 return isMask_64(U.VAL);
516 unsigned Ones = countTrailingOnesSlowCase();
517 return (Ones > 0) && ((Ones + countLeadingZerosSlowCase()) == BitWidth);
518 }
519
520 /// Return true if this APInt value contains a sequence of ones with
521 /// the remainder zero.
522 bool isShiftedMask() const {
523 if (isSingleWord())
524 return isShiftedMask_64(U.VAL);
525 unsigned Ones = countPopulationSlowCase();
526 unsigned LeadZ = countLeadingZerosSlowCase();
527 return (Ones + LeadZ + countTrailingZeros()) == BitWidth;
528 }
529
530 /// @}
531 /// \name Value Generators
532 /// @{
533
534 /// Gets maximum unsigned value of APInt for specific bit width.
535 static APInt getMaxValue(unsigned numBits) {
536 return getAllOnesValue(numBits);
537 }
538
539 /// Gets maximum signed value of APInt for a specific bit width.
540 static APInt getSignedMaxValue(unsigned numBits) {
541 APInt API = getAllOnesValue(numBits);
542 API.clearBit(numBits - 1);
543 return API;
544 }
545
546 /// Gets minimum unsigned value of APInt for a specific bit width.
547 static APInt getMinValue(unsigned numBits) { return APInt(numBits, 0); }
548
549 /// Gets minimum signed value of APInt for a specific bit width.
550 static APInt getSignedMinValue(unsigned numBits) {
551 APInt API(numBits, 0);
552 API.setBit(numBits - 1);
553 return API;
554 }
555
556 /// Get the SignMask for a specific bit width.
557 ///
558 /// This is just a wrapper function of getSignedMinValue(), and it helps code
559 /// readability when we want to get a SignMask.
560 static APInt getSignMask(unsigned BitWidth) {
561 return getSignedMinValue(BitWidth);
562 }
563
564 /// Get the all-ones value.
565 ///
566 /// \returns the all-ones value for an APInt of the specified bit-width.
567 static APInt getAllOnesValue(unsigned numBits) {
568 return APInt(numBits, WORDTYPE_MAX, true);
569 }
570
571 /// Get the '0' value.
572 ///
573 /// \returns the '0' value for an APInt of the specified bit-width.
574 static APInt getNullValue(unsigned numBits) { return APInt(numBits, 0); }
575
576 /// Compute an APInt containing numBits highbits from this APInt.
577 ///
578 /// Get an APInt with the same BitWidth as this APInt, just zero mask
579 /// the low bits and right shift to the least significant bit.
580 ///
581 /// \returns the high "numBits" bits of this APInt.
582 APInt getHiBits(unsigned numBits) const;
583
584 /// Compute an APInt containing numBits lowbits from this APInt.
585 ///
586 /// Get an APInt with the same BitWidth as this APInt, just zero mask
587 /// the high bits.
588 ///
589 /// \returns the low "numBits" bits of this APInt.
590 APInt getLoBits(unsigned numBits) const;
591
592 /// Return an APInt with exactly one bit set in the result.
593 static APInt getOneBitSet(unsigned numBits, unsigned BitNo) {
594 APInt Res(numBits, 0);
595 Res.setBit(BitNo);
596 return Res;
597 }
598
599 /// Get a value with a block of bits set.
600 ///
601 /// Constructs an APInt value that has a contiguous range of bits set. The
602 /// bits from loBit (inclusive) to hiBit (exclusive) will be set. All other
603 /// bits will be zero. For example, with parameters(32, 0, 16) you would get
604 /// 0x0000FFFF. Please call getBitsSetWithWrap if \p loBit may be greater than
605 /// \p hiBit.
606 ///
607 /// \param numBits the intended bit width of the result
608 /// \param loBit the index of the lowest bit set.
609 /// \param hiBit the index of the highest bit set.
610 ///
611 /// \returns An APInt value with the requested bits set.
612 static APInt getBitsSet(unsigned numBits, unsigned loBit, unsigned hiBit) {
613 assert(loBit <= hiBit && "loBit greater than hiBit")(static_cast<void> (0));
614 APInt Res(numBits, 0);
615 Res.setBits(loBit, hiBit);
616 return Res;
617 }
618
619 /// Wrap version of getBitsSet.
620 /// If \p hiBit is bigger than \p loBit, this is same with getBitsSet.
621 /// If \p hiBit is not bigger than \p loBit, the set bits "wrap". For example,
622 /// with parameters (32, 28, 4), you would get 0xF000000F.
623 /// If \p hiBit is equal to \p loBit, you would get a result with all bits
624 /// set.
625 static APInt getBitsSetWithWrap(unsigned numBits, unsigned loBit,
626 unsigned hiBit) {
627 APInt Res(numBits, 0);
628 Res.setBitsWithWrap(loBit, hiBit);
629 return Res;
630 }
631
632 /// Get a value with upper bits starting at loBit set.
633 ///
634 /// Constructs an APInt value that has a contiguous range of bits set. The
635 /// bits from loBit (inclusive) to numBits (exclusive) will be set. All other
636 /// bits will be zero. For example, with parameters(32, 12) you would get
637 /// 0xFFFFF000.
638 ///
639 /// \param numBits the intended bit width of the result
640 /// \param loBit the index of the lowest bit to set.
641 ///
642 /// \returns An APInt value with the requested bits set.
643 static APInt getBitsSetFrom(unsigned numBits, unsigned loBit) {
644 APInt Res(numBits, 0);
645 Res.setBitsFrom(loBit);
646 return Res;
647 }
648
649 /// Get a value with high bits set
650 ///
651 /// Constructs an APInt value that has the top hiBitsSet bits set.
652 ///
653 /// \param numBits the bitwidth of the result
654 /// \param hiBitsSet the number of high-order bits set in the result.
655 static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet) {
656 APInt Res(numBits, 0);
657 Res.setHighBits(hiBitsSet);
658 return Res;
659 }
660
661 /// Get a value with low bits set
662 ///
663 /// Constructs an APInt value that has the bottom loBitsSet bits set.
664 ///
665 /// \param numBits the bitwidth of the result
666 /// \param loBitsSet the number of low-order bits set in the result.
667 static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet) {
668 APInt Res(numBits, 0);
669 Res.setLowBits(loBitsSet);
670 return Res;
671 }
672
673 /// Return a value containing V broadcasted over NewLen bits.
674 static APInt getSplat(unsigned NewLen, const APInt &V);
675
676 /// Determine if two APInts have the same value, after zero-extending
677 /// one of them (if needed!) to ensure that the bit-widths match.
678 static bool isSameValue(const APInt &I1, const APInt &I2) {
679 if (I1.getBitWidth() == I2.getBitWidth())
680 return I1 == I2;
681
682 if (I1.getBitWidth() > I2.getBitWidth())
683 return I1 == I2.zext(I1.getBitWidth());
684
685 return I1.zext(I2.getBitWidth()) == I2;
686 }
687
688 /// Overload to compute a hash_code for an APInt value.
689 friend hash_code hash_value(const APInt &Arg);
690
691 /// This function returns a pointer to the internal storage of the APInt.
692 /// This is useful for writing out the APInt in binary form without any
693 /// conversions.
694 const uint64_t *getRawData() const {
695 if (isSingleWord())
696 return &U.VAL;
697 return &U.pVal[0];
698 }
699
700 /// @}
701 /// \name Unary Operators
702 /// @{
703
704 /// Postfix increment operator.
705 ///
706 /// Increments *this by 1.
707 ///
708 /// \returns a new APInt value representing the original value of *this.
709 APInt operator++(int) {
710 APInt API(*this);
711 ++(*this);
712 return API;
713 }
714
715 /// Prefix increment operator.
716 ///
717 /// \returns *this incremented by one
718 APInt &operator++();
719
720 /// Postfix decrement operator.
721 ///
722 /// Decrements *this by 1.
723 ///
724 /// \returns a new APInt value representing the original value of *this.
725 APInt operator--(int) {
726 APInt API(*this);
727 --(*this);
728 return API;
729 }
730
731 /// Prefix decrement operator.
732 ///
733 /// \returns *this decremented by one.
734 APInt &operator--();
735
736 /// Logical negation operator.
737 ///
738 /// Performs logical negation operation on this APInt.
739 ///
740 /// \returns true if *this is zero, false otherwise.
741 bool operator!() const {
742 if (isSingleWord())
16
Taking true branch
743 return U.VAL == 0;
17
Returning the value 1, which participates in a condition later
744 return countLeadingZerosSlowCase() == BitWidth;
745 }
746
747 /// @}
748 /// \name Assignment Operators
749 /// @{
750
751 /// Copy assignment operator.
752 ///
753 /// \returns *this after assignment of RHS.
754 APInt &operator=(const APInt &RHS) {
755 // If the bitwidths are the same, we can avoid mucking with memory
756 if (isSingleWord() && RHS.isSingleWord()) {
757 U.VAL = RHS.U.VAL;
758 BitWidth = RHS.BitWidth;
759 return clearUnusedBits();
760 }
761
762 AssignSlowCase(RHS);
763 return *this;
764 }
765
766 /// Move assignment operator.
767 APInt &operator=(APInt &&that) {
768#ifdef EXPENSIVE_CHECKS
769 // Some std::shuffle implementations still do self-assignment.
770 if (this == &that)
771 return *this;
772#endif
773 assert(this != &that && "Self-move not supported")(static_cast<void> (0));
774 if (!isSingleWord())
775 delete[] U.pVal;
776
777 // Use memcpy so that type based alias analysis sees both VAL and pVal
778 // as modified.
779 memcpy(&U, &that.U, sizeof(U));
780
781 BitWidth = that.BitWidth;
782 that.BitWidth = 0;
783
784 return *this;
785 }
786
787 /// Assignment operator.
788 ///
789 /// The RHS value is assigned to *this. If the significant bits in RHS exceed
790 /// the bit width, the excess bits are truncated. If the bit width is larger
791 /// than 64, the value is zero filled in the unspecified high order bits.
792 ///
793 /// \returns *this after assignment of RHS value.
794 APInt &operator=(uint64_t RHS) {
795 if (isSingleWord()) {
796 U.VAL = RHS;
797 return clearUnusedBits();
798 }
799 U.pVal[0] = RHS;
800 memset(U.pVal + 1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);
801 return *this;
802 }
803
804 /// Bitwise AND assignment operator.
805 ///
806 /// Performs a bitwise AND operation on this APInt and RHS. The result is
807 /// assigned to *this.
808 ///
809 /// \returns *this after ANDing with RHS.
810 APInt &operator&=(const APInt &RHS) {
811 assert(BitWidth == RHS.BitWidth && "Bit widths must be the same")(static_cast<void> (0));
812 if (isSingleWord())
813 U.VAL &= RHS.U.VAL;
814 else
815 AndAssignSlowCase(RHS);
816 return *this;
817 }
818
819 /// Bitwise AND assignment operator.
820 ///
821 /// Performs a bitwise AND operation on this APInt and RHS. RHS is
822 /// logically zero-extended or truncated to match the bit-width of
823 /// the LHS.
824 APInt &operator&=(uint64_t RHS) {
825 if (isSingleWord()) {
826 U.VAL &= RHS;
827 return *this;
828 }
829 U.pVal[0] &= RHS;
830 memset(U.pVal+1, 0, (getNumWords() - 1) * APINT_WORD_SIZE);
831 return *this;
832 }
833
834 /// Bitwise OR assignment operator.
835 ///
836 /// Performs a bitwise OR operation on this APInt and RHS. The result is
837 /// assigned *this;
838 ///
839 /// \returns *this after ORing with RHS.
840 APInt &operator|=(const APInt &RHS) {
841 assert(BitWidth == RHS.BitWidth && "Bit widths must be the same")(static_cast<void> (0));
842 if (isSingleWord())
843 U.VAL |= RHS.U.VAL;
844 else
845 OrAssignSlowCase(RHS);
846 return *this;
847 }
848
849 /// Bitwise OR assignment operator.
850 ///
851 /// Performs a bitwise OR operation on this APInt and RHS. RHS is
852 /// logically zero-extended or truncated to match the bit-width of
853 /// the LHS.
854 APInt &operator|=(uint64_t RHS) {
855 if (isSingleWord()) {
856 U.VAL |= RHS;
857 return clearUnusedBits();
858 }
859 U.pVal[0] |= RHS;
860 return *this;
861 }
862
863 /// Bitwise XOR assignment operator.
864 ///
865 /// Performs a bitwise XOR operation on this APInt and RHS. The result is
866 /// assigned to *this.
867 ///
868 /// \returns *this after XORing with RHS.
869 APInt &operator^=(const APInt &RHS) {
870 assert(BitWidth == RHS.BitWidth && "Bit widths must be the same")(static_cast<void> (0));
871 if (isSingleWord())
872 U.VAL ^= RHS.U.VAL;
873 else
874 XorAssignSlowCase(RHS);
875 return *this;
876 }
877
878 /// Bitwise XOR assignment operator.
879 ///
880 /// Performs a bitwise XOR operation on this APInt and RHS. RHS is
881 /// logically zero-extended or truncated to match the bit-width of
882 /// the LHS.
883 APInt &operator^=(uint64_t RHS) {
884 if (isSingleWord()) {
885 U.VAL ^= RHS;
886 return clearUnusedBits();
887 }
888 U.pVal[0] ^= RHS;
889 return *this;
890 }
891
892 /// Multiplication assignment operator.
893 ///
894 /// Multiplies this APInt by RHS and assigns the result to *this.
895 ///
896 /// \returns *this
897 APInt &operator*=(const APInt &RHS);
898 APInt &operator*=(uint64_t RHS);
899
900 /// Addition assignment operator.
901 ///
902 /// Adds RHS to *this and assigns the result to *this.
903 ///
904 /// \returns *this
905 APInt &operator+=(const APInt &RHS);
906 APInt &operator+=(uint64_t RHS);
907
908 /// Subtraction assignment operator.
909 ///
910 /// Subtracts RHS from *this and assigns the result to *this.
911 ///
912 /// \returns *this
913 APInt &operator-=(const APInt &RHS);
914 APInt &operator-=(uint64_t RHS);
915
916 /// Left-shift assignment function.
917 ///
918 /// Shifts *this left by shiftAmt and assigns the result to *this.
919 ///
920 /// \returns *this after shifting left by ShiftAmt
921 APInt &operator<<=(unsigned ShiftAmt) {
922 assert(ShiftAmt <= BitWidth && "Invalid shift amount")(static_cast<void> (0));
923 if (isSingleWord()) {
924 if (ShiftAmt == BitWidth)
925 U.VAL = 0;
926 else
927 U.VAL <<= ShiftAmt;
928 return clearUnusedBits();
929 }
930 shlSlowCase(ShiftAmt);
931 return *this;
932 }
933
934 /// Left-shift assignment function.
935 ///
936 /// Shifts *this left by shiftAmt and assigns the result to *this.
937 ///
938 /// \returns *this after shifting left by ShiftAmt
939 APInt &operator<<=(const APInt &ShiftAmt);
940
941 /// @}
942 /// \name Binary Operators
943 /// @{
944
945 /// Multiplication operator.
946 ///
947 /// Multiplies this APInt by RHS and returns the result.
948 APInt operator*(const APInt &RHS) const;
949
950 /// Left logical shift operator.
951 ///
952 /// Shifts this APInt left by \p Bits and returns the result.
953 APInt operator<<(unsigned Bits) const { return shl(Bits); }
954
955 /// Left logical shift operator.
956 ///
957 /// Shifts this APInt left by \p Bits and returns the result.
958 APInt operator<<(const APInt &Bits) const { return shl(Bits); }
959
960 /// Arithmetic right-shift function.
961 ///
962 /// Arithmetic right-shift this APInt by shiftAmt.
963 APInt ashr(unsigned ShiftAmt) const {
964 APInt R(*this);
965 R.ashrInPlace(ShiftAmt);
966 return R;
967 }
968
969 /// Arithmetic right-shift this APInt by ShiftAmt in place.
970 void ashrInPlace(unsigned ShiftAmt) {
971 assert(ShiftAmt <= BitWidth && "Invalid shift amount")(static_cast<void> (0));
972 if (isSingleWord()) {
973 int64_t SExtVAL = SignExtend64(U.VAL, BitWidth);
974 if (ShiftAmt == BitWidth)
975 U.VAL = SExtVAL >> (APINT_BITS_PER_WORD - 1); // Fill with sign bit.
976 else
977 U.VAL = SExtVAL >> ShiftAmt;
978 clearUnusedBits();
979 return;
980 }
981 ashrSlowCase(ShiftAmt);
982 }
983
984 /// Logical right-shift function.
985 ///
986 /// Logical right-shift this APInt by shiftAmt.
987 APInt lshr(unsigned shiftAmt) const {
988 APInt R(*this);
989 R.lshrInPlace(shiftAmt);
990 return R;
991 }
992
993 /// Logical right-shift this APInt by ShiftAmt in place.
994 void lshrInPlace(unsigned ShiftAmt) {
995 assert(ShiftAmt <= BitWidth && "Invalid shift amount")(static_cast<void> (0));
996 if (isSingleWord()) {
997 if (ShiftAmt == BitWidth)
998 U.VAL = 0;
999 else
1000 U.VAL >>= ShiftAmt;
1001 return;
1002 }
1003 lshrSlowCase(ShiftAmt);
1004 }
1005
1006 /// Left-shift function.
1007 ///
1008 /// Left-shift this APInt by shiftAmt.
1009 APInt shl(unsigned shiftAmt) const {
1010 APInt R(*this);
1011 R <<= shiftAmt;
1012 return R;
1013 }
1014
1015 /// Rotate left by rotateAmt.
1016 APInt rotl(unsigned rotateAmt) const;
1017
1018 /// Rotate right by rotateAmt.
1019 APInt rotr(unsigned rotateAmt) const;
1020
1021 /// Arithmetic right-shift function.
1022 ///
1023 /// Arithmetic right-shift this APInt by shiftAmt.
1024 APInt ashr(const APInt &ShiftAmt) const {
1025 APInt R(*this);
1026 R.ashrInPlace(ShiftAmt);
1027 return R;
1028 }
1029
1030 /// Arithmetic right-shift this APInt by shiftAmt in place.
1031 void ashrInPlace(const APInt &shiftAmt);
1032
1033 /// Logical right-shift function.
1034 ///
1035 /// Logical right-shift this APInt by shiftAmt.
1036 APInt lshr(const APInt &ShiftAmt) const {
1037 APInt R(*this);
1038 R.lshrInPlace(ShiftAmt);
1039 return R;
1040 }
1041
1042 /// Logical right-shift this APInt by ShiftAmt in place.
1043 void lshrInPlace(const APInt &ShiftAmt);
1044
1045 /// Left-shift function.
1046 ///
1047 /// Left-shift this APInt by shiftAmt.
1048 APInt shl(const APInt &ShiftAmt) const {
1049 APInt R(*this);
1050 R <<= ShiftAmt;
1051 return R;
1052 }
1053
1054 /// Rotate left by rotateAmt.
1055 APInt rotl(const APInt &rotateAmt) const;
1056
1057 /// Rotate right by rotateAmt.
1058 APInt rotr(const APInt &rotateAmt) const;
1059
1060 /// Unsigned division operation.
1061 ///
1062 /// Perform an unsigned divide operation on this APInt by RHS. Both this and
1063 /// RHS are treated as unsigned quantities for purposes of this division.
1064 ///
1065 /// \returns a new APInt value containing the division result, rounded towards
1066 /// zero.
1067 APInt udiv(const APInt &RHS) const;
1068 APInt udiv(uint64_t RHS) const;
1069
1070 /// Signed division function for APInt.
1071 ///
1072 /// Signed divide this APInt by APInt RHS.
1073 ///
1074 /// The result is rounded towards zero.
1075 APInt sdiv(const APInt &RHS) const;
1076 APInt sdiv(int64_t RHS) const;
1077
1078 /// Unsigned remainder operation.
1079 ///
1080 /// Perform an unsigned remainder operation on this APInt with RHS being the
1081 /// divisor. Both this and RHS are treated as unsigned quantities for purposes
1082 /// of this operation. Note that this is a true remainder operation and not a
1083 /// modulo operation because the sign follows the sign of the dividend which
1084 /// is *this.
1085 ///
1086 /// \returns a new APInt value containing the remainder result
1087 APInt urem(const APInt &RHS) const;
1088 uint64_t urem(uint64_t RHS) const;
1089
1090 /// Function for signed remainder operation.
1091 ///
1092 /// Signed remainder operation on APInt.
1093 APInt srem(const APInt &RHS) const;
1094 int64_t srem(int64_t RHS) const;
1095
1096 /// Dual division/remainder interface.
1097 ///
1098 /// Sometimes it is convenient to divide two APInt values and obtain both the
1099 /// quotient and remainder. This function does both operations in the same
1100 /// computation making it a little more efficient. The pair of input arguments
1101 /// may overlap with the pair of output arguments. It is safe to call
1102 /// udivrem(X, Y, X, Y), for example.
1103 static void udivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient,
1104 APInt &Remainder);
1105 static void udivrem(const APInt &LHS, uint64_t RHS, APInt &Quotient,
1106 uint64_t &Remainder);
1107
1108 static void sdivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient,
1109 APInt &Remainder);
1110 static void sdivrem(const APInt &LHS, int64_t RHS, APInt &Quotient,
1111 int64_t &Remainder);
1112
1113 // Operations that return overflow indicators.
1114 APInt sadd_ov(const APInt &RHS, bool &Overflow) const;
1115 APInt uadd_ov(const APInt &RHS, bool &Overflow) const;
1116 APInt ssub_ov(const APInt &RHS, bool &Overflow) const;
1117 APInt usub_ov(const APInt &RHS, bool &Overflow) const;
1118 APInt sdiv_ov(const APInt &RHS, bool &Overflow) const;
1119 APInt smul_ov(const APInt &RHS, bool &Overflow) const;
1120 APInt umul_ov(const APInt &RHS, bool &Overflow) const;
1121 APInt sshl_ov(const APInt &Amt, bool &Overflow) const;
1122 APInt ushl_ov(const APInt &Amt, bool &Overflow) const;
1123
1124 // Operations that saturate
1125 APInt sadd_sat(const APInt &RHS) const;
1126 APInt uadd_sat(const APInt &RHS) const;
1127 APInt ssub_sat(const APInt &RHS) const;
1128 APInt usub_sat(const APInt &RHS) const;
1129 APInt smul_sat(const APInt &RHS) const;
1130 APInt umul_sat(const APInt &RHS) const;
1131 APInt sshl_sat(const APInt &RHS) const;
1132 APInt ushl_sat(const APInt &RHS) const;
1133
1134 /// Array-indexing support.
1135 ///
1136 /// \returns the bit value at bitPosition
1137 bool operator[](unsigned bitPosition) const {
1138 assert(bitPosition < getBitWidth() && "Bit position out of bounds!")(static_cast<void> (0));
1139 return (maskBit(bitPosition) & getWord(bitPosition)) != 0;
1140 }
1141
1142 /// @}
1143 /// \name Comparison Operators
1144 /// @{
1145
1146 /// Equality operator.
1147 ///
1148 /// Compares this APInt with RHS for the validity of the equality
1149 /// relationship.
1150 bool operator==(const APInt &RHS) const {
1151 assert(BitWidth == RHS.BitWidth && "Comparison requires equal bit widths")(static_cast<void> (0));
1152 if (isSingleWord())
1153 return U.VAL == RHS.U.VAL;
1154 return EqualSlowCase(RHS);
1155 }
1156
1157 /// Equality operator.
1158 ///
1159 /// Compares this APInt with a uint64_t for the validity of the equality
1160 /// relationship.
1161 ///
1162 /// \returns true if *this == Val
1163 bool operator==(uint64_t Val) const {
1164 return (isSingleWord() || getActiveBits() <= 64) && getZExtValue() == Val;
1165 }
1166
1167 /// Equality comparison.
1168 ///
1169 /// Compares this APInt with RHS for the validity of the equality
1170 /// relationship.
1171 ///
1172 /// \returns true if *this == Val
1173 bool eq(const APInt &RHS) const { return (*this) == RHS; }
1174
1175 /// Inequality operator.
1176 ///
1177 /// Compares this APInt with RHS for the validity of the inequality
1178 /// relationship.
1179 ///
1180 /// \returns true if *this != Val
1181 bool operator!=(const APInt &RHS) const { return !((*this) == RHS); }
1182
1183 /// Inequality operator.
1184 ///
1185 /// Compares this APInt with a uint64_t for the validity of the inequality
1186 /// relationship.
1187 ///
1188 /// \returns true if *this != Val
1189 bool operator!=(uint64_t Val) const { return !((*this) == Val); }
1190
1191 /// Inequality comparison
1192 ///
1193 /// Compares this APInt with RHS for the validity of the inequality
1194 /// relationship.
1195 ///
1196 /// \returns true if *this != Val
1197 bool ne(const APInt &RHS) const { return !((*this) == RHS); }
1198
1199 /// Unsigned less than comparison
1200 ///
1201 /// Regards both *this and RHS as unsigned quantities and compares them for
1202 /// the validity of the less-than relationship.
1203 ///
1204 /// \returns true if *this < RHS when both are considered unsigned.
1205 bool ult(const APInt &RHS) const { return compare(RHS) < 0; }
1206
1207 /// Unsigned less than comparison
1208 ///
1209 /// Regards both *this as an unsigned quantity and compares it with RHS for
1210 /// the validity of the less-than relationship.
1211 ///
1212 /// \returns true if *this < RHS when considered unsigned.
1213 bool ult(uint64_t RHS) const {
1214 // Only need to check active bits if not a single word.
1215 return (isSingleWord() || getActiveBits() <= 64) && getZExtValue() < RHS;
1216 }
1217
1218 /// Signed less than comparison
1219 ///
1220 /// Regards both *this and RHS as signed quantities and compares them for
1221 /// validity of the less-than relationship.
1222 ///
1223 /// \returns true if *this < RHS when both are considered signed.
1224 bool slt(const APInt &RHS) const { return compareSigned(RHS) < 0; }
1225
1226 /// Signed less than comparison
1227 ///
1228 /// Regards both *this as a signed quantity and compares it with RHS for
1229 /// the validity of the less-than relationship.
1230 ///
1231 /// \returns true if *this < RHS when considered signed.
1232 bool slt(int64_t RHS) const {
1233 return (!isSingleWord() && getMinSignedBits() > 64) ? isNegative()
1234 : getSExtValue() < RHS;
1235 }
1236
1237 /// Unsigned less or equal comparison
1238 ///
1239 /// Regards both *this and RHS as unsigned quantities and compares them for
1240 /// validity of the less-or-equal relationship.
1241 ///
1242 /// \returns true if *this <= RHS when both are considered unsigned.
1243 bool ule(const APInt &RHS) const { return compare(RHS) <= 0; }
1244
1245 /// Unsigned less or equal comparison
1246 ///
1247 /// Regards both *this as an unsigned quantity and compares it with RHS for
1248 /// the validity of the less-or-equal relationship.
1249 ///
1250 /// \returns true if *this <= RHS when considered unsigned.
1251 bool ule(uint64_t RHS) const { return !ugt(RHS); }
1252
1253 /// Signed less or equal comparison
1254 ///
1255 /// Regards both *this and RHS as signed quantities and compares them for
1256 /// validity of the less-or-equal relationship.
1257 ///
1258 /// \returns true if *this <= RHS when both are considered signed.
1259 bool sle(const APInt &RHS) const { return compareSigned(RHS) <= 0; }
1260
1261 /// Signed less or equal comparison
1262 ///
1263 /// Regards both *this as a signed quantity and compares it with RHS for the
1264 /// validity of the less-or-equal relationship.
1265 ///
1266 /// \returns true if *this <= RHS when considered signed.
1267 bool sle(uint64_t RHS) const { return !sgt(RHS); }
1268
1269 /// Unsigned greater than comparison
1270 ///
1271 /// Regards both *this and RHS as unsigned quantities and compares them for
1272 /// the validity of the greater-than relationship.
1273 ///
1274 /// \returns true if *this > RHS when both are considered unsigned.
1275 bool ugt(const APInt &RHS) const { return !ule(RHS); }
1276
1277 /// Unsigned greater than comparison
1278 ///
1279 /// Regards both *this as an unsigned quantity and compares it with RHS for
1280 /// the validity of the greater-than relationship.
1281 ///
1282 /// \returns true if *this > RHS when considered unsigned.
1283 bool ugt(uint64_t RHS) const {
1284 // Only need to check active bits if not a single word.
1285 return (!isSingleWord() && getActiveBits() > 64) || getZExtValue() > RHS;
1286 }
1287
1288 /// Signed greater than comparison
1289 ///
1290 /// Regards both *this and RHS as signed quantities and compares them for the
1291 /// validity of the greater-than relationship.
1292 ///
1293 /// \returns true if *this > RHS when both are considered signed.
1294 bool sgt(const APInt &RHS) const { return !sle(RHS); }
1295
1296 /// Signed greater than comparison
1297 ///
1298 /// Regards both *this as a signed quantity and compares it with RHS for
1299 /// the validity of the greater-than relationship.
1300 ///
1301 /// \returns true if *this > RHS when considered signed.
1302 bool sgt(int64_t RHS) const {
1303 return (!isSingleWord() && getMinSignedBits() > 64) ? !isNegative()
1304 : getSExtValue() > RHS;
1305 }
1306
1307 /// Unsigned greater or equal comparison
1308 ///
1309 /// Regards both *this and RHS as unsigned quantities and compares them for
1310 /// validity of the greater-or-equal relationship.
1311 ///
1312 /// \returns true if *this >= RHS when both are considered unsigned.
1313 bool uge(const APInt &RHS) const { return !ult(RHS); }
1314
1315 /// Unsigned greater or equal comparison
1316 ///
1317 /// Regards both *this as an unsigned quantity and compares it with RHS for
1318 /// the validity of the greater-or-equal relationship.
1319 ///
1320 /// \returns true if *this >= RHS when considered unsigned.
1321 bool uge(uint64_t RHS) const { return !ult(RHS); }
1322
1323 /// Signed greater or equal comparison
1324 ///
1325 /// Regards both *this and RHS as signed quantities and compares them for
1326 /// validity of the greater-or-equal relationship.
1327 ///
1328 /// \returns true if *this >= RHS when both are considered signed.
1329 bool sge(const APInt &RHS) const { return !slt(RHS); }
1330
1331 /// Signed greater or equal comparison
1332 ///
1333 /// Regards both *this as a signed quantity and compares it with RHS for
1334 /// the validity of the greater-or-equal relationship.
1335 ///
1336 /// \returns true if *this >= RHS when considered signed.
1337 bool sge(int64_t RHS) const { return !slt(RHS); }
1338
1339 /// This operation tests if there are any pairs of corresponding bits
1340 /// between this APInt and RHS that are both set.
1341 bool intersects(const APInt &RHS) const {
1342 assert(BitWidth == RHS.BitWidth && "Bit widths must be the same")(static_cast<void> (0));
1343 if (isSingleWord())
1344 return (U.VAL & RHS.U.VAL) != 0;
1345 return intersectsSlowCase(RHS);
1346 }
1347
1348 /// This operation checks that all bits set in this APInt are also set in RHS.
1349 bool isSubsetOf(const APInt &RHS) const {
1350 assert(BitWidth == RHS.BitWidth && "Bit widths must be the same")(static_cast<void> (0));
1351 if (isSingleWord())
1352 return (U.VAL & ~RHS.U.VAL) == 0;
1353 return isSubsetOfSlowCase(RHS);
1354 }
1355
1356 /// @}
1357 /// \name Resizing Operators
1358 /// @{
1359
1360 /// Truncate to new width.
1361 ///
1362 /// Truncate the APInt to a specified width. It is an error to specify a width
1363 /// that is greater than or equal to the current width.
1364 APInt trunc(unsigned width) const;
1365
1366 /// Truncate to new width with unsigned saturation.
1367 ///
1368 /// If the APInt, treated as unsigned integer, can be losslessly truncated to
1369 /// the new bitwidth, then return truncated APInt. Else, return max value.
1370 APInt truncUSat(unsigned width) const;
1371
1372 /// Truncate to new width with signed saturation.
1373 ///
1374 /// If this APInt, treated as signed integer, can be losslessly truncated to
1375 /// the new bitwidth, then return truncated APInt. Else, return either
1376 /// signed min value if the APInt was negative, or signed max value.
1377 APInt truncSSat(unsigned width) const;
1378
1379 /// Sign extend to a new width.
1380 ///
1381 /// This operation sign extends the APInt to a new width. If the high order
1382 /// bit is set, the fill on the left will be done with 1 bits, otherwise zero.
1383 /// It is an error to specify a width that is less than or equal to the
1384 /// current width.
1385 APInt sext(unsigned width) const;
1386
1387 /// Zero extend to a new width.
1388 ///
1389 /// This operation zero extends the APInt to a new width. The high order bits
1390 /// are filled with 0 bits. It is an error to specify a width that is less
1391 /// than or equal to the current width.
1392 APInt zext(unsigned width) const;
1393
1394 /// Sign extend or truncate to width
1395 ///
1396 /// Make this APInt have the bit width given by \p width. The value is sign
1397 /// extended, truncated, or left alone to make it that width.
1398 APInt sextOrTrunc(unsigned width) const;
1399
1400 /// Zero extend or truncate to width
1401 ///
1402 /// Make this APInt have the bit width given by \p width. The value is zero
1403 /// extended, truncated, or left alone to make it that width.
1404 APInt zextOrTrunc(unsigned width) const;
1405
1406 /// Truncate to width
1407 ///
1408 /// Make this APInt have the bit width given by \p width. The value is
1409 /// truncated or left alone to make it that width.
1410 APInt truncOrSelf(unsigned width) const;
1411
1412 /// Sign extend or truncate to width
1413 ///
1414 /// Make this APInt have the bit width given by \p width. The value is sign
1415 /// extended, or left alone to make it that width.
1416 APInt sextOrSelf(unsigned width) const;
1417
1418 /// Zero extend or truncate to width
1419 ///
1420 /// Make this APInt have the bit width given by \p width. The value is zero
1421 /// extended, or left alone to make it that width.
1422 APInt zextOrSelf(unsigned width) const;
1423
1424 /// @}
1425 /// \name Bit Manipulation Operators
1426 /// @{
1427
1428 /// Set every bit to 1.
1429 void setAllBits() {
1430 if (isSingleWord())
1431 U.VAL = WORDTYPE_MAX;
1432 else
1433 // Set all the bits in all the words.
1434 memset(U.pVal, -1, getNumWords() * APINT_WORD_SIZE);
1435 // Clear the unused ones
1436 clearUnusedBits();
1437 }
1438
1439 /// Set a given bit to 1.
1440 ///
1441 /// Set the given bit to 1 whose position is given as "bitPosition".
1442 void setBit(unsigned BitPosition) {
1443 assert(BitPosition < BitWidth && "BitPosition out of range")(static_cast<void> (0));
1444 WordType Mask = maskBit(BitPosition);
1445 if (isSingleWord())
1446 U.VAL |= Mask;
1447 else
1448 U.pVal[whichWord(BitPosition)] |= Mask;
1449 }
1450
1451 /// Set the sign bit to 1.
1452 void setSignBit() {
1453 setBit(BitWidth - 1);
1454 }
1455
1456 /// Set a given bit to a given value.
1457 void setBitVal(unsigned BitPosition, bool BitValue) {
1458 if (BitValue)
1459 setBit(BitPosition);
1460 else
1461 clearBit(BitPosition);
1462 }
1463
1464 /// Set the bits from loBit (inclusive) to hiBit (exclusive) to 1.
1465 /// This function handles "wrap" case when \p loBit >= \p hiBit, and calls
1466 /// setBits when \p loBit < \p hiBit.
1467 /// For \p loBit == \p hiBit wrap case, set every bit to 1.
1468 void setBitsWithWrap(unsigned loBit, unsigned hiBit) {
1469 assert(hiBit <= BitWidth && "hiBit out of range")(static_cast<void> (0));
1470 assert(loBit <= BitWidth && "loBit out of range")(static_cast<void> (0));
1471 if (loBit < hiBit) {
1472 setBits(loBit, hiBit);
1473 return;
1474 }
1475 setLowBits(hiBit);
1476 setHighBits(BitWidth - loBit);
1477 }
1478
1479 /// Set the bits from loBit (inclusive) to hiBit (exclusive) to 1.
1480 /// This function handles case when \p loBit <= \p hiBit.
1481 void setBits(unsigned loBit, unsigned hiBit) {
1482 assert(hiBit <= BitWidth && "hiBit out of range")(static_cast<void> (0));
1483 assert(loBit <= BitWidth && "loBit out of range")(static_cast<void> (0));
1484 assert(loBit <= hiBit && "loBit greater than hiBit")(static_cast<void> (0));
1485 if (loBit == hiBit)
1486 return;
1487 if (loBit < APINT_BITS_PER_WORD && hiBit <= APINT_BITS_PER_WORD) {
1488 uint64_t mask = WORDTYPE_MAX >> (APINT_BITS_PER_WORD - (hiBit - loBit));
1489 mask <<= loBit;
1490 if (isSingleWord())
1491 U.VAL |= mask;
1492 else
1493 U.pVal[0] |= mask;
1494 } else {
1495 setBitsSlowCase(loBit, hiBit);
1496 }
1497 }
1498
1499 /// Set the top bits starting from loBit.
1500 void setBitsFrom(unsigned loBit) {
1501 return setBits(loBit, BitWidth);
1502 }
1503
1504 /// Set the bottom loBits bits.
1505 void setLowBits(unsigned loBits) {
1506 return setBits(0, loBits);
1507 }
1508
1509 /// Set the top hiBits bits.
1510 void setHighBits(unsigned hiBits) {
1511 return setBits(BitWidth - hiBits, BitWidth);
1512 }
1513
1514 /// Set every bit to 0.
1515 void clearAllBits() {
1516 if (isSingleWord())
1517 U.VAL = 0;
1518 else
1519 memset(U.pVal, 0, getNumWords() * APINT_WORD_SIZE);
1520 }
1521
1522 /// Set a given bit to 0.
1523 ///
1524 /// Set the given bit to 0 whose position is given as "bitPosition".
1525 void clearBit(unsigned BitPosition) {
1526 assert(BitPosition < BitWidth && "BitPosition out of range")(static_cast<void> (0));
1527 WordType Mask = ~maskBit(BitPosition);
1528 if (isSingleWord())
1529 U.VAL &= Mask;
1530 else
1531 U.pVal[whichWord(BitPosition)] &= Mask;
1532 }
1533
1534 /// Set bottom loBits bits to 0.
1535 void clearLowBits(unsigned loBits) {
1536 assert(loBits <= BitWidth && "More bits than bitwidth")(static_cast<void> (0));
1537 APInt Keep = getHighBitsSet(BitWidth, BitWidth - loBits);
1538 *this &= Keep;
1539 }
1540
1541 /// Set the sign bit to 0.
1542 void clearSignBit() {
1543 clearBit(BitWidth - 1);
1544 }
1545
1546 /// Toggle every bit to its opposite value.
1547 void flipAllBits() {
1548 if (isSingleWord()) {
1549 U.VAL ^= WORDTYPE_MAX;
1550 clearUnusedBits();
1551 } else {
1552 flipAllBitsSlowCase();
1553 }
1554 }
1555
1556 /// Toggles a given bit to its opposite value.
1557 ///
1558 /// Toggle a given bit to its opposite value whose position is given
1559 /// as "bitPosition".
1560 void flipBit(unsigned bitPosition);
1561
1562 /// Negate this APInt in place.
1563 void negate() {
1564 flipAllBits();
1565 ++(*this);
1566 }
1567
1568 /// Insert the bits from a smaller APInt starting at bitPosition.
1569 void insertBits(const APInt &SubBits, unsigned bitPosition);
1570 void insertBits(uint64_t SubBits, unsigned bitPosition, unsigned numBits);
1571
1572 /// Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
1573 APInt extractBits(unsigned numBits, unsigned bitPosition) const;
1574 uint64_t extractBitsAsZExtValue(unsigned numBits, unsigned bitPosition) const;
1575
1576 /// @}
1577 /// \name Value Characterization Functions
1578 /// @{
1579
1580 /// Return the number of bits in the APInt.
1581 unsigned getBitWidth() const { return BitWidth; }
1582
1583 /// Get the number of words.
1584 ///
1585 /// Here one word's bitwidth equals to that of uint64_t.
1586 ///
1587 /// \returns the number of words to hold the integer value of this APInt.
1588 unsigned getNumWords() const { return getNumWords(BitWidth); }
1589
1590 /// Get the number of words.
1591 ///
1592 /// *NOTE* Here one word's bitwidth equals to that of uint64_t.
1593 ///
1594 /// \returns the number of words to hold the integer value with a given bit
1595 /// width.
1596 static unsigned getNumWords(unsigned BitWidth) {
1597 return ((uint64_t)BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD;
1598 }
1599
1600 /// Compute the number of active bits in the value
1601 ///
1602 /// This function returns the number of active bits which is defined as the
1603 /// bit width minus the number of leading zeros. This is used in several
1604 /// computations to see how "wide" the value is.
1605 unsigned getActiveBits() const { return BitWidth - countLeadingZeros(); }
1606
1607 /// Compute the number of active words in the value of this APInt.
1608 ///
1609 /// This is used in conjunction with getActiveData to extract the raw value of
1610 /// the APInt.
1611 unsigned getActiveWords() const {
1612 unsigned numActiveBits = getActiveBits();
1613 return numActiveBits ? whichWord(numActiveBits - 1) + 1 : 1;
1614 }
1615
1616 /// Get the minimum bit size for this signed APInt
1617 ///
1618 /// Computes the minimum bit width for this APInt while considering it to be a
1619 /// signed (and probably negative) value. If the value is not negative, this
1620 /// function returns the same value as getActiveBits()+1. Otherwise, it
1621 /// returns the smallest bit width that will retain the negative value. For
1622 /// example, -1 can be written as 0b1 or 0xFFFFFFFFFF. 0b1 is shorter and so
1623 /// for -1, this function will always return 1.
1624 unsigned getMinSignedBits() const { return BitWidth - getNumSignBits() + 1; }
1625
1626 /// Get zero extended value
1627 ///
1628 /// This method attempts to return the value of this APInt as a zero extended
1629 /// uint64_t. The bitwidth must be <= 64 or the value must fit within a
1630 /// uint64_t. Otherwise an assertion will result.
1631 uint64_t getZExtValue() const {
1632 if (isSingleWord())
1633 return U.VAL;
1634 assert(getActiveBits() <= 64 && "Too many bits for uint64_t")(static_cast<void> (0));
1635 return U.pVal[0];
1636 }
1637
1638 /// Get sign extended value
1639 ///
1640 /// This method attempts to return the value of this APInt as a sign extended
1641 /// int64_t. The bit width must be <= 64 or the value must fit within an
1642 /// int64_t. Otherwise an assertion will result.
1643 int64_t getSExtValue() const {
1644 if (isSingleWord())
1645 return SignExtend64(U.VAL, BitWidth);
1646 assert(getMinSignedBits() <= 64 && "Too many bits for int64_t")(static_cast<void> (0));
1647 return int64_t(U.pVal[0]);
1648 }
1649
1650 /// Get bits required for string value.
1651 ///
1652 /// This method determines how many bits are required to hold the APInt
1653 /// equivalent of the string given by \p str.
1654 static unsigned getBitsNeeded(StringRef str, uint8_t radix);
1655
1656 /// The APInt version of the countLeadingZeros functions in
1657 /// MathExtras.h.
1658 ///
1659 /// It counts the number of zeros from the most significant bit to the first
1660 /// one bit.
1661 ///
1662 /// \returns BitWidth if the value is zero, otherwise returns the number of
1663 /// zeros from the most significant bit to the first one bits.
1664 unsigned countLeadingZeros() const {
1665 if (isSingleWord()) {
1666 unsigned unusedBits = APINT_BITS_PER_WORD - BitWidth;
1667 return llvm::countLeadingZeros(U.VAL) - unusedBits;
1668 }
1669 return countLeadingZerosSlowCase();
1670 }
1671
1672 /// Count the number of leading one bits.
1673 ///
1674 /// This function is an APInt version of the countLeadingOnes
1675 /// functions in MathExtras.h. It counts the number of ones from the most
1676 /// significant bit to the first zero bit.
1677 ///
1678 /// \returns 0 if the high order bit is not set, otherwise returns the number
1679 /// of 1 bits from the most significant to the least
1680 unsigned countLeadingOnes() const {
1681 if (isSingleWord())
1682 return llvm::countLeadingOnes(U.VAL << (APINT_BITS_PER_WORD - BitWidth));
1683 return countLeadingOnesSlowCase();
1684 }
1685
1686 /// Computes the number of leading bits of this APInt that are equal to its
1687 /// sign bit.
1688 unsigned getNumSignBits() const {
1689 return isNegative() ? countLeadingOnes() : countLeadingZeros();
1690 }
1691
1692 /// Count the number of trailing zero bits.
1693 ///
1694 /// This function is an APInt version of the countTrailingZeros
1695 /// functions in MathExtras.h. It counts the number of zeros from the least
1696 /// significant bit to the first set bit.
1697 ///
1698 /// \returns BitWidth if the value is zero, otherwise returns the number of
1699 /// zeros from the least significant bit to the first one bit.
1700 unsigned countTrailingZeros() const {
1701 if (isSingleWord()) {
1702 unsigned TrailingZeros = llvm::countTrailingZeros(U.VAL);
1703 return (TrailingZeros > BitWidth ? BitWidth : TrailingZeros);
1704 }
1705 return countTrailingZerosSlowCase();
1706 }
1707
1708 /// Count the number of trailing one bits.
1709 ///
1710 /// This function is an APInt version of the countTrailingOnes
1711 /// functions in MathExtras.h. It counts the number of ones from the least
1712 /// significant bit to the first zero bit.
1713 ///
1714 /// \returns BitWidth if the value is all ones, otherwise returns the number
1715 /// of ones from the least significant bit to the first zero bit.
1716 unsigned countTrailingOnes() const {
1717 if (isSingleWord())
1718 return llvm::countTrailingOnes(U.VAL);
1719 return countTrailingOnesSlowCase();
1720 }
1721
1722 /// Count the number of bits set.
1723 ///
1724 /// This function is an APInt version of the countPopulation functions
1725 /// in MathExtras.h. It counts the number of 1 bits in the APInt value.
1726 ///
1727 /// \returns 0 if the value is zero, otherwise returns the number of set bits.
1728 unsigned countPopulation() const {
1729 if (isSingleWord())
1730 return llvm::countPopulation(U.VAL);
1731 return countPopulationSlowCase();
1732 }
1733
1734 /// @}
1735 /// \name Conversion Functions
1736 /// @{
1737 void print(raw_ostream &OS, bool isSigned) const;
1738
1739 /// Converts an APInt to a string and append it to Str. Str is commonly a
1740 /// SmallString.
1741 void toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
1742 bool formatAsCLiteral = false) const;
1743
1744 /// Considers the APInt to be unsigned and converts it into a string in the
1745 /// radix given. The radix can be 2, 8, 10 16, or 36.
1746 void toStringUnsigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
1747 toString(Str, Radix, false, false);
1748 }
1749
1750 /// Considers the APInt to be signed and converts it into a string in the
1751 /// radix given. The radix can be 2, 8, 10, 16, or 36.
1752 void toStringSigned(SmallVectorImpl<char> &Str, unsigned Radix = 10) const {
1753 toString(Str, Radix, true, false);
1754 }
1755
1756 /// \returns a byte-swapped representation of this APInt Value.
1757 APInt byteSwap() const;
1758
1759 /// \returns the value with the bit representation reversed of this APInt
1760 /// Value.
1761 APInt reverseBits() const;
1762
1763 /// Converts this APInt to a double value.
1764 double roundToDouble(bool isSigned) const;
1765
1766 /// Converts this unsigned APInt to a double value.
1767 double roundToDouble() const { return roundToDouble(false); }
1768
1769 /// Converts this signed APInt to a double value.
1770 double signedRoundToDouble() const { return roundToDouble(true); }
1771
1772 /// Converts APInt bits to a double
1773 ///
1774 /// The conversion does not do a translation from integer to double, it just
1775 /// re-interprets the bits as a double. Note that it is valid to do this on
1776 /// any bit width. Exactly 64 bits will be translated.
1777 double bitsToDouble() const {
1778 return BitsToDouble(getWord(0));
1779 }
1780
1781 /// Converts APInt bits to a float
1782 ///
1783 /// The conversion does not do a translation from integer to float, it just
1784 /// re-interprets the bits as a float. Note that it is valid to do this on
1785 /// any bit width. Exactly 32 bits will be translated.
1786 float bitsToFloat() const {
1787 return BitsToFloat(static_cast<uint32_t>(getWord(0)));
1788 }
1789
1790 /// Converts a double to APInt bits.
1791 ///
1792 /// The conversion does not do a translation from double to integer, it just
1793 /// re-interprets the bits of the double.
1794 static APInt doubleToBits(double V) {
1795 return APInt(sizeof(double) * CHAR_BIT8, DoubleToBits(V));
1796 }
1797
1798 /// Converts a float to APInt bits.
1799 ///
1800 /// The conversion does not do a translation from float to integer, it just
1801 /// re-interprets the bits of the float.
1802 static APInt floatToBits(float V) {
1803 return APInt(sizeof(float) * CHAR_BIT8, FloatToBits(V));
1804 }
1805
1806 /// @}
1807 /// \name Mathematics Operations
1808 /// @{
1809
1810 /// \returns the floor log base 2 of this APInt.
1811 unsigned logBase2() const { return getActiveBits() - 1; }
1812
1813 /// \returns the ceil log base 2 of this APInt.
1814 unsigned ceilLogBase2() const {
1815 APInt temp(*this);
1816 --temp;
1817 return temp.getActiveBits();
1818 }
1819
1820 /// \returns the nearest log base 2 of this APInt. Ties round up.
1821 ///
1822 /// NOTE: When we have a BitWidth of 1, we define:
1823 ///
1824 /// log2(0) = UINT32_MAX
1825 /// log2(1) = 0
1826 ///
1827 /// to get around any mathematical concerns resulting from
1828 /// referencing 2 in a space where 2 does no exist.
1829 unsigned nearestLogBase2() const {
1830 // Special case when we have a bitwidth of 1. If VAL is 1, then we
1831 // get 0. If VAL is 0, we get WORDTYPE_MAX which gets truncated to
1832 // UINT32_MAX.
1833 if (BitWidth == 1)
1834 return U.VAL - 1;
1835
1836 // Handle the zero case.
1837 if (isNullValue())
1838 return UINT32_MAX(4294967295U);
1839
1840 // The non-zero case is handled by computing:
1841 //
1842 // nearestLogBase2(x) = logBase2(x) + x[logBase2(x)-1].
1843 //
1844 // where x[i] is referring to the value of the ith bit of x.
1845 unsigned lg = logBase2();
1846 return lg + unsigned((*this)[lg - 1]);
1847 }
1848
1849 /// \returns the log base 2 of this APInt if its an exact power of two, -1
1850 /// otherwise
1851 int32_t exactLogBase2() const {
1852 if (!isPowerOf2())
1853 return -1;
1854 return logBase2();
1855 }
1856
1857 /// Compute the square root
1858 APInt sqrt() const;
1859
1860 /// Get the absolute value;
1861 ///
1862 /// If *this is < 0 then return -(*this), otherwise *this;
1863 APInt abs() const {
1864 if (isNegative())
1865 return -(*this);
1866 return *this;
1867 }
1868
1869 /// \returns the multiplicative inverse for a given modulo.
1870 APInt multiplicativeInverse(const APInt &modulo) const;
1871
1872 /// @}
1873 /// \name Support for division by constant
1874 /// @{
1875
1876 /// Calculate the magic number for signed division by a constant.
1877 struct ms;
1878 ms magic() const;
1879
1880 /// Calculate the magic number for unsigned division by a constant.
1881 struct mu;
1882 mu magicu(unsigned LeadingZeros = 0) const;
1883
1884 /// @}
1885 /// \name Building-block Operations for APInt and APFloat
1886 /// @{
1887
1888 // These building block operations operate on a representation of arbitrary
1889 // precision, two's-complement, bignum integer values. They should be
1890 // sufficient to implement APInt and APFloat bignum requirements. Inputs are
1891 // generally a pointer to the base of an array of integer parts, representing
1892 // an unsigned bignum, and a count of how many parts there are.
1893
1894 /// Sets the least significant part of a bignum to the input value, and zeroes
1895 /// out higher parts.
1896 static void tcSet(WordType *, WordType, unsigned);
1897
1898 /// Assign one bignum to another.
1899 static void tcAssign(WordType *, const WordType *, unsigned);
1900
1901 /// Returns true if a bignum is zero, false otherwise.
1902 static bool tcIsZero(const WordType *, unsigned);
1903
1904 /// Extract the given bit of a bignum; returns 0 or 1. Zero-based.
1905 static int tcExtractBit(const WordType *, unsigned bit);
1906
1907 /// Copy the bit vector of width srcBITS from SRC, starting at bit srcLSB, to
1908 /// DST, of dstCOUNT parts, such that the bit srcLSB becomes the least
1909 /// significant bit of DST. All high bits above srcBITS in DST are
1910 /// zero-filled.
1911 static void tcExtract(WordType *, unsigned dstCount,
1912 const WordType *, unsigned srcBits,
1913 unsigned srcLSB);
1914
1915 /// Set the given bit of a bignum. Zero-based.
1916 static void tcSetBit(WordType *, unsigned bit);
1917
1918 /// Clear the given bit of a bignum. Zero-based.
1919 static void tcClearBit(WordType *, unsigned bit);
1920
1921 /// Returns the bit number of the least or most significant set bit of a
1922 /// number. If the input number has no bits set -1U is returned.
1923 static unsigned tcLSB(const WordType *, unsigned n);
1924 static unsigned tcMSB(const WordType *parts, unsigned n);
1925
1926 /// Negate a bignum in-place.
1927 static void tcNegate(WordType *, unsigned);
1928
1929 /// DST += RHS + CARRY where CARRY is zero or one. Returns the carry flag.
1930 static WordType tcAdd(WordType *, const WordType *,
1931 WordType carry, unsigned);
1932 /// DST += RHS. Returns the carry flag.
1933 static WordType tcAddPart(WordType *, WordType, unsigned);
1934
1935 /// DST -= RHS + CARRY where CARRY is zero or one. Returns the carry flag.
1936 static WordType tcSubtract(WordType *, const WordType *,
1937 WordType carry, unsigned);
1938 /// DST -= RHS. Returns the carry flag.
1939 static WordType tcSubtractPart(WordType *, WordType, unsigned);
1940
1941 /// DST += SRC * MULTIPLIER + PART if add is true
1942 /// DST = SRC * MULTIPLIER + PART if add is false
1943 ///
1944 /// Requires 0 <= DSTPARTS <= SRCPARTS + 1. If DST overlaps SRC they must
1945 /// start at the same point, i.e. DST == SRC.
1946 ///
1947 /// If DSTPARTS == SRC_PARTS + 1 no overflow occurs and zero is returned.
1948 /// Otherwise DST is filled with the least significant DSTPARTS parts of the
1949 /// result, and if all of the omitted higher parts were zero return zero,
1950 /// otherwise overflow occurred and return one.
1951 static int tcMultiplyPart(WordType *dst, const WordType *src,
1952 WordType multiplier, WordType carry,
1953 unsigned srcParts, unsigned dstParts,
1954 bool add);
1955
1956 /// DST = LHS * RHS, where DST has the same width as the operands and is
1957 /// filled with the least significant parts of the result. Returns one if
1958 /// overflow occurred, otherwise zero. DST must be disjoint from both
1959 /// operands.
1960 static int tcMultiply(WordType *, const WordType *, const WordType *,
1961 unsigned);
1962
1963 /// DST = LHS * RHS, where DST has width the sum of the widths of the
1964 /// operands. No overflow occurs. DST must be disjoint from both operands.
1965 static void tcFullMultiply(WordType *, const WordType *,
1966 const WordType *, unsigned, unsigned);
1967
1968 /// If RHS is zero LHS and REMAINDER are left unchanged, return one.
1969 /// Otherwise set LHS to LHS / RHS with the fractional part discarded, set
1970 /// REMAINDER to the remainder, return zero. i.e.
1971 ///
1972 /// OLD_LHS = RHS * LHS + REMAINDER
1973 ///
1974 /// SCRATCH is a bignum of the same size as the operands and result for use by
1975 /// the routine; its contents need not be initialized and are destroyed. LHS,
1976 /// REMAINDER and SCRATCH must be distinct.
1977 static int tcDivide(WordType *lhs, const WordType *rhs,
1978 WordType *remainder, WordType *scratch,
1979 unsigned parts);
1980
1981 /// Shift a bignum left Count bits. Shifted in bits are zero. There are no
1982 /// restrictions on Count.
1983 static void tcShiftLeft(WordType *, unsigned Words, unsigned Count);
1984
1985 /// Shift a bignum right Count bits. Shifted in bits are zero. There are no
1986 /// restrictions on Count.
1987 static void tcShiftRight(WordType *, unsigned Words, unsigned Count);
1988
1989 /// The obvious AND, OR and XOR and complement operations.
1990 static void tcAnd(WordType *, const WordType *, unsigned);
1991 static void tcOr(WordType *, const WordType *, unsigned);
1992 static void tcXor(WordType *, const WordType *, unsigned);
1993 static void tcComplement(WordType *, unsigned);
1994
1995 /// Comparison (unsigned) of two bignums.
1996 static int tcCompare(const WordType *, const WordType *, unsigned);
1997
1998 /// Increment a bignum in-place. Return the carry flag.
1999 static WordType tcIncrement(WordType *dst, unsigned parts) {
2000 return tcAddPart(dst, 1, parts);
2001 }
2002
2003 /// Decrement a bignum in-place. Return the borrow flag.
2004 static WordType tcDecrement(WordType *dst, unsigned parts) {
2005 return tcSubtractPart(dst, 1, parts);
2006 }
2007
2008 /// Set the least significant BITS and clear the rest.
2009 static void tcSetLeastSignificantBits(WordType *, unsigned, unsigned bits);
2010
2011 /// debug method
2012 void dump() const;
2013
2014 /// @}
2015};
2016
2017/// Magic data for optimising signed division by a constant.
2018struct APInt::ms {
2019 APInt m; ///< magic number
2020 unsigned s; ///< shift amount
2021};
2022
2023/// Magic data for optimising unsigned division by a constant.
2024struct APInt::mu {
2025 APInt m; ///< magic number
2026 bool a; ///< add indicator
2027 unsigned s; ///< shift amount
2028};
2029
2030inline bool operator==(uint64_t V1, const APInt &V2) { return V2 == V1; }
2031
2032inline bool operator!=(uint64_t V1, const APInt &V2) { return V2 != V1; }
2033
2034/// Unary bitwise complement operator.
2035///
2036/// \returns an APInt that is the bitwise complement of \p v.
2037inline APInt operator~(APInt v) {
2038 v.flipAllBits();
2039 return v;
2040}
2041
2042inline APInt operator&(APInt a, const APInt &b) {
2043 a &= b;
2044 return a;
2045}
2046
2047inline APInt operator&(const APInt &a, APInt &&b) {
2048 b &= a;
2049 return std::move(b);
2050}
2051
2052inline APInt operator&(APInt a, uint64_t RHS) {
2053 a &= RHS;
2054 return a;
2055}
2056
2057inline APInt operator&(uint64_t LHS, APInt b) {
2058 b &= LHS;
2059 return b;
2060}
2061
2062inline APInt operator|(APInt a, const APInt &b) {
2063 a |= b;
2064 return a;
2065}
2066
2067inline APInt operator|(const APInt &a, APInt &&b) {
2068 b |= a;
2069 return std::move(b);
2070}
2071
2072inline APInt operator|(APInt a, uint64_t RHS) {
2073 a |= RHS;
2074 return a;
2075}
2076
2077inline APInt operator|(uint64_t LHS, APInt b) {
2078 b |= LHS;
2079 return b;
2080}
2081
2082inline APInt operator^(APInt a, const APInt &b) {
2083 a ^= b;
2084 return a;
2085}
2086
2087inline APInt operator^(const APInt &a, APInt &&b) {
2088 b ^= a;
2089 return std::move(b);
2090}
2091
2092inline APInt operator^(APInt a, uint64_t RHS) {
2093 a ^= RHS;
2094 return a;
2095}
2096
2097inline APInt operator^(uint64_t LHS, APInt b) {
2098 b ^= LHS;
2099 return b;
2100}
2101
2102inline raw_ostream &operator<<(raw_ostream &OS, const APInt &I) {
2103 I.print(OS, true);
2104 return OS;
2105}
2106
2107inline APInt operator-(APInt v) {
2108 v.negate();
2109 return v;
2110}
2111
2112inline APInt operator+(APInt a, const APInt &b) {
2113 a += b;
2114 return a;
2115}
2116
2117inline APInt operator+(const APInt &a, APInt &&b) {
2118 b += a;
2119 return std::move(b);
2120}
2121
2122inline APInt operator+(APInt a, uint64_t RHS) {
2123 a += RHS;
2124 return a;
2125}
2126
2127inline APInt operator+(uint64_t LHS, APInt b) {
2128 b += LHS;
2129 return b;
2130}
2131
2132inline APInt operator-(APInt a, const APInt &b) {
2133 a -= b;
2134 return a;
2135}
2136
2137inline APInt operator-(const APInt &a, APInt &&b) {
2138 b.negate();
2139 b += a;
2140 return std::move(b);
2141}
2142
2143inline APInt operator-(APInt a, uint64_t RHS) {
2144 a -= RHS;
2145 return a;
2146}
2147
2148inline APInt operator-(uint64_t LHS, APInt b) {
2149 b.negate();
2150 b += LHS;
2151 return b;
2152}
2153
2154inline APInt operator*(APInt a, uint64_t RHS) {
2155 a *= RHS;
2156 return a;
2157}
2158
2159inline APInt operator*(uint64_t LHS, APInt b) {
2160 b *= LHS;
2161 return b;
2162}
2163
2164
2165namespace APIntOps {
2166
2167/// Determine the smaller of two APInts considered to be signed.
2168inline const APInt &smin(const APInt &A, const APInt &B) {
2169 return A.slt(B) ? A : B;
2170}
2171
2172/// Determine the larger of two APInts considered to be signed.
2173inline const APInt &smax(const APInt &A, const APInt &B) {
2174 return A.sgt(B) ? A : B;
2175}
2176
2177/// Determine the smaller of two APInts considered to be unsigned.
2178inline const APInt &umin(const APInt &A, const APInt &B) {
2179 return A.ult(B) ? A : B;
2180}
2181
2182/// Determine the larger of two APInts considered to be unsigned.
2183inline const APInt &umax(const APInt &A, const APInt &B) {
2184 return A.ugt(B) ? A : B;
2185}
2186
2187/// Compute GCD of two unsigned APInt values.
2188///
2189/// This function returns the greatest common divisor of the two APInt values
2190/// using Stein's algorithm.
2191///
2192/// \returns the greatest common divisor of A and B.
2193APInt GreatestCommonDivisor(APInt A, APInt B);
2194
2195/// Converts the given APInt to a double value.
2196///
2197/// Treats the APInt as an unsigned value for conversion purposes.
2198inline double RoundAPIntToDouble(const APInt &APIVal) {
2199 return APIVal.roundToDouble();
2200}
2201
2202/// Converts the given APInt to a double value.
2203///
2204/// Treats the APInt as a signed value for conversion purposes.
2205inline double RoundSignedAPIntToDouble(const APInt &APIVal) {
2206 return APIVal.signedRoundToDouble();
2207}
2208
2209/// Converts the given APInt to a float value.
2210inline float RoundAPIntToFloat(const APInt &APIVal) {
2211 return float(RoundAPIntToDouble(APIVal));
2212}
2213
2214/// Converts the given APInt to a float value.
2215///
2216/// Treats the APInt as a signed value for conversion purposes.
2217inline float RoundSignedAPIntToFloat(const APInt &APIVal) {
2218 return float(APIVal.signedRoundToDouble());
2219}
2220
2221/// Converts the given double value into a APInt.
2222///
2223/// This function convert a double value to an APInt value.
2224APInt RoundDoubleToAPInt(double Double, unsigned width);
2225
2226/// Converts a float value into a APInt.
2227///
2228/// Converts a float value into an APInt value.
2229inline APInt RoundFloatToAPInt(float Float, unsigned width) {
2230 return RoundDoubleToAPInt(double(Float), width);
2231}
2232
2233/// Return A unsign-divided by B, rounded by the given rounding mode.
2234APInt RoundingUDiv(const APInt &A, const APInt &B, APInt::Rounding RM);
2235
2236/// Return A sign-divided by B, rounded by the given rounding mode.
2237APInt RoundingSDiv(const APInt &A, const APInt &B, APInt::Rounding RM);
2238
2239/// Let q(n) = An^2 + Bn + C, and BW = bit width of the value range
2240/// (e.g. 32 for i32).
2241/// This function finds the smallest number n, such that
2242/// (a) n >= 0 and q(n) = 0, or
2243/// (b) n >= 1 and q(n-1) and q(n), when evaluated in the set of all
2244/// integers, belong to two different intervals [Rk, Rk+R),
2245/// where R = 2^BW, and k is an integer.
2246/// The idea here is to find when q(n) "overflows" 2^BW, while at the
2247/// same time "allowing" subtraction. In unsigned modulo arithmetic a
2248/// subtraction (treated as addition of negated numbers) would always
2249/// count as an overflow, but here we want to allow values to decrease
2250/// and increase as long as they are within the same interval.
2251/// Specifically, adding of two negative numbers should not cause an
2252/// overflow (as long as the magnitude does not exceed the bit width).
2253/// On the other hand, given a positive number, adding a negative
2254/// number to it can give a negative result, which would cause the
2255/// value to go from [-2^BW, 0) to [0, 2^BW). In that sense, zero is
2256/// treated as a special case of an overflow.
2257///
2258/// This function returns None if after finding k that minimizes the
2259/// positive solution to q(n) = kR, both solutions are contained between
2260/// two consecutive integers.
2261///
2262/// There are cases where q(n) > T, and q(n+1) < T (assuming evaluation
2263/// in arithmetic modulo 2^BW, and treating the values as signed) by the
2264/// virtue of *signed* overflow. This function will *not* find such an n,
2265/// however it may find a value of n satisfying the inequalities due to
2266/// an *unsigned* overflow (if the values are treated as unsigned).
2267/// To find a solution for a signed overflow, treat it as a problem of
2268/// finding an unsigned overflow with a range with of BW-1.
2269///
2270/// The returned value may have a different bit width from the input
2271/// coefficients.
2272Optional<APInt> SolveQuadraticEquationWrap(APInt A, APInt B, APInt C,
2273 unsigned RangeWidth);
2274
2275/// Compare two values, and if they are different, return the position of the
2276/// most significant bit that is different in the values.
2277Optional<unsigned> GetMostSignificantDifferentBit(const APInt &A,
2278 const APInt &B);
2279
2280} // End of APIntOps namespace
2281
2282// See friend declaration above. This additional declaration is required in
2283// order to compile LLVM with IBM xlC compiler.
2284hash_code hash_value(const APInt &Arg);
2285
2286/// StoreIntToMemory - Fills the StoreBytes bytes of memory starting from Dst
2287/// with the integer held in IntVal.
2288void StoreIntToMemory(const APInt &IntVal, uint8_t *Dst, unsigned StoreBytes);
2289
2290/// LoadIntFromMemory - Loads the integer stored in the LoadBytes bytes starting
2291/// from Src into IntVal, which is assumed to be wide enough and to hold zero.
2292void LoadIntFromMemory(APInt &IntVal, const uint8_t *Src, unsigned LoadBytes);
2293
2294/// Provide DenseMapInfo for APInt.
2295template <> struct DenseMapInfo<APInt> {
2296 static inline APInt getEmptyKey() {
2297 APInt V(nullptr, 0);
2298 V.U.VAL = 0;
2299 return V;
2300 }
2301
2302 static inline APInt getTombstoneKey() {
2303 APInt V(nullptr, 0);
2304 V.U.VAL = 1;
2305 return V;
2306 }
2307
2308 static unsigned getHashValue(const APInt &Key);
2309
2310 static bool isEqual(const APInt &LHS, const APInt &RHS) {
2311 return LHS.getBitWidth() == RHS.getBitWidth() && LHS == RHS;
2312 }
2313};
2314
2315} // namespace llvm
2316
2317#endif

/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/clang/include/clang/AST/Type.h

1//===- Type.h - C Language Family Type Representation -----------*- C++ -*-===//
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/// \file
10/// C Language Family Type Representation
11///
12/// This file defines the clang::Type interface and subclasses, used to
13/// represent types for languages in the C family.
14//
15//===----------------------------------------------------------------------===//
16
17#ifndef LLVM_CLANG_AST_TYPE_H
18#define LLVM_CLANG_AST_TYPE_H
19
20#include "clang/AST/DependenceFlags.h"
21#include "clang/AST/NestedNameSpecifier.h"
22#include "clang/AST/TemplateName.h"
23#include "clang/Basic/AddressSpaces.h"
24#include "clang/Basic/AttrKinds.h"
25#include "clang/Basic/Diagnostic.h"
26#include "clang/Basic/ExceptionSpecificationType.h"
27#include "clang/Basic/LLVM.h"
28#include "clang/Basic/Linkage.h"
29#include "clang/Basic/PartialDiagnostic.h"
30#include "clang/Basic/SourceLocation.h"
31#include "clang/Basic/Specifiers.h"
32#include "clang/Basic/Visibility.h"
33#include "llvm/ADT/APInt.h"
34#include "llvm/ADT/APSInt.h"
35#include "llvm/ADT/ArrayRef.h"
36#include "llvm/ADT/FoldingSet.h"
37#include "llvm/ADT/None.h"
38#include "llvm/ADT/Optional.h"
39#include "llvm/ADT/PointerIntPair.h"
40#include "llvm/ADT/PointerUnion.h"
41#include "llvm/ADT/StringRef.h"
42#include "llvm/ADT/Twine.h"
43#include "llvm/ADT/iterator_range.h"
44#include "llvm/Support/Casting.h"
45#include "llvm/Support/Compiler.h"
46#include "llvm/Support/ErrorHandling.h"
47#include "llvm/Support/PointerLikeTypeTraits.h"
48#include "llvm/Support/TrailingObjects.h"
49#include "llvm/Support/type_traits.h"
50#include <cassert>
51#include <cstddef>
52#include <cstdint>
53#include <cstring>
54#include <string>
55#include <type_traits>
56#include <utility>
57
58namespace clang {
59
60class ExtQuals;
61class QualType;
62class ConceptDecl;
63class TagDecl;
64class TemplateParameterList;
65class Type;
66
67enum {
68 TypeAlignmentInBits = 4,
69 TypeAlignment = 1 << TypeAlignmentInBits
70};
71
72namespace serialization {
73 template <class T> class AbstractTypeReader;
74 template <class T> class AbstractTypeWriter;
75}
76
77} // namespace clang
78
79namespace llvm {
80
81 template <typename T>
82 struct PointerLikeTypeTraits;
83 template<>
84 struct PointerLikeTypeTraits< ::clang::Type*> {
85 static inline void *getAsVoidPointer(::clang::Type *P) { return P; }
86
87 static inline ::clang::Type *getFromVoidPointer(void *P) {
88 return static_cast< ::clang::Type*>(P);
89 }
90
91 static constexpr int NumLowBitsAvailable = clang::TypeAlignmentInBits;
92 };
93
94 template<>
95 struct PointerLikeTypeTraits< ::clang::ExtQuals*> {
96 static inline void *getAsVoidPointer(::clang::ExtQuals *P) { return P; }
97
98 static inline ::clang::ExtQuals *getFromVoidPointer(void *P) {
99 return static_cast< ::clang::ExtQuals*>(P);
100 }
101
102 static constexpr int NumLowBitsAvailable = clang::TypeAlignmentInBits;
103 };
104
105} // namespace llvm
106
107namespace clang {
108
109class ASTContext;
110template <typename> class CanQual;
111class CXXRecordDecl;
112class DeclContext;
113class EnumDecl;
114class Expr;
115class ExtQualsTypeCommonBase;
116class FunctionDecl;
117class IdentifierInfo;
118class NamedDecl;
119class ObjCInterfaceDecl;
120class ObjCProtocolDecl;
121class ObjCTypeParamDecl;
122struct PrintingPolicy;
123class RecordDecl;
124class Stmt;
125class TagDecl;
126class TemplateArgument;
127class TemplateArgumentListInfo;
128class TemplateArgumentLoc;
129class TemplateTypeParmDecl;
130class TypedefNameDecl;
131class UnresolvedUsingTypenameDecl;
132
133using CanQualType = CanQual<Type>;
134
135// Provide forward declarations for all of the *Type classes.
136#define TYPE(Class, Base) class Class##Type;
137#include "clang/AST/TypeNodes.inc"
138
139/// The collection of all-type qualifiers we support.
140/// Clang supports five independent qualifiers:
141/// * C99: const, volatile, and restrict
142/// * MS: __unaligned
143/// * Embedded C (TR18037): address spaces
144/// * Objective C: the GC attributes (none, weak, or strong)
145class Qualifiers {
146public:
147 enum TQ { // NOTE: These flags must be kept in sync with DeclSpec::TQ.
148 Const = 0x1,
149 Restrict = 0x2,
150 Volatile = 0x4,
151 CVRMask = Const | Volatile | Restrict
152 };
153
154 enum GC {
155 GCNone = 0,
156 Weak,
157 Strong
158 };
159
160 enum ObjCLifetime {
161 /// There is no lifetime qualification on this type.
162 OCL_None,
163
164 /// This object can be modified without requiring retains or
165 /// releases.
166 OCL_ExplicitNone,
167
168 /// Assigning into this object requires the old value to be
169 /// released and the new value to be retained. The timing of the
170 /// release of the old value is inexact: it may be moved to
171 /// immediately after the last known point where the value is
172 /// live.
173 OCL_Strong,
174
175 /// Reading or writing from this object requires a barrier call.
176 OCL_Weak,
177
178 /// Assigning into this object requires a lifetime extension.
179 OCL_Autoreleasing
180 };
181
182 enum {
183 /// The maximum supported address space number.
184 /// 23 bits should be enough for anyone.
185 MaxAddressSpace = 0x7fffffu,
186
187 /// The width of the "fast" qualifier mask.
188 FastWidth = 3,
189
190 /// The fast qualifier mask.
191 FastMask = (1 << FastWidth) - 1
192 };
193
194 /// Returns the common set of qualifiers while removing them from
195 /// the given sets.
196 static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) {
197 // If both are only CVR-qualified, bit operations are sufficient.
198 if (!(L.Mask & ~CVRMask) && !(R.Mask & ~CVRMask)) {
199 Qualifiers Q;
200 Q.Mask = L.Mask & R.Mask;
201 L.Mask &= ~Q.Mask;
202 R.Mask &= ~Q.Mask;
203 return Q;
204 }
205
206 Qualifiers Q;
207 unsigned CommonCRV = L.getCVRQualifiers() & R.getCVRQualifiers();
208 Q.addCVRQualifiers(CommonCRV);
209 L.removeCVRQualifiers(CommonCRV);
210 R.removeCVRQualifiers(CommonCRV);
211
212 if (L.getObjCGCAttr() == R.getObjCGCAttr()) {
213 Q.setObjCGCAttr(L.getObjCGCAttr());
214 L.removeObjCGCAttr();
215 R.removeObjCGCAttr();
216 }
217
218 if (L.getObjCLifetime() == R.getObjCLifetime()) {
219 Q.setObjCLifetime(L.getObjCLifetime());
220 L.removeObjCLifetime();
221 R.removeObjCLifetime();
222 }
223
224 if (L.getAddressSpace() == R.getAddressSpace()) {
225 Q.setAddressSpace(L.getAddressSpace());
226 L.removeAddressSpace();
227 R.removeAddressSpace();
228 }
229 return Q;
230 }
231
232 static Qualifiers fromFastMask(unsigned Mask) {
233 Qualifiers Qs;
234 Qs.addFastQualifiers(Mask);
235 return Qs;
236 }
237
238 static Qualifiers fromCVRMask(unsigned CVR) {
239 Qualifiers Qs;
240 Qs.addCVRQualifiers(CVR);
241 return Qs;
242 }
243
244 static Qualifiers fromCVRUMask(unsigned CVRU) {
245 Qualifiers Qs;
246 Qs.addCVRUQualifiers(CVRU);
247 return Qs;
248 }
249
250 // Deserialize qualifiers from an opaque representation.
251 static Qualifiers fromOpaqueValue(unsigned opaque) {
252 Qualifiers Qs;
253 Qs.Mask = opaque;
254 return Qs;
255 }
256
257 // Serialize these qualifiers into an opaque representation.
258 unsigned getAsOpaqueValue() const {
259 return Mask;
260 }
261
262 bool hasConst() const { return Mask & Const; }
263 bool hasOnlyConst() const { return Mask == Const; }
264 void removeConst() { Mask &= ~Const; }
265 void addConst() { Mask |= Const; }
266
267 bool hasVolatile() const { return Mask & Volatile; }
268 bool hasOnlyVolatile() const { return Mask == Volatile; }
269 void removeVolatile() { Mask &= ~Volatile; }
270 void addVolatile() { Mask |= Volatile; }
271
272 bool hasRestrict() const { return Mask & Restrict; }
273 bool hasOnlyRestrict() const { return Mask == Restrict; }
274 void removeRestrict() { Mask &= ~Restrict; }
275 void addRestrict() { Mask |= Restrict; }
276
277 bool hasCVRQualifiers() const { return getCVRQualifiers(); }
278 unsigned getCVRQualifiers() const { return Mask & CVRMask; }
279 unsigned getCVRUQualifiers() const { return Mask & (CVRMask | UMask); }
280
281 void setCVRQualifiers(unsigned mask) {
282 assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits")(static_cast<void> (0));
283 Mask = (Mask & ~CVRMask) | mask;
284 }
285 void removeCVRQualifiers(unsigned mask) {
286 assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits")(static_cast<void> (0));
287 Mask &= ~mask;
288 }
289 void removeCVRQualifiers() {
290 removeCVRQualifiers(CVRMask);
291 }
292 void addCVRQualifiers(unsigned mask) {
293 assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits")(static_cast<void> (0));
294 Mask |= mask;
295 }
296 void addCVRUQualifiers(unsigned mask) {
297 assert(!(mask & ~CVRMask & ~UMask) && "bitmask contains non-CVRU bits")(static_cast<void> (0));
298 Mask |= mask;
299 }
300
301 bool hasUnaligned() const { return Mask & UMask; }
302 void setUnaligned(bool flag) {
303 Mask = (Mask & ~UMask) | (flag ? UMask : 0);
304 }
305 void removeUnaligned() { Mask &= ~UMask; }
306 void addUnaligned() { Mask |= UMask; }
307
308 bool hasObjCGCAttr() const { return Mask & GCAttrMask; }
309 GC getObjCGCAttr() const { return GC((Mask & GCAttrMask) >> GCAttrShift); }
310 void setObjCGCAttr(GC type) {
311 Mask = (Mask & ~GCAttrMask) | (type << GCAttrShift);
312 }
313 void removeObjCGCAttr() { setObjCGCAttr(GCNone); }
314 void addObjCGCAttr(GC type) {
315 assert(type)(static_cast<void> (0));
316 setObjCGCAttr(type);
317 }
318 Qualifiers withoutObjCGCAttr() const {
319 Qualifiers qs = *this;
320 qs.removeObjCGCAttr();
321 return qs;
322 }
323 Qualifiers withoutObjCLifetime() const {
324 Qualifiers qs = *this;
325 qs.removeObjCLifetime();
326 return qs;
327 }
328 Qualifiers withoutAddressSpace() const {
329 Qualifiers qs = *this;
330 qs.removeAddressSpace();
331 return qs;
332 }
333
334 bool hasObjCLifetime() const { return Mask & LifetimeMask; }
335 ObjCLifetime getObjCLifetime() const {
336 return ObjCLifetime((Mask & LifetimeMask) >> LifetimeShift);
337 }
338 void setObjCLifetime(ObjCLifetime type) {
339 Mask = (Mask & ~LifetimeMask) | (type << LifetimeShift);
340 }
341 void removeObjCLifetime() { setObjCLifetime(OCL_None); }
342 void addObjCLifetime(ObjCLifetime type) {
343 assert(type)(static_cast<void> (0));
344 assert(!hasObjCLifetime())(static_cast<void> (0));
345 Mask |= (type << LifetimeShift);
346 }
347
348 /// True if the lifetime is neither None or ExplicitNone.
349 bool hasNonTrivialObjCLifetime() const {
350 ObjCLifetime lifetime = getObjCLifetime();
351 return (lifetime > OCL_ExplicitNone);
352 }
353
354 /// True if the lifetime is either strong or weak.
355 bool hasStrongOrWeakObjCLifetime() const {
356 ObjCLifetime lifetime = getObjCLifetime();
357 return (lifetime == OCL_Strong || lifetime == OCL_Weak);
358 }
359
360 bool hasAddressSpace() const { return Mask & AddressSpaceMask; }
361 LangAS getAddressSpace() const {
362 return static_cast<LangAS>(Mask >> AddressSpaceShift);
363 }
364 bool hasTargetSpecificAddressSpace() const {
365 return isTargetAddressSpace(getAddressSpace());
366 }
367 /// Get the address space attribute value to be printed by diagnostics.
368 unsigned getAddressSpaceAttributePrintValue() const {
369 auto Addr = getAddressSpace();
370 // This function is not supposed to be used with language specific
371 // address spaces. If that happens, the diagnostic message should consider
372 // printing the QualType instead of the address space value.
373 assert(Addr == LangAS::Default || hasTargetSpecificAddressSpace())(static_cast<void> (0));
374 if (Addr != LangAS::Default)
375 return toTargetAddressSpace(Addr);
376 // TODO: The diagnostic messages where Addr may be 0 should be fixed
377 // since it cannot differentiate the situation where 0 denotes the default
378 // address space or user specified __attribute__((address_space(0))).
379 return 0;
380 }
381 void setAddressSpace(LangAS space) {
382 assert((unsigned)space <= MaxAddressSpace)(static_cast<void> (0));
383 Mask = (Mask & ~AddressSpaceMask)
384 | (((uint32_t) space) << AddressSpaceShift);
385 }
386 void removeAddressSpace() { setAddressSpace(LangAS::Default); }
387 void addAddressSpace(LangAS space) {
388 assert(space != LangAS::Default)(static_cast<void> (0));
389 setAddressSpace(space);
390 }
391
392 // Fast qualifiers are those that can be allocated directly
393 // on a QualType object.
394 bool hasFastQualifiers() const { return getFastQualifiers(); }
395 unsigned getFastQualifiers() const { return Mask & FastMask; }
396 void setFastQualifiers(unsigned mask) {
397 assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits")(static_cast<void> (0));
398 Mask = (Mask & ~FastMask) | mask;
399 }
400 void removeFastQualifiers(unsigned mask) {
401 assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits")(static_cast<void> (0));
402 Mask &= ~mask;
403 }
404 void removeFastQualifiers() {
405 removeFastQualifiers(FastMask);
406 }
407 void addFastQualifiers(unsigned mask) {
408 assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits")(static_cast<void> (0));
409 Mask |= mask;
410 }
411
412 /// Return true if the set contains any qualifiers which require an ExtQuals
413 /// node to be allocated.
414 bool hasNonFastQualifiers() const { return Mask & ~FastMask; }
415 Qualifiers getNonFastQualifiers() const {
416 Qualifiers Quals = *this;
417 Quals.setFastQualifiers(0);
418 return Quals;
419 }
420
421 /// Return true if the set contains any qualifiers.
422 bool hasQualifiers() const { return Mask; }
423 bool empty() const { return !Mask; }
424
425 /// Add the qualifiers from the given set to this set.
426 void addQualifiers(Qualifiers Q) {
427 // If the other set doesn't have any non-boolean qualifiers, just
428 // bit-or it in.
429 if (!(Q.Mask & ~CVRMask))
430 Mask |= Q.Mask;
431 else {
432 Mask |= (Q.Mask & CVRMask);
433 if (Q.hasAddressSpace())
434 addAddressSpace(Q.getAddressSpace());
435 if (Q.hasObjCGCAttr())
436 addObjCGCAttr(Q.getObjCGCAttr());
437 if (Q.hasObjCLifetime())
438 addObjCLifetime(Q.getObjCLifetime());
439 }
440 }
441
442 /// Remove the qualifiers from the given set from this set.
443 void removeQualifiers(Qualifiers Q) {
444 // If the other set doesn't have any non-boolean qualifiers, just
445 // bit-and the inverse in.
446 if (!(Q.Mask & ~CVRMask))
447 Mask &= ~Q.Mask;
448 else {
449 Mask &= ~(Q.Mask & CVRMask);
450 if (getObjCGCAttr() == Q.getObjCGCAttr())
451 removeObjCGCAttr();
452 if (getObjCLifetime() == Q.getObjCLifetime())
453 removeObjCLifetime();
454 if (getAddressSpace() == Q.getAddressSpace())
455 removeAddressSpace();
456 }
457 }
458
459 /// Add the qualifiers from the given set to this set, given that
460 /// they don't conflict.
461 void addConsistentQualifiers(Qualifiers qs) {
462 assert(getAddressSpace() == qs.getAddressSpace() ||(static_cast<void> (0))
463 !hasAddressSpace() || !qs.hasAddressSpace())(static_cast<void> (0));
464 assert(getObjCGCAttr() == qs.getObjCGCAttr() ||(static_cast<void> (0))
465 !hasObjCGCAttr() || !qs.hasObjCGCAttr())(static_cast<void> (0));
466 assert(getObjCLifetime() == qs.getObjCLifetime() ||(static_cast<void> (0))
467 !hasObjCLifetime() || !qs.hasObjCLifetime())(static_cast<void> (0));
468 Mask |= qs.Mask;
469 }
470
471 /// Returns true if address space A is equal to or a superset of B.
472 /// OpenCL v2.0 defines conversion rules (OpenCLC v2.0 s6.5.5) and notion of
473 /// overlapping address spaces.
474 /// CL1.1 or CL1.2:
475 /// every address space is a superset of itself.
476 /// CL2.0 adds:
477 /// __generic is a superset of any address space except for __constant.
478 static bool isAddressSpaceSupersetOf(LangAS A, LangAS B) {
479 // Address spaces must match exactly.
480 return A == B ||
481 // Otherwise in OpenCLC v2.0 s6.5.5: every address space except
482 // for __constant can be used as __generic.
483 (A == LangAS::opencl_generic && B != LangAS::opencl_constant) ||
484 // We also define global_device and global_host address spaces,
485 // to distinguish global pointers allocated on host from pointers
486 // allocated on device, which are a subset of __global.
487 (A == LangAS::opencl_global && (B == LangAS::opencl_global_device ||
488 B == LangAS::opencl_global_host)) ||
489 (A == LangAS::sycl_global && (B == LangAS::sycl_global_device ||
490 B == LangAS::sycl_global_host)) ||
491 // Consider pointer size address spaces to be equivalent to default.
492 ((isPtrSizeAddressSpace(A) || A == LangAS::Default) &&
493 (isPtrSizeAddressSpace(B) || B == LangAS::Default)) ||
494 // Default is a superset of SYCL address spaces.
495 (A == LangAS::Default &&
496 (B == LangAS::sycl_private || B == LangAS::sycl_local ||
497 B == LangAS::sycl_global || B == LangAS::sycl_global_device ||
498 B == LangAS::sycl_global_host)) ||
499 // In HIP device compilation, any cuda address space is allowed
500 // to implicitly cast into the default address space.
501 (A == LangAS::Default &&
502 (B == LangAS::cuda_constant || B == LangAS::cuda_device ||
503 B == LangAS::cuda_shared));
504 }
505
506 /// Returns true if the address space in these qualifiers is equal to or
507 /// a superset of the address space in the argument qualifiers.
508 bool isAddressSpaceSupersetOf(Qualifiers other) const {
509 return isAddressSpaceSupersetOf(getAddressSpace(), other.getAddressSpace());
510 }
511
512 /// Determines if these qualifiers compatibly include another set.
513 /// Generally this answers the question of whether an object with the other
514 /// qualifiers can be safely used as an object with these qualifiers.
515 bool compatiblyIncludes(Qualifiers other) const {
516 return isAddressSpaceSupersetOf(other) &&
517 // ObjC GC qualifiers can match, be added, or be removed, but can't
518 // be changed.
519 (getObjCGCAttr() == other.getObjCGCAttr() || !hasObjCGCAttr() ||
520 !other.hasObjCGCAttr()) &&
521 // ObjC lifetime qualifiers must match exactly.
522 getObjCLifetime() == other.getObjCLifetime() &&
523 // CVR qualifiers may subset.
524 (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask)) &&
525 // U qualifier may superset.
526 (!other.hasUnaligned() || hasUnaligned());
527 }
528
529 /// Determines if these qualifiers compatibly include another set of
530 /// qualifiers from the narrow perspective of Objective-C ARC lifetime.
531 ///
532 /// One set of Objective-C lifetime qualifiers compatibly includes the other
533 /// if the lifetime qualifiers match, or if both are non-__weak and the
534 /// including set also contains the 'const' qualifier, or both are non-__weak
535 /// and one is None (which can only happen in non-ARC modes).
536 bool compatiblyIncludesObjCLifetime(Qualifiers other) const {
537 if (getObjCLifetime() == other.getObjCLifetime())
538 return true;
539
540 if (getObjCLifetime() == OCL_Weak || other.getObjCLifetime() == OCL_Weak)
541 return false;
542
543 if (getObjCLifetime() == OCL_None || other.getObjCLifetime() == OCL_None)
544 return true;
545
546 return hasConst();
547 }
548
549 /// Determine whether this set of qualifiers is a strict superset of
550 /// another set of qualifiers, not considering qualifier compatibility.
551 bool isStrictSupersetOf(Qualifiers Other) const;
552
553 bool operator==(Qualifiers Other) const { return Mask == Other.Mask; }
554 bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; }
555
556 explicit operator bool() const { return hasQualifiers(); }
557
558 Qualifiers &operator+=(Qualifiers R) {
559 addQualifiers(R);
560 return *this;
561 }
562
563 // Union two qualifier sets. If an enumerated qualifier appears
564 // in both sets, use the one from the right.
565 friend Qualifiers operator+(Qualifiers L, Qualifiers R) {
566 L += R;
567 return L;
568 }
569
570 Qualifiers &operator-=(Qualifiers R) {
571 removeQualifiers(R);
572 return *this;
573 }
574
575 /// Compute the difference between two qualifier sets.
576 friend Qualifiers operator-(Qualifiers L, Qualifiers R) {
577 L -= R;
578 return L;
579 }
580
581 std::string getAsString() const;
582 std::string getAsString(const PrintingPolicy &Policy) const;
583
584 static std::string getAddrSpaceAsString(LangAS AS);
585
586 bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const;
587 void print(raw_ostream &OS, const PrintingPolicy &Policy,
588 bool appendSpaceIfNonEmpty = false) const;
589
590 void Profile(llvm::FoldingSetNodeID &ID) const {
591 ID.AddInteger(Mask);
592 }
593
594private:
595 // bits: |0 1 2|3|4 .. 5|6 .. 8|9 ... 31|
596 // |C R V|U|GCAttr|Lifetime|AddressSpace|
597 uint32_t Mask = 0;
598
599 static const uint32_t UMask = 0x8;
600 static const uint32_t UShift = 3;
601 static const uint32_t GCAttrMask = 0x30;
602 static const uint32_t GCAttrShift = 4;
603 static const uint32_t LifetimeMask = 0x1C0;
604 static const uint32_t LifetimeShift = 6;
605 static const uint32_t AddressSpaceMask =
606 ~(CVRMask | UMask | GCAttrMask | LifetimeMask);
607 static const uint32_t AddressSpaceShift = 9;
608};
609
610/// A std::pair-like structure for storing a qualified type split
611/// into its local qualifiers and its locally-unqualified type.
612struct SplitQualType {
613 /// The locally-unqualified type.
614 const Type *Ty = nullptr;
615
616 /// The local qualifiers.
617 Qualifiers Quals;
618
619 SplitQualType() = default;
620 SplitQualType(const Type *ty, Qualifiers qs) : Ty(ty), Quals(qs) {}
621
622 SplitQualType getSingleStepDesugaredType() const; // end of this file
623
624 // Make std::tie work.
625 std::pair<const Type *,Qualifiers> asPair() const {
626 return std::pair<const Type *, Qualifiers>(Ty, Quals);
627 }
628
629 friend bool operator==(SplitQualType a, SplitQualType b) {
630 return a.Ty == b.Ty && a.Quals == b.Quals;
631 }
632 friend bool operator!=(SplitQualType a, SplitQualType b) {
633 return a.Ty != b.Ty || a.Quals != b.Quals;
634 }
635};
636
637/// The kind of type we are substituting Objective-C type arguments into.
638///
639/// The kind of substitution affects the replacement of type parameters when
640/// no concrete type information is provided, e.g., when dealing with an
641/// unspecialized type.
642enum class ObjCSubstitutionContext {
643 /// An ordinary type.
644 Ordinary,
645
646 /// The result type of a method or function.
647 Result,
648
649 /// The parameter type of a method or function.
650 Parameter,
651
652 /// The type of a property.
653 Property,
654
655 /// The superclass of a type.
656 Superclass,
657};
658
659/// A (possibly-)qualified type.
660///
661/// For efficiency, we don't store CV-qualified types as nodes on their
662/// own: instead each reference to a type stores the qualifiers. This
663/// greatly reduces the number of nodes we need to allocate for types (for
664/// example we only need one for 'int', 'const int', 'volatile int',
665/// 'const volatile int', etc).
666///
667/// As an added efficiency bonus, instead of making this a pair, we
668/// just store the two bits we care about in the low bits of the
669/// pointer. To handle the packing/unpacking, we make QualType be a
670/// simple wrapper class that acts like a smart pointer. A third bit
671/// indicates whether there are extended qualifiers present, in which
672/// case the pointer points to a special structure.
673class QualType {
674 friend class QualifierCollector;
675
676 // Thankfully, these are efficiently composable.
677 llvm::PointerIntPair<llvm::PointerUnion<const Type *, const ExtQuals *>,
678 Qualifiers::FastWidth> Value;
679
680 const ExtQuals *getExtQualsUnsafe() const {
681 return Value.getPointer().get<const ExtQuals*>();
682 }
683
684 const Type *getTypePtrUnsafe() const {
685 return Value.getPointer().get<const Type*>();
686 }
687
688 const ExtQualsTypeCommonBase *getCommonPtr() const {
689 assert(!isNull() && "Cannot retrieve a NULL type pointer")(static_cast<void> (0));
690 auto CommonPtrVal = reinterpret_cast<uintptr_t>(Value.getOpaqueValue());
691 CommonPtrVal &= ~(uintptr_t)((1 << TypeAlignmentInBits) - 1);
692 return reinterpret_cast<ExtQualsTypeCommonBase*>(CommonPtrVal);
693 }
694
695public:
696 QualType() = default;
697 QualType(const Type *Ptr, unsigned Quals) : Value(Ptr, Quals) {}
698 QualType(const ExtQuals *Ptr, unsigned Quals) : Value(Ptr, Quals) {}
699
700 unsigned getLocalFastQualifiers() const { return Value.getInt(); }
701 void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); }
702
703 /// Retrieves a pointer to the underlying (unqualified) type.
704 ///
705 /// This function requires that the type not be NULL. If the type might be
706 /// NULL, use the (slightly less efficient) \c getTypePtrOrNull().
707 const Type *getTypePtr() const;
708
709 const Type *getTypePtrOrNull() const;
710
711 /// Retrieves a pointer to the name of the base type.
712 const IdentifierInfo *getBaseTypeIdentifier() const;
713
714 /// Divides a QualType into its unqualified type and a set of local
715 /// qualifiers.
716 SplitQualType split() const;
717
718 void *getAsOpaquePtr() const { return Value.getOpaqueValue(); }
719
720 static QualType getFromOpaquePtr(const void *Ptr) {
721 QualType T;
722 T.Value.setFromOpaqueValue(const_cast<void*>(Ptr));
723 return T;
724 }
725
726 const Type &operator*() const {
727 return *getTypePtr();
728 }
729
730 const Type *operator->() const {
731 return getTypePtr();
732 }
733
734 bool isCanonical() const;
735 bool isCanonicalAsParam() const;
736
737 /// Return true if this QualType doesn't point to a type yet.
738 bool isNull() const {
739 return Value.getPointer().isNull();
22
Calling 'PointerUnion::isNull'
25
Returning from 'PointerUnion::isNull'
26
Returning the value 1, which participates in a condition later
740 }
741
742 /// Determine whether this particular QualType instance has the
743 /// "const" qualifier set, without looking through typedefs that may have
744 /// added "const" at a different level.
745 bool isLocalConstQualified() const {
746 return (getLocalFastQualifiers() & Qualifiers::Const);
747 }
748
749 /// Determine whether this type is const-qualified.
750 bool isConstQualified() const;
751
752 /// Determine whether this particular QualType instance has the
753 /// "restrict" qualifier set, without looking through typedefs that may have
754 /// added "restrict" at a different level.
755 bool isLocalRestrictQualified() const {
756 return (getLocalFastQualifiers() & Qualifiers::Restrict);
757 }
758
759 /// Determine whether this type is restrict-qualified.
760 bool isRestrictQualified() const;
761
762 /// Determine whether this particular QualType instance has the
763 /// "volatile" qualifier set, without looking through typedefs that may have
764 /// added "volatile" at a different level.
765 bool isLocalVolatileQualified() const {
766 return (getLocalFastQualifiers() & Qualifiers::Volatile);
767 }
768
769 /// Determine whether this type is volatile-qualified.
770 bool isVolatileQualified() const;
771
772 /// Determine whether this particular QualType instance has any
773 /// qualifiers, without looking through any typedefs that might add
774 /// qualifiers at a different level.
775 bool hasLocalQualifiers() const {
776 return getLocalFastQualifiers() || hasLocalNonFastQualifiers();
777 }
778
779 /// Determine whether this type has any qualifiers.
780 bool hasQualifiers() const;
781
782 /// Determine whether this particular QualType instance has any
783 /// "non-fast" qualifiers, e.g., those that are stored in an ExtQualType
784 /// instance.
785 bool hasLocalNonFastQualifiers() const {
786 return Value.getPointer().is<const ExtQuals*>();
787 }
788
789 /// Retrieve the set of qualifiers local to this particular QualType
790 /// instance, not including any qualifiers acquired through typedefs or
791 /// other sugar.
792 Qualifiers getLocalQualifiers() const;
793
794 /// Retrieve the set of qualifiers applied to this type.
795 Qualifiers getQualifiers() const;
796
797 /// Retrieve the set of CVR (const-volatile-restrict) qualifiers
798 /// local to this particular QualType instance, not including any qualifiers
799 /// acquired through typedefs or other sugar.
800 unsigned getLocalCVRQualifiers() const {
801 return getLocalFastQualifiers();
802 }
803
804 /// Retrieve the set of CVR (const-volatile-restrict) qualifiers
805 /// applied to this type.
806 unsigned getCVRQualifiers() const;
807
808 bool isConstant(const ASTContext& Ctx) const {
809 return QualType::isConstant(*this, Ctx);
810 }
811
812 /// Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
813 bool isPODType(const ASTContext &Context) const;
814
815 /// Return true if this is a POD type according to the rules of the C++98
816 /// standard, regardless of the current compilation's language.
817 bool isCXX98PODType(const ASTContext &Context) const;
818
819 /// Return true if this is a POD type according to the more relaxed rules
820 /// of the C++11 standard, regardless of the current compilation's language.
821 /// (C++0x [basic.types]p9). Note that, unlike
822 /// CXXRecordDecl::isCXX11StandardLayout, this takes DRs into account.
823 bool isCXX11PODType(const ASTContext &Context) const;
824
825 /// Return true if this is a trivial type per (C++0x [basic.types]p9)
826 bool isTrivialType(const ASTContext &Context) const;
827
828 /// Return true if this is a trivially copyable type (C++0x [basic.types]p9)
829 bool isTriviallyCopyableType(const ASTContext &Context) const;
830
831
832 /// Returns true if it is a class and it might be dynamic.
833 bool mayBeDynamicClass() const;
834
835 /// Returns true if it is not a class or if the class might not be dynamic.
836 bool mayBeNotDynamicClass() const;
837
838 // Don't promise in the API that anything besides 'const' can be
839 // easily added.
840
841 /// Add the `const` type qualifier to this QualType.
842 void addConst() {
843 addFastQualifiers(Qualifiers::Const);
844 }
845 QualType withConst() const {
846 return withFastQualifiers(Qualifiers::Const);
847 }
848
849 /// Add the `volatile` type qualifier to this QualType.
850 void addVolatile() {
851 addFastQualifiers(Qualifiers::Volatile);
852 }
853 QualType withVolatile() const {
854 return withFastQualifiers(Qualifiers::Volatile);
855 }
856
857 /// Add the `restrict` qualifier to this QualType.
858 void addRestrict() {
859 addFastQualifiers(Qualifiers::Restrict);
860 }
861 QualType withRestrict() const {
862 return withFastQualifiers(Qualifiers::Restrict);
863 }
864
865 QualType withCVRQualifiers(unsigned CVR) const {
866 return withFastQualifiers(CVR);
867 }
868
869 void addFastQualifiers(unsigned TQs) {
870 assert(!(TQs & ~Qualifiers::FastMask)(static_cast<void> (0))
871 && "non-fast qualifier bits set in mask!")(static_cast<void> (0));
872 Value.setInt(Value.getInt() | TQs);
873 }
874
875 void removeLocalConst();
876 void removeLocalVolatile();
877 void removeLocalRestrict();
878 void removeLocalCVRQualifiers(unsigned Mask);
879
880 void removeLocalFastQualifiers() { Value.setInt(0); }
881 void removeLocalFastQualifiers(unsigned Mask) {
882 assert(!(Mask & ~Qualifiers::FastMask) && "mask has non-fast qualifiers")(static_cast<void> (0));
883 Value.setInt(Value.getInt() & ~Mask);
884 }
885
886 // Creates a type with the given qualifiers in addition to any
887 // qualifiers already on this type.
888 QualType withFastQualifiers(unsigned TQs) const {
889 QualType T = *this;
890 T.addFastQualifiers(TQs);
891 return T;
892 }
893
894 // Creates a type with exactly the given fast qualifiers, removing
895 // any existing fast qualifiers.
896 QualType withExactLocalFastQualifiers(unsigned TQs) const {
897 return withoutLocalFastQualifiers().withFastQualifiers(TQs);
898 }
899
900 // Removes fast qualifiers, but leaves any extended qualifiers in place.
901 QualType withoutLocalFastQualifiers() const {
902 QualType T = *this;
903 T.removeLocalFastQualifiers();
904 return T;
905 }
906
907 QualType getCanonicalType() const;
908
909 /// Return this type with all of the instance-specific qualifiers
910 /// removed, but without removing any qualifiers that may have been applied
911 /// through typedefs.
912 QualType getLocalUnqualifiedType() const { return QualType(getTypePtr(), 0); }
913
914 /// Retrieve the unqualified variant of the given type,
915 /// removing as little sugar as possible.
916 ///
917 /// This routine looks through various kinds of sugar to find the
918 /// least-desugared type that is unqualified. For example, given:
919 ///
920 /// \code
921 /// typedef int Integer;
922 /// typedef const Integer CInteger;
923 /// typedef CInteger DifferenceType;
924 /// \endcode
925 ///
926 /// Executing \c getUnqualifiedType() on the type \c DifferenceType will
927 /// desugar until we hit the type \c Integer, which has no qualifiers on it.
928 ///
929 /// The resulting type might still be qualified if it's sugar for an array
930 /// type. To strip qualifiers even from within a sugared array type, use
931 /// ASTContext::getUnqualifiedArrayType.
932 inline QualType getUnqualifiedType() const;
933
934 /// Retrieve the unqualified variant of the given type, removing as little
935 /// sugar as possible.
936 ///
937 /// Like getUnqualifiedType(), but also returns the set of
938 /// qualifiers that were built up.
939 ///
940 /// The resulting type might still be qualified if it's sugar for an array
941 /// type. To strip qualifiers even from within a sugared array type, use
942 /// ASTContext::getUnqualifiedArrayType.
943 inline SplitQualType getSplitUnqualifiedType() const;
944
945 /// Determine whether this type is more qualified than the other
946 /// given type, requiring exact equality for non-CVR qualifiers.
947 bool isMoreQualifiedThan(QualType Other) const;
948
949 /// Determine whether this type is at least as qualified as the other
950 /// given type, requiring exact equality for non-CVR qualifiers.
951 bool isAtLeastAsQualifiedAs(QualType Other) const;
952
953 QualType getNonReferenceType() const;
954
955 /// Determine the type of a (typically non-lvalue) expression with the
956 /// specified result type.
957 ///
958 /// This routine should be used for expressions for which the return type is
959 /// explicitly specified (e.g., in a cast or call) and isn't necessarily
960 /// an lvalue. It removes a top-level reference (since there are no
961 /// expressions of reference type) and deletes top-level cvr-qualifiers
962 /// from non-class types (in C++) or all types (in C).
963 QualType getNonLValueExprType(const ASTContext &Context) const;
964
965 /// Remove an outer pack expansion type (if any) from this type. Used as part
966 /// of converting the type of a declaration to the type of an expression that
967 /// references that expression. It's meaningless for an expression to have a
968 /// pack expansion type.
969 QualType getNonPackExpansionType() const;
970
971 /// Return the specified type with any "sugar" removed from
972 /// the type. This takes off typedefs, typeof's etc. If the outer level of
973 /// the type is already concrete, it returns it unmodified. This is similar
974 /// to getting the canonical type, but it doesn't remove *all* typedefs. For
975 /// example, it returns "T*" as "T*", (not as "int*"), because the pointer is
976 /// concrete.
977 ///
978 /// Qualifiers are left in place.
979 QualType getDesugaredType(const ASTContext &Context) const {
980 return getDesugaredType(*this, Context);
981 }
982
983 SplitQualType getSplitDesugaredType() const {
984 return getSplitDesugaredType(*this);
985 }
986
987 /// Return the specified type with one level of "sugar" removed from
988 /// the type.
989 ///
990 /// This routine takes off the first typedef, typeof, etc. If the outer level
991 /// of the type is already concrete, it returns it unmodified.
992 QualType getSingleStepDesugaredType(const ASTContext &Context) const {
993 return getSingleStepDesugaredTypeImpl(*this, Context);
994 }
995
996 /// Returns the specified type after dropping any
997 /// outer-level parentheses.
998 QualType IgnoreParens() const {
999 if (isa<ParenType>(*this))
1000 return QualType::IgnoreParens(*this);
1001 return *this;
1002 }
1003
1004 /// Indicate whether the specified types and qualifiers are identical.
1005 friend bool operator==(const QualType &LHS, const QualType &RHS) {
1006 return LHS.Value == RHS.Value;
1007 }
1008 friend bool operator!=(const QualType &LHS, const QualType &RHS) {
1009 return LHS.Value != RHS.Value;
1010 }
1011 friend bool operator<(const QualType &LHS, const QualType &RHS) {
1012 return LHS.Value < RHS.Value;
1013 }
1014
1015 static std::string getAsString(SplitQualType split,
1016 const PrintingPolicy &Policy) {
1017 return getAsString(split.Ty, split.Quals, Policy);
1018 }
1019 static std::string getAsString(const Type *ty, Qualifiers qs,
1020 const PrintingPolicy &Policy);
1021
1022 std::string getAsString() const;
1023 std::string getAsString(const PrintingPolicy &Policy) const;
1024
1025 void print(raw_ostream &OS, const PrintingPolicy &Policy,
1026 const Twine &PlaceHolder = Twine(),
1027 unsigned Indentation = 0) const;
1028
1029 static void print(SplitQualType split, raw_ostream &OS,
1030 const PrintingPolicy &policy, const Twine &PlaceHolder,
1031 unsigned Indentation = 0) {
1032 return print(split.Ty, split.Quals, OS, policy, PlaceHolder, Indentation);
1033 }
1034
1035 static void print(const Type *ty, Qualifiers qs,
1036 raw_ostream &OS, const PrintingPolicy &policy,
1037 const Twine &PlaceHolder,
1038 unsigned Indentation = 0);
1039
1040 void getAsStringInternal(std::string &Str,
1041 const PrintingPolicy &Policy) const;
1042
1043 static void getAsStringInternal(SplitQualType split, std::string &out,
1044 const PrintingPolicy &policy) {
1045 return getAsStringInternal(split.Ty, split.Quals, out, policy);
1046 }
1047
1048 static void getAsStringInternal(const Type *ty, Qualifiers qs,
1049 std::string &out,
1050 const PrintingPolicy &policy);
1051
1052 class StreamedQualTypeHelper {
1053 const QualType &T;
1054 const PrintingPolicy &Policy;
1055 const Twine &PlaceHolder;
1056 unsigned Indentation;
1057
1058 public:
1059 StreamedQualTypeHelper(const QualType &T, const PrintingPolicy &Policy,
1060 const Twine &PlaceHolder, unsigned Indentation)
1061 : T(T), Policy(Policy), PlaceHolder(PlaceHolder),
1062 Indentation(Indentation) {}
1063
1064 friend raw_ostream &operator<<(raw_ostream &OS,
1065 const StreamedQualTypeHelper &SQT) {
1066 SQT.T.print(OS, SQT.Policy, SQT.PlaceHolder, SQT.Indentation);
1067 return OS;
1068 }
1069 };
1070
1071 StreamedQualTypeHelper stream(const PrintingPolicy &Policy,
1072 const Twine &PlaceHolder = Twine(),
1073 unsigned Indentation = 0) const {
1074 return StreamedQualTypeHelper(*this, Policy, PlaceHolder, Indentation);
1075 }
1076
1077 void dump(const char *s) const;
1078 void dump() const;
1079 void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
1080
1081 void Profile(llvm::FoldingSetNodeID &ID) const {
1082 ID.AddPointer(getAsOpaquePtr());
1083 }
1084
1085 /// Check if this type has any address space qualifier.
1086 inline bool hasAddressSpace() const;
1087
1088 /// Return the address space of this type.
1089 inline LangAS getAddressSpace() const;
1090
1091 /// Returns true if address space qualifiers overlap with T address space
1092 /// qualifiers.
1093 /// OpenCL C defines conversion rules for pointers to different address spaces
1094 /// and notion of overlapping address spaces.
1095 /// CL1.1 or CL1.2:
1096 /// address spaces overlap iff they are they same.
1097 /// OpenCL C v2.0 s6.5.5 adds:
1098 /// __generic overlaps with any address space except for __constant.
1099 bool isAddressSpaceOverlapping(QualType T) const {
1100 Qualifiers Q = getQualifiers();
1101 Qualifiers TQ = T.getQualifiers();
1102 // Address spaces overlap if at least one of them is a superset of another
1103 return Q.isAddressSpaceSupersetOf(TQ) || TQ.isAddressSpaceSupersetOf(Q);
1104 }
1105
1106 /// Returns gc attribute of this type.
1107 inline Qualifiers::GC getObjCGCAttr() const;
1108
1109 /// true when Type is objc's weak.
1110 bool isObjCGCWeak() const {
1111 return getObjCGCAttr() == Qualifiers::Weak;
1112 }
1113
1114 /// true when Type is objc's strong.
1115 bool isObjCGCStrong() const {
1116 return getObjCGCAttr() == Qualifiers::Strong;
1117 }
1118
1119 /// Returns lifetime attribute of this type.
1120 Qualifiers::ObjCLifetime getObjCLifetime() const {
1121 return getQualifiers().getObjCLifetime();
1122 }
1123
1124 bool hasNonTrivialObjCLifetime() const {
1125 return getQualifiers().hasNonTrivialObjCLifetime();
1126 }
1127
1128 bool hasStrongOrWeakObjCLifetime() const {
1129 return getQualifiers().hasStrongOrWeakObjCLifetime();
1130 }
1131
1132 // true when Type is objc's weak and weak is enabled but ARC isn't.
1133 bool isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const;
1134
1135 enum PrimitiveDefaultInitializeKind {
1136 /// The type does not fall into any of the following categories. Note that
1137 /// this case is zero-valued so that values of this enum can be used as a
1138 /// boolean condition for non-triviality.
1139 PDIK_Trivial,
1140
1141 /// The type is an Objective-C retainable pointer type that is qualified
1142 /// with the ARC __strong qualifier.
1143 PDIK_ARCStrong,
1144
1145 /// The type is an Objective-C retainable pointer type that is qualified
1146 /// with the ARC __weak qualifier.
1147 PDIK_ARCWeak,
1148
1149 /// The type is a struct containing a field whose type is not PCK_Trivial.
1150 PDIK_Struct
1151 };
1152
1153 /// Functions to query basic properties of non-trivial C struct types.
1154
1155 /// Check if this is a non-trivial type that would cause a C struct
1156 /// transitively containing this type to be non-trivial to default initialize
1157 /// and return the kind.
1158 PrimitiveDefaultInitializeKind
1159 isNonTrivialToPrimitiveDefaultInitialize() const;
1160
1161 enum PrimitiveCopyKind {
1162 /// The type does not fall into any of the following categories. Note that
1163 /// this case is zero-valued so that values of this enum can be used as a
1164 /// boolean condition for non-triviality.
1165 PCK_Trivial,
1166
1167 /// The type would be trivial except that it is volatile-qualified. Types
1168 /// that fall into one of the other non-trivial cases may additionally be
1169 /// volatile-qualified.
1170 PCK_VolatileTrivial,
1171
1172 /// The type is an Objective-C retainable pointer type that is qualified
1173 /// with the ARC __strong qualifier.
1174 PCK_ARCStrong,
1175
1176 /// The type is an Objective-C retainable pointer type that is qualified
1177 /// with the ARC __weak qualifier.
1178 PCK_ARCWeak,
1179
1180 /// The type is a struct containing a field whose type is neither
1181 /// PCK_Trivial nor PCK_VolatileTrivial.
1182 /// Note that a C++ struct type does not necessarily match this; C++ copying
1183 /// semantics are too complex to express here, in part because they depend
1184 /// on the exact constructor or assignment operator that is chosen by
1185 /// overload resolution to do the copy.
1186 PCK_Struct
1187 };
1188
1189 /// Check if this is a non-trivial type that would cause a C struct
1190 /// transitively containing this type to be non-trivial to copy and return the
1191 /// kind.
1192 PrimitiveCopyKind isNonTrivialToPrimitiveCopy() const;
1193
1194 /// Check if this is a non-trivial type that would cause a C struct
1195 /// transitively containing this type to be non-trivial to destructively
1196 /// move and return the kind. Destructive move in this context is a C++-style
1197 /// move in which the source object is placed in a valid but unspecified state
1198 /// after it is moved, as opposed to a truly destructive move in which the
1199 /// source object is placed in an uninitialized state.
1200 PrimitiveCopyKind isNonTrivialToPrimitiveDestructiveMove() const;
1201
1202 enum DestructionKind {
1203 DK_none,
1204 DK_cxx_destructor,
1205 DK_objc_strong_lifetime,
1206 DK_objc_weak_lifetime,
1207 DK_nontrivial_c_struct
1208 };
1209
1210 /// Returns a nonzero value if objects of this type require
1211 /// non-trivial work to clean up after. Non-zero because it's
1212 /// conceivable that qualifiers (objc_gc(weak)?) could make
1213 /// something require destruction.
1214 DestructionKind isDestructedType() const {
1215 return isDestructedTypeImpl(*this);
1216 }
1217
1218 /// Check if this is or contains a C union that is non-trivial to
1219 /// default-initialize, which is a union that has a member that is non-trivial
1220 /// to default-initialize. If this returns true,
1221 /// isNonTrivialToPrimitiveDefaultInitialize returns PDIK_Struct.
1222 bool hasNonTrivialToPrimitiveDefaultInitializeCUnion() const;
1223
1224 /// Check if this is or contains a C union that is non-trivial to destruct,
1225 /// which is a union that has a member that is non-trivial to destruct. If
1226 /// this returns true, isDestructedType returns DK_nontrivial_c_struct.
1227 bool hasNonTrivialToPrimitiveDestructCUnion() const;
1228
1229 /// Check if this is or contains a C union that is non-trivial to copy, which
1230 /// is a union that has a member that is non-trivial to copy. If this returns
1231 /// true, isNonTrivialToPrimitiveCopy returns PCK_Struct.
1232 bool hasNonTrivialToPrimitiveCopyCUnion() const;
1233
1234 /// Determine whether expressions of the given type are forbidden
1235 /// from being lvalues in C.
1236 ///
1237 /// The expression types that are forbidden to be lvalues are:
1238 /// - 'void', but not qualified void
1239 /// - function types
1240 ///
1241 /// The exact rule here is C99 6.3.2.1:
1242 /// An lvalue is an expression with an object type or an incomplete
1243 /// type other than void.
1244 bool isCForbiddenLValueType() const;
1245
1246 /// Substitute type arguments for the Objective-C type parameters used in the
1247 /// subject type.
1248 ///
1249 /// \param ctx ASTContext in which the type exists.
1250 ///
1251 /// \param typeArgs The type arguments that will be substituted for the
1252 /// Objective-C type parameters in the subject type, which are generally
1253 /// computed via \c Type::getObjCSubstitutions. If empty, the type
1254 /// parameters will be replaced with their bounds or id/Class, as appropriate
1255 /// for the context.
1256 ///
1257 /// \param context The context in which the subject type was written.
1258 ///
1259 /// \returns the resulting type.
1260 QualType substObjCTypeArgs(ASTContext &ctx,
1261 ArrayRef<QualType> typeArgs,
1262 ObjCSubstitutionContext context) const;
1263
1264 /// Substitute type arguments from an object type for the Objective-C type
1265 /// parameters used in the subject type.
1266 ///
1267 /// This operation combines the computation of type arguments for
1268 /// substitution (\c Type::getObjCSubstitutions) with the actual process of
1269 /// substitution (\c QualType::substObjCTypeArgs) for the convenience of
1270 /// callers that need to perform a single substitution in isolation.
1271 ///
1272 /// \param objectType The type of the object whose member type we're
1273 /// substituting into. For example, this might be the receiver of a message
1274 /// or the base of a property access.
1275 ///
1276 /// \param dc The declaration context from which the subject type was
1277 /// retrieved, which indicates (for example) which type parameters should
1278 /// be substituted.
1279 ///
1280 /// \param context The context in which the subject type was written.
1281 ///
1282 /// \returns the subject type after replacing all of the Objective-C type
1283 /// parameters with their corresponding arguments.
1284 QualType substObjCMemberType(QualType objectType,
1285 const DeclContext *dc,
1286 ObjCSubstitutionContext context) const;
1287
1288 /// Strip Objective-C "__kindof" types from the given type.
1289 QualType stripObjCKindOfType(const ASTContext &ctx) const;
1290
1291 /// Remove all qualifiers including _Atomic.
1292 QualType getAtomicUnqualifiedType() const;
1293
1294private:
1295 // These methods are implemented in a separate translation unit;
1296 // "static"-ize them to avoid creating temporary QualTypes in the
1297 // caller.
1298 static bool isConstant(QualType T, const ASTContext& Ctx);
1299 static QualType getDesugaredType(QualType T, const ASTContext &Context);
1300 static SplitQualType getSplitDesugaredType(QualType T);
1301 static SplitQualType getSplitUnqualifiedTypeImpl(QualType type);
1302 static QualType getSingleStepDesugaredTypeImpl(QualType type,
1303 const ASTContext &C);
1304 static QualType IgnoreParens(QualType T);
1305 static DestructionKind isDestructedTypeImpl(QualType type);
1306
1307 /// Check if \param RD is or contains a non-trivial C union.
1308 static bool hasNonTrivialToPrimitiveDefaultInitializeCUnion(const RecordDecl *RD);
1309 static bool hasNonTrivialToPrimitiveDestructCUnion(const RecordDecl *RD);
1310 static bool hasNonTrivialToPrimitiveCopyCUnion(const RecordDecl *RD);
1311};
1312
1313} // namespace clang
1314
1315namespace llvm {
1316
1317/// Implement simplify_type for QualType, so that we can dyn_cast from QualType
1318/// to a specific Type class.
1319template<> struct simplify_type< ::clang::QualType> {
1320 using SimpleType = const ::clang::Type *;
1321
1322 static SimpleType getSimplifiedValue(::clang::QualType Val) {
1323 return Val.getTypePtr();
1324 }
1325};
1326
1327// Teach SmallPtrSet that QualType is "basically a pointer".
1328template<>
1329struct PointerLikeTypeTraits<clang::QualType> {
1330 static inline void *getAsVoidPointer(clang::QualType P) {
1331 return P.getAsOpaquePtr();
1332 }
1333
1334 static inline clang::QualType getFromVoidPointer(void *P) {
1335 return clang::QualType::getFromOpaquePtr(P);
1336 }
1337
1338 // Various qualifiers go in low bits.
1339 static constexpr int NumLowBitsAvailable = 0;
1340};
1341
1342} // namespace llvm
1343
1344namespace clang {
1345
1346/// Base class that is common to both the \c ExtQuals and \c Type
1347/// classes, which allows \c QualType to access the common fields between the
1348/// two.
1349class ExtQualsTypeCommonBase {
1350 friend class ExtQuals;
1351 friend class QualType;
1352 friend class Type;
1353
1354 /// The "base" type of an extended qualifiers type (\c ExtQuals) or
1355 /// a self-referential pointer (for \c Type).
1356 ///
1357 /// This pointer allows an efficient mapping from a QualType to its
1358 /// underlying type pointer.
1359 const Type *const BaseType;
1360
1361 /// The canonical type of this type. A QualType.
1362 QualType CanonicalType;
1363
1364 ExtQualsTypeCommonBase(const Type *baseType, QualType canon)
1365 : BaseType(baseType), CanonicalType(canon) {}
1366};
1367
1368/// We can encode up to four bits in the low bits of a
1369/// type pointer, but there are many more type qualifiers that we want
1370/// to be able to apply to an arbitrary type. Therefore we have this
1371/// struct, intended to be heap-allocated and used by QualType to
1372/// store qualifiers.
1373///
1374/// The current design tags the 'const', 'restrict', and 'volatile' qualifiers
1375/// in three low bits on the QualType pointer; a fourth bit records whether
1376/// the pointer is an ExtQuals node. The extended qualifiers (address spaces,
1377/// Objective-C GC attributes) are much more rare.
1378class ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode {
1379 // NOTE: changing the fast qualifiers should be straightforward as
1380 // long as you don't make 'const' non-fast.
1381 // 1. Qualifiers:
1382 // a) Modify the bitmasks (Qualifiers::TQ and DeclSpec::TQ).
1383 // Fast qualifiers must occupy the low-order bits.
1384 // b) Update Qualifiers::FastWidth and FastMask.
1385 // 2. QualType:
1386 // a) Update is{Volatile,Restrict}Qualified(), defined inline.
1387 // b) Update remove{Volatile,Restrict}, defined near the end of
1388 // this header.
1389 // 3. ASTContext:
1390 // a) Update get{Volatile,Restrict}Type.
1391
1392 /// The immutable set of qualifiers applied by this node. Always contains
1393 /// extended qualifiers.
1394 Qualifiers Quals;
1395
1396 ExtQuals *this_() { return this; }
1397
1398public:
1399 ExtQuals(const Type *baseType, QualType canon, Qualifiers quals)
1400 : ExtQualsTypeCommonBase(baseType,
1401 canon.isNull() ? QualType(this_(), 0) : canon),
1402 Quals(quals) {
1403 assert(Quals.hasNonFastQualifiers()(static_cast<void> (0))
1404 && "ExtQuals created with no fast qualifiers")(static_cast<void> (0));
1405 assert(!Quals.hasFastQualifiers()(static_cast<void> (0))
1406 && "ExtQuals created with fast qualifiers")(static_cast<void> (0));
1407 }
1408
1409 Qualifiers getQualifiers() const { return Quals; }
1410
1411 bool hasObjCGCAttr() const { return Quals.hasObjCGCAttr(); }
1412 Qualifiers::GC getObjCGCAttr() const { return Quals.getObjCGCAttr(); }
1413
1414 bool hasObjCLifetime() const { return Quals.hasObjCLifetime(); }
1415 Qualifiers::ObjCLifetime getObjCLifetime() const {
1416 return Quals.getObjCLifetime();
1417 }
1418
1419 bool hasAddressSpace() const { return Quals.hasAddressSpace(); }
1420 LangAS getAddressSpace() const { return Quals.getAddressSpace(); }
1421
1422 const Type *getBaseType() const { return BaseType; }
1423
1424public:
1425 void Profile(llvm::FoldingSetNodeID &ID) const {
1426 Profile(ID, getBaseType(), Quals);
1427 }
1428
1429 static void Profile(llvm::FoldingSetNodeID &ID,
1430 const Type *BaseType,
1431 Qualifiers Quals) {
1432 assert(!Quals.hasFastQualifiers() && "fast qualifiers in ExtQuals hash!")(static_cast<void> (0));
1433 ID.AddPointer(BaseType);
1434 Quals.Profile(ID);
1435 }
1436};
1437
1438/// The kind of C++11 ref-qualifier associated with a function type.
1439/// This determines whether a member function's "this" object can be an
1440/// lvalue, rvalue, or neither.
1441enum RefQualifierKind {
1442 /// No ref-qualifier was provided.
1443 RQ_None = 0,
1444
1445 /// An lvalue ref-qualifier was provided (\c &).
1446 RQ_LValue,
1447
1448 /// An rvalue ref-qualifier was provided (\c &&).
1449 RQ_RValue
1450};
1451
1452/// Which keyword(s) were used to create an AutoType.
1453enum class AutoTypeKeyword {
1454 /// auto
1455 Auto,
1456
1457 /// decltype(auto)
1458 DecltypeAuto,
1459
1460 /// __auto_type (GNU extension)
1461 GNUAutoType
1462};
1463
1464/// The base class of the type hierarchy.
1465///
1466/// A central concept with types is that each type always has a canonical
1467/// type. A canonical type is the type with any typedef names stripped out
1468/// of it or the types it references. For example, consider:
1469///
1470/// typedef int foo;
1471/// typedef foo* bar;
1472/// 'int *' 'foo *' 'bar'
1473///
1474/// There will be a Type object created for 'int'. Since int is canonical, its
1475/// CanonicalType pointer points to itself. There is also a Type for 'foo' (a
1476/// TypedefType). Its CanonicalType pointer points to the 'int' Type. Next
1477/// there is a PointerType that represents 'int*', which, like 'int', is
1478/// canonical. Finally, there is a PointerType type for 'foo*' whose canonical
1479/// type is 'int*', and there is a TypedefType for 'bar', whose canonical type
1480/// is also 'int*'.
1481///
1482/// Non-canonical types are useful for emitting diagnostics, without losing
1483/// information about typedefs being used. Canonical types are useful for type
1484/// comparisons (they allow by-pointer equality tests) and useful for reasoning
1485/// about whether something has a particular form (e.g. is a function type),
1486/// because they implicitly, recursively, strip all typedefs out of a type.
1487///
1488/// Types, once created, are immutable.
1489///
1490class alignas(8) Type : public ExtQualsTypeCommonBase {
1491public:
1492 enum TypeClass {
1493#define TYPE(Class, Base) Class,
1494#define LAST_TYPE(Class) TypeLast = Class
1495#define ABSTRACT_TYPE(Class, Base)
1496#include "clang/AST/TypeNodes.inc"
1497 };
1498
1499private:
1500 /// Bitfields required by the Type class.
1501 class TypeBitfields {
1502 friend class Type;
1503 template <class T> friend class TypePropertyCache;
1504
1505 /// TypeClass bitfield - Enum that specifies what subclass this belongs to.
1506 unsigned TC : 8;
1507
1508 /// Store information on the type dependency.
1509 unsigned Dependence : llvm::BitWidth<TypeDependence>;
1510
1511 /// True if the cache (i.e. the bitfields here starting with
1512 /// 'Cache') is valid.
1513 mutable unsigned CacheValid : 1;
1514
1515 /// Linkage of this type.
1516 mutable unsigned CachedLinkage : 3;
1517
1518 /// Whether this type involves and local or unnamed types.
1519 mutable unsigned CachedLocalOrUnnamed : 1;
1520
1521 /// Whether this type comes from an AST file.
1522 mutable unsigned FromAST : 1;
1523
1524 bool isCacheValid() const {
1525 return CacheValid;
1526 }
1527
1528 Linkage getLinkage() const {
1529 assert(isCacheValid() && "getting linkage from invalid cache")(static_cast<void> (0));
1530 return static_cast<Linkage>(CachedLinkage);
1531 }
1532
1533 bool hasLocalOrUnnamedType() const {
1534 assert(isCacheValid() && "getting linkage from invalid cache")(static_cast<void> (0));
1535 return CachedLocalOrUnnamed;
1536 }
1537 };
1538 enum { NumTypeBits = 8 + llvm::BitWidth<TypeDependence> + 6 };
1539
1540protected:
1541 // These classes allow subclasses to somewhat cleanly pack bitfields
1542 // into Type.
1543
1544 class ArrayTypeBitfields {
1545 friend class ArrayType;
1546
1547 unsigned : NumTypeBits;
1548
1549 /// CVR qualifiers from declarations like
1550 /// 'int X[static restrict 4]'. For function parameters only.
1551 unsigned IndexTypeQuals : 3;
1552
1553 /// Storage class qualifiers from declarations like
1554 /// 'int X[static restrict 4]'. For function parameters only.
1555 /// Actually an ArrayType::ArraySizeModifier.
1556 unsigned SizeModifier : 3;
1557 };
1558
1559 class ConstantArrayTypeBitfields {
1560 friend class ConstantArrayType;
1561
1562 unsigned : NumTypeBits + 3 + 3;
1563
1564 /// Whether we have a stored size expression.
1565 unsigned HasStoredSizeExpr : 1;
1566 };
1567
1568 class BuiltinTypeBitfields {
1569 friend class BuiltinType;
1570
1571 unsigned : NumTypeBits;
1572
1573 /// The kind (BuiltinType::Kind) of builtin type this is.
1574 unsigned Kind : 8;
1575 };
1576
1577 /// FunctionTypeBitfields store various bits belonging to FunctionProtoType.
1578 /// Only common bits are stored here. Additional uncommon bits are stored
1579 /// in a trailing object after FunctionProtoType.
1580 class FunctionTypeBitfields {
1581 friend class FunctionProtoType;
1582 friend class FunctionType;
1583
1584 unsigned : NumTypeBits;
1585
1586 /// Extra information which affects how the function is called, like
1587 /// regparm and the calling convention.
1588 unsigned ExtInfo : 13;
1589
1590 /// The ref-qualifier associated with a \c FunctionProtoType.
1591 ///
1592 /// This is a value of type \c RefQualifierKind.
1593 unsigned RefQualifier : 2;
1594
1595 /// Used only by FunctionProtoType, put here to pack with the
1596 /// other bitfields.
1597 /// The qualifiers are part of FunctionProtoType because...
1598 ///
1599 /// C++ 8.3.5p4: The return type, the parameter type list and the
1600 /// cv-qualifier-seq, [...], are part of the function type.
1601 unsigned FastTypeQuals : Qualifiers::FastWidth;
1602 /// Whether this function has extended Qualifiers.
1603 unsigned HasExtQuals : 1;
1604
1605 /// The number of parameters this function has, not counting '...'.
1606 /// According to [implimits] 8 bits should be enough here but this is
1607 /// somewhat easy to exceed with metaprogramming and so we would like to
1608 /// keep NumParams as wide as reasonably possible.
1609 unsigned NumParams : 16;
1610
1611 /// The type of exception specification this function has.
1612 unsigned ExceptionSpecType : 4;
1613
1614 /// Whether this function has extended parameter information.
1615 unsigned HasExtParameterInfos : 1;
1616
1617 /// Whether the function is variadic.
1618 unsigned Variadic : 1;
1619
1620 /// Whether this function has a trailing return type.
1621 unsigned HasTrailingReturn : 1;
1622 };
1623
1624 class ObjCObjectTypeBitfields {
1625 friend class ObjCObjectType;
1626
1627 unsigned : NumTypeBits;
1628
1629 /// The number of type arguments stored directly on this object type.
1630 unsigned NumTypeArgs : 7;
1631
1632 /// The number of protocols stored directly on this object type.
1633 unsigned NumProtocols : 6;
1634
1635 /// Whether this is a "kindof" type.
1636 unsigned IsKindOf : 1;
1637 };
1638
1639 class ReferenceTypeBitfields {
1640 friend class ReferenceType;
1641
1642 unsigned : NumTypeBits;
1643
1644 /// True if the type was originally spelled with an lvalue sigil.
1645 /// This is never true of rvalue references but can also be false
1646 /// on lvalue references because of C++0x [dcl.typedef]p9,
1647 /// as follows:
1648 ///
1649 /// typedef int &ref; // lvalue, spelled lvalue
1650 /// typedef int &&rvref; // rvalue
1651 /// ref &a; // lvalue, inner ref, spelled lvalue
1652 /// ref &&a; // lvalue, inner ref
1653 /// rvref &a; // lvalue, inner ref, spelled lvalue
1654 /// rvref &&a; // rvalue, inner ref
1655 unsigned SpelledAsLValue : 1;
1656
1657 /// True if the inner type is a reference type. This only happens
1658 /// in non-canonical forms.
1659 unsigned InnerRef : 1;
1660 };
1661
1662 class TypeWithKeywordBitfields {
1663 friend class TypeWithKeyword;
1664
1665 unsigned : NumTypeBits;
1666
1667 /// An ElaboratedTypeKeyword. 8 bits for efficient access.
1668 unsigned Keyword : 8;
1669 };
1670
1671 enum { NumTypeWithKeywordBits = 8 };
1672
1673 class ElaboratedTypeBitfields {
1674 friend class ElaboratedType;
1675
1676 unsigned : NumTypeBits;
1677 unsigned : NumTypeWithKeywordBits;
1678
1679 /// Whether the ElaboratedType has a trailing OwnedTagDecl.
1680 unsigned HasOwnedTagDecl : 1;
1681 };
1682
1683 class VectorTypeBitfields {
1684 friend class VectorType;
1685 friend class DependentVectorType;
1686
1687 unsigned : NumTypeBits;
1688
1689 /// The kind of vector, either a generic vector type or some
1690 /// target-specific vector type such as for AltiVec or Neon.
1691 unsigned VecKind : 3;
1692 /// The number of elements in the vector.
1693 uint32_t NumElements;
1694 };
1695
1696 class AttributedTypeBitfields {
1697 friend class AttributedType;
1698
1699 unsigned : NumTypeBits;
1700
1701 /// An AttributedType::Kind
1702 unsigned AttrKind : 32 - NumTypeBits;
1703 };
1704
1705 class AutoTypeBitfields {
1706 friend class AutoType;
1707
1708 unsigned : NumTypeBits;
1709
1710 /// Was this placeholder type spelled as 'auto', 'decltype(auto)',
1711 /// or '__auto_type'? AutoTypeKeyword value.
1712 unsigned Keyword : 2;
1713
1714 /// The number of template arguments in the type-constraints, which is
1715 /// expected to be able to hold at least 1024 according to [implimits].
1716 /// However as this limit is somewhat easy to hit with template
1717 /// metaprogramming we'd prefer to keep it as large as possible.
1718 /// At the moment it has been left as a non-bitfield since this type
1719 /// safely fits in 64 bits as an unsigned, so there is no reason to
1720 /// introduce the performance impact of a bitfield.
1721 unsigned NumArgs;
1722 };
1723
1724 class SubstTemplateTypeParmPackTypeBitfields {
1725 friend class SubstTemplateTypeParmPackType;
1726
1727 unsigned : NumTypeBits;
1728
1729 /// The number of template arguments in \c Arguments, which is
1730 /// expected to be able to hold at least 1024 according to [implimits].
1731 /// However as this limit is somewhat easy to hit with template
1732 /// metaprogramming we'd prefer to keep it as large as possible.
1733 /// At the moment it has been left as a non-bitfield since this type
1734 /// safely fits in 64 bits as an unsigned, so there is no reason to
1735 /// introduce the performance impact of a bitfield.
1736 unsigned NumArgs;
1737 };
1738
1739 class TemplateSpecializationTypeBitfields {
1740 friend class TemplateSpecializationType;
1741
1742 unsigned : NumTypeBits;
1743
1744 /// Whether this template specialization type is a substituted type alias.
1745 unsigned TypeAlias : 1;
1746
1747 /// The number of template arguments named in this class template
1748 /// specialization, which is expected to be able to hold at least 1024
1749 /// according to [implimits]. However, as this limit is somewhat easy to
1750 /// hit with template metaprogramming we'd prefer to keep it as large
1751 /// as possible. At the moment it has been left as a non-bitfield since
1752 /// this type safely fits in 64 bits as an unsigned, so there is no reason
1753 /// to introduce the performance impact of a bitfield.
1754 unsigned NumArgs;
1755 };
1756
1757 class DependentTemplateSpecializationTypeBitfields {
1758 friend class DependentTemplateSpecializationType;
1759
1760 unsigned : NumTypeBits;
1761 unsigned : NumTypeWithKeywordBits;
1762
1763 /// The number of template arguments named in this class template
1764 /// specialization, which is expected to be able to hold at least 1024
1765 /// according to [implimits]. However, as this limit is somewhat easy to
1766 /// hit with template metaprogramming we'd prefer to keep it as large
1767 /// as possible. At the moment it has been left as a non-bitfield since
1768 /// this type safely fits in 64 bits as an unsigned, so there is no reason
1769 /// to introduce the performance impact of a bitfield.
1770 unsigned NumArgs;
1771 };
1772
1773 class PackExpansionTypeBitfields {
1774 friend class PackExpansionType;
1775
1776 unsigned : NumTypeBits;
1777
1778 /// The number of expansions that this pack expansion will
1779 /// generate when substituted (+1), which is expected to be able to
1780 /// hold at least 1024 according to [implimits]. However, as this limit
1781 /// is somewhat easy to hit with template metaprogramming we'd prefer to
1782 /// keep it as large as possible. At the moment it has been left as a
1783 /// non-bitfield since this type safely fits in 64 bits as an unsigned, so
1784 /// there is no reason to introduce the performance impact of a bitfield.
1785 ///
1786 /// This field will only have a non-zero value when some of the parameter
1787 /// packs that occur within the pattern have been substituted but others
1788 /// have not.
1789 unsigned NumExpansions;
1790 };
1791
1792 union {
1793 TypeBitfields TypeBits;
1794 ArrayTypeBitfields ArrayTypeBits;
1795 ConstantArrayTypeBitfields ConstantArrayTypeBits;
1796 AttributedTypeBitfields AttributedTypeBits;
1797 AutoTypeBitfields AutoTypeBits;
1798 BuiltinTypeBitfields BuiltinTypeBits;
1799 FunctionTypeBitfields FunctionTypeBits;
1800 ObjCObjectTypeBitfields ObjCObjectTypeBits;
1801 ReferenceTypeBitfields ReferenceTypeBits;
1802 TypeWithKeywordBitfields TypeWithKeywordBits;
1803 ElaboratedTypeBitfields ElaboratedTypeBits;
1804 VectorTypeBitfields VectorTypeBits;
1805 SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits;
1806 TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
1807 DependentTemplateSpecializationTypeBitfields
1808 DependentTemplateSpecializationTypeBits;
1809 PackExpansionTypeBitfields PackExpansionTypeBits;
1810 };
1811
1812private:
1813 template <class T> friend class TypePropertyCache;
1814
1815 /// Set whether this type comes from an AST file.
1816 void setFromAST(bool V = true) const {
1817 TypeBits.FromAST = V;
1818 }
1819
1820protected:
1821 friend class ASTContext;
1822
1823 Type(TypeClass tc, QualType canon, TypeDependence Dependence)
1824 : ExtQualsTypeCommonBase(this,
1825 canon.isNull() ? QualType(this_(), 0) : canon) {
1826 static_assert(sizeof(*this) <= 8 + sizeof(ExtQualsTypeCommonBase),
1827 "changing bitfields changed sizeof(Type)!");
1828 static_assert(alignof(decltype(*this)) % sizeof(void *) == 0,
1829 "Insufficient alignment!");
1830 TypeBits.TC = tc;
1831 TypeBits.Dependence = static_cast<unsigned>(Dependence);
1832 TypeBits.CacheValid = false;
1833 TypeBits.CachedLocalOrUnnamed = false;
1834 TypeBits.CachedLinkage = NoLinkage;
1835 TypeBits.FromAST = false;
1836 }
1837
1838 // silence VC++ warning C4355: 'this' : used in base member initializer list
1839 Type *this_() { return this; }
1840
1841 void setDependence(TypeDependence D) {
1842 TypeBits.Dependence = static_cast<unsigned>(D);
1843 }
1844
1845 void addDependence(TypeDependence D) { setDependence(getDependence() | D); }
1846
1847public:
1848 friend class ASTReader;
1849 friend class ASTWriter;
1850 template <class T> friend class serialization::AbstractTypeReader;
1851 template <class T> friend class serialization::AbstractTypeWriter;
1852
1853 Type(const Type &) = delete;
1854 Type(Type &&) = delete;
1855 Type &operator=(const Type &) = delete;
1856 Type &operator=(Type &&) = delete;
1857
1858 TypeClass getTypeClass() const { return static_cast<TypeClass>(TypeBits.TC); }
1859
1860 /// Whether this type comes from an AST file.
1861 bool isFromAST() const { return TypeBits.FromAST; }
1862
1863 /// Whether this type is or contains an unexpanded parameter
1864 /// pack, used to support C++0x variadic templates.
1865 ///
1866 /// A type that contains a parameter pack shall be expanded by the
1867 /// ellipsis operator at some point. For example, the typedef in the
1868 /// following example contains an unexpanded parameter pack 'T':
1869 ///
1870 /// \code
1871 /// template<typename ...T>
1872 /// struct X {
1873 /// typedef T* pointer_types; // ill-formed; T is a parameter pack.
1874 /// };
1875 /// \endcode
1876 ///
1877 /// Note that this routine does not specify which
1878 bool containsUnexpandedParameterPack() const {
1879 return getDependence() & TypeDependence::UnexpandedPack;
1880 }
1881
1882 /// Determines if this type would be canonical if it had no further
1883 /// qualification.
1884 bool isCanonicalUnqualified() const {
1885 return CanonicalType == QualType(this, 0);
1886 }
1887
1888 /// Pull a single level of sugar off of this locally-unqualified type.
1889 /// Users should generally prefer SplitQualType::getSingleStepDesugaredType()
1890 /// or QualType::getSingleStepDesugaredType(const ASTContext&).
1891 QualType getLocallyUnqualifiedSingleStepDesugaredType() const;
1892
1893 /// As an extension, we classify types as one of "sized" or "sizeless";
1894 /// every type is one or the other. Standard types are all sized;
1895 /// sizeless types are purely an extension.
1896 ///
1897 /// Sizeless types contain data with no specified size, alignment,
1898 /// or layout.
1899 bool isSizelessType() const;
1900 bool isSizelessBuiltinType() const;
1901
1902 /// Determines if this is a sizeless type supported by the
1903 /// 'arm_sve_vector_bits' type attribute, which can be applied to a single
1904 /// SVE vector or predicate, excluding tuple types such as svint32x4_t.
1905 bool isVLSTBuiltinType() const;
1906
1907 /// Returns the representative type for the element of an SVE builtin type.
1908 /// This is used to represent fixed-length SVE vectors created with the
1909 /// 'arm_sve_vector_bits' type attribute as VectorType.
1910 QualType getSveEltType(const ASTContext &Ctx) const;
1911
1912 /// Types are partitioned into 3 broad categories (C99 6.2.5p1):
1913 /// object types, function types, and incomplete types.
1914
1915 /// Return true if this is an incomplete type.
1916 /// A type that can describe objects, but which lacks information needed to
1917 /// determine its size (e.g. void, or a fwd declared struct). Clients of this
1918 /// routine will need to determine if the size is actually required.
1919 ///
1920 /// Def If non-null, and the type refers to some kind of declaration
1921 /// that can be completed (such as a C struct, C++ class, or Objective-C
1922 /// class), will be set to the declaration.
1923 bool isIncompleteType(NamedDecl **Def = nullptr) const;
1924
1925 /// Return true if this is an incomplete or object
1926 /// type, in other words, not a function type.
1927 bool isIncompleteOrObjectType() const {
1928 return !isFunctionType();
1929 }
1930
1931 /// Determine whether this type is an object type.
1932 bool isObjectType() const {
1933 // C++ [basic.types]p8:
1934 // An object type is a (possibly cv-qualified) type that is not a
1935 // function type, not a reference type, and not a void type.
1936 return !isReferenceType() && !isFunctionType() && !isVoidType();
1937 }
1938
1939 /// Return true if this is a literal type
1940 /// (C++11 [basic.types]p10)
1941 bool isLiteralType(const ASTContext &Ctx) const;
1942
1943 /// Determine if this type is a structural type, per C++20 [temp.param]p7.
1944 bool isStructuralType() const;
1945
1946 /// Test if this type is a standard-layout type.
1947 /// (C++0x [basic.type]p9)
1948 bool isStandardLayoutType() const;
1949
1950 /// Helper methods to distinguish type categories. All type predicates
1951 /// operate on the canonical type, ignoring typedefs and qualifiers.
1952
1953 /// Returns true if the type is a builtin type.
1954 bool isBuiltinType() const;
1955
1956 /// Test for a particular builtin type.
1957 bool isSpecificBuiltinType(unsigned K) const;
1958
1959 /// Test for a type which does not represent an actual type-system type but
1960 /// is instead used as a placeholder for various convenient purposes within
1961 /// Clang. All such types are BuiltinTypes.
1962 bool isPlaceholderType() const;
1963 const BuiltinType *getAsPlaceholderType() const;
1964
1965 /// Test for a specific placeholder type.
1966 bool isSpecificPlaceholderType(unsigned K) const;
1967
1968 /// Test for a placeholder type other than Overload; see
1969 /// BuiltinType::isNonOverloadPlaceholderType.
1970 bool isNonOverloadPlaceholderType() const;
1971
1972 /// isIntegerType() does *not* include complex integers (a GCC extension).
1973 /// isComplexIntegerType() can be used to test for complex integers.
1974 bool isIntegerType() const; // C99 6.2.5p17 (int, char, bool, enum)
1975 bool isEnumeralType() const;
1976
1977 /// Determine whether this type is a scoped enumeration type.
1978 bool isScopedEnumeralType() const;
1979 bool isBooleanType() const;
1980 bool isCharType() const;
1981 bool isWideCharType() const;
1982 bool isChar8Type() const;
1983 bool isChar16Type() const;
1984 bool isChar32Type() const;
1985 bool isAnyCharacterType() const;
1986 bool isIntegralType(const ASTContext &Ctx) const;
1987
1988 /// Determine whether this type is an integral or enumeration type.
1989 bool isIntegralOrEnumerationType() const;
1990
1991 /// Determine whether this type is an integral or unscoped enumeration type.
1992 bool isIntegralOrUnscopedEnumerationType() const;
1993 bool isUnscopedEnumerationType() const;
1994
1995 /// Floating point categories.
1996 bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double)
1997 /// isComplexType() does *not* include complex integers (a GCC extension).
1998 /// isComplexIntegerType() can be used to test for complex integers.
1999 bool isComplexType() const; // C99 6.2.5p11 (complex)
2000 bool isAnyComplexType() const; // C99 6.2.5p11 (complex) + Complex Int.
2001 bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex)
2002 bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half)
2003 bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661
2004 bool isBFloat16Type() const;
2005 bool isFloat128Type() const;
2006 bool isRealType() const; // C99 6.2.5p17 (real floating + integer)
2007 bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating)
2008 bool isVoidType() const; // C99 6.2.5p19
2009 bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers)
2010 bool isAggregateType() const;
2011 bool isFundamentalType() const;
2012 bool isCompoundType() const;
2013
2014 // Type Predicates: Check to see if this type is structurally the specified
2015 // type, ignoring typedefs and qualifiers.
2016 bool isFunctionType() const;
2017 bool isFunctionNoProtoType() const { return getAs<FunctionNoProtoType>(); }
2018 bool isFunctionProtoType() const { return getAs<FunctionProtoType>(); }
2019 bool isPointerType() const;
2020 bool isAnyPointerType() const; // Any C pointer or ObjC object pointer
2021 bool isBlockPointerType() const;
2022 bool isVoidPointerType() const;
2023 bool isReferenceType() const;
2024 bool isLValueReferenceType() const;
2025 bool isRValueReferenceType() const;
2026 bool isObjectPointerType() const;
2027 bool isFunctionPointerType() const;
2028 bool isFunctionReferenceType() const;
2029 bool isMemberPointerType() const;
2030 bool isMemberFunctionPointerType() const;
2031 bool isMemberDataPointerType() const;
2032 bool isArrayType() const;
2033 bool isConstantArrayType() const;
2034 bool isIncompleteArrayType() const;
2035 bool isVariableArrayType() const;
2036 bool isDependentSizedArrayType() const;
2037 bool isRecordType() const;
2038 bool isClassType() const;
2039 bool isStructureType() const;
2040 bool isObjCBoxableRecordType() const;
2041 bool isInterfaceType() const;
2042 bool isStructureOrClassType() const;
2043 bool isUnionType() const;
2044 bool isComplexIntegerType() const; // GCC _Complex integer type.
2045 bool isVectorType() const; // GCC vector type.
2046 bool isExtVectorType() const; // Extended vector type.
2047 bool isMatrixType() const; // Matrix type.
2048 bool isConstantMatrixType() const; // Constant matrix type.
2049 bool isDependentAddressSpaceType() const; // value-dependent address space qualifier
2050 bool isObjCObjectPointerType() const; // pointer to ObjC object
2051 bool isObjCRetainableType() const; // ObjC object or block pointer
2052 bool isObjCLifetimeType() const; // (array of)* retainable type
2053 bool isObjCIndirectLifetimeType() const; // (pointer to)* lifetime type
2054 bool isObjCNSObjectType() const; // __attribute__((NSObject))
2055 bool isObjCIndependentClassType() const; // __attribute__((objc_independent_class))
2056 // FIXME: change this to 'raw' interface type, so we can used 'interface' type
2057 // for the common case.
2058 bool isObjCObjectType() const; // NSString or typeof(*(id)0)
2059 bool isObjCQualifiedInterfaceType() const; // NSString<foo>
2060 bool isObjCQualifiedIdType() const; // id<foo>
2061 bool isObjCQualifiedClassType() const; // Class<foo>
2062 bool isObjCObjectOrInterfaceType() const;
2063 bool isObjCIdType() const; // id
2064 bool isDecltypeType() const;
2065 /// Was this type written with the special inert-in-ARC __unsafe_unretained
2066 /// qualifier?
2067 ///
2068 /// This approximates the answer to the following question: if this
2069 /// translation unit were compiled in ARC, would this type be qualified
2070 /// with __unsafe_unretained?
2071 bool isObjCInertUnsafeUnretainedType() const {
2072 return hasAttr(attr::ObjCInertUnsafeUnretained);
2073 }
2074
2075 /// Whether the type is Objective-C 'id' or a __kindof type of an
2076 /// object type, e.g., __kindof NSView * or __kindof id
2077 /// <NSCopying>.
2078 ///
2079 /// \param bound Will be set to the bound on non-id subtype types,
2080 /// which will be (possibly specialized) Objective-C class type, or
2081 /// null for 'id.
2082 bool isObjCIdOrObjectKindOfType(const ASTContext &ctx,
2083 const ObjCObjectType *&bound) const;
2084
2085 bool isObjCClassType() const; // Class
2086
2087 /// Whether the type is Objective-C 'Class' or a __kindof type of an
2088 /// Class type, e.g., __kindof Class <NSCopying>.
2089 ///
2090 /// Unlike \c isObjCIdOrObjectKindOfType, there is no relevant bound
2091 /// here because Objective-C's type system cannot express "a class
2092 /// object for a subclass of NSFoo".
2093 bool isObjCClassOrClassKindOfType() const;
2094
2095 bool isBlockCompatibleObjCPointerType(ASTContext &ctx) const;
2096 bool isObjCSelType() const; // Class
2097 bool isObjCBuiltinType() const; // 'id' or 'Class'
2098 bool isObjCARCBridgableType() const;
2099 bool isCARCBridgableType() const;
2100 bool isTemplateTypeParmType() const; // C++ template type parameter
2101 bool isNullPtrType() const; // C++11 std::nullptr_t
2102 bool isNothrowT() const; // C++ std::nothrow_t
2103 bool isAlignValT() const; // C++17 std::align_val_t
2104 bool isStdByteType() const; // C++17 std::byte
2105 bool isAtomicType() const; // C11 _Atomic()
2106 bool isUndeducedAutoType() const; // C++11 auto or
2107 // C++14 decltype(auto)
2108 bool isTypedefNameType() const; // typedef or alias template
2109
2110#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
2111 bool is##Id##Type() const;
2112#include "clang/Basic/OpenCLImageTypes.def"
2113
2114 bool isImageType() const; // Any OpenCL image type
2115
2116 bool isSamplerT() const; // OpenCL sampler_t
2117 bool isEventT() const; // OpenCL event_t
2118 bool isClkEventT() const; // OpenCL clk_event_t
2119 bool isQueueT() const; // OpenCL queue_t
2120 bool isReserveIDT() const; // OpenCL reserve_id_t
2121
2122#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
2123 bool is##Id##Type() const;
2124#include "clang/Basic/OpenCLExtensionTypes.def"
2125 // Type defined in cl_intel_device_side_avc_motion_estimation OpenCL extension
2126 bool isOCLIntelSubgroupAVCType() const;
2127 bool isOCLExtOpaqueType() const; // Any OpenCL extension type
2128
2129 bool isPipeType() const; // OpenCL pipe type
2130 bool isExtIntType() const; // Extended Int Type
2131 bool isOpenCLSpecificType() const; // Any OpenCL specific type
2132
2133 /// Determines if this type, which must satisfy
2134 /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather
2135 /// than implicitly __strong.
2136 bool isObjCARCImplicitlyUnretainedType() const;
2137
2138 /// Check if the type is the CUDA device builtin surface type.
2139 bool isCUDADeviceBuiltinSurfaceType() const;
2140 /// Check if the type is the CUDA device builtin texture type.
2141 bool isCUDADeviceBuiltinTextureType() const;
2142
2143 /// Return the implicit lifetime for this type, which must not be dependent.
2144 Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const;
2145
2146 enum ScalarTypeKind {
2147 STK_CPointer,
2148 STK_BlockPointer,
2149 STK_ObjCObjectPointer,
2150 STK_MemberPointer,
2151 STK_Bool,
2152 STK_Integral,
2153 STK_Floating,
2154 STK_IntegralComplex,
2155 STK_FloatingComplex,
2156 STK_FixedPoint
2157 };
2158
2159 /// Given that this is a scalar type, classify it.
2160 ScalarTypeKind getScalarTypeKind() const;
2161
2162 TypeDependence getDependence() const {
2163 return static_cast<TypeDependence>(TypeBits.Dependence);
2164 }
2165
2166 /// Whether this type is an error type.
2167 bool containsErrors() const {
2168 return getDependence() & TypeDependence::Error;
2169 }
2170
2171 /// Whether this type is a dependent type, meaning that its definition
2172 /// somehow depends on a template parameter (C++ [temp.dep.type]).
2173 bool isDependentType() const {
2174 return getDependence() & TypeDependence::Dependent;
2175 }
2176
2177 /// Determine whether this type is an instantiation-dependent type,
2178 /// meaning that the type involves a template parameter (even if the
2179 /// definition does not actually depend on the type substituted for that
2180 /// template parameter).
2181 bool isInstantiationDependentType() const {
2182 return getDependence() & TypeDependence::Instantiation;
2183 }
2184
2185 /// Determine whether this type is an undeduced type, meaning that
2186 /// it somehow involves a C++11 'auto' type or similar which has not yet been
2187 /// deduced.
2188 bool isUndeducedType() const;
2189
2190 /// Whether this type is a variably-modified type (C99 6.7.5).
2191 bool isVariablyModifiedType() const {
2192 return getDependence() & TypeDependence::VariablyModified;
2193 }
2194
2195 /// Whether this type involves a variable-length array type
2196 /// with a definite size.
2197 bool hasSizedVLAType() const;
2198
2199 /// Whether this type is or contains a local or unnamed type.
2200 bool hasUnnamedOrLocalType() const;
2201
2202 bool isOverloadableType() const;
2203
2204 /// Determine wither this type is a C++ elaborated-type-specifier.
2205 bool isElaboratedTypeSpecifier() const;
2206
2207 bool canDecayToPointerType() const;
2208
2209 /// Whether this type is represented natively as a pointer. This includes
2210 /// pointers, references, block pointers, and Objective-C interface,
2211 /// qualified id, and qualified interface types, as well as nullptr_t.
2212 bool hasPointerRepresentation() const;
2213
2214 /// Whether this type can represent an objective pointer type for the
2215 /// purpose of GC'ability
2216 bool hasObjCPointerRepresentation() const;
2217
2218 /// Determine whether this type has an integer representation
2219 /// of some sort, e.g., it is an integer type or a vector.
2220 bool hasIntegerRepresentation() const;
2221
2222 /// Determine whether this type has an signed integer representation
2223 /// of some sort, e.g., it is an signed integer type or a vector.
2224 bool hasSignedIntegerRepresentation() const;
2225
2226 /// Determine whether this type has an unsigned integer representation
2227 /// of some sort, e.g., it is an unsigned integer type or a vector.
2228 bool hasUnsignedIntegerRepresentation() const;
2229
2230 /// Determine whether this type has a floating-point representation
2231 /// of some sort, e.g., it is a floating-point type or a vector thereof.
2232 bool hasFloatingRepresentation() const;
2233
2234 // Type Checking Functions: Check to see if this type is structurally the
2235 // specified type, ignoring typedefs and qualifiers, and return a pointer to
2236 // the best type we can.
2237 const RecordType *getAsStructureType() const;
2238 /// NOTE: getAs*ArrayType are methods on ASTContext.
2239 const RecordType *getAsUnionType() const;
2240 const ComplexType *getAsComplexIntegerType() const; // GCC complex int type.
2241 const ObjCObjectType *getAsObjCInterfaceType() const;
2242
2243 // The following is a convenience method that returns an ObjCObjectPointerType
2244 // for object declared using an interface.
2245 const ObjCObjectPointerType *getAsObjCInterfacePointerType() const;
2246 const ObjCObjectPointerType *getAsObjCQualifiedIdType() const;
2247 const ObjCObjectPointerType *getAsObjCQualifiedClassType() const;
2248 const ObjCObjectType *getAsObjCQualifiedInterfaceType() const;
2249
2250 /// Retrieves the CXXRecordDecl that this type refers to, either
2251 /// because the type is a RecordType or because it is the injected-class-name
2252 /// type of a class template or class template partial specialization.
2253 CXXRecordDecl *getAsCXXRecordDecl() const;
2254
2255 /// Retrieves the RecordDecl this type refers to.
2256 RecordDecl *getAsRecordDecl() const;
2257
2258 /// Retrieves the TagDecl that this type refers to, either
2259 /// because the type is a TagType or because it is the injected-class-name
2260 /// type of a class template or class template partial specialization.
2261 TagDecl *getAsTagDecl() const;
2262
2263 /// If this is a pointer or reference to a RecordType, return the
2264 /// CXXRecordDecl that the type refers to.
2265 ///
2266 /// If this is not a pointer or reference, or the type being pointed to does
2267 /// not refer to a CXXRecordDecl, returns NULL.
2268 const CXXRecordDecl *getPointeeCXXRecordDecl() const;
2269
2270 /// Get the DeducedType whose type will be deduced for a variable with
2271 /// an initializer of this type. This looks through declarators like pointer
2272 /// types, but not through decltype or typedefs.
2273 DeducedType *getContainedDeducedType() const;
2274
2275 /// Get the AutoType whose type will be deduced for a variable with
2276 /// an initializer of this type. This looks through declarators like pointer
2277 /// types, but not through decltype or typedefs.
2278 AutoType *getContainedAutoType() const {
2279 return dyn_cast_or_null<AutoType>(getContainedDeducedType());
2280 }
2281
2282 /// Determine whether this type was written with a leading 'auto'
2283 /// corresponding to a trailing return type (possibly for a nested
2284 /// function type within a pointer to function type or similar).
2285 bool hasAutoForTrailingReturnType() const;
2286
2287 /// Member-template getAs<specific type>'. Look through sugar for
2288 /// an instance of \<specific type>. This scheme will eventually
2289 /// replace the specific getAsXXXX methods above.
2290 ///
2291 /// There are some specializations of this member template listed
2292 /// immediately following this class.
2293 template <typename T> const T *getAs() const;
2294
2295 /// Member-template getAsAdjusted<specific type>. Look through specific kinds
2296 /// of sugar (parens, attributes, etc) for an instance of \<specific type>.
2297 /// This is used when you need to walk over sugar nodes that represent some
2298 /// kind of type adjustment from a type that was written as a \<specific type>
2299 /// to another type that is still canonically a \<specific type>.
2300 template <typename T> const T *getAsAdjusted() const;
2301
2302 /// A variant of getAs<> for array types which silently discards
2303 /// qualifiers from the outermost type.
2304 const ArrayType *getAsArrayTypeUnsafe() const;
2305
2306 /// Member-template castAs<specific type>. Look through sugar for
2307 /// the underlying instance of \<specific type>.
2308 ///
2309 /// This method has the same relationship to getAs<T> as cast<T> has
2310 /// to dyn_cast<T>; which is to say, the underlying type *must*
2311 /// have the intended type, and this method will never return null.
2312 template <typename T> const T *castAs() const;
2313
2314 /// A variant of castAs<> for array type which silently discards
2315 /// qualifiers from the outermost type.
2316 const ArrayType *castAsArrayTypeUnsafe() const;
2317
2318 /// Determine whether this type had the specified attribute applied to it
2319 /// (looking through top-level type sugar).
2320 bool hasAttr(attr::Kind AK) const;
2321
2322 /// Get the base element type of this type, potentially discarding type
2323 /// qualifiers. This should never be used when type qualifiers
2324 /// are meaningful.
2325 const Type *getBaseElementTypeUnsafe() const;
2326
2327 /// If this is an array type, return the element type of the array,
2328 /// potentially with type qualifiers missing.
2329 /// This should never be used when type qualifiers are meaningful.
2330 const Type *getArrayElementTypeNoTypeQual() const;
2331
2332 /// If this is a pointer type, return the pointee type.
2333 /// If this is an array type, return the array element type.
2334 /// This should never be used when type qualifiers are meaningful.
2335 const Type *getPointeeOrArrayElementType() const;
2336
2337 /// If this is a pointer, ObjC object pointer, or block
2338 /// pointer, this returns the respective pointee.
2339 QualType getPointeeType() const;
2340
2341 /// Return the specified type with any "sugar" removed from the type,
2342 /// removing any typedefs, typeofs, etc., as well as any qualifiers.
2343 const Type *getUnqualifiedDesugaredType() const;
2344
2345 /// More type predicates useful for type checking/promotion
2346 bool isPromotableIntegerType() const; // C99 6.3.1.1p2
2347
2348 /// Return true if this is an integer type that is
2349 /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
2350 /// or an enum decl which has a signed representation.
2351 bool isSignedIntegerType() const;
2352
2353 /// Return true if this is an integer type that is
2354 /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool],
2355 /// or an enum decl which has an unsigned representation.
2356 bool isUnsignedIntegerType() const;
2357
2358 /// Determines whether this is an integer type that is signed or an
2359 /// enumeration types whose underlying type is a signed integer type.
2360 bool isSignedIntegerOrEnumerationType() const;
2361
2362 /// Determines whether this is an integer type that is unsigned or an
2363 /// enumeration types whose underlying type is a unsigned integer type.
2364 bool isUnsignedIntegerOrEnumerationType() const;
2365
2366 /// Return true if this is a fixed point type according to
2367 /// ISO/IEC JTC1 SC22 WG14 N1169.
2368 bool isFixedPointType() const;
2369
2370 /// Return true if this is a fixed point or integer type.
2371 bool isFixedPointOrIntegerType() const;
2372
2373 /// Return true if this is a saturated fixed point type according to
2374 /// ISO/IEC JTC1 SC22 WG14 N1169. This type can be signed or unsigned.
2375 bool isSaturatedFixedPointType() const;
2376
2377 /// Return true if this is a saturated fixed point type according to
2378 /// ISO/IEC JTC1 SC22 WG14 N1169. This type can be signed or unsigned.
2379 bool isUnsaturatedFixedPointType() const;
2380
2381 /// Return true if this is a fixed point type that is signed according
2382 /// to ISO/IEC JTC1 SC22 WG14 N1169. This type can also be saturated.
2383 bool isSignedFixedPointType() const;
2384
2385 /// Return true if this is a fixed point type that is unsigned according
2386 /// to ISO/IEC JTC1 SC22 WG14 N1169. This type can also be saturated.
2387 bool isUnsignedFixedPointType() const;
2388
2389 /// Return true if this is not a variable sized type,
2390 /// according to the rules of C99 6.7.5p3. It is not legal to call this on
2391 /// incomplete types.
2392 bool isConstantSizeType() const;
2393
2394 /// Returns true if this type can be represented by some
2395 /// set of type specifiers.
2396 bool isSpecifierType() const;
2397
2398 /// Determine the linkage of this type.
2399 Linkage getLinkage() const;
2400
2401 /// Determine the visibility of this type.
2402 Visibility getVisibility() const {
2403 return getLinkageAndVisibility().getVisibility();
2404 }
2405
2406 /// Return true if the visibility was explicitly set is the code.
2407 bool isVisibilityExplicit() const {
2408 return getLinkageAndVisibility().isVisibilityExplicit();
2409 }
2410
2411 /// Determine the linkage and visibility of this type.
2412 LinkageInfo getLinkageAndVisibility() const;
2413
2414 /// True if the computed linkage is valid. Used for consistency
2415 /// checking. Should always return true.
2416 bool isLinkageValid() const;
2417
2418 /// Determine the nullability of the given type.
2419 ///
2420 /// Note that nullability is only captured as sugar within the type
2421 /// system, not as part of the canonical type, so nullability will
2422 /// be lost by canonicalization and desugaring.
2423 Optional<NullabilityKind> getNullability(const ASTContext &context) const;
2424
2425 /// Determine whether the given type can have a nullability
2426 /// specifier applied to it, i.e., if it is any kind of pointer type.
2427 ///
2428 /// \param ResultIfUnknown The value to return if we don't yet know whether
2429 /// this type can have nullability because it is dependent.
2430 bool canHaveNullability(bool ResultIfUnknown = true) const;
2431
2432 /// Retrieve the set of substitutions required when accessing a member
2433 /// of the Objective-C receiver type that is declared in the given context.
2434 ///
2435 /// \c *this is the type of the object we're operating on, e.g., the
2436 /// receiver for a message send or the base of a property access, and is
2437 /// expected to be of some object or object pointer type.
2438 ///
2439 /// \param dc The declaration context for which we are building up a
2440 /// substitution mapping, which should be an Objective-C class, extension,
2441 /// category, or method within.
2442 ///
2443 /// \returns an array of type arguments that can be substituted for
2444 /// the type parameters of the given declaration context in any type described
2445 /// within that context, or an empty optional to indicate that no
2446 /// substitution is required.
2447 Optional<ArrayRef<QualType>>
2448 getObjCSubstitutions(const DeclContext *dc) const;
2449
2450 /// Determines if this is an ObjC interface type that may accept type
2451 /// parameters.
2452 bool acceptsObjCTypeParams() const;
2453
2454 const char *getTypeClassName() const;
2455
2456 QualType getCanonicalTypeInternal() const {
2457 return CanonicalType;
2458 }
2459
2460 CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h
2461 void dump() const;
2462 void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
2463};
2464
2465/// This will check for a TypedefType by removing any existing sugar
2466/// until it reaches a TypedefType or a non-sugared type.
2467template <> const TypedefType *Type::getAs() const;
2468
2469/// This will check for a TemplateSpecializationType by removing any
2470/// existing sugar until it reaches a TemplateSpecializationType or a
2471/// non-sugared type.
2472template <> const TemplateSpecializationType *Type::getAs() const;
2473
2474/// This will check for an AttributedType by removing any existing sugar
2475/// until it reaches an AttributedType or a non-sugared type.
2476template <> const AttributedType *Type::getAs() const;
2477
2478// We can do canonical leaf types faster, because we don't have to
2479// worry about preserving child type decoration.
2480#define TYPE(Class, Base)
2481#define LEAF_TYPE(Class) \
2482template <> inline const Class##Type *Type::getAs() const { \
2483 return dyn_cast<Class##Type>(CanonicalType); \
2484} \
2485template <> inline const Class##Type *Type::castAs() const { \
2486 return cast<Class##Type>(CanonicalType); \
2487}
2488#include "clang/AST/TypeNodes.inc"
2489
2490/// This class is used for builtin types like 'int'. Builtin
2491/// types are always canonical and have a literal name field.
2492class BuiltinType : public Type {
2493public:
2494 enum Kind {
2495// OpenCL image types
2496#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) Id,
2497#include "clang/Basic/OpenCLImageTypes.def"
2498// OpenCL extension types
2499#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) Id,
2500#include "clang/Basic/OpenCLExtensionTypes.def"
2501// SVE Types
2502#define SVE_TYPE(Name, Id, SingletonId) Id,
2503#include "clang/Basic/AArch64SVEACLETypes.def"
2504// PPC MMA Types
2505#define PPC_VECTOR_TYPE(Name, Id, Size) Id,
2506#include "clang/Basic/PPCTypes.def"
2507// RVV Types
2508#define RVV_TYPE(Name, Id, SingletonId) Id,
2509#include "clang/Basic/RISCVVTypes.def"
2510// All other builtin types
2511#define BUILTIN_TYPE(Id, SingletonId) Id,
2512#define LAST_BUILTIN_TYPE(Id) LastKind = Id
2513#include "clang/AST/BuiltinTypes.def"
2514 };
2515
2516private:
2517 friend class ASTContext; // ASTContext creates these.
2518
2519 BuiltinType(Kind K)
2520 : Type(Builtin, QualType(),
2521 K == Dependent ? TypeDependence::DependentInstantiation
2522 : TypeDependence::None) {
2523 BuiltinTypeBits.Kind = K;
2524 }
2525
2526public:
2527 Kind getKind() const { return static_cast<Kind>(BuiltinTypeBits.Kind); }
2528 StringRef getName(const PrintingPolicy &Policy) const;
2529
2530 const char *getNameAsCString(const PrintingPolicy &Policy) const {
2531 // The StringRef is null-terminated.
2532 StringRef str = getName(Policy);
2533 assert(!str.empty() && str.data()[str.size()] == '\0')(static_cast<void> (0));
2534 return str.data();
2535 }
2536
2537 bool isSugared() const { return false; }
2538 QualType desugar() const { return QualType(this, 0); }
2539
2540 bool isInteger() const {
2541 return getKind() >= Bool && getKind() <= Int128;
2542 }
2543
2544 bool isSignedInteger() const {
2545 return getKind() >= Char_S && getKind() <= Int128;
2546 }
2547
2548 bool isUnsignedInteger() const {
2549 return getKind() >= Bool && getKind() <= UInt128;
2550 }
2551
2552 bool isFloatingPoint() const {
2553 return getKind() >= Half && getKind() <= Float128;
2554 }
2555
2556 /// Determines whether the given kind corresponds to a placeholder type.
2557 static bool isPlaceholderTypeKind(Kind K) {
2558 return K >= Overload;
2559 }
2560
2561 /// Determines whether this type is a placeholder type, i.e. a type
2562 /// which cannot appear in arbitrary positions in a fully-formed
2563 /// expression.
2564 bool isPlaceholderType() const {
2565 return isPlaceholderTypeKind(getKind());
2566 }
2567
2568 /// Determines whether this type is a placeholder type other than
2569 /// Overload. Most placeholder types require only syntactic
2570 /// information about their context in order to be resolved (e.g.
2571 /// whether it is a call expression), which means they can (and
2572 /// should) be resolved in an earlier "phase" of analysis.
2573 /// Overload expressions sometimes pick up further information
2574 /// from their context, like whether the context expects a
2575 /// specific function-pointer type, and so frequently need
2576 /// special treatment.
2577 bool isNonOverloadPlaceholderType() const {
2578 return getKind() > Overload;
2579 }
2580
2581 static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }
2582};
2583
2584/// Complex values, per C99 6.2.5p11. This supports the C99 complex
2585/// types (_Complex float etc) as well as the GCC integer complex extensions.
2586class ComplexType : public Type, public llvm::FoldingSetNode {
2587 friend class ASTContext; // ASTContext creates these.
2588
2589 QualType ElementType;
2590
2591 ComplexType(QualType Element, QualType CanonicalPtr)
2592 : Type(Complex, CanonicalPtr, Element->getDependence()),
2593 ElementType(Element) {}
2594
2595public:
2596 QualType getElementType() const { return ElementType; }
2597
2598 bool isSugared() const { return false; }
2599 QualType desugar() const { return QualType(this, 0); }
2600
2601 void Profile(llvm::FoldingSetNodeID &ID) {
2602 Profile(ID, getElementType());
2603 }
2604
2605 static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) {
2606 ID.AddPointer(Element.getAsOpaquePtr());
2607 }
2608
2609 static bool classof(const Type *T) { return T->getTypeClass() == Complex; }
2610};
2611
2612/// Sugar for parentheses used when specifying types.
2613class ParenType : public Type, public llvm::FoldingSetNode {
2614 friend class ASTContext; // ASTContext creates these.
2615
2616 QualType Inner;
2617
2618 ParenType(QualType InnerType, QualType CanonType)
2619 : Type(Paren, CanonType, InnerType->getDependence()), Inner(InnerType) {}
2620
2621public:
2622 QualType getInnerType() const { return Inner; }
2623
2624 bool isSugared() const { return true; }
2625 QualType desugar() const { return getInnerType(); }
2626
2627 void Profile(llvm::FoldingSetNodeID &ID) {
2628 Profile(ID, getInnerType());
2629 }
2630
2631 static void Profile(llvm::FoldingSetNodeID &ID, QualType Inner) {
2632 Inner.Profile(ID);
2633 }
2634
2635 static bool classof(const Type *T) { return T->getTypeClass() == Paren; }
2636};
2637
2638/// PointerType - C99 6.7.5.1 - Pointer Declarators.
2639class PointerType : public Type, public llvm::FoldingSetNode {
2640 friend class ASTContext; // ASTContext creates these.
2641
2642 QualType PointeeType;
2643
2644 PointerType(QualType Pointee, QualType CanonicalPtr)
2645 : Type(Pointer, CanonicalPtr, Pointee->getDependence()),
2646 PointeeType(Pointee) {}
2647
2648public:
2649 QualType getPointeeType() const { return PointeeType; }
2650
2651 bool isSugared() const { return false; }
2652 QualType desugar() const { return QualType(this, 0); }
2653
2654 void Profile(llvm::FoldingSetNodeID &ID) {
2655 Profile(ID, getPointeeType());
2656 }
2657
2658 static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
2659 ID.AddPointer(Pointee.getAsOpaquePtr());
2660 }
2661
2662 static bool classof(const Type *T) { return T->getTypeClass() == Pointer; }
2663};
2664
2665/// Represents a type which was implicitly adjusted by the semantic
2666/// engine for arbitrary reasons. For example, array and function types can
2667/// decay, and function types can have their calling conventions adjusted.
2668class AdjustedType : public Type, public llvm::FoldingSetNode {
2669 QualType OriginalTy;
2670 QualType AdjustedTy;
2671
2672protected:
2673 friend class ASTContext; // ASTContext creates these.
2674
2675 AdjustedType(TypeClass TC, QualType OriginalTy, QualType AdjustedTy,
2676 QualType CanonicalPtr)
2677 : Type(TC, CanonicalPtr, OriginalTy->getDependence()),
2678 OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {}
2679
2680public:
2681 QualType getOriginalType() const { return OriginalTy; }
2682 QualType getAdjustedType() const { return AdjustedTy; }
2683
2684 bool isSugared() const { return true; }
2685 QualType desugar() const { return AdjustedTy; }
2686
2687 void Profile(llvm::FoldingSetNodeID &ID) {
2688 Profile(ID, OriginalTy, AdjustedTy);
2689 }
2690
2691 static void Profile(llvm::FoldingSetNodeID &ID, QualType Orig, QualType New) {
2692 ID.AddPointer(Orig.getAsOpaquePtr());
2693 ID.AddPointer(New.getAsOpaquePtr());
2694 }
2695
2696 static bool classof(const Type *T) {
2697 return T->getTypeClass() == Adjusted || T->getTypeClass() == Decayed;
2698 }
2699};
2700
2701/// Represents a pointer type decayed from an array or function type.
2702class DecayedType : public AdjustedType {
2703 friend class ASTContext; // ASTContext creates these.
2704
2705 inline
2706 DecayedType(QualType OriginalType, QualType Decayed, QualType Canonical);
2707
2708public:
2709 QualType getDecayedType() const { return getAdjustedType(); }
2710
2711 inline QualType getPointeeType() const;
2712
2713 static bool classof(const Type *T) { return T->getTypeClass() == Decayed; }
2714};
2715
2716/// Pointer to a block type.
2717/// This type is to represent types syntactically represented as
2718/// "void (^)(int)", etc. Pointee is required to always be a function type.
2719class BlockPointerType : public Type, public llvm::FoldingSetNode {
2720 friend class ASTContext; // ASTContext creates these.
2721
2722 // Block is some kind of pointer type
2723 QualType PointeeType;
2724
2725 BlockPointerType(QualType Pointee, QualType CanonicalCls)
2726 : Type(BlockPointer, CanonicalCls, Pointee->getDependence()),
2727 PointeeType(Pointee) {}
2728
2729public:
2730 // Get the pointee type. Pointee is required to always be a function type.
2731 QualType getPointeeType() const { return PointeeType; }
2732
2733 bool isSugared() const { return false; }
2734 QualType desugar() const { return QualType(this, 0); }
2735
2736 void Profile(llvm::FoldingSetNodeID &ID) {
2737 Profile(ID, getPointeeType());
2738 }
2739
2740 static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) {
2741 ID.AddPointer(Pointee.getAsOpaquePtr());
2742 }
2743
2744 static bool classof(const Type *T) {
2745 return T->getTypeClass() == BlockPointer;
2746 }
2747};
2748
2749/// Base for LValueReferenceType and RValueReferenceType
2750class ReferenceType : public Type, public llvm::FoldingSetNode {
2751 QualType PointeeType;
2752
2753protected:
2754 ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef,
2755 bool SpelledAsLValue)
2756 : Type(tc, CanonicalRef, Referencee->getDependence()),
2757 PointeeType(Referencee) {
2758 ReferenceTypeBits.SpelledAsLValue = SpelledAsLValue;
2759 ReferenceTypeBits.InnerRef = Referencee->isReferenceType();
2760 }
2761
2762public:
2763 bool isSpelledAsLValue() const { return ReferenceTypeBits.SpelledAsLValue; }
2764 bool isInnerRef() const { return ReferenceTypeBits.InnerRef; }
2765
2766 QualType getPointeeTypeAsWritten() const { return PointeeType; }
2767
2768 QualType getPointeeType() const {
2769 // FIXME: this might strip inner qualifiers; okay?
2770 const ReferenceType *T = this;
2771 while (T->isInnerRef())
2772 T = T->PointeeType->castAs<ReferenceType>();
2773 return T->PointeeType;
2774 }
2775
2776 void Profile(llvm::FoldingSetNodeID &ID) {
2777 Profile(ID, PointeeType, isSpelledAsLValue());
2778 }
2779
2780 static void Profile(llvm::FoldingSetNodeID &ID,
2781 QualType Referencee,
2782 bool SpelledAsLValue) {
2783 ID.AddPointer(Referencee.getAsOpaquePtr());
2784 ID.AddBoolean(SpelledAsLValue);
2785 }
2786
2787 static bool classof(const Type *T) {
2788 return T->getTypeClass() == LValueReference ||
2789 T->getTypeClass() == RValueReference;
2790 }
2791};
2792
2793/// An lvalue reference type, per C++11 [dcl.ref].
2794class LValueReferenceType : public ReferenceType {
2795 friend class ASTContext; // ASTContext creates these
2796
2797 LValueReferenceType(QualType Referencee, QualType CanonicalRef,
2798 bool SpelledAsLValue)
2799 : ReferenceType(LValueReference, Referencee, CanonicalRef,
2800 SpelledAsLValue) {}
2801
2802public:
2803 bool isSugared() const { return false; }
2804 QualType desugar() const { return QualType(this, 0); }
2805
2806 static bool classof(const Type *T) {
2807 return T->getTypeClass() == LValueReference;
2808 }
2809};
2810
2811/// An rvalue reference type, per C++11 [dcl.ref].
2812class RValueReferenceType : public ReferenceType {
2813 friend class ASTContext; // ASTContext creates these
2814
2815 RValueReferenceType(QualType Referencee, QualType CanonicalRef)
2816 : ReferenceType(RValueReference, Referencee, CanonicalRef, false) {}
2817
2818public:
2819 bool isSugared() const { return false; }
2820 QualType desugar() const { return QualType(this, 0); }
2821
2822 static bool classof(const Type *T) {
2823 return T->getTypeClass() == RValueReference;
2824 }
2825};
2826
2827/// A pointer to member type per C++ 8.3.3 - Pointers to members.
2828///
2829/// This includes both pointers to data members and pointer to member functions.
2830class MemberPointerType : public Type, public llvm::FoldingSetNode {
2831 friend class ASTContext; // ASTContext creates these.
2832
2833 QualType PointeeType;
2834
2835 /// The class of which the pointee is a member. Must ultimately be a
2836 /// RecordType, but could be a typedef or a template parameter too.
2837 const Type *Class;
2838
2839 MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr)
2840 : Type(MemberPointer, CanonicalPtr,
2841 (Cls->getDependence() & ~TypeDependence::VariablyModified) |
2842 Pointee->getDependence()),
2843 PointeeType(Pointee), Class(Cls) {}
2844
2845public:
2846 QualType getPointeeType() const { return PointeeType; }
2847
2848 /// Returns true if the member type (i.e. the pointee type) is a
2849 /// function type rather than a data-member type.
2850 bool isMemberFunctionPointer() const {
2851 return PointeeType->isFunctionProtoType();
2852 }
2853
2854 /// Returns true if the member type (i.e. the pointee type) is a
2855 /// data type rather than a function type.
2856 bool isMemberDataPointer() const {
2857 return !PointeeType->isFunctionProtoType();
2858 }
2859
2860 const Type *getClass() const { return Class; }
2861 CXXRecordDecl *getMostRecentCXXRecordDecl() const;
2862
2863 bool isSugared() const { return false; }
2864 QualType desugar() const { return QualType(this, 0); }
2865
2866 void Profile(llvm::FoldingSetNodeID &ID) {
2867 Profile(ID, getPointeeType(), getClass());
2868 }
2869
2870 static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
2871 const Type *Class) {
2872 ID.AddPointer(Pointee.getAsOpaquePtr());
2873 ID.AddPointer(Class);
2874 }
2875
2876 static bool classof(const Type *T) {
2877 return T->getTypeClass() == MemberPointer;
2878 }
2879};
2880
2881/// Represents an array type, per C99 6.7.5.2 - Array Declarators.
2882class ArrayType : public Type, public llvm::FoldingSetNode {
2883public:
2884 /// Capture whether this is a normal array (e.g. int X[4])
2885 /// an array with a static size (e.g. int X[static 4]), or an array
2886 /// with a star size (e.g. int X[*]).
2887 /// 'static' is only allowed on function parameters.
2888 enum ArraySizeModifier {
2889 Normal, Static, Star
2890 };
2891
2892private:
2893 /// The element type of the array.
2894 QualType ElementType;
2895
2896protected:
2897 friend class ASTContext; // ASTContext creates these.
2898
2899 ArrayType(TypeClass tc, QualType et, QualType can, ArraySizeModifier sm,
2900 unsigned tq, const Expr *sz = nullptr);
2901
2902public:
2903 QualType getElementType() const { return ElementType; }
2904
2905 ArraySizeModifier getSizeModifier() const {
2906 return ArraySizeModifier(ArrayTypeBits.SizeModifier);
2907 }
2908
2909 Qualifiers getIndexTypeQualifiers() const {
2910 return Qualifiers::fromCVRMask(getIndexTypeCVRQualifiers());
2911 }
2912
2913 unsigned getIndexTypeCVRQualifiers() const {
2914 return ArrayTypeBits.IndexTypeQuals;
2915 }
2916
2917 static bool classof(const Type *T) {
2918 return T->getTypeClass() == ConstantArray ||
2919 T->getTypeClass() == VariableArray ||
2920 T->getTypeClass() == IncompleteArray ||
2921 T->getTypeClass() == DependentSizedArray;
2922 }
2923};
2924
2925/// Represents the canonical version of C arrays with a specified constant size.
2926/// For example, the canonical type for 'int A[4 + 4*100]' is a
2927/// ConstantArrayType where the element type is 'int' and the size is 404.
2928class ConstantArrayType final
2929 : public ArrayType,
2930 private llvm::TrailingObjects<ConstantArrayType, const Expr *> {
2931 friend class ASTContext; // ASTContext creates these.
2932 friend TrailingObjects;
2933
2934 llvm::APInt Size; // Allows us to unique the type.
2935
2936 ConstantArrayType(QualType et, QualType can, const llvm::APInt &size,
2937 const Expr *sz, ArraySizeModifier sm, unsigned tq)
2938 : ArrayType(ConstantArray, et, can, sm, tq, sz), Size(size) {
2939 ConstantArrayTypeBits.HasStoredSizeExpr = sz != nullptr;
2940 if (ConstantArrayTypeBits.HasStoredSizeExpr) {
2941 assert(!can.isNull() && "canonical constant array should not have size")(static_cast<void> (0));
2942 *getTrailingObjects<const Expr*>() = sz;
2943 }
2944 }
2945
2946 unsigned numTrailingObjects(OverloadToken<const Expr*>) const {
2947 return ConstantArrayTypeBits.HasStoredSizeExpr;
2948 }
2949
2950public:
2951 const llvm::APInt &getSize() const { return Size; }
2952 const Expr *getSizeExpr() const {
2953 return ConstantArrayTypeBits.HasStoredSizeExpr
2954 ? *getTrailingObjects<const Expr *>()
2955 : nullptr;
2956 }
2957 bool isSugared() const { return false; }
2958 QualType desugar() const { return QualType(this, 0); }
2959
2960 /// Determine the number of bits required to address a member of
2961 // an array with the given element type and number of elements.
2962 static unsigned getNumAddressingBits(const ASTContext &Context,
2963 QualType ElementType,
2964 const llvm::APInt &NumElements);
2965
2966 /// Determine the maximum number of active bits that an array's size
2967 /// can require, which limits the maximum size of the array.
2968 static unsigned getMaxSizeBits(const ASTContext &Context);
2969
2970 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) {
2971 Profile(ID, Ctx, getElementType(), getSize(), getSizeExpr(),
2972 getSizeModifier(), getIndexTypeCVRQualifiers());
2973 }
2974
2975 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx,
2976 QualType ET, const llvm::APInt &ArraySize,
2977 const Expr *SizeExpr, ArraySizeModifier SizeMod,
2978 unsigned TypeQuals);
2979
2980 static bool classof(const Type *T) {
2981 return T->getTypeClass() == ConstantArray;
2982 }
2983};
2984
2985/// Represents a C array with an unspecified size. For example 'int A[]' has
2986/// an IncompleteArrayType where the element type is 'int' and the size is
2987/// unspecified.
2988class IncompleteArrayType : public ArrayType {
2989 friend class ASTContext; // ASTContext creates these.
2990
2991 IncompleteArrayType(QualType et, QualType can,
2992 ArraySizeModifier sm, unsigned tq)
2993 : ArrayType(IncompleteArray, et, can, sm, tq) {}
2994
2995public:
2996 friend class StmtIteratorBase;
2997
2998 bool isSugared() const { return false; }
2999 QualType desugar() const { return QualType(this, 0); }
3000
3001 static bool classof(const Type *T) {
3002 return T->getTypeClass() == IncompleteArray;
3003 }
3004
3005 void Profile(llvm::FoldingSetNodeID &ID) {
3006 Profile(ID, getElementType(), getSizeModifier(),
3007 getIndexTypeCVRQualifiers());
3008 }
3009
3010 static void Profile(llvm::FoldingSetNodeID &ID, QualType ET,
3011 ArraySizeModifier SizeMod, unsigned TypeQuals) {
3012 ID.AddPointer(ET.getAsOpaquePtr());
3013 ID.AddInteger(SizeMod);
3014 ID.AddInteger(TypeQuals);
3015 }
3016};
3017
3018/// Represents a C array with a specified size that is not an
3019/// integer-constant-expression. For example, 'int s[x+foo()]'.
3020/// Since the size expression is an arbitrary expression, we store it as such.
3021///
3022/// Note: VariableArrayType's aren't uniqued (since the expressions aren't) and
3023/// should not be: two lexically equivalent variable array types could mean
3024/// different things, for example, these variables do not have the same type
3025/// dynamically:
3026///
3027/// void foo(int x) {
3028/// int Y[x];
3029/// ++x;
3030/// int Z[x];
3031/// }
3032class VariableArrayType : public ArrayType {
3033 friend class ASTContext; // ASTContext creates these.
3034
3035 /// An assignment-expression. VLA's are only permitted within
3036 /// a function block.
3037 Stmt *SizeExpr;
3038
3039 /// The range spanned by the left and right array brackets.
3040 SourceRange Brackets;
3041
3042 VariableArrayType(QualType et, QualType can, Expr *e,
3043 ArraySizeModifier sm, unsigned tq,
3044 SourceRange brackets)
3045 : ArrayType(VariableArray, et, can, sm, tq, e),
3046 SizeExpr((Stmt*) e), Brackets(brackets) {}
3047
3048public:
3049 friend class StmtIteratorBase;
3050
3051 Expr *getSizeExpr() const {
3052 // We use C-style casts instead of cast<> here because we do not wish
3053 // to have a dependency of Type.h on Stmt.h/Expr.h.
3054 return (Expr*) SizeExpr;
3055 }
3056
3057 SourceRange getBracketsRange() const { return Brackets; }
3058 SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
3059 SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
3060
3061 bool isSugared() const { return false; }
3062 QualType desugar() const { return QualType(this, 0); }
3063
3064 static bool classof(const Type *T) {
3065 return T->getTypeClass() == VariableArray;
3066 }
3067
3068 void Profile(llvm::FoldingSetNodeID &ID) {
3069 llvm_unreachable("Cannot unique VariableArrayTypes.")__builtin_unreachable();
3070 }
3071};
3072
3073/// Represents an array type in C++ whose size is a value-dependent expression.
3074///
3075/// For example:
3076/// \code
3077/// template<typename T, int Size>
3078/// class array {
3079/// T data[Size];
3080/// };
3081/// \endcode
3082///
3083/// For these types, we won't actually know what the array bound is
3084/// until template instantiation occurs, at which point this will
3085/// become either a ConstantArrayType or a VariableArrayType.
3086class DependentSizedArrayType : public ArrayType {
3087 friend class ASTContext; // ASTContext creates these.
3088
3089 const ASTContext &Context;
3090
3091 /// An assignment expression that will instantiate to the
3092 /// size of the array.
3093 ///
3094 /// The expression itself might be null, in which case the array
3095 /// type will have its size deduced from an initializer.
3096 Stmt *SizeExpr;
3097
3098 /// The range spanned by the left and right array brackets.
3099 SourceRange Brackets;
3100
3101 DependentSizedArrayType(const ASTContext &Context, QualType et, QualType can,
3102 Expr *e, ArraySizeModifier sm, unsigned tq,
3103 SourceRange brackets);
3104
3105public:
3106 friend class StmtIteratorBase;
3107
3108 Expr *getSizeExpr() const {
3109 // We use C-style casts instead of cast<> here because we do not wish
3110 // to have a dependency of Type.h on Stmt.h/Expr.h.
3111 return (Expr*) SizeExpr;
3112 }
3113
3114 SourceRange getBracketsRange() const { return Brackets; }
3115 SourceLocation getLBracketLoc() const { return Brackets.getBegin(); }
3116 SourceLocation getRBracketLoc() const { return Brackets.getEnd(); }
3117
3118 bool isSugared() const { return false; }
3119 QualType desugar() const { return QualType(this, 0); }
3120
3121 static bool classof(const Type *T) {
3122 return T->getTypeClass() == DependentSizedArray;
3123 }
3124
3125 void Profile(llvm::FoldingSetNodeID &ID) {
3126 Profile(ID, Context, getElementType(),
3127 getSizeModifier(), getIndexTypeCVRQualifiers(), getSizeExpr());
3128 }
3129
3130 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
3131 QualType ET, ArraySizeModifier SizeMod,
3132 unsigned TypeQuals, Expr *E);
3133};
3134
3135/// Represents an extended address space qualifier where the input address space
3136/// value is dependent. Non-dependent address spaces are not represented with a
3137/// special Type subclass; they are stored on an ExtQuals node as part of a QualType.
3138///
3139/// For example:
3140/// \code
3141/// template<typename T, int AddrSpace>
3142/// class AddressSpace {
3143/// typedef T __attribute__((address_space(AddrSpace))) type;
3144/// }
3145/// \endcode
3146class DependentAddressSpaceType : public Type, public llvm::FoldingSetNode {
3147 friend class ASTContext;
3148
3149 const ASTContext &Context;
3150 Expr *AddrSpaceExpr;
3151 QualType PointeeType;
3152 SourceLocation loc;
3153
3154 DependentAddressSpaceType(const ASTContext &Context, QualType PointeeType,
3155 QualType can, Expr *AddrSpaceExpr,
3156 SourceLocation loc);
3157
3158public:
3159 Expr *getAddrSpaceExpr() const { return AddrSpaceExpr; }
3160 QualType getPointeeType() const { return PointeeType; }
3161 SourceLocation getAttributeLoc() const { return loc; }
3162
3163 bool isSugared() const { return false; }
3164 QualType desugar() const { return QualType(this, 0); }
3165
3166 static bool classof(const Type *T) {
3167 return T->getTypeClass() == DependentAddressSpace;
3168 }
3169
3170 void Profile(llvm::FoldingSetNodeID &ID) {
3171 Profile(ID, Context, getPointeeType(), getAddrSpaceExpr());
3172 }
3173
3174 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
3175 QualType PointeeType, Expr *AddrSpaceExpr);
3176};
3177
3178/// Represents an extended vector type where either the type or size is
3179/// dependent.
3180///
3181/// For example:
3182/// \code
3183/// template<typename T, int Size>
3184/// class vector {
3185/// typedef T __attribute__((ext_vector_type(Size))) type;
3186/// }
3187/// \endcode
3188class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode {
3189 friend class ASTContext;
3190
3191 const ASTContext &Context;
3192 Expr *SizeExpr;
3193
3194 /// The element type of the array.
3195 QualType ElementType;
3196
3197 SourceLocation loc;
3198
3199 DependentSizedExtVectorType(const ASTContext &Context, QualType ElementType,
3200 QualType can, Expr *SizeExpr, SourceLocation loc);
3201
3202public:
3203 Expr *getSizeExpr() const { return SizeExpr; }
3204 QualType getElementType() const { return ElementType; }
3205 SourceLocation getAttributeLoc() const { return loc; }
3206
3207 bool isSugared() const { return false; }
3208 QualType desugar() const { return QualType(this, 0); }
3209
3210 static bool classof(const Type *T) {
3211 return T->getTypeClass() == DependentSizedExtVector;
3212 }
3213
3214 void Profile(llvm::FoldingSetNodeID &ID) {
3215 Profile(ID, Context, getElementType(), getSizeExpr());
3216 }
3217
3218 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
3219 QualType ElementType, Expr *SizeExpr);
3220};
3221
3222
3223/// Represents a GCC generic vector type. This type is created using
3224/// __attribute__((vector_size(n)), where "n" specifies the vector size in
3225/// bytes; or from an Altivec __vector or vector declaration.
3226/// Since the constructor takes the number of vector elements, the
3227/// client is responsible for converting the size into the number of elements.
3228class VectorType : public Type, public llvm::FoldingSetNode {
3229public:
3230 enum VectorKind {
3231 /// not a target-specific vector type
3232 GenericVector,
3233
3234 /// is AltiVec vector
3235 AltiVecVector,
3236
3237 /// is AltiVec 'vector Pixel'
3238 AltiVecPixel,
3239
3240 /// is AltiVec 'vector bool ...'
3241 AltiVecBool,
3242
3243 /// is ARM Neon vector
3244 NeonVector,
3245
3246 /// is ARM Neon polynomial vector
3247 NeonPolyVector,
3248
3249 /// is AArch64 SVE fixed-length data vector
3250 SveFixedLengthDataVector,
3251
3252 /// is AArch64 SVE fixed-length predicate vector
3253 SveFixedLengthPredicateVector
3254 };
3255
3256protected:
3257 friend class ASTContext; // ASTContext creates these.
3258
3259 /// The element type of the vector.
3260 QualType ElementType;
3261
3262 VectorType(QualType vecType, unsigned nElements, QualType canonType,
3263 VectorKind vecKind);
3264
3265 VectorType(TypeClass tc, QualType vecType, unsigned nElements,
3266 QualType canonType, VectorKind vecKind);
3267
3268public:
3269 QualType getElementType() const { return ElementType; }
3270 unsigned getNumElements() const { return VectorTypeBits.NumElements; }
3271
3272 bool isSugared() const { return false; }
3273 QualType desugar() const { return QualType(this, 0); }
3274
3275 VectorKind getVectorKind() const {
3276 return VectorKind(VectorTypeBits.VecKind);
3277 }
3278
3279 void Profile(llvm::FoldingSetNodeID &ID) {
3280 Profile(ID, getElementType(), getNumElements(),
3281 getTypeClass(), getVectorKind());
3282 }
3283
3284 static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
3285 unsigned NumElements, TypeClass TypeClass,
3286 VectorKind VecKind) {
3287 ID.AddPointer(ElementType.getAsOpaquePtr());
3288 ID.AddInteger(NumElements);
3289 ID.AddInteger(TypeClass);
3290 ID.AddInteger(VecKind);
3291 }
3292
3293 static bool classof(const Type *T) {
3294 return T->getTypeClass() == Vector || T->getTypeClass() == ExtVector;
3295 }
3296};
3297
3298/// Represents a vector type where either the type or size is dependent.
3299////
3300/// For example:
3301/// \code
3302/// template<typename T, int Size>
3303/// class vector {
3304/// typedef T __attribute__((vector_size(Size))) type;
3305/// }
3306/// \endcode
3307class DependentVectorType : public Type, public llvm::FoldingSetNode {
3308 friend class ASTContext;
3309
3310 const ASTContext &Context;
3311 QualType ElementType;
3312 Expr *SizeExpr;
3313 SourceLocation Loc;
3314
3315 DependentVectorType(const ASTContext &Context, QualType ElementType,
3316 QualType CanonType, Expr *SizeExpr,
3317 SourceLocation Loc, VectorType::VectorKind vecKind);
3318
3319public:
3320 Expr *getSizeExpr() const { return SizeExpr; }
3321 QualType getElementType() const { return ElementType; }
3322 SourceLocation getAttributeLoc() const { return Loc; }
3323 VectorType::VectorKind getVectorKind() const {
3324 return VectorType::VectorKind(VectorTypeBits.VecKind);
3325 }
3326
3327 bool isSugared() const { return false; }
3328 QualType desugar() const { return QualType(this, 0); }
3329
3330 static bool classof(const Type *T) {
3331 return T->getTypeClass() == DependentVector;
3332 }
3333
3334 void Profile(llvm::FoldingSetNodeID &ID) {
3335 Profile(ID, Context, getElementType(), getSizeExpr(), getVectorKind());
3336 }
3337
3338 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
3339 QualType ElementType, const Expr *SizeExpr,
3340 VectorType::VectorKind VecKind);
3341};
3342
3343/// ExtVectorType - Extended vector type. This type is created using
3344/// __attribute__((ext_vector_type(n)), where "n" is the number of elements.
3345/// Unlike vector_size, ext_vector_type is only allowed on typedef's. This
3346/// class enables syntactic extensions, like Vector Components for accessing
3347/// points (as .xyzw), colors (as .rgba), and textures (modeled after OpenGL
3348/// Shading Language).
3349class ExtVectorType : public VectorType {
3350 friend class ASTContext; // ASTContext creates these.
3351
3352 ExtVectorType(QualType vecType, unsigned nElements, QualType canonType)
3353 : VectorType(ExtVector, vecType, nElements, canonType, GenericVector) {}
3354
3355public:
3356 static int getPointAccessorIdx(char c) {
3357 switch (c) {
3358 default: return -1;
3359 case 'x': case 'r': return 0;
3360 case 'y': case 'g': return 1;
3361 case 'z': case 'b': return 2;
3362 case 'w': case 'a': return 3;
3363 }
3364 }
3365
3366 static int getNumericAccessorIdx(char c) {
3367 switch (c) {
3368 default: return -1;
3369 case '0': return 0;
3370 case '1': return 1;
3371 case '2': return 2;
3372 case '3': return 3;
3373 case '4': return 4;
3374 case '5': return 5;
3375 case '6': return 6;
3376 case '7': return 7;
3377 case '8': return 8;
3378 case '9': return 9;
3379 case 'A':
3380 case 'a': return 10;
3381 case 'B':
3382 case 'b': return 11;
3383 case 'C':
3384 case 'c': return 12;
3385 case 'D':
3386 case 'd': return 13;
3387 case 'E':
3388 case 'e': return 14;
3389 case 'F':
3390 case 'f': return 15;
3391 }
3392 }
3393
3394 static int getAccessorIdx(char c, bool isNumericAccessor) {
3395 if (isNumericAccessor)
3396 return getNumericAccessorIdx(c);
3397 else
3398 return getPointAccessorIdx(c);
3399 }
3400
3401 bool isAccessorWithinNumElements(char c, bool isNumericAccessor) const {
3402 if (int idx = getAccessorIdx(c, isNumericAccessor)+1)
3403 return unsigned(idx-1) < getNumElements();
3404 return false;
3405 }
3406
3407 bool isSugared() const { return false; }
3408 QualType desugar() const { return QualType(this, 0); }
3409
3410 static bool classof(const Type *T) {
3411 return T->getTypeClass() == ExtVector;
3412 }
3413};
3414
3415/// Represents a matrix type, as defined in the Matrix Types clang extensions.
3416/// __attribute__((matrix_type(rows, columns))), where "rows" specifies
3417/// number of rows and "columns" specifies the number of columns.
3418class MatrixType : public Type, public llvm::FoldingSetNode {
3419protected:
3420 friend class ASTContext;
3421
3422 /// The element type of the matrix.
3423 QualType ElementType;
3424
3425 MatrixType(QualType ElementTy, QualType CanonElementTy);
3426
3427 MatrixType(TypeClass TypeClass, QualType ElementTy, QualType CanonElementTy,
3428 const Expr *RowExpr = nullptr, const Expr *ColumnExpr = nullptr);
3429
3430public:
3431 /// Returns type of the elements being stored in the matrix
3432 QualType getElementType() const { return ElementType; }
3433
3434 /// Valid elements types are the following:
3435 /// * an integer type (as in C2x 6.2.5p19), but excluding enumerated types
3436 /// and _Bool
3437 /// * the standard floating types float or double
3438 /// * a half-precision floating point type, if one is supported on the target
3439 static bool isValidElementType(QualType T) {
3440 return T->isDependentType() ||
3441 (T->isRealType() && !T->isBooleanType() && !T->isEnumeralType());
3442 }
3443
3444 bool isSugared() const { return false; }
3445 QualType desugar() const { return QualType(this, 0); }
3446
3447 static bool classof(const Type *T) {
3448 return T->getTypeClass() == ConstantMatrix ||
3449 T->getTypeClass() == DependentSizedMatrix;
3450 }
3451};
3452
3453/// Represents a concrete matrix type with constant number of rows and columns
3454class ConstantMatrixType final : public MatrixType {
3455protected:
3456 friend class ASTContext;
3457
3458 /// Number of rows and columns.
3459 unsigned NumRows;
3460 unsigned NumColumns;
3461
3462 static constexpr unsigned MaxElementsPerDimension = (1 << 20) - 1;
3463
3464 ConstantMatrixType(QualType MatrixElementType, unsigned NRows,
3465 unsigned NColumns, QualType CanonElementType);
3466
3467 ConstantMatrixType(TypeClass typeClass, QualType MatrixType, unsigned NRows,
3468 unsigned NColumns, QualType CanonElementType);
3469
3470public:
3471 /// Returns the number of rows in the matrix.
3472 unsigned getNumRows() const { return NumRows; }
3473
3474 /// Returns the number of columns in the matrix.
3475 unsigned getNumColumns() const { return NumColumns; }
3476
3477 /// Returns the number of elements required to embed the matrix into a vector.
3478 unsigned getNumElementsFlattened() const {
3479 return getNumRows() * getNumColumns();
3480 }
3481
3482 /// Returns true if \p NumElements is a valid matrix dimension.
3483 static constexpr bool isDimensionValid(size_t NumElements) {
3484 return NumElements > 0 && NumElements <= MaxElementsPerDimension;
3485 }
3486
3487 /// Returns the maximum number of elements per dimension.
3488 static constexpr unsigned getMaxElementsPerDimension() {
3489 return MaxElementsPerDimension;
3490 }
3491
3492 void Profile(llvm::FoldingSetNodeID &ID) {
3493 Profile(ID, getElementType(), getNumRows(), getNumColumns(),
3494 getTypeClass());
3495 }
3496
3497 static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
3498 unsigned NumRows, unsigned NumColumns,
3499 TypeClass TypeClass) {
3500 ID.AddPointer(ElementType.getAsOpaquePtr());
3501 ID.AddInteger(NumRows);
3502 ID.AddInteger(NumColumns);
3503 ID.AddInteger(TypeClass);
3504 }
3505
3506 static bool classof(const Type *T) {
3507 return T->getTypeClass() == ConstantMatrix;
3508 }
3509};
3510
3511/// Represents a matrix type where the type and the number of rows and columns
3512/// is dependent on a template.
3513class DependentSizedMatrixType final : public MatrixType {
3514 friend class ASTContext;
3515
3516 const ASTContext &Context;
3517 Expr *RowExpr;
3518 Expr *ColumnExpr;
3519
3520 SourceLocation loc;
3521
3522 DependentSizedMatrixType(const ASTContext &Context, QualType ElementType,
3523 QualType CanonicalType, Expr *RowExpr,
3524 Expr *ColumnExpr, SourceLocation loc);
3525
3526public:
3527 Expr *getRowExpr() const { return RowExpr; }
3528 Expr *getColumnExpr() const { return ColumnExpr; }
3529 SourceLocation getAttributeLoc() const { return loc; }
3530
3531 static bool classof(const Type *T) {
3532 return T->getTypeClass() == DependentSizedMatrix;
3533 }
3534
3535 void Profile(llvm::FoldingSetNodeID &ID) {
3536 Profile(ID, Context, getElementType(), getRowExpr(), getColumnExpr());
3537 }
3538
3539 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
3540 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr);
3541};
3542
3543/// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base
3544/// class of FunctionNoProtoType and FunctionProtoType.
3545class FunctionType : public Type {
3546 // The type returned by the function.
3547 QualType ResultType;
3548
3549public:
3550 /// Interesting information about a specific parameter that can't simply
3551 /// be reflected in parameter's type. This is only used by FunctionProtoType
3552 /// but is in FunctionType to make this class available during the
3553 /// specification of the bases of FunctionProtoType.
3554 ///
3555 /// It makes sense to model language features this way when there's some
3556 /// sort of parameter-specific override (such as an attribute) that
3557 /// affects how the function is called. For example, the ARC ns_consumed
3558 /// attribute changes whether a parameter is passed at +0 (the default)
3559 /// or +1 (ns_consumed). This must be reflected in the function type,
3560 /// but isn't really a change to the parameter type.
3561 ///
3562 /// One serious disadvantage of modelling language features this way is
3563 /// that they generally do not work with language features that attempt
3564 /// to destructure types. For example, template argument deduction will
3565 /// not be able to match a parameter declared as
3566 /// T (*)(U)
3567 /// against an argument of type
3568 /// void (*)(__attribute__((ns_consumed)) id)
3569 /// because the substitution of T=void, U=id into the former will
3570 /// not produce the latter.
3571 class ExtParameterInfo {
3572 enum {
3573 ABIMask = 0x0F,
3574 IsConsumed = 0x10,
3575 HasPassObjSize = 0x20,
3576 IsNoEscape = 0x40,
3577 };
3578 unsigned char Data = 0;
3579
3580 public:
3581 ExtParameterInfo() = default;
3582
3583 /// Return the ABI treatment of this parameter.
3584 ParameterABI getABI() const { return ParameterABI(Data & ABIMask); }
3585 ExtParameterInfo withABI(ParameterABI kind) const {
3586 ExtParameterInfo copy = *this;
3587 copy.Data = (copy.Data & ~ABIMask) | unsigned(kind);
3588 return copy;
3589 }
3590
3591 /// Is this parameter considered "consumed" by Objective-C ARC?
3592 /// Consumed parameters must have retainable object type.
3593 bool isConsumed() const { return (Data & IsConsumed); }
3594 ExtParameterInfo withIsConsumed(bool consumed) const {
3595 ExtParameterInfo copy = *this;
3596 if (consumed)
3597 copy.Data |= IsConsumed;
3598 else
3599 copy.Data &= ~IsConsumed;
3600 return copy;
3601 }
3602
3603 bool hasPassObjectSize() const { return Data & HasPassObjSize; }
3604 ExtParameterInfo withHasPassObjectSize() const {
3605 ExtParameterInfo Copy = *this;
3606 Copy.Data |= HasPassObjSize;
3607 return Copy;
3608 }
3609
3610 bool isNoEscape() const { return Data & IsNoEscape; }
3611 ExtParameterInfo withIsNoEscape(bool NoEscape) const {
3612 ExtParameterInfo Copy = *this;
3613 if (NoEscape)
3614 Copy.Data |= IsNoEscape;
3615 else
3616 Copy.Data &= ~IsNoEscape;
3617 return Copy;
3618 }
3619
3620 unsigned char getOpaqueValue() const { return Data; }
3621 static ExtParameterInfo getFromOpaqueValue(unsigned char data) {
3622 ExtParameterInfo result;
3623 result.Data = data;
3624 return result;
3625 }
3626
3627 friend bool operator==(ExtParameterInfo lhs, ExtParameterInfo rhs) {
3628 return lhs.Data == rhs.Data;
3629 }
3630
3631 friend bool operator!=(ExtParameterInfo lhs, ExtParameterInfo rhs) {
3632 return lhs.Data != rhs.Data;
3633 }
3634 };
3635
3636 /// A class which abstracts out some details necessary for
3637 /// making a call.
3638 ///
3639 /// It is not actually used directly for storing this information in
3640 /// a FunctionType, although FunctionType does currently use the
3641 /// same bit-pattern.
3642 ///
3643 // If you add a field (say Foo), other than the obvious places (both,
3644 // constructors, compile failures), what you need to update is
3645 // * Operator==
3646 // * getFoo
3647 // * withFoo
3648 // * functionType. Add Foo, getFoo.
3649 // * ASTContext::getFooType
3650 // * ASTContext::mergeFunctionTypes
3651 // * FunctionNoProtoType::Profile
3652 // * FunctionProtoType::Profile
3653 // * TypePrinter::PrintFunctionProto
3654 // * AST read and write
3655 // * Codegen
3656 class ExtInfo {
3657 friend class FunctionType;
3658
3659 // Feel free to rearrange or add bits, but if you go over 16, you'll need to
3660 // adjust the Bits field below, and if you add bits, you'll need to adjust
3661 // Type::FunctionTypeBitfields::ExtInfo as well.
3662
3663 // | CC |noreturn|produces|nocallersavedregs|regparm|nocfcheck|cmsenscall|
3664 // |0 .. 4| 5 | 6 | 7 |8 .. 10| 11 | 12 |
3665 //
3666 // regparm is either 0 (no regparm attribute) or the regparm value+1.
3667 enum { CallConvMask = 0x1F };
3668 enum { NoReturnMask = 0x20 };
3669 enum { ProducesResultMask = 0x40 };
3670 enum { NoCallerSavedRegsMask = 0x80 };
3671 enum {
3672 RegParmMask = 0x700,
3673 RegParmOffset = 8
3674 };
3675 enum { NoCfCheckMask = 0x800 };
3676 enum { CmseNSCallMask = 0x1000 };
3677 uint16_t Bits = CC_C;
3678
3679 ExtInfo(unsigned Bits) : Bits(static_cast<uint16_t>(Bits)) {}
3680
3681 public:
3682 // Constructor with no defaults. Use this when you know that you
3683 // have all the elements (when reading an AST file for example).
3684 ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc,
3685 bool producesResult, bool noCallerSavedRegs, bool NoCfCheck,
3686 bool cmseNSCall) {
3687 assert((!hasRegParm || regParm < 7) && "Invalid regparm value")(static_cast<void> (0));
3688 Bits = ((unsigned)cc) | (noReturn ? NoReturnMask : 0) |
3689 (producesResult ? ProducesResultMask : 0) |
3690 (noCallerSavedRegs ? NoCallerSavedRegsMask : 0) |
3691 (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0) |
3692 (NoCfCheck ? NoCfCheckMask : 0) |
3693 (cmseNSCall ? CmseNSCallMask : 0);
3694 }
3695
3696 // Constructor with all defaults. Use when for example creating a
3697 // function known to use defaults.
3698 ExtInfo() = default;
3699
3700 // Constructor with just the calling convention, which is an important part
3701 // of the canonical type.
3702 ExtInfo(CallingConv CC) : Bits(CC) {}
3703
3704 bool getNoReturn() const { return Bits & NoReturnMask; }
3705 bool getProducesResult() const { return Bits & ProducesResultMask; }
3706 bool getCmseNSCall() const { return Bits & CmseNSCallMask; }
3707 bool getNoCallerSavedRegs() const { return Bits & NoCallerSavedRegsMask; }
3708 bool getNoCfCheck() const { return Bits & NoCfCheckMask; }
3709 bool getHasRegParm() const { return ((Bits & RegParmMask) >> RegParmOffset) != 0; }
3710
3711 unsigned getRegParm() const {
3712 unsigned RegParm = (Bits & RegParmMask) >> RegParmOffset;
3713 if (RegParm > 0)
3714 --RegParm;
3715 return RegParm;
3716 }
3717
3718 CallingConv getCC() const { return CallingConv(Bits & CallConvMask); }
3719
3720 bool operator==(ExtInfo Other) const {
3721 return Bits == Other.Bits;
3722 }
3723 bool operator!=(ExtInfo Other) const {
3724 return Bits != Other.Bits;
3725 }
3726
3727 // Note that we don't have setters. That is by design, use
3728 // the following with methods instead of mutating these objects.
3729
3730 ExtInfo withNoReturn(bool noReturn) const {
3731 if (noReturn)
3732 return ExtInfo(Bits | NoReturnMask);
3733 else
3734 return ExtInfo(Bits & ~NoReturnMask);
3735 }
3736
3737 ExtInfo withProducesResult(bool producesResult) const {
3738 if (producesResult)
3739 return ExtInfo(Bits | ProducesResultMask);
3740 else
3741 return ExtInfo(Bits & ~ProducesResultMask);
3742 }
3743
3744 ExtInfo withCmseNSCall(bool cmseNSCall) const {
3745 if (cmseNSCall)
3746 return ExtInfo(Bits | CmseNSCallMask);
3747 else
3748 return ExtInfo(Bits & ~CmseNSCallMask);
3749 }
3750
3751 ExtInfo withNoCallerSavedRegs(bool noCallerSavedRegs) const {
3752 if (noCallerSavedRegs)
3753 return ExtInfo(Bits | NoCallerSavedRegsMask);
3754 else
3755 return ExtInfo(Bits & ~NoCallerSavedRegsMask);
3756 }
3757
3758 ExtInfo withNoCfCheck(bool noCfCheck) const {
3759 if (noCfCheck)
3760 return ExtInfo(Bits | NoCfCheckMask);
3761 else
3762 return ExtInfo(Bits & ~NoCfCheckMask);
3763 }
3764
3765 ExtInfo withRegParm(unsigned RegParm) const {
3766 assert(RegParm < 7 && "Invalid regparm value")(static_cast<void> (0));
3767 return ExtInfo((Bits & ~RegParmMask) |
3768 ((RegParm + 1) << RegParmOffset));
3769 }
3770
3771 ExtInfo withCallingConv(CallingConv cc) const {
3772 return ExtInfo((Bits & ~CallConvMask) | (unsigned) cc);
3773 }
3774
3775 void Profile(llvm::FoldingSetNodeID &ID) const {
3776 ID.AddInteger(Bits);
3777 }
3778 };
3779
3780 /// A simple holder for a QualType representing a type in an
3781 /// exception specification. Unfortunately needed by FunctionProtoType
3782 /// because TrailingObjects cannot handle repeated types.
3783 struct ExceptionType { QualType Type; };
3784
3785 /// A simple holder for various uncommon bits which do not fit in
3786 /// FunctionTypeBitfields. Aligned to alignof(void *) to maintain the
3787 /// alignment of subsequent objects in TrailingObjects. You must update
3788 /// hasExtraBitfields in FunctionProtoType after adding extra data here.
3789 struct alignas(void *) FunctionTypeExtraBitfields {
3790 /// The number of types in the exception specification.
3791 /// A whole unsigned is not needed here and according to
3792 /// [implimits] 8 bits would be enough here.
3793 unsigned NumExceptionType;
3794 };
3795
3796protected:
3797 FunctionType(TypeClass tc, QualType res, QualType Canonical,
3798 TypeDependence Dependence, ExtInfo Info)
3799 : Type(tc, Canonical, Dependence), ResultType(res) {
3800 FunctionTypeBits.ExtInfo = Info.Bits;
3801 }
3802
3803 Qualifiers getFastTypeQuals() const {
3804 return Qualifiers::fromFastMask(FunctionTypeBits.FastTypeQuals);
3805 }
3806
3807public:
3808 QualType getReturnType() const { return ResultType; }
3809
3810 bool getHasRegParm() const { return getExtInfo().getHasRegParm(); }
3811 unsigned getRegParmType() const { return getExtInfo().getRegParm(); }
3812
3813 /// Determine whether this function type includes the GNU noreturn
3814 /// attribute. The C++11 [[noreturn]] attribute does not affect the function
3815 /// type.
3816 bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); }
3817
3818 bool getCmseNSCallAttr() const { return getExtInfo().getCmseNSCall(); }
3819 CallingConv getCallConv() const { return getExtInfo().getCC(); }
3820 ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); }
3821
3822 static_assert((~Qualifiers::FastMask & Qualifiers::CVRMask) == 0,
3823 "Const, volatile and restrict are assumed to be a subset of "
3824 "the fast qualifiers.");
3825
3826 bool isConst() const { return getFastTypeQuals().hasConst(); }
3827 bool isVolatile() const { return getFastTypeQuals().hasVolatile(); }
3828 bool isRestrict() const { return getFastTypeQuals().hasRestrict(); }
3829
3830 /// Determine the type of an expression that calls a function of
3831 /// this type.
3832 QualType getCallResultType(const ASTContext &Context) const {
3833 return getReturnType().getNonLValueExprType(Context);
3834 }
3835
3836 static StringRef getNameForCallConv(CallingConv CC);
3837
3838 static bool classof(const Type *T) {
3839 return T->getTypeClass() == FunctionNoProto ||
3840 T->getTypeClass() == FunctionProto;
3841 }
3842};
3843
3844/// Represents a K&R-style 'int foo()' function, which has
3845/// no information available about its arguments.
3846class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
3847 friend class ASTContext; // ASTContext creates these.
3848
3849 FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info)
3850 : FunctionType(FunctionNoProto, Result, Canonical,
3851 Result->getDependence() &
3852 ~(TypeDependence::DependentInstantiation |
3853 TypeDependence::UnexpandedPack),
3854 Info) {}
3855
3856public:
3857 // No additional state past what FunctionType provides.
3858
3859 bool isSugared() const { return false; }
3860 QualType desugar() const { return QualType(this, 0); }
3861
3862 void Profile(llvm::FoldingSetNodeID &ID) {
3863 Profile(ID, getReturnType(), getExtInfo());
3864 }
3865
3866 static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType,
3867 ExtInfo Info) {
3868 Info.Profile(ID);
3869 ID.AddPointer(ResultType.getAsOpaquePtr());
3870 }
3871
3872 static bool classof(const Type *T) {
3873 return T->getTypeClass() == FunctionNoProto;
3874 }
3875};
3876
3877/// Represents a prototype with parameter type info, e.g.
3878/// 'int foo(int)' or 'int foo(void)'. 'void' is represented as having no
3879/// parameters, not as having a single void parameter. Such a type can have
3880/// an exception specification, but this specification is not part of the
3881/// canonical type. FunctionProtoType has several trailing objects, some of
3882/// which optional. For more information about the trailing objects see
3883/// the first comment inside FunctionProtoType.
3884class FunctionProtoType final
3885 : public FunctionType,
3886 public llvm::FoldingSetNode,
3887 private llvm::TrailingObjects<
3888 FunctionProtoType, QualType, SourceLocation,
3889 FunctionType::FunctionTypeExtraBitfields, FunctionType::ExceptionType,
3890 Expr *, FunctionDecl *, FunctionType::ExtParameterInfo, Qualifiers> {
3891 friend class ASTContext; // ASTContext creates these.
3892 friend TrailingObjects;
3893
3894 // FunctionProtoType is followed by several trailing objects, some of
3895 // which optional. They are in order:
3896 //
3897 // * An array of getNumParams() QualType holding the parameter types.
3898 // Always present. Note that for the vast majority of FunctionProtoType,
3899 // these will be the only trailing objects.
3900 //
3901 // * Optionally if the function is variadic, the SourceLocation of the
3902 // ellipsis.
3903 //
3904 // * Optionally if some extra data is stored in FunctionTypeExtraBitfields
3905 // (see FunctionTypeExtraBitfields and FunctionTypeBitfields):
3906 // a single FunctionTypeExtraBitfields. Present if and only if
3907 // hasExtraBitfields() is true.
3908 //
3909 // * Optionally exactly one of:
3910 // * an array of getNumExceptions() ExceptionType,
3911 // * a single Expr *,
3912 // * a pair of FunctionDecl *,
3913 // * a single FunctionDecl *
3914 // used to store information about the various types of exception
3915 // specification. See getExceptionSpecSize for the details.
3916 //
3917 // * Optionally an array of getNumParams() ExtParameterInfo holding
3918 // an ExtParameterInfo for each of the parameters. Present if and
3919 // only if hasExtParameterInfos() is true.
3920 //
3921 // * Optionally a Qualifiers object to represent extra qualifiers that can't
3922 // be represented by FunctionTypeBitfields.FastTypeQuals. Present if and only
3923 // if hasExtQualifiers() is true.
3924 //
3925 // The optional FunctionTypeExtraBitfields has to be before the data
3926 // related to the exception specification since it contains the number
3927 // of exception types.
3928 //
3929 // We put the ExtParameterInfos last. If all were equal, it would make
3930 // more sense to put these before the exception specification, because
3931 // it's much easier to skip past them compared to the elaborate switch
3932 // required to skip the exception specification. However, all is not
3933 // equal; ExtParameterInfos are used to model very uncommon features,
3934 // and it's better not to burden the more common paths.
3935
3936public:
3937 /// Holds information about the various types of exception specification.
3938 /// ExceptionSpecInfo is not stored as such in FunctionProtoType but is
3939 /// used to group together the various bits of information about the
3940 /// exception specification.
3941 struct ExceptionSpecInfo {
3942 /// The kind of exception specification this is.
3943 ExceptionSpecificationType Type = EST_None;
3944
3945 /// Explicitly-specified list of exception types.
3946 ArrayRef<QualType> Exceptions;
3947
3948 /// Noexcept expression, if this is a computed noexcept specification.
3949 Expr *NoexceptExpr = nullptr;
3950
3951 /// The function whose exception specification this is, for
3952 /// EST_Unevaluated and EST_Uninstantiated.
3953 FunctionDecl *SourceDecl = nullptr;
3954
3955 /// The function template whose exception specification this is instantiated
3956 /// from, for EST_Uninstantiated.
3957 FunctionDecl *SourceTemplate = nullptr;
3958
3959 ExceptionSpecInfo() = default;
3960
3961 ExceptionSpecInfo(ExceptionSpecificationType EST) : Type(EST) {}
3962 };
3963
3964 /// Extra information about a function prototype. ExtProtoInfo is not
3965 /// stored as such in FunctionProtoType but is used to group together
3966 /// the various bits of extra information about a function prototype.
3967 struct ExtProtoInfo {
3968 FunctionType::ExtInfo ExtInfo;
3969 bool Variadic : 1;
3970 bool HasTrailingReturn : 1;
3971 Qualifiers TypeQuals;
3972 RefQualifierKind RefQualifier = RQ_None;
3973 ExceptionSpecInfo ExceptionSpec;
3974 const ExtParameterInfo *ExtParameterInfos = nullptr;
3975 SourceLocation EllipsisLoc;
3976
3977 ExtProtoInfo() : Variadic(false), HasTrailingReturn(false) {}
3978
3979 ExtProtoInfo(CallingConv CC)
3980 : ExtInfo(CC), Variadic(false), HasTrailingReturn(false) {}
3981
3982 ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &ESI) {
3983 ExtProtoInfo Result(*this);
3984 Result.ExceptionSpec = ESI;
3985 return Result;
3986 }
3987 };
3988
3989private:
3990 unsigned numTrailingObjects(OverloadToken<QualType>) const {
3991 return getNumParams();
3992 }
3993
3994 unsigned numTrailingObjects(OverloadToken<SourceLocation>) const {
3995 return isVariadic();
3996 }
3997
3998 unsigned numTrailingObjects(OverloadToken<FunctionTypeExtraBitfields>) const {
3999 return hasExtraBitfields();
4000 }
4001
4002 unsigned numTrailingObjects(OverloadToken<ExceptionType>) const {
4003 return getExceptionSpecSize().NumExceptionType;
4004 }
4005
4006 unsigned numTrailingObjects(OverloadToken<Expr *>) const {
4007 return getExceptionSpecSize().NumExprPtr;
4008 }
4009
4010 unsigned numTrailingObjects(OverloadToken<FunctionDecl *>) const {
4011 return getExceptionSpecSize().NumFunctionDeclPtr;
4012 }
4013
4014 unsigned numTrailingObjects(OverloadToken<ExtParameterInfo>) const {
4015 return hasExtParameterInfos() ? getNumParams() : 0;
4016 }
4017
4018 /// Determine whether there are any argument types that
4019 /// contain an unexpanded parameter pack.
4020 static bool containsAnyUnexpandedParameterPack(const QualType *ArgArray,
4021 unsigned numArgs) {
4022 for (unsigned Idx = 0; Idx < numArgs; ++Idx)
4023 if (ArgArray[Idx]->containsUnexpandedParameterPack())
4024 return true;
4025
4026 return false;
4027 }
4028
4029 FunctionProtoType(QualType result, ArrayRef<QualType> params,
4030 QualType canonical, const ExtProtoInfo &epi);
4031
4032 /// This struct is returned by getExceptionSpecSize and is used to
4033 /// translate an ExceptionSpecificationType to the number and kind
4034 /// of trailing objects related to the exception specification.
4035 struct ExceptionSpecSizeHolder {
4036 unsigned NumExceptionType;
4037 unsigned NumExprPtr;
4038 unsigned NumFunctionDeclPtr;
4039 };
4040
4041 /// Return the number and kind of trailing objects
4042 /// related to the exception specification.
4043 static ExceptionSpecSizeHolder
4044 getExceptionSpecSize(ExceptionSpecificationType EST, unsigned NumExceptions) {
4045 switch (EST) {
4046 case EST_None:
4047 case EST_DynamicNone:
4048 case EST_MSAny:
4049 case EST_BasicNoexcept:
4050 case EST_Unparsed:
4051 case EST_NoThrow:
4052 return {0, 0, 0};
4053
4054 case EST_Dynamic:
4055 return {NumExceptions, 0, 0};
4056
4057 case EST_DependentNoexcept:
4058 case EST_NoexceptFalse:
4059 case EST_NoexceptTrue:
4060 return {0, 1, 0};
4061
4062 case EST_Uninstantiated:
4063 return {0, 0, 2};
4064
4065 case EST_Unevaluated:
4066 return {0, 0, 1};
4067 }
4068 llvm_unreachable("bad exception specification kind")__builtin_unreachable();
4069 }
4070
4071 /// Return the number and kind of trailing objects
4072 /// related to the exception specification.
4073 ExceptionSpecSizeHolder getExceptionSpecSize() const {
4074 return getExceptionSpecSize(getExceptionSpecType(), getNumExceptions());
4075 }
4076
4077 /// Whether the trailing FunctionTypeExtraBitfields is present.
4078 static bool hasExtraBitfields(ExceptionSpecificationType EST) {
4079 // If the exception spec type is EST_Dynamic then we have > 0 exception
4080 // types and the exact number is stored in FunctionTypeExtraBitfields.
4081 return EST == EST_Dynamic;
4082 }
4083
4084 /// Whether the trailing FunctionTypeExtraBitfields is present.
4085 bool hasExtraBitfields() const {
4086 return hasExtraBitfields(getExceptionSpecType());
4087 }
4088
4089 bool hasExtQualifiers() const {
4090 return FunctionTypeBits.HasExtQuals;
4091 }
4092
4093public:
4094 unsigned getNumParams() const { return FunctionTypeBits.NumParams; }
4095
4096 QualType getParamType(unsigned i) const {
4097 assert(i < getNumParams() && "invalid parameter index")(static_cast<void> (0));
4098 return param_type_begin()[i];
4099 }
4100
4101 ArrayRef<QualType> getParamTypes() const {
4102 return llvm::makeArrayRef(param_type_begin(), param_type_end());
4103 }
4104
4105 ExtProtoInfo getExtProtoInfo() const {
4106 ExtProtoInfo EPI;
4107 EPI.ExtInfo = getExtInfo();
4108 EPI.Variadic = isVariadic();
4109 EPI.EllipsisLoc = getEllipsisLoc();
4110 EPI.HasTrailingReturn = hasTrailingReturn();
4111 EPI.ExceptionSpec = getExceptionSpecInfo();
4112 EPI.TypeQuals = getMethodQuals();
4113 EPI.RefQualifier = getRefQualifier();
4114 EPI.ExtParameterInfos = getExtParameterInfosOrNull();
4115 return EPI;
4116 }
4117
4118 /// Get the kind of exception specification on this function.
4119 ExceptionSpecificationType getExceptionSpecType() const {
4120 return static_cast<ExceptionSpecificationType>(
4121 FunctionTypeBits.ExceptionSpecType);
4122 }
4123
4124 /// Return whether this function has any kind of exception spec.
4125 bool hasExceptionSpec() const { return getExceptionSpecType() != EST_None; }
4126
4127 /// Return whether this function has a dynamic (throw) exception spec.
4128 bool hasDynamicExceptionSpec() const {
4129 return isDynamicExceptionSpec(getExceptionSpecType());
4130 }
4131
4132 /// Return whether this function has a noexcept exception spec.
4133 bool hasNoexceptExceptionSpec() const {
4134 return isNoexceptExceptionSpec(getExceptionSpecType());
4135 }
4136
4137 /// Return whether this function has a dependent exception spec.
4138 bool hasDependentExceptionSpec() const;
4139
4140 /// Return whether this function has an instantiation-dependent exception
4141 /// spec.
4142 bool hasInstantiationDependentExceptionSpec() const;
4143
4144 /// Return all the available information about this type's exception spec.
4145 ExceptionSpecInfo getExceptionSpecInfo() const {
4146 ExceptionSpecInfo Result;
4147 Result.Type = getExceptionSpecType();
4148 if (Result.Type == EST_Dynamic) {
4149 Result.Exceptions = exceptions();
4150 } else if (isComputedNoexcept(Result.Type)) {
4151 Result.NoexceptExpr = getNoexceptExpr();
4152 } else if (Result.Type == EST_Uninstantiated) {
4153 Result.SourceDecl = getExceptionSpecDecl();
4154 Result.SourceTemplate = getExceptionSpecTemplate();
4155 } else if (Result.Type == EST_Unevaluated) {
4156 Result.SourceDecl = getExceptionSpecDecl();
4157 }
4158 return Result;
4159 }
4160
4161 /// Return the number of types in the exception specification.
4162 unsigned getNumExceptions() const {
4163 return getExceptionSpecType() == EST_Dynamic
4164 ? getTrailingObjects<FunctionTypeExtraBitfields>()
4165 ->NumExceptionType
4166 : 0;
4167 }
4168
4169 /// Return the ith exception type, where 0 <= i < getNumExceptions().
4170 QualType getExceptionType(unsigned i) const {
4171 assert(i < getNumExceptions() && "Invalid exception number!")(static_cast<void> (0));
4172 return exception_begin()[i];
4173 }
4174
4175 /// Return the expression inside noexcept(expression), or a null pointer
4176 /// if there is none (because the exception spec is not of this form).
4177 Expr *getNoexceptExpr() const {
4178 if (!isComputedNoexcept(getExceptionSpecType()))
4179 return nullptr;
4180 return *getTrailingObjects<Expr *>();
4181 }
4182
4183 /// If this function type has an exception specification which hasn't
4184 /// been determined yet (either because it has not been evaluated or because
4185 /// it has not been instantiated), this is the function whose exception
4186 /// specification is represented by this type.
4187 FunctionDecl *getExceptionSpecDecl() const {
4188 if (getExceptionSpecType() != EST_Uninstantiated &&
4189 getExceptionSpecType() != EST_Unevaluated)
4190 return nullptr;
4191 return getTrailingObjects<FunctionDecl *>()[0];
4192 }
4193
4194 /// If this function type has an uninstantiated exception
4195 /// specification, this is the function whose exception specification
4196 /// should be instantiated to find the exception specification for
4197 /// this type.
4198 FunctionDecl *getExceptionSpecTemplate() const {
4199 if (getExceptionSpecType() != EST_Uninstantiated)
4200 return nullptr;
4201 return getTrailingObjects<FunctionDecl *>()[1];
4202 }
4203
4204 /// Determine whether this function type has a non-throwing exception
4205 /// specification.
4206 CanThrowResult canThrow() const;
4207
4208 /// Determine whether this function type has a non-throwing exception
4209 /// specification. If this depends on template arguments, returns
4210 /// \c ResultIfDependent.
4211 bool isNothrow(bool ResultIfDependent = false) const {
4212 return ResultIfDependent ? canThrow() != CT_Can : canThrow() == CT_Cannot;
4213 }
4214
4215 /// Whether this function prototype is variadic.
4216 bool isVariadic() const { return FunctionTypeBits.Variadic; }
4217
4218 SourceLocation getEllipsisLoc() const {
4219 return isVariadic() ? *getTrailingObjects<SourceLocation>()
4220 : SourceLocation();
4221 }
4222
4223 /// Determines whether this function prototype contains a
4224 /// parameter pack at the end.
4225 ///
4226 /// A function template whose last parameter is a parameter pack can be
4227 /// called with an arbitrary number of arguments, much like a variadic
4228 /// function.
4229 bool isTemplateVariadic() const;
4230
4231 /// Whether this function prototype has a trailing return type.
4232 bool hasTrailingReturn() const { return FunctionTypeBits.HasTrailingReturn; }
4233
4234 Qualifiers getMethodQuals() const {
4235 if (hasExtQualifiers())
4236 return *getTrailingObjects<Qualifiers>();
4237 else
4238 return getFastTypeQuals();
4239 }
4240
4241 /// Retrieve the ref-qualifier associated with this function type.
4242 RefQualifierKind getRefQualifier() const {
4243 return static_cast<RefQualifierKind>(FunctionTypeBits.RefQualifier);
4244 }
4245
4246 using param_type_iterator = const QualType *;
4247 using param_type_range = llvm::iterator_range<param_type_iterator>;
4248
4249 param_type_range param_types() const {
4250 return param_type_range(param_type_begin(), param_type_end());
4251 }
4252
4253 param_type_iterator param_type_begin() const {
4254 return getTrailingObjects<QualType>();
4255 }
4256
4257 param_type_iterator param_type_end() const {
4258 return param_type_begin() + getNumParams();
4259 }
4260
4261 using exception_iterator = const QualType *;
4262
4263 ArrayRef<QualType> exceptions() const {
4264 return llvm::makeArrayRef(exception_begin(), exception_end());
4265 }
4266
4267 exception_iterator exception_begin() const {
4268 return reinterpret_cast<exception_iterator>(
4269 getTrailingObjects<ExceptionType>());
4270 }
4271
4272 exception_iterator exception_end() const {
4273 return exception_begin() + getNumExceptions();
4274 }
4275
4276 /// Is there any interesting extra information for any of the parameters
4277 /// of this function type?
4278 bool hasExtParameterInfos() const {
4279 return FunctionTypeBits.HasExtParameterInfos;
4280 }
4281
4282 ArrayRef<ExtParameterInfo> getExtParameterInfos() const {
4283 assert(hasExtParameterInfos())(static_cast<void> (0));
4284 return ArrayRef<ExtParameterInfo>(getTrailingObjects<ExtParameterInfo>(),
4285 getNumParams());
4286 }
4287
4288 /// Return a pointer to the beginning of the array of extra parameter
4289 /// information, if present, or else null if none of the parameters
4290 /// carry it. This is equivalent to getExtProtoInfo().ExtParameterInfos.
4291 const ExtParameterInfo *getExtParameterInfosOrNull() const {
4292 if (!hasExtParameterInfos())
4293 return nullptr;
4294 return getTrailingObjects<ExtParameterInfo>();
4295 }
4296
4297 ExtParameterInfo getExtParameterInfo(unsigned I) const {
4298 assert(I < getNumParams() && "parameter index out of range")(static_cast<void> (0));
4299 if (hasExtParameterInfos())
4300 return getTrailingObjects<ExtParameterInfo>()[I];
4301 return ExtParameterInfo();
4302 }
4303
4304 ParameterABI getParameterABI(unsigned I) const {
4305 assert(I < getNumParams() && "parameter index out of range")(static_cast<void> (0));
4306 if (hasExtParameterInfos())
4307 return getTrailingObjects<ExtParameterInfo>()[I].getABI();
4308 return ParameterABI::Ordinary;
4309 }
4310
4311 bool isParamConsumed(unsigned I) const {
4312 assert(I < getNumParams() && "parameter index out of range")(static_cast<void> (0));
4313 if (hasExtParameterInfos())
4314 return getTrailingObjects<ExtParameterInfo>()[I].isConsumed();
4315 return false;
4316 }
4317
4318 bool isSugared() const { return false; }
4319 QualType desugar() const { return QualType(this, 0); }
4320
4321 void printExceptionSpecification(raw_ostream &OS,
4322 const PrintingPolicy &Policy) const;
4323
4324 static bool classof(const Type *T) {
4325 return T->getTypeClass() == FunctionProto;
4326 }
4327
4328 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx);
4329 static void Profile(llvm::FoldingSetNodeID &ID, QualType Result,
4330 param_type_iterator ArgTys, unsigned NumArgs,
4331 const ExtProtoInfo &EPI, const ASTContext &Context,
4332 bool Canonical);
4333};
4334
4335/// Represents the dependent type named by a dependently-scoped
4336/// typename using declaration, e.g.
4337/// using typename Base<T>::foo;
4338///
4339/// Template instantiation turns these into the underlying type.
4340class UnresolvedUsingType : public Type {
4341 friend class ASTContext; // ASTContext creates these.
4342
4343 UnresolvedUsingTypenameDecl *Decl;
4344
4345 UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D)
4346 : Type(UnresolvedUsing, QualType(),
4347 TypeDependence::DependentInstantiation),
4348 Decl(const_cast<UnresolvedUsingTypenameDecl *>(D)) {}
4349
4350public:
4351 UnresolvedUsingTypenameDecl *getDecl() const { return Decl; }
4352
4353 bool isSugared() const { return false; }
4354 QualType desugar() const { return QualType(this, 0); }
4355
4356 static bool classof(const Type *T) {
4357 return T->getTypeClass() == UnresolvedUsing;
4358 }
4359
4360 void Profile(llvm::FoldingSetNodeID &ID) {
4361 return Profile(ID, Decl);
4362 }
4363
4364 static void Profile(llvm::FoldingSetNodeID &ID,
4365 UnresolvedUsingTypenameDecl *D) {
4366 ID.AddPointer(D);
4367 }
4368};
4369
4370class TypedefType : public Type {
4371 TypedefNameDecl *Decl;
4372
4373private:
4374 friend class ASTContext; // ASTContext creates these.
4375
4376 TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType underlying,
4377 QualType can);
4378
4379public:
4380 TypedefNameDecl *getDecl() const { return Decl; }
4381
4382 bool isSugared() const { return true; }
4383 QualType desugar() const;
4384
4385 static bool classof(const Type *T) { return T->getTypeClass() == Typedef; }
4386};
4387
4388/// Sugar type that represents a type that was qualified by a qualifier written
4389/// as a macro invocation.
4390class MacroQualifiedType : public Type {
4391 friend class ASTContext; // ASTContext creates these.
4392
4393 QualType UnderlyingTy;
4394 const IdentifierInfo *MacroII;
4395
4396 MacroQualifiedType(QualType UnderlyingTy, QualType CanonTy,
4397 const IdentifierInfo *MacroII)
4398 : Type(MacroQualified, CanonTy, UnderlyingTy->getDependence()),
4399 UnderlyingTy(UnderlyingTy), MacroII(MacroII) {
4400 assert(isa<AttributedType>(UnderlyingTy) &&(static_cast<void> (0))
4401 "Expected a macro qualified type to only wrap attributed types.")(static_cast<void> (0));
4402 }
4403
4404public:
4405 const IdentifierInfo *getMacroIdentifier() const { return MacroII; }
4406 QualType getUnderlyingType() const { return UnderlyingTy; }
4407
4408 /// Return this attributed type's modified type with no qualifiers attached to
4409 /// it.
4410 QualType getModifiedType() const;
4411
4412 bool isSugared() const { return true; }
4413 QualType desugar() const;
4414
4415 static bool classof(const Type *T) {
4416 return T->getTypeClass() == MacroQualified;
4417 }
4418};
4419
4420/// Represents a `typeof` (or __typeof__) expression (a GCC extension).
4421class TypeOfExprType : public Type {
4422 Expr *TOExpr;
4423
4424protected:
4425 friend class ASTContext; // ASTContext creates these.
4426
4427 TypeOfExprType(Expr *E, QualType can = QualType());
4428
4429public:
4430 Expr *getUnderlyingExpr() const { return TOExpr; }
4431
4432 /// Remove a single level of sugar.
4433 QualType desugar() const;
4434
4435 /// Returns whether this type directly provides sugar.
4436 bool isSugared() const;
4437
4438 static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; }
4439};
4440
4441/// Internal representation of canonical, dependent
4442/// `typeof(expr)` types.
4443///
4444/// This class is used internally by the ASTContext to manage
4445/// canonical, dependent types, only. Clients will only see instances
4446/// of this class via TypeOfExprType nodes.
4447class DependentTypeOfExprType
4448 : public TypeOfExprType, public llvm::FoldingSetNode {
4449 const ASTContext &Context;
4450
4451public:
4452 DependentTypeOfExprType(const ASTContext &Context, Expr *E)
4453 : TypeOfExprType(E), Context(Context) {}
4454
4455 void Profile(llvm::FoldingSetNodeID &ID) {
4456 Profile(ID, Context, getUnderlyingExpr());
4457 }
4458
4459 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
4460 Expr *E);
4461};
4462
4463/// Represents `typeof(type)`, a GCC extension.
4464class TypeOfType : public Type {
4465 friend class ASTContext; // ASTContext creates these.
4466
4467 QualType TOType;
4468
4469 TypeOfType(QualType T, QualType can)
4470 : Type(TypeOf, can, T->getDependence()), TOType(T) {
4471 assert(!isa<TypedefType>(can) && "Invalid canonical type")(static_cast<void> (0));
4472 }
4473
4474public:
4475 QualType getUnderlyingType() const { return TOType; }
4476
4477 /// Remove a single level of sugar.
4478 QualType desugar() const { return getUnderlyingType(); }
4479
4480 /// Returns whether this type directly provides sugar.
4481 bool isSugared() const { return true; }
4482
4483 static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; }
4484};
4485
4486/// Represents the type `decltype(expr)` (C++11).
4487class DecltypeType : public Type {
4488 Expr *E;
4489 QualType UnderlyingType;
4490
4491protected:
4492 friend class ASTContext; // ASTContext creates these.
4493
4494 DecltypeType(Expr *E, QualType underlyingType, QualType can = QualType());
4495
4496public:
4497 Expr *getUnderlyingExpr() const { return E; }
4498 QualType getUnderlyingType() const { return UnderlyingType; }
4499
4500 /// Remove a single level of sugar.
4501 QualType desugar() const;
4502
4503 /// Returns whether this type directly provides sugar.
4504 bool isSugared() const;
4505
4506 static bool classof(const Type *T) { return T->getTypeClass() == Decltype; }
4507};
4508
4509/// Internal representation of canonical, dependent
4510/// decltype(expr) types.
4511///
4512/// This class is used internally by the ASTContext to manage
4513/// canonical, dependent types, only. Clients will only see instances
4514/// of this class via DecltypeType nodes.
4515class DependentDecltypeType : public DecltypeType, public llvm::FoldingSetNode {
4516 const ASTContext &Context;
4517
4518public:
4519 DependentDecltypeType(const ASTContext &Context, Expr *E);
4520
4521 void Profile(llvm::FoldingSetNodeID &ID) {
4522 Profile(ID, Context, getUnderlyingExpr());
4523 }
4524
4525 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
4526 Expr *E);
4527};
4528
4529/// A unary type transform, which is a type constructed from another.
4530class UnaryTransformType : public Type {
4531public:
4532 enum UTTKind {
4533 EnumUnderlyingType
4534 };
4535
4536private:
4537 /// The untransformed type.
4538 QualType BaseType;
4539
4540 /// The transformed type if not dependent, otherwise the same as BaseType.
4541 QualType UnderlyingType;
4542
4543 UTTKind UKind;
4544
4545protected:
4546 friend class ASTContext;
4547
4548 UnaryTransformType(QualType BaseTy, QualType UnderlyingTy, UTTKind UKind,
4549 QualType CanonicalTy);
4550
4551public:
4552 bool isSugared() const { return !isDependentType(); }
4553 QualType desugar() const { return UnderlyingType; }
4554
4555 QualType getUnderlyingType() const { return UnderlyingType; }
4556 QualType getBaseType() const { return BaseType; }
4557
4558 UTTKind getUTTKind() const { return UKind; }
4559
4560 static bool classof(const Type *T) {
4561 return T->getTypeClass() == UnaryTransform;
4562 }
4563};
4564
4565/// Internal representation of canonical, dependent
4566/// __underlying_type(type) types.
4567///
4568/// This class is used internally by the ASTContext to manage
4569/// canonical, dependent types, only. Clients will only see instances
4570/// of this class via UnaryTransformType nodes.
4571class DependentUnaryTransformType : public UnaryTransformType,
4572 public llvm::FoldingSetNode {
4573public:
4574 DependentUnaryTransformType(const ASTContext &C, QualType BaseType,
4575 UTTKind UKind);
4576
4577 void Profile(llvm::FoldingSetNodeID &ID) {
4578 Profile(ID, getBaseType(), getUTTKind());
4579 }
4580
4581 static void Profile(llvm::FoldingSetNodeID &ID, QualType BaseType,
4582 UTTKind UKind) {
4583 ID.AddPointer(BaseType.getAsOpaquePtr());
4584 ID.AddInteger((unsigned)UKind);
4585 }
4586};
4587
4588class TagType : public Type {
4589 friend class ASTReader;
4590 template <class T> friend class serialization::AbstractTypeReader;
4591
4592 /// Stores the TagDecl associated with this type. The decl may point to any
4593 /// TagDecl that declares the entity.
4594 TagDecl *decl;
4595
4596protected:
4597 TagType(TypeClass TC, const TagDecl *D, QualType can);
4598
4599public:
4600 TagDecl *getDecl() const;
4601
4602 /// Determines whether this type is in the process of being defined.
4603 bool isBeingDefined() const;
4604
4605 static bool classof(const Type *T) {
4606 return T->getTypeClass() == Enum || T->getTypeClass() == Record;
4607 }
4608};
4609
4610/// A helper class that allows the use of isa/cast/dyncast
4611/// to detect TagType objects of structs/unions/classes.
4612class RecordType : public TagType {
4613protected:
4614 friend class ASTContext; // ASTContext creates these.
4615
4616 explicit RecordType(const RecordDecl *D)
4617 : TagType(Record, reinterpret_cast<const TagDecl*>(D), QualType()) {}
4618 explicit RecordType(TypeClass TC, RecordDecl *D)
4619 : TagType(TC, reinterpret_cast<const TagDecl*>(D), QualType()) {}
4620
4621public:
4622 RecordDecl *getDecl() const {
4623 return reinterpret_cast<RecordDecl*>(TagType::getDecl());
4624 }
4625
4626 /// Recursively check all fields in the record for const-ness. If any field
4627 /// is declared const, return true. Otherwise, return false.
4628 bool hasConstFields() const;
4629
4630 bool isSugared() const { return false; }
4631 QualType desugar() const { return QualType(this, 0); }
4632
4633 static bool classof(const Type *T) { return T->getTypeClass() == Record; }
4634};
4635
4636/// A helper class that allows the use of isa/cast/dyncast
4637/// to detect TagType objects of enums.
4638class EnumType : public TagType {
4639 friend class ASTContext; // ASTContext creates these.
4640
4641 explicit EnumType(const EnumDecl *D)
4642 : TagType(Enum, reinterpret_cast<const TagDecl*>(D), QualType()) {}
4643
4644public:
4645 EnumDecl *getDecl() const {
4646 return reinterpret_cast<EnumDecl*>(TagType::getDecl());
4647 }
4648
4649 bool isSugared() const { return false; }
4650 QualType desugar() const { return QualType(this, 0); }
4651
4652 static bool classof(const Type *T) { return T->getTypeClass() == Enum; }
4653};
4654
4655/// An attributed type is a type to which a type attribute has been applied.
4656///
4657/// The "modified type" is the fully-sugared type to which the attributed
4658/// type was applied; generally it is not canonically equivalent to the
4659/// attributed type. The "equivalent type" is the minimally-desugared type
4660/// which the type is canonically equivalent to.
4661///
4662/// For example, in the following attributed type:
4663/// int32_t __attribute__((vector_size(16)))
4664/// - the modified type is the TypedefType for int32_t
4665/// - the equivalent type is VectorType(16, int32_t)
4666/// - the canonical type is VectorType(16, int)
4667class AttributedType : public Type, public llvm::FoldingSetNode {
4668public:
4669 using Kind = attr::Kind;
4670
4671private:
4672 friend class ASTContext; // ASTContext creates these
4673
4674 QualType ModifiedType;
4675 QualType EquivalentType;
4676
4677 AttributedType(QualType canon, attr::Kind attrKind, QualType modified,
4678 QualType equivalent)
4679 : Type(Attributed, canon, equivalent->getDependence()),
4680 ModifiedType(modified), EquivalentType(equivalent) {
4681 AttributedTypeBits.AttrKind = attrKind;
4682 }
4683
4684public:
4685 Kind getAttrKind() const {
4686 return static_cast<Kind>(AttributedTypeBits.AttrKind);
4687 }
4688
4689 QualType getModifiedType() const { return ModifiedType; }
4690 QualType getEquivalentType() const { return EquivalentType; }
4691
4692 bool isSugared() const { return true; }
4693 QualType desugar() const { return getEquivalentType(); }
4694
4695 /// Does this attribute behave like a type qualifier?
4696 ///
4697 /// A type qualifier adjusts a type to provide specialized rules for
4698 /// a specific object, like the standard const and volatile qualifiers.
4699 /// This includes attributes controlling things like nullability,
4700 /// address spaces, and ARC ownership. The value of the object is still
4701 /// largely described by the modified type.
4702 ///
4703 /// In contrast, many type attributes "rewrite" their modified type to
4704 /// produce a fundamentally different type, not necessarily related in any
4705 /// formalizable way to the original type. For example, calling convention
4706 /// and vector attributes are not simple type qualifiers.
4707 ///
4708 /// Type qualifiers are often, but not always, reflected in the canonical
4709 /// type.
4710 bool isQualifier() const;
4711
4712 bool isMSTypeSpec() const;
4713
4714 bool isCallingConv() const;
4715
4716 llvm::Optional<NullabilityKind> getImmediateNullability() const;
4717
4718 /// Retrieve the attribute kind corresponding to the given
4719 /// nullability kind.
4720 static Kind getNullabilityAttrKind(NullabilityKind kind) {
4721 switch (kind) {
4722 case NullabilityKind::NonNull:
4723 return attr::TypeNonNull;
4724
4725 case NullabilityKind::Nullable:
4726 return attr::TypeNullable;
4727
4728 case NullabilityKind::NullableResult:
4729 return attr::TypeNullableResult;
4730
4731 case NullabilityKind::Unspecified:
4732 return attr::TypeNullUnspecified;
4733 }
4734 llvm_unreachable("Unknown nullability kind.")__builtin_unreachable();
4735 }
4736
4737 /// Strip off the top-level nullability annotation on the given
4738 /// type, if it's there.
4739 ///
4740 /// \param T The type to strip. If the type is exactly an
4741 /// AttributedType specifying nullability (without looking through
4742 /// type sugar), the nullability is returned and this type changed
4743 /// to the underlying modified type.
4744 ///
4745 /// \returns the top-level nullability, if present.
4746 static Optional<NullabilityKind> stripOuterNullability(QualType &T);
4747
4748 void Profile(llvm::FoldingSetNodeID &ID) {
4749 Profile(ID, getAttrKind(), ModifiedType, EquivalentType);
4750 }
4751
4752 static void Profile(llvm::FoldingSetNodeID &ID, Kind attrKind,
4753 QualType modified, QualType equivalent) {
4754 ID.AddInteger(attrKind);
4755 ID.AddPointer(modified.getAsOpaquePtr());
4756 ID.AddPointer(equivalent.getAsOpaquePtr());
4757 }
4758
4759 static bool classof(const Type *T) {
4760 return T->getTypeClass() == Attributed;
4761 }
4762};
4763
4764class TemplateTypeParmType : public Type, public llvm::FoldingSetNode {
4765 friend class ASTContext; // ASTContext creates these
4766
4767 // Helper data collector for canonical types.
4768 struct CanonicalTTPTInfo {
4769 unsigned Depth : 15;
4770 unsigned ParameterPack : 1;
4771 unsigned Index : 16;
4772 };
4773
4774 union {
4775 // Info for the canonical type.
4776 CanonicalTTPTInfo CanTTPTInfo;
4777
4778 // Info for the non-canonical type.
4779 TemplateTypeParmDecl *TTPDecl;
4780 };
4781
4782 /// Build a non-canonical type.
4783 TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon)
4784 : Type(TemplateTypeParm, Canon,
4785 TypeDependence::DependentInstantiation |
4786 (Canon->getDependence() & TypeDependence::UnexpandedPack)),
4787 TTPDecl(TTPDecl) {}
4788
4789 /// Build the canonical type.
4790 TemplateTypeParmType(unsigned D, unsigned I, bool PP)
4791 : Type(TemplateTypeParm, QualType(this, 0),
4792 TypeDependence::DependentInstantiation |
4793 (PP ? TypeDependence::UnexpandedPack : TypeDependence::None)) {
4794 CanTTPTInfo.Depth = D;
4795 CanTTPTInfo.Index = I;
4796 CanTTPTInfo.ParameterPack = PP;
4797 }
4798
4799 const CanonicalTTPTInfo& getCanTTPTInfo() const {
4800 QualType Can = getCanonicalTypeInternal();
4801 return Can->castAs<TemplateTypeParmType>()->CanTTPTInfo;
4802 }
4803
4804public:
4805 unsigned getDepth() const { return getCanTTPTInfo().Depth; }
4806 unsigned getIndex() const { return getCanTTPTInfo().Index; }
4807 bool isParameterPack() const { return getCanTTPTInfo().ParameterPack; }
4808
4809 TemplateTypeParmDecl *getDecl() const {
4810 return isCanonicalUnqualified() ? nullptr : TTPDecl;
4811 }
4812
4813 IdentifierInfo *getIdentifier() const;
4814
4815 bool isSugared() const { return false; }
4816 QualType desugar() const { return QualType(this, 0); }
4817
4818 void Profile(llvm::FoldingSetNodeID &ID) {
4819 Profile(ID, getDepth(), getIndex(), isParameterPack(), getDecl());
4820 }
4821
4822 static void Profile(llvm::FoldingSetNodeID &ID, unsigned Depth,
4823 unsigned Index, bool ParameterPack,
4824 TemplateTypeParmDecl *TTPDecl) {
4825 ID.AddInteger(Depth);
4826 ID.AddInteger(Index);
4827 ID.AddBoolean(ParameterPack);
4828 ID.AddPointer(TTPDecl);
4829 }
4830
4831 static bool classof(const Type *T) {
4832 return T->getTypeClass() == TemplateTypeParm;
4833 }
4834};
4835
4836/// Represents the result of substituting a type for a template
4837/// type parameter.
4838///
4839/// Within an instantiated template, all template type parameters have
4840/// been replaced with these. They are used solely to record that a
4841/// type was originally written as a template type parameter;
4842/// therefore they are never canonical.
4843class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode {
4844 friend class ASTContext;
4845
4846 // The original type parameter.
4847 const TemplateTypeParmType *Replaced;
4848
4849 SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon)
4850 : Type(SubstTemplateTypeParm, Canon, Canon->getDependence()),
4851 Replaced(Param) {}
4852
4853public:
4854 /// Gets the template parameter that was substituted for.
4855 const TemplateTypeParmType *getReplacedParameter() const {
4856 return Replaced;
4857 }
4858
4859 /// Gets the type that was substituted for the template
4860 /// parameter.
4861 QualType getReplacementType() const {
4862 return getCanonicalTypeInternal();
4863 }
4864
4865 bool isSugared() const { return true; }
4866 QualType desugar() const { return getReplacementType(); }
4867
4868 void Profile(llvm::FoldingSetNodeID &ID) {
4869 Profile(ID, getReplacedParameter(), getReplacementType());
4870 }
4871
4872 static void Profile(llvm::FoldingSetNodeID &ID,
4873 const TemplateTypeParmType *Replaced,
4874 QualType Replacement) {
4875 ID.AddPointer(Replaced);
4876 ID.AddPointer(Replacement.getAsOpaquePtr());
4877 }
4878
4879 static bool classof(const Type *T) {
4880 return T->getTypeClass() == SubstTemplateTypeParm;
4881 }
4882};
4883
4884/// Represents the result of substituting a set of types for a template
4885/// type parameter pack.
4886///
4887/// When a pack expansion in the source code contains multiple parameter packs
4888/// and those parameter packs correspond to different levels of template
4889/// parameter lists, this type node is used to represent a template type
4890/// parameter pack from an outer level, which has already had its argument pack
4891/// substituted but that still lives within a pack expansion that itself
4892/// could not be instantiated. When actually performing a substitution into
4893/// that pack expansion (e.g., when all template parameters have corresponding
4894/// arguments), this type will be replaced with the \c SubstTemplateTypeParmType
4895/// at the current pack substitution index.
4896class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
4897 friend class ASTContext;
4898
4899 /// The original type parameter.
4900 const TemplateTypeParmType *Replaced;
4901
4902 /// A pointer to the set of template arguments that this
4903 /// parameter pack is instantiated with.
4904 const TemplateArgument *Arguments;
4905
4906 SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param,
4907 QualType Canon,
4908 const TemplateArgument &ArgPack);
4909
4910public:
4911 IdentifierInfo *getIdentifier() const { return Replaced->getIdentifier(); }
4912
4913 /// Gets the template parameter that was substituted for.
4914 const TemplateTypeParmType *getReplacedParameter() const {
4915 return Replaced;
4916 }
4917
4918 unsigned getNumArgs() const {
4919 return SubstTemplateTypeParmPackTypeBits.NumArgs;
4920 }
4921
4922 bool isSugared() const { return false; }
4923 QualType desugar() const { return QualType(this, 0); }
4924
4925 TemplateArgument getArgumentPack() const;
4926
4927 void Profile(llvm::FoldingSetNodeID &ID);
4928 static void Profile(llvm::FoldingSetNodeID &ID,
4929 const TemplateTypeParmType *Replaced,
4930 const TemplateArgument &ArgPack);
4931
4932 static bool classof(const Type *T) {
4933 return T->getTypeClass() == SubstTemplateTypeParmPack;
4934 }
4935};
4936
4937/// Common base class for placeholders for types that get replaced by
4938/// placeholder type deduction: C++11 auto, C++14 decltype(auto), C++17 deduced
4939/// class template types, and constrained type names.
4940///
4941/// These types are usually a placeholder for a deduced type. However, before
4942/// the initializer is attached, or (usually) if the initializer is
4943/// type-dependent, there is no deduced type and the type is canonical. In
4944/// the latter case, it is also a dependent type.
4945class DeducedType : public Type {
4946protected:
4947 DeducedType(TypeClass TC, QualType DeducedAsType,
4948 TypeDependence ExtraDependence)
4949 : Type(TC,
4950 // FIXME: Retain the sugared deduced type?
4951 DeducedAsType.isNull() ? QualType(this, 0)
4952 : DeducedAsType.getCanonicalType(),
4953 ExtraDependence | (DeducedAsType.isNull()
4954 ? TypeDependence::None
4955 : DeducedAsType->getDependence() &
4956 ~TypeDependence::VariablyModified)) {}
4957
4958public:
4959 bool isSugared() const { return !isCanonicalUnqualified(); }
4960 QualType desugar() const { return getCanonicalTypeInternal(); }
4961
4962 /// Get the type deduced for this placeholder type, or null if it's
4963 /// either not been deduced or was deduced to a dependent type.
4964 QualType getDeducedType() const {
4965 return !isCanonicalUnqualified() ? getCanonicalTypeInternal() : QualType();
4966 }
4967 bool isDeduced() const {
4968 return !isCanonicalUnqualified() || isDependentType();
4969 }
4970
4971 static bool classof(const Type *T) {
4972 return T->getTypeClass() == Auto ||
4973 T->getTypeClass() == DeducedTemplateSpecialization;
4974 }
4975};
4976
4977/// Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained
4978/// by a type-constraint.
4979class alignas(8) AutoType : public DeducedType, public llvm::FoldingSetNode {
4980 friend class ASTContext; // ASTContext creates these
4981
4982 ConceptDecl *TypeConstraintConcept;
4983
4984 AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword,
4985 TypeDependence ExtraDependence, ConceptDecl *CD,
4986 ArrayRef<TemplateArgument> TypeConstraintArgs);
4987
4988 const TemplateArgument *getArgBuffer() const {
4989 return reinterpret_cast<const TemplateArgument*>(this+1);
4990 }
4991
4992 TemplateArgument *getArgBuffer() {
4993 return reinterpret_cast<TemplateArgument*>(this+1);
4994 }
4995
4996public:
4997 /// Retrieve the template arguments.
4998 const TemplateArgument *getArgs() const {
4999 return getArgBuffer();
5000 }
5001
5002 /// Retrieve the number of template arguments.
5003 unsigned getNumArgs() const {
5004 return AutoTypeBits.NumArgs;
5005 }
5006
5007 const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
5008
5009 ArrayRef<TemplateArgument> getTypeConstraintArguments() const {
5010 return {getArgs(), getNumArgs()};
5011 }
5012
5013 ConceptDecl *getTypeConstraintConcept() const {
5014 return TypeConstraintConcept;
5015 }
5016
5017 bool isConstrained() const {
5018 return TypeConstraintConcept != nullptr;
5019 }
5020
5021 bool isDecltypeAuto() const {
5022 return getKeyword() == AutoTypeKeyword::DecltypeAuto;
5023 }
5024
5025 AutoTypeKeyword getKeyword() const {
5026 return (AutoTypeKeyword)AutoTypeBits.Keyword;
5027 }
5028
5029 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
5030 Profile(ID, Context, getDeducedType(), getKeyword(), isDependentType(),
5031 getTypeConstraintConcept(), getTypeConstraintArguments());
5032 }
5033
5034 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
5035 QualType Deduced, AutoTypeKeyword Keyword,
5036 bool IsDependent, ConceptDecl *CD,
5037 ArrayRef<TemplateArgument> Arguments);
5038
5039 static bool classof(const Type *T) {
5040 return T->getTypeClass() == Auto;
5041 }
5042};
5043
5044/// Represents a C++17 deduced template specialization type.
5045class DeducedTemplateSpecializationType : public DeducedType,
5046 public llvm::FoldingSetNode {
5047 friend class ASTContext; // ASTContext creates these
5048
5049 /// The name of the template whose arguments will be deduced.
5050 TemplateName Template;
5051
5052 DeducedTemplateSpecializationType(TemplateName Template,
5053 QualType DeducedAsType,
5054 bool IsDeducedAsDependent)
5055 : DeducedType(DeducedTemplateSpecialization, DeducedAsType,
5056 toTypeDependence(Template.getDependence()) |
5057 (IsDeducedAsDependent
5058 ? TypeDependence::DependentInstantiation
5059 : TypeDependence::None)),
5060 Template(Template) {}
5061
5062public:
5063 /// Retrieve the name of the template that we are deducing.
5064 TemplateName getTemplateName() const { return Template;}
5065
5066 void Profile(llvm::FoldingSetNodeID &ID) {
5067 Profile(ID, getTemplateName(), getDeducedType(), isDependentType());
5068 }
5069
5070 static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Template,
5071 QualType Deduced, bool IsDependent) {
5072 Template.Profile(ID);
5073 ID.AddPointer(Deduced.getAsOpaquePtr());
5074 ID.AddBoolean(IsDependent);
5075 }
5076
5077 static bool classof(const Type *T) {
5078 return T->getTypeClass() == DeducedTemplateSpecialization;
5079 }
5080};
5081
5082/// Represents a type template specialization; the template
5083/// must be a class template, a type alias template, or a template
5084/// template parameter. A template which cannot be resolved to one of
5085/// these, e.g. because it is written with a dependent scope
5086/// specifier, is instead represented as a
5087/// @c DependentTemplateSpecializationType.
5088///
5089/// A non-dependent template specialization type is always "sugar",
5090/// typically for a \c RecordType. For example, a class template
5091/// specialization type of \c vector<int> will refer to a tag type for
5092/// the instantiation \c std::vector<int, std::allocator<int>>
5093///
5094/// Template specializations are dependent if either the template or
5095/// any of the template arguments are dependent, in which case the
5096/// type may also be canonical.
5097///
5098/// Instances of this type are allocated with a trailing array of
5099/// TemplateArguments, followed by a QualType representing the
5100/// non-canonical aliased type when the template is a type alias
5101/// template.
5102class alignas(8) TemplateSpecializationType
5103 : public Type,
5104 public llvm::FoldingSetNode {
5105 friend class ASTContext; // ASTContext creates these
5106
5107 /// The name of the template being specialized. This is
5108 /// either a TemplateName::Template (in which case it is a
5109 /// ClassTemplateDecl*, a TemplateTemplateParmDecl*, or a
5110 /// TypeAliasTemplateDecl*), a
5111 /// TemplateName::SubstTemplateTemplateParmPack, or a
5112 /// TemplateName::SubstTemplateTemplateParm (in which case the
5113 /// replacement must, recursively, be one of these).
5114 TemplateName Template;
5115
5116 TemplateSpecializationType(TemplateName T,
5117 ArrayRef<TemplateArgument> Args,
5118 QualType Canon,
5119 QualType Aliased);
5120
5121public:
5122 /// Determine whether any of the given template arguments are dependent.
5123 ///
5124 /// The converted arguments should be supplied when known; whether an
5125 /// argument is dependent can depend on the conversions performed on it
5126 /// (for example, a 'const int' passed as a template argument might be
5127 /// dependent if the parameter is a reference but non-dependent if the
5128 /// parameter is an int).
5129 ///
5130 /// Note that the \p Args parameter is unused: this is intentional, to remind
5131 /// the caller that they need to pass in the converted arguments, not the
5132 /// specified arguments.
5133 static bool
5134 anyDependentTemplateArguments(ArrayRef<TemplateArgumentLoc> Args,
5135 ArrayRef<TemplateArgument> Converted);
5136 static bool
5137 anyDependentTemplateArguments(const TemplateArgumentListInfo &,
5138 ArrayRef<TemplateArgument> Converted);
5139 static bool anyInstantiationDependentTemplateArguments(
5140 ArrayRef<TemplateArgumentLoc> Args);
5141
5142 /// True if this template specialization type matches a current
5143 /// instantiation in the context in which it is found.
5144 bool isCurrentInstantiation() const {
5145 return isa<InjectedClassNameType>(getCanonicalTypeInternal());
5146 }
5147
5148 /// Determine if this template specialization type is for a type alias
5149 /// template that has been substituted.
5150 ///
5151 /// Nearly every template specialization type whose template is an alias
5152 /// template will be substituted. However, this is not the case when
5153 /// the specialization contains a pack expansion but the template alias
5154 /// does not have a corresponding parameter pack, e.g.,
5155 ///
5156 /// \code
5157 /// template<typename T, typename U, typename V> struct S;
5158 /// template<typename T, typename U> using A = S<T, int, U>;
5159 /// template<typename... Ts> struct X {
5160 /// typedef A<Ts...> type; // not a type alias
5161 /// };
5162 /// \endcode
5163 bool isTypeAlias() const { return TemplateSpecializationTypeBits.TypeAlias; }
5164
5165 /// Get the aliased type, if this is a specialization of a type alias
5166 /// template.
5167 QualType getAliasedType() const {
5168 assert(isTypeAlias() && "not a type alias template specialization")(static_cast<void> (0));
5169 return *reinterpret_cast<const QualType*>(end());
5170 }
5171
5172 using iterator = const TemplateArgument *;
5173
5174 iterator begin() const { return getArgs(); }
5175 iterator end() const; // defined inline in TemplateBase.h
5176
5177 /// Retrieve the name of the template that we are specializing.
5178 TemplateName getTemplateName() const { return Template; }
5179
5180 /// Retrieve the template arguments.
5181 const TemplateArgument *getArgs() const {
5182 return reinterpret_cast<const TemplateArgument *>(this + 1);
5183 }
5184
5185 /// Retrieve the number of template arguments.
5186 unsigned getNumArgs() const {
5187 return TemplateSpecializationTypeBits.NumArgs;
5188 }
5189
5190 /// Retrieve a specific template argument as a type.
5191 /// \pre \c isArgType(Arg)
5192 const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
5193
5194 ArrayRef<TemplateArgument> template_arguments() const {
5195 return {getArgs(), getNumArgs()};
5196 }
5197
5198 bool isSugared() const {
5199 return !isDependentType() || isCurrentInstantiation() || isTypeAlias();
5200 }
5201
5202 QualType desugar() const {
5203 return isTypeAlias() ? getAliasedType() : getCanonicalTypeInternal();
5204 }
5205
5206 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) {
5207 Profile(ID, Template, template_arguments(), Ctx);
5208 if (isTypeAlias())
5209 getAliasedType().Profile(ID);
5210 }
5211
5212 static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
5213 ArrayRef<TemplateArgument> Args,
5214 const ASTContext &Context);
5215
5216 static bool classof(const Type *T) {
5217 return T->getTypeClass() == TemplateSpecialization;
5218 }
5219};
5220
5221/// Print a template argument list, including the '<' and '>'
5222/// enclosing the template arguments.
5223void printTemplateArgumentList(raw_ostream &OS,
5224 ArrayRef<TemplateArgument> Args,
5225 const PrintingPolicy &Policy,
5226 const TemplateParameterList *TPL = nullptr);
5227
5228void printTemplateArgumentList(raw_ostream &OS,
5229 ArrayRef<TemplateArgumentLoc> Args,
5230 const PrintingPolicy &Policy,
5231 const TemplateParameterList *TPL = nullptr);
5232
5233void printTemplateArgumentList(raw_ostream &OS,
5234 const TemplateArgumentListInfo &Args,
5235 const PrintingPolicy &Policy,
5236 const TemplateParameterList *TPL = nullptr);
5237
5238/// The injected class name of a C++ class template or class
5239/// template partial specialization. Used to record that a type was
5240/// spelled with a bare identifier rather than as a template-id; the
5241/// equivalent for non-templated classes is just RecordType.
5242///
5243/// Injected class name types are always dependent. Template
5244/// instantiation turns these into RecordTypes.
5245///
5246/// Injected class name types are always canonical. This works
5247/// because it is impossible to compare an injected class name type
5248/// with the corresponding non-injected template type, for the same
5249/// reason that it is impossible to directly compare template
5250/// parameters from different dependent contexts: injected class name
5251/// types can only occur within the scope of a particular templated
5252/// declaration, and within that scope every template specialization
5253/// will canonicalize to the injected class name (when appropriate
5254/// according to the rules of the language).
5255class InjectedClassNameType : public Type {
5256 friend class ASTContext; // ASTContext creates these.
5257 friend class ASTNodeImporter;
5258 friend class ASTReader; // FIXME: ASTContext::getInjectedClassNameType is not
5259 // currently suitable for AST reading, too much
5260 // interdependencies.
5261 template <class T> friend class serialization::AbstractTypeReader;
5262
5263 CXXRecordDecl *Decl;
5264
5265 /// The template specialization which this type represents.
5266 /// For example, in
5267 /// template <class T> class A { ... };
5268 /// this is A<T>, whereas in
5269 /// template <class X, class Y> class A<B<X,Y> > { ... };
5270 /// this is A<B<X,Y> >.
5271 ///
5272 /// It is always unqualified, always a template specialization type,
5273 /// and always dependent.
5274 QualType InjectedType;
5275
5276 InjectedClassNameType(CXXRecordDecl *D, QualType TST)
5277 : Type(InjectedClassName, QualType(),
5278 TypeDependence::DependentInstantiation),
5279 Decl(D), InjectedType(TST) {
5280 assert(isa<TemplateSpecializationType>(TST))(static_cast<void> (0));
5281 assert(!TST.hasQualifiers())(static_cast<void> (0));
5282 assert(TST->isDependentType())(static_cast<void> (0));
5283 }
5284
5285public:
5286 QualType getInjectedSpecializationType() const { return InjectedType; }
5287
5288 const TemplateSpecializationType *getInjectedTST() const {
5289 return cast<TemplateSpecializationType>(InjectedType.getTypePtr());
5290 }
5291
5292 TemplateName getTemplateName() const {
5293 return getInjectedTST()->getTemplateName();
5294 }
5295
5296 CXXRecordDecl *getDecl() const;
5297
5298 bool isSugared() const { return false; }
5299 QualType desugar() const { return QualType(this, 0); }
5300
5301 static bool classof(const Type *T) {
5302 return T->getTypeClass() == InjectedClassName;
5303 }
5304};
5305
5306/// The kind of a tag type.
5307enum TagTypeKind {
5308 /// The "struct" keyword.
5309 TTK_Struct,
5310
5311 /// The "__interface" keyword.
5312 TTK_Interface,
5313
5314 /// The "union" keyword.
5315 TTK_Union,
5316
5317 /// The "class" keyword.
5318 TTK_Class,
5319
5320 /// The "enum" keyword.
5321 TTK_Enum
5322};
5323
5324/// The elaboration keyword that precedes a qualified type name or
5325/// introduces an elaborated-type-specifier.
5326enum ElaboratedTypeKeyword {
5327 /// The "struct" keyword introduces the elaborated-type-specifier.
5328 ETK_Struct,
5329
5330 /// The "__interface" keyword introduces the elaborated-type-specifier.
5331 ETK_Interface,
5332
5333 /// The "union" keyword introduces the elaborated-type-specifier.
5334 ETK_Union,
5335
5336 /// The "class" keyword introduces the elaborated-type-specifier.
5337 ETK_Class,
5338
5339 /// The "enum" keyword introduces the elaborated-type-specifier.
5340 ETK_Enum,
5341
5342 /// The "typename" keyword precedes the qualified type name, e.g.,
5343 /// \c typename T::type.
5344 ETK_Typename,
5345
5346 /// No keyword precedes the qualified type name.
5347 ETK_None
5348};
5349
5350/// A helper class for Type nodes having an ElaboratedTypeKeyword.
5351/// The keyword in stored in the free bits of the base class.
5352/// Also provides a few static helpers for converting and printing
5353/// elaborated type keyword and tag type kind enumerations.
5354class TypeWithKeyword : public Type {
5355protected:
5356 TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc,
5357 QualType Canonical, TypeDependence Dependence)
5358 : Type(tc, Canonical, Dependence) {
5359 TypeWithKeywordBits.Keyword = Keyword;
5360 }
5361
5362public:
5363 ElaboratedTypeKeyword getKeyword() const {
5364 return static_cast<ElaboratedTypeKeyword>(TypeWithKeywordBits.Keyword);
5365 }
5366
5367 /// Converts a type specifier (DeclSpec::TST) into an elaborated type keyword.
5368 static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec);
5369
5370 /// Converts a type specifier (DeclSpec::TST) into a tag type kind.
5371 /// It is an error to provide a type specifier which *isn't* a tag kind here.
5372 static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec);
5373
5374 /// Converts a TagTypeKind into an elaborated type keyword.
5375 static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag);
5376
5377 /// Converts an elaborated type keyword into a TagTypeKind.
5378 /// It is an error to provide an elaborated type keyword
5379 /// which *isn't* a tag kind here.
5380 static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword);
5381
5382 static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword);
5383
5384 static StringRef getKeywordName(ElaboratedTypeKeyword Keyword);
5385
5386 static StringRef getTagTypeKindName(TagTypeKind Kind) {
5387 return getKeywordName(getKeywordForTagTypeKind(Kind));
5388 }
5389
5390 class CannotCastToThisType {};
5391 static CannotCastToThisType classof(const Type *);
5392};
5393
5394/// Represents a type that was referred to using an elaborated type
5395/// keyword, e.g., struct S, or via a qualified name, e.g., N::M::type,
5396/// or both.
5397///
5398/// This type is used to keep track of a type name as written in the
5399/// source code, including tag keywords and any nested-name-specifiers.
5400/// The type itself is always "sugar", used to express what was written
5401/// in the source code but containing no additional semantic information.
5402class ElaboratedType final
5403 : public TypeWithKeyword,
5404 public llvm::FoldingSetNode,
5405 private llvm::TrailingObjects<ElaboratedType, TagDecl *> {
5406 friend class ASTContext; // ASTContext creates these
5407 friend TrailingObjects;
5408
5409 /// The nested name specifier containing the qualifier.
5410 NestedNameSpecifier *NNS;
5411
5412 /// The type that this qualified name refers to.
5413 QualType NamedType;
5414
5415 /// The (re)declaration of this tag type owned by this occurrence is stored
5416 /// as a trailing object if there is one. Use getOwnedTagDecl to obtain
5417 /// it, or obtain a null pointer if there is none.
5418
5419 ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
5420 QualType NamedType, QualType CanonType, TagDecl *OwnedTagDecl)
5421 : TypeWithKeyword(Keyword, Elaborated, CanonType,
5422 // Any semantic dependence on the qualifier will have
5423 // been incorporated into NamedType. We still need to
5424 // track syntactic (instantiation / error / pack)
5425 // dependence on the qualifier.
5426 NamedType->getDependence() |
5427 (NNS ? toSyntacticDependence(
5428 toTypeDependence(NNS->getDependence()))
5429 : TypeDependence::None)),
5430 NNS(NNS), NamedType(NamedType) {
5431 ElaboratedTypeBits.HasOwnedTagDecl = false;
5432 if (OwnedTagDecl) {
5433 ElaboratedTypeBits.HasOwnedTagDecl = true;
5434 *getTrailingObjects<TagDecl *>() = OwnedTagDecl;
5435 }
5436 assert(!(Keyword == ETK_None && NNS == nullptr) &&(static_cast<void> (0))
5437 "ElaboratedType cannot have elaborated type keyword "(static_cast<void> (0))
5438 "and name qualifier both null.")(static_cast<void> (0));
5439 }
5440
5441public:
5442 /// Retrieve the qualification on this type.
5443 NestedNameSpecifier *getQualifier() const { return NNS; }
5444
5445 /// Retrieve the type named by the qualified-id.
5446 QualType getNamedType() const { return NamedType; }
5447
5448 /// Remove a single level of sugar.
5449 QualType desugar() const { return getNamedType(); }
5450
5451 /// Returns whether this type directly provides sugar.
5452 bool isSugared() const { return true; }
5453
5454 /// Return the (re)declaration of this type owned by this occurrence of this
5455 /// type, or nullptr if there is none.
5456 TagDecl *getOwnedTagDecl() const {
5457 return ElaboratedTypeBits.HasOwnedTagDecl ? *getTrailingObjects<TagDecl *>()
5458 : nullptr;
5459 }
5460
5461 void Profile(llvm::FoldingSetNodeID &ID) {
5462 Profile(ID, getKeyword(), NNS, NamedType, getOwnedTagDecl());
5463 }
5464
5465 static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
5466 NestedNameSpecifier *NNS, QualType NamedType,
5467 TagDecl *OwnedTagDecl) {
5468 ID.AddInteger(Keyword);
5469 ID.AddPointer(NNS);
5470 NamedType.Profile(ID);
5471 ID.AddPointer(OwnedTagDecl);
5472 }
5473
5474 static bool classof(const Type *T) { return T->getTypeClass() == Elaborated; }
5475};
5476
5477/// Represents a qualified type name for which the type name is
5478/// dependent.
5479///
5480/// DependentNameType represents a class of dependent types that involve a
5481/// possibly dependent nested-name-specifier (e.g., "T::") followed by a
5482/// name of a type. The DependentNameType may start with a "typename" (for a
5483/// typename-specifier), "class", "struct", "union", or "enum" (for a
5484/// dependent elaborated-type-specifier), or nothing (in contexts where we
5485/// know that we must be referring to a type, e.g., in a base class specifier).
5486/// Typically the nested-name-specifier is dependent, but in MSVC compatibility
5487/// mode, this type is used with non-dependent names to delay name lookup until
5488/// instantiation.
5489class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
5490 friend class ASTContext; // ASTContext creates these
5491
5492 /// The nested name specifier containing the qualifier.
5493 NestedNameSpecifier *NNS;
5494
5495 /// The type that this typename specifier refers to.
5496 const IdentifierInfo *Name;
5497
5498 DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
5499 const IdentifierInfo *Name, QualType CanonType)
5500 : TypeWithKeyword(Keyword, DependentName, CanonType,
5501 TypeDependence::DependentInstantiation |
5502 toTypeDependence(NNS->getDependence())),
5503 NNS(NNS), Name(Name) {}
5504
5505public:
5506 /// Retrieve the qualification on this type.
5507 NestedNameSpecifier *getQualifier() const { return NNS; }
5508
5509 /// Retrieve the type named by the typename specifier as an identifier.
5510 ///
5511 /// This routine will return a non-NULL identifier pointer when the
5512 /// form of the original typename was terminated by an identifier,
5513 /// e.g., "typename T::type".
5514 const IdentifierInfo *getIdentifier() const {
5515 return Name;
5516 }
5517
5518 bool isSugared() const { return false; }
5519 QualType desugar() const { return QualType(this, 0); }
5520
5521 void Profile(llvm::FoldingSetNodeID &ID) {
5522 Profile(ID, getKeyword(), NNS, Name);
5523 }
5524
5525 static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
5526 NestedNameSpecifier *NNS, const IdentifierInfo *Name) {
5527 ID.AddInteger(Keyword);
5528 ID.AddPointer(NNS);
5529 ID.AddPointer(Name);
5530 }
5531
5532 static bool classof(const Type *T) {
5533 return T->getTypeClass() == DependentName;
5534 }
5535};
5536
5537/// Represents a template specialization type whose template cannot be
5538/// resolved, e.g.
5539/// A<T>::template B<T>
5540class alignas(8) DependentTemplateSpecializationType
5541 : public TypeWithKeyword,
5542 public llvm::FoldingSetNode {
5543 friend class ASTContext; // ASTContext creates these
5544
5545 /// The nested name specifier containing the qualifier.
5546 NestedNameSpecifier *NNS;
5547
5548 /// The identifier of the template.
5549 const IdentifierInfo *Name;
5550
5551 DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
5552 NestedNameSpecifier *NNS,
5553 const IdentifierInfo *Name,
5554 ArrayRef<TemplateArgument> Args,
5555 QualType Canon);
5556
5557 const TemplateArgument *getArgBuffer() const {
5558 return reinterpret_cast<const TemplateArgument*>(this+1);
5559 }
5560
5561 TemplateArgument *getArgBuffer() {
5562 return reinterpret_cast<TemplateArgument*>(this+1);
5563 }
5564
5565public:
5566 NestedNameSpecifier *getQualifier() const { return NNS; }
5567 const IdentifierInfo *getIdentifier() const { return Name; }
5568
5569 /// Retrieve the template arguments.
5570 const TemplateArgument *getArgs() const {
5571 return getArgBuffer();
5572 }
5573
5574 /// Retrieve the number of template arguments.
5575 unsigned getNumArgs() const {
5576 return DependentTemplateSpecializationTypeBits.NumArgs;
5577 }
5578
5579 const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
5580
5581 ArrayRef<TemplateArgument> template_arguments() const {
5582 return {getArgs(), getNumArgs()};
5583 }
5584
5585 using iterator = const TemplateArgument *;
5586
5587 iterator begin() const { return getArgs(); }
5588 iterator end() const; // inline in TemplateBase.h
5589
5590 bool isSugared() const { return false; }
5591 QualType desugar() const { return QualType(this, 0); }
5592
5593 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
5594 Profile(ID, Context, getKeyword(), NNS, Name, {getArgs(), getNumArgs()});
5595 }
5596
5597 static void Profile(llvm::FoldingSetNodeID &ID,
5598 const ASTContext &Context,
5599 ElaboratedTypeKeyword Keyword,
5600 NestedNameSpecifier *Qualifier,
5601 const IdentifierInfo *Name,
5602 ArrayRef<TemplateArgument> Args);
5603
5604 static bool classof(const Type *T) {
5605 return T->getTypeClass() == DependentTemplateSpecialization;
5606 }
5607};
5608
5609/// Represents a pack expansion of types.
5610///
5611/// Pack expansions are part of C++11 variadic templates. A pack
5612/// expansion contains a pattern, which itself contains one or more
5613/// "unexpanded" parameter packs. When instantiated, a pack expansion
5614/// produces a series of types, each instantiated from the pattern of
5615/// the expansion, where the Ith instantiation of the pattern uses the
5616/// Ith arguments bound to each of the unexpanded parameter packs. The
5617/// pack expansion is considered to "expand" these unexpanded
5618/// parameter packs.
5619///
5620/// \code
5621/// template<typename ...Types> struct tuple;
5622///
5623/// template<typename ...Types>
5624/// struct tuple_of_references {
5625/// typedef tuple<Types&...> type;
5626/// };
5627/// \endcode
5628///
5629/// Here, the pack expansion \c Types&... is represented via a
5630/// PackExpansionType whose pattern is Types&.
5631class PackExpansionType : public Type, public llvm::FoldingSetNode {
5632 friend class ASTContext; // ASTContext creates these
5633
5634 /// The pattern of the pack expansion.
5635 QualType Pattern;
5636
5637 PackExpansionType(QualType Pattern, QualType Canon,
5638 Optional<unsigned> NumExpansions)
5639 : Type(PackExpansion, Canon,
5640 (Pattern->getDependence() | TypeDependence::Dependent |
5641 TypeDependence::Instantiation) &
5642 ~TypeDependence::UnexpandedPack),
5643 Pattern(Pattern) {
5644 PackExpansionTypeBits.NumExpansions =
5645 NumExpansions ? *NumExpansions + 1 : 0;
5646 }
5647
5648public:
5649 /// Retrieve the pattern of this pack expansion, which is the
5650 /// type that will be repeatedly instantiated when instantiating the
5651 /// pack expansion itself.
5652 QualType getPattern() const { return Pattern; }
5653
5654 /// Retrieve the number of expansions that this pack expansion will
5655 /// generate, if known.
5656 Optional<unsigned> getNumExpansions() const {
5657 if (PackExpansionTypeBits.NumExpansions)
5658 return PackExpansionTypeBits.NumExpansions - 1;
5659 return None;
5660 }
5661
5662 bool isSugared() const { return false; }
5663 QualType desugar() const { return QualType(this, 0); }
5664
5665 void Profile(llvm::FoldingSetNodeID &ID) {
5666 Profile(ID, getPattern(), getNumExpansions());
5667 }
5668
5669 static void Profile(llvm::FoldingSetNodeID &ID, QualType Pattern,
5670 Optional<unsigned> NumExpansions) {
5671 ID.AddPointer(Pattern.getAsOpaquePtr());
5672 ID.AddBoolean(NumExpansions.hasValue());
5673 if (NumExpansions)
5674 ID.AddInteger(*NumExpansions);
5675 }
5676
5677 static bool classof(const Type *T) {
5678 return T->getTypeClass() == PackExpansion;
5679 }
5680};
5681
5682/// This class wraps the list of protocol qualifiers. For types that can
5683/// take ObjC protocol qualifers, they can subclass this class.
5684template <class T>
5685class ObjCProtocolQualifiers {
5686protected:
5687 ObjCProtocolQualifiers() = default;
5688
5689 ObjCProtocolDecl * const *getProtocolStorage() const {
5690 return const_cast<ObjCProtocolQualifiers*>(this)->getProtocolStorage();
5691 }
5692
5693 ObjCProtocolDecl **getProtocolStorage() {
5694 return static_cast<T*>(this)->getProtocolStorageImpl();
5695 }
5696
5697 void setNumProtocols(unsigned N) {
5698 static_cast<T*>(this)->setNumProtocolsImpl(N);
5699 }
5700
5701 void initialize(ArrayRef<ObjCProtocolDecl *> protocols) {
5702 setNumProtocols(protocols.size());
5703 assert(getNumProtocols() == protocols.size() &&(static_cast<void> (0))
5704 "bitfield overflow in protocol count")(static_cast<void> (0));
5705 if (!protocols.empty())
5706 memcpy(getProtocolStorage(), protocols.data(),
5707 protocols.size() * sizeof(ObjCProtocolDecl*));
5708 }
5709
5710public:
5711 using qual_iterator = ObjCProtocolDecl * const *;
5712 using qual_range = llvm::iterator_range<qual_iterator>;
5713
5714 qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
5715 qual_iterator qual_begin() const { return getProtocolStorage(); }
5716 qual_iterator qual_end() const { return qual_begin() + getNumProtocols(); }
5717
5718 bool qual_empty() const { return getNumProtocols() == 0; }
5719
5720 /// Return the number of qualifying protocols in this type, or 0 if
5721 /// there are none.
5722 unsigned getNumProtocols() const {
5723 return static_cast<const T*>(this)->getNumProtocolsImpl();
5724 }
5725
5726 /// Fetch a protocol by index.
5727 ObjCProtocolDecl *getProtocol(unsigned I) const {
5728 assert(I < getNumProtocols() && "Out-of-range protocol access")(static_cast<void> (0));
5729 return qual_begin()[I];
5730 }
5731
5732 /// Retrieve all of the protocol qualifiers.
5733 ArrayRef<ObjCProtocolDecl *> getProtocols() const {
5734 return ArrayRef<ObjCProtocolDecl *>(qual_begin(), getNumProtocols());
5735 }
5736};
5737
5738/// Represents a type parameter type in Objective C. It can take
5739/// a list of protocols.
5740class ObjCTypeParamType : public Type,
5741 public ObjCProtocolQualifiers<ObjCTypeParamType>,
5742 public llvm::FoldingSetNode {
5743 friend class ASTContext;
5744 friend class ObjCProtocolQualifiers<ObjCTypeParamType>;
5745
5746 /// The number of protocols stored on this type.
5747 unsigned NumProtocols : 6;
5748
5749 ObjCTypeParamDecl *OTPDecl;
5750
5751 /// The protocols are stored after the ObjCTypeParamType node. In the
5752 /// canonical type, the list of protocols are sorted alphabetically
5753 /// and uniqued.
5754 ObjCProtocolDecl **getProtocolStorageImpl();
5755
5756 /// Return the number of qualifying protocols in this interface type,
5757 /// or 0 if there are none.
5758 unsigned getNumProtocolsImpl() const {
5759 return NumProtocols;
5760 }
5761
5762 void setNumProtocolsImpl(unsigned N) {
5763 NumProtocols = N;
5764 }
5765
5766 ObjCTypeParamType(const ObjCTypeParamDecl *D,
5767 QualType can,
5768 ArrayRef<ObjCProtocolDecl *> protocols);
5769
5770public:
5771 bool isSugared() const { return true; }
5772 QualType desugar() const { return getCanonicalTypeInternal(); }
5773
5774 static bool classof(const Type *T) {
5775 return T->getTypeClass() == ObjCTypeParam;
5776 }
5777
5778 void Profile(llvm::FoldingSetNodeID &ID);
5779 static void Profile(llvm::FoldingSetNodeID &ID,
5780 const ObjCTypeParamDecl *OTPDecl,
5781 QualType CanonicalType,
5782 ArrayRef<ObjCProtocolDecl *> protocols);
5783
5784 ObjCTypeParamDecl *getDecl() const { return OTPDecl; }
5785};
5786
5787/// Represents a class type in Objective C.
5788///
5789/// Every Objective C type is a combination of a base type, a set of
5790/// type arguments (optional, for parameterized classes) and a list of
5791/// protocols.
5792///
5793/// Given the following declarations:
5794/// \code
5795/// \@class C<T>;
5796/// \@protocol P;
5797/// \endcode
5798///
5799/// 'C' is an ObjCInterfaceType C. It is sugar for an ObjCObjectType
5800/// with base C and no protocols.
5801///
5802/// 'C<P>' is an unspecialized ObjCObjectType with base C and protocol list [P].
5803/// 'C<C*>' is a specialized ObjCObjectType with type arguments 'C*' and no
5804/// protocol list.
5805/// 'C<C*><P>' is a specialized ObjCObjectType with base C, type arguments 'C*',
5806/// and protocol list [P].
5807///
5808/// 'id' is a TypedefType which is sugar for an ObjCObjectPointerType whose
5809/// pointee is an ObjCObjectType with base BuiltinType::ObjCIdType
5810/// and no protocols.
5811///
5812/// 'id<P>' is an ObjCObjectPointerType whose pointee is an ObjCObjectType
5813/// with base BuiltinType::ObjCIdType and protocol list [P]. Eventually
5814/// this should get its own sugar class to better represent the source.
5815class ObjCObjectType : public Type,
5816 public ObjCProtocolQualifiers<ObjCObjectType> {
5817 friend class ObjCProtocolQualifiers<ObjCObjectType>;
5818
5819 // ObjCObjectType.NumTypeArgs - the number of type arguments stored
5820 // after the ObjCObjectPointerType node.
5821 // ObjCObjectType.NumProtocols - the number of protocols stored
5822 // after the type arguments of ObjCObjectPointerType node.
5823 //
5824 // These protocols are those written directly on the type. If
5825 // protocol qualifiers ever become additive, the iterators will need
5826 // to get kindof complicated.
5827 //
5828 // In the canonical object type, these are sorted alphabetically
5829 // and uniqued.
5830
5831 /// Either a BuiltinType or an InterfaceType or sugar for either.
5832 QualType BaseType;
5833
5834 /// Cached superclass type.
5835 mutable llvm::PointerIntPair<const ObjCObjectType *, 1, bool>
5836 CachedSuperClassType;
5837
5838 QualType *getTypeArgStorage();
5839 const QualType *getTypeArgStorage() const {
5840 return const_cast<ObjCObjectType *>(this)->getTypeArgStorage();
5841 }
5842
5843 ObjCProtocolDecl **getProtocolStorageImpl();
5844 /// Return the number of qualifying protocols in this interface type,
5845 /// or 0 if there are none.
5846 unsigned getNumProtocolsImpl() const {
5847 return ObjCObjectTypeBits.NumProtocols;
5848 }
5849 void setNumProtocolsImpl(unsigned N) {
5850 ObjCObjectTypeBits.NumProtocols = N;
5851 }
5852
5853protected:
5854 enum Nonce_ObjCInterface { Nonce_ObjCInterface };
5855
5856 ObjCObjectType(QualType Canonical, QualType Base,
5857 ArrayRef<QualType> typeArgs,
5858 ArrayRef<ObjCProtocolDecl *> protocols,
5859 bool isKindOf);
5860
5861 ObjCObjectType(enum Nonce_ObjCInterface)
5862 : Type(ObjCInterface, QualType(), TypeDependence::None),
5863 BaseType(QualType(this_(), 0)) {
5864 ObjCObjectTypeBits.NumProtocols = 0;
5865 ObjCObjectTypeBits.NumTypeArgs = 0;
5866 ObjCObjectTypeBits.IsKindOf = 0;
5867 }
5868
5869 void computeSuperClassTypeSlow() const;
5870
5871public:
5872 /// Gets the base type of this object type. This is always (possibly
5873 /// sugar for) one of:
5874 /// - the 'id' builtin type (as opposed to the 'id' type visible to the
5875 /// user, which is a typedef for an ObjCObjectPointerType)
5876 /// - the 'Class' builtin type (same caveat)
5877 /// - an ObjCObjectType (currently always an ObjCInterfaceType)
5878 QualType getBaseType() const { return BaseType; }
5879
5880 bool isObjCId() const {
5881 return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCId);
5882 }
5883
5884 bool isObjCClass() const {
5885 return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCClass);
5886 }
5887
5888 bool isObjCUnqualifiedId() const { return qual_empty() && isObjCId(); }
5889 bool isObjCUnqualifiedClass() const { return qual_empty() && isObjCClass(); }
5890 bool isObjCUnqualifiedIdOrClass() const {
5891 if (!qual_empty()) return false;
5892 if (const BuiltinType *T = getBaseType()->getAs<BuiltinType>())
5893 return T->getKind() == BuiltinType::ObjCId ||
5894 T->getKind() == BuiltinType::ObjCClass;
5895 return false;
5896 }
5897 bool isObjCQualifiedId() const { return !qual_empty() && isObjCId(); }
5898 bool isObjCQualifiedClass() const { return !qual_empty() && isObjCClass(); }
5899
5900 /// Gets the interface declaration for this object type, if the base type
5901 /// really is an interface.
5902 ObjCInterfaceDecl *getInterface() const;
5903
5904 /// Determine whether this object type is "specialized", meaning
5905 /// that it has type arguments.
5906 bool isSpecialized() const;
5907
5908 /// Determine whether this object type was written with type arguments.
5909 bool isSpecializedAsWritten() const {
5910 return ObjCObjectTypeBits.NumTypeArgs > 0;
5911 }
5912
5913 /// Determine whether this object type is "unspecialized", meaning
5914 /// that it has no type arguments.
5915 bool isUnspecialized() const { return !isSpecialized(); }
5916
5917 /// Determine whether this object type is "unspecialized" as
5918 /// written, meaning that it has no type arguments.
5919 bool isUnspecializedAsWritten() const { return !isSpecializedAsWritten(); }
5920
5921 /// Retrieve the type arguments of this object type (semantically).
5922 ArrayRef<QualType> getTypeArgs() const;
5923
5924 /// Retrieve the type arguments of this object type as they were
5925 /// written.
5926 ArrayRef<QualType> getTypeArgsAsWritten() const {
5927 return llvm::makeArrayRef(getTypeArgStorage(),
5928 ObjCObjectTypeBits.NumTypeArgs);
5929 }
5930
5931 /// Whether this is a "__kindof" type as written.
5932 bool isKindOfTypeAsWritten() const { return ObjCObjectTypeBits.IsKindOf; }
5933
5934 /// Whether this ia a "__kindof" type (semantically).
5935 bool isKindOfType() const;
5936
5937 /// Retrieve the type of the superclass of this object type.
5938 ///
5939 /// This operation substitutes any type arguments into the
5940 /// superclass of the current class type, potentially producing a
5941 /// specialization of the superclass type. Produces a null type if
5942 /// there is no superclass.
5943 QualType getSuperClassType() const {
5944 if (!CachedSuperClassType.getInt())
5945 computeSuperClassTypeSlow();
5946
5947 assert(CachedSuperClassType.getInt() && "Superclass not set?")(static_cast<void> (0));
5948 return QualType(CachedSuperClassType.getPointer(), 0);
5949 }
5950
5951 /// Strip off the Objective-C "kindof" type and (with it) any
5952 /// protocol qualifiers.
5953 QualType stripObjCKindOfTypeAndQuals(const ASTContext &ctx) const;
5954
5955 bool isSugared() const { return false; }
5956 QualType desugar() const { return QualType(this, 0); }
5957
5958 static bool classof(const Type *T) {
5959 return T->getTypeClass() == ObjCObject ||
5960 T->getTypeClass() == ObjCInterface;
5961 }
5962};
5963
5964/// A class providing a concrete implementation
5965/// of ObjCObjectType, so as to not increase the footprint of
5966/// ObjCInterfaceType. Code outside of ASTContext and the core type
5967/// system should not reference this type.
5968class ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode {
5969 friend class ASTContext;
5970
5971 // If anyone adds fields here, ObjCObjectType::getProtocolStorage()
5972 // will need to be modified.
5973
5974 ObjCObjectTypeImpl(QualType Canonical, QualType Base,
5975 ArrayRef<QualType> typeArgs,
5976 ArrayRef<ObjCProtocolDecl *> protocols,
5977 bool isKindOf)
5978 : ObjCObjectType(Canonical, Base, typeArgs, protocols, isKindOf) {}
5979
5980public:
5981 void Profile(llvm::FoldingSetNodeID &ID);
5982 static void Profile(llvm::FoldingSetNodeID &ID,
5983 QualType Base,
5984 ArrayRef<QualType> typeArgs,
5985 ArrayRef<ObjCProtocolDecl *> protocols,
5986 bool isKindOf);
5987};
5988
5989inline QualType *ObjCObjectType::getTypeArgStorage() {
5990 return reinterpret_cast<QualType *>(static_cast<ObjCObjectTypeImpl*>(this)+1);
5991}
5992
5993inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorageImpl() {
5994 return reinterpret_cast<ObjCProtocolDecl**>(
5995 getTypeArgStorage() + ObjCObjectTypeBits.NumTypeArgs);
5996}
5997
5998inline ObjCProtocolDecl **ObjCTypeParamType::getProtocolStorageImpl() {
5999 return reinterpret_cast<ObjCProtocolDecl**>(
6000 static_cast<ObjCTypeParamType*>(this)+1);
6001}
6002
6003/// Interfaces are the core concept in Objective-C for object oriented design.
6004/// They basically correspond to C++ classes. There are two kinds of interface
6005/// types: normal interfaces like `NSString`, and qualified interfaces, which
6006/// are qualified with a protocol list like `NSString<NSCopyable, NSAmazing>`.
6007///
6008/// ObjCInterfaceType guarantees the following properties when considered
6009/// as a subtype of its superclass, ObjCObjectType:
6010/// - There are no protocol qualifiers. To reinforce this, code which
6011/// tries to invoke the protocol methods via an ObjCInterfaceType will
6012/// fail to compile.
6013/// - It is its own base type. That is, if T is an ObjCInterfaceType*,
6014/// T->getBaseType() == QualType(T, 0).
6015class ObjCInterfaceType : public ObjCObjectType {
6016 friend class ASTContext; // ASTContext creates these.
6017 friend class ASTReader;
6018 friend class ObjCInterfaceDecl;
6019 template <class T> friend class serialization::AbstractTypeReader;
6020
6021 mutable ObjCInterfaceDecl *Decl;
6022
6023 ObjCInterfaceType(const ObjCInterfaceDecl *D)
6024 : ObjCObjectType(Nonce_ObjCInterface),
6025 Decl(const_cast<ObjCInterfaceDecl*>(D)) {}
6026
6027public:
6028 /// Get the declaration of this interface.
6029 ObjCInterfaceDecl *getDecl() const { return Decl; }
6030
6031 bool isSugared() const { return false; }
6032 QualType desugar() const { return QualType(this, 0); }
6033
6034 static bool classof(const Type *T) {
6035 return T->getTypeClass() == ObjCInterface;
6036 }
6037
6038 // Nonsense to "hide" certain members of ObjCObjectType within this
6039 // class. People asking for protocols on an ObjCInterfaceType are
6040 // not going to get what they want: ObjCInterfaceTypes are
6041 // guaranteed to have no protocols.
6042 enum {
6043 qual_iterator,
6044 qual_begin,
6045 qual_end,
6046 getNumProtocols,
6047 getProtocol
6048 };
6049};
6050
6051inline ObjCInterfaceDecl *ObjCObjectType::getInterface() const {
6052 QualType baseType = getBaseType();
6053 while (const auto *ObjT = baseType->getAs<ObjCObjectType>()) {
6054 if (const auto *T = dyn_cast<ObjCInterfaceType>(ObjT))
6055 return T->getDecl();
6056
6057 baseType = ObjT->getBaseType();
6058 }
6059
6060 return nullptr;
6061}
6062
6063/// Represents a pointer to an Objective C object.
6064///
6065/// These are constructed from pointer declarators when the pointee type is
6066/// an ObjCObjectType (or sugar for one). In addition, the 'id' and 'Class'
6067/// types are typedefs for these, and the protocol-qualified types 'id<P>'
6068/// and 'Class<P>' are translated into these.
6069///
6070/// Pointers to pointers to Objective C objects are still PointerTypes;
6071/// only the first level of pointer gets it own type implementation.
6072class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode {
6073 friend class ASTContext; // ASTContext creates these.
6074
6075 QualType PointeeType;
6076
6077 ObjCObjectPointerType(QualType Canonical, QualType Pointee)
6078 : Type(ObjCObjectPointer, Canonical, Pointee->getDependence()),
6079 PointeeType(Pointee) {}
6080
6081public:
6082 /// Gets the type pointed to by this ObjC pointer.
6083 /// The result will always be an ObjCObjectType or sugar thereof.
6084 QualType getPointeeType() const { return PointeeType; }
6085
6086 /// Gets the type pointed to by this ObjC pointer. Always returns non-null.
6087 ///
6088 /// This method is equivalent to getPointeeType() except that
6089 /// it discards any typedefs (or other sugar) between this
6090 /// type and the "outermost" object type. So for:
6091 /// \code
6092 /// \@class A; \@protocol P; \@protocol Q;
6093 /// typedef A<P> AP;
6094 /// typedef A A1;
6095 /// typedef A1<P> A1P;
6096 /// typedef A1P<Q> A1PQ;
6097 /// \endcode
6098 /// For 'A*', getObjectType() will return 'A'.
6099 /// For 'A<P>*', getObjectType() will return 'A<P>'.
6100 /// For 'AP*', getObjectType() will return 'A<P>'.
6101 /// For 'A1*', getObjectType() will return 'A'.
6102 /// For 'A1<P>*', getObjectType() will return 'A1<P>'.
6103 /// For 'A1P*', getObjectType() will return 'A1<P>'.
6104 /// For 'A1PQ*', getObjectType() will return 'A1<Q>', because
6105 /// adding protocols to a protocol-qualified base discards the
6106 /// old qualifiers (for now). But if it didn't, getObjectType()
6107 /// would return 'A1P<Q>' (and we'd have to make iterating over
6108 /// qualifiers more complicated).
6109 const ObjCObjectType *getObjectType() const {
6110 return PointeeType->castAs<ObjCObjectType>();
6111 }
6112
6113 /// If this pointer points to an Objective C
6114 /// \@interface type, gets the type for that interface. Any protocol
6115 /// qualifiers on the interface are ignored.
6116 ///
6117 /// \return null if the base type for this pointer is 'id' or 'Class'
6118 const ObjCInterfaceType *getInterfaceType() const;
6119
6120 /// If this pointer points to an Objective \@interface
6121 /// type, gets the declaration for that interface.
6122 ///
6123 /// \return null if the base type for this pointer is 'id' or 'Class'
6124 ObjCInterfaceDecl *getInterfaceDecl() const {
6125 return getObjectType()->getInterface();
6126 }
6127
6128 /// True if this is equivalent to the 'id' type, i.e. if
6129 /// its object type is the primitive 'id' type with no protocols.
6130 bool isObjCIdType() const {
6131 return getObjectType()->isObjCUnqualifiedId();
6132 }
6133
6134 /// True if this is equivalent to the 'Class' type,
6135 /// i.e. if its object tive is the primitive 'Class' type with no protocols.
6136 bool isObjCClassType() const {
6137 return getObjectType()->isObjCUnqualifiedClass();
6138 }
6139
6140 /// True if this is equivalent to the 'id' or 'Class' type,
6141 bool isObjCIdOrClassType() const {
6142 return getObjectType()->isObjCUnqualifiedIdOrClass();
6143 }
6144
6145 /// True if this is equivalent to 'id<P>' for some non-empty set of
6146 /// protocols.
6147 bool isObjCQualifiedIdType() const {
6148 return getObjectType()->isObjCQualifiedId();
6149 }
6150
6151 /// True if this is equivalent to 'Class<P>' for some non-empty set of
6152 /// protocols.
6153 bool isObjCQualifiedClassType() const {
6154 return getObjectType()->isObjCQualifiedClass();
6155 }
6156
6157 /// Whether this is a "__kindof" type.
6158 bool isKindOfType() const { return getObjectType()->isKindOfType(); }
6159
6160 /// Whether this type is specialized, meaning that it has type arguments.
6161 bool isSpecialized() const { return getObjectType()->isSpecialized(); }
6162
6163 /// Whether this type is specialized, meaning that it has type arguments.
6164 bool isSpecializedAsWritten() const {
6165 return getObjectType()->isSpecializedAsWritten();
6166 }
6167
6168 /// Whether this type is unspecialized, meaning that is has no type arguments.
6169 bool isUnspecialized() const { return getObjectType()->isUnspecialized(); }
6170
6171 /// Determine whether this object type is "unspecialized" as
6172 /// written, meaning that it has no type arguments.
6173 bool isUnspecializedAsWritten() const { return !isSpecializedAsWritten(); }
6174
6175 /// Retrieve the type arguments for this type.
6176 ArrayRef<QualType> getTypeArgs() const {
6177 return getObjectType()->getTypeArgs();
6178 }
6179
6180 /// Retrieve the type arguments for this type.
6181 ArrayRef<QualType> getTypeArgsAsWritten() const {
6182 return getObjectType()->getTypeArgsAsWritten();
6183 }
6184
6185 /// An iterator over the qualifiers on the object type. Provided
6186 /// for convenience. This will always iterate over the full set of
6187 /// protocols on a type, not just those provided directly.
6188 using qual_iterator = ObjCObjectType::qual_iterator;
6189 using qual_range = llvm::iterator_range<qual_iterator>;
6190
6191 qual_range quals() const { return qual_range(qual_begin(), qual_end()); }
6192
6193 qual_iterator qual_begin() const {
6194 return getObjectType()->qual_begin();
6195 }
6196
6197 qual_iterator qual_end() const {
6198 return getObjectType()->qual_end();
6199 }
6200
6201 bool qual_empty() const { return getObjectType()->qual_empty(); }
6202
6203 /// Return the number of qualifying protocols on the object type.
6204 unsigned getNumProtocols() const {
6205 return getObjectType()->getNumProtocols();
6206 }
6207
6208 /// Retrieve a qualifying protocol by index on the object type.
6209 ObjCProtocolDecl *getProtocol(unsigned I) const {
6210 return getObjectType()->getProtocol(I);
6211 }
6212
6213 bool isSugared() const { return false; }
6214 QualType desugar() const { return QualType(this, 0); }
6215
6216 /// Retrieve the type of the superclass of this object pointer type.
6217 ///
6218 /// This operation substitutes any type arguments into the
6219 /// superclass of the current class type, potentially producing a
6220 /// pointer to a specialization of the superclass type. Produces a
6221 /// null type if there is no superclass.
6222 QualType getSuperClassType() const;
6223
6224 /// Strip off the Objective-C "kindof" type and (with it) any
6225 /// protocol qualifiers.
6226 const ObjCObjectPointerType *stripObjCKindOfTypeAndQuals(
6227 const ASTContext &ctx) const;
6228
6229 void Profile(llvm::FoldingSetNodeID &ID) {
6230 Profile(ID, getPointeeType());
6231 }
6232
6233 static void Profile(llvm::FoldingSetNodeID &ID, QualType T) {
6234 ID.AddPointer(T.getAsOpaquePtr());
6235 }
6236
6237 static bool classof(const Type *T) {
6238 return T->getTypeClass() == ObjCObjectPointer;
6239 }
6240};
6241
6242class AtomicType : public Type, public llvm::FoldingSetNode {
6243 friend class ASTContext; // ASTContext creates these.
6244
6245 QualType ValueType;
6246
6247 AtomicType(QualType ValTy, QualType Canonical)
6248 : Type(Atomic, Canonical, ValTy->getDependence()), ValueType(ValTy) {}
6249
6250public:
6251 /// Gets the type contained by this atomic type, i.e.
6252 /// the type returned by performing an atomic load of this atomic type.
6253 QualType getValueType() const { return ValueType; }
6254
6255 bool isSugared() const { return false; }
6256 QualType desugar() const { return QualType(this, 0); }
6257
6258 void Profile(llvm::FoldingSetNodeID &ID) {
6259 Profile(ID, getValueType());
6260 }
6261
6262 static void Profile(llvm::FoldingSetNodeID &ID, QualType T) {
6263 ID.AddPointer(T.getAsOpaquePtr());
6264 }
6265
6266 static bool classof(const Type *T) {
6267 return T->getTypeClass() == Atomic;
6268 }
6269};
6270
6271/// PipeType - OpenCL20.
6272class PipeType : public Type, public llvm::FoldingSetNode {
6273 friend class ASTContext; // ASTContext creates these.
6274
6275 QualType ElementType;
6276 bool isRead;
6277
6278 PipeType(QualType elemType, QualType CanonicalPtr, bool isRead)
6279 : Type(Pipe, CanonicalPtr, elemType->getDependence()),
6280 ElementType(elemType), isRead(isRead) {}
6281
6282public:
6283 QualType getElementType() const { return ElementType; }
6284
6285 bool isSugared() const { return false; }
6286
6287 QualType desugar() const { return QualType(this, 0); }
6288
6289 void Profile(llvm::FoldingSetNodeID &ID) {
6290 Profile(ID, getElementType(), isReadOnly());
6291 }
6292
6293 static void Profile(llvm::FoldingSetNodeID &ID, QualType T, bool isRead) {
6294 ID.AddPointer(T.getAsOpaquePtr());
6295 ID.AddBoolean(isRead);
6296 }
6297
6298 static bool classof(const Type *T) {
6299 return T->getTypeClass() == Pipe;
6300 }
6301
6302 bool isReadOnly() const { return isRead; }
6303};
6304
6305/// A fixed int type of a specified bitwidth.
6306class ExtIntType final : public Type, public llvm::FoldingSetNode {
6307 friend class ASTContext;
6308 unsigned IsUnsigned : 1;
6309 unsigned NumBits : 24;
6310
6311protected:
6312 ExtIntType(bool isUnsigned, unsigned NumBits);
6313
6314public:
6315 bool isUnsigned() const { return IsUnsigned; }
6316 bool isSigned() const { return !IsUnsigned; }
6317 unsigned getNumBits() const { return NumBits; }
6318
6319 bool isSugared() const { return false; }
6320 QualType desugar() const { return QualType(this, 0); }
6321
6322 void Profile(llvm::FoldingSetNodeID &ID) {
6323 Profile(ID, isUnsigned(), getNumBits());
6324 }
6325
6326 static void Profile(llvm::FoldingSetNodeID &ID, bool IsUnsigned,
6327 unsigned NumBits) {
6328 ID.AddBoolean(IsUnsigned);
6329 ID.AddInteger(NumBits);
6330 }
6331
6332 static bool classof(const Type *T) { return T->getTypeClass() == ExtInt; }
6333};
6334
6335class DependentExtIntType final : public Type, public llvm::FoldingSetNode {
6336 friend class ASTContext;
6337 const ASTContext &Context;
6338 llvm::PointerIntPair<Expr*, 1, bool> ExprAndUnsigned;
6339
6340protected:
6341 DependentExtIntType(const ASTContext &Context, bool IsUnsigned,
6342 Expr *NumBits);
6343
6344public:
6345 bool isUnsigned() const;
6346 bool isSigned() const { return !isUnsigned(); }
6347 Expr *getNumBitsExpr() const;
6348
6349 bool isSugared() const { return false; }
6350 QualType desugar() const { return QualType(this, 0); }
6351
6352 void Profile(llvm::FoldingSetNodeID &ID) {
6353 Profile(ID, Context, isUnsigned(), getNumBitsExpr());
6354 }
6355 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
6356 bool IsUnsigned, Expr *NumBitsExpr);
6357
6358 static bool classof(const Type *T) {
6359 return T->getTypeClass() == DependentExtInt;
6360 }
6361};
6362
6363/// A qualifier set is used to build a set of qualifiers.
6364class QualifierCollector : public Qualifiers {
6365public:
6366 QualifierCollector(Qualifiers Qs = Qualifiers()) : Qualifiers(Qs) {}
6367
6368 /// Collect any qualifiers on the given type and return an
6369 /// unqualified type. The qualifiers are assumed to be consistent
6370 /// with those already in the type.
6371 const Type *strip(QualType type) {
6372 addFastQualifiers(type.getLocalFastQualifiers());
6373 if (!type.hasLocalNonFastQualifiers())
6374 return type.getTypePtrUnsafe();
6375
6376 const ExtQuals *extQuals = type.getExtQualsUnsafe();
6377 addConsistentQualifiers(extQuals->getQualifiers());
6378 return extQuals->getBaseType();
6379 }
6380
6381 /// Apply the collected qualifiers to the given type.
6382 QualType apply(const ASTContext &Context, QualType QT) const;
6383
6384 /// Apply the collected qualifiers to the given type.
6385 QualType apply(const ASTContext &Context, const Type* T) const;
6386};
6387
6388/// A container of type source information.
6389///
6390/// A client can read the relevant info using TypeLoc wrappers, e.g:
6391/// @code
6392/// TypeLoc TL = TypeSourceInfo->getTypeLoc();
6393/// TL.getBeginLoc().print(OS, SrcMgr);
6394/// @endcode
6395class alignas(8) TypeSourceInfo {
6396 // Contains a memory block after the class, used for type source information,
6397 // allocated by ASTContext.
6398 friend class ASTContext;
6399
6400 QualType Ty;
6401
6402 TypeSourceInfo(QualType ty) : Ty(ty) {}
6403
6404public:
6405 /// Return the type wrapped by this type source info.
6406 QualType getType() const { return Ty; }
6407
6408 /// Return the TypeLoc wrapper for the type source info.
6409 TypeLoc getTypeLoc() const; // implemented in TypeLoc.h
6410
6411 /// Override the type stored in this TypeSourceInfo. Use with caution!
6412 void overrideType(QualType T) { Ty = T; }
6413};
6414
6415// Inline function definitions.
6416
6417inline SplitQualType SplitQualType::getSingleStepDesugaredType() const {
6418 SplitQualType desugar =
6419 Ty->getLocallyUnqualifiedSingleStepDesugaredType().split();
6420 desugar.Quals.addConsistentQualifiers(Quals);
6421 return desugar;
6422}
6423
6424inline const Type *QualType::getTypePtr() const {
6425 return getCommonPtr()->BaseType;
6426}
6427
6428inline const Type *QualType::getTypePtrOrNull() const {
6429 return (isNull() ? nullptr : getCommonPtr()->BaseType);
6430}
6431
6432inline SplitQualType QualType::split() const {
6433 if (!hasLocalNonFastQualifiers())
6434 return SplitQualType(getTypePtrUnsafe(),
6435 Qualifiers::fromFastMask(getLocalFastQualifiers()));
6436
6437 const ExtQuals *eq = getExtQualsUnsafe();
6438 Qualifiers qs = eq->getQualifiers();
6439 qs.addFastQualifiers(getLocalFastQualifiers());
6440 return SplitQualType(eq->getBaseType(), qs);
6441}
6442
6443inline Qualifiers QualType::getLocalQualifiers() const {
6444 Qualifiers Quals;
6445 if (hasLocalNonFastQualifiers())
6446 Quals = getExtQualsUnsafe()->getQualifiers();
6447 Quals.addFastQualifiers(getLocalFastQualifiers());
6448 return Quals;
6449}
6450
6451inline Qualifiers QualType::getQualifiers() const {
6452 Qualifiers quals = getCommonPtr()->CanonicalType.getLocalQualifiers();
6453 quals.addFastQualifiers(getLocalFastQualifiers());
6454 return quals;
6455}
6456
6457inline unsigned QualType::getCVRQualifiers() const {
6458 unsigned cvr = getCommonPtr()->CanonicalType.getLocalCVRQualifiers();
6459 cvr |= getLocalCVRQualifiers();
6460 return cvr;
6461}
6462
6463inline QualType QualType::getCanonicalType() const {
6464 QualType canon = getCommonPtr()->CanonicalType;
6465 return canon.withFastQualifiers(getLocalFastQualifiers());
6466}
6467
6468inline bool QualType::isCanonical() const {
6469 return getTypePtr()->isCanonicalUnqualified();
6470}
6471
6472inline bool QualType::isCanonicalAsParam() const {
6473 if (!isCanonical()) return false;
6474 if (hasLocalQualifiers()) return false;
6475
6476 const Type *T = getTypePtr();
6477 if (T->isVariablyModifiedType() && T->hasSizedVLAType())
6478 return false;
6479
6480 return !isa<FunctionType>(T) && !isa<ArrayType>(T);
6481}
6482
6483inline bool QualType::isConstQualified() const {
6484 return isLocalConstQualified() ||
6485 getCommonPtr()->CanonicalType.isLocalConstQualified();
6486}
6487
6488inline bool QualType::isRestrictQualified() const {
6489 return isLocalRestrictQualified() ||
6490 getCommonPtr()->CanonicalType.isLocalRestrictQualified();
6491}
6492
6493
6494inline bool QualType::isVolatileQualified() const {
6495 return isLocalVolatileQualified() ||
6496 getCommonPtr()->CanonicalType.isLocalVolatileQualified();
6497}
6498
6499inline bool QualType::hasQualifiers() const {
6500 return hasLocalQualifiers() ||
6501 getCommonPtr()->CanonicalType.hasLocalQualifiers();
6502}
6503
6504inline QualType QualType::getUnqualifiedType() const {
6505 if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers())
6506 return QualType(getTypePtr(), 0);
6507
6508 return QualType(getSplitUnqualifiedTypeImpl(*this).Ty, 0);
6509}
6510
6511inline SplitQualType QualType::getSplitUnqualifiedType() const {
6512 if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers())
6513 return split();
6514
6515 return getSplitUnqualifiedTypeImpl(*this);
6516}
6517
6518inline void QualType::removeLocalConst() {
6519 removeLocalFastQualifiers(Qualifiers::Const);
6520}
6521
6522inline void QualType::removeLocalRestrict() {
6523 removeLocalFastQualifiers(Qualifiers::Restrict);
6524}
6525
6526inline void QualType::removeLocalVolatile() {
6527 removeLocalFastQualifiers(Qualifiers::Volatile);
6528}
6529
6530inline void QualType::removeLocalCVRQualifiers(unsigned Mask) {
6531 assert(!(Mask & ~Qualifiers::CVRMask) && "mask has non-CVR bits")(static_cast<void> (0));
6532 static_assert((int)Qualifiers::CVRMask == (int)Qualifiers::FastMask,
6533 "Fast bits differ from CVR bits!");
6534
6535 // Fast path: we don't need to touch the slow qualifiers.
6536 removeLocalFastQualifiers(Mask);
6537}
6538
6539/// Check if this type has any address space qualifier.
6540inline bool QualType::hasAddressSpace() const {
6541 return getQualifiers().hasAddressSpace();
6542}
6543
6544/// Return the address space of this type.
6545inline LangAS QualType::getAddressSpace() const {
6546 return getQualifiers().getAddressSpace();
6547}
6548
6549/// Return the gc attribute of this type.
6550inline Qualifiers::GC QualType::getObjCGCAttr() const {
6551 return getQualifiers().getObjCGCAttr();
6552}
6553
6554inline bool QualType::hasNonTrivialToPrimitiveDefaultInitializeCUnion() const {
6555 if (auto *RD = getTypePtr()->getBaseElementTypeUnsafe()->getAsRecordDecl())
6556 return hasNonTrivialToPrimitiveDefaultInitializeCUnion(RD);
6557 return false;
6558}
6559
6560inline bool QualType::hasNonTrivialToPrimitiveDestructCUnion() const {
6561 if (auto *RD = getTypePtr()->getBaseElementTypeUnsafe()->getAsRecordDecl())
6562 return hasNonTrivialToPrimitiveDestructCUnion(RD);
6563 return false;
6564}
6565
6566inline bool QualType::hasNonTrivialToPrimitiveCopyCUnion() const {
6567 if (auto *RD = getTypePtr()->getBaseElementTypeUnsafe()->getAsRecordDecl())
6568 return hasNonTrivialToPrimitiveCopyCUnion(RD);
6569 return false;
6570}
6571
6572inline FunctionType::ExtInfo getFunctionExtInfo(const Type &t) {
6573 if (const auto *PT = t.getAs<PointerType>()) {
6574 if (const auto *FT = PT->getPointeeType()->getAs<FunctionType>())
6575 return FT->getExtInfo();
6576 } else if (const auto *FT = t.getAs<FunctionType>())
6577 return FT->getExtInfo();
6578
6579 return FunctionType::ExtInfo();
6580}
6581
6582inline FunctionType::ExtInfo getFunctionExtInfo(QualType t) {
6583 return getFunctionExtInfo(*t);
6584}
6585
6586/// Determine whether this type is more
6587/// qualified than the Other type. For example, "const volatile int"
6588/// is more qualified than "const int", "volatile int", and
6589/// "int". However, it is not more qualified than "const volatile
6590/// int".
6591inline bool QualType::isMoreQualifiedThan(QualType other) const {
6592 Qualifiers MyQuals = getQualifiers();
6593 Qualifiers OtherQuals = other.getQualifiers();
6594 return (MyQuals != OtherQuals && MyQuals.compatiblyIncludes(OtherQuals));
6595}
6596
6597/// Determine whether this type is at last
6598/// as qualified as the Other type. For example, "const volatile
6599/// int" is at least as qualified as "const int", "volatile int",
6600/// "int", and "const volatile int".
6601inline bool QualType::isAtLeastAsQualifiedAs(QualType other) const {
6602 Qualifiers OtherQuals = other.getQualifiers();
6603
6604 // Ignore __unaligned qualifier if this type is a void.
6605 if (getUnqualifiedType()->isVoidType())
6606 OtherQuals.removeUnaligned();
6607
6608 return getQualifiers().compatiblyIncludes(OtherQuals);
6609}
6610
6611/// If Type is a reference type (e.g., const
6612/// int&), returns the type that the reference refers to ("const
6613/// int"). Otherwise, returns the type itself. This routine is used
6614/// throughout Sema to implement C++ 5p6:
6615///
6616/// If an expression initially has the type "reference to T" (8.3.2,
6617/// 8.5.3), the type is adjusted to "T" prior to any further
6618/// analysis, the expression designates the object or function
6619/// denoted by the reference, and the expression is an lvalue.
6620inline QualType QualType::getNonReferenceType() const {
6621 if (const auto *RefType = (*this)->getAs<ReferenceType>())
6622 return RefType->getPointeeType();
6623 else
6624 return *this;
6625}
6626
6627inline bool QualType::isCForbiddenLValueType() const {
6628 return ((getTypePtr()->isVoidType() && !hasQualifiers()) ||
6629 getTypePtr()->isFunctionType());
6630}
6631
6632/// Tests whether the type is categorized as a fundamental type.
6633///
6634/// \returns True for types specified in C++0x [basic.fundamental].
6635inline bool Type::isFundamentalType() const {
6636 return isVoidType() ||
6637 isNullPtrType() ||
6638 // FIXME: It's really annoying that we don't have an
6639 // 'isArithmeticType()' which agrees with the standard definition.
6640 (isArithmeticType() && !isEnumeralType());
6641}
6642
6643/// Tests whether the type is categorized as a compound type.
6644///
6645/// \returns True for types specified in C++0x [basic.compound].
6646inline bool Type::isCompoundType() const {
6647 // C++0x [basic.compound]p1:
6648 // Compound types can be constructed in the following ways:
6649 // -- arrays of objects of a given type [...];
6650 return isArrayType() ||
6651 // -- functions, which have parameters of given types [...];
6652 isFunctionType() ||
6653 // -- pointers to void or objects or functions [...];
6654 isPointerType() ||
6655 // -- references to objects or functions of a given type. [...]
6656 isReferenceType() ||
6657 // -- classes containing a sequence of objects of various types, [...];
6658 isRecordType() ||
6659 // -- unions, which are classes capable of containing objects of different
6660 // types at different times;
6661 isUnionType() ||
6662 // -- enumerations, which comprise a set of named constant values. [...];
6663 isEnumeralType() ||
6664 // -- pointers to non-static class members, [...].
6665 isMemberPointerType();
6666}
6667
6668inline bool Type::isFunctionType() const {
6669 return isa<FunctionType>(CanonicalType);
6670}
6671
6672inline bool Type::isPointerType() const {
6673 return isa<PointerType>(CanonicalType);
6674}
6675
6676inline bool Type::isAnyPointerType() const {
6677 return isPointerType() || isObjCObjectPointerType();
6678}
6679
6680inline bool Type::isBlockPointerType() const {
6681 return isa<BlockPointerType>(CanonicalType);
6682}
6683
6684inline bool Type::isReferenceType() const {
6685 return isa<ReferenceType>(CanonicalType);
6686}
6687
6688inline bool Type::isLValueReferenceType() const {
6689 return isa<LValueReferenceType>(CanonicalType);
6690}
6691
6692inline bool Type::isRValueReferenceType() const {
6693 return isa<RValueReferenceType>(CanonicalType);
6694}
6695
6696inline bool Type::isObjectPointerType() const {
6697 // Note: an "object pointer type" is not the same thing as a pointer to an
6698 // object type; rather, it is a pointer to an object type or a pointer to cv
6699 // void.
6700 if (const auto *T = getAs<PointerType>())
6701 return !T->getPointeeType()->isFunctionType();
6702 else
6703 return false;
6704}
6705
6706inline bool Type::isFunctionPointerType() const {
6707 if (const auto *T = getAs<PointerType>())
6708 return T->getPointeeType()->isFunctionType();
6709 else
6710 return false;
6711}
6712
6713inline bool Type::isFunctionReferenceType() const {
6714 if (const auto *T = getAs<ReferenceType>())
6715 return T->getPointeeType()->isFunctionType();
6716 else
6717 return false;
6718}
6719
6720inline bool Type::isMemberPointerType() const {
6721 return isa<MemberPointerType>(CanonicalType);
6722}
6723
6724inline bool Type::isMemberFunctionPointerType() const {
6725 if (const auto *T = getAs<MemberPointerType>())
6726 return T->isMemberFunctionPointer();
6727 else
6728 return false;
6729}
6730
6731inline bool Type::isMemberDataPointerType() const {
6732 if (const auto *T = getAs<MemberPointerType>())
6733 return T->isMemberDataPointer();
6734 else
6735 return false;
6736}
6737
6738inline bool Type::isArrayType() const {
6739 return isa<ArrayType>(CanonicalType);
6740}
6741
6742inline bool Type::isConstantArrayType() const {
6743 return isa<ConstantArrayType>(CanonicalType);
6744}
6745
6746inline bool Type::isIncompleteArrayType() const {
6747 return isa<IncompleteArrayType>(CanonicalType);
6748}
6749
6750inline bool Type::isVariableArrayType() const {
6751 return isa<VariableArrayType>(CanonicalType);
6752}
6753
6754inline bool Type::isDependentSizedArrayType() const {
6755 return isa<DependentSizedArrayType>(CanonicalType);
6756}
6757
6758inline bool Type::isBuiltinType() const {
6759 return isa<BuiltinType>(CanonicalType);
6760}
6761
6762inline bool Type::isRecordType() const {
6763 return isa<RecordType>(CanonicalType);
6764}
6765
6766inline bool Type::isEnumeralType() const {
6767 return isa<EnumType>(CanonicalType);
6768}
6769
6770inline bool Type::isAnyComplexType() const {
6771 return isa<ComplexType>(CanonicalType);
6772}
6773
6774inline bool Type::isVectorType() const {
6775 return isa<VectorType>(CanonicalType);
6776}
6777
6778inline bool Type::isExtVectorType() const {
6779 return isa<ExtVectorType>(CanonicalType);
6780}
6781
6782inline bool Type::isMatrixType() const {
6783 return isa<MatrixType>(CanonicalType);
6784}
6785
6786inline bool Type::isConstantMatrixType() const {
6787 return isa<ConstantMatrixType>(CanonicalType);
6788}
6789
6790inline bool Type::isDependentAddressSpaceType() const {
6791 return isa<DependentAddressSpaceType>(CanonicalType);
6792}
6793
6794inline bool Type::isObjCObjectPointerType() const {
6795 return isa<ObjCObjectPointerType>(CanonicalType);
6796}
6797
6798inline bool Type::isObjCObjectType() const {
6799 return isa<ObjCObjectType>(CanonicalType);
6800}
6801
6802inline bool Type::isObjCObjectOrInterfaceType() const {
6803 return isa<ObjCInterfaceType>(CanonicalType) ||
6804 isa<ObjCObjectType>(CanonicalType);
6805}
6806
6807inline bool Type::isAtomicType() const {
6808 return isa<AtomicType>(CanonicalType);
6809}
6810
6811inline bool Type::isUndeducedAutoType() const {
6812 return isa<AutoType>(CanonicalType);
6813}
6814
6815inline bool Type::isObjCQualifiedIdType() const {
6816 if (const auto *OPT = getAs<ObjCObjectPointerType>())
6817 return OPT->isObjCQualifiedIdType();
6818 return false;
6819}
6820
6821inline bool Type::isObjCQualifiedClassType() const {
6822 if (const auto *OPT = getAs<ObjCObjectPointerType>())
6823 return OPT->isObjCQualifiedClassType();
6824 return false;
6825}
6826
6827inline bool Type::isObjCIdType() const {
6828 if (const auto *OPT = getAs<ObjCObjectPointerType>())
6829 return OPT->isObjCIdType();
6830 return false;
6831}
6832
6833inline bool Type::isObjCClassType() const {
6834 if (const auto *OPT = getAs<ObjCObjectPointerType>())
6835 return OPT->isObjCClassType();
6836 return false;
6837}
6838
6839inline bool Type::isObjCSelType() const {
6840 if (const auto *OPT = getAs<PointerType>())
6841 return OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCSel);
6842 return false;
6843}
6844
6845inline bool Type::isObjCBuiltinType() const {
6846 return isObjCIdType() || isObjCClassType() || isObjCSelType();
6847}
6848
6849inline bool Type::isDecltypeType() const {
6850 return isa<DecltypeType>(this);
6851}
6852
6853#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
6854 inline bool Type::is##Id##Type() const { \
6855 return isSpecificBuiltinType(BuiltinType::Id); \
6856 }
6857#include "clang/Basic/OpenCLImageTypes.def"
6858
6859inline bool Type::isSamplerT() const {
6860 return isSpecificBuiltinType(BuiltinType::OCLSampler);
6861}
6862
6863inline bool Type::isEventT() const {
6864 return isSpecificBuiltinType(BuiltinType::OCLEvent);
6865}
6866
6867inline bool Type::isClkEventT() const {
6868 return isSpecificBuiltinType(BuiltinType::OCLClkEvent);
6869}
6870
6871inline bool Type::isQueueT() const {
6872 return isSpecificBuiltinType(BuiltinType::OCLQueue);
6873}
6874
6875inline bool Type::isReserveIDT() const {
6876 return isSpecificBuiltinType(BuiltinType::OCLReserveID);
6877}
6878
6879inline bool Type::isImageType() const {
6880#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) is##Id##Type() ||
6881 return
6882#include "clang/Basic/OpenCLImageTypes.def"
6883 false; // end boolean or operation
6884}
6885
6886inline bool Type::isPipeType() const {
6887 return isa<PipeType>(CanonicalType);
6888}
6889
6890inline bool Type::isExtIntType() const {
6891 return isa<ExtIntType>(CanonicalType);
6892}
6893
6894#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
6895 inline bool Type::is##Id##Type() const { \
6896 return isSpecificBuiltinType(BuiltinType::Id); \
6897 }
6898#include "clang/Basic/OpenCLExtensionTypes.def"
6899
6900inline bool Type::isOCLIntelSubgroupAVCType() const {
6901#define INTEL_SUBGROUP_AVC_TYPE(ExtType, Id) \
6902 isOCLIntelSubgroupAVC##Id##Type() ||
6903 return
6904#include "clang/Basic/OpenCLExtensionTypes.def"
6905 false; // end of boolean or operation
6906}
6907
6908inline bool Type::isOCLExtOpaqueType() const {
6909#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) is##Id##Type() ||
6910 return
6911#include "clang/Basic/OpenCLExtensionTypes.def"
6912 false; // end of boolean or operation
6913}
6914
6915inline bool Type::isOpenCLSpecificType() const {
6916 return isSamplerT() || isEventT() || isImageType() || isClkEventT() ||
6917 isQueueT() || isReserveIDT() || isPipeType() || isOCLExtOpaqueType();
6918}
6919
6920inline bool Type::isTemplateTypeParmType() const {
6921 return isa<TemplateTypeParmType>(CanonicalType);
6922}
6923
6924inline bool Type::isSpecificBuiltinType(unsigned K) const {
6925 if (const BuiltinType *BT = getAs<BuiltinType>()) {
6926 return BT->getKind() == static_cast<BuiltinType::Kind>(K);
6927 }
6928 return false;
6929}
6930
6931inline bool Type::isPlaceholderType() const {
6932 if (const auto *BT = dyn_cast<BuiltinType>(this))
6933 return BT->isPlaceholderType();
6934 return false;
6935}
6936
6937inline const BuiltinType *Type::getAsPlaceholderType() const {
6938 if (const auto *BT = dyn_cast<BuiltinType>(this))
6939 if (BT->isPlaceholderType())
6940 return BT;
6941 return nullptr;
6942}
6943
6944inline bool Type::isSpecificPlaceholderType(unsigned K) const {
6945 assert(BuiltinType::isPlaceholderTypeKind((BuiltinType::Kind) K))(static_cast<void> (0));
6946 return isSpecificBuiltinType(K);
6947}
6948
6949inline bool Type::isNonOverloadPlaceholderType() const {
6950 if (const auto *BT = dyn_cast<BuiltinType>(this))
6951 return BT->isNonOverloadPlaceholderType();
6952 return false;
6953}
6954
6955inline bool Type::isVoidType() const {
6956 return isSpecificBuiltinType(BuiltinType::Void);
6957}
6958
6959inline bool Type::isHalfType() const {
6960 // FIXME: Should we allow complex __fp16? Probably not.
6961 return isSpecificBuiltinType(BuiltinType::Half);
6962}
6963
6964inline bool Type::isFloat16Type() const {
6965 return isSpecificBuiltinType(BuiltinType::Float16);
6966}
6967
6968inline bool Type::isBFloat16Type() const {
6969 return isSpecificBuiltinType(BuiltinType::BFloat16);
6970}
6971
6972inline bool Type::isFloat128Type() const {
6973 return isSpecificBuiltinType(BuiltinType::Float128);
6974}
6975
6976inline bool Type::isNullPtrType() const {
6977 return isSpecificBuiltinType(BuiltinType::NullPtr);
6978}
6979
6980bool IsEnumDeclComplete(EnumDecl *);
6981bool IsEnumDeclScoped(EnumDecl *);
6982
6983inline bool Type::isIntegerType() const {
6984 if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
6985 return BT->getKind() >= BuiltinType::Bool &&
6986 BT->getKind() <= BuiltinType::Int128;
6987 if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) {
6988 // Incomplete enum types are not treated as integer types.
6989 // FIXME: In C++, enum types are never integer types.
6990 return IsEnumDeclComplete(ET->getDecl()) &&
6991 !IsEnumDeclScoped(ET->getDecl());
6992 }
6993 return isExtIntType();
6994}
6995
6996inline bool Type::isFixedPointType() const {
6997 if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) {
6998 return BT->getKind() >= BuiltinType::ShortAccum &&
6999 BT->getKind() <= BuiltinType::SatULongFract;
7000 }
7001 return false;
7002}
7003
7004inline bool Type::isFixedPointOrIntegerType() const {
7005 return isFixedPointType() || isIntegerType();
7006}
7007
7008inline bool Type::isSaturatedFixedPointType() const {
7009 if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) {
7010 return BT->getKind() >= BuiltinType::SatShortAccum &&
7011 BT->getKind() <= BuiltinType::SatULongFract;
7012 }
7013 return false;
7014}
7015
7016inline bool Type::isUnsaturatedFixedPointType() const {
7017 return isFixedPointType() && !isSaturatedFixedPointType();
7018}
7019
7020inline bool Type::isSignedFixedPointType() const {
7021 if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) {
7022 return ((BT->getKind() >= BuiltinType::ShortAccum &&
7023 BT->getKind() <= BuiltinType::LongAccum) ||
7024 (BT->getKind() >= BuiltinType::ShortFract &&
7025 BT->getKind() <= BuiltinType::LongFract) ||
7026 (BT->getKind() >= BuiltinType::SatShortAccum &&
7027 BT->getKind() <= BuiltinType::SatLongAccum) ||
7028 (BT->getKind() >= BuiltinType::SatShortFract &&
7029 BT->getKind() <= BuiltinType::SatLongFract));
7030 }
7031 return false;
7032}
7033
7034inline bool Type::isUnsignedFixedPointType() const {
7035 return isFixedPointType() && !isSignedFixedPointType();
7036}
7037
7038inline bool Type::isScalarType() const {
7039 if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
7040 return BT->getKind() > BuiltinType::Void &&
7041 BT->getKind() <= BuiltinType::NullPtr;
7042 if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
7043 // Enums are scalar types, but only if they are defined. Incomplete enums
7044 // are not treated as scalar types.
7045 return IsEnumDeclComplete(ET->getDecl());
7046 return isa<PointerType>(CanonicalType) ||
7047 isa<BlockPointerType>(CanonicalType) ||
7048 isa<MemberPointerType>(CanonicalType) ||
7049 isa<ComplexType>(CanonicalType) ||
7050 isa<ObjCObjectPointerType>(CanonicalType) ||
7051 isExtIntType();
7052}
7053
7054inline bool Type::isIntegralOrEnumerationType() const {
7055 if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
7056 return BT->getKind() >= BuiltinType::Bool &&
7057 BT->getKind() <= BuiltinType::Int128;
7058
7059 // Check for a complete enum type; incomplete enum types are not properly an
7060 // enumeration type in the sense required here.
7061 if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
7062 return IsEnumDeclComplete(ET->getDecl());
7063
7064 return isExtIntType();
7065}
7066
7067inline bool Type::isBooleanType() const {
7068 if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
7069 return BT->getKind() == BuiltinType::Bool;
7070 return false;
7071}
7072
7073inline bool Type::isUndeducedType() const {
7074 auto *DT = getContainedDeducedType();
7075 return DT && !DT->isDeduced();
7076}
7077
7078/// Determines whether this is a type for which one can define
7079/// an overloaded operator.
7080inline bool Type::isOverloadableType() const {
7081 return isDependentType() || isRecordType() || isEnumeralType();
7082}
7083
7084/// Determines whether this type is written as a typedef-name.
7085inline bool Type::isTypedefNameType() const {
7086 if (getAs<TypedefType>())
7087 return true;
7088 if (auto *TST = getAs<TemplateSpecializationType>())
7089 return TST->isTypeAlias();
7090 return false;
7091}
7092
7093/// Determines whether this type can decay to a pointer type.
7094inline bool Type::canDecayToPointerType() const {
7095 return isFunctionType() || isArrayType();
7096}
7097
7098inline bool Type::hasPointerRepresentation() const {
7099 return (isPointerType() || isReferenceType() || isBlockPointerType() ||
7100 isObjCObjectPointerType() || isNullPtrType());
7101}
7102
7103inline bool Type::hasObjCPointerRepresentation() const {
7104 return isObjCObjectPointerType();
7105}
7106
7107inline const Type *Type::getBaseElementTypeUnsafe() const {
7108 const Type *type = this;
7109 while (const ArrayType *arrayType = type->getAsArrayTypeUnsafe())
7110 type = arrayType->getElementType().getTypePtr();
7111 return type;
7112}
7113
7114inline const Type *Type::getPointeeOrArrayElementType() const {
7115 const Type *type = this;
7116 if (type->isAnyPointerType())
7117 return type->getPointeeType().getTypePtr();
7118 else if (type->isArrayType())
7119 return type->getBaseElementTypeUnsafe();
7120 return type;
7121}
7122/// Insertion operator for partial diagnostics. This allows sending adress
7123/// spaces into a diagnostic with <<.
7124inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
7125 LangAS AS) {
7126 PD.AddTaggedVal(static_cast<std::underlying_type_t<LangAS>>(AS),
7127 DiagnosticsEngine::ArgumentKind::ak_addrspace);
7128 return PD;
7129}
7130
7131/// Insertion operator for partial diagnostics. This allows sending Qualifiers
7132/// into a diagnostic with <<.
7133inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
7134 Qualifiers Q) {
7135 PD.AddTaggedVal(Q.getAsOpaqueValue(),
7136 DiagnosticsEngine::ArgumentKind::ak_qual);
7137 return PD;
7138}
7139
7140/// Insertion operator for partial diagnostics. This allows sending QualType's
7141/// into a diagnostic with <<.
7142inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &PD,
7143 QualType T) {
7144 PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
7145 DiagnosticsEngine::ak_qualtype);
7146 return PD;
7147}
7148
7149// Helper class template that is used by Type::getAs to ensure that one does
7150// not try to look through a qualified type to get to an array type.
7151template <typename T>
7152using TypeIsArrayType =
7153 std::integral_constant<bool, std::is_same<T, ArrayType>::value ||
7154 std::is_base_of<ArrayType, T>::value>;
7155
7156// Member-template getAs<specific type>'.
7157template <typename T> const T *Type::getAs() const {
7158 static_assert(!TypeIsArrayType<T>::value,
7159 "ArrayType cannot be used with getAs!");
7160
7161 // If this is directly a T type, return it.
7162 if (const auto *Ty = dyn_cast<T>(this))
7163 return Ty;
7164
7165 // If the canonical form of this type isn't the right kind, reject it.
7166 if (!isa<T>(CanonicalType))
7167 return nullptr;
7168
7169 // If this is a typedef for the type, strip the typedef off without
7170 // losing all typedef information.
7171 return cast<T>(getUnqualifiedDesugaredType());
7172}
7173
7174template <typename T> const T *Type::getAsAdjusted() const {
7175 static_assert(!TypeIsArrayType<T>::value, "ArrayType cannot be used with getAsAdjusted!");
7176
7177 // If this is directly a T type, return it.
7178 if (const auto *Ty = dyn_cast<T>(this))
7179 return Ty;
7180
7181 // If the canonical form of this type isn't the right kind, reject it.
7182 if (!isa<T>(CanonicalType))
7183 return nullptr;
7184
7185 // Strip off type adjustments that do not modify the underlying nature of the
7186 // type.
7187 const Type *Ty = this;
7188 while (Ty) {
7189 if (const auto *A = dyn_cast<AttributedType>(Ty))
7190 Ty = A->getModifiedType().getTypePtr();
7191 else if (const auto *E = dyn_cast<ElaboratedType>(Ty))
7192 Ty = E->desugar().getTypePtr();
7193 else if (const auto *P = dyn_cast<ParenType>(Ty))
7194 Ty = P->desugar().getTypePtr();
7195 else if (const auto *A = dyn_cast<AdjustedType>(Ty))
7196 Ty = A->desugar().getTypePtr();
7197 else if (const auto *M = dyn_cast<MacroQualifiedType>(Ty))
7198 Ty = M->desugar().getTypePtr();
7199 else
7200 break;
7201 }
7202
7203 // Just because the canonical type is correct does not mean we can use cast<>,
7204 // since we may not have stripped off all the sugar down to the base type.
7205 return dyn_cast<T>(Ty);
7206}
7207
7208inline const ArrayType *Type::getAsArrayTypeUnsafe() const {
7209 // If this is directly an array type, return it.
7210 if (const auto *arr = dyn_cast<ArrayType>(this))
7211 return arr;
7212
7213 // If the canonical form of this type isn't the right kind, reject it.
7214 if (!isa<ArrayType>(CanonicalType))
7215 return nullptr;
7216
7217 // If this is a typedef for the type, strip the typedef off without
7218 // losing all typedef information.
7219 return cast<ArrayType>(getUnqualifiedDesugaredType());
7220}
7221
7222template <typename T> const T *Type::castAs() const {
7223 static_assert(!TypeIsArrayType<T>::value,
7224 "ArrayType cannot be used with castAs!");
7225
7226 if (const auto *ty = dyn_cast<T>(this)) return ty;
7227 assert(isa<T>(CanonicalType))(static_cast<void> (0));
7228 return cast<T>(getUnqualifiedDesugaredType());
7229}
7230
7231inline const ArrayType *Type::castAsArrayTypeUnsafe() const {
7232 assert(isa<ArrayType>(CanonicalType))(static_cast<void> (0));
7233 if (const auto *arr = dyn_cast<ArrayType>(this)) return arr;
7234 return cast<ArrayType>(getUnqualifiedDesugaredType());
7235}
7236
7237DecayedType::DecayedType(QualType OriginalType, QualType DecayedPtr,
7238 QualType CanonicalPtr)
7239 : AdjustedType(Decayed, OriginalType, DecayedPtr, CanonicalPtr) {
7240#ifndef NDEBUG1
7241 QualType Adjusted = getAdjustedType();
7242 (void)AttributedType::stripOuterNullability(Adjusted);
7243 assert(isa<PointerType>(Adjusted))(static_cast<void> (0));
7244#endif
7245}
7246
7247QualType DecayedType::getPointeeType() const {
7248 QualType Decayed = getDecayedType();
7249 (void)AttributedType::stripOuterNullability(Decayed);
7250 return cast<PointerType>(Decayed)->getPointeeType();
7251}
7252
7253// Get the decimal string representation of a fixed point type, represented
7254// as a scaled integer.
7255// TODO: At some point, we should change the arguments to instead just accept an
7256// APFixedPoint instead of APSInt and scale.
7257void FixedPointValueToString(SmallVectorImpl<char> &Str, llvm::APSInt Val,
7258 unsigned Scale);
7259
7260} // namespace clang
7261
7262#endif // LLVM_CLANG_AST_TYPE_H

/build/llvm-toolchain-snapshot-14~++20210903100615+fd66b44ec19e/llvm/include/llvm/ADT/PointerUnion.h

1//===- llvm/ADT/PointerUnion.h - Discriminated Union of 2 Ptrs --*- C++ -*-===//
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 file defines the PointerUnion class, which is a discriminated union of
10// pointer types.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ADT_POINTERUNION_H
15#define LLVM_ADT_POINTERUNION_H
16
17#include "llvm/ADT/DenseMapInfo.h"
18#include "llvm/ADT/PointerIntPair.h"
19#include "llvm/Support/PointerLikeTypeTraits.h"
20#include <cassert>
21#include <cstddef>
22#include <cstdint>
23
24namespace llvm {
25
26namespace pointer_union_detail {
27 /// Determine the number of bits required to store integers with values < n.
28 /// This is ceil(log2(n)).
29 constexpr int bitsRequired(unsigned n) {
30 return n > 1 ? 1 + bitsRequired((n + 1) / 2) : 0;
31 }
32
33 template <typename... Ts> constexpr int lowBitsAvailable() {
34 return std::min<int>({PointerLikeTypeTraits<Ts>::NumLowBitsAvailable...});
35 }
36
37 /// Find the index of a type in a list of types. TypeIndex<T, Us...>::Index
38 /// is the index of T in Us, or sizeof...(Us) if T does not appear in the
39 /// list.
40 template <typename T, typename ...Us> struct TypeIndex;
41 template <typename T, typename ...Us> struct TypeIndex<T, T, Us...> {
42 static constexpr int Index = 0;
43 };
44 template <typename T, typename U, typename... Us>
45 struct TypeIndex<T, U, Us...> {
46 static constexpr int Index = 1 + TypeIndex<T, Us...>::Index;
47 };
48 template <typename T> struct TypeIndex<T> {
49 static constexpr int Index = 0;
50 };
51
52 /// Find the first type in a list of types.
53 template <typename T, typename...> struct GetFirstType {
54 using type = T;
55 };
56
57 /// Provide PointerLikeTypeTraits for void* that is used by PointerUnion
58 /// for the template arguments.
59 template <typename ...PTs> class PointerUnionUIntTraits {
60 public:
61 static inline void *getAsVoidPointer(void *P) { return P; }
62 static inline void *getFromVoidPointer(void *P) { return P; }
63 static constexpr int NumLowBitsAvailable = lowBitsAvailable<PTs...>();
64 };
65
66 template <typename Derived, typename ValTy, int I, typename ...Types>
67 class PointerUnionMembers;
68
69 template <typename Derived, typename ValTy, int I>
70 class PointerUnionMembers<Derived, ValTy, I> {
71 protected:
72 ValTy Val;
73 PointerUnionMembers() = default;
74 PointerUnionMembers(ValTy Val) : Val(Val) {}
75
76 friend struct PointerLikeTypeTraits<Derived>;
77 };
78
79 template <typename Derived, typename ValTy, int I, typename Type,
80 typename ...Types>
81 class PointerUnionMembers<Derived, ValTy, I, Type, Types...>
82 : public PointerUnionMembers<Derived, ValTy, I + 1, Types...> {
83 using Base = PointerUnionMembers<Derived, ValTy, I + 1, Types...>;
84 public:
85 using Base::Base;
86 PointerUnionMembers() = default;
87 PointerUnionMembers(Type V)
88 : Base(ValTy(const_cast<void *>(
89 PointerLikeTypeTraits<Type>::getAsVoidPointer(V)),
90 I)) {}
91
92 using Base::operator=;
93 Derived &operator=(Type V) {
94 this->Val = ValTy(
95 const_cast<void *>(PointerLikeTypeTraits<Type>::getAsVoidPointer(V)),
96 I);
97 return static_cast<Derived &>(*this);
98 };
99 };
100}
101
102/// A discriminated union of two or more pointer types, with the discriminator
103/// in the low bit of the pointer.
104///
105/// This implementation is extremely efficient in space due to leveraging the
106/// low bits of the pointer, while exposing a natural and type-safe API.
107///
108/// Common use patterns would be something like this:
109/// PointerUnion<int*, float*> P;
110/// P = (int*)0;
111/// printf("%d %d", P.is<int*>(), P.is<float*>()); // prints "1 0"
112/// X = P.get<int*>(); // ok.
113/// Y = P.get<float*>(); // runtime assertion failure.
114/// Z = P.get<double*>(); // compile time failure.
115/// P = (float*)0;
116/// Y = P.get<float*>(); // ok.
117/// X = P.get<int*>(); // runtime assertion failure.
118template <typename... PTs>
119class PointerUnion
120 : public pointer_union_detail::PointerUnionMembers<
121 PointerUnion<PTs...>,
122 PointerIntPair<
123 void *, pointer_union_detail::bitsRequired(sizeof...(PTs)), int,
124 pointer_union_detail::PointerUnionUIntTraits<PTs...>>,
125 0, PTs...> {
126 // The first type is special because we want to directly cast a pointer to a
127 // default-initialized union to a pointer to the first type. But we don't
128 // want PointerUnion to be a 'template <typename First, typename ...Rest>'
129 // because it's much more convenient to have a name for the whole pack. So
130 // split off the first type here.
131 using First = typename pointer_union_detail::GetFirstType<PTs...>::type;
132 using Base = typename PointerUnion::PointerUnionMembers;
133
134public:
135 PointerUnion() = default;
136
137 PointerUnion(std::nullptr_t) : PointerUnion() {}
138 using Base::Base;
139
140 /// Test if the pointer held in the union is null, regardless of
141 /// which type it is.
142 bool isNull() const { return !this->Val.getPointer(); }
23
Assuming the condition is true
24
Returning the value 1, which participates in a condition later
143
144 explicit operator bool() const { return !isNull(); }
145
146 /// Test if the Union currently holds the type matching T.
147 template <typename T> bool is() const {
148 constexpr int Index = pointer_union_detail::TypeIndex<T, PTs...>::Index;
149 static_assert(Index < sizeof...(PTs),
150 "PointerUnion::is<T> given type not in the union");
151 return this->Val.getInt() == Index;
152 }
153
154 /// Returns the value of the specified pointer type.
155 ///
156 /// If the specified pointer type is incorrect, assert.
157 template <typename T> T get() const {
158 assert(is<T>() && "Invalid accessor called")(static_cast<void> (0));
159 return PointerLikeTypeTraits<T>::getFromVoidPointer(this->Val.getPointer());
160 }
161
162 /// Returns the current pointer if it is of the specified pointer type,
163 /// otherwise returns null.
164 template <typename T> T dyn_cast() const {
165 if (is<T>())
166 return get<T>();
167 return T();
168 }
169
170 /// If the union is set to the first pointer type get an address pointing to
171 /// it.
172 First const *getAddrOfPtr1() const {
173 return const_cast<PointerUnion *>(this)->getAddrOfPtr1();
174 }
175
176 /// If the union is set to the first pointer type get an address pointing to
177 /// it.
178 First *getAddrOfPtr1() {
179 assert(is<First>() && "Val is not the first pointer")(static_cast<void> (0));
180 assert((static_cast<void> (0))
181 PointerLikeTypeTraits<First>::getAsVoidPointer(get<First>()) ==(static_cast<void> (0))
182 this->Val.getPointer() &&(static_cast<void> (0))
183 "Can't get the address because PointerLikeTypeTraits changes the ptr")(static_cast<void> (0));
184 return const_cast<First *>(
185 reinterpret_cast<const First *>(this->Val.getAddrOfPointer()));
186 }
187
188 /// Assignment from nullptr which just clears the union.
189 const PointerUnion &operator=(std::nullptr_t) {
190 this->Val.initWithPointer(nullptr);
191 return *this;
192 }
193
194 /// Assignment from elements of the union.
195 using Base::operator=;
196
197 void *getOpaqueValue() const { return this->Val.getOpaqueValue(); }
198 static inline PointerUnion getFromOpaqueValue(void *VP) {
199 PointerUnion V;
200 V.Val = decltype(V.Val)::getFromOpaqueValue(VP);
201 return V;
202 }
203};
204
205template <typename ...PTs>
206bool operator==(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) {
207 return lhs.getOpaqueValue() == rhs.getOpaqueValue();
208}
209
210template <typename ...PTs>
211bool operator!=(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) {
212 return lhs.getOpaqueValue() != rhs.getOpaqueValue();
213}
214
215template <typename ...PTs>
216bool operator<(PointerUnion<PTs...> lhs, PointerUnion<PTs...> rhs) {
217 return lhs.getOpaqueValue() < rhs.getOpaqueValue();
218}
219
220// Teach SmallPtrSet that PointerUnion is "basically a pointer", that has
221// # low bits available = min(PT1bits,PT2bits)-1.
222template <typename ...PTs>
223struct PointerLikeTypeTraits<PointerUnion<PTs...>> {
224 static inline void *getAsVoidPointer(const PointerUnion<PTs...> &P) {
225 return P.getOpaqueValue();
226 }
227
228 static inline PointerUnion<PTs...> getFromVoidPointer(void *P) {
229 return PointerUnion<PTs...>::getFromOpaqueValue(P);
230 }
231
232 // The number of bits available are the min of the pointer types minus the
233 // bits needed for the discriminator.
234 static constexpr int NumLowBitsAvailable = PointerLikeTypeTraits<decltype(
235 PointerUnion<PTs...>::Val)>::NumLowBitsAvailable;
236};
237
238// Teach DenseMap how to use PointerUnions as keys.
239template <typename ...PTs> struct DenseMapInfo<PointerUnion<PTs...>> {
240 using Union = PointerUnion<PTs...>;
241 using FirstInfo =
242 DenseMapInfo<typename pointer_union_detail::GetFirstType<PTs...>::type>;
243
244 static inline Union getEmptyKey() { return Union(FirstInfo::getEmptyKey()); }
245
246 static inline Union getTombstoneKey() {
247 return Union(FirstInfo::getTombstoneKey());
248 }
249
250 static unsigned getHashValue(const Union &UnionVal) {
251 intptr_t key = (intptr_t)UnionVal.getOpaqueValue();
252 return DenseMapInfo<intptr_t>::getHashValue(key);
253 }
254
255 static bool isEqual(const Union &LHS, const Union &RHS) {
256 return LHS == RHS;
257 }
258};
259
260} // end namespace llvm
261
262#endif // LLVM_ADT_POINTERUNION_H