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]

Recog and unary operations matched in operands


Hi
The unary operators matches in operations are currently "allowed" and they
are very usefull for i387 patterns to hide the no-op float_expand operations.
Problem is that most parts of compiler don't expect such thinks to happen.
I've already fixed it for recog (accepted) and reload (doomed).

Yesterday I realized that regclass surfers to similar problem and there
are most probably other passes too. In order to avoid such hidden dragons
in gcc I propose to add real_operand and real_operand_loc to recog.h as
done by this patch, that will point to the operands stripped by unary
operations.

Then I can easilly make pass trought compiler and replace the recog_data.operand
by real_operand in case the second is correct and avoid these problems.
(as I did as a test in recog.c)
Then my grand predicates changes to i387 patterns may get reality and INDREG
patch simple...

Is that approach OK?

BTW many passes do their own job to ignore optional SUBREGs matched in operands.
Possibly we can make another variables pointing to the operands after stripping.
If this is good idea, can you propose the name?

Honza

Tue Nov 23 16:35:01 MET 1999  Jan Hubicka  <hubicka@freesoft.cz>

	* recg.c (extract_insn): Caluclate the real_operand and
	real_operand_loc values.
	(constrain_operands): Use real_operand instead of operand.
	Do not ignore the unarry operands manually.
	* recog.h (operand_data): New fields real_operand
	and real_operand_loc.

Index: egcs/gcc/recog.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/recog.c,v
retrieving revision 1.51
diff -c -3 -p -r1.51 recog.c
*** recog.c	1999/11/01 01:11:21	1.51
--- recog.c	1999/11/23 15:27:21
*************** extract_insn (insn)
*** 2055,2064 ****
  	}
      }
    for (i = 0; i < noperands; i++)
!     recog_data.operand_type[i]
!       = (recog_data.constraints[i][0] == '=' ? OP_OUT
! 	 : recog_data.constraints[i][0] == '+' ? OP_INOUT
! 	 : OP_IN);
  
    if (recog_data.n_alternatives > MAX_RECOG_ALTERNATIVES)
      abort ();
--- 2055,2073 ----
  	}
      }
    for (i = 0; i < noperands; i++)
!     {
!       recog_data.operand_type[i]
! 	= (recog_data.constraints[i][0] == '=' ? OP_OUT
! 	   : recog_data.constraints[i][0] == '+' ? OP_INOUT
! 	   : OP_IN);
! 
!       recog_data.real_operand_loc[i] = recog_data.operand_loc[i];
!       while (GET_RTX_CLASS (GET_CODE (*recog_data.real_operand_loc[i])) == '1')
! 	recog_data.real_operand_loc[i]
! 	  = &XEXP (*recog_data.real_operand_loc[i], 0);
! 
!       recog_data.real_operand[i] = *recog_data.real_operand_loc[i];
!     }
  
    if (recog_data.n_alternatives > MAX_RECOG_ALTERNATIVES)
      abort ();
