1*61046927SAndroid Build Coastguard WorkerWelcome to Mesa's GLSL compiler. A brief overview of how things flow: 2*61046927SAndroid Build Coastguard Worker 3*61046927SAndroid Build Coastguard Worker1) lex and yacc-based preprocessor takes the incoming shader string 4*61046927SAndroid Build Coastguard Workerand produces a new string containing the preprocessed shader. This 5*61046927SAndroid Build Coastguard Workertakes care of things like #if, #ifdef, #define, and preprocessor macro 6*61046927SAndroid Build Coastguard Workerinvocations. Note that #version, #extension, and some others are 7*61046927SAndroid Build Coastguard Workerpassed straight through. See glcpp/* 8*61046927SAndroid Build Coastguard Worker 9*61046927SAndroid Build Coastguard Worker2) lex and yacc-based parser takes the preprocessed string and 10*61046927SAndroid Build Coastguard Workergenerates the AST (abstract syntax tree). Almost no checking is 11*61046927SAndroid Build Coastguard Workerperformed in this stage. See glsl_lexer.ll and glsl_parser.yy. 12*61046927SAndroid Build Coastguard Worker 13*61046927SAndroid Build Coastguard Worker3) The AST is converted to "HIR". This is the intermediate 14*61046927SAndroid Build Coastguard Workerrepresentation of the compiler. Constructors are generated, function 15*61046927SAndroid Build Coastguard Workercalls are resolved to particular function signatures, and all the 16*61046927SAndroid Build Coastguard Workersemantic checking is performed. See ast_*.cpp for the conversion, and 17*61046927SAndroid Build Coastguard Workerir.h for the IR structures. 18*61046927SAndroid Build Coastguard Worker 19*61046927SAndroid Build Coastguard Worker4) The driver (Mesa, or main.cpp for the standalone binary) performs 20*61046927SAndroid Build Coastguard Workeroptimizations. These include copy propagation, dead code elimination, 21*61046927SAndroid Build Coastguard Workerconstant folding, and others. Generally the driver will call 22*61046927SAndroid Build Coastguard Workeroptimizations in a loop, as each may open up opportunities for other 23*61046927SAndroid Build Coastguard Workeroptimizations to do additional work. See most files called ir_*.cpp 24*61046927SAndroid Build Coastguard Worker 25*61046927SAndroid Build Coastguard Worker5) linking is performed. This does checking to ensure that the 26*61046927SAndroid Build Coastguard Workeroutputs of the vertex shader match the inputs of the fragment shader, 27*61046927SAndroid Build Coastguard Workerand assigns locations to uniforms, attributes, and varyings. See 28*61046927SAndroid Build Coastguard Workerlinker.cpp. 29*61046927SAndroid Build Coastguard Worker 30*61046927SAndroid Build Coastguard Worker6) The driver may perform additional optimization at this point, as 31*61046927SAndroid Build Coastguard Workerfor example dead code elimination previously couldn't remove functions 32*61046927SAndroid Build Coastguard Workeror global variable usage when we didn't know what other code would be 33*61046927SAndroid Build Coastguard Workerlinked in. 34*61046927SAndroid Build Coastguard Worker 35*61046927SAndroid Build Coastguard Worker7) The driver performs code generation out of the IR, taking a linked 36*61046927SAndroid Build Coastguard Workershader program and producing a compiled program for each stage. See 37*61046927SAndroid Build Coastguard Worker../mesa/program/ir_to_mesa.cpp for Mesa IR code generation. 38*61046927SAndroid Build Coastguard Worker 39*61046927SAndroid Build Coastguard WorkerFAQ: 40*61046927SAndroid Build Coastguard Worker 41*61046927SAndroid Build Coastguard WorkerQ: What is HIR versus IR versus LIR? 42*61046927SAndroid Build Coastguard Worker 43*61046927SAndroid Build Coastguard WorkerA: The idea behind the naming was that ast_to_hir would produce a 44*61046927SAndroid Build Coastguard Workerhigh-level IR ("HIR"), with things like matrix operations, structure 45*61046927SAndroid Build Coastguard Workerassignments, etc., present. A series of lowering passes would occur 46*61046927SAndroid Build Coastguard Workerthat do things like break matrix multiplication into a series of dot 47*61046927SAndroid Build Coastguard Workerproducts/MADs, make structure assignment be a series of assignment of 48*61046927SAndroid Build Coastguard Workercomponents, flatten if statements into conditional moves, and such, 49*61046927SAndroid Build Coastguard Workerproducing a low level IR ("LIR"). 50*61046927SAndroid Build Coastguard Worker 51*61046927SAndroid Build Coastguard WorkerHowever, it now appears that each driver will have different 52*61046927SAndroid Build Coastguard Workerrequirements from a LIR. A 915-generation chipset wants all functions 53*61046927SAndroid Build Coastguard Workerinlined, all loops unrolled, all ifs flattened, no variable array 54*61046927SAndroid Build Coastguard Workeraccesses, and matrix multiplication broken down. The Mesa IR backend 55*61046927SAndroid Build Coastguard Workerfor swrast would like matrices and structure assignment broken down, 56*61046927SAndroid Build Coastguard Workerbut it can support function calls and dynamic branching. A 965 vertex 57*61046927SAndroid Build Coastguard Workershader IR backend could potentially even handle some matrix operations 58*61046927SAndroid Build Coastguard Workerwithout breaking them down, but the 965 fragment shader IR backend 59*61046927SAndroid Build Coastguard Workerwould want to break to have (almost) all operations down channel-wise 60*61046927SAndroid Build Coastguard Workerand perform optimization on that. As a result, there's no single 61*61046927SAndroid Build Coastguard Workerlow-level IR that will make everyone happy. So that usage has fallen 62*61046927SAndroid Build Coastguard Workerout of favor, and each driver will perform a series of lowering passes 63*61046927SAndroid Build Coastguard Workerto take the HIR down to whatever restrictions it wants to impose 64*61046927SAndroid Build Coastguard Workerbefore doing codegen. 65*61046927SAndroid Build Coastguard Worker 66*61046927SAndroid Build Coastguard WorkerQ: How is the IR structured? 67*61046927SAndroid Build Coastguard Worker 68*61046927SAndroid Build Coastguard WorkerA: The best way to get started seeing it would be to run the 69*61046927SAndroid Build Coastguard Workerstandalone compiler against a shader: 70*61046927SAndroid Build Coastguard Worker 71*61046927SAndroid Build Coastguard Worker./glsl_compiler --dump-lir \ 72*61046927SAndroid Build Coastguard Worker ~/src/piglit/tests/shaders/glsl-orangebook-ch06-bump.frag 73*61046927SAndroid Build Coastguard Worker 74*61046927SAndroid Build Coastguard WorkerSo for example one of the ir_instructions in main() contains: 75*61046927SAndroid Build Coastguard Worker 76*61046927SAndroid Build Coastguard Worker(assign (constant bool (1)) (var_ref litColor) (expression vec3 * (var_ref Surf 77*61046927SAndroid Build Coastguard WorkeraceColor) (var_ref __retval) ) ) 78*61046927SAndroid Build Coastguard Worker 79*61046927SAndroid Build Coastguard WorkerOr more visually: 80*61046927SAndroid Build Coastguard Worker (assign) 81*61046927SAndroid Build Coastguard Worker / | \ 82*61046927SAndroid Build Coastguard Worker (var_ref) (expression *) (constant bool 1) 83*61046927SAndroid Build Coastguard Worker / / \ 84*61046927SAndroid Build Coastguard Worker(litColor) (var_ref) (var_ref) 85*61046927SAndroid Build Coastguard Worker / \ 86*61046927SAndroid Build Coastguard Worker (SurfaceColor) (__retval) 87*61046927SAndroid Build Coastguard Worker 88*61046927SAndroid Build Coastguard Workerwhich came from: 89*61046927SAndroid Build Coastguard Worker 90*61046927SAndroid Build Coastguard WorkerlitColor = SurfaceColor * max(dot(normDelta, LightDir), 0.0); 91*61046927SAndroid Build Coastguard Worker 92*61046927SAndroid Build Coastguard Worker(the max call is not represented in this expression tree, as it was a 93*61046927SAndroid Build Coastguard Workerfunction call that got inlined but not brought into this expression 94*61046927SAndroid Build Coastguard Workertree) 95*61046927SAndroid Build Coastguard Worker 96*61046927SAndroid Build Coastguard WorkerEach of those nodes is a subclass of ir_instruction. A particular 97*61046927SAndroid Build Coastguard Workerir_instruction instance may only appear once in the whole IR tree with 98*61046927SAndroid Build Coastguard Workerthe exception of ir_variables, which appear once as variable 99*61046927SAndroid Build Coastguard Workerdeclarations: 100*61046927SAndroid Build Coastguard Worker 101*61046927SAndroid Build Coastguard Worker(declare () vec3 normDelta) 102*61046927SAndroid Build Coastguard Worker 103*61046927SAndroid Build Coastguard Workerand multiple times as the targets of variable dereferences: 104*61046927SAndroid Build Coastguard Worker... 105*61046927SAndroid Build Coastguard Worker(assign (constant bool (1)) (var_ref __retval) (expression float dot 106*61046927SAndroid Build Coastguard Worker (var_ref normDelta) (var_ref LightDir) ) ) 107*61046927SAndroid Build Coastguard Worker... 108*61046927SAndroid Build Coastguard Worker(assign (constant bool (1)) (var_ref __retval) (expression vec3 - 109*61046927SAndroid Build Coastguard Worker (var_ref LightDir) (expression vec3 * (constant float (2.000000)) 110*61046927SAndroid Build Coastguard Worker (expression vec3 * (expression float dot (var_ref normDelta) (var_ref 111*61046927SAndroid Build Coastguard Worker LightDir) ) (var_ref normDelta) ) ) ) ) 112*61046927SAndroid Build Coastguard Worker... 113*61046927SAndroid Build Coastguard Worker 114*61046927SAndroid Build Coastguard WorkerEach node has a type. Expressions may involve several different types: 115*61046927SAndroid Build Coastguard Worker(declare (uniform ) mat4 gl_ModelViewMatrix) 116*61046927SAndroid Build Coastguard Worker((assign (constant bool (1)) (var_ref constructor_tmp) (expression 117*61046927SAndroid Build Coastguard Worker vec4 * (var_ref gl_ModelViewMatrix) (var_ref gl_Vertex) ) ) 118*61046927SAndroid Build Coastguard Worker 119*61046927SAndroid Build Coastguard WorkerAn expression tree can be arbitrarily deep, and the compiler tries to 120*61046927SAndroid Build Coastguard Workerkeep them structured like that so that things like algebraic 121*61046927SAndroid Build Coastguard Workeroptimizations ((color * 1.0 == color) and ((mat1 * mat2) * vec == mat1 122*61046927SAndroid Build Coastguard Worker* (mat2 * vec))) or recognizing operation patterns for code generation 123*61046927SAndroid Build Coastguard Worker(vec1 * vec2 + vec3 == mad(vec1, vec2, vec3)) are easier. This comes 124*61046927SAndroid Build Coastguard Workerat the expense of additional trickery in implementing some 125*61046927SAndroid Build Coastguard Workeroptimizations like CSE where one must navigate an expression tree. 126*61046927SAndroid Build Coastguard Worker 127*61046927SAndroid Build Coastguard WorkerQ: Why no SSA representation? 128*61046927SAndroid Build Coastguard Worker 129*61046927SAndroid Build Coastguard WorkerA: Converting an IR tree to SSA form makes dead code elimination, 130*61046927SAndroid Build Coastguard Workercommon subexpression elimination, and many other optimizations much 131*61046927SAndroid Build Coastguard Workereasier. However, in our primarily vector-based language, there's some 132*61046927SAndroid Build Coastguard Workermajor questions as to how it would work. Do we do SSA on the scalar 133*61046927SAndroid Build Coastguard Workeror vector level? If we do it at the vector level, we're going to end 134*61046927SAndroid Build Coastguard Workerup with many different versions of the variable when encountering code 135*61046927SAndroid Build Coastguard Workerlike: 136*61046927SAndroid Build Coastguard Worker 137*61046927SAndroid Build Coastguard Worker(assign (constant bool (1)) (swiz x (var_ref __retval) ) (var_ref a) ) 138*61046927SAndroid Build Coastguard Worker(assign (constant bool (1)) (swiz y (var_ref __retval) ) (var_ref b) ) 139*61046927SAndroid Build Coastguard Worker(assign (constant bool (1)) (swiz z (var_ref __retval) ) (var_ref c) ) 140*61046927SAndroid Build Coastguard Worker 141*61046927SAndroid Build Coastguard WorkerIf every masked update of a component relies on the previous value of 142*61046927SAndroid Build Coastguard Workerthe variable, then we're probably going to be quite limited in our 143*61046927SAndroid Build Coastguard Workerdead code elimination wins, and recognizing common expressions may 144*61046927SAndroid Build Coastguard Workerjust not happen. On the other hand, if we operate channel-wise, then 145*61046927SAndroid Build Coastguard Workerwe'll be prone to optimizing the operation on one of the channels at 146*61046927SAndroid Build Coastguard Workerthe expense of making its instruction flow different from the other 147*61046927SAndroid Build Coastguard Workerchannels, and a vector-based GPU would end up with worse code than if 148*61046927SAndroid Build Coastguard Workerwe didn't optimize operations on that channel! 149*61046927SAndroid Build Coastguard Worker 150*61046927SAndroid Build Coastguard WorkerOnce again, it appears that our optimization requirements are driven 151*61046927SAndroid Build Coastguard Workersignificantly by the target architecture. For now, targeting the Mesa 152*61046927SAndroid Build Coastguard WorkerIR backend, SSA does not appear to be that important to producing 153*61046927SAndroid Build Coastguard Workerexcellent code, but we do expect to do some SSA-based optimizations 154*61046927SAndroid Build Coastguard Workerfor the 965 fragment shader backend when that is developed. 155*61046927SAndroid Build Coastguard Worker 156*61046927SAndroid Build Coastguard WorkerQ: How should I expand instructions that take multiple backend instructions? 157*61046927SAndroid Build Coastguard Worker 158*61046927SAndroid Build Coastguard WorkerSometimes you'll have to do the expansion in your code generation. 159*61046927SAndroid Build Coastguard WorkerHowever, in many cases you'll want to do a pass over the IR to convert 160*61046927SAndroid Build Coastguard Workernon-native instructions to a series of native instructions. For 161*61046927SAndroid Build Coastguard Workerexample, for the Mesa backend we have ir_div_to_mul_rcp.cpp because 162*61046927SAndroid Build Coastguard WorkerMesa IR (and many hardware backends) only have a reciprocal 163*61046927SAndroid Build Coastguard Workerinstruction, not a divide. Implementing non-native instructions this 164*61046927SAndroid Build Coastguard Workerway gives the chance for constant folding to occur, so (a / 2.0) 165*61046927SAndroid Build Coastguard Workerbecomes (a * 0.5) after codegen instead of (a * (1.0 / 2.0)) 166*61046927SAndroid Build Coastguard Worker 167*61046927SAndroid Build Coastguard WorkerQ: How shoud I handle my special hardware instructions with respect to IR? 168*61046927SAndroid Build Coastguard Worker 169*61046927SAndroid Build Coastguard WorkerOur current theory is that if multiple targets have an instruction for 170*61046927SAndroid Build Coastguard Workersome operation, then we should probably be able to represent that in 171*61046927SAndroid Build Coastguard Workerthe IR. Generally this is in the form of an ir_{bin,un}op expression 172*61046927SAndroid Build Coastguard Workertype. For example, we initially implemented fract() using (a - 173*61046927SAndroid Build Coastguard Workerfloor(a)), but both 945 and 965 have instructions to give that result, 174*61046927SAndroid Build Coastguard Workerand it would also simplify the implementation of mod(), so 175*61046927SAndroid Build Coastguard Workerir_unop_fract was added. The following areas need updating to add a 176*61046927SAndroid Build Coastguard Workernew expression type: 177*61046927SAndroid Build Coastguard Worker 178*61046927SAndroid Build Coastguard Workerir.h (new enum) 179*61046927SAndroid Build Coastguard Workerir.cpp:operator_strs (used for ir_reader) 180*61046927SAndroid Build Coastguard Workerir_constant_expression.cpp (you probably want to be able to constant fold) 181*61046927SAndroid Build Coastguard Workerir_validate.cpp (check users have the right types) 182*61046927SAndroid Build Coastguard Worker 183*61046927SAndroid Build Coastguard WorkerYou may also need to update the backends if they will see the new expr type: 184*61046927SAndroid Build Coastguard Worker 185*61046927SAndroid Build Coastguard Worker../mesa/program/ir_to_mesa.cpp 186*61046927SAndroid Build Coastguard Worker 187*61046927SAndroid Build Coastguard WorkerYou can then use the new expression from builtins (if all backends 188*61046927SAndroid Build Coastguard Workerwould rather see it), or scan the IR and convert to use your new 189*61046927SAndroid Build Coastguard Workerexpression type (see ir_mod_to_floor, for example). 190*61046927SAndroid Build Coastguard Worker 191*61046927SAndroid Build Coastguard WorkerQ: How is memory management handled in the compiler? 192*61046927SAndroid Build Coastguard Worker 193*61046927SAndroid Build Coastguard WorkerThe hierarchical memory allocator "talloc" developed for the Samba 194*61046927SAndroid Build Coastguard Workerproject is used, so that things like optimization passes don't have to 195*61046927SAndroid Build Coastguard Workerworry about their garbage collection so much. It has a few nice 196*61046927SAndroid Build Coastguard Workerfeatures, including low performance overhead and good debugging 197*61046927SAndroid Build Coastguard Workersupport that's trivially available. 198*61046927SAndroid Build Coastguard Worker 199*61046927SAndroid Build Coastguard WorkerGenerally, each stage of the compile creates a talloc context and 200*61046927SAndroid Build Coastguard Workerallocates its memory out of that or children of it. At the end of the 201*61046927SAndroid Build Coastguard Workerstage, the pieces still live are stolen to a new context and the old 202*61046927SAndroid Build Coastguard Workerone freed, or the whole context is kept for use by the next stage. 203*61046927SAndroid Build Coastguard Worker 204*61046927SAndroid Build Coastguard WorkerFor IR transformations, a temporary context is used, then at the end 205*61046927SAndroid Build Coastguard Workerof all transformations, reparent_ir reparents all live nodes under the 206*61046927SAndroid Build Coastguard Workershader's IR list, and the old context full of dead nodes is freed. 207*61046927SAndroid Build Coastguard WorkerWhen developing a single IR transformation pass, this means that you 208*61046927SAndroid Build Coastguard Workerwant to allocate instruction nodes out of the temporary context, so if 209*61046927SAndroid Build Coastguard Workerit becomes dead it doesn't live on as the child of a live node. At 210*61046927SAndroid Build Coastguard Workerthe moment, optimization passes aren't passed that temporary context, 211*61046927SAndroid Build Coastguard Workerso they find it by calling talloc_parent() on a nearby IR node. The 212*61046927SAndroid Build Coastguard Workertalloc_parent() call is expensive, so many passes will cache the 213*61046927SAndroid Build Coastguard Workerresult of the first talloc_parent(). Cleaning up all the optimization 214*61046927SAndroid Build Coastguard Workerpasses to take a context argument and not call talloc_parent() is left 215*61046927SAndroid Build Coastguard Workeras an exercise. 216*61046927SAndroid Build Coastguard Worker 217*61046927SAndroid Build Coastguard WorkerQ: What is the file naming convention in this directory? 218*61046927SAndroid Build Coastguard Worker 219*61046927SAndroid Build Coastguard WorkerInitially, there really wasn't one. We have since adopted one: 220*61046927SAndroid Build Coastguard Worker 221*61046927SAndroid Build Coastguard Worker - Files that implement code lowering passes should be named lower_* 222*61046927SAndroid Build Coastguard Worker (e.g., lower_builtins.cpp). 223*61046927SAndroid Build Coastguard Worker - Files that implement optimization passes should be named opt_*. 224*61046927SAndroid Build Coastguard Worker - Files that implement a class that is used throught the code should 225*61046927SAndroid Build Coastguard Worker take the name of that class (e.g., ir_hierarchical_visitor.cpp). 226*61046927SAndroid Build Coastguard Worker - Files that contain code not fitting in one of the previous 227*61046927SAndroid Build Coastguard Worker categories should have a sensible name (e.g., glsl_parser.yy). 228