Skip to content

Commit

Permalink
[flang] Cleanup of NYI messages (#73740)
Browse files Browse the repository at this point in the history
This update makes the user visible messages relating to features that
are not yet implemented be more consistent. I also cleaned up some of
the code.

For NYI messages that refer to intrinsics, I made sure the the message
begins with "not yet implemented: intrinsic:" to make them easier to
recognize.

I created some utility functions for NYI reporting that I put into
.../include/Optimizer/Support/Utils.h. These mainly convert MLIR types
to their Fortran equivalents.

I converted the NYI code to use the newly created utility functions.
  • Loading branch information
psteinfeld committed Nov 29, 2023
1 parent 2273ee0 commit 04b1853
Show file tree
Hide file tree
Showing 12 changed files with 178 additions and 140 deletions.
63 changes: 63 additions & 0 deletions flang/include/flang/Optimizer/Support/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@
#define FORTRAN_OPTIMIZER_SUPPORT_UTILS_H

#include "flang/Common/default-kinds.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/Todo.h"
#include "flang/Optimizer/Dialect/FIROps.h"
#include "flang/Optimizer/Dialect/FIRType.h"
#include "flang/Optimizer/Support/FatalError.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/IR/BuiltinAttributes.h"
Expand Down Expand Up @@ -70,6 +73,66 @@ fromDefaultKinds(const Fortran::common::IntrinsicTypeDefaultKinds &defKinds) {
static_cast<fir::KindTy>(
defKinds.GetDefaultKind(Fortran::common::TypeCategory::Real))};
}

inline std::string mlirTypeToString(mlir::Type type) {
std::string result{};
llvm::raw_string_ostream sstream(result);
sstream << type;
return result;
}

inline std::string numericMlirTypeToFortran(fir::FirOpBuilder &builder,
mlir::Type type, mlir::Location loc,
const llvm::Twine &name) {
if (type.isF16())
return "REAL(KIND=2)";
else if (type.isBF16())
return "REAL(KIND=3)";
else if (type.isTF32())
return "REAL(KIND=unknown)";
else if (type.isF32())
return "REAL(KIND=4)";
else if (type.isF64())
return "REAL(KIND=8)";
else if (type.isF80())
return "REAL(KIND=10)";
else if (type.isF128())
return "REAL(KIND=16)";
else if (type.isInteger(8))
return "INTEGER(KIND=1)";
else if (type.isInteger(16))
return "INTEGER(KIND=2)";
else if (type.isInteger(32))
return "INTEGER(KIND=4)";
else if (type.isInteger(64))
return "INTEGER(KIND=8)";
else if (type.isInteger(128))
return "INTEGER(KIND=16)";
else if (type == fir::ComplexType::get(builder.getContext(), 2))
return "COMPLEX(KIND=2)";
else if (type == fir::ComplexType::get(builder.getContext(), 3))
return "COMPLEX(KIND=3)";
else if (type == fir::ComplexType::get(builder.getContext(), 4))
return "COMPLEX(KIND=4)";
else if (type == fir::ComplexType::get(builder.getContext(), 8))
return "COMPLEX(KIND=8)";
else if (type == fir::ComplexType::get(builder.getContext(), 10))
return "COMPLEX(KIND=10)";
else if (type == fir::ComplexType::get(builder.getContext(), 16))
return "COMPLEX(KIND=16)";
else
fir::emitFatalError(loc, "unsupported type in " + name + ": " +
fir::mlirTypeToString(type));
}

inline void intrinsicTypeTODO(fir::FirOpBuilder &builder, mlir::Type type,
mlir::Location loc,
const llvm::Twine &intrinsicName) {
TODO(loc,
"intrinsic: " +
fir::numericMlirTypeToFortran(builder, type, loc, intrinsicName) +
" in " + intrinsicName);
}
} // namespace fir

