[m-rev.] for review: Reduce memory requirement to build compiler in profdeep grade.
Peter Wang
novalazy at gmail.com
Wed May 12 17:31:37 AEST 2021
On Wed, 12 May 2021 15:57:26 +1000 "Zoltan Somogyi" <zoltan.somogyi at runbox.com> wrote:
>
> 2021-05-11 18:07 GMT+10:00 "Peter Wang" <novalazy at gmail.com>:
> > output_int_binop_for_java needs to handle various cases that require
> > extra casts/masking, so I don't think it's that simple. I left it as-is.
>
> OK, so I have done it instead. The diff is attached, the first bootcheck
> is now on to the tests. For review by you, Peter, since you have the right
> details swapped in.
>
> Note that the diff is hard to read, even with diff --patience, because it
> deletes almost twice as many lines as it adds. I think the best way to review it
> would be to just apply it and read the result, or to read only the lines
> starting with + in the diff. I think the new version of the code, besides
> being shorter, is also much more readable.
It does look a lot better.
>
> Does anyone know why in some cases, when the result of a binop
> needs to be cast, we output
>
> (cast-to-type) (operand1 op operand2)
>
> while in other cases we output
>
> ((cast-to-type) (operand1 op operand2))
>
> In other words, why we put parentheses around the whole thing
> in some cases but not in others?
I wouldn't trust my knowledge of operator precedences (and even if I did),
I could see myself writing the latter just in case. Maybe whoever wrote
it was thinking the same thing.
> diff --git a/compiler/mlds_to_java_data.m b/compiler/mlds_to_java_data.m
> index 32d0fc710..820750da1 100644
> +++ b/compiler/mlds_to_java_data.m
> @@ -573,287 +576,242 @@ output_binop_for_java(Info, Stream, Op, X, Y, !IO) :-
>
> output_int_binop_for_java(Info, Stream, Op, X, Y, !IO) :-
> (
> + ( Op = int_add(Type), OpStr = "+"
> + ; Op = int_sub(Type), OpStr = "-"
> + ; Op = int_mul(Type), OpStr = "*"
> + ),
> + (
> + ( Type = int_type_int
> + ; Type = int_type_int64
> + ; Type = int_type_int32
Reorder those two.
> + ; Type = int_type_uint
> + ; Type = int_type_uint32
> + ; Type = int_type_uint64
> + ),
> + output_basic_binop_maybe_with_enum_for_java(Info, Stream,
> + OpStr, X, Y, !IO)
> + ;
> + ( Type = int_type_int8, Cast = "(byte) "
> + ; Type = int_type_int16, Cast = "(short) "
> + ; Type = int_type_uint8, Cast = "(byte) "
> + ; Type = int_type_uint16, Cast = "(short) "
> + ),
> + io.write_string(Stream, Cast, !IO),
> + % XXX Document why we aren't calling
> + % output_basic_binop_maybe_with_enum_for_java here.
> + output_basic_binop_for_java(Info, Stream,
> + OpStr, X, Y, !IO)
> + )
> + ;
> + ( Op = int_div(Type), OpStr = "/"
> + ; Op = int_mod(Type), OpStr = "%"
> + ),
> + (
> + ( Type = int_type_int
> + ; Type = int_type_int32
> + ; Type = int_type_int64
> + ),
> + output_basic_binop_maybe_with_enum_for_java(Info, Stream,
> + OpStr, X, Y, !IO)
> + ;
> + ( Type = int_type_int8, Cast = "(byte) "
> + ; Type = int_type_int16, Cast = "(short) "
> + ),
> + io.write_string(Stream, Cast, !IO),
> + output_basic_binop_for_java(Info, Stream,
> + OpStr, X, Y, !IO)
> + ;
> + ( Type = int_type_uint8, Cast = "(byte)", Mask = "0xff"
> + ; Type = int_type_uint16, Cast = "(short)", Mask = "0xffff"
> + ; Type = int_type_uint32, Cast = "(int)", Mask = "0xffffffff"
> + ; Type = int_type_uint, Cast = "(int)", Mask = "0xffffffff"
> + ),
> + io.format(Stream, "(%s ", [s(Cast)], !IO),
> + output_basic_binop_with_mask_for_java(Info, Stream,
> + OpStr, Mask, X, Y, !IO),
> + io.write_string(Stream, ")", !IO)
> + ;
> + Type = int_type_uint64,
> + % We could compute FuncName along with OpStr above,
> + % but uint64 operands are rare enough that it is better
> + % not to burden the non-uint64 code path with recording FuncName.
> + ( Op = int_div(_), FuncName = "java.lang.Long.divideUnsigned"
> + ; Op = int_mod(_), FuncName = "java.lang.Long.remainderUnsigned"
> + ),
> + output_binop_func_call_for_java(Info, Stream,
> + FuncName, X, Y, !IO)
> + )
> + ;
> + ( Op = int_lt(Type), OpStr = "<"
> + ; Op = int_gt(Type), OpStr = ">"
> + ; Op = int_le(Type), OpStr = "<="
> + ; Op = int_ge(Type), OpStr = ">="
> + ),
> + (
> + ( Type = int_type_int
> + ; Type = int_type_int8
> + ; Type = int_type_int16
> + ; Type = int_type_int32
> + ; Type = int_type_int64
> + ),
> + output_basic_binop_maybe_with_enum_for_java(Info, Stream,
> + OpStr, X, Y, !IO)
> + ;
> + ( Type = int_type_uint8, Mask = "0xffL"
> + ; Type = int_type_uint16, Mask = "0xffffL"
Remove the 'L' suffixes. They weren't there before.
> + ; Type = int_type_uint32, Mask = "0xffffffffL"
> + ; Type = int_type_uint, Mask = "0xffffffffL"
> + ),
> + output_basic_binop_with_mask_for_java(Info, Stream,
> + OpStr, Mask, X, Y, !IO)
> + ;
> + Type = int_type_uint64,
> + io.write_string(Stream, "(", !IO),
> + output_binop_func_call_for_java(Info, Stream,
> + "java.lang.Long.compareUnsigned", X, Y, !IO),
> + io.format(Stream, " %s 0)", [s(OpStr)], !IO)
> + )
> + ;
> + ( Op = bitwise_and(Type), OpStr = "&"
> + ; Op = bitwise_or(Type), OpStr = "|"
> + ; Op = bitwise_xor(Type), OpStr = "^"
> + ),
> + (
> + ( Type = int_type_int
> + ; Type = int_type_int32
> + ; Type = int_type_int64
> + ; Type = int_type_uint
> + ; Type = int_type_uint32
> + ; Type = int_type_uint64
> + ),
> + output_basic_binop_maybe_with_enum_for_java(Info, Stream,
> + OpStr, X, Y, !IO)
> + ;
> + ( Type = int_type_int8, Cast = "(byte) "
> + ; Type = int_type_int16, Cast = "(short) "
> + ; Type = int_type_uint8, Cast = "(byte) "
> + ; Type = int_type_uint16, Cast = "(short) "
> + ),
> + io.write_string(Stream, Cast, !IO),
> + output_basic_binop_for_java(Info, Stream,
> + OpStr, X, Y, !IO)
> + )
> + ;
> + (
> + Op = unchecked_left_shift(Type, _ShiftByType),
> + OpStr = "<<"
> + ;
> + Op = unchecked_right_shift(Type, _ShiftByType),
> + (
> + ( Type = int_type_int
> + ; Type = int_type_int8
> + ; Type = int_type_int16
> + ; Type = int_type_int32
> + ; Type = int_type_int64
> + ),
> + OpStr = ">>"
> + ;
> + ( Type = int_type_uint
> + ; Type = int_type_uint8
> + ; Type = int_type_uint16
> + ; Type = int_type_uint32
> + ; Type = int_type_uint64
> + ),
> + OpStr = ">>>"
> + )
> + ),
> + % We ignore the distinction between shift_by_int and
> + % shift_by_uint, because when targeting Java, we represent
> % Mercury uints as Java ints anyway.
> + (
> + ( Type = int_type_int
> + ; Type = int_type_int32
> + ; Type = int_type_int64
> + ; Type = int_type_uint
> + ; Type = int_type_uint32
> + ; Type = int_type_uint64
> + ),
> + output_basic_binop_maybe_with_enum_for_java(Info, Stream,
> + OpStr, X, Y, !IO)
> + ;
> + ( Type = int_type_int8, Cast = "(byte) ", Mask = ""
> + ; Type = int_type_int16, Cast = "(short) ", Mask = ""
> + ; Type = int_type_uint8, Cast = "(byte) ", Mask = "0xff"
> + ; Type = int_type_uint16, Cast = "(short) ", Mask = "0xffff"
> + ),
> + io.write_string(Stream, Cast, !IO),
> + ( if
> + Op = unchecked_right_shift(_, _),
> + Mask \= ""
> + then
> + output_basic_binop_with_mask_for_java(Info, Stream,
> + OpStr, Mask, X, Y, !IO)
output_basic_binop_with_mask_for_java will mask both X and Y,
whereas the old code only masked X.
A comment about what Mask does would prevent questions about why it
isn't needed for left shifts. It converts a signed byte or short value
into a positive int value, thus preventing shifting in 1s from the left
when right shifting.
> + else
> + output_basic_binop_for_java(Info, Stream,
> + OpStr, X, Y, !IO)
> + )
> + )
> ).
>
The rest looks fine.
Peter
More information about the reviews
mailing list