Skip to content

Commit 18452d1

Browse files
clementvaljeanPeriermleairkiranchandramohanpsteinfeld
committed
[fir] Add fir transformational intrinsic builder
This patch adds the builder to generate transformational intrinsic runtime API calls. This patch is part of the upstreaming effort from fir-dev branch. Reviewed By: rovka Differential Revision: https://reviews.llvm.org/D114470 Co-authored-by: Jean Perier <[email protected]> Co-authored-by: mleair <[email protected]> Co-authored-by: Kiran Chandramohan <[email protected]> Co-authored-by: Peter Steinfeld <[email protected]>
1 parent fd71159 commit 18452d1

File tree

5 files changed

+370
-0
lines changed

5 files changed

+370
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//===-- Transformational.h --------------------------------------*- 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+
#ifndef FORTRAN_OPTIMIZER_BUILDER_RUNTIME_TRANSFORMATIONAL_H
11+
#define FORTRAN_OPTIMIZER_BUILDER_RUNTIME_TRANSFORMATIONAL_H
12+
13+
#include "mlir/Dialect/StandardOps/IR/Ops.h"
14+
15+
namespace fir {
16+
class ExtendedValue;
17+
class FirOpBuilder;
18+
} // namespace fir
19+
20+
namespace fir::runtime {
21+
22+
void genCshift(fir::FirOpBuilder &builder, mlir::Location loc,
23+
mlir::Value resultBox, mlir::Value arrayBox,
24+
mlir::Value shiftBox, mlir::Value dimBox);
25+
26+
void genCshiftVector(fir::FirOpBuilder &builder, mlir::Location loc,
27+
mlir::Value resultBox, mlir::Value arrayBox,
28+
mlir::Value shiftBox);
29+
30+
void genEoshift(fir::FirOpBuilder &builder, mlir::Location loc,
31+
mlir::Value resultBox, mlir::Value arrayBox,
32+
mlir::Value shiftBox, mlir::Value boundBox, mlir::Value dimBox);
33+
34+
void genEoshiftVector(fir::FirOpBuilder &builder, mlir::Location loc,
35+
mlir::Value resultBox, mlir::Value arrayBox,
36+
mlir::Value shiftBox, mlir::Value boundBox);
37+
38+
void genMatmul(fir::FirOpBuilder &builder, mlir::Location loc,
39+
mlir::Value matrixABox, mlir::Value matrixBBox,
40+
mlir::Value resultBox);
41+
42+
void genPack(fir::FirOpBuilder &builder, mlir::Location loc,
43+
mlir::Value resultBox, mlir::Value arrayBox, mlir::Value maskBox,
44+
mlir::Value vectorBox);
45+
46+
void genReshape(fir::FirOpBuilder &builder, mlir::Location loc,
47+
mlir::Value resultBox, mlir::Value sourceBox,
48+
mlir::Value shapeBox, mlir::Value padBox, mlir::Value orderBox);
49+
50+
void genSpread(fir::FirOpBuilder &builder, mlir::Location loc,
51+
mlir::Value resultBox, mlir::Value sourceBox, mlir::Value dim,
52+
mlir::Value ncopies);
53+
54+
void genTranspose(fir::FirOpBuilder &builder, mlir::Location loc,
55+
mlir::Value resultBox, mlir::Value sourceBox);
56+
57+
void genUnpack(fir::FirOpBuilder &builder, mlir::Location loc,
58+
mlir::Value resultBox, mlir::Value vectorBox,
59+
mlir::Value maskBox, mlir::Value fieldBox);
60+
61+
} // namespace fir::runtime
62+
63+
#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_TRANSFORMATIONAL_H

