still more genrecog tweeks

Richard Henderson rth@cygnus.com
Thu Oct 14 23:59:00 GMT 1999


This accumulated from processing the bulk of the md files.

* Be more permissive about modes wrt certain CALL idioms.
* Don't abort on m88k.md.
* Don't warn for (set (match_operand 0 "reg" "") (pc)).
* Don't loose track of the line number when someone does 
  something silly with continuation markers.


r~

        * genrecog.c (message_with_line): Prototype.
        (validate_pattern): Pass along the set for the dest, not a flag.
        Fix non-lvalue message.  Don't warn for VOIDmode SET_DEST of CALL.
        Check for PC/CC0 as sources.
        (nodes_identical): Check for children position match before
        allowing the combination.

        * rtl.c (read_rtx): Track line number across \\\n.

Index: genrecog.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/genrecog.c,v
retrieving revision 1.66
diff -c -p -d -r1.66 genrecog.c
*** genrecog.c	1999/10/15 01:52:29	1.66
--- genrecog.c	1999/10/15 06:51:13
*************** static const char * special_mode_pred_ta
*** 227,232 ****
--- 227,235 ----
  #define NUM_SPECIAL_MODE_PREDS \
    (sizeof (special_mode_pred_table) / sizeof (special_mode_pred_table[0]))
  
+ static void message_with_line
+   PVPROTO ((int, const char *, ...)) ATTRIBUTE_PRINTF_2;
+ 
  static struct decision *new_decision
    PROTO((const char *, struct decision_head *));
  static struct decision_test *new_decision_test
*************** static struct decision_test *new_decisio
*** 234,240 ****
  static rtx find_operand
    PROTO((rtx, int));
  static void validate_pattern
!   PROTO((rtx, rtx, int));
  static struct decision *add_to_sequence
    PROTO((rtx, struct decision_head *, const char *, enum routine_type, int));
  
--- 237,243 ----
  static rtx find_operand
    PROTO((rtx, int));
  static void validate_pattern
!   PROTO((rtx, rtx, rtx));
  static struct decision *add_to_sequence
    PROTO((rtx, struct decision_head *, const char *, enum routine_type, int));
  
*************** find_operand (pattern, n)
*** 418,430 ****
    return NULL;
  }
  
! /* Check for various errors in patterns.  */
  
  static void
! validate_pattern (pattern, insn, set_dest)
       rtx pattern;
       rtx insn;
!      int set_dest;
  {
    const char *fmt;
    RTX_CODE code;
--- 421,434 ----
    return NULL;
  }
  
! /* Check for various errors in patterns.  SET is nonnull for a destination,
!    and is the complete set pattern.  */
  
  static void
! validate_pattern (pattern, insn, set)
       rtx pattern;
       rtx insn;
!      rtx set;
  {
    const char *fmt;
    RTX_CODE code;
*************** validate_pattern (pattern, insn, set_des
*** 502,516 ****
  		}
  	  }
  
  	/* Allowing non-lvalues in destinations -- particularly CONST_INT --
  	   while not likely to occur at runtime, results in less efficient
  	   code from insn-recog.c.  */
! 	if (set_dest
  	    && pred_name[0] != '\0'
  	    && allows_non_lvalue)
  	  {
  	    message_with_line (pattern_lineno,
! 			"warning: destination operand 0 allows non-lvalue",
  			XINT (pattern, 0));
  	  }
  
--- 506,533 ----
  		}
  	  }
  
+ 	/* A MATCH_OPERAND that is a SET should have an output reload.  */
+ 	if (set
+ 	    && code == MATCH_OPERAND
+ 	    && XSTR (pattern, 2)[0] != '\0'
+ 	    && XSTR (pattern, 2)[0] != '='
+ 	    && XSTR (pattern, 2)[0] != '+')
+ 	  {
+ 	    message_with_line (pattern_lineno,
+ 			       "operand %d missing output reload", 
+ 			       XINT (pattern, 0));
+ 	    error_count++;
+ 	  }
+ 
  	/* Allowing non-lvalues in destinations -- particularly CONST_INT --
  	   while not likely to occur at runtime, results in less efficient
  	   code from insn-recog.c.  */
! 	if (set
  	    && pred_name[0] != '\0'
  	    && allows_non_lvalue)
  	  {
  	    message_with_line (pattern_lineno,
! 			"warning: destination operand %d allows non-lvalue",
  			XINT (pattern, 0));
  	  }
  
