The hash function for MI expressions, used by MachineCSE, is really
authorChandler Carruth <chandlerc@gmail.com>
Thu, 5 Jul 2012 10:03:57 +0000 (10:03 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Thu, 5 Jul 2012 10:03:57 +0000 (10:03 +0000)
broken. This patch fixes the superficial problems which lead to the
intractably slow compile times reported in PR13225.

The specific issue is that we were failing to include the *offset* of
a global variable in the hash code. Oops. This would in turn cause all
MIs which were only distinguishable due to operating on different
offsets of a global variable to produce identical hash functions. In
some of the test cases attached to the PR I saw hash table activity
where there were O(1000) probes-per-lookup *on average*. A very few
entries were responsible for most of these probes.

There is still quite a bit more to do here. The ad-hoc layering of data
in MachineOperands makes them *extremely* brittle to hash correctly.
We're missing quite a few other cases, the only ones I've fixed here are
the specific MO types which were allowed through the assert() in
getOffset().

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159741 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/MachineInstr.cpp

index 85b5e3986467c6b17d2352ab28fa749369b63572..0ee0213d9a47b00124a064478f787876a30e9200 100644 (file)
@@ -1882,19 +1882,24 @@ MachineInstrExpressionTrait::getHashValue(const MachineInstr* const &MI) {
       HashComponents.push_back(hash_combine(MO.getType(), MO.getImm()));
       break;
     case MachineOperand::MO_FrameIndex:
-    case MachineOperand::MO_ConstantPoolIndex:
     case MachineOperand::MO_JumpTableIndex:
       HashComponents.push_back(hash_combine(MO.getType(), MO.getIndex()));
       break;
+    case MachineOperand::MO_ConstantPoolIndex:
+      HashComponents.push_back(hash_combine(MO.getType(), MO.getIndex(),
+                                            MO.getOffset()));
+      break;
     case MachineOperand::MO_MachineBasicBlock:
       HashComponents.push_back(hash_combine(MO.getType(), MO.getMBB()));
       break;
     case MachineOperand::MO_GlobalAddress:
-      HashComponents.push_back(hash_combine(MO.getType(), MO.getGlobal()));
+      HashComponents.push_back(hash_combine(MO.getType(), MO.getGlobal(),
+                                            MO.getOffset()));
       break;
     case MachineOperand::MO_BlockAddress:
       HashComponents.push_back(hash_combine(MO.getType(),
-                                            MO.getBlockAddress()));
+                                            MO.getBlockAddress(),
+                                            MO.getOffset()));
       break;
     case MachineOperand::MO_MCSymbol:
       HashComponents.push_back(hash_combine(MO.getType(), MO.getMCSymbol()));