blob: 0897b4765e22934b10d3b7f71e89938350a1d2f0 [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
Samuel Antaoee8fb302016-01-06 13:42:12 +000013#include "CGCXXABI.h"
14#include "CGCleanup.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000015#include "CGOpenMPRuntime.h"
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000016#include "CGRecordLayout.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000017#include "CodeGenFunction.h"
John McCall5ad74072017-03-02 20:04:19 +000018#include "clang/CodeGen/ConstantInitBuilder.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000019#include "clang/AST/Decl.h"
Chandler Carruth0d9593d2015-01-14 11:29:14 +000020#include "clang/AST/StmtOpenMP.h"
Richard Smithbf5bcf22018-06-26 23:20:26 +000021#include "clang/Basic/BitmaskEnum.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000022#include "llvm/ADT/ArrayRef.h"
Teresa Johnsonffc4e242016-11-11 05:35:12 +000023#include "llvm/Bitcode/BitcodeReader.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000024#include "llvm/IR/DerivedTypes.h"
25#include "llvm/IR/GlobalValue.h"
26#include "llvm/IR/Value.h"
Samuel Antaoee8fb302016-01-06 13:42:12 +000027#include "llvm/Support/Format.h"
Alexey Bataev9959db52014-05-06 10:08:46 +000028#include "llvm/Support/raw_ostream.h"
Alexey Bataev23b69422014-06-18 07:08:49 +000029#include <cassert>
Alexey Bataev9959db52014-05-06 10:08:46 +000030
31using namespace clang;
32using namespace CodeGen;
33
Benjamin Kramerc52193f2014-10-10 13:57:57 +000034namespace {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000035/// Base class for handling code generation inside OpenMP regions.
Alexey Bataev18095712014-10-10 12:19:54 +000036class CGOpenMPRegionInfo : public CodeGenFunction::CGCapturedStmtInfo {
37public:
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000038 /// Kinds of OpenMP regions used in codegen.
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000039 enum CGOpenMPRegionKind {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000040 /// Region with outlined function for standalone 'parallel'
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000041 /// directive.
42 ParallelOutlinedRegion,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000043 /// Region with outlined function for standalone 'task' directive.
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000044 TaskOutlinedRegion,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000045 /// Region for constructs that do not require function outlining,
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000046 /// like 'for', 'sections', 'atomic' etc. directives.
47 InlinedRegion,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000048 /// Region with outlined function for standalone 'target' directive.
Samuel Antaobed3c462015-10-02 16:14:20 +000049 TargetRegion,
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000050 };
Alexey Bataev18095712014-10-10 12:19:54 +000051
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000052 CGOpenMPRegionInfo(const CapturedStmt &CS,
53 const CGOpenMPRegionKind RegionKind,
Alexey Bataev25e5b442015-09-15 12:52:43 +000054 const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind,
55 bool HasCancel)
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000056 : CGCapturedStmtInfo(CS, CR_OpenMP), RegionKind(RegionKind),
Alexey Bataev25e5b442015-09-15 12:52:43 +000057 CodeGen(CodeGen), Kind(Kind), HasCancel(HasCancel) {}
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000058
59 CGOpenMPRegionInfo(const CGOpenMPRegionKind RegionKind,
Alexey Bataev25e5b442015-09-15 12:52:43 +000060 const RegionCodeGenTy &CodeGen, OpenMPDirectiveKind Kind,
61 bool HasCancel)
Alexey Bataev81c7ea02015-07-03 09:56:58 +000062 : CGCapturedStmtInfo(CR_OpenMP), RegionKind(RegionKind), CodeGen(CodeGen),
Alexey Bataev25e5b442015-09-15 12:52:43 +000063 Kind(Kind), HasCancel(HasCancel) {}
Alexey Bataev8cbe0a62015-02-26 10:27:34 +000064
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000065 /// Get a variable or parameter for storing global thread id
Alexey Bataev18095712014-10-10 12:19:54 +000066 /// inside OpenMP construct.
Alexey Bataev8cbe0a62015-02-26 10:27:34 +000067 virtual const VarDecl *getThreadIDVariable() const = 0;
Alexey Bataev18095712014-10-10 12:19:54 +000068
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000069 /// Emit the captured statement body.
Hans Wennborg7eb54642015-09-10 17:07:54 +000070 void EmitBody(CodeGenFunction &CGF, const Stmt *S) override;
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000071
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000072 /// Get an LValue for the current ThreadID variable.
Alexey Bataev62b63b12015-03-10 07:28:44 +000073 /// \return LValue for thread id variable. This LValue always has type int32*.
74 virtual LValue getThreadIDVariableLValue(CodeGenFunction &CGF);
Alexey Bataev18095712014-10-10 12:19:54 +000075
Alexey Bataev48591dd2016-04-20 04:01:36 +000076 virtual void emitUntiedSwitch(CodeGenFunction & /*CGF*/) {}
77
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000078 CGOpenMPRegionKind getRegionKind() const { return RegionKind; }
Alexey Bataev8cbe0a62015-02-26 10:27:34 +000079
Alexey Bataev81c7ea02015-07-03 09:56:58 +000080 OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
81
Alexey Bataev25e5b442015-09-15 12:52:43 +000082 bool hasCancel() const { return HasCancel; }
83
Alexey Bataev18095712014-10-10 12:19:54 +000084 static bool classof(const CGCapturedStmtInfo *Info) {
85 return Info->getKind() == CR_OpenMP;
86 }
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000087
Alexey Bataev48591dd2016-04-20 04:01:36 +000088 ~CGOpenMPRegionInfo() override = default;
89
Alexey Bataev8cbe0a62015-02-26 10:27:34 +000090protected:
Alexey Bataev6f1ffc02015-04-10 04:50:10 +000091 CGOpenMPRegionKind RegionKind;
Hans Wennborg45c74392016-01-12 20:54:36 +000092 RegionCodeGenTy CodeGen;
Alexey Bataev81c7ea02015-07-03 09:56:58 +000093 OpenMPDirectiveKind Kind;
Alexey Bataev25e5b442015-09-15 12:52:43 +000094 bool HasCancel;
Alexey Bataev8cbe0a62015-02-26 10:27:34 +000095};
Alexey Bataev18095712014-10-10 12:19:54 +000096
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000097/// API for captured statement code generation in OpenMP constructs.
Alexey Bataev48591dd2016-04-20 04:01:36 +000098class CGOpenMPOutlinedRegionInfo final : public CGOpenMPRegionInfo {
Alexey Bataev8cbe0a62015-02-26 10:27:34 +000099public:
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000100 CGOpenMPOutlinedRegionInfo(const CapturedStmt &CS, const VarDecl *ThreadIDVar,
Alexey Bataev81c7ea02015-07-03 09:56:58 +0000101 const RegionCodeGenTy &CodeGen,
Arpith Chacko Jacobbb36fe82017-01-10 15:42:51 +0000102 OpenMPDirectiveKind Kind, bool HasCancel,
103 StringRef HelperName)
Alexey Bataev25e5b442015-09-15 12:52:43 +0000104 : CGOpenMPRegionInfo(CS, ParallelOutlinedRegion, CodeGen, Kind,
105 HasCancel),
Arpith Chacko Jacobbb36fe82017-01-10 15:42:51 +0000106 ThreadIDVar(ThreadIDVar), HelperName(HelperName) {
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000107 assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region.");
108 }
Eugene Zelenko0a4f3f42016-02-10 19:11:58 +0000109
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000110 /// Get a variable or parameter for storing global thread id
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000111 /// inside OpenMP construct.
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000112 const VarDecl *getThreadIDVariable() const override { return ThreadIDVar; }
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000113
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000114 /// Get the name of the capture helper.
Arpith Chacko Jacobbb36fe82017-01-10 15:42:51 +0000115 StringRef getHelperName() const override { return HelperName; }
Alexey Bataev18095712014-10-10 12:19:54 +0000116
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000117 static bool classof(const CGCapturedStmtInfo *Info) {
118 return CGOpenMPRegionInfo::classof(Info) &&
119 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() ==
120 ParallelOutlinedRegion;
121 }
122
Alexey Bataev18095712014-10-10 12:19:54 +0000123private:
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000124 /// A variable or parameter storing global thread id for OpenMP
Alexey Bataev18095712014-10-10 12:19:54 +0000125 /// constructs.
126 const VarDecl *ThreadIDVar;
Arpith Chacko Jacobbb36fe82017-01-10 15:42:51 +0000127 StringRef HelperName;
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000128};
129
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000130/// API for captured statement code generation in OpenMP constructs.
Alexey Bataev48591dd2016-04-20 04:01:36 +0000131class CGOpenMPTaskOutlinedRegionInfo final : public CGOpenMPRegionInfo {
Alexey Bataev62b63b12015-03-10 07:28:44 +0000132public:
Alexey Bataev48591dd2016-04-20 04:01:36 +0000133 class UntiedTaskActionTy final : public PrePostActionTy {
134 bool Untied;
135 const VarDecl *PartIDVar;
136 const RegionCodeGenTy UntiedCodeGen;
137 llvm::SwitchInst *UntiedSwitch = nullptr;
138
139 public:
140 UntiedTaskActionTy(bool Tied, const VarDecl *PartIDVar,
141 const RegionCodeGenTy &UntiedCodeGen)
142 : Untied(!Tied), PartIDVar(PartIDVar), UntiedCodeGen(UntiedCodeGen) {}
143 void Enter(CodeGenFunction &CGF) override {
144 if (Untied) {
145 // Emit task switching point.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000146 LValue PartIdLVal = CGF.EmitLoadOfPointerLValue(
Alexey Bataev48591dd2016-04-20 04:01:36 +0000147 CGF.GetAddrOfLocalVar(PartIDVar),
148 PartIDVar->getType()->castAs<PointerType>());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000149 llvm::Value *Res =
150 CGF.EmitLoadOfScalar(PartIdLVal, PartIDVar->getLocation());
151 llvm::BasicBlock *DoneBB = CGF.createBasicBlock(".untied.done.");
Alexey Bataev48591dd2016-04-20 04:01:36 +0000152 UntiedSwitch = CGF.Builder.CreateSwitch(Res, DoneBB);
153 CGF.EmitBlock(DoneBB);
154 CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);
155 CGF.EmitBlock(CGF.createBasicBlock(".untied.jmp."));
156 UntiedSwitch->addCase(CGF.Builder.getInt32(0),
157 CGF.Builder.GetInsertBlock());
158 emitUntiedSwitch(CGF);
159 }
160 }
161 void emitUntiedSwitch(CodeGenFunction &CGF) const {
162 if (Untied) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000163 LValue PartIdLVal = CGF.EmitLoadOfPointerLValue(
Alexey Bataev48591dd2016-04-20 04:01:36 +0000164 CGF.GetAddrOfLocalVar(PartIDVar),
165 PartIDVar->getType()->castAs<PointerType>());
166 CGF.EmitStoreOfScalar(CGF.Builder.getInt32(UntiedSwitch->getNumCases()),
167 PartIdLVal);
168 UntiedCodeGen(CGF);
169 CodeGenFunction::JumpDest CurPoint =
170 CGF.getJumpDestInCurrentScope(".untied.next.");
171 CGF.EmitBranchThroughCleanup(CGF.ReturnBlock);
172 CGF.EmitBlock(CGF.createBasicBlock(".untied.jmp."));
173 UntiedSwitch->addCase(CGF.Builder.getInt32(UntiedSwitch->getNumCases()),
174 CGF.Builder.GetInsertBlock());
175 CGF.EmitBranchThroughCleanup(CurPoint);
176 CGF.EmitBlock(CurPoint.getBlock());
177 }
178 }
179 unsigned getNumberOfParts() const { return UntiedSwitch->getNumCases(); }
180 };
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000181 CGOpenMPTaskOutlinedRegionInfo(const CapturedStmt &CS,
Alexey Bataev62b63b12015-03-10 07:28:44 +0000182 const VarDecl *ThreadIDVar,
Alexey Bataev81c7ea02015-07-03 09:56:58 +0000183 const RegionCodeGenTy &CodeGen,
Alexey Bataev48591dd2016-04-20 04:01:36 +0000184 OpenMPDirectiveKind Kind, bool HasCancel,
185 const UntiedTaskActionTy &Action)
Alexey Bataev25e5b442015-09-15 12:52:43 +0000186 : CGOpenMPRegionInfo(CS, TaskOutlinedRegion, CodeGen, Kind, HasCancel),
Alexey Bataev48591dd2016-04-20 04:01:36 +0000187 ThreadIDVar(ThreadIDVar), Action(Action) {
Alexey Bataev62b63b12015-03-10 07:28:44 +0000188 assert(ThreadIDVar != nullptr && "No ThreadID in OpenMP region.");
189 }
Eugene Zelenko0a4f3f42016-02-10 19:11:58 +0000190
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000191 /// Get a variable or parameter for storing global thread id
Alexey Bataev62b63b12015-03-10 07:28:44 +0000192 /// inside OpenMP construct.
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000193 const VarDecl *getThreadIDVariable() const override { return ThreadIDVar; }
Alexey Bataev62b63b12015-03-10 07:28:44 +0000194
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000195 /// Get an LValue for the current ThreadID variable.
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000196 LValue getThreadIDVariableLValue(CodeGenFunction &CGF) override;
Alexey Bataev62b63b12015-03-10 07:28:44 +0000197
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000198 /// Get the name of the capture helper.
Alexey Bataev62b63b12015-03-10 07:28:44 +0000199 StringRef getHelperName() const override { return ".omp_outlined."; }
200
Alexey Bataev48591dd2016-04-20 04:01:36 +0000201 void emitUntiedSwitch(CodeGenFunction &CGF) override {
202 Action.emitUntiedSwitch(CGF);
203 }
204
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000205 static bool classof(const CGCapturedStmtInfo *Info) {
206 return CGOpenMPRegionInfo::classof(Info) &&
207 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() ==
208 TaskOutlinedRegion;
209 }
210
Alexey Bataev62b63b12015-03-10 07:28:44 +0000211private:
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000212 /// A variable or parameter storing global thread id for OpenMP
Alexey Bataev62b63b12015-03-10 07:28:44 +0000213 /// constructs.
214 const VarDecl *ThreadIDVar;
Alexey Bataev48591dd2016-04-20 04:01:36 +0000215 /// Action for emitting code for untied tasks.
216 const UntiedTaskActionTy &Action;
Alexey Bataev62b63b12015-03-10 07:28:44 +0000217};
218
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000219/// API for inlined captured statement code generation in OpenMP
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000220/// constructs.
221class CGOpenMPInlinedRegionInfo : public CGOpenMPRegionInfo {
222public:
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000223 CGOpenMPInlinedRegionInfo(CodeGenFunction::CGCapturedStmtInfo *OldCSI,
Alexey Bataev81c7ea02015-07-03 09:56:58 +0000224 const RegionCodeGenTy &CodeGen,
Alexey Bataev25e5b442015-09-15 12:52:43 +0000225 OpenMPDirectiveKind Kind, bool HasCancel)
226 : CGOpenMPRegionInfo(InlinedRegion, CodeGen, Kind, HasCancel),
227 OldCSI(OldCSI),
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000228 OuterRegionInfo(dyn_cast_or_null<CGOpenMPRegionInfo>(OldCSI)) {}
Eugene Zelenko0a4f3f42016-02-10 19:11:58 +0000229
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000230 // Retrieve the value of the context parameter.
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000231 llvm::Value *getContextValue() const override {
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000232 if (OuterRegionInfo)
233 return OuterRegionInfo->getContextValue();
234 llvm_unreachable("No context value for inlined OpenMP region");
235 }
Eugene Zelenko0a4f3f42016-02-10 19:11:58 +0000236
Hans Wennborg7eb54642015-09-10 17:07:54 +0000237 void setContextValue(llvm::Value *V) override {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000238 if (OuterRegionInfo) {
239 OuterRegionInfo->setContextValue(V);
240 return;
241 }
242 llvm_unreachable("No context value for inlined OpenMP region");
243 }
Eugene Zelenko0a4f3f42016-02-10 19:11:58 +0000244
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000245 /// Lookup the captured field decl for a variable.
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000246 const FieldDecl *lookup(const VarDecl *VD) const override {
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000247 if (OuterRegionInfo)
248 return OuterRegionInfo->lookup(VD);
Alexey Bataev69c62a92015-04-15 04:52:20 +0000249 // If there is no outer outlined region,no need to lookup in a list of
250 // captured variables, we can use the original one.
251 return nullptr;
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000252 }
Eugene Zelenko0a4f3f42016-02-10 19:11:58 +0000253
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000254 FieldDecl *getThisFieldDecl() const override {
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000255 if (OuterRegionInfo)
256 return OuterRegionInfo->getThisFieldDecl();
257 return nullptr;
258 }
Eugene Zelenko0a4f3f42016-02-10 19:11:58 +0000259
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000260 /// Get a variable or parameter for storing global thread id
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000261 /// inside OpenMP construct.
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000262 const VarDecl *getThreadIDVariable() const override {
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000263 if (OuterRegionInfo)
264 return OuterRegionInfo->getThreadIDVariable();
265 return nullptr;
266 }
Alexey Bataev62b63b12015-03-10 07:28:44 +0000267
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000268 /// Get an LValue for the current ThreadID variable.
Alexey Bataev311a9282017-10-12 13:51:32 +0000269 LValue getThreadIDVariableLValue(CodeGenFunction &CGF) override {
270 if (OuterRegionInfo)
271 return OuterRegionInfo->getThreadIDVariableLValue(CGF);
272 llvm_unreachable("No LValue for inlined OpenMP construct");
273 }
274
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000275 /// Get the name of the capture helper.
Alexander Kornienko34eb2072015-04-11 02:00:23 +0000276 StringRef getHelperName() const override {
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000277 if (auto *OuterRegionInfo = getOldCSI())
278 return OuterRegionInfo->getHelperName();
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000279 llvm_unreachable("No helper name for inlined OpenMP construct");
280 }
281
Alexey Bataev48591dd2016-04-20 04:01:36 +0000282 void emitUntiedSwitch(CodeGenFunction &CGF) override {
283 if (OuterRegionInfo)
284 OuterRegionInfo->emitUntiedSwitch(CGF);
285 }
286
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000287 CodeGenFunction::CGCapturedStmtInfo *getOldCSI() const { return OldCSI; }
288
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000289 static bool classof(const CGCapturedStmtInfo *Info) {
290 return CGOpenMPRegionInfo::classof(Info) &&
291 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() == InlinedRegion;
292 }
293
Alexey Bataev48591dd2016-04-20 04:01:36 +0000294 ~CGOpenMPInlinedRegionInfo() override = default;
295
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000296private:
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000297 /// CodeGen info about outer OpenMP region.
Alexey Bataev8cbe0a62015-02-26 10:27:34 +0000298 CodeGenFunction::CGCapturedStmtInfo *OldCSI;
299 CGOpenMPRegionInfo *OuterRegionInfo;
Alexey Bataev18095712014-10-10 12:19:54 +0000300};
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000301
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000302/// API for captured statement code generation in OpenMP target
Samuel Antaobed3c462015-10-02 16:14:20 +0000303/// constructs. For this captures, implicit parameters are used instead of the
Samuel Antaoee8fb302016-01-06 13:42:12 +0000304/// captured fields. The name of the target region has to be unique in a given
305/// application so it is provided by the client, because only the client has
306/// the information to generate that.
Alexey Bataev48591dd2016-04-20 04:01:36 +0000307class CGOpenMPTargetRegionInfo final : public CGOpenMPRegionInfo {
Samuel Antaobed3c462015-10-02 16:14:20 +0000308public:
309 CGOpenMPTargetRegionInfo(const CapturedStmt &CS,
Samuel Antaoee8fb302016-01-06 13:42:12 +0000310 const RegionCodeGenTy &CodeGen, StringRef HelperName)
Samuel Antaobed3c462015-10-02 16:14:20 +0000311 : CGOpenMPRegionInfo(CS, TargetRegion, CodeGen, OMPD_target,
Samuel Antaoee8fb302016-01-06 13:42:12 +0000312 /*HasCancel=*/false),
313 HelperName(HelperName) {}
Samuel Antaobed3c462015-10-02 16:14:20 +0000314
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000315 /// This is unused for target regions because each starts executing
Samuel Antaobed3c462015-10-02 16:14:20 +0000316 /// with a single thread.
317 const VarDecl *getThreadIDVariable() const override { return nullptr; }
318
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000319 /// Get the name of the capture helper.
Samuel Antaoee8fb302016-01-06 13:42:12 +0000320 StringRef getHelperName() const override { return HelperName; }
Samuel Antaobed3c462015-10-02 16:14:20 +0000321
322 static bool classof(const CGCapturedStmtInfo *Info) {
323 return CGOpenMPRegionInfo::classof(Info) &&
324 cast<CGOpenMPRegionInfo>(Info)->getRegionKind() == TargetRegion;
325 }
Samuel Antaoee8fb302016-01-06 13:42:12 +0000326
327private:
328 StringRef HelperName;
Samuel Antaobed3c462015-10-02 16:14:20 +0000329};
330
Alexey Bataev14fa1c62016-03-29 05:34:15 +0000331static void EmptyCodeGen(CodeGenFunction &, PrePostActionTy &) {
Samuel Antaob68e2db2016-03-03 16:20:23 +0000332 llvm_unreachable("No codegen for expressions");
333}
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000334/// API for generation of expressions captured in a innermost OpenMP
Samuel Antaob68e2db2016-03-03 16:20:23 +0000335/// region.
Alexey Bataev48591dd2016-04-20 04:01:36 +0000336class CGOpenMPInnerExprInfo final : public CGOpenMPInlinedRegionInfo {
Samuel Antaob68e2db2016-03-03 16:20:23 +0000337public:
338 CGOpenMPInnerExprInfo(CodeGenFunction &CGF, const CapturedStmt &CS)
339 : CGOpenMPInlinedRegionInfo(CGF.CapturedStmtInfo, EmptyCodeGen,
340 OMPD_unknown,
341 /*HasCancel=*/false),
342 PrivScope(CGF) {
343 // Make sure the globals captured in the provided statement are local by
344 // using the privatization logic. We assume the same variable is not
345 // captured more than once.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000346 for (const auto &C : CS.captures()) {
Samuel Antaob68e2db2016-03-03 16:20:23 +0000347 if (!C.capturesVariable() && !C.capturesVariableByCopy())
348 continue;
349
350 const VarDecl *VD = C.getCapturedVar();
351 if (VD->isLocalVarDeclOrParm())
352 continue;
353
Bruno Ricci5fc4db72018-12-21 14:10:18 +0000354 DeclRefExpr DRE(CGF.getContext(), const_cast<VarDecl *>(VD),
Samuel Antaob68e2db2016-03-03 16:20:23 +0000355 /*RefersToEnclosingVariableOrCapture=*/false,
356 VD->getType().getNonReferenceType(), VK_LValue,
Alexey Bataeva9b9cc02018-01-23 18:12:38 +0000357 C.getLocation());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000358 PrivScope.addPrivate(
359 VD, [&CGF, &DRE]() { return CGF.EmitLValue(&DRE).getAddress(); });
Samuel Antaob68e2db2016-03-03 16:20:23 +0000360 }
361 (void)PrivScope.Privatize();
362 }
363
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000364 /// Lookup the captured field decl for a variable.
Samuel Antaob68e2db2016-03-03 16:20:23 +0000365 const FieldDecl *lookup(const VarDecl *VD) const override {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000366 if (const FieldDecl *FD = CGOpenMPInlinedRegionInfo::lookup(VD))
Samuel Antaob68e2db2016-03-03 16:20:23 +0000367 return FD;
368 return nullptr;
369 }
370
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000371 /// Emit the captured statement body.
Samuel Antaob68e2db2016-03-03 16:20:23 +0000372 void EmitBody(CodeGenFunction &CGF, const Stmt *S) override {
373 llvm_unreachable("No body for expressions");
374 }
375
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000376 /// Get a variable or parameter for storing global thread id
Samuel Antaob68e2db2016-03-03 16:20:23 +0000377 /// inside OpenMP construct.
378 const VarDecl *getThreadIDVariable() const override {
379 llvm_unreachable("No thread id for expressions");
380 }
381
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000382 /// Get the name of the capture helper.
Samuel Antaob68e2db2016-03-03 16:20:23 +0000383 StringRef getHelperName() const override {
384 llvm_unreachable("No helper name for expressions");
385 }
386
387 static bool classof(const CGCapturedStmtInfo *Info) { return false; }
388
389private:
390 /// Private scope to capture global variables.
391 CodeGenFunction::OMPPrivateScope PrivScope;
392};
393
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000394/// RAII for emitting code of OpenMP constructs.
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000395class InlinedOpenMPRegionRAII {
396 CodeGenFunction &CGF;
Alexey Bataev4ba78a42016-04-27 07:56:03 +0000397 llvm::DenseMap<const VarDecl *, FieldDecl *> LambdaCaptureFields;
398 FieldDecl *LambdaThisCaptureField = nullptr;
Alexey Bataeva8a9153a2017-12-29 18:07:07 +0000399 const CodeGen::CGBlockInfo *BlockInfo = nullptr;
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000400
401public:
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000402 /// Constructs region for combined constructs.
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000403 /// \param CodeGen Code generation sequence for combined directives. Includes
404 /// a list of functions used for code generation of implicitly inlined
405 /// regions.
Alexey Bataev81c7ea02015-07-03 09:56:58 +0000406 InlinedOpenMPRegionRAII(CodeGenFunction &CGF, const RegionCodeGenTy &CodeGen,
Alexey Bataev25e5b442015-09-15 12:52:43 +0000407 OpenMPDirectiveKind Kind, bool HasCancel)
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000408 : CGF(CGF) {
409 // Start emission for the construct.
Alexey Bataev25e5b442015-09-15 12:52:43 +0000410 CGF.CapturedStmtInfo = new CGOpenMPInlinedRegionInfo(
411 CGF.CapturedStmtInfo, CodeGen, Kind, HasCancel);
Alexey Bataev4ba78a42016-04-27 07:56:03 +0000412 std::swap(CGF.LambdaCaptureFields, LambdaCaptureFields);
413 LambdaThisCaptureField = CGF.LambdaThisCaptureField;
414 CGF.LambdaThisCaptureField = nullptr;
Alexey Bataeva8a9153a2017-12-29 18:07:07 +0000415 BlockInfo = CGF.BlockInfo;
416 CGF.BlockInfo = nullptr;
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000417 }
Eugene Zelenko0a4f3f42016-02-10 19:11:58 +0000418
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000419 ~InlinedOpenMPRegionRAII() {
420 // Restore original CapturedStmtInfo only if we're done with code emission.
421 auto *OldCSI =
422 cast<CGOpenMPInlinedRegionInfo>(CGF.CapturedStmtInfo)->getOldCSI();
423 delete CGF.CapturedStmtInfo;
424 CGF.CapturedStmtInfo = OldCSI;
Alexey Bataev4ba78a42016-04-27 07:56:03 +0000425 std::swap(CGF.LambdaCaptureFields, LambdaCaptureFields);
426 CGF.LambdaThisCaptureField = LambdaThisCaptureField;
Alexey Bataeva8a9153a2017-12-29 18:07:07 +0000427 CGF.BlockInfo = BlockInfo;
Alexey Bataev6f1ffc02015-04-10 04:50:10 +0000428 }
429};
430
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000431/// Values for bit flags used in the ident_t to describe the fields.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000432/// All enumeric elements are named and described in accordance with the code
James Y Knight5d71fc52019-01-29 16:37:27 +0000433/// from https://github.com/llvm/llvm-project/blob/master/openmp/runtime/src/kmp.h
Alexey Bataev0f87dbe2017-08-14 17:56:13 +0000434enum OpenMPLocationFlags : unsigned {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000435 /// Use trampoline for internal microtask.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000436 OMP_IDENT_IMD = 0x01,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000437 /// Use c-style ident structure.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000438 OMP_IDENT_KMPC = 0x02,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000439 /// Atomic reduction option for kmpc_reduce.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000440 OMP_ATOMIC_REDUCE = 0x10,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000441 /// Explicit 'barrier' directive.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000442 OMP_IDENT_BARRIER_EXPL = 0x20,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000443 /// Implicit barrier in code.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000444 OMP_IDENT_BARRIER_IMPL = 0x40,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000445 /// Implicit barrier in 'for' directive.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000446 OMP_IDENT_BARRIER_IMPL_FOR = 0x40,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000447 /// Implicit barrier in 'sections' directive.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000448 OMP_IDENT_BARRIER_IMPL_SECTIONS = 0xC0,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000449 /// Implicit barrier in 'single' directive.
Alexey Bataev0f87dbe2017-08-14 17:56:13 +0000450 OMP_IDENT_BARRIER_IMPL_SINGLE = 0x140,
451 /// Call of __kmp_for_static_init for static loop.
452 OMP_IDENT_WORK_LOOP = 0x200,
453 /// Call of __kmp_for_static_init for sections.
454 OMP_IDENT_WORK_SECTIONS = 0x400,
455 /// Call of __kmp_for_static_init for distribute.
456 OMP_IDENT_WORK_DISTRIBUTE = 0x800,
457 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/OMP_IDENT_WORK_DISTRIBUTE)
Alexey Bataev50b3c952016-02-19 10:38:26 +0000458};
459
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +0000460namespace {
461LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
462/// Values for bit flags for marking which requires clauses have been used.
463enum OpenMPOffloadingRequiresDirFlags : int64_t {
464 /// flag undefined.
465 OMP_REQ_UNDEFINED = 0x000,
466 /// no requires clause present.
467 OMP_REQ_NONE = 0x001,
468 /// reverse_offload clause.
469 OMP_REQ_REVERSE_OFFLOAD = 0x002,
470 /// unified_address clause.
471 OMP_REQ_UNIFIED_ADDRESS = 0x004,
472 /// unified_shared_memory clause.
473 OMP_REQ_UNIFIED_SHARED_MEMORY = 0x008,
474 /// dynamic_allocators clause.
475 OMP_REQ_DYNAMIC_ALLOCATORS = 0x010,
476 LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/OMP_REQ_DYNAMIC_ALLOCATORS)
477};
478} // anonymous namespace
479
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000480/// Describes ident structure that describes a source location.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000481/// All descriptions are taken from
James Y Knight5d71fc52019-01-29 16:37:27 +0000482/// https://github.com/llvm/llvm-project/blob/master/openmp/runtime/src/kmp.h
Alexey Bataev50b3c952016-02-19 10:38:26 +0000483/// Original structure:
484/// typedef struct ident {
485/// kmp_int32 reserved_1; /**< might be used in Fortran;
486/// see above */
487/// kmp_int32 flags; /**< also f.flags; KMP_IDENT_xxx flags;
488/// KMP_IDENT_KMPC identifies this union
489/// member */
490/// kmp_int32 reserved_2; /**< not really used in Fortran any more;
491/// see above */
492///#if USE_ITT_BUILD
493/// /* but currently used for storing
494/// region-specific ITT */
495/// /* contextual information. */
496///#endif /* USE_ITT_BUILD */
497/// kmp_int32 reserved_3; /**< source[4] in Fortran, do not use for
498/// C++ */
499/// char const *psource; /**< String describing the source location.
500/// The string is composed of semi-colon separated
501// fields which describe the source file,
502/// the function and a pair of line numbers that
503/// delimit the construct.
504/// */
505/// } ident_t;
506enum IdentFieldIndex {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000507 /// might be used in Fortran
Alexey Bataev50b3c952016-02-19 10:38:26 +0000508 IdentField_Reserved_1,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000509 /// OMP_IDENT_xxx flags; OMP_IDENT_KMPC identifies this union member.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000510 IdentField_Flags,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000511 /// Not really used in Fortran any more
Alexey Bataev50b3c952016-02-19 10:38:26 +0000512 IdentField_Reserved_2,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000513 /// Source[4] in Fortran, do not use for C++
Alexey Bataev50b3c952016-02-19 10:38:26 +0000514 IdentField_Reserved_3,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000515 /// String describing the source location. The string is composed of
Alexey Bataev50b3c952016-02-19 10:38:26 +0000516 /// semi-colon separated fields which describe the source file, the function
517 /// and a pair of line numbers that delimit the construct.
518 IdentField_PSource
519};
520
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000521/// Schedule types for 'omp for' loops (these enumerators are taken from
Alexey Bataev50b3c952016-02-19 10:38:26 +0000522/// the enum sched_type in kmp.h).
523enum OpenMPSchedType {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000524 /// Lower bound for default (unordered) versions.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000525 OMP_sch_lower = 32,
526 OMP_sch_static_chunked = 33,
527 OMP_sch_static = 34,
528 OMP_sch_dynamic_chunked = 35,
529 OMP_sch_guided_chunked = 36,
530 OMP_sch_runtime = 37,
531 OMP_sch_auto = 38,
Alexey Bataev6cff6242016-05-30 13:05:14 +0000532 /// static with chunk adjustment (e.g., simd)
Samuel Antao4c8035b2016-12-12 18:00:20 +0000533 OMP_sch_static_balanced_chunked = 45,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000534 /// Lower bound for 'ordered' versions.
Alexey Bataev50b3c952016-02-19 10:38:26 +0000535 OMP_ord_lower = 64,
536 OMP_ord_static_chunked = 65,
537 OMP_ord_static = 66,
538 OMP_ord_dynamic_chunked = 67,
539 OMP_ord_guided_chunked = 68,
540 OMP_ord_runtime = 69,
541 OMP_ord_auto = 70,
542 OMP_sch_default = OMP_sch_static,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000543 /// dist_schedule types
Carlo Bertollifc35ad22016-03-07 16:04:49 +0000544 OMP_dist_sch_static_chunked = 91,
545 OMP_dist_sch_static = 92,
Alexey Bataev9ebd7422016-05-10 09:57:36 +0000546 /// Support for OpenMP 4.5 monotonic and nonmonotonic schedule modifiers.
547 /// Set if the monotonic schedule modifier was present.
548 OMP_sch_modifier_monotonic = (1 << 29),
549 /// Set if the nonmonotonic schedule modifier was present.
550 OMP_sch_modifier_nonmonotonic = (1 << 30),
Alexey Bataev50b3c952016-02-19 10:38:26 +0000551};
552
553enum OpenMPRTLFunction {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000554 /// Call to void __kmpc_fork_call(ident_t *loc, kmp_int32 argc,
Alexey Bataev50b3c952016-02-19 10:38:26 +0000555 /// kmpc_micro microtask, ...);
556 OMPRTL__kmpc_fork_call,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000557 /// Call to void *__kmpc_threadprivate_cached(ident_t *loc,
Alexey Bataev50b3c952016-02-19 10:38:26 +0000558 /// kmp_int32 global_tid, void *data, size_t size, void ***cache);
559 OMPRTL__kmpc_threadprivate_cached,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000560 /// Call to void __kmpc_threadprivate_register( ident_t *,
Alexey Bataev50b3c952016-02-19 10:38:26 +0000561 /// void *data, kmpc_ctor ctor, kmpc_cctor cctor, kmpc_dtor dtor);
562 OMPRTL__kmpc_threadprivate_register,
563 // Call to __kmpc_int32 kmpc_global_thread_num(ident_t *loc);
564 OMPRTL__kmpc_global_thread_num,
565 // Call to void __kmpc_critical(ident_t *loc, kmp_int32 global_tid,
566 // kmp_critical_name *crit);
567 OMPRTL__kmpc_critical,
568 // Call to void __kmpc_critical_with_hint(ident_t *loc, kmp_int32
569 // global_tid, kmp_critical_name *crit, uintptr_t hint);
570 OMPRTL__kmpc_critical_with_hint,
571 // Call to void __kmpc_end_critical(ident_t *loc, kmp_int32 global_tid,
572 // kmp_critical_name *crit);
573 OMPRTL__kmpc_end_critical,
574 // Call to kmp_int32 __kmpc_cancel_barrier(ident_t *loc, kmp_int32
575 // global_tid);
576 OMPRTL__kmpc_cancel_barrier,
577 // Call to void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid);
578 OMPRTL__kmpc_barrier,
579 // Call to void __kmpc_for_static_fini(ident_t *loc, kmp_int32 global_tid);
580 OMPRTL__kmpc_for_static_fini,
581 // Call to void __kmpc_serialized_parallel(ident_t *loc, kmp_int32
582 // global_tid);
583 OMPRTL__kmpc_serialized_parallel,
584 // Call to void __kmpc_end_serialized_parallel(ident_t *loc, kmp_int32
585 // global_tid);
586 OMPRTL__kmpc_end_serialized_parallel,
587 // Call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid,
588 // kmp_int32 num_threads);
589 OMPRTL__kmpc_push_num_threads,
590 // Call to void __kmpc_flush(ident_t *loc);
591 OMPRTL__kmpc_flush,
592 // Call to kmp_int32 __kmpc_master(ident_t *, kmp_int32 global_tid);
593 OMPRTL__kmpc_master,
594 // Call to void __kmpc_end_master(ident_t *, kmp_int32 global_tid);
595 OMPRTL__kmpc_end_master,
596 // Call to kmp_int32 __kmpc_omp_taskyield(ident_t *, kmp_int32 global_tid,
597 // int end_part);
598 OMPRTL__kmpc_omp_taskyield,
599 // Call to kmp_int32 __kmpc_single(ident_t *, kmp_int32 global_tid);
600 OMPRTL__kmpc_single,
601 // Call to void __kmpc_end_single(ident_t *, kmp_int32 global_tid);
602 OMPRTL__kmpc_end_single,
603 // Call to kmp_task_t * __kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid,
604 // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
605 // kmp_routine_entry_t *task_entry);
606 OMPRTL__kmpc_omp_task_alloc,
607 // Call to kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t *
608 // new_task);
609 OMPRTL__kmpc_omp_task,
610 // Call to void __kmpc_copyprivate(ident_t *loc, kmp_int32 global_tid,
611 // size_t cpy_size, void *cpy_data, void(*cpy_func)(void *, void *),
612 // kmp_int32 didit);
613 OMPRTL__kmpc_copyprivate,
614 // Call to kmp_int32 __kmpc_reduce(ident_t *loc, kmp_int32 global_tid,
615 // kmp_int32 num_vars, size_t reduce_size, void *reduce_data, void
616 // (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name *lck);
617 OMPRTL__kmpc_reduce,
618 // Call to kmp_int32 __kmpc_reduce_nowait(ident_t *loc, kmp_int32
619 // global_tid, kmp_int32 num_vars, size_t reduce_size, void *reduce_data,
620 // void (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name
621 // *lck);
622 OMPRTL__kmpc_reduce_nowait,
623 // Call to void __kmpc_end_reduce(ident_t *loc, kmp_int32 global_tid,
624 // kmp_critical_name *lck);
625 OMPRTL__kmpc_end_reduce,
626 // Call to void __kmpc_end_reduce_nowait(ident_t *loc, kmp_int32 global_tid,
627 // kmp_critical_name *lck);
628 OMPRTL__kmpc_end_reduce_nowait,
629 // Call to void __kmpc_omp_task_begin_if0(ident_t *, kmp_int32 gtid,
630 // kmp_task_t * new_task);
631 OMPRTL__kmpc_omp_task_begin_if0,
632 // Call to void __kmpc_omp_task_complete_if0(ident_t *, kmp_int32 gtid,
633 // kmp_task_t * new_task);
634 OMPRTL__kmpc_omp_task_complete_if0,
635 // Call to void __kmpc_ordered(ident_t *loc, kmp_int32 global_tid);
636 OMPRTL__kmpc_ordered,
637 // Call to void __kmpc_end_ordered(ident_t *loc, kmp_int32 global_tid);
638 OMPRTL__kmpc_end_ordered,
639 // Call to kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32
640 // global_tid);
641 OMPRTL__kmpc_omp_taskwait,
642 // Call to void __kmpc_taskgroup(ident_t *loc, kmp_int32 global_tid);
643 OMPRTL__kmpc_taskgroup,
644 // Call to void __kmpc_end_taskgroup(ident_t *loc, kmp_int32 global_tid);
645 OMPRTL__kmpc_end_taskgroup,
646 // Call to void __kmpc_push_proc_bind(ident_t *loc, kmp_int32 global_tid,
647 // int proc_bind);
648 OMPRTL__kmpc_push_proc_bind,
649 // Call to kmp_int32 __kmpc_omp_task_with_deps(ident_t *loc_ref, kmp_int32
650 // gtid, kmp_task_t * new_task, kmp_int32 ndeps, kmp_depend_info_t
651 // *dep_list, kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list);
652 OMPRTL__kmpc_omp_task_with_deps,
653 // Call to void __kmpc_omp_wait_deps(ident_t *loc_ref, kmp_int32
654 // gtid, kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32
655 // ndeps_noalias, kmp_depend_info_t *noalias_dep_list);
656 OMPRTL__kmpc_omp_wait_deps,
657 // Call to kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32
658 // global_tid, kmp_int32 cncl_kind);
659 OMPRTL__kmpc_cancellationpoint,
660 // Call to kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid,
661 // kmp_int32 cncl_kind);
662 OMPRTL__kmpc_cancel,
Carlo Bertolli430d8ec2016-03-03 20:34:23 +0000663 // Call to void __kmpc_push_num_teams(ident_t *loc, kmp_int32 global_tid,
664 // kmp_int32 num_teams, kmp_int32 thread_limit);
665 OMPRTL__kmpc_push_num_teams,
Alexey Bataev7292c292016-04-25 12:22:29 +0000666 // Call to void __kmpc_fork_teams(ident_t *loc, kmp_int32 argc, kmpc_micro
667 // microtask, ...);
Carlo Bertolli430d8ec2016-03-03 20:34:23 +0000668 OMPRTL__kmpc_fork_teams,
Alexey Bataev7292c292016-04-25 12:22:29 +0000669 // Call to void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t *task, int
670 // if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int nogroup, int
671 // sched, kmp_uint64 grainsize, void *task_dup);
672 OMPRTL__kmpc_taskloop,
Alexey Bataev8b427062016-05-25 12:36:08 +0000673 // Call to void __kmpc_doacross_init(ident_t *loc, kmp_int32 gtid, kmp_int32
674 // num_dims, struct kmp_dim *dims);
675 OMPRTL__kmpc_doacross_init,
676 // Call to void __kmpc_doacross_fini(ident_t *loc, kmp_int32 gtid);
677 OMPRTL__kmpc_doacross_fini,
678 // Call to void __kmpc_doacross_post(ident_t *loc, kmp_int32 gtid, kmp_int64
679 // *vec);
680 OMPRTL__kmpc_doacross_post,
681 // Call to void __kmpc_doacross_wait(ident_t *loc, kmp_int32 gtid, kmp_int64
682 // *vec);
683 OMPRTL__kmpc_doacross_wait,
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000684 // Call to void *__kmpc_task_reduction_init(int gtid, int num_data, void
685 // *data);
686 OMPRTL__kmpc_task_reduction_init,
687 // Call to void *__kmpc_task_reduction_get_th_data(int gtid, void *tg, void
688 // *d);
689 OMPRTL__kmpc_task_reduction_get_th_data,
Alexey Bataev6cf7b712019-04-08 19:06:42 +0000690 // Call to void *__kmpc_alloc(int gtid, size_t sz, omp_allocator_handle_t al);
Alexey Bataev4f680db2019-03-19 16:41:16 +0000691 OMPRTL__kmpc_alloc,
Alexey Bataev6cf7b712019-04-08 19:06:42 +0000692 // Call to void __kmpc_free(int gtid, void *ptr, omp_allocator_handle_t al);
Alexey Bataev4f680db2019-03-19 16:41:16 +0000693 OMPRTL__kmpc_free,
Alexey Bataev50b3c952016-02-19 10:38:26 +0000694
695 //
696 // Offloading related calls
697 //
Alexey Bataev7bb33532019-01-07 21:30:43 +0000698 // Call to void __kmpc_push_target_tripcount(int64_t device_id, kmp_uint64
699 // size);
700 OMPRTL__kmpc_push_target_tripcount,
George Rokos63bc9d62017-11-21 18:25:12 +0000701 // Call to int32_t __tgt_target(int64_t device_id, void *host_ptr, int32_t
702 // arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
Alexey Bataev50b3c952016-02-19 10:38:26 +0000703 // *arg_types);
704 OMPRTL__tgt_target,
Alexey Bataeva9f77c62017-12-13 21:04:20 +0000705 // Call to int32_t __tgt_target_nowait(int64_t device_id, void *host_ptr,
706 // int32_t arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
707 // *arg_types);
708 OMPRTL__tgt_target_nowait,
George Rokos63bc9d62017-11-21 18:25:12 +0000709 // Call to int32_t __tgt_target_teams(int64_t device_id, void *host_ptr,
710 // int32_t arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
711 // *arg_types, int32_t num_teams, int32_t thread_limit);
Samuel Antaob68e2db2016-03-03 16:20:23 +0000712 OMPRTL__tgt_target_teams,
Alexey Bataeva9f77c62017-12-13 21:04:20 +0000713 // Call to int32_t __tgt_target_teams_nowait(int64_t device_id, void
714 // *host_ptr, int32_t arg_num, void** args_base, void **args, size_t
715 // *arg_sizes, int64_t *arg_types, int32_t num_teams, int32_t thread_limit);
716 OMPRTL__tgt_target_teams_nowait,
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +0000717 // Call to void __tgt_register_requires(int64_t flags);
718 OMPRTL__tgt_register_requires,
Alexey Bataev50b3c952016-02-19 10:38:26 +0000719 // Call to void __tgt_register_lib(__tgt_bin_desc *desc);
720 OMPRTL__tgt_register_lib,
721 // Call to void __tgt_unregister_lib(__tgt_bin_desc *desc);
722 OMPRTL__tgt_unregister_lib,
George Rokos63bc9d62017-11-21 18:25:12 +0000723 // Call to void __tgt_target_data_begin(int64_t device_id, int32_t arg_num,
724 // void** args_base, void **args, size_t *arg_sizes, int64_t *arg_types);
Samuel Antaodf158d52016-04-27 22:58:19 +0000725 OMPRTL__tgt_target_data_begin,
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +0000726 // Call to void __tgt_target_data_begin_nowait(int64_t device_id, int32_t
727 // arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
728 // *arg_types);
729 OMPRTL__tgt_target_data_begin_nowait,
George Rokos63bc9d62017-11-21 18:25:12 +0000730 // Call to void __tgt_target_data_end(int64_t device_id, int32_t arg_num,
731 // void** args_base, void **args, size_t *arg_sizes, int64_t *arg_types);
Samuel Antaodf158d52016-04-27 22:58:19 +0000732 OMPRTL__tgt_target_data_end,
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +0000733 // Call to void __tgt_target_data_end_nowait(int64_t device_id, int32_t
734 // arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
735 // *arg_types);
736 OMPRTL__tgt_target_data_end_nowait,
George Rokos63bc9d62017-11-21 18:25:12 +0000737 // Call to void __tgt_target_data_update(int64_t device_id, int32_t arg_num,
738 // void** args_base, void **args, size_t *arg_sizes, int64_t *arg_types);
Samuel Antao8d2d7302016-05-26 18:30:22 +0000739 OMPRTL__tgt_target_data_update,
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +0000740 // Call to void __tgt_target_data_update_nowait(int64_t device_id, int32_t
741 // arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
742 // *arg_types);
743 OMPRTL__tgt_target_data_update_nowait,
Alexey Bataev50b3c952016-02-19 10:38:26 +0000744};
745
Alexey Bataev14fa1c62016-03-29 05:34:15 +0000746/// A basic class for pre|post-action for advanced codegen sequence for OpenMP
747/// region.
748class CleanupTy final : public EHScopeStack::Cleanup {
749 PrePostActionTy *Action;
750
751public:
752 explicit CleanupTy(PrePostActionTy *Action) : Action(Action) {}
753 void Emit(CodeGenFunction &CGF, Flags /*flags*/) override {
754 if (!CGF.HaveInsertPoint())
755 return;
756 Action->Exit(CGF);
757 }
758};
759
Hans Wennborg7eb54642015-09-10 17:07:54 +0000760} // anonymous namespace
Alexey Bataev18095712014-10-10 12:19:54 +0000761
Alexey Bataev14fa1c62016-03-29 05:34:15 +0000762void RegionCodeGenTy::operator()(CodeGenFunction &CGF) const {
763 CodeGenFunction::RunCleanupsScope Scope(CGF);
764 if (PrePostAction) {
765 CGF.EHStack.pushCleanup<CleanupTy>(NormalAndEHCleanup, PrePostAction);
766 Callback(CodeGen, CGF, *PrePostAction);
767 } else {
768 PrePostActionTy Action;
769 Callback(CodeGen, CGF, Action);
770 }
771}
772
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000773/// Check if the combiner is a call to UDR combiner and if it is so return the
774/// UDR decl used for reduction.
775static const OMPDeclareReductionDecl *
776getReductionInit(const Expr *ReductionOp) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000777 if (const auto *CE = dyn_cast<CallExpr>(ReductionOp))
778 if (const auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee()))
779 if (const auto *DRE =
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000780 dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts()))
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000781 if (const auto *DRD = dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl()))
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000782 return DRD;
783 return nullptr;
784}
785
786static void emitInitWithReductionInitializer(CodeGenFunction &CGF,
787 const OMPDeclareReductionDecl *DRD,
788 const Expr *InitOp,
789 Address Private, Address Original,
790 QualType Ty) {
791 if (DRD->getInitializer()) {
792 std::pair<llvm::Function *, llvm::Function *> Reduction =
793 CGF.CGM.getOpenMPRuntime().getUserDefinedReduction(DRD);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000794 const auto *CE = cast<CallExpr>(InitOp);
795 const auto *OVE = cast<OpaqueValueExpr>(CE->getCallee());
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000796 const Expr *LHS = CE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
797 const Expr *RHS = CE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000798 const auto *LHSDRE =
799 cast<DeclRefExpr>(cast<UnaryOperator>(LHS)->getSubExpr());
800 const auto *RHSDRE =
801 cast<DeclRefExpr>(cast<UnaryOperator>(RHS)->getSubExpr());
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000802 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
803 PrivateScope.addPrivate(cast<VarDecl>(LHSDRE->getDecl()),
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000804 [=]() { return Private; });
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000805 PrivateScope.addPrivate(cast<VarDecl>(RHSDRE->getDecl()),
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000806 [=]() { return Original; });
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000807 (void)PrivateScope.Privatize();
808 RValue Func = RValue::get(Reduction.second);
809 CodeGenFunction::OpaqueValueMapping Map(CGF, OVE, Func);
810 CGF.EmitIgnoredExpr(InitOp);
811 } else {
812 llvm::Constant *Init = CGF.CGM.EmitNullConstant(Ty);
Alexey Bataev18fa2322018-05-02 14:20:50 +0000813 std::string Name = CGF.CGM.getOpenMPRuntime().getName({"init"});
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000814 auto *GV = new llvm::GlobalVariable(
815 CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true,
Alexey Bataev18fa2322018-05-02 14:20:50 +0000816 llvm::GlobalValue::PrivateLinkage, Init, Name);
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000817 LValue LV = CGF.MakeNaturalAlignAddrLValue(GV, Ty);
818 RValue InitRVal;
819 switch (CGF.getEvaluationKind(Ty)) {
820 case TEK_Scalar:
Alexey Bataeva9b9cc02018-01-23 18:12:38 +0000821 InitRVal = CGF.EmitLoadOfLValue(LV, DRD->getLocation());
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000822 break;
823 case TEK_Complex:
824 InitRVal =
Alexey Bataeva9b9cc02018-01-23 18:12:38 +0000825 RValue::getComplex(CGF.EmitLoadOfComplex(LV, DRD->getLocation()));
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000826 break;
827 case TEK_Aggregate:
828 InitRVal = RValue::getAggregate(LV.getAddress());
829 break;
830 }
Alexey Bataeva9b9cc02018-01-23 18:12:38 +0000831 OpaqueValueExpr OVE(DRD->getLocation(), Ty, VK_RValue);
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000832 CodeGenFunction::OpaqueValueMapping OpaqueMap(CGF, &OVE, InitRVal);
833 CGF.EmitAnyExprToMem(&OVE, Private, Ty.getQualifiers(),
834 /*IsInitializer=*/false);
835 }
836}
837
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000838/// Emit initialization of arrays of complex types.
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000839/// \param DestAddr Address of the array.
840/// \param Type Type of array.
841/// \param Init Initial expression of array.
842/// \param SrcAddr Address of the original array.
843static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr,
Alexey Bataeva7b19152017-10-12 20:03:39 +0000844 QualType Type, bool EmitDeclareReductionInit,
845 const Expr *Init,
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000846 const OMPDeclareReductionDecl *DRD,
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000847 Address SrcAddr = Address::invalid()) {
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000848 // Perform element-by-element initialization.
849 QualType ElementTy;
850
851 // Drill down to the base element type on both arrays.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000852 const ArrayType *ArrayTy = Type->getAsArrayTypeUnsafe();
853 llvm::Value *NumElements = CGF.emitArrayLength(ArrayTy, ElementTy, DestAddr);
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000854 DestAddr =
855 CGF.Builder.CreateElementBitCast(DestAddr, DestAddr.getElementType());
856 if (DRD)
857 SrcAddr =
858 CGF.Builder.CreateElementBitCast(SrcAddr, DestAddr.getElementType());
859
860 llvm::Value *SrcBegin = nullptr;
861 if (DRD)
862 SrcBegin = SrcAddr.getPointer();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000863 llvm::Value *DestBegin = DestAddr.getPointer();
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000864 // Cast from pointer to array type to pointer to single element.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000865 llvm::Value *DestEnd = CGF.Builder.CreateGEP(DestBegin, NumElements);
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000866 // The basic structure here is a while-do loop.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000867 llvm::BasicBlock *BodyBB = CGF.createBasicBlock("omp.arrayinit.body");
868 llvm::BasicBlock *DoneBB = CGF.createBasicBlock("omp.arrayinit.done");
869 llvm::Value *IsEmpty =
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000870 CGF.Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arrayinit.isempty");
871 CGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
872
873 // Enter the loop body, making that address the current address.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000874 llvm::BasicBlock *EntryBB = CGF.Builder.GetInsertBlock();
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000875 CGF.EmitBlock(BodyBB);
876
877 CharUnits ElementSize = CGF.getContext().getTypeSizeInChars(ElementTy);
878
879 llvm::PHINode *SrcElementPHI = nullptr;
880 Address SrcElementCurrent = Address::invalid();
881 if (DRD) {
882 SrcElementPHI = CGF.Builder.CreatePHI(SrcBegin->getType(), 2,
883 "omp.arraycpy.srcElementPast");
884 SrcElementPHI->addIncoming(SrcBegin, EntryBB);
885 SrcElementCurrent =
886 Address(SrcElementPHI,
887 SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize));
888 }
889 llvm::PHINode *DestElementPHI = CGF.Builder.CreatePHI(
890 DestBegin->getType(), 2, "omp.arraycpy.destElementPast");
891 DestElementPHI->addIncoming(DestBegin, EntryBB);
892 Address DestElementCurrent =
893 Address(DestElementPHI,
894 DestAddr.getAlignment().alignmentOfArrayElement(ElementSize));
895
896 // Emit copy.
897 {
898 CodeGenFunction::RunCleanupsScope InitScope(CGF);
Alexey Bataeva7b19152017-10-12 20:03:39 +0000899 if (EmitDeclareReductionInit) {
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000900 emitInitWithReductionInitializer(CGF, DRD, Init, DestElementCurrent,
901 SrcElementCurrent, ElementTy);
902 } else
903 CGF.EmitAnyExprToMem(Init, DestElementCurrent, ElementTy.getQualifiers(),
904 /*IsInitializer=*/false);
905 }
906
907 if (DRD) {
908 // Shift the address forward by one element.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000909 llvm::Value *SrcElementNext = CGF.Builder.CreateConstGEP1_32(
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000910 SrcElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
911 SrcElementPHI->addIncoming(SrcElementNext, CGF.Builder.GetInsertBlock());
912 }
913
914 // Shift the address forward by one element.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000915 llvm::Value *DestElementNext = CGF.Builder.CreateConstGEP1_32(
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000916 DestElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
917 // Check whether we've reached the end.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000918 llvm::Value *Done =
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000919 CGF.Builder.CreateICmpEQ(DestElementNext, DestEnd, "omp.arraycpy.done");
920 CGF.Builder.CreateCondBr(Done, DoneBB, BodyBB);
921 DestElementPHI->addIncoming(DestElementNext, CGF.Builder.GetInsertBlock());
922
923 // Done.
924 CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
925}
926
927LValue ReductionCodeGen::emitSharedLValue(CodeGenFunction &CGF, const Expr *E) {
Alexey Bataevf47c4b42017-09-26 13:47:31 +0000928 return CGF.EmitOMPSharedLValue(E);
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000929}
930
931LValue ReductionCodeGen::emitSharedLValueUB(CodeGenFunction &CGF,
932 const Expr *E) {
933 if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(E))
934 return CGF.EmitOMPArraySectionExpr(OASE, /*IsLowerBound=*/false);
935 return LValue();
936}
937
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000938void ReductionCodeGen::emitAggregateInitialization(
939 CodeGenFunction &CGF, unsigned N, Address PrivateAddr, LValue SharedLVal,
940 const OMPDeclareReductionDecl *DRD) {
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000941 // Emit VarDecl with copy init for arrays.
942 // Get the address of the original variable captured in current
943 // captured region.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000944 const auto *PrivateVD =
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000945 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
Alexey Bataeva7b19152017-10-12 20:03:39 +0000946 bool EmitDeclareReductionInit =
947 DRD && (DRD->getInitializer() || !PrivateVD->hasInit());
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000948 EmitOMPAggregateInit(CGF, PrivateAddr, PrivateVD->getType(),
Alexey Bataeva7b19152017-10-12 20:03:39 +0000949 EmitDeclareReductionInit,
950 EmitDeclareReductionInit ? ClausesData[N].ReductionOp
951 : PrivateVD->getInit(),
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000952 DRD, SharedLVal.getAddress());
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000953}
954
955ReductionCodeGen::ReductionCodeGen(ArrayRef<const Expr *> Shareds,
956 ArrayRef<const Expr *> Privates,
957 ArrayRef<const Expr *> ReductionOps) {
958 ClausesData.reserve(Shareds.size());
959 SharedAddresses.reserve(Shareds.size());
960 Sizes.reserve(Shareds.size());
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000961 BaseDecls.reserve(Shareds.size());
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000962 auto IPriv = Privates.begin();
963 auto IRed = ReductionOps.begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000964 for (const Expr *Ref : Shareds) {
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000965 ClausesData.emplace_back(Ref, *IPriv, *IRed);
966 std::advance(IPriv, 1);
967 std::advance(IRed, 1);
968 }
969}
970
971void ReductionCodeGen::emitSharedLValue(CodeGenFunction &CGF, unsigned N) {
972 assert(SharedAddresses.size() == N &&
973 "Number of generated lvalues must be exactly N.");
Jonas Hahnfeld4525c822017-10-23 19:01:35 +0000974 LValue First = emitSharedLValue(CGF, ClausesData[N].Ref);
975 LValue Second = emitSharedLValueUB(CGF, ClausesData[N].Ref);
976 SharedAddresses.emplace_back(First, Second);
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000977}
978
979void ReductionCodeGen::emitAggregateType(CodeGenFunction &CGF, unsigned N) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000980 const auto *PrivateVD =
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000981 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
982 QualType PrivateType = PrivateVD->getType();
983 bool AsArraySection = isa<OMPArraySectionExpr>(ClausesData[N].Ref);
Jonas Hahnfeld4525c822017-10-23 19:01:35 +0000984 if (!PrivateType->isVariablyModifiedType()) {
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000985 Sizes.emplace_back(
986 CGF.getTypeSize(
987 SharedAddresses[N].first.getType().getNonReferenceType()),
988 nullptr);
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000989 return;
990 }
991 llvm::Value *Size;
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000992 llvm::Value *SizeInChars;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +0000993 auto *ElemType =
Alexey Bataevbe5a8b42017-07-17 13:30:36 +0000994 cast<llvm::PointerType>(SharedAddresses[N].first.getPointer()->getType())
995 ->getElementType();
996 auto *ElemSizeOf = llvm::ConstantExpr::getSizeOf(ElemType);
Alexey Bataev5c40bec2017-07-13 13:36:14 +0000997 if (AsArraySection) {
998 Size = CGF.Builder.CreatePtrDiff(SharedAddresses[N].second.getPointer(),
999 SharedAddresses[N].first.getPointer());
1000 Size = CGF.Builder.CreateNUWAdd(
1001 Size, llvm::ConstantInt::get(Size->getType(), /*V=*/1));
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001002 SizeInChars = CGF.Builder.CreateNUWMul(Size, ElemSizeOf);
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001003 } else {
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001004 SizeInChars = CGF.getTypeSize(
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001005 SharedAddresses[N].first.getType().getNonReferenceType());
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001006 Size = CGF.Builder.CreateExactUDiv(SizeInChars, ElemSizeOf);
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001007 }
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001008 Sizes.emplace_back(SizeInChars, Size);
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001009 CodeGenFunction::OpaqueValueMapping OpaqueMap(
1010 CGF,
1011 cast<OpaqueValueExpr>(
1012 CGF.getContext().getAsVariableArrayType(PrivateType)->getSizeExpr()),
1013 RValue::get(Size));
1014 CGF.EmitVariablyModifiedType(PrivateType);
1015}
1016
1017void ReductionCodeGen::emitAggregateType(CodeGenFunction &CGF, unsigned N,
1018 llvm::Value *Size) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001019 const auto *PrivateVD =
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001020 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
1021 QualType PrivateType = PrivateVD->getType();
Jonas Hahnfeld4525c822017-10-23 19:01:35 +00001022 if (!PrivateType->isVariablyModifiedType()) {
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001023 assert(!Size && !Sizes[N].second &&
Jonas Hahnfeld4525c822017-10-23 19:01:35 +00001024 "Size should be nullptr for non-variably modified reduction "
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001025 "items.");
1026 return;
1027 }
1028 CodeGenFunction::OpaqueValueMapping OpaqueMap(
1029 CGF,
1030 cast<OpaqueValueExpr>(
1031 CGF.getContext().getAsVariableArrayType(PrivateType)->getSizeExpr()),
1032 RValue::get(Size));
1033 CGF.EmitVariablyModifiedType(PrivateType);
1034}
1035
1036void ReductionCodeGen::emitInitialization(
1037 CodeGenFunction &CGF, unsigned N, Address PrivateAddr, LValue SharedLVal,
1038 llvm::function_ref<bool(CodeGenFunction &)> DefaultInit) {
1039 assert(SharedAddresses.size() > N && "No variable was generated");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001040 const auto *PrivateVD =
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001041 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001042 const OMPDeclareReductionDecl *DRD =
1043 getReductionInit(ClausesData[N].ReductionOp);
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001044 QualType PrivateType = PrivateVD->getType();
1045 PrivateAddr = CGF.Builder.CreateElementBitCast(
1046 PrivateAddr, CGF.ConvertTypeForMem(PrivateType));
1047 QualType SharedType = SharedAddresses[N].first.getType();
1048 SharedLVal = CGF.MakeAddrLValue(
1049 CGF.Builder.CreateElementBitCast(SharedLVal.getAddress(),
1050 CGF.ConvertTypeForMem(SharedType)),
Ivan A. Kosarevf5f20462017-10-12 11:29:46 +00001051 SharedType, SharedAddresses[N].first.getBaseInfo(),
Ivan A. Kosarevb9c59f32017-10-31 11:05:34 +00001052 CGF.CGM.getTBAAInfoForSubobject(SharedAddresses[N].first, SharedType));
Jonas Hahnfeld4525c822017-10-23 19:01:35 +00001053 if (CGF.getContext().getAsArrayType(PrivateVD->getType())) {
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001054 emitAggregateInitialization(CGF, N, PrivateAddr, SharedLVal, DRD);
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001055 } else if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) {
1056 emitInitWithReductionInitializer(CGF, DRD, ClausesData[N].ReductionOp,
1057 PrivateAddr, SharedLVal.getAddress(),
1058 SharedLVal.getType());
1059 } else if (!DefaultInit(CGF) && PrivateVD->hasInit() &&
1060 !CGF.isTrivialInitializer(PrivateVD->getInit())) {
1061 CGF.EmitAnyExprToMem(PrivateVD->getInit(), PrivateAddr,
1062 PrivateVD->getType().getQualifiers(),
1063 /*IsInitializer=*/false);
1064 }
1065}
1066
1067bool ReductionCodeGen::needCleanups(unsigned N) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001068 const auto *PrivateVD =
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001069 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
1070 QualType PrivateType = PrivateVD->getType();
1071 QualType::DestructionKind DTorKind = PrivateType.isDestructedType();
1072 return DTorKind != QualType::DK_none;
1073}
1074
1075void ReductionCodeGen::emitCleanups(CodeGenFunction &CGF, unsigned N,
1076 Address PrivateAddr) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001077 const auto *PrivateVD =
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001078 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
1079 QualType PrivateType = PrivateVD->getType();
1080 QualType::DestructionKind DTorKind = PrivateType.isDestructedType();
1081 if (needCleanups(N)) {
1082 PrivateAddr = CGF.Builder.CreateElementBitCast(
1083 PrivateAddr, CGF.ConvertTypeForMem(PrivateType));
1084 CGF.pushDestroy(DTorKind, PrivateAddr, PrivateType);
1085 }
1086}
1087
1088static LValue loadToBegin(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,
1089 LValue BaseLV) {
1090 BaseTy = BaseTy.getNonReferenceType();
1091 while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&
1092 !CGF.getContext().hasSameType(BaseTy, ElTy)) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001093 if (const auto *PtrTy = BaseTy->getAs<PointerType>()) {
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001094 BaseLV = CGF.EmitLoadOfPointerLValue(BaseLV.getAddress(), PtrTy);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001095 } else {
Ivan A. Kosarev9f9d1572017-10-30 11:49:31 +00001096 LValue RefLVal = CGF.MakeAddrLValue(BaseLV.getAddress(), BaseTy);
1097 BaseLV = CGF.EmitLoadOfReferenceLValue(RefLVal);
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001098 }
1099 BaseTy = BaseTy->getPointeeType();
1100 }
1101 return CGF.MakeAddrLValue(
1102 CGF.Builder.CreateElementBitCast(BaseLV.getAddress(),
1103 CGF.ConvertTypeForMem(ElTy)),
Ivan A. Kosarevf5f20462017-10-12 11:29:46 +00001104 BaseLV.getType(), BaseLV.getBaseInfo(),
Ivan A. Kosarevb9c59f32017-10-31 11:05:34 +00001105 CGF.CGM.getTBAAInfoForSubobject(BaseLV, BaseLV.getType()));
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001106}
1107
1108static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,
1109 llvm::Type *BaseLVType, CharUnits BaseLVAlignment,
1110 llvm::Value *Addr) {
1111 Address Tmp = Address::invalid();
1112 Address TopTmp = Address::invalid();
1113 Address MostTopTmp = Address::invalid();
1114 BaseTy = BaseTy.getNonReferenceType();
1115 while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&
1116 !CGF.getContext().hasSameType(BaseTy, ElTy)) {
1117 Tmp = CGF.CreateMemTemp(BaseTy);
1118 if (TopTmp.isValid())
1119 CGF.Builder.CreateStore(Tmp.getPointer(), TopTmp);
1120 else
1121 MostTopTmp = Tmp;
1122 TopTmp = Tmp;
1123 BaseTy = BaseTy->getPointeeType();
1124 }
1125 llvm::Type *Ty = BaseLVType;
1126 if (Tmp.isValid())
1127 Ty = Tmp.getElementType();
1128 Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Addr, Ty);
1129 if (Tmp.isValid()) {
1130 CGF.Builder.CreateStore(Addr, Tmp);
1131 return MostTopTmp;
1132 }
1133 return Address(Addr, BaseLVAlignment);
1134}
1135
Alexey Bataev1c44e152018-03-06 18:59:43 +00001136static const VarDecl *getBaseDecl(const Expr *Ref, const DeclRefExpr *&DE) {
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001137 const VarDecl *OrigVD = nullptr;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001138 if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(Ref)) {
1139 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
1140 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001141 Base = TempOASE->getBase()->IgnoreParenImpCasts();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001142 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001143 Base = TempASE->getBase()->IgnoreParenImpCasts();
1144 DE = cast<DeclRefExpr>(Base);
1145 OrigVD = cast<VarDecl>(DE->getDecl());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001146 } else if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(Ref)) {
1147 const Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
1148 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001149 Base = TempASE->getBase()->IgnoreParenImpCasts();
1150 DE = cast<DeclRefExpr>(Base);
1151 OrigVD = cast<VarDecl>(DE->getDecl());
1152 }
Alexey Bataev1c44e152018-03-06 18:59:43 +00001153 return OrigVD;
1154}
1155
1156Address ReductionCodeGen::adjustPrivateAddress(CodeGenFunction &CGF, unsigned N,
1157 Address PrivateAddr) {
1158 const DeclRefExpr *DE;
1159 if (const VarDecl *OrigVD = ::getBaseDecl(ClausesData[N].Ref, DE)) {
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001160 BaseDecls.emplace_back(OrigVD);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001161 LValue OriginalBaseLValue = CGF.EmitLValue(DE);
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001162 LValue BaseLValue =
1163 loadToBegin(CGF, OrigVD->getType(), SharedAddresses[N].first.getType(),
1164 OriginalBaseLValue);
1165 llvm::Value *Adjustment = CGF.Builder.CreatePtrDiff(
1166 BaseLValue.getPointer(), SharedAddresses[N].first.getPointer());
Jonas Hahnfeld273d2612017-12-06 19:15:28 +00001167 llvm::Value *PrivatePointer =
1168 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
1169 PrivateAddr.getPointer(),
1170 SharedAddresses[N].first.getAddress().getType());
1171 llvm::Value *Ptr = CGF.Builder.CreateGEP(PrivatePointer, Adjustment);
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001172 return castToBase(CGF, OrigVD->getType(),
1173 SharedAddresses[N].first.getType(),
Jonas Hahnfeld273d2612017-12-06 19:15:28 +00001174 OriginalBaseLValue.getAddress().getType(),
Alexey Bataev5c40bec2017-07-13 13:36:14 +00001175 OriginalBaseLValue.getAlignment(), Ptr);
1176 }
1177 BaseDecls.emplace_back(
1178 cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Ref)->getDecl()));
1179 return PrivateAddr;
1180}
1181
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001182bool ReductionCodeGen::usesReductionInitializer(unsigned N) const {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001183 const OMPDeclareReductionDecl *DRD =
1184 getReductionInit(ClausesData[N].ReductionOp);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00001185 return DRD && DRD->getInitializer();
1186}
1187
Alexey Bataev18095712014-10-10 12:19:54 +00001188LValue CGOpenMPRegionInfo::getThreadIDVariableLValue(CodeGenFunction &CGF) {
Alexey Bataev31300ed2016-02-04 11:27:03 +00001189 return CGF.EmitLoadOfPointerLValue(
1190 CGF.GetAddrOfLocalVar(getThreadIDVariable()),
1191 getThreadIDVariable()->getType()->castAs<PointerType>());
Alexey Bataev18095712014-10-10 12:19:54 +00001192}
1193
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001194void CGOpenMPRegionInfo::EmitBody(CodeGenFunction &CGF, const Stmt * /*S*/) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00001195 if (!CGF.HaveInsertPoint())
1196 return;
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001197 // 1.2.2 OpenMP Language Terminology
1198 // Structured block - An executable statement with a single entry at the
1199 // top and a single exit at the bottom.
1200 // The point of exit cannot be a branch out of the structured block.
1201 // longjmp() and throw() must not violate the entry/exit criteria.
1202 CGF.EHStack.pushTerminate();
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001203 CodeGen(CGF);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00001204 CGF.EHStack.popTerminate();
Alexey Bataev4a5bb772014-10-08 14:01:46 +00001205}
1206
Alexey Bataev62b63b12015-03-10 07:28:44 +00001207LValue CGOpenMPTaskOutlinedRegionInfo::getThreadIDVariableLValue(
1208 CodeGenFunction &CGF) {
Alexey Bataev2377fe92015-09-10 08:12:02 +00001209 return CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(getThreadIDVariable()),
1210 getThreadIDVariable()->getType(),
Ivan A. Kosarev5f8c0ca2017-10-10 09:39:32 +00001211 AlignmentSource::Decl);
Alexey Bataev62b63b12015-03-10 07:28:44 +00001212}
1213
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001214static FieldDecl *addFieldToRecordDecl(ASTContext &C, DeclContext *DC,
1215 QualType FieldTy) {
1216 auto *Field = FieldDecl::Create(
1217 C, DC, SourceLocation(), SourceLocation(), /*Id=*/nullptr, FieldTy,
1218 C.getTrivialTypeSourceInfo(FieldTy, SourceLocation()),
1219 /*BW=*/nullptr, /*Mutable=*/false, /*InitStyle=*/ICIS_NoInit);
1220 Field->setAccess(AS_public);
1221 DC->addDecl(Field);
1222 return Field;
1223}
1224
Alexey Bataev18fa2322018-05-02 14:20:50 +00001225CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM, StringRef FirstSeparator,
1226 StringRef Separator)
1227 : CGM(CGM), FirstSeparator(FirstSeparator), Separator(Separator),
1228 OffloadEntriesInfoManager(CGM) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001229 ASTContext &C = CGM.getContext();
1230 RecordDecl *RD = C.buildImplicitRecord("ident_t");
1231 QualType KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
1232 RD->startDefinition();
1233 // reserved_1
1234 addFieldToRecordDecl(C, RD, KmpInt32Ty);
1235 // flags
1236 addFieldToRecordDecl(C, RD, KmpInt32Ty);
1237 // reserved_2
1238 addFieldToRecordDecl(C, RD, KmpInt32Ty);
1239 // reserved_3
1240 addFieldToRecordDecl(C, RD, KmpInt32Ty);
1241 // psource
1242 addFieldToRecordDecl(C, RD, C.VoidPtrTy);
1243 RD->completeDefinition();
1244 IdentQTy = C.getRecordType(RD);
1245 IdentTy = CGM.getTypes().ConvertRecordDeclType(RD);
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00001246 KmpCriticalNameTy = llvm::ArrayType::get(CGM.Int32Ty, /*NumElements*/ 8);
Samuel Antaoee8fb302016-01-06 13:42:12 +00001247
1248 loadOffloadInfoMetadata();
Alexey Bataev9959db52014-05-06 10:08:46 +00001249}
1250
Alexey Bataev91797552015-03-18 04:13:55 +00001251void CGOpenMPRuntime::clear() {
1252 InternalVars.clear();
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00001253 // Clean non-target variable declarations possibly used only in debug info.
1254 for (const auto &Data : EmittedNonTargetVariables) {
1255 if (!Data.getValue().pointsToAliveValue())
1256 continue;
1257 auto *GV = dyn_cast<llvm::GlobalVariable>(Data.getValue());
1258 if (!GV)
1259 continue;
1260 if (!GV->isDeclaration() || GV->getNumUses() > 0)
1261 continue;
1262 GV->eraseFromParent();
1263 }
Alexey Bataev91797552015-03-18 04:13:55 +00001264}
1265
Alexey Bataev18fa2322018-05-02 14:20:50 +00001266std::string CGOpenMPRuntime::getName(ArrayRef<StringRef> Parts) const {
1267 SmallString<128> Buffer;
1268 llvm::raw_svector_ostream OS(Buffer);
1269 StringRef Sep = FirstSeparator;
1270 for (StringRef Part : Parts) {
1271 OS << Sep << Part;
1272 Sep = Separator;
1273 }
1274 return OS.str();
1275}
1276
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001277static llvm::Function *
1278emitCombinerOrInitializer(CodeGenModule &CGM, QualType Ty,
1279 const Expr *CombinerInitializer, const VarDecl *In,
1280 const VarDecl *Out, bool IsCombiner) {
1281 // void .omp_combiner.(Ty *in, Ty *out);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001282 ASTContext &C = CGM.getContext();
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001283 QualType PtrTy = C.getPointerType(Ty).withRestrict();
1284 FunctionArgList Args;
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001285 ImplicitParamDecl OmpOutParm(C, /*DC=*/nullptr, Out->getLocation(),
Alexey Bataev56223232017-06-09 13:40:18 +00001286 /*Id=*/nullptr, PtrTy, ImplicitParamDecl::Other);
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001287 ImplicitParamDecl OmpInParm(C, /*DC=*/nullptr, In->getLocation(),
Alexey Bataev56223232017-06-09 13:40:18 +00001288 /*Id=*/nullptr, PtrTy, ImplicitParamDecl::Other);
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001289 Args.push_back(&OmpOutParm);
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001290 Args.push_back(&OmpInParm);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001291 const CGFunctionInfo &FnInfo =
John McCallc56a8b32016-03-11 04:30:31 +00001292 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001293 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
Alexey Bataev18fa2322018-05-02 14:20:50 +00001294 std::string Name = CGM.getOpenMPRuntime().getName(
1295 {IsCombiner ? "omp_combiner" : "omp_initializer", ""});
1296 auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
1297 Name, &CGM.getModule());
Rafael Espindola51ec5a92018-02-28 23:46:35 +00001298 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo);
Alexey Bataev8c5555c2019-05-21 15:11:58 +00001299 if (CGM.getLangOpts().Optimize) {
1300 Fn->removeFnAttr(llvm::Attribute::NoInline);
1301 Fn->removeFnAttr(llvm::Attribute::OptimizeNone);
1302 Fn->addFnAttr(llvm::Attribute::AlwaysInline);
1303 }
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001304 CodeGenFunction CGF(CGM);
1305 // Map "T omp_in;" variable to "*omp_in_parm" value in all expressions.
1306 // Map "T omp_out;" variable to "*omp_out_parm" value in all expressions.
Alexey Bataev7cae94e2018-01-04 19:45:16 +00001307 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, In->getLocation(),
1308 Out->getLocation());
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001309 CodeGenFunction::OMPPrivateScope Scope(CGF);
1310 Address AddrIn = CGF.GetAddrOfLocalVar(&OmpInParm);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001311 Scope.addPrivate(In, [&CGF, AddrIn, PtrTy]() {
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001312 return CGF.EmitLoadOfPointerLValue(AddrIn, PtrTy->castAs<PointerType>())
1313 .getAddress();
1314 });
1315 Address AddrOut = CGF.GetAddrOfLocalVar(&OmpOutParm);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001316 Scope.addPrivate(Out, [&CGF, AddrOut, PtrTy]() {
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001317 return CGF.EmitLoadOfPointerLValue(AddrOut, PtrTy->castAs<PointerType>())
1318 .getAddress();
1319 });
1320 (void)Scope.Privatize();
Alexey Bataev070f43a2017-09-06 14:49:58 +00001321 if (!IsCombiner && Out->hasInit() &&
1322 !CGF.isTrivialInitializer(Out->getInit())) {
1323 CGF.EmitAnyExprToMem(Out->getInit(), CGF.GetAddrOfLocalVar(Out),
1324 Out->getType().getQualifiers(),
1325 /*IsInitializer=*/true);
1326 }
1327 if (CombinerInitializer)
1328 CGF.EmitIgnoredExpr(CombinerInitializer);
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001329 Scope.ForceCleanup();
1330 CGF.FinishFunction();
1331 return Fn;
1332}
1333
1334void CGOpenMPRuntime::emitUserDefinedReduction(
1335 CodeGenFunction *CGF, const OMPDeclareReductionDecl *D) {
1336 if (UDRMap.count(D) > 0)
1337 return;
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001338 llvm::Function *Combiner = emitCombinerOrInitializer(
Alexey Bataeve6aa4692018-09-13 16:54:05 +00001339 CGM, D->getType(), D->getCombiner(),
1340 cast<VarDecl>(cast<DeclRefExpr>(D->getCombinerIn())->getDecl()),
1341 cast<VarDecl>(cast<DeclRefExpr>(D->getCombinerOut())->getDecl()),
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001342 /*IsCombiner=*/true);
1343 llvm::Function *Initializer = nullptr;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001344 if (const Expr *Init = D->getInitializer()) {
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001345 Initializer = emitCombinerOrInitializer(
Alexey Bataev070f43a2017-09-06 14:49:58 +00001346 CGM, D->getType(),
1347 D->getInitializerKind() == OMPDeclareReductionDecl::CallInit ? Init
1348 : nullptr,
Alexey Bataeve6aa4692018-09-13 16:54:05 +00001349 cast<VarDecl>(cast<DeclRefExpr>(D->getInitOrig())->getDecl()),
1350 cast<VarDecl>(cast<DeclRefExpr>(D->getInitPriv())->getDecl()),
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001351 /*IsCombiner=*/false);
1352 }
Alexey Bataev43a919f2018-04-13 17:48:43 +00001353 UDRMap.try_emplace(D, Combiner, Initializer);
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001354 if (CGF) {
1355 auto &Decls = FunctionUDRMap.FindAndConstruct(CGF->CurFn);
1356 Decls.second.push_back(D);
1357 }
1358}
1359
Alexey Bataeva839ddd2016-03-17 10:19:46 +00001360std::pair<llvm::Function *, llvm::Function *>
1361CGOpenMPRuntime::getUserDefinedReduction(const OMPDeclareReductionDecl *D) {
1362 auto I = UDRMap.find(D);
1363 if (I != UDRMap.end())
1364 return I->second;
1365 emitUserDefinedReduction(/*CGF=*/nullptr, D);
1366 return UDRMap.lookup(D);
1367}
1368
James Y Knight9871db02019-02-05 16:42:33 +00001369static llvm::Function *emitParallelOrTeamsOutlinedFunction(
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00001370 CodeGenModule &CGM, const OMPExecutableDirective &D, const CapturedStmt *CS,
1371 const VarDecl *ThreadIDVar, OpenMPDirectiveKind InnermostKind,
1372 const StringRef OutlinedHelperName, const RegionCodeGenTy &CodeGen) {
Alexey Bataev62b63b12015-03-10 07:28:44 +00001373 assert(ThreadIDVar->getType()->isPointerType() &&
1374 "thread id variable must be of type kmp_int32 *");
Alexey Bataev18095712014-10-10 12:19:54 +00001375 CodeGenFunction CGF(CGM, true);
Alexey Bataev25e5b442015-09-15 12:52:43 +00001376 bool HasCancel = false;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001377 if (const auto *OPD = dyn_cast<OMPParallelDirective>(&D))
Alexey Bataev25e5b442015-09-15 12:52:43 +00001378 HasCancel = OPD->hasCancel();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001379 else if (const auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&D))
Alexey Bataev25e5b442015-09-15 12:52:43 +00001380 HasCancel = OPSD->hasCancel();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001381 else if (const auto *OPFD = dyn_cast<OMPParallelForDirective>(&D))
Alexey Bataev25e5b442015-09-15 12:52:43 +00001382 HasCancel = OPFD->hasCancel();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001383 else if (const auto *OPFD = dyn_cast<OMPTargetParallelForDirective>(&D))
Alexey Bataev2139ed62017-11-16 18:20:21 +00001384 HasCancel = OPFD->hasCancel();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001385 else if (const auto *OPFD = dyn_cast<OMPDistributeParallelForDirective>(&D))
Alexey Bataev10a54312017-11-27 16:54:08 +00001386 HasCancel = OPFD->hasCancel();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001387 else if (const auto *OPFD =
1388 dyn_cast<OMPTeamsDistributeParallelForDirective>(&D))
Alexey Bataev10a54312017-11-27 16:54:08 +00001389 HasCancel = OPFD->hasCancel();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001390 else if (const auto *OPFD =
Alexey Bataev10a54312017-11-27 16:54:08 +00001391 dyn_cast<OMPTargetTeamsDistributeParallelForDirective>(&D))
1392 HasCancel = OPFD->hasCancel();
Alexey Bataev25e5b442015-09-15 12:52:43 +00001393 CGOpenMPOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen, InnermostKind,
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00001394 HasCancel, OutlinedHelperName);
Alexey Bataevd157d472015-06-24 03:35:38 +00001395 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
Alexey Bataev2377fe92015-09-10 08:12:02 +00001396 return CGF.GenerateOpenMPCapturedStmtFunction(*CS);
Alexey Bataev18095712014-10-10 12:19:54 +00001397}
1398
James Y Knight9871db02019-02-05 16:42:33 +00001399llvm::Function *CGOpenMPRuntime::emitParallelOutlinedFunction(
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00001400 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
1401 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
1402 const CapturedStmt *CS = D.getCapturedStmt(OMPD_parallel);
1403 return emitParallelOrTeamsOutlinedFunction(
1404 CGM, D, CS, ThreadIDVar, InnermostKind, getOutlinedHelperName(), CodeGen);
1405}
1406
James Y Knight9871db02019-02-05 16:42:33 +00001407llvm::Function *CGOpenMPRuntime::emitTeamsOutlinedFunction(
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00001408 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
1409 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
1410 const CapturedStmt *CS = D.getCapturedStmt(OMPD_teams);
1411 return emitParallelOrTeamsOutlinedFunction(
1412 CGM, D, CS, ThreadIDVar, InnermostKind, getOutlinedHelperName(), CodeGen);
1413}
1414
James Y Knight9871db02019-02-05 16:42:33 +00001415llvm::Function *CGOpenMPRuntime::emitTaskOutlinedFunction(
Alexey Bataev81c7ea02015-07-03 09:56:58 +00001416 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
Alexey Bataev48591dd2016-04-20 04:01:36 +00001417 const VarDecl *PartIDVar, const VarDecl *TaskTVar,
1418 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
1419 bool Tied, unsigned &NumberOfParts) {
1420 auto &&UntiedCodeGen = [this, &D, TaskTVar](CodeGenFunction &CGF,
1421 PrePostActionTy &) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001422 llvm::Value *ThreadID = getThreadID(CGF, D.getBeginLoc());
1423 llvm::Value *UpLoc = emitUpdateLocation(CGF, D.getBeginLoc());
Alexey Bataev48591dd2016-04-20 04:01:36 +00001424 llvm::Value *TaskArgs[] = {
1425 UpLoc, ThreadID,
1426 CGF.EmitLoadOfPointerLValue(CGF.GetAddrOfLocalVar(TaskTVar),
1427 TaskTVar->getType()->castAs<PointerType>())
1428 .getPointer()};
1429 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_task), TaskArgs);
1430 };
1431 CGOpenMPTaskOutlinedRegionInfo::UntiedTaskActionTy Action(Tied, PartIDVar,
1432 UntiedCodeGen);
1433 CodeGen.setAction(Action);
Alexey Bataev62b63b12015-03-10 07:28:44 +00001434 assert(!ThreadIDVar->getType()->isPointerType() &&
1435 "thread id variable must be of type kmp_int32 for tasks");
Alexey Bataev475a7442018-01-12 19:39:11 +00001436 const OpenMPDirectiveKind Region =
1437 isOpenMPTaskLoopDirective(D.getDirectiveKind()) ? OMPD_taskloop
1438 : OMPD_task;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001439 const CapturedStmt *CS = D.getCapturedStmt(Region);
1440 const auto *TD = dyn_cast<OMPTaskDirective>(&D);
Alexey Bataev62b63b12015-03-10 07:28:44 +00001441 CodeGenFunction CGF(CGM, true);
Alexey Bataev7292c292016-04-25 12:22:29 +00001442 CGOpenMPTaskOutlinedRegionInfo CGInfo(*CS, ThreadIDVar, CodeGen,
1443 InnermostKind,
1444 TD ? TD->hasCancel() : false, Action);
Alexey Bataevd157d472015-06-24 03:35:38 +00001445 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
James Y Knight9871db02019-02-05 16:42:33 +00001446 llvm::Function *Res = CGF.GenerateCapturedStmtFunction(*CS);
Alexey Bataev48591dd2016-04-20 04:01:36 +00001447 if (!Tied)
1448 NumberOfParts = Action.getNumberOfParts();
1449 return Res;
Alexey Bataev62b63b12015-03-10 07:28:44 +00001450}
1451
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001452static void buildStructValue(ConstantStructBuilder &Fields, CodeGenModule &CGM,
1453 const RecordDecl *RD, const CGRecordLayout &RL,
1454 ArrayRef<llvm::Constant *> Data) {
1455 llvm::StructType *StructTy = RL.getLLVMType();
1456 unsigned PrevIdx = 0;
1457 ConstantInitBuilder CIBuilder(CGM);
1458 auto DI = Data.begin();
1459 for (const FieldDecl *FD : RD->fields()) {
1460 unsigned Idx = RL.getLLVMFieldNo(FD);
1461 // Fill the alignment.
1462 for (unsigned I = PrevIdx; I < Idx; ++I)
1463 Fields.add(llvm::Constant::getNullValue(StructTy->getElementType(I)));
1464 PrevIdx = Idx + 1;
1465 Fields.add(*DI);
1466 ++DI;
1467 }
1468}
1469
1470template <class... As>
1471static llvm::GlobalVariable *
Mike Ricee1ca7b62018-08-29 15:45:11 +00001472createGlobalStruct(CodeGenModule &CGM, QualType Ty, bool IsConstant,
1473 ArrayRef<llvm::Constant *> Data, const Twine &Name,
1474 As &&... Args) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001475 const auto *RD = cast<RecordDecl>(Ty->getAsTagDecl());
1476 const CGRecordLayout &RL = CGM.getTypes().getCGRecordLayout(RD);
1477 ConstantInitBuilder CIBuilder(CGM);
1478 ConstantStructBuilder Fields = CIBuilder.beginStruct(RL.getLLVMType());
1479 buildStructValue(Fields, CGM, RD, RL, Data);
1480 return Fields.finishAndCreateGlobal(
Mike Ricee1ca7b62018-08-29 15:45:11 +00001481 Name, CGM.getContext().getAlignOfGlobalVarInChars(Ty), IsConstant,
1482 std::forward<As>(Args)...);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001483}
1484
1485template <typename T>
Benjamin Kramer651d0bf2018-05-15 21:26:47 +00001486static void
1487createConstantGlobalStructAndAddToParent(CodeGenModule &CGM, QualType Ty,
1488 ArrayRef<llvm::Constant *> Data,
1489 T &Parent) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001490 const auto *RD = cast<RecordDecl>(Ty->getAsTagDecl());
1491 const CGRecordLayout &RL = CGM.getTypes().getCGRecordLayout(RD);
1492 ConstantStructBuilder Fields = Parent.beginStruct(RL.getLLVMType());
1493 buildStructValue(Fields, CGM, RD, RL, Data);
1494 Fields.finishAndAddTo(Parent);
1495}
1496
Alexey Bataev50b3c952016-02-19 10:38:26 +00001497Address CGOpenMPRuntime::getOrCreateDefaultLocation(unsigned Flags) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001498 CharUnits Align = CGM.getContext().getTypeAlignInChars(IdentQTy);
Alexey Bataevceeaa482018-11-21 21:04:34 +00001499 unsigned Reserved2Flags = getDefaultLocationReserved2Flags();
1500 FlagsTy FlagsKey(Flags, Reserved2Flags);
1501 llvm::Value *Entry = OpenMPDefaultLocMap.lookup(FlagsKey);
Alexey Bataev9959db52014-05-06 10:08:46 +00001502 if (!Entry) {
1503 if (!DefaultOpenMPPSource) {
1504 // Initialize default location for psource field of ident_t structure of
1505 // all ident_t objects. Format is ";file;function;line;column;;".
1506 // Taken from
James Y Knight5d71fc52019-01-29 16:37:27 +00001507 // https://github.com/llvm/llvm-project/blob/master/openmp/runtime/src/kmp_str.cpp
Alexey Bataev9959db52014-05-06 10:08:46 +00001508 DefaultOpenMPPSource =
John McCall7f416cc2015-09-08 08:05:57 +00001509 CGM.GetAddrOfConstantCString(";unknown;unknown;0;0;;").getPointer();
Alexey Bataev9959db52014-05-06 10:08:46 +00001510 DefaultOpenMPPSource =
1511 llvm::ConstantExpr::getBitCast(DefaultOpenMPPSource, CGM.Int8PtrTy);
1512 }
Alexey Bataev9959db52014-05-06 10:08:46 +00001513
Alexey Bataevceeaa482018-11-21 21:04:34 +00001514 llvm::Constant *Data[] = {
1515 llvm::ConstantInt::getNullValue(CGM.Int32Ty),
1516 llvm::ConstantInt::get(CGM.Int32Ty, Flags),
1517 llvm::ConstantInt::get(CGM.Int32Ty, Reserved2Flags),
1518 llvm::ConstantInt::getNullValue(CGM.Int32Ty), DefaultOpenMPPSource};
Mike Ricee1ca7b62018-08-29 15:45:11 +00001519 llvm::GlobalValue *DefaultOpenMPLocation =
Alexey Bataevceeaa482018-11-21 21:04:34 +00001520 createGlobalStruct(CGM, IdentQTy, isDefaultLocationConstant(), Data, "",
Mike Ricee1ca7b62018-08-29 15:45:11 +00001521 llvm::GlobalValue::PrivateLinkage);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001522 DefaultOpenMPLocation->setUnnamedAddr(
1523 llvm::GlobalValue::UnnamedAddr::Global);
John McCall6c9f1fdb2016-11-19 08:17:24 +00001524
Alexey Bataevceeaa482018-11-21 21:04:34 +00001525 OpenMPDefaultLocMap[FlagsKey] = Entry = DefaultOpenMPLocation;
Alexey Bataev9959db52014-05-06 10:08:46 +00001526 }
John McCall7f416cc2015-09-08 08:05:57 +00001527 return Address(Entry, Align);
Alexey Bataev9959db52014-05-06 10:08:46 +00001528}
1529
Alexey Bataevfd006c42018-10-05 15:08:53 +00001530void CGOpenMPRuntime::setLocThreadIdInsertPt(CodeGenFunction &CGF,
1531 bool AtCurrentPoint) {
1532 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
1533 assert(!Elem.second.ServiceInsertPt && "Insert point is set already.");
1534
1535 llvm::Value *Undef = llvm::UndefValue::get(CGF.Int32Ty);
1536 if (AtCurrentPoint) {
1537 Elem.second.ServiceInsertPt = new llvm::BitCastInst(
1538 Undef, CGF.Int32Ty, "svcpt", CGF.Builder.GetInsertBlock());
1539 } else {
1540 Elem.second.ServiceInsertPt =
1541 new llvm::BitCastInst(Undef, CGF.Int32Ty, "svcpt");
1542 Elem.second.ServiceInsertPt->insertAfter(CGF.AllocaInsertPt);
1543 }
1544}
1545
1546void CGOpenMPRuntime::clearLocThreadIdInsertPt(CodeGenFunction &CGF) {
1547 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
1548 if (Elem.second.ServiceInsertPt) {
1549 llvm::Instruction *Ptr = Elem.second.ServiceInsertPt;
1550 Elem.second.ServiceInsertPt = nullptr;
1551 Ptr->eraseFromParent();
1552 }
1553}
1554
Alexey Bataev3eff5f42015-02-25 08:32:46 +00001555llvm::Value *CGOpenMPRuntime::emitUpdateLocation(CodeGenFunction &CGF,
1556 SourceLocation Loc,
Alexey Bataev50b3c952016-02-19 10:38:26 +00001557 unsigned Flags) {
1558 Flags |= OMP_IDENT_KMPC;
Alexey Bataev9959db52014-05-06 10:08:46 +00001559 // If no debug info is generated - return global default location.
Benjamin Kramer8c305922016-02-02 11:06:51 +00001560 if (CGM.getCodeGenOpts().getDebugInfo() == codegenoptions::NoDebugInfo ||
Alexey Bataev9959db52014-05-06 10:08:46 +00001561 Loc.isInvalid())
John McCall7f416cc2015-09-08 08:05:57 +00001562 return getOrCreateDefaultLocation(Flags).getPointer();
Alexey Bataev9959db52014-05-06 10:08:46 +00001563
1564 assert(CGF.CurFn && "No function in current CodeGenFunction.");
1565
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001566 CharUnits Align = CGM.getContext().getTypeAlignInChars(IdentQTy);
John McCall7f416cc2015-09-08 08:05:57 +00001567 Address LocValue = Address::invalid();
Alexey Bataev1e4b7132014-12-03 12:11:24 +00001568 auto I = OpenMPLocThreadIDMap.find(CGF.CurFn);
1569 if (I != OpenMPLocThreadIDMap.end())
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001570 LocValue = Address(I->second.DebugLoc, Align);
John McCall7f416cc2015-09-08 08:05:57 +00001571
Alexander Musmanc6388682014-12-15 07:07:06 +00001572 // OpenMPLocThreadIDMap may have null DebugLoc and non-null ThreadID, if
1573 // GetOpenMPThreadID was called before this routine.
John McCall7f416cc2015-09-08 08:05:57 +00001574 if (!LocValue.isValid()) {
Alexey Bataev15007ba2014-05-07 06:18:01 +00001575 // Generate "ident_t .kmpc_loc.addr;"
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001576 Address AI = CGF.CreateMemTemp(IdentQTy, ".kmpc_loc.addr");
Alexey Bataev18095712014-10-10 12:19:54 +00001577 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
John McCall7f416cc2015-09-08 08:05:57 +00001578 Elem.second.DebugLoc = AI.getPointer();
Alexey Bataev9959db52014-05-06 10:08:46 +00001579 LocValue = AI;
1580
Alexey Bataevfd006c42018-10-05 15:08:53 +00001581 if (!Elem.second.ServiceInsertPt)
1582 setLocThreadIdInsertPt(CGF);
Alexey Bataev9959db52014-05-06 10:08:46 +00001583 CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
Alexey Bataevfd006c42018-10-05 15:08:53 +00001584 CGF.Builder.SetInsertPoint(Elem.second.ServiceInsertPt);
Alexey Bataev3eff5f42015-02-25 08:32:46 +00001585 CGF.Builder.CreateMemCpy(LocValue, getOrCreateDefaultLocation(Flags),
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001586 CGF.getTypeSize(IdentQTy));
Alexey Bataev9959db52014-05-06 10:08:46 +00001587 }
1588
1589 // char **psource = &.kmpc_loc_<flags>.addr.psource;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001590 LValue Base = CGF.MakeAddrLValue(LocValue, IdentQTy);
1591 auto Fields = cast<RecordDecl>(IdentQTy->getAsTagDecl())->field_begin();
1592 LValue PSource =
1593 CGF.EmitLValueForField(Base, *std::next(Fields, IdentField_PSource));
Alexey Bataev9959db52014-05-06 10:08:46 +00001594
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001595 llvm::Value *OMPDebugLoc = OpenMPDebugLocMap.lookup(Loc.getRawEncoding());
Alexey Bataevf002aca2014-05-30 05:48:40 +00001596 if (OMPDebugLoc == nullptr) {
1597 SmallString<128> Buffer2;
1598 llvm::raw_svector_ostream OS2(Buffer2);
1599 // Build debug location
1600 PresumedLoc PLoc = CGF.getContext().getSourceManager().getPresumedLoc(Loc);
1601 OS2 << ";" << PLoc.getFilename() << ";";
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001602 if (const auto *FD = dyn_cast_or_null<FunctionDecl>(CGF.CurFuncDecl))
Alexey Bataevf002aca2014-05-30 05:48:40 +00001603 OS2 << FD->getQualifiedNameAsString();
Alexey Bataevf002aca2014-05-30 05:48:40 +00001604 OS2 << ";" << PLoc.getLine() << ";" << PLoc.getColumn() << ";;";
1605 OMPDebugLoc = CGF.Builder.CreateGlobalStringPtr(OS2.str());
1606 OpenMPDebugLocMap[Loc.getRawEncoding()] = OMPDebugLoc;
Alexey Bataev9959db52014-05-06 10:08:46 +00001607 }
Alexey Bataev9959db52014-05-06 10:08:46 +00001608 // *psource = ";<File>;<Function>;<Line>;<Column>;;";
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001609 CGF.EmitStoreOfScalar(OMPDebugLoc, PSource);
Alexey Bataevf002aca2014-05-30 05:48:40 +00001610
John McCall7f416cc2015-09-08 08:05:57 +00001611 // Our callers always pass this to a runtime function, so for
1612 // convenience, go ahead and return a naked pointer.
1613 return LocValue.getPointer();
Alexey Bataev9959db52014-05-06 10:08:46 +00001614}
1615
Alexey Bataev3eff5f42015-02-25 08:32:46 +00001616llvm::Value *CGOpenMPRuntime::getThreadID(CodeGenFunction &CGF,
1617 SourceLocation Loc) {
Alexey Bataev9959db52014-05-06 10:08:46 +00001618 assert(CGF.CurFn && "No function in current CodeGenFunction.");
1619
Alexey Bataev4a5bb772014-10-08 14:01:46 +00001620 llvm::Value *ThreadID = nullptr;
Alexey Bataev18095712014-10-10 12:19:54 +00001621 // Check whether we've already cached a load of the thread id in this
1622 // function.
Alexey Bataev1e4b7132014-12-03 12:11:24 +00001623 auto I = OpenMPLocThreadIDMap.find(CGF.CurFn);
Alexey Bataev18095712014-10-10 12:19:54 +00001624 if (I != OpenMPLocThreadIDMap.end()) {
1625 ThreadID = I->second.ThreadID;
Alexey Bataev03b340a2014-10-21 03:16:40 +00001626 if (ThreadID != nullptr)
1627 return ThreadID;
1628 }
Alexey Bataevaee18552017-08-16 14:01:00 +00001629 // If exceptions are enabled, do not use parameter to avoid possible crash.
Alexey Bataev5d2c9a42017-11-02 18:55:05 +00001630 if (!CGF.EHStack.requiresLandingPad() || !CGF.getLangOpts().Exceptions ||
1631 !CGF.getLangOpts().CXXExceptions ||
Alexey Bataev0e1b4582017-11-02 14:25:34 +00001632 CGF.Builder.GetInsertBlock() == CGF.AllocaInsertPt->getParent()) {
Alexey Bataevaee18552017-08-16 14:01:00 +00001633 if (auto *OMPRegionInfo =
1634 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
1635 if (OMPRegionInfo->getThreadIDVariable()) {
1636 // Check if this an outlined function with thread id passed as argument.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001637 LValue LVal = OMPRegionInfo->getThreadIDVariableLValue(CGF);
Alexey Bataev1e491372018-01-23 18:44:14 +00001638 ThreadID = CGF.EmitLoadOfScalar(LVal, Loc);
Alexey Bataevaee18552017-08-16 14:01:00 +00001639 // If value loaded in entry block, cache it and use it everywhere in
1640 // function.
1641 if (CGF.Builder.GetInsertBlock() == CGF.AllocaInsertPt->getParent()) {
1642 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
1643 Elem.second.ThreadID = ThreadID;
1644 }
1645 return ThreadID;
Alexey Bataev8cbe0a62015-02-26 10:27:34 +00001646 }
Alexey Bataevd6c57552014-07-25 07:55:17 +00001647 }
Alexey Bataev9959db52014-05-06 10:08:46 +00001648 }
Alexey Bataev8cbe0a62015-02-26 10:27:34 +00001649
1650 // This is not an outlined function region - need to call __kmpc_int32
1651 // kmpc_global_thread_num(ident_t *loc).
1652 // Generate thread id value and cache this value for use across the
1653 // function.
Alexey Bataevfd006c42018-10-05 15:08:53 +00001654 auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn);
1655 if (!Elem.second.ServiceInsertPt)
1656 setLocThreadIdInsertPt(CGF);
Alexey Bataev8cbe0a62015-02-26 10:27:34 +00001657 CGBuilderTy::InsertPointGuard IPG(CGF.Builder);
Alexey Bataevfd006c42018-10-05 15:08:53 +00001658 CGF.Builder.SetInsertPoint(Elem.second.ServiceInsertPt);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001659 llvm::CallInst *Call = CGF.Builder.CreateCall(
Alexey Bataev0e1b4582017-11-02 14:25:34 +00001660 createRuntimeFunction(OMPRTL__kmpc_global_thread_num),
1661 emitUpdateLocation(CGF, Loc));
1662 Call->setCallingConv(CGF.getRuntimeCC());
Alexey Bataev0e1b4582017-11-02 14:25:34 +00001663 Elem.second.ThreadID = Call;
1664 return Call;
Alexey Bataev9959db52014-05-06 10:08:46 +00001665}
1666
Alexey Bataev3eff5f42015-02-25 08:32:46 +00001667void CGOpenMPRuntime::functionFinished(CodeGenFunction &CGF) {
Alexey Bataev9959db52014-05-06 10:08:46 +00001668 assert(CGF.CurFn && "No function in current CodeGenFunction.");
Alexey Bataevfd006c42018-10-05 15:08:53 +00001669 if (OpenMPLocThreadIDMap.count(CGF.CurFn)) {
1670 clearLocThreadIdInsertPt(CGF);
Alexey Bataev03b340a2014-10-21 03:16:40 +00001671 OpenMPLocThreadIDMap.erase(CGF.CurFn);
Alexey Bataevfd006c42018-10-05 15:08:53 +00001672 }
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001673 if (FunctionUDRMap.count(CGF.CurFn) > 0) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001674 for(auto *D : FunctionUDRMap[CGF.CurFn])
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001675 UDRMap.erase(D);
Alexey Bataevc5b1d322016-03-04 09:22:22 +00001676 FunctionUDRMap.erase(CGF.CurFn);
1677 }
Alexey Bataev9959db52014-05-06 10:08:46 +00001678}
1679
1680llvm::Type *CGOpenMPRuntime::getIdentTyPointerTy() {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001681 return IdentTy->getPointerTo();
Alexey Bataev9959db52014-05-06 10:08:46 +00001682}
1683
1684llvm::Type *CGOpenMPRuntime::getKmpc_MicroPointerTy() {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00001685 if (!Kmpc_MicroTy) {
1686 // Build void (*kmpc_micro)(kmp_int32 *global_tid, kmp_int32 *bound_tid,...)
1687 llvm::Type *MicroParams[] = {llvm::PointerType::getUnqual(CGM.Int32Ty),
1688 llvm::PointerType::getUnqual(CGM.Int32Ty)};
1689 Kmpc_MicroTy = llvm::FunctionType::get(CGM.VoidTy, MicroParams, true);
1690 }
Alexey Bataev9959db52014-05-06 10:08:46 +00001691 return llvm::PointerType::getUnqual(Kmpc_MicroTy);
1692}
1693
James Y Knight9871db02019-02-05 16:42:33 +00001694llvm::FunctionCallee CGOpenMPRuntime::createRuntimeFunction(unsigned Function) {
1695 llvm::FunctionCallee RTLFn = nullptr;
Alexey Bataev50b3c952016-02-19 10:38:26 +00001696 switch (static_cast<OpenMPRTLFunction>(Function)) {
Alexey Bataev9959db52014-05-06 10:08:46 +00001697 case OMPRTL__kmpc_fork_call: {
1698 // Build void __kmpc_fork_call(ident_t *loc, kmp_int32 argc, kmpc_micro
1699 // microtask, ...);
Alexey Bataev23b69422014-06-18 07:08:49 +00001700 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
1701 getKmpc_MicroPointerTy()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001702 auto *FnTy =
Alexey Bataevd74d0602014-10-13 06:02:40 +00001703 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ true);
Alexey Bataev9959db52014-05-06 10:08:46 +00001704 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_fork_call");
James Y Knight9871db02019-02-05 16:42:33 +00001705 if (auto *F = dyn_cast<llvm::Function>(RTLFn.getCallee())) {
Johannes Doerfertac991bb2019-01-19 05:36:54 +00001706 if (!F->hasMetadata(llvm::LLVMContext::MD_callback)) {
1707 llvm::LLVMContext &Ctx = F->getContext();
1708 llvm::MDBuilder MDB(Ctx);
1709 // Annotate the callback behavior of the __kmpc_fork_call:
1710 // - The callback callee is argument number 2 (microtask).
1711 // - The first two arguments of the callback callee are unknown (-1).
1712 // - All variadic arguments to the __kmpc_fork_call are passed to the
1713 // callback callee.
1714 F->addMetadata(
1715 llvm::LLVMContext::MD_callback,
1716 *llvm::MDNode::get(Ctx, {MDB.createCallbackEncoding(
1717 2, {-1, -1},
1718 /* VarArgsArePassed */ true)}));
1719 }
1720 }
Alexey Bataev9959db52014-05-06 10:08:46 +00001721 break;
1722 }
1723 case OMPRTL__kmpc_global_thread_num: {
1724 // Build kmp_int32 __kmpc_global_thread_num(ident_t *loc);
Alexey Bataev23b69422014-06-18 07:08:49 +00001725 llvm::Type *TypeParams[] = {getIdentTyPointerTy()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001726 auto *FnTy =
Alexey Bataevd74d0602014-10-13 06:02:40 +00001727 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
Alexey Bataev9959db52014-05-06 10:08:46 +00001728 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_global_thread_num");
1729 break;
1730 }
Alexey Bataev97720002014-11-11 04:05:39 +00001731 case OMPRTL__kmpc_threadprivate_cached: {
1732 // Build void *__kmpc_threadprivate_cached(ident_t *loc,
1733 // kmp_int32 global_tid, void *data, size_t size, void ***cache);
1734 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
1735 CGM.VoidPtrTy, CGM.SizeTy,
1736 CGM.VoidPtrTy->getPointerTo()->getPointerTo()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001737 auto *FnTy =
Alexey Bataev97720002014-11-11 04:05:39 +00001738 llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg*/ false);
1739 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_threadprivate_cached");
1740 break;
1741 }
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00001742 case OMPRTL__kmpc_critical: {
Alexey Bataevf9472182014-09-22 12:32:31 +00001743 // Build void __kmpc_critical(ident_t *loc, kmp_int32 global_tid,
1744 // kmp_critical_name *crit);
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00001745 llvm::Type *TypeParams[] = {
1746 getIdentTyPointerTy(), CGM.Int32Ty,
1747 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001748 auto *FnTy =
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00001749 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1750 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_critical");
1751 break;
1752 }
Alexey Bataevfc57d162015-12-15 10:55:09 +00001753 case OMPRTL__kmpc_critical_with_hint: {
1754 // Build void __kmpc_critical_with_hint(ident_t *loc, kmp_int32 global_tid,
1755 // kmp_critical_name *crit, uintptr_t hint);
1756 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
1757 llvm::PointerType::getUnqual(KmpCriticalNameTy),
1758 CGM.IntPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001759 auto *FnTy =
Alexey Bataevfc57d162015-12-15 10:55:09 +00001760 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1761 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_critical_with_hint");
1762 break;
1763 }
Alexey Bataev97720002014-11-11 04:05:39 +00001764 case OMPRTL__kmpc_threadprivate_register: {
1765 // Build void __kmpc_threadprivate_register(ident_t *, void *data,
1766 // kmpc_ctor ctor, kmpc_cctor cctor, kmpc_dtor dtor);
1767 // typedef void *(*kmpc_ctor)(void *);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001768 auto *KmpcCtorTy =
Alexey Bataev97720002014-11-11 04:05:39 +00001769 llvm::FunctionType::get(CGM.VoidPtrTy, CGM.VoidPtrTy,
1770 /*isVarArg*/ false)->getPointerTo();
1771 // typedef void *(*kmpc_cctor)(void *, void *);
1772 llvm::Type *KmpcCopyCtorTyArgs[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001773 auto *KmpcCopyCtorTy =
Alexey Bataev97720002014-11-11 04:05:39 +00001774 llvm::FunctionType::get(CGM.VoidPtrTy, KmpcCopyCtorTyArgs,
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001775 /*isVarArg*/ false)
1776 ->getPointerTo();
Alexey Bataev97720002014-11-11 04:05:39 +00001777 // typedef void (*kmpc_dtor)(void *);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001778 auto *KmpcDtorTy =
Alexey Bataev97720002014-11-11 04:05:39 +00001779 llvm::FunctionType::get(CGM.VoidTy, CGM.VoidPtrTy, /*isVarArg*/ false)
1780 ->getPointerTo();
1781 llvm::Type *FnTyArgs[] = {getIdentTyPointerTy(), CGM.VoidPtrTy, KmpcCtorTy,
1782 KmpcCopyCtorTy, KmpcDtorTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001783 auto *FnTy = llvm::FunctionType::get(CGM.VoidTy, FnTyArgs,
Alexey Bataev97720002014-11-11 04:05:39 +00001784 /*isVarArg*/ false);
1785 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_threadprivate_register");
1786 break;
1787 }
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00001788 case OMPRTL__kmpc_end_critical: {
Alexey Bataevf9472182014-09-22 12:32:31 +00001789 // Build void __kmpc_end_critical(ident_t *loc, kmp_int32 global_tid,
1790 // kmp_critical_name *crit);
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00001791 llvm::Type *TypeParams[] = {
1792 getIdentTyPointerTy(), CGM.Int32Ty,
1793 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001794 auto *FnTy =
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00001795 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1796 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_critical");
1797 break;
1798 }
Alexey Bataev8f7c1b02014-12-05 04:09:23 +00001799 case OMPRTL__kmpc_cancel_barrier: {
1800 // Build kmp_int32 __kmpc_cancel_barrier(ident_t *loc, kmp_int32
1801 // global_tid);
Alexey Bataev4a5bb772014-10-08 14:01:46 +00001802 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001803 auto *FnTy =
Alexey Bataev8f7c1b02014-12-05 04:09:23 +00001804 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
1805 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name*/ "__kmpc_cancel_barrier");
Alexey Bataev4a5bb772014-10-08 14:01:46 +00001806 break;
1807 }
Alexey Bataev81c7ea02015-07-03 09:56:58 +00001808 case OMPRTL__kmpc_barrier: {
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00001809 // Build void __kmpc_barrier(ident_t *loc, kmp_int32 global_tid);
Alexey Bataev81c7ea02015-07-03 09:56:58 +00001810 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001811 auto *FnTy =
Alexey Bataev81c7ea02015-07-03 09:56:58 +00001812 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1813 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name*/ "__kmpc_barrier");
1814 break;
1815 }
Alexander Musmanc6388682014-12-15 07:07:06 +00001816 case OMPRTL__kmpc_for_static_fini: {
1817 // Build void __kmpc_for_static_fini(ident_t *loc, kmp_int32 global_tid);
1818 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001819 auto *FnTy =
Alexander Musmanc6388682014-12-15 07:07:06 +00001820 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1821 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_for_static_fini");
1822 break;
1823 }
Alexey Bataevb2059782014-10-13 08:23:51 +00001824 case OMPRTL__kmpc_push_num_threads: {
1825 // Build void __kmpc_push_num_threads(ident_t *loc, kmp_int32 global_tid,
1826 // kmp_int32 num_threads)
1827 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
1828 CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001829 auto *FnTy =
Alexey Bataevb2059782014-10-13 08:23:51 +00001830 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1831 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_num_threads");
1832 break;
1833 }
Alexey Bataevd74d0602014-10-13 06:02:40 +00001834 case OMPRTL__kmpc_serialized_parallel: {
1835 // Build void __kmpc_serialized_parallel(ident_t *loc, kmp_int32
1836 // global_tid);
1837 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001838 auto *FnTy =
Alexey Bataevd74d0602014-10-13 06:02:40 +00001839 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1840 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_serialized_parallel");
1841 break;
1842 }
1843 case OMPRTL__kmpc_end_serialized_parallel: {
1844 // Build void __kmpc_end_serialized_parallel(ident_t *loc, kmp_int32
1845 // global_tid);
1846 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001847 auto *FnTy =
Alexey Bataevd74d0602014-10-13 06:02:40 +00001848 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
1849 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_serialized_parallel");
1850 break;
1851 }
Alexey Bataevcc37cc12014-11-20 04:34:54 +00001852 case OMPRTL__kmpc_flush: {
Alexey Bataevd76df6d2015-02-24 12:55:09 +00001853 // Build void __kmpc_flush(ident_t *loc);
Alexey Bataevcc37cc12014-11-20 04:34:54 +00001854 llvm::Type *TypeParams[] = {getIdentTyPointerTy()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001855 auto *FnTy =
Alexey Bataevd76df6d2015-02-24 12:55:09 +00001856 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
Alexey Bataevcc37cc12014-11-20 04:34:54 +00001857 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_flush");
1858 break;
1859 }
Alexey Bataev8d690652014-12-04 07:23:53 +00001860 case OMPRTL__kmpc_master: {
1861 // Build kmp_int32 __kmpc_master(ident_t *loc, kmp_int32 global_tid);
1862 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001863 auto *FnTy =
Alexey Bataev8d690652014-12-04 07:23:53 +00001864 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
1865 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_master");
1866 break;
1867 }
1868 case OMPRTL__kmpc_end_master: {
1869 // Build void __kmpc_end_master(ident_t *loc, kmp_int32 global_tid);
1870 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001871 auto *FnTy =
Alexey Bataev8d690652014-12-04 07:23:53 +00001872 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
1873 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_master");
1874 break;
1875 }
Alexey Bataev9f797f32015-02-05 05:57:51 +00001876 case OMPRTL__kmpc_omp_taskyield: {
1877 // Build kmp_int32 __kmpc_omp_taskyield(ident_t *, kmp_int32 global_tid,
1878 // int end_part);
1879 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001880 auto *FnTy =
Alexey Bataev9f797f32015-02-05 05:57:51 +00001881 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
1882 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_taskyield");
1883 break;
1884 }
Alexey Bataev6956e2e2015-02-05 06:35:41 +00001885 case OMPRTL__kmpc_single: {
1886 // Build kmp_int32 __kmpc_single(ident_t *loc, kmp_int32 global_tid);
1887 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001888 auto *FnTy =
Alexey Bataev6956e2e2015-02-05 06:35:41 +00001889 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
1890 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_single");
1891 break;
1892 }
1893 case OMPRTL__kmpc_end_single: {
1894 // Build void __kmpc_end_single(ident_t *loc, kmp_int32 global_tid);
1895 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001896 auto *FnTy =
Alexey Bataev6956e2e2015-02-05 06:35:41 +00001897 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
1898 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_single");
1899 break;
1900 }
Alexey Bataev62b63b12015-03-10 07:28:44 +00001901 case OMPRTL__kmpc_omp_task_alloc: {
1902 // Build kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid,
1903 // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
1904 // kmp_routine_entry_t *task_entry);
1905 assert(KmpRoutineEntryPtrTy != nullptr &&
1906 "Type kmp_routine_entry_t must be created.");
1907 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty,
1908 CGM.SizeTy, CGM.SizeTy, KmpRoutineEntryPtrTy};
1909 // Return void * and then cast to particular kmp_task_t type.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001910 auto *FnTy =
Alexey Bataev62b63b12015-03-10 07:28:44 +00001911 llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg=*/false);
1912 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task_alloc");
1913 break;
1914 }
1915 case OMPRTL__kmpc_omp_task: {
1916 // Build kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t
1917 // *new_task);
1918 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
1919 CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001920 auto *FnTy =
Alexey Bataev62b63b12015-03-10 07:28:44 +00001921 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
1922 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task");
1923 break;
1924 }
Alexey Bataeva63048e2015-03-23 06:18:07 +00001925 case OMPRTL__kmpc_copyprivate: {
1926 // Build void __kmpc_copyprivate(ident_t *loc, kmp_int32 global_tid,
Alexey Bataev66beaa92015-04-30 03:47:32 +00001927 // size_t cpy_size, void *cpy_data, void(*cpy_func)(void *, void *),
Alexey Bataeva63048e2015-03-23 06:18:07 +00001928 // kmp_int32 didit);
1929 llvm::Type *CpyTypeParams[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
1930 auto *CpyFnTy =
1931 llvm::FunctionType::get(CGM.VoidTy, CpyTypeParams, /*isVarArg=*/false);
Alexey Bataev66beaa92015-04-30 03:47:32 +00001932 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.SizeTy,
Alexey Bataeva63048e2015-03-23 06:18:07 +00001933 CGM.VoidPtrTy, CpyFnTy->getPointerTo(),
1934 CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001935 auto *FnTy =
Alexey Bataeva63048e2015-03-23 06:18:07 +00001936 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
1937 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_copyprivate");
1938 break;
1939 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001940 case OMPRTL__kmpc_reduce: {
1941 // Build kmp_int32 __kmpc_reduce(ident_t *loc, kmp_int32 global_tid,
1942 // kmp_int32 num_vars, size_t reduce_size, void *reduce_data, void
1943 // (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name *lck);
1944 llvm::Type *ReduceTypeParams[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
1945 auto *ReduceFnTy = llvm::FunctionType::get(CGM.VoidTy, ReduceTypeParams,
1946 /*isVarArg=*/false);
1947 llvm::Type *TypeParams[] = {
1948 getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty, CGM.SizeTy,
1949 CGM.VoidPtrTy, ReduceFnTy->getPointerTo(),
1950 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001951 auto *FnTy =
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001952 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
1953 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_reduce");
1954 break;
1955 }
1956 case OMPRTL__kmpc_reduce_nowait: {
1957 // Build kmp_int32 __kmpc_reduce_nowait(ident_t *loc, kmp_int32
1958 // global_tid, kmp_int32 num_vars, size_t reduce_size, void *reduce_data,
1959 // void (*reduce_func)(void *lhs_data, void *rhs_data), kmp_critical_name
1960 // *lck);
1961 llvm::Type *ReduceTypeParams[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
1962 auto *ReduceFnTy = llvm::FunctionType::get(CGM.VoidTy, ReduceTypeParams,
1963 /*isVarArg=*/false);
1964 llvm::Type *TypeParams[] = {
1965 getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty, CGM.SizeTy,
1966 CGM.VoidPtrTy, ReduceFnTy->getPointerTo(),
1967 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001968 auto *FnTy =
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001969 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
1970 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_reduce_nowait");
1971 break;
1972 }
1973 case OMPRTL__kmpc_end_reduce: {
1974 // Build void __kmpc_end_reduce(ident_t *loc, kmp_int32 global_tid,
1975 // kmp_critical_name *lck);
1976 llvm::Type *TypeParams[] = {
1977 getIdentTyPointerTy(), CGM.Int32Ty,
1978 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001979 auto *FnTy =
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001980 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
1981 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_reduce");
1982 break;
1983 }
1984 case OMPRTL__kmpc_end_reduce_nowait: {
1985 // Build __kmpc_end_reduce_nowait(ident_t *loc, kmp_int32 global_tid,
1986 // kmp_critical_name *lck);
1987 llvm::Type *TypeParams[] = {
1988 getIdentTyPointerTy(), CGM.Int32Ty,
1989 llvm::PointerType::getUnqual(KmpCriticalNameTy)};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00001990 auto *FnTy =
Alexey Bataev794ba0d2015-04-10 10:43:45 +00001991 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
1992 RTLFn =
1993 CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_end_reduce_nowait");
1994 break;
1995 }
Alexey Bataev1d677132015-04-22 13:57:31 +00001996 case OMPRTL__kmpc_omp_task_begin_if0: {
1997 // Build void __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t
1998 // *new_task);
1999 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
2000 CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002001 auto *FnTy =
Alexey Bataev1d677132015-04-22 13:57:31 +00002002 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2003 RTLFn =
2004 CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task_begin_if0");
2005 break;
2006 }
2007 case OMPRTL__kmpc_omp_task_complete_if0: {
2008 // Build void __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t
2009 // *new_task);
2010 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
2011 CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002012 auto *FnTy =
Alexey Bataev1d677132015-04-22 13:57:31 +00002013 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2014 RTLFn = CGM.CreateRuntimeFunction(FnTy,
2015 /*Name=*/"__kmpc_omp_task_complete_if0");
2016 break;
2017 }
Alexey Bataev98eb6e32015-04-22 11:15:40 +00002018 case OMPRTL__kmpc_ordered: {
2019 // Build void __kmpc_ordered(ident_t *loc, kmp_int32 global_tid);
2020 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002021 auto *FnTy =
Alexey Bataev98eb6e32015-04-22 11:15:40 +00002022 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2023 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_ordered");
2024 break;
2025 }
2026 case OMPRTL__kmpc_end_ordered: {
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002027 // Build void __kmpc_end_ordered(ident_t *loc, kmp_int32 global_tid);
Alexey Bataev98eb6e32015-04-22 11:15:40 +00002028 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002029 auto *FnTy =
Alexey Bataev98eb6e32015-04-22 11:15:40 +00002030 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2031 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_ordered");
2032 break;
2033 }
Alexey Bataev8b8e2022015-04-27 05:22:09 +00002034 case OMPRTL__kmpc_omp_taskwait: {
2035 // Build kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32 global_tid);
2036 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002037 auto *FnTy =
Alexey Bataev8b8e2022015-04-27 05:22:09 +00002038 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
2039 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_omp_taskwait");
2040 break;
2041 }
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002042 case OMPRTL__kmpc_taskgroup: {
2043 // Build void __kmpc_taskgroup(ident_t *loc, kmp_int32 global_tid);
2044 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002045 auto *FnTy =
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002046 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2047 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_taskgroup");
2048 break;
2049 }
2050 case OMPRTL__kmpc_end_taskgroup: {
2051 // Build void __kmpc_end_taskgroup(ident_t *loc, kmp_int32 global_tid);
2052 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002053 auto *FnTy =
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002054 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2055 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_taskgroup");
2056 break;
2057 }
Alexey Bataev7f210c62015-06-18 13:40:03 +00002058 case OMPRTL__kmpc_push_proc_bind: {
2059 // Build void __kmpc_push_proc_bind(ident_t *loc, kmp_int32 global_tid,
2060 // int proc_bind)
2061 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002062 auto *FnTy =
Alexey Bataev7f210c62015-06-18 13:40:03 +00002063 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2064 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_proc_bind");
2065 break;
2066 }
Alexey Bataev1d2353d2015-06-24 11:01:36 +00002067 case OMPRTL__kmpc_omp_task_with_deps: {
2068 // Build kmp_int32 __kmpc_omp_task_with_deps(ident_t *, kmp_int32 gtid,
2069 // kmp_task_t *new_task, kmp_int32 ndeps, kmp_depend_info_t *dep_list,
2070 // kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list);
2071 llvm::Type *TypeParams[] = {
2072 getIdentTyPointerTy(), CGM.Int32Ty, CGM.VoidPtrTy, CGM.Int32Ty,
2073 CGM.VoidPtrTy, CGM.Int32Ty, CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002074 auto *FnTy =
Alexey Bataev1d2353d2015-06-24 11:01:36 +00002075 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg=*/false);
2076 RTLFn =
2077 CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_task_with_deps");
2078 break;
2079 }
2080 case OMPRTL__kmpc_omp_wait_deps: {
2081 // Build void __kmpc_omp_wait_deps(ident_t *, kmp_int32 gtid,
2082 // kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32 ndeps_noalias,
2083 // kmp_depend_info_t *noalias_dep_list);
2084 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
2085 CGM.Int32Ty, CGM.VoidPtrTy,
2086 CGM.Int32Ty, CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002087 auto *FnTy =
Alexey Bataev1d2353d2015-06-24 11:01:36 +00002088 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2089 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_omp_wait_deps");
2090 break;
2091 }
Alexey Bataev0f34da12015-07-02 04:17:07 +00002092 case OMPRTL__kmpc_cancellationpoint: {
2093 // Build kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32
2094 // global_tid, kmp_int32 cncl_kind)
2095 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002096 auto *FnTy =
Alexey Bataev0f34da12015-07-02 04:17:07 +00002097 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2098 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_cancellationpoint");
2099 break;
2100 }
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00002101 case OMPRTL__kmpc_cancel: {
2102 // Build kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid,
2103 // kmp_int32 cncl_kind)
2104 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.IntTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002105 auto *FnTy =
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00002106 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2107 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_cancel");
2108 break;
2109 }
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00002110 case OMPRTL__kmpc_push_num_teams: {
2111 // Build void kmpc_push_num_teams (ident_t loc, kmp_int32 global_tid,
2112 // kmp_int32 num_teams, kmp_int32 num_threads)
2113 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty, CGM.Int32Ty,
2114 CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002115 auto *FnTy =
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00002116 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2117 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_num_teams");
2118 break;
2119 }
2120 case OMPRTL__kmpc_fork_teams: {
2121 // Build void __kmpc_fork_teams(ident_t *loc, kmp_int32 argc, kmpc_micro
2122 // microtask, ...);
2123 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
2124 getKmpc_MicroPointerTy()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002125 auto *FnTy =
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00002126 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ true);
2127 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_fork_teams");
James Y Knight9871db02019-02-05 16:42:33 +00002128 if (auto *F = dyn_cast<llvm::Function>(RTLFn.getCallee())) {
Johannes Doerfertac991bb2019-01-19 05:36:54 +00002129 if (!F->hasMetadata(llvm::LLVMContext::MD_callback)) {
2130 llvm::LLVMContext &Ctx = F->getContext();
2131 llvm::MDBuilder MDB(Ctx);
2132 // Annotate the callback behavior of the __kmpc_fork_teams:
2133 // - The callback callee is argument number 2 (microtask).
2134 // - The first two arguments of the callback callee are unknown (-1).
2135 // - All variadic arguments to the __kmpc_fork_teams are passed to the
2136 // callback callee.
2137 F->addMetadata(
2138 llvm::LLVMContext::MD_callback,
2139 *llvm::MDNode::get(Ctx, {MDB.createCallbackEncoding(
2140 2, {-1, -1},
2141 /* VarArgsArePassed */ true)}));
2142 }
2143 }
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00002144 break;
2145 }
Alexey Bataev7292c292016-04-25 12:22:29 +00002146 case OMPRTL__kmpc_taskloop: {
2147 // Build void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t *task, int
2148 // if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int nogroup, int
2149 // sched, kmp_uint64 grainsize, void *task_dup);
2150 llvm::Type *TypeParams[] = {getIdentTyPointerTy(),
2151 CGM.IntTy,
2152 CGM.VoidPtrTy,
2153 CGM.IntTy,
2154 CGM.Int64Ty->getPointerTo(),
2155 CGM.Int64Ty->getPointerTo(),
2156 CGM.Int64Ty,
2157 CGM.IntTy,
2158 CGM.IntTy,
2159 CGM.Int64Ty,
2160 CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002161 auto *FnTy =
Alexey Bataev7292c292016-04-25 12:22:29 +00002162 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2163 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_taskloop");
2164 break;
2165 }
Alexey Bataev8b427062016-05-25 12:36:08 +00002166 case OMPRTL__kmpc_doacross_init: {
2167 // Build void __kmpc_doacross_init(ident_t *loc, kmp_int32 gtid, kmp_int32
2168 // num_dims, struct kmp_dim *dims);
2169 llvm::Type *TypeParams[] = {getIdentTyPointerTy(),
2170 CGM.Int32Ty,
2171 CGM.Int32Ty,
2172 CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002173 auto *FnTy =
Alexey Bataev8b427062016-05-25 12:36:08 +00002174 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2175 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_doacross_init");
2176 break;
2177 }
2178 case OMPRTL__kmpc_doacross_fini: {
2179 // Build void __kmpc_doacross_fini(ident_t *loc, kmp_int32 gtid);
2180 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002181 auto *FnTy =
Alexey Bataev8b427062016-05-25 12:36:08 +00002182 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2183 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_doacross_fini");
2184 break;
2185 }
2186 case OMPRTL__kmpc_doacross_post: {
2187 // Build void __kmpc_doacross_post(ident_t *loc, kmp_int32 gtid, kmp_int64
2188 // *vec);
2189 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
2190 CGM.Int64Ty->getPointerTo()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002191 auto *FnTy =
Alexey Bataev8b427062016-05-25 12:36:08 +00002192 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2193 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_doacross_post");
2194 break;
2195 }
2196 case OMPRTL__kmpc_doacross_wait: {
2197 // Build void __kmpc_doacross_wait(ident_t *loc, kmp_int32 gtid, kmp_int64
2198 // *vec);
2199 llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty,
2200 CGM.Int64Ty->getPointerTo()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002201 auto *FnTy =
Alexey Bataev8b427062016-05-25 12:36:08 +00002202 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2203 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_doacross_wait");
2204 break;
2205 }
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00002206 case OMPRTL__kmpc_task_reduction_init: {
2207 // Build void *__kmpc_task_reduction_init(int gtid, int num_data, void
2208 // *data);
2209 llvm::Type *TypeParams[] = {CGM.IntTy, CGM.IntTy, CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002210 auto *FnTy =
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00002211 llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg=*/false);
2212 RTLFn =
2213 CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_task_reduction_init");
2214 break;
2215 }
2216 case OMPRTL__kmpc_task_reduction_get_th_data: {
2217 // Build void *__kmpc_task_reduction_get_th_data(int gtid, void *tg, void
2218 // *d);
2219 llvm::Type *TypeParams[] = {CGM.IntTy, CGM.VoidPtrTy, CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002220 auto *FnTy =
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00002221 llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg=*/false);
2222 RTLFn = CGM.CreateRuntimeFunction(
2223 FnTy, /*Name=*/"__kmpc_task_reduction_get_th_data");
2224 break;
2225 }
Alexey Bataev4f680db2019-03-19 16:41:16 +00002226 case OMPRTL__kmpc_alloc: {
Alexey Bataev6cf7b712019-04-08 19:06:42 +00002227 // Build to void *__kmpc_alloc(int gtid, size_t sz, omp_allocator_handle_t
2228 // al); omp_allocator_handle_t type is void *.
2229 llvm::Type *TypeParams[] = {CGM.IntTy, CGM.SizeTy, CGM.VoidPtrTy};
Alexey Bataev4f680db2019-03-19 16:41:16 +00002230 auto *FnTy =
2231 llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg=*/false);
2232 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_alloc");
2233 break;
2234 }
2235 case OMPRTL__kmpc_free: {
Alexey Bataev6cf7b712019-04-08 19:06:42 +00002236 // Build to void __kmpc_free(int gtid, void *ptr, omp_allocator_handle_t
2237 // al); omp_allocator_handle_t type is void *.
2238 llvm::Type *TypeParams[] = {CGM.IntTy, CGM.VoidPtrTy, CGM.VoidPtrTy};
Alexey Bataev4f680db2019-03-19 16:41:16 +00002239 auto *FnTy =
2240 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2241 RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_free");
2242 break;
2243 }
Alexey Bataev7bb33532019-01-07 21:30:43 +00002244 case OMPRTL__kmpc_push_target_tripcount: {
2245 // Build void __kmpc_push_target_tripcount(int64_t device_id, kmp_uint64
2246 // size);
2247 llvm::Type *TypeParams[] = {CGM.Int64Ty, CGM.Int64Ty};
2248 llvm::FunctionType *FnTy =
2249 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2250 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_push_target_tripcount");
2251 break;
2252 }
Samuel Antaobed3c462015-10-02 16:14:20 +00002253 case OMPRTL__tgt_target: {
George Rokos63bc9d62017-11-21 18:25:12 +00002254 // Build int32_t __tgt_target(int64_t device_id, void *host_ptr, int32_t
2255 // arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
Samuel Antaobed3c462015-10-02 16:14:20 +00002256 // *arg_types);
George Rokos63bc9d62017-11-21 18:25:12 +00002257 llvm::Type *TypeParams[] = {CGM.Int64Ty,
Samuel Antaobed3c462015-10-02 16:14:20 +00002258 CGM.VoidPtrTy,
2259 CGM.Int32Ty,
2260 CGM.VoidPtrPtrTy,
2261 CGM.VoidPtrPtrTy,
2262 CGM.SizeTy->getPointerTo(),
George Rokos63bc9d62017-11-21 18:25:12 +00002263 CGM.Int64Ty->getPointerTo()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002264 auto *FnTy =
Samuel Antaobed3c462015-10-02 16:14:20 +00002265 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2266 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target");
2267 break;
2268 }
Alexey Bataeva9f77c62017-12-13 21:04:20 +00002269 case OMPRTL__tgt_target_nowait: {
2270 // Build int32_t __tgt_target_nowait(int64_t device_id, void *host_ptr,
2271 // int32_t arg_num, void** args_base, void **args, size_t *arg_sizes,
2272 // int64_t *arg_types);
2273 llvm::Type *TypeParams[] = {CGM.Int64Ty,
2274 CGM.VoidPtrTy,
2275 CGM.Int32Ty,
2276 CGM.VoidPtrPtrTy,
2277 CGM.VoidPtrPtrTy,
2278 CGM.SizeTy->getPointerTo(),
2279 CGM.Int64Ty->getPointerTo()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002280 auto *FnTy =
Alexey Bataeva9f77c62017-12-13 21:04:20 +00002281 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2282 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_nowait");
2283 break;
2284 }
Samuel Antaob68e2db2016-03-03 16:20:23 +00002285 case OMPRTL__tgt_target_teams: {
George Rokos63bc9d62017-11-21 18:25:12 +00002286 // Build int32_t __tgt_target_teams(int64_t device_id, void *host_ptr,
Samuel Antaob68e2db2016-03-03 16:20:23 +00002287 // int32_t arg_num, void** args_base, void **args, size_t *arg_sizes,
George Rokos63bc9d62017-11-21 18:25:12 +00002288 // int64_t *arg_types, int32_t num_teams, int32_t thread_limit);
2289 llvm::Type *TypeParams[] = {CGM.Int64Ty,
Samuel Antaob68e2db2016-03-03 16:20:23 +00002290 CGM.VoidPtrTy,
2291 CGM.Int32Ty,
2292 CGM.VoidPtrPtrTy,
2293 CGM.VoidPtrPtrTy,
2294 CGM.SizeTy->getPointerTo(),
George Rokos63bc9d62017-11-21 18:25:12 +00002295 CGM.Int64Ty->getPointerTo(),
Samuel Antaob68e2db2016-03-03 16:20:23 +00002296 CGM.Int32Ty,
2297 CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002298 auto *FnTy =
Samuel Antaob68e2db2016-03-03 16:20:23 +00002299 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2300 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_teams");
2301 break;
2302 }
Alexey Bataeva9f77c62017-12-13 21:04:20 +00002303 case OMPRTL__tgt_target_teams_nowait: {
2304 // Build int32_t __tgt_target_teams_nowait(int64_t device_id, void
2305 // *host_ptr, int32_t arg_num, void** args_base, void **args, size_t
2306 // *arg_sizes, int64_t *arg_types, int32_t num_teams, int32_t thread_limit);
2307 llvm::Type *TypeParams[] = {CGM.Int64Ty,
2308 CGM.VoidPtrTy,
2309 CGM.Int32Ty,
2310 CGM.VoidPtrPtrTy,
2311 CGM.VoidPtrPtrTy,
2312 CGM.SizeTy->getPointerTo(),
2313 CGM.Int64Ty->getPointerTo(),
2314 CGM.Int32Ty,
2315 CGM.Int32Ty};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002316 auto *FnTy =
Alexey Bataeva9f77c62017-12-13 21:04:20 +00002317 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2318 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_teams_nowait");
2319 break;
2320 }
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +00002321 case OMPRTL__tgt_register_requires: {
2322 // Build void __tgt_register_requires(int64_t flags);
2323 llvm::Type *TypeParams[] = {CGM.Int64Ty};
2324 auto *FnTy =
2325 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2326 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_register_requires");
2327 break;
2328 }
Samuel Antaoee8fb302016-01-06 13:42:12 +00002329 case OMPRTL__tgt_register_lib: {
2330 // Build void __tgt_register_lib(__tgt_bin_desc *desc);
2331 QualType ParamTy =
2332 CGM.getContext().getPointerType(getTgtBinaryDescriptorQTy());
2333 llvm::Type *TypeParams[] = {CGM.getTypes().ConvertTypeForMem(ParamTy)};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002334 auto *FnTy =
Samuel Antaoee8fb302016-01-06 13:42:12 +00002335 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2336 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_register_lib");
2337 break;
2338 }
2339 case OMPRTL__tgt_unregister_lib: {
2340 // Build void __tgt_unregister_lib(__tgt_bin_desc *desc);
2341 QualType ParamTy =
2342 CGM.getContext().getPointerType(getTgtBinaryDescriptorQTy());
2343 llvm::Type *TypeParams[] = {CGM.getTypes().ConvertTypeForMem(ParamTy)};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002344 auto *FnTy =
Samuel Antaoee8fb302016-01-06 13:42:12 +00002345 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2346 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_unregister_lib");
2347 break;
2348 }
Samuel Antaodf158d52016-04-27 22:58:19 +00002349 case OMPRTL__tgt_target_data_begin: {
George Rokos63bc9d62017-11-21 18:25:12 +00002350 // Build void __tgt_target_data_begin(int64_t device_id, int32_t arg_num,
2351 // void** args_base, void **args, size_t *arg_sizes, int64_t *arg_types);
2352 llvm::Type *TypeParams[] = {CGM.Int64Ty,
Samuel Antaodf158d52016-04-27 22:58:19 +00002353 CGM.Int32Ty,
2354 CGM.VoidPtrPtrTy,
2355 CGM.VoidPtrPtrTy,
2356 CGM.SizeTy->getPointerTo(),
George Rokos63bc9d62017-11-21 18:25:12 +00002357 CGM.Int64Ty->getPointerTo()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002358 auto *FnTy =
Samuel Antaodf158d52016-04-27 22:58:19 +00002359 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2360 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_begin");
2361 break;
2362 }
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +00002363 case OMPRTL__tgt_target_data_begin_nowait: {
2364 // Build void __tgt_target_data_begin_nowait(int64_t device_id, int32_t
2365 // arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
2366 // *arg_types);
2367 llvm::Type *TypeParams[] = {CGM.Int64Ty,
2368 CGM.Int32Ty,
2369 CGM.VoidPtrPtrTy,
2370 CGM.VoidPtrPtrTy,
2371 CGM.SizeTy->getPointerTo(),
2372 CGM.Int64Ty->getPointerTo()};
2373 auto *FnTy =
2374 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2375 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_begin_nowait");
2376 break;
2377 }
Samuel Antaodf158d52016-04-27 22:58:19 +00002378 case OMPRTL__tgt_target_data_end: {
George Rokos63bc9d62017-11-21 18:25:12 +00002379 // Build void __tgt_target_data_end(int64_t device_id, int32_t arg_num,
2380 // void** args_base, void **args, size_t *arg_sizes, int64_t *arg_types);
2381 llvm::Type *TypeParams[] = {CGM.Int64Ty,
Samuel Antaodf158d52016-04-27 22:58:19 +00002382 CGM.Int32Ty,
2383 CGM.VoidPtrPtrTy,
2384 CGM.VoidPtrPtrTy,
2385 CGM.SizeTy->getPointerTo(),
George Rokos63bc9d62017-11-21 18:25:12 +00002386 CGM.Int64Ty->getPointerTo()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002387 auto *FnTy =
Samuel Antaodf158d52016-04-27 22:58:19 +00002388 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2389 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_end");
2390 break;
2391 }
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +00002392 case OMPRTL__tgt_target_data_end_nowait: {
2393 // Build void __tgt_target_data_end_nowait(int64_t device_id, int32_t
2394 // arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
2395 // *arg_types);
2396 llvm::Type *TypeParams[] = {CGM.Int64Ty,
2397 CGM.Int32Ty,
2398 CGM.VoidPtrPtrTy,
2399 CGM.VoidPtrPtrTy,
2400 CGM.SizeTy->getPointerTo(),
2401 CGM.Int64Ty->getPointerTo()};
2402 auto *FnTy =
2403 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2404 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_end_nowait");
2405 break;
2406 }
Samuel Antao8d2d7302016-05-26 18:30:22 +00002407 case OMPRTL__tgt_target_data_update: {
George Rokos63bc9d62017-11-21 18:25:12 +00002408 // Build void __tgt_target_data_update(int64_t device_id, int32_t arg_num,
2409 // void** args_base, void **args, size_t *arg_sizes, int64_t *arg_types);
2410 llvm::Type *TypeParams[] = {CGM.Int64Ty,
Samuel Antao8d2d7302016-05-26 18:30:22 +00002411 CGM.Int32Ty,
2412 CGM.VoidPtrPtrTy,
2413 CGM.VoidPtrPtrTy,
2414 CGM.SizeTy->getPointerTo(),
George Rokos63bc9d62017-11-21 18:25:12 +00002415 CGM.Int64Ty->getPointerTo()};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002416 auto *FnTy =
Samuel Antao8d2d7302016-05-26 18:30:22 +00002417 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2418 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_update");
2419 break;
2420 }
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +00002421 case OMPRTL__tgt_target_data_update_nowait: {
2422 // Build void __tgt_target_data_update_nowait(int64_t device_id, int32_t
2423 // arg_num, void** args_base, void **args, size_t *arg_sizes, int64_t
2424 // *arg_types);
2425 llvm::Type *TypeParams[] = {CGM.Int64Ty,
2426 CGM.Int32Ty,
2427 CGM.VoidPtrPtrTy,
2428 CGM.VoidPtrPtrTy,
2429 CGM.SizeTy->getPointerTo(),
2430 CGM.Int64Ty->getPointerTo()};
2431 auto *FnTy =
2432 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2433 RTLFn = CGM.CreateRuntimeFunction(FnTy, "__tgt_target_data_update_nowait");
2434 break;
2435 }
Alexey Bataev9959db52014-05-06 10:08:46 +00002436 }
Alexey Bataev50b3c952016-02-19 10:38:26 +00002437 assert(RTLFn && "Unable to find OpenMP runtime function");
Alexey Bataev9959db52014-05-06 10:08:46 +00002438 return RTLFn;
2439}
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00002440
James Y Knight9871db02019-02-05 16:42:33 +00002441llvm::FunctionCallee
2442CGOpenMPRuntime::createForStaticInitFunction(unsigned IVSize, bool IVSigned) {
Alexander Musman21212e42015-03-13 10:38:23 +00002443 assert((IVSize == 32 || IVSize == 64) &&
2444 "IV size is not compatible with the omp runtime");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002445 StringRef Name = IVSize == 32 ? (IVSigned ? "__kmpc_for_static_init_4"
2446 : "__kmpc_for_static_init_4u")
2447 : (IVSigned ? "__kmpc_for_static_init_8"
2448 : "__kmpc_for_static_init_8u");
2449 llvm::Type *ITy = IVSize == 32 ? CGM.Int32Ty : CGM.Int64Ty;
2450 auto *PtrTy = llvm::PointerType::getUnqual(ITy);
Alexander Musman21212e42015-03-13 10:38:23 +00002451 llvm::Type *TypeParams[] = {
2452 getIdentTyPointerTy(), // loc
2453 CGM.Int32Ty, // tid
2454 CGM.Int32Ty, // schedtype
2455 llvm::PointerType::getUnqual(CGM.Int32Ty), // p_lastiter
2456 PtrTy, // p_lower
2457 PtrTy, // p_upper
2458 PtrTy, // p_stride
2459 ITy, // incr
2460 ITy // chunk
2461 };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002462 auto *FnTy =
Alexander Musman21212e42015-03-13 10:38:23 +00002463 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2464 return CGM.CreateRuntimeFunction(FnTy, Name);
2465}
2466
James Y Knight9871db02019-02-05 16:42:33 +00002467llvm::FunctionCallee
2468CGOpenMPRuntime::createDispatchInitFunction(unsigned IVSize, bool IVSigned) {
Alexander Musman92bdaab2015-03-12 13:37:50 +00002469 assert((IVSize == 32 || IVSize == 64) &&
2470 "IV size is not compatible with the omp runtime");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002471 StringRef Name =
Alexander Musman92bdaab2015-03-12 13:37:50 +00002472 IVSize == 32
2473 ? (IVSigned ? "__kmpc_dispatch_init_4" : "__kmpc_dispatch_init_4u")
2474 : (IVSigned ? "__kmpc_dispatch_init_8" : "__kmpc_dispatch_init_8u");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002475 llvm::Type *ITy = IVSize == 32 ? CGM.Int32Ty : CGM.Int64Ty;
Alexander Musman92bdaab2015-03-12 13:37:50 +00002476 llvm::Type *TypeParams[] = { getIdentTyPointerTy(), // loc
2477 CGM.Int32Ty, // tid
2478 CGM.Int32Ty, // schedtype
2479 ITy, // lower
2480 ITy, // upper
2481 ITy, // stride
2482 ITy // chunk
2483 };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002484 auto *FnTy =
Alexander Musman92bdaab2015-03-12 13:37:50 +00002485 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg*/ false);
2486 return CGM.CreateRuntimeFunction(FnTy, Name);
2487}
2488
James Y Knight9871db02019-02-05 16:42:33 +00002489llvm::FunctionCallee
2490CGOpenMPRuntime::createDispatchFiniFunction(unsigned IVSize, bool IVSigned) {
Alexey Bataev98eb6e32015-04-22 11:15:40 +00002491 assert((IVSize == 32 || IVSize == 64) &&
2492 "IV size is not compatible with the omp runtime");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002493 StringRef Name =
Alexey Bataev98eb6e32015-04-22 11:15:40 +00002494 IVSize == 32
2495 ? (IVSigned ? "__kmpc_dispatch_fini_4" : "__kmpc_dispatch_fini_4u")
2496 : (IVSigned ? "__kmpc_dispatch_fini_8" : "__kmpc_dispatch_fini_8u");
2497 llvm::Type *TypeParams[] = {
2498 getIdentTyPointerTy(), // loc
2499 CGM.Int32Ty, // tid
2500 };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002501 auto *FnTy =
Alexey Bataev98eb6e32015-04-22 11:15:40 +00002502 llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
2503 return CGM.CreateRuntimeFunction(FnTy, Name);
2504}
2505
James Y Knight9871db02019-02-05 16:42:33 +00002506llvm::FunctionCallee
2507CGOpenMPRuntime::createDispatchNextFunction(unsigned IVSize, bool IVSigned) {
Alexander Musman92bdaab2015-03-12 13:37:50 +00002508 assert((IVSize == 32 || IVSize == 64) &&
2509 "IV size is not compatible with the omp runtime");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002510 StringRef Name =
Alexander Musman92bdaab2015-03-12 13:37:50 +00002511 IVSize == 32
2512 ? (IVSigned ? "__kmpc_dispatch_next_4" : "__kmpc_dispatch_next_4u")
2513 : (IVSigned ? "__kmpc_dispatch_next_8" : "__kmpc_dispatch_next_8u");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002514 llvm::Type *ITy = IVSize == 32 ? CGM.Int32Ty : CGM.Int64Ty;
2515 auto *PtrTy = llvm::PointerType::getUnqual(ITy);
Alexander Musman92bdaab2015-03-12 13:37:50 +00002516 llvm::Type *TypeParams[] = {
2517 getIdentTyPointerTy(), // loc
2518 CGM.Int32Ty, // tid
2519 llvm::PointerType::getUnqual(CGM.Int32Ty), // p_lastiter
2520 PtrTy, // p_lower
2521 PtrTy, // p_upper
2522 PtrTy // p_stride
2523 };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002524 auto *FnTy =
Alexander Musman92bdaab2015-03-12 13:37:50 +00002525 llvm::FunctionType::get(CGM.Int32Ty, TypeParams, /*isVarArg*/ false);
2526 return CGM.CreateRuntimeFunction(FnTy, Name);
2527}
2528
Alexey Bataev03f270c2018-03-30 18:31:07 +00002529Address CGOpenMPRuntime::getAddrOfDeclareTargetLink(const VarDecl *VD) {
2530 if (CGM.getLangOpts().OpenMPSimd)
2531 return Address::invalid();
Alexey Bataev92327c52018-03-26 16:40:55 +00002532 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
Alexey Bataev97b72212018-08-14 18:31:20 +00002533 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
Alexey Bataev92327c52018-03-26 16:40:55 +00002534 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
2535 SmallString<64> PtrName;
2536 {
2537 llvm::raw_svector_ostream OS(PtrName);
2538 OS << CGM.getMangledName(GlobalDecl(VD)) << "_decl_tgt_link_ptr";
2539 }
2540 llvm::Value *Ptr = CGM.getModule().getNamedValue(PtrName);
2541 if (!Ptr) {
2542 QualType PtrTy = CGM.getContext().getPointerType(VD->getType());
2543 Ptr = getOrCreateInternalVariable(CGM.getTypes().ConvertTypeForMem(PtrTy),
2544 PtrName);
Alexey Bataev03f270c2018-03-30 18:31:07 +00002545 if (!CGM.getLangOpts().OpenMPIsDevice) {
2546 auto *GV = cast<llvm::GlobalVariable>(Ptr);
2547 GV->setLinkage(llvm::GlobalValue::ExternalLinkage);
2548 GV->setInitializer(CGM.GetAddrOfGlobal(VD));
2549 }
2550 CGM.addUsedGlobal(cast<llvm::GlobalValue>(Ptr));
2551 registerTargetGlobalVariable(VD, cast<llvm::Constant>(Ptr));
Alexey Bataev92327c52018-03-26 16:40:55 +00002552 }
2553 return Address(Ptr, CGM.getContext().getDeclAlign(VD));
2554 }
2555 return Address::invalid();
2556}
2557
Alexey Bataev97720002014-11-11 04:05:39 +00002558llvm::Constant *
2559CGOpenMPRuntime::getOrCreateThreadPrivateCache(const VarDecl *VD) {
Samuel Antaof8b50122015-07-13 22:54:53 +00002560 assert(!CGM.getLangOpts().OpenMPUseTLS ||
2561 !CGM.getContext().getTargetInfo().isTLSSupported());
Alexey Bataev97720002014-11-11 04:05:39 +00002562 // Lookup the entry, lazily creating it if necessary.
Alexey Bataev18fa2322018-05-02 14:20:50 +00002563 std::string Suffix = getName({"cache", ""});
2564 return getOrCreateInternalVariable(
2565 CGM.Int8PtrPtrTy, Twine(CGM.getMangledName(VD)).concat(Suffix));
Alexey Bataev97720002014-11-11 04:05:39 +00002566}
2567
John McCall7f416cc2015-09-08 08:05:57 +00002568Address CGOpenMPRuntime::getAddrOfThreadPrivate(CodeGenFunction &CGF,
2569 const VarDecl *VD,
2570 Address VDAddr,
2571 SourceLocation Loc) {
Samuel Antaof8b50122015-07-13 22:54:53 +00002572 if (CGM.getLangOpts().OpenMPUseTLS &&
2573 CGM.getContext().getTargetInfo().isTLSSupported())
2574 return VDAddr;
2575
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002576 llvm::Type *VarTy = VDAddr.getElementType();
Alexey Bataev3eff5f42015-02-25 08:32:46 +00002577 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
John McCall7f416cc2015-09-08 08:05:57 +00002578 CGF.Builder.CreatePointerCast(VDAddr.getPointer(),
2579 CGM.Int8PtrTy),
Alexey Bataev97720002014-11-11 04:05:39 +00002580 CGM.getSize(CGM.GetTargetTypeStoreSize(VarTy)),
2581 getOrCreateThreadPrivateCache(VD)};
John McCall7f416cc2015-09-08 08:05:57 +00002582 return Address(CGF.EmitRuntimeCall(
2583 createRuntimeFunction(OMPRTL__kmpc_threadprivate_cached), Args),
2584 VDAddr.getAlignment());
Alexey Bataev97720002014-11-11 04:05:39 +00002585}
2586
Alexey Bataev3eff5f42015-02-25 08:32:46 +00002587void CGOpenMPRuntime::emitThreadPrivateVarInit(
John McCall7f416cc2015-09-08 08:05:57 +00002588 CodeGenFunction &CGF, Address VDAddr, llvm::Value *Ctor,
Alexey Bataev97720002014-11-11 04:05:39 +00002589 llvm::Value *CopyCtor, llvm::Value *Dtor, SourceLocation Loc) {
2590 // Call kmp_int32 __kmpc_global_thread_num(&loc) to init OpenMP runtime
2591 // library.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002592 llvm::Value *OMPLoc = emitUpdateLocation(CGF, Loc);
Alexey Bataev3eff5f42015-02-25 08:32:46 +00002593 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_global_thread_num),
Alexey Bataev97720002014-11-11 04:05:39 +00002594 OMPLoc);
2595 // Call __kmpc_threadprivate_register(&loc, &var, ctor, cctor/*NULL*/, dtor)
2596 // to register constructor/destructor for variable.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002597 llvm::Value *Args[] = {
2598 OMPLoc, CGF.Builder.CreatePointerCast(VDAddr.getPointer(), CGM.VoidPtrTy),
2599 Ctor, CopyCtor, Dtor};
Alexey Bataev1e4b7132014-12-03 12:11:24 +00002600 CGF.EmitRuntimeCall(
Alexey Bataev3eff5f42015-02-25 08:32:46 +00002601 createRuntimeFunction(OMPRTL__kmpc_threadprivate_register), Args);
Alexey Bataev97720002014-11-11 04:05:39 +00002602}
2603
Alexey Bataev3eff5f42015-02-25 08:32:46 +00002604llvm::Function *CGOpenMPRuntime::emitThreadPrivateVarDefinition(
John McCall7f416cc2015-09-08 08:05:57 +00002605 const VarDecl *VD, Address VDAddr, SourceLocation Loc,
Alexey Bataev97720002014-11-11 04:05:39 +00002606 bool PerformInit, CodeGenFunction *CGF) {
Samuel Antaof8b50122015-07-13 22:54:53 +00002607 if (CGM.getLangOpts().OpenMPUseTLS &&
2608 CGM.getContext().getTargetInfo().isTLSSupported())
2609 return nullptr;
2610
Alexey Bataev97720002014-11-11 04:05:39 +00002611 VD = VD->getDefinition(CGM.getContext());
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00002612 if (VD && ThreadPrivateWithDefinition.insert(CGM.getMangledName(VD)).second) {
Alexey Bataev97720002014-11-11 04:05:39 +00002613 QualType ASTTy = VD->getType();
2614
2615 llvm::Value *Ctor = nullptr, *CopyCtor = nullptr, *Dtor = nullptr;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002616 const Expr *Init = VD->getAnyInitializer();
Alexey Bataev97720002014-11-11 04:05:39 +00002617 if (CGM.getLangOpts().CPlusPlus && PerformInit) {
2618 // Generate function that re-emits the declaration's initializer into the
2619 // threadprivate copy of the variable VD
2620 CodeGenFunction CtorCGF(CGM);
2621 FunctionArgList Args;
Alexey Bataev7cae94e2018-01-04 19:45:16 +00002622 ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr, Loc,
2623 /*Id=*/nullptr, CGM.getContext().VoidPtrTy,
Alexey Bataev56223232017-06-09 13:40:18 +00002624 ImplicitParamDecl::Other);
Alexey Bataev97720002014-11-11 04:05:39 +00002625 Args.push_back(&Dst);
2626
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002627 const auto &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
John McCallc56a8b32016-03-11 04:30:31 +00002628 CGM.getContext().VoidPtrTy, Args);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002629 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
Alexey Bataev18fa2322018-05-02 14:20:50 +00002630 std::string Name = getName({"__kmpc_global_ctor_", ""});
2631 llvm::Function *Fn =
2632 CGM.CreateGlobalInitOrDestructFunction(FTy, Name, FI, Loc);
Alexey Bataev97720002014-11-11 04:05:39 +00002633 CtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidPtrTy, Fn, FI,
Alexey Bataev7cae94e2018-01-04 19:45:16 +00002634 Args, Loc, Loc);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002635 llvm::Value *ArgVal = CtorCGF.EmitLoadOfScalar(
John McCall7f416cc2015-09-08 08:05:57 +00002636 CtorCGF.GetAddrOfLocalVar(&Dst), /*Volatile=*/false,
Alexey Bataev97720002014-11-11 04:05:39 +00002637 CGM.getContext().VoidPtrTy, Dst.getLocation());
John McCall7f416cc2015-09-08 08:05:57 +00002638 Address Arg = Address(ArgVal, VDAddr.getAlignment());
Alexey Bataev7cae94e2018-01-04 19:45:16 +00002639 Arg = CtorCGF.Builder.CreateElementBitCast(
2640 Arg, CtorCGF.ConvertTypeForMem(ASTTy));
Alexey Bataev97720002014-11-11 04:05:39 +00002641 CtorCGF.EmitAnyExprToMem(Init, Arg, Init->getType().getQualifiers(),
2642 /*IsInitializer=*/true);
2643 ArgVal = CtorCGF.EmitLoadOfScalar(
John McCall7f416cc2015-09-08 08:05:57 +00002644 CtorCGF.GetAddrOfLocalVar(&Dst), /*Volatile=*/false,
Alexey Bataev97720002014-11-11 04:05:39 +00002645 CGM.getContext().VoidPtrTy, Dst.getLocation());
2646 CtorCGF.Builder.CreateStore(ArgVal, CtorCGF.ReturnValue);
2647 CtorCGF.FinishFunction();
2648 Ctor = Fn;
2649 }
2650 if (VD->getType().isDestructedType() != QualType::DK_none) {
2651 // Generate function that emits destructor call for the threadprivate copy
2652 // of the variable VD
2653 CodeGenFunction DtorCGF(CGM);
2654 FunctionArgList Args;
Alexey Bataev7cae94e2018-01-04 19:45:16 +00002655 ImplicitParamDecl Dst(CGM.getContext(), /*DC=*/nullptr, Loc,
2656 /*Id=*/nullptr, CGM.getContext().VoidPtrTy,
Alexey Bataev56223232017-06-09 13:40:18 +00002657 ImplicitParamDecl::Other);
Alexey Bataev97720002014-11-11 04:05:39 +00002658 Args.push_back(&Dst);
2659
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002660 const auto &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
John McCallc56a8b32016-03-11 04:30:31 +00002661 CGM.getContext().VoidTy, Args);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002662 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
Alexey Bataev18fa2322018-05-02 14:20:50 +00002663 std::string Name = getName({"__kmpc_global_dtor_", ""});
2664 llvm::Function *Fn =
2665 CGM.CreateGlobalInitOrDestructFunction(FTy, Name, FI, Loc);
Adrian Prantl1858c662016-04-24 22:22:29 +00002666 auto NL = ApplyDebugLocation::CreateEmpty(DtorCGF);
Alexey Bataev97720002014-11-11 04:05:39 +00002667 DtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, Fn, FI, Args,
Alexey Bataev7cae94e2018-01-04 19:45:16 +00002668 Loc, Loc);
Adrian Prantl1858c662016-04-24 22:22:29 +00002669 // Create a scope with an artificial location for the body of this function.
2670 auto AL = ApplyDebugLocation::CreateArtificial(DtorCGF);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002671 llvm::Value *ArgVal = DtorCGF.EmitLoadOfScalar(
Alexey Bataev97720002014-11-11 04:05:39 +00002672 DtorCGF.GetAddrOfLocalVar(&Dst),
John McCall7f416cc2015-09-08 08:05:57 +00002673 /*Volatile=*/false, CGM.getContext().VoidPtrTy, Dst.getLocation());
2674 DtorCGF.emitDestroy(Address(ArgVal, VDAddr.getAlignment()), ASTTy,
Alexey Bataev97720002014-11-11 04:05:39 +00002675 DtorCGF.getDestroyer(ASTTy.isDestructedType()),
2676 DtorCGF.needsEHCleanup(ASTTy.isDestructedType()));
2677 DtorCGF.FinishFunction();
2678 Dtor = Fn;
2679 }
2680 // Do not emit init function if it is not required.
2681 if (!Ctor && !Dtor)
2682 return nullptr;
2683
2684 llvm::Type *CopyCtorTyArgs[] = {CGM.VoidPtrTy, CGM.VoidPtrTy};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002685 auto *CopyCtorTy = llvm::FunctionType::get(CGM.VoidPtrTy, CopyCtorTyArgs,
2686 /*isVarArg=*/false)
2687 ->getPointerTo();
Alexey Bataev97720002014-11-11 04:05:39 +00002688 // Copying constructor for the threadprivate variable.
2689 // Must be NULL - reserved by runtime, but currently it requires that this
2690 // parameter is always NULL. Otherwise it fires assertion.
2691 CopyCtor = llvm::Constant::getNullValue(CopyCtorTy);
2692 if (Ctor == nullptr) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002693 auto *CtorTy = llvm::FunctionType::get(CGM.VoidPtrTy, CGM.VoidPtrTy,
2694 /*isVarArg=*/false)
2695 ->getPointerTo();
Alexey Bataev97720002014-11-11 04:05:39 +00002696 Ctor = llvm::Constant::getNullValue(CtorTy);
2697 }
2698 if (Dtor == nullptr) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002699 auto *DtorTy = llvm::FunctionType::get(CGM.VoidTy, CGM.VoidPtrTy,
2700 /*isVarArg=*/false)
2701 ->getPointerTo();
Alexey Bataev97720002014-11-11 04:05:39 +00002702 Dtor = llvm::Constant::getNullValue(DtorTy);
2703 }
2704 if (!CGF) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002705 auto *InitFunctionTy =
Alexey Bataev97720002014-11-11 04:05:39 +00002706 llvm::FunctionType::get(CGM.VoidTy, /*isVarArg*/ false);
Alexey Bataev18fa2322018-05-02 14:20:50 +00002707 std::string Name = getName({"__omp_threadprivate_init_", ""});
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002708 llvm::Function *InitFunction = CGM.CreateGlobalInitOrDestructFunction(
Alexey Bataev18fa2322018-05-02 14:20:50 +00002709 InitFunctionTy, Name, CGM.getTypes().arrangeNullaryFunction());
Alexey Bataev97720002014-11-11 04:05:39 +00002710 CodeGenFunction InitCGF(CGM);
2711 FunctionArgList ArgList;
2712 InitCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, InitFunction,
2713 CGM.getTypes().arrangeNullaryFunction(), ArgList,
Alexey Bataev7cae94e2018-01-04 19:45:16 +00002714 Loc, Loc);
Alexey Bataev3eff5f42015-02-25 08:32:46 +00002715 emitThreadPrivateVarInit(InitCGF, VDAddr, Ctor, CopyCtor, Dtor, Loc);
Alexey Bataev97720002014-11-11 04:05:39 +00002716 InitCGF.FinishFunction();
2717 return InitFunction;
2718 }
Alexey Bataev3eff5f42015-02-25 08:32:46 +00002719 emitThreadPrivateVarInit(*CGF, VDAddr, Ctor, CopyCtor, Dtor, Loc);
Alexey Bataev97720002014-11-11 04:05:39 +00002720 }
2721 return nullptr;
2722}
2723
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002724/// Obtain information that uniquely identifies a target entry. This
Alexey Bataev34f8a702018-03-28 14:28:54 +00002725/// consists of the file and device IDs as well as line number associated with
2726/// the relevant entry source location.
2727static void getTargetEntryUniqueInfo(ASTContext &C, SourceLocation Loc,
2728 unsigned &DeviceID, unsigned &FileID,
2729 unsigned &LineNum) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002730 SourceManager &SM = C.getSourceManager();
Alexey Bataev34f8a702018-03-28 14:28:54 +00002731
2732 // The loc should be always valid and have a file ID (the user cannot use
2733 // #pragma directives in macros)
2734
2735 assert(Loc.isValid() && "Source location is expected to be always valid.");
Alexey Bataev34f8a702018-03-28 14:28:54 +00002736
2737 PresumedLoc PLoc = SM.getPresumedLoc(Loc);
2738 assert(PLoc.isValid() && "Source location is expected to be always valid.");
2739
2740 llvm::sys::fs::UniqueID ID;
Alexey Bataev64e62dc2018-04-30 16:26:57 +00002741 if (auto EC = llvm::sys::fs::getUniqueID(PLoc.getFilename(), ID))
2742 SM.getDiagnostics().Report(diag::err_cannot_open_file)
2743 << PLoc.getFilename() << EC.message();
Alexey Bataev34f8a702018-03-28 14:28:54 +00002744
2745 DeviceID = ID.getDevice();
2746 FileID = ID.getFile();
2747 LineNum = PLoc.getLine();
2748}
2749
2750bool CGOpenMPRuntime::emitDeclareTargetVarDefinition(const VarDecl *VD,
2751 llvm::GlobalVariable *Addr,
2752 bool PerformInit) {
2753 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
Alexey Bataev97b72212018-08-14 18:31:20 +00002754 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
Alexey Bataev34f8a702018-03-28 14:28:54 +00002755 if (!Res || *Res == OMPDeclareTargetDeclAttr::MT_Link)
Alexey Bataevd01b7492018-08-15 19:45:12 +00002756 return CGM.getLangOpts().OpenMPIsDevice;
Alexey Bataev34f8a702018-03-28 14:28:54 +00002757 VD = VD->getDefinition(CGM.getContext());
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00002758 if (VD && !DeclareTargetWithDefinition.insert(CGM.getMangledName(VD)).second)
Alexey Bataev34f8a702018-03-28 14:28:54 +00002759 return CGM.getLangOpts().OpenMPIsDevice;
2760
2761 QualType ASTTy = VD->getType();
2762
Stephen Kellyf2ceec42018-08-09 21:08:08 +00002763 SourceLocation Loc = VD->getCanonicalDecl()->getBeginLoc();
Alexey Bataev34f8a702018-03-28 14:28:54 +00002764 // Produce the unique prefix to identify the new target regions. We use
2765 // the source location of the variable declaration which we know to not
2766 // conflict with any target region.
2767 unsigned DeviceID;
2768 unsigned FileID;
2769 unsigned Line;
2770 getTargetEntryUniqueInfo(CGM.getContext(), Loc, DeviceID, FileID, Line);
2771 SmallString<128> Buffer, Out;
2772 {
2773 llvm::raw_svector_ostream OS(Buffer);
2774 OS << "__omp_offloading_" << llvm::format("_%x", DeviceID)
2775 << llvm::format("_%x_", FileID) << VD->getName() << "_l" << Line;
2776 }
2777
2778 const Expr *Init = VD->getAnyInitializer();
2779 if (CGM.getLangOpts().CPlusPlus && PerformInit) {
2780 llvm::Constant *Ctor;
2781 llvm::Constant *ID;
2782 if (CGM.getLangOpts().OpenMPIsDevice) {
2783 // Generate function that re-emits the declaration's initializer into
2784 // the threadprivate copy of the variable VD
2785 CodeGenFunction CtorCGF(CGM);
2786
2787 const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();
2788 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
2789 llvm::Function *Fn = CGM.CreateGlobalInitOrDestructFunction(
2790 FTy, Twine(Buffer, "_ctor"), FI, Loc);
2791 auto NL = ApplyDebugLocation::CreateEmpty(CtorCGF);
2792 CtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, Fn, FI,
2793 FunctionArgList(), Loc, Loc);
2794 auto AL = ApplyDebugLocation::CreateArtificial(CtorCGF);
2795 CtorCGF.EmitAnyExprToMem(Init,
2796 Address(Addr, CGM.getContext().getDeclAlign(VD)),
2797 Init->getType().getQualifiers(),
2798 /*IsInitializer=*/true);
2799 CtorCGF.FinishFunction();
2800 Ctor = Fn;
2801 ID = llvm::ConstantExpr::getBitCast(Fn, CGM.Int8PtrTy);
Alexey Bataeve253f2f2018-05-09 14:15:18 +00002802 CGM.addUsedGlobal(cast<llvm::GlobalValue>(Ctor));
Alexey Bataev34f8a702018-03-28 14:28:54 +00002803 } else {
2804 Ctor = new llvm::GlobalVariable(
2805 CGM.getModule(), CGM.Int8Ty, /*isConstant=*/true,
2806 llvm::GlobalValue::PrivateLinkage,
2807 llvm::Constant::getNullValue(CGM.Int8Ty), Twine(Buffer, "_ctor"));
2808 ID = Ctor;
2809 }
2810
2811 // Register the information for the entry associated with the constructor.
2812 Out.clear();
2813 OffloadEntriesInfoManager.registerTargetRegionEntryInfo(
2814 DeviceID, FileID, Twine(Buffer, "_ctor").toStringRef(Out), Line, Ctor,
Alexey Bataev03f270c2018-03-30 18:31:07 +00002815 ID, OffloadEntriesInfoManagerTy::OMPTargetRegionEntryCtor);
Alexey Bataev34f8a702018-03-28 14:28:54 +00002816 }
2817 if (VD->getType().isDestructedType() != QualType::DK_none) {
2818 llvm::Constant *Dtor;
2819 llvm::Constant *ID;
2820 if (CGM.getLangOpts().OpenMPIsDevice) {
2821 // Generate function that emits destructor call for the threadprivate
2822 // copy of the variable VD
2823 CodeGenFunction DtorCGF(CGM);
2824
2825 const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();
2826 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
2827 llvm::Function *Fn = CGM.CreateGlobalInitOrDestructFunction(
2828 FTy, Twine(Buffer, "_dtor"), FI, Loc);
2829 auto NL = ApplyDebugLocation::CreateEmpty(DtorCGF);
2830 DtorCGF.StartFunction(GlobalDecl(), CGM.getContext().VoidTy, Fn, FI,
2831 FunctionArgList(), Loc, Loc);
2832 // Create a scope with an artificial location for the body of this
2833 // function.
2834 auto AL = ApplyDebugLocation::CreateArtificial(DtorCGF);
2835 DtorCGF.emitDestroy(Address(Addr, CGM.getContext().getDeclAlign(VD)),
2836 ASTTy, DtorCGF.getDestroyer(ASTTy.isDestructedType()),
2837 DtorCGF.needsEHCleanup(ASTTy.isDestructedType()));
2838 DtorCGF.FinishFunction();
2839 Dtor = Fn;
2840 ID = llvm::ConstantExpr::getBitCast(Fn, CGM.Int8PtrTy);
Alexey Bataeve253f2f2018-05-09 14:15:18 +00002841 CGM.addUsedGlobal(cast<llvm::GlobalValue>(Dtor));
Alexey Bataev34f8a702018-03-28 14:28:54 +00002842 } else {
2843 Dtor = new llvm::GlobalVariable(
2844 CGM.getModule(), CGM.Int8Ty, /*isConstant=*/true,
2845 llvm::GlobalValue::PrivateLinkage,
2846 llvm::Constant::getNullValue(CGM.Int8Ty), Twine(Buffer, "_dtor"));
2847 ID = Dtor;
2848 }
2849 // Register the information for the entry associated with the destructor.
2850 Out.clear();
2851 OffloadEntriesInfoManager.registerTargetRegionEntryInfo(
2852 DeviceID, FileID, Twine(Buffer, "_dtor").toStringRef(Out), Line, Dtor,
Alexey Bataev03f270c2018-03-30 18:31:07 +00002853 ID, OffloadEntriesInfoManagerTy::OMPTargetRegionEntryDtor);
Alexey Bataev34f8a702018-03-28 14:28:54 +00002854 }
2855 return CGM.getLangOpts().OpenMPIsDevice;
2856}
2857
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00002858Address CGOpenMPRuntime::getAddrOfArtificialThreadPrivate(CodeGenFunction &CGF,
2859 QualType VarType,
2860 StringRef Name) {
Alexey Bataev18fa2322018-05-02 14:20:50 +00002861 std::string Suffix = getName({"artificial", ""});
2862 std::string CacheSuffix = getName({"cache", ""});
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00002863 llvm::Type *VarLVType = CGF.ConvertTypeForMem(VarType);
Alexey Bataev18fa2322018-05-02 14:20:50 +00002864 llvm::Value *GAddr =
2865 getOrCreateInternalVariable(VarLVType, Twine(Name).concat(Suffix));
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00002866 llvm::Value *Args[] = {
2867 emitUpdateLocation(CGF, SourceLocation()),
2868 getThreadID(CGF, SourceLocation()),
2869 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(GAddr, CGM.VoidPtrTy),
2870 CGF.Builder.CreateIntCast(CGF.getTypeSize(VarType), CGM.SizeTy,
2871 /*IsSigned=*/false),
Alexey Bataev18fa2322018-05-02 14:20:50 +00002872 getOrCreateInternalVariable(
2873 CGM.VoidPtrPtrTy, Twine(Name).concat(Suffix).concat(CacheSuffix))};
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00002874 return Address(
2875 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
2876 CGF.EmitRuntimeCall(
2877 createRuntimeFunction(OMPRTL__kmpc_threadprivate_cached), Args),
2878 VarLVType->getPointerTo(/*AddrSpace=*/0)),
2879 CGM.getPointerAlign());
2880}
2881
Arpith Chacko Jacobbb36fe82017-01-10 15:42:51 +00002882void CGOpenMPRuntime::emitOMPIfClause(CodeGenFunction &CGF, const Expr *Cond,
2883 const RegionCodeGenTy &ThenGen,
2884 const RegionCodeGenTy &ElseGen) {
Alexey Bataev1d677132015-04-22 13:57:31 +00002885 CodeGenFunction::LexicalScope ConditionScope(CGF, Cond->getSourceRange());
2886
2887 // If the condition constant folds and can be elided, try to avoid emitting
2888 // the condition and the dead arm of the if/else.
2889 bool CondConstant;
2890 if (CGF.ConstantFoldsToSimpleInteger(Cond, CondConstant)) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002891 if (CondConstant)
Alexey Bataev1d677132015-04-22 13:57:31 +00002892 ThenGen(CGF);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002893 else
Alexey Bataev1d677132015-04-22 13:57:31 +00002894 ElseGen(CGF);
Alexey Bataev1d677132015-04-22 13:57:31 +00002895 return;
2896 }
2897
2898 // Otherwise, the condition did not fold, or we couldn't elide it. Just
2899 // emit the conditional branch.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002900 llvm::BasicBlock *ThenBlock = CGF.createBasicBlock("omp_if.then");
2901 llvm::BasicBlock *ElseBlock = CGF.createBasicBlock("omp_if.else");
2902 llvm::BasicBlock *ContBlock = CGF.createBasicBlock("omp_if.end");
Alexey Bataev1d677132015-04-22 13:57:31 +00002903 CGF.EmitBranchOnBoolExpr(Cond, ThenBlock, ElseBlock, /*TrueCount=*/0);
2904
2905 // Emit the 'then' code.
2906 CGF.EmitBlock(ThenBlock);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002907 ThenGen(CGF);
Alexey Bataev1d677132015-04-22 13:57:31 +00002908 CGF.EmitBranch(ContBlock);
2909 // Emit the 'else' code if present.
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002910 // There is no need to emit line number for unconditional branch.
2911 (void)ApplyDebugLocation::CreateEmpty(CGF);
2912 CGF.EmitBlock(ElseBlock);
2913 ElseGen(CGF);
2914 // There is no need to emit line number for unconditional branch.
2915 (void)ApplyDebugLocation::CreateEmpty(CGF);
2916 CGF.EmitBranch(ContBlock);
Alexey Bataev1d677132015-04-22 13:57:31 +00002917 // Emit the continuation block for code after the if.
2918 CGF.EmitBlock(ContBlock, /*IsFinished=*/true);
Alexey Bataev4a5bb772014-10-08 14:01:46 +00002919}
2920
Alexey Bataev1d677132015-04-22 13:57:31 +00002921void CGOpenMPRuntime::emitParallelCall(CodeGenFunction &CGF, SourceLocation Loc,
James Y Knight9871db02019-02-05 16:42:33 +00002922 llvm::Function *OutlinedFn,
Alexey Bataev2377fe92015-09-10 08:12:02 +00002923 ArrayRef<llvm::Value *> CapturedVars,
Alexey Bataev1d677132015-04-22 13:57:31 +00002924 const Expr *IfCond) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00002925 if (!CGF.HaveInsertPoint())
2926 return;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002927 llvm::Value *RTLoc = emitUpdateLocation(CGF, Loc);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002928 auto &&ThenGen = [OutlinedFn, CapturedVars, RTLoc](CodeGenFunction &CGF,
2929 PrePostActionTy &) {
Alexey Bataev2377fe92015-09-10 08:12:02 +00002930 // Build call __kmpc_fork_call(loc, n, microtask, var1, .., varn);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002931 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
Alexey Bataev2377fe92015-09-10 08:12:02 +00002932 llvm::Value *Args[] = {
2933 RTLoc,
2934 CGF.Builder.getInt32(CapturedVars.size()), // Number of captured vars
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002935 CGF.Builder.CreateBitCast(OutlinedFn, RT.getKmpc_MicroPointerTy())};
Alexey Bataev2377fe92015-09-10 08:12:02 +00002936 llvm::SmallVector<llvm::Value *, 16> RealArgs;
2937 RealArgs.append(std::begin(Args), std::end(Args));
2938 RealArgs.append(CapturedVars.begin(), CapturedVars.end());
2939
James Y Knight9871db02019-02-05 16:42:33 +00002940 llvm::FunctionCallee RTLFn =
2941 RT.createRuntimeFunction(OMPRTL__kmpc_fork_call);
Alexey Bataev2377fe92015-09-10 08:12:02 +00002942 CGF.EmitRuntimeCall(RTLFn, RealArgs);
2943 };
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002944 auto &&ElseGen = [OutlinedFn, CapturedVars, RTLoc, Loc](CodeGenFunction &CGF,
2945 PrePostActionTy &) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002946 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
2947 llvm::Value *ThreadID = RT.getThreadID(CGF, Loc);
Alexey Bataev1d677132015-04-22 13:57:31 +00002948 // Build calls:
2949 // __kmpc_serialized_parallel(&Loc, GTid);
2950 llvm::Value *Args[] = {RTLoc, ThreadID};
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002951 CGF.EmitRuntimeCall(
2952 RT.createRuntimeFunction(OMPRTL__kmpc_serialized_parallel), Args);
Alexey Bataevd74d0602014-10-13 06:02:40 +00002953
Alexey Bataev1d677132015-04-22 13:57:31 +00002954 // OutlinedFn(&GTid, &zero, CapturedStruct);
Alexey Bataev18fa2322018-05-02 14:20:50 +00002955 Address ZeroAddr = CGF.CreateDefaultAlignTempAlloca(CGF.Int32Ty,
2956 /*Name*/ ".zero.addr");
Alexey Bataev1d677132015-04-22 13:57:31 +00002957 CGF.InitTempAlloca(ZeroAddr, CGF.Builder.getInt32(/*C*/ 0));
Alexey Bataev2377fe92015-09-10 08:12:02 +00002958 llvm::SmallVector<llvm::Value *, 16> OutlinedFnArgs;
Alexey Bataev8521ff62018-07-25 20:03:01 +00002959 // ThreadId for serialized parallels is 0.
2960 OutlinedFnArgs.push_back(ZeroAddr.getPointer());
Alexey Bataev2377fe92015-09-10 08:12:02 +00002961 OutlinedFnArgs.push_back(ZeroAddr.getPointer());
2962 OutlinedFnArgs.append(CapturedVars.begin(), CapturedVars.end());
Alexey Bataev3c595a62017-08-14 15:01:03 +00002963 RT.emitOutlinedFunctionCall(CGF, Loc, OutlinedFn, OutlinedFnArgs);
Alexey Bataevd74d0602014-10-13 06:02:40 +00002964
Alexey Bataev1d677132015-04-22 13:57:31 +00002965 // __kmpc_end_serialized_parallel(&Loc, GTid);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002966 llvm::Value *EndArgs[] = {RT.emitUpdateLocation(CGF, Loc), ThreadID};
Alexey Bataev1d677132015-04-22 13:57:31 +00002967 CGF.EmitRuntimeCall(
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002968 RT.createRuntimeFunction(OMPRTL__kmpc_end_serialized_parallel),
2969 EndArgs);
Alexey Bataev1d677132015-04-22 13:57:31 +00002970 };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002971 if (IfCond) {
Alexey Bataev1d677132015-04-22 13:57:31 +00002972 emitOMPIfClause(CGF, IfCond, ThenGen, ElseGen);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002973 } else {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00002974 RegionCodeGenTy ThenRCG(ThenGen);
2975 ThenRCG(CGF);
Alexey Bataevf539faa2016-03-28 12:58:34 +00002976 }
Alexey Bataevd74d0602014-10-13 06:02:40 +00002977}
2978
NAKAMURA Takumi59c74b222014-10-27 08:08:18 +00002979// If we're inside an (outlined) parallel region, use the region info's
Alexey Bataevd74d0602014-10-13 06:02:40 +00002980// thread-ID variable (it is passed in a first argument of the outlined function
2981// as "kmp_int32 *gtid"). Otherwise, if we're not inside parallel region, but in
2982// regular serial code region, get thread ID by calling kmp_int32
2983// kmpc_global_thread_num(ident_t *loc), stash this thread ID in a temporary and
2984// return the address of that temp.
John McCall7f416cc2015-09-08 08:05:57 +00002985Address CGOpenMPRuntime::emitThreadIDAddress(CodeGenFunction &CGF,
2986 SourceLocation Loc) {
Alexey Bataev3015bcc2016-01-22 08:56:50 +00002987 if (auto *OMPRegionInfo =
Alexey Bataevd74d0602014-10-13 06:02:40 +00002988 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
Alexey Bataev8cbe0a62015-02-26 10:27:34 +00002989 if (OMPRegionInfo->getThreadIDVariable())
Alexey Bataev62b63b12015-03-10 07:28:44 +00002990 return OMPRegionInfo->getThreadIDVariableLValue(CGF).getAddress();
Alexey Bataev8cbe0a62015-02-26 10:27:34 +00002991
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002992 llvm::Value *ThreadID = getThreadID(CGF, Loc);
2993 QualType Int32Ty =
Alexey Bataevd74d0602014-10-13 06:02:40 +00002994 CGF.getContext().getIntTypeForBitwidth(/*DestWidth*/ 32, /*Signed*/ true);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00002995 Address ThreadIDTemp = CGF.CreateMemTemp(Int32Ty, /*Name*/ ".threadid_temp.");
Alexey Bataevd74d0602014-10-13 06:02:40 +00002996 CGF.EmitStoreOfScalar(ThreadID,
John McCall7f416cc2015-09-08 08:05:57 +00002997 CGF.MakeAddrLValue(ThreadIDTemp, Int32Ty));
Alexey Bataevd74d0602014-10-13 06:02:40 +00002998
2999 return ThreadIDTemp;
3000}
3001
Alexey Bataev1af5bd52019-03-05 17:47:18 +00003002llvm::Constant *CGOpenMPRuntime::getOrCreateInternalVariable(
3003 llvm::Type *Ty, const llvm::Twine &Name, unsigned AddressSpace) {
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00003004 SmallString<256> Buffer;
3005 llvm::raw_svector_ostream Out(Buffer);
Alexey Bataev97720002014-11-11 04:05:39 +00003006 Out << Name;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003007 StringRef RuntimeName = Out.str();
Alexey Bataev43a919f2018-04-13 17:48:43 +00003008 auto &Elem = *InternalVars.try_emplace(RuntimeName, nullptr).first;
David Blaikie13156b62014-11-19 03:06:06 +00003009 if (Elem.second) {
3010 assert(Elem.second->getType()->getPointerElementType() == Ty &&
Alexey Bataev97720002014-11-11 04:05:39 +00003011 "OMP internal variable has different type than requested");
David Blaikie13156b62014-11-19 03:06:06 +00003012 return &*Elem.second;
Alexey Bataev97720002014-11-11 04:05:39 +00003013 }
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00003014
David Blaikie13156b62014-11-19 03:06:06 +00003015 return Elem.second = new llvm::GlobalVariable(
3016 CGM.getModule(), Ty, /*IsConstant*/ false,
3017 llvm::GlobalValue::CommonLinkage, llvm::Constant::getNullValue(Ty),
Alexey Bataev1af5bd52019-03-05 17:47:18 +00003018 Elem.first(), /*InsertBefore=*/nullptr,
3019 llvm::GlobalValue::NotThreadLocal, AddressSpace);
Alexey Bataev97720002014-11-11 04:05:39 +00003020}
3021
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003022llvm::Value *CGOpenMPRuntime::getCriticalRegionLock(StringRef CriticalName) {
Alexey Bataev18fa2322018-05-02 14:20:50 +00003023 std::string Prefix = Twine("gomp_critical_user_", CriticalName).str();
3024 std::string Name = getName({Prefix, "var"});
3025 return getOrCreateInternalVariable(KmpCriticalNameTy, Name);
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00003026}
3027
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00003028namespace {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003029/// Common pre(post)-action for different OpenMP constructs.
3030class CommonActionTy final : public PrePostActionTy {
James Y Knight9871db02019-02-05 16:42:33 +00003031 llvm::FunctionCallee EnterCallee;
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003032 ArrayRef<llvm::Value *> EnterArgs;
James Y Knight9871db02019-02-05 16:42:33 +00003033 llvm::FunctionCallee ExitCallee;
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003034 ArrayRef<llvm::Value *> ExitArgs;
3035 bool Conditional;
3036 llvm::BasicBlock *ContBlock = nullptr;
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00003037
3038public:
James Y Knight9871db02019-02-05 16:42:33 +00003039 CommonActionTy(llvm::FunctionCallee EnterCallee,
3040 ArrayRef<llvm::Value *> EnterArgs,
3041 llvm::FunctionCallee ExitCallee,
3042 ArrayRef<llvm::Value *> ExitArgs, bool Conditional = false)
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003043 : EnterCallee(EnterCallee), EnterArgs(EnterArgs), ExitCallee(ExitCallee),
3044 ExitArgs(ExitArgs), Conditional(Conditional) {}
3045 void Enter(CodeGenFunction &CGF) override {
3046 llvm::Value *EnterRes = CGF.EmitRuntimeCall(EnterCallee, EnterArgs);
3047 if (Conditional) {
3048 llvm::Value *CallBool = CGF.Builder.CreateIsNotNull(EnterRes);
3049 auto *ThenBlock = CGF.createBasicBlock("omp_if.then");
3050 ContBlock = CGF.createBasicBlock("omp_if.end");
3051 // Generate the branch (If-stmt)
3052 CGF.Builder.CreateCondBr(CallBool, ThenBlock, ContBlock);
3053 CGF.EmitBlock(ThenBlock);
3054 }
Alexey Bataeva744ff52015-05-05 09:24:37 +00003055 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003056 void Done(CodeGenFunction &CGF) {
3057 // Emit the rest of blocks/branches
3058 CGF.EmitBranch(ContBlock);
3059 CGF.EmitBlock(ContBlock, true);
3060 }
3061 void Exit(CodeGenFunction &CGF) override {
3062 CGF.EmitRuntimeCall(ExitCallee, ExitArgs);
Alexey Bataev3e6124b2015-04-10 07:48:12 +00003063 }
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00003064};
Hans Wennborg7eb54642015-09-10 17:07:54 +00003065} // anonymous namespace
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00003066
3067void CGOpenMPRuntime::emitCriticalRegion(CodeGenFunction &CGF,
3068 StringRef CriticalName,
3069 const RegionCodeGenTy &CriticalOpGen,
Alexey Bataevfc57d162015-12-15 10:55:09 +00003070 SourceLocation Loc, const Expr *Hint) {
3071 // __kmpc_critical[_with_hint](ident_t *, gtid, Lock[, hint]);
Alexey Bataev75ddfab2014-12-01 11:32:38 +00003072 // CriticalOpGen();
3073 // __kmpc_end_critical(ident_t *, gtid, Lock);
3074 // Prepare arguments and build a call to __kmpc_critical
Alexey Bataev8ef31412015-12-18 07:58:25 +00003075 if (!CGF.HaveInsertPoint())
3076 return;
Alexey Bataevfc57d162015-12-15 10:55:09 +00003077 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
3078 getCriticalRegionLock(CriticalName)};
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003079 llvm::SmallVector<llvm::Value *, 4> EnterArgs(std::begin(Args),
3080 std::end(Args));
Alexey Bataevfc57d162015-12-15 10:55:09 +00003081 if (Hint) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003082 EnterArgs.push_back(CGF.Builder.CreateIntCast(
3083 CGF.EmitScalarExpr(Hint), CGM.IntPtrTy, /*isSigned=*/false));
3084 }
3085 CommonActionTy Action(
3086 createRuntimeFunction(Hint ? OMPRTL__kmpc_critical_with_hint
3087 : OMPRTL__kmpc_critical),
3088 EnterArgs, createRuntimeFunction(OMPRTL__kmpc_end_critical), Args);
3089 CriticalOpGen.setAction(Action);
Alexey Bataevfc57d162015-12-15 10:55:09 +00003090 emitInlinedDirective(CGF, OMPD_critical, CriticalOpGen);
Alexey Bataev3a3bf0b2014-09-22 10:01:53 +00003091}
Alexey Bataev4a5bb772014-10-08 14:01:46 +00003092
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003093void CGOpenMPRuntime::emitMasterRegion(CodeGenFunction &CGF,
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00003094 const RegionCodeGenTy &MasterOpGen,
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003095 SourceLocation Loc) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003096 if (!CGF.HaveInsertPoint())
3097 return;
Alexey Bataev8d690652014-12-04 07:23:53 +00003098 // if(__kmpc_master(ident_t *, gtid)) {
3099 // MasterOpGen();
3100 // __kmpc_end_master(ident_t *, gtid);
3101 // }
3102 // Prepare arguments and build a call to __kmpc_master
Alexey Bataevd7614fb2015-04-10 06:33:45 +00003103 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003104 CommonActionTy Action(createRuntimeFunction(OMPRTL__kmpc_master), Args,
3105 createRuntimeFunction(OMPRTL__kmpc_end_master), Args,
3106 /*Conditional=*/true);
3107 MasterOpGen.setAction(Action);
3108 emitInlinedDirective(CGF, OMPD_master, MasterOpGen);
3109 Action.Done(CGF);
Alexey Bataev8d690652014-12-04 07:23:53 +00003110}
3111
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003112void CGOpenMPRuntime::emitTaskyieldCall(CodeGenFunction &CGF,
3113 SourceLocation Loc) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003114 if (!CGF.HaveInsertPoint())
3115 return;
Alexey Bataev9f797f32015-02-05 05:57:51 +00003116 // Build call __kmpc_omp_taskyield(loc, thread_id, 0);
3117 llvm::Value *Args[] = {
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003118 emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
Alexey Bataev9f797f32015-02-05 05:57:51 +00003119 llvm::ConstantInt::get(CGM.IntTy, /*V=*/0, /*isSigned=*/true)};
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003120 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_taskyield), Args);
Alexey Bataev48591dd2016-04-20 04:01:36 +00003121 if (auto *Region = dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
3122 Region->emitUntiedSwitch(CGF);
Alexey Bataev9f797f32015-02-05 05:57:51 +00003123}
3124
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00003125void CGOpenMPRuntime::emitTaskgroupRegion(CodeGenFunction &CGF,
3126 const RegionCodeGenTy &TaskgroupOpGen,
3127 SourceLocation Loc) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003128 if (!CGF.HaveInsertPoint())
3129 return;
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00003130 // __kmpc_taskgroup(ident_t *, gtid);
3131 // TaskgroupOpGen();
3132 // __kmpc_end_taskgroup(ident_t *, gtid);
3133 // Prepare arguments and build a call to __kmpc_taskgroup
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003134 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
3135 CommonActionTy Action(createRuntimeFunction(OMPRTL__kmpc_taskgroup), Args,
3136 createRuntimeFunction(OMPRTL__kmpc_end_taskgroup),
3137 Args);
3138 TaskgroupOpGen.setAction(Action);
3139 emitInlinedDirective(CGF, OMPD_taskgroup, TaskgroupOpGen);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00003140}
3141
John McCall7f416cc2015-09-08 08:05:57 +00003142/// Given an array of pointers to variables, project the address of a
3143/// given variable.
Alexey Bataevf24e7b12015-10-08 09:10:53 +00003144static Address emitAddrOfVarFromArray(CodeGenFunction &CGF, Address Array,
3145 unsigned Index, const VarDecl *Var) {
John McCall7f416cc2015-09-08 08:05:57 +00003146 // Pull out the pointer to the variable.
James Y Knight751fe282019-02-09 22:22:28 +00003147 Address PtrAddr = CGF.Builder.CreateConstArrayGEP(Array, Index);
John McCall7f416cc2015-09-08 08:05:57 +00003148 llvm::Value *Ptr = CGF.Builder.CreateLoad(PtrAddr);
3149
3150 Address Addr = Address(Ptr, CGF.getContext().getDeclAlign(Var));
Alexey Bataevf24e7b12015-10-08 09:10:53 +00003151 Addr = CGF.Builder.CreateElementBitCast(
3152 Addr, CGF.ConvertTypeForMem(Var->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00003153 return Addr;
3154}
3155
Alexey Bataeva63048e2015-03-23 06:18:07 +00003156static llvm::Value *emitCopyprivateCopyFunction(
Alexey Bataev420d45b2015-04-14 05:11:24 +00003157 CodeGenModule &CGM, llvm::Type *ArgsType,
3158 ArrayRef<const Expr *> CopyprivateVars, ArrayRef<const Expr *> DestExprs,
Alexey Bataev7cae94e2018-01-04 19:45:16 +00003159 ArrayRef<const Expr *> SrcExprs, ArrayRef<const Expr *> AssignmentOps,
3160 SourceLocation Loc) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003161 ASTContext &C = CGM.getContext();
Alexey Bataeva63048e2015-03-23 06:18:07 +00003162 // void copy_func(void *LHSArg, void *RHSArg);
3163 FunctionArgList Args;
Alexey Bataev7cae94e2018-01-04 19:45:16 +00003164 ImplicitParamDecl LHSArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
3165 ImplicitParamDecl::Other);
3166 ImplicitParamDecl RHSArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
3167 ImplicitParamDecl::Other);
Alexey Bataeva63048e2015-03-23 06:18:07 +00003168 Args.push_back(&LHSArg);
3169 Args.push_back(&RHSArg);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003170 const auto &CGFI =
3171 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
Alexey Bataev18fa2322018-05-02 14:20:50 +00003172 std::string Name =
3173 CGM.getOpenMPRuntime().getName({"omp", "copyprivate", "copy_func"});
3174 auto *Fn = llvm::Function::Create(CGM.getTypes().GetFunctionType(CGFI),
3175 llvm::GlobalValue::InternalLinkage, Name,
3176 &CGM.getModule());
Rafael Espindola51ec5a92018-02-28 23:46:35 +00003177 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, CGFI);
Alexey Bataevc0f879b2018-04-10 20:10:53 +00003178 Fn->setDoesNotRecurse();
Alexey Bataeva63048e2015-03-23 06:18:07 +00003179 CodeGenFunction CGF(CGM);
Alexey Bataev7cae94e2018-01-04 19:45:16 +00003180 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args, Loc, Loc);
Alexey Bataev420d45b2015-04-14 05:11:24 +00003181 // Dest = (void*[n])(LHSArg);
Alexey Bataeva63048e2015-03-23 06:18:07 +00003182 // Src = (void*[n])(RHSArg);
John McCall7f416cc2015-09-08 08:05:57 +00003183 Address LHS(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
3184 CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&LHSArg)),
3185 ArgsType), CGF.getPointerAlign());
3186 Address RHS(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
3187 CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&RHSArg)),
3188 ArgsType), CGF.getPointerAlign());
Alexey Bataeva63048e2015-03-23 06:18:07 +00003189 // *(Type0*)Dst[0] = *(Type0*)Src[0];
3190 // *(Type1*)Dst[1] = *(Type1*)Src[1];
3191 // ...
3192 // *(Typen*)Dst[n] = *(Typen*)Src[n];
Alexey Bataeva63048e2015-03-23 06:18:07 +00003193 for (unsigned I = 0, E = AssignmentOps.size(); I < E; ++I) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003194 const auto *DestVar =
3195 cast<VarDecl>(cast<DeclRefExpr>(DestExprs[I])->getDecl());
John McCall7f416cc2015-09-08 08:05:57 +00003196 Address DestAddr = emitAddrOfVarFromArray(CGF, LHS, I, DestVar);
3197
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003198 const auto *SrcVar =
3199 cast<VarDecl>(cast<DeclRefExpr>(SrcExprs[I])->getDecl());
John McCall7f416cc2015-09-08 08:05:57 +00003200 Address SrcAddr = emitAddrOfVarFromArray(CGF, RHS, I, SrcVar);
3201
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003202 const auto *VD = cast<DeclRefExpr>(CopyprivateVars[I])->getDecl();
Alexey Bataev1d9c15c2015-05-19 12:31:28 +00003203 QualType Type = VD->getType();
John McCall7f416cc2015-09-08 08:05:57 +00003204 CGF.EmitOMPCopy(Type, DestAddr, SrcAddr, DestVar, SrcVar, AssignmentOps[I]);
Alexey Bataeva63048e2015-03-23 06:18:07 +00003205 }
Alexey Bataeva63048e2015-03-23 06:18:07 +00003206 CGF.FinishFunction();
3207 return Fn;
3208}
3209
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003210void CGOpenMPRuntime::emitSingleRegion(CodeGenFunction &CGF,
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00003211 const RegionCodeGenTy &SingleOpGen,
Alexey Bataeva63048e2015-03-23 06:18:07 +00003212 SourceLocation Loc,
3213 ArrayRef<const Expr *> CopyprivateVars,
3214 ArrayRef<const Expr *> SrcExprs,
3215 ArrayRef<const Expr *> DstExprs,
3216 ArrayRef<const Expr *> AssignmentOps) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003217 if (!CGF.HaveInsertPoint())
3218 return;
Alexey Bataeva63048e2015-03-23 06:18:07 +00003219 assert(CopyprivateVars.size() == SrcExprs.size() &&
3220 CopyprivateVars.size() == DstExprs.size() &&
3221 CopyprivateVars.size() == AssignmentOps.size());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003222 ASTContext &C = CGM.getContext();
Alexey Bataeva63048e2015-03-23 06:18:07 +00003223 // int32 did_it = 0;
Alexey Bataev6956e2e2015-02-05 06:35:41 +00003224 // if(__kmpc_single(ident_t *, gtid)) {
3225 // SingleOpGen();
3226 // __kmpc_end_single(ident_t *, gtid);
Alexey Bataeva63048e2015-03-23 06:18:07 +00003227 // did_it = 1;
Alexey Bataev6956e2e2015-02-05 06:35:41 +00003228 // }
Alexey Bataeva63048e2015-03-23 06:18:07 +00003229 // call __kmpc_copyprivate(ident_t *, gtid, <buf_size>, <copyprivate list>,
3230 // <copy_func>, did_it);
3231
John McCall7f416cc2015-09-08 08:05:57 +00003232 Address DidIt = Address::invalid();
Alexey Bataeva63048e2015-03-23 06:18:07 +00003233 if (!CopyprivateVars.empty()) {
3234 // int32 did_it = 0;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003235 QualType KmpInt32Ty =
3236 C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
Alexey Bataeva63048e2015-03-23 06:18:07 +00003237 DidIt = CGF.CreateMemTemp(KmpInt32Ty, ".omp.copyprivate.did_it");
John McCall7f416cc2015-09-08 08:05:57 +00003238 CGF.Builder.CreateStore(CGF.Builder.getInt32(0), DidIt);
Alexey Bataeva63048e2015-03-23 06:18:07 +00003239 }
Alexey Bataev6956e2e2015-02-05 06:35:41 +00003240 // Prepare arguments and build a call to __kmpc_single
Alexey Bataevd7614fb2015-04-10 06:33:45 +00003241 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003242 CommonActionTy Action(createRuntimeFunction(OMPRTL__kmpc_single), Args,
3243 createRuntimeFunction(OMPRTL__kmpc_end_single), Args,
3244 /*Conditional=*/true);
3245 SingleOpGen.setAction(Action);
3246 emitInlinedDirective(CGF, OMPD_single, SingleOpGen);
3247 if (DidIt.isValid()) {
3248 // did_it = 1;
3249 CGF.Builder.CreateStore(CGF.Builder.getInt32(1), DidIt);
3250 }
3251 Action.Done(CGF);
Alexey Bataeva63048e2015-03-23 06:18:07 +00003252 // call __kmpc_copyprivate(ident_t *, gtid, <buf_size>, <copyprivate list>,
3253 // <copy_func>, did_it);
John McCall7f416cc2015-09-08 08:05:57 +00003254 if (DidIt.isValid()) {
Alexey Bataeva63048e2015-03-23 06:18:07 +00003255 llvm::APInt ArraySize(/*unsigned int numBits=*/32, CopyprivateVars.size());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003256 QualType CopyprivateArrayTy =
Alexey Bataeva63048e2015-03-23 06:18:07 +00003257 C.getConstantArrayType(C.VoidPtrTy, ArraySize, ArrayType::Normal,
3258 /*IndexTypeQuals=*/0);
3259 // Create a list of all private variables for copyprivate.
John McCall7f416cc2015-09-08 08:05:57 +00003260 Address CopyprivateList =
Alexey Bataeva63048e2015-03-23 06:18:07 +00003261 CGF.CreateMemTemp(CopyprivateArrayTy, ".omp.copyprivate.cpr_list");
3262 for (unsigned I = 0, E = CopyprivateVars.size(); I < E; ++I) {
James Y Knight751fe282019-02-09 22:22:28 +00003263 Address Elem = CGF.Builder.CreateConstArrayGEP(CopyprivateList, I);
John McCall7f416cc2015-09-08 08:05:57 +00003264 CGF.Builder.CreateStore(
Alexey Bataeva63048e2015-03-23 06:18:07 +00003265 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
John McCall7f416cc2015-09-08 08:05:57 +00003266 CGF.EmitLValue(CopyprivateVars[I]).getPointer(), CGF.VoidPtrTy),
3267 Elem);
Alexey Bataeva63048e2015-03-23 06:18:07 +00003268 }
3269 // Build function that copies private values from single region to all other
3270 // threads in the corresponding parallel region.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003271 llvm::Value *CpyFn = emitCopyprivateCopyFunction(
Alexey Bataeva63048e2015-03-23 06:18:07 +00003272 CGM, CGF.ConvertTypeForMem(CopyprivateArrayTy)->getPointerTo(),
Alexey Bataev7cae94e2018-01-04 19:45:16 +00003273 CopyprivateVars, SrcExprs, DstExprs, AssignmentOps, Loc);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003274 llvm::Value *BufSize = CGF.getTypeSize(CopyprivateArrayTy);
John McCall7f416cc2015-09-08 08:05:57 +00003275 Address CL =
3276 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(CopyprivateList,
3277 CGF.VoidPtrTy);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003278 llvm::Value *DidItVal = CGF.Builder.CreateLoad(DidIt);
Alexey Bataeva63048e2015-03-23 06:18:07 +00003279 llvm::Value *Args[] = {
3280 emitUpdateLocation(CGF, Loc), // ident_t *<loc>
3281 getThreadID(CGF, Loc), // i32 <gtid>
Alexey Bataev66beaa92015-04-30 03:47:32 +00003282 BufSize, // size_t <buf_size>
John McCall7f416cc2015-09-08 08:05:57 +00003283 CL.getPointer(), // void *<copyprivate list>
Alexey Bataeva63048e2015-03-23 06:18:07 +00003284 CpyFn, // void (*) (void *, void *) <copy_func>
3285 DidItVal // i32 did_it
3286 };
3287 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_copyprivate), Args);
3288 }
Alexey Bataev6956e2e2015-02-05 06:35:41 +00003289}
3290
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003291void CGOpenMPRuntime::emitOrderedRegion(CodeGenFunction &CGF,
3292 const RegionCodeGenTy &OrderedOpGen,
Alexey Bataev5f600d62015-09-29 03:48:57 +00003293 SourceLocation Loc, bool IsThreads) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003294 if (!CGF.HaveInsertPoint())
3295 return;
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003296 // __kmpc_ordered(ident_t *, gtid);
3297 // OrderedOpGen();
3298 // __kmpc_end_ordered(ident_t *, gtid);
3299 // Prepare arguments and build a call to __kmpc_ordered
Alexey Bataev5f600d62015-09-29 03:48:57 +00003300 if (IsThreads) {
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003301 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
Alexey Bataev14fa1c62016-03-29 05:34:15 +00003302 CommonActionTy Action(createRuntimeFunction(OMPRTL__kmpc_ordered), Args,
3303 createRuntimeFunction(OMPRTL__kmpc_end_ordered),
3304 Args);
3305 OrderedOpGen.setAction(Action);
3306 emitInlinedDirective(CGF, OMPD_ordered, OrderedOpGen);
3307 return;
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003308 }
Alexey Bataev5f600d62015-09-29 03:48:57 +00003309 emitInlinedDirective(CGF, OMPD_ordered, OrderedOpGen);
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003310}
3311
Alexey Bataevc3028ca2018-12-04 15:03:25 +00003312unsigned CGOpenMPRuntime::getDefaultFlagsForBarriers(OpenMPDirectiveKind Kind) {
Alexey Bataev50b3c952016-02-19 10:38:26 +00003313 unsigned Flags;
3314 if (Kind == OMPD_for)
3315 Flags = OMP_IDENT_BARRIER_IMPL_FOR;
3316 else if (Kind == OMPD_sections)
3317 Flags = OMP_IDENT_BARRIER_IMPL_SECTIONS;
3318 else if (Kind == OMPD_single)
3319 Flags = OMP_IDENT_BARRIER_IMPL_SINGLE;
3320 else if (Kind == OMPD_barrier)
3321 Flags = OMP_IDENT_BARRIER_EXPL;
3322 else
3323 Flags = OMP_IDENT_BARRIER_IMPL;
Alexey Bataevc3028ca2018-12-04 15:03:25 +00003324 return Flags;
3325}
3326
Alexey Bataevf6a53d62019-03-18 18:40:00 +00003327void CGOpenMPRuntime::getDefaultScheduleAndChunk(
3328 CodeGenFunction &CGF, const OMPLoopDirective &S,
3329 OpenMPScheduleClauseKind &ScheduleKind, const Expr *&ChunkExpr) const {
3330 // Check if the loop directive is actually a doacross loop directive. In this
3331 // case choose static, 1 schedule.
3332 if (llvm::any_of(
3333 S.getClausesOfKind<OMPOrderedClause>(),
3334 [](const OMPOrderedClause *C) { return C->getNumForLoops(); })) {
3335 ScheduleKind = OMPC_SCHEDULE_static;
3336 // Chunk size is 1 in this case.
3337 llvm::APInt ChunkSize(32, 1);
3338 ChunkExpr = IntegerLiteral::Create(
3339 CGF.getContext(), ChunkSize,
3340 CGF.getContext().getIntTypeForBitwidth(32, /*Signed=*/0),
3341 SourceLocation());
3342 }
3343}
3344
Alexey Bataevc3028ca2018-12-04 15:03:25 +00003345void CGOpenMPRuntime::emitBarrierCall(CodeGenFunction &CGF, SourceLocation Loc,
3346 OpenMPDirectiveKind Kind, bool EmitChecks,
3347 bool ForceSimpleCall) {
3348 if (!CGF.HaveInsertPoint())
3349 return;
3350 // Build call __kmpc_cancel_barrier(loc, thread_id);
3351 // Build call __kmpc_barrier(loc, thread_id);
3352 unsigned Flags = getDefaultFlagsForBarriers(Kind);
Alexey Bataev81c7ea02015-07-03 09:56:58 +00003353 // Build call __kmpc_cancel_barrier(loc, thread_id) or __kmpc_barrier(loc,
3354 // thread_id);
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003355 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc, Flags),
3356 getThreadID(CGF, Loc)};
Alexey Bataev3015bcc2016-01-22 08:56:50 +00003357 if (auto *OMPRegionInfo =
3358 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
Alexey Bataev25e5b442015-09-15 12:52:43 +00003359 if (!ForceSimpleCall && OMPRegionInfo->hasCancel()) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003360 llvm::Value *Result = CGF.EmitRuntimeCall(
Alexey Bataev81c7ea02015-07-03 09:56:58 +00003361 createRuntimeFunction(OMPRTL__kmpc_cancel_barrier), Args);
Alexey Bataev25e5b442015-09-15 12:52:43 +00003362 if (EmitChecks) {
Alexey Bataev81c7ea02015-07-03 09:56:58 +00003363 // if (__kmpc_cancel_barrier()) {
3364 // exit from construct;
3365 // }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003366 llvm::BasicBlock *ExitBB = CGF.createBasicBlock(".cancel.exit");
3367 llvm::BasicBlock *ContBB = CGF.createBasicBlock(".cancel.continue");
3368 llvm::Value *Cmp = CGF.Builder.CreateIsNotNull(Result);
Alexey Bataev81c7ea02015-07-03 09:56:58 +00003369 CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
3370 CGF.EmitBlock(ExitBB);
3371 // exit from construct;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003372 CodeGenFunction::JumpDest CancelDestination =
Alexey Bataev25e5b442015-09-15 12:52:43 +00003373 CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
Alexey Bataev81c7ea02015-07-03 09:56:58 +00003374 CGF.EmitBranchThroughCleanup(CancelDestination);
3375 CGF.EmitBlock(ContBB, /*IsFinished=*/true);
3376 }
3377 return;
3378 }
3379 }
3380 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_barrier), Args);
Alexey Bataev4a5bb772014-10-08 14:01:46 +00003381}
3382
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003383/// Map the OpenMP loop schedule to the runtime enumeration.
Alexander Musmanc6388682014-12-15 07:07:06 +00003384static OpenMPSchedType getRuntimeSchedule(OpenMPScheduleClauseKind ScheduleKind,
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00003385 bool Chunked, bool Ordered) {
Alexander Musmanc6388682014-12-15 07:07:06 +00003386 switch (ScheduleKind) {
3387 case OMPC_SCHEDULE_static:
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00003388 return Chunked ? (Ordered ? OMP_ord_static_chunked : OMP_sch_static_chunked)
3389 : (Ordered ? OMP_ord_static : OMP_sch_static);
Alexander Musmanc6388682014-12-15 07:07:06 +00003390 case OMPC_SCHEDULE_dynamic:
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00003391 return Ordered ? OMP_ord_dynamic_chunked : OMP_sch_dynamic_chunked;
Alexander Musmanc6388682014-12-15 07:07:06 +00003392 case OMPC_SCHEDULE_guided:
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00003393 return Ordered ? OMP_ord_guided_chunked : OMP_sch_guided_chunked;
Alexander Musmanc6388682014-12-15 07:07:06 +00003394 case OMPC_SCHEDULE_runtime:
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00003395 return Ordered ? OMP_ord_runtime : OMP_sch_runtime;
3396 case OMPC_SCHEDULE_auto:
3397 return Ordered ? OMP_ord_auto : OMP_sch_auto;
Alexander Musmanc6388682014-12-15 07:07:06 +00003398 case OMPC_SCHEDULE_unknown:
3399 assert(!Chunked && "chunk was specified but schedule kind not known");
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00003400 return Ordered ? OMP_ord_static : OMP_sch_static;
Alexander Musmanc6388682014-12-15 07:07:06 +00003401 }
3402 llvm_unreachable("Unexpected runtime schedule");
3403}
3404
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003405/// Map the OpenMP distribute schedule to the runtime enumeration.
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003406static OpenMPSchedType
3407getRuntimeSchedule(OpenMPDistScheduleClauseKind ScheduleKind, bool Chunked) {
3408 // only static is allowed for dist_schedule
3409 return Chunked ? OMP_dist_sch_static_chunked : OMP_dist_sch_static;
3410}
3411
Alexander Musmanc6388682014-12-15 07:07:06 +00003412bool CGOpenMPRuntime::isStaticNonchunked(OpenMPScheduleClauseKind ScheduleKind,
3413 bool Chunked) const {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003414 OpenMPSchedType Schedule =
3415 getRuntimeSchedule(ScheduleKind, Chunked, /*Ordered=*/false);
Alexander Musmanc6388682014-12-15 07:07:06 +00003416 return Schedule == OMP_sch_static;
3417}
3418
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003419bool CGOpenMPRuntime::isStaticNonchunked(
3420 OpenMPDistScheduleClauseKind ScheduleKind, bool Chunked) const {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003421 OpenMPSchedType Schedule = getRuntimeSchedule(ScheduleKind, Chunked);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003422 return Schedule == OMP_dist_sch_static;
3423}
3424
Gheorghe-Teodor Berceae9256762018-10-29 15:45:47 +00003425bool CGOpenMPRuntime::isStaticChunked(OpenMPScheduleClauseKind ScheduleKind,
3426 bool Chunked) const {
3427 OpenMPSchedType Schedule =
3428 getRuntimeSchedule(ScheduleKind, Chunked, /*Ordered=*/false);
3429 return Schedule == OMP_sch_static_chunked;
3430}
3431
3432bool CGOpenMPRuntime::isStaticChunked(
3433 OpenMPDistScheduleClauseKind ScheduleKind, bool Chunked) const {
3434 OpenMPSchedType Schedule = getRuntimeSchedule(ScheduleKind, Chunked);
3435 return Schedule == OMP_dist_sch_static_chunked;
3436}
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003437
Alexander Musmandf7a8e22015-01-22 08:49:35 +00003438bool CGOpenMPRuntime::isDynamic(OpenMPScheduleClauseKind ScheduleKind) const {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003439 OpenMPSchedType Schedule =
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00003440 getRuntimeSchedule(ScheduleKind, /*Chunked=*/false, /*Ordered=*/false);
Alexander Musmandf7a8e22015-01-22 08:49:35 +00003441 assert(Schedule != OMP_sch_static_chunked && "cannot be chunked here");
3442 return Schedule != OMP_sch_static;
3443}
3444
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003445static int addMonoNonMonoModifier(OpenMPSchedType Schedule,
3446 OpenMPScheduleClauseModifier M1,
3447 OpenMPScheduleClauseModifier M2) {
Alexey Bataev6cff6242016-05-30 13:05:14 +00003448 int Modifier = 0;
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003449 switch (M1) {
3450 case OMPC_SCHEDULE_MODIFIER_monotonic:
Alexey Bataev6cff6242016-05-30 13:05:14 +00003451 Modifier = OMP_sch_modifier_monotonic;
3452 break;
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003453 case OMPC_SCHEDULE_MODIFIER_nonmonotonic:
Alexey Bataev6cff6242016-05-30 13:05:14 +00003454 Modifier = OMP_sch_modifier_nonmonotonic;
3455 break;
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003456 case OMPC_SCHEDULE_MODIFIER_simd:
Alexey Bataev6cff6242016-05-30 13:05:14 +00003457 if (Schedule == OMP_sch_static_chunked)
3458 Schedule = OMP_sch_static_balanced_chunked;
3459 break;
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003460 case OMPC_SCHEDULE_MODIFIER_last:
3461 case OMPC_SCHEDULE_MODIFIER_unknown:
3462 break;
3463 }
3464 switch (M2) {
3465 case OMPC_SCHEDULE_MODIFIER_monotonic:
Alexey Bataev6cff6242016-05-30 13:05:14 +00003466 Modifier = OMP_sch_modifier_monotonic;
3467 break;
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003468 case OMPC_SCHEDULE_MODIFIER_nonmonotonic:
Alexey Bataev6cff6242016-05-30 13:05:14 +00003469 Modifier = OMP_sch_modifier_nonmonotonic;
3470 break;
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003471 case OMPC_SCHEDULE_MODIFIER_simd:
Alexey Bataev6cff6242016-05-30 13:05:14 +00003472 if (Schedule == OMP_sch_static_chunked)
3473 Schedule = OMP_sch_static_balanced_chunked;
3474 break;
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003475 case OMPC_SCHEDULE_MODIFIER_last:
3476 case OMPC_SCHEDULE_MODIFIER_unknown:
3477 break;
3478 }
Alexey Bataev6cff6242016-05-30 13:05:14 +00003479 return Schedule | Modifier;
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003480}
3481
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003482void CGOpenMPRuntime::emitForDispatchInit(
3483 CodeGenFunction &CGF, SourceLocation Loc,
3484 const OpenMPScheduleTy &ScheduleKind, unsigned IVSize, bool IVSigned,
3485 bool Ordered, const DispatchRTInput &DispatchValues) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003486 if (!CGF.HaveInsertPoint())
3487 return;
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003488 OpenMPSchedType Schedule = getRuntimeSchedule(
3489 ScheduleKind.Schedule, DispatchValues.Chunk != nullptr, Ordered);
John McCall7f416cc2015-09-08 08:05:57 +00003490 assert(Ordered ||
3491 (Schedule != OMP_sch_static && Schedule != OMP_sch_static_chunked &&
Alexey Bataev6cff6242016-05-30 13:05:14 +00003492 Schedule != OMP_ord_static && Schedule != OMP_ord_static_chunked &&
3493 Schedule != OMP_sch_static_balanced_chunked));
John McCall7f416cc2015-09-08 08:05:57 +00003494 // Call __kmpc_dispatch_init(
3495 // ident_t *loc, kmp_int32 tid, kmp_int32 schedule,
3496 // kmp_int[32|64] lower, kmp_int[32|64] upper,
3497 // kmp_int[32|64] stride, kmp_int[32|64] chunk);
Alexander Musmanc6388682014-12-15 07:07:06 +00003498
John McCall7f416cc2015-09-08 08:05:57 +00003499 // If the Chunk was not specified in the clause - use default value 1.
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003500 llvm::Value *Chunk = DispatchValues.Chunk ? DispatchValues.Chunk
3501 : CGF.Builder.getIntN(IVSize, 1);
John McCall7f416cc2015-09-08 08:05:57 +00003502 llvm::Value *Args[] = {
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003503 emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
3504 CGF.Builder.getInt32(addMonoNonMonoModifier(
3505 Schedule, ScheduleKind.M1, ScheduleKind.M2)), // Schedule type
Carlo Bertollib0ff0a62017-04-25 17:52:12 +00003506 DispatchValues.LB, // Lower
3507 DispatchValues.UB, // Upper
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003508 CGF.Builder.getIntN(IVSize, 1), // Stride
3509 Chunk // Chunk
John McCall7f416cc2015-09-08 08:05:57 +00003510 };
3511 CGF.EmitRuntimeCall(createDispatchInitFunction(IVSize, IVSigned), Args);
3512}
3513
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003514static void emitForStaticInitCall(
3515 CodeGenFunction &CGF, llvm::Value *UpdateLocation, llvm::Value *ThreadId,
James Y Knight9871db02019-02-05 16:42:33 +00003516 llvm::FunctionCallee ForStaticInitFunction, OpenMPSchedType Schedule,
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003517 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003518 const CGOpenMPRuntime::StaticRTInput &Values) {
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003519 if (!CGF.HaveInsertPoint())
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003520 return;
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003521
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003522 assert(!Values.Ordered);
3523 assert(Schedule == OMP_sch_static || Schedule == OMP_sch_static_chunked ||
3524 Schedule == OMP_sch_static_balanced_chunked ||
3525 Schedule == OMP_ord_static || Schedule == OMP_ord_static_chunked ||
3526 Schedule == OMP_dist_sch_static ||
3527 Schedule == OMP_dist_sch_static_chunked);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003528
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003529 // Call __kmpc_for_static_init(
3530 // ident_t *loc, kmp_int32 tid, kmp_int32 schedtype,
3531 // kmp_int32 *p_lastiter, kmp_int[32|64] *p_lower,
3532 // kmp_int[32|64] *p_upper, kmp_int[32|64] *p_stride,
3533 // kmp_int[32|64] incr, kmp_int[32|64] chunk);
3534 llvm::Value *Chunk = Values.Chunk;
3535 if (Chunk == nullptr) {
3536 assert((Schedule == OMP_sch_static || Schedule == OMP_ord_static ||
3537 Schedule == OMP_dist_sch_static) &&
3538 "expected static non-chunked schedule");
3539 // If the Chunk was not specified in the clause - use default value 1.
3540 Chunk = CGF.Builder.getIntN(Values.IVSize, 1);
3541 } else {
3542 assert((Schedule == OMP_sch_static_chunked ||
3543 Schedule == OMP_sch_static_balanced_chunked ||
3544 Schedule == OMP_ord_static_chunked ||
3545 Schedule == OMP_dist_sch_static_chunked) &&
3546 "expected static chunked schedule");
3547 }
3548 llvm::Value *Args[] = {
3549 UpdateLocation,
3550 ThreadId,
3551 CGF.Builder.getInt32(addMonoNonMonoModifier(Schedule, M1,
3552 M2)), // Schedule type
3553 Values.IL.getPointer(), // &isLastIter
3554 Values.LB.getPointer(), // &LB
3555 Values.UB.getPointer(), // &UB
3556 Values.ST.getPointer(), // &Stride
3557 CGF.Builder.getIntN(Values.IVSize, 1), // Incr
3558 Chunk // Chunk
3559 };
3560 CGF.EmitRuntimeCall(ForStaticInitFunction, Args);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003561}
3562
John McCall7f416cc2015-09-08 08:05:57 +00003563void CGOpenMPRuntime::emitForStaticInit(CodeGenFunction &CGF,
3564 SourceLocation Loc,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003565 OpenMPDirectiveKind DKind,
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003566 const OpenMPScheduleTy &ScheduleKind,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003567 const StaticRTInput &Values) {
3568 OpenMPSchedType ScheduleNum = getRuntimeSchedule(
3569 ScheduleKind.Schedule, Values.Chunk != nullptr, Values.Ordered);
3570 assert(isOpenMPWorksharingDirective(DKind) &&
3571 "Expected loop-based or sections-based directive.");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003572 llvm::Value *UpdatedLocation = emitUpdateLocation(CGF, Loc,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003573 isOpenMPLoopDirective(DKind)
3574 ? OMP_IDENT_WORK_LOOP
3575 : OMP_IDENT_WORK_SECTIONS);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003576 llvm::Value *ThreadId = getThreadID(CGF, Loc);
James Y Knight9871db02019-02-05 16:42:33 +00003577 llvm::FunctionCallee StaticInitFunction =
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003578 createForStaticInitFunction(Values.IVSize, Values.IVSigned);
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003579 emitForStaticInitCall(CGF, UpdatedLocation, ThreadId, StaticInitFunction,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003580 ScheduleNum, ScheduleKind.M1, ScheduleKind.M2, Values);
Carlo Bertollifc35ad22016-03-07 16:04:49 +00003581}
John McCall7f416cc2015-09-08 08:05:57 +00003582
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003583void CGOpenMPRuntime::emitDistributeStaticInit(
3584 CodeGenFunction &CGF, SourceLocation Loc,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003585 OpenMPDistScheduleClauseKind SchedKind,
3586 const CGOpenMPRuntime::StaticRTInput &Values) {
3587 OpenMPSchedType ScheduleNum =
3588 getRuntimeSchedule(SchedKind, Values.Chunk != nullptr);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003589 llvm::Value *UpdatedLocation =
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003590 emitUpdateLocation(CGF, Loc, OMP_IDENT_WORK_DISTRIBUTE);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003591 llvm::Value *ThreadId = getThreadID(CGF, Loc);
James Y Knight9871db02019-02-05 16:42:33 +00003592 llvm::FunctionCallee StaticInitFunction =
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003593 createForStaticInitFunction(Values.IVSize, Values.IVSigned);
Alexey Bataev9ebd7422016-05-10 09:57:36 +00003594 emitForStaticInitCall(CGF, UpdatedLocation, ThreadId, StaticInitFunction,
3595 ScheduleNum, OMPC_SCHEDULE_MODIFIER_unknown,
Alexey Bataev0f87dbe2017-08-14 17:56:13 +00003596 OMPC_SCHEDULE_MODIFIER_unknown, Values);
Alexander Musmanc6388682014-12-15 07:07:06 +00003597}
3598
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003599void CGOpenMPRuntime::emitForStaticFinish(CodeGenFunction &CGF,
Alexey Bataevf43f7142017-09-06 16:17:35 +00003600 SourceLocation Loc,
3601 OpenMPDirectiveKind DKind) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003602 if (!CGF.HaveInsertPoint())
3603 return;
Alexander Musmanc6388682014-12-15 07:07:06 +00003604 // Call __kmpc_for_static_fini(ident_t *loc, kmp_int32 tid);
Alexey Bataevf43f7142017-09-06 16:17:35 +00003605 llvm::Value *Args[] = {
3606 emitUpdateLocation(CGF, Loc,
3607 isOpenMPDistributeDirective(DKind)
3608 ? OMP_IDENT_WORK_DISTRIBUTE
3609 : isOpenMPLoopDirective(DKind)
3610 ? OMP_IDENT_WORK_LOOP
3611 : OMP_IDENT_WORK_SECTIONS),
3612 getThreadID(CGF, Loc)};
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003613 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_for_static_fini),
3614 Args);
Alexander Musmanc6388682014-12-15 07:07:06 +00003615}
3616
Alexey Bataevd7589ffe2015-05-20 13:12:48 +00003617void CGOpenMPRuntime::emitForOrderedIterationEnd(CodeGenFunction &CGF,
3618 SourceLocation Loc,
3619 unsigned IVSize,
3620 bool IVSigned) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003621 if (!CGF.HaveInsertPoint())
3622 return;
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003623 // Call __kmpc_for_dynamic_fini_(4|8)[u](ident_t *loc, kmp_int32 tid);
Alexey Bataev50b3c952016-02-19 10:38:26 +00003624 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
Alexey Bataev98eb6e32015-04-22 11:15:40 +00003625 CGF.EmitRuntimeCall(createDispatchFiniFunction(IVSize, IVSigned), Args);
3626}
3627
Alexander Musman92bdaab2015-03-12 13:37:50 +00003628llvm::Value *CGOpenMPRuntime::emitForNext(CodeGenFunction &CGF,
3629 SourceLocation Loc, unsigned IVSize,
John McCall7f416cc2015-09-08 08:05:57 +00003630 bool IVSigned, Address IL,
3631 Address LB, Address UB,
3632 Address ST) {
Alexander Musman92bdaab2015-03-12 13:37:50 +00003633 // Call __kmpc_dispatch_next(
3634 // ident_t *loc, kmp_int32 tid, kmp_int32 *p_lastiter,
3635 // kmp_int[32|64] *p_lower, kmp_int[32|64] *p_upper,
3636 // kmp_int[32|64] *p_stride);
3637 llvm::Value *Args[] = {
Alexey Bataev50b3c952016-02-19 10:38:26 +00003638 emitUpdateLocation(CGF, Loc),
3639 getThreadID(CGF, Loc),
John McCall7f416cc2015-09-08 08:05:57 +00003640 IL.getPointer(), // &isLastIter
3641 LB.getPointer(), // &Lower
3642 UB.getPointer(), // &Upper
3643 ST.getPointer() // &Stride
Alexander Musman92bdaab2015-03-12 13:37:50 +00003644 };
3645 llvm::Value *Call =
3646 CGF.EmitRuntimeCall(createDispatchNextFunction(IVSize, IVSigned), Args);
3647 return CGF.EmitScalarConversion(
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003648 Call, CGF.getContext().getIntTypeForBitwidth(32, /*Signed=*/1),
Filipe Cabecinhas7af183d2015-08-11 04:19:28 +00003649 CGF.getContext().BoolTy, Loc);
Alexander Musman92bdaab2015-03-12 13:37:50 +00003650}
3651
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003652void CGOpenMPRuntime::emitNumThreadsClause(CodeGenFunction &CGF,
3653 llvm::Value *NumThreads,
3654 SourceLocation Loc) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003655 if (!CGF.HaveInsertPoint())
3656 return;
Alexey Bataevb2059782014-10-13 08:23:51 +00003657 // Build call __kmpc_push_num_threads(&loc, global_tid, num_threads)
3658 llvm::Value *Args[] = {
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003659 emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
Alexey Bataevb2059782014-10-13 08:23:51 +00003660 CGF.Builder.CreateIntCast(NumThreads, CGF.Int32Ty, /*isSigned*/ true)};
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003661 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_push_num_threads),
3662 Args);
Alexey Bataevb2059782014-10-13 08:23:51 +00003663}
3664
Alexey Bataev7f210c62015-06-18 13:40:03 +00003665void CGOpenMPRuntime::emitProcBindClause(CodeGenFunction &CGF,
3666 OpenMPProcBindClauseKind ProcBind,
3667 SourceLocation Loc) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003668 if (!CGF.HaveInsertPoint())
3669 return;
Alexey Bataev7f210c62015-06-18 13:40:03 +00003670 // Constants for proc bind value accepted by the runtime.
3671 enum ProcBindTy {
3672 ProcBindFalse = 0,
3673 ProcBindTrue,
3674 ProcBindMaster,
3675 ProcBindClose,
3676 ProcBindSpread,
3677 ProcBindIntel,
3678 ProcBindDefault
3679 } RuntimeProcBind;
3680 switch (ProcBind) {
3681 case OMPC_PROC_BIND_master:
3682 RuntimeProcBind = ProcBindMaster;
3683 break;
3684 case OMPC_PROC_BIND_close:
3685 RuntimeProcBind = ProcBindClose;
3686 break;
3687 case OMPC_PROC_BIND_spread:
3688 RuntimeProcBind = ProcBindSpread;
3689 break;
3690 case OMPC_PROC_BIND_unknown:
3691 llvm_unreachable("Unsupported proc_bind value.");
3692 }
3693 // Build call __kmpc_push_proc_bind(&loc, global_tid, proc_bind)
3694 llvm::Value *Args[] = {
3695 emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
3696 llvm::ConstantInt::get(CGM.IntTy, RuntimeProcBind, /*isSigned=*/true)};
3697 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_push_proc_bind), Args);
3698}
3699
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003700void CGOpenMPRuntime::emitFlush(CodeGenFunction &CGF, ArrayRef<const Expr *>,
3701 SourceLocation Loc) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00003702 if (!CGF.HaveInsertPoint())
3703 return;
Alexey Bataevd76df6d2015-02-24 12:55:09 +00003704 // Build call void __kmpc_flush(ident_t *loc)
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003705 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_flush),
3706 emitUpdateLocation(CGF, Loc));
Alexey Bataevcc37cc12014-11-20 04:34:54 +00003707}
Alexey Bataev3eff5f42015-02-25 08:32:46 +00003708
Alexey Bataev62b63b12015-03-10 07:28:44 +00003709namespace {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003710/// Indexes of fields for type kmp_task_t.
Alexey Bataev62b63b12015-03-10 07:28:44 +00003711enum KmpTaskTFields {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003712 /// List of shared variables.
Alexey Bataev62b63b12015-03-10 07:28:44 +00003713 KmpTaskTShareds,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003714 /// Task routine.
Alexey Bataev62b63b12015-03-10 07:28:44 +00003715 KmpTaskTRoutine,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003716 /// Partition id for the untied tasks.
Alexey Bataev62b63b12015-03-10 07:28:44 +00003717 KmpTaskTPartId,
Alexey Bataevad537bb2016-05-30 09:06:50 +00003718 /// Function with call of destructors for private variables.
3719 Data1,
3720 /// Task priority.
3721 Data2,
Alexey Bataev7292c292016-04-25 12:22:29 +00003722 /// (Taskloops only) Lower bound.
3723 KmpTaskTLowerBound,
3724 /// (Taskloops only) Upper bound.
3725 KmpTaskTUpperBound,
3726 /// (Taskloops only) Stride.
3727 KmpTaskTStride,
3728 /// (Taskloops only) Is last iteration flag.
3729 KmpTaskTLastIter,
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00003730 /// (Taskloops only) Reduction data.
3731 KmpTaskTReductions,
Alexey Bataev62b63b12015-03-10 07:28:44 +00003732};
Hans Wennborg7eb54642015-09-10 17:07:54 +00003733} // anonymous namespace
Alexey Bataev62b63b12015-03-10 07:28:44 +00003734
Samuel Antaoee8fb302016-01-06 13:42:12 +00003735bool CGOpenMPRuntime::OffloadEntriesInfoManagerTy::empty() const {
Alexey Bataev03f270c2018-03-30 18:31:07 +00003736 return OffloadEntriesTargetRegion.empty() &&
3737 OffloadEntriesDeviceGlobalVar.empty();
Samuel Antaoee8fb302016-01-06 13:42:12 +00003738}
3739
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00003740/// Initialize target region entry.
Samuel Antaoee8fb302016-01-06 13:42:12 +00003741void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3742 initializeTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
3743 StringRef ParentName, unsigned LineNum,
Samuel Antao2de62b02016-02-13 23:35:10 +00003744 unsigned Order) {
Samuel Antaoee8fb302016-01-06 13:42:12 +00003745 assert(CGM.getLangOpts().OpenMPIsDevice && "Initialization of entries is "
3746 "only required for the device "
3747 "code generation.");
Samuel Antao2de62b02016-02-13 23:35:10 +00003748 OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum] =
Samuel Antaof83efdb2017-01-05 16:02:49 +00003749 OffloadEntryInfoTargetRegion(Order, /*Addr=*/nullptr, /*ID=*/nullptr,
Alexey Bataev34f8a702018-03-28 14:28:54 +00003750 OMPTargetRegionEntryTargetRegion);
Samuel Antaoee8fb302016-01-06 13:42:12 +00003751 ++OffloadingEntriesNum;
3752}
3753
3754void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3755 registerTargetRegionEntryInfo(unsigned DeviceID, unsigned FileID,
3756 StringRef ParentName, unsigned LineNum,
Samuel Antaof83efdb2017-01-05 16:02:49 +00003757 llvm::Constant *Addr, llvm::Constant *ID,
Alexey Bataev34f8a702018-03-28 14:28:54 +00003758 OMPTargetRegionEntryKind Flags) {
Samuel Antaoee8fb302016-01-06 13:42:12 +00003759 // If we are emitting code for a target, the entry is already initialized,
3760 // only has to be registered.
3761 if (CGM.getLangOpts().OpenMPIsDevice) {
Alexey Bataev64e62dc2018-04-30 16:26:57 +00003762 if (!hasTargetRegionEntryInfo(DeviceID, FileID, ParentName, LineNum)) {
3763 unsigned DiagID = CGM.getDiags().getCustomDiagID(
3764 DiagnosticsEngine::Error,
3765 "Unable to find target region on line '%0' in the device code.");
3766 CGM.getDiags().Report(DiagID) << LineNum;
3767 return;
3768 }
Samuel Antao2de62b02016-02-13 23:35:10 +00003769 auto &Entry =
3770 OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum];
Samuel Antaoee8fb302016-01-06 13:42:12 +00003771 assert(Entry.isValid() && "Entry not initialized!");
3772 Entry.setAddress(Addr);
3773 Entry.setID(ID);
Samuel Antaof83efdb2017-01-05 16:02:49 +00003774 Entry.setFlags(Flags);
Samuel Antaoee8fb302016-01-06 13:42:12 +00003775 } else {
Alexey Bataev03f270c2018-03-30 18:31:07 +00003776 OffloadEntryInfoTargetRegion Entry(OffloadingEntriesNum, Addr, ID, Flags);
Samuel Antao2de62b02016-02-13 23:35:10 +00003777 OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum] = Entry;
Alexey Bataev03f270c2018-03-30 18:31:07 +00003778 ++OffloadingEntriesNum;
Samuel Antaoee8fb302016-01-06 13:42:12 +00003779 }
3780}
3781
3782bool CGOpenMPRuntime::OffloadEntriesInfoManagerTy::hasTargetRegionEntryInfo(
Samuel Antao2de62b02016-02-13 23:35:10 +00003783 unsigned DeviceID, unsigned FileID, StringRef ParentName,
3784 unsigned LineNum) const {
Samuel Antaoee8fb302016-01-06 13:42:12 +00003785 auto PerDevice = OffloadEntriesTargetRegion.find(DeviceID);
3786 if (PerDevice == OffloadEntriesTargetRegion.end())
3787 return false;
3788 auto PerFile = PerDevice->second.find(FileID);
3789 if (PerFile == PerDevice->second.end())
3790 return false;
3791 auto PerParentName = PerFile->second.find(ParentName);
3792 if (PerParentName == PerFile->second.end())
3793 return false;
3794 auto PerLine = PerParentName->second.find(LineNum);
3795 if (PerLine == PerParentName->second.end())
3796 return false;
Samuel Antaoee8fb302016-01-06 13:42:12 +00003797 // Fail if this entry is already registered.
Samuel Antao2de62b02016-02-13 23:35:10 +00003798 if (PerLine->second.getAddress() || PerLine->second.getID())
Samuel Antaoee8fb302016-01-06 13:42:12 +00003799 return false;
3800 return true;
3801}
3802
3803void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::actOnTargetRegionEntriesInfo(
3804 const OffloadTargetRegionEntryInfoActTy &Action) {
3805 // Scan all target region entries and perform the provided action.
Alexey Bataev03f270c2018-03-30 18:31:07 +00003806 for (const auto &D : OffloadEntriesTargetRegion)
3807 for (const auto &F : D.second)
3808 for (const auto &P : F.second)
3809 for (const auto &L : P.second)
Samuel Antao2de62b02016-02-13 23:35:10 +00003810 Action(D.first, F.first, P.first(), L.first, L.second);
Samuel Antaoee8fb302016-01-06 13:42:12 +00003811}
3812
Alexey Bataev03f270c2018-03-30 18:31:07 +00003813void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3814 initializeDeviceGlobalVarEntryInfo(StringRef Name,
3815 OMPTargetGlobalVarEntryKind Flags,
3816 unsigned Order) {
3817 assert(CGM.getLangOpts().OpenMPIsDevice && "Initialization of entries is "
3818 "only required for the device "
3819 "code generation.");
3820 OffloadEntriesDeviceGlobalVar.try_emplace(Name, Order, Flags);
3821 ++OffloadingEntriesNum;
3822}
Samuel Antaoee8fb302016-01-06 13:42:12 +00003823
Alexey Bataev03f270c2018-03-30 18:31:07 +00003824void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3825 registerDeviceGlobalVarEntryInfo(StringRef VarName, llvm::Constant *Addr,
3826 CharUnits VarSize,
3827 OMPTargetGlobalVarEntryKind Flags,
3828 llvm::GlobalValue::LinkageTypes Linkage) {
3829 if (CGM.getLangOpts().OpenMPIsDevice) {
3830 auto &Entry = OffloadEntriesDeviceGlobalVar[VarName];
3831 assert(Entry.isValid() && Entry.getFlags() == Flags &&
3832 "Entry not initialized!");
3833 assert((!Entry.getAddress() || Entry.getAddress() == Addr) &&
3834 "Resetting with the new address.");
Alexey Bataev8259cc32019-03-12 20:05:17 +00003835 if (Entry.getAddress() && hasDeviceGlobalVarEntryInfo(VarName)) {
3836 if (Entry.getVarSize().isZero()) {
3837 Entry.setVarSize(VarSize);
3838 Entry.setLinkage(Linkage);
3839 }
Alexey Bataev03f270c2018-03-30 18:31:07 +00003840 return;
Alexey Bataev8259cc32019-03-12 20:05:17 +00003841 }
Alexey Bataev03f270c2018-03-30 18:31:07 +00003842 Entry.setVarSize(VarSize);
3843 Entry.setLinkage(Linkage);
Alexey Bataev8259cc32019-03-12 20:05:17 +00003844 Entry.setAddress(Addr);
Alexey Bataev03f270c2018-03-30 18:31:07 +00003845 } else {
Alexey Bataev8259cc32019-03-12 20:05:17 +00003846 if (hasDeviceGlobalVarEntryInfo(VarName)) {
3847 auto &Entry = OffloadEntriesDeviceGlobalVar[VarName];
3848 assert(Entry.isValid() && Entry.getFlags() == Flags &&
3849 "Entry not initialized!");
3850 assert((!Entry.getAddress() || Entry.getAddress() == Addr) &&
3851 "Resetting with the new address.");
3852 if (Entry.getVarSize().isZero()) {
3853 Entry.setVarSize(VarSize);
3854 Entry.setLinkage(Linkage);
3855 }
Alexey Bataev03f270c2018-03-30 18:31:07 +00003856 return;
Alexey Bataev8259cc32019-03-12 20:05:17 +00003857 }
Alexey Bataev03f270c2018-03-30 18:31:07 +00003858 OffloadEntriesDeviceGlobalVar.try_emplace(
3859 VarName, OffloadingEntriesNum, Addr, VarSize, Flags, Linkage);
3860 ++OffloadingEntriesNum;
3861 }
3862}
3863
3864void CGOpenMPRuntime::OffloadEntriesInfoManagerTy::
3865 actOnDeviceGlobalVarEntriesInfo(
3866 const OffloadDeviceGlobalVarEntryInfoActTy &Action) {
3867 // Scan all target region entries and perform the provided action.
3868 for (const auto &E : OffloadEntriesDeviceGlobalVar)
3869 Action(E.getKey(), E.getValue());
Samuel Antaoee8fb302016-01-06 13:42:12 +00003870}
3871
3872llvm::Function *
3873CGOpenMPRuntime::createOffloadingBinaryDescriptorRegistration() {
Samuel Antaoee8fb302016-01-06 13:42:12 +00003874 // If we don't have entries or if we are emitting code for the device, we
3875 // don't need to do anything.
3876 if (CGM.getLangOpts().OpenMPIsDevice || OffloadEntriesInfoManager.empty())
3877 return nullptr;
3878
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003879 llvm::Module &M = CGM.getModule();
3880 ASTContext &C = CGM.getContext();
Samuel Antaoee8fb302016-01-06 13:42:12 +00003881
3882 // Get list of devices we care about
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003883 const std::vector<llvm::Triple> &Devices = CGM.getLangOpts().OMPTargetTriples;
Samuel Antaoee8fb302016-01-06 13:42:12 +00003884
3885 // We should be creating an offloading descriptor only if there are devices
3886 // specified.
3887 assert(!Devices.empty() && "No OpenMP offloading devices??");
3888
3889 // Create the external variables that will point to the begin and end of the
3890 // host entries section. These will be defined by the linker.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003891 llvm::Type *OffloadEntryTy =
Samuel Antaoee8fb302016-01-06 13:42:12 +00003892 CGM.getTypes().ConvertTypeForMem(getTgtOffloadEntryQTy());
Alexey Bataev18fa2322018-05-02 14:20:50 +00003893 std::string EntriesBeginName = getName({"omp_offloading", "entries_begin"});
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003894 auto *HostEntriesBegin = new llvm::GlobalVariable(
Samuel Antaoee8fb302016-01-06 13:42:12 +00003895 M, OffloadEntryTy, /*isConstant=*/true,
Eugene Zelenko1660a5d2016-01-26 19:01:06 +00003896 llvm::GlobalValue::ExternalLinkage, /*Initializer=*/nullptr,
Alexey Bataev18fa2322018-05-02 14:20:50 +00003897 EntriesBeginName);
3898 std::string EntriesEndName = getName({"omp_offloading", "entries_end"});
3899 auto *HostEntriesEnd =
3900 new llvm::GlobalVariable(M, OffloadEntryTy, /*isConstant=*/true,
3901 llvm::GlobalValue::ExternalLinkage,
3902 /*Initializer=*/nullptr, EntriesEndName);
Samuel Antaoee8fb302016-01-06 13:42:12 +00003903
3904 // Create all device images
Samuel Antaoee8fb302016-01-06 13:42:12 +00003905 auto *DeviceImageTy = cast<llvm::StructType>(
3906 CGM.getTypes().ConvertTypeForMem(getTgtDeviceImageQTy()));
John McCall23c9dc62016-11-28 22:18:27 +00003907 ConstantInitBuilder DeviceImagesBuilder(CGM);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003908 ConstantArrayBuilder DeviceImagesEntries =
3909 DeviceImagesBuilder.beginArray(DeviceImageTy);
Samuel Antaoee8fb302016-01-06 13:42:12 +00003910
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003911 for (const llvm::Triple &Device : Devices) {
Alexey Bataev03f270c2018-03-30 18:31:07 +00003912 StringRef T = Device.getTriple();
Alexey Bataev18fa2322018-05-02 14:20:50 +00003913 std::string BeginName = getName({"omp_offloading", "img_start", ""});
Samuel Antaoee8fb302016-01-06 13:42:12 +00003914 auto *ImgBegin = new llvm::GlobalVariable(
Alexey Bataev62a4cb02018-07-31 18:27:42 +00003915 M, CGM.Int8Ty, /*isConstant=*/true,
3916 llvm::GlobalValue::ExternalWeakLinkage,
Alexey Bataev18fa2322018-05-02 14:20:50 +00003917 /*Initializer=*/nullptr, Twine(BeginName).concat(T));
3918 std::string EndName = getName({"omp_offloading", "img_end", ""});
Samuel Antaoee8fb302016-01-06 13:42:12 +00003919 auto *ImgEnd = new llvm::GlobalVariable(
Alexey Bataev62a4cb02018-07-31 18:27:42 +00003920 M, CGM.Int8Ty, /*isConstant=*/true,
3921 llvm::GlobalValue::ExternalWeakLinkage,
Alexey Bataev18fa2322018-05-02 14:20:50 +00003922 /*Initializer=*/nullptr, Twine(EndName).concat(T));
Samuel Antaoee8fb302016-01-06 13:42:12 +00003923
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003924 llvm::Constant *Data[] = {ImgBegin, ImgEnd, HostEntriesBegin,
3925 HostEntriesEnd};
3926 createConstantGlobalStructAndAddToParent(CGM, getTgtDeviceImageQTy(), Data,
3927 DeviceImagesEntries);
Samuel Antaoee8fb302016-01-06 13:42:12 +00003928 }
3929
3930 // Create device images global array.
Alexey Bataev18fa2322018-05-02 14:20:50 +00003931 std::string ImagesName = getName({"omp_offloading", "device_images"});
John McCall6c9f1fdb2016-11-19 08:17:24 +00003932 llvm::GlobalVariable *DeviceImages =
Alexey Bataev18fa2322018-05-02 14:20:50 +00003933 DeviceImagesEntries.finishAndCreateGlobal(ImagesName,
3934 CGM.getPointerAlign(),
3935 /*isConstant=*/true);
Peter Collingbournebcf909d2016-06-14 21:02:05 +00003936 DeviceImages->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
Samuel Antaoee8fb302016-01-06 13:42:12 +00003937
3938 // This is a Zero array to be used in the creation of the constant expressions
3939 llvm::Constant *Index[] = {llvm::Constant::getNullValue(CGM.Int32Ty),
3940 llvm::Constant::getNullValue(CGM.Int32Ty)};
3941
3942 // Create the target region descriptor.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003943 llvm::Constant *Data[] = {
3944 llvm::ConstantInt::get(CGM.Int32Ty, Devices.size()),
3945 llvm::ConstantExpr::getGetElementPtr(DeviceImages->getValueType(),
3946 DeviceImages, Index),
3947 HostEntriesBegin, HostEntriesEnd};
Alexey Bataev18fa2322018-05-02 14:20:50 +00003948 std::string Descriptor = getName({"omp_offloading", "descriptor"});
Mike Ricee1ca7b62018-08-29 15:45:11 +00003949 llvm::GlobalVariable *Desc = createGlobalStruct(
3950 CGM, getTgtBinaryDescriptorQTy(), /*IsConstant=*/true, Data, Descriptor);
Samuel Antaoee8fb302016-01-06 13:42:12 +00003951
3952 // Emit code to register or unregister the descriptor at execution
3953 // startup or closing, respectively.
3954
Alexey Bataev03f270c2018-03-30 18:31:07 +00003955 llvm::Function *UnRegFn;
3956 {
3957 FunctionArgList Args;
3958 ImplicitParamDecl DummyPtr(C, C.VoidPtrTy, ImplicitParamDecl::Other);
3959 Args.push_back(&DummyPtr);
Samuel Antaoee8fb302016-01-06 13:42:12 +00003960
Alexey Bataev03f270c2018-03-30 18:31:07 +00003961 CodeGenFunction CGF(CGM);
3962 // Disable debug info for global (de-)initializer because they are not part
3963 // of some particular construct.
3964 CGF.disableDebugInfo();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003965 const auto &FI =
3966 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
3967 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
Alexey Bataev18fa2322018-05-02 14:20:50 +00003968 std::string UnregName = getName({"omp_offloading", "descriptor_unreg"});
3969 UnRegFn = CGM.CreateGlobalInitOrDestructFunction(FTy, UnregName, FI);
Alexey Bataev03f270c2018-03-30 18:31:07 +00003970 CGF.StartFunction(GlobalDecl(), C.VoidTy, UnRegFn, FI, Args);
3971 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__tgt_unregister_lib),
3972 Desc);
3973 CGF.FinishFunction();
3974 }
3975 llvm::Function *RegFn;
3976 {
3977 CodeGenFunction CGF(CGM);
3978 // Disable debug info for global (de-)initializer because they are not part
3979 // of some particular construct.
3980 CGF.disableDebugInfo();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00003981 const auto &FI = CGM.getTypes().arrangeNullaryFunction();
Alexey Bataev03f270c2018-03-30 18:31:07 +00003982 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
Sergey Dmitrievbde9cf92018-08-03 20:19:28 +00003983
3984 // Encode offload target triples into the registration function name. It
3985 // will serve as a comdat key for the registration/unregistration code for
3986 // this particular combination of offloading targets.
3987 SmallVector<StringRef, 4U> RegFnNameParts(Devices.size() + 2U);
3988 RegFnNameParts[0] = "omp_offloading";
3989 RegFnNameParts[1] = "descriptor_reg";
3990 llvm::transform(Devices, std::next(RegFnNameParts.begin(), 2),
3991 [](const llvm::Triple &T) -> const std::string& {
3992 return T.getTriple();
3993 });
3994 llvm::sort(std::next(RegFnNameParts.begin(), 2), RegFnNameParts.end());
3995 std::string Descriptor = getName(RegFnNameParts);
Alexey Bataev18fa2322018-05-02 14:20:50 +00003996 RegFn = CGM.CreateGlobalInitOrDestructFunction(FTy, Descriptor, FI);
Alexey Bataev03f270c2018-03-30 18:31:07 +00003997 CGF.StartFunction(GlobalDecl(), C.VoidTy, RegFn, FI, FunctionArgList());
3998 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__tgt_register_lib), Desc);
3999 // Create a variable to drive the registration and unregistration of the
4000 // descriptor, so we can reuse the logic that emits Ctors and Dtors.
4001 ImplicitParamDecl RegUnregVar(C, C.getTranslationUnitDecl(),
4002 SourceLocation(), nullptr, C.CharTy,
4003 ImplicitParamDecl::Other);
4004 CGM.getCXXABI().registerGlobalDtor(CGF, RegUnregVar, UnRegFn, Desc);
4005 CGF.FinishFunction();
4006 }
George Rokos29d0f002017-05-27 03:03:13 +00004007 if (CGM.supportsCOMDAT()) {
4008 // It is sufficient to call registration function only once, so create a
4009 // COMDAT group for registration/unregistration functions and associated
4010 // data. That would reduce startup time and code size. Registration
4011 // function serves as a COMDAT group key.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004012 llvm::Comdat *ComdatKey = M.getOrInsertComdat(RegFn->getName());
George Rokos29d0f002017-05-27 03:03:13 +00004013 RegFn->setLinkage(llvm::GlobalValue::LinkOnceAnyLinkage);
4014 RegFn->setVisibility(llvm::GlobalValue::HiddenVisibility);
4015 RegFn->setComdat(ComdatKey);
4016 UnRegFn->setComdat(ComdatKey);
4017 DeviceImages->setComdat(ComdatKey);
4018 Desc->setComdat(ComdatKey);
4019 }
Samuel Antaoee8fb302016-01-06 13:42:12 +00004020 return RegFn;
4021}
4022
Alexey Bataev03f270c2018-03-30 18:31:07 +00004023void CGOpenMPRuntime::createOffloadEntry(
4024 llvm::Constant *ID, llvm::Constant *Addr, uint64_t Size, int32_t Flags,
4025 llvm::GlobalValue::LinkageTypes Linkage) {
Samuel Antao2de62b02016-02-13 23:35:10 +00004026 StringRef Name = Addr->getName();
Samuel Antaoee8fb302016-01-06 13:42:12 +00004027 llvm::Module &M = CGM.getModule();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004028 llvm::LLVMContext &C = M.getContext();
Samuel Antaoee8fb302016-01-06 13:42:12 +00004029
4030 // Create constant string with the name.
4031 llvm::Constant *StrPtrInit = llvm::ConstantDataArray::getString(C, Name);
4032
Alexey Bataev18fa2322018-05-02 14:20:50 +00004033 std::string StringName = getName({"omp_offloading", "entry_name"});
4034 auto *Str = new llvm::GlobalVariable(
4035 M, StrPtrInit->getType(), /*isConstant=*/true,
4036 llvm::GlobalValue::InternalLinkage, StrPtrInit, StringName);
Peter Collingbournebcf909d2016-06-14 21:02:05 +00004037 Str->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
Samuel Antaoee8fb302016-01-06 13:42:12 +00004038
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004039 llvm::Constant *Data[] = {llvm::ConstantExpr::getBitCast(ID, CGM.VoidPtrTy),
4040 llvm::ConstantExpr::getBitCast(Str, CGM.Int8PtrTy),
4041 llvm::ConstantInt::get(CGM.SizeTy, Size),
4042 llvm::ConstantInt::get(CGM.Int32Ty, Flags),
4043 llvm::ConstantInt::get(CGM.Int32Ty, 0)};
Alexey Bataev18fa2322018-05-02 14:20:50 +00004044 std::string EntryName = getName({"omp_offloading", "entry", ""});
Mike Ricee1ca7b62018-08-29 15:45:11 +00004045 llvm::GlobalVariable *Entry = createGlobalStruct(
4046 CGM, getTgtOffloadEntryQTy(), /*IsConstant=*/true, Data,
4047 Twine(EntryName).concat(Name), llvm::GlobalValue::WeakAnyLinkage);
Samuel Antaoee8fb302016-01-06 13:42:12 +00004048
4049 // The entry has to be created in the section the linker expects it to be.
Alexey Bataev18fa2322018-05-02 14:20:50 +00004050 std::string Section = getName({"omp_offloading", "entries"});
4051 Entry->setSection(Section);
Samuel Antaoee8fb302016-01-06 13:42:12 +00004052}
4053
4054void CGOpenMPRuntime::createOffloadEntriesAndInfoMetadata() {
4055 // Emit the offloading entries and metadata so that the device codegen side
Samuel Antao4c8035b2016-12-12 18:00:20 +00004056 // can easily figure out what to emit. The produced metadata looks like
4057 // this:
Samuel Antaoee8fb302016-01-06 13:42:12 +00004058 //
4059 // !omp_offload.info = !{!1, ...}
4060 //
4061 // Right now we only generate metadata for function that contain target
4062 // regions.
4063
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +00004064 // If we do not have entries, we don't need to do anything.
Samuel Antaoee8fb302016-01-06 13:42:12 +00004065 if (OffloadEntriesInfoManager.empty())
4066 return;
4067
4068 llvm::Module &M = CGM.getModule();
4069 llvm::LLVMContext &C = M.getContext();
Alexey Bataev03f270c2018-03-30 18:31:07 +00004070 SmallVector<const OffloadEntriesInfoManagerTy::OffloadEntryInfo *, 16>
Samuel Antaoee8fb302016-01-06 13:42:12 +00004071 OrderedEntries(OffloadEntriesInfoManager.size());
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00004072 llvm::SmallVector<StringRef, 16> ParentFunctions(
4073 OffloadEntriesInfoManager.size());
Samuel Antaoee8fb302016-01-06 13:42:12 +00004074
Simon Pilgrim2c518802017-03-30 14:13:19 +00004075 // Auxiliary methods to create metadata values and strings.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004076 auto &&GetMDInt = [this](unsigned V) {
Samuel Antaoee8fb302016-01-06 13:42:12 +00004077 return llvm::ConstantAsMetadata::get(
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004078 llvm::ConstantInt::get(CGM.Int32Ty, V));
Samuel Antaoee8fb302016-01-06 13:42:12 +00004079 };
4080
Alexey Bataev03f270c2018-03-30 18:31:07 +00004081 auto &&GetMDString = [&C](StringRef V) { return llvm::MDString::get(C, V); };
4082
4083 // Create the offloading info metadata node.
4084 llvm::NamedMDNode *MD = M.getOrInsertNamedMetadata("omp_offload.info");
Samuel Antaoee8fb302016-01-06 13:42:12 +00004085
4086 // Create function that emits metadata for each target region entry;
Alexey Bataev03f270c2018-03-30 18:31:07 +00004087 auto &&TargetRegionMetadataEmitter =
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00004088 [&C, MD, &OrderedEntries, &ParentFunctions, &GetMDInt, &GetMDString](
Alexey Bataev03f270c2018-03-30 18:31:07 +00004089 unsigned DeviceID, unsigned FileID, StringRef ParentName,
4090 unsigned Line,
4091 const OffloadEntriesInfoManagerTy::OffloadEntryInfoTargetRegion &E) {
4092 // Generate metadata for target regions. Each entry of this metadata
4093 // contains:
4094 // - Entry 0 -> Kind of this type of metadata (0).
4095 // - Entry 1 -> Device ID of the file where the entry was identified.
4096 // - Entry 2 -> File ID of the file where the entry was identified.
4097 // - Entry 3 -> Mangled name of the function where the entry was
4098 // identified.
4099 // - Entry 4 -> Line in the file where the entry was identified.
4100 // - Entry 5 -> Order the entry was created.
4101 // The first element of the metadata node is the kind.
4102 llvm::Metadata *Ops[] = {GetMDInt(E.getKind()), GetMDInt(DeviceID),
4103 GetMDInt(FileID), GetMDString(ParentName),
4104 GetMDInt(Line), GetMDInt(E.getOrder())};
Samuel Antaoee8fb302016-01-06 13:42:12 +00004105
Alexey Bataev03f270c2018-03-30 18:31:07 +00004106 // Save this entry in the right position of the ordered entries array.
4107 OrderedEntries[E.getOrder()] = &E;
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00004108 ParentFunctions[E.getOrder()] = ParentName;
Samuel Antaoee8fb302016-01-06 13:42:12 +00004109
Alexey Bataev03f270c2018-03-30 18:31:07 +00004110 // Add metadata to the named metadata node.
4111 MD->addOperand(llvm::MDNode::get(C, Ops));
4112 };
Samuel Antaoee8fb302016-01-06 13:42:12 +00004113
4114 OffloadEntriesInfoManager.actOnTargetRegionEntriesInfo(
4115 TargetRegionMetadataEmitter);
4116
Alexey Bataev03f270c2018-03-30 18:31:07 +00004117 // Create function that emits metadata for each device global variable entry;
4118 auto &&DeviceGlobalVarMetadataEmitter =
4119 [&C, &OrderedEntries, &GetMDInt, &GetMDString,
4120 MD](StringRef MangledName,
4121 const OffloadEntriesInfoManagerTy::OffloadEntryInfoDeviceGlobalVar
4122 &E) {
4123 // Generate metadata for global variables. Each entry of this metadata
4124 // contains:
4125 // - Entry 0 -> Kind of this type of metadata (1).
4126 // - Entry 1 -> Mangled name of the variable.
4127 // - Entry 2 -> Declare target kind.
4128 // - Entry 3 -> Order the entry was created.
4129 // The first element of the metadata node is the kind.
4130 llvm::Metadata *Ops[] = {
4131 GetMDInt(E.getKind()), GetMDString(MangledName),
4132 GetMDInt(E.getFlags()), GetMDInt(E.getOrder())};
4133
4134 // Save this entry in the right position of the ordered entries array.
4135 OrderedEntries[E.getOrder()] = &E;
4136
4137 // Add metadata to the named metadata node.
4138 MD->addOperand(llvm::MDNode::get(C, Ops));
4139 };
4140
4141 OffloadEntriesInfoManager.actOnDeviceGlobalVarEntriesInfo(
4142 DeviceGlobalVarMetadataEmitter);
4143
4144 for (const auto *E : OrderedEntries) {
Samuel Antaoee8fb302016-01-06 13:42:12 +00004145 assert(E && "All ordered entries must exist!");
Alexey Bataev03f270c2018-03-30 18:31:07 +00004146 if (const auto *CE =
Samuel Antaoee8fb302016-01-06 13:42:12 +00004147 dyn_cast<OffloadEntriesInfoManagerTy::OffloadEntryInfoTargetRegion>(
4148 E)) {
Alexey Bataev64e62dc2018-04-30 16:26:57 +00004149 if (!CE->getID() || !CE->getAddress()) {
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00004150 // Do not blame the entry if the parent funtion is not emitted.
4151 StringRef FnName = ParentFunctions[CE->getOrder()];
4152 if (!CGM.GetGlobalValue(FnName))
4153 continue;
Alexey Bataev64e62dc2018-04-30 16:26:57 +00004154 unsigned DiagID = CGM.getDiags().getCustomDiagID(
4155 DiagnosticsEngine::Error,
Alexey Bataev7f01d202018-07-16 18:12:18 +00004156 "Offloading entry for target region is incorrect: either the "
Alexey Bataev64e62dc2018-04-30 16:26:57 +00004157 "address or the ID is invalid.");
4158 CGM.getDiags().Report(DiagID);
4159 continue;
4160 }
Alexey Bataev34f8a702018-03-28 14:28:54 +00004161 createOffloadEntry(CE->getID(), CE->getAddress(), /*Size=*/0,
Alexey Bataev03f270c2018-03-30 18:31:07 +00004162 CE->getFlags(), llvm::GlobalValue::WeakAnyLinkage);
4163 } else if (const auto *CE =
4164 dyn_cast<OffloadEntriesInfoManagerTy::
4165 OffloadEntryInfoDeviceGlobalVar>(E)) {
Alexey Bataevc52f01d2018-07-16 20:05:25 +00004166 OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind Flags =
4167 static_cast<OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind>(
4168 CE->getFlags());
4169 switch (Flags) {
4170 case OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryTo: {
4171 if (!CE->getAddress()) {
4172 unsigned DiagID = CGM.getDiags().getCustomDiagID(
4173 DiagnosticsEngine::Error,
4174 "Offloading entry for declare target variable is incorrect: the "
4175 "address is invalid.");
4176 CGM.getDiags().Report(DiagID);
4177 continue;
4178 }
Alexey Bataevb4dd6d22018-08-29 20:41:37 +00004179 // The vaiable has no definition - no need to add the entry.
4180 if (CE->getVarSize().isZero())
4181 continue;
Alexey Bataevc52f01d2018-07-16 20:05:25 +00004182 break;
4183 }
4184 case OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryLink:
4185 assert(((CGM.getLangOpts().OpenMPIsDevice && !CE->getAddress()) ||
4186 (!CGM.getLangOpts().OpenMPIsDevice && CE->getAddress())) &&
4187 "Declaret target link address is set.");
4188 if (CGM.getLangOpts().OpenMPIsDevice)
4189 continue;
4190 if (!CE->getAddress()) {
4191 unsigned DiagID = CGM.getDiags().getCustomDiagID(
4192 DiagnosticsEngine::Error,
4193 "Offloading entry for declare target variable is incorrect: the "
4194 "address is invalid.");
4195 CGM.getDiags().Report(DiagID);
4196 continue;
4197 }
4198 break;
Alexey Bataev64e62dc2018-04-30 16:26:57 +00004199 }
Alexey Bataev03f270c2018-03-30 18:31:07 +00004200 createOffloadEntry(CE->getAddress(), CE->getAddress(),
Alexey Bataevc52f01d2018-07-16 20:05:25 +00004201 CE->getVarSize().getQuantity(), Flags,
Alexey Bataev03f270c2018-03-30 18:31:07 +00004202 CE->getLinkage());
4203 } else {
Samuel Antaoee8fb302016-01-06 13:42:12 +00004204 llvm_unreachable("Unsupported entry kind.");
Alexey Bataev03f270c2018-03-30 18:31:07 +00004205 }
Samuel Antaoee8fb302016-01-06 13:42:12 +00004206 }
4207}
4208
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004209/// Loads all the offload entries information from the host IR
Samuel Antaoee8fb302016-01-06 13:42:12 +00004210/// metadata.
4211void CGOpenMPRuntime::loadOffloadInfoMetadata() {
4212 // If we are in target mode, load the metadata from the host IR. This code has
4213 // to match the metadaata creation in createOffloadEntriesAndInfoMetadata().
4214
4215 if (!CGM.getLangOpts().OpenMPIsDevice)
4216 return;
4217
4218 if (CGM.getLangOpts().OMPHostIRFile.empty())
4219 return;
4220
4221 auto Buf = llvm::MemoryBuffer::getFile(CGM.getLangOpts().OMPHostIRFile);
Alexey Bataev64e62dc2018-04-30 16:26:57 +00004222 if (auto EC = Buf.getError()) {
4223 CGM.getDiags().Report(diag::err_cannot_open_file)
4224 << CGM.getLangOpts().OMPHostIRFile << EC.message();
Samuel Antaoee8fb302016-01-06 13:42:12 +00004225 return;
Alexey Bataev64e62dc2018-04-30 16:26:57 +00004226 }
Samuel Antaoee8fb302016-01-06 13:42:12 +00004227
4228 llvm::LLVMContext C;
Peter Collingbourned9445c42016-11-13 07:00:17 +00004229 auto ME = expectedToErrorOrAndEmitErrors(
4230 C, llvm::parseBitcodeFile(Buf.get()->getMemBufferRef(), C));
Samuel Antaoee8fb302016-01-06 13:42:12 +00004231
Alexey Bataev64e62dc2018-04-30 16:26:57 +00004232 if (auto EC = ME.getError()) {
4233 unsigned DiagID = CGM.getDiags().getCustomDiagID(
4234 DiagnosticsEngine::Error, "Unable to parse host IR file '%0':'%1'");
4235 CGM.getDiags().Report(DiagID)
4236 << CGM.getLangOpts().OMPHostIRFile << EC.message();
Samuel Antaoee8fb302016-01-06 13:42:12 +00004237 return;
Alexey Bataev64e62dc2018-04-30 16:26:57 +00004238 }
Samuel Antaoee8fb302016-01-06 13:42:12 +00004239
4240 llvm::NamedMDNode *MD = ME.get()->getNamedMetadata("omp_offload.info");
4241 if (!MD)
4242 return;
4243
George Burgess IV00f70bd2018-03-01 05:43:23 +00004244 for (llvm::MDNode *MN : MD->operands()) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004245 auto &&GetMDInt = [MN](unsigned Idx) {
4246 auto *V = cast<llvm::ConstantAsMetadata>(MN->getOperand(Idx));
Samuel Antaoee8fb302016-01-06 13:42:12 +00004247 return cast<llvm::ConstantInt>(V->getValue())->getZExtValue();
4248 };
4249
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004250 auto &&GetMDString = [MN](unsigned Idx) {
4251 auto *V = cast<llvm::MDString>(MN->getOperand(Idx));
Samuel Antaoee8fb302016-01-06 13:42:12 +00004252 return V->getString();
4253 };
4254
Alexey Bataev03f270c2018-03-30 18:31:07 +00004255 switch (GetMDInt(0)) {
Samuel Antaoee8fb302016-01-06 13:42:12 +00004256 default:
4257 llvm_unreachable("Unexpected metadata!");
4258 break;
4259 case OffloadEntriesInfoManagerTy::OffloadEntryInfo::
Alexey Bataev34f8a702018-03-28 14:28:54 +00004260 OffloadingEntryInfoTargetRegion:
Samuel Antaoee8fb302016-01-06 13:42:12 +00004261 OffloadEntriesInfoManager.initializeTargetRegionEntryInfo(
Alexey Bataev03f270c2018-03-30 18:31:07 +00004262 /*DeviceID=*/GetMDInt(1), /*FileID=*/GetMDInt(2),
4263 /*ParentName=*/GetMDString(3), /*Line=*/GetMDInt(4),
4264 /*Order=*/GetMDInt(5));
4265 break;
4266 case OffloadEntriesInfoManagerTy::OffloadEntryInfo::
4267 OffloadingEntryInfoDeviceGlobalVar:
4268 OffloadEntriesInfoManager.initializeDeviceGlobalVarEntryInfo(
4269 /*MangledName=*/GetMDString(1),
4270 static_cast<OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind>(
4271 /*Flags=*/GetMDInt(2)),
4272 /*Order=*/GetMDInt(3));
Samuel Antaoee8fb302016-01-06 13:42:12 +00004273 break;
4274 }
4275 }
4276}
4277
Alexey Bataev62b63b12015-03-10 07:28:44 +00004278void CGOpenMPRuntime::emitKmpRoutineEntryT(QualType KmpInt32Ty) {
4279 if (!KmpRoutineEntryPtrTy) {
4280 // Build typedef kmp_int32 (* kmp_routine_entry_t)(kmp_int32, void *); type.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004281 ASTContext &C = CGM.getContext();
Alexey Bataev62b63b12015-03-10 07:28:44 +00004282 QualType KmpRoutineEntryTyArgs[] = {KmpInt32Ty, C.VoidPtrTy};
4283 FunctionProtoType::ExtProtoInfo EPI;
4284 KmpRoutineEntryPtrQTy = C.getPointerType(
4285 C.getFunctionType(KmpInt32Ty, KmpRoutineEntryTyArgs, EPI));
4286 KmpRoutineEntryPtrTy = CGM.getTypes().ConvertType(KmpRoutineEntryPtrQTy);
4287 }
4288}
4289
Samuel Antaoee8fb302016-01-06 13:42:12 +00004290QualType CGOpenMPRuntime::getTgtOffloadEntryQTy() {
Samuel Antaoee8fb302016-01-06 13:42:12 +00004291 // Make sure the type of the entry is already created. This is the type we
4292 // have to create:
4293 // struct __tgt_offload_entry{
4294 // void *addr; // Pointer to the offload entry info.
4295 // // (function or global)
4296 // char *name; // Name of the function or global.
4297 // size_t size; // Size of the entry info (0 if it a function).
Samuel Antaof83efdb2017-01-05 16:02:49 +00004298 // int32_t flags; // Flags associated with the entry, e.g. 'link'.
4299 // int32_t reserved; // Reserved, to use by the runtime library.
Samuel Antaoee8fb302016-01-06 13:42:12 +00004300 // };
4301 if (TgtOffloadEntryQTy.isNull()) {
4302 ASTContext &C = CGM.getContext();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004303 RecordDecl *RD = C.buildImplicitRecord("__tgt_offload_entry");
Samuel Antaoee8fb302016-01-06 13:42:12 +00004304 RD->startDefinition();
4305 addFieldToRecordDecl(C, RD, C.VoidPtrTy);
4306 addFieldToRecordDecl(C, RD, C.getPointerType(C.CharTy));
4307 addFieldToRecordDecl(C, RD, C.getSizeType());
Samuel Antaof83efdb2017-01-05 16:02:49 +00004308 addFieldToRecordDecl(
4309 C, RD, C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/true));
4310 addFieldToRecordDecl(
4311 C, RD, C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/true));
Samuel Antaoee8fb302016-01-06 13:42:12 +00004312 RD->completeDefinition();
Jonas Hahnfeld5e4df282018-01-18 15:38:03 +00004313 RD->addAttr(PackedAttr::CreateImplicit(C));
Samuel Antaoee8fb302016-01-06 13:42:12 +00004314 TgtOffloadEntryQTy = C.getRecordType(RD);
4315 }
4316 return TgtOffloadEntryQTy;
4317}
4318
4319QualType CGOpenMPRuntime::getTgtDeviceImageQTy() {
4320 // These are the types we need to build:
4321 // struct __tgt_device_image{
4322 // void *ImageStart; // Pointer to the target code start.
4323 // void *ImageEnd; // Pointer to the target code end.
4324 // // We also add the host entries to the device image, as it may be useful
4325 // // for the target runtime to have access to that information.
4326 // __tgt_offload_entry *EntriesBegin; // Begin of the table with all
4327 // // the entries.
4328 // __tgt_offload_entry *EntriesEnd; // End of the table with all the
4329 // // entries (non inclusive).
4330 // };
4331 if (TgtDeviceImageQTy.isNull()) {
4332 ASTContext &C = CGM.getContext();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004333 RecordDecl *RD = C.buildImplicitRecord("__tgt_device_image");
Samuel Antaoee8fb302016-01-06 13:42:12 +00004334 RD->startDefinition();
4335 addFieldToRecordDecl(C, RD, C.VoidPtrTy);
4336 addFieldToRecordDecl(C, RD, C.VoidPtrTy);
4337 addFieldToRecordDecl(C, RD, C.getPointerType(getTgtOffloadEntryQTy()));
4338 addFieldToRecordDecl(C, RD, C.getPointerType(getTgtOffloadEntryQTy()));
4339 RD->completeDefinition();
4340 TgtDeviceImageQTy = C.getRecordType(RD);
4341 }
4342 return TgtDeviceImageQTy;
4343}
4344
4345QualType CGOpenMPRuntime::getTgtBinaryDescriptorQTy() {
4346 // struct __tgt_bin_desc{
4347 // int32_t NumDevices; // Number of devices supported.
4348 // __tgt_device_image *DeviceImages; // Arrays of device images
4349 // // (one per device).
4350 // __tgt_offload_entry *EntriesBegin; // Begin of the table with all the
4351 // // entries.
4352 // __tgt_offload_entry *EntriesEnd; // End of the table with all the
4353 // // entries (non inclusive).
4354 // };
4355 if (TgtBinaryDescriptorQTy.isNull()) {
4356 ASTContext &C = CGM.getContext();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004357 RecordDecl *RD = C.buildImplicitRecord("__tgt_bin_desc");
Samuel Antaoee8fb302016-01-06 13:42:12 +00004358 RD->startDefinition();
4359 addFieldToRecordDecl(
4360 C, RD, C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/true));
4361 addFieldToRecordDecl(C, RD, C.getPointerType(getTgtDeviceImageQTy()));
4362 addFieldToRecordDecl(C, RD, C.getPointerType(getTgtOffloadEntryQTy()));
4363 addFieldToRecordDecl(C, RD, C.getPointerType(getTgtOffloadEntryQTy()));
4364 RD->completeDefinition();
4365 TgtBinaryDescriptorQTy = C.getRecordType(RD);
4366 }
4367 return TgtBinaryDescriptorQTy;
4368}
4369
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004370namespace {
Alexey Bataev9e034042015-05-05 04:05:12 +00004371struct PrivateHelpersTy {
4372 PrivateHelpersTy(const VarDecl *Original, const VarDecl *PrivateCopy,
4373 const VarDecl *PrivateElemInit)
4374 : Original(Original), PrivateCopy(PrivateCopy),
4375 PrivateElemInit(PrivateElemInit) {}
4376 const VarDecl *Original;
4377 const VarDecl *PrivateCopy;
4378 const VarDecl *PrivateElemInit;
4379};
4380typedef std::pair<CharUnits /*Align*/, PrivateHelpersTy> PrivateDataTy;
Hans Wennborg7eb54642015-09-10 17:07:54 +00004381} // anonymous namespace
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004382
Alexey Bataev9e034042015-05-05 04:05:12 +00004383static RecordDecl *
Craig Topper8674c5c2015-09-29 04:30:07 +00004384createPrivatesRecordDecl(CodeGenModule &CGM, ArrayRef<PrivateDataTy> Privates) {
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004385 if (!Privates.empty()) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004386 ASTContext &C = CGM.getContext();
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004387 // Build struct .kmp_privates_t. {
4388 // /* private vars */
4389 // };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004390 RecordDecl *RD = C.buildImplicitRecord(".kmp_privates.t");
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004391 RD->startDefinition();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004392 for (const auto &Pair : Privates) {
4393 const VarDecl *VD = Pair.second.Original;
4394 QualType Type = VD->getType().getNonReferenceType();
4395 FieldDecl *FD = addFieldToRecordDecl(C, RD, Type);
Alexey Bataevc71a4092015-09-11 10:29:41 +00004396 if (VD->hasAttrs()) {
4397 for (specific_attr_iterator<AlignedAttr> I(VD->getAttrs().begin()),
4398 E(VD->getAttrs().end());
4399 I != E; ++I)
4400 FD->addAttr(*I);
4401 }
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004402 }
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004403 RD->completeDefinition();
4404 return RD;
4405 }
4406 return nullptr;
4407}
4408
Alexey Bataev9e034042015-05-05 04:05:12 +00004409static RecordDecl *
Alexey Bataev7292c292016-04-25 12:22:29 +00004410createKmpTaskTRecordDecl(CodeGenModule &CGM, OpenMPDirectiveKind Kind,
4411 QualType KmpInt32Ty,
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00004412 QualType KmpRoutineEntryPointerQTy) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004413 ASTContext &C = CGM.getContext();
Alexey Bataev62b63b12015-03-10 07:28:44 +00004414 // Build struct kmp_task_t {
4415 // void * shareds;
4416 // kmp_routine_entry_t routine;
4417 // kmp_int32 part_id;
Alexey Bataevad537bb2016-05-30 09:06:50 +00004418 // kmp_cmplrdata_t data1;
4419 // kmp_cmplrdata_t data2;
Alexey Bataev7292c292016-04-25 12:22:29 +00004420 // For taskloops additional fields:
4421 // kmp_uint64 lb;
4422 // kmp_uint64 ub;
4423 // kmp_int64 st;
4424 // kmp_int32 liter;
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00004425 // void * reductions;
Alexey Bataev62b63b12015-03-10 07:28:44 +00004426 // };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004427 RecordDecl *UD = C.buildImplicitRecord("kmp_cmplrdata_t", TTK_Union);
Alexey Bataevad537bb2016-05-30 09:06:50 +00004428 UD->startDefinition();
4429 addFieldToRecordDecl(C, UD, KmpInt32Ty);
4430 addFieldToRecordDecl(C, UD, KmpRoutineEntryPointerQTy);
4431 UD->completeDefinition();
4432 QualType KmpCmplrdataTy = C.getRecordType(UD);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004433 RecordDecl *RD = C.buildImplicitRecord("kmp_task_t");
Alexey Bataev62b63b12015-03-10 07:28:44 +00004434 RD->startDefinition();
4435 addFieldToRecordDecl(C, RD, C.VoidPtrTy);
4436 addFieldToRecordDecl(C, RD, KmpRoutineEntryPointerQTy);
4437 addFieldToRecordDecl(C, RD, KmpInt32Ty);
Alexey Bataevad537bb2016-05-30 09:06:50 +00004438 addFieldToRecordDecl(C, RD, KmpCmplrdataTy);
4439 addFieldToRecordDecl(C, RD, KmpCmplrdataTy);
Alexey Bataev7292c292016-04-25 12:22:29 +00004440 if (isOpenMPTaskLoopDirective(Kind)) {
4441 QualType KmpUInt64Ty =
4442 CGM.getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
4443 QualType KmpInt64Ty =
4444 CGM.getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
4445 addFieldToRecordDecl(C, RD, KmpUInt64Ty);
4446 addFieldToRecordDecl(C, RD, KmpUInt64Ty);
4447 addFieldToRecordDecl(C, RD, KmpInt64Ty);
4448 addFieldToRecordDecl(C, RD, KmpInt32Ty);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00004449 addFieldToRecordDecl(C, RD, C.VoidPtrTy);
Alexey Bataev7292c292016-04-25 12:22:29 +00004450 }
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00004451 RD->completeDefinition();
4452 return RD;
4453}
4454
4455static RecordDecl *
4456createKmpTaskTWithPrivatesRecordDecl(CodeGenModule &CGM, QualType KmpTaskTQTy,
Craig Topper8674c5c2015-09-29 04:30:07 +00004457 ArrayRef<PrivateDataTy> Privates) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004458 ASTContext &C = CGM.getContext();
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00004459 // Build struct kmp_task_t_with_privates {
4460 // kmp_task_t task_data;
4461 // .kmp_privates_t. privates;
4462 // };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004463 RecordDecl *RD = C.buildImplicitRecord("kmp_task_t_with_privates");
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00004464 RD->startDefinition();
4465 addFieldToRecordDecl(C, RD, KmpTaskTQTy);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004466 if (const RecordDecl *PrivateRD = createPrivatesRecordDecl(CGM, Privates))
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004467 addFieldToRecordDecl(C, RD, C.getRecordType(PrivateRD));
Alexey Bataev62b63b12015-03-10 07:28:44 +00004468 RD->completeDefinition();
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004469 return RD;
Alexey Bataev62b63b12015-03-10 07:28:44 +00004470}
4471
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004472/// Emit a proxy function which accepts kmp_task_t as the second
Alexey Bataev62b63b12015-03-10 07:28:44 +00004473/// argument.
4474/// \code
4475/// kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
Alexey Bataev48591dd2016-04-20 04:01:36 +00004476/// TaskFunction(gtid, tt->part_id, &tt->privates, task_privates_map, tt,
Alexey Bataev7292c292016-04-25 12:22:29 +00004477/// For taskloops:
4478/// tt->task_data.lb, tt->task_data.ub, tt->task_data.st, tt->task_data.liter,
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00004479/// tt->reductions, tt->shareds);
Alexey Bataev62b63b12015-03-10 07:28:44 +00004480/// return 0;
4481/// }
4482/// \endcode
James Y Knight9871db02019-02-05 16:42:33 +00004483static llvm::Function *
Alexey Bataev62b63b12015-03-10 07:28:44 +00004484emitProxyTaskFunction(CodeGenModule &CGM, SourceLocation Loc,
Alexey Bataev7292c292016-04-25 12:22:29 +00004485 OpenMPDirectiveKind Kind, QualType KmpInt32Ty,
4486 QualType KmpTaskTWithPrivatesPtrQTy,
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00004487 QualType KmpTaskTWithPrivatesQTy, QualType KmpTaskTQTy,
James Y Knight9871db02019-02-05 16:42:33 +00004488 QualType SharedsPtrTy, llvm::Function *TaskFunction,
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004489 llvm::Value *TaskPrivatesMap) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004490 ASTContext &C = CGM.getContext();
Alexey Bataev62b63b12015-03-10 07:28:44 +00004491 FunctionArgList Args;
Alexey Bataev56223232017-06-09 13:40:18 +00004492 ImplicitParamDecl GtidArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, KmpInt32Ty,
4493 ImplicitParamDecl::Other);
4494 ImplicitParamDecl TaskTypeArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4495 KmpTaskTWithPrivatesPtrQTy.withRestrict(),
4496 ImplicitParamDecl::Other);
Alexey Bataev62b63b12015-03-10 07:28:44 +00004497 Args.push_back(&GtidArg);
4498 Args.push_back(&TaskTypeArg);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004499 const auto &TaskEntryFnInfo =
John McCallc56a8b32016-03-11 04:30:31 +00004500 CGM.getTypes().arrangeBuiltinFunctionDeclaration(KmpInt32Ty, Args);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004501 llvm::FunctionType *TaskEntryTy =
4502 CGM.getTypes().GetFunctionType(TaskEntryFnInfo);
Alexey Bataev18fa2322018-05-02 14:20:50 +00004503 std::string Name = CGM.getOpenMPRuntime().getName({"omp_task_entry", ""});
4504 auto *TaskEntry = llvm::Function::Create(
4505 TaskEntryTy, llvm::GlobalValue::InternalLinkage, Name, &CGM.getModule());
Rafael Espindola51ec5a92018-02-28 23:46:35 +00004506 CGM.SetInternalFunctionAttributes(GlobalDecl(), TaskEntry, TaskEntryFnInfo);
Alexey Bataevc0f879b2018-04-10 20:10:53 +00004507 TaskEntry->setDoesNotRecurse();
Alexey Bataev62b63b12015-03-10 07:28:44 +00004508 CodeGenFunction CGF(CGM);
Alexey Bataev7cae94e2018-01-04 19:45:16 +00004509 CGF.StartFunction(GlobalDecl(), KmpInt32Ty, TaskEntry, TaskEntryFnInfo, Args,
4510 Loc, Loc);
Alexey Bataev62b63b12015-03-10 07:28:44 +00004511
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004512 // TaskFunction(gtid, tt->task_data.part_id, &tt->privates, task_privates_map,
Alexey Bataev7292c292016-04-25 12:22:29 +00004513 // tt,
4514 // For taskloops:
4515 // tt->task_data.lb, tt->task_data.ub, tt->task_data.st, tt->task_data.liter,
4516 // tt->task_data.shareds);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004517 llvm::Value *GtidParam = CGF.EmitLoadOfScalar(
John McCall7f416cc2015-09-08 08:05:57 +00004518 CGF.GetAddrOfLocalVar(&GtidArg), /*Volatile=*/false, KmpInt32Ty, Loc);
Alexey Bataev31300ed2016-02-04 11:27:03 +00004519 LValue TDBase = CGF.EmitLoadOfPointerLValue(
4520 CGF.GetAddrOfLocalVar(&TaskTypeArg),
4521 KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004522 const auto *KmpTaskTWithPrivatesQTyRD =
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00004523 cast<RecordDecl>(KmpTaskTWithPrivatesQTy->getAsTagDecl());
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004524 LValue Base =
4525 CGF.EmitLValueForField(TDBase, *KmpTaskTWithPrivatesQTyRD->field_begin());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004526 const auto *KmpTaskTQTyRD = cast<RecordDecl>(KmpTaskTQTy->getAsTagDecl());
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00004527 auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004528 LValue PartIdLVal = CGF.EmitLValueForField(Base, *PartIdFI);
4529 llvm::Value *PartidParam = PartIdLVal.getPointer();
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00004530
4531 auto SharedsFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTShareds);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004532 LValue SharedsLVal = CGF.EmitLValueForField(Base, *SharedsFI);
4533 llvm::Value *SharedsParam = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
Alexey Bataev1e491372018-01-23 18:44:14 +00004534 CGF.EmitLoadOfScalar(SharedsLVal, Loc),
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004535 CGF.ConvertTypeForMem(SharedsPtrTy));
4536
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004537 auto PrivatesFI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin(), 1);
4538 llvm::Value *PrivatesParam;
4539 if (PrivatesFI != KmpTaskTWithPrivatesQTyRD->field_end()) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004540 LValue PrivatesLVal = CGF.EmitLValueForField(TDBase, *PrivatesFI);
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004541 PrivatesParam = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
John McCall7f416cc2015-09-08 08:05:57 +00004542 PrivatesLVal.getPointer(), CGF.VoidPtrTy);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004543 } else {
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004544 PrivatesParam = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004545 }
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004546
Alexey Bataev7292c292016-04-25 12:22:29 +00004547 llvm::Value *CommonArgs[] = {GtidParam, PartidParam, PrivatesParam,
4548 TaskPrivatesMap,
4549 CGF.Builder
4550 .CreatePointerBitCastOrAddrSpaceCast(
4551 TDBase.getAddress(), CGF.VoidPtrTy)
4552 .getPointer()};
4553 SmallVector<llvm::Value *, 16> CallArgs(std::begin(CommonArgs),
4554 std::end(CommonArgs));
4555 if (isOpenMPTaskLoopDirective(Kind)) {
4556 auto LBFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLowerBound);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004557 LValue LBLVal = CGF.EmitLValueForField(Base, *LBFI);
4558 llvm::Value *LBParam = CGF.EmitLoadOfScalar(LBLVal, Loc);
Alexey Bataev7292c292016-04-25 12:22:29 +00004559 auto UBFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTUpperBound);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004560 LValue UBLVal = CGF.EmitLValueForField(Base, *UBFI);
4561 llvm::Value *UBParam = CGF.EmitLoadOfScalar(UBLVal, Loc);
Alexey Bataev7292c292016-04-25 12:22:29 +00004562 auto StFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTStride);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004563 LValue StLVal = CGF.EmitLValueForField(Base, *StFI);
4564 llvm::Value *StParam = CGF.EmitLoadOfScalar(StLVal, Loc);
Alexey Bataev7292c292016-04-25 12:22:29 +00004565 auto LIFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLastIter);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004566 LValue LILVal = CGF.EmitLValueForField(Base, *LIFI);
4567 llvm::Value *LIParam = CGF.EmitLoadOfScalar(LILVal, Loc);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00004568 auto RFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTReductions);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004569 LValue RLVal = CGF.EmitLValueForField(Base, *RFI);
4570 llvm::Value *RParam = CGF.EmitLoadOfScalar(RLVal, Loc);
Alexey Bataev7292c292016-04-25 12:22:29 +00004571 CallArgs.push_back(LBParam);
4572 CallArgs.push_back(UBParam);
4573 CallArgs.push_back(StParam);
4574 CallArgs.push_back(LIParam);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00004575 CallArgs.push_back(RParam);
Alexey Bataev7292c292016-04-25 12:22:29 +00004576 }
4577 CallArgs.push_back(SharedsParam);
4578
Alexey Bataev3c595a62017-08-14 15:01:03 +00004579 CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, Loc, TaskFunction,
4580 CallArgs);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004581 CGF.EmitStoreThroughLValue(RValue::get(CGF.Builder.getInt32(/*C=*/0)),
4582 CGF.MakeAddrLValue(CGF.ReturnValue, KmpInt32Ty));
Alexey Bataev62b63b12015-03-10 07:28:44 +00004583 CGF.FinishFunction();
4584 return TaskEntry;
4585}
4586
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00004587static llvm::Value *emitDestructorsFunction(CodeGenModule &CGM,
4588 SourceLocation Loc,
4589 QualType KmpInt32Ty,
4590 QualType KmpTaskTWithPrivatesPtrQTy,
4591 QualType KmpTaskTWithPrivatesQTy) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004592 ASTContext &C = CGM.getContext();
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004593 FunctionArgList Args;
Alexey Bataev56223232017-06-09 13:40:18 +00004594 ImplicitParamDecl GtidArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, KmpInt32Ty,
4595 ImplicitParamDecl::Other);
4596 ImplicitParamDecl TaskTypeArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4597 KmpTaskTWithPrivatesPtrQTy.withRestrict(),
4598 ImplicitParamDecl::Other);
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004599 Args.push_back(&GtidArg);
4600 Args.push_back(&TaskTypeArg);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004601 const auto &DestructorFnInfo =
John McCallc56a8b32016-03-11 04:30:31 +00004602 CGM.getTypes().arrangeBuiltinFunctionDeclaration(KmpInt32Ty, Args);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004603 llvm::FunctionType *DestructorFnTy =
4604 CGM.getTypes().GetFunctionType(DestructorFnInfo);
Alexey Bataev18fa2322018-05-02 14:20:50 +00004605 std::string Name =
4606 CGM.getOpenMPRuntime().getName({"omp_task_destructor", ""});
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004607 auto *DestructorFn =
4608 llvm::Function::Create(DestructorFnTy, llvm::GlobalValue::InternalLinkage,
Alexey Bataev18fa2322018-05-02 14:20:50 +00004609 Name, &CGM.getModule());
Rafael Espindola51ec5a92018-02-28 23:46:35 +00004610 CGM.SetInternalFunctionAttributes(GlobalDecl(), DestructorFn,
Akira Hatanaka44a59f82015-10-28 02:30:47 +00004611 DestructorFnInfo);
Alexey Bataevc0f879b2018-04-10 20:10:53 +00004612 DestructorFn->setDoesNotRecurse();
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004613 CodeGenFunction CGF(CGM);
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004614 CGF.StartFunction(GlobalDecl(), KmpInt32Ty, DestructorFn, DestructorFnInfo,
Alexey Bataev7cae94e2018-01-04 19:45:16 +00004615 Args, Loc, Loc);
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004616
Alexey Bataev31300ed2016-02-04 11:27:03 +00004617 LValue Base = CGF.EmitLoadOfPointerLValue(
4618 CGF.GetAddrOfLocalVar(&TaskTypeArg),
4619 KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004620 const auto *KmpTaskTWithPrivatesQTyRD =
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00004621 cast<RecordDecl>(KmpTaskTWithPrivatesQTy->getAsTagDecl());
4622 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004623 Base = CGF.EmitLValueForField(Base, *FI);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004624 for (const auto *Field :
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004625 cast<RecordDecl>(FI->getType()->getAsTagDecl())->fields()) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004626 if (QualType::DestructionKind DtorKind =
4627 Field->getType().isDestructedType()) {
4628 LValue FieldLValue = CGF.EmitLValueForField(Base, Field);
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004629 CGF.pushDestroy(DtorKind, FieldLValue.getAddress(), Field->getType());
4630 }
4631 }
4632 CGF.FinishFunction();
4633 return DestructorFn;
4634}
4635
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00004636/// Emit a privates mapping function for correct handling of private and
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004637/// firstprivate variables.
4638/// \code
4639/// void .omp_task_privates_map.(const .privates. *noalias privs, <ty1>
4640/// **noalias priv1,..., <tyn> **noalias privn) {
4641/// *priv1 = &.privates.priv1;
4642/// ...;
4643/// *privn = &.privates.privn;
4644/// }
4645/// \endcode
4646static llvm::Value *
4647emitTaskPrivateMappingFunction(CodeGenModule &CGM, SourceLocation Loc,
Craig Topper8674c5c2015-09-29 04:30:07 +00004648 ArrayRef<const Expr *> PrivateVars,
4649 ArrayRef<const Expr *> FirstprivateVars,
Alexey Bataevf93095a2016-05-05 08:46:22 +00004650 ArrayRef<const Expr *> LastprivateVars,
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004651 QualType PrivatesQTy,
Craig Topper8674c5c2015-09-29 04:30:07 +00004652 ArrayRef<PrivateDataTy> Privates) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004653 ASTContext &C = CGM.getContext();
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004654 FunctionArgList Args;
4655 ImplicitParamDecl TaskPrivatesArg(
4656 C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
Alexey Bataev56223232017-06-09 13:40:18 +00004657 C.getPointerType(PrivatesQTy).withConst().withRestrict(),
4658 ImplicitParamDecl::Other);
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004659 Args.push_back(&TaskPrivatesArg);
4660 llvm::DenseMap<const VarDecl *, unsigned> PrivateVarsPos;
4661 unsigned Counter = 1;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004662 for (const Expr *E : PrivateVars) {
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004663 Args.push_back(ImplicitParamDecl::Create(
Alexey Bataev56223232017-06-09 13:40:18 +00004664 C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4665 C.getPointerType(C.getPointerType(E->getType()))
4666 .withConst()
4667 .withRestrict(),
4668 ImplicitParamDecl::Other));
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004669 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004670 PrivateVarsPos[VD] = Counter;
4671 ++Counter;
4672 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004673 for (const Expr *E : FirstprivateVars) {
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004674 Args.push_back(ImplicitParamDecl::Create(
Alexey Bataev56223232017-06-09 13:40:18 +00004675 C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4676 C.getPointerType(C.getPointerType(E->getType()))
4677 .withConst()
4678 .withRestrict(),
4679 ImplicitParamDecl::Other));
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004680 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004681 PrivateVarsPos[VD] = Counter;
4682 ++Counter;
4683 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004684 for (const Expr *E : LastprivateVars) {
Alexey Bataevf93095a2016-05-05 08:46:22 +00004685 Args.push_back(ImplicitParamDecl::Create(
Alexey Bataev56223232017-06-09 13:40:18 +00004686 C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4687 C.getPointerType(C.getPointerType(E->getType()))
4688 .withConst()
4689 .withRestrict(),
4690 ImplicitParamDecl::Other));
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004691 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataevf93095a2016-05-05 08:46:22 +00004692 PrivateVarsPos[VD] = Counter;
4693 ++Counter;
4694 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004695 const auto &TaskPrivatesMapFnInfo =
John McCallc56a8b32016-03-11 04:30:31 +00004696 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004697 llvm::FunctionType *TaskPrivatesMapTy =
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004698 CGM.getTypes().GetFunctionType(TaskPrivatesMapFnInfo);
Alexey Bataev18fa2322018-05-02 14:20:50 +00004699 std::string Name =
4700 CGM.getOpenMPRuntime().getName({"omp_task_privates_map", ""});
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004701 auto *TaskPrivatesMap = llvm::Function::Create(
Alexey Bataev18fa2322018-05-02 14:20:50 +00004702 TaskPrivatesMapTy, llvm::GlobalValue::InternalLinkage, Name,
4703 &CGM.getModule());
Rafael Espindola51ec5a92018-02-28 23:46:35 +00004704 CGM.SetInternalFunctionAttributes(GlobalDecl(), TaskPrivatesMap,
Akira Hatanaka44a59f82015-10-28 02:30:47 +00004705 TaskPrivatesMapFnInfo);
Alexey Bataev8c5555c2019-05-21 15:11:58 +00004706 if (CGM.getLangOpts().Optimize) {
4707 TaskPrivatesMap->removeFnAttr(llvm::Attribute::NoInline);
4708 TaskPrivatesMap->removeFnAttr(llvm::Attribute::OptimizeNone);
4709 TaskPrivatesMap->addFnAttr(llvm::Attribute::AlwaysInline);
4710 }
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004711 CodeGenFunction CGF(CGM);
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004712 CGF.StartFunction(GlobalDecl(), C.VoidTy, TaskPrivatesMap,
Alexey Bataev7cae94e2018-01-04 19:45:16 +00004713 TaskPrivatesMapFnInfo, Args, Loc, Loc);
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004714
4715 // *privi = &.privates.privi;
Alexey Bataev31300ed2016-02-04 11:27:03 +00004716 LValue Base = CGF.EmitLoadOfPointerLValue(
4717 CGF.GetAddrOfLocalVar(&TaskPrivatesArg),
4718 TaskPrivatesArg.getType()->castAs<PointerType>());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004719 const auto *PrivatesQTyRD = cast<RecordDecl>(PrivatesQTy->getAsTagDecl());
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004720 Counter = 0;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004721 for (const FieldDecl *Field : PrivatesQTyRD->fields()) {
4722 LValue FieldLVal = CGF.EmitLValueForField(Base, Field);
4723 const VarDecl *VD = Args[PrivateVarsPos[Privates[Counter].second.Original]];
4724 LValue RefLVal =
4725 CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(VD), VD->getType());
4726 LValue RefLoadLVal = CGF.EmitLoadOfPointerLValue(
Alexey Bataev31300ed2016-02-04 11:27:03 +00004727 RefLVal.getAddress(), RefLVal.getType()->castAs<PointerType>());
Alexey Bataev2377fe92015-09-10 08:12:02 +00004728 CGF.EmitStoreOfScalar(FieldLVal.getPointer(), RefLoadLVal);
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004729 ++Counter;
4730 }
4731 CGF.FinishFunction();
4732 return TaskPrivatesMap;
4733}
4734
Alexey Bataevf93095a2016-05-05 08:46:22 +00004735/// Emit initialization for private variables in task-based directives.
Alexey Bataev8a831592016-05-10 10:36:51 +00004736static void emitPrivatesInit(CodeGenFunction &CGF,
Alexey Bataevf93095a2016-05-05 08:46:22 +00004737 const OMPExecutableDirective &D,
4738 Address KmpTaskSharedsPtr, LValue TDBase,
4739 const RecordDecl *KmpTaskTWithPrivatesQTyRD,
4740 QualType SharedsTy, QualType SharedsPtrTy,
4741 const OMPTaskDataTy &Data,
4742 ArrayRef<PrivateDataTy> Privates, bool ForDup) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004743 ASTContext &C = CGF.getContext();
Alexey Bataevf93095a2016-05-05 08:46:22 +00004744 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
4745 LValue PrivatesBase = CGF.EmitLValueForField(TDBase, *FI);
Alexey Bataev8451efa2018-01-15 19:06:12 +00004746 OpenMPDirectiveKind Kind = isOpenMPTaskLoopDirective(D.getDirectiveKind())
4747 ? OMPD_taskloop
4748 : OMPD_task;
4749 const CapturedStmt &CS = *D.getCapturedStmt(Kind);
4750 CodeGenFunction::CGCapturedStmtInfo CapturesInfo(CS);
Alexey Bataevf93095a2016-05-05 08:46:22 +00004751 LValue SrcBase;
Alexey Bataevd2202ca2017-12-27 17:58:32 +00004752 bool IsTargetTask =
4753 isOpenMPTargetDataManagementDirective(D.getDirectiveKind()) ||
4754 isOpenMPTargetExecutionDirective(D.getDirectiveKind());
4755 // For target-based directives skip 3 firstprivate arrays BasePointersArray,
4756 // PointersArray and SizesArray. The original variables for these arrays are
4757 // not captured and we get their addresses explicitly.
4758 if ((!IsTargetTask && !Data.FirstprivateVars.empty()) ||
Alexey Bataev8451efa2018-01-15 19:06:12 +00004759 (IsTargetTask && KmpTaskSharedsPtr.isValid())) {
Alexey Bataevf93095a2016-05-05 08:46:22 +00004760 SrcBase = CGF.MakeAddrLValue(
4761 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
4762 KmpTaskSharedsPtr, CGF.ConvertTypeForMem(SharedsPtrTy)),
4763 SharedsTy);
4764 }
Alexey Bataevf93095a2016-05-05 08:46:22 +00004765 FI = cast<RecordDecl>(FI->getType()->getAsTagDecl())->field_begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004766 for (const PrivateDataTy &Pair : Privates) {
4767 const VarDecl *VD = Pair.second.PrivateCopy;
4768 const Expr *Init = VD->getAnyInitializer();
Alexey Bataevf93095a2016-05-05 08:46:22 +00004769 if (Init && (!ForDup || (isa<CXXConstructExpr>(Init) &&
4770 !CGF.isTrivialInitializer(Init)))) {
Alexey Bataev8a831592016-05-10 10:36:51 +00004771 LValue PrivateLValue = CGF.EmitLValueForField(PrivatesBase, *FI);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004772 if (const VarDecl *Elem = Pair.second.PrivateElemInit) {
4773 const VarDecl *OriginalVD = Pair.second.Original;
Alexey Bataevd2202ca2017-12-27 17:58:32 +00004774 // Check if the variable is the target-based BasePointersArray,
4775 // PointersArray or SizesArray.
4776 LValue SharedRefLValue;
Alexey Bataevab41ea62019-03-13 20:46:28 +00004777 QualType Type = PrivateLValue.getType();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004778 const FieldDecl *SharedField = CapturesInfo.lookup(OriginalVD);
Alexey Bataev8451efa2018-01-15 19:06:12 +00004779 if (IsTargetTask && !SharedField) {
4780 assert(isa<ImplicitParamDecl>(OriginalVD) &&
4781 isa<CapturedDecl>(OriginalVD->getDeclContext()) &&
4782 cast<CapturedDecl>(OriginalVD->getDeclContext())
4783 ->getNumParams() == 0 &&
4784 isa<TranslationUnitDecl>(
4785 cast<CapturedDecl>(OriginalVD->getDeclContext())
4786 ->getDeclContext()) &&
4787 "Expected artificial target data variable.");
Alexey Bataevd2202ca2017-12-27 17:58:32 +00004788 SharedRefLValue =
4789 CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(OriginalVD), Type);
4790 } else {
Alexey Bataevd2202ca2017-12-27 17:58:32 +00004791 SharedRefLValue = CGF.EmitLValueForField(SrcBase, SharedField);
4792 SharedRefLValue = CGF.MakeAddrLValue(
4793 Address(SharedRefLValue.getPointer(), C.getDeclAlign(OriginalVD)),
4794 SharedRefLValue.getType(), LValueBaseInfo(AlignmentSource::Decl),
4795 SharedRefLValue.getTBAAInfo());
4796 }
Alexey Bataevf93095a2016-05-05 08:46:22 +00004797 if (Type->isArrayType()) {
4798 // Initialize firstprivate array.
4799 if (!isa<CXXConstructExpr>(Init) || CGF.isTrivialInitializer(Init)) {
4800 // Perform simple memcpy.
Ivan A. Kosarev1860b522018-01-25 14:21:55 +00004801 CGF.EmitAggregateAssign(PrivateLValue, SharedRefLValue, Type);
Alexey Bataevf93095a2016-05-05 08:46:22 +00004802 } else {
4803 // Initialize firstprivate array using element-by-element
Simon Pilgrim2c518802017-03-30 14:13:19 +00004804 // initialization.
Alexey Bataevf93095a2016-05-05 08:46:22 +00004805 CGF.EmitOMPAggregateAssign(
4806 PrivateLValue.getAddress(), SharedRefLValue.getAddress(), Type,
4807 [&CGF, Elem, Init, &CapturesInfo](Address DestElement,
4808 Address SrcElement) {
4809 // Clean up any temporaries needed by the initialization.
4810 CodeGenFunction::OMPPrivateScope InitScope(CGF);
4811 InitScope.addPrivate(
4812 Elem, [SrcElement]() -> Address { return SrcElement; });
4813 (void)InitScope.Privatize();
4814 // Emit initialization for single element.
4815 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(
4816 CGF, &CapturesInfo);
4817 CGF.EmitAnyExprToMem(Init, DestElement,
4818 Init->getType().getQualifiers(),
4819 /*IsInitializer=*/false);
4820 });
4821 }
4822 } else {
4823 CodeGenFunction::OMPPrivateScope InitScope(CGF);
4824 InitScope.addPrivate(Elem, [SharedRefLValue]() -> Address {
4825 return SharedRefLValue.getAddress();
4826 });
4827 (void)InitScope.Privatize();
4828 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CapturesInfo);
4829 CGF.EmitExprAsInit(Init, VD, PrivateLValue,
4830 /*capturedByInit=*/false);
4831 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004832 } else {
Alexey Bataevf93095a2016-05-05 08:46:22 +00004833 CGF.EmitExprAsInit(Init, VD, PrivateLValue, /*capturedByInit=*/false);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004834 }
Alexey Bataevf93095a2016-05-05 08:46:22 +00004835 }
Alexey Bataevf93095a2016-05-05 08:46:22 +00004836 ++FI;
4837 }
Alexey Bataevf93095a2016-05-05 08:46:22 +00004838}
4839
4840/// Check if duplication function is required for taskloops.
4841static bool checkInitIsRequired(CodeGenFunction &CGF,
4842 ArrayRef<PrivateDataTy> Privates) {
4843 bool InitRequired = false;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004844 for (const PrivateDataTy &Pair : Privates) {
4845 const VarDecl *VD = Pair.second.PrivateCopy;
4846 const Expr *Init = VD->getAnyInitializer();
Alexey Bataevf93095a2016-05-05 08:46:22 +00004847 InitRequired = InitRequired || (Init && isa<CXXConstructExpr>(Init) &&
4848 !CGF.isTrivialInitializer(Init));
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004849 if (InitRequired)
4850 break;
Alexey Bataevf93095a2016-05-05 08:46:22 +00004851 }
4852 return InitRequired;
4853}
4854
4855
4856/// Emit task_dup function (for initialization of
4857/// private/firstprivate/lastprivate vars and last_iter flag)
4858/// \code
4859/// void __task_dup_entry(kmp_task_t *task_dst, const kmp_task_t *task_src, int
4860/// lastpriv) {
4861/// // setup lastprivate flag
4862/// task_dst->last = lastpriv;
4863/// // could be constructor calls here...
4864/// }
4865/// \endcode
4866static llvm::Value *
4867emitTaskDupFunction(CodeGenModule &CGM, SourceLocation Loc,
4868 const OMPExecutableDirective &D,
4869 QualType KmpTaskTWithPrivatesPtrQTy,
4870 const RecordDecl *KmpTaskTWithPrivatesQTyRD,
4871 const RecordDecl *KmpTaskTQTyRD, QualType SharedsTy,
4872 QualType SharedsPtrTy, const OMPTaskDataTy &Data,
4873 ArrayRef<PrivateDataTy> Privates, bool WithLastIter) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004874 ASTContext &C = CGM.getContext();
Alexey Bataevf93095a2016-05-05 08:46:22 +00004875 FunctionArgList Args;
Alexey Bataev56223232017-06-09 13:40:18 +00004876 ImplicitParamDecl DstArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4877 KmpTaskTWithPrivatesPtrQTy,
4878 ImplicitParamDecl::Other);
4879 ImplicitParamDecl SrcArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
4880 KmpTaskTWithPrivatesPtrQTy,
4881 ImplicitParamDecl::Other);
4882 ImplicitParamDecl LastprivArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.IntTy,
4883 ImplicitParamDecl::Other);
Alexey Bataevf93095a2016-05-05 08:46:22 +00004884 Args.push_back(&DstArg);
4885 Args.push_back(&SrcArg);
4886 Args.push_back(&LastprivArg);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004887 const auto &TaskDupFnInfo =
Alexey Bataevf93095a2016-05-05 08:46:22 +00004888 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004889 llvm::FunctionType *TaskDupTy = CGM.getTypes().GetFunctionType(TaskDupFnInfo);
Alexey Bataev18fa2322018-05-02 14:20:50 +00004890 std::string Name = CGM.getOpenMPRuntime().getName({"omp_task_dup", ""});
4891 auto *TaskDup = llvm::Function::Create(
4892 TaskDupTy, llvm::GlobalValue::InternalLinkage, Name, &CGM.getModule());
Rafael Espindola51ec5a92018-02-28 23:46:35 +00004893 CGM.SetInternalFunctionAttributes(GlobalDecl(), TaskDup, TaskDupFnInfo);
Alexey Bataevc0f879b2018-04-10 20:10:53 +00004894 TaskDup->setDoesNotRecurse();
Alexey Bataevf93095a2016-05-05 08:46:22 +00004895 CodeGenFunction CGF(CGM);
Alexey Bataev7cae94e2018-01-04 19:45:16 +00004896 CGF.StartFunction(GlobalDecl(), C.VoidTy, TaskDup, TaskDupFnInfo, Args, Loc,
4897 Loc);
Alexey Bataevf93095a2016-05-05 08:46:22 +00004898
4899 LValue TDBase = CGF.EmitLoadOfPointerLValue(
4900 CGF.GetAddrOfLocalVar(&DstArg),
4901 KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
4902 // task_dst->liter = lastpriv;
4903 if (WithLastIter) {
4904 auto LIFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLastIter);
4905 LValue Base = CGF.EmitLValueForField(
4906 TDBase, *KmpTaskTWithPrivatesQTyRD->field_begin());
4907 LValue LILVal = CGF.EmitLValueForField(Base, *LIFI);
4908 llvm::Value *Lastpriv = CGF.EmitLoadOfScalar(
4909 CGF.GetAddrOfLocalVar(&LastprivArg), /*Volatile=*/false, C.IntTy, Loc);
4910 CGF.EmitStoreOfScalar(Lastpriv, LILVal);
4911 }
4912
4913 // Emit initial values for private copies (if any).
4914 assert(!Privates.empty());
4915 Address KmpTaskSharedsPtr = Address::invalid();
4916 if (!Data.FirstprivateVars.empty()) {
4917 LValue TDBase = CGF.EmitLoadOfPointerLValue(
4918 CGF.GetAddrOfLocalVar(&SrcArg),
4919 KmpTaskTWithPrivatesPtrQTy->castAs<PointerType>());
4920 LValue Base = CGF.EmitLValueForField(
4921 TDBase, *KmpTaskTWithPrivatesQTyRD->field_begin());
4922 KmpTaskSharedsPtr = Address(
4923 CGF.EmitLoadOfScalar(CGF.EmitLValueForField(
4924 Base, *std::next(KmpTaskTQTyRD->field_begin(),
4925 KmpTaskTShareds)),
4926 Loc),
4927 CGF.getNaturalTypeAlignment(SharedsTy));
4928 }
Alexey Bataev8a831592016-05-10 10:36:51 +00004929 emitPrivatesInit(CGF, D, KmpTaskSharedsPtr, TDBase, KmpTaskTWithPrivatesQTyRD,
4930 SharedsTy, SharedsPtrTy, Data, Privates, /*ForDup=*/true);
Alexey Bataevf93095a2016-05-05 08:46:22 +00004931 CGF.FinishFunction();
4932 return TaskDup;
4933}
4934
Alexey Bataev8a831592016-05-10 10:36:51 +00004935/// Checks if destructor function is required to be generated.
4936/// \return true if cleanups are required, false otherwise.
4937static bool
4938checkDestructorsRequired(const RecordDecl *KmpTaskTWithPrivatesQTyRD) {
4939 bool NeedsCleanup = false;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004940 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin(), 1);
4941 const auto *PrivateRD = cast<RecordDecl>(FI->getType()->getAsTagDecl());
4942 for (const FieldDecl *FD : PrivateRD->fields()) {
Alexey Bataev8a831592016-05-10 10:36:51 +00004943 NeedsCleanup = NeedsCleanup || FD->getType().isDestructedType();
4944 if (NeedsCleanup)
4945 break;
4946 }
4947 return NeedsCleanup;
4948}
4949
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004950CGOpenMPRuntime::TaskResultTy
4951CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
4952 const OMPExecutableDirective &D,
James Y Knight9871db02019-02-05 16:42:33 +00004953 llvm::Function *TaskFunction, QualType SharedsTy,
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004954 Address Shareds, const OMPTaskDataTy &Data) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004955 ASTContext &C = CGM.getContext();
Alexey Bataev7292c292016-04-25 12:22:29 +00004956 llvm::SmallVector<PrivateDataTy, 4> Privates;
Alexey Bataev3ae88e22015-05-22 08:56:35 +00004957 // Aggregate privates and sort them by the alignment.
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004958 auto I = Data.PrivateCopies.begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004959 for (const Expr *E : Data.PrivateVars) {
4960 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataev43a919f2018-04-13 17:48:43 +00004961 Privates.emplace_back(
Alexey Bataevc71a4092015-09-11 10:29:41 +00004962 C.getDeclAlign(VD),
Alexey Bataev9e034042015-05-05 04:05:12 +00004963 PrivateHelpersTy(VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
Alexey Bataev43a919f2018-04-13 17:48:43 +00004964 /*PrivateElemInit=*/nullptr));
Alexey Bataev36c1eb92015-04-30 06:51:57 +00004965 ++I;
4966 }
Alexey Bataev24b5bae2016-04-28 09:23:51 +00004967 I = Data.FirstprivateCopies.begin();
4968 auto IElemInitRef = Data.FirstprivateInits.begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004969 for (const Expr *E : Data.FirstprivateVars) {
4970 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataev43a919f2018-04-13 17:48:43 +00004971 Privates.emplace_back(
Alexey Bataevc71a4092015-09-11 10:29:41 +00004972 C.getDeclAlign(VD),
Alexey Bataev9e034042015-05-05 04:05:12 +00004973 PrivateHelpersTy(
4974 VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
Alexey Bataev43a919f2018-04-13 17:48:43 +00004975 cast<VarDecl>(cast<DeclRefExpr>(*IElemInitRef)->getDecl())));
Richard Trieucc3949d2016-02-18 22:34:54 +00004976 ++I;
4977 ++IElemInitRef;
Alexey Bataev9e034042015-05-05 04:05:12 +00004978 }
Alexey Bataevf93095a2016-05-05 08:46:22 +00004979 I = Data.LastprivateCopies.begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004980 for (const Expr *E : Data.LastprivateVars) {
4981 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
Alexey Bataev43a919f2018-04-13 17:48:43 +00004982 Privates.emplace_back(
Alexey Bataevf93095a2016-05-05 08:46:22 +00004983 C.getDeclAlign(VD),
4984 PrivateHelpersTy(VD, cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()),
Alexey Bataev43a919f2018-04-13 17:48:43 +00004985 /*PrivateElemInit=*/nullptr));
Alexey Bataevf93095a2016-05-05 08:46:22 +00004986 ++I;
4987 }
Fangrui Song899d1392019-04-24 14:43:05 +00004988 llvm::stable_sort(Privates, [](PrivateDataTy L, PrivateDataTy R) {
4989 return L.first > R.first;
4990 });
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00004991 QualType KmpInt32Ty = C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
Alexey Bataev62b63b12015-03-10 07:28:44 +00004992 // Build type kmp_routine_entry_t (if not built yet).
4993 emitKmpRoutineEntryT(KmpInt32Ty);
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00004994 // Build type kmp_task_t (if not built yet).
Alexey Bataeve213f3e2017-10-11 15:29:40 +00004995 if (isOpenMPTaskLoopDirective(D.getDirectiveKind())) {
4996 if (SavedKmpTaskloopTQTy.isNull()) {
4997 SavedKmpTaskloopTQTy = C.getRecordType(createKmpTaskTRecordDecl(
4998 CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy));
4999 }
5000 KmpTaskTQTy = SavedKmpTaskloopTQTy;
Alexey Bataev3a03a7f2017-10-11 15:56:38 +00005001 } else {
Alexey Bataevd2202ca2017-12-27 17:58:32 +00005002 assert((D.getDirectiveKind() == OMPD_task ||
5003 isOpenMPTargetExecutionDirective(D.getDirectiveKind()) ||
5004 isOpenMPTargetDataManagementDirective(D.getDirectiveKind())) &&
5005 "Expected taskloop, task or target directive");
Alexey Bataeve213f3e2017-10-11 15:29:40 +00005006 if (SavedKmpTaskTQTy.isNull()) {
5007 SavedKmpTaskTQTy = C.getRecordType(createKmpTaskTRecordDecl(
5008 CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy));
5009 }
5010 KmpTaskTQTy = SavedKmpTaskTQTy;
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00005011 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005012 const auto *KmpTaskTQTyRD = cast<RecordDecl>(KmpTaskTQTy->getAsTagDecl());
Alexey Bataev62b63b12015-03-10 07:28:44 +00005013 // Build particular struct kmp_task_t for the given task.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005014 const RecordDecl *KmpTaskTWithPrivatesQTyRD =
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00005015 createKmpTaskTWithPrivatesRecordDecl(CGM, KmpTaskTQTy, Privates);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005016 QualType KmpTaskTWithPrivatesQTy = C.getRecordType(KmpTaskTWithPrivatesQTyRD);
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00005017 QualType KmpTaskTWithPrivatesPtrQTy =
5018 C.getPointerType(KmpTaskTWithPrivatesQTy);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005019 llvm::Type *KmpTaskTWithPrivatesTy = CGF.ConvertType(KmpTaskTWithPrivatesQTy);
5020 llvm::Type *KmpTaskTWithPrivatesPtrTy =
5021 KmpTaskTWithPrivatesTy->getPointerTo();
5022 llvm::Value *KmpTaskTWithPrivatesTySize =
5023 CGF.getTypeSize(KmpTaskTWithPrivatesQTy);
Alexey Bataev62b63b12015-03-10 07:28:44 +00005024 QualType SharedsPtrTy = C.getPointerType(SharedsTy);
5025
Alexey Bataev3ae88e22015-05-22 08:56:35 +00005026 // Emit initial values for private copies (if any).
5027 llvm::Value *TaskPrivatesMap = nullptr;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005028 llvm::Type *TaskPrivatesMapTy =
James Y Knight9871db02019-02-05 16:42:33 +00005029 std::next(TaskFunction->arg_begin(), 3)->getType();
Alexey Bataev3ae88e22015-05-22 08:56:35 +00005030 if (!Privates.empty()) {
5031 auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
Alexey Bataevf93095a2016-05-05 08:46:22 +00005032 TaskPrivatesMap = emitTaskPrivateMappingFunction(
5033 CGM, Loc, Data.PrivateVars, Data.FirstprivateVars, Data.LastprivateVars,
5034 FI->getType(), Privates);
Alexey Bataev3ae88e22015-05-22 08:56:35 +00005035 TaskPrivatesMap = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5036 TaskPrivatesMap, TaskPrivatesMapTy);
5037 } else {
5038 TaskPrivatesMap = llvm::ConstantPointerNull::get(
5039 cast<llvm::PointerType>(TaskPrivatesMapTy));
5040 }
Alexey Bataev62b63b12015-03-10 07:28:44 +00005041 // Build a proxy function kmp_int32 .omp_task_entry.(kmp_int32 gtid,
5042 // kmp_task_t *tt);
James Y Knight9871db02019-02-05 16:42:33 +00005043 llvm::Function *TaskEntry = emitProxyTaskFunction(
Alexey Bataev7292c292016-04-25 12:22:29 +00005044 CGM, Loc, D.getDirectiveKind(), KmpInt32Ty, KmpTaskTWithPrivatesPtrQTy,
5045 KmpTaskTWithPrivatesQTy, KmpTaskTQTy, SharedsPtrTy, TaskFunction,
5046 TaskPrivatesMap);
Alexey Bataev62b63b12015-03-10 07:28:44 +00005047
5048 // Build call kmp_task_t * __kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid,
5049 // kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds,
5050 // kmp_routine_entry_t *task_entry);
5051 // Task flags. Format is taken from
James Y Knight5d71fc52019-01-29 16:37:27 +00005052 // https://github.com/llvm/llvm-project/blob/master/openmp/runtime/src/kmp.h,
Alexey Bataev62b63b12015-03-10 07:28:44 +00005053 // description of kmp_tasking_flags struct.
Alexey Bataev1e1e2862016-05-10 12:21:02 +00005054 enum {
5055 TiedFlag = 0x1,
5056 FinalFlag = 0x2,
5057 DestructorsFlag = 0x8,
5058 PriorityFlag = 0x20
5059 };
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005060 unsigned Flags = Data.Tied ? TiedFlag : 0;
Alexey Bataev8a831592016-05-10 10:36:51 +00005061 bool NeedsCleanup = false;
5062 if (!Privates.empty()) {
5063 NeedsCleanup = checkDestructorsRequired(KmpTaskTWithPrivatesQTyRD);
5064 if (NeedsCleanup)
5065 Flags = Flags | DestructorsFlag;
5066 }
Alexey Bataev1e1e2862016-05-10 12:21:02 +00005067 if (Data.Priority.getInt())
5068 Flags = Flags | PriorityFlag;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005069 llvm::Value *TaskFlags =
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005070 Data.Final.getPointer()
5071 ? CGF.Builder.CreateSelect(Data.Final.getPointer(),
Alexey Bataev62b63b12015-03-10 07:28:44 +00005072 CGF.Builder.getInt32(FinalFlag),
5073 CGF.Builder.getInt32(/*C=*/0))
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005074 : CGF.Builder.getInt32(Data.Final.getInt() ? FinalFlag : 0);
Alexey Bataev62b63b12015-03-10 07:28:44 +00005075 TaskFlags = CGF.Builder.CreateOr(TaskFlags, CGF.Builder.getInt32(Flags));
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005076 llvm::Value *SharedsSize = CGM.getSize(C.getTypeSizeInChars(SharedsTy));
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005077 llvm::Value *AllocArgs[] = {emitUpdateLocation(CGF, Loc),
5078 getThreadID(CGF, Loc), TaskFlags,
5079 KmpTaskTWithPrivatesTySize, SharedsSize,
5080 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5081 TaskEntry, KmpRoutineEntryPtrTy)};
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005082 llvm::Value *NewTask = CGF.EmitRuntimeCall(
Alexey Bataev62b63b12015-03-10 07:28:44 +00005083 createRuntimeFunction(OMPRTL__kmpc_omp_task_alloc), AllocArgs);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005084 llvm::Value *NewTaskNewTaskTTy =
5085 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5086 NewTask, KmpTaskTWithPrivatesPtrTy);
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00005087 LValue Base = CGF.MakeNaturalAlignAddrLValue(NewTaskNewTaskTTy,
5088 KmpTaskTWithPrivatesQTy);
5089 LValue TDBase =
5090 CGF.EmitLValueForField(Base, *KmpTaskTWithPrivatesQTyRD->field_begin());
Alexey Bataev62b63b12015-03-10 07:28:44 +00005091 // Fill the data in the resulting kmp_task_t record.
5092 // Copy shareds if there are any.
John McCall7f416cc2015-09-08 08:05:57 +00005093 Address KmpTaskSharedsPtr = Address::invalid();
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00005094 if (!SharedsTy->getAsStructureType()->getDecl()->field_empty()) {
Alexey Bataev2377fe92015-09-10 08:12:02 +00005095 KmpTaskSharedsPtr =
5096 Address(CGF.EmitLoadOfScalar(
5097 CGF.EmitLValueForField(
5098 TDBase, *std::next(KmpTaskTQTyRD->field_begin(),
5099 KmpTaskTShareds)),
5100 Loc),
5101 CGF.getNaturalTypeAlignment(SharedsTy));
Ivan A. Kosarev1860b522018-01-25 14:21:55 +00005102 LValue Dest = CGF.MakeAddrLValue(KmpTaskSharedsPtr, SharedsTy);
5103 LValue Src = CGF.MakeAddrLValue(Shareds, SharedsTy);
Richard Smithe78fac52018-04-05 20:52:58 +00005104 CGF.EmitAggregateCopy(Dest, Src, SharedsTy, AggValueSlot::DoesNotOverlap);
Alexey Bataev8fc69dc2015-05-18 07:54:53 +00005105 }
Alexey Bataev36c1eb92015-04-30 06:51:57 +00005106 // Emit initial values for private copies (if any).
Alexey Bataevf93095a2016-05-05 08:46:22 +00005107 TaskResultTy Result;
Alexey Bataev36c1eb92015-04-30 06:51:57 +00005108 if (!Privates.empty()) {
Alexey Bataev8a831592016-05-10 10:36:51 +00005109 emitPrivatesInit(CGF, D, KmpTaskSharedsPtr, Base, KmpTaskTWithPrivatesQTyRD,
5110 SharedsTy, SharedsPtrTy, Data, Privates,
5111 /*ForDup=*/false);
Alexey Bataevf93095a2016-05-05 08:46:22 +00005112 if (isOpenMPTaskLoopDirective(D.getDirectiveKind()) &&
5113 (!Data.LastprivateVars.empty() || checkInitIsRequired(CGF, Privates))) {
5114 Result.TaskDupFn = emitTaskDupFunction(
5115 CGM, Loc, D, KmpTaskTWithPrivatesPtrQTy, KmpTaskTWithPrivatesQTyRD,
5116 KmpTaskTQTyRD, SharedsTy, SharedsPtrTy, Data, Privates,
5117 /*WithLastIter=*/!Data.LastprivateVars.empty());
Alexey Bataev36c1eb92015-04-30 06:51:57 +00005118 }
5119 }
Alexey Bataevad537bb2016-05-30 09:06:50 +00005120 // Fields of union "kmp_cmplrdata_t" for destructors and priority.
5121 enum { Priority = 0, Destructors = 1 };
Alexey Bataev62b63b12015-03-10 07:28:44 +00005122 // Provide pointer to function with destructors for privates.
Alexey Bataevad537bb2016-05-30 09:06:50 +00005123 auto FI = std::next(KmpTaskTQTyRD->field_begin(), Data1);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005124 const RecordDecl *KmpCmplrdataUD =
5125 (*FI)->getType()->getAsUnionType()->getDecl();
Alexey Bataevad537bb2016-05-30 09:06:50 +00005126 if (NeedsCleanup) {
5127 llvm::Value *DestructorFn = emitDestructorsFunction(
5128 CGM, Loc, KmpInt32Ty, KmpTaskTWithPrivatesPtrQTy,
5129 KmpTaskTWithPrivatesQTy);
5130 LValue Data1LV = CGF.EmitLValueForField(TDBase, *FI);
5131 LValue DestructorsLV = CGF.EmitLValueForField(
5132 Data1LV, *std::next(KmpCmplrdataUD->field_begin(), Destructors));
5133 CGF.EmitStoreOfScalar(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5134 DestructorFn, KmpRoutineEntryPtrTy),
5135 DestructorsLV);
5136 }
5137 // Set priority.
5138 if (Data.Priority.getInt()) {
5139 LValue Data2LV = CGF.EmitLValueForField(
5140 TDBase, *std::next(KmpTaskTQTyRD->field_begin(), Data2));
5141 LValue PriorityLV = CGF.EmitLValueForField(
5142 Data2LV, *std::next(KmpCmplrdataUD->field_begin(), Priority));
5143 CGF.EmitStoreOfScalar(Data.Priority.getPointer(), PriorityLV);
5144 }
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005145 Result.NewTask = NewTask;
5146 Result.TaskEntry = TaskEntry;
5147 Result.NewTaskNewTaskTTy = NewTaskNewTaskTTy;
5148 Result.TDBase = TDBase;
5149 Result.KmpTaskTQTyRD = KmpTaskTQTyRD;
5150 return Result;
Alexey Bataev7292c292016-04-25 12:22:29 +00005151}
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005152
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005153void CGOpenMPRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
5154 const OMPExecutableDirective &D,
James Y Knight9871db02019-02-05 16:42:33 +00005155 llvm::Function *TaskFunction,
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005156 QualType SharedsTy, Address Shareds,
5157 const Expr *IfCond,
5158 const OMPTaskDataTy &Data) {
Alexey Bataev7292c292016-04-25 12:22:29 +00005159 if (!CGF.HaveInsertPoint())
5160 return;
5161
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005162 TaskResultTy Result =
5163 emitTaskInit(CGF, Loc, D, TaskFunction, SharedsTy, Shareds, Data);
5164 llvm::Value *NewTask = Result.NewTask;
James Y Knight9871db02019-02-05 16:42:33 +00005165 llvm::Function *TaskEntry = Result.TaskEntry;
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005166 llvm::Value *NewTaskNewTaskTTy = Result.NewTaskNewTaskTTy;
5167 LValue TDBase = Result.TDBase;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005168 const RecordDecl *KmpTaskTQTyRD = Result.KmpTaskTQTyRD;
5169 ASTContext &C = CGM.getContext();
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005170 // Process list of dependences.
John McCall7f416cc2015-09-08 08:05:57 +00005171 Address DependenciesArray = Address::invalid();
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005172 unsigned NumDependencies = Data.Dependences.size();
John McCall7f416cc2015-09-08 08:05:57 +00005173 if (NumDependencies) {
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005174 // Dependence kind for RTL.
Sergi Mateo Bellido31df1ad2019-02-04 07:33:19 +00005175 enum RTLDependenceKindTy { DepIn = 0x01, DepInOut = 0x3, DepMutexInOutSet = 0x4 };
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005176 enum RTLDependInfoFieldsTy { BaseAddr, Len, Flags };
5177 RecordDecl *KmpDependInfoRD;
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005178 QualType FlagsTy =
5179 C.getIntTypeForBitwidth(C.getTypeSize(C.BoolTy), /*Signed=*/false);
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005180 llvm::Type *LLVMFlagsTy = CGF.ConvertTypeForMem(FlagsTy);
5181 if (KmpDependInfoTy.isNull()) {
5182 KmpDependInfoRD = C.buildImplicitRecord("kmp_depend_info");
5183 KmpDependInfoRD->startDefinition();
5184 addFieldToRecordDecl(C, KmpDependInfoRD, C.getIntPtrType());
5185 addFieldToRecordDecl(C, KmpDependInfoRD, C.getSizeType());
5186 addFieldToRecordDecl(C, KmpDependInfoRD, FlagsTy);
5187 KmpDependInfoRD->completeDefinition();
5188 KmpDependInfoTy = C.getRecordType(KmpDependInfoRD);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005189 } else {
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005190 KmpDependInfoRD = cast<RecordDecl>(KmpDependInfoTy->getAsTagDecl());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005191 }
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005192 // Define type kmp_depend_info[<Dependences.size()>];
5193 QualType KmpDependInfoArrayTy = C.getConstantArrayType(
John McCall7f416cc2015-09-08 08:05:57 +00005194 KmpDependInfoTy, llvm::APInt(/*numBits=*/64, NumDependencies),
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005195 ArrayType::Normal, /*IndexTypeQuals=*/0);
5196 // kmp_depend_info[<Dependences.size()>] deps;
Alexey Bataev48591dd2016-04-20 04:01:36 +00005197 DependenciesArray =
5198 CGF.CreateMemTemp(KmpDependInfoArrayTy, ".dep.arr.addr");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005199 for (unsigned I = 0; I < NumDependencies; ++I) {
5200 const Expr *E = Data.Dependences[I].second;
5201 LValue Addr = CGF.EmitLValue(E);
Alexey Bataevd6fdc8b2015-08-31 07:32:19 +00005202 llvm::Value *Size;
5203 QualType Ty = E->getType();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005204 if (const auto *ASE =
5205 dyn_cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts())) {
Alexey Bataevd6fdc8b2015-08-31 07:32:19 +00005206 LValue UpAddrLVal =
5207 CGF.EmitOMPArraySectionExpr(ASE, /*LowerBound=*/false);
5208 llvm::Value *UpAddr =
John McCall7f416cc2015-09-08 08:05:57 +00005209 CGF.Builder.CreateConstGEP1_32(UpAddrLVal.getPointer(), /*Idx0=*/1);
Alexey Bataevd6fdc8b2015-08-31 07:32:19 +00005210 llvm::Value *LowIntPtr =
John McCall7f416cc2015-09-08 08:05:57 +00005211 CGF.Builder.CreatePtrToInt(Addr.getPointer(), CGM.SizeTy);
Alexey Bataevd6fdc8b2015-08-31 07:32:19 +00005212 llvm::Value *UpIntPtr = CGF.Builder.CreatePtrToInt(UpAddr, CGM.SizeTy);
5213 Size = CGF.Builder.CreateNUWSub(UpIntPtr, LowIntPtr);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005214 } else {
Alexey Bataev1189bd02016-01-26 12:20:39 +00005215 Size = CGF.getTypeSize(Ty);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005216 }
5217 LValue Base = CGF.MakeAddrLValue(
James Y Knight751fe282019-02-09 22:22:28 +00005218 CGF.Builder.CreateConstArrayGEP(DependenciesArray, I),
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005219 KmpDependInfoTy);
5220 // deps[i].base_addr = &<Dependences[i].second>;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005221 LValue BaseAddrLVal = CGF.EmitLValueForField(
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005222 Base, *std::next(KmpDependInfoRD->field_begin(), BaseAddr));
John McCall7f416cc2015-09-08 08:05:57 +00005223 CGF.EmitStoreOfScalar(
5224 CGF.Builder.CreatePtrToInt(Addr.getPointer(), CGF.IntPtrTy),
5225 BaseAddrLVal);
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005226 // deps[i].len = sizeof(<Dependences[i].second>);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005227 LValue LenLVal = CGF.EmitLValueForField(
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005228 Base, *std::next(KmpDependInfoRD->field_begin(), Len));
5229 CGF.EmitStoreOfScalar(Size, LenLVal);
5230 // deps[i].flags = <Dependences[i].first>;
5231 RTLDependenceKindTy DepKind;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005232 switch (Data.Dependences[I].first) {
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005233 case OMPC_DEPEND_in:
5234 DepKind = DepIn;
5235 break;
Alexey Bataev92e82f92015-11-23 13:33:42 +00005236 // Out and InOut dependencies must use the same code.
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005237 case OMPC_DEPEND_out:
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005238 case OMPC_DEPEND_inout:
5239 DepKind = DepInOut;
5240 break;
Sergi Mateo Bellido31df1ad2019-02-04 07:33:19 +00005241 case OMPC_DEPEND_mutexinoutset:
5242 DepKind = DepMutexInOutSet;
5243 break;
Alexey Bataeveb482352015-12-18 05:05:56 +00005244 case OMPC_DEPEND_source:
Alexey Bataeva636c7f2015-12-23 10:27:45 +00005245 case OMPC_DEPEND_sink:
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005246 case OMPC_DEPEND_unknown:
5247 llvm_unreachable("Unknown task dependence type");
5248 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005249 LValue FlagsLVal = CGF.EmitLValueForField(
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005250 Base, *std::next(KmpDependInfoRD->field_begin(), Flags));
5251 CGF.EmitStoreOfScalar(llvm::ConstantInt::get(LLVMFlagsTy, DepKind),
5252 FlagsLVal);
5253 }
John McCall7f416cc2015-09-08 08:05:57 +00005254 DependenciesArray = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
James Y Knightf5f1b0e2019-02-08 15:34:12 +00005255 CGF.Builder.CreateConstArrayGEP(DependenciesArray, 0), CGF.VoidPtrTy);
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005256 }
5257
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +00005258 // NOTE: routine and part_id fields are initialized by __kmpc_omp_task_alloc()
Alexey Bataev62b63b12015-03-10 07:28:44 +00005259 // libcall.
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005260 // Build kmp_int32 __kmpc_omp_task_with_deps(ident_t *, kmp_int32 gtid,
5261 // kmp_task_t *new_task, kmp_int32 ndeps, kmp_depend_info_t *dep_list,
5262 // kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list) if dependence
5263 // list is not empty
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005264 llvm::Value *ThreadID = getThreadID(CGF, Loc);
5265 llvm::Value *UpLoc = emitUpdateLocation(CGF, Loc);
John McCall7f416cc2015-09-08 08:05:57 +00005266 llvm::Value *TaskArgs[] = { UpLoc, ThreadID, NewTask };
5267 llvm::Value *DepTaskArgs[7];
5268 if (NumDependencies) {
5269 DepTaskArgs[0] = UpLoc;
5270 DepTaskArgs[1] = ThreadID;
5271 DepTaskArgs[2] = NewTask;
5272 DepTaskArgs[3] = CGF.Builder.getInt32(NumDependencies);
5273 DepTaskArgs[4] = DependenciesArray.getPointer();
5274 DepTaskArgs[5] = CGF.Builder.getInt32(0);
5275 DepTaskArgs[6] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
5276 }
Malcolm Parsonsc6e45832017-01-13 18:55:32 +00005277 auto &&ThenCodeGen = [this, &Data, TDBase, KmpTaskTQTyRD, NumDependencies,
5278 &TaskArgs,
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005279 &DepTaskArgs](CodeGenFunction &CGF, PrePostActionTy &) {
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005280 if (!Data.Tied) {
Alexey Bataev48591dd2016-04-20 04:01:36 +00005281 auto PartIdFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTPartId);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005282 LValue PartIdLVal = CGF.EmitLValueForField(TDBase, *PartIdFI);
Alexey Bataev48591dd2016-04-20 04:01:36 +00005283 CGF.EmitStoreOfScalar(CGF.Builder.getInt32(0), PartIdLVal);
5284 }
John McCall7f416cc2015-09-08 08:05:57 +00005285 if (NumDependencies) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005286 CGF.EmitRuntimeCall(
Alexey Bataev48591dd2016-04-20 04:01:36 +00005287 createRuntimeFunction(OMPRTL__kmpc_omp_task_with_deps), DepTaskArgs);
John McCall7f416cc2015-09-08 08:05:57 +00005288 } else {
Alexey Bataev48591dd2016-04-20 04:01:36 +00005289 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_task),
John McCall7f416cc2015-09-08 08:05:57 +00005290 TaskArgs);
5291 }
Alexey Bataev48591dd2016-04-20 04:01:36 +00005292 // Check if parent region is untied and build return for untied task;
5293 if (auto *Region =
5294 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
5295 Region->emitUntiedSwitch(CGF);
Alexey Bataev1d677132015-04-22 13:57:31 +00005296 };
John McCall7f416cc2015-09-08 08:05:57 +00005297
5298 llvm::Value *DepWaitTaskArgs[6];
5299 if (NumDependencies) {
5300 DepWaitTaskArgs[0] = UpLoc;
5301 DepWaitTaskArgs[1] = ThreadID;
5302 DepWaitTaskArgs[2] = CGF.Builder.getInt32(NumDependencies);
5303 DepWaitTaskArgs[3] = DependenciesArray.getPointer();
5304 DepWaitTaskArgs[4] = CGF.Builder.getInt32(0);
5305 DepWaitTaskArgs[5] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
5306 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005307 auto &&ElseCodeGen = [&TaskArgs, ThreadID, NewTaskNewTaskTTy, TaskEntry,
Alexey Bataev3c595a62017-08-14 15:01:03 +00005308 NumDependencies, &DepWaitTaskArgs,
5309 Loc](CodeGenFunction &CGF, PrePostActionTy &) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005310 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005311 CodeGenFunction::RunCleanupsScope LocalScope(CGF);
5312 // Build void __kmpc_omp_wait_deps(ident_t *, kmp_int32 gtid,
5313 // kmp_int32 ndeps, kmp_depend_info_t *dep_list, kmp_int32
5314 // ndeps_noalias, kmp_depend_info_t *noalias_dep_list); if dependence info
5315 // is specified.
John McCall7f416cc2015-09-08 08:05:57 +00005316 if (NumDependencies)
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005317 CGF.EmitRuntimeCall(RT.createRuntimeFunction(OMPRTL__kmpc_omp_wait_deps),
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005318 DepWaitTaskArgs);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005319 // Call proxy_task_entry(gtid, new_task);
Alexey Bataev3c595a62017-08-14 15:01:03 +00005320 auto &&CodeGen = [TaskEntry, ThreadID, NewTaskNewTaskTTy,
5321 Loc](CodeGenFunction &CGF, PrePostActionTy &Action) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005322 Action.Enter(CGF);
5323 llvm::Value *OutlinedFnArgs[] = {ThreadID, NewTaskNewTaskTTy};
Alexey Bataev3c595a62017-08-14 15:01:03 +00005324 CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, Loc, TaskEntry,
Alexey Bataev2c7eee52017-08-04 19:10:54 +00005325 OutlinedFnArgs);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005326 };
5327
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005328 // Build void __kmpc_omp_task_begin_if0(ident_t *, kmp_int32 gtid,
5329 // kmp_task_t *new_task);
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005330 // Build void __kmpc_omp_task_complete_if0(ident_t *, kmp_int32 gtid,
5331 // kmp_task_t *new_task);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005332 RegionCodeGenTy RCG(CodeGen);
5333 CommonActionTy Action(
5334 RT.createRuntimeFunction(OMPRTL__kmpc_omp_task_begin_if0), TaskArgs,
5335 RT.createRuntimeFunction(OMPRTL__kmpc_omp_task_complete_if0), TaskArgs);
5336 RCG.setAction(Action);
5337 RCG(CGF);
Alexey Bataev1d2353d2015-06-24 11:01:36 +00005338 };
John McCall7f416cc2015-09-08 08:05:57 +00005339
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005340 if (IfCond) {
Alexey Bataev1d677132015-04-22 13:57:31 +00005341 emitOMPIfClause(CGF, IfCond, ThenCodeGen, ElseCodeGen);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005342 } else {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005343 RegionCodeGenTy ThenRCG(ThenCodeGen);
5344 ThenRCG(CGF);
Alexey Bataevf539faa2016-03-28 12:58:34 +00005345 }
Alexey Bataev62b63b12015-03-10 07:28:44 +00005346}
5347
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005348void CGOpenMPRuntime::emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc,
5349 const OMPLoopDirective &D,
James Y Knight9871db02019-02-05 16:42:33 +00005350 llvm::Function *TaskFunction,
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005351 QualType SharedsTy, Address Shareds,
5352 const Expr *IfCond,
5353 const OMPTaskDataTy &Data) {
Alexey Bataev7292c292016-04-25 12:22:29 +00005354 if (!CGF.HaveInsertPoint())
5355 return;
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005356 TaskResultTy Result =
5357 emitTaskInit(CGF, Loc, D, TaskFunction, SharedsTy, Shareds, Data);
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +00005358 // NOTE: routine and part_id fields are initialized by __kmpc_omp_task_alloc()
Alexey Bataev7292c292016-04-25 12:22:29 +00005359 // libcall.
5360 // Call to void __kmpc_taskloop(ident_t *loc, int gtid, kmp_task_t *task, int
5361 // if_val, kmp_uint64 *lb, kmp_uint64 *ub, kmp_int64 st, int nogroup, int
5362 // sched, kmp_uint64 grainsize, void *task_dup);
5363 llvm::Value *ThreadID = getThreadID(CGF, Loc);
5364 llvm::Value *UpLoc = emitUpdateLocation(CGF, Loc);
5365 llvm::Value *IfVal;
5366 if (IfCond) {
5367 IfVal = CGF.Builder.CreateIntCast(CGF.EvaluateExprAsBool(IfCond), CGF.IntTy,
5368 /*isSigned=*/true);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005369 } else {
Alexey Bataev7292c292016-04-25 12:22:29 +00005370 IfVal = llvm::ConstantInt::getSigned(CGF.IntTy, /*V=*/1);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005371 }
Alexey Bataev7292c292016-04-25 12:22:29 +00005372
5373 LValue LBLVal = CGF.EmitLValueForField(
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005374 Result.TDBase,
5375 *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTLowerBound));
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005376 const auto *LBVar =
Alexey Bataev7292c292016-04-25 12:22:29 +00005377 cast<VarDecl>(cast<DeclRefExpr>(D.getLowerBoundVariable())->getDecl());
5378 CGF.EmitAnyExprToMem(LBVar->getInit(), LBLVal.getAddress(), LBLVal.getQuals(),
5379 /*IsInitializer=*/true);
5380 LValue UBLVal = CGF.EmitLValueForField(
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005381 Result.TDBase,
5382 *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTUpperBound));
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005383 const auto *UBVar =
Alexey Bataev7292c292016-04-25 12:22:29 +00005384 cast<VarDecl>(cast<DeclRefExpr>(D.getUpperBoundVariable())->getDecl());
5385 CGF.EmitAnyExprToMem(UBVar->getInit(), UBLVal.getAddress(), UBLVal.getQuals(),
5386 /*IsInitializer=*/true);
5387 LValue StLVal = CGF.EmitLValueForField(
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005388 Result.TDBase,
5389 *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTStride));
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005390 const auto *StVar =
Alexey Bataev7292c292016-04-25 12:22:29 +00005391 cast<VarDecl>(cast<DeclRefExpr>(D.getStrideVariable())->getDecl());
5392 CGF.EmitAnyExprToMem(StVar->getInit(), StLVal.getAddress(), StLVal.getQuals(),
5393 /*IsInitializer=*/true);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00005394 // Store reductions address.
5395 LValue RedLVal = CGF.EmitLValueForField(
5396 Result.TDBase,
5397 *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTReductions));
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005398 if (Data.Reductions) {
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00005399 CGF.EmitStoreOfScalar(Data.Reductions, RedLVal);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005400 } else {
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00005401 CGF.EmitNullInitialization(RedLVal.getAddress(),
5402 CGF.getContext().VoidPtrTy);
5403 }
Alexey Bataev2b19a6f2016-04-28 09:15:06 +00005404 enum { NoSchedule = 0, Grainsize = 1, NumTasks = 2 };
Alexey Bataev7292c292016-04-25 12:22:29 +00005405 llvm::Value *TaskArgs[] = {
Alexey Bataev33446032017-07-12 18:09:32 +00005406 UpLoc,
5407 ThreadID,
5408 Result.NewTask,
5409 IfVal,
5410 LBLVal.getPointer(),
5411 UBLVal.getPointer(),
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00005412 CGF.EmitLoadOfScalar(StLVal, Loc),
Alexey Bataevac6e4de2018-10-24 19:06:37 +00005413 llvm::ConstantInt::getSigned(
5414 CGF.IntTy, 1), // Always 1 because taskgroup emitted by the compiler
Alexey Bataev2b19a6f2016-04-28 09:15:06 +00005415 llvm::ConstantInt::getSigned(
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005416 CGF.IntTy, Data.Schedule.getPointer()
5417 ? Data.Schedule.getInt() ? NumTasks : Grainsize
Alexey Bataev2b19a6f2016-04-28 09:15:06 +00005418 : NoSchedule),
Alexey Bataev24b5bae2016-04-28 09:23:51 +00005419 Data.Schedule.getPointer()
5420 ? CGF.Builder.CreateIntCast(Data.Schedule.getPointer(), CGF.Int64Ty,
Alexey Bataev2b19a6f2016-04-28 09:15:06 +00005421 /*isSigned=*/false)
5422 : llvm::ConstantInt::get(CGF.Int64Ty, /*V=*/0),
Alexey Bataev33446032017-07-12 18:09:32 +00005423 Result.TaskDupFn ? CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5424 Result.TaskDupFn, CGF.VoidPtrTy)
5425 : llvm::ConstantPointerNull::get(CGF.VoidPtrTy)};
Alexey Bataev7292c292016-04-25 12:22:29 +00005426 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_taskloop), TaskArgs);
5427}
5428
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00005429/// Emit reduction operation for each element of array (required for
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005430/// array sections) LHS op = RHS.
5431/// \param Type Type of array.
5432/// \param LHSVar Variable on the left side of the reduction operation
5433/// (references element of array in original variable).
5434/// \param RHSVar Variable on the right side of the reduction operation
5435/// (references element of array in original variable).
5436/// \param RedOpGen Generator of reduction operation with use of LHSVar and
5437/// RHSVar.
Benjamin Kramere003ca22015-10-28 13:54:16 +00005438static void EmitOMPAggregateReduction(
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005439 CodeGenFunction &CGF, QualType Type, const VarDecl *LHSVar,
5440 const VarDecl *RHSVar,
5441 const llvm::function_ref<void(CodeGenFunction &CGF, const Expr *,
5442 const Expr *, const Expr *)> &RedOpGen,
5443 const Expr *XExpr = nullptr, const Expr *EExpr = nullptr,
5444 const Expr *UpExpr = nullptr) {
5445 // Perform element-by-element initialization.
5446 QualType ElementTy;
5447 Address LHSAddr = CGF.GetAddrOfLocalVar(LHSVar);
5448 Address RHSAddr = CGF.GetAddrOfLocalVar(RHSVar);
5449
5450 // Drill down to the base element type on both arrays.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005451 const ArrayType *ArrayTy = Type->getAsArrayTypeUnsafe();
5452 llvm::Value *NumElements = CGF.emitArrayLength(ArrayTy, ElementTy, LHSAddr);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005453
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005454 llvm::Value *RHSBegin = RHSAddr.getPointer();
5455 llvm::Value *LHSBegin = LHSAddr.getPointer();
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005456 // Cast from pointer to array type to pointer to single element.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005457 llvm::Value *LHSEnd = CGF.Builder.CreateGEP(LHSBegin, NumElements);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005458 // The basic structure here is a while-do loop.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005459 llvm::BasicBlock *BodyBB = CGF.createBasicBlock("omp.arraycpy.body");
5460 llvm::BasicBlock *DoneBB = CGF.createBasicBlock("omp.arraycpy.done");
5461 llvm::Value *IsEmpty =
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005462 CGF.Builder.CreateICmpEQ(LHSBegin, LHSEnd, "omp.arraycpy.isempty");
5463 CGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
5464
5465 // Enter the loop body, making that address the current address.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005466 llvm::BasicBlock *EntryBB = CGF.Builder.GetInsertBlock();
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005467 CGF.EmitBlock(BodyBB);
5468
5469 CharUnits ElementSize = CGF.getContext().getTypeSizeInChars(ElementTy);
5470
5471 llvm::PHINode *RHSElementPHI = CGF.Builder.CreatePHI(
5472 RHSBegin->getType(), 2, "omp.arraycpy.srcElementPast");
5473 RHSElementPHI->addIncoming(RHSBegin, EntryBB);
5474 Address RHSElementCurrent =
5475 Address(RHSElementPHI,
5476 RHSAddr.getAlignment().alignmentOfArrayElement(ElementSize));
5477
5478 llvm::PHINode *LHSElementPHI = CGF.Builder.CreatePHI(
5479 LHSBegin->getType(), 2, "omp.arraycpy.destElementPast");
5480 LHSElementPHI->addIncoming(LHSBegin, EntryBB);
5481 Address LHSElementCurrent =
5482 Address(LHSElementPHI,
5483 LHSAddr.getAlignment().alignmentOfArrayElement(ElementSize));
5484
5485 // Emit copy.
5486 CodeGenFunction::OMPPrivateScope Scope(CGF);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005487 Scope.addPrivate(LHSVar, [=]() { return LHSElementCurrent; });
5488 Scope.addPrivate(RHSVar, [=]() { return RHSElementCurrent; });
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005489 Scope.Privatize();
5490 RedOpGen(CGF, XExpr, EExpr, UpExpr);
5491 Scope.ForceCleanup();
5492
5493 // Shift the address forward by one element.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005494 llvm::Value *LHSElementNext = CGF.Builder.CreateConstGEP1_32(
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005495 LHSElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005496 llvm::Value *RHSElementNext = CGF.Builder.CreateConstGEP1_32(
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005497 RHSElementPHI, /*Idx0=*/1, "omp.arraycpy.src.element");
5498 // Check whether we've reached the end.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005499 llvm::Value *Done =
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005500 CGF.Builder.CreateICmpEQ(LHSElementNext, LHSEnd, "omp.arraycpy.done");
5501 CGF.Builder.CreateCondBr(Done, DoneBB, BodyBB);
5502 LHSElementPHI->addIncoming(LHSElementNext, CGF.Builder.GetInsertBlock());
5503 RHSElementPHI->addIncoming(RHSElementNext, CGF.Builder.GetInsertBlock());
5504
5505 // Done.
5506 CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
5507}
5508
Alexey Bataeva839ddd2016-03-17 10:19:46 +00005509/// Emit reduction combiner. If the combiner is a simple expression emit it as
5510/// is, otherwise consider it as combiner of UDR decl and emit it as a call of
5511/// UDR combiner function.
5512static void emitReductionCombiner(CodeGenFunction &CGF,
5513 const Expr *ReductionOp) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005514 if (const auto *CE = dyn_cast<CallExpr>(ReductionOp))
5515 if (const auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee()))
5516 if (const auto *DRE =
Alexey Bataeva839ddd2016-03-17 10:19:46 +00005517 dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts()))
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005518 if (const auto *DRD =
5519 dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl())) {
Alexey Bataeva839ddd2016-03-17 10:19:46 +00005520 std::pair<llvm::Function *, llvm::Function *> Reduction =
5521 CGF.CGM.getOpenMPRuntime().getUserDefinedReduction(DRD);
5522 RValue Func = RValue::get(Reduction.first);
5523 CodeGenFunction::OpaqueValueMapping Map(CGF, OVE, Func);
5524 CGF.EmitIgnoredExpr(ReductionOp);
5525 return;
5526 }
5527 CGF.EmitIgnoredExpr(ReductionOp);
5528}
5529
James Y Knight9871db02019-02-05 16:42:33 +00005530llvm::Function *CGOpenMPRuntime::emitReductionFunction(
Alexey Bataev982a35e2019-03-19 17:09:52 +00005531 SourceLocation Loc, llvm::Type *ArgsType, ArrayRef<const Expr *> Privates,
5532 ArrayRef<const Expr *> LHSExprs, ArrayRef<const Expr *> RHSExprs,
5533 ArrayRef<const Expr *> ReductionOps) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005534 ASTContext &C = CGM.getContext();
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005535
5536 // void reduction_func(void *LHSArg, void *RHSArg);
5537 FunctionArgList Args;
Alexey Bataev7cae94e2018-01-04 19:45:16 +00005538 ImplicitParamDecl LHSArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
5539 ImplicitParamDecl::Other);
5540 ImplicitParamDecl RHSArg(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
5541 ImplicitParamDecl::Other);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005542 Args.push_back(&LHSArg);
5543 Args.push_back(&RHSArg);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005544 const auto &CGFI =
5545 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
Alexey Bataev18fa2322018-05-02 14:20:50 +00005546 std::string Name = getName({"omp", "reduction", "reduction_func"});
5547 auto *Fn = llvm::Function::Create(CGM.getTypes().GetFunctionType(CGFI),
5548 llvm::GlobalValue::InternalLinkage, Name,
5549 &CGM.getModule());
Rafael Espindola51ec5a92018-02-28 23:46:35 +00005550 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, CGFI);
Alexey Bataevc0f879b2018-04-10 20:10:53 +00005551 Fn->setDoesNotRecurse();
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005552 CodeGenFunction CGF(CGM);
Alexey Bataev7cae94e2018-01-04 19:45:16 +00005553 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, CGFI, Args, Loc, Loc);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005554
5555 // Dst = (void*[n])(LHSArg);
5556 // Src = (void*[n])(RHSArg);
John McCall7f416cc2015-09-08 08:05:57 +00005557 Address LHS(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5558 CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&LHSArg)),
5559 ArgsType), CGF.getPointerAlign());
5560 Address RHS(CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
5561 CGF.Builder.CreateLoad(CGF.GetAddrOfLocalVar(&RHSArg)),
5562 ArgsType), CGF.getPointerAlign());
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005563
5564 // ...
5565 // *(Type<i>*)lhs[i] = RedOp<i>(*(Type<i>*)lhs[i], *(Type<i>*)rhs[i]);
5566 // ...
5567 CodeGenFunction::OMPPrivateScope Scope(CGF);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005568 auto IPriv = Privates.begin();
5569 unsigned Idx = 0;
5570 for (unsigned I = 0, E = ReductionOps.size(); I < E; ++I, ++IPriv, ++Idx) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005571 const auto *RHSVar =
5572 cast<VarDecl>(cast<DeclRefExpr>(RHSExprs[I])->getDecl());
5573 Scope.addPrivate(RHSVar, [&CGF, RHS, Idx, RHSVar]() {
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005574 return emitAddrOfVarFromArray(CGF, RHS, Idx, RHSVar);
John McCall7f416cc2015-09-08 08:05:57 +00005575 });
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005576 const auto *LHSVar =
5577 cast<VarDecl>(cast<DeclRefExpr>(LHSExprs[I])->getDecl());
5578 Scope.addPrivate(LHSVar, [&CGF, LHS, Idx, LHSVar]() {
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005579 return emitAddrOfVarFromArray(CGF, LHS, Idx, LHSVar);
John McCall7f416cc2015-09-08 08:05:57 +00005580 });
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005581 QualType PrivTy = (*IPriv)->getType();
Alexey Bataev1189bd02016-01-26 12:20:39 +00005582 if (PrivTy->isVariablyModifiedType()) {
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005583 // Get array size and emit VLA type.
5584 ++Idx;
James Y Knight751fe282019-02-09 22:22:28 +00005585 Address Elem = CGF.Builder.CreateConstArrayGEP(LHS, Idx);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005586 llvm::Value *Ptr = CGF.Builder.CreateLoad(Elem);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005587 const VariableArrayType *VLA =
5588 CGF.getContext().getAsVariableArrayType(PrivTy);
5589 const auto *OVE = cast<OpaqueValueExpr>(VLA->getSizeExpr());
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005590 CodeGenFunction::OpaqueValueMapping OpaqueMap(
Alexey Bataev1189bd02016-01-26 12:20:39 +00005591 CGF, OVE, RValue::get(CGF.Builder.CreatePtrToInt(Ptr, CGF.SizeTy)));
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005592 CGF.EmitVariablyModifiedType(PrivTy);
5593 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005594 }
5595 Scope.Privatize();
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005596 IPriv = Privates.begin();
5597 auto ILHS = LHSExprs.begin();
5598 auto IRHS = RHSExprs.begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005599 for (const Expr *E : ReductionOps) {
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005600 if ((*IPriv)->getType()->isArrayType()) {
5601 // Emit reduction for array section.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005602 const auto *LHSVar = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
5603 const auto *RHSVar = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
Alexey Bataeva839ddd2016-03-17 10:19:46 +00005604 EmitOMPAggregateReduction(
5605 CGF, (*IPriv)->getType(), LHSVar, RHSVar,
5606 [=](CodeGenFunction &CGF, const Expr *, const Expr *, const Expr *) {
5607 emitReductionCombiner(CGF, E);
5608 });
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005609 } else {
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005610 // Emit reduction for array subscript or single variable.
Alexey Bataeva839ddd2016-03-17 10:19:46 +00005611 emitReductionCombiner(CGF, E);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005612 }
Richard Trieucc3949d2016-02-18 22:34:54 +00005613 ++IPriv;
5614 ++ILHS;
5615 ++IRHS;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005616 }
5617 Scope.ForceCleanup();
5618 CGF.FinishFunction();
5619 return Fn;
5620}
5621
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00005622void CGOpenMPRuntime::emitSingleReductionCombiner(CodeGenFunction &CGF,
5623 const Expr *ReductionOp,
5624 const Expr *PrivateRef,
5625 const DeclRefExpr *LHS,
5626 const DeclRefExpr *RHS) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005627 if (PrivateRef->getType()->isArrayType()) {
5628 // Emit reduction for array section.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005629 const auto *LHSVar = cast<VarDecl>(LHS->getDecl());
5630 const auto *RHSVar = cast<VarDecl>(RHS->getDecl());
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005631 EmitOMPAggregateReduction(
5632 CGF, PrivateRef->getType(), LHSVar, RHSVar,
5633 [=](CodeGenFunction &CGF, const Expr *, const Expr *, const Expr *) {
5634 emitReductionCombiner(CGF, ReductionOp);
5635 });
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005636 } else {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005637 // Emit reduction for array subscript or single variable.
5638 emitReductionCombiner(CGF, ReductionOp);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005639 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005640}
5641
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005642void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005643 ArrayRef<const Expr *> Privates,
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005644 ArrayRef<const Expr *> LHSExprs,
5645 ArrayRef<const Expr *> RHSExprs,
5646 ArrayRef<const Expr *> ReductionOps,
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00005647 ReductionOptionsTy Options) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00005648 if (!CGF.HaveInsertPoint())
5649 return;
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00005650
5651 bool WithNowait = Options.WithNowait;
5652 bool SimpleReduction = Options.SimpleReduction;
5653
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005654 // Next code should be emitted for reduction:
5655 //
5656 // static kmp_critical_name lock = { 0 };
5657 //
5658 // void reduce_func(void *lhs[<n>], void *rhs[<n>]) {
5659 // *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]);
5660 // ...
5661 // *(Type<n>-1*)lhs[<n>-1] = ReductionOperation<n>-1(*(Type<n>-1*)lhs[<n>-1],
5662 // *(Type<n>-1*)rhs[<n>-1]);
5663 // }
5664 //
5665 // ...
5666 // void *RedList[<n>] = {&<RHSExprs>[0], ..., &<RHSExprs>[<n>-1]};
5667 // switch (__kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList),
5668 // RedList, reduce_func, &<lock>)) {
5669 // case 1:
5670 // ...
5671 // <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
5672 // ...
5673 // __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
5674 // break;
5675 // case 2:
5676 // ...
5677 // Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
5678 // ...
Alexey Bataev69a47792015-05-07 03:54:03 +00005679 // [__kmpc_end_reduce(<loc>, <gtid>, &<lock>);]
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005680 // break;
5681 // default:;
5682 // }
Alexey Bataev89e7e8e2015-06-17 06:21:39 +00005683 //
5684 // if SimpleReduction is true, only the next code is generated:
5685 // ...
5686 // <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
5687 // ...
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005688
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005689 ASTContext &C = CGM.getContext();
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005690
Alexey Bataev89e7e8e2015-06-17 06:21:39 +00005691 if (SimpleReduction) {
5692 CodeGenFunction::RunCleanupsScope Scope(CGF);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005693 auto IPriv = Privates.begin();
5694 auto ILHS = LHSExprs.begin();
5695 auto IRHS = RHSExprs.begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005696 for (const Expr *E : ReductionOps) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005697 emitSingleReductionCombiner(CGF, E, *IPriv, cast<DeclRefExpr>(*ILHS),
5698 cast<DeclRefExpr>(*IRHS));
Richard Trieucc3949d2016-02-18 22:34:54 +00005699 ++IPriv;
5700 ++ILHS;
5701 ++IRHS;
Alexey Bataev89e7e8e2015-06-17 06:21:39 +00005702 }
5703 return;
5704 }
5705
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005706 // 1. Build a list of reduction variables.
5707 // void *RedList[<n>] = {<ReductionVars>[0], ..., <ReductionVars>[<n>-1]};
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005708 auto Size = RHSExprs.size();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005709 for (const Expr *E : Privates) {
Alexey Bataev1189bd02016-01-26 12:20:39 +00005710 if (E->getType()->isVariablyModifiedType())
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005711 // Reserve place for array size.
5712 ++Size;
5713 }
5714 llvm::APInt ArraySize(/*unsigned int numBits=*/32, Size);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005715 QualType ReductionArrayTy =
5716 C.getConstantArrayType(C.VoidPtrTy, ArraySize, ArrayType::Normal,
5717 /*IndexTypeQuals=*/0);
John McCall7f416cc2015-09-08 08:05:57 +00005718 Address ReductionList =
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005719 CGF.CreateMemTemp(ReductionArrayTy, ".omp.reduction.red_list");
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005720 auto IPriv = Privates.begin();
5721 unsigned Idx = 0;
5722 for (unsigned I = 0, E = RHSExprs.size(); I < E; ++I, ++IPriv, ++Idx) {
James Y Knight751fe282019-02-09 22:22:28 +00005723 Address Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx);
John McCall7f416cc2015-09-08 08:05:57 +00005724 CGF.Builder.CreateStore(
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005725 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
John McCall7f416cc2015-09-08 08:05:57 +00005726 CGF.EmitLValue(RHSExprs[I]).getPointer(), CGF.VoidPtrTy),
5727 Elem);
Alexey Bataev1189bd02016-01-26 12:20:39 +00005728 if ((*IPriv)->getType()->isVariablyModifiedType()) {
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005729 // Store array size.
5730 ++Idx;
James Y Knight751fe282019-02-09 22:22:28 +00005731 Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx);
Alexey Bataev1189bd02016-01-26 12:20:39 +00005732 llvm::Value *Size = CGF.Builder.CreateIntCast(
5733 CGF.getVLASize(
5734 CGF.getContext().getAsVariableArrayType((*IPriv)->getType()))
Sander de Smalen891af03a2018-02-03 13:55:59 +00005735 .NumElts,
Alexey Bataev1189bd02016-01-26 12:20:39 +00005736 CGF.SizeTy, /*isSigned=*/false);
5737 CGF.Builder.CreateStore(CGF.Builder.CreateIntToPtr(Size, CGF.VoidPtrTy),
5738 Elem);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005739 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005740 }
5741
5742 // 2. Emit reduce_func().
James Y Knight9871db02019-02-05 16:42:33 +00005743 llvm::Function *ReductionFn = emitReductionFunction(
Alexey Bataev982a35e2019-03-19 17:09:52 +00005744 Loc, CGF.ConvertTypeForMem(ReductionArrayTy)->getPointerTo(), Privates,
5745 LHSExprs, RHSExprs, ReductionOps);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005746
5747 // 3. Create static kmp_critical_name lock = { 0 };
Alexey Bataev18fa2322018-05-02 14:20:50 +00005748 std::string Name = getName({"reduction"});
5749 llvm::Value *Lock = getCriticalRegionLock(Name);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005750
5751 // 4. Build res = __kmpc_reduce{_nowait}(<loc>, <gtid>, <n>, sizeof(RedList),
5752 // RedList, reduce_func, &<lock>);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005753 llvm::Value *IdentTLoc = emitUpdateLocation(CGF, Loc, OMP_ATOMIC_REDUCE);
5754 llvm::Value *ThreadId = getThreadID(CGF, Loc);
5755 llvm::Value *ReductionArrayTySize = CGF.getTypeSize(ReductionArrayTy);
5756 llvm::Value *RL = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
Samuel Antao4c8035b2016-12-12 18:00:20 +00005757 ReductionList.getPointer(), CGF.VoidPtrTy);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005758 llvm::Value *Args[] = {
5759 IdentTLoc, // ident_t *<loc>
5760 ThreadId, // i32 <gtid>
5761 CGF.Builder.getInt32(RHSExprs.size()), // i32 <n>
5762 ReductionArrayTySize, // size_type sizeof(RedList)
5763 RL, // void *RedList
5764 ReductionFn, // void (*) (void *, void *) <reduce_func>
5765 Lock // kmp_critical_name *&<lock>
5766 };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005767 llvm::Value *Res = CGF.EmitRuntimeCall(
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005768 createRuntimeFunction(WithNowait ? OMPRTL__kmpc_reduce_nowait
5769 : OMPRTL__kmpc_reduce),
5770 Args);
5771
5772 // 5. Build switch(res)
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005773 llvm::BasicBlock *DefaultBB = CGF.createBasicBlock(".omp.reduction.default");
5774 llvm::SwitchInst *SwInst =
5775 CGF.Builder.CreateSwitch(Res, DefaultBB, /*NumCases=*/2);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005776
5777 // 6. Build case 1:
5778 // ...
5779 // <LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]);
5780 // ...
5781 // __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
5782 // break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005783 llvm::BasicBlock *Case1BB = CGF.createBasicBlock(".omp.reduction.case1");
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005784 SwInst->addCase(CGF.Builder.getInt32(1), Case1BB);
5785 CGF.EmitBlock(Case1BB);
5786
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005787 // Add emission of __kmpc_end_reduce{_nowait}(<loc>, <gtid>, &<lock>);
5788 llvm::Value *EndArgs[] = {
5789 IdentTLoc, // ident_t *<loc>
5790 ThreadId, // i32 <gtid>
5791 Lock // kmp_critical_name *&<lock>
5792 };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005793 auto &&CodeGen = [Privates, LHSExprs, RHSExprs, ReductionOps](
5794 CodeGenFunction &CGF, PrePostActionTy &Action) {
5795 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005796 auto IPriv = Privates.begin();
5797 auto ILHS = LHSExprs.begin();
5798 auto IRHS = RHSExprs.begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005799 for (const Expr *E : ReductionOps) {
Arpith Chacko Jacob101e8fb2017-02-16 16:20:16 +00005800 RT.emitSingleReductionCombiner(CGF, E, *IPriv, cast<DeclRefExpr>(*ILHS),
5801 cast<DeclRefExpr>(*IRHS));
Richard Trieucc3949d2016-02-18 22:34:54 +00005802 ++IPriv;
5803 ++ILHS;
5804 ++IRHS;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005805 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005806 };
5807 RegionCodeGenTy RCG(CodeGen);
5808 CommonActionTy Action(
5809 nullptr, llvm::None,
5810 createRuntimeFunction(WithNowait ? OMPRTL__kmpc_end_reduce_nowait
5811 : OMPRTL__kmpc_end_reduce),
5812 EndArgs);
5813 RCG.setAction(Action);
5814 RCG(CGF);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005815
5816 CGF.EmitBranch(DefaultBB);
5817
5818 // 7. Build case 2:
5819 // ...
5820 // Atomic(<LHSExprs>[i] = RedOp<i>(*<LHSExprs>[i], *<RHSExprs>[i]));
5821 // ...
5822 // break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005823 llvm::BasicBlock *Case2BB = CGF.createBasicBlock(".omp.reduction.case2");
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005824 SwInst->addCase(CGF.Builder.getInt32(2), Case2BB);
5825 CGF.EmitBlock(Case2BB);
5826
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005827 auto &&AtomicCodeGen = [Loc, Privates, LHSExprs, RHSExprs, ReductionOps](
5828 CodeGenFunction &CGF, PrePostActionTy &Action) {
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005829 auto ILHS = LHSExprs.begin();
5830 auto IRHS = RHSExprs.begin();
5831 auto IPriv = Privates.begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005832 for (const Expr *E : ReductionOps) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005833 const Expr *XExpr = nullptr;
5834 const Expr *EExpr = nullptr;
5835 const Expr *UpExpr = nullptr;
5836 BinaryOperatorKind BO = BO_Comma;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005837 if (const auto *BO = dyn_cast<BinaryOperator>(E)) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005838 if (BO->getOpcode() == BO_Assign) {
5839 XExpr = BO->getLHS();
5840 UpExpr = BO->getRHS();
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005841 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005842 }
5843 // Try to emit update expression as a simple atomic.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005844 const Expr *RHSExpr = UpExpr;
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005845 if (RHSExpr) {
5846 // Analyze RHS part of the whole expression.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005847 if (const auto *ACO = dyn_cast<AbstractConditionalOperator>(
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005848 RHSExpr->IgnoreParenImpCasts())) {
5849 // If this is a conditional operator, analyze its condition for
5850 // min/max reduction operator.
5851 RHSExpr = ACO->getCond();
Alexey Bataev69a47792015-05-07 03:54:03 +00005852 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005853 if (const auto *BORHS =
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005854 dyn_cast<BinaryOperator>(RHSExpr->IgnoreParenImpCasts())) {
5855 EExpr = BORHS->getRHS();
5856 BO = BORHS->getOpcode();
Alexey Bataevf24e7b12015-10-08 09:10:53 +00005857 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005858 }
5859 if (XExpr) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005860 const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
Malcolm Parsonsc6e45832017-01-13 18:55:32 +00005861 auto &&AtomicRedGen = [BO, VD,
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005862 Loc](CodeGenFunction &CGF, const Expr *XExpr,
5863 const Expr *EExpr, const Expr *UpExpr) {
5864 LValue X = CGF.EmitLValue(XExpr);
5865 RValue E;
5866 if (EExpr)
5867 E = CGF.EmitAnyExpr(EExpr);
5868 CGF.EmitOMPAtomicSimpleUpdateExpr(
JF Bastien92f4ef12016-04-06 17:26:42 +00005869 X, E, BO, /*IsXLHSInRHSPart=*/true,
5870 llvm::AtomicOrdering::Monotonic, Loc,
Malcolm Parsonsc6e45832017-01-13 18:55:32 +00005871 [&CGF, UpExpr, VD, Loc](RValue XRValue) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005872 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
5873 PrivateScope.addPrivate(
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005874 VD, [&CGF, VD, XRValue, Loc]() {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005875 Address LHSTemp = CGF.CreateMemTemp(VD->getType());
5876 CGF.emitOMPSimpleStore(
5877 CGF.MakeAddrLValue(LHSTemp, VD->getType()), XRValue,
5878 VD->getType().getNonReferenceType(), Loc);
5879 return LHSTemp;
5880 });
5881 (void)PrivateScope.Privatize();
5882 return CGF.EmitAnyExpr(UpExpr);
5883 });
5884 };
5885 if ((*IPriv)->getType()->isArrayType()) {
5886 // Emit atomic reduction for array section.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005887 const auto *RHSVar =
5888 cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005889 EmitOMPAggregateReduction(CGF, (*IPriv)->getType(), VD, RHSVar,
5890 AtomicRedGen, XExpr, EExpr, UpExpr);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005891 } else {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005892 // Emit atomic reduction for array subscript or single variable.
5893 AtomicRedGen(CGF, XExpr, EExpr, UpExpr);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005894 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005895 } else {
5896 // Emit as a critical region.
5897 auto &&CritRedGen = [E, Loc](CodeGenFunction &CGF, const Expr *,
Alexey Bataev18fa2322018-05-02 14:20:50 +00005898 const Expr *, const Expr *) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005899 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
Alexey Bataev18fa2322018-05-02 14:20:50 +00005900 std::string Name = RT.getName({"atomic_reduction"});
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005901 RT.emitCriticalRegion(
Alexey Bataev18fa2322018-05-02 14:20:50 +00005902 CGF, Name,
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005903 [=](CodeGenFunction &CGF, PrePostActionTy &Action) {
5904 Action.Enter(CGF);
5905 emitReductionCombiner(CGF, E);
5906 },
5907 Loc);
5908 };
5909 if ((*IPriv)->getType()->isArrayType()) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005910 const auto *LHSVar =
5911 cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
5912 const auto *RHSVar =
5913 cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005914 EmitOMPAggregateReduction(CGF, (*IPriv)->getType(), LHSVar, RHSVar,
5915 CritRedGen);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005916 } else {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005917 CritRedGen(CGF, nullptr, nullptr, nullptr);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005918 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005919 }
Richard Trieucc3949d2016-02-18 22:34:54 +00005920 ++ILHS;
5921 ++IRHS;
5922 ++IPriv;
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005923 }
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005924 };
5925 RegionCodeGenTy AtomicRCG(AtomicCodeGen);
5926 if (!WithNowait) {
5927 // Add emission of __kmpc_end_reduce(<loc>, <gtid>, &<lock>);
5928 llvm::Value *EndArgs[] = {
5929 IdentTLoc, // ident_t *<loc>
5930 ThreadId, // i32 <gtid>
5931 Lock // kmp_critical_name *&<lock>
5932 };
5933 CommonActionTy Action(nullptr, llvm::None,
5934 createRuntimeFunction(OMPRTL__kmpc_end_reduce),
5935 EndArgs);
5936 AtomicRCG.setAction(Action);
5937 AtomicRCG(CGF);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005938 } else {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00005939 AtomicRCG(CGF);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005940 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00005941
5942 CGF.EmitBranch(DefaultBB);
5943 CGF.EmitBlock(DefaultBB, /*IsFinished=*/true);
5944}
5945
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00005946/// Generates unique name for artificial threadprivate variables.
Alexey Bataev1c44e152018-03-06 18:59:43 +00005947/// Format is: <Prefix> "." <Decl_mangled_name> "_" "<Decl_start_loc_raw_enc>"
5948static std::string generateUniqueName(CodeGenModule &CGM, StringRef Prefix,
5949 const Expr *Ref) {
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00005950 SmallString<256> Buffer;
5951 llvm::raw_svector_ostream Out(Buffer);
Alexey Bataev1c44e152018-03-06 18:59:43 +00005952 const clang::DeclRefExpr *DE;
5953 const VarDecl *D = ::getBaseDecl(Ref, DE);
5954 if (!D)
5955 D = cast<VarDecl>(cast<DeclRefExpr>(Ref)->getDecl());
5956 D = D->getCanonicalDecl();
Alexey Bataev18fa2322018-05-02 14:20:50 +00005957 std::string Name = CGM.getOpenMPRuntime().getName(
5958 {D->isLocalVarDeclOrParm() ? D->getName() : CGM.getMangledName(D)});
5959 Out << Prefix << Name << "_"
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005960 << D->getCanonicalDecl()->getBeginLoc().getRawEncoding();
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00005961 return Out.str();
5962}
5963
5964/// Emits reduction initializer function:
5965/// \code
5966/// void @.red_init(void* %arg) {
5967/// %0 = bitcast void* %arg to <type>*
5968/// store <type> <init>, <type>* %0
5969/// ret void
5970/// }
5971/// \endcode
5972static llvm::Value *emitReduceInitFunction(CodeGenModule &CGM,
5973 SourceLocation Loc,
5974 ReductionCodeGen &RCG, unsigned N) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005975 ASTContext &C = CGM.getContext();
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00005976 FunctionArgList Args;
Alexey Bataev7cae94e2018-01-04 19:45:16 +00005977 ImplicitParamDecl Param(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
5978 ImplicitParamDecl::Other);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00005979 Args.emplace_back(&Param);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005980 const auto &FnInfo =
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00005981 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00005982 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
Alexey Bataev18fa2322018-05-02 14:20:50 +00005983 std::string Name = CGM.getOpenMPRuntime().getName({"red_init", ""});
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00005984 auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
Alexey Bataev18fa2322018-05-02 14:20:50 +00005985 Name, &CGM.getModule());
Rafael Espindola51ec5a92018-02-28 23:46:35 +00005986 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo);
Alexey Bataevc0f879b2018-04-10 20:10:53 +00005987 Fn->setDoesNotRecurse();
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00005988 CodeGenFunction CGF(CGM);
Alexey Bataev7cae94e2018-01-04 19:45:16 +00005989 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, Loc, Loc);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00005990 Address PrivateAddr = CGF.EmitLoadOfPointer(
5991 CGF.GetAddrOfLocalVar(&Param),
5992 C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
5993 llvm::Value *Size = nullptr;
5994 // If the size of the reduction item is non-constant, load it from global
5995 // threadprivate variable.
5996 if (RCG.getSizes(N).second) {
5997 Address SizeAddr = CGM.getOpenMPRuntime().getAddrOfArtificialThreadPrivate(
5998 CGF, CGM.getContext().getSizeType(),
Alexey Bataev1c44e152018-03-06 18:59:43 +00005999 generateUniqueName(CGM, "reduction_size", RCG.getRefExpr(N)));
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00006000 Size = CGF.EmitLoadOfScalar(SizeAddr, /*Volatile=*/false,
6001 CGM.getContext().getSizeType(), Loc);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006002 }
6003 RCG.emitAggregateType(CGF, N, Size);
6004 LValue SharedLVal;
6005 // If initializer uses initializer from declare reduction construct, emit a
6006 // pointer to the address of the original reduction item (reuired by reduction
6007 // initializer)
6008 if (RCG.usesReductionInitializer(N)) {
6009 Address SharedAddr =
6010 CGM.getOpenMPRuntime().getAddrOfArtificialThreadPrivate(
6011 CGF, CGM.getContext().VoidPtrTy,
Alexey Bataev1c44e152018-03-06 18:59:43 +00006012 generateUniqueName(CGM, "reduction", RCG.getRefExpr(N)));
Alexey Bataev21dab122018-03-09 15:20:30 +00006013 SharedAddr = CGF.EmitLoadOfPointer(
6014 SharedAddr,
6015 CGM.getContext().VoidPtrTy.castAs<PointerType>()->getTypePtr());
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006016 SharedLVal = CGF.MakeAddrLValue(SharedAddr, CGM.getContext().VoidPtrTy);
6017 } else {
6018 SharedLVal = CGF.MakeNaturalAlignAddrLValue(
6019 llvm::ConstantPointerNull::get(CGM.VoidPtrTy),
6020 CGM.getContext().VoidPtrTy);
6021 }
6022 // Emit the initializer:
6023 // %0 = bitcast void* %arg to <type>*
6024 // store <type> <init>, <type>* %0
6025 RCG.emitInitialization(CGF, N, PrivateAddr, SharedLVal,
6026 [](CodeGenFunction &) { return false; });
6027 CGF.FinishFunction();
6028 return Fn;
6029}
6030
6031/// Emits reduction combiner function:
6032/// \code
6033/// void @.red_comb(void* %arg0, void* %arg1) {
6034/// %lhs = bitcast void* %arg0 to <type>*
6035/// %rhs = bitcast void* %arg1 to <type>*
6036/// %2 = <ReductionOp>(<type>* %lhs, <type>* %rhs)
6037/// store <type> %2, <type>* %lhs
6038/// ret void
6039/// }
6040/// \endcode
6041static llvm::Value *emitReduceCombFunction(CodeGenModule &CGM,
6042 SourceLocation Loc,
6043 ReductionCodeGen &RCG, unsigned N,
6044 const Expr *ReductionOp,
6045 const Expr *LHS, const Expr *RHS,
6046 const Expr *PrivateRef) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006047 ASTContext &C = CGM.getContext();
6048 const auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(LHS)->getDecl());
6049 const auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(RHS)->getDecl());
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006050 FunctionArgList Args;
Alexey Bataev7cae94e2018-01-04 19:45:16 +00006051 ImplicitParamDecl ParamInOut(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr,
6052 C.VoidPtrTy, ImplicitParamDecl::Other);
6053 ImplicitParamDecl ParamIn(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
6054 ImplicitParamDecl::Other);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006055 Args.emplace_back(&ParamInOut);
6056 Args.emplace_back(&ParamIn);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006057 const auto &FnInfo =
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006058 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006059 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
Alexey Bataev18fa2322018-05-02 14:20:50 +00006060 std::string Name = CGM.getOpenMPRuntime().getName({"red_comb", ""});
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006061 auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
Alexey Bataev18fa2322018-05-02 14:20:50 +00006062 Name, &CGM.getModule());
Rafael Espindola51ec5a92018-02-28 23:46:35 +00006063 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo);
Alexey Bataevc0f879b2018-04-10 20:10:53 +00006064 Fn->setDoesNotRecurse();
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006065 CodeGenFunction CGF(CGM);
Alexey Bataev7cae94e2018-01-04 19:45:16 +00006066 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, Loc, Loc);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006067 llvm::Value *Size = nullptr;
6068 // If the size of the reduction item is non-constant, load it from global
6069 // threadprivate variable.
6070 if (RCG.getSizes(N).second) {
6071 Address SizeAddr = CGM.getOpenMPRuntime().getAddrOfArtificialThreadPrivate(
6072 CGF, CGM.getContext().getSizeType(),
Alexey Bataev1c44e152018-03-06 18:59:43 +00006073 generateUniqueName(CGM, "reduction_size", RCG.getRefExpr(N)));
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00006074 Size = CGF.EmitLoadOfScalar(SizeAddr, /*Volatile=*/false,
6075 CGM.getContext().getSizeType(), Loc);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006076 }
6077 RCG.emitAggregateType(CGF, N, Size);
6078 // Remap lhs and rhs variables to the addresses of the function arguments.
6079 // %lhs = bitcast void* %arg0 to <type>*
6080 // %rhs = bitcast void* %arg1 to <type>*
6081 CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006082 PrivateScope.addPrivate(LHSVD, [&C, &CGF, &ParamInOut, LHSVD]() {
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006083 // Pull out the pointer to the variable.
6084 Address PtrAddr = CGF.EmitLoadOfPointer(
6085 CGF.GetAddrOfLocalVar(&ParamInOut),
6086 C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
6087 return CGF.Builder.CreateElementBitCast(
6088 PtrAddr, CGF.ConvertTypeForMem(LHSVD->getType()));
6089 });
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006090 PrivateScope.addPrivate(RHSVD, [&C, &CGF, &ParamIn, RHSVD]() {
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006091 // Pull out the pointer to the variable.
6092 Address PtrAddr = CGF.EmitLoadOfPointer(
6093 CGF.GetAddrOfLocalVar(&ParamIn),
6094 C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
6095 return CGF.Builder.CreateElementBitCast(
6096 PtrAddr, CGF.ConvertTypeForMem(RHSVD->getType()));
6097 });
6098 PrivateScope.Privatize();
6099 // Emit the combiner body:
6100 // %2 = <ReductionOp>(<type> *%lhs, <type> *%rhs)
6101 // store <type> %2, <type>* %lhs
6102 CGM.getOpenMPRuntime().emitSingleReductionCombiner(
6103 CGF, ReductionOp, PrivateRef, cast<DeclRefExpr>(LHS),
6104 cast<DeclRefExpr>(RHS));
6105 CGF.FinishFunction();
6106 return Fn;
6107}
6108
6109/// Emits reduction finalizer function:
6110/// \code
6111/// void @.red_fini(void* %arg) {
6112/// %0 = bitcast void* %arg to <type>*
6113/// <destroy>(<type>* %0)
6114/// ret void
6115/// }
6116/// \endcode
6117static llvm::Value *emitReduceFiniFunction(CodeGenModule &CGM,
6118 SourceLocation Loc,
6119 ReductionCodeGen &RCG, unsigned N) {
6120 if (!RCG.needCleanups(N))
6121 return nullptr;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006122 ASTContext &C = CGM.getContext();
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006123 FunctionArgList Args;
Alexey Bataev7cae94e2018-01-04 19:45:16 +00006124 ImplicitParamDecl Param(C, /*DC=*/nullptr, Loc, /*Id=*/nullptr, C.VoidPtrTy,
6125 ImplicitParamDecl::Other);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006126 Args.emplace_back(&Param);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006127 const auto &FnInfo =
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006128 CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006129 llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
Alexey Bataev18fa2322018-05-02 14:20:50 +00006130 std::string Name = CGM.getOpenMPRuntime().getName({"red_fini", ""});
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006131 auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
Alexey Bataev18fa2322018-05-02 14:20:50 +00006132 Name, &CGM.getModule());
Rafael Espindola51ec5a92018-02-28 23:46:35 +00006133 CGM.SetInternalFunctionAttributes(GlobalDecl(), Fn, FnInfo);
Alexey Bataevc0f879b2018-04-10 20:10:53 +00006134 Fn->setDoesNotRecurse();
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006135 CodeGenFunction CGF(CGM);
Alexey Bataev7cae94e2018-01-04 19:45:16 +00006136 CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args, Loc, Loc);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006137 Address PrivateAddr = CGF.EmitLoadOfPointer(
6138 CGF.GetAddrOfLocalVar(&Param),
6139 C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
6140 llvm::Value *Size = nullptr;
6141 // If the size of the reduction item is non-constant, load it from global
6142 // threadprivate variable.
6143 if (RCG.getSizes(N).second) {
6144 Address SizeAddr = CGM.getOpenMPRuntime().getAddrOfArtificialThreadPrivate(
6145 CGF, CGM.getContext().getSizeType(),
Alexey Bataev1c44e152018-03-06 18:59:43 +00006146 generateUniqueName(CGM, "reduction_size", RCG.getRefExpr(N)));
Alexey Bataeva9b9cc02018-01-23 18:12:38 +00006147 Size = CGF.EmitLoadOfScalar(SizeAddr, /*Volatile=*/false,
6148 CGM.getContext().getSizeType(), Loc);
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006149 }
6150 RCG.emitAggregateType(CGF, N, Size);
6151 // Emit the finalizer body:
6152 // <destroy>(<type>* %0)
6153 RCG.emitCleanups(CGF, N, PrivateAddr);
6154 CGF.FinishFunction();
6155 return Fn;
6156}
6157
6158llvm::Value *CGOpenMPRuntime::emitTaskReductionInit(
6159 CodeGenFunction &CGF, SourceLocation Loc, ArrayRef<const Expr *> LHSExprs,
6160 ArrayRef<const Expr *> RHSExprs, const OMPTaskDataTy &Data) {
6161 if (!CGF.HaveInsertPoint() || Data.ReductionVars.empty())
6162 return nullptr;
6163
6164 // Build typedef struct:
6165 // kmp_task_red_input {
6166 // void *reduce_shar; // shared reduction item
6167 // size_t reduce_size; // size of data item
6168 // void *reduce_init; // data initialization routine
6169 // void *reduce_fini; // data finalization routine
6170 // void *reduce_comb; // data combiner routine
6171 // kmp_task_red_flags_t flags; // flags for additional info from compiler
6172 // } kmp_task_red_input_t;
6173 ASTContext &C = CGM.getContext();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006174 RecordDecl *RD = C.buildImplicitRecord("kmp_task_red_input_t");
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006175 RD->startDefinition();
6176 const FieldDecl *SharedFD = addFieldToRecordDecl(C, RD, C.VoidPtrTy);
6177 const FieldDecl *SizeFD = addFieldToRecordDecl(C, RD, C.getSizeType());
6178 const FieldDecl *InitFD = addFieldToRecordDecl(C, RD, C.VoidPtrTy);
6179 const FieldDecl *FiniFD = addFieldToRecordDecl(C, RD, C.VoidPtrTy);
6180 const FieldDecl *CombFD = addFieldToRecordDecl(C, RD, C.VoidPtrTy);
6181 const FieldDecl *FlagsFD = addFieldToRecordDecl(
6182 C, RD, C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/false));
6183 RD->completeDefinition();
6184 QualType RDType = C.getRecordType(RD);
6185 unsigned Size = Data.ReductionVars.size();
6186 llvm::APInt ArraySize(/*numBits=*/64, Size);
6187 QualType ArrayRDType = C.getConstantArrayType(
6188 RDType, ArraySize, ArrayType::Normal, /*IndexTypeQuals=*/0);
6189 // kmp_task_red_input_t .rd_input.[Size];
6190 Address TaskRedInput = CGF.CreateMemTemp(ArrayRDType, ".rd_input.");
6191 ReductionCodeGen RCG(Data.ReductionVars, Data.ReductionCopies,
6192 Data.ReductionOps);
6193 for (unsigned Cnt = 0; Cnt < Size; ++Cnt) {
6194 // kmp_task_red_input_t &ElemLVal = .rd_input.[Cnt];
6195 llvm::Value *Idxs[] = {llvm::ConstantInt::get(CGM.SizeTy, /*V=*/0),
6196 llvm::ConstantInt::get(CGM.SizeTy, Cnt)};
6197 llvm::Value *GEP = CGF.EmitCheckedInBoundsGEP(
6198 TaskRedInput.getPointer(), Idxs,
6199 /*SignedIndices=*/false, /*IsSubtraction=*/false, Loc,
6200 ".rd_input.gep.");
6201 LValue ElemLVal = CGF.MakeNaturalAlignAddrLValue(GEP, RDType);
6202 // ElemLVal.reduce_shar = &Shareds[Cnt];
6203 LValue SharedLVal = CGF.EmitLValueForField(ElemLVal, SharedFD);
6204 RCG.emitSharedLValue(CGF, Cnt);
6205 llvm::Value *CastedShared =
6206 CGF.EmitCastToVoidPtr(RCG.getSharedLValue(Cnt).getPointer());
6207 CGF.EmitStoreOfScalar(CastedShared, SharedLVal);
6208 RCG.emitAggregateType(CGF, Cnt);
6209 llvm::Value *SizeValInChars;
6210 llvm::Value *SizeVal;
6211 std::tie(SizeValInChars, SizeVal) = RCG.getSizes(Cnt);
6212 // We use delayed creation/initialization for VLAs, array sections and
6213 // custom reduction initializations. It is required because runtime does not
6214 // provide the way to pass the sizes of VLAs/array sections to
6215 // initializer/combiner/finalizer functions and does not pass the pointer to
6216 // original reduction item to the initializer. Instead threadprivate global
6217 // variables are used to store these values and use them in the functions.
6218 bool DelayedCreation = !!SizeVal;
6219 SizeValInChars = CGF.Builder.CreateIntCast(SizeValInChars, CGM.SizeTy,
6220 /*isSigned=*/false);
6221 LValue SizeLVal = CGF.EmitLValueForField(ElemLVal, SizeFD);
6222 CGF.EmitStoreOfScalar(SizeValInChars, SizeLVal);
6223 // ElemLVal.reduce_init = init;
6224 LValue InitLVal = CGF.EmitLValueForField(ElemLVal, InitFD);
6225 llvm::Value *InitAddr =
6226 CGF.EmitCastToVoidPtr(emitReduceInitFunction(CGM, Loc, RCG, Cnt));
6227 CGF.EmitStoreOfScalar(InitAddr, InitLVal);
6228 DelayedCreation = DelayedCreation || RCG.usesReductionInitializer(Cnt);
6229 // ElemLVal.reduce_fini = fini;
6230 LValue FiniLVal = CGF.EmitLValueForField(ElemLVal, FiniFD);
6231 llvm::Value *Fini = emitReduceFiniFunction(CGM, Loc, RCG, Cnt);
6232 llvm::Value *FiniAddr = Fini
6233 ? CGF.EmitCastToVoidPtr(Fini)
6234 : llvm::ConstantPointerNull::get(CGM.VoidPtrTy);
6235 CGF.EmitStoreOfScalar(FiniAddr, FiniLVal);
6236 // ElemLVal.reduce_comb = comb;
6237 LValue CombLVal = CGF.EmitLValueForField(ElemLVal, CombFD);
6238 llvm::Value *CombAddr = CGF.EmitCastToVoidPtr(emitReduceCombFunction(
6239 CGM, Loc, RCG, Cnt, Data.ReductionOps[Cnt], LHSExprs[Cnt],
6240 RHSExprs[Cnt], Data.ReductionCopies[Cnt]));
6241 CGF.EmitStoreOfScalar(CombAddr, CombLVal);
6242 // ElemLVal.flags = 0;
6243 LValue FlagsLVal = CGF.EmitLValueForField(ElemLVal, FlagsFD);
6244 if (DelayedCreation) {
6245 CGF.EmitStoreOfScalar(
6246 llvm::ConstantInt::get(CGM.Int32Ty, /*V=*/1, /*IsSigned=*/true),
6247 FlagsLVal);
6248 } else
6249 CGF.EmitNullInitialization(FlagsLVal.getAddress(), FlagsLVal.getType());
6250 }
6251 // Build call void *__kmpc_task_reduction_init(int gtid, int num_data, void
6252 // *data);
6253 llvm::Value *Args[] = {
6254 CGF.Builder.CreateIntCast(getThreadID(CGF, Loc), CGM.IntTy,
6255 /*isSigned=*/true),
6256 llvm::ConstantInt::get(CGM.IntTy, Size, /*isSigned=*/true),
6257 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(TaskRedInput.getPointer(),
6258 CGM.VoidPtrTy)};
6259 return CGF.EmitRuntimeCall(
6260 createRuntimeFunction(OMPRTL__kmpc_task_reduction_init), Args);
6261}
6262
6263void CGOpenMPRuntime::emitTaskReductionFixups(CodeGenFunction &CGF,
6264 SourceLocation Loc,
6265 ReductionCodeGen &RCG,
6266 unsigned N) {
6267 auto Sizes = RCG.getSizes(N);
6268 // Emit threadprivate global variable if the type is non-constant
6269 // (Sizes.second = nullptr).
6270 if (Sizes.second) {
6271 llvm::Value *SizeVal = CGF.Builder.CreateIntCast(Sizes.second, CGM.SizeTy,
6272 /*isSigned=*/false);
6273 Address SizeAddr = getAddrOfArtificialThreadPrivate(
6274 CGF, CGM.getContext().getSizeType(),
Alexey Bataev1c44e152018-03-06 18:59:43 +00006275 generateUniqueName(CGM, "reduction_size", RCG.getRefExpr(N)));
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006276 CGF.Builder.CreateStore(SizeVal, SizeAddr, /*IsVolatile=*/false);
6277 }
6278 // Store address of the original reduction item if custom initializer is used.
6279 if (RCG.usesReductionInitializer(N)) {
6280 Address SharedAddr = getAddrOfArtificialThreadPrivate(
6281 CGF, CGM.getContext().VoidPtrTy,
Alexey Bataev1c44e152018-03-06 18:59:43 +00006282 generateUniqueName(CGM, "reduction", RCG.getRefExpr(N)));
Alexey Bataevbe5a8b42017-07-17 13:30:36 +00006283 CGF.Builder.CreateStore(
6284 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
6285 RCG.getSharedLValue(N).getPointer(), CGM.VoidPtrTy),
6286 SharedAddr, /*IsVolatile=*/false);
6287 }
6288}
6289
6290Address CGOpenMPRuntime::getTaskReductionItem(CodeGenFunction &CGF,
6291 SourceLocation Loc,
6292 llvm::Value *ReductionsPtr,
6293 LValue SharedLVal) {
6294 // Build call void *__kmpc_task_reduction_get_th_data(int gtid, void *tg, void
6295 // *d);
6296 llvm::Value *Args[] = {
6297 CGF.Builder.CreateIntCast(getThreadID(CGF, Loc), CGM.IntTy,
6298 /*isSigned=*/true),
6299 ReductionsPtr,
6300 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(SharedLVal.getPointer(),
6301 CGM.VoidPtrTy)};
6302 return Address(
6303 CGF.EmitRuntimeCall(
6304 createRuntimeFunction(OMPRTL__kmpc_task_reduction_get_th_data), Args),
6305 SharedLVal.getAlignment());
6306}
6307
Alexey Bataev8b8e2022015-04-27 05:22:09 +00006308void CGOpenMPRuntime::emitTaskwaitCall(CodeGenFunction &CGF,
6309 SourceLocation Loc) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00006310 if (!CGF.HaveInsertPoint())
6311 return;
Alexey Bataev8b8e2022015-04-27 05:22:09 +00006312 // Build call kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32
6313 // global_tid);
6314 llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
6315 // Ignore return result until untied tasks are supported.
6316 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_taskwait), Args);
Alexey Bataev48591dd2016-04-20 04:01:36 +00006317 if (auto *Region = dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo))
6318 Region->emitUntiedSwitch(CGF);
Alexey Bataev8b8e2022015-04-27 05:22:09 +00006319}
6320
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00006321void CGOpenMPRuntime::emitInlinedDirective(CodeGenFunction &CGF,
Alexey Bataev81c7ea02015-07-03 09:56:58 +00006322 OpenMPDirectiveKind InnerKind,
Alexey Bataev25e5b442015-09-15 12:52:43 +00006323 const RegionCodeGenTy &CodeGen,
6324 bool HasCancel) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00006325 if (!CGF.HaveInsertPoint())
6326 return;
Alexey Bataev25e5b442015-09-15 12:52:43 +00006327 InlinedOpenMPRegionRAII Region(CGF, CodeGen, InnerKind, HasCancel);
Alexey Bataev6f1ffc02015-04-10 04:50:10 +00006328 CGF.CapturedStmtInfo->EmitBody(CGF, /*S=*/nullptr);
Alexey Bataev8cbe0a62015-02-26 10:27:34 +00006329}
6330
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00006331namespace {
6332enum RTCancelKind {
6333 CancelNoreq = 0,
6334 CancelParallel = 1,
6335 CancelLoop = 2,
6336 CancelSections = 3,
6337 CancelTaskgroup = 4
6338};
Eugene Zelenko0a4f3f42016-02-10 19:11:58 +00006339} // anonymous namespace
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00006340
6341static RTCancelKind getCancellationKind(OpenMPDirectiveKind CancelRegion) {
6342 RTCancelKind CancelKind = CancelNoreq;
Alexey Bataev0f34da12015-07-02 04:17:07 +00006343 if (CancelRegion == OMPD_parallel)
6344 CancelKind = CancelParallel;
6345 else if (CancelRegion == OMPD_for)
6346 CancelKind = CancelLoop;
6347 else if (CancelRegion == OMPD_sections)
6348 CancelKind = CancelSections;
6349 else {
6350 assert(CancelRegion == OMPD_taskgroup);
6351 CancelKind = CancelTaskgroup;
6352 }
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00006353 return CancelKind;
6354}
6355
6356void CGOpenMPRuntime::emitCancellationPointCall(
6357 CodeGenFunction &CGF, SourceLocation Loc,
6358 OpenMPDirectiveKind CancelRegion) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00006359 if (!CGF.HaveInsertPoint())
6360 return;
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00006361 // Build call kmp_int32 __kmpc_cancellationpoint(ident_t *loc, kmp_int32
6362 // global_tid, kmp_int32 cncl_kind);
Alexey Bataev81c7ea02015-07-03 09:56:58 +00006363 if (auto *OMPRegionInfo =
6364 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
Jonas Hahnfeldb07931f2017-02-17 18:32:58 +00006365 // For 'cancellation point taskgroup', the task region info may not have a
6366 // cancel. This may instead happen in another adjacent task.
6367 if (CancelRegion == OMPD_taskgroup || OMPRegionInfo->hasCancel()) {
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00006368 llvm::Value *Args[] = {
6369 emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
6370 CGF.Builder.getInt32(getCancellationKind(CancelRegion))};
Alexey Bataev81c7ea02015-07-03 09:56:58 +00006371 // Ignore return result until untied tasks are supported.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006372 llvm::Value *Result = CGF.EmitRuntimeCall(
Alexey Bataev81c7ea02015-07-03 09:56:58 +00006373 createRuntimeFunction(OMPRTL__kmpc_cancellationpoint), Args);
6374 // if (__kmpc_cancellationpoint()) {
Alexey Bataev81c7ea02015-07-03 09:56:58 +00006375 // exit from construct;
6376 // }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006377 llvm::BasicBlock *ExitBB = CGF.createBasicBlock(".cancel.exit");
6378 llvm::BasicBlock *ContBB = CGF.createBasicBlock(".cancel.continue");
6379 llvm::Value *Cmp = CGF.Builder.CreateIsNotNull(Result);
Alexey Bataev81c7ea02015-07-03 09:56:58 +00006380 CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
6381 CGF.EmitBlock(ExitBB);
Alexey Bataev81c7ea02015-07-03 09:56:58 +00006382 // exit from construct;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006383 CodeGenFunction::JumpDest CancelDest =
Alexey Bataev25e5b442015-09-15 12:52:43 +00006384 CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
Alexey Bataev81c7ea02015-07-03 09:56:58 +00006385 CGF.EmitBranchThroughCleanup(CancelDest);
6386 CGF.EmitBlock(ContBB, /*IsFinished=*/true);
6387 }
Alexey Bataev0f34da12015-07-02 04:17:07 +00006388 }
Alexey Bataev0f34da12015-07-02 04:17:07 +00006389}
6390
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00006391void CGOpenMPRuntime::emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
Alexey Bataev87933c72015-09-18 08:07:34 +00006392 const Expr *IfCond,
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00006393 OpenMPDirectiveKind CancelRegion) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00006394 if (!CGF.HaveInsertPoint())
6395 return;
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00006396 // Build call kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid,
6397 // kmp_int32 cncl_kind);
6398 if (auto *OMPRegionInfo =
6399 dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00006400 auto &&ThenGen = [Loc, CancelRegion, OMPRegionInfo](CodeGenFunction &CGF,
6401 PrePostActionTy &) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006402 CGOpenMPRuntime &RT = CGF.CGM.getOpenMPRuntime();
Alexey Bataev87933c72015-09-18 08:07:34 +00006403 llvm::Value *Args[] = {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00006404 RT.emitUpdateLocation(CGF, Loc), RT.getThreadID(CGF, Loc),
Alexey Bataev87933c72015-09-18 08:07:34 +00006405 CGF.Builder.getInt32(getCancellationKind(CancelRegion))};
6406 // Ignore return result until untied tasks are supported.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006407 llvm::Value *Result = CGF.EmitRuntimeCall(
Alexey Bataev14fa1c62016-03-29 05:34:15 +00006408 RT.createRuntimeFunction(OMPRTL__kmpc_cancel), Args);
Alexey Bataev87933c72015-09-18 08:07:34 +00006409 // if (__kmpc_cancel()) {
Alexey Bataev87933c72015-09-18 08:07:34 +00006410 // exit from construct;
6411 // }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006412 llvm::BasicBlock *ExitBB = CGF.createBasicBlock(".cancel.exit");
6413 llvm::BasicBlock *ContBB = CGF.createBasicBlock(".cancel.continue");
6414 llvm::Value *Cmp = CGF.Builder.CreateIsNotNull(Result);
Alexey Bataev87933c72015-09-18 08:07:34 +00006415 CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
6416 CGF.EmitBlock(ExitBB);
Alexey Bataev87933c72015-09-18 08:07:34 +00006417 // exit from construct;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006418 CodeGenFunction::JumpDest CancelDest =
Alexey Bataev87933c72015-09-18 08:07:34 +00006419 CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
6420 CGF.EmitBranchThroughCleanup(CancelDest);
6421 CGF.EmitBlock(ContBB, /*IsFinished=*/true);
6422 };
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006423 if (IfCond) {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00006424 emitOMPIfClause(CGF, IfCond, ThenGen,
6425 [](CodeGenFunction &, PrePostActionTy &) {});
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006426 } else {
Alexey Bataev14fa1c62016-03-29 05:34:15 +00006427 RegionCodeGenTy ThenRCG(ThenGen);
6428 ThenRCG(CGF);
6429 }
Alexey Bataev7d5d33e2015-07-06 05:50:32 +00006430 }
6431}
Samuel Antaobed3c462015-10-02 16:14:20 +00006432
Samuel Antaoee8fb302016-01-06 13:42:12 +00006433void CGOpenMPRuntime::emitTargetOutlinedFunction(
6434 const OMPExecutableDirective &D, StringRef ParentName,
6435 llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
Alexey Bataev14fa1c62016-03-29 05:34:15 +00006436 bool IsOffloadEntry, const RegionCodeGenTy &CodeGen) {
Samuel Antaoee8fb302016-01-06 13:42:12 +00006437 assert(!ParentName.empty() && "Invalid target region parent name!");
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +00006438 HasEmittedTargetRegion = true;
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +00006439 emitTargetOutlinedFunctionHelper(D, ParentName, OutlinedFn, OutlinedFnID,
6440 IsOffloadEntry, CodeGen);
6441}
6442
6443void CGOpenMPRuntime::emitTargetOutlinedFunctionHelper(
6444 const OMPExecutableDirective &D, StringRef ParentName,
6445 llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
6446 bool IsOffloadEntry, const RegionCodeGenTy &CodeGen) {
Samuel Antao2de62b02016-02-13 23:35:10 +00006447 // Create a unique name for the entry function using the source location
6448 // information of the current target region. The name will be something like:
Samuel Antaoee8fb302016-01-06 13:42:12 +00006449 //
Samuel Antao2de62b02016-02-13 23:35:10 +00006450 // __omp_offloading_DD_FFFF_PP_lBB
Samuel Antaoee8fb302016-01-06 13:42:12 +00006451 //
6452 // where DD_FFFF is an ID unique to the file (device and file IDs), PP is the
Samuel Antao2de62b02016-02-13 23:35:10 +00006453 // mangled name of the function that encloses the target region and BB is the
6454 // line number of the target region.
Samuel Antaoee8fb302016-01-06 13:42:12 +00006455
6456 unsigned DeviceID;
6457 unsigned FileID;
6458 unsigned Line;
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006459 getTargetEntryUniqueInfo(CGM.getContext(), D.getBeginLoc(), DeviceID, FileID,
Samuel Antao2de62b02016-02-13 23:35:10 +00006460 Line);
Samuel Antaoee8fb302016-01-06 13:42:12 +00006461 SmallString<64> EntryFnName;
6462 {
6463 llvm::raw_svector_ostream OS(EntryFnName);
Samuel Antao2de62b02016-02-13 23:35:10 +00006464 OS << "__omp_offloading" << llvm::format("_%x", DeviceID)
6465 << llvm::format("_%x_", FileID) << ParentName << "_l" << Line;
Samuel Antaoee8fb302016-01-06 13:42:12 +00006466 }
6467
Alexey Bataev475a7442018-01-12 19:39:11 +00006468 const CapturedStmt &CS = *D.getCapturedStmt(OMPD_target);
Arpith Chacko Jacob5c309e42016-03-22 01:48:56 +00006469
Samuel Antaobed3c462015-10-02 16:14:20 +00006470 CodeGenFunction CGF(CGM, true);
Samuel Antaoee8fb302016-01-06 13:42:12 +00006471 CGOpenMPTargetRegionInfo CGInfo(CS, CodeGen, EntryFnName);
Samuel Antaobed3c462015-10-02 16:14:20 +00006472 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
Samuel Antaoee8fb302016-01-06 13:42:12 +00006473
Samuel Antao6d004262016-06-16 18:39:34 +00006474 OutlinedFn = CGF.GenerateOpenMPCapturedStmtFunction(CS);
Samuel Antaoee8fb302016-01-06 13:42:12 +00006475
6476 // If this target outline function is not an offload entry, we don't need to
6477 // register it.
6478 if (!IsOffloadEntry)
6479 return;
6480
6481 // The target region ID is used by the runtime library to identify the current
6482 // target region, so it only has to be unique and not necessarily point to
6483 // anything. It could be the pointer to the outlined function that implements
6484 // the target region, but we aren't using that so that the compiler doesn't
6485 // need to keep that, and could therefore inline the host function if proven
6486 // worthwhile during optimization. In the other hand, if emitting code for the
6487 // device, the ID has to be the function address so that it can retrieved from
6488 // the offloading entry and launched by the runtime library. We also mark the
6489 // outlined function to have external linkage in case we are emitting code for
6490 // the device, because these functions will be entry points to the device.
6491
6492 if (CGM.getLangOpts().OpenMPIsDevice) {
6493 OutlinedFnID = llvm::ConstantExpr::getBitCast(OutlinedFn, CGM.Int8PtrTy);
Alexey Bataev9a700172018-05-08 14:16:57 +00006494 OutlinedFn->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
Rafael Espindolacbca4872018-01-11 22:15:12 +00006495 OutlinedFn->setDSOLocal(false);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006496 } else {
Alexey Bataevc15ea702018-05-09 18:02:37 +00006497 std::string Name = getName({EntryFnName, "region_id"});
Samuel Antaoee8fb302016-01-06 13:42:12 +00006498 OutlinedFnID = new llvm::GlobalVariable(
6499 CGM.getModule(), CGM.Int8Ty, /*isConstant=*/true,
Alexey Bataev9a700172018-05-08 14:16:57 +00006500 llvm::GlobalValue::WeakAnyLinkage,
Alexey Bataev18fa2322018-05-02 14:20:50 +00006501 llvm::Constant::getNullValue(CGM.Int8Ty), Name);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006502 }
Samuel Antaoee8fb302016-01-06 13:42:12 +00006503
6504 // Register the information for the entry associated with this target region.
6505 OffloadEntriesInfoManager.registerTargetRegionEntryInfo(
Samuel Antaof83efdb2017-01-05 16:02:49 +00006506 DeviceID, FileID, ParentName, Line, OutlinedFn, OutlinedFnID,
Alexey Bataev03f270c2018-03-30 18:31:07 +00006507 OffloadEntriesInfoManagerTy::OMPTargetRegionEntryTargetRegion);
Samuel Antaobed3c462015-10-02 16:14:20 +00006508}
6509
Alexey Bataev5c427362019-04-10 19:11:33 +00006510/// Checks if the expression is constant or does not have non-trivial function
6511/// calls.
6512static bool isTrivial(ASTContext &Ctx, const Expr * E) {
6513 // We can skip constant expressions.
6514 // We can skip expressions with trivial calls or simple expressions.
6515 return (E->isEvaluatable(Ctx, Expr::SE_AllowUndefinedBehavior) ||
6516 !E->hasNonTrivialCall(Ctx)) &&
6517 !E->HasSideEffects(Ctx, /*IncludePossibleEffects=*/true);
6518}
Carlo Bertolli6eee9062016-04-29 01:37:30 +00006519
Alexey Bataev5c427362019-04-10 19:11:33 +00006520const Stmt *CGOpenMPRuntime::getSingleCompoundChild(ASTContext &Ctx,
6521 const Stmt *Body) {
6522 const Stmt *Child = Body->IgnoreContainers();
6523 while (const auto *C = dyn_cast_or_null<CompoundStmt>(Child)) {
6524 Child = nullptr;
6525 for (const Stmt *S : C->body()) {
6526 if (const auto *E = dyn_cast<Expr>(S)) {
6527 if (isTrivial(Ctx, E))
6528 continue;
6529 }
6530 // Some of the statements can be ignored.
6531 if (isa<AsmStmt>(S) || isa<NullStmt>(S) || isa<OMPFlushDirective>(S) ||
6532 isa<OMPBarrierDirective>(S) || isa<OMPTaskyieldDirective>(S))
6533 continue;
6534 // Analyze declarations.
6535 if (const auto *DS = dyn_cast<DeclStmt>(S)) {
6536 if (llvm::all_of(DS->decls(), [&Ctx](const Decl *D) {
6537 if (isa<EmptyDecl>(D) || isa<DeclContext>(D) ||
6538 isa<TypeDecl>(D) || isa<PragmaCommentDecl>(D) ||
6539 isa<PragmaDetectMismatchDecl>(D) || isa<UsingDecl>(D) ||
6540 isa<UsingDirectiveDecl>(D) ||
6541 isa<OMPDeclareReductionDecl>(D) ||
6542 isa<OMPThreadPrivateDecl>(D) || isa<OMPAllocateDecl>(D))
6543 return true;
6544 const auto *VD = dyn_cast<VarDecl>(D);
6545 if (!VD)
6546 return false;
6547 return VD->isConstexpr() ||
6548 ((VD->getType().isTrivialType(Ctx) ||
6549 VD->getType()->isReferenceType()) &&
6550 (!VD->hasInit() || isTrivial(Ctx, VD->getInit())));
6551 }))
6552 continue;
6553 }
6554 // Found multiple children - cannot get the one child only.
6555 if (Child)
6556 return nullptr;
6557 Child = S;
6558 }
6559 if (Child)
6560 Child = Child->IgnoreContainers();
6561 }
6562 return Child;
Carlo Bertolli6eee9062016-04-29 01:37:30 +00006563}
6564
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00006565/// Emit the number of teams for a target directive. Inspect the num_teams
6566/// clause associated with a teams construct combined or closely nested
6567/// with the target directive.
6568///
6569/// Emit a team of size one for directives such as 'target parallel' that
6570/// have no associated teams construct.
6571///
6572/// Otherwise, return nullptr.
Samuel Antaob68e2db2016-03-03 16:20:23 +00006573static llvm::Value *
Alexey Bataev5c427362019-04-10 19:11:33 +00006574emitNumTeamsForTargetDirective(CodeGenFunction &CGF,
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00006575 const OMPExecutableDirective &D) {
Alexey Bataev5c427362019-04-10 19:11:33 +00006576 assert(!CGF.getLangOpts().OpenMPIsDevice &&
6577 "Clauses associated with the teams directive expected to be emitted "
6578 "only for the host!");
6579 OpenMPDirectiveKind DirectiveKind = D.getDirectiveKind();
6580 assert(isOpenMPTargetExecutionDirective(DirectiveKind) &&
6581 "Expected target-based executable directive.");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006582 CGBuilderTy &Bld = CGF.Builder;
Alexey Bataev5c427362019-04-10 19:11:33 +00006583 switch (DirectiveKind) {
6584 case OMPD_target: {
6585 const auto *CS = D.getInnermostCapturedStmt();
6586 const auto *Body =
6587 CS->getCapturedStmt()->IgnoreContainers(/*IgnoreCaptured=*/true);
6588 const Stmt *ChildStmt =
6589 CGOpenMPRuntime::getSingleCompoundChild(CGF.getContext(), Body);
6590 if (const auto *NestedDir =
6591 dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
6592 if (isOpenMPTeamsDirective(NestedDir->getDirectiveKind())) {
6593 if (NestedDir->hasClausesOfKind<OMPNumTeamsClause>()) {
6594 CGOpenMPInnerExprInfo CGInfo(CGF, *CS);
6595 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
6596 const Expr *NumTeams =
6597 NestedDir->getSingleClause<OMPNumTeamsClause>()->getNumTeams();
6598 llvm::Value *NumTeamsVal =
6599 CGF.EmitScalarExpr(NumTeams,
6600 /*IgnoreResultAssign*/ true);
6601 return Bld.CreateIntCast(NumTeamsVal, CGF.Int32Ty,
6602 /*IsSigned=*/true);
6603 }
6604 return Bld.getInt32(0);
Alexey Bataev50a1c782017-12-01 21:31:08 +00006605 }
Alexey Bataev5c427362019-04-10 19:11:33 +00006606 if (isOpenMPParallelDirective(NestedDir->getDirectiveKind()) ||
6607 isOpenMPSimdDirective(NestedDir->getDirectiveKind()))
6608 return Bld.getInt32(1);
Alexey Bataev50a1c782017-12-01 21:31:08 +00006609 return Bld.getInt32(0);
6610 }
Alexey Bataev5c427362019-04-10 19:11:33 +00006611 return nullptr;
Samuel Antaob68e2db2016-03-03 16:20:23 +00006612 }
Alexey Bataev5c427362019-04-10 19:11:33 +00006613 case OMPD_target_teams:
6614 case OMPD_target_teams_distribute:
6615 case OMPD_target_teams_distribute_simd:
6616 case OMPD_target_teams_distribute_parallel_for:
6617 case OMPD_target_teams_distribute_parallel_for_simd: {
6618 if (D.hasClausesOfKind<OMPNumTeamsClause>()) {
6619 CodeGenFunction::RunCleanupsScope NumTeamsScope(CGF);
6620 const Expr *NumTeams =
6621 D.getSingleClause<OMPNumTeamsClause>()->getNumTeams();
6622 llvm::Value *NumTeamsVal =
6623 CGF.EmitScalarExpr(NumTeams,
6624 /*IgnoreResultAssign*/ true);
6625 return Bld.CreateIntCast(NumTeamsVal, CGF.Int32Ty,
6626 /*IsSigned=*/true);
6627 }
6628 return Bld.getInt32(0);
6629 }
6630 case OMPD_target_parallel:
6631 case OMPD_target_parallel_for:
6632 case OMPD_target_parallel_for_simd:
6633 case OMPD_target_simd:
6634 return Bld.getInt32(1);
6635 case OMPD_parallel:
6636 case OMPD_for:
6637 case OMPD_parallel_for:
6638 case OMPD_parallel_sections:
6639 case OMPD_for_simd:
6640 case OMPD_parallel_for_simd:
6641 case OMPD_cancel:
6642 case OMPD_cancellation_point:
6643 case OMPD_ordered:
6644 case OMPD_threadprivate:
6645 case OMPD_allocate:
6646 case OMPD_task:
6647 case OMPD_simd:
6648 case OMPD_sections:
6649 case OMPD_section:
6650 case OMPD_single:
6651 case OMPD_master:
6652 case OMPD_critical:
6653 case OMPD_taskyield:
6654 case OMPD_barrier:
6655 case OMPD_taskwait:
6656 case OMPD_taskgroup:
6657 case OMPD_atomic:
6658 case OMPD_flush:
6659 case OMPD_teams:
6660 case OMPD_target_data:
6661 case OMPD_target_exit_data:
6662 case OMPD_target_enter_data:
6663 case OMPD_distribute:
6664 case OMPD_distribute_simd:
6665 case OMPD_distribute_parallel_for:
6666 case OMPD_distribute_parallel_for_simd:
6667 case OMPD_teams_distribute:
6668 case OMPD_teams_distribute_simd:
6669 case OMPD_teams_distribute_parallel_for:
6670 case OMPD_teams_distribute_parallel_for_simd:
6671 case OMPD_target_update:
6672 case OMPD_declare_simd:
6673 case OMPD_declare_target:
6674 case OMPD_end_declare_target:
6675 case OMPD_declare_reduction:
6676 case OMPD_declare_mapper:
6677 case OMPD_taskloop:
6678 case OMPD_taskloop_simd:
6679 case OMPD_requires:
6680 case OMPD_unknown:
6681 break;
6682 }
6683 llvm_unreachable("Unexpected directive kind.");
6684}
Samuel Antaob68e2db2016-03-03 16:20:23 +00006685
Alexey Bataev5c427362019-04-10 19:11:33 +00006686static llvm::Value *getNumThreads(CodeGenFunction &CGF, const CapturedStmt *CS,
6687 llvm::Value *DefaultThreadLimitVal) {
6688 const Stmt *Child = CGOpenMPRuntime::getSingleCompoundChild(
6689 CGF.getContext(), CS->getCapturedStmt());
6690 if (const auto *Dir = dyn_cast_or_null<OMPExecutableDirective>(Child)) {
6691 if (isOpenMPParallelDirective(Dir->getDirectiveKind())) {
Alexey Bataevdc9e7dc2019-04-17 16:53:08 +00006692 llvm::Value *NumThreads = nullptr;
6693 llvm::Value *CondVal = nullptr;
6694 // Handle if clause. If if clause present, the number of threads is
6695 // calculated as <cond> ? (<numthreads> ? <numthreads> : 0 ) : 1.
6696 if (Dir->hasClausesOfKind<OMPIfClause>()) {
6697 CGOpenMPInnerExprInfo CGInfo(CGF, *CS);
6698 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
6699 const OMPIfClause *IfClause = nullptr;
6700 for (const auto *C : Dir->getClausesOfKind<OMPIfClause>()) {
6701 if (C->getNameModifier() == OMPD_unknown ||
6702 C->getNameModifier() == OMPD_parallel) {
6703 IfClause = C;
6704 break;
6705 }
6706 }
6707 if (IfClause) {
6708 const Expr *Cond = IfClause->getCondition();
6709 bool Result;
6710 if (Cond->EvaluateAsBooleanCondition(Result, CGF.getContext())) {
6711 if (!Result)
6712 return CGF.Builder.getInt32(1);
6713 } else {
6714 CodeGenFunction::LexicalScope Scope(CGF, Cond->getSourceRange());
6715 if (const auto *PreInit =
6716 cast_or_null<DeclStmt>(IfClause->getPreInitStmt())) {
6717 for (const auto *I : PreInit->decls()) {
6718 if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
6719 CGF.EmitVarDecl(cast<VarDecl>(*I));
6720 } else {
6721 CodeGenFunction::AutoVarEmission Emission =
6722 CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
6723 CGF.EmitAutoVarCleanups(Emission);
6724 }
6725 }
6726 }
6727 CondVal = CGF.EvaluateExprAsBool(Cond);
6728 }
6729 }
6730 }
6731 // Check the value of num_threads clause iff if clause was not specified
6732 // or is not evaluated to false.
Alexey Bataev5c427362019-04-10 19:11:33 +00006733 if (Dir->hasClausesOfKind<OMPNumThreadsClause>()) {
6734 CGOpenMPInnerExprInfo CGInfo(CGF, *CS);
6735 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
6736 const auto *NumThreadsClause =
6737 Dir->getSingleClause<OMPNumThreadsClause>();
6738 CodeGenFunction::LexicalScope Scope(
6739 CGF, NumThreadsClause->getNumThreads()->getSourceRange());
6740 if (const auto *PreInit =
6741 cast_or_null<DeclStmt>(NumThreadsClause->getPreInitStmt())) {
6742 for (const auto *I : PreInit->decls()) {
6743 if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
6744 CGF.EmitVarDecl(cast<VarDecl>(*I));
6745 } else {
6746 CodeGenFunction::AutoVarEmission Emission =
6747 CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
6748 CGF.EmitAutoVarCleanups(Emission);
6749 }
6750 }
6751 }
Alexey Bataevdc9e7dc2019-04-17 16:53:08 +00006752 NumThreads = CGF.EmitScalarExpr(NumThreadsClause->getNumThreads());
Alexey Bataev5c427362019-04-10 19:11:33 +00006753 NumThreads = CGF.Builder.CreateIntCast(NumThreads, CGF.Int32Ty,
Alexey Bataevdc9e7dc2019-04-17 16:53:08 +00006754 /*IsSigned=*/false);
6755 if (DefaultThreadLimitVal)
6756 NumThreads = CGF.Builder.CreateSelect(
6757 CGF.Builder.CreateICmpULT(DefaultThreadLimitVal, NumThreads),
6758 DefaultThreadLimitVal, NumThreads);
6759 } else {
6760 NumThreads = DefaultThreadLimitVal ? DefaultThreadLimitVal
6761 : CGF.Builder.getInt32(0);
Alexey Bataev5c427362019-04-10 19:11:33 +00006762 }
Alexey Bataevdc9e7dc2019-04-17 16:53:08 +00006763 // Process condition of the if clause.
6764 if (CondVal) {
6765 NumThreads = CGF.Builder.CreateSelect(CondVal, NumThreads,
6766 CGF.Builder.getInt32(1));
6767 }
6768 return NumThreads;
Alexey Bataev5c427362019-04-10 19:11:33 +00006769 }
6770 if (isOpenMPSimdDirective(Dir->getDirectiveKind()))
6771 return CGF.Builder.getInt32(1);
6772 return DefaultThreadLimitVal;
6773 }
6774 return DefaultThreadLimitVal ? DefaultThreadLimitVal
6775 : CGF.Builder.getInt32(0);
Samuel Antaob68e2db2016-03-03 16:20:23 +00006776}
6777
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00006778/// Emit the number of threads for a target directive. Inspect the
6779/// thread_limit clause associated with a teams construct combined or closely
6780/// nested with the target directive.
6781///
6782/// Emit the num_threads clause for directives such as 'target parallel' that
6783/// have no associated teams construct.
6784///
6785/// Otherwise, return nullptr.
Samuel Antaob68e2db2016-03-03 16:20:23 +00006786static llvm::Value *
Alexey Bataev5c427362019-04-10 19:11:33 +00006787emitNumThreadsForTargetDirective(CodeGenFunction &CGF,
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00006788 const OMPExecutableDirective &D) {
Alexey Bataev5c427362019-04-10 19:11:33 +00006789 assert(!CGF.getLangOpts().OpenMPIsDevice &&
6790 "Clauses associated with the teams directive expected to be emitted "
6791 "only for the host!");
6792 OpenMPDirectiveKind DirectiveKind = D.getDirectiveKind();
6793 assert(isOpenMPTargetExecutionDirective(DirectiveKind) &&
6794 "Expected target-based executable directive.");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00006795 CGBuilderTy &Bld = CGF.Builder;
Alexey Bataev5c427362019-04-10 19:11:33 +00006796 llvm::Value *ThreadLimitVal = nullptr;
6797 llvm::Value *NumThreadsVal = nullptr;
6798 switch (DirectiveKind) {
6799 case OMPD_target: {
6800 const CapturedStmt *CS = D.getInnermostCapturedStmt();
6801 if (llvm::Value *NumThreads = getNumThreads(CGF, CS, ThreadLimitVal))
6802 return NumThreads;
6803 const Stmt *Child = CGOpenMPRuntime::getSingleCompoundChild(
6804 CGF.getContext(), CS->getCapturedStmt());
6805 if (const auto *Dir = dyn_cast_or_null<OMPExecutableDirective>(Child)) {
6806 if (Dir->hasClausesOfKind<OMPThreadLimitClause>()) {
6807 CGOpenMPInnerExprInfo CGInfo(CGF, *CS);
6808 CodeGenFunction::CGCapturedStmtRAII CapInfoRAII(CGF, &CGInfo);
6809 const auto *ThreadLimitClause =
6810 Dir->getSingleClause<OMPThreadLimitClause>();
6811 CodeGenFunction::LexicalScope Scope(
6812 CGF, ThreadLimitClause->getThreadLimit()->getSourceRange());
6813 if (const auto *PreInit =
6814 cast_or_null<DeclStmt>(ThreadLimitClause->getPreInitStmt())) {
6815 for (const auto *I : PreInit->decls()) {
6816 if (!I->hasAttr<OMPCaptureNoInitAttr>()) {
6817 CGF.EmitVarDecl(cast<VarDecl>(*I));
6818 } else {
6819 CodeGenFunction::AutoVarEmission Emission =
6820 CGF.EmitAutoVarAlloca(cast<VarDecl>(*I));
6821 CGF.EmitAutoVarCleanups(Emission);
6822 }
6823 }
6824 }
6825 llvm::Value *ThreadLimit = CGF.EmitScalarExpr(
6826 ThreadLimitClause->getThreadLimit(), /*IgnoreResultAssign=*/true);
6827 ThreadLimitVal =
Alexey Bataevdc9e7dc2019-04-17 16:53:08 +00006828 Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty, /*IsSigned=*/false);
Alexey Bataev5c427362019-04-10 19:11:33 +00006829 }
6830 if (isOpenMPTeamsDirective(Dir->getDirectiveKind()) &&
6831 !isOpenMPDistributeDirective(Dir->getDirectiveKind())) {
6832 CS = Dir->getInnermostCapturedStmt();
6833 const Stmt *Child = CGOpenMPRuntime::getSingleCompoundChild(
6834 CGF.getContext(), CS->getCapturedStmt());
6835 Dir = dyn_cast_or_null<OMPExecutableDirective>(Child);
6836 }
6837 if (Dir && isOpenMPDistributeDirective(Dir->getDirectiveKind()) &&
6838 !isOpenMPSimdDirective(Dir->getDirectiveKind())) {
6839 CS = Dir->getInnermostCapturedStmt();
6840 if (llvm::Value *NumThreads = getNumThreads(CGF, CS, ThreadLimitVal))
6841 return NumThreads;
6842 }
6843 if (Dir && isOpenMPSimdDirective(Dir->getDirectiveKind()))
6844 return Bld.getInt32(1);
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00006845 }
Alexey Bataev5c427362019-04-10 19:11:33 +00006846 return ThreadLimitVal ? ThreadLimitVal : Bld.getInt32(0);
6847 }
6848 case OMPD_target_teams: {
6849 if (D.hasClausesOfKind<OMPThreadLimitClause>()) {
6850 CodeGenFunction::RunCleanupsScope ThreadLimitScope(CGF);
6851 const auto *ThreadLimitClause = D.getSingleClause<OMPThreadLimitClause>();
6852 llvm::Value *ThreadLimit = CGF.EmitScalarExpr(
6853 ThreadLimitClause->getThreadLimit(), /*IgnoreResultAssign=*/true);
6854 ThreadLimitVal =
Alexey Bataevdc9e7dc2019-04-17 16:53:08 +00006855 Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty, /*IsSigned=*/false);
Alexey Bataev5c427362019-04-10 19:11:33 +00006856 }
6857 const CapturedStmt *CS = D.getInnermostCapturedStmt();
6858 if (llvm::Value *NumThreads = getNumThreads(CGF, CS, ThreadLimitVal))
6859 return NumThreads;
6860 const Stmt *Child = CGOpenMPRuntime::getSingleCompoundChild(
6861 CGF.getContext(), CS->getCapturedStmt());
6862 if (const auto *Dir = dyn_cast_or_null<OMPExecutableDirective>(Child)) {
6863 if (Dir->getDirectiveKind() == OMPD_distribute) {
6864 CS = Dir->getInnermostCapturedStmt();
6865 if (llvm::Value *NumThreads = getNumThreads(CGF, CS, ThreadLimitVal))
6866 return NumThreads;
6867 }
6868 }
6869 return ThreadLimitVal ? ThreadLimitVal : Bld.getInt32(0);
6870 }
6871 case OMPD_target_teams_distribute:
6872 if (D.hasClausesOfKind<OMPThreadLimitClause>()) {
6873 CodeGenFunction::RunCleanupsScope ThreadLimitScope(CGF);
6874 const auto *ThreadLimitClause = D.getSingleClause<OMPThreadLimitClause>();
6875 llvm::Value *ThreadLimit = CGF.EmitScalarExpr(
6876 ThreadLimitClause->getThreadLimit(), /*IgnoreResultAssign=*/true);
6877 ThreadLimitVal =
Alexey Bataevdc9e7dc2019-04-17 16:53:08 +00006878 Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty, /*IsSigned=*/false);
Alexey Bataev5c427362019-04-10 19:11:33 +00006879 }
6880 return getNumThreads(CGF, D.getInnermostCapturedStmt(), ThreadLimitVal);
6881 case OMPD_target_parallel:
6882 case OMPD_target_parallel_for:
6883 case OMPD_target_parallel_for_simd:
6884 case OMPD_target_teams_distribute_parallel_for:
Alexey Bataevdc9e7dc2019-04-17 16:53:08 +00006885 case OMPD_target_teams_distribute_parallel_for_simd: {
6886 llvm::Value *CondVal = nullptr;
6887 // Handle if clause. If if clause present, the number of threads is
6888 // calculated as <cond> ? (<numthreads> ? <numthreads> : 0 ) : 1.
6889 if (D.hasClausesOfKind<OMPIfClause>()) {
6890 const OMPIfClause *IfClause = nullptr;
6891 for (const auto *C : D.getClausesOfKind<OMPIfClause>()) {
6892 if (C->getNameModifier() == OMPD_unknown ||
6893 C->getNameModifier() == OMPD_parallel) {
6894 IfClause = C;
6895 break;
6896 }
6897 }
6898 if (IfClause) {
6899 const Expr *Cond = IfClause->getCondition();
6900 bool Result;
6901 if (Cond->EvaluateAsBooleanCondition(Result, CGF.getContext())) {
6902 if (!Result)
6903 return Bld.getInt32(1);
6904 } else {
6905 CodeGenFunction::RunCleanupsScope Scope(CGF);
6906 CondVal = CGF.EvaluateExprAsBool(Cond);
6907 }
6908 }
6909 }
Alexey Bataev5c427362019-04-10 19:11:33 +00006910 if (D.hasClausesOfKind<OMPThreadLimitClause>()) {
6911 CodeGenFunction::RunCleanupsScope ThreadLimitScope(CGF);
6912 const auto *ThreadLimitClause = D.getSingleClause<OMPThreadLimitClause>();
6913 llvm::Value *ThreadLimit = CGF.EmitScalarExpr(
6914 ThreadLimitClause->getThreadLimit(), /*IgnoreResultAssign=*/true);
6915 ThreadLimitVal =
Alexey Bataevdc9e7dc2019-04-17 16:53:08 +00006916 Bld.CreateIntCast(ThreadLimit, CGF.Int32Ty, /*IsSigned=*/false);
Alexey Bataev5c427362019-04-10 19:11:33 +00006917 }
6918 if (D.hasClausesOfKind<OMPNumThreadsClause>()) {
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00006919 CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF);
Alexey Bataev5c427362019-04-10 19:11:33 +00006920 const auto *NumThreadsClause = D.getSingleClause<OMPNumThreadsClause>();
6921 llvm::Value *NumThreads = CGF.EmitScalarExpr(
6922 NumThreadsClause->getNumThreads(), /*IgnoreResultAssign=*/true);
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00006923 NumThreadsVal =
Alexey Bataevdc9e7dc2019-04-17 16:53:08 +00006924 Bld.CreateIntCast(NumThreads, CGF.Int32Ty, /*IsSigned=*/false);
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00006925 ThreadLimitVal = ThreadLimitVal
Alexey Bataev5c427362019-04-10 19:11:33 +00006926 ? Bld.CreateSelect(Bld.CreateICmpULT(NumThreadsVal,
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00006927 ThreadLimitVal),
6928 NumThreadsVal, ThreadLimitVal)
6929 : NumThreadsVal;
Alexey Bataev50a1c782017-12-01 21:31:08 +00006930 }
Alexey Bataevdc9e7dc2019-04-17 16:53:08 +00006931 if (!ThreadLimitVal)
6932 ThreadLimitVal = Bld.getInt32(0);
6933 if (CondVal)
6934 return Bld.CreateSelect(CondVal, ThreadLimitVal, Bld.getInt32(1));
6935 return ThreadLimitVal;
6936 }
Alexey Bataev5c427362019-04-10 19:11:33 +00006937 case OMPD_target_teams_distribute_simd:
6938 case OMPD_target_simd:
6939 return Bld.getInt32(1);
6940 case OMPD_parallel:
6941 case OMPD_for:
6942 case OMPD_parallel_for:
6943 case OMPD_parallel_sections:
6944 case OMPD_for_simd:
6945 case OMPD_parallel_for_simd:
6946 case OMPD_cancel:
6947 case OMPD_cancellation_point:
6948 case OMPD_ordered:
6949 case OMPD_threadprivate:
6950 case OMPD_allocate:
6951 case OMPD_task:
6952 case OMPD_simd:
6953 case OMPD_sections:
6954 case OMPD_section:
6955 case OMPD_single:
6956 case OMPD_master:
6957 case OMPD_critical:
6958 case OMPD_taskyield:
6959 case OMPD_barrier:
6960 case OMPD_taskwait:
6961 case OMPD_taskgroup:
6962 case OMPD_atomic:
6963 case OMPD_flush:
6964 case OMPD_teams:
6965 case OMPD_target_data:
6966 case OMPD_target_exit_data:
6967 case OMPD_target_enter_data:
6968 case OMPD_distribute:
6969 case OMPD_distribute_simd:
6970 case OMPD_distribute_parallel_for:
6971 case OMPD_distribute_parallel_for_simd:
6972 case OMPD_teams_distribute:
6973 case OMPD_teams_distribute_simd:
6974 case OMPD_teams_distribute_parallel_for:
6975 case OMPD_teams_distribute_parallel_for_simd:
6976 case OMPD_target_update:
6977 case OMPD_declare_simd:
6978 case OMPD_declare_target:
6979 case OMPD_end_declare_target:
6980 case OMPD_declare_reduction:
6981 case OMPD_declare_mapper:
6982 case OMPD_taskloop:
6983 case OMPD_taskloop_simd:
6984 case OMPD_requires:
6985 case OMPD_unknown:
6986 break;
Samuel Antaob68e2db2016-03-03 16:20:23 +00006987 }
Alexey Bataev5c427362019-04-10 19:11:33 +00006988 llvm_unreachable("Unsupported directive kind.");
Samuel Antaob68e2db2016-03-03 16:20:23 +00006989}
6990
Samuel Antao86ace552016-04-27 22:40:57 +00006991namespace {
Alexey Bataevb3638132018-07-19 16:34:13 +00006992LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
6993
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00006994// Utility to handle information from clauses associated with a given
Samuel Antao86ace552016-04-27 22:40:57 +00006995// construct that use mappable expressions (e.g. 'map' clause, 'to' clause).
6996// It provides a convenient interface to obtain the information and generate
6997// code for that information.
6998class MappableExprsHandler {
6999public:
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007000 /// Values for bit flags used to specify the mapping type for
Samuel Antao86ace552016-04-27 22:40:57 +00007001 /// offloading.
Alexey Bataevb3638132018-07-19 16:34:13 +00007002 enum OpenMPOffloadMappingFlags : uint64_t {
7003 /// No flags
7004 OMP_MAP_NONE = 0x0,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007005 /// Allocate memory on the device and move data from host to device.
Samuel Antao86ace552016-04-27 22:40:57 +00007006 OMP_MAP_TO = 0x01,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007007 /// Allocate memory on the device and move data from device to host.
Samuel Antao86ace552016-04-27 22:40:57 +00007008 OMP_MAP_FROM = 0x02,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007009 /// Always perform the requested mapping action on the element, even
Samuel Antao86ace552016-04-27 22:40:57 +00007010 /// if it was already mapped before.
7011 OMP_MAP_ALWAYS = 0x04,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007012 /// Delete the element from the device environment, ignoring the
Samuel Antao86ace552016-04-27 22:40:57 +00007013 /// current reference count associated with the element.
Samuel Antao6782e942016-05-26 16:48:10 +00007014 OMP_MAP_DELETE = 0x08,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007015 /// The element being mapped is a pointer-pointee pair; both the
George Rokos065755d2017-11-07 18:27:04 +00007016 /// pointer and the pointee should be mapped.
7017 OMP_MAP_PTR_AND_OBJ = 0x10,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007018 /// This flags signals that the base address of an entry should be
George Rokos065755d2017-11-07 18:27:04 +00007019 /// passed to the target kernel as an argument.
7020 OMP_MAP_TARGET_PARAM = 0x20,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007021 /// Signal that the runtime library has to return the device pointer
George Rokos065755d2017-11-07 18:27:04 +00007022 /// in the current position for the data being mapped. Used when we have the
7023 /// use_device_ptr clause.
7024 OMP_MAP_RETURN_PARAM = 0x40,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007025 /// This flag signals that the reference being passed is a pointer to
Samuel Antaod486f842016-05-26 16:53:38 +00007026 /// private data.
George Rokos065755d2017-11-07 18:27:04 +00007027 OMP_MAP_PRIVATE = 0x80,
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007028 /// Pass the element to the device by value.
George Rokos065755d2017-11-07 18:27:04 +00007029 OMP_MAP_LITERAL = 0x100,
Alexey Bataevf47c4b42017-09-26 13:47:31 +00007030 /// Implicit map
7031 OMP_MAP_IMPLICIT = 0x200,
Alexey Bataevb3638132018-07-19 16:34:13 +00007032 /// The 16 MSBs of the flags indicate whether the entry is member of some
7033 /// struct/class.
7034 OMP_MAP_MEMBER_OF = 0xffff000000000000,
7035 LLVM_MARK_AS_BITMASK_ENUM(/* LargestFlag = */ OMP_MAP_MEMBER_OF),
Samuel Antao86ace552016-04-27 22:40:57 +00007036 };
7037
Samuel Antaocc10b852016-07-28 14:23:26 +00007038 /// Class that associates information with a base pointer to be passed to the
7039 /// runtime library.
7040 class BasePointerInfo {
7041 /// The base pointer.
7042 llvm::Value *Ptr = nullptr;
7043 /// The base declaration that refers to this device pointer, or null if
7044 /// there is none.
7045 const ValueDecl *DevPtrDecl = nullptr;
7046
7047 public:
7048 BasePointerInfo(llvm::Value *Ptr, const ValueDecl *DevPtrDecl = nullptr)
7049 : Ptr(Ptr), DevPtrDecl(DevPtrDecl) {}
7050 llvm::Value *operator*() const { return Ptr; }
7051 const ValueDecl *getDevicePtrDecl() const { return DevPtrDecl; }
7052 void setDevicePtrDecl(const ValueDecl *D) { DevPtrDecl = D; }
7053 };
7054
Alexey Bataevb3638132018-07-19 16:34:13 +00007055 using MapBaseValuesArrayTy = SmallVector<BasePointerInfo, 4>;
7056 using MapValuesArrayTy = SmallVector<llvm::Value *, 4>;
7057 using MapFlagsArrayTy = SmallVector<OpenMPOffloadMappingFlags, 4>;
7058
7059 /// Map between a struct and the its lowest & highest elements which have been
7060 /// mapped.
7061 /// [ValueDecl *] --> {LE(FieldIndex, Pointer),
7062 /// HE(FieldIndex, Pointer)}
7063 struct StructRangeInfoTy {
7064 std::pair<unsigned /*FieldIndex*/, Address /*Pointer*/> LowestElem = {
7065 0, Address::invalid()};
7066 std::pair<unsigned /*FieldIndex*/, Address /*Pointer*/> HighestElem = {
7067 0, Address::invalid()};
7068 Address Base = Address::invalid();
7069 };
Samuel Antao86ace552016-04-27 22:40:57 +00007070
7071private:
Alexey Bataevb3638132018-07-19 16:34:13 +00007072 /// Kind that defines how a device pointer has to be returned.
7073 struct MapInfo {
7074 OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
7075 OpenMPMapClauseKind MapType = OMPC_MAP_unknown;
Kelvin Lief579432018-12-18 22:18:41 +00007076 ArrayRef<OpenMPMapModifierKind> MapModifiers;
Alexey Bataevb3638132018-07-19 16:34:13 +00007077 bool ReturnDevicePointer = false;
7078 bool IsImplicit = false;
7079
7080 MapInfo() = default;
7081 MapInfo(
7082 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
Kelvin Lief579432018-12-18 22:18:41 +00007083 OpenMPMapClauseKind MapType,
7084 ArrayRef<OpenMPMapModifierKind> MapModifiers,
Alexey Bataevb3638132018-07-19 16:34:13 +00007085 bool ReturnDevicePointer, bool IsImplicit)
Kelvin Lief579432018-12-18 22:18:41 +00007086 : Components(Components), MapType(MapType), MapModifiers(MapModifiers),
Alexey Bataevb3638132018-07-19 16:34:13 +00007087 ReturnDevicePointer(ReturnDevicePointer), IsImplicit(IsImplicit) {}
7088 };
7089
7090 /// If use_device_ptr is used on a pointer which is a struct member and there
7091 /// is no map information about it, then emission of that entry is deferred
7092 /// until the whole struct has been processed.
7093 struct DeferredDevicePtrEntryTy {
7094 const Expr *IE = nullptr;
7095 const ValueDecl *VD = nullptr;
7096
7097 DeferredDevicePtrEntryTy(const Expr *IE, const ValueDecl *VD)
7098 : IE(IE), VD(VD) {}
7099 };
7100
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007101 /// Directive from where the map clauses were extracted.
Samuel Antao44bcdb32016-07-28 15:31:29 +00007102 const OMPExecutableDirective &CurDir;
Samuel Antao86ace552016-04-27 22:40:57 +00007103
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007104 /// Function the directive is being generated for.
Samuel Antao86ace552016-04-27 22:40:57 +00007105 CodeGenFunction &CGF;
7106
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007107 /// Set of all first private variables in the current directive.
Samuel Antaod486f842016-05-26 16:53:38 +00007108 llvm::SmallPtrSet<const VarDecl *, 8> FirstPrivateDecls;
7109
Samuel Antao6890b092016-07-28 14:25:09 +00007110 /// Map between device pointer declarations and their expression components.
7111 /// The key value for declarations in 'this' is null.
7112 llvm::DenseMap<
7113 const ValueDecl *,
7114 SmallVector<OMPClauseMappableExprCommon::MappableExprComponentListRef, 4>>
7115 DevPointersMap;
7116
Samuel Antao86ace552016-04-27 22:40:57 +00007117 llvm::Value *getExprTypeSize(const Expr *E) const {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007118 QualType ExprTy = E->getType().getCanonicalType();
Samuel Antao86ace552016-04-27 22:40:57 +00007119
7120 // Reference types are ignored for mapping purposes.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007121 if (const auto *RefTy = ExprTy->getAs<ReferenceType>())
Samuel Antao86ace552016-04-27 22:40:57 +00007122 ExprTy = RefTy->getPointeeType().getCanonicalType();
7123
7124 // Given that an array section is considered a built-in type, we need to
7125 // do the calculation based on the length of the section instead of relying
7126 // on CGF.getTypeSize(E->getType()).
7127 if (const auto *OAE = dyn_cast<OMPArraySectionExpr>(E)) {
7128 QualType BaseTy = OMPArraySectionExpr::getBaseOriginalType(
7129 OAE->getBase()->IgnoreParenImpCasts())
7130 .getCanonicalType();
7131
7132 // If there is no length associated with the expression, that means we
7133 // are using the whole length of the base.
7134 if (!OAE->getLength() && OAE->getColonLoc().isValid())
7135 return CGF.getTypeSize(BaseTy);
7136
7137 llvm::Value *ElemSize;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007138 if (const auto *PTy = BaseTy->getAs<PointerType>()) {
Samuel Antao86ace552016-04-27 22:40:57 +00007139 ElemSize = CGF.getTypeSize(PTy->getPointeeType().getCanonicalType());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007140 } else {
7141 const auto *ATy = cast<ArrayType>(BaseTy.getTypePtr());
Samuel Antao86ace552016-04-27 22:40:57 +00007142 assert(ATy && "Expecting array type if not a pointer type.");
7143 ElemSize = CGF.getTypeSize(ATy->getElementType().getCanonicalType());
7144 }
7145
7146 // If we don't have a length at this point, that is because we have an
7147 // array section with a single element.
7148 if (!OAE->getLength())
7149 return ElemSize;
7150
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007151 llvm::Value *LengthVal = CGF.EmitScalarExpr(OAE->getLength());
Samuel Antao86ace552016-04-27 22:40:57 +00007152 LengthVal =
7153 CGF.Builder.CreateIntCast(LengthVal, CGF.SizeTy, /*isSigned=*/false);
7154 return CGF.Builder.CreateNUWMul(LengthVal, ElemSize);
7155 }
7156 return CGF.getTypeSize(ExprTy);
7157 }
7158
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007159 /// Return the corresponding bits for a given map clause modifier. Add
Samuel Antao86ace552016-04-27 22:40:57 +00007160 /// a flag marking the map as a pointer if requested. Add a flag marking the
Samuel Antao6782e942016-05-26 16:48:10 +00007161 /// map as the first one of a series of maps that relate to the same map
7162 /// expression.
Kelvin Lief579432018-12-18 22:18:41 +00007163 OpenMPOffloadMappingFlags getMapTypeBits(
7164 OpenMPMapClauseKind MapType, ArrayRef<OpenMPMapModifierKind> MapModifiers,
7165 bool IsImplicit, bool AddPtrFlag, bool AddIsTargetParamFlag) const {
Alexey Bataevb3638132018-07-19 16:34:13 +00007166 OpenMPOffloadMappingFlags Bits =
7167 IsImplicit ? OMP_MAP_IMPLICIT : OMP_MAP_NONE;
Samuel Antao86ace552016-04-27 22:40:57 +00007168 switch (MapType) {
7169 case OMPC_MAP_alloc:
Samuel Antao6782e942016-05-26 16:48:10 +00007170 case OMPC_MAP_release:
7171 // alloc and release is the default behavior in the runtime library, i.e.
7172 // if we don't pass any bits alloc/release that is what the runtime is
7173 // going to do. Therefore, we don't need to signal anything for these two
7174 // type modifiers.
Samuel Antao86ace552016-04-27 22:40:57 +00007175 break;
7176 case OMPC_MAP_to:
Alexey Bataevb3638132018-07-19 16:34:13 +00007177 Bits |= OMP_MAP_TO;
Samuel Antao86ace552016-04-27 22:40:57 +00007178 break;
7179 case OMPC_MAP_from:
Alexey Bataevb3638132018-07-19 16:34:13 +00007180 Bits |= OMP_MAP_FROM;
Samuel Antao86ace552016-04-27 22:40:57 +00007181 break;
7182 case OMPC_MAP_tofrom:
Alexey Bataevb3638132018-07-19 16:34:13 +00007183 Bits |= OMP_MAP_TO | OMP_MAP_FROM;
Samuel Antao86ace552016-04-27 22:40:57 +00007184 break;
7185 case OMPC_MAP_delete:
Alexey Bataevb3638132018-07-19 16:34:13 +00007186 Bits |= OMP_MAP_DELETE;
Samuel Antao86ace552016-04-27 22:40:57 +00007187 break;
Alexey Bataevb3638132018-07-19 16:34:13 +00007188 case OMPC_MAP_unknown:
Samuel Antao86ace552016-04-27 22:40:57 +00007189 llvm_unreachable("Unexpected map type!");
Samuel Antao86ace552016-04-27 22:40:57 +00007190 }
7191 if (AddPtrFlag)
George Rokos065755d2017-11-07 18:27:04 +00007192 Bits |= OMP_MAP_PTR_AND_OBJ;
7193 if (AddIsTargetParamFlag)
7194 Bits |= OMP_MAP_TARGET_PARAM;
Kelvin Lief579432018-12-18 22:18:41 +00007195 if (llvm::find(MapModifiers, OMPC_MAP_MODIFIER_always)
7196 != MapModifiers.end())
Samuel Antao86ace552016-04-27 22:40:57 +00007197 Bits |= OMP_MAP_ALWAYS;
7198 return Bits;
7199 }
7200
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007201 /// Return true if the provided expression is a final array section. A
Samuel Antao86ace552016-04-27 22:40:57 +00007202 /// final array section, is one whose length can't be proved to be one.
7203 bool isFinalArraySectionExpression(const Expr *E) const {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007204 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
Samuel Antao86ace552016-04-27 22:40:57 +00007205
7206 // It is not an array section and therefore not a unity-size one.
7207 if (!OASE)
7208 return false;
7209
7210 // An array section with no colon always refer to a single element.
7211 if (OASE->getColonLoc().isInvalid())
7212 return false;
7213
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007214 const Expr *Length = OASE->getLength();
Samuel Antao86ace552016-04-27 22:40:57 +00007215
7216 // If we don't have a length we have to check if the array has size 1
7217 // for this dimension. Also, we should always expect a length if the
7218 // base type is pointer.
7219 if (!Length) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007220 QualType BaseQTy = OMPArraySectionExpr::getBaseOriginalType(
7221 OASE->getBase()->IgnoreParenImpCasts())
7222 .getCanonicalType();
7223 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
Samuel Antao86ace552016-04-27 22:40:57 +00007224 return ATy->getSize().getSExtValue() != 1;
7225 // If we don't have a constant dimension length, we have to consider
7226 // the current section as having any size, so it is not necessarily
7227 // unitary. If it happen to be unity size, that's user fault.
7228 return true;
7229 }
7230
7231 // Check if the length evaluates to 1.
Fangrui Song407659a2018-11-30 23:41:18 +00007232 Expr::EvalResult Result;
7233 if (!Length->EvaluateAsInt(Result, CGF.getContext()))
Samuel Antao86ace552016-04-27 22:40:57 +00007234 return true; // Can have more that size 1.
7235
Fangrui Song407659a2018-11-30 23:41:18 +00007236 llvm::APSInt ConstLength = Result.Val.getInt();
Samuel Antao86ace552016-04-27 22:40:57 +00007237 return ConstLength.getSExtValue() != 1;
7238 }
7239
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007240 /// Generate the base pointers, section pointers, sizes and map type
Samuel Antao86ace552016-04-27 22:40:57 +00007241 /// bits for the provided map type, map modifier, and expression components.
7242 /// \a IsFirstComponent should be set to true if the provided set of
7243 /// components is the first associated with a capture.
7244 void generateInfoForComponentList(
Kelvin Lief579432018-12-18 22:18:41 +00007245 OpenMPMapClauseKind MapType,
7246 ArrayRef<OpenMPMapModifierKind> MapModifiers,
Samuel Antao86ace552016-04-27 22:40:57 +00007247 OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
Samuel Antaocc10b852016-07-28 14:23:26 +00007248 MapBaseValuesArrayTy &BasePointers, MapValuesArrayTy &Pointers,
Samuel Antao86ace552016-04-27 22:40:57 +00007249 MapValuesArrayTy &Sizes, MapFlagsArrayTy &Types,
Alexey Bataevb3638132018-07-19 16:34:13 +00007250 StructRangeInfoTy &PartialStruct, bool IsFirstComponentList,
Alexey Bataeve82445f2018-09-20 13:54:02 +00007251 bool IsImplicit,
7252 ArrayRef<OMPClauseMappableExprCommon::MappableExprComponentListRef>
7253 OverlappedElements = llvm::None) const {
Samuel Antao86ace552016-04-27 22:40:57 +00007254 // The following summarizes what has to be generated for each map and the
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +00007255 // types below. The generated information is expressed in this order:
Samuel Antao86ace552016-04-27 22:40:57 +00007256 // base pointer, section pointer, size, flags
7257 // (to add to the ones that come from the map type and modifier).
7258 //
7259 // double d;
7260 // int i[100];
7261 // float *p;
7262 //
7263 // struct S1 {
7264 // int i;
7265 // float f[50];
7266 // }
7267 // struct S2 {
7268 // int i;
7269 // float f[50];
7270 // S1 s;
7271 // double *p;
7272 // struct S2 *ps;
7273 // }
7274 // S2 s;
7275 // S2 *ps;
7276 //
7277 // map(d)
Alexey Bataevb3638132018-07-19 16:34:13 +00007278 // &d, &d, sizeof(double), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007279 //
7280 // map(i)
Alexey Bataevb3638132018-07-19 16:34:13 +00007281 // &i, &i, 100*sizeof(int), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007282 //
7283 // map(i[1:23])
Alexey Bataevb3638132018-07-19 16:34:13 +00007284 // &i(=&i[0]), &i[1], 23*sizeof(int), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007285 //
7286 // map(p)
Alexey Bataevb3638132018-07-19 16:34:13 +00007287 // &p, &p, sizeof(float*), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007288 //
7289 // map(p[1:24])
Alexey Bataevb3638132018-07-19 16:34:13 +00007290 // p, &p[1], 24*sizeof(float), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007291 //
7292 // map(s)
Alexey Bataevb3638132018-07-19 16:34:13 +00007293 // &s, &s, sizeof(S2), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007294 //
7295 // map(s.i)
Alexey Bataevb3638132018-07-19 16:34:13 +00007296 // &s, &(s.i), sizeof(int), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007297 //
7298 // map(s.s.f)
Alexey Bataevb3638132018-07-19 16:34:13 +00007299 // &s, &(s.s.f[0]), 50*sizeof(float), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007300 //
7301 // map(s.p)
Alexey Bataevb3638132018-07-19 16:34:13 +00007302 // &s, &(s.p), sizeof(double*), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007303 //
Alexey Bataevb3638132018-07-19 16:34:13 +00007304 // map(to: s.p[:22])
7305 // &s, &(s.p), sizeof(double*), TARGET_PARAM (*)
7306 // &s, &(s.p), sizeof(double*), MEMBER_OF(1) (**)
7307 // &(s.p), &(s.p[0]), 22*sizeof(double),
7308 // MEMBER_OF(1) | PTR_AND_OBJ | TO (***)
7309 // (*) alloc space for struct members, only this is a target parameter
7310 // (**) map the pointer (nothing to be mapped in this example) (the compiler
7311 // optimizes this entry out, same in the examples below)
7312 // (***) map the pointee (map: to)
Samuel Antao86ace552016-04-27 22:40:57 +00007313 //
7314 // map(s.ps)
Alexey Bataevb3638132018-07-19 16:34:13 +00007315 // &s, &(s.ps), sizeof(S2*), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007316 //
Alexey Bataevb3638132018-07-19 16:34:13 +00007317 // map(from: s.ps->s.i)
7318 // &s, &(s.ps), sizeof(S2*), TARGET_PARAM
7319 // &s, &(s.ps), sizeof(S2*), MEMBER_OF(1)
7320 // &(s.ps), &(s.ps->s.i), sizeof(int), MEMBER_OF(1) | PTR_AND_OBJ | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007321 //
Alexey Bataevb3638132018-07-19 16:34:13 +00007322 // map(to: s.ps->ps)
7323 // &s, &(s.ps), sizeof(S2*), TARGET_PARAM
7324 // &s, &(s.ps), sizeof(S2*), MEMBER_OF(1)
7325 // &(s.ps), &(s.ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ | TO
Samuel Antao86ace552016-04-27 22:40:57 +00007326 //
7327 // map(s.ps->ps->ps)
Alexey Bataevb3638132018-07-19 16:34:13 +00007328 // &s, &(s.ps), sizeof(S2*), TARGET_PARAM
7329 // &s, &(s.ps), sizeof(S2*), MEMBER_OF(1)
7330 // &(s.ps), &(s.ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ
7331 // &(s.ps->ps), &(s.ps->ps->ps), sizeof(S2*), PTR_AND_OBJ | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007332 //
Alexey Bataevb3638132018-07-19 16:34:13 +00007333 // map(to: s.ps->ps->s.f[:22])
7334 // &s, &(s.ps), sizeof(S2*), TARGET_PARAM
7335 // &s, &(s.ps), sizeof(S2*), MEMBER_OF(1)
7336 // &(s.ps), &(s.ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ
7337 // &(s.ps->ps), &(s.ps->ps->s.f[0]), 22*sizeof(float), PTR_AND_OBJ | TO
Samuel Antao86ace552016-04-27 22:40:57 +00007338 //
7339 // map(ps)
Alexey Bataevb3638132018-07-19 16:34:13 +00007340 // &ps, &ps, sizeof(S2*), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007341 //
7342 // map(ps->i)
Alexey Bataevb3638132018-07-19 16:34:13 +00007343 // ps, &(ps->i), sizeof(int), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007344 //
7345 // map(ps->s.f)
Alexey Bataevb3638132018-07-19 16:34:13 +00007346 // ps, &(ps->s.f[0]), 50*sizeof(float), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007347 //
Alexey Bataevb3638132018-07-19 16:34:13 +00007348 // map(from: ps->p)
7349 // ps, &(ps->p), sizeof(double*), TARGET_PARAM | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007350 //
Alexey Bataevb3638132018-07-19 16:34:13 +00007351 // map(to: ps->p[:22])
7352 // ps, &(ps->p), sizeof(double*), TARGET_PARAM
7353 // ps, &(ps->p), sizeof(double*), MEMBER_OF(1)
7354 // &(ps->p), &(ps->p[0]), 22*sizeof(double), MEMBER_OF(1) | PTR_AND_OBJ | TO
Samuel Antao86ace552016-04-27 22:40:57 +00007355 //
7356 // map(ps->ps)
Alexey Bataevb3638132018-07-19 16:34:13 +00007357 // ps, &(ps->ps), sizeof(S2*), TARGET_PARAM | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007358 //
Alexey Bataevb3638132018-07-19 16:34:13 +00007359 // map(from: ps->ps->s.i)
7360 // ps, &(ps->ps), sizeof(S2*), TARGET_PARAM
7361 // ps, &(ps->ps), sizeof(S2*), MEMBER_OF(1)
7362 // &(ps->ps), &(ps->ps->s.i), sizeof(int), MEMBER_OF(1) | PTR_AND_OBJ | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007363 //
Alexey Bataevb3638132018-07-19 16:34:13 +00007364 // map(from: ps->ps->ps)
7365 // ps, &(ps->ps), sizeof(S2*), TARGET_PARAM
7366 // ps, &(ps->ps), sizeof(S2*), MEMBER_OF(1)
7367 // &(ps->ps), &(ps->ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007368 //
7369 // map(ps->ps->ps->ps)
Alexey Bataevb3638132018-07-19 16:34:13 +00007370 // ps, &(ps->ps), sizeof(S2*), TARGET_PARAM
7371 // ps, &(ps->ps), sizeof(S2*), MEMBER_OF(1)
7372 // &(ps->ps), &(ps->ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ
7373 // &(ps->ps->ps), &(ps->ps->ps->ps), sizeof(S2*), PTR_AND_OBJ | TO | FROM
Samuel Antao86ace552016-04-27 22:40:57 +00007374 //
Alexey Bataevb3638132018-07-19 16:34:13 +00007375 // map(to: ps->ps->ps->s.f[:22])
7376 // ps, &(ps->ps), sizeof(S2*), TARGET_PARAM
7377 // ps, &(ps->ps), sizeof(S2*), MEMBER_OF(1)
7378 // &(ps->ps), &(ps->ps->ps), sizeof(S2*), MEMBER_OF(1) | PTR_AND_OBJ
7379 // &(ps->ps->ps), &(ps->ps->ps->s.f[0]), 22*sizeof(float), PTR_AND_OBJ | TO
7380 //
7381 // map(to: s.f[:22]) map(from: s.p[:33])
7382 // &s, &(s.f[0]), 50*sizeof(float) + sizeof(struct S1) +
7383 // sizeof(double*) (**), TARGET_PARAM
7384 // &s, &(s.f[0]), 22*sizeof(float), MEMBER_OF(1) | TO
7385 // &s, &(s.p), sizeof(double*), MEMBER_OF(1)
7386 // &(s.p), &(s.p[0]), 33*sizeof(double), MEMBER_OF(1) | PTR_AND_OBJ | FROM
7387 // (*) allocate contiguous space needed to fit all mapped members even if
7388 // we allocate space for members not mapped (in this example,
7389 // s.f[22..49] and s.s are not mapped, yet we must allocate space for
7390 // them as well because they fall between &s.f[0] and &s.p)
7391 //
7392 // map(from: s.f[:22]) map(to: ps->p[:33])
7393 // &s, &(s.f[0]), 22*sizeof(float), TARGET_PARAM | FROM
7394 // ps, &(ps->p), sizeof(S2*), TARGET_PARAM
7395 // ps, &(ps->p), sizeof(double*), MEMBER_OF(2) (*)
7396 // &(ps->p), &(ps->p[0]), 33*sizeof(double), MEMBER_OF(2) | PTR_AND_OBJ | TO
7397 // (*) the struct this entry pertains to is the 2nd element in the list of
7398 // arguments, hence MEMBER_OF(2)
7399 //
7400 // map(from: s.f[:22], s.s) map(to: ps->p[:33])
7401 // &s, &(s.f[0]), 50*sizeof(float) + sizeof(struct S1), TARGET_PARAM
7402 // &s, &(s.f[0]), 22*sizeof(float), MEMBER_OF(1) | FROM
7403 // &s, &(s.s), sizeof(struct S1), MEMBER_OF(1) | FROM
7404 // ps, &(ps->p), sizeof(S2*), TARGET_PARAM
7405 // ps, &(ps->p), sizeof(double*), MEMBER_OF(4) (*)
7406 // &(ps->p), &(ps->p[0]), 33*sizeof(double), MEMBER_OF(4) | PTR_AND_OBJ | TO
7407 // (*) the struct this entry pertains to is the 4th element in the list
7408 // of arguments, hence MEMBER_OF(4)
Samuel Antao86ace552016-04-27 22:40:57 +00007409
7410 // Track if the map information being generated is the first for a capture.
7411 bool IsCaptureFirstInfo = IsFirstComponentList;
Alexey Bataev92327c52018-03-26 16:40:55 +00007412 bool IsLink = false; // Is this variable a "declare target link"?
Samuel Antao86ace552016-04-27 22:40:57 +00007413
7414 // Scan the components from the base to the complete expression.
7415 auto CI = Components.rbegin();
7416 auto CE = Components.rend();
7417 auto I = CI;
7418
7419 // Track if the map information being generated is the first for a list of
7420 // components.
7421 bool IsExpressionFirstInfo = true;
Alexey Bataevb3638132018-07-19 16:34:13 +00007422 Address BP = Address::invalid();
Patrick Lystere13b1e32019-01-02 19:28:48 +00007423 const Expr *AssocExpr = I->getAssociatedExpression();
7424 const auto *AE = dyn_cast<ArraySubscriptExpr>(AssocExpr);
7425 const auto *OASE = dyn_cast<OMPArraySectionExpr>(AssocExpr);
Samuel Antao86ace552016-04-27 22:40:57 +00007426
Patrick Lystere13b1e32019-01-02 19:28:48 +00007427 if (isa<MemberExpr>(AssocExpr)) {
Samuel Antao86ace552016-04-27 22:40:57 +00007428 // The base is the 'this' pointer. The content of the pointer is going
7429 // to be the base of the field being mapped.
Alexey Bataevb3638132018-07-19 16:34:13 +00007430 BP = CGF.LoadCXXThisAddress();
Patrick Lystere13b1e32019-01-02 19:28:48 +00007431 } else if ((AE && isa<CXXThisExpr>(AE->getBase()->IgnoreParenImpCasts())) ||
7432 (OASE &&
7433 isa<CXXThisExpr>(OASE->getBase()->IgnoreParenImpCasts()))) {
7434 BP = CGF.EmitOMPSharedLValue(AssocExpr).getAddress();
Samuel Antao86ace552016-04-27 22:40:57 +00007435 } else {
7436 // The base is the reference to the variable.
7437 // BP = &Var.
Patrick Lystere13b1e32019-01-02 19:28:48 +00007438 BP = CGF.EmitOMPSharedLValue(AssocExpr).getAddress();
Alexey Bataev92327c52018-03-26 16:40:55 +00007439 if (const auto *VD =
7440 dyn_cast_or_null<VarDecl>(I->getAssociatedDeclaration())) {
7441 if (llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
Alexey Bataev97b72212018-08-14 18:31:20 +00007442 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
Alexey Bataev2c1dffe2018-04-16 20:34:41 +00007443 if (*Res == OMPDeclareTargetDeclAttr::MT_Link) {
7444 IsLink = true;
Alexey Bataevb3638132018-07-19 16:34:13 +00007445 BP = CGF.CGM.getOpenMPRuntime().getAddrOfDeclareTargetLink(VD);
Alexey Bataev2c1dffe2018-04-16 20:34:41 +00007446 }
Alexey Bataev92327c52018-03-26 16:40:55 +00007447 }
Samuel Antao86ace552016-04-27 22:40:57 +00007448
7449 // If the variable is a pointer and is being dereferenced (i.e. is not
Nico Webera6916892016-06-10 18:53:04 +00007450 // the last component), the base has to be the pointer itself, not its
Samuel Antao403ffd42016-07-27 22:49:49 +00007451 // reference. References are ignored for mapping purposes.
7452 QualType Ty =
7453 I->getAssociatedDeclaration()->getType().getNonReferenceType();
7454 if (Ty->isAnyPointerType() && std::next(I) != CE) {
Alexey Bataevb3638132018-07-19 16:34:13 +00007455 BP = CGF.EmitLoadOfPointer(BP, Ty->castAs<PointerType>());
Samuel Antao86ace552016-04-27 22:40:57 +00007456
7457 // We do not need to generate individual map information for the
7458 // pointer, it can be associated with the combined storage.
7459 ++I;
7460 }
7461 }
7462
Alexey Bataevb3638132018-07-19 16:34:13 +00007463 // Track whether a component of the list should be marked as MEMBER_OF some
7464 // combined entry (for partial structs). Only the first PTR_AND_OBJ entry
7465 // in a component list should be marked as MEMBER_OF, all subsequent entries
7466 // do not belong to the base struct. E.g.
7467 // struct S2 s;
7468 // s.ps->ps->ps->f[:]
7469 // (1) (2) (3) (4)
7470 // ps(1) is a member pointer, ps(2) is a pointee of ps(1), so it is a
7471 // PTR_AND_OBJ entry; the PTR is ps(1), so MEMBER_OF the base struct. ps(3)
7472 // is the pointee of ps(2) which is not member of struct s, so it should not
7473 // be marked as such (it is still PTR_AND_OBJ).
7474 // The variable is initialized to false so that PTR_AND_OBJ entries which
7475 // are not struct members are not considered (e.g. array of pointers to
7476 // data).
7477 bool ShouldBeMemberOf = false;
7478
7479 // Variable keeping track of whether or not we have encountered a component
7480 // in the component list which is a member expression. Useful when we have a
7481 // pointer or a final array section, in which case it is the previous
7482 // component in the list which tells us whether we have a member expression.
7483 // E.g. X.f[:]
7484 // While processing the final array section "[:]" it is "f" which tells us
7485 // whether we are dealing with a member of a declared struct.
7486 const MemberExpr *EncounteredME = nullptr;
7487
Samuel Antao86ace552016-04-27 22:40:57 +00007488 for (; I != CE; ++I) {
Alexey Bataevb3638132018-07-19 16:34:13 +00007489 // If the current component is member of a struct (parent struct) mark it.
7490 if (!EncounteredME) {
7491 EncounteredME = dyn_cast<MemberExpr>(I->getAssociatedExpression());
7492 // If we encounter a PTR_AND_OBJ entry from now on it should be marked
7493 // as MEMBER_OF the parent struct.
7494 if (EncounteredME)
7495 ShouldBeMemberOf = true;
7496 }
7497
Samuel Antao86ace552016-04-27 22:40:57 +00007498 auto Next = std::next(I);
7499
7500 // We need to generate the addresses and sizes if this is the last
7501 // component, if the component is a pointer or if it is an array section
7502 // whose length can't be proved to be one. If this is a pointer, it
7503 // becomes the base address for the following components.
7504
7505 // A final array section, is one whose length can't be proved to be one.
7506 bool IsFinalArraySection =
7507 isFinalArraySectionExpression(I->getAssociatedExpression());
7508
7509 // Get information on whether the element is a pointer. Have to do a
7510 // special treatment for array sections given that they are built-in
7511 // types.
7512 const auto *OASE =
7513 dyn_cast<OMPArraySectionExpr>(I->getAssociatedExpression());
7514 bool IsPointer =
Alexey Bataevb3638132018-07-19 16:34:13 +00007515 (OASE && OMPArraySectionExpr::getBaseOriginalType(OASE)
7516 .getCanonicalType()
7517 ->isAnyPointerType()) ||
Samuel Antao86ace552016-04-27 22:40:57 +00007518 I->getAssociatedExpression()->getType()->isAnyPointerType();
7519
7520 if (Next == CE || IsPointer || IsFinalArraySection) {
Samuel Antao86ace552016-04-27 22:40:57 +00007521 // If this is not the last component, we expect the pointer to be
7522 // associated with an array expression or member expression.
7523 assert((Next == CE ||
7524 isa<MemberExpr>(Next->getAssociatedExpression()) ||
7525 isa<ArraySubscriptExpr>(Next->getAssociatedExpression()) ||
7526 isa<OMPArraySectionExpr>(Next->getAssociatedExpression())) &&
7527 "Unexpected expression");
7528
Alexey Bataevb3638132018-07-19 16:34:13 +00007529 Address LB =
7530 CGF.EmitOMPSharedLValue(I->getAssociatedExpression()).getAddress();
Samuel Antao86ace552016-04-27 22:40:57 +00007531
Alexey Bataevb3638132018-07-19 16:34:13 +00007532 // If this component is a pointer inside the base struct then we don't
7533 // need to create any entry for it - it will be combined with the object
7534 // it is pointing to into a single PTR_AND_OBJ entry.
7535 bool IsMemberPointer =
7536 IsPointer && EncounteredME &&
7537 (dyn_cast<MemberExpr>(I->getAssociatedExpression()) ==
7538 EncounteredME);
Alexey Bataeve82445f2018-09-20 13:54:02 +00007539 if (!OverlappedElements.empty()) {
7540 // Handle base element with the info for overlapped elements.
7541 assert(!PartialStruct.Base.isValid() && "The base element is set.");
7542 assert(Next == CE &&
7543 "Expected last element for the overlapped elements.");
7544 assert(!IsPointer &&
7545 "Unexpected base element with the pointer type.");
7546 // Mark the whole struct as the struct that requires allocation on the
7547 // device.
7548 PartialStruct.LowestElem = {0, LB};
7549 CharUnits TypeSize = CGF.getContext().getTypeSizeInChars(
7550 I->getAssociatedExpression()->getType());
7551 Address HB = CGF.Builder.CreateConstGEP(
7552 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(LB,
7553 CGF.VoidPtrTy),
James Y Knight751fe282019-02-09 22:22:28 +00007554 TypeSize.getQuantity() - 1);
Alexey Bataeve82445f2018-09-20 13:54:02 +00007555 PartialStruct.HighestElem = {
7556 std::numeric_limits<decltype(
7557 PartialStruct.HighestElem.first)>::max(),
7558 HB};
7559 PartialStruct.Base = BP;
7560 // Emit data for non-overlapped data.
7561 OpenMPOffloadMappingFlags Flags =
7562 OMP_MAP_MEMBER_OF |
Kelvin Lief579432018-12-18 22:18:41 +00007563 getMapTypeBits(MapType, MapModifiers, IsImplicit,
Alexey Bataeve82445f2018-09-20 13:54:02 +00007564 /*AddPtrFlag=*/false,
7565 /*AddIsTargetParamFlag=*/false);
7566 LB = BP;
7567 llvm::Value *Size = nullptr;
7568 // Do bitcopy of all non-overlapped structure elements.
7569 for (OMPClauseMappableExprCommon::MappableExprComponentListRef
7570 Component : OverlappedElements) {
7571 Address ComponentLB = Address::invalid();
7572 for (const OMPClauseMappableExprCommon::MappableComponent &MC :
7573 Component) {
7574 if (MC.getAssociatedDeclaration()) {
7575 ComponentLB =
7576 CGF.EmitOMPSharedLValue(MC.getAssociatedExpression())
7577 .getAddress();
7578 Size = CGF.Builder.CreatePtrDiff(
7579 CGF.EmitCastToVoidPtr(ComponentLB.getPointer()),
7580 CGF.EmitCastToVoidPtr(LB.getPointer()));
7581 break;
7582 }
7583 }
7584 BasePointers.push_back(BP.getPointer());
7585 Pointers.push_back(LB.getPointer());
7586 Sizes.push_back(Size);
7587 Types.push_back(Flags);
James Y Knight751fe282019-02-09 22:22:28 +00007588 LB = CGF.Builder.CreateConstGEP(ComponentLB, 1);
Alexey Bataeve82445f2018-09-20 13:54:02 +00007589 }
7590 BasePointers.push_back(BP.getPointer());
7591 Pointers.push_back(LB.getPointer());
7592 Size = CGF.Builder.CreatePtrDiff(
7593 CGF.EmitCastToVoidPtr(
James Y Knight751fe282019-02-09 22:22:28 +00007594 CGF.Builder.CreateConstGEP(HB, 1).getPointer()),
Alexey Bataeve82445f2018-09-20 13:54:02 +00007595 CGF.EmitCastToVoidPtr(LB.getPointer()));
7596 Sizes.push_back(Size);
7597 Types.push_back(Flags);
7598 break;
7599 }
7600 llvm::Value *Size = getExprTypeSize(I->getAssociatedExpression());
Alexey Bataevb3638132018-07-19 16:34:13 +00007601 if (!IsMemberPointer) {
7602 BasePointers.push_back(BP.getPointer());
7603 Pointers.push_back(LB.getPointer());
7604 Sizes.push_back(Size);
Samuel Antao03a3cec2016-07-27 22:52:16 +00007605
Alexey Bataevb3638132018-07-19 16:34:13 +00007606 // We need to add a pointer flag for each map that comes from the
7607 // same expression except for the first one. We also need to signal
7608 // this map is the first one that relates with the current capture
7609 // (there is a set of entries for each capture).
7610 OpenMPOffloadMappingFlags Flags = getMapTypeBits(
Kelvin Lief579432018-12-18 22:18:41 +00007611 MapType, MapModifiers, IsImplicit,
Alexey Bataevb3638132018-07-19 16:34:13 +00007612 !IsExpressionFirstInfo || IsLink, IsCaptureFirstInfo && !IsLink);
7613
7614 if (!IsExpressionFirstInfo) {
7615 // If we have a PTR_AND_OBJ pair where the OBJ is a pointer as well,
7616 // then we reset the TO/FROM/ALWAYS/DELETE flags.
7617 if (IsPointer)
7618 Flags &= ~(OMP_MAP_TO | OMP_MAP_FROM | OMP_MAP_ALWAYS |
7619 OMP_MAP_DELETE);
7620
7621 if (ShouldBeMemberOf) {
7622 // Set placeholder value MEMBER_OF=FFFF to indicate that the flag
7623 // should be later updated with the correct value of MEMBER_OF.
7624 Flags |= OMP_MAP_MEMBER_OF;
7625 // From now on, all subsequent PTR_AND_OBJ entries should not be
7626 // marked as MEMBER_OF.
7627 ShouldBeMemberOf = false;
7628 }
7629 }
7630
7631 Types.push_back(Flags);
Samuel Antao03a3cec2016-07-27 22:52:16 +00007632 }
7633
Alexey Bataevb3638132018-07-19 16:34:13 +00007634 // If we have encountered a member expression so far, keep track of the
7635 // mapped member. If the parent is "*this", then the value declaration
7636 // is nullptr.
7637 if (EncounteredME) {
7638 const auto *FD = dyn_cast<FieldDecl>(EncounteredME->getMemberDecl());
7639 unsigned FieldIndex = FD->getFieldIndex();
Samuel Antao03a3cec2016-07-27 22:52:16 +00007640
Alexey Bataevb3638132018-07-19 16:34:13 +00007641 // Update info about the lowest and highest elements for this struct
7642 if (!PartialStruct.Base.isValid()) {
7643 PartialStruct.LowestElem = {FieldIndex, LB};
7644 PartialStruct.HighestElem = {FieldIndex, LB};
7645 PartialStruct.Base = BP;
7646 } else if (FieldIndex < PartialStruct.LowestElem.first) {
7647 PartialStruct.LowestElem = {FieldIndex, LB};
7648 } else if (FieldIndex > PartialStruct.HighestElem.first) {
7649 PartialStruct.HighestElem = {FieldIndex, LB};
7650 }
7651 }
Samuel Antao86ace552016-04-27 22:40:57 +00007652
7653 // If we have a final array section, we are done with this expression.
7654 if (IsFinalArraySection)
7655 break;
7656
7657 // The pointer becomes the base for the next element.
7658 if (Next != CE)
7659 BP = LB;
7660
7661 IsExpressionFirstInfo = false;
7662 IsCaptureFirstInfo = false;
Samuel Antao86ace552016-04-27 22:40:57 +00007663 }
7664 }
7665 }
7666
Alexey Bataevb3638132018-07-19 16:34:13 +00007667 /// Return the adjusted map modifiers if the declaration a capture refers to
7668 /// appears in a first-private clause. This is expected to be used only with
7669 /// directives that start with 'target'.
7670 MappableExprsHandler::OpenMPOffloadMappingFlags
7671 getMapModifiersForPrivateClauses(const CapturedStmt::Capture &Cap) const {
7672 assert(Cap.capturesVariable() && "Expected capture by reference only!");
7673
7674 // A first private variable captured by reference will use only the
7675 // 'private ptr' and 'map to' flag. Return the right flags if the captured
7676 // declaration is known as first-private in this handler.
Alexey Bataev1af5bd52019-03-05 17:47:18 +00007677 if (FirstPrivateDecls.count(Cap.getCapturedVar())) {
7678 if (Cap.getCapturedVar()->getType().isConstant(CGF.getContext()) &&
7679 Cap.getCaptureKind() == CapturedStmt::VCK_ByRef)
7680 return MappableExprsHandler::OMP_MAP_ALWAYS |
7681 MappableExprsHandler::OMP_MAP_TO;
Alexey Bataevc2b831f2019-04-02 16:03:40 +00007682 if (Cap.getCapturedVar()->getType()->isAnyPointerType())
7683 return MappableExprsHandler::OMP_MAP_TO |
7684 MappableExprsHandler::OMP_MAP_PTR_AND_OBJ;
Alexey Bataevb3638132018-07-19 16:34:13 +00007685 return MappableExprsHandler::OMP_MAP_PRIVATE |
7686 MappableExprsHandler::OMP_MAP_TO;
Alexey Bataev1af5bd52019-03-05 17:47:18 +00007687 }
Alexey Bataevb3638132018-07-19 16:34:13 +00007688 return MappableExprsHandler::OMP_MAP_TO |
7689 MappableExprsHandler::OMP_MAP_FROM;
7690 }
7691
7692 static OpenMPOffloadMappingFlags getMemberOfFlag(unsigned Position) {
7693 // Member of is given by the 16 MSB of the flag, so rotate by 48 bits.
7694 return static_cast<OpenMPOffloadMappingFlags>(((uint64_t)Position + 1)
7695 << 48);
7696 }
7697
7698 static void setCorrectMemberOfFlag(OpenMPOffloadMappingFlags &Flags,
7699 OpenMPOffloadMappingFlags MemberOfFlag) {
7700 // If the entry is PTR_AND_OBJ but has not been marked with the special
7701 // placeholder value 0xFFFF in the MEMBER_OF field, then it should not be
7702 // marked as MEMBER_OF.
7703 if ((Flags & OMP_MAP_PTR_AND_OBJ) &&
7704 ((Flags & OMP_MAP_MEMBER_OF) != OMP_MAP_MEMBER_OF))
7705 return;
7706
7707 // Reset the placeholder value to prepare the flag for the assignment of the
7708 // proper MEMBER_OF value.
7709 Flags &= ~OMP_MAP_MEMBER_OF;
7710 Flags |= MemberOfFlag;
7711 }
7712
Alexey Bataeve82445f2018-09-20 13:54:02 +00007713 void getPlainLayout(const CXXRecordDecl *RD,
7714 llvm::SmallVectorImpl<const FieldDecl *> &Layout,
7715 bool AsBase) const {
7716 const CGRecordLayout &RL = CGF.getTypes().getCGRecordLayout(RD);
7717
7718 llvm::StructType *St =
7719 AsBase ? RL.getBaseSubobjectLLVMType() : RL.getLLVMType();
7720
7721 unsigned NumElements = St->getNumElements();
7722 llvm::SmallVector<
7723 llvm::PointerUnion<const CXXRecordDecl *, const FieldDecl *>, 4>
7724 RecordLayout(NumElements);
7725
7726 // Fill bases.
7727 for (const auto &I : RD->bases()) {
7728 if (I.isVirtual())
7729 continue;
7730 const auto *Base = I.getType()->getAsCXXRecordDecl();
7731 // Ignore empty bases.
7732 if (Base->isEmpty() || CGF.getContext()
7733 .getASTRecordLayout(Base)
7734 .getNonVirtualSize()
7735 .isZero())
7736 continue;
7737
7738 unsigned FieldIndex = RL.getNonVirtualBaseLLVMFieldNo(Base);
7739 RecordLayout[FieldIndex] = Base;
7740 }
7741 // Fill in virtual bases.
7742 for (const auto &I : RD->vbases()) {
7743 const auto *Base = I.getType()->getAsCXXRecordDecl();
7744 // Ignore empty bases.
7745 if (Base->isEmpty())
7746 continue;
7747 unsigned FieldIndex = RL.getVirtualBaseIndex(Base);
7748 if (RecordLayout[FieldIndex])
7749 continue;
7750 RecordLayout[FieldIndex] = Base;
7751 }
7752 // Fill in all the fields.
7753 assert(!RD->isUnion() && "Unexpected union.");
7754 for (const auto *Field : RD->fields()) {
7755 // Fill in non-bitfields. (Bitfields always use a zero pattern, which we
7756 // will fill in later.)
7757 if (!Field->isBitField()) {
7758 unsigned FieldIndex = RL.getLLVMFieldNo(Field);
7759 RecordLayout[FieldIndex] = Field;
7760 }
7761 }
7762 for (const llvm::PointerUnion<const CXXRecordDecl *, const FieldDecl *>
7763 &Data : RecordLayout) {
7764 if (Data.isNull())
7765 continue;
7766 if (const auto *Base = Data.dyn_cast<const CXXRecordDecl *>())
7767 getPlainLayout(Base, Layout, /*AsBase=*/true);
7768 else
7769 Layout.push_back(Data.get<const FieldDecl *>());
7770 }
7771 }
7772
Alexey Bataevb3638132018-07-19 16:34:13 +00007773public:
7774 MappableExprsHandler(const OMPExecutableDirective &Dir, CodeGenFunction &CGF)
7775 : CurDir(Dir), CGF(CGF) {
7776 // Extract firstprivate clause information.
7777 for (const auto *C : Dir.getClausesOfKind<OMPFirstprivateClause>())
7778 for (const auto *D : C->varlists())
7779 FirstPrivateDecls.insert(
7780 cast<VarDecl>(cast<DeclRefExpr>(D)->getDecl())->getCanonicalDecl());
7781 // Extract device pointer clause information.
7782 for (const auto *C : Dir.getClausesOfKind<OMPIsDevicePtrClause>())
7783 for (auto L : C->component_lists())
7784 DevPointersMap[L.first].push_back(L.second);
7785 }
7786
7787 /// Generate code for the combined entry if we have a partially mapped struct
7788 /// and take care of the mapping flags of the arguments corresponding to
7789 /// individual struct members.
7790 void emitCombinedEntry(MapBaseValuesArrayTy &BasePointers,
7791 MapValuesArrayTy &Pointers, MapValuesArrayTy &Sizes,
7792 MapFlagsArrayTy &Types, MapFlagsArrayTy &CurTypes,
7793 const StructRangeInfoTy &PartialStruct) const {
7794 // Base is the base of the struct
7795 BasePointers.push_back(PartialStruct.Base.getPointer());
7796 // Pointer is the address of the lowest element
7797 llvm::Value *LB = PartialStruct.LowestElem.second.getPointer();
7798 Pointers.push_back(LB);
7799 // Size is (addr of {highest+1} element) - (addr of lowest element)
7800 llvm::Value *HB = PartialStruct.HighestElem.second.getPointer();
7801 llvm::Value *HAddr = CGF.Builder.CreateConstGEP1_32(HB, /*Idx0=*/1);
7802 llvm::Value *CLAddr = CGF.Builder.CreatePointerCast(LB, CGF.VoidPtrTy);
7803 llvm::Value *CHAddr = CGF.Builder.CreatePointerCast(HAddr, CGF.VoidPtrTy);
7804 llvm::Value *Diff = CGF.Builder.CreatePtrDiff(CHAddr, CLAddr);
7805 llvm::Value *Size = CGF.Builder.CreateIntCast(Diff, CGF.SizeTy,
7806 /*isSinged=*/false);
7807 Sizes.push_back(Size);
7808 // Map type is always TARGET_PARAM
7809 Types.push_back(OMP_MAP_TARGET_PARAM);
7810 // Remove TARGET_PARAM flag from the first element
7811 (*CurTypes.begin()) &= ~OMP_MAP_TARGET_PARAM;
7812
7813 // All other current entries will be MEMBER_OF the combined entry
7814 // (except for PTR_AND_OBJ entries which do not have a placeholder value
7815 // 0xFFFF in the MEMBER_OF field).
7816 OpenMPOffloadMappingFlags MemberOfFlag =
7817 getMemberOfFlag(BasePointers.size() - 1);
7818 for (auto &M : CurTypes)
7819 setCorrectMemberOfFlag(M, MemberOfFlag);
7820 }
7821
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007822 /// Generate all the base pointers, section pointers, sizes and map
Samuel Antaocc10b852016-07-28 14:23:26 +00007823 /// types for the extracted mappable expressions. Also, for each item that
7824 /// relates with a device pointer, a pair of the relevant declaration and
7825 /// index where it occurs is appended to the device pointers info array.
7826 void generateAllInfo(MapBaseValuesArrayTy &BasePointers,
Samuel Antao86ace552016-04-27 22:40:57 +00007827 MapValuesArrayTy &Pointers, MapValuesArrayTy &Sizes,
7828 MapFlagsArrayTy &Types) const {
Samuel Antao86ace552016-04-27 22:40:57 +00007829 // We have to process the component lists that relate with the same
7830 // declaration in a single chunk so that we can generate the map flags
7831 // correctly. Therefore, we organize all lists in a map.
Alexey Bataev5d1c3f62017-06-27 15:46:42 +00007832 llvm::MapVector<const ValueDecl *, SmallVector<MapInfo, 8>> Info;
Samuel Antao8d2d7302016-05-26 18:30:22 +00007833
7834 // Helper function to fill the information map for the different supported
7835 // clauses.
Samuel Antaocc10b852016-07-28 14:23:26 +00007836 auto &&InfoGen = [&Info](
7837 const ValueDecl *D,
7838 OMPClauseMappableExprCommon::MappableExprComponentListRef L,
Kelvin Lief579432018-12-18 22:18:41 +00007839 OpenMPMapClauseKind MapType,
7840 ArrayRef<OpenMPMapModifierKind> MapModifiers,
Alexey Bataevb3638132018-07-19 16:34:13 +00007841 bool ReturnDevicePointer, bool IsImplicit) {
Samuel Antaocc10b852016-07-28 14:23:26 +00007842 const ValueDecl *VD =
7843 D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
Kelvin Lief579432018-12-18 22:18:41 +00007844 Info[VD].emplace_back(L, MapType, MapModifiers, ReturnDevicePointer,
Alexey Bataevf47c4b42017-09-26 13:47:31 +00007845 IsImplicit);
Samuel Antaocc10b852016-07-28 14:23:26 +00007846 };
Samuel Antao8d2d7302016-05-26 18:30:22 +00007847
Paul Robinson78fb1322016-08-01 22:12:46 +00007848 // FIXME: MSVC 2013 seems to require this-> to find member CurDir.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007849 for (const auto *C : this->CurDir.getClausesOfKind<OMPMapClause>())
7850 for (const auto &L : C->component_lists()) {
Kelvin Lief579432018-12-18 22:18:41 +00007851 InfoGen(L.first, L.second, C->getMapType(), C->getMapTypeModifiers(),
Alexey Bataevb3638132018-07-19 16:34:13 +00007852 /*ReturnDevicePointer=*/false, C->isImplicit());
Alexey Bataevf47c4b42017-09-26 13:47:31 +00007853 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007854 for (const auto *C : this->CurDir.getClausesOfKind<OMPToClause>())
7855 for (const auto &L : C->component_lists()) {
Kelvin Lief579432018-12-18 22:18:41 +00007856 InfoGen(L.first, L.second, OMPC_MAP_to, llvm::None,
Alexey Bataevb3638132018-07-19 16:34:13 +00007857 /*ReturnDevicePointer=*/false, C->isImplicit());
Alexey Bataevf47c4b42017-09-26 13:47:31 +00007858 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007859 for (const auto *C : this->CurDir.getClausesOfKind<OMPFromClause>())
7860 for (const auto &L : C->component_lists()) {
Kelvin Lief579432018-12-18 22:18:41 +00007861 InfoGen(L.first, L.second, OMPC_MAP_from, llvm::None,
Alexey Bataevb3638132018-07-19 16:34:13 +00007862 /*ReturnDevicePointer=*/false, C->isImplicit());
Alexey Bataevf47c4b42017-09-26 13:47:31 +00007863 }
Samuel Antao86ace552016-04-27 22:40:57 +00007864
Samuel Antaocc10b852016-07-28 14:23:26 +00007865 // Look at the use_device_ptr clause information and mark the existing map
7866 // entries as such. If there is no map information for an entry in the
7867 // use_device_ptr list, we create one with map type 'alloc' and zero size
Alexey Bataevb3638132018-07-19 16:34:13 +00007868 // section. It is the user fault if that was not mapped before. If there is
7869 // no map information and the pointer is a struct member, then we defer the
7870 // emission of that entry until the whole struct has been processed.
7871 llvm::MapVector<const ValueDecl *, SmallVector<DeferredDevicePtrEntryTy, 4>>
7872 DeferredInfo;
7873
Paul Robinson78fb1322016-08-01 22:12:46 +00007874 // FIXME: MSVC 2013 seems to require this-> to find member CurDir.
Alexey Bataevb3638132018-07-19 16:34:13 +00007875 for (const auto *C :
7876 this->CurDir.getClausesOfKind<OMPUseDevicePtrClause>()) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007877 for (const auto &L : C->component_lists()) {
Samuel Antaocc10b852016-07-28 14:23:26 +00007878 assert(!L.second.empty() && "Not expecting empty list of components!");
7879 const ValueDecl *VD = L.second.back().getAssociatedDeclaration();
7880 VD = cast<ValueDecl>(VD->getCanonicalDecl());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007881 const Expr *IE = L.second.back().getAssociatedExpression();
Samuel Antaocc10b852016-07-28 14:23:26 +00007882 // If the first component is a member expression, we have to look into
7883 // 'this', which maps to null in the map of map information. Otherwise
7884 // look directly for the information.
7885 auto It = Info.find(isa<MemberExpr>(IE) ? nullptr : VD);
7886
7887 // We potentially have map information for this declaration already.
7888 // Look for the first set of components that refer to it.
7889 if (It != Info.end()) {
7890 auto CI = std::find_if(
7891 It->second.begin(), It->second.end(), [VD](const MapInfo &MI) {
7892 return MI.Components.back().getAssociatedDeclaration() == VD;
7893 });
7894 // If we found a map entry, signal that the pointer has to be returned
7895 // and move on to the next declaration.
7896 if (CI != It->second.end()) {
Alexey Bataevb3638132018-07-19 16:34:13 +00007897 CI->ReturnDevicePointer = true;
Samuel Antaocc10b852016-07-28 14:23:26 +00007898 continue;
7899 }
7900 }
7901
7902 // We didn't find any match in our map information - generate a zero
Alexey Bataevb3638132018-07-19 16:34:13 +00007903 // size array section - if the pointer is a struct member we defer this
7904 // action until the whole struct has been processed.
Paul Robinson78fb1322016-08-01 22:12:46 +00007905 // FIXME: MSVC 2013 seems to require this-> to find member CGF.
Alexey Bataevb3638132018-07-19 16:34:13 +00007906 if (isa<MemberExpr>(IE)) {
7907 // Insert the pointer into Info to be processed by
7908 // generateInfoForComponentList. Because it is a member pointer
7909 // without a pointee, no entry will be generated for it, therefore
7910 // we need to generate one after the whole struct has been processed.
7911 // Nonetheless, generateInfoForComponentList must be called to take
7912 // the pointer into account for the calculation of the range of the
7913 // partial struct.
Kelvin Lief579432018-12-18 22:18:41 +00007914 InfoGen(nullptr, L.second, OMPC_MAP_unknown, llvm::None,
Alexey Bataevb3638132018-07-19 16:34:13 +00007915 /*ReturnDevicePointer=*/false, C->isImplicit());
7916 DeferredInfo[nullptr].emplace_back(IE, VD);
7917 } else {
7918 llvm::Value *Ptr = this->CGF.EmitLoadOfScalar(
7919 this->CGF.EmitLValue(IE), IE->getExprLoc());
7920 BasePointers.emplace_back(Ptr, VD);
7921 Pointers.push_back(Ptr);
7922 Sizes.push_back(llvm::Constant::getNullValue(this->CGF.SizeTy));
7923 Types.push_back(OMP_MAP_RETURN_PARAM | OMP_MAP_TARGET_PARAM);
7924 }
Samuel Antaocc10b852016-07-28 14:23:26 +00007925 }
Alexey Bataevb3638132018-07-19 16:34:13 +00007926 }
Samuel Antaocc10b852016-07-28 14:23:26 +00007927
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007928 for (const auto &M : Info) {
Samuel Antao86ace552016-04-27 22:40:57 +00007929 // We need to know when we generate information for the first component
7930 // associated with a capture, because the mapping flags depend on it.
7931 bool IsFirstComponentList = true;
Alexey Bataevb3638132018-07-19 16:34:13 +00007932
7933 // Temporary versions of arrays
7934 MapBaseValuesArrayTy CurBasePointers;
7935 MapValuesArrayTy CurPointers;
7936 MapValuesArrayTy CurSizes;
7937 MapFlagsArrayTy CurTypes;
7938 StructRangeInfoTy PartialStruct;
7939
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007940 for (const MapInfo &L : M.second) {
Samuel Antao86ace552016-04-27 22:40:57 +00007941 assert(!L.Components.empty() &&
7942 "Not expecting declaration with no component lists.");
Samuel Antaocc10b852016-07-28 14:23:26 +00007943
7944 // Remember the current base pointer index.
Alexey Bataevb3638132018-07-19 16:34:13 +00007945 unsigned CurrentBasePointersIdx = CurBasePointers.size();
Paul Robinson78fb1322016-08-01 22:12:46 +00007946 // FIXME: MSVC 2013 seems to require this-> to find the member method.
Alexey Bataevf47c4b42017-09-26 13:47:31 +00007947 this->generateInfoForComponentList(
Kelvin Lief579432018-12-18 22:18:41 +00007948 L.MapType, L.MapModifiers, L.Components, CurBasePointers,
Alexey Bataevb3638132018-07-19 16:34:13 +00007949 CurPointers, CurSizes, CurTypes, PartialStruct,
7950 IsFirstComponentList, L.IsImplicit);
Samuel Antaocc10b852016-07-28 14:23:26 +00007951
7952 // If this entry relates with a device pointer, set the relevant
7953 // declaration and add the 'return pointer' flag.
Alexey Bataevb3638132018-07-19 16:34:13 +00007954 if (L.ReturnDevicePointer) {
7955 assert(CurBasePointers.size() > CurrentBasePointersIdx &&
Samuel Antaocc10b852016-07-28 14:23:26 +00007956 "Unexpected number of mapped base pointers.");
7957
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00007958 const ValueDecl *RelevantVD =
7959 L.Components.back().getAssociatedDeclaration();
Samuel Antaocc10b852016-07-28 14:23:26 +00007960 assert(RelevantVD &&
7961 "No relevant declaration related with device pointer??");
7962
Alexey Bataevb3638132018-07-19 16:34:13 +00007963 CurBasePointers[CurrentBasePointersIdx].setDevicePtrDecl(RelevantVD);
7964 CurTypes[CurrentBasePointersIdx] |= OMP_MAP_RETURN_PARAM;
Samuel Antaocc10b852016-07-28 14:23:26 +00007965 }
Samuel Antao86ace552016-04-27 22:40:57 +00007966 IsFirstComponentList = false;
7967 }
Alexey Bataevb3638132018-07-19 16:34:13 +00007968
7969 // Append any pending zero-length pointers which are struct members and
7970 // used with use_device_ptr.
7971 auto CI = DeferredInfo.find(M.first);
7972 if (CI != DeferredInfo.end()) {
7973 for (const DeferredDevicePtrEntryTy &L : CI->second) {
7974 llvm::Value *BasePtr = this->CGF.EmitLValue(L.IE).getPointer();
7975 llvm::Value *Ptr = this->CGF.EmitLoadOfScalar(
7976 this->CGF.EmitLValue(L.IE), L.IE->getExprLoc());
7977 CurBasePointers.emplace_back(BasePtr, L.VD);
7978 CurPointers.push_back(Ptr);
7979 CurSizes.push_back(llvm::Constant::getNullValue(this->CGF.SizeTy));
7980 // Entry is PTR_AND_OBJ and RETURN_PARAM. Also, set the placeholder
7981 // value MEMBER_OF=FFFF so that the entry is later updated with the
7982 // correct value of MEMBER_OF.
7983 CurTypes.push_back(OMP_MAP_PTR_AND_OBJ | OMP_MAP_RETURN_PARAM |
7984 OMP_MAP_MEMBER_OF);
7985 }
7986 }
7987
7988 // If there is an entry in PartialStruct it means we have a struct with
7989 // individual members mapped. Emit an extra combined entry.
7990 if (PartialStruct.Base.isValid())
7991 emitCombinedEntry(BasePointers, Pointers, Sizes, Types, CurTypes,
7992 PartialStruct);
7993
7994 // We need to append the results of this capture to what we already have.
7995 BasePointers.append(CurBasePointers.begin(), CurBasePointers.end());
7996 Pointers.append(CurPointers.begin(), CurPointers.end());
7997 Sizes.append(CurSizes.begin(), CurSizes.end());
7998 Types.append(CurTypes.begin(), CurTypes.end());
Samuel Antao86ace552016-04-27 22:40:57 +00007999 }
8000 }
8001
Alexey Bataev60705422018-10-30 15:50:12 +00008002 /// Emit capture info for lambdas for variables captured by reference.
Alexey Bataev969dbc02018-11-08 15:47:39 +00008003 void generateInfoForLambdaCaptures(
8004 const ValueDecl *VD, llvm::Value *Arg, MapBaseValuesArrayTy &BasePointers,
8005 MapValuesArrayTy &Pointers, MapValuesArrayTy &Sizes,
8006 MapFlagsArrayTy &Types,
8007 llvm::DenseMap<llvm::Value *, llvm::Value *> &LambdaPointers) const {
Alexey Bataev60705422018-10-30 15:50:12 +00008008 const auto *RD = VD->getType()
8009 .getCanonicalType()
8010 .getNonReferenceType()
8011 ->getAsCXXRecordDecl();
8012 if (!RD || !RD->isLambda())
8013 return;
8014 Address VDAddr = Address(Arg, CGF.getContext().getDeclAlign(VD));
8015 LValue VDLVal = CGF.MakeAddrLValue(
8016 VDAddr, VD->getType().getCanonicalType().getNonReferenceType());
8017 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
8018 FieldDecl *ThisCapture = nullptr;
8019 RD->getCaptureFields(Captures, ThisCapture);
8020 if (ThisCapture) {
8021 LValue ThisLVal =
8022 CGF.EmitLValueForFieldInitialization(VDLVal, ThisCapture);
Alexey Bataev969dbc02018-11-08 15:47:39 +00008023 LValue ThisLValVal = CGF.EmitLValueForField(VDLVal, ThisCapture);
8024 LambdaPointers.try_emplace(ThisLVal.getPointer(), VDLVal.getPointer());
8025 BasePointers.push_back(ThisLVal.getPointer());
8026 Pointers.push_back(ThisLValVal.getPointer());
Alexey Bataev60705422018-10-30 15:50:12 +00008027 Sizes.push_back(CGF.getTypeSize(CGF.getContext().VoidPtrTy));
Alexey Bataev2dc07d02018-11-02 15:25:06 +00008028 Types.push_back(OMP_MAP_PTR_AND_OBJ | OMP_MAP_LITERAL |
Alexey Bataev60705422018-10-30 15:50:12 +00008029 OMP_MAP_MEMBER_OF | OMP_MAP_IMPLICIT);
8030 }
8031 for (const LambdaCapture &LC : RD->captures()) {
8032 if (LC.getCaptureKind() != LCK_ByRef)
8033 continue;
8034 const VarDecl *VD = LC.getCapturedVar();
8035 auto It = Captures.find(VD);
8036 assert(It != Captures.end() && "Found lambda capture without field.");
8037 LValue VarLVal = CGF.EmitLValueForFieldInitialization(VDLVal, It->second);
Alexey Bataev969dbc02018-11-08 15:47:39 +00008038 LValue VarLValVal = CGF.EmitLValueForField(VDLVal, It->second);
8039 LambdaPointers.try_emplace(VarLVal.getPointer(), VDLVal.getPointer());
8040 BasePointers.push_back(VarLVal.getPointer());
8041 Pointers.push_back(VarLValVal.getPointer());
Alexey Bataev60705422018-10-30 15:50:12 +00008042 Sizes.push_back(CGF.getTypeSize(
8043 VD->getType().getCanonicalType().getNonReferenceType()));
Alexey Bataev2dc07d02018-11-02 15:25:06 +00008044 Types.push_back(OMP_MAP_PTR_AND_OBJ | OMP_MAP_LITERAL |
Alexey Bataev60705422018-10-30 15:50:12 +00008045 OMP_MAP_MEMBER_OF | OMP_MAP_IMPLICIT);
8046 }
8047 }
8048
8049 /// Set correct indices for lambdas captures.
Alexey Bataev969dbc02018-11-08 15:47:39 +00008050 void adjustMemberOfForLambdaCaptures(
8051 const llvm::DenseMap<llvm::Value *, llvm::Value *> &LambdaPointers,
8052 MapBaseValuesArrayTy &BasePointers, MapValuesArrayTy &Pointers,
8053 MapFlagsArrayTy &Types) const {
Alexey Bataev60705422018-10-30 15:50:12 +00008054 for (unsigned I = 0, E = Types.size(); I < E; ++I) {
8055 // Set correct member_of idx for all implicit lambda captures.
Alexey Bataev2dc07d02018-11-02 15:25:06 +00008056 if (Types[I] != (OMP_MAP_PTR_AND_OBJ | OMP_MAP_LITERAL |
Alexey Bataev60705422018-10-30 15:50:12 +00008057 OMP_MAP_MEMBER_OF | OMP_MAP_IMPLICIT))
8058 continue;
Alexey Bataev969dbc02018-11-08 15:47:39 +00008059 llvm::Value *BasePtr = LambdaPointers.lookup(*BasePointers[I]);
8060 assert(BasePtr && "Unable to find base lambda address.");
Alexey Bataev60705422018-10-30 15:50:12 +00008061 int TgtIdx = -1;
8062 for (unsigned J = I; J > 0; --J) {
8063 unsigned Idx = J - 1;
8064 if (Pointers[Idx] != BasePtr)
8065 continue;
8066 TgtIdx = Idx;
8067 break;
8068 }
8069 assert(TgtIdx != -1 && "Unable to find parent lambda.");
8070 // All other current entries will be MEMBER_OF the combined entry
8071 // (except for PTR_AND_OBJ entries which do not have a placeholder value
8072 // 0xFFFF in the MEMBER_OF field).
8073 OpenMPOffloadMappingFlags MemberOfFlag = getMemberOfFlag(TgtIdx);
8074 setCorrectMemberOfFlag(Types[I], MemberOfFlag);
8075 }
8076 }
8077
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008078 /// Generate the base pointers, section pointers, sizes and map types
Samuel Antao86ace552016-04-27 22:40:57 +00008079 /// associated to a given capture.
8080 void generateInfoForCapture(const CapturedStmt::Capture *Cap,
Samuel Antao6890b092016-07-28 14:25:09 +00008081 llvm::Value *Arg,
Samuel Antaocc10b852016-07-28 14:23:26 +00008082 MapBaseValuesArrayTy &BasePointers,
Samuel Antao86ace552016-04-27 22:40:57 +00008083 MapValuesArrayTy &Pointers,
Alexey Bataevb3638132018-07-19 16:34:13 +00008084 MapValuesArrayTy &Sizes, MapFlagsArrayTy &Types,
8085 StructRangeInfoTy &PartialStruct) const {
Samuel Antao86ace552016-04-27 22:40:57 +00008086 assert(!Cap->capturesVariableArrayType() &&
8087 "Not expecting to generate map info for a variable array type!");
8088
Samuel Antao6890b092016-07-28 14:25:09 +00008089 // We need to know when we generating information for the first component
Alexey Bataevb3638132018-07-19 16:34:13 +00008090 const ValueDecl *VD = Cap->capturesThis()
8091 ? nullptr
8092 : Cap->getCapturedVar()->getCanonicalDecl();
Samuel Antao86ace552016-04-27 22:40:57 +00008093
Samuel Antao6890b092016-07-28 14:25:09 +00008094 // If this declaration appears in a is_device_ptr clause we just have to
8095 // pass the pointer by value. If it is a reference to a declaration, we just
Alexey Bataevb3638132018-07-19 16:34:13 +00008096 // pass its value.
8097 if (DevPointersMap.count(VD)) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008098 BasePointers.emplace_back(Arg, VD);
Samuel Antao6890b092016-07-28 14:25:09 +00008099 Pointers.push_back(Arg);
8100 Sizes.push_back(CGF.getTypeSize(CGF.getContext().VoidPtrTy));
George Rokos065755d2017-11-07 18:27:04 +00008101 Types.push_back(OMP_MAP_LITERAL | OMP_MAP_TARGET_PARAM);
Samuel Antao6890b092016-07-28 14:25:09 +00008102 return;
8103 }
8104
Alexey Bataeve82445f2018-09-20 13:54:02 +00008105 using MapData =
8106 std::tuple<OMPClauseMappableExprCommon::MappableExprComponentListRef,
Kelvin Lief579432018-12-18 22:18:41 +00008107 OpenMPMapClauseKind, ArrayRef<OpenMPMapModifierKind>, bool>;
Alexey Bataeve82445f2018-09-20 13:54:02 +00008108 SmallVector<MapData, 4> DeclComponentLists;
Paul Robinson78fb1322016-08-01 22:12:46 +00008109 // FIXME: MSVC 2013 seems to require this-> to find member CurDir.
Alexey Bataeve82445f2018-09-20 13:54:02 +00008110 for (const auto *C : this->CurDir.getClausesOfKind<OMPMapClause>()) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008111 for (const auto &L : C->decl_component_lists(VD)) {
Samuel Antao86ace552016-04-27 22:40:57 +00008112 assert(L.first == VD &&
8113 "We got information for the wrong declaration??");
8114 assert(!L.second.empty() &&
8115 "Not expecting declaration with no component lists.");
Alexey Bataeve82445f2018-09-20 13:54:02 +00008116 DeclComponentLists.emplace_back(L.second, C->getMapType(),
Kelvin Lief579432018-12-18 22:18:41 +00008117 C->getMapTypeModifiers(),
Alexey Bataeve82445f2018-09-20 13:54:02 +00008118 C->isImplicit());
Samuel Antao86ace552016-04-27 22:40:57 +00008119 }
Alexey Bataeve82445f2018-09-20 13:54:02 +00008120 }
8121
8122 // Find overlapping elements (including the offset from the base element).
8123 llvm::SmallDenseMap<
8124 const MapData *,
8125 llvm::SmallVector<
8126 OMPClauseMappableExprCommon::MappableExprComponentListRef, 4>,
8127 4>
8128 OverlappedData;
8129 size_t Count = 0;
8130 for (const MapData &L : DeclComponentLists) {
8131 OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
8132 OpenMPMapClauseKind MapType;
Kelvin Lief579432018-12-18 22:18:41 +00008133 ArrayRef<OpenMPMapModifierKind> MapModifiers;
Alexey Bataeve82445f2018-09-20 13:54:02 +00008134 bool IsImplicit;
Kelvin Lief579432018-12-18 22:18:41 +00008135 std::tie(Components, MapType, MapModifiers, IsImplicit) = L;
Alexey Bataeve82445f2018-09-20 13:54:02 +00008136 ++Count;
8137 for (const MapData &L1 : makeArrayRef(DeclComponentLists).slice(Count)) {
8138 OMPClauseMappableExprCommon::MappableExprComponentListRef Components1;
Kelvin Lief579432018-12-18 22:18:41 +00008139 std::tie(Components1, MapType, MapModifiers, IsImplicit) = L1;
Alexey Bataeve82445f2018-09-20 13:54:02 +00008140 auto CI = Components.rbegin();
8141 auto CE = Components.rend();
8142 auto SI = Components1.rbegin();
8143 auto SE = Components1.rend();
8144 for (; CI != CE && SI != SE; ++CI, ++SI) {
8145 if (CI->getAssociatedExpression()->getStmtClass() !=
8146 SI->getAssociatedExpression()->getStmtClass())
8147 break;
8148 // Are we dealing with different variables/fields?
8149 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
8150 break;
8151 }
8152 // Found overlapping if, at least for one component, reached the head of
8153 // the components list.
8154 if (CI == CE || SI == SE) {
8155 assert((CI != CE || SI != SE) &&
8156 "Unexpected full match of the mapping components.");
8157 const MapData &BaseData = CI == CE ? L : L1;
8158 OMPClauseMappableExprCommon::MappableExprComponentListRef SubData =
8159 SI == SE ? Components : Components1;
Alexey Bataeve82445f2018-09-20 13:54:02 +00008160 auto &OverlappedElements = OverlappedData.FindAndConstruct(&BaseData);
8161 OverlappedElements.getSecond().push_back(SubData);
8162 }
8163 }
8164 }
8165 // Sort the overlapped elements for each item.
8166 llvm::SmallVector<const FieldDecl *, 4> Layout;
8167 if (!OverlappedData.empty()) {
8168 if (const auto *CRD =
8169 VD->getType().getCanonicalType()->getAsCXXRecordDecl())
8170 getPlainLayout(CRD, Layout, /*AsBase=*/false);
8171 else {
8172 const auto *RD = VD->getType().getCanonicalType()->getAsRecordDecl();
8173 Layout.append(RD->field_begin(), RD->field_end());
8174 }
8175 }
8176 for (auto &Pair : OverlappedData) {
8177 llvm::sort(
8178 Pair.getSecond(),
8179 [&Layout](
8180 OMPClauseMappableExprCommon::MappableExprComponentListRef First,
8181 OMPClauseMappableExprCommon::MappableExprComponentListRef
8182 Second) {
8183 auto CI = First.rbegin();
8184 auto CE = First.rend();
8185 auto SI = Second.rbegin();
8186 auto SE = Second.rend();
8187 for (; CI != CE && SI != SE; ++CI, ++SI) {
8188 if (CI->getAssociatedExpression()->getStmtClass() !=
8189 SI->getAssociatedExpression()->getStmtClass())
8190 break;
8191 // Are we dealing with different variables/fields?
8192 if (CI->getAssociatedDeclaration() !=
8193 SI->getAssociatedDeclaration())
8194 break;
8195 }
Richard Trieu5061e832018-09-21 21:20:33 +00008196
8197 // Lists contain the same elements.
8198 if (CI == CE && SI == SE)
8199 return false;
8200
8201 // List with less elements is less than list with more elements.
8202 if (CI == CE || SI == SE)
8203 return CI == CE;
8204
Alexey Bataeve82445f2018-09-20 13:54:02 +00008205 const auto *FD1 = cast<FieldDecl>(CI->getAssociatedDeclaration());
8206 const auto *FD2 = cast<FieldDecl>(SI->getAssociatedDeclaration());
8207 if (FD1->getParent() == FD2->getParent())
8208 return FD1->getFieldIndex() < FD2->getFieldIndex();
8209 const auto It =
8210 llvm::find_if(Layout, [FD1, FD2](const FieldDecl *FD) {
8211 return FD == FD1 || FD == FD2;
8212 });
8213 return *It == FD1;
8214 });
8215 }
8216
8217 // Associated with a capture, because the mapping flags depend on it.
8218 // Go through all of the elements with the overlapped elements.
8219 for (const auto &Pair : OverlappedData) {
8220 const MapData &L = *Pair.getFirst();
8221 OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
8222 OpenMPMapClauseKind MapType;
Kelvin Lief579432018-12-18 22:18:41 +00008223 ArrayRef<OpenMPMapModifierKind> MapModifiers;
Alexey Bataeve82445f2018-09-20 13:54:02 +00008224 bool IsImplicit;
Kelvin Lief579432018-12-18 22:18:41 +00008225 std::tie(Components, MapType, MapModifiers, IsImplicit) = L;
Alexey Bataeve82445f2018-09-20 13:54:02 +00008226 ArrayRef<OMPClauseMappableExprCommon::MappableExprComponentListRef>
8227 OverlappedComponents = Pair.getSecond();
8228 bool IsFirstComponentList = true;
Kelvin Lief579432018-12-18 22:18:41 +00008229 generateInfoForComponentList(MapType, MapModifiers, Components,
Alexey Bataeve82445f2018-09-20 13:54:02 +00008230 BasePointers, Pointers, Sizes, Types,
8231 PartialStruct, IsFirstComponentList,
8232 IsImplicit, OverlappedComponents);
8233 }
8234 // Go through other elements without overlapped elements.
8235 bool IsFirstComponentList = OverlappedData.empty();
8236 for (const MapData &L : DeclComponentLists) {
8237 OMPClauseMappableExprCommon::MappableExprComponentListRef Components;
8238 OpenMPMapClauseKind MapType;
Kelvin Lief579432018-12-18 22:18:41 +00008239 ArrayRef<OpenMPMapModifierKind> MapModifiers;
Alexey Bataeve82445f2018-09-20 13:54:02 +00008240 bool IsImplicit;
Kelvin Lief579432018-12-18 22:18:41 +00008241 std::tie(Components, MapType, MapModifiers, IsImplicit) = L;
Alexey Bataeve82445f2018-09-20 13:54:02 +00008242 auto It = OverlappedData.find(&L);
8243 if (It == OverlappedData.end())
Kelvin Lief579432018-12-18 22:18:41 +00008244 generateInfoForComponentList(MapType, MapModifiers, Components,
Alexey Bataeve82445f2018-09-20 13:54:02 +00008245 BasePointers, Pointers, Sizes, Types,
8246 PartialStruct, IsFirstComponentList,
8247 IsImplicit);
8248 IsFirstComponentList = false;
8249 }
Alexey Bataevb3638132018-07-19 16:34:13 +00008250 }
Samuel Antao86ace552016-04-27 22:40:57 +00008251
Alexey Bataevb3638132018-07-19 16:34:13 +00008252 /// Generate the base pointers, section pointers, sizes and map types
8253 /// associated with the declare target link variables.
8254 void generateInfoForDeclareTargetLink(MapBaseValuesArrayTy &BasePointers,
8255 MapValuesArrayTy &Pointers,
8256 MapValuesArrayTy &Sizes,
8257 MapFlagsArrayTy &Types) const {
8258 // Map other list items in the map clause which are not captured variables
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +00008259 // but "declare target link" global variables.
Alexey Bataevb3638132018-07-19 16:34:13 +00008260 for (const auto *C : this->CurDir.getClausesOfKind<OMPMapClause>()) {
8261 for (const auto &L : C->component_lists()) {
8262 if (!L.first)
8263 continue;
8264 const auto *VD = dyn_cast<VarDecl>(L.first);
8265 if (!VD)
8266 continue;
8267 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
Alexey Bataev97b72212018-08-14 18:31:20 +00008268 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
Alexey Bataevb3638132018-07-19 16:34:13 +00008269 if (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)
8270 continue;
8271 StructRangeInfoTy PartialStruct;
8272 generateInfoForComponentList(
Kelvin Lief579432018-12-18 22:18:41 +00008273 C->getMapType(), C->getMapTypeModifiers(), L.second, BasePointers,
Alexey Bataevb3638132018-07-19 16:34:13 +00008274 Pointers, Sizes, Types, PartialStruct,
8275 /*IsFirstComponentList=*/true, C->isImplicit());
8276 assert(!PartialStruct.Base.isValid() &&
8277 "No partial structs for declare target link expected.");
8278 }
8279 }
Samuel Antao86ace552016-04-27 22:40:57 +00008280 }
Samuel Antaod486f842016-05-26 16:53:38 +00008281
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008282 /// Generate the default map information for a given capture \a CI,
Samuel Antaod486f842016-05-26 16:53:38 +00008283 /// record field declaration \a RI and captured value \a CV.
Samuel Antaocc10b852016-07-28 14:23:26 +00008284 void generateDefaultMapInfo(const CapturedStmt::Capture &CI,
8285 const FieldDecl &RI, llvm::Value *CV,
8286 MapBaseValuesArrayTy &CurBasePointers,
8287 MapValuesArrayTy &CurPointers,
8288 MapValuesArrayTy &CurSizes,
Alexey Bataevb3638132018-07-19 16:34:13 +00008289 MapFlagsArrayTy &CurMapTypes) const {
Samuel Antaod486f842016-05-26 16:53:38 +00008290 // Do the default mapping.
8291 if (CI.capturesThis()) {
8292 CurBasePointers.push_back(CV);
8293 CurPointers.push_back(CV);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008294 const auto *PtrTy = cast<PointerType>(RI.getType().getTypePtr());
Samuel Antaod486f842016-05-26 16:53:38 +00008295 CurSizes.push_back(CGF.getTypeSize(PtrTy->getPointeeType()));
8296 // Default map type.
Samuel Antaocc10b852016-07-28 14:23:26 +00008297 CurMapTypes.push_back(OMP_MAP_TO | OMP_MAP_FROM);
Samuel Antaod486f842016-05-26 16:53:38 +00008298 } else if (CI.capturesVariableByCopy()) {
Samuel Antao6d004262016-06-16 18:39:34 +00008299 CurBasePointers.push_back(CV);
8300 CurPointers.push_back(CV);
Samuel Antaod486f842016-05-26 16:53:38 +00008301 if (!RI.getType()->isAnyPointerType()) {
Samuel Antao6d004262016-06-16 18:39:34 +00008302 // We have to signal to the runtime captures passed by value that are
8303 // not pointers.
George Rokos065755d2017-11-07 18:27:04 +00008304 CurMapTypes.push_back(OMP_MAP_LITERAL);
Samuel Antaod486f842016-05-26 16:53:38 +00008305 CurSizes.push_back(CGF.getTypeSize(RI.getType()));
8306 } else {
8307 // Pointers are implicitly mapped with a zero size and no flags
8308 // (other than first map that is added for all implicit maps).
Alexey Bataevb3638132018-07-19 16:34:13 +00008309 CurMapTypes.push_back(OMP_MAP_NONE);
Samuel Antaod486f842016-05-26 16:53:38 +00008310 CurSizes.push_back(llvm::Constant::getNullValue(CGF.SizeTy));
8311 }
8312 } else {
8313 assert(CI.capturesVariable() && "Expected captured reference.");
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008314 const auto *PtrTy = cast<ReferenceType>(RI.getType().getTypePtr());
Samuel Antaod486f842016-05-26 16:53:38 +00008315 QualType ElementType = PtrTy->getPointeeType();
8316 CurSizes.push_back(CGF.getTypeSize(ElementType));
8317 // The default map type for a scalar/complex type is 'to' because by
8318 // default the value doesn't have to be retrieved. For an aggregate
8319 // type, the default is 'tofrom'.
Alexey Bataevb3638132018-07-19 16:34:13 +00008320 CurMapTypes.push_back(getMapModifiersForPrivateClauses(CI));
Alexey Bataev1af5bd52019-03-05 17:47:18 +00008321 const VarDecl *VD = CI.getCapturedVar();
8322 if (FirstPrivateDecls.count(VD) &&
8323 VD->getType().isConstant(CGF.getContext())) {
8324 llvm::Constant *Addr =
8325 CGF.CGM.getOpenMPRuntime().registerTargetFirstprivateCopy(CGF, VD);
8326 // Copy the value of the original variable to the new global copy.
8327 CGF.Builder.CreateMemCpy(
8328 CGF.MakeNaturalAlignAddrLValue(Addr, ElementType).getAddress(),
8329 Address(CV, CGF.getContext().getTypeAlignInChars(ElementType)),
Alexey Bataevc2b831f2019-04-02 16:03:40 +00008330 CurSizes.back(), /*isVolatile=*/false);
Alexey Bataev1af5bd52019-03-05 17:47:18 +00008331 // Use new global variable as the base pointers.
8332 CurBasePointers.push_back(Addr);
8333 CurPointers.push_back(Addr);
8334 } else {
8335 CurBasePointers.push_back(CV);
Alexey Bataevc2b831f2019-04-02 16:03:40 +00008336 if (FirstPrivateDecls.count(VD) && ElementType->isAnyPointerType()) {
8337 Address PtrAddr = CGF.EmitLoadOfReference(CGF.MakeAddrLValue(
8338 CV, ElementType, CGF.getContext().getDeclAlign(VD),
8339 AlignmentSource::Decl));
8340 CurPointers.push_back(PtrAddr.getPointer());
8341 } else {
8342 CurPointers.push_back(CV);
8343 }
Alexey Bataev1af5bd52019-03-05 17:47:18 +00008344 }
Samuel Antaod486f842016-05-26 16:53:38 +00008345 }
George Rokos065755d2017-11-07 18:27:04 +00008346 // Every default map produces a single argument which is a target parameter.
8347 CurMapTypes.back() |= OMP_MAP_TARGET_PARAM;
Alexey Bataevb3638132018-07-19 16:34:13 +00008348
8349 // Add flag stating this is an implicit map.
8350 CurMapTypes.back() |= OMP_MAP_IMPLICIT;
Samuel Antaod486f842016-05-26 16:53:38 +00008351 }
Samuel Antao86ace552016-04-27 22:40:57 +00008352};
Samuel Antaodf158d52016-04-27 22:58:19 +00008353
8354enum OpenMPOffloadingReservedDeviceIDs {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008355 /// Device ID if the device was not defined, runtime should get it
Samuel Antaodf158d52016-04-27 22:58:19 +00008356 /// from environment variables in the spec.
8357 OMP_DEVICEID_UNDEF = -1,
8358};
8359} // anonymous namespace
8360
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008361/// Emit the arrays used to pass the captures and map information to the
Samuel Antaodf158d52016-04-27 22:58:19 +00008362/// offloading runtime library. If there is no map or capture information,
8363/// return nullptr by reference.
8364static void
Samuel Antaocc10b852016-07-28 14:23:26 +00008365emitOffloadingArrays(CodeGenFunction &CGF,
8366 MappableExprsHandler::MapBaseValuesArrayTy &BasePointers,
Samuel Antaodf158d52016-04-27 22:58:19 +00008367 MappableExprsHandler::MapValuesArrayTy &Pointers,
8368 MappableExprsHandler::MapValuesArrayTy &Sizes,
Samuel Antaocc10b852016-07-28 14:23:26 +00008369 MappableExprsHandler::MapFlagsArrayTy &MapTypes,
8370 CGOpenMPRuntime::TargetDataInfo &Info) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008371 CodeGenModule &CGM = CGF.CGM;
8372 ASTContext &Ctx = CGF.getContext();
Samuel Antaodf158d52016-04-27 22:58:19 +00008373
Samuel Antaocc10b852016-07-28 14:23:26 +00008374 // Reset the array information.
8375 Info.clearArrayInfo();
8376 Info.NumberOfPtrs = BasePointers.size();
Samuel Antaodf158d52016-04-27 22:58:19 +00008377
Samuel Antaocc10b852016-07-28 14:23:26 +00008378 if (Info.NumberOfPtrs) {
Samuel Antaodf158d52016-04-27 22:58:19 +00008379 // Detect if we have any capture size requiring runtime evaluation of the
8380 // size so that a constant array could be eventually used.
8381 bool hasRuntimeEvaluationCaptureSize = false;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008382 for (llvm::Value *S : Sizes)
Samuel Antaodf158d52016-04-27 22:58:19 +00008383 if (!isa<llvm::Constant>(S)) {
8384 hasRuntimeEvaluationCaptureSize = true;
8385 break;
8386 }
8387
Samuel Antaocc10b852016-07-28 14:23:26 +00008388 llvm::APInt PointerNumAP(32, Info.NumberOfPtrs, /*isSigned=*/true);
Samuel Antaodf158d52016-04-27 22:58:19 +00008389 QualType PointerArrayType =
8390 Ctx.getConstantArrayType(Ctx.VoidPtrTy, PointerNumAP, ArrayType::Normal,
8391 /*IndexTypeQuals=*/0);
8392
Samuel Antaocc10b852016-07-28 14:23:26 +00008393 Info.BasePointersArray =
Samuel Antaodf158d52016-04-27 22:58:19 +00008394 CGF.CreateMemTemp(PointerArrayType, ".offload_baseptrs").getPointer();
Samuel Antaocc10b852016-07-28 14:23:26 +00008395 Info.PointersArray =
Samuel Antaodf158d52016-04-27 22:58:19 +00008396 CGF.CreateMemTemp(PointerArrayType, ".offload_ptrs").getPointer();
8397
8398 // If we don't have any VLA types or other types that require runtime
8399 // evaluation, we can use a constant array for the map sizes, otherwise we
8400 // need to fill up the arrays as we do for the pointers.
8401 if (hasRuntimeEvaluationCaptureSize) {
8402 QualType SizeArrayType = Ctx.getConstantArrayType(
8403 Ctx.getSizeType(), PointerNumAP, ArrayType::Normal,
8404 /*IndexTypeQuals=*/0);
Samuel Antaocc10b852016-07-28 14:23:26 +00008405 Info.SizesArray =
Samuel Antaodf158d52016-04-27 22:58:19 +00008406 CGF.CreateMemTemp(SizeArrayType, ".offload_sizes").getPointer();
8407 } else {
8408 // We expect all the sizes to be constant, so we collect them to create
8409 // a constant array.
8410 SmallVector<llvm::Constant *, 16> ConstSizes;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008411 for (llvm::Value *S : Sizes)
Samuel Antaodf158d52016-04-27 22:58:19 +00008412 ConstSizes.push_back(cast<llvm::Constant>(S));
8413
8414 auto *SizesArrayInit = llvm::ConstantArray::get(
8415 llvm::ArrayType::get(CGM.SizeTy, ConstSizes.size()), ConstSizes);
Alexey Bataev18fa2322018-05-02 14:20:50 +00008416 std::string Name = CGM.getOpenMPRuntime().getName({"offload_sizes"});
Samuel Antaodf158d52016-04-27 22:58:19 +00008417 auto *SizesArrayGbl = new llvm::GlobalVariable(
8418 CGM.getModule(), SizesArrayInit->getType(),
8419 /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage,
Alexey Bataev18fa2322018-05-02 14:20:50 +00008420 SizesArrayInit, Name);
Peter Collingbournebcf909d2016-06-14 21:02:05 +00008421 SizesArrayGbl->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
Samuel Antaocc10b852016-07-28 14:23:26 +00008422 Info.SizesArray = SizesArrayGbl;
Samuel Antaodf158d52016-04-27 22:58:19 +00008423 }
8424
8425 // The map types are always constant so we don't need to generate code to
8426 // fill arrays. Instead, we create an array constant.
Alexey Bataevb3638132018-07-19 16:34:13 +00008427 SmallVector<uint64_t, 4> Mapping(MapTypes.size(), 0);
8428 llvm::copy(MapTypes, Mapping.begin());
Samuel Antaodf158d52016-04-27 22:58:19 +00008429 llvm::Constant *MapTypesArrayInit =
Alexey Bataevb3638132018-07-19 16:34:13 +00008430 llvm::ConstantDataArray::get(CGF.Builder.getContext(), Mapping);
Alexey Bataev18fa2322018-05-02 14:20:50 +00008431 std::string MaptypesName =
8432 CGM.getOpenMPRuntime().getName({"offload_maptypes"});
Samuel Antaodf158d52016-04-27 22:58:19 +00008433 auto *MapTypesArrayGbl = new llvm::GlobalVariable(
8434 CGM.getModule(), MapTypesArrayInit->getType(),
8435 /*isConstant=*/true, llvm::GlobalValue::PrivateLinkage,
Alexey Bataev18fa2322018-05-02 14:20:50 +00008436 MapTypesArrayInit, MaptypesName);
Peter Collingbournebcf909d2016-06-14 21:02:05 +00008437 MapTypesArrayGbl->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
Samuel Antaocc10b852016-07-28 14:23:26 +00008438 Info.MapTypesArray = MapTypesArrayGbl;
Samuel Antaodf158d52016-04-27 22:58:19 +00008439
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008440 for (unsigned I = 0; I < Info.NumberOfPtrs; ++I) {
8441 llvm::Value *BPVal = *BasePointers[I];
Samuel Antaodf158d52016-04-27 22:58:19 +00008442 llvm::Value *BP = CGF.Builder.CreateConstInBoundsGEP2_32(
Samuel Antaocc10b852016-07-28 14:23:26 +00008443 llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008444 Info.BasePointersArray, 0, I);
Alexey Bataev1fdfdf72017-06-29 16:43:05 +00008445 BP = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
8446 BP, BPVal->getType()->getPointerTo(/*AddrSpace=*/0));
Samuel Antaodf158d52016-04-27 22:58:19 +00008447 Address BPAddr(BP, Ctx.getTypeAlignInChars(Ctx.VoidPtrTy));
8448 CGF.Builder.CreateStore(BPVal, BPAddr);
8449
Samuel Antaocc10b852016-07-28 14:23:26 +00008450 if (Info.requiresDevicePointerInfo())
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008451 if (const ValueDecl *DevVD = BasePointers[I].getDevicePtrDecl())
Alexey Bataev43a919f2018-04-13 17:48:43 +00008452 Info.CaptureDeviceAddrMap.try_emplace(DevVD, BPAddr);
Samuel Antaocc10b852016-07-28 14:23:26 +00008453
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008454 llvm::Value *PVal = Pointers[I];
Samuel Antaodf158d52016-04-27 22:58:19 +00008455 llvm::Value *P = CGF.Builder.CreateConstInBoundsGEP2_32(
Samuel Antaocc10b852016-07-28 14:23:26 +00008456 llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008457 Info.PointersArray, 0, I);
Alexey Bataev1fdfdf72017-06-29 16:43:05 +00008458 P = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
8459 P, PVal->getType()->getPointerTo(/*AddrSpace=*/0));
Samuel Antaodf158d52016-04-27 22:58:19 +00008460 Address PAddr(P, Ctx.getTypeAlignInChars(Ctx.VoidPtrTy));
8461 CGF.Builder.CreateStore(PVal, PAddr);
8462
8463 if (hasRuntimeEvaluationCaptureSize) {
8464 llvm::Value *S = CGF.Builder.CreateConstInBoundsGEP2_32(
Samuel Antaocc10b852016-07-28 14:23:26 +00008465 llvm::ArrayType::get(CGM.SizeTy, Info.NumberOfPtrs),
8466 Info.SizesArray,
Samuel Antaodf158d52016-04-27 22:58:19 +00008467 /*Idx0=*/0,
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008468 /*Idx1=*/I);
Samuel Antaodf158d52016-04-27 22:58:19 +00008469 Address SAddr(S, Ctx.getTypeAlignInChars(Ctx.getSizeType()));
8470 CGF.Builder.CreateStore(
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008471 CGF.Builder.CreateIntCast(Sizes[I], CGM.SizeTy, /*isSigned=*/true),
Samuel Antaodf158d52016-04-27 22:58:19 +00008472 SAddr);
8473 }
8474 }
8475 }
8476}
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00008477/// Emit the arguments to be passed to the runtime library based on the
Samuel Antaodf158d52016-04-27 22:58:19 +00008478/// arrays of pointers, sizes and map types.
8479static void emitOffloadingArraysArgument(
8480 CodeGenFunction &CGF, llvm::Value *&BasePointersArrayArg,
8481 llvm::Value *&PointersArrayArg, llvm::Value *&SizesArrayArg,
Samuel Antaocc10b852016-07-28 14:23:26 +00008482 llvm::Value *&MapTypesArrayArg, CGOpenMPRuntime::TargetDataInfo &Info) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008483 CodeGenModule &CGM = CGF.CGM;
Samuel Antaocc10b852016-07-28 14:23:26 +00008484 if (Info.NumberOfPtrs) {
Samuel Antaodf158d52016-04-27 22:58:19 +00008485 BasePointersArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(
Samuel Antaocc10b852016-07-28 14:23:26 +00008486 llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),
8487 Info.BasePointersArray,
Samuel Antaodf158d52016-04-27 22:58:19 +00008488 /*Idx0=*/0, /*Idx1=*/0);
8489 PointersArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(
Samuel Antaocc10b852016-07-28 14:23:26 +00008490 llvm::ArrayType::get(CGM.VoidPtrTy, Info.NumberOfPtrs),
8491 Info.PointersArray,
Samuel Antaodf158d52016-04-27 22:58:19 +00008492 /*Idx0=*/0,
8493 /*Idx1=*/0);
8494 SizesArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(
Samuel Antaocc10b852016-07-28 14:23:26 +00008495 llvm::ArrayType::get(CGM.SizeTy, Info.NumberOfPtrs), Info.SizesArray,
Samuel Antaodf158d52016-04-27 22:58:19 +00008496 /*Idx0=*/0, /*Idx1=*/0);
8497 MapTypesArrayArg = CGF.Builder.CreateConstInBoundsGEP2_32(
George Rokos63bc9d62017-11-21 18:25:12 +00008498 llvm::ArrayType::get(CGM.Int64Ty, Info.NumberOfPtrs),
Samuel Antaocc10b852016-07-28 14:23:26 +00008499 Info.MapTypesArray,
Samuel Antaodf158d52016-04-27 22:58:19 +00008500 /*Idx0=*/0,
8501 /*Idx1=*/0);
8502 } else {
8503 BasePointersArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy);
8504 PointersArrayArg = llvm::ConstantPointerNull::get(CGM.VoidPtrPtrTy);
8505 SizesArrayArg = llvm::ConstantPointerNull::get(CGM.SizeTy->getPointerTo());
8506 MapTypesArrayArg =
George Rokos63bc9d62017-11-21 18:25:12 +00008507 llvm::ConstantPointerNull::get(CGM.Int64Ty->getPointerTo());
Samuel Antaodf158d52016-04-27 22:58:19 +00008508 }
Samuel Antao86ace552016-04-27 22:40:57 +00008509}
8510
Alexey Bataev7bb33532019-01-07 21:30:43 +00008511/// Check for inner distribute directive.
8512static const OMPExecutableDirective *
8513getNestedDistributeDirective(ASTContext &Ctx, const OMPExecutableDirective &D) {
8514 const auto *CS = D.getInnermostCapturedStmt();
8515 const auto *Body =
8516 CS->getCapturedStmt()->IgnoreContainers(/*IgnoreCaptured=*/true);
Alexey Bataev5c427362019-04-10 19:11:33 +00008517 const Stmt *ChildStmt =
8518 CGOpenMPSIMDRuntime::getSingleCompoundChild(Ctx, Body);
Alexey Bataev7bb33532019-01-07 21:30:43 +00008519
Alexey Bataev5c427362019-04-10 19:11:33 +00008520 if (const auto *NestedDir =
8521 dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
Alexey Bataev7bb33532019-01-07 21:30:43 +00008522 OpenMPDirectiveKind DKind = NestedDir->getDirectiveKind();
8523 switch (D.getDirectiveKind()) {
8524 case OMPD_target:
8525 if (isOpenMPDistributeDirective(DKind))
8526 return NestedDir;
8527 if (DKind == OMPD_teams) {
8528 Body = NestedDir->getInnermostCapturedStmt()->IgnoreContainers(
8529 /*IgnoreCaptured=*/true);
8530 if (!Body)
8531 return nullptr;
Alexey Bataev5c427362019-04-10 19:11:33 +00008532 ChildStmt = CGOpenMPSIMDRuntime::getSingleCompoundChild(Ctx, Body);
8533 if (const auto *NND =
8534 dyn_cast_or_null<OMPExecutableDirective>(ChildStmt)) {
Alexey Bataev7bb33532019-01-07 21:30:43 +00008535 DKind = NND->getDirectiveKind();
8536 if (isOpenMPDistributeDirective(DKind))
8537 return NND;
8538 }
8539 }
8540 return nullptr;
8541 case OMPD_target_teams:
8542 if (isOpenMPDistributeDirective(DKind))
8543 return NestedDir;
8544 return nullptr;
8545 case OMPD_target_parallel:
8546 case OMPD_target_simd:
8547 case OMPD_target_parallel_for:
8548 case OMPD_target_parallel_for_simd:
8549 return nullptr;
8550 case OMPD_target_teams_distribute:
8551 case OMPD_target_teams_distribute_simd:
8552 case OMPD_target_teams_distribute_parallel_for:
8553 case OMPD_target_teams_distribute_parallel_for_simd:
8554 case OMPD_parallel:
8555 case OMPD_for:
8556 case OMPD_parallel_for:
8557 case OMPD_parallel_sections:
8558 case OMPD_for_simd:
8559 case OMPD_parallel_for_simd:
8560 case OMPD_cancel:
8561 case OMPD_cancellation_point:
8562 case OMPD_ordered:
8563 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00008564 case OMPD_allocate:
Alexey Bataev7bb33532019-01-07 21:30:43 +00008565 case OMPD_task:
8566 case OMPD_simd:
8567 case OMPD_sections:
8568 case OMPD_section:
8569 case OMPD_single:
8570 case OMPD_master:
8571 case OMPD_critical:
8572 case OMPD_taskyield:
8573 case OMPD_barrier:
8574 case OMPD_taskwait:
8575 case OMPD_taskgroup:
8576 case OMPD_atomic:
8577 case OMPD_flush:
8578 case OMPD_teams:
8579 case OMPD_target_data:
8580 case OMPD_target_exit_data:
8581 case OMPD_target_enter_data:
8582 case OMPD_distribute:
8583 case OMPD_distribute_simd:
8584 case OMPD_distribute_parallel_for:
8585 case OMPD_distribute_parallel_for_simd:
8586 case OMPD_teams_distribute:
8587 case OMPD_teams_distribute_simd:
8588 case OMPD_teams_distribute_parallel_for:
8589 case OMPD_teams_distribute_parallel_for_simd:
8590 case OMPD_target_update:
8591 case OMPD_declare_simd:
8592 case OMPD_declare_target:
8593 case OMPD_end_declare_target:
8594 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +00008595 case OMPD_declare_mapper:
Alexey Bataev7bb33532019-01-07 21:30:43 +00008596 case OMPD_taskloop:
8597 case OMPD_taskloop_simd:
8598 case OMPD_requires:
8599 case OMPD_unknown:
8600 llvm_unreachable("Unexpected directive.");
8601 }
8602 }
8603
8604 return nullptr;
8605}
8606
8607void CGOpenMPRuntime::emitTargetNumIterationsCall(
8608 CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *Device,
8609 const llvm::function_ref<llvm::Value *(
8610 CodeGenFunction &CGF, const OMPLoopDirective &D)> &SizeEmitter) {
8611 OpenMPDirectiveKind Kind = D.getDirectiveKind();
8612 const OMPExecutableDirective *TD = &D;
8613 // Get nested teams distribute kind directive, if any.
8614 if (!isOpenMPDistributeDirective(Kind) || !isOpenMPTeamsDirective(Kind))
8615 TD = getNestedDistributeDirective(CGM.getContext(), D);
8616 if (!TD)
8617 return;
8618 const auto *LD = cast<OMPLoopDirective>(TD);
8619 auto &&CodeGen = [LD, &Device, &SizeEmitter, this](CodeGenFunction &CGF,
8620 PrePostActionTy &) {
8621 llvm::Value *NumIterations = SizeEmitter(CGF, *LD);
8622
8623 // Emit device ID if any.
8624 llvm::Value *DeviceID;
8625 if (Device)
8626 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
8627 CGF.Int64Ty, /*isSigned=*/true);
8628 else
8629 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
8630
8631 llvm::Value *Args[] = {DeviceID, NumIterations};
8632 CGF.EmitRuntimeCall(
8633 createRuntimeFunction(OMPRTL__kmpc_push_target_tripcount), Args);
8634 };
8635 emitInlinedDirective(CGF, OMPD_unknown, CodeGen);
8636}
8637
Samuel Antaobed3c462015-10-02 16:14:20 +00008638void CGOpenMPRuntime::emitTargetCall(CodeGenFunction &CGF,
8639 const OMPExecutableDirective &D,
James Y Knight9871db02019-02-05 16:42:33 +00008640 llvm::Function *OutlinedFn,
Samuel Antaoee8fb302016-01-06 13:42:12 +00008641 llvm::Value *OutlinedFnID,
Alexey Bataev8451efa2018-01-15 19:06:12 +00008642 const Expr *IfCond, const Expr *Device) {
Alexey Bataev8ef31412015-12-18 07:58:25 +00008643 if (!CGF.HaveInsertPoint())
8644 return;
Samuel Antaobed3c462015-10-02 16:14:20 +00008645
Samuel Antaoee8fb302016-01-06 13:42:12 +00008646 assert(OutlinedFn && "Invalid outlined function!");
8647
Alexey Bataev8451efa2018-01-15 19:06:12 +00008648 const bool RequiresOuterTask = D.hasClausesOfKind<OMPDependClause>();
8649 llvm::SmallVector<llvm::Value *, 16> CapturedVars;
Alexey Bataev475a7442018-01-12 19:39:11 +00008650 const CapturedStmt &CS = *D.getCapturedStmt(OMPD_target);
Alexey Bataev8451efa2018-01-15 19:06:12 +00008651 auto &&ArgsCodegen = [&CS, &CapturedVars](CodeGenFunction &CGF,
8652 PrePostActionTy &) {
8653 CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
8654 };
8655 emitInlinedDirective(CGF, OMPD_unknown, ArgsCodegen);
Samuel Antao86ace552016-04-27 22:40:57 +00008656
Alexey Bataev8451efa2018-01-15 19:06:12 +00008657 CodeGenFunction::OMPTargetDataInfo InputInfo;
8658 llvm::Value *MapTypesArray = nullptr;
Samuel Antaobed3c462015-10-02 16:14:20 +00008659 // Fill up the pointer arrays and transfer execution to the device.
Alexey Bataev8451efa2018-01-15 19:06:12 +00008660 auto &&ThenGen = [this, Device, OutlinedFn, OutlinedFnID, &D, &InputInfo,
8661 &MapTypesArray, &CS, RequiresOuterTask,
8662 &CapturedVars](CodeGenFunction &CGF, PrePostActionTy &) {
Samuel Antaobed3c462015-10-02 16:14:20 +00008663 // On top of the arrays that were filled up, the target offloading call
8664 // takes as arguments the device id as well as the host pointer. The host
8665 // pointer is used by the runtime library to identify the current target
8666 // region, so it only has to be unique and not necessarily point to
8667 // anything. It could be the pointer to the outlined function that
8668 // implements the target region, but we aren't using that so that the
8669 // compiler doesn't need to keep that, and could therefore inline the host
8670 // function if proven worthwhile during optimization.
8671
Samuel Antaoee8fb302016-01-06 13:42:12 +00008672 // From this point on, we need to have an ID of the target region defined.
8673 assert(OutlinedFnID && "Invalid outlined function ID!");
Samuel Antaobed3c462015-10-02 16:14:20 +00008674
8675 // Emit device ID if any.
8676 llvm::Value *DeviceID;
George Rokos63bc9d62017-11-21 18:25:12 +00008677 if (Device) {
Samuel Antaobed3c462015-10-02 16:14:20 +00008678 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
George Rokos63bc9d62017-11-21 18:25:12 +00008679 CGF.Int64Ty, /*isSigned=*/true);
8680 } else {
8681 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
8682 }
Samuel Antaobed3c462015-10-02 16:14:20 +00008683
Samuel Antaodf158d52016-04-27 22:58:19 +00008684 // Emit the number of elements in the offloading arrays.
Alexey Bataev8451efa2018-01-15 19:06:12 +00008685 llvm::Value *PointerNum =
8686 CGF.Builder.getInt32(InputInfo.NumberOfTargetItems);
Samuel Antaodf158d52016-04-27 22:58:19 +00008687
Samuel Antaob68e2db2016-03-03 16:20:23 +00008688 // Return value of the runtime offloading call.
8689 llvm::Value *Return;
8690
Alexey Bataev5c427362019-04-10 19:11:33 +00008691 llvm::Value *NumTeams = emitNumTeamsForTargetDirective(CGF, D);
8692 llvm::Value *NumThreads = emitNumThreadsForTargetDirective(CGF, D);
Samuel Antaob68e2db2016-03-03 16:20:23 +00008693
Alexey Bataeva9f77c62017-12-13 21:04:20 +00008694 bool HasNowait = D.hasClausesOfKind<OMPNowaitClause>();
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00008695 // The target region is an outlined function launched by the runtime
8696 // via calls __tgt_target() or __tgt_target_teams().
8697 //
8698 // __tgt_target() launches a target region with one team and one thread,
8699 // executing a serial region. This master thread may in turn launch
8700 // more threads within its team upon encountering a parallel region,
8701 // however, no additional teams can be launched on the device.
8702 //
8703 // __tgt_target_teams() launches a target region with one or more teams,
8704 // each with one or more threads. This call is required for target
8705 // constructs such as:
8706 // 'target teams'
8707 // 'target' / 'teams'
8708 // 'target teams distribute parallel for'
8709 // 'target parallel'
8710 // and so on.
8711 //
8712 // Note that on the host and CPU targets, the runtime implementation of
8713 // these calls simply call the outlined function without forking threads.
8714 // The outlined functions themselves have runtime calls to
8715 // __kmpc_fork_teams() and __kmpc_fork() for this purpose, codegen'd by
8716 // the compiler in emitTeamsCall() and emitParallelCall().
8717 //
8718 // In contrast, on the NVPTX target, the implementation of
8719 // __tgt_target_teams() launches a GPU kernel with the requested number
8720 // of teams and threads so no additional calls to the runtime are required.
Samuel Antaob68e2db2016-03-03 16:20:23 +00008721 if (NumTeams) {
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00008722 // If we have NumTeams defined this means that we have an enclosed teams
8723 // region. Therefore we also expect to have NumThreads defined. These two
8724 // values should be defined in the presence of a teams directive,
8725 // regardless of having any clauses associated. If the user is using teams
8726 // but no clauses, these two values will be the default that should be
8727 // passed to the runtime library - a 32-bit integer with the value zero.
8728 assert(NumThreads && "Thread limit expression should be available along "
8729 "with number of teams.");
Alexey Bataev8451efa2018-01-15 19:06:12 +00008730 llvm::Value *OffloadingArgs[] = {DeviceID,
8731 OutlinedFnID,
8732 PointerNum,
8733 InputInfo.BasePointersArray.getPointer(),
8734 InputInfo.PointersArray.getPointer(),
8735 InputInfo.SizesArray.getPointer(),
8736 MapTypesArray,
8737 NumTeams,
8738 NumThreads};
Samuel Antaob68e2db2016-03-03 16:20:23 +00008739 Return = CGF.EmitRuntimeCall(
Alexey Bataev8451efa2018-01-15 19:06:12 +00008740 createRuntimeFunction(HasNowait ? OMPRTL__tgt_target_teams_nowait
8741 : OMPRTL__tgt_target_teams),
Alexey Bataeva9f77c62017-12-13 21:04:20 +00008742 OffloadingArgs);
Samuel Antaob68e2db2016-03-03 16:20:23 +00008743 } else {
Alexey Bataev8451efa2018-01-15 19:06:12 +00008744 llvm::Value *OffloadingArgs[] = {DeviceID,
8745 OutlinedFnID,
8746 PointerNum,
8747 InputInfo.BasePointersArray.getPointer(),
8748 InputInfo.PointersArray.getPointer(),
8749 InputInfo.SizesArray.getPointer(),
8750 MapTypesArray};
Alexey Bataeva9f77c62017-12-13 21:04:20 +00008751 Return = CGF.EmitRuntimeCall(
Alexey Bataev8451efa2018-01-15 19:06:12 +00008752 createRuntimeFunction(HasNowait ? OMPRTL__tgt_target_nowait
8753 : OMPRTL__tgt_target),
Alexey Bataeva9f77c62017-12-13 21:04:20 +00008754 OffloadingArgs);
Samuel Antaob68e2db2016-03-03 16:20:23 +00008755 }
Samuel Antaobed3c462015-10-02 16:14:20 +00008756
Alexey Bataev2a007e02017-10-02 14:20:58 +00008757 // Check the error code and execute the host version if required.
8758 llvm::BasicBlock *OffloadFailedBlock =
8759 CGF.createBasicBlock("omp_offload.failed");
8760 llvm::BasicBlock *OffloadContBlock =
8761 CGF.createBasicBlock("omp_offload.cont");
8762 llvm::Value *Failed = CGF.Builder.CreateIsNotNull(Return);
8763 CGF.Builder.CreateCondBr(Failed, OffloadFailedBlock, OffloadContBlock);
8764
8765 CGF.EmitBlock(OffloadFailedBlock);
Alexey Bataev8451efa2018-01-15 19:06:12 +00008766 if (RequiresOuterTask) {
8767 CapturedVars.clear();
8768 CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
8769 }
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008770 emitOutlinedFunctionCall(CGF, D.getBeginLoc(), OutlinedFn, CapturedVars);
Alexey Bataev2a007e02017-10-02 14:20:58 +00008771 CGF.EmitBranch(OffloadContBlock);
8772
8773 CGF.EmitBlock(OffloadContBlock, /*IsFinished=*/true);
Samuel Antaobed3c462015-10-02 16:14:20 +00008774 };
8775
Samuel Antaoee8fb302016-01-06 13:42:12 +00008776 // Notify that the host version must be executed.
Alexey Bataev8451efa2018-01-15 19:06:12 +00008777 auto &&ElseGen = [this, &D, OutlinedFn, &CS, &CapturedVars,
8778 RequiresOuterTask](CodeGenFunction &CGF,
8779 PrePostActionTy &) {
8780 if (RequiresOuterTask) {
8781 CapturedVars.clear();
8782 CGF.GenerateOpenMPCapturedVars(CS, CapturedVars);
8783 }
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008784 emitOutlinedFunctionCall(CGF, D.getBeginLoc(), OutlinedFn, CapturedVars);
Alexey Bataev8451efa2018-01-15 19:06:12 +00008785 };
8786
8787 auto &&TargetThenGen = [this, &ThenGen, &D, &InputInfo, &MapTypesArray,
8788 &CapturedVars, RequiresOuterTask,
8789 &CS](CodeGenFunction &CGF, PrePostActionTy &) {
8790 // Fill up the arrays with all the captured variables.
8791 MappableExprsHandler::MapBaseValuesArrayTy BasePointers;
8792 MappableExprsHandler::MapValuesArrayTy Pointers;
8793 MappableExprsHandler::MapValuesArrayTy Sizes;
8794 MappableExprsHandler::MapFlagsArrayTy MapTypes;
8795
Alexey Bataev8451efa2018-01-15 19:06:12 +00008796 // Get mappable expression information.
8797 MappableExprsHandler MEHandler(D, CGF);
Alexey Bataev969dbc02018-11-08 15:47:39 +00008798 llvm::DenseMap<llvm::Value *, llvm::Value *> LambdaPointers;
Alexey Bataev8451efa2018-01-15 19:06:12 +00008799
8800 auto RI = CS.getCapturedRecordDecl()->field_begin();
8801 auto CV = CapturedVars.begin();
8802 for (CapturedStmt::const_capture_iterator CI = CS.capture_begin(),
8803 CE = CS.capture_end();
8804 CI != CE; ++CI, ++RI, ++CV) {
Alexey Bataevb3638132018-07-19 16:34:13 +00008805 MappableExprsHandler::MapBaseValuesArrayTy CurBasePointers;
8806 MappableExprsHandler::MapValuesArrayTy CurPointers;
8807 MappableExprsHandler::MapValuesArrayTy CurSizes;
8808 MappableExprsHandler::MapFlagsArrayTy CurMapTypes;
8809 MappableExprsHandler::StructRangeInfoTy PartialStruct;
Alexey Bataev8451efa2018-01-15 19:06:12 +00008810
8811 // VLA sizes are passed to the outlined region by copy and do not have map
8812 // information associated.
8813 if (CI->capturesVariableArrayType()) {
8814 CurBasePointers.push_back(*CV);
8815 CurPointers.push_back(*CV);
8816 CurSizes.push_back(CGF.getTypeSize(RI->getType()));
8817 // Copy to the device as an argument. No need to retrieve it.
8818 CurMapTypes.push_back(MappableExprsHandler::OMP_MAP_LITERAL |
8819 MappableExprsHandler::OMP_MAP_TARGET_PARAM);
8820 } else {
8821 // If we have any information in the map clause, we use it, otherwise we
8822 // just do a default mapping.
8823 MEHandler.generateInfoForCapture(CI, *CV, CurBasePointers, CurPointers,
Alexey Bataevb3638132018-07-19 16:34:13 +00008824 CurSizes, CurMapTypes, PartialStruct);
Alexey Bataev8451efa2018-01-15 19:06:12 +00008825 if (CurBasePointers.empty())
8826 MEHandler.generateDefaultMapInfo(*CI, **RI, *CV, CurBasePointers,
8827 CurPointers, CurSizes, CurMapTypes);
Alexey Bataev60705422018-10-30 15:50:12 +00008828 // Generate correct mapping for variables captured by reference in
8829 // lambdas.
8830 if (CI->capturesVariable())
Alexey Bataev969dbc02018-11-08 15:47:39 +00008831 MEHandler.generateInfoForLambdaCaptures(
8832 CI->getCapturedVar(), *CV, CurBasePointers, CurPointers, CurSizes,
8833 CurMapTypes, LambdaPointers);
Alexey Bataev8451efa2018-01-15 19:06:12 +00008834 }
8835 // We expect to have at least an element of information for this capture.
8836 assert(!CurBasePointers.empty() &&
8837 "Non-existing map pointer for capture!");
8838 assert(CurBasePointers.size() == CurPointers.size() &&
8839 CurBasePointers.size() == CurSizes.size() &&
8840 CurBasePointers.size() == CurMapTypes.size() &&
8841 "Inconsistent map information sizes!");
8842
Alexey Bataevb3638132018-07-19 16:34:13 +00008843 // If there is an entry in PartialStruct it means we have a struct with
8844 // individual members mapped. Emit an extra combined entry.
8845 if (PartialStruct.Base.isValid())
8846 MEHandler.emitCombinedEntry(BasePointers, Pointers, Sizes, MapTypes,
8847 CurMapTypes, PartialStruct);
8848
Alexey Bataev8451efa2018-01-15 19:06:12 +00008849 // We need to append the results of this capture to what we already have.
8850 BasePointers.append(CurBasePointers.begin(), CurBasePointers.end());
8851 Pointers.append(CurPointers.begin(), CurPointers.end());
8852 Sizes.append(CurSizes.begin(), CurSizes.end());
8853 MapTypes.append(CurMapTypes.begin(), CurMapTypes.end());
8854 }
Alexey Bataev60705422018-10-30 15:50:12 +00008855 // Adjust MEMBER_OF flags for the lambdas captures.
Alexey Bataev969dbc02018-11-08 15:47:39 +00008856 MEHandler.adjustMemberOfForLambdaCaptures(LambdaPointers, BasePointers,
8857 Pointers, MapTypes);
Alexey Bataev92327c52018-03-26 16:40:55 +00008858 // Map other list items in the map clause which are not captured variables
8859 // but "declare target link" global variables.
Alexey Bataevb3638132018-07-19 16:34:13 +00008860 MEHandler.generateInfoForDeclareTargetLink(BasePointers, Pointers, Sizes,
8861 MapTypes);
Alexey Bataev8451efa2018-01-15 19:06:12 +00008862
8863 TargetDataInfo Info;
8864 // Fill up the arrays and create the arguments.
8865 emitOffloadingArrays(CGF, BasePointers, Pointers, Sizes, MapTypes, Info);
8866 emitOffloadingArraysArgument(CGF, Info.BasePointersArray,
8867 Info.PointersArray, Info.SizesArray,
8868 Info.MapTypesArray, Info);
8869 InputInfo.NumberOfTargetItems = Info.NumberOfPtrs;
8870 InputInfo.BasePointersArray =
8871 Address(Info.BasePointersArray, CGM.getPointerAlign());
8872 InputInfo.PointersArray =
8873 Address(Info.PointersArray, CGM.getPointerAlign());
8874 InputInfo.SizesArray = Address(Info.SizesArray, CGM.getPointerAlign());
8875 MapTypesArray = Info.MapTypesArray;
8876 if (RequiresOuterTask)
8877 CGF.EmitOMPTargetTaskBasedDirective(D, ThenGen, InputInfo);
8878 else
8879 emitInlinedDirective(CGF, D.getDirectiveKind(), ThenGen);
8880 };
8881
8882 auto &&TargetElseGen = [this, &ElseGen, &D, RequiresOuterTask](
8883 CodeGenFunction &CGF, PrePostActionTy &) {
8884 if (RequiresOuterTask) {
8885 CodeGenFunction::OMPTargetDataInfo InputInfo;
8886 CGF.EmitOMPTargetTaskBasedDirective(D, ElseGen, InputInfo);
8887 } else {
8888 emitInlinedDirective(CGF, D.getDirectiveKind(), ElseGen);
8889 }
Samuel Antaoee8fb302016-01-06 13:42:12 +00008890 };
8891
8892 // If we have a target function ID it means that we need to support
8893 // offloading, otherwise, just execute on the host. We need to execute on host
8894 // regardless of the conditional in the if clause if, e.g., the user do not
8895 // specify target triples.
8896 if (OutlinedFnID) {
Alexey Bataev8451efa2018-01-15 19:06:12 +00008897 if (IfCond) {
8898 emitOMPIfClause(CGF, IfCond, TargetThenGen, TargetElseGen);
8899 } else {
8900 RegionCodeGenTy ThenRCG(TargetThenGen);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00008901 ThenRCG(CGF);
Alexey Bataevf539faa2016-03-28 12:58:34 +00008902 }
8903 } else {
Alexey Bataev8451efa2018-01-15 19:06:12 +00008904 RegionCodeGenTy ElseRCG(TargetElseGen);
Alexey Bataev14fa1c62016-03-29 05:34:15 +00008905 ElseRCG(CGF);
Alexey Bataevf539faa2016-03-28 12:58:34 +00008906 }
Samuel Antaobed3c462015-10-02 16:14:20 +00008907}
Samuel Antaoee8fb302016-01-06 13:42:12 +00008908
8909void CGOpenMPRuntime::scanForTargetRegionsFunctions(const Stmt *S,
8910 StringRef ParentName) {
8911 if (!S)
8912 return;
8913
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00008914 // Codegen OMP target directives that offload compute to the device.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008915 bool RequiresDeviceCodegen =
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00008916 isa<OMPExecutableDirective>(S) &&
8917 isOpenMPTargetExecutionDirective(
8918 cast<OMPExecutableDirective>(S)->getDirectiveKind());
Samuel Antaoee8fb302016-01-06 13:42:12 +00008919
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008920 if (RequiresDeviceCodegen) {
8921 const auto &E = *cast<OMPExecutableDirective>(S);
Samuel Antaoee8fb302016-01-06 13:42:12 +00008922 unsigned DeviceID;
8923 unsigned FileID;
8924 unsigned Line;
Stephen Kellyf2ceec42018-08-09 21:08:08 +00008925 getTargetEntryUniqueInfo(CGM.getContext(), E.getBeginLoc(), DeviceID,
Samuel Antao2de62b02016-02-13 23:35:10 +00008926 FileID, Line);
Samuel Antaoee8fb302016-01-06 13:42:12 +00008927
8928 // Is this a target region that should not be emitted as an entry point? If
8929 // so just signal we are done with this target region.
Samuel Antao2de62b02016-02-13 23:35:10 +00008930 if (!OffloadEntriesInfoManager.hasTargetRegionEntryInfo(DeviceID, FileID,
8931 ParentName, Line))
Samuel Antaoee8fb302016-01-06 13:42:12 +00008932 return;
8933
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008934 switch (E.getDirectiveKind()) {
8935 case OMPD_target:
8936 CodeGenFunction::EmitOMPTargetDeviceFunction(CGM, ParentName,
8937 cast<OMPTargetDirective>(E));
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00008938 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008939 case OMPD_target_parallel:
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00008940 CodeGenFunction::EmitOMPTargetParallelDeviceFunction(
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008941 CGM, ParentName, cast<OMPTargetParallelDirective>(E));
Arpith Chacko Jacob19b911c2017-01-18 18:18:53 +00008942 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008943 case OMPD_target_teams:
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00008944 CodeGenFunction::EmitOMPTargetTeamsDeviceFunction(
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008945 CGM, ParentName, cast<OMPTargetTeamsDirective>(E));
Arpith Chacko Jacob99a1e0e2017-01-25 02:18:43 +00008946 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008947 case OMPD_target_teams_distribute:
Alexey Bataevdfa430f2017-12-08 15:03:50 +00008948 CodeGenFunction::EmitOMPTargetTeamsDistributeDeviceFunction(
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008949 CGM, ParentName, cast<OMPTargetTeamsDistributeDirective>(E));
Alexey Bataevdfa430f2017-12-08 15:03:50 +00008950 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008951 case OMPD_target_teams_distribute_simd:
Alexey Bataevfbe17fb2017-12-13 19:45:06 +00008952 CodeGenFunction::EmitOMPTargetTeamsDistributeSimdDeviceFunction(
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008953 CGM, ParentName, cast<OMPTargetTeamsDistributeSimdDirective>(E));
Alexey Bataevfbe17fb2017-12-13 19:45:06 +00008954 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008955 case OMPD_target_parallel_for:
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00008956 CodeGenFunction::EmitOMPTargetParallelForDeviceFunction(
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008957 CGM, ParentName, cast<OMPTargetParallelForDirective>(E));
Alexey Bataevfb0ebec2017-11-08 20:16:14 +00008958 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008959 case OMPD_target_parallel_for_simd:
Alexey Bataev5d7edca2017-11-09 17:32:15 +00008960 CodeGenFunction::EmitOMPTargetParallelForSimdDeviceFunction(
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008961 CGM, ParentName, cast<OMPTargetParallelForSimdDirective>(E));
Alexey Bataev5d7edca2017-11-09 17:32:15 +00008962 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008963 case OMPD_target_simd:
Alexey Bataevf8365372017-11-17 17:57:25 +00008964 CodeGenFunction::EmitOMPTargetSimdDeviceFunction(
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008965 CGM, ParentName, cast<OMPTargetSimdDirective>(E));
Alexey Bataevf8365372017-11-17 17:57:25 +00008966 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008967 case OMPD_target_teams_distribute_parallel_for:
Carlo Bertolli52978c32018-01-03 21:12:44 +00008968 CodeGenFunction::EmitOMPTargetTeamsDistributeParallelForDeviceFunction(
8969 CGM, ParentName,
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008970 cast<OMPTargetTeamsDistributeParallelForDirective>(E));
Carlo Bertolli52978c32018-01-03 21:12:44 +00008971 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008972 case OMPD_target_teams_distribute_parallel_for_simd:
Alexey Bataev647dd842018-01-15 20:59:40 +00008973 CodeGenFunction::
8974 EmitOMPTargetTeamsDistributeParallelForSimdDeviceFunction(
8975 CGM, ParentName,
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008976 cast<OMPTargetTeamsDistributeParallelForSimdDirective>(E));
Alexey Bataev647dd842018-01-15 20:59:40 +00008977 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008978 case OMPD_parallel:
8979 case OMPD_for:
8980 case OMPD_parallel_for:
8981 case OMPD_parallel_sections:
8982 case OMPD_for_simd:
8983 case OMPD_parallel_for_simd:
8984 case OMPD_cancel:
8985 case OMPD_cancellation_point:
8986 case OMPD_ordered:
8987 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00008988 case OMPD_allocate:
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00008989 case OMPD_task:
8990 case OMPD_simd:
8991 case OMPD_sections:
8992 case OMPD_section:
8993 case OMPD_single:
8994 case OMPD_master:
8995 case OMPD_critical:
8996 case OMPD_taskyield:
8997 case OMPD_barrier:
8998 case OMPD_taskwait:
8999 case OMPD_taskgroup:
9000 case OMPD_atomic:
9001 case OMPD_flush:
9002 case OMPD_teams:
9003 case OMPD_target_data:
9004 case OMPD_target_exit_data:
9005 case OMPD_target_enter_data:
9006 case OMPD_distribute:
9007 case OMPD_distribute_simd:
9008 case OMPD_distribute_parallel_for:
9009 case OMPD_distribute_parallel_for_simd:
9010 case OMPD_teams_distribute:
9011 case OMPD_teams_distribute_simd:
9012 case OMPD_teams_distribute_parallel_for:
9013 case OMPD_teams_distribute_parallel_for_simd:
9014 case OMPD_target_update:
9015 case OMPD_declare_simd:
9016 case OMPD_declare_target:
9017 case OMPD_end_declare_target:
9018 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +00009019 case OMPD_declare_mapper:
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009020 case OMPD_taskloop:
9021 case OMPD_taskloop_simd:
Kelvin Li1408f912018-09-26 04:28:39 +00009022 case OMPD_requires:
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009023 case OMPD_unknown:
Arpith Chacko Jacob43a8b7b2017-01-16 15:26:02 +00009024 llvm_unreachable("Unknown target directive for OpenMP device codegen.");
9025 }
Samuel Antaoee8fb302016-01-06 13:42:12 +00009026 return;
9027 }
9028
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009029 if (const auto *E = dyn_cast<OMPExecutableDirective>(S)) {
Alexey Bataev475a7442018-01-12 19:39:11 +00009030 if (!E->hasAssociatedStmt() || !E->getAssociatedStmt())
Samuel Antaoee8fb302016-01-06 13:42:12 +00009031 return;
9032
9033 scanForTargetRegionsFunctions(
Alexey Bataev475a7442018-01-12 19:39:11 +00009034 E->getInnermostCapturedStmt()->getCapturedStmt(), ParentName);
Samuel Antaoee8fb302016-01-06 13:42:12 +00009035 return;
9036 }
9037
9038 // If this is a lambda function, look into its body.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009039 if (const auto *L = dyn_cast<LambdaExpr>(S))
Samuel Antaoee8fb302016-01-06 13:42:12 +00009040 S = L->getBody();
9041
9042 // Keep looking for target regions recursively.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009043 for (const Stmt *II : S->children())
Samuel Antaoee8fb302016-01-06 13:42:12 +00009044 scanForTargetRegionsFunctions(II, ParentName);
Samuel Antaoee8fb302016-01-06 13:42:12 +00009045}
9046
9047bool CGOpenMPRuntime::emitTargetFunctions(GlobalDecl GD) {
Samuel Antaoee8fb302016-01-06 13:42:12 +00009048 // If emitting code for the host, we do not process FD here. Instead we do
9049 // the normal code generation.
9050 if (!CGM.getLangOpts().OpenMPIsDevice)
9051 return false;
9052
Alexey Bataeve6aa4692018-09-13 16:54:05 +00009053 const ValueDecl *VD = cast<ValueDecl>(GD.getDecl());
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00009054 StringRef Name = CGM.getMangledName(GD);
9055 // Try to detect target regions in the function.
Alexey Bataeve6aa4692018-09-13 16:54:05 +00009056 if (const auto *FD = dyn_cast<FunctionDecl>(VD))
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00009057 scanForTargetRegionsFunctions(FD->getBody(), Name);
Samuel Antaoee8fb302016-01-06 13:42:12 +00009058
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00009059 // Do not to emit function if it is not marked as declare target.
Alexey Bataeve6aa4692018-09-13 16:54:05 +00009060 return !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) &&
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00009061 AlreadyEmittedTargetFunctions.count(Name) == 0;
Samuel Antaoee8fb302016-01-06 13:42:12 +00009062}
9063
9064bool CGOpenMPRuntime::emitTargetGlobalVariable(GlobalDecl GD) {
9065 if (!CGM.getLangOpts().OpenMPIsDevice)
9066 return false;
9067
9068 // Check if there are Ctors/Dtors in this declaration and look for target
9069 // regions in it. We use the complete variant to produce the kernel name
9070 // mangling.
9071 QualType RDTy = cast<VarDecl>(GD.getDecl())->getType();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009072 if (const auto *RD = RDTy->getBaseElementTypeUnsafe()->getAsCXXRecordDecl()) {
9073 for (const CXXConstructorDecl *Ctor : RD->ctors()) {
Samuel Antaoee8fb302016-01-06 13:42:12 +00009074 StringRef ParentName =
9075 CGM.getMangledName(GlobalDecl(Ctor, Ctor_Complete));
9076 scanForTargetRegionsFunctions(Ctor->getBody(), ParentName);
9077 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009078 if (const CXXDestructorDecl *Dtor = RD->getDestructor()) {
Samuel Antaoee8fb302016-01-06 13:42:12 +00009079 StringRef ParentName =
9080 CGM.getMangledName(GlobalDecl(Dtor, Dtor_Complete));
9081 scanForTargetRegionsFunctions(Dtor->getBody(), ParentName);
9082 }
9083 }
9084
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00009085 // Do not to emit variable if it is not marked as declare target.
Alexey Bataev92327c52018-03-26 16:40:55 +00009086 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
Alexey Bataev97b72212018-08-14 18:31:20 +00009087 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
9088 cast<VarDecl>(GD.getDecl()));
Alexey Bataevbf8fe712018-08-07 16:14:36 +00009089 if (!Res || *Res == OMPDeclareTargetDeclAttr::MT_Link) {
Alexey Bataevd01b7492018-08-15 19:45:12 +00009090 DeferredGlobalVariables.insert(cast<VarDecl>(GD.getDecl()));
Alexey Bataevbf8fe712018-08-07 16:14:36 +00009091 return true;
9092 }
9093 return false;
Samuel Antaoee8fb302016-01-06 13:42:12 +00009094}
9095
Alexey Bataev1af5bd52019-03-05 17:47:18 +00009096llvm::Constant *
9097CGOpenMPRuntime::registerTargetFirstprivateCopy(CodeGenFunction &CGF,
9098 const VarDecl *VD) {
9099 assert(VD->getType().isConstant(CGM.getContext()) &&
9100 "Expected constant variable.");
9101 StringRef VarName;
9102 llvm::Constant *Addr;
9103 llvm::GlobalValue::LinkageTypes Linkage;
9104 QualType Ty = VD->getType();
9105 SmallString<128> Buffer;
9106 {
9107 unsigned DeviceID;
9108 unsigned FileID;
9109 unsigned Line;
9110 getTargetEntryUniqueInfo(CGM.getContext(), VD->getLocation(), DeviceID,
9111 FileID, Line);
9112 llvm::raw_svector_ostream OS(Buffer);
9113 OS << "__omp_offloading_firstprivate_" << llvm::format("_%x", DeviceID)
9114 << llvm::format("_%x_", FileID) << VD->getName() << "_l" << Line;
9115 VarName = OS.str();
9116 }
9117 Linkage = llvm::GlobalValue::InternalLinkage;
9118 Addr =
9119 getOrCreateInternalVariable(CGM.getTypes().ConvertTypeForMem(Ty), VarName,
9120 getDefaultFirstprivateAddressSpace());
9121 cast<llvm::GlobalValue>(Addr)->setLinkage(Linkage);
9122 CharUnits VarSize = CGM.getContext().getTypeSizeInChars(Ty);
9123 CGM.addCompilerUsedGlobal(cast<llvm::GlobalValue>(Addr));
9124 OffloadEntriesInfoManager.registerDeviceGlobalVarEntryInfo(
9125 VarName, Addr, VarSize,
9126 OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryTo, Linkage);
9127 return Addr;
9128}
9129
Alexey Bataev03f270c2018-03-30 18:31:07 +00009130void CGOpenMPRuntime::registerTargetGlobalVariable(const VarDecl *VD,
9131 llvm::Constant *Addr) {
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00009132 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
9133 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
9134 if (!Res) {
9135 if (CGM.getLangOpts().OpenMPIsDevice) {
9136 // Register non-target variables being emitted in device code (debug info
9137 // may cause this).
9138 StringRef VarName = CGM.getMangledName(VD);
9139 EmittedNonTargetVariables.try_emplace(VarName, Addr);
Alexey Bataev03f270c2018-03-30 18:31:07 +00009140 }
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00009141 return;
Alexey Bataev03f270c2018-03-30 18:31:07 +00009142 }
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00009143 // Register declare target variables.
9144 OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryKind Flags;
9145 StringRef VarName;
9146 CharUnits VarSize;
9147 llvm::GlobalValue::LinkageTypes Linkage;
9148 switch (*Res) {
9149 case OMPDeclareTargetDeclAttr::MT_To:
9150 Flags = OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryTo;
9151 VarName = CGM.getMangledName(VD);
9152 if (VD->hasDefinition(CGM.getContext()) != VarDecl::DeclarationOnly) {
9153 VarSize = CGM.getContext().getTypeSizeInChars(VD->getType());
9154 assert(!VarSize.isZero() && "Expected non-zero size of the variable");
9155 } else {
9156 VarSize = CharUnits::Zero();
9157 }
9158 Linkage = CGM.getLLVMLinkageVarDefinition(VD, /*IsConstant=*/false);
9159 // Temp solution to prevent optimizations of the internal variables.
9160 if (CGM.getLangOpts().OpenMPIsDevice && !VD->isExternallyVisible()) {
9161 std::string RefName = getName({VarName, "ref"});
9162 if (!CGM.GetGlobalValue(RefName)) {
9163 llvm::Constant *AddrRef =
9164 getOrCreateInternalVariable(Addr->getType(), RefName);
9165 auto *GVAddrRef = cast<llvm::GlobalVariable>(AddrRef);
9166 GVAddrRef->setConstant(/*Val=*/true);
9167 GVAddrRef->setLinkage(llvm::GlobalValue::InternalLinkage);
9168 GVAddrRef->setInitializer(Addr);
9169 CGM.addCompilerUsedGlobal(GVAddrRef);
9170 }
9171 }
9172 break;
9173 case OMPDeclareTargetDeclAttr::MT_Link:
9174 Flags = OffloadEntriesInfoManagerTy::OMPTargetGlobalVarEntryLink;
9175 if (CGM.getLangOpts().OpenMPIsDevice) {
9176 VarName = Addr->getName();
9177 Addr = nullptr;
9178 } else {
9179 VarName = getAddrOfDeclareTargetLink(VD).getName();
9180 Addr = cast<llvm::Constant>(getAddrOfDeclareTargetLink(VD).getPointer());
9181 }
9182 VarSize = CGM.getPointerSize();
9183 Linkage = llvm::GlobalValue::WeakAnyLinkage;
9184 break;
9185 }
9186 OffloadEntriesInfoManager.registerDeviceGlobalVarEntryInfo(
9187 VarName, Addr, VarSize, Flags, Linkage);
Alexey Bataev03f270c2018-03-30 18:31:07 +00009188}
9189
Samuel Antaoee8fb302016-01-06 13:42:12 +00009190bool CGOpenMPRuntime::emitTargetGlobal(GlobalDecl GD) {
Alexey Bataeve6aa4692018-09-13 16:54:05 +00009191 if (isa<FunctionDecl>(GD.getDecl()) ||
9192 isa<OMPDeclareReductionDecl>(GD.getDecl()))
Samuel Antaoee8fb302016-01-06 13:42:12 +00009193 return emitTargetFunctions(GD);
9194
9195 return emitTargetGlobalVariable(GD);
9196}
9197
Alexey Bataevbf8fe712018-08-07 16:14:36 +00009198void CGOpenMPRuntime::emitDeferredTargetDecls() const {
9199 for (const VarDecl *VD : DeferredGlobalVariables) {
9200 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
Alexey Bataev97b72212018-08-14 18:31:20 +00009201 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
Alexey Bataevd01b7492018-08-15 19:45:12 +00009202 if (!Res)
9203 continue;
9204 if (*Res == OMPDeclareTargetDeclAttr::MT_To) {
Alexey Bataevbf8fe712018-08-07 16:14:36 +00009205 CGM.EmitGlobal(VD);
Alexey Bataevd01b7492018-08-15 19:45:12 +00009206 } else {
9207 assert(*Res == OMPDeclareTargetDeclAttr::MT_Link &&
9208 "Expected to or link clauses.");
9209 (void)CGM.getOpenMPRuntime().getAddrOfDeclareTargetLink(VD);
Alexey Bataevbf8fe712018-08-07 16:14:36 +00009210 }
9211 }
9212}
9213
Alexey Bataev60705422018-10-30 15:50:12 +00009214void CGOpenMPRuntime::adjustTargetSpecificDataForLambdas(
9215 CodeGenFunction &CGF, const OMPExecutableDirective &D) const {
9216 assert(isOpenMPTargetExecutionDirective(D.getDirectiveKind()) &&
9217 " Expected target-based directive.");
9218}
9219
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +00009220void CGOpenMPRuntime::checkArchForUnifiedAddressing(
9221 const OMPRequiresDecl *D) {
9222 for (const OMPClause *Clause : D->clauselists()) {
9223 if (Clause->getClauseKind() == OMPC_unified_shared_memory) {
9224 HasRequiresUnifiedSharedMemory = true;
9225 break;
9226 }
9227 }
9228}
9229
Alexey Bataevc5687252019-03-21 19:35:27 +00009230bool CGOpenMPRuntime::hasAllocateAttributeForGlobalVar(const VarDecl *VD,
9231 LangAS &AS) {
9232 if (!VD || !VD->hasAttr<OMPAllocateDeclAttr>())
9233 return false;
9234 const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
9235 switch(A->getAllocatorType()) {
9236 case OMPAllocateDeclAttr::OMPDefaultMemAlloc:
9237 // Not supported, fallback to the default mem space.
9238 case OMPAllocateDeclAttr::OMPLargeCapMemAlloc:
9239 case OMPAllocateDeclAttr::OMPCGroupMemAlloc:
9240 case OMPAllocateDeclAttr::OMPHighBWMemAlloc:
9241 case OMPAllocateDeclAttr::OMPLowLatMemAlloc:
9242 case OMPAllocateDeclAttr::OMPThreadMemAlloc:
9243 case OMPAllocateDeclAttr::OMPConstMemAlloc:
9244 case OMPAllocateDeclAttr::OMPPTeamMemAlloc:
9245 AS = LangAS::Default;
9246 return true;
9247 case OMPAllocateDeclAttr::OMPUserDefinedMemAlloc:
9248 llvm_unreachable("Expected predefined allocator for the variables with the "
9249 "static storage.");
9250 }
9251 return false;
9252}
9253
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00009254CGOpenMPRuntime::DisableAutoDeclareTargetRAII::DisableAutoDeclareTargetRAII(
9255 CodeGenModule &CGM)
9256 : CGM(CGM) {
9257 if (CGM.getLangOpts().OpenMPIsDevice) {
9258 SavedShouldMarkAsGlobal = CGM.getOpenMPRuntime().ShouldMarkAsGlobal;
9259 CGM.getOpenMPRuntime().ShouldMarkAsGlobal = false;
9260 }
9261}
9262
9263CGOpenMPRuntime::DisableAutoDeclareTargetRAII::~DisableAutoDeclareTargetRAII() {
9264 if (CGM.getLangOpts().OpenMPIsDevice)
9265 CGM.getOpenMPRuntime().ShouldMarkAsGlobal = SavedShouldMarkAsGlobal;
9266}
9267
Alexey Bataev6d944102018-05-02 15:45:28 +00009268bool CGOpenMPRuntime::markAsGlobalTarget(GlobalDecl GD) {
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00009269 if (!CGM.getLangOpts().OpenMPIsDevice || !ShouldMarkAsGlobal)
9270 return true;
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00009271
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00009272 StringRef Name = CGM.getMangledName(GD);
Alexey Bataev6d944102018-05-02 15:45:28 +00009273 const auto *D = cast<FunctionDecl>(GD.getDecl());
Alexey Bataev34f8a702018-03-28 14:28:54 +00009274 // Do not to emit function if it is marked as declare target as it was already
9275 // emitted.
Alexey Bataev97b72212018-08-14 18:31:20 +00009276 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(D)) {
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00009277 if (D->hasBody() && AlreadyEmittedTargetFunctions.count(Name) == 0) {
9278 if (auto *F = dyn_cast_or_null<llvm::Function>(CGM.GetGlobalValue(Name)))
Alexey Bataev34f8a702018-03-28 14:28:54 +00009279 return !F->isDeclaration();
9280 return false;
9281 }
9282 return true;
9283 }
9284
Alexey Bataev2a6f3f52018-11-07 19:11:14 +00009285 return !AlreadyEmittedTargetFunctions.insert(Name).second;
Alexey Bataev4f4bf7c2018-03-15 15:47:20 +00009286}
9287
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +00009288llvm::Function *CGOpenMPRuntime::emitRequiresDirectiveRegFun() {
9289 // If we don't have entries or if we are emitting code for the device, we
9290 // don't need to do anything.
9291 if (CGM.getLangOpts().OMPTargetTriples.empty() ||
9292 CGM.getLangOpts().OpenMPSimd || CGM.getLangOpts().OpenMPIsDevice ||
9293 (OffloadEntriesInfoManager.empty() &&
9294 !HasEmittedDeclareTargetRegion &&
9295 !HasEmittedTargetRegion))
9296 return nullptr;
9297
9298 // Create and register the function that handles the requires directives.
9299 ASTContext &C = CGM.getContext();
9300
9301 llvm::Function *RequiresRegFn;
9302 {
9303 CodeGenFunction CGF(CGM);
9304 const auto &FI = CGM.getTypes().arrangeNullaryFunction();
9305 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
9306 std::string ReqName = getName({"omp_offloading", "requires_reg"});
9307 RequiresRegFn = CGM.CreateGlobalInitOrDestructFunction(FTy, ReqName, FI);
9308 CGF.StartFunction(GlobalDecl(), C.VoidTy, RequiresRegFn, FI, {});
9309 OpenMPOffloadingRequiresDirFlags Flags = OMP_REQ_NONE;
9310 // TODO: check for other requires clauses.
9311 // The requires directive takes effect only when a target region is
9312 // present in the compilation unit. Otherwise it is ignored and not
9313 // passed to the runtime. This avoids the runtime from throwing an error
9314 // for mismatching requires clauses across compilation units that don't
9315 // contain at least 1 target region.
9316 assert((HasEmittedTargetRegion ||
9317 HasEmittedDeclareTargetRegion ||
9318 !OffloadEntriesInfoManager.empty()) &&
9319 "Target or declare target region expected.");
9320 if (HasRequiresUnifiedSharedMemory)
9321 Flags = OMP_REQ_UNIFIED_SHARED_MEMORY;
9322 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__tgt_register_requires),
9323 llvm::ConstantInt::get(CGM.Int64Ty, Flags));
9324 CGF.FinishFunction();
9325 }
9326 return RequiresRegFn;
9327}
9328
Samuel Antaoee8fb302016-01-06 13:42:12 +00009329llvm::Function *CGOpenMPRuntime::emitRegistrationFunction() {
9330 // If we have offloading in the current module, we need to emit the entries
9331 // now and register the offloading descriptor.
9332 createOffloadEntriesAndInfoMetadata();
9333
9334 // Create and register the offloading binary descriptors. This is the main
9335 // entity that captures all the information about offloading in the current
9336 // compilation unit.
9337 return createOffloadingBinaryDescriptorRegistration();
9338}
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00009339
9340void CGOpenMPRuntime::emitTeamsCall(CodeGenFunction &CGF,
9341 const OMPExecutableDirective &D,
9342 SourceLocation Loc,
James Y Knight9871db02019-02-05 16:42:33 +00009343 llvm::Function *OutlinedFn,
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00009344 ArrayRef<llvm::Value *> CapturedVars) {
9345 if (!CGF.HaveInsertPoint())
9346 return;
9347
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009348 llvm::Value *RTLoc = emitUpdateLocation(CGF, Loc);
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00009349 CodeGenFunction::RunCleanupsScope Scope(CGF);
9350
9351 // Build call __kmpc_fork_teams(loc, n, microtask, var1, .., varn);
9352 llvm::Value *Args[] = {
9353 RTLoc,
9354 CGF.Builder.getInt32(CapturedVars.size()), // Number of captured vars
9355 CGF.Builder.CreateBitCast(OutlinedFn, getKmpc_MicroPointerTy())};
9356 llvm::SmallVector<llvm::Value *, 16> RealArgs;
9357 RealArgs.append(std::begin(Args), std::end(Args));
9358 RealArgs.append(CapturedVars.begin(), CapturedVars.end());
9359
James Y Knight9871db02019-02-05 16:42:33 +00009360 llvm::FunctionCallee RTLFn = createRuntimeFunction(OMPRTL__kmpc_fork_teams);
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00009361 CGF.EmitRuntimeCall(RTLFn, RealArgs);
9362}
9363
9364void CGOpenMPRuntime::emitNumTeamsClause(CodeGenFunction &CGF,
Carlo Bertollic6872252016-04-04 15:55:02 +00009365 const Expr *NumTeams,
9366 const Expr *ThreadLimit,
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00009367 SourceLocation Loc) {
9368 if (!CGF.HaveInsertPoint())
9369 return;
9370
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009371 llvm::Value *RTLoc = emitUpdateLocation(CGF, Loc);
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00009372
Carlo Bertollic6872252016-04-04 15:55:02 +00009373 llvm::Value *NumTeamsVal =
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009374 NumTeams
Carlo Bertollic6872252016-04-04 15:55:02 +00009375 ? CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(NumTeams),
9376 CGF.CGM.Int32Ty, /* isSigned = */ true)
9377 : CGF.Builder.getInt32(0);
9378
9379 llvm::Value *ThreadLimitVal =
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009380 ThreadLimit
Carlo Bertollic6872252016-04-04 15:55:02 +00009381 ? CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(ThreadLimit),
9382 CGF.CGM.Int32Ty, /* isSigned = */ true)
9383 : CGF.Builder.getInt32(0);
9384
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00009385 // Build call __kmpc_push_num_teamss(&loc, global_tid, num_teams, thread_limit)
Carlo Bertollic6872252016-04-04 15:55:02 +00009386 llvm::Value *PushNumTeamsArgs[] = {RTLoc, getThreadID(CGF, Loc), NumTeamsVal,
9387 ThreadLimitVal};
Carlo Bertolli430d8ec2016-03-03 20:34:23 +00009388 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_push_num_teams),
9389 PushNumTeamsArgs);
9390}
Samuel Antaodf158d52016-04-27 22:58:19 +00009391
Samuel Antaocc10b852016-07-28 14:23:26 +00009392void CGOpenMPRuntime::emitTargetDataCalls(
9393 CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond,
9394 const Expr *Device, const RegionCodeGenTy &CodeGen, TargetDataInfo &Info) {
Samuel Antaodf158d52016-04-27 22:58:19 +00009395 if (!CGF.HaveInsertPoint())
9396 return;
9397
Samuel Antaocc10b852016-07-28 14:23:26 +00009398 // Action used to replace the default codegen action and turn privatization
9399 // off.
9400 PrePostActionTy NoPrivAction;
Samuel Antaodf158d52016-04-27 22:58:19 +00009401
9402 // Generate the code for the opening of the data environment. Capture all the
9403 // arguments of the runtime call by reference because they are used in the
9404 // closing of the region.
Alexey Bataevd2202ca2017-12-27 17:58:32 +00009405 auto &&BeginThenGen = [this, &D, Device, &Info,
9406 &CodeGen](CodeGenFunction &CGF, PrePostActionTy &) {
Samuel Antaodf158d52016-04-27 22:58:19 +00009407 // Fill up the arrays with all the mapped variables.
Samuel Antaocc10b852016-07-28 14:23:26 +00009408 MappableExprsHandler::MapBaseValuesArrayTy BasePointers;
Samuel Antaodf158d52016-04-27 22:58:19 +00009409 MappableExprsHandler::MapValuesArrayTy Pointers;
9410 MappableExprsHandler::MapValuesArrayTy Sizes;
9411 MappableExprsHandler::MapFlagsArrayTy MapTypes;
9412
9413 // Get map clause information.
9414 MappableExprsHandler MCHandler(D, CGF);
9415 MCHandler.generateAllInfo(BasePointers, Pointers, Sizes, MapTypes);
Samuel Antaodf158d52016-04-27 22:58:19 +00009416
9417 // Fill up the arrays and create the arguments.
Samuel Antaocc10b852016-07-28 14:23:26 +00009418 emitOffloadingArrays(CGF, BasePointers, Pointers, Sizes, MapTypes, Info);
Samuel Antaodf158d52016-04-27 22:58:19 +00009419
9420 llvm::Value *BasePointersArrayArg = nullptr;
9421 llvm::Value *PointersArrayArg = nullptr;
9422 llvm::Value *SizesArrayArg = nullptr;
9423 llvm::Value *MapTypesArrayArg = nullptr;
9424 emitOffloadingArraysArgument(CGF, BasePointersArrayArg, PointersArrayArg,
Samuel Antaocc10b852016-07-28 14:23:26 +00009425 SizesArrayArg, MapTypesArrayArg, Info);
Samuel Antaodf158d52016-04-27 22:58:19 +00009426
9427 // Emit device ID if any.
9428 llvm::Value *DeviceID = nullptr;
George Rokos63bc9d62017-11-21 18:25:12 +00009429 if (Device) {
Samuel Antaodf158d52016-04-27 22:58:19 +00009430 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
George Rokos63bc9d62017-11-21 18:25:12 +00009431 CGF.Int64Ty, /*isSigned=*/true);
9432 } else {
9433 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
9434 }
Samuel Antaodf158d52016-04-27 22:58:19 +00009435
9436 // Emit the number of elements in the offloading arrays.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009437 llvm::Value *PointerNum = CGF.Builder.getInt32(Info.NumberOfPtrs);
Samuel Antaodf158d52016-04-27 22:58:19 +00009438
9439 llvm::Value *OffloadingArgs[] = {
9440 DeviceID, PointerNum, BasePointersArrayArg,
9441 PointersArrayArg, SizesArrayArg, MapTypesArrayArg};
Alexey Bataevd2202ca2017-12-27 17:58:32 +00009442 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__tgt_target_data_begin),
Samuel Antaodf158d52016-04-27 22:58:19 +00009443 OffloadingArgs);
Samuel Antaocc10b852016-07-28 14:23:26 +00009444
9445 // If device pointer privatization is required, emit the body of the region
9446 // here. It will have to be duplicated: with and without privatization.
9447 if (!Info.CaptureDeviceAddrMap.empty())
9448 CodeGen(CGF);
Samuel Antaodf158d52016-04-27 22:58:19 +00009449 };
9450
9451 // Generate code for the closing of the data region.
Alexey Bataevd2202ca2017-12-27 17:58:32 +00009452 auto &&EndThenGen = [this, Device, &Info](CodeGenFunction &CGF,
9453 PrePostActionTy &) {
Samuel Antaocc10b852016-07-28 14:23:26 +00009454 assert(Info.isValid() && "Invalid data environment closing arguments.");
Samuel Antaodf158d52016-04-27 22:58:19 +00009455
9456 llvm::Value *BasePointersArrayArg = nullptr;
9457 llvm::Value *PointersArrayArg = nullptr;
9458 llvm::Value *SizesArrayArg = nullptr;
9459 llvm::Value *MapTypesArrayArg = nullptr;
9460 emitOffloadingArraysArgument(CGF, BasePointersArrayArg, PointersArrayArg,
Samuel Antaocc10b852016-07-28 14:23:26 +00009461 SizesArrayArg, MapTypesArrayArg, Info);
Samuel Antaodf158d52016-04-27 22:58:19 +00009462
9463 // Emit device ID if any.
9464 llvm::Value *DeviceID = nullptr;
George Rokos63bc9d62017-11-21 18:25:12 +00009465 if (Device) {
Samuel Antaodf158d52016-04-27 22:58:19 +00009466 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
George Rokos63bc9d62017-11-21 18:25:12 +00009467 CGF.Int64Ty, /*isSigned=*/true);
9468 } else {
9469 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
9470 }
Samuel Antaodf158d52016-04-27 22:58:19 +00009471
9472 // Emit the number of elements in the offloading arrays.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009473 llvm::Value *PointerNum = CGF.Builder.getInt32(Info.NumberOfPtrs);
Samuel Antaodf158d52016-04-27 22:58:19 +00009474
9475 llvm::Value *OffloadingArgs[] = {
9476 DeviceID, PointerNum, BasePointersArrayArg,
9477 PointersArrayArg, SizesArrayArg, MapTypesArrayArg};
Alexey Bataevd2202ca2017-12-27 17:58:32 +00009478 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__tgt_target_data_end),
Samuel Antaodf158d52016-04-27 22:58:19 +00009479 OffloadingArgs);
9480 };
9481
Samuel Antaocc10b852016-07-28 14:23:26 +00009482 // If we need device pointer privatization, we need to emit the body of the
9483 // region with no privatization in the 'else' branch of the conditional.
9484 // Otherwise, we don't have to do anything.
9485 auto &&BeginElseGen = [&Info, &CodeGen, &NoPrivAction](CodeGenFunction &CGF,
9486 PrePostActionTy &) {
9487 if (!Info.CaptureDeviceAddrMap.empty()) {
9488 CodeGen.setAction(NoPrivAction);
9489 CodeGen(CGF);
9490 }
9491 };
9492
9493 // We don't have to do anything to close the region if the if clause evaluates
9494 // to false.
9495 auto &&EndElseGen = [](CodeGenFunction &CGF, PrePostActionTy &) {};
Samuel Antaodf158d52016-04-27 22:58:19 +00009496
9497 if (IfCond) {
Samuel Antaocc10b852016-07-28 14:23:26 +00009498 emitOMPIfClause(CGF, IfCond, BeginThenGen, BeginElseGen);
Samuel Antaodf158d52016-04-27 22:58:19 +00009499 } else {
Samuel Antaocc10b852016-07-28 14:23:26 +00009500 RegionCodeGenTy RCG(BeginThenGen);
9501 RCG(CGF);
Samuel Antaodf158d52016-04-27 22:58:19 +00009502 }
9503
Samuel Antaocc10b852016-07-28 14:23:26 +00009504 // If we don't require privatization of device pointers, we emit the body in
9505 // between the runtime calls. This avoids duplicating the body code.
9506 if (Info.CaptureDeviceAddrMap.empty()) {
9507 CodeGen.setAction(NoPrivAction);
9508 CodeGen(CGF);
9509 }
Samuel Antaodf158d52016-04-27 22:58:19 +00009510
9511 if (IfCond) {
Samuel Antaocc10b852016-07-28 14:23:26 +00009512 emitOMPIfClause(CGF, IfCond, EndThenGen, EndElseGen);
Samuel Antaodf158d52016-04-27 22:58:19 +00009513 } else {
Samuel Antaocc10b852016-07-28 14:23:26 +00009514 RegionCodeGenTy RCG(EndThenGen);
9515 RCG(CGF);
Samuel Antaodf158d52016-04-27 22:58:19 +00009516 }
9517}
Samuel Antaobd0ae2e2016-04-27 23:07:29 +00009518
Samuel Antao8d2d7302016-05-26 18:30:22 +00009519void CGOpenMPRuntime::emitTargetDataStandAloneCall(
Samuel Antao8dd66282016-04-27 23:14:30 +00009520 CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond,
9521 const Expr *Device) {
Samuel Antaobd0ae2e2016-04-27 23:07:29 +00009522 if (!CGF.HaveInsertPoint())
9523 return;
9524
Samuel Antao8dd66282016-04-27 23:14:30 +00009525 assert((isa<OMPTargetEnterDataDirective>(D) ||
Samuel Antao8d2d7302016-05-26 18:30:22 +00009526 isa<OMPTargetExitDataDirective>(D) ||
9527 isa<OMPTargetUpdateDirective>(D)) &&
9528 "Expecting either target enter, exit data, or update directives.");
Samuel Antao8dd66282016-04-27 23:14:30 +00009529
Alexey Bataevd2202ca2017-12-27 17:58:32 +00009530 CodeGenFunction::OMPTargetDataInfo InputInfo;
9531 llvm::Value *MapTypesArray = nullptr;
Samuel Antaobd0ae2e2016-04-27 23:07:29 +00009532 // Generate the code for the opening of the data environment.
Alexey Bataevd2202ca2017-12-27 17:58:32 +00009533 auto &&ThenGen = [this, &D, Device, &InputInfo,
9534 &MapTypesArray](CodeGenFunction &CGF, PrePostActionTy &) {
Samuel Antaobd0ae2e2016-04-27 23:07:29 +00009535 // Emit device ID if any.
9536 llvm::Value *DeviceID = nullptr;
George Rokos63bc9d62017-11-21 18:25:12 +00009537 if (Device) {
Samuel Antaobd0ae2e2016-04-27 23:07:29 +00009538 DeviceID = CGF.Builder.CreateIntCast(CGF.EmitScalarExpr(Device),
George Rokos63bc9d62017-11-21 18:25:12 +00009539 CGF.Int64Ty, /*isSigned=*/true);
9540 } else {
9541 DeviceID = CGF.Builder.getInt64(OMP_DEVICEID_UNDEF);
9542 }
Samuel Antaobd0ae2e2016-04-27 23:07:29 +00009543
9544 // Emit the number of elements in the offloading arrays.
Alexey Bataevd2202ca2017-12-27 17:58:32 +00009545 llvm::Constant *PointerNum =
9546 CGF.Builder.getInt32(InputInfo.NumberOfTargetItems);
Samuel Antaobd0ae2e2016-04-27 23:07:29 +00009547
Alexey Bataevd2202ca2017-12-27 17:58:32 +00009548 llvm::Value *OffloadingArgs[] = {DeviceID,
9549 PointerNum,
9550 InputInfo.BasePointersArray.getPointer(),
9551 InputInfo.PointersArray.getPointer(),
9552 InputInfo.SizesArray.getPointer(),
9553 MapTypesArray};
Samuel Antao8d2d7302016-05-26 18:30:22 +00009554
Samuel Antao8d2d7302016-05-26 18:30:22 +00009555 // Select the right runtime function call for each expected standalone
9556 // directive.
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +00009557 const bool HasNowait = D.hasClausesOfKind<OMPNowaitClause>();
Samuel Antao8d2d7302016-05-26 18:30:22 +00009558 OpenMPRTLFunction RTLFn;
9559 switch (D.getDirectiveKind()) {
Samuel Antao8d2d7302016-05-26 18:30:22 +00009560 case OMPD_target_enter_data:
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +00009561 RTLFn = HasNowait ? OMPRTL__tgt_target_data_begin_nowait
9562 : OMPRTL__tgt_target_data_begin;
Samuel Antao8d2d7302016-05-26 18:30:22 +00009563 break;
9564 case OMPD_target_exit_data:
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +00009565 RTLFn = HasNowait ? OMPRTL__tgt_target_data_end_nowait
9566 : OMPRTL__tgt_target_data_end;
Samuel Antao8d2d7302016-05-26 18:30:22 +00009567 break;
9568 case OMPD_target_update:
Alexey Bataev0cc6b8e2017-12-14 17:00:17 +00009569 RTLFn = HasNowait ? OMPRTL__tgt_target_data_update_nowait
9570 : OMPRTL__tgt_target_data_update;
Samuel Antao8d2d7302016-05-26 18:30:22 +00009571 break;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009572 case OMPD_parallel:
9573 case OMPD_for:
9574 case OMPD_parallel_for:
9575 case OMPD_parallel_sections:
9576 case OMPD_for_simd:
9577 case OMPD_parallel_for_simd:
9578 case OMPD_cancel:
9579 case OMPD_cancellation_point:
9580 case OMPD_ordered:
9581 case OMPD_threadprivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00009582 case OMPD_allocate:
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009583 case OMPD_task:
9584 case OMPD_simd:
9585 case OMPD_sections:
9586 case OMPD_section:
9587 case OMPD_single:
9588 case OMPD_master:
9589 case OMPD_critical:
9590 case OMPD_taskyield:
9591 case OMPD_barrier:
9592 case OMPD_taskwait:
9593 case OMPD_taskgroup:
9594 case OMPD_atomic:
9595 case OMPD_flush:
9596 case OMPD_teams:
9597 case OMPD_target_data:
9598 case OMPD_distribute:
9599 case OMPD_distribute_simd:
9600 case OMPD_distribute_parallel_for:
9601 case OMPD_distribute_parallel_for_simd:
9602 case OMPD_teams_distribute:
9603 case OMPD_teams_distribute_simd:
9604 case OMPD_teams_distribute_parallel_for:
9605 case OMPD_teams_distribute_parallel_for_simd:
9606 case OMPD_declare_simd:
9607 case OMPD_declare_target:
9608 case OMPD_end_declare_target:
9609 case OMPD_declare_reduction:
Michael Kruse251e1482019-02-01 20:25:04 +00009610 case OMPD_declare_mapper:
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009611 case OMPD_taskloop:
9612 case OMPD_taskloop_simd:
9613 case OMPD_target:
9614 case OMPD_target_simd:
9615 case OMPD_target_teams_distribute:
9616 case OMPD_target_teams_distribute_simd:
9617 case OMPD_target_teams_distribute_parallel_for:
9618 case OMPD_target_teams_distribute_parallel_for_simd:
9619 case OMPD_target_teams:
9620 case OMPD_target_parallel:
9621 case OMPD_target_parallel_for:
9622 case OMPD_target_parallel_for_simd:
Kelvin Li1408f912018-09-26 04:28:39 +00009623 case OMPD_requires:
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009624 case OMPD_unknown:
9625 llvm_unreachable("Unexpected standalone target data directive.");
9626 break;
Samuel Antao8d2d7302016-05-26 18:30:22 +00009627 }
Alexey Bataevd2202ca2017-12-27 17:58:32 +00009628 CGF.EmitRuntimeCall(createRuntimeFunction(RTLFn), OffloadingArgs);
Samuel Antaobd0ae2e2016-04-27 23:07:29 +00009629 };
9630
Alexey Bataevd2202ca2017-12-27 17:58:32 +00009631 auto &&TargetThenGen = [this, &ThenGen, &D, &InputInfo, &MapTypesArray](
9632 CodeGenFunction &CGF, PrePostActionTy &) {
9633 // Fill up the arrays with all the mapped variables.
9634 MappableExprsHandler::MapBaseValuesArrayTy BasePointers;
9635 MappableExprsHandler::MapValuesArrayTy Pointers;
9636 MappableExprsHandler::MapValuesArrayTy Sizes;
9637 MappableExprsHandler::MapFlagsArrayTy MapTypes;
Samuel Antaobd0ae2e2016-04-27 23:07:29 +00009638
Alexey Bataevd2202ca2017-12-27 17:58:32 +00009639 // Get map clause information.
9640 MappableExprsHandler MEHandler(D, CGF);
9641 MEHandler.generateAllInfo(BasePointers, Pointers, Sizes, MapTypes);
9642
9643 TargetDataInfo Info;
9644 // Fill up the arrays and create the arguments.
9645 emitOffloadingArrays(CGF, BasePointers, Pointers, Sizes, MapTypes, Info);
9646 emitOffloadingArraysArgument(CGF, Info.BasePointersArray,
9647 Info.PointersArray, Info.SizesArray,
9648 Info.MapTypesArray, Info);
9649 InputInfo.NumberOfTargetItems = Info.NumberOfPtrs;
9650 InputInfo.BasePointersArray =
9651 Address(Info.BasePointersArray, CGM.getPointerAlign());
9652 InputInfo.PointersArray =
9653 Address(Info.PointersArray, CGM.getPointerAlign());
9654 InputInfo.SizesArray =
9655 Address(Info.SizesArray, CGM.getPointerAlign());
9656 MapTypesArray = Info.MapTypesArray;
9657 if (D.hasClausesOfKind<OMPDependClause>())
9658 CGF.EmitOMPTargetTaskBasedDirective(D, ThenGen, InputInfo);
9659 else
Alexey Bataev768f1f22018-01-09 19:59:25 +00009660 emitInlinedDirective(CGF, D.getDirectiveKind(), ThenGen);
Alexey Bataevd2202ca2017-12-27 17:58:32 +00009661 };
9662
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009663 if (IfCond) {
Alexey Bataevd2202ca2017-12-27 17:58:32 +00009664 emitOMPIfClause(CGF, IfCond, TargetThenGen,
9665 [](CodeGenFunction &CGF, PrePostActionTy &) {});
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009666 } else {
Alexey Bataevd2202ca2017-12-27 17:58:32 +00009667 RegionCodeGenTy ThenRCG(TargetThenGen);
9668 ThenRCG(CGF);
Samuel Antaobd0ae2e2016-04-27 23:07:29 +00009669 }
9670}
Alexey Bataevc7a82b42016-05-06 09:40:08 +00009671
9672namespace {
9673 /// Kind of parameter in a function with 'declare simd' directive.
9674 enum ParamKindTy { LinearWithVarStride, Linear, Uniform, Vector };
9675 /// Attribute set of the parameter.
9676 struct ParamAttrTy {
9677 ParamKindTy Kind = Vector;
9678 llvm::APSInt StrideOrArg;
9679 llvm::APSInt Alignment;
9680 };
9681} // namespace
9682
9683static unsigned evaluateCDTSize(const FunctionDecl *FD,
9684 ArrayRef<ParamAttrTy> ParamAttrs) {
9685 // Every vector variant of a SIMD-enabled function has a vector length (VLEN).
9686 // If OpenMP clause "simdlen" is used, the VLEN is the value of the argument
9687 // of that clause. The VLEN value must be power of 2.
9688 // In other case the notion of the function`s "characteristic data type" (CDT)
9689 // is used to compute the vector length.
9690 // CDT is defined in the following order:
9691 // a) For non-void function, the CDT is the return type.
9692 // b) If the function has any non-uniform, non-linear parameters, then the
9693 // CDT is the type of the first such parameter.
9694 // c) If the CDT determined by a) or b) above is struct, union, or class
9695 // type which is pass-by-value (except for the type that maps to the
9696 // built-in complex data type), the characteristic data type is int.
9697 // d) If none of the above three cases is applicable, the CDT is int.
9698 // The VLEN is then determined based on the CDT and the size of vector
9699 // register of that ISA for which current vector version is generated. The
9700 // VLEN is computed using the formula below:
9701 // VLEN = sizeof(vector_register) / sizeof(CDT),
9702 // where vector register size specified in section 3.2.1 Registers and the
9703 // Stack Frame of original AMD64 ABI document.
9704 QualType RetType = FD->getReturnType();
9705 if (RetType.isNull())
9706 return 0;
9707 ASTContext &C = FD->getASTContext();
9708 QualType CDT;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009709 if (!RetType.isNull() && !RetType->isVoidType()) {
Alexey Bataevc7a82b42016-05-06 09:40:08 +00009710 CDT = RetType;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009711 } else {
Alexey Bataevc7a82b42016-05-06 09:40:08 +00009712 unsigned Offset = 0;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009713 if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
Alexey Bataevc7a82b42016-05-06 09:40:08 +00009714 if (ParamAttrs[Offset].Kind == Vector)
9715 CDT = C.getPointerType(C.getRecordType(MD->getParent()));
9716 ++Offset;
9717 }
9718 if (CDT.isNull()) {
9719 for (unsigned I = 0, E = FD->getNumParams(); I < E; ++I) {
9720 if (ParamAttrs[I + Offset].Kind == Vector) {
9721 CDT = FD->getParamDecl(I)->getType();
9722 break;
9723 }
9724 }
9725 }
9726 }
9727 if (CDT.isNull())
9728 CDT = C.IntTy;
9729 CDT = CDT->getCanonicalTypeUnqualified();
9730 if (CDT->isRecordType() || CDT->isUnionType())
9731 CDT = C.IntTy;
9732 return C.getTypeSize(CDT);
9733}
9734
9735static void
9736emitX86DeclareSimdFunction(const FunctionDecl *FD, llvm::Function *Fn,
Benjamin Kramer81cb4b72016-11-24 16:01:20 +00009737 const llvm::APSInt &VLENVal,
Alexey Bataevc7a82b42016-05-06 09:40:08 +00009738 ArrayRef<ParamAttrTy> ParamAttrs,
9739 OMPDeclareSimdDeclAttr::BranchStateTy State) {
9740 struct ISADataTy {
9741 char ISA;
9742 unsigned VecRegSize;
9743 };
9744 ISADataTy ISAData[] = {
9745 {
9746 'b', 128
9747 }, // SSE
9748 {
9749 'c', 256
9750 }, // AVX
9751 {
9752 'd', 256
9753 }, // AVX2
9754 {
9755 'e', 512
9756 }, // AVX512
9757 };
9758 llvm::SmallVector<char, 2> Masked;
9759 switch (State) {
9760 case OMPDeclareSimdDeclAttr::BS_Undefined:
9761 Masked.push_back('N');
9762 Masked.push_back('M');
9763 break;
9764 case OMPDeclareSimdDeclAttr::BS_Notinbranch:
9765 Masked.push_back('N');
9766 break;
9767 case OMPDeclareSimdDeclAttr::BS_Inbranch:
9768 Masked.push_back('M');
9769 break;
9770 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009771 for (char Mask : Masked) {
9772 for (const ISADataTy &Data : ISAData) {
Alexey Bataevc7a82b42016-05-06 09:40:08 +00009773 SmallString<256> Buffer;
9774 llvm::raw_svector_ostream Out(Buffer);
9775 Out << "_ZGV" << Data.ISA << Mask;
9776 if (!VLENVal) {
9777 Out << llvm::APSInt::getUnsigned(Data.VecRegSize /
9778 evaluateCDTSize(FD, ParamAttrs));
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009779 } else {
Alexey Bataevc7a82b42016-05-06 09:40:08 +00009780 Out << VLENVal;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +00009781 }
9782 for (const ParamAttrTy &ParamAttr : ParamAttrs) {
Alexey Bataevc7a82b42016-05-06 09:40:08 +00009783 switch (ParamAttr.Kind){
9784 case LinearWithVarStride:
9785 Out << 's' << ParamAttr.StrideOrArg;
9786 break;
9787 case Linear:
9788 Out << 'l';
9789 if (!!ParamAttr.StrideOrArg)
9790 Out << ParamAttr.StrideOrArg;
9791 break;
9792 case Uniform:
9793 Out << 'u';
9794 break;
9795 case Vector:
9796 Out << 'v';
9797 break;
9798 }
9799 if (!!ParamAttr.Alignment)
9800 Out << 'a' << ParamAttr.Alignment;
9801 }
9802 Out << '_' << Fn->getName();
9803 Fn->addFnAttr(Out.str());
9804 }
9805 }
9806}
9807
Alexey Bataeva0a22642019-04-16 13:56:21 +00009808// This are the Functions that are needed to mangle the name of the
9809// vector functions generated by the compiler, according to the rules
9810// defined in the "Vector Function ABI specifications for AArch64",
9811// available at
9812// https://developer.arm.com/products/software-development-tools/hpc/arm-compiler-for-hpc/vector-function-abi.
9813
9814/// Maps To Vector (MTV), as defined in 3.1.1 of the AAVFABI.
9815///
9816/// TODO: Need to implement the behavior for reference marked with a
9817/// var or no linear modifiers (1.b in the section). For this, we
9818/// need to extend ParamKindTy to support the linear modifiers.
9819static bool getAArch64MTV(QualType QT, ParamKindTy Kind) {
9820 QT = QT.getCanonicalType();
9821
9822 if (QT->isVoidType())
9823 return false;
9824
9825 if (Kind == ParamKindTy::Uniform)
9826 return false;
9827
9828 if (Kind == ParamKindTy::Linear)
9829 return false;
9830
9831 // TODO: Handle linear references with modifiers
9832
9833 if (Kind == ParamKindTy::LinearWithVarStride)
9834 return false;
9835
9836 return true;
9837}
9838
9839/// Pass By Value (PBV), as defined in 3.1.2 of the AAVFABI.
9840static bool getAArch64PBV(QualType QT, ASTContext &C) {
9841 QT = QT.getCanonicalType();
9842 unsigned Size = C.getTypeSize(QT);
9843
9844 // Only scalars and complex within 16 bytes wide set PVB to true.
9845 if (Size != 8 && Size != 16 && Size != 32 && Size != 64 && Size != 128)
9846 return false;
9847
9848 if (QT->isFloatingType())
9849 return true;
9850
9851 if (QT->isIntegerType())
9852 return true;
9853
9854 if (QT->isPointerType())
9855 return true;
9856
9857 // TODO: Add support for complex types (section 3.1.2, item 2).
9858
9859 return false;
9860}
9861
9862/// Computes the lane size (LS) of a return type or of an input parameter,
9863/// as defined by `LS(P)` in 3.2.1 of the AAVFABI.
9864/// TODO: Add support for references, section 3.2.1, item 1.
9865static unsigned getAArch64LS(QualType QT, ParamKindTy Kind, ASTContext &C) {
9866 if (getAArch64MTV(QT, Kind) && QT.getCanonicalType()->isPointerType()) {
9867 QualType PTy = QT.getCanonicalType()->getPointeeType();
9868 if (getAArch64PBV(PTy, C))
9869 return C.getTypeSize(PTy);
9870 }
9871 if (getAArch64PBV(QT, C))
9872 return C.getTypeSize(QT);
9873
9874 return C.getTypeSize(C.getUIntPtrType());
9875}
9876
9877// Get Narrowest Data Size (NDS) and Widest Data Size (WDS) from the
9878// signature of the scalar function, as defined in 3.2.2 of the
9879// AAVFABI.
9880static std::tuple<unsigned, unsigned, bool>
9881getNDSWDS(const FunctionDecl *FD, ArrayRef<ParamAttrTy> ParamAttrs) {
9882 QualType RetType = FD->getReturnType().getCanonicalType();
9883
9884 ASTContext &C = FD->getASTContext();
9885
9886 bool OutputBecomesInput = false;
9887
9888 llvm::SmallVector<unsigned, 8> Sizes;
9889 if (!RetType->isVoidType()) {
9890 Sizes.push_back(getAArch64LS(RetType, ParamKindTy::Vector, C));
9891 if (!getAArch64PBV(RetType, C) && getAArch64MTV(RetType, {}))
9892 OutputBecomesInput = true;
9893 }
9894 for (unsigned I = 0, E = FD->getNumParams(); I < E; ++I) {
9895 QualType QT = FD->getParamDecl(I)->getType().getCanonicalType();
9896 Sizes.push_back(getAArch64LS(QT, ParamAttrs[I].Kind, C));
9897 }
9898
9899 assert(!Sizes.empty() && "Unable to determine NDS and WDS.");
9900 // The LS of a function parameter / return value can only be a power
9901 // of 2, starting from 8 bits, up to 128.
9902 assert(std::all_of(Sizes.begin(), Sizes.end(),
9903 [](unsigned Size) {
9904 return Size == 8 || Size == 16 || Size == 32 ||
9905 Size == 64 || Size == 128;
9906 }) &&
9907 "Invalid size");
9908
9909 return std::make_tuple(*std::min_element(std::begin(Sizes), std::end(Sizes)),
9910 *std::max_element(std::begin(Sizes), std::end(Sizes)),
9911 OutputBecomesInput);
9912}
9913
9914/// Mangle the parameter part of the vector function name according to
9915/// their OpenMP classification. The mangling function is defined in
9916/// section 3.5 of the AAVFABI.
9917static std::string mangleVectorParameters(ArrayRef<ParamAttrTy> ParamAttrs) {
9918 SmallString<256> Buffer;
9919 llvm::raw_svector_ostream Out(Buffer);
9920 for (const auto &ParamAttr : ParamAttrs) {
9921 switch (ParamAttr.Kind) {
9922 case LinearWithVarStride:
9923 Out << "ls" << ParamAttr.StrideOrArg;
9924 break;
9925 case Linear:
9926 Out << 'l';
9927 // Don't print the step value if it is not present or if it is
9928 // equal to 1.
9929 if (!!ParamAttr.StrideOrArg && ParamAttr.StrideOrArg != 1)
9930 Out << ParamAttr.StrideOrArg;
9931 break;
9932 case Uniform:
9933 Out << 'u';
9934 break;
9935 case Vector:
9936 Out << 'v';
9937 break;
9938 }
9939
9940 if (!!ParamAttr.Alignment)
9941 Out << 'a' << ParamAttr.Alignment;
9942 }
9943
9944 return Out.str();
9945}
9946
9947// Function used to add the attribute. The parameter `VLEN` is
9948// templated to allow the use of "x" when targeting scalable functions
9949// for SVE.
9950template <typename T>
9951static void addAArch64VectorName(T VLEN, StringRef LMask, StringRef Prefix,
9952 char ISA, StringRef ParSeq,
9953 StringRef MangledName, bool OutputBecomesInput,
9954 llvm::Function *Fn) {
9955 SmallString<256> Buffer;
9956 llvm::raw_svector_ostream Out(Buffer);
9957 Out << Prefix << ISA << LMask << VLEN;
9958 if (OutputBecomesInput)
9959 Out << "v";
9960 Out << ParSeq << "_" << MangledName;
9961 Fn->addFnAttr(Out.str());
9962}
9963
9964// Helper function to generate the Advanced SIMD names depending on
9965// the value of the NDS when simdlen is not present.
9966static void addAArch64AdvSIMDNDSNames(unsigned NDS, StringRef Mask,
9967 StringRef Prefix, char ISA,
9968 StringRef ParSeq, StringRef MangledName,
9969 bool OutputBecomesInput,
9970 llvm::Function *Fn) {
9971 switch (NDS) {
9972 case 8:
9973 addAArch64VectorName(8, Mask, Prefix, ISA, ParSeq, MangledName,
9974 OutputBecomesInput, Fn);
9975 addAArch64VectorName(16, Mask, Prefix, ISA, ParSeq, MangledName,
9976 OutputBecomesInput, Fn);
9977 break;
9978 case 16:
9979 addAArch64VectorName(4, Mask, Prefix, ISA, ParSeq, MangledName,
9980 OutputBecomesInput, Fn);
9981 addAArch64VectorName(8, Mask, Prefix, ISA, ParSeq, MangledName,
9982 OutputBecomesInput, Fn);
9983 break;
9984 case 32:
9985 addAArch64VectorName(2, Mask, Prefix, ISA, ParSeq, MangledName,
9986 OutputBecomesInput, Fn);
9987 addAArch64VectorName(4, Mask, Prefix, ISA, ParSeq, MangledName,
9988 OutputBecomesInput, Fn);
9989 break;
9990 case 64:
9991 case 128:
9992 addAArch64VectorName(2, Mask, Prefix, ISA, ParSeq, MangledName,
9993 OutputBecomesInput, Fn);
9994 break;
9995 default:
9996 llvm_unreachable("Scalar type is too wide.");
9997 }
9998}
9999
10000/// Emit vector function attributes for AArch64, as defined in the AAVFABI.
10001static void emitAArch64DeclareSimdFunction(
10002 CodeGenModule &CGM, const FunctionDecl *FD, unsigned UserVLEN,
10003 ArrayRef<ParamAttrTy> ParamAttrs,
10004 OMPDeclareSimdDeclAttr::BranchStateTy State, StringRef MangledName,
10005 char ISA, unsigned VecRegSize, llvm::Function *Fn, SourceLocation SLoc) {
10006
10007 // Get basic data for building the vector signature.
10008 const auto Data = getNDSWDS(FD, ParamAttrs);
10009 const unsigned NDS = std::get<0>(Data);
10010 const unsigned WDS = std::get<1>(Data);
10011 const bool OutputBecomesInput = std::get<2>(Data);
10012
10013 // Check the values provided via `simdlen` by the user.
10014 // 1. A `simdlen(1)` doesn't produce vector signatures,
10015 if (UserVLEN == 1) {
10016 unsigned DiagID = CGM.getDiags().getCustomDiagID(
10017 DiagnosticsEngine::Warning,
10018 "The clause simdlen(1) has no effect when targeting aarch64.");
10019 CGM.getDiags().Report(SLoc, DiagID);
10020 return;
10021 }
10022
10023 // 2. Section 3.3.1, item 1: user input must be a power of 2 for
10024 // Advanced SIMD output.
10025 if (ISA == 'n' && UserVLEN && !llvm::isPowerOf2_32(UserVLEN)) {
10026 unsigned DiagID = CGM.getDiags().getCustomDiagID(
10027 DiagnosticsEngine::Warning, "The value specified in simdlen must be a "
10028 "power of 2 when targeting Advanced SIMD.");
10029 CGM.getDiags().Report(SLoc, DiagID);
10030 return;
10031 }
10032
10033 // 3. Section 3.4.1. SVE fixed lengh must obey the architectural
10034 // limits.
10035 if (ISA == 's' && UserVLEN != 0) {
10036 if ((UserVLEN * WDS > 2048) || (UserVLEN * WDS % 128 != 0)) {
10037 unsigned DiagID = CGM.getDiags().getCustomDiagID(
10038 DiagnosticsEngine::Warning, "The clause simdlen must fit the %0-bit "
10039 "lanes in the architectural constraints "
10040 "for SVE (min is 128-bit, max is "
10041 "2048-bit, by steps of 128-bit)");
10042 CGM.getDiags().Report(SLoc, DiagID) << WDS;
10043 return;
10044 }
10045 }
10046
10047 // Sort out parameter sequence.
10048 const std::string ParSeq = mangleVectorParameters(ParamAttrs);
10049 StringRef Prefix = "_ZGV";
10050 // Generate simdlen from user input (if any).
10051 if (UserVLEN) {
10052 if (ISA == 's') {
10053 // SVE generates only a masked function.
10054 addAArch64VectorName(UserVLEN, "M", Prefix, ISA, ParSeq, MangledName,
10055 OutputBecomesInput, Fn);
10056 } else {
10057 assert(ISA == 'n' && "Expected ISA either 's' or 'n'.");
10058 // Advanced SIMD generates one or two functions, depending on
10059 // the `[not]inbranch` clause.
10060 switch (State) {
10061 case OMPDeclareSimdDeclAttr::BS_Undefined:
10062 addAArch64VectorName(UserVLEN, "N", Prefix, ISA, ParSeq, MangledName,
10063 OutputBecomesInput, Fn);
10064 addAArch64VectorName(UserVLEN, "M", Prefix, ISA, ParSeq, MangledName,
10065 OutputBecomesInput, Fn);
10066 break;
10067 case OMPDeclareSimdDeclAttr::BS_Notinbranch:
10068 addAArch64VectorName(UserVLEN, "N", Prefix, ISA, ParSeq, MangledName,
10069 OutputBecomesInput, Fn);
10070 break;
10071 case OMPDeclareSimdDeclAttr::BS_Inbranch:
10072 addAArch64VectorName(UserVLEN, "M", Prefix, ISA, ParSeq, MangledName,
10073 OutputBecomesInput, Fn);
10074 break;
10075 }
10076 }
10077 } else {
10078 // If no user simdlen is provided, follow the AAVFABI rules for
10079 // generating the vector length.
10080 if (ISA == 's') {
10081 // SVE, section 3.4.1, item 1.
10082 addAArch64VectorName("x", "M", Prefix, ISA, ParSeq, MangledName,
10083 OutputBecomesInput, Fn);
10084 } else {
10085 assert(ISA == 'n' && "Expected ISA either 's' or 'n'.");
10086 // Advanced SIMD, Section 3.3.1 of the AAVFABI, generates one or
10087 // two vector names depending on the use of the clause
10088 // `[not]inbranch`.
10089 switch (State) {
10090 case OMPDeclareSimdDeclAttr::BS_Undefined:
10091 addAArch64AdvSIMDNDSNames(NDS, "N", Prefix, ISA, ParSeq, MangledName,
10092 OutputBecomesInput, Fn);
10093 addAArch64AdvSIMDNDSNames(NDS, "M", Prefix, ISA, ParSeq, MangledName,
10094 OutputBecomesInput, Fn);
10095 break;
10096 case OMPDeclareSimdDeclAttr::BS_Notinbranch:
10097 addAArch64AdvSIMDNDSNames(NDS, "N", Prefix, ISA, ParSeq, MangledName,
10098 OutputBecomesInput, Fn);
10099 break;
10100 case OMPDeclareSimdDeclAttr::BS_Inbranch:
10101 addAArch64AdvSIMDNDSNames(NDS, "M", Prefix, ISA, ParSeq, MangledName,
10102 OutputBecomesInput, Fn);
10103 break;
10104 }
10105 }
10106 }
10107}
10108
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010109void CGOpenMPRuntime::emitDeclareSimdFunction(const FunctionDecl *FD,
10110 llvm::Function *Fn) {
10111 ASTContext &C = CGM.getContext();
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010112 FD = FD->getMostRecentDecl();
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010113 // Map params to their positions in function decl.
10114 llvm::DenseMap<const Decl *, unsigned> ParamPositions;
10115 if (isa<CXXMethodDecl>(FD))
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010116 ParamPositions.try_emplace(FD, 0);
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010117 unsigned ParamPos = ParamPositions.size();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010118 for (const ParmVarDecl *P : FD->parameters()) {
10119 ParamPositions.try_emplace(P->getCanonicalDecl(), ParamPos);
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010120 ++ParamPos;
10121 }
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010122 while (FD) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010123 for (const auto *Attr : FD->specific_attrs<OMPDeclareSimdDeclAttr>()) {
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010124 llvm::SmallVector<ParamAttrTy, 8> ParamAttrs(ParamPositions.size());
10125 // Mark uniform parameters.
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010126 for (const Expr *E : Attr->uniforms()) {
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010127 E = E->IgnoreParenImpCasts();
10128 unsigned Pos;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010129 if (isa<CXXThisExpr>(E)) {
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010130 Pos = ParamPositions[FD];
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010131 } else {
10132 const auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
10133 ->getCanonicalDecl();
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010134 Pos = ParamPositions[PVD];
10135 }
10136 ParamAttrs[Pos].Kind = Uniform;
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010137 }
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010138 // Get alignment info.
10139 auto NI = Attr->alignments_begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010140 for (const Expr *E : Attr->aligneds()) {
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010141 E = E->IgnoreParenImpCasts();
10142 unsigned Pos;
10143 QualType ParmTy;
10144 if (isa<CXXThisExpr>(E)) {
10145 Pos = ParamPositions[FD];
10146 ParmTy = E->getType();
10147 } else {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010148 const auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
10149 ->getCanonicalDecl();
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010150 Pos = ParamPositions[PVD];
10151 ParmTy = PVD->getType();
10152 }
10153 ParamAttrs[Pos].Alignment =
10154 (*NI)
10155 ? (*NI)->EvaluateKnownConstInt(C)
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010156 : llvm::APSInt::getUnsigned(
10157 C.toCharUnitsFromBits(C.getOpenMPDefaultSimdAlign(ParmTy))
10158 .getQuantity());
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010159 ++NI;
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010160 }
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010161 // Mark linear parameters.
10162 auto SI = Attr->steps_begin();
10163 auto MI = Attr->modifiers_begin();
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010164 for (const Expr *E : Attr->linears()) {
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010165 E = E->IgnoreParenImpCasts();
10166 unsigned Pos;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010167 if (isa<CXXThisExpr>(E)) {
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010168 Pos = ParamPositions[FD];
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010169 } else {
10170 const auto *PVD = cast<ParmVarDecl>(cast<DeclRefExpr>(E)->getDecl())
10171 ->getCanonicalDecl();
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010172 Pos = ParamPositions[PVD];
10173 }
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010174 ParamAttrTy &ParamAttr = ParamAttrs[Pos];
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010175 ParamAttr.Kind = Linear;
10176 if (*SI) {
Fangrui Song407659a2018-11-30 23:41:18 +000010177 Expr::EvalResult Result;
10178 if (!(*SI)->EvaluateAsInt(Result, C, Expr::SE_AllowSideEffects)) {
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010179 if (const auto *DRE =
10180 cast<DeclRefExpr>((*SI)->IgnoreParenImpCasts())) {
10181 if (const auto *StridePVD = cast<ParmVarDecl>(DRE->getDecl())) {
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010182 ParamAttr.Kind = LinearWithVarStride;
10183 ParamAttr.StrideOrArg = llvm::APSInt::getUnsigned(
10184 ParamPositions[StridePVD->getCanonicalDecl()]);
10185 }
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010186 }
Fangrui Song407659a2018-11-30 23:41:18 +000010187 } else {
10188 ParamAttr.StrideOrArg = Result.Val.getInt();
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010189 }
10190 }
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010191 ++SI;
10192 ++MI;
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010193 }
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010194 llvm::APSInt VLENVal;
Alexey Bataeva0a22642019-04-16 13:56:21 +000010195 SourceLocation ExprLoc;
10196 const Expr *VLENExpr = Attr->getSimdlen();
10197 if (VLENExpr) {
10198 VLENVal = VLENExpr->EvaluateKnownConstInt(C);
10199 ExprLoc = VLENExpr->getExprLoc();
10200 }
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010201 OMPDeclareSimdDeclAttr::BranchStateTy State = Attr->getBranchState();
10202 if (CGM.getTriple().getArch() == llvm::Triple::x86 ||
Alexey Bataeva0a22642019-04-16 13:56:21 +000010203 CGM.getTriple().getArch() == llvm::Triple::x86_64) {
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010204 emitX86DeclareSimdFunction(FD, Fn, VLENVal, ParamAttrs, State);
Alexey Bataeva0a22642019-04-16 13:56:21 +000010205 } else if (CGM.getTriple().getArch() == llvm::Triple::aarch64) {
10206 unsigned VLEN = VLENVal.getExtValue();
10207 StringRef MangledName = Fn->getName();
10208 if (CGM.getTarget().hasFeature("sve"))
10209 emitAArch64DeclareSimdFunction(CGM, FD, VLEN, ParamAttrs, State,
10210 MangledName, 's', 128, Fn, ExprLoc);
10211 if (CGM.getTarget().hasFeature("neon"))
10212 emitAArch64DeclareSimdFunction(CGM, FD, VLEN, ParamAttrs, State,
10213 MangledName, 'n', 128, Fn, ExprLoc);
10214 }
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010215 }
Alexey Bataev20cf67c2018-03-02 18:07:00 +000010216 FD = FD->getPreviousDecl();
Alexey Bataevc7a82b42016-05-06 09:40:08 +000010217 }
10218}
Alexey Bataev8b427062016-05-25 12:36:08 +000010219
10220namespace {
10221/// Cleanup action for doacross support.
10222class DoacrossCleanupTy final : public EHScopeStack::Cleanup {
10223public:
10224 static const int DoacrossFinArgs = 2;
10225
10226private:
James Y Knight9871db02019-02-05 16:42:33 +000010227 llvm::FunctionCallee RTLFn;
Alexey Bataev8b427062016-05-25 12:36:08 +000010228 llvm::Value *Args[DoacrossFinArgs];
10229
10230public:
James Y Knight9871db02019-02-05 16:42:33 +000010231 DoacrossCleanupTy(llvm::FunctionCallee RTLFn,
10232 ArrayRef<llvm::Value *> CallArgs)
Alexey Bataev8b427062016-05-25 12:36:08 +000010233 : RTLFn(RTLFn) {
10234 assert(CallArgs.size() == DoacrossFinArgs);
10235 std::copy(CallArgs.begin(), CallArgs.end(), std::begin(Args));
10236 }
10237 void Emit(CodeGenFunction &CGF, Flags /*flags*/) override {
10238 if (!CGF.HaveInsertPoint())
10239 return;
10240 CGF.EmitRuntimeCall(RTLFn, Args);
10241 }
10242};
10243} // namespace
10244
10245void CGOpenMPRuntime::emitDoacrossInit(CodeGenFunction &CGF,
Alexey Bataevf138fda2018-08-13 19:04:24 +000010246 const OMPLoopDirective &D,
10247 ArrayRef<Expr *> NumIterations) {
Alexey Bataev8b427062016-05-25 12:36:08 +000010248 if (!CGF.HaveInsertPoint())
10249 return;
10250
10251 ASTContext &C = CGM.getContext();
10252 QualType Int64Ty = C.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/true);
10253 RecordDecl *RD;
10254 if (KmpDimTy.isNull()) {
10255 // Build struct kmp_dim { // loop bounds info casted to kmp_int64
10256 // kmp_int64 lo; // lower
10257 // kmp_int64 up; // upper
10258 // kmp_int64 st; // stride
10259 // };
10260 RD = C.buildImplicitRecord("kmp_dim");
10261 RD->startDefinition();
10262 addFieldToRecordDecl(C, RD, Int64Ty);
10263 addFieldToRecordDecl(C, RD, Int64Ty);
10264 addFieldToRecordDecl(C, RD, Int64Ty);
10265 RD->completeDefinition();
10266 KmpDimTy = C.getRecordType(RD);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010267 } else {
Alexey Bataev8b427062016-05-25 12:36:08 +000010268 RD = cast<RecordDecl>(KmpDimTy->getAsTagDecl());
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010269 }
Alexey Bataevf138fda2018-08-13 19:04:24 +000010270 llvm::APInt Size(/*numBits=*/32, NumIterations.size());
10271 QualType ArrayTy =
10272 C.getConstantArrayType(KmpDimTy, Size, ArrayType::Normal, 0);
Alexey Bataev8b427062016-05-25 12:36:08 +000010273
Alexey Bataevf138fda2018-08-13 19:04:24 +000010274 Address DimsAddr = CGF.CreateMemTemp(ArrayTy, "dims");
10275 CGF.EmitNullInitialization(DimsAddr, ArrayTy);
Alexey Bataev8b427062016-05-25 12:36:08 +000010276 enum { LowerFD = 0, UpperFD, StrideFD };
10277 // Fill dims with data.
Alexey Bataevf138fda2018-08-13 19:04:24 +000010278 for (unsigned I = 0, E = NumIterations.size(); I < E; ++I) {
James Y Knight751fe282019-02-09 22:22:28 +000010279 LValue DimsLVal = CGF.MakeAddrLValue(
10280 CGF.Builder.CreateConstArrayGEP(DimsAddr, I), KmpDimTy);
Alexey Bataevf138fda2018-08-13 19:04:24 +000010281 // dims.upper = num_iterations;
10282 LValue UpperLVal = CGF.EmitLValueForField(
10283 DimsLVal, *std::next(RD->field_begin(), UpperFD));
10284 llvm::Value *NumIterVal =
10285 CGF.EmitScalarConversion(CGF.EmitScalarExpr(NumIterations[I]),
10286 D.getNumIterations()->getType(), Int64Ty,
10287 D.getNumIterations()->getExprLoc());
10288 CGF.EmitStoreOfScalar(NumIterVal, UpperLVal);
10289 // dims.stride = 1;
10290 LValue StrideLVal = CGF.EmitLValueForField(
10291 DimsLVal, *std::next(RD->field_begin(), StrideFD));
10292 CGF.EmitStoreOfScalar(llvm::ConstantInt::getSigned(CGM.Int64Ty, /*V=*/1),
10293 StrideLVal);
10294 }
Alexey Bataev8b427062016-05-25 12:36:08 +000010295
10296 // Build call void __kmpc_doacross_init(ident_t *loc, kmp_int32 gtid,
10297 // kmp_int32 num_dims, struct kmp_dim * dims);
Alexey Bataevf138fda2018-08-13 19:04:24 +000010298 llvm::Value *Args[] = {
10299 emitUpdateLocation(CGF, D.getBeginLoc()),
10300 getThreadID(CGF, D.getBeginLoc()),
10301 llvm::ConstantInt::getSigned(CGM.Int32Ty, NumIterations.size()),
10302 CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
James Y Knight751fe282019-02-09 22:22:28 +000010303 CGF.Builder.CreateConstArrayGEP(DimsAddr, 0).getPointer(),
Alexey Bataevf138fda2018-08-13 19:04:24 +000010304 CGM.VoidPtrTy)};
Alexey Bataev8b427062016-05-25 12:36:08 +000010305
James Y Knight9871db02019-02-05 16:42:33 +000010306 llvm::FunctionCallee RTLFn =
10307 createRuntimeFunction(OMPRTL__kmpc_doacross_init);
Alexey Bataev8b427062016-05-25 12:36:08 +000010308 CGF.EmitRuntimeCall(RTLFn, Args);
10309 llvm::Value *FiniArgs[DoacrossCleanupTy::DoacrossFinArgs] = {
Stephen Kelly1c301dc2018-08-09 21:09:38 +000010310 emitUpdateLocation(CGF, D.getEndLoc()), getThreadID(CGF, D.getEndLoc())};
James Y Knight9871db02019-02-05 16:42:33 +000010311 llvm::FunctionCallee FiniRTLFn =
10312 createRuntimeFunction(OMPRTL__kmpc_doacross_fini);
Alexey Bataev8b427062016-05-25 12:36:08 +000010313 CGF.EHStack.pushCleanup<DoacrossCleanupTy>(NormalAndEHCleanup, FiniRTLFn,
10314 llvm::makeArrayRef(FiniArgs));
10315}
10316
10317void CGOpenMPRuntime::emitDoacrossOrdered(CodeGenFunction &CGF,
10318 const OMPDependClause *C) {
10319 QualType Int64Ty =
10320 CGM.getContext().getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
Alexey Bataevf138fda2018-08-13 19:04:24 +000010321 llvm::APInt Size(/*numBits=*/32, C->getNumLoops());
10322 QualType ArrayTy = CGM.getContext().getConstantArrayType(
10323 Int64Ty, Size, ArrayType::Normal, 0);
10324 Address CntAddr = CGF.CreateMemTemp(ArrayTy, ".cnt.addr");
10325 for (unsigned I = 0, E = C->getNumLoops(); I < E; ++I) {
10326 const Expr *CounterVal = C->getLoopData(I);
10327 assert(CounterVal);
10328 llvm::Value *CntVal = CGF.EmitScalarConversion(
10329 CGF.EmitScalarExpr(CounterVal), CounterVal->getType(), Int64Ty,
10330 CounterVal->getExprLoc());
James Y Knight751fe282019-02-09 22:22:28 +000010331 CGF.EmitStoreOfScalar(CntVal, CGF.Builder.CreateConstArrayGEP(CntAddr, I),
10332 /*Volatile=*/false, Int64Ty);
Alexey Bataevf138fda2018-08-13 19:04:24 +000010333 }
10334 llvm::Value *Args[] = {
10335 emitUpdateLocation(CGF, C->getBeginLoc()),
10336 getThreadID(CGF, C->getBeginLoc()),
James Y Knight751fe282019-02-09 22:22:28 +000010337 CGF.Builder.CreateConstArrayGEP(CntAddr, 0).getPointer()};
James Y Knight9871db02019-02-05 16:42:33 +000010338 llvm::FunctionCallee RTLFn;
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010339 if (C->getDependencyKind() == OMPC_DEPEND_source) {
Alexey Bataev8b427062016-05-25 12:36:08 +000010340 RTLFn = createRuntimeFunction(OMPRTL__kmpc_doacross_post);
Alexey Bataeva4fa0b82018-04-16 17:59:34 +000010341 } else {
Alexey Bataev8b427062016-05-25 12:36:08 +000010342 assert(C->getDependencyKind() == OMPC_DEPEND_sink);
10343 RTLFn = createRuntimeFunction(OMPRTL__kmpc_doacross_wait);
10344 }
10345 CGF.EmitRuntimeCall(RTLFn, Args);
10346}
10347
Alexey Bataev7ef47a62018-02-22 18:33:31 +000010348void CGOpenMPRuntime::emitCall(CodeGenFunction &CGF, SourceLocation Loc,
James Y Knight9871db02019-02-05 16:42:33 +000010349 llvm::FunctionCallee Callee,
Alexey Bataev7ef47a62018-02-22 18:33:31 +000010350 ArrayRef<llvm::Value *> Args) const {
10351 assert(Loc.isValid() && "Outlined function call location must be valid.");
Alexey Bataev3c595a62017-08-14 15:01:03 +000010352 auto DL = ApplyDebugLocation::CreateDefaultArtificial(CGF, Loc);
10353
James Y Knight9871db02019-02-05 16:42:33 +000010354 if (auto *Fn = dyn_cast<llvm::Function>(Callee.getCallee())) {
Alexey Bataev2c7eee52017-08-04 19:10:54 +000010355 if (Fn->doesNotThrow()) {
Alexey Bataev3c595a62017-08-14 15:01:03 +000010356 CGF.EmitNounwindRuntimeCall(Fn, Args);
Alexey Bataev2c7eee52017-08-04 19:10:54 +000010357 return;
10358 }
10359 }
Alexey Bataev3c595a62017-08-14 15:01:03 +000010360 CGF.EmitRuntimeCall(Callee, Args);
10361}
10362
10363void CGOpenMPRuntime::emitOutlinedFunctionCall(
James Y Knight9871db02019-02-05 16:42:33 +000010364 CodeGenFunction &CGF, SourceLocation Loc, llvm::FunctionCallee OutlinedFn,
Alexey Bataev3c595a62017-08-14 15:01:03 +000010365 ArrayRef<llvm::Value *> Args) const {
Alexey Bataev7ef47a62018-02-22 18:33:31 +000010366 emitCall(CGF, Loc, OutlinedFn, Args);
Alexey Bataev2c7eee52017-08-04 19:10:54 +000010367}
Alexey Bataev3b8d5582017-08-08 18:04:06 +000010368
Gheorghe-Teodor Bercea66cdbb472019-05-21 19:42:01 +000010369void CGOpenMPRuntime::emitFunctionProlog(CodeGenFunction &CGF, const Decl *D) {
10370 if (const auto *FD = dyn_cast<FunctionDecl>(D))
10371 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD))
10372 HasEmittedDeclareTargetRegion = true;
10373}
10374
Alexey Bataev3b8d5582017-08-08 18:04:06 +000010375Address CGOpenMPRuntime::getParameterAddress(CodeGenFunction &CGF,
10376 const VarDecl *NativeParam,
10377 const VarDecl *TargetParam) const {
10378 return CGF.GetAddrOfLocalVar(NativeParam);
10379}
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000010380
Alexey Bataev4f680db2019-03-19 16:41:16 +000010381namespace {
10382/// Cleanup action for allocate support.
10383class OMPAllocateCleanupTy final : public EHScopeStack::Cleanup {
10384public:
10385 static const int CleanupArgs = 3;
10386
10387private:
10388 llvm::FunctionCallee RTLFn;
10389 llvm::Value *Args[CleanupArgs];
10390
10391public:
10392 OMPAllocateCleanupTy(llvm::FunctionCallee RTLFn,
10393 ArrayRef<llvm::Value *> CallArgs)
10394 : RTLFn(RTLFn) {
10395 assert(CallArgs.size() == CleanupArgs &&
10396 "Size of arguments does not match.");
10397 std::copy(CallArgs.begin(), CallArgs.end(), std::begin(Args));
10398 }
10399 void Emit(CodeGenFunction &CGF, Flags /*flags*/) override {
10400 if (!CGF.HaveInsertPoint())
10401 return;
10402 CGF.EmitRuntimeCall(RTLFn, Args);
10403 }
10404};
10405} // namespace
10406
Gheorghe-Teodor Bercead3dcf2f2018-03-14 14:17:45 +000010407Address CGOpenMPRuntime::getAddressOfLocalVariable(CodeGenFunction &CGF,
10408 const VarDecl *VD) {
Alexey Bataev084b0c2f02019-03-21 20:36:16 +000010409 if (!VD)
10410 return Address::invalid();
Alexey Bataev4f680db2019-03-19 16:41:16 +000010411 const VarDecl *CVD = VD->getCanonicalDecl();
10412 if (!CVD->hasAttr<OMPAllocateDeclAttr>())
10413 return Address::invalid();
Alexey Bataev084b0c2f02019-03-21 20:36:16 +000010414 const auto *AA = CVD->getAttr<OMPAllocateDeclAttr>();
10415 // Use the default allocation.
Alexey Bataev0fd3c682019-04-02 19:44:46 +000010416 if (AA->getAllocatorType() == OMPAllocateDeclAttr::OMPDefaultMemAlloc &&
10417 !AA->getAllocator())
Alexey Bataev084b0c2f02019-03-21 20:36:16 +000010418 return Address::invalid();
Alexey Bataev084b0c2f02019-03-21 20:36:16 +000010419 llvm::Value *Size;
10420 CharUnits Align = CGM.getContext().getDeclAlign(CVD);
10421 if (CVD->getType()->isVariablyModifiedType()) {
10422 Size = CGF.getTypeSize(CVD->getType());
Alexey Bataev9c397812019-04-03 17:57:06 +000010423 // Align the size: ((size + align - 1) / align) * align
10424 Size = CGF.Builder.CreateNUWAdd(
10425 Size, CGM.getSize(Align - CharUnits::fromQuantity(1)));
10426 Size = CGF.Builder.CreateUDiv(Size, CGM.getSize(Align));
10427 Size = CGF.Builder.CreateNUWMul(Size, CGM.getSize(Align));
Alexey Bataev084b0c2f02019-03-21 20:36:16 +000010428 } else {
10429 CharUnits Sz = CGM.getContext().getTypeSizeInChars(CVD->getType());
Alexey Bataev084b0c2f02019-03-21 20:36:16 +000010430 Size = CGM.getSize(Sz.alignTo(Align));
Alexey Bataev4f680db2019-03-19 16:41:16 +000010431 }
Alexey Bataev084b0c2f02019-03-21 20:36:16 +000010432 llvm::Value *ThreadID = getThreadID(CGF, CVD->getBeginLoc());
10433 assert(AA->getAllocator() &&
10434 "Expected allocator expression for non-default allocator.");
10435 llvm::Value *Allocator = CGF.EmitScalarExpr(AA->getAllocator());
Alexey Bataev6cf7b712019-04-08 19:06:42 +000010436 // According to the standard, the original allocator type is a enum (integer).
10437 // Convert to pointer type, if required.
10438 if (Allocator->getType()->isIntegerTy())
10439 Allocator = CGF.Builder.CreateIntToPtr(Allocator, CGM.VoidPtrTy);
10440 else if (Allocator->getType()->isPointerTy())
10441 Allocator = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Allocator,
10442 CGM.VoidPtrTy);
Alexey Bataev084b0c2f02019-03-21 20:36:16 +000010443 llvm::Value *Args[] = {ThreadID, Size, Allocator};
10444
10445 llvm::Value *Addr =
10446 CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_alloc), Args,
10447 CVD->getName() + ".void.addr");
10448 llvm::Value *FiniArgs[OMPAllocateCleanupTy::CleanupArgs] = {ThreadID, Addr,
10449 Allocator};
10450 llvm::FunctionCallee FiniRTLFn = createRuntimeFunction(OMPRTL__kmpc_free);
10451
10452 CGF.EHStack.pushCleanup<OMPAllocateCleanupTy>(NormalAndEHCleanup, FiniRTLFn,
10453 llvm::makeArrayRef(FiniArgs));
10454 Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
10455 Addr,
10456 CGF.ConvertTypeForMem(CGM.getContext().getPointerType(CVD->getType())),
10457 CVD->getName() + ".addr");
10458 return Address(Addr, Align);
Gheorghe-Teodor Bercead3dcf2f2018-03-14 14:17:45 +000010459}
10460
James Y Knight9871db02019-02-05 16:42:33 +000010461llvm::Function *CGOpenMPSIMDRuntime::emitParallelOutlinedFunction(
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000010462 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
10463 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
10464 llvm_unreachable("Not supported in SIMD-only mode");
10465}
10466
James Y Knight9871db02019-02-05 16:42:33 +000010467llvm::Function *CGOpenMPSIMDRuntime::emitTeamsOutlinedFunction(
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000010468 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
10469 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen) {
10470 llvm_unreachable("Not supported in SIMD-only mode");
10471}
10472
James Y Knight9871db02019-02-05 16:42:33 +000010473llvm::Function *CGOpenMPSIMDRuntime::emitTaskOutlinedFunction(
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000010474 const OMPExecutableDirective &D, const VarDecl *ThreadIDVar,
10475 const VarDecl *PartIDVar, const VarDecl *TaskTVar,
10476 OpenMPDirectiveKind InnermostKind, const RegionCodeGenTy &CodeGen,
10477 bool Tied, unsigned &NumberOfParts) {
10478 llvm_unreachable("Not supported in SIMD-only mode");
10479}
10480
10481void CGOpenMPSIMDRuntime::emitParallelCall(CodeGenFunction &CGF,
10482 SourceLocation Loc,
James Y Knight9871db02019-02-05 16:42:33 +000010483 llvm::Function *OutlinedFn,
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000010484 ArrayRef<llvm::Value *> CapturedVars,
10485 const Expr *IfCond) {
10486 llvm_unreachable("Not supported in SIMD-only mode");
10487}
10488
10489void CGOpenMPSIMDRuntime::emitCriticalRegion(
10490 CodeGenFunction &CGF, StringRef CriticalName,
10491 const RegionCodeGenTy &CriticalOpGen, SourceLocation Loc,
10492 const Expr *Hint) {
10493 llvm_unreachable("Not supported in SIMD-only mode");
10494}
10495
10496void CGOpenMPSIMDRuntime::emitMasterRegion(CodeGenFunction &CGF,
10497 const RegionCodeGenTy &MasterOpGen,
10498 SourceLocation Loc) {
10499 llvm_unreachable("Not supported in SIMD-only mode");
10500}
10501
10502void CGOpenMPSIMDRuntime::emitTaskyieldCall(CodeGenFunction &CGF,
10503 SourceLocation Loc) {
10504 llvm_unreachable("Not supported in SIMD-only mode");
10505}
10506
10507void CGOpenMPSIMDRuntime::emitTaskgroupRegion(
10508 CodeGenFunction &CGF, const RegionCodeGenTy &TaskgroupOpGen,
10509 SourceLocation Loc) {
10510 llvm_unreachable("Not supported in SIMD-only mode");
10511}
10512
10513void CGOpenMPSIMDRuntime::emitSingleRegion(
10514 CodeGenFunction &CGF, const RegionCodeGenTy &SingleOpGen,
10515 SourceLocation Loc, ArrayRef<const Expr *> CopyprivateVars,
10516 ArrayRef<const Expr *> DestExprs, ArrayRef<const Expr *> SrcExprs,
10517 ArrayRef<const Expr *> AssignmentOps) {
10518 llvm_unreachable("Not supported in SIMD-only mode");
10519}
10520
10521void CGOpenMPSIMDRuntime::emitOrderedRegion(CodeGenFunction &CGF,
10522 const RegionCodeGenTy &OrderedOpGen,
10523 SourceLocation Loc,
10524 bool IsThreads) {
10525 llvm_unreachable("Not supported in SIMD-only mode");
10526}
10527
10528void CGOpenMPSIMDRuntime::emitBarrierCall(CodeGenFunction &CGF,
10529 SourceLocation Loc,
10530 OpenMPDirectiveKind Kind,
10531 bool EmitChecks,
10532 bool ForceSimpleCall) {
10533 llvm_unreachable("Not supported in SIMD-only mode");
10534}
10535
10536void CGOpenMPSIMDRuntime::emitForDispatchInit(
10537 CodeGenFunction &CGF, SourceLocation Loc,
10538 const OpenMPScheduleTy &ScheduleKind, unsigned IVSize, bool IVSigned,
10539 bool Ordered, const DispatchRTInput &DispatchValues) {
10540 llvm_unreachable("Not supported in SIMD-only mode");
10541}
10542
10543void CGOpenMPSIMDRuntime::emitForStaticInit(
10544 CodeGenFunction &CGF, SourceLocation Loc, OpenMPDirectiveKind DKind,
10545 const OpenMPScheduleTy &ScheduleKind, const StaticRTInput &Values) {
10546 llvm_unreachable("Not supported in SIMD-only mode");
10547}
10548
10549void CGOpenMPSIMDRuntime::emitDistributeStaticInit(
10550 CodeGenFunction &CGF, SourceLocation Loc,
10551 OpenMPDistScheduleClauseKind SchedKind, const StaticRTInput &Values) {
10552 llvm_unreachable("Not supported in SIMD-only mode");
10553}
10554
10555void CGOpenMPSIMDRuntime::emitForOrderedIterationEnd(CodeGenFunction &CGF,
10556 SourceLocation Loc,
10557 unsigned IVSize,
10558 bool IVSigned) {
10559 llvm_unreachable("Not supported in SIMD-only mode");
10560}
10561
10562void CGOpenMPSIMDRuntime::emitForStaticFinish(CodeGenFunction &CGF,
10563 SourceLocation Loc,
10564 OpenMPDirectiveKind DKind) {
10565 llvm_unreachable("Not supported in SIMD-only mode");
10566}
10567
10568llvm::Value *CGOpenMPSIMDRuntime::emitForNext(CodeGenFunction &CGF,
10569 SourceLocation Loc,
10570 unsigned IVSize, bool IVSigned,
10571 Address IL, Address LB,
10572 Address UB, Address ST) {
10573 llvm_unreachable("Not supported in SIMD-only mode");
10574}
10575
10576void CGOpenMPSIMDRuntime::emitNumThreadsClause(CodeGenFunction &CGF,
10577 llvm::Value *NumThreads,
10578 SourceLocation Loc) {
10579 llvm_unreachable("Not supported in SIMD-only mode");
10580}
10581
10582void CGOpenMPSIMDRuntime::emitProcBindClause(CodeGenFunction &CGF,
10583 OpenMPProcBindClauseKind ProcBind,
10584 SourceLocation Loc) {
10585 llvm_unreachable("Not supported in SIMD-only mode");
10586}
10587
10588Address CGOpenMPSIMDRuntime::getAddrOfThreadPrivate(CodeGenFunction &CGF,
10589 const VarDecl *VD,
10590 Address VDAddr,
10591 SourceLocation Loc) {
10592 llvm_unreachable("Not supported in SIMD-only mode");
10593}
10594
10595llvm::Function *CGOpenMPSIMDRuntime::emitThreadPrivateVarDefinition(
10596 const VarDecl *VD, Address VDAddr, SourceLocation Loc, bool PerformInit,
10597 CodeGenFunction *CGF) {
10598 llvm_unreachable("Not supported in SIMD-only mode");
10599}
10600
10601Address CGOpenMPSIMDRuntime::getAddrOfArtificialThreadPrivate(
10602 CodeGenFunction &CGF, QualType VarType, StringRef Name) {
10603 llvm_unreachable("Not supported in SIMD-only mode");
10604}
10605
10606void CGOpenMPSIMDRuntime::emitFlush(CodeGenFunction &CGF,
10607 ArrayRef<const Expr *> Vars,
10608 SourceLocation Loc) {
10609 llvm_unreachable("Not supported in SIMD-only mode");
10610}
10611
10612void CGOpenMPSIMDRuntime::emitTaskCall(CodeGenFunction &CGF, SourceLocation Loc,
10613 const OMPExecutableDirective &D,
James Y Knight9871db02019-02-05 16:42:33 +000010614 llvm::Function *TaskFunction,
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000010615 QualType SharedsTy, Address Shareds,
10616 const Expr *IfCond,
10617 const OMPTaskDataTy &Data) {
10618 llvm_unreachable("Not supported in SIMD-only mode");
10619}
10620
10621void CGOpenMPSIMDRuntime::emitTaskLoopCall(
10622 CodeGenFunction &CGF, SourceLocation Loc, const OMPLoopDirective &D,
James Y Knight9871db02019-02-05 16:42:33 +000010623 llvm::Function *TaskFunction, QualType SharedsTy, Address Shareds,
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000010624 const Expr *IfCond, const OMPTaskDataTy &Data) {
10625 llvm_unreachable("Not supported in SIMD-only mode");
10626}
10627
10628void CGOpenMPSIMDRuntime::emitReduction(
10629 CodeGenFunction &CGF, SourceLocation Loc, ArrayRef<const Expr *> Privates,
10630 ArrayRef<const Expr *> LHSExprs, ArrayRef<const Expr *> RHSExprs,
10631 ArrayRef<const Expr *> ReductionOps, ReductionOptionsTy Options) {
10632 assert(Options.SimpleReduction && "Only simple reduction is expected.");
10633 CGOpenMPRuntime::emitReduction(CGF, Loc, Privates, LHSExprs, RHSExprs,
10634 ReductionOps, Options);
10635}
10636
10637llvm::Value *CGOpenMPSIMDRuntime::emitTaskReductionInit(
10638 CodeGenFunction &CGF, SourceLocation Loc, ArrayRef<const Expr *> LHSExprs,
10639 ArrayRef<const Expr *> RHSExprs, const OMPTaskDataTy &Data) {
10640 llvm_unreachable("Not supported in SIMD-only mode");
10641}
10642
10643void CGOpenMPSIMDRuntime::emitTaskReductionFixups(CodeGenFunction &CGF,
10644 SourceLocation Loc,
10645 ReductionCodeGen &RCG,
10646 unsigned N) {
10647 llvm_unreachable("Not supported in SIMD-only mode");
10648}
10649
10650Address CGOpenMPSIMDRuntime::getTaskReductionItem(CodeGenFunction &CGF,
10651 SourceLocation Loc,
10652 llvm::Value *ReductionsPtr,
10653 LValue SharedLVal) {
10654 llvm_unreachable("Not supported in SIMD-only mode");
10655}
10656
10657void CGOpenMPSIMDRuntime::emitTaskwaitCall(CodeGenFunction &CGF,
10658 SourceLocation Loc) {
10659 llvm_unreachable("Not supported in SIMD-only mode");
10660}
10661
10662void CGOpenMPSIMDRuntime::emitCancellationPointCall(
10663 CodeGenFunction &CGF, SourceLocation Loc,
10664 OpenMPDirectiveKind CancelRegion) {
10665 llvm_unreachable("Not supported in SIMD-only mode");
10666}
10667
10668void CGOpenMPSIMDRuntime::emitCancelCall(CodeGenFunction &CGF,
10669 SourceLocation Loc, const Expr *IfCond,
10670 OpenMPDirectiveKind CancelRegion) {
10671 llvm_unreachable("Not supported in SIMD-only mode");
10672}
10673
10674void CGOpenMPSIMDRuntime::emitTargetOutlinedFunction(
10675 const OMPExecutableDirective &D, StringRef ParentName,
10676 llvm::Function *&OutlinedFn, llvm::Constant *&OutlinedFnID,
10677 bool IsOffloadEntry, const RegionCodeGenTy &CodeGen) {
10678 llvm_unreachable("Not supported in SIMD-only mode");
10679}
10680
10681void CGOpenMPSIMDRuntime::emitTargetCall(CodeGenFunction &CGF,
10682 const OMPExecutableDirective &D,
James Y Knight9871db02019-02-05 16:42:33 +000010683 llvm::Function *OutlinedFn,
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000010684 llvm::Value *OutlinedFnID,
James Y Knight9871db02019-02-05 16:42:33 +000010685 const Expr *IfCond,
10686 const Expr *Device) {
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000010687 llvm_unreachable("Not supported in SIMD-only mode");
10688}
10689
10690bool CGOpenMPSIMDRuntime::emitTargetFunctions(GlobalDecl GD) {
10691 llvm_unreachable("Not supported in SIMD-only mode");
10692}
10693
10694bool CGOpenMPSIMDRuntime::emitTargetGlobalVariable(GlobalDecl GD) {
10695 llvm_unreachable("Not supported in SIMD-only mode");
10696}
10697
10698bool CGOpenMPSIMDRuntime::emitTargetGlobal(GlobalDecl GD) {
10699 return false;
10700}
10701
10702llvm::Function *CGOpenMPSIMDRuntime::emitRegistrationFunction() {
10703 return nullptr;
10704}
10705
10706void CGOpenMPSIMDRuntime::emitTeamsCall(CodeGenFunction &CGF,
10707 const OMPExecutableDirective &D,
10708 SourceLocation Loc,
James Y Knight9871db02019-02-05 16:42:33 +000010709 llvm::Function *OutlinedFn,
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000010710 ArrayRef<llvm::Value *> CapturedVars) {
10711 llvm_unreachable("Not supported in SIMD-only mode");
10712}
10713
10714void CGOpenMPSIMDRuntime::emitNumTeamsClause(CodeGenFunction &CGF,
10715 const Expr *NumTeams,
10716 const Expr *ThreadLimit,
10717 SourceLocation Loc) {
10718 llvm_unreachable("Not supported in SIMD-only mode");
10719}
10720
10721void CGOpenMPSIMDRuntime::emitTargetDataCalls(
10722 CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond,
10723 const Expr *Device, const RegionCodeGenTy &CodeGen, TargetDataInfo &Info) {
10724 llvm_unreachable("Not supported in SIMD-only mode");
10725}
10726
10727void CGOpenMPSIMDRuntime::emitTargetDataStandAloneCall(
10728 CodeGenFunction &CGF, const OMPExecutableDirective &D, const Expr *IfCond,
10729 const Expr *Device) {
10730 llvm_unreachable("Not supported in SIMD-only mode");
10731}
10732
10733void CGOpenMPSIMDRuntime::emitDoacrossInit(CodeGenFunction &CGF,
Alexey Bataevf138fda2018-08-13 19:04:24 +000010734 const OMPLoopDirective &D,
10735 ArrayRef<Expr *> NumIterations) {
Alexey Bataeva8a9153a2017-12-29 18:07:07 +000010736 llvm_unreachable("Not supported in SIMD-only mode");
10737}
10738
10739void CGOpenMPSIMDRuntime::emitDoacrossOrdered(CodeGenFunction &CGF,
10740 const OMPDependClause *C) {
10741 llvm_unreachable("Not supported in SIMD-only mode");
10742}
10743
10744const VarDecl *
10745CGOpenMPSIMDRuntime::translateParameter(const FieldDecl *FD,
10746 const VarDecl *NativeParam) const {
10747 llvm_unreachable("Not supported in SIMD-only mode");
10748}
10749
10750Address
10751CGOpenMPSIMDRuntime::getParameterAddress(CodeGenFunction &CGF,
10752 const VarDecl *NativeParam,
10753 const VarDecl *TargetParam) const {
10754 llvm_unreachable("Not supported in SIMD-only mode");
10755}