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,

> On Fri, Jun 20, 2003 at 12:29:18AM +0200, Zdenek Dvorak wrote:
> > crtstuff.c:287: error: unrecognizable insn:
> > (insn 83 0 54 (set (subreg:SI (reg:CC 68) 0)
> >         (subreg:SI (reg:CC 17 flags) 0)) -1 (nil)
> >     (nil))
> > crtstuff.c:287: internal compiler error: in extract_insn, at recog.c:2191
> 
> Ok, got it.
> 
> Problem is 
> 
> recog.c:
> 1012        /* A register whose class is NO_REGS is not a general operand.  */
> 1013        return (REGNO (op) >= FIRST_PSEUDO_REGISTER
> 1014                || REGNO_REG_CLASS (REGNO (op)) != NO_REGS);
> 
> I.e. we must provide a movcc pattern on x86.

I currently don't have a time to do it.  Would the following solution
be acceptable in the meantime?

Zdenek


Index: config/i386/i386.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.h,v
retrieving revision 1.345
diff -c -3 -p -r1.345 i386.h
*** config/i386/i386.h	19 Jun 2003 21:47:11 -0000	1.345
--- config/i386/i386.h	21 Jun 2003 21:15:08 -0000
*************** do {									\
*** 1115,1120 ****
--- 1115,1123 ----
  	       && (TARGET_64BIT || !TARGET_PARTIAL_REG_STALL))	\
  	   || ((MODE2) == DImode && TARGET_64BIT))))
  
+ /* It is possible to write patterns to move flags; but until someone
+    does it,  */
+ #define AVOID_CCMODE_COPIES
  
  /* Specify the modes required to caller save a given hard regno.
     We do this on i386 to prevent flags from being saved at all.
Index: cfgrtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgrtl.c,v
retrieving revision 1.81
diff -c -3 -p -r1.81 cfgrtl.c
*** cfgrtl.c	13 Jun 2003 22:56:09 -0000	1.81
--- cfgrtl.c	21 Jun 2003 21:15:03 -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,1438 ----
  
    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);
+   if (regno >= FIRST_PSEUDO_REGISTER)
+     SET_REGNO_REG_SET (killed, regno);
+   else
+     {
+       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, noccmode;
+   enum machine_mode mode;
+ 
+ #ifdef AVOID_CCMODE_COPIES
+   noccmode = true;
+ #else
+   noccmode = false;
+ #endif
+ 
+   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;
+ 
+       if (noccmode && mode == CCmode)
+ 	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;
+ 
+       start_sequence ();
+       for (x = save_regs; x; x = XEXP (x, 1))
+ 	{
+ 	  from = XEXP (XEXP (x, 0), 1);
+ 	  to = XEXP (XEXP (x, 0), 0);
+ 	  emit_move_insn (to, from);
+ 	}
+       emit_insn (insn);
+       for (x = save_regs; x; x = XEXP (x, 1))
+ 	{
+ 	  from = XEXP (XEXP (x, 0), 0);
+ 	  to = XEXP (XEXP (x, 0), 1);
+ 	  emit_move_insn (to, from);
+ 	}
+       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]