HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

For inline

04-20-2008, 11:29 AM#1
Vexorian
There were ideas and ideas, like letting define come back and adding an inline keyword I have concluded though that both those mean work from the coder where the compiler must think about that stuff, so I'll instead take back the idea to add an --optimize argument to jasshelper (toggleable by newgen's jasshelper menu, I guess) and slowly add rules for inlining.

The negative side of it is that there are cases which look like suitable for inline when they actually aren't, imagine this:

Collapse JASS:
globals
     integer x
endglobals
function incx takes integer f returns integer
     set x=x+f
returns x
endfunction


function f takes integer g returns integer
    return incx(1)*g
endfunction

//...
set x=4
call BJDebugMsg( I2S(f(x) )  )

So, when last line gets function f inlined, it would show "25", if it is not inlined it will show 20.

I am thinking of some easy rules for inlining one-liners , later we would worry about bigger functions, imho one liners comprise 99% of the cases that need inlining and 100% of the useful ones... With functions that are larger than 1 line, map size might begin to play a more important role.

These are the temporary rules:
1. function is a one liner.
2. Arguments are used in the function in the same order as the function receives them.
3. Arguments are used in the function one or less times.
3. For every argument given to a function: It must either be a (variable,constant or constant function) OR be present at the function's line.
4. Arguments must be evaluated in the function before other things.

for example:

Collapse JASS:
function getx takes integer this returns real
    return GetUnitX(u[this])
endfunction
should always get inlined.

Collapse JASS:
function x takes real level returns real
    return 1.0
endfunction
Should only get inlined when the argument given is a variable name, a constant or a call to a constant function

And
Collapse JASS:
function y takes real a, real b returns real
    return b*a
endfunction

function z takes real a, real b returns real
    return a*a*b
endfunction

function w takes real a, real b returns real
     return x[level]*a*b
endfunction
are examples of things not to inline.
04-20-2008, 03:52 PM#2
Troll-Brain
where is the function setx ?
you mean incx maybe ?
04-20-2008, 04:00 PM#3
Vexorian
that's right.
04-20-2008, 04:08 PM#4
Troll-Brain
Quote:
1. function is a one liner.
it will be more next ?

and a function with one only argument can be inline, no more than one argument ?
04-20-2008, 04:12 PM#5
Vexorian
Quote:
and a function with one only argument can be inline, no more than one argument ?
I never said that.
04-20-2008, 04:14 PM#6
Troll-Brain
so i missunderstood the last examples
04-22-2008, 01:03 PM#7
Vexorian
I got pseudo code for an inliner that should work for most functions that require inlining, I got updates to the rules.

1. I will assume that all function calls:
* Modify the state.
* Modify the state in a way that makes inlining cause bugs.

This is assumption is wrong 90% of the time, but I think it is better to have false possitives for not being able to inline than to have false negatives.

2. I'll keep a list of functions that don't change the state, right now I am thinking it can have some natives, I also will add something that will detect return bug exploiters (H2I) and mark them as non-state-changing.

3. real arguments require special handling:

Collapse JASS:

function dps takes real level returns real
    return level/2 + 0.1
endfunction


function something takes nothing returns nothing
 local integer level=GetUnitAbilityLevel(//blah blah blah)
 local real r= dps(level)
     
endfunction


inlining dps in this case will cause issues, since level/2 will be integer division.

So I'll have to keep a list of functions, variables and their types, will also need to parse common.j and blizzard.j , anyways if somebody uses a integer in place on a real and the function is safe to be inlined, I'll have to add I2R() automatically.

The initial release of the inlining scheme in jasshelper probably is not going to parse common.j/blizzard.j and be unable to guess if a complex expression like (a * b + 1) (Yeah so complex) is a real or an integer, in cases where it cannot figure things out, I am going to just avoid inlining.


4. If an argument is not present in the function's line or if it is in a position different to the one in the argument list, I am gonna mark it as "requires constant" this means that I will only inline that function if the call gives a constant value or local variable to that argument. When the argument is missing, then it also allows a global variable

This means:

Collapse JASS:
function X takes real y, real z returns real
    return z*y
endfunction

call BJDebugMsg( R2S(  X(0.2,0.1) ) ) //gets inlined
call BJDebugMsg( R2S(  X(0.2, f() )                  ) ) //doesn't get inlined.
call BJDebugMsg( R2S(  X(0.2,globalvar)                  ) ) //doesn't get inlined.
call BJDebugMsg( R2S(  X(0.2,localvar)                  ) ) //gets inlined.



Collapse JASS:
function X takes real y returns real
    return 45.0
endfunction

call BJDebugMsg( R2S(  X(0.2) ) ) //gets inlined
call BJDebugMsg( R2S(  X(anyvar)                  ) ) //gets inlined
call BJDebugMsg( R2S(  X( f() ) ) ) //doesn't get inlined.



5. functions that use the same argument twice. These are not going to be inlined, at least not yet.

6. function calls in the function's line. These are totally allowed if they belong to the special list I mentioned above, or if they are evaluated after all the arguments.

7. Will do the inlining procedure after all jasshelper conversions, the reason is that structs make everything harder and it looks like the algorithm doesn't require any extra information than what the final script got.

8. Will ignore the 'constant' keyword altogether, so constant functions may be inlined, or they may not, it will not depend at all on they having that keyword.

Anyways, I am thinking things like these will get inlined with the current idea:

Collapse JASS:
function F takes integer a, integer b returns integer
    return A[a]*A[b]
endfunction


function G takes integer this returns real
    return GetUnitX(u[this])
endfunction

function D takes real level returns real
    return 500*level + 12.0
endfunction

function V takes handle h returns integer
    return  A[H2I(h)-0x100000]
endfunction

function S takes integer this, real x returns nothing
    set K[this]=x
endfunction

function C takes integer this, real x returns nothing
    call SetUnitX(U[this],x)
endfunction

function T takes nothing returns real
    return TimerGetElapsed(mytimer)
endfunction


I actually think this covers most important one liners...
04-27-2008, 01:39 PM#8
Troll-Brain
Just a question.
will you allow to define like Zoxc did with his World Editor Helper ?
04-27-2008, 01:46 PM#9
Vexorian
That's unrelated isn't it?

I think that after doing my inliner I won't have to. If WEHelper is FOSS I can implement it in Jasshelper though, does anyone know WEHelper's license?
04-27-2008, 02:03 PM#10
Troll-Brain
Quote:
does anyone know WEHelper's license?
not me, i thought it was open source
PS : what FOSS means ?
04-27-2008, 02:06 PM#11
Vexorian
There's a difference between something being open source and something having source code available.
04-27-2008, 02:12 PM#12
Troll-Brain
oh ok, and what about ask him ?
04-27-2008, 02:16 PM#13
Vexorian
Good luck with THAT.