Hi!
I'm writing a xvid plugin and have the following problem. I to make the plugin code more readable I wrote a small method that should be inlined into the c-code whenever it is called:
insert: color into: output at: offset | intColor | intColor _ self cCoerce: color to: 'int'. output at: offset put: (0 max: (255 min: intColor))
That works. But in addition the generator outputs code for the method itself. But that code does not compile because the generator generates code with output as an int var.
Now declaring outpus as a pointer like:
insert: color into: output at: offset
| intColor | self var: #output type: 'unsigned char*'. intColor _ self cCoerce: color to: 'int'. output at: offset put: (0 max: (255 min: intColor))
does help, but now the method is not inlined any more. Even forcing inlining using self inline: true
does not help.
Martin
You should look at CCodeGenerator>>collectInlineList
to understand why your code does not get inlined.
A long time ago I wrote up a change set to force inline of methods I thought were safe, but violated the rules, see http://www.smalltalkconsulting.com/papers/tipsAndThoughts/source/ ForceInline-JMM.cs Since this example is 5 years old, I'd expect it might require some changes. A little bit of debugging should show you why the inliner is not doing the inlining.
Lastly since you are fiddling with slang, you should be aware if that if you have a instance variable, and if that instance variable is used in methods that fold via inlining into a single C routine the global variable will become a c routine scoped variable. This optimization was used to improve the garbage collector since the mark logic is folded into a single routine but had used instance vars for recording state across multiple methods in ObjectMemory. If you do not wish this behavior you code up an accessor, then it will resort back to a global var.
On May 1, 2005, at 9:15 AM, Martin Kuball wrote:
Hi!
I'm writing a xvid plugin and have the following problem. I to make the plugin code more readable I wrote a small method that should be inlined into the c-code whenever it is called:
insert: color into: output at: offset | intColor | intColor _ self cCoerce: color to: 'int'. output at: offset put: (0 max: (255 min: intColor))
That works. But in addition the generator outputs code for the method itself. But that code does not compile because the generator generates code with output as an int var.
Now declaring outpus as a pointer like:
insert: color into: output at: offset
| intColor | self var: #output type: 'unsigned char*'. intColor _ self cCoerce: color to: 'int'. output at: offset put: (0 max: (255 min: intColor))
does help, but now the method is not inlined any more. Even forcing inlining using self inline: true
does not help.
Martin
-- ======================================================================== === John M. McIntosh johnmci@smalltalkconsulting.com 1-800-477-2659 Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com ======================================================================== ===
Am Monday 02 May 2005 09:48 schrieb John M McIntosh:
You should look at CCodeGenerator>>collectInlineList
to understand why your code does not get inlined.
Well, the offending line is self var: #output type: 'unsigned char*'.
The inlined code can do well without it. But the code generated for the method does not compile without it. So my question is still: why do inlined methods get their own c method definitions? I think I could live without them.
A long time ago I wrote up a change set to force inline of methods I thought were safe, but violated the rules, see http://www.smalltalkconsulting.com/papers/tipsAndThoughts/source/ ForceInline-JMM.cs Since this example is 5 years old, I'd expect it might require some changes. A little bit of debugging should show you why the inliner is not doing the inlining.
Lastly since you are fiddling with slang, you should be aware if that if you have a instance variable, and if that instance variable is used in methods that fold via inlining into a single C routine the global variable will become a c routine scoped variable. This optimization was used to improve the garbage collector since the mark logic is folded into a single routine but had used instance vars for recording state across multiple methods in ObjectMemory. If you do not wish this behavior you code up an accessor, then it will resort back to a global var.
On May 1, 2005, at 9:15 AM, Martin Kuball wrote:
Hi!
I'm writing a xvid plugin and have the following problem. I to make the plugin code more readable I wrote a small method that should be inlined into the c-code whenever it is called:
insert: color into: output at: offset
| intColor |
intColor _ self cCoerce: color to: 'int'. output at: offset put: (0 max: (255 min: intColor))
That works. But in addition the generator outputs code for the method itself. But that code does not compile because the generator generates code with output as an int var.
Now declaring outpus as a pointer like:
insert: color into: output at: offset
| intColor |
self var: #output type: 'unsigned char*'. intColor _ self cCoerce: color to: 'int'. output at: offset put: (0 max: (255 min: intColor))
does help, but now the method is not inlined any more. Even forcing inlining using self inline: true
does not help.
Martin
--
===== === John M. McIntosh johnmci@smalltalkconsulting.com 1-800-477-2659 Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com =================================================================== ===== ===
Martin Kuball MartinKuball@web.de wrote:
Am Monday 02 May 2005 09:48 schrieb John M McIntosh:
You should look at CCodeGenerator>>collectInlineList
to understand why your code does not get inlined.
Well, the offending line is self var: #output type: 'unsigned char*'.
The inlined code can do well without it. But the code generated for the method does not compile without it. So my question is still: why do inlined methods get their own c method definitions? I think I could live without them.
It's all down to how clever (or stupid) the inlining code is. Since the inlining is done purely on a textual basis it isn't smart enough to do semantic analysis or C block analysis etc; so when you have any C declaration in a translated method it gets marked as non-inlinable. Note the line in #collectInlineList that goes hasCCode := m declarations size > 0. and consider it along with TMethod>recordDeclarations. If you (or anyone) can think of a way to handle C declarations in the inlining process, don't hesitate to suggest code.
An alternative that hasn't been tried yet is to stop doing the inlining ourselves and instead mark generated functions for the C compiler to inline. So far as I can tell all current C compilers accept an inline pragma and I suspect could do a much better job. Someone with some time and a wish to help might like to investigate. Generate the VM code with our inlining turned off but add some code to stick the C inline pragma in the function declarations when we have a self inline: true. Run sensible benchmark suites. Gain fame.
tim -- Tim Rowledge, tim@sumeru.stanford.edu, http://sumeru.stanford.edu/tim I am still waiting for the advent of the computer science groupie.
Am Tuesday 03 May 2005 21:46 schrieb Tim Rowledge:
Martin Kuball MartinKuball@web.de wrote:
Am Monday 02 May 2005 09:48 schrieb John M McIntosh:
You should look at CCodeGenerator>>collectInlineList
to understand why your code does not get inlined.
Well, the offending line is self var: #output type: 'unsigned char*'.
The inlined code can do well without it. But the code generated for the method does not compile without it. So my question is still: why do inlined methods get their own c method definitions? I think I could live without them.
It's all down to how clever (or stupid) the inlining code is. Since the inlining is done purely on a textual basis it isn't smart enough to do semantic analysis or C block analysis etc; so when you have any C declaration in a translated method it gets marked as non-inlinable. Note the line in #collectInlineList that goes hasCCode := m declarations size > 0. and consider it along with TMethod>recordDeclarations. If you (or anyone) can think of a way to handle C declarations in the inlining process, don't hesitate to suggest code.
Well, I think you can safely ignore the var:type: message. If the "input" variable in the method that contains the inlined code does not have the right type, you are in trouble anyway. And I don't see a problem with declarations for local variables either. The declarations are added to the other declarations of the method thas includes the inlined code. You just use the givent type instead of int. Where is the problem?
An alternative that hasn't been tried yet is to stop doing the inlining ourselves and instead mark generated functions for the C compiler to inline. So far as I can tell all current C compilers accept an inline pragma and I suspect could do a much better job. Someone with some time and a wish to help might like to investigate. Generate the VM code with our inlining turned off but add some code to stick the C inline pragma in the function declarations when we have a self inline: true. Run sensible benchmark suites. Gain fame.
Sounds good.
Martin
squeak-dev@lists.squeakfoundation.org