diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gallium/drivers/nv50/nv50_pc.c | 30 | ||||
| -rw-r--r-- | src/gallium/drivers/nv50/nv50_pc.h | 1 | ||||
| -rw-r--r-- | src/gallium/drivers/nv50/nv50_pc_optimize.c | 31 | ||||
| -rw-r--r-- | src/gallium/drivers/nv50/nv50_pc_print.c | 7 | 
4 files changed, 34 insertions, 35 deletions
diff --git a/src/gallium/drivers/nv50/nv50_pc.c b/src/gallium/drivers/nv50/nv50_pc.c index e09f94074d..0e8aadf5a9 100644 --- a/src/gallium/drivers/nv50/nv50_pc.c +++ b/src/gallium/drivers/nv50/nv50_pc.c @@ -254,7 +254,7 @@ nv50_emit_program(struct nv_pc *pc)     assert(pc->emit == &code[pc->bin_size / 4]);     /* XXX: we can do better than this ... */ -   if ((pc->emit[-1] & 3) == 3) { +   if ((pc->emit[-2] & 2) || (pc->emit[-1] & 3) == 3) {        pc->emit[0] = 0xf0000001;        pc->emit[1] = 0xe0000000;        pc->bin_size += 8; @@ -347,16 +347,16 @@ nvbb_insert_phi(struct nv_basic_block *b, struct nv_instruction *i)           b->entry->prev = i;        } else {           b->entry = i; -	 b->exit = i; +         b->exit = i;        }     } else {        assert(b->entry);        if (b->entry->opcode == NV_OP_PHI) { /* insert after entry */ -	 assert(b->entry == b->exit); +         assert(b->entry == b->exit);           b->entry->next = i;           i->prev = b->entry;           b->entry = i; -	 b->exit = i; +         b->exit = i;        } else { /* insert before entry */           assert(b->entry->prev && b->exit);           i->next = b->entry; @@ -396,12 +396,9 @@ nv_nvi_delete(struct nv_instruction *nvi)     debug_printf("REM: "); nv_print_instruction(nvi); -   for (j = 0; j < 4; ++j) { -      if (!nvi->src[j]) -         break; -      --(nvi->src[j]->value->refc); -      nvi->src[j] = NULL; -   }	        +   for (j = 0; j < 5; ++j) +      nv_reference(NULL, &nvi->src[j], NULL); +   nv_reference(NULL, &nvi->flags_src, NULL);     if (nvi->next)        nvi->next->prev = nvi->prev; @@ -414,19 +411,16 @@ nv_nvi_delete(struct nv_instruction *nvi)        nvi->prev->next = nvi->next;     if (nvi == b->entry) { -      assert(nvi->opcode != NV_OP_PHI || !nvi->next); - -      if (!nvi->next || (nvi->opcode == NV_OP_PHI)) -         b->entry = nvi->prev; -      else -         b->entry = nvi->next; +      /* PHIs don't get hooked to b->entry */ +      b->entry = nvi->next; +      assert(!nvi->prev || nvi->prev->opcode == NV_OP_PHI);     }     if (nvi == b->phi) { -      assert(!nvi->prev);        if (nvi->opcode != NV_OP_PHI) -         debug_printf("WARN: b->phi points to non-PHI instruction\n"); +         debug_printf("NOTE: b->phi points to non-PHI instruction\n"); +      assert(!nvi->prev);        if (!nvi->next || nvi->next->opcode != NV_OP_PHI)           b->phi = NULL;        else diff --git a/src/gallium/drivers/nv50/nv50_pc.h b/src/gallium/drivers/nv50/nv50_pc.h index ffcdaf44af..da3f984783 100644 --- a/src/gallium/drivers/nv50/nv50_pc.h +++ b/src/gallium/drivers/nv50/nv50_pc.h @@ -402,7 +402,6 @@ nv_reference(struct nv_pc *pc, struct nv_ref **d, struct nv_value *s)           ++(s->refc);        }     } else { -      assert(*d);        *d = NULL;     }  } 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]); diff --git a/src/gallium/drivers/nv50/nv50_pc_print.c b/src/gallium/drivers/nv50/nv50_pc_print.c index 82080779c3..c2c3eb25bc 100644 --- a/src/gallium/drivers/nv50/nv50_pc_print.c +++ b/src/gallium/drivers/nv50/nv50_pc_print.c @@ -291,6 +291,9 @@ nv_print_instruction(struct nv_instruction *i)     if (i->def[0])        nv_print_value(i->def[0], NULL, NV_TYPE_ANY);     else +   if (i->target) +      PRINT(" %s(BB:%i)", orng, i->target->id); +   else        PRINT(" #");     for (j = 0; j < 4; ++j) { @@ -304,7 +307,5 @@ nv_print_instruction(struct nv_instruction *i)                     (j == nv50_indirect_opnd(i)) ?                     i->src[4]->value : NULL);     } -   if (!i->is_long) -      PRINT(" %ss", norm); -   PRINT("\n"); +   PRINT(" %s%c\n", norm, i->is_long ? 'l' : 's');  }  | 
