================
@@ -1443,34 +1446,87 @@ static void
lowerArrayDtorCtorIntoLoop(cir::CIRBaseBuilderTy &builder,
}
};
- builder.createDoWhile(
- loc,
- /*condBuilder=*/
- [&](mlir::OpBuilder &b, mlir::Location loc) {
- auto currentElement = cir::LoadOp::create(b, loc, eltTy, tmpAddr);
- auto cmp = cir::CmpOp::create(builder, loc, cir::CmpOpKind::ne,
- currentElement, stop);
- builder.createCondition(cmp);
- },
- /*bodyBuilder=*/
- [&](mlir::OpBuilder &b, mlir::Location loc) {
- auto currentElement = cir::LoadOp::create(b, loc, eltTy, tmpAddr);
- if (isCtor) {
- cloneRegionBodyInto(bodyBlock, currentElement);
- mlir::Value stride = builder.getUnsignedInt(loc, 1, sizeTypeSize);
- auto nextElement = cir::PtrStrideOp::create(builder, loc, eltTy,
- currentElement, stride);
- builder.createStore(loc, nextElement, tmpAddr);
- } else {
- mlir::Value stride = builder.getSignedInt(loc, -1, sizeTypeSize);
- auto prevElement = cir::PtrStrideOp::create(builder, loc, eltTy,
- currentElement, stride);
- builder.createStore(loc, prevElement, tmpAddr);
- cloneRegionBodyInto(bodyBlock, prevElement);
- }
-
- builder.createYield(loc);
- });
+ mlir::Block *partialDtorBlock = nullptr;
+ if (auto arrayCtor = mlir::dyn_cast<cir::ArrayCtor>(op)) {
+ mlir::Region &partialDtor = arrayCtor.getPartialDtor();
+ if (!partialDtor.empty())
+ partialDtorBlock = &partialDtor.front();
+ }
+
+ auto emitCtorDtorLoop = [&]() {
+ builder.createDoWhile(
+ loc,
+ /*condBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ auto currentElement = cir::LoadOp::create(b, loc, eltTy, tmpAddr);
+ auto cmp = cir::CmpOp::create(builder, loc, cir::CmpOpKind::ne,
+ currentElement, stop);
+ builder.createCondition(cmp);
+ },
+ /*bodyBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ auto currentElement = cir::LoadOp::create(b, loc, eltTy, tmpAddr);
+ if (isCtor) {
+ cloneRegionBodyInto(bodyBlock, currentElement);
+ mlir::Value stride = builder.getUnsignedInt(loc, 1, sizeTypeSize);
+ auto nextElement = cir::PtrStrideOp::create(builder, loc, eltTy,
+ currentElement,
stride);
+ builder.createStore(loc, nextElement, tmpAddr);
+ } else {
+ mlir::Value stride = builder.getSignedInt(loc, -1, sizeTypeSize);
+ auto prevElement = cir::PtrStrideOp::create(builder, loc, eltTy,
+ currentElement,
stride);
+ builder.createStore(loc, prevElement, tmpAddr);
+ cloneRegionBodyInto(bodyBlock, prevElement);
+ }
+
+ builder.createYield(loc);
+ });
+ };
+
+ if (partialDtorBlock) {
+ cir::CleanupScopeOp::create(
+ builder, loc, cir::CleanupKind::EH,
+ /*bodyBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ emitCtorDtorLoop();
+ builder.createYield(loc);
+ },
+ /*cleanupBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ auto cur = cir::LoadOp::create(b, loc, eltTy, tmpAddr);
+ auto cmp =
+ cir::CmpOp::create(builder, loc, cir::CmpOpKind::ne, cur, begin);
+ cir::IfOp::create(
+ builder, loc, cmp, /*withElseRegion=*/false,
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ builder.createDoWhile(
+ loc,
+ /*condBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ auto el = cir::LoadOp::create(b, loc, eltTy, tmpAddr);
+ auto neq = cir::CmpOp::create(
+ builder, loc, cir::CmpOpKind::ne, el, begin);
+ builder.createCondition(neq);
+ },
+ /*bodyBuilder=*/
+ [&](mlir::OpBuilder &b, mlir::Location loc) {
+ auto el = cir::LoadOp::create(b, loc, eltTy, tmpAddr);
+ mlir::Value negOne =
+ builder.getSignedInt(loc, -1, sizeTypeSize);
+ auto prev = cir::PtrStrideOp::create(builder, loc, eltTy,
+ el, negOne);
+ builder.createStore(loc, prev, tmpAddr);
+ cloneRegionBodyInto(partialDtorBlock, prev);
+ builder.createYield(loc);
+ });
+ cir::YieldOp::create(builder, loc);
+ });
+ builder.createYield(loc);
----------------
xlauko wrote:
cir::YieldOp::create
https://github.com/llvm/llvm-project/pull/190834
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits