brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.8 KiB · 1b1abef Raw
240 lines · cpp
1//===-- HLFIRDialect.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/HLFIR/HLFIRDialect.h"14#include "flang/Optimizer/Dialect/FIROps.h"15#include "flang/Optimizer/Dialect/FIRType.h"16#include "flang/Optimizer/HLFIR/HLFIROps.h"17#include "mlir/Dialect/Arith/IR/Arith.h"18#include "mlir/IR/Builders.h"19#include "mlir/IR/BuiltinTypes.h"20#include "mlir/IR/DialectImplementation.h"21#include "mlir/IR/Matchers.h"22#include "mlir/IR/OpImplementation.h"23#include "llvm/ADT/SmallVector.h"24#include "llvm/ADT/TypeSwitch.h"25 26#include "flang/Optimizer/HLFIR/HLFIRDialect.cpp.inc"27 28#define GET_TYPEDEF_CLASSES29#include "flang/Optimizer/HLFIR/HLFIRTypes.cpp.inc"30 31#define GET_ATTRDEF_CLASSES32#include "flang/Optimizer/HLFIR/HLFIRAttributes.cpp.inc"33 34void hlfir::hlfirDialect::initialize() {35  addTypes<36#define GET_TYPEDEF_LIST37#include "flang/Optimizer/HLFIR/HLFIRTypes.cpp.inc"38      >();39  addOperations<40#define GET_OP_LIST41#include "flang/Optimizer/HLFIR/HLFIROps.cpp.inc"42      >();43}44 45// `expr` `<` `*` | bounds (`x` bounds)* `:` type [`?`] `>`46// bounds ::= `?` | int-lit47mlir::Type hlfir::ExprType::parse(mlir::AsmParser &parser) {48  if (parser.parseLess())49    return {};50  ExprType::Shape shape;51  if (parser.parseOptionalStar()) {52    if (parser.parseDimensionList(shape, /*allowDynamic=*/true))53      return {};54  } else if (parser.parseColon()) {55    return {};56  }57  mlir::Type eleTy;58  if (parser.parseType(eleTy))59    return {};60  const bool polymorphic = mlir::succeeded(parser.parseOptionalQuestion());61  if (parser.parseGreater())62    return {};63  return ExprType::get(parser.getContext(), shape, eleTy, polymorphic);64}65 66void hlfir::ExprType::print(mlir::AsmPrinter &printer) const {67  auto shape = getShape();68  printer << '<';69  if (shape.size()) {70    for (const auto &b : shape) {71      if (b >= 0)72        printer << b << 'x';73      else74        printer << "?x";75    }76  }77  printer << getEleTy();78  if (isPolymorphic())79    printer << '?';80  printer << '>';81}82 83bool hlfir::isFortranVariableType(mlir::Type type) {84  return llvm::TypeSwitch<mlir::Type, bool>(type)85      .Case<fir::ReferenceType, fir::PointerType, fir::HeapType>([](auto p) {86        mlir::Type eleType = p.getEleTy();87        return mlir::isa<fir::BaseBoxType>(eleType) ||88               !fir::hasDynamicSize(eleType);89      })90      .Case<fir::BaseBoxType, fir::BoxCharType>([](auto) { return true; })91      .Case<fir::VectorType>([](auto) { return true; })92      .Default([](mlir::Type) { return false; });93}94 95bool hlfir::isFortranScalarCharacterType(mlir::Type type) {96  return isFortranScalarCharacterExprType(type) ||97         mlir::isa<fir::BoxCharType>(type) ||98         mlir::isa<fir::CharacterType>(99             fir::unwrapPassByRefType(fir::unwrapRefType(type)));100}101 102bool hlfir::isFortranScalarCharacterExprType(mlir::Type type) {103  if (auto exprType = mlir::dyn_cast<hlfir::ExprType>(type))104    return exprType.isScalar() &&105           mlir::isa<fir::CharacterType>(exprType.getElementType());106  return false;107}108 109bool hlfir::isFortranArrayCharacterExprType(mlir::Type type) {110  if (auto exprType = mlir::dyn_cast<hlfir::ExprType>(type))111    return exprType.isArray() &&112           mlir::isa<fir::CharacterType>(exprType.getElementType());113 114  return false;115}116 117bool hlfir::isFortranScalarNumericalType(mlir::Type type) {118  return fir::isa_integer(type) || fir::isa_real(type) ||119         fir::isa_complex(type);120}121 122bool hlfir::isFortranNumericalArrayObject(mlir::Type type) {123  if (isBoxAddressType(type))124    return false;125  if (auto arrayTy = mlir::dyn_cast<fir::SequenceType>(126          getFortranElementOrSequenceType(type)))127    return isFortranScalarNumericalType(arrayTy.getEleTy());128  return false;129}130 131bool hlfir::isFortranNumericalOrLogicalArrayObject(mlir::Type type) {132  if (isBoxAddressType(type))133    return false;134  if (auto arrayTy = mlir::dyn_cast<fir::SequenceType>(135          getFortranElementOrSequenceType(type))) {136    mlir::Type eleTy = arrayTy.getEleTy();137    return isFortranScalarNumericalType(eleTy) ||138           mlir::isa<fir::LogicalType>(eleTy);139  }140  return false;141}142 143bool hlfir::isFortranArrayObject(mlir::Type type) {144  if (isBoxAddressType(type))145    return false;146  return !!mlir::dyn_cast<fir::SequenceType>(147      getFortranElementOrSequenceType(type));148}149 150bool hlfir::isPassByRefOrIntegerType(mlir::Type type) {151  mlir::Type unwrappedType = fir::unwrapPassByRefType(type);152  return fir::isa_integer(unwrappedType);153}154 155bool hlfir::isI1Type(mlir::Type type) {156  if (mlir::IntegerType integer = mlir::dyn_cast<mlir::IntegerType>(type))157    if (integer.getWidth() == 1)158      return true;159  return false;160}161 162bool hlfir::isFortranLogicalArrayObject(mlir::Type type) {163  if (isBoxAddressType(type))164    return false;165  if (auto arrayTy = mlir::dyn_cast<fir::SequenceType>(166          getFortranElementOrSequenceType(type))) {167    mlir::Type eleTy = arrayTy.getEleTy();168    return mlir::isa<fir::LogicalType>(eleTy);169  }170  return false;171}172 173bool hlfir::isMaskArgument(mlir::Type type) {174  if (isBoxAddressType(type))175    return false;176 177  mlir::Type unwrappedType = fir::unwrapPassByRefType(fir::unwrapRefType(type));178  mlir::Type elementType = getFortranElementType(unwrappedType);179  if (unwrappedType != elementType)180    // input type is an array181    return mlir::isa<fir::LogicalType>(elementType);182 183  // input is a scalar, so allow i1 too184  return mlir::isa<fir::LogicalType>(elementType) || isI1Type(elementType);185}186 187bool hlfir::isPolymorphicObject(mlir::Type type) {188  if (auto exprType = mlir::dyn_cast<hlfir::ExprType>(type))189    return exprType.isPolymorphic();190 191  return fir::isPolymorphicType(type);192}193 194mlir::Value hlfir::genExprShape(mlir::OpBuilder &builder,195                                const mlir::Location &loc,196                                const hlfir::ExprType &expr) {197  mlir::IndexType indexTy = builder.getIndexType();198  llvm::SmallVector<mlir::Value> extents;199  extents.reserve(expr.getRank());200 201  for (std::int64_t extent : expr.getShape()) {202    if (extent == hlfir::ExprType::getUnknownExtent())203      return {};204    extents.emplace_back(mlir::arith::ConstantOp::create(205        builder, loc, indexTy, builder.getIntegerAttr(indexTy, extent)));206  }207 208  fir::ShapeType shapeTy =209      fir::ShapeType::get(builder.getContext(), expr.getRank());210  fir::ShapeOp shape = fir::ShapeOp::create(builder, loc, shapeTy, extents);211  return shape.getResult();212}213 214bool hlfir::mayHaveAllocatableComponent(mlir::Type ty) {215  return fir::isPolymorphicType(ty) || fir::isUnlimitedPolymorphicType(ty) ||216         fir::isRecordWithAllocatableMember(hlfir::getFortranElementType(ty));217}218 219mlir::Type hlfir::getExprType(mlir::Type variableType) {220  hlfir::ExprType::Shape typeShape;221  bool isPolymorphic = fir::isPolymorphicType(variableType);222  mlir::Type type = getFortranElementOrSequenceType(variableType);223  if (auto seqType = mlir::dyn_cast<fir::SequenceType>(type)) {224    assert(!seqType.hasUnknownShape() && "assumed-rank cannot be expressions");225    typeShape.append(seqType.getShape().begin(), seqType.getShape().end());226    type = seqType.getEleTy();227  }228  return hlfir::ExprType::get(variableType.getContext(), typeShape, type,229                              isPolymorphic);230}231 232bool hlfir::isFortranIntegerScalarOrArrayObject(mlir::Type type) {233  if (isBoxAddressType(type))234    return false;235 236  mlir::Type unwrappedType = fir::unwrapPassByRefType(fir::unwrapRefType(type));237  mlir::Type elementType = getFortranElementType(unwrappedType);238  return mlir::isa<mlir::IntegerType>(elementType);239}240