flang/lib/Optimizer/Builder/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ add_flang_library(FIRBuilder
77
DoLoopHelper.cpp
88
FIRBuilder.cpp
99
MutableBox.cpp
10+
Runtime/Transformational.cpp
1011

1112
DEPENDS
1213
FIRDialect
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
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/Lower/Todo.h"
12+
#include "flang/Optimizer/Builder/BoxValue.h"
13+
#include "flang/Optimizer/Builder/Character.h"
14+
#include "flang/Optimizer/Builder/FIRBuilder.h"
15+
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
16+
#include "flang/Runtime/matmul.h"
17+
#include "flang/Runtime/transformational.h"
18+
#include "mlir/Dialect/StandardOps/IR/Ops.h"
19+
20+
using namespace Fortran::runtime;
21+
22+
/// Generate call to Cshift intrinsic
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.getType();
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
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.getType();
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
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.getType();
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
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.getType();
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.
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.getType();
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.
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.getType();
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.
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.getType();
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.
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.getType();
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.
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.getType();
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.
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.getType();
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+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
//===- TransformationalTest.cpp -- Transformational intrinsic generation --===//
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/Transformational.h"
10+
#include "RuntimeCallTestBase.h"
11+
#include "gtest/gtest.h"
12+
13+
TEST_F(RuntimeCallTest, genCshiftTest) {
14+
auto loc = firBuilder->getUnknownLoc();
15+
mlir::Type seqTy =
16+
fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);
17+
mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy);
18+
mlir::Value array = firBuilder->create<fir::UndefOp>(loc, seqTy);
19+
mlir::Value shift = firBuilder->create<fir::UndefOp>(loc, seqTy);
20+
mlir::Value dim = firBuilder->create<fir::UndefOp>(loc, seqTy);
21+
fir::runtime::genCshift(*firBuilder, loc, result, array, shift, dim);
22+
checkCallOpFromResultBox(result, "_FortranACshift", 4);
23+
}
24+
25+
TEST_F(RuntimeCallTest, genCshiftVectorTest) {
26+
auto loc = firBuilder->getUnknownLoc();
27+
mlir::Type seqTy =
28+
fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);
29+
mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy);
30+
mlir::Value array = firBuilder->create<fir::UndefOp>(loc, seqTy);
31+
mlir::Value shift = firBuilder->create<fir::UndefOp>(loc, seqTy);
32+
fir::runtime::genCshiftVector(*firBuilder, loc, result, array, shift);
33+
checkCallOpFromResultBox(result, "_FortranACshiftVector", 3);
34+
}
35+
36+
TEST_F(RuntimeCallTest, genEoshiftTest) {
37+
auto loc = firBuilder->getUnknownLoc();
38+
mlir::Type seqTy =
39+
fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);
40+
mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy);
41+
mlir::Value array = firBuilder->create<fir::UndefOp>(loc, seqTy);
42+
mlir::Value shift = firBuilder->create<fir::UndefOp>(loc, seqTy);
43+
mlir::Value bound = firBuilder->create<fir::UndefOp>(loc, seqTy);
44+
mlir::Value dim = firBuilder->create<fir::UndefOp>(loc, seqTy);
45+
fir::runtime::genEoshift(*firBuilder, loc, result, array, shift, bound, dim);
46+
checkCallOpFromResultBox(result, "_FortranAEoshift", 5);
47+
}
48+
49+
TEST_F(RuntimeCallTest, genEoshiftVectorTest) {
50+
auto loc = firBuilder->getUnknownLoc();
51+
mlir::Type seqTy =
52+
fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);
53+
mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy);
54+
mlir::Value array = firBuilder->create<fir::UndefOp>(loc, seqTy);
55+
mlir::Value shift = firBuilder->create<fir::UndefOp>(loc, seqTy);
56+
mlir::Value bound = firBuilder->create<fir::UndefOp>(loc, seqTy);
57+
fir::runtime::genEoshiftVector(*firBuilder, loc, result, array, shift, bound);
58+
checkCallOpFromResultBox(result, "_FortranAEoshiftVector", 4);
59+
}
60+
61+
TEST_F(RuntimeCallTest, genMatmulTest) {
62+
auto loc = firBuilder->getUnknownLoc();
63+
mlir::Type seqTy =
64+
fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);
65+
mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy);
66+
mlir::Value matrixA = firBuilder->create<fir::UndefOp>(loc, seqTy);
67+
mlir::Value matrixB = firBuilder->create<fir::UndefOp>(loc, seqTy);
68+
fir::runtime::genMatmul(*firBuilder, loc, matrixA, matrixB, result);
69+
checkCallOpFromResultBox(result, "_FortranAMatmul", 3);
70+
}
71+
72+
TEST_F(RuntimeCallTest, genPackTest) {
73+
auto loc = firBuilder->getUnknownLoc();
74+
mlir::Type seqTy =
75+
fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);
76+
mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy);
77+
mlir::Value array = firBuilder->create<fir::UndefOp>(loc, seqTy);
78+
mlir::Value mask = firBuilder->create<fir::UndefOp>(loc, seqTy);
79+
mlir::Value vector = firBuilder->create<fir::UndefOp>(loc, seqTy);
80+
fir::runtime::genPack(*firBuilder, loc, result, array, mask, vector);
81+
checkCallOpFromResultBox(result, "_FortranAPack", 4);
82+
}
83+
84+
TEST_F(RuntimeCallTest, genReshapeTest) {
85+
auto loc = firBuilder->getUnknownLoc();
86+
mlir::Type seqTy =
87+
fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);
88+
mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy);
89+
mlir::Value source = firBuilder->create<fir::UndefOp>(loc, seqTy);
90+
mlir::Value shape = firBuilder->create<fir::UndefOp>(loc, seqTy);
91+
mlir::Value pad = firBuilder->create<fir::UndefOp>(loc, seqTy);
92+
mlir::Value order = firBuilder->create<fir::UndefOp>(loc, seqTy);
93+
fir::runtime::genReshape(*firBuilder, loc, result, source, shape, pad, order);
94+
checkCallOpFromResultBox(result, "_FortranAReshape", 5);
95+
}
96+
97+
TEST_F(RuntimeCallTest, genSpreadTest) {
98+
auto loc = firBuilder->getUnknownLoc();
99+
mlir::Type seqTy =
100+
fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);
101+
mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy);
102+
mlir::Value source = firBuilder->create<fir::UndefOp>(loc, seqTy);
103+
mlir::Value dim = firBuilder->create<fir::UndefOp>(loc, seqTy);
104+
mlir::Value ncopies = firBuilder->create<fir::UndefOp>(loc, seqTy);
105+
fir::runtime::genSpread(*firBuilder, loc, result, source, dim, ncopies);
106+
checkCallOpFromResultBox(result, "_FortranASpread", 4);
107+
}
108+
109+
TEST_F(RuntimeCallTest, genTransposeTest) {
110+
auto loc = firBuilder->getUnknownLoc();
111+
mlir::Type seqTy =
112+
fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);
113+
mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy);
114+
mlir::Value source = firBuilder->create<fir::UndefOp>(loc, seqTy);
115+
fir::runtime::genTranspose(*firBuilder, loc, result, source);
116+
checkCallOpFromResultBox(result, "_FortranATranspose", 2);
117+
}
118+
119+
TEST_F(RuntimeCallTest, genUnpack) {
120+
auto loc = firBuilder->getUnknownLoc();
121+
mlir::Type seqTy =
122+
fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);
123+
mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy);
124+
mlir::Value vector = firBuilder->create<fir::UndefOp>(loc, seqTy);
125+
mlir::Value mask = firBuilder->create<fir::UndefOp>(loc, seqTy);
126+
mlir::Value field = firBuilder->create<fir::UndefOp>(loc, seqTy);
127+
fir::runtime::genUnpack(*firBuilder, loc, result, vector, mask, field);
128+
checkCallOpFromResultBox(result, "_FortranAUnpack", 4);
129+
}

flang/unittests/Optimizer/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ add_flang_unittest(FlangOptimizerTests
1313
Builder/ComplexTest.cpp
1414
Builder/DoLoopHelperTest.cpp
1515
Builder/FIRBuilderTest.cpp
16+
Builder/Runtime/TransformationalTest.cpp
1617
FIRContextTest.cpp
1718
InternalNamesTest.cpp
1819
KindMappingTest.cpp

0 commit comments

Comments
 (0)