[Mesa-dev] [PATCH 09/10] i965: Add and use is_scheduling_barrier() function.

Matt Turner mattst88 at gmail.com
Tue Mar 8 22:58:25 UTC 2016


On Fri, Mar 4, 2016 at 8:49 PM, Francisco Jerez <currojerez at riseup.net> wrote:
> Matt Turner <mattst88 at gmail.com> writes:
>
>> Though there is a lot of overlap with has_side_effects(), these do mean
>> different things.
>
> Can we do it the other way around and implement is_scheduling_barrier()
> in terms of has_side_effects()?  has_side_effects() seems like the more
> fundamental of the two and because is_scheduling_barrier() is specific
> to the scheduler it would make more sense to keep it static inline in
> brw_schedule_instructions.cpp for the sake of encapsulation.
>
> AFAIUI is_scheduling_barrier() is merely a makeshift approximation at
> missing memory dependency analysis, and in the long term is the wrong
> question to ask (IMHO the right question is "does this instruction have
> an execution dependency with respect to this other?", which implies that
> either of the two instructions has some sort of side effect, but not the
> converse).  has_side_effects() OTOH has a well-defined answer that can
> be answered by looking at the semantics of the instruction alone,
> independent from scheduling heuristics and surrounding compiler
> infrastructure.
>
> I think for the moment I'd make is_scheduling_barrier return true if the
> instruction has side effects, except where you have the guarantee that
> the side-effectful instruction won't have a (non-dataflow related)
> execution dependency with any other instruction of the program, which is
> currently only the case for non-EOT FB_WRITE -- Pretty much has Ken had
> open-coded it in his scheduling changes except for the non-EOT part.

I think your suggestion is to keep has_side_effects() the same and to
wrap it with a static is_scheduling_barrier(). What we have is

bool
backend_instruction::has_side_effects() const
{
   switch (opcode) {
   [list of instructions]
      return true;
   default:
      return false;
   }
}

bool
fs_inst::has_side_effects() const
{
   return this->eot || backend_instruction::has_side_effects();
}

And then in the scheduler,

if ((inst->opcode == FS_OPCODE_PLACEHOLDER_HALT ||
     inst->has_side_effects()) &&
    inst->opcode != FS_OPCODE_FB_WRITE)
   add_barrier_deps(n);

where the FS_OPCODE_FB_WRITE check was added recently to avoid
treating it as a barrier. That seems pretty dirty, because
has_side_effects() returns true for that opcode, so we're just hacking
around that. I noted in my revert that it also had the effect of
making an FB_WRITE with EOT not a barrier.

So, your suggestion is to add another layer on top of that, that
checks inst->eot?

We'd have something like

static inline is_scheduling_barrier(fs_inst *inst)
{
   return inst->opcode == FS_OPCODE_PLACEHOLDER_HALT ||
          (inst->has_side_effects() &&
           inst->opcode != FS_OPCODE_FB_WRITE) ||
          inst->eot;
}

where, tracing through the execution, fs_inst::has_side_effects would
return true because inst->eot, but since opcode is FB_WRITE that
expression would evaluate to false. But then because inst->eot, it'd
evaluate to true.

Doesn't that seem *really* hacky?

Can I go ahead and get someone else's opinion? I doubt you're going to agree.


More information about the mesa-dev mailing list