forked from OSchip/llvm-project
[flang][NFC] Remove obsolete FIRBuilder and BoxValue
This patch removes some files made obsolete by newer version of them available in the Optimizer directory. `flang/include/flang/Lower/FIRBuilder.h` and `flang/lib/Lower/FIRBuilder.cpp` are removed and replace by the newer version present in `flang/include/flang/Optimizer/Builder/FIRBuilder.h` and `flang/lib/Optimizer/Builder/FIRBuilder.cpp`. `flang/include/flang/Lower/Support/BoxValue.h` and `flang/lib/Lower/ConvertExpr.cpp` are removed and replace by the newer version present in `flang/include/flang/Optimizer/Builder/BoxValue.h` This patch is a preparation to be able to upstream the lowering from fir-dev. Reviewed By: jeanPerier, kiranchandramohan Differential Revision: https://reviews.llvm.org/D118404
This commit is contained in:
parent
bfd8210f6f
commit
8a0d0a3a54
|
@ -12,6 +12,11 @@
|
|||
#include "flang/Common/Fortran.h"
|
||||
#include "mlir/IR/BuiltinOps.h"
|
||||
|
||||
namespace fir {
|
||||
class KindMapping;
|
||||
class FirOpBuilder;
|
||||
} // namespace fir
|
||||
|
||||
namespace Fortran {
|
||||
namespace common {
|
||||
template <typename>
|
||||
|
@ -39,7 +44,6 @@ struct Variable;
|
|||
|
||||
using SomeExpr = Fortran::evaluate::Expr<Fortran::evaluate::SomeType>;
|
||||
using SymbolRef = Fortran::common::Reference<const Fortran::semantics::Symbol>;
|
||||
class FirOpBuilder;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// AbstractConverter interface
|
||||
|
@ -114,7 +118,7 @@ public:
|
|||
//===--------------------------------------------------------------------===//
|
||||
|
||||
/// Get the OpBuilder
|
||||
virtual Fortran::lower::FirOpBuilder &getFirOpBuilder() = 0;
|
||||
virtual fir::FirOpBuilder &getFirOpBuilder() = 0;
|
||||
/// Get the ModuleOp
|
||||
virtual mlir::ModuleOp &getModuleOp() = 0;
|
||||
/// Get the MLIRContext
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "flang/Common/Fortran.h"
|
||||
#include "flang/Lower/AbstractConverter.h"
|
||||
#include "flang/Optimizer/Builder/FIRBuilder.h"
|
||||
#include "flang/Optimizer/Support/KindMapping.h"
|
||||
#include "mlir/IR/BuiltinOps.h"
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
#ifndef FORTRAN_LOWER_CHARACTEREXPR_H
|
||||
#define FORTRAN_LOWER_CHARACTEREXPR_H
|
||||
|
||||
#include "flang/Lower/FIRBuilder.h"
|
||||
#include "flang/Lower/Support/BoxValue.h"
|
||||
#include "flang/Optimizer/Builder/BoxValue.h"
|
||||
#include "flang/Optimizer/Builder/FIRBuilder.h"
|
||||
|
||||
namespace Fortran::lower {
|
||||
|
||||
|
@ -18,7 +18,7 @@ namespace Fortran::lower {
|
|||
class CharacterExprHelper {
|
||||
public:
|
||||
/// Constructor.
|
||||
explicit CharacterExprHelper(FirOpBuilder &builder, mlir::Location loc)
|
||||
explicit CharacterExprHelper(fir::FirOpBuilder &builder, mlir::Location loc)
|
||||
: builder{builder}, loc{loc} {}
|
||||
CharacterExprHelper(const CharacterExprHelper &) = delete;
|
||||
|
||||
|
@ -144,7 +144,7 @@ private:
|
|||
mlir::Value createBlankConstantCode(fir::CharacterType type);
|
||||
|
||||
private:
|
||||
FirOpBuilder &builder;
|
||||
fir::FirOpBuilder &builder;
|
||||
mlir::Location loc;
|
||||
};
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#define FORTRAN_LOWER_COARRAY_H
|
||||
|
||||
#include "flang/Lower/AbstractConverter.h"
|
||||
#include "flang/Lower/Support/BoxValue.h"
|
||||
#include "flang/Optimizer/Builder/BoxValue.h"
|
||||
|
||||
namespace Fortran {
|
||||
|
||||
|
|
|
@ -9,14 +9,14 @@
|
|||
#ifndef FORTRAN_LOWER_COMPLEXEXPR_H
|
||||
#define FORTRAN_LOWER_COMPLEXEXPR_H
|
||||
|
||||
#include "flang/Lower/FIRBuilder.h"
|
||||
#include "flang/Optimizer/Builder/FIRBuilder.h"
|
||||
|
||||
namespace Fortran::lower {
|
||||
|
||||
/// Helper to facilitate lowering of COMPLEX manipulations in FIR.
|
||||
class ComplexExprHelper {
|
||||
public:
|
||||
explicit ComplexExprHelper(FirOpBuilder &builder, mlir::Location loc)
|
||||
explicit ComplexExprHelper(fir::FirOpBuilder &builder, mlir::Location loc)
|
||||
: builder(builder), loc(loc) {}
|
||||
ComplexExprHelper(const ComplexExprHelper &) = delete;
|
||||
|
||||
|
@ -78,7 +78,7 @@ protected:
|
|||
}
|
||||
|
||||
private:
|
||||
FirOpBuilder &builder;
|
||||
fir::FirOpBuilder &builder;
|
||||
mlir::Location loc;
|
||||
};
|
||||
|
||||
|
|
|
@ -9,19 +9,19 @@
|
|||
#ifndef FORTRAN_LOWER_DOLOOPHELPER_H
|
||||
#define FORTRAN_LOWER_DOLOOPHELPER_H
|
||||
|
||||
#include "flang/Lower/FIRBuilder.h"
|
||||
#include "flang/Optimizer/Builder/FIRBuilder.h"
|
||||
|
||||
namespace Fortran::lower {
|
||||
|
||||
/// Helper to build fir.do_loop Ops.
|
||||
class DoLoopHelper {
|
||||
public:
|
||||
explicit DoLoopHelper(FirOpBuilder &builder, mlir::Location loc)
|
||||
explicit DoLoopHelper(fir::FirOpBuilder &builder, mlir::Location loc)
|
||||
: builder(builder), loc(loc) {}
|
||||
DoLoopHelper(const DoLoopHelper &) = delete;
|
||||
|
||||
/// Type of a callback to generate the loop body.
|
||||
using BodyGenerator = std::function<void(FirOpBuilder &, mlir::Value)>;
|
||||
using BodyGenerator = std::function<void(fir::FirOpBuilder &, mlir::Value)>;
|
||||
|
||||
/// Build loop [\p lb, \p ub] with step \p step.
|
||||
/// If \p step is an empty value, 1 is used for the step.
|
||||
|
@ -36,7 +36,7 @@ public:
|
|||
void createLoop(mlir::Value count, const BodyGenerator &bodyGenerator);
|
||||
|
||||
private:
|
||||
FirOpBuilder &builder;
|
||||
fir::FirOpBuilder &builder;
|
||||
mlir::Location loc;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,197 +0,0 @@
|
|||
//===-- Lower/FirBuilder.h -- FIR operation builder -------------*- 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Builder routines for constructing the FIR dialect of MLIR. As FIR is a
|
||||
// dialect of MLIR, it makes extensive use of MLIR interfaces and MLIR's coding
|
||||
// style (https://mlir.llvm.org/getting_started/DeveloperGuide/) is used in this
|
||||
// module.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef FORTRAN_LOWER_FIRBUILDER_H
|
||||
#define FORTRAN_LOWER_FIRBUILDER_H
|
||||
|
||||
#include "flang/Common/reference.h"
|
||||
#include "flang/Optimizer/Dialect/FIROps.h"
|
||||
#include "flang/Optimizer/Dialect/FIRType.h"
|
||||
#include "flang/Optimizer/Support/KindMapping.h"
|
||||
#include "mlir/IR/Builders.h"
|
||||
#include "mlir/IR/BuiltinOps.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
|
||||
namespace Fortran::lower {
|
||||
class AbstractConverter;
|
||||
class BoxValue;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// FirOpBuilder
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// Extends the MLIR OpBuilder to provide methods for building common FIR
|
||||
/// patterns.
|
||||
class FirOpBuilder : public mlir::OpBuilder {
|
||||
public:
|
||||
explicit FirOpBuilder(mlir::Operation *op, const fir::KindMapping &kindMap)
|
||||
: OpBuilder{op}, kindMap{kindMap} {}
|
||||
|
||||
/// Get the current Region of the insertion point.
|
||||
mlir::Region &getRegion() { return *getBlock()->getParent(); }
|
||||
|
||||
/// Get the current Module
|
||||
mlir::ModuleOp getModule() {
|
||||
return getRegion().getParentOfType<mlir::ModuleOp>();
|
||||
}
|
||||
|
||||
/// Get the current Function
|
||||
mlir::FuncOp getFunction() {
|
||||
return getRegion().getParentOfType<mlir::FuncOp>();
|
||||
}
|
||||
|
||||
/// Get a reference to the kind map.
|
||||
const fir::KindMapping &getKindMap() { return kindMap; }
|
||||
|
||||
/// The LHS and RHS are not always in agreement in terms of
|
||||
/// type. In some cases, the disagreement is between COMPLEX and other scalar
|
||||
/// types. In that case, the conversion must insert/extract out of a COMPLEX
|
||||
/// value to have the proper semantics and be strongly typed.
|
||||
mlir::Value convertWithSemantics(mlir::Location loc, mlir::Type toTy,
|
||||
mlir::Value val);
|
||||
|
||||
/// Get the entry block of the current Function
|
||||
mlir::Block *getEntryBlock() { return &getFunction().front(); }
|
||||
|
||||
/// Safely create a reference type to the type `eleTy`.
|
||||
mlir::Type getRefType(mlir::Type eleTy);
|
||||
|
||||
/// Create a null constant of type RefType and value 0. Need to pass in the
|
||||
/// Location information.
|
||||
mlir::Value createNullConstant(mlir::Location loc);
|
||||
|
||||
/// Create an integer constant of type \p type and value \p i.
|
||||
mlir::Value createIntegerConstant(mlir::Location loc, mlir::Type integerType,
|
||||
std::int64_t i);
|
||||
|
||||
mlir::Value createRealConstant(mlir::Location loc, mlir::Type realType,
|
||||
const llvm::APFloat &val);
|
||||
/// Create a real constant of type \p realType with a value zero.
|
||||
mlir::Value createRealZeroConstant(mlir::Location loc, mlir::Type realType);
|
||||
|
||||
/// Create a slot for a local on the stack. Besides the variable's type and
|
||||
/// shape, it may be given name or target attributes.
|
||||
mlir::Value allocateLocal(mlir::Location loc, mlir::Type ty,
|
||||
llvm::StringRef nm,
|
||||
llvm::ArrayRef<mlir::Value> shape,
|
||||
bool asTarget = false);
|
||||
|
||||
/// Create a temporary. A temp is allocated using `fir.alloca` and can be read
|
||||
/// and written using `fir.load` and `fir.store`, resp. The temporary can be
|
||||
/// given a name via a front-end `Symbol` or a `StringRef`.
|
||||
mlir::Value createTemporary(mlir::Location loc, mlir::Type type,
|
||||
llvm::StringRef name = {},
|
||||
llvm::ArrayRef<mlir::Value> shape = {});
|
||||
|
||||
/// Create an unnamed and untracked temporary on the stack.
|
||||
mlir::Value createTemporary(mlir::Location loc, mlir::Type type,
|
||||
llvm::ArrayRef<mlir::Value> shape) {
|
||||
return createTemporary(loc, type, llvm::StringRef{}, shape);
|
||||
}
|
||||
|
||||
/// Create a global value.
|
||||
fir::GlobalOp createGlobal(mlir::Location loc, mlir::Type type,
|
||||
llvm::StringRef name,
|
||||
mlir::StringAttr linkage = {},
|
||||
mlir::Attribute value = {}, bool isConst = false);
|
||||
|
||||
fir::GlobalOp createGlobal(mlir::Location loc, mlir::Type type,
|
||||
llvm::StringRef name, bool isConst,
|
||||
std::function<void(FirOpBuilder &)> bodyBuilder,
|
||||
mlir::StringAttr linkage = {});
|
||||
|
||||
/// Create a global constant (read-only) value.
|
||||
fir::GlobalOp createGlobalConstant(mlir::Location loc, mlir::Type type,
|
||||
llvm::StringRef name,
|
||||
mlir::StringAttr linkage = {},
|
||||
mlir::Attribute value = {}) {
|
||||
return createGlobal(loc, type, name, linkage, value, /*isConst=*/true);
|
||||
}
|
||||
|
||||
fir::GlobalOp
|
||||
createGlobalConstant(mlir::Location loc, mlir::Type type,
|
||||
llvm::StringRef name,
|
||||
std::function<void(FirOpBuilder &)> bodyBuilder,
|
||||
mlir::StringAttr linkage = {}) {
|
||||
return createGlobal(loc, type, name, /*isConst=*/true, bodyBuilder,
|
||||
linkage);
|
||||
}
|
||||
|
||||
/// Convert a StringRef string into a fir::StringLitOp.
|
||||
fir::StringLitOp createStringLit(mlir::Location loc, mlir::Type eleTy,
|
||||
llvm::StringRef string);
|
||||
|
||||
/// Get a function by name. If the function exists in the current module, it
|
||||
/// is returned. Otherwise, a null FuncOp is returned.
|
||||
mlir::FuncOp getNamedFunction(llvm::StringRef name) {
|
||||
return getNamedFunction(getModule(), name);
|
||||
}
|
||||
|
||||
static mlir::FuncOp getNamedFunction(mlir::ModuleOp module,
|
||||
llvm::StringRef name);
|
||||
|
||||
fir::GlobalOp getNamedGlobal(llvm::StringRef name) {
|
||||
return getNamedGlobal(getModule(), name);
|
||||
}
|
||||
|
||||
static fir::GlobalOp getNamedGlobal(mlir::ModuleOp module,
|
||||
llvm::StringRef name);
|
||||
|
||||
/// Lazy creation of fir.convert op.
|
||||
mlir::Value createConvert(mlir::Location loc, mlir::Type toTy,
|
||||
mlir::Value val);
|
||||
|
||||
/// Create a new FuncOp. If the function may have already been created, use
|
||||
/// `addNamedFunction` instead.
|
||||
mlir::FuncOp createFunction(mlir::Location loc, llvm::StringRef name,
|
||||
mlir::FunctionType ty) {
|
||||
return createFunction(loc, getModule(), name, ty);
|
||||
}
|
||||
|
||||
static mlir::FuncOp createFunction(mlir::Location loc, mlir::ModuleOp module,
|
||||
llvm::StringRef name,
|
||||
mlir::FunctionType ty);
|
||||
|
||||
/// Determine if the named function is already in the module. Return the
|
||||
/// instance if found, otherwise add a new named function to the module.
|
||||
mlir::FuncOp addNamedFunction(mlir::Location loc, llvm::StringRef name,
|
||||
mlir::FunctionType ty) {
|
||||
if (auto func = getNamedFunction(name))
|
||||
return func;
|
||||
return createFunction(loc, name, ty);
|
||||
}
|
||||
|
||||
static mlir::FuncOp addNamedFunction(mlir::Location loc,
|
||||
mlir::ModuleOp module,
|
||||
llvm::StringRef name,
|
||||
mlir::FunctionType ty) {
|
||||
if (auto func = getNamedFunction(module, name))
|
||||
return func;
|
||||
return createFunction(loc, module, name, ty);
|
||||
}
|
||||
|
||||
/// Cast the input value to IndexType.
|
||||
mlir::Value convertToIndexType(mlir::Location loc, mlir::Value val) {
|
||||
return createConvert(loc, getIndexType(), val);
|
||||
}
|
||||
|
||||
private:
|
||||
const fir::KindMapping &kindMap;
|
||||
};
|
||||
|
||||
} // namespace Fortran::lower
|
||||
|
||||
#endif // FORTRAN_LOWER_FIRBUILDER_H
|
|
@ -9,7 +9,7 @@
|
|||
#ifndef FORTRAN_LOWER_INTRINSICCALL_H
|
||||
#define FORTRAN_LOWER_INTRINSICCALL_H
|
||||
|
||||
#include "flang/Lower/FIRBuilder.h"
|
||||
#include "flang/Optimizer/Builder/FIRBuilder.h"
|
||||
|
||||
namespace fir {
|
||||
class ExtendedValue;
|
||||
|
@ -31,7 +31,7 @@ namespace Fortran::lower {
|
|||
/// Generate the FIR+MLIR operations for the generic intrinsic \p name
|
||||
/// with arguments \p args and expected result type \p resultType.
|
||||
/// Returned mlir::Value is the returned Fortran intrinsic value.
|
||||
fir::ExtendedValue genIntrinsicCall(FirOpBuilder &, mlir::Location,
|
||||
fir::ExtendedValue genIntrinsicCall(fir::FirOpBuilder &, mlir::Location,
|
||||
llvm::StringRef name, mlir::Type resultType,
|
||||
llvm::ArrayRef<fir::ExtendedValue> args);
|
||||
|
||||
|
@ -39,7 +39,7 @@ fir::ExtendedValue genIntrinsicCall(FirOpBuilder &, mlir::Location,
|
|||
// implementation) of an unrestricted intrinsic (defined by its signature
|
||||
// and generic name)
|
||||
mlir::SymbolRefAttr
|
||||
getUnrestrictedIntrinsicSymbolRefAttr(FirOpBuilder &, mlir::Location,
|
||||
getUnrestrictedIntrinsicSymbolRefAttr(fir::FirOpBuilder &, mlir::Location,
|
||||
llvm::StringRef name,
|
||||
mlir::FunctionType signature);
|
||||
|
||||
|
@ -50,16 +50,16 @@ getUnrestrictedIntrinsicSymbolRefAttr(FirOpBuilder &, mlir::Location,
|
|||
|
||||
/// Generate maximum. There must be at least one argument and all arguments
|
||||
/// must have the same type.
|
||||
mlir::Value genMax(FirOpBuilder &, mlir::Location,
|
||||
mlir::Value genMax(fir::FirOpBuilder &, mlir::Location,
|
||||
llvm::ArrayRef<mlir::Value> args);
|
||||
|
||||
/// Generate minimum. Same constraints as genMax.
|
||||
mlir::Value genMin(FirOpBuilder &, mlir::Location,
|
||||
mlir::Value genMin(fir::FirOpBuilder &, mlir::Location,
|
||||
llvm::ArrayRef<mlir::Value> args);
|
||||
|
||||
/// Generate power function x**y with given the expected
|
||||
/// result type.
|
||||
mlir::Value genPow(FirOpBuilder &, mlir::Location, mlir::Type resultType,
|
||||
mlir::Value genPow(fir::FirOpBuilder &, mlir::Location, mlir::Type resultType,
|
||||
mlir::Value x, mlir::Value y);
|
||||
|
||||
} // namespace Fortran::lower
|
||||
|
|
|
@ -1,238 +0,0 @@
|
|||
//===-- Lower/Support/BoxValue.h -- internal box values ---------*- 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 LOWER_SUPPORT_BOXVALUE_H
|
||||
#define LOWER_SUPPORT_BOXVALUE_H
|
||||
|
||||
#include "mlir/IR/Value.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
|
||||
namespace fir {
|
||||
class CharBoxValue;
|
||||
class ArrayBoxValue;
|
||||
class CharArrayBoxValue;
|
||||
class BoxValue;
|
||||
class ProcBoxValue;
|
||||
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const CharBoxValue &);
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const ArrayBoxValue &);
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const CharArrayBoxValue &);
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const BoxValue &);
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const ProcBoxValue &);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Boxed values
|
||||
//
|
||||
// Define a set of containers used internally by the lowering bridge to keep
|
||||
// track of extended values associated with a Fortran subexpression. These
|
||||
// associations are maintained during the construction of FIR.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// Most expressions of intrinsic type can be passed unboxed. Their properties
|
||||
/// are known statically.
|
||||
using UnboxedValue = mlir::Value;
|
||||
|
||||
/// Abstract base class.
|
||||
class AbstractBox {
|
||||
public:
|
||||
AbstractBox() = delete;
|
||||
AbstractBox(mlir::Value addr) : addr{addr} {}
|
||||
mlir::Value getAddr() const { return addr; }
|
||||
|
||||
protected:
|
||||
mlir::Value addr;
|
||||
};
|
||||
|
||||
/// Expressions of CHARACTER type have an associated, possibly dynamic LEN
|
||||
/// value.
|
||||
class CharBoxValue : public AbstractBox {
|
||||
public:
|
||||
CharBoxValue(mlir::Value addr, mlir::Value len)
|
||||
: AbstractBox{addr}, len{len} {}
|
||||
|
||||
CharBoxValue clone(mlir::Value newBase) const { return {newBase, len}; }
|
||||
|
||||
mlir::Value getLen() const { return len; }
|
||||
mlir::Value getBuffer() const { return getAddr(); }
|
||||
|
||||
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
|
||||
const CharBoxValue &);
|
||||
LLVM_DUMP_METHOD void dump() const { llvm::errs() << *this; }
|
||||
|
||||
protected:
|
||||
mlir::Value len;
|
||||
};
|
||||
|
||||
/// Abstract base class.
|
||||
/// Expressions of type array have at minimum a shape. These expressions may
|
||||
/// have lbound attributes (dynamic values) that affect the interpretation of
|
||||
/// indexing expressions.
|
||||
class AbstractArrayBox {
|
||||
public:
|
||||
AbstractArrayBox() = default;
|
||||
AbstractArrayBox(llvm::ArrayRef<mlir::Value> extents,
|
||||
llvm::ArrayRef<mlir::Value> lbounds)
|
||||
: extents{extents.begin(), extents.end()}, lbounds{lbounds.begin(),
|
||||
lbounds.end()} {}
|
||||
|
||||
// Every array has extents that describe its shape.
|
||||
const llvm::SmallVectorImpl<mlir::Value> &getExtents() const {
|
||||
return extents;
|
||||
}
|
||||
|
||||
// An array expression may have user-defined lower bound values.
|
||||
// If this vector is empty, the default in all dimensions in `1`.
|
||||
const llvm::SmallVectorImpl<mlir::Value> &getLBounds() const {
|
||||
return lbounds;
|
||||
}
|
||||
|
||||
bool lboundsAllOne() const { return lbounds.empty(); }
|
||||
|
||||
protected:
|
||||
llvm::SmallVector<mlir::Value, 4> extents;
|
||||
llvm::SmallVector<mlir::Value, 4> lbounds;
|
||||
};
|
||||
|
||||
/// Expressions with rank > 0 have extents. They may also have lbounds that are
|
||||
/// not 1.
|
||||
class ArrayBoxValue : public AbstractBox, public AbstractArrayBox {
|
||||
public:
|
||||
ArrayBoxValue(mlir::Value addr, llvm::ArrayRef<mlir::Value> extents,
|
||||
llvm::ArrayRef<mlir::Value> lbounds = {})
|
||||
: AbstractBox{addr}, AbstractArrayBox{extents, lbounds} {}
|
||||
|
||||
ArrayBoxValue clone(mlir::Value newBase) const {
|
||||
return {newBase, extents, lbounds};
|
||||
}
|
||||
|
||||
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
|
||||
const ArrayBoxValue &);
|
||||
LLVM_DUMP_METHOD void dump() const { operator<<(llvm::errs(), *this); }
|
||||
};
|
||||
|
||||
/// Expressions of type CHARACTER and with rank > 0.
|
||||
class CharArrayBoxValue : public CharBoxValue, public AbstractArrayBox {
|
||||
public:
|
||||
CharArrayBoxValue(mlir::Value addr, mlir::Value len,
|
||||
llvm::ArrayRef<mlir::Value> extents,
|
||||
llvm::ArrayRef<mlir::Value> lbounds = {})
|
||||
: CharBoxValue{addr, len}, AbstractArrayBox{extents, lbounds} {}
|
||||
|
||||
CharArrayBoxValue clone(mlir::Value newBase) const {
|
||||
return {newBase, len, extents, lbounds};
|
||||
}
|
||||
|
||||
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
|
||||
const CharArrayBoxValue &);
|
||||
LLVM_DUMP_METHOD void dump() const { operator<<(llvm::errs(), *this); }
|
||||
};
|
||||
|
||||
/// Expressions that are procedure POINTERs may need a set of references to
|
||||
/// variables in the host scope.
|
||||
class ProcBoxValue : public AbstractBox {
|
||||
public:
|
||||
ProcBoxValue(mlir::Value addr, mlir::Value context)
|
||||
: AbstractBox{addr}, hostContext{context} {}
|
||||
|
||||
ProcBoxValue clone(mlir::Value newBase) const {
|
||||
return {newBase, hostContext};
|
||||
}
|
||||
|
||||
mlir::Value getHostContext() const { return hostContext; }
|
||||
|
||||
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
|
||||
const ProcBoxValue &);
|
||||
LLVM_DUMP_METHOD void dump() const { operator<<(llvm::errs(), *this); }
|
||||
|
||||
protected:
|
||||
mlir::Value hostContext;
|
||||
};
|
||||
|
||||
/// In the generalized form, a boxed value can have a dynamic size, be an array
|
||||
/// with dynamic extents and lbounds, and take dynamic type parameters.
|
||||
class BoxValue : public AbstractBox, public AbstractArrayBox {
|
||||
public:
|
||||
BoxValue(mlir::Value addr) : AbstractBox{addr}, AbstractArrayBox{} {}
|
||||
BoxValue(mlir::Value addr, mlir::Value len)
|
||||
: AbstractBox{addr}, AbstractArrayBox{}, len{len} {}
|
||||
BoxValue(mlir::Value addr, llvm::ArrayRef<mlir::Value> extents,
|
||||
llvm::ArrayRef<mlir::Value> lbounds = {})
|
||||
: AbstractBox{addr}, AbstractArrayBox{extents, lbounds} {}
|
||||
BoxValue(mlir::Value addr, mlir::Value len,
|
||||
llvm::ArrayRef<mlir::Value> params,
|
||||
llvm::ArrayRef<mlir::Value> extents,
|
||||
llvm::ArrayRef<mlir::Value> lbounds = {})
|
||||
: AbstractBox{addr}, AbstractArrayBox{extents, lbounds}, len{len},
|
||||
params{params.begin(), params.end()} {}
|
||||
|
||||
BoxValue clone(mlir::Value newBase) const {
|
||||
return {newBase, len, params, extents, lbounds};
|
||||
}
|
||||
|
||||
mlir::Value getLen() const { return len; }
|
||||
const llvm::SmallVectorImpl<mlir::Value> &getLenTypeParams() const {
|
||||
return params;
|
||||
}
|
||||
|
||||
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &, const BoxValue &);
|
||||
LLVM_DUMP_METHOD void dump() const { operator<<(llvm::errs(), *this); }
|
||||
|
||||
protected:
|
||||
mlir::Value len;
|
||||
llvm::SmallVector<mlir::Value, 2> params;
|
||||
};
|
||||
|
||||
/// Used for triple notation (array slices)
|
||||
using RangeBoxValue = std::tuple<mlir::Value, mlir::Value, mlir::Value>;
|
||||
|
||||
class ExtendedValue;
|
||||
|
||||
mlir::Value getBase(const ExtendedValue &exv);
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &, const ExtendedValue &);
|
||||
ExtendedValue substBase(const ExtendedValue &exv, mlir::Value base);
|
||||
|
||||
/// An extended value is a box of values pertaining to a discrete entity. It is
|
||||
/// used in lowering to track all the runtime values related to an entity. For
|
||||
/// example, an entity may have an address in memory that contains its value(s)
|
||||
/// as well as various attribute values that describe the shape and starting
|
||||
/// indices if it is an array entity.
|
||||
class ExtendedValue {
|
||||
public:
|
||||
template <typename A>
|
||||
constexpr ExtendedValue(A &&box) : box{std::forward<A>(box)} {}
|
||||
|
||||
constexpr const CharBoxValue *getCharBox() const {
|
||||
return std::get_if<CharBoxValue>(&box);
|
||||
}
|
||||
|
||||
constexpr const UnboxedValue *getUnboxed() const {
|
||||
return std::get_if<UnboxedValue>(&box);
|
||||
}
|
||||
|
||||
/// LLVM style debugging of extended values
|
||||
LLVM_DUMP_METHOD void dump() const { llvm::errs() << *this << '\n'; }
|
||||
|
||||
friend llvm::raw_ostream &operator<<(llvm::raw_ostream &,
|
||||
const ExtendedValue &);
|
||||
friend mlir::Value getBase(const ExtendedValue &exv);
|
||||
friend ExtendedValue substBase(const ExtendedValue &exv, mlir::Value base);
|
||||
|
||||
private:
|
||||
std::variant<UnboxedValue, CharBoxValue, ArrayBoxValue, CharArrayBoxValue,
|
||||
BoxValue, ProcBoxValue>
|
||||
box;
|
||||
};
|
||||
} // namespace fir
|
||||
|
||||
#endif // LOWER_SUPPORT_BOXVALUE_H
|
|
@ -22,7 +22,7 @@ namespace fir::factory {
|
|||
class CharacterExprHelper {
|
||||
public:
|
||||
/// Constructor.
|
||||
explicit CharacterExprHelper(FirOpBuilder &builder, mlir::Location loc)
|
||||
explicit CharacterExprHelper(fir::FirOpBuilder &builder, mlir::Location loc)
|
||||
: builder{builder}, loc{loc} {}
|
||||
CharacterExprHelper(const CharacterExprHelper &) = delete;
|
||||
|
||||
|
|
|
@ -6,9 +6,7 @@ add_flang_library(FortranLower
|
|||
Coarray.cpp
|
||||
ComplexExpr.cpp
|
||||
ConvertType.cpp
|
||||
ConvertExpr.cpp
|
||||
DoLoopHelper.cpp
|
||||
FIRBuilder.cpp
|
||||
IntrinsicCall.cpp
|
||||
IO.cpp
|
||||
Mangler.cpp
|
||||
|
|
|
@ -180,7 +180,7 @@ void Fortran::lower::CharacterExprHelper::createCopy(
|
|||
const fir::CharBoxValue &dest, const fir::CharBoxValue &src,
|
||||
mlir::Value count) {
|
||||
Fortran::lower::DoLoopHelper{builder, loc}.createLoop(
|
||||
count, [&](Fortran::lower::FirOpBuilder &, mlir::Value index) {
|
||||
count, [&](fir::FirOpBuilder &, mlir::Value index) {
|
||||
auto charVal = createLoadCharAt(src, index);
|
||||
createStoreCharAt(dest, index, charVal);
|
||||
});
|
||||
|
@ -192,7 +192,7 @@ void Fortran::lower::CharacterExprHelper::createPadding(
|
|||
// Always create the loop, if upper < lower, no iteration will be
|
||||
// executed.
|
||||
Fortran::lower::DoLoopHelper{builder, loc}.createLoop(
|
||||
lower, upper, [&](Fortran::lower::FirOpBuilder &, mlir::Value index) {
|
||||
lower, upper, [&](fir::FirOpBuilder &, mlir::Value index) {
|
||||
createStoreCharAt(str, index, blank);
|
||||
});
|
||||
}
|
||||
|
@ -202,7 +202,8 @@ 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, llvm::StringRef{}, sizes);
|
||||
auto ref = builder.allocateLocal(loc, type, "", ".chrtmp",
|
||||
/*shape=*/llvm::None, sizes);
|
||||
return {ref, len};
|
||||
}
|
||||
|
||||
|
@ -287,7 +288,7 @@ fir::CharBoxValue Fortran::lower::CharacterExprHelper::createConcatenate(
|
|||
builder.createConvert(loc, builder.getIndexType(), lhs.getLen());
|
||||
Fortran::lower::DoLoopHelper{builder, loc}.createLoop(
|
||||
lhs.getLen(), upperBound, one,
|
||||
[&](Fortran::lower::FirOpBuilder &bldr, mlir::Value index) {
|
||||
[&](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);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "RTBuilder.h"
|
||||
#include "flang/Lower/Bridge.h"
|
||||
#include "flang/Lower/CharacterExpr.h"
|
||||
#include "flang/Lower/FIRBuilder.h"
|
||||
#include "flang/Optimizer/Builder/FIRBuilder.h"
|
||||
#include "flang/Runtime/character.h"
|
||||
#include "mlir/Dialect/StandardOps/IR/Ops.h"
|
||||
|
||||
|
@ -55,7 +55,7 @@ inline int64_t getLength(mlir::Type argTy) {
|
|||
/// Get (or generate) the MLIR FuncOp for a given runtime function.
|
||||
template <typename E>
|
||||
static mlir::FuncOp getRuntimeFunc(mlir::Location loc,
|
||||
Fortran::lower::FirOpBuilder &builder) {
|
||||
fir::FirOpBuilder &builder) {
|
||||
auto name = getName<E>();
|
||||
auto func = builder.getNamedFunction(name);
|
||||
if (func)
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "flang/Lower/Coarray.h"
|
||||
#include "SymbolMap.h"
|
||||
#include "flang/Lower/AbstractConverter.h"
|
||||
#include "flang/Lower/FIRBuilder.h"
|
||||
#include "flang/Optimizer/Builder/FIRBuilder.h"
|
||||
#include "flang/Parser/parse-tree.h"
|
||||
#include "flang/Semantics/expression.h"
|
||||
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
//===-- ConvertExpr.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/Common/idioms.h"
|
||||
#include "flang/Lower/IntrinsicCall.h"
|
||||
#include "flang/Lower/Support/BoxValue.h"
|
||||
|
||||
mlir::Value fir::getBase(const fir::ExtendedValue &ex) {
|
||||
return std::visit(Fortran::common::visitors{
|
||||
[](const fir::UnboxedValue &x) { return x; },
|
||||
[](const auto &x) { return x.getAddr(); },
|
||||
},
|
||||
ex.box);
|
||||
}
|
||||
|
||||
llvm::raw_ostream &fir::operator<<(llvm::raw_ostream &os,
|
||||
const fir::CharBoxValue &box) {
|
||||
os << "boxchar { addr: " << box.getAddr() << ", len: " << box.getLen()
|
||||
<< " }";
|
||||
return os;
|
||||
}
|
||||
|
||||
llvm::raw_ostream &fir::operator<<(llvm::raw_ostream &os,
|
||||
const fir::ArrayBoxValue &box) {
|
||||
os << "boxarray { addr: " << box.getAddr();
|
||||
if (box.getLBounds().size()) {
|
||||
os << ", lbounds: [";
|
||||
llvm::interleaveComma(box.getLBounds(), os);
|
||||
os << "]";
|
||||
} else {
|
||||
os << ", lbounds: all-ones";
|
||||
}
|
||||
os << ", shape: [";
|
||||
llvm::interleaveComma(box.getExtents(), os);
|
||||
os << "]}";
|
||||
return os;
|
||||
}
|
||||
|
||||
llvm::raw_ostream &fir::operator<<(llvm::raw_ostream &os,
|
||||
const fir::CharArrayBoxValue &box) {
|
||||
os << "boxchararray { addr: " << box.getAddr() << ", len : " << box.getLen();
|
||||
if (box.getLBounds().size()) {
|
||||
os << ", lbounds: [";
|
||||
llvm::interleaveComma(box.getLBounds(), os);
|
||||
os << "]";
|
||||
} else {
|
||||
os << " lbounds: all-ones";
|
||||
}
|
||||
os << ", shape: [";
|
||||
llvm::interleaveComma(box.getExtents(), os);
|
||||
os << "]}";
|
||||
return os;
|
||||
}
|
||||
|
||||
llvm::raw_ostream &fir::operator<<(llvm::raw_ostream &os,
|
||||
const fir::BoxValue &box) {
|
||||
os << "box { addr: " << box.getAddr();
|
||||
if (box.getLen())
|
||||
os << ", size: " << box.getLen();
|
||||
if (box.params.size()) {
|
||||
os << ", type params: [";
|
||||
llvm::interleaveComma(box.params, os);
|
||||
os << "]";
|
||||
}
|
||||
if (box.getLBounds().size()) {
|
||||
os << ", lbounds: [";
|
||||
llvm::interleaveComma(box.getLBounds(), os);
|
||||
os << "]";
|
||||
}
|
||||
if (box.getExtents().size()) {
|
||||
os << ", shape: [";
|
||||
llvm::interleaveComma(box.getExtents(), os);
|
||||
os << "]";
|
||||
}
|
||||
os << "}";
|
||||
return os;
|
||||
}
|
||||
|
||||
llvm::raw_ostream &fir::operator<<(llvm::raw_ostream &os,
|
||||
const fir::ProcBoxValue &box) {
|
||||
os << "boxproc: { addr: " << box.getAddr() << ", context: " << box.hostContext
|
||||
<< "}";
|
||||
return os;
|
||||
}
|
||||
|
||||
llvm::raw_ostream &fir::operator<<(llvm::raw_ostream &os,
|
||||
const fir::ExtendedValue &ex) {
|
||||
std::visit([&](const auto &value) { os << value; }, ex.box);
|
||||
return os;
|
||||
}
|
|
@ -1,187 +0,0 @@
|
|||
//===-- FIRBuilder.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/FIRBuilder.h"
|
||||
#include "SymbolMap.h"
|
||||
#include "flang/Lower/Bridge.h"
|
||||
#include "flang/Lower/ComplexExpr.h"
|
||||
#include "flang/Lower/ConvertType.h"
|
||||
#include "flang/Optimizer/Dialect/FIROpsSupport.h"
|
||||
#include "flang/Semantics/symbol.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
mlir::FuncOp Fortran::lower::FirOpBuilder::createFunction(
|
||||
mlir::Location loc, mlir::ModuleOp module, llvm::StringRef name,
|
||||
mlir::FunctionType ty) {
|
||||
return fir::createFuncOp(loc, module, name, ty);
|
||||
}
|
||||
|
||||
mlir::FuncOp
|
||||
Fortran::lower::FirOpBuilder::getNamedFunction(mlir::ModuleOp modOp,
|
||||
llvm::StringRef name) {
|
||||
return modOp.lookupSymbol<mlir::FuncOp>(name);
|
||||
}
|
||||
|
||||
fir::GlobalOp
|
||||
Fortran::lower::FirOpBuilder::getNamedGlobal(mlir::ModuleOp modOp,
|
||||
llvm::StringRef name) {
|
||||
return modOp.lookupSymbol<fir::GlobalOp>(name);
|
||||
}
|
||||
|
||||
mlir::Type Fortran::lower::FirOpBuilder::getRefType(mlir::Type eleTy) {
|
||||
assert(!eleTy.isa<fir::ReferenceType>());
|
||||
return fir::ReferenceType::get(eleTy);
|
||||
}
|
||||
|
||||
mlir::Value
|
||||
Fortran::lower::FirOpBuilder::createNullConstant(mlir::Location loc) {
|
||||
auto indexType = getIndexType();
|
||||
auto zero = createIntegerConstant(loc, indexType, 0);
|
||||
auto noneRefType = getRefType(getNoneType());
|
||||
return createConvert(loc, noneRefType, zero);
|
||||
}
|
||||
|
||||
mlir::Value Fortran::lower::FirOpBuilder::createIntegerConstant(
|
||||
mlir::Location loc, mlir::Type ty, std::int64_t cst) {
|
||||
return create<mlir::arith::ConstantOp>(loc, ty, getIntegerAttr(ty, cst));
|
||||
}
|
||||
|
||||
mlir::Value Fortran::lower::FirOpBuilder::createRealConstant(
|
||||
mlir::Location loc, mlir::Type realType, const llvm::APFloat &val) {
|
||||
return create<mlir::arith::ConstantOp>(loc, realType,
|
||||
getFloatAttr(realType, val));
|
||||
}
|
||||
|
||||
mlir::Value
|
||||
Fortran::lower::FirOpBuilder::createRealZeroConstant(mlir::Location loc,
|
||||
mlir::Type realType) {
|
||||
mlir::Attribute attr;
|
||||
if (auto firType = realType.dyn_cast<fir::RealType>()) {
|
||||
attr = getFloatAttr(
|
||||
realType,
|
||||
llvm::APFloat(kindMap.getFloatSemantics(firType.getFKind()), 0));
|
||||
} else { // mlir::FloatType.
|
||||
attr = getZeroAttr(realType);
|
||||
}
|
||||
return create<mlir::arith::ConstantOp>(loc, realType, attr);
|
||||
}
|
||||
|
||||
mlir::Value Fortran::lower::FirOpBuilder::allocateLocal(
|
||||
mlir::Location loc, mlir::Type ty, llvm::StringRef nm,
|
||||
llvm::ArrayRef<mlir::Value> shape, bool asTarget) {
|
||||
llvm::SmallVector<mlir::Value, 8> indices;
|
||||
auto idxTy = getIndexType();
|
||||
llvm::for_each(shape, [&](mlir::Value sh) {
|
||||
indices.push_back(createConvert(loc, idxTy, sh));
|
||||
});
|
||||
llvm::SmallVector<mlir::NamedAttribute, 2> attrs;
|
||||
if (asTarget)
|
||||
attrs.emplace_back(mlir::StringAttr::get(getContext(), "target"),
|
||||
getUnitAttr());
|
||||
return create<fir::AllocaOp>(loc, ty, nm, llvm::None, indices, attrs);
|
||||
}
|
||||
|
||||
/// Create a temporary variable on the stack. Anonymous temporaries have no
|
||||
/// `name` value.
|
||||
mlir::Value Fortran::lower::FirOpBuilder::createTemporary(
|
||||
mlir::Location loc, mlir::Type type, llvm::StringRef name,
|
||||
llvm::ArrayRef<mlir::Value> shape) {
|
||||
auto insPt = saveInsertionPoint();
|
||||
if (shape.empty())
|
||||
setInsertionPointToStart(getEntryBlock());
|
||||
else
|
||||
setInsertionPointAfter(shape.back().getDefiningOp());
|
||||
assert(!type.isa<fir::ReferenceType>() && "cannot be a reference");
|
||||
auto ae = create<fir::AllocaOp>(loc, type, name, llvm::None, shape);
|
||||
restoreInsertionPoint(insPt);
|
||||
return ae;
|
||||
}
|
||||
|
||||
/// Create a global variable in the (read-only) data section. A global variable
|
||||
/// must have a unique name to identify and reference it.
|
||||
fir::GlobalOp Fortran::lower::FirOpBuilder::createGlobal(
|
||||
mlir::Location loc, mlir::Type type, llvm::StringRef name,
|
||||
mlir::StringAttr linkage, mlir::Attribute value, bool isConst) {
|
||||
auto module = getModule();
|
||||
auto insertPt = saveInsertionPoint();
|
||||
if (auto glob = module.lookupSymbol<fir::GlobalOp>(name))
|
||||
return glob;
|
||||
setInsertionPoint(module.getBody()->getTerminator());
|
||||
auto glob = create<fir::GlobalOp>(loc, name, isConst, type, value, linkage);
|
||||
restoreInsertionPoint(insertPt);
|
||||
return glob;
|
||||
}
|
||||
|
||||
fir::GlobalOp Fortran::lower::FirOpBuilder::createGlobal(
|
||||
mlir::Location loc, mlir::Type type, llvm::StringRef name, bool isConst,
|
||||
std::function<void(FirOpBuilder &)> bodyBuilder, mlir::StringAttr linkage) {
|
||||
auto module = getModule();
|
||||
auto insertPt = saveInsertionPoint();
|
||||
if (auto glob = module.lookupSymbol<fir::GlobalOp>(name))
|
||||
return glob;
|
||||
setInsertionPoint(module.getBody()->getTerminator());
|
||||
auto glob = create<fir::GlobalOp>(loc, name, isConst, type, mlir::Attribute{},
|
||||
linkage);
|
||||
auto ®ion = glob.getRegion();
|
||||
region.push_back(new mlir::Block);
|
||||
auto &block = glob.getRegion().back();
|
||||
setInsertionPointToStart(&block);
|
||||
bodyBuilder(*this);
|
||||
restoreInsertionPoint(insertPt);
|
||||
return glob;
|
||||
}
|
||||
|
||||
mlir::Value Fortran::lower::FirOpBuilder::convertWithSemantics(
|
||||
mlir::Location loc, mlir::Type toTy, mlir::Value val) {
|
||||
assert(toTy && "store location must be typed");
|
||||
auto fromTy = val.getType();
|
||||
if (fromTy == toTy)
|
||||
return val;
|
||||
// FIXME: add a fir::is_integer() test
|
||||
ComplexExprHelper helper{*this, loc};
|
||||
if ((fir::isa_real(fromTy) || fromTy.isSignlessInteger()) &&
|
||||
fir::isa_complex(toTy)) {
|
||||
// imaginary part is zero
|
||||
auto eleTy = helper.getComplexPartType(toTy);
|
||||
auto cast = createConvert(loc, eleTy, val);
|
||||
llvm::APFloat zero{
|
||||
kindMap.getFloatSemantics(toTy.cast<fir::ComplexType>().getFKind()), 0};
|
||||
auto imag = createRealConstant(loc, eleTy, zero);
|
||||
return helper.createComplex(toTy, cast, imag);
|
||||
}
|
||||
// FIXME: add a fir::is_integer() test
|
||||
if (fir::isa_complex(fromTy) &&
|
||||
(toTy.isSignlessInteger() || fir::isa_real(toTy))) {
|
||||
// drop the imaginary part
|
||||
auto rp = helper.extractComplexPart(val, /*isImagPart=*/false);
|
||||
return createConvert(loc, toTy, rp);
|
||||
}
|
||||
return createConvert(loc, toTy, val);
|
||||
}
|
||||
|
||||
mlir::Value Fortran::lower::FirOpBuilder::createConvert(mlir::Location loc,
|
||||
mlir::Type toTy,
|
||||
mlir::Value val) {
|
||||
if (val.getType() != toTy)
|
||||
return create<fir::ConvertOp>(loc, toTy, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
fir::StringLitOp Fortran::lower::FirOpBuilder::createStringLit(
|
||||
mlir::Location loc, mlir::Type eleTy, llvm::StringRef data) {
|
||||
auto strAttr = mlir::StringAttr::get(getContext(), data);
|
||||
auto valTag = mlir::StringAttr::get(getContext(), fir::StringLitOp::value());
|
||||
mlir::NamedAttribute dataAttr(valTag, strAttr);
|
||||
auto sizeTag = mlir::StringAttr::get(getContext(), fir::StringLitOp::size());
|
||||
mlir::NamedAttribute sizeAttr(sizeTag, getI64IntegerAttr(data.size()));
|
||||
llvm::SmallVector<mlir::NamedAttribute, 2> attrs{dataAttr, sizeAttr};
|
||||
auto arrTy =
|
||||
fir::SequenceType::get(fir::SequenceType::Shape(1, data.size()), eleTy);
|
||||
return create<fir::StringLitOp>(loc, llvm::ArrayRef<mlir::Type>{arrTy},
|
||||
llvm::None, attrs);
|
||||
}
|
|
@ -11,10 +11,10 @@
|
|||
#include "flang/Lower/Bridge.h"
|
||||
#include "flang/Lower/CharacterExpr.h"
|
||||
#include "flang/Lower/ComplexExpr.h"
|
||||
#include "flang/Lower/FIRBuilder.h"
|
||||
#include "flang/Lower/PFTBuilder.h"
|
||||
#include "flang/Lower/Runtime.h"
|
||||
#include "flang/Lower/Utils.h"
|
||||
#include "flang/Optimizer/Builder/FIRBuilder.h"
|
||||
#include "flang/Parser/parse-tree.h"
|
||||
#include "flang/Runtime/io-api.h"
|
||||
#include "flang/Semantics/tools.h"
|
||||
|
@ -114,7 +114,7 @@ inline int64_t getLength(mlir::Type argTy) {
|
|||
/// Get (or generate) the MLIR FuncOp for a given IO runtime function.
|
||||
template <typename E>
|
||||
static mlir::FuncOp getIORuntimeFunc(mlir::Location loc,
|
||||
Fortran::lower::FirOpBuilder &builder) {
|
||||
fir::FirOpBuilder &builder) {
|
||||
auto name = getName<E>();
|
||||
auto func = builder.getNamedFunction(name);
|
||||
if (func)
|
||||
|
@ -162,7 +162,7 @@ static mlir::Value genEndIO(Fortran::lower::AbstractConverter &converter,
|
|||
/// If a call returns `ok==false`, further suboperation calls for an I/O
|
||||
/// statement will be skipped. This may generate branch heavy, deeply nested
|
||||
/// conditionals for I/O statements with a large number of suboperations.
|
||||
static void makeNextConditionalOn(Fortran::lower::FirOpBuilder &builder,
|
||||
static void makeNextConditionalOn(fir::FirOpBuilder &builder,
|
||||
mlir::Location loc,
|
||||
mlir::OpBuilder::InsertPoint &insertPt,
|
||||
bool checkResult, mlir::Value ok,
|
||||
|
@ -190,8 +190,7 @@ static void genIoLoop(Fortran::lower::AbstractConverter &converter,
|
|||
|
||||
/// Get the OutputXyz routine to output a value of the given type.
|
||||
static mlir::FuncOp getOutputFunc(mlir::Location loc,
|
||||
Fortran::lower::FirOpBuilder &builder,
|
||||
mlir::Type type) {
|
||||
fir::FirOpBuilder &builder, mlir::Type type) {
|
||||
if (auto ty = type.dyn_cast<mlir::IntegerType>())
|
||||
return ty.getWidth() == 1
|
||||
? getIORuntimeFunc<mkIOKey(OutputLogical)>(loc, builder)
|
||||
|
@ -261,8 +260,7 @@ genOutputItemList(Fortran::lower::AbstractConverter &converter,
|
|||
}
|
||||
|
||||
/// Get the InputXyz routine to input a value of the given type.
|
||||
static mlir::FuncOp getInputFunc(mlir::Location loc,
|
||||
Fortran::lower::FirOpBuilder &builder,
|
||||
static mlir::FuncOp getInputFunc(mlir::Location loc, fir::FirOpBuilder &builder,
|
||||
mlir::Type type) {
|
||||
if (auto ty = type.dyn_cast<mlir::IntegerType>())
|
||||
return ty.getWidth() == 1
|
||||
|
@ -429,27 +427,27 @@ static void genIoLoop(Fortran::lower::AbstractConverter &converter,
|
|||
// Default argument generation.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static mlir::Value getDefaultFilename(Fortran::lower::FirOpBuilder &builder,
|
||||
static mlir::Value getDefaultFilename(fir::FirOpBuilder &builder,
|
||||
mlir::Location loc, mlir::Type toType) {
|
||||
mlir::Value null = builder.create<mlir::arith::ConstantOp>(
|
||||
loc, builder.getI64IntegerAttr(0));
|
||||
return builder.createConvert(loc, toType, null);
|
||||
}
|
||||
|
||||
static mlir::Value getDefaultLineNo(Fortran::lower::FirOpBuilder &builder,
|
||||
static mlir::Value getDefaultLineNo(fir::FirOpBuilder &builder,
|
||||
mlir::Location loc, mlir::Type toType) {
|
||||
return builder.create<mlir::arith::ConstantOp>(
|
||||
loc, builder.getIntegerAttr(toType, 0));
|
||||
}
|
||||
|
||||
static mlir::Value getDefaultScratch(Fortran::lower::FirOpBuilder &builder,
|
||||
static mlir::Value getDefaultScratch(fir::FirOpBuilder &builder,
|
||||
mlir::Location loc, mlir::Type toType) {
|
||||
mlir::Value null = builder.create<mlir::arith::ConstantOp>(
|
||||
loc, builder.getI64IntegerAttr(0));
|
||||
return builder.createConvert(loc, toType, null);
|
||||
}
|
||||
|
||||
static mlir::Value getDefaultScratchLen(Fortran::lower::FirOpBuilder &builder,
|
||||
static mlir::Value getDefaultScratchLen(fir::FirOpBuilder &builder,
|
||||
mlir::Location loc, mlir::Type toType) {
|
||||
return builder.create<mlir::arith::ConstantOp>(
|
||||
loc, builder.getIntegerAttr(toType, 0));
|
||||
|
@ -488,8 +486,7 @@ lowerSourceTextAsStringLit(Fortran::lower::AbstractConverter &converter,
|
|||
text = text.drop_front(text.find('('));
|
||||
text = text.take_front(text.rfind(')') + 1);
|
||||
auto &builder = converter.getFirOpBuilder();
|
||||
auto lit = builder.createStringLit(
|
||||
loc, /*FIXME*/ fir::CharacterType::get(builder.getContext(), 1, 1), text);
|
||||
auto lit = builder.createStringLitOp(loc, text);
|
||||
auto data =
|
||||
Fortran::lower::CharacterExprHelper{builder, loc}.materializeCharacter(
|
||||
lit);
|
||||
|
@ -1149,10 +1146,10 @@ Fortran::lower::genWaitStatement(Fortran::lower::AbstractConverter &converter,
|
|||
|
||||
// Determine the correct BeginXyz{In|Out}put api to invoke.
|
||||
template <bool isInput>
|
||||
mlir::FuncOp getBeginDataTransfer(mlir::Location loc, FirOpBuilder &builder,
|
||||
bool isFormatted, bool isList, bool isIntern,
|
||||
bool isOtherIntern, bool isAsynch,
|
||||
bool isNml) {
|
||||
mlir::FuncOp
|
||||
getBeginDataTransfer(mlir::Location loc, fir::FirOpBuilder &builder,
|
||||
bool isFormatted, bool isList, bool isIntern,
|
||||
bool isOtherIntern, bool isAsynch, bool isNml) {
|
||||
if constexpr (isInput) {
|
||||
if (isAsynch)
|
||||
return getIORuntimeFunc<mkIOKey(BeginAsynchronousInput)>(loc, builder);
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
#include "flang/Lower/CharacterExpr.h"
|
||||
#include "flang/Lower/ComplexExpr.h"
|
||||
#include "flang/Lower/ConvertType.h"
|
||||
#include "flang/Lower/FIRBuilder.h"
|
||||
#include "flang/Lower/Mangler.h"
|
||||
#include "flang/Lower/Runtime.h"
|
||||
#include "flang/Optimizer/Builder/FIRBuilder.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include <algorithm>
|
||||
|
@ -91,8 +91,7 @@ enum class ExtremumBehavior {
|
|||
struct IntrinsicLibrary {
|
||||
|
||||
// Constructors.
|
||||
explicit IntrinsicLibrary(Fortran::lower::FirOpBuilder &builder,
|
||||
mlir::Location loc)
|
||||
explicit IntrinsicLibrary(fir::FirOpBuilder &builder, mlir::Location loc)
|
||||
: builder{builder}, loc{loc} {}
|
||||
IntrinsicLibrary() = delete;
|
||||
IntrinsicLibrary(const IntrinsicLibrary &) = delete;
|
||||
|
@ -113,9 +112,8 @@ struct IntrinsicLibrary {
|
|||
mlir::Value genRuntimeCall(llvm::StringRef name, mlir::Type,
|
||||
llvm::ArrayRef<mlir::Value>);
|
||||
|
||||
using RuntimeCallGenerator =
|
||||
std::function<mlir::Value(Fortran::lower::FirOpBuilder &, mlir::Location,
|
||||
llvm::ArrayRef<mlir::Value>)>;
|
||||
using RuntimeCallGenerator = std::function<mlir::Value(
|
||||
fir::FirOpBuilder &, mlir::Location, llvm::ArrayRef<mlir::Value>)>;
|
||||
RuntimeCallGenerator
|
||||
getRuntimeCallGenerator(llvm::StringRef name,
|
||||
mlir::FunctionType soughtFuncType);
|
||||
|
@ -193,7 +191,7 @@ struct IntrinsicLibrary {
|
|||
getUnrestrictedIntrinsicSymbolRefAttr(llvm::StringRef name,
|
||||
mlir::FunctionType signature);
|
||||
|
||||
Fortran::lower::FirOpBuilder &builder;
|
||||
fir::FirOpBuilder &builder;
|
||||
mlir::Location loc;
|
||||
};
|
||||
|
||||
|
@ -492,8 +490,7 @@ private:
|
|||
|
||||
/// Build mlir::FuncOp from runtime symbol description and add
|
||||
/// fir.runtime attribute.
|
||||
static mlir::FuncOp getFuncOp(mlir::Location loc,
|
||||
Fortran::lower::FirOpBuilder &builder,
|
||||
static mlir::FuncOp getFuncOp(mlir::Location loc, fir::FirOpBuilder &builder,
|
||||
const RuntimeFunction &runtime) {
|
||||
auto function = builder.addNamedFunction(
|
||||
loc, runtime.symbol, runtime.typeGenerator(builder.getContext()));
|
||||
|
@ -506,7 +503,7 @@ static mlir::FuncOp getFuncOp(mlir::Location loc,
|
|||
/// result.
|
||||
/// If nothing is found, the mlir::FuncOp will contain a nullptr.
|
||||
mlir::FuncOp searchFunctionInLibrary(
|
||||
mlir::Location loc, Fortran::lower::FirOpBuilder &builder,
|
||||
mlir::Location loc, fir::FirOpBuilder &builder,
|
||||
const Fortran::common::StaticMultimapView<RuntimeFunction> &lib,
|
||||
llvm::StringRef name, mlir::FunctionType funcType,
|
||||
const RuntimeFunction **bestNearMatch,
|
||||
|
@ -533,7 +530,7 @@ mlir::FuncOp searchFunctionInLibrary(
|
|||
/// the caller is responsible to insert argument and return value conversions.
|
||||
/// If nothing is found, the mlir::FuncOp will contain a nullptr.
|
||||
static mlir::FuncOp getRuntimeFunction(mlir::Location loc,
|
||||
Fortran::lower::FirOpBuilder &builder,
|
||||
fir::FirOpBuilder &builder,
|
||||
llvm::StringRef name,
|
||||
mlir::FunctionType funcType) {
|
||||
const RuntimeFunction *bestNearMatch = nullptr;
|
||||
|
@ -579,9 +576,9 @@ static mlir::FuncOp getRuntimeFunction(mlir::Location loc,
|
|||
}
|
||||
|
||||
/// Helpers to get function type from arguments and result type.
|
||||
static mlir::FunctionType
|
||||
getFunctionType(mlir::Type resultType, llvm::ArrayRef<mlir::Value> arguments,
|
||||
Fortran::lower::FirOpBuilder &builder) {
|
||||
static mlir::FunctionType getFunctionType(mlir::Type resultType,
|
||||
llvm::ArrayRef<mlir::Value> arguments,
|
||||
fir::FirOpBuilder &builder) {
|
||||
llvm::SmallVector<mlir::Type, 2> argumentTypes;
|
||||
for (auto &arg : arguments)
|
||||
argumentTypes.push_back(arg.getType());
|
||||
|
@ -591,8 +588,7 @@ getFunctionType(mlir::Type resultType, llvm::ArrayRef<mlir::Value> arguments,
|
|||
|
||||
/// fir::ExtendedValue to mlir::Value translation layer
|
||||
|
||||
fir::ExtendedValue toExtendedValue(mlir::Value val,
|
||||
Fortran::lower::FirOpBuilder &builder,
|
||||
fir::ExtendedValue toExtendedValue(mlir::Value val, fir::FirOpBuilder &builder,
|
||||
mlir::Location loc) {
|
||||
assert(val && "optional unhandled here");
|
||||
auto type = val.getType();
|
||||
|
@ -629,8 +625,8 @@ fir::ExtendedValue toExtendedValue(mlir::Value val,
|
|||
return base;
|
||||
}
|
||||
|
||||
mlir::Value toValue(const fir::ExtendedValue &val,
|
||||
Fortran::lower::FirOpBuilder &builder, mlir::Location loc) {
|
||||
mlir::Value toValue(const fir::ExtendedValue &val, fir::FirOpBuilder &builder,
|
||||
mlir::Location loc) {
|
||||
if (auto charBox = val.getCharBox()) {
|
||||
auto buffer = charBox->getBuffer();
|
||||
if (buffer.getType().isa<fir::BoxCharType>())
|
||||
|
@ -775,8 +771,8 @@ mlir::FuncOp IntrinsicLibrary::getWrapper(GeneratorType generator,
|
|||
// Create local context to emit code into the newly created function
|
||||
// This new function is not linked to a source file location, only
|
||||
// its calls will be.
|
||||
auto localBuilder = std::make_unique<Fortran::lower::FirOpBuilder>(
|
||||
function, builder.getKindMap());
|
||||
auto localBuilder =
|
||||
std::make_unique<fir::FirOpBuilder>(function, builder.getKindMap());
|
||||
localBuilder->setInsertionPointToStart(&function.front());
|
||||
// Location of code inside wrapper of the wrapper is independent from
|
||||
// the location of the intrinsic call.
|
||||
|
@ -876,9 +872,9 @@ IntrinsicLibrary::getRuntimeCallGenerator(llvm::StringRef name,
|
|||
actualFuncType.getNumInputs() == soughtFuncType.getNumInputs() &&
|
||||
actualFuncType.getNumResults() == 1 && "Bad intrinsic match");
|
||||
|
||||
return [funcOp, actualFuncType, soughtFuncType](
|
||||
Fortran::lower::FirOpBuilder &builder, mlir::Location loc,
|
||||
llvm::ArrayRef<mlir::Value> args) {
|
||||
return [funcOp, actualFuncType,
|
||||
soughtFuncType](fir::FirOpBuilder &builder, mlir::Location loc,
|
||||
llvm::ArrayRef<mlir::Value> args) {
|
||||
llvm::SmallVector<mlir::Value, 2> convertedArguments;
|
||||
for (const auto &pair : llvm::zip(actualFuncType.getInputs(), args))
|
||||
convertedArguments.push_back(
|
||||
|
@ -1197,7 +1193,7 @@ mlir::Value IntrinsicLibrary::genSign(mlir::Type resultType,
|
|||
// Compare two FIR values and return boolean result as i1.
|
||||
template <Extremum extremum, ExtremumBehavior behavior>
|
||||
static mlir::Value createExtremumCompare(mlir::Location loc,
|
||||
Fortran::lower::FirOpBuilder &builder,
|
||||
fir::FirOpBuilder &builder,
|
||||
mlir::Value left, mlir::Value right) {
|
||||
static constexpr auto integerPredicate =
|
||||
extremum == Extremum::Max ? mlir::arith::CmpIPredicate::sgt
|
||||
|
@ -1273,15 +1269,14 @@ mlir::Value IntrinsicLibrary::genExtremum(mlir::Type,
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
fir::ExtendedValue
|
||||
Fortran::lower::genIntrinsicCall(Fortran::lower::FirOpBuilder &builder,
|
||||
mlir::Location loc, llvm::StringRef name,
|
||||
mlir::Type resultType,
|
||||
Fortran::lower::genIntrinsicCall(fir::FirOpBuilder &builder, mlir::Location loc,
|
||||
llvm::StringRef name, mlir::Type resultType,
|
||||
llvm::ArrayRef<fir::ExtendedValue> args) {
|
||||
return IntrinsicLibrary{builder, loc}.genIntrinsicCall(name, resultType,
|
||||
args);
|
||||
}
|
||||
|
||||
mlir::Value Fortran::lower::genMax(Fortran::lower::FirOpBuilder &builder,
|
||||
mlir::Value Fortran::lower::genMax(fir::FirOpBuilder &builder,
|
||||
mlir::Location loc,
|
||||
llvm::ArrayRef<mlir::Value> args) {
|
||||
assert(args.size() > 0 && "max requires at least one argument");
|
||||
|
@ -1290,7 +1285,7 @@ mlir::Value Fortran::lower::genMax(Fortran::lower::FirOpBuilder &builder,
|
|||
args);
|
||||
}
|
||||
|
||||
mlir::Value Fortran::lower::genMin(Fortran::lower::FirOpBuilder &builder,
|
||||
mlir::Value Fortran::lower::genMin(fir::FirOpBuilder &builder,
|
||||
mlir::Location loc,
|
||||
llvm::ArrayRef<mlir::Value> args) {
|
||||
assert(args.size() > 0 && "min requires at least one argument");
|
||||
|
@ -1299,15 +1294,15 @@ mlir::Value Fortran::lower::genMin(Fortran::lower::FirOpBuilder &builder,
|
|||
args);
|
||||
}
|
||||
|
||||
mlir::Value Fortran::lower::genPow(Fortran::lower::FirOpBuilder &builder,
|
||||
mlir::Value Fortran::lower::genPow(fir::FirOpBuilder &builder,
|
||||
mlir::Location loc, mlir::Type type,
|
||||
mlir::Value x, mlir::Value y) {
|
||||
return IntrinsicLibrary{builder, loc}.genRuntimeCall("pow", type, {x, y});
|
||||
}
|
||||
|
||||
mlir::SymbolRefAttr Fortran::lower::getUnrestrictedIntrinsicSymbolRefAttr(
|
||||
Fortran::lower::FirOpBuilder &builder, mlir::Location loc,
|
||||
llvm::StringRef name, mlir::FunctionType signature) {
|
||||
fir::FirOpBuilder &builder, mlir::Location loc, llvm::StringRef name,
|
||||
mlir::FunctionType signature) {
|
||||
return IntrinsicLibrary{builder, loc}.getUnrestrictedIntrinsicSymbolRefAttr(
|
||||
name, signature);
|
||||
}
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
#include "flang/Lower/OpenACC.h"
|
||||
#include "flang/Common/idioms.h"
|
||||
#include "flang/Lower/Bridge.h"
|
||||
#include "flang/Lower/FIRBuilder.h"
|
||||
#include "flang/Lower/PFTBuilder.h"
|
||||
#include "flang/Lower/Support/BoxValue.h"
|
||||
#include "flang/Lower/Todo.h"
|
||||
#include "flang/Optimizer/Builder/BoxValue.h"
|
||||
#include "flang/Optimizer/Builder/FIRBuilder.h"
|
||||
#include "flang/Parser/parse-tree.h"
|
||||
#include "flang/Semantics/tools.h"
|
||||
#include "mlir/Dialect/OpenACC/OpenACC.h"
|
||||
|
@ -87,8 +87,7 @@ static void addOperand(SmallVectorImpl<Value> &operands,
|
|||
}
|
||||
|
||||
template <typename Op, typename Terminator>
|
||||
static Op createRegionOp(Fortran::lower::FirOpBuilder &builder,
|
||||
mlir::Location loc,
|
||||
static Op createRegionOp(fir::FirOpBuilder &builder, mlir::Location loc,
|
||||
const SmallVectorImpl<Value> &operands,
|
||||
const SmallVectorImpl<int32_t> &operandSegments) {
|
||||
llvm::ArrayRef<mlir::Type> argTy;
|
||||
|
@ -108,8 +107,7 @@ static Op createRegionOp(Fortran::lower::FirOpBuilder &builder,
|
|||
}
|
||||
|
||||
template <typename Op>
|
||||
static Op createSimpleOp(Fortran::lower::FirOpBuilder &builder,
|
||||
mlir::Location loc,
|
||||
static Op createSimpleOp(fir::FirOpBuilder &builder, mlir::Location loc,
|
||||
const SmallVectorImpl<Value> &operands,
|
||||
const SmallVectorImpl<int32_t> &operandSegments) {
|
||||
llvm::ArrayRef<mlir::Type> argTy;
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
#include "flang/Lower/OpenMP.h"
|
||||
#include "flang/Common/idioms.h"
|
||||
#include "flang/Lower/Bridge.h"
|
||||
#include "flang/Lower/FIRBuilder.h"
|
||||
#include "flang/Lower/PFTBuilder.h"
|
||||
#include "flang/Lower/Support/BoxValue.h"
|
||||
#include "flang/Lower/Todo.h"
|
||||
#include "flang/Optimizer/Builder/BoxValue.h"
|
||||
#include "flang/Optimizer/Builder/FIRBuilder.h"
|
||||
#include "flang/Parser/parse-tree.h"
|
||||
#include "flang/Semantics/tools.h"
|
||||
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
|
||||
|
@ -49,7 +49,7 @@ static void genObjectList(const Fortran::parser::OmpObjectList &objectList,
|
|||
}
|
||||
|
||||
template <typename Op>
|
||||
static void createBodyOfOp(Op &op, Fortran::lower::FirOpBuilder &firOpBuilder,
|
||||
static void createBodyOfOp(Op &op, fir::FirOpBuilder &firOpBuilder,
|
||||
mlir::Location &loc) {
|
||||
firOpBuilder.createBlock(&op.getRegion());
|
||||
auto &block = op.getRegion().back();
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include "flang/Common/idioms.h"
|
||||
#include "flang/Common/reference.h"
|
||||
#include "flang/Lower/Support/BoxValue.h"
|
||||
#include "flang/Optimizer/Builder/BoxValue.h"
|
||||
#include "flang/Optimizer/Dialect/FIRType.h"
|
||||
#include "flang/Semantics/symbol.h"
|
||||
#include "mlir/IR/Value.h"
|
||||
|
@ -216,16 +216,6 @@ public:
|
|||
makeSym(sym, SymbolBox::CharFullDim(value, len, extents, lbounds), force);
|
||||
}
|
||||
|
||||
/// Generalized derived type mapping.
|
||||
void addDerivedSymbol(semantics::SymbolRef sym, mlir::Value value,
|
||||
mlir::Value size, llvm::ArrayRef<mlir::Value> extents,
|
||||
llvm::ArrayRef<mlir::Value> lbounds,
|
||||
llvm::ArrayRef<mlir::Value> params,
|
||||
bool force = false) {
|
||||
makeSym(sym, SymbolBox::Derived(value, size, params, extents, lbounds),
|
||||
force);
|
||||
}
|
||||
|
||||
/// Find `symbol` and return its value if it appears in the current mappings.
|
||||
SymbolBox lookupSymbol(semantics::SymbolRef sym) {
|
||||
auto iter = symbolMap.find(&*sym);
|
||||
|
|
Loading…
Reference in New Issue