Updated CMake files accordingly, using better regex Updated license headers to match new extension and fit within 80 columns Updated other comments within files that referred to the old extension Original-commit: flang-compiler/f18@ae7721e611 Reviewed-on: https://github.com/flang-compiler/f18/pull/958
80 lines
3.3 KiB
C++
80 lines
3.3 KiB
C++
//===-- lib/evaluate/fold-complex.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 "fold-implementation.h"
|
|
|
|
namespace Fortran::evaluate {
|
|
|
|
template<int KIND>
|
|
Expr<Type<TypeCategory::Complex, KIND>> FoldIntrinsicFunction(
|
|
FoldingContext &context,
|
|
FunctionRef<Type<TypeCategory::Complex, KIND>> &&funcRef) {
|
|
using T = Type<TypeCategory::Complex, KIND>;
|
|
ActualArguments &args{funcRef.arguments()};
|
|
auto *intrinsic{std::get_if<SpecificIntrinsic>(&funcRef.proc().u)};
|
|
CHECK(intrinsic);
|
|
std::string name{intrinsic->name};
|
|
if (name == "acos" || name == "acosh" || name == "asin" || name == "asinh" ||
|
|
name == "atan" || name == "atanh" || name == "cos" || name == "cosh" ||
|
|
name == "exp" || name == "log" || name == "sin" || name == "sinh" ||
|
|
name == "sqrt" || name == "tan" || name == "tanh") {
|
|
if (auto callable{context.hostIntrinsicsLibrary()
|
|
.GetHostProcedureWrapper<Scalar, T, T>(name)}) {
|
|
return FoldElementalIntrinsic<T, T>(
|
|
context, std::move(funcRef), *callable);
|
|
} else {
|
|
context.messages().Say(
|
|
"%s(complex(kind=%d)) cannot be folded on host"_en_US, name, KIND);
|
|
}
|
|
} else if (name == "conjg") {
|
|
return FoldElementalIntrinsic<T, T>(
|
|
context, std::move(funcRef), &Scalar<T>::CONJG);
|
|
} else if (name == "cmplx") {
|
|
using Part = typename T::Part;
|
|
if (args.size() == 1) {
|
|
if (auto *x{UnwrapExpr<Expr<SomeComplex>>(args[0])}) {
|
|
return Fold(context, ConvertToType<T>(std::move(*x)));
|
|
}
|
|
Expr<SomeType> re{std::move(*args[0].value().UnwrapExpr())};
|
|
Expr<SomeType> im{AsGenericExpr(Constant<Part>{Scalar<Part>{}})};
|
|
return Fold(context,
|
|
Expr<T>{ComplexConstructor<KIND>{ToReal<KIND>(context, std::move(re)),
|
|
ToReal<KIND>(context, std::move(im))}});
|
|
}
|
|
CHECK(args.size() == 2 || args.size() == 3);
|
|
Expr<SomeType> re{std::move(*args[0].value().UnwrapExpr())};
|
|
Expr<SomeType> im{args[1] ? std::move(*args[1].value().UnwrapExpr())
|
|
: AsGenericExpr(Constant<Part>{Scalar<Part>{}})};
|
|
return Fold(context,
|
|
Expr<T>{ComplexConstructor<KIND>{ToReal<KIND>(context, std::move(re)),
|
|
ToReal<KIND>(context, std::move(im))}});
|
|
} else if (name == "merge") {
|
|
return FoldMerge<T>(context, std::move(funcRef));
|
|
}
|
|
// TODO: cshift, dot_product, eoshift, matmul, pack, product,
|
|
// reduce, spread, sum, transfer, transpose, unpack
|
|
return Expr<T>{std::move(funcRef)};
|
|
}
|
|
|
|
template<int KIND>
|
|
Expr<Type<TypeCategory::Complex, KIND>> FoldOperation(
|
|
FoldingContext &context, ComplexConstructor<KIND> &&x) {
|
|
if (auto array{ApplyElementwise(context, x)}) {
|
|
return *array;
|
|
}
|
|
using Result = Type<TypeCategory::Complex, KIND>;
|
|
if (auto folded{OperandsAreConstants(x)}) {
|
|
return Expr<Result>{
|
|
Constant<Result>{Scalar<Result>{folded->first, folded->second}}};
|
|
}
|
|
return Expr<Result>{std::move(x)};
|
|
}
|
|
|
|
FOR_EACH_COMPLEX_KIND(template class ExpressionBase, )
|
|
template class ExpressionBase<SomeComplex>;
|
|
}
|