//===- ArrayConstructor.cpp - array constructor runtime API calls ---------===//
//
// 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/Optimizer/Builder/Runtime/ArrayConstructor.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
#include "flang/Runtime/array-constructor.h"
using namespace Fortran::runtime;
namespace fir::runtime {
template <>
constexpr TypeBuilderFunc
getModel<Fortran::runtime::ArrayConstructorVector &>() {
return getModel<void *>();
}
} // namespace fir::runtime
mlir::Value fir::runtime::genInitArrayConstructorVector(
mlir::Location loc, fir::FirOpBuilder &builder, mlir::Value toBox,
mlir::Value useValueLengthParameters) {
// Allocate storage for the runtime cookie for the array constructor vector.
// Use the "host" size and alignment, but double them to be safe regardless of
// the target. The "cookieSize" argument is used to validate this wild
// assumption until runtime interfaces are improved.
std::size_t arrayVectorStructBitSize =
2 * sizeof(Fortran::runtime::ArrayConstructorVector) * 8;
std::size_t alignLike = alignof(Fortran::runtime::ArrayConstructorVector) * 8;
fir::SequenceType::Extent numElem =
(arrayVectorStructBitSize + alignLike - 1) / alignLike;
mlir::Type intType = builder.getIntegerType(alignLike);
mlir::Type seqType = fir::SequenceType::get({numElem}, intType);
mlir::Value cookie =
builder.createTemporary(loc, seqType, ".rt.arrayctor.vector");
mlir::func::FuncOp func =
fir::runtime::getRuntimeFunc<mkRTKey(InitArrayConstructorVector)>(
loc, builder);
mlir::FunctionType funcType = func.getFunctionType();
cookie = builder.createConvert(loc, funcType.getInput(0), cookie);
mlir::Value cookieSize = builder.createIntegerConstant(
loc, funcType.getInput(3), numElem * alignLike / 8);
mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
mlir::Value sourceLine =
fir::factory::locationToLineNo(builder, loc, funcType.getInput(5));
auto args = fir::runtime::createArguments(builder, loc, funcType, cookie,
toBox, useValueLengthParameters,
cookieSize, sourceFile, sourceLine);
builder.create<fir::CallOp>(loc, func, args);
return cookie;
}
void fir::runtime::genPushArrayConstructorValue(
mlir::Location loc, fir::FirOpBuilder &builder,
mlir::Value arrayConstructorVector, mlir::Value fromBox) {
mlir::func::FuncOp func =
fir::runtime::getRuntimeFunc<mkRTKey(PushArrayConstructorValue)>(loc,
builder);
mlir::FunctionType funcType = func.getFunctionType();
auto args = fir::runtime::createArguments(builder, loc, funcType,
arrayConstructorVector, fromBox);
builder.create<fir::CallOp>(loc, func, args);
}
void fir::runtime::genPushArrayConstructorSimpleScalar(
mlir::Location loc, fir::FirOpBuilder &builder,
mlir::Value arrayConstructorVector, mlir::Value fromAddress) {
mlir::func::FuncOp func =
fir::runtime::getRuntimeFunc<mkRTKey(PushArrayConstructorSimpleScalar)>(
loc, builder);
mlir::FunctionType funcType = func.getFunctionType();
auto args = fir::runtime::createArguments(
builder, loc, funcType, arrayConstructorVector, fromAddress);
builder.create<fir::CallOp>(loc, func, args);
}