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