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(&region, 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 (cgf.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 &copyRegion, size_t numBounds) {

492 mlir::Block *block = createRecipeBlock(copyRegion, mainOp.getType(), loc,

493 numBounds, false);

494 builder.setInsertionPointToEnd(&copyRegion.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(&copyRegion.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 &copyRegion, 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 &region, 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...