* Clobber REG_CC only for some constraint alternatives? @ 2020-08-14 11:16 Senthil Kumar Selvaraj 2020-08-14 15:32 ` Matt Wette ` (3 more replies) 0 siblings, 4 replies; 32+ messages in thread From: Senthil Kumar Selvaraj @ 2020-08-14 11:16 UTC (permalink / raw) To: gcc; +Cc: ebotcazou, law Hi, I'm working on porting AVR to MODE_CC, and there are quite a few patterns that clobber the condition code reg only for certain constraint alternatives. For e.g., (define_insn "mov<mode>_insn" [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r") (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))] "register_operand (operands[0], <MODE>mode) || reg_or_0_operand (operands[1], <MODE>mode)" { return output_movqi (insn, operands, NULL); } [(set_attr "length" "1,1,5,5,1,1,4") (set_attr "adjust_len" "mov8") (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")]) As you can deduce from the (set_attr "cc" ..), only constraint alternatives 0,2,3 and 6 clobber CC - others leave it unchanged. My first version of the port adds a post-reload splitter that adds a (clobber (reg:CC REG_CC)) unconditionally, and it appears to work. If I do want to add the clobber conditionally, would something like the below be a good way to do it (get_cc_reg_clobber_rtx returns either const0_rtx or cc_reg_rtx based on get_attr_cc (insn))? Or is there a better/cleaner way? (define_insn_and_split "mov<mode>_insn" [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r") (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))] "register_operand (operands[0], <MODE>mode) || reg_or_0_operand (operands[1], <MODE>mode)" "#" "&& reload_completed" [(parallel [(set (match_dup 0) (match_dup 1)) (clobber (match_dup 2))])] { operands[2] = get_cc_reg_clobber_rtx (curr_insn); } [(set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")]) (define_insn "*mov<mode>_insn_clobber_flags" [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,Qm ,r ,*r") (match_operand:ALL1 1 "nox_general_operand" "r Y00,r Y00,Qm,i")) (clobber (reg:CC REG_CC))] "(register_operand (operands[0], <MODE>mode) || reg_or_0_operand (operands[1], <MODE>mode)) && reload_completed" { return output_movqi (insn, operands, NULL); } [(set_attr "length" "1,5,5,4") (set_attr "adjust_len" "mov8")]) (define_insn "*mov<mode>_insn_noclobber_flags" [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r,d ,q,r") (match_operand:ALL1 1 "nox_general_operand" "r,n Ynn,r,q")) (clobber (const_int 0))] "(register_operand (operands[0], <MODE>mode) || reg_or_0_operand (operands[1], <MODE>mode)) && reload_completed" { return output_movqi (insn, operands, NULL); } [(set_attr "length" "1,1,1,1") (set_attr "adjust_len" "mov8")]) Regards Senthil ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-14 11:16 Clobber REG_CC only for some constraint alternatives? Senthil Kumar Selvaraj @ 2020-08-14 15:32 ` Matt Wette 2020-08-14 17:42 ` Pip Cet 2020-08-14 16:23 ` Segher Boessenkool ` (2 subsequent siblings) 3 siblings, 1 reply; 32+ messages in thread From: Matt Wette @ 2020-08-14 15:32 UTC (permalink / raw) To: gcc On 8/14/20 4:16 AM, Senthil Kumar Selvaraj via Gcc wrote: > Hi, > > I'm working on porting AVR to MODE_CC, and there are quite a few > patterns that clobber the condition code reg only for certain > constraint alternatives. For e.g., > > (define_insn "mov<mode>_insn" > [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r") > (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))] > "register_operand (operands[0], <MODE>mode) > || reg_or_0_operand (operands[1], <MODE>mode)" > { > return output_movqi (insn, operands, NULL); > } > [(set_attr "length" "1,1,5,5,1,1,4") > (set_attr "adjust_len" "mov8") > (set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")]) > > As you can deduce from the (set_attr "cc" ..), only constraint > alternatives 0,2,3 and 6 clobber CC - others leave it unchanged. > > My first version of the port adds a post-reload splitter that adds a > (clobber (reg:CC REG_CC)) unconditionally, and it appears to work. If I > do want to add the clobber conditionally, would something like the below > be a good way to do it (get_cc_reg_clobber_rtx returns either const0_rtx > or cc_reg_rtx based on get_attr_cc (insn))? Or is there a better/cleaner way? > > (define_insn_and_split "mov<mode>_insn" > [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r") > (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))] > "register_operand (operands[0], <MODE>mode) > || reg_or_0_operand (operands[1], <MODE>mode)" > "#" > "&& reload_completed" > [(parallel [(set (match_dup 0) > (match_dup 1)) > (clobber (match_dup 2))])] > { > operands[2] = get_cc_reg_clobber_rtx (curr_insn); > } > [(set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")]) > > (define_insn "*mov<mode>_insn_clobber_flags" > [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,Qm ,r ,*r") > (match_operand:ALL1 1 "nox_general_operand" "r Y00,r Y00,Qm,i")) > (clobber (reg:CC REG_CC))] > "(register_operand (operands[0], <MODE>mode) > || reg_or_0_operand (operands[1], <MODE>mode)) > && reload_completed" > { > return output_movqi (insn, operands, NULL); > } > [(set_attr "length" "1,5,5,4") > (set_attr "adjust_len" "mov8")]) > > (define_insn "*mov<mode>_insn_noclobber_flags" > [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r,d ,q,r") > (match_operand:ALL1 1 "nox_general_operand" "r,n Ynn,r,q")) > (clobber (const_int 0))] > "(register_operand (operands[0], <MODE>mode) > || reg_or_0_operand (operands[1], <MODE>mode)) > && reload_completed" > { > return output_movqi (insn, operands, NULL); > } > [(set_attr "length" "1,1,1,1") > (set_attr "adjust_len" "mov8")]) > > Regards > Senthil Happy to see someone working this. Are you starting with one CC mode? I noticed that the current CC0 implementation seems to effectively use several modes. For example, one for use of the t flag. I'm sure it will be easier to start with one mode. Matt ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-14 15:32 ` Matt Wette @ 2020-08-14 17:42 ` Pip Cet 0 siblings, 0 replies; 32+ messages in thread From: Pip Cet @ 2020-08-14 17:42 UTC (permalink / raw) To: Matt Wette; +Cc: gcc On Fri, Aug 14, 2020 at 3:33 PM Matt Wette via Gcc <gcc@gcc.gnu.org> wrote: > Happy to see someone working this. Are you starting with one CC mode? I'm also working on this (mostly at bug#92792), and so far am using two modes: the general reg:CC mode for proper comparison insns, and CCNZ for optimization in the CC-setting variants produced by the cmpelim pass. > I noticed that the current CC0 implementation seems to effectively use > several modes. For example, one for use of the t flag. As far as I can tell, the current code emits T setters and getters together as one insn, even going to the trouble of setting T redundantly when it already has been set. Am I missing something? ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-14 11:16 Clobber REG_CC only for some constraint alternatives? Senthil Kumar Selvaraj 2020-08-14 15:32 ` Matt Wette @ 2020-08-14 16:23 ` Segher Boessenkool 2020-08-14 17:47 ` Pip Cet 2020-08-16 3:25 ` Hans-Peter Nilsson 2020-08-17 16:45 ` Jeff Law 3 siblings, 1 reply; 32+ messages in thread From: Segher Boessenkool @ 2020-08-14 16:23 UTC (permalink / raw) To: Senthil Kumar Selvaraj; +Cc: gcc, ebotcazou Hi! On Fri, Aug 14, 2020 at 04:46:59PM +0530, Senthil Kumar Selvaraj via Gcc wrote: > I'm working on porting AVR to MODE_CC, I'm very happy to see people work on that. > (define_insn "*mov<mode>_insn_noclobber_flags" > [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r,d ,q,r") > (match_operand:ALL1 1 "nox_general_operand" "r,n Ynn,r,q")) > (clobber (const_int 0))] This is not correct, clobbers like that are not defined RTL, and are actually used internally (by combine at least), so this will confuse that. If you want to say some alternative does not clobber anything, just use the constraint "X" for that alternative. $ grep -r "clobber.*scratch.*X" gcc/config/ HtH, Segher ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-14 16:23 ` Segher Boessenkool @ 2020-08-14 17:47 ` Pip Cet 2020-08-15 0:29 ` Segher Boessenkool 0 siblings, 1 reply; 32+ messages in thread From: Pip Cet @ 2020-08-14 17:47 UTC (permalink / raw) To: Segher Boessenkool; +Cc: Senthil Kumar Selvaraj, gcc, ebotcazou On Fri, Aug 14, 2020 at 4:24 PM Segher Boessenkool <segher@kernel.crashing.org> wrote: > On Fri, Aug 14, 2020 at 04:46:59PM +0530, Senthil Kumar Selvaraj via Gcc wrote: > > (define_insn "*mov<mode>_insn_noclobber_flags" > > [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r,d ,q,r") > > (match_operand:ALL1 1 "nox_general_operand" "r,n Ynn,r,q")) > > (clobber (const_int 0))] > > This is not correct, clobbers like that are not defined RTL, and are > actually used internally (by combine at least), so this will confuse > that. > > If you want to say some alternative does not clobber anything, just use > the constraint "X" for that alternative. Just to clarify, such clobbers would still show up in RTL, right? Because some passes, such as cmpelim, do not currently appear to deal very well with extra clobbers, so that might be a problem. What I'm currently doing is this: (define_split [(set (match_operand 0 "nonimmediate_operand") (match_operand 1 "nox_general_operand"))] "reload_completed && mov_clobbers_cc (insn, operands)" [(parallel [(set (match_dup 0) (match_dup 1)) (clobber (reg:CC REG_CC))])]) which, if I understand correctly, introduces the parallel-clobber expression only when necessary, at the same time as post-reload splitters introduce REG_CC references. Is that correct? Thanks Pip ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-14 17:47 ` Pip Cet @ 2020-08-15 0:29 ` Segher Boessenkool 2020-08-15 10:18 ` Pip Cet 0 siblings, 1 reply; 32+ messages in thread From: Segher Boessenkool @ 2020-08-15 0:29 UTC (permalink / raw) To: Pip Cet; +Cc: Senthil Kumar Selvaraj, gcc, ebotcazou Hi! On Fri, Aug 14, 2020 at 05:47:02PM +0000, Pip Cet wrote: > On Fri, Aug 14, 2020 at 4:24 PM Segher Boessenkool > <segher@kernel.crashing.org> wrote: > > On Fri, Aug 14, 2020 at 04:46:59PM +0530, Senthil Kumar Selvaraj via Gcc wrote: > > > (define_insn "*mov<mode>_insn_noclobber_flags" > > > [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r,d ,q,r") > > > (match_operand:ALL1 1 "nox_general_operand" "r,n Ynn,r,q")) > > > (clobber (const_int 0))] > > > > This is not correct, clobbers like that are not defined RTL, and are > > actually used internally (by combine at least), so this will confuse > > that. > > > > If you want to say some alternative does not clobber anything, just use > > the constraint "X" for that alternative. > > Just to clarify, such clobbers would still show up in RTL, right? Yes, as (clobber (scratch:CC)) (or whatever the mode is). No register will be allocated to it. You can do a define_split splitting it into the form without clobber, if you want? (You can "split" to just one insn fine.) It's neatest when written as a define_insn_and_split. > Because some passes, such as cmpelim, do not currently appear to deal > very well with extra clobbers, so that might be a problem. Not sure if it would mind here... It is not a clobber of a reg. > What I'm currently doing is this: > > (define_split > [(set (match_operand 0 "nonimmediate_operand") > (match_operand 1 "nox_general_operand"))] > "reload_completed && mov_clobbers_cc (insn, operands)" > [(parallel [(set (match_dup 0) (match_dup 1)) > (clobber (reg:CC REG_CC))])]) > > which, if I understand correctly, introduces the parallel-clobber > expression only when necessary, at the same time as post-reload > splitters introduce REG_CC references. Is that correct? Yes. And this will work correctly if somehow you ensure that REG_CC isn't live anywhere you introduce such a clobber. Segher ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-15 0:29 ` Segher Boessenkool @ 2020-08-15 10:18 ` Pip Cet 2020-08-16 0:50 ` Segher Boessenkool 0 siblings, 1 reply; 32+ messages in thread From: Pip Cet @ 2020-08-15 10:18 UTC (permalink / raw) To: Segher Boessenkool; +Cc: Senthil Kumar Selvaraj, gcc, ebotcazou On Sat, Aug 15, 2020 at 12:30 AM Segher Boessenkool <segher@kernel.crashing.org> wrote: > On Fri, Aug 14, 2020 at 05:47:02PM +0000, Pip Cet wrote: > > On Fri, Aug 14, 2020 at 4:24 PM Segher Boessenkool > > <segher@kernel.crashing.org> wrote: > > > If you want to say some alternative does not clobber anything, just use > > > the constraint "X" for that alternative. > > > > Just to clarify, such clobbers would still show up in RTL, right? > > Yes, as > > (clobber (scratch:CC)) > > (or whatever the mode is). No register will be allocated to it. You > can do a define_split splitting it into the form without clobber, if > you want? (You can "split" to just one insn fine.) It's neatest when > written as a define_insn_and_split. That does sound like a neat solution for leaving the current patterns largely intact, thanks! I'll try both variants, both and without the define_split. > > What I'm currently doing is this: > > > > (define_split > > [(set (match_operand 0 "nonimmediate_operand") > > (match_operand 1 "nox_general_operand"))] > > "reload_completed && mov_clobbers_cc (insn, operands)" > > [(parallel [(set (match_dup 0) (match_dup 1)) > > (clobber (reg:CC REG_CC))])]) > > > > which, if I understand correctly, introduces the parallel-clobber > > expression only when necessary, at the same time as post-reload > > splitters introduce REG_CC references. Is that correct? > > Yes. And this will work correctly if somehow you ensure that REG_CC > isn't live anywhere you introduce such a clobber. IIUC, the idea is that references to REG_CC, except for clobbers, are only introduced in the post-reload split pass, so it cannot be live before our define_split runs. Does that make sense? ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-15 10:18 ` Pip Cet @ 2020-08-16 0:50 ` Segher Boessenkool 2020-08-16 18:28 ` Pip Cet 0 siblings, 1 reply; 32+ messages in thread From: Segher Boessenkool @ 2020-08-16 0:50 UTC (permalink / raw) To: Pip Cet; +Cc: Senthil Kumar Selvaraj, gcc, ebotcazou On Sat, Aug 15, 2020 at 10:18:27AM +0000, Pip Cet wrote: > > > What I'm currently doing is this: > > > > > > (define_split > > > [(set (match_operand 0 "nonimmediate_operand") > > > (match_operand 1 "nox_general_operand"))] > > > "reload_completed && mov_clobbers_cc (insn, operands)" > > > [(parallel [(set (match_dup 0) (match_dup 1)) > > > (clobber (reg:CC REG_CC))])]) > > > > > > which, if I understand correctly, introduces the parallel-clobber > > > expression only when necessary, at the same time as post-reload > > > splitters introduce REG_CC references. Is that correct? > > > > Yes. And this will work correctly if somehow you ensure that REG_CC > > isn't live anywhere you introduce such a clobber. > > IIUC, the idea is that references to REG_CC, except for clobbers, are > only introduced in the post-reload split pass, so it cannot be live > before our define_split runs. Does that make sense? Yes, it does. It has some huge restrictions (using the reg in inline assembler can never work reliably, for example, so you'll have to disallow that). And earlier passes (like combine) cannot optimise this, etc. But it is a pretty straightforward way to move from CC0 to the modern world! Segher ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-16 0:50 ` Segher Boessenkool @ 2020-08-16 18:28 ` Pip Cet 2020-08-17 7:31 ` Senthil Kumar Selvaraj ` (2 more replies) 0 siblings, 3 replies; 32+ messages in thread From: Pip Cet @ 2020-08-16 18:28 UTC (permalink / raw) To: Segher Boessenkool; +Cc: Senthil Kumar Selvaraj, gcc, ebotcazou On Sun, Aug 16, 2020 at 12:50 AM Segher Boessenkool <segher@kernel.crashing.org> wrote: > On Sat, Aug 15, 2020 at 10:18:27AM +0000, Pip Cet wrote: > > > > What I'm currently doing is this: > > > > > > > > (define_split > > > > [(set (match_operand 0 "nonimmediate_operand") > > > > (match_operand 1 "nox_general_operand"))] > > > > "reload_completed && mov_clobbers_cc (insn, operands)" > > > > [(parallel [(set (match_dup 0) (match_dup 1)) > > > > (clobber (reg:CC REG_CC))])]) > > > > > > > > which, if I understand correctly, introduces the parallel-clobber > > > > expression only when necessary, at the same time as post-reload > > > > splitters introduce REG_CC references. Is that correct? > > > > > > Yes. And this will work correctly if somehow you ensure that REG_CC > > > isn't live anywhere you introduce such a clobber. > > > > IIUC, the idea is that references to REG_CC, except for clobbers, are > > only introduced in the post-reload split pass, so it cannot be live > > before our define_split runs. Does that make sense? > > Yes, it does. It has some huge restrictions (using the reg in inline > assembler can never work reliably, for example, so you'll have to > disallow that). Is there any approach that doesn't suffer from that problem? My understanding was that we need to allow reload to insert CC-clobbering insns on this (and many other) architectures, and that there are so many places where reload might choose to do so (including before and after inline asm) that using the register prior to reload just isn't possible. I'd be glad to be wrong, though :-) Is it true that reload chooses which constraint alternative is used for each insn? Is that information available somehow to post-reload splits? The problem is that the "X" constraint matches whatever's there already, and doesn't replace it with the (scratch:CC) expression that would work, so I can't rewrite those insns not to clobber the CC reg. For example, here's what I currently have: (define_expand "mov<mode>" [(parallel [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "") (match_operand:MOVMODE 1 "general_operand" "")) (clobber (reg:CC REG_CC))])] ...) (define_insn "mov<mode>_insn" [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r,r ,d ,Qm ,r ,q,r,*r") (match_operand:ALL1 1 "nox_general_operand" "r,Y00,n Ynn,r Y00,Qm,r,q,i")) (clobber (match_scratch:CC 2 "=X,c,X,c,c,X,X,c"))] ...) That works, but it results in an incorrect CC clobber for, say, register-to-register movqi. For that, I'd need something like (define_split [(parallel [(set (match_operand:ALL1 0 "nonimmediate_operand") (match_operand:ALL1 1 "nox_general_operand")) (clobber (reg:CC REG_CC))])] "reload_completed && REG_P (operands[0]) && REG_P (operands[1])" [(parallel [(set (match_dup 0) (match_dup 1)) (clobber (scratch:CC))])]) and so on, for all four constraint alternatives that don't actually clobber REG_CC (and also for a fifth which only rarely clobbers REG_CC). That's duplicated code, of course. All this is at least somewhat academic: the code produced isn't drastically better after my cc conversion, but it's not usually any worse, and I'm still looking at assembler examples that are pessimized a little to find out how to fix them... > And earlier passes (like combine) cannot optimise this, I'm not sure what "this" refers to: my understanding is that the idea is to let combine see CC-free code, or code with CC clobbers only, which it can then optimize, and only add "real" CC references after reload, so many optimizations should just work. > But it is a pretty straightforward way to move from CC0 to the > modern world! With the limitations of the reload pass being as they are, I don't really see a dramatically better alternative. I suppose we could explicitly save and restore CC flags around insns emitted when reload_in_progress is true, to simulate non-CC-clobbering add/mov insn patterns? That sounds like it would reduce code quality a lot, unless great care were taken to make sure all of the save/restore CC flags insns were optimized away in later passes. In any case, thanks for the answers so far! Pip ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-16 18:28 ` Pip Cet @ 2020-08-17 7:31 ` Senthil Kumar Selvaraj 2020-08-17 9:18 ` Pip Cet 2020-08-17 17:21 ` Segher Boessenkool 2020-08-18 15:17 ` Hans-Peter Nilsson 2 siblings, 1 reply; 32+ messages in thread From: Senthil Kumar Selvaraj @ 2020-08-17 7:31 UTC (permalink / raw) To: Pip Cet; +Cc: Segher Boessenkool, Senthil Kumar Selvaraj, gcc, ebotcazou Pip Cet writes: > On Sun, Aug 16, 2020 at 12:50 AM Segher Boessenkool > <segher@kernel.crashing.org> wrote: >> On Sat, Aug 15, 2020 at 10:18:27AM +0000, Pip Cet wrote: >> > > > What I'm currently doing is this: >> > > > >> > > > (define_split >> > > > [(set (match_operand 0 "nonimmediate_operand") >> > > > (match_operand 1 "nox_general_operand"))] >> > > > "reload_completed && mov_clobbers_cc (insn, operands)" >> > > > [(parallel [(set (match_dup 0) (match_dup 1)) >> > > > (clobber (reg:CC REG_CC))])]) >> > > > >> > > > which, if I understand correctly, introduces the parallel-clobber >> > > > expression only when necessary, at the same time as post-reload >> > > > splitters introduce REG_CC references. Is that correct? >> > > >> > > Yes. And this will work correctly if somehow you ensure that REG_CC >> > > isn't live anywhere you introduce such a clobber. >> > >> > IIUC, the idea is that references to REG_CC, except for clobbers, are >> > only introduced in the post-reload split pass, so it cannot be live >> > before our define_split runs. Does that make sense? >> >> Yes, it does. It has some huge restrictions (using the reg in inline >> assembler can never work reliably, for example, so you'll have to >> disallow that). > > Is there any approach that doesn't suffer from that problem? My > understanding was that we need to allow reload to insert CC-clobbering > insns on this (and many other) architectures, and that there are so > many places where reload might choose to do so (including before and > after inline asm) that using the register prior to reload just isn't > possible. I'd be glad to be wrong, though :-) > > Is it true that reload chooses which constraint alternative is used > for each insn? Is that information available somehow to post-reload > splits? The problem is that the "X" constraint matches whatever's > there already, and doesn't replace it with the (scratch:CC) expression > that would work, so I can't rewrite those insns not to clobber the CC > reg. > > For example, here's what I currently have: > > (define_expand "mov<mode>" > [(parallel [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "") > (match_operand:MOVMODE 1 "general_operand" "")) > (clobber (reg:CC REG_CC))])] > ...) > > (define_insn "mov<mode>_insn" > [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r,r ,d ,Qm > ,r ,q,r,*r") > (match_operand:ALL1 1 "nox_general_operand" "r,Y00,n Ynn,r > Y00,Qm,r,q,i")) > (clobber (match_scratch:CC 2 "=X,c,X,c,c,X,X,c"))] > ...) > > That works, but it results in an incorrect CC clobber for, say, > register-to-register movqi. For that, I'd need something like > > (define_split > [(parallel [(set (match_operand:ALL1 0 "nonimmediate_operand") > (match_operand:ALL1 1 "nox_general_operand")) > (clobber (reg:CC REG_CC))])] > "reload_completed && REG_P (operands[0]) && REG_P (operands[1])" > [(parallel [(set (match_dup 0) > (match_dup 1)) > (clobber (scratch:CC))])]) > > and so on, for all four constraint alternatives that don't actually > clobber REG_CC (and also for a fifth which only rarely clobbers > REG_CC). That's duplicated code, of course. The (setattr "cc" ...) that is currently present for all patterns accounts for the constraint alternatives,so using get_attr_cc to split to a (clobber) of either cc_reg_rtx or a gen_rtx_SCRATCH (CCmode) appears to work. (define_insn_and_split "mov<mode>_insn" [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r") (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i"))] "register_operand (operands[0], <MODE>mode) || reg_or_0_operand (operands[1], <MODE>mode)" "#" "&& reload_completed" [(parallel [(set (match_dup 0) (match_dup 1)) (clobber (match_dup 2))])] { operands[2] = get_cc_reg_clobber_rtx (curr_insn); } [(set_attr "cc" "ldi,none,clobber,clobber,none,none,clobber")]) (define_insn "*mov<mode>_insn" [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r") (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i")) (clobber (match_scratch:CC 2 "=X ,X ,c ,c ,X,X,c"))] "(register_operand (operands[0], <MODE>mode) || reg_or_0_operand (operands[1], <MODE>mode)) && reload_completed" { return output_movqi (insn, operands, NULL); } [(set_attr "length" "1,1,5,5,1,1,4") (set_attr "adjust_len" "mov8")]) As you mentioned elsewhere, keeping the clobber with "X" helps keep a single pattern for both CC reg clobbering and non-clobbering insns. > > All this is at least somewhat academic: the code produced isn't > drastically better after my cc conversion, but it's not usually any > worse, and I'm still looking at assembler examples that are pessimized > a little to find out how to fix them... > >> And earlier passes (like combine) cannot optimise this, > > I'm not sure what "this" refers to: my understanding is that the idea > is to let combine see CC-free code, or code with CC clobbers only, > which it can then optimize, and only add "real" CC references after > reload, so many optimizations should just work. > >> But it is a pretty straightforward way to move from CC0 to the >> modern world! > > With the limitations of the reload pass being as they are, I don't > really see a dramatically better alternative. I suppose we could > explicitly save and restore CC flags around insns emitted when > reload_in_progress is true, to simulate non-CC-clobbering add/mov insn > patterns? That sounds like it would reduce code quality a lot, unless > great care were taken to make sure all of the save/restore CC flags > insns were optimized away in later passes. > > In any case, thanks for the answers so far! > > Pip ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-17 7:31 ` Senthil Kumar Selvaraj @ 2020-08-17 9:18 ` Pip Cet 2020-08-18 6:52 ` Senthil Kumar Selvaraj 0 siblings, 1 reply; 32+ messages in thread From: Pip Cet @ 2020-08-17 9:18 UTC (permalink / raw) To: Senthil Kumar Selvaraj; +Cc: Segher Boessenkool, gcc, ebotcazou On Mon, Aug 17, 2020 at 7:31 AM Senthil Kumar Selvaraj <senthil.thecoder@gmail.com> wrote: > > (define_split > > [(parallel [(set (match_operand:ALL1 0 "nonimmediate_operand") > > (match_operand:ALL1 1 "nox_general_operand")) > > (clobber (reg:CC REG_CC))])] > > "reload_completed && REG_P (operands[0]) && REG_P (operands[1])" > > [(parallel [(set (match_dup 0) > > (match_dup 1)) > > (clobber (scratch:CC))])]) > > > > and so on, for all four constraint alternatives that don't actually > > clobber REG_CC (and also for a fifth which only rarely clobbers > > REG_CC). That's duplicated code, of course. > > The (setattr "cc" ...) that is currently present for all > patterns accounts for the constraint alternatives,so using > get_attr_cc to split to a (clobber) of either cc_reg_rtx or a > gen_rtx_SCRATCH (CCmode) appears to work. Thanks! Using an insn attribute is actually what I ended up doing (https://github.com/pipcet/gcc/commit/d4509afae9238e0ade4d3e1e97dd8577dae96115) :-) It's still confusing, IMHO, that insn attributes (but not the get_attr_alternative attribute which is mentioned in the documentation) are available when which_alternative is not. > (define_insn "*mov<mode>_insn" > [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r") > (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i")) > (clobber (match_scratch:CC 2 "=X ,X ,c ,c ,X,X,c"))] Hmm. Technically, of course, clearing register 0 (a special case of the first alternative) would clobber the flags, but as it happens, the rewrite above produces the right clobber expression which is simply accepted by the "X"... I'm not sure whether anything else is trying to recognize such insns, but as it stands that define_insn would recognize the incorrect insn: [(set (reg:QI 0) (const_int 0)) (clobber (scratch:CC))] ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-17 9:18 ` Pip Cet @ 2020-08-18 6:52 ` Senthil Kumar Selvaraj 2020-08-20 11:51 ` Pip Cet 0 siblings, 1 reply; 32+ messages in thread From: Senthil Kumar Selvaraj @ 2020-08-18 6:52 UTC (permalink / raw) To: Pip Cet; +Cc: Senthil Kumar Selvaraj, Segher Boessenkool, gcc, ebotcazou Pip Cet writes: > On Mon, Aug 17, 2020 at 7:31 AM Senthil Kumar Selvaraj > <senthil.thecoder@gmail.com> wrote: >> > (define_split >> > [(parallel [(set (match_operand:ALL1 0 "nonimmediate_operand") >> > (match_operand:ALL1 1 "nox_general_operand")) >> > (clobber (reg:CC REG_CC))])] >> > "reload_completed && REG_P (operands[0]) && REG_P (operands[1])" >> > [(parallel [(set (match_dup 0) >> > (match_dup 1)) >> > (clobber (scratch:CC))])]) >> > >> > and so on, for all four constraint alternatives that don't actually >> > clobber REG_CC (and also for a fifth which only rarely clobbers >> > REG_CC). That's duplicated code, of course. >> >> The (setattr "cc" ...) that is currently present for all >> patterns accounts for the constraint alternatives,so using >> get_attr_cc to split to a (clobber) of either cc_reg_rtx or a >> gen_rtx_SCRATCH (CCmode) appears to work. > > Thanks! Using an insn attribute is actually what I ended up doing > (https://github.com/pipcet/gcc/commit/d4509afae9238e0ade4d3e1e97dd8577dae96115) > :-) > > It's still confusing, IMHO, that insn attributes (but not the > get_attr_alternative attribute which is mentioned in the > documentation) are available when which_alternative is not. > >> (define_insn "*mov<mode>_insn" >> [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r ,d ,Qm ,r ,q,r,*r") >> (match_operand:ALL1 1 "nox_general_operand" "r Y00,n Ynn,r Y00,Qm,r,q,i")) >> (clobber (match_scratch:CC 2 "=X ,X ,c ,c ,X,X,c"))] > > Hmm. Technically, of course, clearing register 0 (a special case of > the first alternative) would clobber the flags, but as it happens, the > rewrite above produces the right clobber expression which is simply > accepted by the "X"... I'm not sure whether anything else is trying to > recognize such insns, but as it stands that define_insn would > recognize the incorrect insn: > > [(set (reg:QI 0) (const_int 0)) > (clobber (scratch:CC))] get_cc_reg_clobber_rtx also looks at the insn itself (i.e. whatever the erstwhile NOTICE_UPDATE_CC hook did), so if the cc attribute is LDI, and operands[1] is const0_rtx, it would return cc_reg_rtx as the clobber reg. AFAICT, some passes after reload verify if operands match constraints, and that would work in this case - I'm not sure if the pattern you mentioned could show up, outside of wrong splitters/peepholes in the md file. Another approach would be to conservatively use a 'c' constraint and clobber REG_CC for all reg-reg moves. Regards Senthil ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-18 6:52 ` Senthil Kumar Selvaraj @ 2020-08-20 11:51 ` Pip Cet 2020-08-20 16:06 ` Senthil Kumar Selvaraj 0 siblings, 1 reply; 32+ messages in thread From: Pip Cet @ 2020-08-20 11:51 UTC (permalink / raw) To: Senthil Kumar Selvaraj; +Cc: Segher Boessenkool, gcc, ebotcazou On Tue, Aug 18, 2020 at 6:52 AM Senthil Kumar Selvaraj <senthil.thecoder@gmail.com> wrote: > > recognize such insns, but as it stands that define_insn would > > recognize the incorrect insn: > > > > [(set (reg:QI 0) (const_int 0)) > > (clobber (scratch:CC))] > > get_cc_reg_clobber_rtx also looks at the insn itself (i.e. whatever > the erstwhile NOTICE_UPDATE_CC hook did), so if the cc attribute is LDI, > and operands[1] is const0_rtx, it would return cc_reg_rtx as the clobber reg. > > AFAICT, some passes after reload verify if operands match constraints, > and that would work in this case - I'm not sure if the pattern you > mentioned could show up, outside of wrong splitters/peepholes in the md file. I don't think they can, but it's still another case of lying to GCC. At the very least, output_movqi should assert that it isn't asked to produce code for this situation. > Another approach would be to conservatively use a 'c' constraint and > clobber REG_CC for all reg-reg moves. I'd prefer splitting the constraint alternatives to have one clear-r0 alternative, an ldi alternative, and a clear -r1_31 alternative. As for define_subst, is it really worth it? If I'm reading the documentation correctly, it's not powerful enough to deal with scratch operands on its own, so we'd probably need three or four variants of define_subst just to handle those cases. I'm probably missing something obvious, but what's the reason for keeping the CC-clobbering post-reload splitter when we already have a CC-setting one? Are there significant post-reload optimizations that can deal with a clobber but not an arbitrary assignment to CC? If so, wouldn't it be better to fix those optimizations? (There are at least some pre-reload optimizations that don't work with the CC-clobbering insn patterns. lower_subreg.c's simple_move, for example, recognizes only two-operand sets. This resulted in pessimized code, but is easy to fix.) ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-20 11:51 ` Pip Cet @ 2020-08-20 16:06 ` Senthil Kumar Selvaraj 2020-08-24 18:18 ` Jeff Law 0 siblings, 1 reply; 32+ messages in thread From: Senthil Kumar Selvaraj @ 2020-08-20 16:06 UTC (permalink / raw) To: Pip Cet; +Cc: Senthil Kumar Selvaraj, Segher Boessenkool, gcc, ebotcazou Pip Cet writes: > On Tue, Aug 18, 2020 at 6:52 AM Senthil Kumar Selvaraj > <senthil.thecoder@gmail.com> wrote: >> > recognize such insns, but as it stands that define_insn would >> > recognize the incorrect insn: >> > >> > [(set (reg:QI 0) (const_int 0)) >> > (clobber (scratch:CC))] >> >> get_cc_reg_clobber_rtx also looks at the insn itself (i.e. whatever >> the erstwhile NOTICE_UPDATE_CC hook did), so if the cc attribute is LDI, >> and operands[1] is const0_rtx, it would return cc_reg_rtx as the clobber reg. >> >> AFAICT, some passes after reload verify if operands match constraints, >> and that would work in this case - I'm not sure if the pattern you >> mentioned could show up, outside of wrong splitters/peepholes in the md file. > > I don't think they can, but it's still another case of lying to GCC. > > At the very least, output_movqi should assert that it isn't asked to > produce code for this situation. I agree. > >> Another approach would be to conservatively use a 'c' constraint and >> clobber REG_CC for all reg-reg moves. > > I'd prefer splitting the constraint alternatives to have one clear-r0 > alternative, an ldi alternative, and a clear -r1_31 alternative. > > As for define_subst, is it really worth it? If I'm reading the > documentation correctly, it's not powerful enough to deal with scratch > operands on its own, so we'd probably need three or four variants of > define_subst just to handle those cases. Is this related to cmpelim not looking at REG_CC clobber if there are other (clobber scratch..) preceding it? > > I'm probably missing something obvious, but what's the reason for > keeping the CC-clobbering post-reload splitter when we already have a > CC-setting one? Are there significant post-reload optimizations that > can deal with a clobber but not an arbitrary assignment to CC? If so, > wouldn't it be better to fix those optimizations? The post-reload splitter introduces the clobber. The wiki suggests that approach if most insns clobber REG_CC, perhaps because of the missed optimizations you describe below? > > (There are at least some pre-reload optimizations that don't work with > the CC-clobbering insn patterns. lower_subreg.c's simple_move, for > example, recognizes only two-operand sets. This resulted in pessimized > code, but is easy to fix.) Regards Senthil ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-20 16:06 ` Senthil Kumar Selvaraj @ 2020-08-24 18:18 ` Jeff Law 2020-08-26 3:58 ` Hans-Peter Nilsson 2020-08-26 11:18 ` Pip Cet 0 siblings, 2 replies; 32+ messages in thread From: Jeff Law @ 2020-08-24 18:18 UTC (permalink / raw) To: Senthil Kumar Selvaraj, Pip Cet; +Cc: gcc, ebotcazou, Segher Boessenkool On Thu, 2020-08-20 at 21:36 +0530, Senthil Kumar Selvaraj via Gcc wrote: > Pip Cet writes: > > > On Tue, Aug 18, 2020 at 6:52 AM Senthil Kumar Selvaraj > > <senthil.thecoder@gmail.com> wrote: > > > > recognize such insns, but as it stands that define_insn would > > > > recognize the incorrect insn: > > > > > > > > [(set (reg:QI 0) (const_int 0)) > > > > (clobber (scratch:CC))] > > > > > > get_cc_reg_clobber_rtx also looks at the insn itself (i.e. whatever > > > the erstwhile NOTICE_UPDATE_CC hook did), so if the cc attribute is LDI, > > > and operands[1] is const0_rtx, it would return cc_reg_rtx as the clobber reg. > > > > > > AFAICT, some passes after reload verify if operands match constraints, > > > and that would work in this case - I'm not sure if the pattern you > > > mentioned could show up, outside of wrong splitters/peepholes in the md file. > > > > I don't think they can, but it's still another case of lying to GCC. > > > > At the very least, output_movqi should assert that it isn't asked to > > produce code for this situation. > > I agree. > > > Another approach would be to conservatively use a 'c' constraint and > > > clobber REG_CC for all reg-reg moves. > > > > I'd prefer splitting the constraint alternatives to have one clear-r0 > > alternative, an ldi alternative, and a clear -r1_31 alternative. > > > > As for define_subst, is it really worth it? If I'm reading the > > documentation correctly, it's not powerful enough to deal with scratch > > operands on its own, so we'd probably need three or four variants of > > define_subst just to handle those cases. > > Is this related to cmpelim not looking at REG_CC clobber if there are > other (clobber scratch..) preceding it? > > I'm probably missing something obvious, but what's the reason for > > keeping the CC-clobbering post-reload splitter when we already have a > > CC-setting one? Are there significant post-reload optimizations that > > can deal with a clobber but not an arbitrary assignment to CC? If so, > > wouldn't it be better to fix those optimizations? > > The post-reload splitter introduces the clobber. The wiki > suggests that approach if most insns clobber REG_CC, perhaps because of > the missed optimizations you describe below? If most patterns set/clobber the flags, then yes, it's slightly better to only expose them after reload. Various passes that directly grub through RTL rather than using helpers like single_set will optimize things better. That's the approach I've taken with the H8 conversion, which is basically working at this point and when I have the time I walk through various minor codegen inefficiences. Jeff ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-24 18:18 ` Jeff Law @ 2020-08-26 3:58 ` Hans-Peter Nilsson 2020-08-26 16:20 ` Jeff Law 2020-08-26 11:18 ` Pip Cet 1 sibling, 1 reply; 32+ messages in thread From: Hans-Peter Nilsson @ 2020-08-26 3:58 UTC (permalink / raw) To: law; +Cc: Senthil Kumar Selvaraj, Pip Cet, gcc, ebotcazou, Segher Boessenkool On Mon, 24 Aug 2020, Jeff Law via Gcc wrote: > On Thu, 2020-08-20 at 21:36 +0530, Senthil Kumar Selvaraj via Gcc wrote: > > The post-reload splitter introduces the clobber. The wiki > > suggests that approach if most insns clobber REG_CC, perhaps because of > > the missed optimizations you describe below? > If most patterns set/clobber the flags, then yes, it's slightly better to only > expose them after reload. Various passes that directly grub through RTL rather > than using helpers like single_set will optimize things better. The "slightly" being omissions like the one fixed in combine.c last month. ;-) There's one in reload too ("Discard obvious no-ops, even without -O"), but it seems to be acting the other way(!) If, for a machine where most insns clobber REG_CC, you instead emit with the clobber initially, you can have a tidier port: one define_subst:ed pattern instead of... How many is it with the only-expose-after-reload method (counting define_insn, define_split, possibly a define_expand too that wasn't there for cc0)? Two or three, per (original) insn with cc0? brgds, H-P ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-26 3:58 ` Hans-Peter Nilsson @ 2020-08-26 16:20 ` Jeff Law 2020-08-26 18:26 ` Hans-Peter Nilsson 0 siblings, 1 reply; 32+ messages in thread From: Jeff Law @ 2020-08-26 16:20 UTC (permalink / raw) To: Hans-Peter Nilsson Cc: Senthil Kumar Selvaraj, Pip Cet, gcc, ebotcazou, Segher Boessenkool On Tue, 2020-08-25 at 23:58 -0400, Hans-Peter Nilsson wrote: > On Mon, 24 Aug 2020, Jeff Law via Gcc wrote: > > On Thu, 2020-08-20 at 21:36 +0530, Senthil Kumar Selvaraj via Gcc wrote: > > > The post-reload splitter introduces the clobber. The wiki > > > suggests that approach if most insns clobber REG_CC, perhaps because of > > > the missed optimizations you describe below? > > If most patterns set/clobber the flags, then yes, it's slightly better to only > > expose them after reload. Various passes that directly grub through RTL rather > > than using helpers like single_set will optimize things better. > > The "slightly" being omissions like the one fixed in combine.c > last month. ;-) There's one in reload too ("Discard obvious > no-ops, even without -O"), but it seems to be acting the other > way(!) Yea, this is the kind of thing I'm thinking of when I say "slightly". > > If, for a machine where most insns clobber REG_CC, you instead > emit with the clobber initially, you can have a tidier port: one > define_subst:ed pattern instead of... How many is it with the > only-expose-after-reload method (counting define_insn, > define_split, possibly a define_expand too that wasn't there for > cc0)? Two or three, per (original) insn with cc0? It depends :-) On the H8 I've tried to focus efforts on creating the additional patterns only when they're actually helpful. So it'd normally be 2X or 3X the number of patterns, but it's slightly less on the H8. I pondered a define_subst approach, but with my lack of experience with define_subst and the head start from my son on the mechanical changes it seemed easier to just continue without define_subst. jeff ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-26 16:20 ` Jeff Law @ 2020-08-26 18:26 ` Hans-Peter Nilsson 0 siblings, 0 replies; 32+ messages in thread From: Hans-Peter Nilsson @ 2020-08-26 18:26 UTC (permalink / raw) To: Jeff Law Cc: Senthil Kumar Selvaraj, Pip Cet, gcc, ebotcazou, Segher Boessenkool On Wed, 26 Aug 2020, Jeff Law wrote: > On Tue, 2020-08-25 at 23:58 -0400, Hans-Peter Nilsson wrote: > > On Mon, 24 Aug 2020, Jeff Law via Gcc wrote: > > > On Thu, 2020-08-20 at 21:36 +0530, Senthil Kumar Selvaraj via Gcc wrote: > > > > The post-reload splitter introduces the clobber. The wiki > > > > suggests that approach if most insns clobber REG_CC, perhaps because of > > > > the missed optimizations you describe below? > > > If most patterns set/clobber the flags, then yes, it's slightly better to only > > > expose them after reload. Various passes that directly grub through RTL rather > > > than using helpers like single_set will optimize things better. > > > > The "slightly" being omissions like the one fixed in combine.c > > last month. ;-) There's one in reload too ("Discard obvious > > no-ops, even without -O"), but it seems to be acting the other > > way(!) > Yea, this is the kind of thing I'm thinking of when I say "slightly". JFTR, I'd like to stress that point: contrary to my initial fears, my experience with the CRIS de-cc0ration is that the straight-set insn assumptions in gcc are few and far-between enough to be ignored as a factor regarding missed optimizations, when picking a strategy. brgds, H-P ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-24 18:18 ` Jeff Law 2020-08-26 3:58 ` Hans-Peter Nilsson @ 2020-08-26 11:18 ` Pip Cet 2020-08-26 16:21 ` Jeff Law ` (2 more replies) 1 sibling, 3 replies; 32+ messages in thread From: Pip Cet @ 2020-08-26 11:18 UTC (permalink / raw) To: law; +Cc: Senthil Kumar Selvaraj, gcc, ebotcazou, Segher Boessenkool On Mon, Aug 24, 2020 at 6:18 PM Jeff Law <law@redhat.com> wrote: > > The post-reload splitter introduces the clobber. The wiki > > suggests that approach if most insns clobber REG_CC, perhaps because of > > the missed optimizations you describe below? > If most patterns set/clobber the flags, then yes, it's slightly better to only > expose them after reload. Various passes that directly grub through RTL rather > than using helpers like single_set will optimize things better. I think I made it to the next pitfall :-) The cmpelim pass tries to recognize cc-setting variants of insns. Whether or not there is one (i.e. whether or not the insn should be recognized) depends on the "cc" attribute, which depends on which alternative is used. So I did the obvious thing, and put a condition in the define_insn which depends on get_cc_attr (insn). But get_cc_attr() tries to recognize the insn, so we recurse indefinitely and die with a segfault. Things appear to work with a somewhat subtle hack: we recognize that a false positive from the inner recognition isn't harmful, because the outer condition will still catch invalid cases. static int recurse = 0; if (recurse) return gen_rtx_REG (CCmode, REG_CC); // causes the insn to be recognized recurse++; int old_insn_code = INSN_CODE (insn); enum attr_cc cc = get_attr_cc (insn); INSN_CODE (insn) = old_insn_code; recurse--; But surely that's not the right way? Note that whether there is a CC-setting variant depends not just on the "cc" attr, but also on the precise operands for some values of the "cc" attr, which requires hairy C code to figure out. Is it possible to avoid this situation by avoiding constraint alternatives, and defining insns separately for each of them? ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-26 11:18 ` Pip Cet @ 2020-08-26 16:21 ` Jeff Law [not found] ` <87h7so2w0c.fsf@gcc.gnu.org> 2020-09-01 19:38 ` Hans-Peter Nilsson 2 siblings, 0 replies; 32+ messages in thread From: Jeff Law @ 2020-08-26 16:21 UTC (permalink / raw) To: Pip Cet; +Cc: Senthil Kumar Selvaraj, gcc, ebotcazou, Segher Boessenkool On Wed, 2020-08-26 at 11:18 +0000, Pip Cet wrote: > On Mon, Aug 24, 2020 at 6:18 PM Jeff Law <law@redhat.com> wrote: > > > The post-reload splitter introduces the clobber. The wiki > > > suggests that approach if most insns clobber REG_CC, perhaps because of > > > the missed optimizations you describe below? > > If most patterns set/clobber the flags, then yes, it's slightly better to only > > expose them after reload. Various passes that directly grub through RTL rather > > than using helpers like single_set will optimize things better. > > I think I made it to the next pitfall :-) > > The cmpelim pass tries to recognize cc-setting variants of insns. > Whether or not there is one (i.e. whether or not the insn should be > recognized) depends on the "cc" attribute, which depends on which > alternative is used. So I did the obvious thing, and put a condition > in the define_insn which depends on get_cc_attr (insn). But > get_cc_attr() tries to recognize the insn, so we recurse indefinitely > and die with a segfault. > > Things appear to work with a somewhat subtle hack: we recognize that a > false positive from the inner recognition isn't harmful, because the > outer condition will still catch invalid cases. > > static int recurse = 0; > if (recurse) > return gen_rtx_REG (CCmode, REG_CC); // causes the insn to be recognized > recurse++; > int old_insn_code = INSN_CODE (insn); > enum attr_cc cc = get_attr_cc (insn); > INSN_CODE (insn) = old_insn_code; > recurse--; > > But surely that's not the right way? > > Note that whether there is a CC-setting variant depends not just on > the "cc" attr, but also on the precise operands for some values of the > "cc" attr, which requires hairy C code to figure out. > > Is it possible to avoid this situation by avoiding constraint > alternatives, and defining insns separately for each of them? You can split most things up like you've suggested. The exception would be the movXX patterns. Jeff ^ permalink raw reply [flat|nested] 32+ messages in thread
[parent not found: <87h7so2w0c.fsf@gcc.gnu.org>]
* Re: Clobber REG_CC only for some constraint alternatives? [not found] ` <87h7so2w0c.fsf@gcc.gnu.org> @ 2020-08-27 14:48 ` Jeff Law 0 siblings, 0 replies; 32+ messages in thread From: Jeff Law @ 2020-08-27 14:48 UTC (permalink / raw) To: Senthil Kumar Selvaraj, Pip Cet; +Cc: gcc, ebotcazou, Segher Boessenkool On Thu, 2020-08-27 at 16:31 +0530, Senthil Kumar Selvaraj wrote: > Pip Cet writes: > > > On Mon, Aug 24, 2020 at 6:18 PM Jeff Law <law@redhat.com> wrote: > > > > The post-reload splitter introduces the clobber. The wiki > > > > suggests that approach if most insns clobber REG_CC, perhaps because of > > > > the missed optimizations you describe below? > > > If most patterns set/clobber the flags, then yes, it's slightly better to only > > > expose them after reload. Various passes that directly grub through RTL rather > > > than using helpers like single_set will optimize things better. > > > > I think I made it to the next pitfall :-) > > > > The cmpelim pass tries to recognize cc-setting variants of insns. > > Whether or not there is one (i.e. whether or not the insn should be > > recognized) depends on the "cc" attribute, which depends on which > > alternative is used. So I did the obvious thing, and put a condition > > in the define_insn which depends on get_cc_attr (insn). But > > get_cc_attr() tries to recognize the insn, so we recurse indefinitely > > and die with a segfault. > > > > Things appear to work with a somewhat subtle hack: we recognize that a > > false positive from the inner recognition isn't harmful, because the > > outer condition will still catch invalid cases. > > > > static int recurse = 0; > > if (recurse) > > return gen_rtx_REG (CCmode, REG_CC); // causes the insn to be recognized > > recurse++; > > int old_insn_code = INSN_CODE (insn); > > enum attr_cc cc = get_attr_cc (insn); > > INSN_CODE (insn) = old_insn_code; > > recurse--; > > > > But surely that's not the right way? > > > > Note that whether there is a CC-setting variant depends not just on > > the "cc" attr, but also on the precise operands for some values of the > > "cc" attr, which requires hairy C code to figure out. > > This is only for ldi and plus cc attribute values, right? Can we > conservatively have only the clobber, and see how it impacts generated code? You should always be able to claim its clobbered, to get things running, then evaluate if it's worth trying to model that case more accurately to get better compare elimination. jeff ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-26 11:18 ` Pip Cet 2020-08-26 16:21 ` Jeff Law [not found] ` <87h7so2w0c.fsf@gcc.gnu.org> @ 2020-09-01 19:38 ` Hans-Peter Nilsson 2 siblings, 0 replies; 32+ messages in thread From: Hans-Peter Nilsson @ 2020-09-01 19:38 UTC (permalink / raw) To: Pip Cet; +Cc: gcc On Wed, 26 Aug 2020, Pip Cet via Gcc wrote: > Note that whether there is a CC-setting variant depends not just on > the "cc" attr, but also on the precise operands for some values of the > "cc" attr, which requires hairy C code to figure out. > > Is it possible to avoid this situation by avoiding constraint > alternatives, and defining insns separately for each of them? Well, rather than "avoid this situation", fix it. Besides defaulting to clobber and separate splitters like Jeff wrote, the best action here is to make the "cc" attribute accurate when non-clobber. That is, make the "hairy C code" part of the alternative-matching-expression (typically the constraint combination). brgds, H-P ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-16 18:28 ` Pip Cet 2020-08-17 7:31 ` Senthil Kumar Selvaraj @ 2020-08-17 17:21 ` Segher Boessenkool 2020-08-18 15:17 ` Hans-Peter Nilsson 2 siblings, 0 replies; 32+ messages in thread From: Segher Boessenkool @ 2020-08-17 17:21 UTC (permalink / raw) To: Pip Cet; +Cc: Senthil Kumar Selvaraj, gcc, ebotcazou Hi! On Sun, Aug 16, 2020 at 06:28:44PM +0000, Pip Cet wrote: > > > IIUC, the idea is that references to REG_CC, except for clobbers, are > > > only introduced in the post-reload split pass, so it cannot be live > > > before our define_split runs. Does that make sense? > > > > Yes, it does. It has some huge restrictions (using the reg in inline > > assembler can never work reliably, for example, so you'll have to > > disallow that). > > Is there any approach that doesn't suffer from that problem? My > understanding was that we need to allow reload to insert CC-clobbering > insns on this (and many other) architectures, and that there are so > many places where reload might choose to do so (including before and > after inline asm) that using the register prior to reload just isn't > possible. I'd be glad to be wrong, though :-) You can insert the clobber at expand time already. That probably works worse if most of your insns clobber the flags, but better if many do not. > Is it true that reload chooses which constraint alternative is used > for each insn? Register allocation does, yes (reload (or LRA) is the last step of that, it has the last say). > Is that information available somehow to post-reload > splits? In the "which_alternative" variable (not an attribute, an actual variable; so use it from a C block or C expression). There also is the "alternative" attribute (which uses "which_alternative" under the hood), which is handy for defining *other* attributes. > The problem is that the "X" constraint matches whatever's > there already, and doesn't replace it with the (scratch:CC) expression > that would work, so I can't rewrite those insns not to clobber the CC > reg. > > For example, here's what I currently have: > > (define_expand "mov<mode>" > [(parallel [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "") > (match_operand:MOVMODE 1 "general_operand" "")) > (clobber (reg:CC REG_CC))])] > ...) Yeah, if you use a hard register at expand time already, it won't be changed by register allocation. > (define_insn "mov<mode>_insn" > [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r,r ,d ,Qm > ,r ,q,r,*r") > (match_operand:ALL1 1 "nox_general_operand" "r,Y00,n Ynn,r > Y00,Qm,r,q,i")) > (clobber (match_scratch:CC 2 "=X,c,X,c,c,X,X,c"))] > ...) > > That works, but it results in an incorrect CC clobber for, say, > register-to-register movqi. For that, I'd need something like > > (define_split > [(parallel [(set (match_operand:ALL1 0 "nonimmediate_operand") > (match_operand:ALL1 1 "nox_general_operand")) > (clobber (reg:CC REG_CC))])] > "reload_completed && REG_P (operands[0]) && REG_P (operands[1])" > [(parallel [(set (match_dup 0) > (match_dup 1)) > (clobber (scratch:CC))])]) > > and so on, for all four constraint alternatives that don't actually > clobber REG_CC (and also for a fifth which only rarely clobbers > REG_CC). That's duplicated code, of course. You can make it a define_insn_and_split where the condition can look at the actual operands, or can use which_alternative. > All this is at least somewhat academic: the code produced isn't > drastically better after my cc conversion, but it's not usually any > worse, and I'm still looking at assembler examples that are pessimized > a little to find out how to fix them... Great :-) > > And earlier passes (like combine) cannot optimise this, > > I'm not sure what "this" refers to: my understanding is that the idea > is to let combine see CC-free code, or code with CC clobbers only, > which it can then optimize, and only add "real" CC references after > reload, so many optimizations should just work. "This" was meant to refer to "anything to do with the CC reg". If it doesn't yet exist until after reload, of course no pass before it can do anything with it :-) > > But it is a pretty straightforward way to move from CC0 to the > > modern world! > > With the limitations of the reload pass being as they are, I don't > really see a dramatically better alternative. I suppose we could > explicitly save and restore CC flags around insns emitted when > reload_in_progress is true, to simulate non-CC-clobbering add/mov insn > patterns? That sounds like it would reduce code quality a lot, unless > great care were taken to make sure all of the save/restore CC flags > insns were optimized away in later passes. Do you have move insns that do not clobber the CC reg? If not, good luck :-) > In any case, thanks for the answers so far! My pleasure. Segher ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-16 18:28 ` Pip Cet 2020-08-17 7:31 ` Senthil Kumar Selvaraj 2020-08-17 17:21 ` Segher Boessenkool @ 2020-08-18 15:17 ` Hans-Peter Nilsson 2 siblings, 0 replies; 32+ messages in thread From: Hans-Peter Nilsson @ 2020-08-18 15:17 UTC (permalink / raw) To: Pip Cet; +Cc: gcc On Sun, 16 Aug 2020, Pip Cet via Gcc wrote: > For example, here's what I currently have: > > (define_expand "mov<mode>" > [(parallel [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "") > (match_operand:MOVMODE 1 "general_operand" "")) > (clobber (reg:CC REG_CC))])] > ...) > > (define_insn "mov<mode>_insn" > [(set (match_operand:ALL1 0 "nonimmediate_operand" "=r,r ,d ,Qm > ,r ,q,r,*r") > (match_operand:ALL1 1 "nox_general_operand" "r,Y00,n Ynn,r > Y00,Qm,r,q,i")) > (clobber (match_scratch:CC 2 "=X,c,X,c,c,X,X,c"))] > ...) > > That works, but it results in an incorrect CC clobber for, say, > register-to-register movqi. For that, I'd need something like Another way to re-use an existing "cc" attribute from cc0 times is like I did in a82c9fb3f70 (supporting machinery and movsi usage), minimizing code edits and duplication when using it for CC-setting insns. For an example of that, see the subsequent commit a33649e6664. (Just decorate the insn name with the appropriate define_subst ornament!) I'll be quiet now, but good luck. brgds, H-P ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-14 11:16 Clobber REG_CC only for some constraint alternatives? Senthil Kumar Selvaraj 2020-08-14 15:32 ` Matt Wette 2020-08-14 16:23 ` Segher Boessenkool @ 2020-08-16 3:25 ` Hans-Peter Nilsson 2020-08-19 5:57 ` Senthil Kumar Selvaraj 2020-08-17 16:45 ` Jeff Law 3 siblings, 1 reply; 32+ messages in thread From: Hans-Peter Nilsson @ 2020-08-16 3:25 UTC (permalink / raw) To: Senthil Kumar Selvaraj; +Cc: gcc, ebotcazou On Fri, 14 Aug 2020, Senthil Kumar Selvaraj via Gcc wrote: > As you can deduce from the (set_attr "cc" ..), only constraint > alternatives 0,2,3 and 6 clobber CC - others leave it unchanged. Yes, I recognize that. > My first version of the port adds a post-reload splitter that adds a > (clobber (reg:CC REG_CC)) unconditionally, and it appears to work. Ouch, temporarily lying to gcc here. > If I > do want to add the clobber conditionally, would something like the below > be a good way to do it (get_cc_reg_clobber_rtx returns either const0_rtx > or cc_reg_rtx based on get_attr_cc (insn))? Or is there a better/cleaner way? I suggest having a look at what I did for the CRIS port. Check the git history. In short: - Add the clobber initially, to *all* patterns. - Add postreload splitters for the special combinations that don't clobber CC (ones without clobbering CC). - Use the old "cc" attribute to control and generate clobber/useful CC-setting alternatives (for various new CC_ modes) with use of define_subst. No regressions in CC quality (with one pending patch). brgds, H-P ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-16 3:25 ` Hans-Peter Nilsson @ 2020-08-19 5:57 ` Senthil Kumar Selvaraj 2020-08-19 22:31 ` Hans-Peter Nilsson 0 siblings, 1 reply; 32+ messages in thread From: Senthil Kumar Selvaraj @ 2020-08-19 5:57 UTC (permalink / raw) To: Hans-Peter Nilsson; +Cc: Senthil Kumar Selvaraj, gcc, ebotcazou Hans-Peter Nilsson writes: > On Fri, 14 Aug 2020, Senthil Kumar Selvaraj via Gcc wrote: >> As you can deduce from the (set_attr "cc" ..), only constraint >> alternatives 0,2,3 and 6 clobber CC - others leave it unchanged. > > Yes, I recognize that. > >> My first version of the port adds a post-reload splitter that adds a >> (clobber (reg:CC REG_CC)) unconditionally, and it appears to work. > > Ouch, temporarily lying to gcc here. > >> If I >> do want to add the clobber conditionally, would something like the below >> be a good way to do it (get_cc_reg_clobber_rtx returns either const0_rtx >> or cc_reg_rtx based on get_attr_cc (insn))? Or is there a better/cleaner way? > > I suggest having a look at what I did for the CRIS port. > Check the git history. > > In short: > - Add the clobber initially, to *all* patterns. > - Add postreload splitters for the special combinations that > don't clobber CC (ones without clobbering CC). > - Use the old "cc" attribute to control and generate > clobber/useful CC-setting alternatives (for various new CC_ > modes) with use of define_subst. This sounds like a great plan - the idea of always generating insn variants for however many CCmodes are available, and then using cc_enabled to disable them selectively (based on the attribute value corresponding to the alternative chosen) looks really neat. I did not understand the purpose of subst_attr for "ccnz" "ccnzvc" and "cccc" though - wouldn't a (set_attr "cc_enabled", "...") do the same thing? Also, I already have a version that hides REG_CC until reload (based on the suggestion in the wiki page), but I guess this approach will work equally well with that too? Regards Senthil ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-19 5:57 ` Senthil Kumar Selvaraj @ 2020-08-19 22:31 ` Hans-Peter Nilsson 2020-08-20 5:40 ` Senthil Kumar Selvaraj 0 siblings, 1 reply; 32+ messages in thread From: Hans-Peter Nilsson @ 2020-08-19 22:31 UTC (permalink / raw) To: Senthil Kumar Selvaraj; +Cc: gcc, ebotcazou On Wed, 19 Aug 2020, Senthil Kumar Selvaraj wrote: > > Hans-Peter Nilsson writes: > > > On Fri, 14 Aug 2020, Senthil Kumar Selvaraj via Gcc wrote: > >> As you can deduce from the (set_attr "cc" ..), only constraint > >> alternatives 0,2,3 and 6 clobber CC - others leave it unchanged. > > > > Yes, I recognize that. > > > >> My first version of the port adds a post-reload splitter that adds a > >> (clobber (reg:CC REG_CC)) unconditionally, and it appears to work. > > > > Ouch, temporarily lying to gcc here. > > > >> If I > >> do want to add the clobber conditionally, would something like the below > >> be a good way to do it (get_cc_reg_clobber_rtx returns either const0_rtx > >> or cc_reg_rtx based on get_attr_cc (insn))? Or is there a better/cleaner way? > > > > I suggest having a look at what I did for the CRIS port. > > Check the git history. > > > > In short: > > - Add the clobber initially, to *all* patterns. > > - Add postreload splitters for the special combinations that > > don't clobber CC (ones without clobbering CC). > > - Use the old "cc" attribute to control and generate > > clobber/useful CC-setting alternatives (for various new CC_ > > modes) with use of define_subst. > > This sounds like a great plan - the idea of always generating insn > variants for however many CCmodes are available, and then using > cc_enabled to disable them selectively (based on the attribute value > corresponding to the alternative chosen) looks really neat. I did not > understand the purpose of subst_attr for "ccnz" "ccnzvc" and "cccc" > though - wouldn't a (set_attr "cc_enabled", "...") do the same thing? You mean adding a whole new line with separate per-alternative settings instead of just a suffix to the name, per instruction, to get it compare-elim-optimized? (Ok, plus a tweak to SELECT_CC_MODE; see a33649e). That's not simpler to me, and error-prone without benefits. Note that the "cc" attribute was already there from cc0 times, just as for AVR! But beware, the cc attributes *might* need tweaking, and also note that disabling an alternative for an insn may make gcc pick a subsequent one, which may be invalid when matching operands for the disabled alternative. But that's the simplistic and obvious reply, perhaps I'm misinterpreting and you mean something else? For the purpose of the different CCmodes, see cris-modes.def, in particular the second paragraph, which I'm not repeating here. > Also, I already have a version that hides REG_CC until reload (based on > the suggestion in the wiki page), but I guess this approach will work > equally well with that too? Ow, I see it does! I don't know, that's unchartered territory to me, but it does seem like visium was written that way. It seems a bit wordy though; the define_split isn't necessary if you have the clobber from the start and use define_subst for the other alternatives. You still need splitters for special-cases of insns where condition codes aren't affected though. If these "special cases" approach being the norm, then I don't know. IMHO, introducing REG_CC clobbers only *after* reload seems like it could backfire. Doing things behind gcc's back is what we're eliminating, not re-introducing, to be dogmatic. That wiki page mentions using define_subst to avoid all (near-)duplicates, but not in its examples. brgds, H-P ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-19 22:31 ` Hans-Peter Nilsson @ 2020-08-20 5:40 ` Senthil Kumar Selvaraj 2020-08-20 8:51 ` Andrew Stubbs 2020-08-20 16:53 ` Hans-Peter Nilsson 0 siblings, 2 replies; 32+ messages in thread From: Senthil Kumar Selvaraj @ 2020-08-20 5:40 UTC (permalink / raw) To: Hans-Peter Nilsson; +Cc: Senthil Kumar Selvaraj, gcc, ebotcazou Hans-Peter Nilsson writes: > On Wed, 19 Aug 2020, Senthil Kumar Selvaraj wrote: >> >> Hans-Peter Nilsson writes: >> >> > On Fri, 14 Aug 2020, Senthil Kumar Selvaraj via Gcc wrote: >> >> As you can deduce from the (set_attr "cc" ..), only constraint >> >> alternatives 0,2,3 and 6 clobber CC - others leave it unchanged. >> > >> > Yes, I recognize that. >> > >> >> My first version of the port adds a post-reload splitter that adds a >> >> (clobber (reg:CC REG_CC)) unconditionally, and it appears to work. >> > >> > Ouch, temporarily lying to gcc here. >> > >> >> If I >> >> do want to add the clobber conditionally, would something like the below >> >> be a good way to do it (get_cc_reg_clobber_rtx returns either const0_rtx >> >> or cc_reg_rtx based on get_attr_cc (insn))? Or is there a better/cleaner way? >> > >> > I suggest having a look at what I did for the CRIS port. >> > Check the git history. >> > >> > In short: >> > - Add the clobber initially, to *all* patterns. >> > - Add postreload splitters for the special combinations that >> > don't clobber CC (ones without clobbering CC). >> > - Use the old "cc" attribute to control and generate >> > clobber/useful CC-setting alternatives (for various new CC_ >> > modes) with use of define_subst. >> >> This sounds like a great plan - the idea of always generating insn >> variants for however many CCmodes are available, and then using >> cc_enabled to disable them selectively (based on the attribute value >> corresponding to the alternative chosen) looks really neat. I did not >> understand the purpose of subst_attr for "ccnz" "ccnzvc" and "cccc" >> though - wouldn't a (set_attr "cc_enabled", "...") do the same thing? > > You mean adding a whole new line with separate per-alternative > settings instead of just a suffix to the name, per instruction, > to get it compare-elim-optimized? (Ok, plus a tweak to > SELECT_CC_MODE; see a33649e). That's not simpler to me, and > error-prone without benefits. Note that the "cc" attribute was > already there from cc0 times, just as for AVR! > > But beware, the cc attributes *might* need tweaking, and also > note that disabling an alternative for an insn may make gcc pick > a subsequent one, which may be invalid when matching operands > for the disabled alternative. > > But that's the simplistic and obvious reply, perhaps I'm > misinterpreting and you mean something else? For the purpose of > the different CCmodes, see cris-modes.def, in particular the > second paragraph, which I'm not repeating here. My question was a lot more basic. From the internals documentation, I understand that, with define_subst_attr for setcc, setnz and setnzc, and the corresponding define_substs, (define_insn "*movsi_internal<setcc><setnz><setnzvc> ...) results in a (define_insn "*movsi_internal ...) and in addition to that, (define_insn "*movsi_internal_setcc ...) // output template of setcc_subst (define_insn "*movsi_internal_setnz ...) // output template of setnz_subst (define_insn "*movsi_internal_setnzvc ...) // output template of setnzvc_subst I understood why this was done. What I didn't understand was the (set-attr "cc<cccc><ccnz><ccnzvc>") part - as far I can tell, this results in (set_attr "cc_enabled" ...) in all of the three substituted patterns, so I wondered why not just have (set_attr "cc_enabled" ...) in the original define_insn instead. I now realize that with (set-attr "cc<cccc><ccnz><ccnzvc>"), the original unsubstituted pattern will have only a (set_attr "cc" ...) and would therefore not match the attr check for "enabled" - correctly so, as the original insn pattern clobbers CRIS_CC0_REGNUM. Did I get that right? > >> Also, I already have a version that hides REG_CC until reload (based on >> the suggestion in the wiki page), but I guess this approach will work >> equally well with that too? > > Ow, I see it does! I don't know, that's unchartered territory > to me, but it does seem like visium was written that way. It > seems a bit wordy though; the define_split isn't necessary if > you have the clobber from the start and use define_subst for the > other alternatives. You still need splitters for special-cases > of insns where condition codes aren't affected though. If these > "special cases" approach being the norm, then I don't know. Ok, I'll try the cris approach too, and see if it makes any difference. > > IMHO, introducing REG_CC clobbers only *after* reload seems like > it could backfire. Doing things behind gcc's back is what we're > eliminating, not re-introducing, to be dogmatic. > > That wiki page mentions using define_subst to avoid all > (near-)duplicates, but not in its examples. Yes, I saw that too. Regards Senthil ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-20 5:40 ` Senthil Kumar Selvaraj @ 2020-08-20 8:51 ` Andrew Stubbs 2020-08-20 10:59 ` H.J. Lu 2020-08-20 16:53 ` Hans-Peter Nilsson 1 sibling, 1 reply; 32+ messages in thread From: Andrew Stubbs @ 2020-08-20 8:51 UTC (permalink / raw) To: Senthil Kumar Selvaraj, Hans-Peter Nilsson; +Cc: gcc, ebotcazou On 20/08/2020 06:40, Senthil Kumar Selvaraj via Gcc wrote: > What I didn't understand was the (set-attr "cc<cccc><ccnz><ccnzvc>") > part - as far I can tell, this results in (set_attr "cc_enabled" ...) in > all of the three substituted patterns, so I wondered why not just have > (set_attr "cc_enabled" ...) in the original define_insn instead. > > I now realize that with (set-attr "cc<cccc><ccnz><ccnzvc>"), the original > unsubstituted pattern will have only a (set_attr "cc" ...) and would > therefore not match the attr check for "enabled" - correctly so, as the > original insn pattern clobbers CRIS_CC0_REGNUM. Did I get that right? The best (only?) way to understand define_subst is to read the expanded machine description. This is not written anywhere, by default, but there's a way to get it. cd <build>/gcc make mddump less tmp-mddump.md Not only are all the define_subst expanded, but so are all the other iterators. HTH Andrew ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-20 8:51 ` Andrew Stubbs @ 2020-08-20 10:59 ` H.J. Lu 0 siblings, 0 replies; 32+ messages in thread From: H.J. Lu @ 2020-08-20 10:59 UTC (permalink / raw) To: Andrew Stubbs Cc: Senthil Kumar Selvaraj, Hans-Peter Nilsson, GCC Development, Eric Botcazou On Thu, Aug 20, 2020 at 1:53 AM Andrew Stubbs <ams@codesourcery.com> wrote: > > On 20/08/2020 06:40, Senthil Kumar Selvaraj via Gcc wrote: > > What I didn't understand was the (set-attr "cc<cccc><ccnz><ccnzvc>") > > part - as far I can tell, this results in (set_attr "cc_enabled" ...) in > > all of the three substituted patterns, so I wondered why not just have > > (set_attr "cc_enabled" ...) in the original define_insn instead. > > > > I now realize that with (set-attr "cc<cccc><ccnz><ccnzvc>"), the original > > unsubstituted pattern will have only a (set_attr "cc" ...) and would > > therefore not match the attr check for "enabled" - correctly so, as the > > original insn pattern clobbers CRIS_CC0_REGNUM. Did I get that right? > > The best (only?) way to understand define_subst is to read the expanded > machine description. This is not written anywhere, by default, but > there's a way to get it. > > cd <build>/gcc > make mddump > less tmp-mddump.md > > Not only are all the define_subst expanded, but so are all the other > iterators. Shouldn't it be documented? -- H.J. ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-20 5:40 ` Senthil Kumar Selvaraj 2020-08-20 8:51 ` Andrew Stubbs @ 2020-08-20 16:53 ` Hans-Peter Nilsson 1 sibling, 0 replies; 32+ messages in thread From: Hans-Peter Nilsson @ 2020-08-20 16:53 UTC (permalink / raw) To: Senthil Kumar Selvaraj; +Cc: gcc On Thu, 20 Aug 2020, Senthil Kumar Selvaraj wrote: > What I didn't understand was the (set-attr "cc<cccc><ccnz><ccnzvc>") > part - as far I can tell, this results in (set_attr "cc_enabled" ...) in > all of the three substituted patterns, so I wondered why not just have > (set_attr "cc_enabled" ...) in the original define_insn instead. > > I now realize that with (set-attr "cc<cccc><ccnz><ccnzvc>"), the original > unsubstituted pattern will have only a (set_attr "cc" ...) and would > therefore not match the attr check for "enabled" - correctly so, as the > original insn pattern clobbers CRIS_CC0_REGNUM. Did I get that right? Aha: yes, correct. Attribute "cc" is now "unused" in the original (un-subst:ed) insn. Commit a82c9fb3. brgds, H-P ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: Clobber REG_CC only for some constraint alternatives? 2020-08-14 11:16 Clobber REG_CC only for some constraint alternatives? Senthil Kumar Selvaraj ` (2 preceding siblings ...) 2020-08-16 3:25 ` Hans-Peter Nilsson @ 2020-08-17 16:45 ` Jeff Law 3 siblings, 0 replies; 32+ messages in thread From: Jeff Law @ 2020-08-17 16:45 UTC (permalink / raw) To: Senthil Kumar Selvaraj, gcc; +Cc: ebotcazou On Fri, 2020-08-14 at 16:46 +0530, Senthil Kumar Selvaraj wrote: > Hi, > > I'm working on porting AVR to MODE_CC, and there are quite a few > patterns that clobber the condition code reg only for certain > constraint alternatives. For e.g., Yea. H8 has the same issue. It's worth noting that showing a clobber for the CC register even when the bits aren't clobbered is safe. So I started with that on the H8, even though it did result in some code efficiency regressions. Then I started pulling apart those patterns when testing showed it was worth the effort. Jeff ^ permalink raw reply [flat|nested] 32+ messages in thread
end of thread, other threads:[~2020-09-01 19:38 UTC | newest] Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-08-14 11:16 Clobber REG_CC only for some constraint alternatives? Senthil Kumar Selvaraj 2020-08-14 15:32 ` Matt Wette 2020-08-14 17:42 ` Pip Cet 2020-08-14 16:23 ` Segher Boessenkool 2020-08-14 17:47 ` Pip Cet 2020-08-15 0:29 ` Segher Boessenkool 2020-08-15 10:18 ` Pip Cet 2020-08-16 0:50 ` Segher Boessenkool 2020-08-16 18:28 ` Pip Cet 2020-08-17 7:31 ` Senthil Kumar Selvaraj 2020-08-17 9:18 ` Pip Cet 2020-08-18 6:52 ` Senthil Kumar Selvaraj 2020-08-20 11:51 ` Pip Cet 2020-08-20 16:06 ` Senthil Kumar Selvaraj 2020-08-24 18:18 ` Jeff Law 2020-08-26 3:58 ` Hans-Peter Nilsson 2020-08-26 16:20 ` Jeff Law 2020-08-26 18:26 ` Hans-Peter Nilsson 2020-08-26 11:18 ` Pip Cet 2020-08-26 16:21 ` Jeff Law [not found] ` <87h7so2w0c.fsf@gcc.gnu.org> 2020-08-27 14:48 ` Jeff Law 2020-09-01 19:38 ` Hans-Peter Nilsson 2020-08-17 17:21 ` Segher Boessenkool 2020-08-18 15:17 ` Hans-Peter Nilsson 2020-08-16 3:25 ` Hans-Peter Nilsson 2020-08-19 5:57 ` Senthil Kumar Selvaraj 2020-08-19 22:31 ` Hans-Peter Nilsson 2020-08-20 5:40 ` Senthil Kumar Selvaraj 2020-08-20 8:51 ` Andrew Stubbs 2020-08-20 10:59 ` H.J. Lu 2020-08-20 16:53 ` Hans-Peter Nilsson 2020-08-17 16:45 ` Jeff Law
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).