<div dir="ltr"><p dir="ltr"><br>
On Dec 10, 2015 6:58 AM, "Francisco Jerez" <<a href="mailto:currojerez@riseup.net" target="_blank">currojerez@riseup.net</a>> wrote:<br>
><br>
> Jason Ekstrand <<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>> writes:<br>
><br>
> > We aren't using it anymore.<br>
><br>
> It seems useful to me to be able to represent indirect access as part of<br>
> any instruction source or destination register.<br>
><br>
> The following:<br>
><br>
> | mov_indirect g0, g1, a0<br>
> | foo g2, g0<br>
><br>
> and the converse case with indirect destination offset (which you don't<br>
> seem to represent currently) can be implemented by the hardware more<br>
> efficiently using a single instruction in certain cases.  The current IR<br>
> is able to represent what the hardware can do, but supporting the<br>
> MOV_INDIRECT instruction only would force us to keep the indirection<br>
> separate from the instruction that uses it, so it seems like a less<br>
> expressive representation to me than the current approach, unless you're<br>
> willing to add _INDIRECT variants of most hardware opcodes.</p>
<p dir="ltr">Yes and, mostly, no.  Yes, you can put an indirect on almost anything but it has substantial restrictions:</p>
<p dir="ltr"> 1) Destination indirects must be uniform (I'm only 95% sure this is the case)</p>
<p dir="ltr"> 2) We only have 8 address subregisters on HSW and prior and 16 on BDW which means:</p>
<p dir="ltr">    a) All indirects must be uniform OR<br></p><p>    b) We must be on Broadwell, have only two indirects, and split the instruction OR</p><p>    c) We can only have one indirect (and still split the instruction on HSW)</p><p>So, yes, "everthing can be uniform", but not in real life.  The reladdr abstraction, while maybe ok for a high-level IR, doesn't accurately represent the hardware at all because it can't represent any of the restrictions without piles of helper functions and checks.  The MOV_INDIRECT instruction, on the other hand, is something we can always do because it falls in the "one indirect" case above.  The reladdr abstraction also suffers from the recursive reladdr problem which MOV_INDIRECT neatly side-steps by design.  We can't even use reladdr past initial NIR -> FS stage because none of the optimization passes know what to do with it (and no, I don't want to add reladdr support to any of them).</p><p>Yes, removing reladdr makes the IR "less expressive", but we're not really using that expressiveness nor is reladdr the abstraction we want.  If we want to start taking more advantage of relative addressing in the future, we can come up with a better abstraction then.</p><p>--Jason<br></p><p dir="ltr">> > ---<br>
> >  src/mesa/drivers/dri/i965/brw_fs.cpp  | 7 +------<br>
> >  src/mesa/drivers/dri/i965/brw_ir_fs.h | 5 +----<br>
> >  2 files changed, 2 insertions(+), 10 deletions(-)<br>
> ><br>
> > diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp<br>
> > index 7cc03c5..786c5fb 100644<br>
> > --- a/src/mesa/drivers/dri/i965/brw_fs.cpp<br>
> > +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp<br>
> > @@ -433,7 +433,6 @@ fs_reg::fs_reg(struct ::brw_reg reg) :<br>
> >  {<br>
> >     this->reg_offset = 0;<br>
> >     this->subreg_offset = 0;<br>
> > -   this->reladdr = NULL;<br>
> >     this->stride = 1;<br>
> >     if (this->file == IMM &&<br>
> >         (this->type != BRW_REGISTER_TYPE_V &&<br>
> > @@ -448,7 +447,6 @@ fs_reg::equals(const fs_reg &r) const<br>
> >  {<br>
> >     return (this->backend_reg::equals(r) &&<br>
> >             subreg_offset == r.subreg_offset &&<br>
> > -           !reladdr && !r.reladdr &&<br>
> >             stride == r.stride);<br>
> >  }<br>
> ><br>
> > @@ -4716,9 +4714,7 @@ fs_visitor::dump_instruction(backend_instruction *be_inst, FILE *file)<br>
> >           break;<br>
> >        case UNIFORM:<br>
> >           fprintf(file, "u%d", inst->src[i].nr + inst->src[i].reg_offset);<br>
> > -         if (inst->src[i].reladdr) {<br>
> > -            fprintf(file, "+reladdr");<br>
> > -         } else if (inst->src[i].subreg_offset) {<br>
> > +         if (inst->src[i].subreg_offset) {<br>
> >              fprintf(file, "+%d.%d", inst->src[i].reg_offset,<br>
> >                      inst->src[i].subreg_offset);<br>
> >           }<br>
> > @@ -4829,7 +4825,6 @@ fs_visitor::get_instruction_generating_reg(fs_inst *start,<br>
> >  {<br>
> >     if (end == start ||<br>
> >         end->is_partial_write() ||<br>
> > -       reg.reladdr ||<br>
> >         !reg.equals(end->dst)) {<br>
> >        return NULL;<br>
> >     } else {<br>
> > diff --git a/src/mesa/drivers/dri/i965/brw_ir_fs.h b/src/mesa/drivers/dri/i965/brw_ir_fs.h<br>
> > index c3eec2e..e4f20f4 100644<br>
> > --- a/src/mesa/drivers/dri/i965/brw_ir_fs.h<br>
> > +++ b/src/mesa/drivers/dri/i965/brw_ir_fs.h<br>
> > @@ -58,8 +58,6 @@ public:<br>
> >      */<br>
> >     int subreg_offset;<br>
> ><br>
> > -   fs_reg *reladdr;<br>
> > -<br>
> >     /** Register region horizontal stride */<br>
> >     uint8_t stride;<br>
> >  };<br>
> > @@ -136,8 +134,7 @@ component(fs_reg reg, unsigned idx)<br>
> >  static inline bool<br>
> >  is_uniform(const fs_reg &reg)<br>
> >  {<br>
> > -   return (reg.stride == 0 || reg.is_null()) &&<br>
> > -          (!reg.reladdr || is_uniform(*reg.reladdr));<br>
> > +   return (reg.stride == 0 || reg.is_null());<br>
> >  }<br>
> ><br>
> >  /**<br>
> > --<br>
> > 2.5.0.400.gff86faf<br>
> ><br>
> > _______________________________________________<br>
> > mesa-dev mailing list<br>
> > <a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
> > <a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</p>
</div>