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]

Patch: division by const improvement


This patch performs the division-by-constant optimization in cases
where the opportunity arises through constant propagation in gcse.
Bootstrapped on Darwin.  [I'd prefer delete_insn() to the
NOTE_INSN_DELETED changes, and it did bootstrap that way, but
NEXT_INSN(insn) is referenced a couple of functions up, and I'm
not sure that's valid after delete_insn() has been called.  Is it?]

2001-10-26  Dale Johannesen  <dalej@apple.com>

         * gcse.c (cprop_insn):  check for new opportunities to
             do divide-by-int-const optimization, and do it
           gcse.c (gcse_main):  extra bookkeeping required by above
           gcse.c:  include "tree.h" (for TRUNC_DIV_EXPR)


Index: gcse.c
===================================================================
RCS file: /cvs/Darwin/Commands/GNU/gcc/gcc/gcse.c,v
*************** Software Foundation, 59 Temple Place - S
*** 147,152 ****
--- 147,153 ----
   #include "toplev.h"

   #include "rtl.h"
+ #include "tree.h"
   #include "tm_p.h"
   #include "regs.h"
   #include "hard-reg-set.h"
*************** gcse_main (f, file)
*** 815,820 ****
--- 816,827 ----
          during this pass.  */
         changed = one_cprop_pass (pass + 1, 0);

+       /* div by const optimization can introduce new instructions.
+          All this stuff needs to be recomputed. */
+       free_gcse_mem ();
+       max_gcse_regno = max_reg_num ();
+       alloc_gcse_mem (f);
+
         if (optimize_size)
         changed |= one_classic_gcse_pass (pass + 1);
         else
*************** cprop_insn (bb, insn, alter_jumps)
*** 4214,4219 ****
--- 4221,4276 ----
               break;
             }
   #endif
+         /* Look for int div by constant and expand if found. */
+         if ( GET_CODE (insn) == INSN
+              && GET_CODE (PATTERN (insn)) == SET
+              && ( GET_CODE (XEXP (PATTERN (insn), 1)) == DIV
+                   || GET_CODE (XEXP (PATTERN (insn), 1)) == UDIV)
+              && GET_MODE (XEXP (PATTERN (insn), 1)) == SImode
+              && GET_CODE (XEXP (XEXP (PATTERN (insn), 1), 1)) == 
CONST_INT )
+           {
+             rtx seq;
+             start_sequence ();
+             expand_divmod (0, TRUNC_DIV_EXPR, SImode,
+                   XEXP (XEXP (PATTERN (insn), 1), 0),
+                   XEXP (XEXP (PATTERN (insn), 1), 1),
+                   XEXP (PATTERN (insn), 0),
+                   GET_CODE (XEXP (PATTERN (insn), 1))==DIV ? 0 : 1);
+             seq = gen_sequence ();
+             end_sequence ();
+             emit_insn_after (seq, insn);
+             PUT_CODE (insn, NOTE);
+             NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
+             NOTE_SOURCE_FILE (insn) = 0;
+             update_bb_for_insn (bb);
+             changed = 1;
+             break;
+           }
+         else if ( GET_CODE (insn) == INSN
+                  && GET_CODE (PATTERN (insn)) == SET
+                  && (note = find_reg_equal_equiv_note (insn))
+                  && (GET_CODE (XEXP (note, 0)) == DIV
+                      || GET_CODE (XEXP (note, 0)) == UDIV)
+                  && GET_MODE (XEXP (note, 0)) == SImode
+                  && GET_CODE (XEXP (XEXP (note, 0), 1)) == CONST_INT )
+           {
+             rtx seq;
+             start_sequence ();
+             expand_divmod (0, TRUNC_DIV_EXPR, SImode,
+                   XEXP (XEXP (note, 0), 0),
+                   XEXP (XEXP (note, 0), 1),
+                   XEXP (PATTERN (insn), 0),
+                   GET_CODE (XEXP (note, 0))==DIV ? 0 : 1);
+             seq = gen_sequence ();
+             end_sequence ();
+             emit_insn_after (seq, insn);
+             PUT_CODE (insn, NOTE);
+             NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
+             NOTE_SOURCE_FILE (insn) = 0;
+             update_bb_for_insn (bb);
+             changed = 1;
+             break;
+           }
         }
         else if (GET_CODE (src) == REG
                && REGNO (src) >= FIRST_PSEUDO_REGISTER


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