re PR middle-end/4520 (cselib.c hash_rtx incorrectly hashes based on rtx address)
authorRoger Sayle <roger@eyesopen.com>
Tue, 12 Sep 2006 16:02:31 +0000 (16:02 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Tue, 12 Sep 2006 16:02:31 +0000 (16:02 +0000)
PR middle-end/4520
PR bootstrap/28784
* cselib.c (cselib_hash_rtx): Avoid hashing on the address of labels
and symbols.  Instead use the implementation from cse.c's hash_rtx.

From-SVN: r116891

gcc/ChangeLog
gcc/cselib.c

index 5d66902..0a0d31b 100644 (file)
@@ -1,3 +1,10 @@
+2006-09-12  Roger Sayle  <roger@eyesopen.com>
+
+       PR middle-end/4520
+       PR bootstrap/28784
+       * cselib.c (cselib_hash_rtx): Avoid hashing on the address of labels
+       and symbols.  Instead use the implementation from cse.c's hash_rtx.
+
 2006-09-12  Jan Hubicka  <jh@suse.cz>
 
        PR rtl-optimization/28071
index edfc328..4070da7 100644 (file)
@@ -630,14 +630,28 @@ cselib_hash_rtx (rtx x, int create)
 
       /* Assume there is only one rtx object for any given label.  */
     case LABEL_REF:
-      hash
-       += ((unsigned) LABEL_REF << 7) + (unsigned long) XEXP (x, 0);
+      /* We don't hash on the address of the CODE_LABEL to avoid bootstrap
+        differences and differences between each stage's debugging dumps.  */
+      hash += (((unsigned int) LABEL_REF << 7)
+              + CODE_LABEL_NUMBER (XEXP (x, 0)));
       return hash ? hash : (unsigned int) LABEL_REF;
 
     case SYMBOL_REF:
-      hash
-       += ((unsigned) SYMBOL_REF << 7) + (unsigned long) XSTR (x, 0);
-      return hash ? hash : (unsigned int) SYMBOL_REF;
+      {
+       /* Don't hash on the symbol's address to avoid bootstrap differences.
+          Different hash values may cause expressions to be recorded in
+          different orders and thus different registers to be used in the
+          final assembler.  This also avoids differences in the dump files
+          between various stages.  */
+       unsigned int h = 0;
+       const unsigned char *p = (const unsigned char *) XSTR (x, 0);
+
+       while (*p)
+         h += (h << 7) + *p++; /* ??? revisit */
+
+       hash += ((unsigned int) SYMBOL_REF << 7) + h;
+       return hash ? hash : (unsigned int) SYMBOL_REF;
+      }
 
     case PRE_DEC:
     case PRE_INC: