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] Value profile based optimizations, part 1


Hello,

> > + regset mkr_live;
> 
> Don't like the use of the global variable.
> 
> > +     SET_REGNO_REG_SET (killed, regno);
> 
> Need to iterate over HARD_REG_NREGS.
> 
> > +   mkr_live = e->dest->global_live_at_start;
> > +   for (x = insn; x; x = NEXT_INSN (x))
> > +     if (INSN_P (x))
> > +       note_stores (PATTERN (x), mark_killed_regs, killed);
> 
> Just clear global_live_at_start from killed after this loop
> to avoid the global variable.
> 
> > + 	  y = emit_insn (gen_rtx_SET (VOIDmode, to, from));
> 
> emit_move_insn, surely?

OK now (provided it passes testing)?

Zdenek

Index: cfgrtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgrtl.c,v
retrieving revision 1.80
diff -c -3 -p -r1.80 cfgrtl.c
*** cfgrtl.c	12 Jun 2003 18:09:55 -0000	1.80
--- cfgrtl.c	19 Jun 2003 00:58:54 -0000
*************** Software Foundation, 59 Temple Place - S
*** 56,61 ****
--- 56,63 ----
  #include "obstack.h"
  #include "insn-config.h"
  #include "cfglayout.h"
+ #include "recog.h"
+ #include "expr.h"
  
  /* Stubs in case we don't have a return insn.  */
  #ifndef HAVE_return
*************** static bool rtl_redirect_edge_and_branch
*** 88,93 ****
--- 90,96 ----
  static edge rtl_split_block		PARAMS ((basic_block, void *));
  static void rtl_dump_bb			PARAMS ((basic_block, FILE *));
  static int rtl_verify_flow_info_1	PARAMS ((void));
+ static void mark_killed_regs (rtx, rtx, void *);
  
  /* Return true if NOTE is not one of the ones that must be kept paired,
     so that we may simply delete it.  */
*************** insert_insn_on_edge (pattern, e)
*** 1335,1340 ****
--- 1338,1433 ----
  
    e->insns = get_insns ();
    end_sequence ();
+ }
+ 
+ /* Called from safe_insert_insn_on_edge through note_stores, marks live
+    registers that are killed by the store.  */
+ static void
+ mark_killed_regs (rtx reg, rtx set ATTRIBUTE_UNUSED, void *data)
+ {
+   regset killed = data;
+   int regno, i;
+ 
+   if (GET_CODE (reg) == SUBREG)
+     reg = SUBREG_REG (reg);
+   if (!REG_P (reg))
+     return;
+   regno = REGNO (reg);
+   
+   for (i = 0; i < HARD_REGNO_NREGS (regno, GET_MODE (reg)); i++)
+     SET_REGNO_REG_SET (killed, regno + i);
+ }
+ 
+ /* Similar to insert_insn_on_edge, tries to put INSN to edge E.  Additionally
+    it checks whether this will not clobber the registers that are live on the
+    edge (i.e. it requieres liveness information to be up-to-date) and if there
+    are some, then it tries to save and restore them.  Returns true if
+    succesful.  */
+ bool
+ safe_insert_insn_on_edge (rtx insn, edge e)
+ {
+   rtx x;
+   regset_head killed_head;
+   regset killed = INITIALIZE_REG_SET (killed_head);
+   rtx save_regs = NULL_RTX;
+   int regno;
+   enum machine_mode mode;
+ 
+   for (x = insn; x; x = NEXT_INSN (x))
+     if (INSN_P (x))
+       note_stores (PATTERN (x), mark_killed_regs, killed);
+   bitmap_operation (killed, killed, e->dest->global_live_at_start, BITMAP_AND);
+ 
+   EXECUTE_IF_SET_IN_REG_SET (killed, 0, regno,
+     {
+       mode = regno < FIRST_PSEUDO_REGISTER
+ 	      ? reg_raw_mode[regno]
+ 	      : GET_MODE (regno_reg_rtx[regno]);
+       if (mode == VOIDmode)
+ 	return false;
+       save_regs = alloc_EXPR_LIST (0,
+ 				   alloc_EXPR_LIST (0,
+ 						    gen_reg_rtx (mode),
+ 						    gen_raw_REG (mode, regno)),
+ 				   save_regs);
+     });
+ 
+   if (save_regs)
+     {
+       rtx from, to, y;
+ 
+       start_sequence ();
+       for (x = save_regs; x; x = XEXP (x, 1))
+ 	{
+ 	  from = XEXP (XEXP (x, 0), 1);
+ 	  to = XEXP (XEXP (x, 0), 0);
+ 	  y = emit_move_insn (to, from);
+ 	  if (recog (PATTERN (y), y, NULL) < 0)
+ 	    {
+ 	      end_sequence ();
+ 	      return false;
+ 	    }
+ 	}
+       emit_insn (insn);
+       for (x = save_regs; x; x = XEXP (x, 1))
+ 	{
+ 	  from = XEXP (XEXP (x, 0), 0);
+ 	  to = XEXP (XEXP (x, 0), 1);
+ 	  y = emit_move_insn (to, from);
+ 	  if (recog (PATTERN (y), y, NULL) < 0)
+ 	    {
+ 	      end_sequence ();
+ 	      return false;
+ 	    }
+ 	}
+       insn = get_insns ();
+       end_sequence ();
+       free_EXPR_LIST_list (&save_regs);
+     }
+   insert_insn_on_edge (insn, e);
+   
+   FREE_REG_SET (killed);
+   return true;
  }
  
  /* Update the CFG for the instructions queued on edge E.  */


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