Module: Mesa
Branch: master
Commit: 3e5f9789d653726d2602de67e996b73a813ebc2e
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=3e5f9789d653726d2602de67e996b73a813ebc2e

Author: Tom Stellard <tstel...@gmail.com>
Date:   Sat Nov 13 17:12:58 2010 -0800

r300/compiler: Fix instruction scheduling within IF blocks

Reads of registers that where not written to within the same block were
not being tracked.  So in a situations like this:
0: IF
1: ADD t0, t1, t2
2: MOV t2, t1

Instruction 2 didn't know that instruction 1 read from t2, so
in some cases instruction 2 was being scheduled before instruction 1.

NOTE: This is a candidate for the 7.9 branch.

---

 .../dri/r300/compiler/radeon_pair_schedule.c       |   37 +++++++++++---------
 1 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c 
b/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c
index 553e9dc..f760a90 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c
@@ -126,15 +126,6 @@ static struct reg_value ** get_reg_valuep(struct 
schedule_state * s,
        return &s->Temporary[index].Values[chan];
 }
 
-static struct reg_value * get_reg_value(struct schedule_state * s,
-               rc_register_file file, unsigned int index, unsigned int chan)
-{
-       struct reg_value ** pv = get_reg_valuep(s, file, index, chan);
-       if (!pv)
-               return 0;
-       return *pv;
-}
-
 static void add_inst_to_list(struct schedule_instruction ** list, struct 
schedule_instruction * inst)
 {
        inst->NextReady = *list;
@@ -591,13 +582,13 @@ static void scan_read(void * data, struct rc_instruction 
* inst,
                rc_register_file file, unsigned int index, unsigned int chan)
 {
        struct schedule_state * s = data;
-       struct reg_value * v = get_reg_value(s, file, index, chan);
+       struct reg_value ** v = get_reg_valuep(s, file, index, chan);
        struct reg_value_reader * reader;
 
        if (!v)
                return;
 
-       if (v->Writer == s->Current) {
+       if (*v && (*v)->Writer == s->Current) {
                /* The instruction reads and writes to a register component.
                 * In this case, we only want to increment dependencies by one.
                 */
@@ -608,16 +599,28 @@ static void scan_read(void * data, struct rc_instruction 
* inst,
 
        reader = memory_pool_malloc(&s->C->Pool, sizeof(*reader));
        reader->Reader = s->Current;
-       reader->Next = v->Readers;
-       v->Readers = reader;
-       v->NumReaders++;
-
-       s->Current->NumDependencies++;
+       if (!*v) {
+               /* In this situation, the instruction reads from a register
+                * that hasn't been written to or read from in the current
+                * block. */
+               *v = memory_pool_malloc(&s->C->Pool, sizeof(struct reg_value));
+               memset(*v, 0, sizeof(struct reg_value));
+               (*v)->Readers = reader;
+       } else {
+               reader->Next = (*v)->Readers;
+               (*v)->Readers = reader;
+               /* Only update the current instruction's dependencies if the
+                * register it reads from has been written to in this block. */
+               if ((*v)->Writer) {
+                       s->Current->NumDependencies++;
+               }
+       }
+       (*v)->NumReaders++;
 
        if (s->Current->NumReadValues >= 12) {
                rc_error(s->C, "%s: NumReadValues overflow\n", __FUNCTION__);
        } else {
-               s->Current->ReadValues[s->Current->NumReadValues++] = v;
+               s->Current->ReadValues[s->Current->NumReadValues++] = *v;
        }
 }
 

_______________________________________________
mesa-commit mailing list
mesa-commit@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to