summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/nv50/nv50_pc_optimize.c
diff options
context:
space:
mode:
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>2010-07-26 15:06:58 +0200
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>2010-07-31 18:32:34 +0200
commit582311ca979ac2316807cdffb15e7a25000693f4 (patch)
tree23484302afee0b2b135484e771aa3405656e996d /src/gallium/drivers/nv50/nv50_pc_optimize.c
parent28ded2585ca856b67b8cc0dd7c1de000b3fc729b (diff)
nv50: fix for empty BBs
Diffstat (limited to 'src/gallium/drivers/nv50/nv50_pc_optimize.c')
-rw-r--r--src/gallium/drivers/nv50/nv50_pc_optimize.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/src/gallium/drivers/nv50/nv50_pc_optimize.c b/src/gallium/drivers/nv50/nv50_pc_optimize.c
index 107ef0f4bf..42f3a8634e 100644
--- a/src/gallium/drivers/nv50/nv50_pc_optimize.c
+++ b/src/gallium/drivers/nv50/nv50_pc_optimize.c
@@ -122,15 +122,29 @@ nvi_isnop(struct nv_instruction *nvi)
static void
nv_pc_pass_pre_emission(struct nv_pc *pc, struct nv_basic_block *b)
{
+ struct nv_basic_block *in;
struct nv_instruction *nvi, *next;
int j;
uint size, n32 = 0;
b->priv = 0;
- if (pc->num_blocks)
- b->bin_pos = pc->bb_list[pc->num_blocks - 1]->bin_pos +
- pc->bb_list[pc->num_blocks - 1]->bin_size;
+ for (j = pc->num_blocks - 1; j >= 0 && !pc->bb_list[j]->bin_size; --j);
+ if (j >= 0) {
+ in = pc->bb_list[j];
+
+ /* check for no-op branches (BRA $PC+8) */
+ if (in->exit && in->exit->opcode == NV_OP_BRA && in->exit->target == b) {
+ in->bin_size -= 8;
+ pc->bin_size -= 8;
+
+ for (++j; j < pc->num_blocks; ++j)
+ pc->bb_list[j]->bin_pos -= 8;
+
+ nv_nvi_delete(in->exit);
+ }
+ b->bin_pos = in->bin_pos + in->bin_size;
+ }
pc->bb_list[pc->num_blocks++] = b;
@@ -183,7 +197,7 @@ nv_pc_pass_pre_emission(struct nv_pc *pc, struct nv_basic_block *b)
b->exit->prev->is_long = 1;
}
}
- assert(!b->exit || b->exit->is_long);
+ assert(!b->entry || (b->exit && b->exit->is_long));
pc->bin_size += b->bin_size *= 4;
@@ -194,15 +208,6 @@ nv_pc_pass_pre_emission(struct nv_pc *pc, struct nv_basic_block *b)
if (!b->out[1] && ++(b->out[0]->priv) != b->out[0]->num_in)
return;
-#if 0
- /* delete ELSE branch */
- if (b->entry &&
- b->entry->opcode == NV_OP_BRA && b->entry->target == b->out[0]) {
- nv_nvi_delete(b->entry);
- b->bin_size -= 2;
- pc->bin_size -= 8;
- }
-#endif
for (j = 0; j < 2; ++j)
if (b->out[j] && b->out[j] != b)
nv_pc_pass_pre_emission(pc, b->out[j]);