nv50,nvc0: don't insert instructions after the block terminator
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Fri, 8 Apr 2011 13:51:48 +0000 (15:51 +0200)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Sun, 10 Apr 2011 12:06:51 +0000 (14:06 +0200)
src/gallium/drivers/nv50/nv50_pc.c
src/gallium/drivers/nv50/nv50_pc_regalloc.c
src/gallium/drivers/nv50/nv50_tgsi_to_nc.c
src/gallium/drivers/nvc0/nvc0_pc_regalloc.c
src/gallium/drivers/nvc0/nvc0_tgsi_to_nc.c

index f6870cc1d8edcf79e68ee20a616382cf5866d53a..4fe13a75b296ca3c362d606893cfb8ec5ad62a84 100644 (file)
@@ -625,6 +625,9 @@ nvbb_insert_tail(struct nv_basic_block *b, struct nv_instruction *i)
 
    i->bb = b;
    b->num_instructions++;
+
+   if (i->prev && i->prev->is_terminator)
+      nv_nvi_permute(i->prev, i);
 }
 
 void
index df3ac54dce341b33b34f8965029a0cc6485bc2aa..e4f418aa7ca333b29e3353484470c9059d928ecd 100644 (file)
@@ -516,7 +516,9 @@ pass_generate_phi_movs(struct nv_pc_pass *ctx, struct nv_basic_block *b)
       }
 
       if (pn != p && pn->exit) {
-         ctx->pc->current_block = b->in[n ? 0 : 1];
+         assert(!b->in[!n]->exit || b->in[!n]->exit->is_terminator);
+         /* insert terminator (branch to ENDIF) in new else block */
+         ctx->pc->current_block = pn;
          ni = new_instruction(ctx->pc, NV_OP_BRA);
          ni->target = b;
          ni->is_terminator = 1;
index 1449cb04c69cf62ecd6c1d77573aae053d145d9e..f548836a9c48d5b09688f9a6d710deb0ace4f1e8 100644 (file)
@@ -273,6 +273,12 @@ fetch_by_bb(struct bld_value_stack *stack,
          fetch_by_bb(stack, vals, n, b->in[i]);
 }
 
+static INLINE boolean
+nvbb_is_terminated(struct nv_basic_block *bb)
+{
+   return bb->exit && bb->exit->is_terminator;
+}
+
 static INLINE struct nv_value *
 bld_load_imm_u32(struct bld_context *bld, uint32_t u);
 
@@ -1727,8 +1733,7 @@ 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->is_terminator)
+      if (!nvbb_is_terminated(bld->pc->current_block))
          bld_flow(bld, NV_OP_BRA, NV_CC_TR, NULL, b, FALSE);
 
       --bld->cond_lvl;
@@ -1800,7 +1805,8 @@ bld_instruction(struct bld_context *bld,
    {
       struct nv_basic_block *bb = bld->loop_bb[bld->loop_lvl - 1];
 
-      bld_flow(bld, NV_OP_BRA, NV_CC_TR, NULL, bb, FALSE);
+      if (!nvbb_is_terminated(bld->pc->current_block))
+         bld_flow(bld, NV_OP_BRA, NV_CC_TR, NULL, bb, FALSE);
 
       nvbb_attach_block(bld->pc->current_block, bb, CFG_EDGE_BACK);
 
index f4afe083e2dde92a32e1a79a21d9837c9b81c9fe..0515a0d77ebfcc4b238de54c56004627dc2257c3 100644 (file)
@@ -504,7 +504,9 @@ pass_generate_phi_movs(struct nv_pc_pass *ctx, struct nv_basic_block *b)
       }
 
       if (pn != p && pn->exit) {
-         ctx->pc->current_block = b->in[n ? 0 : 1];
+         assert(!b->in[!n]->exit || b->in[!n]->exit->terminator);
+         /* insert terminator (branch to ENDIF) in new else block */
+         ctx->pc->current_block = pn;
          ni = new_instruction(ctx->pc, NV_OP_BRA);
          ni->target = b;
          ni->terminator = 1;
index a44d330c7319d106d85609afdde2c377c3dfb991..53fd7e70fc9d00c46b24f679d6484e72b983c2b2 100644 (file)
@@ -259,6 +259,12 @@ fetch_by_bb(struct bld_register *reg,
          fetch_by_bb(reg, vals, n, b->in[i]);
 }
 
+static INLINE boolean
+nvc0_bblock_is_terminated(struct nv_basic_block *bb)
+{
+   return bb->exit && bb->exit->terminator;
+}
+
 static INLINE struct nv_value *
 bld_load_imm_u32(struct bld_context *bld, uint32_t u);
 
@@ -1637,8 +1643,7 @@ 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)
+      if (!nvc0_bblock_is_terminated(bld->pc->current_block))
          bld_flow(bld, NV_OP_BRA, NULL, NV_CC_P, b, FALSE);
 
       --bld->cond_lvl;