#version 120
float dontinlineme(float x) {
while (x > 0) {
if ((x / 5) * 5 == x) {
return x;
}
x--;
}
return x;
}
float inlineme(float x) {
return (x / 5) * 5;
}
attribute float attr;
void main() {
gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
float x = dontinlineme(attr);
float y = inlineme(attr+1.0);
if (x == y) {
gl_Position.yz = vec2(float(x), float(y));
} else {
gl_Position.yxz = vec3(0.4, 0.5, 0.6);
}
}
Here's the AST that is created that represents the shader:
FUNCTION main ( scope=0x80547b680
) param scope = 0x80547b680
{ locals=0x80547b710 outer=0x80547b680
//child 0 of 4:
EXPR: locals=0x80547b788 outer=0x80547b680
ASSIGNMENT locals=0x80547c0a8 outer=0x80547b680
VAR' gl_Position (in scope 0x7fffffffacb8) locals=0x80547b878 outer=0x80547b680
:= at 0x80547b7a0 locals=0x80547c0a8 outer=0x80547b680
LITERAL (0.000000 0.000000 0.000000 1.000000 )
//child 1 of 4:
{ locals=0x80547c270 outer=0x80547b680
//child 0 of 1:
DECL (locals=0x80547c528 outer=0x80547b680) float x (0x80547c290) (in scope 0x80547b680) := INITIALIZER
COMMA-SEQ at 0x80547c2e8 locals=0x805480ca0 outer=0x80547b680
//child 0 of 3:
DECL (locals=0x805480dd8 outer=0x805480ca0) float __resultTmp (0x805480e28) (in scope 0x805480ca0) ;
//child 1 of 3:
{{ // new scope locals=0x805480ea0 outer=0x805479098: x
//child 0 of 4:
DECL (locals=0x805482910 outer=0x805480ea0) float x (0x8054829c8) (in scope 0x805480ea0) :=
VAR' attr (in scope 0x7fffffffad10) locals=0x8054829a0 outer=0x80547b680
//child 1 of 4:
WHILE LOOP: locals = 0x805480fa8
WHILE cond:
EXPR: locals=0x8054810b0 outer=0x805480fa8
VAR' x (in scope 0x805480ea0) locals=0x805481248 outer=0x805480fa8
> at 0x8054810c8 locals=0x805481140 outer=0x805480fa8
LITERAL (0 )
WHILE body:
{{ // new scope locals=0x805481298 outer=0x805480fa8:
//child 0 of 2:
IF
ASM: vec4_multiply at 0x805481538 locals=0x8054853a0 outer=0x8038e47c0
ASM at 0x805481538 locals=0x8054853a0 outer=0x8038e47c0
//child 0 of 2:
COMMA-SEQ at 0x8054853b8 locals=0x8054857c0 outer=0x805481298
//child 0 of 3:
DECL (locals=0x8054858f8 outer=0x8054857c0) float __resultTmp (0x805485948) (in scope 0x8054857c0) ;
//child 1 of 3:
{{ // new scope locals=0x8054859a0 outer=0x8038e7b68: b bInv
//child 0 of 5:
DECL (locals=0x805486170 outer=0x8054859a0) const float b (0x805486228) (in scope 0x8054859a0) :=
LITERAL (5 )
//child 1 of 5:
{ locals=0x805485b20 outer=0x8054859a0
//child 0 of 1:
DECL (locals=0x805485bb0 outer=0x8054859a0) float bInv (0x805486290) (in scope 0x8054859a0) ;
}
//child 2 of 5:
ASM: float_rcp at 0x8054863a8 locals=0x805485bd8 outer=0x8054859a0
ASM at 0x8054863a8 locals=0x805485bd8 outer=0x8054859a0
//child 0 of 2:
FIELD x of
VAR' bInv (in scope 0x8054859a0) locals=0x805485d70 outer=0x8054859a0
//child 1 of 2:
VAR' b (in scope 0x8054859a0) locals=0x805485d98 outer=0x8054859a0
//child 3 of 5:
ASM: vec4_multiply at 0x805486408 locals=0x805485dc0 outer=0x8054859a0
ASM at 0x805486408 locals=0x805485dc0 outer=0x8054859a0
//child 0 of 3:
VAR' __resultTmp (in scope 0x8054857c0) locals=0x805485fb0 outer=0x8054857c0
//child 1 of 3:
VAR' x (in scope 0x805480ea0) locals=0x805485fd0 outer=0x805481298
//child 2 of 3:
VAR' bInv (in scope 0x8054859a0) locals=0x805485f80 outer=0x8054859a0
//child 4 of 5:
LABEL (null)
}}
//child 2 of 3:
VAR __resultTmp (in scope 0x8054857c0)
//child 1 of 2:
LITERAL (5 )
== at 0x8054813b8 locals=0x805481520 outer=0x805481298
VAR' x (in scope 0x805480ea0) locals=0x8054818a8 outer=0x805481298
THEN
{{ // new scope locals=0x8054818d0 outer=0x805481298:
//child 0 of 1:
{ locals=0x805481ff8 outer=0x8054818d0
//child 0 of 2:
ASSIGNMENT locals=0x805482100 outer=0x805481ff8
VAR' __resultTmp (in scope 0x805480ca0) locals=0x805482208 outer=0x805480ca0
:= at 0x805482010 locals=0x805482100 outer=0x805481ff8
VAR' x (in scope 0x805480ea0) locals=0x805482228 outer=0x8054818d0
//child 1 of 2:
RETURN
}
}}
ELSE
EXPR: locals=0x805481a20 outer=0x805481298
(oper-void)
ENDIF
//child 1 of 2:
EXPR: locals=0x805481ae0 outer=0x805481298
COMMA-SEQ at 0x805481af8 locals=0x80548b698 outer=0x805481298
//child 0 of 3:
DECL (locals=0x80548b7d0 outer=0x80548b698) float __resultTmp (0x80548b820) (in scope 0x80548b698) ;
//child 1 of 3:
{{ // new scope locals=0x80548b878 outer=0x8041e1398:
//child 0 of 3:
EXPR: locals=0x80548b980 outer=0x8041e1398
ASSIGNMENT locals=0x80548ba10 outer=0x8041e1398
VAR' __resultTmp (in scope 0x80548b698) locals=0x80548be88 outer=0x80548b698
:= at 0x80548b998 locals=0x80548ba10 outer=0x8041e1398
VAR' x (in scope 0x805480ea0) locals=0x80548bea8 outer=0x805481298
//child 1 of 3:
EXPR: locals=0x80548bb68 outer=0x8041e1398
ASSIGNMENT locals=0x80548bbf8 outer=0x8041e1398
VAR' x (in scope 0x805480ea0) locals=0x80548bec8 outer=0x805481298
:= at 0x80548bb80 locals=0x80548bbf8 outer=0x8041e1398
ASM: vec4_subtract at 0x80548bc70 locals=0x80548e378 outer=0x8038e1490
ASM at 0x80548bc70 locals=0x80548e378 outer=0x8038e1490
//child 0 of 2:
VAR' x (in scope 0x805480ea0) locals=0x80548e560 outer=0x805481298
//child 1 of 2:
LITERAL (1.000000 )
//child 2 of 3:
LABEL (null)
}}
//child 2 of 3:
VAR __resultTmp (in scope 0x80548b698)
}}
END WHILE LOOP
//child 2 of 4:
{ locals=0x805482570 outer=0x805480ea0
//child 0 of 2:
ASSIGNMENT locals=0x805482678 outer=0x805482570
VAR' __resultTmp (in scope 0x805480ca0) locals=0x805482780 outer=0x805480ca0
:= at 0x805482588 locals=0x805482678 outer=0x805482570
VAR' x (in scope 0x805480ea0) locals=0x8054827a0 outer=0x805480ea0
//child 1 of 2:
RETURN
}
//child 3 of 4:
LABEL (null)
}}
//child 2 of 3:
VAR __resultTmp (in scope 0x805480ca0)
}
//child 2 of 4:
{ locals=0x80547c660 outer=0x80547b680
//child 0 of 1:
DECL (locals=0x80547cc28 outer=0x80547b680) float y (0x80547c688) (in scope 0x80547b680) := INITIALIZER
COMMA-SEQ at 0x80547c6e0 locals=0x80548f4e8 outer=0x80547b680
//child 0 of 3:
DECL (locals=0x80548f620 outer=0x80548f4e8) float __resultTmp (0x80548f670) (in scope 0x80548f4e8) ;
//child 1 of 3:
{{ // new scope locals=0x80548f6c8 outer=0x80547abf0: x
//child 0 of 3:
DECL (locals=0x805490570 outer=0x80548f6c8) float x (0x805490758) (in scope 0x80548f6c8) :=
ASM: vec4_add at 0x805490588 locals=0x805492b70 outer=0x8038de1d8
ASM at 0x805490588 locals=0x805492b70 outer=0x8038de1d8
//child 0 of 2:
VAR' attr (in scope 0x7fffffffad10) locals=0x805492d58 outer=0x80547b680
//child 1 of 2:
LITERAL (1.000000 )
//child 1 of 3:
{ locals=0x80548ffd0 outer=0x80548f6c8
//child 0 of 2:
ASSIGNMENT locals=0x8054900d8 outer=0x80548ffd0
VAR' __resultTmp (in scope 0x80548f4e8) locals=0x8054901e0 outer=0x80548f4e8
:= at 0x80548ffe8 locals=0x8054900d8 outer=0x80548ffd0
ASM: vec4_multiply at 0x805490150 locals=0x805493158 outer=0x8038e47c0
ASM at 0x805490150 locals=0x805493158 outer=0x8038e47c0
//child 0 of 2:
COMMA-SEQ at 0x805493170 locals=0x805493578 outer=0x80548f6c8
//child 0 of 3:
DECL (locals=0x8054936b0 outer=0x805493578) float __resultTmp (0x805493700) (in scope 0x805493578) ;
//child 1 of 3:
{{ // new scope locals=0x805493758 outer=0x8038e7b68: b bInv
//child 0 of 5:
DECL (locals=0x805493f28 outer=0x805493758) const float b (0x805493fe0) (in scope 0x805493758) :=
LITERAL (5 )
//child 1 of 5:
{ locals=0x8054938d8 outer=0x805493758
//child 0 of 1:
DECL (locals=0x805493968 outer=0x805493758) float bInv (0x805494048) (in scope 0x805493758) ;
}
//child 2 of 5:
ASM: float_rcp at 0x805494160 locals=0x805493990 outer=0x805493758
ASM at 0x805494160 locals=0x805493990 outer=0x805493758
//child 0 of 2:
FIELD x of
VAR' bInv (in scope 0x805493758) locals=0x805493b28 outer=0x805493758
//child 1 of 2:
VAR' b (in scope 0x805493758) locals=0x805493b50 outer=0x805493758
//child 3 of 5:
ASM: vec4_multiply at 0x8054941c0 locals=0x805493b78 outer=0x805493758
ASM at 0x8054941c0 locals=0x805493b78 outer=0x805493758
//child 0 of 3:
VAR' __resultTmp (in scope 0x805493578) locals=0x805493d68 outer=0x805493578
//child 1 of 3:
VAR' x (in scope 0x80548f6c8) locals=0x805493d88 outer=0x80548f6c8
//child 2 of 3:
VAR' bInv (in scope 0x805493758) locals=0x805493d38 outer=0x805493758
//child 4 of 5:
LABEL (null)
}}
//child 2 of 3:
VAR __resultTmp (in scope 0x805493578)
//child 1 of 2:
LITERAL (5 )
//child 1 of 2:
(oper-void)
}
//child 2 of 3:
LABEL (null)
}}
//child 2 of 3:
VAR __resultTmp (in scope 0x80548f4e8)
}
//child 3 of 4:
IF
VAR' x (in scope 0x80547b680) locals=0x80547ceb0 outer=0x80547b680
== at 0x80547dc90 locals=0x80547d0c0 outer=0x80547b680
VAR' y (in scope 0x80547b680) locals=0x80547cf88 outer=0x80547b680
THEN
{{ // new scope locals=0x80547d288 outer=0x80547b680:
//child 0 of 1:
EXPR: locals=0x80547d300 outer=0x80547d288
ASSIGNMENT locals=0x80547db88 outer=0x80547d288
FIELD yz of
VAR' gl_Position (in scope 0x7fffffffacb8) locals=0x80547d3f0 outer=0x80547d288
:= at 0x80547d318 locals=0x80547db88 outer=0x80547d288
COMMA-SEQ at 0x80547dc00 locals=0x8054998f8 outer=0x80547d288
//child 0 of 3:
DECL (locals=0x805499a30 outer=0x8054998f8) vec2 __resultTmp (0x805499a80) (in scope 0x8054998f8) ;
//child 1 of 3:
{{ // new scope locals=0x805499ad8 outer=0x80380d510: x y
//child 0 of 5:
DECL (locals=0x80549a248 outer=0x805499ad8) const float x (0x80549a398) (in scope 0x805499ad8) :=
COMMA-SEQ at 0x80549a260 locals=0x80549cb98 outer=0x80547d288
//child 0 of 3:
DECL (locals=0x80549ccd0 outer=0x80549cb98) float __resultTmp (0x80549cd20) (in scope 0x80549cb98) ;
//child 1 of 3:
{{ // new scope locals=0x80549cd78 outer=0x80380cb18:
//child 0 of 2:
EXPR: locals=0x80549ce08 outer=0x80380cb18
ASSIGNMENT locals=0x80549ce98 outer=0x80380cb18
VAR' __resultTmp (in scope 0x80549cb98) locals=0x80549cff8 outer=0x80549cb98
:= at 0x80549ce20 locals=0x80549ce98 outer=0x80380cb18
VAR' x (in scope 0x80547b680) locals=0x80549d018 outer=0x80547d288
//child 1 of 2:
LABEL (null)
}}
//child 2 of 3:
VAR __resultTmp (in scope 0x80549cb98)
//child 1 of 5:
DECL (locals=0x80549a570 outer=0x805499ad8) const float y (0x80549a6c8) (in scope 0x805499ad8) :=
COMMA-SEQ at 0x80549a588 locals=0x80549f860 outer=0x80547d288
//child 0 of 3:
DECL (locals=0x80549f998 outer=0x80549f860) float __resultTmp (0x80549f9e8) (in scope 0x80549f860) ;
//child 1 of 3:
{{ // new scope locals=0x80549fa40 outer=0x80380cb18:
//child 0 of 2:
EXPR: locals=0x80549fad0 outer=0x80380cb18
ASSIGNMENT locals=0x80549fb60 outer=0x80380cb18
VAR' __resultTmp (in scope 0x80549f860) locals=0x80549fcc0 outer=0x80549f860
:= at 0x80549fae8 locals=0x80549fb60 outer=0x80380cb18
VAR' y (in scope 0x80547b680) locals=0x80549fce0 outer=0x80547d288
//child 1 of 2:
LABEL (null)
}}
//child 2 of 3:
VAR __resultTmp (in scope 0x80549f860)
//child 2 of 5:
EXPR: locals=0x805499be0 outer=0x805499ad8
ASSIGNMENT locals=0x805499c70 outer=0x805499ad8
FIELD x of
VAR' __resultTmp (in scope 0x8054998f8) locals=0x80549a0e8 outer=0x8054998f8
:= at 0x805499bf8 locals=0x805499c70 outer=0x805499ad8
VAR' x (in scope 0x805499ad8) locals=0x805499e30 outer=0x805499ad8
//child 3 of 5:
EXPR: locals=0x805499e60 outer=0x805499ad8
ASSIGNMENT locals=0x805499ef0 outer=0x805499ad8
FIELD y of
VAR' __resultTmp (in scope 0x8054998f8) locals=0x80549a108 outer=0x8054998f8
:= at 0x805499e78 locals=0x805499ef0 outer=0x805499ad8
VAR' y (in scope 0x805499ad8) locals=0x80549a0b0 outer=0x805499ad8
//child 4 of 5:
LABEL (null)
}}
//child 2 of 3:
VAR __resultTmp (in scope 0x8054998f8)
}}
ELSE
{{ // new scope locals=0x80547ddb0 outer=0x80547b680:
//child 0 of 1:
EXPR: locals=0x80547de28 outer=0x80547ddb0
ASSIGNMENT locals=0x80547e698 outer=0x80547ddb0
FIELD yxz of
VAR' gl_Position (in scope 0x7fffffffacb8) locals=0x80547df18 outer=0x80547ddb0
:= at 0x80547de40 locals=0x80547e698 outer=0x80547ddb0
LITERAL (0.400000 0.500000 0.600000 )
}}
ENDIF
}
Here's the intermediate representation that this gets turned into:
NEW SCOPE
COPY
VAR gl_Position at ENV_PARAM[0] store 0x805458248
FLOAT 0 0 0 1
VAR_DECL x (0x80547c290) at TEMP[-7] store 0x805480b40
COPY
VAR x at TEMP[-7] store 0x805480b40
VAR_DECL __resultTmp (0x805480e28) at TEMP[-7] store 0x805482c58
CALL dontinlineme_1
VAR __resultTmp at TEMP[-7] store 0x805482c58
VAR_DECL y (0x80547c688) at TEMP[-7] store 0x80548f390
COPY
VAR y at TEMP[-7] store 0x80548f390
VAR_DECL __resultTmp (0x80548f670) at TEMP[-7] store 0x805490958
NEW SCOPE
VAR_DECL x (0x805490758) at TEMP[-7] store 0x805492a10
COPY
VAR x at TEMP[-7] store 0x805492a10
IR_ADD (0x805492d98, 0x805492e08) (store 0x805492f18)
VAR attr.x??? at LOCAL_PARAM[16] store 0x80547b650
FLOAT 1 1 1 1
COPY
VAR __resultTmp at TEMP[-7] store 0x805490958
IR_MUL (0x805496db0, 0x805496e20) (store 0x805496f30)
VAR_DECL __resultTmp (0x805493700) at TEMP[-7] store 0x805494308
NEW SCOPE
VAR_DECL b (0x805493fe0) at TEMP[-7] store 0x8054963c0
COPY
VAR b at TEMP[-7] store 0x8054963c0
FLOAT 5 5 5 5
VAR_DECL bInv (0x805494048) at TEMP[-7] store 0x805496650
IR_RCP (0x8054966f0, 0x0) (store 0x8054968b0)
VAR b at TEMP[-7] store 0x8054963c0
IR_MUL (0x805496950, 0x8054969c0) (store 0x805494308)
VAR x at TEMP[-7] store 0x805492a10
VAR bInv at TEMP[-7] store 0x805496650
LABEL: __endOfFunc_/_
VAR __resultTmp at TEMP[-7] store 0x805494308
FLOAT 5 5 5 5
IR_NOP (0x0, 0x0) (store 0x0)
LABEL: __endOfFunc_inlineme_
VAR __resultTmp at TEMP[-7] store 0x805490958
IF
COND
IR_EQUAL (0x805497580, 0x805497510) (store 0x805497660)
VAR x at TEMP[-7] store 0x805480b40
VAR y at TEMP[-7] store 0x80548f390
THEN
NEW SCOPE
COPY
SWIZZLE .yz?? of (store 0x8054997f8)
VAR gl_Position at ENV_PARAM[0] store 0x805458248
SWIZZLE .xxyw of (store 0x8054a2c40)
VAR_DECL __resultTmp (0x805499a80) at TEMP[-7] store 0x80549a988
NEW SCOPE
VAR_DECL x (0x80549a398) at TEMP[-7] store 0x80549ca40
COPY
VAR x at TEMP[-7] store 0x80549ca40
VAR_DECL __resultTmp (0x80549cd20) at TEMP[-7] store 0x80549d180
NEW SCOPE
COPY
VAR __resultTmp at TEMP[-7] store 0x80549d180
VAR x at TEMP[-7] store 0x805480b40
LABEL: __endOfFunc_float_
VAR __resultTmp at TEMP[-7] store 0x80549d180
VAR_DECL y (0x80549a6c8) at TEMP[-7] store 0x80549f708
COPY
VAR y at TEMP[-7] store 0x80549f708
VAR_DECL __resultTmp (0x80549f9e8) at TEMP[-7] store 0x80549fe48
NEW SCOPE
COPY
VAR __resultTmp at TEMP[-7] store 0x80549fe48
VAR y at TEMP[-7] store 0x80548f390
LABEL: __endOfFunc_float_
VAR __resultTmp at TEMP[-7] store 0x80549fe48
COPY
SWIZZLE .x??? of (store 0x8054a24b0)
VAR __resultTmp at TEMP[-7] store 0x80549a988
VAR x at TEMP[-7] store 0x80549ca40
COPY
SWIZZLE .y??? of (store 0x8054a2710)
VAR __resultTmp at TEMP[-7] store 0x80549a988
SWIZZLE .xxzw of (store 0x8054a2820)
VAR y at TEMP[-7] store 0x80549f708
LABEL: __endOfFunc_vec2_
VAR __resultTmp at TEMP[-7] store 0x80549a988
ELSE
NEW SCOPE
COPY
SWIZZLE .yxz? of (store 0x8054a4e48)
VAR gl_Position at ENV_PARAM[0] store 0x805458248
SWIZZLE .yxzw of (store 0x8054a4f88)
FLOAT 0.4 0.5 0.6 0.6
ENDIF
LABEL: __endOfFunc__main
And here's the actual generated code:
# Vertex Program/Shader
0: MOV OUTPUT[0], CONST[0];
1: CAL 22; # dontinlineme_1
2: MOV TEMP[0].x, TEMP[0].yyyy;
3: ADD TEMP[0].w, INPUT[16].xxxx, CONST[0].wwww;
4: MOV TEMP[1].z, CONST[1].xxxx;
5: RCP TEMP[1].w, TEMP[1].zzzz;
6: MUL TEMP[1].y, TEMP[0].wwww, TEMP[1].wwww;
7: MUL TEMP[0].z, TEMP[1].yyyy, CONST[1].xxxx;
8: MOV TEMP[0].y, TEMP[0].zzzz;
9: SEQ TEMP[0].z, TEMP[0].xxxx, TEMP[0].yyyy;
10: IF TEMP[0].zzzz; # (if false, goto 19);
11: MOV TEMP[1].z, TEMP[0].xxxx;
12: MOV TEMP[0].w, TEMP[1].zzzz;
13: MOV TEMP[1].w, TEMP[0].yyyy;
14: MOV TEMP[1].z, TEMP[1].wwww;
15: MOV TEMP[1].x, TEMP[0].wwww;
16: MOV TEMP[1].y, TEMP[1].zzzw;
17: MOV OUTPUT[0].yz, TEMP[1].xxyw;
18: ELSE; # (goto 21)
19: MOV OUTPUT[0].xyz, CONST[2].yxzw;
20: ENDIF;
21: END
22: BGNSUB; # dontinlineme_1
23: MOV TEMP[0].z, INPUT[16].xxxx;
24: BGNLOOP; # (end at 40)
25: SLE TEMP[0].w, TEMP[0].zzzz, CONST[0].xxxx;
26: IF TEMP[0].wwww; # (if false, goto 29);
27: BRK (TR); # (goto 41);
28: ENDIF;
29: MOV TEMP[1].y, CONST[1].xxxx;
30: RCP TEMP[1].z, TEMP[1].yyyy;
31: MUL TEMP[1].x, TEMP[0].zzzz, TEMP[1].zzzz;
32: MUL TEMP[1].y, TEMP[1].xxxx, CONST[1].xxxx;
33: SEQ TEMP[1].x, TEMP[1].yyyy, TEMP[0].zzzz;
34: IF TEMP[1].xxxx; # (if false, goto 37);
35: MOV TEMP[0].y, TEMP[0].zzzz;
36: RET (TR);
37: ENDIF;
38: MOV TEMP[1].y, TEMP[0].zzzz;
39: SUB TEMP[0].z, TEMP[0].zzzz, CONST[0].wwww;
40: ENDLOOP; # (goto 24)
41: MOV TEMP[0].y, TEMP[0].zzzz;
42: RET (TR);
43: ENDSUB; # dontinlineme_1
InputsRead: 0x10000 (0b1,00000000,00000000)
OutputsWritten: 0x0 (0b0)
NumInstructions=44
NumTemporaries=0
NumParameters=0
NumAttributes=0
NumAddressRegs=0
SamplersUsed: 0x0 (0b0)
Samplers=[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ]
param list 0x802cb4280
dirty state flags: 0x0
param[0] sz=4 CONST (null) = {0, 0, 0, 1}
param[1] sz=1 CONST (null) = {5, 5, 5, 5}
param[2] sz=3 CONST (null) = {0.4, 0.5, 0.6, 0.6}
Hopefully that helps make things clearer.