summaryrefslogtreecommitdiffstats
path: root/src/glsl/loop_analysis.h
Commit message (Collapse)AuthorAgeFilesLines
* glsl: introduce data section to ir_variableTapani Pälli2013-12-121-1/+2
| | | | | | | | Data section helps serialization and cloning of a ir_variable. This patch includes the helper bits used for read only ir_variables. Signed-off-by: Tapani Pälli <[email protected]> Reviewed-by: Paul Berry <[email protected]>
* glsl/loops: Stop creating normatively bound loops in loop_controls.Paul Berry2013-12-091-6/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously, when loop_controls analyzed a loop and found that it had a fixed bound (known at compile time), it would remove all of the loop terminators and instead set the loop's normative_bound field to force the loop to execute the correct number of times. This made loop unrolling easy, but it had a serious disadvantage. Since most GPU's don't have a native mechanism for executing a loop a fixed number of times, in order to implement the normative bound, the back-ends would have to synthesize a new loop induction variable. As a result, many loops wound up having two induction variables instead of one. This caused extra register pressure and unnecessary instructions. This patch modifies loop_controls so that it doesn't set the loop's normative_bound anymore. Instead it leaves one of the terminators in the loop (the limiting terminator), so the back-end doesn't have to go to any extra work to ensure the loop terminates at the right time. This complicates loop unrolling slightly: when deciding whether a loop can be unrolled, we have to account for the presence of the limiting terminator. And when we do unroll the loop, we have to remove the limiting terminator first. For an example of how this results in more efficient back end code, consider the loop: for (int i = 0; i < 100; i++) { total += i; } Previous to this patch, on i965, this loop would compile down to this (vec4) native code: mov(8) g4<1>.xD 0D mov(8) g8<1>.xD 0D loop: cmp.ge.f0(8) null g8<4;4,1>.xD 100D (+f0) if(8) break(8) endif(8) add(8) g5<1>.xD g5<4;4,1>.xD g4<4;4,1>.xD add(8) g8<1>.xD g8<4;4,1>.xD 1D add(8) g4<1>.xD g4<4;4,1>.xD 1D while(8) loop (notice that both g8 and g4 are loop induction variables; one is used to terminate the loop, and the other is used to accumulate the total). After this patch, the same loop compiles to: mov(8) g4<1>.xD 0D loop: cmp.ge.f0(8) null g4<4;4,1>.xD 100D (+f0) if(8) break(8) endif(8) add(8) g5<1>.xD g5<4;4,1>.xD g4<4;4,1>.xD add(8) g4<1>.xD g4<4;4,1>.xD 1D while(8) loop Reviewed-by: Ian Romanick <[email protected]>
* glsl/loops: Get rid of loop_variable_state::max_iterations.Paul Berry2013-12-091-10/+0
| | | | | | | | This value is now redundant with loop_variable_state::limiting_terminator->iterations and ir_loop::normative_bound. Reviewed-by: Ian Romanick <[email protected]>
* glsl/loops: Move some analysis from loop_controls to loop_analysis.Paul Berry2013-12-091-0/+30
| | | | | | | | | | | | | | | | | | | | Previously, the sole responsibility of loop_analysis was to find all the variables referenced in the loop that are either loop constant or induction variables, and find all of the simple if statements that might terminate the loop. The remainder of the analysis necessary to determine how many times a loop executed was performed by loop_controls. This patch makes loop_analysis also responsible for determining the number of iterations after which each loop terminator will terminate the loop, and for figuring out which terminator will terminate the loop first (I'm calling this the "limiting terminator"). This will allow loop unrolling to make use of information that was previously only visible from loop_controls, namely the identity of the limiting terminator. Reviewed-by: Ian Romanick <[email protected]>
* glsl/loops: Remove unnecessary list walk from loop_control_visitor.Paul Berry2013-12-091-0/+9
| | | | | | | | | | | When loop_control_visitor::visit_leave(ir_loop *) is analyzing a loop terminator that acts on a certain ir_variable, it doesn't need to walk the list of induction variables to find the loop_variable entry corresponding to the variable. It can just look it up in the loop_variable_state hashtable and verify that the loop_variable entry represents an induction variable. Reviewed-by: Ian Romanick <[email protected]>
* glsl/loops: Remove unused fields iv_scale and biv from loop_variable class.Paul Berry2013-12-091-10/+4
| | | | | | | | | These fields were part of some planned optimizations that never materialized. Remove them for now to simplify things; if we ever get round to adding the optimizations that would require them, we can always re-introduce them. Reviewed-by: Ian Romanick <[email protected]>
* glsl/loops: replace loop controls with a normative bound.Paul Berry2013-12-091-2/+1
| | | | | | | | | | | | | | This patch replaces the ir_loop fields "from", "to", "increment", "counter", and "cmp" with a single integer ("normative_bound") that serves the same purpose. I've used the name "normative_bound" to emphasize the fact that the back-end is required to emit code to prevent the loop from running more than normative_bound times. (By contrast, an "informative" bound would be a bound that is informational only). Reviewed-by: Jordan Justen <[email protected]> Reviewed-by: Ian Romanick <[email protected]>
* glsl: Fix loop analysis of nested loops.Paul Berry2013-12-091-4/+8
| | | | | | | | | | | | | | | | | | | | Previously, when visiting a variable dereference, loop analysis would only consider its effect on the innermost enclosing loop. As a result, when encountering a loop like this: for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { ... i = 2; } } it would incorrectly conclude that the outer loop ran three times. Fixes piglit test "vs-inner-loop-modifies-outer-loop-var.shader_test". Reviewed-by: Jordan Justen <[email protected]> Reviewed-by: Ian Romanick <[email protected]>
* glsl: Extract functions from loop_analysis::visit(ir_dereference_variable *).Paul Berry2013-12-091-0/+4
| | | | | | | This function is about to get more complex. Reviewed-by: Jordan Justen <[email protected]> Reviewed-by: Ian Romanick <[email protected]>
* glsl: Remove unused field loop_variable_state::loop.Paul Berry2013-11-291-5/+0
| | | | | | This field was neither initialized nor used. It was just dead memory. Reviewed-by: Kenneth Graunke <[email protected]>
* glsl: Change loop_analysis to not look like a resource leakIan Romanick2013-02-071-1/+1
| | | | | | | | | | | | | | | Previously the loop_state was allocated in the loop_analysis constructor, but not freed in the (nonexistent) destructor. Moving the allocation of the loop_state makes this code appear less sketchy. Either way, there is no actual leak. The loop_state is freed by the single caller of analyze_loop_variables. Signed-off-by: Ian Romanick <[email protected]> Cc: Dave Airlie <[email protected]> Reviewed-by: Matt Turner <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=57753
* glsl: Hook up loop_variable_state destructor to plug a memory leak.Kenneth Graunke2012-06-071-0/+17
| | | | | | | | | | | | | While ~loop_state() is already freeing the loop_variable_state objects via ralloc_free(this->mem_ctx), the ~loop_variable_state() destructor was never getting called, so the hash table inside loop_variable_state was never getting destroyed. Fixes a memory leak in any shader with loops. NOTE: This is a candidate for stable release branches. Signed-off-by: Kenneth Graunke <[email protected]>
* glsl: Don't trust loop analysis in the presence of function calls.Kenneth Graunke2012-04-021-0/+6
| | | | | | | | | | | | | | | | | | | | | Function calls may have side effects that alter variables used inside the loop. In the fragment shader, they may even terminate the shader. This means our analysis about loop-constant or induction variables may be completely wrong. In general it's impossible to determine whether they actually do or not (due to the halting problem), so we'd need to perform conservative static analysis. For now, it's not worth the complexity: most functions will be inlined, at which point we can unroll them successfully. Fixes Piglit tests: - shaders/glsl-fs-unroll-out-param - shaders/glsl-fs-unroll-side-effect NOTE: This is a candidate for release branches. Signed-off-by: Kenneth Graunke <[email protected]> Reviewed-by: Ian Romanick <[email protected]>
* glsl: Skip the rest of loop unrolling if no loops were found.Eric Anholt2011-01-181-0/+2
| | | | | Shaves 1.6% (+/- 1.0%) off of ff_fragment_shader glean texCombine time (n=5).
* glsl: add several EmitNo* options, and MaxUnrollIterationsLuca Barbieri2010-09-081-1/+1
| | | | | | | | | This increases the chance that GLSL programs will actually work. Note that continues and returns are not yet lowered, so linking will just fail if not supported. Signed-off-by: Ian Romanick <[email protected]>
* glsl2: Add module to perform simple loop unrollingIan Romanick2010-09-031-0/+14
|
* glsl2: Track the number of ir_loop_jump instructions that are in a loopIan Romanick2010-09-031-0/+6
|
* glsl2: Add module to suss out loop control variables from loop analysis dataIan Romanick2010-09-031-0/+20
| | | | This is the next step on the road to loop unrolling
* glsl2: Add module to analyze variables used in loopsIan Romanick2010-09-031-0/+190
This is the first step eventually leading to loop unrolling.