Tcl Source Code

View Ticket
Login
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: