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