[flang-commits] [flang] 0a494d0 - [flang][NFC] Remove obsolete Character helper

Valentin Clement via flang-commits flang-commits at lists.llvm.org
Mon Jan 31 09:29:38 PST 2022


Author: Valentin Clement
Date: 2022-01-31T18:29:32+01:00
New Revision: 0a494d0623a7ed6042d9f27bb4df81d59af1e935

URL: https://github.com/llvm/llvm-project/commit/0a494d0623a7ed6042d9f27bb4df81d59af1e935
DIFF: https://github.com/llvm/llvm-project/commit/0a494d0623a7ed6042d9f27bb4df81d59af1e935.diff

LOG: [flang][NFC] Remove obsolete Character helper

During the upstreaming process from fir-dev some
new builder have been introduced in the `flang/Optimizer/Builder/Character.h`
and `flang/include/Builder/Runtime/Character.h` files.
This patch removes the obsolete Charachter helpers still present
in the lowering directories.

This patch is part of the upstreaming effort from fir-dev branch.

Reviewed By: kiranchandramohan

Differential Revision: https://reviews.llvm.org/D118594

Added: 
    

Modified: 
    flang/lib/Lower/CMakeLists.txt

Removed: 
    flang/include/flang/Lower/CharacterExpr.h
    flang/include/flang/Lower/CharacterRuntime.h
    flang/lib/Lower/CharacterExpr.cpp
    flang/lib/Lower/CharacterRuntime.cpp


