================
@@ -599,29 +622,209 @@ static mlir::Value emitCopiedCoercedLoad(mlir::OpBuilder
&builder,
"a direct offset must leave the record as the slot's type");
mlir::OpBuilder::InsertionGuard guard(builder);
builder.setInsertionPoint(load);
- mlir::Value recView = emitViewAtOffset(builder, loc, recTy, slot, ignored,
0);
- cir::CopyOp::create(builder, loc, recView, load.getAddr(),
- builder.getI64IntegerAttr(slot.getAlignment()),
- builder.getI64IntegerAttr(srcAlign));
+ mlir::Value recView =
+ emitViewAtOffset(builder, loc, recTy, slot, ignored, /*offset=*/0);
+ auto copy =
+ cir::CopyOp::create(builder, loc, recView, load.getAddr(),
+ builder.getI64IntegerAttr(slot.getAlignment()),
+ builder.getI64IntegerAttr(srcAlign));
+ copy.setIsVolatile(load.getIsVolatile());
+ return slot;
+}
+
+/// Copy the bytes of the record \p load reads into a coercion slot, as
+/// emitCopiedCoercionSlot does, then read \p coercedTy out of the slot at
+/// \p offset. The read takes the slot's alignment at \p offset.
+static mlir::Value emitCopiedCoercedLoad(mlir::OpBuilder &builder,
+ mlir::Location loc, cir::LoadOp load,
+ mlir::Type coercedTy,
+ mlir::Block *slotBlock,
+ const mlir::DataLayout &dl,
+ unsigned offset) {
+ cir::AllocaOp slot = emitCopiedCoercionSlot(builder, loc, load, coercedTy,
+ slotBlock, dl, offset);
+ mlir::OpBuilder::InsertionGuard guard(builder);
+ builder.setInsertionPoint(load);
+ SmallPtrSet<mlir::Operation *, 4> ignored;
mlir::Value coercedView =
emitViewAtOffset(builder, loc, coercedTy, slot, ignored, offset);
auto coerced = cir::LoadOp::create(builder, loc, coercedView);
coerced.setAlignment(llvm::MinAlign(slot.getAlignment(), offset));
return coerced;
}
+/// Read \p coercedTy at \p offset out of the bytes the record load \p load
+/// reads: straight out of its storage if \p load is not volatile and
+/// canReadInPlace accepts it, and otherwise out of a coercion slot at the
start
+/// of \p slotBlock that those bytes are copied into. emitInPlaceCoercedLoad
+/// does not mark its read volatile, so a volatile load is read through the
+/// volatile copy instead. Either way no new load of the record type is
+/// emitted.
+static mlir::Value emitCoercedRecordLoad(
+ mlir::OpBuilder &builder, mlir::Location loc, cir::LoadOp load,
+ mlir::Type coercedTy, mlir::Block *slotBlock, const mlir::DataLayout &dl,
+ const cir::CIRDataLayout &cirDataLayout, unsigned offset) {
+ if (!load.getIsVolatile() &&
+ canReadInPlace(load, coercedTy, cirDataLayout, offset))
+ return emitInPlaceCoercedLoad(builder, loc, load, coercedTy, offset);
+ return emitCopiedCoercedLoad(builder, loc, load, coercedTy, slotBlock, dl,
+ offset);
+}
+
+/// Whether \p ty is a struct that ends in pad members, as CIRGen emits for
tail
+/// padding another object may reuse. It is also true of other structs CIRGen
+/// ends in pad members, such as an over-aligned one.
+static bool hasTailPadding(mlir::Type ty) {
----------------
adams381 wrote:
Done.
https://github.com/llvm/llvm-project/pull/231663
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits