Jean Perier a5fb402838 [flang] add hlfir::FortranEntity class
Add hlfir::FortranEntity class and a first helper to convert it to
fir::ExtendedValue.

The hlfir::FortranEntity will be the core class of the new expression
lowering. It is conceptually very similar to what fir::ExtendedValue
is today, except that it is wrapping single mlir::Value: it holds the
SSA value for a lowered Fortran variable or expression value.

Differential Revision: https://reviews.llvm.org/D136428
2022-10-21 13:20:36 +02:00

100 lines
4.0 KiB
C++

//===-- HLFIRTools.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
//
//===----------------------------------------------------------------------===//
//
// Tools to manipulate HLFIR variable and expressions
//
//===----------------------------------------------------------------------===//
#include "flang/Optimizer/Builder/HLFIRTools.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/Todo.h"
// Return explicit extents. If the base is a fir.box, this won't read it to
// return the extents and will instead return an empty vector.
static llvm::SmallVector<mlir::Value>
getExplicitExtents(fir::FortranVariableOpInterface var) {
llvm::SmallVector<mlir::Value> result;
if (mlir::Value shape = var.getShape()) {
auto *shapeOp = shape.getDefiningOp();
if (auto s = mlir::dyn_cast_or_null<fir::ShapeOp>(shapeOp)) {
auto e = s.getExtents();
result.append(e.begin(), e.end());
} else if (auto s = mlir::dyn_cast_or_null<fir::ShapeShiftOp>(shapeOp)) {
auto e = s.getExtents();
result.append(e.begin(), e.end());
} else if (mlir::dyn_cast_or_null<fir::ShiftOp>(shapeOp)) {
return {};
} else {
TODO(var->getLoc(), "read fir.shape to get extents");
}
}
return result;
}
// Return explicit lower bounds. For pointers and allocatables, this will not
// read the lower bounds and instead return an empty vector.
static llvm::SmallVector<mlir::Value>
getExplicitLbounds(fir::FortranVariableOpInterface var) {
llvm::SmallVector<mlir::Value> result;
if (mlir::Value shape = var.getShape()) {
auto *shapeOp = shape.getDefiningOp();
if (auto s = mlir::dyn_cast_or_null<fir::ShapeOp>(shapeOp)) {
return {};
} else if (auto s = mlir::dyn_cast_or_null<fir::ShapeShiftOp>(shapeOp)) {
auto e = s.getOrigins();
result.append(e.begin(), e.end());
} else if (auto s = mlir::dyn_cast_or_null<fir::ShiftOp>(shapeOp)) {
auto e = s.getOrigins();
result.append(e.begin(), e.end());
} else {
TODO(var->getLoc(), "read fir.shape to get lower bounds");
}
}
return result;
}
static llvm::SmallVector<mlir::Value>
getExplicitTypeParams(fir::FortranVariableOpInterface var) {
llvm::SmallVector<mlir::Value> res;
mlir::OperandRange range = var.getExplicitTypeParams();
res.append(range.begin(), range.end());
return res;
}
std::pair<fir::ExtendedValue, llvm::Optional<hlfir::CleanupFunction>>
hlfir::translateToExtendedValue(mlir::Location loc, fir::FirOpBuilder &,
hlfir::FortranEntity entity) {
if (auto variable = entity.getIfVariable())
return {hlfir::translateToExtendedValue(variable), {}};
if (entity.getType().isa<hlfir::ExprType>())
TODO(loc, "hlfir.expr to fir::ExtendedValue"); // use hlfir.associate
return {{static_cast<mlir::Value>(entity)}, {}};
}
fir::ExtendedValue
hlfir::translateToExtendedValue(fir::FortranVariableOpInterface variable) {
if (variable.isPointer() || variable.isAllocatable())
TODO(variable->getLoc(), "pointer or allocatable "
"FortranVariableOpInterface to extendedValue");
if (variable.getBase().getType().isa<fir::BaseBoxType>())
return fir::BoxValue(variable.getBase(), getExplicitLbounds(variable),
getExplicitTypeParams(variable),
getExplicitExtents(variable));
if (variable.isCharacter()) {
if (variable.isArray())
return fir::CharArrayBoxValue(
variable.getBase(), variable.getExplicitCharLen(),
getExplicitExtents(variable), getExplicitLbounds(variable));
return fir::CharBoxValue(variable.getBase(), variable.getExplicitCharLen());
}
if (variable.isArray())
return fir::ArrayBoxValue(variable.getBase(), getExplicitExtents(variable),
getExplicitLbounds(variable));
return variable.getBase();
}