From cabcd851e6bf629e5a402d122c81a821b77e3e51 Mon Sep 17 00:00:00 2001 From: Jean Perier Date: Tue, 26 Mar 2019 10:29:46 -0700 Subject: [PATCH] [flang] Prepare to be merged with master branch ActualArgument was modified in the master branch from a struct to class. In order to compile once merged, this PR required the related access paterns to be adapted to match the new ActualArgument. As a consequence, this PR does not compile anymore on its own, it needs to be merged with the master branch to work. Original-commit: flang-compiler/f18@48cdd2ed0ed18b9749f976257c7302e34c20b025 Tree-same-pre-rewrite: false --- flang/lib/evaluate/fold.cc | 115 ++++++++++++++++++++++++++------------------- 1 file changed, 67 insertions(+), 48 deletions(-) diff --git a/flang/lib/evaluate/fold.cc b/flang/lib/evaluate/fold.cc index b94d25a..efeec47 100644 --- a/flang/lib/evaluate/fold.cc +++ b/flang/lib/evaluate/fold.cc @@ -181,7 +181,7 @@ static inline Expr FoldElementalIntrinsicHelper(FoldingContext &context, (... && IsSpecificIntrinsicType)); // TODO derived types for MERGE? static_assert(sizeof...(TA) > 0); std::tuple *...> args{ - UnwrapExpr>(*funcRef.arguments()[I]->value)...}; + UnwrapExpr>(funcRef.arguments()[I].value().value())...}; if ((... && (std::get(args) != nullptr))) { // Compute the shape of the result based on shapes of arguments std::vector shape; @@ -259,6 +259,16 @@ static Expr FoldElementalIntrinsic(FoldingContext &context, context, std::move(funcRef), func, std::index_sequence_for{}); } +template +static Expr *UnwrapArgument(std::optional &arg) { + return UnwrapExpr>(arg.value().value()); +} + +static BOZLiteralConstant *UnwrapBozArgument( + std::optional &arg) { + return std::get_if(&arg.value().value().u); +} + template Expr> FoldOperation(FoldingContext &context, FunctionRef> &&funcRef) { @@ -272,16 +282,13 @@ Expr> FoldOperation(FoldingContext &context, } if (auto *intrinsic{std::get_if(&funcRef.proc().u)}) { const std::string name{intrinsic->name}; - // abs, dim, dshiftl, dshiftr, exponent, iand, ibclr, ibset, ieor, int, ior, - // ishft, kind, len, leadz, maskl, maskr, merge_bits shifta, shiftl, shiftr, - // trailz if (name == "abs") { return FoldElementalIntrinsic(context, std::move(funcRef), ScalarFunc([&context](const Scalar &i) -> Scalar { typename Scalar::ValueWithOverflow j{i.ABS()}; if (j.overflow) { context.messages().Say( - "abs(integer(kind=%n)) folding overflowed"_en_US, KIND); + "abs(integer(kind=%d)) folding overflowed"_en_US, KIND); } return j.value; })); @@ -291,16 +298,18 @@ Expr> FoldOperation(FoldingContext &context, } else if (name == "dshiftl" || name == "dshiftr") { // convert boz for (int i{0}; i <= 1; ++i) { - if (auto *x{std::get_if(&args[i]->value->u)}) { - *args[i]->value = Fold(context, ConvertToType(std::move(*x))); + if (auto *x{UnwrapBozArgument(args[i])}) { + args[i].value().value() = + Fold(context, ConvertToType(std::move(*x))); } } // Third argument can be of any kind. However, it must be smaller or equal // than BIT_SIZE. It can be converted to Int4 to simplify. using Int4 = Type; - if (auto *n{std::get_if>(&args[2]->value->u)}) { + if (auto *n{UnwrapArgument(args[2])}) { if (n->GetType()->kind != 4) { - *args[2]->value = Fold(context, ConvertToType(std::move(*n))); + args[2].value().value() = + Fold(context, ConvertToType(std::move(*n))); } } const auto fptr{ @@ -313,7 +322,7 @@ Expr> FoldOperation(FoldingContext &context, fptr, i, j, static_cast(shift.ToInt64())); })); } else if (name == "exponent") { - if (auto *sx{std::get_if>(&args[0]->value->u)}) { + if (auto *sx{UnwrapArgument(args[0])}) { return std::visit( [&funcRef, &context](const auto &x) -> Expr { using TR = typename std::decay_t::Result; @@ -327,8 +336,9 @@ Expr> FoldOperation(FoldingContext &context, } else if (name == "iand" || name == "ior" || name == "ieor") { // convert boz for (int i{0}; i <= 1; ++i) { - if (auto *x{std::get_if(&args[i]->value->u)}) { - *args[i]->value = Fold(context, ConvertToType(std::move(*x))); + if (auto *x{UnwrapBozArgument(args[i])}) { + args[i].value().value() = + Fold(context, ConvertToType(std::move(*x))); } } auto fptr{&Scalar::IAND}; @@ -338,7 +348,7 @@ Expr> FoldOperation(FoldingContext &context, } else if (name == "ieor") { fptr = &Scalar::IEOR; } else { - common::die("missing case to fold intrinsic function %s", name); + common::die("missing case to fold intrinsic function %s", name.c_str()); } return FoldElementalIntrinsic( context, std::move(funcRef), ScalarFunc(fptr)); @@ -347,9 +357,10 @@ Expr> FoldOperation(FoldingContext &context, // Second argument can be of any kind. However, it must be smaller or // equal than BIT_SIZE. It can be converted to Int4 to simplify. using Int4 = Type; - if (auto *n{std::get_if>(&args[1]->value->u)}) { + if (auto *n{UnwrapArgument(args[1])}) { if (n->GetType()->kind != 4) { - *args[1]->value = Fold(context, ConvertToType(std::move(*n))); + args[1].value().value() = + Fold(context, ConvertToType(std::move(*n))); } } auto fptr{&Scalar::IBCLR}; @@ -365,7 +376,7 @@ Expr> FoldOperation(FoldingContext &context, } else if (name == "shiftl") { fptr = &Scalar::SHIFTL; } else { - common::die("missing case to fold intrinsic function %s", name); + common::die("missing case to fold intrinsic function %s", name.c_str()); } return FoldElementalIntrinsic(context, std::move(funcRef), ScalarFunc([&fptr](const Scalar &i, @@ -386,16 +397,16 @@ Expr> FoldOperation(FoldingContext &context, return Expr{std::move(funcRef)}; // unreachable } }, - std::move(args[0]->value->u)); + std::move(args[0].value().value().u)); } else if (name == "kind") { if constexpr (common::HasMember) { - return Expr{args[0]->value->GetType()->kind}; + return Expr{args[0].value().GetType()->kind}; } else { common::die("kind() result not integral"); } } else if (name == "leadz" || name == "trailz" || name == "poppar" || name == "popcnt") { - if (auto *sn{std::get_if>(&args[0]->value->u)}) { + if (auto *sn{UnwrapArgument(args[0])}) { return std::visit( [&funcRef, &context, &name](const auto &n) -> Expr { using TI = typename std::decay_t::Result; @@ -413,7 +424,8 @@ Expr> FoldOperation(FoldingContext &context, } else if (name == "popcnt") { fptr = &Scalar::POPCNT; } else { - common::die("missing case to fold intrinsic function %s", name); + common::die( + "missing case to fold intrinsic function %s", name.c_str()); } return FoldElementalIntrinsic(context, std::move(funcRef), ScalarFunc([&fptr](const Scalar &i) -> Scalar { @@ -425,9 +437,9 @@ Expr> FoldOperation(FoldingContext &context, common::die("leadz argument must be integer"); } } else if (name == "len") { - if (auto *charExpr{UnwrapExpr>(*args[0]->value)}) { + if (auto *charExpr{UnwrapArgument(args[0])}) { return std::visit( - [&context](auto &kx) { + [&](auto &kx) { if constexpr (std::is_same_v) { return kx.LEN(); } else { @@ -436,15 +448,16 @@ Expr> FoldOperation(FoldingContext &context, }, charExpr->u); } else { - common::die("len() result not SubscriptInteger"); + common::die("len() argument must be of character type"); } } else if (name == "maskl" || name == "maskr") { // Argument can be of any kind but value has to be smaller than bit_size. // It can be safely converted to Int4 to simplify. using Int4 = Type; - if (auto *n{std::get_if>(&args[0]->value->u)}) { + if (auto *n{UnwrapArgument(args[0])}) { if (n->GetType()->kind != 4) { - *args[0]->value = Fold(context, ConvertToType(std::move(*n))); + args[0].value().value() = + Fold(context, ConvertToType(std::move(*n))); } } const auto fptr{name == "maskl" ? &Scalar::MASKL : &Scalar::MASKR}; @@ -455,8 +468,9 @@ Expr> FoldOperation(FoldingContext &context, } else if (name == "merge_bits") { // convert boz for (int i{0}; i <= 2; ++i) { - if (auto *x{std::get_if(&args[i]->value->u)}) { - *args[i]->value = Fold(context, ConvertToType(std::move(*x))); + if (auto *x{UnwrapBozArgument(args[i])}) { + args[i].value().value() = + Fold(context, ConvertToType(std::move(*x))); } } return FoldElementalIntrinsic( @@ -481,7 +495,8 @@ Expr> FoldOperation(FoldingContext &context, ActualArguments &args{funcRef.arguments()}; for (std::optional &arg : args) { if (arg.has_value()) { - *arg->value = FoldOperation(context, std::move(*arg->value)); + arg.value().value() = + FoldOperation(context, std::move(arg.value().value())); } } if (auto *intrinsic{std::get_if(&funcRef.proc().u)}) { @@ -523,9 +538,10 @@ Expr> FoldOperation(FoldingContext &context, if (args.size() == 2) { // elemental // runtime functions use int arg using Int4 = Type; - if (auto *n{std::get_if>(&args[0]->value->u)}) { + if (auto *n{UnwrapArgument(args[0])}) { if (n->GetType()->kind != 4) { - *args[0]->value = Fold(context, ConvertToType(std::move(*n))); + args[0].value().value() = + Fold(context, ConvertToType(std::move(*n))); } } if (auto callable{ @@ -541,10 +557,10 @@ Expr> FoldOperation(FoldingContext &context, } } else if (name == "abs") { // Argument can be complex or real - if (auto *x{std::get_if>(&args[0]->value->u)}) { + if (auto *x{UnwrapArgument(args[0])}) { return FoldElementalIntrinsic( context, std::move(funcRef), &Scalar::ABS); - } else if (auto *z{std::get_if>(&args[0]->value->u)}) { + } else if (auto *z{UnwrapArgument(args[0])}) { if (auto callable{ context.hostIntrinsicsLibrary() .GetHostProcedureWrapper("abs")}) { @@ -562,9 +578,10 @@ Expr> FoldOperation(FoldingContext &context, context, std::move(funcRef), &Scalar::AIMAG); } else if (name == "aint") { // Convert argument to the requested kind before calling aint - if (auto *x{std::get_if>(&args[0]->value->u)}) { + if (auto *x{UnwrapArgument(args[0])}) { if (!(x->GetType()->kind == T::kind)) { - *args[0]->value = Fold(context, ConvertToType(std::move(*x))); + args[0].value().value() = + Fold(context, ConvertToType(std::move(*x))); } } return FoldElementalIntrinsic(context, std::move(funcRef), @@ -577,8 +594,8 @@ Expr> FoldOperation(FoldingContext &context, return y.value; })); } else if (name == "dprod") { - if (auto *x{std::get_if>(&args[0]->value->u)}) { - if (auto *y{std::get_if>(&args[1]->value->u)}) { + if (auto *x{UnwrapArgument(args[0])}) { + if (auto *y{UnwrapArgument(args[1])}) { return Fold(context, Expr{Multiply{ConvertToType(std::move(*x)), ConvertToType(std::move(*y))}}); @@ -608,7 +625,7 @@ Expr> FoldOperation(FoldingContext &context, return Expr{std::move(funcRef)}; // unreachable } }, - std::move(args[0]->value->u)); + std::move(args[0].value().value().u)); } // TODO: anint, cshift, dim, dot_product, eoshift, fraction, huge, matmul, // max, maxval, merge, min, minval, modulo, nearest, norm2, pack, product, @@ -626,7 +643,8 @@ Expr> FoldOperation(FoldingContext &context, ActualArguments &args{funcRef.arguments()}; for (std::optional &arg : args) { if (arg.has_value()) { - *arg->value = FoldOperation(context, std::move(*arg->value)); + arg.value().value() = + FoldOperation(context, std::move(arg.value().value())); } } if (auto *intrinsic{std::get_if(&funcRef.proc().u)}) { @@ -649,7 +667,7 @@ Expr> FoldOperation(FoldingContext &context, context, std::move(funcRef), &Scalar::CONJG); } else if (name == "cmplx") { if (args.size() == 2) { - if (auto *x{std::get_if>(&args[0]->value->u)}) { + if (auto *x{UnwrapArgument(args[0])}) { return Fold(context, ConvertToType(std::move(*x))); } else { common::die("x must be complex in cmplx(x[, kind])"); @@ -658,9 +676,9 @@ Expr> FoldOperation(FoldingContext &context, CHECK(args.size() == 3); using Part = typename T::Part; Expr im{args[1].has_value() - ? std::move(*args[1]->value) + ? std::move(args[1].value().value()) : AsGenericExpr(Constant{Scalar{}})}; - Expr re{std::move(*args[0]->value)}; + Expr re{std::move(args[0].value().value())}; int reRank{re.Rank()}; int imRank{im.Rank()}; semantics::Attrs attrs; @@ -691,7 +709,8 @@ Expr> FoldOperation(FoldingContext &context, ActualArguments &args{funcRef.arguments()}; for (std::optional &arg : args) { if (arg.has_value()) { - *arg->value = FoldOperation(context, std::move(*arg->value)); + arg.value().value() = + FoldOperation(context, std::move(arg.value().value())); } } if (auto *intrinsic{std::get_if(&funcRef.proc().u)}) { @@ -703,12 +722,12 @@ Expr> FoldOperation(FoldingContext &context, // arguments to the biggest integer type before comparing them to // simplify. for (int i{0}; i <= 1; ++i) { - if (auto *x{std::get_if>(&args[i]->value->u)}) { - *args[i]->value = + if (auto *x{UnwrapArgument(args[i])}) { + args[i].value().value() = Fold(context, ConvertToType(std::move(*x))); - } else if (auto *x{ - std::get_if(&args[i]->value->u)}) { - *args[i]->value = AsGenericExpr(Constant{std::move(*x)}); + } else if (auto *x{UnwrapBozArgument(args[i])}) { + args[i].value().value() = + AsGenericExpr(Constant{std::move(*x)}); } } auto fptr{&Scalar::BGE}; @@ -720,7 +739,7 @@ Expr> FoldOperation(FoldingContext &context, } else if (name == "blt") { fptr = &Scalar::BLT; } else { - common::die("missing case to fold intrinsic function %s", name); + common::die("missing case to fold intrinsic function %s", name.c_str()); } return FoldElementalIntrinsic(context, std::move(funcRef), -- 2.7.4