nvc0: preemptively insert branch at ENDIF
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Thu, 24 Feb 2011 16:22:15 +0000 (17:22 +0100)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Thu, 24 Feb 2011 16:35:35 +0000 (17:35 +0100)
Might be necessary if a block sneaks in somewhere, like a common
block for moves of phi sources after a loop break.

This is harmless and normally will be removed before emission.

src/gallium/drivers/nvc0/nvc0_pc_optimize.c
src/gallium/drivers/nvc0/nvc0_tgsi_to_nc.c

index 3d03400518b7472ad90bf4f30b56f6e03dce0672..8d4d0f3af60c962af561872a530ecd42ebeb8325 100644 (file)
@@ -142,9 +142,10 @@ nv_pc_pass_pre_emission(void *priv, struct nv_basic_block *b)
    struct nv_instruction *nvi, *next;
    int j;
 
+   /* find first non-empty block emitted before b */
    for (j = pc->num_blocks - 1; j >= 0 && !pc->bb_list[j]->emit_size; --j);
 
-   if (j >= 0) {
+   for (; j >= 0; --j) {
       in = pc->bb_list[j];
 
       /* check for no-op branches (BRA $PC+8) */
@@ -158,6 +159,9 @@ nv_pc_pass_pre_emission(void *priv, struct nv_basic_block *b)
          nvc0_insn_delete(in->exit);
       }
       b->emit_pos = in->emit_pos + in->emit_size;
+
+      if (in->emit_size) /* no more no-op branches to b */
+         break;
    }
 
    pc->bb_list[pc->num_blocks++] = b;
index 5e208e8623dce7e51f028855905687f5fe96fc9e..fc19ef1eb1972eb611206da591ea76c6b2d6d98c 100644 (file)
@@ -1634,6 +1634,10 @@ bld_instruction(struct bld_context *bld,
    {
       struct nv_basic_block *b = new_basic_block(bld->pc);
 
+      if (bld->pc->current_block->exit &&
+          !bld->pc->current_block->exit->terminator)
+         bld_flow(bld, NV_OP_BRA, NULL, NV_CC_P, b, FALSE);
+
       --bld->cond_lvl;
       nvc0_bblock_attach(bld->pc->current_block, b, bld->out_kind);
       nvc0_bblock_attach(bld->cond_bb[bld->cond_lvl], b, CFG_EDGE_FORWARD);