Inline intermediate any/all classifications
This is another significant milestone. The next logical step with classification optimization is to inline all of those intermediate classifications generated from any and all blocks, since there are so many of them. This means having the parent classification absorb all dependencies; not output dependencies for the classification; not compile the assignments for those classifications; and to inline them at the match site. They’re used only once, since they’re generated for each individual block. We need to keep the actual classification generation around (and just inline them) for now, probably until TAMER, because we depend upon their symbol for determining their dimensionality, which we need for the optimization work we just did---we must inline them into the proper group (matrix, vector, or scalar). The optimization work done up to this point had inlining in mind---only a little bit of work was needed to make sure that every classification can simply be stripped of its assignment and be a valid expression that can be inlined in place of the original reference. The result of that was predictably significant for the `ui/package` program that I've been testing with: - 4,514 classifications were inlined; - The file size dropped to 7.5MiB (from 8.2MiB previously---remember that we started at 16MiB); and - GC ticks were cut in half, from 67->31. Unfortunately, this optimization added nearly 1m of time to the compilation of that program. Speaking from the future: the UI build optimizations in liza-proguic were introduced to offset this difference (and provide a net gain in performance).master
parent
97caefab1b
commit
7dbb653624
|
@ -539,7 +539,8 @@
|
|||
-->
|
||||
<template mode="compile" priority="7"
|
||||
match="lv:classify[ count( lv:match ) = 1
|
||||
and lv:match/@value='TRUE' ]">
|
||||
and lv:match/@value='TRUE'
|
||||
and not( lv:match/@preproc:inline ) ]">
|
||||
<param name="symtable-map" as="map(*)" tunnel="yes" />
|
||||
|
||||
<variable name="src" as="xs:string"
|
||||
|
@ -631,7 +632,13 @@
|
|||
<template match="lv:classify" mode="compile" priority="5">
|
||||
<param name="symtable-map" as="map(*)" tunnel="yes" />
|
||||
|
||||
<sequence select="compiler:compile-classify( $symtable-map, . )" />
|
||||
<sequence select="compiler:compile-classify-assign( $symtable-map, . )" />
|
||||
</template>
|
||||
|
||||
|
||||
<template mode="compile" priority="8"
|
||||
match="lv:classify[ @preproc:inline='true' ]">
|
||||
<!-- emit nothing; it'll be inlined at the match site -->
|
||||
</template>
|
||||
|
||||
|
||||
|
@ -672,21 +679,44 @@
|
|||
$outer, ',', $inner, ')' )" />
|
||||
</function>
|
||||
|
||||
|
||||
<function name="compiler:compile-classify-assign" as="xs:string">
|
||||
<param name="symtable-map" as="map(*)" />
|
||||
<param name="classify" as="element( lv:classify )" />
|
||||
|
||||
<sequence select="string-join(
|
||||
( $compiler:nl,
|
||||
compiler:compile-classify(
|
||||
$symtable-map, $classify ) ) )" />
|
||||
</function>
|
||||
|
||||
|
||||
<function name="compiler:compile-classify-inline" as="xs:string">
|
||||
<param name="symtable-map" as="map(*)" />
|
||||
<param name="classify" as="element( lv:classify )" />
|
||||
|
||||
<!-- keep only the JS expression, grouping to ensure that surrounding
|
||||
expressions (scalars, specifically, that lack grouping) maintain
|
||||
their precedence -->
|
||||
<sequence select="concat(
|
||||
'(',
|
||||
compiler:compile-classify(
|
||||
$symtable-map, $classify )[ 2 ],
|
||||
')' )" />
|
||||
</function>
|
||||
|
||||
<!--
|
||||
Generate code to perform a classification
|
||||
|
||||
Based on the criteria provided by the classification, generate and store the
|
||||
result of a boolean expression performing the classification using global
|
||||
arguments.
|
||||
|
||||
@return generated classification expression
|
||||
This return a sequence of (assignment prefix, compiled js, assignment
|
||||
suffix); the caller should keep the assignment prefix and suffix for
|
||||
normal compilation, but should keep only the JS portion (which is a
|
||||
standalone expression) for inlining.
|
||||
-->
|
||||
<function name="compiler:compile-classify" as="xs:string+">
|
||||
<param name="symtable-map" as="map(*)" />
|
||||
<param name="classify" as="element( lv:classify )" />
|
||||
|
||||
<value-of select="$compiler:nl" />
|
||||
|
||||
<variable name="dest" as="xs:string"
|
||||
select="compiler:class-yields-var( $classify )" />
|
||||
|
||||
|
@ -769,8 +799,12 @@
|
|||
$js-vec,
|
||||
$js-matrix ) )" />
|
||||
|
||||
<!-- sequence of (assignment prefix, js, assignment suffix); it's up to
|
||||
the caller to determine which of these to keep -->
|
||||
<sequence select="concat( $var, '=', $reduce,
|
||||
'(', $yield-to, '=', $js, ');' )" />
|
||||
'(', $yield-to, '=' ),
|
||||
$js,
|
||||
');'" />
|
||||
</function>
|
||||
|
||||
|
||||
|
@ -1122,14 +1156,32 @@
|
|||
<param name="symtable-map" as="map(*)" />
|
||||
<param name="match" as="element( lv:match )" />
|
||||
|
||||
<variable name="sym" as="element( preproc:sym )"
|
||||
select="$symtable-map( $match/@on )" />
|
||||
<choose>
|
||||
<when test="$match/@preproc:inline='true'">
|
||||
<variable name="classify" as="element( lv:classify )?"
|
||||
select="( $match/parent::lv:classify
|
||||
/preceding-sibling::lv:classify[ @yields=$match/@on ] )[1]" />
|
||||
|
||||
<if test="empty( $classify )">
|
||||
<message terminate="yes"
|
||||
select="concat( 'internal error: inline: ',
|
||||
'cannot locate class `', $match/@on, '''' )" />
|
||||
</if>
|
||||
|
||||
<variable name="var" as="xs:string"
|
||||
select="if ( $sym/@type = 'const' ) then 'C' else 'A'" />
|
||||
<sequence select="compiler:compile-classify-inline(
|
||||
$symtable-map, $classify )" />
|
||||
</when>
|
||||
|
||||
<sequence select="concat( $var, '[''', $match/@on, ''']' )" />
|
||||
<otherwise>
|
||||
<variable name="sym" as="element( preproc:sym )"
|
||||
select="$symtable-map( $match/@on )" />
|
||||
|
||||
<variable name="var" as="xs:string"
|
||||
select="if ( $sym/@type = 'const' ) then 'C' else 'A'" />
|
||||
|
||||
<sequence select="concat( $var, '[''', $match/@on, ''']' )" />
|
||||
</otherwise>
|
||||
</choose>
|
||||
</function>
|
||||
|
||||
|
||||
|
|
|
@ -312,6 +312,10 @@
|
|||
<next-match />
|
||||
</template>
|
||||
|
||||
<template mode="preproc:depgen" priority="9"
|
||||
match="lv:classify[ preproc:inline='true' ]">
|
||||
<!-- ignore; dependencies will be inlined -->
|
||||
</template>
|
||||
|
||||
<template mode="preproc:depgen" priority="7"
|
||||
match="lv:classify">
|
||||
|
@ -460,6 +464,29 @@
|
|||
</template>
|
||||
|
||||
|
||||
<!--
|
||||
Inlined matches will not be counted as dependencies themselves, but their
|
||||
dependencies are our own
|
||||
-->
|
||||
<template match="lv:match[ @preproc:inline='true' ]"
|
||||
mode="preproc:depgen" priority="7">
|
||||
<variable name="self" as="element( lv:match )" select="." />
|
||||
|
||||
<variable name="classify" as="element( lv:classify )?"
|
||||
select="( parent::lv:classify
|
||||
/preceding-sibling::lv:classify[ @yields=$self/@on ] )[1]" />
|
||||
|
||||
<if test="empty( $classify )">
|
||||
<message terminate="yes"
|
||||
select="concat( 'internal error: inline depgen: ',
|
||||
'cannot locate class `', @on, '''' )" />
|
||||
</if>
|
||||
|
||||
<apply-templates mode="preproc:depgen"
|
||||
select="$classify/element()" />
|
||||
</template>
|
||||
|
||||
|
||||
<template match="lv:match[ @value ]" mode="preproc:depgen" priority="5">
|
||||
<!-- process the @value -->
|
||||
<call-template name="preproc:depgen-c-normal">
|
||||
|
|
|
@ -422,6 +422,7 @@
|
|||
<lv:classify as="{$id}" yields="{$yields}"
|
||||
preproc:generated="true"
|
||||
preproc:generated-from="{$parent-name}"
|
||||
preproc:inline="true"
|
||||
desc="(generated from predicate group of {$parent-name}">
|
||||
<if test="local-name() = 'any'">
|
||||
<attribute name="any" select="'true'" />
|
||||
|
@ -431,7 +432,9 @@
|
|||
</lv:classify>
|
||||
|
||||
<!-- this will remain in its place -->
|
||||
<lv:match on="{$yields}" value="TRUE" preproc:generated="true" />
|
||||
<lv:match on="{$yields}" value="TRUE"
|
||||
preproc:generated="true"
|
||||
preproc:inline="true" />
|
||||
</template>
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue