16
16
#include " CGOmpSsRuntime.h"
17
17
#include " CGRecordLayout.h"
18
18
#include " CodeGenFunction.h"
19
+ #include " ConstantEmitter.h"
19
20
#include " clang/CodeGen/ConstantInitBuilder.h"
20
21
#include " clang/AST/Decl.h"
21
22
#include " clang/AST/StmtOmpSs.h"
23
+ #include " clang/AST/StmtVisitor.h"
22
24
#include " clang/Basic/BitmaskEnum.h"
23
25
#include " llvm/ADT/ArrayRef.h"
24
26
#include " llvm/Bitcode/BitcodeReader.h"
34
36
using namespace clang ;
35
37
using namespace CodeGen ;
36
38
39
+ class OSSDependVisitor
40
+ : public ConstStmtVisitor<OSSDependVisitor, void > {
41
+ CodeGenFunction &CGF;
42
+
43
+ llvm::Type *OSSArgTy;
44
+
45
+ llvm::Value *Ptr ;
46
+ SmallVector<llvm::Value *, 4 > Starts;
47
+ SmallVector<llvm::Value *, 4 > Ends;
48
+ SmallVector<llvm::Value *, 4 > Dims;
49
+ QualType BaseElementTy;
50
+
51
+ public:
52
+
53
+ OSSDependVisitor (CodeGenFunction &CGF)
54
+ : CGF(CGF),
55
+ OSSArgTy (CGF.ConvertType(CGF.getContext().LongTy))
56
+ {}
57
+
58
+ // ===--------------------------------------------------------------------===//
59
+ // Utilities
60
+ // ===--------------------------------------------------------------------===//
61
+
62
+ void FillBaseExprDimsAndType (const Expr *E) {
63
+ BaseElementTy = E->getType ();
64
+ if (const ConstantArrayType *BaseArrayTy = CGF.getContext ().getAsConstantArrayType (BaseElementTy)){
65
+ BaseElementTy = CGF.getContext ().getBaseElementType (BaseElementTy);
66
+ }
67
+ QualType TmpTy = E->getType ();
68
+ // Add Dimensions
69
+ if (TmpTy->isPointerType ()) {
70
+ // T *
71
+ Dims.push_back (llvm::ConstantInt::getSigned (OSSArgTy, 1 ));
72
+ } else if (!TmpTy->isArrayType ()) {
73
+ // T
74
+ Dims.push_back (llvm::ConstantInt::getSigned (OSSArgTy, 1 ));
75
+ }
76
+ while (const ConstantArrayType *BaseArrayTy = CGF.getContext ().getAsConstantArrayType (TmpTy)){
77
+ // T []
78
+ uint64_t DimSize = BaseArrayTy->getSize ().getSExtValue ();
79
+ Dims.push_back (llvm::ConstantInt::getSigned (OSSArgTy, DimSize));
80
+ TmpTy = BaseArrayTy->getElementType ();
81
+ }
82
+ }
83
+
84
+ // ===--------------------------------------------------------------------===//
85
+ // Visitor Methods
86
+ // ===--------------------------------------------------------------------===//
87
+
88
+ void Visit (const Expr *E) {
89
+ ConstStmtVisitor<OSSDependVisitor, void >::Visit (E);
90
+ }
91
+
92
+ void VisitStmt (const Stmt *S) {
93
+ llvm_unreachable (" Unhandled stmt" );
94
+ }
95
+
96
+ void VisitExpr (const Expr *E) {
97
+ llvm_unreachable (" Unhandled expr" );
98
+ }
99
+
100
+ // l-values.
101
+ void VisitDeclRefExpr (const DeclRefExpr *E) {
102
+ Ptr = CGF.EmitDeclRefLValue (E).getPointer ();
103
+ FillBaseExprDimsAndType (E);
104
+ }
105
+
106
+ void VisitArraySubscriptExpr (const ArraySubscriptExpr *E) {
107
+ BaseElementTy = E->getType ();
108
+ // Get Base Type
109
+ if (const ConstantArrayType *BaseArrayTy = CGF.getContext ().getAsConstantArrayType (BaseElementTy)){
110
+ BaseElementTy = CGF.getContext ().getBaseElementType (BaseElementTy);
111
+ }
112
+ // Get the inner expr
113
+ const Expr *Expr = E;
114
+ while (const ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(Expr->IgnoreParenImpCasts ())) {
115
+ Expr = ASE->getBase ();
116
+ // Add indexes
117
+ llvm::Value *Idx = ConstantEmitter (CGF).emitAbstract (ASE->getIdx (),
118
+ ASE->getIdx ()->getType ());
119
+ Idx = CGF.Builder .CreateSExt (Idx, OSSArgTy);
120
+ llvm::Value *IdxEnd = CGF.Builder .CreateAdd (Idx, llvm::ConstantInt::getSigned (OSSArgTy, 1 ));
121
+ Starts.push_back (Idx);
122
+ Ends.push_back (IdxEnd);
123
+ if (Expr->IgnoreParenImpCasts ()->getType ()->isPointerType ())
124
+ break ;
125
+ }
126
+
127
+ Ptr = CGF.EmitScalarExpr (Expr);
128
+
129
+ if (const CastExpr *CE = dyn_cast<CastExpr>(Expr)) {
130
+ QualType TmpTy = CE->getType ();
131
+ // Add Dimensions
132
+ if (TmpTy->isPointerType ()) {
133
+ // T (*)[]
134
+ Dims.push_back (llvm::ConstantInt::getSigned (OSSArgTy, 1 ));
135
+ TmpTy = cast<PointerType>(TmpTy)->getPointeeType ();
136
+ while (const ConstantArrayType *BaseArrayTy = CGF.getContext ().getAsConstantArrayType (TmpTy)){
137
+ // T []
138
+ uint64_t DimSize = BaseArrayTy->getSize ().getSExtValue ();
139
+ Dims.push_back (llvm::ConstantInt::getSigned (OSSArgTy, DimSize));
140
+ TmpTy = BaseArrayTy->getElementType ();
141
+ }
142
+ } else {
143
+ // T *
144
+ Dims.push_back (llvm::ConstantInt::getSigned (OSSArgTy, 1 ));
145
+ }
146
+ }
147
+ }
148
+
149
+ void VisitMemberExpr (const MemberExpr *E) {
150
+ Ptr = CGF.EmitMemberExpr (E).getPointer ();
151
+ FillBaseExprDimsAndType (E);
152
+ }
153
+
154
+ void VisitUnaryDeref (const UnaryOperator *E) {
155
+ Ptr = CGF.EmitUnaryOpLValue (E).getPointer ();
156
+ FillBaseExprDimsAndType (E);
157
+ }
158
+
159
+ ArrayRef<llvm::Value *> getStarts () const {
160
+ return Starts;
161
+ }
162
+
163
+ ArrayRef<llvm::Value *> getEnds () const {
164
+ return Ends;
165
+ }
166
+
167
+ ArrayRef<llvm::Value *> getDims () const {
168
+ return Dims;
169
+ }
170
+
171
+ QualType getBaseElementTy () {
172
+ return BaseElementTy;
173
+ }
174
+
175
+ llvm::Value *getPtr () {
176
+ return Ptr ;
177
+ }
178
+
179
+ };
180
+
181
+ static void EmitDSA (StringRef Name, CodeGenFunction &CGF, const Expr *E,
182
+ SmallVectorImpl<llvm::OperandBundleDef> &TaskInfo) {
183
+ if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
184
+ TaskInfo.emplace_back (Name, CGF.EmitDeclRefLValue (DRE).getPointer ());
185
+ }
186
+ else {
187
+ llvm_unreachable (" Unhandled expression" );
188
+ }
189
+ }
190
+
191
+ static void EmitDependency (StringRef Name, CodeGenFunction &CGF, const Expr *E,
192
+ SmallVectorImpl<llvm::OperandBundleDef> &TaskInfo) {
193
+
194
+ // C long -> LLVM long
195
+ llvm::Type *OSSArgTy = CGF.ConvertType (CGF.getContext ().LongTy );
196
+
197
+ OSSDependVisitor DepVisitor (CGF);
198
+ DepVisitor.Visit (E);
199
+
200
+ SmallVector<llvm::Value*, 4 > DepData;
201
+
202
+ SmallVector<llvm::Value *, 4 > Starts (
203
+ DepVisitor.getStarts ().begin (),
204
+ DepVisitor.getStarts ().end ());
205
+
206
+ SmallVector<llvm::Value *, 4 > Ends (
207
+ DepVisitor.getEnds ().begin (),
208
+ DepVisitor.getEnds ().end ());
209
+
210
+ SmallVector<llvm::Value *, 4 > Dims (
211
+ DepVisitor.getDims ().begin (),
212
+ DepVisitor.getDims ().end ());
213
+ QualType BaseElementTy = DepVisitor.getBaseElementTy ();
214
+ llvm::Value *Ptr = DepVisitor.getPtr ();
215
+
216
+ uint64_t BaseElementSize =
217
+ CGF.CGM
218
+ .getDataLayout ()
219
+ .getTypeSizeInBits (CGF
220
+ .ConvertType (BaseElementTy))/8 ;
221
+
222
+ DepData.push_back (Ptr );
223
+ bool First = true ;
224
+ for (size_t i = Dims.size () - 1 ; i > 0 ; --i) {
225
+ llvm::Value *Dim = Dims[i];
226
+ llvm::Value *IdxStart;
227
+ llvm::Value *IdxEnd;
228
+ // In arrays we have to output all dimensions, but
229
+ // the number of indices may be less than the number
230
+ // of dimensions (array[1] -> int array[10][20])
231
+ if (i < Starts.size ()) {
232
+ IdxStart = Starts[Starts.size () - i - 1 ];
233
+ IdxEnd = Ends[Starts.size () - i - 1 ];
234
+ } else {
235
+ IdxStart = llvm::ConstantInt::getSigned (OSSArgTy, 0 );
236
+ IdxEnd = Dim;
237
+ }
238
+ if (First) {
239
+ First = false ;
240
+ Dim = CGF.Builder .CreateMul (Dim,
241
+ llvm::ConstantInt::getSigned (OSSArgTy,
242
+ BaseElementSize));
243
+ IdxStart = CGF.Builder .CreateMul (IdxStart,
244
+ llvm::ConstantInt::getSigned (OSSArgTy,
245
+ BaseElementSize));
246
+ IdxEnd = CGF.Builder .CreateMul (IdxEnd,
247
+ llvm::ConstantInt::getSigned (OSSArgTy,
248
+ BaseElementSize));
249
+ }
250
+ DepData.push_back (Dim);
251
+ DepData.push_back (IdxStart);
252
+ DepData.push_back (IdxEnd);
253
+ }
254
+ llvm::Value *Dim = Dims[0 ];
255
+ llvm::Value *IdxStart;
256
+ llvm::Value *IdxEnd;
257
+ if (Starts.size () > 0 ) {
258
+ IdxStart = Starts[Starts.size () - 1 ];
259
+ IdxEnd = Ends[Starts.size () - 1 ];
260
+ } else {
261
+ IdxStart = llvm::ConstantInt::getSigned (OSSArgTy, 0 );
262
+ IdxEnd = Dim;
263
+ }
264
+
265
+ if (First) {
266
+ First = false ;
267
+ Dim = CGF.Builder .CreateMul (Dim,
268
+ llvm::ConstantInt::getSigned (OSSArgTy,
269
+ BaseElementSize));
270
+ IdxStart = CGF.Builder .CreateMul (IdxStart,
271
+ llvm::ConstantInt::getSigned (OSSArgTy,
272
+ BaseElementSize));
273
+ IdxEnd = CGF.Builder .CreateMul (IdxEnd,
274
+ llvm::ConstantInt::getSigned (OSSArgTy,
275
+ BaseElementSize));
276
+ }
277
+ DepData.push_back (Dim);
278
+ DepData.push_back (IdxStart);
279
+ DepData.push_back (IdxEnd);
280
+
281
+ TaskInfo.emplace_back (Name, makeArrayRef (DepData));
282
+ }
283
+
37
284
void CGOmpSsRuntime::emitTaskwaitCall (CodeGenFunction &CGF,
38
285
SourceLocation Loc) {
39
286
llvm::Value *Callee = CGM.getIntrinsic (llvm::Intrinsic::directive_marker);
@@ -53,34 +300,31 @@ void CGOmpSsRuntime::emitTaskCall(CodeGenFunction &CGF,
53
300
SmallVector<llvm::OperandBundleDef, 8 > TaskInfo;
54
301
TaskInfo.emplace_back (" DIR.OSS" , llvm::ConstantDataArray::getString (CGM.getLLVMContext (), " TASK" ));
55
302
for (const Expr *E : Data.SharedVars ) {
56
- const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl ());
57
- if (VD->hasLocalStorage ()) {
58
- Address Addr = CGF.GetAddrOfLocalVar (VD);
59
- TaskInfo.emplace_back (" QUAL.OSS.SHARED" , Addr.getPointer ());
60
- }
61
- else {
62
- TaskInfo.emplace_back (" QUAL.OSS.SHARED" , CGM.GetAddrOfGlobalVar (VD));
63
- }
303
+ EmitDSA (" QUAL.OSS.SHARED" , CGF, E, TaskInfo);
64
304
}
65
305
for (const Expr *E : Data.PrivateVars ) {
66
- const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl ());
67
- if (VD->hasLocalStorage ()) {
68
- Address Addr = CGF.GetAddrOfLocalVar (VD);
69
- TaskInfo.emplace_back (" QUAL.OSS.PRIVATE" , Addr.getPointer ());
70
- }
71
- else {
72
- TaskInfo.emplace_back (" QUAL.OSS.PRIVATE" , CGM.GetAddrOfGlobalVar (VD));
73
- }
306
+ EmitDSA (" QUAL.OSS.PRIVATE" , CGF, E, TaskInfo);
74
307
}
75
308
for (const Expr *E : Data.FirstprivateVars ) {
76
- const auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl ());
77
- if (VD->hasLocalStorage ()) {
78
- Address Addr = CGF.GetAddrOfLocalVar (VD);
79
- TaskInfo.emplace_back (" QUAL.OSS.FIRSTPRIVATE" , Addr.getPointer ());
80
- }
81
- else {
82
- TaskInfo.emplace_back (" QUAL.OSS.FIRSTPRIVATE" , CGM.GetAddrOfGlobalVar (VD));
83
- }
309
+ EmitDSA (" QUAL.OSS.FIRSTPRIVATE" , CGF, E, TaskInfo);
310
+ }
311
+ for (const Expr *E : Data.DependIn ) {
312
+ EmitDependency (" QUAL.OSS.DEP.IN" , CGF, E, TaskInfo);
313
+ }
314
+ for (const Expr *E : Data.DependOut ) {
315
+ EmitDependency (" QUAL.OSS.DEP.OUT" , CGF, E, TaskInfo);
316
+ }
317
+ for (const Expr *E : Data.DependInout ) {
318
+ EmitDependency (" QUAL.OSS.DEP.INOUT" , CGF, E, TaskInfo);
319
+ }
320
+ for (const Expr *E : Data.DependWeakIn ) {
321
+ EmitDependency (" QUAL.OSS.DEP.WEAKIN" , CGF, E, TaskInfo);
322
+ }
323
+ for (const Expr *E : Data.DependWeakOut ) {
324
+ EmitDependency (" QUAL.OSS.DEP.WEAKOUT" , CGF, E, TaskInfo);
325
+ }
326
+ for (const Expr *E : Data.DependWeakInout ) {
327
+ EmitDependency (" QUAL.OSS.DEP.WEAKINOUT" , CGF, E, TaskInfo);
84
328
}
85
329
86
330
llvm::Value *Result =
0 commit comments