diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Derived.h b/flang/include/flang/Optimizer/Builder/Runtime/Derived.h new file mode 100644 --- /dev/null +++ b/flang/include/flang/Optimizer/Builder/Runtime/Derived.h @@ -0,0 +1,34 @@ +//===-- Derived.h - generate derived type runtime API calls -*- C++ -----*-===// +// +// 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_DERIVED_H +#define FORTRAN_OPTIMIZER_BUILDER_RUNTIME_DERIVED_H + +namespace mlir { +class Value; +class Location; +} // namespace mlir + +namespace fir { +class FirOpBuilder; +} + +namespace fir::runtime { + +/// Generate call to derived type initialization runtime routine to +/// default initialize \p box. +void genDerivedTypeInitialize(fir::FirOpBuilder &builder, mlir::Location loc, + mlir::Value box); + +/// Generate call to derived type destruction runtime routine to +/// destroy \p box. +void genDerivedTypeDestroy(fir::FirOpBuilder &builder, mlir::Location loc, + mlir::Value box); + +} // namespace fir::runtime +#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_DERIVED_H diff --git a/flang/lib/Optimizer/Builder/CMakeLists.txt b/flang/lib/Optimizer/Builder/CMakeLists.txt --- a/flang/lib/Optimizer/Builder/CMakeLists.txt +++ b/flang/lib/Optimizer/Builder/CMakeLists.txt @@ -7,6 +7,7 @@ DoLoopHelper.cpp FIRBuilder.cpp MutableBox.cpp + Runtime/Derived.cpp Runtime/Reduction.cpp DEPENDS diff --git a/flang/lib/Optimizer/Builder/Runtime/Derived.cpp b/flang/lib/Optimizer/Builder/Runtime/Derived.cpp new file mode 100644 --- /dev/null +++ b/flang/lib/Optimizer/Builder/Runtime/Derived.cpp @@ -0,0 +1,35 @@ +//===-- Derived.cpp -- derived type runtime API ---------------------------===// +// +// 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/Derived.h" +#include "flang/Optimizer/Builder/FIRBuilder.h" +#include "flang/Optimizer/Builder/Runtime/RTBuilder.h" +#include "flang/Runtime/derived-api.h" + +using namespace Fortran::runtime; + +void fir::runtime::genDerivedTypeInitialize(fir::FirOpBuilder &builder, + mlir::Location loc, + mlir::Value box) { + auto func = fir::runtime::getRuntimeFunc(loc, builder); + auto fTy = func.getType(); + auto sourceFile = fir::factory::locationToFilename(builder, loc); + auto sourceLine = + fir::factory::locationToLineNo(builder, loc, fTy.getInput(2)); + auto args = fir::runtime::createArguments(builder, loc, fTy, box, sourceFile, + sourceLine); + builder.create(loc, func, args); +} + +void fir::runtime::genDerivedTypeDestroy(fir::FirOpBuilder &builder, + mlir::Location loc, mlir::Value box) { + auto func = fir::runtime::getRuntimeFunc(loc, builder); + auto fTy = func.getType(); + auto args = fir::runtime::createArguments(builder, loc, fTy, box); + builder.create(loc, func, args); +} diff --git a/flang/unittests/Optimizer/Builder/Runtime/DerivedTest.cpp b/flang/unittests/Optimizer/Builder/Runtime/DerivedTest.cpp new file mode 100644 --- /dev/null +++ b/flang/unittests/Optimizer/Builder/Runtime/DerivedTest.cpp @@ -0,0 +1,29 @@ +//===- DerivedTest.cpp -- Derived type runtime builder unit tests ---------===// +// +// 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/Derived.h" +#include "RuntimeCallTestBase.h" +#include "gtest/gtest.h" + +TEST_F(RuntimeCallTest, genDerivedTypeInitialize) { + auto loc = firBuilder->getUnknownLoc(); + mlir::Type seqTy = + fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty); + mlir::Value box = firBuilder->create(loc, seqTy); + fir::runtime::genDerivedTypeInitialize(*firBuilder, loc, box); + checkCallOpFromResultBox(box, "_FortranAInitialize", 1); +} + +TEST_F(RuntimeCallTest, genDerivedTypeDestroy) { + auto loc = firBuilder->getUnknownLoc(); + mlir::Type seqTy = + fir::SequenceType::get(fir::SequenceType::Shape(1, 10), i32Ty); + mlir::Value box = firBuilder->create(loc, seqTy); + fir::runtime::genDerivedTypeDestroy(*firBuilder, loc, box); + checkCallOpFromResultBox(box, "_FortranADestroy", 1, /*addLocArg=*/false); +} diff --git a/flang/unittests/Optimizer/Builder/Runtime/RuntimeCallTestBase.h b/flang/unittests/Optimizer/Builder/Runtime/RuntimeCallTestBase.h --- a/flang/unittests/Optimizer/Builder/Runtime/RuntimeCallTestBase.h +++ b/flang/unittests/Optimizer/Builder/Runtime/RuntimeCallTestBase.h @@ -70,26 +70,28 @@ mlir::Type c16Ty; }; -static void checkCallOp( - mlir::Operation *op, llvm::StringRef fctName, unsigned nbArgs) { +static void checkCallOp(mlir::Operation *op, llvm::StringRef fctName, + unsigned nbArgs, bool addLocArg = true) { EXPECT_TRUE(mlir::isa(*op)); auto callOp = mlir::dyn_cast(*op); EXPECT_TRUE(callOp.callee().hasValue()); mlir::SymbolRefAttr callee = *callOp.callee(); EXPECT_EQ(fctName, callee.getRootReference().getValue()); // sourceFile and sourceLine are added arguments. - EXPECT_EQ(nbArgs + 2, callOp.args().size()); + if (addLocArg) + nbArgs += 2; + EXPECT_EQ(nbArgs, callOp.args().size()); } -static void checkCallOpFromResultBox( - mlir::Value result, llvm::StringRef fctName, unsigned nbArgs) { +static void checkCallOpFromResultBox(mlir::Value result, + llvm::StringRef fctName, unsigned nbArgs, bool addLocArg = true) { EXPECT_TRUE(result.hasOneUse()); for (auto &u : result.getUses()) { if (mlir::isa(*u.getOwner())) { - checkCallOp(u.getOwner(), fctName, nbArgs); + checkCallOp(u.getOwner(), fctName, nbArgs, addLocArg); } else { auto convOp = mlir::dyn_cast(*u.getOwner()); - checkCallOpFromResultBox(convOp.getResult(), fctName, nbArgs); + checkCallOpFromResultBox(convOp.getResult(), fctName, nbArgs, addLocArg); } } } diff --git a/flang/unittests/Optimizer/CMakeLists.txt b/flang/unittests/Optimizer/CMakeLists.txt --- a/flang/unittests/Optimizer/CMakeLists.txt +++ b/flang/unittests/Optimizer/CMakeLists.txt @@ -13,6 +13,7 @@ Builder/ComplexTest.cpp Builder/DoLoopHelperTest.cpp Builder/FIRBuilderTest.cpp + Builder/Runtime/DerivedTest.cpp Builder/Runtime/ReductionTest.cpp FIRContextTest.cpp InternalNamesTest.cpp