blob: a7c16d48083128446aafae4643f5fceae93da20a [file] [log] [blame]
//===-- MutableBox.h -- MutableBox utilities -----------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
//
//===----------------------------------------------------------------------===//
#ifndef FORTRAN_OPTIMIZER_BUILDER_MUTABLEBOX_H
#define FORTRAN_OPTIMIZER_BUILDER_MUTABLEBOX_H
#include "llvm/ADT/StringRef.h"
namespace mlir {
class Value;
class ValueRange;
class Type;
class Location;
} // namespace mlir
namespace fir {
class FirOpBuilder;
class MutableBoxValue;
class ExtendedValue;
} // namespace fir
namespace fir::factory {
/// Create a fir.box of type \p boxType that can be used to initialize an
/// allocatable variable. Initialization of such variable has to be done at the
/// beginning of the variable lifetime by storing the created box in the memory
/// for the variable box.
/// \p nonDeferredParams must provide the non deferred length parameters so that
/// they can already be placed in the unallocated box (inquiries about these
/// parameters are legal even in unallocated state).
mlir::Value createUnallocatedBox(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Type boxType,
mlir::ValueRange nonDeferredParams);
/// Create a MutableBoxValue for a temporary allocatable.
/// The created MutableBoxValue wraps a fir.ref<fir.box<fir.heap<type>>> and is
/// initialized to unallocated/diassociated status. An optional name can be
/// given to the created !fir.ref<fir.box>.
fir::MutableBoxValue createTempMutableBox(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Type type,
llvm::StringRef name = {});
/// Update a MutableBoxValue to describe entity \p source (that must be in
/// memory). If \lbounds is not empty, it is used to defined the MutableBoxValue
/// lower bounds, otherwise, the lower bounds from \p source are used.
void associateMutableBox(fir::FirOpBuilder &builder, mlir::Location loc,
const fir::MutableBoxValue &box,
const fir::ExtendedValue &source,
mlir::ValueRange lbounds);
/// Update a MutableBoxValue to describe entity \p source (that must be in
/// memory) with a new array layout given by \p lbounds and \p ubounds.
/// \p source must be known to be contiguous at compile time, or it must have
/// rank 1 (constraint from Fortran 2018 standard 10.2.2.3 point 9).
void associateMutableBoxWithRemap(fir::FirOpBuilder &builder,
mlir::Location loc,
const fir::MutableBoxValue &box,
const fir::ExtendedValue &source,
mlir::ValueRange lbounds,
mlir::ValueRange ubounds);
/// Set the association status of a MutableBoxValue to
/// disassociated/unallocated. Nothing is done with the entity that was
/// previously associated/allocated. The function generates code that sets the
/// address field of the MutableBoxValue to zero.
void disassociateMutableBox(fir::FirOpBuilder &builder, mlir::Location loc,
const fir::MutableBoxValue &box);
/// Generate code to conditionally reallocate a MutableBoxValue with a new
/// shape, lower bounds, and length parameters if it is unallocated or if its
/// current shape or deferred length parameters do not match the provided ones.
/// Lower bounds are only used if the entity needs to be allocated, otherwise,
/// the MutableBoxValue will keep its current lower bounds.
/// If the MutableBoxValue is an array, the provided shape can be empty, in
/// which case the MutableBoxValue must already be allocated at runtime and its
/// shape and lower bounds will be kept. If \p shape is empty, only a length
/// parameter mismatch can trigger a reallocation. See Fortran 10.2.1.3 point 3
/// that this function is implementing for more details. The polymorphic
/// requirements are not yet covered by this function.
void genReallocIfNeeded(fir::FirOpBuilder &builder, mlir::Location loc,
const fir::MutableBoxValue &box,
mlir::ValueRange lbounds, mlir::ValueRange shape,
mlir::ValueRange lengthParams);
/// Finalize a mutable box if it is allocated or associated. This includes both
/// calling the finalizer, if any, and deallocating the storage.
void genFinalization(fir::FirOpBuilder &builder, mlir::Location loc,
const fir::MutableBoxValue &box);
void genInlinedAllocation(fir::FirOpBuilder &builder, mlir::Location loc,
const fir::MutableBoxValue &box,
mlir::ValueRange lbounds, mlir::ValueRange extents,
mlir::ValueRange lenParams,
llvm::StringRef allocName);
void genInlinedDeallocate(fir::FirOpBuilder &builder, mlir::Location loc,
const fir::MutableBoxValue &box);
/// When the MutableBoxValue was passed as a fir.ref<fir.box> to a call that may
/// have modified it, update the MutableBoxValue according to the
/// fir.ref<fir.box> value.
void syncMutableBoxFromIRBox(fir::FirOpBuilder &builder, mlir::Location loc,
const fir::MutableBoxValue &box);
/// Read all mutable properties into a normal symbol box.
/// It is OK to call this on unassociated/unallocated boxes but any use of the
/// resulting values will be undefined (only the base address will be guaranteed
/// to be null).
fir::ExtendedValue genMutableBoxRead(fir::FirOpBuilder &builder,
mlir::Location loc,
const fir::MutableBoxValue &box,
bool mayBePolymorphic = true);
/// Returns the fir.ref<fir.box<T>> of a MutableBoxValue filled with the current
/// association / allocation properties. If the fir.ref<fir.box> already exists
/// and is-up to date, this is a no-op, otherwise, code will be generated to
/// fill it.
mlir::Value getMutableIRBox(fir::FirOpBuilder &builder, mlir::Location loc,
const fir::MutableBoxValue &box);
/// Generate allocation or association status test and returns the resulting
/// i1. This is testing this for a valid/non-null base address value.
mlir::Value genIsAllocatedOrAssociatedTest(fir::FirOpBuilder &builder,
mlir::Location loc,
const fir::MutableBoxValue &box);
} // namespace fir::factory
#endif // FORTRAN_OPTIMIZER_BUILDER_MUTABLEBOX_H