[flang] Upstream partial lowering of EXIT intrinsic

This patch adds partial lowering of the "EXIT" intrinsic to
the backend runtime hook implemented in patch D110741. It also adds a
helper function to the `RuntimeCallTestBase.h` for testing for an
intrinsic function call in a `mlir::Block`.

Differential Revision: https://reviews.llvm.org/D118141
This commit is contained in:
Josh Mottley 2022-01-07 17:06:47 +00:00
parent 7518d38f0a
commit ce8022faa3
6 changed files with 91 additions and 0 deletions

View File

@ -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

View File

@ -14,6 +14,7 @@ add_flang_library(FIRBuilder
Runtime/Numeric.cpp
Runtime/Ragged.cpp
Runtime/Reduction.cpp
Runtime/Stop.cpp
Runtime/Transformational.cpp
DEPENDS

View File

@ -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<mkRTKey(Exit)>(loc, builder);
llvm::SmallVector<mlir::Value> args =
fir::runtime::createArguments(builder, loc, exitFunc.getType(), status);
builder.create<fir::CallOp>(loc, exitFunc, args);
}

View File

@ -120,4 +120,24 @@ static inline void checkCallOpFromResultBox(mlir::Value result,
checkCallOpFromResultBox(convOp.getResult(), fctName, nbArgs, addLocArgs);
}
/// Check the operations in \p block for a `fir::CallOp` operation where the
/// function being called shares its function name with \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.
/// This results in exiting the test as soon as the first correct instance of
/// `fir::CallOp` is found).
static inline void checkBlockForCallOp(
mlir::Block *block, llvm::StringRef fctName, unsigned nbArgs) {
assert(block && "mlir::Block given is a nullptr");
for (auto &op : block->getOperations()) {
if (auto callOp = mlir::dyn_cast<fir::CallOp>(op)) {
if (fctName == callOp.callee()->getRootReference().getValue()) {
EXPECT_EQ(nbArgs, callOp.args().size());
return;
}
}
}
FAIL() << "No calls to " << fctName << " were found!";
}
#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_RUNTIMECALLTESTBASE_H

View File

@ -0,0 +1,20 @@
//===- 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) {
mlir::Location loc = firBuilder->getUnknownLoc();
mlir::Value status = firBuilder->createIntegerConstant(loc, i32Ty, 0);
fir::runtime::genExit(*firBuilder, loc, status);
mlir::Block *block = firBuilder->getBlock();
EXPECT_TRUE(block) << "Failed to retrieve the block!";
checkBlockForCallOp(block, "_FortranAExit", 1);
}

View File

@ -20,6 +20,7 @@ add_flang_unittest(FlangOptimizerTests
Builder/Runtime/NumericTest.cpp
Builder/Runtime/RaggedTest.cpp
Builder/Runtime/ReductionTest.cpp
Builder/Runtime/StopTest.cpp
Builder/Runtime/TransformationalTest.cpp
FIRContextTest.cpp
InternalNamesTest.cpp