Do not execute unnecessary code paths

Benchmarking showed virtually no benefit, surprisingly.  But this can be
used in conjunction with other optimizations in the future.
master
Mike Gerwitz 2020-04-17 11:11:28 -04:00
parent 9c63337fc6
commit 74f2849e8b
2 changed files with 75 additions and 41 deletions

View File

@ -139,6 +139,60 @@
</template>
<template mode="js-name-ref" priority="5"
match="c:sum[@of]|c:product[@of]">
<variable name="of" select="@of" />
<variable name="func" select="ancestor::lv:function" />
<!-- XXX: this needs to use compile-calc-value, but can't right now
beacuse it's not a c:value-of! -->
<choose>
<!-- is @of a function param? -->
<when test="
$func
and root(.)/preproc:symtable/preproc:sym[
@type='lparam'
and @name=concat( ':', $func/@name, ':', $of )
]
">
<value-of select="@of" />
</when>
<!-- let expression -->
<when test="$of = ancestor::c:let/c:values/c:value/@name">
<value-of select="$of" />
</when>
<!-- maybe a constant? -->
<when test="
root(.)/preproc:symtable/preproc:sym[
@type='const'
and @name=$of
]
">
<text>consts['</text>
<value-of select="@of" />
<text>']</text>
</when>
<otherwise>
<text>args['</text>
<value-of select="@of" />
<text>']</text>
</otherwise>
</choose>
</template>
<template mode="js-name-ref" priority="1"
match="*">
<message select="'internal error: invalid js-name-ref src'"
terminate="yes" />
</template>
<!--
Generates code for the sum or product of a set
@ -199,50 +253,11 @@
<!-- will store result of the summation/product -->
<text>var sum = 0;</text>
<variable name="of" select="@of" />
<variable name="func" select="ancestor::lv:function" />
<!-- XXX: this needs to use compile-calc-value, but can't right now
beacuse it's not a c:value-of! -->
<variable name="value">
<choose>
<!-- is @of a function param? -->
<when test="
$func
and root(.)/preproc:symtable/preproc:sym[
@type='lparam'
and @name=concat( ':', $func/@name, ':', $of )
]
">
<value-of select="@of" />
</when>
<!-- let expression -->
<when test="$of = ancestor::c:let/c:values/c:value/@name">
<value-of select="$of" />
</when>
<!-- maybe a constant? -->
<when test="
root(.)/preproc:symtable/preproc:sym[
@type='const'
and @name=$of
]
">
<text>consts['</text>
<value-of select="@of" />
<text>']</text>
</when>
<otherwise>
<text>args['</text>
<value-of select="@of" />
<text>']</text>
</otherwise>
</choose>
<apply-templates mode="js-name-ref"
select="." />
</variable>
<!-- if we're looking to generate a set, initialize it -->

View File

@ -1131,6 +1131,25 @@
<apply-templates select="." mode="compile-cmatch" />
<text>;</text>
<!-- preempt expensive logic, but still return a vector of the proper
length -->
<!-- TODO: when writing TAMER, note that this must be improved upon: it
only detects iterators of immedite children -->
<text>if (!predmatch) {</text>
<for-each select="c:sum[@generates]|c:product[@generates]">
<variable name="value">
<apply-templates mode="js-name-ref"
select="." />
</variable>
<text>args['</text>
<value-of select="@generates" />
<text>']=(new Array(</text>
<value-of select="$value" />
<text>.length)).fill(0);</text>
</for-each>
<text>return 0;}</text>
<!-- return the result of the calculation for this rate block -->
<text>return (+( </text>
<!-- yield 0 if there are no calculations (rather than a syntax error!) -->