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: RFC: reloading sums


        * reload.c (can_reload_into): New function.

Oops, I forgot extract_insn.  It didn't show up in any of the
tests because the only code I found so far that hits this condition
is the original testcase, and there recog_memoized already rejects
the add.
		
-- 
--------------------------
SuperH (UK) Ltd.
2410 Aztec West / Almondsbury / BRISTOL / BS32 4QX
T:+44 1454 465658
2003-06-19  J"orn Rennecke <joern.rennecke@superh.com>

	* reload.c (can_reload_into): New function.
	(push_reload): Use it.

Index: reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.214
diff -p -r1.214 reload.c
*** reload.c	12 Jun 2003 19:01:08 -0000	1.214
--- reload.c	19 Jun 2003 19:03:53 -0000
*************** reload_inner_reg_of_subreg (x, mode, out
*** 840,845 ****
--- 840,898 ----
  	      != (int) HARD_REGNO_NREGS (REGNO (inner), GET_MODE (inner))));
  }
  
+ /* Return nonzero if IN can be reloaded into REGNO with mode MODE without
+    requiring an extra reload register.  The caller has already found that
+    IN contains some reference to REGNO, so check that we can produce the
+    new value in a single step.  E.g. if we have
+    (set (reg r13) (plus (reg r13) (const int 1))), and there is an
+    instruction that adds one to a register, this should succeed.
+    However, if we have something like
+    (set (reg r13) (plus (reg r13) (const int 999))), and the constant 999
+    needs to be loaded into a register first, we need a separate reload
+    register.  */
+ static int
+ can_reload_into (rtx in, int regno, enum machine_mode mode)
+ {
+   rtx dst, test_insn;
+   int r = 0;
+   struct recog_data save_recog_data;
+ 
+   /* For matching constraints, we often get notional input reloads where
+      we want to use the original register as the reload register.  Speed
+      this up, since it trivially works.  */
+   if (in->code == REG)
+     return 1;
+ 
+   /* To test MEMs properly, we'd have to take into account all the reloads
+      that are already scheduled, which can become quite complicated.
+      And since we've already handled addres reloads for this MEM, it
+      should always succeed anyway.  */
+   if (in->code == MEM)
+     return 1;
+ 
+   /* If we can make a simple SET insn that does the job, everything should
+      be fine.  */
+   dst =  gen_rtx_REG (mode, regno);
+   test_insn = make_insn_raw (gen_rtx_SET (VOIDmode, dst, in));
+   save_recog_data = recog_data;
+   if (recog_memoized (test_insn) >= 0)
+     {
+       extract_insn (test_insn);
+       r = constrain_operands (1);
+     }
+   recog_data = save_recog_data;
+ #if 1
+ {
+   int c = -1;
+   if (GET_CODE (in) == PLUS && GET_CODE (XEXP (in, 1)) == CONST_INT)
+     c = INTVAL (XEXP (in, 1));
+   debug_rtx(PATTERN (test_insn));
+   printf ("can_reload_into returns %d (constant %d)\n", r, c);
+ }
+ #endif
+   return r;
+ }
+ 
  /* Record one reload that needs to be performed.
     IN is an rtx saying where the data are to be found before this instruction.
     OUT says where they must be stored after the instruction.
*************** push_reload (in, out, inloc, outloc, cla
*** 1532,1538 ****
  					  regno + offs))
  		break;
  
! 	    if (offs == nregs)
  	      {
  		rld[i].reg_rtx = gen_rtx_REG (rel_mode, regno);
  		break;
--- 1585,1595 ----
  					  regno + offs))
  		break;
  
! 	    if (offs == nregs
! 		&& (! (refers_to_regno_for_reload_p
! 		       (regno, (regno + HARD_REGNO_NREGS (regno, inmode)),
! 				in, (rtx *)0))
! 		    || can_reload_into (in, regno, inmode)))
  	      {
  		rld[i].reg_rtx = gen_rtx_REG (rel_mode, regno);
  		break;

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