* lto-streamer-out.c (hash_scc): Avoid quadratic hashing loop.
authorJan Hubicka <hubicka@ucw.cz>
Wed, 9 Jul 2014 19:09:50 +0000 (21:09 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Wed, 9 Jul 2014 19:09:50 +0000 (19:09 +0000)
From-SVN: r212404

gcc/ChangeLog
gcc/lto-streamer-out.c

index d166c4860367ea6b191dbdaf1f933918e11bb032..96b437fbcf4f496cee29743e4cbf243fa3e94cf7 100644 (file)
@@ -1,3 +1,7 @@
+2014-07-08  Jan Hubicka  <hubicka@ucw.cz>
+
+       * lto-streamer-out.c (hash_scc): Avoid quadratic hashing loop.
+
 2014-07-08  Jan Hubicka  <hubicka@ucw.cz>
 
        Revert:
index 30645627d02036c274f6328d50dfc9b16b4037d8..bd289090bae046f5816c1db769febd2abc4260bf 100644 (file)
@@ -1131,32 +1131,18 @@ hash_scc (struct streamer_tree_cache_d *cache, unsigned first, unsigned size)
 
   /* Sort the SCC of type, hash pairs so that when we mix in
      all members of the SCC the hash value becomes independent on
-     the order we visited the SCC.  Disregard hashes equal to
-     the hash of the tree we mix into because we cannot guarantee
-     a stable sort for those across different TUs.  */
+     the order we visited the SCC.  Produce hash of the whole SCC as
+     combination of hashes of individual elements.  Then combine that hash into
+     hash of each element, so othewise identically looking elements from two
+     different SCCs are distinguished.  */
   qsort (&sccstack[first], size, sizeof (scc_entry), scc_entry_compare);
-  hashval_t *tem = XALLOCAVEC (hashval_t, size);
-  for (unsigned i = 0; i < size; ++i)
-    {
-      hashval_t hash = sccstack[first+i].hash;
-      hashval_t orig_hash = hash;
-      unsigned j;
-      /* Skip same hashes.  */
-      for (j = i + 1;
-          j < size && sccstack[first+j].hash == orig_hash; ++j)
-       ;
-      for (; j < size; ++j)
-       hash = iterative_hash_hashval_t (sccstack[first+j].hash, hash);
-      for (j = 0; sccstack[first+j].hash != orig_hash; ++j)
-       hash = iterative_hash_hashval_t (sccstack[first+j].hash, hash);
-      tem[i] = hash;
-    }
-  hashval_t scc_hash = 0;
+
+  hashval_t scc_hash = sccstack[first].hash;
+  for (unsigned i = 1; i < size; ++i)
+    scc_hash = iterative_hash_hashval_t (scc_hash,
+                                        sccstack[first+i].hash);
   for (unsigned i = 0; i < size; ++i)
-    {
-      sccstack[first+i].hash = tem[i];
-      scc_hash = iterative_hash_hashval_t (tem[i], scc_hash);
-    }
+    sccstack[first+i].hash = iterative_hash_hashval_t (sccstack[first+i].hash, scc_hash);
   return scc_hash;
 }