switch uncleanliness

Richard Henderson rth@redhat.com
Fri Jan 26 15:42:00 GMT 2001


Bear with me here a moment.

I was trying to build a cross-compiler from Alpha to a target for which
either the compiler or the assembler is not 64-bit clean.  Rather than
attacking the problem head on and fixing things proper, I thought I'd be
clever, save time, and hack config.h to use a 32-bit HOST_WIDE_INT.

It nearly worked.  I did run into the following:

We index cost_table with -1 to 127.  Except that TREE_INT_CST_LOW
is unsigned, so that -1 comes out 0xffffffff.  Which accidentally
works if HOST_WIDE_INT is the same size as a pointer, since you
get overflow.  If not, instant SEGV.

Fixed by rearranging such that the unsigned arithmetic overflows
before it gets widened to the pointer size.


r~


        * stmt.c (cost_table): Remove.
        (COST_TABLE, cost_table_initialized): New.
        (estimate_case_costs): Use the later instead of the former.
        (balance_case_nodes): Likewise.

Index: stmt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/stmt.c,v
retrieving revision 1.182
diff -c -p -d -r1.182 stmt.c
*** stmt.c	2001/01/20 17:47:45	1.182
--- stmt.c	2001/01/26 23:20:59
*************** typedef struct case_node *case_node_ptr;
*** 106,113 ****
  
  /* This must be a signed type, and non-ANSI compilers lack signed char.  */
  static short cost_table_[129];
- static short *cost_table;
  static int use_cost_table;
  
  /* Stack of control and binding constructs we are currently inside.
  
--- 106,117 ----
  
  /* This must be a signed type, and non-ANSI compilers lack signed char.  */
  static short cost_table_[129];
  static int use_cost_table;
+ static int cost_table_initialized;
+ 
+ /* Special care is needed because we allow -1, but TREE_INT_CST_LOW
+    is unsigned.  */
+ #define COST_TABLE(I)  cost_table_[(unsigned HOST_WIDE_INT)((I) + 1)]
  
  /* Stack of control and binding constructs we are currently inside.
  
*************** estimate_case_costs (node)
*** 5768,5794 ****
    /* If we haven't already made the cost table, make it now.  Note that the
       lower bound of the table is -1, not zero.  */
  
!   if (cost_table == NULL)
      {
!       cost_table = cost_table_ + 1;
  
        for (i = 0; i < 128; i++)
  	{
  	  if (ISALNUM (i))
! 	    cost_table[i] = 16;
  	  else if (ISPUNCT (i))
! 	    cost_table[i] = 8;
  	  else if (ISCNTRL (i))
! 	    cost_table[i] = -1;
  	}
  
!       cost_table[' '] = 8;
!       cost_table['\t'] = 4;
!       cost_table['\0'] = 4;
!       cost_table['\n'] = 2;
!       cost_table['\f'] = 1;
!       cost_table['\v'] = 1;
!       cost_table['\b'] = 1;
      }
  
    /* See if all the case expressions look like text.  It is text if the
--- 5772,5798 ----
    /* If we haven't already made the cost table, make it now.  Note that the
       lower bound of the table is -1, not zero.  */
  
!   if (! cost_table_initialized)
      {
!       cost_table_initialized = 1;
  
        for (i = 0; i < 128; i++)
  	{
  	  if (ISALNUM (i))
! 	    COST_TABLE (i) = 16;
  	  else if (ISPUNCT (i))
! 	    COST_TABLE (i) = 8;
  	  else if (ISCNTRL (i))
! 	    COST_TABLE (i) = -1;
  	}
  
!       COST_TABLE (' ') = 8;
!       COST_TABLE ('\t') = 4;
!       COST_TABLE ('\0') = 4;
!       COST_TABLE ('\n') = 2;
!       COST_TABLE ('\f') = 1;
!       COST_TABLE ('\v') = 1;
!       COST_TABLE ('\b') = 1;
      }
  
    /* See if all the case expressions look like text.  It is text if the
*************** estimate_case_costs (node)
*** 5804,5810 ****
  
        for (i = (HOST_WIDE_INT) TREE_INT_CST_LOW (n->low);
  	   i <= (HOST_WIDE_INT) TREE_INT_CST_LOW (n->high); i++)
! 	if (cost_table[i] < 0)
  	  return 0;
      }
  
--- 5808,5814 ----
  
        for (i = (HOST_WIDE_INT) TREE_INT_CST_LOW (n->low);
  	   i <= (HOST_WIDE_INT) TREE_INT_CST_LOW (n->high); i++)
! 	if (COST_TABLE (i) < 0)
  	  return 0;
      }
  
*************** balance_case_nodes (head, parent)
*** 5895,5905 ****
  	    {
  	      ranges++;
  	      if (use_cost_table)
! 		cost += cost_table[TREE_INT_CST_LOW (np->high)];
  	    }
  
  	  if (use_cost_table)
! 	    cost += cost_table[TREE_INT_CST_LOW (np->low)];
  
  	  i++;
  	  np = np->right;
--- 5899,5909 ----
  	    {
  	      ranges++;
  	      if (use_cost_table)
! 		cost += COST_TABLE (TREE_INT_CST_LOW (np->high));
  	    }
  
  	  if (use_cost_table)
! 	    cost += COST_TABLE (TREE_INT_CST_LOW (np->low));
  
  	  i++;
  	  np = np->right;
*************** balance_case_nodes (head, parent)
*** 5920,5927 ****
  		{
  		  /* Skip nodes while their cost does not reach that amount.  */
  		  if (!tree_int_cst_equal ((*npp)->low, (*npp)->high))
! 		    i -= cost_table[TREE_INT_CST_LOW ((*npp)->high)];
! 		  i -= cost_table[TREE_INT_CST_LOW ((*npp)->low)];
  		  if (i <= 0)
  		    break;
  		  npp = &(*npp)->right;
--- 5924,5931 ----
  		{
  		  /* Skip nodes while their cost does not reach that amount.  */
  		  if (!tree_int_cst_equal ((*npp)->low, (*npp)->high))
! 		    i -= COST_TABLE (TREE_INT_CST_LOW ((*npp)->high));
! 		  i -= COST_TABLE (TREE_INT_CST_LOW ((*npp)->low));
  		  if (i <= 0)
  		    break;
  		  npp = &(*npp)->right;
*************** emit_case_nodes (index, node, default_la
*** 6253,6259 ****
  	     a branch-greater-than will get us to the default
  	     label correctly.  */
  	  if (use_cost_table
! 	      && cost_table[TREE_INT_CST_LOW (node->high)] < 12)
  	    ;
  #endif /* 0 */
  	  if (node->left->left || node->left->right
--- 6257,6263 ----
  	     a branch-greater-than will get us to the default
  	     label correctly.  */
  	  if (use_cost_table
! 	      && COST_TABLE (TREE_INT_CST_LOW (node->high)) < 12)
  	    ;
  #endif /* 0 */
  	  if (node->left->left || node->left->right


More information about the Gcc-patches mailing list