blob: 77a62b1aa1e87439e5afb104712c59f2326ade83 [file] [log] [blame]
Alexey Bataev9959db52014-05-06 10:08:46 +00001//===----- CGOpenMPRuntime.cpp - Interface to OpenMP Runtimes -------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Alexey Bataev9959db52014-05-06 10:08:46 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This provides a class for OpenMP runtime code generation.
10//
11//===----------------------------------------------------------------------===//
12
Reid Kleckner98031782019-12-09 16:11:56 -080013#include "CGOpenMPRuntime.h"
Samuel Antaoee8fb302016-01-06 13:42:12 +000014#include "CGCXXABI.h"
15#include "CGCleanup.h"
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000016#include "CGRecordLayout.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000017#include "CodeGenFunction.h"
Reid Kleckner98031782019-12-09 16:11:56 -080018#include "clang/AST/Attr.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000019#include "clang/AST/Decl.h"
Alexey Bataev0860db92019-12-19 10:01:10 -050020#include "clang/AST/OpenMPClause.h"
Chandler Carruth0d9593d2015-01-14 11:29:14 +000021#include "clang/AST/StmtOpenMP.h"
Alexey Bataeva58da1a2019-12-27 09:44:43 -050022#include "clang/AST/StmtVisitor.h"
Richard Smithbf5bcf22018-06-26 23:20:26 +000023#include "clang/Basic/BitmaskEnum.h"
Alexey Bataev2d4f80f2020-02-11 15:15:21 -050024#include "clang/Basic/OpenMPKinds.h"
Reid Kleckner86565c12020-02-27 11:01:58 -080025#include "clang/Basic/SourceManager.h"
Reid Kleckner98031782019-12-09 16:11:56 -080026#include "clang/CodeGen/ConstantInitBuilder.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000027#include "llvm/ADT/ArrayRef.h"
Alexey Bataev4e8231b2019-11-05 15:13:30 -050028#include "llvm/ADT/SetOperations.h"
Alexey Bataev8b321922020-01-16 15:46:34 -050029#include "llvm/ADT/StringExtras.h"
Teresa Johnsonffc4e242016-11-11 05:35:12 +000030#include "llvm/Bitcode/BitcodeReader.h"
Johannes Doerfertb3c06db2019-11-04 23:00:36 -060031#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000032#include "llvm/IR/DerivedTypes.h"
33#include "llvm/IR/GlobalValue.h"
34#include "llvm/IR/Value.h"
Alexey Bataev2d4f80f2020-02-11 15:15:21 -050035#include "llvm/Support/AtomicOrdering.h"
Samuel Antaoee8fb302016-01-06 13:42:12 +000036#include "llvm/Support/Format.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000037#include "llvm/Support/raw_ostream.h"
Alexey Bataev23b69422014-06-18 07:08:49 +000038#include <cassert>
Alexey Bataev9959db52014-05-06 10:08:46 +000039
40using namespace clang;
41using namespace CodeGen;
Johannes Doerferteb3e81f2019-11-04 22:00:49 -060042using namespace llvm::omp;
Alexey Bataev9959db52014-05-06 10:08:46 +000043
Benjamin Kramerc52193f2014-10-10 13:57:57 +000044namespace {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000045/// Base class for handling code generation inside OpenMP regions.
Alexey Bataev18095712014-10-10 12:19:54 +000046class CGOpenMPRegionInfo : public CodeGenFunction::CGCapturedStmtInfo {
47public:
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000048 /// Kinds of OpenMP regions used in codegen.
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000049 enum CGOpenMPRegionKind {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000050 /// Region with outlined function for standalone 'parallel'
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000051 /// directive.
52 ParallelOutlinedRegion,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000053 /// Region with outlined function for standalone 'task' directive.
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000054 TaskOutlinedRegion,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000055 /// Region for constructs that do not require function outlining,
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000056 /// like 'for', 'sections', 'atomic' etc. directives.
57 InlinedRegion,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000058 /// Region with outlined function for standalone 'target' directive.
Samuel Antaobed3c462015-10-02 16:14:20 +000059 TargetRegion,
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000060 };
Alexey Bataev18095712014-10-10 12:19:54 +000061
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000062 CGOpenMPRegionInfo(const CapturedStmt &CS,
63 const CGOpenMPRegionKind RegionKind,
Alexey Bataev25e5b442015-09-15 12:52:43 +000064 const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind,
65 bool HasCancel)
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000066 : CGCapturedStmtInfo(CS, CR_OpenMP), RegionKind(RegionKind),
Alexey Bataev25e5b442015-09-15 12:52:43 +000067 CodeGen(CodeGen), Kind(Kind), HasCancel(HasCancel) {}
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000068
69 CGOpenMPRegionInfo(const CGOpenMPRegionKind RegionKind,
Alexey Bataev25e5b442015-09-15 12:52:43 +000070 const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind,
71 bool HasCancel)
Alexey Bataev81c7ea02015-07-03 09:56:58 +000072 : CGCapturedStmtInfo(CR_OpenMP), RegionKind(RegionKind), CodeGen(CodeGen),
Alexey Bataev25e5b442015-09-15 12:52:43 +000073 Kind(Kind), HasCancel(HasCancel) {}
Alexey Bataev8cbe0a62015-02-26 10:27:34 +000074
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000075 /// Get a variable or parameter for storing global thread id
Alexey Bataev18095712014-10-10 12:19:54 +000076 /// inside OpenMP construct.
Alexey Bataev8cbe0a62015-02-26 10:27:34 +000077 virtual const VarDecl *getThreadIDVariable() const = 0;
Alexey Bataev18095712014-10-10 12:19:54 +000078
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000079 /// Emit the captured statement body.
Hans Wennborg7eb54642015-09-10 17:07:54 +000080 void EmitBody(CodeGenFunction &CGF, const Stmt *S) override;
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000081
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000082 /// Get an LValue for the current ThreadID variable.
Alexey Bataev62b63b12015-03-10 07:28:44 +000083 /// \return LValue for thread id variable. This LValue always has type int32*.
84 virtual LValue getThreadIDVariableLValue(CodeGenFunction &CGF);
Alexey Bataev18095712014-10-10 12:19:54 +000085
Alexey Bataev48591dd2016-04-20 04:01:36 +000086 virtual void emitUntiedSwitch(CodeGenFunction & /*CGF*/) {}
87
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000088 CGOpenMPRegionKind getRegionKind() const { return RegionKind; }
Alexey Bataev8cbe0a62015-02-26 10:27:34 +000089
Alexey Bataev81c7ea02015-07-03 09:56:58 +000090 OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
91
Alexey Bataev25e5b442015-09-15 12:52:43 +000092 bool hasCancel() const { return HasCancel; }
93
Alexey Bataev18095712014-10-10 12:19:54 +000094 static bool classof(const CGCapturedStmtInfo *Info) {
95 return Info->getKind() == CR_OpenMP;
96 }
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000097
Alexey Bataev48591dd2016-04-20 04:01:36 +000098 ~CGOpenMPRegionInfo() override = default;
99
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000100protected:
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000101 CGOpenMPRegionKind RegionKind;
Hans Wennborg45c74392016-01-12 20:54:36 +0000102 RegionCodeGenTy CodeGen;
Alexey Bataev81c7ea02015-07-03 09:56:58 +0000103 OpenMPDirectiveKind Kind;
Alexey Bataev25e5b442015-09-15 12:52:43 +0000104 bool HasCancel;
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000105};
Alexey Bataev18095712014-10-10 12:19:54 +0000106
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000107/// API for captured statement code generation in OpenMP constructs.
Alexey Bataev48591dd2016-04-20 04:01:36 +0000108class CGOpenMPOutlinedRegionInfo final : public CGOpenMPRegionInfo {
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000109public:
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000110 CGOpenMPOutlinedRegionInfo(const CapturedStmt &CS, const VarDecl *ThreadIDVar,
Alexey Bataev81c7ea02015-07-03 09:56:58 +0000111 const RegionCodeGenTy &CodeGen,
Arpith Chacko Jacobbb36fe82017-01-10 15:42:51 +0000112 OpenMPDirectiveKind Kind, bool HasCancel,
113 StringRef HelperName)
Alexey Bataev25e5b442015-09-15 12:52:43 +0000114 : CGOpenMPRegionInfo(CS, ParallelOutlinedRegion, CodeGen, Kind,
115 HasCancel),
Arpith Chacko Jacobbb36fe82017-01-10 15:42:51 +0000116 ThreadIDVar(ThreadIDVar), HelperName(HelperName) {
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000117 assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region.");
118 }
Eugene Zelenko0a4f3f42016-02-10 19:11:58 +0000119
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000120 /// Get a variable or parameter for storing global thread id
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000121 /// inside OpenMP construct.
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000122 const VarDecl *getThreadIDVariable() const override { return ThreadIDVar; }
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000123
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000124 /// Get the name of the capture helper.
Arpith Chacko Jacobbb36fe82017-01-10 15:42:51 +0000125 StringRef getHelperName() const override { return HelperName; }
Alexey Bataev18095712014-10-10 12:19:54 +0000126
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000127 static bool classof(const CGCapturedStmtInfo *Info) {
128 return CGOpenMPRegionInfo::classof(Info) &&
129 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() ==
130 ParallelOutlinedRegion;
131 }
132
Alexey Bataev18095712014-10-10 12:19:54 +0000133private:
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000134 /// A variable or parameter storing global thread id for OpenMP
Alexey Bataev18095712014-10-10 12:19:54 +0000135 /// constructs.
136 const VarDecl *ThreadIDVar;
Arpith Chacko Jacobbb36fe82017-01-10 15:42:51 +0000137 StringRef HelperName;
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000138};
139
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000140/// API for captured statement code generation in OpenMP constructs.
Alexey Bataev48591dd2016-04-20 04:01:36 +0000141class CGOpenMPTaskOutlinedRegionInfo final : public CGOpenMPRegionInfo {
Alexey Bataev62b63b12015-03-10 07:28:44 +0000142public:
Alexey Bataev48591dd2016-04-20 04:01:36 +0000143 class UntiedTaskActionTy final : public PrePostActionTy {
144 bool Untied;
145 const VarDecl *PartIDVar;
146 const RegionCodeGenTy UntiedCodeGen;
147 llvm::SwitchInst *UntiedSwitch = nullptr;
148
149 public:
150 UntiedTaskActionTy(bool Tied, const VarDecl *PartIDVar,
151 const RegionCodeGenTy &UntiedCodeGen)
152 : Untied(!Tied), PartIDVar(PartIDVar), UntiedCodeGen(UntiedCodeGen) {}
153 void Enter(CodeGenFunction &CGF) override {
154 if (Untied) {
155 // Emit task switching point.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000156 LValue PartIdLVal = CGF.EmitLoadOfPointerLValue(
Alexey Bataev48591dd2016-04-20 04:01:36 +0000157 CGF.GetAddrOfLocalVar(PartIDVar),
158 PartIDVar->getType()->castAs<PointerType>());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000159 llvm::Value *Res =
160 CGF.EmitLoadOfScalar(PartIdLVal, PartIDVar->getLocation());
161 llvm::BasicBlock *DoneBB = CGF.createBasicBlock(".untied.done.");
Alexey Bataev48591dd2016-04-20 04:01:36 +0000162 UntiedSwitch = CGF.Builder.CreateSwitch(Res, DoneBB);
163 CGF.EmitBlock(DoneBB);
164 CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);
165 CGF.EmitBlock(CGF.createBasicBlock(".untied.jmp."));
166 UntiedSwitch->addCase(CGF.Builder.getInt32(0),
167 CGF.Builder.GetInsertBlock());
168 emitUntiedSwitch(CGF);
169 }
170 }
171 void emitUntiedSwitch(CodeGenFunction &CGF) const {
172 if (Untied) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000173 LValue PartIdLVal = CGF.EmitLoadOfPointerLValue(
Alexey Bataev48591dd2016-04-20 04:01:36 +0000174 CGF.GetAddrOfLocalVar(PartIDVar),
175 PartIDVar->getType()->castAs<PointerType>());
176 CGF.EmitStoreOfScalar(CGF.Builder.getInt32(UntiedSwitch->getNumCases()),
177 PartIdLVal);
178 UntiedCodeGen(CGF);
179 CodeGenFunction::JumpDest CurPoint =
180 CGF.getJumpDestInCurrentScope(".untied.next.");
181 CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);
182 CGF.EmitBlock(CGF.createBasicBlock(".untied.jmp."));
183 UntiedSwitch->addCase(CGF.Builder.getInt32(UntiedSwitch->getNumCases()),
184 CGF.Builder.GetInsertBlock());
185 CGF.EmitBranchThroughCleanup(CurPoint);
186 CGF.EmitBlock(CurPoint.getBlock());
187 }
188 }
189 unsigned getNumberOfParts() const { return UntiedSwitch->getNumCases(); }
190 };
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000191 CGOpenMPTaskOutlinedRegionInfo(const CapturedStmt &CS,
Alexey Bataev62b63b12015-03-10 07:28:44 +0000192 const VarDecl *ThreadIDVar,
Alexey Bataev81c7ea02015-07-03 09:56:58 +0000193 const RegionCodeGenTy &CodeGen,
Alexey Bataev48591dd2016-04-20 04:01:36 +0000194 OpenMPDirectiveKind Kind, bool HasCancel,
195 const UntiedTaskActionTy &Action)
Alexey Bataev25e5b442015-09-15 12:52:43 +0000196 : CGOpenMPRegionInfo(CS, TaskOutlinedRegion, CodeGen, Kind, HasCancel),
Alexey Bataev48591dd2016-04-20 04:01:36 +0000197 ThreadIDVar(ThreadIDVar), Action(Action) {
Alexey Bataev62b63b12015-03-10 07:28:44 +0000198 assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region.");
199 }
Eugene Zelenko0a4f3f42016-02-10 19:11:58 +0000200
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000201 /// Get a variable or parameter for storing global thread id
Alexey Bataev62b63b12015-03-10 07:28:44 +0000202 /// inside OpenMP construct.
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000203 const VarDecl *getThreadIDVariable() const override { return ThreadIDVar; }
Alexey Bataev62b63b12015-03-10 07:28:44 +0000204
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000205 /// Get an LValue for the current ThreadID variable.
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000206 LValue getThreadIDVariableLValue(CodeGenFunction &CGF) override;
Alexey Bataev62b63b12015-03-10 07:28:44 +0000207
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000208 /// Get the name of the capture helper.
Alexey Bataev62b63b12015-03-10 07:28:44 +0000209 StringRef getHelperName() const override { return ".omp_outlined."; }
210
Alexey Bataev48591dd2016-04-20 04:01:36 +0000211 void emitUntiedSwitch(CodeGenFunction &CGF) override {
212 Action.emitUntiedSwitch(CGF);
213 }
214
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000215 static bool classof(const CGCapturedStmtInfo *Info) {
216 return CGOpenMPRegionInfo::classof(Info) &&
217 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() ==
218 TaskOutlinedRegion;
219 }
220
Alexey Bataev62b63b12015-03-10 07:28:44 +0000221private:
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000222 /// A variable or parameter storing global thread id for OpenMP
Alexey Bataev62b63b12015-03-10 07:28:44 +0000223 /// constructs.
224 const VarDecl *ThreadIDVar;
Alexey Bataev48591dd2016-04-20 04:01:36 +0000225 /// Action for emitting code for untied tasks.
226 const UntiedTaskActionTy &Action;
Alexey Bataev62b63b12015-03-10 07:28:44 +0000227};
228
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000229/// API for inlined captured statement code generation in OpenMP
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000230/// constructs.
231class CGOpenMPInlinedRegionInfo : public CGOpenMPRegionInfo {
232public:
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000233 CGOpenMPInlinedRegionInfo(CodeGenFunction::CGCapturedStmtInfo *OldCSI,
Alexey Bataev81c7ea02015-07-03 09:56:58 +0000234 const RegionCodeGenTy &CodeGen,
Alexey Bataev25e5b442015-09-15 12:52:43 +0000235 OpenMPDirectiveKind Kind, bool HasCancel)
236 : CGOpenMPRegionInfo(InlinedRegion, CodeGen, Kind, HasCancel),
237 OldCSI(OldCSI),
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000238 OuterRegionInfo(dyn_cast_or_null<CGOpenMPRegionInfo>(OldCSI)) {}
Eugene Zelenko0a4f3f42016-02-10 19:11:58 +0000239
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000240 // Retrieve the value of the context parameter.
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000241 llvm::Value *getContextValue() const override {
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000242 if (OuterRegionInfo)
243 return OuterRegionInfo->getContextValue();
244 llvm_unreachable("No context value for inlined OpenMP region");
245 }
Eugene Zelenko0a4f3f42016-02-10 19:11:58 +0000246
Hans Wennborg7eb54642015-09-10 17:07:54 +0000247 void setContextValue(llvm::Value *V) override {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000248 if (OuterRegionInfo) {
249 OuterRegionInfo->setContextValue(V);
250 return;
251 }
252 llvm_unreachable("No context value for inlined OpenMP region");
253 }
Eugene Zelenko0a4f3f42016-02-10 19:11:58 +0000254
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000255 /// Lookup the captured field decl for a variable.
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000256 const FieldDecl *lookup(const VarDecl *VD) const override {
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000257 if (OuterRegionInfo)
258 return OuterRegionInfo->lookup(VD);
Alexey Bataev69c62a92015-04-15 04:52:20 +0000259 // If there is no outer outlined region,no need to lookup in a list of
260 // captured variables, we can use the original one.
261 return nullptr;
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000262 }
Eugene Zelenko0a4f3f42016-02-10 19:11:58 +0000263
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000264 FieldDecl *getThisFieldDecl() const override {
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000265 if (OuterRegionInfo)
266 return OuterRegionInfo->getThisFieldDecl();
267 return nullptr;
268 }
Eugene Zelenko0a4f3f42016-02-10 19:11:58 +0000269
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000270 /// Get a variable or parameter for storing global thread id
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000271 /// inside OpenMP construct.
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000272 const VarDecl *getThreadIDVariable() const override {
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000273 if (OuterRegionInfo)
274 return OuterRegionInfo->getThreadIDVariable();
275 return nullptr;
276 }
Alexey Bataev62b63b12015-03-10 07:28:44 +0000277
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000278 /// Get an LValue for the current ThreadID variable.
Alexey Bataev311a9282017-10-12 13:51:32 +0000279 LValue getThreadIDVariableLValue(CodeGenFunction &CGF) override {
280 if (OuterRegionInfo)
281 return OuterRegionInfo->getThreadIDVariableLValue(CGF);
282 llvm_unreachable("No LValue for inlined OpenMP construct");
283 }
284
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000285 /// Get the name of the capture helper.
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000286 StringRef getHelperName() const override {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000287 if (auto *OuterRegionInfo = getOldCSI())
288 return OuterRegionInfo->getHelperName();
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000289 llvm_unreachable("No helper name for inlined OpenMP construct");
290 }
291
Alexey Bataev48591dd2016-04-20 04:01:36 +0000292 void emitUntiedSwitch(CodeGenFunction &CGF) override {
293 if (OuterRegionInfo)
294 OuterRegionInfo->emitUntiedSwitch(CGF);
295 }
296
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000297 CodeGenFunction::CGCapturedStmtInfo *getOldCSI() const { return OldCSI; }
298
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000299 static bool classof(const CGCapturedStmtInfo *Info) {
300 return CGOpenMPRegionInfo::classof(Info) &&
301 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() == InlinedRegion;
302 }
303
Alexey Bataev48591dd2016-04-20 04:01:36 +0000304 ~CGOpenMPInlinedRegionInfo() override = default;
305
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000306private:
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000307 /// CodeGen info about outer OpenMP region.
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000308 CodeGenFunction::CGCapturedStmtInfo *OldCSI;
309 CGOpenMPRegionInfo *OuterRegionInfo;
Alexey Bataev18095712014-10-10 12:19:54 +0000310};
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000311
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000312/// API for captured statement code generation in OpenMP target
Samuel Antaobed3c462015-10-02 16:14:20 +0000313/// constructs. For this captures, implicit parameters are used instead of the
Samuel Antaoee8fb302016-01-06 13:42:12 +0000314/// captured fields. The name of the target region has to be unique in a given
315/// application so it is provided by the client, because only the client has
316/// the information to generate that.
Alexey Bataev48591dd2016-04-20 04:01:36 +0000317class CGOpenMPTargetRegionInfo final : public CGOpenMPRegionInfo {
Samuel Antaobed3c462015-10-02 16:14:20 +0000318public:
319 CGOpenMPTargetRegionInfo(const CapturedStmt &CS,
Samuel Antaoee8fb302016-01-06 13:42:12 +0000320 const RegionCodeGenTy &CodeGen, StringRef HelperName)
Samuel Antaobed3c462015-10-02 16:14:20 +0000321 : CGOpenMPRegionInfo(CS, TargetRegion, CodeGen, OMPD_target,
Samuel Antaoee8fb302016-01-06 13:42:12 +0000322 /*HasCancel=*/false),
323 HelperName(HelperName) {}
Samuel Antaobed3c462015-10-02 16:14:20 +0000324
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000325 /// This is unused for target regions because each starts executing
Samuel Antaobed3c462015-10-02 16:14:20 +0000326 /// with a single thread.
327 const VarDecl *getThreadIDVariable() const override { return nullptr; }
328
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000329 /// Get the name of the capture helper.
Samuel Antaoee8fb302016-01-06 13:42:12 +0000330 StringRef getHelperName() const override { return HelperName; }
Samuel Antaobed3c462015-10-02 16:14:20 +0000331
332 static bool classof(const CGCapturedStmtInfo *Info) {
333 return CGOpenMPRegionInfo::classof(Info) &&
334 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() == TargetRegion;
335 }
Samuel Antaoee8fb302016-01-06 13:42:12 +0000336
337private:
338 StringRef HelperName;
Samuel Antaobed3c462015-10-02 16:14:20 +0000339};
340
Alexey Bataev14fa1c62016-03-29 05:34:15 +0000341static void EmptyCodeGen(CodeGenFunction &, PrePostActionTy &) {
Samuel Antaob68e2db2016-03-03 16:20:23 +0000342 llvm_unreachable("No codegen for expressions");
343}
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000344/// API for generation of expressions captured in a innermost OpenMP
Samuel Antaob68e2db2016-03-03 16:20:23 +0000345/// region.
Alexey Bataev48591dd2016-04-20 04:01:36 +0000346class CGOpenMPInnerExprInfo final : public CGOpenMPInlinedRegionInfo {
Samuel Antaob68e2db2016-03-03 16:20:23 +0000347public:
348 CGOpenMPInnerExprInfo(CodeGenFunction &CGF, const CapturedStmt &CS)
349 : CGOpenMPInlinedRegionInfo(CGF.CapturedStmtInfo, EmptyCodeGen,
350 OMPD_unknown,
351 /*HasCancel=*/false),
352 PrivScope(CGF) {
353 // Make sure the globals captured in the provided statement are local by
354 // using the privatization logic. We assume the same variable is not
355 // captured more than once.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000356 for (const auto &C : CS.captures()) {
Samuel Antaob68e2db2016-03-03 16:20:23 +0000357 if (!C.capturesVariable() && !C.capturesVariableByCopy())
358 continue;
359
360 const VarDecl *VD = C.getCapturedVar();
361 if (VD->isLocalVarDeclOrParm())
362 continue;
363
Bruno Ricci5fc4db72018-12-21 14:10:18 +0000364 DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(VD),
Samuel Antaob68e2db2016-03-03 16:20:23 +0000365 /*RefersToEnclosingVariableOrCapture=*/false,
366 VD->getType().getNonReferenceType(), VK_LValue,
Alexey Bataeva9b9cc02018-01-23 18:12:38 +0000367 C.getLocation());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000368 PrivScope.addPrivate(
Akira Hatanakaf139ae32019-12-03 15:17:01 -0800369 VD, [&CGF, &DRE]() { return CGF.EmitLValue(&DRE).getAddress(CGF); });
Samuel Antaob68e2db2016-03-03 16:20:23 +0000370 }
371 (void)PrivScope.Privatize();
372 }
373
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000374 /// Lookup the captured field decl for a variable.
Samuel Antaob68e2db2016-03-03 16:20:23 +0000375 const FieldDecl *lookup(const VarDecl *VD) const override {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000376 if (const FieldDecl *FD = CGOpenMPInlinedRegionInfo::lookup(VD))
Samuel Antaob68e2db2016-03-03 16:20:23 +0000377 return FD;
378 return nullptr;
379 }
380
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000381 /// Emit the captured statement body.
Samuel Antaob68e2db2016-03-03 16:20:23 +0000382 void EmitBody(CodeGenFunction &CGF, const Stmt *S) override {
383 llvm_unreachable("No body for expressions");
384 }
385
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000386 /// Get a variable or parameter for storing global thread id
Samuel Antaob68e2db2016-03-03 16:20:23 +0000387 /// inside OpenMP construct.
388 const VarDecl *getThreadIDVariable() const override {
389 llvm_unreachable("No thread id for expressions");
390 }
391
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000392 /// Get the name of the capture helper.
Samuel Antaob68e2db2016-03-03 16:20:23 +0000393 StringRef getHelperName() const override {
394 llvm_unreachable("No helper name for expressions");
395 }
396
397 static bool classof(const CGCapturedStmtInfo *Info) { return false; }
398
399private:
400 /// Private scope to capture global variables.
401 CodeGenFunction::OMPPrivateScope PrivScope;
402};
403
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000404/// RAII for emitting code of OpenMP constructs.
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000405class InlinedOpenMPRegionRAII {
406 CodeGenFunction &CGF;
Alexey Bataev4ba78a42016-04-27 07:56:03 +0000407 llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
408 FieldDecl *LambdaThisCaptureField = nullptr;
Alexey Bataeva8a9153a2017-12-29 18:07:07 +0000409 const CodeGen::CGBlockInfo *BlockInfo = nullptr;
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000410
411public:
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000412 /// Constructs region for combined constructs.
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000413 /// \param CodeGen Code generation sequence for combined directives. Includes
414 /// a list of functions used for code generation of implicitly inlined
415 /// regions.
Alexey Bataev81c7ea02015-07-03 09:56:58 +0000416 InlinedOpenMPRegionRAII(CodeGenFunction &CGF, const RegionCodeGenTy &CodeGen,
Alexey Bataev25e5b442015-09-15 12:52:43 +0000417 OpenMPDirectiveKind Kind, bool HasCancel)
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000418 : CGF(CGF) {
419 // Start emission for the construct.
Alexey Bataev25e5b442015-09-15 12:52:43 +0000420 CGF.CapturedStmtInfo = new CGOpenMPInlinedRegionInfo(
421 CGF.CapturedStmtInfo, CodeGen, Kind, HasCancel);
Alexey Bataev4ba78a42016-04-27 07:56:03 +0000422 std::swap(CGF.LambdaCaptureFields, LambdaCaptureFields);
423 LambdaThisCaptureField = CGF.LambdaThisCaptureField;
424 CGF.LambdaThisCaptureField = nullptr;
Alexey Bataeva8a9153a2017-12-29 18:07:07 +0000425 BlockInfo = CGF.BlockInfo;
426 CGF.BlockInfo = nullptr;
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000427 }
Eugene Zelenko0a4f3f42016-02-10 19:11:58 +0000428
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000429 ~InlinedOpenMPRegionRAII() {
430 // Restore original CapturedStmtInfo only if we're done with code emission.
431 auto *OldCSI =
432 cast<CGOpenMPInlinedRegionInfo>(CGF.CapturedStmtInfo)->getOldCSI();
433 delete CGF.CapturedStmtInfo;
434 CGF.CapturedStmtInfo = OldCSI;
Alexey Bataev4ba78a42016-04-27 07:56:03 +0000435 std::swap(CGF.LambdaCaptureFields, LambdaCaptureFields);
436 CGF.LambdaThisCaptureField = LambdaThisCaptureField;
Alexey Bataeva8a9153a2017-12-29 18:07:07 +0000437 CGF.BlockInfo = BlockInfo;
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000438 }
439};
440
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000441/// Values for bit flags used in the ident_t to describe the fields.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000442/// All enumeric elements are named and described in accordance with the code
James Y Knight5d71fc52019-01-29 16:37:27 +0000443/// from https://github.com/llvm/llvm-project/blob/master/openmp/runtime/src/kmp.h
Alexey Bataev0f87dbe2017-08-14 17:56:13 +0000444enum OpenMPLocationFlags : unsigned {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000445 /// Use trampoline for internal microtask.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000446 OMP_IDENT_IMD = 0x01,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000447 /// Use c-style ident structure.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000448 OMP_IDENT_KMPC = 0x02,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000449 /// Atomic reduction option for kmpc_reduce.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000450 OMP_ATOMIC_REDUCE = 0x10,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000451 /// Explicit 'barrier' directive.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000452 OMP_IDENT_BARRIER_EXPL = 0x20,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000453 /// Implicit barrier in code.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000454 OMP_IDENT_BARRIER_IMPL = 0x40,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000455 /// Implicit barrier in 'for' directive.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000456 OMP_IDENT_BARRIER_IMPL_FOR = 0x40,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000457 /// Implicit barrier in 'sections' directive.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000458 OMP_IDENT_BARRIER_IMPL_SECTIONS = 0xC0,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000459 /// Implicit barrier in 'single' directive.
Alexey Bataev0f87dbe2017-08-14 17:56:13 +0000460 OMP_IDENT_BARRIER_IMPL_SINGLE = 0x140,
461 /// Call of __kmp_for_static_init for static loop.
462 OMP_IDENT_WORK_LOOP = 0x200,
463 /// Call of __kmp_for_static_init for sections.
464 OMP_IDENT_WORK_SECTIONS = 0x400,
465 /// Call of __kmp_for_static_init for distribute.
466 OMP_IDENT_WORK_DISTRIBUTE = 0x800,
467 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/OMP_IDENT_WORK_DISTRIBUTE)
Alexey Bataev50b3c952016-02-19 10:38:26 +0000468};
469
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +0000470namespace {
471LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
472/// Values for bit flags for marking which requires clauses have been used.
473enum OpenMPOffloadingRequiresDirFlags : int64_t {
474 /// flag undefined.
475 OMP_REQ_UNDEFINED = 0x000,
476 /// no requires clause present.
477 OMP_REQ_NONE = 0x001,
478 /// reverse_offload clause.
479 OMP_REQ_REVERSE_OFFLOAD = 0x002,
480 /// unified_address clause.
481 OMP_REQ_UNIFIED_ADDRESS = 0x004,
482 /// unified_shared_memory clause.
483 OMP_REQ_UNIFIED_SHARED_MEMORY = 0x008,
484 /// dynamic_allocators clause.
485 OMP_REQ_DYNAMIC_ALLOCATORS = 0x010,
486 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/OMP_REQ_DYNAMIC_ALLOCATORS)
487};
Gheorghe-Teodor Bercea545a9fe2019-06-14 20:19:54 +0000488
489enum OpenMPOffloadingReservedDeviceIDs {
490 /// Device ID if the device was not defined, runtime should get it
491 /// from environment variables in the spec.
492 OMP_DEVICEID_UNDEF = -1,
493};
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +0000494} // anonymous namespace
495
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000496/// Describes ident structure that describes a source location.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000497/// All descriptions are taken from
James Y Knight5d71fc52019-01-29 16:37:27 +0000498/// https://github.com/llvm/llvm-project/blob/master/openmp/runtime/src/kmp.h
Alexey Bataev50b3c952016-02-19 10:38:26 +0000499/// Original structure:
500/// typedef struct ident {
501/// kmp_int32 reserved_1; /**< might be used in Fortran;
502/// see above */
503/// kmp_int32 flags; /**< also f.flags; KMP_IDENT_xxx flags;
504/// KMP_IDENT_KMPC identifies this union
505/// member */
506/// kmp_int32 reserved_2; /**< not really used in Fortran any more;
507/// see above */
508///#if USE_ITT_BUILD
509/// /* but currently used for storing
510/// region-specific ITT */
511/// /* contextual information. */
512///#endif /* USE_ITT_BUILD */
513/// kmp_int32 reserved_3; /**< source[4] in Fortran, do not use for
514/// C++ */
515/// char const *psource; /**< String describing the source location.
516/// The string is composed of semi-colon separated
517// fields which describe the source file,
518/// the function and a pair of line numbers that
519/// delimit the construct.
520/// */
521/// } ident_t;
522enum IdentFieldIndex {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000523 /// might be used in Fortran
Alexey Bataev50b3c952016-02-19 10:38:26 +0000524 IdentField_Reserved_1,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000525 /// OMP_IDENT_xxx flags; OMP_IDENT_KMPC identifies this union member.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000526 IdentField_Flags,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000527 /// Not really used in Fortran any more
Alexey Bataev50b3c952016-02-19 10:38:26 +0000528 IdentField_Reserved_2,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000529 /// Source[4] in Fortran, do not use for C++
Alexey Bataev50b3c952016-02-19 10:38:26 +0000530 IdentField_Reserved_3,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000531 /// String describing the source location. The string is composed of
Alexey Bataev50b3c952016-02-19 10:38:26 +0000532 /// semi-colon separated fields which describe the source file, the function
533 /// and a pair of line numbers that delimit the construct.
534 IdentField_PSource
535};
536
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000537/// Schedule types for 'omp for' loops (these enumerators are taken from
Alexey Bataev50b3c952016-02-19 10:38:26 +0000538/// the enum sched_type in kmp.h).
539enum OpenMPSchedType {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000540 /// Lower bound for default (unordered) versions.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000541 OMP_sch_lower = 32,
542 OMP_sch_static_chunked = 33,
543 OMP_sch_static = 34,
544 OMP_sch_dynamic_chunked = 35,
545 OMP_sch_guided_chunked = 36,
546 OMP_sch_runtime = 37,
547 OMP_sch_auto = 38,
Alexey Bataev6cff6242016-05-30 13:05:14 +0000548 /// static with chunk adjustment (e.g., simd)
Samuel Antao4c8035b2016-12-12 18:00:20 +0000549 OMP_sch_static_balanced_chunked = 45,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000550 /// Lower bound for 'ordered' versions.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000551 OMP_ord_lower = 64,
552 OMP_ord_static_chunked = 65,
553 OMP_ord_static = 66,
554 OMP_ord_dynamic_chunked = 67,
555 OMP_ord_guided_chunked = 68,
556 OMP_ord_runtime = 69,
557 OMP_ord_auto = 70,
558 OMP_sch_default = OMP_sch_static,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000559 /// dist_schedule types
Carlo Bertollifc35ad22016-03-07 16:04:49 +0000560 OMP_dist_sch_static_chunked = 91,
561 OMP_dist_sch_static = 92,
Alexey Bataev9ebd7422016-05-10 09:57:36 +0000562 /// Support for OpenMP 4.5 monotonic and nonmonotonic schedule modifiers.
563 /// Set if the monotonic schedule modifier was present.
564 OMP_sch_modifier_monotonic = (1 << 29),
565 /// Set if the nonmonotonic schedule modifier was present.
566 OMP_sch_modifier_nonmonotonic = (1 << 30),
Alexey Bataev50b3c952016-02-19 10:38:26 +0000567};
568
569enum OpenMPRTLFunction {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000570 /// Call to void __kmpc_fork_call(ident_t *loc, kmp_int32 argc,
Alexey Bataev50b3c952016-02-19 10:38:26 +0000571 /// kmpc_micro microtask, ...);
572 OMPRTL__kmpc_fork_call,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000573 /// Call to void *__kmpc_threadprivate_cached(ident_t *loc,
Alexey Bataev50b3c952016-02-19 10:38:26 +0000574 /// kmp_int32 global_tid, void *data, size_t size, void ***cache);
575 OMPRTL__kmpc_threadprivate_cached,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000576 /// Call to void __kmpc_threadprivate_register( ident_t *,
Alexey Bataev50b3c952016-02-19 10:38:26 +0000577 /// void *data, kmpc_ctor ctor, kmpc_cctor cctor, kmpc_dtor dtor);
578 OMPRTL__kmpc_threadprivate_register,
579 // Call to __kmpc_int32 kmpc_global_thread_num(ident_t *loc);
580 OMPRTL__kmpc_global_thread_num,
581 // Call to void __kmpc_critical(ident_t *loc, kmp_int32 global_tid,
582 // kmp_critical_name *crit);
583 OMPRTL__kmpc_critical,
584 // Call to void __kmpc_critical_with_hint(ident_t *loc, kmp_int32
585 // global_tid, kmp_critical_name *crit, uintptr_t hint);
586 OMPRTL__kmpc_critical_with_hint,
587 // Call to void __kmpc_end_critical(ident_t *loc, kmp_int32 global_tid,
588 // kmp_critical_name *crit);
589 OMPRTL__kmpc_end_critical,
590 // Call to kmp_int32 __kmpc_cancel_barrier(ident_t *loc, kmp_int32
591 // global_tid);
592 OMPRTL__kmpc_cancel_barrier,
593 // Call to void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid);
594 OMPRTL__kmpc_barrier,
595 // Call to void __kmpc_for_static_fini(ident_t *loc, kmp_int32 global_tid);
596 OMPRTL__kmpc_for_static_fini,
597 // Call to void __kmpc_serialized_parallel(ident_t *loc, kmp_int32
598 // global_tid);
599 OMPRTL__kmpc_serialized_parallel,
600 // Call to void __kmpc_end_serialized_parallel(ident_t *loc, kmp_int32
601 // global_tid);
602 OMPRTL__kmpc_end_serialized_parallel,
603 // Call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid,
604 // kmp_int32 num_threads);
605 OMPRTL__kmpc_push_num_threads,
606 // Call to void __kmpc_flush(ident_t *loc);
607 OMPRTL__kmpc_flush,
608 // Call to kmp_int32 __kmpc_master(ident_t *, kmp_int32 global_tid);
609 OMPRTL__kmpc_master,
610 // Call to void __kmpc_end_master(ident_t *, kmp_int32 global_tid);
611 OMPRTL__kmpc_end_master,
612 // Call to kmp_int32 __kmpc_omp_taskyield(ident_t *, kmp_int32 global_tid,
613 // int end_part);
614 OMPRTL__kmpc_omp_taskyield,
615 // Call to kmp_int32 __kmpc_single(ident_t *, kmp_int32 global_tid);
616 OMPRTL__kmpc_single,
617 // Call to void __kmpc_end_single(ident_t *, kmp_int32 global_tid);
618 OMPRTL__kmpc_end_single,
619 // Call to kmp_task_t * __kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid,
620 // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
621 // kmp_routine_entry_t *task_entry);
622 OMPRTL__kmpc_omp_task_alloc,
Gheorghe-Teodor Bercea545a9fe2019-06-14 20:19:54 +0000623 // Call to kmp_task_t * __kmpc_omp_target_task_alloc(ident_t *,
624 // kmp_int32 gtid, kmp_int32 flags, size_t sizeof_kmp_task_t,
625 // size_t sizeof_shareds, kmp_routine_entry_t *task_entry,
626 // kmp_int64 device_id);
627 OMPRTL__kmpc_omp_target_task_alloc,
Alexey Bataev50b3c952016-02-19 10:38:26 +0000628 // Call to kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t *
629 // new_task);
630 OMPRTL__kmpc_omp_task,
631 // Call to void __kmpc_copyprivate(ident_t *loc, kmp_int32 global_tid,
632 // size_t cpy_size, void *cpy_data, void(*cpy_func)(void *, void *),
633 // kmp_int32 didit);
634 OMPRTL__kmpc_copyprivate,
635 // Call to kmp_int32 __kmpc_reduce(ident_t *loc, kmp_int32 global_tid,
636 // kmp_int32 num_vars, size_t reduce_size, void *reduce_data, void
637 // (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name *lck);
638 OMPRTL__kmpc_reduce,
639 // Call to kmp_int32 __kmpc_reduce_nowait(ident_t *loc, kmp_int32
640 // global_tid, kmp_int32 num_vars, size_t reduce_size, void *reduce_data,
641 // void (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name
642 // *lck);
643 OMPRTL__kmpc_reduce_nowait,
644 // Call to void __kmpc_end_reduce(ident_t *loc, kmp_int32 global_tid,
645 // kmp_critical_name *lck);
646 OMPRTL__kmpc_end_reduce,
647 // Call to void __kmpc_end_reduce_nowait(ident_t *loc, kmp_int32 global_tid,
648 // kmp_critical_name *lck);
649 OMPRTL__kmpc_end_reduce_nowait,
650 // Call to void __kmpc_omp_task_begin_if0(ident_t *, kmp_int32 gtid,
651 // kmp_task_t * new_task);
652 OMPRTL__kmpc_omp_task_begin_if0,
653 // Call to void __kmpc_omp_task_complete_if0(ident_t *, kmp_int32 gtid,
654 // kmp_task_t * new_task);
655 OMPRTL__kmpc_omp_task_complete_if0,
656 // Call to void __kmpc_ordered(ident_t *loc, kmp_int32 global_tid);
657 OMPRTL__kmpc_ordered,
658 // Call to void __kmpc_end_ordered(ident_t *loc, kmp_int32 global_tid);
659 OMPRTL__kmpc_end_ordered,
660 // Call to kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32
661 // global_tid);
662 OMPRTL__kmpc_omp_taskwait,
663 // Call to void __kmpc_taskgroup(ident_t *loc, kmp_int32 global_tid);
664 OMPRTL__kmpc_taskgroup,
665 // Call to void __kmpc_end_taskgroup(ident_t *loc, kmp_int32 global_tid);
666 OMPRTL__kmpc_end_taskgroup,
667 // Call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32 global_tid,
668 // int proc_bind);
669 OMPRTL__kmpc_push_proc_bind,
670 // Call to kmp_int32 __kmpc_omp_task_with_deps(ident_t *loc_ref, kmp_int32
671 // gtid, kmp_task_t * new_task, kmp_int32 ndeps, kmp_depend_info_t
672 // *dep_list, kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list);
673 OMPRTL__kmpc_omp_task_with_deps,
674 // Call to void __kmpc_omp_wait_deps(ident_t *loc_ref, kmp_int32
675 // gtid, kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32
676 // ndeps_noalias, kmp_depend_info_t *noalias_dep_list);
677 OMPRTL__kmpc_omp_wait_deps,
678 // Call to kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32
679 // global_tid, kmp_int32 cncl_kind);
680 OMPRTL__kmpc_cancellationpoint,
681 // Call to kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid,
682 // kmp_int32 cncl_kind);
683 OMPRTL__kmpc_cancel,
Carlo Bertolli430d8ec2016-03-03 20:34:23 +0000684 // Call to void __kmpc_push_num_teams(ident_t *loc, kmp_int32 global_tid,
685 // kmp_int32 num_teams, kmp_int32 thread_limit);
686 OMPRTL__kmpc_push_num_teams,
Alexey Bataev7292c292016-04-25 12:22:29 +0000687 // Call to void __kmpc_fork_teams(ident_t *loc, kmp_int32 argc, kmpc_micro
688 // microtask, ...);
Carlo Bertolli430d8ec2016-03-03 20:34:23 +0000689 OMPRTL__kmpc_fork_teams,
Alexey Bataev7292c292016-04-25 12:22:29 +0000690 // Call to void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t *task, int
691 // if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int nogroup, int
692 // sched, kmp_uint64 grainsize, void *task_dup);
693 OMPRTL__kmpc_taskloop,
Alexey Bataev8b427062016-05-25 12:36:08 +0000694 // Call to void __kmpc_doacross_init(ident_t *loc, kmp_int32 gtid, kmp_int32
695 // num_dims, struct kmp_dim *dims);
696 OMPRTL__kmpc_doacross_init,
697 // Call to void __kmpc_doacross_fini(ident_t *loc, kmp_int32 gtid);
698 OMPRTL__kmpc_doacross_fini,
699 // Call to void __kmpc_doacross_post(ident_t *loc, kmp_int32 gtid, kmp_int64
700 // *vec);
701 OMPRTL__kmpc_doacross_post,
702 // Call to void __kmpc_doacross_wait(ident_t *loc, kmp_int32 gtid, kmp_int64
703 // *vec);
704 OMPRTL__kmpc_doacross_wait,
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000705 // Call to void *__kmpc_task_reduction_init(int gtid, int num_data, void
706 // *data);
707 OMPRTL__kmpc_task_reduction_init,
708 // Call to void *__kmpc_task_reduction_get_th_data(int gtid, void *tg, void
709 // *d);
710 OMPRTL__kmpc_task_reduction_get_th_data,
Alexey Bataev6cf7b712019-04-08 19:06:42 +0000711 // Call to void *__kmpc_alloc(int gtid, size_t sz, omp_allocator_handle_t al);
Alexey Bataev4f680db2019-03-19 16:41:16 +0000712 OMPRTL__kmpc_alloc,
Alexey Bataev6cf7b712019-04-08 19:06:42 +0000713 // Call to void __kmpc_free(int gtid, void *ptr, omp_allocator_handle_t al);
Alexey Bataev4f680db2019-03-19 16:41:16 +0000714 OMPRTL__kmpc_free,
Alexey Bataev50b3c952016-02-19 10:38:26 +0000715
716 //
717 // Offloading related calls
718 //
Alexey Bataev7bb33532019-01-07 21:30:43 +0000719 // Call to void __kmpc_push_target_tripcount(int64_t device_id, kmp_uint64
720 // size);
721 OMPRTL__kmpc_push_target_tripcount,
George Rokos63bc9d62017-11-21 18:25:12 +0000722 // Call to int32_t __tgt_target(int64_t device_id, void *host_ptr, int32_t
Alexey Bataeva90fc662019-06-25 16:00:43 +0000723 // arg_num, void** args_base, void **args, int64_t *arg_sizes, int64_t
Alexey Bataev50b3c952016-02-19 10:38:26 +0000724 // *arg_types);
725 OMPRTL__tgt_target,
Alexey Bataeva9f77c62017-12-13 21:04:20 +0000726 // Call to int32_t __tgt_target_nowait(int64_t device_id, void *host_ptr,
Alexey Bataeva90fc662019-06-25 16:00:43 +0000727 // int32_t arg_num, void** args_base, void **args, int64_t *arg_sizes, int64_t
Alexey Bataeva9f77c62017-12-13 21:04:20 +0000728 // *arg_types);
729 OMPRTL__tgt_target_nowait,
George Rokos63bc9d62017-11-21 18:25:12 +0000730 // Call to int32_t __tgt_target_teams(int64_t device_id, void *host_ptr,
Alexey Bataeva90fc662019-06-25 16:00:43 +0000731 // int32_t arg_num, void** args_base, void **args, int64_t *arg_sizes, int64_t
George Rokos63bc9d62017-11-21 18:25:12 +0000732 // *arg_types, int32_t num_teams, int32_t thread_limit);
Samuel Antaob68e2db2016-03-03 16:20:23 +0000733 OMPRTL__tgt_target_teams,
Alexey Bataeva9f77c62017-12-13 21:04:20 +0000734 // Call to int32_t __tgt_target_teams_nowait(int64_t device_id, void
Alexey Bataeva90fc662019-06-25 16:00:43 +0000735 // *host_ptr, int32_t arg_num, void** args_base, void **args, int64_t
Alexey Bataeva9f77c62017-12-13 21:04:20 +0000736 // *arg_sizes, int64_t *arg_types, int32_t num_teams, int32_t thread_limit);
737 OMPRTL__tgt_target_teams_nowait,
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +0000738 // Call to void __tgt_register_requires(int64_t flags);
739 OMPRTL__tgt_register_requires,
George Rokos63bc9d62017-11-21 18:25:12 +0000740 // Call to void __tgt_target_data_begin(int64_t device_id, int32_t arg_num,
Alexey Bataeva90fc662019-06-25 16:00:43 +0000741 // void** args_base, void **args, int64_t *arg_sizes, int64_t *arg_types);
Samuel Antaodf158d52016-04-27 22:58:19 +0000742 OMPRTL__tgt_target_data_begin,
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +0000743 // Call to void __tgt_target_data_begin_nowait(int64_t device_id, int32_t
Alexey Bataeva90fc662019-06-25 16:00:43 +0000744 // arg_num, void** args_base, void **args, int64_t *arg_sizes, int64_t
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +0000745 // *arg_types);
746 OMPRTL__tgt_target_data_begin_nowait,
George Rokos63bc9d62017-11-21 18:25:12 +0000747 // Call to void __tgt_target_data_end(int64_t device_id, int32_t arg_num,
748 // void** args_base, void **args, size_t *arg_sizes, int64_t *arg_types);
Samuel Antaodf158d52016-04-27 22:58:19 +0000749 OMPRTL__tgt_target_data_end,
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +0000750 // Call to void __tgt_target_data_end_nowait(int64_t device_id, int32_t
Alexey Bataeva90fc662019-06-25 16:00:43 +0000751 // arg_num, void** args_base, void **args, int64_t *arg_sizes, int64_t
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +0000752 // *arg_types);
753 OMPRTL__tgt_target_data_end_nowait,
George Rokos63bc9d62017-11-21 18:25:12 +0000754 // Call to void __tgt_target_data_update(int64_t device_id, int32_t arg_num,
Alexey Bataeva90fc662019-06-25 16:00:43 +0000755 // void** args_base, void **args, int64_t *arg_sizes, int64_t *arg_types);
Samuel Antao8d2d7302016-05-26 18:30:22 +0000756 OMPRTL__tgt_target_data_update,
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +0000757 // Call to void __tgt_target_data_update_nowait(int64_t device_id, int32_t
Alexey Bataeva90fc662019-06-25 16:00:43 +0000758 // arg_num, void** args_base, void **args, int64_t *arg_sizes, int64_t
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +0000759 // *arg_types);
760 OMPRTL__tgt_target_data_update_nowait,
Michael Krused47b9432019-08-05 18:43:21 +0000761 // Call to int64_t __tgt_mapper_num_components(void *rt_mapper_handle);
762 OMPRTL__tgt_mapper_num_components,
763 // Call to void __tgt_push_mapper_component(void *rt_mapper_handle, void
764 // *base, void *begin, int64_t size, int64_t type);
765 OMPRTL__tgt_push_mapper_component,
Alexey Bataev50b3c952016-02-19 10:38:26 +0000766};
767
Alexey Bataev14fa1c62016-03-29 05:34:15 +0000768/// A basic class for pre|post-action for advanced codegen sequence for OpenMP
769/// region.
770class CleanupTy final : public EHScopeStack::Cleanup {
771 PrePostActionTy *Action;
772
773public:
774 explicit CleanupTy(PrePostActionTy *Action) : Action(Action) {}
775 void Emit(CodeGenFunction &CGF, Flags /*flags*/) override {
776 if (!CGF.HaveInsertPoint())
777 return;
778 Action->Exit(CGF);
779 }
780};
781
Hans Wennborg7eb54642015-09-10 17:07:54 +0000782} // anonymous namespace
Alexey Bataev18095712014-10-10 12:19:54 +0000783
Alexey Bataev14fa1c62016-03-29 05:34:15 +0000784void RegionCodeGenTy::operator()(CodeGenFunction &CGF) const {
785 CodeGenFunction::RunCleanupsScope Scope(CGF);
786 if (PrePostAction) {
787 CGF.EHStack.pushCleanup<CleanupTy>(NormalAndEHCleanup, PrePostAction);
788 Callback(CodeGen, CGF, *PrePostAction);
789 } else {
790 PrePostActionTy Action;
791 Callback(CodeGen, CGF, Action);
792 }
793}
794
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000795/// Check if the combiner is a call to UDR combiner and if it is so return the
796/// UDR decl used for reduction.
797static const OMPDeclareReductionDecl *
798getReductionInit(const Expr *ReductionOp) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000799 if (const auto *CE = dyn_cast<CallExpr>(ReductionOp))
800 if (const auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee()))
801 if (const auto *DRE =
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000802 dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts()))
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000803 if (const auto *DRD = dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl()))
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000804 return DRD;
805 return nullptr;
806}
807
808static void emitInitWithReductionInitializer(CodeGenFunction &CGF,
809 const OMPDeclareReductionDecl *DRD,
810 const Expr *InitOp,
811 Address Private, Address Original,
812 QualType Ty) {
813 if (DRD->getInitializer()) {
814 std::pair<llvm::Function *, llvm::Function *> Reduction =
815 CGF.CGM.getOpenMPRuntime().getUserDefinedReduction(DRD);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000816 const auto *CE = cast<CallExpr>(InitOp);
817 const auto *OVE = cast<OpaqueValueExpr>(CE->getCallee());
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000818 const Expr *LHS = CE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
819 const Expr *RHS = CE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000820 const auto *LHSDRE =
821 cast<DeclRefExpr>(cast<UnaryOperator>(LHS)->getSubExpr());
822 const auto *RHSDRE =
823 cast<DeclRefExpr>(cast<UnaryOperator>(RHS)->getSubExpr());
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000824 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
825 PrivateScope.addPrivate(cast<VarDecl>(LHSDRE->getDecl()),
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000826 [=]() { return Private; });
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000827 PrivateScope.addPrivate(cast<VarDecl>(RHSDRE->getDecl()),
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000828 [=]() { return Original; });
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000829 (void)PrivateScope.Privatize();
830 RValue Func = RValue::get(Reduction.second);
831 CodeGenFunction::OpaqueValueMapping Map(CGF, OVE, Func);
832 CGF.EmitIgnoredExpr(InitOp);
833 } else {
834 llvm::Constant *Init = CGF.CGM.EmitNullConstant(Ty);
Alexey Bataev18fa2322018-05-02 14:20:50 +0000835 std::string Name = CGF.CGM.getOpenMPRuntime().getName({"init"});
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000836 auto *GV = new llvm::GlobalVariable(
837 CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true,
Alexey Bataev18fa2322018-05-02 14:20:50 +0000838 llvm::GlobalValue::PrivateLinkage, Init, Name);
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000839 LValue LV = CGF.MakeNaturalAlignAddrLValue(GV, Ty);
840 RValue InitRVal;
841 switch (CGF.getEvaluationKind(Ty)) {
842 case TEK_Scalar:
Alexey Bataeva9b9cc02018-01-23 18:12:38 +0000843 InitRVal = CGF.EmitLoadOfLValue(LV, DRD->getLocation());
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000844 break;
845 case TEK_Complex:
846 InitRVal =
Alexey Bataeva9b9cc02018-01-23 18:12:38 +0000847 RValue::getComplex(CGF.EmitLoadOfComplex(LV, DRD->getLocation()));
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000848 break;
849 case TEK_Aggregate:
Akira Hatanakaf139ae32019-12-03 15:17:01 -0800850 InitRVal = RValue::getAggregate(LV.getAddress(CGF));
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000851 break;
852 }
Alexey Bataeva9b9cc02018-01-23 18:12:38 +0000853 OpaqueValueExpr OVE(DRD->getLocation(), Ty, VK_RValue);
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000854 CodeGenFunction::OpaqueValueMapping OpaqueMap(CGF, &OVE, InitRVal);
855 CGF.EmitAnyExprToMem(&OVE, Private, Ty.getQualifiers(),
856 /*IsInitializer=*/false);
857 }
858}
859
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000860/// Emit initialization of arrays of complex types.
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000861/// \param DestAddr Address of the array.
862/// \param Type Type of array.
863/// \param Init Initial expression of array.
864/// \param SrcAddr Address of the original array.
865static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr,
Alexey Bataeva7b19152017-10-12 20:03:39 +0000866 QualType Type, bool EmitDeclareReductionInit,
867 const Expr *Init,
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000868 const OMPDeclareReductionDecl *DRD,
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000869 Address SrcAddr = Address::invalid()) {
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000870 // Perform element-by-element initialization.
871 QualType ElementTy;
872
873 // Drill down to the base element type on both arrays.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000874 const ArrayType *ArrayTy = Type->getAsArrayTypeUnsafe();
875 llvm::Value *NumElements = CGF.emitArrayLength(ArrayTy, ElementTy, DestAddr);
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000876 DestAddr =
877 CGF.Builder.CreateElementBitCast(DestAddr, DestAddr.getElementType());
878 if (DRD)
879 SrcAddr =
880 CGF.Builder.CreateElementBitCast(SrcAddr, DestAddr.getElementType());
881
882 llvm::Value *SrcBegin = nullptr;
883 if (DRD)
884 SrcBegin = SrcAddr.getPointer();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000885 llvm::Value *DestBegin = DestAddr.getPointer();
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000886 // Cast from pointer to array type to pointer to single element.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000887 llvm::Value *DestEnd = CGF.Builder.CreateGEP(DestBegin, NumElements);
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000888 // The basic structure here is a while-do loop.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000889 llvm::BasicBlock *BodyBB = CGF.createBasicBlock("omp.arrayinit.body");
890 llvm::BasicBlock *DoneBB = CGF.createBasicBlock("omp.arrayinit.done");
891 llvm::Value *IsEmpty =
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000892 CGF.Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arrayinit.isempty");
893 CGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
894
895 // Enter the loop body, making that address the current address.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000896 llvm::BasicBlock *EntryBB = CGF.Builder.GetInsertBlock();
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000897 CGF.EmitBlock(BodyBB);
898
899 CharUnits ElementSize = CGF.getContext().getTypeSizeInChars(ElementTy);
900
901 llvm::PHINode *SrcElementPHI = nullptr;
902 Address SrcElementCurrent = Address::invalid();
903 if (DRD) {
904 SrcElementPHI = CGF.Builder.CreatePHI(SrcBegin->getType(), 2,
905 "omp.arraycpy.srcElementPast");
906 SrcElementPHI->addIncoming(SrcBegin, EntryBB);
907 SrcElementCurrent =
908 Address(SrcElementPHI,
909 SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize));
910 }
911 llvm::PHINode *DestElementPHI = CGF.Builder.CreatePHI(
912 DestBegin->getType(), 2, "omp.arraycpy.destElementPast");
913 DestElementPHI->addIncoming(DestBegin, EntryBB);
914 Address DestElementCurrent =
915 Address(DestElementPHI,
916 DestAddr.getAlignment().alignmentOfArrayElement(ElementSize));
917
918 // Emit copy.
919 {
920 CodeGenFunction::RunCleanupsScope InitScope(CGF);
Alexey Bataeva7b19152017-10-12 20:03:39 +0000921 if (EmitDeclareReductionInit) {
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000922 emitInitWithReductionInitializer(CGF, DRD, Init, DestElementCurrent,
923 SrcElementCurrent, ElementTy);
924 } else
925 CGF.EmitAnyExprToMem(Init, DestElementCurrent, ElementTy.getQualifiers(),
926 /*IsInitializer=*/false);
927 }
928
929 if (DRD) {
930 // Shift the address forward by one element.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000931 llvm::Value *SrcElementNext = CGF.Builder.CreateConstGEP1_32(
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000932 SrcElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
933 SrcElementPHI->addIncoming(SrcElementNext, CGF.Builder.GetInsertBlock());
934 }
935
936 // Shift the address forward by one element.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000937 llvm::Value *DestElementNext = CGF.Builder.CreateConstGEP1_32(
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000938 DestElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
939 // Check whether we've reached the end.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000940 llvm::Value *Done =
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000941 CGF.Builder.CreateICmpEQ(DestElementNext, DestEnd, "omp.arraycpy.done");
942 CGF.Builder.CreateCondBr(Done, DoneBB, BodyBB);
943 DestElementPHI->addIncoming(DestElementNext, CGF.Builder.GetInsertBlock());
944
945 // Done.
946 CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
947}
948
949LValue ReductionCodeGen::emitSharedLValue(CodeGenFunction &CGF, const Expr *E) {
Alexey Bataevf47c4b42017-09-26 13:47:31 +0000950 return CGF.EmitOMPSharedLValue(E);
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000951}
952
953LValue ReductionCodeGen::emitSharedLValueUB(CodeGenFunction &CGF,
954 const Expr *E) {
955 if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(E))
956 return CGF.EmitOMPArraySectionExpr(OASE, /*IsLowerBound=*/false);
957 return LValue();
958}
959
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000960void ReductionCodeGen::emitAggregateInitialization(
961 CodeGenFunction &CGF, unsigned N, Address PrivateAddr, LValue SharedLVal,
962 const OMPDeclareReductionDecl *DRD) {
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000963 // Emit VarDecl with copy init for arrays.
964 // Get the address of the original variable captured in current
965 // captured region.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000966 const auto *PrivateVD =
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000967 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
Alexey Bataeva7b19152017-10-12 20:03:39 +0000968 bool EmitDeclareReductionInit =
969 DRD && (DRD->getInitializer() || !PrivateVD->hasInit());
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000970 EmitOMPAggregateInit(CGF, PrivateAddr, PrivateVD->getType(),
Alexey Bataeva7b19152017-10-12 20:03:39 +0000971 EmitDeclareReductionInit,
972 EmitDeclareReductionInit ? ClausesData[N].ReductionOp
973 : PrivateVD->getInit(),
Akira Hatanakaf139ae32019-12-03 15:17:01 -0800974 DRD, SharedLVal.getAddress(CGF));
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000975}
976
977ReductionCodeGen::ReductionCodeGen(ArrayRef<const Expr *> Shareds,
978 ArrayRef<const Expr *> Privates,
979 ArrayRef<const Expr *> ReductionOps) {
980 ClausesData.reserve(Shareds.size());
981 SharedAddresses.reserve(Shareds.size());
982 Sizes.reserve(Shareds.size());
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000983 BaseDecls.reserve(Shareds.size());
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000984 auto IPriv = Privates.begin();
985 auto IRed = ReductionOps.begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000986 for (const Expr *Ref : Shareds) {
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000987 ClausesData.emplace_back(Ref, *IPriv, *IRed);
988 std::advance(IPriv, 1);
989 std::advance(IRed, 1);
990 }
991}
992
993void ReductionCodeGen::emitSharedLValue(CodeGenFunction &CGF, unsigned N) {
994 assert(SharedAddresses.size() == N &&
995 "Number of generated lvalues must be exactly N.");
Jonas Hahnfeld4525c822017-10-23 19:01:35 +0000996 LValue First = emitSharedLValue(CGF, ClausesData[N].Ref);
997 LValue Second = emitSharedLValueUB(CGF, ClausesData[N].Ref);
998 SharedAddresses.emplace_back(First, Second);
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000999}
1000
1001void ReductionCodeGen::emitAggregateType(CodeGenFunction &CGF, unsigned N) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001002 const auto *PrivateVD =
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001003 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
1004 QualType PrivateType = PrivateVD->getType();
1005 bool AsArraySection = isa<OMPArraySectionExpr>(ClausesData[N].Ref);
Jonas Hahnfeld4525c822017-10-23 19:01:35 +00001006 if (!PrivateType->isVariablyModifiedType()) {
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001007 Sizes.emplace_back(
1008 CGF.getTypeSize(
1009 SharedAddresses[N].first.getType().getNonReferenceType()),
1010 nullptr);
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001011 return;
1012 }
1013 llvm::Value *Size;
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001014 llvm::Value *SizeInChars;
Akira Hatanakaf139ae32019-12-03 15:17:01 -08001015 auto *ElemType = cast<llvm::PointerType>(
1016 SharedAddresses[N].first.getPointer(CGF)->getType())
1017 ->getElementType();
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001018 auto *ElemSizeOf = llvm::ConstantExpr::getSizeOf(ElemType);
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001019 if (AsArraySection) {
Akira Hatanakaf139ae32019-12-03 15:17:01 -08001020 Size = CGF.Builder.CreatePtrDiff(SharedAddresses[N].second.getPointer(CGF),
1021 SharedAddresses[N].first.getPointer(CGF));
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001022 Size = CGF.Builder.CreateNUWAdd(
1023 Size, llvm::ConstantInt::get(Size->getType(), /*V=*/1));
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001024 SizeInChars = CGF.Builder.CreateNUWMul(Size, ElemSizeOf);
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001025 } else {
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001026 SizeInChars = CGF.getTypeSize(
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001027 SharedAddresses[N].first.getType().getNonReferenceType());
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001028 Size = CGF.Builder.CreateExactUDiv(SizeInChars, ElemSizeOf);
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001029 }
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001030 Sizes.emplace_back(SizeInChars, Size);
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001031 CodeGenFunction::OpaqueValueMapping OpaqueMap(
1032 CGF,
1033 cast<OpaqueValueExpr>(
1034 CGF.getContext().getAsVariableArrayType(PrivateType)->getSizeExpr()),
1035 RValue::get(Size));
1036 CGF.EmitVariablyModifiedType(PrivateType);
1037}
1038
1039void ReductionCodeGen::emitAggregateType(CodeGenFunction &CGF, unsigned N,
1040 llvm::Value *Size) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001041 const auto *PrivateVD =
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001042 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
1043 QualType PrivateType = PrivateVD->getType();
Jonas Hahnfeld4525c822017-10-23 19:01:35 +00001044 if (!PrivateType->isVariablyModifiedType()) {
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001045 assert(!Size && !Sizes[N].second &&
Jonas Hahnfeld4525c822017-10-23 19:01:35 +00001046 "Size should be nullptr for non-variably modified reduction "
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001047 "items.");
1048 return;
1049 }
1050 CodeGenFunction::OpaqueValueMapping OpaqueMap(
1051 CGF,
1052 cast<OpaqueValueExpr>(
1053 CGF.getContext().getAsVariableArrayType(PrivateType)->getSizeExpr()),
1054 RValue::get(Size));
1055 CGF.EmitVariablyModifiedType(PrivateType);
1056}
1057
1058void ReductionCodeGen::emitInitialization(
1059 CodeGenFunction &CGF, unsigned N, Address PrivateAddr, LValue SharedLVal,
1060 llvm::function_ref<bool(CodeGenFunction &)> DefaultInit) {
1061 assert(SharedAddresses.size() > N && "No variable was generated");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001062 const auto *PrivateVD =
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001063 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001064 const OMPDeclareReductionDecl *DRD =
1065 getReductionInit(ClausesData[N].ReductionOp);
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001066 QualType PrivateType = PrivateVD->getType();
1067 PrivateAddr = CGF.Builder.CreateElementBitCast(
1068 PrivateAddr, CGF.ConvertTypeForMem(PrivateType));
1069 QualType SharedType = SharedAddresses[N].first.getType();
1070 SharedLVal = CGF.MakeAddrLValue(
Akira Hatanakaf139ae32019-12-03 15:17:01 -08001071 CGF.Builder.CreateElementBitCast(SharedLVal.getAddress(CGF),
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001072 CGF.ConvertTypeForMem(SharedType)),
Ivan A. Kosarevf5f20462017-10-12 11:29:46 +00001073 SharedType, SharedAddresses[N].first.getBaseInfo(),
Ivan A. Kosarevb9c59f32017-10-31 11:05:34 +00001074 CGF.CGM.getTBAAInfoForSubobject(SharedAddresses[N].first, SharedType));
Jonas Hahnfeld4525c822017-10-23 19:01:35 +00001075 if (CGF.getContext().getAsArrayType(PrivateVD->getType())) {
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001076 emitAggregateInitialization(CGF, N, PrivateAddr, SharedLVal, DRD);
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001077 } else if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) {
1078 emitInitWithReductionInitializer(CGF, DRD, ClausesData[N].ReductionOp,
Akira Hatanakaf139ae32019-12-03 15:17:01 -08001079 PrivateAddr, SharedLVal.getAddress(CGF),
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001080 SharedLVal.getType());
1081 } else if (!DefaultInit(CGF) && PrivateVD->hasInit() &&
1082 !CGF.isTrivialInitializer(PrivateVD->getInit())) {
1083 CGF.EmitAnyExprToMem(PrivateVD->getInit(), PrivateAddr,
1084 PrivateVD->getType().getQualifiers(),
1085 /*IsInitializer=*/false);
1086 }
1087}
1088
1089bool ReductionCodeGen::needCleanups(unsigned N) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001090 const auto *PrivateVD =
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001091 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
1092 QualType PrivateType = PrivateVD->getType();
1093 QualType::DestructionKind DTorKind = PrivateType.isDestructedType();
1094 return DTorKind != QualType::DK_none;
1095}
1096
1097void ReductionCodeGen::emitCleanups(CodeGenFunction &CGF, unsigned N,
1098 Address PrivateAddr) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001099 const auto *PrivateVD =
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001100 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
1101 QualType PrivateType = PrivateVD->getType();
1102 QualType::DestructionKind DTorKind = PrivateType.isDestructedType();
1103 if (needCleanups(N)) {
1104 PrivateAddr = CGF.Builder.CreateElementBitCast(
1105 PrivateAddr, CGF.ConvertTypeForMem(PrivateType));
1106 CGF.pushDestroy(DTorKind, PrivateAddr, PrivateType);
1107 }
1108}
1109
1110static LValue loadToBegin(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,
1111 LValue BaseLV) {
1112 BaseTy = BaseTy.getNonReferenceType();
1113 while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&
1114 !CGF.getContext().hasSameType(BaseTy, ElTy)) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001115 if (const auto *PtrTy = BaseTy->getAs<PointerType>()) {
Akira Hatanakaf139ae32019-12-03 15:17:01 -08001116 BaseLV = CGF.EmitLoadOfPointerLValue(BaseLV.getAddress(CGF), PtrTy);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001117 } else {
Akira Hatanakaf139ae32019-12-03 15:17:01 -08001118 LValue RefLVal = CGF.MakeAddrLValue(BaseLV.getAddress(CGF), BaseTy);
Ivan A. Kosarev9f9d1572017-10-30 11:49:31 +00001119 BaseLV = CGF.EmitLoadOfReferenceLValue(RefLVal);
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001120 }
1121 BaseTy = BaseTy->getPointeeType();
1122 }
1123 return CGF.MakeAddrLValue(
Akira Hatanakaf139ae32019-12-03 15:17:01 -08001124 CGF.Builder.CreateElementBitCast(BaseLV.getAddress(CGF),
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001125 CGF.ConvertTypeForMem(ElTy)),
Ivan A. Kosarevf5f20462017-10-12 11:29:46 +00001126 BaseLV.getType(), BaseLV.getBaseInfo(),
Ivan A. Kosarevb9c59f32017-10-31 11:05:34 +00001127 CGF.CGM.getTBAAInfoForSubobject(BaseLV, BaseLV.getType()));
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001128}
1129
1130static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,
1131 llvm::Type *BaseLVType, CharUnits BaseLVAlignment,
1132 llvm::Value *Addr) {
1133 Address Tmp = Address::invalid();
1134 Address TopTmp = Address::invalid();
1135 Address MostTopTmp = Address::invalid();
1136 BaseTy = BaseTy.getNonReferenceType();
1137 while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&
1138 !CGF.getContext().hasSameType(BaseTy, ElTy)) {
1139 Tmp = CGF.CreateMemTemp(BaseTy);
1140 if (TopTmp.isValid())
1141 CGF.Builder.CreateStore(Tmp.getPointer(), TopTmp);
1142 else
1143 MostTopTmp = Tmp;
1144 TopTmp = Tmp;
1145 BaseTy = BaseTy->getPointeeType();
1146 }
1147 llvm::Type *Ty = BaseLVType;
1148 if (Tmp.isValid())
1149 Ty = Tmp.getElementType();
1150 Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Addr, Ty);
1151 if (Tmp.isValid()) {
1152 CGF.Builder.CreateStore(Addr, Tmp);
1153 return MostTopTmp;
1154 }
1155 return Address(Addr, BaseLVAlignment);
1156}
1157
Alexey Bataev1c44e152018-03-06 18:59:43 +00001158static const VarDecl *getBaseDecl(const Expr *Ref, const DeclRefExpr *&DE) {
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001159 const VarDecl *OrigVD = nullptr;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001160 if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(Ref)) {
1161 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
1162 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001163 Base = TempOASE->getBase()->IgnoreParenImpCasts();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001164 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001165 Base = TempASE->getBase()->IgnoreParenImpCasts();
1166 DE = cast<DeclRefExpr>(Base);
1167 OrigVD = cast<VarDecl>(DE->getDecl());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001168 } else if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(Ref)) {
1169 const Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
1170 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001171 Base = TempASE->getBase()->IgnoreParenImpCasts();
1172 DE = cast<DeclRefExpr>(Base);
1173 OrigVD = cast<VarDecl>(DE->getDecl());
1174 }
Alexey Bataev1c44e152018-03-06 18:59:43 +00001175 return OrigVD;
1176}
1177
1178Address ReductionCodeGen::adjustPrivateAddress(CodeGenFunction &CGF, unsigned N,
1179 Address PrivateAddr) {
1180 const DeclRefExpr *DE;
1181 if (const VarDecl *OrigVD = ::getBaseDecl(ClausesData[N].Ref, DE)) {
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001182 BaseDecls.emplace_back(OrigVD);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001183 LValue OriginalBaseLValue = CGF.EmitLValue(DE);
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001184 LValue BaseLValue =
1185 loadToBegin(CGF, OrigVD->getType(), SharedAddresses[N].first.getType(),
1186 OriginalBaseLValue);
1187 llvm::Value *Adjustment = CGF.Builder.CreatePtrDiff(
Akira Hatanakaf139ae32019-12-03 15:17:01 -08001188 BaseLValue.getPointer(CGF), SharedAddresses[N].first.getPointer(CGF));
Jonas Hahnfeld273d2612017-12-06 19:15:28 +00001189 llvm::Value *PrivatePointer =
1190 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
1191 PrivateAddr.getPointer(),
Akira Hatanakaf139ae32019-12-03 15:17:01 -08001192 SharedAddresses[N].first.getAddress(CGF).getType());
Jonas Hahnfeld273d2612017-12-06 19:15:28 +00001193 llvm::Value *Ptr = CGF.Builder.CreateGEP(PrivatePointer, Adjustment);
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001194 return castToBase(CGF, OrigVD->getType(),
1195 SharedAddresses[N].first.getType(),
Akira Hatanakaf139ae32019-12-03 15:17:01 -08001196 OriginalBaseLValue.getAddress(CGF).getType(),
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001197 OriginalBaseLValue.getAlignment(), Ptr);
1198 }
1199 BaseDecls.emplace_back(
1200 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Ref)->getDecl()));
1201 return PrivateAddr;
1202}
1203
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001204bool ReductionCodeGen::usesReductionInitializer(unsigned N) const {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001205 const OMPDeclareReductionDecl *DRD =
1206 getReductionInit(ClausesData[N].ReductionOp);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001207 return DRD && DRD->getInitializer();
1208}
1209
Alexey Bataev18095712014-10-10 12:19:54 +00001210LValue CGOpenMPRegionInfo::getThreadIDVariableLValue(CodeGenFunction &CGF) {
Alexey Bataev31300ed2016-02-04 11:27:03 +00001211 return CGF.EmitLoadOfPointerLValue(
1212 CGF.GetAddrOfLocalVar(getThreadIDVariable()),
1213 getThreadIDVariable()->getType()->castAs<PointerType>());
Alexey Bataev18095712014-10-10 12:19:54 +00001214}
1215
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001216void CGOpenMPRegionInfo::EmitBody(CodeGenFunction &CGF, const Stmt * /*S*/) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001217 if (!CGF.HaveInsertPoint())
1218 return;
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001219 // 1.2.2 OpenMP Language Terminology
1220 // Structured block - An executable statement with a single entry at the
1221 // top and a single exit at the bottom.
1222 // The point of exit cannot be a branch out of the structured block.
1223 // longjmp() and throw() must not violate the entry/exit criteria.
1224 CGF.EHStack.pushTerminate();
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001225 CodeGen(CGF);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001226 CGF.EHStack.popTerminate();
Alexey Bataev4a5bb772014-10-08 14:01:46 +00001227}
1228
Alexey Bataev62b63b12015-03-10 07:28:44 +00001229LValue CGOpenMPTaskOutlinedRegionInfo::getThreadIDVariableLValue(
1230 CodeGenFunction &CGF) {
Alexey Bataev2377fe92015-09-10 08:12:02 +00001231 return CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(getThreadIDVariable()),
1232 getThreadIDVariable()->getType(),
Ivan A. Kosarev5f8c0ca2017-10-10 09:39:32 +00001233 AlignmentSource::Decl);
Alexey Bataev62b63b12015-03-10 07:28:44 +00001234}
1235
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001236static FieldDecl *addFieldToRecordDecl(ASTContext &C, DeclContext *DC,
1237 QualType FieldTy) {
1238 auto *Field = FieldDecl::Create(
1239 C, DC, SourceLocation(), SourceLocation(), /*Id=*/nullptr, FieldTy,
1240 C.getTrivialTypeSourceInfo(FieldTy, SourceLocation()),
1241 /*BW=*/nullptr, /*Mutable=*/false, /*InitStyle=*/ICIS_NoInit);
1242 Field->setAccess(AS_public);
1243 DC->addDecl(Field);
1244 return Field;
1245}
1246
Alexey Bataev18fa2322018-05-02 14:20:50 +00001247CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM, StringRef FirstSeparator,
1248 StringRef Separator)
1249 : CGM(CGM), FirstSeparator(FirstSeparator), Separator(Separator),
1250 OffloadEntriesInfoManager(CGM) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001251 ASTContext &C = CGM.getContext();
1252 RecordDecl *RD = C.buildImplicitRecord("ident_t");
1253 QualType KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
1254 RD->startDefinition();
1255 // reserved_1
1256 addFieldToRecordDecl(C, RD, KmpInt32Ty);
1257 // flags
1258 addFieldToRecordDecl(C, RD, KmpInt32Ty);
1259 // reserved_2
1260 addFieldToRecordDecl(C, RD, KmpInt32Ty);
1261 // reserved_3
1262 addFieldToRecordDecl(C, RD, KmpInt32Ty);
1263 // psource
1264 addFieldToRecordDecl(C, RD, C.VoidPtrTy);
1265 RD->completeDefinition();
1266 IdentQTy = C.getRecordType(RD);
1267 IdentTy = CGM.getTypes().ConvertRecordDeclType(RD);
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00001268 KmpCriticalNameTy = llvm::ArrayType::get(CGM.Int32Ty, /*NumElements*/ 8);
Samuel Antaoee8fb302016-01-06 13:42:12 +00001269
1270 loadOffloadInfoMetadata();
Alexey Bataev9959db52014-05-06 10:08:46 +00001271}
1272
Alexey Bataevc2cd2d42019-10-10 17:28:10 +00001273bool CGOpenMPRuntime::tryEmitDeclareVariant(const GlobalDecl &NewGD,
1274 const GlobalDecl &OldGD,
1275 llvm::GlobalValue *OrigAddr,
1276 bool IsForDefinition) {
Alexey Bataev2df5f122019-10-01 20:18:32 +00001277 // Emit at least a definition for the aliasee if the the address of the
1278 // original function is requested.
1279 if (IsForDefinition || OrigAddr)
1280 (void)CGM.GetAddrOfGlobal(NewGD);
1281 StringRef NewMangledName = CGM.getMangledName(NewGD);
1282 llvm::GlobalValue *Addr = CGM.GetGlobalValue(NewMangledName);
1283 if (Addr && !Addr->isDeclaration()) {
1284 const auto *D = cast<FunctionDecl>(OldGD.getDecl());
Alexey Bataev5ad52582019-12-12 15:33:18 -05001285 const CGFunctionInfo &FI = CGM.getTypes().arrangeGlobalDeclaration(NewGD);
Alexey Bataev2df5f122019-10-01 20:18:32 +00001286 llvm::Type *DeclTy = CGM.getTypes().GetFunctionType(FI);
1287
1288 // Create a reference to the named value. This ensures that it is emitted
1289 // if a deferred decl.
1290 llvm::GlobalValue::LinkageTypes LT = CGM.getFunctionLinkage(OldGD);
1291
1292 // Create the new alias itself, but don't set a name yet.
1293 auto *GA =
1294 llvm::GlobalAlias::create(DeclTy, 0, LT, "", Addr, &CGM.getModule());
1295
1296 if (OrigAddr) {
1297 assert(OrigAddr->isDeclaration() && "Expected declaration");
1298
1299 GA->takeName(OrigAddr);
1300 OrigAddr->replaceAllUsesWith(
1301 llvm::ConstantExpr::getBitCast(GA, OrigAddr->getType()));
1302 OrigAddr->eraseFromParent();
1303 } else {
1304 GA->setName(CGM.getMangledName(OldGD));
1305 }
1306
1307 // Set attributes which are particular to an alias; this is a
1308 // specialization of the attributes which may be set on a global function.
1309 if (D->hasAttr<WeakAttr>() || D->hasAttr<WeakRefAttr>() ||
1310 D->isWeakImported())
1311 GA->setLinkage(llvm::Function::WeakAnyLinkage);
1312
1313 CGM.SetCommonAttributes(OldGD, GA);
1314 return true;
1315 }
1316 return false;
1317}
1318
Alexey Bataev91797552015-03-18 04:13:55 +00001319void CGOpenMPRuntime::clear() {
1320 InternalVars.clear();
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00001321 // Clean non-target variable declarations possibly used only in debug info.
1322 for (const auto &Data : EmittedNonTargetVariables) {
1323 if (!Data.getValue().pointsToAliveValue())
1324 continue;
1325 auto *GV = dyn_cast<llvm::GlobalVariable>(Data.getValue());
1326 if (!GV)
1327 continue;
1328 if (!GV->isDeclaration() || GV->getNumUses() > 0)
1329 continue;
1330 GV->eraseFromParent();
1331 }
Alexey Bataev2df5f122019-10-01 20:18:32 +00001332 // Emit aliases for the deferred aliasees.
1333 for (const auto &Pair : DeferredVariantFunction) {
1334 StringRef MangledName = CGM.getMangledName(Pair.second.second);
1335 llvm::GlobalValue *Addr = CGM.GetGlobalValue(MangledName);
1336 // If not able to emit alias, just emit original declaration.
Alexey Bataevc2cd2d42019-10-10 17:28:10 +00001337 (void)tryEmitDeclareVariant(Pair.second.first, Pair.second.second, Addr,
1338 /*IsForDefinition=*/false);
Alexey Bataev2df5f122019-10-01 20:18:32 +00001339 }
Alexey Bataev91797552015-03-18 04:13:55 +00001340}
1341
Alexey Bataev18fa2322018-05-02 14:20:50 +00001342std::string CGOpenMPRuntime::getName(ArrayRef<StringRef> Parts) const {
1343 SmallString<128> Buffer;
1344 llvm::raw_svector_ostream OS(Buffer);
1345 StringRef Sep = FirstSeparator;
1346 for (StringRef Part : Parts) {
1347 OS << Sep << Part;
1348 Sep = Separator;
1349 }
Benjamin Krameradcd0262020-01-28 20:23:46 +01001350 return std::string(OS.str());
Alexey Bataev18fa2322018-05-02 14:20:50 +00001351}
1352
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001353static llvm::Function *
1354emitCombinerOrInitializer(CodeGenModule &CGM, QualType Ty,
1355 const Expr *CombinerInitializer, const VarDecl *In,
1356 const VarDecl *Out, bool IsCombiner) {
1357 // void .omp_combiner.(Ty *in, Ty *out);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001358 ASTContext &C = CGM.getContext();
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001359 QualType PtrTy = C.getPointerType(Ty).withRestrict();
1360 FunctionArgList Args;
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001361 ImplicitParamDecl OmpOutParm(C, /*DC=*/nullptr, Out->getLocation(),
Alexey Bataev56223232017-06-09 13:40:18 +00001362 /*Id=*/nullptr, PtrTy, ImplicitParamDecl::Other);
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001363 ImplicitParamDecl OmpInParm(C, /*DC=*/nullptr, In->getLocation(),
Alexey Bataev56223232017-06-09 13:40:18 +00001364 /*Id=*/nullptr, PtrTy, ImplicitParamDecl::Other);
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001365 Args.push_back(&OmpOutParm);
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001366 Args.push_back(&OmpInParm);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001367 const CGFunctionInfo &FnInfo =
John McCallc56a8b32016-03-11 04:30:31 +00001368 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001369 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
Alexey Bataev18fa2322018-05-02 14:20:50 +00001370 std::string Name = CGM.getOpenMPRuntime().getName(
1371 {IsCombiner ? "omp_combiner" : "omp_initializer", ""});
1372 auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
1373 Name, &CGM.getModule());
Rafael Espindola51ec5a92018-02-28 23:46:35 +00001374 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo);
Alexey Bataev8c5555c2019-05-21 15:11:58 +00001375 if (CGM.getLangOpts().Optimize) {
1376 Fn->removeFnAttr(llvm::Attribute::NoInline);
1377 Fn->removeFnAttr(llvm::Attribute::OptimizeNone);
1378 Fn->addFnAttr(llvm::Attribute::AlwaysInline);
1379 }
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001380 CodeGenFunction CGF(CGM);
1381 // Map "T omp_in;" variable to "*omp_in_parm" value in all expressions.
1382 // Map "T omp_out;" variable to "*omp_out_parm" value in all expressions.
Alexey Bataev7cae94e2018-01-04 19:45:16 +00001383 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, In->getLocation(),
1384 Out->getLocation());
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001385 CodeGenFunction::OMPPrivateScope Scope(CGF);
1386 Address AddrIn = CGF.GetAddrOfLocalVar(&OmpInParm);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001387 Scope.addPrivate(In, [&CGF, AddrIn, PtrTy]() {
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001388 return CGF.EmitLoadOfPointerLValue(AddrIn, PtrTy->castAs<PointerType>())
Akira Hatanakaf139ae32019-12-03 15:17:01 -08001389 .getAddress(CGF);
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001390 });
1391 Address AddrOut = CGF.GetAddrOfLocalVar(&OmpOutParm);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001392 Scope.addPrivate(Out, [&CGF, AddrOut, PtrTy]() {
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001393 return CGF.EmitLoadOfPointerLValue(AddrOut, PtrTy->castAs<PointerType>())
Akira Hatanakaf139ae32019-12-03 15:17:01 -08001394 .getAddress(CGF);
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001395 });
1396 (void)Scope.Privatize();
Alexey Bataev070f43a2017-09-06 14:49:58 +00001397 if (!IsCombiner && Out->hasInit() &&
1398 !CGF.isTrivialInitializer(Out->getInit())) {
1399 CGF.EmitAnyExprToMem(Out->getInit(), CGF.GetAddrOfLocalVar(Out),
1400 Out->getType().getQualifiers(),
1401 /*IsInitializer=*/true);
1402 }
1403 if (CombinerInitializer)
1404 CGF.EmitIgnoredExpr(CombinerInitializer);
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001405 Scope.ForceCleanup();
1406 CGF.FinishFunction();
1407 return Fn;
1408}
1409
1410void CGOpenMPRuntime::emitUserDefinedReduction(
1411 CodeGenFunction *CGF, const OMPDeclareReductionDecl *D) {
1412 if (UDRMap.count(D) > 0)
1413 return;
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001414 llvm::Function *Combiner = emitCombinerOrInitializer(
Alexey Bataeve6aa4692018-09-13 16:54:05 +00001415 CGM, D->getType(), D->getCombiner(),
1416 cast<VarDecl>(cast<DeclRefExpr>(D->getCombinerIn())->getDecl()),
1417 cast<VarDecl>(cast<DeclRefExpr>(D->getCombinerOut())->getDecl()),
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001418 /*IsCombiner=*/true);
1419 llvm::Function *Initializer = nullptr;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001420 if (const Expr *Init = D->getInitializer()) {
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001421 Initializer = emitCombinerOrInitializer(
Alexey Bataev070f43a2017-09-06 14:49:58 +00001422 CGM, D->getType(),
1423 D->getInitializerKind() == OMPDeclareReductionDecl::CallInit ? Init
1424 : nullptr,
Alexey Bataeve6aa4692018-09-13 16:54:05 +00001425 cast<VarDecl>(cast<DeclRefExpr>(D->getInitOrig())->getDecl()),
1426 cast<VarDecl>(cast<DeclRefExpr>(D->getInitPriv())->getDecl()),
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001427 /*IsCombiner=*/false);
1428 }
Alexey Bataev43a919f2018-04-13 17:48:43 +00001429 UDRMap.try_emplace(D, Combiner, Initializer);
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001430 if (CGF) {
1431 auto &Decls = FunctionUDRMap.FindAndConstruct(CGF->CurFn);
1432 Decls.second.push_back(D);
1433 }
1434}
1435
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001436std::pair<llvm::Function *, llvm::Function *>
1437CGOpenMPRuntime::getUserDefinedReduction(const OMPDeclareReductionDecl *D) {
1438 auto I = UDRMap.find(D);
1439 if (I != UDRMap.end())
1440 return I->second;
1441 emitUserDefinedReduction(/*CGF=*/nullptr, D);
1442 return UDRMap.lookup(D);
1443}
1444
Benjamin Kramerdf186502020-01-14 14:06:12 +01001445namespace {
Johannes Doerfertf9c3c5da2019-12-25 10:33:56 -06001446// Temporary RAII solution to perform a push/pop stack event on the OpenMP IR
1447// Builder if one is present.
1448struct PushAndPopStackRAII {
1449 PushAndPopStackRAII(llvm::OpenMPIRBuilder *OMPBuilder, CodeGenFunction &CGF,
1450 bool HasCancel)
1451 : OMPBuilder(OMPBuilder) {
1452 if (!OMPBuilder)
1453 return;
1454
1455 // The following callback is the crucial part of clangs cleanup process.
1456 //
1457 // NOTE:
1458 // Once the OpenMPIRBuilder is used to create parallel regions (and
1459 // similar), the cancellation destination (Dest below) is determined via
1460 // IP. That means if we have variables to finalize we split the block at IP,
1461 // use the new block (=BB) as destination to build a JumpDest (via
1462 // getJumpDestInCurrentScope(BB)) which then is fed to
1463 // EmitBranchThroughCleanup. Furthermore, there will not be the need
1464 // to push & pop an FinalizationInfo object.
1465 // The FiniCB will still be needed but at the point where the
1466 // OpenMPIRBuilder is asked to construct a parallel (or similar) construct.
1467 auto FiniCB = [&CGF](llvm::OpenMPIRBuilder::InsertPointTy IP) {
1468 assert(IP.getBlock()->end() == IP.getPoint() &&
1469 "Clang CG should cause non-terminated block!");
1470 CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
1471 CGF.Builder.restoreIP(IP);
1472 CodeGenFunction::JumpDest Dest =
1473 CGF.getOMPCancelDestination(OMPD_parallel);
1474 CGF.EmitBranchThroughCleanup(Dest);
1475 };
1476
1477 // TODO: Remove this once we emit parallel regions through the
1478 // OpenMPIRBuilder as it can do this setup internally.
1479 llvm::OpenMPIRBuilder::FinalizationInfo FI(
1480 {FiniCB, OMPD_parallel, HasCancel});
1481 OMPBuilder->pushFinalizationCB(std::move(FI));
1482 }
1483 ~PushAndPopStackRAII() {
1484 if (OMPBuilder)
1485 OMPBuilder->popFinalizationCB();
1486 }
1487 llvm::OpenMPIRBuilder *OMPBuilder;
1488};
Benjamin Kramerdf186502020-01-14 14:06:12 +01001489} // namespace
Johannes Doerfertf9c3c5da2019-12-25 10:33:56 -06001490
James Y Knight9871db02019-02-05 16:42:33 +00001491static llvm::Function *emitParallelOrTeamsOutlinedFunction(
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00001492 CodeGenModule &CGM, const OMPExecutableDirective &D, const CapturedStmt *CS,
1493 const VarDecl *ThreadIDVar, OpenMPDirectiveKind InnermostKind,
1494 const StringRef OutlinedHelperName, const RegionCodeGenTy &CodeGen) {
Alexey Bataev62b63b12015-03-10 07:28:44 +00001495 assert(ThreadIDVar->getType()->isPointerType() &&
1496 "thread id variable must be of type kmp_int32 *");
Alexey Bataev18095712014-10-10 12:19:54 +00001497 CodeGenFunction CGF(CGM, true);
Alexey Bataev25e5b442015-09-15 12:52:43 +00001498 bool HasCancel = false;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001499 if (const auto *OPD = dyn_cast<OMPParallelDirective>(&D))
Alexey Bataev25e5b442015-09-15 12:52:43 +00001500 HasCancel = OPD->hasCancel();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001501 else if (const auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&D))
Alexey Bataev25e5b442015-09-15 12:52:43 +00001502 HasCancel = OPSD->hasCancel();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001503 else if (const auto *OPFD = dyn_cast<OMPParallelForDirective>(&D))
Alexey Bataev25e5b442015-09-15 12:52:43 +00001504 HasCancel = OPFD->hasCancel();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001505 else if (const auto *OPFD = dyn_cast<OMPTargetParallelForDirective>(&D))
Alexey Bataev2139ed62017-11-16 18:20:21 +00001506 HasCancel = OPFD->hasCancel();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001507 else if (const auto *OPFD = dyn_cast<OMPDistributeParallelForDirective>(&D))
Alexey Bataev10a54312017-11-27 16:54:08 +00001508 HasCancel = OPFD->hasCancel();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001509 else if (const auto *OPFD =
1510 dyn_cast<OMPTeamsDistributeParallelForDirective>(&D))
Alexey Bataev10a54312017-11-27 16:54:08 +00001511 HasCancel = OPFD->hasCancel();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001512 else if (const auto *OPFD =
Alexey Bataev10a54312017-11-27 16:54:08 +00001513 dyn_cast<OMPTargetTeamsDistributeParallelForDirective>(&D))
1514 HasCancel = OPFD->hasCancel();
Johannes Doerfertf9c3c5da2019-12-25 10:33:56 -06001515
1516 // TODO: Temporarily inform the OpenMPIRBuilder, if any, about the new
1517 // parallel region to make cancellation barriers work properly.
1518 llvm::OpenMPIRBuilder *OMPBuilder = CGM.getOpenMPIRBuilder();
1519 PushAndPopStackRAII PSR(OMPBuilder, CGF, HasCancel);
Alexey Bataev25e5b442015-09-15 12:52:43 +00001520 CGOpenMPOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen, InnermostKind,
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00001521 HasCancel, OutlinedHelperName);
Alexey Bataevd157d472015-06-24 03:35:38 +00001522 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
Alexey Bataevc33ba8c2020-01-17 14:05:40 -05001523 return CGF.GenerateOpenMPCapturedStmtFunction(*CS, D.getBeginLoc());
Alexey Bataev18095712014-10-10 12:19:54 +00001524}
1525
James Y Knight9871db02019-02-05 16:42:33 +00001526llvm::Function *CGOpenMPRuntime::emitParallelOutlinedFunction(
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00001527 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
1528 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
1529 const CapturedStmt *CS = D.getCapturedStmt(OMPD_parallel);
1530 return emitParallelOrTeamsOutlinedFunction(
1531 CGM, D, CS, ThreadIDVar, InnermostKind, getOutlinedHelperName(), CodeGen);
1532}
1533
James Y Knight9871db02019-02-05 16:42:33 +00001534llvm::Function *CGOpenMPRuntime::emitTeamsOutlinedFunction(
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00001535 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
1536 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
1537 const CapturedStmt *CS = D.getCapturedStmt(OMPD_teams);
1538 return emitParallelOrTeamsOutlinedFunction(
1539 CGM, D, CS, ThreadIDVar, InnermostKind, getOutlinedHelperName(), CodeGen);
1540}
1541
James Y Knight9871db02019-02-05 16:42:33 +00001542llvm::Function *CGOpenMPRuntime::emitTaskOutlinedFunction(
Alexey Bataev81c7ea02015-07-03 09:56:58 +00001543 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
Alexey Bataev48591dd2016-04-20 04:01:36 +00001544 const VarDecl *PartIDVar, const VarDecl *TaskTVar,
1545 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
1546 bool Tied, unsigned &NumberOfParts) {
1547 auto &&UntiedCodeGen = [this, &D, TaskTVar](CodeGenFunction &CGF,
1548 PrePostActionTy &) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001549 llvm::Value *ThreadID = getThreadID(CGF, D.getBeginLoc());
1550 llvm::Value *UpLoc = emitUpdateLocation(CGF, D.getBeginLoc());
Alexey Bataev48591dd2016-04-20 04:01:36 +00001551 llvm::Value *TaskArgs[] = {
1552 UpLoc, ThreadID,
1553 CGF.EmitLoadOfPointerLValue(CGF.GetAddrOfLocalVar(TaskTVar),
1554 TaskTVar->getType()->castAs<PointerType>())
Akira Hatanakaf139ae32019-12-03 15:17:01 -08001555 .getPointer(CGF)};
Alexey Bataev48591dd2016-04-20 04:01:36 +00001556 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_task), TaskArgs);
1557 };
1558 CGOpenMPTaskOutlinedRegionInfo::UntiedTaskActionTy Action(Tied, PartIDVar,
1559 UntiedCodeGen);
1560 CodeGen.setAction(Action);
Alexey Bataev62b63b12015-03-10 07:28:44 +00001561 assert(!ThreadIDVar->getType()->isPointerType() &&
1562 "thread id variable must be of type kmp_int32 for tasks");
Alexey Bataev475a7442018-01-12 19:39:11 +00001563 const OpenMPDirectiveKind Region =
1564 isOpenMPTaskLoopDirective(D.getDirectiveKind()) ? OMPD_taskloop
1565 : OMPD_task;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001566 const CapturedStmt *CS = D.getCapturedStmt(Region);
Alexey Bataeve0ca4792020-02-12 16:12:53 -05001567 bool HasCancel = false;
1568 if (const auto *TD = dyn_cast<OMPTaskDirective>(&D))
1569 HasCancel = TD->hasCancel();
1570 else if (const auto *TD = dyn_cast<OMPTaskLoopDirective>(&D))
1571 HasCancel = TD->hasCancel();
1572 else if (const auto *TD = dyn_cast<OMPMasterTaskLoopDirective>(&D))
1573 HasCancel = TD->hasCancel();
1574 else if (const auto *TD = dyn_cast<OMPParallelMasterTaskLoopDirective>(&D))
1575 HasCancel = TD->hasCancel();
1576
Alexey Bataev62b63b12015-03-10 07:28:44 +00001577 CodeGenFunction CGF(CGM, true);
Alexey Bataev7292c292016-04-25 12:22:29 +00001578 CGOpenMPTaskOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen,
Alexey Bataeve0ca4792020-02-12 16:12:53 -05001579 InnermostKind, HasCancel, Action);
Alexey Bataevd157d472015-06-24 03:35:38 +00001580 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
James Y Knight9871db02019-02-05 16:42:33 +00001581 llvm::Function *Res = CGF.GenerateCapturedStmtFunction(*CS);
Alexey Bataev48591dd2016-04-20 04:01:36 +00001582 if (!Tied)
1583 NumberOfParts = Action.getNumberOfParts();
1584 return Res;
Alexey Bataev62b63b12015-03-10 07:28:44 +00001585}
1586
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001587static void buildStructValue(ConstantStructBuilder &Fields, CodeGenModule &CGM,
1588 const RecordDecl *RD, const CGRecordLayout &RL,
1589 ArrayRef<llvm::Constant *> Data) {
1590 llvm::StructType *StructTy = RL.getLLVMType();
1591 unsigned PrevIdx = 0;
1592 ConstantInitBuilder CIBuilder(CGM);
1593 auto DI = Data.begin();
1594 for (const FieldDecl *FD : RD->fields()) {
1595 unsigned Idx = RL.getLLVMFieldNo(FD);
1596 // Fill the alignment.
1597 for (unsigned I = PrevIdx; I < Idx; ++I)
1598 Fields.add(llvm::Constant::getNullValue(StructTy->getElementType(I)));
1599 PrevIdx = Idx + 1;
1600 Fields.add(*DI);
1601 ++DI;
1602 }
1603}
1604
1605template <class... As>
1606static llvm::GlobalVariable *
Mike Ricee1ca7b62018-08-29 15:45:11 +00001607createGlobalStruct(CodeGenModule &CGM, QualType Ty, bool IsConstant,
1608 ArrayRef<llvm::Constant *> Data, const Twine &Name,
1609 As &&... Args) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001610 const auto *RD = cast<RecordDecl>(Ty->getAsTagDecl());
1611 const CGRecordLayout &RL = CGM.getTypes().getCGRecordLayout(RD);
1612 ConstantInitBuilder CIBuilder(CGM);
1613 ConstantStructBuilder Fields = CIBuilder.beginStruct(RL.getLLVMType());
1614 buildStructValue(Fields, CGM, RD, RL, Data);
1615 return Fields.finishAndCreateGlobal(
Mike Ricee1ca7b62018-08-29 15:45:11 +00001616 Name, CGM.getContext().getAlignOfGlobalVarInChars(Ty), IsConstant,
1617 std::forward<As>(Args)...);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001618}
1619
1620template <typename T>
Benjamin Kramer651d0bf2018-05-15 21:26:47 +00001621static void
1622createConstantGlobalStructAndAddToParent(CodeGenModule &CGM, QualType Ty,
1623 ArrayRef<llvm::Constant *> Data,
1624 T &Parent) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001625 const auto *RD = cast<RecordDecl>(Ty->getAsTagDecl());
1626 const CGRecordLayout &RL = CGM.getTypes().getCGRecordLayout(RD);
1627 ConstantStructBuilder Fields = Parent.beginStruct(RL.getLLVMType());
1628 buildStructValue(Fields, CGM, RD, RL, Data);
1629 Fields.finishAndAddTo(Parent);
1630}
1631
Alexey Bataev50b3c952016-02-19 10:38:26 +00001632Address CGOpenMPRuntime::getOrCreateDefaultLocation(unsigned Flags) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001633 CharUnits Align = CGM.getContext().getTypeAlignInChars(IdentQTy);
Alexey Bataevceeaa482018-11-21 21:04:34 +00001634 unsigned Reserved2Flags = getDefaultLocationReserved2Flags();
1635 FlagsTy FlagsKey(Flags, Reserved2Flags);
1636 llvm::Value *Entry = OpenMPDefaultLocMap.lookup(FlagsKey);
Alexey Bataev9959db52014-05-06 10:08:46 +00001637 if (!Entry) {
1638 if (!DefaultOpenMPPSource) {
1639 // Initialize default location for psource field of ident_t structure of
1640 // all ident_t objects. Format is ";file;function;line;column;;".
1641 // Taken from
James Y Knight5d71fc52019-01-29 16:37:27 +00001642 // https://github.com/llvm/llvm-project/blob/master/openmp/runtime/src/kmp_str.cpp
Alexey Bataev9959db52014-05-06 10:08:46 +00001643 DefaultOpenMPPSource =
John McCall7f416cc2015-09-08 08:05:57 +00001644 CGM.GetAddrOfConstantCString(";unknown;unknown;0;0;;").getPointer();
Alexey Bataev9959db52014-05-06 10:08:46 +00001645 DefaultOpenMPPSource =
1646 llvm::ConstantExpr::getBitCast(DefaultOpenMPPSource, CGM.Int8PtrTy);
1647 }
Alexey Bataev9959db52014-05-06 10:08:46 +00001648
Alexey Bataevceeaa482018-11-21 21:04:34 +00001649 llvm::Constant *Data[] = {
1650 llvm::ConstantInt::getNullValue(CGM.Int32Ty),
1651 llvm::ConstantInt::get(CGM.Int32Ty, Flags),
1652 llvm::ConstantInt::get(CGM.Int32Ty, Reserved2Flags),
1653 llvm::ConstantInt::getNullValue(CGM.Int32Ty), DefaultOpenMPPSource};
Mike Ricee1ca7b62018-08-29 15:45:11 +00001654 llvm::GlobalValue *DefaultOpenMPLocation =
Alexey Bataevceeaa482018-11-21 21:04:34 +00001655 createGlobalStruct(CGM, IdentQTy, isDefaultLocationConstant(), Data, "",
Mike Ricee1ca7b62018-08-29 15:45:11 +00001656 llvm::GlobalValue::PrivateLinkage);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001657 DefaultOpenMPLocation->setUnnamedAddr(
1658 llvm::GlobalValue::UnnamedAddr::Global);
John McCall6c9f1fdb2016-11-19 08:17:24 +00001659
Alexey Bataevceeaa482018-11-21 21:04:34 +00001660 OpenMPDefaultLocMap[FlagsKey] = Entry = DefaultOpenMPLocation;
Alexey Bataev9959db52014-05-06 10:08:46 +00001661 }
John McCall7f416cc2015-09-08 08:05:57 +00001662 return Address(Entry, Align);
Alexey Bataev9959db52014-05-06 10:08:46 +00001663}
1664
Alexey Bataevfd006c42018-10-05 15:08:53 +00001665void CGOpenMPRuntime::setLocThreadIdInsertPt(CodeGenFunction &CGF,
1666 bool AtCurrentPoint) {
1667 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
1668 assert(!Elem.second.ServiceInsertPt && "Insert point is set already.");
1669
1670 llvm::Value *Undef = llvm::UndefValue::get(CGF.Int32Ty);
1671 if (AtCurrentPoint) {
1672 Elem.second.ServiceInsertPt = new llvm::BitCastInst(
1673 Undef, CGF.Int32Ty, "svcpt", CGF.Builder.GetInsertBlock());
1674 } else {
1675 Elem.second.ServiceInsertPt =
1676 new llvm::BitCastInst(Undef, CGF.Int32Ty, "svcpt");
1677 Elem.second.ServiceInsertPt->insertAfter(CGF.AllocaInsertPt);
1678 }
1679}
1680
1681void CGOpenMPRuntime::clearLocThreadIdInsertPt(CodeGenFunction &CGF) {
1682 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
1683 if (Elem.second.ServiceInsertPt) {
1684 llvm::Instruction *Ptr = Elem.second.ServiceInsertPt;
1685 Elem.second.ServiceInsertPt = nullptr;
1686 Ptr->eraseFromParent();
1687 }
1688}
1689
Alexey Bataev3eff5f42015-02-25 08:32:46 +00001690llvm::Value *CGOpenMPRuntime::emitUpdateLocation(CodeGenFunction &CGF,
1691 SourceLocation Loc,
Alexey Bataev50b3c952016-02-19 10:38:26 +00001692 unsigned Flags) {
1693 Flags |= OMP_IDENT_KMPC;
Alexey Bataev9959db52014-05-06 10:08:46 +00001694 // If no debug info is generated - return global default location.
Benjamin Kramer8c305922016-02-02 11:06:51 +00001695 if (CGM.getCodeGenOpts().getDebugInfo() == codegenoptions::NoDebugInfo ||
Alexey Bataev9959db52014-05-06 10:08:46 +00001696 Loc.isInvalid())
John McCall7f416cc2015-09-08 08:05:57 +00001697 return getOrCreateDefaultLocation(Flags).getPointer();
Alexey Bataev9959db52014-05-06 10:08:46 +00001698
1699 assert(CGF.CurFn && "No function in current CodeGenFunction.");
1700
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001701 CharUnits Align = CGM.getContext().getTypeAlignInChars(IdentQTy);
John McCall7f416cc2015-09-08 08:05:57 +00001702 Address LocValue = Address::invalid();
Alexey Bataev1e4b7132014-12-03 12:11:24 +00001703 auto I = OpenMPLocThreadIDMap.find(CGF.CurFn);
1704 if (I != OpenMPLocThreadIDMap.end())
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001705 LocValue = Address(I->second.DebugLoc, Align);
John McCall7f416cc2015-09-08 08:05:57 +00001706
Alexander Musmanc6388682014-12-15 07:07:06 +00001707 // OpenMPLocThreadIDMap may have null DebugLoc and non-null ThreadID, if
1708 // GetOpenMPThreadID was called before this routine.
John McCall7f416cc2015-09-08 08:05:57 +00001709 if (!LocValue.isValid()) {
Alexey Bataev15007ba2014-05-07 06:18:01 +00001710 // Generate "ident_t .kmpc_loc.addr;"
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001711 Address AI = CGF.CreateMemTemp(IdentQTy, ".kmpc_loc.addr");
Alexey Bataev18095712014-10-10 12:19:54 +00001712 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
John McCall7f416cc2015-09-08 08:05:57 +00001713 Elem.second.DebugLoc = AI.getPointer();
Alexey Bataev9959db52014-05-06 10:08:46 +00001714 LocValue = AI;
1715
Alexey Bataevfd006c42018-10-05 15:08:53 +00001716 if (!Elem.second.ServiceInsertPt)
1717 setLocThreadIdInsertPt(CGF);
Alexey Bataev9959db52014-05-06 10:08:46 +00001718 CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
Alexey Bataevfd006c42018-10-05 15:08:53 +00001719 CGF.Builder.SetInsertPoint(Elem.second.ServiceInsertPt);
Alexey Bataev3eff5f42015-02-25 08:32:46 +00001720 CGF.Builder.CreateMemCpy(LocValue, getOrCreateDefaultLocation(Flags),
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001721 CGF.getTypeSize(IdentQTy));
Alexey Bataev9959db52014-05-06 10:08:46 +00001722 }
1723
1724 // char **psource = &.kmpc_loc_<flags>.addr.psource;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001725 LValue Base = CGF.MakeAddrLValue(LocValue, IdentQTy);
1726 auto Fields = cast<RecordDecl>(IdentQTy->getAsTagDecl())->field_begin();
1727 LValue PSource =
1728 CGF.EmitLValueForField(Base, *std::next(Fields, IdentField_PSource));
Alexey Bataev9959db52014-05-06 10:08:46 +00001729
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001730 llvm::Value *OMPDebugLoc = OpenMPDebugLocMap.lookup(Loc.getRawEncoding());
Alexey Bataevf002aca2014-05-30 05:48:40 +00001731 if (OMPDebugLoc == nullptr) {
1732 SmallString<128> Buffer2;
1733 llvm::raw_svector_ostream OS2(Buffer2);
1734 // Build debug location
1735 PresumedLoc PLoc = CGF.getContext().getSourceManager().getPresumedLoc(Loc);
1736 OS2 << ";" << PLoc.getFilename() << ";";
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001737 if (const auto *FD = dyn_cast_or_null<FunctionDecl>(CGF.CurFuncDecl))
Alexey Bataevf002aca2014-05-30 05:48:40 +00001738 OS2 << FD->getQualifiedNameAsString();
Alexey Bataevf002aca2014-05-30 05:48:40 +00001739 OS2 << ";" << PLoc.getLine() << ";" << PLoc.getColumn() << ";;";
1740 OMPDebugLoc = CGF.Builder.CreateGlobalStringPtr(OS2.str());
1741 OpenMPDebugLocMap[Loc.getRawEncoding()] = OMPDebugLoc;
Alexey Bataev9959db52014-05-06 10:08:46 +00001742 }
Alexey Bataev9959db52014-05-06 10:08:46 +00001743 // *psource = ";<File>;<Function>;<Line>;<Column>;;";
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001744 CGF.EmitStoreOfScalar(OMPDebugLoc, PSource);
Alexey Bataevf002aca2014-05-30 05:48:40 +00001745
John McCall7f416cc2015-09-08 08:05:57 +00001746 // Our callers always pass this to a runtime function, so for
1747 // convenience, go ahead and return a naked pointer.
1748 return LocValue.getPointer();
Alexey Bataev9959db52014-05-06 10:08:46 +00001749}
1750
Alexey Bataev3eff5f42015-02-25 08:32:46 +00001751llvm::Value *CGOpenMPRuntime::getThreadID(CodeGenFunction &CGF,
1752 SourceLocation Loc) {
Alexey Bataev9959db52014-05-06 10:08:46 +00001753 assert(CGF.CurFn && "No function in current CodeGenFunction.");
1754
Alexey Bataev4a5bb772014-10-08 14:01:46 +00001755 llvm::Value *ThreadID = nullptr;
Alexey Bataev18095712014-10-10 12:19:54 +00001756 // Check whether we've already cached a load of the thread id in this
1757 // function.
Alexey Bataev1e4b7132014-12-03 12:11:24 +00001758 auto I = OpenMPLocThreadIDMap.find(CGF.CurFn);
Alexey Bataev18095712014-10-10 12:19:54 +00001759 if (I != OpenMPLocThreadIDMap.end()) {
1760 ThreadID = I->second.ThreadID;
Alexey Bataev03b340a2014-10-21 03:16:40 +00001761 if (ThreadID != nullptr)
1762 return ThreadID;
1763 }
Alexey Bataevaee18552017-08-16 14:01:00 +00001764 // If exceptions are enabled, do not use parameter to avoid possible crash.
Alexey Bataev780f5552019-10-17 17:12:03 +00001765 if (auto *OMPRegionInfo =
1766 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
1767 if (OMPRegionInfo->getThreadIDVariable()) {
1768 // Check if this an outlined function with thread id passed as argument.
1769 LValue LVal = OMPRegionInfo->getThreadIDVariableLValue(CGF);
1770 llvm::BasicBlock *TopBlock = CGF.AllocaInsertPt->getParent();
1771 if (!CGF.EHStack.requiresLandingPad() || !CGF.getLangOpts().Exceptions ||
1772 !CGF.getLangOpts().CXXExceptions ||
1773 CGF.Builder.GetInsertBlock() == TopBlock ||
Akira Hatanakaf139ae32019-12-03 15:17:01 -08001774 !isa<llvm::Instruction>(LVal.getPointer(CGF)) ||
1775 cast<llvm::Instruction>(LVal.getPointer(CGF))->getParent() ==
1776 TopBlock ||
1777 cast<llvm::Instruction>(LVal.getPointer(CGF))->getParent() ==
Alexey Bataev780f5552019-10-17 17:12:03 +00001778 CGF.Builder.GetInsertBlock()) {
Alexey Bataev1e491372018-01-23 18:44:14 +00001779 ThreadID = CGF.EmitLoadOfScalar(LVal, Loc);
Alexey Bataevaee18552017-08-16 14:01:00 +00001780 // If value loaded in entry block, cache it and use it everywhere in
1781 // function.
Alexey Bataev780f5552019-10-17 17:12:03 +00001782 if (CGF.Builder.GetInsertBlock() == TopBlock) {
Alexey Bataevaee18552017-08-16 14:01:00 +00001783 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
1784 Elem.second.ThreadID = ThreadID;
1785 }
1786 return ThreadID;
Alexey Bataev8cbe0a62015-02-26 10:27:34 +00001787 }
Alexey Bataevd6c57552014-07-25 07:55:17 +00001788 }
Alexey Bataev9959db52014-05-06 10:08:46 +00001789 }
Alexey Bataev8cbe0a62015-02-26 10:27:34 +00001790
1791 // This is not an outlined function region - need to call __kmpc_int32
1792 // kmpc_global_thread_num(ident_t *loc).
1793 // Generate thread id value and cache this value for use across the
1794 // function.
Alexey Bataevfd006c42018-10-05 15:08:53 +00001795 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
1796 if (!Elem.second.ServiceInsertPt)
1797 setLocThreadIdInsertPt(CGF);
Alexey Bataev8cbe0a62015-02-26 10:27:34 +00001798 CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
Alexey Bataevfd006c42018-10-05 15:08:53 +00001799 CGF.Builder.SetInsertPoint(Elem.second.ServiceInsertPt);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001800 llvm::CallInst *Call = CGF.Builder.CreateCall(
Alexey Bataev0e1b4582017-11-02 14:25:34 +00001801 createRuntimeFunction(OMPRTL__kmpc_global_thread_num),
1802 emitUpdateLocation(CGF, Loc));
1803 Call->setCallingConv(CGF.getRuntimeCC());
Alexey Bataev0e1b4582017-11-02 14:25:34 +00001804 Elem.second.ThreadID = Call;
1805 return Call;
Alexey Bataev9959db52014-05-06 10:08:46 +00001806}
1807
Alexey Bataev3eff5f42015-02-25 08:32:46 +00001808void CGOpenMPRuntime::functionFinished(CodeGenFunction &CGF) {
Alexey Bataev9959db52014-05-06 10:08:46 +00001809 assert(CGF.CurFn && "No function in current CodeGenFunction.");
Alexey Bataevfd006c42018-10-05 15:08:53 +00001810 if (OpenMPLocThreadIDMap.count(CGF.CurFn)) {
1811 clearLocThreadIdInsertPt(CGF);
Alexey Bataev03b340a2014-10-21 03:16:40 +00001812 OpenMPLocThreadIDMap.erase(CGF.CurFn);
Alexey Bataevfd006c42018-10-05 15:08:53 +00001813 }
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001814 if (FunctionUDRMap.count(CGF.CurFn) > 0) {
Alexey Bataev46978742020-01-30 10:46:11 -05001815 for(const auto *D : FunctionUDRMap[CGF.CurFn])
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001816 UDRMap.erase(D);
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001817 FunctionUDRMap.erase(CGF.CurFn);
1818 }
Michael Krused47b9432019-08-05 18:43:21 +00001819 auto I = FunctionUDMMap.find(CGF.CurFn);
1820 if (I != FunctionUDMMap.end()) {
Alexey Bataev46978742020-01-30 10:46:11 -05001821 for(const auto *D : I->second)
Michael Krused47b9432019-08-05 18:43:21 +00001822 UDMMap.erase(D);
1823 FunctionUDMMap.erase(I);
1824 }
Alexey Bataev46978742020-01-30 10:46:11 -05001825 LastprivateConditionalToTypes.erase(CGF.CurFn);
Alexey Bataev9959db52014-05-06 10:08:46 +00001826}
1827
1828llvm::Type *CGOpenMPRuntime::getIdentTyPointerTy() {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001829 return IdentTy->getPointerTo();
Alexey Bataev9959db52014-05-06 10:08:46 +00001830}
1831
1832llvm::Type *CGOpenMPRuntime::getKmpc_MicroPointerTy() {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001833 if (!Kmpc_MicroTy) {
1834 // Build void (*kmpc_micro)(kmp_int32 *global_tid, kmp_int32 *bound_tid,...)
1835 llvm::Type *MicroParams[] = {llvm::PointerType::getUnqual(CGM.Int32Ty),
1836 llvm::PointerType::getUnqual(CGM.Int32Ty)};
1837 Kmpc_MicroTy = llvm::FunctionType::get(CGM.VoidTy, MicroParams, true);
1838 }
Alexey Bataev9959db52014-05-06 10:08:46 +00001839 return llvm::PointerType::getUnqual(Kmpc_MicroTy);
1840}
1841
James Y Knight9871db02019-02-05 16:42:33 +00001842llvm::FunctionCallee CGOpenMPRuntime::createRuntimeFunction(unsigned Function) {
1843 llvm::FunctionCallee RTLFn = nullptr;
Alexey Bataev50b3c952016-02-19 10:38:26 +00001844 switch (static_cast<OpenMPRTLFunction>(Function)) {
Alexey Bataev9959db52014-05-06 10:08:46 +00001845 case OMPRTL__kmpc_fork_call: {
1846 // Build void __kmpc_fork_call(ident_t *loc, kmp_int32 argc, kmpc_micro
1847 // microtask, ...);
Alexey Bataev23b69422014-06-18 07:08:49 +00001848 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
1849 getKmpc_MicroPointerTy()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001850 auto *FnTy =
Alexey Bataevd74d0602014-10-13 06:02:40 +00001851 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ true);
Alexey Bataev9959db52014-05-06 10:08:46 +00001852 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_fork_call");
James Y Knight9871db02019-02-05 16:42:33 +00001853 if (auto *F = dyn_cast<llvm::Function>(RTLFn.getCallee())) {
Johannes Doerfertac991bb2019-01-19 05:36:54 +00001854 if (!F->hasMetadata(llvm::LLVMContext::MD_callback)) {
1855 llvm::LLVMContext &Ctx = F->getContext();
1856 llvm::MDBuilder MDB(Ctx);
1857 // Annotate the callback behavior of the __kmpc_fork_call:
1858 // - The callback callee is argument number 2 (microtask).
1859 // - The first two arguments of the callback callee are unknown (-1).
1860 // - All variadic arguments to the __kmpc_fork_call are passed to the
1861 // callback callee.
1862 F->addMetadata(
1863 llvm::LLVMContext::MD_callback,
1864 *llvm::MDNode::get(Ctx, {MDB.createCallbackEncoding(
1865 2, {-1, -1},
1866 /* VarArgsArePassed */ true)}));
1867 }
1868 }
Alexey Bataev9959db52014-05-06 10:08:46 +00001869 break;
1870 }
1871 case OMPRTL__kmpc_global_thread_num: {
1872 // Build kmp_int32 __kmpc_global_thread_num(ident_t *loc);
Alexey Bataev23b69422014-06-18 07:08:49 +00001873 llvm::Type *TypeParams[] = {getIdentTyPointerTy()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001874 auto *FnTy =
Alexey Bataevd74d0602014-10-13 06:02:40 +00001875 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
Alexey Bataev9959db52014-05-06 10:08:46 +00001876 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_global_thread_num");
1877 break;
1878 }
Alexey Bataev97720002014-11-11 04:05:39 +00001879 case OMPRTL__kmpc_threadprivate_cached: {
1880 // Build void *__kmpc_threadprivate_cached(ident_t *loc,
1881 // kmp_int32 global_tid, void *data, size_t size, void ***cache);
1882 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
1883 CGM.VoidPtrTy, CGM.SizeTy,
1884 CGM.VoidPtrTy->getPointerTo()->getPointerTo()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001885 auto *FnTy =
Alexey Bataev97720002014-11-11 04:05:39 +00001886 llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg*/ false);
1887 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_threadprivate_cached");
1888 break;
1889 }
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00001890 case OMPRTL__kmpc_critical: {
Alexey Bataevf9472182014-09-22 12:32:31 +00001891 // Build void __kmpc_critical(ident_t *loc, kmp_int32 global_tid,
1892 // kmp_critical_name *crit);
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00001893 llvm::Type *TypeParams[] = {
1894 getIdentTyPointerTy(), CGM.Int32Ty,
1895 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001896 auto *FnTy =
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00001897 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1898 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_critical");
1899 break;
1900 }
Alexey Bataevfc57d162015-12-15 10:55:09 +00001901 case OMPRTL__kmpc_critical_with_hint: {
1902 // Build void __kmpc_critical_with_hint(ident_t *loc, kmp_int32 global_tid,
1903 // kmp_critical_name *crit, uintptr_t hint);
1904 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
1905 llvm::PointerType::getUnqual(KmpCriticalNameTy),
1906 CGM.IntPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001907 auto *FnTy =
Alexey Bataevfc57d162015-12-15 10:55:09 +00001908 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1909 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_critical_with_hint");
1910 break;
1911 }
Alexey Bataev97720002014-11-11 04:05:39 +00001912 case OMPRTL__kmpc_threadprivate_register: {
1913 // Build void __kmpc_threadprivate_register(ident_t *, void *data,
1914 // kmpc_ctor ctor, kmpc_cctor cctor, kmpc_dtor dtor);
1915 // typedef void *(*kmpc_ctor)(void *);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001916 auto *KmpcCtorTy =
Alexey Bataev97720002014-11-11 04:05:39 +00001917 llvm::FunctionType::get(CGM.VoidPtrTy, CGM.VoidPtrTy,
1918 /*isVarArg*/ false)->getPointerTo();
1919 // typedef void *(*kmpc_cctor)(void *, void *);
1920 llvm::Type *KmpcCopyCtorTyArgs[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001921 auto *KmpcCopyCtorTy =
Alexey Bataev97720002014-11-11 04:05:39 +00001922 llvm::FunctionType::get(CGM.VoidPtrTy, KmpcCopyCtorTyArgs,
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001923 /*isVarArg*/ false)
1924 ->getPointerTo();
Alexey Bataev97720002014-11-11 04:05:39 +00001925 // typedef void (*kmpc_dtor)(void *);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001926 auto *KmpcDtorTy =
Alexey Bataev97720002014-11-11 04:05:39 +00001927 llvm::FunctionType::get(CGM.VoidTy, CGM.VoidPtrTy, /*isVarArg*/ false)
1928 ->getPointerTo();
1929 llvm::Type *FnTyArgs[] = {getIdentTyPointerTy(), CGM.VoidPtrTy, KmpcCtorTy,
1930 KmpcCopyCtorTy, KmpcDtorTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001931 auto *FnTy = llvm::FunctionType::get(CGM.VoidTy, FnTyArgs,
Alexey Bataev97720002014-11-11 04:05:39 +00001932 /*isVarArg*/ false);
1933 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_threadprivate_register");
1934 break;
1935 }
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00001936 case OMPRTL__kmpc_end_critical: {
Alexey Bataevf9472182014-09-22 12:32:31 +00001937 // Build void __kmpc_end_critical(ident_t *loc, kmp_int32 global_tid,
1938 // kmp_critical_name *crit);
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00001939 llvm::Type *TypeParams[] = {
1940 getIdentTyPointerTy(), CGM.Int32Ty,
1941 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001942 auto *FnTy =
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00001943 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1944 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_critical");
1945 break;
1946 }
Alexey Bataev8f7c1b02014-12-05 04:09:23 +00001947 case OMPRTL__kmpc_cancel_barrier: {
1948 // Build kmp_int32 __kmpc_cancel_barrier(ident_t *loc, kmp_int32
1949 // global_tid);
Alexey Bataev4a5bb772014-10-08 14:01:46 +00001950 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001951 auto *FnTy =
Alexey Bataev8f7c1b02014-12-05 04:09:23 +00001952 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
1953 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name*/ "__kmpc_cancel_barrier");
Alexey Bataev4a5bb772014-10-08 14:01:46 +00001954 break;
1955 }
Alexey Bataev81c7ea02015-07-03 09:56:58 +00001956 case OMPRTL__kmpc_barrier: {
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00001957 // Build void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid);
Alexey Bataev81c7ea02015-07-03 09:56:58 +00001958 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001959 auto *FnTy =
Alexey Bataev81c7ea02015-07-03 09:56:58 +00001960 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1961 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name*/ "__kmpc_barrier");
1962 break;
1963 }
Alexander Musmanc6388682014-12-15 07:07:06 +00001964 case OMPRTL__kmpc_for_static_fini: {
1965 // Build void __kmpc_for_static_fini(ident_t *loc, kmp_int32 global_tid);
1966 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001967 auto *FnTy =
Alexander Musmanc6388682014-12-15 07:07:06 +00001968 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1969 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_for_static_fini");
1970 break;
1971 }
Alexey Bataevb2059782014-10-13 08:23:51 +00001972 case OMPRTL__kmpc_push_num_threads: {
1973 // Build void __kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid,
1974 // kmp_int32 num_threads)
1975 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
1976 CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001977 auto *FnTy =
Alexey Bataevb2059782014-10-13 08:23:51 +00001978 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1979 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_num_threads");
1980 break;
1981 }
Alexey Bataevd74d0602014-10-13 06:02:40 +00001982 case OMPRTL__kmpc_serialized_parallel: {
1983 // Build void __kmpc_serialized_parallel(ident_t *loc, kmp_int32
1984 // global_tid);
1985 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001986 auto *FnTy =
Alexey Bataevd74d0602014-10-13 06:02:40 +00001987 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1988 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_serialized_parallel");
1989 break;
1990 }
1991 case OMPRTL__kmpc_end_serialized_parallel: {
1992 // Build void __kmpc_end_serialized_parallel(ident_t *loc, kmp_int32
1993 // global_tid);
1994 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001995 auto *FnTy =
Alexey Bataevd74d0602014-10-13 06:02:40 +00001996 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1997 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_serialized_parallel");
1998 break;
1999 }
Alexey Bataevcc37cc12014-11-20 04:34:54 +00002000 case OMPRTL__kmpc_flush: {
Alexey Bataevd76df6d2015-02-24 12:55:09 +00002001 // Build void __kmpc_flush(ident_t *loc);
Alexey Bataevcc37cc12014-11-20 04:34:54 +00002002 llvm::Type *TypeParams[] = {getIdentTyPointerTy()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002003 auto *FnTy =
Alexey Bataevd76df6d2015-02-24 12:55:09 +00002004 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
Alexey Bataevcc37cc12014-11-20 04:34:54 +00002005 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_flush");
2006 break;
2007 }
Alexey Bataev8d690652014-12-04 07:23:53 +00002008 case OMPRTL__kmpc_master: {
2009 // Build kmp_int32 __kmpc_master(ident_t *loc, kmp_int32 global_tid);
2010 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002011 auto *FnTy =
Alexey Bataev8d690652014-12-04 07:23:53 +00002012 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
2013 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_master");
2014 break;
2015 }
2016 case OMPRTL__kmpc_end_master: {
2017 // Build void __kmpc_end_master(ident_t *loc, kmp_int32 global_tid);
2018 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002019 auto *FnTy =
Alexey Bataev8d690652014-12-04 07:23:53 +00002020 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2021 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_master");
2022 break;
2023 }
Alexey Bataev9f797f32015-02-05 05:57:51 +00002024 case OMPRTL__kmpc_omp_taskyield: {
2025 // Build kmp_int32 __kmpc_omp_taskyield(ident_t *, kmp_int32 global_tid,
2026 // int end_part);
2027 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002028 auto *FnTy =
Alexey Bataev9f797f32015-02-05 05:57:51 +00002029 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
2030 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_taskyield");
2031 break;
2032 }
Alexey Bataev6956e2e2015-02-05 06:35:41 +00002033 case OMPRTL__kmpc_single: {
2034 // Build kmp_int32 __kmpc_single(ident_t *loc, kmp_int32 global_tid);
2035 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002036 auto *FnTy =
Alexey Bataev6956e2e2015-02-05 06:35:41 +00002037 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
2038 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_single");
2039 break;
2040 }
2041 case OMPRTL__kmpc_end_single: {
2042 // Build void __kmpc_end_single(ident_t *loc, kmp_int32 global_tid);
2043 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002044 auto *FnTy =
Alexey Bataev6956e2e2015-02-05 06:35:41 +00002045 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2046 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_single");
2047 break;
2048 }
Alexey Bataev62b63b12015-03-10 07:28:44 +00002049 case OMPRTL__kmpc_omp_task_alloc: {
2050 // Build kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid,
2051 // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
2052 // kmp_routine_entry_t *task_entry);
2053 assert(KmpRoutineEntryPtrTy != nullptr &&
2054 "Type kmp_routine_entry_t must be created.");
2055 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty,
2056 CGM.SizeTy, CGM.SizeTy, KmpRoutineEntryPtrTy};
2057 // Return void * and then cast to particular kmp_task_t type.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002058 auto *FnTy =
Alexey Bataev62b63b12015-03-10 07:28:44 +00002059 llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg=*/false);
2060 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task_alloc");
2061 break;
2062 }
Gheorghe-Teodor Bercea545a9fe2019-06-14 20:19:54 +00002063 case OMPRTL__kmpc_omp_target_task_alloc: {
2064 // Build kmp_task_t *__kmpc_omp_target_task_alloc(ident_t *, kmp_int32 gtid,
2065 // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
2066 // kmp_routine_entry_t *task_entry, kmp_int64 device_id);
2067 assert(KmpRoutineEntryPtrTy != nullptr &&
2068 "Type kmp_routine_entry_t must be created.");
2069 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty,
2070 CGM.SizeTy, CGM.SizeTy, KmpRoutineEntryPtrTy,
2071 CGM.Int64Ty};
2072 // Return void * and then cast to particular kmp_task_t type.
2073 auto *FnTy =
2074 llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg=*/false);
2075 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_target_task_alloc");
2076 break;
2077 }
Alexey Bataev62b63b12015-03-10 07:28:44 +00002078 case OMPRTL__kmpc_omp_task: {
2079 // Build kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t
2080 // *new_task);
2081 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
2082 CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002083 auto *FnTy =
Alexey Bataev62b63b12015-03-10 07:28:44 +00002084 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
2085 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task");
2086 break;
2087 }
Alexey Bataeva63048e2015-03-23 06:18:07 +00002088 case OMPRTL__kmpc_copyprivate: {
2089 // Build void __kmpc_copyprivate(ident_t *loc, kmp_int32 global_tid,
Alexey Bataev66beaa92015-04-30 03:47:32 +00002090 // size_t cpy_size, void *cpy_data, void(*cpy_func)(void *, void *),
Alexey Bataeva63048e2015-03-23 06:18:07 +00002091 // kmp_int32 didit);
2092 llvm::Type *CpyTypeParams[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
2093 auto *CpyFnTy =
2094 llvm::FunctionType::get(CGM.VoidTy, CpyTypeParams, /*isVarArg=*/false);
Alexey Bataev66beaa92015-04-30 03:47:32 +00002095 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.SizeTy,
Alexey Bataeva63048e2015-03-23 06:18:07 +00002096 CGM.VoidPtrTy, CpyFnTy->getPointerTo(),
2097 CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002098 auto *FnTy =
Alexey Bataeva63048e2015-03-23 06:18:07 +00002099 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2100 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_copyprivate");
2101 break;
2102 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002103 case OMPRTL__kmpc_reduce: {
2104 // Build kmp_int32 __kmpc_reduce(ident_t *loc, kmp_int32 global_tid,
2105 // kmp_int32 num_vars, size_t reduce_size, void *reduce_data, void
2106 // (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name *lck);
2107 llvm::Type *ReduceTypeParams[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
2108 auto *ReduceFnTy = llvm::FunctionType::get(CGM.VoidTy, ReduceTypeParams,
2109 /*isVarArg=*/false);
2110 llvm::Type *TypeParams[] = {
2111 getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty, CGM.SizeTy,
2112 CGM.VoidPtrTy, ReduceFnTy->getPointerTo(),
2113 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002114 auto *FnTy =
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002115 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
2116 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_reduce");
2117 break;
2118 }
2119 case OMPRTL__kmpc_reduce_nowait: {
2120 // Build kmp_int32 __kmpc_reduce_nowait(ident_t *loc, kmp_int32
2121 // global_tid, kmp_int32 num_vars, size_t reduce_size, void *reduce_data,
2122 // void (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name
2123 // *lck);
2124 llvm::Type *ReduceTypeParams[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
2125 auto *ReduceFnTy = llvm::FunctionType::get(CGM.VoidTy, ReduceTypeParams,
2126 /*isVarArg=*/false);
2127 llvm::Type *TypeParams[] = {
2128 getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty, CGM.SizeTy,
2129 CGM.VoidPtrTy, ReduceFnTy->getPointerTo(),
2130 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002131 auto *FnTy =
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002132 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
2133 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_reduce_nowait");
2134 break;
2135 }
2136 case OMPRTL__kmpc_end_reduce: {
2137 // Build void __kmpc_end_reduce(ident_t *loc, kmp_int32 global_tid,
2138 // kmp_critical_name *lck);
2139 llvm::Type *TypeParams[] = {
2140 getIdentTyPointerTy(), CGM.Int32Ty,
2141 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002142 auto *FnTy =
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002143 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2144 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_reduce");
2145 break;
2146 }
2147 case OMPRTL__kmpc_end_reduce_nowait: {
2148 // Build __kmpc_end_reduce_nowait(ident_t *loc, kmp_int32 global_tid,
2149 // kmp_critical_name *lck);
2150 llvm::Type *TypeParams[] = {
2151 getIdentTyPointerTy(), CGM.Int32Ty,
2152 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002153 auto *FnTy =
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002154 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2155 RTLFn =
2156 CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_reduce_nowait");
2157 break;
2158 }
Alexey Bataev1d677132015-04-22 13:57:31 +00002159 case OMPRTL__kmpc_omp_task_begin_if0: {
2160 // Build void __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t
2161 // *new_task);
2162 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
2163 CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002164 auto *FnTy =
Alexey Bataev1d677132015-04-22 13:57:31 +00002165 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2166 RTLFn =
2167 CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task_begin_if0");
2168 break;
2169 }
2170 case OMPRTL__kmpc_omp_task_complete_if0: {
2171 // Build void __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t
2172 // *new_task);
2173 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
2174 CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002175 auto *FnTy =
Alexey Bataev1d677132015-04-22 13:57:31 +00002176 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2177 RTLFn = CGM.CreateRuntimeFunction(FnTy,
2178 /*Name=*/"__kmpc_omp_task_complete_if0");
2179 break;
2180 }
Alexey Bataev98eb6e32015-04-22 11:15:40 +00002181 case OMPRTL__kmpc_ordered: {
2182 // Build void __kmpc_ordered(ident_t *loc, kmp_int32 global_tid);
2183 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002184 auto *FnTy =
Alexey Bataev98eb6e32015-04-22 11:15:40 +00002185 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2186 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_ordered");
2187 break;
2188 }
2189 case OMPRTL__kmpc_end_ordered: {
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002190 // Build void __kmpc_end_ordered(ident_t *loc, kmp_int32 global_tid);
Alexey Bataev98eb6e32015-04-22 11:15:40 +00002191 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002192 auto *FnTy =
Alexey Bataev98eb6e32015-04-22 11:15:40 +00002193 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2194 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_ordered");
2195 break;
2196 }
Alexey Bataev8b8e2022015-04-27 05:22:09 +00002197 case OMPRTL__kmpc_omp_taskwait: {
2198 // Build kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32 global_tid);
2199 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002200 auto *FnTy =
Alexey Bataev8b8e2022015-04-27 05:22:09 +00002201 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
2202 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_omp_taskwait");
2203 break;
2204 }
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002205 case OMPRTL__kmpc_taskgroup: {
2206 // Build void __kmpc_taskgroup(ident_t *loc, kmp_int32 global_tid);
2207 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002208 auto *FnTy =
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002209 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2210 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_taskgroup");
2211 break;
2212 }
2213 case OMPRTL__kmpc_end_taskgroup: {
2214 // Build void __kmpc_end_taskgroup(ident_t *loc, kmp_int32 global_tid);
2215 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002216 auto *FnTy =
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002217 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2218 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_taskgroup");
2219 break;
2220 }
Alexey Bataev7f210c62015-06-18 13:40:03 +00002221 case OMPRTL__kmpc_push_proc_bind: {
2222 // Build void __kmpc_push_proc_bind(ident_t *loc, kmp_int32 global_tid,
2223 // int proc_bind)
2224 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002225 auto *FnTy =
Alexey Bataev7f210c62015-06-18 13:40:03 +00002226 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2227 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_proc_bind");
2228 break;
2229 }
Alexey Bataev1d2353d2015-06-24 11:01:36 +00002230 case OMPRTL__kmpc_omp_task_with_deps: {
2231 // Build kmp_int32 __kmpc_omp_task_with_deps(ident_t *, kmp_int32 gtid,
2232 // kmp_task_t *new_task, kmp_int32 ndeps, kmp_depend_info_t *dep_list,
2233 // kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list);
2234 llvm::Type *TypeParams[] = {
2235 getIdentTyPointerTy(), CGM.Int32Ty, CGM.VoidPtrTy, CGM.Int32Ty,
2236 CGM.VoidPtrTy, CGM.Int32Ty, CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002237 auto *FnTy =
Alexey Bataev1d2353d2015-06-24 11:01:36 +00002238 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
2239 RTLFn =
2240 CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task_with_deps");
2241 break;
2242 }
2243 case OMPRTL__kmpc_omp_wait_deps: {
2244 // Build void __kmpc_omp_wait_deps(ident_t *, kmp_int32 gtid,
2245 // kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32 ndeps_noalias,
2246 // kmp_depend_info_t *noalias_dep_list);
2247 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
2248 CGM.Int32Ty, CGM.VoidPtrTy,
2249 CGM.Int32Ty, CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002250 auto *FnTy =
Alexey Bataev1d2353d2015-06-24 11:01:36 +00002251 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2252 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_wait_deps");
2253 break;
2254 }
Alexey Bataev0f34da12015-07-02 04:17:07 +00002255 case OMPRTL__kmpc_cancellationpoint: {
2256 // Build kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32
2257 // global_tid, kmp_int32 cncl_kind)
2258 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002259 auto *FnTy =
Alexey Bataev0f34da12015-07-02 04:17:07 +00002260 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2261 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_cancellationpoint");
2262 break;
2263 }
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00002264 case OMPRTL__kmpc_cancel: {
2265 // Build kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid,
2266 // kmp_int32 cncl_kind)
2267 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002268 auto *FnTy =
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00002269 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2270 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_cancel");
2271 break;
2272 }
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00002273 case OMPRTL__kmpc_push_num_teams: {
2274 // Build void kmpc_push_num_teams (ident_t loc, kmp_int32 global_tid,
2275 // kmp_int32 num_teams, kmp_int32 num_threads)
2276 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty,
2277 CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002278 auto *FnTy =
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00002279 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2280 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_num_teams");
2281 break;
2282 }
2283 case OMPRTL__kmpc_fork_teams: {
2284 // Build void __kmpc_fork_teams(ident_t *loc, kmp_int32 argc, kmpc_micro
2285 // microtask, ...);
2286 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
2287 getKmpc_MicroPointerTy()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002288 auto *FnTy =
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00002289 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ true);
2290 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_fork_teams");
James Y Knight9871db02019-02-05 16:42:33 +00002291 if (auto *F = dyn_cast<llvm::Function>(RTLFn.getCallee())) {
Johannes Doerfertac991bb2019-01-19 05:36:54 +00002292 if (!F->hasMetadata(llvm::LLVMContext::MD_callback)) {
2293 llvm::LLVMContext &Ctx = F->getContext();
2294 llvm::MDBuilder MDB(Ctx);
2295 // Annotate the callback behavior of the __kmpc_fork_teams:
2296 // - The callback callee is argument number 2 (microtask).
2297 // - The first two arguments of the callback callee are unknown (-1).
2298 // - All variadic arguments to the __kmpc_fork_teams are passed to the
2299 // callback callee.
2300 F->addMetadata(
2301 llvm::LLVMContext::MD_callback,
2302 *llvm::MDNode::get(Ctx, {MDB.createCallbackEncoding(
2303 2, {-1, -1},
2304 /* VarArgsArePassed */ true)}));
2305 }
2306 }
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00002307 break;
2308 }
Alexey Bataev7292c292016-04-25 12:22:29 +00002309 case OMPRTL__kmpc_taskloop: {
2310 // Build void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t *task, int
2311 // if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int nogroup, int
2312 // sched, kmp_uint64 grainsize, void *task_dup);
2313 llvm::Type *TypeParams[] = {getIdentTyPointerTy(),
2314 CGM.IntTy,
2315 CGM.VoidPtrTy,
2316 CGM.IntTy,
2317 CGM.Int64Ty->getPointerTo(),
2318 CGM.Int64Ty->getPointerTo(),
2319 CGM.Int64Ty,
2320 CGM.IntTy,
2321 CGM.IntTy,
2322 CGM.Int64Ty,
2323 CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002324 auto *FnTy =
Alexey Bataev7292c292016-04-25 12:22:29 +00002325 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2326 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_taskloop");
2327 break;
2328 }
Alexey Bataev8b427062016-05-25 12:36:08 +00002329 case OMPRTL__kmpc_doacross_init: {
2330 // Build void __kmpc_doacross_init(ident_t *loc, kmp_int32 gtid, kmp_int32
2331 // num_dims, struct kmp_dim *dims);
2332 llvm::Type *TypeParams[] = {getIdentTyPointerTy(),
2333 CGM.Int32Ty,
2334 CGM.Int32Ty,
2335 CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002336 auto *FnTy =
Alexey Bataev8b427062016-05-25 12:36:08 +00002337 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2338 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_doacross_init");
2339 break;
2340 }
2341 case OMPRTL__kmpc_doacross_fini: {
2342 // Build void __kmpc_doacross_fini(ident_t *loc, kmp_int32 gtid);
2343 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002344 auto *FnTy =
Alexey Bataev8b427062016-05-25 12:36:08 +00002345 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2346 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_doacross_fini");
2347 break;
2348 }
2349 case OMPRTL__kmpc_doacross_post: {
2350 // Build void __kmpc_doacross_post(ident_t *loc, kmp_int32 gtid, kmp_int64
2351 // *vec);
2352 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
2353 CGM.Int64Ty->getPointerTo()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002354 auto *FnTy =
Alexey Bataev8b427062016-05-25 12:36:08 +00002355 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2356 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_doacross_post");
2357 break;
2358 }
2359 case OMPRTL__kmpc_doacross_wait: {
2360 // Build void __kmpc_doacross_wait(ident_t *loc, kmp_int32 gtid, kmp_int64
2361 // *vec);
2362 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
2363 CGM.Int64Ty->getPointerTo()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002364 auto *FnTy =
Alexey Bataev8b427062016-05-25 12:36:08 +00002365 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2366 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_doacross_wait");
2367 break;
2368 }
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00002369 case OMPRTL__kmpc_task_reduction_init: {
2370 // Build void *__kmpc_task_reduction_init(int gtid, int num_data, void
2371 // *data);
2372 llvm::Type *TypeParams[] = {CGM.IntTy, CGM.IntTy, CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002373 auto *FnTy =
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00002374 llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg=*/false);
2375 RTLFn =
2376 CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_task_reduction_init");
2377 break;
2378 }
2379 case OMPRTL__kmpc_task_reduction_get_th_data: {
2380 // Build void *__kmpc_task_reduction_get_th_data(int gtid, void *tg, void
2381 // *d);
2382 llvm::Type *TypeParams[] = {CGM.IntTy, CGM.VoidPtrTy, CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002383 auto *FnTy =
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00002384 llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg=*/false);
2385 RTLFn = CGM.CreateRuntimeFunction(
2386 FnTy, /*Name=*/"__kmpc_task_reduction_get_th_data");
2387 break;
2388 }
Alexey Bataev4f680db2019-03-19 16:41:16 +00002389 case OMPRTL__kmpc_alloc: {
Alexey Bataev6cf7b712019-04-08 19:06:42 +00002390 // Build to void *__kmpc_alloc(int gtid, size_t sz, omp_allocator_handle_t
2391 // al); omp_allocator_handle_t type is void *.
2392 llvm::Type *TypeParams[] = {CGM.IntTy, CGM.SizeTy, CGM.VoidPtrTy};
Alexey Bataev4f680db2019-03-19 16:41:16 +00002393 auto *FnTy =
2394 llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg=*/false);
2395 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_alloc");
2396 break;
2397 }
2398 case OMPRTL__kmpc_free: {
Alexey Bataev6cf7b712019-04-08 19:06:42 +00002399 // Build to void __kmpc_free(int gtid, void *ptr, omp_allocator_handle_t
2400 // al); omp_allocator_handle_t type is void *.
2401 llvm::Type *TypeParams[] = {CGM.IntTy, CGM.VoidPtrTy, CGM.VoidPtrTy};
Alexey Bataev4f680db2019-03-19 16:41:16 +00002402 auto *FnTy =
2403 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2404 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_free");
2405 break;
2406 }
Alexey Bataev7bb33532019-01-07 21:30:43 +00002407 case OMPRTL__kmpc_push_target_tripcount: {
2408 // Build void __kmpc_push_target_tripcount(int64_t device_id, kmp_uint64
2409 // size);
2410 llvm::Type *TypeParams[] = {CGM.Int64Ty, CGM.Int64Ty};
2411 llvm::FunctionType *FnTy =
2412 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2413 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_target_tripcount");
2414 break;
2415 }
Samuel Antaobed3c462015-10-02 16:14:20 +00002416 case OMPRTL__tgt_target: {
George Rokos63bc9d62017-11-21 18:25:12 +00002417 // Build int32_t __tgt_target(int64_t device_id, void *host_ptr, int32_t
Alexey Bataeva90fc662019-06-25 16:00:43 +00002418 // arg_num, void** args_base, void **args, int64_t *arg_sizes, int64_t
Samuel Antaobed3c462015-10-02 16:14:20 +00002419 // *arg_types);
George Rokos63bc9d62017-11-21 18:25:12 +00002420 llvm::Type *TypeParams[] = {CGM.Int64Ty,
Samuel Antaobed3c462015-10-02 16:14:20 +00002421 CGM.VoidPtrTy,
2422 CGM.Int32Ty,
2423 CGM.VoidPtrPtrTy,
2424 CGM.VoidPtrPtrTy,
Alexey Bataeva90fc662019-06-25 16:00:43 +00002425 CGM.Int64Ty->getPointerTo(),
George Rokos63bc9d62017-11-21 18:25:12 +00002426 CGM.Int64Ty->getPointerTo()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002427 auto *FnTy =
Samuel Antaobed3c462015-10-02 16:14:20 +00002428 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2429 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target");
2430 break;
2431 }
Alexey Bataeva9f77c62017-12-13 21:04:20 +00002432 case OMPRTL__tgt_target_nowait: {
2433 // Build int32_t __tgt_target_nowait(int64_t device_id, void *host_ptr,
Alexey Bataeva90fc662019-06-25 16:00:43 +00002434 // int32_t arg_num, void** args_base, void **args, int64_t *arg_sizes,
Alexey Bataeva9f77c62017-12-13 21:04:20 +00002435 // int64_t *arg_types);
2436 llvm::Type *TypeParams[] = {CGM.Int64Ty,
2437 CGM.VoidPtrTy,
2438 CGM.Int32Ty,
2439 CGM.VoidPtrPtrTy,
2440 CGM.VoidPtrPtrTy,
Alexey Bataeva90fc662019-06-25 16:00:43 +00002441 CGM.Int64Ty->getPointerTo(),
Alexey Bataeva9f77c62017-12-13 21:04:20 +00002442 CGM.Int64Ty->getPointerTo()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002443 auto *FnTy =
Alexey Bataeva9f77c62017-12-13 21:04:20 +00002444 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2445 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_nowait");
2446 break;
2447 }
Samuel Antaob68e2db2016-03-03 16:20:23 +00002448 case OMPRTL__tgt_target_teams: {
George Rokos63bc9d62017-11-21 18:25:12 +00002449 // Build int32_t __tgt_target_teams(int64_t device_id, void *host_ptr,
Alexey Bataeva90fc662019-06-25 16:00:43 +00002450 // int32_t arg_num, void** args_base, void **args, int64_t *arg_sizes,
George Rokos63bc9d62017-11-21 18:25:12 +00002451 // int64_t *arg_types, int32_t num_teams, int32_t thread_limit);
2452 llvm::Type *TypeParams[] = {CGM.Int64Ty,
Samuel Antaob68e2db2016-03-03 16:20:23 +00002453 CGM.VoidPtrTy,
2454 CGM.Int32Ty,
2455 CGM.VoidPtrPtrTy,
2456 CGM.VoidPtrPtrTy,
Alexey Bataeva90fc662019-06-25 16:00:43 +00002457 CGM.Int64Ty->getPointerTo(),
George Rokos63bc9d62017-11-21 18:25:12 +00002458 CGM.Int64Ty->getPointerTo(),
Samuel Antaob68e2db2016-03-03 16:20:23 +00002459 CGM.Int32Ty,
2460 CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002461 auto *FnTy =
Samuel Antaob68e2db2016-03-03 16:20:23 +00002462 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2463 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_teams");
2464 break;
2465 }
Alexey Bataeva9f77c62017-12-13 21:04:20 +00002466 case OMPRTL__tgt_target_teams_nowait: {
2467 // Build int32_t __tgt_target_teams_nowait(int64_t device_id, void
Alexey Bataeva90fc662019-06-25 16:00:43 +00002468 // *host_ptr, int32_t arg_num, void** args_base, void **args, int64_t
Alexey Bataeva9f77c62017-12-13 21:04:20 +00002469 // *arg_sizes, int64_t *arg_types, int32_t num_teams, int32_t thread_limit);
2470 llvm::Type *TypeParams[] = {CGM.Int64Ty,
2471 CGM.VoidPtrTy,
2472 CGM.Int32Ty,
2473 CGM.VoidPtrPtrTy,
2474 CGM.VoidPtrPtrTy,
Alexey Bataeva90fc662019-06-25 16:00:43 +00002475 CGM.Int64Ty->getPointerTo(),
Alexey Bataeva9f77c62017-12-13 21:04:20 +00002476 CGM.Int64Ty->getPointerTo(),
2477 CGM.Int32Ty,
2478 CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002479 auto *FnTy =
Alexey Bataeva9f77c62017-12-13 21:04:20 +00002480 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2481 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_teams_nowait");
2482 break;
2483 }
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +00002484 case OMPRTL__tgt_register_requires: {
2485 // Build void __tgt_register_requires(int64_t flags);
2486 llvm::Type *TypeParams[] = {CGM.Int64Ty};
2487 auto *FnTy =
2488 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2489 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_register_requires");
2490 break;
2491 }
Samuel Antaodf158d52016-04-27 22:58:19 +00002492 case OMPRTL__tgt_target_data_begin: {
George Rokos63bc9d62017-11-21 18:25:12 +00002493 // Build void __tgt_target_data_begin(int64_t device_id, int32_t arg_num,
Alexey Bataeva90fc662019-06-25 16:00:43 +00002494 // void** args_base, void **args, int64_t *arg_sizes, int64_t *arg_types);
George Rokos63bc9d62017-11-21 18:25:12 +00002495 llvm::Type *TypeParams[] = {CGM.Int64Ty,
Samuel Antaodf158d52016-04-27 22:58:19 +00002496 CGM.Int32Ty,
2497 CGM.VoidPtrPtrTy,
2498 CGM.VoidPtrPtrTy,
Alexey Bataeva90fc662019-06-25 16:00:43 +00002499 CGM.Int64Ty->getPointerTo(),
George Rokos63bc9d62017-11-21 18:25:12 +00002500 CGM.Int64Ty->getPointerTo()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002501 auto *FnTy =
Samuel Antaodf158d52016-04-27 22:58:19 +00002502 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2503 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_begin");
2504 break;
2505 }
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +00002506 case OMPRTL__tgt_target_data_begin_nowait: {
2507 // Build void __tgt_target_data_begin_nowait(int64_t device_id, int32_t
Alexey Bataeva90fc662019-06-25 16:00:43 +00002508 // arg_num, void** args_base, void **args, int64_t *arg_sizes, int64_t
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +00002509 // *arg_types);
2510 llvm::Type *TypeParams[] = {CGM.Int64Ty,
2511 CGM.Int32Ty,
2512 CGM.VoidPtrPtrTy,
2513 CGM.VoidPtrPtrTy,
Alexey Bataeva90fc662019-06-25 16:00:43 +00002514 CGM.Int64Ty->getPointerTo(),
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +00002515 CGM.Int64Ty->getPointerTo()};
2516 auto *FnTy =
2517 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2518 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_begin_nowait");
2519 break;
2520 }
Samuel Antaodf158d52016-04-27 22:58:19 +00002521 case OMPRTL__tgt_target_data_end: {
George Rokos63bc9d62017-11-21 18:25:12 +00002522 // Build void __tgt_target_data_end(int64_t device_id, int32_t arg_num,
Alexey Bataeva90fc662019-06-25 16:00:43 +00002523 // void** args_base, void **args, int64_t *arg_sizes, int64_t *arg_types);
George Rokos63bc9d62017-11-21 18:25:12 +00002524 llvm::Type *TypeParams[] = {CGM.Int64Ty,
Samuel Antaodf158d52016-04-27 22:58:19 +00002525 CGM.Int32Ty,
2526 CGM.VoidPtrPtrTy,
2527 CGM.VoidPtrPtrTy,
Alexey Bataeva90fc662019-06-25 16:00:43 +00002528 CGM.Int64Ty->getPointerTo(),
George Rokos63bc9d62017-11-21 18:25:12 +00002529 CGM.Int64Ty->getPointerTo()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002530 auto *FnTy =
Samuel Antaodf158d52016-04-27 22:58:19 +00002531 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2532 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_end");
2533 break;
2534 }
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +00002535 case OMPRTL__tgt_target_data_end_nowait: {
2536 // Build void __tgt_target_data_end_nowait(int64_t device_id, int32_t
Alexey Bataeva90fc662019-06-25 16:00:43 +00002537 // arg_num, void** args_base, void **args, int64_t *arg_sizes, int64_t
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +00002538 // *arg_types);
2539 llvm::Type *TypeParams[] = {CGM.Int64Ty,
2540 CGM.Int32Ty,
2541 CGM.VoidPtrPtrTy,
2542 CGM.VoidPtrPtrTy,
Alexey Bataeva90fc662019-06-25 16:00:43 +00002543 CGM.Int64Ty->getPointerTo(),
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +00002544 CGM.Int64Ty->getPointerTo()};
2545 auto *FnTy =
2546 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2547 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_end_nowait");
2548 break;
2549 }
Samuel Antao8d2d7302016-05-26 18:30:22 +00002550 case OMPRTL__tgt_target_data_update: {
George Rokos63bc9d62017-11-21 18:25:12 +00002551 // Build void __tgt_target_data_update(int64_t device_id, int32_t arg_num,
Alexey Bataeva90fc662019-06-25 16:00:43 +00002552 // void** args_base, void **args, int64_t *arg_sizes, int64_t *arg_types);
George Rokos63bc9d62017-11-21 18:25:12 +00002553 llvm::Type *TypeParams[] = {CGM.Int64Ty,
Samuel Antao8d2d7302016-05-26 18:30:22 +00002554 CGM.Int32Ty,
2555 CGM.VoidPtrPtrTy,
2556 CGM.VoidPtrPtrTy,
Alexey Bataeva90fc662019-06-25 16:00:43 +00002557 CGM.Int64Ty->getPointerTo(),
George Rokos63bc9d62017-11-21 18:25:12 +00002558 CGM.Int64Ty->getPointerTo()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002559 auto *FnTy =
Samuel Antao8d2d7302016-05-26 18:30:22 +00002560 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2561 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_update");
2562 break;
2563 }
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +00002564 case OMPRTL__tgt_target_data_update_nowait: {
2565 // Build void __tgt_target_data_update_nowait(int64_t device_id, int32_t
Alexey Bataeva90fc662019-06-25 16:00:43 +00002566 // arg_num, void** args_base, void **args, int64_t *arg_sizes, int64_t
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +00002567 // *arg_types);
2568 llvm::Type *TypeParams[] = {CGM.Int64Ty,
2569 CGM.Int32Ty,
2570 CGM.VoidPtrPtrTy,
2571 CGM.VoidPtrPtrTy,
Alexey Bataeva90fc662019-06-25 16:00:43 +00002572 CGM.Int64Ty->getPointerTo(),
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +00002573 CGM.Int64Ty->getPointerTo()};
2574 auto *FnTy =
2575 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2576 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_update_nowait");
2577 break;
2578 }
Michael Krused47b9432019-08-05 18:43:21 +00002579 case OMPRTL__tgt_mapper_num_components: {
2580 // Build int64_t __tgt_mapper_num_components(void *rt_mapper_handle);
2581 llvm::Type *TypeParams[] = {CGM.VoidPtrTy};
2582 auto *FnTy =
2583 llvm::FunctionType::get(CGM.Int64Ty, TypeParams, /*isVarArg*/ false);
2584 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_mapper_num_components");
2585 break;
2586 }
2587 case OMPRTL__tgt_push_mapper_component: {
2588 // Build void __tgt_push_mapper_component(void *rt_mapper_handle, void
2589 // *base, void *begin, int64_t size, int64_t type);
2590 llvm::Type *TypeParams[] = {CGM.VoidPtrTy, CGM.VoidPtrTy, CGM.VoidPtrTy,
2591 CGM.Int64Ty, CGM.Int64Ty};
2592 auto *FnTy =
2593 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2594 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_push_mapper_component");
2595 break;
2596 }
Alexey Bataev9959db52014-05-06 10:08:46 +00002597 }
Alexey Bataev50b3c952016-02-19 10:38:26 +00002598 assert(RTLFn && "Unable to find OpenMP runtime function");
Alexey Bataev9959db52014-05-06 10:08:46 +00002599 return RTLFn;
2600}
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00002601
James Y Knight9871db02019-02-05 16:42:33 +00002602llvm::FunctionCallee
2603CGOpenMPRuntime::createForStaticInitFunction(unsigned IVSize, bool IVSigned) {
Alexander Musman21212e42015-03-13 10:38:23 +00002604 assert((IVSize == 32 || IVSize == 64) &&
2605 "IV size is not compatible with the omp runtime");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002606 StringRef Name = IVSize == 32 ? (IVSigned ? "__kmpc_for_static_init_4"
2607 : "__kmpc_for_static_init_4u")
2608 : (IVSigned ? "__kmpc_for_static_init_8"
2609 : "__kmpc_for_static_init_8u");
2610 llvm::Type *ITy = IVSize == 32 ? CGM.Int32Ty : CGM.Int64Ty;
2611 auto *PtrTy = llvm::PointerType::getUnqual(ITy);
Alexander Musman21212e42015-03-13 10:38:23 +00002612 llvm::Type *TypeParams[] = {
2613 getIdentTyPointerTy(), // loc
2614 CGM.Int32Ty, // tid
2615 CGM.Int32Ty, // schedtype
2616 llvm::PointerType::getUnqual(CGM.Int32Ty), // p_lastiter
2617 PtrTy, // p_lower
2618 PtrTy, // p_upper
2619 PtrTy, // p_stride
2620 ITy, // incr
2621 ITy // chunk
2622 };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002623 auto *FnTy =
Alexander Musman21212e42015-03-13 10:38:23 +00002624 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2625 return CGM.CreateRuntimeFunction(FnTy, Name);
2626}
2627
James Y Knight9871db02019-02-05 16:42:33 +00002628llvm::FunctionCallee
2629CGOpenMPRuntime::createDispatchInitFunction(unsigned IVSize, bool IVSigned) {
Alexander Musman92bdaab2015-03-12 13:37:50 +00002630 assert((IVSize == 32 || IVSize == 64) &&
2631 "IV size is not compatible with the omp runtime");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002632 StringRef Name =
Alexander Musman92bdaab2015-03-12 13:37:50 +00002633 IVSize == 32
2634 ? (IVSigned ? "__kmpc_dispatch_init_4" : "__kmpc_dispatch_init_4u")
2635 : (IVSigned ? "__kmpc_dispatch_init_8" : "__kmpc_dispatch_init_8u");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002636 llvm::Type *ITy = IVSize == 32 ? CGM.Int32Ty : CGM.Int64Ty;
Alexander Musman92bdaab2015-03-12 13:37:50 +00002637 llvm::Type *TypeParams[] = { getIdentTyPointerTy(), // loc
2638 CGM.Int32Ty, // tid
2639 CGM.Int32Ty, // schedtype
2640 ITy, // lower
2641 ITy, // upper
2642 ITy, // stride
2643 ITy // chunk
2644 };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002645 auto *FnTy =
Alexander Musman92bdaab2015-03-12 13:37:50 +00002646 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2647 return CGM.CreateRuntimeFunction(FnTy, Name);
2648}
2649
James Y Knight9871db02019-02-05 16:42:33 +00002650llvm::FunctionCallee
2651CGOpenMPRuntime::createDispatchFiniFunction(unsigned IVSize, bool IVSigned) {
Alexey Bataev98eb6e32015-04-22 11:15:40 +00002652 assert((IVSize == 32 || IVSize == 64) &&
2653 "IV size is not compatible with the omp runtime");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002654 StringRef Name =
Alexey Bataev98eb6e32015-04-22 11:15:40 +00002655 IVSize == 32
2656 ? (IVSigned ? "__kmpc_dispatch_fini_4" : "__kmpc_dispatch_fini_4u")
2657 : (IVSigned ? "__kmpc_dispatch_fini_8" : "__kmpc_dispatch_fini_8u");
2658 llvm::Type *TypeParams[] = {
2659 getIdentTyPointerTy(), // loc
2660 CGM.Int32Ty, // tid
2661 };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002662 auto *FnTy =
Alexey Bataev98eb6e32015-04-22 11:15:40 +00002663 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2664 return CGM.CreateRuntimeFunction(FnTy, Name);
2665}
2666
James Y Knight9871db02019-02-05 16:42:33 +00002667llvm::FunctionCallee
2668CGOpenMPRuntime::createDispatchNextFunction(unsigned IVSize, bool IVSigned) {
Alexander Musman92bdaab2015-03-12 13:37:50 +00002669 assert((IVSize == 32 || IVSize == 64) &&
2670 "IV size is not compatible with the omp runtime");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002671 StringRef Name =
Alexander Musman92bdaab2015-03-12 13:37:50 +00002672 IVSize == 32
2673 ? (IVSigned ? "__kmpc_dispatch_next_4" : "__kmpc_dispatch_next_4u")
2674 : (IVSigned ? "__kmpc_dispatch_next_8" : "__kmpc_dispatch_next_8u");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002675 llvm::Type *ITy = IVSize == 32 ? CGM.Int32Ty : CGM.Int64Ty;
2676 auto *PtrTy = llvm::PointerType::getUnqual(ITy);
Alexander Musman92bdaab2015-03-12 13:37:50 +00002677 llvm::Type *TypeParams[] = {
2678 getIdentTyPointerTy(), // loc
2679 CGM.Int32Ty, // tid
2680 llvm::PointerType::getUnqual(CGM.Int32Ty), // p_lastiter
2681 PtrTy, // p_lower
2682 PtrTy, // p_upper
2683 PtrTy // p_stride
2684 };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002685 auto *FnTy =
Alexander Musman92bdaab2015-03-12 13:37:50 +00002686 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2687 return CGM.CreateRuntimeFunction(FnTy, Name);
2688}
2689
Gheorghe-Teodor Bercea625f59d2019-08-01 21:15:58 +00002690/// Obtain information that uniquely identifies a target entry. This
2691/// consists of the file and device IDs as well as line number associated with
2692/// the relevant entry source location.
2693static void getTargetEntryUniqueInfo(ASTContext &C, SourceLocation Loc,
2694 unsigned &DeviceID, unsigned &FileID,
2695 unsigned &LineNum) {
2696 SourceManager &SM = C.getSourceManager();
2697
2698 // The loc should be always valid and have a file ID (the user cannot use
2699 // #pragma directives in macros)
2700
2701 assert(Loc.isValid() && "Source location is expected to be always valid.");
2702
2703 PresumedLoc PLoc = SM.getPresumedLoc(Loc);
2704 assert(PLoc.isValid() && "Source location is expected to be always valid.");
2705
2706 llvm::sys::fs::UniqueID ID;
2707 if (auto EC = llvm::sys::fs::getUniqueID(PLoc.getFilename(), ID))
2708 SM.getDiagnostics().Report(diag::err_cannot_open_file)
2709 << PLoc.getFilename() << EC.message();
2710
2711 DeviceID = ID.getDevice();
2712 FileID = ID.getFile();
2713 LineNum = PLoc.getLine();
2714}
2715
Gheorghe-Teodor Bercea0034e842019-06-20 18:04:47 +00002716Address CGOpenMPRuntime::getAddrOfDeclareTargetVar(const VarDecl *VD) {
Alexey Bataev03f270c2018-03-30 18:31:07 +00002717 if (CGM.getLangOpts().OpenMPSimd)
2718 return Address::invalid();
Alexey Bataev92327c52018-03-26 16:40:55 +00002719 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
Alexey Bataev97b72212018-08-14 18:31:20 +00002720 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
Gheorghe-Teodor Bercea0034e842019-06-20 18:04:47 +00002721 if (Res && (*Res == OMPDeclareTargetDeclAttr::MT_Link ||
2722 (*Res == OMPDeclareTargetDeclAttr::MT_To &&
2723 HasRequiresUnifiedSharedMemory))) {
Alexey Bataev92327c52018-03-26 16:40:55 +00002724 SmallString<64> PtrName;
2725 {
2726 llvm::raw_svector_ostream OS(PtrName);
Gheorghe-Teodor Bercea625f59d2019-08-01 21:15:58 +00002727 OS << CGM.getMangledName(GlobalDecl(VD));
2728 if (!VD->isExternallyVisible()) {
2729 unsigned DeviceID, FileID, Line;
2730 getTargetEntryUniqueInfo(CGM.getContext(),
2731 VD->getCanonicalDecl()->getBeginLoc(),
2732 DeviceID, FileID, Line);
2733 OS << llvm::format("_%x", FileID);
2734 }
2735 OS << "_decl_tgt_ref_ptr";
Alexey Bataev92327c52018-03-26 16:40:55 +00002736 }
2737 llvm::Value *Ptr = CGM.getModule().getNamedValue(PtrName);
2738 if (!Ptr) {
2739 QualType PtrTy = CGM.getContext().getPointerType(VD->getType());
2740 Ptr = getOrCreateInternalVariable(CGM.getTypes().ConvertTypeForMem(PtrTy),
2741 PtrName);
Gheorghe-Teodor Bercea625f59d2019-08-01 21:15:58 +00002742
2743 auto *GV = cast<llvm::GlobalVariable>(Ptr);
2744 GV->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
2745
2746 if (!CGM.getLangOpts().OpenMPIsDevice)
Alexey Bataev03f270c2018-03-30 18:31:07 +00002747 GV->setInitializer(CGM.GetAddrOfGlobal(VD));
Alexey Bataev03f270c2018-03-30 18:31:07 +00002748 registerTargetGlobalVariable(VD, cast<llvm::Constant>(Ptr));
Alexey Bataev92327c52018-03-26 16:40:55 +00002749 }
2750 return Address(Ptr, CGM.getContext().getDeclAlign(VD));
2751 }
2752 return Address::invalid();
2753}
2754
Alexey Bataev97720002014-11-11 04:05:39 +00002755llvm::Constant *
2756CGOpenMPRuntime::getOrCreateThreadPrivateCache(const VarDecl *VD) {
Samuel Antaof8b50122015-07-13 22:54:53 +00002757 assert(!CGM.getLangOpts().OpenMPUseTLS ||
2758 !CGM.getContext().getTargetInfo().isTLSSupported());
Alexey Bataev97720002014-11-11 04:05:39 +00002759 // Lookup the entry, lazily creating it if necessary.
Alexey Bataev18fa2322018-05-02 14:20:50 +00002760 std::string Suffix = getName({"cache", ""});
2761 return getOrCreateInternalVariable(
2762 CGM.Int8PtrPtrTy, Twine(CGM.getMangledName(VD)).concat(Suffix));
Alexey Bataev97720002014-11-11 04:05:39 +00002763}
2764
John McCall7f416cc2015-09-08 08:05:57 +00002765Address CGOpenMPRuntime::getAddrOfThreadPrivate(CodeGenFunction &CGF,
2766 const VarDecl *VD,
2767 Address VDAddr,
2768 SourceLocation Loc) {
Samuel Antaof8b50122015-07-13 22:54:53 +00002769 if (CGM.getLangOpts().OpenMPUseTLS &&
2770 CGM.getContext().getTargetInfo().isTLSSupported())
2771 return VDAddr;
2772
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002773 llvm::Type *VarTy = VDAddr.getElementType();
Alexey Bataev3eff5f42015-02-25 08:32:46 +00002774 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
John McCall7f416cc2015-09-08 08:05:57 +00002775 CGF.Builder.CreatePointerCast(VDAddr.getPointer(),
2776 CGM.Int8PtrTy),
Alexey Bataev97720002014-11-11 04:05:39 +00002777 CGM.getSize(CGM.GetTargetTypeStoreSize(VarTy)),
2778 getOrCreateThreadPrivateCache(VD)};
John McCall7f416cc2015-09-08 08:05:57 +00002779 return Address(CGF.EmitRuntimeCall(
2780 createRuntimeFunction(OMPRTL__kmpc_threadprivate_cached), Args),
2781 VDAddr.getAlignment());
Alexey Bataev97720002014-11-11 04:05:39 +00002782}
2783
Alexey Bataev3eff5f42015-02-25 08:32:46 +00002784void CGOpenMPRuntime::emitThreadPrivateVarInit(
John McCall7f416cc2015-09-08 08:05:57 +00002785 CodeGenFunction &CGF, Address VDAddr, llvm::Value *Ctor,
Alexey Bataev97720002014-11-11 04:05:39 +00002786 llvm::Value *CopyCtor, llvm::Value *Dtor, SourceLocation Loc) {
2787 // Call kmp_int32 __kmpc_global_thread_num(&loc) to init OpenMP runtime
2788 // library.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002789 llvm::Value *OMPLoc = emitUpdateLocation(CGF, Loc);
Alexey Bataev3eff5f42015-02-25 08:32:46 +00002790 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_global_thread_num),
Alexey Bataev97720002014-11-11 04:05:39 +00002791 OMPLoc);
2792 // Call __kmpc_threadprivate_register(&loc, &var, ctor, cctor/*NULL*/, dtor)
2793 // to register constructor/destructor for variable.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002794 llvm::Value *Args[] = {
2795 OMPLoc, CGF.Builder.CreatePointerCast(VDAddr.getPointer(), CGM.VoidPtrTy),
2796 Ctor, CopyCtor, Dtor};
Alexey Bataev1e4b7132014-12-03 12:11:24 +00002797 CGF.EmitRuntimeCall(
Alexey Bataev3eff5f42015-02-25 08:32:46 +00002798 createRuntimeFunction(OMPRTL__kmpc_threadprivate_register), Args);
Alexey Bataev97720002014-11-11 04:05:39 +00002799}
2800
Alexey Bataev3eff5f42015-02-25 08:32:46 +00002801llvm::Function *CGOpenMPRuntime::emitThreadPrivateVarDefinition(
John McCall7f416cc2015-09-08 08:05:57 +00002802 const VarDecl *VD, Address VDAddr, SourceLocation Loc,
Alexey Bataev97720002014-11-11 04:05:39 +00002803 bool PerformInit, CodeGenFunction *CGF) {
Samuel Antaof8b50122015-07-13 22:54:53 +00002804 if (CGM.getLangOpts().OpenMPUseTLS &&
2805 CGM.getContext().getTargetInfo().isTLSSupported())
2806 return nullptr;
2807
Alexey Bataev97720002014-11-11 04:05:39 +00002808 VD = VD->getDefinition(CGM.getContext());
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00002809 if (VD && ThreadPrivateWithDefinition.insert(CGM.getMangledName(VD)).second) {
Alexey Bataev97720002014-11-11 04:05:39 +00002810 QualType ASTTy = VD->getType();
2811
2812 llvm::Value *Ctor = nullptr, *CopyCtor = nullptr, *Dtor = nullptr;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002813 const Expr *Init = VD->getAnyInitializer();
Alexey Bataev97720002014-11-11 04:05:39 +00002814 if (CGM.getLangOpts().CPlusPlus && PerformInit) {
2815 // Generate function that re-emits the declaration's initializer into the
2816 // threadprivate copy of the variable VD
2817 CodeGenFunction CtorCGF(CGM);
2818 FunctionArgList Args;
Alexey Bataev7cae94e2018-01-04 19:45:16 +00002819 ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr, Loc,
2820 /*Id=*/nullptr, CGM.getContext().VoidPtrTy,
Alexey Bataev56223232017-06-09 13:40:18 +00002821 ImplicitParamDecl::Other);
Alexey Bataev97720002014-11-11 04:05:39 +00002822 Args.push_back(&Dst);
2823
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002824 const auto &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
John McCallc56a8b32016-03-11 04:30:31 +00002825 CGM.getContext().VoidPtrTy, Args);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002826 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
Alexey Bataev18fa2322018-05-02 14:20:50 +00002827 std::string Name = getName({"__kmpc_global_ctor_", ""});
2828 llvm::Function *Fn =
2829 CGM.CreateGlobalInitOrDestructFunction(FTy, Name, FI, Loc);
Alexey Bataev97720002014-11-11 04:05:39 +00002830 CtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidPtrTy, Fn, FI,
Alexey Bataev7cae94e2018-01-04 19:45:16 +00002831 Args, Loc, Loc);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002832 llvm::Value *ArgVal = CtorCGF.EmitLoadOfScalar(
John McCall7f416cc2015-09-08 08:05:57 +00002833 CtorCGF.GetAddrOfLocalVar(&Dst), /*Volatile=*/false,
Alexey Bataev97720002014-11-11 04:05:39 +00002834 CGM.getContext().VoidPtrTy, Dst.getLocation());
John McCall7f416cc2015-09-08 08:05:57 +00002835 Address Arg = Address(ArgVal, VDAddr.getAlignment());
Alexey Bataev7cae94e2018-01-04 19:45:16 +00002836 Arg = CtorCGF.Builder.CreateElementBitCast(
2837 Arg, CtorCGF.ConvertTypeForMem(ASTTy));
Alexey Bataev97720002014-11-11 04:05:39 +00002838 CtorCGF.EmitAnyExprToMem(Init, Arg, Init->getType().getQualifiers(),
2839 /*IsInitializer=*/true);
2840 ArgVal = CtorCGF.EmitLoadOfScalar(
John McCall7f416cc2015-09-08 08:05:57 +00002841 CtorCGF.GetAddrOfLocalVar(&Dst), /*Volatile=*/false,
Alexey Bataev97720002014-11-11 04:05:39 +00002842 CGM.getContext().VoidPtrTy, Dst.getLocation());
2843 CtorCGF.Builder.CreateStore(ArgVal, CtorCGF.ReturnValue);
2844 CtorCGF.FinishFunction();
2845 Ctor = Fn;
2846 }
2847 if (VD->getType().isDestructedType() != QualType::DK_none) {
2848 // Generate function that emits destructor call for the threadprivate copy
2849 // of the variable VD
2850 CodeGenFunction DtorCGF(CGM);
2851 FunctionArgList Args;
Alexey Bataev7cae94e2018-01-04 19:45:16 +00002852 ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr, Loc,
2853 /*Id=*/nullptr, CGM.getContext().VoidPtrTy,
Alexey Bataev56223232017-06-09 13:40:18 +00002854 ImplicitParamDecl::Other);
Alexey Bataev97720002014-11-11 04:05:39 +00002855 Args.push_back(&Dst);
2856
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002857 const auto &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
John McCallc56a8b32016-03-11 04:30:31 +00002858 CGM.getContext().VoidTy, Args);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002859 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
Alexey Bataev18fa2322018-05-02 14:20:50 +00002860 std::string Name = getName({"__kmpc_global_dtor_", ""});
2861 llvm::Function *Fn =
2862 CGM.CreateGlobalInitOrDestructFunction(FTy, Name, FI, Loc);
Adrian Prantl1858c662016-04-24 22:22:29 +00002863 auto NL = ApplyDebugLocation::CreateEmpty(DtorCGF);
Alexey Bataev97720002014-11-11 04:05:39 +00002864 DtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, Fn, FI, Args,
Alexey Bataev7cae94e2018-01-04 19:45:16 +00002865 Loc, Loc);
Adrian Prantl1858c662016-04-24 22:22:29 +00002866 // Create a scope with an artificial location for the body of this function.
2867 auto AL = ApplyDebugLocation::CreateArtificial(DtorCGF);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002868 llvm::Value *ArgVal = DtorCGF.EmitLoadOfScalar(
Alexey Bataev97720002014-11-11 04:05:39 +00002869 DtorCGF.GetAddrOfLocalVar(&Dst),
John McCall7f416cc2015-09-08 08:05:57 +00002870 /*Volatile=*/false, CGM.getContext().VoidPtrTy, Dst.getLocation());
2871 DtorCGF.emitDestroy(Address(ArgVal, VDAddr.getAlignment()), ASTTy,
Alexey Bataev97720002014-11-11 04:05:39 +00002872 DtorCGF.getDestroyer(ASTTy.isDestructedType()),
2873 DtorCGF.needsEHCleanup(ASTTy.isDestructedType()));
2874 DtorCGF.FinishFunction();
2875 Dtor = Fn;
2876 }
2877 // Do not emit init function if it is not required.
2878 if (!Ctor && !Dtor)
2879 return nullptr;
2880
2881 llvm::Type *CopyCtorTyArgs[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002882 auto *CopyCtorTy = llvm::FunctionType::get(CGM.VoidPtrTy, CopyCtorTyArgs,
2883 /*isVarArg=*/false)
2884 ->getPointerTo();
Alexey Bataev97720002014-11-11 04:05:39 +00002885 // Copying constructor for the threadprivate variable.
2886 // Must be NULL - reserved by runtime, but currently it requires that this
2887 // parameter is always NULL. Otherwise it fires assertion.
2888 CopyCtor = llvm::Constant::getNullValue(CopyCtorTy);
2889 if (Ctor == nullptr) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002890 auto *CtorTy = llvm::FunctionType::get(CGM.VoidPtrTy, CGM.VoidPtrTy,
2891 /*isVarArg=*/false)
2892 ->getPointerTo();
Alexey Bataev97720002014-11-11 04:05:39 +00002893 Ctor = llvm::Constant::getNullValue(CtorTy);
2894 }
2895 if (Dtor == nullptr) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002896 auto *DtorTy = llvm::FunctionType::get(CGM.VoidTy, CGM.VoidPtrTy,
2897 /*isVarArg=*/false)
2898 ->getPointerTo();
Alexey Bataev97720002014-11-11 04:05:39 +00002899 Dtor = llvm::Constant::getNullValue(DtorTy);
2900 }
2901 if (!CGF) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002902 auto *InitFunctionTy =
Alexey Bataev97720002014-11-11 04:05:39 +00002903 llvm::FunctionType::get(CGM.VoidTy, /*isVarArg*/ false);
Alexey Bataev18fa2322018-05-02 14:20:50 +00002904 std::string Name = getName({"__omp_threadprivate_init_", ""});
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002905 llvm::Function *InitFunction = CGM.CreateGlobalInitOrDestructFunction(
Alexey Bataev18fa2322018-05-02 14:20:50 +00002906 InitFunctionTy, Name, CGM.getTypes().arrangeNullaryFunction());
Alexey Bataev97720002014-11-11 04:05:39 +00002907 CodeGenFunction InitCGF(CGM);
2908 FunctionArgList ArgList;
2909 InitCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, InitFunction,
2910 CGM.getTypes().arrangeNullaryFunction(), ArgList,
Alexey Bataev7cae94e2018-01-04 19:45:16 +00002911 Loc, Loc);
Alexey Bataev3eff5f42015-02-25 08:32:46 +00002912 emitThreadPrivateVarInit(InitCGF, VDAddr, Ctor, CopyCtor, Dtor, Loc);
Alexey Bataev97720002014-11-11 04:05:39 +00002913 InitCGF.FinishFunction();
2914 return InitFunction;
2915 }
Alexey Bataev3eff5f42015-02-25 08:32:46 +00002916 emitThreadPrivateVarInit(*CGF, VDAddr, Ctor, CopyCtor, Dtor, Loc);
Alexey Bataev97720002014-11-11 04:05:39 +00002917 }
2918 return nullptr;
2919}
2920
Alexey Bataev34f8a702018-03-28 14:28:54 +00002921bool CGOpenMPRuntime::emitDeclareTargetVarDefinition(const VarDecl *VD,
2922 llvm::GlobalVariable *Addr,
2923 bool PerformInit) {
Alexey Bataev36724b72019-10-03 16:46:49 +00002924 if (CGM.getLangOpts().OMPTargetTriples.empty() &&
2925 !CGM.getLangOpts().OpenMPIsDevice)
Alexey Bataev4db9dc62019-09-23 15:53:51 +00002926 return false;
Alexey Bataev34f8a702018-03-28 14:28:54 +00002927 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
Alexey Bataev97b72212018-08-14 18:31:20 +00002928 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
Gheorghe-Teodor Bercea0034e842019-06-20 18:04:47 +00002929 if (!Res || *Res == OMPDeclareTargetDeclAttr::MT_Link ||
2930 (*Res == OMPDeclareTargetDeclAttr::MT_To &&
2931 HasRequiresUnifiedSharedMemory))
Alexey Bataevd01b7492018-08-15 19:45:12 +00002932 return CGM.getLangOpts().OpenMPIsDevice;
Alexey Bataev34f8a702018-03-28 14:28:54 +00002933 VD = VD->getDefinition(CGM.getContext());
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00002934 if (VD && !DeclareTargetWithDefinition.insert(CGM.getMangledName(VD)).second)
Alexey Bataev34f8a702018-03-28 14:28:54 +00002935 return CGM.getLangOpts().OpenMPIsDevice;
2936
2937 QualType ASTTy = VD->getType();
2938
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002939 SourceLocation Loc = VD->getCanonicalDecl()->getBeginLoc();
Alexey Bataev34f8a702018-03-28 14:28:54 +00002940 // Produce the unique prefix to identify the new target regions. We use
2941 // the source location of the variable declaration which we know to not
2942 // conflict with any target region.
2943 unsigned DeviceID;
2944 unsigned FileID;
2945 unsigned Line;
2946 getTargetEntryUniqueInfo(CGM.getContext(), Loc, DeviceID, FileID, Line);
2947 SmallString<128> Buffer, Out;
2948 {
2949 llvm::raw_svector_ostream OS(Buffer);
2950 OS << "__omp_offloading_" << llvm::format("_%x", DeviceID)
2951 << llvm::format("_%x_", FileID) << VD->getName() << "_l" << Line;
2952 }
2953
2954 const Expr *Init = VD->getAnyInitializer();
2955 if (CGM.getLangOpts().CPlusPlus && PerformInit) {
2956 llvm::Constant *Ctor;
2957 llvm::Constant *ID;
2958 if (CGM.getLangOpts().OpenMPIsDevice) {
2959 // Generate function that re-emits the declaration's initializer into
2960 // the threadprivate copy of the variable VD
2961 CodeGenFunction CtorCGF(CGM);
2962
2963 const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();
2964 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
2965 llvm::Function *Fn = CGM.CreateGlobalInitOrDestructFunction(
2966 FTy, Twine(Buffer, "_ctor"), FI, Loc);
2967 auto NL = ApplyDebugLocation::CreateEmpty(CtorCGF);
2968 CtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, Fn, FI,
2969 FunctionArgList(), Loc, Loc);
2970 auto AL = ApplyDebugLocation::CreateArtificial(CtorCGF);
2971 CtorCGF.EmitAnyExprToMem(Init,
2972 Address(Addr, CGM.getContext().getDeclAlign(VD)),
2973 Init->getType().getQualifiers(),
2974 /*IsInitializer=*/true);
2975 CtorCGF.FinishFunction();
2976 Ctor = Fn;
2977 ID = llvm::ConstantExpr::getBitCast(Fn, CGM.Int8PtrTy);
Alexey Bataeve253f2f2018-05-09 14:15:18 +00002978 CGM.addUsedGlobal(cast<llvm::GlobalValue>(Ctor));
Alexey Bataev34f8a702018-03-28 14:28:54 +00002979 } else {
2980 Ctor = new llvm::GlobalVariable(
2981 CGM.getModule(), CGM.Int8Ty, /*isConstant=*/true,
2982 llvm::GlobalValue::PrivateLinkage,
2983 llvm::Constant::getNullValue(CGM.Int8Ty), Twine(Buffer, "_ctor"));
2984 ID = Ctor;
2985 }
2986
2987 // Register the information for the entry associated with the constructor.
2988 Out.clear();
2989 OffloadEntriesInfoManager.registerTargetRegionEntryInfo(
2990 DeviceID, FileID, Twine(Buffer, "_ctor").toStringRef(Out), Line, Ctor,
Alexey Bataev03f270c2018-03-30 18:31:07 +00002991 ID, OffloadEntriesInfoManagerTy::OMPTargetRegionEntryCtor);
Alexey Bataev34f8a702018-03-28 14:28:54 +00002992 }
2993 if (VD->getType().isDestructedType() != QualType::DK_none) {
2994 llvm::Constant *Dtor;
2995 llvm::Constant *ID;
2996 if (CGM.getLangOpts().OpenMPIsDevice) {
2997 // Generate function that emits destructor call for the threadprivate
2998 // copy of the variable VD
2999 CodeGenFunction DtorCGF(CGM);
3000
3001 const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();
3002 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
3003 llvm::Function *Fn = CGM.CreateGlobalInitOrDestructFunction(
3004 FTy, Twine(Buffer, "_dtor"), FI, Loc);
3005 auto NL = ApplyDebugLocation::CreateEmpty(DtorCGF);
3006 DtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, Fn, FI,
3007 FunctionArgList(), Loc, Loc);
3008 // Create a scope with an artificial location for the body of this
3009 // function.
3010 auto AL = ApplyDebugLocation::CreateArtificial(DtorCGF);
3011 DtorCGF.emitDestroy(Address(Addr, CGM.getContext().getDeclAlign(VD)),
3012 ASTTy, DtorCGF.getDestroyer(ASTTy.isDestructedType()),
3013 DtorCGF.needsEHCleanup(ASTTy.isDestructedType()));
3014 DtorCGF.FinishFunction();
3015 Dtor = Fn;
3016 ID = llvm::ConstantExpr::getBitCast(Fn, CGM.Int8PtrTy);
Alexey Bataeve253f2f2018-05-09 14:15:18 +00003017 CGM.addUsedGlobal(cast<llvm::GlobalValue>(Dtor));
Alexey Bataev34f8a702018-03-28 14:28:54 +00003018 } else {
3019 Dtor = new llvm::GlobalVariable(
3020 CGM.getModule(), CGM.Int8Ty, /*isConstant=*/true,
3021 llvm::GlobalValue::PrivateLinkage,
3022 llvm::Constant::getNullValue(CGM.Int8Ty), Twine(Buffer, "_dtor"));
3023 ID = Dtor;
3024 }
3025 // Register the information for the entry associated with the destructor.
3026 Out.clear();
3027 OffloadEntriesInfoManager.registerTargetRegionEntryInfo(
3028 DeviceID, FileID, Twine(Buffer, "_dtor").toStringRef(Out), Line, Dtor,
Alexey Bataev03f270c2018-03-30 18:31:07 +00003029 ID, OffloadEntriesInfoManagerTy::OMPTargetRegionEntryDtor);
Alexey Bataev34f8a702018-03-28 14:28:54 +00003030 }
3031 return CGM.getLangOpts().OpenMPIsDevice;
3032}
3033
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00003034Address CGOpenMPRuntime::getAddrOfArtificialThreadPrivate(CodeGenFunction &CGF,
3035 QualType VarType,
3036 StringRef Name) {
Alexey Bataev18fa2322018-05-02 14:20:50 +00003037 std::string Suffix = getName({"artificial", ""});
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00003038 llvm::Type *VarLVType = CGF.ConvertTypeForMem(VarType);
Alexey Bataev18fa2322018-05-02 14:20:50 +00003039 llvm::Value *GAddr =
3040 getOrCreateInternalVariable(VarLVType, Twine(Name).concat(Suffix));
Alexey Bataev8be5a0f2019-12-31 12:41:57 -05003041 if (CGM.getLangOpts().OpenMP && CGM.getLangOpts().OpenMPUseTLS &&
3042 CGM.getTarget().isTLSSupported()) {
3043 cast<llvm::GlobalVariable>(GAddr)->setThreadLocal(/*Val=*/true);
3044 return Address(GAddr, CGM.getContext().getTypeAlignInChars(VarType));
3045 }
3046 std::string CacheSuffix = getName({"cache", ""});
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00003047 llvm::Value *Args[] = {
3048 emitUpdateLocation(CGF, SourceLocation()),
3049 getThreadID(CGF, SourceLocation()),
3050 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(GAddr, CGM.VoidPtrTy),
3051 CGF.Builder.CreateIntCast(CGF.getTypeSize(VarType), CGM.SizeTy,
Rui Ueyama49a3ad22019-07-16 04:46:31 +00003052 /*isSigned=*/false),
Alexey Bataev18fa2322018-05-02 14:20:50 +00003053 getOrCreateInternalVariable(
3054 CGM.VoidPtrPtrTy, Twine(Name).concat(Suffix).concat(CacheSuffix))};
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00003055 return Address(
3056 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
3057 CGF.EmitRuntimeCall(
3058 createRuntimeFunction(OMPRTL__kmpc_threadprivate_cached), Args),
3059 VarLVType->getPointerTo(/*AddrSpace=*/0)),
Alexey Bataev8be5a0f2019-12-31 12:41:57 -05003060 CGM.getContext().getTypeAlignInChars(VarType));
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00003061}
3062
Alexey Bataev1d943ae2019-11-19 12:12:23 -05003063void CGOpenMPRuntime::emitIfClause(CodeGenFunction &CGF, const Expr *Cond,
3064 const RegionCodeGenTy &ThenGen,
3065 const RegionCodeGenTy &ElseGen) {
Alexey Bataev1d677132015-04-22 13:57:31 +00003066 CodeGenFunction::LexicalScope ConditionScope(CGF, Cond->getSourceRange());
3067
3068 // If the condition constant folds and can be elided, try to avoid emitting
3069 // the condition and the dead arm of the if/else.
3070 bool CondConstant;
3071 if (CGF.ConstantFoldsToSimpleInteger(Cond, CondConstant)) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003072 if (CondConstant)
Alexey Bataev1d677132015-04-22 13:57:31 +00003073 ThenGen(CGF);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003074 else
Alexey Bataev1d677132015-04-22 13:57:31 +00003075 ElseGen(CGF);
Alexey Bataev1d677132015-04-22 13:57:31 +00003076 return;
3077 }
3078
3079 // Otherwise, the condition did not fold, or we couldn't elide it. Just
3080 // emit the conditional branch.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003081 llvm::BasicBlock *ThenBlock = CGF.createBasicBlock("omp_if.then");
3082 llvm::BasicBlock *ElseBlock = CGF.createBasicBlock("omp_if.else");
3083 llvm::BasicBlock *ContBlock = CGF.createBasicBlock("omp_if.end");
Alexey Bataev1d677132015-04-22 13:57:31 +00003084 CGF.EmitBranchOnBoolExpr(Cond, ThenBlock, ElseBlock, /*TrueCount=*/0);
3085
3086 // Emit the 'then' code.
3087 CGF.EmitBlock(ThenBlock);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003088 ThenGen(CGF);
Alexey Bataev1d677132015-04-22 13:57:31 +00003089 CGF.EmitBranch(ContBlock);
3090 // Emit the 'else' code if present.
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003091 // There is no need to emit line number for unconditional branch.
3092 (void)ApplyDebugLocation::CreateEmpty(CGF);
3093 CGF.EmitBlock(ElseBlock);
3094 ElseGen(CGF);
3095 // There is no need to emit line number for unconditional branch.
3096 (void)ApplyDebugLocation::CreateEmpty(CGF);
3097 CGF.EmitBranch(ContBlock);
Alexey Bataev1d677132015-04-22 13:57:31 +00003098 // Emit the continuation block for code after the if.
3099 CGF.EmitBlock(ContBlock, /*IsFinished=*/true);
Alexey Bataev4a5bb772014-10-08 14:01:46 +00003100}
3101
Alexey Bataev1d677132015-04-22 13:57:31 +00003102void CGOpenMPRuntime::emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
James Y Knight9871db02019-02-05 16:42:33 +00003103 llvm::Function *OutlinedFn,
Alexey Bataev2377fe92015-09-10 08:12:02 +00003104 ArrayRef<llvm::Value *> CapturedVars,
Alexey Bataev1d677132015-04-22 13:57:31 +00003105 const Expr *IfCond) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003106 if (!CGF.HaveInsertPoint())
3107 return;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003108 llvm::Value *RTLoc = emitUpdateLocation(CGF, Loc);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003109 auto &&ThenGen = [OutlinedFn, CapturedVars, RTLoc](CodeGenFunction &CGF,
3110 PrePostActionTy &) {
Alexey Bataev2377fe92015-09-10 08:12:02 +00003111 // Build call __kmpc_fork_call(loc, n, microtask, var1, .., varn);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003112 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
Alexey Bataev2377fe92015-09-10 08:12:02 +00003113 llvm::Value *Args[] = {
3114 RTLoc,
3115 CGF.Builder.getInt32(CapturedVars.size()), // Number of captured vars
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003116 CGF.Builder.CreateBitCast(OutlinedFn, RT.getKmpc_MicroPointerTy())};
Alexey Bataev2377fe92015-09-10 08:12:02 +00003117 llvm::SmallVector<llvm::Value *, 16> RealArgs;
3118 RealArgs.append(std::begin(Args), std::end(Args));
3119 RealArgs.append(CapturedVars.begin(), CapturedVars.end());
3120
James Y Knight9871db02019-02-05 16:42:33 +00003121 llvm::FunctionCallee RTLFn =
3122 RT.createRuntimeFunction(OMPRTL__kmpc_fork_call);
Alexey Bataev2377fe92015-09-10 08:12:02 +00003123 CGF.EmitRuntimeCall(RTLFn, RealArgs);
3124 };
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003125 auto &&ElseGen = [OutlinedFn, CapturedVars, RTLoc, Loc](CodeGenFunction &CGF,
3126 PrePostActionTy &) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003127 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
3128 llvm::Value *ThreadID = RT.getThreadID(CGF, Loc);
Alexey Bataev1d677132015-04-22 13:57:31 +00003129 // Build calls:
3130 // __kmpc_serialized_parallel(&Loc, GTid);
3131 llvm::Value *Args[] = {RTLoc, ThreadID};
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003132 CGF.EmitRuntimeCall(
3133 RT.createRuntimeFunction(OMPRTL__kmpc_serialized_parallel), Args);
Alexey Bataevd74d0602014-10-13 06:02:40 +00003134
Alexey Bataev3e0f4f82019-10-17 14:36:43 +00003135 // OutlinedFn(&GTid, &zero_bound, CapturedStruct);
3136 Address ThreadIDAddr = RT.emitThreadIDAddress(CGF, Loc);
Alexey Bataevf89cf212019-10-16 16:59:01 +00003137 Address ZeroAddrBound =
3138 CGF.CreateDefaultAlignTempAlloca(CGF.Int32Ty,
3139 /*Name=*/".bound.zero.addr");
3140 CGF.InitTempAlloca(ZeroAddrBound, CGF.Builder.getInt32(/*C*/ 0));
Alexey Bataev2377fe92015-09-10 08:12:02 +00003141 llvm::SmallVector<llvm::Value *, 16> OutlinedFnArgs;
Alexey Bataev8521ff62018-07-25 20:03:01 +00003142 // ThreadId for serialized parallels is 0.
Alexey Bataev3e0f4f82019-10-17 14:36:43 +00003143 OutlinedFnArgs.push_back(ThreadIDAddr.getPointer());
Alexey Bataevf89cf212019-10-16 16:59:01 +00003144 OutlinedFnArgs.push_back(ZeroAddrBound.getPointer());
Alexey Bataev2377fe92015-09-10 08:12:02 +00003145 OutlinedFnArgs.append(CapturedVars.begin(), CapturedVars.end());
Alexey Bataev3c595a62017-08-14 15:01:03 +00003146 RT.emitOutlinedFunctionCall(CGF, Loc, OutlinedFn, OutlinedFnArgs);
Alexey Bataevd74d0602014-10-13 06:02:40 +00003147
Alexey Bataev1d677132015-04-22 13:57:31 +00003148 // __kmpc_end_serialized_parallel(&Loc, GTid);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003149 llvm::Value *EndArgs[] = {RT.emitUpdateLocation(CGF, Loc), ThreadID};
Alexey Bataev1d677132015-04-22 13:57:31 +00003150 CGF.EmitRuntimeCall(
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003151 RT.createRuntimeFunction(OMPRTL__kmpc_end_serialized_parallel),
3152 EndArgs);
Alexey Bataev1d677132015-04-22 13:57:31 +00003153 };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003154 if (IfCond) {
Alexey Bataev1d943ae2019-11-19 12:12:23 -05003155 emitIfClause(CGF, IfCond, ThenGen, ElseGen);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003156 } else {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003157 RegionCodeGenTy ThenRCG(ThenGen);
3158 ThenRCG(CGF);
Alexey Bataevf539faa2016-03-28 12:58:34 +00003159 }
Alexey Bataevd74d0602014-10-13 06:02:40 +00003160}
3161
NAKAMURA Takumi59c74b222014-10-27 08:08:18 +00003162// If we're inside an (outlined) parallel region, use the region info's
Alexey Bataevd74d0602014-10-13 06:02:40 +00003163// thread-ID variable (it is passed in a first argument of the outlined function
3164// as "kmp_int32 *gtid"). Otherwise, if we're not inside parallel region, but in
3165// regular serial code region, get thread ID by calling kmp_int32
3166// kmpc_global_thread_num(ident_t *loc), stash this thread ID in a temporary and
3167// return the address of that temp.
John McCall7f416cc2015-09-08 08:05:57 +00003168Address CGOpenMPRuntime::emitThreadIDAddress(CodeGenFunction &CGF,
3169 SourceLocation Loc) {
Alexey Bataev3015bcc2016-01-22 08:56:50 +00003170 if (auto *OMPRegionInfo =
Alexey Bataevd74d0602014-10-13 06:02:40 +00003171 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
Alexey Bataev8cbe0a62015-02-26 10:27:34 +00003172 if (OMPRegionInfo->getThreadIDVariable())
Akira Hatanakaf139ae32019-12-03 15:17:01 -08003173 return OMPRegionInfo->getThreadIDVariableLValue(CGF).getAddress(CGF);
Alexey Bataev8cbe0a62015-02-26 10:27:34 +00003174
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003175 llvm::Value *ThreadID = getThreadID(CGF, Loc);
3176 QualType Int32Ty =
Alexey Bataevd74d0602014-10-13 06:02:40 +00003177 CGF.getContext().getIntTypeForBitwidth(/*DestWidth*/ 32, /*Signed*/ true);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003178 Address ThreadIDTemp = CGF.CreateMemTemp(Int32Ty, /*Name*/ ".threadid_temp.");
Alexey Bataevd74d0602014-10-13 06:02:40 +00003179 CGF.EmitStoreOfScalar(ThreadID,
John McCall7f416cc2015-09-08 08:05:57 +00003180 CGF.MakeAddrLValue(ThreadIDTemp, Int32Ty));
Alexey Bataevd74d0602014-10-13 06:02:40 +00003181
3182 return ThreadIDTemp;
3183}
3184
Alexey Bataev1af5bd52019-03-05 17:47:18 +00003185llvm::Constant *CGOpenMPRuntime::getOrCreateInternalVariable(
3186 llvm::Type *Ty, const llvm::Twine &Name, unsigned AddressSpace) {
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00003187 SmallString<256> Buffer;
3188 llvm::raw_svector_ostream Out(Buffer);
Alexey Bataev97720002014-11-11 04:05:39 +00003189 Out << Name;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003190 StringRef RuntimeName = Out.str();
Alexey Bataev43a919f2018-04-13 17:48:43 +00003191 auto &Elem = *InternalVars.try_emplace(RuntimeName, nullptr).first;
David Blaikie13156b62014-11-19 03:06:06 +00003192 if (Elem.second) {
3193 assert(Elem.second->getType()->getPointerElementType() == Ty &&
Alexey Bataev97720002014-11-11 04:05:39 +00003194 "OMP internal variable has different type than requested");
David Blaikie13156b62014-11-19 03:06:06 +00003195 return &*Elem.second;
Alexey Bataev97720002014-11-11 04:05:39 +00003196 }
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00003197
David Blaikie13156b62014-11-19 03:06:06 +00003198 return Elem.second = new llvm::GlobalVariable(
3199 CGM.getModule(), Ty, /*IsConstant*/ false,
3200 llvm::GlobalValue::CommonLinkage, llvm::Constant::getNullValue(Ty),
Alexey Bataev1af5bd52019-03-05 17:47:18 +00003201 Elem.first(), /*InsertBefore=*/nullptr,
3202 llvm::GlobalValue::NotThreadLocal, AddressSpace);
Alexey Bataev97720002014-11-11 04:05:39 +00003203}
3204
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003205llvm::Value *CGOpenMPRuntime::getCriticalRegionLock(StringRef CriticalName) {
Alexey Bataev18fa2322018-05-02 14:20:50 +00003206 std::string Prefix = Twine("gomp_critical_user_", CriticalName).str();
3207 std::string Name = getName({Prefix, "var"});
3208 return getOrCreateInternalVariable(KmpCriticalNameTy, Name);
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00003209}
3210
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00003211namespace {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003212/// Common pre(post)-action for different OpenMP constructs.
3213class CommonActionTy final : public PrePostActionTy {
James Y Knight9871db02019-02-05 16:42:33 +00003214 llvm::FunctionCallee EnterCallee;
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003215 ArrayRef<llvm::Value *> EnterArgs;
James Y Knight9871db02019-02-05 16:42:33 +00003216 llvm::FunctionCallee ExitCallee;
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003217 ArrayRef<llvm::Value *> ExitArgs;
3218 bool Conditional;
3219 llvm::BasicBlock *ContBlock = nullptr;
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00003220
3221public:
James Y Knight9871db02019-02-05 16:42:33 +00003222 CommonActionTy(llvm::FunctionCallee EnterCallee,
3223 ArrayRef<llvm::Value *> EnterArgs,
3224 llvm::FunctionCallee ExitCallee,
3225 ArrayRef<llvm::Value *> ExitArgs, bool Conditional = false)
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003226 : EnterCallee(EnterCallee), EnterArgs(EnterArgs), ExitCallee(ExitCallee),
3227 ExitArgs(ExitArgs), Conditional(Conditional) {}
3228 void Enter(CodeGenFunction &CGF) override {
3229 llvm::Value *EnterRes = CGF.EmitRuntimeCall(EnterCallee, EnterArgs);
3230 if (Conditional) {
3231 llvm::Value *CallBool = CGF.Builder.CreateIsNotNull(EnterRes);
3232 auto *ThenBlock = CGF.createBasicBlock("omp_if.then");
3233 ContBlock = CGF.createBasicBlock("omp_if.end");
3234 // Generate the branch (If-stmt)
3235 CGF.Builder.CreateCondBr(CallBool, ThenBlock, ContBlock);
3236 CGF.EmitBlock(ThenBlock);
3237 }
Alexey Bataeva744ff52015-05-05 09:24:37 +00003238 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003239 void Done(CodeGenFunction &CGF) {
3240 // Emit the rest of blocks/branches
3241 CGF.EmitBranch(ContBlock);
3242 CGF.EmitBlock(ContBlock, true);
3243 }
3244 void Exit(CodeGenFunction &CGF) override {
3245 CGF.EmitRuntimeCall(ExitCallee, ExitArgs);
Alexey Bataev3e6124b2015-04-10 07:48:12 +00003246 }
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00003247};
Hans Wennborg7eb54642015-09-10 17:07:54 +00003248} // anonymous namespace
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00003249
3250void CGOpenMPRuntime::emitCriticalRegion(CodeGenFunction &CGF,
3251 StringRef CriticalName,
3252 const RegionCodeGenTy &CriticalOpGen,
Alexey Bataevfc57d162015-12-15 10:55:09 +00003253 SourceLocation Loc, const Expr *Hint) {
3254 // __kmpc_critical[_with_hint](ident_t *, gtid, Lock[, hint]);
Alexey Bataev75ddfab2014-12-01 11:32:38 +00003255 // CriticalOpGen();
3256 // __kmpc_end_critical(ident_t *, gtid, Lock);
3257 // Prepare arguments and build a call to __kmpc_critical
Alexey Bataev8ef31412015-12-18 07:58:25 +00003258 if (!CGF.HaveInsertPoint())
3259 return;
Alexey Bataevfc57d162015-12-15 10:55:09 +00003260 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
3261 getCriticalRegionLock(CriticalName)};
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003262 llvm::SmallVector<llvm::Value *, 4> EnterArgs(std::begin(Args),
3263 std::end(Args));
Alexey Bataevfc57d162015-12-15 10:55:09 +00003264 if (Hint) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003265 EnterArgs.push_back(CGF.Builder.CreateIntCast(
3266 CGF.EmitScalarExpr(Hint), CGM.IntPtrTy, /*isSigned=*/false));
3267 }
3268 CommonActionTy Action(
3269 createRuntimeFunction(Hint ? OMPRTL__kmpc_critical_with_hint
3270 : OMPRTL__kmpc_critical),
3271 EnterArgs, createRuntimeFunction(OMPRTL__kmpc_end_critical), Args);
3272 CriticalOpGen.setAction(Action);
Alexey Bataevfc57d162015-12-15 10:55:09 +00003273 emitInlinedDirective(CGF, OMPD_critical, CriticalOpGen);
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00003274}
Alexey Bataev4a5bb772014-10-08 14:01:46 +00003275
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003276void CGOpenMPRuntime::emitMasterRegion(CodeGenFunction &CGF,
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00003277 const RegionCodeGenTy &MasterOpGen,
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003278 SourceLocation Loc) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003279 if (!CGF.HaveInsertPoint())
3280 return;
Alexey Bataev8d690652014-12-04 07:23:53 +00003281 // if(__kmpc_master(ident_t *, gtid)) {
3282 // MasterOpGen();
3283 // __kmpc_end_master(ident_t *, gtid);
3284 // }
3285 // Prepare arguments and build a call to __kmpc_master
Alexey Bataevd7614fb2015-04-10 06:33:45 +00003286 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003287 CommonActionTy Action(createRuntimeFunction(OMPRTL__kmpc_master), Args,
3288 createRuntimeFunction(OMPRTL__kmpc_end_master), Args,
3289 /*Conditional=*/true);
3290 MasterOpGen.setAction(Action);
3291 emitInlinedDirective(CGF, OMPD_master, MasterOpGen);
3292 Action.Done(CGF);
Alexey Bataev8d690652014-12-04 07:23:53 +00003293}
3294
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003295void CGOpenMPRuntime::emitTaskyieldCall(CodeGenFunction &CGF,
3296 SourceLocation Loc) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003297 if (!CGF.HaveInsertPoint())
3298 return;
Roger Ferrer Ibanez2bef1c02019-12-12 08:55:46 +00003299 llvm::OpenMPIRBuilder *OMPBuilder = CGF.CGM.getOpenMPIRBuilder();
3300 if (OMPBuilder) {
3301 OMPBuilder->CreateTaskyield(CGF.Builder);
3302 } else {
3303 // Build call __kmpc_omp_taskyield(loc, thread_id, 0);
3304 llvm::Value *Args[] = {
3305 emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
3306 llvm::ConstantInt::get(CGM.IntTy, /*V=*/0, /*isSigned=*/true)};
3307 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_taskyield),
3308 Args);
3309 }
3310
Alexey Bataev48591dd2016-04-20 04:01:36 +00003311 if (auto *Region = dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
3312 Region->emitUntiedSwitch(CGF);
Alexey Bataev9f797f32015-02-05 05:57:51 +00003313}
3314
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00003315void CGOpenMPRuntime::emitTaskgroupRegion(CodeGenFunction &CGF,
3316 const RegionCodeGenTy &TaskgroupOpGen,
3317 SourceLocation Loc) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003318 if (!CGF.HaveInsertPoint())
3319 return;
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00003320 // __kmpc_taskgroup(ident_t *, gtid);
3321 // TaskgroupOpGen();
3322 // __kmpc_end_taskgroup(ident_t *, gtid);
3323 // Prepare arguments and build a call to __kmpc_taskgroup
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003324 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
3325 CommonActionTy Action(createRuntimeFunction(OMPRTL__kmpc_taskgroup), Args,
3326 createRuntimeFunction(OMPRTL__kmpc_end_taskgroup),
3327 Args);
3328 TaskgroupOpGen.setAction(Action);
3329 emitInlinedDirective(CGF, OMPD_taskgroup, TaskgroupOpGen);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00003330}
3331
John McCall7f416cc2015-09-08 08:05:57 +00003332/// Given an array of pointers to variables, project the address of a
3333/// given variable.
Alexey Bataevf24e7b12015-10-08 09:10:53 +00003334static Address emitAddrOfVarFromArray(CodeGenFunction &CGF, Address Array,
3335 unsigned Index, const VarDecl *Var) {
John McCall7f416cc2015-09-08 08:05:57 +00003336 // Pull out the pointer to the variable.
James Y Knight751fe282019-02-09 22:22:28 +00003337 Address PtrAddr = CGF.Builder.CreateConstArrayGEP(Array, Index);
John McCall7f416cc2015-09-08 08:05:57 +00003338 llvm::Value *Ptr = CGF.Builder.CreateLoad(PtrAddr);
3339
3340 Address Addr = Address(Ptr, CGF.getContext().getDeclAlign(Var));
Alexey Bataevf24e7b12015-10-08 09:10:53 +00003341 Addr = CGF.Builder.CreateElementBitCast(
3342 Addr, CGF.ConvertTypeForMem(Var->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00003343 return Addr;
3344}
3345
Alexey Bataeva63048e2015-03-23 06:18:07 +00003346static llvm::Value *emitCopyprivateCopyFunction(
Alexey Bataev420d45b2015-04-14 05:11:24 +00003347 CodeGenModule &CGM, llvm::Type *ArgsType,
3348 ArrayRef<const Expr *> CopyprivateVars, ArrayRef<const Expr *> DestExprs,
Alexey Bataev7cae94e2018-01-04 19:45:16 +00003349 ArrayRef<const Expr *> SrcExprs, ArrayRef<const Expr *> AssignmentOps,
3350 SourceLocation Loc) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003351 ASTContext &C = CGM.getContext();
Alexey Bataeva63048e2015-03-23 06:18:07 +00003352 // void copy_func(void *LHSArg, void *RHSArg);
3353 FunctionArgList Args;
Alexey Bataev7cae94e2018-01-04 19:45:16 +00003354 ImplicitParamDecl LHSArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
3355 ImplicitParamDecl::Other);
3356 ImplicitParamDecl RHSArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
3357 ImplicitParamDecl::Other);
Alexey Bataeva63048e2015-03-23 06:18:07 +00003358 Args.push_back(&LHSArg);
3359 Args.push_back(&RHSArg);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003360 const auto &CGFI =
3361 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
Alexey Bataev18fa2322018-05-02 14:20:50 +00003362 std::string Name =
3363 CGM.getOpenMPRuntime().getName({"omp", "copyprivate", "copy_func"});
3364 auto *Fn = llvm::Function::Create(CGM.getTypes().GetFunctionType(CGFI),
3365 llvm::GlobalValue::InternalLinkage, Name,
3366 &CGM.getModule());
Rafael Espindola51ec5a92018-02-28 23:46:35 +00003367 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, CGFI);
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003368 Fn->setDoesNotRecurse();
Alexey Bataeva63048e2015-03-23 06:18:07 +00003369 CodeGenFunction CGF(CGM);
Alexey Bataev7cae94e2018-01-04 19:45:16 +00003370 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args, Loc, Loc);
Alexey Bataev420d45b2015-04-14 05:11:24 +00003371 // Dest = (void*[n])(LHSArg);
Alexey Bataeva63048e2015-03-23 06:18:07 +00003372 // Src = (void*[n])(RHSArg);
John McCall7f416cc2015-09-08 08:05:57 +00003373 Address LHS(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
3374 CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&LHSArg)),
3375 ArgsType), CGF.getPointerAlign());
3376 Address RHS(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
3377 CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&RHSArg)),
3378 ArgsType), CGF.getPointerAlign());
Alexey Bataeva63048e2015-03-23 06:18:07 +00003379 // *(Type0*)Dst[0] = *(Type0*)Src[0];
3380 // *(Type1*)Dst[1] = *(Type1*)Src[1];
3381 // ...
3382 // *(Typen*)Dst[n] = *(Typen*)Src[n];
Alexey Bataeva63048e2015-03-23 06:18:07 +00003383 for (unsigned I = 0, E = AssignmentOps.size(); I < E; ++I) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003384 const auto *DestVar =
3385 cast<VarDecl>(cast<DeclRefExpr>(DestExprs[I])->getDecl());
John McCall7f416cc2015-09-08 08:05:57 +00003386 Address DestAddr = emitAddrOfVarFromArray(CGF, LHS, I, DestVar);
3387
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003388 const auto *SrcVar =
3389 cast<VarDecl>(cast<DeclRefExpr>(SrcExprs[I])->getDecl());
John McCall7f416cc2015-09-08 08:05:57 +00003390 Address SrcAddr = emitAddrOfVarFromArray(CGF, RHS, I, SrcVar);
3391
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003392 const auto *VD = cast<DeclRefExpr>(CopyprivateVars[I])->getDecl();
Alexey Bataev1d9c15c2015-05-19 12:31:28 +00003393 QualType Type = VD->getType();
John McCall7f416cc2015-09-08 08:05:57 +00003394 CGF.EmitOMPCopy(Type, DestAddr, SrcAddr, DestVar, SrcVar, AssignmentOps[I]);
Alexey Bataeva63048e2015-03-23 06:18:07 +00003395 }
Alexey Bataeva63048e2015-03-23 06:18:07 +00003396 CGF.FinishFunction();
3397 return Fn;
3398}
3399
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003400void CGOpenMPRuntime::emitSingleRegion(CodeGenFunction &CGF,
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00003401 const RegionCodeGenTy &SingleOpGen,
Alexey Bataeva63048e2015-03-23 06:18:07 +00003402 SourceLocation Loc,
3403 ArrayRef<const Expr *> CopyprivateVars,
3404 ArrayRef<const Expr *> SrcExprs,
3405 ArrayRef<const Expr *> DstExprs,
3406 ArrayRef<const Expr *> AssignmentOps) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003407 if (!CGF.HaveInsertPoint())
3408 return;
Alexey Bataeva63048e2015-03-23 06:18:07 +00003409 assert(CopyprivateVars.size() == SrcExprs.size() &&
3410 CopyprivateVars.size() == DstExprs.size() &&
3411 CopyprivateVars.size() == AssignmentOps.size());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003412 ASTContext &C = CGM.getContext();
Alexey Bataeva63048e2015-03-23 06:18:07 +00003413 // int32 did_it = 0;
Alexey Bataev6956e2e2015-02-05 06:35:41 +00003414 // if(__kmpc_single(ident_t *, gtid)) {
3415 // SingleOpGen();
3416 // __kmpc_end_single(ident_t *, gtid);
Alexey Bataeva63048e2015-03-23 06:18:07 +00003417 // did_it = 1;
Alexey Bataev6956e2e2015-02-05 06:35:41 +00003418 // }
Alexey Bataeva63048e2015-03-23 06:18:07 +00003419 // call __kmpc_copyprivate(ident_t *, gtid, <buf_size>, <copyprivate list>,
3420 // <copy_func>, did_it);
3421
John McCall7f416cc2015-09-08 08:05:57 +00003422 Address DidIt = Address::invalid();
Alexey Bataeva63048e2015-03-23 06:18:07 +00003423 if (!CopyprivateVars.empty()) {
3424 // int32 did_it = 0;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003425 QualType KmpInt32Ty =
3426 C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
Alexey Bataeva63048e2015-03-23 06:18:07 +00003427 DidIt = CGF.CreateMemTemp(KmpInt32Ty, ".omp.copyprivate.did_it");
John McCall7f416cc2015-09-08 08:05:57 +00003428 CGF.Builder.CreateStore(CGF.Builder.getInt32(0), DidIt);
Alexey Bataeva63048e2015-03-23 06:18:07 +00003429 }
Alexey Bataev6956e2e2015-02-05 06:35:41 +00003430 // Prepare arguments and build a call to __kmpc_single
Alexey Bataevd7614fb2015-04-10 06:33:45 +00003431 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003432 CommonActionTy Action(createRuntimeFunction(OMPRTL__kmpc_single), Args,
3433 createRuntimeFunction(OMPRTL__kmpc_end_single), Args,
3434 /*Conditional=*/true);
3435 SingleOpGen.setAction(Action);
3436 emitInlinedDirective(CGF, OMPD_single, SingleOpGen);
3437 if (DidIt.isValid()) {
3438 // did_it = 1;
3439 CGF.Builder.CreateStore(CGF.Builder.getInt32(1), DidIt);
3440 }
3441 Action.Done(CGF);
Alexey Bataeva63048e2015-03-23 06:18:07 +00003442 // call __kmpc_copyprivate(ident_t *, gtid, <buf_size>, <copyprivate list>,
3443 // <copy_func>, did_it);
John McCall7f416cc2015-09-08 08:05:57 +00003444 if (DidIt.isValid()) {
Alexey Bataeva63048e2015-03-23 06:18:07 +00003445 llvm::APInt ArraySize(/*unsigned int numBits=*/32, CopyprivateVars.size());
Richard Smith772e2662019-10-04 01:25:59 +00003446 QualType CopyprivateArrayTy = C.getConstantArrayType(
3447 C.VoidPtrTy, ArraySize, nullptr, ArrayType::Normal,
3448 /*IndexTypeQuals=*/0);
Alexey Bataeva63048e2015-03-23 06:18:07 +00003449 // Create a list of all private variables for copyprivate.
John McCall7f416cc2015-09-08 08:05:57 +00003450 Address CopyprivateList =
Alexey Bataeva63048e2015-03-23 06:18:07 +00003451 CGF.CreateMemTemp(CopyprivateArrayTy, ".omp.copyprivate.cpr_list");
3452 for (unsigned I = 0, E = CopyprivateVars.size(); I < E; ++I) {
James Y Knight751fe282019-02-09 22:22:28 +00003453 Address Elem = CGF.Builder.CreateConstArrayGEP(CopyprivateList, I);
John McCall7f416cc2015-09-08 08:05:57 +00003454 CGF.Builder.CreateStore(
Alexey Bataeva63048e2015-03-23 06:18:07 +00003455 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
Akira Hatanakaf139ae32019-12-03 15:17:01 -08003456 CGF.EmitLValue(CopyprivateVars[I]).getPointer(CGF),
3457 CGF.VoidPtrTy),
John McCall7f416cc2015-09-08 08:05:57 +00003458 Elem);
Alexey Bataeva63048e2015-03-23 06:18:07 +00003459 }
3460 // Build function that copies private values from single region to all other
3461 // threads in the corresponding parallel region.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003462 llvm::Value *CpyFn = emitCopyprivateCopyFunction(
Alexey Bataeva63048e2015-03-23 06:18:07 +00003463 CGM, CGF.ConvertTypeForMem(CopyprivateArrayTy)->getPointerTo(),
Alexey Bataev7cae94e2018-01-04 19:45:16 +00003464 CopyprivateVars, SrcExprs, DstExprs, AssignmentOps, Loc);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003465 llvm::Value *BufSize = CGF.getTypeSize(CopyprivateArrayTy);
John McCall7f416cc2015-09-08 08:05:57 +00003466 Address CL =
3467 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(CopyprivateList,
3468 CGF.VoidPtrTy);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003469 llvm::Value *DidItVal = CGF.Builder.CreateLoad(DidIt);
Alexey Bataeva63048e2015-03-23 06:18:07 +00003470 llvm::Value *Args[] = {
3471 emitUpdateLocation(CGF, Loc), // ident_t *<loc>
3472 getThreadID(CGF, Loc), // i32 <gtid>
Alexey Bataev66beaa92015-04-30 03:47:32 +00003473 BufSize, // size_t <buf_size>
John McCall7f416cc2015-09-08 08:05:57 +00003474 CL.getPointer(), // void *<copyprivate list>
Alexey Bataeva63048e2015-03-23 06:18:07 +00003475 CpyFn, // void (*) (void *, void *) <copy_func>
3476 DidItVal // i32 did_it
3477 };
3478 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_copyprivate), Args);
3479 }
Alexey Bataev6956e2e2015-02-05 06:35:41 +00003480}
3481
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003482void CGOpenMPRuntime::emitOrderedRegion(CodeGenFunction &CGF,
3483 const RegionCodeGenTy &OrderedOpGen,
Alexey Bataev5f600d62015-09-29 03:48:57 +00003484 SourceLocation Loc, bool IsThreads) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003485 if (!CGF.HaveInsertPoint())
3486 return;
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003487 // __kmpc_ordered(ident_t *, gtid);
3488 // OrderedOpGen();
3489 // __kmpc_end_ordered(ident_t *, gtid);
3490 // Prepare arguments and build a call to __kmpc_ordered
Alexey Bataev5f600d62015-09-29 03:48:57 +00003491 if (IsThreads) {
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003492 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003493 CommonActionTy Action(createRuntimeFunction(OMPRTL__kmpc_ordered), Args,
3494 createRuntimeFunction(OMPRTL__kmpc_end_ordered),
3495 Args);
3496 OrderedOpGen.setAction(Action);
3497 emitInlinedDirective(CGF, OMPD_ordered, OrderedOpGen);
3498 return;
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003499 }
Alexey Bataev5f600d62015-09-29 03:48:57 +00003500 emitInlinedDirective(CGF, OMPD_ordered, OrderedOpGen);
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003501}
3502
Alexey Bataevc3028ca2018-12-04 15:03:25 +00003503unsigned CGOpenMPRuntime::getDefaultFlagsForBarriers(OpenMPDirectiveKind Kind) {
Alexey Bataev50b3c952016-02-19 10:38:26 +00003504 unsigned Flags;
3505 if (Kind == OMPD_for)
3506 Flags = OMP_IDENT_BARRIER_IMPL_FOR;
3507 else if (Kind == OMPD_sections)
3508 Flags = OMP_IDENT_BARRIER_IMPL_SECTIONS;
3509 else if (Kind == OMPD_single)
3510 Flags = OMP_IDENT_BARRIER_IMPL_SINGLE;
3511 else if (Kind == OMPD_barrier)
3512 Flags = OMP_IDENT_BARRIER_EXPL;
3513 else
3514 Flags = OMP_IDENT_BARRIER_IMPL;
Alexey Bataevc3028ca2018-12-04 15:03:25 +00003515 return Flags;
3516}
3517
Alexey Bataevf6a53d62019-03-18 18:40:00 +00003518void CGOpenMPRuntime::getDefaultScheduleAndChunk(
3519 CodeGenFunction &CGF, const OMPLoopDirective &S,
3520 OpenMPScheduleClauseKind &ScheduleKind, const Expr *&ChunkExpr) const {
3521 // Check if the loop directive is actually a doacross loop directive. In this
3522 // case choose static, 1 schedule.
3523 if (llvm::any_of(
3524 S.getClausesOfKind<OMPOrderedClause>(),
3525 [](const OMPOrderedClause *C) { return C->getNumForLoops(); })) {
3526 ScheduleKind = OMPC_SCHEDULE_static;
3527 // Chunk size is 1 in this case.
3528 llvm::APInt ChunkSize(32, 1);
3529 ChunkExpr = IntegerLiteral::Create(
3530 CGF.getContext(), ChunkSize,
3531 CGF.getContext().getIntTypeForBitwidth(32, /*Signed=*/0),
3532 SourceLocation());
3533 }
3534}
3535
Alexey Bataevc3028ca2018-12-04 15:03:25 +00003536void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
3537 OpenMPDirectiveKind Kind, bool EmitChecks,
3538 bool ForceSimpleCall) {
Johannes Doerfertb3c06db2019-11-04 23:00:36 -06003539 // Check if we should use the OMPBuilder
3540 auto *OMPRegionInfo =
3541 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo);
3542 llvm::OpenMPIRBuilder *OMPBuilder = CGF.CGM.getOpenMPIRBuilder();
3543 if (OMPBuilder) {
Johannes Doerfertf9c3c5da2019-12-25 10:33:56 -06003544 CGF.Builder.restoreIP(OMPBuilder->CreateBarrier(
3545 CGF.Builder, Kind, ForceSimpleCall, EmitChecks));
Johannes Doerfertb3c06db2019-11-04 23:00:36 -06003546 return;
3547 }
3548
Alexey Bataevc3028ca2018-12-04 15:03:25 +00003549 if (!CGF.HaveInsertPoint())
3550 return;
3551 // Build call __kmpc_cancel_barrier(loc, thread_id);
3552 // Build call __kmpc_barrier(loc, thread_id);
3553 unsigned Flags = getDefaultFlagsForBarriers(Kind);
Alexey Bataev81c7ea02015-07-03 09:56:58 +00003554 // Build call __kmpc_cancel_barrier(loc, thread_id) or __kmpc_barrier(loc,
3555 // thread_id);
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003556 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc, Flags),
3557 getThreadID(CGF, Loc)};
Johannes Doerfertb3c06db2019-11-04 23:00:36 -06003558 if (OMPRegionInfo) {
Alexey Bataev25e5b442015-09-15 12:52:43 +00003559 if (!ForceSimpleCall && OMPRegionInfo->hasCancel()) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003560 llvm::Value *Result = CGF.EmitRuntimeCall(
Alexey Bataev81c7ea02015-07-03 09:56:58 +00003561 createRuntimeFunction(OMPRTL__kmpc_cancel_barrier), Args);
Alexey Bataev25e5b442015-09-15 12:52:43 +00003562 if (EmitChecks) {
Alexey Bataev81c7ea02015-07-03 09:56:58 +00003563 // if (__kmpc_cancel_barrier()) {
3564 // exit from construct;
3565 // }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003566 llvm::BasicBlock *ExitBB = CGF.createBasicBlock(".cancel.exit");
3567 llvm::BasicBlock *ContBB = CGF.createBasicBlock(".cancel.continue");
3568 llvm::Value *Cmp = CGF.Builder.CreateIsNotNull(Result);
Alexey Bataev81c7ea02015-07-03 09:56:58 +00003569 CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
3570 CGF.EmitBlock(ExitBB);
3571 // exit from construct;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003572 CodeGenFunction::JumpDest CancelDestination =
Alexey Bataev25e5b442015-09-15 12:52:43 +00003573 CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
Alexey Bataev81c7ea02015-07-03 09:56:58 +00003574 CGF.EmitBranchThroughCleanup(CancelDestination);
3575 CGF.EmitBlock(ContBB, /*IsFinished=*/true);
3576 }
3577 return;
3578 }
3579 }
3580 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_barrier), Args);
Alexey Bataev4a5bb772014-10-08 14:01:46 +00003581}
3582
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003583/// Map the OpenMP loop schedule to the runtime enumeration.
Alexander Musmanc6388682014-12-15 07:07:06 +00003584static OpenMPSchedType getRuntimeSchedule(OpenMPScheduleClauseKind ScheduleKind,
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00003585 bool Chunked, bool Ordered) {
Alexander Musmanc6388682014-12-15 07:07:06 +00003586 switch (ScheduleKind) {
3587 case OMPC_SCHEDULE_static:
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00003588 return Chunked ? (Ordered ? OMP_ord_static_chunked : OMP_sch_static_chunked)
3589 : (Ordered ? OMP_ord_static : OMP_sch_static);
Alexander Musmanc6388682014-12-15 07:07:06 +00003590 case OMPC_SCHEDULE_dynamic:
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00003591 return Ordered ? OMP_ord_dynamic_chunked : OMP_sch_dynamic_chunked;
Alexander Musmanc6388682014-12-15 07:07:06 +00003592 case OMPC_SCHEDULE_guided:
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00003593 return Ordered ? OMP_ord_guided_chunked : OMP_sch_guided_chunked;
Alexander Musmanc6388682014-12-15 07:07:06 +00003594 case OMPC_SCHEDULE_runtime:
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00003595 return Ordered ? OMP_ord_runtime : OMP_sch_runtime;
3596 case OMPC_SCHEDULE_auto:
3597 return Ordered ? OMP_ord_auto : OMP_sch_auto;
Alexander Musmanc6388682014-12-15 07:07:06 +00003598 case OMPC_SCHEDULE_unknown:
3599 assert(!Chunked && "chunk was specified but schedule kind not known");
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00003600 return Ordered ? OMP_ord_static : OMP_sch_static;
Alexander Musmanc6388682014-12-15 07:07:06 +00003601 }
3602 llvm_unreachable("Unexpected runtime schedule");
3603}
3604
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003605/// Map the OpenMP distribute schedule to the runtime enumeration.
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003606static OpenMPSchedType
3607getRuntimeSchedule(OpenMPDistScheduleClauseKind ScheduleKind, bool Chunked) {
3608 // only static is allowed for dist_schedule
3609 return Chunked ? OMP_dist_sch_static_chunked : OMP_dist_sch_static;
3610}
3611
Alexander Musmanc6388682014-12-15 07:07:06 +00003612bool CGOpenMPRuntime::isStaticNonchunked(OpenMPScheduleClauseKind ScheduleKind,
3613 bool Chunked) const {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003614 OpenMPSchedType Schedule =
3615 getRuntimeSchedule(ScheduleKind, Chunked, /*Ordered=*/false);
Alexander Musmanc6388682014-12-15 07:07:06 +00003616 return Schedule == OMP_sch_static;
3617}
3618
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003619bool CGOpenMPRuntime::isStaticNonchunked(
3620 OpenMPDistScheduleClauseKind ScheduleKind, bool Chunked) const {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003621 OpenMPSchedType Schedule = getRuntimeSchedule(ScheduleKind, Chunked);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003622 return Schedule == OMP_dist_sch_static;
3623}
3624
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00003625bool CGOpenMPRuntime::isStaticChunked(OpenMPScheduleClauseKind ScheduleKind,
3626 bool Chunked) const {
3627 OpenMPSchedType Schedule =
3628 getRuntimeSchedule(ScheduleKind, Chunked, /*Ordered=*/false);
3629 return Schedule == OMP_sch_static_chunked;
3630}
3631
3632bool CGOpenMPRuntime::isStaticChunked(
3633 OpenMPDistScheduleClauseKind ScheduleKind, bool Chunked) const {
3634 OpenMPSchedType Schedule = getRuntimeSchedule(ScheduleKind, Chunked);
3635 return Schedule == OMP_dist_sch_static_chunked;
3636}
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003637
Alexander Musmandf7a8e22015-01-22 08:49:35 +00003638bool CGOpenMPRuntime::isDynamic(OpenMPScheduleClauseKind ScheduleKind) const {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003639 OpenMPSchedType Schedule =
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00003640 getRuntimeSchedule(ScheduleKind, /*Chunked=*/false, /*Ordered=*/false);
Alexander Musmandf7a8e22015-01-22 08:49:35 +00003641 assert(Schedule != OMP_sch_static_chunked && "cannot be chunked here");
3642 return Schedule != OMP_sch_static;
3643}
3644
Alexey Bataev07a3b592019-08-23 19:52:05 +00003645static int addMonoNonMonoModifier(CodeGenModule &CGM, OpenMPSchedType Schedule,
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003646 OpenMPScheduleClauseModifier M1,
3647 OpenMPScheduleClauseModifier M2) {
Alexey Bataev6cff6242016-05-30 13:05:14 +00003648 int Modifier = 0;
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003649 switch (M1) {
3650 case OMPC_SCHEDULE_MODIFIER_monotonic:
Alexey Bataev6cff6242016-05-30 13:05:14 +00003651 Modifier = OMP_sch_modifier_monotonic;
3652 break;
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003653 case OMPC_SCHEDULE_MODIFIER_nonmonotonic:
Alexey Bataev6cff6242016-05-30 13:05:14 +00003654 Modifier = OMP_sch_modifier_nonmonotonic;
3655 break;
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003656 case OMPC_SCHEDULE_MODIFIER_simd:
Alexey Bataev6cff6242016-05-30 13:05:14 +00003657 if (Schedule == OMP_sch_static_chunked)
3658 Schedule = OMP_sch_static_balanced_chunked;
3659 break;
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003660 case OMPC_SCHEDULE_MODIFIER_last:
3661 case OMPC_SCHEDULE_MODIFIER_unknown:
3662 break;
3663 }
3664 switch (M2) {
3665 case OMPC_SCHEDULE_MODIFIER_monotonic:
Alexey Bataev6cff6242016-05-30 13:05:14 +00003666 Modifier = OMP_sch_modifier_monotonic;
3667 break;
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003668 case OMPC_SCHEDULE_MODIFIER_nonmonotonic:
Alexey Bataev6cff6242016-05-30 13:05:14 +00003669 Modifier = OMP_sch_modifier_nonmonotonic;
3670 break;
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003671 case OMPC_SCHEDULE_MODIFIER_simd:
Alexey Bataev6cff6242016-05-30 13:05:14 +00003672 if (Schedule == OMP_sch_static_chunked)
3673 Schedule = OMP_sch_static_balanced_chunked;
3674 break;
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003675 case OMPC_SCHEDULE_MODIFIER_last:
3676 case OMPC_SCHEDULE_MODIFIER_unknown:
3677 break;
3678 }
Alexey Bataev07a3b592019-08-23 19:52:05 +00003679 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Desription.
3680 // If the static schedule kind is specified or if the ordered clause is
3681 // specified, and if the nonmonotonic modifier is not specified, the effect is
3682 // as if the monotonic modifier is specified. Otherwise, unless the monotonic
3683 // modifier is specified, the effect is as if the nonmonotonic modifier is
3684 // specified.
3685 if (CGM.getLangOpts().OpenMP >= 50 && Modifier == 0) {
3686 if (!(Schedule == OMP_sch_static_chunked || Schedule == OMP_sch_static ||
3687 Schedule == OMP_sch_static_balanced_chunked ||
Alexey Bataevc3eded02019-11-18 11:13:08 -05003688 Schedule == OMP_ord_static_chunked || Schedule == OMP_ord_static ||
3689 Schedule == OMP_dist_sch_static_chunked ||
3690 Schedule == OMP_dist_sch_static))
Alexey Bataev07a3b592019-08-23 19:52:05 +00003691 Modifier = OMP_sch_modifier_nonmonotonic;
3692 }
Alexey Bataev6cff6242016-05-30 13:05:14 +00003693 return Schedule | Modifier;
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003694}
3695
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003696void CGOpenMPRuntime::emitForDispatchInit(
3697 CodeGenFunction &CGF, SourceLocation Loc,
3698 const OpenMPScheduleTy &ScheduleKind, unsigned IVSize, bool IVSigned,
3699 bool Ordered, const DispatchRTInput &DispatchValues) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003700 if (!CGF.HaveInsertPoint())
3701 return;
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003702 OpenMPSchedType Schedule = getRuntimeSchedule(
3703 ScheduleKind.Schedule, DispatchValues.Chunk != nullptr, Ordered);
John McCall7f416cc2015-09-08 08:05:57 +00003704 assert(Ordered ||
3705 (Schedule != OMP_sch_static && Schedule != OMP_sch_static_chunked &&
Alexey Bataev6cff6242016-05-30 13:05:14 +00003706 Schedule != OMP_ord_static && Schedule != OMP_ord_static_chunked &&
3707 Schedule != OMP_sch_static_balanced_chunked));
John McCall7f416cc2015-09-08 08:05:57 +00003708 // Call __kmpc_dispatch_init(
3709 // ident_t *loc, kmp_int32 tid, kmp_int32 schedule,
3710 // kmp_int[32|64] lower, kmp_int[32|64] upper,
3711 // kmp_int[32|64] stride, kmp_int[32|64] chunk);
Alexander Musmanc6388682014-12-15 07:07:06 +00003712
John McCall7f416cc2015-09-08 08:05:57 +00003713 // If the Chunk was not specified in the clause - use default value 1.
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003714 llvm::Value *Chunk = DispatchValues.Chunk ? DispatchValues.Chunk
3715 : CGF.Builder.getIntN(IVSize, 1);
John McCall7f416cc2015-09-08 08:05:57 +00003716 llvm::Value *Args[] = {
Alexey Bataev07a3b592019-08-23 19:52:05 +00003717 emitUpdateLocation(CGF, Loc),
3718 getThreadID(CGF, Loc),
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003719 CGF.Builder.getInt32(addMonoNonMonoModifier(
Alexey Bataev07a3b592019-08-23 19:52:05 +00003720 CGM, Schedule, ScheduleKind.M1, ScheduleKind.M2)), // Schedule type
3721 DispatchValues.LB, // Lower
3722 DispatchValues.UB, // Upper
3723 CGF.Builder.getIntN(IVSize, 1), // Stride
3724 Chunk // Chunk
John McCall7f416cc2015-09-08 08:05:57 +00003725 };
3726 CGF.EmitRuntimeCall(createDispatchInitFunction(IVSize, IVSigned), Args);
3727}
3728
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003729static void emitForStaticInitCall(
3730 CodeGenFunction &CGF, llvm::Value *UpdateLocation, llvm::Value *ThreadId,
James Y Knight9871db02019-02-05 16:42:33 +00003731 llvm::FunctionCallee ForStaticInitFunction, OpenMPSchedType Schedule,
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003732 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003733 const CGOpenMPRuntime::StaticRTInput &Values) {
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003734 if (!CGF.HaveInsertPoint())
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003735 return;
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003736
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003737 assert(!Values.Ordered);
3738 assert(Schedule == OMP_sch_static || Schedule == OMP_sch_static_chunked ||
3739 Schedule == OMP_sch_static_balanced_chunked ||
3740 Schedule == OMP_ord_static || Schedule == OMP_ord_static_chunked ||
3741 Schedule == OMP_dist_sch_static ||
3742 Schedule == OMP_dist_sch_static_chunked);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003743
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003744 // Call __kmpc_for_static_init(
3745 // ident_t *loc, kmp_int32 tid, kmp_int32 schedtype,
3746 // kmp_int32 *p_lastiter, kmp_int[32|64] *p_lower,
3747 // kmp_int[32|64] *p_upper, kmp_int[32|64] *p_stride,
3748 // kmp_int[32|64] incr, kmp_int[32|64] chunk);
3749 llvm::Value *Chunk = Values.Chunk;
3750 if (Chunk == nullptr) {
3751 assert((Schedule == OMP_sch_static || Schedule == OMP_ord_static ||
3752 Schedule == OMP_dist_sch_static) &&
3753 "expected static non-chunked schedule");
3754 // If the Chunk was not specified in the clause - use default value 1.
3755 Chunk = CGF.Builder.getIntN(Values.IVSize, 1);
3756 } else {
3757 assert((Schedule == OMP_sch_static_chunked ||
3758 Schedule == OMP_sch_static_balanced_chunked ||
3759 Schedule == OMP_ord_static_chunked ||
3760 Schedule == OMP_dist_sch_static_chunked) &&
3761 "expected static chunked schedule");
3762 }
3763 llvm::Value *Args[] = {
3764 UpdateLocation,
3765 ThreadId,
Alexey Bataev07a3b592019-08-23 19:52:05 +00003766 CGF.Builder.getInt32(addMonoNonMonoModifier(CGF.CGM, Schedule, M1,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003767 M2)), // Schedule type
3768 Values.IL.getPointer(), // &isLastIter
3769 Values.LB.getPointer(), // &LB
3770 Values.UB.getPointer(), // &UB
3771 Values.ST.getPointer(), // &Stride
3772 CGF.Builder.getIntN(Values.IVSize, 1), // Incr
3773 Chunk // Chunk
3774 };
3775 CGF.EmitRuntimeCall(ForStaticInitFunction, Args);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003776}
3777
John McCall7f416cc2015-09-08 08:05:57 +00003778void CGOpenMPRuntime::emitForStaticInit(CodeGenFunction &CGF,
3779 SourceLocation Loc,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003780 OpenMPDirectiveKind DKind,
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003781 const OpenMPScheduleTy &ScheduleKind,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003782 const StaticRTInput &Values) {
3783 OpenMPSchedType ScheduleNum = getRuntimeSchedule(
3784 ScheduleKind.Schedule, Values.Chunk != nullptr, Values.Ordered);
3785 assert(isOpenMPWorksharingDirective(DKind) &&
3786 "Expected loop-based or sections-based directive.");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003787 llvm::Value *UpdatedLocation = emitUpdateLocation(CGF, Loc,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003788 isOpenMPLoopDirective(DKind)
3789 ? OMP_IDENT_WORK_LOOP
3790 : OMP_IDENT_WORK_SECTIONS);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003791 llvm::Value *ThreadId = getThreadID(CGF, Loc);
James Y Knight9871db02019-02-05 16:42:33 +00003792 llvm::FunctionCallee StaticInitFunction =
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003793 createForStaticInitFunction(Values.IVSize, Values.IVSigned);
Alexey Bataevc33ba8c2020-01-17 14:05:40 -05003794 auto DL = ApplyDebugLocation::CreateDefaultArtificial(CGF, Loc);
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003795 emitForStaticInitCall(CGF, UpdatedLocation, ThreadId, StaticInitFunction,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003796 ScheduleNum, ScheduleKind.M1, ScheduleKind.M2, Values);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003797}
John McCall7f416cc2015-09-08 08:05:57 +00003798
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003799void CGOpenMPRuntime::emitDistributeStaticInit(
3800 CodeGenFunction &CGF, SourceLocation Loc,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003801 OpenMPDistScheduleClauseKind SchedKind,
3802 const CGOpenMPRuntime::StaticRTInput &Values) {
3803 OpenMPSchedType ScheduleNum =
3804 getRuntimeSchedule(SchedKind, Values.Chunk != nullptr);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003805 llvm::Value *UpdatedLocation =
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003806 emitUpdateLocation(CGF, Loc, OMP_IDENT_WORK_DISTRIBUTE);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003807 llvm::Value *ThreadId = getThreadID(CGF, Loc);
James Y Knight9871db02019-02-05 16:42:33 +00003808 llvm::FunctionCallee StaticInitFunction =
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003809 createForStaticInitFunction(Values.IVSize, Values.IVSigned);
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003810 emitForStaticInitCall(CGF, UpdatedLocation, ThreadId, StaticInitFunction,
3811 ScheduleNum, OMPC_SCHEDULE_MODIFIER_unknown,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003812 OMPC_SCHEDULE_MODIFIER_unknown, Values);
Alexander Musmanc6388682014-12-15 07:07:06 +00003813}
3814
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003815void CGOpenMPRuntime::emitForStaticFinish(CodeGenFunction &CGF,
Alexey Bataevf43f7142017-09-06 16:17:35 +00003816 SourceLocation Loc,
3817 OpenMPDirectiveKind DKind) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003818 if (!CGF.HaveInsertPoint())
3819 return;
Alexander Musmanc6388682014-12-15 07:07:06 +00003820 // Call __kmpc_for_static_fini(ident_t *loc, kmp_int32 tid);
Alexey Bataevf43f7142017-09-06 16:17:35 +00003821 llvm::Value *Args[] = {
3822 emitUpdateLocation(CGF, Loc,
3823 isOpenMPDistributeDirective(DKind)
3824 ? OMP_IDENT_WORK_DISTRIBUTE
3825 : isOpenMPLoopDirective(DKind)
3826 ? OMP_IDENT_WORK_LOOP
3827 : OMP_IDENT_WORK_SECTIONS),
3828 getThreadID(CGF, Loc)};
Alexey Bataevc33ba8c2020-01-17 14:05:40 -05003829 auto DL = ApplyDebugLocation::CreateDefaultArtificial(CGF, Loc);
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003830 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_for_static_fini),
3831 Args);
Alexander Musmanc6388682014-12-15 07:07:06 +00003832}
3833
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00003834void CGOpenMPRuntime::emitForOrderedIterationEnd(CodeGenFunction &CGF,
3835 SourceLocation Loc,
3836 unsigned IVSize,
3837 bool IVSigned) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003838 if (!CGF.HaveInsertPoint())
3839 return;
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003840 // Call __kmpc_for_dynamic_fini_(4|8)[u](ident_t *loc, kmp_int32 tid);
Alexey Bataev50b3c952016-02-19 10:38:26 +00003841 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003842 CGF.EmitRuntimeCall(createDispatchFiniFunction(IVSize, IVSigned), Args);
3843}
3844
Alexander Musman92bdaab2015-03-12 13:37:50 +00003845llvm::Value *CGOpenMPRuntime::emitForNext(CodeGenFunction &CGF,
3846 SourceLocation Loc, unsigned IVSize,
John McCall7f416cc2015-09-08 08:05:57 +00003847 bool IVSigned, Address IL,
3848 Address LB, Address UB,
3849 Address ST) {
Alexander Musman92bdaab2015-03-12 13:37:50 +00003850 // Call __kmpc_dispatch_next(
3851 // ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter,
3852 // kmp_int[32|64] *p_lower, kmp_int[32|64] *p_upper,
3853 // kmp_int[32|64] *p_stride);
3854 llvm::Value *Args[] = {
Alexey Bataev50b3c952016-02-19 10:38:26 +00003855 emitUpdateLocation(CGF, Loc),
3856 getThreadID(CGF, Loc),
John McCall7f416cc2015-09-08 08:05:57 +00003857 IL.getPointer(), // &isLastIter
3858 LB.getPointer(), // &Lower
3859 UB.getPointer(), // &Upper
3860 ST.getPointer() // &Stride
Alexander Musman92bdaab2015-03-12 13:37:50 +00003861 };
3862 llvm::Value *Call =
3863 CGF.EmitRuntimeCall(createDispatchNextFunction(IVSize, IVSigned), Args);
3864 return CGF.EmitScalarConversion(
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003865 Call, CGF.getContext().getIntTypeForBitwidth(32, /*Signed=*/1),
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003866 CGF.getContext().BoolTy, Loc);
Alexander Musman92bdaab2015-03-12 13:37:50 +00003867}
3868
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003869void CGOpenMPRuntime::emitNumThreadsClause(CodeGenFunction &CGF,
3870 llvm::Value *NumThreads,
3871 SourceLocation Loc) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003872 if (!CGF.HaveInsertPoint())
3873 return;
Alexey Bataevb2059782014-10-13 08:23:51 +00003874 // Build call __kmpc_push_num_threads(&loc, global_tid, num_threads)
3875 llvm::Value *Args[] = {
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003876 emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
Alexey Bataevb2059782014-10-13 08:23:51 +00003877 CGF.Builder.CreateIntCast(NumThreads, CGF.Int32Ty, /*isSigned*/ true)};
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003878 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_push_num_threads),
3879 Args);
Alexey Bataevb2059782014-10-13 08:23:51 +00003880}
3881
Alexey Bataev7f210c62015-06-18 13:40:03 +00003882void CGOpenMPRuntime::emitProcBindClause(CodeGenFunction &CGF,
Johannes Doerfert6c5d1f402019-12-25 18:15:36 -06003883 ProcBindKind ProcBind,
Alexey Bataev7f210c62015-06-18 13:40:03 +00003884 SourceLocation Loc) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003885 if (!CGF.HaveInsertPoint())
3886 return;
Johannes Doerfert6c5d1f402019-12-25 18:15:36 -06003887 assert(ProcBind != OMP_PROC_BIND_unknown && "Unsupported proc_bind value.");
Alexey Bataev7f210c62015-06-18 13:40:03 +00003888 // Build call __kmpc_push_proc_bind(&loc, global_tid, proc_bind)
3889 llvm::Value *Args[] = {
3890 emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
Johannes Doerfert6c5d1f402019-12-25 18:15:36 -06003891 llvm::ConstantInt::get(CGM.IntTy, unsigned(ProcBind), /*isSigned=*/true)};
Alexey Bataev7f210c62015-06-18 13:40:03 +00003892 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_push_proc_bind), Args);
3893}
3894
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003895void CGOpenMPRuntime::emitFlush(CodeGenFunction &CGF, ArrayRef<const Expr *>,
Alexey Bataeve8e05de2020-02-07 12:22:23 -05003896 SourceLocation Loc, llvm::AtomicOrdering AO) {
Kiran Chandramohana969e052020-02-04 21:43:40 +00003897 llvm::OpenMPIRBuilder *OMPBuilder = CGF.CGM.getOpenMPIRBuilder();
3898 if (OMPBuilder) {
3899 OMPBuilder->CreateFlush(CGF.Builder);
3900 } else {
3901 if (!CGF.HaveInsertPoint())
3902 return;
3903 // Build call void __kmpc_flush(ident_t *loc)
3904 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_flush),
3905 emitUpdateLocation(CGF, Loc));
3906 }
Alexey Bataevcc37cc12014-11-20 04:34:54 +00003907}
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003908
Alexey Bataev62b63b12015-03-10 07:28:44 +00003909namespace {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003910/// Indexes of fields for type kmp_task_t.
Alexey Bataev62b63b12015-03-10 07:28:44 +00003911enum KmpTaskTFields {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003912 /// List of shared variables.
Alexey Bataev62b63b12015-03-10 07:28:44 +00003913 KmpTaskTShareds,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003914 /// Task routine.
Alexey Bataev62b63b12015-03-10 07:28:44 +00003915 KmpTaskTRoutine,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003916 /// Partition id for the untied tasks.
Alexey Bataev62b63b12015-03-10 07:28:44 +00003917 KmpTaskTPartId,
Alexey Bataevad537bb2016-05-30 09:06:50 +00003918 /// Function with call of destructors for private variables.
3919 Data1,
3920 /// Task priority.
3921 Data2,
Alexey Bataev7292c292016-04-25 12:22:29 +00003922 /// (Taskloops only) Lower bound.
3923 KmpTaskTLowerBound,
3924 /// (Taskloops only) Upper bound.
3925 KmpTaskTUpperBound,
3926 /// (Taskloops only) Stride.
3927 KmpTaskTStride,
3928 /// (Taskloops only) Is last iteration flag.
3929 KmpTaskTLastIter,
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00003930 /// (Taskloops only) Reduction data.
3931 KmpTaskTReductions,
Alexey Bataev62b63b12015-03-10 07:28:44 +00003932};
Hans Wennborg7eb54642015-09-10 17:07:54 +00003933} // anonymous namespace
Alexey Bataev62b63b12015-03-10 07:28:44 +00003934
Samuel Antaoee8fb302016-01-06 13:42:12 +00003935bool CGOpenMPRuntime::OffloadEntriesInfoManagerTy::empty() const {
Alexey Bataev03f270c2018-03-30 18:31:07 +00003936 return OffloadEntriesTargetRegion.empty() &&
3937 OffloadEntriesDeviceGlobalVar.empty();
Samuel Antaoee8fb302016-01-06 13:42:12 +00003938}
3939
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003940/// Initialize target region entry.
Samuel Antaoee8fb302016-01-06 13:42:12 +00003941void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3942 initializeTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
3943 StringRef ParentName, unsigned LineNum,
Samuel Antao2de62b02016-02-13 23:35:10 +00003944 unsigned Order) {
Samuel Antaoee8fb302016-01-06 13:42:12 +00003945 assert(CGM.getLangOpts().OpenMPIsDevice && "Initialization of entries is "
3946 "only required for the device "
3947 "code generation.");
Samuel Antao2de62b02016-02-13 23:35:10 +00003948 OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum] =
Samuel Antaof83efdb2017-01-05 16:02:49 +00003949 OffloadEntryInfoTargetRegion(Order, /*Addr=*/nullptr, /*ID=*/nullptr,
Alexey Bataev34f8a702018-03-28 14:28:54 +00003950 OMPTargetRegionEntryTargetRegion);
Samuel Antaoee8fb302016-01-06 13:42:12 +00003951 ++OffloadingEntriesNum;
3952}
3953
3954void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3955 registerTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
3956 StringRef ParentName, unsigned LineNum,
Samuel Antaof83efdb2017-01-05 16:02:49 +00003957 llvm::Constant *Addr, llvm::Constant *ID,
Alexey Bataev34f8a702018-03-28 14:28:54 +00003958 OMPTargetRegionEntryKind Flags) {
Samuel Antaoee8fb302016-01-06 13:42:12 +00003959 // If we are emitting code for a target, the entry is already initialized,
3960 // only has to be registered.
3961 if (CGM.getLangOpts().OpenMPIsDevice) {
Alexey Bataev64e62dc2018-04-30 16:26:57 +00003962 if (!hasTargetRegionEntryInfo(DeviceID, FileID, ParentName, LineNum)) {
3963 unsigned DiagID = CGM.getDiags().getCustomDiagID(
3964 DiagnosticsEngine::Error,
3965 "Unable to find target region on line '%0' in the device code.");
3966 CGM.getDiags().Report(DiagID) << LineNum;
3967 return;
3968 }
Samuel Antao2de62b02016-02-13 23:35:10 +00003969 auto &Entry =
3970 OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum];
Samuel Antaoee8fb302016-01-06 13:42:12 +00003971 assert(Entry.isValid() && "Entry not initialized!");
3972 Entry.setAddress(Addr);
3973 Entry.setID(ID);
Samuel Antaof83efdb2017-01-05 16:02:49 +00003974 Entry.setFlags(Flags);
Samuel Antaoee8fb302016-01-06 13:42:12 +00003975 } else {
Alexey Bataev03f270c2018-03-30 18:31:07 +00003976 OffloadEntryInfoTargetRegion Entry(OffloadingEntriesNum, Addr, ID, Flags);
Samuel Antao2de62b02016-02-13 23:35:10 +00003977 OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum] = Entry;
Alexey Bataev03f270c2018-03-30 18:31:07 +00003978 ++OffloadingEntriesNum;
Samuel Antaoee8fb302016-01-06 13:42:12 +00003979 }
3980}
3981
3982bool CGOpenMPRuntime::OffloadEntriesInfoManagerTy::hasTargetRegionEntryInfo(
Samuel Antao2de62b02016-02-13 23:35:10 +00003983 unsigned DeviceID, unsigned FileID, StringRef ParentName,
3984 unsigned LineNum) const {
Samuel Antaoee8fb302016-01-06 13:42:12 +00003985 auto PerDevice = OffloadEntriesTargetRegion.find(DeviceID);
3986 if (PerDevice == OffloadEntriesTargetRegion.end())
3987 return false;
3988 auto PerFile = PerDevice->second.find(FileID);
3989 if (PerFile == PerDevice->second.end())
3990 return false;
3991 auto PerParentName = PerFile->second.find(ParentName);
3992 if (PerParentName == PerFile->second.end())
3993 return false;
3994 auto PerLine = PerParentName->second.find(LineNum);
3995 if (PerLine == PerParentName->second.end())
3996 return false;
Samuel Antaoee8fb302016-01-06 13:42:12 +00003997 // Fail if this entry is already registered.
Samuel Antao2de62b02016-02-13 23:35:10 +00003998 if (PerLine->second.getAddress() || PerLine->second.getID())
Samuel Antaoee8fb302016-01-06 13:42:12 +00003999 return false;
4000 return true;
4001}
4002
4003void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::actOnTargetRegionEntriesInfo(
4004 const OffloadTargetRegionEntryInfoActTy &Action) {
4005 // Scan all target region entries and perform the provided action.
Alexey Bataev03f270c2018-03-30 18:31:07 +00004006 for (const auto &D : OffloadEntriesTargetRegion)
4007 for (const auto &F : D.second)
4008 for (const auto &P : F.second)
4009 for (const auto &L : P.second)
Samuel Antao2de62b02016-02-13 23:35:10 +00004010 Action(D.first, F.first, P.first(), L.first, L.second);
Samuel Antaoee8fb302016-01-06 13:42:12 +00004011}
4012
Alexey Bataev03f270c2018-03-30 18:31:07 +00004013void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
4014 initializeDeviceGlobalVarEntryInfo(StringRef Name,
4015 OMPTargetGlobalVarEntryKind Flags,
4016 unsigned Order) {
4017 assert(CGM.getLangOpts().OpenMPIsDevice && "Initialization of entries is "
4018 "only required for the device "
4019 "code generation.");
4020 OffloadEntriesDeviceGlobalVar.try_emplace(Name, Order, Flags);
4021 ++OffloadingEntriesNum;
4022}
Samuel Antaoee8fb302016-01-06 13:42:12 +00004023
Alexey Bataev03f270c2018-03-30 18:31:07 +00004024void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
4025 registerDeviceGlobalVarEntryInfo(StringRef VarName, llvm::Constant *Addr,
4026 CharUnits VarSize,
4027 OMPTargetGlobalVarEntryKind Flags,
4028 llvm::GlobalValue::LinkageTypes Linkage) {
4029 if (CGM.getLangOpts().OpenMPIsDevice) {
4030 auto &Entry = OffloadEntriesDeviceGlobalVar[VarName];
4031 assert(Entry.isValid() && Entry.getFlags() == Flags &&
4032 "Entry not initialized!");
4033 assert((!Entry.getAddress() || Entry.getAddress() == Addr) &&
4034 "Resetting with the new address.");
Alexey Bataev8259cc32019-03-12 20:05:17 +00004035 if (Entry.getAddress() && hasDeviceGlobalVarEntryInfo(VarName)) {
4036 if (Entry.getVarSize().isZero()) {
4037 Entry.setVarSize(VarSize);
4038 Entry.setLinkage(Linkage);
4039 }
Alexey Bataev03f270c2018-03-30 18:31:07 +00004040 return;
Alexey Bataev8259cc32019-03-12 20:05:17 +00004041 }
Alexey Bataev03f270c2018-03-30 18:31:07 +00004042 Entry.setVarSize(VarSize);
4043 Entry.setLinkage(Linkage);
Alexey Bataev8259cc32019-03-12 20:05:17 +00004044 Entry.setAddress(Addr);
Alexey Bataev03f270c2018-03-30 18:31:07 +00004045 } else {
Alexey Bataev8259cc32019-03-12 20:05:17 +00004046 if (hasDeviceGlobalVarEntryInfo(VarName)) {
4047 auto &Entry = OffloadEntriesDeviceGlobalVar[VarName];
4048 assert(Entry.isValid() && Entry.getFlags() == Flags &&
4049 "Entry not initialized!");
4050 assert((!Entry.getAddress() || Entry.getAddress() == Addr) &&
4051 "Resetting with the new address.");
4052 if (Entry.getVarSize().isZero()) {
4053 Entry.setVarSize(VarSize);
4054 Entry.setLinkage(Linkage);
4055 }
Alexey Bataev03f270c2018-03-30 18:31:07 +00004056 return;
Alexey Bataev8259cc32019-03-12 20:05:17 +00004057 }
Alexey Bataev03f270c2018-03-30 18:31:07 +00004058 OffloadEntriesDeviceGlobalVar.try_emplace(
4059 VarName, OffloadingEntriesNum, Addr, VarSize, Flags, Linkage);
4060 ++OffloadingEntriesNum;
4061 }
4062}
4063
4064void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
4065 actOnDeviceGlobalVarEntriesInfo(
4066 const OffloadDeviceGlobalVarEntryInfoActTy &Action) {
4067 // Scan all target region entries and perform the provided action.
4068 for (const auto &E : OffloadEntriesDeviceGlobalVar)
4069 Action(E.getKey(), E.getValue());
Samuel Antaoee8fb302016-01-06 13:42:12 +00004070}
4071
Alexey Bataev03f270c2018-03-30 18:31:07 +00004072void CGOpenMPRuntime::createOffloadEntry(
4073 llvm::Constant *ID, llvm::Constant *Addr, uint64_t Size, int32_t Flags,
4074 llvm::GlobalValue::LinkageTypes Linkage) {
Samuel Antao2de62b02016-02-13 23:35:10 +00004075 StringRef Name = Addr->getName();
Samuel Antaoee8fb302016-01-06 13:42:12 +00004076 llvm::Module &M = CGM.getModule();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004077 llvm::LLVMContext &C = M.getContext();
Samuel Antaoee8fb302016-01-06 13:42:12 +00004078
4079 // Create constant string with the name.
4080 llvm::Constant *StrPtrInit = llvm::ConstantDataArray::getString(C, Name);
4081
Alexey Bataev18fa2322018-05-02 14:20:50 +00004082 std::string StringName = getName({"omp_offloading", "entry_name"});
4083 auto *Str = new llvm::GlobalVariable(
4084 M, StrPtrInit->getType(), /*isConstant=*/true,
4085 llvm::GlobalValue::InternalLinkage, StrPtrInit, StringName);
Peter Collingbournebcf909d2016-06-14 21:02:05 +00004086 Str->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
Samuel Antaoee8fb302016-01-06 13:42:12 +00004087
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004088 llvm::Constant *Data[] = {llvm::ConstantExpr::getBitCast(ID, CGM.VoidPtrTy),
4089 llvm::ConstantExpr::getBitCast(Str, CGM.Int8PtrTy),
4090 llvm::ConstantInt::get(CGM.SizeTy, Size),
4091 llvm::ConstantInt::get(CGM.Int32Ty, Flags),
4092 llvm::ConstantInt::get(CGM.Int32Ty, 0)};
Alexey Bataev18fa2322018-05-02 14:20:50 +00004093 std::string EntryName = getName({"omp_offloading", "entry", ""});
Mike Ricee1ca7b62018-08-29 15:45:11 +00004094 llvm::GlobalVariable *Entry = createGlobalStruct(
4095 CGM, getTgtOffloadEntryQTy(), /*IsConstant=*/true, Data,
4096 Twine(EntryName).concat(Name), llvm::GlobalValue::WeakAnyLinkage);
Samuel Antaoee8fb302016-01-06 13:42:12 +00004097
4098 // The entry has to be created in the section the linker expects it to be.
Sergey Dmitriev4b343fd2019-09-27 20:00:51 +00004099 Entry->setSection("omp_offloading_entries");
Samuel Antaoee8fb302016-01-06 13:42:12 +00004100}
4101
4102void CGOpenMPRuntime::createOffloadEntriesAndInfoMetadata() {
4103 // Emit the offloading entries and metadata so that the device codegen side
Samuel Antao4c8035b2016-12-12 18:00:20 +00004104 // can easily figure out what to emit. The produced metadata looks like
4105 // this:
Samuel Antaoee8fb302016-01-06 13:42:12 +00004106 //
4107 // !omp_offload.info = !{!1, ...}
4108 //
4109 // Right now we only generate metadata for function that contain target
4110 // regions.
4111
Sergey Dmitriev5836c352019-10-15 18:42:47 +00004112 // If we are in simd mode or there are no entries, we don't need to do
4113 // anything.
4114 if (CGM.getLangOpts().OpenMPSimd || OffloadEntriesInfoManager.empty())
Samuel Antaoee8fb302016-01-06 13:42:12 +00004115 return;
4116
4117 llvm::Module &M = CGM.getModule();
4118 llvm::LLVMContext &C = M.getContext();
Alexey Bataevba643691d2019-10-03 16:20:34 +00004119 SmallVector<std::tuple<const OffloadEntriesInfoManagerTy::OffloadEntryInfo *,
4120 SourceLocation, StringRef>,
4121 16>
Samuel Antaoee8fb302016-01-06 13:42:12 +00004122 OrderedEntries(OffloadEntriesInfoManager.size());
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00004123 llvm::SmallVector<StringRef, 16> ParentFunctions(
4124 OffloadEntriesInfoManager.size());
Samuel Antaoee8fb302016-01-06 13:42:12 +00004125
Simon Pilgrim2c518802017-03-30 14:13:19 +00004126 // Auxiliary methods to create metadata values and strings.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004127 auto &&GetMDInt = [this](unsigned V) {
Samuel Antaoee8fb302016-01-06 13:42:12 +00004128 return llvm::ConstantAsMetadata::get(
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004129 llvm::ConstantInt::get(CGM.Int32Ty, V));
Samuel Antaoee8fb302016-01-06 13:42:12 +00004130 };
4131
Alexey Bataev03f270c2018-03-30 18:31:07 +00004132 auto &&GetMDString = [&C](StringRef V) { return llvm::MDString::get(C, V); };
4133
4134 // Create the offloading info metadata node.
4135 llvm::NamedMDNode *MD = M.getOrInsertNamedMetadata("omp_offload.info");
Samuel Antaoee8fb302016-01-06 13:42:12 +00004136
4137 // Create function that emits metadata for each target region entry;
Alexey Bataev03f270c2018-03-30 18:31:07 +00004138 auto &&TargetRegionMetadataEmitter =
Alexey Bataevba643691d2019-10-03 16:20:34 +00004139 [this, &C, MD, &OrderedEntries, &ParentFunctions, &GetMDInt,
4140 &GetMDString](
Alexey Bataev03f270c2018-03-30 18:31:07 +00004141 unsigned DeviceID, unsigned FileID, StringRef ParentName,
4142 unsigned Line,
4143 const OffloadEntriesInfoManagerTy::OffloadEntryInfoTargetRegion &E) {
4144 // Generate metadata for target regions. Each entry of this metadata
4145 // contains:
4146 // - Entry 0 -> Kind of this type of metadata (0).
4147 // - Entry 1 -> Device ID of the file where the entry was identified.
4148 // - Entry 2 -> File ID of the file where the entry was identified.
4149 // - Entry 3 -> Mangled name of the function where the entry was
4150 // identified.
4151 // - Entry 4 -> Line in the file where the entry was identified.
4152 // - Entry 5 -> Order the entry was created.
4153 // The first element of the metadata node is the kind.
4154 llvm::Metadata *Ops[] = {GetMDInt(E.getKind()), GetMDInt(DeviceID),
4155 GetMDInt(FileID), GetMDString(ParentName),
4156 GetMDInt(Line), GetMDInt(E.getOrder())};
Samuel Antaoee8fb302016-01-06 13:42:12 +00004157
Alexey Bataevba643691d2019-10-03 16:20:34 +00004158 SourceLocation Loc;
4159 for (auto I = CGM.getContext().getSourceManager().fileinfo_begin(),
4160 E = CGM.getContext().getSourceManager().fileinfo_end();
4161 I != E; ++I) {
4162 if (I->getFirst()->getUniqueID().getDevice() == DeviceID &&
4163 I->getFirst()->getUniqueID().getFile() == FileID) {
4164 Loc = CGM.getContext().getSourceManager().translateFileLineCol(
4165 I->getFirst(), Line, 1);
4166 break;
4167 }
4168 }
Alexey Bataev03f270c2018-03-30 18:31:07 +00004169 // Save this entry in the right position of the ordered entries array.
Alexey Bataevba643691d2019-10-03 16:20:34 +00004170 OrderedEntries[E.getOrder()] = std::make_tuple(&E, Loc, ParentName);
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00004171 ParentFunctions[E.getOrder()] = ParentName;
Samuel Antaoee8fb302016-01-06 13:42:12 +00004172
Alexey Bataev03f270c2018-03-30 18:31:07 +00004173 // Add metadata to the named metadata node.
4174 MD->addOperand(llvm::MDNode::get(C, Ops));
4175 };
Samuel Antaoee8fb302016-01-06 13:42:12 +00004176
4177 OffloadEntriesInfoManager.actOnTargetRegionEntriesInfo(
4178 TargetRegionMetadataEmitter);
4179
Alexey Bataev03f270c2018-03-30 18:31:07 +00004180 // Create function that emits metadata for each device global variable entry;
4181 auto &&DeviceGlobalVarMetadataEmitter =
4182 [&C, &OrderedEntries, &GetMDInt, &GetMDString,
4183 MD](StringRef MangledName,
4184 const OffloadEntriesInfoManagerTy::OffloadEntryInfoDeviceGlobalVar
4185 &E) {
4186 // Generate metadata for global variables. Each entry of this metadata
4187 // contains:
4188 // - Entry 0 -> Kind of this type of metadata (1).
4189 // - Entry 1 -> Mangled name of the variable.
4190 // - Entry 2 -> Declare target kind.
4191 // - Entry 3 -> Order the entry was created.
4192 // The first element of the metadata node is the kind.
4193 llvm::Metadata *Ops[] = {
4194 GetMDInt(E.getKind()), GetMDString(MangledName),
4195 GetMDInt(E.getFlags()), GetMDInt(E.getOrder())};
4196
4197 // Save this entry in the right position of the ordered entries array.
Alexey Bataevba643691d2019-10-03 16:20:34 +00004198 OrderedEntries[E.getOrder()] =
4199 std::make_tuple(&E, SourceLocation(), MangledName);
Alexey Bataev03f270c2018-03-30 18:31:07 +00004200
4201 // Add metadata to the named metadata node.
4202 MD->addOperand(llvm::MDNode::get(C, Ops));
4203 };
4204
4205 OffloadEntriesInfoManager.actOnDeviceGlobalVarEntriesInfo(
4206 DeviceGlobalVarMetadataEmitter);
4207
Alexey Bataevba643691d2019-10-03 16:20:34 +00004208 for (const auto &E : OrderedEntries) {
4209 assert(std::get<0>(E) && "All ordered entries must exist!");
Alexey Bataev03f270c2018-03-30 18:31:07 +00004210 if (const auto *CE =
Samuel Antaoee8fb302016-01-06 13:42:12 +00004211 dyn_cast<OffloadEntriesInfoManagerTy::OffloadEntryInfoTargetRegion>(
Alexey Bataevba643691d2019-10-03 16:20:34 +00004212 std::get<0>(E))) {
Alexey Bataev64e62dc2018-04-30 16:26:57 +00004213 if (!CE->getID() || !CE->getAddress()) {
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00004214 // Do not blame the entry if the parent funtion is not emitted.
4215 StringRef FnName = ParentFunctions[CE->getOrder()];
4216 if (!CGM.GetGlobalValue(FnName))
4217 continue;
Alexey Bataev64e62dc2018-04-30 16:26:57 +00004218 unsigned DiagID = CGM.getDiags().getCustomDiagID(
4219 DiagnosticsEngine::Error,
Alexey Bataevba643691d2019-10-03 16:20:34 +00004220 "Offloading entry for target region in %0 is incorrect: either the "
Alexey Bataev64e62dc2018-04-30 16:26:57 +00004221 "address or the ID is invalid.");
Alexey Bataevba643691d2019-10-03 16:20:34 +00004222 CGM.getDiags().Report(std::get<1>(E), DiagID) << FnName;
Alexey Bataev64e62dc2018-04-30 16:26:57 +00004223 continue;
4224 }
Alexey Bataev34f8a702018-03-28 14:28:54 +00004225 createOffloadEntry(CE->getID(), CE->getAddress(), /*Size=*/0,
Alexey Bataev03f270c2018-03-30 18:31:07 +00004226 CE->getFlags(), llvm::GlobalValue::WeakAnyLinkage);
Alexey Bataevba643691d2019-10-03 16:20:34 +00004227 } else if (const auto *CE = dyn_cast<OffloadEntriesInfoManagerTy::
4228 OffloadEntryInfoDeviceGlobalVar>(
4229 std::get<0>(E))) {
Alexey Bataevc52f01d2018-07-16 20:05:25 +00004230 OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind Flags =
4231 static_cast<OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind>(
4232 CE->getFlags());
4233 switch (Flags) {
4234 case OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryTo: {
Gheorghe-Teodor Bercea0034e842019-06-20 18:04:47 +00004235 if (CGM.getLangOpts().OpenMPIsDevice &&
4236 CGM.getOpenMPRuntime().hasRequiresUnifiedSharedMemory())
4237 continue;
Alexey Bataevc52f01d2018-07-16 20:05:25 +00004238 if (!CE->getAddress()) {
4239 unsigned DiagID = CGM.getDiags().getCustomDiagID(
Alexey Bataevba643691d2019-10-03 16:20:34 +00004240 DiagnosticsEngine::Error, "Offloading entry for declare target "
4241 "variable %0 is incorrect: the "
4242 "address is invalid.");
4243 CGM.getDiags().Report(std::get<1>(E), DiagID) << std::get<2>(E);
Alexey Bataevc52f01d2018-07-16 20:05:25 +00004244 continue;
4245 }
Alexey Bataevb4dd6d22018-08-29 20:41:37 +00004246 // The vaiable has no definition - no need to add the entry.
4247 if (CE->getVarSize().isZero())
4248 continue;
Alexey Bataevc52f01d2018-07-16 20:05:25 +00004249 break;
4250 }
4251 case OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryLink:
4252 assert(((CGM.getLangOpts().OpenMPIsDevice && !CE->getAddress()) ||
4253 (!CGM.getLangOpts().OpenMPIsDevice && CE->getAddress())) &&
4254 "Declaret target link address is set.");
4255 if (CGM.getLangOpts().OpenMPIsDevice)
4256 continue;
4257 if (!CE->getAddress()) {
4258 unsigned DiagID = CGM.getDiags().getCustomDiagID(
4259 DiagnosticsEngine::Error,
4260 "Offloading entry for declare target variable is incorrect: the "
4261 "address is invalid.");
4262 CGM.getDiags().Report(DiagID);
4263 continue;
4264 }
4265 break;
Alexey Bataev64e62dc2018-04-30 16:26:57 +00004266 }
Alexey Bataev03f270c2018-03-30 18:31:07 +00004267 createOffloadEntry(CE->getAddress(), CE->getAddress(),
Alexey Bataevc52f01d2018-07-16 20:05:25 +00004268 CE->getVarSize().getQuantity(), Flags,
Alexey Bataev03f270c2018-03-30 18:31:07 +00004269 CE->getLinkage());
4270 } else {
Samuel Antaoee8fb302016-01-06 13:42:12 +00004271 llvm_unreachable("Unsupported entry kind.");
Alexey Bataev03f270c2018-03-30 18:31:07 +00004272 }
Samuel Antaoee8fb302016-01-06 13:42:12 +00004273 }
4274}
4275
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004276/// Loads all the offload entries information from the host IR
Samuel Antaoee8fb302016-01-06 13:42:12 +00004277/// metadata.
4278void CGOpenMPRuntime::loadOffloadInfoMetadata() {
4279 // If we are in target mode, load the metadata from the host IR. This code has
4280 // to match the metadaata creation in createOffloadEntriesAndInfoMetadata().
4281
4282 if (!CGM.getLangOpts().OpenMPIsDevice)
4283 return;
4284
4285 if (CGM.getLangOpts().OMPHostIRFile.empty())
4286 return;
4287
4288 auto Buf = llvm::MemoryBuffer::getFile(CGM.getLangOpts().OMPHostIRFile);
Alexey Bataev64e62dc2018-04-30 16:26:57 +00004289 if (auto EC = Buf.getError()) {
4290 CGM.getDiags().Report(diag::err_cannot_open_file)
4291 << CGM.getLangOpts().OMPHostIRFile << EC.message();
Samuel Antaoee8fb302016-01-06 13:42:12 +00004292 return;
Alexey Bataev64e62dc2018-04-30 16:26:57 +00004293 }
Samuel Antaoee8fb302016-01-06 13:42:12 +00004294
4295 llvm::LLVMContext C;
Peter Collingbourned9445c42016-11-13 07:00:17 +00004296 auto ME = expectedToErrorOrAndEmitErrors(
4297 C, llvm::parseBitcodeFile(Buf.get()->getMemBufferRef(), C));
Samuel Antaoee8fb302016-01-06 13:42:12 +00004298
Alexey Bataev64e62dc2018-04-30 16:26:57 +00004299 if (auto EC = ME.getError()) {
4300 unsigned DiagID = CGM.getDiags().getCustomDiagID(
4301 DiagnosticsEngine::Error, "Unable to parse host IR file '%0':'%1'");
4302 CGM.getDiags().Report(DiagID)
4303 << CGM.getLangOpts().OMPHostIRFile << EC.message();
Samuel Antaoee8fb302016-01-06 13:42:12 +00004304 return;
Alexey Bataev64e62dc2018-04-30 16:26:57 +00004305 }
Samuel Antaoee8fb302016-01-06 13:42:12 +00004306
4307 llvm::NamedMDNode *MD = ME.get()->getNamedMetadata("omp_offload.info");
4308 if (!MD)
4309 return;
4310
George Burgess IV00f70bd2018-03-01 05:43:23 +00004311 for (llvm::MDNode *MN : MD->operands()) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004312 auto &&GetMDInt = [MN](unsigned Idx) {
4313 auto *V = cast<llvm::ConstantAsMetadata>(MN->getOperand(Idx));
Samuel Antaoee8fb302016-01-06 13:42:12 +00004314 return cast<llvm::ConstantInt>(V->getValue())->getZExtValue();
4315 };
4316
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004317 auto &&GetMDString = [MN](unsigned Idx) {
4318 auto *V = cast<llvm::MDString>(MN->getOperand(Idx));
Samuel Antaoee8fb302016-01-06 13:42:12 +00004319 return V->getString();
4320 };
4321
Alexey Bataev03f270c2018-03-30 18:31:07 +00004322 switch (GetMDInt(0)) {
Samuel Antaoee8fb302016-01-06 13:42:12 +00004323 default:
4324 llvm_unreachable("Unexpected metadata!");
4325 break;
4326 case OffloadEntriesInfoManagerTy::OffloadEntryInfo::
Alexey Bataev34f8a702018-03-28 14:28:54 +00004327 OffloadingEntryInfoTargetRegion:
Samuel Antaoee8fb302016-01-06 13:42:12 +00004328 OffloadEntriesInfoManager.initializeTargetRegionEntryInfo(
Alexey Bataev03f270c2018-03-30 18:31:07 +00004329 /*DeviceID=*/GetMDInt(1), /*FileID=*/GetMDInt(2),
4330 /*ParentName=*/GetMDString(3), /*Line=*/GetMDInt(4),
4331 /*Order=*/GetMDInt(5));
4332 break;
4333 case OffloadEntriesInfoManagerTy::OffloadEntryInfo::
4334 OffloadingEntryInfoDeviceGlobalVar:
4335 OffloadEntriesInfoManager.initializeDeviceGlobalVarEntryInfo(
4336 /*MangledName=*/GetMDString(1),
4337 static_cast<OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind>(
4338 /*Flags=*/GetMDInt(2)),
4339 /*Order=*/GetMDInt(3));
Samuel Antaoee8fb302016-01-06 13:42:12 +00004340 break;
4341 }
4342 }
4343}
4344
Alexey Bataev62b63b12015-03-10 07:28:44 +00004345void CGOpenMPRuntime::emitKmpRoutineEntryT(QualType KmpInt32Ty) {
4346 if (!KmpRoutineEntryPtrTy) {
4347 // Build typedef kmp_int32 (* kmp_routine_entry_t)(kmp_int32, void *); type.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004348 ASTContext &C = CGM.getContext();
Alexey Bataev62b63b12015-03-10 07:28:44 +00004349 QualType KmpRoutineEntryTyArgs[] = {KmpInt32Ty, C.VoidPtrTy};
4350 FunctionProtoType::ExtProtoInfo EPI;
4351 KmpRoutineEntryPtrQTy = C.getPointerType(
4352 C.getFunctionType(KmpInt32Ty, KmpRoutineEntryTyArgs, EPI));
4353 KmpRoutineEntryPtrTy = CGM.getTypes().ConvertType(KmpRoutineEntryPtrQTy);
4354 }
4355}
4356
Samuel Antaoee8fb302016-01-06 13:42:12 +00004357QualType CGOpenMPRuntime::getTgtOffloadEntryQTy() {
Samuel Antaoee8fb302016-01-06 13:42:12 +00004358 // Make sure the type of the entry is already created. This is the type we
4359 // have to create:
4360 // struct __tgt_offload_entry{
4361 // void *addr; // Pointer to the offload entry info.
4362 // // (function or global)
4363 // char *name; // Name of the function or global.
4364 // size_t size; // Size of the entry info (0 if it a function).
Samuel Antaof83efdb2017-01-05 16:02:49 +00004365 // int32_t flags; // Flags associated with the entry, e.g. 'link'.
4366 // int32_t reserved; // Reserved, to use by the runtime library.
Samuel Antaoee8fb302016-01-06 13:42:12 +00004367 // };
4368 if (TgtOffloadEntryQTy.isNull()) {
4369 ASTContext &C = CGM.getContext();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004370 RecordDecl *RD = C.buildImplicitRecord("__tgt_offload_entry");
Samuel Antaoee8fb302016-01-06 13:42:12 +00004371 RD->startDefinition();
4372 addFieldToRecordDecl(C, RD, C.VoidPtrTy);
4373 addFieldToRecordDecl(C, RD, C.getPointerType(C.CharTy));
4374 addFieldToRecordDecl(C, RD, C.getSizeType());
Samuel Antaof83efdb2017-01-05 16:02:49 +00004375 addFieldToRecordDecl(
4376 C, RD, C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/true));
4377 addFieldToRecordDecl(
4378 C, RD, C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/true));
Samuel Antaoee8fb302016-01-06 13:42:12 +00004379 RD->completeDefinition();
Jonas Hahnfeld5e4df282018-01-18 15:38:03 +00004380 RD->addAttr(PackedAttr::CreateImplicit(C));
Samuel Antaoee8fb302016-01-06 13:42:12 +00004381 TgtOffloadEntryQTy = C.getRecordType(RD);
4382 }
4383 return TgtOffloadEntryQTy;
4384}
4385
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004386namespace {
Alexey Bataev9e034042015-05-05 04:05:12 +00004387struct PrivateHelpersTy {
4388 PrivateHelpersTy(const VarDecl *Original, const VarDecl *PrivateCopy,
4389 const VarDecl *PrivateElemInit)
4390 : Original(Original), PrivateCopy(PrivateCopy),
4391 PrivateElemInit(PrivateElemInit) {}
4392 const VarDecl *Original;
4393 const VarDecl *PrivateCopy;
4394 const VarDecl *PrivateElemInit;
4395};
4396typedef std::pair<CharUnits /*Align*/, PrivateHelpersTy> PrivateDataTy;
Hans Wennborg7eb54642015-09-10 17:07:54 +00004397} // anonymous namespace
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004398
Alexey Bataev9e034042015-05-05 04:05:12 +00004399static RecordDecl *
Craig Topper8674c5c2015-09-29 04:30:07 +00004400createPrivatesRecordDecl(CodeGenModule &CGM, ArrayRef<PrivateDataTy> Privates) {
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004401 if (!Privates.empty()) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004402 ASTContext &C = CGM.getContext();
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004403 // Build struct .kmp_privates_t. {
4404 // /* private vars */
4405 // };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004406 RecordDecl *RD = C.buildImplicitRecord(".kmp_privates.t");
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004407 RD->startDefinition();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004408 for (const auto &Pair : Privates) {
4409 const VarDecl *VD = Pair.second.Original;
4410 QualType Type = VD->getType().getNonReferenceType();
4411 FieldDecl *FD = addFieldToRecordDecl(C, RD, Type);
Alexey Bataevc71a4092015-09-11 10:29:41 +00004412 if (VD->hasAttrs()) {
4413 for (specific_attr_iterator<AlignedAttr> I(VD->getAttrs().begin()),
4414 E(VD->getAttrs().end());
4415 I != E; ++I)
4416 FD->addAttr(*I);
4417 }
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004418 }
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004419 RD->completeDefinition();
4420 return RD;
4421 }
4422 return nullptr;
4423}
4424
Alexey Bataev9e034042015-05-05 04:05:12 +00004425static RecordDecl *
Alexey Bataev7292c292016-04-25 12:22:29 +00004426createKmpTaskTRecordDecl(CodeGenModule &CGM, OpenMPDirectiveKind Kind,
4427 QualType KmpInt32Ty,
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00004428 QualType KmpRoutineEntryPointerQTy) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004429 ASTContext &C = CGM.getContext();
Alexey Bataev62b63b12015-03-10 07:28:44 +00004430 // Build struct kmp_task_t {
4431 // void * shareds;
4432 // kmp_routine_entry_t routine;
4433 // kmp_int32 part_id;
Alexey Bataevad537bb2016-05-30 09:06:50 +00004434 // kmp_cmplrdata_t data1;
4435 // kmp_cmplrdata_t data2;
Alexey Bataev7292c292016-04-25 12:22:29 +00004436 // For taskloops additional fields:
4437 // kmp_uint64 lb;
4438 // kmp_uint64 ub;
4439 // kmp_int64 st;
4440 // kmp_int32 liter;
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00004441 // void * reductions;
Alexey Bataev62b63b12015-03-10 07:28:44 +00004442 // };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004443 RecordDecl *UD = C.buildImplicitRecord("kmp_cmplrdata_t", TTK_Union);
Alexey Bataevad537bb2016-05-30 09:06:50 +00004444 UD->startDefinition();
4445 addFieldToRecordDecl(C, UD, KmpInt32Ty);
4446 addFieldToRecordDecl(C, UD, KmpRoutineEntryPointerQTy);
4447 UD->completeDefinition();
4448 QualType KmpCmplrdataTy = C.getRecordType(UD);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004449 RecordDecl *RD = C.buildImplicitRecord("kmp_task_t");
Alexey Bataev62b63b12015-03-10 07:28:44 +00004450 RD->startDefinition();
4451 addFieldToRecordDecl(C, RD, C.VoidPtrTy);
4452 addFieldToRecordDecl(C, RD, KmpRoutineEntryPointerQTy);
4453 addFieldToRecordDecl(C, RD, KmpInt32Ty);
Alexey Bataevad537bb2016-05-30 09:06:50 +00004454 addFieldToRecordDecl(C, RD, KmpCmplrdataTy);
4455 addFieldToRecordDecl(C, RD, KmpCmplrdataTy);
Alexey Bataev7292c292016-04-25 12:22:29 +00004456 if (isOpenMPTaskLoopDirective(Kind)) {
4457 QualType KmpUInt64Ty =
4458 CGM.getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
4459 QualType KmpInt64Ty =
4460 CGM.getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
4461 addFieldToRecordDecl(C, RD, KmpUInt64Ty);
4462 addFieldToRecordDecl(C, RD, KmpUInt64Ty);
4463 addFieldToRecordDecl(C, RD, KmpInt64Ty);
4464 addFieldToRecordDecl(C, RD, KmpInt32Ty);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00004465 addFieldToRecordDecl(C, RD, C.VoidPtrTy);
Alexey Bataev7292c292016-04-25 12:22:29 +00004466 }
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00004467 RD->completeDefinition();
4468 return RD;
4469}
4470
4471static RecordDecl *
4472createKmpTaskTWithPrivatesRecordDecl(CodeGenModule &CGM, QualType KmpTaskTQTy,
Craig Topper8674c5c2015-09-29 04:30:07 +00004473 ArrayRef<PrivateDataTy> Privates) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004474 ASTContext &C = CGM.getContext();
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00004475 // Build struct kmp_task_t_with_privates {
4476 // kmp_task_t task_data;
4477 // .kmp_privates_t. privates;
4478 // };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004479 RecordDecl *RD = C.buildImplicitRecord("kmp_task_t_with_privates");
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00004480 RD->startDefinition();
4481 addFieldToRecordDecl(C, RD, KmpTaskTQTy);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004482 if (const RecordDecl *PrivateRD = createPrivatesRecordDecl(CGM, Privates))
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004483 addFieldToRecordDecl(C, RD, C.getRecordType(PrivateRD));
Alexey Bataev62b63b12015-03-10 07:28:44 +00004484 RD->completeDefinition();
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004485 return RD;
Alexey Bataev62b63b12015-03-10 07:28:44 +00004486}
4487
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004488/// Emit a proxy function which accepts kmp_task_t as the second
Alexey Bataev62b63b12015-03-10 07:28:44 +00004489/// argument.
4490/// \code
4491/// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
Alexey Bataev48591dd2016-04-20 04:01:36 +00004492/// TaskFunction(gtid, tt->part_id, &tt->privates, task_privates_map, tt,
Alexey Bataev7292c292016-04-25 12:22:29 +00004493/// For taskloops:
4494/// tt->task_data.lb, tt->task_data.ub, tt->task_data.st, tt->task_data.liter,
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00004495/// tt->reductions, tt->shareds);
Alexey Bataev62b63b12015-03-10 07:28:44 +00004496/// return 0;
4497/// }
4498/// \endcode
James Y Knight9871db02019-02-05 16:42:33 +00004499static llvm::Function *
Alexey Bataev62b63b12015-03-10 07:28:44 +00004500emitProxyTaskFunction(CodeGenModule &CGM, SourceLocation Loc,
Alexey Bataev7292c292016-04-25 12:22:29 +00004501 OpenMPDirectiveKind Kind, QualType KmpInt32Ty,
4502 QualType KmpTaskTWithPrivatesPtrQTy,
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00004503 QualType KmpTaskTWithPrivatesQTy, QualType KmpTaskTQTy,
James Y Knight9871db02019-02-05 16:42:33 +00004504 QualType SharedsPtrTy, llvm::Function *TaskFunction,
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004505 llvm::Value *TaskPrivatesMap) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004506 ASTContext &C = CGM.getContext();
Alexey Bataev62b63b12015-03-10 07:28:44 +00004507 FunctionArgList Args;
Alexey Bataev56223232017-06-09 13:40:18 +00004508 ImplicitParamDecl GtidArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, KmpInt32Ty,
4509 ImplicitParamDecl::Other);
4510 ImplicitParamDecl TaskTypeArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4511 KmpTaskTWithPrivatesPtrQTy.withRestrict(),
4512 ImplicitParamDecl::Other);
Alexey Bataev62b63b12015-03-10 07:28:44 +00004513 Args.push_back(&GtidArg);
4514 Args.push_back(&TaskTypeArg);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004515 const auto &TaskEntryFnInfo =
John McCallc56a8b32016-03-11 04:30:31 +00004516 CGM.getTypes().arrangeBuiltinFunctionDeclaration(KmpInt32Ty, Args);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004517 llvm::FunctionType *TaskEntryTy =
4518 CGM.getTypes().GetFunctionType(TaskEntryFnInfo);
Alexey Bataev18fa2322018-05-02 14:20:50 +00004519 std::string Name = CGM.getOpenMPRuntime().getName({"omp_task_entry", ""});
4520 auto *TaskEntry = llvm::Function::Create(
4521 TaskEntryTy, llvm::GlobalValue::InternalLinkage, Name, &CGM.getModule());
Rafael Espindola51ec5a92018-02-28 23:46:35 +00004522 CGM.SetInternalFunctionAttributes(GlobalDecl(), TaskEntry, TaskEntryFnInfo);
Alexey Bataevc0f879b2018-04-10 20:10:53 +00004523 TaskEntry->setDoesNotRecurse();
Alexey Bataev62b63b12015-03-10 07:28:44 +00004524 CodeGenFunction CGF(CGM);
Alexey Bataev7cae94e2018-01-04 19:45:16 +00004525 CGF.StartFunction(GlobalDecl(), KmpInt32Ty, TaskEntry, TaskEntryFnInfo, Args,
4526 Loc, Loc);
Alexey Bataev62b63b12015-03-10 07:28:44 +00004527
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004528 // TaskFunction(gtid, tt->task_data.part_id, &tt->privates, task_privates_map,
Alexey Bataev7292c292016-04-25 12:22:29 +00004529 // tt,
4530 // For taskloops:
4531 // tt->task_data.lb, tt->task_data.ub, tt->task_data.st, tt->task_data.liter,
4532 // tt->task_data.shareds);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004533 llvm::Value *GtidParam = CGF.EmitLoadOfScalar(
John McCall7f416cc2015-09-08 08:05:57 +00004534 CGF.GetAddrOfLocalVar(&GtidArg), /*Volatile=*/false, KmpInt32Ty, Loc);
Alexey Bataev31300ed2016-02-04 11:27:03 +00004535 LValue TDBase = CGF.EmitLoadOfPointerLValue(
4536 CGF.GetAddrOfLocalVar(&TaskTypeArg),
4537 KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004538 const auto *KmpTaskTWithPrivatesQTyRD =
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00004539 cast<RecordDecl>(KmpTaskTWithPrivatesQTy->getAsTagDecl());
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004540 LValue Base =
4541 CGF.EmitLValueForField(TDBase, *KmpTaskTWithPrivatesQTyRD->field_begin());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004542 const auto *KmpTaskTQTyRD = cast<RecordDecl>(KmpTaskTQTy->getAsTagDecl());
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00004543 auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004544 LValue PartIdLVal = CGF.EmitLValueForField(Base, *PartIdFI);
Akira Hatanakaf139ae32019-12-03 15:17:01 -08004545 llvm::Value *PartidParam = PartIdLVal.getPointer(CGF);
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00004546
4547 auto SharedsFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTShareds);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004548 LValue SharedsLVal = CGF.EmitLValueForField(Base, *SharedsFI);
4549 llvm::Value *SharedsParam = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
Alexey Bataev1e491372018-01-23 18:44:14 +00004550 CGF.EmitLoadOfScalar(SharedsLVal, Loc),
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004551 CGF.ConvertTypeForMem(SharedsPtrTy));
4552
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004553 auto PrivatesFI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin(), 1);
4554 llvm::Value *PrivatesParam;
4555 if (PrivatesFI != KmpTaskTWithPrivatesQTyRD->field_end()) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004556 LValue PrivatesLVal = CGF.EmitLValueForField(TDBase, *PrivatesFI);
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004557 PrivatesParam = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
Akira Hatanakaf139ae32019-12-03 15:17:01 -08004558 PrivatesLVal.getPointer(CGF), CGF.VoidPtrTy);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004559 } else {
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004560 PrivatesParam = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004561 }
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004562
Alexey Bataev7292c292016-04-25 12:22:29 +00004563 llvm::Value *CommonArgs[] = {GtidParam, PartidParam, PrivatesParam,
4564 TaskPrivatesMap,
4565 CGF.Builder
4566 .CreatePointerBitCastOrAddrSpaceCast(
Akira Hatanakaf139ae32019-12-03 15:17:01 -08004567 TDBase.getAddress(CGF), CGF.VoidPtrTy)
Alexey Bataev7292c292016-04-25 12:22:29 +00004568 .getPointer()};
4569 SmallVector<llvm::Value *, 16> CallArgs(std::begin(CommonArgs),
4570 std::end(CommonArgs));
4571 if (isOpenMPTaskLoopDirective(Kind)) {
4572 auto LBFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLowerBound);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004573 LValue LBLVal = CGF.EmitLValueForField(Base, *LBFI);
4574 llvm::Value *LBParam = CGF.EmitLoadOfScalar(LBLVal, Loc);
Alexey Bataev7292c292016-04-25 12:22:29 +00004575 auto UBFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTUpperBound);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004576 LValue UBLVal = CGF.EmitLValueForField(Base, *UBFI);
4577 llvm::Value *UBParam = CGF.EmitLoadOfScalar(UBLVal, Loc);
Alexey Bataev7292c292016-04-25 12:22:29 +00004578 auto StFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTStride);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004579 LValue StLVal = CGF.EmitLValueForField(Base, *StFI);
4580 llvm::Value *StParam = CGF.EmitLoadOfScalar(StLVal, Loc);
Alexey Bataev7292c292016-04-25 12:22:29 +00004581 auto LIFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLastIter);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004582 LValue LILVal = CGF.EmitLValueForField(Base, *LIFI);
4583 llvm::Value *LIParam = CGF.EmitLoadOfScalar(LILVal, Loc);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00004584 auto RFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTReductions);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004585 LValue RLVal = CGF.EmitLValueForField(Base, *RFI);
4586 llvm::Value *RParam = CGF.EmitLoadOfScalar(RLVal, Loc);
Alexey Bataev7292c292016-04-25 12:22:29 +00004587 CallArgs.push_back(LBParam);
4588 CallArgs.push_back(UBParam);
4589 CallArgs.push_back(StParam);
4590 CallArgs.push_back(LIParam);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00004591 CallArgs.push_back(RParam);
Alexey Bataev7292c292016-04-25 12:22:29 +00004592 }
4593 CallArgs.push_back(SharedsParam);
4594
Alexey Bataev3c595a62017-08-14 15:01:03 +00004595 CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, Loc, TaskFunction,
4596 CallArgs);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004597 CGF.EmitStoreThroughLValue(RValue::get(CGF.Builder.getInt32(/*C=*/0)),
4598 CGF.MakeAddrLValue(CGF.ReturnValue, KmpInt32Ty));
Alexey Bataev62b63b12015-03-10 07:28:44 +00004599 CGF.FinishFunction();
4600 return TaskEntry;
4601}
4602
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00004603static llvm::Value *emitDestructorsFunction(CodeGenModule &CGM,
4604 SourceLocation Loc,
4605 QualType KmpInt32Ty,
4606 QualType KmpTaskTWithPrivatesPtrQTy,
4607 QualType KmpTaskTWithPrivatesQTy) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004608 ASTContext &C = CGM.getContext();
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004609 FunctionArgList Args;
Alexey Bataev56223232017-06-09 13:40:18 +00004610 ImplicitParamDecl GtidArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, KmpInt32Ty,
4611 ImplicitParamDecl::Other);
4612 ImplicitParamDecl TaskTypeArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4613 KmpTaskTWithPrivatesPtrQTy.withRestrict(),
4614 ImplicitParamDecl::Other);
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004615 Args.push_back(&GtidArg);
4616 Args.push_back(&TaskTypeArg);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004617 const auto &DestructorFnInfo =
John McCallc56a8b32016-03-11 04:30:31 +00004618 CGM.getTypes().arrangeBuiltinFunctionDeclaration(KmpInt32Ty, Args);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004619 llvm::FunctionType *DestructorFnTy =
4620 CGM.getTypes().GetFunctionType(DestructorFnInfo);
Alexey Bataev18fa2322018-05-02 14:20:50 +00004621 std::string Name =
4622 CGM.getOpenMPRuntime().getName({"omp_task_destructor", ""});
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004623 auto *DestructorFn =
4624 llvm::Function::Create(DestructorFnTy, llvm::GlobalValue::InternalLinkage,
Alexey Bataev18fa2322018-05-02 14:20:50 +00004625 Name, &CGM.getModule());
Rafael Espindola51ec5a92018-02-28 23:46:35 +00004626 CGM.SetInternalFunctionAttributes(GlobalDecl(), DestructorFn,
Akira Hatanaka44a59f82015-10-28 02:30:47 +00004627 DestructorFnInfo);
Alexey Bataevc0f879b2018-04-10 20:10:53 +00004628 DestructorFn->setDoesNotRecurse();
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004629 CodeGenFunction CGF(CGM);
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004630 CGF.StartFunction(GlobalDecl(), KmpInt32Ty, DestructorFn, DestructorFnInfo,
Alexey Bataev7cae94e2018-01-04 19:45:16 +00004631 Args, Loc, Loc);
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004632
Alexey Bataev31300ed2016-02-04 11:27:03 +00004633 LValue Base = CGF.EmitLoadOfPointerLValue(
4634 CGF.GetAddrOfLocalVar(&TaskTypeArg),
4635 KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004636 const auto *KmpTaskTWithPrivatesQTyRD =
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00004637 cast<RecordDecl>(KmpTaskTWithPrivatesQTy->getAsTagDecl());
4638 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004639 Base = CGF.EmitLValueForField(Base, *FI);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004640 for (const auto *Field :
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004641 cast<RecordDecl>(FI->getType()->getAsTagDecl())->fields()) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004642 if (QualType::DestructionKind DtorKind =
4643 Field->getType().isDestructedType()) {
4644 LValue FieldLValue = CGF.EmitLValueForField(Base, Field);
Akira Hatanakaf139ae32019-12-03 15:17:01 -08004645 CGF.pushDestroy(DtorKind, FieldLValue.getAddress(CGF), Field->getType());
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004646 }
4647 }
4648 CGF.FinishFunction();
4649 return DestructorFn;
4650}
4651
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004652/// Emit a privates mapping function for correct handling of private and
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004653/// firstprivate variables.
4654/// \code
4655/// void .omp_task_privates_map.(const .privates. *noalias privs, <ty1>
4656/// **noalias priv1,..., <tyn> **noalias privn) {
4657/// *priv1 = &.privates.priv1;
4658/// ...;
4659/// *privn = &.privates.privn;
4660/// }
4661/// \endcode
4662static llvm::Value *
4663emitTaskPrivateMappingFunction(CodeGenModule &CGM, SourceLocation Loc,
Craig Topper8674c5c2015-09-29 04:30:07 +00004664 ArrayRef<const Expr *> PrivateVars,
4665 ArrayRef<const Expr *> FirstprivateVars,
Alexey Bataevf93095a2016-05-05 08:46:22 +00004666 ArrayRef<const Expr *> LastprivateVars,
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004667 QualType PrivatesQTy,
Craig Topper8674c5c2015-09-29 04:30:07 +00004668 ArrayRef<PrivateDataTy> Privates) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004669 ASTContext &C = CGM.getContext();
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004670 FunctionArgList Args;
4671 ImplicitParamDecl TaskPrivatesArg(
4672 C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
Alexey Bataev56223232017-06-09 13:40:18 +00004673 C.getPointerType(PrivatesQTy).withConst().withRestrict(),
4674 ImplicitParamDecl::Other);
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004675 Args.push_back(&TaskPrivatesArg);
4676 llvm::DenseMap<const VarDecl *, unsigned> PrivateVarsPos;
4677 unsigned Counter = 1;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004678 for (const Expr *E : PrivateVars) {
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004679 Args.push_back(ImplicitParamDecl::Create(
Alexey Bataev56223232017-06-09 13:40:18 +00004680 C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4681 C.getPointerType(C.getPointerType(E->getType()))
4682 .withConst()
4683 .withRestrict(),
4684 ImplicitParamDecl::Other));
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004685 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004686 PrivateVarsPos[VD] = Counter;
4687 ++Counter;
4688 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004689 for (const Expr *E : FirstprivateVars) {
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004690 Args.push_back(ImplicitParamDecl::Create(
Alexey Bataev56223232017-06-09 13:40:18 +00004691 C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4692 C.getPointerType(C.getPointerType(E->getType()))
4693 .withConst()
4694 .withRestrict(),
4695 ImplicitParamDecl::Other));
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004696 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004697 PrivateVarsPos[VD] = Counter;
4698 ++Counter;
4699 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004700 for (const Expr *E : LastprivateVars) {
Alexey Bataevf93095a2016-05-05 08:46:22 +00004701 Args.push_back(ImplicitParamDecl::Create(
Alexey Bataev56223232017-06-09 13:40:18 +00004702 C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4703 C.getPointerType(C.getPointerType(E->getType()))
4704 .withConst()
4705 .withRestrict(),
4706 ImplicitParamDecl::Other));
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004707 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataevf93095a2016-05-05 08:46:22 +00004708 PrivateVarsPos[VD] = Counter;
4709 ++Counter;
4710 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004711 const auto &TaskPrivatesMapFnInfo =
John McCallc56a8b32016-03-11 04:30:31 +00004712 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004713 llvm::FunctionType *TaskPrivatesMapTy =
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004714 CGM.getTypes().GetFunctionType(TaskPrivatesMapFnInfo);
Alexey Bataev18fa2322018-05-02 14:20:50 +00004715 std::string Name =
4716 CGM.getOpenMPRuntime().getName({"omp_task_privates_map", ""});
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004717 auto *TaskPrivatesMap = llvm::Function::Create(
Alexey Bataev18fa2322018-05-02 14:20:50 +00004718 TaskPrivatesMapTy, llvm::GlobalValue::InternalLinkage, Name,
4719 &CGM.getModule());
Rafael Espindola51ec5a92018-02-28 23:46:35 +00004720 CGM.SetInternalFunctionAttributes(GlobalDecl(), TaskPrivatesMap,
Akira Hatanaka44a59f82015-10-28 02:30:47 +00004721 TaskPrivatesMapFnInfo);
Alexey Bataev8c5555c2019-05-21 15:11:58 +00004722 if (CGM.getLangOpts().Optimize) {
4723 TaskPrivatesMap->removeFnAttr(llvm::Attribute::NoInline);
4724 TaskPrivatesMap->removeFnAttr(llvm::Attribute::OptimizeNone);
4725 TaskPrivatesMap->addFnAttr(llvm::Attribute::AlwaysInline);
4726 }
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004727 CodeGenFunction CGF(CGM);
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004728 CGF.StartFunction(GlobalDecl(), C.VoidTy, TaskPrivatesMap,
Alexey Bataev7cae94e2018-01-04 19:45:16 +00004729 TaskPrivatesMapFnInfo, Args, Loc, Loc);
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004730
4731 // *privi = &.privates.privi;
Alexey Bataev31300ed2016-02-04 11:27:03 +00004732 LValue Base = CGF.EmitLoadOfPointerLValue(
4733 CGF.GetAddrOfLocalVar(&TaskPrivatesArg),
4734 TaskPrivatesArg.getType()->castAs<PointerType>());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004735 const auto *PrivatesQTyRD = cast<RecordDecl>(PrivatesQTy->getAsTagDecl());
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004736 Counter = 0;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004737 for (const FieldDecl *Field : PrivatesQTyRD->fields()) {
4738 LValue FieldLVal = CGF.EmitLValueForField(Base, Field);
4739 const VarDecl *VD = Args[PrivateVarsPos[Privates[Counter].second.Original]];
4740 LValue RefLVal =
4741 CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(VD), VD->getType());
4742 LValue RefLoadLVal = CGF.EmitLoadOfPointerLValue(
Akira Hatanakaf139ae32019-12-03 15:17:01 -08004743 RefLVal.getAddress(CGF), RefLVal.getType()->castAs<PointerType>());
4744 CGF.EmitStoreOfScalar(FieldLVal.getPointer(CGF), RefLoadLVal);
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004745 ++Counter;
4746 }
4747 CGF.FinishFunction();
4748 return TaskPrivatesMap;
4749}
4750
Alexey Bataevf93095a2016-05-05 08:46:22 +00004751/// Emit initialization for private variables in task-based directives.
Alexey Bataev8a831592016-05-10 10:36:51 +00004752static void emitPrivatesInit(CodeGenFunction &CGF,
Alexey Bataevf93095a2016-05-05 08:46:22 +00004753 const OMPExecutableDirective &D,
4754 Address KmpTaskSharedsPtr, LValue TDBase,
4755 const RecordDecl *KmpTaskTWithPrivatesQTyRD,
4756 QualType SharedsTy, QualType SharedsPtrTy,
4757 const OMPTaskDataTy &Data,
4758 ArrayRef<PrivateDataTy> Privates, bool ForDup) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004759 ASTContext &C = CGF.getContext();
Alexey Bataevf93095a2016-05-05 08:46:22 +00004760 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
4761 LValue PrivatesBase = CGF.EmitLValueForField(TDBase, *FI);
Alexey Bataev8451efa2018-01-15 19:06:12 +00004762 OpenMPDirectiveKind Kind = isOpenMPTaskLoopDirective(D.getDirectiveKind())
4763 ? OMPD_taskloop
4764 : OMPD_task;
4765 const CapturedStmt &CS = *D.getCapturedStmt(Kind);
4766 CodeGenFunction::CGCapturedStmtInfo CapturesInfo(CS);
Alexey Bataevf93095a2016-05-05 08:46:22 +00004767 LValue SrcBase;
Alexey Bataevd2202ca2017-12-27 17:58:32 +00004768 bool IsTargetTask =
4769 isOpenMPTargetDataManagementDirective(D.getDirectiveKind()) ||
4770 isOpenMPTargetExecutionDirective(D.getDirectiveKind());
4771 // For target-based directives skip 3 firstprivate arrays BasePointersArray,
4772 // PointersArray and SizesArray. The original variables for these arrays are
4773 // not captured and we get their addresses explicitly.
4774 if ((!IsTargetTask && !Data.FirstprivateVars.empty()) ||
Alexey Bataev8451efa2018-01-15 19:06:12 +00004775 (IsTargetTask && KmpTaskSharedsPtr.isValid())) {
Alexey Bataevf93095a2016-05-05 08:46:22 +00004776 SrcBase = CGF.MakeAddrLValue(
4777 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
4778 KmpTaskSharedsPtr, CGF.ConvertTypeForMem(SharedsPtrTy)),
4779 SharedsTy);
4780 }
Alexey Bataevf93095a2016-05-05 08:46:22 +00004781 FI = cast<RecordDecl>(FI->getType()->getAsTagDecl())->field_begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004782 for (const PrivateDataTy &Pair : Privates) {
4783 const VarDecl *VD = Pair.second.PrivateCopy;
4784 const Expr *Init = VD->getAnyInitializer();
Alexey Bataevf93095a2016-05-05 08:46:22 +00004785 if (Init && (!ForDup || (isa<CXXConstructExpr>(Init) &&
4786 !CGF.isTrivialInitializer(Init)))) {
Alexey Bataev8a831592016-05-10 10:36:51 +00004787 LValue PrivateLValue = CGF.EmitLValueForField(PrivatesBase, *FI);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004788 if (const VarDecl *Elem = Pair.second.PrivateElemInit) {
4789 const VarDecl *OriginalVD = Pair.second.Original;
Alexey Bataevd2202ca2017-12-27 17:58:32 +00004790 // Check if the variable is the target-based BasePointersArray,
4791 // PointersArray or SizesArray.
4792 LValue SharedRefLValue;
Alexey Bataevab41ea62019-03-13 20:46:28 +00004793 QualType Type = PrivateLValue.getType();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004794 const FieldDecl *SharedField = CapturesInfo.lookup(OriginalVD);
Alexey Bataev8451efa2018-01-15 19:06:12 +00004795 if (IsTargetTask && !SharedField) {
4796 assert(isa<ImplicitParamDecl>(OriginalVD) &&
4797 isa<CapturedDecl>(OriginalVD->getDeclContext()) &&
4798 cast<CapturedDecl>(OriginalVD->getDeclContext())
4799 ->getNumParams() == 0 &&
4800 isa<TranslationUnitDecl>(
4801 cast<CapturedDecl>(OriginalVD->getDeclContext())
4802 ->getDeclContext()) &&
4803 "Expected artificial target data variable.");
Alexey Bataevd2202ca2017-12-27 17:58:32 +00004804 SharedRefLValue =
4805 CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(OriginalVD), Type);
4806 } else {
Alexey Bataevd2202ca2017-12-27 17:58:32 +00004807 SharedRefLValue = CGF.EmitLValueForField(SrcBase, SharedField);
4808 SharedRefLValue = CGF.MakeAddrLValue(
Akira Hatanakaf139ae32019-12-03 15:17:01 -08004809 Address(SharedRefLValue.getPointer(CGF),
4810 C.getDeclAlign(OriginalVD)),
Alexey Bataevd2202ca2017-12-27 17:58:32 +00004811 SharedRefLValue.getType(), LValueBaseInfo(AlignmentSource::Decl),
4812 SharedRefLValue.getTBAAInfo());
4813 }
Alexey Bataevf93095a2016-05-05 08:46:22 +00004814 if (Type->isArrayType()) {
4815 // Initialize firstprivate array.
4816 if (!isa<CXXConstructExpr>(Init) || CGF.isTrivialInitializer(Init)) {
4817 // Perform simple memcpy.
Ivan A. Kosarev1860b522018-01-25 14:21:55 +00004818 CGF.EmitAggregateAssign(PrivateLValue, SharedRefLValue, Type);
Alexey Bataevf93095a2016-05-05 08:46:22 +00004819 } else {
4820 // Initialize firstprivate array using element-by-element
Simon Pilgrim2c518802017-03-30 14:13:19 +00004821 // initialization.
Alexey Bataevf93095a2016-05-05 08:46:22 +00004822 CGF.EmitOMPAggregateAssign(
Akira Hatanakaf139ae32019-12-03 15:17:01 -08004823 PrivateLValue.getAddress(CGF), SharedRefLValue.getAddress(CGF),
4824 Type,
Alexey Bataevf93095a2016-05-05 08:46:22 +00004825 [&CGF, Elem, Init, &CapturesInfo](Address DestElement,
4826 Address SrcElement) {
4827 // Clean up any temporaries needed by the initialization.
4828 CodeGenFunction::OMPPrivateScope InitScope(CGF);
4829 InitScope.addPrivate(
4830 Elem, [SrcElement]() -> Address { return SrcElement; });
4831 (void)InitScope.Privatize();
4832 // Emit initialization for single element.
4833 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(
4834 CGF, &CapturesInfo);
4835 CGF.EmitAnyExprToMem(Init, DestElement,
4836 Init->getType().getQualifiers(),
4837 /*IsInitializer=*/false);
4838 });
4839 }
4840 } else {
4841 CodeGenFunction::OMPPrivateScope InitScope(CGF);
Akira Hatanakaf139ae32019-12-03 15:17:01 -08004842 InitScope.addPrivate(Elem, [SharedRefLValue, &CGF]() -> Address {
4843 return SharedRefLValue.getAddress(CGF);
Alexey Bataevf93095a2016-05-05 08:46:22 +00004844 });
4845 (void)InitScope.Privatize();
4846 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CapturesInfo);
4847 CGF.EmitExprAsInit(Init, VD, PrivateLValue,
4848 /*capturedByInit=*/false);
4849 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004850 } else {
Alexey Bataevf93095a2016-05-05 08:46:22 +00004851 CGF.EmitExprAsInit(Init, VD, PrivateLValue, /*capturedByInit=*/false);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004852 }
Alexey Bataevf93095a2016-05-05 08:46:22 +00004853 }
Alexey Bataevf93095a2016-05-05 08:46:22 +00004854 ++FI;
4855 }
Alexey Bataevf93095a2016-05-05 08:46:22 +00004856}
4857
4858/// Check if duplication function is required for taskloops.
4859static bool checkInitIsRequired(CodeGenFunction &CGF,
4860 ArrayRef<PrivateDataTy> Privates) {
4861 bool InitRequired = false;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004862 for (const PrivateDataTy &Pair : Privates) {
4863 const VarDecl *VD = Pair.second.PrivateCopy;
4864 const Expr *Init = VD->getAnyInitializer();
Alexey Bataevf93095a2016-05-05 08:46:22 +00004865 InitRequired = InitRequired || (Init && isa<CXXConstructExpr>(Init) &&
4866 !CGF.isTrivialInitializer(Init));
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004867 if (InitRequired)
4868 break;
Alexey Bataevf93095a2016-05-05 08:46:22 +00004869 }
4870 return InitRequired;
4871}
4872
4873
4874/// Emit task_dup function (for initialization of
4875/// private/firstprivate/lastprivate vars and last_iter flag)
4876/// \code
4877/// void __task_dup_entry(kmp_task_t *task_dst, const kmp_task_t *task_src, int
4878/// lastpriv) {
4879/// // setup lastprivate flag
4880/// task_dst->last = lastpriv;
4881/// // could be constructor calls here...
4882/// }
4883/// \endcode
4884static llvm::Value *
4885emitTaskDupFunction(CodeGenModule &CGM, SourceLocation Loc,
4886 const OMPExecutableDirective &D,
4887 QualType KmpTaskTWithPrivatesPtrQTy,
4888 const RecordDecl *KmpTaskTWithPrivatesQTyRD,
4889 const RecordDecl *KmpTaskTQTyRD, QualType SharedsTy,
4890 QualType SharedsPtrTy, const OMPTaskDataTy &Data,
4891 ArrayRef<PrivateDataTy> Privates, bool WithLastIter) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004892 ASTContext &C = CGM.getContext();
Alexey Bataevf93095a2016-05-05 08:46:22 +00004893 FunctionArgList Args;
Alexey Bataev56223232017-06-09 13:40:18 +00004894 ImplicitParamDecl DstArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4895 KmpTaskTWithPrivatesPtrQTy,
4896 ImplicitParamDecl::Other);
4897 ImplicitParamDecl SrcArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4898 KmpTaskTWithPrivatesPtrQTy,
4899 ImplicitParamDecl::Other);
4900 ImplicitParamDecl LastprivArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.IntTy,
4901 ImplicitParamDecl::Other);
Alexey Bataevf93095a2016-05-05 08:46:22 +00004902 Args.push_back(&DstArg);
4903 Args.push_back(&SrcArg);
4904 Args.push_back(&LastprivArg);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004905 const auto &TaskDupFnInfo =
Alexey Bataevf93095a2016-05-05 08:46:22 +00004906 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004907 llvm::FunctionType *TaskDupTy = CGM.getTypes().GetFunctionType(TaskDupFnInfo);
Alexey Bataev18fa2322018-05-02 14:20:50 +00004908 std::string Name = CGM.getOpenMPRuntime().getName({"omp_task_dup", ""});
4909 auto *TaskDup = llvm::Function::Create(
4910 TaskDupTy, llvm::GlobalValue::InternalLinkage, Name, &CGM.getModule());
Rafael Espindola51ec5a92018-02-28 23:46:35 +00004911 CGM.SetInternalFunctionAttributes(GlobalDecl(), TaskDup, TaskDupFnInfo);
Alexey Bataevc0f879b2018-04-10 20:10:53 +00004912 TaskDup->setDoesNotRecurse();
Alexey Bataevf93095a2016-05-05 08:46:22 +00004913 CodeGenFunction CGF(CGM);
Alexey Bataev7cae94e2018-01-04 19:45:16 +00004914 CGF.StartFunction(GlobalDecl(), C.VoidTy, TaskDup, TaskDupFnInfo, Args, Loc,
4915 Loc);
Alexey Bataevf93095a2016-05-05 08:46:22 +00004916
4917 LValue TDBase = CGF.EmitLoadOfPointerLValue(
4918 CGF.GetAddrOfLocalVar(&DstArg),
4919 KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
4920 // task_dst->liter = lastpriv;
4921 if (WithLastIter) {
4922 auto LIFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLastIter);
4923 LValue Base = CGF.EmitLValueForField(
4924 TDBase, *KmpTaskTWithPrivatesQTyRD->field_begin());
4925 LValue LILVal = CGF.EmitLValueForField(Base, *LIFI);
4926 llvm::Value *Lastpriv = CGF.EmitLoadOfScalar(
4927 CGF.GetAddrOfLocalVar(&LastprivArg), /*Volatile=*/false, C.IntTy, Loc);
4928 CGF.EmitStoreOfScalar(Lastpriv, LILVal);
4929 }
4930
4931 // Emit initial values for private copies (if any).
4932 assert(!Privates.empty());
4933 Address KmpTaskSharedsPtr = Address::invalid();
4934 if (!Data.FirstprivateVars.empty()) {
4935 LValue TDBase = CGF.EmitLoadOfPointerLValue(
4936 CGF.GetAddrOfLocalVar(&SrcArg),
4937 KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
4938 LValue Base = CGF.EmitLValueForField(
4939 TDBase, *KmpTaskTWithPrivatesQTyRD->field_begin());
4940 KmpTaskSharedsPtr = Address(
4941 CGF.EmitLoadOfScalar(CGF.EmitLValueForField(
4942 Base, *std::next(KmpTaskTQTyRD->field_begin(),
4943 KmpTaskTShareds)),
4944 Loc),
4945 CGF.getNaturalTypeAlignment(SharedsTy));
4946 }
Alexey Bataev8a831592016-05-10 10:36:51 +00004947 emitPrivatesInit(CGF, D, KmpTaskSharedsPtr, TDBase, KmpTaskTWithPrivatesQTyRD,
4948 SharedsTy, SharedsPtrTy, Data, Privates, /*ForDup=*/true);
Alexey Bataevf93095a2016-05-05 08:46:22 +00004949 CGF.FinishFunction();
4950 return TaskDup;
4951}
4952
Alexey Bataev8a831592016-05-10 10:36:51 +00004953/// Checks if destructor function is required to be generated.
4954/// \return true if cleanups are required, false otherwise.
4955static bool
4956checkDestructorsRequired(const RecordDecl *KmpTaskTWithPrivatesQTyRD) {
4957 bool NeedsCleanup = false;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004958 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin(), 1);
4959 const auto *PrivateRD = cast<RecordDecl>(FI->getType()->getAsTagDecl());
4960 for (const FieldDecl *FD : PrivateRD->fields()) {
Alexey Bataev8a831592016-05-10 10:36:51 +00004961 NeedsCleanup = NeedsCleanup || FD->getType().isDestructedType();
4962 if (NeedsCleanup)
4963 break;
4964 }
4965 return NeedsCleanup;
4966}
4967
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004968CGOpenMPRuntime::TaskResultTy
4969CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
4970 const OMPExecutableDirective &D,
James Y Knight9871db02019-02-05 16:42:33 +00004971 llvm::Function *TaskFunction, QualType SharedsTy,
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004972 Address Shareds, const OMPTaskDataTy &Data) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004973 ASTContext &C = CGM.getContext();
Alexey Bataev7292c292016-04-25 12:22:29 +00004974 llvm::SmallVector<PrivateDataTy, 4> Privates;
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004975 // Aggregate privates and sort them by the alignment.
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004976 auto I = Data.PrivateCopies.begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004977 for (const Expr *E : Data.PrivateVars) {
4978 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataev43a919f2018-04-13 17:48:43 +00004979 Privates.emplace_back(
Alexey Bataevc71a4092015-09-11 10:29:41 +00004980 C.getDeclAlign(VD),
Alexey Bataev9e034042015-05-05 04:05:12 +00004981 PrivateHelpersTy(VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
Alexey Bataev43a919f2018-04-13 17:48:43 +00004982 /*PrivateElemInit=*/nullptr));
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004983 ++I;
4984 }
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004985 I = Data.FirstprivateCopies.begin();
4986 auto IElemInitRef = Data.FirstprivateInits.begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004987 for (const Expr *E : Data.FirstprivateVars) {
4988 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataev43a919f2018-04-13 17:48:43 +00004989 Privates.emplace_back(
Alexey Bataevc71a4092015-09-11 10:29:41 +00004990 C.getDeclAlign(VD),
Alexey Bataev9e034042015-05-05 04:05:12 +00004991 PrivateHelpersTy(
4992 VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
Alexey Bataev43a919f2018-04-13 17:48:43 +00004993 cast<VarDecl>(cast<DeclRefExpr>(*IElemInitRef)->getDecl())));
Richard Trieucc3949d2016-02-18 22:34:54 +00004994 ++I;
4995 ++IElemInitRef;
Alexey Bataev9e034042015-05-05 04:05:12 +00004996 }
Alexey Bataevf93095a2016-05-05 08:46:22 +00004997 I = Data.LastprivateCopies.begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004998 for (const Expr *E : Data.LastprivateVars) {
4999 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataev43a919f2018-04-13 17:48:43 +00005000 Privates.emplace_back(
Alexey Bataevf93095a2016-05-05 08:46:22 +00005001 C.getDeclAlign(VD),
5002 PrivateHelpersTy(VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
Alexey Bataev43a919f2018-04-13 17:48:43 +00005003 /*PrivateElemInit=*/nullptr));
Alexey Bataevf93095a2016-05-05 08:46:22 +00005004 ++I;
5005 }
Fangrui Song899d1392019-04-24 14:43:05 +00005006 llvm::stable_sort(Privates, [](PrivateDataTy L, PrivateDataTy R) {
5007 return L.first > R.first;
5008 });
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005009 QualType KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
Alexey Bataev62b63b12015-03-10 07:28:44 +00005010 // Build type kmp_routine_entry_t (if not built yet).
5011 emitKmpRoutineEntryT(KmpInt32Ty);
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00005012 // Build type kmp_task_t (if not built yet).
Alexey Bataeve213f3e2017-10-11 15:29:40 +00005013 if (isOpenMPTaskLoopDirective(D.getDirectiveKind())) {
5014 if (SavedKmpTaskloopTQTy.isNull()) {
5015 SavedKmpTaskloopTQTy = C.getRecordType(createKmpTaskTRecordDecl(
5016 CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy));
5017 }
5018 KmpTaskTQTy = SavedKmpTaskloopTQTy;
Alexey Bataev3a03a7f2017-10-11 15:56:38 +00005019 } else {
Alexey Bataevd2202ca2017-12-27 17:58:32 +00005020 assert((D.getDirectiveKind() == OMPD_task ||
5021 isOpenMPTargetExecutionDirective(D.getDirectiveKind()) ||
5022 isOpenMPTargetDataManagementDirective(D.getDirectiveKind())) &&
5023 "Expected taskloop, task or target directive");
Alexey Bataeve213f3e2017-10-11 15:29:40 +00005024 if (SavedKmpTaskTQTy.isNull()) {
5025 SavedKmpTaskTQTy = C.getRecordType(createKmpTaskTRecordDecl(
5026 CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy));
5027 }
5028 KmpTaskTQTy = SavedKmpTaskTQTy;
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00005029 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005030 const auto *KmpTaskTQTyRD = cast<RecordDecl>(KmpTaskTQTy->getAsTagDecl());
Alexey Bataev62b63b12015-03-10 07:28:44 +00005031 // Build particular struct kmp_task_t for the given task.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005032 const RecordDecl *KmpTaskTWithPrivatesQTyRD =
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00005033 createKmpTaskTWithPrivatesRecordDecl(CGM, KmpTaskTQTy, Privates);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005034 QualType KmpTaskTWithPrivatesQTy = C.getRecordType(KmpTaskTWithPrivatesQTyRD);
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00005035 QualType KmpTaskTWithPrivatesPtrQTy =
5036 C.getPointerType(KmpTaskTWithPrivatesQTy);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005037 llvm::Type *KmpTaskTWithPrivatesTy = CGF.ConvertType(KmpTaskTWithPrivatesQTy);
5038 llvm::Type *KmpTaskTWithPrivatesPtrTy =
5039 KmpTaskTWithPrivatesTy->getPointerTo();
5040 llvm::Value *KmpTaskTWithPrivatesTySize =
5041 CGF.getTypeSize(KmpTaskTWithPrivatesQTy);
Alexey Bataev62b63b12015-03-10 07:28:44 +00005042 QualType SharedsPtrTy = C.getPointerType(SharedsTy);
5043
Alexey Bataev3ae88e22015-05-22 08:56:35 +00005044 // Emit initial values for private copies (if any).
5045 llvm::Value *TaskPrivatesMap = nullptr;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005046 llvm::Type *TaskPrivatesMapTy =
James Y Knight9871db02019-02-05 16:42:33 +00005047 std::next(TaskFunction->arg_begin(), 3)->getType();
Alexey Bataev3ae88e22015-05-22 08:56:35 +00005048 if (!Privates.empty()) {
5049 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
Alexey Bataevf93095a2016-05-05 08:46:22 +00005050 TaskPrivatesMap = emitTaskPrivateMappingFunction(
5051 CGM, Loc, Data.PrivateVars, Data.FirstprivateVars, Data.LastprivateVars,
5052 FI->getType(), Privates);
Alexey Bataev3ae88e22015-05-22 08:56:35 +00005053 TaskPrivatesMap = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5054 TaskPrivatesMap, TaskPrivatesMapTy);
5055 } else {
5056 TaskPrivatesMap = llvm::ConstantPointerNull::get(
5057 cast<llvm::PointerType>(TaskPrivatesMapTy));
5058 }
Alexey Bataev62b63b12015-03-10 07:28:44 +00005059 // Build a proxy function kmp_int32 .omp_task_entry.(kmp_int32 gtid,
5060 // kmp_task_t *tt);
James Y Knight9871db02019-02-05 16:42:33 +00005061 llvm::Function *TaskEntry = emitProxyTaskFunction(
Alexey Bataev7292c292016-04-25 12:22:29 +00005062 CGM, Loc, D.getDirectiveKind(), KmpInt32Ty, KmpTaskTWithPrivatesPtrQTy,
5063 KmpTaskTWithPrivatesQTy, KmpTaskTQTy, SharedsPtrTy, TaskFunction,
5064 TaskPrivatesMap);
Alexey Bataev62b63b12015-03-10 07:28:44 +00005065
5066 // Build call kmp_task_t * __kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid,
5067 // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
5068 // kmp_routine_entry_t *task_entry);
5069 // Task flags. Format is taken from
James Y Knight5d71fc52019-01-29 16:37:27 +00005070 // https://github.com/llvm/llvm-project/blob/master/openmp/runtime/src/kmp.h,
Alexey Bataev62b63b12015-03-10 07:28:44 +00005071 // description of kmp_tasking_flags struct.
Alexey Bataev1e1e2862016-05-10 12:21:02 +00005072 enum {
5073 TiedFlag = 0x1,
5074 FinalFlag = 0x2,
5075 DestructorsFlag = 0x8,
5076 PriorityFlag = 0x20
5077 };
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005078 unsigned Flags = Data.Tied ? TiedFlag : 0;
Alexey Bataev8a831592016-05-10 10:36:51 +00005079 bool NeedsCleanup = false;
5080 if (!Privates.empty()) {
5081 NeedsCleanup = checkDestructorsRequired(KmpTaskTWithPrivatesQTyRD);
5082 if (NeedsCleanup)
5083 Flags = Flags | DestructorsFlag;
5084 }
Alexey Bataev1e1e2862016-05-10 12:21:02 +00005085 if (Data.Priority.getInt())
5086 Flags = Flags | PriorityFlag;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005087 llvm::Value *TaskFlags =
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005088 Data.Final.getPointer()
5089 ? CGF.Builder.CreateSelect(Data.Final.getPointer(),
Alexey Bataev62b63b12015-03-10 07:28:44 +00005090 CGF.Builder.getInt32(FinalFlag),
5091 CGF.Builder.getInt32(/*C=*/0))
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005092 : CGF.Builder.getInt32(Data.Final.getInt() ? FinalFlag : 0);
Alexey Bataev62b63b12015-03-10 07:28:44 +00005093 TaskFlags = CGF.Builder.CreateOr(TaskFlags, CGF.Builder.getInt32(Flags));
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005094 llvm::Value *SharedsSize = CGM.getSize(C.getTypeSizeInChars(SharedsTy));
Gheorghe-Teodor Bercea545a9fe2019-06-14 20:19:54 +00005095 SmallVector<llvm::Value *, 8> AllocArgs = {emitUpdateLocation(CGF, Loc),
5096 getThreadID(CGF, Loc), TaskFlags, KmpTaskTWithPrivatesTySize,
5097 SharedsSize, CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5098 TaskEntry, KmpRoutineEntryPtrTy)};
5099 llvm::Value *NewTask;
5100 if (D.hasClausesOfKind<OMPNowaitClause>()) {
5101 // Check if we have any device clause associated with the directive.
5102 const Expr *Device = nullptr;
5103 if (auto *C = D.getSingleClause<OMPDeviceClause>())
5104 Device = C->getDevice();
5105 // Emit device ID if any otherwise use default value.
5106 llvm::Value *DeviceID;
5107 if (Device)
5108 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
5109 CGF.Int64Ty, /*isSigned=*/true);
5110 else
5111 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
5112 AllocArgs.push_back(DeviceID);
5113 NewTask = CGF.EmitRuntimeCall(
5114 createRuntimeFunction(OMPRTL__kmpc_omp_target_task_alloc), AllocArgs);
5115 } else {
5116 NewTask = CGF.EmitRuntimeCall(
Alexey Bataev62b63b12015-03-10 07:28:44 +00005117 createRuntimeFunction(OMPRTL__kmpc_omp_task_alloc), AllocArgs);
Gheorghe-Teodor Bercea545a9fe2019-06-14 20:19:54 +00005118 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005119 llvm::Value *NewTaskNewTaskTTy =
5120 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5121 NewTask, KmpTaskTWithPrivatesPtrTy);
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00005122 LValue Base = CGF.MakeNaturalAlignAddrLValue(NewTaskNewTaskTTy,
5123 KmpTaskTWithPrivatesQTy);
5124 LValue TDBase =
5125 CGF.EmitLValueForField(Base, *KmpTaskTWithPrivatesQTyRD->field_begin());
Alexey Bataev62b63b12015-03-10 07:28:44 +00005126 // Fill the data in the resulting kmp_task_t record.
5127 // Copy shareds if there are any.
John McCall7f416cc2015-09-08 08:05:57 +00005128 Address KmpTaskSharedsPtr = Address::invalid();
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00005129 if (!SharedsTy->getAsStructureType()->getDecl()->field_empty()) {
Alexey Bataev2377fe92015-09-10 08:12:02 +00005130 KmpTaskSharedsPtr =
5131 Address(CGF.EmitLoadOfScalar(
5132 CGF.EmitLValueForField(
5133 TDBase, *std::next(KmpTaskTQTyRD->field_begin(),
5134 KmpTaskTShareds)),
5135 Loc),
5136 CGF.getNaturalTypeAlignment(SharedsTy));
Ivan A. Kosarev1860b522018-01-25 14:21:55 +00005137 LValue Dest = CGF.MakeAddrLValue(KmpTaskSharedsPtr, SharedsTy);
5138 LValue Src = CGF.MakeAddrLValue(Shareds, SharedsTy);
Richard Smithe78fac52018-04-05 20:52:58 +00005139 CGF.EmitAggregateCopy(Dest, Src, SharedsTy, AggValueSlot::DoesNotOverlap);
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00005140 }
Alexey Bataev36c1eb92015-04-30 06:51:57 +00005141 // Emit initial values for private copies (if any).
Alexey Bataevf93095a2016-05-05 08:46:22 +00005142 TaskResultTy Result;
Alexey Bataev36c1eb92015-04-30 06:51:57 +00005143 if (!Privates.empty()) {
Alexey Bataev8a831592016-05-10 10:36:51 +00005144 emitPrivatesInit(CGF, D, KmpTaskSharedsPtr, Base, KmpTaskTWithPrivatesQTyRD,
5145 SharedsTy, SharedsPtrTy, Data, Privates,
5146 /*ForDup=*/false);
Alexey Bataevf93095a2016-05-05 08:46:22 +00005147 if (isOpenMPTaskLoopDirective(D.getDirectiveKind()) &&
5148 (!Data.LastprivateVars.empty() || checkInitIsRequired(CGF, Privates))) {
5149 Result.TaskDupFn = emitTaskDupFunction(
5150 CGM, Loc, D, KmpTaskTWithPrivatesPtrQTy, KmpTaskTWithPrivatesQTyRD,
5151 KmpTaskTQTyRD, SharedsTy, SharedsPtrTy, Data, Privates,
5152 /*WithLastIter=*/!Data.LastprivateVars.empty());
Alexey Bataev36c1eb92015-04-30 06:51:57 +00005153 }
5154 }
Alexey Bataevad537bb2016-05-30 09:06:50 +00005155 // Fields of union "kmp_cmplrdata_t" for destructors and priority.
5156 enum { Priority = 0, Destructors = 1 };
Alexey Bataev62b63b12015-03-10 07:28:44 +00005157 // Provide pointer to function with destructors for privates.
Alexey Bataevad537bb2016-05-30 09:06:50 +00005158 auto FI = std::next(KmpTaskTQTyRD->field_begin(), Data1);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005159 const RecordDecl *KmpCmplrdataUD =
5160 (*FI)->getType()->getAsUnionType()->getDecl();
Alexey Bataevad537bb2016-05-30 09:06:50 +00005161 if (NeedsCleanup) {
5162 llvm::Value *DestructorFn = emitDestructorsFunction(
5163 CGM, Loc, KmpInt32Ty, KmpTaskTWithPrivatesPtrQTy,
5164 KmpTaskTWithPrivatesQTy);
5165 LValue Data1LV = CGF.EmitLValueForField(TDBase, *FI);
5166 LValue DestructorsLV = CGF.EmitLValueForField(
5167 Data1LV, *std::next(KmpCmplrdataUD->field_begin(), Destructors));
5168 CGF.EmitStoreOfScalar(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5169 DestructorFn, KmpRoutineEntryPtrTy),
5170 DestructorsLV);
5171 }
5172 // Set priority.
5173 if (Data.Priority.getInt()) {
5174 LValue Data2LV = CGF.EmitLValueForField(
5175 TDBase, *std::next(KmpTaskTQTyRD->field_begin(), Data2));
5176 LValue PriorityLV = CGF.EmitLValueForField(
5177 Data2LV, *std::next(KmpCmplrdataUD->field_begin(), Priority));
5178 CGF.EmitStoreOfScalar(Data.Priority.getPointer(), PriorityLV);
5179 }
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005180 Result.NewTask = NewTask;
5181 Result.TaskEntry = TaskEntry;
5182 Result.NewTaskNewTaskTTy = NewTaskNewTaskTTy;
5183 Result.TDBase = TDBase;
5184 Result.KmpTaskTQTyRD = KmpTaskTQTyRD;
5185 return Result;
Alexey Bataev7292c292016-04-25 12:22:29 +00005186}
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005187
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005188void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
5189 const OMPExecutableDirective &D,
James Y Knight9871db02019-02-05 16:42:33 +00005190 llvm::Function *TaskFunction,
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005191 QualType SharedsTy, Address Shareds,
5192 const Expr *IfCond,
5193 const OMPTaskDataTy &Data) {
Alexey Bataev7292c292016-04-25 12:22:29 +00005194 if (!CGF.HaveInsertPoint())
5195 return;
5196
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005197 TaskResultTy Result =
5198 emitTaskInit(CGF, Loc, D, TaskFunction, SharedsTy, Shareds, Data);
5199 llvm::Value *NewTask = Result.NewTask;
James Y Knight9871db02019-02-05 16:42:33 +00005200 llvm::Function *TaskEntry = Result.TaskEntry;
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005201 llvm::Value *NewTaskNewTaskTTy = Result.NewTaskNewTaskTTy;
5202 LValue TDBase = Result.TDBase;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005203 const RecordDecl *KmpTaskTQTyRD = Result.KmpTaskTQTyRD;
5204 ASTContext &C = CGM.getContext();
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005205 // Process list of dependences.
John McCall7f416cc2015-09-08 08:05:57 +00005206 Address DependenciesArray = Address::invalid();
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005207 unsigned NumDependencies = Data.Dependences.size();
John McCall7f416cc2015-09-08 08:05:57 +00005208 if (NumDependencies) {
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005209 // Dependence kind for RTL.
Sergi Mateo Bellido31df1ad2019-02-04 07:33:19 +00005210 enum RTLDependenceKindTy { DepIn = 0x01, DepInOut = 0x3, DepMutexInOutSet = 0x4 };
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005211 enum RTLDependInfoFieldsTy { BaseAddr, Len, Flags };
5212 RecordDecl *KmpDependInfoRD;
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005213 QualType FlagsTy =
5214 C.getIntTypeForBitwidth(C.getTypeSize(C.BoolTy), /*Signed=*/false);
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005215 llvm::Type *LLVMFlagsTy = CGF.ConvertTypeForMem(FlagsTy);
5216 if (KmpDependInfoTy.isNull()) {
5217 KmpDependInfoRD = C.buildImplicitRecord("kmp_depend_info");
5218 KmpDependInfoRD->startDefinition();
5219 addFieldToRecordDecl(C, KmpDependInfoRD, C.getIntPtrType());
5220 addFieldToRecordDecl(C, KmpDependInfoRD, C.getSizeType());
5221 addFieldToRecordDecl(C, KmpDependInfoRD, FlagsTy);
5222 KmpDependInfoRD->completeDefinition();
5223 KmpDependInfoTy = C.getRecordType(KmpDependInfoRD);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005224 } else {
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005225 KmpDependInfoRD = cast<RecordDecl>(KmpDependInfoTy->getAsTagDecl());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005226 }
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005227 // Define type kmp_depend_info[<Dependences.size()>];
5228 QualType KmpDependInfoArrayTy = C.getConstantArrayType(
John McCall7f416cc2015-09-08 08:05:57 +00005229 KmpDependInfoTy, llvm::APInt(/*numBits=*/64, NumDependencies),
Richard Smith772e2662019-10-04 01:25:59 +00005230 nullptr, ArrayType::Normal, /*IndexTypeQuals=*/0);
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005231 // kmp_depend_info[<Dependences.size()>] deps;
Alexey Bataev48591dd2016-04-20 04:01:36 +00005232 DependenciesArray =
5233 CGF.CreateMemTemp(KmpDependInfoArrayTy, ".dep.arr.addr");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005234 for (unsigned I = 0; I < NumDependencies; ++I) {
5235 const Expr *E = Data.Dependences[I].second;
5236 LValue Addr = CGF.EmitLValue(E);
Alexey Bataevd6fdc8b2015-08-31 07:32:19 +00005237 llvm::Value *Size;
5238 QualType Ty = E->getType();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005239 if (const auto *ASE =
5240 dyn_cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts())) {
Alexey Bataevd6fdc8b2015-08-31 07:32:19 +00005241 LValue UpAddrLVal =
Rui Ueyama49a3ad22019-07-16 04:46:31 +00005242 CGF.EmitOMPArraySectionExpr(ASE, /*IsLowerBound=*/false);
Akira Hatanakaf139ae32019-12-03 15:17:01 -08005243 llvm::Value *UpAddr = CGF.Builder.CreateConstGEP1_32(
5244 UpAddrLVal.getPointer(CGF), /*Idx0=*/1);
Alexey Bataevd6fdc8b2015-08-31 07:32:19 +00005245 llvm::Value *LowIntPtr =
Akira Hatanakaf139ae32019-12-03 15:17:01 -08005246 CGF.Builder.CreatePtrToInt(Addr.getPointer(CGF), CGM.SizeTy);
Alexey Bataevd6fdc8b2015-08-31 07:32:19 +00005247 llvm::Value *UpIntPtr = CGF.Builder.CreatePtrToInt(UpAddr, CGM.SizeTy);
5248 Size = CGF.Builder.CreateNUWSub(UpIntPtr, LowIntPtr);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005249 } else {
Alexey Bataev1189bd02016-01-26 12:20:39 +00005250 Size = CGF.getTypeSize(Ty);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005251 }
5252 LValue Base = CGF.MakeAddrLValue(
James Y Knight751fe282019-02-09 22:22:28 +00005253 CGF.Builder.CreateConstArrayGEP(DependenciesArray, I),
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005254 KmpDependInfoTy);
5255 // deps[i].base_addr = &<Dependences[i].second>;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005256 LValue BaseAddrLVal = CGF.EmitLValueForField(
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005257 Base, *std::next(KmpDependInfoRD->field_begin(), BaseAddr));
John McCall7f416cc2015-09-08 08:05:57 +00005258 CGF.EmitStoreOfScalar(
Akira Hatanakaf139ae32019-12-03 15:17:01 -08005259 CGF.Builder.CreatePtrToInt(Addr.getPointer(CGF), CGF.IntPtrTy),
John McCall7f416cc2015-09-08 08:05:57 +00005260 BaseAddrLVal);
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005261 // deps[i].len = sizeof(<Dependences[i].second>);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005262 LValue LenLVal = CGF.EmitLValueForField(
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005263 Base, *std::next(KmpDependInfoRD->field_begin(), Len));
5264 CGF.EmitStoreOfScalar(Size, LenLVal);
5265 // deps[i].flags = <Dependences[i].first>;
5266 RTLDependenceKindTy DepKind;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005267 switch (Data.Dependences[I].first) {
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005268 case OMPC_DEPEND_in:
5269 DepKind = DepIn;
5270 break;
Alexey Bataev92e82f92015-11-23 13:33:42 +00005271 // Out and InOut dependencies must use the same code.
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005272 case OMPC_DEPEND_out:
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005273 case OMPC_DEPEND_inout:
5274 DepKind = DepInOut;
5275 break;
Sergi Mateo Bellido31df1ad2019-02-04 07:33:19 +00005276 case OMPC_DEPEND_mutexinoutset:
5277 DepKind = DepMutexInOutSet;
5278 break;
Alexey Bataeveb482352015-12-18 05:05:56 +00005279 case OMPC_DEPEND_source:
Alexey Bataeva636c7f2015-12-23 10:27:45 +00005280 case OMPC_DEPEND_sink:
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005281 case OMPC_DEPEND_unknown:
5282 llvm_unreachable("Unknown task dependence type");
5283 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005284 LValue FlagsLVal = CGF.EmitLValueForField(
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005285 Base, *std::next(KmpDependInfoRD->field_begin(), Flags));
5286 CGF.EmitStoreOfScalar(llvm::ConstantInt::get(LLVMFlagsTy, DepKind),
5287 FlagsLVal);
5288 }
John McCall7f416cc2015-09-08 08:05:57 +00005289 DependenciesArray = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
James Y Knightf5f1b0e2019-02-08 15:34:12 +00005290 CGF.Builder.CreateConstArrayGEP(DependenciesArray, 0), CGF.VoidPtrTy);
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005291 }
5292
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +00005293 // NOTE: routine and part_id fields are initialized by __kmpc_omp_task_alloc()
Alexey Bataev62b63b12015-03-10 07:28:44 +00005294 // libcall.
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005295 // Build kmp_int32 __kmpc_omp_task_with_deps(ident_t *, kmp_int32 gtid,
5296 // kmp_task_t *new_task, kmp_int32 ndeps, kmp_depend_info_t *dep_list,
5297 // kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list) if dependence
5298 // list is not empty
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005299 llvm::Value *ThreadID = getThreadID(CGF, Loc);
5300 llvm::Value *UpLoc = emitUpdateLocation(CGF, Loc);
John McCall7f416cc2015-09-08 08:05:57 +00005301 llvm::Value *TaskArgs[] = { UpLoc, ThreadID, NewTask };
5302 llvm::Value *DepTaskArgs[7];
5303 if (NumDependencies) {
5304 DepTaskArgs[0] = UpLoc;
5305 DepTaskArgs[1] = ThreadID;
5306 DepTaskArgs[2] = NewTask;
5307 DepTaskArgs[3] = CGF.Builder.getInt32(NumDependencies);
5308 DepTaskArgs[4] = DependenciesArray.getPointer();
5309 DepTaskArgs[5] = CGF.Builder.getInt32(0);
5310 DepTaskArgs[6] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
5311 }
Malcolm Parsonsc6e45832017-01-13 18:55:32 +00005312 auto &&ThenCodeGen = [this, &Data, TDBase, KmpTaskTQTyRD, NumDependencies,
5313 &TaskArgs,
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005314 &DepTaskArgs](CodeGenFunction &CGF, PrePostActionTy &) {
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005315 if (!Data.Tied) {
Alexey Bataev48591dd2016-04-20 04:01:36 +00005316 auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005317 LValue PartIdLVal = CGF.EmitLValueForField(TDBase, *PartIdFI);
Alexey Bataev48591dd2016-04-20 04:01:36 +00005318 CGF.EmitStoreOfScalar(CGF.Builder.getInt32(0), PartIdLVal);
5319 }
John McCall7f416cc2015-09-08 08:05:57 +00005320 if (NumDependencies) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005321 CGF.EmitRuntimeCall(
Alexey Bataev48591dd2016-04-20 04:01:36 +00005322 createRuntimeFunction(OMPRTL__kmpc_omp_task_with_deps), DepTaskArgs);
John McCall7f416cc2015-09-08 08:05:57 +00005323 } else {
Alexey Bataev48591dd2016-04-20 04:01:36 +00005324 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_task),
John McCall7f416cc2015-09-08 08:05:57 +00005325 TaskArgs);
5326 }
Alexey Bataev48591dd2016-04-20 04:01:36 +00005327 // Check if parent region is untied and build return for untied task;
5328 if (auto *Region =
5329 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
5330 Region->emitUntiedSwitch(CGF);
Alexey Bataev1d677132015-04-22 13:57:31 +00005331 };
John McCall7f416cc2015-09-08 08:05:57 +00005332
5333 llvm::Value *DepWaitTaskArgs[6];
5334 if (NumDependencies) {
5335 DepWaitTaskArgs[0] = UpLoc;
5336 DepWaitTaskArgs[1] = ThreadID;
5337 DepWaitTaskArgs[2] = CGF.Builder.getInt32(NumDependencies);
5338 DepWaitTaskArgs[3] = DependenciesArray.getPointer();
5339 DepWaitTaskArgs[4] = CGF.Builder.getInt32(0);
5340 DepWaitTaskArgs[5] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
5341 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005342 auto &&ElseCodeGen = [&TaskArgs, ThreadID, NewTaskNewTaskTTy, TaskEntry,
Alexey Bataev3c595a62017-08-14 15:01:03 +00005343 NumDependencies, &DepWaitTaskArgs,
5344 Loc](CodeGenFunction &CGF, PrePostActionTy &) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005345 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005346 CodeGenFunction::RunCleanupsScope LocalScope(CGF);
5347 // Build void __kmpc_omp_wait_deps(ident_t *, kmp_int32 gtid,
5348 // kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32
5349 // ndeps_noalias, kmp_depend_info_t *noalias_dep_list); if dependence info
5350 // is specified.
John McCall7f416cc2015-09-08 08:05:57 +00005351 if (NumDependencies)
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005352 CGF.EmitRuntimeCall(RT.createRuntimeFunction(OMPRTL__kmpc_omp_wait_deps),
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005353 DepWaitTaskArgs);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005354 // Call proxy_task_entry(gtid, new_task);
Alexey Bataev3c595a62017-08-14 15:01:03 +00005355 auto &&CodeGen = [TaskEntry, ThreadID, NewTaskNewTaskTTy,
5356 Loc](CodeGenFunction &CGF, PrePostActionTy &Action) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005357 Action.Enter(CGF);
5358 llvm::Value *OutlinedFnArgs[] = {ThreadID, NewTaskNewTaskTTy};
Alexey Bataev3c595a62017-08-14 15:01:03 +00005359 CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, Loc, TaskEntry,
Alexey Bataev2c7eee52017-08-04 19:10:54 +00005360 OutlinedFnArgs);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005361 };
5362
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005363 // Build void __kmpc_omp_task_begin_if0(ident_t *, kmp_int32 gtid,
5364 // kmp_task_t *new_task);
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005365 // Build void __kmpc_omp_task_complete_if0(ident_t *, kmp_int32 gtid,
5366 // kmp_task_t *new_task);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005367 RegionCodeGenTy RCG(CodeGen);
5368 CommonActionTy Action(
5369 RT.createRuntimeFunction(OMPRTL__kmpc_omp_task_begin_if0), TaskArgs,
5370 RT.createRuntimeFunction(OMPRTL__kmpc_omp_task_complete_if0), TaskArgs);
5371 RCG.setAction(Action);
5372 RCG(CGF);
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005373 };
John McCall7f416cc2015-09-08 08:05:57 +00005374
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005375 if (IfCond) {
Alexey Bataev1d943ae2019-11-19 12:12:23 -05005376 emitIfClause(CGF, IfCond, ThenCodeGen, ElseCodeGen);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005377 } else {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005378 RegionCodeGenTy ThenRCG(ThenCodeGen);
5379 ThenRCG(CGF);
Alexey Bataevf539faa2016-03-28 12:58:34 +00005380 }
Alexey Bataev62b63b12015-03-10 07:28:44 +00005381}
5382
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005383void CGOpenMPRuntime::emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc,
5384 const OMPLoopDirective &D,
James Y Knight9871db02019-02-05 16:42:33 +00005385 llvm::Function *TaskFunction,
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005386 QualType SharedsTy, Address Shareds,
5387 const Expr *IfCond,
5388 const OMPTaskDataTy &Data) {
Alexey Bataev7292c292016-04-25 12:22:29 +00005389 if (!CGF.HaveInsertPoint())
5390 return;
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005391 TaskResultTy Result =
5392 emitTaskInit(CGF, Loc, D, TaskFunction, SharedsTy, Shareds, Data);
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +00005393 // NOTE: routine and part_id fields are initialized by __kmpc_omp_task_alloc()
Alexey Bataev7292c292016-04-25 12:22:29 +00005394 // libcall.
5395 // Call to void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t *task, int
5396 // if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int nogroup, int
5397 // sched, kmp_uint64 grainsize, void *task_dup);
5398 llvm::Value *ThreadID = getThreadID(CGF, Loc);
5399 llvm::Value *UpLoc = emitUpdateLocation(CGF, Loc);
5400 llvm::Value *IfVal;
5401 if (IfCond) {
5402 IfVal = CGF.Builder.CreateIntCast(CGF.EvaluateExprAsBool(IfCond), CGF.IntTy,
5403 /*isSigned=*/true);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005404 } else {
Alexey Bataev7292c292016-04-25 12:22:29 +00005405 IfVal = llvm::ConstantInt::getSigned(CGF.IntTy, /*V=*/1);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005406 }
Alexey Bataev7292c292016-04-25 12:22:29 +00005407
5408 LValue LBLVal = CGF.EmitLValueForField(
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005409 Result.TDBase,
5410 *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTLowerBound));
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005411 const auto *LBVar =
Alexey Bataev7292c292016-04-25 12:22:29 +00005412 cast<VarDecl>(cast<DeclRefExpr>(D.getLowerBoundVariable())->getDecl());
Akira Hatanakaf139ae32019-12-03 15:17:01 -08005413 CGF.EmitAnyExprToMem(LBVar->getInit(), LBLVal.getAddress(CGF),
5414 LBLVal.getQuals(),
Alexey Bataev7292c292016-04-25 12:22:29 +00005415 /*IsInitializer=*/true);
5416 LValue UBLVal = CGF.EmitLValueForField(
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005417 Result.TDBase,
5418 *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTUpperBound));
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005419 const auto *UBVar =
Alexey Bataev7292c292016-04-25 12:22:29 +00005420 cast<VarDecl>(cast<DeclRefExpr>(D.getUpperBoundVariable())->getDecl());
Akira Hatanakaf139ae32019-12-03 15:17:01 -08005421 CGF.EmitAnyExprToMem(UBVar->getInit(), UBLVal.getAddress(CGF),
5422 UBLVal.getQuals(),
Alexey Bataev7292c292016-04-25 12:22:29 +00005423 /*IsInitializer=*/true);
5424 LValue StLVal = CGF.EmitLValueForField(
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005425 Result.TDBase,
5426 *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTStride));
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005427 const auto *StVar =
Alexey Bataev7292c292016-04-25 12:22:29 +00005428 cast<VarDecl>(cast<DeclRefExpr>(D.getStrideVariable())->getDecl());
Akira Hatanakaf139ae32019-12-03 15:17:01 -08005429 CGF.EmitAnyExprToMem(StVar->getInit(), StLVal.getAddress(CGF),
5430 StLVal.getQuals(),
Alexey Bataev7292c292016-04-25 12:22:29 +00005431 /*IsInitializer=*/true);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00005432 // Store reductions address.
5433 LValue RedLVal = CGF.EmitLValueForField(
5434 Result.TDBase,
5435 *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTReductions));
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005436 if (Data.Reductions) {
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00005437 CGF.EmitStoreOfScalar(Data.Reductions, RedLVal);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005438 } else {
Akira Hatanakaf139ae32019-12-03 15:17:01 -08005439 CGF.EmitNullInitialization(RedLVal.getAddress(CGF),
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00005440 CGF.getContext().VoidPtrTy);
5441 }
Alexey Bataev2b19a6f2016-04-28 09:15:06 +00005442 enum { NoSchedule = 0, Grainsize = 1, NumTasks = 2 };
Alexey Bataev7292c292016-04-25 12:22:29 +00005443 llvm::Value *TaskArgs[] = {
Alexey Bataev33446032017-07-12 18:09:32 +00005444 UpLoc,
5445 ThreadID,
5446 Result.NewTask,
5447 IfVal,
Akira Hatanakaf139ae32019-12-03 15:17:01 -08005448 LBLVal.getPointer(CGF),
5449 UBLVal.getPointer(CGF),
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00005450 CGF.EmitLoadOfScalar(StLVal, Loc),
Alexey Bataevac6e4de2018-10-24 19:06:37 +00005451 llvm::ConstantInt::getSigned(
Akira Hatanakaf139ae32019-12-03 15:17:01 -08005452 CGF.IntTy, 1), // Always 1 because taskgroup emitted by the compiler
Alexey Bataev2b19a6f2016-04-28 09:15:06 +00005453 llvm::ConstantInt::getSigned(
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005454 CGF.IntTy, Data.Schedule.getPointer()
5455 ? Data.Schedule.getInt() ? NumTasks : Grainsize
Alexey Bataev2b19a6f2016-04-28 09:15:06 +00005456 : NoSchedule),
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005457 Data.Schedule.getPointer()
5458 ? CGF.Builder.CreateIntCast(Data.Schedule.getPointer(), CGF.Int64Ty,
Alexey Bataev2b19a6f2016-04-28 09:15:06 +00005459 /*isSigned=*/false)
5460 : llvm::ConstantInt::get(CGF.Int64Ty, /*V=*/0),
Alexey Bataev33446032017-07-12 18:09:32 +00005461 Result.TaskDupFn ? CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5462 Result.TaskDupFn, CGF.VoidPtrTy)
5463 : llvm::ConstantPointerNull::get(CGF.VoidPtrTy)};
Alexey Bataev7292c292016-04-25 12:22:29 +00005464 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_taskloop), TaskArgs);
5465}
5466
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005467/// Emit reduction operation for each element of array (required for
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005468/// array sections) LHS op = RHS.
5469/// \param Type Type of array.
5470/// \param LHSVar Variable on the left side of the reduction operation
5471/// (references element of array in original variable).
5472/// \param RHSVar Variable on the right side of the reduction operation
5473/// (references element of array in original variable).
5474/// \param RedOpGen Generator of reduction operation with use of LHSVar and
5475/// RHSVar.
Benjamin Kramere003ca22015-10-28 13:54:16 +00005476static void EmitOMPAggregateReduction(
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005477 CodeGenFunction &CGF, QualType Type, const VarDecl *LHSVar,
5478 const VarDecl *RHSVar,
5479 const llvm::function_ref<void(CodeGenFunction &CGF, const Expr *,
5480 const Expr *, const Expr *)> &RedOpGen,
5481 const Expr *XExpr = nullptr, const Expr *EExpr = nullptr,
5482 const Expr *UpExpr = nullptr) {
5483 // Perform element-by-element initialization.
5484 QualType ElementTy;
5485 Address LHSAddr = CGF.GetAddrOfLocalVar(LHSVar);
5486 Address RHSAddr = CGF.GetAddrOfLocalVar(RHSVar);
5487
5488 // Drill down to the base element type on both arrays.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005489 const ArrayType *ArrayTy = Type->getAsArrayTypeUnsafe();
5490 llvm::Value *NumElements = CGF.emitArrayLength(ArrayTy, ElementTy, LHSAddr);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005491
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005492 llvm::Value *RHSBegin = RHSAddr.getPointer();
5493 llvm::Value *LHSBegin = LHSAddr.getPointer();
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005494 // Cast from pointer to array type to pointer to single element.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005495 llvm::Value *LHSEnd = CGF.Builder.CreateGEP(LHSBegin, NumElements);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005496 // The basic structure here is a while-do loop.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005497 llvm::BasicBlock *BodyBB = CGF.createBasicBlock("omp.arraycpy.body");
5498 llvm::BasicBlock *DoneBB = CGF.createBasicBlock("omp.arraycpy.done");
5499 llvm::Value *IsEmpty =
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005500 CGF.Builder.CreateICmpEQ(LHSBegin, LHSEnd, "omp.arraycpy.isempty");
5501 CGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
5502
5503 // Enter the loop body, making that address the current address.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005504 llvm::BasicBlock *EntryBB = CGF.Builder.GetInsertBlock();
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005505 CGF.EmitBlock(BodyBB);
5506
5507 CharUnits ElementSize = CGF.getContext().getTypeSizeInChars(ElementTy);
5508
5509 llvm::PHINode *RHSElementPHI = CGF.Builder.CreatePHI(
5510 RHSBegin->getType(), 2, "omp.arraycpy.srcElementPast");
5511 RHSElementPHI->addIncoming(RHSBegin, EntryBB);
5512 Address RHSElementCurrent =
5513 Address(RHSElementPHI,
5514 RHSAddr.getAlignment().alignmentOfArrayElement(ElementSize));
5515
5516 llvm::PHINode *LHSElementPHI = CGF.Builder.CreatePHI(
5517 LHSBegin->getType(), 2, "omp.arraycpy.destElementPast");
5518 LHSElementPHI->addIncoming(LHSBegin, EntryBB);
5519 Address LHSElementCurrent =
5520 Address(LHSElementPHI,
5521 LHSAddr.getAlignment().alignmentOfArrayElement(ElementSize));
5522
5523 // Emit copy.
5524 CodeGenFunction::OMPPrivateScope Scope(CGF);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005525 Scope.addPrivate(LHSVar, [=]() { return LHSElementCurrent; });
5526 Scope.addPrivate(RHSVar, [=]() { return RHSElementCurrent; });
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005527 Scope.Privatize();
5528 RedOpGen(CGF, XExpr, EExpr, UpExpr);
5529 Scope.ForceCleanup();
5530
5531 // Shift the address forward by one element.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005532 llvm::Value *LHSElementNext = CGF.Builder.CreateConstGEP1_32(
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005533 LHSElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005534 llvm::Value *RHSElementNext = CGF.Builder.CreateConstGEP1_32(
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005535 RHSElementPHI, /*Idx0=*/1, "omp.arraycpy.src.element");
5536 // Check whether we've reached the end.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005537 llvm::Value *Done =
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005538 CGF.Builder.CreateICmpEQ(LHSElementNext, LHSEnd, "omp.arraycpy.done");
5539 CGF.Builder.CreateCondBr(Done, DoneBB, BodyBB);
5540 LHSElementPHI->addIncoming(LHSElementNext, CGF.Builder.GetInsertBlock());
5541 RHSElementPHI->addIncoming(RHSElementNext, CGF.Builder.GetInsertBlock());
5542
5543 // Done.
5544 CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
5545}
5546
Alexey Bataeva839ddd2016-03-17 10:19:46 +00005547/// Emit reduction combiner. If the combiner is a simple expression emit it as
5548/// is, otherwise consider it as combiner of UDR decl and emit it as a call of
5549/// UDR combiner function.
5550static void emitReductionCombiner(CodeGenFunction &CGF,
5551 const Expr *ReductionOp) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005552 if (const auto *CE = dyn_cast<CallExpr>(ReductionOp))
5553 if (const auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee()))
5554 if (const auto *DRE =
Alexey Bataeva839ddd2016-03-17 10:19:46 +00005555 dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts()))
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005556 if (const auto *DRD =
5557 dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl())) {
Alexey Bataeva839ddd2016-03-17 10:19:46 +00005558 std::pair<llvm::Function *, llvm::Function *> Reduction =
5559 CGF.CGM.getOpenMPRuntime().getUserDefinedReduction(DRD);
5560 RValue Func = RValue::get(Reduction.first);
5561 CodeGenFunction::OpaqueValueMapping Map(CGF, OVE, Func);
5562 CGF.EmitIgnoredExpr(ReductionOp);
5563 return;
5564 }
5565 CGF.EmitIgnoredExpr(ReductionOp);
5566}
5567
James Y Knight9871db02019-02-05 16:42:33 +00005568llvm::Function *CGOpenMPRuntime::emitReductionFunction(
Alexey Bataev982a35e2019-03-19 17:09:52 +00005569 SourceLocation Loc, llvm::Type *ArgsType, ArrayRef<const Expr *> Privates,
5570 ArrayRef<const Expr *> LHSExprs, ArrayRef<const Expr *> RHSExprs,
5571 ArrayRef<const Expr *> ReductionOps) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005572 ASTContext &C = CGM.getContext();
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005573
5574 // void reduction_func(void *LHSArg, void *RHSArg);
5575 FunctionArgList Args;
Alexey Bataev7cae94e2018-01-04 19:45:16 +00005576 ImplicitParamDecl LHSArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
5577 ImplicitParamDecl::Other);
5578 ImplicitParamDecl RHSArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
5579 ImplicitParamDecl::Other);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005580 Args.push_back(&LHSArg);
5581 Args.push_back(&RHSArg);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005582 const auto &CGFI =
5583 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
Alexey Bataev18fa2322018-05-02 14:20:50 +00005584 std::string Name = getName({"omp", "reduction", "reduction_func"});
5585 auto *Fn = llvm::Function::Create(CGM.getTypes().GetFunctionType(CGFI),
5586 llvm::GlobalValue::InternalLinkage, Name,
5587 &CGM.getModule());
Rafael Espindola51ec5a92018-02-28 23:46:35 +00005588 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, CGFI);
Alexey Bataevc0f879b2018-04-10 20:10:53 +00005589 Fn->setDoesNotRecurse();
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005590 CodeGenFunction CGF(CGM);
Alexey Bataev7cae94e2018-01-04 19:45:16 +00005591 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args, Loc, Loc);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005592
5593 // Dst = (void*[n])(LHSArg);
5594 // Src = (void*[n])(RHSArg);
John McCall7f416cc2015-09-08 08:05:57 +00005595 Address LHS(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5596 CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&LHSArg)),
5597 ArgsType), CGF.getPointerAlign());
5598 Address RHS(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5599 CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&RHSArg)),
5600 ArgsType), CGF.getPointerAlign());
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005601
5602 // ...
5603 // *(Type<i>*)lhs[i] = RedOp<i>(*(Type<i>*)lhs[i], *(Type<i>*)rhs[i]);
5604 // ...
5605 CodeGenFunction::OMPPrivateScope Scope(CGF);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005606 auto IPriv = Privates.begin();
5607 unsigned Idx = 0;
5608 for (unsigned I = 0, E = ReductionOps.size(); I < E; ++I, ++IPriv, ++Idx) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005609 const auto *RHSVar =
5610 cast<VarDecl>(cast<DeclRefExpr>(RHSExprs[I])->getDecl());
5611 Scope.addPrivate(RHSVar, [&CGF, RHS, Idx, RHSVar]() {
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005612 return emitAddrOfVarFromArray(CGF, RHS, Idx, RHSVar);
John McCall7f416cc2015-09-08 08:05:57 +00005613 });
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005614 const auto *LHSVar =
5615 cast<VarDecl>(cast<DeclRefExpr>(LHSExprs[I])->getDecl());
5616 Scope.addPrivate(LHSVar, [&CGF, LHS, Idx, LHSVar]() {
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005617 return emitAddrOfVarFromArray(CGF, LHS, Idx, LHSVar);
John McCall7f416cc2015-09-08 08:05:57 +00005618 });
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005619 QualType PrivTy = (*IPriv)->getType();
Alexey Bataev1189bd02016-01-26 12:20:39 +00005620 if (PrivTy->isVariablyModifiedType()) {
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005621 // Get array size and emit VLA type.
5622 ++Idx;
James Y Knight751fe282019-02-09 22:22:28 +00005623 Address Elem = CGF.Builder.CreateConstArrayGEP(LHS, Idx);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005624 llvm::Value *Ptr = CGF.Builder.CreateLoad(Elem);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005625 const VariableArrayType *VLA =
5626 CGF.getContext().getAsVariableArrayType(PrivTy);
5627 const auto *OVE = cast<OpaqueValueExpr>(VLA->getSizeExpr());
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005628 CodeGenFunction::OpaqueValueMapping OpaqueMap(
Alexey Bataev1189bd02016-01-26 12:20:39 +00005629 CGF, OVE, RValue::get(CGF.Builder.CreatePtrToInt(Ptr, CGF.SizeTy)));
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005630 CGF.EmitVariablyModifiedType(PrivTy);
5631 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005632 }
5633 Scope.Privatize();
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005634 IPriv = Privates.begin();
5635 auto ILHS = LHSExprs.begin();
5636 auto IRHS = RHSExprs.begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005637 for (const Expr *E : ReductionOps) {
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005638 if ((*IPriv)->getType()->isArrayType()) {
5639 // Emit reduction for array section.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005640 const auto *LHSVar = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
5641 const auto *RHSVar = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
Alexey Bataeva839ddd2016-03-17 10:19:46 +00005642 EmitOMPAggregateReduction(
5643 CGF, (*IPriv)->getType(), LHSVar, RHSVar,
5644 [=](CodeGenFunction &CGF, const Expr *, const Expr *, const Expr *) {
5645 emitReductionCombiner(CGF, E);
5646 });
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005647 } else {
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005648 // Emit reduction for array subscript or single variable.
Alexey Bataeva839ddd2016-03-17 10:19:46 +00005649 emitReductionCombiner(CGF, E);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005650 }
Richard Trieucc3949d2016-02-18 22:34:54 +00005651 ++IPriv;
5652 ++ILHS;
5653 ++IRHS;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005654 }
5655 Scope.ForceCleanup();
5656 CGF.FinishFunction();
5657 return Fn;
5658}
5659
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00005660void CGOpenMPRuntime::emitSingleReductionCombiner(CodeGenFunction &CGF,
5661 const Expr *ReductionOp,
5662 const Expr *PrivateRef,
5663 const DeclRefExpr *LHS,
5664 const DeclRefExpr *RHS) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005665 if (PrivateRef->getType()->isArrayType()) {
5666 // Emit reduction for array section.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005667 const auto *LHSVar = cast<VarDecl>(LHS->getDecl());
5668 const auto *RHSVar = cast<VarDecl>(RHS->getDecl());
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005669 EmitOMPAggregateReduction(
5670 CGF, PrivateRef->getType(), LHSVar, RHSVar,
5671 [=](CodeGenFunction &CGF, const Expr *, const Expr *, const Expr *) {
5672 emitReductionCombiner(CGF, ReductionOp);
5673 });
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005674 } else {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005675 // Emit reduction for array subscript or single variable.
5676 emitReductionCombiner(CGF, ReductionOp);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005677 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005678}
5679
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005680void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005681 ArrayRef<const Expr *> Privates,
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005682 ArrayRef<const Expr *> LHSExprs,
5683 ArrayRef<const Expr *> RHSExprs,
5684 ArrayRef<const Expr *> ReductionOps,
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00005685 ReductionOptionsTy Options) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00005686 if (!CGF.HaveInsertPoint())
5687 return;
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00005688
5689 bool WithNowait = Options.WithNowait;
5690 bool SimpleReduction = Options.SimpleReduction;
5691
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005692 // Next code should be emitted for reduction:
5693 //
5694 // static kmp_critical_name lock = { 0 };
5695 //
5696 // void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
5697 // *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
5698 // ...
5699 // *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
5700 // *(Type<n>-1*)rhs[<n>-1]);
5701 // }
5702 //
5703 // ...
5704 // void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n>-1]};
5705 // switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList),
5706 // RedList, reduce_func, &<lock>)) {
5707 // case 1:
5708 // ...
5709 // <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
5710 // ...
5711 // __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
5712 // break;
5713 // case 2:
5714 // ...
5715 // Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
5716 // ...
Alexey Bataev69a47792015-05-07 03:54:03 +00005717 // [__kmpc_end_reduce(<loc>, <gtid>, &<lock>);]
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005718 // break;
5719 // default:;
5720 // }
Alexey Bataev89e7e8e2015-06-17 06:21:39 +00005721 //
5722 // if SimpleReduction is true, only the next code is generated:
5723 // ...
5724 // <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
5725 // ...
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005726
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005727 ASTContext &C = CGM.getContext();
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005728
Alexey Bataev89e7e8e2015-06-17 06:21:39 +00005729 if (SimpleReduction) {
5730 CodeGenFunction::RunCleanupsScope Scope(CGF);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005731 auto IPriv = Privates.begin();
5732 auto ILHS = LHSExprs.begin();
5733 auto IRHS = RHSExprs.begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005734 for (const Expr *E : ReductionOps) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005735 emitSingleReductionCombiner(CGF, E, *IPriv, cast<DeclRefExpr>(*ILHS),
5736 cast<DeclRefExpr>(*IRHS));
Richard Trieucc3949d2016-02-18 22:34:54 +00005737 ++IPriv;
5738 ++ILHS;
5739 ++IRHS;
Alexey Bataev89e7e8e2015-06-17 06:21:39 +00005740 }
5741 return;
5742 }
5743
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005744 // 1. Build a list of reduction variables.
5745 // void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005746 auto Size = RHSExprs.size();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005747 for (const Expr *E : Privates) {
Alexey Bataev1189bd02016-01-26 12:20:39 +00005748 if (E->getType()->isVariablyModifiedType())
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005749 // Reserve place for array size.
5750 ++Size;
5751 }
5752 llvm::APInt ArraySize(/*unsigned int numBits=*/32, Size);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005753 QualType ReductionArrayTy =
Richard Smith772e2662019-10-04 01:25:59 +00005754 C.getConstantArrayType(C.VoidPtrTy, ArraySize, nullptr, ArrayType::Normal,
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005755 /*IndexTypeQuals=*/0);
John McCall7f416cc2015-09-08 08:05:57 +00005756 Address ReductionList =
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005757 CGF.CreateMemTemp(ReductionArrayTy, ".omp.reduction.red_list");
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005758 auto IPriv = Privates.begin();
5759 unsigned Idx = 0;
5760 for (unsigned I = 0, E = RHSExprs.size(); I < E; ++I, ++IPriv, ++Idx) {
James Y Knight751fe282019-02-09 22:22:28 +00005761 Address Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx);
John McCall7f416cc2015-09-08 08:05:57 +00005762 CGF.Builder.CreateStore(
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005763 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
Akira Hatanakaf139ae32019-12-03 15:17:01 -08005764 CGF.EmitLValue(RHSExprs[I]).getPointer(CGF), CGF.VoidPtrTy),
John McCall7f416cc2015-09-08 08:05:57 +00005765 Elem);
Alexey Bataev1189bd02016-01-26 12:20:39 +00005766 if ((*IPriv)->getType()->isVariablyModifiedType()) {
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005767 // Store array size.
5768 ++Idx;
James Y Knight751fe282019-02-09 22:22:28 +00005769 Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx);
Alexey Bataev1189bd02016-01-26 12:20:39 +00005770 llvm::Value *Size = CGF.Builder.CreateIntCast(
5771 CGF.getVLASize(
5772 CGF.getContext().getAsVariableArrayType((*IPriv)->getType()))
Sander de Smalen891af03a2018-02-03 13:55:59 +00005773 .NumElts,
Alexey Bataev1189bd02016-01-26 12:20:39 +00005774 CGF.SizeTy, /*isSigned=*/false);
5775 CGF.Builder.CreateStore(CGF.Builder.CreateIntToPtr(Size, CGF.VoidPtrTy),
5776 Elem);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005777 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005778 }
5779
5780 // 2. Emit reduce_func().
James Y Knight9871db02019-02-05 16:42:33 +00005781 llvm::Function *ReductionFn = emitReductionFunction(
Alexey Bataev982a35e2019-03-19 17:09:52 +00005782 Loc, CGF.ConvertTypeForMem(ReductionArrayTy)->getPointerTo(), Privates,
5783 LHSExprs, RHSExprs, ReductionOps);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005784
5785 // 3. Create static kmp_critical_name lock = { 0 };
Alexey Bataev18fa2322018-05-02 14:20:50 +00005786 std::string Name = getName({"reduction"});
5787 llvm::Value *Lock = getCriticalRegionLock(Name);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005788
5789 // 4. Build res = __kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList),
5790 // RedList, reduce_func, &<lock>);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005791 llvm::Value *IdentTLoc = emitUpdateLocation(CGF, Loc, OMP_ATOMIC_REDUCE);
5792 llvm::Value *ThreadId = getThreadID(CGF, Loc);
5793 llvm::Value *ReductionArrayTySize = CGF.getTypeSize(ReductionArrayTy);
5794 llvm::Value *RL = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
Samuel Antao4c8035b2016-12-12 18:00:20 +00005795 ReductionList.getPointer(), CGF.VoidPtrTy);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005796 llvm::Value *Args[] = {
5797 IdentTLoc, // ident_t *<loc>
5798 ThreadId, // i32 <gtid>
5799 CGF.Builder.getInt32(RHSExprs.size()), // i32 <n>
5800 ReductionArrayTySize, // size_type sizeof(RedList)
5801 RL, // void *RedList
5802 ReductionFn, // void (*) (void *, void *) <reduce_func>
5803 Lock // kmp_critical_name *&<lock>
5804 };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005805 llvm::Value *Res = CGF.EmitRuntimeCall(
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005806 createRuntimeFunction(WithNowait ? OMPRTL__kmpc_reduce_nowait
5807 : OMPRTL__kmpc_reduce),
5808 Args);
5809
5810 // 5. Build switch(res)
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005811 llvm::BasicBlock *DefaultBB = CGF.createBasicBlock(".omp.reduction.default");
5812 llvm::SwitchInst *SwInst =
5813 CGF.Builder.CreateSwitch(Res, DefaultBB, /*NumCases=*/2);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005814
5815 // 6. Build case 1:
5816 // ...
5817 // <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
5818 // ...
5819 // __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
5820 // break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005821 llvm::BasicBlock *Case1BB = CGF.createBasicBlock(".omp.reduction.case1");
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005822 SwInst->addCase(CGF.Builder.getInt32(1), Case1BB);
5823 CGF.EmitBlock(Case1BB);
5824
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005825 // Add emission of __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
5826 llvm::Value *EndArgs[] = {
5827 IdentTLoc, // ident_t *<loc>
5828 ThreadId, // i32 <gtid>
5829 Lock // kmp_critical_name *&<lock>
5830 };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005831 auto &&CodeGen = [Privates, LHSExprs, RHSExprs, ReductionOps](
5832 CodeGenFunction &CGF, PrePostActionTy &Action) {
5833 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005834 auto IPriv = Privates.begin();
5835 auto ILHS = LHSExprs.begin();
5836 auto IRHS = RHSExprs.begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005837 for (const Expr *E : ReductionOps) {
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00005838 RT.emitSingleReductionCombiner(CGF, E, *IPriv, cast<DeclRefExpr>(*ILHS),
5839 cast<DeclRefExpr>(*IRHS));
Richard Trieucc3949d2016-02-18 22:34:54 +00005840 ++IPriv;
5841 ++ILHS;
5842 ++IRHS;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005843 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005844 };
5845 RegionCodeGenTy RCG(CodeGen);
5846 CommonActionTy Action(
5847 nullptr, llvm::None,
5848 createRuntimeFunction(WithNowait ? OMPRTL__kmpc_end_reduce_nowait
5849 : OMPRTL__kmpc_end_reduce),
5850 EndArgs);
5851 RCG.setAction(Action);
5852 RCG(CGF);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005853
5854 CGF.EmitBranch(DefaultBB);
5855
5856 // 7. Build case 2:
5857 // ...
5858 // Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
5859 // ...
5860 // break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005861 llvm::BasicBlock *Case2BB = CGF.createBasicBlock(".omp.reduction.case2");
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005862 SwInst->addCase(CGF.Builder.getInt32(2), Case2BB);
5863 CGF.EmitBlock(Case2BB);
5864
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005865 auto &&AtomicCodeGen = [Loc, Privates, LHSExprs, RHSExprs, ReductionOps](
5866 CodeGenFunction &CGF, PrePostActionTy &Action) {
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005867 auto ILHS = LHSExprs.begin();
5868 auto IRHS = RHSExprs.begin();
5869 auto IPriv = Privates.begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005870 for (const Expr *E : ReductionOps) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005871 const Expr *XExpr = nullptr;
5872 const Expr *EExpr = nullptr;
5873 const Expr *UpExpr = nullptr;
5874 BinaryOperatorKind BO = BO_Comma;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005875 if (const auto *BO = dyn_cast<BinaryOperator>(E)) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005876 if (BO->getOpcode() == BO_Assign) {
5877 XExpr = BO->getLHS();
5878 UpExpr = BO->getRHS();
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005879 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005880 }
5881 // Try to emit update expression as a simple atomic.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005882 const Expr *RHSExpr = UpExpr;
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005883 if (RHSExpr) {
5884 // Analyze RHS part of the whole expression.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005885 if (const auto *ACO = dyn_cast<AbstractConditionalOperator>(
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005886 RHSExpr->IgnoreParenImpCasts())) {
5887 // If this is a conditional operator, analyze its condition for
5888 // min/max reduction operator.
5889 RHSExpr = ACO->getCond();
Alexey Bataev69a47792015-05-07 03:54:03 +00005890 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005891 if (const auto *BORHS =
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005892 dyn_cast<BinaryOperator>(RHSExpr->IgnoreParenImpCasts())) {
5893 EExpr = BORHS->getRHS();
5894 BO = BORHS->getOpcode();
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005895 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005896 }
5897 if (XExpr) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005898 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
Malcolm Parsonsc6e45832017-01-13 18:55:32 +00005899 auto &&AtomicRedGen = [BO, VD,
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005900 Loc](CodeGenFunction &CGF, const Expr *XExpr,
5901 const Expr *EExpr, const Expr *UpExpr) {
5902 LValue X = CGF.EmitLValue(XExpr);
5903 RValue E;
5904 if (EExpr)
5905 E = CGF.EmitAnyExpr(EExpr);
5906 CGF.EmitOMPAtomicSimpleUpdateExpr(
JF Bastien92f4ef12016-04-06 17:26:42 +00005907 X, E, BO, /*IsXLHSInRHSPart=*/true,
5908 llvm::AtomicOrdering::Monotonic, Loc,
Malcolm Parsonsc6e45832017-01-13 18:55:32 +00005909 [&CGF, UpExpr, VD, Loc](RValue XRValue) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005910 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
5911 PrivateScope.addPrivate(
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005912 VD, [&CGF, VD, XRValue, Loc]() {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005913 Address LHSTemp = CGF.CreateMemTemp(VD->getType());
5914 CGF.emitOMPSimpleStore(
5915 CGF.MakeAddrLValue(LHSTemp, VD->getType()), XRValue,
5916 VD->getType().getNonReferenceType(), Loc);
5917 return LHSTemp;
5918 });
5919 (void)PrivateScope.Privatize();
5920 return CGF.EmitAnyExpr(UpExpr);
5921 });
5922 };
5923 if ((*IPriv)->getType()->isArrayType()) {
5924 // Emit atomic reduction for array section.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005925 const auto *RHSVar =
5926 cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005927 EmitOMPAggregateReduction(CGF, (*IPriv)->getType(), VD, RHSVar,
5928 AtomicRedGen, XExpr, EExpr, UpExpr);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005929 } else {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005930 // Emit atomic reduction for array subscript or single variable.
5931 AtomicRedGen(CGF, XExpr, EExpr, UpExpr);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005932 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005933 } else {
5934 // Emit as a critical region.
5935 auto &&CritRedGen = [E, Loc](CodeGenFunction &CGF, const Expr *,
Alexey Bataev18fa2322018-05-02 14:20:50 +00005936 const Expr *, const Expr *) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005937 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
Alexey Bataev18fa2322018-05-02 14:20:50 +00005938 std::string Name = RT.getName({"atomic_reduction"});
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005939 RT.emitCriticalRegion(
Alexey Bataev18fa2322018-05-02 14:20:50 +00005940 CGF, Name,
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005941 [=](CodeGenFunction &CGF, PrePostActionTy &Action) {
5942 Action.Enter(CGF);
5943 emitReductionCombiner(CGF, E);
5944 },
5945 Loc);
5946 };
5947 if ((*IPriv)->getType()->isArrayType()) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005948 const auto *LHSVar =
5949 cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
5950 const auto *RHSVar =
5951 cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005952 EmitOMPAggregateReduction(CGF, (*IPriv)->getType(), LHSVar, RHSVar,
5953 CritRedGen);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005954 } else {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005955 CritRedGen(CGF, nullptr, nullptr, nullptr);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005956 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005957 }
Richard Trieucc3949d2016-02-18 22:34:54 +00005958 ++ILHS;
5959 ++IRHS;
5960 ++IPriv;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005961 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005962 };
5963 RegionCodeGenTy AtomicRCG(AtomicCodeGen);
5964 if (!WithNowait) {
5965 // Add emission of __kmpc_end_reduce(<loc>, <gtid>, &<lock>);
5966 llvm::Value *EndArgs[] = {
5967 IdentTLoc, // ident_t *<loc>
5968 ThreadId, // i32 <gtid>
5969 Lock // kmp_critical_name *&<lock>
5970 };
5971 CommonActionTy Action(nullptr, llvm::None,
5972 createRuntimeFunction(OMPRTL__kmpc_end_reduce),
5973 EndArgs);
5974 AtomicRCG.setAction(Action);
5975 AtomicRCG(CGF);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005976 } else {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005977 AtomicRCG(CGF);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005978 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005979
5980 CGF.EmitBranch(DefaultBB);
5981 CGF.EmitBlock(DefaultBB, /*IsFinished=*/true);
5982}
5983
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00005984/// Generates unique name for artificial threadprivate variables.
Alexey Bataev1c44e152018-03-06 18:59:43 +00005985/// Format is: <Prefix> "." <Decl_mangled_name> "_" "<Decl_start_loc_raw_enc>"
5986static std::string generateUniqueName(CodeGenModule &CGM, StringRef Prefix,
5987 const Expr *Ref) {
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00005988 SmallString<256> Buffer;
5989 llvm::raw_svector_ostream Out(Buffer);
Alexey Bataev1c44e152018-03-06 18:59:43 +00005990 const clang::DeclRefExpr *DE;
5991 const VarDecl *D = ::getBaseDecl(Ref, DE);
5992 if (!D)
5993 D = cast<VarDecl>(cast<DeclRefExpr>(Ref)->getDecl());
5994 D = D->getCanonicalDecl();
Alexey Bataev18fa2322018-05-02 14:20:50 +00005995 std::string Name = CGM.getOpenMPRuntime().getName(
5996 {D->isLocalVarDeclOrParm() ? D->getName() : CGM.getMangledName(D)});
5997 Out << Prefix << Name << "_"
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005998 << D->getCanonicalDecl()->getBeginLoc().getRawEncoding();
Benjamin Krameradcd0262020-01-28 20:23:46 +01005999 return std::string(Out.str());
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006000}
6001
6002/// Emits reduction initializer function:
6003/// \code
6004/// void @.red_init(void* %arg) {
6005/// %0 = bitcast void* %arg to <type>*
6006/// store <type> <init>, <type>* %0
6007/// ret void
6008/// }
6009/// \endcode
6010static llvm::Value *emitReduceInitFunction(CodeGenModule &CGM,
6011 SourceLocation Loc,
6012 ReductionCodeGen &RCG, unsigned N) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006013 ASTContext &C = CGM.getContext();
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006014 FunctionArgList Args;
Alexey Bataev7cae94e2018-01-04 19:45:16 +00006015 ImplicitParamDecl Param(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
6016 ImplicitParamDecl::Other);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006017 Args.emplace_back(&Param);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006018 const auto &FnInfo =
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006019 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006020 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
Alexey Bataev18fa2322018-05-02 14:20:50 +00006021 std::string Name = CGM.getOpenMPRuntime().getName({"red_init", ""});
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006022 auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
Alexey Bataev18fa2322018-05-02 14:20:50 +00006023 Name, &CGM.getModule());
Rafael Espindola51ec5a92018-02-28 23:46:35 +00006024 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo);
Alexey Bataevc0f879b2018-04-10 20:10:53 +00006025 Fn->setDoesNotRecurse();
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006026 CodeGenFunction CGF(CGM);
Alexey Bataev7cae94e2018-01-04 19:45:16 +00006027 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, Loc, Loc);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006028 Address PrivateAddr = CGF.EmitLoadOfPointer(
6029 CGF.GetAddrOfLocalVar(&Param),
6030 C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
6031 llvm::Value *Size = nullptr;
6032 // If the size of the reduction item is non-constant, load it from global
6033 // threadprivate variable.
6034 if (RCG.getSizes(N).second) {
6035 Address SizeAddr = CGM.getOpenMPRuntime().getAddrOfArtificialThreadPrivate(
6036 CGF, CGM.getContext().getSizeType(),
Alexey Bataev1c44e152018-03-06 18:59:43 +00006037 generateUniqueName(CGM, "reduction_size", RCG.getRefExpr(N)));
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00006038 Size = CGF.EmitLoadOfScalar(SizeAddr, /*Volatile=*/false,
6039 CGM.getContext().getSizeType(), Loc);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006040 }
6041 RCG.emitAggregateType(CGF, N, Size);
6042 LValue SharedLVal;
6043 // If initializer uses initializer from declare reduction construct, emit a
6044 // pointer to the address of the original reduction item (reuired by reduction
6045 // initializer)
6046 if (RCG.usesReductionInitializer(N)) {
6047 Address SharedAddr =
6048 CGM.getOpenMPRuntime().getAddrOfArtificialThreadPrivate(
6049 CGF, CGM.getContext().VoidPtrTy,
Alexey Bataev1c44e152018-03-06 18:59:43 +00006050 generateUniqueName(CGM, "reduction", RCG.getRefExpr(N)));
Alexey Bataev21dab122018-03-09 15:20:30 +00006051 SharedAddr = CGF.EmitLoadOfPointer(
6052 SharedAddr,
6053 CGM.getContext().VoidPtrTy.castAs<PointerType>()->getTypePtr());
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006054 SharedLVal = CGF.MakeAddrLValue(SharedAddr, CGM.getContext().VoidPtrTy);
6055 } else {
6056 SharedLVal = CGF.MakeNaturalAlignAddrLValue(
6057 llvm::ConstantPointerNull::get(CGM.VoidPtrTy),
6058 CGM.getContext().VoidPtrTy);
6059 }
6060 // Emit the initializer:
6061 // %0 = bitcast void* %arg to <type>*
6062 // store <type> <init>, <type>* %0
6063 RCG.emitInitialization(CGF, N, PrivateAddr, SharedLVal,
6064 [](CodeGenFunction &) { return false; });
6065 CGF.FinishFunction();
6066 return Fn;
6067}
6068
6069/// Emits reduction combiner function:
6070/// \code
6071/// void @.red_comb(void* %arg0, void* %arg1) {
6072/// %lhs = bitcast void* %arg0 to <type>*
6073/// %rhs = bitcast void* %arg1 to <type>*
6074/// %2 = <ReductionOp>(<type>* %lhs, <type>* %rhs)
6075/// store <type> %2, <type>* %lhs
6076/// ret void
6077/// }
6078/// \endcode
6079static llvm::Value *emitReduceCombFunction(CodeGenModule &CGM,
6080 SourceLocation Loc,
6081 ReductionCodeGen &RCG, unsigned N,
6082 const Expr *ReductionOp,
6083 const Expr *LHS, const Expr *RHS,
6084 const Expr *PrivateRef) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006085 ASTContext &C = CGM.getContext();
6086 const auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(LHS)->getDecl());
6087 const auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(RHS)->getDecl());
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006088 FunctionArgList Args;
Alexey Bataev7cae94e2018-01-04 19:45:16 +00006089 ImplicitParamDecl ParamInOut(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
6090 C.VoidPtrTy, ImplicitParamDecl::Other);
6091 ImplicitParamDecl ParamIn(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
6092 ImplicitParamDecl::Other);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006093 Args.emplace_back(&ParamInOut);
6094 Args.emplace_back(&ParamIn);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006095 const auto &FnInfo =
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006096 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006097 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
Alexey Bataev18fa2322018-05-02 14:20:50 +00006098 std::string Name = CGM.getOpenMPRuntime().getName({"red_comb", ""});
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006099 auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
Alexey Bataev18fa2322018-05-02 14:20:50 +00006100 Name, &CGM.getModule());
Rafael Espindola51ec5a92018-02-28 23:46:35 +00006101 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo);
Alexey Bataevc0f879b2018-04-10 20:10:53 +00006102 Fn->setDoesNotRecurse();
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006103 CodeGenFunction CGF(CGM);
Alexey Bataev7cae94e2018-01-04 19:45:16 +00006104 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, Loc, Loc);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006105 llvm::Value *Size = nullptr;
6106 // If the size of the reduction item is non-constant, load it from global
6107 // threadprivate variable.
6108 if (RCG.getSizes(N).second) {
6109 Address SizeAddr = CGM.getOpenMPRuntime().getAddrOfArtificialThreadPrivate(
6110 CGF, CGM.getContext().getSizeType(),
Alexey Bataev1c44e152018-03-06 18:59:43 +00006111 generateUniqueName(CGM, "reduction_size", RCG.getRefExpr(N)));
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00006112 Size = CGF.EmitLoadOfScalar(SizeAddr, /*Volatile=*/false,
6113 CGM.getContext().getSizeType(), Loc);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006114 }
6115 RCG.emitAggregateType(CGF, N, Size);
6116 // Remap lhs and rhs variables to the addresses of the function arguments.
6117 // %lhs = bitcast void* %arg0 to <type>*
6118 // %rhs = bitcast void* %arg1 to <type>*
6119 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006120 PrivateScope.addPrivate(LHSVD, [&C, &CGF, &ParamInOut, LHSVD]() {
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006121 // Pull out the pointer to the variable.
6122 Address PtrAddr = CGF.EmitLoadOfPointer(
6123 CGF.GetAddrOfLocalVar(&ParamInOut),
6124 C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
6125 return CGF.Builder.CreateElementBitCast(
6126 PtrAddr, CGF.ConvertTypeForMem(LHSVD->getType()));
6127 });
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006128 PrivateScope.addPrivate(RHSVD, [&C, &CGF, &ParamIn, RHSVD]() {
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006129 // Pull out the pointer to the variable.
6130 Address PtrAddr = CGF.EmitLoadOfPointer(
6131 CGF.GetAddrOfLocalVar(&ParamIn),
6132 C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
6133 return CGF.Builder.CreateElementBitCast(
6134 PtrAddr, CGF.ConvertTypeForMem(RHSVD->getType()));
6135 });
6136 PrivateScope.Privatize();
6137 // Emit the combiner body:
6138 // %2 = <ReductionOp>(<type> *%lhs, <type> *%rhs)
6139 // store <type> %2, <type>* %lhs
6140 CGM.getOpenMPRuntime().emitSingleReductionCombiner(
6141 CGF, ReductionOp, PrivateRef, cast<DeclRefExpr>(LHS),
6142 cast<DeclRefExpr>(RHS));
6143 CGF.FinishFunction();
6144 return Fn;
6145}
6146
6147/// Emits reduction finalizer function:
6148/// \code
6149/// void @.red_fini(void* %arg) {
6150/// %0 = bitcast void* %arg to <type>*
6151/// <destroy>(<type>* %0)
6152/// ret void
6153/// }
6154/// \endcode
6155static llvm::Value *emitReduceFiniFunction(CodeGenModule &CGM,
6156 SourceLocation Loc,
6157 ReductionCodeGen &RCG, unsigned N) {
6158 if (!RCG.needCleanups(N))
6159 return nullptr;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006160 ASTContext &C = CGM.getContext();
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006161 FunctionArgList Args;
Alexey Bataev7cae94e2018-01-04 19:45:16 +00006162 ImplicitParamDecl Param(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
6163 ImplicitParamDecl::Other);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006164 Args.emplace_back(&Param);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006165 const auto &FnInfo =
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006166 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006167 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
Alexey Bataev18fa2322018-05-02 14:20:50 +00006168 std::string Name = CGM.getOpenMPRuntime().getName({"red_fini", ""});
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006169 auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
Alexey Bataev18fa2322018-05-02 14:20:50 +00006170 Name, &CGM.getModule());
Rafael Espindola51ec5a92018-02-28 23:46:35 +00006171 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo);
Alexey Bataevc0f879b2018-04-10 20:10:53 +00006172 Fn->setDoesNotRecurse();
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006173 CodeGenFunction CGF(CGM);
Alexey Bataev7cae94e2018-01-04 19:45:16 +00006174 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, Loc, Loc);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006175 Address PrivateAddr = CGF.EmitLoadOfPointer(
6176 CGF.GetAddrOfLocalVar(&Param),
6177 C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
6178 llvm::Value *Size = nullptr;
6179 // If the size of the reduction item is non-constant, load it from global
6180 // threadprivate variable.
6181 if (RCG.getSizes(N).second) {
6182 Address SizeAddr = CGM.getOpenMPRuntime().getAddrOfArtificialThreadPrivate(
6183 CGF, CGM.getContext().getSizeType(),
Alexey Bataev1c44e152018-03-06 18:59:43 +00006184 generateUniqueName(CGM, "reduction_size", RCG.getRefExpr(N)));
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00006185 Size = CGF.EmitLoadOfScalar(SizeAddr, /*Volatile=*/false,
6186 CGM.getContext().getSizeType(), Loc);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006187 }
6188 RCG.emitAggregateType(CGF, N, Size);
6189 // Emit the finalizer body:
6190 // <destroy>(<type>* %0)
6191 RCG.emitCleanups(CGF, N, PrivateAddr);
Adrian Prantlce7d3592019-12-05 12:26:16 -08006192 CGF.FinishFunction(Loc);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006193 return Fn;
6194}
6195
6196llvm::Value *CGOpenMPRuntime::emitTaskReductionInit(
6197 CodeGenFunction &CGF, SourceLocation Loc, ArrayRef<const Expr *> LHSExprs,
6198 ArrayRef<const Expr *> RHSExprs, const OMPTaskDataTy &Data) {
6199 if (!CGF.HaveInsertPoint() || Data.ReductionVars.empty())
6200 return nullptr;
6201
6202 // Build typedef struct:
6203 // kmp_task_red_input {
6204 // void *reduce_shar; // shared reduction item
6205 // size_t reduce_size; // size of data item
6206 // void *reduce_init; // data initialization routine
6207 // void *reduce_fini; // data finalization routine
6208 // void *reduce_comb; // data combiner routine
6209 // kmp_task_red_flags_t flags; // flags for additional info from compiler
6210 // } kmp_task_red_input_t;
6211 ASTContext &C = CGM.getContext();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006212 RecordDecl *RD = C.buildImplicitRecord("kmp_task_red_input_t");
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006213 RD->startDefinition();
6214 const FieldDecl *SharedFD = addFieldToRecordDecl(C, RD, C.VoidPtrTy);
6215 const FieldDecl *SizeFD = addFieldToRecordDecl(C, RD, C.getSizeType());
6216 const FieldDecl *InitFD = addFieldToRecordDecl(C, RD, C.VoidPtrTy);
6217 const FieldDecl *FiniFD = addFieldToRecordDecl(C, RD, C.VoidPtrTy);
6218 const FieldDecl *CombFD = addFieldToRecordDecl(C, RD, C.VoidPtrTy);
6219 const FieldDecl *FlagsFD = addFieldToRecordDecl(
6220 C, RD, C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/false));
6221 RD->completeDefinition();
6222 QualType RDType = C.getRecordType(RD);
6223 unsigned Size = Data.ReductionVars.size();
6224 llvm::APInt ArraySize(/*numBits=*/64, Size);
6225 QualType ArrayRDType = C.getConstantArrayType(
Richard Smith772e2662019-10-04 01:25:59 +00006226 RDType, ArraySize, nullptr, ArrayType::Normal, /*IndexTypeQuals=*/0);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006227 // kmp_task_red_input_t .rd_input.[Size];
6228 Address TaskRedInput = CGF.CreateMemTemp(ArrayRDType, ".rd_input.");
6229 ReductionCodeGen RCG(Data.ReductionVars, Data.ReductionCopies,
6230 Data.ReductionOps);
6231 for (unsigned Cnt = 0; Cnt < Size; ++Cnt) {
6232 // kmp_task_red_input_t &ElemLVal = .rd_input.[Cnt];
6233 llvm::Value *Idxs[] = {llvm::ConstantInt::get(CGM.SizeTy, /*V=*/0),
6234 llvm::ConstantInt::get(CGM.SizeTy, Cnt)};
6235 llvm::Value *GEP = CGF.EmitCheckedInBoundsGEP(
6236 TaskRedInput.getPointer(), Idxs,
6237 /*SignedIndices=*/false, /*IsSubtraction=*/false, Loc,
6238 ".rd_input.gep.");
6239 LValue ElemLVal = CGF.MakeNaturalAlignAddrLValue(GEP, RDType);
6240 // ElemLVal.reduce_shar = &Shareds[Cnt];
6241 LValue SharedLVal = CGF.EmitLValueForField(ElemLVal, SharedFD);
6242 RCG.emitSharedLValue(CGF, Cnt);
6243 llvm::Value *CastedShared =
Akira Hatanakaf139ae32019-12-03 15:17:01 -08006244 CGF.EmitCastToVoidPtr(RCG.getSharedLValue(Cnt).getPointer(CGF));
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006245 CGF.EmitStoreOfScalar(CastedShared, SharedLVal);
6246 RCG.emitAggregateType(CGF, Cnt);
6247 llvm::Value *SizeValInChars;
6248 llvm::Value *SizeVal;
6249 std::tie(SizeValInChars, SizeVal) = RCG.getSizes(Cnt);
6250 // We use delayed creation/initialization for VLAs, array sections and
6251 // custom reduction initializations. It is required because runtime does not
6252 // provide the way to pass the sizes of VLAs/array sections to
6253 // initializer/combiner/finalizer functions and does not pass the pointer to
6254 // original reduction item to the initializer. Instead threadprivate global
6255 // variables are used to store these values and use them in the functions.
6256 bool DelayedCreation = !!SizeVal;
6257 SizeValInChars = CGF.Builder.CreateIntCast(SizeValInChars, CGM.SizeTy,
6258 /*isSigned=*/false);
6259 LValue SizeLVal = CGF.EmitLValueForField(ElemLVal, SizeFD);
6260 CGF.EmitStoreOfScalar(SizeValInChars, SizeLVal);
6261 // ElemLVal.reduce_init = init;
6262 LValue InitLVal = CGF.EmitLValueForField(ElemLVal, InitFD);
6263 llvm::Value *InitAddr =
6264 CGF.EmitCastToVoidPtr(emitReduceInitFunction(CGM, Loc, RCG, Cnt));
6265 CGF.EmitStoreOfScalar(InitAddr, InitLVal);
6266 DelayedCreation = DelayedCreation || RCG.usesReductionInitializer(Cnt);
6267 // ElemLVal.reduce_fini = fini;
6268 LValue FiniLVal = CGF.EmitLValueForField(ElemLVal, FiniFD);
6269 llvm::Value *Fini = emitReduceFiniFunction(CGM, Loc, RCG, Cnt);
6270 llvm::Value *FiniAddr = Fini
6271 ? CGF.EmitCastToVoidPtr(Fini)
6272 : llvm::ConstantPointerNull::get(CGM.VoidPtrTy);
6273 CGF.EmitStoreOfScalar(FiniAddr, FiniLVal);
6274 // ElemLVal.reduce_comb = comb;
6275 LValue CombLVal = CGF.EmitLValueForField(ElemLVal, CombFD);
6276 llvm::Value *CombAddr = CGF.EmitCastToVoidPtr(emitReduceCombFunction(
6277 CGM, Loc, RCG, Cnt, Data.ReductionOps[Cnt], LHSExprs[Cnt],
6278 RHSExprs[Cnt], Data.ReductionCopies[Cnt]));
6279 CGF.EmitStoreOfScalar(CombAddr, CombLVal);
6280 // ElemLVal.flags = 0;
6281 LValue FlagsLVal = CGF.EmitLValueForField(ElemLVal, FlagsFD);
6282 if (DelayedCreation) {
6283 CGF.EmitStoreOfScalar(
Rui Ueyama49a3ad22019-07-16 04:46:31 +00006284 llvm::ConstantInt::get(CGM.Int32Ty, /*V=*/1, /*isSigned=*/true),
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006285 FlagsLVal);
6286 } else
Akira Hatanakaf139ae32019-12-03 15:17:01 -08006287 CGF.EmitNullInitialization(FlagsLVal.getAddress(CGF),
6288 FlagsLVal.getType());
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006289 }
6290 // Build call void *__kmpc_task_reduction_init(int gtid, int num_data, void
6291 // *data);
6292 llvm::Value *Args[] = {
6293 CGF.Builder.CreateIntCast(getThreadID(CGF, Loc), CGM.IntTy,
6294 /*isSigned=*/true),
6295 llvm::ConstantInt::get(CGM.IntTy, Size, /*isSigned=*/true),
6296 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(TaskRedInput.getPointer(),
6297 CGM.VoidPtrTy)};
6298 return CGF.EmitRuntimeCall(
6299 createRuntimeFunction(OMPRTL__kmpc_task_reduction_init), Args);
6300}
6301
6302void CGOpenMPRuntime::emitTaskReductionFixups(CodeGenFunction &CGF,
6303 SourceLocation Loc,
6304 ReductionCodeGen &RCG,
6305 unsigned N) {
6306 auto Sizes = RCG.getSizes(N);
6307 // Emit threadprivate global variable if the type is non-constant
6308 // (Sizes.second = nullptr).
6309 if (Sizes.second) {
6310 llvm::Value *SizeVal = CGF.Builder.CreateIntCast(Sizes.second, CGM.SizeTy,
6311 /*isSigned=*/false);
6312 Address SizeAddr = getAddrOfArtificialThreadPrivate(
6313 CGF, CGM.getContext().getSizeType(),
Alexey Bataev1c44e152018-03-06 18:59:43 +00006314 generateUniqueName(CGM, "reduction_size", RCG.getRefExpr(N)));
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006315 CGF.Builder.CreateStore(SizeVal, SizeAddr, /*IsVolatile=*/false);
6316 }
6317 // Store address of the original reduction item if custom initializer is used.
6318 if (RCG.usesReductionInitializer(N)) {
6319 Address SharedAddr = getAddrOfArtificialThreadPrivate(
6320 CGF, CGM.getContext().VoidPtrTy,
Alexey Bataev1c44e152018-03-06 18:59:43 +00006321 generateUniqueName(CGM, "reduction", RCG.getRefExpr(N)));
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006322 CGF.Builder.CreateStore(
6323 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
Akira Hatanakaf139ae32019-12-03 15:17:01 -08006324 RCG.getSharedLValue(N).getPointer(CGF), CGM.VoidPtrTy),
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006325 SharedAddr, /*IsVolatile=*/false);
6326 }
6327}
6328
6329Address CGOpenMPRuntime::getTaskReductionItem(CodeGenFunction &CGF,
6330 SourceLocation Loc,
6331 llvm::Value *ReductionsPtr,
6332 LValue SharedLVal) {
6333 // Build call void *__kmpc_task_reduction_get_th_data(int gtid, void *tg, void
6334 // *d);
Akira Hatanakaf139ae32019-12-03 15:17:01 -08006335 llvm::Value *Args[] = {CGF.Builder.CreateIntCast(getThreadID(CGF, Loc),
6336 CGM.IntTy,
6337 /*isSigned=*/true),
6338 ReductionsPtr,
6339 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
6340 SharedLVal.getPointer(CGF), CGM.VoidPtrTy)};
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006341 return Address(
6342 CGF.EmitRuntimeCall(
6343 createRuntimeFunction(OMPRTL__kmpc_task_reduction_get_th_data), Args),
6344 SharedLVal.getAlignment());
6345}
6346
Alexey Bataev8b8e2022015-04-27 05:22:09 +00006347void CGOpenMPRuntime::emitTaskwaitCall(CodeGenFunction &CGF,
6348 SourceLocation Loc) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00006349 if (!CGF.HaveInsertPoint())
6350 return;
Roger Ferrer Ibaneza82f35e2019-12-12 09:19:10 +00006351
6352 llvm::OpenMPIRBuilder *OMPBuilder = CGF.CGM.getOpenMPIRBuilder();
6353 if (OMPBuilder) {
6354 OMPBuilder->CreateTaskwait(CGF.Builder);
6355 } else {
6356 // Build call kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32
6357 // global_tid);
6358 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
6359 // Ignore return result until untied tasks are supported.
6360 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_taskwait), Args);
6361 }
6362
Alexey Bataev48591dd2016-04-20 04:01:36 +00006363 if (auto *Region = dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
6364 Region->emitUntiedSwitch(CGF);
Alexey Bataev8b8e2022015-04-27 05:22:09 +00006365}
6366
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00006367void CGOpenMPRuntime::emitInlinedDirective(CodeGenFunction &CGF,
Alexey Bataev81c7ea02015-07-03 09:56:58 +00006368 OpenMPDirectiveKind InnerKind,
Alexey Bataev25e5b442015-09-15 12:52:43 +00006369 const RegionCodeGenTy &CodeGen,
6370 bool HasCancel) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00006371 if (!CGF.HaveInsertPoint())
6372 return;
Alexey Bataev25e5b442015-09-15 12:52:43 +00006373 InlinedOpenMPRegionRAII Region(CGF, CodeGen, InnerKind, HasCancel);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00006374 CGF.CapturedStmtInfo->EmitBody(CGF, /*S=*/nullptr);
Alexey Bataev8cbe0a62015-02-26 10:27:34 +00006375}
6376
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00006377namespace {
6378enum RTCancelKind {
6379 CancelNoreq = 0,
6380 CancelParallel = 1,
6381 CancelLoop = 2,
6382 CancelSections = 3,
6383 CancelTaskgroup = 4
6384};
Eugene Zelenko0a4f3f42016-02-10 19:11:58 +00006385} // anonymous namespace
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00006386
6387static RTCancelKind getCancellationKind(OpenMPDirectiveKind CancelRegion) {
6388 RTCancelKind CancelKind = CancelNoreq;
Alexey Bataev0f34da12015-07-02 04:17:07 +00006389 if (CancelRegion == OMPD_parallel)
6390 CancelKind = CancelParallel;
6391 else if (CancelRegion == OMPD_for)
6392 CancelKind = CancelLoop;
6393 else if (CancelRegion == OMPD_sections)
6394 CancelKind = CancelSections;
6395 else {
6396 assert(CancelRegion == OMPD_taskgroup);
6397 CancelKind = CancelTaskgroup;
6398 }
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00006399 return CancelKind;
6400}
6401
6402void CGOpenMPRuntime::emitCancellationPointCall(
6403 CodeGenFunction &CGF, SourceLocation Loc,
6404 OpenMPDirectiveKind CancelRegion) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00006405 if (!CGF.HaveInsertPoint())
6406 return;
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00006407 // Build call kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32
6408 // global_tid, kmp_int32 cncl_kind);
Alexey Bataev81c7ea02015-07-03 09:56:58 +00006409 if (auto *OMPRegionInfo =
6410 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
Jonas Hahnfeldb07931f2017-02-17 18:32:58 +00006411 // For 'cancellation point taskgroup', the task region info may not have a
6412 // cancel. This may instead happen in another adjacent task.
6413 if (CancelRegion == OMPD_taskgroup || OMPRegionInfo->hasCancel()) {
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00006414 llvm::Value *Args[] = {
6415 emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
6416 CGF.Builder.getInt32(getCancellationKind(CancelRegion))};
Alexey Bataev81c7ea02015-07-03 09:56:58 +00006417 // Ignore return result until untied tasks are supported.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006418 llvm::Value *Result = CGF.EmitRuntimeCall(
Alexey Bataev81c7ea02015-07-03 09:56:58 +00006419 createRuntimeFunction(OMPRTL__kmpc_cancellationpoint), Args);
6420 // if (__kmpc_cancellationpoint()) {
Alexey Bataev81c7ea02015-07-03 09:56:58 +00006421 // exit from construct;
6422 // }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006423 llvm::BasicBlock *ExitBB = CGF.createBasicBlock(".cancel.exit");
6424 llvm::BasicBlock *ContBB = CGF.createBasicBlock(".cancel.continue");
6425 llvm::Value *Cmp = CGF.Builder.CreateIsNotNull(Result);
Alexey Bataev81c7ea02015-07-03 09:56:58 +00006426 CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
6427 CGF.EmitBlock(ExitBB);
Alexey Bataev81c7ea02015-07-03 09:56:58 +00006428 // exit from construct;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006429 CodeGenFunction::JumpDest CancelDest =
Alexey Bataev25e5b442015-09-15 12:52:43 +00006430 CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
Alexey Bataev81c7ea02015-07-03 09:56:58 +00006431 CGF.EmitBranchThroughCleanup(CancelDest);
6432 CGF.EmitBlock(ContBB, /*IsFinished=*/true);
6433 }
Alexey Bataev0f34da12015-07-02 04:17:07 +00006434 }
Alexey Bataev0f34da12015-07-02 04:17:07 +00006435}
6436
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00006437void CGOpenMPRuntime::emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
Alexey Bataev87933c72015-09-18 08:07:34 +00006438 const Expr *IfCond,
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00006439 OpenMPDirectiveKind CancelRegion) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00006440 if (!CGF.HaveInsertPoint())
6441 return;
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00006442 // Build call kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid,
6443 // kmp_int32 cncl_kind);
6444 if (auto *OMPRegionInfo =
6445 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00006446 auto &&ThenGen = [Loc, CancelRegion, OMPRegionInfo](CodeGenFunction &CGF,
6447 PrePostActionTy &) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006448 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
Alexey Bataev87933c72015-09-18 08:07:34 +00006449 llvm::Value *Args[] = {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00006450 RT.emitUpdateLocation(CGF, Loc), RT.getThreadID(CGF, Loc),
Alexey Bataev87933c72015-09-18 08:07:34 +00006451 CGF.Builder.getInt32(getCancellationKind(CancelRegion))};
6452 // Ignore return result until untied tasks are supported.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006453 llvm::Value *Result = CGF.EmitRuntimeCall(
Alexey Bataev14fa1c62016-03-29 05:34:15 +00006454 RT.createRuntimeFunction(OMPRTL__kmpc_cancel), Args);
Alexey Bataev87933c72015-09-18 08:07:34 +00006455 // if (__kmpc_cancel()) {
Alexey Bataev87933c72015-09-18 08:07:34 +00006456 // exit from construct;
6457 // }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006458 llvm::BasicBlock *ExitBB = CGF.createBasicBlock(".cancel.exit");
6459 llvm::BasicBlock *ContBB = CGF.createBasicBlock(".cancel.continue");
6460 llvm::Value *Cmp = CGF.Builder.CreateIsNotNull(Result);
Alexey Bataev87933c72015-09-18 08:07:34 +00006461 CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
6462 CGF.EmitBlock(ExitBB);
Alexey Bataev87933c72015-09-18 08:07:34 +00006463 // exit from construct;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006464 CodeGenFunction::JumpDest CancelDest =
Alexey Bataev87933c72015-09-18 08:07:34 +00006465 CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
6466 CGF.EmitBranchThroughCleanup(CancelDest);
6467 CGF.EmitBlock(ContBB, /*IsFinished=*/true);
6468 };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006469 if (IfCond) {
Alexey Bataev1d943ae2019-11-19 12:12:23 -05006470 emitIfClause(CGF, IfCond, ThenGen,
6471 [](CodeGenFunction &, PrePostActionTy &) {});
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006472 } else {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00006473 RegionCodeGenTy ThenRCG(ThenGen);
6474 ThenRCG(CGF);
6475 }
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00006476 }
6477}
Samuel Antaobed3c462015-10-02 16:14:20 +00006478
Samuel Antaoee8fb302016-01-06 13:42:12 +00006479void CGOpenMPRuntime::emitTargetOutlinedFunction(
6480 const OMPExecutableDirective &D, StringRef ParentName,
6481 llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
Alexey Bataev14fa1c62016-03-29 05:34:15 +00006482 bool IsOffloadEntry, const RegionCodeGenTy &CodeGen) {
Samuel Antaoee8fb302016-01-06 13:42:12 +00006483 assert(!ParentName.empty() && "Invalid target region parent name!");
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +00006484 HasEmittedTargetRegion = true;
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +00006485 emitTargetOutlinedFunctionHelper(D, ParentName, OutlinedFn, OutlinedFnID,
6486 IsOffloadEntry, CodeGen);
6487}
6488
6489void CGOpenMPRuntime::emitTargetOutlinedFunctionHelper(
6490 const OMPExecutableDirective &D, StringRef ParentName,
6491 llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
6492 bool IsOffloadEntry, const RegionCodeGenTy &CodeGen) {
Samuel Antao2de62b02016-02-13 23:35:10 +00006493 // Create a unique name for the entry function using the source location
6494 // information of the current target region. The name will be something like:
Samuel Antaoee8fb302016-01-06 13:42:12 +00006495 //
Samuel Antao2de62b02016-02-13 23:35:10 +00006496 // __omp_offloading_DD_FFFF_PP_lBB
Samuel Antaoee8fb302016-01-06 13:42:12 +00006497 //
6498 // where DD_FFFF is an ID unique to the file (device and file IDs), PP is the
Samuel Antao2de62b02016-02-13 23:35:10 +00006499 // mangled name of the function that encloses the target region and BB is the
6500 // line number of the target region.
Samuel Antaoee8fb302016-01-06 13:42:12 +00006501
6502 unsigned DeviceID;
6503 unsigned FileID;
6504 unsigned Line;
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006505 getTargetEntryUniqueInfo(CGM.getContext(), D.getBeginLoc(), DeviceID, FileID,
Samuel Antao2de62b02016-02-13 23:35:10 +00006506 Line);
Samuel Antaoee8fb302016-01-06 13:42:12 +00006507 SmallString<64> EntryFnName;
6508 {
6509 llvm::raw_svector_ostream OS(EntryFnName);
Samuel Antao2de62b02016-02-13 23:35:10 +00006510 OS << "__omp_offloading" << llvm::format("_%x", DeviceID)
6511 << llvm::format("_%x_", FileID) << ParentName << "_l" << Line;
Samuel Antaoee8fb302016-01-06 13:42:12 +00006512 }
6513
Alexey Bataev475a7442018-01-12 19:39:11 +00006514 const CapturedStmt &CS = *D.getCapturedStmt(OMPD_target);
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +00006515
Samuel Antaobed3c462015-10-02 16:14:20 +00006516 CodeGenFunction CGF(CGM, true);
Samuel Antaoee8fb302016-01-06 13:42:12 +00006517 CGOpenMPTargetRegionInfo CGInfo(CS, CodeGen, EntryFnName);
Samuel Antaobed3c462015-10-02 16:14:20 +00006518 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
Samuel Antaoee8fb302016-01-06 13:42:12 +00006519
Alexey Bataevc33ba8c2020-01-17 14:05:40 -05006520 OutlinedFn = CGF.GenerateOpenMPCapturedStmtFunction(CS, D.getBeginLoc());
Samuel Antaoee8fb302016-01-06 13:42:12 +00006521
6522 // If this target outline function is not an offload entry, we don't need to
6523 // register it.
6524 if (!IsOffloadEntry)
6525 return;
6526
6527 // The target region ID is used by the runtime library to identify the current
6528 // target region, so it only has to be unique and not necessarily point to
6529 // anything. It could be the pointer to the outlined function that implements
6530 // the target region, but we aren't using that so that the compiler doesn't
6531 // need to keep that, and could therefore inline the host function if proven
6532 // worthwhile during optimization. In the other hand, if emitting code for the
6533 // device, the ID has to be the function address so that it can retrieved from
6534 // the offloading entry and launched by the runtime library. We also mark the
6535 // outlined function to have external linkage in case we are emitting code for
6536 // the device, because these functions will be entry points to the device.
6537
6538 if (CGM.getLangOpts().OpenMPIsDevice) {
6539 OutlinedFnID = llvm::ConstantExpr::getBitCast(OutlinedFn, CGM.Int8PtrTy);
Alexey Bataev9a700172018-05-08 14:16:57 +00006540 OutlinedFn->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
Rafael Espindolacbca4872018-01-11 22:15:12 +00006541 OutlinedFn->setDSOLocal(false);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006542 } else {
Alexey Bataevc15ea702018-05-09 18:02:37 +00006543 std::string Name = getName({EntryFnName, "region_id"});
Samuel Antaoee8fb302016-01-06 13:42:12 +00006544 OutlinedFnID = new llvm::GlobalVariable(
6545 CGM.getModule(), CGM.Int8Ty, /*isConstant=*/true,
Alexey Bataev9a700172018-05-08 14:16:57 +00006546 llvm::GlobalValue::WeakAnyLinkage,
Alexey Bataev18fa2322018-05-02 14:20:50 +00006547 llvm::Constant::getNullValue(CGM.Int8Ty), Name);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006548 }
Samuel Antaoee8fb302016-01-06 13:42:12 +00006549
6550 // Register the information for the entry associated with this target region.
6551 OffloadEntriesInfoManager.registerTargetRegionEntryInfo(
Samuel Antaof83efdb2017-01-05 16:02:49 +00006552 DeviceID, FileID, ParentName, Line, OutlinedFn, OutlinedFnID,
Alexey Bataev03f270c2018-03-30 18:31:07 +00006553 OffloadEntriesInfoManagerTy::OMPTargetRegionEntryTargetRegion);
Samuel Antaobed3c462015-10-02 16:14:20 +00006554}
6555
Alexey Bataev5c427362019-04-10 19:11:33 +00006556/// Checks if the expression is constant or does not have non-trivial function
6557/// calls.
6558static bool isTrivial(ASTContext &Ctx, const Expr * E) {
6559 // We can skip constant expressions.
6560 // We can skip expressions with trivial calls or simple expressions.
6561 return (E->isEvaluatable(Ctx, Expr::SE_AllowUndefinedBehavior) ||
6562 !E->hasNonTrivialCall(Ctx)) &&
6563 !E->HasSideEffects(Ctx, /*IncludePossibleEffects=*/true);
6564}
Carlo Bertolli6eee9062016-04-29 01:37:30 +00006565
Alexey Bataev5c427362019-04-10 19:11:33 +00006566const Stmt *CGOpenMPRuntime::getSingleCompoundChild(ASTContext &Ctx,
6567 const Stmt *Body) {
6568 const Stmt *Child = Body->IgnoreContainers();
6569 while (const auto *C = dyn_cast_or_null<CompoundStmt>(Child)) {
6570 Child = nullptr;
6571 for (const Stmt *S : C->body()) {
6572 if (const auto *E = dyn_cast<Expr>(S)) {
6573 if (isTrivial(Ctx, E))
6574 continue;
6575 }
6576 // Some of the statements can be ignored.
6577 if (isa<AsmStmt>(S) || isa<NullStmt>(S) || isa<OMPFlushDirective>(S) ||
6578 isa<OMPBarrierDirective>(S) || isa<OMPTaskyieldDirective>(S))
6579 continue;
6580 // Analyze declarations.
6581 if (const auto *DS = dyn_cast<DeclStmt>(S)) {
6582 if (llvm::all_of(DS->decls(), [&Ctx](const Decl *D) {
6583 if (isa<EmptyDecl>(D) || isa<DeclContext>(D) ||
6584 isa<TypeDecl>(D) || isa<PragmaCommentDecl>(D) ||
6585 isa<PragmaDetectMismatchDecl>(D) || isa<UsingDecl>(D) ||
6586 isa<UsingDirectiveDecl>(D) ||
6587 isa<OMPDeclareReductionDecl>(D) ||
6588 isa<OMPThreadPrivateDecl>(D) || isa<OMPAllocateDecl>(D))
6589 return true;
6590 const auto *VD = dyn_cast<VarDecl>(D);
6591 if (!VD)
6592 return false;
6593 return VD->isConstexpr() ||
6594 ((VD->getType().isTrivialType(Ctx) ||
6595 VD->getType()->isReferenceType()) &&
6596 (!VD->hasInit() || isTrivial(Ctx, VD->getInit())));
6597 }))
6598 continue;
6599 }
6600 // Found multiple children - cannot get the one child only.
6601 if (Child)
6602 return nullptr;
6603 Child = S;
6604 }
6605 if (Child)
6606 Child = Child->IgnoreContainers();
6607 }
6608 return Child;
Carlo Bertolli6eee9062016-04-29 01:37:30 +00006609}
6610
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00006611/// Emit the number of teams for a target directive. Inspect the num_teams
6612/// clause associated with a teams construct combined or closely nested
6613/// with the target directive.
6614///
6615/// Emit a team of size one for directives such as 'target parallel' that
6616/// have no associated teams construct.
6617///
6618/// Otherwise, return nullptr.
Samuel Antaob68e2db2016-03-03 16:20:23 +00006619static llvm::Value *
Alexey Bataev5c427362019-04-10 19:11:33 +00006620emitNumTeamsForTargetDirective(CodeGenFunction &CGF,
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00006621 const OMPExecutableDirective &D) {
Alexey Bataev5c427362019-04-10 19:11:33 +00006622 assert(!CGF.getLangOpts().OpenMPIsDevice &&
6623 "Clauses associated with the teams directive expected to be emitted "
6624 "only for the host!");
6625 OpenMPDirectiveKind DirectiveKind = D.getDirectiveKind();
6626 assert(isOpenMPTargetExecutionDirective(DirectiveKind) &&
6627 "Expected target-based executable directive.");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006628 CGBuilderTy &Bld = CGF.Builder;
Alexey Bataev5c427362019-04-10 19:11:33 +00006629 switch (DirectiveKind) {
6630 case OMPD_target: {
6631 const auto *CS = D.getInnermostCapturedStmt();
6632 const auto *Body =
6633 CS->getCapturedStmt()->IgnoreContainers(/*IgnoreCaptured=*/true);
6634 const Stmt *ChildStmt =
6635 CGOpenMPRuntime::getSingleCompoundChild(CGF.getContext(), Body);
6636 if (const auto *NestedDir =
6637 dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
6638 if (isOpenMPTeamsDirective(NestedDir->getDirectiveKind())) {
6639 if (NestedDir->hasClausesOfKind<OMPNumTeamsClause>()) {
6640 CGOpenMPInnerExprInfo CGInfo(CGF, *CS);
6641 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
6642 const Expr *NumTeams =
6643 NestedDir->getSingleClause<OMPNumTeamsClause>()->getNumTeams();
6644 llvm::Value *NumTeamsVal =
6645 CGF.EmitScalarExpr(NumTeams,
6646 /*IgnoreResultAssign*/ true);
6647 return Bld.CreateIntCast(NumTeamsVal, CGF.Int32Ty,
Rui Ueyama49a3ad22019-07-16 04:46:31 +00006648 /*isSigned=*/true);
Alexey Bataev5c427362019-04-10 19:11:33 +00006649 }
6650 return Bld.getInt32(0);
Alexey Bataev50a1c782017-12-01 21:31:08 +00006651 }
Alexey Bataev5c427362019-04-10 19:11:33 +00006652 if (isOpenMPParallelDirective(NestedDir->getDirectiveKind()) ||
6653 isOpenMPSimdDirective(NestedDir->getDirectiveKind()))
6654 return Bld.getInt32(1);
Alexey Bataev50a1c782017-12-01 21:31:08 +00006655 return Bld.getInt32(0);
6656 }
Alexey Bataev5c427362019-04-10 19:11:33 +00006657 return nullptr;
Samuel Antaob68e2db2016-03-03 16:20:23 +00006658 }
Alexey Bataev5c427362019-04-10 19:11:33 +00006659 case OMPD_target_teams:
6660 case OMPD_target_teams_distribute:
6661 case OMPD_target_teams_distribute_simd:
6662 case OMPD_target_teams_distribute_parallel_for:
6663 case OMPD_target_teams_distribute_parallel_for_simd: {
6664 if (D.hasClausesOfKind<OMPNumTeamsClause>()) {
6665 CodeGenFunction::RunCleanupsScope NumTeamsScope(CGF);
6666 const Expr *NumTeams =
6667 D.getSingleClause<OMPNumTeamsClause>()->getNumTeams();
6668 llvm::Value *NumTeamsVal =
6669 CGF.EmitScalarExpr(NumTeams,
6670 /*IgnoreResultAssign*/ true);
6671 return Bld.CreateIntCast(NumTeamsVal, CGF.Int32Ty,
Rui Ueyama49a3ad22019-07-16 04:46:31 +00006672 /*isSigned=*/true);
Alexey Bataev5c427362019-04-10 19:11:33 +00006673 }
6674 return Bld.getInt32(0);
6675 }
6676 case OMPD_target_parallel:
6677 case OMPD_target_parallel_for:
6678 case OMPD_target_parallel_for_simd:
6679 case OMPD_target_simd:
6680 return Bld.getInt32(1);
6681 case OMPD_parallel:
6682 case OMPD_for:
6683 case OMPD_parallel_for:
cchen47d60942019-12-05 13:43:48 -05006684 case OMPD_parallel_master:
Alexey Bataev5c427362019-04-10 19:11:33 +00006685 case OMPD_parallel_sections:
6686 case OMPD_for_simd:
6687 case OMPD_parallel_for_simd:
6688 case OMPD_cancel:
6689 case OMPD_cancellation_point:
6690 case OMPD_ordered:
6691 case OMPD_threadprivate:
6692 case OMPD_allocate:
6693 case OMPD_task:
6694 case OMPD_simd:
6695 case OMPD_sections:
6696 case OMPD_section:
6697 case OMPD_single:
6698 case OMPD_master:
6699 case OMPD_critical:
6700 case OMPD_taskyield:
6701 case OMPD_barrier:
6702 case OMPD_taskwait:
6703 case OMPD_taskgroup:
6704 case OMPD_atomic:
6705 case OMPD_flush:
6706 case OMPD_teams:
6707 case OMPD_target_data:
6708 case OMPD_target_exit_data:
6709 case OMPD_target_enter_data:
6710 case OMPD_distribute:
6711 case OMPD_distribute_simd:
6712 case OMPD_distribute_parallel_for:
6713 case OMPD_distribute_parallel_for_simd:
6714 case OMPD_teams_distribute:
6715 case OMPD_teams_distribute_simd:
6716 case OMPD_teams_distribute_parallel_for:
6717 case OMPD_teams_distribute_parallel_for_simd:
6718 case OMPD_target_update:
6719 case OMPD_declare_simd:
Alexey Bataevd158cf62019-09-13 20:18:17 +00006720 case OMPD_declare_variant:
Alexey Bataev5c427362019-04-10 19:11:33 +00006721 case OMPD_declare_target:
6722 case OMPD_end_declare_target:
6723 case OMPD_declare_reduction:
6724 case OMPD_declare_mapper:
6725 case OMPD_taskloop:
6726 case OMPD_taskloop_simd:
Alexey Bataev60e51c42019-10-10 20:13:02 +00006727 case OMPD_master_taskloop:
Alexey Bataevb8552ab2019-10-18 16:47:35 +00006728 case OMPD_master_taskloop_simd:
Alexey Bataev5bbcead2019-10-14 17:17:41 +00006729 case OMPD_parallel_master_taskloop:
Alexey Bataev14a388f2019-10-25 10:27:13 -04006730 case OMPD_parallel_master_taskloop_simd:
Alexey Bataev5c427362019-04-10 19:11:33 +00006731 case OMPD_requires:
6732 case OMPD_unknown:
6733 break;
6734 }
6735 llvm_unreachable("Unexpected directive kind.");
6736}
Samuel Antaob68e2db2016-03-03 16:20:23 +00006737
Alexey Bataev5c427362019-04-10 19:11:33 +00006738static llvm::Value *getNumThreads(CodeGenFunction &CGF, const CapturedStmt *CS,
6739 llvm::Value *DefaultThreadLimitVal) {
6740 const Stmt *Child = CGOpenMPRuntime::getSingleCompoundChild(
6741 CGF.getContext(), CS->getCapturedStmt());
6742 if (const auto *Dir = dyn_cast_or_null<OMPExecutableDirective>(Child)) {
6743 if (isOpenMPParallelDirective(Dir->getDirectiveKind())) {
Alexey Bataevdc9e7dc2019-04-17 16:53:08 +00006744 llvm::Value *NumThreads = nullptr;
6745 llvm::Value *CondVal = nullptr;
6746 // Handle if clause. If if clause present, the number of threads is
6747 // calculated as <cond> ? (<numthreads> ? <numthreads> : 0 ) : 1.
6748 if (Dir->hasClausesOfKind<OMPIfClause>()) {
6749 CGOpenMPInnerExprInfo CGInfo(CGF, *CS);
6750 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
6751 const OMPIfClause *IfClause = nullptr;
6752 for (const auto *C : Dir->getClausesOfKind<OMPIfClause>()) {
6753 if (C->getNameModifier() == OMPD_unknown ||
6754 C->getNameModifier() == OMPD_parallel) {
6755 IfClause = C;
6756 break;
6757 }
6758 }
6759 if (IfClause) {
6760 const Expr *Cond = IfClause->getCondition();
6761 bool Result;
6762 if (Cond->EvaluateAsBooleanCondition(Result, CGF.getContext())) {
6763 if (!Result)
6764 return CGF.Builder.getInt32(1);
6765 } else {
6766 CodeGenFunction::LexicalScope Scope(CGF, Cond->getSourceRange());
6767 if (const auto *PreInit =
6768 cast_or_null<DeclStmt>(IfClause->getPreInitStmt())) {
6769 for (const auto *I : PreInit->decls()) {
6770 if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
6771 CGF.EmitVarDecl(cast<VarDecl>(*I));
6772 } else {
6773 CodeGenFunction::AutoVarEmission Emission =
6774 CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
6775 CGF.EmitAutoVarCleanups(Emission);
6776 }
6777 }
6778 }
6779 CondVal = CGF.EvaluateExprAsBool(Cond);
6780 }
6781 }
6782 }
6783 // Check the value of num_threads clause iff if clause was not specified
6784 // or is not evaluated to false.
Alexey Bataev5c427362019-04-10 19:11:33 +00006785 if (Dir->hasClausesOfKind<OMPNumThreadsClause>()) {
6786 CGOpenMPInnerExprInfo CGInfo(CGF, *CS);
6787 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
6788 const auto *NumThreadsClause =
6789 Dir->getSingleClause<OMPNumThreadsClause>();
6790 CodeGenFunction::LexicalScope Scope(
6791 CGF, NumThreadsClause->getNumThreads()->getSourceRange());
6792 if (const auto *PreInit =
6793 cast_or_null<DeclStmt>(NumThreadsClause->getPreInitStmt())) {
6794 for (const auto *I : PreInit->decls()) {
6795 if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
6796 CGF.EmitVarDecl(cast<VarDecl>(*I));
6797 } else {
6798 CodeGenFunction::AutoVarEmission Emission =
6799 CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
6800 CGF.EmitAutoVarCleanups(Emission);
6801 }
6802 }
6803 }
Alexey Bataevdc9e7dc2019-04-17 16:53:08 +00006804 NumThreads = CGF.EmitScalarExpr(NumThreadsClause->getNumThreads());
Alexey Bataev5c427362019-04-10 19:11:33 +00006805 NumThreads = CGF.Builder.CreateIntCast(NumThreads, CGF.Int32Ty,
Rui Ueyama49a3ad22019-07-16 04:46:31 +00006806 /*isSigned=*/false);
Alexey Bataevdc9e7dc2019-04-17 16:53:08 +00006807 if (DefaultThreadLimitVal)
6808 NumThreads = CGF.Builder.CreateSelect(
6809 CGF.Builder.CreateICmpULT(DefaultThreadLimitVal, NumThreads),
6810 DefaultThreadLimitVal, NumThreads);
6811 } else {
6812 NumThreads = DefaultThreadLimitVal ? DefaultThreadLimitVal
6813 : CGF.Builder.getInt32(0);
Alexey Bataev5c427362019-04-10 19:11:33 +00006814 }
Alexey Bataevdc9e7dc2019-04-17 16:53:08 +00006815 // Process condition of the if clause.
6816 if (CondVal) {
6817 NumThreads = CGF.Builder.CreateSelect(CondVal, NumThreads,
6818 CGF.Builder.getInt32(1));
6819 }
6820 return NumThreads;
Alexey Bataev5c427362019-04-10 19:11:33 +00006821 }
6822 if (isOpenMPSimdDirective(Dir->getDirectiveKind()))
6823 return CGF.Builder.getInt32(1);
6824 return DefaultThreadLimitVal;
6825 }
6826 return DefaultThreadLimitVal ? DefaultThreadLimitVal
6827 : CGF.Builder.getInt32(0);
Samuel Antaob68e2db2016-03-03 16:20:23 +00006828}
6829
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00006830/// Emit the number of threads for a target directive. Inspect the
6831/// thread_limit clause associated with a teams construct combined or closely
6832/// nested with the target directive.
6833///
6834/// Emit the num_threads clause for directives such as 'target parallel' that
6835/// have no associated teams construct.
6836///
6837/// Otherwise, return nullptr.
Samuel Antaob68e2db2016-03-03 16:20:23 +00006838static llvm::Value *
Alexey Bataev5c427362019-04-10 19:11:33 +00006839emitNumThreadsForTargetDirective(CodeGenFunction &CGF,
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00006840 const OMPExecutableDirective &D) {
Alexey Bataev5c427362019-04-10 19:11:33 +00006841 assert(!CGF.getLangOpts().OpenMPIsDevice &&
6842 "Clauses associated with the teams directive expected to be emitted "
6843 "only for the host!");
6844 OpenMPDirectiveKind DirectiveKind = D.getDirectiveKind();
6845 assert(isOpenMPTargetExecutionDirective(DirectiveKind) &&
6846 "Expected target-based executable directive.");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006847 CGBuilderTy &Bld = CGF.Builder;
Alexey Bataev5c427362019-04-10 19:11:33 +00006848 llvm::Value *ThreadLimitVal = nullptr;
6849 llvm::Value *NumThreadsVal = nullptr;
6850 switch (DirectiveKind) {
6851 case OMPD_target: {
6852 const CapturedStmt *CS = D.getInnermostCapturedStmt();
6853 if (llvm::Value *NumThreads = getNumThreads(CGF, CS, ThreadLimitVal))
6854 return NumThreads;
6855 const Stmt *Child = CGOpenMPRuntime::getSingleCompoundChild(
6856 CGF.getContext(), CS->getCapturedStmt());
6857 if (const auto *Dir = dyn_cast_or_null<OMPExecutableDirective>(Child)) {
6858 if (Dir->hasClausesOfKind<OMPThreadLimitClause>()) {
6859 CGOpenMPInnerExprInfo CGInfo(CGF, *CS);
6860 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
6861 const auto *ThreadLimitClause =
6862 Dir->getSingleClause<OMPThreadLimitClause>();
6863 CodeGenFunction::LexicalScope Scope(
6864 CGF, ThreadLimitClause->getThreadLimit()->getSourceRange());
6865 if (const auto *PreInit =
6866 cast_or_null<DeclStmt>(ThreadLimitClause->getPreInitStmt())) {
6867 for (const auto *I : PreInit->decls()) {
6868 if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
6869 CGF.EmitVarDecl(cast<VarDecl>(*I));
6870 } else {
6871 CodeGenFunction::AutoVarEmission Emission =
6872 CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
6873 CGF.EmitAutoVarCleanups(Emission);
6874 }
6875 }
6876 }
6877 llvm::Value *ThreadLimit = CGF.EmitScalarExpr(
6878 ThreadLimitClause->getThreadLimit(), /*IgnoreResultAssign=*/true);
6879 ThreadLimitVal =
Rui Ueyama49a3ad22019-07-16 04:46:31 +00006880 Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty, /*isSigned=*/false);
Alexey Bataev5c427362019-04-10 19:11:33 +00006881 }
6882 if (isOpenMPTeamsDirective(Dir->getDirectiveKind()) &&
6883 !isOpenMPDistributeDirective(Dir->getDirectiveKind())) {
6884 CS = Dir->getInnermostCapturedStmt();
6885 const Stmt *Child = CGOpenMPRuntime::getSingleCompoundChild(
6886 CGF.getContext(), CS->getCapturedStmt());
6887 Dir = dyn_cast_or_null<OMPExecutableDirective>(Child);
6888 }
6889 if (Dir && isOpenMPDistributeDirective(Dir->getDirectiveKind()) &&
6890 !isOpenMPSimdDirective(Dir->getDirectiveKind())) {
6891 CS = Dir->getInnermostCapturedStmt();
6892 if (llvm::Value *NumThreads = getNumThreads(CGF, CS, ThreadLimitVal))
6893 return NumThreads;
6894 }
6895 if (Dir && isOpenMPSimdDirective(Dir->getDirectiveKind()))
6896 return Bld.getInt32(1);
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00006897 }
Alexey Bataev5c427362019-04-10 19:11:33 +00006898 return ThreadLimitVal ? ThreadLimitVal : Bld.getInt32(0);
6899 }
6900 case OMPD_target_teams: {
6901 if (D.hasClausesOfKind<OMPThreadLimitClause>()) {
6902 CodeGenFunction::RunCleanupsScope ThreadLimitScope(CGF);
6903 const auto *ThreadLimitClause = D.getSingleClause<OMPThreadLimitClause>();
6904 llvm::Value *ThreadLimit = CGF.EmitScalarExpr(
6905 ThreadLimitClause->getThreadLimit(), /*IgnoreResultAssign=*/true);
6906 ThreadLimitVal =
Rui Ueyama49a3ad22019-07-16 04:46:31 +00006907 Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty, /*isSigned=*/false);
Alexey Bataev5c427362019-04-10 19:11:33 +00006908 }
6909 const CapturedStmt *CS = D.getInnermostCapturedStmt();
6910 if (llvm::Value *NumThreads = getNumThreads(CGF, CS, ThreadLimitVal))
6911 return NumThreads;
6912 const Stmt *Child = CGOpenMPRuntime::getSingleCompoundChild(
6913 CGF.getContext(), CS->getCapturedStmt());
6914 if (const auto *Dir = dyn_cast_or_null<OMPExecutableDirective>(Child)) {
6915 if (Dir->getDirectiveKind() == OMPD_distribute) {
6916 CS = Dir->getInnermostCapturedStmt();
6917 if (llvm::Value *NumThreads = getNumThreads(CGF, CS, ThreadLimitVal))
6918 return NumThreads;
6919 }
6920 }
6921 return ThreadLimitVal ? ThreadLimitVal : Bld.getInt32(0);
6922 }
6923 case OMPD_target_teams_distribute:
6924 if (D.hasClausesOfKind<OMPThreadLimitClause>()) {
6925 CodeGenFunction::RunCleanupsScope ThreadLimitScope(CGF);
6926 const auto *ThreadLimitClause = D.getSingleClause<OMPThreadLimitClause>();
6927 llvm::Value *ThreadLimit = CGF.EmitScalarExpr(
6928 ThreadLimitClause->getThreadLimit(), /*IgnoreResultAssign=*/true);
6929 ThreadLimitVal =
Rui Ueyama49a3ad22019-07-16 04:46:31 +00006930 Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty, /*isSigned=*/false);
Alexey Bataev5c427362019-04-10 19:11:33 +00006931 }
6932 return getNumThreads(CGF, D.getInnermostCapturedStmt(), ThreadLimitVal);
6933 case OMPD_target_parallel:
6934 case OMPD_target_parallel_for:
6935 case OMPD_target_parallel_for_simd:
6936 case OMPD_target_teams_distribute_parallel_for:
Alexey Bataevdc9e7dc2019-04-17 16:53:08 +00006937 case OMPD_target_teams_distribute_parallel_for_simd: {
6938 llvm::Value *CondVal = nullptr;
6939 // Handle if clause. If if clause present, the number of threads is
6940 // calculated as <cond> ? (<numthreads> ? <numthreads> : 0 ) : 1.
6941 if (D.hasClausesOfKind<OMPIfClause>()) {
6942 const OMPIfClause *IfClause = nullptr;
6943 for (const auto *C : D.getClausesOfKind<OMPIfClause>()) {
6944 if (C->getNameModifier() == OMPD_unknown ||
6945 C->getNameModifier() == OMPD_parallel) {
6946 IfClause = C;
6947 break;
6948 }
6949 }
6950 if (IfClause) {
6951 const Expr *Cond = IfClause->getCondition();
6952 bool Result;
6953 if (Cond->EvaluateAsBooleanCondition(Result, CGF.getContext())) {
6954 if (!Result)
6955 return Bld.getInt32(1);
6956 } else {
6957 CodeGenFunction::RunCleanupsScope Scope(CGF);
6958 CondVal = CGF.EvaluateExprAsBool(Cond);
6959 }
6960 }
6961 }
Alexey Bataev5c427362019-04-10 19:11:33 +00006962 if (D.hasClausesOfKind<OMPThreadLimitClause>()) {
6963 CodeGenFunction::RunCleanupsScope ThreadLimitScope(CGF);
6964 const auto *ThreadLimitClause = D.getSingleClause<OMPThreadLimitClause>();
6965 llvm::Value *ThreadLimit = CGF.EmitScalarExpr(
6966 ThreadLimitClause->getThreadLimit(), /*IgnoreResultAssign=*/true);
6967 ThreadLimitVal =
Rui Ueyama49a3ad22019-07-16 04:46:31 +00006968 Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty, /*isSigned=*/false);
Alexey Bataev5c427362019-04-10 19:11:33 +00006969 }
6970 if (D.hasClausesOfKind<OMPNumThreadsClause>()) {
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00006971 CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
Alexey Bataev5c427362019-04-10 19:11:33 +00006972 const auto *NumThreadsClause = D.getSingleClause<OMPNumThreadsClause>();
6973 llvm::Value *NumThreads = CGF.EmitScalarExpr(
6974 NumThreadsClause->getNumThreads(), /*IgnoreResultAssign=*/true);
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00006975 NumThreadsVal =
Rui Ueyama49a3ad22019-07-16 04:46:31 +00006976 Bld.CreateIntCast(NumThreads, CGF.Int32Ty, /*isSigned=*/false);
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00006977 ThreadLimitVal = ThreadLimitVal
Alexey Bataev5c427362019-04-10 19:11:33 +00006978 ? Bld.CreateSelect(Bld.CreateICmpULT(NumThreadsVal,
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00006979 ThreadLimitVal),
6980 NumThreadsVal, ThreadLimitVal)
6981 : NumThreadsVal;
Alexey Bataev50a1c782017-12-01 21:31:08 +00006982 }
Alexey Bataevdc9e7dc2019-04-17 16:53:08 +00006983 if (!ThreadLimitVal)
6984 ThreadLimitVal = Bld.getInt32(0);
6985 if (CondVal)
6986 return Bld.CreateSelect(CondVal, ThreadLimitVal, Bld.getInt32(1));
6987 return ThreadLimitVal;
6988 }
Alexey Bataev5c427362019-04-10 19:11:33 +00006989 case OMPD_target_teams_distribute_simd:
6990 case OMPD_target_simd:
6991 return Bld.getInt32(1);
6992 case OMPD_parallel:
6993 case OMPD_for:
6994 case OMPD_parallel_for:
cchen47d60942019-12-05 13:43:48 -05006995 case OMPD_parallel_master:
Alexey Bataev5c427362019-04-10 19:11:33 +00006996 case OMPD_parallel_sections:
6997 case OMPD_for_simd:
6998 case OMPD_parallel_for_simd:
6999 case OMPD_cancel:
7000 case OMPD_cancellation_point:
7001 case OMPD_ordered:
7002 case OMPD_threadprivate:
7003 case OMPD_allocate:
7004 case OMPD_task:
7005 case OMPD_simd:
7006 case OMPD_sections:
7007 case OMPD_section:
7008 case OMPD_single:
7009 case OMPD_master:
7010 case OMPD_critical:
7011 case OMPD_taskyield:
7012 case OMPD_barrier:
7013 case OMPD_taskwait:
7014 case OMPD_taskgroup:
7015 case OMPD_atomic:
7016 case OMPD_flush:
7017 case OMPD_teams:
7018 case OMPD_target_data:
7019 case OMPD_target_exit_data:
7020 case OMPD_target_enter_data:
7021 case OMPD_distribute:
7022 case OMPD_distribute_simd:
7023 case OMPD_distribute_parallel_for:
7024 case OMPD_distribute_parallel_for_simd:
7025 case OMPD_teams_distribute:
7026 case OMPD_teams_distribute_simd:
7027 case OMPD_teams_distribute_parallel_for:
7028 case OMPD_teams_distribute_parallel_for_simd:
7029 case OMPD_target_update:
7030 case OMPD_declare_simd:
Alexey Bataevd158cf62019-09-13 20:18:17 +00007031 case OMPD_declare_variant:
Alexey Bataev5c427362019-04-10 19:11:33 +00007032 case OMPD_declare_target:
7033 case OMPD_end_declare_target:
7034 case OMPD_declare_reduction:
7035 case OMPD_declare_mapper:
7036 case OMPD_taskloop:
7037 case OMPD_taskloop_simd:
Alexey Bataev60e51c42019-10-10 20:13:02 +00007038 case OMPD_master_taskloop:
Alexey Bataevb8552ab2019-10-18 16:47:35 +00007039 case OMPD_master_taskloop_simd:
Alexey Bataev5bbcead2019-10-14 17:17:41 +00007040 case OMPD_parallel_master_taskloop:
Alexey Bataev14a388f2019-10-25 10:27:13 -04007041 case OMPD_parallel_master_taskloop_simd:
Alexey Bataev5c427362019-04-10 19:11:33 +00007042 case OMPD_requires:
7043 case OMPD_unknown:
7044 break;
Samuel Antaob68e2db2016-03-03 16:20:23 +00007045 }
Alexey Bataev5c427362019-04-10 19:11:33 +00007046 llvm_unreachable("Unsupported directive kind.");
Samuel Antaob68e2db2016-03-03 16:20:23 +00007047}
7048
Samuel Antao86ace552016-04-27 22:40:57 +00007049namespace {
Alexey Bataevb3638132018-07-19 16:34:13 +00007050LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
7051
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007052// Utility to handle information from clauses associated with a given
Samuel Antao86ace552016-04-27 22:40:57 +00007053// construct that use mappable expressions (e.g. 'map' clause, 'to' clause).
7054// It provides a convenient interface to obtain the information and generate
7055// code for that information.
7056class MappableExprsHandler {
7057public:
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007058 /// Values for bit flags used to specify the mapping type for
Samuel Antao86ace552016-04-27 22:40:57 +00007059 /// offloading.
Alexey Bataevb3638132018-07-19 16:34:13 +00007060 enum OpenMPOffloadMappingFlags : uint64_t {
7061 /// No flags
7062 OMP_MAP_NONE = 0x0,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007063 /// Allocate memory on the device and move data from host to device.
Samuel Antao86ace552016-04-27 22:40:57 +00007064 OMP_MAP_TO = 0x01,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007065 /// Allocate memory on the device and move data from device to host.
Samuel Antao86ace552016-04-27 22:40:57 +00007066 OMP_MAP_FROM = 0x02,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007067 /// Always perform the requested mapping action on the element, even
Samuel Antao86ace552016-04-27 22:40:57 +00007068 /// if it was already mapped before.
7069 OMP_MAP_ALWAYS = 0x04,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007070 /// Delete the element from the device environment, ignoring the
Samuel Antao86ace552016-04-27 22:40:57 +00007071 /// current reference count associated with the element.
Samuel Antao6782e942016-05-26 16:48:10 +00007072 OMP_MAP_DELETE = 0x08,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007073 /// The element being mapped is a pointer-pointee pair; both the
George Rokos065755d2017-11-07 18:27:04 +00007074 /// pointer and the pointee should be mapped.
7075 OMP_MAP_PTR_AND_OBJ = 0x10,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007076 /// This flags signals that the base address of an entry should be
George Rokos065755d2017-11-07 18:27:04 +00007077 /// passed to the target kernel as an argument.
7078 OMP_MAP_TARGET_PARAM = 0x20,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007079 /// Signal that the runtime library has to return the device pointer
George Rokos065755d2017-11-07 18:27:04 +00007080 /// in the current position for the data being mapped. Used when we have the
7081 /// use_device_ptr clause.
7082 OMP_MAP_RETURN_PARAM = 0x40,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007083 /// This flag signals that the reference being passed is a pointer to
Samuel Antaod486f842016-05-26 16:53:38 +00007084 /// private data.
George Rokos065755d2017-11-07 18:27:04 +00007085 OMP_MAP_PRIVATE = 0x80,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007086 /// Pass the element to the device by value.
George Rokos065755d2017-11-07 18:27:04 +00007087 OMP_MAP_LITERAL = 0x100,
Alexey Bataevf47c4b42017-09-26 13:47:31 +00007088 /// Implicit map
7089 OMP_MAP_IMPLICIT = 0x200,
Gheorghe-Teodor Bercea0fd073b2019-08-09 21:42:13 +00007090 /// Close is a hint to the runtime to allocate memory close to
7091 /// the target device.
7092 OMP_MAP_CLOSE = 0x400,
Alexey Bataevb3638132018-07-19 16:34:13 +00007093 /// The 16 MSBs of the flags indicate whether the entry is member of some
7094 /// struct/class.
7095 OMP_MAP_MEMBER_OF = 0xffff000000000000,
7096 LLVM_MARK_AS_BITMASK_ENUM(/* LargestFlag = */ OMP_MAP_MEMBER_OF),
Samuel Antao86ace552016-04-27 22:40:57 +00007097 };
7098
Michael Krused47b9432019-08-05 18:43:21 +00007099 /// Get the offset of the OMP_MAP_MEMBER_OF field.
7100 static unsigned getFlagMemberOffset() {
7101 unsigned Offset = 0;
7102 for (uint64_t Remain = OMP_MAP_MEMBER_OF; !(Remain & 1);
7103 Remain = Remain >> 1)
7104 Offset++;
7105 return Offset;
7106 }
7107
Samuel Antaocc10b852016-07-28 14:23:26 +00007108 /// Class that associates information with a base pointer to be passed to the
7109 /// runtime library.
7110 class BasePointerInfo {
7111 /// The base pointer.
7112 llvm::Value *Ptr = nullptr;
7113 /// The base declaration that refers to this device pointer, or null if
7114 /// there is none.
7115 const ValueDecl *DevPtrDecl = nullptr;
7116
7117 public:
7118 BasePointerInfo(llvm::Value *Ptr, const ValueDecl *DevPtrDecl = nullptr)
7119 : Ptr(Ptr), DevPtrDecl(DevPtrDecl) {}
7120 llvm::Value *operator*() const { return Ptr; }
7121 const ValueDecl *getDevicePtrDecl() const { return DevPtrDecl; }
7122 void setDevicePtrDecl(const ValueDecl *D) { DevPtrDecl = D; }
7123 };
7124
Alexey Bataevb3638132018-07-19 16:34:13 +00007125 using MapBaseValuesArrayTy = SmallVector<BasePointerInfo, 4>;
7126 using MapValuesArrayTy = SmallVector<llvm::Value *, 4>;
7127 using MapFlagsArrayTy = SmallVector<OpenMPOffloadMappingFlags, 4>;
7128
7129 /// Map between a struct and the its lowest & highest elements which have been
7130 /// mapped.
7131 /// [ValueDecl *] --> {LE(FieldIndex, Pointer),
7132 /// HE(FieldIndex, Pointer)}
7133 struct StructRangeInfoTy {
7134 std::pair<unsigned /*FieldIndex*/, Address /*Pointer*/> LowestElem = {
7135 0, Address::invalid()};
7136 std::pair<unsigned /*FieldIndex*/, Address /*Pointer*/> HighestElem = {
7137 0, Address::invalid()};
7138 Address Base = Address::invalid();
7139 };
Samuel Antao86ace552016-04-27 22:40:57 +00007140
7141private:
Alexey Bataevb3638132018-07-19 16:34:13 +00007142 /// Kind that defines how a device pointer has to be returned.
7143 struct MapInfo {
7144 OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
7145 OpenMPMapClauseKind MapType = OMPC_MAP_unknown;
Kelvin Lief579432018-12-18 22:18:41 +00007146 ArrayRef<OpenMPMapModifierKind> MapModifiers;
Alexey Bataevb3638132018-07-19 16:34:13 +00007147 bool ReturnDevicePointer = false;
7148 bool IsImplicit = false;
7149
7150 MapInfo() = default;
7151 MapInfo(
7152 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
Kelvin Lief579432018-12-18 22:18:41 +00007153 OpenMPMapClauseKind MapType,
7154 ArrayRef<OpenMPMapModifierKind> MapModifiers,
Alexey Bataevb3638132018-07-19 16:34:13 +00007155 bool ReturnDevicePointer, bool IsImplicit)
Kelvin Lief579432018-12-18 22:18:41 +00007156 : Components(Components), MapType(MapType), MapModifiers(MapModifiers),
Alexey Bataevb3638132018-07-19 16:34:13 +00007157 ReturnDevicePointer(ReturnDevicePointer), IsImplicit(IsImplicit) {}
7158 };
7159
7160 /// If use_device_ptr is used on a pointer which is a struct member and there
7161 /// is no map information about it, then emission of that entry is deferred
7162 /// until the whole struct has been processed.
7163 struct DeferredDevicePtrEntryTy {
7164 const Expr *IE = nullptr;
7165 const ValueDecl *VD = nullptr;
7166
7167 DeferredDevicePtrEntryTy(const Expr *IE, const ValueDecl *VD)
7168 : IE(IE), VD(VD) {}
7169 };
7170
Michael Krused47b9432019-08-05 18:43:21 +00007171 /// The target directive from where the mappable clauses were extracted. It
7172 /// is either a executable directive or a user-defined mapper directive.
7173 llvm::PointerUnion<const OMPExecutableDirective *,
7174 const OMPDeclareMapperDecl *>
7175 CurDir;
Samuel Antao86ace552016-04-27 22:40:57 +00007176
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007177 /// Function the directive is being generated for.
Samuel Antao86ace552016-04-27 22:40:57 +00007178 CodeGenFunction &CGF;
7179
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007180 /// Set of all first private variables in the current directive.
Alexey Bataevf288cf92019-06-27 18:53:07 +00007181 /// bool data is set to true if the variable is implicitly marked as
7182 /// firstprivate, false otherwise.
7183 llvm::DenseMap<CanonicalDeclPtr<const VarDecl>, bool> FirstPrivateDecls;
Samuel Antaod486f842016-05-26 16:53:38 +00007184
Samuel Antao6890b092016-07-28 14:25:09 +00007185 /// Map between device pointer declarations and their expression components.
7186 /// The key value for declarations in 'this' is null.
7187 llvm::DenseMap<
7188 const ValueDecl *,
7189 SmallVector<OMPClauseMappableExprCommon::MappableExprComponentListRef, 4>>
7190 DevPointersMap;
7191
Samuel Antao86ace552016-04-27 22:40:57 +00007192 llvm::Value *getExprTypeSize(const Expr *E) const {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007193 QualType ExprTy = E->getType().getCanonicalType();
Samuel Antao86ace552016-04-27 22:40:57 +00007194
7195 // Reference types are ignored for mapping purposes.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007196 if (const auto *RefTy = ExprTy->getAs<ReferenceType>())
Samuel Antao86ace552016-04-27 22:40:57 +00007197 ExprTy = RefTy->getPointeeType().getCanonicalType();
7198
7199 // Given that an array section is considered a built-in type, we need to
7200 // do the calculation based on the length of the section instead of relying
7201 // on CGF.getTypeSize(E->getType()).
7202 if (const auto *OAE = dyn_cast<OMPArraySectionExpr>(E)) {
7203 QualType BaseTy = OMPArraySectionExpr::getBaseOriginalType(
7204 OAE->getBase()->IgnoreParenImpCasts())
7205 .getCanonicalType();
7206
Alexey Bataevb9b8ca22019-10-01 18:18:03 +00007207 // If there is no length associated with the expression and lower bound is
7208 // not specified too, that means we are using the whole length of the
7209 // base.
7210 if (!OAE->getLength() && OAE->getColonLoc().isValid() &&
7211 !OAE->getLowerBound())
Samuel Antao86ace552016-04-27 22:40:57 +00007212 return CGF.getTypeSize(BaseTy);
7213
7214 llvm::Value *ElemSize;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007215 if (const auto *PTy = BaseTy->getAs<PointerType>()) {
Samuel Antao86ace552016-04-27 22:40:57 +00007216 ElemSize = CGF.getTypeSize(PTy->getPointeeType().getCanonicalType());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007217 } else {
7218 const auto *ATy = cast<ArrayType>(BaseTy.getTypePtr());
Samuel Antao86ace552016-04-27 22:40:57 +00007219 assert(ATy && "Expecting array type if not a pointer type.");
7220 ElemSize = CGF.getTypeSize(ATy->getElementType().getCanonicalType());
7221 }
7222
7223 // If we don't have a length at this point, that is because we have an
7224 // array section with a single element.
Alexey Bataevb9b8ca22019-10-01 18:18:03 +00007225 if (!OAE->getLength() && OAE->getColonLoc().isInvalid())
Samuel Antao86ace552016-04-27 22:40:57 +00007226 return ElemSize;
7227
Alexey Bataevb9b8ca22019-10-01 18:18:03 +00007228 if (const Expr *LenExpr = OAE->getLength()) {
Michael Liaod838cf72019-10-02 00:22:45 +00007229 llvm::Value *LengthVal = CGF.EmitScalarExpr(LenExpr);
7230 LengthVal = CGF.EmitScalarConversion(LengthVal, LenExpr->getType(),
7231 CGF.getContext().getSizeType(),
7232 LenExpr->getExprLoc());
Alexey Bataevb9b8ca22019-10-01 18:18:03 +00007233 return CGF.Builder.CreateNUWMul(LengthVal, ElemSize);
7234 }
7235 assert(!OAE->getLength() && OAE->getColonLoc().isValid() &&
7236 OAE->getLowerBound() && "expected array_section[lb:].");
7237 // Size = sizetype - lb * elemtype;
7238 llvm::Value *LengthVal = CGF.getTypeSize(BaseTy);
7239 llvm::Value *LBVal = CGF.EmitScalarExpr(OAE->getLowerBound());
7240 LBVal = CGF.EmitScalarConversion(LBVal, OAE->getLowerBound()->getType(),
7241 CGF.getContext().getSizeType(),
7242 OAE->getLowerBound()->getExprLoc());
7243 LBVal = CGF.Builder.CreateNUWMul(LBVal, ElemSize);
7244 llvm::Value *Cmp = CGF.Builder.CreateICmpUGT(LengthVal, LBVal);
7245 llvm::Value *TrueVal = CGF.Builder.CreateNUWSub(LengthVal, LBVal);
7246 LengthVal = CGF.Builder.CreateSelect(
7247 Cmp, TrueVal, llvm::ConstantInt::get(CGF.SizeTy, 0));
7248 return LengthVal;
Samuel Antao86ace552016-04-27 22:40:57 +00007249 }
7250 return CGF.getTypeSize(ExprTy);
7251 }
7252
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007253 /// Return the corresponding bits for a given map clause modifier. Add
Samuel Antao86ace552016-04-27 22:40:57 +00007254 /// a flag marking the map as a pointer if requested. Add a flag marking the
Samuel Antao6782e942016-05-26 16:48:10 +00007255 /// map as the first one of a series of maps that relate to the same map
7256 /// expression.
Kelvin Lief579432018-12-18 22:18:41 +00007257 OpenMPOffloadMappingFlags getMapTypeBits(
7258 OpenMPMapClauseKind MapType, ArrayRef<OpenMPMapModifierKind> MapModifiers,
7259 bool IsImplicit, bool AddPtrFlag, bool AddIsTargetParamFlag) const {
Alexey Bataevb3638132018-07-19 16:34:13 +00007260 OpenMPOffloadMappingFlags Bits =
7261 IsImplicit ? OMP_MAP_IMPLICIT : OMP_MAP_NONE;
Samuel Antao86ace552016-04-27 22:40:57 +00007262 switch (MapType) {
7263 case OMPC_MAP_alloc:
Samuel Antao6782e942016-05-26 16:48:10 +00007264 case OMPC_MAP_release:
7265 // alloc and release is the default behavior in the runtime library, i.e.
7266 // if we don't pass any bits alloc/release that is what the runtime is
7267 // going to do. Therefore, we don't need to signal anything for these two
7268 // type modifiers.
Samuel Antao86ace552016-04-27 22:40:57 +00007269 break;
7270 case OMPC_MAP_to:
Alexey Bataevb3638132018-07-19 16:34:13 +00007271 Bits |= OMP_MAP_TO;
Samuel Antao86ace552016-04-27 22:40:57 +00007272 break;
7273 case OMPC_MAP_from:
Alexey Bataevb3638132018-07-19 16:34:13 +00007274 Bits |= OMP_MAP_FROM;
Samuel Antao86ace552016-04-27 22:40:57 +00007275 break;
7276 case OMPC_MAP_tofrom:
Alexey Bataevb3638132018-07-19 16:34:13 +00007277 Bits |= OMP_MAP_TO | OMP_MAP_FROM;
Samuel Antao86ace552016-04-27 22:40:57 +00007278 break;
7279 case OMPC_MAP_delete:
Alexey Bataevb3638132018-07-19 16:34:13 +00007280 Bits |= OMP_MAP_DELETE;
Samuel Antao86ace552016-04-27 22:40:57 +00007281 break;
Alexey Bataevb3638132018-07-19 16:34:13 +00007282 case OMPC_MAP_unknown:
Samuel Antao86ace552016-04-27 22:40:57 +00007283 llvm_unreachable("Unexpected map type!");
Samuel Antao86ace552016-04-27 22:40:57 +00007284 }
7285 if (AddPtrFlag)
George Rokos065755d2017-11-07 18:27:04 +00007286 Bits |= OMP_MAP_PTR_AND_OBJ;
7287 if (AddIsTargetParamFlag)
7288 Bits |= OMP_MAP_TARGET_PARAM;
Kelvin Lief579432018-12-18 22:18:41 +00007289 if (llvm::find(MapModifiers, OMPC_MAP_MODIFIER_always)
7290 != MapModifiers.end())
Samuel Antao86ace552016-04-27 22:40:57 +00007291 Bits |= OMP_MAP_ALWAYS;
Gheorghe-Teodor Bercea0fd073b2019-08-09 21:42:13 +00007292 if (llvm::find(MapModifiers, OMPC_MAP_MODIFIER_close)
7293 != MapModifiers.end())
7294 Bits |= OMP_MAP_CLOSE;
Samuel Antao86ace552016-04-27 22:40:57 +00007295 return Bits;
7296 }
7297
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007298 /// Return true if the provided expression is a final array section. A
Samuel Antao86ace552016-04-27 22:40:57 +00007299 /// final array section, is one whose length can't be proved to be one.
7300 bool isFinalArraySectionExpression(const Expr *E) const {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007301 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
Samuel Antao86ace552016-04-27 22:40:57 +00007302
7303 // It is not an array section and therefore not a unity-size one.
7304 if (!OASE)
7305 return false;
7306
7307 // An array section with no colon always refer to a single element.
7308 if (OASE->getColonLoc().isInvalid())
7309 return false;
7310
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007311 const Expr *Length = OASE->getLength();
Samuel Antao86ace552016-04-27 22:40:57 +00007312
7313 // If we don't have a length we have to check if the array has size 1
7314 // for this dimension. Also, we should always expect a length if the
7315 // base type is pointer.
7316 if (!Length) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007317 QualType BaseQTy = OMPArraySectionExpr::getBaseOriginalType(
7318 OASE->getBase()->IgnoreParenImpCasts())
7319 .getCanonicalType();
7320 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
Samuel Antao86ace552016-04-27 22:40:57 +00007321 return ATy->getSize().getSExtValue() != 1;
7322 // If we don't have a constant dimension length, we have to consider
7323 // the current section as having any size, so it is not necessarily
7324 // unitary. If it happen to be unity size, that's user fault.
7325 return true;
7326 }
7327
7328 // Check if the length evaluates to 1.
Fangrui Song407659a2018-11-30 23:41:18 +00007329 Expr::EvalResult Result;
7330 if (!Length->EvaluateAsInt(Result, CGF.getContext()))
Samuel Antao86ace552016-04-27 22:40:57 +00007331 return true; // Can have more that size 1.
7332
Fangrui Song407659a2018-11-30 23:41:18 +00007333 llvm::APSInt ConstLength = Result.Val.getInt();
Samuel Antao86ace552016-04-27 22:40:57 +00007334 return ConstLength.getSExtValue() != 1;
7335 }
7336
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007337 /// Generate the base pointers, section pointers, sizes and map type
Samuel Antao86ace552016-04-27 22:40:57 +00007338 /// bits for the provided map type, map modifier, and expression components.
7339 /// \a IsFirstComponent should be set to true if the provided set of
7340 /// components is the first associated with a capture.
7341 void generateInfoForComponentList(
Kelvin Lief579432018-12-18 22:18:41 +00007342 OpenMPMapClauseKind MapType,
7343 ArrayRef<OpenMPMapModifierKind> MapModifiers,
Samuel Antao86ace552016-04-27 22:40:57 +00007344 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
Samuel Antaocc10b852016-07-28 14:23:26 +00007345 MapBaseValuesArrayTy &BasePointers, MapValuesArrayTy &Pointers,
Samuel Antao86ace552016-04-27 22:40:57 +00007346 MapValuesArrayTy &Sizes, MapFlagsArrayTy &Types,
Alexey Bataevb3638132018-07-19 16:34:13 +00007347 StructRangeInfoTy &PartialStruct, bool IsFirstComponentList,
Alexey Bataeve82445f2018-09-20 13:54:02 +00007348 bool IsImplicit,
7349 ArrayRef<OMPClauseMappableExprCommon::MappableExprComponentListRef>
7350 OverlappedElements = llvm::None) const {
Samuel Antao86ace552016-04-27 22:40:57 +00007351 // The following summarizes what has to be generated for each map and the
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +00007352 // types below. The generated information is expressed in this order:
Samuel Antao86ace552016-04-27 22:40:57 +00007353 // base pointer, section pointer, size, flags
7354 // (to add to the ones that come from the map type and modifier).
7355 //
7356 // double d;
7357 // int i[100];
7358 // float *p;
7359 //
7360 // struct S1 {
7361 // int i;
7362 // float f[50];
7363 // }
7364 // struct S2 {
7365 // int i;
7366 // float f[50];
7367 // S1 s;
7368 // double *p;
7369 // struct S2 *ps;
7370 // }
7371 // S2 s;
7372 // S2 *ps;
7373 //
7374 // map(d)
Alexey Bataevb3638132018-07-19 16:34:13 +00007375 // &d, &d, sizeof(double), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007376 //
7377 // map(i)
Alexey Bataevb3638132018-07-19 16:34:13 +00007378 // &i, &i, 100*sizeof(int), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007379 //
7380 // map(i[1:23])
Alexey Bataevb3638132018-07-19 16:34:13 +00007381 // &i(=&i[0]), &i[1], 23*sizeof(int), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007382 //
7383 // map(p)
Alexey Bataevb3638132018-07-19 16:34:13 +00007384 // &p, &p, sizeof(float*), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007385 //
7386 // map(p[1:24])
Alexey Bataevb3638132018-07-19 16:34:13 +00007387 // p, &p[1], 24*sizeof(float), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007388 //
7389 // map(s)
Alexey Bataevb3638132018-07-19 16:34:13 +00007390 // &s, &s, sizeof(S2), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007391 //
7392 // map(s.i)
Alexey Bataevb3638132018-07-19 16:34:13 +00007393 // &s, &(s.i), sizeof(int), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007394 //
7395 // map(s.s.f)
Alexey Bataevb3638132018-07-19 16:34:13 +00007396 // &s, &(s.s.f[0]), 50*sizeof(float), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007397 //
7398 // map(s.p)
Alexey Bataevb3638132018-07-19 16:34:13 +00007399 // &s, &(s.p), sizeof(double*), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007400 //
Alexey Bataevb3638132018-07-19 16:34:13 +00007401 // map(to: s.p[:22])
7402 // &s, &(s.p), sizeof(double*), TARGET_PARAM (*)
7403 // &s, &(s.p), sizeof(double*), MEMBER_OF(1) (**)
7404 // &(s.p), &(s.p[0]), 22*sizeof(double),
7405 // MEMBER_OF(1) | PTR_AND_OBJ | TO (***)
7406 // (*) alloc space for struct members, only this is a target parameter
7407 // (**) map the pointer (nothing to be mapped in this example) (the compiler
7408 // optimizes this entry out, same in the examples below)
7409 // (***) map the pointee (map: to)
Samuel Antao86ace552016-04-27 22:40:57 +00007410 //
7411 // map(s.ps)
Alexey Bataevb3638132018-07-19 16:34:13 +00007412 // &s, &(s.ps), sizeof(S2*), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007413 //
Alexey Bataevb3638132018-07-19 16:34:13 +00007414 // map(from: s.ps->s.i)
7415 // &s, &(s.ps), sizeof(S2*), TARGET_PARAM
7416 // &s, &(s.ps), sizeof(S2*), MEMBER_OF(1)
7417 // &(s.ps), &(s.ps->s.i), sizeof(int), MEMBER_OF(1) | PTR_AND_OBJ | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007418 //
Alexey Bataevb3638132018-07-19 16:34:13 +00007419 // map(to: s.ps->ps)
7420 // &s, &(s.ps), sizeof(S2*), TARGET_PARAM
7421 // &s, &(s.ps), sizeof(S2*), MEMBER_OF(1)
7422 // &(s.ps), &(s.ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ | TO
Samuel Antao86ace552016-04-27 22:40:57 +00007423 //
7424 // map(s.ps->ps->ps)
Alexey Bataevb3638132018-07-19 16:34:13 +00007425 // &s, &(s.ps), sizeof(S2*), TARGET_PARAM
7426 // &s, &(s.ps), sizeof(S2*), MEMBER_OF(1)
7427 // &(s.ps), &(s.ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ
7428 // &(s.ps->ps), &(s.ps->ps->ps), sizeof(S2*), PTR_AND_OBJ | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007429 //
Alexey Bataevb3638132018-07-19 16:34:13 +00007430 // map(to: s.ps->ps->s.f[:22])
7431 // &s, &(s.ps), sizeof(S2*), TARGET_PARAM
7432 // &s, &(s.ps), sizeof(S2*), MEMBER_OF(1)
7433 // &(s.ps), &(s.ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ
7434 // &(s.ps->ps), &(s.ps->ps->s.f[0]), 22*sizeof(float), PTR_AND_OBJ | TO
Samuel Antao86ace552016-04-27 22:40:57 +00007435 //
7436 // map(ps)
Alexey Bataevb3638132018-07-19 16:34:13 +00007437 // &ps, &ps, sizeof(S2*), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007438 //
7439 // map(ps->i)
Alexey Bataevb3638132018-07-19 16:34:13 +00007440 // ps, &(ps->i), sizeof(int), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007441 //
7442 // map(ps->s.f)
Alexey Bataevb3638132018-07-19 16:34:13 +00007443 // ps, &(ps->s.f[0]), 50*sizeof(float), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007444 //
Alexey Bataevb3638132018-07-19 16:34:13 +00007445 // map(from: ps->p)
7446 // ps, &(ps->p), sizeof(double*), TARGET_PARAM | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007447 //
Alexey Bataevb3638132018-07-19 16:34:13 +00007448 // map(to: ps->p[:22])
7449 // ps, &(ps->p), sizeof(double*), TARGET_PARAM
7450 // ps, &(ps->p), sizeof(double*), MEMBER_OF(1)
7451 // &(ps->p), &(ps->p[0]), 22*sizeof(double), MEMBER_OF(1) | PTR_AND_OBJ | TO
Samuel Antao86ace552016-04-27 22:40:57 +00007452 //
7453 // map(ps->ps)
Alexey Bataevb3638132018-07-19 16:34:13 +00007454 // ps, &(ps->ps), sizeof(S2*), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007455 //
Alexey Bataevb3638132018-07-19 16:34:13 +00007456 // map(from: ps->ps->s.i)
7457 // ps, &(ps->ps), sizeof(S2*), TARGET_PARAM
7458 // ps, &(ps->ps), sizeof(S2*), MEMBER_OF(1)
7459 // &(ps->ps), &(ps->ps->s.i), sizeof(int), MEMBER_OF(1) | PTR_AND_OBJ | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007460 //
Alexey Bataevb3638132018-07-19 16:34:13 +00007461 // map(from: ps->ps->ps)
7462 // ps, &(ps->ps), sizeof(S2*), TARGET_PARAM
7463 // ps, &(ps->ps), sizeof(S2*), MEMBER_OF(1)
7464 // &(ps->ps), &(ps->ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007465 //
7466 // map(ps->ps->ps->ps)
Alexey Bataevb3638132018-07-19 16:34:13 +00007467 // ps, &(ps->ps), sizeof(S2*), TARGET_PARAM
7468 // ps, &(ps->ps), sizeof(S2*), MEMBER_OF(1)
7469 // &(ps->ps), &(ps->ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ
7470 // &(ps->ps->ps), &(ps->ps->ps->ps), sizeof(S2*), PTR_AND_OBJ | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007471 //
Alexey Bataevb3638132018-07-19 16:34:13 +00007472 // map(to: ps->ps->ps->s.f[:22])
7473 // ps, &(ps->ps), sizeof(S2*), TARGET_PARAM
7474 // ps, &(ps->ps), sizeof(S2*), MEMBER_OF(1)
7475 // &(ps->ps), &(ps->ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ
7476 // &(ps->ps->ps), &(ps->ps->ps->s.f[0]), 22*sizeof(float), PTR_AND_OBJ | TO
7477 //
7478 // map(to: s.f[:22]) map(from: s.p[:33])
7479 // &s, &(s.f[0]), 50*sizeof(float) + sizeof(struct S1) +
7480 // sizeof(double*) (**), TARGET_PARAM
7481 // &s, &(s.f[0]), 22*sizeof(float), MEMBER_OF(1) | TO
7482 // &s, &(s.p), sizeof(double*), MEMBER_OF(1)
7483 // &(s.p), &(s.p[0]), 33*sizeof(double), MEMBER_OF(1) | PTR_AND_OBJ | FROM
7484 // (*) allocate contiguous space needed to fit all mapped members even if
7485 // we allocate space for members not mapped (in this example,
7486 // s.f[22..49] and s.s are not mapped, yet we must allocate space for
7487 // them as well because they fall between &s.f[0] and &s.p)
7488 //
7489 // map(from: s.f[:22]) map(to: ps->p[:33])
7490 // &s, &(s.f[0]), 22*sizeof(float), TARGET_PARAM | FROM
7491 // ps, &(ps->p), sizeof(S2*), TARGET_PARAM
7492 // ps, &(ps->p), sizeof(double*), MEMBER_OF(2) (*)
7493 // &(ps->p), &(ps->p[0]), 33*sizeof(double), MEMBER_OF(2) | PTR_AND_OBJ | TO
7494 // (*) the struct this entry pertains to is the 2nd element in the list of
7495 // arguments, hence MEMBER_OF(2)
7496 //
7497 // map(from: s.f[:22], s.s) map(to: ps->p[:33])
7498 // &s, &(s.f[0]), 50*sizeof(float) + sizeof(struct S1), TARGET_PARAM
7499 // &s, &(s.f[0]), 22*sizeof(float), MEMBER_OF(1) | FROM
7500 // &s, &(s.s), sizeof(struct S1), MEMBER_OF(1) | FROM
7501 // ps, &(ps->p), sizeof(S2*), TARGET_PARAM
7502 // ps, &(ps->p), sizeof(double*), MEMBER_OF(4) (*)
7503 // &(ps->p), &(ps->p[0]), 33*sizeof(double), MEMBER_OF(4) | PTR_AND_OBJ | TO
7504 // (*) the struct this entry pertains to is the 4th element in the list
7505 // of arguments, hence MEMBER_OF(4)
Samuel Antao86ace552016-04-27 22:40:57 +00007506
7507 // Track if the map information being generated is the first for a capture.
7508 bool IsCaptureFirstInfo = IsFirstComponentList;
Gheorghe-Teodor Bercea0034e842019-06-20 18:04:47 +00007509 // When the variable is on a declare target link or in a to clause with
7510 // unified memory, a reference is needed to hold the host/device address
7511 // of the variable.
7512 bool RequiresReference = false;
Samuel Antao86ace552016-04-27 22:40:57 +00007513
7514 // Scan the components from the base to the complete expression.
7515 auto CI = Components.rbegin();
7516 auto CE = Components.rend();
7517 auto I = CI;
7518
7519 // Track if the map information being generated is the first for a list of
7520 // components.
7521 bool IsExpressionFirstInfo = true;
Alexey Bataevb3638132018-07-19 16:34:13 +00007522 Address BP = Address::invalid();
Patrick Lystere13b1e32019-01-02 19:28:48 +00007523 const Expr *AssocExpr = I->getAssociatedExpression();
7524 const auto *AE = dyn_cast<ArraySubscriptExpr>(AssocExpr);
7525 const auto *OASE = dyn_cast<OMPArraySectionExpr>(AssocExpr);
Samuel Antao86ace552016-04-27 22:40:57 +00007526
Patrick Lystere13b1e32019-01-02 19:28:48 +00007527 if (isa<MemberExpr>(AssocExpr)) {
Samuel Antao86ace552016-04-27 22:40:57 +00007528 // The base is the 'this' pointer. The content of the pointer is going
7529 // to be the base of the field being mapped.
Alexey Bataevb3638132018-07-19 16:34:13 +00007530 BP = CGF.LoadCXXThisAddress();
Patrick Lystere13b1e32019-01-02 19:28:48 +00007531 } else if ((AE && isa<CXXThisExpr>(AE->getBase()->IgnoreParenImpCasts())) ||
7532 (OASE &&
7533 isa<CXXThisExpr>(OASE->getBase()->IgnoreParenImpCasts()))) {
Akira Hatanakaf139ae32019-12-03 15:17:01 -08007534 BP = CGF.EmitOMPSharedLValue(AssocExpr).getAddress(CGF);
Samuel Antao86ace552016-04-27 22:40:57 +00007535 } else {
7536 // The base is the reference to the variable.
7537 // BP = &Var.
Akira Hatanakaf139ae32019-12-03 15:17:01 -08007538 BP = CGF.EmitOMPSharedLValue(AssocExpr).getAddress(CGF);
Alexey Bataev92327c52018-03-26 16:40:55 +00007539 if (const auto *VD =
7540 dyn_cast_or_null<VarDecl>(I->getAssociatedDeclaration())) {
7541 if (llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
Gheorghe-Teodor Bercea0034e842019-06-20 18:04:47 +00007542 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
7543 if ((*Res == OMPDeclareTargetDeclAttr::MT_Link) ||
7544 (*Res == OMPDeclareTargetDeclAttr::MT_To &&
7545 CGF.CGM.getOpenMPRuntime().hasRequiresUnifiedSharedMemory())) {
7546 RequiresReference = true;
7547 BP = CGF.CGM.getOpenMPRuntime().getAddrOfDeclareTargetVar(VD);
Alexey Bataev2c1dffe2018-04-16 20:34:41 +00007548 }
Gheorghe-Teodor Bercea0034e842019-06-20 18:04:47 +00007549 }
Alexey Bataev92327c52018-03-26 16:40:55 +00007550 }
Samuel Antao86ace552016-04-27 22:40:57 +00007551
7552 // If the variable is a pointer and is being dereferenced (i.e. is not
Nico Webera6916892016-06-10 18:53:04 +00007553 // the last component), the base has to be the pointer itself, not its
Samuel Antao403ffd42016-07-27 22:49:49 +00007554 // reference. References are ignored for mapping purposes.
7555 QualType Ty =
7556 I->getAssociatedDeclaration()->getType().getNonReferenceType();
7557 if (Ty->isAnyPointerType() && std::next(I) != CE) {
Alexey Bataevb3638132018-07-19 16:34:13 +00007558 BP = CGF.EmitLoadOfPointer(BP, Ty->castAs<PointerType>());
Samuel Antao86ace552016-04-27 22:40:57 +00007559
7560 // We do not need to generate individual map information for the
7561 // pointer, it can be associated with the combined storage.
7562 ++I;
7563 }
7564 }
7565
Alexey Bataevb3638132018-07-19 16:34:13 +00007566 // Track whether a component of the list should be marked as MEMBER_OF some
7567 // combined entry (for partial structs). Only the first PTR_AND_OBJ entry
7568 // in a component list should be marked as MEMBER_OF, all subsequent entries
7569 // do not belong to the base struct. E.g.
7570 // struct S2 s;
7571 // s.ps->ps->ps->f[:]
7572 // (1) (2) (3) (4)
7573 // ps(1) is a member pointer, ps(2) is a pointee of ps(1), so it is a
7574 // PTR_AND_OBJ entry; the PTR is ps(1), so MEMBER_OF the base struct. ps(3)
7575 // is the pointee of ps(2) which is not member of struct s, so it should not
7576 // be marked as such (it is still PTR_AND_OBJ).
7577 // The variable is initialized to false so that PTR_AND_OBJ entries which
7578 // are not struct members are not considered (e.g. array of pointers to
7579 // data).
7580 bool ShouldBeMemberOf = false;
7581
7582 // Variable keeping track of whether or not we have encountered a component
7583 // in the component list which is a member expression. Useful when we have a
7584 // pointer or a final array section, in which case it is the previous
7585 // component in the list which tells us whether we have a member expression.
7586 // E.g. X.f[:]
7587 // While processing the final array section "[:]" it is "f" which tells us
7588 // whether we are dealing with a member of a declared struct.
7589 const MemberExpr *EncounteredME = nullptr;
7590
Samuel Antao86ace552016-04-27 22:40:57 +00007591 for (; I != CE; ++I) {
Alexey Bataevb3638132018-07-19 16:34:13 +00007592 // If the current component is member of a struct (parent struct) mark it.
7593 if (!EncounteredME) {
7594 EncounteredME = dyn_cast<MemberExpr>(I->getAssociatedExpression());
7595 // If we encounter a PTR_AND_OBJ entry from now on it should be marked
7596 // as MEMBER_OF the parent struct.
7597 if (EncounteredME)
7598 ShouldBeMemberOf = true;
7599 }
7600
Samuel Antao86ace552016-04-27 22:40:57 +00007601 auto Next = std::next(I);
7602
7603 // We need to generate the addresses and sizes if this is the last
7604 // component, if the component is a pointer or if it is an array section
7605 // whose length can't be proved to be one. If this is a pointer, it
7606 // becomes the base address for the following components.
7607
7608 // A final array section, is one whose length can't be proved to be one.
7609 bool IsFinalArraySection =
7610 isFinalArraySectionExpression(I->getAssociatedExpression());
7611
7612 // Get information on whether the element is a pointer. Have to do a
7613 // special treatment for array sections given that they are built-in
7614 // types.
7615 const auto *OASE =
7616 dyn_cast<OMPArraySectionExpr>(I->getAssociatedExpression());
7617 bool IsPointer =
Alexey Bataevb3638132018-07-19 16:34:13 +00007618 (OASE && OMPArraySectionExpr::getBaseOriginalType(OASE)
7619 .getCanonicalType()
7620 ->isAnyPointerType()) ||
Samuel Antao86ace552016-04-27 22:40:57 +00007621 I->getAssociatedExpression()->getType()->isAnyPointerType();
7622
7623 if (Next == CE || IsPointer || IsFinalArraySection) {
Samuel Antao86ace552016-04-27 22:40:57 +00007624 // If this is not the last component, we expect the pointer to be
7625 // associated with an array expression or member expression.
7626 assert((Next == CE ||
7627 isa<MemberExpr>(Next->getAssociatedExpression()) ||
7628 isa<ArraySubscriptExpr>(Next->getAssociatedExpression()) ||
7629 isa<OMPArraySectionExpr>(Next->getAssociatedExpression())) &&
7630 "Unexpected expression");
7631
Akira Hatanakaf139ae32019-12-03 15:17:01 -08007632 Address LB = CGF.EmitOMPSharedLValue(I->getAssociatedExpression())
7633 .getAddress(CGF);
Samuel Antao86ace552016-04-27 22:40:57 +00007634
Alexey Bataevb3638132018-07-19 16:34:13 +00007635 // If this component is a pointer inside the base struct then we don't
7636 // need to create any entry for it - it will be combined with the object
7637 // it is pointing to into a single PTR_AND_OBJ entry.
7638 bool IsMemberPointer =
7639 IsPointer && EncounteredME &&
7640 (dyn_cast<MemberExpr>(I->getAssociatedExpression()) ==
7641 EncounteredME);
Alexey Bataeve82445f2018-09-20 13:54:02 +00007642 if (!OverlappedElements.empty()) {
7643 // Handle base element with the info for overlapped elements.
7644 assert(!PartialStruct.Base.isValid() && "The base element is set.");
7645 assert(Next == CE &&
7646 "Expected last element for the overlapped elements.");
7647 assert(!IsPointer &&
7648 "Unexpected base element with the pointer type.");
7649 // Mark the whole struct as the struct that requires allocation on the
7650 // device.
7651 PartialStruct.LowestElem = {0, LB};
7652 CharUnits TypeSize = CGF.getContext().getTypeSizeInChars(
7653 I->getAssociatedExpression()->getType());
7654 Address HB = CGF.Builder.CreateConstGEP(
7655 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(LB,
7656 CGF.VoidPtrTy),
James Y Knight751fe282019-02-09 22:22:28 +00007657 TypeSize.getQuantity() - 1);
Alexey Bataeve82445f2018-09-20 13:54:02 +00007658 PartialStruct.HighestElem = {
7659 std::numeric_limits<decltype(
7660 PartialStruct.HighestElem.first)>::max(),
7661 HB};
7662 PartialStruct.Base = BP;
7663 // Emit data for non-overlapped data.
7664 OpenMPOffloadMappingFlags Flags =
7665 OMP_MAP_MEMBER_OF |
Kelvin Lief579432018-12-18 22:18:41 +00007666 getMapTypeBits(MapType, MapModifiers, IsImplicit,
Alexey Bataeve82445f2018-09-20 13:54:02 +00007667 /*AddPtrFlag=*/false,
7668 /*AddIsTargetParamFlag=*/false);
7669 LB = BP;
7670 llvm::Value *Size = nullptr;
7671 // Do bitcopy of all non-overlapped structure elements.
7672 for (OMPClauseMappableExprCommon::MappableExprComponentListRef
7673 Component : OverlappedElements) {
7674 Address ComponentLB = Address::invalid();
7675 for (const OMPClauseMappableExprCommon::MappableComponent &MC :
7676 Component) {
7677 if (MC.getAssociatedDeclaration()) {
7678 ComponentLB =
7679 CGF.EmitOMPSharedLValue(MC.getAssociatedExpression())
Akira Hatanakaf139ae32019-12-03 15:17:01 -08007680 .getAddress(CGF);
Alexey Bataeve82445f2018-09-20 13:54:02 +00007681 Size = CGF.Builder.CreatePtrDiff(
7682 CGF.EmitCastToVoidPtr(ComponentLB.getPointer()),
7683 CGF.EmitCastToVoidPtr(LB.getPointer()));
7684 break;
7685 }
7686 }
7687 BasePointers.push_back(BP.getPointer());
7688 Pointers.push_back(LB.getPointer());
Alexey Bataeva90fc662019-06-25 16:00:43 +00007689 Sizes.push_back(CGF.Builder.CreateIntCast(Size, CGF.Int64Ty,
7690 /*isSigned=*/true));
Alexey Bataeve82445f2018-09-20 13:54:02 +00007691 Types.push_back(Flags);
James Y Knight751fe282019-02-09 22:22:28 +00007692 LB = CGF.Builder.CreateConstGEP(ComponentLB, 1);
Alexey Bataeve82445f2018-09-20 13:54:02 +00007693 }
7694 BasePointers.push_back(BP.getPointer());
7695 Pointers.push_back(LB.getPointer());
7696 Size = CGF.Builder.CreatePtrDiff(
7697 CGF.EmitCastToVoidPtr(
James Y Knight751fe282019-02-09 22:22:28 +00007698 CGF.Builder.CreateConstGEP(HB, 1).getPointer()),
Alexey Bataeve82445f2018-09-20 13:54:02 +00007699 CGF.EmitCastToVoidPtr(LB.getPointer()));
Alexey Bataeva90fc662019-06-25 16:00:43 +00007700 Sizes.push_back(
7701 CGF.Builder.CreateIntCast(Size, CGF.Int64Ty, /*isSigned=*/true));
Alexey Bataeve82445f2018-09-20 13:54:02 +00007702 Types.push_back(Flags);
7703 break;
7704 }
7705 llvm::Value *Size = getExprTypeSize(I->getAssociatedExpression());
Alexey Bataevb3638132018-07-19 16:34:13 +00007706 if (!IsMemberPointer) {
7707 BasePointers.push_back(BP.getPointer());
7708 Pointers.push_back(LB.getPointer());
Alexey Bataeva90fc662019-06-25 16:00:43 +00007709 Sizes.push_back(
7710 CGF.Builder.CreateIntCast(Size, CGF.Int64Ty, /*isSigned=*/true));
Samuel Antao03a3cec2016-07-27 22:52:16 +00007711
Alexey Bataevb3638132018-07-19 16:34:13 +00007712 // We need to add a pointer flag for each map that comes from the
7713 // same expression except for the first one. We also need to signal
7714 // this map is the first one that relates with the current capture
7715 // (there is a set of entries for each capture).
7716 OpenMPOffloadMappingFlags Flags = getMapTypeBits(
Kelvin Lief579432018-12-18 22:18:41 +00007717 MapType, MapModifiers, IsImplicit,
Gheorghe-Teodor Bercea0034e842019-06-20 18:04:47 +00007718 !IsExpressionFirstInfo || RequiresReference,
7719 IsCaptureFirstInfo && !RequiresReference);
Alexey Bataevb3638132018-07-19 16:34:13 +00007720
7721 if (!IsExpressionFirstInfo) {
7722 // If we have a PTR_AND_OBJ pair where the OBJ is a pointer as well,
Gheorghe-Teodor Bercea0fd073b2019-08-09 21:42:13 +00007723 // then we reset the TO/FROM/ALWAYS/DELETE/CLOSE flags.
Alexey Bataevb3638132018-07-19 16:34:13 +00007724 if (IsPointer)
7725 Flags &= ~(OMP_MAP_TO | OMP_MAP_FROM | OMP_MAP_ALWAYS |
Gheorghe-Teodor Bercea0fd073b2019-08-09 21:42:13 +00007726 OMP_MAP_DELETE | OMP_MAP_CLOSE);
Alexey Bataevb3638132018-07-19 16:34:13 +00007727
7728 if (ShouldBeMemberOf) {
7729 // Set placeholder value MEMBER_OF=FFFF to indicate that the flag
7730 // should be later updated with the correct value of MEMBER_OF.
7731 Flags |= OMP_MAP_MEMBER_OF;
7732 // From now on, all subsequent PTR_AND_OBJ entries should not be
7733 // marked as MEMBER_OF.
7734 ShouldBeMemberOf = false;
7735 }
7736 }
7737
7738 Types.push_back(Flags);
Samuel Antao03a3cec2016-07-27 22:52:16 +00007739 }
7740
Alexey Bataevb3638132018-07-19 16:34:13 +00007741 // If we have encountered a member expression so far, keep track of the
7742 // mapped member. If the parent is "*this", then the value declaration
7743 // is nullptr.
7744 if (EncounteredME) {
7745 const auto *FD = dyn_cast<FieldDecl>(EncounteredME->getMemberDecl());
7746 unsigned FieldIndex = FD->getFieldIndex();
Samuel Antao03a3cec2016-07-27 22:52:16 +00007747
Alexey Bataevb3638132018-07-19 16:34:13 +00007748 // Update info about the lowest and highest elements for this struct
7749 if (!PartialStruct.Base.isValid()) {
7750 PartialStruct.LowestElem = {FieldIndex, LB};
7751 PartialStruct.HighestElem = {FieldIndex, LB};
7752 PartialStruct.Base = BP;
7753 } else if (FieldIndex < PartialStruct.LowestElem.first) {
7754 PartialStruct.LowestElem = {FieldIndex, LB};
7755 } else if (FieldIndex > PartialStruct.HighestElem.first) {
7756 PartialStruct.HighestElem = {FieldIndex, LB};
7757 }
7758 }
Samuel Antao86ace552016-04-27 22:40:57 +00007759
7760 // If we have a final array section, we are done with this expression.
7761 if (IsFinalArraySection)
7762 break;
7763
7764 // The pointer becomes the base for the next element.
7765 if (Next != CE)
7766 BP = LB;
7767
7768 IsExpressionFirstInfo = false;
7769 IsCaptureFirstInfo = false;
Samuel Antao86ace552016-04-27 22:40:57 +00007770 }
7771 }
7772 }
7773
Alexey Bataevb3638132018-07-19 16:34:13 +00007774 /// Return the adjusted map modifiers if the declaration a capture refers to
7775 /// appears in a first-private clause. This is expected to be used only with
7776 /// directives that start with 'target'.
7777 MappableExprsHandler::OpenMPOffloadMappingFlags
7778 getMapModifiersForPrivateClauses(const CapturedStmt::Capture &Cap) const {
7779 assert(Cap.capturesVariable() && "Expected capture by reference only!");
7780
7781 // A first private variable captured by reference will use only the
7782 // 'private ptr' and 'map to' flag. Return the right flags if the captured
7783 // declaration is known as first-private in this handler.
Alexey Bataev1af5bd52019-03-05 17:47:18 +00007784 if (FirstPrivateDecls.count(Cap.getCapturedVar())) {
7785 if (Cap.getCapturedVar()->getType().isConstant(CGF.getContext()) &&
7786 Cap.getCaptureKind() == CapturedStmt::VCK_ByRef)
7787 return MappableExprsHandler::OMP_MAP_ALWAYS |
7788 MappableExprsHandler::OMP_MAP_TO;
Alexey Bataevc2b831f2019-04-02 16:03:40 +00007789 if (Cap.getCapturedVar()->getType()->isAnyPointerType())
7790 return MappableExprsHandler::OMP_MAP_TO |
7791 MappableExprsHandler::OMP_MAP_PTR_AND_OBJ;
Alexey Bataevb3638132018-07-19 16:34:13 +00007792 return MappableExprsHandler::OMP_MAP_PRIVATE |
7793 MappableExprsHandler::OMP_MAP_TO;
Alexey Bataev1af5bd52019-03-05 17:47:18 +00007794 }
Alexey Bataevb3638132018-07-19 16:34:13 +00007795 return MappableExprsHandler::OMP_MAP_TO |
7796 MappableExprsHandler::OMP_MAP_FROM;
7797 }
7798
7799 static OpenMPOffloadMappingFlags getMemberOfFlag(unsigned Position) {
Michael Krused47b9432019-08-05 18:43:21 +00007800 // Rotate by getFlagMemberOffset() bits.
Alexey Bataevb3638132018-07-19 16:34:13 +00007801 return static_cast<OpenMPOffloadMappingFlags>(((uint64_t)Position + 1)
Michael Krused47b9432019-08-05 18:43:21 +00007802 << getFlagMemberOffset());
Alexey Bataevb3638132018-07-19 16:34:13 +00007803 }
7804
7805 static void setCorrectMemberOfFlag(OpenMPOffloadMappingFlags &Flags,
7806 OpenMPOffloadMappingFlags MemberOfFlag) {
7807 // If the entry is PTR_AND_OBJ but has not been marked with the special
7808 // placeholder value 0xFFFF in the MEMBER_OF field, then it should not be
7809 // marked as MEMBER_OF.
7810 if ((Flags & OMP_MAP_PTR_AND_OBJ) &&
7811 ((Flags & OMP_MAP_MEMBER_OF) != OMP_MAP_MEMBER_OF))
7812 return;
7813
7814 // Reset the placeholder value to prepare the flag for the assignment of the
7815 // proper MEMBER_OF value.
7816 Flags &= ~OMP_MAP_MEMBER_OF;
7817 Flags |= MemberOfFlag;
7818 }
7819
Alexey Bataeve82445f2018-09-20 13:54:02 +00007820 void getPlainLayout(const CXXRecordDecl *RD,
7821 llvm::SmallVectorImpl<const FieldDecl *> &Layout,
7822 bool AsBase) const {
7823 const CGRecordLayout &RL = CGF.getTypes().getCGRecordLayout(RD);
7824
7825 llvm::StructType *St =
7826 AsBase ? RL.getBaseSubobjectLLVMType() : RL.getLLVMType();
7827
7828 unsigned NumElements = St->getNumElements();
7829 llvm::SmallVector<
7830 llvm::PointerUnion<const CXXRecordDecl *, const FieldDecl *>, 4>
7831 RecordLayout(NumElements);
7832
7833 // Fill bases.
7834 for (const auto &I : RD->bases()) {
7835 if (I.isVirtual())
7836 continue;
7837 const auto *Base = I.getType()->getAsCXXRecordDecl();
7838 // Ignore empty bases.
7839 if (Base->isEmpty() || CGF.getContext()
7840 .getASTRecordLayout(Base)
7841 .getNonVirtualSize()
7842 .isZero())
7843 continue;
7844
7845 unsigned FieldIndex = RL.getNonVirtualBaseLLVMFieldNo(Base);
7846 RecordLayout[FieldIndex] = Base;
7847 }
7848 // Fill in virtual bases.
7849 for (const auto &I : RD->vbases()) {
7850 const auto *Base = I.getType()->getAsCXXRecordDecl();
7851 // Ignore empty bases.
7852 if (Base->isEmpty())
7853 continue;
7854 unsigned FieldIndex = RL.getVirtualBaseIndex(Base);
7855 if (RecordLayout[FieldIndex])
7856 continue;
7857 RecordLayout[FieldIndex] = Base;
7858 }
7859 // Fill in all the fields.
7860 assert(!RD->isUnion() && "Unexpected union.");
7861 for (const auto *Field : RD->fields()) {
7862 // Fill in non-bitfields. (Bitfields always use a zero pattern, which we
7863 // will fill in later.)
Richard Smith78b239e2019-06-20 20:44:45 +00007864 if (!Field->isBitField() && !Field->isZeroSize(CGF.getContext())) {
Alexey Bataeve82445f2018-09-20 13:54:02 +00007865 unsigned FieldIndex = RL.getLLVMFieldNo(Field);
7866 RecordLayout[FieldIndex] = Field;
7867 }
7868 }
7869 for (const llvm::PointerUnion<const CXXRecordDecl *, const FieldDecl *>
7870 &Data : RecordLayout) {
7871 if (Data.isNull())
7872 continue;
7873 if (const auto *Base = Data.dyn_cast<const CXXRecordDecl *>())
7874 getPlainLayout(Base, Layout, /*AsBase=*/true);
7875 else
7876 Layout.push_back(Data.get<const FieldDecl *>());
7877 }
7878 }
7879
Alexey Bataevb3638132018-07-19 16:34:13 +00007880public:
7881 MappableExprsHandler(const OMPExecutableDirective &Dir, CodeGenFunction &CGF)
Michael Krused47b9432019-08-05 18:43:21 +00007882 : CurDir(&Dir), CGF(CGF) {
Alexey Bataevb3638132018-07-19 16:34:13 +00007883 // Extract firstprivate clause information.
7884 for (const auto *C : Dir.getClausesOfKind<OMPFirstprivateClause>())
7885 for (const auto *D : C->varlists())
Alexey Bataevf288cf92019-06-27 18:53:07 +00007886 FirstPrivateDecls.try_emplace(
7887 cast<VarDecl>(cast<DeclRefExpr>(D)->getDecl()), C->isImplicit());
Alexey Bataevb3638132018-07-19 16:34:13 +00007888 // Extract device pointer clause information.
7889 for (const auto *C : Dir.getClausesOfKind<OMPIsDevicePtrClause>())
7890 for (auto L : C->component_lists())
7891 DevPointersMap[L.first].push_back(L.second);
7892 }
7893
Michael Krused47b9432019-08-05 18:43:21 +00007894 /// Constructor for the declare mapper directive.
7895 MappableExprsHandler(const OMPDeclareMapperDecl &Dir, CodeGenFunction &CGF)
7896 : CurDir(&Dir), CGF(CGF) {}
7897
Alexey Bataevb3638132018-07-19 16:34:13 +00007898 /// Generate code for the combined entry if we have a partially mapped struct
7899 /// and take care of the mapping flags of the arguments corresponding to
7900 /// individual struct members.
7901 void emitCombinedEntry(MapBaseValuesArrayTy &BasePointers,
7902 MapValuesArrayTy &Pointers, MapValuesArrayTy &Sizes,
7903 MapFlagsArrayTy &Types, MapFlagsArrayTy &CurTypes,
7904 const StructRangeInfoTy &PartialStruct) const {
7905 // Base is the base of the struct
7906 BasePointers.push_back(PartialStruct.Base.getPointer());
7907 // Pointer is the address of the lowest element
7908 llvm::Value *LB = PartialStruct.LowestElem.second.getPointer();
7909 Pointers.push_back(LB);
7910 // Size is (addr of {highest+1} element) - (addr of lowest element)
7911 llvm::Value *HB = PartialStruct.HighestElem.second.getPointer();
7912 llvm::Value *HAddr = CGF.Builder.CreateConstGEP1_32(HB, /*Idx0=*/1);
7913 llvm::Value *CLAddr = CGF.Builder.CreatePointerCast(LB, CGF.VoidPtrTy);
7914 llvm::Value *CHAddr = CGF.Builder.CreatePointerCast(HAddr, CGF.VoidPtrTy);
7915 llvm::Value *Diff = CGF.Builder.CreatePtrDiff(CHAddr, CLAddr);
Alexey Bataeva90fc662019-06-25 16:00:43 +00007916 llvm::Value *Size = CGF.Builder.CreateIntCast(Diff, CGF.Int64Ty,
Rui Ueyama49a3ad22019-07-16 04:46:31 +00007917 /*isSigned=*/false);
Alexey Bataevb3638132018-07-19 16:34:13 +00007918 Sizes.push_back(Size);
7919 // Map type is always TARGET_PARAM
7920 Types.push_back(OMP_MAP_TARGET_PARAM);
7921 // Remove TARGET_PARAM flag from the first element
7922 (*CurTypes.begin()) &= ~OMP_MAP_TARGET_PARAM;
7923
7924 // All other current entries will be MEMBER_OF the combined entry
7925 // (except for PTR_AND_OBJ entries which do not have a placeholder value
7926 // 0xFFFF in the MEMBER_OF field).
7927 OpenMPOffloadMappingFlags MemberOfFlag =
7928 getMemberOfFlag(BasePointers.size() - 1);
7929 for (auto &M : CurTypes)
7930 setCorrectMemberOfFlag(M, MemberOfFlag);
7931 }
7932
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007933 /// Generate all the base pointers, section pointers, sizes and map
Samuel Antaocc10b852016-07-28 14:23:26 +00007934 /// types for the extracted mappable expressions. Also, for each item that
7935 /// relates with a device pointer, a pair of the relevant declaration and
7936 /// index where it occurs is appended to the device pointers info array.
7937 void generateAllInfo(MapBaseValuesArrayTy &BasePointers,
Samuel Antao86ace552016-04-27 22:40:57 +00007938 MapValuesArrayTy &Pointers, MapValuesArrayTy &Sizes,
7939 MapFlagsArrayTy &Types) const {
Samuel Antao86ace552016-04-27 22:40:57 +00007940 // We have to process the component lists that relate with the same
7941 // declaration in a single chunk so that we can generate the map flags
7942 // correctly. Therefore, we organize all lists in a map.
Alexey Bataev5d1c3f62017-06-27 15:46:42 +00007943 llvm::MapVector<const ValueDecl *, SmallVector<MapInfo, 8>> Info;
Samuel Antao8d2d7302016-05-26 18:30:22 +00007944
7945 // Helper function to fill the information map for the different supported
7946 // clauses.
Samuel Antaocc10b852016-07-28 14:23:26 +00007947 auto &&InfoGen = [&Info](
7948 const ValueDecl *D,
7949 OMPClauseMappableExprCommon::MappableExprComponentListRef L,
Kelvin Lief579432018-12-18 22:18:41 +00007950 OpenMPMapClauseKind MapType,
7951 ArrayRef<OpenMPMapModifierKind> MapModifiers,
Alexey Bataevb3638132018-07-19 16:34:13 +00007952 bool ReturnDevicePointer, bool IsImplicit) {
Samuel Antaocc10b852016-07-28 14:23:26 +00007953 const ValueDecl *VD =
7954 D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
Kelvin Lief579432018-12-18 22:18:41 +00007955 Info[VD].emplace_back(L, MapType, MapModifiers, ReturnDevicePointer,
Alexey Bataevf47c4b42017-09-26 13:47:31 +00007956 IsImplicit);
Samuel Antaocc10b852016-07-28 14:23:26 +00007957 };
Samuel Antao8d2d7302016-05-26 18:30:22 +00007958
Michael Krused47b9432019-08-05 18:43:21 +00007959 assert(CurDir.is<const OMPExecutableDirective *>() &&
7960 "Expect a executable directive");
7961 const auto *CurExecDir = CurDir.get<const OMPExecutableDirective *>();
7962 for (const auto *C : CurExecDir->getClausesOfKind<OMPMapClause>())
Mark de Wever51abceb2019-11-12 20:48:11 +01007963 for (const auto L : C->component_lists()) {
Kelvin Lief579432018-12-18 22:18:41 +00007964 InfoGen(L.first, L.second, C->getMapType(), C->getMapTypeModifiers(),
Alexey Bataevb3638132018-07-19 16:34:13 +00007965 /*ReturnDevicePointer=*/false, C->isImplicit());
Alexey Bataevf47c4b42017-09-26 13:47:31 +00007966 }
Michael Krused47b9432019-08-05 18:43:21 +00007967 for (const auto *C : CurExecDir->getClausesOfKind<OMPToClause>())
Mark de Wever51abceb2019-11-12 20:48:11 +01007968 for (const auto L : C->component_lists()) {
Kelvin Lief579432018-12-18 22:18:41 +00007969 InfoGen(L.first, L.second, OMPC_MAP_to, llvm::None,
Alexey Bataevb3638132018-07-19 16:34:13 +00007970 /*ReturnDevicePointer=*/false, C->isImplicit());
Alexey Bataevf47c4b42017-09-26 13:47:31 +00007971 }
Michael Krused47b9432019-08-05 18:43:21 +00007972 for (const auto *C : CurExecDir->getClausesOfKind<OMPFromClause>())
Mark de Wever51abceb2019-11-12 20:48:11 +01007973 for (const auto L : C->component_lists()) {
Kelvin Lief579432018-12-18 22:18:41 +00007974 InfoGen(L.first, L.second, OMPC_MAP_from, llvm::None,
Alexey Bataevb3638132018-07-19 16:34:13 +00007975 /*ReturnDevicePointer=*/false, C->isImplicit());
Alexey Bataevf47c4b42017-09-26 13:47:31 +00007976 }
Samuel Antao86ace552016-04-27 22:40:57 +00007977
Samuel Antaocc10b852016-07-28 14:23:26 +00007978 // Look at the use_device_ptr clause information and mark the existing map
7979 // entries as such. If there is no map information for an entry in the
7980 // use_device_ptr list, we create one with map type 'alloc' and zero size
Alexey Bataevb3638132018-07-19 16:34:13 +00007981 // section. It is the user fault if that was not mapped before. If there is
7982 // no map information and the pointer is a struct member, then we defer the
7983 // emission of that entry until the whole struct has been processed.
7984 llvm::MapVector<const ValueDecl *, SmallVector<DeferredDevicePtrEntryTy, 4>>
7985 DeferredInfo;
7986
Alexey Bataevb3638132018-07-19 16:34:13 +00007987 for (const auto *C :
Michael Krused47b9432019-08-05 18:43:21 +00007988 CurExecDir->getClausesOfKind<OMPUseDevicePtrClause>()) {
Mark de Wever51abceb2019-11-12 20:48:11 +01007989 for (const auto L : C->component_lists()) {
Samuel Antaocc10b852016-07-28 14:23:26 +00007990 assert(!L.second.empty() && "Not expecting empty list of components!");
7991 const ValueDecl *VD = L.second.back().getAssociatedDeclaration();
7992 VD = cast<ValueDecl>(VD->getCanonicalDecl());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007993 const Expr *IE = L.second.back().getAssociatedExpression();
Samuel Antaocc10b852016-07-28 14:23:26 +00007994 // If the first component is a member expression, we have to look into
7995 // 'this', which maps to null in the map of map information. Otherwise
7996 // look directly for the information.
7997 auto It = Info.find(isa<MemberExpr>(IE) ? nullptr : VD);
7998
7999 // We potentially have map information for this declaration already.
8000 // Look for the first set of components that refer to it.
8001 if (It != Info.end()) {
8002 auto CI = std::find_if(
8003 It->second.begin(), It->second.end(), [VD](const MapInfo &MI) {
8004 return MI.Components.back().getAssociatedDeclaration() == VD;
8005 });
8006 // If we found a map entry, signal that the pointer has to be returned
8007 // and move on to the next declaration.
8008 if (CI != It->second.end()) {
Alexey Bataevb3638132018-07-19 16:34:13 +00008009 CI->ReturnDevicePointer = true;
Samuel Antaocc10b852016-07-28 14:23:26 +00008010 continue;
8011 }
8012 }
8013
8014 // We didn't find any match in our map information - generate a zero
Alexey Bataevb3638132018-07-19 16:34:13 +00008015 // size array section - if the pointer is a struct member we defer this
8016 // action until the whole struct has been processed.
Alexey Bataevb3638132018-07-19 16:34:13 +00008017 if (isa<MemberExpr>(IE)) {
8018 // Insert the pointer into Info to be processed by
8019 // generateInfoForComponentList. Because it is a member pointer
8020 // without a pointee, no entry will be generated for it, therefore
8021 // we need to generate one after the whole struct has been processed.
8022 // Nonetheless, generateInfoForComponentList must be called to take
8023 // the pointer into account for the calculation of the range of the
8024 // partial struct.
Kelvin Lief579432018-12-18 22:18:41 +00008025 InfoGen(nullptr, L.second, OMPC_MAP_unknown, llvm::None,
Alexey Bataevb3638132018-07-19 16:34:13 +00008026 /*ReturnDevicePointer=*/false, C->isImplicit());
8027 DeferredInfo[nullptr].emplace_back(IE, VD);
8028 } else {
Michael Krused47b9432019-08-05 18:43:21 +00008029 llvm::Value *Ptr =
8030 CGF.EmitLoadOfScalar(CGF.EmitLValue(IE), IE->getExprLoc());
Alexey Bataevb3638132018-07-19 16:34:13 +00008031 BasePointers.emplace_back(Ptr, VD);
8032 Pointers.push_back(Ptr);
Michael Krused47b9432019-08-05 18:43:21 +00008033 Sizes.push_back(llvm::Constant::getNullValue(CGF.Int64Ty));
Alexey Bataevb3638132018-07-19 16:34:13 +00008034 Types.push_back(OMP_MAP_RETURN_PARAM | OMP_MAP_TARGET_PARAM);
8035 }
Samuel Antaocc10b852016-07-28 14:23:26 +00008036 }
Alexey Bataevb3638132018-07-19 16:34:13 +00008037 }
Samuel Antaocc10b852016-07-28 14:23:26 +00008038
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008039 for (const auto &M : Info) {
Samuel Antao86ace552016-04-27 22:40:57 +00008040 // We need to know when we generate information for the first component
8041 // associated with a capture, because the mapping flags depend on it.
8042 bool IsFirstComponentList = true;
Alexey Bataevb3638132018-07-19 16:34:13 +00008043
8044 // Temporary versions of arrays
8045 MapBaseValuesArrayTy CurBasePointers;
8046 MapValuesArrayTy CurPointers;
8047 MapValuesArrayTy CurSizes;
8048 MapFlagsArrayTy CurTypes;
8049 StructRangeInfoTy PartialStruct;
8050
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008051 for (const MapInfo &L : M.second) {
Samuel Antao86ace552016-04-27 22:40:57 +00008052 assert(!L.Components.empty() &&
8053 "Not expecting declaration with no component lists.");
Samuel Antaocc10b852016-07-28 14:23:26 +00008054
8055 // Remember the current base pointer index.
Alexey Bataevb3638132018-07-19 16:34:13 +00008056 unsigned CurrentBasePointersIdx = CurBasePointers.size();
Michael Krused47b9432019-08-05 18:43:21 +00008057 generateInfoForComponentList(L.MapType, L.MapModifiers, L.Components,
8058 CurBasePointers, CurPointers, CurSizes,
8059 CurTypes, PartialStruct,
8060 IsFirstComponentList, L.IsImplicit);
Samuel Antaocc10b852016-07-28 14:23:26 +00008061
8062 // If this entry relates with a device pointer, set the relevant
8063 // declaration and add the 'return pointer' flag.
Alexey Bataevb3638132018-07-19 16:34:13 +00008064 if (L.ReturnDevicePointer) {
8065 assert(CurBasePointers.size() > CurrentBasePointersIdx &&
Samuel Antaocc10b852016-07-28 14:23:26 +00008066 "Unexpected number of mapped base pointers.");
8067
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008068 const ValueDecl *RelevantVD =
8069 L.Components.back().getAssociatedDeclaration();
Samuel Antaocc10b852016-07-28 14:23:26 +00008070 assert(RelevantVD &&
8071 "No relevant declaration related with device pointer??");
8072
Alexey Bataevb3638132018-07-19 16:34:13 +00008073 CurBasePointers[CurrentBasePointersIdx].setDevicePtrDecl(RelevantVD);
8074 CurTypes[CurrentBasePointersIdx] |= OMP_MAP_RETURN_PARAM;
Samuel Antaocc10b852016-07-28 14:23:26 +00008075 }
Samuel Antao86ace552016-04-27 22:40:57 +00008076 IsFirstComponentList = false;
8077 }
Alexey Bataevb3638132018-07-19 16:34:13 +00008078
8079 // Append any pending zero-length pointers which are struct members and
8080 // used with use_device_ptr.
8081 auto CI = DeferredInfo.find(M.first);
8082 if (CI != DeferredInfo.end()) {
8083 for (const DeferredDevicePtrEntryTy &L : CI->second) {
Akira Hatanakaf139ae32019-12-03 15:17:01 -08008084 llvm::Value *BasePtr = this->CGF.EmitLValue(L.IE).getPointer(CGF);
Alexey Bataevb3638132018-07-19 16:34:13 +00008085 llvm::Value *Ptr = this->CGF.EmitLoadOfScalar(
8086 this->CGF.EmitLValue(L.IE), L.IE->getExprLoc());
8087 CurBasePointers.emplace_back(BasePtr, L.VD);
8088 CurPointers.push_back(Ptr);
Alexey Bataeva90fc662019-06-25 16:00:43 +00008089 CurSizes.push_back(llvm::Constant::getNullValue(this->CGF.Int64Ty));
Alexey Bataevb3638132018-07-19 16:34:13 +00008090 // Entry is PTR_AND_OBJ and RETURN_PARAM. Also, set the placeholder
8091 // value MEMBER_OF=FFFF so that the entry is later updated with the
8092 // correct value of MEMBER_OF.
8093 CurTypes.push_back(OMP_MAP_PTR_AND_OBJ | OMP_MAP_RETURN_PARAM |
8094 OMP_MAP_MEMBER_OF);
8095 }
8096 }
8097
8098 // If there is an entry in PartialStruct it means we have a struct with
8099 // individual members mapped. Emit an extra combined entry.
8100 if (PartialStruct.Base.isValid())
8101 emitCombinedEntry(BasePointers, Pointers, Sizes, Types, CurTypes,
8102 PartialStruct);
8103
8104 // We need to append the results of this capture to what we already have.
8105 BasePointers.append(CurBasePointers.begin(), CurBasePointers.end());
8106 Pointers.append(CurPointers.begin(), CurPointers.end());
8107 Sizes.append(CurSizes.begin(), CurSizes.end());
8108 Types.append(CurTypes.begin(), CurTypes.end());
Samuel Antao86ace552016-04-27 22:40:57 +00008109 }
8110 }
8111
Michael Krused47b9432019-08-05 18:43:21 +00008112 /// Generate all the base pointers, section pointers, sizes and map types for
8113 /// the extracted map clauses of user-defined mapper.
8114 void generateAllInfoForMapper(MapBaseValuesArrayTy &BasePointers,
8115 MapValuesArrayTy &Pointers,
8116 MapValuesArrayTy &Sizes,
8117 MapFlagsArrayTy &Types) const {
8118 assert(CurDir.is<const OMPDeclareMapperDecl *>() &&
8119 "Expect a declare mapper directive");
8120 const auto *CurMapperDir = CurDir.get<const OMPDeclareMapperDecl *>();
8121 // We have to process the component lists that relate with the same
8122 // declaration in a single chunk so that we can generate the map flags
8123 // correctly. Therefore, we organize all lists in a map.
8124 llvm::MapVector<const ValueDecl *, SmallVector<MapInfo, 8>> Info;
8125
8126 // Helper function to fill the information map for the different supported
8127 // clauses.
8128 auto &&InfoGen = [&Info](
8129 const ValueDecl *D,
8130 OMPClauseMappableExprCommon::MappableExprComponentListRef L,
8131 OpenMPMapClauseKind MapType,
8132 ArrayRef<OpenMPMapModifierKind> MapModifiers,
8133 bool ReturnDevicePointer, bool IsImplicit) {
8134 const ValueDecl *VD =
8135 D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
8136 Info[VD].emplace_back(L, MapType, MapModifiers, ReturnDevicePointer,
8137 IsImplicit);
8138 };
8139
8140 for (const auto *C : CurMapperDir->clauselists()) {
8141 const auto *MC = cast<OMPMapClause>(C);
Mark de Wever51abceb2019-11-12 20:48:11 +01008142 for (const auto L : MC->component_lists()) {
Michael Krused47b9432019-08-05 18:43:21 +00008143 InfoGen(L.first, L.second, MC->getMapType(), MC->getMapTypeModifiers(),
8144 /*ReturnDevicePointer=*/false, MC->isImplicit());
8145 }
8146 }
8147
8148 for (const auto &M : Info) {
8149 // We need to know when we generate information for the first component
8150 // associated with a capture, because the mapping flags depend on it.
8151 bool IsFirstComponentList = true;
8152
8153 // Temporary versions of arrays
8154 MapBaseValuesArrayTy CurBasePointers;
8155 MapValuesArrayTy CurPointers;
8156 MapValuesArrayTy CurSizes;
8157 MapFlagsArrayTy CurTypes;
8158 StructRangeInfoTy PartialStruct;
8159
8160 for (const MapInfo &L : M.second) {
8161 assert(!L.Components.empty() &&
8162 "Not expecting declaration with no component lists.");
8163 generateInfoForComponentList(L.MapType, L.MapModifiers, L.Components,
8164 CurBasePointers, CurPointers, CurSizes,
8165 CurTypes, PartialStruct,
8166 IsFirstComponentList, L.IsImplicit);
8167 IsFirstComponentList = false;
8168 }
8169
8170 // If there is an entry in PartialStruct it means we have a struct with
8171 // individual members mapped. Emit an extra combined entry.
8172 if (PartialStruct.Base.isValid())
8173 emitCombinedEntry(BasePointers, Pointers, Sizes, Types, CurTypes,
8174 PartialStruct);
8175
8176 // We need to append the results of this capture to what we already have.
8177 BasePointers.append(CurBasePointers.begin(), CurBasePointers.end());
8178 Pointers.append(CurPointers.begin(), CurPointers.end());
8179 Sizes.append(CurSizes.begin(), CurSizes.end());
8180 Types.append(CurTypes.begin(), CurTypes.end());
8181 }
8182 }
8183
Alexey Bataev60705422018-10-30 15:50:12 +00008184 /// Emit capture info for lambdas for variables captured by reference.
Alexey Bataev969dbc02018-11-08 15:47:39 +00008185 void generateInfoForLambdaCaptures(
8186 const ValueDecl *VD, llvm::Value *Arg, MapBaseValuesArrayTy &BasePointers,
8187 MapValuesArrayTy &Pointers, MapValuesArrayTy &Sizes,
8188 MapFlagsArrayTy &Types,
8189 llvm::DenseMap<llvm::Value *, llvm::Value *> &LambdaPointers) const {
Alexey Bataev60705422018-10-30 15:50:12 +00008190 const auto *RD = VD->getType()
8191 .getCanonicalType()
8192 .getNonReferenceType()
8193 ->getAsCXXRecordDecl();
8194 if (!RD || !RD->isLambda())
8195 return;
8196 Address VDAddr = Address(Arg, CGF.getContext().getDeclAlign(VD));
8197 LValue VDLVal = CGF.MakeAddrLValue(
8198 VDAddr, VD->getType().getCanonicalType().getNonReferenceType());
8199 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
8200 FieldDecl *ThisCapture = nullptr;
8201 RD->getCaptureFields(Captures, ThisCapture);
8202 if (ThisCapture) {
8203 LValue ThisLVal =
8204 CGF.EmitLValueForFieldInitialization(VDLVal, ThisCapture);
Alexey Bataev969dbc02018-11-08 15:47:39 +00008205 LValue ThisLValVal = CGF.EmitLValueForField(VDLVal, ThisCapture);
Akira Hatanakaf139ae32019-12-03 15:17:01 -08008206 LambdaPointers.try_emplace(ThisLVal.getPointer(CGF),
8207 VDLVal.getPointer(CGF));
8208 BasePointers.push_back(ThisLVal.getPointer(CGF));
8209 Pointers.push_back(ThisLValVal.getPointer(CGF));
Alexey Bataeva90fc662019-06-25 16:00:43 +00008210 Sizes.push_back(
8211 CGF.Builder.CreateIntCast(CGF.getTypeSize(CGF.getContext().VoidPtrTy),
8212 CGF.Int64Ty, /*isSigned=*/true));
Alexey Bataev2dc07d02018-11-02 15:25:06 +00008213 Types.push_back(OMP_MAP_PTR_AND_OBJ | OMP_MAP_LITERAL |
Alexey Bataev60705422018-10-30 15:50:12 +00008214 OMP_MAP_MEMBER_OF | OMP_MAP_IMPLICIT);
8215 }
8216 for (const LambdaCapture &LC : RD->captures()) {
Alexey Bataevaf6725b2019-07-11 13:54:26 +00008217 if (!LC.capturesVariable())
Alexey Bataev60705422018-10-30 15:50:12 +00008218 continue;
8219 const VarDecl *VD = LC.getCapturedVar();
Alexey Bataevaf6725b2019-07-11 13:54:26 +00008220 if (LC.getCaptureKind() != LCK_ByRef && !VD->getType()->isPointerType())
8221 continue;
Alexey Bataev60705422018-10-30 15:50:12 +00008222 auto It = Captures.find(VD);
8223 assert(It != Captures.end() && "Found lambda capture without field.");
8224 LValue VarLVal = CGF.EmitLValueForFieldInitialization(VDLVal, It->second);
Alexey Bataevaf6725b2019-07-11 13:54:26 +00008225 if (LC.getCaptureKind() == LCK_ByRef) {
8226 LValue VarLValVal = CGF.EmitLValueForField(VDLVal, It->second);
Akira Hatanakaf139ae32019-12-03 15:17:01 -08008227 LambdaPointers.try_emplace(VarLVal.getPointer(CGF),
8228 VDLVal.getPointer(CGF));
8229 BasePointers.push_back(VarLVal.getPointer(CGF));
8230 Pointers.push_back(VarLValVal.getPointer(CGF));
Alexey Bataevaf6725b2019-07-11 13:54:26 +00008231 Sizes.push_back(CGF.Builder.CreateIntCast(
8232 CGF.getTypeSize(
8233 VD->getType().getCanonicalType().getNonReferenceType()),
8234 CGF.Int64Ty, /*isSigned=*/true));
8235 } else {
8236 RValue VarRVal = CGF.EmitLoadOfLValue(VarLVal, RD->getLocation());
Akira Hatanakaf139ae32019-12-03 15:17:01 -08008237 LambdaPointers.try_emplace(VarLVal.getPointer(CGF),
8238 VDLVal.getPointer(CGF));
8239 BasePointers.push_back(VarLVal.getPointer(CGF));
Alexey Bataevaf6725b2019-07-11 13:54:26 +00008240 Pointers.push_back(VarRVal.getScalarVal());
8241 Sizes.push_back(llvm::ConstantInt::get(CGF.Int64Ty, 0));
8242 }
Alexey Bataev2dc07d02018-11-02 15:25:06 +00008243 Types.push_back(OMP_MAP_PTR_AND_OBJ | OMP_MAP_LITERAL |
Alexey Bataev60705422018-10-30 15:50:12 +00008244 OMP_MAP_MEMBER_OF | OMP_MAP_IMPLICIT);
8245 }
8246 }
8247
8248 /// Set correct indices for lambdas captures.
Alexey Bataev969dbc02018-11-08 15:47:39 +00008249 void adjustMemberOfForLambdaCaptures(
8250 const llvm::DenseMap<llvm::Value *, llvm::Value *> &LambdaPointers,
8251 MapBaseValuesArrayTy &BasePointers, MapValuesArrayTy &Pointers,
8252 MapFlagsArrayTy &Types) const {
Alexey Bataev60705422018-10-30 15:50:12 +00008253 for (unsigned I = 0, E = Types.size(); I < E; ++I) {
8254 // Set correct member_of idx for all implicit lambda captures.
Alexey Bataev2dc07d02018-11-02 15:25:06 +00008255 if (Types[I] != (OMP_MAP_PTR_AND_OBJ | OMP_MAP_LITERAL |
Alexey Bataev60705422018-10-30 15:50:12 +00008256 OMP_MAP_MEMBER_OF | OMP_MAP_IMPLICIT))
8257 continue;
Alexey Bataev969dbc02018-11-08 15:47:39 +00008258 llvm::Value *BasePtr = LambdaPointers.lookup(*BasePointers[I]);
8259 assert(BasePtr && "Unable to find base lambda address.");
Alexey Bataev60705422018-10-30 15:50:12 +00008260 int TgtIdx = -1;
8261 for (unsigned J = I; J > 0; --J) {
8262 unsigned Idx = J - 1;
8263 if (Pointers[Idx] != BasePtr)
8264 continue;
8265 TgtIdx = Idx;
8266 break;
8267 }
8268 assert(TgtIdx != -1 && "Unable to find parent lambda.");
8269 // All other current entries will be MEMBER_OF the combined entry
8270 // (except for PTR_AND_OBJ entries which do not have a placeholder value
8271 // 0xFFFF in the MEMBER_OF field).
8272 OpenMPOffloadMappingFlags MemberOfFlag = getMemberOfFlag(TgtIdx);
8273 setCorrectMemberOfFlag(Types[I], MemberOfFlag);
8274 }
8275 }
8276
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008277 /// Generate the base pointers, section pointers, sizes and map types
Samuel Antao86ace552016-04-27 22:40:57 +00008278 /// associated to a given capture.
8279 void generateInfoForCapture(const CapturedStmt::Capture *Cap,
Samuel Antao6890b092016-07-28 14:25:09 +00008280 llvm::Value *Arg,
Samuel Antaocc10b852016-07-28 14:23:26 +00008281 MapBaseValuesArrayTy &BasePointers,
Samuel Antao86ace552016-04-27 22:40:57 +00008282 MapValuesArrayTy &Pointers,
Alexey Bataevb3638132018-07-19 16:34:13 +00008283 MapValuesArrayTy &Sizes, MapFlagsArrayTy &Types,
8284 StructRangeInfoTy &PartialStruct) const {
Samuel Antao86ace552016-04-27 22:40:57 +00008285 assert(!Cap->capturesVariableArrayType() &&
8286 "Not expecting to generate map info for a variable array type!");
8287
Samuel Antao6890b092016-07-28 14:25:09 +00008288 // We need to know when we generating information for the first component
Alexey Bataevb3638132018-07-19 16:34:13 +00008289 const ValueDecl *VD = Cap->capturesThis()
8290 ? nullptr
8291 : Cap->getCapturedVar()->getCanonicalDecl();
Samuel Antao86ace552016-04-27 22:40:57 +00008292
Samuel Antao6890b092016-07-28 14:25:09 +00008293 // If this declaration appears in a is_device_ptr clause we just have to
8294 // pass the pointer by value. If it is a reference to a declaration, we just
Alexey Bataevb3638132018-07-19 16:34:13 +00008295 // pass its value.
8296 if (DevPointersMap.count(VD)) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008297 BasePointers.emplace_back(Arg, VD);
Samuel Antao6890b092016-07-28 14:25:09 +00008298 Pointers.push_back(Arg);
Alexey Bataeva90fc662019-06-25 16:00:43 +00008299 Sizes.push_back(
8300 CGF.Builder.CreateIntCast(CGF.getTypeSize(CGF.getContext().VoidPtrTy),
8301 CGF.Int64Ty, /*isSigned=*/true));
George Rokos065755d2017-11-07 18:27:04 +00008302 Types.push_back(OMP_MAP_LITERAL | OMP_MAP_TARGET_PARAM);
Samuel Antao6890b092016-07-28 14:25:09 +00008303 return;
8304 }
8305
Alexey Bataeve82445f2018-09-20 13:54:02 +00008306 using MapData =
8307 std::tuple<OMPClauseMappableExprCommon::MappableExprComponentListRef,
Kelvin Lief579432018-12-18 22:18:41 +00008308 OpenMPMapClauseKind, ArrayRef<OpenMPMapModifierKind>, bool>;
Alexey Bataeve82445f2018-09-20 13:54:02 +00008309 SmallVector<MapData, 4> DeclComponentLists;
Michael Krused47b9432019-08-05 18:43:21 +00008310 assert(CurDir.is<const OMPExecutableDirective *>() &&
8311 "Expect a executable directive");
8312 const auto *CurExecDir = CurDir.get<const OMPExecutableDirective *>();
8313 for (const auto *C : CurExecDir->getClausesOfKind<OMPMapClause>()) {
Mark de Wever51abceb2019-11-12 20:48:11 +01008314 for (const auto L : C->decl_component_lists(VD)) {
Samuel Antao86ace552016-04-27 22:40:57 +00008315 assert(L.first == VD &&
8316 "We got information for the wrong declaration??");
8317 assert(!L.second.empty() &&
8318 "Not expecting declaration with no component lists.");
Alexey Bataeve82445f2018-09-20 13:54:02 +00008319 DeclComponentLists.emplace_back(L.second, C->getMapType(),
Kelvin Lief579432018-12-18 22:18:41 +00008320 C->getMapTypeModifiers(),
Alexey Bataeve82445f2018-09-20 13:54:02 +00008321 C->isImplicit());
Samuel Antao86ace552016-04-27 22:40:57 +00008322 }
Alexey Bataeve82445f2018-09-20 13:54:02 +00008323 }
8324
8325 // Find overlapping elements (including the offset from the base element).
8326 llvm::SmallDenseMap<
8327 const MapData *,
8328 llvm::SmallVector<
8329 OMPClauseMappableExprCommon::MappableExprComponentListRef, 4>,
8330 4>
8331 OverlappedData;
8332 size_t Count = 0;
8333 for (const MapData &L : DeclComponentLists) {
8334 OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
8335 OpenMPMapClauseKind MapType;
Kelvin Lief579432018-12-18 22:18:41 +00008336 ArrayRef<OpenMPMapModifierKind> MapModifiers;
Alexey Bataeve82445f2018-09-20 13:54:02 +00008337 bool IsImplicit;
Kelvin Lief579432018-12-18 22:18:41 +00008338 std::tie(Components, MapType, MapModifiers, IsImplicit) = L;
Alexey Bataeve82445f2018-09-20 13:54:02 +00008339 ++Count;
8340 for (const MapData &L1 : makeArrayRef(DeclComponentLists).slice(Count)) {
8341 OMPClauseMappableExprCommon::MappableExprComponentListRef Components1;
Kelvin Lief579432018-12-18 22:18:41 +00008342 std::tie(Components1, MapType, MapModifiers, IsImplicit) = L1;
Alexey Bataeve82445f2018-09-20 13:54:02 +00008343 auto CI = Components.rbegin();
8344 auto CE = Components.rend();
8345 auto SI = Components1.rbegin();
8346 auto SE = Components1.rend();
8347 for (; CI != CE && SI != SE; ++CI, ++SI) {
8348 if (CI->getAssociatedExpression()->getStmtClass() !=
8349 SI->getAssociatedExpression()->getStmtClass())
8350 break;
8351 // Are we dealing with different variables/fields?
8352 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
8353 break;
8354 }
8355 // Found overlapping if, at least for one component, reached the head of
8356 // the components list.
8357 if (CI == CE || SI == SE) {
8358 assert((CI != CE || SI != SE) &&
8359 "Unexpected full match of the mapping components.");
8360 const MapData &BaseData = CI == CE ? L : L1;
8361 OMPClauseMappableExprCommon::MappableExprComponentListRef SubData =
8362 SI == SE ? Components : Components1;
Alexey Bataeve82445f2018-09-20 13:54:02 +00008363 auto &OverlappedElements = OverlappedData.FindAndConstruct(&BaseData);
8364 OverlappedElements.getSecond().push_back(SubData);
8365 }
8366 }
8367 }
8368 // Sort the overlapped elements for each item.
8369 llvm::SmallVector<const FieldDecl *, 4> Layout;
8370 if (!OverlappedData.empty()) {
8371 if (const auto *CRD =
8372 VD->getType().getCanonicalType()->getAsCXXRecordDecl())
8373 getPlainLayout(CRD, Layout, /*AsBase=*/false);
8374 else {
8375 const auto *RD = VD->getType().getCanonicalType()->getAsRecordDecl();
8376 Layout.append(RD->field_begin(), RD->field_end());
8377 }
8378 }
8379 for (auto &Pair : OverlappedData) {
8380 llvm::sort(
8381 Pair.getSecond(),
8382 [&Layout](
8383 OMPClauseMappableExprCommon::MappableExprComponentListRef First,
8384 OMPClauseMappableExprCommon::MappableExprComponentListRef
8385 Second) {
8386 auto CI = First.rbegin();
8387 auto CE = First.rend();
8388 auto SI = Second.rbegin();
8389 auto SE = Second.rend();
8390 for (; CI != CE && SI != SE; ++CI, ++SI) {
8391 if (CI->getAssociatedExpression()->getStmtClass() !=
8392 SI->getAssociatedExpression()->getStmtClass())
8393 break;
8394 // Are we dealing with different variables/fields?
8395 if (CI->getAssociatedDeclaration() !=
8396 SI->getAssociatedDeclaration())
8397 break;
8398 }
Richard Trieu5061e832018-09-21 21:20:33 +00008399
8400 // Lists contain the same elements.
8401 if (CI == CE && SI == SE)
8402 return false;
8403
8404 // List with less elements is less than list with more elements.
8405 if (CI == CE || SI == SE)
8406 return CI == CE;
8407
Alexey Bataeve82445f2018-09-20 13:54:02 +00008408 const auto *FD1 = cast<FieldDecl>(CI->getAssociatedDeclaration());
8409 const auto *FD2 = cast<FieldDecl>(SI->getAssociatedDeclaration());
8410 if (FD1->getParent() == FD2->getParent())
8411 return FD1->getFieldIndex() < FD2->getFieldIndex();
8412 const auto It =
8413 llvm::find_if(Layout, [FD1, FD2](const FieldDecl *FD) {
8414 return FD == FD1 || FD == FD2;
8415 });
8416 return *It == FD1;
8417 });
8418 }
8419
8420 // Associated with a capture, because the mapping flags depend on it.
8421 // Go through all of the elements with the overlapped elements.
8422 for (const auto &Pair : OverlappedData) {
8423 const MapData &L = *Pair.getFirst();
8424 OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
8425 OpenMPMapClauseKind MapType;
Kelvin Lief579432018-12-18 22:18:41 +00008426 ArrayRef<OpenMPMapModifierKind> MapModifiers;
Alexey Bataeve82445f2018-09-20 13:54:02 +00008427 bool IsImplicit;
Kelvin Lief579432018-12-18 22:18:41 +00008428 std::tie(Components, MapType, MapModifiers, IsImplicit) = L;
Alexey Bataeve82445f2018-09-20 13:54:02 +00008429 ArrayRef<OMPClauseMappableExprCommon::MappableExprComponentListRef>
8430 OverlappedComponents = Pair.getSecond();
8431 bool IsFirstComponentList = true;
Kelvin Lief579432018-12-18 22:18:41 +00008432 generateInfoForComponentList(MapType, MapModifiers, Components,
Alexey Bataeve82445f2018-09-20 13:54:02 +00008433 BasePointers, Pointers, Sizes, Types,
8434 PartialStruct, IsFirstComponentList,
8435 IsImplicit, OverlappedComponents);
8436 }
8437 // Go through other elements without overlapped elements.
8438 bool IsFirstComponentList = OverlappedData.empty();
8439 for (const MapData &L : DeclComponentLists) {
8440 OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
8441 OpenMPMapClauseKind MapType;
Kelvin Lief579432018-12-18 22:18:41 +00008442 ArrayRef<OpenMPMapModifierKind> MapModifiers;
Alexey Bataeve82445f2018-09-20 13:54:02 +00008443 bool IsImplicit;
Kelvin Lief579432018-12-18 22:18:41 +00008444 std::tie(Components, MapType, MapModifiers, IsImplicit) = L;
Alexey Bataeve82445f2018-09-20 13:54:02 +00008445 auto It = OverlappedData.find(&L);
8446 if (It == OverlappedData.end())
Kelvin Lief579432018-12-18 22:18:41 +00008447 generateInfoForComponentList(MapType, MapModifiers, Components,
Alexey Bataeve82445f2018-09-20 13:54:02 +00008448 BasePointers, Pointers, Sizes, Types,
8449 PartialStruct, IsFirstComponentList,
8450 IsImplicit);
8451 IsFirstComponentList = false;
8452 }
Alexey Bataevb3638132018-07-19 16:34:13 +00008453 }
Samuel Antao86ace552016-04-27 22:40:57 +00008454
Alexey Bataevb3638132018-07-19 16:34:13 +00008455 /// Generate the base pointers, section pointers, sizes and map types
8456 /// associated with the declare target link variables.
8457 void generateInfoForDeclareTargetLink(MapBaseValuesArrayTy &BasePointers,
8458 MapValuesArrayTy &Pointers,
8459 MapValuesArrayTy &Sizes,
8460 MapFlagsArrayTy &Types) const {
Michael Krused47b9432019-08-05 18:43:21 +00008461 assert(CurDir.is<const OMPExecutableDirective *>() &&
8462 "Expect a executable directive");
8463 const auto *CurExecDir = CurDir.get<const OMPExecutableDirective *>();
Alexey Bataevb3638132018-07-19 16:34:13 +00008464 // Map other list items in the map clause which are not captured variables
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +00008465 // but "declare target link" global variables.
Michael Krused47b9432019-08-05 18:43:21 +00008466 for (const auto *C : CurExecDir->getClausesOfKind<OMPMapClause>()) {
Mark de Wever51abceb2019-11-12 20:48:11 +01008467 for (const auto L : C->component_lists()) {
Alexey Bataevb3638132018-07-19 16:34:13 +00008468 if (!L.first)
8469 continue;
8470 const auto *VD = dyn_cast<VarDecl>(L.first);
8471 if (!VD)
8472 continue;
8473 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
Alexey Bataev97b72212018-08-14 18:31:20 +00008474 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
Gheorghe-Teodor Bercea5254f0a2019-06-14 17:58:26 +00008475 if (CGF.CGM.getOpenMPRuntime().hasRequiresUnifiedSharedMemory() ||
8476 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)
Alexey Bataevb3638132018-07-19 16:34:13 +00008477 continue;
8478 StructRangeInfoTy PartialStruct;
8479 generateInfoForComponentList(
Kelvin Lief579432018-12-18 22:18:41 +00008480 C->getMapType(), C->getMapTypeModifiers(), L.second, BasePointers,
Alexey Bataevb3638132018-07-19 16:34:13 +00008481 Pointers, Sizes, Types, PartialStruct,
8482 /*IsFirstComponentList=*/true, C->isImplicit());
8483 assert(!PartialStruct.Base.isValid() &&
8484 "No partial structs for declare target link expected.");
8485 }
8486 }
Samuel Antao86ace552016-04-27 22:40:57 +00008487 }
Samuel Antaod486f842016-05-26 16:53:38 +00008488
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008489 /// Generate the default map information for a given capture \a CI,
Samuel Antaod486f842016-05-26 16:53:38 +00008490 /// record field declaration \a RI and captured value \a CV.
Samuel Antaocc10b852016-07-28 14:23:26 +00008491 void generateDefaultMapInfo(const CapturedStmt::Capture &CI,
8492 const FieldDecl &RI, llvm::Value *CV,
8493 MapBaseValuesArrayTy &CurBasePointers,
8494 MapValuesArrayTy &CurPointers,
8495 MapValuesArrayTy &CurSizes,
Alexey Bataevb3638132018-07-19 16:34:13 +00008496 MapFlagsArrayTy &CurMapTypes) const {
Alexey Bataevf288cf92019-06-27 18:53:07 +00008497 bool IsImplicit = true;
Samuel Antaod486f842016-05-26 16:53:38 +00008498 // Do the default mapping.
8499 if (CI.capturesThis()) {
8500 CurBasePointers.push_back(CV);
8501 CurPointers.push_back(CV);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008502 const auto *PtrTy = cast<PointerType>(RI.getType().getTypePtr());
Alexey Bataeva90fc662019-06-25 16:00:43 +00008503 CurSizes.push_back(
8504 CGF.Builder.CreateIntCast(CGF.getTypeSize(PtrTy->getPointeeType()),
8505 CGF.Int64Ty, /*isSigned=*/true));
Samuel Antaod486f842016-05-26 16:53:38 +00008506 // Default map type.
Samuel Antaocc10b852016-07-28 14:23:26 +00008507 CurMapTypes.push_back(OMP_MAP_TO | OMP_MAP_FROM);
Samuel Antaod486f842016-05-26 16:53:38 +00008508 } else if (CI.capturesVariableByCopy()) {
Samuel Antao6d004262016-06-16 18:39:34 +00008509 CurBasePointers.push_back(CV);
8510 CurPointers.push_back(CV);
Samuel Antaod486f842016-05-26 16:53:38 +00008511 if (!RI.getType()->isAnyPointerType()) {
Samuel Antao6d004262016-06-16 18:39:34 +00008512 // We have to signal to the runtime captures passed by value that are
8513 // not pointers.
George Rokos065755d2017-11-07 18:27:04 +00008514 CurMapTypes.push_back(OMP_MAP_LITERAL);
Alexey Bataeva90fc662019-06-25 16:00:43 +00008515 CurSizes.push_back(CGF.Builder.CreateIntCast(
8516 CGF.getTypeSize(RI.getType()), CGF.Int64Ty, /*isSigned=*/true));
Samuel Antaod486f842016-05-26 16:53:38 +00008517 } else {
8518 // Pointers are implicitly mapped with a zero size and no flags
8519 // (other than first map that is added for all implicit maps).
Alexey Bataevb3638132018-07-19 16:34:13 +00008520 CurMapTypes.push_back(OMP_MAP_NONE);
Alexey Bataeva90fc662019-06-25 16:00:43 +00008521 CurSizes.push_back(llvm::Constant::getNullValue(CGF.Int64Ty));
Samuel Antaod486f842016-05-26 16:53:38 +00008522 }
Alexey Bataevf288cf92019-06-27 18:53:07 +00008523 const VarDecl *VD = CI.getCapturedVar();
8524 auto I = FirstPrivateDecls.find(VD);
8525 if (I != FirstPrivateDecls.end())
8526 IsImplicit = I->getSecond();
Samuel Antaod486f842016-05-26 16:53:38 +00008527 } else {
8528 assert(CI.capturesVariable() && "Expected captured reference.");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008529 const auto *PtrTy = cast<ReferenceType>(RI.getType().getTypePtr());
Samuel Antaod486f842016-05-26 16:53:38 +00008530 QualType ElementType = PtrTy->getPointeeType();
Alexey Bataeva90fc662019-06-25 16:00:43 +00008531 CurSizes.push_back(CGF.Builder.CreateIntCast(
8532 CGF.getTypeSize(ElementType), CGF.Int64Ty, /*isSigned=*/true));
Samuel Antaod486f842016-05-26 16:53:38 +00008533 // The default map type for a scalar/complex type is 'to' because by
8534 // default the value doesn't have to be retrieved. For an aggregate
8535 // type, the default is 'tofrom'.
Alexey Bataevb3638132018-07-19 16:34:13 +00008536 CurMapTypes.push_back(getMapModifiersForPrivateClauses(CI));
Alexey Bataev1af5bd52019-03-05 17:47:18 +00008537 const VarDecl *VD = CI.getCapturedVar();
Alexey Bataevf288cf92019-06-27 18:53:07 +00008538 auto I = FirstPrivateDecls.find(VD);
8539 if (I != FirstPrivateDecls.end() &&
Alexey Bataev1af5bd52019-03-05 17:47:18 +00008540 VD->getType().isConstant(CGF.getContext())) {
8541 llvm::Constant *Addr =
8542 CGF.CGM.getOpenMPRuntime().registerTargetFirstprivateCopy(CGF, VD);
8543 // Copy the value of the original variable to the new global copy.
8544 CGF.Builder.CreateMemCpy(
Akira Hatanakaf139ae32019-12-03 15:17:01 -08008545 CGF.MakeNaturalAlignAddrLValue(Addr, ElementType).getAddress(CGF),
Alexey Bataev1af5bd52019-03-05 17:47:18 +00008546 Address(CV, CGF.getContext().getTypeAlignInChars(ElementType)),
Rui Ueyama49a3ad22019-07-16 04:46:31 +00008547 CurSizes.back(), /*IsVolatile=*/false);
Alexey Bataev1af5bd52019-03-05 17:47:18 +00008548 // Use new global variable as the base pointers.
8549 CurBasePointers.push_back(Addr);
8550 CurPointers.push_back(Addr);
8551 } else {
8552 CurBasePointers.push_back(CV);
Alexey Bataevf288cf92019-06-27 18:53:07 +00008553 if (I != FirstPrivateDecls.end() && ElementType->isAnyPointerType()) {
Alexey Bataevc2b831f2019-04-02 16:03:40 +00008554 Address PtrAddr = CGF.EmitLoadOfReference(CGF.MakeAddrLValue(
8555 CV, ElementType, CGF.getContext().getDeclAlign(VD),
8556 AlignmentSource::Decl));
8557 CurPointers.push_back(PtrAddr.getPointer());
8558 } else {
8559 CurPointers.push_back(CV);
8560 }
Alexey Bataev1af5bd52019-03-05 17:47:18 +00008561 }
Alexey Bataevf288cf92019-06-27 18:53:07 +00008562 if (I != FirstPrivateDecls.end())
8563 IsImplicit = I->getSecond();
Samuel Antaod486f842016-05-26 16:53:38 +00008564 }
George Rokos065755d2017-11-07 18:27:04 +00008565 // Every default map produces a single argument which is a target parameter.
8566 CurMapTypes.back() |= OMP_MAP_TARGET_PARAM;
Alexey Bataevb3638132018-07-19 16:34:13 +00008567
8568 // Add flag stating this is an implicit map.
Alexey Bataevf288cf92019-06-27 18:53:07 +00008569 if (IsImplicit)
8570 CurMapTypes.back() |= OMP_MAP_IMPLICIT;
Samuel Antaod486f842016-05-26 16:53:38 +00008571 }
Samuel Antao86ace552016-04-27 22:40:57 +00008572};
Samuel Antaodf158d52016-04-27 22:58:19 +00008573} // anonymous namespace
8574
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008575/// Emit the arrays used to pass the captures and map information to the
Samuel Antaodf158d52016-04-27 22:58:19 +00008576/// offloading runtime library. If there is no map or capture information,
8577/// return nullptr by reference.
8578static void
Samuel Antaocc10b852016-07-28 14:23:26 +00008579emitOffloadingArrays(CodeGenFunction &CGF,
8580 MappableExprsHandler::MapBaseValuesArrayTy &BasePointers,
Samuel Antaodf158d52016-04-27 22:58:19 +00008581 MappableExprsHandler::MapValuesArrayTy &Pointers,
8582 MappableExprsHandler::MapValuesArrayTy &Sizes,
Samuel Antaocc10b852016-07-28 14:23:26 +00008583 MappableExprsHandler::MapFlagsArrayTy &MapTypes,
8584 CGOpenMPRuntime::TargetDataInfo &Info) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008585 CodeGenModule &CGM = CGF.CGM;
8586 ASTContext &Ctx = CGF.getContext();
Samuel Antaodf158d52016-04-27 22:58:19 +00008587
Samuel Antaocc10b852016-07-28 14:23:26 +00008588 // Reset the array information.
8589 Info.clearArrayInfo();
8590 Info.NumberOfPtrs = BasePointers.size();
Samuel Antaodf158d52016-04-27 22:58:19 +00008591
Samuel Antaocc10b852016-07-28 14:23:26 +00008592 if (Info.NumberOfPtrs) {
Samuel Antaodf158d52016-04-27 22:58:19 +00008593 // Detect if we have any capture size requiring runtime evaluation of the
8594 // size so that a constant array could be eventually used.
8595 bool hasRuntimeEvaluationCaptureSize = false;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008596 for (llvm::Value *S : Sizes)
Samuel Antaodf158d52016-04-27 22:58:19 +00008597 if (!isa<llvm::Constant>(S)) {
8598 hasRuntimeEvaluationCaptureSize = true;
8599 break;
8600 }
8601
Samuel Antaocc10b852016-07-28 14:23:26 +00008602 llvm::APInt PointerNumAP(32, Info.NumberOfPtrs, /*isSigned=*/true);
Richard Smith772e2662019-10-04 01:25:59 +00008603 QualType PointerArrayType = Ctx.getConstantArrayType(
8604 Ctx.VoidPtrTy, PointerNumAP, nullptr, ArrayType::Normal,
8605 /*IndexTypeQuals=*/0);
Samuel Antaodf158d52016-04-27 22:58:19 +00008606
Samuel Antaocc10b852016-07-28 14:23:26 +00008607 Info.BasePointersArray =
Samuel Antaodf158d52016-04-27 22:58:19 +00008608 CGF.CreateMemTemp(PointerArrayType, ".offload_baseptrs").getPointer();
Samuel Antaocc10b852016-07-28 14:23:26 +00008609 Info.PointersArray =
Samuel Antaodf158d52016-04-27 22:58:19 +00008610 CGF.CreateMemTemp(PointerArrayType, ".offload_ptrs").getPointer();
8611
8612 // If we don't have any VLA types or other types that require runtime
8613 // evaluation, we can use a constant array for the map sizes, otherwise we
8614 // need to fill up the arrays as we do for the pointers.
Alexey Bataeva90fc662019-06-25 16:00:43 +00008615 QualType Int64Ty =
8616 Ctx.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
Samuel Antaodf158d52016-04-27 22:58:19 +00008617 if (hasRuntimeEvaluationCaptureSize) {
Richard Smith772e2662019-10-04 01:25:59 +00008618 QualType SizeArrayType = Ctx.getConstantArrayType(
8619 Int64Ty, PointerNumAP, nullptr, ArrayType::Normal,
8620 /*IndexTypeQuals=*/0);
Samuel Antaocc10b852016-07-28 14:23:26 +00008621 Info.SizesArray =
Samuel Antaodf158d52016-04-27 22:58:19 +00008622 CGF.CreateMemTemp(SizeArrayType, ".offload_sizes").getPointer();
8623 } else {
8624 // We expect all the sizes to be constant, so we collect them to create
8625 // a constant array.
8626 SmallVector<llvm::Constant *, 16> ConstSizes;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008627 for (llvm::Value *S : Sizes)
Samuel Antaodf158d52016-04-27 22:58:19 +00008628 ConstSizes.push_back(cast<llvm::Constant>(S));
8629
8630 auto *SizesArrayInit = llvm::ConstantArray::get(
Alexey Bataeva90fc662019-06-25 16:00:43 +00008631 llvm::ArrayType::get(CGM.Int64Ty, ConstSizes.size()), ConstSizes);
Alexey Bataev18fa2322018-05-02 14:20:50 +00008632 std::string Name = CGM.getOpenMPRuntime().getName({"offload_sizes"});
Samuel Antaodf158d52016-04-27 22:58:19 +00008633 auto *SizesArrayGbl = new llvm::GlobalVariable(
8634 CGM.getModule(), SizesArrayInit->getType(),
8635 /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage,
Alexey Bataev18fa2322018-05-02 14:20:50 +00008636 SizesArrayInit, Name);
Peter Collingbournebcf909d2016-06-14 21:02:05 +00008637 SizesArrayGbl->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
Samuel Antaocc10b852016-07-28 14:23:26 +00008638 Info.SizesArray = SizesArrayGbl;
Samuel Antaodf158d52016-04-27 22:58:19 +00008639 }
8640
8641 // The map types are always constant so we don't need to generate code to
8642 // fill arrays. Instead, we create an array constant.
Alexey Bataevb3638132018-07-19 16:34:13 +00008643 SmallVector<uint64_t, 4> Mapping(MapTypes.size(), 0);
8644 llvm::copy(MapTypes, Mapping.begin());
Samuel Antaodf158d52016-04-27 22:58:19 +00008645 llvm::Constant *MapTypesArrayInit =
Alexey Bataevb3638132018-07-19 16:34:13 +00008646 llvm::ConstantDataArray::get(CGF.Builder.getContext(), Mapping);
Alexey Bataev18fa2322018-05-02 14:20:50 +00008647 std::string MaptypesName =
8648 CGM.getOpenMPRuntime().getName({"offload_maptypes"});
Samuel Antaodf158d52016-04-27 22:58:19 +00008649 auto *MapTypesArrayGbl = new llvm::GlobalVariable(
8650 CGM.getModule(), MapTypesArrayInit->getType(),
8651 /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage,
Alexey Bataev18fa2322018-05-02 14:20:50 +00008652 MapTypesArrayInit, MaptypesName);
Peter Collingbournebcf909d2016-06-14 21:02:05 +00008653 MapTypesArrayGbl->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
Samuel Antaocc10b852016-07-28 14:23:26 +00008654 Info.MapTypesArray = MapTypesArrayGbl;
Samuel Antaodf158d52016-04-27 22:58:19 +00008655
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008656 for (unsigned I = 0; I < Info.NumberOfPtrs; ++I) {
8657 llvm::Value *BPVal = *BasePointers[I];
Samuel Antaodf158d52016-04-27 22:58:19 +00008658 llvm::Value *BP = CGF.Builder.CreateConstInBoundsGEP2_32(
Samuel Antaocc10b852016-07-28 14:23:26 +00008659 llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008660 Info.BasePointersArray, 0, I);
Alexey Bataev1fdfdf72017-06-29 16:43:05 +00008661 BP = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
8662 BP, BPVal->getType()->getPointerTo(/*AddrSpace=*/0));
Samuel Antaodf158d52016-04-27 22:58:19 +00008663 Address BPAddr(BP, Ctx.getTypeAlignInChars(Ctx.VoidPtrTy));
8664 CGF.Builder.CreateStore(BPVal, BPAddr);
8665
Samuel Antaocc10b852016-07-28 14:23:26 +00008666 if (Info.requiresDevicePointerInfo())
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008667 if (const ValueDecl *DevVD = BasePointers[I].getDevicePtrDecl())
Alexey Bataev43a919f2018-04-13 17:48:43 +00008668 Info.CaptureDeviceAddrMap.try_emplace(DevVD, BPAddr);
Samuel Antaocc10b852016-07-28 14:23:26 +00008669
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008670 llvm::Value *PVal = Pointers[I];
Samuel Antaodf158d52016-04-27 22:58:19 +00008671 llvm::Value *P = CGF.Builder.CreateConstInBoundsGEP2_32(
Samuel Antaocc10b852016-07-28 14:23:26 +00008672 llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008673 Info.PointersArray, 0, I);
Alexey Bataev1fdfdf72017-06-29 16:43:05 +00008674 P = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
8675 P, PVal->getType()->getPointerTo(/*AddrSpace=*/0));
Samuel Antaodf158d52016-04-27 22:58:19 +00008676 Address PAddr(P, Ctx.getTypeAlignInChars(Ctx.VoidPtrTy));
8677 CGF.Builder.CreateStore(PVal, PAddr);
8678
8679 if (hasRuntimeEvaluationCaptureSize) {
8680 llvm::Value *S = CGF.Builder.CreateConstInBoundsGEP2_32(
Alexey Bataeva90fc662019-06-25 16:00:43 +00008681 llvm::ArrayType::get(CGM.Int64Ty, Info.NumberOfPtrs),
Samuel Antaocc10b852016-07-28 14:23:26 +00008682 Info.SizesArray,
Samuel Antaodf158d52016-04-27 22:58:19 +00008683 /*Idx0=*/0,
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008684 /*Idx1=*/I);
Alexey Bataeva90fc662019-06-25 16:00:43 +00008685 Address SAddr(S, Ctx.getTypeAlignInChars(Int64Ty));
Samuel Antaodf158d52016-04-27 22:58:19 +00008686 CGF.Builder.CreateStore(
Alexey Bataeva90fc662019-06-25 16:00:43 +00008687 CGF.Builder.CreateIntCast(Sizes[I], CGM.Int64Ty, /*isSigned=*/true),
Samuel Antaodf158d52016-04-27 22:58:19 +00008688 SAddr);
8689 }
8690 }
8691 }
8692}
Michael Krused47b9432019-08-05 18:43:21 +00008693
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008694/// Emit the arguments to be passed to the runtime library based on the
Samuel Antaodf158d52016-04-27 22:58:19 +00008695/// arrays of pointers, sizes and map types.
8696static void emitOffloadingArraysArgument(
8697 CodeGenFunction &CGF, llvm::Value *&BasePointersArrayArg,
8698 llvm::Value *&PointersArrayArg, llvm::Value *&SizesArrayArg,
Samuel Antaocc10b852016-07-28 14:23:26 +00008699 llvm::Value *&MapTypesArrayArg, CGOpenMPRuntime::TargetDataInfo &Info) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008700 CodeGenModule &CGM = CGF.CGM;
Samuel Antaocc10b852016-07-28 14:23:26 +00008701 if (Info.NumberOfPtrs) {
Samuel Antaodf158d52016-04-27 22:58:19 +00008702 BasePointersArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(
Samuel Antaocc10b852016-07-28 14:23:26 +00008703 llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),
8704 Info.BasePointersArray,
Samuel Antaodf158d52016-04-27 22:58:19 +00008705 /*Idx0=*/0, /*Idx1=*/0);
8706 PointersArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(
Samuel Antaocc10b852016-07-28 14:23:26 +00008707 llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),
8708 Info.PointersArray,
Samuel Antaodf158d52016-04-27 22:58:19 +00008709 /*Idx0=*/0,
8710 /*Idx1=*/0);
8711 SizesArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(
Alexey Bataeva90fc662019-06-25 16:00:43 +00008712 llvm::ArrayType::get(CGM.Int64Ty, Info.NumberOfPtrs), Info.SizesArray,
Samuel Antaodf158d52016-04-27 22:58:19 +00008713 /*Idx0=*/0, /*Idx1=*/0);
8714 MapTypesArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(
George Rokos63bc9d62017-11-21 18:25:12 +00008715 llvm::ArrayType::get(CGM.Int64Ty, Info.NumberOfPtrs),
Samuel Antaocc10b852016-07-28 14:23:26 +00008716 Info.MapTypesArray,
Samuel Antaodf158d52016-04-27 22:58:19 +00008717 /*Idx0=*/0,
8718 /*Idx1=*/0);
8719 } else {
8720 BasePointersArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy);
8721 PointersArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy);
Alexey Bataeva90fc662019-06-25 16:00:43 +00008722 SizesArrayArg = llvm::ConstantPointerNull::get(CGM.Int64Ty->getPointerTo());
Samuel Antaodf158d52016-04-27 22:58:19 +00008723 MapTypesArrayArg =
George Rokos63bc9d62017-11-21 18:25:12 +00008724 llvm::ConstantPointerNull::get(CGM.Int64Ty->getPointerTo());
Samuel Antaodf158d52016-04-27 22:58:19 +00008725 }
Samuel Antao86ace552016-04-27 22:40:57 +00008726}
8727
Alexey Bataev7bb33532019-01-07 21:30:43 +00008728/// Check for inner distribute directive.
8729static const OMPExecutableDirective *
8730getNestedDistributeDirective(ASTContext &Ctx, const OMPExecutableDirective &D) {
8731 const auto *CS = D.getInnermostCapturedStmt();
8732 const auto *Body =
8733 CS->getCapturedStmt()->IgnoreContainers(/*IgnoreCaptured=*/true);
Alexey Bataev5c427362019-04-10 19:11:33 +00008734 const Stmt *ChildStmt =
8735 CGOpenMPSIMDRuntime::getSingleCompoundChild(Ctx, Body);
Alexey Bataev7bb33532019-01-07 21:30:43 +00008736
Alexey Bataev5c427362019-04-10 19:11:33 +00008737 if (const auto *NestedDir =
8738 dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
Alexey Bataev7bb33532019-01-07 21:30:43 +00008739 OpenMPDirectiveKind DKind = NestedDir->getDirectiveKind();
8740 switch (D.getDirectiveKind()) {
8741 case OMPD_target:
8742 if (isOpenMPDistributeDirective(DKind))
8743 return NestedDir;
8744 if (DKind == OMPD_teams) {
8745 Body = NestedDir->getInnermostCapturedStmt()->IgnoreContainers(
8746 /*IgnoreCaptured=*/true);
8747 if (!Body)
8748 return nullptr;
Alexey Bataev5c427362019-04-10 19:11:33 +00008749 ChildStmt = CGOpenMPSIMDRuntime::getSingleCompoundChild(Ctx, Body);
8750 if (const auto *NND =
8751 dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
Alexey Bataev7bb33532019-01-07 21:30:43 +00008752 DKind = NND->getDirectiveKind();
8753 if (isOpenMPDistributeDirective(DKind))
8754 return NND;
8755 }
8756 }
8757 return nullptr;
8758 case OMPD_target_teams:
8759 if (isOpenMPDistributeDirective(DKind))
8760 return NestedDir;
8761 return nullptr;
8762 case OMPD_target_parallel:
8763 case OMPD_target_simd:
8764 case OMPD_target_parallel_for:
8765 case OMPD_target_parallel_for_simd:
8766 return nullptr;
8767 case OMPD_target_teams_distribute:
8768 case OMPD_target_teams_distribute_simd:
8769 case OMPD_target_teams_distribute_parallel_for:
8770 case OMPD_target_teams_distribute_parallel_for_simd:
8771 case OMPD_parallel:
8772 case OMPD_for:
8773 case OMPD_parallel_for:
cchen47d60942019-12-05 13:43:48 -05008774 case OMPD_parallel_master:
Alexey Bataev7bb33532019-01-07 21:30:43 +00008775 case OMPD_parallel_sections:
8776 case OMPD_for_simd:
8777 case OMPD_parallel_for_simd:
8778 case OMPD_cancel:
8779 case OMPD_cancellation_point:
8780 case OMPD_ordered:
8781 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00008782 case OMPD_allocate:
Alexey Bataev7bb33532019-01-07 21:30:43 +00008783 case OMPD_task:
8784 case OMPD_simd:
8785 case OMPD_sections:
8786 case OMPD_section:
8787 case OMPD_single:
8788 case OMPD_master:
8789 case OMPD_critical:
8790 case OMPD_taskyield:
8791 case OMPD_barrier:
8792 case OMPD_taskwait:
8793 case OMPD_taskgroup:
8794 case OMPD_atomic:
8795 case OMPD_flush:
8796 case OMPD_teams:
8797 case OMPD_target_data:
8798 case OMPD_target_exit_data:
8799 case OMPD_target_enter_data:
8800 case OMPD_distribute:
8801 case OMPD_distribute_simd:
8802 case OMPD_distribute_parallel_for:
8803 case OMPD_distribute_parallel_for_simd:
8804 case OMPD_teams_distribute:
8805 case OMPD_teams_distribute_simd:
8806 case OMPD_teams_distribute_parallel_for:
8807 case OMPD_teams_distribute_parallel_for_simd:
8808 case OMPD_target_update:
8809 case OMPD_declare_simd:
Alexey Bataevd158cf62019-09-13 20:18:17 +00008810 case OMPD_declare_variant:
Alexey Bataev7bb33532019-01-07 21:30:43 +00008811 case OMPD_declare_target:
8812 case OMPD_end_declare_target:
8813 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +00008814 case OMPD_declare_mapper:
Alexey Bataev7bb33532019-01-07 21:30:43 +00008815 case OMPD_taskloop:
8816 case OMPD_taskloop_simd:
Alexey Bataev60e51c42019-10-10 20:13:02 +00008817 case OMPD_master_taskloop:
Alexey Bataevb8552ab2019-10-18 16:47:35 +00008818 case OMPD_master_taskloop_simd:
Alexey Bataev5bbcead2019-10-14 17:17:41 +00008819 case OMPD_parallel_master_taskloop:
Alexey Bataev14a388f2019-10-25 10:27:13 -04008820 case OMPD_parallel_master_taskloop_simd:
Alexey Bataev7bb33532019-01-07 21:30:43 +00008821 case OMPD_requires:
8822 case OMPD_unknown:
8823 llvm_unreachable("Unexpected directive.");
8824 }
8825 }
8826
8827 return nullptr;
8828}
8829
Michael Krused47b9432019-08-05 18:43:21 +00008830/// Emit the user-defined mapper function. The code generation follows the
8831/// pattern in the example below.
8832/// \code
8833/// void .omp_mapper.<type_name>.<mapper_id>.(void *rt_mapper_handle,
8834/// void *base, void *begin,
8835/// int64_t size, int64_t type) {
8836/// // Allocate space for an array section first.
8837/// if (size > 1 && !maptype.IsDelete)
8838/// __tgt_push_mapper_component(rt_mapper_handle, base, begin,
8839/// size*sizeof(Ty), clearToFrom(type));
8840/// // Map members.
8841/// for (unsigned i = 0; i < size; i++) {
8842/// // For each component specified by this mapper:
8843/// for (auto c : all_components) {
8844/// if (c.hasMapper())
8845/// (*c.Mapper())(rt_mapper_handle, c.arg_base, c.arg_begin, c.arg_size,
8846/// c.arg_type);
8847/// else
8848/// __tgt_push_mapper_component(rt_mapper_handle, c.arg_base,
8849/// c.arg_begin, c.arg_size, c.arg_type);
8850/// }
8851/// }
8852/// // Delete the array section.
8853/// if (size > 1 && maptype.IsDelete)
8854/// __tgt_push_mapper_component(rt_mapper_handle, base, begin,
8855/// size*sizeof(Ty), clearToFrom(type));
8856/// }
8857/// \endcode
8858void CGOpenMPRuntime::emitUserDefinedMapper(const OMPDeclareMapperDecl *D,
8859 CodeGenFunction *CGF) {
8860 if (UDMMap.count(D) > 0)
8861 return;
8862 ASTContext &C = CGM.getContext();
8863 QualType Ty = D->getType();
8864 QualType PtrTy = C.getPointerType(Ty).withRestrict();
8865 QualType Int64Ty = C.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/true);
8866 auto *MapperVarDecl =
8867 cast<VarDecl>(cast<DeclRefExpr>(D->getMapperVarRef())->getDecl());
8868 SourceLocation Loc = D->getLocation();
8869 CharUnits ElementSize = C.getTypeSizeInChars(Ty);
8870
8871 // Prepare mapper function arguments and attributes.
8872 ImplicitParamDecl HandleArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
8873 C.VoidPtrTy, ImplicitParamDecl::Other);
8874 ImplicitParamDecl BaseArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
8875 ImplicitParamDecl::Other);
8876 ImplicitParamDecl BeginArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
8877 C.VoidPtrTy, ImplicitParamDecl::Other);
8878 ImplicitParamDecl SizeArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, Int64Ty,
8879 ImplicitParamDecl::Other);
8880 ImplicitParamDecl TypeArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, Int64Ty,
8881 ImplicitParamDecl::Other);
8882 FunctionArgList Args;
8883 Args.push_back(&HandleArg);
8884 Args.push_back(&BaseArg);
8885 Args.push_back(&BeginArg);
8886 Args.push_back(&SizeArg);
8887 Args.push_back(&TypeArg);
8888 const CGFunctionInfo &FnInfo =
8889 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
8890 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
8891 SmallString<64> TyStr;
8892 llvm::raw_svector_ostream Out(TyStr);
8893 CGM.getCXXABI().getMangleContext().mangleTypeName(Ty, Out);
8894 std::string Name = getName({"omp_mapper", TyStr, D->getName()});
8895 auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
8896 Name, &CGM.getModule());
8897 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo);
8898 Fn->removeFnAttr(llvm::Attribute::OptimizeNone);
8899 // Start the mapper function code generation.
8900 CodeGenFunction MapperCGF(CGM);
8901 MapperCGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, Loc, Loc);
8902 // Compute the starting and end addreses of array elements.
8903 llvm::Value *Size = MapperCGF.EmitLoadOfScalar(
8904 MapperCGF.GetAddrOfLocalVar(&SizeArg), /*Volatile=*/false,
8905 C.getPointerType(Int64Ty), Loc);
8906 llvm::Value *PtrBegin = MapperCGF.Builder.CreateBitCast(
8907 MapperCGF.GetAddrOfLocalVar(&BeginArg).getPointer(),
8908 CGM.getTypes().ConvertTypeForMem(C.getPointerType(PtrTy)));
8909 llvm::Value *PtrEnd = MapperCGF.Builder.CreateGEP(PtrBegin, Size);
8910 llvm::Value *MapType = MapperCGF.EmitLoadOfScalar(
8911 MapperCGF.GetAddrOfLocalVar(&TypeArg), /*Volatile=*/false,
8912 C.getPointerType(Int64Ty), Loc);
8913 // Prepare common arguments for array initiation and deletion.
8914 llvm::Value *Handle = MapperCGF.EmitLoadOfScalar(
8915 MapperCGF.GetAddrOfLocalVar(&HandleArg),
8916 /*Volatile=*/false, C.getPointerType(C.VoidPtrTy), Loc);
8917 llvm::Value *BaseIn = MapperCGF.EmitLoadOfScalar(
8918 MapperCGF.GetAddrOfLocalVar(&BaseArg),
8919 /*Volatile=*/false, C.getPointerType(C.VoidPtrTy), Loc);
8920 llvm::Value *BeginIn = MapperCGF.EmitLoadOfScalar(
8921 MapperCGF.GetAddrOfLocalVar(&BeginArg),
8922 /*Volatile=*/false, C.getPointerType(C.VoidPtrTy), Loc);
8923
8924 // Emit array initiation if this is an array section and \p MapType indicates
8925 // that memory allocation is required.
8926 llvm::BasicBlock *HeadBB = MapperCGF.createBasicBlock("omp.arraymap.head");
8927 emitUDMapperArrayInitOrDel(MapperCGF, Handle, BaseIn, BeginIn, Size, MapType,
8928 ElementSize, HeadBB, /*IsInit=*/true);
8929
8930 // Emit a for loop to iterate through SizeArg of elements and map all of them.
8931
8932 // Emit the loop header block.
8933 MapperCGF.EmitBlock(HeadBB);
8934 llvm::BasicBlock *BodyBB = MapperCGF.createBasicBlock("omp.arraymap.body");
8935 llvm::BasicBlock *DoneBB = MapperCGF.createBasicBlock("omp.done");
8936 // Evaluate whether the initial condition is satisfied.
8937 llvm::Value *IsEmpty =
8938 MapperCGF.Builder.CreateICmpEQ(PtrBegin, PtrEnd, "omp.arraymap.isempty");
8939 MapperCGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
8940 llvm::BasicBlock *EntryBB = MapperCGF.Builder.GetInsertBlock();
8941
8942 // Emit the loop body block.
8943 MapperCGF.EmitBlock(BodyBB);
8944 llvm::PHINode *PtrPHI = MapperCGF.Builder.CreatePHI(
8945 PtrBegin->getType(), 2, "omp.arraymap.ptrcurrent");
8946 PtrPHI->addIncoming(PtrBegin, EntryBB);
8947 Address PtrCurrent =
8948 Address(PtrPHI, MapperCGF.GetAddrOfLocalVar(&BeginArg)
8949 .getAlignment()
8950 .alignmentOfArrayElement(ElementSize));
8951 // Privatize the declared variable of mapper to be the current array element.
8952 CodeGenFunction::OMPPrivateScope Scope(MapperCGF);
Akira Hatanaka9f37c0e2019-12-03 13:07:22 -08008953 Scope.addPrivate(MapperVarDecl, [&MapperCGF, PtrCurrent, PtrTy]() {
Michael Krused47b9432019-08-05 18:43:21 +00008954 return MapperCGF
8955 .EmitLoadOfPointerLValue(PtrCurrent, PtrTy->castAs<PointerType>())
Akira Hatanakaf139ae32019-12-03 15:17:01 -08008956 .getAddress(MapperCGF);
Michael Krused47b9432019-08-05 18:43:21 +00008957 });
8958 (void)Scope.Privatize();
8959
8960 // Get map clause information. Fill up the arrays with all mapped variables.
8961 MappableExprsHandler::MapBaseValuesArrayTy BasePointers;
8962 MappableExprsHandler::MapValuesArrayTy Pointers;
8963 MappableExprsHandler::MapValuesArrayTy Sizes;
8964 MappableExprsHandler::MapFlagsArrayTy MapTypes;
8965 MappableExprsHandler MEHandler(*D, MapperCGF);
8966 MEHandler.generateAllInfoForMapper(BasePointers, Pointers, Sizes, MapTypes);
8967
8968 // Call the runtime API __tgt_mapper_num_components to get the number of
8969 // pre-existing components.
8970 llvm::Value *OffloadingArgs[] = {Handle};
8971 llvm::Value *PreviousSize = MapperCGF.EmitRuntimeCall(
8972 createRuntimeFunction(OMPRTL__tgt_mapper_num_components), OffloadingArgs);
8973 llvm::Value *ShiftedPreviousSize = MapperCGF.Builder.CreateShl(
8974 PreviousSize,
8975 MapperCGF.Builder.getInt64(MappableExprsHandler::getFlagMemberOffset()));
8976
8977 // Fill up the runtime mapper handle for all components.
8978 for (unsigned I = 0; I < BasePointers.size(); ++I) {
8979 llvm::Value *CurBaseArg = MapperCGF.Builder.CreateBitCast(
8980 *BasePointers[I], CGM.getTypes().ConvertTypeForMem(C.VoidPtrTy));
8981 llvm::Value *CurBeginArg = MapperCGF.Builder.CreateBitCast(
8982 Pointers[I], CGM.getTypes().ConvertTypeForMem(C.VoidPtrTy));
8983 llvm::Value *CurSizeArg = Sizes[I];
8984
8985 // Extract the MEMBER_OF field from the map type.
8986 llvm::BasicBlock *MemberBB = MapperCGF.createBasicBlock("omp.member");
8987 MapperCGF.EmitBlock(MemberBB);
8988 llvm::Value *OriMapType = MapperCGF.Builder.getInt64(MapTypes[I]);
8989 llvm::Value *Member = MapperCGF.Builder.CreateAnd(
8990 OriMapType,
8991 MapperCGF.Builder.getInt64(MappableExprsHandler::OMP_MAP_MEMBER_OF));
8992 llvm::BasicBlock *MemberCombineBB =
8993 MapperCGF.createBasicBlock("omp.member.combine");
8994 llvm::BasicBlock *TypeBB = MapperCGF.createBasicBlock("omp.type");
8995 llvm::Value *IsMember = MapperCGF.Builder.CreateIsNull(Member);
8996 MapperCGF.Builder.CreateCondBr(IsMember, TypeBB, MemberCombineBB);
8997 // Add the number of pre-existing components to the MEMBER_OF field if it
8998 // is valid.
8999 MapperCGF.EmitBlock(MemberCombineBB);
9000 llvm::Value *CombinedMember =
9001 MapperCGF.Builder.CreateNUWAdd(OriMapType, ShiftedPreviousSize);
9002 // Do nothing if it is not a member of previous components.
9003 MapperCGF.EmitBlock(TypeBB);
9004 llvm::PHINode *MemberMapType =
9005 MapperCGF.Builder.CreatePHI(CGM.Int64Ty, 4, "omp.membermaptype");
9006 MemberMapType->addIncoming(OriMapType, MemberBB);
9007 MemberMapType->addIncoming(CombinedMember, MemberCombineBB);
9008
9009 // Combine the map type inherited from user-defined mapper with that
9010 // specified in the program. According to the OMP_MAP_TO and OMP_MAP_FROM
9011 // bits of the \a MapType, which is the input argument of the mapper
9012 // function, the following code will set the OMP_MAP_TO and OMP_MAP_FROM
9013 // bits of MemberMapType.
9014 // [OpenMP 5.0], 1.2.6. map-type decay.
9015 // | alloc | to | from | tofrom | release | delete
9016 // ----------------------------------------------------------
9017 // alloc | alloc | alloc | alloc | alloc | release | delete
9018 // to | alloc | to | alloc | to | release | delete
9019 // from | alloc | alloc | from | from | release | delete
9020 // tofrom | alloc | to | from | tofrom | release | delete
9021 llvm::Value *LeftToFrom = MapperCGF.Builder.CreateAnd(
9022 MapType,
9023 MapperCGF.Builder.getInt64(MappableExprsHandler::OMP_MAP_TO |
9024 MappableExprsHandler::OMP_MAP_FROM));
9025 llvm::BasicBlock *AllocBB = MapperCGF.createBasicBlock("omp.type.alloc");
9026 llvm::BasicBlock *AllocElseBB =
9027 MapperCGF.createBasicBlock("omp.type.alloc.else");
9028 llvm::BasicBlock *ToBB = MapperCGF.createBasicBlock("omp.type.to");
9029 llvm::BasicBlock *ToElseBB = MapperCGF.createBasicBlock("omp.type.to.else");
9030 llvm::BasicBlock *FromBB = MapperCGF.createBasicBlock("omp.type.from");
9031 llvm::BasicBlock *EndBB = MapperCGF.createBasicBlock("omp.type.end");
9032 llvm::Value *IsAlloc = MapperCGF.Builder.CreateIsNull(LeftToFrom);
9033 MapperCGF.Builder.CreateCondBr(IsAlloc, AllocBB, AllocElseBB);
9034 // In case of alloc, clear OMP_MAP_TO and OMP_MAP_FROM.
9035 MapperCGF.EmitBlock(AllocBB);
9036 llvm::Value *AllocMapType = MapperCGF.Builder.CreateAnd(
9037 MemberMapType,
9038 MapperCGF.Builder.getInt64(~(MappableExprsHandler::OMP_MAP_TO |
9039 MappableExprsHandler::OMP_MAP_FROM)));
9040 MapperCGF.Builder.CreateBr(EndBB);
9041 MapperCGF.EmitBlock(AllocElseBB);
9042 llvm::Value *IsTo = MapperCGF.Builder.CreateICmpEQ(
9043 LeftToFrom,
9044 MapperCGF.Builder.getInt64(MappableExprsHandler::OMP_MAP_TO));
9045 MapperCGF.Builder.CreateCondBr(IsTo, ToBB, ToElseBB);
9046 // In case of to, clear OMP_MAP_FROM.
9047 MapperCGF.EmitBlock(ToBB);
9048 llvm::Value *ToMapType = MapperCGF.Builder.CreateAnd(
9049 MemberMapType,
9050 MapperCGF.Builder.getInt64(~MappableExprsHandler::OMP_MAP_FROM));
9051 MapperCGF.Builder.CreateBr(EndBB);
9052 MapperCGF.EmitBlock(ToElseBB);
9053 llvm::Value *IsFrom = MapperCGF.Builder.CreateICmpEQ(
9054 LeftToFrom,
9055 MapperCGF.Builder.getInt64(MappableExprsHandler::OMP_MAP_FROM));
9056 MapperCGF.Builder.CreateCondBr(IsFrom, FromBB, EndBB);
9057 // In case of from, clear OMP_MAP_TO.
9058 MapperCGF.EmitBlock(FromBB);
9059 llvm::Value *FromMapType = MapperCGF.Builder.CreateAnd(
9060 MemberMapType,
9061 MapperCGF.Builder.getInt64(~MappableExprsHandler::OMP_MAP_TO));
9062 // In case of tofrom, do nothing.
9063 MapperCGF.EmitBlock(EndBB);
9064 llvm::PHINode *CurMapType =
9065 MapperCGF.Builder.CreatePHI(CGM.Int64Ty, 4, "omp.maptype");
9066 CurMapType->addIncoming(AllocMapType, AllocBB);
9067 CurMapType->addIncoming(ToMapType, ToBB);
9068 CurMapType->addIncoming(FromMapType, FromBB);
9069 CurMapType->addIncoming(MemberMapType, ToElseBB);
9070
9071 // TODO: call the corresponding mapper function if a user-defined mapper is
9072 // associated with this map clause.
9073 // Call the runtime API __tgt_push_mapper_component to fill up the runtime
9074 // data structure.
9075 llvm::Value *OffloadingArgs[] = {Handle, CurBaseArg, CurBeginArg,
9076 CurSizeArg, CurMapType};
9077 MapperCGF.EmitRuntimeCall(
9078 createRuntimeFunction(OMPRTL__tgt_push_mapper_component),
9079 OffloadingArgs);
9080 }
9081
9082 // Update the pointer to point to the next element that needs to be mapped,
9083 // and check whether we have mapped all elements.
9084 llvm::Value *PtrNext = MapperCGF.Builder.CreateConstGEP1_32(
9085 PtrPHI, /*Idx0=*/1, "omp.arraymap.next");
9086 PtrPHI->addIncoming(PtrNext, BodyBB);
9087 llvm::Value *IsDone =
9088 MapperCGF.Builder.CreateICmpEQ(PtrNext, PtrEnd, "omp.arraymap.isdone");
9089 llvm::BasicBlock *ExitBB = MapperCGF.createBasicBlock("omp.arraymap.exit");
9090 MapperCGF.Builder.CreateCondBr(IsDone, ExitBB, BodyBB);
9091
9092 MapperCGF.EmitBlock(ExitBB);
9093 // Emit array deletion if this is an array section and \p MapType indicates
9094 // that deletion is required.
9095 emitUDMapperArrayInitOrDel(MapperCGF, Handle, BaseIn, BeginIn, Size, MapType,
9096 ElementSize, DoneBB, /*IsInit=*/false);
9097
9098 // Emit the function exit block.
9099 MapperCGF.EmitBlock(DoneBB, /*IsFinished=*/true);
9100 MapperCGF.FinishFunction();
9101 UDMMap.try_emplace(D, Fn);
9102 if (CGF) {
9103 auto &Decls = FunctionUDMMap.FindAndConstruct(CGF->CurFn);
9104 Decls.second.push_back(D);
9105 }
9106}
9107
9108/// Emit the array initialization or deletion portion for user-defined mapper
9109/// code generation. First, it evaluates whether an array section is mapped and
9110/// whether the \a MapType instructs to delete this section. If \a IsInit is
9111/// true, and \a MapType indicates to not delete this array, array
9112/// initialization code is generated. If \a IsInit is false, and \a MapType
9113/// indicates to not this array, array deletion code is generated.
9114void CGOpenMPRuntime::emitUDMapperArrayInitOrDel(
9115 CodeGenFunction &MapperCGF, llvm::Value *Handle, llvm::Value *Base,
9116 llvm::Value *Begin, llvm::Value *Size, llvm::Value *MapType,
9117 CharUnits ElementSize, llvm::BasicBlock *ExitBB, bool IsInit) {
9118 StringRef Prefix = IsInit ? ".init" : ".del";
9119
9120 // Evaluate if this is an array section.
9121 llvm::BasicBlock *IsDeleteBB =
Alexey Bataev8b321922020-01-16 15:46:34 -05009122 MapperCGF.createBasicBlock(getName({"omp.array", Prefix, ".evaldelete"}));
9123 llvm::BasicBlock *BodyBB =
9124 MapperCGF.createBasicBlock(getName({"omp.array", Prefix}));
Michael Krused47b9432019-08-05 18:43:21 +00009125 llvm::Value *IsArray = MapperCGF.Builder.CreateICmpSGE(
9126 Size, MapperCGF.Builder.getInt64(1), "omp.arrayinit.isarray");
9127 MapperCGF.Builder.CreateCondBr(IsArray, IsDeleteBB, ExitBB);
9128
9129 // Evaluate if we are going to delete this section.
9130 MapperCGF.EmitBlock(IsDeleteBB);
9131 llvm::Value *DeleteBit = MapperCGF.Builder.CreateAnd(
9132 MapType,
9133 MapperCGF.Builder.getInt64(MappableExprsHandler::OMP_MAP_DELETE));
9134 llvm::Value *DeleteCond;
9135 if (IsInit) {
9136 DeleteCond = MapperCGF.Builder.CreateIsNull(
Alexey Bataev8b321922020-01-16 15:46:34 -05009137 DeleteBit, getName({"omp.array", Prefix, ".delete"}));
Michael Krused47b9432019-08-05 18:43:21 +00009138 } else {
9139 DeleteCond = MapperCGF.Builder.CreateIsNotNull(
Alexey Bataev8b321922020-01-16 15:46:34 -05009140 DeleteBit, getName({"omp.array", Prefix, ".delete"}));
Michael Krused47b9432019-08-05 18:43:21 +00009141 }
9142 MapperCGF.Builder.CreateCondBr(DeleteCond, BodyBB, ExitBB);
9143
9144 MapperCGF.EmitBlock(BodyBB);
9145 // Get the array size by multiplying element size and element number (i.e., \p
9146 // Size).
9147 llvm::Value *ArraySize = MapperCGF.Builder.CreateNUWMul(
9148 Size, MapperCGF.Builder.getInt64(ElementSize.getQuantity()));
9149 // Remove OMP_MAP_TO and OMP_MAP_FROM from the map type, so that it achieves
9150 // memory allocation/deletion purpose only.
9151 llvm::Value *MapTypeArg = MapperCGF.Builder.CreateAnd(
9152 MapType,
9153 MapperCGF.Builder.getInt64(~(MappableExprsHandler::OMP_MAP_TO |
9154 MappableExprsHandler::OMP_MAP_FROM)));
9155 // Call the runtime API __tgt_push_mapper_component to fill up the runtime
9156 // data structure.
9157 llvm::Value *OffloadingArgs[] = {Handle, Base, Begin, ArraySize, MapTypeArg};
9158 MapperCGF.EmitRuntimeCall(
9159 createRuntimeFunction(OMPRTL__tgt_push_mapper_component), OffloadingArgs);
9160}
9161
Alexey Bataev7bb33532019-01-07 21:30:43 +00009162void CGOpenMPRuntime::emitTargetNumIterationsCall(
Alexey Bataevec7946e2019-09-23 14:06:51 +00009163 CodeGenFunction &CGF, const OMPExecutableDirective &D,
9164 llvm::Value *DeviceID,
9165 llvm::function_ref<llvm::Value *(CodeGenFunction &CGF,
9166 const OMPLoopDirective &D)>
9167 SizeEmitter) {
Alexey Bataev7bb33532019-01-07 21:30:43 +00009168 OpenMPDirectiveKind Kind = D.getDirectiveKind();
9169 const OMPExecutableDirective *TD = &D;
9170 // Get nested teams distribute kind directive, if any.
9171 if (!isOpenMPDistributeDirective(Kind) || !isOpenMPTeamsDirective(Kind))
9172 TD = getNestedDistributeDirective(CGM.getContext(), D);
9173 if (!TD)
9174 return;
9175 const auto *LD = cast<OMPLoopDirective>(TD);
Alexey Bataevec7946e2019-09-23 14:06:51 +00009176 auto &&CodeGen = [LD, DeviceID, SizeEmitter, this](CodeGenFunction &CGF,
Alexey Bataev7bb33532019-01-07 21:30:43 +00009177 PrePostActionTy &) {
Alexey Bataevec7946e2019-09-23 14:06:51 +00009178 if (llvm::Value *NumIterations = SizeEmitter(CGF, *LD)) {
9179 llvm::Value *Args[] = {DeviceID, NumIterations};
9180 CGF.EmitRuntimeCall(
9181 createRuntimeFunction(OMPRTL__kmpc_push_target_tripcount), Args);
9182 }
Alexey Bataev7bb33532019-01-07 21:30:43 +00009183 };
9184 emitInlinedDirective(CGF, OMPD_unknown, CodeGen);
9185}
9186
Alexey Bataevec7946e2019-09-23 14:06:51 +00009187void CGOpenMPRuntime::emitTargetCall(
9188 CodeGenFunction &CGF, const OMPExecutableDirective &D,
9189 llvm::Function *OutlinedFn, llvm::Value *OutlinedFnID, const Expr *IfCond,
9190 const Expr *Device,
9191 llvm::function_ref<llvm::Value *(CodeGenFunction &CGF,
9192 const OMPLoopDirective &D)>
9193 SizeEmitter) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00009194 if (!CGF.HaveInsertPoint())
9195 return;
Samuel Antaobed3c462015-10-02 16:14:20 +00009196
Samuel Antaoee8fb302016-01-06 13:42:12 +00009197 assert(OutlinedFn && "Invalid outlined function!");
9198
Alexey Bataev8451efa2018-01-15 19:06:12 +00009199 const bool RequiresOuterTask = D.hasClausesOfKind<OMPDependClause>();
9200 llvm::SmallVector<llvm::Value *, 16> CapturedVars;
Alexey Bataev475a7442018-01-12 19:39:11 +00009201 const CapturedStmt &CS = *D.getCapturedStmt(OMPD_target);
Alexey Bataev8451efa2018-01-15 19:06:12 +00009202 auto &&ArgsCodegen = [&CS, &CapturedVars](CodeGenFunction &CGF,
9203 PrePostActionTy &) {
9204 CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
9205 };
9206 emitInlinedDirective(CGF, OMPD_unknown, ArgsCodegen);
Samuel Antao86ace552016-04-27 22:40:57 +00009207
Alexey Bataev8451efa2018-01-15 19:06:12 +00009208 CodeGenFunction::OMPTargetDataInfo InputInfo;
9209 llvm::Value *MapTypesArray = nullptr;
Samuel Antaobed3c462015-10-02 16:14:20 +00009210 // Fill up the pointer arrays and transfer execution to the device.
Alexey Bataev8451efa2018-01-15 19:06:12 +00009211 auto &&ThenGen = [this, Device, OutlinedFn, OutlinedFnID, &D, &InputInfo,
Alexey Bataevec7946e2019-09-23 14:06:51 +00009212 &MapTypesArray, &CS, RequiresOuterTask, &CapturedVars,
9213 SizeEmitter](CodeGenFunction &CGF, PrePostActionTy &) {
Samuel Antaobed3c462015-10-02 16:14:20 +00009214 // On top of the arrays that were filled up, the target offloading call
9215 // takes as arguments the device id as well as the host pointer. The host
9216 // pointer is used by the runtime library to identify the current target
9217 // region, so it only has to be unique and not necessarily point to
9218 // anything. It could be the pointer to the outlined function that
9219 // implements the target region, but we aren't using that so that the
9220 // compiler doesn't need to keep that, and could therefore inline the host
9221 // function if proven worthwhile during optimization.
9222
Samuel Antaoee8fb302016-01-06 13:42:12 +00009223 // From this point on, we need to have an ID of the target region defined.
9224 assert(OutlinedFnID && "Invalid outlined function ID!");
Samuel Antaobed3c462015-10-02 16:14:20 +00009225
9226 // Emit device ID if any.
9227 llvm::Value *DeviceID;
George Rokos63bc9d62017-11-21 18:25:12 +00009228 if (Device) {
Samuel Antaobed3c462015-10-02 16:14:20 +00009229 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
George Rokos63bc9d62017-11-21 18:25:12 +00009230 CGF.Int64Ty, /*isSigned=*/true);
9231 } else {
9232 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
9233 }
Samuel Antaobed3c462015-10-02 16:14:20 +00009234
Samuel Antaodf158d52016-04-27 22:58:19 +00009235 // Emit the number of elements in the offloading arrays.
Alexey Bataev8451efa2018-01-15 19:06:12 +00009236 llvm::Value *PointerNum =
9237 CGF.Builder.getInt32(InputInfo.NumberOfTargetItems);
Samuel Antaodf158d52016-04-27 22:58:19 +00009238
Samuel Antaob68e2db2016-03-03 16:20:23 +00009239 // Return value of the runtime offloading call.
9240 llvm::Value *Return;
9241
Alexey Bataev5c427362019-04-10 19:11:33 +00009242 llvm::Value *NumTeams = emitNumTeamsForTargetDirective(CGF, D);
9243 llvm::Value *NumThreads = emitNumThreadsForTargetDirective(CGF, D);
Samuel Antaob68e2db2016-03-03 16:20:23 +00009244
Alexey Bataevec7946e2019-09-23 14:06:51 +00009245 // Emit tripcount for the target loop-based directive.
9246 emitTargetNumIterationsCall(CGF, D, DeviceID, SizeEmitter);
9247
Alexey Bataeva9f77c62017-12-13 21:04:20 +00009248 bool HasNowait = D.hasClausesOfKind<OMPNowaitClause>();
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00009249 // The target region is an outlined function launched by the runtime
9250 // via calls __tgt_target() or __tgt_target_teams().
9251 //
9252 // __tgt_target() launches a target region with one team and one thread,
9253 // executing a serial region. This master thread may in turn launch
9254 // more threads within its team upon encountering a parallel region,
9255 // however, no additional teams can be launched on the device.
9256 //
9257 // __tgt_target_teams() launches a target region with one or more teams,
9258 // each with one or more threads. This call is required for target
9259 // constructs such as:
9260 // 'target teams'
9261 // 'target' / 'teams'
9262 // 'target teams distribute parallel for'
9263 // 'target parallel'
9264 // and so on.
9265 //
9266 // Note that on the host and CPU targets, the runtime implementation of
9267 // these calls simply call the outlined function without forking threads.
9268 // The outlined functions themselves have runtime calls to
9269 // __kmpc_fork_teams() and __kmpc_fork() for this purpose, codegen'd by
9270 // the compiler in emitTeamsCall() and emitParallelCall().
9271 //
9272 // In contrast, on the NVPTX target, the implementation of
9273 // __tgt_target_teams() launches a GPU kernel with the requested number
9274 // of teams and threads so no additional calls to the runtime are required.
Samuel Antaob68e2db2016-03-03 16:20:23 +00009275 if (NumTeams) {
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00009276 // If we have NumTeams defined this means that we have an enclosed teams
9277 // region. Therefore we also expect to have NumThreads defined. These two
9278 // values should be defined in the presence of a teams directive,
9279 // regardless of having any clauses associated. If the user is using teams
9280 // but no clauses, these two values will be the default that should be
9281 // passed to the runtime library - a 32-bit integer with the value zero.
9282 assert(NumThreads && "Thread limit expression should be available along "
9283 "with number of teams.");
Alexey Bataev8451efa2018-01-15 19:06:12 +00009284 llvm::Value *OffloadingArgs[] = {DeviceID,
9285 OutlinedFnID,
9286 PointerNum,
9287 InputInfo.BasePointersArray.getPointer(),
9288 InputInfo.PointersArray.getPointer(),
9289 InputInfo.SizesArray.getPointer(),
9290 MapTypesArray,
9291 NumTeams,
9292 NumThreads};
Samuel Antaob68e2db2016-03-03 16:20:23 +00009293 Return = CGF.EmitRuntimeCall(
Alexey Bataev8451efa2018-01-15 19:06:12 +00009294 createRuntimeFunction(HasNowait ? OMPRTL__tgt_target_teams_nowait
9295 : OMPRTL__tgt_target_teams),
Alexey Bataeva9f77c62017-12-13 21:04:20 +00009296 OffloadingArgs);
Samuel Antaob68e2db2016-03-03 16:20:23 +00009297 } else {
Alexey Bataev8451efa2018-01-15 19:06:12 +00009298 llvm::Value *OffloadingArgs[] = {DeviceID,
9299 OutlinedFnID,
9300 PointerNum,
9301 InputInfo.BasePointersArray.getPointer(),
9302 InputInfo.PointersArray.getPointer(),
9303 InputInfo.SizesArray.getPointer(),
9304 MapTypesArray};
Alexey Bataeva9f77c62017-12-13 21:04:20 +00009305 Return = CGF.EmitRuntimeCall(
Alexey Bataev8451efa2018-01-15 19:06:12 +00009306 createRuntimeFunction(HasNowait ? OMPRTL__tgt_target_nowait
9307 : OMPRTL__tgt_target),
Alexey Bataeva9f77c62017-12-13 21:04:20 +00009308 OffloadingArgs);
Samuel Antaob68e2db2016-03-03 16:20:23 +00009309 }
Samuel Antaobed3c462015-10-02 16:14:20 +00009310
Alexey Bataev2a007e02017-10-02 14:20:58 +00009311 // Check the error code and execute the host version if required.
9312 llvm::BasicBlock *OffloadFailedBlock =
9313 CGF.createBasicBlock("omp_offload.failed");
9314 llvm::BasicBlock *OffloadContBlock =
9315 CGF.createBasicBlock("omp_offload.cont");
9316 llvm::Value *Failed = CGF.Builder.CreateIsNotNull(Return);
9317 CGF.Builder.CreateCondBr(Failed, OffloadFailedBlock, OffloadContBlock);
9318
9319 CGF.EmitBlock(OffloadFailedBlock);
Alexey Bataev8451efa2018-01-15 19:06:12 +00009320 if (RequiresOuterTask) {
9321 CapturedVars.clear();
9322 CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
9323 }
Stephen Kellyf2ceec42018-08-09 21:08:08 +00009324 emitOutlinedFunctionCall(CGF, D.getBeginLoc(), OutlinedFn, CapturedVars);
Alexey Bataev2a007e02017-10-02 14:20:58 +00009325 CGF.EmitBranch(OffloadContBlock);
9326
9327 CGF.EmitBlock(OffloadContBlock, /*IsFinished=*/true);
Samuel Antaobed3c462015-10-02 16:14:20 +00009328 };
9329
Samuel Antaoee8fb302016-01-06 13:42:12 +00009330 // Notify that the host version must be executed.
Alexey Bataev8451efa2018-01-15 19:06:12 +00009331 auto &&ElseGen = [this, &D, OutlinedFn, &CS, &CapturedVars,
9332 RequiresOuterTask](CodeGenFunction &CGF,
9333 PrePostActionTy &) {
9334 if (RequiresOuterTask) {
9335 CapturedVars.clear();
9336 CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
9337 }
Stephen Kellyf2ceec42018-08-09 21:08:08 +00009338 emitOutlinedFunctionCall(CGF, D.getBeginLoc(), OutlinedFn, CapturedVars);
Alexey Bataev8451efa2018-01-15 19:06:12 +00009339 };
9340
9341 auto &&TargetThenGen = [this, &ThenGen, &D, &InputInfo, &MapTypesArray,
9342 &CapturedVars, RequiresOuterTask,
9343 &CS](CodeGenFunction &CGF, PrePostActionTy &) {
9344 // Fill up the arrays with all the captured variables.
9345 MappableExprsHandler::MapBaseValuesArrayTy BasePointers;
9346 MappableExprsHandler::MapValuesArrayTy Pointers;
9347 MappableExprsHandler::MapValuesArrayTy Sizes;
9348 MappableExprsHandler::MapFlagsArrayTy MapTypes;
9349
Alexey Bataev8451efa2018-01-15 19:06:12 +00009350 // Get mappable expression information.
9351 MappableExprsHandler MEHandler(D, CGF);
Alexey Bataev969dbc02018-11-08 15:47:39 +00009352 llvm::DenseMap<llvm::Value *, llvm::Value *> LambdaPointers;
Alexey Bataev8451efa2018-01-15 19:06:12 +00009353
9354 auto RI = CS.getCapturedRecordDecl()->field_begin();
9355 auto CV = CapturedVars.begin();
9356 for (CapturedStmt::const_capture_iterator CI = CS.capture_begin(),
9357 CE = CS.capture_end();
9358 CI != CE; ++CI, ++RI, ++CV) {
Alexey Bataevb3638132018-07-19 16:34:13 +00009359 MappableExprsHandler::MapBaseValuesArrayTy CurBasePointers;
9360 MappableExprsHandler::MapValuesArrayTy CurPointers;
9361 MappableExprsHandler::MapValuesArrayTy CurSizes;
9362 MappableExprsHandler::MapFlagsArrayTy CurMapTypes;
9363 MappableExprsHandler::StructRangeInfoTy PartialStruct;
Alexey Bataev8451efa2018-01-15 19:06:12 +00009364
9365 // VLA sizes are passed to the outlined region by copy and do not have map
9366 // information associated.
9367 if (CI->capturesVariableArrayType()) {
9368 CurBasePointers.push_back(*CV);
9369 CurPointers.push_back(*CV);
Alexey Bataeva90fc662019-06-25 16:00:43 +00009370 CurSizes.push_back(CGF.Builder.CreateIntCast(
9371 CGF.getTypeSize(RI->getType()), CGF.Int64Ty, /*isSigned=*/true));
Alexey Bataev8451efa2018-01-15 19:06:12 +00009372 // Copy to the device as an argument. No need to retrieve it.
9373 CurMapTypes.push_back(MappableExprsHandler::OMP_MAP_LITERAL |
Alexey Bataevf288cf92019-06-27 18:53:07 +00009374 MappableExprsHandler::OMP_MAP_TARGET_PARAM |
9375 MappableExprsHandler::OMP_MAP_IMPLICIT);
Alexey Bataev8451efa2018-01-15 19:06:12 +00009376 } else {
9377 // If we have any information in the map clause, we use it, otherwise we
9378 // just do a default mapping.
9379 MEHandler.generateInfoForCapture(CI, *CV, CurBasePointers, CurPointers,
Alexey Bataevb3638132018-07-19 16:34:13 +00009380 CurSizes, CurMapTypes, PartialStruct);
Alexey Bataev8451efa2018-01-15 19:06:12 +00009381 if (CurBasePointers.empty())
9382 MEHandler.generateDefaultMapInfo(*CI, **RI, *CV, CurBasePointers,
9383 CurPointers, CurSizes, CurMapTypes);
Alexey Bataev60705422018-10-30 15:50:12 +00009384 // Generate correct mapping for variables captured by reference in
9385 // lambdas.
9386 if (CI->capturesVariable())
Alexey Bataev969dbc02018-11-08 15:47:39 +00009387 MEHandler.generateInfoForLambdaCaptures(
9388 CI->getCapturedVar(), *CV, CurBasePointers, CurPointers, CurSizes,
9389 CurMapTypes, LambdaPointers);
Alexey Bataev8451efa2018-01-15 19:06:12 +00009390 }
9391 // We expect to have at least an element of information for this capture.
9392 assert(!CurBasePointers.empty() &&
9393 "Non-existing map pointer for capture!");
9394 assert(CurBasePointers.size() == CurPointers.size() &&
9395 CurBasePointers.size() == CurSizes.size() &&
9396 CurBasePointers.size() == CurMapTypes.size() &&
9397 "Inconsistent map information sizes!");
9398
Alexey Bataevb3638132018-07-19 16:34:13 +00009399 // If there is an entry in PartialStruct it means we have a struct with
9400 // individual members mapped. Emit an extra combined entry.
9401 if (PartialStruct.Base.isValid())
9402 MEHandler.emitCombinedEntry(BasePointers, Pointers, Sizes, MapTypes,
9403 CurMapTypes, PartialStruct);
9404
Alexey Bataev8451efa2018-01-15 19:06:12 +00009405 // We need to append the results of this capture to what we already have.
9406 BasePointers.append(CurBasePointers.begin(), CurBasePointers.end());
9407 Pointers.append(CurPointers.begin(), CurPointers.end());
9408 Sizes.append(CurSizes.begin(), CurSizes.end());
9409 MapTypes.append(CurMapTypes.begin(), CurMapTypes.end());
9410 }
Alexey Bataev60705422018-10-30 15:50:12 +00009411 // Adjust MEMBER_OF flags for the lambdas captures.
Alexey Bataev969dbc02018-11-08 15:47:39 +00009412 MEHandler.adjustMemberOfForLambdaCaptures(LambdaPointers, BasePointers,
9413 Pointers, MapTypes);
Alexey Bataev92327c52018-03-26 16:40:55 +00009414 // Map other list items in the map clause which are not captured variables
9415 // but "declare target link" global variables.
Alexey Bataevb3638132018-07-19 16:34:13 +00009416 MEHandler.generateInfoForDeclareTargetLink(BasePointers, Pointers, Sizes,
9417 MapTypes);
Alexey Bataev8451efa2018-01-15 19:06:12 +00009418
9419 TargetDataInfo Info;
9420 // Fill up the arrays and create the arguments.
9421 emitOffloadingArrays(CGF, BasePointers, Pointers, Sizes, MapTypes, Info);
9422 emitOffloadingArraysArgument(CGF, Info.BasePointersArray,
9423 Info.PointersArray, Info.SizesArray,
9424 Info.MapTypesArray, Info);
9425 InputInfo.NumberOfTargetItems = Info.NumberOfPtrs;
9426 InputInfo.BasePointersArray =
9427 Address(Info.BasePointersArray, CGM.getPointerAlign());
9428 InputInfo.PointersArray =
9429 Address(Info.PointersArray, CGM.getPointerAlign());
9430 InputInfo.SizesArray = Address(Info.SizesArray, CGM.getPointerAlign());
9431 MapTypesArray = Info.MapTypesArray;
9432 if (RequiresOuterTask)
9433 CGF.EmitOMPTargetTaskBasedDirective(D, ThenGen, InputInfo);
9434 else
9435 emitInlinedDirective(CGF, D.getDirectiveKind(), ThenGen);
9436 };
9437
9438 auto &&TargetElseGen = [this, &ElseGen, &D, RequiresOuterTask](
9439 CodeGenFunction &CGF, PrePostActionTy &) {
9440 if (RequiresOuterTask) {
9441 CodeGenFunction::OMPTargetDataInfo InputInfo;
9442 CGF.EmitOMPTargetTaskBasedDirective(D, ElseGen, InputInfo);
9443 } else {
9444 emitInlinedDirective(CGF, D.getDirectiveKind(), ElseGen);
9445 }
Samuel Antaoee8fb302016-01-06 13:42:12 +00009446 };
9447
9448 // If we have a target function ID it means that we need to support
9449 // offloading, otherwise, just execute on the host. We need to execute on host
9450 // regardless of the conditional in the if clause if, e.g., the user do not
9451 // specify target triples.
9452 if (OutlinedFnID) {
Alexey Bataev8451efa2018-01-15 19:06:12 +00009453 if (IfCond) {
Alexey Bataev1d943ae2019-11-19 12:12:23 -05009454 emitIfClause(CGF, IfCond, TargetThenGen, TargetElseGen);
Alexey Bataev8451efa2018-01-15 19:06:12 +00009455 } else {
9456 RegionCodeGenTy ThenRCG(TargetThenGen);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00009457 ThenRCG(CGF);
Alexey Bataevf539faa2016-03-28 12:58:34 +00009458 }
9459 } else {
Alexey Bataev8451efa2018-01-15 19:06:12 +00009460 RegionCodeGenTy ElseRCG(TargetElseGen);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00009461 ElseRCG(CGF);
Alexey Bataevf539faa2016-03-28 12:58:34 +00009462 }
Samuel Antaobed3c462015-10-02 16:14:20 +00009463}
Samuel Antaoee8fb302016-01-06 13:42:12 +00009464
9465void CGOpenMPRuntime::scanForTargetRegionsFunctions(const Stmt *S,
9466 StringRef ParentName) {
9467 if (!S)
9468 return;
9469
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00009470 // Codegen OMP target directives that offload compute to the device.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009471 bool RequiresDeviceCodegen =
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00009472 isa<OMPExecutableDirective>(S) &&
9473 isOpenMPTargetExecutionDirective(
9474 cast<OMPExecutableDirective>(S)->getDirectiveKind());
Samuel Antaoee8fb302016-01-06 13:42:12 +00009475
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009476 if (RequiresDeviceCodegen) {
9477 const auto &E = *cast<OMPExecutableDirective>(S);
Samuel Antaoee8fb302016-01-06 13:42:12 +00009478 unsigned DeviceID;
9479 unsigned FileID;
9480 unsigned Line;
Stephen Kellyf2ceec42018-08-09 21:08:08 +00009481 getTargetEntryUniqueInfo(CGM.getContext(), E.getBeginLoc(), DeviceID,
Samuel Antao2de62b02016-02-13 23:35:10 +00009482 FileID, Line);
Samuel Antaoee8fb302016-01-06 13:42:12 +00009483
9484 // Is this a target region that should not be emitted as an entry point? If
9485 // so just signal we are done with this target region.
Samuel Antao2de62b02016-02-13 23:35:10 +00009486 if (!OffloadEntriesInfoManager.hasTargetRegionEntryInfo(DeviceID, FileID,
9487 ParentName, Line))
Samuel Antaoee8fb302016-01-06 13:42:12 +00009488 return;
9489
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009490 switch (E.getDirectiveKind()) {
9491 case OMPD_target:
9492 CodeGenFunction::EmitOMPTargetDeviceFunction(CGM, ParentName,
9493 cast<OMPTargetDirective>(E));
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00009494 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009495 case OMPD_target_parallel:
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00009496 CodeGenFunction::EmitOMPTargetParallelDeviceFunction(
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009497 CGM, ParentName, cast<OMPTargetParallelDirective>(E));
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00009498 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009499 case OMPD_target_teams:
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00009500 CodeGenFunction::EmitOMPTargetTeamsDeviceFunction(
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009501 CGM, ParentName, cast<OMPTargetTeamsDirective>(E));
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00009502 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009503 case OMPD_target_teams_distribute:
Alexey Bataevdfa430f2017-12-08 15:03:50 +00009504 CodeGenFunction::EmitOMPTargetTeamsDistributeDeviceFunction(
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009505 CGM, ParentName, cast<OMPTargetTeamsDistributeDirective>(E));
Alexey Bataevdfa430f2017-12-08 15:03:50 +00009506 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009507 case OMPD_target_teams_distribute_simd:
Alexey Bataevfbe17fb2017-12-13 19:45:06 +00009508 CodeGenFunction::EmitOMPTargetTeamsDistributeSimdDeviceFunction(
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009509 CGM, ParentName, cast<OMPTargetTeamsDistributeSimdDirective>(E));
Alexey Bataevfbe17fb2017-12-13 19:45:06 +00009510 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009511 case OMPD_target_parallel_for:
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00009512 CodeGenFunction::EmitOMPTargetParallelForDeviceFunction(
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009513 CGM, ParentName, cast<OMPTargetParallelForDirective>(E));
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00009514 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009515 case OMPD_target_parallel_for_simd:
Alexey Bataev5d7edca2017-11-09 17:32:15 +00009516 CodeGenFunction::EmitOMPTargetParallelForSimdDeviceFunction(
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009517 CGM, ParentName, cast<OMPTargetParallelForSimdDirective>(E));
Alexey Bataev5d7edca2017-11-09 17:32:15 +00009518 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009519 case OMPD_target_simd:
Alexey Bataevf8365372017-11-17 17:57:25 +00009520 CodeGenFunction::EmitOMPTargetSimdDeviceFunction(
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009521 CGM, ParentName, cast<OMPTargetSimdDirective>(E));
Alexey Bataevf8365372017-11-17 17:57:25 +00009522 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009523 case OMPD_target_teams_distribute_parallel_for:
Carlo Bertolli52978c32018-01-03 21:12:44 +00009524 CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForDeviceFunction(
9525 CGM, ParentName,
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009526 cast<OMPTargetTeamsDistributeParallelForDirective>(E));
Carlo Bertolli52978c32018-01-03 21:12:44 +00009527 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009528 case OMPD_target_teams_distribute_parallel_for_simd:
Alexey Bataev647dd842018-01-15 20:59:40 +00009529 CodeGenFunction::
9530 EmitOMPTargetTeamsDistributeParallelForSimdDeviceFunction(
9531 CGM, ParentName,
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009532 cast<OMPTargetTeamsDistributeParallelForSimdDirective>(E));
Alexey Bataev647dd842018-01-15 20:59:40 +00009533 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009534 case OMPD_parallel:
9535 case OMPD_for:
9536 case OMPD_parallel_for:
cchen47d60942019-12-05 13:43:48 -05009537 case OMPD_parallel_master:
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009538 case OMPD_parallel_sections:
9539 case OMPD_for_simd:
9540 case OMPD_parallel_for_simd:
9541 case OMPD_cancel:
9542 case OMPD_cancellation_point:
9543 case OMPD_ordered:
9544 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00009545 case OMPD_allocate:
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009546 case OMPD_task:
9547 case OMPD_simd:
9548 case OMPD_sections:
9549 case OMPD_section:
9550 case OMPD_single:
9551 case OMPD_master:
9552 case OMPD_critical:
9553 case OMPD_taskyield:
9554 case OMPD_barrier:
9555 case OMPD_taskwait:
9556 case OMPD_taskgroup:
9557 case OMPD_atomic:
9558 case OMPD_flush:
9559 case OMPD_teams:
9560 case OMPD_target_data:
9561 case OMPD_target_exit_data:
9562 case OMPD_target_enter_data:
9563 case OMPD_distribute:
9564 case OMPD_distribute_simd:
9565 case OMPD_distribute_parallel_for:
9566 case OMPD_distribute_parallel_for_simd:
9567 case OMPD_teams_distribute:
9568 case OMPD_teams_distribute_simd:
9569 case OMPD_teams_distribute_parallel_for:
9570 case OMPD_teams_distribute_parallel_for_simd:
9571 case OMPD_target_update:
9572 case OMPD_declare_simd:
Alexey Bataevd158cf62019-09-13 20:18:17 +00009573 case OMPD_declare_variant:
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009574 case OMPD_declare_target:
9575 case OMPD_end_declare_target:
9576 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +00009577 case OMPD_declare_mapper:
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009578 case OMPD_taskloop:
9579 case OMPD_taskloop_simd:
Alexey Bataev60e51c42019-10-10 20:13:02 +00009580 case OMPD_master_taskloop:
Alexey Bataevb8552ab2019-10-18 16:47:35 +00009581 case OMPD_master_taskloop_simd:
Alexey Bataev5bbcead2019-10-14 17:17:41 +00009582 case OMPD_parallel_master_taskloop:
Alexey Bataev14a388f2019-10-25 10:27:13 -04009583 case OMPD_parallel_master_taskloop_simd:
Kelvin Li1408f912018-09-26 04:28:39 +00009584 case OMPD_requires:
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009585 case OMPD_unknown:
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00009586 llvm_unreachable("Unknown target directive for OpenMP device codegen.");
9587 }
Samuel Antaoee8fb302016-01-06 13:42:12 +00009588 return;
9589 }
9590
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009591 if (const auto *E = dyn_cast<OMPExecutableDirective>(S)) {
Alexey Bataev475a7442018-01-12 19:39:11 +00009592 if (!E->hasAssociatedStmt() || !E->getAssociatedStmt())
Samuel Antaoee8fb302016-01-06 13:42:12 +00009593 return;
9594
9595 scanForTargetRegionsFunctions(
Alexey Bataev475a7442018-01-12 19:39:11 +00009596 E->getInnermostCapturedStmt()->getCapturedStmt(), ParentName);
Samuel Antaoee8fb302016-01-06 13:42:12 +00009597 return;
9598 }
9599
9600 // If this is a lambda function, look into its body.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009601 if (const auto *L = dyn_cast<LambdaExpr>(S))
Samuel Antaoee8fb302016-01-06 13:42:12 +00009602 S = L->getBody();
9603
9604 // Keep looking for target regions recursively.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009605 for (const Stmt *II : S->children())
Samuel Antaoee8fb302016-01-06 13:42:12 +00009606 scanForTargetRegionsFunctions(II, ParentName);
Samuel Antaoee8fb302016-01-06 13:42:12 +00009607}
9608
9609bool CGOpenMPRuntime::emitTargetFunctions(GlobalDecl GD) {
Samuel Antaoee8fb302016-01-06 13:42:12 +00009610 // If emitting code for the host, we do not process FD here. Instead we do
9611 // the normal code generation.
Alexey Bataev729e2422019-08-23 16:11:14 +00009612 if (!CGM.getLangOpts().OpenMPIsDevice) {
9613 if (const auto *FD = dyn_cast<FunctionDecl>(GD.getDecl())) {
9614 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
9615 OMPDeclareTargetDeclAttr::getDeviceType(FD);
9616 // Do not emit device_type(nohost) functions for the host.
9617 if (DevTy && *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
9618 return true;
9619 }
Samuel Antaoee8fb302016-01-06 13:42:12 +00009620 return false;
Alexey Bataev729e2422019-08-23 16:11:14 +00009621 }
Samuel Antaoee8fb302016-01-06 13:42:12 +00009622
Alexey Bataeve6aa4692018-09-13 16:54:05 +00009623 const ValueDecl *VD = cast<ValueDecl>(GD.getDecl());
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00009624 // Try to detect target regions in the function.
Alexey Bataev729e2422019-08-23 16:11:14 +00009625 if (const auto *FD = dyn_cast<FunctionDecl>(VD)) {
Alexey Bataev45588422020-01-07 14:11:45 -05009626 StringRef Name = CGM.getMangledName(GD);
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00009627 scanForTargetRegionsFunctions(FD->getBody(), Name);
Alexey Bataev729e2422019-08-23 16:11:14 +00009628 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
9629 OMPDeclareTargetDeclAttr::getDeviceType(FD);
9630 // Do not emit device_type(nohost) functions for the host.
9631 if (DevTy && *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
9632 return true;
9633 }
Samuel Antaoee8fb302016-01-06 13:42:12 +00009634
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00009635 // Do not to emit function if it is not marked as declare target.
Alexey Bataeve6aa4692018-09-13 16:54:05 +00009636 return !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) &&
Alexey Bataev45588422020-01-07 14:11:45 -05009637 AlreadyEmittedTargetDecls.count(VD) == 0;
Samuel Antaoee8fb302016-01-06 13:42:12 +00009638}
9639
9640bool CGOpenMPRuntime::emitTargetGlobalVariable(GlobalDecl GD) {
9641 if (!CGM.getLangOpts().OpenMPIsDevice)
9642 return false;
9643
9644 // Check if there are Ctors/Dtors in this declaration and look for target
9645 // regions in it. We use the complete variant to produce the kernel name
9646 // mangling.
9647 QualType RDTy = cast<VarDecl>(GD.getDecl())->getType();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009648 if (const auto *RD = RDTy->getBaseElementTypeUnsafe()->getAsCXXRecordDecl()) {
9649 for (const CXXConstructorDecl *Ctor : RD->ctors()) {
Samuel Antaoee8fb302016-01-06 13:42:12 +00009650 StringRef ParentName =
9651 CGM.getMangledName(GlobalDecl(Ctor, Ctor_Complete));
9652 scanForTargetRegionsFunctions(Ctor->getBody(), ParentName);
9653 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009654 if (const CXXDestructorDecl *Dtor = RD->getDestructor()) {
Samuel Antaoee8fb302016-01-06 13:42:12 +00009655 StringRef ParentName =
9656 CGM.getMangledName(GlobalDecl(Dtor, Dtor_Complete));
9657 scanForTargetRegionsFunctions(Dtor->getBody(), ParentName);
9658 }
9659 }
9660
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00009661 // Do not to emit variable if it is not marked as declare target.
Alexey Bataev92327c52018-03-26 16:40:55 +00009662 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
Alexey Bataev97b72212018-08-14 18:31:20 +00009663 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
9664 cast<VarDecl>(GD.getDecl()));
Gheorghe-Teodor Bercea0034e842019-06-20 18:04:47 +00009665 if (!Res || *Res == OMPDeclareTargetDeclAttr::MT_Link ||
9666 (*Res == OMPDeclareTargetDeclAttr::MT_To &&
9667 HasRequiresUnifiedSharedMemory)) {
Alexey Bataevd01b7492018-08-15 19:45:12 +00009668 DeferredGlobalVariables.insert(cast<VarDecl>(GD.getDecl()));
Alexey Bataevbf8fe712018-08-07 16:14:36 +00009669 return true;
9670 }
9671 return false;
Samuel Antaoee8fb302016-01-06 13:42:12 +00009672}
9673
Alexey Bataev1af5bd52019-03-05 17:47:18 +00009674llvm::Constant *
9675CGOpenMPRuntime::registerTargetFirstprivateCopy(CodeGenFunction &CGF,
9676 const VarDecl *VD) {
9677 assert(VD->getType().isConstant(CGM.getContext()) &&
9678 "Expected constant variable.");
9679 StringRef VarName;
9680 llvm::Constant *Addr;
9681 llvm::GlobalValue::LinkageTypes Linkage;
9682 QualType Ty = VD->getType();
9683 SmallString<128> Buffer;
9684 {
9685 unsigned DeviceID;
9686 unsigned FileID;
9687 unsigned Line;
9688 getTargetEntryUniqueInfo(CGM.getContext(), VD->getLocation(), DeviceID,
9689 FileID, Line);
9690 llvm::raw_svector_ostream OS(Buffer);
9691 OS << "__omp_offloading_firstprivate_" << llvm::format("_%x", DeviceID)
9692 << llvm::format("_%x_", FileID) << VD->getName() << "_l" << Line;
9693 VarName = OS.str();
9694 }
9695 Linkage = llvm::GlobalValue::InternalLinkage;
9696 Addr =
9697 getOrCreateInternalVariable(CGM.getTypes().ConvertTypeForMem(Ty), VarName,
9698 getDefaultFirstprivateAddressSpace());
9699 cast<llvm::GlobalValue>(Addr)->setLinkage(Linkage);
9700 CharUnits VarSize = CGM.getContext().getTypeSizeInChars(Ty);
9701 CGM.addCompilerUsedGlobal(cast<llvm::GlobalValue>(Addr));
9702 OffloadEntriesInfoManager.registerDeviceGlobalVarEntryInfo(
9703 VarName, Addr, VarSize,
9704 OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryTo, Linkage);
9705 return Addr;
9706}
9707
Alexey Bataev03f270c2018-03-30 18:31:07 +00009708void CGOpenMPRuntime::registerTargetGlobalVariable(const VarDecl *VD,
9709 llvm::Constant *Addr) {
Alexey Bataev36724b72019-10-03 16:46:49 +00009710 if (CGM.getLangOpts().OMPTargetTriples.empty() &&
9711 !CGM.getLangOpts().OpenMPIsDevice)
Alexey Bataev4db9dc62019-09-23 15:53:51 +00009712 return;
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00009713 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
9714 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
9715 if (!Res) {
9716 if (CGM.getLangOpts().OpenMPIsDevice) {
9717 // Register non-target variables being emitted in device code (debug info
9718 // may cause this).
9719 StringRef VarName = CGM.getMangledName(VD);
9720 EmittedNonTargetVariables.try_emplace(VarName, Addr);
Alexey Bataev03f270c2018-03-30 18:31:07 +00009721 }
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00009722 return;
Alexey Bataev03f270c2018-03-30 18:31:07 +00009723 }
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00009724 // Register declare target variables.
9725 OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind Flags;
9726 StringRef VarName;
9727 CharUnits VarSize;
9728 llvm::GlobalValue::LinkageTypes Linkage;
Gheorghe-Teodor Bercea0034e842019-06-20 18:04:47 +00009729
9730 if (*Res == OMPDeclareTargetDeclAttr::MT_To &&
9731 !HasRequiresUnifiedSharedMemory) {
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00009732 Flags = OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryTo;
9733 VarName = CGM.getMangledName(VD);
9734 if (VD->hasDefinition(CGM.getContext()) != VarDecl::DeclarationOnly) {
9735 VarSize = CGM.getContext().getTypeSizeInChars(VD->getType());
9736 assert(!VarSize.isZero() && "Expected non-zero size of the variable");
9737 } else {
9738 VarSize = CharUnits::Zero();
9739 }
9740 Linkage = CGM.getLLVMLinkageVarDefinition(VD, /*IsConstant=*/false);
9741 // Temp solution to prevent optimizations of the internal variables.
9742 if (CGM.getLangOpts().OpenMPIsDevice && !VD->isExternallyVisible()) {
9743 std::string RefName = getName({VarName, "ref"});
9744 if (!CGM.GetGlobalValue(RefName)) {
9745 llvm::Constant *AddrRef =
9746 getOrCreateInternalVariable(Addr->getType(), RefName);
9747 auto *GVAddrRef = cast<llvm::GlobalVariable>(AddrRef);
9748 GVAddrRef->setConstant(/*Val=*/true);
9749 GVAddrRef->setLinkage(llvm::GlobalValue::InternalLinkage);
9750 GVAddrRef->setInitializer(Addr);
9751 CGM.addCompilerUsedGlobal(GVAddrRef);
9752 }
9753 }
Gheorghe-Teodor Bercea0034e842019-06-20 18:04:47 +00009754 } else {
9755 assert(((*Res == OMPDeclareTargetDeclAttr::MT_Link) ||
9756 (*Res == OMPDeclareTargetDeclAttr::MT_To &&
9757 HasRequiresUnifiedSharedMemory)) &&
9758 "Declare target attribute must link or to with unified memory.");
9759 if (*Res == OMPDeclareTargetDeclAttr::MT_Link)
9760 Flags = OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryLink;
9761 else
9762 Flags = OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryTo;
9763
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00009764 if (CGM.getLangOpts().OpenMPIsDevice) {
9765 VarName = Addr->getName();
9766 Addr = nullptr;
9767 } else {
Gheorghe-Teodor Bercea0034e842019-06-20 18:04:47 +00009768 VarName = getAddrOfDeclareTargetVar(VD).getName();
9769 Addr = cast<llvm::Constant>(getAddrOfDeclareTargetVar(VD).getPointer());
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00009770 }
9771 VarSize = CGM.getPointerSize();
9772 Linkage = llvm::GlobalValue::WeakAnyLinkage;
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00009773 }
Gheorghe-Teodor Bercea0034e842019-06-20 18:04:47 +00009774
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00009775 OffloadEntriesInfoManager.registerDeviceGlobalVarEntryInfo(
9776 VarName, Addr, VarSize, Flags, Linkage);
Alexey Bataev03f270c2018-03-30 18:31:07 +00009777}
9778
Samuel Antaoee8fb302016-01-06 13:42:12 +00009779bool CGOpenMPRuntime::emitTargetGlobal(GlobalDecl GD) {
Alexey Bataeve6aa4692018-09-13 16:54:05 +00009780 if (isa<FunctionDecl>(GD.getDecl()) ||
9781 isa<OMPDeclareReductionDecl>(GD.getDecl()))
Samuel Antaoee8fb302016-01-06 13:42:12 +00009782 return emitTargetFunctions(GD);
9783
9784 return emitTargetGlobalVariable(GD);
9785}
9786
Alexey Bataevbf8fe712018-08-07 16:14:36 +00009787void CGOpenMPRuntime::emitDeferredTargetDecls() const {
9788 for (const VarDecl *VD : DeferredGlobalVariables) {
9789 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
Alexey Bataev97b72212018-08-14 18:31:20 +00009790 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
Alexey Bataevd01b7492018-08-15 19:45:12 +00009791 if (!Res)
9792 continue;
Gheorghe-Teodor Bercea0034e842019-06-20 18:04:47 +00009793 if (*Res == OMPDeclareTargetDeclAttr::MT_To &&
9794 !HasRequiresUnifiedSharedMemory) {
Alexey Bataevbf8fe712018-08-07 16:14:36 +00009795 CGM.EmitGlobal(VD);
Alexey Bataevd01b7492018-08-15 19:45:12 +00009796 } else {
Gheorghe-Teodor Bercea0034e842019-06-20 18:04:47 +00009797 assert((*Res == OMPDeclareTargetDeclAttr::MT_Link ||
9798 (*Res == OMPDeclareTargetDeclAttr::MT_To &&
9799 HasRequiresUnifiedSharedMemory)) &&
9800 "Expected link clause or to clause with unified memory.");
9801 (void)CGM.getOpenMPRuntime().getAddrOfDeclareTargetVar(VD);
Alexey Bataevbf8fe712018-08-07 16:14:36 +00009802 }
9803 }
9804}
9805
Alexey Bataev60705422018-10-30 15:50:12 +00009806void CGOpenMPRuntime::adjustTargetSpecificDataForLambdas(
9807 CodeGenFunction &CGF, const OMPExecutableDirective &D) const {
9808 assert(isOpenMPTargetExecutionDirective(D.getDirectiveKind()) &&
9809 " Expected target-based directive.");
9810}
9811
Alexey Bataev2d4f80f2020-02-11 15:15:21 -05009812void CGOpenMPRuntime::processRequiresDirective(const OMPRequiresDecl *D) {
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +00009813 for (const OMPClause *Clause : D->clauselists()) {
9814 if (Clause->getClauseKind() == OMPC_unified_shared_memory) {
9815 HasRequiresUnifiedSharedMemory = true;
Alexey Bataev2d4f80f2020-02-11 15:15:21 -05009816 } else if (const auto *AC =
9817 dyn_cast<OMPAtomicDefaultMemOrderClause>(Clause)) {
9818 switch (AC->getAtomicDefaultMemOrderKind()) {
9819 case OMPC_ATOMIC_DEFAULT_MEM_ORDER_acq_rel:
9820 RequiresAtomicOrdering = llvm::AtomicOrdering::AcquireRelease;
9821 break;
9822 case OMPC_ATOMIC_DEFAULT_MEM_ORDER_seq_cst:
9823 RequiresAtomicOrdering = llvm::AtomicOrdering::SequentiallyConsistent;
9824 break;
9825 case OMPC_ATOMIC_DEFAULT_MEM_ORDER_relaxed:
9826 RequiresAtomicOrdering = llvm::AtomicOrdering::Monotonic;
9827 break;
9828 case OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown:
9829 break;
9830 }
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +00009831 }
9832 }
9833}
9834
Alexey Bataev2d4f80f2020-02-11 15:15:21 -05009835llvm::AtomicOrdering CGOpenMPRuntime::getDefaultMemoryOrdering() const {
9836 return RequiresAtomicOrdering;
9837}
9838
Alexey Bataevc5687252019-03-21 19:35:27 +00009839bool CGOpenMPRuntime::hasAllocateAttributeForGlobalVar(const VarDecl *VD,
9840 LangAS &AS) {
9841 if (!VD || !VD->hasAttr<OMPAllocateDeclAttr>())
9842 return false;
9843 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
9844 switch(A->getAllocatorType()) {
9845 case OMPAllocateDeclAttr::OMPDefaultMemAlloc:
9846 // Not supported, fallback to the default mem space.
9847 case OMPAllocateDeclAttr::OMPLargeCapMemAlloc:
9848 case OMPAllocateDeclAttr::OMPCGroupMemAlloc:
9849 case OMPAllocateDeclAttr::OMPHighBWMemAlloc:
9850 case OMPAllocateDeclAttr::OMPLowLatMemAlloc:
9851 case OMPAllocateDeclAttr::OMPThreadMemAlloc:
9852 case OMPAllocateDeclAttr::OMPConstMemAlloc:
9853 case OMPAllocateDeclAttr::OMPPTeamMemAlloc:
9854 AS = LangAS::Default;
9855 return true;
9856 case OMPAllocateDeclAttr::OMPUserDefinedMemAlloc:
9857 llvm_unreachable("Expected predefined allocator for the variables with the "
9858 "static storage.");
9859 }
9860 return false;
9861}
9862
Gheorghe-Teodor Bercea5254f0a2019-06-14 17:58:26 +00009863bool CGOpenMPRuntime::hasRequiresUnifiedSharedMemory() const {
9864 return HasRequiresUnifiedSharedMemory;
9865}
9866
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00009867CGOpenMPRuntime::DisableAutoDeclareTargetRAII::DisableAutoDeclareTargetRAII(
9868 CodeGenModule &CGM)
9869 : CGM(CGM) {
9870 if (CGM.getLangOpts().OpenMPIsDevice) {
9871 SavedShouldMarkAsGlobal = CGM.getOpenMPRuntime().ShouldMarkAsGlobal;
9872 CGM.getOpenMPRuntime().ShouldMarkAsGlobal = false;
9873 }
9874}
9875
9876CGOpenMPRuntime::DisableAutoDeclareTargetRAII::~DisableAutoDeclareTargetRAII() {
9877 if (CGM.getLangOpts().OpenMPIsDevice)
9878 CGM.getOpenMPRuntime().ShouldMarkAsGlobal = SavedShouldMarkAsGlobal;
9879}
9880
Alexey Bataev6d944102018-05-02 15:45:28 +00009881bool CGOpenMPRuntime::markAsGlobalTarget(GlobalDecl GD) {
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00009882 if (!CGM.getLangOpts().OpenMPIsDevice || !ShouldMarkAsGlobal)
9883 return true;
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00009884
Alexey Bataev6d944102018-05-02 15:45:28 +00009885 const auto *D = cast<FunctionDecl>(GD.getDecl());
Alexey Bataev34f8a702018-03-28 14:28:54 +00009886 // Do not to emit function if it is marked as declare target as it was already
9887 // emitted.
Alexey Bataev97b72212018-08-14 18:31:20 +00009888 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(D)) {
Alexey Bataev45588422020-01-07 14:11:45 -05009889 if (D->hasBody() && AlreadyEmittedTargetDecls.count(D) == 0) {
9890 if (auto *F = dyn_cast_or_null<llvm::Function>(
9891 CGM.GetGlobalValue(CGM.getMangledName(GD))))
Alexey Bataev34f8a702018-03-28 14:28:54 +00009892 return !F->isDeclaration();
9893 return false;
9894 }
9895 return true;
9896 }
9897
Alexey Bataev45588422020-01-07 14:11:45 -05009898 return !AlreadyEmittedTargetDecls.insert(D).second;
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00009899}
9900
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +00009901llvm::Function *CGOpenMPRuntime::emitRequiresDirectiveRegFun() {
9902 // If we don't have entries or if we are emitting code for the device, we
9903 // don't need to do anything.
9904 if (CGM.getLangOpts().OMPTargetTriples.empty() ||
9905 CGM.getLangOpts().OpenMPSimd || CGM.getLangOpts().OpenMPIsDevice ||
9906 (OffloadEntriesInfoManager.empty() &&
9907 !HasEmittedDeclareTargetRegion &&
9908 !HasEmittedTargetRegion))
9909 return nullptr;
9910
9911 // Create and register the function that handles the requires directives.
9912 ASTContext &C = CGM.getContext();
9913
9914 llvm::Function *RequiresRegFn;
9915 {
9916 CodeGenFunction CGF(CGM);
9917 const auto &FI = CGM.getTypes().arrangeNullaryFunction();
9918 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
9919 std::string ReqName = getName({"omp_offloading", "requires_reg"});
9920 RequiresRegFn = CGM.CreateGlobalInitOrDestructFunction(FTy, ReqName, FI);
9921 CGF.StartFunction(GlobalDecl(), C.VoidTy, RequiresRegFn, FI, {});
9922 OpenMPOffloadingRequiresDirFlags Flags = OMP_REQ_NONE;
9923 // TODO: check for other requires clauses.
9924 // The requires directive takes effect only when a target region is
9925 // present in the compilation unit. Otherwise it is ignored and not
9926 // passed to the runtime. This avoids the runtime from throwing an error
9927 // for mismatching requires clauses across compilation units that don't
9928 // contain at least 1 target region.
9929 assert((HasEmittedTargetRegion ||
9930 HasEmittedDeclareTargetRegion ||
9931 !OffloadEntriesInfoManager.empty()) &&
9932 "Target or declare target region expected.");
9933 if (HasRequiresUnifiedSharedMemory)
9934 Flags = OMP_REQ_UNIFIED_SHARED_MEMORY;
9935 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__tgt_register_requires),
9936 llvm::ConstantInt::get(CGM.Int64Ty, Flags));
9937 CGF.FinishFunction();
9938 }
9939 return RequiresRegFn;
9940}
9941
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00009942void CGOpenMPRuntime::emitTeamsCall(CodeGenFunction &CGF,
9943 const OMPExecutableDirective &D,
9944 SourceLocation Loc,
James Y Knight9871db02019-02-05 16:42:33 +00009945 llvm::Function *OutlinedFn,
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00009946 ArrayRef<llvm::Value *> CapturedVars) {
9947 if (!CGF.HaveInsertPoint())
9948 return;
9949
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009950 llvm::Value *RTLoc = emitUpdateLocation(CGF, Loc);
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00009951 CodeGenFunction::RunCleanupsScope Scope(CGF);
9952
9953 // Build call __kmpc_fork_teams(loc, n, microtask, var1, .., varn);
9954 llvm::Value *Args[] = {
9955 RTLoc,
9956 CGF.Builder.getInt32(CapturedVars.size()), // Number of captured vars
9957 CGF.Builder.CreateBitCast(OutlinedFn, getKmpc_MicroPointerTy())};
9958 llvm::SmallVector<llvm::Value *, 16> RealArgs;
9959 RealArgs.append(std::begin(Args), std::end(Args));
9960 RealArgs.append(CapturedVars.begin(), CapturedVars.end());
9961
James Y Knight9871db02019-02-05 16:42:33 +00009962 llvm::FunctionCallee RTLFn = createRuntimeFunction(OMPRTL__kmpc_fork_teams);
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00009963 CGF.EmitRuntimeCall(RTLFn, RealArgs);
9964}
9965
9966void CGOpenMPRuntime::emitNumTeamsClause(CodeGenFunction &CGF,
Carlo Bertollic6872252016-04-04 15:55:02 +00009967 const Expr *NumTeams,
9968 const Expr *ThreadLimit,
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00009969 SourceLocation Loc) {
9970 if (!CGF.HaveInsertPoint())
9971 return;
9972
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009973 llvm::Value *RTLoc = emitUpdateLocation(CGF, Loc);
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00009974
Carlo Bertollic6872252016-04-04 15:55:02 +00009975 llvm::Value *NumTeamsVal =
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009976 NumTeams
Carlo Bertollic6872252016-04-04 15:55:02 +00009977 ? CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(NumTeams),
9978 CGF.CGM.Int32Ty, /* isSigned = */ true)
9979 : CGF.Builder.getInt32(0);
9980
9981 llvm::Value *ThreadLimitVal =
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009982 ThreadLimit
Carlo Bertollic6872252016-04-04 15:55:02 +00009983 ? CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(ThreadLimit),
9984 CGF.CGM.Int32Ty, /* isSigned = */ true)
9985 : CGF.Builder.getInt32(0);
9986
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00009987 // Build call __kmpc_push_num_teamss(&loc, global_tid, num_teams, thread_limit)
Carlo Bertollic6872252016-04-04 15:55:02 +00009988 llvm::Value *PushNumTeamsArgs[] = {RTLoc, getThreadID(CGF, Loc), NumTeamsVal,
9989 ThreadLimitVal};
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00009990 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_push_num_teams),
9991 PushNumTeamsArgs);
9992}
Samuel Antaodf158d52016-04-27 22:58:19 +00009993
Samuel Antaocc10b852016-07-28 14:23:26 +00009994void CGOpenMPRuntime::emitTargetDataCalls(
9995 CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond,
9996 const Expr *Device, const RegionCodeGenTy &CodeGen, TargetDataInfo &Info) {
Samuel Antaodf158d52016-04-27 22:58:19 +00009997 if (!CGF.HaveInsertPoint())
9998 return;
9999
Samuel Antaocc10b852016-07-28 14:23:26 +000010000 // Action used to replace the default codegen action and turn privatization
10001 // off.
10002 PrePostActionTy NoPrivAction;
Samuel Antaodf158d52016-04-27 22:58:19 +000010003
10004 // Generate the code for the opening of the data environment. Capture all the
10005 // arguments of the runtime call by reference because they are used in the
10006 // closing of the region.
Alexey Bataevd2202ca2017-12-27 17:58:32 +000010007 auto &&BeginThenGen = [this, &D, Device, &Info,
10008 &CodeGen](CodeGenFunction &CGF, PrePostActionTy &) {
Samuel Antaodf158d52016-04-27 22:58:19 +000010009 // Fill up the arrays with all the mapped variables.
Samuel Antaocc10b852016-07-28 14:23:26 +000010010 MappableExprsHandler::MapBaseValuesArrayTy BasePointers;
Samuel Antaodf158d52016-04-27 22:58:19 +000010011 MappableExprsHandler::MapValuesArrayTy Pointers;
10012 MappableExprsHandler::MapValuesArrayTy Sizes;
10013 MappableExprsHandler::MapFlagsArrayTy MapTypes;
10014
10015 // Get map clause information.
10016 MappableExprsHandler MCHandler(D, CGF);
10017 MCHandler.generateAllInfo(BasePointers, Pointers, Sizes, MapTypes);
Samuel Antaodf158d52016-04-27 22:58:19 +000010018
10019 // Fill up the arrays and create the arguments.
Samuel Antaocc10b852016-07-28 14:23:26 +000010020 emitOffloadingArrays(CGF, BasePointers, Pointers, Sizes, MapTypes, Info);
Samuel Antaodf158d52016-04-27 22:58:19 +000010021
10022 llvm::Value *BasePointersArrayArg = nullptr;
10023 llvm::Value *PointersArrayArg = nullptr;
10024 llvm::Value *SizesArrayArg = nullptr;
10025 llvm::Value *MapTypesArrayArg = nullptr;
10026 emitOffloadingArraysArgument(CGF, BasePointersArrayArg, PointersArrayArg,
Samuel Antaocc10b852016-07-28 14:23:26 +000010027 SizesArrayArg, MapTypesArrayArg, Info);
Samuel Antaodf158d52016-04-27 22:58:19 +000010028
10029 // Emit device ID if any.
10030 llvm::Value *DeviceID = nullptr;
George Rokos63bc9d62017-11-21 18:25:12 +000010031 if (Device) {
Samuel Antaodf158d52016-04-27 22:58:19 +000010032 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
George Rokos63bc9d62017-11-21 18:25:12 +000010033 CGF.Int64Ty, /*isSigned=*/true);
10034 } else {
10035 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
10036 }
Samuel Antaodf158d52016-04-27 22:58:19 +000010037
10038 // Emit the number of elements in the offloading arrays.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010039 llvm::Value *PointerNum = CGF.Builder.getInt32(Info.NumberOfPtrs);
Samuel Antaodf158d52016-04-27 22:58:19 +000010040
10041 llvm::Value *OffloadingArgs[] = {
10042 DeviceID, PointerNum, BasePointersArrayArg,
10043 PointersArrayArg, SizesArrayArg, MapTypesArrayArg};
Alexey Bataevd2202ca2017-12-27 17:58:32 +000010044 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__tgt_target_data_begin),
Samuel Antaodf158d52016-04-27 22:58:19 +000010045 OffloadingArgs);
Samuel Antaocc10b852016-07-28 14:23:26 +000010046
10047 // If device pointer privatization is required, emit the body of the region
10048 // here. It will have to be duplicated: with and without privatization.
10049 if (!Info.CaptureDeviceAddrMap.empty())
10050 CodeGen(CGF);
Samuel Antaodf158d52016-04-27 22:58:19 +000010051 };
10052
10053 // Generate code for the closing of the data region.
Alexey Bataevd2202ca2017-12-27 17:58:32 +000010054 auto &&EndThenGen = [this, Device, &Info](CodeGenFunction &CGF,
10055 PrePostActionTy &) {
Samuel Antaocc10b852016-07-28 14:23:26 +000010056 assert(Info.isValid() && "Invalid data environment closing arguments.");
Samuel Antaodf158d52016-04-27 22:58:19 +000010057
10058 llvm::Value *BasePointersArrayArg = nullptr;
10059 llvm::Value *PointersArrayArg = nullptr;
10060 llvm::Value *SizesArrayArg = nullptr;
10061 llvm::Value *MapTypesArrayArg = nullptr;
10062 emitOffloadingArraysArgument(CGF, BasePointersArrayArg, PointersArrayArg,
Samuel Antaocc10b852016-07-28 14:23:26 +000010063 SizesArrayArg, MapTypesArrayArg, Info);
Samuel Antaodf158d52016-04-27 22:58:19 +000010064
10065 // Emit device ID if any.
10066 llvm::Value *DeviceID = nullptr;
George Rokos63bc9d62017-11-21 18:25:12 +000010067 if (Device) {
Samuel Antaodf158d52016-04-27 22:58:19 +000010068 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
George Rokos63bc9d62017-11-21 18:25:12 +000010069 CGF.Int64Ty, /*isSigned=*/true);
10070 } else {
10071 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
10072 }
Samuel Antaodf158d52016-04-27 22:58:19 +000010073
10074 // Emit the number of elements in the offloading arrays.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010075 llvm::Value *PointerNum = CGF.Builder.getInt32(Info.NumberOfPtrs);
Samuel Antaodf158d52016-04-27 22:58:19 +000010076
10077 llvm::Value *OffloadingArgs[] = {
10078 DeviceID, PointerNum, BasePointersArrayArg,
10079 PointersArrayArg, SizesArrayArg, MapTypesArrayArg};
Alexey Bataevd2202ca2017-12-27 17:58:32 +000010080 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__tgt_target_data_end),
Samuel Antaodf158d52016-04-27 22:58:19 +000010081 OffloadingArgs);
10082 };
10083
Samuel Antaocc10b852016-07-28 14:23:26 +000010084 // If we need device pointer privatization, we need to emit the body of the
10085 // region with no privatization in the 'else' branch of the conditional.
10086 // Otherwise, we don't have to do anything.
10087 auto &&BeginElseGen = [&Info, &CodeGen, &NoPrivAction](CodeGenFunction &CGF,
10088 PrePostActionTy &) {
10089 if (!Info.CaptureDeviceAddrMap.empty()) {
10090 CodeGen.setAction(NoPrivAction);
10091 CodeGen(CGF);
10092 }
10093 };
10094
10095 // We don't have to do anything to close the region if the if clause evaluates
10096 // to false.
10097 auto &&EndElseGen = [](CodeGenFunction &CGF, PrePostActionTy &) {};
Samuel Antaodf158d52016-04-27 22:58:19 +000010098
10099 if (IfCond) {
Alexey Bataev1d943ae2019-11-19 12:12:23 -050010100 emitIfClause(CGF, IfCond, BeginThenGen, BeginElseGen);
Samuel Antaodf158d52016-04-27 22:58:19 +000010101 } else {
Samuel Antaocc10b852016-07-28 14:23:26 +000010102 RegionCodeGenTy RCG(BeginThenGen);
10103 RCG(CGF);
Samuel Antaodf158d52016-04-27 22:58:19 +000010104 }
10105
Samuel Antaocc10b852016-07-28 14:23:26 +000010106 // If we don't require privatization of device pointers, we emit the body in
10107 // between the runtime calls. This avoids duplicating the body code.
10108 if (Info.CaptureDeviceAddrMap.empty()) {
10109 CodeGen.setAction(NoPrivAction);
10110 CodeGen(CGF);
10111 }
Samuel Antaodf158d52016-04-27 22:58:19 +000010112
10113 if (IfCond) {
Alexey Bataev1d943ae2019-11-19 12:12:23 -050010114 emitIfClause(CGF, IfCond, EndThenGen, EndElseGen);
Samuel Antaodf158d52016-04-27 22:58:19 +000010115 } else {
Samuel Antaocc10b852016-07-28 14:23:26 +000010116 RegionCodeGenTy RCG(EndThenGen);
10117 RCG(CGF);
Samuel Antaodf158d52016-04-27 22:58:19 +000010118 }
10119}
Samuel Antaobd0ae2e2016-04-27 23:07:29 +000010120
Samuel Antao8d2d7302016-05-26 18:30:22 +000010121void CGOpenMPRuntime::emitTargetDataStandAloneCall(
Samuel Antao8dd66282016-04-27 23:14:30 +000010122 CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond,
10123 const Expr *Device) {
Samuel Antaobd0ae2e2016-04-27 23:07:29 +000010124 if (!CGF.HaveInsertPoint())
10125 return;
10126
Samuel Antao8dd66282016-04-27 23:14:30 +000010127 assert((isa<OMPTargetEnterDataDirective>(D) ||
Samuel Antao8d2d7302016-05-26 18:30:22 +000010128 isa<OMPTargetExitDataDirective>(D) ||
10129 isa<OMPTargetUpdateDirective>(D)) &&
10130 "Expecting either target enter, exit data, or update directives.");
Samuel Antao8dd66282016-04-27 23:14:30 +000010131
Alexey Bataevd2202ca2017-12-27 17:58:32 +000010132 CodeGenFunction::OMPTargetDataInfo InputInfo;
10133 llvm::Value *MapTypesArray = nullptr;
Samuel Antaobd0ae2e2016-04-27 23:07:29 +000010134 // Generate the code for the opening of the data environment.
Alexey Bataevd2202ca2017-12-27 17:58:32 +000010135 auto &&ThenGen = [this, &D, Device, &InputInfo,
10136 &MapTypesArray](CodeGenFunction &CGF, PrePostActionTy &) {
Samuel Antaobd0ae2e2016-04-27 23:07:29 +000010137 // Emit device ID if any.
10138 llvm::Value *DeviceID = nullptr;
George Rokos63bc9d62017-11-21 18:25:12 +000010139 if (Device) {
Samuel Antaobd0ae2e2016-04-27 23:07:29 +000010140 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
George Rokos63bc9d62017-11-21 18:25:12 +000010141 CGF.Int64Ty, /*isSigned=*/true);
10142 } else {
10143 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
10144 }
Samuel Antaobd0ae2e2016-04-27 23:07:29 +000010145
10146 // Emit the number of elements in the offloading arrays.
Alexey Bataevd2202ca2017-12-27 17:58:32 +000010147 llvm::Constant *PointerNum =
10148 CGF.Builder.getInt32(InputInfo.NumberOfTargetItems);
Samuel Antaobd0ae2e2016-04-27 23:07:29 +000010149
Alexey Bataevd2202ca2017-12-27 17:58:32 +000010150 llvm::Value *OffloadingArgs[] = {DeviceID,
10151 PointerNum,
10152 InputInfo.BasePointersArray.getPointer(),
10153 InputInfo.PointersArray.getPointer(),
10154 InputInfo.SizesArray.getPointer(),
10155 MapTypesArray};
Samuel Antao8d2d7302016-05-26 18:30:22 +000010156
Samuel Antao8d2d7302016-05-26 18:30:22 +000010157 // Select the right runtime function call for each expected standalone
10158 // directive.
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +000010159 const bool HasNowait = D.hasClausesOfKind<OMPNowaitClause>();
Samuel Antao8d2d7302016-05-26 18:30:22 +000010160 OpenMPRTLFunction RTLFn;
10161 switch (D.getDirectiveKind()) {
Samuel Antao8d2d7302016-05-26 18:30:22 +000010162 case OMPD_target_enter_data:
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +000010163 RTLFn = HasNowait ? OMPRTL__tgt_target_data_begin_nowait
10164 : OMPRTL__tgt_target_data_begin;
Samuel Antao8d2d7302016-05-26 18:30:22 +000010165 break;
10166 case OMPD_target_exit_data:
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +000010167 RTLFn = HasNowait ? OMPRTL__tgt_target_data_end_nowait
10168 : OMPRTL__tgt_target_data_end;
Samuel Antao8d2d7302016-05-26 18:30:22 +000010169 break;
10170 case OMPD_target_update:
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +000010171 RTLFn = HasNowait ? OMPRTL__tgt_target_data_update_nowait
10172 : OMPRTL__tgt_target_data_update;
Samuel Antao8d2d7302016-05-26 18:30:22 +000010173 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010174 case OMPD_parallel:
10175 case OMPD_for:
10176 case OMPD_parallel_for:
cchen47d60942019-12-05 13:43:48 -050010177 case OMPD_parallel_master:
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010178 case OMPD_parallel_sections:
10179 case OMPD_for_simd:
10180 case OMPD_parallel_for_simd:
10181 case OMPD_cancel:
10182 case OMPD_cancellation_point:
10183 case OMPD_ordered:
10184 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +000010185 case OMPD_allocate:
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010186 case OMPD_task:
10187 case OMPD_simd:
10188 case OMPD_sections:
10189 case OMPD_section:
10190 case OMPD_single:
10191 case OMPD_master:
10192 case OMPD_critical:
10193 case OMPD_taskyield:
10194 case OMPD_barrier:
10195 case OMPD_taskwait:
10196 case OMPD_taskgroup:
10197 case OMPD_atomic:
10198 case OMPD_flush:
10199 case OMPD_teams:
10200 case OMPD_target_data:
10201 case OMPD_distribute:
10202 case OMPD_distribute_simd:
10203 case OMPD_distribute_parallel_for:
10204 case OMPD_distribute_parallel_for_simd:
10205 case OMPD_teams_distribute:
10206 case OMPD_teams_distribute_simd:
10207 case OMPD_teams_distribute_parallel_for:
10208 case OMPD_teams_distribute_parallel_for_simd:
10209 case OMPD_declare_simd:
Alexey Bataevd158cf62019-09-13 20:18:17 +000010210 case OMPD_declare_variant:
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010211 case OMPD_declare_target:
10212 case OMPD_end_declare_target:
10213 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +000010214 case OMPD_declare_mapper:
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010215 case OMPD_taskloop:
10216 case OMPD_taskloop_simd:
Alexey Bataev60e51c42019-10-10 20:13:02 +000010217 case OMPD_master_taskloop:
Alexey Bataevb8552ab2019-10-18 16:47:35 +000010218 case OMPD_master_taskloop_simd:
Alexey Bataev5bbcead2019-10-14 17:17:41 +000010219 case OMPD_parallel_master_taskloop:
Alexey Bataev14a388f2019-10-25 10:27:13 -040010220 case OMPD_parallel_master_taskloop_simd:
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010221 case OMPD_target:
10222 case OMPD_target_simd:
10223 case OMPD_target_teams_distribute:
10224 case OMPD_target_teams_distribute_simd:
10225 case OMPD_target_teams_distribute_parallel_for:
10226 case OMPD_target_teams_distribute_parallel_for_simd:
10227 case OMPD_target_teams:
10228 case OMPD_target_parallel:
10229 case OMPD_target_parallel_for:
10230 case OMPD_target_parallel_for_simd:
Kelvin Li1408f912018-09-26 04:28:39 +000010231 case OMPD_requires:
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010232 case OMPD_unknown:
10233 llvm_unreachable("Unexpected standalone target data directive.");
10234 break;
Samuel Antao8d2d7302016-05-26 18:30:22 +000010235 }
Alexey Bataevd2202ca2017-12-27 17:58:32 +000010236 CGF.EmitRuntimeCall(createRuntimeFunction(RTLFn), OffloadingArgs);
Samuel Antaobd0ae2e2016-04-27 23:07:29 +000010237 };
10238
Alexey Bataevd2202ca2017-12-27 17:58:32 +000010239 auto &&TargetThenGen = [this, &ThenGen, &D, &InputInfo, &MapTypesArray](
10240 CodeGenFunction &CGF, PrePostActionTy &) {
10241 // Fill up the arrays with all the mapped variables.
10242 MappableExprsHandler::MapBaseValuesArrayTy BasePointers;
10243 MappableExprsHandler::MapValuesArrayTy Pointers;
10244 MappableExprsHandler::MapValuesArrayTy Sizes;
10245 MappableExprsHandler::MapFlagsArrayTy MapTypes;
Samuel Antaobd0ae2e2016-04-27 23:07:29 +000010246
Alexey Bataevd2202ca2017-12-27 17:58:32 +000010247 // Get map clause information.
10248 MappableExprsHandler MEHandler(D, CGF);
10249 MEHandler.generateAllInfo(BasePointers, Pointers, Sizes, MapTypes);
10250
10251 TargetDataInfo Info;
10252 // Fill up the arrays and create the arguments.
10253 emitOffloadingArrays(CGF, BasePointers, Pointers, Sizes, MapTypes, Info);
10254 emitOffloadingArraysArgument(CGF, Info.BasePointersArray,
10255 Info.PointersArray, Info.SizesArray,
10256 Info.MapTypesArray, Info);
10257 InputInfo.NumberOfTargetItems = Info.NumberOfPtrs;
10258 InputInfo.BasePointersArray =
10259 Address(Info.BasePointersArray, CGM.getPointerAlign());
10260 InputInfo.PointersArray =
10261 Address(Info.PointersArray, CGM.getPointerAlign());
10262 InputInfo.SizesArray =
10263 Address(Info.SizesArray, CGM.getPointerAlign());
10264 MapTypesArray = Info.MapTypesArray;
10265 if (D.hasClausesOfKind<OMPDependClause>())
10266 CGF.EmitOMPTargetTaskBasedDirective(D, ThenGen, InputInfo);
10267 else
Alexey Bataev768f1f22018-01-09 19:59:25 +000010268 emitInlinedDirective(CGF, D.getDirectiveKind(), ThenGen);
Alexey Bataevd2202ca2017-12-27 17:58:32 +000010269 };
10270
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010271 if (IfCond) {
Alexey Bataev1d943ae2019-11-19 12:12:23 -050010272 emitIfClause(CGF, IfCond, TargetThenGen,
10273 [](CodeGenFunction &CGF, PrePostActionTy &) {});
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010274 } else {
Alexey Bataevd2202ca2017-12-27 17:58:32 +000010275 RegionCodeGenTy ThenRCG(TargetThenGen);
10276 ThenRCG(CGF);
Samuel Antaobd0ae2e2016-04-27 23:07:29 +000010277 }
10278}
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010279
10280namespace {
10281 /// Kind of parameter in a function with 'declare simd' directive.
10282 enum ParamKindTy { LinearWithVarStride, Linear, Uniform, Vector };
10283 /// Attribute set of the parameter.
10284 struct ParamAttrTy {
10285 ParamKindTy Kind = Vector;
10286 llvm::APSInt StrideOrArg;
10287 llvm::APSInt Alignment;
10288 };
10289} // namespace
10290
10291static unsigned evaluateCDTSize(const FunctionDecl *FD,
10292 ArrayRef<ParamAttrTy> ParamAttrs) {
10293 // Every vector variant of a SIMD-enabled function has a vector length (VLEN).
10294 // If OpenMP clause "simdlen" is used, the VLEN is the value of the argument
10295 // of that clause. The VLEN value must be power of 2.
10296 // In other case the notion of the function`s "characteristic data type" (CDT)
10297 // is used to compute the vector length.
10298 // CDT is defined in the following order:
10299 // a) For non-void function, the CDT is the return type.
10300 // b) If the function has any non-uniform, non-linear parameters, then the
10301 // CDT is the type of the first such parameter.
10302 // c) If the CDT determined by a) or b) above is struct, union, or class
10303 // type which is pass-by-value (except for the type that maps to the
10304 // built-in complex data type), the characteristic data type is int.
10305 // d) If none of the above three cases is applicable, the CDT is int.
10306 // The VLEN is then determined based on the CDT and the size of vector
10307 // register of that ISA for which current vector version is generated. The
10308 // VLEN is computed using the formula below:
10309 // VLEN = sizeof(vector_register) / sizeof(CDT),
10310 // where vector register size specified in section 3.2.1 Registers and the
10311 // Stack Frame of original AMD64 ABI document.
10312 QualType RetType = FD->getReturnType();
10313 if (RetType.isNull())
10314 return 0;
10315 ASTContext &C = FD->getASTContext();
10316 QualType CDT;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010317 if (!RetType.isNull() && !RetType->isVoidType()) {
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010318 CDT = RetType;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010319 } else {
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010320 unsigned Offset = 0;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010321 if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010322 if (ParamAttrs[Offset].Kind == Vector)
10323 CDT = C.getPointerType(C.getRecordType(MD->getParent()));
10324 ++Offset;
10325 }
10326 if (CDT.isNull()) {
10327 for (unsigned I = 0, E = FD->getNumParams(); I < E; ++I) {
10328 if (ParamAttrs[I + Offset].Kind == Vector) {
10329 CDT = FD->getParamDecl(I)->getType();
10330 break;
10331 }
10332 }
10333 }
10334 }
10335 if (CDT.isNull())
10336 CDT = C.IntTy;
10337 CDT = CDT->getCanonicalTypeUnqualified();
10338 if (CDT->isRecordType() || CDT->isUnionType())
10339 CDT = C.IntTy;
10340 return C.getTypeSize(CDT);
10341}
10342
10343static void
10344emitX86DeclareSimdFunction(const FunctionDecl *FD, llvm::Function *Fn,
Benjamin Kramer81cb4b72016-11-24 16:01:20 +000010345 const llvm::APSInt &VLENVal,
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010346 ArrayRef<ParamAttrTy> ParamAttrs,
10347 OMPDeclareSimdDeclAttr::BranchStateTy State) {
10348 struct ISADataTy {
10349 char ISA;
10350 unsigned VecRegSize;
10351 };
10352 ISADataTy ISAData[] = {
10353 {
10354 'b', 128
10355 }, // SSE
10356 {
10357 'c', 256
10358 }, // AVX
10359 {
10360 'd', 256
10361 }, // AVX2
10362 {
10363 'e', 512
10364 }, // AVX512
10365 };
10366 llvm::SmallVector<char, 2> Masked;
10367 switch (State) {
10368 case OMPDeclareSimdDeclAttr::BS_Undefined:
10369 Masked.push_back('N');
10370 Masked.push_back('M');
10371 break;
10372 case OMPDeclareSimdDeclAttr::BS_Notinbranch:
10373 Masked.push_back('N');
10374 break;
10375 case OMPDeclareSimdDeclAttr::BS_Inbranch:
10376 Masked.push_back('M');
10377 break;
10378 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010379 for (char Mask : Masked) {
10380 for (const ISADataTy &Data : ISAData) {
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010381 SmallString<256> Buffer;
10382 llvm::raw_svector_ostream Out(Buffer);
10383 Out << "_ZGV" << Data.ISA << Mask;
10384 if (!VLENVal) {
Simon Pilgrim823a99c2019-05-22 13:02:19 +000010385 unsigned NumElts = evaluateCDTSize(FD, ParamAttrs);
10386 assert(NumElts && "Non-zero simdlen/cdtsize expected");
10387 Out << llvm::APSInt::getUnsigned(Data.VecRegSize / NumElts);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010388 } else {
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010389 Out << VLENVal;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010390 }
10391 for (const ParamAttrTy &ParamAttr : ParamAttrs) {
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010392 switch (ParamAttr.Kind){
10393 case LinearWithVarStride:
10394 Out << 's' << ParamAttr.StrideOrArg;
10395 break;
10396 case Linear:
10397 Out << 'l';
10398 if (!!ParamAttr.StrideOrArg)
10399 Out << ParamAttr.StrideOrArg;
10400 break;
10401 case Uniform:
10402 Out << 'u';
10403 break;
10404 case Vector:
10405 Out << 'v';
10406 break;
10407 }
10408 if (!!ParamAttr.Alignment)
10409 Out << 'a' << ParamAttr.Alignment;
10410 }
10411 Out << '_' << Fn->getName();
10412 Fn->addFnAttr(Out.str());
10413 }
10414 }
10415}
10416
Alexey Bataeva0a22642019-04-16 13:56:21 +000010417// This are the Functions that are needed to mangle the name of the
10418// vector functions generated by the compiler, according to the rules
10419// defined in the "Vector Function ABI specifications for AArch64",
10420// available at
10421// https://developer.arm.com/products/software-development-tools/hpc/arm-compiler-for-hpc/vector-function-abi.
10422
10423/// Maps To Vector (MTV), as defined in 3.1.1 of the AAVFABI.
10424///
10425/// TODO: Need to implement the behavior for reference marked with a
10426/// var or no linear modifiers (1.b in the section). For this, we
10427/// need to extend ParamKindTy to support the linear modifiers.
10428static bool getAArch64MTV(QualType QT, ParamKindTy Kind) {
10429 QT = QT.getCanonicalType();
10430
10431 if (QT->isVoidType())
10432 return false;
10433
10434 if (Kind == ParamKindTy::Uniform)
10435 return false;
10436
10437 if (Kind == ParamKindTy::Linear)
10438 return false;
10439
10440 // TODO: Handle linear references with modifiers
10441
10442 if (Kind == ParamKindTy::LinearWithVarStride)
10443 return false;
10444
10445 return true;
10446}
10447
10448/// Pass By Value (PBV), as defined in 3.1.2 of the AAVFABI.
10449static bool getAArch64PBV(QualType QT, ASTContext &C) {
10450 QT = QT.getCanonicalType();
10451 unsigned Size = C.getTypeSize(QT);
10452
10453 // Only scalars and complex within 16 bytes wide set PVB to true.
10454 if (Size != 8 && Size != 16 && Size != 32 && Size != 64 && Size != 128)
10455 return false;
10456
10457 if (QT->isFloatingType())
10458 return true;
10459
10460 if (QT->isIntegerType())
10461 return true;
10462
10463 if (QT->isPointerType())
10464 return true;
10465
10466 // TODO: Add support for complex types (section 3.1.2, item 2).
10467
10468 return false;
10469}
10470
10471/// Computes the lane size (LS) of a return type or of an input parameter,
10472/// as defined by `LS(P)` in 3.2.1 of the AAVFABI.
10473/// TODO: Add support for references, section 3.2.1, item 1.
10474static unsigned getAArch64LS(QualType QT, ParamKindTy Kind, ASTContext &C) {
10475 if (getAArch64MTV(QT, Kind) && QT.getCanonicalType()->isPointerType()) {
10476 QualType PTy = QT.getCanonicalType()->getPointeeType();
10477 if (getAArch64PBV(PTy, C))
10478 return C.getTypeSize(PTy);
10479 }
10480 if (getAArch64PBV(QT, C))
10481 return C.getTypeSize(QT);
10482
10483 return C.getTypeSize(C.getUIntPtrType());
10484}
10485
10486// Get Narrowest Data Size (NDS) and Widest Data Size (WDS) from the
10487// signature of the scalar function, as defined in 3.2.2 of the
10488// AAVFABI.
10489static std::tuple<unsigned, unsigned, bool>
10490getNDSWDS(const FunctionDecl *FD, ArrayRef<ParamAttrTy> ParamAttrs) {
10491 QualType RetType = FD->getReturnType().getCanonicalType();
10492
10493 ASTContext &C = FD->getASTContext();
10494
10495 bool OutputBecomesInput = false;
10496
10497 llvm::SmallVector<unsigned, 8> Sizes;
10498 if (!RetType->isVoidType()) {
10499 Sizes.push_back(getAArch64LS(RetType, ParamKindTy::Vector, C));
10500 if (!getAArch64PBV(RetType, C) && getAArch64MTV(RetType, {}))
10501 OutputBecomesInput = true;
10502 }
10503 for (unsigned I = 0, E = FD->getNumParams(); I < E; ++I) {
10504 QualType QT = FD->getParamDecl(I)->getType().getCanonicalType();
10505 Sizes.push_back(getAArch64LS(QT, ParamAttrs[I].Kind, C));
10506 }
10507
10508 assert(!Sizes.empty() && "Unable to determine NDS and WDS.");
10509 // The LS of a function parameter / return value can only be a power
10510 // of 2, starting from 8 bits, up to 128.
10511 assert(std::all_of(Sizes.begin(), Sizes.end(),
10512 [](unsigned Size) {
10513 return Size == 8 || Size == 16 || Size == 32 ||
10514 Size == 64 || Size == 128;
10515 }) &&
10516 "Invalid size");
10517
10518 return std::make_tuple(*std::min_element(std::begin(Sizes), std::end(Sizes)),
10519 *std::max_element(std::begin(Sizes), std::end(Sizes)),
10520 OutputBecomesInput);
10521}
10522
10523/// Mangle the parameter part of the vector function name according to
10524/// their OpenMP classification. The mangling function is defined in
10525/// section 3.5 of the AAVFABI.
10526static std::string mangleVectorParameters(ArrayRef<ParamAttrTy> ParamAttrs) {
10527 SmallString<256> Buffer;
10528 llvm::raw_svector_ostream Out(Buffer);
10529 for (const auto &ParamAttr : ParamAttrs) {
10530 switch (ParamAttr.Kind) {
10531 case LinearWithVarStride:
10532 Out << "ls" << ParamAttr.StrideOrArg;
10533 break;
10534 case Linear:
10535 Out << 'l';
10536 // Don't print the step value if it is not present or if it is
10537 // equal to 1.
10538 if (!!ParamAttr.StrideOrArg && ParamAttr.StrideOrArg != 1)
10539 Out << ParamAttr.StrideOrArg;
10540 break;
10541 case Uniform:
10542 Out << 'u';
10543 break;
10544 case Vector:
10545 Out << 'v';
10546 break;
10547 }
10548
10549 if (!!ParamAttr.Alignment)
10550 Out << 'a' << ParamAttr.Alignment;
10551 }
10552
Benjamin Krameradcd0262020-01-28 20:23:46 +010010553 return std::string(Out.str());
Alexey Bataeva0a22642019-04-16 13:56:21 +000010554}
10555
10556// Function used to add the attribute. The parameter `VLEN` is
10557// templated to allow the use of "x" when targeting scalable functions
10558// for SVE.
10559template <typename T>
10560static void addAArch64VectorName(T VLEN, StringRef LMask, StringRef Prefix,
10561 char ISA, StringRef ParSeq,
10562 StringRef MangledName, bool OutputBecomesInput,
10563 llvm::Function *Fn) {
10564 SmallString<256> Buffer;
10565 llvm::raw_svector_ostream Out(Buffer);
10566 Out << Prefix << ISA << LMask << VLEN;
10567 if (OutputBecomesInput)
10568 Out << "v";
10569 Out << ParSeq << "_" << MangledName;
10570 Fn->addFnAttr(Out.str());
10571}
10572
10573// Helper function to generate the Advanced SIMD names depending on
10574// the value of the NDS when simdlen is not present.
10575static void addAArch64AdvSIMDNDSNames(unsigned NDS, StringRef Mask,
10576 StringRef Prefix, char ISA,
10577 StringRef ParSeq, StringRef MangledName,
10578 bool OutputBecomesInput,
10579 llvm::Function *Fn) {
10580 switch (NDS) {
10581 case 8:
10582 addAArch64VectorName(8, Mask, Prefix, ISA, ParSeq, MangledName,
10583 OutputBecomesInput, Fn);
10584 addAArch64VectorName(16, Mask, Prefix, ISA, ParSeq, MangledName,
10585 OutputBecomesInput, Fn);
10586 break;
10587 case 16:
10588 addAArch64VectorName(4, Mask, Prefix, ISA, ParSeq, MangledName,
10589 OutputBecomesInput, Fn);
10590 addAArch64VectorName(8, Mask, Prefix, ISA, ParSeq, MangledName,
10591 OutputBecomesInput, Fn);
10592 break;
10593 case 32:
10594 addAArch64VectorName(2, Mask, Prefix, ISA, ParSeq, MangledName,
10595 OutputBecomesInput, Fn);
10596 addAArch64VectorName(4, Mask, Prefix, ISA, ParSeq, MangledName,
10597 OutputBecomesInput, Fn);
10598 break;
10599 case 64:
10600 case 128:
10601 addAArch64VectorName(2, Mask, Prefix, ISA, ParSeq, MangledName,
10602 OutputBecomesInput, Fn);
10603 break;
10604 default:
10605 llvm_unreachable("Scalar type is too wide.");
10606 }
10607}
10608
10609/// Emit vector function attributes for AArch64, as defined in the AAVFABI.
10610static void emitAArch64DeclareSimdFunction(
10611 CodeGenModule &CGM, const FunctionDecl *FD, unsigned UserVLEN,
10612 ArrayRef<ParamAttrTy> ParamAttrs,
10613 OMPDeclareSimdDeclAttr::BranchStateTy State, StringRef MangledName,
10614 char ISA, unsigned VecRegSize, llvm::Function *Fn, SourceLocation SLoc) {
10615
10616 // Get basic data for building the vector signature.
10617 const auto Data = getNDSWDS(FD, ParamAttrs);
10618 const unsigned NDS = std::get<0>(Data);
10619 const unsigned WDS = std::get<1>(Data);
10620 const bool OutputBecomesInput = std::get<2>(Data);
10621
10622 // Check the values provided via `simdlen` by the user.
10623 // 1. A `simdlen(1)` doesn't produce vector signatures,
10624 if (UserVLEN == 1) {
10625 unsigned DiagID = CGM.getDiags().getCustomDiagID(
10626 DiagnosticsEngine::Warning,
10627 "The clause simdlen(1) has no effect when targeting aarch64.");
10628 CGM.getDiags().Report(SLoc, DiagID);
10629 return;
10630 }
10631
10632 // 2. Section 3.3.1, item 1: user input must be a power of 2 for
10633 // Advanced SIMD output.
10634 if (ISA == 'n' && UserVLEN && !llvm::isPowerOf2_32(UserVLEN)) {
10635 unsigned DiagID = CGM.getDiags().getCustomDiagID(
10636 DiagnosticsEngine::Warning, "The value specified in simdlen must be a "
10637 "power of 2 when targeting Advanced SIMD.");
10638 CGM.getDiags().Report(SLoc, DiagID);
10639 return;
10640 }
10641
10642 // 3. Section 3.4.1. SVE fixed lengh must obey the architectural
10643 // limits.
10644 if (ISA == 's' && UserVLEN != 0) {
10645 if ((UserVLEN * WDS > 2048) || (UserVLEN * WDS % 128 != 0)) {
10646 unsigned DiagID = CGM.getDiags().getCustomDiagID(
10647 DiagnosticsEngine::Warning, "The clause simdlen must fit the %0-bit "
10648 "lanes in the architectural constraints "
10649 "for SVE (min is 128-bit, max is "
10650 "2048-bit, by steps of 128-bit)");
10651 CGM.getDiags().Report(SLoc, DiagID) << WDS;
10652 return;
10653 }
10654 }
10655
10656 // Sort out parameter sequence.
10657 const std::string ParSeq = mangleVectorParameters(ParamAttrs);
10658 StringRef Prefix = "_ZGV";
10659 // Generate simdlen from user input (if any).
10660 if (UserVLEN) {
10661 if (ISA == 's') {
10662 // SVE generates only a masked function.
10663 addAArch64VectorName(UserVLEN, "M", Prefix, ISA, ParSeq, MangledName,
10664 OutputBecomesInput, Fn);
10665 } else {
10666 assert(ISA == 'n' && "Expected ISA either 's' or 'n'.");
10667 // Advanced SIMD generates one or two functions, depending on
10668 // the `[not]inbranch` clause.
10669 switch (State) {
10670 case OMPDeclareSimdDeclAttr::BS_Undefined:
10671 addAArch64VectorName(UserVLEN, "N", Prefix, ISA, ParSeq, MangledName,
10672 OutputBecomesInput, Fn);
10673 addAArch64VectorName(UserVLEN, "M", Prefix, ISA, ParSeq, MangledName,
10674 OutputBecomesInput, Fn);
10675 break;
10676 case OMPDeclareSimdDeclAttr::BS_Notinbranch:
10677 addAArch64VectorName(UserVLEN, "N", Prefix, ISA, ParSeq, MangledName,
10678 OutputBecomesInput, Fn);
10679 break;
10680 case OMPDeclareSimdDeclAttr::BS_Inbranch:
10681 addAArch64VectorName(UserVLEN, "M", Prefix, ISA, ParSeq, MangledName,
10682 OutputBecomesInput, Fn);
10683 break;
10684 }
10685 }
10686 } else {
10687 // If no user simdlen is provided, follow the AAVFABI rules for
10688 // generating the vector length.
10689 if (ISA == 's') {
10690 // SVE, section 3.4.1, item 1.
10691 addAArch64VectorName("x", "M", Prefix, ISA, ParSeq, MangledName,
10692 OutputBecomesInput, Fn);
10693 } else {
10694 assert(ISA == 'n' && "Expected ISA either 's' or 'n'.");
10695 // Advanced SIMD, Section 3.3.1 of the AAVFABI, generates one or
10696 // two vector names depending on the use of the clause
10697 // `[not]inbranch`.
10698 switch (State) {
10699 case OMPDeclareSimdDeclAttr::BS_Undefined:
10700 addAArch64AdvSIMDNDSNames(NDS, "N", Prefix, ISA, ParSeq, MangledName,
10701 OutputBecomesInput, Fn);
10702 addAArch64AdvSIMDNDSNames(NDS, "M", Prefix, ISA, ParSeq, MangledName,
10703 OutputBecomesInput, Fn);
10704 break;
10705 case OMPDeclareSimdDeclAttr::BS_Notinbranch:
10706 addAArch64AdvSIMDNDSNames(NDS, "N", Prefix, ISA, ParSeq, MangledName,
10707 OutputBecomesInput, Fn);
10708 break;
10709 case OMPDeclareSimdDeclAttr::BS_Inbranch:
10710 addAArch64AdvSIMDNDSNames(NDS, "M", Prefix, ISA, ParSeq, MangledName,
10711 OutputBecomesInput, Fn);
10712 break;
10713 }
10714 }
10715 }
10716}
10717
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010718void CGOpenMPRuntime::emitDeclareSimdFunction(const FunctionDecl *FD,
10719 llvm::Function *Fn) {
10720 ASTContext &C = CGM.getContext();
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010721 FD = FD->getMostRecentDecl();
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010722 // Map params to their positions in function decl.
10723 llvm::DenseMap<const Decl *, unsigned> ParamPositions;
10724 if (isa<CXXMethodDecl>(FD))
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010725 ParamPositions.try_emplace(FD, 0);
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010726 unsigned ParamPos = ParamPositions.size();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010727 for (const ParmVarDecl *P : FD->parameters()) {
10728 ParamPositions.try_emplace(P->getCanonicalDecl(), ParamPos);
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010729 ++ParamPos;
10730 }
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010731 while (FD) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010732 for (const auto *Attr : FD->specific_attrs<OMPDeclareSimdDeclAttr>()) {
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010733 llvm::SmallVector<ParamAttrTy, 8> ParamAttrs(ParamPositions.size());
10734 // Mark uniform parameters.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010735 for (const Expr *E : Attr->uniforms()) {
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010736 E = E->IgnoreParenImpCasts();
10737 unsigned Pos;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010738 if (isa<CXXThisExpr>(E)) {
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010739 Pos = ParamPositions[FD];
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010740 } else {
10741 const auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
10742 ->getCanonicalDecl();
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010743 Pos = ParamPositions[PVD];
10744 }
10745 ParamAttrs[Pos].Kind = Uniform;
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010746 }
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010747 // Get alignment info.
10748 auto NI = Attr->alignments_begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010749 for (const Expr *E : Attr->aligneds()) {
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010750 E = E->IgnoreParenImpCasts();
10751 unsigned Pos;
10752 QualType ParmTy;
10753 if (isa<CXXThisExpr>(E)) {
10754 Pos = ParamPositions[FD];
10755 ParmTy = E->getType();
10756 } else {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010757 const auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
10758 ->getCanonicalDecl();
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010759 Pos = ParamPositions[PVD];
10760 ParmTy = PVD->getType();
10761 }
10762 ParamAttrs[Pos].Alignment =
10763 (*NI)
10764 ? (*NI)->EvaluateKnownConstInt(C)
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010765 : llvm::APSInt::getUnsigned(
10766 C.toCharUnitsFromBits(C.getOpenMPDefaultSimdAlign(ParmTy))
10767 .getQuantity());
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010768 ++NI;
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010769 }
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010770 // Mark linear parameters.
10771 auto SI = Attr->steps_begin();
10772 auto MI = Attr->modifiers_begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010773 for (const Expr *E : Attr->linears()) {
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010774 E = E->IgnoreParenImpCasts();
10775 unsigned Pos;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010776 if (isa<CXXThisExpr>(E)) {
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010777 Pos = ParamPositions[FD];
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010778 } else {
10779 const auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
10780 ->getCanonicalDecl();
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010781 Pos = ParamPositions[PVD];
10782 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010783 ParamAttrTy &ParamAttr = ParamAttrs[Pos];
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010784 ParamAttr.Kind = Linear;
10785 if (*SI) {
Fangrui Song407659a2018-11-30 23:41:18 +000010786 Expr::EvalResult Result;
10787 if (!(*SI)->EvaluateAsInt(Result, C, Expr::SE_AllowSideEffects)) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010788 if (const auto *DRE =
10789 cast<DeclRefExpr>((*SI)->IgnoreParenImpCasts())) {
10790 if (const auto *StridePVD = cast<ParmVarDecl>(DRE->getDecl())) {
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010791 ParamAttr.Kind = LinearWithVarStride;
10792 ParamAttr.StrideOrArg = llvm::APSInt::getUnsigned(
10793 ParamPositions[StridePVD->getCanonicalDecl()]);
10794 }
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010795 }
Fangrui Song407659a2018-11-30 23:41:18 +000010796 } else {
10797 ParamAttr.StrideOrArg = Result.Val.getInt();
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010798 }
10799 }
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010800 ++SI;
10801 ++MI;
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010802 }
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010803 llvm::APSInt VLENVal;
Alexey Bataeva0a22642019-04-16 13:56:21 +000010804 SourceLocation ExprLoc;
10805 const Expr *VLENExpr = Attr->getSimdlen();
10806 if (VLENExpr) {
10807 VLENVal = VLENExpr->EvaluateKnownConstInt(C);
10808 ExprLoc = VLENExpr->getExprLoc();
10809 }
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010810 OMPDeclareSimdDeclAttr::BranchStateTy State = Attr->getBranchState();
Jim Linab1bcda2020-01-07 17:32:39 +080010811 if (CGM.getTriple().isX86()) {
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010812 emitX86DeclareSimdFunction(FD, Fn, VLENVal, ParamAttrs, State);
Alexey Bataeva0a22642019-04-16 13:56:21 +000010813 } else if (CGM.getTriple().getArch() == llvm::Triple::aarch64) {
10814 unsigned VLEN = VLENVal.getExtValue();
10815 StringRef MangledName = Fn->getName();
10816 if (CGM.getTarget().hasFeature("sve"))
10817 emitAArch64DeclareSimdFunction(CGM, FD, VLEN, ParamAttrs, State,
10818 MangledName, 's', 128, Fn, ExprLoc);
10819 if (CGM.getTarget().hasFeature("neon"))
10820 emitAArch64DeclareSimdFunction(CGM, FD, VLEN, ParamAttrs, State,
10821 MangledName, 'n', 128, Fn, ExprLoc);
10822 }
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010823 }
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010824 FD = FD->getPreviousDecl();
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010825 }
10826}
Alexey Bataev8b427062016-05-25 12:36:08 +000010827
10828namespace {
10829/// Cleanup action for doacross support.
10830class DoacrossCleanupTy final : public EHScopeStack::Cleanup {
10831public:
10832 static const int DoacrossFinArgs = 2;
10833
10834private:
James Y Knight9871db02019-02-05 16:42:33 +000010835 llvm::FunctionCallee RTLFn;
Alexey Bataev8b427062016-05-25 12:36:08 +000010836 llvm::Value *Args[DoacrossFinArgs];
10837
10838public:
James Y Knight9871db02019-02-05 16:42:33 +000010839 DoacrossCleanupTy(llvm::FunctionCallee RTLFn,
10840 ArrayRef<llvm::Value *> CallArgs)
Alexey Bataev8b427062016-05-25 12:36:08 +000010841 : RTLFn(RTLFn) {
10842 assert(CallArgs.size() == DoacrossFinArgs);
10843 std::copy(CallArgs.begin(), CallArgs.end(), std::begin(Args));
10844 }
10845 void Emit(CodeGenFunction &CGF, Flags /*flags*/) override {
10846 if (!CGF.HaveInsertPoint())
10847 return;
10848 CGF.EmitRuntimeCall(RTLFn, Args);
10849 }
10850};
10851} // namespace
10852
10853void CGOpenMPRuntime::emitDoacrossInit(CodeGenFunction &CGF,
Alexey Bataevf138fda2018-08-13 19:04:24 +000010854 const OMPLoopDirective &D,
10855 ArrayRef<Expr *> NumIterations) {
Alexey Bataev8b427062016-05-25 12:36:08 +000010856 if (!CGF.HaveInsertPoint())
10857 return;
10858
10859 ASTContext &C = CGM.getContext();
10860 QualType Int64Ty = C.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/true);
10861 RecordDecl *RD;
10862 if (KmpDimTy.isNull()) {
10863 // Build struct kmp_dim { // loop bounds info casted to kmp_int64
10864 // kmp_int64 lo; // lower
10865 // kmp_int64 up; // upper
10866 // kmp_int64 st; // stride
10867 // };
10868 RD = C.buildImplicitRecord("kmp_dim");
10869 RD->startDefinition();
10870 addFieldToRecordDecl(C, RD, Int64Ty);
10871 addFieldToRecordDecl(C, RD, Int64Ty);
10872 addFieldToRecordDecl(C, RD, Int64Ty);
10873 RD->completeDefinition();
10874 KmpDimTy = C.getRecordType(RD);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010875 } else {
Alexey Bataev8b427062016-05-25 12:36:08 +000010876 RD = cast<RecordDecl>(KmpDimTy->getAsTagDecl());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010877 }
Alexey Bataevf138fda2018-08-13 19:04:24 +000010878 llvm::APInt Size(/*numBits=*/32, NumIterations.size());
10879 QualType ArrayTy =
Richard Smith772e2662019-10-04 01:25:59 +000010880 C.getConstantArrayType(KmpDimTy, Size, nullptr, ArrayType::Normal, 0);
Alexey Bataev8b427062016-05-25 12:36:08 +000010881
Alexey Bataevf138fda2018-08-13 19:04:24 +000010882 Address DimsAddr = CGF.CreateMemTemp(ArrayTy, "dims");
10883 CGF.EmitNullInitialization(DimsAddr, ArrayTy);
Alexey Bataev8b427062016-05-25 12:36:08 +000010884 enum { LowerFD = 0, UpperFD, StrideFD };
10885 // Fill dims with data.
Alexey Bataevf138fda2018-08-13 19:04:24 +000010886 for (unsigned I = 0, E = NumIterations.size(); I < E; ++I) {
James Y Knight751fe282019-02-09 22:22:28 +000010887 LValue DimsLVal = CGF.MakeAddrLValue(
10888 CGF.Builder.CreateConstArrayGEP(DimsAddr, I), KmpDimTy);
Alexey Bataevf138fda2018-08-13 19:04:24 +000010889 // dims.upper = num_iterations;
10890 LValue UpperLVal = CGF.EmitLValueForField(
10891 DimsLVal, *std::next(RD->field_begin(), UpperFD));
10892 llvm::Value *NumIterVal =
10893 CGF.EmitScalarConversion(CGF.EmitScalarExpr(NumIterations[I]),
10894 D.getNumIterations()->getType(), Int64Ty,
10895 D.getNumIterations()->getExprLoc());
10896 CGF.EmitStoreOfScalar(NumIterVal, UpperLVal);
10897 // dims.stride = 1;
10898 LValue StrideLVal = CGF.EmitLValueForField(
10899 DimsLVal, *std::next(RD->field_begin(), StrideFD));
10900 CGF.EmitStoreOfScalar(llvm::ConstantInt::getSigned(CGM.Int64Ty, /*V=*/1),
10901 StrideLVal);
10902 }
Alexey Bataev8b427062016-05-25 12:36:08 +000010903
10904 // Build call void __kmpc_doacross_init(ident_t *loc, kmp_int32 gtid,
10905 // kmp_int32 num_dims, struct kmp_dim * dims);
Alexey Bataevf138fda2018-08-13 19:04:24 +000010906 llvm::Value *Args[] = {
10907 emitUpdateLocation(CGF, D.getBeginLoc()),
10908 getThreadID(CGF, D.getBeginLoc()),
10909 llvm::ConstantInt::getSigned(CGM.Int32Ty, NumIterations.size()),
10910 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
James Y Knight751fe282019-02-09 22:22:28 +000010911 CGF.Builder.CreateConstArrayGEP(DimsAddr, 0).getPointer(),
Alexey Bataevf138fda2018-08-13 19:04:24 +000010912 CGM.VoidPtrTy)};
Alexey Bataev8b427062016-05-25 12:36:08 +000010913
James Y Knight9871db02019-02-05 16:42:33 +000010914 llvm::FunctionCallee RTLFn =
10915 createRuntimeFunction(OMPRTL__kmpc_doacross_init);
Alexey Bataev8b427062016-05-25 12:36:08 +000010916 CGF.EmitRuntimeCall(RTLFn, Args);
10917 llvm::Value *FiniArgs[DoacrossCleanupTy::DoacrossFinArgs] = {
Stephen Kelly1c301dc2018-08-09 21:09:38 +000010918 emitUpdateLocation(CGF, D.getEndLoc()), getThreadID(CGF, D.getEndLoc())};
James Y Knight9871db02019-02-05 16:42:33 +000010919 llvm::FunctionCallee FiniRTLFn =
10920 createRuntimeFunction(OMPRTL__kmpc_doacross_fini);
Alexey Bataev8b427062016-05-25 12:36:08 +000010921 CGF.EHStack.pushCleanup<DoacrossCleanupTy>(NormalAndEHCleanup, FiniRTLFn,
10922 llvm::makeArrayRef(FiniArgs));
10923}
10924
10925void CGOpenMPRuntime::emitDoacrossOrdered(CodeGenFunction &CGF,
10926 const OMPDependClause *C) {
10927 QualType Int64Ty =
10928 CGM.getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
Alexey Bataevf138fda2018-08-13 19:04:24 +000010929 llvm::APInt Size(/*numBits=*/32, C->getNumLoops());
10930 QualType ArrayTy = CGM.getContext().getConstantArrayType(
Richard Smith772e2662019-10-04 01:25:59 +000010931 Int64Ty, Size, nullptr, ArrayType::Normal, 0);
Alexey Bataevf138fda2018-08-13 19:04:24 +000010932 Address CntAddr = CGF.CreateMemTemp(ArrayTy, ".cnt.addr");
10933 for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I) {
10934 const Expr *CounterVal = C->getLoopData(I);
10935 assert(CounterVal);
10936 llvm::Value *CntVal = CGF.EmitScalarConversion(
10937 CGF.EmitScalarExpr(CounterVal), CounterVal->getType(), Int64Ty,
10938 CounterVal->getExprLoc());
James Y Knight751fe282019-02-09 22:22:28 +000010939 CGF.EmitStoreOfScalar(CntVal, CGF.Builder.CreateConstArrayGEP(CntAddr, I),
10940 /*Volatile=*/false, Int64Ty);
Alexey Bataevf138fda2018-08-13 19:04:24 +000010941 }
10942 llvm::Value *Args[] = {
10943 emitUpdateLocation(CGF, C->getBeginLoc()),
10944 getThreadID(CGF, C->getBeginLoc()),
James Y Knight751fe282019-02-09 22:22:28 +000010945 CGF.Builder.CreateConstArrayGEP(CntAddr, 0).getPointer()};
James Y Knight9871db02019-02-05 16:42:33 +000010946 llvm::FunctionCallee RTLFn;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010947 if (C->getDependencyKind() == OMPC_DEPEND_source) {
Alexey Bataev8b427062016-05-25 12:36:08 +000010948 RTLFn = createRuntimeFunction(OMPRTL__kmpc_doacross_post);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010949 } else {
Alexey Bataev8b427062016-05-25 12:36:08 +000010950 assert(C->getDependencyKind() == OMPC_DEPEND_sink);
10951 RTLFn = createRuntimeFunction(OMPRTL__kmpc_doacross_wait);
10952 }
10953 CGF.EmitRuntimeCall(RTLFn, Args);
10954}
10955
Alexey Bataev7ef47a62018-02-22 18:33:31 +000010956void CGOpenMPRuntime::emitCall(CodeGenFunction &CGF, SourceLocation Loc,
James Y Knight9871db02019-02-05 16:42:33 +000010957 llvm::FunctionCallee Callee,
Alexey Bataev7ef47a62018-02-22 18:33:31 +000010958 ArrayRef<llvm::Value *> Args) const {
10959 assert(Loc.isValid() && "Outlined function call location must be valid.");
Alexey Bataev3c595a62017-08-14 15:01:03 +000010960 auto DL = ApplyDebugLocation::CreateDefaultArtificial(CGF, Loc);
10961
James Y Knight9871db02019-02-05 16:42:33 +000010962 if (auto *Fn = dyn_cast<llvm::Function>(Callee.getCallee())) {
Alexey Bataev2c7eee52017-08-04 19:10:54 +000010963 if (Fn->doesNotThrow()) {
Alexey Bataev3c595a62017-08-14 15:01:03 +000010964 CGF.EmitNounwindRuntimeCall(Fn, Args);
Alexey Bataev2c7eee52017-08-04 19:10:54 +000010965 return;
10966 }
10967 }
Alexey Bataev3c595a62017-08-14 15:01:03 +000010968 CGF.EmitRuntimeCall(Callee, Args);
10969}
10970
10971void CGOpenMPRuntime::emitOutlinedFunctionCall(
James Y Knight9871db02019-02-05 16:42:33 +000010972 CodeGenFunction &CGF, SourceLocation Loc, llvm::FunctionCallee OutlinedFn,
Alexey Bataev3c595a62017-08-14 15:01:03 +000010973 ArrayRef<llvm::Value *> Args) const {
Alexey Bataev7ef47a62018-02-22 18:33:31 +000010974 emitCall(CGF, Loc, OutlinedFn, Args);
Alexey Bataev2c7eee52017-08-04 19:10:54 +000010975}
Alexey Bataev3b8d5582017-08-08 18:04:06 +000010976
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +000010977void CGOpenMPRuntime::emitFunctionProlog(CodeGenFunction &CGF, const Decl *D) {
10978 if (const auto *FD = dyn_cast<FunctionDecl>(D))
10979 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD))
10980 HasEmittedDeclareTargetRegion = true;
10981}
10982
Alexey Bataev3b8d5582017-08-08 18:04:06 +000010983Address CGOpenMPRuntime::getParameterAddress(CodeGenFunction &CGF,
10984 const VarDecl *NativeParam,
10985 const VarDecl *TargetParam) const {
10986 return CGF.GetAddrOfLocalVar(NativeParam);
10987}
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000010988
Alexey Bataev4f680db2019-03-19 16:41:16 +000010989namespace {
10990/// Cleanup action for allocate support.
10991class OMPAllocateCleanupTy final : public EHScopeStack::Cleanup {
10992public:
10993 static const int CleanupArgs = 3;
10994
10995private:
10996 llvm::FunctionCallee RTLFn;
10997 llvm::Value *Args[CleanupArgs];
10998
10999public:
11000 OMPAllocateCleanupTy(llvm::FunctionCallee RTLFn,
11001 ArrayRef<llvm::Value *> CallArgs)
11002 : RTLFn(RTLFn) {
11003 assert(CallArgs.size() == CleanupArgs &&
11004 "Size of arguments does not match.");
11005 std::copy(CallArgs.begin(), CallArgs.end(), std::begin(Args));
11006 }
11007 void Emit(CodeGenFunction &CGF, Flags /*flags*/) override {
11008 if (!CGF.HaveInsertPoint())
11009 return;
11010 CGF.EmitRuntimeCall(RTLFn, Args);
11011 }
11012};
11013} // namespace
11014
Gheorghe-Teodor Bercead3dcf2f2018-03-14 14:17:45 +000011015Address CGOpenMPRuntime::getAddressOfLocalVariable(CodeGenFunction &CGF,
11016 const VarDecl *VD) {
Alexey Bataev084b0c2f02019-03-21 20:36:16 +000011017 if (!VD)
11018 return Address::invalid();
Alexey Bataev4f680db2019-03-19 16:41:16 +000011019 const VarDecl *CVD = VD->getCanonicalDecl();
11020 if (!CVD->hasAttr<OMPAllocateDeclAttr>())
11021 return Address::invalid();
Alexey Bataev084b0c2f02019-03-21 20:36:16 +000011022 const auto *AA = CVD->getAttr<OMPAllocateDeclAttr>();
11023 // Use the default allocation.
Alexey Bataev0fd3c682019-04-02 19:44:46 +000011024 if (AA->getAllocatorType() == OMPAllocateDeclAttr::OMPDefaultMemAlloc &&
11025 !AA->getAllocator())
Alexey Bataev084b0c2f02019-03-21 20:36:16 +000011026 return Address::invalid();
Alexey Bataev084b0c2f02019-03-21 20:36:16 +000011027 llvm::Value *Size;
11028 CharUnits Align = CGM.getContext().getDeclAlign(CVD);
11029 if (CVD->getType()->isVariablyModifiedType()) {
11030 Size = CGF.getTypeSize(CVD->getType());
Alexey Bataev9c397812019-04-03 17:57:06 +000011031 // Align the size: ((size + align - 1) / align) * align
11032 Size = CGF.Builder.CreateNUWAdd(
11033 Size, CGM.getSize(Align - CharUnits::fromQuantity(1)));
11034 Size = CGF.Builder.CreateUDiv(Size, CGM.getSize(Align));
11035 Size = CGF.Builder.CreateNUWMul(Size, CGM.getSize(Align));
Alexey Bataev084b0c2f02019-03-21 20:36:16 +000011036 } else {
11037 CharUnits Sz = CGM.getContext().getTypeSizeInChars(CVD->getType());
Alexey Bataev084b0c2f02019-03-21 20:36:16 +000011038 Size = CGM.getSize(Sz.alignTo(Align));
Alexey Bataev4f680db2019-03-19 16:41:16 +000011039 }
Alexey Bataev084b0c2f02019-03-21 20:36:16 +000011040 llvm::Value *ThreadID = getThreadID(CGF, CVD->getBeginLoc());
11041 assert(AA->getAllocator() &&
11042 "Expected allocator expression for non-default allocator.");
11043 llvm::Value *Allocator = CGF.EmitScalarExpr(AA->getAllocator());
Alexey Bataev6cf7b712019-04-08 19:06:42 +000011044 // According to the standard, the original allocator type is a enum (integer).
11045 // Convert to pointer type, if required.
11046 if (Allocator->getType()->isIntegerTy())
11047 Allocator = CGF.Builder.CreateIntToPtr(Allocator, CGM.VoidPtrTy);
11048 else if (Allocator->getType()->isPointerTy())
11049 Allocator = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Allocator,
11050 CGM.VoidPtrTy);
Alexey Bataev084b0c2f02019-03-21 20:36:16 +000011051 llvm::Value *Args[] = {ThreadID, Size, Allocator};
11052
11053 llvm::Value *Addr =
11054 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_alloc), Args,
Alexey Bataev8b321922020-01-16 15:46:34 -050011055 getName({CVD->getName(), ".void.addr"}));
Alexey Bataev084b0c2f02019-03-21 20:36:16 +000011056 llvm::Value *FiniArgs[OMPAllocateCleanupTy::CleanupArgs] = {ThreadID, Addr,
11057 Allocator};
11058 llvm::FunctionCallee FiniRTLFn = createRuntimeFunction(OMPRTL__kmpc_free);
11059
11060 CGF.EHStack.pushCleanup<OMPAllocateCleanupTy>(NormalAndEHCleanup, FiniRTLFn,
11061 llvm::makeArrayRef(FiniArgs));
11062 Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
11063 Addr,
11064 CGF.ConvertTypeForMem(CGM.getContext().getPointerType(CVD->getType())),
Alexey Bataev8b321922020-01-16 15:46:34 -050011065 getName({CVD->getName(), ".addr"}));
Alexey Bataev084b0c2f02019-03-21 20:36:16 +000011066 return Address(Addr, Align);
Gheorghe-Teodor Bercead3dcf2f2018-03-14 14:17:45 +000011067}
11068
Alexey Bataev2df5f122019-10-01 20:18:32 +000011069/// Finds the variant function that matches current context with its context
11070/// selector.
Alexey Bataev4e8231b2019-11-05 15:13:30 -050011071static const FunctionDecl *getDeclareVariantFunction(CodeGenModule &CGM,
Alexey Bataev0364c762019-10-03 20:49:48 +000011072 const FunctionDecl *FD) {
Alexey Bataev2df5f122019-10-01 20:18:32 +000011073 if (!FD->hasAttrs() || !FD->hasAttr<OMPDeclareVariantAttr>())
11074 return FD;
Johannes Doerfert1228d422019-12-19 20:42:12 -060011075
11076 SmallVector<Expr *, 8> VariantExprs;
11077 SmallVector<VariantMatchInfo, 8> VMIs;
Alexey Bataev0364c762019-10-03 20:49:48 +000011078 for (const auto *A : FD->specific_attrs<OMPDeclareVariantAttr>()) {
Johannes Doerfertb86bf832020-02-15 18:07:42 -060011079 const OMPTraitInfo &TI = A->getTraitInfos();
Johannes Doerfert1228d422019-12-19 20:42:12 -060011080 VMIs.push_back(VariantMatchInfo());
Johannes Doerfertb86bf832020-02-15 18:07:42 -060011081 TI.getAsVariantMatchInfo(CGM.getContext(), VMIs.back());
Johannes Doerfert1228d422019-12-19 20:42:12 -060011082 VariantExprs.push_back(A->getVariantFuncRef());
Alexey Bataev2df5f122019-10-01 20:18:32 +000011083 }
Johannes Doerfert1228d422019-12-19 20:42:12 -060011084
11085 OMPContext Ctx(CGM.getLangOpts().OpenMPIsDevice, CGM.getTriple());
11086 // FIXME: Keep the context in the OMPIRBuilder so we can add constructs as we
11087 // build them.
11088
11089 int BestMatchIdx = getBestVariantMatchForContext(VMIs, Ctx);
11090 if (BestMatchIdx < 0)
Alexey Bataev2df5f122019-10-01 20:18:32 +000011091 return FD;
Johannes Doerfert1228d422019-12-19 20:42:12 -060011092
Alexey Bataev2df5f122019-10-01 20:18:32 +000011093 return cast<FunctionDecl>(
Johannes Doerfert1228d422019-12-19 20:42:12 -060011094 cast<DeclRefExpr>(VariantExprs[BestMatchIdx]->IgnoreParenImpCasts())
Alexey Bataev2df5f122019-10-01 20:18:32 +000011095 ->getDecl());
11096}
11097
11098bool CGOpenMPRuntime::emitDeclareVariant(GlobalDecl GD, bool IsForDefinition) {
11099 const auto *D = cast<FunctionDecl>(GD.getDecl());
11100 // If the original function is defined already, use its definition.
11101 StringRef MangledName = CGM.getMangledName(GD);
11102 llvm::GlobalValue *Orig = CGM.GetGlobalValue(MangledName);
11103 if (Orig && !Orig->isDeclaration())
11104 return false;
Alexey Bataev4e8231b2019-11-05 15:13:30 -050011105 const FunctionDecl *NewFD = getDeclareVariantFunction(CGM, D);
Alexey Bataev2df5f122019-10-01 20:18:32 +000011106 // Emit original function if it does not have declare variant attribute or the
11107 // context does not match.
11108 if (NewFD == D)
11109 return false;
11110 GlobalDecl NewGD = GD.getWithDecl(NewFD);
Alexey Bataevc2cd2d42019-10-10 17:28:10 +000011111 if (tryEmitDeclareVariant(NewGD, GD, Orig, IsForDefinition)) {
Alexey Bataev2df5f122019-10-01 20:18:32 +000011112 DeferredVariantFunction.erase(D);
11113 return true;
11114 }
11115 DeferredVariantFunction.insert(std::make_pair(D, std::make_pair(NewGD, GD)));
11116 return true;
11117}
11118
Alexey Bataev0860db92019-12-19 10:01:10 -050011119CGOpenMPRuntime::NontemporalDeclsRAII::NontemporalDeclsRAII(
11120 CodeGenModule &CGM, const OMPLoopDirective &S)
11121 : CGM(CGM), NeedToPush(S.hasClausesOfKind<OMPNontemporalClause>()) {
11122 assert(CGM.getLangOpts().OpenMP && "Not in OpenMP mode.");
11123 if (!NeedToPush)
11124 return;
11125 NontemporalDeclsSet &DS =
11126 CGM.getOpenMPRuntime().NontemporalDeclsStack.emplace_back();
11127 for (const auto *C : S.getClausesOfKind<OMPNontemporalClause>()) {
11128 for (const Stmt *Ref : C->private_refs()) {
11129 const auto *SimpleRefExpr = cast<Expr>(Ref)->IgnoreParenImpCasts();
11130 const ValueDecl *VD;
11131 if (const auto *DRE = dyn_cast<DeclRefExpr>(SimpleRefExpr)) {
11132 VD = DRE->getDecl();
11133 } else {
11134 const auto *ME = cast<MemberExpr>(SimpleRefExpr);
11135 assert((ME->isImplicitCXXThis() ||
11136 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) &&
11137 "Expected member of current class.");
11138 VD = ME->getMemberDecl();
11139 }
11140 DS.insert(VD);
11141 }
11142 }
11143}
11144
11145CGOpenMPRuntime::NontemporalDeclsRAII::~NontemporalDeclsRAII() {
11146 if (!NeedToPush)
11147 return;
11148 CGM.getOpenMPRuntime().NontemporalDeclsStack.pop_back();
11149}
11150
11151bool CGOpenMPRuntime::isNontemporalDecl(const ValueDecl *VD) const {
11152 assert(CGM.getLangOpts().OpenMP && "Not in OpenMP mode.");
11153
11154 return llvm::any_of(
11155 CGM.getOpenMPRuntime().NontemporalDeclsStack,
11156 [VD](const NontemporalDeclsSet &Set) { return Set.count(VD) > 0; });
11157}
11158
Alexey Bataev46978742020-01-30 10:46:11 -050011159void CGOpenMPRuntime::LastprivateConditionalRAII::tryToDisableInnerAnalysis(
11160 const OMPExecutableDirective &S,
11161 llvm::DenseSet<CanonicalDeclPtr<const Decl>> &NeedToAddForLPCsAsDisabled)
11162 const {
11163 llvm::DenseSet<CanonicalDeclPtr<const Decl>> NeedToCheckForLPCs;
11164 // Vars in target/task regions must be excluded completely.
11165 if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()) ||
11166 isOpenMPTaskingDirective(S.getDirectiveKind())) {
11167 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
11168 getOpenMPCaptureRegions(CaptureRegions, S.getDirectiveKind());
11169 const CapturedStmt *CS = S.getCapturedStmt(CaptureRegions.front());
11170 for (const CapturedStmt::Capture &Cap : CS->captures()) {
11171 if (Cap.capturesVariable() || Cap.capturesVariableByCopy())
11172 NeedToCheckForLPCs.insert(Cap.getCapturedVar());
11173 }
11174 }
11175 // Exclude vars in private clauses.
11176 for (const auto *C : S.getClausesOfKind<OMPPrivateClause>()) {
11177 for (const Expr *Ref : C->varlists()) {
11178 if (!Ref->getType()->isScalarType())
11179 continue;
11180 const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
11181 if (!DRE)
11182 continue;
11183 NeedToCheckForLPCs.insert(DRE->getDecl());
11184 }
11185 }
11186 for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) {
11187 for (const Expr *Ref : C->varlists()) {
11188 if (!Ref->getType()->isScalarType())
11189 continue;
11190 const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
11191 if (!DRE)
11192 continue;
11193 NeedToCheckForLPCs.insert(DRE->getDecl());
11194 }
11195 }
11196 for (const auto *C : S.getClausesOfKind<OMPLastprivateClause>()) {
11197 for (const Expr *Ref : C->varlists()) {
11198 if (!Ref->getType()->isScalarType())
11199 continue;
11200 const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
11201 if (!DRE)
11202 continue;
11203 NeedToCheckForLPCs.insert(DRE->getDecl());
11204 }
11205 }
11206 for (const auto *C : S.getClausesOfKind<OMPReductionClause>()) {
11207 for (const Expr *Ref : C->varlists()) {
11208 if (!Ref->getType()->isScalarType())
11209 continue;
11210 const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
11211 if (!DRE)
11212 continue;
11213 NeedToCheckForLPCs.insert(DRE->getDecl());
11214 }
11215 }
11216 for (const auto *C : S.getClausesOfKind<OMPLinearClause>()) {
11217 for (const Expr *Ref : C->varlists()) {
11218 if (!Ref->getType()->isScalarType())
11219 continue;
11220 const auto *DRE = dyn_cast<DeclRefExpr>(Ref->IgnoreParenImpCasts());
11221 if (!DRE)
11222 continue;
11223 NeedToCheckForLPCs.insert(DRE->getDecl());
11224 }
11225 }
11226 for (const Decl *VD : NeedToCheckForLPCs) {
11227 for (const LastprivateConditionalData &Data :
11228 llvm::reverse(CGM.getOpenMPRuntime().LastprivateConditionalStack)) {
11229 if (Data.DeclToUniqueName.count(VD) > 0) {
11230 if (!Data.Disabled)
11231 NeedToAddForLPCsAsDisabled.insert(VD);
11232 break;
11233 }
11234 }
11235 }
11236}
11237
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011238CGOpenMPRuntime::LastprivateConditionalRAII::LastprivateConditionalRAII(
11239 CodeGenFunction &CGF, const OMPExecutableDirective &S, LValue IVLVal)
11240 : CGM(CGF.CGM),
Alexey Bataev46978742020-01-30 10:46:11 -050011241 Action((CGM.getLangOpts().OpenMP >= 50 &&
11242 llvm::any_of(S.getClausesOfKind<OMPLastprivateClause>(),
11243 [](const OMPLastprivateClause *C) {
11244 return C->getKind() ==
11245 OMPC_LASTPRIVATE_conditional;
11246 }))
11247 ? ActionToDo::PushAsLastprivateConditional
11248 : ActionToDo::DoNotPush) {
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011249 assert(CGM.getLangOpts().OpenMP && "Not in OpenMP mode.");
Alexey Bataev46978742020-01-30 10:46:11 -050011250 if (CGM.getLangOpts().OpenMP < 50 || Action == ActionToDo::DoNotPush)
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011251 return;
Alexey Bataev46978742020-01-30 10:46:11 -050011252 assert(Action == ActionToDo::PushAsLastprivateConditional &&
11253 "Expected a push action.");
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011254 LastprivateConditionalData &Data =
11255 CGM.getOpenMPRuntime().LastprivateConditionalStack.emplace_back();
11256 for (const auto *C : S.getClausesOfKind<OMPLastprivateClause>()) {
11257 if (C->getKind() != OMPC_LASTPRIVATE_conditional)
11258 continue;
11259
11260 for (const Expr *Ref : C->varlists()) {
Alexey Bataev46978742020-01-30 10:46:11 -050011261 Data.DeclToUniqueName.insert(std::make_pair(
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011262 cast<DeclRefExpr>(Ref->IgnoreParenImpCasts())->getDecl(),
Alexey Bataev46978742020-01-30 10:46:11 -050011263 SmallString<16>(generateUniqueName(CGM, "pl_cond", Ref))));
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011264 }
11265 }
11266 Data.IVLVal = IVLVal;
Alexey Bataev46978742020-01-30 10:46:11 -050011267 Data.Fn = CGF.CurFn;
11268}
11269
11270CGOpenMPRuntime::LastprivateConditionalRAII::LastprivateConditionalRAII(
11271 CodeGenFunction &CGF, const OMPExecutableDirective &S)
11272 : CGM(CGF.CGM), Action(ActionToDo::DoNotPush) {
11273 assert(CGM.getLangOpts().OpenMP && "Not in OpenMP mode.");
11274 if (CGM.getLangOpts().OpenMP < 50)
11275 return;
11276 llvm::DenseSet<CanonicalDeclPtr<const Decl>> NeedToAddForLPCsAsDisabled;
11277 tryToDisableInnerAnalysis(S, NeedToAddForLPCsAsDisabled);
11278 if (!NeedToAddForLPCsAsDisabled.empty()) {
11279 Action = ActionToDo::DisableLastprivateConditional;
11280 LastprivateConditionalData &Data =
11281 CGM.getOpenMPRuntime().LastprivateConditionalStack.emplace_back();
11282 for (const Decl *VD : NeedToAddForLPCsAsDisabled)
11283 Data.DeclToUniqueName.insert(std::make_pair(VD, SmallString<16>()));
11284 Data.Fn = CGF.CurFn;
11285 Data.Disabled = true;
11286 }
11287}
11288
11289CGOpenMPRuntime::LastprivateConditionalRAII
11290CGOpenMPRuntime::LastprivateConditionalRAII::disable(
11291 CodeGenFunction &CGF, const OMPExecutableDirective &S) {
11292 return LastprivateConditionalRAII(CGF, S);
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011293}
11294
11295CGOpenMPRuntime::LastprivateConditionalRAII::~LastprivateConditionalRAII() {
Alexey Bataev46978742020-01-30 10:46:11 -050011296 if (CGM.getLangOpts().OpenMP < 50)
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011297 return;
Alexey Bataev46978742020-01-30 10:46:11 -050011298 if (Action == ActionToDo::DisableLastprivateConditional) {
11299 assert(CGM.getOpenMPRuntime().LastprivateConditionalStack.back().Disabled &&
11300 "Expected list of disabled private vars.");
11301 CGM.getOpenMPRuntime().LastprivateConditionalStack.pop_back();
11302 }
11303 if (Action == ActionToDo::PushAsLastprivateConditional) {
11304 assert(
11305 !CGM.getOpenMPRuntime().LastprivateConditionalStack.back().Disabled &&
11306 "Expected list of lastprivate conditional vars.");
11307 CGM.getOpenMPRuntime().LastprivateConditionalStack.pop_back();
11308 }
11309}
11310
11311Address CGOpenMPRuntime::emitLastprivateConditionalInit(CodeGenFunction &CGF,
11312 const VarDecl *VD) {
11313 ASTContext &C = CGM.getContext();
11314 auto I = LastprivateConditionalToTypes.find(CGF.CurFn);
11315 if (I == LastprivateConditionalToTypes.end())
11316 I = LastprivateConditionalToTypes.try_emplace(CGF.CurFn).first;
11317 QualType NewType;
11318 const FieldDecl *VDField;
11319 const FieldDecl *FiredField;
11320 LValue BaseLVal;
11321 auto VI = I->getSecond().find(VD);
11322 if (VI == I->getSecond().end()) {
11323 RecordDecl *RD = C.buildImplicitRecord("lasprivate.conditional");
11324 RD->startDefinition();
11325 VDField = addFieldToRecordDecl(C, RD, VD->getType().getNonReferenceType());
11326 FiredField = addFieldToRecordDecl(C, RD, C.CharTy);
11327 RD->completeDefinition();
11328 NewType = C.getRecordType(RD);
11329 Address Addr = CGF.CreateMemTemp(NewType, C.getDeclAlign(VD), VD->getName());
11330 BaseLVal = CGF.MakeAddrLValue(Addr, NewType, AlignmentSource::Decl);
11331 I->getSecond().try_emplace(VD, NewType, VDField, FiredField, BaseLVal);
11332 } else {
11333 NewType = std::get<0>(VI->getSecond());
11334 VDField = std::get<1>(VI->getSecond());
11335 FiredField = std::get<2>(VI->getSecond());
11336 BaseLVal = std::get<3>(VI->getSecond());
11337 }
11338 LValue FiredLVal =
11339 CGF.EmitLValueForField(BaseLVal, FiredField);
11340 CGF.EmitStoreOfScalar(
11341 llvm::ConstantInt::getNullValue(CGF.ConvertTypeForMem(C.CharTy)),
11342 FiredLVal);
11343 return CGF.EmitLValueForField(BaseLVal, VDField).getAddress(CGF);
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011344}
11345
11346namespace {
11347/// Checks if the lastprivate conditional variable is referenced in LHS.
11348class LastprivateConditionalRefChecker final
11349 : public ConstStmtVisitor<LastprivateConditionalRefChecker, bool> {
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011350 ArrayRef<CGOpenMPRuntime::LastprivateConditionalData> LPM;
11351 const Expr *FoundE = nullptr;
11352 const Decl *FoundD = nullptr;
11353 StringRef UniqueDeclName;
11354 LValue IVLVal;
Alexey Bataev46978742020-01-30 10:46:11 -050011355 llvm::Function *FoundFn = nullptr;
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011356 SourceLocation Loc;
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011357
11358public:
11359 bool VisitDeclRefExpr(const DeclRefExpr *E) {
11360 for (const CGOpenMPRuntime::LastprivateConditionalData &D :
11361 llvm::reverse(LPM)) {
Alexey Bataev46978742020-01-30 10:46:11 -050011362 auto It = D.DeclToUniqueName.find(E->getDecl());
11363 if (It == D.DeclToUniqueName.end())
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011364 continue;
Alexey Bataev46978742020-01-30 10:46:11 -050011365 if (D.Disabled)
11366 return false;
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011367 FoundE = E;
11368 FoundD = E->getDecl()->getCanonicalDecl();
Alexey Bataev46978742020-01-30 10:46:11 -050011369 UniqueDeclName = It->second;
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011370 IVLVal = D.IVLVal;
Alexey Bataev46978742020-01-30 10:46:11 -050011371 FoundFn = D.Fn;
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011372 break;
11373 }
11374 return FoundE == E;
11375 }
11376 bool VisitMemberExpr(const MemberExpr *E) {
Alexey Bataev46978742020-01-30 10:46:11 -050011377 if (!CodeGenFunction::IsWrappedCXXThis(E->getBase()))
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011378 return false;
11379 for (const CGOpenMPRuntime::LastprivateConditionalData &D :
11380 llvm::reverse(LPM)) {
Alexey Bataev46978742020-01-30 10:46:11 -050011381 auto It = D.DeclToUniqueName.find(E->getMemberDecl());
11382 if (It == D.DeclToUniqueName.end())
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011383 continue;
Alexey Bataev46978742020-01-30 10:46:11 -050011384 if (D.Disabled)
11385 return false;
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011386 FoundE = E;
11387 FoundD = E->getMemberDecl()->getCanonicalDecl();
Alexey Bataev46978742020-01-30 10:46:11 -050011388 UniqueDeclName = It->second;
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011389 IVLVal = D.IVLVal;
Alexey Bataev46978742020-01-30 10:46:11 -050011390 FoundFn = D.Fn;
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011391 break;
11392 }
11393 return FoundE == E;
11394 }
11395 bool VisitStmt(const Stmt *S) {
11396 for (const Stmt *Child : S->children()) {
11397 if (!Child)
11398 continue;
11399 if (const auto *E = dyn_cast<Expr>(Child))
11400 if (!E->isGLValue())
11401 continue;
11402 if (Visit(Child))
11403 return true;
11404 }
11405 return false;
11406 }
11407 explicit LastprivateConditionalRefChecker(
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011408 ArrayRef<CGOpenMPRuntime::LastprivateConditionalData> LPM)
Alexey Bataev46978742020-01-30 10:46:11 -050011409 : LPM(LPM) {}
11410 std::tuple<const Expr *, const Decl *, StringRef, LValue, llvm::Function *>
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011411 getFoundData() const {
Alexey Bataev46978742020-01-30 10:46:11 -050011412 return std::make_tuple(FoundE, FoundD, UniqueDeclName, IVLVal, FoundFn);
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011413 }
11414};
11415} // namespace
11416
Alexey Bataev46978742020-01-30 10:46:11 -050011417void CGOpenMPRuntime::emitLastprivateConditionalUpdate(CodeGenFunction &CGF,
11418 LValue IVLVal,
11419 StringRef UniqueDeclName,
11420 LValue LVal,
11421 SourceLocation Loc) {
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011422 // Last updated loop counter for the lastprivate conditional var.
11423 // int<xx> last_iv = 0;
11424 llvm::Type *LLIVTy = CGF.ConvertTypeForMem(IVLVal.getType());
11425 llvm::Constant *LastIV =
Alexey Bataev8b321922020-01-16 15:46:34 -050011426 getOrCreateInternalVariable(LLIVTy, getName({UniqueDeclName, "iv"}));
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011427 cast<llvm::GlobalVariable>(LastIV)->setAlignment(
11428 IVLVal.getAlignment().getAsAlign());
11429 LValue LastIVLVal = CGF.MakeNaturalAlignAddrLValue(LastIV, IVLVal.getType());
11430
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011431 // Last value of the lastprivate conditional.
11432 // decltype(priv_a) last_a;
11433 llvm::Constant *Last = getOrCreateInternalVariable(
Alexey Bataev46978742020-01-30 10:46:11 -050011434 CGF.ConvertTypeForMem(LVal.getType()), UniqueDeclName);
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011435 cast<llvm::GlobalVariable>(Last)->setAlignment(
11436 LVal.getAlignment().getAsAlign());
11437 LValue LastLVal =
11438 CGF.MakeAddrLValue(Last, LVal.getType(), LVal.getAlignment());
11439
11440 // Global loop counter. Required to handle inner parallel-for regions.
Alexey Bataev46978742020-01-30 10:46:11 -050011441 // iv
11442 llvm::Value *IVVal = CGF.EmitLoadOfScalar(IVLVal, Loc);
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011443
11444 // #pragma omp critical(a)
11445 // if (last_iv <= iv) {
11446 // last_iv = iv;
11447 // last_a = priv_a;
11448 // }
11449 auto &&CodeGen = [&LastIVLVal, &IVLVal, IVVal, &LVal, &LastLVal,
Alexey Bataev46978742020-01-30 10:46:11 -050011450 Loc](CodeGenFunction &CGF, PrePostActionTy &Action) {
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011451 Action.Enter(CGF);
Alexey Bataev46978742020-01-30 10:46:11 -050011452 llvm::Value *LastIVVal = CGF.EmitLoadOfScalar(LastIVLVal, Loc);
11453 // (last_iv <= iv) ? Check if the variable is updated and store new
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011454 // value in global var.
11455 llvm::Value *CmpRes;
11456 if (IVLVal.getType()->isSignedIntegerType()) {
11457 CmpRes = CGF.Builder.CreateICmpSLE(LastIVVal, IVVal);
11458 } else {
11459 assert(IVLVal.getType()->isUnsignedIntegerType() &&
11460 "Loop iteration variable must be integer.");
11461 CmpRes = CGF.Builder.CreateICmpULE(LastIVVal, IVVal);
11462 }
11463 llvm::BasicBlock *ThenBB = CGF.createBasicBlock("lp_cond_then");
11464 llvm::BasicBlock *ExitBB = CGF.createBasicBlock("lp_cond_exit");
11465 CGF.Builder.CreateCondBr(CmpRes, ThenBB, ExitBB);
11466 // {
11467 CGF.EmitBlock(ThenBB);
11468
Alexey Bataev46978742020-01-30 10:46:11 -050011469 // last_iv = iv;
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011470 CGF.EmitStoreOfScalar(IVVal, LastIVLVal);
11471
11472 // last_a = priv_a;
11473 switch (CGF.getEvaluationKind(LVal.getType())) {
11474 case TEK_Scalar: {
Alexey Bataev46978742020-01-30 10:46:11 -050011475 llvm::Value *PrivVal = CGF.EmitLoadOfScalar(LVal, Loc);
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011476 CGF.EmitStoreOfScalar(PrivVal, LastLVal);
11477 break;
11478 }
11479 case TEK_Complex: {
Alexey Bataev46978742020-01-30 10:46:11 -050011480 CodeGenFunction::ComplexPairTy PrivVal = CGF.EmitLoadOfComplex(LVal, Loc);
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011481 CGF.EmitStoreOfComplex(PrivVal, LastLVal, /*isInit=*/false);
11482 break;
11483 }
11484 case TEK_Aggregate:
11485 llvm_unreachable(
11486 "Aggregates are not supported in lastprivate conditional.");
11487 }
11488 // }
11489 CGF.EmitBranch(ExitBB);
11490 // There is no need to emit line number for unconditional branch.
11491 (void)ApplyDebugLocation::CreateEmpty(CGF);
11492 CGF.EmitBlock(ExitBB, /*IsFinished=*/true);
11493 };
11494
11495 if (CGM.getLangOpts().OpenMPSimd) {
11496 // Do not emit as a critical region as no parallel region could be emitted.
11497 RegionCodeGenTy ThenRCG(CodeGen);
11498 ThenRCG(CGF);
11499 } else {
Alexey Bataev46978742020-01-30 10:46:11 -050011500 emitCriticalRegion(CGF, UniqueDeclName, CodeGen, Loc);
11501 }
11502}
11503
11504void CGOpenMPRuntime::checkAndEmitLastprivateConditional(CodeGenFunction &CGF,
11505 const Expr *LHS) {
11506 if (CGF.getLangOpts().OpenMP < 50 || LastprivateConditionalStack.empty())
11507 return;
11508 LastprivateConditionalRefChecker Checker(LastprivateConditionalStack);
11509 if (!Checker.Visit(LHS))
11510 return;
11511 const Expr *FoundE;
11512 const Decl *FoundD;
11513 StringRef UniqueDeclName;
11514 LValue IVLVal;
11515 llvm::Function *FoundFn;
11516 std::tie(FoundE, FoundD, UniqueDeclName, IVLVal, FoundFn) =
11517 Checker.getFoundData();
11518 if (FoundFn != CGF.CurFn) {
11519 // Special codegen for inner parallel regions.
11520 // ((struct.lastprivate.conditional*)&priv_a)->Fired = 1;
11521 auto It = LastprivateConditionalToTypes[FoundFn].find(FoundD);
11522 assert(It != LastprivateConditionalToTypes[FoundFn].end() &&
11523 "Lastprivate conditional is not found in outer region.");
11524 QualType StructTy = std::get<0>(It->getSecond());
11525 const FieldDecl* FiredDecl = std::get<2>(It->getSecond());
11526 LValue PrivLVal = CGF.EmitLValue(FoundE);
11527 Address StructAddr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
11528 PrivLVal.getAddress(CGF),
11529 CGF.ConvertTypeForMem(CGF.getContext().getPointerType(StructTy)));
11530 LValue BaseLVal =
11531 CGF.MakeAddrLValue(StructAddr, StructTy, AlignmentSource::Decl);
11532 LValue FiredLVal = CGF.EmitLValueForField(BaseLVal, FiredDecl);
11533 CGF.EmitAtomicStore(RValue::get(llvm::ConstantInt::get(
11534 CGF.ConvertTypeForMem(FiredDecl->getType()), 1)),
11535 FiredLVal, llvm::AtomicOrdering::Unordered,
11536 /*IsVolatile=*/true, /*isInit=*/false);
11537 return;
11538 }
11539
11540 // Private address of the lastprivate conditional in the current context.
11541 // priv_a
11542 LValue LVal = CGF.EmitLValue(FoundE);
11543 emitLastprivateConditionalUpdate(CGF, IVLVal, UniqueDeclName, LVal,
11544 FoundE->getExprLoc());
11545}
11546
11547void CGOpenMPRuntime::checkAndEmitSharedLastprivateConditional(
11548 CodeGenFunction &CGF, const OMPExecutableDirective &D,
11549 const llvm::DenseSet<CanonicalDeclPtr<const VarDecl>> &IgnoredDecls) {
11550 if (CGF.getLangOpts().OpenMP < 50 || LastprivateConditionalStack.empty())
11551 return;
11552 auto Range = llvm::reverse(LastprivateConditionalStack);
11553 auto It = llvm::find_if(
11554 Range, [](const LastprivateConditionalData &D) { return !D.Disabled; });
11555 if (It == Range.end() || It->Fn != CGF.CurFn)
11556 return;
11557 auto LPCI = LastprivateConditionalToTypes.find(It->Fn);
11558 assert(LPCI != LastprivateConditionalToTypes.end() &&
11559 "Lastprivates must be registered already.");
11560 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
11561 getOpenMPCaptureRegions(CaptureRegions, D.getDirectiveKind());
11562 const CapturedStmt *CS = D.getCapturedStmt(CaptureRegions.back());
11563 for (const auto &Pair : It->DeclToUniqueName) {
11564 const auto *VD = cast<VarDecl>(Pair.first->getCanonicalDecl());
11565 if (!CS->capturesVariable(VD) || IgnoredDecls.count(VD) > 0)
11566 continue;
11567 auto I = LPCI->getSecond().find(Pair.first);
11568 assert(I != LPCI->getSecond().end() &&
11569 "Lastprivate must be rehistered already.");
11570 // bool Cmp = priv_a.Fired != 0;
11571 LValue BaseLVal = std::get<3>(I->getSecond());
11572 LValue FiredLVal =
11573 CGF.EmitLValueForField(BaseLVal, std::get<2>(I->getSecond()));
11574 llvm::Value *Res = CGF.EmitLoadOfScalar(FiredLVal, D.getBeginLoc());
11575 llvm::Value *Cmp = CGF.Builder.CreateIsNotNull(Res);
11576 llvm::BasicBlock *ThenBB = CGF.createBasicBlock("lpc.then");
11577 llvm::BasicBlock *DoneBB = CGF.createBasicBlock("lpc.done");
11578 // if (Cmp) {
11579 CGF.Builder.CreateCondBr(Cmp, ThenBB, DoneBB);
11580 CGF.EmitBlock(ThenBB);
11581 Address Addr = CGF.GetAddrOfLocalVar(VD);
11582 LValue LVal;
11583 if (VD->getType()->isReferenceType())
11584 LVal = CGF.EmitLoadOfReferenceLValue(Addr, VD->getType(),
11585 AlignmentSource::Decl);
11586 else
11587 LVal = CGF.MakeAddrLValue(Addr, VD->getType().getNonReferenceType(),
11588 AlignmentSource::Decl);
11589 emitLastprivateConditionalUpdate(CGF, It->IVLVal, Pair.second, LVal,
11590 D.getBeginLoc());
11591 auto AL = ApplyDebugLocation::CreateArtificial(CGF);
11592 CGF.EmitBlock(DoneBB, /*IsFinal=*/true);
11593 // }
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011594 }
11595}
11596
11597void CGOpenMPRuntime::emitLastprivateConditionalFinalUpdate(
11598 CodeGenFunction &CGF, LValue PrivLVal, const VarDecl *VD,
11599 SourceLocation Loc) {
11600 if (CGF.getLangOpts().OpenMP < 50)
11601 return;
Alexey Bataev46978742020-01-30 10:46:11 -050011602 auto It = LastprivateConditionalStack.back().DeclToUniqueName.find(VD);
11603 assert(It != LastprivateConditionalStack.back().DeclToUniqueName.end() &&
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011604 "Unknown lastprivate conditional variable.");
Alexey Bataev46978742020-01-30 10:46:11 -050011605 StringRef UniqueName = It->second;
Alexey Bataeva58da1a2019-12-27 09:44:43 -050011606 llvm::GlobalVariable *GV = CGM.getModule().getNamedGlobal(UniqueName);
11607 // The variable was not updated in the region - exit.
11608 if (!GV)
11609 return;
11610 LValue LPLVal = CGF.MakeAddrLValue(
11611 GV, PrivLVal.getType().getNonReferenceType(), PrivLVal.getAlignment());
11612 llvm::Value *Res = CGF.EmitLoadOfScalar(LPLVal, Loc);
11613 CGF.EmitStoreOfScalar(Res, PrivLVal);
11614}
11615
James Y Knight9871db02019-02-05 16:42:33 +000011616llvm::Function *CGOpenMPSIMDRuntime::emitParallelOutlinedFunction(
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000011617 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
11618 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
11619 llvm_unreachable("Not supported in SIMD-only mode");
11620}
11621
James Y Knight9871db02019-02-05 16:42:33 +000011622llvm::Function *CGOpenMPSIMDRuntime::emitTeamsOutlinedFunction(
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000011623 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
11624 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
11625 llvm_unreachable("Not supported in SIMD-only mode");
11626}
11627
James Y Knight9871db02019-02-05 16:42:33 +000011628llvm::Function *CGOpenMPSIMDRuntime::emitTaskOutlinedFunction(
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000011629 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
11630 const VarDecl *PartIDVar, const VarDecl *TaskTVar,
11631 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
11632 bool Tied, unsigned &NumberOfParts) {
11633 llvm_unreachable("Not supported in SIMD-only mode");
11634}
11635
11636void CGOpenMPSIMDRuntime::emitParallelCall(CodeGenFunction &CGF,
11637 SourceLocation Loc,
James Y Knight9871db02019-02-05 16:42:33 +000011638 llvm::Function *OutlinedFn,
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000011639 ArrayRef<llvm::Value *> CapturedVars,
11640 const Expr *IfCond) {
11641 llvm_unreachable("Not supported in SIMD-only mode");
11642}
11643
11644void CGOpenMPSIMDRuntime::emitCriticalRegion(
11645 CodeGenFunction &CGF, StringRef CriticalName,
11646 const RegionCodeGenTy &CriticalOpGen, SourceLocation Loc,
11647 const Expr *Hint) {
11648 llvm_unreachable("Not supported in SIMD-only mode");
11649}
11650
11651void CGOpenMPSIMDRuntime::emitMasterRegion(CodeGenFunction &CGF,
11652 const RegionCodeGenTy &MasterOpGen,
11653 SourceLocation Loc) {
11654 llvm_unreachable("Not supported in SIMD-only mode");
11655}
11656
11657void CGOpenMPSIMDRuntime::emitTaskyieldCall(CodeGenFunction &CGF,
11658 SourceLocation Loc) {
11659 llvm_unreachable("Not supported in SIMD-only mode");
11660}
11661
11662void CGOpenMPSIMDRuntime::emitTaskgroupRegion(
11663 CodeGenFunction &CGF, const RegionCodeGenTy &TaskgroupOpGen,
11664 SourceLocation Loc) {
11665 llvm_unreachable("Not supported in SIMD-only mode");
11666}
11667
11668void CGOpenMPSIMDRuntime::emitSingleRegion(
11669 CodeGenFunction &CGF, const RegionCodeGenTy &SingleOpGen,
11670 SourceLocation Loc, ArrayRef<const Expr *> CopyprivateVars,
11671 ArrayRef<const Expr *> DestExprs, ArrayRef<const Expr *> SrcExprs,
11672 ArrayRef<const Expr *> AssignmentOps) {
11673 llvm_unreachable("Not supported in SIMD-only mode");
11674}
11675
11676void CGOpenMPSIMDRuntime::emitOrderedRegion(CodeGenFunction &CGF,
11677 const RegionCodeGenTy &OrderedOpGen,
11678 SourceLocation Loc,
11679 bool IsThreads) {
11680 llvm_unreachable("Not supported in SIMD-only mode");
11681}
11682
11683void CGOpenMPSIMDRuntime::emitBarrierCall(CodeGenFunction &CGF,
11684 SourceLocation Loc,
11685 OpenMPDirectiveKind Kind,
11686 bool EmitChecks,
11687 bool ForceSimpleCall) {
11688 llvm_unreachable("Not supported in SIMD-only mode");
11689}
11690
11691void CGOpenMPSIMDRuntime::emitForDispatchInit(
11692 CodeGenFunction &CGF, SourceLocation Loc,
11693 const OpenMPScheduleTy &ScheduleKind, unsigned IVSize, bool IVSigned,
11694 bool Ordered, const DispatchRTInput &DispatchValues) {
11695 llvm_unreachable("Not supported in SIMD-only mode");
11696}
11697
11698void CGOpenMPSIMDRuntime::emitForStaticInit(
11699 CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind DKind,
11700 const OpenMPScheduleTy &ScheduleKind, const StaticRTInput &Values) {
11701 llvm_unreachable("Not supported in SIMD-only mode");
11702}
11703
11704void CGOpenMPSIMDRuntime::emitDistributeStaticInit(
11705 CodeGenFunction &CGF, SourceLocation Loc,
11706 OpenMPDistScheduleClauseKind SchedKind, const StaticRTInput &Values) {
11707 llvm_unreachable("Not supported in SIMD-only mode");
11708}
11709
11710void CGOpenMPSIMDRuntime::emitForOrderedIterationEnd(CodeGenFunction &CGF,
11711 SourceLocation Loc,
11712 unsigned IVSize,
11713 bool IVSigned) {
11714 llvm_unreachable("Not supported in SIMD-only mode");
11715}
11716
11717void CGOpenMPSIMDRuntime::emitForStaticFinish(CodeGenFunction &CGF,
11718 SourceLocation Loc,
11719 OpenMPDirectiveKind DKind) {
11720 llvm_unreachable("Not supported in SIMD-only mode");
11721}
11722
11723llvm::Value *CGOpenMPSIMDRuntime::emitForNext(CodeGenFunction &CGF,
11724 SourceLocation Loc,
11725 unsigned IVSize, bool IVSigned,
11726 Address IL, Address LB,
11727 Address UB, Address ST) {
11728 llvm_unreachable("Not supported in SIMD-only mode");
11729}
11730
11731void CGOpenMPSIMDRuntime::emitNumThreadsClause(CodeGenFunction &CGF,
11732 llvm::Value *NumThreads,
11733 SourceLocation Loc) {
11734 llvm_unreachable("Not supported in SIMD-only mode");
11735}
11736
11737void CGOpenMPSIMDRuntime::emitProcBindClause(CodeGenFunction &CGF,
Johannes Doerfert6c5d1f402019-12-25 18:15:36 -060011738 ProcBindKind ProcBind,
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000011739 SourceLocation Loc) {
11740 llvm_unreachable("Not supported in SIMD-only mode");
11741}
11742
11743Address CGOpenMPSIMDRuntime::getAddrOfThreadPrivate(CodeGenFunction &CGF,
11744 const VarDecl *VD,
11745 Address VDAddr,
11746 SourceLocation Loc) {
11747 llvm_unreachable("Not supported in SIMD-only mode");
11748}
11749
11750llvm::Function *CGOpenMPSIMDRuntime::emitThreadPrivateVarDefinition(
11751 const VarDecl *VD, Address VDAddr, SourceLocation Loc, bool PerformInit,
11752 CodeGenFunction *CGF) {
11753 llvm_unreachable("Not supported in SIMD-only mode");
11754}
11755
11756Address CGOpenMPSIMDRuntime::getAddrOfArtificialThreadPrivate(
11757 CodeGenFunction &CGF, QualType VarType, StringRef Name) {
11758 llvm_unreachable("Not supported in SIMD-only mode");
11759}
11760
11761void CGOpenMPSIMDRuntime::emitFlush(CodeGenFunction &CGF,
11762 ArrayRef<const Expr *> Vars,
Alexey Bataeve8e05de2020-02-07 12:22:23 -050011763 SourceLocation Loc,
11764 llvm::AtomicOrdering AO) {
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000011765 llvm_unreachable("Not supported in SIMD-only mode");
11766}
11767
11768void CGOpenMPSIMDRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
11769 const OMPExecutableDirective &D,
James Y Knight9871db02019-02-05 16:42:33 +000011770 llvm::Function *TaskFunction,
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000011771 QualType SharedsTy, Address Shareds,
11772 const Expr *IfCond,
11773 const OMPTaskDataTy &Data) {
11774 llvm_unreachable("Not supported in SIMD-only mode");
11775}
11776
11777void CGOpenMPSIMDRuntime::emitTaskLoopCall(
11778 CodeGenFunction &CGF, SourceLocation Loc, const OMPLoopDirective &D,
James Y Knight9871db02019-02-05 16:42:33 +000011779 llvm::Function *TaskFunction, QualType SharedsTy, Address Shareds,
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000011780 const Expr *IfCond, const OMPTaskDataTy &Data) {
11781 llvm_unreachable("Not supported in SIMD-only mode");
11782}
11783
11784void CGOpenMPSIMDRuntime::emitReduction(
11785 CodeGenFunction &CGF, SourceLocation Loc, ArrayRef<const Expr *> Privates,
11786 ArrayRef<const Expr *> LHSExprs, ArrayRef<const Expr *> RHSExprs,
11787 ArrayRef<const Expr *> ReductionOps, ReductionOptionsTy Options) {
11788 assert(Options.SimpleReduction && "Only simple reduction is expected.");
11789 CGOpenMPRuntime::emitReduction(CGF, Loc, Privates, LHSExprs, RHSExprs,
11790 ReductionOps, Options);
11791}
11792
11793llvm::Value *CGOpenMPSIMDRuntime::emitTaskReductionInit(
11794 CodeGenFunction &CGF, SourceLocation Loc, ArrayRef<const Expr *> LHSExprs,
11795 ArrayRef<const Expr *> RHSExprs, const OMPTaskDataTy &Data) {
11796 llvm_unreachable("Not supported in SIMD-only mode");
11797}
11798
11799void CGOpenMPSIMDRuntime::emitTaskReductionFixups(CodeGenFunction &CGF,
11800 SourceLocation Loc,
11801 ReductionCodeGen &RCG,
11802 unsigned N) {
11803 llvm_unreachable("Not supported in SIMD-only mode");
11804}
11805
11806Address CGOpenMPSIMDRuntime::getTaskReductionItem(CodeGenFunction &CGF,
11807 SourceLocation Loc,
11808 llvm::Value *ReductionsPtr,
11809 LValue SharedLVal) {
11810 llvm_unreachable("Not supported in SIMD-only mode");
11811}
11812
11813void CGOpenMPSIMDRuntime::emitTaskwaitCall(CodeGenFunction &CGF,
11814 SourceLocation Loc) {
11815 llvm_unreachable("Not supported in SIMD-only mode");
11816}
11817
11818void CGOpenMPSIMDRuntime::emitCancellationPointCall(
11819 CodeGenFunction &CGF, SourceLocation Loc,
11820 OpenMPDirectiveKind CancelRegion) {
11821 llvm_unreachable("Not supported in SIMD-only mode");
11822}
11823
11824void CGOpenMPSIMDRuntime::emitCancelCall(CodeGenFunction &CGF,
11825 SourceLocation Loc, const Expr *IfCond,
11826 OpenMPDirectiveKind CancelRegion) {
11827 llvm_unreachable("Not supported in SIMD-only mode");
11828}
11829
11830void CGOpenMPSIMDRuntime::emitTargetOutlinedFunction(
11831 const OMPExecutableDirective &D, StringRef ParentName,
11832 llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
11833 bool IsOffloadEntry, const RegionCodeGenTy &CodeGen) {
11834 llvm_unreachable("Not supported in SIMD-only mode");
11835}
11836
Alexey Bataevec7946e2019-09-23 14:06:51 +000011837void CGOpenMPSIMDRuntime::emitTargetCall(
11838 CodeGenFunction &CGF, const OMPExecutableDirective &D,
11839 llvm::Function *OutlinedFn, llvm::Value *OutlinedFnID, const Expr *IfCond,
11840 const Expr *Device,
11841 llvm::function_ref<llvm::Value *(CodeGenFunction &CGF,
11842 const OMPLoopDirective &D)>
11843 SizeEmitter) {
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000011844 llvm_unreachable("Not supported in SIMD-only mode");
11845}
11846
11847bool CGOpenMPSIMDRuntime::emitTargetFunctions(GlobalDecl GD) {
11848 llvm_unreachable("Not supported in SIMD-only mode");
11849}
11850
11851bool CGOpenMPSIMDRuntime::emitTargetGlobalVariable(GlobalDecl GD) {
11852 llvm_unreachable("Not supported in SIMD-only mode");
11853}
11854
11855bool CGOpenMPSIMDRuntime::emitTargetGlobal(GlobalDecl GD) {
11856 return false;
11857}
11858
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000011859void CGOpenMPSIMDRuntime::emitTeamsCall(CodeGenFunction &CGF,
11860 const OMPExecutableDirective &D,
11861 SourceLocation Loc,
James Y Knight9871db02019-02-05 16:42:33 +000011862 llvm::Function *OutlinedFn,
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000011863 ArrayRef<llvm::Value *> CapturedVars) {
11864 llvm_unreachable("Not supported in SIMD-only mode");
11865}
11866
11867void CGOpenMPSIMDRuntime::emitNumTeamsClause(CodeGenFunction &CGF,
11868 const Expr *NumTeams,
11869 const Expr *ThreadLimit,
11870 SourceLocation Loc) {
11871 llvm_unreachable("Not supported in SIMD-only mode");
11872}
11873
11874void CGOpenMPSIMDRuntime::emitTargetDataCalls(
11875 CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond,
11876 const Expr *Device, const RegionCodeGenTy &CodeGen, TargetDataInfo &Info) {
11877 llvm_unreachable("Not supported in SIMD-only mode");
11878}
11879
11880void CGOpenMPSIMDRuntime::emitTargetDataStandAloneCall(
11881 CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond,
11882 const Expr *Device) {
11883 llvm_unreachable("Not supported in SIMD-only mode");
11884}
11885
11886void CGOpenMPSIMDRuntime::emitDoacrossInit(CodeGenFunction &CGF,
Alexey Bataevf138fda2018-08-13 19:04:24 +000011887 const OMPLoopDirective &D,
11888 ArrayRef<Expr *> NumIterations) {
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000011889 llvm_unreachable("Not supported in SIMD-only mode");
11890}
11891
11892void CGOpenMPSIMDRuntime::emitDoacrossOrdered(CodeGenFunction &CGF,
11893 const OMPDependClause *C) {
11894 llvm_unreachable("Not supported in SIMD-only mode");
11895}
11896
11897const VarDecl *
11898CGOpenMPSIMDRuntime::translateParameter(const FieldDecl *FD,
11899 const VarDecl *NativeParam) const {
11900 llvm_unreachable("Not supported in SIMD-only mode");
11901}
11902
11903Address
11904CGOpenMPSIMDRuntime::getParameterAddress(CodeGenFunction &CGF,
11905 const VarDecl *NativeParam,
11906 const VarDecl *TargetParam) const {
11907 llvm_unreachable("Not supported in SIMD-only mode");
11908}