xref: /llvm-project/flang/lib/Optimizer/Builder/Runtime/ArrayConstructor.cpp (revision c91ba04328e1ded6f284469a7828d181324d4e30)
1 //===- ArrayConstructor.cpp - array constructor runtime API calls ---------===//
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 #include "flang/Optimizer/Builder/Runtime/ArrayConstructor.h"
10 #include "flang/Optimizer/Builder/FIRBuilder.h"
11 #include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
12 #include "flang/Runtime/array-constructor-consts.h"
13 
14 using namespace Fortran::runtime;
15 
16 namespace fir::runtime {
17 template <>
18 constexpr TypeBuilderFunc
19 getModel<Fortran::runtime::ArrayConstructorVector &>() {
20   return getModel<void *>();
21 }
22 } // namespace fir::runtime
23 
24 mlir::Value fir::runtime::genInitArrayConstructorVector(
25     mlir::Location loc, fir::FirOpBuilder &builder, mlir::Value toBox,
26     mlir::Value useValueLengthParameters) {
27   // Allocate storage for the runtime cookie for the array constructor vector.
28   // Use pessimistic values for size and alignment that are valid for all
29   // supported targets. Whether the actual ArrayConstructorVector object fits
30   // into the available MaxArrayConstructorVectorSizeInBytes is verified when
31   // building clang-rt.
32   std::size_t arrayVectorStructBitSize =
33       MaxArrayConstructorVectorSizeInBytes * 8;
34   std::size_t alignLike = MaxArrayConstructorVectorAlignInBytes * 8;
35   fir::SequenceType::Extent numElem =
36       (arrayVectorStructBitSize + alignLike - 1) / alignLike;
37   mlir::Type intType = builder.getIntegerType(alignLike);
38   mlir::Type seqType = fir::SequenceType::get({numElem}, intType);
39   mlir::Value cookie =
40       builder.createTemporary(loc, seqType, ".rt.arrayctor.vector");
41 
42   mlir::func::FuncOp func =
43       fir::runtime::getRuntimeFunc<mkRTKey(InitArrayConstructorVector)>(
44           loc, builder);
45   mlir::FunctionType funcType = func.getFunctionType();
46   cookie = builder.createConvert(loc, funcType.getInput(0), cookie);
47   mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc);
48   mlir::Value sourceLine =
49       fir::factory::locationToLineNo(builder, loc, funcType.getInput(4));
50   auto args = fir::runtime::createArguments(builder, loc, funcType, cookie,
51                                             toBox, useValueLengthParameters,
52                                             sourceFile, sourceLine);
53   builder.create<fir::CallOp>(loc, func, args);
54   return cookie;
55 }
56 
57 void fir::runtime::genPushArrayConstructorValue(
58     mlir::Location loc, fir::FirOpBuilder &builder,
59     mlir::Value arrayConstructorVector, mlir::Value fromBox) {
60   mlir::func::FuncOp func =
61       fir::runtime::getRuntimeFunc<mkRTKey(PushArrayConstructorValue)>(loc,
62                                                                        builder);
63   mlir::FunctionType funcType = func.getFunctionType();
64   auto args = fir::runtime::createArguments(builder, loc, funcType,
65                                             arrayConstructorVector, fromBox);
66   builder.create<fir::CallOp>(loc, func, args);
67 }
68 
69 void fir::runtime::genPushArrayConstructorSimpleScalar(
70     mlir::Location loc, fir::FirOpBuilder &builder,
71     mlir::Value arrayConstructorVector, mlir::Value fromAddress) {
72   mlir::func::FuncOp func =
73       fir::runtime::getRuntimeFunc<mkRTKey(PushArrayConstructorSimpleScalar)>(
74           loc, builder);
75   mlir::FunctionType funcType = func.getFunctionType();
76   auto args = fir::runtime::createArguments(
77       builder, loc, funcType, arrayConstructorVector, fromAddress);
78   builder.create<fir::CallOp>(loc, func, args);
79 }
80