Order symtable, sym-dep, fragments

This ordering will simplify streaming processing of xmlo files in
TAMER.  Specifically, we know that symbols will have been declared by the
time dependencies are added to the graph (and so we should only be creating
edges to existing nodes); and we can halt reading as soon as the closing
fragments tag is encountered, avoiding parsing the entirety of these massive
XML files.

On one particularly large program, this cuts time down from ~0.333s to
~0.300 in the POC linker.
master
Mike Gerwitz 2020-01-02 23:29:49 -05:00
parent 1f4db84f24
commit ff0c8bb34f
5 changed files with 66 additions and 17 deletions

View File

@ -1,4 +1,4 @@
# This number is incremented for every compiler change to force rebuilding
# of xmlo files.
0
1

View File

@ -31,21 +31,42 @@
<template mode="preproc:compile-fragments" priority="9"
match="lv:package">
<copy>
<sequence select="@*" />
<apply-templates select="*" mode="preproc:compile-fragments-root" />
</copy>
</template>
<template mode="preproc:compile-fragments-root" priority="1"
match="node()">
<sequence select="." />
</template>
<!-- Position fragments directly after dependencies. This allows TAMER to
halt processing early on, rather than having to read the rest of the
file (fragments used to be placed at the end). -->
<template mode="preproc:compile-fragments-root" priority="5"
match="preproc:sym-deps">
<sequence select="." />
<variable name="package" as="element( lv:package )"
select="parent::lv:package" />
<variable name="symtable-map" as="map( xs:string, element( preproc:sym ) )"
select="map:merge(
for $sym in preproc:symtable/preproc:sym
for $sym in $package/preproc:symtable/preproc:sym
return map{ string( $sym/@name ) : $sym } )" />
<copy>
<sequence select="@*, *" />
<preproc:fragments>
<apply-templates mode="preproc:compile-fragments">
<with-param name="symtable-map" select="$symtable-map"
tunnel="yes" />
</apply-templates>
</preproc:fragments>
</copy>
<preproc:fragments>
<apply-templates select="$package/*"
mode="preproc:compile-fragments">
<with-param name="symtable-map" select="$symtable-map"
tunnel="yes" />
</apply-templates>
</preproc:fragments>
</template>

View File

@ -123,7 +123,8 @@
<!-- final result with compiled fragments -->
<lv:package>
<sequence select="$pkg-with-symtable/@*,
$pkg-with-symtable/node()" />
$pkg-with-symtable/preproc:sym-deps/preceding-sibling::*,
$pkg-with-symtable/preproc:sym-deps" />
<preproc:fragments>
<!-- special fragment to be output as the head -->
@ -148,6 +149,8 @@
<text>};</text>
</preproc:fragment>
</preproc:fragments>
<sequence select="$pkg-with-symtable/preproc:sym-deps/following-sibling::*" />
</lv:package>
</template>
@ -197,7 +200,8 @@
<!-- final result with compiled fragments -->
<lv:package>
<sequence select="$pkg-with-symtable/@*,
$pkg-with-symtable/node()" />
$pkg-with-symtable/preproc:sym-deps/preceding-sibling::*,
$pkg-with-symtable/preproc:sym-deps" />
<preproc:fragments>
<!-- special fragment to be output as the head -->
@ -222,6 +226,8 @@
<text>};</text>
</preproc:fragment>
</preproc:fragments>
<sequence select="$pkg-with-symtable/preproc:sym-deps/following-sibling::*" />
</lv:package>
</template>

View File

@ -66,13 +66,27 @@
<text>[depgen] *determining symbol dependencies...</text>
</message>
<apply-templates select="preproc:symtable" mode="preproc:depgen" />
<sequence select="*" />
<apply-templates select="*" mode="preproc:depgen-root" />
</copy>
</template>
<template mode="preproc:depgen-root" priority="1"
match="node()">
<sequence select="." />
</template>
<template mode="preproc:depgen-root" priority="5"
match="preproc:symtable">
<!-- Place symbol table _before_ dependencies. This simplifies
streaming processing in TAMER. -->
<sequence select="." />
<apply-templates select="." mode="preproc:depgen" />
</template>
<template match="preproc:symtable" mode="preproc:depgen" priority="9">
<variable name="symtable" select="." />

View File

@ -314,6 +314,14 @@ fn load_xmlo<'a>(
_ => Ok(()),
}
}
Ok(Event::End(ele)) => {
match ele.name() {
// We don't need to read any further than the end of
// the fragments (symtable, sym-deps, fragments)
b"preproc:fragments" => break (),
_ => Ok(()),
}
}
Ok(Event::Eof) => break (),
Err(e) => {
panic!("Error at {}: {:?}", reader.buffer_position(), e);