summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/freedreno
diff options
context:
space:
mode:
authorRob Clark <robclark@freedesktop.org>2016-04-05 12:39:47 -0400
committerRob Clark <robclark@freedesktop.org>2016-04-05 15:04:25 -0400
commitf9cdbf44054009122fcc16c887fb90ccc33b52c9 (patch)
tree592fcae6b07a4a68f22ef6ddee239f0d9c2aceec /src/gallium/drivers/freedreno
parent0daab9878d2b96356cf667591a2c877d912be52d (diff)
downloadexternal_mesa3d-f9cdbf44054009122fcc16c887fb90ccc33b52c9.zip
external_mesa3d-f9cdbf44054009122fcc16c887fb90ccc33b52c9.tar.gz
external_mesa3d-f9cdbf44054009122fcc16c887fb90ccc33b52c9.tar.bz2
freedreno/ir3: eliminate unnecessary absneg's
The frontend inserts (abs) and (neg)'s to convert between NIR boolean (~0/0) and native boolean (1/0). So we'd end up with things like: cmps.s.ge r1.x, ... absneg.s r1.x, (neg)r1.x absneg.s r1.x, (abs)r1.x sel.b32 r2.x, r0.x, r1.x, r0.y The (neg) already gets collapsed due to the following (abs). Now by realizing that r1.x comes from a cmps.s instruction, we can drop the (abs) as well. Signed-off-by: Rob Clark <robclark@freedesktop.org>
Diffstat (limited to 'src/gallium/drivers/freedreno')
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3.h12
-rw-r--r--src/gallium/drivers/freedreno/ir3/ir3_cp.c17
2 files changed, 26 insertions, 3 deletions
diff --git a/src/gallium/drivers/freedreno/ir3/ir3.h b/src/gallium/drivers/freedreno/ir3/ir3.h
index 23e43b1..3859f6a 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3.h
+++ b/src/gallium/drivers/freedreno/ir3/ir3.h
@@ -628,6 +628,18 @@ static inline bool is_input(struct ir3_instruction *instr)
}
}
+static inline bool is_bool(struct ir3_instruction *instr)
+{
+ switch (instr->opc) {
+ case OPC_CMPS_F:
+ case OPC_CMPS_S:
+ case OPC_CMPS_U:
+ return true;
+ default:
+ return false;
+ }
+}
+
static inline bool is_meta(struct ir3_instruction *instr)
{
/* TODO how should we count PHI (and maybe fan-in/out) which
diff --git a/src/gallium/drivers/freedreno/ir3/ir3_cp.c b/src/gallium/drivers/freedreno/ir3/ir3_cp.c
index f032f0b..6037bec 100644
--- a/src/gallium/drivers/freedreno/ir3/ir3_cp.c
+++ b/src/gallium/drivers/freedreno/ir3/ir3_cp.c
@@ -189,8 +189,10 @@ static bool valid_flags(struct ir3_instruction *instr, unsigned n,
/* propagate register flags from src to dst.. negates need special
* handling to cancel each other out.
*/
-static void combine_flags(unsigned *dstflags, unsigned srcflags)
+static void combine_flags(unsigned *dstflags, struct ir3_instruction *src)
{
+ unsigned srcflags = src->regs[1]->flags;
+
/* if what we are combining into already has (abs) flags,
* we can drop (neg) from src:
*/
@@ -216,6 +218,15 @@ static void combine_flags(unsigned *dstflags, unsigned srcflags)
*dstflags |= srcflags & IR3_REG_IMMED;
*dstflags |= srcflags & IR3_REG_RELATIV;
*dstflags |= srcflags & IR3_REG_ARRAY;
+
+ /* if src of the src is boolean we can drop the (abs) since we know
+ * the source value is already a postitive integer. This cleans
+ * up the absnegs that get inserted when converting between nir and
+ * native boolean (see ir3_b2n/n2b)
+ */
+ struct ir3_instruction *srcsrc = ssa(src->regs[1]);
+ if (srcsrc && is_bool(srcsrc))
+ *dstflags &= ~IR3_REG_SABS;
}
/**
@@ -241,7 +252,7 @@ reg_cp(struct ir3_instruction *instr, struct ir3_register *reg, unsigned n)
struct ir3_register *src_reg = src->regs[1];
unsigned new_flags = reg->flags;
- combine_flags(&new_flags, src_reg->flags);
+ combine_flags(&new_flags, src);
if (valid_flags(instr, n, new_flags)) {
if (new_flags & IR3_REG_ARRAY) {
@@ -262,7 +273,7 @@ reg_cp(struct ir3_instruction *instr, struct ir3_register *reg, unsigned n)
struct ir3_register *src_reg = src->regs[1];
unsigned new_flags = reg->flags;
- combine_flags(&new_flags, src_reg->flags);
+ combine_flags(&new_flags, src);
if (!valid_flags(instr, n, new_flags)) {
/* special case for "normal" mad instructions, we can