This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch: division by const improvement
- To: gcc-patches at gcc dot gnu dot org
- Subject: Patch: division by const improvement
- From: Dale Johannesen <dalej at apple dot com>
- Date: Fri, 26 Oct 2001 15:17:39 -0700
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