*************** constrain_operands (strict)
*** 2232,2238 ****
  
        for (opno = 0; opno < recog_data.n_operands; opno++)
  	{
! 	  register rtx op = recog_data.operand[opno];
  	  enum machine_mode mode = GET_MODE (op);
  	  register const char *p = constraints[opno];
  	  int offset = 0;
--- 2241,2247 ----
  
        for (opno = 0; opno < recog_data.n_operands; opno++)
  	{
! 	  register rtx op = recog_data.real_operand[opno];
  	  enum machine_mode mode = GET_MODE (op);
  	  register const char *p = constraints[opno];
  	  int offset = 0;
*************** constrain_operands (strict)
*** 2241,2251 ****
  
  	  earlyclobber[opno] = 0;
  
- 	  /* A unary operator may be accepted by the predicate, but it
- 	     is irrelevant for matching constraints.  */
- 	  if (GET_RTX_CLASS (GET_CODE (op)) == '1')
- 	    op = XEXP (op, 0);
- 
  	  if (GET_CODE (op) == SUBREG)
  	    {
  	      if (GET_CODE (SUBREG_REG (op)) == REG
--- 2250,2255 ----
*************** constrain_operands (strict)
*** 2292,2306 ****
  		  val = 1;
  		else
  		  {
! 		    rtx op1 = recog_data.operand[c - '0'];
! 		    rtx op2 = recog_data.operand[opno];
! 
! 	            /* A unary operator may be accepted by the predicate,
! 		       but it is irrelevant for matching constraints.  */
! 	            if (GET_RTX_CLASS (GET_CODE (op1)) == '1')
! 	              op1 = XEXP (op1, 0);
! 	            if (GET_RTX_CLASS (GET_CODE (op2)) == '1')
! 	              op2 = XEXP (op2, 0);
  
  		    val = operands_match_p (op1, op2);
  		  }
--- 2296,2303 ----
  		  val = 1;
  		else
  		  {
! 		    rtx op1 = recog_data.real_operand[c - '0'];
! 		    rtx op2 = recog_data.real_operand[opno];
  
  		    val = operands_match_p (op1, op2);
  		  }
*************** constrain_operands (strict)
*** 2512,2537 ****
  		 because we would often report failure when we have
  		 two memory operands, one of which was formerly a REG.  */
  	      if (earlyclobber[eopno]
! 		  && GET_CODE (recog_data.operand[eopno]) == REG)
  		for (opno = 0; opno < recog_data.n_operands; opno++)
! 		  if ((GET_CODE (recog_data.operand[opno]) == MEM
  		       || recog_data.operand_type[opno] != OP_OUT)
  		      && opno != eopno
  		      /* Ignore things like match_operator operands.  */
  		      && *recog_data.constraints[opno] != 0
  		      && ! (matching_operands[opno] == eopno
! 			    && operands_match_p (recog_data.operand[opno],
! 						 recog_data.operand[eopno]))
! 		      && ! safe_from_earlyclobber (recog_data.operand[opno],
! 						   recog_data.operand[eopno]))
  		    lose = 1;
  
  	  if (! lose)
  	    {
  	      while (--funny_match_index >= 0)
  		{
! 		  recog_data.operand[funny_match[funny_match_index].other]
! 		    = recog_data.operand[funny_match[funny_match_index].this];
  		}
  
  	      return 1;
--- 2509,2534 ----
  		 because we would often report failure when we have
  		 two memory operands, one of which was formerly a REG.  */
  	      if (earlyclobber[eopno]
! 		  && GET_CODE (recog_data.real_operand[eopno]) == REG)
  		for (opno = 0; opno < recog_data.n_operands; opno++)
! 		  if ((GET_CODE (recog_data.real_operand[opno]) == MEM
  		       || recog_data.operand_type[opno] != OP_OUT)
  		      && opno != eopno
  		      /* Ignore things like match_operator operands.  */
  		      && *recog_data.constraints[opno] != 0
  		      && ! (matching_operands[opno] == eopno
! 			    && operands_match_p (recog_data.real_operand[opno],
! 						 recog_data.real_operand[eopno]))
! 		      && ! safe_from_earlyclobber (recog_data.real_operand[opno],
! 						   recog_data.real_operand[eopno]))
  		    lose = 1;
  
  	  if (! lose)
  	    {
  	      while (--funny_match_index >= 0)
  		{
! 		  recog_data.real_operand[funny_match[funny_match_index].other]
! 		    = recog_data.real_operand[funny_match[funny_match_index].this];
  		}
  
  	      return 1;
Index: egcs/gcc/recog.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/recog.h,v
retrieving revision 1.26
diff -c -3 -p -r1.26 recog.h
*** recog.h	1999/10/22 22:02:17	1.26
--- recog.h	1999/11/23 15:27:21
*************** struct recog_data
*** 139,146 ****
--- 139,153 ----
    /* Gives value of operand N.  */
    rtx operand[MAX_RECOG_OPERANDS];
  
+   /* Gives value of operand N after stripping down the unary operators
+      matched by predicates.  */
+   rtx real_operand[MAX_RECOG_OPERANDS];
+ 
    /* Gives location where operand N was found.  */
    rtx *operand_loc[MAX_RECOG_OPERANDS];
+ 
+   /* Gives location where real_operand N was found.  */
+   rtx *real_operand_loc[MAX_RECOG_OPERANDS];
  
    /* Gives the constraint string for operand N.  */
    const char *constraints[MAX_RECOG_OPERANDS];


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