[squeak-dev] Avoiding compiler inlining

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Avoiding compiler inlining

Nicolas Cellier-3

Following cascading of macros, I need turning some inline off. A
recurrent topic in Squeak-dev.

Well, once i thought about using a Compiler reflective annotation (i.e.
a pragma) in order to turn optimization off.

Stupid me.
Inlined messages are made of block receiver/arguments.
So one would simply turn inlining off by sending a yourself message to a
block.


        [false] yourself whileTrue.
       
        false ifTrue: [self inspect] yourself.

Of course, yourself is not a very explicit message...
We could create another #turnOffInlining or something...

Except that in Squeak as other Smalltalks, the Old Compiler is quite
pedantic about optimizing these messages.

[false] yourself  <- receiver of whileTrue must be a block or variable
->whileTrue.

false ifTrue: [self inspect]  <- argument of ifTrue: must be a block or
variable ->yourself.


Common! You don't like the system? Change It!
This is just 1 method attached.

Ah, and the ifNil test is just a trick for the cascades, remember?

Isn't life easier with Smalltalk compared to a static world?

Nicolas

'From Pharo0.1 of 16 May 2008 [Latest update: #10201] on 13 January 2009 at 1:30:27 am'!
"Change Set: PreventMessageInlining-nice
Date: 13 January 2009
Author: nice

We regularly here about this topic:
How to avoid inlining of some messages like
and: or: ifTrue: whileTrue: etc...

Well it could be fairly easy...
Don't use a block but a message, like:

        2=0 ifFalse: [self inspect] yourself.
That does not work because Old Compiler is quite pedantic,
Ta da!! this one method change should do the trick.

You don't like the system?
Common, change it."!


!MessageNode methodsFor: 'private' stamp: 'nice 1/13/2009 01:29'!
checkBlock: node as: nodeName from: encoder maxArgs: maxArgs
        "vb: #canBeSpecialArgument for blocks hardcodes 0 arguments as the requirement for special blocks. We work around that here by further checking the number of arguments for blocks.."

        node ifNil: [^false]. "Guard against nil receiver in a cascade. This enables cascading of macros."
        node canBeSpecialArgument ifTrue:
                [^node isMemberOf: BlockNode].
        (node isKindOf: BlockNode)
                ifTrue:
                        [node numberOfArguments <= maxArgs
                                ifTrue: [^true]
                                ifFalse: [^encoder notify: '<- ', nodeName , ' of ' ,
                                        (MacroSelectors at: special) , ' has too many arguments']]
                ifFalse:
                        [^false]! !



Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Avoiding compiler inlining

Igor Stasenko
2009/1/12 nicolas cellier <[hidden email]>:

>
> Following cascading of macros, I need turning some inline off. A recurrent
> topic in Squeak-dev.
>
> Well, once i thought about using a Compiler reflective annotation (i.e. a
> pragma) in order to turn optimization off.
>
> Stupid me.
> Inlined messages are made of block receiver/arguments.
> So one would simply turn inlining off by sending a yourself message to a
> block.
>
>
>        [false] yourself whileTrue.
>
>        false ifTrue: [self inspect] yourself.
>
> Of course, yourself is not a very explicit message...
> We could create another #turnOffInlining or something...
>
> Except that in Squeak as other Smalltalks, the Old Compiler is quite
> pedantic about optimizing these messages.
>
> [false] yourself  <- receiver of whileTrue must be a block or variable
> ->whileTrue.
>
> false ifTrue: [self inspect]  <- argument of ifTrue: must be a block or
> variable ->yourself.
>
>
> Common! You don't like the system? Change It!
> This is just 1 method attached.

Heh.. you seem stumbled upon same things as i was :)

well, if you writing own code so you have a total control whether you
want inlining or not, you can simply write:
[ ... ] perform: #whileTrue

(x=y) perform: #ifTrue: with: [ ... ]

:)

but if you don't want inlining at all in a system (like me) - the only
way is to change the compiler.

>
> Ah, and the ifNil test is just a trick for the cascades, remember?
>
> Isn't life easier with Smalltalk compared to a static world?
>
> Nicolas
>


--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Avoiding compiler inlining

Martin Beck-3
Igor Stasenko wrote:

