diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Stop.h b/flang/include/flang/Optimizer/Builder/Runtime/Stop.h new file mode 100644 --- /dev/null +++ b/flang/include/flang/Optimizer/Builder/Runtime/Stop.h @@ -0,0 +1,27 @@ +//===-- Stop.h - generate stop 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_STOP_H +#define FORTRAN_OPTIMIZER_BUILDER_RUNTIME_STOP_H + +namespace mlir { +class Value; +class Location; +} // namespace mlir + +namespace fir { +class FirOpBuilder; +} + +namespace fir::runtime { + +/// Generate call to EXIT intrinsic runtime routine. +void genExit(fir::FirOpBuilder &, mlir::Location, mlir::Value status); + +} // namespace fir::runtime +#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_STOP_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 @@ -13,6 +13,7 @@ Runtime/Numeric.cpp Runtime/Ragged.cpp Runtime/Reduction.cpp + Runtime/Stop.cpp Runtime/Transformational.cpp DEPENDS diff --git a/flang/lib/Optimizer/Builder/Runtime/Stop.cpp b/flang/lib/Optimizer/Builder/Runtime/Stop.cpp new file mode 100644 --- /dev/null +++ b/flang/lib/Optimizer/Builder/Runtime/Stop.cpp @@ -0,0 +1,22 @@ +//===-- Stop.h - generate stop 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 +// +//===----------------------------------------------------------------------===// + +#include "flang/Optimizer/Builder/Runtime/Stop.h" +#include "flang/Optimizer/Builder/FIRBuilder.h" +#include "flang/Optimizer/Builder/Runtime/RTBuilder.h" +#include "flang/Runtime/stop.h" + +using namespace Fortran::runtime; + +void fir::runtime::genExit(fir::FirOpBuilder &builder, mlir::Location loc, + mlir::Value status) { + auto exitFunc = fir::runtime::getRuntimeFunc(loc, builder); + llvm::SmallVector args = + fir::runtime::createArguments(builder, loc, exitFunc.getType(), status); + builder.create(loc, exitFunc, args); +} 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 @@ -120,4 +120,25 @@ checkCallOpFromResultBox(convOp.getResult(), fctName, nbArgs, addLocArgs); } +/// Check the operations in \p block for containing a `fir::CallOp` operation +/// where its name matches \p fctName and the number of arguments is equal to \p +/// nbArgs. Note that this check only cares if the operation exists, and not the +/// order in when the operation is called. +static inline void checkBlockForCallOp( + mlir::Block *block, llvm::StringRef fctName, unsigned nbArgs) { + EXPECT_TRUE(block); + bool opFound = false; + for (auto &op : block->getOperations()) { + if (auto callOp = mlir::dyn_cast(op)) { + mlir::SymbolRefAttr callee = *callOp.callee(); + if (fctName == callee.getRootReference().getValue()) { + opFound = true; + EXPECT_EQ(nbArgs, callOp.args().size()); + break; + } + } + } + EXPECT_TRUE(opFound); +} + #endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_RUNTIMECALLTESTBASE_H diff --git a/flang/unittests/Optimizer/Builder/Runtime/StopTest.cpp b/flang/unittests/Optimizer/Builder/Runtime/StopTest.cpp new file mode 100644 --- /dev/null +++ b/flang/unittests/Optimizer/Builder/Runtime/StopTest.cpp @@ -0,0 +1,18 @@ +//===- StopTest.cpp -- Stop 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/Stop.h" +#include "RuntimeCallTestBase.h" +#include "gtest/gtest.h" + +TEST_F(RuntimeCallTest, genExitTest) { + auto loc = firBuilder->getUnknownLoc(); + mlir::Value status = firBuilder->createIntegerConstant(loc, i32Ty, 0); + fir::runtime::genExit(*firBuilder, loc, status); + checkBlockForCallOp(firBuilder->getBlock(), "_FortranAExit", 1); +} 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 @@ -19,6 +19,7 @@ Builder/Runtime/NumericTest.cpp Builder/Runtime/RaggedTest.cpp Builder/Runtime/ReductionTest.cpp + Builder/Runtime/StopTest.cpp Builder/Runtime/TransformationalTest.cpp FIRContextTest.cpp InternalNamesTest.cpp