This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH for [ARM] subsequent use of plus and minus operators couldbe improved


Joern Rennecke wrote:
+ next = NEXT_INSN (insn);

If you only handle adjacent instructions, and don't use the data available in reload_cse_move2add, putting the code there is just confusing. You could put that code into any old loop that traverses the insns. In that respect, I think your previous patch that did a separate traversal was better. If we really save a worthwhile amount of time by traversing the insns only once - that would have to be because of better memory locality, as putting too much into a single function tends to screw up register allocation - then we should just merge all the post-reload operations that don't need to run sequentially into one huge glob of code.

Doing your transformation without a cost check is also a bit dubious,

I have no information about how I can do this cost check correctly.


although with a well-written machine description, any disadvantagous
combination will probably be undone in the pre-sched2 instruction
splitting pass.

+               rtx new_value = GEN_INT (INTVAL (XEXP (insn_src, 1)) +
+                                        INTVAL (XEXP (next_src, 1)));

This new constant that you create can end up with incorrect sign extension.



Thanks, I missed it. Corrected patch can be seen in the attached file.


Regards,
	Gábor Lóki
*** orig/gcc/reload1.c	Sat Mar 29 00:22:05 2003
--- patch/gcc/reload1.c	Thu May  8 14:23:52 2003
*************** reload_cse_move2add (first)
*** 9130,9135 ****
--- 9130,9192 ----
        if (! INSN_P (insn))
  	continue;
        pat = PATTERN (insn);
+       
+       /* Try to transform 
+            (set (regX) (plus (regY) (constA)))
+            (set (regX) (plus (regX) (constB)))
+          to
+            (set (regX) (plus (regY) (constA + constB))) */
+       if (NEXT_INSN (insn)
+           && GET_MODE (insn) == VOIDmode
+           && GET_MODE (NEXT_INSN (insn)) == VOIDmode      
+           && GET_CODE (pat) == SET 
+           && GET_CODE (NEXT_INSN (insn)) == INSN 
+           && GET_CODE (PATTERN (NEXT_INSN (insn))) == SET)
+         {
+           rtx insn_dest, insn_src, next_dest, next_src;
+           insn_dest = SET_DEST (pat);
+           insn_src = SET_SRC (pat);
+           next_dest = SET_DEST (PATTERN (NEXT_INSN (insn)));
+           next_src = SET_SRC (PATTERN (NEXT_INSN (insn)));
+           
+           if (GET_CODE (insn_dest) == REG 
+               && GET_CODE (insn_src) == PLUS 
+               && GET_CODE (XEXP (insn_src, 0)) == REG 
+               && GET_CODE (XEXP (insn_src, 1)) == CONST_INT 
+               && GET_CODE (next_dest) == REG 
+               && GET_CODE (next_src) == PLUS 
+               && GET_CODE (XEXP (next_src, 0)) == REG 
+               && GET_CODE (XEXP (next_src, 1)) == CONST_INT 
+               && REGNO (insn_dest) == REGNO (next_dest) 
+               && REGNO (next_dest) == REGNO (XEXP (next_src, 0)))
+             {
+               int success = 0;
+               HOST_WIDE_INT constA = INTVAL (XEXP (insn_src, 1));
+               HOST_WIDE_INT constB = INTVAL (XEXP (next_src, 1));
+               HOST_WIDE_INT constSum = constA + constB;
+               
+               /* Overflow occurs if constA and constB have the same sign, but
+                  constA and constSum differ in sign. Use `^' to test whether 
+                  signs differ, and `>= 0' to isolate the sign.  */ 
+               if (~(constA ^ constB) & (constA ^ constSum) >= 0)
+                 {
+                   if (constSum == 0)
+                     /* Create (set (regX) (regY)) if the new 
+                        constant is zero.  */
+                     success = validate_change (insn, 
+                                                &SET_SRC (pat), 
+                                                XEXP (insn_src,0), 0);
+                   else                                          
+                     /* Otherwise, replace constA with the new constant.  */
+                     success = validate_change (insn, 
+                                                &XEXP (insn_src, 1),
+                                                GEN_INT (constSum), 0);
+                   if (success)
+                     delete_insn (NEXT_INSN (insn));
+                 }
+             }   
+         }
+ 
        /* For simplicity, we only perform this optimization on
  	 straightforward SETs.  */
        if (GET_CODE (pat) == SET

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]