> 2009/1/12 nicolas cellier <[hidden email]>:
>> Following cascading of macros, I need turning some inline off. A recurrent
>> topic in Squeak-dev.
>>
>> Well, once i thought about using a Compiler reflective annotation (i.e. a
>> pragma) in order to turn optimization off.
>>
>> Stupid me.
>> Inlined messages are made of block receiver/arguments.
>> So one would simply turn inlining off by sending a yourself message to a
>> block.
>>
>>
>>        [false] yourself whileTrue.
>>
>>        false ifTrue: [self inspect] yourself.
>>
>> Of course, yourself is not a very explicit message...
>> We could create another #turnOffInlining or something...
>>
>> Except that in Squeak as other Smalltalks, the Old Compiler is quite
>> pedantic about optimizing these messages.
>>
>> [false] yourself  <- receiver of whileTrue must be a block or variable
>> ->whileTrue.
>>
>> false ifTrue: [self inspect]  <- argument of ifTrue: must be a block or
>> variable ->yourself.
>>
>>
>> Common! You don't like the system? Change It!
>> This is just 1 method attached.
>
> Heh.. you seem stumbled upon same things as i was :)
>
> well, if you writing own code so you have a total control whether you
> want inlining or not, you can simply write:
> [ ... ] perform: #whileTrue
>
But keep in mind, that (at least in my Squeak 3.10 image)
BlockContext>>whileTrue: is defined recursively:

whileTrue: aBlock
  ^ [self value] whileTrue: [aBlock value]

Thus, you still get inlined code somewhere. However, this can be changed
to use BlockContext>>restart, I think...

Regards, Martin

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Avoiding compiler inlining

Eliot Miranda-2


On Tue, Jan 13, 2009 at 2:15 AM, Martin Beck <[hidden email]> wrote:
Igor Stasenko wrote:
> 2009/1/12 nicolas cellier <[hidden email]>:
>> Following cascading of macros, I need turning some inline off. A recurrent
>> topic in Squeak-dev.
>>
>> Well, once i thought about using a Compiler reflective annotation (i.e. a
>> pragma) in order to turn optimization off.
>>
>> Stupid me.
>> Inlined messages are made of block receiver/arguments.
>> So one would simply turn inlining off by sending a yourself message to a
>> block.
>>
>>
>>        [false] yourself whileTrue.
>>
>>        false ifTrue: [self inspect] yourself.
>>
>> Of course, yourself is not a very explicit message...
>> We could create another #turnOffInlining or something...
>>
>> Except that in Squeak as other Smalltalks, the Old Compiler is quite
>> pedantic about optimizing these messages.
>>
>> [false] yourself  <- receiver of whileTrue must be a block or variable
>> ->whileTrue.
>>
>> false ifTrue: [self inspect]  <- argument of ifTrue: must be a block or
>> variable ->yourself.
>>
>>
>> Common! You don't like the system? Change It!
>> This is just 1 method attached.
>
> Heh.. you seem stumbled upon same things as i was :)
>
> well, if you writing own code so you have a total control whether you
> want inlining or not, you can simply write:
> [ ... ] perform: #whileTrue
>
But keep in mind, that (at least in my Squeak 3.10 image)
BlockContext>>whileTrue: is defined recursively:

whileTrue: aBlock
 ^ [self value] whileTrue: [aBlock value]

but this recursive definition works:

whileTrue: aBlock
    ^aBlock value ifTrue: [self whileTrue: aBlock]

Recursion  does work if written correctly ;)
 


Thus, you still get inlined code somewhere. However, this can be changed
to use BlockContext>>restart, I think...

Regards, Martin




Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Avoiding compiler inlining

Eliot Miranda-2
In reply to this post by Martin Beck-3


On Tue, Jan 13, 2009 at 2:15 AM, Martin Beck <[hidden email]> wrote:
Igor Stasenko wrote:
> 2009/1/12 nicolas cellier <[hidden email]>:
>> Following cascading of macros, I need turning some inline off. A recurrent
>> topic in Squeak-dev.
>>
>> Well, once i thought about using a Compiler reflective annotation (i.e. a
>> pragma) in order to turn optimization off.
>>
>> Stupid me.
>> Inlined messages are made of block receiver/arguments.
>> So one would simply turn inlining off by sending a yourself message to a
>> block.
>>
>>
>>        [false] yourself whileTrue.
>>
>>        false ifTrue: [self inspect] yourself.
>>
>> Of course, yourself is not a very explicit message...
>> We could create another #turnOffInlining or something...
>>
>> Except that in Squeak as other Smalltalks, the Old Compiler is quite
>> pedantic about optimizing these messages.
>>
>> [false] yourself  <- receiver of whileTrue must be a block or variable
>> ->whileTrue.
>>
>> false ifTrue: [self inspect]  <- argument of ifTrue: must be a block or
>> variable ->yourself.
>>
>>
>> Common! You don't like the system? Change It!
>> This is just 1 method attached.
>
> Heh.. you seem stumbled upon same things as i was :)
>
> well, if you writing own code so you have a total control whether you
> want inlining or not, you can simply write:
> [ ... ] perform: #whileTrue
>
But keep in mind, that (at least in my Squeak 3.10 image)
BlockContext>>whileTrue: is defined recursively:

