@@ -29,7 +29,8 @@ struct LoweringPreparePass : public LoweringPrepareBase<LoweringPreparePass> {
29
29
void runOnOp (mlir::Operation *op);
30
30
void lowerCastOp (cir::CastOp op);
31
31
void lowerUnaryOp (cir::UnaryOp op);
32
- void lowerArrayCtor (ArrayCtor op);
32
+ void lowerArrayDtor (cir::ArrayDtor op);
33
+ void lowerArrayCtor (cir::ArrayCtor op);
33
34
34
35
// /
35
36
// / AST related
@@ -172,28 +173,30 @@ void LoweringPreparePass::lowerUnaryOp(cir::UnaryOp op) {
172
173
static void lowerArrayDtorCtorIntoLoop (cir::CIRBaseBuilderTy &builder,
173
174
clang::ASTContext *astCtx,
174
175
mlir::Operation *op, mlir::Type eltTy,
175
- mlir::Value arrayAddr,
176
- uint64_t arrayLen ) {
176
+ mlir::Value arrayAddr, uint64_t arrayLen,
177
+ bool isCtor ) {
177
178
// Generate loop to call into ctor/dtor for every element.
178
179
mlir::Location loc = op->getLoc ();
179
180
180
- // TODO: instead of fixed integer size, create alias for PtrDiffTy and unify
181
- // with CIRGen stuff.
181
+ // TODO: instead of getting the size from the AST context , create alias for
182
+ // PtrDiffTy and unify with CIRGen stuff.
182
183
const unsigned sizeTypeSize =
183
184
astCtx->getTypeSize (astCtx->getSignedSizeType ());
184
- auto ptrDiffTy =
185
- cir::IntType::get (builder. getContext (), sizeTypeSize, /* isSigned= */ false );
186
- mlir::Value numArrayElementsConst = builder.getUnsignedInt (loc, arrayLen, 64 );
185
+ uint64_t endOffset = isCtor ? arrayLen : arrayLen - 1 ;
186
+ mlir::Value endOffsetVal =
187
+ builder.getUnsignedInt (loc, endOffset, sizeTypeSize );
187
188
188
- auto begin = builder.create <cir::CastOp>(
189
- loc, eltTy, cir::CastKind::array_to_ptrdecay, arrayAddr);
190
- mlir::Value end = builder.create <cir::PtrStrideOp>(loc, eltTy, begin,
191
- numArrayElementsConst);
189
+ auto begin = cir::CastOp::create (builder, loc, eltTy,
190
+ cir::CastKind::array_to_ptrdecay, arrayAddr);
191
+ mlir::Value end =
192
+ cir::PtrStrideOp::create (builder, loc, eltTy, begin, endOffsetVal);
193
+ mlir::Value start = isCtor ? begin : end;
194
+ mlir::Value stop = isCtor ? end : begin;
192
195
193
196
mlir::Value tmpAddr = builder.createAlloca (
194
197
loc, /* addr type*/ builder.getPointerTo (eltTy),
195
198
/* var type*/ eltTy, " __array_idx" , builder.getAlignmentAttr (1 ));
196
- builder.createStore (loc, begin , tmpAddr);
199
+ builder.createStore (loc, start , tmpAddr);
197
200
198
201
cir::DoWhileOp loop = builder.createDoWhile (
199
202
loc,
@@ -202,7 +205,7 @@ static void lowerArrayDtorCtorIntoLoop(cir::CIRBaseBuilderTy &builder,
202
205
auto currentElement = b.create <cir::LoadOp>(loc, eltTy, tmpAddr);
203
206
mlir::Type boolTy = cir::BoolType::get (b.getContext ());
204
207
auto cmp = builder.create <cir::CmpOp>(loc, boolTy, cir::CmpOpKind::ne,
205
- currentElement, end );
208
+ currentElement, stop );
206
209
builder.createCondition (cmp);
207
210
},
208
211
/* bodyBuilder=*/
@@ -213,15 +216,19 @@ static void lowerArrayDtorCtorIntoLoop(cir::CIRBaseBuilderTy &builder,
213
216
op->walk ([&](cir::CallOp c) { ctorCall = c; });
214
217
assert (ctorCall && " expected ctor call" );
215
218
216
- auto one = builder.create <cir::ConstantOp>(
217
- loc, ptrDiffTy, cir::IntAttr::get (ptrDiffTy, 1 ));
219
+ // Array elements get constructed in order but destructed in reverse.
220
+ mlir::Value stride;
221
+ if (isCtor)
222
+ stride = builder.getUnsignedInt (loc, 1 , sizeTypeSize);
223
+ else
224
+ stride = builder.getSignedInt (loc, -1 , sizeTypeSize);
218
225
219
- ctorCall->moveAfter (one );
226
+ ctorCall->moveBefore (stride. getDefiningOp () );
220
227
ctorCall->setOperand (0 , currentElement);
228
+ auto nextElement = cir::PtrStrideOp::create (builder, loc, eltTy,
229
+ currentElement, stride);
221
230
222
- // Advance pointer and store them to temporary variable
223
- auto nextElement =
224
- builder.create <cir::PtrStrideOp>(loc, eltTy, currentElement, one);
231
+ // Store the element pointer to the temporary variable
225
232
builder.createStore (loc, nextElement, tmpAddr);
226
233
builder.createYield (loc);
227
234
});
@@ -230,6 +237,18 @@ static void lowerArrayDtorCtorIntoLoop(cir::CIRBaseBuilderTy &builder,
230
237
op->erase ();
231
238
}
232
239
240
+ void LoweringPreparePass::lowerArrayDtor (cir::ArrayDtor op) {
241
+ CIRBaseBuilderTy builder (getContext ());
242
+ builder.setInsertionPointAfter (op.getOperation ());
243
+
244
+ mlir::Type eltTy = op->getRegion (0 ).getArgument (0 ).getType ();
245
+ assert (!cir::MissingFeatures::vlas ());
246
+ auto arrayLen =
247
+ mlir::cast<cir::ArrayType>(op.getAddr ().getType ().getPointee ()).getSize ();
248
+ lowerArrayDtorCtorIntoLoop (builder, astCtx, op, eltTy, op.getAddr (), arrayLen,
249
+ false );
250
+ }
251
+
233
252
void LoweringPreparePass::lowerArrayCtor (cir::ArrayCtor op) {
234
253
cir::CIRBaseBuilderTy builder (getContext ());
235
254
builder.setInsertionPointAfter (op.getOperation ());
@@ -238,13 +257,15 @@ void LoweringPreparePass::lowerArrayCtor(cir::ArrayCtor op) {
238
257
assert (!cir::MissingFeatures::vlas ());
239
258
auto arrayLen =
240
259
mlir::cast<cir::ArrayType>(op.getAddr ().getType ().getPointee ()).getSize ();
241
- lowerArrayDtorCtorIntoLoop (builder, astCtx, op, eltTy, op.getAddr (),
242
- arrayLen );
260
+ lowerArrayDtorCtorIntoLoop (builder, astCtx, op, eltTy, op.getAddr (), arrayLen,
261
+ true );
243
262
}
244
263
245
264
void LoweringPreparePass::runOnOp (mlir::Operation *op) {
246
265
if (auto arrayCtor = dyn_cast<ArrayCtor>(op))
247
266
lowerArrayCtor (arrayCtor);
267
+ else if (auto arrayDtor = dyn_cast<cir::ArrayDtor>(op))
268
+ lowerArrayDtor (arrayDtor);
248
269
else if (auto cast = mlir::dyn_cast<cir::CastOp>(op))
249
270
lowerCastOp (cast);
250
271
else if (auto unary = mlir::dyn_cast<cir::UnaryOp>(op))
@@ -257,7 +278,8 @@ void LoweringPreparePass::runOnOperation() {
257
278
llvm::SmallVector<mlir::Operation *> opsToTransform;
258
279
259
280
op->walk ([&](mlir::Operation *op) {
260
- if (mlir::isa<cir::ArrayCtor, cir::CastOp, cir::UnaryOp>(op))
281
+ if (mlir::isa<cir::ArrayCtor, cir::ArrayDtor, cir::CastOp, cir::UnaryOp>(
282
+ op))
261
283
opsToTransform.push_back (op);
262
284
});
263
285
0 commit comments