*************** validate_pattern (pattern, insn, set_des
*** 519,525 ****
  	   it is a mistake.  Only DEFINE_INSN is eligible, since SPLIT
  	   and PEEP2 can FAIL within the output pattern.  Exclude 
  	   address_operand, since its mode is related to the mode of
! 	   the memory not the operand.  */
  
  	if (GET_MODE (pattern) == VOIDmode
  	    && code == MATCH_OPERAND
--- 536,543 ----
  	   it is a mistake.  Only DEFINE_INSN is eligible, since SPLIT
  	   and PEEP2 can FAIL within the output pattern.  Exclude 
  	   address_operand, since its mode is related to the mode of
! 	   the memory not the operand.  Exclude the SET_DEST of a call
! 	   instruction, as that is a common idiom.  */
  
  	if (GET_MODE (pattern) == VOIDmode
  	    && code == MATCH_OPERAND
*************** validate_pattern (pattern, insn, set_des
*** 528,553 ****
  	    && ! special_mode_pred
  	    && pred_name[0] != '\0'
  	    && strcmp (pred_name, "address_operand") != 0
! 	    && strstr (c_test, "operands") == NULL)
  	  {
  	    message_with_line (pattern_lineno,
  			       "warning: operand %d missing mode?",
  			       XINT (pattern, 0));
  	  }
- 
- 	/* A MATCH_OPERAND that is a SET should have an output reload.  */
- 	if (set_dest
- 	    && code == MATCH_OPERAND
- 	    && XSTR (pattern, 2)[0] != '\0'
- 	    && XSTR (pattern, 2)[0] != '='
- 	    && XSTR (pattern, 2)[0] != '+')
- 	  {
- 	    message_with_line (pattern_lineno,
- 			       "operand %d missing output reload", 
- 			       XINT (pattern, 0));
- 	    error_count++;
- 	  }
- 
  	return;
        }
  
--- 546,560 ----
  	    && ! special_mode_pred
  	    && pred_name[0] != '\0'
  	    && strcmp (pred_name, "address_operand") != 0
! 	    && strstr (c_test, "operands") == NULL
! 	    && ! (set
! 		  && GET_CODE (set) == SET
! 		  && GET_CODE (SET_SRC (set)) == CALL))
  	  {
  	    message_with_line (pattern_lineno,
  			       "warning: operand %d missing mode?",
  			       XINT (pattern, 0));
  	  }
  	return;
        }
  
*************** validate_pattern (pattern, insn, set_des
*** 600,605 ****
--- 607,614 ----
  	else if (dmode != smode
  		 && GET_CODE (dest) != PC
  		 && GET_CODE (dest) != CC0
+ 		 && GET_CODE (src) != PC
+ 		 && GET_CODE (src) != CC0
  		 && GET_CODE (src) != CONST_INT)
  	  {
  	    const char *which;
*************** validate_pattern (pattern, insn, set_des
*** 609,622 ****
  	  }
  
  	if (dest != SET_DEST (pattern))
! 	  validate_pattern (dest, insn, 1);
! 	validate_pattern (SET_DEST (pattern), insn, 1);
!         validate_pattern (SET_SRC (pattern), insn, 0);
          return;
        }
  
      case CLOBBER:
!       validate_pattern (SET_DEST (pattern), insn, 1);
        return;
  
      case LABEL_REF:
--- 618,631 ----
  	  }
  
  	if (dest != SET_DEST (pattern))
! 	  validate_pattern (dest, insn, pattern);
! 	validate_pattern (SET_DEST (pattern), insn, pattern);
!         validate_pattern (SET_SRC (pattern), insn, NULL_RTX);
          return;
        }
  
      case CLOBBER:
!       validate_pattern (SET_DEST (pattern), insn, pattern);
        return;
  
      case LABEL_REF:
*************** validate_pattern (pattern, insn, set_des
*** 640,651 ****
        switch (fmt[i])
  	{
  	case 'e': case 'u':
! 	  validate_pattern (XEXP (pattern, i), insn, 0);
  	  break;
  
  	case 'E':
  	  for (j = 0; j < XVECLEN (pattern, i); j++)
! 	    validate_pattern (XVECEXP (pattern, i, j), insn, 0);
  	  break;
  
  	case 'i': case 'w': case '0': case 's':
--- 649,660 ----
        switch (fmt[i])
  	{
  	case 'e': case 'u':
! 	  validate_pattern (XEXP (pattern, i), insn, NULL_RTX);
  	  break;
  
  	case 'E':
  	  for (j = 0; j < XVECLEN (pattern, i); j++)
! 	    validate_pattern (XVECEXP (pattern, i, j), insn, NULL_RTX);
  	  break;
  
  	case 'i': case 'w': case '0': case 's':
*************** nodes_identical (d1, d2)
*** 1219,1225 ****
      }
  
    /* For success, they should now both be null.  */
!   return t1 == t2;
  }
  
  /* A subroutine of merge_trees; given two nodes that have been declared
--- 1228,1244 ----
      }
  
    /* For success, they should now both be null.  */
!   if (t1 != t2)
!     return 0;
! 
!   /* Check that their subnodes are at the same position, as any one set
!      of sibling decisions must be at the same position.  */
!   if (d1->success.first
!       && d2->success.first
!       && strcmp (d1->success.first->position, d2->success.first->position))
!     return 0;
! 
!   return 1;
  }
  
  /* A subroutine of merge_trees; given two nodes that have been declared
*************** make_insn_sequence (insn, type)
*** 2313,2319 ****
        PUT_MODE (x, VOIDmode);
      }
  
!   validate_pattern (x, insn, 0);
  
    memset(&head, 0, sizeof(head));
    last = add_to_sequence (x, &head, "", type, 1);
--- 2332,2338 ----
        PUT_MODE (x, VOIDmode);
      }
  
!   validate_pattern (x, insn, NULL_RTX);
  
    memset(&head, 0, sizeof(head));
    last = add_to_sequence (x, &head, "", type, 1);
Index: rtl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.c,v
retrieving revision 1.49
diff -c -p -d -r1.49 rtl.c
*** rtl.c	1999/10/14 03:43:48	1.49
--- rtl.c	1999/10/15 06:51:13
*************** read_rtx (infile)
*** 954,959 ****
--- 954,961 ----
  		      obstack_grow (rtl_obstack, "\\n\\t", 4);
  		      continue;
  		    }
+ 		  if (c == '\n')
+ 		    read_rtx_lineno++;
  		}
  	      else if (c == '"')
  		break;


More information about the Gcc-patches mailing list