Message ID | 4F35B27A.9020907@redhat.com |
---|---|
State | New |
Headers | show |
On Sat, Feb 11, 2012 at 1:12 AM, Richard Henderson <rth@redhat.com> wrote: > Seeing as how Uros is starting to go down the path of cleaning up the > flags handling for x86, I thought I'd go ahead and knock up the idea > that I've been tossing around to help automate the process of building > patterns that match both clobbering the flags and setting the flags to > a comparison. > > This is far from complete, but it at least shows the direction. > > What I know is missing off the top of my head are: > > (0) Documentation in some .texi file; atm there's only what's in rtl.def. > > (1) Generate (clobber (reg flags)) from genemit, should this construct > be used in a named insn pattern. > > (2) Can't be usefully used with define_insn_and_split, and no way to tell. > This problem should simply be documented in the .texi file as user error. > > (3) Can't be used for x86 add patterns, as the "clobber" version wants the > freedom to use "lea" and the "set flags" version cannot. And there are > different sets of constraints if lea may be used or not. > > What would be nice, however, is exposing the targetm.cc_modes_compatible > thing in such a way that the x86 add patterns could use that, for the > separate insn that does do the set flags. > > Exposing the targetm.cc_modes_compatible thing separately might also > clean up some of the evil magic in genrecog.c too. > > Comments? To see if I understand what a cc0 port conversion would look like with "match_flags", I tried to apply this magic to convert one of the pet ports, the mighty pdp11. The pdp11 port doesn't have any define_insn_and_splits, so I didn't run into the problem you mentioned in (2). What is the problem here? I suppose it has to do with finding out what the flags setter is after the split? If so, then couldn't that be resolved with some rules about how the post-split patterns should be constructed? Other than that: To convert a port, there is still a lot of work to be done to define and handle the various CC modes properly (well, not for the pdp11, because it writes out >1 insn for most define_insns), but it is great not having to define all the pairs of clobber-flags and set-flags insns. At least, I didn't end up rewriting the complete .md file. It was relatively easy. Less book-keeping involved, etc. Hope this goes in for GCC 4.8. Ciao! Steven
On 02/14/2012 12:52 AM, Steven Bosscher wrote: > Other than that: To convert a port, there is still a lot of work to be > done to define and handle the various CC modes properly (well, not for > the pdp11, because it writes out >1 insn for most define_insns), but > it is great not having to define all the pairs of clobber-flags and > set-flags insns. At least, I didn't end up rewriting the complete .md > file. It was relatively easy. Less book-keeping involved, etc. And where's the patch? :) Paolo
On Fri, 10 Feb 2012, Richard Henderson wrote: > Seeing as how Uros is starting to go down the path of cleaning up the > flags handling for x86, I thought I'd go ahead and knock up the idea > that I've been tossing around to help automate the process of building > patterns that match both clobbering the flags and setting the flags to > a comparison. Sometimes the destination too unless there's overlap, but I don't know how often that matters. > This is far from complete, but it at least shows the direction. Yes, nice! > What I know is missing off the top of my head are: > (2) Can't be usefully used with define_insn_and_split, and no way to tell. > This problem should simply be documented in the .texi file as user error. Not sure I see the problem or the impact of the absence. Would it help if there was a way to match_dup the clobber/set? Maybe as a match_op_flags, the same as match_flags but with the first argument being an assigning operand number. You probably wouldn't want to use this very often.) > (3) Can't be used for x86 add patterns, as the "clobber" version wants the > freedom to use "lea" and the "set flags" version cannot. And there are > different sets of constraints if lea may be used or not. Other targets too, but as it's warty for x86 I hope eventually this'll see improvement... > Comments? Er... very interesting! (The kind of patch you want to play around with to have any further insightful comments.) So I can use match_{operand,whatever} in the second, optional operand to match_flags? No, wait, no use to have anything but a match_dup, hm. I don't see where it'd make sense to have anything else but the default, absent argument. Example? brgds, H-P
On 02/22/12 17:16, Hans-Peter Nilsson wrote: >> What I know is missing off the top of my head are: > >> (2) Can't be usefully used with define_insn_and_split, and no way to tell. >> This problem should simply be documented in the .texi file as user error. > > Not sure I see the problem or the impact of the absence. Would > it help if there was a way to match_dup the clobber/set? Maybe > as a match_op_flags, the same as match_flags but with the first > argument being an assigning operand number. You probably > wouldn't want to use this very often.) Yes, one could probably have some use of it with a split, if the match_flags is assigned an operand number. You'd have to be very careful about preserving the contents of the compare if you adjust the other instruction data at all... I've also thought of using the operand number as a quick way to test whether the flags are actually live. I.e. if (GET_CODE (operands[n]) == CLOBBER) within the split or the C output template. r~
On Sat, Feb 11, 2012 at 1:12 AM, Richard Henderson <rth@redhat.com> wrote: > Seeing as how Uros is starting to go down the path of cleaning up the > flags handling for x86, I thought I'd go ahead and knock up the idea > that I've been tossing around to help automate the process of building > patterns that match both clobbering the flags and setting the flags to > a comparison. > > This is far from complete, but it at least shows the direction. > > What I know is missing off the top of my head are: > > (0) Documentation in some .texi file; atm there's only what's in rtl.def. > > (1) Generate (clobber (reg flags)) from genemit, should this construct > be used in a named insn pattern. > > (2) Can't be usefully used with define_insn_and_split, and no way to tell. > This problem should simply be documented in the .texi file as user error. > > (3) Can't be used for x86 add patterns, as the "clobber" version wants the > freedom to use "lea" and the "set flags" version cannot. And there are > different sets of constraints if lea may be used or not. > > What would be nice, however, is exposing the targetm.cc_modes_compatible > thing in such a way that the x86 add patterns could use that, for the > separate insn that does do the set flags. > > Exposing the targetm.cc_modes_compatible thing separately might also > clean up some of the evil magic in genrecog.c too. > > Comments? Hello Richard, Are you still working on this for GCC 4.8? Ciao! Steven
On 05/17/12 10:59, Steven Bosscher wrote:
> Are you still working on this for GCC 4.8?
Not actively.
r~
diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi index 7e9e535..b0261e3 100644 --- a/gcc/doc/rtl.texi +++ b/gcc/doc/rtl.texi @@ -250,6 +250,12 @@ core, @samp{S} is equivalent to @samp{s}, but when the object is read, from an @samp{md} file, the string value of this operand may be omitted. An omitted string is taken to be the null string. +@item v +@samp{v} indicates an expression which is optional. In the RTL objects +in core, @samp{v} is equivalent to @samp{e}, but when the object is +read from an @samp{md} file, the expression for this operand may be +omitted. + @item V @samp{V} indicates a vector which is optional. In the RTL objects in core, @samp{V} is equivalent to @samp{E}, but when the object is read diff --git a/gcc/gengenrtl.c b/gcc/gengenrtl.c index 67688ac..99765a7 100644 --- a/gcc/gengenrtl.c +++ b/gcc/gengenrtl.c @@ -58,10 +58,10 @@ type_from_format (int c) case 's': return "const char *"; - case 'e': case 'u': + case 'e': case 'u': case 'v': return "rtx "; - case 'E': + case 'E': case 'V': return "rtvec "; case 't': return "union tree_node *"; /* tree - typedef not available */ @@ -88,10 +88,10 @@ accessor_from_format (int c) case 's': return "XSTR"; - case 'e': case 'u': + case 'e': case 'u': case 'v': return "XEXP"; - case 'E': + case 'E': case 'V': return "XVEC"; case 't': diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c index 9bd8621..a83cb4f 100644 --- a/gcc/print-rtl.c +++ b/gcc/print-rtl.c @@ -361,7 +361,7 @@ print_rtx (const_rtx in_rtx) } break; - case 'e': + case 'e': case 'v': do_e: indent += 2; if (i == 7 && INSN_P (in_rtx)) diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c index 1402c54..a5d4ccb 100644 --- a/gcc/read-rtl.c +++ b/gcc/read-rtl.c @@ -363,6 +363,7 @@ apply_iterator_to_rtx (rtx original, struct mapping *iterator, int value, XSTR (x, i) = apply_iterator_to_string (XSTR (x, i), iterator, value); break; + case 'v': case 'e': XEXP (x, i) = apply_iterator_to_rtx (XEXP (x, i), iterator, value, mode_maps, unknown_mode_attr); @@ -406,6 +407,7 @@ uses_iterator_p (rtx x, struct mapping *iterator) for (i = 0; format_ptr[i] != 0; i++) switch (format_ptr[i]) { + case 'v': case 'e': if (uses_iterator_p (XEXP (x, i), iterator)) return true; @@ -929,6 +931,18 @@ read_rtx_code (const char *code_name, struct map_value **mode_maps) case '0': break; + case 'v': + /* 'v' is an optional expression: if a closeparen follows, + just store NULL for this element. */ + c = read_skip_spaces (); + unread_char (c); + if (c == ')') + { + XEXP (return_rtx, i) = NULL; + break; + } + /* FALLTHRU */ + case 'e': case 'u': XEXP (return_rtx, i) = read_nested_rtx (mode_maps); @@ -944,7 +958,7 @@ read_rtx_code (const char *code_name, struct map_value **mode_maps) XVEC (return_rtx, i) = 0; break; } - /* Now process the vector. */ + /* FALLTHRU */ case 'E': {