<p dir="ltr"><br>
On Dec 11, 2015 5:44 AM, "Francisco Jerez" <<a href="mailto:currojerez@riseup.net">currojerez@riseup.net</a>> wrote:<br>
><br>
> Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">jason@jlekstrand.net</a>> writes:<br>
><br>
> > On Dec 10, 2015 6:58 AM, "Francisco Jerez" <<a href="mailto:currojerez@riseup.net">currojerez@riseup.net</a>> wrote:<br>
> >><br>
> >> Jason Ekstrand <<a href="mailto:jason@jlekstrand.net">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.<br>
> ><br>
> > Yes and, mostly, no.  Yes, you can put an indirect on almost anything but<br>
> > it has substantial restrictions:<br>
> ><br>
> Yes, I'm aware of the restrictions of indirect addressing on Gen<br>
> hardware.  The fact that reladdr can represent addressing modes which<br>
> aren't directly implemented in the hardware doesn't invalidate the<br>
> abstraction, nor implies that optimization and translation passes must<br>
> be made aware of such restrictions.  It just means that our abstraction<br>
> is a superset of the hardware indirect addressing scheme, which is fine<br>
> given a lowering pass to convert indirect addressing into a legal form.<br>
><br>
> Your proposal instead goes the opposite direction and replaces the<br>
> preexisting abstraction with a new abstraction which can only represent<br>
> a tiny subset of the functionality of hardware instructions, which I<br>
> don't think is acceptable for a low-level IR.<br>
><br>
> > 1) Destination indirects must be uniform (I'm only 95% sure this is the<br>
> > case)<br>
> ><br>
> > 2) We only have 8 address subregisters on HSW and prior and 16 on BDW which<br>
> > means:<br>
> ><br>
><br>
> That's the kind of thing that SIMD lowering would be able to take care<br>
> of easily.</p>
<p dir="ltr">Yes, and we use it for MOV_INDIRECT.</p>
<p dir="ltr">> >     a) All indirects must be uniform OR<br>
> ><br>
> >     b) We must be on Broadwell, have only two indirects, and split the<br>
> > instruction OR<br>
> ><br>
> >     c) We can only have one indirect (and still split the instruction on<br>
> > HSW)<br>
> ><br>
> > So, yes, "everthing can be uniform", but not in real life.<br>
><br>
> > The reladdr abstraction, while maybe ok for a high-level IR, doesn't<br>
> > accurately represent the hardware at all because it can't represent<br>
> > any of the restrictions without piles of helper functions and checks.<br>
><br>
> The reladdr abstraction can represent the full flexibility of the<br>
> hardware, while MOV_INDIRECT cannot, that makes reladdr a more accurate<br>
> low-level representation of the program.  For that reason I'd argue the<br>
> exact opposite: MOV_INDIRECT would be a great abstraction and a welcome<br>
> simplification for a high-level IR (e.g. NIR), in which nothing is lost<br>
> by sacrificing the expressiveness of individual instructions in favour<br>
> of instruction composition, because the back-end can always combine<br>
> multiple high-level instructions into a single low-level instruction<br>
> where the hardware ISA allows, as long as the low-level IR is able to<br>
> represent the full functionality of hardware instructions (IOW the<br>
> mapping between low-level IR instructions and hardware instructions is<br>
> surjective), which is further from being the case after this series.</p>
<p dir="ltr">Flexibility and expressiveness isn't always a good thing.  Yes, reladdr is more "expressive", but it's not getting used because that expressiveness makes it a pain.  You could say it is getting used, but it's current use is just an intermediate to something less expressive than MOV_INDIRECT.  In that sense, we are expressing *more* with MOV_INDIRECT than we were before since we are also expressing in directing on registers and not just pull constants.</p>
<p dir="ltr">Also, while reladdr is "expressive", it doesn't actually represent the hardware.  If we wanted that, we would expose the address register file (which I did consider doing).  However, that comes with it's own set of issues.</p>
<p dir="ltr">> > The MOV_INDIRECT instruction, on the other hand, is something we can<br>
> > always do because it falls in the "one indirect" case above.  The<br>
> > reladdr abstraction also suffers from the recursive reladdr problem<br>
> > which MOV_INDIRECT neatly side-steps by design.<br>
><br>
> I don't think the reladdr "problem" requires any fundamentally more<br>
> difficult logic in optimization passes than what you need in order to<br>
> handle MOV_INDIRECT instructions reasonably.</p>
<p dir="ltr">No, it just requires rewriting them because iterating over sources just became recursive.</p>
<p dir="ltr">> > We can't even use reladdr past initial NIR -> FS stage because none of<br>
> > the optimization passes know what to do with it (and no, I don't want<br>
> > to add reladdr support to any of them).<br>
> ><br>
> > Yes, removing reladdr makes the IR "less expressive", but we're not really<br>
> > using that expressiveness nor is reladdr the abstraction we want.  If we<br>
> > want to start taking more advantage of relative addressing in the future,<br>
> > we can come up with a better abstraction then.<br>
> ><br>
> > --Jason<br>
> ><br>
> >> > ---<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<br>
> > 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<br>
> > *be_inst, FILE *file)<br>
> >> >           break;<br>
> >> >        case UNIFORM:<br>
> >> >           fprintf(file, "u%d", inst->src[i].nr +<br>
> > 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 @@<br>
> > 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<br>
> > 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">mesa-dev@lists.freedesktop.org</a><br>
> >> > <a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</p>