134 lines · cpp
1//===-- Utils.cpp ---------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/10//11//===----------------------------------------------------------------------===//12 13#include "flang/Optimizer/Support/Utils.h"14#include "flang/Optimizer/Dialect/FIROps.h"15#include "flang/Optimizer/Dialect/FIRType.h"16#include "flang/Optimizer/Support/InternalNames.h"17 18fir::TypeInfoOp fir::lookupTypeInfoOp(fir::RecordType recordType,19 mlir::ModuleOp module,20 const mlir::SymbolTable *symbolTable) {21 // fir.type_info was created with the mangled name of the derived type.22 // It is the same as the name in the related fir.type, except when a pass23 // lowered the fir.type (e.g., when lowering fir.boxproc type if the type has24 // pointer procedure components), in which case suffix may have been added to25 // the fir.type name. Get rid of them when looking up for the fir.type_info.26 llvm::StringRef originalMangledTypeName =27 fir::NameUniquer::dropTypeConversionMarkers(recordType.getName());28 return fir::lookupTypeInfoOp(originalMangledTypeName, module, symbolTable);29}30 31fir::TypeInfoOp fir::lookupTypeInfoOp(llvm::StringRef name,32 mlir::ModuleOp module,33 const mlir::SymbolTable *symbolTable) {34 if (symbolTable)35 if (auto typeInfo = symbolTable->lookup<fir::TypeInfoOp>(name))36 return typeInfo;37 return module.lookupSymbol<fir::TypeInfoOp>(name);38}39 40std::optional<llvm::ArrayRef<int64_t>> fir::getComponentLowerBoundsIfNonDefault(41 fir::RecordType recordType, llvm::StringRef component,42 mlir::ModuleOp module, const mlir::SymbolTable *symbolTable) {43 fir::TypeInfoOp typeInfo =44 fir::lookupTypeInfoOp(recordType, module, symbolTable);45 if (!typeInfo || typeInfo.getComponentInfo().empty())46 return std::nullopt;47 for (auto componentInfo :48 typeInfo.getComponentInfo().getOps<fir::DTComponentOp>())49 if (componentInfo.getName() == component)50 return componentInfo.getLowerBounds();51 return std::nullopt;52}53 54std::optional<bool>55fir::isRecordWithFinalRoutine(fir::RecordType recordType, mlir::ModuleOp module,56 const mlir::SymbolTable *symbolTable) {57 fir::TypeInfoOp typeInfo =58 fir::lookupTypeInfoOp(recordType, module, symbolTable);59 if (!typeInfo)60 return std::nullopt;61 return !typeInfo.getNoFinal();62}63 64mlir::LLVM::ConstantOp65fir::genConstantIndex(mlir::Location loc, mlir::Type ity,66 mlir::ConversionPatternRewriter &rewriter,67 std::int64_t offset) {68 auto cattr = rewriter.getI64IntegerAttr(offset);69 return mlir::LLVM::ConstantOp::create(rewriter, loc, ity, cattr);70}71 72mlir::Value73fir::computeElementDistance(mlir::Location loc, mlir::Type llvmObjectType,74 mlir::Type idxTy,75 mlir::ConversionPatternRewriter &rewriter,76 const mlir::DataLayout &dataLayout) {77 llvm::TypeSize size = dataLayout.getTypeSize(llvmObjectType);78 unsigned short alignment = dataLayout.getTypeABIAlignment(llvmObjectType);79 std::int64_t distance = llvm::alignTo(size, alignment);80 return fir::genConstantIndex(loc, idxTy, rewriter, distance);81}82 83mlir::Value84fir::genAllocationScaleSize(mlir::Location loc, mlir::Type dataTy,85 mlir::Type ity,86 mlir::ConversionPatternRewriter &rewriter) {87 auto seqTy = mlir::dyn_cast<fir::SequenceType>(dataTy);88 fir::SequenceType::Extent constSize = 1;89 if (seqTy) {90 int constRows = seqTy.getConstantRows();91 const fir::SequenceType::ShapeRef &shape = seqTy.getShape();92 if (constRows != static_cast<int>(shape.size())) {93 for (auto extent : shape) {94 if (constRows-- > 0)95 continue;96 if (extent != fir::SequenceType::getUnknownExtent())97 constSize *= extent;98 }99 }100 }101 102 if (constSize != 1) {103 mlir::Value constVal{104 fir::genConstantIndex(loc, ity, rewriter, constSize).getResult()};105 return constVal;106 }107 return nullptr;108}109 110mlir::Value fir::integerCast(const fir::LLVMTypeConverter &converter,111 mlir::Location loc,112 mlir::ConversionPatternRewriter &rewriter,113 mlir::Type ty, mlir::Value val, bool fold) {114 auto valTy = val.getType();115 // If the value was not yet lowered, lower its type so that it can116 // be used in getPrimitiveTypeSizeInBits.117 if (!mlir::isa<mlir::IntegerType>(valTy))118 valTy = converter.convertType(valTy);119 auto toSize = mlir::LLVM::getPrimitiveTypeSizeInBits(ty);120 auto fromSize = mlir::LLVM::getPrimitiveTypeSizeInBits(valTy);121 if (fold) {122 if (toSize < fromSize)123 return rewriter.createOrFold<mlir::LLVM::TruncOp>(loc, ty, val);124 if (toSize > fromSize)125 return rewriter.createOrFold<mlir::LLVM::SExtOp>(loc, ty, val);126 } else {127 if (toSize < fromSize)128 return mlir::LLVM::TruncOp::create(rewriter, loc, ty, val);129 if (toSize > fromSize)130 return mlir::LLVM::SExtOp::create(rewriter, loc, ty, val);131 }132 return val;133}134