1 //===-- Transformational.cpp ------------------------------------*- C++ -*-===//
2 // Generate transformational intrinsic runtime API calls.
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "flang/Optimizer/Builder/Runtime/Transformational.h"
11 #include "flang/Optimizer/Builder/BoxValue.h"
12 #include "flang/Optimizer/Builder/Character.h"
13 #include "flang/Optimizer/Builder/FIRBuilder.h"
14 #include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
15 #include "flang/Optimizer/Builder/Todo.h"
16 #include "flang/Runtime/matmul.h"
17 #include "flang/Runtime/transformational.h"
18 #include "mlir/Dialect/Func/IR/FuncOps.h"
19 
20 using namespace Fortran::runtime;
21 
22 /// Generate call to Cshift intrinsic
genCshift(fir::FirOpBuilder & builder,mlir::Location loc,mlir::Value resultBox,mlir::Value arrayBox,mlir::Value shiftBox,mlir::Value dimBox)23 void fir::runtime::genCshift(fir::FirOpBuilder &builder, mlir::Location loc,
24                              mlir::Value resultBox, mlir::Value arrayBox,
25                              mlir::Value shiftBox, mlir::Value dimBox) {
26   auto cshiftFunc = fir::runtime::getRuntimeFunc<mkRTKey(Cshift)>(loc, builder);
27   auto fTy = cshiftFunc.getFunctionType();
28   auto sourceFile = fir::factory::locationToFilename(builder, loc);
29   auto sourceLine =
30       fir::factory::locationToLineNo(builder, loc, fTy.getInput(5));
31   auto args =
32       fir::runtime::createArguments(builder, loc, fTy, resultBox, arrayBox,
33                                     shiftBox, dimBox, sourceFile, sourceLine);
34   builder.create<fir::CallOp>(loc, cshiftFunc, args);
35 }
36 
37 /// Generate call to the vector version of the Cshift intrinsic
genCshiftVector(fir::FirOpBuilder & builder,mlir::Location loc,mlir::Value resultBox,mlir::Value arrayBox,mlir::Value shiftBox)38 void fir::runtime::genCshiftVector(fir::FirOpBuilder &builder,
39                                    mlir::Location loc, mlir::Value resultBox,
40                                    mlir::Value arrayBox, mlir::Value shiftBox) {
41   auto cshiftFunc =
42       fir::runtime::getRuntimeFunc<mkRTKey(CshiftVector)>(loc, builder);
43   auto fTy = cshiftFunc.getFunctionType();
44 
45   auto sourceFile = fir::factory::locationToFilename(builder, loc);
46   auto sourceLine =
47       fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
48   auto args = fir::runtime::createArguments(
49       builder, loc, fTy, resultBox, arrayBox, shiftBox, sourceFile, sourceLine);
50   builder.create<fir::CallOp>(loc, cshiftFunc, args);
51 }
52 
53 /// Generate call to Eoshift intrinsic
genEoshift(fir::FirOpBuilder & builder,mlir::Location loc,mlir::Value resultBox,mlir::Value arrayBox,mlir::Value shiftBox,mlir::Value boundBox,mlir::Value dimBox)54 void fir::runtime::genEoshift(fir::FirOpBuilder &builder, mlir::Location loc,
55                               mlir::Value resultBox, mlir::Value arrayBox,
56                               mlir::Value shiftBox, mlir::Value boundBox,
57                               mlir::Value dimBox) {
58   auto eoshiftFunc =
59       fir::runtime::getRuntimeFunc<mkRTKey(Eoshift)>(loc, builder);
60   auto fTy = eoshiftFunc.getFunctionType();
61   auto sourceFile = fir::factory::locationToFilename(builder, loc);
62   auto sourceLine =
63       fir::factory::locationToLineNo(builder, loc, fTy.getInput(6));
64   auto args = fir::runtime::createArguments(builder, loc, fTy, resultBox,
65                                             arrayBox, shiftBox, boundBox,
66                                             dimBox, sourceFile, sourceLine);
67   builder.create<fir::CallOp>(loc, eoshiftFunc, args);
68 }
69 
70 /// Generate call to the vector version of the Eoshift intrinsic
genEoshiftVector(fir::FirOpBuilder & builder,mlir::Location loc,mlir::Value resultBox,mlir::Value arrayBox,mlir::Value shiftBox,mlir::Value boundBox)71 void fir::runtime::genEoshiftVector(fir::FirOpBuilder &builder,
72                                     mlir::Location loc, mlir::Value resultBox,
73                                     mlir::Value arrayBox, mlir::Value shiftBox,
74                                     mlir::Value boundBox) {
75   auto eoshiftFunc =
76       fir::runtime::getRuntimeFunc<mkRTKey(EoshiftVector)>(loc, builder);
77   auto fTy = eoshiftFunc.getFunctionType();
78 
79   auto sourceFile = fir::factory::locationToFilename(builder, loc);
80   auto sourceLine =
81       fir::factory::locationToLineNo(builder, loc, fTy.getInput(5));
82 
83   auto args =
84       fir::runtime::createArguments(builder, loc, fTy, resultBox, arrayBox,
85                                     shiftBox, boundBox, sourceFile, sourceLine);
86   builder.create<fir::CallOp>(loc, eoshiftFunc, args);
87 }
88 
89 /// Generate call to Matmul intrinsic runtime routine.
genMatmul(fir::FirOpBuilder & builder,mlir::Location loc,mlir::Value resultBox,mlir::Value matrixABox,mlir::Value matrixBBox)90 void fir::runtime::genMatmul(fir::FirOpBuilder &builder, mlir::Location loc,
91                              mlir::Value resultBox, mlir::Value matrixABox,
92                              mlir::Value matrixBBox) {
93   auto func = fir::runtime::getRuntimeFunc<mkRTKey(Matmul)>(loc, builder);
94   auto fTy = func.getFunctionType();
95   auto sourceFile = fir::factory::locationToFilename(builder, loc);
96   auto sourceLine =
97       fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
98   auto args =
99       fir::runtime::createArguments(builder, loc, fTy, resultBox, matrixABox,
100                                     matrixBBox, sourceFile, sourceLine);
101   builder.create<fir::CallOp>(loc, func, args);
102 }
103 
104 /// Generate call to Pack intrinsic runtime routine.
genPack(fir::FirOpBuilder & builder,mlir::Location loc,mlir::Value resultBox,mlir::Value arrayBox,mlir::Value maskBox,mlir::Value vectorBox)105 void fir::runtime::genPack(fir::FirOpBuilder &builder, mlir::Location loc,
106                            mlir::Value resultBox, mlir::Value arrayBox,
107                            mlir::Value maskBox, mlir::Value vectorBox) {
108   auto packFunc = fir::runtime::getRuntimeFunc<mkRTKey(Pack)>(loc, builder);
109   auto fTy = packFunc.getFunctionType();
110   auto sourceFile = fir::factory::locationToFilename(builder, loc);
111   auto sourceLine =
112       fir::factory::locationToLineNo(builder, loc, fTy.getInput(5));
113   auto args =
114       fir::runtime::createArguments(builder, loc, fTy, resultBox, arrayBox,
115                                     maskBox, vectorBox, sourceFile, sourceLine);
116   builder.create<fir::CallOp>(loc, packFunc, args);
117 }
118 
119 /// Generate call to Reshape intrinsic runtime routine.
genReshape(fir::FirOpBuilder & builder,mlir::Location loc,mlir::Value resultBox,mlir::Value sourceBox,mlir::Value shapeBox,mlir::Value padBox,mlir::Value orderBox)120 void fir::runtime::genReshape(fir::FirOpBuilder &builder, mlir::Location loc,
121                               mlir::Value resultBox, mlir::Value sourceBox,
122                               mlir::Value shapeBox, mlir::Value padBox,
123                               mlir::Value orderBox) {
124   auto func = fir::runtime::getRuntimeFunc<mkRTKey(Reshape)>(loc, builder);
125   auto fTy = func.getFunctionType();
126   auto sourceFile = fir::factory::locationToFilename(builder, loc);
127   auto sourceLine =
128       fir::factory::locationToLineNo(builder, loc, fTy.getInput(6));
129   auto args = fir::runtime::createArguments(builder, loc, fTy, resultBox,
130                                             sourceBox, shapeBox, padBox,
131                                             orderBox, sourceFile, sourceLine);
132   builder.create<fir::CallOp>(loc, func, args);
133 }
134 
135 /// Generate call to Spread intrinsic runtime routine.
genSpread(fir::FirOpBuilder & builder,mlir::Location loc,mlir::Value resultBox,mlir::Value sourceBox,mlir::Value dim,mlir::Value ncopies)136 void fir::runtime::genSpread(fir::FirOpBuilder &builder, mlir::Location loc,
137                              mlir::Value resultBox, mlir::Value sourceBox,
138                              mlir::Value dim, mlir::Value ncopies) {
139   auto func = fir::runtime::getRuntimeFunc<mkRTKey(Spread)>(loc, builder);
140   auto fTy = func.getFunctionType();
141   auto sourceFile = fir::factory::locationToFilename(builder, loc);
142   auto sourceLine =
143       fir::factory::locationToLineNo(builder, loc, fTy.getInput(5));
144   auto args =
145       fir::runtime::createArguments(builder, loc, fTy, resultBox, sourceBox,
146                                     dim, ncopies, sourceFile, sourceLine);
147   builder.create<fir::CallOp>(loc, func, args);
148 }
149 
150 /// Generate call to Transpose intrinsic runtime routine.
genTranspose(fir::FirOpBuilder & builder,mlir::Location loc,mlir::Value resultBox,mlir::Value sourceBox)151 void fir::runtime::genTranspose(fir::FirOpBuilder &builder, mlir::Location loc,
152                                 mlir::Value resultBox, mlir::Value sourceBox) {
153   auto func = fir::runtime::getRuntimeFunc<mkRTKey(Transpose)>(loc, builder);
154   auto fTy = func.getFunctionType();
155   auto sourceFile = fir::factory::locationToFilename(builder, loc);
156   auto sourceLine =
157       fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));
158   auto args = fir::runtime::createArguments(builder, loc, fTy, resultBox,
159                                             sourceBox, sourceFile, sourceLine);
160   builder.create<fir::CallOp>(loc, func, args);
161 }
162 
163 /// Generate call to Unpack intrinsic runtime routine.
genUnpack(fir::FirOpBuilder & builder,mlir::Location loc,mlir::Value resultBox,mlir::Value vectorBox,mlir::Value maskBox,mlir::Value fieldBox)164 void fir::runtime::genUnpack(fir::FirOpBuilder &builder, mlir::Location loc,
165                              mlir::Value resultBox, mlir::Value vectorBox,
166                              mlir::Value maskBox, mlir::Value fieldBox) {
167   auto unpackFunc = fir::runtime::getRuntimeFunc<mkRTKey(Unpack)>(loc, builder);
168   auto fTy = unpackFunc.getFunctionType();
169   auto sourceFile = fir::factory::locationToFilename(builder, loc);
170   auto sourceLine =
171       fir::factory::locationToLineNo(builder, loc, fTy.getInput(5));
172   auto args =
173       fir::runtime::createArguments(builder, loc, fTy, resultBox, vectorBox,
174                                     maskBox, fieldBox, sourceFile, sourceLine);
175   builder.create<fir::CallOp>(loc, unpackFunc, args);
176 }
177