Ticket UUID: | 465811 | |||
Title: | Optimize if/while/... during compilation | |||
Type: | RFE | Version: | None | |
Submitter: | andreas_kupries | Created on: | 2001-09-27 20:50:54 | |
Subsystem: | 47. Bytecode Compiler | Assigned To: | msofer | |
Priority: | 5 Medium | Severity: | ||
Status: | Closed | Last Modified: | 2002-02-23 02:59:33 | |
Resolution: | Accepted | Closed By: | msofer | |
Closed on: | 2002-02-22 19:59:33 | |||
Description: |
This is possibly not a feature request but a performance bug / enhancement. The control commands [if], [while] and [for] currently do not check their expression arguments for static strings and constant expressions. This means that for example if {0} { bla } is compiled into bytecode despite the fact that the code will not be executed, ever. I propose that the compile procedures for the aformentioned commands are extended to detect simple constant expressions and to react accordingly. I.e. not to compile the if/while/for statement at all or only partially and to compile only the sub-scripts which are reachable for the constant expression. This enhancement is along the lines of the optimization for [proc {args} {}], but should present less problems with recompilation as no commands are implicitly added or removed from the interp. It does present a new set of challenges if we want to go beyond the detection of simple constant expressions to the detection of (0 && ...) etc. Note: This is easier for logical expressions as they are defined to have shortcircuit evaluation and thus present less problems with regard to variable tracing. | |||
User Comments: |
msofer added on 2002-02-23 02:59:33:
Logged In: YES user_id=148712 Doh ... simple constant conditions *are* detected ("if 0", "while on", ...). What is not done is the detection of simple expressions that evaluate to a constant ("if {0 && $w}") msofer added on 2002-02-23 02:55:40: Logged In: YES user_id=148712 Committed; the detection of simple constant conditions remains in the to-do list. hobbs added on 2002-02-23 02:25:51: Logged In: YES user_id=72656 go ahead and commit msofer added on 2002-02-09 01:17:44: Logged In: YES user_id=148712 while 1 {...} does compile the efficient version; witness Source "while 1 break\n" Cmds 2, src 14, inst 7, litObjs 1, aux 0, stkDepth 1, code/src 11.14 Code 156 = header 100+inst 7+litObj 4+exc 28+aux 0+cmdMap 8 Exception ranges 1, depth 1: 0: level 1, loop, pc 0-0, continue 0, break 4 Commands 2: 1: pc 0-5, src 0-12 2: pc 0-0, src 8-12 Command 1: "while 1 break" Command 2: "break" (0) break (1) pop (2) jump1 -2 # pc 0 (4) push1 0 # "" (6) done andreas_kupries added on 2002-02-09 01:00:24: Logged In: YES user_id=75003 In general it looks ok, in detail I can't say cause I know zilch about the data structures used by the compiler. I will reassign this to Jeff. Question about: while (1) {}. Does it generate B: body goto B or the less efficient goto A B: body A: goto B ? msofer added on 2002-02-09 00:07:25: File Added - 17495: 465811.patch msofer added on 2002-02-09 00:07:24: Logged In: YES user_id=148712 The enclosed patch includes the following optimisations: * [if]: optimise for constant boolean conditions * [for]: loop rotation to avoid one extra branch in the loop * [while]: both optimisations above It also fixes the bug in my last comment. Assigning to aku for comments. msofer added on 2001-09-29 05:08:00: Logged In: YES user_id=148712 proc foo {} { if {0} { catch this thing that won't work } return 0 } currently errs out on compilation; it is a bug ... kennykb added on 2001-09-29 05:03:50: Logged In: YES user_id=99768 This sounds like a fine idea. We also have to make sure that the scripts themselves are constant. Otherwise, we'll generate incorrect code for something like if 0 [commandWithSideEffects] |
Attachments:
- 465811.patch [download] added by msofer on 2002-02-09 00:07:24. [details]