diff options
author | Alyssa Rosenzweig <[email protected]> | 2019-09-18 08:26:30 -0400 |
---|---|---|
committer | Alyssa Rosenzweig <[email protected]> | 2019-09-30 08:40:13 -0400 |
commit | 826fd7308bba1fcd4fd4c94c798f4f45a741e657 (patch) | |
tree | 8de238c09aa2ff2281c902b94367241b472bbfd2 /src/panfrost | |
parent | f48038b588df726cd34f5d15e999498310da7432 (diff) |
pan/midgard: Add mir_choose_instruction stub
In the future, this routine will implement the core scheduling logic to
decide which instruction out of the worklist will be scheduled next, in
a way that minimizes cycle count and register pressure.
In the present, we are more interested in replicating in-order
scheduling with the much-more-powerful out-of-order model. So rather
than discriminating by a register pressure estimate, we simply choose
the latest possible instruction in the worklist.
Signed-off-by: Alyssa Rosenzweig <[email protected]>
Diffstat (limited to 'src/panfrost')
-rw-r--r-- | src/panfrost/midgard/midgard_schedule.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/panfrost/midgard/midgard_schedule.c b/src/panfrost/midgard/midgard_schedule.c index aff93399a80..046480ba2ac 100644 --- a/src/panfrost/midgard/midgard_schedule.c +++ b/src/panfrost/midgard/midgard_schedule.c @@ -767,6 +767,61 @@ mir_initialize_worklist(BITSET_WORD *worklist, midgard_instruction **instruction } } +/* While scheduling, we need to choose instructions satisfying certain + * criteria. As we schedule backwards, we choose the *last* instruction in the + * worklist to simulate in-order scheduling. Chosen instructions must satisfy a + * given predicate. */ + +struct midgard_predicate { + /* TAG or ~0 for dont-care */ + unsigned tag; + + /* True if we want to pop off the chosen instruction */ + bool destructive; +}; + +static midgard_instruction * +mir_choose_instruction( + midgard_instruction **instructions, + BITSET_WORD *worklist, unsigned count, + struct midgard_predicate *predicate) +{ + /* Parse the predicate */ + unsigned tag = predicate->tag; + + /* Iterate to find the best instruction satisfying the predicate */ + unsigned i; + BITSET_WORD tmp; + + signed best_index = -1; + + BITSET_FOREACH_SET(i, tmp, worklist, count) { + if (tag != ~0 && instructions[i]->type != tag) + continue; + + /* Simulate in-order scheduling */ + if ((signed) i < best_index) + continue; + + best_index = i; + } + + + /* Did we find anything? */ + + if (best_index < 0) + return NULL; + + /* If we found something, remove it from the worklist */ + assert(best_index < count); + + if (predicate->destructive) { + BITSET_CLEAR(worklist, best_index); + } + + return instructions[best_index]; +} + /* Schedule a single block by iterating its instruction to create bundles. * While we go, tally about the bundle sizes to compute the block size. */ |