#endif // FORTRAN_OPTIMIZER_SUPPORT_UTILS_H
25 changes: 16 additions & 9 deletions flang/lib/Optimizer/Builder/IntrinsicCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1235,7 +1235,7 @@ searchMathOperation(fir::FirOpBuilder &builder, llvm::StringRef name,
static void checkPrecisionLoss(llvm::StringRef name,
mlir::FunctionType funcType,
const FunctionDistance &distance,
mlir::Location loc) {
fir::FirOpBuilder &builder, mlir::Location loc) {
if (!distance.isLosingPrecision())
return;

Expand All @@ -1249,13 +1249,20 @@ static void checkPrecisionLoss(llvm::StringRef name,
llvm::raw_string_ostream sstream(message);
if (name == "pow") {
assert(funcType.getNumInputs() == 2 && "power operator has two arguments");
sstream << funcType.getInput(0) << " ** " << funcType.getInput(1);
std::string displayName{" ** "};
sstream << numericMlirTypeToFortran(builder, funcType.getInput(0), loc,
displayName)
<< displayName
<< numericMlirTypeToFortran(builder, funcType.getInput(1), loc,
displayName);
} else {
sstream << name << "(";
sstream << name.upper() << "(";
if (funcType.getNumInputs() > 0)
sstream << funcType.getInput(0);
for (mlir::Type argType : funcType.getInputs().drop_front())
sstream << ", " << argType;
sstream << numericMlirTypeToFortran(builder, funcType.getInput(0), loc,
name);
for (mlir::Type argType : funcType.getInputs().drop_front()) {
sstream << ", " << numericMlirTypeToFortran(builder, argType, loc, name);
}
sstream << ")";
}
sstream << "'";
Expand Down Expand Up @@ -1373,7 +1380,7 @@ void crashOnMissingIntrinsic(mlir::Location loc, llvm::StringRef name) {
else if (isCoarrayIntrinsic(name))
TODO(loc, "coarray: intrinsic " + llvm::Twine(name));
else
TODO(loc, "intrinsic: " + llvm::Twine(name));
TODO(loc, "intrinsic: " + llvm::Twine(name.upper()));
}

template <typename GeneratorType>
Expand Down Expand Up @@ -1756,7 +1763,7 @@ IntrinsicLibrary::getRuntimeCallGenerator(llvm::StringRef name,
if (!mathOp && bestNearMatch) {
// Use the best near match, optionally issuing an error,
// if types conversions cause precision loss.
checkPrecisionLoss(name, soughtFuncType, bestMatchDistance, loc);
checkPrecisionLoss(name, soughtFuncType, bestMatchDistance, builder, loc);
mathOp = bestNearMatch;
}

Expand Down Expand Up @@ -4373,7 +4380,7 @@ mlir::Value IntrinsicLibrary::genModulo(mlir::Type resultType,
// Real case
if (resultType == mlir::FloatType::getF128(builder.getContext()))

TODO(loc, "intrinsic: modulo for floating point of KIND=16");
TODO(loc, "REAL(KIND=16): in MODULO intrinsic");
auto remainder = builder.create<mlir::arith::RemFOp>(loc, args[0], args[1]);
mlir::Value zero = builder.createRealZeroConstant(loc, remainder.getType());
auto remainderIsNotZero = builder.create<mlir::arith::CmpFOp>(
Expand Down
51 changes: 17 additions & 34 deletions flang/lib/Optimizer/Builder/Runtime/Numeric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "flang/Optimizer/Builder/Character.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
#include "flang/Optimizer/Builder/Todo.h"
#include "flang/Optimizer/Support/Utils.h"
#include "flang/Runtime/numeric.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"

Expand Down Expand Up @@ -240,10 +240,7 @@ mlir::Value fir::runtime::genExponent(fir::FirOpBuilder &builder,
mlir::Value x) {
mlir::func::FuncOp func;
mlir::Type fltTy = x.getType();

if (fltTy.isF16()) {
TODO(loc, "support for REAL with KIND = 2 in EXPONENT");
} else if (fltTy.isF32()) {
if (fltTy.isF32()) {
if (resultType.isInteger(32))
func = fir::runtime::getRuntimeFunc<mkRTKey(Exponent4_4)>(loc, builder);
else if (resultType.isInteger(64))
Expand All @@ -264,7 +261,7 @@ mlir::Value fir::runtime::genExponent(fir::FirOpBuilder &builder,
else if (resultType.isInteger(64))
func = fir::runtime::getRuntimeFunc<ForcedExponent16_8>(loc, builder);
} else
fir::emitFatalError(loc, "unsupported REAL kind in EXPONENT");
fir::intrinsicTypeTODO(builder, fltTy, loc, "EXPONENT");

auto funcTy = func.getFunctionType();
llvm::SmallVector<mlir::Value> args = {
Expand All @@ -278,9 +275,7 @@ mlir::Value fir::runtime::genFraction(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value x) {
mlir::func::FuncOp func;
mlir::Type fltTy = x.getType();
if (fltTy.isF16())
TODO(loc, "support for REAL with KIND = 2 in FRACTION");
else if (fltTy.isF32())
if (fltTy.isF32())
func = fir::runtime::getRuntimeFunc<mkRTKey(Fraction4)>(loc, builder);
else if (fltTy.isF64())
func = fir::runtime::getRuntimeFunc<mkRTKey(Fraction8)>(loc, builder);
Expand All @@ -289,7 +284,7 @@ mlir::Value fir::runtime::genFraction(fir::FirOpBuilder &builder,
else if (fltTy.isF128())
func = fir::runtime::getRuntimeFunc<ForcedFraction16>(loc, builder);
else
fir::emitFatalError(loc, "unsupported REAL kind in FRACTION");
fir::intrinsicTypeTODO(builder, fltTy, loc, "FRACTION");

auto funcTy = func.getFunctionType();
llvm::SmallVector<mlir::Value> args = {
Expand All @@ -307,9 +302,7 @@ mlir::Value fir::runtime::genMod(fir::FirOpBuilder &builder, mlir::Location loc,
if (fltTy != p.getType())
fir::emitFatalError(loc, "arguments type mismatch in MOD");

if (fltTy.isF16())
TODO(loc, "support for REAL with KIND = 2 in MOD");
else if (fltTy.isF32())
if (fltTy.isF32())
func = fir::runtime::getRuntimeFunc<mkRTKey(ModReal4)>(loc, builder);
else if (fltTy.isF64())
func = fir::runtime::getRuntimeFunc<mkRTKey(ModReal8)>(loc, builder);
Expand All @@ -318,7 +311,7 @@ mlir::Value fir::runtime::genMod(fir::FirOpBuilder &builder, mlir::Location loc,
else if (fltTy.isF128())
func = fir::runtime::getRuntimeFunc<ForcedMod16>(loc, builder);
else
fir::emitFatalError(loc, "unsupported REAL kind in MOD");
fir::intrinsicTypeTODO(builder, fltTy, loc, "MOD");

auto funcTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
Expand All @@ -337,9 +330,7 @@ mlir::Value fir::runtime::genNearest(fir::FirOpBuilder &builder,
mlir::func::FuncOp func;
mlir::Type fltTy = x.getType();

if (fltTy.isF16())
TODO(loc, "support for REAL with KIND = 2 in NEAREST");
else if (fltTy.isF32())
if (fltTy.isF32())
func = fir::runtime::getRuntimeFunc<mkRTKey(Nearest4)>(loc, builder);
else if (fltTy.isF64())
func = fir::runtime::getRuntimeFunc<mkRTKey(Nearest8)>(loc, builder);
Expand All @@ -348,7 +339,7 @@ mlir::Value fir::runtime::genNearest(fir::FirOpBuilder &builder,
else if (fltTy.isF128())
func = fir::runtime::getRuntimeFunc<ForcedNearest16>(loc, builder);
else
fir::emitFatalError(loc, "unsupported REAL kind in NEAREST");
fir::intrinsicTypeTODO(builder, fltTy, loc, "NEAREST");

auto funcTy = func.getFunctionType();

Expand All @@ -374,9 +365,7 @@ mlir::Value fir::runtime::genRRSpacing(fir::FirOpBuilder &builder,
mlir::func::FuncOp func;
mlir::Type fltTy = x.getType();

if (fltTy.isF16())
TODO(loc, "support for REAL with KIND = 2 in RRSPACING");
else if (fltTy.isF32())
if (fltTy.isF32())
func = fir::runtime::getRuntimeFunc<mkRTKey(RRSpacing4)>(loc, builder);
else if (fltTy.isF64())
func = fir::runtime::getRuntimeFunc<mkRTKey(RRSpacing8)>(loc, builder);
Expand All @@ -385,7 +374,7 @@ mlir::Value fir::runtime::genRRSpacing(fir::FirOpBuilder &builder,
else if (fltTy.isF128())
func = fir::runtime::getRuntimeFunc<ForcedRRSpacing16>(loc, builder);
else
fir::emitFatalError(loc, "unsupported REAL kind in RRSPACING");
fir::intrinsicTypeTODO(builder, fltTy, loc, "RRSPACING");

auto funcTy = func.getFunctionType();
llvm::SmallVector<mlir::Value> args = {
Expand All @@ -401,9 +390,7 @@ mlir::Value fir::runtime::genScale(fir::FirOpBuilder &builder,
mlir::func::FuncOp func;
mlir::Type fltTy = x.getType();

if (fltTy.isF16())
TODO(loc, "support for REAL with KIND = 2 in SCALE");
else if (fltTy.isF32())
if (fltTy.isF32())
func = fir::runtime::getRuntimeFunc<mkRTKey(Scale4)>(loc, builder);
else if (fltTy.isF64())
func = fir::runtime::getRuntimeFunc<mkRTKey(Scale8)>(loc, builder);
Expand All @@ -412,7 +399,7 @@ mlir::Value fir::runtime::genScale(fir::FirOpBuilder &builder,
else if (fltTy.isF128())
func = fir::runtime::getRuntimeFunc<ForcedScale16>(loc, builder);
else
fir::emitFatalError(loc, "unsupported REAL kind in SCALE");
fir::intrinsicTypeTODO(builder, fltTy, loc, "SCALE");

auto funcTy = func.getFunctionType();
auto args = fir::runtime::createArguments(builder, loc, funcTy, x, i);
Expand Down Expand Up @@ -480,9 +467,7 @@ mlir::Value fir::runtime::genSetExponent(fir::FirOpBuilder &builder,
mlir::func::FuncOp func;
mlir::Type fltTy = x.getType();

if (fltTy.isF16())
TODO(loc, "support for REAL with KIND = 2 in FRACTION");
else if (fltTy.isF32())
if (fltTy.isF32())
func = fir::runtime::getRuntimeFunc<mkRTKey(SetExponent4)>(loc, builder);
else if (fltTy.isF64())
func = fir::runtime::getRuntimeFunc<mkRTKey(SetExponent8)>(loc, builder);
Expand All @@ -491,7 +476,7 @@ mlir::Value fir::runtime::genSetExponent(fir::FirOpBuilder &builder,
else if (fltTy.isF128())
func = fir::runtime::getRuntimeFunc<ForcedSetExponent16>(loc, builder);
else
fir::emitFatalError(loc, "unsupported REAL kind in FRACTION");
fir::intrinsicTypeTODO(builder, fltTy, loc, "SET_EXPONENT");

auto funcTy = func.getFunctionType();
auto args = fir::runtime::createArguments(builder, loc, funcTy, x, i);
Expand All @@ -505,9 +490,7 @@ mlir::Value fir::runtime::genSpacing(fir::FirOpBuilder &builder,
mlir::func::FuncOp func;
mlir::Type fltTy = x.getType();

if (fltTy.isF16())
TODO(loc, "support for REAL with KIND = 2 in SPACING");
else if (fltTy.isF32())
if (fltTy.isF32())
func = fir::runtime::getRuntimeFunc<mkRTKey(Spacing4)>(loc, builder);
else if (fltTy.isF64())
func = fir::runtime::getRuntimeFunc<mkRTKey(Spacing8)>(loc, builder);
Expand All @@ -516,7 +499,7 @@ mlir::Value fir::runtime::genSpacing(fir::FirOpBuilder &builder,
else if (fltTy.isF128())
func = fir::runtime::getRuntimeFunc<ForcedSpacing16>(loc, builder);
else
fir::emitFatalError(loc, "unsupported REAL kind in SPACING");
fir::intrinsicTypeTODO(builder, fltTy, loc, "SPACING");

auto funcTy = func.getFunctionType();
llvm::SmallVector<mlir::Value> args = {
Expand Down

0 comments on commit 04b1853

Please sign in to comment.