summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/freedreno/ir3/ir3_depth.c
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2015-06-09 17:17:06 -0400
committerRob Clark <robclark@freedesktop.org>2015-06-21 07:54:38 -0400
commit457f7c2a2a93b45396ac66e0d4b3896d2db8fdf3 (patch)
tree1286493bc6b7fd01738125b6fc91db78c3dc805f /src/gallium/drivers/freedreno/ir3/ir3_depth.c
parent660d5c1646f5d63f9626b24beabc9cfc318849d4 (diff)
downloadexternal_mesa3d-457f7c2a2a93b45396ac66e0d4b3896d2db8fdf3.tar.gz
external_mesa3d-457f7c2a2a93b45396ac66e0d4b3896d2db8fdf3.tar.bz2
external_mesa3d-457f7c2a2a93b45396ac66e0d4b3896d2db8fdf3.zip
freedreno/ir3: block reshuffling and loops!
This shuffles things around to allow the shader to have multiple basic blocks. We drop the entire CFG structure from nir and just preserve the blocks. At scheduling we know whether to schedule conditional branches or unconditional jumps at the end of the block based on the # of block successors. (Dropping jumps to the following instruction, etc.) One slight complication is that variables (load_var/store_var, ie. arrays) are not in SSA form, so we have to figure out where to put the phi's ourself. For this, we use the predecessor set information from nir_block. (We could perhaps use NIR's dominance frontier information to help with this?) Signed-off-by: Rob Clark <robclark@freedesktop.org>
Diffstat (limited to 'src/gallium/drivers/freedreno/ir3/ir3_depth.c')
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_depth.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_depth.c b/src/gallium/drivers/freedreno/ir3/ir3_depth.c
index 6fc8b1762f..3a10824347 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_depth.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_depth.c
@@ -134,6 +134,8 @@ remove_unused_by_block(struct ir3_block *block)
{
list_for_each_entry_safe (struct ir3_instruction, instr, &block->instr_list, node) {
if (!ir3_instr_check_mark(instr)) {
+ if (is_flow(instr) && (instr->opc == OPC_END))
+ continue;
/* mark it, in case it is input, so we can
* remove unused inputs:
*/
@@ -149,13 +151,21 @@ ir3_depth(struct ir3 *ir)
{
unsigned i;
- ir3_clear_mark(ir->block->shader);
+ ir3_clear_mark(ir);
for (i = 0; i < ir->noutputs; i++)
if (ir->outputs[i])
ir3_instr_depth(ir->outputs[i]);
+ /* We also need to account for if-condition: */
+ list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
+ if (block->condition)
+ ir3_instr_depth(block->condition);
+ }
+
/* mark un-used instructions: */
- remove_unused_by_block(ir->block);
+ list_for_each_entry (struct ir3_block, block, &ir->block_list, node) {
+ remove_unused_by_block(block);
+ }
/* cleanup unused inputs: */
for (i = 0; i < ir->ninputs; i++) {