################################################################################
diff  --git a/flang/include/flang/Lower/CharacterExpr.h b/flang/include/flang/Lower/CharacterExpr.h
deleted file mode 100644
index cb8ec9578628f..0000000000000
--- a/flang/include/flang/Lower/CharacterExpr.h
+++ /dev/null
@@ -1,153 +0,0 @@
-//===-- Lower/CharacterExpr.h -- lowering of characters ---------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef FORTRAN_LOWER_CHARACTEREXPR_H
-#define FORTRAN_LOWER_CHARACTEREXPR_H
-
-#include "flang/Optimizer/Builder/BoxValue.h"
-#include "flang/Optimizer/Builder/FIRBuilder.h"
-
-namespace Fortran::lower {
-
-/// Helper to facilitate lowering of CHARACTER in FIR.
-class CharacterExprHelper {
-public:
-  /// Constructor.
-  explicit CharacterExprHelper(fir::FirOpBuilder &builder, mlir::Location loc)
-      : builder{builder}, loc{loc} {}
-  CharacterExprHelper(const CharacterExprHelper &) = delete;
-
-  /// Unless otherwise stated, all mlir::Value inputs of these pseudo-fir ops
-  /// must be of type:
-  /// - fir.boxchar<kind> (dynamic length character),
-  /// - fir.ref<fir.array<len x fir.char<kind>>> (character with compile time
-  ///      constant length),
-  /// - fir.array<len x fir.char<kind>> (compile time constant character)
-
-  /// Copy the \p count first characters of \p src into \p dest.
-  /// \p count can have any integer type.
-  void createCopy(mlir::Value dest, mlir::Value src, mlir::Value count);
-
-  /// Set characters of \p str at position [\p lower, \p upper) to blanks.
-  /// \p lower and \upper bounds are zero based.
-  /// If \p upper <= \p lower, no padding is done.
-  /// \p upper and \p lower can have any integer type.
-  void createPadding(mlir::Value str, mlir::Value lower, mlir::Value upper);
-
-  /// Create str(lb:ub), lower bounds must always be specified, upper
-  /// bound is optional.
-  mlir::Value createSubstring(mlir::Value str,
-                              llvm::ArrayRef<mlir::Value> bounds);
-
-  /// Return blank character of given \p type !fir.char<kind>
-  mlir::Value createBlankConstant(fir::CharacterType type);
-
-  /// Lower \p lhs = \p rhs where \p lhs and \p rhs are scalar characters.
-  /// It handles cases where \p lhs and \p rhs may overlap.
-  void createAssign(mlir::Value lhs, mlir::Value rhs);
-
-  /// Lower an assignment where the buffer and LEN parameter are known and do
-  /// not need to be unboxed.
-  void createAssign(mlir::Value lptr, mlir::Value llen, mlir::Value rptr,
-                    mlir::Value rlen);
-
-  /// Create lhs // rhs in temp obtained with fir.alloca
-  mlir::Value createConcatenate(mlir::Value lhs, mlir::Value rhs);
-
-  /// LEN_TRIM intrinsic.
-  mlir::Value createLenTrim(mlir::Value str);
-
-  /// Embox \p addr and \p len and return fir.boxchar.
-  /// Take care of type conversions before emboxing.
-  /// \p len is converted to the integer type for character lengths if needed.
-  mlir::Value createEmboxChar(mlir::Value addr, mlir::Value len);
-
-  /// Unbox \p boxchar into (fir.ref<fir.char<kind>>, getLengthType()).
-  std::pair<mlir::Value, mlir::Value> createUnboxChar(mlir::Value boxChar);
-
-  /// Allocate a temp of fir::CharacterType type and length len.
-  /// Returns related fir.ref<fir.char<kind>>.
-  mlir::Value createCharacterTemp(mlir::Type type, mlir::Value len);
-
-  /// Allocate a temp of compile time constant length.
-  /// Returns related fir.ref<fir.array<len x fir.char<kind>>>.
-  mlir::Value createCharacterTemp(mlir::Type type, int len) {
-    return createTemp(type, len);
-  }
-
-  /// Return buffer/length pair of character str, if str is a constant,
-  /// it is allocated into a temp, otherwise, its memory reference is
-  /// returned as the buffer.
-  /// The buffer type of str is of type:
-  ///   - fir.ref<fir.array<len x fir.char<kind>>> if str has compile time
-  ///      constant length.
-  ///   - fir.ref<fir.char<kind>> if str has dynamic length.
-  std::pair<mlir::Value, mlir::Value> materializeCharacter(mlir::Value str);
-
-  /// Return true if \p type is a character literal type (is
-  /// fir.array<len x fir.char<kind>>).;
-  static bool isCharacterLiteral(mlir::Type type);
-
-  /// Return true if \p type is one of the following type
-  /// - fir.boxchar<kind>
-  /// - fir.ref<fir.array<len x fir.char<kind>>>
-  /// - fir.array<len x fir.char<kind>>
-  static bool isCharacter(mlir::Type type);
-
-  /// Extract the kind of a character type
-  static int getCharacterKind(mlir::Type type);
-
-  /// Return the integer type that must be used to manipulate
-  /// Character lengths. TODO: move this to FirOpBuilder?
-  mlir::Type getLengthType() { return builder.getIndexType(); }
-
-  /// Create an extended value from:
-  /// - fir.boxchar<kind>
-  /// - fir.ref<fir.array<len x fir.char<kind>>>
-  /// - fir.array<len x fir.char<kind>>
-  /// - fir.char<kind>
-  /// - fir.ref<char<kind>>
-  /// If the no length is passed, it is attempted to be extracted from \p
-  /// character (or its type). This will crash if this is not possible.
-  /// The returned value is a CharBoxValue if \p character is a scalar,
-  /// otherwise it is a CharArrayBoxValue.
-  fir::ExtendedValue toExtendedValue(mlir::Value character,
-                                     mlir::Value len = {});
-
-private:
-  fir::CharBoxValue materializeValue(const fir::CharBoxValue &str);
-  fir::CharBoxValue toDataLengthPair(mlir::Value character);
-  mlir::Type getReferenceType(const fir::CharBoxValue &c) const;
-  mlir::Value createEmbox(const fir::CharBoxValue &str);
-  mlir::Value createLoadCharAt(const fir::CharBoxValue &str, mlir::Value index);
-  void createStoreCharAt(const fir::CharBoxValue &str, mlir::Value index,
-                         mlir::Value c);
-  void createCopy(const fir::CharBoxValue &dest, const fir::CharBoxValue &src,
-                  mlir::Value count);
-  void createPadding(const fir::CharBoxValue &str, mlir::Value lower,
-                     mlir::Value upper);
-  fir::CharBoxValue createTemp(mlir::Type type, mlir::Value len);
-  void createLengthOneAssign(const fir::CharBoxValue &lhs,
-                             const fir::CharBoxValue &rhs);
-  void createAssign(const fir::CharBoxValue &lhs, const fir::CharBoxValue &rhs);
-  fir::CharBoxValue createConcatenate(const fir::CharBoxValue &lhs,
-                                      const fir::CharBoxValue &rhs);
-  fir::CharBoxValue createSubstring(const fir::CharBoxValue &str,
-                                    llvm::ArrayRef<mlir::Value> bounds);
-  mlir::Value createLenTrim(const fir::CharBoxValue &str);
-  mlir::Value createTemp(mlir::Type type, int len);
-  mlir::Value createBlankConstantCode(fir::CharacterType type);
-
-private:
-  fir::FirOpBuilder &builder;
-  mlir::Location loc;
-};
-
-} // namespace Fortran::lower
-
-#endif // FORTRAN_LOWER_CHARACTEREXPR_H

