BrookGPU: BRCC Architecture

Getting Started
    BRT C++
Current Issues

BRCC is a source to source compiler that takes in Brook (.br) files and produces C++ files that can then be fed through a standard C++ compiler.


BRCC runs in three distinct stages. First, it parses the input file into a TransUnit. Then, it runs a few passes over the TransUnit identifying Brook specific pieces and converting them into BRT (Brook Run-Time) specialized types. Finally, it traverses the TransUnit printing each node. The untransformed units reproduce their original contents and the BRT units emit C++ code to execute the Brook operations / call into the BRT for the run-time determined portions. Note that a number of operations (e.g. compiling Cg/HLSL to fragment assembly) are deferred until the print phase since they are really only needed for emitting the code, not representing it.

BRCC Organization

BRCC is built upon an open source project named cTool ( cTool is a C++ program that takes C as its input and builds a TransUnit that reflects its parsed form. It also knows how to traverse the parsed content and print it out again. The key files from cTool are:
gram.y The bison grammar for the parser. It's fairly sophisticated (cTool recognizes pretty much all of C and a number of gcc extensions).
decl.{cpp, h} Class definitions, enums, and implementations for all of the objects that represent C declarations in the parse tree. E.g. StructDef, BaseType, etc.
express.{cpp, h} Class definitions and implementations for all of the objects that represent C expressions in the parse tree. E.g. BinaryExpr, FunctionCall, etc.
stemnt.{cpp, h} Class definitions and implementations for all of the objects that represent C statements (or collections of statements) in the parse tree. E.g. FunctionDef, Block, IfStemnt, etc.

There are a number of other files from cTool that are part of the support, but those above are the heart of parsing and representing C (and Brook). The cTool files can all be recognized by their copyright at the top.

The second major class of files are those reflecting the various BRT* classes. After parsing using the cTool files, BRCC traverses the tree and converts objects representing special Brook constructs into Brook-specialized objects. The key files here are:
brtdecl.{cpp, h} A specialization of decl.{cpp, h} that is used for the BRTStream type (declarations of streams outside of kernel functions).
brtexpress.{cpp, h} A specialization of express.{cpp, h} that is used for the BRTStreamInitializer type (initializer expressions given at stream declaration time).
brtstemnt.{cpp, h} A specialization of stemnt.{cpp, h} that is used for BRTKernelDef and its subclasses (one for CPU hosted kernels and one for GPU). BRCC converts FunctionDefs that represent kernels into one of these types.

The third major class of files are files that provide helper functionality to the brt* files. Their separation from the brt* files is largely an artifact of history / their development and they should be folded into the appropriate brt* files over time: codegen.{cpp, h} - Takes a kernel's prototype and body and produces prototypes and a wrapper function to invoke the kernel from C and runs the kernel contents through a Cg/HLSL compiler, annotates the output, and provides it as a const char * in the output file. brook2cpp.{cpp, h} - For CPU hosted kernels, brook2cpp converts the Cg/HLSL contents of the kernel into corresponding C++.

What Changes Go Where

Thus far, all of the changes that happen at parse time (e.g. handling floatN constructors, recognizing <>, 'kernel', etc.) have happened within the cTool files themselves. Clearly for changes to the grammar, this is unavoidable, but BRCC has also followed cTool's trend of putting all the decls in decl.*, all the expressions in express.*, etc. so the parse time representation of a stream is handled in decl.*, floatN constructors are in express.*, etc.

All the changes connected to supporting the second phase and then printing of BRT types have gone in files named brt-. BRT expressions are in brtexpress.*, etc. This has been sufficient so far, but certain functionality (e.g. BRTCPUKernelDef) might grow enough in complexity to deserve its own file. In those cases, new files that contain BRT types should (logically enough) still have a brt- prefix in their names.

There are a few other stray files such as main.* and subprocess.*. They offer generic functionality not associated with any cTool classes or BRT classes and creating new helper files to stash general functionality helps reduce the clutter in cTool / BRT files and encapsulate functionality.

(Appendix) Differences from C:

  • <> notation for declaring and denoting streams
  • kernel, reduce, iter, indexof keyword
  • kernel bodies only support as much of C/C++ as Cg / HLSL supports
  • float2, float3, float4 available as types Logo The fly fishing flies featured on this web site can be purchased at The English Fly Fishing Shop