xref: /aosp_15_r20/external/mesa3d/src/compiler/nir/README (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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