diff  --git a/flang/include/flang/Lower/CharacterRuntime.h b/flang/include/flang/Lower/CharacterRuntime.h
deleted file mode 100644
index 0411c90c34516..0000000000000
--- a/flang/include/flang/Lower/CharacterRuntime.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//===-- Lower/CharacterRuntime.h -- lower CHARACTER operations --*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef FORTRAN_LOWER_CHARACTERRUNTIME_H
-#define FORTRAN_LOWER_CHARACTERRUNTIME_H
-
-#include "mlir/Dialect/StandardOps/IR/Ops.h"
-
-namespace Fortran {
-namespace lower {
-class AbstractConverter;
-
-/// Generate call to a character comparison for two ssa-values of type
-/// `boxchar`.
-mlir::Value genBoxCharCompare(AbstractConverter &converter, mlir::Location loc,
-                              mlir::arith::CmpIPredicate cmp, mlir::Value lhs,
-                              mlir::Value rhs);
-
-/// Generate call to a character comparison op for two unboxed variables. There
-/// are 4 arguments, 2 for the lhs and 2 for the rhs. Each CHARACTER must pass a
-/// reference to its buffer (`ref<char<K>>`) and its LEN type parameter (some
-/// integral type).
-mlir::Value genRawCharCompare(AbstractConverter &converter, mlir::Location loc,
-                              mlir::arith::CmpIPredicate cmp,
-                              mlir::Value lhsBuff, mlir::Value lhsLen,
-                              mlir::Value rhsBuff, mlir::Value rhsLen);
-
-} // namespace lower
-} // namespace Fortran
-
-#endif // FORTRAN_LOWER_CHARACTERRUNTIME_H

