Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable abs and sqrt to return a param in more cases #24127

Merged
merged 13 commits into from
Jan 17, 2024
19 changes: 19 additions & 0 deletions compiler/AST/primitive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,23 @@ returnInfoComplexField(CallExpr* call) { // for get real/imag primitives
return QualifiedType(dtUnknown);
}

static QualifiedType
returnInfoAbs(CallExpr* call) {
Type *t = call->get(1)->getValType();
if (t == dtComplex[COMPLEX_SIZE_64]) {
return QualifiedType(dtReal[FLOAT_SIZE_32], QUAL_VAL);
} else if (t == dtComplex[COMPLEX_SIZE_128]) {
return QualifiedType(dtReal[FLOAT_SIZE_64], QUAL_VAL);
} else if (t == dtImag[FLOAT_SIZE_32]) {
return QualifiedType(dtReal[FLOAT_SIZE_32], QUAL_VAL);
} else if (t == dtImag[FLOAT_SIZE_64]) {
return QualifiedType(dtReal[FLOAT_SIZE_64], QUAL_VAL);
}

return QualifiedType(t, QUAL_VAL);
}


static QualifiedType
returnInfoFirst(CallExpr* call) {
return call->get(1)->qualType();
Expand Down Expand Up @@ -743,6 +760,8 @@ initPrimitive() {
prim_def(PRIM_UNARY_PLUS, "u+", returnInfoFirstDeref);
prim_def(PRIM_UNARY_NOT, "u~", returnInfoFirstDeref);
prim_def(PRIM_UNARY_LNOT, "u!", returnInfoBool);
prim_def(PRIM_SQRT, "sqrt", returnInfoFirst);
prim_def(PRIM_ABS, "abs", returnInfoAbs);
prim_def(PRIM_ADD, "+", returnInfoNumericUp);
prim_def(PRIM_SUBTRACT, "-", returnInfoNumericUp);
prim_def(PRIM_MULT, "*", returnInfoNumericUp);
Expand Down
8 changes: 7 additions & 1 deletion compiler/codegen/cg-expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4608,7 +4608,7 @@ DEFINE_PRIM(UNARY_PLUS) {
else
ret = tmp; // nothing is necessary.
}
DEFINE_PRIM(UNARY_NOT) {
DEFINE_PRIM(UNARY_NOT) {
GenRet tmp = codegenValue(call->get(1));

if (gGenInfo->cfile) {
Expand All @@ -4622,6 +4622,12 @@ DEFINE_PRIM(UNARY_PLUS) {
DEFINE_PRIM(UNARY_LNOT) {
ret = codegenIsZero(call->get(1));
}
DEFINE_PRIM(SQRT) {
INT_FATAL(call, "not expecting to codegen primitive sqrt calls");
}
DEFINE_PRIM(ABS) {
INT_FATAL(call, "not expecting to codegen primitive abs calls");
}
DEFINE_PRIM(ADD) {
ret = codegenAdd(call->get(1), call->get(2));
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/optimizations/optimizeOnClauses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ classifyPrimitive(CallExpr *call) {
case PRIM_POW:
case PRIM_MIN:
case PRIM_MAX:
case PRIM_SQRT:
case PRIM_ABS:

case PRIM_GET_MEMBER:
case PRIM_GET_SVEC_MEMBER:
Expand Down
12 changes: 12 additions & 0 deletions compiler/resolution/postFold.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,18 @@ static Expr* postFoldPrimop(CallExpr* call) {
} else if (call->isPrimitive(PRIM_UNARY_LNOT) == true) {
FOLD_CALL1(P_prim_lnot);

} else if (call->isPrimitive(PRIM_ABS) == true) {
FOLD_CALL1(P_prim_abs);

} else if (call->isPrimitive(PRIM_SQRT) == true) {
FOLD_CALL1(P_prim_sqrt);

} else if (call->isPrimitive(PRIM_GET_REAL) == true) {
FOLD_CALL1(P_prim_get_real);

} else if (call->isPrimitive(PRIM_GET_IMAG) == true) {
FOLD_CALL1(P_prim_get_imag);

} else if (call->isPrimitive(PRIM_ADD) == true) {
FOLD_CALL2(P_prim_add);

Expand Down
40 changes: 19 additions & 21 deletions doc/rst/language/spec/types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -214,36 +214,30 @@ include ``imag(32)`` and ``imag(64)``.
Complex Types
~~~~~~~~~~~~~

Like the integral and real types, the complex types can be parameterized
by the number of bits used to represent them. A complex number is
composed of two real numbers so the number of bits used to represent a
complex is twice the number of bits used to represent the real numbers.
The default complex type, ``complex``, is 128 bits; it consists of two
64-bit real numbers. The complex types that are supported are
machine-dependent, but usually include ``complex(64)`` and
``complex(128)``.
The ``complex`` type represents a complex number. A ``complex`` value has
floating-point values for the real and imaginary components.

As with the integral and real types, the type ``complex`` can be
parameterized by the number of bits used to represent the complex number.
Since the complex number consists of two components, the number of bits
used to represent it is twice the number of bits used to represent each
component.

In particular:

* ``complex(64)`` contains two ``real(32)`` fields
* ``complex(128)`` contains two ``real(64)`` fields

The real and imaginary components can be accessed via the methods ``re``
and ``im``. The type of these components is a ``real``. The standard :mod:`Math`
module provides some functions on complex types. See the :mod:`Math`
module documentation.
and ``im``. Note that ``im`` returns a ``real`` of appropriate width,
rather than an ``imag``.

*Example*.

Given a complex number ``c`` with the value ``3.14+2.72i``, the
expressions ``c.re`` and ``c.im`` refer to ``3.14`` and ``2.72``
respectively.

complex is defined as if it were a record with two fields.
Note that both of these fields are of type *real*.
Specifically the imaginary component is not of type *imag*.
This is important when using the getter/setter for the
field *im*.

.. method:: proc complex.bits: param int

Returns the number of bits used to represent this complex number.

.. method:: proc complex.re ref


Expand All @@ -263,6 +257,10 @@ field *im*.
When used as an lvalue, this is a setter that assigns the
imaginary component.

The standard :mod:`Math` module provides more functions on complex types.
See the :mod:`Math` module documentation.


.. _The_String_Type:

The String Type
Expand Down
8 changes: 8 additions & 0 deletions frontend/include/chpl/types/ComplexType.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,18 @@ class ComplexType final : public PrimitiveType {

static const ComplexType* get(Context* context, int bitwidth);

/** Returns the bit width of this complex (64 or 128 bits,
including both components */
int bitwidth() const override {
return bitwidth_;
}

/** Returns the bit width of a single component of this complex
(which is half of bitwidth() ) */
int componentBitwidth() const {
return bitwidth_ / 2;
}

bool isDefaultWidth() const override {
return bitwidth_ == defaultBitwidth();
}
Expand Down
3 changes: 3 additions & 0 deletions frontend/include/chpl/uast/prim-ops-list.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ PRIMITIVE_R(REDUCE_ASSIGN, "reduce=")
PRIMITIVE_G(MIN, "_min")
PRIMITIVE_G(MAX, "_max")

PRIMITIVE_G(ABS, "abs")
PRIMITIVE_G(SQRT, "sqrt")

PRIMITIVE_G(SETCID, "setcid")
PRIMITIVE_G(TESTCID, "testcid")
PRIMITIVE_G(GETCID, "getcid")
Expand Down
Loading