addressof and alpha_expand_block_move

Richard Henderson rth@cygnus.com
Tue Jan 20 18:39:00 GMT 1998


I recently discovered a case in which addressof interacted badly
with the code I'd written for doing block moves, which resulted
in rtl that is not valid for the machine.

The simple way out was to just copy the address to a register and
be done with it, but it seemed to me that we could do something
nicer.

Here I allow addressof to be a part of an address, so that we 
are allowed to build constructs such as

(insn 2417 2415 2419 (set (reg:DI 807)
        (mem:DI (and:DI (plus:DI (addressof:DI (reg:DI 785) 134)
                    (const_int 1))
                (const_int -8)))) -1 (nil)
    (nil))

This by itself fixes the problem, since the purge_addressof routines
will fill in a register at the right place and whatnot.  But with a
little change we can keep this as one instruction

(insn 2417 2415 2421 (set (reg:DI 807)
        (mem:DI (and:DI (plus:DI (reg:DI 63 FP)
                    (const_int 25))
                (const_int -8)))) 272 {movsi+2} (nil)
    (nil))

It could be argued that combine should be taught about such things
(that is, merging a (plus R1 C) into (mem (and (plus R0 C))))...

Comments?


r~



Tue Jan 20 16:43:49 1998  Richard Henderson   <rth@cygnus.com>

	* function.c (fixup_var_refs_1): Recognize (plus addressof const) 
	and replace with something more optimal if possible.

	* alpha.h (GO_IF_LEGITIMATE_SIMPLE_ADDRESS): Allow addressof
	where we would accept a reg.


Index: function.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/function.c,v
retrieving revision 1.11
diff -c -p -d -r1.11 function.c
*** function.c	1998/01/20 10:02:05	1.11
--- function.c	1998/01/21 00:41:43
*************** fixup_var_refs_1 (var, promoted_mode, lo
*** 1735,1740 ****
--- 1735,1759 ----
  
    switch (code)
      {
+     case PLUS: 
+       if (GET_CODE (XEXP (x, 0)) == ADDRESSOF
+ 	  && XEXP (XEXP (x, 0), 0) == var
+ 	  && GET_CODE (XEXP (x, 1)) == CONST_INT)
+ 	{
+ 	  rtx sub = plus_constant (copy_rtx (XEXP (var, 0)),
+ 				   INTVAL (XEXP (x, 1)));
+ 
+ 	  start_sequence ();
+ 	  if (validate_change (insn, loc, sub, 0))
+ 	    {
+ 	      emit_insn_before (gen_sequence (), insn);
+ 	      end_sequence ();
+ 	      return;
+ 	    }
+ 	  end_sequence ();
+ 	}
+       break;
+ 
      case ADDRESSOF:
        if (XEXP (x, 0) == var)
  	{
Index: config/alpha/alpha.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/alpha/alpha.h,v
retrieving revision 1.19
diff -c -p -d -r1.19 alpha.h
*** alpha.h	1998/01/16 08:59:59	1.19
--- alpha.h	1998/01/21 00:41:45
*************** extern void alpha_init_expanders ();
*** 1365,1380 ****
  
     First define the basic valid address.  */
  
! #define GO_IF_LEGITIMATE_SIMPLE_ADDRESS(MODE, X, ADDR) \
! { if (REG_P (X) && REG_OK_FOR_BASE_P (X))	\
!     goto ADDR;					\
!   if (CONSTANT_ADDRESS_P (X))			\
!     goto ADDR;					\
!   if (GET_CODE (X) == PLUS			\
!       && REG_P (XEXP (X, 0))			\
!       && REG_OK_FOR_BASE_P (XEXP (X, 0))	\
!       && CONSTANT_ADDRESS_P (XEXP (X, 1)))	\
!     goto ADDR;					\
  }
  
  /* Now accept the simple address, or, for DImode only, an AND of a simple
--- 1365,1385 ----
  
     First define the basic valid address.  */
  
! #define GO_IF_LEGITIMATE_SIMPLE_ADDRESS(MODE, X, ADDR)	\
! { if (REG_P (X) && REG_OK_FOR_BASE_P (X))		\
!     goto ADDR;						\
!   /* Accept addressof since it will eventually become	\
!      a register or an offset of the FP.  */		\
!   if (GET_CODE (X) == ADDRESSOF)			\
!     goto ADDR;						\
!   if (CONSTANT_ADDRESS_P (X))				\
!     goto ADDR;						\
!   if (GET_CODE (X) == PLUS				\
!       && ((REG_P (XEXP (X, 0))				\
!            && REG_OK_FOR_BASE_P (XEXP (X, 0))		\
!            && CONSTANT_ADDRESS_P (XEXP (X, 1)))		\
! 	  || GET_CODE (XEXP (X, 0)) == ADDRESSOF))	\
!     goto ADDR;						\
  }
  
  /* Now accept the simple address, or, for DImode only, an AND of a simple



More information about the Gcc mailing list