[flang-commits] [flang] 18452d1 - [fir] Add fir transformational intrinsic builder
Valentin Clement via flang-commits
flang-commits at lists.llvm.org
Mon Nov 29 01:09:48 PST 2021
Author: Valentin Clement
Date: 2021-11-29T10:09:36+01:00
New Revision: 18452d1f12479ff5e1b437ef7efc9538e505c437
URL: https://github.com/llvm/llvm-project/commit/18452d1f12479ff5e1b437ef7efc9538e505c437
DIFF: https://github.com/llvm/llvm-project/commit/18452d1f12479ff5e1b437ef7efc9538e505c437.diff
LOG: [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 <jperier at nvidia.com>
Co-authored-by: mleair <leairmark at gmail.com>
Co-authored-by: Kiran Chandramohan <kiran.chandramohan at arm.com>
Co-authored-by: Peter Steinfeld <psteinfeld at nvidia.com>
Added:
flang/include/flang/Optimizer/Builder/Runtime/Transformational.h
flang/lib/Optimizer/Builder/Runtime/Transformational.cpp
flang/unittests/Optimizer/Builder/Runtime/TransformationalTest.cpp
Modified:
flang/lib/Optimizer/Builder/CMakeLists.txt
flang/unittests/Optimizer/CMakeLists.txt
Removed:
################################################################################
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Transformational.h b/flang/include/flang/Optimizer/Builder/Runtime/Transformational.h
new file mode 100644
index 000000000000..5f1f28b78656
--- /dev/null
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Transformational.h
@@ -0,0 +1,63 @@
+//===-- Transformational.h --------------------------------------*- C++ -*-===//
+// Generate transformational intrinsic 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_OPTIMIZER_BUILDER_RUNTIME_TRANSFORMATIONAL_H
+#define FORTRAN_OPTIMIZER_BUILDER_RUNTIME_TRANSFORMATIONAL_H
+
+#include "mlir/Dialect/StandardOps/IR/Ops.h"
+
+namespace fir {
+class ExtendedValue;
+class FirOpBuilder;
+} // namespace fir
+
+namespace fir::runtime {
+
+void genCshift(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultBox, mlir::Value arrayBox,
+ mlir::Value shiftBox, mlir::Value dimBox);
+
+void genCshiftVector(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultBox, mlir::Value arrayBox,
+ mlir::Value shiftBox);
+
+void genEoshift(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultBox, mlir::Value arrayBox,
+ mlir::Value shiftBox, mlir::Value boundBox, mlir::Value dimBox);
+
+void genEoshiftVector(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultBox, mlir::Value arrayBox,
+ mlir::Value shiftBox, mlir::Value boundBox);
+
+void genMatmul(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value matrixABox, mlir::Value matrixBBox,
+ mlir::Value resultBox);
+
+void genPack(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultBox, mlir::Value arrayBox, mlir::Value maskBox,
+ mlir::Value vectorBox);
+
+void genReshape(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultBox, mlir::Value sourceBox,
+ mlir::Value shapeBox, mlir::Value padBox, mlir::Value orderBox);
+
+void genSpread(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultBox, mlir::Value sourceBox, mlir::Value dim,
+ mlir::Value ncopies);
+
+void genTranspose(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultBox, mlir::Value sourceBox);
+
+void genUnpack(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultBox, mlir::Value vectorBox,
+ mlir::Value maskBox, mlir::Value fieldBox);
+
+} // namespace fir::runtime
+
+#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_TRANSFORMATIONAL_H
diff --git a/flang/lib/Optimizer/Builder/CMakeLists.txt b/flang/lib/Optimizer/Builder/CMakeLists.txt
index 13c10128905b..228423315d70 100644
--- a/flang/lib/Optimizer/Builder/CMakeLists.txt
+++ b/flang/lib/Optimizer/Builder/CMakeLists.txt
@@ -7,6 +7,7 @@ add_flang_library(FIRBuilder
DoLoopHelper.cpp
FIRBuilder.cpp
MutableBox.cpp
+ Runtime/Transformational.cpp
DEPENDS
FIRDialect
diff --git a/flang/lib/Optimizer/Builder/Runtime/Transformational.cpp b/flang/lib/Optimizer/Builder/Runtime/Transformational.cpp
new file mode 100644
index 000000000000..467f09ef2f7b
--- /dev/null
+++ b/flang/lib/Optimizer/Builder/Runtime/Transformational.cpp
@@ -0,0 +1,176 @@
+//===-- Transformational.cpp ------------------------------------*- C++ -*-===//
+// Generate transformational intrinsic 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/Transformational.h"
+#include "flang/Lower/Todo.h"
+#include "flang/Optimizer/Builder/BoxValue.h"
+#include "flang/Optimizer/Builder/Character.h"
+#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
+#include "flang/Runtime/matmul.h"
+#include "flang/Runtime/transformational.h"
+#include "mlir/Dialect/StandardOps/IR/Ops.h"
+
+using namespace Fortran::runtime;
+
+/// Generate call to Cshift intrinsic
+void fir::runtime::genCshift(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultBox, mlir::Value arrayBox,
+ mlir::Value shiftBox, mlir::Value dimBox) {
+ auto cshiftFunc = fir::runtime::getRuntimeFunc<mkRTKey(Cshift)>(loc, builder);
+ auto fTy = cshiftFunc.getType();
+ auto sourceFile = fir::factory::locationToFilename(builder, loc);
+ auto sourceLine =
+ fir::factory::locationToLineNo(builder, loc, fTy.getInput(5));
+ auto args =
+ fir::runtime::createArguments(builder, loc, fTy, resultBox, arrayBox,
+ shiftBox, dimBox, sourceFile, sourceLine);
+ builder.create<fir::CallOp>(loc, cshiftFunc, args);
+}
+
+/// Generate call to the vector version of the Cshift intrinsic
+void fir::runtime::genCshiftVector(fir::FirOpBuilder &builder,
+ mlir::Location loc, mlir::Value resultBox,
+ mlir::Value arrayBox, mlir::Value shiftBox) {
+ auto cshiftFunc =
+ fir::runtime::getRuntimeFunc<mkRTKey(CshiftVector)>(loc, builder);
+ auto fTy = cshiftFunc.getType();
+
+ auto sourceFile = fir::factory::locationToFilename(builder, loc);
+ auto sourceLine =
+ fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
+ auto args = fir::runtime::createArguments(
+ builder, loc, fTy, resultBox, arrayBox, shiftBox, sourceFile, sourceLine);
+ builder.create<fir::CallOp>(loc, cshiftFunc, args);
+}
+
+/// Generate call to Eoshift intrinsic
+void fir::runtime::genEoshift(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultBox, mlir::Value arrayBox,
+ mlir::Value shiftBox, mlir::Value boundBox,
+ mlir::Value dimBox) {
+ auto eoshiftFunc =
+ fir::runtime::getRuntimeFunc<mkRTKey(Eoshift)>(loc, builder);
+ auto fTy = eoshiftFunc.getType();
+ auto sourceFile = fir::factory::locationToFilename(builder, loc);
+ auto sourceLine =
+ fir::factory::locationToLineNo(builder, loc, fTy.getInput(6));
+ auto args = fir::runtime::createArguments(builder, loc, fTy, resultBox,
+ arrayBox, shiftBox, boundBox,
+ dimBox, sourceFile, sourceLine);
+ builder.create<fir::CallOp>(loc, eoshiftFunc, args);
+}
+
+/// Generate call to the vector version of the Eoshift intrinsic
+void fir::runtime::genEoshiftVector(fir::FirOpBuilder &builder,
+ mlir::Location loc, mlir::Value resultBox,
+ mlir::Value arrayBox, mlir::Value shiftBox,
+ mlir::Value boundBox) {
+ auto eoshiftFunc =
+ fir::runtime::getRuntimeFunc<mkRTKey(EoshiftVector)>(loc, builder);
+ auto fTy = eoshiftFunc.getType();
+
+ auto sourceFile = fir::factory::locationToFilename(builder, loc);
+ auto sourceLine =
+ fir::factory::locationToLineNo(builder, loc, fTy.getInput(5));
+
+ auto args =
+ fir::runtime::createArguments(builder, loc, fTy, resultBox, arrayBox,
+ shiftBox, boundBox, sourceFile, sourceLine);
+ builder.create<fir::CallOp>(loc, eoshiftFunc, args);
+}
+
+/// Generate call to Matmul intrinsic runtime routine.
+void fir::runtime::genMatmul(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultBox, mlir::Value matrixABox,
+ mlir::Value matrixBBox) {
+ auto func = fir::runtime::getRuntimeFunc<mkRTKey(Matmul)>(loc, builder);
+ auto fTy = func.getType();
+ auto sourceFile = fir::factory::locationToFilename(builder, loc);
+ auto sourceLine =
+ fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
+ auto args =
+ fir::runtime::createArguments(builder, loc, fTy, resultBox, matrixABox,
+ matrixBBox, sourceFile, sourceLine);
+ builder.create<fir::CallOp>(loc, func, args);
+}
+
+/// Generate call to Pack intrinsic runtime routine.
+void fir::runtime::genPack(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultBox, mlir::Value arrayBox,
+ mlir::Value maskBox, mlir::Value vectorBox) {
+ auto packFunc = fir::runtime::getRuntimeFunc<mkRTKey(Pack)>(loc, builder);
+ auto fTy = packFunc.getType();
+ auto sourceFile = fir::factory::locationToFilename(builder, loc);
+ auto sourceLine =
+ fir::factory::locationToLineNo(builder, loc, fTy.getInput(5));
+ auto args =
+ fir::runtime::createArguments(builder, loc, fTy, resultBox, arrayBox,
+ maskBox, vectorBox, sourceFile, sourceLine);
+ builder.create<fir::CallOp>(loc, packFunc, args);
+}
+
+/// Generate call to Reshape intrinsic runtime routine.
+void fir::runtime::genReshape(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultBox, mlir::Value sourceBox,
+ mlir::Value shapeBox, mlir::Value padBox,
+ mlir::Value orderBox) {
+ auto func = fir::runtime::getRuntimeFunc<mkRTKey(Reshape)>(loc, builder);
+ auto fTy = func.getType();
+ auto sourceFile = fir::factory::locationToFilename(builder, loc);
+ auto sourceLine =
+ fir::factory::locationToLineNo(builder, loc, fTy.getInput(6));
+ auto args = fir::runtime::createArguments(builder, loc, fTy, resultBox,
+ sourceBox, shapeBox, padBox,
+ orderBox, sourceFile, sourceLine);
+ builder.create<fir::CallOp>(loc, func, args);
+}
+
+/// Generate call to Spread intrinsic runtime routine.
+void fir::runtime::genSpread(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultBox, mlir::Value sourceBox,
+ mlir::Value dim, mlir::Value ncopies) {
+ auto func = fir::runtime::getRuntimeFunc<mkRTKey(Spread)>(loc, builder);
+ auto fTy = func.getType();
+ auto sourceFile = fir::factory::locationToFilename(builder, loc);
+ auto sourceLine =
+ fir::factory::locationToLineNo(builder, loc, fTy.getInput(5));
+ auto args =
+ fir::runtime::createArguments(builder, loc, fTy, resultBox, sourceBox,
+ dim, ncopies, sourceFile, sourceLine);
+ builder.create<fir::CallOp>(loc, func, args);
+}
+
+/// Generate call to Transpose intrinsic runtime routine.
+void fir::runtime::genTranspose(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultBox, mlir::Value sourceBox) {
+ auto func = fir::runtime::getRuntimeFunc<mkRTKey(Transpose)>(loc, builder);
+ auto fTy = func.getType();
+ auto sourceFile = fir::factory::locationToFilename(builder, loc);
+ auto sourceLine =
+ fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));
+ auto args = fir::runtime::createArguments(builder, loc, fTy, resultBox,
+ sourceBox, sourceFile, sourceLine);
+ builder.create<fir::CallOp>(loc, func, args);
+}
+
+/// Generate call to Unpack intrinsic runtime routine.
+void fir::runtime::genUnpack(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value resultBox, mlir::Value vectorBox,
+ mlir::Value maskBox, mlir::Value fieldBox) {
+ auto unpackFunc = fir::runtime::getRuntimeFunc<mkRTKey(Unpack)>(loc, builder);
+ auto fTy = unpackFunc.getType();
+ auto sourceFile = fir::factory::locationToFilename(builder, loc);
+ auto sourceLine =
+ fir::factory::locationToLineNo(builder, loc, fTy.getInput(5));
+ auto args =
+ fir::runtime::createArguments(builder, loc, fTy, resultBox, vectorBox,
+ maskBox, fieldBox, sourceFile, sourceLine);
+ builder.create<fir::CallOp>(loc, unpackFunc, args);
+}
diff --git a/flang/unittests/Optimizer/Builder/Runtime/TransformationalTest.cpp b/flang/unittests/Optimizer/Builder/Runtime/TransformationalTest.cpp
new file mode 100644
index 000000000000..37e13ccb06b5
--- /dev/null
+++ b/flang/unittests/Optimizer/Builder/Runtime/TransformationalTest.cpp
@@ -0,0 +1,129 @@
+//===- TransformationalTest.cpp -- Transformational intrinsic generation --===//
+//
+// 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/Transformational.h"
+#include "RuntimeCallTestBase.h"
+#include "gtest/gtest.h"
+
+TEST_F(RuntimeCallTest, genCshiftTest) {
+ auto loc = firBuilder->getUnknownLoc();
+ mlir::Type seqTy =
+ fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);
+ mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value array = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value shift = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value dim = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ fir::runtime::genCshift(*firBuilder, loc, result, array, shift, dim);
+ checkCallOpFromResultBox(result, "_FortranACshift", 4);
+}
+
+TEST_F(RuntimeCallTest, genCshiftVectorTest) {
+ auto loc = firBuilder->getUnknownLoc();
+ mlir::Type seqTy =
+ fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);
+ mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value array = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value shift = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ fir::runtime::genCshiftVector(*firBuilder, loc, result, array, shift);
+ checkCallOpFromResultBox(result, "_FortranACshiftVector", 3);
+}
+
+TEST_F(RuntimeCallTest, genEoshiftTest) {
+ auto loc = firBuilder->getUnknownLoc();
+ mlir::Type seqTy =
+ fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);
+ mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value array = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value shift = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value bound = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value dim = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ fir::runtime::genEoshift(*firBuilder, loc, result, array, shift, bound, dim);
+ checkCallOpFromResultBox(result, "_FortranAEoshift", 5);
+}
+
+TEST_F(RuntimeCallTest, genEoshiftVectorTest) {
+ auto loc = firBuilder->getUnknownLoc();
+ mlir::Type seqTy =
+ fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);
+ mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value array = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value shift = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value bound = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ fir::runtime::genEoshiftVector(*firBuilder, loc, result, array, shift, bound);
+ checkCallOpFromResultBox(result, "_FortranAEoshiftVector", 4);
+}
+
+TEST_F(RuntimeCallTest, genMatmulTest) {
+ auto loc = firBuilder->getUnknownLoc();
+ mlir::Type seqTy =
+ fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);
+ mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value matrixA = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value matrixB = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ fir::runtime::genMatmul(*firBuilder, loc, matrixA, matrixB, result);
+ checkCallOpFromResultBox(result, "_FortranAMatmul", 3);
+}
+
+TEST_F(RuntimeCallTest, genPackTest) {
+ auto loc = firBuilder->getUnknownLoc();
+ mlir::Type seqTy =
+ fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);
+ mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value array = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value mask = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value vector = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ fir::runtime::genPack(*firBuilder, loc, result, array, mask, vector);
+ checkCallOpFromResultBox(result, "_FortranAPack", 4);
+}
+
+TEST_F(RuntimeCallTest, genReshapeTest) {
+ auto loc = firBuilder->getUnknownLoc();
+ mlir::Type seqTy =
+ fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);
+ mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value source = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value shape = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value pad = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value order = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ fir::runtime::genReshape(*firBuilder, loc, result, source, shape, pad, order);
+ checkCallOpFromResultBox(result, "_FortranAReshape", 5);
+}
+
+TEST_F(RuntimeCallTest, genSpreadTest) {
+ auto loc = firBuilder->getUnknownLoc();
+ mlir::Type seqTy =
+ fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);
+ mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value source = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value dim = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value ncopies = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ fir::runtime::genSpread(*firBuilder, loc, result, source, dim, ncopies);
+ checkCallOpFromResultBox(result, "_FortranASpread", 4);
+}
+
+TEST_F(RuntimeCallTest, genTransposeTest) {
+ auto loc = firBuilder->getUnknownLoc();
+ mlir::Type seqTy =
+ fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);
+ mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value source = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ fir::runtime::genTranspose(*firBuilder, loc, result, source);
+ checkCallOpFromResultBox(result, "_FortranATranspose", 2);
+}
+
+TEST_F(RuntimeCallTest, genUnpack) {
+ auto loc = firBuilder->getUnknownLoc();
+ mlir::Type seqTy =
+ fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty);
+ mlir::Value result = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value vector = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value mask = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ mlir::Value field = firBuilder->create<fir::UndefOp>(loc, seqTy);
+ fir::runtime::genUnpack(*firBuilder, loc, result, vector, mask, field);
+ checkCallOpFromResultBox(result, "_FortranAUnpack", 4);
+}
diff --git a/flang/unittests/Optimizer/CMakeLists.txt b/flang/unittests/Optimizer/CMakeLists.txt
index e54aae6554de..d36dda71b914 100644
--- a/flang/unittests/Optimizer/CMakeLists.txt
+++ b/flang/unittests/Optimizer/CMakeLists.txt
@@ -13,6 +13,7 @@ add_flang_unittest(FlangOptimizerTests
Builder/ComplexTest.cpp
Builder/DoLoopHelperTest.cpp
Builder/FIRBuilderTest.cpp
+ Builder/Runtime/TransformationalTest.cpp
FIRContextTest.cpp
InternalNamesTest.cpp
KindMappingTest.cpp
More information about the flang-commits
mailing list