whileTrue: aBlock
 ^ [self value] whileTrue: [aBlock value]

(Oops, too early in the morning)

this definition  works correctly:

whileTrue: aBlock
    ^self value ifTrue: [self whileTrue: aBlock]

 


Thus, you still get inlined code somewhere. However, this can be changed
to use BlockContext>>restart, I think...

Regards, Martin




Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Avoiding compiler inlining

Eliot Miranda-2
In reply to this post by Martin Beck-3


On Tue, Jan 13, 2009 at 2:15 AM, Martin Beck <[hidden email]> wrote:
Igor Stasenko wrote:
> 2009/1/12 nicolas cellier <[hidden email]>:
>> Following cascading of macros, I need turning some inline off. A recurrent
>> topic in Squeak-dev.
>>
>> Well, once i thought about using a Compiler reflective annotation (i.e. a
>> pragma) in order to turn optimization off.
>>
>> Stupid me.
>> Inlined messages are made of block receiver/arguments.
>> So one would simply turn inlining off by sending a yourself message to a
>> block.
>>
>>
>>        [false] yourself whileTrue.
>>
>>        false ifTrue: [self inspect] yourself.
>>
>> Of course, yourself is not a very explicit message...
>> We could create another #turnOffInlining or something...
>>
>> Except that in Squeak as other Smalltalks, the Old Compiler is quite
>> pedantic about optimizing these messages.
>>
>> [false] yourself  <- receiver of whileTrue must be a block or variable
>> ->whileTrue.
>>
>> false ifTrue: [self inspect]  <- argument of ifTrue: must be a block or
>> variable ->yourself.
>>
>>
>> Common! You don't like the system? Change It!
>> This is just 1 method attached.
>
> Heh.. you seem stumbled upon same things as i was :)
>
> well, if you writing own code so you have a total control whether you
> want inlining or not, you can simply write:
> [ ... ] perform: #whileTrue
>
But keep in mind, that (at least in my Squeak 3.10 image)
BlockContext>>whileTrue: is defined recursively:

whileTrue: aBlock
 ^ [self value] whileTrue: [aBlock value]

Argh!  Never try to write an email when you're hurrying before taking the kids to school.  This one works:

whileTrue: aBlock
    ^self value ifTrue:
        [aBlock value.
         self whileTrue: aBlock]



Thus, you still get inlined code somewhere. However, this can be changed
to use BlockContext>>restart, I think...

Regards, Martin




Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Avoiding compiler inlining

Bert Freudenberg
In reply to this post by Eliot Miranda-2
On 13.01.2009, at 17:16, Eliot Miranda wrote:
> but this recursive definition works:
>
> whileTrue: aBlock
>     ^aBlock value ifTrue: [self whileTrue: aBlock]
>
> Recursion  does work if written correctly ;)

Now if we just had tail-send optimization ...

- Bert -



Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Avoiding compiler inlining

Nicolas Cellier-3
In reply to this post by Igor Stasenko
Igor Stasenko a écrit :

>>
>> Common! You don't like the system? Change It!
>> This is just 1 method attached.
>
> Heh.. you seem stumbled upon same things as i was :)
>
> well, if you writing own code so you have a total control whether you
> want inlining or not, you can simply write:
> [ ... ] perform: #whileTrue
>
> (x=y) perform: #ifTrue: with: [ ... ]
>
> :)
>
> but if you don't want inlining at all in a system (like me) - the only
> way is to change the compiler.
>

Basically, if you want both to coexist, just create a subclass of
MessageNode to redefine noteSpecialSelector:, then subclass all the
chain Compiler/Parser to use that MessageNode... And change
compilerClass where you desire.

If you just want to change the whole system, just change
noteSpecialSelector:. Of course, you will have to find other ways to
decently optimize the execution...

Nicolas


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Re: Avoiding compiler inlining

Igor Stasenko
2009/1/13 nicolas cellier <[hidden email]>:

> Igor Stasenko a écrit :
>>>
>>> Common! You don't like the system? Change It!
>>> This is just 1 method attached.
>>
>> Heh.. you seem stumbled upon same things as i was :)
>>
>> well, if you writing own code so you have a total control whether you
>> want inlining or not, you can simply write:
>> [ ... ] perform: #whileTrue
>>
>> (x=y) perform: #ifTrue: with: [ ... ]
>>
>> :)
>>
>> but if you don't want inlining at all in a system (like me) - the only
>> way is to change the compiler.
>>
>
> Basically, if you want both to coexist, just create a subclass of
> MessageNode to redefine noteSpecialSelector:, then subclass all the chain
> Compiler/Parser to use that MessageNode... And change compilerClass where
> you desire.
>
> If you just want to change the whole system, just change
> noteSpecialSelector:. Of course, you will have to find other ways to
> decently optimize the execution...
>
I made it easier: i wrote own parser  :)

