|
| 1 | +//===-- MutableBox.h -- MutableBox utilities -----------------------------===// |
| 2 | +// |
| 3 | +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | +// See https://llvm.org/LICENSE.txt for license information. |
| 5 | +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | +// |
| 7 | +//===----------------------------------------------------------------------===// |
| 8 | +// |
| 9 | +// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ |
| 10 | +// |
| 11 | +//===----------------------------------------------------------------------===// |
| 12 | + |
| 13 | +#ifndef FORTRAN_OPTIMIZER_BUILDER_MUTABLEBOX_H |
| 14 | +#define FORTRAN_OPTIMIZER_BUILDER_MUTABLEBOX_H |
| 15 | + |
| 16 | +#include "llvm/ADT/StringRef.h" |
| 17 | + |
| 18 | +namespace mlir { |
| 19 | +class Value; |
| 20 | +class ValueRange; |
| 21 | +class Type; |
| 22 | +class Location; |
| 23 | +} // namespace mlir |
| 24 | + |
| 25 | +namespace fir { |
| 26 | +class FirOpBuilder; |
| 27 | +class MutableBoxValue; |
| 28 | +class ExtendedValue; |
| 29 | +} // namespace fir |
| 30 | + |
| 31 | +namespace fir::factory { |
| 32 | + |
| 33 | +/// Create a fir.box of type \p boxType that can be used to initialize an |
| 34 | +/// allocatable variable. Initialization of such variable has to be done at the |
| 35 | +/// beginning of the variable lifetime by storing the created box in the memory |
| 36 | +/// for the variable box. |
| 37 | +/// \p nonDeferredParams must provide the non deferred length parameters so that |
| 38 | +/// they can already be placed in the unallocated box (inquiries about these |
| 39 | +/// parameters are legal even in unallocated state). |
| 40 | +mlir::Value createUnallocatedBox(fir::FirOpBuilder &builder, mlir::Location loc, |
| 41 | + mlir::Type boxType, |
| 42 | + mlir::ValueRange nonDeferredParams); |
| 43 | + |
| 44 | +/// Create a MutableBoxValue for a temporary allocatable. |
| 45 | +/// The created MutableBoxValue wraps a fir.ref<fir.box<fir.heap<type>>> and is |
| 46 | +/// initialized to unallocated/diassociated status. An optional name can be |
| 47 | +/// given to the created !fir.ref<fir.box>. |
| 48 | +fir::MutableBoxValue createTempMutableBox(fir::FirOpBuilder &builder, |
| 49 | + mlir::Location loc, mlir::Type type, |
| 50 | + llvm::StringRef name = {}); |
| 51 | + |
| 52 | +/// Update a MutableBoxValue to describe entity \p source (that must be in |
| 53 | +/// memory). If \lbounds is not empty, it is used to defined the MutableBoxValue |
| 54 | +/// lower bounds, otherwise, the lower bounds from \p source are used. |
| 55 | +void associateMutableBox(fir::FirOpBuilder &builder, mlir::Location loc, |
| 56 | + const fir::MutableBoxValue &box, |
| 57 | + const fir::ExtendedValue &source, |
| 58 | + mlir::ValueRange lbounds); |
| 59 | + |
| 60 | +/// Update a MutableBoxValue to describe entity \p source (that must be in |
| 61 | +/// memory) with a new array layout given by \p lbounds and \p ubounds. |
| 62 | +/// \p source must be known to be contiguous at compile time, or it must have |
| 63 | +/// rank 1 (constraint from Fortran 2018 standard 10.2.2.3 point 9). |
| 64 | +void associateMutableBoxWithRemap(fir::FirOpBuilder &builder, |
| 65 | + mlir::Location loc, |
| 66 | + const fir::MutableBoxValue &box, |
| 67 | + const fir::ExtendedValue &source, |
| 68 | + mlir::ValueRange lbounds, |
| 69 | + mlir::ValueRange ubounds); |
| 70 | + |
| 71 | +/// Set the association status of a MutableBoxValue to |
| 72 | +/// disassociated/unallocated. Nothing is done with the entity that was |
| 73 | +/// previously associated/allocated. The function generates code that sets the |
| 74 | +/// address field of the MutableBoxValue to zero. |
| 75 | +void disassociateMutableBox(fir::FirOpBuilder &builder, mlir::Location loc, |
| 76 | + const fir::MutableBoxValue &box); |
| 77 | + |
| 78 | +/// Generate code to conditionally reallocate a MutableBoxValue with a new |
| 79 | +/// shape, lower bounds, and length parameters if it is unallocated or if its |
| 80 | +/// current shape or deferred length parameters do not match the provided ones. |
| 81 | +/// Lower bounds are only used if the entity needs to be allocated, otherwise, |
| 82 | +/// the MutableBoxValue will keep its current lower bounds. |
| 83 | +/// If the MutableBoxValue is an array, the provided shape can be empty, in |
| 84 | +/// which case the MutableBoxValue must already be allocated at runtime and its |
| 85 | +/// shape and lower bounds will be kept. If \p shape is empty, only a length |
| 86 | +/// parameter mismatch can trigger a reallocation. See Fortran 10.2.1.3 point 3 |
| 87 | +/// that this function is implementing for more details. The polymorphic |
| 88 | +/// requirements are not yet covered by this function. |
| 89 | +void genReallocIfNeeded(fir::FirOpBuilder &builder, mlir::Location loc, |
| 90 | + const fir::MutableBoxValue &box, |
| 91 | + mlir::ValueRange lbounds, mlir::ValueRange shape, |
| 92 | + mlir::ValueRange lengthParams); |
| 93 | + |
| 94 | +/// Finalize a mutable box if it is allocated or associated. This includes both |
| 95 | +/// calling the finalizer, if any, and deallocating the storage. |
| 96 | +void genFinalization(fir::FirOpBuilder &builder, mlir::Location loc, |
| 97 | + const fir::MutableBoxValue &box); |
| 98 | + |
| 99 | +void genInlinedAllocation(fir::FirOpBuilder &builder, mlir::Location loc, |
| 100 | + const fir::MutableBoxValue &box, |
| 101 | + mlir::ValueRange lbounds, mlir::ValueRange extents, |
| 102 | + mlir::ValueRange lenParams, |
| 103 | + llvm::StringRef allocName); |
| 104 | + |
| 105 | +void genInlinedDeallocate(fir::FirOpBuilder &builder, mlir::Location loc, |
| 106 | + const fir::MutableBoxValue &box); |
| 107 | + |
| 108 | +/// When the MutableBoxValue was passed as a fir.ref<fir.box> to a call that may |
| 109 | +/// have modified it, update the MutableBoxValue according to the |
| 110 | +/// fir.ref<fir.box> value. |
| 111 | +void syncMutableBoxFromIRBox(fir::FirOpBuilder &builder, mlir::Location loc, |
| 112 | + const fir::MutableBoxValue &box); |
| 113 | + |
| 114 | +/// Read all mutable properties into a normal symbol box. |
| 115 | +/// It is OK to call this on unassociated/unallocated boxes but any use of the |
| 116 | +/// resulting values will be undefined (only the base address will be guaranteed |
| 117 | +/// to be null). |
| 118 | +fir::ExtendedValue genMutableBoxRead(fir::FirOpBuilder &builder, |
| 119 | + mlir::Location loc, |
| 120 | + const fir::MutableBoxValue &box, |
| 121 | + bool mayBePolymorphic = true); |
| 122 | + |
| 123 | +/// Returns the fir.ref<fir.box<T>> of a MutableBoxValue filled with the current |
| 124 | +/// association / allocation properties. If the fir.ref<fir.box> already exists |
| 125 | +/// and is-up to date, this is a no-op, otherwise, code will be generated to |
| 126 | +/// fill it. |
| 127 | +mlir::Value getMutableIRBox(fir::FirOpBuilder &builder, mlir::Location loc, |
| 128 | + const fir::MutableBoxValue &box); |
| 129 | + |
| 130 | +/// Generate allocation or association status test and returns the resulting |
| 131 | +/// i1. This is testing this for a valid/non-null base address value. |
| 132 | +mlir::Value genIsAllocatedOrAssociatedTest(fir::FirOpBuilder &builder, |
| 133 | + mlir::Location loc, |
| 134 | + const fir::MutableBoxValue &box); |
| 135 | + |
| 136 | +} // namespace fir::factory |
| 137 | + |
| 138 | +#endif // FORTRAN_OPTIMIZER_BUILDER_MUTABLEBOX_H |
0 commit comments