1*61046927SAndroid Build Coastguard WorkerNew IR, or NIR, is an IR for Mesa intended to sit below GLSL IR and Mesa IR. 2*61046927SAndroid Build Coastguard WorkerIts design inherits from the various IRs that Mesa has used in the past, as 3*61046927SAndroid Build Coastguard Workerwell as Direct3D assembly, and it includes a few new ideas as well. It is a 4*61046927SAndroid Build Coastguard Workerflat (in terms of using instructions instead of expressions), typeless IR, 5*61046927SAndroid Build Coastguard Workersimilar to TGSI and Mesa IR. It also supports SSA (although it doesn't require 6*61046927SAndroid Build Coastguard Workerit). 7*61046927SAndroid Build Coastguard Worker 8*61046927SAndroid Build Coastguard WorkerVariables 9*61046927SAndroid Build Coastguard Worker========= 10*61046927SAndroid Build Coastguard Worker 11*61046927SAndroid Build Coastguard WorkerNIR includes support for source-level GLSL variables through a structure mostly 12*61046927SAndroid Build Coastguard Workercopied from GLSL IR. These will be used for linking and conversion from GLSL IR 13*61046927SAndroid Build Coastguard Worker(and later, from an AST), but for the most part, they will be lowered to 14*61046927SAndroid Build Coastguard Workerregisters (see below) and loads/stores. 15*61046927SAndroid Build Coastguard Worker 16*61046927SAndroid Build Coastguard WorkerRegisters 17*61046927SAndroid Build Coastguard Worker========= 18*61046927SAndroid Build Coastguard Worker 19*61046927SAndroid Build Coastguard WorkerRegisters are light-weight; they consist of a structure that only contains its 20*61046927SAndroid Build Coastguard Workersize, its index for liveness analysis, and an optional name for debugging. In 21*61046927SAndroid Build Coastguard Workeraddition, registers can be local to a function or global to the entire shader; 22*61046927SAndroid Build Coastguard Workerthe latter will be used in ARB_shader_subroutine for passing parameters and 23*61046927SAndroid Build Coastguard Workergetting return values from subroutines. Registers can also be an array, in which 24*61046927SAndroid Build Coastguard Workercase they can be accessed indirectly. Each ALU instruction (add, subtract, etc.) 25*61046927SAndroid Build Coastguard Workerworks directly with registers or SSA values (see below). 26*61046927SAndroid Build Coastguard Worker 27*61046927SAndroid Build Coastguard WorkerSSA 28*61046927SAndroid Build Coastguard Worker======== 29*61046927SAndroid Build Coastguard Worker 30*61046927SAndroid Build Coastguard WorkerEverywhere a register can be loaded/stored, an SSA value can be used instead. 31*61046927SAndroid Build Coastguard WorkerThe only exception is that arrays/indirect addressing are not supported with 32*61046927SAndroid Build Coastguard WorkerSSA; although research has been done on extensions of SSA to arrays before, it's 33*61046927SAndroid Build Coastguard Workerusually for the purpose of parallelization (which we're not interested in), and 34*61046927SAndroid Build Coastguard Workeradds some overhead in the form of adding copies or extra arrays (which is much 35*61046927SAndroid Build Coastguard Workermore expensive than introducing copies between non-array registers). SSA uses 36*61046927SAndroid Build Coastguard Workerpoint directly to their corresponding definition, which in turn points to the 37*61046927SAndroid Build Coastguard Workerinstruction it is part of. This creates an implicit use-def chain and avoids the 38*61046927SAndroid Build Coastguard Workerneed for an external structure for each SSA register. 39*61046927SAndroid Build Coastguard Worker 40*61046927SAndroid Build Coastguard WorkerFunctions 41*61046927SAndroid Build Coastguard Worker========= 42*61046927SAndroid Build Coastguard Worker 43*61046927SAndroid Build Coastguard WorkerSupport for function calls is mostly similar to GLSL IR. Each shader contains a 44*61046927SAndroid Build Coastguard Workerlist of functions, and each function has a list of overloads. Each overload 45*61046927SAndroid Build Coastguard Workercontains a list of parameters, and may contain an implementation which specifies 46*61046927SAndroid Build Coastguard Workerthe variables that correspond to the parameters and return value. Inlining a 47*61046927SAndroid Build Coastguard Workerfunction, assuming it has a single return point, is as simple as copying its 48*61046927SAndroid Build Coastguard Workerinstructions, registers, and local variables into the target function and then 49*61046927SAndroid Build Coastguard Workerinserting copies to and from the new parameters as appropriate. After functions 50*61046927SAndroid Build Coastguard Workerare inlined and any non-subroutine functions are deleted, parameters and return 51*61046927SAndroid Build Coastguard Workervariables will be converted to global variables and then global registers. We 52*61046927SAndroid Build Coastguard Workerdon't do this lowering earlier (i.e. the fortranizer idea) for a few reasons: 53*61046927SAndroid Build Coastguard Worker 54*61046927SAndroid Build Coastguard Worker- If we want to do optimizations before link time, we need to have the function 55*61046927SAndroid Build Coastguard Workersignature available during link-time. 56*61046927SAndroid Build Coastguard Worker 57*61046927SAndroid Build Coastguard Worker- If we do any inlining before link time, then we might wind up with the 58*61046927SAndroid Build Coastguard Workerinlined function and the non-inlined function using the same global 59*61046927SAndroid Build Coastguard Workervariables/registers which would preclude optimization. 60*61046927SAndroid Build Coastguard Worker 61*61046927SAndroid Build Coastguard WorkerIntrinsics 62*61046927SAndroid Build Coastguard Worker========= 63*61046927SAndroid Build Coastguard Worker 64*61046927SAndroid Build Coastguard WorkerAny operation (other than function calls and textures) which touches a variable 65*61046927SAndroid Build Coastguard Workeror is not referentially transparent is represented by an intrinsic. Intrinsics 66*61046927SAndroid Build Coastguard Workerare similar to the idea of a "builtin function," i.e. a function declaration 67*61046927SAndroid Build Coastguard Workerwhose implementation is provided by the backend, except they are more powerful 68*61046927SAndroid Build Coastguard Workerin the following ways: 69*61046927SAndroid Build Coastguard Worker 70*61046927SAndroid Build Coastguard Worker- They can also load and store registers when appropriate, which limits the 71*61046927SAndroid Build Coastguard Workernumber of variables needed in later stages of the IR while obviating the need 72*61046927SAndroid Build Coastguard Workerfor a separate load/store variable instruction. 73*61046927SAndroid Build Coastguard Worker 74*61046927SAndroid Build Coastguard Worker- Intrinsics can be marked as side-effect free, which permits them to be 75*61046927SAndroid Build Coastguard Workertreated like any other instruction when it comes to optimizations. This allows 76*61046927SAndroid Build Coastguard Workerload intrinsics to be represented as intrinsics while still being optimized 77*61046927SAndroid Build Coastguard Workeraway by dead code elimination, common subexpression elimination, etc. 78*61046927SAndroid Build Coastguard Worker 79*61046927SAndroid Build Coastguard WorkerIntrinsics are used for: 80*61046927SAndroid Build Coastguard Worker 81*61046927SAndroid Build Coastguard Worker- Atomic operations 82*61046927SAndroid Build Coastguard Worker- Memory barriers 83*61046927SAndroid Build Coastguard Worker- Subroutine calls 84*61046927SAndroid Build Coastguard Worker- Geometry shader emitVertex and endPrimitive 85*61046927SAndroid Build Coastguard Worker- Loading and storing variables (before lowering) 86*61046927SAndroid Build Coastguard Worker- Loading and storing uniforms, shader inputs and outputs, etc (after lowering) 87*61046927SAndroid Build Coastguard Worker- Copying variables (cases where in GLSL the destination is a structure or 88*61046927SAndroid Build Coastguard Workerarray) 89*61046927SAndroid Build Coastguard Worker- The kitchen sink 90*61046927SAndroid Build Coastguard Worker- ... 91*61046927SAndroid Build Coastguard Worker 92*61046927SAndroid Build Coastguard WorkerTextures 93*61046927SAndroid Build Coastguard Worker========= 94*61046927SAndroid Build Coastguard Worker 95*61046927SAndroid Build Coastguard WorkerUnfortunately, there are far too many texture operations to represent each one 96*61046927SAndroid Build Coastguard Workerof them with an intrinsic, so there's a special texture instruction similar to 97*61046927SAndroid Build Coastguard Workerthe GLSL IR one. The biggest difference is that, while the texture instruction 98*61046927SAndroid Build Coastguard Workerhas a sampler dereference field used just like in GLSL IR, this gets lowered to 99*61046927SAndroid Build Coastguard Workera texture unit index (with a possible indirect offset) while the type 100*61046927SAndroid Build Coastguard Workerinformation of the original sampler is kept around for backends. Also, all the 101*61046927SAndroid Build Coastguard Workernon-constant sources are stored in a single array to make it easier for 102*61046927SAndroid Build Coastguard Workeroptimization passes to iterate over all the sources. 103*61046927SAndroid Build Coastguard Worker 104*61046927SAndroid Build Coastguard WorkerControl Flow 105*61046927SAndroid Build Coastguard Worker========= 106*61046927SAndroid Build Coastguard Worker 107*61046927SAndroid Build Coastguard WorkerLike in GLSL IR, control flow consists of a tree of "control flow nodes", which 108*61046927SAndroid Build Coastguard Workerinclude if statements and loops, and jump instructions (break, continue, and 109*61046927SAndroid Build Coastguard Workerreturn). Unlike GLSL IR, though, the leaves of the tree aren't statements but 110*61046927SAndroid Build Coastguard Workerbasic blocks. Each basic block also keeps track of its successors and 111*61046927SAndroid Build Coastguard Workerpredecessors, and function implementations keep track of the beginning basic 112*61046927SAndroid Build Coastguard Workerblock (the first basic block of the function) and the ending basic block (a fake 113*61046927SAndroid Build Coastguard Workerbasic block that every return statement points to). Together, these elements 114*61046927SAndroid Build Coastguard Workermake up the control flow graph, in this case a redundant piece of information on 115*61046927SAndroid Build Coastguard Workertop of the control flow tree that will be used by almost all the optimizations. 116*61046927SAndroid Build Coastguard WorkerThere are helper functions to add and remove control flow nodes that also update 117*61046927SAndroid Build Coastguard Workerthe control flow graph, and so usually it doesn't need to be touched by passes 118*61046927SAndroid Build Coastguard Workerthat modify control flow nodes. 119