197d8972cSEric Schweitz //===-- PreCGRewrite.cpp --------------------------------------------------===// 297d8972cSEric Schweitz // 397d8972cSEric Schweitz // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 497d8972cSEric Schweitz // See https://llvm.org/LICENSE.txt for license information. 597d8972cSEric Schweitz // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 697d8972cSEric Schweitz // 797d8972cSEric Schweitz //===----------------------------------------------------------------------===// 897d8972cSEric Schweitz // 997d8972cSEric Schweitz // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ 1097d8972cSEric Schweitz // 1197d8972cSEric Schweitz //===----------------------------------------------------------------------===// 1297d8972cSEric Schweitz 13039b969bSMichele Scuttari #include "flang/Optimizer/CodeGen/CodeGen.h" 1467d0d7acSMichele Scuttari 159d99b482SValentin Clement #include "flang/Optimizer/Builder/Todo.h" // remove when TODO's are done 16cd5ee271SAbid Qadeer #include "flang/Optimizer/CodeGen/CGOps.h" 1797d8972cSEric Schweitz #include "flang/Optimizer/Dialect/FIRDialect.h" 1897d8972cSEric Schweitz #include "flang/Optimizer/Dialect/FIROps.h" 1997d8972cSEric Schweitz #include "flang/Optimizer/Dialect/FIRType.h" 20b07ef9e7SRenaud-K #include "flang/Optimizer/Dialect/Support/FIRContext.h" 21bf08d0e1SjeanPerier #include "mlir/IR/Iterators.h" 2297d8972cSEric Schweitz #include "mlir/Transforms/DialectConversion.h" 2397d8972cSEric Schweitz #include "llvm/ADT/STLExtras.h" 24861eff24SNico Weber #include "llvm/Support/Debug.h" 2597d8972cSEric Schweitz 2667d0d7acSMichele Scuttari namespace fir { 2767d0d7acSMichele Scuttari #define GEN_PASS_DEF_CODEGENREWRITE 2867d0d7acSMichele Scuttari #include "flang/Optimizer/CodeGen/CGPasses.h.inc" 2967d0d7acSMichele Scuttari } // namespace fir 3067d0d7acSMichele Scuttari 3197d8972cSEric Schweitz //===----------------------------------------------------------------------===// 3297d8972cSEric Schweitz // Codegen rewrite: rewriting of subgraphs of ops 3397d8972cSEric Schweitz //===----------------------------------------------------------------------===// 3497d8972cSEric Schweitz 3597d8972cSEric Schweitz #define DEBUG_TYPE "flang-codegen-rewrite" 3697d8972cSEric Schweitz 3797d8972cSEric Schweitz static void populateShape(llvm::SmallVectorImpl<mlir::Value> &vec, 381f31795cSEric Schweitz fir::ShapeOp shape) { 39149ad3d5SShraiysh Vaishay vec.append(shape.getExtents().begin(), shape.getExtents().end()); 4097d8972cSEric Schweitz } 4197d8972cSEric Schweitz 4297d8972cSEric Schweitz // Operands of fir.shape_shift split into two vectors. 4397d8972cSEric Schweitz static void populateShapeAndShift(llvm::SmallVectorImpl<mlir::Value> &shapeVec, 4497d8972cSEric Schweitz llvm::SmallVectorImpl<mlir::Value> &shiftVec, 451f31795cSEric Schweitz fir::ShapeShiftOp shift) { 461f31795cSEric Schweitz for (auto i = shift.getPairs().begin(), endIter = shift.getPairs().end(); 471f31795cSEric Schweitz i != endIter;) { 4897d8972cSEric Schweitz shiftVec.push_back(*i++); 4997d8972cSEric Schweitz shapeVec.push_back(*i++); 5097d8972cSEric Schweitz } 5197d8972cSEric Schweitz } 5297d8972cSEric Schweitz 5397d8972cSEric Schweitz static void populateShift(llvm::SmallVectorImpl<mlir::Value> &vec, 541f31795cSEric Schweitz fir::ShiftOp shift) { 55149ad3d5SShraiysh Vaishay vec.append(shift.getOrigins().begin(), shift.getOrigins().end()); 5697d8972cSEric Schweitz } 5797d8972cSEric Schweitz 5897d8972cSEric Schweitz namespace { 5997d8972cSEric Schweitz 6097d8972cSEric Schweitz /// Convert fir.embox to the extended form where necessary. 6197d8972cSEric Schweitz /// 6297d8972cSEric Schweitz /// The embox operation can take arguments that specify multidimensional array 6397d8972cSEric Schweitz /// properties at runtime. These properties may be shared between distinct 6497d8972cSEric Schweitz /// objects that have the same properties. Before we lower these small DAGs to 6597d8972cSEric Schweitz /// LLVM-IR, we gather all the information into a single extended operation. For 6697d8972cSEric Schweitz /// example, 6797d8972cSEric Schweitz /// ``` 6897d8972cSEric Schweitz /// %1 = fir.shape_shift %4, %5 : (index, index) -> !fir.shapeshift<1> 6997d8972cSEric Schweitz /// %2 = fir.slice %6, %7, %8 : (index, index, index) -> !fir.slice<1> 70a54f4eaeSMogball /// %3 = fir.embox %0 (%1) [%2] : (!fir.ref<!fir.array<?xi32>>, 71a54f4eaeSMogball /// !fir.shapeshift<1>, !fir.slice<1>) -> !fir.box<!fir.array<?xi32>> 7297d8972cSEric Schweitz /// ``` 7397d8972cSEric Schweitz /// can be rewritten as 7497d8972cSEric Schweitz /// ``` 75a54f4eaeSMogball /// %1 = fircg.ext_embox %0(%5) origin %4[%6, %7, %8] : 76a54f4eaeSMogball /// (!fir.ref<!fir.array<?xi32>>, index, index, index, index, index) -> 77a54f4eaeSMogball /// !fir.box<!fir.array<?xi32>> 7897d8972cSEric Schweitz /// ``` 791f31795cSEric Schweitz class EmboxConversion : public mlir::OpRewritePattern<fir::EmboxOp> { 8097d8972cSEric Schweitz public: 8197d8972cSEric Schweitz using OpRewritePattern::OpRewritePattern; 8297d8972cSEric Schweitz 83db791b27SRamkumar Ramachandra llvm::LogicalResult 841f31795cSEric Schweitz matchAndRewrite(fir::EmboxOp embox, 8597d8972cSEric Schweitz mlir::PatternRewriter &rewriter) const override { 8697d8972cSEric Schweitz // If the embox does not include a shape, then do not convert it 871f31795cSEric Schweitz if (auto shapeVal = embox.getShape()) 8897d8972cSEric Schweitz return rewriteDynamicShape(embox, rewriter, shapeVal); 89fac349a1SChristian Sigg if (mlir::isa<fir::ClassType>(embox.getType())) 909d99b482SValentin Clement TODO(embox.getLoc(), "embox conversion for fir.class type"); 91fac349a1SChristian Sigg if (auto boxTy = mlir::dyn_cast<fir::BoxType>(embox.getType())) 92fac349a1SChristian Sigg if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(boxTy.getEleTy())) 937ae39114SMats Petersson if (!seqTy.hasDynamicExtents()) 9497d8972cSEric Schweitz return rewriteStaticShape(embox, rewriter, seqTy); 9597d8972cSEric Schweitz return mlir::failure(); 9697d8972cSEric Schweitz } 9797d8972cSEric Schweitz 98db791b27SRamkumar Ramachandra llvm::LogicalResult rewriteStaticShape(fir::EmboxOp embox, 9997d8972cSEric Schweitz mlir::PatternRewriter &rewriter, 1001f31795cSEric Schweitz fir::SequenceType seqTy) const { 10197d8972cSEric Schweitz auto loc = embox.getLoc(); 10297d8972cSEric Schweitz llvm::SmallVector<mlir::Value> shapeOpers; 10397d8972cSEric Schweitz auto idxTy = rewriter.getIndexType(); 10497d8972cSEric Schweitz for (auto ext : seqTy.getShape()) { 10597d8972cSEric Schweitz auto iAttr = rewriter.getIndexAttr(ext); 106a54f4eaeSMogball auto extVal = rewriter.create<mlir::arith::ConstantOp>(loc, idxTy, iAttr); 10797d8972cSEric Schweitz shapeOpers.push_back(extVal); 10897d8972cSEric Schweitz } 1091f31795cSEric Schweitz auto xbox = rewriter.create<fir::cg::XEmboxOp>( 1109a417395SKazu Hirata loc, embox.getType(), embox.getMemref(), shapeOpers, std::nullopt, 1119a417395SKazu Hirata std::nullopt, std::nullopt, std::nullopt, embox.getTypeparams(), 112*0def9a92SValentin Clement (バレンタイン クレメン) embox.getSourceBox(), embox.getAllocatorIdxAttr()); 11397d8972cSEric Schweitz LLVM_DEBUG(llvm::dbgs() << "rewriting " << embox << " to " << xbox << '\n'); 11497d8972cSEric Schweitz rewriter.replaceOp(embox, xbox.getOperation()->getResults()); 11597d8972cSEric Schweitz return mlir::success(); 11697d8972cSEric Schweitz } 11797d8972cSEric Schweitz 118db791b27SRamkumar Ramachandra llvm::LogicalResult rewriteDynamicShape(fir::EmboxOp embox, 11997d8972cSEric Schweitz mlir::PatternRewriter &rewriter, 12097d8972cSEric Schweitz mlir::Value shapeVal) const { 12197d8972cSEric Schweitz auto loc = embox.getLoc(); 12297d8972cSEric Schweitz llvm::SmallVector<mlir::Value> shapeOpers; 12397d8972cSEric Schweitz llvm::SmallVector<mlir::Value> shiftOpers; 1241f31795cSEric Schweitz if (auto shapeOp = mlir::dyn_cast<fir::ShapeOp>(shapeVal.getDefiningOp())) { 12597d8972cSEric Schweitz populateShape(shapeOpers, shapeOp); 12697d8972cSEric Schweitz } else { 1271f31795cSEric Schweitz auto shiftOp = 1281f31795cSEric Schweitz mlir::dyn_cast<fir::ShapeShiftOp>(shapeVal.getDefiningOp()); 12997d8972cSEric Schweitz assert(shiftOp && "shape is neither fir.shape nor fir.shape_shift"); 13097d8972cSEric Schweitz populateShapeAndShift(shapeOpers, shiftOpers, shiftOp); 13197d8972cSEric Schweitz } 13297d8972cSEric Schweitz llvm::SmallVector<mlir::Value> sliceOpers; 13397d8972cSEric Schweitz llvm::SmallVector<mlir::Value> subcompOpers; 1343c7ff45cSValentin Clement llvm::SmallVector<mlir::Value> substrOpers; 13597d8972cSEric Schweitz if (auto s = embox.getSlice()) 1361f31795cSEric Schweitz if (auto sliceOp = 1371f31795cSEric Schweitz mlir::dyn_cast_or_null<fir::SliceOp>(s.getDefiningOp())) { 138149ad3d5SShraiysh Vaishay sliceOpers.assign(sliceOp.getTriples().begin(), 139149ad3d5SShraiysh Vaishay sliceOp.getTriples().end()); 140149ad3d5SShraiysh Vaishay subcompOpers.assign(sliceOp.getFields().begin(), 141149ad3d5SShraiysh Vaishay sliceOp.getFields().end()); 142149ad3d5SShraiysh Vaishay substrOpers.assign(sliceOp.getSubstr().begin(), 143149ad3d5SShraiysh Vaishay sliceOp.getSubstr().end()); 14497d8972cSEric Schweitz } 1451f31795cSEric Schweitz auto xbox = rewriter.create<fir::cg::XEmboxOp>( 146149ad3d5SShraiysh Vaishay loc, embox.getType(), embox.getMemref(), shapeOpers, shiftOpers, 1472e978986SValentin Clement sliceOpers, subcompOpers, substrOpers, embox.getTypeparams(), 148*0def9a92SValentin Clement (バレンタイン クレメン) embox.getSourceBox(), embox.getAllocatorIdxAttr()); 14997d8972cSEric Schweitz LLVM_DEBUG(llvm::dbgs() << "rewriting " << embox << " to " << xbox << '\n'); 15097d8972cSEric Schweitz rewriter.replaceOp(embox, xbox.getOperation()->getResults()); 15197d8972cSEric Schweitz return mlir::success(); 15297d8972cSEric Schweitz } 15397d8972cSEric Schweitz }; 15497d8972cSEric Schweitz 15597d8972cSEric Schweitz /// Convert fir.rebox to the extended form where necessary. 15697d8972cSEric Schweitz /// 15797d8972cSEric Schweitz /// For example, 15897d8972cSEric Schweitz /// ``` 159a54f4eaeSMogball /// %5 = fir.rebox %3(%1) : (!fir.box<!fir.array<?xi32>>, !fir.shapeshift<1>) -> 160a54f4eaeSMogball /// !fir.box<!fir.array<?xi32>> 16197d8972cSEric Schweitz /// ``` 16297d8972cSEric Schweitz /// converted to 16397d8972cSEric Schweitz /// ``` 164a54f4eaeSMogball /// %5 = fircg.ext_rebox %3(%13) origin %12 : (!fir.box<!fir.array<?xi32>>, 165a54f4eaeSMogball /// index, index) -> !fir.box<!fir.array<?xi32>> 16697d8972cSEric Schweitz /// ``` 1671f31795cSEric Schweitz class ReboxConversion : public mlir::OpRewritePattern<fir::ReboxOp> { 16897d8972cSEric Schweitz public: 16997d8972cSEric Schweitz using OpRewritePattern::OpRewritePattern; 17097d8972cSEric Schweitz 171db791b27SRamkumar Ramachandra llvm::LogicalResult 1721f31795cSEric Schweitz matchAndRewrite(fir::ReboxOp rebox, 17397d8972cSEric Schweitz mlir::PatternRewriter &rewriter) const override { 17497d8972cSEric Schweitz auto loc = rebox.getLoc(); 17597d8972cSEric Schweitz llvm::SmallVector<mlir::Value> shapeOpers; 17697d8972cSEric Schweitz llvm::SmallVector<mlir::Value> shiftOpers; 177149ad3d5SShraiysh Vaishay if (auto shapeVal = rebox.getShape()) { 1781f31795cSEric Schweitz if (auto shapeOp = mlir::dyn_cast<fir::ShapeOp>(shapeVal.getDefiningOp())) 17997d8972cSEric Schweitz populateShape(shapeOpers, shapeOp); 1801f31795cSEric Schweitz else if (auto shiftOp = 1811f31795cSEric Schweitz mlir::dyn_cast<fir::ShapeShiftOp>(shapeVal.getDefiningOp())) 18297d8972cSEric Schweitz populateShapeAndShift(shapeOpers, shiftOpers, shiftOp); 1831f31795cSEric Schweitz else if (auto shiftOp = 1841f31795cSEric Schweitz mlir::dyn_cast<fir::ShiftOp>(shapeVal.getDefiningOp())) 18597d8972cSEric Schweitz populateShift(shiftOpers, shiftOp); 18697d8972cSEric Schweitz else 18797d8972cSEric Schweitz return mlir::failure(); 18897d8972cSEric Schweitz } 18997d8972cSEric Schweitz llvm::SmallVector<mlir::Value> sliceOpers; 19097d8972cSEric Schweitz llvm::SmallVector<mlir::Value> subcompOpers; 1913c7ff45cSValentin Clement llvm::SmallVector<mlir::Value> substrOpers; 192149ad3d5SShraiysh Vaishay if (auto s = rebox.getSlice()) 1931f31795cSEric Schweitz if (auto sliceOp = 1941f31795cSEric Schweitz mlir::dyn_cast_or_null<fir::SliceOp>(s.getDefiningOp())) { 195149ad3d5SShraiysh Vaishay sliceOpers.append(sliceOp.getTriples().begin(), 196149ad3d5SShraiysh Vaishay sliceOp.getTriples().end()); 197149ad3d5SShraiysh Vaishay subcompOpers.append(sliceOp.getFields().begin(), 198149ad3d5SShraiysh Vaishay sliceOp.getFields().end()); 199149ad3d5SShraiysh Vaishay substrOpers.append(sliceOp.getSubstr().begin(), 200149ad3d5SShraiysh Vaishay sliceOp.getSubstr().end()); 20197d8972cSEric Schweitz } 20297d8972cSEric Schweitz 2031f31795cSEric Schweitz auto xRebox = rewriter.create<fir::cg::XReboxOp>( 204149ad3d5SShraiysh Vaishay loc, rebox.getType(), rebox.getBox(), shapeOpers, shiftOpers, 205149ad3d5SShraiysh Vaishay sliceOpers, subcompOpers, substrOpers); 20697d8972cSEric Schweitz LLVM_DEBUG(llvm::dbgs() 20797d8972cSEric Schweitz << "rewriting " << rebox << " to " << xRebox << '\n'); 20897d8972cSEric Schweitz rewriter.replaceOp(rebox, xRebox.getOperation()->getResults()); 20997d8972cSEric Schweitz return mlir::success(); 21097d8972cSEric Schweitz } 21197d8972cSEric Schweitz }; 21297d8972cSEric Schweitz 21397d8972cSEric Schweitz /// Convert all fir.array_coor to the extended form. 21497d8972cSEric Schweitz /// 21597d8972cSEric Schweitz /// For example, 21697d8972cSEric Schweitz /// ``` 217a54f4eaeSMogball /// %4 = fir.array_coor %addr (%1) [%2] %0 : (!fir.ref<!fir.array<?xi32>>, 218a54f4eaeSMogball /// !fir.shapeshift<1>, !fir.slice<1>, index) -> !fir.ref<i32> 21997d8972cSEric Schweitz /// ``` 22097d8972cSEric Schweitz /// converted to 22197d8972cSEric Schweitz /// ``` 222a54f4eaeSMogball /// %40 = fircg.ext_array_coor %addr(%9) origin %8[%4, %5, %6<%39> : 223a54f4eaeSMogball /// (!fir.ref<!fir.array<?xi32>>, index, index, index, index, index, index) -> 224a54f4eaeSMogball /// !fir.ref<i32> 22597d8972cSEric Schweitz /// ``` 2261f31795cSEric Schweitz class ArrayCoorConversion : public mlir::OpRewritePattern<fir::ArrayCoorOp> { 22797d8972cSEric Schweitz public: 22897d8972cSEric Schweitz using OpRewritePattern::OpRewritePattern; 22997d8972cSEric Schweitz 230db791b27SRamkumar Ramachandra llvm::LogicalResult 2311f31795cSEric Schweitz matchAndRewrite(fir::ArrayCoorOp arrCoor, 23297d8972cSEric Schweitz mlir::PatternRewriter &rewriter) const override { 23397d8972cSEric Schweitz auto loc = arrCoor.getLoc(); 23497d8972cSEric Schweitz llvm::SmallVector<mlir::Value> shapeOpers; 23597d8972cSEric Schweitz llvm::SmallVector<mlir::Value> shiftOpers; 236149ad3d5SShraiysh Vaishay if (auto shapeVal = arrCoor.getShape()) { 2371f31795cSEric Schweitz if (auto shapeOp = mlir::dyn_cast<fir::ShapeOp>(shapeVal.getDefiningOp())) 23897d8972cSEric Schweitz populateShape(shapeOpers, shapeOp); 2391f31795cSEric Schweitz else if (auto shiftOp = 2401f31795cSEric Schweitz mlir::dyn_cast<fir::ShapeShiftOp>(shapeVal.getDefiningOp())) 24197d8972cSEric Schweitz populateShapeAndShift(shapeOpers, shiftOpers, shiftOp); 2421f31795cSEric Schweitz else if (auto shiftOp = 2431f31795cSEric Schweitz mlir::dyn_cast<fir::ShiftOp>(shapeVal.getDefiningOp())) 24497d8972cSEric Schweitz populateShift(shiftOpers, shiftOp); 24597d8972cSEric Schweitz else 24697d8972cSEric Schweitz return mlir::failure(); 24797d8972cSEric Schweitz } 24897d8972cSEric Schweitz llvm::SmallVector<mlir::Value> sliceOpers; 24997d8972cSEric Schweitz llvm::SmallVector<mlir::Value> subcompOpers; 250149ad3d5SShraiysh Vaishay if (auto s = arrCoor.getSlice()) 2511f31795cSEric Schweitz if (auto sliceOp = 2521f31795cSEric Schweitz mlir::dyn_cast_or_null<fir::SliceOp>(s.getDefiningOp())) { 253149ad3d5SShraiysh Vaishay sliceOpers.append(sliceOp.getTriples().begin(), 254149ad3d5SShraiysh Vaishay sliceOp.getTriples().end()); 255149ad3d5SShraiysh Vaishay subcompOpers.append(sliceOp.getFields().begin(), 256149ad3d5SShraiysh Vaishay sliceOp.getFields().end()); 257149ad3d5SShraiysh Vaishay assert(sliceOp.getSubstr().empty() && 2583c7ff45cSValentin Clement "Don't allow substring operations on array_coor. This " 2593c7ff45cSValentin Clement "restriction may be lifted in the future."); 26097d8972cSEric Schweitz } 2611f31795cSEric Schweitz auto xArrCoor = rewriter.create<fir::cg::XArrayCoorOp>( 262149ad3d5SShraiysh Vaishay loc, arrCoor.getType(), arrCoor.getMemref(), shapeOpers, shiftOpers, 263149ad3d5SShraiysh Vaishay sliceOpers, subcompOpers, arrCoor.getIndices(), 264149ad3d5SShraiysh Vaishay arrCoor.getTypeparams()); 26597d8972cSEric Schweitz LLVM_DEBUG(llvm::dbgs() 26697d8972cSEric Schweitz << "rewriting " << arrCoor << " to " << xArrCoor << '\n'); 26797d8972cSEric Schweitz rewriter.replaceOp(arrCoor, xArrCoor.getOperation()->getResults()); 26897d8972cSEric Schweitz return mlir::success(); 26997d8972cSEric Schweitz } 27097d8972cSEric Schweitz }; 27197d8972cSEric Schweitz 272c852174aSJean Perier class DeclareOpConversion : public mlir::OpRewritePattern<fir::DeclareOp> { 273cd5ee271SAbid Qadeer bool preserveDeclare; 274cd5ee271SAbid Qadeer 275c852174aSJean Perier public: 276c852174aSJean Perier using OpRewritePattern::OpRewritePattern; 277cd5ee271SAbid Qadeer DeclareOpConversion(mlir::MLIRContext *ctx, bool preserveDecl) 278cd5ee271SAbid Qadeer : OpRewritePattern(ctx), preserveDeclare(preserveDecl) {} 279c852174aSJean Perier 280db791b27SRamkumar Ramachandra llvm::LogicalResult 281c852174aSJean Perier matchAndRewrite(fir::DeclareOp declareOp, 282c852174aSJean Perier mlir::PatternRewriter &rewriter) const override { 283cd5ee271SAbid Qadeer if (!preserveDeclare) { 284c852174aSJean Perier rewriter.replaceOp(declareOp, declareOp.getMemref()); 285c852174aSJean Perier return mlir::success(); 286c852174aSJean Perier } 287cd5ee271SAbid Qadeer auto loc = declareOp.getLoc(); 288cd5ee271SAbid Qadeer llvm::SmallVector<mlir::Value> shapeOpers; 289cd5ee271SAbid Qadeer llvm::SmallVector<mlir::Value> shiftOpers; 290cd5ee271SAbid Qadeer if (auto shapeVal = declareOp.getShape()) { 291cd5ee271SAbid Qadeer if (auto shapeOp = mlir::dyn_cast<fir::ShapeOp>(shapeVal.getDefiningOp())) 292cd5ee271SAbid Qadeer populateShape(shapeOpers, shapeOp); 293cd5ee271SAbid Qadeer else if (auto shiftOp = 294cd5ee271SAbid Qadeer mlir::dyn_cast<fir::ShapeShiftOp>(shapeVal.getDefiningOp())) 295cd5ee271SAbid Qadeer populateShapeAndShift(shapeOpers, shiftOpers, shiftOp); 296cd5ee271SAbid Qadeer else if (auto shiftOp = 297cd5ee271SAbid Qadeer mlir::dyn_cast<fir::ShiftOp>(shapeVal.getDefiningOp())) 298cd5ee271SAbid Qadeer populateShift(shiftOpers, shiftOp); 299cd5ee271SAbid Qadeer else 300cd5ee271SAbid Qadeer return mlir::failure(); 301cd5ee271SAbid Qadeer } 302cd5ee271SAbid Qadeer // FIXME: Add FortranAttrs and CudaAttrs 303cd5ee271SAbid Qadeer auto xDeclOp = rewriter.create<fir::cg::XDeclareOp>( 304cd5ee271SAbid Qadeer loc, declareOp.getType(), declareOp.getMemref(), shapeOpers, shiftOpers, 305cd5ee271SAbid Qadeer declareOp.getTypeparams(), declareOp.getDummyScope(), 306cd5ee271SAbid Qadeer declareOp.getUniqName()); 307cd5ee271SAbid Qadeer LLVM_DEBUG(llvm::dbgs() 308cd5ee271SAbid Qadeer << "rewriting " << declareOp << " to " << xDeclOp << '\n'); 309cd5ee271SAbid Qadeer rewriter.replaceOp(declareOp, xDeclOp.getOperation()->getResults()); 310cd5ee271SAbid Qadeer return mlir::success(); 311cd5ee271SAbid Qadeer } 312c852174aSJean Perier }; 313c852174aSJean Perier 314986f832cSSlava Zakharin class DummyScopeOpConversion 315986f832cSSlava Zakharin : public mlir::OpRewritePattern<fir::DummyScopeOp> { 316986f832cSSlava Zakharin public: 317986f832cSSlava Zakharin using OpRewritePattern::OpRewritePattern; 318986f832cSSlava Zakharin 319db791b27SRamkumar Ramachandra llvm::LogicalResult 320986f832cSSlava Zakharin matchAndRewrite(fir::DummyScopeOp dummyScopeOp, 321986f832cSSlava Zakharin mlir::PatternRewriter &rewriter) const override { 322986f832cSSlava Zakharin rewriter.replaceOpWithNewOp<fir::UndefOp>(dummyScopeOp, 323986f832cSSlava Zakharin dummyScopeOp.getType()); 324986f832cSSlava Zakharin return mlir::success(); 325986f832cSSlava Zakharin } 326986f832cSSlava Zakharin }; 327986f832cSSlava Zakharin 328bf08d0e1SjeanPerier /// Simple DCE to erase fir.shape/shift/slice/unused shape operands after this 329bf08d0e1SjeanPerier /// pass (fir.shape and like have no codegen). 330bf08d0e1SjeanPerier /// mlir::RegionDCE is expensive and requires running 331bf08d0e1SjeanPerier /// mlir::eraseUnreachableBlocks. It does things that are not needed here, like 332bf08d0e1SjeanPerier /// removing unused block arguments. fir.shape/shift/slice cannot be block 333bf08d0e1SjeanPerier /// arguments. 334bf08d0e1SjeanPerier /// This helper does a naive backward walk of the IR. It is not even guaranteed 335bf08d0e1SjeanPerier /// to walk blocks according to backward dominance, but that is good enough for 336bf08d0e1SjeanPerier /// what is done here, fir.shape/shift/slice have no usages anymore. The 337bf08d0e1SjeanPerier /// backward walk allows getting rid of most of the unused operands, it is not a 338bf08d0e1SjeanPerier /// problem to leave some in the weird cases. 339bf08d0e1SjeanPerier static void simpleDCE(mlir::RewriterBase &rewriter, mlir::Operation *op) { 340bf08d0e1SjeanPerier op->walk<mlir::WalkOrder::PostOrder, mlir::ReverseIterator>( 341bf08d0e1SjeanPerier [&](mlir::Operation *subOp) { 342bf08d0e1SjeanPerier if (mlir::isOpTriviallyDead(subOp)) 343bf08d0e1SjeanPerier rewriter.eraseOp(subOp); 344bf08d0e1SjeanPerier }); 345bf08d0e1SjeanPerier } 346bf08d0e1SjeanPerier 34767d0d7acSMichele Scuttari class CodeGenRewrite : public fir::impl::CodeGenRewriteBase<CodeGenRewrite> { 34897d8972cSEric Schweitz public: 3497eaae4e6STom Eccles using CodeGenRewriteBase<CodeGenRewrite>::CodeGenRewriteBase; 3507eaae4e6STom Eccles 3511f63a56cSTom Eccles void runOnOperation() override final { 3521f63a56cSTom Eccles mlir::ModuleOp mod = getOperation(); 3531f63a56cSTom Eccles 35497d8972cSEric Schweitz auto &context = getContext(); 35597d8972cSEric Schweitz mlir::ConversionTarget target(context); 3566c8d8d10SJakub Kuderski target.addLegalDialect<mlir::arith::ArithDialect, fir::FIROpsDialect, 3571f31795cSEric Schweitz fir::FIRCodeGenDialect, mlir::func::FuncDialect>(); 3581f31795cSEric Schweitz target.addIllegalOp<fir::ArrayCoorOp>(); 3591f31795cSEric Schweitz target.addIllegalOp<fir::ReboxOp>(); 360c852174aSJean Perier target.addIllegalOp<fir::DeclareOp>(); 361986f832cSSlava Zakharin target.addIllegalOp<fir::DummyScopeOp>(); 3621f31795cSEric Schweitz target.addDynamicallyLegalOp<fir::EmboxOp>([](fir::EmboxOp embox) { 363fac349a1SChristian Sigg return !(embox.getShape() || 364fac349a1SChristian Sigg mlir::isa<fir::SequenceType>( 365fac349a1SChristian Sigg mlir::cast<fir::BaseBoxType>(embox.getType()).getEleTy())); 36697d8972cSEric Schweitz }); 3679f85c198SRiver Riddle mlir::RewritePatternSet patterns(&context); 368cd5ee271SAbid Qadeer fir::populatePreCGRewritePatterns(patterns, preserveDeclare); 36997d8972cSEric Schweitz if (mlir::failed( 3701f63a56cSTom Eccles mlir::applyPartialConversion(mod, target, std::move(patterns)))) { 37197d8972cSEric Schweitz mlir::emitError(mlir::UnknownLoc::get(&context), 37297d8972cSEric Schweitz "error in running the pre-codegen conversions"); 37397d8972cSEric Schweitz signalPassFailure(); 3742adcf1b2SJean Perier return; 37597d8972cSEric Schweitz } 3762adcf1b2SJean Perier // Erase any residual (fir.shape, fir.slice...). 3772adcf1b2SJean Perier mlir::IRRewriter rewriter(&context); 378bf08d0e1SjeanPerier simpleDCE(rewriter, mod.getOperation()); 379b09426ffSValentin Clement } 38097d8972cSEric Schweitz }; 38197d8972cSEric Schweitz 38297d8972cSEric Schweitz } // namespace 38397d8972cSEric Schweitz 384cd5ee271SAbid Qadeer void fir::populatePreCGRewritePatterns(mlir::RewritePatternSet &patterns, 385cd5ee271SAbid Qadeer bool preserveDeclare) { 38622eb8000SValentin Clement (バレンタイン クレメン) patterns.insert<EmboxConversion, ArrayCoorConversion, ReboxConversion, 387cd5ee271SAbid Qadeer DummyScopeOpConversion>(patterns.getContext()); 388cd5ee271SAbid Qadeer patterns.add<DeclareOpConversion>(patterns.getContext(), preserveDeclare); 38922eb8000SValentin Clement (バレンタイン クレメン) } 390