[NFC] More synching of sources for upstreaming.
Reviewed By: clementval Differential Revision: https://reviews.llvm.org/D124476
This commit is contained in:
		
							parent
							
								
									df08b34938
								
							
						
					
					
						commit
						44e58509be
					
				| 
						 | 
					@ -32,8 +32,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DEBUG_TYPE "flang-codegen"
 | 
					#define DEBUG_TYPE "flang-codegen"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace mlir;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// fir::LLVMTypeConverter for converting to LLVM IR dialect types.
 | 
					// fir::LLVMTypeConverter for converting to LLVM IR dialect types.
 | 
				
			||||||
#include "TypeConverter.h"
 | 
					#include "TypeConverter.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,8 +55,8 @@ genConstantIndex(mlir::Location loc, mlir::Type ity,
 | 
				
			||||||
  return rewriter.create<mlir::LLVM::ConstantOp>(loc, ity, cattr);
 | 
					  return rewriter.create<mlir::LLVM::ConstantOp>(loc, ity, cattr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Block *createBlock(mlir::ConversionPatternRewriter &rewriter,
 | 
					static mlir::Block *createBlock(mlir::ConversionPatternRewriter &rewriter,
 | 
				
			||||||
                          mlir::Block *insertBefore) {
 | 
					                                mlir::Block *insertBefore) {
 | 
				
			||||||
  assert(insertBefore && "expected valid insertion block");
 | 
					  assert(insertBefore && "expected valid insertion block");
 | 
				
			||||||
  return rewriter.createBlock(insertBefore->getParent(),
 | 
					  return rewriter.createBlock(insertBefore->getParent(),
 | 
				
			||||||
                              mlir::Region::iterator(insertBefore));
 | 
					                              mlir::Region::iterator(insertBefore));
 | 
				
			||||||
| 
						 | 
					@ -138,8 +136,8 @@ protected:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Method to construct code sequence to get the triple for dimension `dim`
 | 
					  /// Method to construct code sequence to get the triple for dimension `dim`
 | 
				
			||||||
  /// from a box.
 | 
					  /// from a box.
 | 
				
			||||||
  SmallVector<mlir::Value, 3>
 | 
					  llvm::SmallVector<mlir::Value, 3>
 | 
				
			||||||
  getDimsFromBox(mlir::Location loc, ArrayRef<mlir::Type> retTys,
 | 
					  getDimsFromBox(mlir::Location loc, llvm::ArrayRef<mlir::Type> retTys,
 | 
				
			||||||
                 mlir::Value box, mlir::Value dim,
 | 
					                 mlir::Value box, mlir::Value dim,
 | 
				
			||||||
                 mlir::ConversionPatternRewriter &rewriter) const {
 | 
					                 mlir::ConversionPatternRewriter &rewriter) const {
 | 
				
			||||||
    mlir::LLVM::ConstantOp c0 = genConstantOffset(loc, rewriter, 0);
 | 
					    mlir::LLVM::ConstantOp c0 = genConstantOffset(loc, rewriter, 0);
 | 
				
			||||||
| 
						 | 
					@ -248,7 +246,7 @@ protected:
 | 
				
			||||||
  mlir::LLVM::GEPOp genGEP(mlir::Location loc, mlir::Type ty,
 | 
					  mlir::LLVM::GEPOp genGEP(mlir::Location loc, mlir::Type ty,
 | 
				
			||||||
                           mlir::ConversionPatternRewriter &rewriter,
 | 
					                           mlir::ConversionPatternRewriter &rewriter,
 | 
				
			||||||
                           mlir::Value base, ARGS... args) const {
 | 
					                           mlir::Value base, ARGS... args) const {
 | 
				
			||||||
    SmallVector<mlir::Value> cv{args...};
 | 
					    llvm::SmallVector<mlir::Value> cv{args...};
 | 
				
			||||||
    return rewriter.create<mlir::LLVM::GEPOp>(loc, ty, base, cv);
 | 
					    return rewriter.create<mlir::LLVM::GEPOp>(loc, ty, base, cv);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -288,7 +286,7 @@ struct AddrOfOpConversion : public FIROpConversion<fir::AddrOfOp> {
 | 
				
			||||||
    auto ty = convertType(addr.getType());
 | 
					    auto ty = convertType(addr.getType());
 | 
				
			||||||
    rewriter.replaceOpWithNewOp<mlir::LLVM::AddressOfOp>(
 | 
					    rewriter.replaceOpWithNewOp<mlir::LLVM::AddressOfOp>(
 | 
				
			||||||
        addr, ty, addr.getSymbol().getRootReference().getValue());
 | 
					        addr, ty, addr.getSymbol().getRootReference().getValue());
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
} // namespace
 | 
					} // namespace
 | 
				
			||||||
| 
						 | 
					@ -379,7 +377,7 @@ struct AllocaOpConversion : public FIROpConversion<fir::AllocaOp> {
 | 
				
			||||||
                                                      alloc->getAttrs());
 | 
					                                                      alloc->getAttrs());
 | 
				
			||||||
      rewriter.replaceOpWithNewOp<mlir::LLVM::BitcastOp>(alloc, resultTy, al);
 | 
					      rewriter.replaceOpWithNewOp<mlir::LLVM::BitcastOp>(alloc, resultTy, al);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
} // namespace
 | 
					} // namespace
 | 
				
			||||||
| 
						 | 
					@ -415,7 +413,7 @@ struct BoxAddrOpConversion : public FIROpConversion<fir::BoxAddrOp> {
 | 
				
			||||||
      rewriter.replaceOpWithNewOp<mlir::LLVM::ExtractValueOp>(boxaddr, ty, a,
 | 
					      rewriter.replaceOpWithNewOp<mlir::LLVM::ExtractValueOp>(boxaddr, ty, a,
 | 
				
			||||||
                                                              c0);
 | 
					                                                              c0);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -438,7 +436,7 @@ struct BoxCharLenOpConversion : public FIROpConversion<fir::BoxCharLenOp> {
 | 
				
			||||||
    mlir::Value lenAfterCast = integerCast(loc, rewriter, returnValTy, len);
 | 
					    mlir::Value lenAfterCast = integerCast(loc, rewriter, returnValTy, len);
 | 
				
			||||||
    rewriter.replaceOp(boxCharLen, lenAfterCast);
 | 
					    rewriter.replaceOp(boxCharLen, lenAfterCast);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -451,7 +449,7 @@ struct BoxDimsOpConversion : public FIROpConversion<fir::BoxDimsOp> {
 | 
				
			||||||
  mlir::LogicalResult
 | 
					  mlir::LogicalResult
 | 
				
			||||||
  matchAndRewrite(fir::BoxDimsOp boxdims, OpAdaptor adaptor,
 | 
					  matchAndRewrite(fir::BoxDimsOp boxdims, OpAdaptor adaptor,
 | 
				
			||||||
                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
					                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
				
			||||||
    SmallVector<mlir::Type, 3> resultTypes = {
 | 
					    llvm::SmallVector<mlir::Type, 3> resultTypes = {
 | 
				
			||||||
        convertType(boxdims.getResult(0).getType()),
 | 
					        convertType(boxdims.getResult(0).getType()),
 | 
				
			||||||
        convertType(boxdims.getResult(1).getType()),
 | 
					        convertType(boxdims.getResult(1).getType()),
 | 
				
			||||||
        convertType(boxdims.getResult(2).getType()),
 | 
					        convertType(boxdims.getResult(2).getType()),
 | 
				
			||||||
| 
						 | 
					@ -460,7 +458,7 @@ struct BoxDimsOpConversion : public FIROpConversion<fir::BoxDimsOp> {
 | 
				
			||||||
        getDimsFromBox(boxdims.getLoc(), resultTypes, adaptor.getOperands()[0],
 | 
					        getDimsFromBox(boxdims.getLoc(), resultTypes, adaptor.getOperands()[0],
 | 
				
			||||||
                       adaptor.getOperands()[1], rewriter);
 | 
					                       adaptor.getOperands()[1], rewriter);
 | 
				
			||||||
    rewriter.replaceOp(boxdims, results);
 | 
					    rewriter.replaceOp(boxdims, results);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -477,7 +475,7 @@ struct BoxEleSizeOpConversion : public FIROpConversion<fir::BoxEleSizeOp> {
 | 
				
			||||||
    auto ty = convertType(boxelesz.getType());
 | 
					    auto ty = convertType(boxelesz.getType());
 | 
				
			||||||
    auto elemSize = getValueFromBox(loc, a, ty, rewriter, kElemLenPosInBox);
 | 
					    auto elemSize = getValueFromBox(loc, a, ty, rewriter, kElemLenPosInBox);
 | 
				
			||||||
    rewriter.replaceOp(boxelesz, elemSize);
 | 
					    rewriter.replaceOp(boxelesz, elemSize);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -494,7 +492,7 @@ struct BoxIsAllocOpConversion : public FIROpConversion<fir::BoxIsAllocOp> {
 | 
				
			||||||
    mlir::Value check =
 | 
					    mlir::Value check =
 | 
				
			||||||
        genBoxAttributeCheck(loc, box, rewriter, kAttrAllocatable);
 | 
					        genBoxAttributeCheck(loc, box, rewriter, kAttrAllocatable);
 | 
				
			||||||
    rewriter.replaceOp(boxisalloc, check);
 | 
					    rewriter.replaceOp(boxisalloc, check);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -513,7 +511,7 @@ struct BoxIsArrayOpConversion : public FIROpConversion<fir::BoxIsArrayOp> {
 | 
				
			||||||
    auto c0 = genConstantOffset(loc, rewriter, 0);
 | 
					    auto c0 = genConstantOffset(loc, rewriter, 0);
 | 
				
			||||||
    rewriter.replaceOpWithNewOp<mlir::LLVM::ICmpOp>(
 | 
					    rewriter.replaceOpWithNewOp<mlir::LLVM::ICmpOp>(
 | 
				
			||||||
        boxisarray, mlir::LLVM::ICmpPredicate::ne, rank, c0);
 | 
					        boxisarray, mlir::LLVM::ICmpPredicate::ne, rank, c0);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -529,7 +527,7 @@ struct BoxIsPtrOpConversion : public FIROpConversion<fir::BoxIsPtrOp> {
 | 
				
			||||||
    auto loc = boxisptr.getLoc();
 | 
					    auto loc = boxisptr.getLoc();
 | 
				
			||||||
    mlir::Value check = genBoxAttributeCheck(loc, box, rewriter, kAttrPointer);
 | 
					    mlir::Value check = genBoxAttributeCheck(loc, box, rewriter, kAttrPointer);
 | 
				
			||||||
    rewriter.replaceOp(boxisptr, check);
 | 
					    rewriter.replaceOp(boxisptr, check);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -546,7 +544,7 @@ struct BoxRankOpConversion : public FIROpConversion<fir::BoxRankOp> {
 | 
				
			||||||
    mlir::Type ty = convertType(boxrank.getType());
 | 
					    mlir::Type ty = convertType(boxrank.getType());
 | 
				
			||||||
    auto result = getValueFromBox(loc, a, ty, rewriter, kRankPosInBox);
 | 
					    auto result = getValueFromBox(loc, a, ty, rewriter, kRankPosInBox);
 | 
				
			||||||
    rewriter.replaceOp(boxrank, result);
 | 
					    rewriter.replaceOp(boxrank, result);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -560,7 +558,7 @@ struct BoxProcHostOpConversion : public FIROpConversion<fir::BoxProcHostOp> {
 | 
				
			||||||
  matchAndRewrite(fir::BoxProcHostOp boxprochost, OpAdaptor adaptor,
 | 
					  matchAndRewrite(fir::BoxProcHostOp boxprochost, OpAdaptor adaptor,
 | 
				
			||||||
                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
					                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
				
			||||||
    TODO(boxprochost.getLoc(), "fir.boxproc_host codegen");
 | 
					    TODO(boxprochost.getLoc(), "fir.boxproc_host codegen");
 | 
				
			||||||
    return failure();
 | 
					    return mlir::failure();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -580,7 +578,7 @@ struct BoxTypeDescOpConversion : public FIROpConversion<fir::BoxTypeDescOp> {
 | 
				
			||||||
    auto typePtrTy = mlir::LLVM::LLVMPointerType::get(typeTy);
 | 
					    auto typePtrTy = mlir::LLVM::LLVMPointerType::get(typeTy);
 | 
				
			||||||
    rewriter.replaceOpWithNewOp<mlir::LLVM::IntToPtrOp>(boxtypedesc, typePtrTy,
 | 
					    rewriter.replaceOpWithNewOp<mlir::LLVM::IntToPtrOp>(boxtypedesc, typePtrTy,
 | 
				
			||||||
                                                        result);
 | 
					                                                        result);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -595,7 +593,7 @@ struct StringLitOpConversion : public FIROpConversion<fir::StringLitOp> {
 | 
				
			||||||
    auto attr = constop.getValue();
 | 
					    auto attr = constop.getValue();
 | 
				
			||||||
    if (attr.isa<mlir::StringAttr>()) {
 | 
					    if (attr.isa<mlir::StringAttr>()) {
 | 
				
			||||||
      rewriter.replaceOpWithNewOp<mlir::LLVM::ConstantOp>(constop, ty, attr);
 | 
					      rewriter.replaceOpWithNewOp<mlir::LLVM::ConstantOp>(constop, ty, attr);
 | 
				
			||||||
      return success();
 | 
					      return mlir::success();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto charTy = constop.getType().cast<fir::CharacterType>();
 | 
					    auto charTy = constop.getType().cast<fir::CharacterType>();
 | 
				
			||||||
| 
						 | 
					@ -619,10 +617,10 @@ struct StringLitOpConversion : public FIROpConversion<fir::StringLitOp> {
 | 
				
			||||||
                                                         index);
 | 
					                                                         index);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      return failure();
 | 
					      return mlir::failure();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    rewriter.replaceOp(constop, cst);
 | 
					    rewriter.replaceOp(constop, cst);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -633,12 +631,12 @@ struct CallOpConversion : public FIROpConversion<fir::CallOp> {
 | 
				
			||||||
  mlir::LogicalResult
 | 
					  mlir::LogicalResult
 | 
				
			||||||
  matchAndRewrite(fir::CallOp call, OpAdaptor adaptor,
 | 
					  matchAndRewrite(fir::CallOp call, OpAdaptor adaptor,
 | 
				
			||||||
                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
					                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
				
			||||||
    SmallVector<mlir::Type> resultTys;
 | 
					    llvm::SmallVector<mlir::Type> resultTys;
 | 
				
			||||||
    for (auto r : call.getResults())
 | 
					    for (auto r : call.getResults())
 | 
				
			||||||
      resultTys.push_back(convertType(r.getType()));
 | 
					      resultTys.push_back(convertType(r.getType()));
 | 
				
			||||||
    rewriter.replaceOpWithNewOp<mlir::LLVM::CallOp>(
 | 
					    rewriter.replaceOpWithNewOp<mlir::LLVM::CallOp>(
 | 
				
			||||||
        call, resultTys, adaptor.getOperands(), call->getAttrs());
 | 
					        call, resultTys, adaptor.getOperands(), call->getAttrs());
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
} // namespace
 | 
					} // namespace
 | 
				
			||||||
| 
						 | 
					@ -667,20 +665,22 @@ struct CmpcOpConversion : public FIROpConversion<fir::CmpcOp> {
 | 
				
			||||||
    mlir::Type resTy = convertType(cmp.getType());
 | 
					    mlir::Type resTy = convertType(cmp.getType());
 | 
				
			||||||
    mlir::Location loc = cmp.getLoc();
 | 
					    mlir::Location loc = cmp.getLoc();
 | 
				
			||||||
    auto pos0 = mlir::ArrayAttr::get(ctxt, rewriter.getI32IntegerAttr(0));
 | 
					    auto pos0 = mlir::ArrayAttr::get(ctxt, rewriter.getI32IntegerAttr(0));
 | 
				
			||||||
    SmallVector<mlir::Value, 2> rp{rewriter.create<mlir::LLVM::ExtractValueOp>(
 | 
					    llvm::SmallVector<mlir::Value, 2> rp{
 | 
				
			||||||
                                       loc, eleTy, operands[0], pos0),
 | 
					        rewriter.create<mlir::LLVM::ExtractValueOp>(loc, eleTy, operands[0],
 | 
				
			||||||
                                   rewriter.create<mlir::LLVM::ExtractValueOp>(
 | 
					                                                    pos0),
 | 
				
			||||||
                                       loc, eleTy, operands[1], pos0)};
 | 
					        rewriter.create<mlir::LLVM::ExtractValueOp>(loc, eleTy, operands[1],
 | 
				
			||||||
 | 
					                                                    pos0)};
 | 
				
			||||||
    auto rcp =
 | 
					    auto rcp =
 | 
				
			||||||
        rewriter.create<mlir::LLVM::FCmpOp>(loc, resTy, rp, cmp->getAttrs());
 | 
					        rewriter.create<mlir::LLVM::FCmpOp>(loc, resTy, rp, cmp->getAttrs());
 | 
				
			||||||
    auto pos1 = mlir::ArrayAttr::get(ctxt, rewriter.getI32IntegerAttr(1));
 | 
					    auto pos1 = mlir::ArrayAttr::get(ctxt, rewriter.getI32IntegerAttr(1));
 | 
				
			||||||
    SmallVector<mlir::Value, 2> ip{rewriter.create<mlir::LLVM::ExtractValueOp>(
 | 
					    llvm::SmallVector<mlir::Value, 2> ip{
 | 
				
			||||||
                                       loc, eleTy, operands[0], pos1),
 | 
					        rewriter.create<mlir::LLVM::ExtractValueOp>(loc, eleTy, operands[0],
 | 
				
			||||||
                                   rewriter.create<mlir::LLVM::ExtractValueOp>(
 | 
					                                                    pos1),
 | 
				
			||||||
                                       loc, eleTy, operands[1], pos1)};
 | 
					        rewriter.create<mlir::LLVM::ExtractValueOp>(loc, eleTy, operands[1],
 | 
				
			||||||
 | 
					                                                    pos1)};
 | 
				
			||||||
    auto icp =
 | 
					    auto icp =
 | 
				
			||||||
        rewriter.create<mlir::LLVM::FCmpOp>(loc, resTy, ip, cmp->getAttrs());
 | 
					        rewriter.create<mlir::LLVM::FCmpOp>(loc, resTy, ip, cmp->getAttrs());
 | 
				
			||||||
    SmallVector<mlir::Value, 2> cp{rcp, icp};
 | 
					    llvm::SmallVector<mlir::Value, 2> cp{rcp, icp};
 | 
				
			||||||
    switch (cmp.getPredicate()) {
 | 
					    switch (cmp.getPredicate()) {
 | 
				
			||||||
    case mlir::arith::CmpFPredicate::OEQ: // .EQ.
 | 
					    case mlir::arith::CmpFPredicate::OEQ: // .EQ.
 | 
				
			||||||
      rewriter.replaceOpWithNewOp<mlir::LLVM::AndOp>(cmp, resTy, cp);
 | 
					      rewriter.replaceOpWithNewOp<mlir::LLVM::AndOp>(cmp, resTy, cp);
 | 
				
			||||||
| 
						 | 
					@ -692,7 +692,7 @@ struct CmpcOpConversion : public FIROpConversion<fir::CmpcOp> {
 | 
				
			||||||
      rewriter.replaceOp(cmp, rcp.getResult());
 | 
					      rewriter.replaceOp(cmp, rcp.getResult());
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -720,10 +720,10 @@ struct ConstcOpConversion : public FIROpConversion<fir::ConstcOp> {
 | 
				
			||||||
        loc, ty, undef, realPart, realIndex);
 | 
					        loc, ty, undef, realPart, realIndex);
 | 
				
			||||||
    rewriter.replaceOpWithNewOp<mlir::LLVM::InsertValueOp>(conc, ty, setReal,
 | 
					    rewriter.replaceOpWithNewOp<mlir::LLVM::InsertValueOp>(conc, ty, setReal,
 | 
				
			||||||
                                                           imPart, imIndex);
 | 
					                                                           imPart, imIndex);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  inline APFloat getValue(mlir::Attribute attr) const {
 | 
					  inline llvm::APFloat getValue(mlir::Attribute attr) const {
 | 
				
			||||||
    return attr.cast<fir::RealAttr>().getValue();
 | 
					    return attr.cast<fir::RealAttr>().getValue();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -746,7 +746,7 @@ struct ConvertOpConversion : public FIROpConversion<fir::ConvertOp> {
 | 
				
			||||||
    mlir::Value op0 = adaptor.getOperands()[0];
 | 
					    mlir::Value op0 = adaptor.getOperands()[0];
 | 
				
			||||||
    if (fromTy == toTy) {
 | 
					    if (fromTy == toTy) {
 | 
				
			||||||
      rewriter.replaceOp(convert, op0);
 | 
					      rewriter.replaceOp(convert, op0);
 | 
				
			||||||
      return success();
 | 
					      return mlir::success();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    auto loc = convert.getLoc();
 | 
					    auto loc = convert.getLoc();
 | 
				
			||||||
    auto convertFpToFp = [&](mlir::Value val, unsigned fromBits,
 | 
					    auto convertFpToFp = [&](mlir::Value val, unsigned fromBits,
 | 
				
			||||||
| 
						 | 
					@ -863,7 +863,7 @@ struct DispatchOpConversion : public FIROpConversion<fir::DispatchOp> {
 | 
				
			||||||
  matchAndRewrite(fir::DispatchOp dispatch, OpAdaptor adaptor,
 | 
					  matchAndRewrite(fir::DispatchOp dispatch, OpAdaptor adaptor,
 | 
				
			||||||
                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
					                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
				
			||||||
    TODO(dispatch.getLoc(), "fir.dispatch codegen");
 | 
					    TODO(dispatch.getLoc(), "fir.dispatch codegen");
 | 
				
			||||||
    return failure();
 | 
					    return mlir::failure();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -877,7 +877,7 @@ struct DispatchTableOpConversion
 | 
				
			||||||
  matchAndRewrite(fir::DispatchTableOp dispTab, OpAdaptor adaptor,
 | 
					  matchAndRewrite(fir::DispatchTableOp dispTab, OpAdaptor adaptor,
 | 
				
			||||||
                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
					                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
				
			||||||
    TODO(dispTab.getLoc(), "fir.dispatch_table codegen");
 | 
					    TODO(dispTab.getLoc(), "fir.dispatch_table codegen");
 | 
				
			||||||
    return failure();
 | 
					    return mlir::failure();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -890,7 +890,7 @@ struct DTEntryOpConversion : public FIROpConversion<fir::DTEntryOp> {
 | 
				
			||||||
  matchAndRewrite(fir::DTEntryOp dtEnt, OpAdaptor adaptor,
 | 
					  matchAndRewrite(fir::DTEntryOp dtEnt, OpAdaptor adaptor,
 | 
				
			||||||
                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
					                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
				
			||||||
    TODO(dtEnt.getLoc(), "fir.dt_entry codegen");
 | 
					    TODO(dtEnt.getLoc(), "fir.dt_entry codegen");
 | 
				
			||||||
    return failure();
 | 
					    return mlir::failure();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -902,7 +902,7 @@ struct GlobalLenOpConversion : public FIROpConversion<fir::GlobalLenOp> {
 | 
				
			||||||
  matchAndRewrite(fir::GlobalLenOp globalLen, OpAdaptor adaptor,
 | 
					  matchAndRewrite(fir::GlobalLenOp globalLen, OpAdaptor adaptor,
 | 
				
			||||||
                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
					                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
				
			||||||
    TODO(globalLen.getLoc(), "fir.global_len codegen");
 | 
					    TODO(globalLen.getLoc(), "fir.global_len codegen");
 | 
				
			||||||
    return failure();
 | 
					    return mlir::failure();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -930,7 +930,7 @@ struct EmboxCharOpConversion : public FIROpConversion<fir::EmboxCharOp> {
 | 
				
			||||||
  matchAndRewrite(fir::EmboxCharOp emboxChar, OpAdaptor adaptor,
 | 
					  matchAndRewrite(fir::EmboxCharOp emboxChar, OpAdaptor adaptor,
 | 
				
			||||||
                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
					                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
				
			||||||
    mlir::ValueRange operands = adaptor.getOperands();
 | 
					    mlir::ValueRange operands = adaptor.getOperands();
 | 
				
			||||||
    MLIRContext *ctx = emboxChar.getContext();
 | 
					    auto *ctx = emboxChar.getContext();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mlir::Value charBuffer = operands[0];
 | 
					    mlir::Value charBuffer = operands[0];
 | 
				
			||||||
    mlir::Value charBufferLen = operands[1];
 | 
					    mlir::Value charBufferLen = operands[1];
 | 
				
			||||||
| 
						 | 
					@ -950,7 +950,7 @@ struct EmboxCharOpConversion : public FIROpConversion<fir::EmboxCharOp> {
 | 
				
			||||||
    rewriter.replaceOpWithNewOp<mlir::LLVM::InsertValueOp>(
 | 
					    rewriter.replaceOpWithNewOp<mlir::LLVM::InsertValueOp>(
 | 
				
			||||||
        emboxChar, llvmStructTy, insertBufferOp, lenAfterCast, c1);
 | 
					        emboxChar, llvmStructTy, insertBufferOp, lenAfterCast, c1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
} // namespace
 | 
					} // namespace
 | 
				
			||||||
| 
						 | 
					@ -1021,7 +1021,7 @@ struct AllocMemOpConversion : public FIROpConversion<fir::AllocMemOp> {
 | 
				
			||||||
        loc, ::getVoidPtrType(heap.getContext()), size, heap->getAttrs());
 | 
					        loc, ::getVoidPtrType(heap.getContext()), size, heap->getAttrs());
 | 
				
			||||||
    rewriter.replaceOpWithNewOp<mlir::LLVM::BitcastOp>(heap, ty,
 | 
					    rewriter.replaceOpWithNewOp<mlir::LLVM::BitcastOp>(heap, ty,
 | 
				
			||||||
                                                       malloc.getResult(0));
 | 
					                                                       malloc.getResult(0));
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Compute the (allocation) size of the allocmem type in bytes.
 | 
					  // Compute the (allocation) size of the allocmem type in bytes.
 | 
				
			||||||
| 
						 | 
					@ -1072,7 +1072,7 @@ struct FreeMemOpConversion : public FIROpConversion<fir::FreeMemOp> {
 | 
				
			||||||
    rewriter.create<mlir::LLVM::CallOp>(
 | 
					    rewriter.create<mlir::LLVM::CallOp>(
 | 
				
			||||||
        loc, mlir::TypeRange{}, mlir::ValueRange{bitcast}, freemem->getAttrs());
 | 
					        loc, mlir::TypeRange{}, mlir::ValueRange{bitcast}, freemem->getAttrs());
 | 
				
			||||||
    rewriter.eraseOp(freemem);
 | 
					    rewriter.eraseOp(freemem);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
} // namespace
 | 
					} // namespace
 | 
				
			||||||
| 
						 | 
					@ -1240,15 +1240,15 @@ struct EmboxCommonConversion : public FIROpConversion<OP> {
 | 
				
			||||||
  /// Basic pattern to write a field in the descriptor
 | 
					  /// Basic pattern to write a field in the descriptor
 | 
				
			||||||
  mlir::Value insertField(mlir::ConversionPatternRewriter &rewriter,
 | 
					  mlir::Value insertField(mlir::ConversionPatternRewriter &rewriter,
 | 
				
			||||||
                          mlir::Location loc, mlir::Value dest,
 | 
					                          mlir::Location loc, mlir::Value dest,
 | 
				
			||||||
                          ArrayRef<unsigned> fldIndexes, mlir::Value value,
 | 
					                          llvm::ArrayRef<unsigned> fldIndexes,
 | 
				
			||||||
                          bool bitcast = false) const {
 | 
					                          mlir::Value value, bool bitcast = false) const {
 | 
				
			||||||
    auto boxTy = dest.getType();
 | 
					    auto boxTy = dest.getType();
 | 
				
			||||||
    auto fldTy = this->getBoxEleTy(boxTy, fldIndexes);
 | 
					    auto fldTy = this->getBoxEleTy(boxTy, fldIndexes);
 | 
				
			||||||
    if (bitcast)
 | 
					    if (bitcast)
 | 
				
			||||||
      value = rewriter.create<mlir::LLVM::BitcastOp>(loc, fldTy, value);
 | 
					      value = rewriter.create<mlir::LLVM::BitcastOp>(loc, fldTy, value);
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      value = this->integerCast(loc, rewriter, fldTy, value);
 | 
					      value = this->integerCast(loc, rewriter, fldTy, value);
 | 
				
			||||||
    SmallVector<mlir::Attribute, 2> attrs;
 | 
					    llvm::SmallVector<mlir::Attribute, 2> attrs;
 | 
				
			||||||
    for (auto i : fldIndexes)
 | 
					    for (auto i : fldIndexes)
 | 
				
			||||||
      attrs.push_back(rewriter.getI32IntegerAttr(i));
 | 
					      attrs.push_back(rewriter.getI32IntegerAttr(i));
 | 
				
			||||||
    auto indexesAttr = mlir::ArrayAttr::get(rewriter.getContext(), attrs);
 | 
					    auto indexesAttr = mlir::ArrayAttr::get(rewriter.getContext(), attrs);
 | 
				
			||||||
| 
						 | 
					@ -1433,11 +1433,11 @@ struct EmboxOpConversion : public EmboxCommonConversion<fir::EmboxOp> {
 | 
				
			||||||
    if (isDerivedTypeWithLenParams(boxTy)) {
 | 
					    if (isDerivedTypeWithLenParams(boxTy)) {
 | 
				
			||||||
      TODO(embox.getLoc(),
 | 
					      TODO(embox.getLoc(),
 | 
				
			||||||
           "fir.embox codegen of derived with length parameters");
 | 
					           "fir.embox codegen of derived with length parameters");
 | 
				
			||||||
      return failure();
 | 
					      return mlir::failure();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    auto result = placeInMemoryIfNotGlobalInit(rewriter, embox.getLoc(), dest);
 | 
					    auto result = placeInMemoryIfNotGlobalInit(rewriter, embox.getLoc(), dest);
 | 
				
			||||||
    rewriter.replaceOp(embox, result);
 | 
					    rewriter.replaceOp(embox, result);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1619,7 +1619,7 @@ struct XEmboxOpConversion : public EmboxCommonConversion<fir::cg::XEmboxOp> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mlir::Value result = placeInMemoryIfNotGlobalInit(rewriter, loc, dest);
 | 
					    mlir::Value result = placeInMemoryIfNotGlobalInit(rewriter, loc, dest);
 | 
				
			||||||
    rewriter.replaceOp(xbox, result);
 | 
					    rewriter.replaceOp(xbox, result);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Return true if `xbox` has a normalized lower bounds attribute. A box value
 | 
					  /// Return true if `xbox` has a normalized lower bounds attribute. A box value
 | 
				
			||||||
| 
						 | 
					@ -1667,7 +1667,7 @@ struct XReboxOpConversion : public EmboxCommonConversion<fir::cg::XReboxOp> {
 | 
				
			||||||
    const unsigned inputRank = rebox.getRank();
 | 
					    const unsigned inputRank = rebox.getRank();
 | 
				
			||||||
    for (unsigned i = 0; i < inputRank; ++i) {
 | 
					    for (unsigned i = 0; i < inputRank; ++i) {
 | 
				
			||||||
      mlir::Value dim = genConstantIndex(loc, idxTy, rewriter, i);
 | 
					      mlir::Value dim = genConstantIndex(loc, idxTy, rewriter, i);
 | 
				
			||||||
      SmallVector<mlir::Value, 3> dimInfo =
 | 
					      llvm::SmallVector<mlir::Value, 3> dimInfo =
 | 
				
			||||||
          getDimsFromBox(loc, {idxTy, idxTy, idxTy}, loweredBox, dim, rewriter);
 | 
					          getDimsFromBox(loc, {idxTy, idxTy, idxTy}, loweredBox, dim, rewriter);
 | 
				
			||||||
      inputExtents.emplace_back(dimInfo[1]);
 | 
					      inputExtents.emplace_back(dimInfo[1]);
 | 
				
			||||||
      inputStrides.emplace_back(dimInfo[2]);
 | 
					      inputStrides.emplace_back(dimInfo[2]);
 | 
				
			||||||
| 
						 | 
					@ -1714,7 +1714,7 @@ private:
 | 
				
			||||||
    mlir::Value result =
 | 
					    mlir::Value result =
 | 
				
			||||||
        placeInMemoryIfNotGlobalInit(rewriter, rebox.getLoc(), dest);
 | 
					        placeInMemoryIfNotGlobalInit(rewriter, rebox.getLoc(), dest);
 | 
				
			||||||
    rewriter.replaceOp(rebox, result);
 | 
					    rewriter.replaceOp(rebox, result);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Apply slice given the base address, extents and strides of the input box.
 | 
					  // Apply slice given the base address, extents and strides of the input box.
 | 
				
			||||||
| 
						 | 
					@ -1864,7 +1864,7 @@ struct EmboxProcOpConversion : public FIROpConversion<fir::EmboxProcOp> {
 | 
				
			||||||
  matchAndRewrite(fir::EmboxProcOp emboxproc, OpAdaptor adaptor,
 | 
					  matchAndRewrite(fir::EmboxProcOp emboxproc, OpAdaptor adaptor,
 | 
				
			||||||
                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
					                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
				
			||||||
    TODO(emboxproc.getLoc(), "fir.emboxproc codegen");
 | 
					    TODO(emboxproc.getLoc(), "fir.emboxproc codegen");
 | 
				
			||||||
    return failure();
 | 
					    return mlir::failure();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1872,7 +1872,7 @@ struct EmboxProcOpConversion : public FIROpConversion<fir::EmboxProcOp> {
 | 
				
			||||||
struct ValueOpCommon {
 | 
					struct ValueOpCommon {
 | 
				
			||||||
  // Translate the arguments pertaining to any multidimensional array to
 | 
					  // Translate the arguments pertaining to any multidimensional array to
 | 
				
			||||||
  // row-major order for LLVM-IR.
 | 
					  // row-major order for LLVM-IR.
 | 
				
			||||||
  static void toRowMajor(SmallVectorImpl<mlir::Attribute> &attrs,
 | 
					  static void toRowMajor(llvm::SmallVectorImpl<mlir::Attribute> &attrs,
 | 
				
			||||||
                         mlir::Type ty) {
 | 
					                         mlir::Type ty) {
 | 
				
			||||||
    assert(ty && "type is null");
 | 
					    assert(ty && "type is null");
 | 
				
			||||||
    const auto end = attrs.size();
 | 
					    const auto end = attrs.size();
 | 
				
			||||||
| 
						 | 
					@ -1944,7 +1944,7 @@ struct ExtractValueOpConversion
 | 
				
			||||||
    auto position = mlir::ArrayAttr::get(extractVal.getContext(), attrs);
 | 
					    auto position = mlir::ArrayAttr::get(extractVal.getContext(), attrs);
 | 
				
			||||||
    rewriter.replaceOpWithNewOp<mlir::LLVM::ExtractValueOp>(
 | 
					    rewriter.replaceOpWithNewOp<mlir::LLVM::ExtractValueOp>(
 | 
				
			||||||
        extractVal, ty, adaptor.getOperands()[0], position);
 | 
					        extractVal, ty, adaptor.getOperands()[0], position);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1964,7 +1964,7 @@ struct InsertValueOpConversion
 | 
				
			||||||
    rewriter.replaceOpWithNewOp<mlir::LLVM::InsertValueOp>(
 | 
					    rewriter.replaceOpWithNewOp<mlir::LLVM::InsertValueOp>(
 | 
				
			||||||
        insertVal, ty, adaptor.getOperands()[0], adaptor.getOperands()[1],
 | 
					        insertVal, ty, adaptor.getOperands()[0], adaptor.getOperands()[1],
 | 
				
			||||||
        position);
 | 
					        position);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1974,8 +1974,8 @@ struct InsertOnRangeOpConversion
 | 
				
			||||||
  using FIROpAndTypeConversion::FIROpAndTypeConversion;
 | 
					  using FIROpAndTypeConversion::FIROpAndTypeConversion;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Increments an array of subscripts in a row major fasion.
 | 
					  // Increments an array of subscripts in a row major fasion.
 | 
				
			||||||
  void incrementSubscripts(const SmallVector<uint64_t> &dims,
 | 
					  void incrementSubscripts(const llvm::SmallVector<uint64_t> &dims,
 | 
				
			||||||
                           SmallVector<uint64_t> &subscripts) const {
 | 
					                           llvm::SmallVector<uint64_t> &subscripts) const {
 | 
				
			||||||
    for (size_t i = dims.size(); i > 0; --i) {
 | 
					    for (size_t i = dims.size(); i > 0; --i) {
 | 
				
			||||||
      if (++subscripts[i - 1] < dims[i - 1]) {
 | 
					      if (++subscripts[i - 1] < dims[i - 1]) {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
| 
						 | 
					@ -1997,8 +1997,8 @@ struct InsertOnRangeOpConversion
 | 
				
			||||||
      type = t.getElementType();
 | 
					      type = t.getElementType();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SmallVector<uint64_t> lBounds;
 | 
					    llvm::SmallVector<uint64_t> lBounds;
 | 
				
			||||||
    SmallVector<uint64_t> uBounds;
 | 
					    llvm::SmallVector<uint64_t> uBounds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Unzip the upper and lower bound and convert to a row major format.
 | 
					    // Unzip the upper and lower bound and convert to a row major format.
 | 
				
			||||||
    mlir::DenseIntElementsAttr coor = range.getCoor();
 | 
					    mlir::DenseIntElementsAttr coor = range.getCoor();
 | 
				
			||||||
| 
						 | 
					@ -2016,28 +2016,28 @@ struct InsertOnRangeOpConversion
 | 
				
			||||||
    auto i64Ty = rewriter.getI64Type();
 | 
					    auto i64Ty = rewriter.getI64Type();
 | 
				
			||||||
    while (subscripts != uBounds) {
 | 
					    while (subscripts != uBounds) {
 | 
				
			||||||
      // Convert uint64_t's to Attribute's.
 | 
					      // Convert uint64_t's to Attribute's.
 | 
				
			||||||
      SmallVector<mlir::Attribute> subscriptAttrs;
 | 
					      llvm::SmallVector<mlir::Attribute> subscriptAttrs;
 | 
				
			||||||
      for (const auto &subscript : subscripts)
 | 
					      for (const auto &subscript : subscripts)
 | 
				
			||||||
        subscriptAttrs.push_back(IntegerAttr::get(i64Ty, subscript));
 | 
					        subscriptAttrs.push_back(mlir::IntegerAttr::get(i64Ty, subscript));
 | 
				
			||||||
      lastOp = rewriter.create<mlir::LLVM::InsertValueOp>(
 | 
					      lastOp = rewriter.create<mlir::LLVM::InsertValueOp>(
 | 
				
			||||||
          loc, ty, lastOp, insertVal,
 | 
					          loc, ty, lastOp, insertVal,
 | 
				
			||||||
          ArrayAttr::get(range.getContext(), subscriptAttrs));
 | 
					          mlir::ArrayAttr::get(range.getContext(), subscriptAttrs));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      incrementSubscripts(dims, subscripts);
 | 
					      incrementSubscripts(dims, subscripts);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Convert uint64_t's to Attribute's.
 | 
					    // Convert uint64_t's to Attribute's.
 | 
				
			||||||
    SmallVector<mlir::Attribute> subscriptAttrs;
 | 
					    llvm::SmallVector<mlir::Attribute> subscriptAttrs;
 | 
				
			||||||
    for (const auto &subscript : subscripts)
 | 
					    for (const auto &subscript : subscripts)
 | 
				
			||||||
      subscriptAttrs.push_back(
 | 
					      subscriptAttrs.push_back(
 | 
				
			||||||
          IntegerAttr::get(rewriter.getI64Type(), subscript));
 | 
					          mlir::IntegerAttr::get(rewriter.getI64Type(), subscript));
 | 
				
			||||||
    mlir::ArrayRef<mlir::Attribute> arrayRef(subscriptAttrs);
 | 
					    mlir::ArrayRef<mlir::Attribute> arrayRef(subscriptAttrs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rewriter.replaceOpWithNewOp<mlir::LLVM::InsertValueOp>(
 | 
					    rewriter.replaceOpWithNewOp<mlir::LLVM::InsertValueOp>(
 | 
				
			||||||
        range, ty, lastOp, insertVal,
 | 
					        range, ty, lastOp, insertVal,
 | 
				
			||||||
        ArrayAttr::get(range.getContext(), arrayRef));
 | 
					        mlir::ArrayAttr::get(range.getContext(), arrayRef));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
} // namespace
 | 
					} // namespace
 | 
				
			||||||
| 
						 | 
					@ -2137,7 +2137,7 @@ struct XArrayCoorOpConversion
 | 
				
			||||||
          rewriter.create<mlir::LLVM::GEPOp>(loc, voidPtrTy, base, args);
 | 
					          rewriter.create<mlir::LLVM::GEPOp>(loc, voidPtrTy, base, args);
 | 
				
			||||||
      if (coor.subcomponent().empty()) {
 | 
					      if (coor.subcomponent().empty()) {
 | 
				
			||||||
        rewriter.replaceOpWithNewOp<mlir::LLVM::BitcastOp>(coor, baseTy, addr);
 | 
					        rewriter.replaceOpWithNewOp<mlir::LLVM::BitcastOp>(coor, baseTy, addr);
 | 
				
			||||||
        return success();
 | 
					        return mlir::success();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      auto casted = rewriter.create<mlir::LLVM::BitcastOp>(loc, baseTy, addr);
 | 
					      auto casted = rewriter.create<mlir::LLVM::BitcastOp>(loc, baseTy, addr);
 | 
				
			||||||
      args.clear();
 | 
					      args.clear();
 | 
				
			||||||
| 
						 | 
					@ -2153,7 +2153,7 @@ struct XArrayCoorOpConversion
 | 
				
			||||||
        args.push_back(operands[i]);
 | 
					        args.push_back(operands[i]);
 | 
				
			||||||
      rewriter.replaceOpWithNewOp<mlir::LLVM::GEPOp>(coor, baseTy, casted,
 | 
					      rewriter.replaceOpWithNewOp<mlir::LLVM::GEPOp>(coor, baseTy, casted,
 | 
				
			||||||
                                                     args);
 | 
					                                                     args);
 | 
				
			||||||
      return success();
 | 
					      return mlir::success();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // The array was not boxed, so it must be contiguous. offset is therefore an
 | 
					    // The array was not boxed, so it must be contiguous. offset is therefore an
 | 
				
			||||||
| 
						 | 
					@ -2198,11 +2198,11 @@ struct XArrayCoorOpConversion
 | 
				
			||||||
      base = rewriter.create<mlir::LLVM::BitcastOp>(loc, newTy,
 | 
					      base = rewriter.create<mlir::LLVM::BitcastOp>(loc, newTy,
 | 
				
			||||||
                                                    adaptor.getOperands()[0]);
 | 
					                                                    adaptor.getOperands()[0]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    SmallVector<mlir::Value> args = {offset};
 | 
					    llvm::SmallVector<mlir::Value> args = {offset};
 | 
				
			||||||
    for (auto i = coor.subcomponentOffset(); i != coor.indicesOffset(); ++i)
 | 
					    for (auto i = coor.subcomponentOffset(); i != coor.indicesOffset(); ++i)
 | 
				
			||||||
      args.push_back(operands[i]);
 | 
					      args.push_back(operands[i]);
 | 
				
			||||||
    rewriter.replaceOpWithNewOp<mlir::LLVM::GEPOp>(coor, ty, base, args);
 | 
					    rewriter.replaceOpWithNewOp<mlir::LLVM::GEPOp>(coor, ty, base, args);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
} // namespace
 | 
					} // namespace
 | 
				
			||||||
| 
						 | 
					@ -2234,7 +2234,7 @@ struct CoordinateOpConversion
 | 
				
			||||||
      llvm::SmallVector<mlir::Value> offs = {c0, operands[1]};
 | 
					      llvm::SmallVector<mlir::Value> offs = {c0, operands[1]};
 | 
				
			||||||
      mlir::Value gep = genGEP(loc, ty, rewriter, base, offs);
 | 
					      mlir::Value gep = genGEP(loc, ty, rewriter, base, offs);
 | 
				
			||||||
      rewriter.replaceOp(coor, gep);
 | 
					      rewriter.replaceOp(coor, gep);
 | 
				
			||||||
      return success();
 | 
					      return mlir::success();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Boxed type - get the base pointer from the box
 | 
					    // Boxed type - get the base pointer from the box
 | 
				
			||||||
| 
						 | 
					@ -2261,9 +2261,9 @@ struct CoordinateOpConversion
 | 
				
			||||||
    assert(val && val.dyn_cast<mlir::OpResult>() && "must not be null value");
 | 
					    assert(val && val.dyn_cast<mlir::OpResult>() && "must not be null value");
 | 
				
			||||||
    mlir::Operation *defop = val.getDefiningOp();
 | 
					    mlir::Operation *defop = val.getDefiningOp();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (auto constOp = dyn_cast<mlir::arith::ConstantIntOp>(defop))
 | 
					    if (auto constOp = mlir::dyn_cast<mlir::arith::ConstantIntOp>(defop))
 | 
				
			||||||
      return constOp.value();
 | 
					      return constOp.value();
 | 
				
			||||||
    if (auto llConstOp = dyn_cast<mlir::LLVM::ConstantOp>(defop))
 | 
					    if (auto llConstOp = mlir::dyn_cast<mlir::LLVM::ConstantOp>(defop))
 | 
				
			||||||
      if (auto attr = llConstOp.getValue().dyn_cast<mlir::IntegerAttr>())
 | 
					      if (auto attr = llConstOp.getValue().dyn_cast<mlir::IntegerAttr>())
 | 
				
			||||||
        return attr.getValue().getSExtValue();
 | 
					        return attr.getValue().getSExtValue();
 | 
				
			||||||
    fir::emitFatalError(val.getLoc(), "must be a constant");
 | 
					    fir::emitFatalError(val.getLoc(), "must be a constant");
 | 
				
			||||||
| 
						 | 
					@ -2343,7 +2343,7 @@ private:
 | 
				
			||||||
    if (coor.getNumOperands() == 2) {
 | 
					    if (coor.getNumOperands() == 2) {
 | 
				
			||||||
      mlir::Operation *coordinateDef =
 | 
					      mlir::Operation *coordinateDef =
 | 
				
			||||||
          (*coor.getCoor().begin()).getDefiningOp();
 | 
					          (*coor.getCoor().begin()).getDefiningOp();
 | 
				
			||||||
      if (isa_and_nonnull<fir::LenParamIndexOp>(coordinateDef))
 | 
					      if (mlir::isa_and_nonnull<fir::LenParamIndexOp>(coordinateDef))
 | 
				
			||||||
        TODO(loc,
 | 
					        TODO(loc,
 | 
				
			||||||
             "fir.coordinate_of - fir.len_param_index is not supported yet");
 | 
					             "fir.coordinate_of - fir.len_param_index is not supported yet");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -2392,7 +2392,7 @@ private:
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        auto voidPtrBase =
 | 
					        auto voidPtrBase =
 | 
				
			||||||
            rewriter.create<mlir::LLVM::BitcastOp>(loc, voidPtrTy, resultAddr);
 | 
					            rewriter.create<mlir::LLVM::BitcastOp>(loc, voidPtrTy, resultAddr);
 | 
				
			||||||
        SmallVector<mlir::Value> args{off};
 | 
					        llvm::SmallVector<mlir::Value> args{off};
 | 
				
			||||||
        resultAddr = rewriter.create<mlir::LLVM::GEPOp>(loc, voidPtrTy,
 | 
					        resultAddr = rewriter.create<mlir::LLVM::GEPOp>(loc, voidPtrTy,
 | 
				
			||||||
                                                        voidPtrBase, args);
 | 
					                                                        voidPtrBase, args);
 | 
				
			||||||
        i += arrTy.getDimension() - 1;
 | 
					        i += arrTy.getDimension() - 1;
 | 
				
			||||||
| 
						 | 
					@ -2417,7 +2417,7 @@ private:
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rewriter.replaceOpWithNewOp<mlir::LLVM::BitcastOp>(coor, ty, resultAddr);
 | 
					    rewriter.replaceOpWithNewOp<mlir::LLVM::BitcastOp>(coor, ty, resultAddr);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mlir::LogicalResult
 | 
					  mlir::LogicalResult
 | 
				
			||||||
| 
						 | 
					@ -2463,14 +2463,14 @@ private:
 | 
				
			||||||
          loc, "fir.coordinate_of with a dynamic element size is unsupported");
 | 
					          loc, "fir.coordinate_of with a dynamic element size is unsupported");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (hasKnownShape || columnIsDeferred) {
 | 
					    if (hasKnownShape || columnIsDeferred) {
 | 
				
			||||||
      SmallVector<mlir::Value> offs;
 | 
					      llvm::SmallVector<mlir::Value> offs;
 | 
				
			||||||
      if (hasKnownShape && hasSubdimension) {
 | 
					      if (hasKnownShape && hasSubdimension) {
 | 
				
			||||||
        mlir::LLVM::ConstantOp c0 =
 | 
					        mlir::LLVM::ConstantOp c0 =
 | 
				
			||||||
            genConstantIndex(loc, lowerTy().indexType(), rewriter, 0);
 | 
					            genConstantIndex(loc, lowerTy().indexType(), rewriter, 0);
 | 
				
			||||||
        offs.push_back(c0);
 | 
					        offs.push_back(c0);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      Optional<int> dims;
 | 
					      llvm::Optional<int> dims;
 | 
				
			||||||
      SmallVector<mlir::Value> arrIdx;
 | 
					      llvm::SmallVector<mlir::Value> arrIdx;
 | 
				
			||||||
      for (std::size_t i = 1, sz = operands.size(); i < sz; ++i) {
 | 
					      for (std::size_t i = 1, sz = operands.size(); i < sz; ++i) {
 | 
				
			||||||
        mlir::Value nxtOpnd = operands[i];
 | 
					        mlir::Value nxtOpnd = operands[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2519,7 +2519,7 @@ private:
 | 
				
			||||||
      mlir::Value base = operands[0];
 | 
					      mlir::Value base = operands[0];
 | 
				
			||||||
      mlir::Value retval = genGEP(loc, ty, rewriter, base, offs);
 | 
					      mlir::Value retval = genGEP(loc, ty, rewriter, base, offs);
 | 
				
			||||||
      rewriter.replaceOp(coor, retval);
 | 
					      rewriter.replaceOp(coor, retval);
 | 
				
			||||||
      return success();
 | 
					      return mlir::success();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return mlir::emitError(
 | 
					    return mlir::emitError(
 | 
				
			||||||
| 
						 | 
					@ -2544,21 +2544,21 @@ struct FieldIndexOpConversion : public FIROpConversion<fir::FieldIndexOp> {
 | 
				
			||||||
      // component type in the parent type (to be used in GEP).
 | 
					      // component type in the parent type (to be used in GEP).
 | 
				
			||||||
      rewriter.replaceOp(field, mlir::ValueRange{genConstantOffset(
 | 
					      rewriter.replaceOp(field, mlir::ValueRange{genConstantOffset(
 | 
				
			||||||
                                    field.getLoc(), rewriter, index)});
 | 
					                                    field.getLoc(), rewriter, index)});
 | 
				
			||||||
      return success();
 | 
					      return mlir::success();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Derived type has compile-time constant layout. Call the compiler
 | 
					    // Derived type has compile-time constant layout. Call the compiler
 | 
				
			||||||
    // generated function to determine the byte offset of the field at runtime.
 | 
					    // generated function to determine the byte offset of the field at runtime.
 | 
				
			||||||
    // This returns a non-constant.
 | 
					    // This returns a non-constant.
 | 
				
			||||||
    FlatSymbolRefAttr symAttr = mlir::SymbolRefAttr::get(
 | 
					    mlir::FlatSymbolRefAttr symAttr = mlir::SymbolRefAttr::get(
 | 
				
			||||||
        field.getContext(), getOffsetMethodName(recTy, field.getFieldId()));
 | 
					        field.getContext(), getOffsetMethodName(recTy, field.getFieldId()));
 | 
				
			||||||
    NamedAttribute callAttr = rewriter.getNamedAttr("callee", symAttr);
 | 
					    mlir::NamedAttribute callAttr = rewriter.getNamedAttr("callee", symAttr);
 | 
				
			||||||
    NamedAttribute fieldAttr = rewriter.getNamedAttr(
 | 
					    mlir::NamedAttribute fieldAttr = rewriter.getNamedAttr(
 | 
				
			||||||
        "field", mlir::IntegerAttr::get(lowerTy().indexType(), index));
 | 
					        "field", mlir::IntegerAttr::get(lowerTy().indexType(), index));
 | 
				
			||||||
    rewriter.replaceOpWithNewOp<mlir::LLVM::CallOp>(
 | 
					    rewriter.replaceOpWithNewOp<mlir::LLVM::CallOp>(
 | 
				
			||||||
        field, lowerTy().offsetType(), adaptor.getOperands(),
 | 
					        field, lowerTy().offsetType(), adaptor.getOperands(),
 | 
				
			||||||
        llvm::ArrayRef<mlir::NamedAttribute>{callAttr, fieldAttr});
 | 
					        llvm::ArrayRef<mlir::NamedAttribute>{callAttr, fieldAttr});
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Re-Construct the name of the compiler generated method that calculates the
 | 
					  // Re-Construct the name of the compiler generated method that calculates the
 | 
				
			||||||
| 
						 | 
					@ -2577,7 +2577,7 @@ struct FirEndOpConversion : public FIROpConversion<fir::FirEndOp> {
 | 
				
			||||||
  matchAndRewrite(fir::FirEndOp firEnd, OpAdaptor,
 | 
					  matchAndRewrite(fir::FirEndOp firEnd, OpAdaptor,
 | 
				
			||||||
                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
					                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
				
			||||||
    TODO(firEnd.getLoc(), "fir.end codegen");
 | 
					    TODO(firEnd.getLoc(), "fir.end codegen");
 | 
				
			||||||
    return failure();
 | 
					    return mlir::failure();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2589,7 +2589,7 @@ struct GenTypeDescOpConversion : public FIROpConversion<fir::GenTypeDescOp> {
 | 
				
			||||||
  matchAndRewrite(fir::GenTypeDescOp gentypedesc, OpAdaptor adaptor,
 | 
					  matchAndRewrite(fir::GenTypeDescOp gentypedesc, OpAdaptor adaptor,
 | 
				
			||||||
                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
					                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
				
			||||||
    TODO(gentypedesc.getLoc(), "fir.gentypedesc codegen");
 | 
					    TODO(gentypedesc.getLoc(), "fir.gentypedesc codegen");
 | 
				
			||||||
    return failure();
 | 
					    return mlir::failure();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2600,8 +2600,9 @@ struct HasValueOpConversion : public FIROpConversion<fir::HasValueOp> {
 | 
				
			||||||
  mlir::LogicalResult
 | 
					  mlir::LogicalResult
 | 
				
			||||||
  matchAndRewrite(fir::HasValueOp op, OpAdaptor adaptor,
 | 
					  matchAndRewrite(fir::HasValueOp op, OpAdaptor adaptor,
 | 
				
			||||||
                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
					                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
				
			||||||
    rewriter.replaceOpWithNewOp<LLVM::ReturnOp>(op, adaptor.getOperands());
 | 
					    rewriter.replaceOpWithNewOp<mlir::LLVM::ReturnOp>(op,
 | 
				
			||||||
    return success();
 | 
					                                                      adaptor.getOperands());
 | 
				
			||||||
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2640,13 +2641,13 @@ struct GlobalOpConversion : public FIROpConversion<fir::GlobalOp> {
 | 
				
			||||||
            auto convertOp = mlir::dyn_cast<fir::ConvertOp>(op);
 | 
					            auto convertOp = mlir::dyn_cast<fir::ConvertOp>(op);
 | 
				
			||||||
            if (!convertOp)
 | 
					            if (!convertOp)
 | 
				
			||||||
              continue;
 | 
					              continue;
 | 
				
			||||||
            constant = cast<mlir::arith::ConstantOp>(
 | 
					            constant = mlir::cast<mlir::arith::ConstantOp>(
 | 
				
			||||||
                convertOp.getValue().getDefiningOp());
 | 
					                convertOp.getValue().getDefiningOp());
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          mlir::Type vecType = mlir::VectorType::get(
 | 
					          mlir::Type vecType = mlir::VectorType::get(
 | 
				
			||||||
              insertOp.getType().getShape(), constant.getType());
 | 
					              insertOp.getType().getShape(), constant.getType());
 | 
				
			||||||
          auto denseAttr = mlir::DenseElementsAttr::get(
 | 
					          auto denseAttr = mlir::DenseElementsAttr::get(
 | 
				
			||||||
              vecType.cast<ShapedType>(), constant.getValue());
 | 
					              vecType.cast<mlir::ShapedType>(), constant.getValue());
 | 
				
			||||||
          rewriter.setInsertionPointAfter(insertOp);
 | 
					          rewriter.setInsertionPointAfter(insertOp);
 | 
				
			||||||
          rewriter.replaceOpWithNewOp<mlir::arith::ConstantOp>(
 | 
					          rewriter.replaceOpWithNewOp<mlir::arith::ConstantOp>(
 | 
				
			||||||
              insertOp, seqTyAttr, denseAttr);
 | 
					              insertOp, seqTyAttr, denseAttr);
 | 
				
			||||||
| 
						 | 
					@ -2654,7 +2655,7 @@ struct GlobalOpConversion : public FIROpConversion<fir::GlobalOp> {
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    rewriter.eraseOp(global);
 | 
					    rewriter.eraseOp(global);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool isFullRange(mlir::DenseIntElementsAttr indexes,
 | 
					  bool isFullRange(mlir::DenseIntElementsAttr indexes,
 | 
				
			||||||
| 
						 | 
					@ -2674,7 +2675,8 @@ struct GlobalOpConversion : public FIROpConversion<fir::GlobalOp> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // TODO: String comparaison should be avoided. Replace linkName with an
 | 
					  // TODO: String comparaison should be avoided. Replace linkName with an
 | 
				
			||||||
  // enumeration.
 | 
					  // enumeration.
 | 
				
			||||||
  mlir::LLVM::Linkage convertLinkage(Optional<StringRef> optLinkage) const {
 | 
					  mlir::LLVM::Linkage
 | 
				
			||||||
 | 
					  convertLinkage(llvm::Optional<llvm::StringRef> optLinkage) const {
 | 
				
			||||||
    if (optLinkage.hasValue()) {
 | 
					    if (optLinkage.hasValue()) {
 | 
				
			||||||
      auto name = optLinkage.getValue();
 | 
					      auto name = optLinkage.getValue();
 | 
				
			||||||
      if (name == "internal")
 | 
					      if (name == "internal")
 | 
				
			||||||
| 
						 | 
					@ -2706,12 +2708,11 @@ struct LoadOpConversion : public FIROpConversion<fir::LoadOp> {
 | 
				
			||||||
    if (load.getType().isa<fir::BoxType>()) {
 | 
					    if (load.getType().isa<fir::BoxType>()) {
 | 
				
			||||||
      rewriter.replaceOp(load, adaptor.getOperands()[0]);
 | 
					      rewriter.replaceOp(load, adaptor.getOperands()[0]);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      mlir::Type ty = convertType(load.getType());
 | 
					 | 
				
			||||||
      ArrayRef<NamedAttribute> at = load->getAttrs();
 | 
					 | 
				
			||||||
      rewriter.replaceOpWithNewOp<mlir::LLVM::LoadOp>(
 | 
					      rewriter.replaceOpWithNewOp<mlir::LLVM::LoadOp>(
 | 
				
			||||||
          load, ty, adaptor.getOperands(), at);
 | 
					          load, convertType(load.getType()), adaptor.getOperands(),
 | 
				
			||||||
 | 
					          load->getAttrs());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2725,12 +2726,12 @@ struct NoReassocOpConversion : public FIROpConversion<fir::NoReassocOp> {
 | 
				
			||||||
  matchAndRewrite(fir::NoReassocOp noreassoc, OpAdaptor adaptor,
 | 
					  matchAndRewrite(fir::NoReassocOp noreassoc, OpAdaptor adaptor,
 | 
				
			||||||
                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
					                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
				
			||||||
    rewriter.replaceOp(noreassoc, adaptor.getOperands()[0]);
 | 
					    rewriter.replaceOp(noreassoc, adaptor.getOperands()[0]);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void genCondBrOp(mlir::Location loc, mlir::Value cmp, mlir::Block *dest,
 | 
					static void genCondBrOp(mlir::Location loc, mlir::Value cmp, mlir::Block *dest,
 | 
				
			||||||
                        Optional<mlir::ValueRange> destOps,
 | 
					                        llvm::Optional<mlir::ValueRange> destOps,
 | 
				
			||||||
                        mlir::ConversionPatternRewriter &rewriter,
 | 
					                        mlir::ConversionPatternRewriter &rewriter,
 | 
				
			||||||
                        mlir::Block *newBlock) {
 | 
					                        mlir::Block *newBlock) {
 | 
				
			||||||
  if (destOps.hasValue())
 | 
					  if (destOps.hasValue())
 | 
				
			||||||
| 
						 | 
					@ -2741,7 +2742,7 @@ static void genCondBrOp(mlir::Location loc, mlir::Value cmp, mlir::Block *dest,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <typename A, typename B>
 | 
					template <typename A, typename B>
 | 
				
			||||||
static void genBrOp(A caseOp, mlir::Block *dest, Optional<B> destOps,
 | 
					static void genBrOp(A caseOp, mlir::Block *dest, llvm::Optional<B> destOps,
 | 
				
			||||||
                    mlir::ConversionPatternRewriter &rewriter) {
 | 
					                    mlir::ConversionPatternRewriter &rewriter) {
 | 
				
			||||||
  if (destOps.hasValue())
 | 
					  if (destOps.hasValue())
 | 
				
			||||||
    rewriter.replaceOpWithNewOp<mlir::LLVM::BrOp>(caseOp, destOps.getValue(),
 | 
					    rewriter.replaceOpWithNewOp<mlir::LLVM::BrOp>(caseOp, destOps.getValue(),
 | 
				
			||||||
| 
						 | 
					@ -2752,7 +2753,7 @@ static void genBrOp(A caseOp, mlir::Block *dest, Optional<B> destOps,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void genCaseLadderStep(mlir::Location loc, mlir::Value cmp,
 | 
					static void genCaseLadderStep(mlir::Location loc, mlir::Value cmp,
 | 
				
			||||||
                              mlir::Block *dest,
 | 
					                              mlir::Block *dest,
 | 
				
			||||||
                              Optional<mlir::ValueRange> destOps,
 | 
					                              llvm::Optional<mlir::ValueRange> destOps,
 | 
				
			||||||
                              mlir::ConversionPatternRewriter &rewriter) {
 | 
					                              mlir::ConversionPatternRewriter &rewriter) {
 | 
				
			||||||
  auto *thisBlock = rewriter.getInsertionBlock();
 | 
					  auto *thisBlock = rewriter.getInsertionBlock();
 | 
				
			||||||
  auto *newBlock = createBlock(rewriter, dest);
 | 
					  auto *newBlock = createBlock(rewriter, dest);
 | 
				
			||||||
| 
						 | 
					@ -2792,7 +2793,7 @@ struct SelectCaseOpConversion : public FIROpConversion<fir::SelectCaseOp> {
 | 
				
			||||||
    auto ty = caseOp.getSelector().getType();
 | 
					    auto ty = caseOp.getSelector().getType();
 | 
				
			||||||
    if (ty.isa<fir::CharacterType>()) {
 | 
					    if (ty.isa<fir::CharacterType>()) {
 | 
				
			||||||
      TODO(caseOp.getLoc(), "fir.select_case codegen with character type");
 | 
					      TODO(caseOp.getLoc(), "fir.select_case codegen with character type");
 | 
				
			||||||
      return failure();
 | 
					      return mlir::failure();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    mlir::Value selector = caseOp.getSelector(adaptor.getOperands());
 | 
					    mlir::Value selector = caseOp.getSelector(adaptor.getOperands());
 | 
				
			||||||
    auto loc = caseOp.getLoc();
 | 
					    auto loc = caseOp.getLoc();
 | 
				
			||||||
| 
						 | 
					@ -2842,7 +2843,7 @@ struct SelectCaseOpConversion : public FIROpConversion<fir::SelectCaseOp> {
 | 
				
			||||||
      assert((t + 1 == conds) && "unit must be last");
 | 
					      assert((t + 1 == conds) && "unit must be last");
 | 
				
			||||||
      genBrOp(caseOp, dest, destOps, rewriter);
 | 
					      genBrOp(caseOp, dest, destOps, rewriter);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2869,20 +2870,20 @@ static void selectMatchAndRewrite(fir::LLVMTypeConverter &lowering, OP select,
 | 
				
			||||||
    if (auto intAttr = attr.template dyn_cast<mlir::IntegerAttr>()) {
 | 
					    if (auto intAttr = attr.template dyn_cast<mlir::IntegerAttr>()) {
 | 
				
			||||||
      destinations.push_back(dest);
 | 
					      destinations.push_back(dest);
 | 
				
			||||||
      destinationsOperands.push_back(destOps.hasValue() ? *destOps
 | 
					      destinationsOperands.push_back(destOps.hasValue() ? *destOps
 | 
				
			||||||
                                                        : ValueRange());
 | 
					                                                        : mlir::ValueRange{});
 | 
				
			||||||
      caseValues.push_back(intAttr.getInt());
 | 
					      caseValues.push_back(intAttr.getInt());
 | 
				
			||||||
      continue;
 | 
					      continue;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    assert(attr.template dyn_cast_or_null<mlir::UnitAttr>());
 | 
					    assert(attr.template dyn_cast_or_null<mlir::UnitAttr>());
 | 
				
			||||||
    assert((t + 1 == conds) && "unit must be last");
 | 
					    assert((t + 1 == conds) && "unit must be last");
 | 
				
			||||||
    defaultDestination = dest;
 | 
					    defaultDestination = dest;
 | 
				
			||||||
    defaultOperands = destOps.hasValue() ? *destOps : ValueRange();
 | 
					    defaultOperands = destOps.hasValue() ? *destOps : mlir::ValueRange{};
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // LLVM::SwitchOp takes a i32 type for the selector.
 | 
					  // LLVM::SwitchOp takes a i32 type for the selector.
 | 
				
			||||||
  if (select.getSelector().getType() != rewriter.getI32Type())
 | 
					  if (select.getSelector().getType() != rewriter.getI32Type())
 | 
				
			||||||
    selector =
 | 
					    selector = rewriter.create<mlir::LLVM::TruncOp>(loc, rewriter.getI32Type(),
 | 
				
			||||||
        rewriter.create<LLVM::TruncOp>(loc, rewriter.getI32Type(), selector);
 | 
					                                                    selector);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  rewriter.replaceOpWithNewOp<mlir::LLVM::SwitchOp>(
 | 
					  rewriter.replaceOpWithNewOp<mlir::LLVM::SwitchOp>(
 | 
				
			||||||
      select, selector,
 | 
					      select, selector,
 | 
				
			||||||
| 
						 | 
					@ -2891,7 +2892,7 @@ static void selectMatchAndRewrite(fir::LLVMTypeConverter &lowering, OP select,
 | 
				
			||||||
      /*caseValues=*/caseValues,
 | 
					      /*caseValues=*/caseValues,
 | 
				
			||||||
      /*caseDestinations=*/destinations,
 | 
					      /*caseDestinations=*/destinations,
 | 
				
			||||||
      /*caseOperands=*/destinationsOperands,
 | 
					      /*caseOperands=*/destinationsOperands,
 | 
				
			||||||
      /*branchWeights=*/ArrayRef<int32_t>());
 | 
					      /*branchWeights=*/llvm::ArrayRef<std::int32_t>());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// conversion of fir::SelectOp to an if-then-else ladder
 | 
					/// conversion of fir::SelectOp to an if-then-else ladder
 | 
				
			||||||
| 
						 | 
					@ -2902,7 +2903,7 @@ struct SelectOpConversion : public FIROpConversion<fir::SelectOp> {
 | 
				
			||||||
  matchAndRewrite(fir::SelectOp op, OpAdaptor adaptor,
 | 
					  matchAndRewrite(fir::SelectOp op, OpAdaptor adaptor,
 | 
				
			||||||
                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
					                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
				
			||||||
    selectMatchAndRewrite<fir::SelectOp>(lowerTy(), op, adaptor, rewriter);
 | 
					    selectMatchAndRewrite<fir::SelectOp>(lowerTy(), op, adaptor, rewriter);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2914,7 +2915,7 @@ struct SelectRankOpConversion : public FIROpConversion<fir::SelectRankOp> {
 | 
				
			||||||
  matchAndRewrite(fir::SelectRankOp op, OpAdaptor adaptor,
 | 
					  matchAndRewrite(fir::SelectRankOp op, OpAdaptor adaptor,
 | 
				
			||||||
                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
					                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
				
			||||||
    selectMatchAndRewrite<fir::SelectRankOp>(lowerTy(), op, adaptor, rewriter);
 | 
					    selectMatchAndRewrite<fir::SelectRankOp>(lowerTy(), op, adaptor, rewriter);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2927,7 +2928,7 @@ struct SelectTypeOpConversion : public FIROpConversion<fir::SelectTypeOp> {
 | 
				
			||||||
                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
					                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
				
			||||||
    mlir::emitError(select.getLoc(),
 | 
					    mlir::emitError(select.getLoc(),
 | 
				
			||||||
                    "fir.select_type should have already been converted");
 | 
					                    "fir.select_type should have already been converted");
 | 
				
			||||||
    return failure();
 | 
					    return mlir::failure();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2951,7 +2952,7 @@ struct StoreOpConversion : public FIROpConversion<fir::StoreOp> {
 | 
				
			||||||
      rewriter.replaceOpWithNewOp<mlir::LLVM::StoreOp>(
 | 
					      rewriter.replaceOpWithNewOp<mlir::LLVM::StoreOp>(
 | 
				
			||||||
          store, adaptor.getOperands()[0], adaptor.getOperands()[1]);
 | 
					          store, adaptor.getOperands()[0], adaptor.getOperands()[1]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2965,7 +2966,7 @@ struct UnboxCharOpConversion : public FIROpConversion<fir::UnboxCharOp> {
 | 
				
			||||||
  mlir::LogicalResult
 | 
					  mlir::LogicalResult
 | 
				
			||||||
  matchAndRewrite(fir::UnboxCharOp unboxchar, OpAdaptor adaptor,
 | 
					  matchAndRewrite(fir::UnboxCharOp unboxchar, OpAdaptor adaptor,
 | 
				
			||||||
                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
					                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
				
			||||||
    MLIRContext *ctx = unboxchar.getContext();
 | 
					    auto *ctx = unboxchar.getContext();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mlir::Type lenTy = convertType(unboxchar.getType(1));
 | 
					    mlir::Type lenTy = convertType(unboxchar.getType(1));
 | 
				
			||||||
    mlir::Value tuple = adaptor.getOperands()[0];
 | 
					    mlir::Value tuple = adaptor.getOperands()[0];
 | 
				
			||||||
| 
						 | 
					@ -2980,8 +2981,8 @@ struct UnboxCharOpConversion : public FIROpConversion<fir::UnboxCharOp> {
 | 
				
			||||||
    mlir::Value lenAfterCast = integerCast(loc, rewriter, lenTy, len);
 | 
					    mlir::Value lenAfterCast = integerCast(loc, rewriter, lenTy, len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rewriter.replaceOp(unboxchar,
 | 
					    rewriter.replaceOp(unboxchar,
 | 
				
			||||||
                       ArrayRef<mlir::Value>{ptrToBuffer, lenAfterCast});
 | 
					                       llvm::ArrayRef<mlir::Value>{ptrToBuffer, lenAfterCast});
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2995,7 +2996,7 @@ struct UnboxProcOpConversion : public FIROpConversion<fir::UnboxProcOp> {
 | 
				
			||||||
  matchAndRewrite(fir::UnboxProcOp unboxproc, OpAdaptor adaptor,
 | 
					  matchAndRewrite(fir::UnboxProcOp unboxproc, OpAdaptor adaptor,
 | 
				
			||||||
                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
					                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
				
			||||||
    TODO(unboxproc.getLoc(), "fir.unboxproc codegen");
 | 
					    TODO(unboxproc.getLoc(), "fir.unboxproc codegen");
 | 
				
			||||||
    return failure();
 | 
					    return mlir::failure();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3008,7 +3009,7 @@ struct UndefOpConversion : public FIROpConversion<fir::UndefOp> {
 | 
				
			||||||
                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
					                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
				
			||||||
    rewriter.replaceOpWithNewOp<mlir::LLVM::UndefOp>(
 | 
					    rewriter.replaceOpWithNewOp<mlir::LLVM::UndefOp>(
 | 
				
			||||||
        undef, convertType(undef.getType()));
 | 
					        undef, convertType(undef.getType()));
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3033,7 +3034,7 @@ struct ZeroOpConversion : public FIROpConversion<fir::ZeroOp> {
 | 
				
			||||||
          zero,
 | 
					          zero,
 | 
				
			||||||
          "conversion of fir.zero with aggregate type not implemented yet");
 | 
					          "conversion of fir.zero with aggregate type not implemented yet");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3045,7 +3046,7 @@ struct UnreachableOpConversion : public FIROpConversion<fir::UnreachableOp> {
 | 
				
			||||||
  matchAndRewrite(fir::UnreachableOp unreach, OpAdaptor adaptor,
 | 
					  matchAndRewrite(fir::UnreachableOp unreach, OpAdaptor adaptor,
 | 
				
			||||||
                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
					                  mlir::ConversionPatternRewriter &rewriter) const override {
 | 
				
			||||||
    rewriter.replaceOpWithNewOp<mlir::LLVM::UnreachableOp>(unreach);
 | 
					    rewriter.replaceOpWithNewOp<mlir::LLVM::UnreachableOp>(unreach);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3080,7 +3081,7 @@ struct IsPresentOpConversion : public FIROpConversion<fir::IsPresentOp> {
 | 
				
			||||||
    rewriter.replaceOpWithNewOp<mlir::LLVM::ICmpOp>(
 | 
					    rewriter.replaceOpWithNewOp<mlir::LLVM::ICmpOp>(
 | 
				
			||||||
        isPresent, mlir::LLVM::ICmpPredicate::ne, addr, c0);
 | 
					        isPresent, mlir::LLVM::ICmpPredicate::ne, addr, c0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3108,7 +3109,7 @@ struct AbsentOpConversion : public FIROpConversion<fir::AbsentOp> {
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      rewriter.replaceOpWithNewOp<mlir::LLVM::NullOp>(absent, ty);
 | 
					      rewriter.replaceOpWithNewOp<mlir::LLVM::NullOp>(absent, ty);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3154,7 +3155,7 @@ struct AddcOpConversion : public FIROpConversion<fir::AddcOp> {
 | 
				
			||||||
    auto r = complexSum<mlir::LLVM::FAddOp>(addc, adaptor.getOperands(),
 | 
					    auto r = complexSum<mlir::LLVM::FAddOp>(addc, adaptor.getOperands(),
 | 
				
			||||||
                                            rewriter, lowerTy());
 | 
					                                            rewriter, lowerTy());
 | 
				
			||||||
    rewriter.replaceOp(addc, r.getResult());
 | 
					    rewriter.replaceOp(addc, r.getResult());
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3169,7 +3170,7 @@ struct SubcOpConversion : public FIROpConversion<fir::SubcOp> {
 | 
				
			||||||
    auto r = complexSum<mlir::LLVM::FSubOp>(subc, adaptor.getOperands(),
 | 
					    auto r = complexSum<mlir::LLVM::FSubOp>(subc, adaptor.getOperands(),
 | 
				
			||||||
                                            rewriter, lowerTy());
 | 
					                                            rewriter, lowerTy());
 | 
				
			||||||
    rewriter.replaceOp(subc, r.getResult());
 | 
					    rewriter.replaceOp(subc, r.getResult());
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3205,7 +3206,7 @@ struct MulcOpConversion : public FIROpConversion<fir::MulcOp> {
 | 
				
			||||||
    auto r1 = rewriter.create<mlir::LLVM::InsertValueOp>(loc, ty, ra, rr, c0);
 | 
					    auto r1 = rewriter.create<mlir::LLVM::InsertValueOp>(loc, ty, ra, rr, c0);
 | 
				
			||||||
    auto r0 = rewriter.create<mlir::LLVM::InsertValueOp>(loc, ty, r1, ri, c1);
 | 
					    auto r0 = rewriter.create<mlir::LLVM::InsertValueOp>(loc, ty, r1, ri, c1);
 | 
				
			||||||
    rewriter.replaceOp(mulc, r0.getResult());
 | 
					    rewriter.replaceOp(mulc, r0.getResult());
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3247,7 +3248,7 @@ struct DivcOpConversion : public FIROpConversion<fir::DivcOp> {
 | 
				
			||||||
    auto r1 = rewriter.create<mlir::LLVM::InsertValueOp>(loc, ty, ra, rr, c0);
 | 
					    auto r1 = rewriter.create<mlir::LLVM::InsertValueOp>(loc, ty, ra, rr, c0);
 | 
				
			||||||
    auto r0 = rewriter.create<mlir::LLVM::InsertValueOp>(loc, ty, r1, ri, c1);
 | 
					    auto r0 = rewriter.create<mlir::LLVM::InsertValueOp>(loc, ty, r1, ri, c1);
 | 
				
			||||||
    rewriter.replaceOp(divc, r0.getResult());
 | 
					    rewriter.replaceOp(divc, r0.getResult());
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3273,7 +3274,7 @@ struct NegcOpConversion : public FIROpConversion<fir::NegcOp> {
 | 
				
			||||||
    auto nip = rewriter.create<mlir::LLVM::FNegOp>(loc, eleTy, ip);
 | 
					    auto nip = rewriter.create<mlir::LLVM::FNegOp>(loc, eleTy, ip);
 | 
				
			||||||
    auto r = rewriter.create<mlir::LLVM::InsertValueOp>(loc, ty, o0, nrp, c0);
 | 
					    auto r = rewriter.create<mlir::LLVM::InsertValueOp>(loc, ty, o0, nrp, c0);
 | 
				
			||||||
    rewriter.replaceOpWithNewOp<mlir::LLVM::InsertValueOp>(neg, ty, r, nip, c1);
 | 
					    rewriter.replaceOpWithNewOp<mlir::LLVM::InsertValueOp>(neg, ty, r, nip, c1);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3294,7 +3295,7 @@ struct MustBeDeadConversion : public FIROpConversion<FromOp> {
 | 
				
			||||||
    if (!op->getUses().empty())
 | 
					    if (!op->getUses().empty())
 | 
				
			||||||
      return rewriter.notifyMatchFailure(op, "op must be dead");
 | 
					      return rewriter.notifyMatchFailure(op, "op must be dead");
 | 
				
			||||||
    rewriter.eraseOp(op);
 | 
					    rewriter.eraseOp(op);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3331,9 +3332,8 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void runOnOperation() override final {
 | 
					  void runOnOperation() override final {
 | 
				
			||||||
    auto mod = getModule();
 | 
					    auto mod = getModule();
 | 
				
			||||||
    if (!forcedTargetTriple.empty()) {
 | 
					    if (!forcedTargetTriple.empty())
 | 
				
			||||||
      fir::setTargetTriple(mod, forcedTargetTriple);
 | 
					      fir::setTargetTriple(mod, forcedTargetTriple);
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto *context = getModule().getContext();
 | 
					    auto *context = getModule().getContext();
 | 
				
			||||||
    fir::LLVMTypeConverter typeConverter{getModule()};
 | 
					    fir::LLVMTypeConverter typeConverter{getModule()};
 | 
				
			||||||
| 
						 | 
					@ -3396,8 +3396,7 @@ struct LLVMIRLoweringPass
 | 
				
			||||||
                               mlir::OperationPass<mlir::ModuleOp>> {
 | 
					                               mlir::OperationPass<mlir::ModuleOp>> {
 | 
				
			||||||
  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(LLVMIRLoweringPass)
 | 
					  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(LLVMIRLoweringPass)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  using Printer = fir::LLVMIRLoweringPrinter;
 | 
					  LLVMIRLoweringPass(llvm::raw_ostream &output, fir::LLVMIRLoweringPrinter p)
 | 
				
			||||||
  LLVMIRLoweringPass(raw_ostream &output, Printer p)
 | 
					 | 
				
			||||||
      : output{output}, printer{p} {}
 | 
					      : output{output}, printer{p} {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mlir::ModuleOp getModule() { return getOperation(); }
 | 
					  mlir::ModuleOp getModule() { return getOperation(); }
 | 
				
			||||||
| 
						 | 
					@ -3417,8 +3416,8 @@ struct LLVMIRLoweringPass
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
  raw_ostream &output;
 | 
					  llvm::raw_ostream &output;
 | 
				
			||||||
  Printer printer;
 | 
					  fir::LLVMIRLoweringPrinter printer;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace
 | 
					} // namespace
 | 
				
			||||||
| 
						 | 
					@ -3428,12 +3427,12 @@ std::unique_ptr<mlir::Pass> fir::createFIRToLLVMPass() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::unique_ptr<mlir::Pass>
 | 
					std::unique_ptr<mlir::Pass>
 | 
				
			||||||
fir::createFIRToLLVMPass(FIRToLLVMPassOptions options) {
 | 
					fir::createFIRToLLVMPass(fir::FIRToLLVMPassOptions options) {
 | 
				
			||||||
  return std::make_unique<FIRToLLVMLowering>(options);
 | 
					  return std::make_unique<FIRToLLVMLowering>(options);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::unique_ptr<mlir::Pass>
 | 
					std::unique_ptr<mlir::Pass>
 | 
				
			||||||
fir::createLLVMDialectToLLVMPass(raw_ostream &output,
 | 
					fir::createLLVMDialectToLLVMPass(llvm::raw_ostream &output,
 | 
				
			||||||
                                 fir::LLVMIRLoweringPrinter printer) {
 | 
					                                 fir::LLVMIRLoweringPrinter printer) {
 | 
				
			||||||
  return std::make_unique<LLVMIRLoweringPass>(output, printer);
 | 
					  return std::make_unique<LLVMIRLoweringPass>(output, printer);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,9 +30,6 @@
 | 
				
			||||||
#include "llvm/ADT/TypeSwitch.h"
 | 
					#include "llvm/ADT/TypeSwitch.h"
 | 
				
			||||||
#include "llvm/Support/Debug.h"
 | 
					#include "llvm/Support/Debug.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace fir;
 | 
					 | 
				
			||||||
using namespace mlir;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define DEBUG_TYPE "flang-target-rewrite"
 | 
					#define DEBUG_TYPE "flang-target-rewrite"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace {
 | 
					namespace {
 | 
				
			||||||
| 
						 | 
					@ -69,9 +66,9 @@ struct FixupTy {
 | 
				
			||||||
/// generation that traverses the FIR and modifies types and operations to a
 | 
					/// generation that traverses the FIR and modifies types and operations to a
 | 
				
			||||||
/// form that is appropriate for the specific target. LLVM IR has specific
 | 
					/// form that is appropriate for the specific target. LLVM IR has specific
 | 
				
			||||||
/// idioms that are used for distinct target processor and ABI combinations.
 | 
					/// idioms that are used for distinct target processor and ABI combinations.
 | 
				
			||||||
class TargetRewrite : public TargetRewriteBase<TargetRewrite> {
 | 
					class TargetRewrite : public fir::TargetRewriteBase<TargetRewrite> {
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
  TargetRewrite(const TargetRewriteOptions &options) {
 | 
					  TargetRewrite(const fir::TargetRewriteOptions &options) {
 | 
				
			||||||
    noCharacterConversion = options.noCharacterConversion;
 | 
					    noCharacterConversion = options.noCharacterConversion;
 | 
				
			||||||
    noComplexConversion = options.noComplexConversion;
 | 
					    noComplexConversion = options.noComplexConversion;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -82,10 +79,10 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto mod = getModule();
 | 
					    auto mod = getModule();
 | 
				
			||||||
    if (!forcedTargetTriple.empty())
 | 
					    if (!forcedTargetTriple.empty())
 | 
				
			||||||
      setTargetTriple(mod, forcedTargetTriple);
 | 
					      fir::setTargetTriple(mod, forcedTargetTriple);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto specifics = CodeGenSpecifics::get(
 | 
					    auto specifics = fir::CodeGenSpecifics::get(
 | 
				
			||||||
        mod.getContext(), getTargetTriple(mod), getKindMapping(mod));
 | 
					        mod.getContext(), fir::getTargetTriple(mod), fir::getKindMapping(mod));
 | 
				
			||||||
    setMembers(specifics.get(), &rewriter);
 | 
					    setMembers(specifics.get(), &rewriter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Perform type conversion on signatures and call sites.
 | 
					    // Perform type conversion on signatures and call sites.
 | 
				
			||||||
| 
						 | 
					@ -97,13 +94,13 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Convert ops in target-specific patterns.
 | 
					    // Convert ops in target-specific patterns.
 | 
				
			||||||
    mod.walk([&](mlir::Operation *op) {
 | 
					    mod.walk([&](mlir::Operation *op) {
 | 
				
			||||||
      if (auto call = dyn_cast<fir::CallOp>(op)) {
 | 
					      if (auto call = mlir::dyn_cast<fir::CallOp>(op)) {
 | 
				
			||||||
        if (!hasPortableSignature(call.getFunctionType()))
 | 
					        if (!hasPortableSignature(call.getFunctionType()))
 | 
				
			||||||
          convertCallOp(call);
 | 
					          convertCallOp(call);
 | 
				
			||||||
      } else if (auto dispatch = dyn_cast<DispatchOp>(op)) {
 | 
					      } else if (auto dispatch = mlir::dyn_cast<fir::DispatchOp>(op)) {
 | 
				
			||||||
        if (!hasPortableSignature(dispatch.getFunctionType()))
 | 
					        if (!hasPortableSignature(dispatch.getFunctionType()))
 | 
				
			||||||
          convertCallOp(dispatch);
 | 
					          convertCallOp(dispatch);
 | 
				
			||||||
      } else if (auto addr = dyn_cast<AddrOfOp>(op)) {
 | 
					      } else if (auto addr = mlir::dyn_cast<fir::AddrOfOp>(op)) {
 | 
				
			||||||
        if (addr.getType().isa<mlir::FunctionType>() &&
 | 
					        if (addr.getType().isa<mlir::FunctionType>() &&
 | 
				
			||||||
            !hasPortableSignature(addr.getType()))
 | 
					            !hasPortableSignature(addr.getType()))
 | 
				
			||||||
          convertAddrOp(addr);
 | 
					          convertAddrOp(addr);
 | 
				
			||||||
| 
						 | 
					@ -123,17 +120,17 @@ public:
 | 
				
			||||||
    // scalar, including the sret case.
 | 
					    // scalar, including the sret case.
 | 
				
			||||||
    assert(m.size() == 1 && "target lowering of complex return not supported");
 | 
					    assert(m.size() == 1 && "target lowering of complex return not supported");
 | 
				
			||||||
    auto resTy = std::get<mlir::Type>(m[0]);
 | 
					    auto resTy = std::get<mlir::Type>(m[0]);
 | 
				
			||||||
    auto attr = std::get<CodeGenSpecifics::Attributes>(m[0]);
 | 
					    auto attr = std::get<fir::CodeGenSpecifics::Attributes>(m[0]);
 | 
				
			||||||
    auto loc = mlir::UnknownLoc::get(resTy.getContext());
 | 
					    auto loc = mlir::UnknownLoc::get(resTy.getContext());
 | 
				
			||||||
    if (attr.isSRet()) {
 | 
					    if (attr.isSRet()) {
 | 
				
			||||||
      assert(isa_ref_type(resTy));
 | 
					      assert(fir::isa_ref_type(resTy) && "must be a memory reference type");
 | 
				
			||||||
      mlir::Value stack =
 | 
					      mlir::Value stack =
 | 
				
			||||||
          rewriter->create<fir::AllocaOp>(loc, dyn_cast_ptrEleTy(resTy));
 | 
					          rewriter->create<fir::AllocaOp>(loc, fir::dyn_cast_ptrEleTy(resTy));
 | 
				
			||||||
      newInTys.push_back(resTy);
 | 
					      newInTys.push_back(resTy);
 | 
				
			||||||
      newOpers.push_back(stack);
 | 
					      newOpers.push_back(stack);
 | 
				
			||||||
      return [=](mlir::Operation *) -> mlir::Value {
 | 
					      return [=](mlir::Operation *) -> mlir::Value {
 | 
				
			||||||
        auto memTy = ReferenceType::get(ty);
 | 
					        auto memTy = fir::ReferenceType::get(ty);
 | 
				
			||||||
        auto cast = rewriter->create<ConvertOp>(loc, memTy, stack);
 | 
					        auto cast = rewriter->create<fir::ConvertOp>(loc, memTy, stack);
 | 
				
			||||||
        return rewriter->create<fir::LoadOp>(loc, cast);
 | 
					        return rewriter->create<fir::LoadOp>(loc, cast);
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -141,8 +138,8 @@ public:
 | 
				
			||||||
    return [=](mlir::Operation *call) -> mlir::Value {
 | 
					    return [=](mlir::Operation *call) -> mlir::Value {
 | 
				
			||||||
      auto mem = rewriter->create<fir::AllocaOp>(loc, resTy);
 | 
					      auto mem = rewriter->create<fir::AllocaOp>(loc, resTy);
 | 
				
			||||||
      rewriter->create<fir::StoreOp>(loc, call->getResult(0), mem);
 | 
					      rewriter->create<fir::StoreOp>(loc, call->getResult(0), mem);
 | 
				
			||||||
      auto memTy = ReferenceType::get(ty);
 | 
					      auto memTy = fir::ReferenceType::get(ty);
 | 
				
			||||||
      auto cast = rewriter->create<ConvertOp>(loc, memTy, mem);
 | 
					      auto cast = rewriter->create<fir::ConvertOp>(loc, memTy, mem);
 | 
				
			||||||
      return rewriter->create<fir::LoadOp>(loc, cast);
 | 
					      return rewriter->create<fir::LoadOp>(loc, cast);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -156,15 +153,15 @@ public:
 | 
				
			||||||
    if (m.size() == 1) {
 | 
					    if (m.size() == 1) {
 | 
				
			||||||
      // COMPLEX is a single aggregate
 | 
					      // COMPLEX is a single aggregate
 | 
				
			||||||
      auto resTy = std::get<mlir::Type>(m[0]);
 | 
					      auto resTy = std::get<mlir::Type>(m[0]);
 | 
				
			||||||
      auto attr = std::get<CodeGenSpecifics::Attributes>(m[0]);
 | 
					      auto attr = std::get<fir::CodeGenSpecifics::Attributes>(m[0]);
 | 
				
			||||||
      auto oldRefTy = ReferenceType::get(ty);
 | 
					      auto oldRefTy = fir::ReferenceType::get(ty);
 | 
				
			||||||
      if (attr.isByVal()) {
 | 
					      if (attr.isByVal()) {
 | 
				
			||||||
        auto mem = rewriter->create<fir::AllocaOp>(loc, ty);
 | 
					        auto mem = rewriter->create<fir::AllocaOp>(loc, ty);
 | 
				
			||||||
        rewriter->create<fir::StoreOp>(loc, oper, mem);
 | 
					        rewriter->create<fir::StoreOp>(loc, oper, mem);
 | 
				
			||||||
        newOpers.push_back(rewriter->create<ConvertOp>(loc, resTy, mem));
 | 
					        newOpers.push_back(rewriter->create<fir::ConvertOp>(loc, resTy, mem));
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        auto mem = rewriter->create<fir::AllocaOp>(loc, resTy);
 | 
					        auto mem = rewriter->create<fir::AllocaOp>(loc, resTy);
 | 
				
			||||||
        auto cast = rewriter->create<ConvertOp>(loc, oldRefTy, mem);
 | 
					        auto cast = rewriter->create<fir::ConvertOp>(loc, oldRefTy, mem);
 | 
				
			||||||
        rewriter->create<fir::StoreOp>(loc, oper, cast);
 | 
					        rewriter->create<fir::StoreOp>(loc, oper, cast);
 | 
				
			||||||
        newOpers.push_back(rewriter->create<fir::LoadOp>(loc, mem));
 | 
					        newOpers.push_back(rewriter->create<fir::LoadOp>(loc, mem));
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
| 
						 | 
					@ -178,7 +175,7 @@ public:
 | 
				
			||||||
        auto ty = std::get<mlir::Type>(tup);
 | 
					        auto ty = std::get<mlir::Type>(tup);
 | 
				
			||||||
        auto index = e.index();
 | 
					        auto index = e.index();
 | 
				
			||||||
        auto idx = rewriter->getIntegerAttr(iTy, index);
 | 
					        auto idx = rewriter->getIntegerAttr(iTy, index);
 | 
				
			||||||
        auto val = rewriter->create<ExtractValueOp>(
 | 
					        auto val = rewriter->create<fir::ExtractValueOp>(
 | 
				
			||||||
            loc, ty, oper, rewriter->getArrayAttr(idx));
 | 
					            loc, ty, oper, rewriter->getArrayAttr(idx));
 | 
				
			||||||
        newInTys.push_back(ty);
 | 
					        newInTys.push_back(ty);
 | 
				
			||||||
        newOpers.push_back(val);
 | 
					        newOpers.push_back(val);
 | 
				
			||||||
| 
						 | 
					@ -234,7 +231,7 @@ public:
 | 
				
			||||||
      mlir::Value oper = std::get<1>(e.value());
 | 
					      mlir::Value oper = std::get<1>(e.value());
 | 
				
			||||||
      unsigned index = e.index();
 | 
					      unsigned index = e.index();
 | 
				
			||||||
      llvm::TypeSwitch<mlir::Type>(ty)
 | 
					      llvm::TypeSwitch<mlir::Type>(ty)
 | 
				
			||||||
          .template Case<BoxCharType>([&](BoxCharType boxTy) {
 | 
					          .template Case<fir::BoxCharType>([&](fir::BoxCharType boxTy) {
 | 
				
			||||||
            bool sret;
 | 
					            bool sret;
 | 
				
			||||||
            if constexpr (std::is_same_v<std::decay_t<A>, fir::CallOp>) {
 | 
					            if constexpr (std::is_same_v<std::decay_t<A>, fir::CallOp>) {
 | 
				
			||||||
              sret = callOp.getCallee() &&
 | 
					              sret = callOp.getCallee() &&
 | 
				
			||||||
| 
						 | 
					@ -248,13 +245,14 @@ public:
 | 
				
			||||||
              TODO(loc, "dispatch + sret not supported yet");
 | 
					              TODO(loc, "dispatch + sret not supported yet");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            auto m = specifics->boxcharArgumentType(boxTy.getEleTy(), sret);
 | 
					            auto m = specifics->boxcharArgumentType(boxTy.getEleTy(), sret);
 | 
				
			||||||
            auto unbox =
 | 
					            auto unbox = rewriter->create<fir::UnboxCharOp>(
 | 
				
			||||||
                rewriter->create<UnboxCharOp>(loc, std::get<mlir::Type>(m[0]),
 | 
					                loc, std::get<mlir::Type>(m[0]), std::get<mlir::Type>(m[1]),
 | 
				
			||||||
                                              std::get<mlir::Type>(m[1]), oper);
 | 
					                oper);
 | 
				
			||||||
            // unboxed CHARACTER arguments
 | 
					            // unboxed CHARACTER arguments
 | 
				
			||||||
            for (auto e : llvm::enumerate(m)) {
 | 
					            for (auto e : llvm::enumerate(m)) {
 | 
				
			||||||
              unsigned idx = e.index();
 | 
					              unsigned idx = e.index();
 | 
				
			||||||
              auto attr = std::get<CodeGenSpecifics::Attributes>(e.value());
 | 
					              auto attr =
 | 
				
			||||||
 | 
					                  std::get<fir::CodeGenSpecifics::Attributes>(e.value());
 | 
				
			||||||
              auto argTy = std::get<mlir::Type>(e.value());
 | 
					              auto argTy = std::get<mlir::Type>(e.value());
 | 
				
			||||||
              if (attr.isAppend()) {
 | 
					              if (attr.isAppend()) {
 | 
				
			||||||
                trailingInTys.push_back(argTy);
 | 
					                trailingInTys.push_back(argTy);
 | 
				
			||||||
| 
						 | 
					@ -272,12 +270,12 @@ public:
 | 
				
			||||||
            rewriteCallComplexInputType(cmplx, oper, newInTys, newOpers);
 | 
					            rewriteCallComplexInputType(cmplx, oper, newInTys, newOpers);
 | 
				
			||||||
          })
 | 
					          })
 | 
				
			||||||
          .template Case<mlir::TupleType>([&](mlir::TupleType tuple) {
 | 
					          .template Case<mlir::TupleType>([&](mlir::TupleType tuple) {
 | 
				
			||||||
            if (isCharacterProcedureTuple(tuple)) {
 | 
					            if (fir::isCharacterProcedureTuple(tuple)) {
 | 
				
			||||||
              mlir::ModuleOp module = getModule();
 | 
					              mlir::ModuleOp module = getModule();
 | 
				
			||||||
              if constexpr (std::is_same_v<std::decay_t<A>, fir::CallOp>) {
 | 
					              if constexpr (std::is_same_v<std::decay_t<A>, fir::CallOp>) {
 | 
				
			||||||
                if (callOp.getCallee()) {
 | 
					                if (callOp.getCallee()) {
 | 
				
			||||||
                  llvm::StringRef charProcAttr =
 | 
					                  llvm::StringRef charProcAttr =
 | 
				
			||||||
                      getCharacterProcedureDummyAttrName();
 | 
					                      fir::getCharacterProcedureDummyAttrName();
 | 
				
			||||||
                  // The charProcAttr attribute is only used as a safety to
 | 
					                  // The charProcAttr attribute is only used as a safety to
 | 
				
			||||||
                  // confirm that this is a dummy procedure and should be split.
 | 
					                  // confirm that this is a dummy procedure and should be split.
 | 
				
			||||||
                  // It cannot be used to match because attributes are not
 | 
					                  // It cannot be used to match because attributes are not
 | 
				
			||||||
| 
						 | 
					@ -294,9 +292,10 @@ public:
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
              mlir::Type funcPointerType = tuple.getType(0);
 | 
					              mlir::Type funcPointerType = tuple.getType(0);
 | 
				
			||||||
              mlir::Type lenType = tuple.getType(1);
 | 
					              mlir::Type lenType = tuple.getType(1);
 | 
				
			||||||
              FirOpBuilder builder(*rewriter, getKindMapping(module));
 | 
					              fir::FirOpBuilder builder(*rewriter, fir::getKindMapping(module));
 | 
				
			||||||
              auto [funcPointer, len] =
 | 
					              auto [funcPointer, len] =
 | 
				
			||||||
                  factory::extractCharacterProcedureTuple(builder, loc, oper);
 | 
					                  fir::factory::extractCharacterProcedureTuple(builder, loc,
 | 
				
			||||||
 | 
					                                                               oper);
 | 
				
			||||||
              newInTys.push_back(funcPointerType);
 | 
					              newInTys.push_back(funcPointerType);
 | 
				
			||||||
              newOpers.push_back(funcPointer);
 | 
					              newOpers.push_back(funcPointer);
 | 
				
			||||||
              trailingInTys.push_back(lenType);
 | 
					              trailingInTys.push_back(lenType);
 | 
				
			||||||
| 
						 | 
					@ -344,7 +343,7 @@ public:
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      for (auto &tup : specifics->complexReturnType(cmplx.getElementType())) {
 | 
					      for (auto &tup : specifics->complexReturnType(cmplx.getElementType())) {
 | 
				
			||||||
        auto argTy = std::get<mlir::Type>(tup);
 | 
					        auto argTy = std::get<mlir::Type>(tup);
 | 
				
			||||||
        if (std::get<CodeGenSpecifics::Attributes>(tup).isSRet())
 | 
					        if (std::get<fir::CodeGenSpecifics::Attributes>(tup).isSRet())
 | 
				
			||||||
          newInTys.push_back(argTy);
 | 
					          newInTys.push_back(argTy);
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
          newResTys.push_back(argTy);
 | 
					          newResTys.push_back(argTy);
 | 
				
			||||||
| 
						 | 
					@ -363,7 +362,7 @@ public:
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Taking the address of a function. Modify the signature as needed.
 | 
					  /// Taking the address of a function. Modify the signature as needed.
 | 
				
			||||||
  void convertAddrOp(AddrOfOp addrOp) {
 | 
					  void convertAddrOp(fir::AddrOfOp addrOp) {
 | 
				
			||||||
    rewriter->setInsertionPoint(addrOp);
 | 
					    rewriter->setInsertionPoint(addrOp);
 | 
				
			||||||
    auto addrTy = addrOp.getType().cast<mlir::FunctionType>();
 | 
					    auto addrTy = addrOp.getType().cast<mlir::FunctionType>();
 | 
				
			||||||
    llvm::SmallVector<mlir::Type> newResTys;
 | 
					    llvm::SmallVector<mlir::Type> newResTys;
 | 
				
			||||||
| 
						 | 
					@ -381,12 +380,12 @@ public:
 | 
				
			||||||
    llvm::SmallVector<mlir::Type> trailingInTys;
 | 
					    llvm::SmallVector<mlir::Type> trailingInTys;
 | 
				
			||||||
    for (mlir::Type ty : addrTy.getInputs()) {
 | 
					    for (mlir::Type ty : addrTy.getInputs()) {
 | 
				
			||||||
      llvm::TypeSwitch<mlir::Type>(ty)
 | 
					      llvm::TypeSwitch<mlir::Type>(ty)
 | 
				
			||||||
          .Case<BoxCharType>([&](BoxCharType box) {
 | 
					          .Case<fir::BoxCharType>([&](auto box) {
 | 
				
			||||||
            if (noCharacterConversion) {
 | 
					            if (noCharacterConversion) {
 | 
				
			||||||
              newInTys.push_back(box);
 | 
					              newInTys.push_back(box);
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
              for (auto &tup : specifics->boxcharArgumentType(box.getEleTy())) {
 | 
					              for (auto &tup : specifics->boxcharArgumentType(box.getEleTy())) {
 | 
				
			||||||
                auto attr = std::get<CodeGenSpecifics::Attributes>(tup);
 | 
					                auto attr = std::get<fir::CodeGenSpecifics::Attributes>(tup);
 | 
				
			||||||
                auto argTy = std::get<mlir::Type>(tup);
 | 
					                auto argTy = std::get<mlir::Type>(tup);
 | 
				
			||||||
                llvm::SmallVector<mlir::Type> &vec =
 | 
					                llvm::SmallVector<mlir::Type> &vec =
 | 
				
			||||||
                    attr.isAppend() ? trailingInTys : newInTys;
 | 
					                    attr.isAppend() ? trailingInTys : newInTys;
 | 
				
			||||||
| 
						 | 
					@ -401,7 +400,7 @@ public:
 | 
				
			||||||
            lowerComplexSignatureArg(ty, newInTys);
 | 
					            lowerComplexSignatureArg(ty, newInTys);
 | 
				
			||||||
          })
 | 
					          })
 | 
				
			||||||
          .Case<mlir::TupleType>([&](mlir::TupleType tuple) {
 | 
					          .Case<mlir::TupleType>([&](mlir::TupleType tuple) {
 | 
				
			||||||
            if (isCharacterProcedureTuple(tuple)) {
 | 
					            if (fir::isCharacterProcedureTuple(tuple)) {
 | 
				
			||||||
              newInTys.push_back(tuple.getType(0));
 | 
					              newInTys.push_back(tuple.getType(0));
 | 
				
			||||||
              trailingInTys.push_back(tuple.getType(1));
 | 
					              trailingInTys.push_back(tuple.getType(1));
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
| 
						 | 
					@ -414,8 +413,8 @@ public:
 | 
				
			||||||
    newInTys.insert(newInTys.end(), trailingInTys.begin(), trailingInTys.end());
 | 
					    newInTys.insert(newInTys.end(), trailingInTys.begin(), trailingInTys.end());
 | 
				
			||||||
    // replace this op with a new one with the updated signature
 | 
					    // replace this op with a new one with the updated signature
 | 
				
			||||||
    auto newTy = rewriter->getFunctionType(newInTys, newResTys);
 | 
					    auto newTy = rewriter->getFunctionType(newInTys, newResTys);
 | 
				
			||||||
    auto newOp =
 | 
					    auto newOp = rewriter->create<fir::AddrOfOp>(addrOp.getLoc(), newTy,
 | 
				
			||||||
        rewriter->create<AddrOfOp>(addrOp.getLoc(), newTy, addrOp.getSymbol());
 | 
					                                                 addrOp.getSymbol());
 | 
				
			||||||
    replaceOp(addrOp, newOp.getResult());
 | 
					    replaceOp(addrOp, newOp.getResult());
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -436,15 +435,15 @@ public:
 | 
				
			||||||
    assert(signature.isa<mlir::FunctionType>());
 | 
					    assert(signature.isa<mlir::FunctionType>());
 | 
				
			||||||
    auto func = signature.dyn_cast<mlir::FunctionType>();
 | 
					    auto func = signature.dyn_cast<mlir::FunctionType>();
 | 
				
			||||||
    for (auto ty : func.getResults())
 | 
					    for (auto ty : func.getResults())
 | 
				
			||||||
      if ((ty.isa<BoxCharType>() && !noCharacterConversion) ||
 | 
					      if ((ty.isa<fir::BoxCharType>() && !noCharacterConversion) ||
 | 
				
			||||||
          (isa_complex(ty) && !noComplexConversion)) {
 | 
					          (fir::isa_complex(ty) && !noComplexConversion)) {
 | 
				
			||||||
        LLVM_DEBUG(llvm::dbgs() << "rewrite " << signature << " for target\n");
 | 
					        LLVM_DEBUG(llvm::dbgs() << "rewrite " << signature << " for target\n");
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    for (auto ty : func.getInputs())
 | 
					    for (auto ty : func.getInputs())
 | 
				
			||||||
      if (((ty.isa<BoxCharType>() || isCharacterProcedureTuple(ty)) &&
 | 
					      if (((ty.isa<fir::BoxCharType>() || fir::isCharacterProcedureTuple(ty)) &&
 | 
				
			||||||
           !noCharacterConversion) ||
 | 
					           !noCharacterConversion) ||
 | 
				
			||||||
          (isa_complex(ty) && !noComplexConversion)) {
 | 
					          (fir::isa_complex(ty) && !noComplexConversion)) {
 | 
				
			||||||
        LLVM_DEBUG(llvm::dbgs() << "rewrite " << signature << " for target\n");
 | 
					        LLVM_DEBUG(llvm::dbgs() << "rewrite " << signature << " for target\n");
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
| 
						 | 
					@ -456,7 +455,7 @@ public:
 | 
				
			||||||
  static bool hasHostAssociations(mlir::func::FuncOp func) {
 | 
					  static bool hasHostAssociations(mlir::func::FuncOp func) {
 | 
				
			||||||
    std::size_t end = func.getFunctionType().getInputs().size();
 | 
					    std::size_t end = func.getFunctionType().getInputs().size();
 | 
				
			||||||
    for (std::size_t i = 0; i < end; ++i)
 | 
					    for (std::size_t i = 0; i < end; ++i)
 | 
				
			||||||
      if (func.getArgAttrOfType<mlir::UnitAttr>(i, getHostAssocAttrName()))
 | 
					      if (func.getArgAttrOfType<mlir::UnitAttr>(i, fir::getHostAssocAttrName()))
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -494,7 +493,7 @@ public:
 | 
				
			||||||
      auto ty = e.value();
 | 
					      auto ty = e.value();
 | 
				
			||||||
      unsigned index = e.index();
 | 
					      unsigned index = e.index();
 | 
				
			||||||
      llvm::TypeSwitch<mlir::Type>(ty)
 | 
					      llvm::TypeSwitch<mlir::Type>(ty)
 | 
				
			||||||
          .Case<BoxCharType>([&](BoxCharType boxTy) {
 | 
					          .Case<fir::BoxCharType>([&](fir::BoxCharType boxTy) {
 | 
				
			||||||
            if (noCharacterConversion) {
 | 
					            if (noCharacterConversion) {
 | 
				
			||||||
              newInTys.push_back(boxTy);
 | 
					              newInTys.push_back(boxTy);
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
| 
						 | 
					@ -506,7 +505,7 @@ public:
 | 
				
			||||||
                       boxTy.getEleTy(), sret))) {
 | 
					                       boxTy.getEleTy(), sret))) {
 | 
				
			||||||
                auto &tup = e.value();
 | 
					                auto &tup = e.value();
 | 
				
			||||||
                auto index = e.index();
 | 
					                auto index = e.index();
 | 
				
			||||||
                auto attr = std::get<CodeGenSpecifics::Attributes>(tup);
 | 
					                auto attr = std::get<fir::CodeGenSpecifics::Attributes>(tup);
 | 
				
			||||||
                auto argTy = std::get<mlir::Type>(tup);
 | 
					                auto argTy = std::get<mlir::Type>(tup);
 | 
				
			||||||
                if (attr.isAppend()) {
 | 
					                if (attr.isAppend()) {
 | 
				
			||||||
                  trailingTys.push_back(argTy);
 | 
					                  trailingTys.push_back(argTy);
 | 
				
			||||||
| 
						 | 
					@ -536,7 +535,7 @@ public:
 | 
				
			||||||
              doComplexArg(func, cmplx, newInTys, fixups);
 | 
					              doComplexArg(func, cmplx, newInTys, fixups);
 | 
				
			||||||
          })
 | 
					          })
 | 
				
			||||||
          .Case<mlir::TupleType>([&](mlir::TupleType tuple) {
 | 
					          .Case<mlir::TupleType>([&](mlir::TupleType tuple) {
 | 
				
			||||||
            if (isCharacterProcedureTuple(tuple)) {
 | 
					            if (fir::isCharacterProcedureTuple(tuple)) {
 | 
				
			||||||
              fixups.emplace_back(FixupTy::Codes::TrailingCharProc,
 | 
					              fixups.emplace_back(FixupTy::Codes::TrailingCharProc,
 | 
				
			||||||
                                  newInTys.size(), trailingTys.size());
 | 
					                                  newInTys.size(), trailingTys.size());
 | 
				
			||||||
              newInTys.push_back(tuple.getType(0));
 | 
					              newInTys.push_back(tuple.getType(0));
 | 
				
			||||||
| 
						 | 
					@ -547,7 +546,7 @@ public:
 | 
				
			||||||
          })
 | 
					          })
 | 
				
			||||||
          .Default([&](mlir::Type ty) { newInTys.push_back(ty); });
 | 
					          .Default([&](mlir::Type ty) { newInTys.push_back(ty); });
 | 
				
			||||||
      if (func.getArgAttrOfType<mlir::UnitAttr>(index,
 | 
					      if (func.getArgAttrOfType<mlir::UnitAttr>(index,
 | 
				
			||||||
                                                getHostAssocAttrName())) {
 | 
					                                                fir::getHostAssocAttrName())) {
 | 
				
			||||||
        func.setArgAttr(index, "llvm.nest", rewriter->getUnitAttr());
 | 
					        func.setArgAttr(index, "llvm.nest", rewriter->getUnitAttr());
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -568,8 +567,9 @@ public:
 | 
				
			||||||
          auto newArg = func.front().insertArgument(fixup.index,
 | 
					          auto newArg = func.front().insertArgument(fixup.index,
 | 
				
			||||||
                                                    newInTys[fixup.index], loc);
 | 
					                                                    newInTys[fixup.index], loc);
 | 
				
			||||||
          rewriter->setInsertionPointToStart(&func.front());
 | 
					          rewriter->setInsertionPointToStart(&func.front());
 | 
				
			||||||
          auto oldArgTy = ReferenceType::get(oldArgTys[fixup.index - offset]);
 | 
					          auto oldArgTy =
 | 
				
			||||||
          auto cast = rewriter->create<ConvertOp>(loc, oldArgTy, newArg);
 | 
					              fir::ReferenceType::get(oldArgTys[fixup.index - offset]);
 | 
				
			||||||
 | 
					          auto cast = rewriter->create<fir::ConvertOp>(loc, oldArgTy, newArg);
 | 
				
			||||||
          auto load = rewriter->create<fir::LoadOp>(loc, cast);
 | 
					          auto load = rewriter->create<fir::LoadOp>(loc, cast);
 | 
				
			||||||
          func.getArgument(fixup.index + 1).replaceAllUsesWith(load);
 | 
					          func.getArgument(fixup.index + 1).replaceAllUsesWith(load);
 | 
				
			||||||
          func.front().eraseArgument(fixup.index + 1);
 | 
					          func.front().eraseArgument(fixup.index + 1);
 | 
				
			||||||
| 
						 | 
					@ -583,8 +583,9 @@ public:
 | 
				
			||||||
          auto mem =
 | 
					          auto mem =
 | 
				
			||||||
              rewriter->create<fir::AllocaOp>(loc, newInTys[fixup.index]);
 | 
					              rewriter->create<fir::AllocaOp>(loc, newInTys[fixup.index]);
 | 
				
			||||||
          rewriter->create<fir::StoreOp>(loc, newArg, mem);
 | 
					          rewriter->create<fir::StoreOp>(loc, newArg, mem);
 | 
				
			||||||
          auto oldArgTy = ReferenceType::get(oldArgTys[fixup.index - offset]);
 | 
					          auto oldArgTy =
 | 
				
			||||||
          auto cast = rewriter->create<ConvertOp>(loc, oldArgTy, mem);
 | 
					              fir::ReferenceType::get(oldArgTys[fixup.index - offset]);
 | 
				
			||||||
 | 
					          auto cast = rewriter->create<fir::ConvertOp>(loc, oldArgTy, mem);
 | 
				
			||||||
          mlir::Value load = rewriter->create<fir::LoadOp>(loc, cast);
 | 
					          mlir::Value load = rewriter->create<fir::LoadOp>(loc, cast);
 | 
				
			||||||
          func.getArgument(fixup.index + 1).replaceAllUsesWith(load);
 | 
					          func.getArgument(fixup.index + 1).replaceAllUsesWith(load);
 | 
				
			||||||
          func.front().eraseArgument(fixup.index + 1);
 | 
					          func.front().eraseArgument(fixup.index + 1);
 | 
				
			||||||
| 
						 | 
					@ -601,7 +602,7 @@ public:
 | 
				
			||||||
          if (fixup.second == 1) {
 | 
					          if (fixup.second == 1) {
 | 
				
			||||||
            rewriter->setInsertionPointToStart(&func.front());
 | 
					            rewriter->setInsertionPointToStart(&func.front());
 | 
				
			||||||
            auto boxTy = oldArgTys[fixup.index - offset - fixup.second];
 | 
					            auto boxTy = oldArgTys[fixup.index - offset - fixup.second];
 | 
				
			||||||
            auto box = rewriter->create<EmboxCharOp>(
 | 
					            auto box = rewriter->create<fir::EmboxCharOp>(
 | 
				
			||||||
                loc, boxTy, func.front().getArgument(fixup.index - 1), newArg);
 | 
					                loc, boxTy, func.front().getArgument(fixup.index - 1), newArg);
 | 
				
			||||||
            func.getArgument(fixup.index + 1).replaceAllUsesWith(box);
 | 
					            func.getArgument(fixup.index + 1).replaceAllUsesWith(box);
 | 
				
			||||||
            func.front().eraseArgument(fixup.index + 1);
 | 
					            func.front().eraseArgument(fixup.index + 1);
 | 
				
			||||||
| 
						 | 
					@ -617,8 +618,9 @@ public:
 | 
				
			||||||
          func.walk([&](mlir::func::ReturnOp ret) {
 | 
					          func.walk([&](mlir::func::ReturnOp ret) {
 | 
				
			||||||
            rewriter->setInsertionPoint(ret);
 | 
					            rewriter->setInsertionPoint(ret);
 | 
				
			||||||
            auto oldOper = ret.getOperand(0);
 | 
					            auto oldOper = ret.getOperand(0);
 | 
				
			||||||
            auto oldOperTy = ReferenceType::get(oldOper.getType());
 | 
					            auto oldOperTy = fir::ReferenceType::get(oldOper.getType());
 | 
				
			||||||
            auto cast = rewriter->create<ConvertOp>(loc, oldOperTy, newArg);
 | 
					            auto cast =
 | 
				
			||||||
 | 
					                rewriter->create<fir::ConvertOp>(loc, oldOperTy, newArg);
 | 
				
			||||||
            rewriter->create<fir::StoreOp>(loc, oldOper, cast);
 | 
					            rewriter->create<fir::StoreOp>(loc, oldOper, cast);
 | 
				
			||||||
            rewriter->create<mlir::func::ReturnOp>(loc);
 | 
					            rewriter->create<mlir::func::ReturnOp>(loc);
 | 
				
			||||||
            ret.erase();
 | 
					            ret.erase();
 | 
				
			||||||
| 
						 | 
					@ -630,10 +632,10 @@ public:
 | 
				
			||||||
          func.walk([&](mlir::func::ReturnOp ret) {
 | 
					          func.walk([&](mlir::func::ReturnOp ret) {
 | 
				
			||||||
            rewriter->setInsertionPoint(ret);
 | 
					            rewriter->setInsertionPoint(ret);
 | 
				
			||||||
            auto oldOper = ret.getOperand(0);
 | 
					            auto oldOper = ret.getOperand(0);
 | 
				
			||||||
            auto oldOperTy = ReferenceType::get(oldOper.getType());
 | 
					            auto oldOperTy = fir::ReferenceType::get(oldOper.getType());
 | 
				
			||||||
            auto mem =
 | 
					            auto mem =
 | 
				
			||||||
                rewriter->create<fir::AllocaOp>(loc, newResTys[fixup.index]);
 | 
					                rewriter->create<fir::AllocaOp>(loc, newResTys[fixup.index]);
 | 
				
			||||||
            auto cast = rewriter->create<ConvertOp>(loc, oldOperTy, mem);
 | 
					            auto cast = rewriter->create<fir::ConvertOp>(loc, oldOperTy, mem);
 | 
				
			||||||
            rewriter->create<fir::StoreOp>(loc, oldOper, cast);
 | 
					            rewriter->create<fir::StoreOp>(loc, oldOper, cast);
 | 
				
			||||||
            mlir::Value load = rewriter->create<fir::LoadOp>(loc, mem);
 | 
					            mlir::Value load = rewriter->create<fir::LoadOp>(loc, mem);
 | 
				
			||||||
            rewriter->create<mlir::func::ReturnOp>(loc, load);
 | 
					            rewriter->create<mlir::func::ReturnOp>(loc, load);
 | 
				
			||||||
| 
						 | 
					@ -648,14 +650,14 @@ public:
 | 
				
			||||||
          if (fixup.second == 1) {
 | 
					          if (fixup.second == 1) {
 | 
				
			||||||
            rewriter->setInsertionPointToStart(&func.front());
 | 
					            rewriter->setInsertionPointToStart(&func.front());
 | 
				
			||||||
            auto cplxTy = oldArgTys[fixup.index - offset - fixup.second];
 | 
					            auto cplxTy = oldArgTys[fixup.index - offset - fixup.second];
 | 
				
			||||||
            auto undef = rewriter->create<UndefOp>(loc, cplxTy);
 | 
					            auto undef = rewriter->create<fir::UndefOp>(loc, cplxTy);
 | 
				
			||||||
            auto iTy = rewriter->getIntegerType(32);
 | 
					            auto iTy = rewriter->getIntegerType(32);
 | 
				
			||||||
            auto zero = rewriter->getIntegerAttr(iTy, 0);
 | 
					            auto zero = rewriter->getIntegerAttr(iTy, 0);
 | 
				
			||||||
            auto one = rewriter->getIntegerAttr(iTy, 1);
 | 
					            auto one = rewriter->getIntegerAttr(iTy, 1);
 | 
				
			||||||
            auto cplx1 = rewriter->create<InsertValueOp>(
 | 
					            auto cplx1 = rewriter->create<fir::InsertValueOp>(
 | 
				
			||||||
                loc, cplxTy, undef, func.front().getArgument(fixup.index - 1),
 | 
					                loc, cplxTy, undef, func.front().getArgument(fixup.index - 1),
 | 
				
			||||||
                rewriter->getArrayAttr(zero));
 | 
					                rewriter->getArrayAttr(zero));
 | 
				
			||||||
            auto cplx = rewriter->create<InsertValueOp>(
 | 
					            auto cplx = rewriter->create<fir::InsertValueOp>(
 | 
				
			||||||
                loc, cplxTy, cplx1, newArg, rewriter->getArrayAttr(one));
 | 
					                loc, cplxTy, cplx1, newArg, rewriter->getArrayAttr(one));
 | 
				
			||||||
            func.getArgument(fixup.index + 1).replaceAllUsesWith(cplx);
 | 
					            func.getArgument(fixup.index + 1).replaceAllUsesWith(cplx);
 | 
				
			||||||
            func.front().eraseArgument(fixup.index + 1);
 | 
					            func.front().eraseArgument(fixup.index + 1);
 | 
				
			||||||
| 
						 | 
					@ -673,8 +675,8 @@ public:
 | 
				
			||||||
              func.front().addArgument(trailingTys[fixup.second], loc);
 | 
					              func.front().addArgument(trailingTys[fixup.second], loc);
 | 
				
			||||||
          auto boxTy = oldArgTys[fixup.index - offset];
 | 
					          auto boxTy = oldArgTys[fixup.index - offset];
 | 
				
			||||||
          rewriter->setInsertionPointToStart(&func.front());
 | 
					          rewriter->setInsertionPointToStart(&func.front());
 | 
				
			||||||
          auto box =
 | 
					          auto box = rewriter->create<fir::EmboxCharOp>(loc, boxTy, newBufArg,
 | 
				
			||||||
              rewriter->create<EmboxCharOp>(loc, boxTy, newBufArg, newLenArg);
 | 
					                                                        newLenArg);
 | 
				
			||||||
          func.getArgument(fixup.index + 1).replaceAllUsesWith(box);
 | 
					          func.getArgument(fixup.index + 1).replaceAllUsesWith(box);
 | 
				
			||||||
          func.front().eraseArgument(fixup.index + 1);
 | 
					          func.front().eraseArgument(fixup.index + 1);
 | 
				
			||||||
        } break;
 | 
					        } break;
 | 
				
			||||||
| 
						 | 
					@ -689,8 +691,9 @@ public:
 | 
				
			||||||
              func.front().addArgument(trailingTys[fixup.second], loc);
 | 
					              func.front().addArgument(trailingTys[fixup.second], loc);
 | 
				
			||||||
          auto tupleType = oldArgTys[fixup.index - offset];
 | 
					          auto tupleType = oldArgTys[fixup.index - offset];
 | 
				
			||||||
          rewriter->setInsertionPointToStart(&func.front());
 | 
					          rewriter->setInsertionPointToStart(&func.front());
 | 
				
			||||||
          FirOpBuilder builder(*rewriter, getKindMapping(getModule()));
 | 
					          fir::FirOpBuilder builder(*rewriter,
 | 
				
			||||||
          auto tuple = factory::createCharacterProcedureTuple(
 | 
					                                    fir::getKindMapping(getModule()));
 | 
				
			||||||
 | 
					          auto tuple = fir::factory::createCharacterProcedureTuple(
 | 
				
			||||||
              builder, loc, tupleType, newProcPointerArg, newLenArg);
 | 
					              builder, loc, tupleType, newProcPointerArg, newLenArg);
 | 
				
			||||||
          func.getArgument(fixup.index + 1).replaceAllUsesWith(tuple);
 | 
					          func.getArgument(fixup.index + 1).replaceAllUsesWith(tuple);
 | 
				
			||||||
          func.front().eraseArgument(fixup.index + 1);
 | 
					          func.front().eraseArgument(fixup.index + 1);
 | 
				
			||||||
| 
						 | 
					@ -730,7 +733,7 @@ public:
 | 
				
			||||||
    auto m = specifics->complexReturnType(cmplx.getElementType());
 | 
					    auto m = specifics->complexReturnType(cmplx.getElementType());
 | 
				
			||||||
    assert(m.size() == 1);
 | 
					    assert(m.size() == 1);
 | 
				
			||||||
    auto &tup = m[0];
 | 
					    auto &tup = m[0];
 | 
				
			||||||
    auto attr = std::get<CodeGenSpecifics::Attributes>(tup);
 | 
					    auto attr = std::get<fir::CodeGenSpecifics::Attributes>(tup);
 | 
				
			||||||
    auto argTy = std::get<mlir::Type>(tup);
 | 
					    auto argTy = std::get<mlir::Type>(tup);
 | 
				
			||||||
    if (attr.isSRet()) {
 | 
					    if (attr.isSRet()) {
 | 
				
			||||||
      unsigned argNo = newInTys.size();
 | 
					      unsigned argNo = newInTys.size();
 | 
				
			||||||
| 
						 | 
					@ -760,7 +763,7 @@ public:
 | 
				
			||||||
    for (auto e : llvm::enumerate(m)) {
 | 
					    for (auto e : llvm::enumerate(m)) {
 | 
				
			||||||
      auto &tup = e.value();
 | 
					      auto &tup = e.value();
 | 
				
			||||||
      auto index = e.index();
 | 
					      auto index = e.index();
 | 
				
			||||||
      auto attr = std::get<CodeGenSpecifics::Attributes>(tup);
 | 
					      auto attr = std::get<fir::CodeGenSpecifics::Attributes>(tup);
 | 
				
			||||||
      auto argTy = std::get<mlir::Type>(tup);
 | 
					      auto argTy = std::get<mlir::Type>(tup);
 | 
				
			||||||
      auto argNo = newInTys.size();
 | 
					      auto argNo = newInTys.size();
 | 
				
			||||||
      if (attr.isByVal()) {
 | 
					      if (attr.isByVal()) {
 | 
				
			||||||
| 
						 | 
					@ -802,19 +805,19 @@ private:
 | 
				
			||||||
    op->erase();
 | 
					    op->erase();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  inline void setMembers(CodeGenSpecifics *s, mlir::OpBuilder *r) {
 | 
					  inline void setMembers(fir::CodeGenSpecifics *s, mlir::OpBuilder *r) {
 | 
				
			||||||
    specifics = s;
 | 
					    specifics = s;
 | 
				
			||||||
    rewriter = r;
 | 
					    rewriter = r;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  inline void clearMembers() { setMembers(nullptr, nullptr); }
 | 
					  inline void clearMembers() { setMembers(nullptr, nullptr); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  CodeGenSpecifics *specifics{};
 | 
					  fir::CodeGenSpecifics *specifics = nullptr;
 | 
				
			||||||
  mlir::OpBuilder *rewriter;
 | 
					  mlir::OpBuilder *rewriter = nullptr;
 | 
				
			||||||
}; // namespace
 | 
					}; // namespace
 | 
				
			||||||
} // namespace
 | 
					} // namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::unique_ptr<mlir::OperationPass<mlir::ModuleOp>>
 | 
					std::unique_ptr<mlir::OperationPass<mlir::ModuleOp>>
 | 
				
			||||||
fir::createFirTargetRewritePass(const TargetRewriteOptions &options) {
 | 
					fir::createFirTargetRewritePass(const fir::TargetRewriteOptions &options) {
 | 
				
			||||||
  return std::make_unique<TargetRewrite>(options);
 | 
					  return std::make_unique<TargetRewrite>(options);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -92,8 +92,8 @@ public:
 | 
				
			||||||
    addConversion(
 | 
					    addConversion(
 | 
				
			||||||
        [&](fir::PointerType pointer) { return convertPointerLike(pointer); });
 | 
					        [&](fir::PointerType pointer) { return convertPointerLike(pointer); });
 | 
				
			||||||
    addConversion([&](fir::RecordType derived,
 | 
					    addConversion([&](fir::RecordType derived,
 | 
				
			||||||
                      SmallVectorImpl<mlir::Type> &results,
 | 
					                      llvm::SmallVectorImpl<mlir::Type> &results,
 | 
				
			||||||
                      ArrayRef<mlir::Type> callStack) {
 | 
					                      llvm::ArrayRef<mlir::Type> callStack) {
 | 
				
			||||||
      return convertRecordType(derived, results, callStack);
 | 
					      return convertRecordType(derived, results, callStack);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    addConversion(
 | 
					    addConversion(
 | 
				
			||||||
| 
						 | 
					@ -138,15 +138,15 @@ public:
 | 
				
			||||||
  mlir::Type indexType() { return mlir::IntegerType::get(&getContext(), 64); }
 | 
					  mlir::Type indexType() { return mlir::IntegerType::get(&getContext(), 64); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // fir.type<name(p : TY'...){f : TY...}>  -->  llvm<"%name = { ty... }">
 | 
					  // fir.type<name(p : TY'...){f : TY...}>  -->  llvm<"%name = { ty... }">
 | 
				
			||||||
  llvm::Optional<LogicalResult>
 | 
					  llvm::Optional<mlir::LogicalResult>
 | 
				
			||||||
  convertRecordType(fir::RecordType derived,
 | 
					  convertRecordType(fir::RecordType derived,
 | 
				
			||||||
                    SmallVectorImpl<mlir::Type> &results,
 | 
					                    llvm::SmallVectorImpl<mlir::Type> &results,
 | 
				
			||||||
                    ArrayRef<mlir::Type> callStack) {
 | 
					                    llvm::ArrayRef<mlir::Type> callStack) {
 | 
				
			||||||
    auto name = derived.getName();
 | 
					    auto name = derived.getName();
 | 
				
			||||||
    auto st = mlir::LLVM::LLVMStructType::getIdentified(&getContext(), name);
 | 
					    auto st = mlir::LLVM::LLVMStructType::getIdentified(&getContext(), name);
 | 
				
			||||||
    if (llvm::count(callStack, derived) > 1) {
 | 
					    if (llvm::count(callStack, derived) > 1) {
 | 
				
			||||||
      results.push_back(st);
 | 
					      results.push_back(st);
 | 
				
			||||||
      return success();
 | 
					      return mlir::success();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    llvm::SmallVector<mlir::Type> members;
 | 
					    llvm::SmallVector<mlir::Type> members;
 | 
				
			||||||
    for (auto mem : derived.getTypeList()) {
 | 
					    for (auto mem : derived.getTypeList()) {
 | 
				
			||||||
| 
						 | 
					@ -158,9 +158,9 @@ public:
 | 
				
			||||||
        members.push_back(convertType(mem.second).cast<mlir::Type>());
 | 
					        members.push_back(convertType(mem.second).cast<mlir::Type>());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (mlir::failed(st.setBody(members, /*isPacked=*/false)))
 | 
					    if (mlir::failed(st.setBody(members, /*isPacked=*/false)))
 | 
				
			||||||
      return failure();
 | 
					      return mlir::failure();
 | 
				
			||||||
    results.push_back(st);
 | 
					    results.push_back(st);
 | 
				
			||||||
    return success();
 | 
					    return mlir::success();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Is an extended descriptor needed given the element type of a fir.box type ?
 | 
					  // Is an extended descriptor needed given the element type of a fir.box type ?
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
// RUN: fir-opt %s | tco | FileCheck %s
 | 
					// RUN: tco %s | FileCheck %s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CHECK: @var_x = external global i32
 | 
					// CHECK: @var_x = external global i32
 | 
				
			||||||
fir.global @var_x : !fir.int<4> {}
 | 
					fir.global @var_x : !fir.int<4> {}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
// RUN: fir-opt %s | tco | FileCheck %s
 | 
					// RUN: tco %s | FileCheck %s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CHECK-LABEL: define void @_QPtest_callee({ i32*, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }* %0)
 | 
					// CHECK-LABEL: define void @_QPtest_callee({ i32*, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]] }* %0)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
// RUN: fir-opt %s | tco | FileCheck %s
 | 
					// RUN: tco %s | FileCheck %s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Test applying slice on fir.box
 | 
					// Test applying slice on fir.box
 | 
				
			||||||
//   subroutine foo(x)
 | 
					//   subroutine foo(x)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue