This patch lowers STOP statement without arguments and ERROR STOP. STOP statement with arguments lowering will come in later patches ince it requires some expression lowering to be added. STOP statement is lowered to a runtime call. Also makes sure we are creating a constant in the MLIR arith constant. This patch is part of the upstreaming effort from fir-dev branch. Reviewed By: kiranchandramohan, schweitz Differential Revision: https://reviews.llvm.org/D118697 Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
71 lines
2.8 KiB
C++
71 lines
2.8 KiB
C++
//===-- Runtime.cpp -------------------------------------------------------===//
|
|
//
|
|
// 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/Lower/Runtime.h"
|
|
#include "flang/Lower/Bridge.h"
|
|
#include "flang/Lower/Todo.h"
|
|
#include "flang/Optimizer/Builder/FIRBuilder.h"
|
|
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
|
|
#include "flang/Parser/parse-tree.h"
|
|
#include "flang/Runtime/stop.h"
|
|
#include "flang/Semantics/tools.h"
|
|
#include "llvm/Support/Debug.h"
|
|
|
|
#define DEBUG_TYPE "flang-lower-runtime"
|
|
|
|
using namespace Fortran::runtime;
|
|
|
|
/// Runtime calls that do not return to the caller indicate this condition by
|
|
/// terminating the current basic block with an unreachable op.
|
|
static void genUnreachable(fir::FirOpBuilder &builder, mlir::Location loc) {
|
|
builder.create<fir::UnreachableOp>(loc);
|
|
mlir::Block *newBlock =
|
|
builder.getBlock()->splitBlock(builder.getInsertionPoint());
|
|
builder.setInsertionPointToStart(newBlock);
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Misc. Fortran statements that lower to runtime calls
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
void Fortran::lower::genStopStatement(
|
|
Fortran::lower::AbstractConverter &converter,
|
|
const Fortran::parser::StopStmt &stmt) {
|
|
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
|
|
mlir::Location loc = converter.getCurrentLocation();
|
|
llvm::SmallVector<mlir::Value> operands;
|
|
mlir::FuncOp callee;
|
|
mlir::FunctionType calleeType;
|
|
// First operand is stop code (zero if absent)
|
|
if (std::get<std::optional<Fortran::parser::StopCode>>(stmt.t)) {
|
|
TODO(loc, "STOP first operand not lowered yet");
|
|
} else {
|
|
callee = fir::runtime::getRuntimeFunc<mkRTKey(StopStatement)>(loc, builder);
|
|
calleeType = callee.getType();
|
|
operands.push_back(
|
|
builder.createIntegerConstant(loc, calleeType.getInput(0), 0));
|
|
}
|
|
|
|
// Second operand indicates ERROR STOP
|
|
bool isError = std::get<Fortran::parser::StopStmt::Kind>(stmt.t) ==
|
|
Fortran::parser::StopStmt::Kind::ErrorStop;
|
|
operands.push_back(builder.createIntegerConstant(
|
|
loc, calleeType.getInput(operands.size()), isError));
|
|
|
|
// Third operand indicates QUIET (default to false).
|
|
if (std::get<std::optional<Fortran::parser::ScalarLogicalExpr>>(stmt.t)) {
|
|
TODO(loc, "STOP third operand not lowered yet");
|
|
} else {
|
|
operands.push_back(builder.createIntegerConstant(
|
|
loc, calleeType.getInput(operands.size()), 0));
|
|
}
|
|
|
|
builder.create<fir::CallOp>(loc, callee, operands);
|
|
genUnreachable(builder, loc);
|
|
}
|