[Vm-dev] [squeak-dev] The Inbox: Collections-nice.807.mcz

Eliot Miranda eliot.miranda at gmail.com
Tue Sep 18 17:26:17 UTC 2018


Hi Levente,

On Tue, Sep 18, 2018 at 8:21 AM Levente Uzonyi <leves at caesar.elte.hu> wrote:

> Hi Eliot,
>
> On Mon, 17 Sep 2018, Eliot Miranda wrote:
>
> > Hi All,
> > On Sat, Sep 15, 2018 at 6:36 PM Bert Freudenberg <bert at freudenbergs.de>
> wrote:
> >       On Sat, Sep 15, 2018 at 4:58 PM Levente Uzonyi <
> leves at caesar.elte.hu> wrote:
> >       Hi Eliot,
> >
> >       Here is a very simple test case:
> >
> >       {
> >               [ 1 to: 500000000 do: [ :i | i = 1 ifTrue: [ true ]
> ifFalse: [ false ] ] ] timeToRun.
> >               [ 1 to: 500000000 do: [ :i | i = 1 ] ] timeToRun.
> >       }
> >
> >       On my machine it gives #(992 1436).
> >
> >
> > Huh, interesting.
> >
> > Eliot, if you figure this out, please let us know what it was ...
> >
> >
> > hmmm.  It's my fault.  It is to do with the criteria the
> StackToRegisterMappingCogit uses to decide whether to inline comparison
> operations.  The code I wrote in genSpecialSelectorComparison says
> >
> > "Only interested in inlining if followed by a conditional branch."
> > inlineCAB := branchDescriptor isBranchTrue or: [branchDescriptor
> isBranchFalse].
> > "Further, only interested in inlining = and ~= if there's a SmallInteger
> constant involved.
> > The relational operators successfully statically predict SmallIntegers;
> the equality operators do not."
> > (inlineCAB and: [primDescriptor opcode = JumpZero or: [primDescriptor
> opcode = JumpNonZero]]) ifTrue:
> > [inlineCAB := argIsIntConst or: [rcvrIsInt]].
> > inlineCAB ifFalse:
> > [^self genSpecialSelectorSend].
> >
> > So the Cogit inlines the = 1 in the first case because it is followed by
> the branch for the ifTrue: [true] ifFalse: [false], but does not inline = 1
> in the second case.  So the second case is a true
> > send, and the true send code (load a register with i, another with 1,
> another with the SmallInteger tag, call the checked entry point of
> SmallInteger>>#=, tag test the receiver, tag test the argument,
> > compare, reify as true or false, return) is more costly, essentially
> because it has a call/return.  I'll discuss with Clément and Sophie we'll
> think about measuring this tradeoff.  This is perhaps a
> > good student project.
> >
> > If anyone has good arguments why the heuristics above are bogus or good
> measurements please post.  In the mean time sorry for the late reply; I was
> airborne on the way back from Cagliari, or sleeping
>
> I see no reason to limit inlining when the result is used. When it's not
> used, then the program is probably incorrect.
> But if you want specific situations when such expressions should be
> jitted, then here's a quick list:
>
> - when the resulting boolean is returned. E.g.:
>
> isEmpty
>
>         ^tally = 0
>
> - when the resulting boolean is the value returned by a block:
>
>         array select: [ :each | each > 0 ]
>
> - when the resulting boolean is part of a larger boolean expression
> (don't know how this can be detected):
>
>         (x = 1 or: [ y = 2 ]) ifTrue: [ ... ]
>
> All in all, I think it's easier to always inline it than not. And I can't
> really find a reason not to inline it.
>

Cool.  Always great to have an excuse for more JIT hacking :-)


> Levente
>
> > in the terminal in Rome and was none too fresh.  ESUG was glorious
> though.  Thanks to all the organisers!!
> >
> > _,,,^..^,,,_
> > best, Eliot
>

_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20180918/0eb260e9/attachment.html>


More information about the Vm-dev mailing list