================
@@ -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

Reply via email to