diff --git a/flang/lib/Lower/CMakeLists.txt b/flang/lib/Lower/CMakeLists.txt --- a/flang/lib/Lower/CMakeLists.txt +++ b/flang/lib/Lower/CMakeLists.txt @@ -7,6 +7,7 @@ Coarray.cpp ComplexExpr.cpp ConvertType.cpp + ConvertExpr.cpp DoLoopHelper.cpp FIRBuilder.cpp IntrinsicCall.cpp diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp new file mode 100644 --- /dev/null +++ b/flang/lib/Lower/ConvertExpr.cpp @@ -0,0 +1,95 @@ +//===-- 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; +} diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp --- a/flang/lib/Optimizer/Dialect/FIROps.cpp +++ b/flang/lib/Optimizer/Dialect/FIROps.cpp @@ -1395,15 +1395,28 @@ //===----------------------------------------------------------------------===// // WhereOp //===----------------------------------------------------------------------===// - void fir::WhereOp::build(mlir::OpBuilder &builder, OperationState &result, mlir::Value cond, bool withElseRegion) { + build(builder, result, llvm::None, cond, withElseRegion); +} + +void fir::WhereOp::build(mlir::OpBuilder &builder, OperationState &result, + mlir::TypeRange resultTypes, mlir::Value cond, + bool withElseRegion) { result.addOperands(cond); + result.addTypes(resultTypes); + mlir::Region *thenRegion = result.addRegion(); + thenRegion->push_back(new mlir::Block()); + if (resultTypes.empty()) + WhereOp::ensureTerminator(*thenRegion, builder, result.location); + mlir::Region *elseRegion = result.addRegion(); - WhereOp::ensureTerminator(*thenRegion, builder, result.location); - if (withElseRegion) - WhereOp::ensureTerminator(*elseRegion, builder, result.location); + if (withElseRegion) { + elseRegion->push_back(new mlir::Block()); + if (resultTypes.empty()) + WhereOp::ensureTerminator(*elseRegion, builder, result.location); + } } static mlir::ParseResult parseWhereOp(OpAsmParser &parser,