Re: [PATCH 6/7] ira.c use DF infrastructure for combine_and_move_insns

2016-03-22 Thread Alan Modra
On Tue, Mar 22, 2016 at 05:29:08PM +0100, Bernd Schmidt wrote:
> On 03/21/2016 02:42 AM, Alan Modra wrote:
> > * ira.c (combine_and_move_insns): Rather than scanning insns,
> > use DF infrastucture to find use and def insns.
> >
> >-  remove_death (regno, insn);
> 
> This call appears to have gone missing. Is that intentional?

No, well spotted.  Reinstated.

-- 
Alan Modra
Australia Development Lab, IBM


Re: [PATCH 6/7] ira.c use DF infrastructure for combine_and_move_insns

2016-03-22 Thread Bernd Schmidt

On 03/21/2016 02:42 AM, Alan Modra wrote:

* ira.c (combine_and_move_insns): Rather than scanning insns,
use DF infrastucture to find use and def insns.

- remove_death (regno, insn);


This call appears to have gone missing. Is that intentional?

Other than that it looks good for stage1.


Bernd


[PATCH 6/7] ira.c use DF infrastructure for combine_and_move_insns

2016-03-20 Thread Alan Modra
This patch actually improves generated code, because REG_DEAD notes
used by the old insn scan are not always present.  On x86_64, see
gcc/wide-int-print.o:print_hex for an example of a function that is
smaller and uses one less callee saved reg.

* ira.c (combine_and_move_insns): Rather than scanning insns,
use DF infrastucture to find use and def insns.

diff --git a/gcc/ira.c b/gcc/ira.c
index 1cace25..aa721fa 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -3628,137 +3628,113 @@ add_store_equivs (void)
 static void
 combine_and_move_insns (void)
 {
-  rtx_insn *insn;
-  basic_block bb;
-  int loop_depth;
   bitmap cleared_regs = BITMAP_ALLOC (NULL);
+  int max = max_reg_num ();
 
-  FOR_EACH_BB_REVERSE_FN (bb, cfun)
+  for (int regno = FIRST_PSEUDO_REGISTER; regno < max; regno++)
 {
-  loop_depth = bb_loop_depth (bb);
-  for (insn = BB_END (bb);
-  insn != PREV_INSN (BB_HEAD (bb));
-  insn = PREV_INSN (insn))
-   {
- rtx link;
+  if (!reg_equiv[regno].replace)
+   continue;
 
- if (! INSN_P (insn))
-   continue;
+  rtx_insn *use_insn = 0;
+  for (df_ref use = DF_REG_USE_CHAIN (regno);
+  use;
+  use = DF_REF_NEXT_REG (use))
+   if (DF_REF_INSN_INFO (use))
+ {
+   if (DEBUG_INSN_P (DF_REF_INSN (use)))
+ continue;
+   gcc_assert (!use_insn);
+   use_insn = DF_REF_INSN (use);
+ }
+  gcc_assert (use_insn);
 
- /* Don't substitute into jumps.  indirect_jump_optimize does
-this for anything we are prepared to handle.  */
- if (JUMP_P (insn))
-   continue;
+  /* Don't substitute into jumps.  indirect_jump_optimize does
+this for anything we are prepared to handle.  */
+  if (JUMP_P (use_insn))
+   continue;
 
- for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
-   {
- if (REG_NOTE_KIND (link) == REG_DEAD
- /* Make sure this insn still refers to the register.  */
- && reg_mentioned_p (XEXP (link, 0), PATTERN (insn)))
-   {
- int regno = REGNO (XEXP (link, 0));
- rtx equiv_insn;
+  df_ref def = DF_REG_DEF_CHAIN (regno);
+  gcc_assert (DF_REG_DEF_COUNT (regno) == 1 && DF_REF_INSN_INFO (def));
+  rtx_insn *def_insn = DF_REF_INSN (def);
 
- if (! reg_equiv[regno].replace
- || reg_equiv[regno].loop_depth < (short) loop_depth)
-   continue;
+  /* We may not move instructions that can throw, since that
+changes basic block boundaries and we are not prepared to
+adjust the CFG to match.  */
+  if (can_throw_internal (def_insn))
+   continue;
 
- /* reg_equiv[REGNO].replace gets set only when
-REG_N_REFS[REGNO] is 2, i.e. the register is set
-once and used once.  (If it were only set, but
-not used, flow would have deleted the setting
-insns.)  Hence there can only be one insn in
-reg_equiv[REGNO].init_insns.  */
- gcc_assert (reg_equiv[regno].init_insns
- && !XEXP (reg_equiv[regno].init_insns, 1));
- equiv_insn = XEXP (reg_equiv[regno].init_insns, 0);
-
- /* We may not move instructions that can throw, since
-that changes basic block boundaries and we are not
-prepared to adjust the CFG to match.  */
- if (can_throw_internal (equiv_insn))
-   continue;
+  basic_block use_bb = BLOCK_FOR_INSN (use_insn);
+  basic_block def_bb = BLOCK_FOR_INSN (def_insn);
+  if (bb_loop_depth (use_bb) > bb_loop_depth (def_bb))
+   continue;
 
- if (asm_noperands (PATTERN (equiv_insn)) < 0
- && validate_replace_rtx (regno_reg_rtx[regno],
-  *(reg_equiv[regno].src_p), insn))
-   {
- rtx equiv_link;
- rtx last_link;
- rtx note;
-
- /* Find the last note.  */
- for (last_link = link; XEXP (last_link, 1);
-  last_link = XEXP (last_link, 1))
-   ;
-
- /* Append the REG_DEAD notes from equiv_insn.  */
- equiv_link = REG_NOTES (equiv_insn);
- while (equiv_link)
-   {
- note = equiv_link;
- equiv_link = XEXP (equiv_link, 1);
- if (REG_NOTE_KIND (note) == REG_DEAD)
-   {
- remove_note (equiv_insn, note);
- XEXP (last_link, 1) = note;
- XEXP (note, 1) = NULL_RTX;
-