As many of you already know, I have been working on a replacement for
Mesa's current GLSL compiler infrastructure since July.  I presented
my plans for this work at XDS in September
(http://web.cecs.pdx.edu/~idr/publications/xds2008-GLSL_work.pdf).
Today I am making the work generally available for review and for
patches.  The compiler is not "done" by any stretch of the
imagination.  However, I have been working on it in isolation for much 
too long, and it's high time to get some review and oversight from the
community.

The front-end parser is complete.  It has been implemented using flex
and bison.  Several features specific to those tools have been used,
so the compiler does actually require them.  Flex and bison implement
some extensions for generating re-entrant lexers and parsers.  It is
probably possible to port to other lex and yacc implementations, but
I'm not terribly interested in do it.  Patches welcome.

The mid-level IR (MIR) has been defined, and numerous transformations
have been implemented.  The program is simplified to 3-address
statements.  In each statement operands must be "simple."  That is, each
operands must be a constant, an variable reference, or an array
reference with either a constant index or a variable reference index.
Function calls and control-flow statements are also handled.  In MIR,
high-level constructs like loops and if-statements are directly
implemented.  Goto-statements are implemented, but they are only used
to replace return-statements when a function is copied in-line.

The fairly recent addition to the design is the low-level IR (LIR).
This is a tree representation of the MIR.  The most common way for a
compiler to generate machine code is to use dynamic programming
perform a least-cost rewrite of a tree.  The conversion for MIR to LIR
introduces target-architecture dependencies.  High-level constructs
like loops and if-statements are replaced with lower-level,
architecture dependent constructs.

The particular dynamic programming system that is being used is lburg.
This is the code-generator generator used by LCC (L-burg C Compiler).
I had to make a couple small patches to lburg.  The code generated by
lburg accidentally introduced some LCC dependencies.  At some point
lburg will need to be replaced.  It's a reasonable tool, but it's not
a perfect fit.  It carries LCC's weird license, so I'm not sure that
just modifying it to suit Mesa's needs is a viable option.  It's only
942 lines of code, so re-writing it will not be an arduous task.  A
portion of that work has already been done.

There is a substantial list of things that remain to be done.  Some of
these need to be done before importing the stand-alone compiler into
the Mesa tree.  Some of it can wait until after this integration.

The biggest thing that needs doing, and my next work item, is to
finish the machine description for the code-generator.  Right now only
a small portion of the source LIR is supported.  Among other things,
if-statements are not yet supported.

In addition, loop constructs are not supported from the front-end.
Right now the parser just ignores all of the loop constructs.  This was
intentional.  I wanted to see how if-statements would be implemented,
top to bottom, before deciding exactly how to implement loops.  Many
of the implementation details of structures and arrays have been
similarly delayed.

After the machine description is complete, a proper register
allocator will be needed.  In its current incarnation, the compiler
generates temporaries without bounds.  It assumes that there are
enough registers to go around.  Clearly, this is not a safe
assumption.  Mesa's current compiler also operates this way.  A proper
register allocator will help things a lot.

The conversion from MIR to LIR treats each MIR statement entirely
independently.  The LIR is a tree representation.  Input values form
the leaves, and connections of outputs to inputs form the branches.
However, none of these connections are made.  As a result, the
generated code is not very good.  In fact, it can't even generate a
dot-product instruction.  Performing additional passes over the LIR to
make these connections should be straightforward.  I honestly think
this can wait.  To me, it is much more important to get all of the
parts complete and generating correct code than it is to generate good
code for a subset.

Right now the compiler only has a skeletal linker.  The infrastructure
is mostly in place to combine multiple shaders of the same type (i.e.,
link multiple vertex shader compilation units together).  It just
needs to be finished.  The linker also needs to perform cross-shader
validation.  That is, it needs to make sure that vertex shader outputs
match fragment shader inputs.  It needs to make sure that uniforms are
consistently declared across shaders.  Etc.  Once shaders are properly
linked, uniforms need to be placed.

The last major missing piece is the GLSL preprocessor.  When I was
talking to Michal Krol at XDS he pointed out that Nvidia released an
open-source GLSL preprocessor.  I haven't investigated it very deeply,
but I expect we could just use that for the time being.  The only copy
of the code I could find was in the sample front-end that 3Dlabs
released back in 2005 (http://mew.cx/glsl/OpenGLCompilerSept202005.zip).

In addition to those major elements, there are a number of minor
elements that need to either be written or re-written.  As far as I
can tell, none of these items require any knowledge of Mesa.  Most of
them don't even require any compiler expertise.

The symbol table currently used is utter rubbish.  There are two main
problems with it.  The biggest problem is that it allocates elements
in a large block.  When more elements are needed, it attempts to
realloc the block.  The symbol table routines return pointers to the
elements, so having the elements change memory locations is just plain
borken.  I'm really not sure what I was thinking when I wrote.  The
other problem is that there is no search acceleration method
implemented.  It needs a hash table or something!

Error logging is also a bit sketchy.  Ideally we'd want to be able to
generate warnings and errors from various stages of the compiler in
arbitrary order.  When the application queries the shader log, all of
the entries would be sorted by source file and line number.  Pretty
headers like "In function foo:" would be added at appropriate places.
I have some ideas for how this could be implemented.

Running valgrind shows pretty quickly that memory management hasn't
been a high prioritie thus far.  It leaks like a sieve.  Some
types of objects are fairly short lived.  Some types of objects are
long lived and are referenced from multiple structures.  The short
lived objects need to be identified.  Some of these objects should be
tracked with a pool-based suballocator.  When the objects are no
longer needed, the entire pool should be destroyed or flushed.  The
remaining short lived objects should be destroyed as needed.  The
longer lived objects need to be reference counted and destroyed
appropriately.

The existing Mesa compiler tokenizes the shading language built-ins
during the build process.  The tokenized form is compiled at run-time.
On of the design goals of the new compiler was to compile the shading
language built-ins to the MIR representation during the build process.
This requires some sort of out-of-core representation of the MIR.  The
compiler needs to be able to save and load MIR data.  An appropriate
representation should be difficult to develop and implement, but it
has not be done yet.  As an added bonus, such a representation would
provide an easy implementation of GL_OES_get_program_binary.

Software links:

 - ftp://ftp.cs.princeton.edu/pub/packages/lcc/lcc-4.2.tar.gz - LCC
   4.2.  This contains lburg. 

 - 
http://people.freedesktop.org/~idr/patches/0001-Use-OP_LABEL-and-STATE_LABEL-accessor-macros.patch
   lburg patch that fixes dependency on generated code to LCC.

 - My source code repository:

       git clone http://people.freedesktop.org/~idr/glsl.git glsl

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Mesa3d-dev mailing list
Mesa3d-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mesa3d-dev

Reply via email to