@@ -1333,27 +1333,30 @@ void LoweringPreparePass::lowerDynamicCastOp(DynamicCastOp op) {
1333
1333
1334
1334
static void lowerArrayDtorCtorIntoLoop (CIRBaseBuilderTy &builder,
1335
1335
mlir::Operation *op, mlir::Type eltTy,
1336
- mlir::Value arrayAddr,
1337
- uint64_t arrayLen ) {
1336
+ mlir::Value arrayAddr, uint64_t arrayLen,
1337
+ bool isCtor ) {
1338
1338
// Generate loop to call into ctor/dtor for every element.
1339
1339
auto loc = op->getLoc ();
1340
1340
1341
1341
// TODO: instead of fixed integer size, create alias for PtrDiffTy and unify
1342
1342
// with CIRGen stuff.
1343
1343
auto ptrDiffTy =
1344
1344
cir::IntType::get (builder.getContext (), 64 , /* signed=*/ false );
1345
- auto numArrayElementsConst = builder.create <cir::ConstantOp>(
1346
- loc, ptrDiffTy, cir::IntAttr::get (ptrDiffTy, arrayLen));
1345
+ uint64_t endOffset = isCtor ? arrayLen : arrayLen - 1 ;
1346
+ mlir::Value endOffsetVal = builder.create <cir::ConstantOp>(
1347
+ loc, ptrDiffTy, cir::IntAttr::get (ptrDiffTy, endOffset));
1347
1348
1348
1349
auto begin = builder.create <cir::CastOp>(
1349
1350
loc, eltTy, cir::CastKind::array_to_ptrdecay, arrayAddr);
1350
- mlir::Value end = builder.create <cir::PtrStrideOp>(loc, eltTy, begin,
1351
- numArrayElementsConst);
1351
+ mlir::Value end =
1352
+ builder.create <cir::PtrStrideOp>(loc, eltTy, begin, endOffsetVal);
1353
+ mlir::Value start = isCtor ? begin : end;
1354
+ mlir::Value stop = isCtor ? end : begin;
1352
1355
1353
1356
auto tmpAddr = builder.createAlloca (
1354
1357
loc, /* addr type*/ builder.getPointerTo (eltTy),
1355
1358
/* var type*/ eltTy, " __array_idx" , clang::CharUnits::One ());
1356
- builder.createStore (loc, begin , tmpAddr);
1359
+ builder.createStore (loc, start , tmpAddr);
1357
1360
1358
1361
auto loop = builder.createDoWhile (
1359
1362
loc,
@@ -1362,7 +1365,7 @@ static void lowerArrayDtorCtorIntoLoop(CIRBaseBuilderTy &builder,
1362
1365
auto currentElement = b.create <cir::LoadOp>(loc, eltTy, tmpAddr);
1363
1366
mlir::Type boolTy = cir::BoolType::get (b.getContext ());
1364
1367
auto cmp = builder.create <cir::CmpOp>(loc, boolTy, cir::CmpOpKind::ne,
1365
- currentElement, end );
1368
+ currentElement, stop );
1366
1369
builder.createCondition (cmp);
1367
1370
},
1368
1371
/* bodyBuilder=*/
@@ -1373,15 +1376,20 @@ static void lowerArrayDtorCtorIntoLoop(CIRBaseBuilderTy &builder,
1373
1376
op->walk ([&](CallOp c) { ctorCall = c; });
1374
1377
assert (ctorCall && " expected ctor call" );
1375
1378
1376
- auto one = builder.create <cir::ConstantOp>(
1377
- loc, ptrDiffTy, cir::IntAttr::get (ptrDiffTy, 1 ));
1379
+ cir::ConstantOp stride;
1380
+ if (isCtor)
1381
+ stride = builder.create <cir::ConstantOp>(
1382
+ loc, ptrDiffTy, cir::IntAttr::get (ptrDiffTy, 1 ));
1383
+ else
1384
+ stride = builder.create <cir::ConstantOp>(
1385
+ loc, ptrDiffTy, cir::IntAttr::get (ptrDiffTy, -1 ));
1378
1386
1379
- ctorCall->moveAfter (one );
1387
+ ctorCall->moveBefore (stride );
1380
1388
ctorCall->setOperand (0 , currentElement);
1381
1389
1382
1390
// Advance pointer and store them to temporary variable
1383
- auto nextElement =
1384
- builder. create <cir::PtrStrideOp>( loc, eltTy, currentElement, one );
1391
+ auto nextElement = builder. create <cir::PtrStrideOp>(
1392
+ loc, eltTy, currentElement, stride );
1385
1393
builder.createStore (loc, nextElement, tmpAddr);
1386
1394
builder.createYield (loc);
1387
1395
});
@@ -1397,7 +1405,7 @@ void LoweringPreparePass::lowerArrayDtor(ArrayDtor op) {
1397
1405
auto eltTy = op->getRegion (0 ).getArgument (0 ).getType ();
1398
1406
auto arrayLen =
1399
1407
mlir::cast<cir::ArrayType>(op.getAddr ().getType ().getPointee ()).getSize ();
1400
- lowerArrayDtorCtorIntoLoop (builder, op, eltTy, op.getAddr (), arrayLen);
1408
+ lowerArrayDtorCtorIntoLoop (builder, op, eltTy, op.getAddr (), arrayLen, false );
1401
1409
}
1402
1410
1403
1411
static std::string getGlobalVarNameForConstString (cir::StoreOp op,
@@ -1460,7 +1468,7 @@ void LoweringPreparePass::lowerArrayCtor(ArrayCtor op) {
1460
1468
auto eltTy = op->getRegion (0 ).getArgument (0 ).getType ();
1461
1469
auto arrayLen =
1462
1470
mlir::cast<cir::ArrayType>(op.getAddr ().getType ().getPointee ()).getSize ();
1463
- lowerArrayDtorCtorIntoLoop (builder, op, eltTy, op.getAddr (), arrayLen);
1471
+ lowerArrayDtorCtorIntoLoop (builder, op, eltTy, op.getAddr (), arrayLen, true );
1464
1472
}
1465
1473
1466
1474
void LoweringPreparePass::lowerStdFindOp (StdFindOp op) {
0 commit comments