@@ -52,19 +52,15 @@ InlineCopyInConversion::matchAndRewrite(hlfir::CopyInOp copyIn,
5252 return rewriter.notifyMatchFailure (copyIn,
5353 " CopyInOp's data type is not trivial" );
5454
55- if (fir::isPointerType (inputVariable.getType ()))
56- return rewriter.notifyMatchFailure (
57- copyIn, " CopyInOp's input variable is a pointer" );
58-
5955 // There should be exactly one user of WasCopied - the corresponding
6056 // CopyOutOp.
61- if (copyIn.getWasCopied ().getUses (). empty ())
62- return rewriter.notifyMatchFailure (copyIn,
63- " CopyInOp's WasCopied has no uses " );
57+ if (! copyIn.getWasCopied ().hasOneUse ())
58+ return rewriter.notifyMatchFailure (
59+ copyIn, " CopyInOp's WasCopied has no single user " );
6460 // The copy out should always be present, either to actually copy or just
6561 // deallocate memory.
6662 auto copyOut = mlir::dyn_cast<hlfir::CopyOutOp>(
67- copyIn.getWasCopied ().getUsers (). begin ().getCurrent ().getUser ());
63+ copyIn.getWasCopied ().user_begin ().getCurrent ().getUser ());
6864
6965 if (!copyOut)
7066 return rewriter.notifyMatchFailure (copyIn,
@@ -77,28 +73,45 @@ InlineCopyInConversion::matchAndRewrite(hlfir::CopyInOp copyIn,
7773
7874 inputVariable =
7975 hlfir::derefPointersAndAllocatables (loc, builder, inputVariable);
80- mlir::Type resultAddrType = copyIn.getCopiedIn ().getType ();
76+ mlir::Type sequenceType =
77+ hlfir::getFortranElementOrSequenceType (inputVariable.getType ());
78+ fir::BoxType resultBoxType = fir::BoxType::get (sequenceType);
8179 mlir::Value isContiguous =
8280 builder.create <fir::IsContiguousBoxOp>(loc, inputVariable);
8381 mlir::Operation::result_range results =
8482 builder
85- .genIfOp (loc, {resultAddrType , builder.getI1Type ()}, isContiguous,
83+ .genIfOp (loc, {resultBoxType , builder.getI1Type ()}, isContiguous,
8684 /* withElseRegion=*/ true )
8785 .genThen ([&]() {
88- mlir::Value falseVal = builder.create <mlir::arith::ConstantOp>(
89- loc, builder.getI1Type (), builder.getBoolAttr (false ));
86+ mlir::Value result = inputVariable;
87+ if (fir::isPointerType (inputVariable.getType ())) {
88+ auto boxAddr = builder.create <fir::BoxAddrOp>(loc, inputVariable);
89+ fir::ReferenceType refTy = fir::ReferenceType::get (sequenceType);
90+ mlir::Value refVal = builder.createConvert (loc, refTy, boxAddr);
91+ mlir::Value shape = hlfir::genShape (loc, builder, inputVariable);
92+ result = builder.create <fir::EmboxOp>(loc, resultBoxType, refVal,
93+ shape);
94+ }
9095 builder.create <fir::ResultOp>(
91- loc, mlir::ValueRange{inputVariable, falseVal });
96+ loc, mlir::ValueRange{result, builder. createBool (loc, false ) });
9297 })
9398 .genElse ([&] {
94- auto [temp, cleanup] =
95- hlfir::createTempFromMold (loc, builder, inputVariable);
9699 mlir::Value shape = hlfir::genShape (loc, builder, inputVariable);
97100 llvm::SmallVector<mlir::Value> extents =
98101 hlfir::getIndexExtents (loc, builder, shape);
99- hlfir::LoopNest loopNest = hlfir::genLoopNest (
100- loc, builder, extents, /* isUnordered=*/ true ,
101- flangomp::shouldUseWorkshareLowering (copyIn));
102+ llvm::StringRef tmpName{" .tmp.copy_in" };
103+ llvm::SmallVector<mlir::Value> lenParams;
104+ mlir::Value alloc = builder.createHeapTemporary (
105+ loc, sequenceType, tmpName, extents, lenParams);
106+
107+ auto declareOp = builder.create <hlfir::DeclareOp>(
108+ loc, alloc, tmpName, shape, lenParams,
109+ /* dummy_scope=*/ nullptr );
110+ hlfir::Entity temp{declareOp.getBase ()};
111+ hlfir::LoopNest loopNest =
112+ hlfir::genLoopNest (loc, builder, extents, /* isUnordered=*/ true ,
113+ flangomp::shouldUseWorkshareLowering (copyIn),
114+ /* couldVectorize=*/ false );
102115 builder.setInsertionPointToStart (loopNest.body );
103116 hlfir::Entity elem = hlfir::getElementAt (
104117 loc, builder, inputVariable, loopNest.oneBasedIndices );
@@ -117,12 +130,12 @@ InlineCopyInConversion::matchAndRewrite(hlfir::CopyInOp copyIn,
117130 fir::ReferenceType refTy =
118131 fir::ReferenceType::get (temp.getElementOrSequenceType ());
119132 mlir::Value refVal = builder.createConvert (loc, refTy, temp);
120- result =
121- builder. create <fir::EmboxOp>(loc, resultAddrType, refVal );
133+ result = builder. create <fir::EmboxOp>(loc, resultBoxType, refVal,
134+ shape );
122135 }
123136
124- builder.create <fir::ResultOp>(loc,
125- mlir::ValueRange{result, cleanup });
137+ builder.create <fir::ResultOp>(
138+ loc, mlir::ValueRange{result, builder. createBool (loc, true ) });
126139 })
127140 .getResults ();
128141
@@ -140,16 +153,7 @@ InlineCopyInConversion::matchAndRewrite(hlfir::CopyInOp copyIn,
140153 });
141154 rewriter.eraseOp (copyOut);
142155
143- mlir::Value tempBox = copyIn.getTempBox ();
144-
145156 rewriter.replaceOp (copyIn, {addr, builder.genNot (loc, isContiguous)});
146-
147- // The TempBox is only needed for flang-rt calls which we're no longer
148- // generating. It should have no uses left at this stage.
149- if (!tempBox.getUses ().empty ())
150- return mlir::failure ();
151- rewriter.eraseOp (tempBox.getDefiningOp ());
152-
153157 return mlir::success ();
154158}
155159
0 commit comments