Le 11/03/2011 06:37, Karl Lehenbauer a écrit :
> * If you have a genius type and want to give her something she'll probably> fail at, then a project to compile Tcl bytecode on the fly into native> code using LLVM would be really badass. (I'm not a bytecode internals guy> and I know the variable tracing issue really kills a lot of the> optimization possibilities, so I don't know how viable this is.)
Trace tree compiling might solve these issues. We already have some of the
infrastructure for experimentation with [trace add execution] as well as
bytecode introspection. As this technique inlines procedure calls, this
addresses Tcl traces and dynamic command dispatching (inc. command redefinition)
quite well IMHO. For example if you have a read trace on a variable used in a
loop body, you're likely to trigger the trace at each iteration until it is
removed. Since commands are inlined by the TTC, this means the trace body would
be inlined & unrolled as part of the loop, and the guard condition would fail
when the trace is deleted.
See:
http://andreasgal.wordpress.com/2008/06/02/trace-trees-faq/
So in the following code:
proc log {name1 name2 op} {upvar $name1 v; puts stderr "$name1 becomes $v"}
trace add variable sum write log
set sum 0
for {set i 0} {$i < 10} {incr i} {
incr sum $i
}
the loop becomes (pseudocode, you get the idea):
/* type-inferred local variables at trace recording time */
int sum = 0;
int i = 0;
/* guard conditions */
while (i < 10 && isIntrinsic("incr") && isIntrinsic("puts")
&& traceVarExists("sum", "write", "log"))
/* loop body */
{
/* incr was an intrinsic at trace recording time */
sum += i;
/* inlined trace call at trace recording time */
{
/* type-inferred arguments and local variables */
string name1 = "sum";
int v = sum;
/* command body */
/* puts was an intrinsic at trace recording time */
printf("%s becomes %d", name1, v);
}
/* incr was an intrinsic at trace recording time */
i++;
}
/* back to interpreter & trace recorder */
setIntVar("sum", sum);
There can be extra steps of optimization to remove unnecessary guard conditions,
but this can also be done by the compilation framework (e.g. LLVM).
So here you can see that the code remains valid as long as the trace exists and
the [incr] and [puts] commands don't get redefined. Since this is the case, the
optimizer may remove the noise and end up with this core code:
int sum = 0;
int i = 0;
while (i < 10) {
sum += i;
printf("%s becomes %d", "sum", sum);
i++;
}
setIntVar("sum", sum);
But even without these optimization steps, the result is way better that
anything traditional compiling techniques can provide in a dynamic environment.
------------------------------------------------------------------------------
Colocation vs. Managed Hosting
A question and answer guide to determining the best fit
for your organization - today and in the future.
http://p.sf.net/sfu/internap-sfd2d
_______________________________________________
Tcl-Core mailing list
Tcl-...@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tcl-core