diff options
| author | Roland Scheidegger <sroland@vmware.com> | 2010-12-02 04:32:06 +0100 |
|---|---|---|
| committer | Roland Scheidegger <sroland@vmware.com> | 2010-12-02 04:32:06 +0100 |
| commit | a45bd509014743d21a532194d7b658a1aeb00cb7 (patch) | |
| tree | d5fc155ee50d2f41fa9e7d4a253a8f9c51bc9e51 /src/glsl/lower_jumps.cpp | |
| parent | 1aeca287a827f29206078fa1204715a477072c08 (diff) | |
| parent | 32e1e591467d9a28c2ac4d2e17af7be2dc429d43 (diff) | |
| download | mesa-gallium-array-textures.tar.gz | |
Merge remote branch 'origin/master' into gallium-array-texturesgallium-array-textures
Conflicts:
src/gallium/drivers/i915/i915_resource_texture.c
src/gallium/drivers/i915/i915_state_emit.c
src/gallium/drivers/i915/i915_surface.c
Diffstat (limited to 'src/glsl/lower_jumps.cpp')
| -rw-r--r-- | src/glsl/lower_jumps.cpp | 44 |
1 files changed, 33 insertions, 11 deletions
diff --git a/src/glsl/lower_jumps.cpp b/src/glsl/lower_jumps.cpp index e1e7a5b0073..9cd15ef7366 100644 --- a/src/glsl/lower_jumps.cpp +++ b/src/glsl/lower_jumps.cpp @@ -23,6 +23,37 @@ /** * \file lower_jumps.cpp + * + * This pass lowers jumps (break, continue, and return) to if/else structures. + * + * It can be asked to: + * 1. Pull jumps out of ifs where possible + * 2. Remove all "continue"s, replacing them with an "execute flag" + * 3. Replace all "break" with a single conditional one at the end of the loop + * 4. Replace all "return"s with a single return at the end of the function, + * for the main function and/or other functions + * + * Applying this pass gives several benefits: + * 1. All functions can be inlined. + * 2. nv40 and other pre-DX10 chips without "continue" can be supported + * 3. nv30 and other pre-DX10 chips with no control flow at all are better + * supported + * + * Continues are lowered by adding a per-loop "execute flag", initialized to + * true, that when cleared inhibits all execution until the end of the loop. + * + * Breaks are lowered to continues, plus setting a "break flag" that is checked + * at the end of the loop, and trigger the unique "break". + * + * Returns are lowered to breaks/continues, plus adding a "return flag" that + * causes loops to break again out of their enclosing loops until all the + * loops are exited: then the "execute flag" logic will ignore everything + * until the end of the function. + * + * Note that "continue" and "return" can also be implemented by adding + * a dummy loop and using break. + * However, this is bad for hardware with limited nesting depth, and + * prevents further optimization, and thus is not currently performed. */ #include "glsl_types.h" @@ -36,7 +67,6 @@ enum jump_strength strength_continue, strength_break, strength_return, - strength_discard }; struct block_record @@ -202,8 +232,6 @@ struct ir_lower_jumps_visitor : public ir_control_flow_visitor { virtual void visit(class ir_discard * ir) { - truncate_after_instruction(ir); - this->block.min_strength = strength_discard; } enum jump_strength get_jump_strength(ir_instruction* ir) @@ -217,8 +245,6 @@ struct ir_lower_jumps_visitor : public ir_control_flow_visitor { return strength_continue; } else if(ir->ir_type == ir_type_return) return strength_return; - else if(ir->ir_type == ir_type_discard) - return strength_discard; else return strength_none; } @@ -253,9 +279,6 @@ struct ir_lower_jumps_visitor : public ir_control_flow_visitor { else lower = lower_sub_return; break; - case strength_discard: - lower = false; /* probably nothing needs this lowered */ - break; } return lower; } @@ -313,9 +336,8 @@ retry: /* we get here if we put code after the if inside a branch */ /* FINISHME: unify returns with identical expressions */ else if(jump_strengths[0] == strength_return && this->function.signature->return_type->is_void()) ir->insert_after(new(ir) ir_return(NULL)); - /* FINISHME: unify discards */ - else - unify = false; + else + unify = false; if(unify) { jumps[0]->remove(); |
