1e9639e9cSValentin Clement (バレンタイン クレメン) //===-- CodeGen.cpp -- bridge to lower to LLVM ----------------------------===// 2e9639e9cSValentin Clement (バレンタイン クレメン) // 3e9639e9cSValentin Clement (バレンタイン クレメン) // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e9639e9cSValentin Clement (バレンタイン クレメン) // See https://llvm.org/LICENSE.txt for license information. 5e9639e9cSValentin Clement (バレンタイン クレメン) // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e9639e9cSValentin Clement (バレンタイン クレメン) // 7e9639e9cSValentin Clement (バレンタイン クレメン) //===----------------------------------------------------------------------===// 8e9639e9cSValentin Clement (バレンタイン クレメン) // 9e9639e9cSValentin Clement (バレンタイン クレメン) // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ 10e9639e9cSValentin Clement (バレンタイン クレメン) // 11e9639e9cSValentin Clement (バレンタイン クレメン) //===----------------------------------------------------------------------===// 12e9639e9cSValentin Clement (バレンタイン クレメン) 13e9639e9cSValentin Clement (バレンタイン クレメン) #include "flang/Optimizer/CodeGen/FIROpPatterns.h" 14e9639e9cSValentin Clement (バレンタイン クレメン) #include "mlir/Dialect/OpenMP/OpenMPDialect.h" 15e9639e9cSValentin Clement (バレンタイン クレメン) #include "llvm/Support/Debug.h" 16e9639e9cSValentin Clement (バレンタイン クレメン) 17e9639e9cSValentin Clement (バレンタイン クレメン) static inline mlir::Type getLlvmPtrType(mlir::MLIRContext *context, 18e9639e9cSValentin Clement (バレンタイン クレメン) unsigned addressSpace = 0) { 19e9639e9cSValentin Clement (バレンタイン クレメン) return mlir::LLVM::LLVMPointerType::get(context, addressSpace); 20e9639e9cSValentin Clement (バレンタイン クレメン) } 21e9639e9cSValentin Clement (バレンタイン クレメン) 22e9639e9cSValentin Clement (バレンタイン クレメン) static unsigned getTypeDescFieldId(mlir::Type ty) { 23fac349a1SChristian Sigg auto isArray = mlir::isa<fir::SequenceType>(fir::dyn_cast_ptrOrBoxEleTy(ty)); 24e9639e9cSValentin Clement (バレンタイン クレメン) return isArray ? kOptTypePtrPosInBox : kDimsPosInBox; 25e9639e9cSValentin Clement (バレンタイン クレメン) } 26e9639e9cSValentin Clement (バレンタイン クレメン) 27e9639e9cSValentin Clement (バレンタイン クレメン) namespace fir { 28e9639e9cSValentin Clement (バレンタイン クレメン) 29e9639e9cSValentin Clement (バレンタイン クレメン) ConvertFIRToLLVMPattern::ConvertFIRToLLVMPattern( 30e9639e9cSValentin Clement (バレンタイン クレメン) llvm::StringRef rootOpName, mlir::MLIRContext *context, 31e9639e9cSValentin Clement (バレンタイン クレメン) const fir::LLVMTypeConverter &typeConverter, 32e9639e9cSValentin Clement (バレンタイン クレメン) const fir::FIRToLLVMPassOptions &options, mlir::PatternBenefit benefit) 33e9639e9cSValentin Clement (バレンタイン クレメン) : ConvertToLLVMPattern(rootOpName, context, typeConverter, benefit), 34e9639e9cSValentin Clement (バレンタイン クレメン) options(options) {} 35e9639e9cSValentin Clement (バレンタイン クレメン) 36e9639e9cSValentin Clement (バレンタイン クレメン) // Convert FIR type to LLVM without turning fir.box<T> into memory 37e9639e9cSValentin Clement (バレンタイン クレメン) // reference. 38e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Type 39e9639e9cSValentin Clement (バレンタイン クレメン) ConvertFIRToLLVMPattern::convertObjectType(mlir::Type firType) const { 40fac349a1SChristian Sigg if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(firType)) 41e9639e9cSValentin Clement (バレンタイン クレメン) return lowerTy().convertBoxTypeAsStruct(boxTy); 42e9639e9cSValentin Clement (バレンタイン クレメン) return lowerTy().convertType(firType); 43e9639e9cSValentin Clement (バレンタイン クレメン) } 44e9639e9cSValentin Clement (バレンタイン クレメン) 45e9639e9cSValentin Clement (バレンタイン クレメン) mlir::LLVM::ConstantOp ConvertFIRToLLVMPattern::genI32Constant( 46e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Location loc, mlir::ConversionPatternRewriter &rewriter, 47e9639e9cSValentin Clement (バレンタイン クレメン) int value) const { 48e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Type i32Ty = rewriter.getI32Type(); 49e9639e9cSValentin Clement (バレンタイン クレメン) mlir::IntegerAttr attr = rewriter.getI32IntegerAttr(value); 50e9639e9cSValentin Clement (バレンタイン クレメン) return rewriter.create<mlir::LLVM::ConstantOp>(loc, i32Ty, attr); 51e9639e9cSValentin Clement (バレンタイン クレメン) } 52e9639e9cSValentin Clement (バレンタイン クレメン) 53e9639e9cSValentin Clement (バレンタイン クレメン) mlir::LLVM::ConstantOp ConvertFIRToLLVMPattern::genConstantOffset( 54e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Location loc, mlir::ConversionPatternRewriter &rewriter, 55e9639e9cSValentin Clement (バレンタイン クレメン) int offset) const { 56e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Type ity = lowerTy().offsetType(); 57e9639e9cSValentin Clement (バレンタイン クレメン) mlir::IntegerAttr cattr = rewriter.getI32IntegerAttr(offset); 58e9639e9cSValentin Clement (バレンタイン クレメン) return rewriter.create<mlir::LLVM::ConstantOp>(loc, ity, cattr); 59e9639e9cSValentin Clement (バレンタイン クレメン) } 60e9639e9cSValentin Clement (バレンタイン クレメン) 61e9639e9cSValentin Clement (バレンタイン クレメン) /// Perform an extension or truncation as needed on an integer value. Lowering 62e9639e9cSValentin Clement (バレンタイン クレメン) /// to the specific target may involve some sign-extending or truncation of 63e9639e9cSValentin Clement (バレンタイン クレメン) /// values, particularly to fit them from abstract box types to the 64e9639e9cSValentin Clement (バレンタイン クレメン) /// appropriate reified structures. 65c0cba519SVijay Kandiah mlir::Value ConvertFIRToLLVMPattern::integerCast( 66c0cba519SVijay Kandiah mlir::Location loc, mlir::ConversionPatternRewriter &rewriter, 67c0cba519SVijay Kandiah mlir::Type ty, mlir::Value val, bool fold) const { 68e9639e9cSValentin Clement (バレンタイン クレメン) auto valTy = val.getType(); 69e9639e9cSValentin Clement (バレンタイン クレメン) // If the value was not yet lowered, lower its type so that it can 70e9639e9cSValentin Clement (バレンタイン クレメン) // be used in getPrimitiveTypeSizeInBits. 71fac349a1SChristian Sigg if (!mlir::isa<mlir::IntegerType>(valTy)) 72e9639e9cSValentin Clement (バレンタイン クレメン) valTy = convertType(valTy); 73e9639e9cSValentin Clement (バレンタイン クレメン) auto toSize = mlir::LLVM::getPrimitiveTypeSizeInBits(ty); 74e9639e9cSValentin Clement (バレンタイン クレメン) auto fromSize = mlir::LLVM::getPrimitiveTypeSizeInBits(valTy); 75c0cba519SVijay Kandiah if (fold) { 76c0cba519SVijay Kandiah if (toSize < fromSize) 77c0cba519SVijay Kandiah return rewriter.createOrFold<mlir::LLVM::TruncOp>(loc, ty, val); 78c0cba519SVijay Kandiah if (toSize > fromSize) 79c0cba519SVijay Kandiah return rewriter.createOrFold<mlir::LLVM::SExtOp>(loc, ty, val); 80c0cba519SVijay Kandiah } else { 81e9639e9cSValentin Clement (バレンタイン クレメン) if (toSize < fromSize) 82e9639e9cSValentin Clement (バレンタイン クレメン) return rewriter.create<mlir::LLVM::TruncOp>(loc, ty, val); 83e9639e9cSValentin Clement (バレンタイン クレメン) if (toSize > fromSize) 84e9639e9cSValentin Clement (バレンタイン クレメン) return rewriter.create<mlir::LLVM::SExtOp>(loc, ty, val); 85c0cba519SVijay Kandiah } 86e9639e9cSValentin Clement (バレンタイン クレメン) return val; 87e9639e9cSValentin Clement (バレンタイン クレメン) } 88e9639e9cSValentin Clement (バレンタイン クレメン) 89e9639e9cSValentin Clement (バレンタイン クレメン) fir::ConvertFIRToLLVMPattern::TypePair 90e9639e9cSValentin Clement (バレンタイン クレメン) ConvertFIRToLLVMPattern::getBoxTypePair(mlir::Type firBoxTy) const { 91e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Type llvmBoxTy = 92e9639e9cSValentin Clement (バレンタイン クレメン) lowerTy().convertBoxTypeAsStruct(mlir::cast<fir::BaseBoxType>(firBoxTy)); 93e9639e9cSValentin Clement (バレンタイン クレメン) return TypePair{firBoxTy, llvmBoxTy}; 94e9639e9cSValentin Clement (バレンタイン クレメン) } 95e9639e9cSValentin Clement (バレンタイン クレメン) 96e9639e9cSValentin Clement (バレンタイン クレメン) /// Construct code sequence to extract the specific value from a `fir.box`. 97e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Value ConvertFIRToLLVMPattern::getValueFromBox( 98e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Location loc, TypePair boxTy, mlir::Value box, mlir::Type resultTy, 99e9639e9cSValentin Clement (バレンタイン クレメン) mlir::ConversionPatternRewriter &rewriter, int boxValue) const { 100fac349a1SChristian Sigg if (mlir::isa<mlir::LLVM::LLVMPointerType>(box.getType())) { 101e9639e9cSValentin Clement (バレンタイン クレメン) auto pty = getLlvmPtrType(resultTy.getContext()); 102e9639e9cSValentin Clement (バレンタイン クレメン) auto p = rewriter.create<mlir::LLVM::GEPOp>( 103e9639e9cSValentin Clement (バレンタイン クレメン) loc, pty, boxTy.llvm, box, 104e9639e9cSValentin Clement (バレンタイン クレメン) llvm::ArrayRef<mlir::LLVM::GEPArg>{0, boxValue}); 105ce2a3d90SKelvin Li auto fldTy = getBoxEleTy(boxTy.llvm, {boxValue}); 106ce2a3d90SKelvin Li auto loadOp = rewriter.create<mlir::LLVM::LoadOp>(loc, fldTy, p); 107ce2a3d90SKelvin Li auto castOp = integerCast(loc, rewriter, resultTy, loadOp); 108e9639e9cSValentin Clement (バレンタイン クレメン) attachTBAATag(loadOp, boxTy.fir, nullptr, p); 109ce2a3d90SKelvin Li return castOp; 110e9639e9cSValentin Clement (バレンタイン クレメン) } 111e9639e9cSValentin Clement (バレンタイン クレメン) return rewriter.create<mlir::LLVM::ExtractValueOp>(loc, box, boxValue); 112e9639e9cSValentin Clement (バレンタイン クレメン) } 113e9639e9cSValentin Clement (バレンタイン クレメン) 114e9639e9cSValentin Clement (バレンタイン クレメン) /// Method to construct code sequence to get the triple for dimension `dim` 115e9639e9cSValentin Clement (バレンタイン クレメン) /// from a box. 116e9639e9cSValentin Clement (バレンタイン クレメン) llvm::SmallVector<mlir::Value, 3> ConvertFIRToLLVMPattern::getDimsFromBox( 117e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Location loc, llvm::ArrayRef<mlir::Type> retTys, TypePair boxTy, 118e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Value box, mlir::Value dim, 119e9639e9cSValentin Clement (バレンタイン クレメン) mlir::ConversionPatternRewriter &rewriter) const { 120e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Value l0 = 121e9639e9cSValentin Clement (バレンタイン クレメン) loadDimFieldFromBox(loc, boxTy, box, dim, 0, retTys[0], rewriter); 122e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Value l1 = 123e9639e9cSValentin Clement (バレンタイン クレメン) loadDimFieldFromBox(loc, boxTy, box, dim, 1, retTys[1], rewriter); 124e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Value l2 = 125e9639e9cSValentin Clement (バレンタイン クレメン) loadDimFieldFromBox(loc, boxTy, box, dim, 2, retTys[2], rewriter); 126e9639e9cSValentin Clement (バレンタイン クレメン) return {l0, l1, l2}; 127e9639e9cSValentin Clement (バレンタイン クレメン) } 128e9639e9cSValentin Clement (バレンタイン クレメン) 129e9639e9cSValentin Clement (バレンタイン クレメン) llvm::SmallVector<mlir::Value, 3> ConvertFIRToLLVMPattern::getDimsFromBox( 130e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Location loc, llvm::ArrayRef<mlir::Type> retTys, TypePair boxTy, 131e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Value box, int dim, mlir::ConversionPatternRewriter &rewriter) const { 132e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Value l0 = 133e9639e9cSValentin Clement (バレンタイン クレメン) getDimFieldFromBox(loc, boxTy, box, dim, 0, retTys[0], rewriter); 134e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Value l1 = 135e9639e9cSValentin Clement (バレンタイン クレメン) getDimFieldFromBox(loc, boxTy, box, dim, 1, retTys[1], rewriter); 136e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Value l2 = 137e9639e9cSValentin Clement (バレンタイン クレメン) getDimFieldFromBox(loc, boxTy, box, dim, 2, retTys[2], rewriter); 138e9639e9cSValentin Clement (バレンタイン クレメン) return {l0, l1, l2}; 139e9639e9cSValentin Clement (バレンタイン クレメン) } 140e9639e9cSValentin Clement (バレンタイン クレメン) 141e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Value ConvertFIRToLLVMPattern::loadDimFieldFromBox( 142e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Location loc, TypePair boxTy, mlir::Value box, mlir::Value dim, 143e9639e9cSValentin Clement (バレンタイン クレメン) int off, mlir::Type ty, mlir::ConversionPatternRewriter &rewriter) const { 144fac349a1SChristian Sigg assert(mlir::isa<mlir::LLVM::LLVMPointerType>(box.getType()) && 145e9639e9cSValentin Clement (バレンタイン クレメン) "descriptor inquiry with runtime dim can only be done on descriptor " 146e9639e9cSValentin Clement (バレンタイン クレメン) "in memory"); 147e9639e9cSValentin Clement (バレンタイン クレメン) mlir::LLVM::GEPOp p = genGEP(loc, boxTy.llvm, rewriter, box, 0, 148e9639e9cSValentin Clement (バレンタイン クレメン) static_cast<int>(kDimsPosInBox), dim, off); 149e9639e9cSValentin Clement (バレンタイン クレメン) auto loadOp = rewriter.create<mlir::LLVM::LoadOp>(loc, ty, p); 150e9639e9cSValentin Clement (バレンタイン クレメン) attachTBAATag(loadOp, boxTy.fir, nullptr, p); 151e9639e9cSValentin Clement (バレンタイン クレメン) return loadOp; 152e9639e9cSValentin Clement (バレンタイン クレメン) } 153e9639e9cSValentin Clement (バレンタイン クレメン) 154e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Value ConvertFIRToLLVMPattern::getDimFieldFromBox( 155e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Location loc, TypePair boxTy, mlir::Value box, int dim, int off, 156e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Type ty, mlir::ConversionPatternRewriter &rewriter) const { 157fac349a1SChristian Sigg if (mlir::isa<mlir::LLVM::LLVMPointerType>(box.getType())) { 158e9639e9cSValentin Clement (バレンタイン クレメン) mlir::LLVM::GEPOp p = genGEP(loc, boxTy.llvm, rewriter, box, 0, 159e9639e9cSValentin Clement (バレンタイン クレメン) static_cast<int>(kDimsPosInBox), dim, off); 160e9639e9cSValentin Clement (バレンタイン クレメン) auto loadOp = rewriter.create<mlir::LLVM::LoadOp>(loc, ty, p); 161e9639e9cSValentin Clement (バレンタイン クレメン) attachTBAATag(loadOp, boxTy.fir, nullptr, p); 162e9639e9cSValentin Clement (バレンタイン クレメン) return loadOp; 163e9639e9cSValentin Clement (バレンタイン クレメン) } 164e9639e9cSValentin Clement (バレンタイン クレメン) return rewriter.create<mlir::LLVM::ExtractValueOp>( 165e9639e9cSValentin Clement (バレンタイン クレメン) loc, box, llvm::ArrayRef<std::int64_t>{kDimsPosInBox, dim, off}); 166e9639e9cSValentin Clement (バレンタイン クレメン) } 167e9639e9cSValentin Clement (バレンタイン クレメン) 168e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Value ConvertFIRToLLVMPattern::getStrideFromBox( 169e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Location loc, TypePair boxTy, mlir::Value box, unsigned dim, 170e9639e9cSValentin Clement (バレンタイン クレメン) mlir::ConversionPatternRewriter &rewriter) const { 171e9639e9cSValentin Clement (バレンタイン クレメン) auto idxTy = lowerTy().indexType(); 172e9639e9cSValentin Clement (バレンタイン クレメン) return getDimFieldFromBox(loc, boxTy, box, dim, kDimStridePos, idxTy, 173e9639e9cSValentin Clement (バレンタイン クレメン) rewriter); 174e9639e9cSValentin Clement (バレンタイン クレメン) } 175e9639e9cSValentin Clement (バレンタイン クレメン) 176e9639e9cSValentin Clement (バレンタイン クレメン) /// Read base address from a fir.box. Returned address has type ty. 177e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Value ConvertFIRToLLVMPattern::getBaseAddrFromBox( 178e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Location loc, TypePair boxTy, mlir::Value box, 179e9639e9cSValentin Clement (バレンタイン クレメン) mlir::ConversionPatternRewriter &rewriter) const { 180e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Type resultTy = ::getLlvmPtrType(boxTy.llvm.getContext()); 181e9639e9cSValentin Clement (バレンタイン クレメン) return getValueFromBox(loc, boxTy, box, resultTy, rewriter, kAddrPosInBox); 182e9639e9cSValentin Clement (バレンタイン クレメン) } 183e9639e9cSValentin Clement (バレンタイン クレメン) 184e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Value ConvertFIRToLLVMPattern::getElementSizeFromBox( 185e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Location loc, mlir::Type resultTy, TypePair boxTy, mlir::Value box, 186e9639e9cSValentin Clement (バレンタイン クレメン) mlir::ConversionPatternRewriter &rewriter) const { 187e9639e9cSValentin Clement (バレンタイン クレメン) return getValueFromBox(loc, boxTy, box, resultTy, rewriter, kElemLenPosInBox); 188e9639e9cSValentin Clement (バレンタイン クレメン) } 189e9639e9cSValentin Clement (バレンタイン クレメン) 19026e0ce0bSjeanPerier /// Read base address from a fir.box. Returned address has type ty. 19126e0ce0bSjeanPerier mlir::Value ConvertFIRToLLVMPattern::getRankFromBox( 19226e0ce0bSjeanPerier mlir::Location loc, TypePair boxTy, mlir::Value box, 19326e0ce0bSjeanPerier mlir::ConversionPatternRewriter &rewriter) const { 19426e0ce0bSjeanPerier mlir::Type resultTy = getBoxEleTy(boxTy.llvm, {kRankPosInBox}); 19526e0ce0bSjeanPerier return getValueFromBox(loc, boxTy, box, resultTy, rewriter, kRankPosInBox); 19626e0ce0bSjeanPerier } 19726e0ce0bSjeanPerier 198*15e1e3b2SValentin Clement (バレンタイン クレメン) /// Read the extra field from a fir.box. 199*15e1e3b2SValentin Clement (バレンタイン クレメン) mlir::Value ConvertFIRToLLVMPattern::getExtraFromBox( 200*15e1e3b2SValentin Clement (バレンタイン クレメン) mlir::Location loc, TypePair boxTy, mlir::Value box, 201*15e1e3b2SValentin Clement (バレンタイン クレメン) mlir::ConversionPatternRewriter &rewriter) const { 202*15e1e3b2SValentin Clement (バレンタイン クレメン) mlir::Type resultTy = getBoxEleTy(boxTy.llvm, {kExtraPosInBox}); 203*15e1e3b2SValentin Clement (バレンタイン クレメン) return getValueFromBox(loc, boxTy, box, resultTy, rewriter, kExtraPosInBox); 204*15e1e3b2SValentin Clement (バレンタイン クレメン) } 205*15e1e3b2SValentin Clement (バレンタイン クレメン) 206e9639e9cSValentin Clement (バレンタイン クレメン) // Get the element type given an LLVM type that is of the form 207e9639e9cSValentin Clement (バレンタイン クレメン) // (array|struct|vector)+ and the provided indexes. 208e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Type ConvertFIRToLLVMPattern::getBoxEleTy( 209e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Type type, llvm::ArrayRef<std::int64_t> indexes) const { 210e9639e9cSValentin Clement (バレンタイン クレメン) for (unsigned i : indexes) { 211fac349a1SChristian Sigg if (auto t = mlir::dyn_cast<mlir::LLVM::LLVMStructType>(type)) { 212e9639e9cSValentin Clement (バレンタイン クレメン) assert(!t.isOpaque() && i < t.getBody().size()); 213e9639e9cSValentin Clement (バレンタイン クレメン) type = t.getBody()[i]; 214fac349a1SChristian Sigg } else if (auto t = mlir::dyn_cast<mlir::LLVM::LLVMArrayType>(type)) { 215e9639e9cSValentin Clement (バレンタイン クレメン) type = t.getElementType(); 216fac349a1SChristian Sigg } else if (auto t = mlir::dyn_cast<mlir::VectorType>(type)) { 217e9639e9cSValentin Clement (バレンタイン クレメン) type = t.getElementType(); 218e9639e9cSValentin Clement (バレンタイン クレメン) } else { 219e9639e9cSValentin Clement (バレンタイン クレメン) fir::emitFatalError(mlir::UnknownLoc::get(type.getContext()), 220e9639e9cSValentin Clement (バレンタイン クレメン) "request for invalid box element type"); 221e9639e9cSValentin Clement (バレンタイン クレメン) } 222e9639e9cSValentin Clement (バレンタイン クレメン) } 223e9639e9cSValentin Clement (バレンタイン クレメン) return type; 224e9639e9cSValentin Clement (バレンタイン クレメン) } 225e9639e9cSValentin Clement (バレンタイン クレメン) 226e9639e9cSValentin Clement (バレンタイン クレメン) // Return LLVM type of the object described by a fir.box of \p boxType. 227e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Type ConvertFIRToLLVMPattern::getLlvmObjectTypeFromBoxType( 228e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Type boxType) const { 229e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Type objectType = fir::dyn_cast_ptrOrBoxEleTy(boxType); 230e9639e9cSValentin Clement (バレンタイン クレメン) assert(objectType && "boxType must be a box type"); 231e9639e9cSValentin Clement (バレンタイン クレメン) return this->convertType(objectType); 232e9639e9cSValentin Clement (バレンタイン クレメン) } 233e9639e9cSValentin Clement (バレンタイン クレメン) 234e9639e9cSValentin Clement (バレンタイン クレメン) /// Read the address of the type descriptor from a box. 235e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Value ConvertFIRToLLVMPattern::loadTypeDescAddress( 236e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Location loc, TypePair boxTy, mlir::Value box, 237e9639e9cSValentin Clement (バレンタイン クレメン) mlir::ConversionPatternRewriter &rewriter) const { 238e9639e9cSValentin Clement (バレンタイン クレメン) unsigned typeDescFieldId = getTypeDescFieldId(boxTy.fir); 239e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Type tdescType = lowerTy().convertTypeDescType(rewriter.getContext()); 240e9639e9cSValentin Clement (バレンタイン クレメン) return getValueFromBox(loc, boxTy, box, tdescType, rewriter, typeDescFieldId); 241e9639e9cSValentin Clement (バレンタイン クレメン) } 242e9639e9cSValentin Clement (バレンタイン クレメン) 243e9639e9cSValentin Clement (バレンタイン クレメン) // Load the attribute from the \p box and perform a check against \p maskValue 244e9639e9cSValentin Clement (バレンタイン クレメン) // The final comparison is implemented as `(attribute & maskValue) != 0`. 245e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Value ConvertFIRToLLVMPattern::genBoxAttributeCheck( 246e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Location loc, TypePair boxTy, mlir::Value box, 247e9639e9cSValentin Clement (バレンタイン クレメン) mlir::ConversionPatternRewriter &rewriter, unsigned maskValue) const { 248e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Type attrTy = rewriter.getI32Type(); 249e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Value attribute = 250e9639e9cSValentin Clement (バレンタイン クレメン) getValueFromBox(loc, boxTy, box, attrTy, rewriter, kAttributePosInBox); 251e9639e9cSValentin Clement (バレンタイン クレメン) mlir::LLVM::ConstantOp attrMask = genConstantOffset(loc, rewriter, maskValue); 252e9639e9cSValentin Clement (バレンタイン クレメン) auto maskRes = 253e9639e9cSValentin Clement (バレンタイン クレメン) rewriter.create<mlir::LLVM::AndOp>(loc, attrTy, attribute, attrMask); 254e9639e9cSValentin Clement (バレンタイン クレメン) mlir::LLVM::ConstantOp c0 = genConstantOffset(loc, rewriter, 0); 255e9639e9cSValentin Clement (バレンタイン クレメン) return rewriter.create<mlir::LLVM::ICmpOp>(loc, mlir::LLVM::ICmpPredicate::ne, 256e9639e9cSValentin Clement (バレンタイン クレメン) maskRes, c0); 257e9639e9cSValentin Clement (バレンタイン クレメン) } 258e9639e9cSValentin Clement (バレンタイン クレメン) 259e398383fSjeanPerier mlir::Value ConvertFIRToLLVMPattern::computeBoxSize( 260e398383fSjeanPerier mlir::Location loc, TypePair boxTy, mlir::Value box, 261e398383fSjeanPerier mlir::ConversionPatternRewriter &rewriter) const { 262e398383fSjeanPerier auto firBoxType = mlir::dyn_cast<fir::BaseBoxType>(boxTy.fir); 263e398383fSjeanPerier assert(firBoxType && "must be a BaseBoxType"); 264e398383fSjeanPerier const mlir::DataLayout &dl = lowerTy().getDataLayout(); 265e398383fSjeanPerier if (!firBoxType.isAssumedRank()) 266e398383fSjeanPerier return genConstantOffset(loc, rewriter, dl.getTypeSize(boxTy.llvm)); 267e398383fSjeanPerier fir::BaseBoxType firScalarBoxType = firBoxType.getBoxTypeWithNewShape(0); 268e398383fSjeanPerier mlir::Type llvmScalarBoxType = 269e398383fSjeanPerier lowerTy().convertBoxTypeAsStruct(firScalarBoxType); 270e398383fSjeanPerier llvm::TypeSize scalarBoxSizeCst = dl.getTypeSize(llvmScalarBoxType); 271e398383fSjeanPerier mlir::Value scalarBoxSize = 272e398383fSjeanPerier genConstantOffset(loc, rewriter, scalarBoxSizeCst); 273e398383fSjeanPerier mlir::Value rawRank = getRankFromBox(loc, boxTy, box, rewriter); 274e398383fSjeanPerier mlir::Value rank = 275e398383fSjeanPerier integerCast(loc, rewriter, scalarBoxSize.getType(), rawRank); 276e398383fSjeanPerier mlir::Type llvmDimsType = getBoxEleTy(boxTy.llvm, {kDimsPosInBox, 1}); 277e398383fSjeanPerier llvm::TypeSize sizePerDimCst = dl.getTypeSize(llvmDimsType); 278e398383fSjeanPerier assert((scalarBoxSizeCst + sizePerDimCst == 279e398383fSjeanPerier dl.getTypeSize(lowerTy().convertBoxTypeAsStruct( 280e398383fSjeanPerier firBoxType.getBoxTypeWithNewShape(1)))) && 281e398383fSjeanPerier "descriptor layout requires adding padding for dim field"); 282e398383fSjeanPerier mlir::Value sizePerDim = genConstantOffset(loc, rewriter, sizePerDimCst); 283e398383fSjeanPerier mlir::Value dimsSize = rewriter.create<mlir::LLVM::MulOp>( 284e398383fSjeanPerier loc, sizePerDim.getType(), sizePerDim, rank); 285e398383fSjeanPerier mlir::Value size = rewriter.create<mlir::LLVM::AddOp>( 286e398383fSjeanPerier loc, scalarBoxSize.getType(), scalarBoxSize, dimsSize); 287e398383fSjeanPerier return size; 288e398383fSjeanPerier } 289e398383fSjeanPerier 290e9639e9cSValentin Clement (バレンタイン クレメン) // Find the Block in which the alloca should be inserted. 291e9639e9cSValentin Clement (バレンタイン クレメン) // The order to recursively find the proper block: 292e9639e9cSValentin Clement (バレンタイン クレメン) // 1. An OpenMP Op that will be outlined. 293c0cba519SVijay Kandiah // 2. An OpenMP or OpenACC Op with one or more regions holding executable code. 294c0cba519SVijay Kandiah // 3. A LLVMFuncOp 295c0cba519SVijay Kandiah // 4. The first ancestor that is one of the above. 296c0cba519SVijay Kandiah mlir::Block *ConvertFIRToLLVMPattern::getBlockForAllocaInsert( 297c0cba519SVijay Kandiah mlir::Operation *op, mlir::Region *parentRegion) const { 298e9639e9cSValentin Clement (バレンタイン クレメン) if (auto iface = mlir::dyn_cast<mlir::omp::OutlineableOpenMPOpInterface>(op)) 299e9639e9cSValentin Clement (バレンタイン クレメン) return iface.getAllocaBlock(); 300c0cba519SVijay Kandiah if (auto recipeIface = mlir::dyn_cast<mlir::accomp::RecipeInterface>(op)) 301c0cba519SVijay Kandiah return recipeIface.getAllocaBlock(*parentRegion); 302e9639e9cSValentin Clement (バレンタイン クレメン) if (auto llvmFuncOp = mlir::dyn_cast<mlir::LLVM::LLVMFuncOp>(op)) 303e9639e9cSValentin Clement (バレンタイン クレメン) return &llvmFuncOp.front(); 3043785d742SKareem Ergawy 305c0cba519SVijay Kandiah return getBlockForAllocaInsert(op->getParentOp(), parentRegion); 306e9639e9cSValentin Clement (バレンタイン クレメン) } 307e9639e9cSValentin Clement (バレンタイン クレメン) 308e9639e9cSValentin Clement (バレンタイン クレメン) // Generate an alloca of size 1 for an object of type \p llvmObjectTy in the 309e9639e9cSValentin Clement (バレンタイン クレメン) // allocation address space provided for the architecture in the DataLayout 310e9639e9cSValentin Clement (バレンタイン クレメン) // specification. If the address space is different from the devices 311e9639e9cSValentin Clement (バレンタイン クレメン) // program address space we perform a cast. In the case of most architectures 312e9639e9cSValentin Clement (バレンタイン クレメン) // the program and allocation address space will be the default of 0 and no 313e9639e9cSValentin Clement (バレンタイン クレメン) // cast will be emitted. 314e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Value ConvertFIRToLLVMPattern::genAllocaAndAddrCastWithType( 315e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Location loc, mlir::Type llvmObjectTy, unsigned alignment, 316e9639e9cSValentin Clement (バレンタイン クレメン) mlir::ConversionPatternRewriter &rewriter) const { 317e9639e9cSValentin Clement (バレンタイン クレメン) auto thisPt = rewriter.saveInsertionPoint(); 318e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Operation *parentOp = rewriter.getInsertionBlock()->getParentOp(); 319e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Region *parentRegion = rewriter.getInsertionBlock()->getParent(); 320c0cba519SVijay Kandiah mlir::Block *insertBlock = getBlockForAllocaInsert(parentOp, parentRegion); 321e9639e9cSValentin Clement (バレンタイン クレメン) rewriter.setInsertionPointToStart(insertBlock); 322e9639e9cSValentin Clement (バレンタイン クレメン) auto size = genI32Constant(loc, rewriter, 1); 323e9639e9cSValentin Clement (バレンタイン クレメン) unsigned allocaAs = getAllocaAddressSpace(rewriter); 324e9639e9cSValentin Clement (バレンタイン クレメン) unsigned programAs = getProgramAddressSpace(rewriter); 325e9639e9cSValentin Clement (バレンタイン クレメン) 326e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Value al = rewriter.create<mlir::LLVM::AllocaOp>( 327e9639e9cSValentin Clement (バレンタイン クレメン) loc, ::getLlvmPtrType(llvmObjectTy.getContext(), allocaAs), llvmObjectTy, 328e9639e9cSValentin Clement (バレンタイン クレメン) size, alignment); 329e9639e9cSValentin Clement (バレンタイン クレメン) 330e9639e9cSValentin Clement (バレンタイン クレメン) // if our allocation address space, is not the same as the program address 331e9639e9cSValentin Clement (バレンタイン クレメン) // space, then we must emit a cast to the program address space before use. 332e9639e9cSValentin Clement (バレンタイン クレメン) // An example case would be on AMDGPU, where the allocation address space is 333e9639e9cSValentin Clement (バレンタイン クレメン) // the numeric value 5 (private), and the program address space is 0 334e9639e9cSValentin Clement (バレンタイン クレメン) // (generic). 335e9639e9cSValentin Clement (バレンタイン クレメン) if (allocaAs != programAs) { 336e9639e9cSValentin Clement (バレンタイン クレメン) al = rewriter.create<mlir::LLVM::AddrSpaceCastOp>( 337e9639e9cSValentin Clement (バレンタイン クレメン) loc, ::getLlvmPtrType(llvmObjectTy.getContext(), programAs), al); 338e9639e9cSValentin Clement (バレンタイン クレメン) } 339e9639e9cSValentin Clement (バレンタイン クレメン) 340e9639e9cSValentin Clement (バレンタイン クレメン) rewriter.restoreInsertionPoint(thisPt); 341e9639e9cSValentin Clement (バレンタイン クレメン) return al; 342e9639e9cSValentin Clement (バレンタイン クレメン) } 343e9639e9cSValentin Clement (バレンタイン クレメン) 344e9639e9cSValentin Clement (バレンタイン クレメン) unsigned ConvertFIRToLLVMPattern::getAllocaAddressSpace( 345e9639e9cSValentin Clement (バレンタイン クレメン) mlir::ConversionPatternRewriter &rewriter) const { 346e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Operation *parentOp = rewriter.getInsertionBlock()->getParentOp(); 347e9639e9cSValentin Clement (バレンタイン クレメン) assert(parentOp != nullptr && 348e9639e9cSValentin Clement (バレンタイン クレメン) "expected insertion block to have parent operation"); 349e9639e9cSValentin Clement (バレンタイン クレメン) if (auto module = parentOp->getParentOfType<mlir::ModuleOp>()) 350e9639e9cSValentin Clement (バレンタイン クレメン) if (mlir::Attribute addrSpace = 351e9639e9cSValentin Clement (バレンタイン クレメン) mlir::DataLayout(module).getAllocaMemorySpace()) 352e9639e9cSValentin Clement (バレンタイン クレメン) return llvm::cast<mlir::IntegerAttr>(addrSpace).getUInt(); 353e9639e9cSValentin Clement (バレンタイン クレメン) return defaultAddressSpace; 354e9639e9cSValentin Clement (バレンタイン クレメン) } 355e9639e9cSValentin Clement (バレンタイン クレメン) 356e9639e9cSValentin Clement (バレンタイン クレメン) unsigned ConvertFIRToLLVMPattern::getProgramAddressSpace( 357e9639e9cSValentin Clement (バレンタイン クレメン) mlir::ConversionPatternRewriter &rewriter) const { 358e9639e9cSValentin Clement (バレンタイン クレメン) mlir::Operation *parentOp = rewriter.getInsertionBlock()->getParentOp(); 359e9639e9cSValentin Clement (バレンタイン クレメン) assert(parentOp != nullptr && 360e9639e9cSValentin Clement (バレンタイン クレメン) "expected insertion block to have parent operation"); 361e9639e9cSValentin Clement (バレンタイン クレメン) if (auto module = parentOp->getParentOfType<mlir::ModuleOp>()) 362e9639e9cSValentin Clement (バレンタイン クレメン) if (mlir::Attribute addrSpace = 363e9639e9cSValentin Clement (バレンタイン クレメン) mlir::DataLayout(module).getProgramMemorySpace()) 364e9639e9cSValentin Clement (バレンタイン クレメン) return llvm::cast<mlir::IntegerAttr>(addrSpace).getUInt(); 365e9639e9cSValentin Clement (バレンタイン クレメン) return defaultAddressSpace; 366e9639e9cSValentin Clement (バレンタイン クレメン) } 367e9639e9cSValentin Clement (バレンタイン クレメン) 368e9639e9cSValentin Clement (バレンタイン クレメン) } // namespace fir 369