brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.4 KiB · 4c7b228 Raw
161 lines · cpp
1//===-- AssumedRankOpConversion.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#include "flang/Lower/BuiltinModules.h"10#include "flang/Optimizer/Builder/FIRBuilder.h"11#include "flang/Optimizer/Builder/Runtime/Support.h"12#include "flang/Optimizer/Builder/Todo.h"13#include "flang/Optimizer/Dialect/FIRDialect.h"14#include "flang/Optimizer/Dialect/FIROps.h"15#include "flang/Optimizer/Support/TypeCode.h"16#include "flang/Optimizer/Support/Utils.h"17#include "flang/Optimizer/Transforms/Passes.h"18#include "flang/Runtime/support.h"19#include "flang/Support/Fortran.h"20#include "mlir/Dialect/Func/IR/FuncOps.h"21#include "mlir/Pass/Pass.h"22#include "mlir/Transforms/DialectConversion.h"23#include "mlir/Transforms/GreedyPatternRewriteDriver.h"24 25namespace fir {26#define GEN_PASS_DEF_ASSUMEDRANKOPCONVERSION27#include "flang/Optimizer/Transforms/Passes.h.inc"28} // namespace fir29 30using namespace fir;31using namespace mlir;32 33namespace {34 35static int getCFIAttribute(mlir::Type boxType) {36  if (fir::isAllocatableType(boxType))37    return CFI_attribute_allocatable;38  if (fir::isPointerType(boxType))39    return CFI_attribute_pointer;40  return CFI_attribute_other;41}42 43static Fortran::runtime::LowerBoundModifier44getLowerBoundModifier(fir::LowerBoundModifierAttribute modifier) {45  switch (modifier) {46  case fir::LowerBoundModifierAttribute::Preserve:47    return Fortran::runtime::LowerBoundModifier::Preserve;48  case fir::LowerBoundModifierAttribute::SetToOnes:49    return Fortran::runtime::LowerBoundModifier::SetToOnes;50  case fir::LowerBoundModifierAttribute::SetToZeroes:51    return Fortran::runtime::LowerBoundModifier::SetToZeroes;52  }53  llvm_unreachable("bad modifier code");54}55 56class ReboxAssumedRankConv57    : public mlir::OpRewritePattern<fir::ReboxAssumedRankOp> {58public:59  using OpRewritePattern::OpRewritePattern;60 61  ReboxAssumedRankConv(mlir::MLIRContext *context,62                       mlir::SymbolTable *symbolTable, fir::KindMapping kindMap)63      : mlir::OpRewritePattern<fir::ReboxAssumedRankOp>(context),64        symbolTable{symbolTable}, kindMap{kindMap} {};65 66  llvm::LogicalResult67  matchAndRewrite(fir::ReboxAssumedRankOp rebox,68                  mlir::PatternRewriter &rewriter) const override {69    fir::FirOpBuilder builder{rewriter, kindMap, symbolTable};70    mlir::Location loc = rebox.getLoc();71    auto newBoxType = mlir::cast<fir::BaseBoxType>(rebox.getType());72    mlir::Type newMaxRankBoxType =73        newBoxType.getBoxTypeWithNewShape(Fortran::common::maxRank);74    // CopyAndUpdateDescriptor FIR interface requires loading75    // !fir.ref<fir.box> input which is expensive with assumed-rank. It could76    // be best to add an entry point that takes a non "const" from to cover77    // this case, but it would be good to indicate to LLVM that from does not78    // get modified.79    if (fir::isBoxAddress(rebox.getBox().getType()))80      TODO(loc, "fir.rebox_assumed_rank codegen with fir.ref<fir.box<>> input");81    mlir::Value tempDesc = builder.createTemporary(loc, newMaxRankBoxType);82    mlir::Value newDtype;83    mlir::Type newEleType = newBoxType.unwrapInnerType();84    auto oldBoxType = mlir::cast<fir::BaseBoxType>(85        fir::unwrapRefType(rebox.getBox().getType()));86    auto newDerivedType = mlir::dyn_cast<fir::RecordType>(newEleType);87    if (newDerivedType && !fir::isPolymorphicType(newBoxType) &&88        (fir::isPolymorphicType(oldBoxType) ||89         (newEleType != oldBoxType.unwrapInnerType())) &&90        !fir::isPolymorphicType(newBoxType)) {91      newDtype = fir::TypeDescOp::create(builder, loc,92                                         mlir::TypeAttr::get(newDerivedType));93    } else {94      newDtype = builder.createNullConstant(loc);95    }96    mlir::Value newAttribute = builder.createIntegerConstant(97        loc, builder.getIntegerType(8), getCFIAttribute(newBoxType));98    int lbsModifierCode =99        static_cast<int>(getLowerBoundModifier(rebox.getLbsModifier()));100    mlir::Value lowerBoundModifier = builder.createIntegerConstant(101        loc, builder.getIntegerType(32), lbsModifierCode);102    fir::runtime::genCopyAndUpdateDescriptor(builder, loc, tempDesc,103                                             rebox.getBox(), newDtype,104                                             newAttribute, lowerBoundModifier);105 106    mlir::Value descValue = fir::LoadOp::create(builder, loc, tempDesc);107    mlir::Value castDesc = builder.createConvert(loc, newBoxType, descValue);108    rewriter.replaceOp(rebox, castDesc);109    return mlir::success();110  }111 112private:113  mlir::SymbolTable *symbolTable = nullptr;114  fir::KindMapping kindMap;115};116 117class IsAssumedSizeConv : public mlir::OpRewritePattern<fir::IsAssumedSizeOp> {118public:119  using OpRewritePattern::OpRewritePattern;120 121  IsAssumedSizeConv(mlir::MLIRContext *context, mlir::SymbolTable *symbolTable,122                    fir::KindMapping kindMap)123      : mlir::OpRewritePattern<fir::IsAssumedSizeOp>(context),124        symbolTable{symbolTable}, kindMap{kindMap} {};125 126  llvm::LogicalResult127  matchAndRewrite(fir::IsAssumedSizeOp isAssumedSizeOp,128                  mlir::PatternRewriter &rewriter) const override {129    fir::FirOpBuilder builder{rewriter, kindMap, symbolTable};130    mlir::Location loc = isAssumedSizeOp.getLoc();131    mlir::Value result =132        fir::runtime::genIsAssumedSize(builder, loc, isAssumedSizeOp.getVal());133    rewriter.replaceOp(isAssumedSizeOp, result);134    return mlir::success();135  }136 137private:138  mlir::SymbolTable *symbolTable = nullptr;139  fir::KindMapping kindMap;140};141 142/// Convert FIR structured control flow ops to CFG ops.143class AssumedRankOpConversion144    : public fir::impl::AssumedRankOpConversionBase<AssumedRankOpConversion> {145public:146  void runOnOperation() override {147    auto *context = &getContext();148    mlir::ModuleOp mod = getOperation();149    mlir::SymbolTable symbolTable(mod);150    fir::KindMapping kindMap = fir::getKindMapping(mod);151    mlir::RewritePatternSet patterns(context);152    patterns.insert<ReboxAssumedRankConv>(context, &symbolTable, kindMap);153    patterns.insert<IsAssumedSizeConv>(context, &symbolTable, kindMap);154    mlir::GreedyRewriteConfig config;155    config.setRegionSimplificationLevel(156        mlir::GreedySimplifyRegionLevel::Disabled);157    (void)applyPatternsGreedily(mod, std::move(patterns), config);158  }159};160} // namespace161