]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/4520 (cselib.c hash_rtx incorrectly hashes based on rtx address)
authorRoger Sayle <roger@eyesopen.com>
Tue, 19 Sep 2006 21:25:28 +0000 (21:25 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Tue, 19 Sep 2006 21:25:28 +0000 (21:25 +0000)
PR middle-end/4520
Backport from mainline
* 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: r117062

gcc/ChangeLog
gcc/cselib.c

index b27df286f7a1d6fba5478e0b9bbb1ebd1614d3fc..4c1e0be4cb46136003c778fdeb2ee8f91d9dc145 100644 (file)
@@ -1,3 +1,10 @@
+2006-09-19  Roger Sayle  <roger@eyesopen.com>
+
+       PR middle-end/4520
+       Backport from mainline
+       * 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-18 Uros Bizjak <uros@kss-loka.si>
 
        PR target/28946
index f453489e12bf9c9b8de4276e82a83719c0eaf123..03ee85038581ad07a44ddab91a06c4db1379c4a1 100644 (file)
@@ -605,14 +605,28 @@ cselib_hash_rtx (rtx x, enum machine_mode mode, 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: