[Vm-dev] VM Maker: VMMaker.oscog-nice.1838.mcz

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Sun Apr 24 13:02:06 UTC 2016


2016-04-24 13:48 GMT+02:00 <commits at source.squeak.org>:

>
> Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:
> http://source.squeak.org/VMMaker/VMMaker.oscog-nice.1838.mcz
>
> ==================== Summary ====================
>
> Name: VMMaker.oscog-nice.1838
> Author: nice
> Time: 24 April 2016, 1:47:02.874 pm
> UUID: 73cf9fda-4e5a-4e0c-a1b9-92ace5f8f3c9
> Ancestors: VMMaker.oscog-nice.1837
>
> Use a type inference that better fits C rules (C99 standard section 6.3):
> - in (float op int), int is promoted to double not float
> - in (unsigned short op short) both operands are promoted to #int due to
> int promotion rules.
>
> The idea behind this is that behaviour of generated code for inlined and
> non inlined code should be the same. We can guaranty such property only if
> we adhere to C rules.
>
> =============== Diff against VMMaker.oscog-nice.1837 ===============
>
> Item was changed:
>   ----- Method: CCodeGenerator>>computeKernelReturnTypes (in category
> 'public') -----
>   computeKernelReturnTypes
>         | dictionary |
>         dictionary := Dictionary newFromPairs:
>                 #(oopAt: #sqInt oopAt:put: #sqInt
>                         oopAtPointer: #sqInt oopAtPointer:put: #sqInt
>                  byteAt: #sqInt byteAt:put: #sqInt
>                         byteAtPointer: #sqInt byteAtPointer:put: #sqInt
>                  shortAt: #sqInt shortAt:put: #sqInt
>                         shortAtPointer: #sqInt shortAtPointer:put: #sqInt
>                  intAt: #sqInt intAt:put: #sqInt
>                         intAtPointer: #sqInt intAtPointer:put: #sqInt
>                  longAt: #sqInt longAt:put: #sqInt
>                         longAtPointer: #sqInt longAtPointer:put: #sqInt
> +                               long32At: #int long32At:put: #int
> -                               long32At: #sqInt long32At:put: #sqInt
>                                         unalignedLongAt: #sqInt
> unalignedLongAt:put: #sqInt
> +                                               unalignedLong32At: #int
> unalignedLong32At:put: #int
> -                                               unalignedLong32At: #sqInt
> unalignedLong32At:put: #sqInt
>
>
Ah, I forgot to comment the purpose of #computeKernelReturnTypes change:
the idea is that we use a type inference that works both for 32 and 64 bits
VM.

Why? Because we generate single source code for both 32 and 64 bits plugins.
So we should have type inference as much independent of BytesPerWord as
possible.

                 long64At: #sqLong long64At:put: #sqLong
>
>                  fetchFloatAt:into: #void storeFloatAt:from: #void
>                         fetchFloatAtPointer:into: #void
> storeFloatAtPointer:from: #void
>                  fetchSingleFloatAt:into: #void storeSingleFloatAt:from:
> #void
>                         fetchSingleFloatAtPointer:into: #void
> storeSingleFloatAtPointer:from: #void
>
>                  pointerForOop: #'char *' oopForPointer: #sqInt).
> -       BytesPerWord = 8 ifTrue:
> -               [#(long32At: long32At:put: unalignedLong32At:
> unalignedLong32At:put:) do:
> -                       [:accessor|
> -                       dictionary at: accessor put: #int]].
>         ^dictionary!
>
> Item was changed:
>   ----- Method: CCodeGenerator>>promoteArithmeticTypes:and: (in category
> 'type inference') -----
>   promoteArithmeticTypes: firstType and: secondType
>         "Answer the return type for an arithmetic send.  This is so that
> the inliner can still inline
> +        simple expressions.  Deal with pointer arithmetic, floating point
> arithmetic and promotion.
> +        It is important to choose deterministically to get stable source
> generation.
> +        Also, the behaviour of inlined and non inlined code should be
> unchanged."
> -        simple expressions.  Deal with pointer arithmetic, floating point
> arithmetic and promotion."
> -       | firstSize secondSize |
>         ((#(#double float) includes: firstType)
>          or: [#(#double float) includes: secondType]) ifTrue:
> +               [^(firstType = #double or: [secondType = #double])
> +                       ifTrue: [#double]
> +                       ifFalse: [#float] "in C99 6.3.1.8, float+int, int
> is converted as a float"].
> -               [^(firstType = #float and: [secondType = #float])
> -                       ifTrue: [#float]
> -                       ifFalse: [#double]].
>         "deal with unknowns, answering nil."
>         (firstType isNil or: [secondType isNil]) ifTrue:
>                 [^nil].
> +       "Deal with integer promotion and arithmetic conversion"
> +       ^self promoteIntegerArithmeticTypes: firstType and: secondType!
> -       "Deal with promotion; answer the longest type, defaulting to the
> recever if they're the same.
> -        See e.g. section 6.3.1.8 Usual arithmetic conversions, from the
> C99 standard:
> -               Otherwise, the integer promotions are performed on both
> operands
> -               Then the following rules are applied to the promoted
> operands:
> -
> -                       If both operands have the same type, then no
> further conversion is needed.
> -
> -                       Otherwise, if both operands have signed integer
> types or both have unsigned integer
> -                       types, the operand with the type of lesser integer
> conversion rank is converted to the
> -                       type of the operand with greater rank.
> -
> -                       Otherwise, if the operand that has unsigned
> integer type has rank greater or equal to
> -                       the rank of the type of the other operand, then
> the operand with signed integer type
> -                       is converted to the type of the operand with
> unsigned integer type.
> -
> -                       Otherwise, if the type of the operand with signed
> integer type can represent all of the
> -                       values of the type of the operand with unsigned
> integer type, then the operand with
> -                       unsigned integer type is converted to the type of
> the operand with signed integer type.
> -
> -                       Otherwise, both operands are converted to the
> unsigned integer type corresponding to
> -                       the type of the operand with signed integer type.
> -
> -       It is important to choose deterministically to get stable source
> generation.  So if the types have
> -       the same size but differ in signedness we choose the unsigned
> type, which is in partial agreement
> -       with the above"
> -       ^(firstSize := self sizeOfIntegralCType: firstType) = (secondSize
> := self sizeOfIntegralCType: secondType)
> -               ifTrue:
> -                       [(firstType first = $u)
> -                               ifTrue: [firstType]
> -                               ifFalse: [(secondType first = $u) ifTrue:
> [secondType] ifFalse: [firstType]]]
> -               ifFalse:
> -                       [firstSize > secondSize ifTrue: [firstType]
> ifFalse: [secondType]]!
>
> Item was added:
> + ----- Method: CCodeGenerator>>promoteIntegerArithmeticTypes:and: (in
> category 'type inference') -----
> + promoteIntegerArithmeticTypes: firstType and: secondType
> +       "Answer the return type for an arithmetic send.
> +       Deal with integer promotion rules of C99.
> +       See section 6.3 Conversions of the standard.
> +
> +       6.3.1.1 ...snip...
> +               If an int can represent all values of the original type,
> the value is converted to an int;
> +               otherwise, it is converted to an unsigned int. These are
> called the integer promotions.
> +               All other types are unchanged by the inte ger promotions
> +
> +       6.3.1.8 ...snip...
> +               Otherwise, the integer promotions are performed on both
> operands
> +               Then the following rules are applied to the promoted
> operands:
> +
> +                       If both operands have the same type, then no
> further conversion is needed.
> +
> +                       Otherwise, if both operands have signed integer
> types or both have unsigned integer
> +                       types, the operand with the type of lesser integer
> conversion rank is converted to the
> +                       type of the operand with greater rank.
> +
> +                       Otherwise, if the operand that has unsigned
> integer type has rank greater or equal to
> +                       the rank of the type of the other operand, then
> the operand with signed integer type
> +                       is converted to the type of the operand with
> unsigned integer type.
> +
> +                       Otherwise, if the type of the operand with signed
> integer type can represent all of the
> +                       values of the type of the operand with unsigned
> integer type, then the operand with
> +                       unsigned integer type is converted to the type of
> the operand with signed integer type.
> +
> +                       Otherwise, both operands are converted to the
> unsigned integer type corresponding to
> +                       the type of the operand with signed integer type.
> +
> +       This is so that the generated code behaviour is unsensitive to
> inlining."
> +       | length1 length2 intSize |
> +       length1 := self sizeOfIntegralCType: firstType.
> +       length2 := self sizeOfIntegralCType: secondType.
> +       intSize := self sizeOfIntegralCType: #int.
> +       (length1 < intSize and: [length2 < intSize]) ifTrue: [^#int].
>  "Integer promotion"
> +       length1 > length2 ifTrue: [^firstType].
> +       length2 > length1 ifTrue: [^secondType].
> +       firstType first = $u ifTrue: [^firstType].
> +       secondType first = $u ifTrue: [^secondType].
> +       ^firstType!
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20160424/59eaabda/attachment.htm


More information about the Vm-dev mailing list