--- ..\Documents\LLVM\llvm-2.9-original\llvm-2.9\lib\Transforms\InstCombine\InstructionCombining.cpp	2011-02-14 17:02:30.000000000 -0800
+++ ..\Documents\LLVM\llvm-2.9\lib\Transforms\InstCombine\InstructionCombining.cpp	2011-07-28 13:13:13.187942900 -0700
@@ -310,6 +310,163 @@
   return false;
 }
 
+/// SimplifyUsingXorChain - This tries to find a sequence (chain) of xor
+/// operations, where each operation result is used as a operand for the next
+/// operation, and the second operand is always 1 << N, where N is
+/// incremented on each xor operation.
+Value *InstCombiner::SimplifyUsingXorChain(BinaryOperator &I) {
+
+  Value *LHS = I.getOperand(0);
+  Value *RHS = I.getOperand(1);
+  BinaryOperator *Op0 = dyn_cast<BinaryOperator>(LHS);
+  BinaryOperator *Op1 = dyn_cast<BinaryOperator>(RHS);
+  Instruction::BinaryOps TopLevelOpcode = I.getOpcode();
+  int isXOR = 0;
+
+  // is Op0 really a xor?
+  if (Op0 && Op0->getOpcode() == I.getOpcode() &&
+      Op0->getParent() == I.getParent()) {
+    isXOR = 1;
+  }
+  // check if the xor instruction is in Op1 (the second operand).
+  else if (Op1 && Op1->getOpcode() == I.getOpcode() &&
+           Op1->getParent() == I.getParent()) {
+    isXOR = 1;
+    BinaryOperator *tmp = Op0;
+    Op0 = Op1;
+    Op1 = tmp;
+    LHS = I.getOperand(1);
+    RHS = I.getOperand(0);
+  }
+
+  if (isXOR) {
+    Value *LHS_LHS = Op0->getOperand(0);
+    Value *LHS_RHS = Op0->getOperand(1);
+    Value *RHS_RHS;
+    Value *LHS_RHS_RHS = 0;
+    Value *sourceRoot = 0;
+    int baseValueToBeShifted = 0;
+    int secondBaseValueToBeShifted = 0;
+    int andConst = 0;
+    int sourceInc = 0;;
+    int isSHL = 0;
+
+    BinaryOperator *Op0_0 = dyn_cast<BinaryOperator>(LHS_LHS);
+    BinaryOperator *Op0_1 = dyn_cast<BinaryOperator>(LHS_RHS);
+
+    // is LHS_RHS a shl?
+    if(Op0_1 && Op0_1->getOpcode() == Instruction::BinaryOps::Shl) {
+      isSHL = 1;
+    }
+    // also check the second operand.
+    else if (Op0_0 && Op0_0->getOpcode() == Instruction::BinaryOps::Shl) {
+      isSHL = 1;
+      BinaryOperator *tmp = Op0_0;
+      Op0_0 = Op0_1;
+      Op0_1 = tmp;
+      LHS_LHS = Op0->getOperand(1);
+      LHS_RHS = Op0->getOperand(0);
+    }
+
+    if(isSHL) {
+      // is the value shifted a constant?
+      if(Op0_1->getOperand(0)->getValueID() == ConstantInt::ConstantIntVal) {
+        // save the value shifted in baseValueToBeShifted.
+        const ConstantInt *CI = dyn_cast<ConstantInt>(Op0_1->getOperand(0));
+        baseValueToBeShifted = static_cast<int>(CI->getValue().getZExtValue());
+
+        // now we must find the shift factor. It will be used to determine if
+        // we can actually fold the XOR instructions. We must check if there is
+        // a simple increment between the two XOR instructions.
+        LHS_RHS_RHS = Op0_1->getOperand(1);
+        Instruction *Op0_1_1 = dyn_cast<Instruction>(LHS_RHS_RHS);
+        switch(Op0_1_1->getOpcode()) {
+        // if it is not an increment instruction (OR or AND) then, it is the
+        // source of the chain.
+        default:
+          // variable incremented in each iteration.
+          sourceRoot = LHS_RHS_RHS;
+          // this is the first XOR, so there is no increment.
+          sourceInc = 0;
+          break;
+        case Instruction::Or:
+          // variable incremented in each iteration.
+          sourceRoot = Op0_1_1->getOperand(0);
+          // this is the value incremented one the last iterarion,
+          // on our implementation, it is not really incremented, instead,
+          // the value shifted is the one altered.
+          const ConstantInt *CI = dyn_cast<ConstantInt>
+                                    (Op0_1_1->getOperand(1));
+          sourceInc = static_cast<int>(CI->getValue().getZExtValue());
+          break;
+        }
+      }
+    }
+
+    // Now we look into the right side of the XOR instruction.
+
+    // check if we reached a 'baseValueToBeShifted' on the left side and
+    // if the right operando of the top XOR is a shl.
+    if(baseValueToBeShifted && Op1 &&
+       Op1->getOpcode() == Instruction::BinaryOps::Shl) {
+
+      // check if the value shifted is a constant == 1.
+      if(Op1->getOperand(0)->getValueID() == ConstantInt::ConstantIntVal) {
+        const ConstantInt *CI = dyn_cast<ConstantInt>(Op1->getOperand(0));
+        secondBaseValueToBeShifted = 
+                              static_cast<int>(CI->getValue().getZExtValue());
+        if(secondBaseValueToBeShifted) {
+
+          // are both XOR instructions using the same source value as operands?
+          // one of them is incrementing the operand by 1? (going to check it
+          // soon).
+          RHS_RHS = Op1->getOperand(1);
+          BinaryOperator *Op1_1 = dyn_cast<BinaryOperator>(RHS_RHS);
+          // if(Op1_1->getOperand(0) == LHS_RHS_RHS).
+          if(Op1_1->getOperand(0) == sourceRoot) {
+
+            // OK, both XOR operands are using the same source value for its
+            // operation, now we fold the two shifts into a single one.
+            // We also fold the two %rem into a single one, afterwards,
+            // DCE do the rest of the work.
+
+            // but first we check if the increment was really a single unit.
+            // TODO: we can make it more generic. Now, we just a accept to fold
+            // a 0000 1111 with a 1111 0000, but it could also be a any other 
+            // variable that does not overlap the first one.
+            const ConstantInt *CI = dyn_cast<ConstantInt>
+                                                        (Op1_1->getOperand(1));
+            int nextInc = static_cast<int>(CI->getValue().getZExtValue());
+            int tmp = baseValueToBeShifted;
+            int stop = 0;
+            while(tmp){stop++; tmp=tmp>>1;}
+            if(sourceInc + stop != nextInc)
+              return 0;
+
+            int newShift = (baseValueToBeShifted |
+                            (secondBaseValueToBeShifted << stop));
+
+            // remake the shift instruction, now its operands has one more bit,
+            // if it was 0000 0011 it becomes 0000 0111.
+            const IntegerType *intType = intType->get(I.getContext(), 32);
+            ConstantInt *newShiftConst = newShiftConst->get(intType, newShift);
+            Op0_1->setOperand(0,newShiftConst);
+
+            // update the basic block, replacing the uses of deleted
+            // instruction by the new ones
+            RHS_RHS->replaceAllUsesWith(LHS_RHS_RHS);
+            RHS->replaceAllUsesWith(LHS_RHS);
+            return LHS;
+          }
+        }
+      }
+    }
+  }
+
+  return 0;
+
+}
+
 /// SimplifyUsingDistributiveLaws - This tries to simplify binary operations
 /// which some other binary operation distributes over either by factorizing
 /// out common terms (eg "(A*B)+(A*C)" -> "A*(B+C)") or expanding out if this
