On Sat, Jun 22, 2024 at 01:00:54PM +0200, Georg-Johann Lay wrote:
> Am 22.06.24 um 10:46 schrieb Stefan Schulze Frielinghaus:
> > On Fri, Jun 21, 2024 at 09:50:43PM +0200, Georg-Johann Lay wrote:
> > > 
> > > 
> > > Am 17.06.24 um 21:13 schrieb Stefan Schulze Frielinghaus via Gcc:
> > > > Hi all,
> > > > 
> > > > I'm trying to add an alternative to an existing insn foobar:
> > > > 
> > > > (define_insn "foobar"
> > > >     [(set (match_operand ...)
> > > >           (match_operand ...))]
> > > >     ""
> > > >     "@
> > > >      foo
> > > >      bar
> > > >      #")
> > > > 
> > > > Since the asm output depends on the operands in a non-trivial way which 
> > > > isn't
> > > > easily solved via iterators, I went for a general C function and came 
> > > > up with:
> > > > 
> > > > (define_insn "foobar"
> > > >     [(set (match_operand ...)
> > > >           (match_operand ...))]
> > > >     ""
> > > >     "@
> > > >      foo
> > > >      * return foobar_helper (operands[0], operands[1]);
> > > >      bar
> > > >      #"
> > > >     [(set_attr_alternative "mnemonic" [(const_string "foo")
> > > >                                        (const_string "specialcase")
> > > >                                        (const_string "bar")
> > > >                                        (const_string "unknown")])])
> > > > 
> > > > If there exist a lot of alternatives, then setting the mnemonic 
> > > > attribute like
> > > > this feels repetitive and is error prone.  Furthermore, if there exists 
> > > > no
> > > > other insn with an output template containing foo/bar, then I would 
> > > > have to
> > > > declare foo/bar via
> > > > 
> > > > (define_attr "mnemonic" "...,foo,bar,..." (const_string "unknown"))
> > > > 
> > > > which again is repetitive.  Thus, I'm wondering if there exists a more 
> > > > elegant
> > > > way to achieve this?  Ultimately, I would like to set the mnemonic
> > > > attribute only manually for the alternative which is implemented via C
> > > > code and let the mnemonic attribute for the remaining alternatives be
> > > > set automagically.  Not sure whether this is supported?
> > > > 
> > > > If all fails, I have another idea how to solve this by utilizing 
> > > > PRINT_OPERAND.
> > > > However, now I'm curious whether my current attempt is feasible or not.
> > > > 
> > > > Cheers,
> > > > Stefan
> > > 
> > > It's a bit unclear to me what you are trying to do, as you are not only
> > > adding an insn alternative, but also are adding insn attribute
> > > "mnemonic", which the original insn did not have.
> > 
> > My take so far is that every insn has a mnemonic attribute which is set
> > either explicitly or implicitly (assuming that the target requested this
> > via define_attr "mnemonic" "...").  This is done in function
> > gen_mnemonic_attr() from gensupport.cc.  Thus, something like
> > 
> > (define_insn "foobar"
> >     [(set (match_operand ...)
> >           (match_operand ...))]
> >     ""
> >     "@
> >      foo
> >      bar
> >      #")
> > 
> > and
> > 
> > (define_insn "foobar"
> >     [(set (match_operand ...)
> >           (match_operand ...))]
> >     ""
> >     "@
> >      foo
> >      bar
> >      #"
> >     [(set_attr_alternative "mnemonic" [(const_string "foo")
> >                                        (const_string "bar")
> >                                        (const_string "unknown")])])
> > 
> > should be equivalent.
> > 
> > Of course, the implicit method fails if the pattern is generated via C
> > statements which is way I set it manually in the initial example.  The
> > initial example contained 3 alternatives plus 1 for the generated one.
> > Setting it manually there might be feasible, however, for my actual
> > problem I have an insn with 27 alternatives where I do not want to set
> > and maintain it manually.  A side effect of setting the attribute
> > implicitly is that each mnemonic is added automatically to the mnemonic
> > hash table which I would have to do manually for my 27 alternatives
> > which I would like to avoid, too.
> > 
> > > 
> > > Also, it's unclear how PRINT_OPERAND would help with setting the 
> > > attribute.
> > 
> > For my particular problem I think one can also utilize PRINT_OPERAND
> > which I should have elaborated a bit more but feared to make the example
> > unnecessarily complicated.  The C code
> > 
> >    foobar_helper (operands[0], operands[1])
> > 
> > emits actually an extended mnemonic "specialcase$VAR\t%0,%1" where $VAR
> > can be either A, B, or C.  The extended mnemonic is just syntactic sugar
> > for the base mnemonic "specialcase\t%0,%1,$IMM" which is why we can lie
> > and hard code the mnemonic attribute to specialcase since this won't
> > effect scheduling.  Since the choice which extended mnemonic should be
> > used depends only on operands[1] I thought about rewriting all this into
> > 
> > (define_insn "foobar"
> >     [(set (match_operand ...)
> >           (match_operand ...))]
> >     ""
> >     "@
> >      foo
> >      specialcase\t%0,%1,%X1
> >      bar
> >      #")
> > 
> > Obviously we have to sacrifice the usage of an extended mnemonic but
> > more problematic is that we have to allocate one of those very few codes
> > X just for this insn.  So this doesn't scale either if one has to come
> > up with many different codes.  Furthermore, this only works in my very
> > particular case since I can split the extended mnemonic into a base
> > mnemonic and an immediate which only depends on one operand, i.e., it
> > would fail if it depended on operands[0] and operands[1].
> > 
> > I hope this makes it a bit more clear, if not just let me know.
> > 
> > Cheers,
> > Stefan
> 
> Maybe the following syntax for setting an attribute is a better
> fit in your case?
> 
>   [(set (attr "length")
>         (symbol_ref ("4 + reg_overlap_mentioned_p (operands[0],
> operands[1])")))
> 
> So you can hook in some function that spits out the attributes,
> and it could also provide mnemonics.

I have been thinking about a symbel_ref hook, too.  However, came to the
conclusion that this would involve manual book keeping, too, i.e., I
would have to set and keep in sync in my symbol_ref expression for my 27
alternative insn all 26 static mnemonics manually only in order to
generate the 27th mnemonic.  Maybe my case is a bit too special.
Ultimately, I was hoping for something like

(define_insn "foobar"
  [(set (match_operand ...)
        (match_operand ...))]
  ""
  "@
   foo
   * return foobar_helper (operands[0], operands[1], insn);
   bar
   #")

where the function which generates the mnemonic is also able to set the
mnemonic attribute e.g. by passing the current insn reference as a
parameter.  Then function gen_mnemonic_attr() could deal with
alternatives 0 and 2 as usual and alternative 1 would have been dealt
with via C code.  However, the more I dig into the generation pipeline I
realize that this is not easily possible.  Function foobar_helper is
called during the final pass where scheduling is already done.  Too late
to set the mnemonic attribute.

Cheers,
Stefan

Reply via email to