clang: lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13#include
14
16
19 mlir::Type opTy,
20 mlir::Location loc,
21 size_t numBounds,
22 bool isInit) {
24 types.reserve(numBounds + 2);
25 types.push_back(opTy);
26
27
28
29 if (!isInit)
30 types.push_back(opTy);
31
32 auto boundsTy = mlir::acc::DataBoundsType::get(&cgf.getMLIRContext());
33 for (size_t i = 0; i < numBounds; ++i)
34 types.push_back(boundsTy);
35
37 return builder.createBlock(®ion, region.end(), types, locs);
38}
39void OpenACCRecipeBuilderBase::makeAllocaCopy(mlir::Location loc,
40 mlir::Type copyType,
41 mlir::Value numEltsToCopy,
42 mlir::Value offsetPerSubarray,
43 mlir::Value destAlloca,
44 mlir::Value srcAlloca) {
45 mlir::OpBuilder::InsertionGuard guardCase(builder);
46
48 auto itrPtrTy = cir::PointerType::get(itrTy);
49 mlir::IntegerAttr itrAlign =
52
53 auto loopBuilder = [&]() {
54 auto itr =
55 cir::AllocaOp::create(builder, loc, itrPtrTy, itrTy, "itr", itrAlign);
57 builder.CIRBaseBuilderTy::createStore(loc, constZero, itr);
59 loc,
60
61 [&](mlir::OpBuilder &b, mlir::Location loc) {
62
63
64
65
66 if (!numEltsToCopy)
68
69 auto loadCur = cir::LoadOp::create(builder, loc, {itr});
71 numEltsToCopy);
73 },
74
75 [&](mlir::OpBuilder &b, mlir::Location loc) {
76
77 auto loadCur = cir::LoadOp::create(builder, loc, {itr});
78 auto srcOffset = builder.createMul(loc, offsetPerSubarray, loadCur);
79
80 auto ptrToOffsetIntoSrc = cir::PtrStrideOp::create(
81 builder, loc, copyType, srcAlloca, srcOffset);
82
83 auto offsetIntoDecayDest = cir::PtrStrideOp::create(
84 builder, loc, builder.getPointerTo(copyType), destAlloca,
85 loadCur);
86
87 builder.CIRBaseBuilderTy::createStore(loc, ptrToOffsetIntoSrc,
88 offsetIntoDecayDest);
90 },
91
92 [&](mlir::OpBuilder &b, mlir::Location loc) {
93
94 auto load = cir::LoadOp::create(builder, loc, {itr});
95 auto inc = cir::UnaryOp::create(builder, loc, load.getType(),
96 cir::UnaryOpKind::Inc, load);
97 builder.CIRBaseBuilderTy::createStore(loc, inc, itr);
99 });
100 };
101
102 cir::ScopeOp::create(builder, loc,
103 [&](mlir::OpBuilder &b, mlir::Location loc) {
104 loopBuilder();
105 builder.createYield(loc);
106 });
107}
108
109mlir::Value OpenACCRecipeBuilderBase::makeBoundsAlloca(
110 mlir::Block *block, SourceRange exprRange, mlir::Location loc,
111 std::string_view allocaName, size_t numBounds,
112 llvm::ArrayRef boundTypes) {
113 mlir::OpBuilder::InsertionGuard guardCase(builder);
114
115
116 llvm::ArrayRefmlir::BlockArgument boundsRange =
117 block->getArguments().drop_front(1);
118
119
120
121
122 assert(boundsRange.size() + 1 == boundTypes.size());
123
124 mlir::Type itrTy = cgf.cgm.convertType(cgf.getContext().UnsignedLongLongTy);
125 auto idxType = mlir::IndexType::get(&cgf.getMLIRContext());
126
127 auto getUpperBound = [&](mlir::Value bound) {
128 auto upperBoundVal =
129 mlir::acc::GetUpperboundOp::create(builder, loc, idxType, bound);
130 return mlir::UnrealizedConversionCastOp::create(builder, loc, itrTy,
131 upperBoundVal.getResult())
132 .getResult(0);
133 };
134
135 auto isArrayTy = [&](QualType ty) {
136 if (ty->isArrayType() && !ty->isConstantArrayType())
137 cgf.cgm.errorNYI(exprRange, "OpenACC recipe init for VLAs");
138 return ty->isConstantArrayType();
139 };
140
141 mlir::Type topLevelTy = cgf.convertType(boundTypes.back());
142 cir::PointerType topLevelTyPtr = builder.getPointerTo(topLevelTy);
143
144 mlir::Value initialAlloca = builder.createAlloca(
145 loc, topLevelTyPtr, topLevelTy, allocaName,
146 cgf.getContext().getTypeAlignInChars(boundTypes.back()));
147
148 bool lastBoundWasArray = isArrayTy(boundTypes.back());
149
150
151
152 mlir::Value lastAlloca = initialAlloca;
153
154
155
156
157 llvm::ArrayRef boundResults = boundTypes.drop_back(1);
158
159
160 llvm::SmallVector allocasLeftArr;
161 llvm::ArrayRef resultTypes = boundTypes.drop_front();
162 std::transform_inclusive_scan(
163 resultTypes.begin(), resultTypes.end(),
164 std::back_inserter(allocasLeftArr), std::plus{},
165 [](QualType ty) { return !ty->isConstantArrayType(); }, false);
166
167
168
169 mlir::Value cumulativeElts;
170 for (auto [bound, resultType, allocasLeft] : llvm::reverse(
171 llvm::zip_equal(boundsRange, boundResults, allocasLeftArr))) {
172
173
174
175 if (!allocasLeft)
176 break;
177
178
179 mlir::Value eltsPerSubArray = getUpperBound(bound);
180 mlir::Value eltsToAlloca;
181
182
183
184
185
186 if (cumulativeElts)
187 eltsToAlloca = builder.createMul(loc, eltsPerSubArray, cumulativeElts);
188 else
189 eltsToAlloca = eltsPerSubArray;
190
191 if (!lastBoundWasArray) {
192
193
194 TypeInfoChars eltInfo = cgf.getContext().getTypeInfoInChars(resultType);
195 cir::ConstantOp eltSize = builder.getConstInt(
196 loc, itrTy, eltInfo.Width.alignTo(eltInfo.Align).getQuantity());
197 mlir::Value curSize = builder.createMul(loc, eltsToAlloca, eltSize);
198
199 mlir::Type eltTy = cgf.convertType(resultType);
200 cir::PointerType ptrTy = builder.getPointerTo(eltTy);
201 mlir::Value curAlloca = builder.createAlloca(
202 loc, ptrTy, eltTy, "openacc.init.bounds",
203 cgf.getContext().getTypeAlignInChars(resultType), curSize);
204
205 makeAllocaCopy(loc, ptrTy, cumulativeElts, eltsPerSubArray, lastAlloca,
206 curAlloca);
207 lastAlloca = curAlloca;
208 } else {
209
210
211
212 cir::ConstantOp constZero = builder.getConstInt(loc, itrTy, 0);
213 lastAlloca = builder.getArrayElement(loc, loc, lastAlloca,
214 cgf.convertType(resultType),
215 constZero, true);
216 }
217
218 cumulativeElts = eltsToAlloca;
219 lastBoundWasArray = isArrayTy(resultType);
220 }
221 return initialAlloca;
222}
223
225 mlir::Value subscriptedValue, mlir::Value subscriptedValue2,
226 mlir::Value bound, mlir::Location loc, bool inverse) {
227 mlir::Operation *bodyInsertLoc;
228
229 mlir::Type itrTy = cgf.cgm.convertType(cgf.getContext().UnsignedLongLongTy);
230 auto itrPtrTy = cir::PointerType::get(itrTy);
231 mlir::IntegerAttr itrAlign =
232 cgf.cgm.getSize(cgf.getContext().getTypeAlignInChars(
233 cgf.getContext().UnsignedLongLongTy));
234 auto idxType = mlir::IndexType::get(&cgf.getMLIRContext());
235
236 auto doSubscriptOp = [&](mlir::Value subVal,
237 cir::LoadOp idxLoad) -> mlir::Value {
239
240 if (auto arrayTy = dyn_castcir::ArrayType(eltTy))
241 return builder.getArrayElement(loc, loc, subVal, arrayTy.getElementType(),
242 idxLoad,
243 true);
244
246
247 auto eltLoad = cir::LoadOp::create(builder, loc, {subVal});
248
249 return cir::PtrStrideOp::create(builder, loc, eltLoad.getType(), eltLoad,
250 idxLoad);
251 };
252
253 auto forStmtBuilder = [&]() {
254
255 auto lowerBoundVal =
256 mlir::acc::GetLowerboundOp::create(builder, loc, idxType, bound);
257 auto lbConversion = mlir::UnrealizedConversionCastOp::create(
258 builder, loc, itrTy, lowerBoundVal.getResult());
259 auto upperBoundVal =
260 mlir::acc::GetUpperboundOp::create(builder, loc, idxType, bound);
261 auto ubConversion = mlir::UnrealizedConversionCastOp::create(
262 builder, loc, itrTy, upperBoundVal.getResult());
263
264
265 auto itr =
266 cir::AllocaOp::create(builder, loc, itrPtrTy, itrTy, "iter", itrAlign);
267
268
269 if (inverse) {
270 cir::ConstantOp constOne = builder.getConstInt(loc, itrTy, 1);
271
272 auto sub = cir::BinOp::create(builder, loc, itrTy, cir::BinOpKind::Sub,
273 ubConversion.getResult(0), constOne);
274
275
276 builder.CIRBaseBuilderTy::createStore(loc, sub, itr);
277 } else {
278
279 builder.CIRBaseBuilderTy::createStore(loc, lbConversion.getResult(0),
280 itr);
281 }
282
283
284
285 auto endItr = inverse ? lbConversion : ubConversion;
286
288 loc,
289
290 [&](mlir::OpBuilder &b, mlir::Location loc) {
291 auto loadCur = cir::LoadOp::create(builder, loc, {itr});
292
293 auto cmp = builder.createCompare(
294 loc, inverse ? cir::CmpOpKind::ge : cir::CmpOpKind::lt, loadCur,
295 endItr.getResult(0));
296 builder.createCondition(cmp);
297 },
298
299 [&](mlir::OpBuilder &b, mlir::Location loc) {
300 auto load = cir::LoadOp::create(builder, loc, {itr});
301
302 if (subscriptedValue)
303 subscriptedValue = doSubscriptOp(subscriptedValue, load);
304 if (subscriptedValue2)
305 subscriptedValue2 = doSubscriptOp(subscriptedValue2, load);
306 bodyInsertLoc = builder.createYield(loc);
307 },
308
309 [&](mlir::OpBuilder &b, mlir::Location loc) {
310 auto load = cir::LoadOp::create(builder, loc, {itr});
311 auto unary = cir::UnaryOp::create(
312 builder, loc, load.getType(),
313 inverse ? cir::UnaryOpKind::Dec : cir::UnaryOpKind::Inc, load);
314 builder.CIRBaseBuilderTy::createStore(loc, unary, itr);
315 builder.createYield(loc);
316 });
317 };
318
319 cir::ScopeOp::create(builder, loc,
320 [&](mlir::OpBuilder &b, mlir::Location loc) {
321 forStmtBuilder();
322 builder.createYield(loc);
323 });
324
325
326
327 builder.setInsertionPoint(bodyInsertLoc);
328 return {subscriptedValue, subscriptedValue2};
329}
330
331mlir::acc::ReductionOperator
333 switch (op) {
335 return mlir::acc::ReductionOperator::AccAdd;
337 return mlir::acc::ReductionOperator::AccMul;
339 return mlir::acc::ReductionOperator::AccMax;
341 return mlir::acc::ReductionOperator::AccMin;
343 return mlir::acc::ReductionOperator::AccIand;
345 return mlir::acc::ReductionOperator::AccIor;
347 return mlir::acc::ReductionOperator::AccXor;
349 return mlir::acc::ReductionOperator::AccLand;
351 return mlir::acc::ReductionOperator::AccLor;
353 llvm_unreachable("invalid reduction operator");
354 }
355
356 llvm_unreachable("invalid reduction operator");
357}
358
359
360
361
362
364 mlir::Location loc, mlir::Location locEnd, mlir::Value mainOp,
366 mlir::Region &destroyRegion) {
367 mlir::Block *block = createRecipeBlock(destroyRegion, mainOp.getType(), loc,
368 numBounds, false);
369 builder.setInsertionPointToEnd(&destroyRegion.back());
371
372 mlir::Type elementTy =
373 mlir::castcir::PointerType(mainOp.getType()).getPointee();
374 auto emitDestroy = [&](mlir::Value var, mlir::Type ty) {
375 Address addr{var, ty, alignment};
376 cgf.emitDestroy(addr, origType,
378 };
379
380 if (numBounds) {
381 mlir::OpBuilder::InsertionGuard guardCase(builder);
382
383
385 block->getArguments().drop_front(2);
386
387 mlir::Value subscriptedValue = block->getArgument(1);
388 for (mlir::BlockArgument boundArg : llvm::reverse(boundsRange))
389 subscriptedValue = createBoundsLoop(subscriptedValue, boundArg, loc,
390 true);
391
392 emitDestroy(subscriptedValue, cgf.cgm.convertType(origType));
393 } else {
394
395
396
397
398 emitDestroy(block->getArgument(1), elementTy);
399 }
400
402 mlir::acc::YieldOp::create(builder, locEnd);
403}
404void OpenACCRecipeBuilderBase::makeBoundsInit(
405 mlir::Value alloca, mlir::Location loc, mlir::Block *block,
406 const VarDecl *allocaDecl, QualType origType, bool isInitSection) {
407 mlir::OpBuilder::InsertionGuard guardCase(builder);
408 builder.setInsertionPointToEnd(block);
410
413
414
415
416
418 block->getArguments().drop_front(isInitSection ? 1 : 2);
419
420 mlir::Value subscriptedValue = alloca;
421 for (mlir::BlockArgument boundArg : llvm::reverse(boundsRange))
422 subscriptedValue = createBoundsLoop(subscriptedValue, boundArg, loc,
423 false);
424
429}
430
431
432
433
435 mlir::Location loc, mlir::Location locEnd, SourceRange exprRange,
436 mlir::Value mainOp, mlir::Region &recipeInitRegion, size_t numBounds,
438 QualType origType, bool emitInitExpr) {
439 assert(allocaDecl && "Required recipe variable not set?");
441
442 mlir::Block *block = createRecipeBlock(recipeInitRegion, mainOp.getType(),
443 loc, numBounds, true);
444 builder.setInsertionPointToEnd(&recipeInitRegion.back());
446
447 const Type *allocaPointeeType =
449
450
451 if (cgf.getContext().getLangOpts().CPlusPlus && !allocaDecl->getInit() &&
455
456
457
458
459
460 cgf.cgm.errorNYI(exprRange, "private/reduction default-init recipe");
461 }
462
463 if (!numBounds) {
464
465
467 cgf.emitAutoVarAlloca(*allocaDecl, builder.saveInsertionPoint());
468 if (emitInitExpr)
469 cgf.emitAutoVarInit(tempDeclEmission);
470 } else {
471 mlir::Value alloca = makeBoundsAlloca(
472 block, exprRange, loc, allocaDecl->getName(), numBounds, boundTypes);
473
474
475
476 if (emitInitExpr && allocaDecl->getInit() &&
477 (.isTrivialInitializer(allocaDecl->getInit()) ||
478 cgf.getContext().getLangOpts().getTrivialAutoVarInit() !=
480 makeBoundsInit(alloca, loc, block, allocaDecl, origType,
481 true);
482 }
483
485 mlir::acc::YieldOp::create(builder, locEnd);
486}
487
489 mlir::Location loc, mlir::Location locEnd, mlir::Value mainOp,
491 mlir::Region ©Region, size_t numBounds) {
492 mlir::Block *block = createRecipeBlock(copyRegion, mainOp.getType(), loc,
493 numBounds, false);
494 builder.setInsertionPointToEnd(©Region.back());
496
497 mlir::Value fromArg = block->getArgument(0);
498 mlir::Value toArg = block->getArgument(1);
499
501 block->getArguments().drop_front(2);
502
503 for (mlir::BlockArgument boundArg : llvm::reverse(boundsRange))
504 std::tie(fromArg, toArg) =
505 createBoundsLoop(fromArg, toArg, boundArg, loc, false);
506
507
508 mlir::Type elementTy =
509 mlir::castcir::PointerType(toArg.getType()).getPointee();
513 Address{toArg, elementTy, cgf.getContext().getDeclAlign(allocaDecl)});
514
515
517 cgf.setAddrOfLocalVar(
518 temporary,
519 Address{fromArg, elementTy, cgf.getContext().getDeclAlign(allocaDecl)});
520 cgf.emitAutoVarInit(tempDeclEmission);
521
522 builder.setInsertionPointToEnd(©Region.back());
524 mlir::acc::YieldOp::create(builder, locEnd);
525}
526
527
528
529
530
532 mlir::Location loc, mlir::Location locEnd, mlir::Value mainOp,
533 mlir::acc::ReductionRecipeOp recipe, size_t numBounds, QualType origType,
535 mlir::Block *block =
536 createRecipeBlock(recipe.getCombinerRegion(), mainOp.getType(), loc,
537 numBounds, false);
538 builder.setInsertionPointToEnd(&recipe.getCombinerRegion().back());
540
541 mlir::Value lhsArg = block->getArgument(0);
542 mlir::Value rhsArg = block->getArgument(1);
544 block->getArguments().drop_front(2);
545
546 if (llvm::any_of(combinerRecipes, [](auto &r) { return r.Op == nullptr; })) {
547 cgf.cgm.errorNYI(loc, "OpenACC Reduction combiner not generated");
548 mlir::acc::YieldOp::create(builder, locEnd, block->getArgument(0));
549 return;
550 }
551
552
553 for (mlir::BlockArgument boundArg : llvm::reverse(boundsRange))
554 std::tie(lhsArg, rhsArg) =
555 createBoundsLoop(lhsArg, rhsArg, boundArg, loc, false);
556
557
558
559
560 auto emitSingleCombiner =
561 [&](mlir::Value lhsArg, mlir::Value rhsArg,
563 mlir::Type elementTy =
564 mlir::castcir::PointerType(lhsArg.getType()).getPointee();
566 cgf.setAddrOfLocalVar(
567 combiner.LHS, Address{lhsArg, elementTy,
568 cgf.getContext().getDeclAlign(combiner.LHS)});
570 cgf.setAddrOfLocalVar(
571 combiner.RHS, Address{rhsArg, elementTy,
572 cgf.getContext().getDeclAlign(combiner.RHS)});
573
574 [[maybe_unused]] mlir::LogicalResult stmtRes =
575 cgf.emitStmt(combiner.Op, true);
576 };
577
578
579
580
581
582 auto emitCombiner = [&](mlir::Value lhsArg, mlir::Value rhsArg, QualType ty) {
583 assert(!ty->isArrayType() && "Array type shouldn't get here");
584 if (const auto *rd = ty->getAsRecordDecl()) {
585 if (combinerRecipes.size() == 1 &&
586 cgf.getContext().hasSameType(ty, combinerRecipes[0].LHS->getType())) {
587
588
589 emitSingleCombiner(lhsArg, rhsArg, combinerRecipes[0]);
590 } else {
591
592
594 cgf.cgm.getTypes().getCIRGenRecordLayout(rd);
595 for (const auto &[field, combiner] :
596 llvm::zip_equal(rd->fields(), combinerRecipes)) {
597 mlir::Type fieldType = cgf.convertType(field->getType());
598 auto fieldPtr = cir::PointerType::get(fieldType);
599 unsigned fieldIndex = layout.getCIRFieldNo(field);
600
601 mlir::Value lhsField = builder.createGetMember(
602 loc, fieldPtr, lhsArg, field->getName(), fieldIndex);
603 mlir::Value rhsField = builder.createGetMember(
604 loc, fieldPtr, rhsArg, field->getName(), fieldIndex);
605
606 emitSingleCombiner(lhsField, rhsField, combiner);
607 }
608 }
609
610 } else {
611
612
613 emitSingleCombiner(lhsArg, rhsArg, combinerRecipes[0]);
614 }
615 };
616
617 if (const auto *cat = cgf.getContext().getAsConstantArrayType(origType)) {
618
619
620 auto itrTy = mlir::castcir::IntType(cgf.ptrDiffTy);
621 auto itrPtrTy = cir::PointerType::get(itrTy);
622
623 mlir::Value zero =
624 builder.getConstInt(loc, mlir::castcir::IntType(cgf.ptrDiffTy), 0);
625 mlir::Value itr =
626 cir::AllocaOp::create(builder, loc, itrPtrTy, itrTy, "itr",
627 cgf.cgm.getSize(cgf.getPointerAlign()));
628 builder.CIRBaseBuilderTy::createStore(loc, zero, itr);
629
631 loc,
632
633 [&](mlir::OpBuilder &b, mlir::Location loc) {
634 auto loadItr = cir::LoadOp::create(builder, loc, {itr});
635 mlir::Value arraySize = builder.getConstInt(
636 loc, mlir::castcir::IntType(cgf.ptrDiffTy), cat->getZExtSize());
637 auto cmp = builder.createCompare(loc, cir::CmpOpKind::lt, loadItr,
638 arraySize);
639 builder.createCondition(cmp);
640 },
641
642 [&](mlir::OpBuilder &b, mlir::Location loc) {
643 auto loadItr = cir::LoadOp::create(builder, loc, {itr});
644 auto lhsElt = builder.getArrayElement(
645 loc, loc, lhsArg, cgf.convertType(cat->getElementType()), loadItr,
646 true);
647 auto rhsElt = builder.getArrayElement(
648 loc, loc, rhsArg, cgf.convertType(cat->getElementType()), loadItr,
649 true);
650
651 emitCombiner(lhsElt, rhsElt, cat->getElementType());
652 builder.createYield(loc);
653 },
654
655 [&](mlir::OpBuilder &b, mlir::Location loc) {
656 auto loadItr = cir::LoadOp::create(builder, loc, {itr});
657 auto inc = cir::UnaryOp::create(builder, loc, loadItr.getType(),
658 cir::UnaryOpKind::Inc, loadItr);
659 builder.CIRBaseBuilderTy::createStore(loc, inc, itr);
660 builder.createYield(loc);
661 }));
662
664 cgf.cgm.errorNYI(loc,
665 "OpenACC Reduction combiner non-constant array recipe");
666 } else {
667 emitCombiner(lhsArg, rhsArg, origType);
668 }
669
670 builder.setInsertionPointToEnd(&recipe.getCombinerRegion().back());
671 ls.forceCleanup();
672 mlir::acc::YieldOp::create(builder, locEnd, block->getArgument(0));
673}
674
675}
cir::ConditionOp createCondition(mlir::Value condition)
Create a loop condition.
cir::ForOp createFor(mlir::Location loc, llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> condBuilder, llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> bodyBuilder, llvm::function_ref< void(mlir::OpBuilder &, mlir::Location)> stepBuilder)
Create a for operation.
cir::CmpOp createCompare(mlir::Location loc, cir::CmpOpKind kind, mlir::Value lhs, mlir::Value rhs)
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
CanQualType UnsignedLongLongTy
cir::ConstantOp getConstInt(mlir::Location loc, llvm::APSInt intVal)
void forceCleanup()
Force the emission of cleanups now, instead of waiting until this object is destroyed.
mlir::Type convertType(clang::QualType t)
void emitAutoVarInit(const AutoVarEmission &emission)
Emit the initializer for an allocated variable.
clang::ASTContext & getContext() const
mlir::Type convertType(clang::QualType type)
mlir::IntegerAttr getSize(CharUnits size)
This class handles record and union layout info while lowering AST types to CIR types.
unsigned getCIRFieldNo(const clang::FieldDecl *fd) const
Return cir::RecordType element number that corresponds to the field FD.
void createReductionRecipeCombiner(mlir::Location loc, mlir::Location locEnd, mlir::Value mainOp, mlir::acc::ReductionRecipeOp recipe, size_t numBounds, QualType origType, llvm::ArrayRef< OpenACCReductionRecipe::CombinerRecipe > combinerRecipes)
Definition CIRGenOpenACCRecipe.cpp:531
void createInitRecipe(mlir::Location loc, mlir::Location locEnd, SourceRange exprRange, mlir::Value mainOp, mlir::Region &recipeInitRegion, size_t numBounds, llvm::ArrayRef< QualType > boundTypes, const VarDecl *allocaDecl, QualType origType, bool emitInitExpr)
Definition CIRGenOpenACCRecipe.cpp:434
CIRGen::CIRGenBuilderTy & builder
void createFirstprivateRecipeCopy(mlir::Location loc, mlir::Location locEnd, mlir::Value mainOp, const VarDecl *allocaDecl, const VarDecl *temporary, mlir::Region ©Region, size_t numBounds)
Definition CIRGenOpenACCRecipe.cpp:488
mlir::acc::ReductionOperator convertReductionOp(OpenACCReductionOperator op)
Definition CIRGenOpenACCRecipe.cpp:332
CIRGen::CIRGenFunction & cgf
std::pair< mlir::Value, mlir::Value > createBoundsLoop(mlir::Value subscriptedValue, mlir::Value subscriptedValue2, mlir::Value bound, mlir::Location loc, bool inverse)
Definition CIRGenOpenACCRecipe.cpp:224
void createRecipeDestroySection(mlir::Location loc, mlir::Location locEnd, mlir::Value mainOp, CharUnits alignment, QualType origType, size_t numBounds, QualType baseType, mlir::Region &destroyRegion)
Definition CIRGenOpenACCRecipe.cpp:363
mlir::Block * createRecipeBlock(mlir::Region ®ion, mlir::Type opTy, mlir::Location loc, size_t numBounds, bool isInit)
Definition CIRGenOpenACCRecipe.cpp:18
CharUnits - This is an opaque type for sizes expressed in character units.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
A (possibly-)qualified type.
A trivial tuple used to represent a source range.
const Type * getPointeeOrArrayElementType() const
If this is a pointer type, return the pointee type.
bool isPointerType() const
bool isBuiltinType() const
Helper methods to distinguish type categories.
Represents a variable declaration or definition.
const Expr * getInit() const
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Invalid
Invalid Reduction Clause Kind.
bool isa(CodeGen::Address addr)
U cast(CodeGen::Address addr)
bool emittedAsOffload
True if the variable was emitted as an offload recipe, and thus doesn't have the same sort of alloca ...
void setAllocatedAddress(Address a)
Represents a scope, including function bodies, compound statements, and the substatements of if/while...