From: peter klausler Date: Tue, 19 Jun 2018 23:26:48 +0000 (-0700) Subject: [flang] Expression work X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e03280c09c6ff4966f81f4771f7cfb1514e0d7be;p=platform%2Fupstream%2Fllvm.git [flang] Expression work Original-commit: flang-compiler/f18@b60c84fff491d19402f95f825b4be42f239ac2a9 Reviewed-on: https://github.com/flang-compiler/f18/pull/111 Tree-same-pre-rewrite: false --- diff --git a/flang/lib/evaluate/expression.h b/flang/lib/evaluate/expression.h index 1f9cb69..343230b 100644 --- a/flang/lib/evaluate/expression.h +++ b/flang/lib/evaluate/expression.h @@ -31,39 +31,24 @@ template struct ExprOperand { common::Indirection> v; }; +template class T> using IntegerKindsVariant = + std::variant, T<2>, T<4>, T<8>, T<16>>; +template class T> using RealKindsVariant = + std::variant, T<4>, T<8>, T<10>, T<16>>; +template class T> using CharacterKindsVariant = + std::variant>; // TODO larger CHARACTER kinds, incl. Kanji + struct IntegerOperand { - std::variant>, - ExprOperand>, - ExprOperand>, - ExprOperand>, - ExprOperand>> - u; + template using Operand = ExprOperand>; + IntegerKindsVariant u; }; struct RealOperand { - std::variant>, - ExprOperand>, - ExprOperand>, - ExprOperand>, - ExprOperand>> - u; -}; -struct ComplexOperand { - std::variant>, - ExprOperand>, - ExprOperand>, - ExprOperand>, - ExprOperand>> - u; + template using Operand = ExprOperand>; + RealKindsVariant u; }; struct CharacterOperand { - std::variant>> u; -}; - -struct FloatingOperand { - std::variant u; -}; -struct NumericOperand { - std::variant u; + template using Operand = ExprOperand>; + CharacterKindsVariant u; }; template struct NumericBase { @@ -72,17 +57,19 @@ template struct NumericBase { using Result = Type; using Operand = ExprOperand; using Constant = typename Result::Value; - struct Unary { - enum class Operator { Parentheses, Negate } op; - Operand x; - }; - struct Binary { - enum class Operator { Add, Subtract, Multiply, Divide, Power } op; - Operand x, y; - }; struct Convert { - NumericOperand x; + // N.B. Conversions to/from Complex are done with CMPLX and part access + // operations (resp.). Conversions between kinds of Complex are done + // via decomposition and reconstruction. + std::variant u; }; + struct Parentheses { Operand x; }; + struct Negate { Operand x; }; + struct Add { Operand x, y; }; + struct Subtract { Operand x, y; }; + struct Multiply { Operand x, y; }; + struct Divide { Operand x, y; }; + struct Power { Operand x, y; }; }; template @@ -90,19 +77,21 @@ struct Expression> : public NumericBase { using Base = NumericBase; using Result = typename Base::Result; - using Constant = typename Base::Constant; using Convert = typename Base::Convert; - using Unary = typename Base::Unary; - using Binary = typename Base::Binary; + using Constant = typename Base::Constant; + using Parentheses = typename Base::Parentheses; + using Negate = typename Base::Negate; + using Add = typename Base::Add; + using Subtract = typename Base::Subtract; + using Multiply = typename Base::Multiply; + using Divide = typename Base::Divide; + using Power = typename Base::Power; Expression() = delete; Expression(Expression &&) = default; - Expression(const Constant &x) : u{x} {} - Expression(Convert &&x) : u{std::move(x)} {} - Expression(typename Unary::Operator o, Expression &&a) - : u{Unary{o, std::move(a)}} {} - Expression(typename Binary::Operator o, Expression &&a, Expression &&b) - : u{Binary{o, std::move(a), std::move(b)}} {} - std::variant u; + Expression(const typename Base::Constant &x) : u{x} {} + template Expression(A &&x) : u{std::move(x)} {} + std::variant u; }; template @@ -121,18 +110,23 @@ struct Expression> using Result = typename Base::Result; using Constant = typename Base::Constant; using Convert = typename Base::Convert; - using Unary = typename Base::Unary; - using Binary = typename Base::Binary; + using Parentheses = typename Base::Parentheses; + using Negate = typename Base::Negate; + using Add = typename Base::Add; + using Subtract = typename Base::Subtract; + using Multiply = typename Base::Multiply; + using Divide = typename Base::Divide; + using Power = typename Base::Power; using IntegerPower = typename Base::IntegerPower; + struct RealPart { ExprOperand x; }; + struct AIMAG { ExprOperand x; }; Expression() = delete; Expression(Expression &&) = default; Expression(const Constant &x) : u{x} {} - Expression(Convert &&x) : u{std::move(x)} {} - Expression(typename Unary::Operator o, Expression &&a) - : u{Unary{o, std::move(a)}} {} - Expression(typename Binary::Operator o, Expression &&a, Expression &&b) - : u{Binary{o, std::move(a), std::move(b)}} {} - std::variant u; + template Expression(A &&x) : u{std::move(x)} {} + std::variant u; }; template @@ -141,19 +135,21 @@ struct Expression> using Base = FloatingBase; using Result = typename Base::Result; using Constant = typename Base::Constant; - using Convert = typename Base::Convert; - using Unary = typename Base::Unary; - using Binary = typename Base::Binary; + using Parentheses = typename Base::Parentheses; + using Negate = typename Base::Negate; + using Add = typename Base::Add; + using Subtract = typename Base::Subtract; + using Multiply = typename Base::Multiply; + using Divide = typename Base::Divide; + using Power = typename Base::Power; using IntegerPower = typename Base::IntegerPower; + struct CMPLX { ExprOperand re, im; }; Expression() = delete; Expression(Expression &&) = default; Expression(const Constant &x) : u{x} {} - Expression(Convert &&x) : u{std::move(x)} {} - Expression(typename Unary::Operator o, Expression &&a) - : u{Unary{o, std::move(a)}} {} - Expression(typename Binary::Operator o, Expression &&a, Expression &&b) - : u{Binary{o, std::move(a), std::move(b)}} {} - std::variant u; + template Expression(A &&x) : u{std::move(x)} {} + std::variant u; }; template<> struct Expression> { @@ -163,54 +159,85 @@ template<> struct Expression> { using Result = Type; using Operand = ExprOperand; using Constant = typename Result::Value; + struct Not { Operand x; }; + struct And { Operand x, y; }; + struct Or { Operand x, y; }; + struct Eqv { Operand x, y; }; + struct Neqv { Operand x, y; }; - struct Unary { - enum class Operator { Not } op; - Operand x; + template struct Comparison { + using Operand = ExprOperand; + struct LT { Operand x, y; }; + struct LE { Operand x, y; }; + struct EQ { Operand x, y; }; + struct NE { Operand x, y; }; + struct GE { Operand x, y; }; + struct GT { Operand x, y; }; + std::variant u; // TODO: .UN.? }; - struct Binary { - enum class Operator { And, Or, Eqv, Neqv } op; - Operand x, y; + template struct Comparison> { + using Operand = ExprOperand>; + struct EQ { Operand x, y; }; + struct NE { Operand x, y; }; + std::variant u; }; - enum class ComparisonOperator { LT, LE, EQ, NE, GE, GT }; // TODO: .UN.? - template struct Comparison { - ComparisonOperator op; - ExprOperand x, y; + struct IntegerComparison { + template using C = Comparison>; + IntegerKindsVariant u; }; - enum class EqualityOperator { EQ, NE }; - template struct ComplexComparison { - EqualityOperator op; - ExprOperand> x, y; + struct RealComparison { + template using C = Comparison>; + RealKindsVariant u; + }; + + struct ComplexComparison { + template using C = Comparison>; + RealKindsVariant u; }; Expression() = delete; Expression(Expression &&) = default; Expression(const Constant &x) : u{x} {} - Expression(typename Unary::Operator o, Expression &&a) - : u{Unary{o, std::move(a)}} {} - Expression(typename Binary::Operator o, Expression &&a, Expression &&b) - : u{Binary{o, std::move(a), std::move(b)}} {} - template - Expression(ComparisonOperator o, Expression &&a, Expression &&b) - : u{Comparison{o, std::move(a), std::move(b)}} {} - template - Expression(EqualityOperator o, Expression> &&a, - Expression> &&b) - : u{ComplexComparison{o, std::move(a), std::move(b)}} {} - std::variant>, + template Expression(A &&x) : u{std::move(x)} {} + + template static Comparison LT(Expression &&x, Expression &&y) { + return {typename Comparison::LT{std::move(x), std::move(y)}}; + } + template static Comparison LE(Expression &&x, Expression &&y) { + return {typename Comparison::LE{std::move(x), std::move(y)}}; + } + template static Comparison EQ(Expression &&x, Expression &&y) { + return {typename Comparison::EQ{std::move(x), std::move(y)}}; + } + template static Comparison NE(Expression &&x, Expression &&y) { + return {typename Comparison::NE{std::move(x), std::move(y)}}; + } + template static Comparison GE(Expression &&x, Expression &&y) { + return {typename Comparison::GE{std::move(x), std::move(y)}}; + } + template static Comparison GT(Expression &&x, Expression &&y) { + return {typename Comparison::GT{std::move(x), std::move(y)}}; + } + + std::variant>, Comparison>, Comparison>, Comparison>, Comparison>, Comparison>, - Comparison>, Comparison>, - Comparison>, Comparison>, - Comparison>, ComplexComparison<2>, - ComplexComparison<4>, ComplexComparison<8>, ComplexComparison<10>, - ComplexComparison<16>> - u; + Comparison>, + Comparison>, + Comparison>, + Comparison>, + Comparison>, + Comparison>, + Comparison>, + Comparison>, + Comparison>, + Comparison>> u; }; template struct Expression> { @@ -218,9 +245,7 @@ template struct Expression> { static constexpr int kind{KIND}; using Result = Type; using Constant = typename Result::Value; - struct Concat { - ExprOperand x, y; - }; + struct Concat { ExprOperand x, y; }; Expression() = delete; Expression(Expression &&) = default; Expression(const Constant &x) : u{x} {} diff --git a/flang/lib/evaluate/type.h b/flang/lib/evaluate/type.h index 792411e..f289762 100644 --- a/flang/lib/evaluate/type.h +++ b/flang/lib/evaluate/type.h @@ -46,31 +46,37 @@ struct Type template<> struct Type : public TypeBase { using Value = value::Real::Value, 11>; + using Complex = Type; }; template<> struct Type : public TypeBase { using Value = value::Real::Value, 24>; + using Complex = Type; }; template<> struct Type : public TypeBase { using Value = value::Real::Value, 53>; + using Complex = Type; }; template<> struct Type : public TypeBase { using Value = value::Real, 64, false>; + using Complex = Type; }; template<> struct Type : public TypeBase { using Value = value::Real::Value, 112>; + using Complex = Type; }; // The KIND type parameter on COMPLEX is the kind of each of its components. template struct Type : public TypeBase { - using Value = value::Complex::Value>; + using Part = Type; + using Value = value::Complex; }; template @@ -95,8 +101,9 @@ template struct Type { using DefaultReal = Type; using DefaultInteger = Type; using IntrinsicTypeParameterType = DefaultInteger; -using DefaultComplex = Type; -using DefaultLogical = Type; +using DefaultComplex = typename DefaultReal::Complex; +using DefaultLogical = Type; using DefaultCharacter = Type; + } // namespace Fortran::evaluate #endif // FORTRAN_EVALUATE_TYPE_H_ diff --git a/flang/test/evaluate/expression.cc b/flang/test/evaluate/expression.cc index 84b020b..a161fc0 100644 --- a/flang/test/evaluate/expression.cc +++ b/flang/test/evaluate/expression.cc @@ -22,12 +22,11 @@ using namespace Fortran::evaluate; int main() { using Int4 = Type; using IntEx4 = Expression; - auto ie = IntEx4{value::Integer<32>(666)}; - auto one = IntEx4{value::Integer<32>(1)}; - auto incr = - IntEx4{IntEx4::Binary::Operator::Add, std::move(ie), std::move(one)}; + IntEx4 ie{value::Integer<32>(666)}; + IntEx4 one{value::Integer<32>(1)}; + IntEx4 incr{IntEx4::Add{std::move(ie), std::move(one)}}; using Log = Expression>; - auto two = IntEx4{value::Integer<32>(2)}; - auto cmp = Log{Log::ComparisonOperator::EQ, std::move(incr), std::move(two)}; + IntEx4 two{value::Integer<32>(2)}; + Log cmp{Log::EQ(std::move(incr), std::move(two))}; return testing::Complete(); }