Ok. I've recently converted much of partcl's test suite over to "pure tcl". Instead of using a perl based test script, the tests are now written in tcl, using a very small test::more like script. Now we can more easily run the tests from tcl's own test suite, and easily use tclsh to run our own tests.

This also turned out to be a speed win for the smaller test scripts: only one parrot had to be invoked.

However, for larger test files (like t/cmd_expr.t), it's a definite slowdown.

If we run:

../../parrot tcl.pbc --pir t/cmd_expr.t

we get a 9K line PIR sub. Running this through parrot dies after about 2.5m on an runtime error on one of the tests.

Here's a snippet from near the end of the code:

start_1559:
dynamic_1559:
  .local pmc command
    $P1566 = new .String
    $P1566 = 'foreach'
    push_eh invalid_1559
    command = get_hll_global  '&foreach'
    clear_eh
  if_null command, invalid_1559
  $P1565 = command($P1560, $P1561, $P1563)
  goto end_1559
invalid_1559:
  .local pmc interactive
  interactive = get_root_global ['tcl'], '$tcl_interactive'
  unless interactive goto err_command1559
  .local pmc unk
  unk=find_global '&unknown'
  unk($P1566, $P1560, $P1561, $P1563)
  goto end_1559
err_command1559:
  $S0 = $P1566
  $S0 = concat "invalid command name \"", $S0
  $S0 .= "\""
  .throw($S0)
end_1559:

  .return ($P1565)

note the .local declarations there - command, interactive, unk - they're duplicated many times throughout the code. In an effort to make this better (both more correct and faster), I made a local modification to the compiler to avoid re-using named pmcs. So, with this change, we get:

start_1559:
dynamic_1559:
  .local pmc command_1559
    $P1566 = new .String
    $P1566 = 'foreach'
    push_eh invalid_1559
    command_1559 = get_hll_global  '&foreach'
    clear_eh
  if_null command_1559, invalid_1559
  $P1565 = command_1559($P1560, $P1561, $P1563)
  goto end_1559
invalid_1559:
  .local pmc interactive_1559
  interactive_1559 = get_hll_global '$tcl_interactive'
  unless interactive_1559 goto err_command1559
  .local pmc unk_1559
  unk_1559=get_hll_global '&unknown'
  unk_1559($P1566, $P1560, $P1561, $P1563)
  goto end_1559
err_command1559:
  $S0 = $P1566
  $S0 = concat "invalid command name \"", $S0
  $S0 .= "\""
  .throw($S0)
end_1559:

So, this adds (rough guess) about 4600 unique variables to the sub. This makes the run time go from about 2.5m to nearly 7m. (until the same eventual runtime failure which isn't an issue for the purposes of this post. =-).

So... not sure if this is more a question for the partcl end (how can we generate PIR more suitable to parrot), or for the parrot end (how can we more efficiently handle this kind of PIR).

I know the usual caveats about speed (get it working first), but this is one of those times where the current speed makes it somewhat difficult.

One potential change to parrot was suggested by Matt Diephouse on IRC: have a way to declare "this variable is no longer used, I promise" to limit the scope of its consideration when doing register allocation.

Thoughts?
--
Will "Coke" Coleda
[EMAIL PROTECTED]


Reply via email to