Switch lowering: use uint32_t for weights everywhere
authorHans Wennborg <hans@hanshq.net>
Mon, 27 Apr 2015 23:52:19 +0000 (23:52 +0000)
committerHans Wennborg <hans@hanshq.net>
Mon, 27 Apr 2015 23:52:19 +0000 (23:52 +0000)
I previously thought switch clusters would need to use uint64_t in case
the weights of multiple cases overflowed a 32-bit int. It turns
out that the weights on a terminator instruction are capped to allow for
being added together, so using a uint32_t should be safe.

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

lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h

index 985a4dfd49d76adc0412b6df6ebf07538e4ebfcf..71b221a02a17bcc87f2663fac8e57c18d8165ae2 100644 (file)
@@ -2126,6 +2126,7 @@ void SelectionDAGBuilder::sortAndRangeify(CaseClusterVector &Clusters) {
       // the previous cluster.
       Clusters[DstIndex - 1].High = CaseVal;
       Clusters[DstIndex - 1].Weight += CC.Weight;
+      assert(Clusters[DstIndex - 1].Weight >= CC.Weight && "Weight overflow!");
     } else {
       std::memmove(&Clusters[DstIndex++], &Clusters[SrcIndex],
                    sizeof(Clusters[SrcIndex]));
@@ -7230,13 +7231,14 @@ bool SelectionDAGBuilder::buildJumpTable(CaseClusterVector &Clusters,
                                          CaseCluster &JTCluster) {
   assert(First <= Last);
 
-  uint64_t Weight = 0;
+  uint32_t Weight = 0;
   unsigned NumCmps = 0;
   std::vector<MachineBasicBlock*> Table;
   DenseMap<MachineBasicBlock*, uint32_t> JTWeights;
   for (unsigned I = First; I <= Last; ++I) {
     assert(Clusters[I].Kind == CC_Range);
     Weight += Clusters[I].Weight;
+    assert(Weight >= Clusters[I].Weight && "Weight overflow!");
     APInt Low = Clusters[I].Low->getValue();
     APInt High = Clusters[I].High->getValue();
     NumCmps += (Low == High) ? 1 : 2;
@@ -7463,7 +7465,7 @@ bool SelectionDAGBuilder::buildBitTests(CaseClusterVector &Clusters,
   }
 
   CaseBitsVector CBV;
-  uint64_t TotalWeight = 0;
+  uint32_t TotalWeight = 0;
   for (unsigned i = First; i <= Last; ++i) {
     // Find the CaseBits for this destination.
     unsigned j;
@@ -7482,8 +7484,8 @@ bool SelectionDAGBuilder::buildBitTests(CaseClusterVector &Clusters,
       CB->Bits++;
     }
     CB->ExtraWeight += Clusters[i].Weight;
-    assert(CB->ExtraWeight >= Clusters[i].Weight && "Weight sum overflowed!");
     TotalWeight += Clusters[i].Weight;
+    assert(TotalWeight >= Clusters[i].Weight && "Weight overflow!");
   }
 
   BitTestInfo BTI;
@@ -7693,8 +7695,10 @@ void SelectionDAGBuilder::lowerWorkItem(SwitchWorkListItem W, Value *Cond,
 
   // Compute total weight.
   uint32_t UnhandledWeights = 0;
-  for (CaseClusterIt I = W.FirstCluster; I <= W.LastCluster; ++I)
+  for (CaseClusterIt I = W.FirstCluster; I <= W.LastCluster; ++I) {
     UnhandledWeights += I->Weight;
+    assert(UnhandledWeights >= I->Weight && "Weight overflow!");
+  }
 
   MachineBasicBlock *CurMBB = W.MBB;
   for (CaseClusterIt I = W.FirstCluster, E = W.LastCluster; I <= E; ++I) {
@@ -7859,8 +7863,10 @@ void SelectionDAGBuilder::visitSwitch(const SwitchInst &SI) {
     MachineBasicBlock *Succ = FuncInfo.MBBMap[I.getCaseSuccessor()];
     const ConstantInt *CaseVal = I.getCaseValue();
     uint32_t Weight = 0; // FIXME: Use 1 instead?
-    if (BPI)
+    if (BPI) {
       Weight = BPI->getEdgeWeight(SI.getParent(), I.getSuccessorIndex());
+      assert(Weight <= UINT32_MAX / SI.getNumSuccessors());
+    }
     Clusters.push_back(CaseCluster::range(CaseVal, CaseVal, Succ, Weight));
   }
 
index 7c2cef61a3150f5df805414bbad7c4ab1a3bec95..ba6d9743d74ac0529f2fc9f2f314ad709fd0b42c 100644 (file)
@@ -153,7 +153,7 @@ private:
       unsigned JTCasesIndex;
       unsigned BTCasesIndex;
     };
-    uint64_t Weight;
+    uint32_t Weight;
 
     static CaseCluster range(const ConstantInt *Low, const ConstantInt *High,
                              MachineBasicBlock *MBB, uint32_t Weight) {