Optimized usage of new SwitchInst case values (IntegersSubset type) in Local.cpp...
authorStepan Dyatkovskiy <stpworld@narod.ru>
Sat, 23 Jun 2012 10:58:58 +0000 (10:58 +0000)
committerStepan Dyatkovskiy <stpworld@narod.ru>
Sat, 23 Jun 2012 10:58:58 +0000 (10:58 +0000)
I got about 1% of compile-time improvement on my machines (Ubuntu 11.10 i386 and Ubuntu 12.04 x64).

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

include/llvm/Instructions.h
lib/Bitcode/Writer/BitcodeWriter.cpp
lib/ExecutionEngine/Interpreter/Execution.cpp
lib/Transforms/Utils/Local.cpp

index f94d8448d361c2e43b7484f72b6e91e47f7ede1e..a79e272946c7d1126ce345c501d6551122e98c35 100644 (file)
@@ -2705,8 +2705,7 @@ public:
     }
 
     /// Resolves case value for current case.
-//    IntegersSubsetRef getCaseValueEx() {
-    IntegersSubset getCaseValueEx() {
+    IntegersSubsetRef getCaseValueEx() {
       assert(Index < SI->getNumCases() && "Index out the number of cases.");
       return *SubsetIt;
     }
index 6526b012d811a9c0029d151854a2872498a94326..333d82ad4a8d4de24a42d40db513209a5786bf3b 100644 (file)
@@ -1157,19 +1157,38 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
       Vals64.push_back(SI.getNumCases());
       for (SwitchInst::CaseIt i = SI.case_begin(), e = SI.case_end();
            i != e; ++i) {
-        IntegersSubset CaseRanges = i.getCaseValueEx();
-        Vals64.push_back(CaseRanges.getNumItems());
-        for (unsigned ri = 0, rn = CaseRanges.getNumItems(); ri != rn; ++ri) {
-          IntegersSubset::Range r = CaseRanges.getItem(ri);
-          bool IsSingleNumber = r.isSingleNumber();
-
-          Vals64.push_back(IsSingleNumber);
-
-          unsigned Code, Abbrev; // will unused.
+        IntegersSubset& CaseRanges = i.getCaseValueEx();
+        unsigned Code, Abbrev; // will unused.
+        
+        if (CaseRanges.isSingleNumber()) {
+          Vals64.push_back(1/*NumItems = 1*/);
+          Vals64.push_back(true/*IsSingleNumber = true*/);
+          EmitAPInt(Vals64, Code, Abbrev, CaseRanges.getSingleNumber(0), true);
+        } else {
+          
+          Vals64.push_back(CaseRanges.getNumItems());
           
-          EmitAPInt(Vals64, Code, Abbrev, r.getLow(), true);
-          if (!IsSingleNumber)
-            EmitAPInt(Vals64, Code, Abbrev, r.getHigh(), true);
+          if (CaseRanges.isSingleNumbersOnly()) {
+            for (unsigned ri = 0, rn = CaseRanges.getNumItems();
+                 ri != rn; ++ri) {
+              
+              Vals64.push_back(true/*IsSingleNumber = true*/);
+              
+              EmitAPInt(Vals64, Code, Abbrev,
+                        CaseRanges.getSingleNumber(ri), true);
+            }
+          } else
+            for (unsigned ri = 0, rn = CaseRanges.getNumItems();
+                 ri != rn; ++ri) {
+              IntegersSubset::Range r = CaseRanges.getItem(ri);
+              bool IsSingleNumber = CaseRanges.isSingleNumber(ri);
+    
+              Vals64.push_back(IsSingleNumber);
+              
+              EmitAPInt(Vals64, Code, Abbrev, r.getLow(), true);
+              if (!IsSingleNumber)
+                EmitAPInt(Vals64, Code, Abbrev, r.getHigh(), true);
+            }
         }
         Vals64.push_back(VE.getValueID(i.getCaseSuccessor()));
       }
index 89c35438ef74dc39e0f1164c431743072cabd2ac..5202b091654e4909133cc6f27ef98fcac0a1a762 100644 (file)
@@ -651,20 +651,40 @@ void Interpreter::visitSwitchInst(SwitchInst &I) {
   // Check to see if any of the cases match...
   BasicBlock *Dest = 0;
   for (SwitchInst::CaseIt i = I.case_begin(), e = I.case_end(); i != e; ++i) {
-    IntegersSubset Case = i.getCaseValueEx();
-    for (unsigned n = 0, en = Case.getNumItems(); n != en; ++n) {
-      IntegersSubset::Range r = Case.getItem(n);
+    IntegersSubset& Case = i.getCaseValueEx();
+    if (Case.isSingleNumber()) {
       // FIXME: Currently work with ConstantInt based numbers.
-      const ConstantInt *LowCI = r.getLow().toConstantInt();
-      const ConstantInt *HighCI = r.getHigh().toConstantInt();
-      GenericValue Low = getOperandValue(const_cast<ConstantInt*>(LowCI), SF);
-      GenericValue High = getOperandValue(const_cast<ConstantInt*>(HighCI), SF);
-      if (executeICMP_ULE(Low, CondVal, ElTy).IntVal != 0 &&
-          executeICMP_ULE(CondVal, High, ElTy).IntVal != 0) {
+      const ConstantInt *CI = Case.getSingleNumber(0).toConstantInt();
+      GenericValue Val = getOperandValue(const_cast<ConstantInt*>(CI), SF);
+      if (executeICMP_EQ(Val, CondVal, ElTy).IntVal != 0) {
         Dest = cast<BasicBlock>(i.getCaseSuccessor());
         break;        
       }
     }
+    if (Case.isSingleNumbersOnly()) {
+      for (unsigned n = 0, en = Case.getNumItems(); n != en; ++n) {
+        // FIXME: Currently work with ConstantInt based numbers.
+        const ConstantInt *CI = Case.getSingleNumber(n).toConstantInt();
+        GenericValue Val = getOperandValue(const_cast<ConstantInt*>(CI), SF);
+        if (executeICMP_EQ(Val, CondVal, ElTy).IntVal != 0) {
+          Dest = cast<BasicBlock>(i.getCaseSuccessor());
+          break;        
+        }
+      }      
+    } else
+      for (unsigned n = 0, en = Case.getNumItems(); n != en; ++n) {
+        IntegersSubset::Range r = Case.getItem(n);
+        // FIXME: Currently work with ConstantInt based numbers.
+        const ConstantInt *LowCI = r.getLow().toConstantInt();
+        const ConstantInt *HighCI = r.getHigh().toConstantInt();
+        GenericValue Low = getOperandValue(const_cast<ConstantInt*>(LowCI), SF);
+        GenericValue High = getOperandValue(const_cast<ConstantInt*>(HighCI), SF);
+        if (executeICMP_ULE(Low, CondVal, ElTy).IntVal != 0 &&
+            executeICMP_ULE(CondVal, High, ElTy).IntVal != 0) {
+          Dest = cast<BasicBlock>(i.getCaseSuccessor());
+          break;        
+        }
+      }
   }
   if (!Dest) Dest = I.getDefaultDest();   // No cases matched: use default
   SwitchToNewBasicBlock(Dest, SF);
index 8e5927470d54b5d4f04d95e08f27e6f63ef18357..ed8bfb5b80fbb42fe59ae56b070691a2224098c7 100644 (file)
@@ -169,11 +169,11 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions) {
       // Otherwise, we can fold this switch into a conditional branch
       // instruction if it has only one non-default destination.
       SwitchInst::CaseIt FirstCase = SI->case_begin();
-      IntegersSubset CaseRanges = FirstCase.getCaseValueEx();
-      if (CaseRanges.getNumItems() == 1 && CaseRanges.isSingleNumber(0)) {
+      IntegersSubset& Case = FirstCase.getCaseValueEx();
+      if (Case.isSingleNumber()) {
         // FIXME: Currently work with ConstantInt based numbers.
         Value *Cond = Builder.CreateICmpEQ(SI->getCondition(),
-            CaseRanges.getItem(0).getLow().toConstantInt(),
+             Case.getSingleNumber(0).toConstantInt(),
             "cond");
 
         // Insert the new branch.
@@ -183,7 +183,6 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions) {
         // Delete the old switch.
         SI->eraseFromParent();
         return true;
-        
       }
     }
     return false;