r600g: optimize away CF_INST_POP
authorChristian König <deathsimple@vodafone.de>
Mon, 13 Dec 2010 23:43:53 +0000 (00:43 +0100)
committerChristian König <deathsimple@vodafone.de>
Wed, 12 Jan 2011 18:31:36 +0000 (19:31 +0100)
If last instruction is an CF_INST_ALU we don't need to emit an
additional CF_INST_POP for stack clean up after an IF ELSE ENDIF.

src/gallium/drivers/r600/eg_asm.c
src/gallium/drivers/r600/r600_asm.c
src/gallium/drivers/r600/r600_shader.c

index c44506c..67d742b 100644 (file)
@@ -35,6 +35,8 @@ int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
 
        switch (cf->inst) {
        case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):
+       case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3):
+       case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3):
        case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3):
                bc->bytecode[id++] = S_SQ_CF_ALU_WORD0_ADDR(cf->addr >> 1) |
                        S_SQ_CF_ALU_WORD0_KCACHE_MODE0(cf->kcache[0].mode) |
index e911f97..3ee54a2 100644 (file)
@@ -631,6 +631,8 @@ int r600_bc_add_literal(struct r600_bc *bc, const u32 *value)
        }
        /* same on EG */
        if (((bc->cf_last->inst != (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3)) &&
+            (bc->cf_last->inst != (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3)) &&
+            (bc->cf_last->inst != (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3)) &&
             (bc->cf_last->inst != (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3))) ||
                LIST_IS_EMPTY(&bc->cf_last->alu)) {
                R600_ERR("last CF is not ALU (%p)\n", bc->cf_last);
@@ -853,6 +855,8 @@ static int r600_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
        switch (cf->inst) {
        case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):
        case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3):
+       case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3):
+       case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3):
                bc->bytecode[id++] = S_SQ_CF_ALU_WORD0_ADDR(cf->addr >> 1) |
                        S_SQ_CF_ALU_WORD0_KCACHE_MODE0(cf->kcache[0].mode) |
                        S_SQ_CF_ALU_WORD0_KCACHE_BANK0(cf->kcache[0].bank) |
@@ -932,6 +936,8 @@ int r600_bc_build(struct r600_bc *bc)
        LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) {
                switch (cf->inst) {
                case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):
+               case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3):
+               case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3):
                case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3):
                        break;
                case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
@@ -978,6 +984,8 @@ int r600_bc_build(struct r600_bc *bc)
                        return r;
                switch (cf->inst) {
                case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):
+               case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3):
+               case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3):
                case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3):
                        LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) {
                                switch(bc->chiprev) {
index 9248eb3..0f7213f 100644 (file)
@@ -2703,9 +2703,25 @@ static int emit_logic_pred(struct r600_shader_ctx *ctx, int opcode)
 
 static int pops(struct r600_shader_ctx *ctx, int pops)
 {
-       r600_bc_add_cfinst(ctx->bc, CTX_INST(V_SQ_CF_WORD1_SQ_CF_INST_POP));
-       ctx->bc->cf_last->pop_count = pops;
-       ctx->bc->cf_last->cf_addr = ctx->bc->cf_last->id + 2;
+       int alu_pop = 3;
+       if (ctx->bc->cf_last) {
+               if (ctx->bc->cf_last->inst == CTX_INST(V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU) << 3)
+                       alu_pop = 0;
+               else if (ctx->bc->cf_last->inst == CTX_INST(V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER) << 3)
+                       alu_pop = 1;
+       }
+       alu_pop += pops;
+       if (alu_pop == 1) {
+               ctx->bc->cf_last->inst = CTX_INST(V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER) << 3;
+               ctx->bc->force_add_cf = 1;
+       } else if (alu_pop == 2) {
+               ctx->bc->cf_last->inst = CTX_INST(V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER) << 3;
+               ctx->bc->force_add_cf = 1;
+       } else {
+               r600_bc_add_cfinst(ctx->bc, CTX_INST(V_SQ_CF_WORD1_SQ_CF_INST_POP));
+               ctx->bc->cf_last->pop_count = pops;
+               ctx->bc->cf_last->cf_addr = ctx->bc->cf_last->id + 2;
+       }
        return 0;
 }