freedreno/ir3: fix RA issue with fanin
authorRob Clark <robclark@freedesktop.org>
Sun, 28 Jun 2015 15:13:58 +0000 (11:13 -0400)
committerRob Clark <robclark@freedesktop.org>
Tue, 30 Jun 2015 16:13:44 +0000 (12:13 -0400)
The fanin source could be grouped, for example with shaders like:

    VERT
    DCL IN[0]
    DCL IN[1]
    DCL OUT[0], POSITION
    DCL OUT[1], GENERIC[9]
    DCL SAMP[0]
    DCL SVIEW[0], 2D, FLOAT
    DCL TEMP[0], LOCAL
      0: MOV TEMP[0].xy, IN[1].xyyy
      1: MOV TEMP[0].w, IN[1].wwww
      2: TXF TEMP[0], TEMP[0], SAMP[0], 2D
      3: MOV OUT[1], TEMP[0]
      4: MOV OUT[0], IN[0]
      5: END

The second arg to the isaml is IN[1].w, so we need to look at the fanin
source to get the correct offset.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
src/gallium/drivers/freedreno/ir3/ir3_ra.c

index ee610c7d01e0eca98e046c2d610267f7288e84d3..9f6ff12a119616d4f805746a6bc2c9a1d949b113 100644 (file)
@@ -320,19 +320,25 @@ get_definer(struct ir3_instruction *instr, int *sz, int *off)
                 * and fanin..  that probably doesn't happen currently.
                 */
                struct ir3_register *src;
+               int dsz, doff;
 
                /* note: don't use foreach_ssa_src as this gets called once
                 * while assigning regs (which clears SSA flag)
                 */
-               foreach_src(src, instr) {
+               foreach_src_n(src, n, instr) {
+                       struct ir3_instruction *dd;
                        if (!src->instr)
                                continue;
-                       if ((!d) || (src->instr->ip < d->ip))
-                               d = src->instr;
+
+                       dd = get_definer(src->instr, &dsz, &doff);
+
+                       if ((!d) || (dd->ip < d->ip)) {
+                               d = dd;
+                               *sz = dsz;
+                               *off = doff - n;
+                       }
                }
 
-               *sz = instr->regs_count - 1;
-               *off = 0;
 
        } else if (instr->cp.right || instr->cp.left) {
                /* covers also the meta:fo case, which ends up w/ single
@@ -447,6 +453,10 @@ ra_block_name_instructions(struct ir3_ra_ctx *ctx, struct ir3_block *block)
                struct ir3_instruction *defn;
                int cls, sz, off;
 
+#ifdef DEBUG
+               instr->name = ~0;
+#endif
+
                ctx->instr_cnt++;
 
                if (instr->regs_count == 0)