diff  --git a/flang/lib/Lower/CMakeLists.txt b/flang/lib/Lower/CMakeLists.txt
index 3e53b8c2a81ad..9981f5d2b8bca 100644
--- a/flang/lib/Lower/CMakeLists.txt
+++ b/flang/lib/Lower/CMakeLists.txt
@@ -3,8 +3,6 @@ get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
 add_flang_library(FortranLower
   Bridge.cpp
   CallInterface.cpp
-  CharacterExpr.cpp
-  CharacterRuntime.cpp
   Coarray.cpp
   ConvertType.cpp
   Mangler.cpp

diff  --git a/flang/lib/Lower/CharacterExpr.cpp b/flang/lib/Lower/CharacterExpr.cpp
deleted file mode 100644
index c262375ae6f98..0000000000000
--- a/flang/lib/Lower/CharacterExpr.cpp
+++ /dev/null
@@ -1,464 +0,0 @@
-//===-- CharacterExpr.cpp -------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "flang/Lower/CharacterExpr.h"
-#include "flang/Lower/ConvertType.h"
-#include "flang/Optimizer/Builder/DoLoopHelper.h"
-#include "flang/Optimizer/Builder/FIRBuilder.h"
-
-//===----------------------------------------------------------------------===//
-// CharacterExprHelper implementation
-//===----------------------------------------------------------------------===//
-
-/// Get fir.char<kind> type with the same kind as inside str.
-static fir::CharacterType getCharacterType(mlir::Type type) {
-  if (auto boxType = type.dyn_cast<fir::BoxCharType>())
-    return boxType.getEleTy();
-  if (auto refType = type.dyn_cast<fir::ReferenceType>())
-    type = refType.getEleTy();
-  if (auto seqType = type.dyn_cast<fir::SequenceType>()) {
-    assert(seqType.getShape().size() == 1 && "rank must be 1");
-    type = seqType.getEleTy();
-  }
-  if (auto charType = type.dyn_cast<fir::CharacterType>())
-    return charType;
-  llvm_unreachable("Invalid character value type");
-}
-
-static fir::CharacterType getCharacterType(const fir::CharBoxValue &box) {
-  return getCharacterType(box.getBuffer().getType());
-}
-
-static bool needToMaterialize(const fir::CharBoxValue &box) {
-  return box.getBuffer().getType().isa<fir::SequenceType>() ||
-         box.getBuffer().getType().isa<fir::CharacterType>();
-}
-
-static std::optional<fir::SequenceType::Extent>
-getCompileTimeLength(const fir::CharBoxValue &box) {
-  // FIXME: should this just return box.getLen() ??
-  auto type = box.getBuffer().getType();
-  if (type.isa<fir::CharacterType>())
-    return 1;
-  if (auto refType = type.dyn_cast<fir::ReferenceType>())
-    type = refType.getEleTy();
-  if (auto seqType = type.dyn_cast<fir::SequenceType>()) {
-    auto shape = seqType.getShape();
-    assert(shape.size() == 1 && "only scalar character supported");
-    if (shape[0] != fir::SequenceType::getUnknownExtent())
-      return shape[0];
-  }
-  return {};
-}
-
-fir::CharBoxValue Fortran::lower::CharacterExprHelper::materializeValue(
-    const fir::CharBoxValue &str) {
-  if (!needToMaterialize(str))
-    return str;
-  auto variable = builder.create<fir::AllocaOp>(loc, str.getBuffer().getType());
-  builder.create<fir::StoreOp>(loc, str.getBuffer(), variable);
-  return {variable, str.getLen()};
-}
-
-fir::CharBoxValue
-Fortran::lower::CharacterExprHelper::toDataLengthPair(mlir::Value character) {
-  // TODO: get rid of toDataLengthPair when adding support for arrays
-  auto charBox = toExtendedValue(character).getCharBox();
-  assert(charBox && "Array unsupported in character lowering helper");
-  return *charBox;
-}
-
-fir::ExtendedValue
-Fortran::lower::CharacterExprHelper::toExtendedValue(mlir::Value character,
-                                                     mlir::Value len) {
-  auto lenType = getLengthType();
-  auto type = character.getType();
-  auto base = character;
-  mlir::Value resultLen = len;
-  llvm::SmallVector<mlir::Value, 2> extents;
-
-  if (auto refType = type.dyn_cast<fir::ReferenceType>())
-    type = refType.getEleTy();
-
-  if (auto arrayType = type.dyn_cast<fir::SequenceType>()) {
-    type = arrayType.getEleTy();
-    auto shape = arrayType.getShape();
-    auto cstLen = shape[0];
-    if (!resultLen && cstLen != fir::SequenceType::getUnknownExtent())
-      resultLen = builder.createIntegerConstant(loc, lenType, cstLen);
-    // FIXME: only allow `?` in last dimension ?
-    auto typeExtents =
-        llvm::ArrayRef<fir::SequenceType::Extent>{shape}.drop_front();
-    auto indexType = builder.getIndexType();
-    for (auto extent : typeExtents) {
-      if (extent == fir::SequenceType::getUnknownExtent())
-        break;
-      extents.emplace_back(
-          builder.createIntegerConstant(loc, indexType, extent));
-    }
-    // Last extent might be missing in case of assumed-size. If more extents
-    // could not be deduced from type, that's an error (a fir.box should
-    // have been used in the interface).
-    if (extents.size() + 1 < typeExtents.size())
-      mlir::emitError(loc, "cannot retrieve array extents from type");
-  } else if (type.isa<fir::CharacterType>()) {
-    if (!resultLen)
-      resultLen = builder.createIntegerConstant(loc, lenType, 1);
-  } else if (auto boxCharType = type.dyn_cast<fir::BoxCharType>()) {
-    auto refType = builder.getRefType(boxCharType.getEleTy());
-    auto unboxed =
-        builder.create<fir::UnboxCharOp>(loc, refType, lenType, character);
-    base = unboxed.getResult(0);
-    if (!resultLen)
-      resultLen = unboxed.getResult(1);
-  } else if (type.isa<fir::BoxType>()) {
-    mlir::emitError(loc, "descriptor or derived type not yet handled");
-  } else {
-    llvm_unreachable("Cannot translate mlir::Value to character ExtendedValue");
-  }
-
-  if (!resultLen)
-    mlir::emitError(loc, "no dynamic length found for character");
-  if (!extents.empty())
-    return fir::CharArrayBoxValue{base, resultLen, extents};
-  return fir::CharBoxValue{base, resultLen};
-}
-
-/// Get fir.ref<fir.char<kind>> type.
-mlir::Type Fortran::lower::CharacterExprHelper::getReferenceType(
-    const fir::CharBoxValue &box) const {
-  return builder.getRefType(getCharacterType(box));
-}
-
-mlir::Value
-Fortran::lower::CharacterExprHelper::createEmbox(const fir::CharBoxValue &box) {
-  // BoxChar require a reference.
-  auto str = box;
-  if (needToMaterialize(box))
-    str = materializeValue(box);
-  auto kind = getCharacterType(str).getFKind();
-  auto boxCharType = fir::BoxCharType::get(builder.getContext(), kind);
-  auto refType = getReferenceType(str);
-  // So far, fir.emboxChar fails lowering to llvm when it is given
-  // fir.ref<fir.array<len x fir.char<kind>>> types, so convert to
-  // fir.ref<fir.char<kind>> if needed.
-  auto buff = str.getBuffer();
-  buff = builder.createConvert(loc, refType, buff);
-  // Convert in case the provided length is not of the integer type that must
-  // be used in boxchar.
-  auto lenType = getLengthType();
-  auto len = str.getLen();
-  len = builder.createConvert(loc, lenType, len);
-  return builder.create<fir::EmboxCharOp>(loc, boxCharType, buff, len);
-}
-
-mlir::Value Fortran::lower::CharacterExprHelper::createLoadCharAt(
-    const fir::CharBoxValue &str, mlir::Value index) {
-  // In case this is addressing a length one character scalar simply return
-  // the single character.
-  if (str.getBuffer().getType().isa<fir::CharacterType>())
-    return str.getBuffer();
-  auto addr = builder.create<fir::CoordinateOp>(loc, getReferenceType(str),
-                                                str.getBuffer(), index);
-  return builder.create<fir::LoadOp>(loc, addr);
-}
-
-void Fortran::lower::CharacterExprHelper::createStoreCharAt(
-    const fir::CharBoxValue &str, mlir::Value index, mlir::Value c) {
-  assert(!needToMaterialize(str) && "not in memory");
-  auto addr = builder.create<fir::CoordinateOp>(loc, getReferenceType(str),
-                                                str.getBuffer(), index);
-  builder.create<fir::StoreOp>(loc, c, addr);
-}
-
-void Fortran::lower::CharacterExprHelper::createCopy(
-    const fir::CharBoxValue &dest, const fir::CharBoxValue &src,
-    mlir::Value count) {
-  fir::factory::DoLoopHelper{builder, loc}.createLoop(
-      count, [&](fir::FirOpBuilder &, mlir::Value index) {
-        auto charVal = createLoadCharAt(src, index);
-        createStoreCharAt(dest, index, charVal);
-      });
-}
-
-void Fortran::lower::CharacterExprHelper::createPadding(
-    const fir::CharBoxValue &str, mlir::Value lower, mlir::Value upper) {
-  auto blank = createBlankConstant(getCharacterType(str));
-  // Always create the loop, if upper < lower, no iteration will be
-  // executed.
-  fir::factory::DoLoopHelper{builder, loc}.createLoop(
-      lower, upper, [&](fir::FirOpBuilder &, mlir::Value index) {
-        createStoreCharAt(str, index, blank);
-      });
-}
-
-fir::CharBoxValue
-Fortran::lower::CharacterExprHelper::createTemp(mlir::Type type,
-                                                mlir::Value len) {
-  assert(type.isa<fir::CharacterType>() && "expected fir character type");
-  llvm::SmallVector<mlir::Value, 3> sizes{len};
-  auto ref = builder.allocateLocal(loc, type, "", ".chrtmp",
-                                   /*shape=*/llvm::None, sizes);
-  return {ref, len};
-}
-
-// Simple length one character assignment without loops.
-void Fortran::lower::CharacterExprHelper::createLengthOneAssign(
-    const fir::CharBoxValue &lhs, const fir::CharBoxValue &rhs) {
-  auto addr = lhs.getBuffer();
-  auto val = rhs.getBuffer();
-  // If rhs value resides in memory, load it.
-  if (!needToMaterialize(rhs))
-    val = builder.create<fir::LoadOp>(loc, val);
-  auto valTy = val.getType();
-  // Precondition is rhs is size 1, but it may be wrapped in a fir.array.
-  if (auto seqTy = valTy.dyn_cast<fir::SequenceType>()) {
-    auto zero = builder.getIntegerAttr(builder.getIndexType(), 0);
-    valTy = seqTy.getEleTy();
-    val = builder.create<fir::ExtractValueOp>(loc, valTy, val,
-                                              builder.getArrayAttr(zero));
-  }
-  auto addrTy = fir::ReferenceType::get(valTy);
-  addr = builder.createConvert(loc, addrTy, addr);
-  assert(fir::dyn_cast_ptrEleTy(addr.getType()) == val.getType());
-  builder.create<fir::StoreOp>(loc, val, addr);
-}
-
-void Fortran::lower::CharacterExprHelper::createAssign(
-    const fir::CharBoxValue &lhs, const fir::CharBoxValue &rhs) {
-  auto rhsCstLen = getCompileTimeLength(rhs);
-  auto lhsCstLen = getCompileTimeLength(lhs);
-  bool compileTimeSameLength =
-      lhsCstLen && rhsCstLen && *lhsCstLen == *rhsCstLen;
-
-  if (compileTimeSameLength && *lhsCstLen == 1) {
-    createLengthOneAssign(lhs, rhs);
-    return;
-  }
-
-  // Copy the minimum of the lhs and rhs lengths and pad the lhs remainder
-  // if needed.
-  mlir::Value copyCount = lhs.getLen();
-  if (!compileTimeSameLength) {
-    auto cmp = builder.create<arith::CmpIOp>(loc, arith::CmpIPredicate::slt,
-                                             lhs.getLen(), rhs.getLen());
-    copyCount =
-        builder.create<mlir::SelectOp>(loc, cmp, lhs.getLen(), rhs.getLen());
-  }
-
-  fir::CharBoxValue safeRhs = rhs;
-  if (needToMaterialize(rhs)) {
-    // TODO: revisit now that character constant handling changed.
-    // Need to materialize the constant to get its elements.
-    // (No equivalent of fir.coordinate_of for array value).
-    safeRhs = materializeValue(rhs);
-  } else {
-    // If rhs is in memory, always assumes rhs might overlap with lhs
-    // in a way that require a temp for the copy. That can be optimize later.
-    // Only create a temp of copyCount size because we do not need more from
-    // rhs.
-    auto temp = createTemp(getCharacterType(rhs), copyCount);
-    createCopy(temp, rhs, copyCount);
-    safeRhs = temp;
-  }
-
-  // Actual copy
-  createCopy(lhs, safeRhs, copyCount);
-
-  // Pad if needed.
-  if (!compileTimeSameLength) {
-    auto one = builder.createIntegerConstant(loc, lhs.getLen().getType(), 1);
-    auto maxPadding =
-        builder.create<mlir::arith::SubIOp>(loc, lhs.getLen(), one);
-    createPadding(lhs, copyCount, maxPadding);
-  }
-}
-
-fir::CharBoxValue Fortran::lower::CharacterExprHelper::createConcatenate(
-    const fir::CharBoxValue &lhs, const fir::CharBoxValue &rhs) {
-  mlir::Value len =
-      builder.create<mlir::arith::AddIOp>(loc, lhs.getLen(), rhs.getLen());
-  auto temp = createTemp(getCharacterType(rhs), len);
-  createCopy(temp, lhs, lhs.getLen());
-  auto one = builder.createIntegerConstant(loc, len.getType(), 1);
-  auto upperBound = builder.create<mlir::arith::SubIOp>(loc, len, one);
-  auto lhsLen =
-      builder.createConvert(loc, builder.getIndexType(), lhs.getLen());
-  fir::factory::DoLoopHelper{builder, loc}.createLoop(
-      lhs.getLen(), upperBound, one,
-      [&](fir::FirOpBuilder &bldr, mlir::Value index) {
-        auto rhsIndex = bldr.create<mlir::arith::SubIOp>(loc, index, lhsLen);
-        auto charVal = createLoadCharAt(rhs, rhsIndex);
-        createStoreCharAt(temp, index, charVal);
-      });
-  return temp;
-}
-
-fir::CharBoxValue Fortran::lower::CharacterExprHelper::createSubstring(
-    const fir::CharBoxValue &box, llvm::ArrayRef<mlir::Value> bounds) {
-  // Constant need to be materialize in memory to use fir.coordinate_of.
-  auto str = box;
-  if (needToMaterialize(box))
-    str = materializeValue(box);
-
-  auto nbounds{bounds.size()};
-  if (nbounds < 1 || nbounds > 2) {
-    mlir::emitError(loc, "Incorrect number of bounds in substring");
-    return {mlir::Value{}, mlir::Value{}};
-  }
-  mlir::SmallVector<mlir::Value, 2> castBounds;
-  // Convert bounds to length type to do safe arithmetic on it.
-  for (auto bound : bounds)
-    castBounds.push_back(builder.createConvert(loc, getLengthType(), bound));
-  auto lowerBound = castBounds[0];
-  // FIR CoordinateOp is zero based but Fortran substring are one based.
-  auto one = builder.createIntegerConstant(loc, lowerBound.getType(), 1);
-  auto offset =
-      builder.create<mlir::arith::SubIOp>(loc, lowerBound, one).getResult();
-  auto idxType = builder.getIndexType();
-  if (offset.getType() != idxType)
-    offset = builder.createConvert(loc, idxType, offset);
-  auto substringRef = builder.create<fir::CoordinateOp>(
-      loc, getReferenceType(str), str.getBuffer(), offset);
-
-  // Compute the length.
-  mlir::Value substringLen{};
-  if (nbounds < 2) {
-    substringLen =
-        builder.create<mlir::arith::SubIOp>(loc, str.getLen(), castBounds[0]);
-  } else {
-    substringLen =
-        builder.create<mlir::arith::SubIOp>(loc, castBounds[1], castBounds[0]);
-  }
-  substringLen = builder.create<mlir::arith::AddIOp>(loc, substringLen, one);
-
-  // Set length to zero if bounds were reversed (Fortran 2018 9.4.1)
-  auto zero = builder.createIntegerConstant(loc, substringLen.getType(), 0);
-  auto cdt = builder.create<mlir::arith::CmpIOp>(
-      loc, mlir::arith::CmpIPredicate::slt, substringLen, zero);
-  substringLen = builder.create<mlir::SelectOp>(loc, cdt, zero, substringLen);
-
-  return {substringRef, substringLen};
-}
-
-mlir::Value Fortran::lower::CharacterExprHelper::createLenTrim(
-    const fir::CharBoxValue &str) {
-  return {};
-}
-
-mlir::Value Fortran::lower::CharacterExprHelper::createTemp(mlir::Type type,
-                                                            int len) {
-  assert(type.isa<fir::CharacterType>() && "expected fir character type");
-  assert(len >= 0 && "expected positive length");
-  fir::SequenceType::Shape shape{len};
-  auto seqType = fir::SequenceType::get(shape, type);
-  return builder.create<fir::AllocaOp>(loc, seqType);
-}
-
-// Returns integer with code for blank. The integer has the same
-// size as the character. Blank has ascii space code for all kinds.
-mlir::Value Fortran::lower::CharacterExprHelper::createBlankConstantCode(
-    fir::CharacterType type) {
-  auto bits = builder.getKindMap().getCharacterBitsize(type.getFKind());
-  auto intType = builder.getIntegerType(bits);
-  return builder.createIntegerConstant(loc, intType, ' ');
-}
-
-mlir::Value Fortran::lower::CharacterExprHelper::createBlankConstant(
-    fir::CharacterType type) {
-  return builder.createConvert(loc, type, createBlankConstantCode(type));
-}
-
-void Fortran::lower::CharacterExprHelper::createCopy(mlir::Value dest,
-                                                     mlir::Value src,
-                                                     mlir::Value count) {
-  createCopy(toDataLengthPair(dest), toDataLengthPair(src), count);
-}
-
-void Fortran::lower::CharacterExprHelper::createPadding(mlir::Value str,
-                                                        mlir::Value lower,
-                                                        mlir::Value upper) {
-  createPadding(toDataLengthPair(str), lower, upper);
-}
-
-mlir::Value Fortran::lower::CharacterExprHelper::createSubstring(
-    mlir::Value str, llvm::ArrayRef<mlir::Value> bounds) {
-  return createEmbox(createSubstring(toDataLengthPair(str), bounds));
-}
-
-void Fortran::lower::CharacterExprHelper::createAssign(mlir::Value lhs,
-                                                       mlir::Value rhs) {
-  createAssign(toDataLengthPair(lhs), toDataLengthPair(rhs));
-}
-
-mlir::Value
-Fortran::lower::CharacterExprHelper::createLenTrim(mlir::Value str) {
-  return createLenTrim(toDataLengthPair(str));
-}
-
-void Fortran::lower::CharacterExprHelper::createAssign(mlir::Value lptr,
-                                                       mlir::Value llen,
-                                                       mlir::Value rptr,
-                                                       mlir::Value rlen) {
-  createAssign(fir::CharBoxValue{lptr, llen}, fir::CharBoxValue{rptr, rlen});
-}
-
-mlir::Value
-Fortran::lower::CharacterExprHelper::createConcatenate(mlir::Value lhs,
-                                                       mlir::Value rhs) {
-  return createEmbox(
-      createConcatenate(toDataLengthPair(lhs), toDataLengthPair(rhs)));
-}
-
-mlir::Value
-Fortran::lower::CharacterExprHelper::createEmboxChar(mlir::Value addr,
-                                                     mlir::Value len) {
-  return createEmbox(fir::CharBoxValue{addr, len});
-}
-
-std::pair<mlir::Value, mlir::Value>
-Fortran::lower::CharacterExprHelper::createUnboxChar(mlir::Value boxChar) {
-  auto box = toDataLengthPair(boxChar);
-  return {box.getBuffer(), box.getLen()};
-}
-
-mlir::Value
-Fortran::lower::CharacterExprHelper::createCharacterTemp(mlir::Type type,
-                                                         mlir::Value len) {
-  return createEmbox(createTemp(type, len));
-}
-
-std::pair<mlir::Value, mlir::Value>
-Fortran::lower::CharacterExprHelper::materializeCharacter(mlir::Value str) {
-  auto box = toDataLengthPair(str);
-  if (needToMaterialize(box))
-    box = materializeValue(box);
-  return {box.getBuffer(), box.getLen()};
-}
-
-bool Fortran::lower::CharacterExprHelper::isCharacterLiteral(mlir::Type type) {
-  if (auto seqType = type.dyn_cast<fir::SequenceType>())
-    return (seqType.getShape().size() == 1) &&
-           seqType.getEleTy().isa<fir::CharacterType>();
-  return false;
-}
-
-bool Fortran::lower::CharacterExprHelper::isCharacter(mlir::Type type) {
-  if (type.isa<fir::BoxCharType>())
-    return true;
-  if (auto refType = type.dyn_cast<fir::ReferenceType>())
-    type = refType.getEleTy();
-  if (auto seqType = type.dyn_cast<fir::SequenceType>())
-    if (seqType.getShape().size() == 1)
-      type = seqType.getEleTy();
-  return type.isa<fir::CharacterType>();
-}
-
-int Fortran::lower::CharacterExprHelper::getCharacterKind(mlir::Type type) {
-  return getCharacterType(type).getFKind();
-}

diff  --git a/flang/lib/Lower/CharacterRuntime.cpp b/flang/lib/Lower/CharacterRuntime.cpp
deleted file mode 100644
index 23b0b6f237ccc..0000000000000
--- a/flang/lib/Lower/CharacterRuntime.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-//===-- CharacterRuntime.cpp -- runtime for CHARACTER type entities -------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "flang/Lower/CharacterRuntime.h"
-#include "RTBuilder.h"
-#include "flang/Lower/Bridge.h"
-#include "flang/Lower/CharacterExpr.h"
-#include "flang/Optimizer/Builder/FIRBuilder.h"
-#include "flang/Runtime/character.h"
-#include "mlir/Dialect/StandardOps/IR/Ops.h"
-
-using namespace Fortran::runtime;
-
-#define NAMIFY_HELPER(X) #X
-#define NAMIFY(X) NAMIFY_HELPER(IONAME(X))
-#define mkRTKey(X) mkKey(RTNAME(X))
-
-namespace Fortran::lower {
-/// Static table of CHARACTER runtime calls
-///
-/// This logical map contains the name and type builder function for each
-/// runtime function listed in the tuple. This table is fully constructed at
-/// compile-time. Use the `mkRTKey` macro to access the table.
-static constexpr std::tuple<
-    mkRTKey(CharacterCompareScalar), mkRTKey(CharacterCompareScalar1),
-    mkRTKey(CharacterCompareScalar2), mkRTKey(CharacterCompareScalar4),
-    mkRTKey(CharacterCompare)>
-    newCharRTTable;
-} // namespace Fortran::lower
-
-using namespace Fortran::lower;
-
-/// Helper function to retrieve the name of the IO function given the key `A`
-template <typename A>
-static constexpr const char *getName() {
-  return std::get<A>(newCharRTTable).name;
-}
-
-/// Helper function to retrieve the type model signature builder of the IO
-/// function as defined by the key `A`
-template <typename A>
-static constexpr FuncTypeBuilderFunc getTypeModel() {
-  return std::get<A>(newCharRTTable).getTypeModel();
-}
-
-inline int64_t getLength(mlir::Type argTy) {
-  return argTy.cast<fir::SequenceType>().getShape()[0];
-}
-
-/// Get (or generate) the MLIR FuncOp for a given runtime function.
-template <typename E>
-static mlir::FuncOp getRuntimeFunc(mlir::Location loc,
-                                   fir::FirOpBuilder &builder) {
-  auto name = getName<E>();
-  auto func = builder.getNamedFunction(name);
-  if (func)
-    return func;
-  auto funTy = getTypeModel<E>()(builder.getContext());
-  func = builder.createFunction(loc, name, funTy);
-  func->setAttr("fir.runtime", builder.getUnitAttr());
-  return func;
-}
-
-/// Helper function to recover the KIND from the FIR type.
-static int discoverKind(mlir::Type ty) {
-  if (auto charTy = ty.dyn_cast<fir::CharacterType>())
-    return charTy.getFKind();
-  if (auto eleTy = fir::dyn_cast_ptrEleTy(ty))
-    return discoverKind(eleTy);
-  if (auto arrTy = ty.dyn_cast<fir::SequenceType>())
-    return discoverKind(arrTy.getEleTy());
-  if (auto boxTy = ty.dyn_cast<fir::BoxCharType>())
-    return discoverKind(boxTy.getEleTy());
-  if (auto boxTy = ty.dyn_cast<fir::BoxType>())
-    return discoverKind(boxTy.getEleTy());
-  llvm_unreachable("unexpected character type");
-}
-
-//===----------------------------------------------------------------------===//
-// Lower character operations
-//===----------------------------------------------------------------------===//
-
-mlir::Value Fortran::lower::genRawCharCompare(
-    Fortran::lower::AbstractConverter &converter, mlir::Location loc,
-    mlir::arith::CmpIPredicate cmp, mlir::Value lhsBuff, mlir::Value lhsLen,
-    mlir::Value rhsBuff, mlir::Value rhsLen) {
-  auto &builder = converter.getFirOpBuilder();
-  mlir::FuncOp beginFunc;
-  switch (discoverKind(lhsBuff.getType())) {
-  case 1:
-    beginFunc = getRuntimeFunc<mkRTKey(CharacterCompareScalar1)>(loc, builder);
-    break;
-  case 2:
-    beginFunc = getRuntimeFunc<mkRTKey(CharacterCompareScalar2)>(loc, builder);
-    break;
-  case 4:
-    beginFunc = getRuntimeFunc<mkRTKey(CharacterCompareScalar4)>(loc, builder);
-    break;
-  default:
-    llvm_unreachable("runtime does not support CHARACTER KIND");
-  }
-  auto fTy = beginFunc.getType();
-  auto lptr = builder.createConvert(loc, fTy.getInput(0), lhsBuff);
-  auto llen = builder.createConvert(loc, fTy.getInput(2), lhsLen);
-  auto rptr = builder.createConvert(loc, fTy.getInput(1), rhsBuff);
-  auto rlen = builder.createConvert(loc, fTy.getInput(3), rhsLen);
-  llvm::SmallVector<mlir::Value, 4> args = {lptr, rptr, llen, rlen};
-  auto tri = builder.create<mlir::CallOp>(loc, beginFunc, args).getResult(0);
-  auto zero = builder.createIntegerConstant(loc, tri.getType(), 0);
-  return builder.create<mlir::arith::CmpIOp>(loc, cmp, tri, zero);
-}
-
-mlir::Value Fortran::lower::genBoxCharCompare(
-    Fortran::lower::AbstractConverter &converter, mlir::Location loc,
-    mlir::arith::CmpIPredicate cmp, mlir::Value lhs, mlir::Value rhs) {
-  auto &builder = converter.getFirOpBuilder();
-  Fortran::lower::CharacterExprHelper helper{builder, loc};
-  auto lhsPair = helper.materializeCharacter(lhs);
-  auto rhsPair = helper.materializeCharacter(rhs);
-  return genRawCharCompare(converter, loc, cmp, lhsPair.first, lhsPair.second,
-                           rhsPair.first, rhsPair.second);
-}


        


More information about the flang-commits mailing list