> Nicolas
>
>
>



--
Best regards,
Igor Stasenko AKA sig.


Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Avoiding compiler inlining

Igor Stasenko
In reply to this post by Eliot Miranda-2
2009/1/13 Eliot Miranda <[hidden email]>:

>
>
> On Tue, Jan 13, 2009 at 2:15 AM, Martin Beck
> <[hidden email]> wrote:
>>
>> Igor Stasenko wrote:
>> > 2009/1/12 nicolas cellier <[hidden email]>:
>> >> Following cascading of macros, I need turning some inline off. A
>> >> recurrent
>> >> topic in Squeak-dev.
>> >>
>> >> Well, once i thought about using a Compiler reflective annotation (i.e.
>> >> a
>> >> pragma) in order to turn optimization off.
>> >>
>> >> Stupid me.
>> >> Inlined messages are made of block receiver/arguments.
>> >> So one would simply turn inlining off by sending a yourself message to
>> >> a
>> >> block.
>> >>
>> >>
>> >>        [false] yourself whileTrue.
>> >>
>> >>        false ifTrue: [self inspect] yourself.
>> >>
>> >> Of course, yourself is not a very explicit message...
>> >> We could create another #turnOffInlining or something...
>> >>
>> >> Except that in Squeak as other Smalltalks, the Old Compiler is quite
>> >> pedantic about optimizing these messages.
>> >>
>> >> [false] yourself  <- receiver of whileTrue must be a block or variable
>> >> ->whileTrue.
>> >>
>> >> false ifTrue: [self inspect]  <- argument of ifTrue: must be a block or
>> >> variable ->yourself.
>> >>
>> >>
>> >> Common! You don't like the system? Change It!
>> >> This is just 1 method attached.
>> >
>> > Heh.. you seem stumbled upon same things as i was :)
>> >
>> > well, if you writing own code so you have a total control whether you
>> > want inlining or not, you can simply write:
>> > [ ... ] perform: #whileTrue
>> >
>> But keep in mind, that (at least in my Squeak 3.10 image)
>> BlockContext>>whileTrue: is defined recursively:
>>
>> whileTrue: aBlock
>>  ^ [self value] whileTrue: [aBlock value]
>
> Argh!  Never try to write an email when you're hurrying before taking the
> kids to school.  This one works:
> whileTrue: aBlock
>     ^self value ifTrue:
>         [aBlock value.
>          self whileTrue: aBlock]
>>
>>
>> Thus, you still get inlined code somewhere. However, this can be changed
>> to use BlockContext>>restart, I think...
>>

Aha, something like following:

 whileTrue: aBlock
    self value ifTrue:  [aBlock value ] ifFalse: [ ^ false ].
    thisContext pc: (thisContext method initialPc).

:)

>> Regards, Martin
>>


--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: [squeak-dev] Avoiding compiler inlining

Randal L. Schwartz
>>>>> "Igor" == Igor Stasenko <[hidden email]> writes:

Igor>     thisContext pc: (thisContext method initialPc).

All we have to do now is inline *this*.

:-)

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<[hidden email]> <URL:http://www.stonehenge.com/merlyn/>
Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.
See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion

Reply | Threaded
Open this post in threaded view
|

[squeak-dev] Re: Avoiding compiler inlining

Klaus D. Witzel
On Sun, 18 Jan 2009 17:57:53 +0100, Randal L. Schwartz wrote:

>>>>>> "Igor" == Igor Stasenko writes:
>
> Igor>     thisContext pc: (thisContext method initialPc).
>
> All we have to do now is inline *this*.
>
> :-)

:) but is is "inlined" in the inlined version of #whileTrue: :)

Switching to bytecodes in the code pane shows it (the unconditional jump):

13 <70> self
14 <C9> send: value
15 <9C> jumpFalse: 21
16 <10> pushTemp: 0
17 <C9> send: value
18 <87> pop
19 <A3 F8> jumpTo: 13
21 <73> pushConstant: nil
22 <7C> returnTop

When compiling all methods in the .image with <nomacros> pragma (my own  
compiler ENH for controlling what is inlined), the ENH makes sure the  
existing code of #whileTrue: & friends is compiled with inlining, so that  
the method performs as if in tail recursive fashion.

This seems to be one of the fix points of the language (another one is  
expression [thisContext] relative to inlining).

>

--
"If at first, the idea is not absurd, then there is no hope for it".  
Albert Einstein