diff --git a/flang/lib/Optimizer/CodeGen/Target.h b/flang/lib/Optimizer/CodeGen/Target.h --- a/flang/lib/Optimizer/CodeGen/Target.h +++ b/flang/lib/Optimizer/CodeGen/Target.h @@ -71,11 +71,13 @@ /// Type representation of a `complex` type argument when passed by /// value. An argument value may need to be passed as a (safe) reference /// argument. - virtual Marshalling complexArgumentType(mlir::Type eleTy) const = 0; + virtual Marshalling complexArgumentType(mlir::Location loc, + mlir::Type eleTy) const = 0; /// Type representation of a `complex` type return value. Such a return /// value may need to be converted to a hidden reference argument. - virtual Marshalling complexReturnType(mlir::Type eleTy) const = 0; + virtual Marshalling complexReturnType(mlir::Location loc, + mlir::Type eleTy) const = 0; /// Type presentation of a `boxchar` type value in memory. virtual mlir::Type boxcharMemoryType(mlir::Type eleTy) const = 0; diff --git a/flang/lib/Optimizer/CodeGen/Target.cpp b/flang/lib/Optimizer/CodeGen/Target.cpp --- a/flang/lib/Optimizer/CodeGen/Target.cpp +++ b/flang/lib/Optimizer/CodeGen/Target.cpp @@ -12,6 +12,7 @@ #include "Target.h" #include "flang/Optimizer/Dialect/FIRType.h" +#include "flang/Optimizer/Support/FatalError.h" #include "flang/Optimizer/Support/KindMapping.h" #include "mlir/IR/BuiltinTypes.h" #include "mlir/IR/TypeRange.h" @@ -79,7 +80,7 @@ static constexpr int defaultWidth = 32; CodeGenSpecifics::Marshalling - complexArgumentType(mlir::Type eleTy) const override { + complexArgumentType(mlir::Location, mlir::Type eleTy) const override { assert(fir::isa_real(eleTy)); CodeGenSpecifics::Marshalling marshal; // Use a type that will be translated into LLVM as: @@ -92,7 +93,7 @@ } CodeGenSpecifics::Marshalling - complexReturnType(mlir::Type eleTy) const override { + complexReturnType(mlir::Location loc, mlir::Type eleTy) const override { assert(fir::isa_real(eleTy)); CodeGenSpecifics::Marshalling marshal; const auto *sem = &floatToSemantics(kindMap, eleTy); @@ -108,7 +109,7 @@ marshal.emplace_back(fir::ReferenceType::get(structTy), AT{/*alignment=*/4, /*byval=*/false, /*sret=*/true}); } else { - llvm::report_fatal_error("complex for this precision not implemented"); + fir::emitFatalError(loc, "complex for this precision not implemented"); } return marshal; } @@ -126,7 +127,7 @@ static constexpr int defaultWidth = 64; CodeGenSpecifics::Marshalling - complexArgumentType(mlir::Type eleTy) const override { + complexArgumentType(mlir::Location loc, mlir::Type eleTy) const override { CodeGenSpecifics::Marshalling marshal; const auto *sem = &floatToSemantics(kindMap, eleTy); if (sem == &llvm::APFloat::IEEEsingle()) { @@ -137,13 +138,13 @@ marshal.emplace_back(eleTy, AT{}); marshal.emplace_back(eleTy, AT{}); } else { - llvm::report_fatal_error("complex for this precision not implemented"); + fir::emitFatalError(loc, "complex for this precision not implemented"); } return marshal; } CodeGenSpecifics::Marshalling - complexReturnType(mlir::Type eleTy) const override { + complexReturnType(mlir::Location loc, mlir::Type eleTy) const override { CodeGenSpecifics::Marshalling marshal; const auto *sem = &floatToSemantics(kindMap, eleTy); if (sem == &llvm::APFloat::IEEEsingle()) { @@ -156,7 +157,7 @@ marshal.emplace_back(mlir::TupleType::get(eleTy.getContext(), range), AT{}); } else { - llvm::report_fatal_error("complex for this precision not implemented"); + fir::emitFatalError(loc, "complex for this precision not implemented"); } return marshal; } @@ -174,7 +175,7 @@ static constexpr int defaultWidth = 64; CodeGenSpecifics::Marshalling - complexArgumentType(mlir::Type eleTy) const override { + complexArgumentType(mlir::Location loc, mlir::Type eleTy) const override { CodeGenSpecifics::Marshalling marshal; const auto *sem = &floatToSemantics(kindMap, eleTy); if (sem == &llvm::APFloat::IEEEsingle() || @@ -182,13 +183,13 @@ // [2 x t] array of 2 eleTy marshal.emplace_back(fir::SequenceType::get({2}, eleTy), AT{}); } else { - llvm::report_fatal_error("complex for this precision not implemented"); + fir::emitFatalError(loc, "complex for this precision not implemented"); } return marshal; } CodeGenSpecifics::Marshalling - complexReturnType(mlir::Type eleTy) const override { + complexReturnType(mlir::Location loc, mlir::Type eleTy) const override { CodeGenSpecifics::Marshalling marshal; const auto *sem = &floatToSemantics(kindMap, eleTy); if (sem == &llvm::APFloat::IEEEsingle() || @@ -199,7 +200,7 @@ marshal.emplace_back(mlir::TupleType::get(eleTy.getContext(), range), AT{}); } else { - llvm::report_fatal_error("complex for this precision not implemented"); + fir::emitFatalError(loc, "complex for this precision not implemented"); } return marshal; } @@ -217,7 +218,7 @@ static constexpr int defaultWidth = 64; CodeGenSpecifics::Marshalling - complexArgumentType(mlir::Type eleTy) const override { + complexArgumentType(mlir::Location, mlir::Type eleTy) const override { CodeGenSpecifics::Marshalling marshal; // two distinct element type arguments (re, im) marshal.emplace_back(eleTy, AT{}); @@ -226,7 +227,7 @@ } CodeGenSpecifics::Marshalling - complexReturnType(mlir::Type eleTy) const override { + complexReturnType(mlir::Location, mlir::Type eleTy) const override { CodeGenSpecifics::Marshalling marshal; // Use a type that will be translated into LLVM as: // { t, t } struct of 2 element type @@ -291,5 +292,5 @@ } break; } - llvm::report_fatal_error("target not implemented"); + fir::emitFatalError(mlir::UnknownLoc::get(ctx), "target not implemented"); } diff --git a/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp b/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp --- a/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp +++ b/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp @@ -114,14 +114,14 @@ template std::function - rewriteCallComplexResultType(A ty, B &newResTys, B &newInTys, C &newOpers) { - auto m = specifics->complexReturnType(ty.getElementType()); + rewriteCallComplexResultType(mlir::Location loc, A ty, B &newResTys, + B &newInTys, C &newOpers) { + auto m = specifics->complexReturnType(loc, ty.getElementType()); // Currently targets mandate COMPLEX is a single aggregate or packed // scalar, including the sret case. assert(m.size() == 1 && "target lowering of complex return not supported"); auto resTy = std::get(m[0]); auto attr = std::get(m[0]); - auto loc = mlir::UnknownLoc::get(resTy.getContext()); if (attr.isSRet()) { assert(fir::isa_ref_type(resTy) && "must be a memory reference type"); mlir::Value stack = @@ -147,9 +147,11 @@ template void rewriteCallComplexInputType(A ty, mlir::Value oper, B &newInTys, C &newOpers) { - auto m = specifics->complexArgumentType(ty.getElementType()); auto *ctx = ty.getContext(); - auto loc = mlir::UnknownLoc::get(ctx); + mlir::Location loc = mlir::UnknownLoc::get(ctx); + if (auto *op = oper.getDefiningOp()) + loc = op->getLoc(); + auto m = specifics->complexArgumentType(loc, ty.getElementType()); if (m.size() == 1) { // COMPLEX is a single aggregate auto resTy = std::get(m[0]); @@ -210,11 +212,11 @@ mlir::Type ty = fnTy.getResult(0); llvm::TypeSwitch(ty) .template Case([&](fir::ComplexType cmplx) { - wrap = rewriteCallComplexResultType(cmplx, newResTys, newInTys, + wrap = rewriteCallComplexResultType(loc, cmplx, newResTys, newInTys, newOpers); }) .template Case([&](mlir::ComplexType cmplx) { - wrap = rewriteCallComplexResultType(cmplx, newResTys, newInTys, + wrap = rewriteCallComplexResultType(loc, cmplx, newResTys, newInTys, newOpers); }) .Default([&](mlir::Type ty) { newResTys.push_back(ty); }); @@ -337,11 +339,13 @@ // Result type fixup for fir::ComplexType and mlir::ComplexType template - void lowerComplexSignatureRes(A cmplx, B &newResTys, B &newInTys) { + void lowerComplexSignatureRes(mlir::Location loc, A cmplx, B &newResTys, + B &newInTys) { if (noComplexConversion) { newResTys.push_back(cmplx); } else { - for (auto &tup : specifics->complexReturnType(cmplx.getElementType())) { + for (auto &tup : + specifics->complexReturnType(loc, cmplx.getElementType())) { auto argTy = std::get(tup); if (std::get(tup).isSRet()) newInTys.push_back(argTy); @@ -353,11 +357,12 @@ // Argument type fixup for fir::ComplexType and mlir::ComplexType template - void lowerComplexSignatureArg(A cmplx, B &newInTys) { + void lowerComplexSignatureArg(mlir::Location loc, A cmplx, B &newInTys) { if (noComplexConversion) newInTys.push_back(cmplx); else - for (auto &tup : specifics->complexArgumentType(cmplx.getElementType())) + for (auto &tup : + specifics->complexArgumentType(loc, cmplx.getElementType())) newInTys.push_back(std::get(tup)); } @@ -367,13 +372,14 @@ auto addrTy = addrOp.getType().cast(); llvm::SmallVector newResTys; llvm::SmallVector newInTys; + auto loc = addrOp.getLoc(); for (mlir::Type ty : addrTy.getResults()) { llvm::TypeSwitch(ty) .Case([&](fir::ComplexType ty) { - lowerComplexSignatureRes(ty, newResTys, newInTys); + lowerComplexSignatureRes(loc, ty, newResTys, newInTys); }) .Case([&](mlir::ComplexType ty) { - lowerComplexSignatureRes(ty, newResTys, newInTys); + lowerComplexSignatureRes(loc, ty, newResTys, newInTys); }) .Default([&](mlir::Type ty) { newResTys.push_back(ty); }); } @@ -394,10 +400,10 @@ } }) .Case([&](fir::ComplexType ty) { - lowerComplexSignatureArg(ty, newInTys); + lowerComplexSignatureArg(loc, ty, newInTys); }) .Case([&](mlir::ComplexType ty) { - lowerComplexSignatureArg(ty, newInTys); + lowerComplexSignatureArg(loc, ty, newInTys); }) .Case([&](mlir::TupleType tuple) { if (fir::isCharacterProcedureTuple(tuple)) { @@ -730,7 +736,8 @@ newResTys.push_back(cmplx); return; } - auto m = specifics->complexReturnType(cmplx.getElementType()); + auto m = + specifics->complexReturnType(func.getLoc(), cmplx.getElementType()); assert(m.size() == 1); auto &tup = m[0]; auto attr = std::get(tup); @@ -757,7 +764,8 @@ newInTys.push_back(cmplx); return; } - auto m = specifics->complexArgumentType(cmplx.getElementType()); + auto m = + specifics->complexArgumentType(func.getLoc(), cmplx.getElementType()); const auto fixupCode = m.size() > 1 ? FixupTy::Codes::Split : FixupTy::Codes::ArgumentType; for (auto e : llvm::enumerate(m)) {