Skip to content

Commit 1a9a850

Browse files
committed
Update TargetAllocMemOpConversion.
Move utility functions to utils Co-authored by @ergawy
1 parent f6e53f0 commit 1a9a850

File tree

8 files changed

+427
-232
lines changed

8 files changed

+427
-232
lines changed

flang/include/flang/Optimizer/Support/Utils.h

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#include "llvm/ADT/DenseMap.h"
2828
#include "llvm/ADT/StringRef.h"
2929

30+
#include "flang/Optimizer/CodeGen/TypeConverter.h"
31+
3032
namespace fir {
3133
/// Return the integer value of a arith::ConstantOp.
3234
inline std::int64_t toInt(mlir::arith::ConstantOp cop) {
@@ -198,6 +200,67 @@ std::optional<llvm::ArrayRef<int64_t>> getComponentLowerBoundsIfNonDefault(
198200
fir::RecordType recordType, llvm::StringRef component,
199201
mlir::ModuleOp module, const mlir::SymbolTable *symbolTable = nullptr);
200202

203+
// Convert FIR type to LLVM without turning fir.box<T> into memory
204+
// reference.
205+
mlir::Type convertObjectType(const fir::LLVMTypeConverter &converter,
206+
mlir::Type firType);
207+
208+
/// Generate a LLVM constant value of type `ity`, using the provided offset.
209+
mlir::LLVM::ConstantOp
210+
genConstantIndex(mlir::Location loc, mlir::Type ity,
211+
mlir::ConversionPatternRewriter &rewriter,
212+
std::int64_t offset);
213+
214+
/// Helper function for generating the LLVM IR that computes the distance
215+
/// in bytes between adjacent elements pointed to by a pointer
216+
/// of type \p ptrTy. The result is returned as a value of \p idxTy integer
217+
/// type.
218+
mlir::Value computeElementDistance(mlir::Location loc,
219+
mlir::Type llvmObjectType, mlir::Type idxTy,
220+
mlir::ConversionPatternRewriter &rewriter,
221+
const mlir::DataLayout &dataLayout);
222+
223+
// Compute the alloc scale size (constant factors encoded in the array type).
224+
// We do this for arrays without a constant interior or arrays of character with
225+
// dynamic length arrays, since those are the only ones that get decayed to a
226+
// pointer to the element type.
227+
template <typename OP>
228+
inline mlir::Value
229+
genAllocationScaleSize(OP op, mlir::Type ity,
230+
mlir::ConversionPatternRewriter &rewriter) {
231+
mlir::Location loc = op.getLoc();
232+
mlir::Type dataTy = op.getInType();
233+
auto seqTy = mlir::dyn_cast<fir::SequenceType>(dataTy);
234+
fir::SequenceType::Extent constSize = 1;
235+
if (seqTy) {
236+
int constRows = seqTy.getConstantRows();
237+
const fir::SequenceType::ShapeRef &shape = seqTy.getShape();
238+
if (constRows != static_cast<int>(shape.size())) {
239+
for (auto extent : shape) {
240+
if (constRows-- > 0)
241+
continue;
242+
if (extent != fir::SequenceType::getUnknownExtent())
243+
constSize *= extent;
244+
}
245+
}
246+
}
247+
248+
if (constSize != 1) {
249+
mlir::Value constVal{
250+
fir::genConstantIndex(loc, ity, rewriter, constSize).getResult()};
251+
return constVal;
252+
}
253+
return nullptr;
254+
}
255+
256+
/// Perform an extension or truncation as needed on an integer value. Lowering
257+
/// to the specific target may involve some sign-extending or truncation of
258+
/// values, particularly to fit them from abstract box types to the
259+
/// appropriate reified structures.
260+
mlir::Value integerCast(const fir::LLVMTypeConverter &converter,
261+
mlir::Location loc,
262+
mlir::ConversionPatternRewriter &rewriter,
263+
mlir::Type ty, mlir::Value val, bool fold = false);
201264
} // namespace fir
202265

203266
#endif // FORTRAN_OPTIMIZER_SUPPORT_UTILS_H

flang/lib/Optimizer/CodeGen/CodeGen.cpp

Lines changed: 26 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,6 @@ static inline mlir::Type getI8Type(mlir::MLIRContext *context) {
8787
return mlir::IntegerType::get(context, 8);
8888
}
8989

90-
static mlir::LLVM::ConstantOp
91-
genConstantIndex(mlir::Location loc, mlir::Type ity,
92-
mlir::ConversionPatternRewriter &rewriter,
93-
std::int64_t offset) {
94-
auto cattr = rewriter.getI64IntegerAttr(offset);
95-
return rewriter.create<mlir::LLVM::ConstantOp>(loc, ity, cattr);
96-
}
97-
9890
static mlir::Block *createBlock(mlir::ConversionPatternRewriter &rewriter,
9991
mlir::Block *insertBefore) {
10092
assert(insertBefore && "expected valid insertion block");
@@ -205,39 +197,6 @@ getDependentTypeMemSizeFn(fir::RecordType recTy, fir::AllocaOp op,
205197
TODO(op.getLoc(), "did not find allocation function");
206198
}
207199

208-
// Compute the alloc scale size (constant factors encoded in the array type).
209-
// We do this for arrays without a constant interior or arrays of character with
210-
// dynamic length arrays, since those are the only ones that get decayed to a
211-
// pointer to the element type.
212-
template <typename OP>
213-
static mlir::Value
214-
genAllocationScaleSize(OP op, mlir::Type ity,
215-
mlir::ConversionPatternRewriter &rewriter) {
216-
mlir::Location loc = op.getLoc();
217-
mlir::Type dataTy = op.getInType();
218-
auto seqTy = mlir::dyn_cast<fir::SequenceType>(dataTy);
219-
fir::SequenceType::Extent constSize = 1;
220-
if (seqTy) {
221-
int constRows = seqTy.getConstantRows();
222-
const fir::SequenceType::ShapeRef &shape = seqTy.getShape();
223-
if (constRows != static_cast<int>(shape.size())) {
224-
for (auto extent : shape) {
225-
if (constRows-- > 0)
226-
continue;
227-
if (extent != fir::SequenceType::getUnknownExtent())
228-
constSize *= extent;
229-
}
230-
}
231-
}
232-
233-
if (constSize != 1) {
234-
mlir::Value constVal{
235-
genConstantIndex(loc, ity, rewriter, constSize).getResult()};
236-
return constVal;
237-
}
238-
return nullptr;
239-
}
240-
241200
namespace {
242201
struct DeclareOpConversion : public fir::FIROpConversion<fir::cg::XDeclareOp> {
243202
public:
@@ -272,7 +231,7 @@ struct AllocaOpConversion : public fir::FIROpConversion<fir::AllocaOp> {
272231
auto loc = alloc.getLoc();
273232
mlir::Type ity = lowerTy().indexType();
274233
unsigned i = 0;
275-
mlir::Value size = genConstantIndex(loc, ity, rewriter, 1).getResult();
234+
mlir::Value size = fir::genConstantIndex(loc, ity, rewriter, 1).getResult();
276235
mlir::Type firObjType = fir::unwrapRefType(alloc.getType());
277236
mlir::Type llvmObjectType = convertObjectType(firObjType);
278237
if (alloc.hasLenParams()) {
@@ -304,7 +263,7 @@ struct AllocaOpConversion : public fir::FIROpConversion<fir::AllocaOp> {
304263
<< scalarType << " with type parameters";
305264
}
306265
}
307-
if (auto scaleSize = genAllocationScaleSize(alloc, ity, rewriter))
266+
if (auto scaleSize = fir::genAllocationScaleSize(alloc, ity, rewriter))
308267
size =
309268
rewriter.createOrFold<mlir::LLVM::MulOp>(loc, ity, size, scaleSize);
310269
if (alloc.hasShapeOperands()) {
@@ -481,7 +440,7 @@ struct BoxIsArrayOpConversion : public fir::FIROpConversion<fir::BoxIsArrayOp> {
481440
auto loc = boxisarray.getLoc();
482441
TypePair boxTyPair = getBoxTypePair(boxisarray.getVal().getType());
483442
mlir::Value rank = getRankFromBox(loc, boxTyPair, a, rewriter);
484-
mlir::Value c0 = genConstantIndex(loc, rank.getType(), rewriter, 0);
443+
mlir::Value c0 = fir::genConstantIndex(loc, rank.getType(), rewriter, 0);
485444
rewriter.replaceOpWithNewOp<mlir::LLVM::ICmpOp>(
486445
boxisarray, mlir::LLVM::ICmpPredicate::ne, rank, c0);
487446
return mlir::success();
@@ -817,7 +776,7 @@ struct ConvertOpConversion : public fir::FIROpConversion<fir::ConvertOp> {
817776
// Do folding for constant inputs.
818777
if (auto constVal = fir::getIntIfConstant(op0)) {
819778
mlir::Value normVal =
820-
genConstantIndex(loc, toTy, rewriter, *constVal ? 1 : 0);
779+
fir::genConstantIndex(loc, toTy, rewriter, *constVal ? 1 : 0);
821780
rewriter.replaceOp(convert, normVal);
822781
return mlir::success();
823782
}
@@ -830,7 +789,7 @@ struct ConvertOpConversion : public fir::FIROpConversion<fir::ConvertOp> {
830789
}
831790

832791
// Compare the input with zero.
833-
mlir::Value zero = genConstantIndex(loc, fromTy, rewriter, 0);
792+
mlir::Value zero = fir::genConstantIndex(loc, fromTy, rewriter, 0);
834793
auto isTrue = rewriter.create<mlir::LLVM::ICmpOp>(
835794
loc, mlir::LLVM::ICmpPredicate::ne, op0, zero);
836795

@@ -1077,21 +1036,6 @@ static mlir::SymbolRefAttr getMalloc(fir::AllocMemOp op,
10771036
return getMallocInModule(mod, op, rewriter, indexType);
10781037
}
10791038

1080-
/// Helper function for generating the LLVM IR that computes the distance
1081-
/// in bytes between adjacent elements pointed to by a pointer
1082-
/// of type \p ptrTy. The result is returned as a value of \p idxTy integer
1083-
/// type.
1084-
static mlir::Value
1085-
computeElementDistance(mlir::Location loc, mlir::Type llvmObjectType,
1086-
mlir::Type idxTy,
1087-
mlir::ConversionPatternRewriter &rewriter,
1088-
const mlir::DataLayout &dataLayout) {
1089-
llvm::TypeSize size = dataLayout.getTypeSize(llvmObjectType);
1090-
unsigned short alignment = dataLayout.getTypeABIAlignment(llvmObjectType);
1091-
std::int64_t distance = llvm::alignTo(size, alignment);
1092-
return genConstantIndex(loc, idxTy, rewriter, distance);
1093-
}
1094-
10951039
/// Return value of the stride in bytes between adjacent elements
10961040
/// of LLVM type \p llTy. The result is returned as a value of
10971041
/// \p idxTy integer type.
@@ -1100,7 +1044,7 @@ genTypeStrideInBytes(mlir::Location loc, mlir::Type idxTy,
11001044
mlir::ConversionPatternRewriter &rewriter, mlir::Type llTy,
11011045
const mlir::DataLayout &dataLayout) {
11021046
// Create a pointer type and use computeElementDistance().
1103-
return computeElementDistance(loc, llTy, idxTy, rewriter, dataLayout);
1047+
return fir::computeElementDistance(loc, llTy, idxTy, rewriter, dataLayout);
11041048
}
11051049

11061050
namespace {
@@ -1119,7 +1063,7 @@ struct AllocMemOpConversion : public fir::FIROpConversion<fir::AllocMemOp> {
11191063
if (fir::isRecordWithTypeParameters(fir::unwrapSequenceType(dataTy)))
11201064
TODO(loc, "fir.allocmem codegen of derived type with length parameters");
11211065
mlir::Value size = genTypeSizeInBytes(loc, ity, rewriter, llvmObjectTy);
1122-
if (auto scaleSize = genAllocationScaleSize(heap, ity, rewriter))
1066+
if (auto scaleSize = fir::genAllocationScaleSize(heap, ity, rewriter))
11231067
size = rewriter.create<mlir::LLVM::MulOp>(loc, ity, size, scaleSize);
11241068
for (mlir::Value opnd : adaptor.getOperands())
11251069
size = rewriter.create<mlir::LLVM::MulOp>(
@@ -1152,7 +1096,8 @@ struct AllocMemOpConversion : public fir::FIROpConversion<fir::AllocMemOp> {
11521096
mlir::Value genTypeSizeInBytes(mlir::Location loc, mlir::Type idxTy,
11531097
mlir::ConversionPatternRewriter &rewriter,
11541098
mlir::Type llTy) const {
1155-
return computeElementDistance(loc, llTy, idxTy, rewriter, getDataLayout());
1099+
return fir::computeElementDistance(loc, llTy, idxTy, rewriter,
1100+
getDataLayout());
11561101
}
11571102
};
11581103
} // namespace
@@ -1336,7 +1281,7 @@ genCUFAllocDescriptor(mlir::Location loc,
13361281
mlir::Type structTy = typeConverter.convertBoxTypeAsStruct(boxTy);
13371282
std::size_t boxSize = dl->getTypeSizeInBits(structTy) / 8;
13381283
mlir::Value sizeInBytes =
1339-
genConstantIndex(loc, llvmIntPtrType, rewriter, boxSize);
1284+
fir::genConstantIndex(loc, llvmIntPtrType, rewriter, boxSize);
13401285
llvm::SmallVector args = {sizeInBytes, sourceFile, sourceLine};
13411286
return rewriter
13421287
.create<mlir::LLVM::CallOp>(loc, fctTy, RTNAME_STRING(CUFAllocDescriptor),
@@ -1592,7 +1537,7 @@ struct EmboxCommonConversion : public fir::FIROpConversion<OP> {
15921537
// representation of derived types with pointer/allocatable components.
15931538
// This has been seen in hashing algorithms using TRANSFER.
15941539
mlir::Value zero =
1595-
genConstantIndex(loc, rewriter.getI64Type(), rewriter, 0);
1540+
fir::genConstantIndex(loc, rewriter.getI64Type(), rewriter, 0);
15961541
descriptor = insertField(rewriter, loc, descriptor,
15971542
{getLenParamFieldId(boxTy), 0}, zero);
15981543
}
@@ -1935,8 +1880,8 @@ struct XEmboxOpConversion : public EmboxCommonConversion<fir::cg::XEmboxOp> {
19351880
bool hasSlice = !xbox.getSlice().empty();
19361881
unsigned sliceOffset = xbox.getSliceOperandIndex();
19371882
mlir::Location loc = xbox.getLoc();
1938-
mlir::Value zero = genConstantIndex(loc, i64Ty, rewriter, 0);
1939-
mlir::Value one = genConstantIndex(loc, i64Ty, rewriter, 1);
1883+
mlir::Value zero = fir::genConstantIndex(loc, i64Ty, rewriter, 0);
1884+
mlir::Value one = fir::genConstantIndex(loc, i64Ty, rewriter, 1);
19401885
mlir::Value prevPtrOff = one;
19411886
mlir::Type eleTy = boxTy.getEleTy();
19421887
const unsigned rank = xbox.getRank();
@@ -1985,7 +1930,7 @@ struct XEmboxOpConversion : public EmboxCommonConversion<fir::cg::XEmboxOp> {
19851930
prevDimByteStride =
19861931
getCharacterByteSize(loc, rewriter, charTy, adaptor.getLenParams());
19871932
} else {
1988-
prevDimByteStride = genConstantIndex(
1933+
prevDimByteStride = fir::genConstantIndex(
19891934
loc, i64Ty, rewriter,
19901935
charTy.getLen() * lowerTy().characterBitsize(charTy) / 8);
19911936
}
@@ -2143,7 +2088,7 @@ struct XReboxOpConversion : public EmboxCommonConversion<fir::cg::XReboxOp> {
21432088
if (auto charTy = mlir::dyn_cast<fir::CharacterType>(inputEleTy)) {
21442089
if (charTy.hasConstantLen()) {
21452090
mlir::Value len =
2146-
genConstantIndex(loc, idxTy, rewriter, charTy.getLen());
2091+
fir::genConstantIndex(loc, idxTy, rewriter, charTy.getLen());
21472092
lenParams.emplace_back(len);
21482093
} else {
21492094
mlir::Value len = getElementSizeFromBox(loc, idxTy, inputBoxTyPair,
@@ -2152,7 +2097,7 @@ struct XReboxOpConversion : public EmboxCommonConversion<fir::cg::XReboxOp> {
21522097
assert(!isInGlobalOp(rewriter) &&
21532098
"character target in global op must have constant length");
21542099
mlir::Value width =
2155-
genConstantIndex(loc, idxTy, rewriter, charTy.getFKind());
2100+
fir::genConstantIndex(loc, idxTy, rewriter, charTy.getFKind());
21562101
len = rewriter.create<mlir::LLVM::SDivOp>(loc, idxTy, len, width);
21572102
}
21582103
lenParams.emplace_back(len);
@@ -2206,8 +2151,9 @@ struct XReboxOpConversion : public EmboxCommonConversion<fir::cg::XReboxOp> {
22062151
mlir::ConversionPatternRewriter &rewriter) const {
22072152
mlir::Location loc = rebox.getLoc();
22082153
mlir::Value zero =
2209-
genConstantIndex(loc, lowerTy().indexType(), rewriter, 0);
2210-
mlir::Value one = genConstantIndex(loc, lowerTy().indexType(), rewriter, 1);
2154+
fir::genConstantIndex(loc, lowerTy().indexType(), rewriter, 0);
2155+
mlir::Value one =
2156+
fir::genConstantIndex(loc, lowerTy().indexType(), rewriter, 1);
22112157
for (auto iter : llvm::enumerate(llvm::zip(extents, strides))) {
22122158
mlir::Value extent = std::get<0>(iter.value());
22132159
unsigned dim = iter.index();
@@ -2239,7 +2185,7 @@ struct XReboxOpConversion : public EmboxCommonConversion<fir::cg::XReboxOp> {
22392185
mlir::Location loc = rebox.getLoc();
22402186
mlir::Type byteTy = ::getI8Type(rebox.getContext());
22412187
mlir::Type idxTy = lowerTy().indexType();
2242-
mlir::Value zero = genConstantIndex(loc, idxTy, rewriter, 0);
2188+
mlir::Value zero = fir::genConstantIndex(loc, idxTy, rewriter, 0);
22432189
// Apply subcomponent and substring shift on base address.
22442190
if (!rebox.getSubcomponent().empty() || !rebox.getSubstr().empty()) {
22452191
// Cast to inputEleTy* so that a GEP can be used.
@@ -2267,7 +2213,7 @@ struct XReboxOpConversion : public EmboxCommonConversion<fir::cg::XReboxOp> {
22672213
// and strides.
22682214
llvm::SmallVector<mlir::Value> slicedExtents;
22692215
llvm::SmallVector<mlir::Value> slicedStrides;
2270-
mlir::Value one = genConstantIndex(loc, idxTy, rewriter, 1);
2216+
mlir::Value one = fir::genConstantIndex(loc, idxTy, rewriter, 1);
22712217
const bool sliceHasOrigins = !rebox.getShift().empty();
22722218
unsigned sliceOps = rebox.getSliceOperandIndex();
22732219
unsigned shiftOps = rebox.getShiftOperandIndex();
@@ -2340,7 +2286,7 @@ struct XReboxOpConversion : public EmboxCommonConversion<fir::cg::XReboxOp> {
23402286
// which may be OK if all new extents are ones, the stride does not
23412287
// matter, use one.
23422288
mlir::Value stride = inputStrides.empty()
2343-
? genConstantIndex(loc, idxTy, rewriter, 1)
2289+
? fir::genConstantIndex(loc, idxTy, rewriter, 1)
23442290
: inputStrides[0];
23452291
for (unsigned i = 0; i < rebox.getShape().size(); ++i) {
23462292
mlir::Value rawExtent = operands[rebox.getShapeOperandIndex() + i];
@@ -2575,9 +2521,9 @@ struct XArrayCoorOpConversion
25752521
unsigned shiftOffset = coor.getShiftOperandIndex();
25762522
unsigned sliceOffset = coor.getSliceOperandIndex();
25772523
auto sliceOps = coor.getSlice().begin();
2578-
mlir::Value one = genConstantIndex(loc, idxTy, rewriter, 1);
2524+
mlir::Value one = fir::genConstantIndex(loc, idxTy, rewriter, 1);
25792525
mlir::Value prevExt = one;
2580-
mlir::Value offset = genConstantIndex(loc, idxTy, rewriter, 0);
2526+
mlir::Value offset = fir::genConstantIndex(loc, idxTy, rewriter, 0);
25812527
const bool isShifted = !coor.getShift().empty();
25822528
const bool isSliced = !coor.getSlice().empty();
25832529
const bool baseIsBoxed =
@@ -2907,7 +2853,7 @@ struct CoordinateOpConversion
29072853
// of lower bound aspects. This both accounts for dynamically sized
29082854
// types and non contiguous arrays.
29092855
auto idxTy = lowerTy().indexType();
2910-
mlir::Value off = genConstantIndex(loc, idxTy, rewriter, 0);
2856+
mlir::Value off = fir::genConstantIndex(loc, idxTy, rewriter, 0);
29112857
unsigned arrayDim = arrTy.getDimension();
29122858
for (unsigned dim = 0; dim < arrayDim && it != end; ++dim, ++it) {
29132859
mlir::Value stride =
@@ -3820,7 +3766,7 @@ struct IsPresentOpConversion : public fir::FIROpConversion<fir::IsPresentOp> {
38203766
ptr = rewriter.create<mlir::LLVM::ExtractValueOp>(loc, ptr, 0);
38213767
}
38223768
mlir::LLVM::ConstantOp c0 =
3823-
genConstantIndex(isPresent.getLoc(), idxTy, rewriter, 0);
3769+
fir::genConstantIndex(isPresent.getLoc(), idxTy, rewriter, 0);
38243770
auto addr = rewriter.create<mlir::LLVM::PtrToIntOp>(loc, idxTy, ptr);
38253771
rewriter.replaceOpWithNewOp<mlir::LLVM::ICmpOp>(
38263772
isPresent, mlir::LLVM::ICmpPredicate::ne, addr, c0);

0 commit comments

Comments
 (0)