diff options
author | Eric Anholt <[email protected]> | 2014-07-03 13:18:49 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2014-08-08 18:59:47 -0700 |
commit | 1d23d55ae97d07b6eb70a3e37a91ecb7de38d8d2 (patch) | |
tree | 60fb2fe8be2c61e2681c81c65bca060ad2c4b6b3 /src/gallium/drivers/vc4 | |
parent | 4c53087c67a266d81653459baa08ece5c1b418d8 (diff) |
vc4: Add an initial pass of algebraic optimization.
There was a lot of extra noise in my piglit shader dumps because of silly
CMPs.
Diffstat (limited to 'src/gallium/drivers/vc4')
-rw-r--r-- | src/gallium/drivers/vc4/Makefile.sources | 1 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_opt_algebraic.c | 77 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_program.c | 9 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_qir.c | 37 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_qir.h | 5 |
5 files changed, 125 insertions, 4 deletions
diff --git a/src/gallium/drivers/vc4/Makefile.sources b/src/gallium/drivers/vc4/Makefile.sources index cf464b06315..1a1b4d00d71 100644 --- a/src/gallium/drivers/vc4/Makefile.sources +++ b/src/gallium/drivers/vc4/Makefile.sources @@ -4,6 +4,7 @@ C_SOURCES := \ vc4_context.c \ vc4_draw.c \ vc4_emit.c \ + vc4_opt_algebraic.c \ vc4_program.c \ vc4_qir.c \ vc4_qpu_emit.c \ diff --git a/src/gallium/drivers/vc4/vc4_opt_algebraic.c b/src/gallium/drivers/vc4/vc4_opt_algebraic.c new file mode 100644 index 00000000000..84e0515d1cf --- /dev/null +++ b/src/gallium/drivers/vc4/vc4_opt_algebraic.c @@ -0,0 +1,77 @@ +/* + * Copyright © 2014 Broadcom + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/** + * @file vc4_opt_algebraic.c + * + * This is the optimization pass for miscellaneous changes to instructions + * where we can simplify the operation by some knowledge about the specific + * operations. + * + * Mostly this will be a matter of turning things into MOVs so that they can + * later be copy-propagated out. + */ + +#include <stdio.h> +#include "vc4_qir.h" + +bool +qir_opt_algebraic(struct qcompile *c) +{ + bool progress = false; + struct simple_node *node; + bool debug = false; + + foreach(node, &c->instructions) { + struct qinst *inst = (struct qinst *)node; + + switch (inst->op) { + case QOP_CMP: + /* Turn "dst = (a < 0) ? b : b)" into "dst = b" */ + if (qir_reg_equals(inst->src[1], inst->src[2])) { + if (debug) { + fprintf(stderr, "optimizing: "); + qir_dump_inst(inst); + fprintf(stderr, "\n"); + } + + inst->op = QOP_MOV; + inst->src[0] = inst->src[1]; + inst->src[1] = c->undef; + progress = true; + + if (debug) { + fprintf(stderr, "to: "); + qir_dump_inst(inst); + fprintf(stderr, "\n"); + } + } + break; + + default: + break; + } + } + + return progress; +} diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c index 993ac41fc11..d1961d691df 100644 --- a/src/gallium/drivers/vc4/vc4_program.c +++ b/src/gallium/drivers/vc4/vc4_program.c @@ -593,14 +593,15 @@ vc4_shader_tgsi_to_qir(struct vc4_compiled_shader *shader, enum qstage stage, break; } + tgsi_parse_free(&trans->parser); + free(trans->temps); + + qir_optimize(c); + if (vc4_debug & VC4_DEBUG_QIR) { fprintf(stderr, "QIR:\n"); qir_dump(c); } - - tgsi_parse_free(&trans->parser); - free(trans->temps); - vc4_generate_code(c); if (vc4_debug & VC4_DEBUG_SHADERDB) { diff --git a/src/gallium/drivers/vc4/vc4_qir.c b/src/gallium/drivers/vc4/vc4_qir.c index b8a8a7ca7dc..308154ff34a 100644 --- a/src/gallium/drivers/vc4/vc4_qir.c +++ b/src/gallium/drivers/vc4/vc4_qir.c @@ -171,6 +171,12 @@ qir_emit(struct qcompile *c, struct qinst *inst) insert_at_tail(&c->instructions, &inst->link); } +bool +qir_reg_equals(struct qreg a, struct qreg b) +{ + return a.file == b.file && a.index == b.index; +} + struct qcompile * qir_compile_init(void) { @@ -198,3 +204,34 @@ qir_get_stage_name(enum qstage stage) return names[stage]; } + +#define OPTPASS(func) \ + do { \ + bool stage_progress = func(c); \ + if (stage_progress) { \ + progress = true; \ + if (print_opt_debug) { \ + fprintf(stderr, \ + "QIR opt pass %2d: %s progress\n", \ + pass, #func); \ + } \ + } \ + } while (0) + +void +qir_optimize(struct qcompile *c) +{ + bool print_opt_debug = false; + int pass = 1; + + while (true) { + bool progress = false; + + OPTPASS(qir_opt_algebraic); + + if (!progress) + break; + + pass++; + } +} diff --git a/src/gallium/drivers/vc4/vc4_qir.h b/src/gallium/drivers/vc4/vc4_qir.h index 76e46ff107f..c0e0f85dede 100644 --- a/src/gallium/drivers/vc4/vc4_qir.h +++ b/src/gallium/drivers/vc4/vc4_qir.h @@ -24,6 +24,7 @@ #ifndef VC4_QIR_H #define VC4_QIR_H +#include <stdbool.h> #include <stdint.h> #include "util/u_simple_list.h" @@ -145,11 +146,15 @@ struct qinst *qir_inst4(enum qop op, struct qreg dst, void qir_emit(struct qcompile *c, struct qinst *inst); struct qreg qir_get_temp(struct qcompile *c); int qir_get_op_nsrc(enum qop qop); +bool qir_reg_equals(struct qreg a, struct qreg b); void qir_dump(struct qcompile *c); void qir_dump_inst(struct qinst *inst); const char *qir_get_stage_name(enum qstage stage); +void qir_optimize(struct qcompile *c); +bool qir_opt_algebraic(struct qcompile *c); + #define QIR_ALU1(name) \ static inline struct qreg \ qir_##name(struct qcompile *c, struct qreg a) \ |