[llvm-commits] CVS: llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/InstructionCombining.cpp.txt Makefile README agrep agrep.h asearch.c asearch1.c bitap.c checkfile.c checkfile.h compat.c follow.c main.c maskgen.c mgrep.c parse.c preprocess.c re.h sgrep.c utilities.c

Chris Lattner lattner at cs.uiuc.edu
Tue Oct 5 11:03:12 PDT 2004



Changes in directory llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep:

InstructionCombining.cpp.txt added (r1.1)
Makefile added (r1.1)
README added (r1.1)
agrep added (r1.1)
agrep.h added (r1.1)
asearch.c added (r1.1)
asearch1.c added (r1.1)
bitap.c added (r1.1)
checkfile.c added (r1.1)
checkfile.h added (r1.1)
compat.c added (r1.1)
follow.c added (r1.1)
main.c added (r1.1)
maskgen.c added (r1.1)
mgrep.c added (r1.1)
parse.c added (r1.1)
preprocess.c added (r1.1)
re.h added (r1.1)
sgrep.c added (r1.1)
utilities.c added (r1.1)
---
Log message:

New benchmark


---
Diffs of the changes:  (+7998 -0)

Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/InstructionCombining.cpp.txt
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/InstructionCombining.cpp.txt:1.1
*** /dev/null	Tue Oct  5 13:03:08 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/InstructionCombining.cpp.txt	Tue Oct  5 13:02:58 2004
***************
*** 0 ****
--- 1,3936 ----
+ //===- InstructionCombining.cpp - Combine multiple instructions -----------===//
+ // 
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by the LLVM research group and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ // 
+ //===----------------------------------------------------------------------===//
+ //
+ // InstructionCombining - Combine instructions to form fewer, simple
+ // instructions.  This pass does not modify the CFG This pass is where algebraic
+ // simplification happens.
+ //
+ // This pass combines things like:
+ //    %Y = add int %X, 1
+ //    %Z = add int %Y, 1
+ // into:
+ //    %Z = add int %X, 2
+ //
+ // This is a simple worklist driven algorithm.
+ //
+ // This pass guarantees that the following canonicalizations are performed on
+ // the program:
+ //    1. If a binary operator has a constant operand, it is moved to the RHS
+ //    2. Bitwise operators with constant operands are always grouped so that
+ //       shifts are performed first, then or's, then and's, then xor's.
+ //    3. SetCC instructions are converted from <,>,<=,>= to ==,!= if possible
+ //    4. All SetCC instructions on boolean values are replaced with logical ops
+ //    5. add X, X is represented as (X*2) => (X << 1)
+ //    6. Multiplies with a power-of-two constant argument are transformed into
+ //       shifts.
+ //    N. This list is incomplete
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #define DEBUG_TYPE "instcombine"
+ #include "llvm/Transforms/Scalar.h"
+ #include "llvm/Instructions.h"
+ #include "llvm/Intrinsics.h"
+ #include "llvm/Pass.h"
+ #include "llvm/Constants.h"
+ #include "llvm/DerivedTypes.h"
+ #include "llvm/GlobalVariable.h"
+ #include "llvm/Target/TargetData.h"
+ #include "llvm/Transforms/Utils/BasicBlockUtils.h"
+ #include "llvm/Transforms/Utils/Local.h"
+ #include "llvm/Support/CallSite.h"
+ #include "llvm/Support/GetElementPtrTypeIterator.h"
+ #include "llvm/Support/InstIterator.h"
+ #include "llvm/Support/InstVisitor.h"
+ #include "llvm/Support/PatternMatch.h"
+ #include "llvm/Support/Debug.h"
+ #include "llvm/ADT/Statistic.h"
+ #include <algorithm>
+ using namespace llvm;
+ using namespace llvm::PatternMatch;
+ 
+ namespace {
+   Statistic<> NumCombined ("instcombine", "Number of insts combined");
+   Statistic<> NumConstProp("instcombine", "Number of constant folds");
+   Statistic<> NumDeadInst ("instcombine", "Number of dead inst eliminated");
+ 
+   class InstCombiner : public FunctionPass,
+                        public InstVisitor<InstCombiner, Instruction*> {
+     // Worklist of all of the instructions that need to be simplified.
+     std::vector<Instruction*> WorkList;
+     TargetData *TD;
+ 
+     /// AddUsersToWorkList - When an instruction is simplified, add all users of
+     /// the instruction to the work lists because they might get more simplified
+     /// now.
+     ///
+     void AddUsersToWorkList(Instruction &I) {
+       for (Value::use_iterator UI = I.use_begin(), UE = I.use_end();
+            UI != UE; ++UI)
+         WorkList.push_back(cast<Instruction>(*UI));
+     }
+ 
+     /// AddUsesToWorkList - When an instruction is simplified, add operands to
+     /// the work lists because they might get more simplified now.
+     ///
+     void AddUsesToWorkList(Instruction &I) {
+       for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
+         if (Instruction *Op = dyn_cast<Instruction>(I.getOperand(i)))
+           WorkList.push_back(Op);
+     }
+ 
+     // removeFromWorkList - remove all instances of I from the worklist.
+     void removeFromWorkList(Instruction *I);
+   public:
+     virtual bool runOnFunction(Function &F);
+ 
+     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+       AU.addRequired<TargetData>();
+       AU.setPreservesCFG();
+     }
+ 
+     TargetData &getTargetData() const { return *TD; }
+ 
+     // Visitation implementation - Implement instruction combining for different
+     // instruction types.  The semantics are as follows:
+     // Return Value:
+     //    null        - No change was made
+     //     I          - Change was made, I is still valid, I may be dead though
+     //   otherwise    - Change was made, replace I with returned instruction
+     //   
+     Instruction *visitAdd(BinaryOperator &I);
+     Instruction *visitSub(BinaryOperator &I);
+     Instruction *visitMul(BinaryOperator &I);
+     Instruction *visitDiv(BinaryOperator &I);
+     Instruction *visitRem(BinaryOperator &I);
+     Instruction *visitAnd(BinaryOperator &I);
+     Instruction *visitOr (BinaryOperator &I);
+     Instruction *visitXor(BinaryOperator &I);
+     Instruction *visitSetCondInst(BinaryOperator &I);
+     Instruction *visitShiftInst(ShiftInst &I);
+     Instruction *visitCastInst(CastInst &CI);
+     Instruction *visitSelectInst(SelectInst &CI);
+     Instruction *visitCallInst(CallInst &CI);
+     Instruction *visitInvokeInst(InvokeInst &II);
+     Instruction *visitPHINode(PHINode &PN);
+     Instruction *visitGetElementPtrInst(GetElementPtrInst &GEP);
+     Instruction *visitAllocationInst(AllocationInst &AI);
+     Instruction *visitFreeInst(FreeInst &FI);
+     Instruction *visitLoadInst(LoadInst &LI);
+     Instruction *visitBranchInst(BranchInst &BI);
+     Instruction *visitSwitchInst(SwitchInst &SI);
+ 
+     // visitInstruction - Specify what to return for unhandled instructions...
+     Instruction *visitInstruction(Instruction &I) { return 0; }
+ 
+   private:
+     Instruction *visitCallSite(CallSite CS);
+     bool transformConstExprCastCall(CallSite CS);
+ 
+   public:
+     // InsertNewInstBefore - insert an instruction New before instruction Old
+     // in the program.  Add the new instruction to the worklist.
+     //
+     Instruction *InsertNewInstBefore(Instruction *New, Instruction &Old) {
+       assert(New && New->getParent() == 0 &&
+              "New instruction already inserted into a basic block!");
+       BasicBlock *BB = Old.getParent();
+       BB->getInstList().insert(&Old, New);  // Insert inst
+       WorkList.push_back(New);              // Add to worklist
+       return New;
+     }
+ 
+     /// InsertCastBefore - Insert a cast of V to TY before the instruction POS.
+     /// This also adds the cast to the worklist.  Finally, this returns the
+     /// cast.
+     Value *InsertCastBefore(Value *V, const Type *Ty, Instruction &Pos) {
+       if (V->getType() == Ty) return V;
+       
+       Instruction *C = new CastInst(V, Ty, V->getName(), &Pos);
+       WorkList.push_back(C);
+       return C;
+     }
+ 
+     // ReplaceInstUsesWith - This method is to be used when an instruction is
+     // found to be dead, replacable with another preexisting expression.  Here
+     // we add all uses of I to the worklist, replace all uses of I with the new
+     // value, then return I, so that the inst combiner will know that I was
+     // modified.
+     //
+     Instruction *ReplaceInstUsesWith(Instruction &I, Value *V) {
+       AddUsersToWorkList(I);         // Add all modified instrs to worklist
+       if (&I != V) {
+         I.replaceAllUsesWith(V);
+         return &I;
+       } else {
+         // If we are replacing the instruction with itself, this must be in a
+         // segment of unreachable code, so just clobber the instruction.
+         I.replaceAllUsesWith(Constant::getNullValue(I.getType()));
+         return &I;
+       }
+     }
+ 
+     // EraseInstFromFunction - When dealing with an instruction that has side
+     // effects or produces a void value, we can't rely on DCE to delete the
+     // instruction.  Instead, visit methods should return the value returned by
+     // this function.
+     Instruction *EraseInstFromFunction(Instruction &I) {
+       assert(I.use_empty() && "Cannot erase instruction that is used!");
+       AddUsesToWorkList(I);
+       removeFromWorkList(&I);
+       I.getParent()->getInstList().erase(&I);
+       return 0;  // Don't do anything with FI
+     }
+ 
+ 
+   private:
+     /// InsertOperandCastBefore - This inserts a cast of V to DestTy before the
+     /// InsertBefore instruction.  This is specialized a bit to avoid inserting
+     /// casts that are known to not do anything...
+     ///
+     Value *InsertOperandCastBefore(Value *V, const Type *DestTy,
+                                    Instruction *InsertBefore);
+ 
+     // SimplifyCommutative - This performs a few simplifications for commutative
+     // operators.
+     bool SimplifyCommutative(BinaryOperator &I);
+ 
+ 
+     // FoldOpIntoPhi - Given a binary operator or cast instruction which has a
+     // PHI node as operand #0, see if we can fold the instruction into the PHI
+     // (which is only possible if all operands to the PHI are constants).
+     Instruction *FoldOpIntoPhi(Instruction &I);
+ 
+     Instruction *OptAndOp(Instruction *Op, ConstantIntegral *OpRHS,
+                           ConstantIntegral *AndRHS, BinaryOperator &TheAnd);
+ 
+     Instruction *InsertRangeTest(Value *V, Constant *Lo, Constant *Hi,
+                                  bool Inside, Instruction &IB);
+   };
+ 
+   RegisterOpt<InstCombiner> X("instcombine", "Combine redundant instructions");
+ }
+ 
+ // getComplexity:  Assign a complexity or rank value to LLVM Values...
+ //   0 -> Constant, 1 -> Other, 2 -> Argument, 2 -> Unary, 3 -> OtherInst
+ static unsigned getComplexity(Value *V) {
+   if (isa<Instruction>(V)) {
+     if (BinaryOperator::isNeg(V) || BinaryOperator::isNot(V))
+       return 2;
+     return 3;
+   }
+   if (isa<Argument>(V)) return 2;
+   return isa<Constant>(V) ? 0 : 1;
+ }
+ 
+ // isOnlyUse - Return true if this instruction will be deleted if we stop using
+ // it.
+ static bool isOnlyUse(Value *V) {
+   return V->hasOneUse() || isa<Constant>(V);
+ }
+ 
+ // getPromotedType - Return the specified type promoted as it would be to pass
+ // though a va_arg area...
+ static const Type *getPromotedType(const Type *Ty) {
+   switch (Ty->getTypeID()) {
+   case Type::SByteTyID:
+   case Type::ShortTyID:  return Type::IntTy;
+   case Type::UByteTyID:
+   case Type::UShortTyID: return Type::UIntTy;
+   case Type::FloatTyID:  return Type::DoubleTy;
+   default:               return Ty;
+   }
+ }
+ 
+ // SimplifyCommutative - This performs a few simplifications for commutative
+ // operators:
+ //
+ //  1. Order operands such that they are listed from right (least complex) to
+ //     left (most complex).  This puts constants before unary operators before
+ //     binary operators.
+ //
+ //  2. Transform: (op (op V, C1), C2) ==> (op V, (op C1, C2))
+ //  3. Transform: (op (op V1, C1), (op V2, C2)) ==> (op (op V1, V2), (op C1,C2))
+ //
+ bool InstCombiner::SimplifyCommutative(BinaryOperator &I) {
+   bool Changed = false;
+   if (getComplexity(I.getOperand(0)) < getComplexity(I.getOperand(1)))
+     Changed = !I.swapOperands();
+   
+   if (!I.isAssociative()) return Changed;
+   Instruction::BinaryOps Opcode = I.getOpcode();
+   if (BinaryOperator *Op = dyn_cast<BinaryOperator>(I.getOperand(0)))
+     if (Op->getOpcode() == Opcode && isa<Constant>(Op->getOperand(1))) {
+       if (isa<Constant>(I.getOperand(1))) {
+         Constant *Folded = ConstantExpr::get(I.getOpcode(),
+                                              cast<Constant>(I.getOperand(1)),
+                                              cast<Constant>(Op->getOperand(1)));
+         I.setOperand(0, Op->getOperand(0));
+         I.setOperand(1, Folded);
+         return true;
+       } else if (BinaryOperator *Op1=dyn_cast<BinaryOperator>(I.getOperand(1)))
+         if (Op1->getOpcode() == Opcode && isa<Constant>(Op1->getOperand(1)) &&
+             isOnlyUse(Op) && isOnlyUse(Op1)) {
+           Constant *C1 = cast<Constant>(Op->getOperand(1));
+           Constant *C2 = cast<Constant>(Op1->getOperand(1));
+ 
+           // Fold (op (op V1, C1), (op V2, C2)) ==> (op (op V1, V2), (op C1,C2))
+           Constant *Folded = ConstantExpr::get(I.getOpcode(), C1, C2);
+           Instruction *New = BinaryOperator::create(Opcode, Op->getOperand(0),
+                                                     Op1->getOperand(0),
+                                                     Op1->getName(), &I);
+           WorkList.push_back(New);
+           I.setOperand(0, New);
+           I.setOperand(1, Folded);
+           return true;
+         }      
+     }
+   return Changed;
+ }
+ 
+ // dyn_castNegVal - Given a 'sub' instruction, return the RHS of the instruction
+ // if the LHS is a constant zero (which is the 'negate' form).
+ //
+ static inline Value *dyn_castNegVal(Value *V) {
+   if (BinaryOperator::isNeg(V))
+     return BinaryOperator::getNegArgument(cast<BinaryOperator>(V));
+ 
+   // Constants can be considered to be negated values if they can be folded...
+   if (Constant *C = dyn_cast<Constant>(V))
+     return ConstantExpr::getNeg(C);
+   return 0;
+ }
+ 
+ static inline Value *dyn_castNotVal(Value *V) {
+   if (BinaryOperator::isNot(V))
+     return BinaryOperator::getNotArgument(cast<BinaryOperator>(V));
+ 
+   // Constants can be considered to be not'ed values...
+   if (ConstantIntegral *C = dyn_cast<ConstantIntegral>(V))
+     return ConstantExpr::getNot(C);
+   return 0;
+ }
+ 
+ // dyn_castFoldableMul - If this value is a multiply that can be folded into
+ // other computations (because it has a constant operand), return the
+ // non-constant operand of the multiply.
+ //
+ static inline Value *dyn_castFoldableMul(Value *V) {
+   if (V->hasOneUse() && V->getType()->isInteger())
+     if (Instruction *I = dyn_cast<Instruction>(V))
+       if (I->getOpcode() == Instruction::Mul)
+         if (isa<Constant>(I->getOperand(1)))
+           return I->getOperand(0);
+   return 0;
+ }
+ 
+ // Log2 - Calculate the log base 2 for the specified value if it is exactly a
+ // power of 2.
+ static unsigned Log2(uint64_t Val) {
+   assert(Val > 1 && "Values 0 and 1 should be handled elsewhere!");
+   unsigned Count = 0;
+   while (Val != 1) {
+     if (Val & 1) return 0;    // Multiple bits set?
+     Val >>= 1;
+     ++Count;
+   }
+   return Count;
+ }
+ 
+ // AddOne, SubOne - Add or subtract a constant one from an integer constant...
+ static ConstantInt *AddOne(ConstantInt *C) {
+   return cast<ConstantInt>(ConstantExpr::getAdd(C,
+                                          ConstantInt::get(C->getType(), 1)));
+ }
+ static ConstantInt *SubOne(ConstantInt *C) {
+   return cast<ConstantInt>(ConstantExpr::getSub(C,
+                                          ConstantInt::get(C->getType(), 1)));
+ }
+ 
+ // isTrueWhenEqual - Return true if the specified setcondinst instruction is
+ // true when both operands are equal...
+ //
+ static bool isTrueWhenEqual(Instruction &I) {
+   return I.getOpcode() == Instruction::SetEQ ||
+          I.getOpcode() == Instruction::SetGE ||
+          I.getOpcode() == Instruction::SetLE;
+ }
+ 
+ /// AssociativeOpt - Perform an optimization on an associative operator.  This
+ /// function is designed to check a chain of associative operators for a
+ /// potential to apply a certain optimization.  Since the optimization may be
+ /// applicable if the expression was reassociated, this checks the chain, then
+ /// reassociates the expression as necessary to expose the optimization
+ /// opportunity.  This makes use of a special Functor, which must define
+ /// 'shouldApply' and 'apply' methods.
+ ///
+ template<typename Functor>
+ Instruction *AssociativeOpt(BinaryOperator &Root, const Functor &F) {
+   unsigned Opcode = Root.getOpcode();
+   Value *LHS = Root.getOperand(0);
+ 
+   // Quick check, see if the immediate LHS matches...
+   if (F.shouldApply(LHS))
+     return F.apply(Root);
+ 
+   // Otherwise, if the LHS is not of the same opcode as the root, return.
+   Instruction *LHSI = dyn_cast<Instruction>(LHS);
+   while (LHSI && LHSI->getOpcode() == Opcode && LHSI->hasOneUse()) {
+     // Should we apply this transform to the RHS?
+     bool ShouldApply = F.shouldApply(LHSI->getOperand(1));
+ 
+     // If not to the RHS, check to see if we should apply to the LHS...
+     if (!ShouldApply && F.shouldApply(LHSI->getOperand(0))) {
+       cast<BinaryOperator>(LHSI)->swapOperands();   // Make the LHS the RHS
+       ShouldApply = true;
+     }
+ 
+     // If the functor wants to apply the optimization to the RHS of LHSI,
+     // reassociate the expression from ((? op A) op B) to (? op (A op B))
+     if (ShouldApply) {
+       BasicBlock *BB = Root.getParent();
+       
+       // Now all of the instructions are in the current basic block, go ahead
+       // and perform the reassociation.
+       Instruction *TmpLHSI = cast<Instruction>(Root.getOperand(0));
+ 
+       // First move the selected RHS to the LHS of the root...
+       Root.setOperand(0, LHSI->getOperand(1));
+ 
+       // Make what used to be the LHS of the root be the user of the root...
+       Value *ExtraOperand = TmpLHSI->getOperand(1);
+       if (&Root == TmpLHSI) {
+         Root.replaceAllUsesWith(Constant::getNullValue(TmpLHSI->getType()));
+         return 0;
+       }
+       Root.replaceAllUsesWith(TmpLHSI);          // Users now use TmpLHSI
+       TmpLHSI->setOperand(1, &Root);             // TmpLHSI now uses the root
+       TmpLHSI->getParent()->getInstList().remove(TmpLHSI);
+       BasicBlock::iterator ARI = &Root; ++ARI;
+       BB->getInstList().insert(ARI, TmpLHSI);    // Move TmpLHSI to after Root
+       ARI = Root;
+ 
+       // Now propagate the ExtraOperand down the chain of instructions until we
+       // get to LHSI.
+       while (TmpLHSI != LHSI) {
+         Instruction *NextLHSI = cast<Instruction>(TmpLHSI->getOperand(0));
+         // Move the instruction to immediately before the chain we are
+         // constructing to avoid breaking dominance properties.
+         NextLHSI->getParent()->getInstList().remove(NextLHSI);
+         BB->getInstList().insert(ARI, NextLHSI);
+         ARI = NextLHSI;
+ 
+         Value *NextOp = NextLHSI->getOperand(1);
+         NextLHSI->setOperand(1, ExtraOperand);
+         TmpLHSI = NextLHSI;
+         ExtraOperand = NextOp;
+       }
+       
+       // Now that the instructions are reassociated, have the functor perform
+       // the transformation...
+       return F.apply(Root);
+     }
+     
+     LHSI = dyn_cast<Instruction>(LHSI->getOperand(0));
+   }
+   return 0;
+ }
+ 
+ 
+ // AddRHS - Implements: X + X --> X << 1
+ struct AddRHS {
+   Value *RHS;
+   AddRHS(Value *rhs) : RHS(rhs) {}
+   bool shouldApply(Value *LHS) const { return LHS == RHS; }
+   Instruction *apply(BinaryOperator &Add) const {
+     return new ShiftInst(Instruction::Shl, Add.getOperand(0),
+                          ConstantInt::get(Type::UByteTy, 1));
+   }
+ };
+ 
+ // AddMaskingAnd - Implements (A & C1)+(B & C2) --> (A & C1)|(B & C2)
+ //                 iff C1&C2 == 0
+ struct AddMaskingAnd {
+   Constant *C2;
+   AddMaskingAnd(Constant *c) : C2(c) {}
+   bool shouldApply(Value *LHS) const {
+     ConstantInt *C1;
+     return match(LHS, m_And(m_Value(), m_ConstantInt(C1))) && 
+            ConstantExpr::getAnd(C1, C2)->isNullValue();
+   }
+   Instruction *apply(BinaryOperator &Add) const {
+     return BinaryOperator::createOr(Add.getOperand(0), Add.getOperand(1));
+   }
+ };
+ 
+ static Value *FoldOperationIntoSelectOperand(Instruction &BI, Value *SO,
+                                              InstCombiner *IC) {
+   // Figure out if the constant is the left or the right argument.
+   bool ConstIsRHS = isa<Constant>(BI.getOperand(1));
+   Constant *ConstOperand = cast<Constant>(BI.getOperand(ConstIsRHS));
+ 
+   if (Constant *SOC = dyn_cast<Constant>(SO)) {
+     if (ConstIsRHS)
+       return ConstantExpr::get(BI.getOpcode(), SOC, ConstOperand);
+     return ConstantExpr::get(BI.getOpcode(), ConstOperand, SOC);
+   }
+ 
+   Value *Op0 = SO, *Op1 = ConstOperand;
+   if (!ConstIsRHS)
+     std::swap(Op0, Op1);
+   Instruction *New;
+   if (BinaryOperator *BO = dyn_cast<BinaryOperator>(&BI))
+     New = BinaryOperator::create(BO->getOpcode(), Op0, Op1);
+   else if (ShiftInst *SI = dyn_cast<ShiftInst>(&BI))
+     New = new ShiftInst(SI->getOpcode(), Op0, Op1);
+   else {
+     assert(0 && "Unknown binary instruction type!");
+     abort();
+   }
+   return IC->InsertNewInstBefore(New, BI);
+ }
+ 
+ 
+ /// FoldOpIntoPhi - Given a binary operator or cast instruction which has a PHI
+ /// node as operand #0, see if we can fold the instruction into the PHI (which
+ /// is only possible if all operands to the PHI are constants).
+ Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) {
+   PHINode *PN = cast<PHINode>(I.getOperand(0));
+   if (!PN->hasOneUse()) return 0;
+ 
+   // Check to see if all of the operands of the PHI are constants.  If not, we
+   // cannot do the transformation.
+   for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
+     if (!isa<Constant>(PN->getIncomingValue(i)))
+       return 0;
+ 
+   // Okay, we can do the transformation: create the new PHI node.
+   PHINode *NewPN = new PHINode(I.getType(), I.getName());
+   I.setName("");
+   NewPN->op_reserve(PN->getNumOperands());
+   InsertNewInstBefore(NewPN, *PN);
+ 
+   // Next, add all of the operands to the PHI.
+   if (I.getNumOperands() == 2) {
+     Constant *C = cast<Constant>(I.getOperand(1));
+     for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
+       Constant *InV = cast<Constant>(PN->getIncomingValue(i));
+       NewPN->addIncoming(ConstantExpr::get(I.getOpcode(), InV, C),
+                          PN->getIncomingBlock(i));
+     }
+   } else {
+     assert(isa<CastInst>(I) && "Unary op should be a cast!");
+     const Type *RetTy = I.getType();
+     for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
+       Constant *InV = cast<Constant>(PN->getIncomingValue(i));
+       NewPN->addIncoming(ConstantExpr::getCast(InV, RetTy),
+                          PN->getIncomingBlock(i));
+     }
+   }
+   return ReplaceInstUsesWith(I, NewPN);
+ }
+ 
+ // FoldBinOpIntoSelect - Given an instruction with a select as one operand and a
+ // constant as the other operand, try to fold the binary operator into the
+ // select arguments.
+ static Instruction *FoldBinOpIntoSelect(Instruction &BI, SelectInst *SI,
+                                         InstCombiner *IC) {
+   // Don't modify shared select instructions
+   if (!SI->hasOneUse()) return 0;
+   Value *TV = SI->getOperand(1);
+   Value *FV = SI->getOperand(2);
+ 
+   if (isa<Constant>(TV) || isa<Constant>(FV)) {
+     Value *SelectTrueVal = FoldOperationIntoSelectOperand(BI, TV, IC);
+     Value *SelectFalseVal = FoldOperationIntoSelectOperand(BI, FV, IC);
+ 
+     return new SelectInst(SI->getCondition(), SelectTrueVal,
+                           SelectFalseVal);
+   }
+   return 0;
+ }
+ 
+ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
+   bool Changed = SimplifyCommutative(I);
+   Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
+ 
+   if (Constant *RHSC = dyn_cast<Constant>(RHS)) {
+     // X + 0 --> X
+     if (!I.getType()->isFloatingPoint() && // -0 + +0 = +0, so it's not a noop
+         RHSC->isNullValue())
+       return ReplaceInstUsesWith(I, LHS);
+     
+     // X + (signbit) --> X ^ signbit
+     if (ConstantInt *CI = dyn_cast<ConstantInt>(RHSC)) {
+       unsigned NumBits = CI->getType()->getPrimitiveSize()*8;
+       uint64_t Val = CI->getRawValue() & (1ULL << NumBits)-1;
+       if (Val == (1ULL << NumBits-1))
+         return BinaryOperator::createXor(LHS, RHS);
+     }
+ 
+     if (isa<PHINode>(LHS))
+       if (Instruction *NV = FoldOpIntoPhi(I))
+         return NV;
+   }
+ 
+   // X + X --> X << 1
+   if (I.getType()->isInteger()) {
+     if (Instruction *Result = AssociativeOpt(I, AddRHS(RHS))) return Result;
+   }
+ 
+   // -A + B  -->  B - A
+   if (Value *V = dyn_castNegVal(LHS))
+     return BinaryOperator::createSub(RHS, V);
+ 
+   // A + -B  -->  A - B
+   if (!isa<Constant>(RHS))
+     if (Value *V = dyn_castNegVal(RHS))
+       return BinaryOperator::createSub(LHS, V);
+ 
+   // X*C + X --> X * (C+1)
+   if (dyn_castFoldableMul(LHS) == RHS) {
+     Constant *CP1 =
+       ConstantExpr::getAdd(
+                         cast<Constant>(cast<Instruction>(LHS)->getOperand(1)),
+                         ConstantInt::get(I.getType(), 1));
+     return BinaryOperator::createMul(RHS, CP1);
+   }
+ 
+   // X + X*C --> X * (C+1)
+   if (dyn_castFoldableMul(RHS) == LHS) {
+     Constant *CP1 =
+       ConstantExpr::getAdd(
+                         cast<Constant>(cast<Instruction>(RHS)->getOperand(1)),
+                         ConstantInt::get(I.getType(), 1));
+     return BinaryOperator::createMul(LHS, CP1);
+   }
+ 
+   // (A & C1)+(B & C2) --> (A & C1)|(B & C2) iff C1&C2 == 0
+   ConstantInt *C2;
+   if (match(RHS, m_And(m_Value(), m_ConstantInt(C2))))
+     if (Instruction *R = AssociativeOpt(I, AddMaskingAnd(C2))) return R;
+ 
+   if (ConstantInt *CRHS = dyn_cast<ConstantInt>(RHS)) {
+     Value *X;
+     if (match(LHS, m_Not(m_Value(X)))) {   // ~X + C --> (C-1) - X
+       Constant *C= ConstantExpr::getSub(CRHS, ConstantInt::get(I.getType(), 1));
+       return BinaryOperator::createSub(C, X);
+     }
+ 
+     // Try to fold constant add into select arguments.
+     if (SelectInst *SI = dyn_cast<SelectInst>(LHS))
+       if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
+         return R;
+   }
+ 
+   return Changed ? &I : 0;
+ }
+ 
+ // isSignBit - Return true if the value represented by the constant only has the
+ // highest order bit set.
+ static bool isSignBit(ConstantInt *CI) {
+   unsigned NumBits = CI->getType()->getPrimitiveSize()*8;
+   return (CI->getRawValue() & ~(-1LL << NumBits)) == (1ULL << (NumBits-1));
+ }
+ 
+ static unsigned getTypeSizeInBits(const Type *Ty) {
+   return Ty == Type::BoolTy ? 1 : Ty->getPrimitiveSize()*8;
+ }
+ 
+ /// RemoveNoopCast - Strip off nonconverting casts from the value.
+ ///
+ static Value *RemoveNoopCast(Value *V) {
+   if (CastInst *CI = dyn_cast<CastInst>(V)) {
+     const Type *CTy = CI->getType();
+     const Type *OpTy = CI->getOperand(0)->getType();
+     if (CTy->isInteger() && OpTy->isInteger()) {
+       if (CTy->getPrimitiveSize() == OpTy->getPrimitiveSize())
+         return RemoveNoopCast(CI->getOperand(0));
+     } else if (isa<PointerType>(CTy) && isa<PointerType>(OpTy))
+       return RemoveNoopCast(CI->getOperand(0));
+   }
+   return V;
+ }
+ 
+ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
+   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+ 
+   if (Op0 == Op1)         // sub X, X  -> 0
+     return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+ 
+   // If this is a 'B = x-(-A)', change to B = x+A...
+   if (Value *V = dyn_castNegVal(Op1))
+     return BinaryOperator::createAdd(Op0, V);
+ 
+   if (ConstantInt *C = dyn_cast<ConstantInt>(Op0)) {
+     // Replace (-1 - A) with (~A)...
+     if (C->isAllOnesValue())
+       return BinaryOperator::createNot(Op1);
+ 
+     // C - ~X == X + (1+C)
+     Value *X;
+     if (match(Op1, m_Not(m_Value(X))))
+       return BinaryOperator::createAdd(X,
+                     ConstantExpr::getAdd(C, ConstantInt::get(I.getType(), 1)));
+     // -((uint)X >> 31) -> ((int)X >> 31)
+     // -((int)X >> 31) -> ((uint)X >> 31)
+     if (C->isNullValue()) {
+       Value *NoopCastedRHS = RemoveNoopCast(Op1);
+       if (ShiftInst *SI = dyn_cast<ShiftInst>(NoopCastedRHS))
+         if (SI->getOpcode() == Instruction::Shr)
+           if (ConstantUInt *CU = dyn_cast<ConstantUInt>(SI->getOperand(1))) {
+             const Type *NewTy;
+             if (SI->getType()->isSigned())
+               NewTy = SI->getType()->getUnsignedVersion();
+             else
+               NewTy = SI->getType()->getSignedVersion();
+             // Check to see if we are shifting out everything but the sign bit.
+             if (CU->getValue() == SI->getType()->getPrimitiveSize()*8-1) {
+               // Ok, the transformation is safe.  Insert a cast of the incoming
+               // value, then the new shift, then the new cast.
+               Instruction *FirstCast = new CastInst(SI->getOperand(0), NewTy,
+                                                  SI->getOperand(0)->getName());
+               Value *InV = InsertNewInstBefore(FirstCast, I);
+               Instruction *NewShift = new ShiftInst(Instruction::Shr, FirstCast,
+                                                     CU, SI->getName());
+               if (NewShift->getType() == I.getType())
+                 return NewShift;
+               else {
+                 InV = InsertNewInstBefore(NewShift, I);
+                 return new CastInst(NewShift, I.getType());
+               }
+             }
+           }
+     }
+ 
+     // Try to fold constant sub into select arguments.
+     if (SelectInst *SI = dyn_cast<SelectInst>(Op1))
+       if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
+         return R;
+ 
+     if (isa<PHINode>(Op0))
+       if (Instruction *NV = FoldOpIntoPhi(I))
+         return NV;
+   }
+ 
+   if (BinaryOperator *Op1I = dyn_cast<BinaryOperator>(Op1))
+     if (Op1I->hasOneUse()) {
+       // Replace (x - (y - z)) with (x + (z - y)) if the (y - z) subexpression
+       // is not used by anyone else...
+       //
+       if (Op1I->getOpcode() == Instruction::Sub &&
+           !Op1I->getType()->isFloatingPoint()) {
+         // Swap the two operands of the subexpr...
+         Value *IIOp0 = Op1I->getOperand(0), *IIOp1 = Op1I->getOperand(1);
+         Op1I->setOperand(0, IIOp1);
+         Op1I->setOperand(1, IIOp0);
+         
+         // Create the new top level add instruction...
+         return BinaryOperator::createAdd(Op0, Op1);
+       }
+ 
+       // Replace (A - (A & B)) with (A & ~B) if this is the only use of (A&B)...
+       //
+       if (Op1I->getOpcode() == Instruction::And &&
+           (Op1I->getOperand(0) == Op0 || Op1I->getOperand(1) == Op0)) {
+         Value *OtherOp = Op1I->getOperand(Op1I->getOperand(0) == Op0);
+ 
+         Value *NewNot =
+           InsertNewInstBefore(BinaryOperator::createNot(OtherOp, "B.not"), I);
+         return BinaryOperator::createAnd(Op0, NewNot);
+       }
+ 
+       // X - X*C --> X * (1-C)
+       if (dyn_castFoldableMul(Op1I) == Op0) {
+         Constant *CP1 =
+           ConstantExpr::getSub(ConstantInt::get(I.getType(), 1),
+                          cast<Constant>(cast<Instruction>(Op1)->getOperand(1)));
+         assert(CP1 && "Couldn't constant fold 1-C?");
+         return BinaryOperator::createMul(Op0, CP1);
+       }
+     }
+ 
+   // X*C - X --> X * (C-1)
+   if (dyn_castFoldableMul(Op0) == Op1) {
+     Constant *CP1 =
+      ConstantExpr::getSub(cast<Constant>(cast<Instruction>(Op0)->getOperand(1)),
+                         ConstantInt::get(I.getType(), 1));
+     assert(CP1 && "Couldn't constant fold C - 1?");
+     return BinaryOperator::createMul(Op1, CP1);
+   }
+ 
+   return 0;
+ }
+ 
+ /// isSignBitCheck - Given an exploded setcc instruction, return true if it is
+ /// really just returns true if the most significant (sign) bit is set.
+ static bool isSignBitCheck(unsigned Opcode, Value *LHS, ConstantInt *RHS) {
+   if (RHS->getType()->isSigned()) {
+     // True if source is LHS < 0 or LHS <= -1
+     return Opcode == Instruction::SetLT && RHS->isNullValue() ||
+            Opcode == Instruction::SetLE && RHS->isAllOnesValue();
+   } else {
+     ConstantUInt *RHSC = cast<ConstantUInt>(RHS);
+     // True if source is LHS > 127 or LHS >= 128, where the constants depend on
+     // the size of the integer type.
+     if (Opcode == Instruction::SetGE)
+       return RHSC->getValue() == 1ULL<<(RHS->getType()->getPrimitiveSize()*8-1);
+     if (Opcode == Instruction::SetGT)
+       return RHSC->getValue() ==
+         (1ULL << (RHS->getType()->getPrimitiveSize()*8-1))-1;
+   }
+   return false;
+ }
+ 
+ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
+   bool Changed = SimplifyCommutative(I);
+   Value *Op0 = I.getOperand(0);
+ 
+   // Simplify mul instructions with a constant RHS...
+   if (Constant *Op1 = dyn_cast<Constant>(I.getOperand(1))) {
+     if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
+ 
+       // ((X << C1)*C2) == (X * (C2 << C1))
+       if (ShiftInst *SI = dyn_cast<ShiftInst>(Op0))
+         if (SI->getOpcode() == Instruction::Shl)
+           if (Constant *ShOp = dyn_cast<Constant>(SI->getOperand(1)))
+             return BinaryOperator::createMul(SI->getOperand(0),
+                                              ConstantExpr::getShl(CI, ShOp));
+       
+       if (CI->isNullValue())
+         return ReplaceInstUsesWith(I, Op1);  // X * 0  == 0
+       if (CI->equalsInt(1))                  // X * 1  == X
+         return ReplaceInstUsesWith(I, Op0);
+       if (CI->isAllOnesValue())              // X * -1 == 0 - X
+         return BinaryOperator::createNeg(Op0, I.getName());
+ 
+       int64_t Val = (int64_t)cast<ConstantInt>(CI)->getRawValue();
+       if (uint64_t C = Log2(Val))            // Replace X*(2^C) with X << C
+         return new ShiftInst(Instruction::Shl, Op0,
+                              ConstantUInt::get(Type::UByteTy, C));
+     } else if (ConstantFP *Op1F = dyn_cast<ConstantFP>(Op1)) {
+       if (Op1F->isNullValue())
+         return ReplaceInstUsesWith(I, Op1);
+ 
+       // "In IEEE floating point, x*1 is not equivalent to x for nans.  However,
+       // ANSI says we can drop signals, so we can do this anyway." (from GCC)
+       if (Op1F->getValue() == 1.0)
+         return ReplaceInstUsesWith(I, Op0);  // Eliminate 'mul double %X, 1.0'
+     }
+ 
+     // Try to fold constant mul into select arguments.
+     if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
+       if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
+         return R;
+ 
+     if (isa<PHINode>(Op0))
+       if (Instruction *NV = FoldOpIntoPhi(I))
+         return NV;
+   }
+ 
+   if (Value *Op0v = dyn_castNegVal(Op0))     // -X * -Y = X*Y
+     if (Value *Op1v = dyn_castNegVal(I.getOperand(1)))
+       return BinaryOperator::createMul(Op0v, Op1v);
+ 
+   // If one of the operands of the multiply is a cast from a boolean value, then
+   // we know the bool is either zero or one, so this is a 'masking' multiply.
+   // See if we can simplify things based on how the boolean was originally
+   // formed.
+   CastInst *BoolCast = 0;
+   if (CastInst *CI = dyn_cast<CastInst>(I.getOperand(0)))
+     if (CI->getOperand(0)->getType() == Type::BoolTy)
+       BoolCast = CI;
+   if (!BoolCast)
+     if (CastInst *CI = dyn_cast<CastInst>(I.getOperand(1)))
+       if (CI->getOperand(0)->getType() == Type::BoolTy)
+         BoolCast = CI;
+   if (BoolCast) {
+     if (SetCondInst *SCI = dyn_cast<SetCondInst>(BoolCast->getOperand(0))) {
+       Value *SCIOp0 = SCI->getOperand(0), *SCIOp1 = SCI->getOperand(1);
+       const Type *SCOpTy = SCIOp0->getType();
+ 
+       // If the setcc is true iff the sign bit of X is set, then convert this
+       // multiply into a shift/and combination.
+       if (isa<ConstantInt>(SCIOp1) &&
+           isSignBitCheck(SCI->getOpcode(), SCIOp0, cast<ConstantInt>(SCIOp1))) {
+         // Shift the X value right to turn it into "all signbits".
+         Constant *Amt = ConstantUInt::get(Type::UByteTy,
+                                           SCOpTy->getPrimitiveSize()*8-1);
+         if (SCIOp0->getType()->isUnsigned()) {
+           const Type *NewTy = SCIOp0->getType()->getSignedVersion();
+           SCIOp0 = InsertNewInstBefore(new CastInst(SCIOp0, NewTy,
+                                                     SCIOp0->getName()), I);
+         }
+ 
+         Value *V =
+           InsertNewInstBefore(new ShiftInst(Instruction::Shr, SCIOp0, Amt,
+                                             BoolCast->getOperand(0)->getName()+
+                                             ".mask"), I);
+ 
+         // If the multiply type is not the same as the source type, sign extend
+         // or truncate to the multiply type.
+         if (I.getType() != V->getType())
+           V = InsertNewInstBefore(new CastInst(V, I.getType(), V->getName()),I);
+         
+         Value *OtherOp = Op0 == BoolCast ? I.getOperand(1) : Op0;
+         return BinaryOperator::createAnd(V, OtherOp);
+       }
+     }
+   }
+ 
+   return Changed ? &I : 0;
+ }
+ 
+ Instruction *InstCombiner::visitDiv(BinaryOperator &I) {
+   if (ConstantInt *RHS = dyn_cast<ConstantInt>(I.getOperand(1))) {
+     // div X, 1 == X
+     if (RHS->equalsInt(1))
+       return ReplaceInstUsesWith(I, I.getOperand(0));
+ 
+     // div X, -1 == -X
+     if (RHS->isAllOnesValue())
+       return BinaryOperator::createNeg(I.getOperand(0));
+ 
+     if (Instruction *LHS = dyn_cast<Instruction>(I.getOperand(0)))
+       if (LHS->getOpcode() == Instruction::Div)
+         if (ConstantInt *LHSRHS = dyn_cast<ConstantInt>(LHS->getOperand(1))) {
+           // (X / C1) / C2  -> X / (C1*C2)
+           return BinaryOperator::createDiv(LHS->getOperand(0),
+                                            ConstantExpr::getMul(RHS, LHSRHS));
+         }
+ 
+     // Check to see if this is an unsigned division with an exact power of 2,
+     // if so, convert to a right shift.
+     if (ConstantUInt *C = dyn_cast<ConstantUInt>(RHS))
+       if (uint64_t Val = C->getValue())    // Don't break X / 0
+         if (uint64_t C = Log2(Val))
+           return new ShiftInst(Instruction::Shr, I.getOperand(0),
+                                ConstantUInt::get(Type::UByteTy, C));
+ 
+     if (isa<PHINode>(I.getOperand(0)) && !RHS->isNullValue())
+       if (Instruction *NV = FoldOpIntoPhi(I))
+         return NV;
+   }
+ 
+   // 0 / X == 0, we don't need to preserve faults!
+   if (ConstantInt *LHS = dyn_cast<ConstantInt>(I.getOperand(0)))
+     if (LHS->equalsInt(0))
+       return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+ 
+   return 0;
+ }
+ 
+ 
+ Instruction *InstCombiner::visitRem(BinaryOperator &I) {
+   if (I.getType()->isSigned())
+     if (Value *RHSNeg = dyn_castNegVal(I.getOperand(1)))
+       if (!isa<ConstantSInt>(RHSNeg) ||
+           cast<ConstantSInt>(RHSNeg)->getValue() > 0) {
+         // X % -Y -> X % Y
+         AddUsesToWorkList(I);
+         I.setOperand(1, RHSNeg);
+         return &I;
+       }
+ 
+   if (ConstantInt *RHS = dyn_cast<ConstantInt>(I.getOperand(1))) {
+     if (RHS->equalsInt(1))  // X % 1 == 0
+       return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+ 
+     // Check to see if this is an unsigned remainder with an exact power of 2,
+     // if so, convert to a bitwise and.
+     if (ConstantUInt *C = dyn_cast<ConstantUInt>(RHS))
+       if (uint64_t Val = C->getValue())    // Don't break X % 0 (divide by zero)
+         if (!(Val & (Val-1)))              // Power of 2
+           return BinaryOperator::createAnd(I.getOperand(0),
+                                         ConstantUInt::get(I.getType(), Val-1));
+     if (isa<PHINode>(I.getOperand(0)) && !RHS->isNullValue())
+       if (Instruction *NV = FoldOpIntoPhi(I))
+         return NV;
+   }
+ 
+   // 0 % X == 0, we don't need to preserve faults!
+   if (ConstantInt *LHS = dyn_cast<ConstantInt>(I.getOperand(0)))
+     if (LHS->equalsInt(0))
+       return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+ 
+   return 0;
+ }
+ 
+ // isMaxValueMinusOne - return true if this is Max-1
+ static bool isMaxValueMinusOne(const ConstantInt *C) {
+   if (const ConstantUInt *CU = dyn_cast<ConstantUInt>(C)) {
+     // Calculate -1 casted to the right type...
+     unsigned TypeBits = C->getType()->getPrimitiveSize()*8;
+     uint64_t Val = ~0ULL;                // All ones
+     Val >>= 64-TypeBits;                 // Shift out unwanted 1 bits...
+     return CU->getValue() == Val-1;
+   }
+ 
+   const ConstantSInt *CS = cast<ConstantSInt>(C);
+   
+   // Calculate 0111111111..11111
+   unsigned TypeBits = C->getType()->getPrimitiveSize()*8;
+   int64_t Val = INT64_MAX;             // All ones
+   Val >>= 64-TypeBits;                 // Shift out unwanted 1 bits...
+   return CS->getValue() == Val-1;
+ }
+ 
+ // isMinValuePlusOne - return true if this is Min+1
+ static bool isMinValuePlusOne(const ConstantInt *C) {
+   if (const ConstantUInt *CU = dyn_cast<ConstantUInt>(C))
+     return CU->getValue() == 1;
+ 
+   const ConstantSInt *CS = cast<ConstantSInt>(C);
+   
+   // Calculate 1111111111000000000000 
+   unsigned TypeBits = C->getType()->getPrimitiveSize()*8;
+   int64_t Val = -1;                    // All ones
+   Val <<= TypeBits-1;                  // Shift over to the right spot
+   return CS->getValue() == Val+1;
+ }
+ 
+ // isOneBitSet - Return true if there is exactly one bit set in the specified
+ // constant.
+ static bool isOneBitSet(const ConstantInt *CI) {
+   uint64_t V = CI->getRawValue();
+   return V && (V & (V-1)) == 0;
+ }
+ 
+ #if 0   // Currently unused
+ // isLowOnes - Return true if the constant is of the form 0+1+.
+ static bool isLowOnes(const ConstantInt *CI) {
+   uint64_t V = CI->getRawValue();
+ 
+   // There won't be bits set in parts that the type doesn't contain.
+   V &= ConstantInt::getAllOnesValue(CI->getType())->getRawValue();
+ 
+   uint64_t U = V+1;  // If it is low ones, this should be a power of two.
+   return U && V && (U & V) == 0;
+ }
+ #endif
+ 
+ // isHighOnes - Return true if the constant is of the form 1+0+.
+ // This is the same as lowones(~X).
+ static bool isHighOnes(const ConstantInt *CI) {
+   uint64_t V = ~CI->getRawValue();
+ 
+   // There won't be bits set in parts that the type doesn't contain.
+   V &= ConstantInt::getAllOnesValue(CI->getType())->getRawValue();
+ 
+   uint64_t U = V+1;  // If it is low ones, this should be a power of two.
+   return U && V && (U & V) == 0;
+ }
+ 
+ 
+ /// getSetCondCode - Encode a setcc opcode into a three bit mask.  These bits
+ /// are carefully arranged to allow folding of expressions such as:
+ ///
+ ///      (A < B) | (A > B) --> (A != B)
+ ///
+ /// Bit value '4' represents that the comparison is true if A > B, bit value '2'
+ /// represents that the comparison is true if A == B, and bit value '1' is true
+ /// if A < B.
+ ///
+ static unsigned getSetCondCode(const SetCondInst *SCI) {
+   switch (SCI->getOpcode()) {
+     // False -> 0
+   case Instruction::SetGT: return 1;
+   case Instruction::SetEQ: return 2;
+   case Instruction::SetGE: return 3;
+   case Instruction::SetLT: return 4;
+   case Instruction::SetNE: return 5;
+   case Instruction::SetLE: return 6;
+     // True -> 7
+   default:
+     assert(0 && "Invalid SetCC opcode!");
+     return 0;
+   }
+ }
+ 
+ /// getSetCCValue - This is the complement of getSetCondCode, which turns an
+ /// opcode and two operands into either a constant true or false, or a brand new
+ /// SetCC instruction.
+ static Value *getSetCCValue(unsigned Opcode, Value *LHS, Value *RHS) {
+   switch (Opcode) {
+   case 0: return ConstantBool::False;
+   case 1: return new SetCondInst(Instruction::SetGT, LHS, RHS);
+   case 2: return new SetCondInst(Instruction::SetEQ, LHS, RHS);
+   case 3: return new SetCondInst(Instruction::SetGE, LHS, RHS);
+   case 4: return new SetCondInst(Instruction::SetLT, LHS, RHS);
+   case 5: return new SetCondInst(Instruction::SetNE, LHS, RHS);
+   case 6: return new SetCondInst(Instruction::SetLE, LHS, RHS);
+   case 7: return ConstantBool::True;
+   default: assert(0 && "Illegal SetCCCode!"); return 0;
+   }
+ }
+ 
+ // FoldSetCCLogical - Implements (setcc1 A, B) & (setcc2 A, B) --> (setcc3 A, B)
+ struct FoldSetCCLogical {
+   InstCombiner &IC;
+   Value *LHS, *RHS;
+   FoldSetCCLogical(InstCombiner &ic, SetCondInst *SCI)
+     : IC(ic), LHS(SCI->getOperand(0)), RHS(SCI->getOperand(1)) {}
+   bool shouldApply(Value *V) const {
+     if (SetCondInst *SCI = dyn_cast<SetCondInst>(V))
+       return (SCI->getOperand(0) == LHS && SCI->getOperand(1) == RHS ||
+               SCI->getOperand(0) == RHS && SCI->getOperand(1) == LHS);
+     return false;
+   }
+   Instruction *apply(BinaryOperator &Log) const {
+     SetCondInst *SCI = cast<SetCondInst>(Log.getOperand(0));
+     if (SCI->getOperand(0) != LHS) {
+       assert(SCI->getOperand(1) == LHS);
+       SCI->swapOperands();  // Swap the LHS and RHS of the SetCC
+     }
+ 
+     unsigned LHSCode = getSetCondCode(SCI);
+     unsigned RHSCode = getSetCondCode(cast<SetCondInst>(Log.getOperand(1)));
+     unsigned Code;
+     switch (Log.getOpcode()) {
+     case Instruction::And: Code = LHSCode & RHSCode; break;
+     case Instruction::Or:  Code = LHSCode | RHSCode; break;
+     case Instruction::Xor: Code = LHSCode ^ RHSCode; break;
+     default: assert(0 && "Illegal logical opcode!"); return 0;
+     }
+ 
+     Value *RV = getSetCCValue(Code, LHS, RHS);
+     if (Instruction *I = dyn_cast<Instruction>(RV))
+       return I;
+     // Otherwise, it's a constant boolean value...
+     return IC.ReplaceInstUsesWith(Log, RV);
+   }
+ };
+ 
+ 
+ // OptAndOp - This handles expressions of the form ((val OP C1) & C2).  Where
+ // the Op parameter is 'OP', OpRHS is 'C1', and AndRHS is 'C2'.  Op is
+ // guaranteed to be either a shift instruction or a binary operator.
+ Instruction *InstCombiner::OptAndOp(Instruction *Op,
+                                     ConstantIntegral *OpRHS,
+                                     ConstantIntegral *AndRHS,
+                                     BinaryOperator &TheAnd) {
+   Value *X = Op->getOperand(0);
+   Constant *Together = 0;
+   if (!isa<ShiftInst>(Op))
+     Together = ConstantExpr::getAnd(AndRHS, OpRHS);
+ 
+   switch (Op->getOpcode()) {
+   case Instruction::Xor:
+     if (Together->isNullValue()) {
+       // (X ^ C1) & C2 --> (X & C2) iff (C1&C2) == 0
+       return BinaryOperator::createAnd(X, AndRHS);
+     } else if (Op->hasOneUse()) {
+       // (X ^ C1) & C2 --> (X & C2) ^ (C1&C2)
+       std::string OpName = Op->getName(); Op->setName("");
+       Instruction *And = BinaryOperator::createAnd(X, AndRHS, OpName);
+       InsertNewInstBefore(And, TheAnd);
+       return BinaryOperator::createXor(And, Together);
+     }
+     break;
+   case Instruction::Or:
+     // (X | C1) & C2 --> X & C2 iff C1 & C1 == 0
+     if (Together->isNullValue())
+       return BinaryOperator::createAnd(X, AndRHS);
+     else {
+       if (Together == AndRHS) // (X | C) & C --> C
+         return ReplaceInstUsesWith(TheAnd, AndRHS);
+       
+       if (Op->hasOneUse() && Together != OpRHS) {
+         // (X | C1) & C2 --> (X | (C1&C2)) & C2
+         std::string Op0Name = Op->getName(); Op->setName("");
+         Instruction *Or = BinaryOperator::createOr(X, Together, Op0Name);
+         InsertNewInstBefore(Or, TheAnd);
+         return BinaryOperator::createAnd(Or, AndRHS);
+       }
+     }
+     break;
+   case Instruction::Add:
+     if (Op->hasOneUse()) {
+       // Adding a one to a single bit bit-field should be turned into an XOR
+       // of the bit.  First thing to check is to see if this AND is with a
+       // single bit constant.
+       uint64_t AndRHSV = cast<ConstantInt>(AndRHS)->getRawValue();
+ 
+       // Clear bits that are not part of the constant.
+       AndRHSV &= (1ULL << AndRHS->getType()->getPrimitiveSize()*8)-1;
+ 
+       // If there is only one bit set...
+       if (isOneBitSet(cast<ConstantInt>(AndRHS))) {
+         // Ok, at this point, we know that we are masking the result of the
+         // ADD down to exactly one bit.  If the constant we are adding has
+         // no bits set below this bit, then we can eliminate the ADD.
+         uint64_t AddRHS = cast<ConstantInt>(OpRHS)->getRawValue();
+             
+         // Check to see if any bits below the one bit set in AndRHSV are set.
+         if ((AddRHS & (AndRHSV-1)) == 0) {
+           // If not, the only thing that can effect the output of the AND is
+           // the bit specified by AndRHSV.  If that bit is set, the effect of
+           // the XOR is to toggle the bit.  If it is clear, then the ADD has
+           // no effect.
+           if ((AddRHS & AndRHSV) == 0) { // Bit is not set, noop
+             TheAnd.setOperand(0, X);
+             return &TheAnd;
+           } else {
+             std::string Name = Op->getName(); Op->setName("");
+             // Pull the XOR out of the AND.
+             Instruction *NewAnd = BinaryOperator::createAnd(X, AndRHS, Name);
+             InsertNewInstBefore(NewAnd, TheAnd);
+             return BinaryOperator::createXor(NewAnd, AndRHS);
+           }
+         }
+       }
+     }
+     break;
+ 
+   case Instruction::Shl: {
+     // We know that the AND will not produce any of the bits shifted in, so if
+     // the anded constant includes them, clear them now!
+     //
+     Constant *AllOne = ConstantIntegral::getAllOnesValue(AndRHS->getType());
+     Constant *ShlMask = ConstantExpr::getShl(AllOne, OpRHS);
+     Constant *CI = ConstantExpr::getAnd(AndRHS, ShlMask);
+                                         
+     if (CI == ShlMask) {   // Masking out bits that the shift already masks
+       return ReplaceInstUsesWith(TheAnd, Op);   // No need for the and.
+     } else if (CI != AndRHS) {                  // Reducing bits set in and.
+       TheAnd.setOperand(1, CI);
+       return &TheAnd;
+     }
+     break;
+   } 
+   case Instruction::Shr:
+     // We know that the AND will not produce any of the bits shifted in, so if
+     // the anded constant includes them, clear them now!  This only applies to
+     // unsigned shifts, because a signed shr may bring in set bits!
+     //
+     if (AndRHS->getType()->isUnsigned()) {
+       Constant *AllOne = ConstantIntegral::getAllOnesValue(AndRHS->getType());
+       Constant *ShrMask = ConstantExpr::getShr(AllOne, OpRHS);
+       Constant *CI = ConstantExpr::getAnd(AndRHS, ShrMask);
+ 
+       if (CI == ShrMask) {   // Masking out bits that the shift already masks.
+         return ReplaceInstUsesWith(TheAnd, Op);
+       } else if (CI != AndRHS) {
+         TheAnd.setOperand(1, CI);  // Reduce bits set in and cst.
+         return &TheAnd;
+       }
+     } else {   // Signed shr.
+       // See if this is shifting in some sign extension, then masking it out
+       // with an and.
+       if (Op->hasOneUse()) {
+         Constant *AllOne = ConstantIntegral::getAllOnesValue(AndRHS->getType());
+         Constant *ShrMask = ConstantExpr::getUShr(AllOne, OpRHS);
+         Constant *CI = ConstantExpr::getAnd(AndRHS, ShrMask);
+         if (CI == ShrMask) {          // Masking out bits shifted in.
+           // Make the argument unsigned.
+           Value *ShVal = Op->getOperand(0);
+           ShVal = InsertCastBefore(ShVal,
+                                    ShVal->getType()->getUnsignedVersion(),
+                                    TheAnd);
+           ShVal = InsertNewInstBefore(new ShiftInst(Instruction::Shr, ShVal,
+                                                     OpRHS, Op->getName()),
+                                       TheAnd);
+           return new CastInst(ShVal, Op->getType());
+         }
+       }
+     }
+     break;
+   }
+   return 0;
+ }
+ 
+ 
+ /// InsertRangeTest - Emit a computation of: (V >= Lo && V < Hi) if Inside is
+ /// true, otherwise (V < Lo || V >= Hi).  In pratice, we emit the more efficient
+ /// (V-Lo) <u Hi-Lo.  This method expects that Lo <= Hi.  IB is the location to
+ /// insert new instructions.
+ Instruction *InstCombiner::InsertRangeTest(Value *V, Constant *Lo, Constant *Hi,
+                                            bool Inside, Instruction &IB) {
+   assert(cast<ConstantBool>(ConstantExpr::getSetLE(Lo, Hi))->getValue() &&
+          "Lo is not <= Hi in range emission code!");
+   if (Inside) {
+     if (Lo == Hi)  // Trivially false.
+       return new SetCondInst(Instruction::SetNE, V, V);
+     if (cast<ConstantIntegral>(Lo)->isMinValue())
+       return new SetCondInst(Instruction::SetLT, V, Hi);
+     
+     Constant *AddCST = ConstantExpr::getNeg(Lo);
+     Instruction *Add = BinaryOperator::createAdd(V, AddCST,V->getName()+".off");
+     InsertNewInstBefore(Add, IB);
+     // Convert to unsigned for the comparison.
+     const Type *UnsType = Add->getType()->getUnsignedVersion();
+     Value *OffsetVal = InsertCastBefore(Add, UnsType, IB);
+     AddCST = ConstantExpr::getAdd(AddCST, Hi);
+     AddCST = ConstantExpr::getCast(AddCST, UnsType);
+     return new SetCondInst(Instruction::SetLT, OffsetVal, AddCST);
+   }
+ 
+   if (Lo == Hi)  // Trivially true.
+     return new SetCondInst(Instruction::SetEQ, V, V);
+ 
+   Hi = SubOne(cast<ConstantInt>(Hi));
+   if (cast<ConstantIntegral>(Lo)->isMinValue()) // V < 0 || V >= Hi ->'V > Hi-1'
+     return new SetCondInst(Instruction::SetGT, V, Hi);
+ 
+   // Emit X-Lo > Hi-Lo-1
+   Constant *AddCST = ConstantExpr::getNeg(Lo);
+   Instruction *Add = BinaryOperator::createAdd(V, AddCST, V->getName()+".off");
+   InsertNewInstBefore(Add, IB);
+   // Convert to unsigned for the comparison.
+   const Type *UnsType = Add->getType()->getUnsignedVersion();
+   Value *OffsetVal = InsertCastBefore(Add, UnsType, IB);
+   AddCST = ConstantExpr::getAdd(AddCST, Hi);
+   AddCST = ConstantExpr::getCast(AddCST, UnsType);
+   return new SetCondInst(Instruction::SetGT, OffsetVal, AddCST);
+ }
+ 
+ 
+ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
+   bool Changed = SimplifyCommutative(I);
+   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+ 
+   // and X, X = X   and X, 0 == 0
+   if (Op0 == Op1 || Op1 == Constant::getNullValue(I.getType()))
+     return ReplaceInstUsesWith(I, Op1);
+ 
+   // and X, -1 == X
+   if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1)) {
+     if (RHS->isAllOnesValue())
+       return ReplaceInstUsesWith(I, Op0);
+ 
+     // Optimize a variety of ((val OP C1) & C2) combinations...
+     if (isa<BinaryOperator>(Op0) || isa<ShiftInst>(Op0)) {
+       Instruction *Op0I = cast<Instruction>(Op0);
+       Value *X = Op0I->getOperand(0);
+       if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1)))
+         if (Instruction *Res = OptAndOp(Op0I, Op0CI, RHS, I))
+           return Res;
+     }
+ 
+     // Try to fold constant and into select arguments.
+     if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
+       if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
+         return R;
+     if (isa<PHINode>(Op0))
+       if (Instruction *NV = FoldOpIntoPhi(I))
+         return NV;
+   }
+ 
+   Value *Op0NotVal = dyn_castNotVal(Op0);
+   Value *Op1NotVal = dyn_castNotVal(Op1);
+ 
+   if (Op0NotVal == Op1 || Op1NotVal == Op0)  // A & ~A  == ~A & A == 0
+     return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+ 
+   // (~A & ~B) == (~(A | B)) - De Morgan's Law
+   if (Op0NotVal && Op1NotVal && isOnlyUse(Op0) && isOnlyUse(Op1)) {
+     Instruction *Or = BinaryOperator::createOr(Op0NotVal, Op1NotVal,
+                                                I.getName()+".demorgan");
+     InsertNewInstBefore(Or, I);
+     return BinaryOperator::createNot(Or);
+   }
+ 
+   if (SetCondInst *RHS = dyn_cast<SetCondInst>(Op1)) {
+     // (setcc1 A, B) & (setcc2 A, B) --> (setcc3 A, B)
+     if (Instruction *R = AssociativeOpt(I, FoldSetCCLogical(*this, RHS)))
+       return R;
+ 
+     Value *LHSVal, *RHSVal;
+     ConstantInt *LHSCst, *RHSCst;
+     Instruction::BinaryOps LHSCC, RHSCC;
+     if (match(Op0, m_SetCond(LHSCC, m_Value(LHSVal), m_ConstantInt(LHSCst))))
+       if (match(RHS, m_SetCond(RHSCC, m_Value(RHSVal), m_ConstantInt(RHSCst))))
+         if (LHSVal == RHSVal &&    // Found (X setcc C1) & (X setcc C2)
+             // Set[GL]E X, CST is folded to Set[GL]T elsewhere.
+             LHSCC != Instruction::SetGE && LHSCC != Instruction::SetLE && 
+             RHSCC != Instruction::SetGE && RHSCC != Instruction::SetLE) {
+           // Ensure that the larger constant is on the RHS.
+           Constant *Cmp = ConstantExpr::getSetGT(LHSCst, RHSCst);
+           SetCondInst *LHS = cast<SetCondInst>(Op0);
+           if (cast<ConstantBool>(Cmp)->getValue()) {
+             std::swap(LHS, RHS);
+             std::swap(LHSCst, RHSCst);
+             std::swap(LHSCC, RHSCC);
+           }
+ 
+           // At this point, we know we have have two setcc instructions
+           // comparing a value against two constants and and'ing the result
+           // together.  Because of the above check, we know that we only have
+           // SetEQ, SetNE, SetLT, and SetGT here.  We also know (from the
+           // FoldSetCCLogical check above), that the two constants are not
+           // equal.
+           assert(LHSCst != RHSCst && "Compares not folded above?");
+ 
+           switch (LHSCC) {
+           default: assert(0 && "Unknown integer condition code!");
+           case Instruction::SetEQ:
+             switch (RHSCC) {
+             default: assert(0 && "Unknown integer condition code!");
+             case Instruction::SetEQ:  // (X == 13 & X == 15) -> false
+             case Instruction::SetGT:  // (X == 13 & X > 15)  -> false
+               return ReplaceInstUsesWith(I, ConstantBool::False);
+             case Instruction::SetNE:  // (X == 13 & X != 15) -> X == 13
+             case Instruction::SetLT:  // (X == 13 & X < 15)  -> X == 13
+               return ReplaceInstUsesWith(I, LHS);
+             }
+           case Instruction::SetNE:
+             switch (RHSCC) {
+             default: assert(0 && "Unknown integer condition code!");
+             case Instruction::SetLT:
+               if (LHSCst == SubOne(RHSCst)) // (X != 13 & X < 14) -> X < 13
+                 return new SetCondInst(Instruction::SetLT, LHSVal, LHSCst);
+               break;                        // (X != 13 & X < 15) -> no change
+             case Instruction::SetEQ:        // (X != 13 & X == 15) -> X == 15
+             case Instruction::SetGT:        // (X != 13 & X > 15)  -> X > 15
+               return ReplaceInstUsesWith(I, RHS);
+             case Instruction::SetNE:
+               if (LHSCst == SubOne(RHSCst)) {// (X != 13 & X != 14) -> X-13 >u 1
+                 Constant *AddCST = ConstantExpr::getNeg(LHSCst);
+                 Instruction *Add = BinaryOperator::createAdd(LHSVal, AddCST,
+                                                       LHSVal->getName()+".off");
+                 InsertNewInstBefore(Add, I);
+                 const Type *UnsType = Add->getType()->getUnsignedVersion();
+                 Value *OffsetVal = InsertCastBefore(Add, UnsType, I);
+                 AddCST = ConstantExpr::getSub(RHSCst, LHSCst);
+                 AddCST = ConstantExpr::getCast(AddCST, UnsType);
+                 return new SetCondInst(Instruction::SetGT, OffsetVal, AddCST);
+               }
+               break;                        // (X != 13 & X != 15) -> no change
+             }
+             break;
+           case Instruction::SetLT:
+             switch (RHSCC) {
+             default: assert(0 && "Unknown integer condition code!");
+             case Instruction::SetEQ:  // (X < 13 & X == 15) -> false
+             case Instruction::SetGT:  // (X < 13 & X > 15)  -> false
+               return ReplaceInstUsesWith(I, ConstantBool::False);
+             case Instruction::SetNE:  // (X < 13 & X != 15) -> X < 13
+             case Instruction::SetLT:  // (X < 13 & X < 15) -> X < 13
+               return ReplaceInstUsesWith(I, LHS);
+             }
+           case Instruction::SetGT:
+             switch (RHSCC) {
+             default: assert(0 && "Unknown integer condition code!");
+             case Instruction::SetEQ:  // (X > 13 & X == 15) -> X > 13
+               return ReplaceInstUsesWith(I, LHS);
+             case Instruction::SetGT:  // (X > 13 & X > 15)  -> X > 15
+               return ReplaceInstUsesWith(I, RHS);
+             case Instruction::SetNE:
+               if (RHSCst == AddOne(LHSCst)) // (X > 13 & X != 14) -> X > 14
+                 return new SetCondInst(Instruction::SetGT, LHSVal, RHSCst);
+               break;                        // (X > 13 & X != 15) -> no change
+             case Instruction::SetLT:   // (X > 13 & X < 15) -> (X-14) <u 1
+               return InsertRangeTest(LHSVal, AddOne(LHSCst), RHSCst, true, I);
+             }
+           }
+         }
+   }
+ 
+   return Changed ? &I : 0;
+ }
+ 
+ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
+   bool Changed = SimplifyCommutative(I);
+   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+ 
+   // or X, X = X   or X, 0 == X
+   if (Op0 == Op1 || Op1 == Constant::getNullValue(I.getType()))
+     return ReplaceInstUsesWith(I, Op0);
+ 
+   // or X, -1 == -1
+   if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1)) {
+     if (RHS->isAllOnesValue())
+       return ReplaceInstUsesWith(I, Op1);
+ 
+     ConstantInt *C1; Value *X;
+     // (X & C1) | C2 --> (X | C2) & (C1|C2)
+     if (match(Op0, m_And(m_Value(X), m_ConstantInt(C1))) && isOnlyUse(Op0)) {
+       std::string Op0Name = Op0->getName(); Op0->setName("");
+       Instruction *Or = BinaryOperator::createOr(X, RHS, Op0Name);
+       InsertNewInstBefore(Or, I);
+       return BinaryOperator::createAnd(Or, ConstantExpr::getOr(RHS, C1));
+     }
+ 
+     // (X ^ C1) | C2 --> (X | C2) ^ (C1&~C2)
+     if (match(Op0, m_Xor(m_Value(X), m_ConstantInt(C1))) && isOnlyUse(Op0)) {
+       std::string Op0Name = Op0->getName(); Op0->setName("");
+       Instruction *Or = BinaryOperator::createOr(X, RHS, Op0Name);
+       InsertNewInstBefore(Or, I);
+       return BinaryOperator::createXor(Or,
+                  ConstantExpr::getAnd(C1, ConstantExpr::getNot(RHS)));
+     }
+ 
+     // Try to fold constant and into select arguments.
+     if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
+       if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
+         return R;
+     if (isa<PHINode>(Op0))
+       if (Instruction *NV = FoldOpIntoPhi(I))
+         return NV;
+   }
+ 
+   // (A & C1)|(A & C2) == A & (C1|C2)
+   Value *A, *B; ConstantInt *C1, *C2;
+   if (match(Op0, m_And(m_Value(A), m_ConstantInt(C1))) &&
+       match(Op1, m_And(m_Value(B), m_ConstantInt(C2))) && A == B)
+     return BinaryOperator::createAnd(A, ConstantExpr::getOr(C1, C2));
+ 
+   if (match(Op0, m_Not(m_Value(A)))) {   // ~A | Op1
+     if (A == Op1)   // ~A | A == -1
+       return ReplaceInstUsesWith(I, 
+                                 ConstantIntegral::getAllOnesValue(I.getType()));
+   } else {
+     A = 0;
+   }
+ 
+   if (match(Op1, m_Not(m_Value(B)))) {   // Op0 | ~B
+     if (Op0 == B)
+       return ReplaceInstUsesWith(I, 
+                                 ConstantIntegral::getAllOnesValue(I.getType()));
+ 
+     // (~A | ~B) == (~(A & B)) - De Morgan's Law
+     if (A && isOnlyUse(Op0) && isOnlyUse(Op1)) {
+       Value *And = InsertNewInstBefore(BinaryOperator::createAnd(A, B,
+                                               I.getName()+".demorgan"), I);
+       return BinaryOperator::createNot(And);
+     }
+   }
+ 
+   // (setcc1 A, B) | (setcc2 A, B) --> (setcc3 A, B)
+   if (SetCondInst *RHS = dyn_cast<SetCondInst>(I.getOperand(1))) {
+     if (Instruction *R = AssociativeOpt(I, FoldSetCCLogical(*this, RHS)))
+       return R;
+ 
+     Value *LHSVal, *RHSVal;
+     ConstantInt *LHSCst, *RHSCst;
+     Instruction::BinaryOps LHSCC, RHSCC;
+     if (match(Op0, m_SetCond(LHSCC, m_Value(LHSVal), m_ConstantInt(LHSCst))))
+       if (match(RHS, m_SetCond(RHSCC, m_Value(RHSVal), m_ConstantInt(RHSCst))))
+         if (LHSVal == RHSVal &&    // Found (X setcc C1) | (X setcc C2)
+             // Set[GL]E X, CST is folded to Set[GL]T elsewhere.
+             LHSCC != Instruction::SetGE && LHSCC != Instruction::SetLE && 
+             RHSCC != Instruction::SetGE && RHSCC != Instruction::SetLE) {
+           // Ensure that the larger constant is on the RHS.
+           Constant *Cmp = ConstantExpr::getSetGT(LHSCst, RHSCst);
+           SetCondInst *LHS = cast<SetCondInst>(Op0);
+           if (cast<ConstantBool>(Cmp)->getValue()) {
+             std::swap(LHS, RHS);
+             std::swap(LHSCst, RHSCst);
+             std::swap(LHSCC, RHSCC);
+           }
+ 
+           // At this point, we know we have have two setcc instructions
+           // comparing a value against two constants and or'ing the result
+           // together.  Because of the above check, we know that we only have
+           // SetEQ, SetNE, SetLT, and SetGT here.  We also know (from the
+           // FoldSetCCLogical check above), that the two constants are not
+           // equal.
+           assert(LHSCst != RHSCst && "Compares not folded above?");
+ 
+           switch (LHSCC) {
+           default: assert(0 && "Unknown integer condition code!");
+           case Instruction::SetEQ:
+             switch (RHSCC) {
+             default: assert(0 && "Unknown integer condition code!");
+             case Instruction::SetEQ:
+               if (LHSCst == SubOne(RHSCst)) {// (X == 13 | X == 14) -> X-13 <u 2
+                 Constant *AddCST = ConstantExpr::getNeg(LHSCst);
+                 Instruction *Add = BinaryOperator::createAdd(LHSVal, AddCST,
+                                                       LHSVal->getName()+".off");
+                 InsertNewInstBefore(Add, I);
+                 const Type *UnsType = Add->getType()->getUnsignedVersion();
+                 Value *OffsetVal = InsertCastBefore(Add, UnsType, I);
+                 AddCST = ConstantExpr::getSub(AddOne(RHSCst), LHSCst);
+                 AddCST = ConstantExpr::getCast(AddCST, UnsType);
+                 return new SetCondInst(Instruction::SetLT, OffsetVal, AddCST);
+               }
+               break;                  // (X == 13 | X == 15) -> no change
+ 
+             case Instruction::SetGT:
+               if (LHSCst == SubOne(RHSCst)) // (X == 13 | X > 14) -> X > 13
+                 return new SetCondInst(Instruction::SetGT, LHSVal, LHSCst);
+               break;                        // (X == 13 | X > 15) -> no change
+             case Instruction::SetNE:  // (X == 13 | X != 15) -> X != 15
+             case Instruction::SetLT:  // (X == 13 | X < 15)  -> X < 15
+               return ReplaceInstUsesWith(I, RHS);
+             }
+             break;
+           case Instruction::SetNE:
+             switch (RHSCC) {
+             default: assert(0 && "Unknown integer condition code!");
+             case Instruction::SetLT:        // (X != 13 | X < 15) -> X < 15
+               return ReplaceInstUsesWith(I, RHS);
+             case Instruction::SetEQ:        // (X != 13 | X == 15) -> X != 13
+             case Instruction::SetGT:        // (X != 13 | X > 15)  -> X != 13
+               return ReplaceInstUsesWith(I, LHS);
+             case Instruction::SetNE:        // (X != 13 | X != 15) -> true
+               return ReplaceInstUsesWith(I, ConstantBool::True);
+             }
+             break;
+           case Instruction::SetLT:
+             switch (RHSCC) {
+             default: assert(0 && "Unknown integer condition code!");
+             case Instruction::SetEQ:  // (X < 13 | X == 14) -> no change
+               break;
+             case Instruction::SetGT:  // (X < 13 | X > 15)  -> (X-13) > 2
+               return InsertRangeTest(LHSVal, LHSCst, AddOne(RHSCst), false, I);
+             case Instruction::SetNE:  // (X < 13 | X != 15) -> X != 15
+             case Instruction::SetLT:  // (X < 13 | X < 15) -> X < 15
+               return ReplaceInstUsesWith(I, RHS);
+             }
+             break;
+           case Instruction::SetGT:
+             switch (RHSCC) {
+             default: assert(0 && "Unknown integer condition code!");
+             case Instruction::SetEQ:  // (X > 13 | X == 15) -> X > 13
+             case Instruction::SetGT:  // (X > 13 | X > 15)  -> X > 13
+               return ReplaceInstUsesWith(I, LHS);
+             case Instruction::SetNE:  // (X > 13 | X != 15)  -> true
+             case Instruction::SetLT:  // (X > 13 | X < 15) -> true
+               return ReplaceInstUsesWith(I, ConstantBool::True);
+             }
+           }
+         }
+   }
+   return Changed ? &I : 0;
+ }
+ 
+ // XorSelf - Implements: X ^ X --> 0
+ struct XorSelf {
+   Value *RHS;
+   XorSelf(Value *rhs) : RHS(rhs) {}
+   bool shouldApply(Value *LHS) const { return LHS == RHS; }
+   Instruction *apply(BinaryOperator &Xor) const {
+     return &Xor;
+   }
+ };
+ 
+ 
+ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
+   bool Changed = SimplifyCommutative(I);
+   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+ 
+   // xor X, X = 0, even if X is nested in a sequence of Xor's.
+   if (Instruction *Result = AssociativeOpt(I, XorSelf(Op1))) {
+     assert(Result == &I && "AssociativeOpt didn't work?");
+     return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
+   }
+ 
+   if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1)) {
+     // xor X, 0 == X
+     if (RHS->isNullValue())
+       return ReplaceInstUsesWith(I, Op0);
+ 
+     if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) {
+       // xor (setcc A, B), true = not (setcc A, B) = setncc A, B
+       if (SetCondInst *SCI = dyn_cast<SetCondInst>(Op0I))
+         if (RHS == ConstantBool::True && SCI->hasOneUse())
+           return new SetCondInst(SCI->getInverseCondition(),
+                                  SCI->getOperand(0), SCI->getOperand(1));
+ 
+       // ~(c-X) == X-c-1 == X+(-c-1)
+       if (Op0I->getOpcode() == Instruction::Sub && RHS->isAllOnesValue())
+         if (Constant *Op0I0C = dyn_cast<Constant>(Op0I->getOperand(0))) {
+           Constant *NegOp0I0C = ConstantExpr::getNeg(Op0I0C);
+           Constant *ConstantRHS = ConstantExpr::getSub(NegOp0I0C,
+                                               ConstantInt::get(I.getType(), 1));
+           return BinaryOperator::createAdd(Op0I->getOperand(1), ConstantRHS);
+         }
+ 
+       // ~(~X & Y) --> (X | ~Y)
+       if (Op0I->getOpcode() == Instruction::And && RHS->isAllOnesValue()) {
+         if (dyn_castNotVal(Op0I->getOperand(1))) Op0I->swapOperands();
+         if (Value *Op0NotVal = dyn_castNotVal(Op0I->getOperand(0))) {
+           Instruction *NotY =
+             BinaryOperator::createNot(Op0I->getOperand(1), 
+                                       Op0I->getOperand(1)->getName()+".not");
+           InsertNewInstBefore(NotY, I);
+           return BinaryOperator::createOr(Op0NotVal, NotY);
+         }
+       }
+           
+       if (ConstantInt *Op0CI = dyn_cast<ConstantInt>(Op0I->getOperand(1)))
+         switch (Op0I->getOpcode()) {
+         case Instruction::Add:
+           // ~(X-c) --> (-c-1)-X
+           if (RHS->isAllOnesValue()) {
+             Constant *NegOp0CI = ConstantExpr::getNeg(Op0CI);
+             return BinaryOperator::createSub(
+                            ConstantExpr::getSub(NegOp0CI,
+                                              ConstantInt::get(I.getType(), 1)),
+                                           Op0I->getOperand(0));
+           }
+           break;
+         case Instruction::And:
+           // (X & C1) ^ C2 --> (X & C1) | C2 iff (C1&C2) == 0
+           if (ConstantExpr::getAnd(RHS, Op0CI)->isNullValue())
+             return BinaryOperator::createOr(Op0, RHS);
+           break;
+         case Instruction::Or:
+           // (X | C1) ^ C2 --> (X | C1) & ~C2 iff (C1&C2) == C2
+           if (ConstantExpr::getAnd(RHS, Op0CI) == RHS)
+             return BinaryOperator::createAnd(Op0, ConstantExpr::getNot(RHS));
+           break;
+         default: break;
+         }
+     }
+ 
+     // Try to fold constant and into select arguments.
+     if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
+       if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
+         return R;
+     if (isa<PHINode>(Op0))
+       if (Instruction *NV = FoldOpIntoPhi(I))
+         return NV;
+   }
+ 
+   if (Value *X = dyn_castNotVal(Op0))   // ~A ^ A == -1
+     if (X == Op1)
+       return ReplaceInstUsesWith(I,
+                                 ConstantIntegral::getAllOnesValue(I.getType()));
+ 
+   if (Value *X = dyn_castNotVal(Op1))   // A ^ ~A == -1
+     if (X == Op0)
+       return ReplaceInstUsesWith(I,
+                                 ConstantIntegral::getAllOnesValue(I.getType()));
+ 
+   if (Instruction *Op1I = dyn_cast<Instruction>(Op1))
+     if (Op1I->getOpcode() == Instruction::Or) {
+       if (Op1I->getOperand(0) == Op0) {              // B^(B|A) == (A|B)^B
+         cast<BinaryOperator>(Op1I)->swapOperands();
+         I.swapOperands();
+         std::swap(Op0, Op1);
+       } else if (Op1I->getOperand(1) == Op0) {       // B^(A|B) == (A|B)^B
+         I.swapOperands();
+         std::swap(Op0, Op1);
+       }      
+     } else if (Op1I->getOpcode() == Instruction::Xor) {
+       if (Op0 == Op1I->getOperand(0))                        // A^(A^B) == B
+         return ReplaceInstUsesWith(I, Op1I->getOperand(1));
+       else if (Op0 == Op1I->getOperand(1))                   // A^(B^A) == B
+         return ReplaceInstUsesWith(I, Op1I->getOperand(0));
+     }
+ 
+   if (Instruction *Op0I = dyn_cast<Instruction>(Op0))
+     if (Op0I->getOpcode() == Instruction::Or && Op0I->hasOneUse()) {
+       if (Op0I->getOperand(0) == Op1)                // (B|A)^B == (A|B)^B
+         cast<BinaryOperator>(Op0I)->swapOperands();
+       if (Op0I->getOperand(1) == Op1) {              // (A|B)^B == A & ~B
+         Value *NotB = InsertNewInstBefore(BinaryOperator::createNot(Op1,
+                                                      Op1->getName()+".not"), I);
+         return BinaryOperator::createAnd(Op0I->getOperand(0), NotB);
+       }
+     } else if (Op0I->getOpcode() == Instruction::Xor) {
+       if (Op1 == Op0I->getOperand(0))                        // (A^B)^A == B
+         return ReplaceInstUsesWith(I, Op0I->getOperand(1));
+       else if (Op1 == Op0I->getOperand(1))                   // (B^A)^A == B
+         return ReplaceInstUsesWith(I, Op0I->getOperand(0));
+     }
+ 
+   // (A & C1)^(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0
+   Value *A, *B; ConstantInt *C1, *C2;
+   if (match(Op0, m_And(m_Value(A), m_ConstantInt(C1))) &&
+       match(Op1, m_And(m_Value(B), m_ConstantInt(C2))) &&
+       ConstantExpr::getAnd(C1, C2)->isNullValue())
+     return BinaryOperator::createOr(Op0, Op1);
+ 
+   // (setcc1 A, B) ^ (setcc2 A, B) --> (setcc3 A, B)
+   if (SetCondInst *RHS = dyn_cast<SetCondInst>(I.getOperand(1)))
+     if (Instruction *R = AssociativeOpt(I, FoldSetCCLogical(*this, RHS)))
+       return R;
+ 
+   return Changed ? &I : 0;
+ }
+ 
+ /// MulWithOverflow - Compute Result = In1*In2, returning true if the result
+ /// overflowed for this type.
+ static bool MulWithOverflow(ConstantInt *&Result, ConstantInt *In1,
+                             ConstantInt *In2) {
+   Result = cast<ConstantInt>(ConstantExpr::getMul(In1, In2));
+   return !In2->isNullValue() && ConstantExpr::getDiv(Result, In2) != In1;
+ }
+ 
+ static bool isPositive(ConstantInt *C) {
+   return cast<ConstantSInt>(C)->getValue() >= 0;
+ }
+ 
+ /// AddWithOverflow - Compute Result = In1+In2, returning true if the result
+ /// overflowed for this type.
+ static bool AddWithOverflow(ConstantInt *&Result, ConstantInt *In1,
+                             ConstantInt *In2) {
+   Result = cast<ConstantInt>(ConstantExpr::getAdd(In1, In2));
+ 
+   if (In1->getType()->isUnsigned())
+     return cast<ConstantUInt>(Result)->getValue() <
+            cast<ConstantUInt>(In1)->getValue();
+   if (isPositive(In1) != isPositive(In2))
+     return false;
+   if (isPositive(In1))
+     return cast<ConstantSInt>(Result)->getValue() <
+            cast<ConstantSInt>(In1)->getValue();
+   return cast<ConstantSInt>(Result)->getValue() >
+          cast<ConstantSInt>(In1)->getValue();
+ }
+ 
+ Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) {
+   bool Changed = SimplifyCommutative(I);
+   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+   const Type *Ty = Op0->getType();
+ 
+   // setcc X, X
+   if (Op0 == Op1)
+     return ReplaceInstUsesWith(I, ConstantBool::get(isTrueWhenEqual(I)));
+ 
+   // setcc <global/alloca*>, 0 - Global/Stack value addresses are never null!
+   if (isa<ConstantPointerNull>(Op1) && 
+       (isa<GlobalValue>(Op0) || isa<AllocaInst>(Op0)))
+     return ReplaceInstUsesWith(I, ConstantBool::get(!isTrueWhenEqual(I)));
+ 
+ 
+   // setcc's with boolean values can always be turned into bitwise operations
+   if (Ty == Type::BoolTy) {
+     switch (I.getOpcode()) {
+     default: assert(0 && "Invalid setcc instruction!");
+     case Instruction::SetEQ: {     //  seteq bool %A, %B -> ~(A^B)
+       Instruction *Xor = BinaryOperator::createXor(Op0, Op1, I.getName()+"tmp");
+       InsertNewInstBefore(Xor, I);
+       return BinaryOperator::createNot(Xor);
+     }
+     case Instruction::SetNE:
+       return BinaryOperator::createXor(Op0, Op1);
+ 
+     case Instruction::SetGT:
+       std::swap(Op0, Op1);                   // Change setgt -> setlt
+       // FALL THROUGH
+     case Instruction::SetLT: {               // setlt bool A, B -> ~X & Y
+       Instruction *Not = BinaryOperator::createNot(Op0, I.getName()+"tmp");
+       InsertNewInstBefore(Not, I);
+       return BinaryOperator::createAnd(Not, Op1);
+     }
+     case Instruction::SetGE:
+       std::swap(Op0, Op1);                   // Change setge -> setle
+       // FALL THROUGH
+     case Instruction::SetLE: {     //  setle bool %A, %B -> ~A | B
+       Instruction *Not = BinaryOperator::createNot(Op0, I.getName()+"tmp");
+       InsertNewInstBefore(Not, I);
+       return BinaryOperator::createOr(Not, Op1);
+     }
+     }
+   }
+ 
+   // See if we are doing a comparison between a constant and an instruction that
+   // can be folded into the comparison.
+   if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
+     // Check to see if we are comparing against the minimum or maximum value...
+     if (CI->isMinValue()) {
+       if (I.getOpcode() == Instruction::SetLT)       // A < MIN -> FALSE
+         return ReplaceInstUsesWith(I, ConstantBool::False);
+       if (I.getOpcode() == Instruction::SetGE)       // A >= MIN -> TRUE
+         return ReplaceInstUsesWith(I, ConstantBool::True);
+       if (I.getOpcode() == Instruction::SetLE)       // A <= MIN -> A == MIN
+         return BinaryOperator::createSetEQ(Op0, Op1);
+       if (I.getOpcode() == Instruction::SetGT)       // A > MIN -> A != MIN
+         return BinaryOperator::createSetNE(Op0, Op1);
+ 
+     } else if (CI->isMaxValue()) {
+       if (I.getOpcode() == Instruction::SetGT)       // A > MAX -> FALSE
+         return ReplaceInstUsesWith(I, ConstantBool::False);
+       if (I.getOpcode() == Instruction::SetLE)       // A <= MAX -> TRUE
+         return ReplaceInstUsesWith(I, ConstantBool::True);
+       if (I.getOpcode() == Instruction::SetGE)       // A >= MAX -> A == MAX
+         return BinaryOperator::createSetEQ(Op0, Op1);
+       if (I.getOpcode() == Instruction::SetLT)       // A < MAX -> A != MAX
+         return BinaryOperator::createSetNE(Op0, Op1);
+ 
+       // Comparing against a value really close to min or max?
+     } else if (isMinValuePlusOne(CI)) {
+       if (I.getOpcode() == Instruction::SetLT)       // A < MIN+1 -> A == MIN
+         return BinaryOperator::createSetEQ(Op0, SubOne(CI));
+       if (I.getOpcode() == Instruction::SetGE)       // A >= MIN-1 -> A != MIN
+         return BinaryOperator::createSetNE(Op0, SubOne(CI));
+ 
+     } else if (isMaxValueMinusOne(CI)) {
+       if (I.getOpcode() == Instruction::SetGT)       // A > MAX-1 -> A == MAX
+         return BinaryOperator::createSetEQ(Op0, AddOne(CI));
+       if (I.getOpcode() == Instruction::SetLE)       // A <= MAX-1 -> A != MAX
+         return BinaryOperator::createSetNE(Op0, AddOne(CI));
+     }
+ 
+     // If we still have a setle or setge instruction, turn it into the
+     // appropriate setlt or setgt instruction.  Since the border cases have
+     // already been handled above, this requires little checking.
+     //
+     if (I.getOpcode() == Instruction::SetLE)
+       return BinaryOperator::createSetLT(Op0, AddOne(CI));
+     if (I.getOpcode() == Instruction::SetGE)
+       return BinaryOperator::createSetGT(Op0, SubOne(CI));
+ 
+     if (Instruction *LHSI = dyn_cast<Instruction>(Op0))
+       switch (LHSI->getOpcode()) {
+       case Instruction::PHI:
+         if (Instruction *NV = FoldOpIntoPhi(I))
+           return NV;
+         break;
+       case Instruction::And:
+         if (LHSI->hasOneUse() && isa<ConstantInt>(LHSI->getOperand(1)) &&
+             LHSI->getOperand(0)->hasOneUse()) {
+           // If this is: (X >> C1) & C2 != C3 (where any shift and any compare
+           // could exist), turn it into (X & (C2 << C1)) != (C3 << C1).  This
+           // happens a LOT in code produced by the C front-end, for bitfield
+           // access.
+           ShiftInst *Shift = dyn_cast<ShiftInst>(LHSI->getOperand(0));
+           ConstantUInt *ShAmt;
+           ShAmt = Shift ? dyn_cast<ConstantUInt>(Shift->getOperand(1)) : 0;
+           ConstantInt *AndCST = cast<ConstantInt>(LHSI->getOperand(1));
+           const Type *Ty = LHSI->getType();
+           
+           // We can fold this as long as we can't shift unknown bits
+           // into the mask.  This can only happen with signed shift
+           // rights, as they sign-extend.
+           if (ShAmt) {
+             bool CanFold = Shift->getOpcode() != Instruction::Shr ||
+                            Shift->getType()->isUnsigned();
+             if (!CanFold) {
+               // To test for the bad case of the signed shr, see if any
+               // of the bits shifted in could be tested after the mask.
+               Constant *OShAmt = ConstantUInt::get(Type::UByteTy, 
+                                    Ty->getPrimitiveSize()*8-ShAmt->getValue());
+               Constant *ShVal = 
+                 ConstantExpr::getShl(ConstantInt::getAllOnesValue(Ty), OShAmt);
+               if (ConstantExpr::getAnd(ShVal, AndCST)->isNullValue())
+                 CanFold = true;
+             }
+             
+             if (CanFold) {
+               Constant *NewCst;
+               if (Shift->getOpcode() == Instruction::Shl)
+                 NewCst = ConstantExpr::getUShr(CI, ShAmt);
+               else
+                 NewCst = ConstantExpr::getShl(CI, ShAmt);
+ 
+               // Check to see if we are shifting out any of the bits being
+               // compared.
+               if (ConstantExpr::get(Shift->getOpcode(), NewCst, ShAmt) != CI){
+                 // If we shifted bits out, the fold is not going to work out.
+                 // As a special case, check to see if this means that the
+                 // result is always true or false now.
+                 if (I.getOpcode() == Instruction::SetEQ)
+                   return ReplaceInstUsesWith(I, ConstantBool::False);
+                 if (I.getOpcode() == Instruction::SetNE)
+                   return ReplaceInstUsesWith(I, ConstantBool::True);
+               } else {
+                 I.setOperand(1, NewCst);
+                 Constant *NewAndCST;
+                 if (Shift->getOpcode() == Instruction::Shl)
+                   NewAndCST = ConstantExpr::getUShr(AndCST, ShAmt);
+                 else
+                   NewAndCST = ConstantExpr::getShl(AndCST, ShAmt);
+                 LHSI->setOperand(1, NewAndCST);
+                 LHSI->setOperand(0, Shift->getOperand(0));
+                 WorkList.push_back(Shift); // Shift is dead.
+                 AddUsesToWorkList(I);
+                 return &I;
+               }
+             }
+           }
+         }
+         break;
+ 
+       case Instruction::Cast: {       // (setcc (cast X to larger), CI)
+         const Type *SrcTy = LHSI->getOperand(0)->getType();
+         if (SrcTy->isIntegral() && LHSI->getType()->isIntegral()) {
+           unsigned SrcBits = SrcTy->getPrimitiveSize()*8;
+           if (SrcTy == Type::BoolTy) SrcBits = 1;
+           unsigned DestBits = LHSI->getType()->getPrimitiveSize()*8;
+           if (LHSI->getType() == Type::BoolTy) DestBits = 1;
+           if (SrcBits < DestBits) {
+             // Check to see if the comparison is always true or false.
+             Constant *NewCst = ConstantExpr::getCast(CI, SrcTy);
+             if (ConstantExpr::getCast(NewCst, LHSI->getType()) != CI) {
+               Constant *Min = ConstantIntegral::getMinValue(SrcTy);
+               Constant *Max = ConstantIntegral::getMaxValue(SrcTy);
+               Min = ConstantExpr::getCast(Min, LHSI->getType());
+               Max = ConstantExpr::getCast(Max, LHSI->getType());
+               switch (I.getOpcode()) {
+               default: assert(0 && "unknown integer comparison");
+               case Instruction::SetEQ:
+                 return ReplaceInstUsesWith(I, ConstantBool::False);
+               case Instruction::SetNE:
+                 return ReplaceInstUsesWith(I, ConstantBool::True);
+               case Instruction::SetLT:
+                 return ReplaceInstUsesWith(I, ConstantExpr::getSetLT(Max, CI));
+               case Instruction::SetGT:
+                 return ReplaceInstUsesWith(I, ConstantExpr::getSetGT(Min, CI));
+               }
+             }
+ 
+             return new SetCondInst(I.getOpcode(), LHSI->getOperand(0),
+                                    ConstantExpr::getCast(CI, SrcTy));
+           }
+         }
+         break;
+       }
+       case Instruction::Shl:         // (setcc (shl X, ShAmt), CI)
+         if (ConstantUInt *ShAmt = dyn_cast<ConstantUInt>(LHSI->getOperand(1))) {
+           switch (I.getOpcode()) {
+           default: break;
+           case Instruction::SetEQ:
+           case Instruction::SetNE: {
+             // If we are comparing against bits always shifted out, the
+             // comparison cannot succeed.
+             Constant *Comp = 
+               ConstantExpr::getShl(ConstantExpr::getShr(CI, ShAmt), ShAmt);
+             if (Comp != CI) {// Comparing against a bit that we know is zero.
+               bool IsSetNE = I.getOpcode() == Instruction::SetNE;
+               Constant *Cst = ConstantBool::get(IsSetNE);
+               return ReplaceInstUsesWith(I, Cst);
+             }
+ 
+             if (LHSI->hasOneUse()) {
+               // Otherwise strength reduce the shift into an and.
+               unsigned ShAmtVal = ShAmt->getValue();
+               unsigned TypeBits = CI->getType()->getPrimitiveSize()*8;
+               uint64_t Val = (1ULL << (TypeBits-ShAmtVal))-1;
+ 
+               Constant *Mask;
+               if (CI->getType()->isUnsigned()) {
+                 Mask = ConstantUInt::get(CI->getType(), Val);
+               } else if (ShAmtVal != 0) {
+                 Mask = ConstantSInt::get(CI->getType(), Val);
+               } else {
+                 Mask = ConstantInt::getAllOnesValue(CI->getType());
+               }
+               
+               Instruction *AndI =
+                 BinaryOperator::createAnd(LHSI->getOperand(0),
+                                           Mask, LHSI->getName()+".mask");
+               Value *And = InsertNewInstBefore(AndI, I);
+               return new SetCondInst(I.getOpcode(), And,
+                                      ConstantExpr::getUShr(CI, ShAmt));
+             }
+           }
+           }
+         }
+         break;
+ 
+       case Instruction::Shr:         // (setcc (shr X, ShAmt), CI)
+         if (ConstantUInt *ShAmt = dyn_cast<ConstantUInt>(LHSI->getOperand(1))) {
+           switch (I.getOpcode()) {
+           default: break;
+           case Instruction::SetEQ:
+           case Instruction::SetNE: {
+             // If we are comparing against bits always shifted out, the
+             // comparison cannot succeed.
+             Constant *Comp = 
+               ConstantExpr::getShr(ConstantExpr::getShl(CI, ShAmt), ShAmt);
+             
+             if (Comp != CI) {// Comparing against a bit that we know is zero.
+               bool IsSetNE = I.getOpcode() == Instruction::SetNE;
+               Constant *Cst = ConstantBool::get(IsSetNE);
+               return ReplaceInstUsesWith(I, Cst);
+             }
+               
+             if (LHSI->hasOneUse() || CI->isNullValue()) {
+               unsigned ShAmtVal = ShAmt->getValue();
+ 
+               // Otherwise strength reduce the shift into an and.
+               uint64_t Val = ~0ULL;          // All ones.
+               Val <<= ShAmtVal;              // Shift over to the right spot.
+ 
+               Constant *Mask;
+               if (CI->getType()->isUnsigned()) {
+                 unsigned TypeBits = CI->getType()->getPrimitiveSize()*8;
+                 Val &= (1ULL << TypeBits)-1;
+                 Mask = ConstantUInt::get(CI->getType(), Val);
+               } else {
+                 Mask = ConstantSInt::get(CI->getType(), Val);
+               }
+               
+               Instruction *AndI =
+                 BinaryOperator::createAnd(LHSI->getOperand(0),
+                                           Mask, LHSI->getName()+".mask");
+               Value *And = InsertNewInstBefore(AndI, I);
+               return new SetCondInst(I.getOpcode(), And,
+                                      ConstantExpr::getShl(CI, ShAmt));
+             }
+             break;
+           }
+           }
+         }
+         break;
+ 
+       case Instruction::Div:
+         // Fold: (div X, C1) op C2 -> range check
+         if (ConstantInt *DivRHS = dyn_cast<ConstantInt>(LHSI->getOperand(1))) {
+           // Fold this div into the comparison, producing a range check.
+           // Determine, based on the divide type, what the range is being
+           // checked.  If there is an overflow on the low or high side, remember
+           // it, otherwise compute the range [low, hi) bounding the new value.
+           bool LoOverflow = false, HiOverflow = 0;
+           ConstantInt *LoBound = 0, *HiBound = 0;
+ 
+           ConstantInt *Prod;
+           bool ProdOV = MulWithOverflow(Prod, CI, DivRHS);
+ 
+           if (DivRHS->isNullValue()) {  // Don't hack on divide by zeros.
+           } else if (LHSI->getType()->isUnsigned()) {  // udiv
+             LoBound = Prod;
+             LoOverflow = ProdOV;
+             HiOverflow = ProdOV || AddWithOverflow(HiBound, LoBound, DivRHS);
+           } else if (isPositive(DivRHS)) {             // Divisor is > 0.
+             if (CI->isNullValue()) {       // (X / pos) op 0
+               // Can't overflow.
+               LoBound = cast<ConstantInt>(ConstantExpr::getNeg(SubOne(DivRHS)));
+               HiBound = DivRHS;
+             } else if (isPositive(CI)) {   // (X / pos) op pos
+               LoBound = Prod;
+               LoOverflow = ProdOV;
+               HiOverflow = ProdOV || AddWithOverflow(HiBound, Prod, DivRHS);
+             } else {                       // (X / pos) op neg
+               Constant *DivRHSH = ConstantExpr::getNeg(SubOne(DivRHS));
+               LoOverflow = AddWithOverflow(LoBound, Prod,
+                                            cast<ConstantInt>(DivRHSH));
+               HiBound = Prod;
+               HiOverflow = ProdOV;
+             }
+           } else {                                     // Divisor is < 0.
+             if (CI->isNullValue()) {       // (X / neg) op 0
+               LoBound = AddOne(DivRHS);
+               HiBound = cast<ConstantInt>(ConstantExpr::getNeg(DivRHS));
+             } else if (isPositive(CI)) {   // (X / neg) op pos
+               HiOverflow = LoOverflow = ProdOV;
+               if (!LoOverflow)
+                 LoOverflow = AddWithOverflow(LoBound, Prod, AddOne(DivRHS));
+               HiBound = AddOne(Prod);
+             } else {                       // (X / neg) op neg
+               LoBound = Prod;
+               LoOverflow = HiOverflow = ProdOV;
+               HiBound = cast<ConstantInt>(ConstantExpr::getSub(Prod, DivRHS));
+             }
+           }
+ 
+           if (LoBound) {
+             Value *X = LHSI->getOperand(0);
+             switch (I.getOpcode()) {
+             default: assert(0 && "Unhandled setcc opcode!");
+             case Instruction::SetEQ:
+               if (LoOverflow && HiOverflow)
+                 return ReplaceInstUsesWith(I, ConstantBool::False);
+               else if (HiOverflow)
+                 return new SetCondInst(Instruction::SetGE, X, LoBound);
+               else if (LoOverflow)
+                 return new SetCondInst(Instruction::SetLT, X, HiBound);
+               else
+                 return InsertRangeTest(X, LoBound, HiBound, true, I);
+             case Instruction::SetNE:
+               if (LoOverflow && HiOverflow)
+                 return ReplaceInstUsesWith(I, ConstantBool::True);
+               else if (HiOverflow)
+                 return new SetCondInst(Instruction::SetLT, X, LoBound);
+               else if (LoOverflow)
+                 return new SetCondInst(Instruction::SetGE, X, HiBound);
+               else
+                 return InsertRangeTest(X, LoBound, HiBound, false, I);
+             case Instruction::SetLT:
+               if (LoOverflow)
+                 return ReplaceInstUsesWith(I, ConstantBool::False);
+               return new SetCondInst(Instruction::SetLT, X, LoBound);
+             case Instruction::SetGT:
+               if (HiOverflow)
+                 return ReplaceInstUsesWith(I, ConstantBool::False);
+               return new SetCondInst(Instruction::SetGE, X, HiBound);
+             }
+           }
+         }
+         break;
+       case Instruction::Select:
+         // If either operand of the select is a constant, we can fold the
+         // comparison into the select arms, which will cause one to be
+         // constant folded and the select turned into a bitwise or.
+         Value *Op1 = 0, *Op2 = 0;
+         if (LHSI->hasOneUse()) {
+           if (Constant *C = dyn_cast<Constant>(LHSI->getOperand(1))) {
+             // Fold the known value into the constant operand.
+             Op1 = ConstantExpr::get(I.getOpcode(), C, CI);
+             // Insert a new SetCC of the other select operand.
+             Op2 = InsertNewInstBefore(new SetCondInst(I.getOpcode(),
+                                                       LHSI->getOperand(2), CI,
+                                                       I.getName()), I);
+           } else if (Constant *C = dyn_cast<Constant>(LHSI->getOperand(2))) {
+             // Fold the known value into the constant operand.
+             Op2 = ConstantExpr::get(I.getOpcode(), C, CI);
+             // Insert a new SetCC of the other select operand.
+             Op1 = InsertNewInstBefore(new SetCondInst(I.getOpcode(),
+                                                       LHSI->getOperand(1), CI,
+                                                       I.getName()), I);
+           }
+         }
+         
+         if (Op1)
+           return new SelectInst(LHSI->getOperand(0), Op1, Op2);
+         break;
+       }
+     
+     // Simplify seteq and setne instructions...
+     if (I.getOpcode() == Instruction::SetEQ ||
+         I.getOpcode() == Instruction::SetNE) {
+       bool isSetNE = I.getOpcode() == Instruction::SetNE;
+ 
+       // If the first operand is (and|or|xor) with a constant, and the second
+       // operand is a constant, simplify a bit.
+       if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Op0)) {
+         switch (BO->getOpcode()) {
+         case Instruction::Rem:
+           // If we have a signed (X % (2^c)) == 0, turn it into an unsigned one.
+           if (CI->isNullValue() && isa<ConstantSInt>(BO->getOperand(1)) &&
+               BO->hasOneUse() &&
+               cast<ConstantSInt>(BO->getOperand(1))->getValue() > 1)
+             if (unsigned L2 =
+                 Log2(cast<ConstantSInt>(BO->getOperand(1))->getValue())) {
+               const Type *UTy = BO->getType()->getUnsignedVersion();
+               Value *NewX = InsertNewInstBefore(new CastInst(BO->getOperand(0),
+                                                              UTy, "tmp"), I);
+               Constant *RHSCst = ConstantUInt::get(UTy, 1ULL << L2);
+               Value *NewRem =InsertNewInstBefore(BinaryOperator::createRem(NewX,
+                                                     RHSCst, BO->getName()), I);
+               return BinaryOperator::create(I.getOpcode(), NewRem,
+                                             Constant::getNullValue(UTy));
+             }
+           break;          
+ 
+         case Instruction::Add:
+           // Replace ((add A, B) != C) with (A != C-B) if B & C are constants.
+           if (ConstantInt *BOp1C = dyn_cast<ConstantInt>(BO->getOperand(1))) {
+             if (BO->hasOneUse())
+               return new SetCondInst(I.getOpcode(), BO->getOperand(0),
+                                      ConstantExpr::getSub(CI, BOp1C));
+           } else if (CI->isNullValue()) {
+             // Replace ((add A, B) != 0) with (A != -B) if A or B is
+             // efficiently invertible, or if the add has just this one use.
+             Value *BOp0 = BO->getOperand(0), *BOp1 = BO->getOperand(1);
+             
+             if (Value *NegVal = dyn_castNegVal(BOp1))
+               return new SetCondInst(I.getOpcode(), BOp0, NegVal);
+             else if (Value *NegVal = dyn_castNegVal(BOp0))
+               return new SetCondInst(I.getOpcode(), NegVal, BOp1);
+             else if (BO->hasOneUse()) {
+               Instruction *Neg = BinaryOperator::createNeg(BOp1, BO->getName());
+               BO->setName("");
+               InsertNewInstBefore(Neg, I);
+               return new SetCondInst(I.getOpcode(), BOp0, Neg);
+             }
+           }
+           break;
+         case Instruction::Xor:
+           // For the xor case, we can xor two constants together, eliminating
+           // the explicit xor.
+           if (Constant *BOC = dyn_cast<Constant>(BO->getOperand(1)))
+             return BinaryOperator::create(I.getOpcode(), BO->getOperand(0),
+                                   ConstantExpr::getXor(CI, BOC));
+ 
+           // FALLTHROUGH
+         case Instruction::Sub:
+           // Replace (([sub|xor] A, B) != 0) with (A != B)
+           if (CI->isNullValue())
+             return new SetCondInst(I.getOpcode(), BO->getOperand(0),
+                                    BO->getOperand(1));
+           break;
+ 
+         case Instruction::Or:
+           // If bits are being or'd in that are not present in the constant we
+           // are comparing against, then the comparison could never succeed!
+           if (Constant *BOC = dyn_cast<Constant>(BO->getOperand(1))) {
+             Constant *NotCI = ConstantExpr::getNot(CI);
+             if (!ConstantExpr::getAnd(BOC, NotCI)->isNullValue())
+               return ReplaceInstUsesWith(I, ConstantBool::get(isSetNE));
+           }
+           break;
+ 
+         case Instruction::And:
+           if (ConstantInt *BOC = dyn_cast<ConstantInt>(BO->getOperand(1))) {
+             // If bits are being compared against that are and'd out, then the
+             // comparison can never succeed!
+             if (!ConstantExpr::getAnd(CI,
+                                       ConstantExpr::getNot(BOC))->isNullValue())
+               return ReplaceInstUsesWith(I, ConstantBool::get(isSetNE));
+ 
+             // If we have ((X & C) == C), turn it into ((X & C) != 0).
+             if (CI == BOC && isOneBitSet(CI))
+               return new SetCondInst(isSetNE ? Instruction::SetEQ :
+                                      Instruction::SetNE, Op0,
+                                      Constant::getNullValue(CI->getType()));
+ 
+             // Replace (and X, (1 << size(X)-1) != 0) with x < 0, converting X
+             // to be a signed value as appropriate.
+             if (isSignBit(BOC)) {
+               Value *X = BO->getOperand(0);
+               // If 'X' is not signed, insert a cast now...
+               if (!BOC->getType()->isSigned()) {
+                 const Type *DestTy = BOC->getType()->getSignedVersion();
+                 X = InsertCastBefore(X, DestTy, I);
+               }
+               return new SetCondInst(isSetNE ? Instruction::SetLT :
+                                          Instruction::SetGE, X,
+                                      Constant::getNullValue(X->getType()));
+             }
+             
+             // ((X & ~7) == 0) --> X < 8
+             if (CI->isNullValue() && isHighOnes(BOC)) {
+               Value *X = BO->getOperand(0);
+               Constant *NegX = ConstantExpr::getNeg(BOC);
+ 
+               // If 'X' is signed, insert a cast now.
+               if (NegX->getType()->isSigned()) {
+                 const Type *DestTy = NegX->getType()->getUnsignedVersion();
+                 X = InsertCastBefore(X, DestTy, I);
+                 NegX = ConstantExpr::getCast(NegX, DestTy);
+               }
+ 
+               return new SetCondInst(isSetNE ? Instruction::SetGE :
+                                      Instruction::SetLT, X, NegX);
+             }
+ 
+           }
+         default: break;
+         }
+       }
+     } else {  // Not a SetEQ/SetNE
+       // If the LHS is a cast from an integral value of the same size, 
+       if (CastInst *Cast = dyn_cast<CastInst>(Op0)) {
+         Value *CastOp = Cast->getOperand(0);
+         const Type *SrcTy = CastOp->getType();
+         unsigned SrcTySize = SrcTy->getPrimitiveSize();
+         if (SrcTy != Cast->getType() && SrcTy->isInteger() &&
+             SrcTySize == Cast->getType()->getPrimitiveSize()) {
+           assert((SrcTy->isSigned() ^ Cast->getType()->isSigned()) && 
+                  "Source and destination signednesses should differ!");
+           if (Cast->getType()->isSigned()) {
+             // If this is a signed comparison, check for comparisons in the
+             // vicinity of zero.
+             if (I.getOpcode() == Instruction::SetLT && CI->isNullValue())
+               // X < 0  => x > 127
+               return BinaryOperator::createSetGT(CastOp,
+                          ConstantUInt::get(SrcTy, (1ULL << (SrcTySize*8-1))-1));
+             else if (I.getOpcode() == Instruction::SetGT &&
+                      cast<ConstantSInt>(CI)->getValue() == -1)
+               // X > -1  => x < 128
+               return BinaryOperator::createSetLT(CastOp,
+                          ConstantUInt::get(SrcTy, 1ULL << (SrcTySize*8-1)));
+           } else {
+             ConstantUInt *CUI = cast<ConstantUInt>(CI);
+             if (I.getOpcode() == Instruction::SetLT &&
+                 CUI->getValue() == 1ULL << (SrcTySize*8-1))
+               // X < 128 => X > -1
+               return BinaryOperator::createSetGT(CastOp,
+                                                  ConstantSInt::get(SrcTy, -1));
+             else if (I.getOpcode() == Instruction::SetGT &&
+                      CUI->getValue() == (1ULL << (SrcTySize*8-1))-1)
+               // X > 127 => X < 0
+               return BinaryOperator::createSetLT(CastOp,
+                                                  Constant::getNullValue(SrcTy));
+           }
+         }
+       }
+     }
+   }
+ 
+   // Test to see if the operands of the setcc are casted versions of other
+   // values.  If the cast can be stripped off both arguments, we do so now.
+   if (CastInst *CI = dyn_cast<CastInst>(Op0)) {
+     Value *CastOp0 = CI->getOperand(0);
+     if (CastOp0->getType()->isLosslesslyConvertibleTo(CI->getType()) &&
+         (isa<Constant>(Op1) || isa<CastInst>(Op1)) &&
+         (I.getOpcode() == Instruction::SetEQ ||
+          I.getOpcode() == Instruction::SetNE)) {
+       // We keep moving the cast from the left operand over to the right
+       // operand, where it can often be eliminated completely.
+       Op0 = CastOp0;
+       
+       // If operand #1 is a cast instruction, see if we can eliminate it as
+       // well.
+       if (CastInst *CI2 = dyn_cast<CastInst>(Op1))
+         if (CI2->getOperand(0)->getType()->isLosslesslyConvertibleTo(
+                                                                Op0->getType()))
+           Op1 = CI2->getOperand(0);
+       
+       // If Op1 is a constant, we can fold the cast into the constant.
+       if (Op1->getType() != Op0->getType())
+         if (Constant *Op1C = dyn_cast<Constant>(Op1)) {
+           Op1 = ConstantExpr::getCast(Op1C, Op0->getType());
+         } else {
+           // Otherwise, cast the RHS right before the setcc
+           Op1 = new CastInst(Op1, Op0->getType(), Op1->getName());
+           InsertNewInstBefore(cast<Instruction>(Op1), I);
+         }
+       return BinaryOperator::create(I.getOpcode(), Op0, Op1);
+     }
+ 
+     // Handle the special case of: setcc (cast bool to X), <cst>
+     // This comes up when you have code like
+     //   int X = A < B;
+     //   if (X) ...
+     // For generality, we handle any zero-extension of any operand comparison
+     // with a constant.
+     if (ConstantInt *ConstantRHS = dyn_cast<ConstantInt>(Op1)) {
+       const Type *SrcTy = CastOp0->getType();
+       const Type *DestTy = Op0->getType();
+       if (SrcTy->getPrimitiveSize() < DestTy->getPrimitiveSize() &&
+           (SrcTy->isUnsigned() || SrcTy == Type::BoolTy)) {
+         // Ok, we have an expansion of operand 0 into a new type.  Get the
+         // constant value, masink off bits which are not set in the RHS.  These
+         // could be set if the destination value is signed.
+         uint64_t ConstVal = ConstantRHS->getRawValue();
+         ConstVal &= (1ULL << DestTy->getPrimitiveSize()*8)-1;
+ 
+         // If the constant we are comparing it with has high bits set, which
+         // don't exist in the original value, the values could never be equal,
+         // because the source would be zero extended.
+         unsigned SrcBits =
+           SrcTy == Type::BoolTy ? 1 : SrcTy->getPrimitiveSize()*8;
+         bool HasSignBit = ConstVal & (1ULL << (DestTy->getPrimitiveSize()*8-1));
+         if (ConstVal & ~((1ULL << SrcBits)-1)) {
+           switch (I.getOpcode()) {
+           default: assert(0 && "Unknown comparison type!");
+           case Instruction::SetEQ:
+             return ReplaceInstUsesWith(I, ConstantBool::False);
+           case Instruction::SetNE:
+             return ReplaceInstUsesWith(I, ConstantBool::True);
+           case Instruction::SetLT:
+           case Instruction::SetLE:
+             if (DestTy->isSigned() && HasSignBit)
+               return ReplaceInstUsesWith(I, ConstantBool::False);
+             return ReplaceInstUsesWith(I, ConstantBool::True);
+           case Instruction::SetGT:
+           case Instruction::SetGE:
+             if (DestTy->isSigned() && HasSignBit)
+               return ReplaceInstUsesWith(I, ConstantBool::True);
+             return ReplaceInstUsesWith(I, ConstantBool::False);
+           }
+         }
+         
+         // Otherwise, we can replace the setcc with a setcc of the smaller
+         // operand value.
+         Op1 = ConstantExpr::getCast(cast<Constant>(Op1), SrcTy);
+         return BinaryOperator::create(I.getOpcode(), CastOp0, Op1);
+       }
+     }
+   }
+   return Changed ? &I : 0;
+ }
+ 
+ 
+ 
+ Instruction *InstCombiner::visitShiftInst(ShiftInst &I) {
+   assert(I.getOperand(1)->getType() == Type::UByteTy);
+   Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
+   bool isLeftShift = I.getOpcode() == Instruction::Shl;
+ 
+   // shl X, 0 == X and shr X, 0 == X
+   // shl 0, X == 0 and shr 0, X == 0
+   if (Op1 == Constant::getNullValue(Type::UByteTy) ||
+       Op0 == Constant::getNullValue(Op0->getType()))
+     return ReplaceInstUsesWith(I, Op0);
+ 
+   // shr int -1, X = -1   (for any arithmetic shift rights of ~0)
+   if (!isLeftShift)
+     if (ConstantSInt *CSI = dyn_cast<ConstantSInt>(Op0))
+       if (CSI->isAllOnesValue())
+         return ReplaceInstUsesWith(I, CSI);
+ 
+   // Try to fold constant and into select arguments.
+   if (isa<Constant>(Op0))
+     if (SelectInst *SI = dyn_cast<SelectInst>(Op1))
+       if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
+         return R;
+ 
+   if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(Op1)) {
+     // shl uint X, 32 = 0 and shr ubyte Y, 9 = 0, ... just don't eliminate shr
+     // of a signed value.
+     //
+     unsigned TypeBits = Op0->getType()->getPrimitiveSize()*8;
+     if (CUI->getValue() >= TypeBits) {
+       if (!Op0->getType()->isSigned() || isLeftShift)
+         return ReplaceInstUsesWith(I, Constant::getNullValue(Op0->getType()));
+       else {
+         I.setOperand(1, ConstantUInt::get(Type::UByteTy, TypeBits-1));
+         return &I;
+       }
+     }
+ 
+     // ((X*C1) << C2) == (X * (C1 << C2))
+     if (BinaryOperator *BO = dyn_cast<BinaryOperator>(Op0))
+       if (BO->getOpcode() == Instruction::Mul && isLeftShift)
+         if (Constant *BOOp = dyn_cast<Constant>(BO->getOperand(1)))
+           return BinaryOperator::createMul(BO->getOperand(0),
+                                            ConstantExpr::getShl(BOOp, CUI));
+     
+     // Try to fold constant and into select arguments.
+     if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
+       if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
+         return R;
+     if (isa<PHINode>(Op0))
+       if (Instruction *NV = FoldOpIntoPhi(I))
+         return NV;
+ 
+     // If the operand is an bitwise operator with a constant RHS, and the
+     // shift is the only use, we can pull it out of the shift.
+     if (Op0->hasOneUse())
+       if (BinaryOperator *Op0BO = dyn_cast<BinaryOperator>(Op0))
+         if (ConstantInt *Op0C = dyn_cast<ConstantInt>(Op0BO->getOperand(1))) {
+           bool isValid = true;     // Valid only for And, Or, Xor
+           bool highBitSet = false; // Transform if high bit of constant set?
+ 
+           switch (Op0BO->getOpcode()) {
+           default: isValid = false; break;   // Do not perform transform!
+           case Instruction::Or:
+           case Instruction::Xor:
+             highBitSet = false;
+             break;
+           case Instruction::And:
+             highBitSet = true;
+             break;
+           }
+ 
+           // If this is a signed shift right, and the high bit is modified
+           // by the logical operation, do not perform the transformation.
+           // The highBitSet boolean indicates the value of the high bit of
+           // the constant which would cause it to be modified for this
+           // operation.
+           //
+           if (isValid && !isLeftShift && !I.getType()->isUnsigned()) {
+             uint64_t Val = Op0C->getRawValue();
+             isValid = ((Val & (1 << (TypeBits-1))) != 0) == highBitSet;
+           }
+ 
+           if (isValid) {
+             Constant *NewRHS = ConstantExpr::get(I.getOpcode(), Op0C, CUI);
+ 
+             Instruction *NewShift =
+               new ShiftInst(I.getOpcode(), Op0BO->getOperand(0), CUI,
+                             Op0BO->getName());
+             Op0BO->setName("");
+             InsertNewInstBefore(NewShift, I);
+ 
+             return BinaryOperator::create(Op0BO->getOpcode(), NewShift,
+                                           NewRHS);
+           }
+         }
+ 
+     // If this is a shift of a shift, see if we can fold the two together...
+     if (ShiftInst *Op0SI = dyn_cast<ShiftInst>(Op0))
+       if (ConstantUInt *ShiftAmt1C =
+                                  dyn_cast<ConstantUInt>(Op0SI->getOperand(1))) {
+         unsigned ShiftAmt1 = ShiftAmt1C->getValue();
+         unsigned ShiftAmt2 = CUI->getValue();
+         
+         // Check for (A << c1) << c2   and   (A >> c1) >> c2
+         if (I.getOpcode() == Op0SI->getOpcode()) {
+           unsigned Amt = ShiftAmt1+ShiftAmt2;   // Fold into one big shift...
+           if (Op0->getType()->getPrimitiveSize()*8 < Amt)
+             Amt = Op0->getType()->getPrimitiveSize()*8;
+           return new ShiftInst(I.getOpcode(), Op0SI->getOperand(0),
+                                ConstantUInt::get(Type::UByteTy, Amt));
+         }
+         
+         // Check for (A << c1) >> c2 or visaversa.  If we are dealing with
+         // signed types, we can only support the (A >> c1) << c2 configuration,
+         // because it can not turn an arbitrary bit of A into a sign bit.
+         if (I.getType()->isUnsigned() || isLeftShift) {
+           // Calculate bitmask for what gets shifted off the edge...
+           Constant *C = ConstantIntegral::getAllOnesValue(I.getType());
+           if (isLeftShift)
+             C = ConstantExpr::getShl(C, ShiftAmt1C);
+           else
+             C = ConstantExpr::getShr(C, ShiftAmt1C);
+           
+           Instruction *Mask =
+             BinaryOperator::createAnd(Op0SI->getOperand(0), C,
+                                       Op0SI->getOperand(0)->getName()+".mask");
+           InsertNewInstBefore(Mask, I);
+           
+           // Figure out what flavor of shift we should use...
+           if (ShiftAmt1 == ShiftAmt2)
+             return ReplaceInstUsesWith(I, Mask);  // (A << c) >> c  === A & c2
+           else if (ShiftAmt1 < ShiftAmt2) {
+             return new ShiftInst(I.getOpcode(), Mask,
+                          ConstantUInt::get(Type::UByteTy, ShiftAmt2-ShiftAmt1));
+           } else {
+             return new ShiftInst(Op0SI->getOpcode(), Mask,
+                          ConstantUInt::get(Type::UByteTy, ShiftAmt1-ShiftAmt2));
+           }
+         }
+       }
+   }
+ 
+   return 0;
+ }
+ 
+ enum CastType {
+   Noop     = 0,
+   Truncate = 1,
+   Signext  = 2,
+   Zeroext  = 3
+ };
+ 
+ /// getCastType - In the future, we will split the cast instruction into these
+ /// various types.  Until then, we have to do the analysis here.
+ static CastType getCastType(const Type *Src, const Type *Dest) {
+   assert(Src->isIntegral() && Dest->isIntegral() &&
+          "Only works on integral types!");
+   unsigned SrcSize = Src->getPrimitiveSize()*8;
+   if (Src == Type::BoolTy) SrcSize = 1;
+   unsigned DestSize = Dest->getPrimitiveSize()*8;
+   if (Dest == Type::BoolTy) DestSize = 1;
+ 
+   if (SrcSize == DestSize) return Noop;
+   if (SrcSize > DestSize)  return Truncate;
+   if (Src->isSigned()) return Signext;
+   return Zeroext;
+ }
+ 
+ 
+ // isEliminableCastOfCast - Return true if it is valid to eliminate the CI
+ // instruction.
+ //
+ static inline bool isEliminableCastOfCast(const Type *SrcTy, const Type *MidTy,
+                                           const Type *DstTy, TargetData *TD) {
+ 
+   // It is legal to eliminate the instruction if casting A->B->A if the sizes
+   // are identical and the bits don't get reinterpreted (for example 
+   // int->float->int would not be allowed).
+   if (SrcTy == DstTy && SrcTy->isLosslesslyConvertibleTo(MidTy))
+     return true;
+ 
+   // If we are casting between pointer and integer types, treat pointers as
+   // integers of the appropriate size for the code below.
+   if (isa<PointerType>(SrcTy)) SrcTy = TD->getIntPtrType();
+   if (isa<PointerType>(MidTy)) MidTy = TD->getIntPtrType();
+   if (isa<PointerType>(DstTy)) DstTy = TD->getIntPtrType();
+ 
+   // Allow free casting and conversion of sizes as long as the sign doesn't
+   // change...
+   if (SrcTy->isIntegral() && MidTy->isIntegral() && DstTy->isIntegral()) {
+     CastType FirstCast = getCastType(SrcTy, MidTy);
+     CastType SecondCast = getCastType(MidTy, DstTy);
+ 
+     // Capture the effect of these two casts.  If the result is a legal cast,
+     // the CastType is stored here, otherwise a special code is used.
+     static const unsigned CastResult[] = {
+       // First cast is noop
+       0, 1, 2, 3,
+       // First cast is a truncate
+       1, 1, 4, 4,         // trunc->extend is not safe to eliminate
+       // First cast is a sign ext
+       2, 5, 2, 4,         // signext->zeroext never ok
+       // First cast is a zero ext
+       3, 5, 3, 3,
+     };
+ 
+     unsigned Result = CastResult[FirstCast*4+SecondCast];
+     switch (Result) {
+     default: assert(0 && "Illegal table value!");
+     case 0:
+     case 1:
+     case 2:
+     case 3:
+       // FIXME: in the future, when LLVM has explicit sign/zeroextends and
+       // truncates, we could eliminate more casts.
+       return (unsigned)getCastType(SrcTy, DstTy) == Result;
+     case 4:
+       return false;  // Not possible to eliminate this here.
+     case 5:
+       // Sign or zero extend followed by truncate is always ok if the result
+       // is a truncate or noop.
+       CastType ResultCast = getCastType(SrcTy, DstTy);
+       if (ResultCast == Noop || ResultCast == Truncate)
+         return true;
+       // Otherwise we are still growing the value, we are only safe if the 
+       // result will match the sign/zeroextendness of the result.
+       return ResultCast == FirstCast;
+     }
+   }
+   return false;
+ }
+ 
+ static bool ValueRequiresCast(const Value *V, const Type *Ty, TargetData *TD) {
+   if (V->getType() == Ty || isa<Constant>(V)) return false;
+   if (const CastInst *CI = dyn_cast<CastInst>(V))
+     if (isEliminableCastOfCast(CI->getOperand(0)->getType(), CI->getType(), Ty,
+                                TD))
+       return false;
+   return true;
+ }
+ 
+ /// InsertOperandCastBefore - This inserts a cast of V to DestTy before the
+ /// InsertBefore instruction.  This is specialized a bit to avoid inserting
+ /// casts that are known to not do anything...
+ ///
+ Value *InstCombiner::InsertOperandCastBefore(Value *V, const Type *DestTy,
+                                              Instruction *InsertBefore) {
+   if (V->getType() == DestTy) return V;
+   if (Constant *C = dyn_cast<Constant>(V))
+     return ConstantExpr::getCast(C, DestTy);
+ 
+   CastInst *CI = new CastInst(V, DestTy, V->getName());
+   InsertNewInstBefore(CI, *InsertBefore);
+   return CI;
+ }
+ 
+ // CastInst simplification
+ //
+ Instruction *InstCombiner::visitCastInst(CastInst &CI) {
+   Value *Src = CI.getOperand(0);
+ 
+   // If the user is casting a value to the same type, eliminate this cast
+   // instruction...
+   if (CI.getType() == Src->getType())
+     return ReplaceInstUsesWith(CI, Src);
+ 
+   // If casting the result of another cast instruction, try to eliminate this
+   // one!
+   //
+   if (CastInst *CSrc = dyn_cast<CastInst>(Src)) {
+     if (isEliminableCastOfCast(CSrc->getOperand(0)->getType(),
+                                CSrc->getType(), CI.getType(), TD)) {
+       // This instruction now refers directly to the cast's src operand.  This
+       // has a good chance of making CSrc dead.
+       CI.setOperand(0, CSrc->getOperand(0));
+       return &CI;
+     }
+ 
+     // If this is an A->B->A cast, and we are dealing with integral types, try
+     // to convert this into a logical 'and' instruction.
+     //
+     if (CSrc->getOperand(0)->getType() == CI.getType() &&
+         CI.getType()->isInteger() && CSrc->getType()->isInteger() &&
+         CI.getType()->isUnsigned() && CSrc->getType()->isUnsigned() &&
+         CSrc->getType()->getPrimitiveSize() < CI.getType()->getPrimitiveSize()){
+       assert(CSrc->getType() != Type::ULongTy &&
+              "Cannot have type bigger than ulong!");
+       uint64_t AndValue = (1ULL << CSrc->getType()->getPrimitiveSize()*8)-1;
+       Constant *AndOp = ConstantUInt::get(CI.getType(), AndValue);
+       return BinaryOperator::createAnd(CSrc->getOperand(0), AndOp);
+     }
+   }
+ 
+   // If this is a cast to bool, turn it into the appropriate setne instruction.
+   if (CI.getType() == Type::BoolTy)
+     return BinaryOperator::createSetNE(CI.getOperand(0),
+                        Constant::getNullValue(CI.getOperand(0)->getType()));
+ 
+   // If casting the result of a getelementptr instruction with no offset, turn
+   // this into a cast of the original pointer!
+   //
+   if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Src)) {
+     bool AllZeroOperands = true;
+     for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i)
+       if (!isa<Constant>(GEP->getOperand(i)) ||
+           !cast<Constant>(GEP->getOperand(i))->isNullValue()) {
+         AllZeroOperands = false;
+         break;
+       }
+     if (AllZeroOperands) {
+       CI.setOperand(0, GEP->getOperand(0));
+       return &CI;
+     }
+   }
+ 
+   // If we are casting a malloc or alloca to a pointer to a type of the same
+   // size, rewrite the allocation instruction to allocate the "right" type.
+   //
+   if (AllocationInst *AI = dyn_cast<AllocationInst>(Src))
+     if (AI->hasOneUse() && !AI->isArrayAllocation())
+       if (const PointerType *PTy = dyn_cast<PointerType>(CI.getType())) {
+         // Get the type really allocated and the type casted to...
+         const Type *AllocElTy = AI->getAllocatedType();
+         const Type *CastElTy = PTy->getElementType();
+         if (AllocElTy->isSized() && CastElTy->isSized()) {
+           unsigned AllocElTySize = TD->getTypeSize(AllocElTy);
+           unsigned CastElTySize = TD->getTypeSize(CastElTy);
+ 
+           // If the allocation is for an even multiple of the cast type size
+           if (CastElTySize && (AllocElTySize % CastElTySize == 0)) {
+             Value *Amt = ConstantUInt::get(Type::UIntTy, 
+                                          AllocElTySize/CastElTySize);
+             std::string Name = AI->getName(); AI->setName("");
+             AllocationInst *New;
+             if (isa<MallocInst>(AI))
+               New = new MallocInst(CastElTy, Amt, Name);
+             else
+               New = new AllocaInst(CastElTy, Amt, Name);
+             InsertNewInstBefore(New, *AI);
+             return ReplaceInstUsesWith(CI, New);
+           }
+         }
+       }
+ 
+   if (isa<PHINode>(Src))
+     if (Instruction *NV = FoldOpIntoPhi(CI))
+       return NV;
+ 
+   // If the source value is an instruction with only this use, we can attempt to
+   // propagate the cast into the instruction.  Also, only handle integral types
+   // for now.
+   if (Instruction *SrcI = dyn_cast<Instruction>(Src))
+     if (SrcI->hasOneUse() && Src->getType()->isIntegral() &&
+         CI.getType()->isInteger()) {  // Don't mess with casts to bool here
+       const Type *DestTy = CI.getType();
+       unsigned SrcBitSize = getTypeSizeInBits(Src->getType());
+       unsigned DestBitSize = getTypeSizeInBits(DestTy);
+ 
+       Value *Op0 = SrcI->getNumOperands() > 0 ? SrcI->getOperand(0) : 0;
+       Value *Op1 = SrcI->getNumOperands() > 1 ? SrcI->getOperand(1) : 0;
+ 
+       switch (SrcI->getOpcode()) {
+       case Instruction::Add:
+       case Instruction::Mul:
+       case Instruction::And:
+       case Instruction::Or:
+       case Instruction::Xor:
+         // If we are discarding information, or just changing the sign, rewrite.
+         if (DestBitSize <= SrcBitSize && DestBitSize != 1) {
+           // Don't insert two casts if they cannot be eliminated.  We allow two
+           // casts to be inserted if the sizes are the same.  This could only be
+           // converting signedness, which is a noop.
+           if (DestBitSize == SrcBitSize || !ValueRequiresCast(Op1, DestTy,TD) ||
+               !ValueRequiresCast(Op0, DestTy, TD)) {
+             Value *Op0c = InsertOperandCastBefore(Op0, DestTy, SrcI);
+             Value *Op1c = InsertOperandCastBefore(Op1, DestTy, SrcI);
+             return BinaryOperator::create(cast<BinaryOperator>(SrcI)
+                              ->getOpcode(), Op0c, Op1c);
+           }
+         }
+         break;
+       case Instruction::Shl:
+         // Allow changing the sign of the source operand.  Do not allow changing
+         // the size of the shift, UNLESS the shift amount is a constant.  We
+         // mush not change variable sized shifts to a smaller size, because it
+         // is undefined to shift more bits out than exist in the value.
+         if (DestBitSize == SrcBitSize ||
+             (DestBitSize < SrcBitSize && isa<Constant>(Op1))) {
+           Value *Op0c = InsertOperandCastBefore(Op0, DestTy, SrcI);
+           return new ShiftInst(Instruction::Shl, Op0c, Op1);
+         }
+         break;
+       }
+     }
+   
+   return 0;
+ }
+ 
+ /// GetSelectFoldableOperands - We want to turn code that looks like this:
+ ///   %C = or %A, %B
+ ///   %D = select %cond, %C, %A
+ /// into:
+ ///   %C = select %cond, %B, 0
+ ///   %D = or %A, %C
+ ///
+ /// Assuming that the specified instruction is an operand to the select, return
+ /// a bitmask indicating which operands of this instruction are foldable if they
+ /// equal the other incoming value of the select.
+ ///
+ static unsigned GetSelectFoldableOperands(Instruction *I) {
+   switch (I->getOpcode()) {
+   case Instruction::Add:
+   case Instruction::Mul:
+   case Instruction::And:
+   case Instruction::Or:
+   case Instruction::Xor:
+     return 3;              // Can fold through either operand.
+   case Instruction::Sub:   // Can only fold on the amount subtracted.
+   case Instruction::Shl:   // Can only fold on the shift amount.
+   case Instruction::Shr:
+     return 1;           
+   default:
+     return 0;              // Cannot fold
+   }
+ }
+ 
+ /// GetSelectFoldableConstant - For the same transformation as the previous
+ /// function, return the identity constant that goes into the select.
+ static Constant *GetSelectFoldableConstant(Instruction *I) {
+   switch (I->getOpcode()) {
+   default: assert(0 && "This cannot happen!"); abort();
+   case Instruction::Add:
+   case Instruction::Sub:
+   case Instruction::Or:
+   case Instruction::Xor:
+     return Constant::getNullValue(I->getType());
+   case Instruction::Shl:
+   case Instruction::Shr:
+     return Constant::getNullValue(Type::UByteTy);
+   case Instruction::And:
+     return ConstantInt::getAllOnesValue(I->getType());
+   case Instruction::Mul:
+     return ConstantInt::get(I->getType(), 1);
+   }
+ }
+ 
+ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
+   Value *CondVal = SI.getCondition();
+   Value *TrueVal = SI.getTrueValue();
+   Value *FalseVal = SI.getFalseValue();
+ 
+   // select true, X, Y  -> X
+   // select false, X, Y -> Y
+   if (ConstantBool *C = dyn_cast<ConstantBool>(CondVal))
+     if (C == ConstantBool::True)
+       return ReplaceInstUsesWith(SI, TrueVal);
+     else {
+       assert(C == ConstantBool::False);
+       return ReplaceInstUsesWith(SI, FalseVal);
+     }
+ 
+   // select C, X, X -> X
+   if (TrueVal == FalseVal)
+     return ReplaceInstUsesWith(SI, TrueVal);
+ 
+   if (SI.getType() == Type::BoolTy)
+     if (ConstantBool *C = dyn_cast<ConstantBool>(TrueVal)) {
+       if (C == ConstantBool::True) {
+         // Change: A = select B, true, C --> A = or B, C
+         return BinaryOperator::createOr(CondVal, FalseVal);
+       } else {
+         // Change: A = select B, false, C --> A = and !B, C
+         Value *NotCond =
+           InsertNewInstBefore(BinaryOperator::createNot(CondVal,
+                                              "not."+CondVal->getName()), SI);
+         return BinaryOperator::createAnd(NotCond, FalseVal);
+       }
+     } else if (ConstantBool *C = dyn_cast<ConstantBool>(FalseVal)) {
+       if (C == ConstantBool::False) {
+         // Change: A = select B, C, false --> A = and B, C
+         return BinaryOperator::createAnd(CondVal, TrueVal);
+       } else {
+         // Change: A = select B, C, true --> A = or !B, C
+         Value *NotCond =
+           InsertNewInstBefore(BinaryOperator::createNot(CondVal,
+                                              "not."+CondVal->getName()), SI);
+         return BinaryOperator::createOr(NotCond, TrueVal);
+       }
+     }
+ 
+   // Selecting between two integer constants?
+   if (ConstantInt *TrueValC = dyn_cast<ConstantInt>(TrueVal))
+     if (ConstantInt *FalseValC = dyn_cast<ConstantInt>(FalseVal)) {
+       // select C, 1, 0 -> cast C to int
+       if (FalseValC->isNullValue() && TrueValC->getRawValue() == 1) {
+         return new CastInst(CondVal, SI.getType());
+       } else if (TrueValC->isNullValue() && FalseValC->getRawValue() == 1) {
+         // select C, 0, 1 -> cast !C to int
+         Value *NotCond =
+           InsertNewInstBefore(BinaryOperator::createNot(CondVal,
+                                                "not."+CondVal->getName()), SI);
+         return new CastInst(NotCond, SI.getType());
+       }
+ 
+       // If one of the constants is zero (we know they can't both be) and we
+       // have a setcc instruction with zero, and we have an 'and' with the
+       // non-constant value, eliminate this whole mess.  This corresponds to
+       // cases like this: ((X & 27) ? 27 : 0)
+       if (TrueValC->isNullValue() || FalseValC->isNullValue())
+         if (Instruction *IC = dyn_cast<Instruction>(SI.getCondition()))
+           if ((IC->getOpcode() == Instruction::SetEQ ||
+                IC->getOpcode() == Instruction::SetNE) &&
+               isa<ConstantInt>(IC->getOperand(1)) &&
+               cast<Constant>(IC->getOperand(1))->isNullValue())
+             if (Instruction *ICA = dyn_cast<Instruction>(IC->getOperand(0)))
+               if (ICA->getOpcode() == Instruction::And &&
+                   isa<ConstantInt>(ICA->getOperand(1)) && 
+                   (ICA->getOperand(1) == TrueValC || 
+                    ICA->getOperand(1) == FalseValC) && 
+                   isOneBitSet(cast<ConstantInt>(ICA->getOperand(1)))) {
+                 // Okay, now we know that everything is set up, we just don't
+                 // know whether we have a setne or seteq and whether the true or
+                 // false val is the zero.
+                 bool ShouldNotVal = !TrueValC->isNullValue();
+                 ShouldNotVal ^= IC->getOpcode() == Instruction::SetNE;
+                 Value *V = ICA;
+                 if (ShouldNotVal)
+                   V = InsertNewInstBefore(BinaryOperator::create(
+                                   Instruction::Xor, V, ICA->getOperand(1)), SI);
+                 return ReplaceInstUsesWith(SI, V);
+               }
+     }
+ 
+   // See if we are selecting two values based on a comparison of the two values.
+   if (SetCondInst *SCI = dyn_cast<SetCondInst>(CondVal)) {
+     if (SCI->getOperand(0) == TrueVal && SCI->getOperand(1) == FalseVal) {
+       // Transform (X == Y) ? X : Y  -> Y
+       if (SCI->getOpcode() == Instruction::SetEQ)
+         return ReplaceInstUsesWith(SI, FalseVal);
+       // Transform (X != Y) ? X : Y  -> X
+       if (SCI->getOpcode() == Instruction::SetNE)
+         return ReplaceInstUsesWith(SI, TrueVal);
+       // NOTE: if we wanted to, this is where to detect MIN/MAX/ABS/etc.
+ 
+     } else if (SCI->getOperand(0) == FalseVal && SCI->getOperand(1) == TrueVal){
+       // Transform (X == Y) ? Y : X  -> X
+       if (SCI->getOpcode() == Instruction::SetEQ)
+         return ReplaceInstUsesWith(SI, FalseVal);
+       // Transform (X != Y) ? Y : X  -> Y
+       if (SCI->getOpcode() == Instruction::SetNE)
+         return ReplaceInstUsesWith(SI, TrueVal);
+       // NOTE: if we wanted to, this is where to detect MIN/MAX/ABS/etc.
+     }
+   }
+   
+   // See if we can fold the select into one of our operands.
+   if (SI.getType()->isInteger()) {
+     // See the comment above GetSelectFoldableOperands for a description of the
+     // transformation we are doing here.
+     if (Instruction *TVI = dyn_cast<Instruction>(TrueVal))
+       if (TVI->hasOneUse() && TVI->getNumOperands() == 2 &&
+           !isa<Constant>(FalseVal))
+         if (unsigned SFO = GetSelectFoldableOperands(TVI)) {
+           unsigned OpToFold = 0;
+           if ((SFO & 1) && FalseVal == TVI->getOperand(0)) {
+             OpToFold = 1;
+           } else  if ((SFO & 2) && FalseVal == TVI->getOperand(1)) {
+             OpToFold = 2;
+           }
+ 
+           if (OpToFold) {
+             Constant *C = GetSelectFoldableConstant(TVI);
+             std::string Name = TVI->getName(); TVI->setName("");
+             Instruction *NewSel =
+               new SelectInst(SI.getCondition(), TVI->getOperand(2-OpToFold), C,
+                              Name);
+             InsertNewInstBefore(NewSel, SI);
+             if (BinaryOperator *BO = dyn_cast<BinaryOperator>(TVI))
+               return BinaryOperator::create(BO->getOpcode(), FalseVal, NewSel);
+             else if (ShiftInst *SI = dyn_cast<ShiftInst>(TVI))
+               return new ShiftInst(SI->getOpcode(), FalseVal, NewSel);
+             else {
+               assert(0 && "Unknown instruction!!");
+             }
+           }
+         }
+ 
+     if (Instruction *FVI = dyn_cast<Instruction>(FalseVal))
+       if (FVI->hasOneUse() && FVI->getNumOperands() == 2 &&
+           !isa<Constant>(TrueVal))
+         if (unsigned SFO = GetSelectFoldableOperands(FVI)) {
+           unsigned OpToFold = 0;
+           if ((SFO & 1) && TrueVal == FVI->getOperand(0)) {
+             OpToFold = 1;
+           } else  if ((SFO & 2) && TrueVal == FVI->getOperand(1)) {
+             OpToFold = 2;
+           }
+ 
+           if (OpToFold) {
+             Constant *C = GetSelectFoldableConstant(FVI);
+             std::string Name = FVI->getName(); FVI->setName("");
+             Instruction *NewSel =
+               new SelectInst(SI.getCondition(), C, FVI->getOperand(2-OpToFold),
+                              Name);
+             InsertNewInstBefore(NewSel, SI);
+             if (BinaryOperator *BO = dyn_cast<BinaryOperator>(FVI))
+               return BinaryOperator::create(BO->getOpcode(), TrueVal, NewSel);
+             else if (ShiftInst *SI = dyn_cast<ShiftInst>(FVI))
+               return new ShiftInst(SI->getOpcode(), TrueVal, NewSel);
+             else {
+               assert(0 && "Unknown instruction!!");
+             }
+           }
+         }
+   }
+   return 0;
+ }
+ 
+ 
+ // CallInst simplification
+ //
+ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
+   // Intrinsics cannot occur in an invoke, so handle them here instead of in
+   // visitCallSite.
+   if (Function *F = CI.getCalledFunction())
+     switch (F->getIntrinsicID()) {
+     case Intrinsic::memmove:
+     case Intrinsic::memcpy:
+     case Intrinsic::memset:
+       // memmove/cpy/set of zero bytes is a noop.
+       if (Constant *NumBytes = dyn_cast<Constant>(CI.getOperand(3))) {
+         if (NumBytes->isNullValue())
+           return EraseInstFromFunction(CI);
+       }
+       break;
+     default:
+       break;
+     }
+ 
+   return visitCallSite(&CI);
+ }
+ 
+ // InvokeInst simplification
+ //
+ Instruction *InstCombiner::visitInvokeInst(InvokeInst &II) {
+   return visitCallSite(&II);
+ }
+ 
+ // visitCallSite - Improvements for call and invoke instructions.
+ //
+ Instruction *InstCombiner::visitCallSite(CallSite CS) {
+   bool Changed = false;
+ 
+   // If the callee is a constexpr cast of a function, attempt to move the cast
+   // to the arguments of the call/invoke.
+   if (transformConstExprCastCall(CS)) return 0;
+ 
+   Value *Callee = CS.getCalledValue();
+   const PointerType *PTy = cast<PointerType>(Callee->getType());
+   const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
+   if (FTy->isVarArg()) {
+     // See if we can optimize any arguments passed through the varargs area of
+     // the call.
+     for (CallSite::arg_iterator I = CS.arg_begin()+FTy->getNumParams(),
+            E = CS.arg_end(); I != E; ++I)
+       if (CastInst *CI = dyn_cast<CastInst>(*I)) {
+         // If this cast does not effect the value passed through the varargs
+         // area, we can eliminate the use of the cast.
+         Value *Op = CI->getOperand(0);
+         if (CI->getType()->isLosslesslyConvertibleTo(Op->getType())) {
+           *I = Op;
+           Changed = true;
+         }
+       }
+   }
+   
+   return Changed ? CS.getInstruction() : 0;
+ }
+ 
+ // transformConstExprCastCall - If the callee is a constexpr cast of a function,
+ // attempt to move the cast to the arguments of the call/invoke.
+ //
+ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
+   if (!isa<ConstantExpr>(CS.getCalledValue())) return false;
+   ConstantExpr *CE = cast<ConstantExpr>(CS.getCalledValue());
+   if (CE->getOpcode() != Instruction::Cast || !isa<Function>(CE->getOperand(0)))
+     return false;
+   Function *Callee = cast<Function>(CE->getOperand(0));
+   Instruction *Caller = CS.getInstruction();
+ 
+   // Okay, this is a cast from a function to a different type.  Unless doing so
+   // would cause a type conversion of one of our arguments, change this call to
+   // be a direct call with arguments casted to the appropriate types.
+   //
+   const FunctionType *FT = Callee->getFunctionType();
+   const Type *OldRetTy = Caller->getType();
+ 
+   // Check to see if we are changing the return type...
+   if (OldRetTy != FT->getReturnType()) {
+     if (Callee->isExternal() &&
+         !OldRetTy->isLosslesslyConvertibleTo(FT->getReturnType()) &&
+         !Caller->use_empty())
+       return false;   // Cannot transform this return value...
+ 
+     // If the callsite is an invoke instruction, and the return value is used by
+     // a PHI node in a successor, we cannot change the return type of the call
+     // because there is no place to put the cast instruction (without breaking
+     // the critical edge).  Bail out in this case.
+     if (!Caller->use_empty())
+       if (InvokeInst *II = dyn_cast<InvokeInst>(Caller))
+         for (Value::use_iterator UI = II->use_begin(), E = II->use_end();
+              UI != E; ++UI)
+           if (PHINode *PN = dyn_cast<PHINode>(*UI))
+             if (PN->getParent() == II->getNormalDest() ||
+                 PN->getParent() == II->getUnwindDest())
+               return false;
+   }
+ 
+   unsigned NumActualArgs = unsigned(CS.arg_end()-CS.arg_begin());
+   unsigned NumCommonArgs = std::min(FT->getNumParams(), NumActualArgs);
+                                     
+   CallSite::arg_iterator AI = CS.arg_begin();
+   for (unsigned i = 0, e = NumCommonArgs; i != e; ++i, ++AI) {
+     const Type *ParamTy = FT->getParamType(i);
+     bool isConvertible = (*AI)->getType()->isLosslesslyConvertibleTo(ParamTy);
+     if (Callee->isExternal() && !isConvertible) return false;    
+   }
+ 
+   if (FT->getNumParams() < NumActualArgs && !FT->isVarArg() &&
+       Callee->isExternal())
+     return false;   // Do not delete arguments unless we have a function body...
+ 
+   // Okay, we decided that this is a safe thing to do: go ahead and start
+   // inserting cast instructions as necessary...
+   std::vector<Value*> Args;
+   Args.reserve(NumActualArgs);
+ 
+   AI = CS.arg_begin();
+   for (unsigned i = 0; i != NumCommonArgs; ++i, ++AI) {
+     const Type *ParamTy = FT->getParamType(i);
+     if ((*AI)->getType() == ParamTy) {
+       Args.push_back(*AI);
+     } else {
+       Args.push_back(InsertNewInstBefore(new CastInst(*AI, ParamTy, "tmp"),
+                                          *Caller));
+     }
+   }
+ 
+   // If the function takes more arguments than the call was taking, add them
+   // now...
+   for (unsigned i = NumCommonArgs; i != FT->getNumParams(); ++i)
+     Args.push_back(Constant::getNullValue(FT->getParamType(i)));
+ 
+   // If we are removing arguments to the function, emit an obnoxious warning...
+   if (FT->getNumParams() < NumActualArgs)
+     if (!FT->isVarArg()) {
+       std::cerr << "WARNING: While resolving call to function '"
+                 << Callee->getName() << "' arguments were dropped!\n";
+     } else {
+       // Add all of the arguments in their promoted form to the arg list...
+       for (unsigned i = FT->getNumParams(); i != NumActualArgs; ++i, ++AI) {
+         const Type *PTy = getPromotedType((*AI)->getType());
+         if (PTy != (*AI)->getType()) {
+           // Must promote to pass through va_arg area!
+           Instruction *Cast = new CastInst(*AI, PTy, "tmp");
+           InsertNewInstBefore(Cast, *Caller);
+           Args.push_back(Cast);
+         } else {
+           Args.push_back(*AI);
+         }
+       }
+     }
+ 
+   if (FT->getReturnType() == Type::VoidTy)
+     Caller->setName("");   // Void type should not have a name...
+ 
+   Instruction *NC;
+   if (InvokeInst *II = dyn_cast<InvokeInst>(Caller)) {
+     NC = new InvokeInst(Callee, II->getNormalDest(), II->getUnwindDest(),
+                         Args, Caller->getName(), Caller);
+   } else {
+     NC = new CallInst(Callee, Args, Caller->getName(), Caller);
+   }
+ 
+   // Insert a cast of the return type as necessary...
+   Value *NV = NC;
+   if (Caller->getType() != NV->getType() && !Caller->use_empty()) {
+     if (NV->getType() != Type::VoidTy) {
+       NV = NC = new CastInst(NC, Caller->getType(), "tmp");
+ 
+       // If this is an invoke instruction, we should insert it after the first
+       // non-phi, instruction in the normal successor block.
+       if (InvokeInst *II = dyn_cast<InvokeInst>(Caller)) {
+         BasicBlock::iterator I = II->getNormalDest()->begin();
+         while (isa<PHINode>(I)) ++I;
+         InsertNewInstBefore(NC, *I);
+       } else {
+         // Otherwise, it's a call, just insert cast right after the call instr
+         InsertNewInstBefore(NC, *Caller);
+       }
+       AddUsersToWorkList(*Caller);
+     } else {
+       NV = Constant::getNullValue(Caller->getType());
+     }
+   }
+ 
+   if (Caller->getType() != Type::VoidTy && !Caller->use_empty())
+     Caller->replaceAllUsesWith(NV);
+   Caller->getParent()->getInstList().erase(Caller);
+   removeFromWorkList(Caller);
+   return true;
+ }
+ 
+ 
+ 
+ // PHINode simplification
+ //
+ Instruction *InstCombiner::visitPHINode(PHINode &PN) {
+   if (Value *V = hasConstantValue(&PN))
+     return ReplaceInstUsesWith(PN, V);
+ 
+   // If the only user of this instruction is a cast instruction, and all of the
+   // incoming values are constants, change this PHI to merge together the casted
+   // constants.
+   if (PN.hasOneUse())
+     if (CastInst *CI = dyn_cast<CastInst>(PN.use_back()))
+       if (CI->getType() != PN.getType()) {  // noop casts will be folded
+         bool AllConstant = true;
+         for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
+           if (!isa<Constant>(PN.getIncomingValue(i))) {
+             AllConstant = false;
+             break;
+           }
+         if (AllConstant) {
+           // Make a new PHI with all casted values.
+           PHINode *New = new PHINode(CI->getType(), PN.getName(), &PN);
+           for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
+             Constant *OldArg = cast<Constant>(PN.getIncomingValue(i));
+             New->addIncoming(ConstantExpr::getCast(OldArg, New->getType()),
+                              PN.getIncomingBlock(i));
+           }
+ 
+           // Update the cast instruction.
+           CI->setOperand(0, New);
+           WorkList.push_back(CI);    // revisit the cast instruction to fold.
+           WorkList.push_back(New);   // Make sure to revisit the new Phi
+           return &PN;                // PN is now dead!
+         }
+       }
+   return 0;
+ }
+ 
+ static Value *InsertSignExtendToPtrTy(Value *V, const Type *DTy,
+                                       Instruction *InsertPoint,
+                                       InstCombiner *IC) {
+   unsigned PS = IC->getTargetData().getPointerSize();
+   const Type *VTy = V->getType();
+   Instruction *Cast;
+   if (!VTy->isSigned() && VTy->getPrimitiveSize() < PS)
+     // We must insert a cast to ensure we sign-extend.
+     V = IC->InsertNewInstBefore(new CastInst(V, VTy->getSignedVersion(),
+                                              V->getName()), *InsertPoint);
+   return IC->InsertNewInstBefore(new CastInst(V, DTy, V->getName()),
+                                  *InsertPoint);
+ }
+ 
+ 
+ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
+   Value *PtrOp = GEP.getOperand(0);
+   // Is it 'getelementptr %P, long 0'  or 'getelementptr %P'
+   // If so, eliminate the noop.
+   if (GEP.getNumOperands() == 1)
+     return ReplaceInstUsesWith(GEP, PtrOp);
+ 
+   bool HasZeroPointerIndex = false;
+   if (Constant *C = dyn_cast<Constant>(GEP.getOperand(1)))
+     HasZeroPointerIndex = C->isNullValue();
+ 
+   if (GEP.getNumOperands() == 2 && HasZeroPointerIndex)
+     return ReplaceInstUsesWith(GEP, PtrOp);
+ 
+   // Eliminate unneeded casts for indices.
+   bool MadeChange = false;
+   gep_type_iterator GTI = gep_type_begin(GEP);
+   for (unsigned i = 1, e = GEP.getNumOperands(); i != e; ++i, ++GTI)
+     if (isa<SequentialType>(*GTI)) {
+       if (CastInst *CI = dyn_cast<CastInst>(GEP.getOperand(i))) {
+         Value *Src = CI->getOperand(0);
+         const Type *SrcTy = Src->getType();
+         const Type *DestTy = CI->getType();
+         if (Src->getType()->isInteger()) {
+           if (SrcTy->getPrimitiveSize() == DestTy->getPrimitiveSize()) {
+             // We can always eliminate a cast from ulong or long to the other.
+             // We can always eliminate a cast from uint to int or the other on
+             // 32-bit pointer platforms.
+             if (DestTy->getPrimitiveSize() >= TD->getPointerSize()) {
+               MadeChange = true;
+               GEP.setOperand(i, Src);
+             }
+           } else if (SrcTy->getPrimitiveSize() < DestTy->getPrimitiveSize() &&
+                      SrcTy->getPrimitiveSize() == 4) {
+             // We can always eliminate a cast from int to [u]long.  We can
+             // eliminate a cast from uint to [u]long iff the target is a 32-bit
+             // pointer target.
+             if (SrcTy->isSigned() || 
+                 SrcTy->getPrimitiveSize() >= TD->getPointerSize()) {
+               MadeChange = true;
+               GEP.setOperand(i, Src);
+             }
+           }
+         }
+       }
+       // If we are using a wider index than needed for this platform, shrink it
+       // to what we need.  If the incoming value needs a cast instruction,
+       // insert it.  This explicit cast can make subsequent optimizations more
+       // obvious.
+       Value *Op = GEP.getOperand(i);
+       if (Op->getType()->getPrimitiveSize() > TD->getPointerSize())
+         if (Constant *C = dyn_cast<Constant>(Op)) {
+           GEP.setOperand(i, ConstantExpr::getCast(C,
+                                      TD->getIntPtrType()->getSignedVersion()));
+           MadeChange = true;
+         } else {
+           Op = InsertNewInstBefore(new CastInst(Op, TD->getIntPtrType(),
+                                                 Op->getName()), GEP);
+           GEP.setOperand(i, Op);
+           MadeChange = true;
+         }
+ 
+       // If this is a constant idx, make sure to canonicalize it to be a signed
+       // operand, otherwise CSE and other optimizations are pessimized.
+       if (ConstantUInt *CUI = dyn_cast<ConstantUInt>(Op)) {
+         GEP.setOperand(i, ConstantExpr::getCast(CUI,
+                                           CUI->getType()->getSignedVersion()));
+         MadeChange = true;
+       }
+     }
+   if (MadeChange) return &GEP;
+ 
+   // Combine Indices - If the source pointer to this getelementptr instruction
+   // is a getelementptr instruction, combine the indices of the two
+   // getelementptr instructions into a single instruction.
+   //
+   std::vector<Value*> SrcGEPOperands;
+   if (GetElementPtrInst *Src = dyn_cast<GetElementPtrInst>(PtrOp)) {
+     SrcGEPOperands.assign(Src->op_begin(), Src->op_end());
+   } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(PtrOp)) {
+     if (CE->getOpcode() == Instruction::GetElementPtr)
+       SrcGEPOperands.assign(CE->op_begin(), CE->op_end());
+   }
+ 
+   if (!SrcGEPOperands.empty()) {
+     // Note that if our source is a gep chain itself that we wait for that
+     // chain to be resolved before we perform this transformation.  This
+     // avoids us creating a TON of code in some cases.
+     //
+     if (isa<GetElementPtrInst>(SrcGEPOperands[0]) &&
+         cast<Instruction>(SrcGEPOperands[0])->getNumOperands() == 2)
+       return 0;   // Wait until our source is folded to completion.
+ 
+     std::vector<Value *> Indices;
+ 
+     // Find out whether the last index in the source GEP is a sequential idx.
+     bool EndsWithSequential = false;
+     for (gep_type_iterator I = gep_type_begin(*cast<User>(PtrOp)),
+            E = gep_type_end(*cast<User>(PtrOp)); I != E; ++I)
+       EndsWithSequential = !isa<StructType>(*I);
+   
+     // Can we combine the two pointer arithmetics offsets?
+     if (EndsWithSequential) {
+       // Replace: gep (gep %P, long B), long A, ...
+       // With:    T = long A+B; gep %P, T, ...
+       //
+       Value *Sum, *SO1 = SrcGEPOperands.back(), *GO1 = GEP.getOperand(1);
+       if (SO1 == Constant::getNullValue(SO1->getType())) {
+         Sum = GO1;
+       } else if (GO1 == Constant::getNullValue(GO1->getType())) {
+         Sum = SO1;
+       } else {
+         // If they aren't the same type, convert both to an integer of the
+         // target's pointer size.
+         if (SO1->getType() != GO1->getType()) {
+           if (Constant *SO1C = dyn_cast<Constant>(SO1)) {
+             SO1 = ConstantExpr::getCast(SO1C, GO1->getType());
+           } else if (Constant *GO1C = dyn_cast<Constant>(GO1)) {
+             GO1 = ConstantExpr::getCast(GO1C, SO1->getType());
+           } else {
+             unsigned PS = TD->getPointerSize();
+             Instruction *Cast;
+             if (SO1->getType()->getPrimitiveSize() == PS) {
+               // Convert GO1 to SO1's type.
+               GO1 = InsertSignExtendToPtrTy(GO1, SO1->getType(), &GEP, this);
+ 
+             } else if (GO1->getType()->getPrimitiveSize() == PS) {
+               // Convert SO1 to GO1's type.
+               SO1 = InsertSignExtendToPtrTy(SO1, GO1->getType(), &GEP, this);
+             } else {
+               const Type *PT = TD->getIntPtrType();
+               SO1 = InsertSignExtendToPtrTy(SO1, PT, &GEP, this);
+               GO1 = InsertSignExtendToPtrTy(GO1, PT, &GEP, this);
+             }
+           }
+         }
+         if (isa<Constant>(SO1) && isa<Constant>(GO1))
+           Sum = ConstantExpr::getAdd(cast<Constant>(SO1), cast<Constant>(GO1));
+         else {
+           Sum = BinaryOperator::createAdd(SO1, GO1, PtrOp->getName()+".sum");
+           InsertNewInstBefore(cast<Instruction>(Sum), GEP);
+         }
+       }
+ 
+       // Recycle the GEP we already have if possible.
+       if (SrcGEPOperands.size() == 2) {
+         GEP.setOperand(0, SrcGEPOperands[0]);
+         GEP.setOperand(1, Sum);
+         return &GEP;
+       } else {
+         Indices.insert(Indices.end(), SrcGEPOperands.begin()+1,
+                        SrcGEPOperands.end()-1);
+         Indices.push_back(Sum);
+         Indices.insert(Indices.end(), GEP.op_begin()+2, GEP.op_end());
+       }
+     } else if (isa<Constant>(*GEP.idx_begin()) && 
+                cast<Constant>(*GEP.idx_begin())->isNullValue() &&
+                SrcGEPOperands.size() != 1) { 
+       // Otherwise we can do the fold if the first index of the GEP is a zero
+       Indices.insert(Indices.end(), SrcGEPOperands.begin()+1,
+                      SrcGEPOperands.end());
+       Indices.insert(Indices.end(), GEP.idx_begin()+1, GEP.idx_end());
+     }
+ 
+     if (!Indices.empty())
+       return new GetElementPtrInst(SrcGEPOperands[0], Indices, GEP.getName());
+ 
+   } else if (GlobalValue *GV = dyn_cast<GlobalValue>(PtrOp)) {
+     // GEP of global variable.  If all of the indices for this GEP are
+     // constants, we can promote this to a constexpr instead of an instruction.
+ 
+     // Scan for nonconstants...
+     std::vector<Constant*> Indices;
+     User::op_iterator I = GEP.idx_begin(), E = GEP.idx_end();
+     for (; I != E && isa<Constant>(*I); ++I)
+       Indices.push_back(cast<Constant>(*I));
+ 
+     if (I == E) {  // If they are all constants...
+       Constant *CE = ConstantExpr::getGetElementPtr(GV, Indices);
+ 
+       // Replace all uses of the GEP with the new constexpr...
+       return ReplaceInstUsesWith(GEP, CE);
+     }
+   } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(PtrOp)) {
+     if (CE->getOpcode() == Instruction::Cast) {
+       if (HasZeroPointerIndex) {
+         // transform: GEP (cast [10 x ubyte]* X to [0 x ubyte]*), long 0, ...
+         // into     : GEP [10 x ubyte]* X, long 0, ...
+         //
+         // This occurs when the program declares an array extern like "int X[];"
+         //
+         Constant *X = CE->getOperand(0);
+         const PointerType *CPTy = cast<PointerType>(CE->getType());
+         if (const PointerType *XTy = dyn_cast<PointerType>(X->getType()))
+           if (const ArrayType *XATy =
+               dyn_cast<ArrayType>(XTy->getElementType()))
+             if (const ArrayType *CATy =
+                 dyn_cast<ArrayType>(CPTy->getElementType()))
+               if (CATy->getElementType() == XATy->getElementType()) {
+                 // At this point, we know that the cast source type is a pointer
+                 // to an array of the same type as the destination pointer
+                 // array.  Because the array type is never stepped over (there
+                 // is a leading zero) we can fold the cast into this GEP.
+                 GEP.setOperand(0, X);
+                 return &GEP;
+               }
+       }
+     }
+   }
+ 
+   return 0;
+ }
+ 
+ Instruction *InstCombiner::visitAllocationInst(AllocationInst &AI) {
+   // Convert: malloc Ty, C - where C is a constant != 1 into: malloc [C x Ty], 1
+   if (AI.isArrayAllocation())    // Check C != 1
+     if (const ConstantUInt *C = dyn_cast<ConstantUInt>(AI.getArraySize())) {
+       const Type *NewTy = ArrayType::get(AI.getAllocatedType(), C->getValue());
+       AllocationInst *New = 0;
+ 
+       // Create and insert the replacement instruction...
+       if (isa<MallocInst>(AI))
+         New = new MallocInst(NewTy, 0, AI.getName());
+       else {
+         assert(isa<AllocaInst>(AI) && "Unknown type of allocation inst!");
+         New = new AllocaInst(NewTy, 0, AI.getName());
+       }
+ 
+       InsertNewInstBefore(New, AI);
+       
+       // Scan to the end of the allocation instructions, to skip over a block of
+       // allocas if possible...
+       //
+       BasicBlock::iterator It = New;
+       while (isa<AllocationInst>(*It)) ++It;
+ 
+       // Now that I is pointing to the first non-allocation-inst in the block,
+       // insert our getelementptr instruction...
+       //
+       std::vector<Value*> Idx(2, Constant::getNullValue(Type::IntTy));
+       Value *V = new GetElementPtrInst(New, Idx, New->getName()+".sub", It);
+ 
+       // Now make everything use the getelementptr instead of the original
+       // allocation.
+       return ReplaceInstUsesWith(AI, V);
+     }
+ 
+   // If alloca'ing a zero byte object, replace the alloca with a null pointer.
+   // Note that we only do this for alloca's, because malloc should allocate and
+   // return a unique pointer, even for a zero byte allocation.
+   if (isa<AllocaInst>(AI) && AI.getAllocatedType()->isSized() && 
+       TD->getTypeSize(AI.getAllocatedType()) == 0)
+     return ReplaceInstUsesWith(AI, Constant::getNullValue(AI.getType()));
+ 
+   return 0;
+ }
+ 
+ Instruction *InstCombiner::visitFreeInst(FreeInst &FI) {
+   Value *Op = FI.getOperand(0);
+ 
+   // Change free <ty>* (cast <ty2>* X to <ty>*) into free <ty2>* X
+   if (CastInst *CI = dyn_cast<CastInst>(Op))
+     if (isa<PointerType>(CI->getOperand(0)->getType())) {
+       FI.setOperand(0, CI->getOperand(0));
+       return &FI;
+     }
+ 
+   // If we have 'free null' delete the instruction.  This can happen in stl code
+   // when lots of inlining happens.
+   if (isa<ConstantPointerNull>(Op))
+     return EraseInstFromFunction(FI);
+ 
+   return 0;
+ }
+ 
+ 
+ /// GetGEPGlobalInitializer - Given a constant, and a getelementptr
+ /// constantexpr, return the constant value being addressed by the constant
+ /// expression, or null if something is funny.
+ ///
+ static Constant *GetGEPGlobalInitializer(Constant *C, ConstantExpr *CE) {
+   if (CE->getOperand(1) != Constant::getNullValue(CE->getOperand(1)->getType()))
+     return 0;  // Do not allow stepping over the value!
+ 
+   // Loop over all of the operands, tracking down which value we are
+   // addressing...
+   gep_type_iterator I = gep_type_begin(CE), E = gep_type_end(CE);
+   for (++I; I != E; ++I)
+     if (const StructType *STy = dyn_cast<StructType>(*I)) {
+       ConstantUInt *CU = cast<ConstantUInt>(I.getOperand());
+       assert(CU->getValue() < STy->getNumElements() &&
+              "Struct index out of range!");
+       if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C)) {
+         C = CS->getOperand(CU->getValue());
+       } else if (isa<ConstantAggregateZero>(C)) {
+ 	C = Constant::getNullValue(STy->getElementType(CU->getValue()));
+       } else {
+         return 0;
+       }
+     } else if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand())) {
+       const ArrayType *ATy = cast<ArrayType>(*I);
+       if ((uint64_t)CI->getRawValue() >= ATy->getNumElements()) return 0;
+       if (ConstantArray *CA = dyn_cast<ConstantArray>(C))
+         C = CA->getOperand(CI->getRawValue());
+       else if (isa<ConstantAggregateZero>(C))
+         C = Constant::getNullValue(ATy->getElementType());
+       else
+         return 0;
+     } else {
+       return 0;
+     }
+   return C;
+ }
+ 
+ static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI) {
+   User *CI = cast<User>(LI.getOperand(0));
+ 
+   const Type *DestPTy = cast<PointerType>(CI->getType())->getElementType();
+   if (const PointerType *SrcTy =
+       dyn_cast<PointerType>(CI->getOperand(0)->getType())) {
+     const Type *SrcPTy = SrcTy->getElementType();
+     if (SrcPTy->isSized() && DestPTy->isSized() &&
+         IC.getTargetData().getTypeSize(SrcPTy) == 
+             IC.getTargetData().getTypeSize(DestPTy) &&
+         (SrcPTy->isInteger() || isa<PointerType>(SrcPTy)) &&
+         (DestPTy->isInteger() || isa<PointerType>(DestPTy))) {
+       // Okay, we are casting from one integer or pointer type to another of
+       // the same size.  Instead of casting the pointer before the load, cast
+       // the result of the loaded value.
+       Value *NewLoad = IC.InsertNewInstBefore(new LoadInst(CI->getOperand(0),
+                                                            CI->getName(),
+                                                            LI.isVolatile()),LI);
+       // Now cast the result of the load.
+       return new CastInst(NewLoad, LI.getType());
+     }
+   }
+   return 0;
+ }
+ 
+ /// isSafeToLoadUnconditionally - Return true if we know that executing a load
+ /// from this value cannot trap.  If it is not obviously safe to load from the
+ /// specified pointer, we do a quick local scan of the basic block containing
+ /// ScanFrom, to determine if the address is already accessed.
+ static bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom) {
+   // If it is an alloca or global variable, it is always safe to load from.
+   if (isa<AllocaInst>(V) || isa<GlobalVariable>(V)) return true;
+ 
+   // Otherwise, be a little bit agressive by scanning the local block where we
+   // want to check to see if the pointer is already being loaded or stored
+   // from/to.  If so, the previous load or store would have already trapped,
+   // so there is no harm doing an extra load (also, CSE will later eliminate
+   // the load entirely).
+   BasicBlock::iterator BBI = ScanFrom, E = ScanFrom->getParent()->begin();
+ 
+   while (BBI != E) {
+     --BBI;
+ 
+     if (LoadInst *LI = dyn_cast<LoadInst>(BBI)) {
+       if (LI->getOperand(0) == V) return true;
+     } else if (StoreInst *SI = dyn_cast<StoreInst>(BBI))
+       if (SI->getOperand(1) == V) return true;
+     
+   }
+   return false;
+ }
+ 
+ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) {
+   Value *Op = LI.getOperand(0);
+ 
+   if (Constant *C = dyn_cast<Constant>(Op))
+     if (C->isNullValue() && !LI.isVolatile())  // load null -> 0
+       return ReplaceInstUsesWith(LI, Constant::getNullValue(LI.getType()));
+ 
+   // Instcombine load (constant global) into the value loaded...
+   if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Op))
+     if (GV->isConstant() && !GV->isExternal())
+       return ReplaceInstUsesWith(LI, GV->getInitializer());
+ 
+   // Instcombine load (constantexpr_GEP global, 0, ...) into the value loaded...
+   if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Op))
+     if (CE->getOpcode() == Instruction::GetElementPtr) {
+       if (GlobalVariable *GV = dyn_cast<GlobalVariable>(CE->getOperand(0)))
+         if (GV->isConstant() && !GV->isExternal())
+           if (Constant *V = GetGEPGlobalInitializer(GV->getInitializer(), CE))
+             return ReplaceInstUsesWith(LI, V);
+     } else if (CE->getOpcode() == Instruction::Cast) {
+       if (Instruction *Res = InstCombineLoadCast(*this, LI))
+         return Res;
+     }
+ 
+   // load (cast X) --> cast (load X) iff safe
+   if (CastInst *CI = dyn_cast<CastInst>(Op))
+     if (Instruction *Res = InstCombineLoadCast(*this, LI))
+       return Res;
+ 
+   if (!LI.isVolatile() && Op->hasOneUse()) {
+     // Change select and PHI nodes to select values instead of addresses: this
+     // helps alias analysis out a lot, allows many others simplifications, and
+     // exposes redundancy in the code.
+     //
+     // Note that we cannot do the transformation unless we know that the
+     // introduced loads cannot trap!  Something like this is valid as long as
+     // the condition is always false: load (select bool %C, int* null, int* %G),
+     // but it would not be valid if we transformed it to load from null
+     // unconditionally.
+     //
+     if (SelectInst *SI = dyn_cast<SelectInst>(Op)) {
+       // load (select (Cond, &V1, &V2))  --> select(Cond, load &V1, load &V2).
+       if (isSafeToLoadUnconditionally(SI->getOperand(1), SI) &&
+           isSafeToLoadUnconditionally(SI->getOperand(2), SI)) {
+         Value *V1 = InsertNewInstBefore(new LoadInst(SI->getOperand(1),
+                                      SI->getOperand(1)->getName()+".val"), LI);
+         Value *V2 = InsertNewInstBefore(new LoadInst(SI->getOperand(2),
+                                      SI->getOperand(2)->getName()+".val"), LI);
+         return new SelectInst(SI->getCondition(), V1, V2);
+       }
+ 
+       // load (select (cond, null, P)) -> load P
+       if (Constant *C = dyn_cast<Constant>(SI->getOperand(1)))
+         if (C->isNullValue()) {
+           LI.setOperand(0, SI->getOperand(2));
+           return &LI;
+         }
+ 
+       // load (select (cond, P, null)) -> load P
+       if (Constant *C = dyn_cast<Constant>(SI->getOperand(2)))
+         if (C->isNullValue()) {
+           LI.setOperand(0, SI->getOperand(1));
+           return &LI;
+         }
+ 
+     } else if (PHINode *PN = dyn_cast<PHINode>(Op)) {
+       // load (phi (&V1, &V2, &V3))  --> phi(load &V1, load &V2, load &V3)
+       bool Safe = PN->getParent() == LI.getParent();
+ 
+       // Scan all of the instructions between the PHI and the load to make
+       // sure there are no instructions that might possibly alter the value
+       // loaded from the PHI.
+       if (Safe) {
+         BasicBlock::iterator I = &LI;
+         for (--I; !isa<PHINode>(I); --I)
+           if (isa<StoreInst>(I) || isa<CallInst>(I)) {
+             Safe = false;
+             break;
+           }
+       }
+ 
+       for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e && Safe; ++i)
+         if (!isSafeToLoadUnconditionally(PN->getIncomingValue(i),
+                                     PN->getIncomingBlock(i)->getTerminator()))
+           Safe = false;
+ 
+       if (Safe) {
+         // Create the PHI.
+         PHINode *NewPN = new PHINode(LI.getType(), PN->getName());
+         InsertNewInstBefore(NewPN, *PN);
+         std::map<BasicBlock*,Value*> LoadMap;  // Don't insert duplicate loads
+ 
+         for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
+           BasicBlock *BB = PN->getIncomingBlock(i);
+           Value *&TheLoad = LoadMap[BB];
+           if (TheLoad == 0) {
+             Value *InVal = PN->getIncomingValue(i);
+             TheLoad = InsertNewInstBefore(new LoadInst(InVal,
+                                                        InVal->getName()+".val"),
+                                           *BB->getTerminator());
+           }
+           NewPN->addIncoming(TheLoad, BB);
+         }
+         return ReplaceInstUsesWith(LI, NewPN);
+       }
+     }
+   }
+   return 0;
+ }
+ 
+ 
+ Instruction *InstCombiner::visitBranchInst(BranchInst &BI) {
+   // Change br (not X), label True, label False to: br X, label False, True
+   Value *X;
+   BasicBlock *TrueDest;
+   BasicBlock *FalseDest;
+   if (match(&BI, m_Br(m_Not(m_Value(X)), TrueDest, FalseDest)) &&
+       !isa<Constant>(X)) {
+     // Swap Destinations and condition...
+     BI.setCondition(X);
+     BI.setSuccessor(0, FalseDest);
+     BI.setSuccessor(1, TrueDest);
+     return &BI;
+   }
+ 
+   // Cannonicalize setne -> seteq
+   Instruction::BinaryOps Op; Value *Y;
+   if (match(&BI, m_Br(m_SetCond(Op, m_Value(X), m_Value(Y)),
+                       TrueDest, FalseDest)))
+     if ((Op == Instruction::SetNE || Op == Instruction::SetLE ||
+          Op == Instruction::SetGE) && BI.getCondition()->hasOneUse()) {
+       SetCondInst *I = cast<SetCondInst>(BI.getCondition());
+       std::string Name = I->getName(); I->setName("");
+       Instruction::BinaryOps NewOpcode = SetCondInst::getInverseCondition(Op);
+       Value *NewSCC =  BinaryOperator::create(NewOpcode, X, Y, Name, I);
+       // Swap Destinations and condition...
+       BI.setCondition(NewSCC);
+       BI.setSuccessor(0, FalseDest);
+       BI.setSuccessor(1, TrueDest);
+       removeFromWorkList(I);
+       I->getParent()->getInstList().erase(I);
+       WorkList.push_back(cast<Instruction>(NewSCC));
+       return &BI;
+     }
+   
+   return 0;
+ }
+ 
+ Instruction *InstCombiner::visitSwitchInst(SwitchInst &SI) {
+   Value *Cond = SI.getCondition();
+   if (Instruction *I = dyn_cast<Instruction>(Cond)) {
+     if (I->getOpcode() == Instruction::Add)
+       if (ConstantInt *AddRHS = dyn_cast<ConstantInt>(I->getOperand(1))) {
+         // change 'switch (X+4) case 1:' into 'switch (X) case -3'
+         for (unsigned i = 2, e = SI.getNumOperands(); i != e; i += 2)
+           SI.setOperand(i, ConstantExpr::getSub(cast<Constant>(SI.getOperand(i)),
+                                                 AddRHS));
+         SI.setOperand(0, I->getOperand(0));
+         WorkList.push_back(I);
+         return &SI;
+       }
+   }
+   return 0;
+ }
+ 
+ 
+ void InstCombiner::removeFromWorkList(Instruction *I) {
+   WorkList.erase(std::remove(WorkList.begin(), WorkList.end(), I),
+                  WorkList.end());
+ }
+ 
+ bool InstCombiner::runOnFunction(Function &F) {
+   bool Changed = false;
+   TD = &getAnalysis<TargetData>();
+ 
+   for (inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i)
+     WorkList.push_back(&*i);
+ 
+ 
+   while (!WorkList.empty()) {
+     Instruction *I = WorkList.back();  // Get an instruction from the worklist
+     WorkList.pop_back();
+ 
+     // Check to see if we can DCE or ConstantPropagate the instruction...
+     // Check to see if we can DIE the instruction...
+     if (isInstructionTriviallyDead(I)) {
+       // Add operands to the worklist...
+       if (I->getNumOperands() < 4)
+         AddUsesToWorkList(*I);
+       ++NumDeadInst;
+ 
+       I->getParent()->getInstList().erase(I);
+       removeFromWorkList(I);
+       continue;
+     }
+ 
+     // Instruction isn't dead, see if we can constant propagate it...
+     if (Constant *C = ConstantFoldInstruction(I)) {
+       // Add operands to the worklist...
+       AddUsesToWorkList(*I);
+       ReplaceInstUsesWith(*I, C);
+ 
+       ++NumConstProp;
+       I->getParent()->getInstList().erase(I);
+       removeFromWorkList(I);
+       continue;
+     }
+ 
+     // Now that we have an instruction, try combining it to simplify it...
+     if (Instruction *Result = visit(*I)) {
+       ++NumCombined;
+       // Should we replace the old instruction with a new one?
+       if (Result != I) {
+         DEBUG(std::cerr << "IC: Old = " << *I
+                         << "    New = " << *Result);
+ 
+         // Everything uses the new instruction now.
+         I->replaceAllUsesWith(Result);
+ 
+         // Push the new instruction and any users onto the worklist.
+         WorkList.push_back(Result);
+         AddUsersToWorkList(*Result);
+ 
+         // Move the name to the new instruction first...
+         std::string OldName = I->getName(); I->setName("");
+         Result->setName(OldName);
+ 
+         // Insert the new instruction into the basic block...
+         BasicBlock *InstParent = I->getParent();
+         InstParent->getInstList().insert(I, Result);
+ 
+         // Make sure that we reprocess all operands now that we reduced their
+         // use counts.
+         for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
+           if (Instruction *OpI = dyn_cast<Instruction>(I->getOperand(i)))
+             WorkList.push_back(OpI);
+ 
+         // Instructions can end up on the worklist more than once.  Make sure
+         // we do not process an instruction that has been deleted.
+         removeFromWorkList(I);
+ 
+         // Erase the old instruction.
+         InstParent->getInstList().erase(I);
+       } else {
+         DEBUG(std::cerr << "IC: MOD = " << *I);
+ 
+         // If the instruction was modified, it's possible that it is now dead.
+         // if so, remove it.
+         if (isInstructionTriviallyDead(I)) {
+           // Make sure we process all operands now that we are reducing their
+           // use counts.
+           for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
+             if (Instruction *OpI = dyn_cast<Instruction>(I->getOperand(i)))
+               WorkList.push_back(OpI);
+           
+           // Instructions may end up in the worklist more than once.  Erase all
+           // occurrances of this instruction.
+           removeFromWorkList(I);
+           I->getParent()->getInstList().erase(I);
+         } else {
+           WorkList.push_back(Result);
+           AddUsersToWorkList(*Result);
+         }
+       }
+       Changed = true;
+     }
+   }
+ 
+   return Changed;
+ }
+ 
+ FunctionPass *llvm::createInstructionCombiningPass() {
+   return new InstCombiner();
+ }
+ 


Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/Makefile
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/Makefile:1.1
*** /dev/null	Tue Oct  5 13:03:12 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/Makefile	Tue Oct  5 13:02:58 2004
***************
*** 0 ****
--- 1,6 ----
+ LEVEL = ../../../..
+ 
+ PROG = agrep
+ RUN_OPTIONS = -2 int $(BUILD_SRC_DIR)/InstructionCombining.cpp.txt
+ include $(LEVEL)/MultiSource/Makefile.multisrc
+ 


Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/README
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/README:1.1
*** /dev/null	Tue Oct  5 13:03:12 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/README	Tue Oct  5 13:02:58 2004
***************
*** 0 ****
--- 1,88 ----
+ This is version 2.04 of agrep - a new tool for fast 
+ text searching allowing errors.
+ agrep is similar to egrep (or grep or fgrep), but it is much more general
+ (and usually faster).
+ The main changes from version 1.1 are 1) incorporating Boyer-Moore
+ type filtering to speed up search considerably, 2) allowing multi patterns 
+ via the -f option; this is similar to fgrep, but from our experience 
+ agrep is much faster, 3) searching for "best match" without having to
+ specify the number of errors allowed, and 4) ascii is no longer required.
+ Several more options were added.
+ 
+ To compile, simply run make in the agrep directory after untar'ing
+ the tar file (tar -xf agrep-2.04.tar will do it).
+ 
+ The three most significant features of agrep that are not supported by
+ the grep family are 
+ 1) the ability to search for approximate patterns;
+     for example, "agrep -2 homogenos foo" will find homogeneous as well 
+     as any other word that can be obtained from homogenos with at most 
+     2 substitutions, insertions, or deletions.
+     "agrep -B homogenos foo" will generate a message of the form
+     best match has 2 errors, there are 5 matches, output them? (y/n)
+ 2) agrep is record oriented rather than just line oriented;  a record
+     is by default a line, but it can be user defined;
+     for example, "agrep -d '^From ' 'pizza' mbox"
+     outputs all mail messages that contain the keyword "pizza".
+     Another example:  "agrep -d '$$' pattern foo" will output all
+     paragraphs (separated by an empty line) that contain pattern.
+ 3) multiple patterns with AND (or OR) logic queries.   
+     For example, "agrep -d '^From ' 'burger,pizza' mbox" 
+     outputs all mail messages containing at least one of the 
+     two keywords (, stands for OR).
+     "agrep -d '^From ' 'good;pizza' mbox" outputs all mail messages
+     containing both keywords.
+ 
+ Putting these options together one can ask queries like
+ 
+ agrep -d '$$' -2 '<CACM>;TheAuthor;Curriculum;<198[5-9]>' bib
+ 
+ which outputs all paragraphs referencing articles in CACM between 
+ 1985 and 1989 by TheAuthor dealing with curriculum.  
+ Two errors are allowed, but they cannot be in either CACM or the year 
+ (the <> brackets forbid errors in the pattern between them).  
+ 
+ Other features include searching for regular expressions (with or
+ without errors), unlimited wild cards, limiting the errors to only 
+ insertions or only substitutions or any combination, 
+ allowing each deletion, for example, to be counted as, say, 
+ 2 substitutions or 3 insertions, restricting parts of the query 
+ to be exact and parts to be approximate, and many more.
+ 
+ agrep is available by anonymous ftp from cs.arizona.edu (IP 192.12.69.5)
+ as agrep/agrep-2.04.tar.Z (or in uncompressed form as agrep/agrep-2.04.tar).
+ The tar file contains the source code (in C), man pages (agrep.1),
+ and two additional files, agrep.algorithms and agrep.chronicle,
+ giving more information.
+ The agrep directory also includes two postscript files: 
+ agrep.ps.1 is a technical report from June 1991 
+ describing the design and implementation of agrep;
+ agrep.ps.2 is a copy of the paper as appeared in the 1992
+ Winter USENIX conference.
+ 
+ Please mail bug reports (or any other comments) 
+ to sw at cs.arizona.edu or to udi at cs.arizona.edu.
+ 
+ We would appreciate if users notify us (at the address above)
+ of any extensions, improvements, or interesting uses of this software.
+ 
+ January 17, 1992
+ 
+ 
+ BUGS_fixed/option_update
+ 
+ 1. remove multiple definitions of some global variables.
+ 2. fix a bug in -G option.
+ 3. fix a bug in -w option.
+ January 23, 1992
+ 
+ 4. fix a bug in pipeline input.
+ 5. make the definition of word-delimiter consistant.
+ March 16, 1992
+ 
+ 6. add option '-y' which, if specified with -B option, will always
+ output the best-matches without a prompt.
+ April 10, 1992
+ 
+ 7. fix a bug regarding exit status.
+ April 15, 1992


Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/agrep


Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/agrep.h
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/agrep.h:1.1
*** /dev/null	Tue Oct  5 13:03:12 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/agrep.h	Tue Oct  5 13:02:58 2004
***************
*** 0 ****
--- 1,56 ----
+ #include <stdio.h>
+ #include <math.h>
+ #include <ctype.h>
+ #include "re.h"
+ /*
+ extern unsigned char *strcpy(), *strncpy(), *strcat();
+ extern int strlen();
+ */
+ #include <string.h>
+ #define CHAR	unsigned char
+ #define MAXPAT 128
+ #define MAXPATT 256
+ #define MAXDELIM 8            /* Max size of a delimiter pattern */
+ #define SHORTREG 15
+ #define MAXREG   30
+ #define MAXNAME  256
+ #define Max_Pats 12    /* max num of patterns */
+ #define Max_Keys 12    /* max num of keywords */
+ #define Max_Psize 128  /* max size of a pattern counting all the characters */
+ #define Max_Keyword 31 /* the max size of a keyword */
+ #define WORD 32        /* the size of a word */
+ #define MaxError 8     /* the max number of errors allowed */
+ #define MaxRerror 4    /* the max number of erros for regular expression */
+ #define MaxDelimit 16   /* the max raw length of a user defined delimiter */
+ #define BlockSize  49152
+ #define Max_record 49152
+ #define SIZE 16384       /* BlockSIze in sgrep */
+ #define MAXLINE   1024  /* maxline in sgrep */
+ #define Maxline   1024
+ #define RBLOCK    8192
+ #define RMAXLINE  1024
+ #define MaxNext   66000
+ #define ON 1
+ #define OFF 0
+ #define Compl 1
+ #define Maxresult 10000
+ #define MaxCan 2500
+ #define MAXSYM 256 /* ASCII */
+ #define WORDB     241    /* -w option */
+ #define LPARENT   242    /* ( */
+ #define RPARENT   243    /* ) */
+ #define LRANGE    244    /* [ */
+ #define RRANGE    245    /* ] */
+ #define LANGLE    246    /* < */
+ #define RANGLE    247    /* > */
+ #define NOTSYM    248    /* ^ */
+ #define WILDCD    249    /* wildcard */
+ #define ORSYM     250   /* | */
+ #define ORPAT     251   /* , */
+ #define ANDPAT    252   /* ; */
+ #define STAR      253   /* closure */
+ #define HYPHEN    237   /* - */
+ #define NOCARE    238   /* . */
+ #define NNLINE    239   /* special symbol for newline in begin of pattern*/
+                        /* matches '\n' and NNLINE */
+ 


Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/asearch.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/asearch.c:1.1
*** /dev/null	Tue Oct  5 13:03:12 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/asearch.c	Tue Oct  5 13:02:58 2004
***************
*** 0 ****
--- 1,315 ----
+ /* Copyright (c) 1991 Sun Wu and Udi Manber.  All Rights Reserved. */
+ #include "agrep.h"
+ 
+ extern unsigned Init1, Init[], Mask[], endposition, D_endpos, AND, NO_ERR_MASK;
+ extern int DELIMITER, FILENAMEONLY, INVERSE;
+ extern CHAR CurrentFileName[];
+ extern int I, num_of_matched, TRUNCATE;
+ 
+ extern int fill_buf(int fd, unsigned char *buf, int record_size);
+ extern void output(register CHAR *buffer, int i1, int i2, int j);
+ 
+ void asearch0(CHAR old_D_pat[], int text, register unsigned D)
+ {
+   register unsigned i, c, r1, r2, CMask, r_NO_ERR, r_Init1,  end, endpos; 
+   unsigned A[MaxError+2], B[MaxError+2];
+   unsigned D_Mask;
+   int D_length, FIRSTROUND, ResidueSize, lasti, l, k, j=0;
+   int printout_end;
+   CHAR buffer[BlockSize+Max_record+1];
+   
+   D_length = strlen(old_D_pat);
+   buffer[Max_record-1] = '\n';
+   D_Mask = D_endpos;
+   for ( i=1; i<D_length; i++) D_Mask = (D_Mask<<1) | D_Mask;
+   D_Mask = ~D_Mask;
+ 
+   r_Init1 = Init1; /* put Init1 in register */
+   r_NO_ERR = NO_ERR_MASK; /* put NO_ERR_MASK in register */
+   endpos = D_endpos;    
+   FIRSTROUND = ON;
+   for(k=0; k<=D; k++) A[k] = B[k] = Init[0];
+   lasti = Max_record;
+ 
+   while ((l = fill_buf(text, buffer + Max_record, Max_record)) > 0)
+   { i = Max_record; end = Max_record + l ;
+     if (FIRSTROUND) { 
+         i = Max_record - 1;
+         FIRSTROUND = OFF; }
+     if (l < BlockSize) {
+         strncpy(buffer+end, old_D_pat, D_length);
+         buffer[end+D_length] = '\0';
+         end = end + D_length; }
+     while (i < end )
+     {
+         c = buffer[i++];
+         CMask = Mask[c];
+               r1 = B[0] & r_Init1;
+               A[0] = (((B[0] >> 1)) & CMask | r1 ) ;
+               for(k=1; k<=D; k++) {
+                      r1 = r_Init1 & B[k];
+                      r2 = B[k-1] | (((A[k-1]|B[k-1])>>1) & r_NO_ERR);
+                      A[k] = ((B[k] >> 1) & CMask) | r2 | r1;
+               }
+         if(A[0] & endpos) {
+            j++;  
+            r1 = A[D];
+            if(((AND == 1) && ((r1 & endposition) == endposition)) ||                           ((AND == 0) && (r1 & endposition)) ^ INVERSE )
+                  {    
+                       if(FILENAMEONLY) {
+                          num_of_matched++;
+                          printf("%s\n", CurrentFileName);
+                          return;  }
+                       printout_end = i - D_length - 1;           
+                       if(!(lasti >= Max_record + l - 1))
+                          output(buffer, lasti, printout_end, j);
+                  }
+            lasti = i - D_length; /* point to starting position of D_pat */
+            for(k=0; k<= D; k++) {
+               B[k] = Init[0];
+            }
+            r1 = B[0] & r_Init1;
+            A[0] = (((B[0]>>1) & CMask) | r1) & D_Mask;
+            for(k=1; k<= D; k++) {
+               r1 = Init1 & B[k];
+               r2 = B[k-1] | (((A[k-1] | B[k-1])>>1)&r_NO_ERR);
+               A[k] = (((B[k]>>1)&CMask) | r1 | r2) ;
+            }
+         }
+         c = buffer[i++];
+         CMask = Mask[c];
+               r1   = r_Init1 & A[0];
+               B[0] = ((A[0] >> 1 ) & CMask) | r1;
+               for(k=1; k<=D; k++) {
+                      r1 = r_Init1 & A[k];
+                      r2 = A[k-1] | (((A[k-1]|B[k-1])>>1) & r_NO_ERR);
+                      B[k] = ((A[k] >> 1) & CMask) | r2 | r1;
+               }
+         if(B[0] & endpos) {
+            j++;  
+            r1 = B[D];
+            if(((AND == 1) && ((r1 & endposition) == endposition)) ||                           ((AND == 0) && (r1 & endposition)) ^ INVERSE )
+                  { 
+                     if(FILENAMEONLY) {
+                        num_of_matched++;
+                        printf("%s\n", CurrentFileName);
+                        return; }
+                     printout_end = i - D_length -1 ; 
+                     if(!(lasti >= Max_record + l - 1))
+                        output(buffer, lasti, printout_end, j);
+                  }
+            lasti = i - D_length ;
+            for(k=0; k<= D; k++) {
+               A[k] = Init[0];
+            }
+            r1 = A[0] & r_Init1; 
+            B[0] = (((A[0]>>1)&CMask) | r1) & D_Mask;
+            for(k=1; k<= D; k++) {
+               r1 = r_Init1 & A[k];
+               r2 = A[k-1] | (((A[k-1] | B[k-1])>>1)&r_NO_ERR);
+               B[k] = (((A[k]>>1)&CMask) | r1 | r2) ;
+            }
+         }
+     }
+     if(l < BlockSize) {
+            lasti = Max_record;
+     }
+     else {
+        ResidueSize = Max_record + l - lasti;
+        if(ResidueSize > Max_record) {
+           ResidueSize = Max_record;
+           TRUNCATE = ON;         }
+        strncpy(buffer+Max_record-ResidueSize, buffer+lasti, ResidueSize);
+        lasti = Max_record - ResidueSize;
+        if(lasti == 0)     lasti = 1; 
+     }
+   }
+   return;
+ }
+ 
+ void asearch(CHAR old_D_pat[], int text, register unsigned D)
+ {
+   register unsigned i, c, r1, r2, CMask, r_NO_ERR, r_Init1; 
+   register unsigned A0, B0, A1, B1, endpos;
+   unsigned A2, B2, A3, B3, A4, B4;
+   unsigned A[MaxError+1], B[MaxError+1];
+   unsigned D_Mask;
+   unsigned end;
+   int D_length, FIRSTROUND, ResidueSize, lasti, l, k, j=0;
+   int printout_end;
+   CHAR buffer[2*Max_record+1];
+      
+   if (I == 0) Init1 = 037777777777;
+   if(D > 4) {
+          asearch0(old_D_pat, text, D); 
+          return;  }
+   D_length = strlen(old_D_pat);
+   buffer[Max_record-1] = '\n';
+   D_Mask = D_endpos;
+   for ( i=1; i<D_length; i++) D_Mask = (D_Mask<<1) | D_Mask;
+   D_Mask = ~D_Mask;
+ 
+   r_Init1 = Init1; /* put Init1 in register */
+   r_NO_ERR = NO_ERR_MASK; /* put NO_ERR_MASK in register */
+   endpos = D_endpos;    
+   FIRSTROUND = ON;
+   A0 = B0 = A1 = B1 = A2 = B2 = A3 = B3 = A4 = B4 = Init[0];
+   for(k=0; k<=D; k++) A[k] = B[k] = Init[0];
+   lasti = Max_record;
+ 
+   while ((l = fill_buf(text, buffer + Max_record, Max_record)) > 0)
+   { i = Max_record; end = Max_record + l ;
+     if (FIRSTROUND) { 
+         i = Max_record - 1;
+ 	if(DELIMITER) {
+ 		for(k=0; k<D_length; k++) {
+ 					if(old_D_pat[k] != buffer[Max_record+k]) 						break;
+ 		}
+ 		if(k>=D_length) j--;
+ 	}
+         FIRSTROUND = OFF; }
+     if (l < BlockSize) {
+         strncpy(buffer+end, old_D_pat, D_length);
+         buffer[end+D_length] = '\0';
+         end = end + D_length; }
+     while (i < end )
+     {
+         c = buffer[i];
+         CMask = Mask[c];
+               r1 = r_Init1 & B0;
+               A0 = ((B0 >>1 ) & CMask) | r1;
+               r1 = r_Init1 & B1;
+               r2 =  B0 | (((A0 | B0) >> 1) & r_NO_ERR); 
+               A1 = ((B1 >>1 ) & CMask) | r2 | r1 ;  
+                      if(D == 1) goto Nextchar;
+               r1 = r_Init1 & B2;
+               r2 =  B1 | (((A1 | B1) >> 1) & r_NO_ERR); 
+               A2 = ((B2 >>1 ) & CMask) | r2 | r1 ;  
+                      if(D == 2) goto Nextchar;
+               r1 = r_Init1 & B3;
+               r2 =  B2 | (((A2 | B2) >> 1) & r_NO_ERR); 
+               A3 = ((B3 >>1 ) & CMask) | r2 | r1 ;  
+                      if(D == 3) goto Nextchar;
+               r1 = r_Init1 & B4;
+               r2 =  B3 | (((A3 | B3) >> 1) & r_NO_ERR); 
+               A4 = ((B4 >>1 ) & CMask) | r2 | r1 ;  
+                      if(D == 4) goto Nextchar;
+ Nextchar: i=i+1;
+         if(A0 & endpos) {
+            j++;  r1 = A0;
+            if ( D == 1) r1 = A1;
+            if ( D == 2) r1 = A2;
+            if ( D == 3) r1 = A3;
+            if ( D == 4) r1 = A4;
+            if(((AND == 1) && ((r1 & endposition) == endposition)) ||                           ((AND == 0) && (r1 & endposition)) ^ INVERSE )
+                  {    
+                       if(FILENAMEONLY) {
+                          num_of_matched++;
+                          printf("%s\n", CurrentFileName);
+                          return;  }
+                       printout_end = i - D_length - 1;           
+                       if(!(lasti >= Max_record + l - 1))
+                          output(buffer, lasti, printout_end, j);
+                  }
+            lasti = i - D_length; /* point to starting position of D_pat */
+            TRUNCATE = OFF;
+            for(k=0; k<= D; k++) {
+               B[k] = Init[0];
+            }
+            r1 = B[0] & Init1;
+            A[0] = (((B[0]>>1) & CMask) | r1) & D_Mask;
+            for(k=1; k<= D; k++) {
+               r1 = Init1 & B[k];
+               r2 = B[k-1] | (((A[k-1] | B[k-1])>>1)&r_NO_ERR);
+               A[k] = (((B[k]>>1)&CMask) | r1 | r2) ;
+            }
+            A0 = A[0]; B0 = B[0]; A1 = A[1]; B1 = B[1]; A2 = A[2]; B2 = B[2];
+            A3 = A[3]; B3 = B[3]; A4 = A[4]; B4 = B[4];
+         }
+         c = buffer[i];
+         CMask = Mask[c];
+               r1 = r_Init1 & A0;
+               B0 = ((A0 >> 1 ) & CMask) | r1;
+ #ifdef DEBUG
+ 	printf("Mask = %o, B0 = %o\n", CMask, B0);
+ #endif
+               r1 = r_Init1 & A1;
+               r2 =  A0 | (((A0 | B0) >> 1) & r_NO_ERR); 
+               B1 = ((A1 >>1 ) & CMask) | r2 | r1 ;  
+                      if(D == 1) goto Nextchar1;
+               r1 = r_Init1 & A2;
+               r2 =  A1 | (((A1 | B1) >> 1) & r_NO_ERR); 
+               B2 = ((A2 >>1 ) & CMask) | r2 | r1 ;  
+                      if(D == 2) goto Nextchar1;
+               r1 = r_Init1 & A3;
+               r2 =  A2 | (((A2 | B2) >> 1) & r_NO_ERR); 
+               B3 = ((A3 >>1 ) & CMask) | r2 | r1 ;  
+                      if(D == 3) goto Nextchar1;
+               r1 = r_Init1 & A4;
+               r2 =  A3 | (((A3 | B3) >> 1) & r_NO_ERR); 
+               B4 = ((A4 >>1 ) & CMask) | r2 | r1 ;  
+                      if(D == 4) goto Nextchar1;
+ Nextchar1: i=i+1;
+         if(B0 & endpos) {
+            j++;  r1 = B0;
+            if ( D == 1) r1 = B1;
+            if ( D == 2) r1 = B2;
+            if ( D == 3) r1 = B3;
+            if ( D == 4) r1 = B4;
+            if(((AND == 1) && ((r1 & endposition) == endposition)) ||                           ((AND == 0) && (r1 & endposition)) ^ INVERSE )
+                  { 
+                     if(FILENAMEONLY) {
+                        num_of_matched++;
+                        printf("%s\n", CurrentFileName);
+                        return; }
+                     printout_end = i - D_length -1 ; 
+                     if(!(lasti >= Max_record + l - 1))
+                        output(buffer, lasti, printout_end, j);
+                  }
+            lasti = i - D_length ;
+            TRUNCATE = OFF;
+            for(k=0; k<= D; k++) {
+               A[k] = Init[0];
+            }
+            r1 = A[0] & Init1; 
+            B[0] = (((A[0]>>1)&CMask) | r1) & D_Mask;
+            for(k=1; k<= D; k++) {
+               r1 = Init1 & A[k];
+               r2 = A[k-1] | (((A[k-1] | B[k-1])>>1)&r_NO_ERR);
+               B[k] = (((A[k]>>1)&CMask) | r1 | r2) ;
+            }
+            A0 = A[0]; B0 = B[0]; A1 = A[1]; B1 = B[1]; A2 = A[2]; B2 = B[2];
+            A3 = A[3]; B3 = B[3]; A4 = A[4]; B4 = B[4];
+         }
+     }
+     if(l < BlockSize) {
+            lasti = Max_record ;
+     }
+     else {
+        ResidueSize = Max_record + l - lasti;
+        if(ResidueSize > Max_record) {
+           ResidueSize = Max_record;
+           TRUNCATE = ON;         }
+        strncpy(buffer+Max_record-ResidueSize, buffer+lasti, ResidueSize);
+        lasti = Max_record - ResidueSize;
+        if(lasti == 0)     lasti = 1; 
+     }
+   }
+   return;
+ }
+ 
+ 
+ 
+ 
+ /*
+ int fill_buf(int fd, unsigned char *buf, int record_size)
+ {
+ int num_read=1;
+ int total_read=0;
+ 	while(total_read < record_size && num_read > 0) {
+ 		num_read = read(fd, buf+total_read, 4096);
+ 		total_read = total_read + num_read;
+ 	}
+ 	return(total_read);
+ }
+ */


Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/asearch1.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/asearch1.c:1.1
*** /dev/null	Tue Oct  5 13:03:12 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/asearch1.c	Tue Oct  5 13:02:58 2004
***************
*** 0 ****
--- 1,132 ----
+ /* Copyright (c) 1991 Sun Wu and Udi Manber.  All Rights Reserved. */
+ #include "agrep.h"
+  
+ extern unsigned Init1, Init[], Mask[], endposition, D_endpos;
+ extern unsigned NO_ERR_MASK;
+ extern int TRUNCATE, DELIMITER, AND, I, S, DD, INVERSE, FILENAMEONLY ;
+ extern char CurrentFileName[];
+ extern int num_of_matched;
+ 
+ extern int fill_buf(int fd, unsigned char *buf, int record_size);
+ extern void output(register CHAR *buffer, int i1, int i2, int j);
+ 
+ void asearch1(char old_D_pat[], int Text, register unsigned D)
+ {
+   register unsigned end, i, r1, r3, r4, r5, CMask, D_Mask, k, endpos; 
+   register unsigned r_NO_ERR;
+   unsigned A[MaxError*2+1], B[MaxError*2+1];
+   int D_length, ResidueSize, lasti, num_read,  FIRSTROUND, j=0;
+   char buffer[BlockSize+Max_record+1];
+    
+   if(I == 0) Init1 = 037777777777;
+   if(DD > D) DD = D+1;
+   if(I  > D) I  = D+1;
+   if(S  > D) S  = D+1;
+   D_length = strlen(old_D_pat);
+   buffer[Max_record-1] = '\n';
+    
+   lasti = Max_record;
+   r_NO_ERR = NO_ERR_MASK;
+ 
+   D_Mask = D_endpos;
+   for(i=1 ; i<D_length; i++) D_Mask = (D_Mask << 1) | D_Mask;
+   D_Mask = ~D_Mask;
+   endpos = D_endpos;
+   r3 = D+1; r4 = D*2;  /* to make sure in register */
+   for(k=0; k < D;   k++) A[k] = B[k] = 0;
+   for(k=D; k <= r4; k++) A[k] = B[k] = Init[0];
+    
+   while ((num_read = fill_buf(Text, buffer + Max_record, Max_record)) > 0)
+   {
+     i=Max_record; end = Max_record + num_read;
+     if(FIRSTROUND) { i = Max_record -1 ;
+ 			if(DELIMITER) {
+ 				for(k=0; k<D_length; k++) {
+ 					if(old_D_pat[k] != buffer[Max_record+k]) 						break;
+ 				}
+ 				if(k>=D_length) j--;
+ 			}
+                      FIRSTROUND = 0; }
+     if(num_read < BlockSize) {
+                       strncpy(buffer+Max_record+num_read, old_D_pat, D_length);
+                       end = end + D_length;
+                       buffer[end] = '\0';
+     }
+     while (i < end)
+     {
+         CMask = Mask[buffer[i++]];
+               r1 = Init1 & B[D];
+               A[D] = ((B[D] >> 1) & CMask )  | r1;
+               for(k = r3; k <= r4; k++)  /* r3 = D+1, r4 = 2*D */
+               { 
+                   r5 = B[k];
+                   r1 = Init1 & r5;
+                   A[k] = ((r5 >> 1) & CMask) | B[k-I] |                                                (((A[k-DD] | B[k-S]) >>1) & r_NO_ERR) | r1 ; 
+               }
+         if(A[D] & endpos) {  
+            j++;
+            if(((AND == 1) && ((A[D*2] & endposition) == endposition)) ||                           ((AND == 0) && (A[D*2] & endposition)) ^ INVERSE )
+                    { 
+                      if(FILENAMEONLY) {
+ 			num_of_matched++;
+                         printf("%s\n", CurrentFileName);
+                         return;       } 
+                      if(lasti < Max_record + num_read)
+                         output(buffer, lasti, i-D_length-1, j); 
+                    }
+            lasti = i - D_length;
+            TRUNCATE = OFF;
+            for(k = D; k <= r4 ; k++) A[k] = B[k] = Init[0];
+            r1 = Init1 & B[D];
+            A[D] = (((B[D] >> 1) & CMask )  | r1) & D_Mask;
+            for(k = r3; k <= r4; k++)  /* r3 = D+1, r4 = 2*D */
+               { 
+                   r5 = B[k];
+                   r1 = Init1 & r5;
+                   A[k] = ((r5 >> 1) & CMask) | B[k-I] |                                                (((A[k-DD] | B[k-S]) >>1) & r_NO_ERR) | r1 ; 
+               }
+         }  /* end if (A[D]&endpos) */
+         CMask = Mask[buffer[i++]];
+               r1 = A[D] & Init1;
+               B[D] = ((A[D] >> 1) & CMask) | r1;
+               for(k = r3; k <= r4; k++)
+               { 
+                   r1 = A[k] & Init1;
+                   B[k] = ((A[k] >> 1) & CMask) | A[k-I] |                                                (((B[k-DD] | A[k-S]) >>1)&r_NO_ERR) | r1 ; 
+               }
+         if(B[D] & endpos)  {  
+              j++;
+            if(((AND == 1) && ((B[r4] & endposition) == endposition)) ||                           ((AND == 0) && (B[r4] & endposition)) ^ INVERSE )
+                    { if(FILENAMEONLY) {
+                         num_of_matched++;
+                         printf("%s\n", CurrentFileName);
+                         return;       }
+                      if(lasti < Max_record + num_read)
+                         output(buffer, lasti, i-D_length-1, j); 
+                    } 
+            lasti = i-D_length; 
+            TRUNCATE = OFF;
+            for(k=D; k <= r4; k++) A[k] = B[k] = Init[0];
+            r1 = Init1 & A[D];
+            B[D] = (((A[D] >> 1) & CMask )  | r1) & D_Mask;
+            for(k = r3; k <= r4; k++)  /* r3 = D+1, r4 = 2*D */
+               { 
+                   r5 = A[k];
+                   r1 = Init1 & r5;
+                   B[k] = ((r5 >> 1) & CMask) | A[k-I] |                                                (((B[k-DD] | A[k-S]) >>1) & r_NO_ERR) | r1 ; 
+               }
+         }  /* end if (B[D]&endpos) */
+     }
+     ResidueSize = Max_record + num_read - lasti;
+     if(ResidueSize > Max_record) {
+             ResidueSize = Max_record;
+             TRUNCATE = ON;   
+     }
+     strncpy(buffer+Max_record-ResidueSize, buffer+lasti, ResidueSize);
+     lasti = Max_record - ResidueSize;
+     if(lasti < 0) lasti = 1;
+     if(num_read < BlockSize) lasti = Max_record;
+   }
+   return;
+ }
+ 


Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/bitap.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/bitap.c:1.1
*** /dev/null	Tue Oct  5 13:03:12 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/bitap.c	Tue Oct  5 13:02:58 2004
***************
*** 0 ****
--- 1,162 ----
+ /* Copyright (c) 1991 Sun Wu and Udi Manber.  All Rights Reserved. */
+ /* if the pattern is not simple fixed pattern, then after preprocessing */
+ /* and generating the masks, the program goes here. four cases:  1.     */ 
+ /* the pattern is simple regular expression and no error, then do the   */
+ /* matching here.  2. the pattern is simple regular expression and      */
+ /* unit cost errors are allowed: then go to asearch().                  */
+ /* 3. the pattern is simple regular expression, and the edit cost is    */
+ /* not uniform, then go to asearch1().                                  */
+ /* if the pattern is regular expression then go to re() if M < 14,      */
+ /* else go to re1()                                                     */
+ /* input parameters: old_D_pat: delimiter pattern.                      */
+ /* fd, input file descriptor, M: size of pattern, D: # of errors.       */
+ #include <unistd.h>
+ #include "agrep.h"
+ 
+ extern unsigned Init1, D_endpos, endposition, Init[], Mask[], Bit[];
+ extern int DELIMITER, FILENAMEONLY, D_length, I, AND, REGEX, JUMP, INVERSE; 
+ extern char D_pattern[];
+ extern int TRUNCATE, DD, S;
+ extern char Progname[], CurrentFileName[];
+ extern int num_of_matched;
+ 
+ extern void re(int Text, int M, int D);
+ extern void re1(int Text, int M, int D);
+ extern void asearch1(char old_D_pat[], int Text, register unsigned D);
+ extern void asearch(CHAR old_D_pat[], int text, register unsigned D);
+ extern int fill_buf(int fd, unsigned char *buf, int record_size);
+ extern void output(register CHAR *buffer, int i1, int i2, int j);
+ 
+ /* bitap dispatches job */
+ 
+ void bitap(char old_D_pat[], char *Pattern, int fd, int M, int D)
+ {
+ char c;  
+ register unsigned r1, r2, r3, CMask, i;
+ register unsigned end, endpos, r_Init1;
+ register unsigned D_Mask;
+ int  ResidueSize , FIRSTROUND, lasti, print_end, j, num_read;
+ int  k;
+ char buffer[Max_record+Max_record+BlockSize];
+   D_length = strlen(old_D_pat);
+   for(i=0; i<D_length; i++) if(old_D_pat[i] == '^' || old_D_pat[i] == '$')
+                                old_D_pat[i] = '\n';
+   if (REGEX) { 
+       if (D > 4) {
+           fprintf(stderr, "%s: the maximum number of erorrs allowed for full regular expression is 4\n", Progname);
+           exit(2);
+       }
+       if (M <= SHORTREG) { re(fd, M, D);   /* SUN: need to find a even point */ 
+                      return; }
+       else { re1(fd, M, D); 
+              return; }
+   }   
+   if (D > 0 && JUMP == ON) 
+      { asearch1(old_D_pat, fd, D); return; }
+   if (D > 0) 
+      { asearch(old_D_pat, fd, D); return; }
+   if(I == 0) Init1 = 037777777777;
+ 
+   j=0;
+   lasti = Max_record;
+   buffer[Max_record-1] = '\n';
+   r_Init1 = Init1;
+   r1 = r2 = r3 = Init[0];
+   endpos = D_endpos;
+   
+   buffer[Max_record-1] = '\n';
+   D_Mask = D_endpos;
+   for(i=1 ; i<D_length; i++) D_Mask = (D_Mask << 1) | D_Mask;
+   D_Mask = ~D_Mask;
+   FIRSTROUND = ON;
+ 
+   while ((num_read = fill_buf(fd, buffer + Max_record, Max_record)) > 0)
+   {
+     i=Max_record; end = Max_record + num_read; 
+     if(FIRSTROUND) {  i = Max_record - 1 ;
+ 
+ 			if(DELIMITER) {
+ 				for(k=0; k<D_length; k++) {
+ 					if(old_D_pat[k] != buffer[Max_record+k]) 						break;
+ 				}
+ 				if(k>=D_length) j--;
+ 			}
+ 
+                       FIRSTROUND = OFF;  }
+     if(num_read < BlockSize) {
+                       strncpy(buffer+Max_record+num_read, old_D_pat, D_length);
+                       end = end + D_length;
+                       buffer[end] = '\0';
+     }
+     while (i < end)
+     {
+         c = buffer[i++];
+         CMask = Mask[c];
+               r1 = r_Init1 & r3;
+               r2 = (( r3 >> 1 ) & CMask) | r1;
+         if ( r2 & endpos ) {
+            j++;
+            if(((AND == 1) && ((r2 & endposition) == endposition)) ||                           ((AND == 0) && (r2 & endposition)) ^ INVERSE )
+                { 
+                  if(FILENAMEONLY) {
+                     num_of_matched++;
+                     printf("%s\n", CurrentFileName);
+                     return; }
+                  print_end = i - D_length - 1;
+                  if(!(lasti >= Max_record+num_read - 1))
+                     output(buffer, lasti, print_end, j); 
+                }
+            lasti = i - D_length; 
+            TRUNCATE = OFF;
+            r2 = r3 = r1 = Init[0];
+            r1 = r_Init1 & r3;
+            r2 = ((( r2 >> 1) & CMask) | r1 ) & D_Mask;
+         }
+         c = buffer[i++];
+         CMask = Mask[c];
+               r1 = r_Init1 & r2;
+               r3 = (( r2 >> 1 ) & CMask) | r1; 
+         if ( r3 & endpos ) {
+            j++;
+            if(((AND == 1) && ((r3 & endposition) == endposition)) ||                           ((AND == 0) && (r3 & endposition)) ^ INVERSE )
+                { 
+                  if(FILENAMEONLY) {
+                     num_of_matched++;
+                     printf("%s\n", CurrentFileName);
+                     return; }
+                  print_end = i - D_length - 1;
+                  if(!(lasti >= Max_record+num_read - 1))
+                     output(buffer, lasti, print_end, j);
+                }
+            lasti = i - D_length ;
+            TRUNCATE = OFF;
+            r2 = r3 = r1 = Init[0]; 
+            r1 = r_Init1 & r2;
+            r3 = ((( r2 >> 1) & CMask) | r1 ) & D_Mask;
+        }   
+     }
+     ResidueSize = num_read + Max_record - lasti;
+     if(ResidueSize > Max_record) {
+             ResidueSize = Max_record;
+             TRUNCATE = ON;   
+     }
+     strncpy(buffer+Max_record-ResidueSize, buffer+lasti, ResidueSize);
+     lasti = Max_record - ResidueSize;
+     if(lasti < 0) {
+        lasti = 1;
+     } 
+   }
+   return;
+ }
+ 
+ int fill_buf(int fd, unsigned char *buf, int record_size)
+ {
+ int num_read=1;
+ int total_read=0;
+ 	while(total_read < record_size && num_read > 0) {
+ 		num_read = read(fd, buf+total_read, 4096);
+ 		total_read = total_read + num_read;
+ 	}
+ 	return(total_read);
+ }
+ 


Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/checkfile.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/checkfile.c:1.1
*** /dev/null	Tue Oct  5 13:03:12 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/checkfile.c	Tue Oct  5 13:02:58 2004
***************
*** 0 ****
--- 1,101 ----
+ /*
+  *  checkfile.c
+  *    takes a file descriptor and checks to see if a file is a regular
+  *    ascii file
+  *
+  */
+ 
+ #include <stdio.h>
+ #include <ctype.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <errno.h>
+ 
+ #include "checkfile.h"
+ 
+ #define MAXLINE 512
+ 
+ extern char Progname[];
+ extern int errno;
+ 
+ unsigned char ibuf[MAXLINE];
+ 
+ /**************************************************************************
+ *
+ *    check_file
+ *       input:  filename or path (null-terminated character string)
+ *       returns: int (0 if file is a regular file, non-0 if not)
+ *
+ *    uses stat(2) to see if a file is a regular file.
+ *
+ ***************************************************************************/
+ 
+ int check_file(char *fname)
+ {
+ struct stat buf;
+ 
+ 
+   if (stat(fname, &buf) != 0) {
+     if (errno == ENOENT)
+       return NOSUCHFILE;
+     else
+       return STATFAILED;  
+     } else {
+ /*
+       if (S_ISREG(buf.st_mode)) {
+         if ((ftype = samplefile(fname)) == ISASCIIFILE) {
+           return ISASCIIFILE;
+         } else if (ftype == ISBINARYFILE) {
+           return ISBINARYFILE;
+         } else if (ftype == OPENFAILED) {
+           return OPENFAILED;
+         }
+       }
+       if (S_ISDIR(buf.st_mode)) {
+         return ISDIRECTORY;
+       }
+       if (S_ISBLK(buf.st_mode)) {
+         return ISBLOCKFILE;
+       }
+       if (S_ISSOCK(buf.st_mode)) {
+         return ISSOCKET;
+       }
+ */
+     }
+   return 0;
+ }
+ 
+ /***************************************************************************
+ *
+ *  samplefile
+ *    reads in the first part of a file, and checks to see that it is
+ *    all ascii.
+ *
+ ***************************************************************************/
+ /*
+ int samplefile(char *fname)
+ {
+ char *p;
+ int numread;
+ int fd;
+ 
+   if ((fd = open(fname, O_RDONLY)) == -1) {
+     fprintf(stderr, "open failed on filename %s\n", fname);
+     return OPENFAILED;
+   }
+   if (numread = read(fd, ibuf, MAXLINE)) {
+    close(fd);
+    p = ibuf;
+     while (isascii(*p++) && --numread);
+     if (!numread) {
+       return(ISASCIIFILE);
+     } else {
+       return(ISBINARYFILE);
+     }
+   } else {
+     close(fd);
+     return(ISASCIIFILE);
+   }
+ }
+ */


Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/checkfile.h
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/checkfile.h:1.1
*** /dev/null	Tue Oct  5 13:03:12 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/checkfile.h	Tue Oct  5 13:02:58 2004
***************
*** 0 ****
--- 1,8 ----
+ #define NOSUCHFILE -3
+ #define OPENFAILED -2
+ #define STATFAILED -1
+ #define ISASCIIFILE 0
+ #define ISDIRECTORY 1
+ #define ISBLOCKFILE 2
+ #define ISSOCKET 3
+ #define ISBINARYFILE 4


Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/compat.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/compat.c:1.1
*** /dev/null	Tue Oct  5 13:03:12 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/compat.c	Tue Oct  5 13:02:58 2004
***************
*** 0 ****
--- 1,58 ----
+ /* test the conflicts between options */
+ #include <stdio.h>
+ 
+ extern int FILENAMEONLY, APPROX, PAT_FILE, COUNT, INVERSE, BESTMATCH;
+ extern FILEOUT;
+ extern REGEX;
+ extern DELIMITER;
+ extern WHOLELINE;
+ extern LINENUM;
+ extern I, S, DD;
+ extern JUMP;
+ extern char Progname[32];
+ 
+ void compat(void)
+ {
+ 	if(BESTMATCH)  if(COUNT || FILENAMEONLY || APPROX || PAT_FILE) {
+ 		BESTMATCH = 0;
+ 		fprintf(stderr, "%s: WARNING!!! -B option ignored when -c, -l, -f, or -# is on\n", Progname);
+ 	}
+ 	if(PAT_FILE)   {
+ 		if(APPROX)  {
+ 			fprintf(stderr, "WARNING!!!  approximate matching is not supported with -f option\n");
+ 		}
+ /*
+ 		if(INVERSE) {
+ 			fprintf(stderr, "%s: -f and -v are not compatible\n", Progname);
+ 			exit(2);
+ 		}
+ */
+ 		if(LINENUM) {
+ 			fprintf(stderr, "%s: -f and -n are not compatible\n", Progname);
+ 			exit(2);
+ 		}
+ 		if(DELIMITER) {
+ 			fprintf(stderr, "%s: -f and -d are not compatible\n", Progname);
+ 			exit(2);
+ 		}
+ 	}
+ 	if(JUMP) {
+ 		if(REGEX) {
+ 			fprintf(stderr, "WARNING!!! -D#, -I#, or -S# option is ignored for regular expression pattern\n");
+ 			JUMP = 0;
+ 		}
+ 		if(I == 0 || S == 0 || DD == 0) {
+ 			fprintf(stderr, "%s: the error cost cannot be 0\n", Progname);
+ 			exit(2);
+ 		}
+ 	}
+ 	if(DELIMITER) {
+ 		if(WHOLELINE) {
+ 			fprintf(stderr, "%s: -d and -x is not compatible\n", Progname);
+ 			exit(2);
+ 		}
+ 	}
+ 
+ }
+ 
+ 


Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/follow.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/follow.c:1.1
*** /dev/null	Tue Oct  5 13:03:12 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/follow.c	Tue Oct  5 13:02:58 2004
***************
*** 0 ****
--- 1,142 ----
+ /* the functions in this file take a syntax tree for a regular
+    expression and produce a DFA using the McNaughton-Yamada
+    construction.						*/
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include "re.h"
+ 
+ /*
+ extern char *strncpy(), *strcat(), *strcpy();
+ extern int  strlen();
+ */
+ extern char *strcat(char *s1, const char *s2);
+ 
+ #define TRUE	1
+ /*
+ extern char *malloc();
+ */
+ extern Pset pset_union(Pset s1, Pset s2); 
+ extern int pos_cnt;
+ extern Re_node parse(char *s);
+ 
+ Re_lit_array lpos; 
+ 
+ 
+ /*  extend_re() extends the RE by adding a ".*(" at the front and a "("
+     at the back.						   	*/
+ 
+ char *extend_re(char *s)
+ {
+     char *s1;
+ 
+     s1 = (char *) malloc((unsigned) strlen(s)+4+1);
+     return (char *) strcat(strcat(strcpy(s1, ".*("), s), ")");
+ }
+ 
+ /* mk_followpos() takes a syntax tree for a regular expression and
+    traverses it once, computing the followpos function at each node
+    and returns a pointer to an array whose ith element is a pointer
+    to a list of position nodes, representing the positions in
+    followpos(i).							*/
+ 
+ void mk_followpos_1(Re_node e, Pset_array fpos)
+ {
+     Pset pos;
+     int i;
+ 
+     switch (Op(e)) {
+ 	case EOS: break;
+ 	case OPSTAR:
+ 	    pos = Lastpos(e);
+ 	    while (pos != NULL) {
+ 		i = pos->posnum;
+ 		(*fpos)[i] = pset_union(Firstpos(e), (*fpos)[i]);
+ 		pos = pos->nextpos;
+ 	    }
+ 	    mk_followpos_1(Child(e), fpos);
+ 	    break;
+ 	case OPCAT:
+ 	    pos = Lastpos(Lchild(e));
+ 	    while (pos != NULL) {
+ 		i = pos->posnum;
+ 		(*fpos)[i] = pset_union(Firstpos(Rchild(e)), (*fpos)[i]);
+ 		pos = pos->nextpos;
+ 	    }
+ 	    mk_followpos_1(Lchild(e), fpos);
+ 	    mk_followpos_1(Rchild(e), fpos);
+ 	    break;
+ 	case OPOPT:
+ 	    mk_followpos_1(Child(e), fpos);
+ 	    break;
+ 	case OPALT:
+ 	    mk_followpos_1(Lchild(e), fpos);
+ 	    mk_followpos_1(Rchild(e), fpos);
+ 	    break;
+ 	case LITERAL:
+ 	    break;
+ 	default: printf("mk_followpos: unknown node type %d\n", Op(e));
+     }
+     return;
+ }
+ 
+ Pset_array mk_followpos(Re_node tree, int npos)
+ {
+     int i;
+     Pset_array fpos;
+ 
+     if (tree == NULL || npos < 0) return NULL;
+     fpos = (Pset_array) malloc((unsigned) (npos+1)*sizeof(Pset));
+     if (fpos == NULL) return NULL;
+     for (i = 0; i <= npos; i++) (*fpos)[i] = NULL;
+     mk_followpos_1(tree, fpos);
+     return fpos;
+ }
+ 
+ /* mk_poslist() sets a static array whose i_th element is a pointer to
+    the RE-literal at position i.  It returns 1 if everything is OK,  0
+    otherwise.								*/
+ 
+ /* init performs initialization actions; it returns -1 in case of error,
+    0 if everything goes OK.						*/
+ 
+ int init(char *s, int table[32][32])
+ {
+     Pset_array fpos;
+     Re_node e;
+     Pset l;
+     int i, j;
+ 
+     if ((e = parse(extend_re(s))) == NULL) return -1;
+     if ((fpos = mk_followpos(e, pos_cnt)) == NULL) return -1;
+     for (i = 0; i <= pos_cnt; i += 1) {
+ #ifdef Debug
+ 	printf("followpos[%d] = ", i);
+ #endif
+         l = (*fpos)[i];
+         j = 0;
+         for ( ; l != NULL; l = l->nextpos)  {
+ #ifdef Debug
+             printf("%d ", l->posnum);
+ #endif
+             table[i][j] = l->posnum;
+             j++;
+         } 
+ #ifdef Debug
+         printf("\n");
+ #endif
+     }
+ #ifdef Debug
+     for (i=0; i <= pos_cnt; i += 1)  {
+        j = 0;
+        while (table[i][j] != 0) {
+           printf(" %d ", table[i][j]);
+           j++;
+       }
+       printf("\n");
+    }
+ #endif
+     return (pos_cnt);
+ }
+ 


Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/main.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/main.c:1.1
*** /dev/null	Tue Oct  5 13:03:12 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/main.c	Tue Oct  5 13:02:58 2004
***************
*** 0 ****
--- 1,1050 ----
+ /* Copyright (c) 1991 Sun Wu and Udi Manber.  All Rights Reserved. */
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
+ #include "agrep.h"
+ #include "checkfile.h"
+ #define CHARTYPE        unsigned char
+ 
+ unsigned Mask[MAXSYM];
+ unsigned Init1, NO_ERR_MASK, Init[MaxError];
+ unsigned Bit[WORD+1];
+ CHAR buffer[BlockSize+Maxline+1];
+ unsigned Next[MaxNext], Next1[MaxNext];
+ unsigned wildmask, endposition, D_endpos; 
+ int  REGEX, RE_ERR, FNAME, WHOLELINE, SIMPLEPATTERN;
+ int  COUNT, HEAD, TAIL, LINENUM, INVERSE, I, S, DD, AND, SGREP, JUMP; 
+ int  Num_Pat, PSIZE, num_of_matched, SILENT, NOPROMPT, BESTMATCH, NOUPPER;
+ int  NOMATCH, TRUNCATE, FIRST_IN_RE, FIRSTOUTPUT;
+ int  WORDBOUND, DELIMITER, D_length;
+ int  EATFIRST, OUTTAIL;
+ int  FILEOUT;
+ int  DNA = 0;
+ int  APPROX = 0;
+ int  PAT_FILE = 0;
+ int  CONSTANT = 0;
+ int total_line = 0; /* used in mgrep */
+                                      
+ CHAR **Textfiles;     /* array of filenames to be searched */
+ CHAR old_D_pat[MaxDelimit] = "\n";  /* to hold original D_pattern */
+ CHAR CurrentFileName[MAXNAME]; 
+ CHAR Progname[MAXNAME]; 
+ CHAR D_pattern[MaxDelimit] = "\n; "; /* string which delimits records --
+                                         defaults to newline */   
+ int  NOFILENAME = 0,  /* Boolean flag, set for -h option */
+      FILENAMEONLY = 0,/* Boolean flag, set for -l option */
+      Numfiles = 0;    /* indicates how many files in Textfiles */
+ extern int init(char *s, int table[32][32]);
+ extern void bitap(char old_D_pat[], char *Pattern, int fd, int M, int D);
+ extern void prepf(int fp);
+ extern void compat(void);
+ extern void mgrep(int fd);
+ extern void sgrep(CHARTYPE *pat, int m, int fd, int D);
+ extern void preprocess(CHAR *D_pattern, CHAR *Pattern);
+ extern int maskgen(unsigned char *Pattern, int D);
+ extern int check_file(char *fname);
+ 
+ int table[WORD][WORD];
+ 
+ void initial_value(void);
+ void compute_next(int M, unsigned *Next, unsigned *Next1);
+ int exponen(int m);
+ void re1(int Text, int M, int D);
+ void re(int Text, int M, int D);
+ void r_output(CHAR *buffer, int i, int end, int j);
+ void file_out(char *fname);
+ void usage(void);
+ void checksg(CHAR *Pattern, int D);
+ void output(register CHAR *buffer, int i1, int i2, int j);
+ 
+ int main(int argc, char *argv[])
+ {
+   int M, D=0, fp, fd, i; 
+   char c;
+   int filetype;
+   unsigned char Pattern[MAXPAT], OldPattern[MAXPAT];
+   
+   initial_value();
+   strcpy(Progname, "agrep");
+   if (argc < 2) usage();
+   Pattern[0] = '\0';
+   while(--argc > 0 && (*++argv)[0] == '-') {
+      c = *(argv[0]+1); 
+      switch(c) {
+        case 'c' : COUNT = ON;    /* output the # of matched */
+                   break;
+        case 's' : SILENT = ON;   /* silent mode  */
+                   break;
+        case 'p' : I = 0;         /* insertion cost is 0 */
+                   break; 
+        case 'x' : WHOLELINE = ON;  /* match the whole line */
+ 		  if(WORDBOUND) {
+ 			fprintf(stderr, "%s: illegal option combination\n", Progname);
+ 			exit(2);
+ 		  }
+                   break;
+        case 'L' : break;
+        case 'd' : DELIMITER = ON;  /* user defines delimiter */
+                   if(argc <= 1) usage();
+                   if (argv[0][2] == '\0') {/* space after -d option */
+                     argv++;
+                     if ((D_length = strlen(argv[0])) > MaxDelimit) {
+                       fprintf(stderr, "%s: delimiter pattern too long\n", Progname);
+                       exit(2);
+                     }
+                     D_pattern[0] = '<';
+                     strcpy(D_pattern+1, argv[0]);
+                     argc--;
+                   } else {
+                     if ((D_length = strlen(argv[0]+2)) > MaxDelimit) {
+                       fprintf(stderr, "%s: delimiter pattern too long\n", Progname);
+                       exit(2);
+                     }
+                     D_pattern[0] = '<';
+                     strcpy(D_pattern+1, argv[0]+2);
+                   } /* else */
+                   strcat(D_pattern, ">; ");
+                   D_length++;   /* to count ';' as one */
+                   break;
+        case 'e' : argc--;
+ 		  if(argc == 0) {
+ 			fprintf(stderr, "%s: the pattern should immediately follow the -e option\n", Progname);
+ 			usage();
+ 		  }
+ 		  if((++argv)[0][0] == '-') {
+                        Pattern[0] = '\\';
+                        strcat(Pattern, (argv)[0]);
+                   }
+                   else strcat(Pattern, argv[0]);
+                   break;
+        case 'f' : PAT_FILE = ON;
+ 		  argv++;
+ 		  argc--;
+ 		  if((fp = open(argv[0], 0)) < 0) {
+ 			fprintf(stderr, "%s: Can't open pattern file %s\n", Progname, argv[0]);
+ 			exit(2);
+ 		  }
+ 		  break;
+        case 'h' : NOFILENAME = ON;
+                   break;
+        case 'i' : NOUPPER = ON;
+                   break;
+        case 'k' : argc--;
+ 		  if(argc == 0) {
+ 			fprintf(stderr, "%s: the pattern should immediately follow the -k option\n", Progname);
+ 			usage();
+ 		  }
+ 		  CONSTANT = ON;
+ 		  argv++;
+ 		  strcat(Pattern, argv[0]);
+ 		  if(argc > 1 && argv[1][0] == '-') {
+ 			fprintf(stderr, "%s: -k should be the last option in the command\n", Progname);
+ 			exit(2);
+ 		  }
+ 		  break;
+        case 'l' : FILENAMEONLY = ON;
+                   break;
+        case 'n' : LINENUM = ON;  /* output prefixed by line no*/
+                   break;
+        case 'v' : INVERSE = ON;  /* output no-matched lines */
+                   break;
+        case 't' : OUTTAIL = ON;  /* output from tail of delimiter */
+                   break;
+        case 'B' : BESTMATCH = ON;
+                   break;
+        case 'w' : WORDBOUND = ON;/* match to words */
+ 		  if(WHOLELINE) {
+ 			fprintf(stderr, "%s: illegal option combination\n", Progname);
+ 			exit(2);
+ 		  }
+                   break;
+        case 'y' : NOPROMPT = ON;
+ 		  break;
+        case 'I' : I = atoi(argv[0]+2);  /* Insertion Cost */
+ 	          JUMP = ON;
+                   break;
+        case 'S' : S = atoi(argv[0]+2);  /* Substitution Cost */
+                   JUMP = ON;
+                   break;
+        case 'D' : DD = atoi(argv[0]+2); /* Deletion Cost */
+                   JUMP = ON;
+                   break;
+        case 'G' : FILEOUT = ON; 
+ 		  COUNT = ON;
+ 		  break;
+        default  : if (isdigit(c)) {
+ 		    APPROX = ON;
+                     D = atoi(argv[0]+1);
+                     if (D > MaxError) {
+                       fprintf(stderr,"%s: the maximum number of errors is %d \n", Progname, MaxError);
+                       exit(2);
+                     }
+                   } else {
+                     fprintf(stderr, "%s: illegal option  -%c\n",Progname, c);
+ 		    usage();
+                   }
+        } /* switch(c) */
+   } /* while (--argc > 0 && (*++argv)[0] == '-') */
+ 
+   if (FILENAMEONLY && NOFILENAME) {
+     fprintf(stderr, "%s: -h and -l options are mutually exclusive\n",Progname);
+   }
+   if (COUNT && (FILENAMEONLY || NOFILENAME)) {
+       FILENAMEONLY = OFF; 
+       if(!FILEOUT) NOFILENAME = OFF;
+   }
+   if (!(PAT_FILE) && Pattern[0] == '\0') { /* Pattern not set with -e option */
+     if (argc == 0) usage();
+     strcpy(Pattern, *argv); 
+     argc--;
+     argv++;
+   }
+   Numfiles = 0;  
+   fd = 3; /* make sure it's not 0 */
+   if (argc == 0)  /* check Pattern against stdin */
+     fd = 0;
+   else {
+     if (!(Textfiles = (CHAR **)malloc(argc * sizeof(CHAR *) ))) {
+       fprintf(stderr, "%s: malloc failure (you probably don't have enough memory)\n", Progname);
+       exit(2);
+     }
+     while (argc--)  { /* one or more filenames on command line -- put
+                           the valid filenames in a array of strings */    
+ /*
+       if ((filetype = check_file(*argv)) != ISASCIIFILE) {
+ 	if(filetype == NOSUCHFILE) fprintf(stderr,"%s: %s: no such file or directory\n",Progname,*argv);
+         argv++;
+ */
+       
+       if ((filetype = check_file(*argv)) == NOSUCHFILE) {
+ 	if(filetype == NOSUCHFILE) fprintf(stderr,"%s: %s: no such file or directory\n",Progname,*argv);
+         argv++;
+       } else { /* file is ascii*/
+         if (!(Textfiles[Numfiles] = (CHAR *)malloc((strlen(*argv)+1)))) {
+           fprintf(stderr, "%s: malloc failure (you probably don't have enough memory)\n", Progname);
+           exit(2);
+         }
+         strcpy(Textfiles[Numfiles++], *argv++);
+ 	   } /* else */
+      } /* while (argc--) */
+   } /* else */
+   checksg(Pattern, D);       /* check if the pattern is simple */
+   strcpy(OldPattern, Pattern);
+   if (SGREP == 0) {
+       preprocess(D_pattern, Pattern);
+       strcpy(old_D_pat, D_pattern);
+       M = maskgen(Pattern, D);
+   }
+   else M = strlen(OldPattern);
+   if (PAT_FILE)  prepf(fp);
+   if (Numfiles > 1) FNAME = ON;
+   if (NOFILENAME) FNAME = 0;
+   num_of_matched = 0;
+   compat(); /* check compatibility between options */
+   if (fd == 0) {
+     if(FILENAMEONLY) {
+        fprintf(stderr, "%s: -l option is not compatible with standard input\n", Progname);
+        exit(2);  
+     }
+     if(PAT_FILE) mgrep(fd);
+     else {
+     	if(SGREP) sgrep(OldPattern, strlen(OldPattern), fd, D);
+    	else      bitap(old_D_pat, Pattern, fd, M, D);
+     }
+     if (COUNT) {
+ 	if(INVERSE && PAT_FILE) printf("%d\n", total_line-num_of_matched);
+ 	else printf("%d\n", num_of_matched);
+     }
+   } 
+   else {
+     for (i = 0; i < Numfiles; i++, close(fd), num_of_matched = 0) {
+       	strcpy(CurrentFileName, Textfiles[i]);
+       	if ((fd = open(Textfiles[i], 0)) <= 0) {
+             fprintf(stderr, "%s: can't open file %s\n",Progname, Textfiles[i]);
+       	} 
+ 	else { 
+ 	     	if(PAT_FILE) mgrep(fd);
+ 	     	else {
+              		if(SGREP) sgrep(OldPattern, strlen(OldPattern), fd, D);
+              		else      bitap(old_D_pat, Pattern, fd, M, D);
+ 	        }
+         	if (num_of_matched) NOMATCH = OFF;
+         	if (COUNT && !FILEOUT) {
+ 			if(INVERSE && PAT_FILE) {
+  		    		if(FNAME) printf("%s: %d\n", CurrentFileName, total_line - num_of_matched);
+ 				else printf("%d\n", total_line - num_of_matched);
+ 			}
+ 			else {
+  		    		if(FNAME) printf("%s: %d\n", CurrentFileName, num_of_matched);
+ 				else printf("%d\n", num_of_matched);
+ 			}
+         	}  /* if COUNT */
+ 		if(FILEOUT && num_of_matched) {
+ 			file_out(CurrentFileName);
+ 		}
+       	} /* else */
+     }  /* for i < Numfiles */
+     if(NOMATCH && BESTMATCH) {
+ 	if(WORDBOUND || WHOLELINE || LINENUM || INVERSE) { 
+ 		SGREP = 0;	
+       		preprocess(D_pattern, Pattern);
+       		strcpy(old_D_pat, D_pattern);
+       		M = maskgen(Pattern, D);
+ 	}
+ 	COUNT=ON; D=1;
+ 	while(D<M && D<=MaxError && num_of_matched == 0) {
+     		for (i = 0; i < Numfiles; i++, close(fd)) {
+       			strcpy(CurrentFileName, Textfiles[i]);
+       			if ((fd = open(Textfiles[i], 0)) > 0) {
+ 	     			if(PAT_FILE) mgrep(fd);
+ 	     			else {
+              		    		if(SGREP) sgrep(OldPattern,strlen(OldPattern),fd,D);
+              		    		else bitap(old_D_pat,Pattern,fd,M,D);
+       				}
+ 			} 
+    		}  /* for i < Numfiles */
+ 		D++;
+ 	} /* while */
+ 	if(num_of_matched > 0) {
+ 		D--; COUNT = 0;
+ 		if(NOPROMPT) goto GO_AHEAD;
+ 		if(D==1) fprintf(stderr, "best match has 1 error, ");
+ 		else fprintf(stderr, "best match has %d errors, ", D);
+ 		fflush(stderr);
+ 		if(num_of_matched == 1) fprintf(stderr,"there is 1 match, output it? (y/n)");
+ 		else fprintf(stderr,"there are %d matches, output them? (y/n)", num_of_matched);
+ 		scanf("%c",&c);
+ 		if(c != 'y') goto CONT;
+ GO_AHEAD:
+     		for (i = 0; i < Numfiles; i++, close(fd)) {
+       			strcpy(CurrentFileName, Textfiles[i]);
+       			if ((fd = open(Textfiles[i], 0)) > 0) {
+ 	     			if(PAT_FILE) mgrep(fd);
+ 	     			else {
+              		    		if(SGREP) sgrep(OldPattern,strlen(OldPattern),fd,D);
+              		    		else bitap(old_D_pat,Pattern,fd,M,D);
+ 				}
+       			} 
+    		}  /* for i < Numfiles */
+ 		NOMATCH = 0;
+ 	}
+    }
+  }
+ CONT:
+  if(EATFIRST) {
+       printf("\n");
+       EATFIRST = OFF;
+  }
+  if(num_of_matched) NOMATCH = OFF;
+  if(NOMATCH) exit(1);
+  exit(0);
+ } /* end of main() */
+ 
+ void initial_value(void)
+ {
+    int i; 
+ 
+    JUMP = REGEX = FNAME = BESTMATCH = NOPROMPT = NOUPPER = 0;
+    COUNT = LINENUM = WHOLELINE = SGREP = 0;
+    EATFIRST = INVERSE = AND = TRUNCATE = OUTTAIL = 0; 
+    FIRST_IN_RE = NOMATCH = FIRSTOUTPUT = ON;
+    I = DD = S = 1;
+    HEAD = TAIL = ON;
+    D_length = 2;
+    SILENT = Num_Pat = PSIZE = SIMPLEPATTERN = num_of_matched = 0 ;
+    WORDBOUND = DELIMITER = RE_ERR = 0;
+    Bit[WORD] = 1;
+    for (i = WORD - 1; i > 0  ; i--)  Bit[i] = Bit[i+1] << 1; 
+    for (i=0; i< MAXSYM; i++) Mask[i] = 0;
+ }
+ 
+ void compute_next(int M, unsigned *Next, unsigned *Next1)
+ {
+   int i, j=0, n,  k, temp;
+   int mid, pp;
+   int MM, base;
+   unsigned V[WORD];
+    
+   base = WORD - M;
+   temp = Bit[base]; Bit[base] = 0;
+   for (i=0; i<WORD; i++) V[i] = 0;
+   for (i=1; i<M; i++)
+   {  
+       j=0;
+       while (table[i][j] > 0 && j < 10) {
+             V[i] = V[i] | Bit[base + table[i][j++]];
+       }
+   }
+   Bit[base]=temp;
+   if(M <= SHORTREG)
+   {
+     k = exponen(M);
+     pp = 2*k;
+     for(i=k; i<pp ; i++)
+     {   n = i;
+         Next[i]= (k>>1);
+         for(j=M; j>=1; j--)
+         {
+            if(n & Bit[WORD]) Next[i] = Next[i] | V[j];
+            n = (n>>1);
+         }
+     }      
+     return;
+   }
+   if(M > MAXREG) fprintf(stderr, "%s: regular expression too long\n", Progname);
+   MM = M;
+   if(M & 1) M=M+1;
+   k = exponen(M/2);
+   pp = 2*k;
+   mid = MM/2;
+   for(i=k; i<pp ; i++)
+   {     n = i;
+         Next[i]= (Bit[base]>>1);
+         for(j=MM; j>mid ; j--)
+         {
+            if(n & Bit[WORD]) Next[i] = Next[i] | V[j-mid];
+            n = (n>>1);
+         }
+         n=i-k;
+         Next1[i-k] = 0;
+         for(j = 0; j<mid; j++)
+         {
+            if(n & Bit[WORD]) Next1[i-k] = Next1[i-k] | V[MM-j];
+            n = (n>>1);
+         }
+   }      
+   return;
+ }
+ 
+ int exponen(int m)
+ { int i, ex;
+   ex= 1;
+   for (i=0; i<m; i++) ex= ex*2;
+   return(ex);
+ }
+ 
+ void re1(int Text, int M, int D)
+ {
+   register unsigned i, c, r0, r1, r2, r3, CMask, Newline, Init0, r_NO_ERR; 
+   register unsigned end;
+   register unsigned hh, LL=0, k;  /* Lower part */
+   int  FIRST_TIME=ON, num_read , j=0, base;
+   unsigned A[MaxRerror+1], B[MaxRerror+1];
+   unsigned Next[MaxNext], Next1[MaxNext];
+   CHAR buffer[BlockSize+Maxline+1];
+   int FIRST_LOOP = 1;
+    
+   r_NO_ERR = NO_ERR_MASK;
+   if(M > 30) {
+      fprintf(stderr, "%s: regular expression too long\n", Progname);
+      exit(2);
+   }
+   base = WORD - M;
+   hh = M/2;
+   for(i=WORD, j=0; j < hh ; i--, j++) LL = LL | Bit[i];
+   if(FIRST_IN_RE) compute_next(M, Next, Next1); 
+                                    /*SUN: try: change to memory allocation */
+   FIRST_IN_RE = 0;
+   Newline = '\n';
+   Init[0] = Bit[base];
+   if(HEAD) Init[0] = Init[0] | Bit[base+1];
+   for(i=1; i<= D; i++) Init[i] = Init[i-1] | Next[Init[i-1]>>hh] | Next1[Init[i-1]&LL];
+   Init1 = Init[0] | 1; 
+   Init0 = Init[0];
+   r2 = r3 = Init[0];
+   for(k=0; k<= D; k++) { A[k] = B[k] = Init[k]; }
+   if ( D == 0 )
+   {
+     while ((num_read = read(Text, buffer + Maxline, BlockSize)) > 0)
+     {
+       i=Maxline; end = num_read + Maxline;
+       if((num_read < BlockSize) && buffer[end-1] != '\n') buffer[end] = '\n';
+       if(FIRST_LOOP) {         /* if first time in the loop add a newline */
+         buffer[i-1] = '\n';  /* in front the  text.  */
+ 	i--;
+         FIRST_LOOP = 0;
+       }
+       while ( i < end )
+       {
+         c = buffer[i++];
+         CMask = Mask[c];
+         if(c != Newline)
+         {  if(CMask != 0) {  
+               r1 = Init1 & r3;
+               r2 = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | r1;
+            }
+ 	   else  {
+               r2 = r3 & Init1; 
+            }
+         }
+         else {  j++; 
+               r1 = Init1 & r3;            /* match against endofline */
+               r2 = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) | r1;
+               if(TAIL) r2 = (Next[r2>>hh] | Next1[r2&LL]) | r2;                                        /* epsilon move */
+               if(( r2 & 1 ) ^ INVERSE) {
+                    if(FILENAMEONLY) {
+                           num_of_matched++;
+                           printf("%s\n", CurrentFileName);
+                           return;
+                    } 
+                    r_output(buffer, i-1, end, j);
+               }
+               r3 = Init0;
+               r2 = (Next[r3>>hh] | Next1[r3&LL]) & CMask | Init0;  
+                                                /* match begin of line */
+         }
+         c = buffer[i++];
+         CMask = Mask[c];
+         if(c != Newline)
+         {  if(CMask != 0) {  
+               r1 = Init1 & r2;
+               r3 = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | r1;
+            }
+ 	   else   r3 = r2 & Init1; 
+         } /* if(NOT Newline) */
+         else {  j++;
+               r1 = Init1 & r2;            /* match against endofline */
+               r3 = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | r1;
+               if(TAIL) r3 = ( Next[r3>>hh] | Next1[r3&LL] ) | r3; 
+                                            /* epsilon move */
+               if(( r3 & 1 ) ^ INVERSE) {
+                    if(FILENAMEONLY) {
+                           num_of_matched++;
+                           printf("%s\n", CurrentFileName);
+                           return;
+                    } 
+                    r_output(buffer, i-1, end, j);
+               }
+               r2 = Init0;
+               r3 = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | Init0; 
+                    /* match begin of line */
+         }
+       } /* while i < end ... */
+       strncpy(buffer, buffer+num_read, Maxline);
+     } /* end while read()... */
+   return;
+   } /*  end if (D == 0) */
+   while ((num_read = read(Text, buffer + Maxline, BlockSize)) > 0)
+   {
+     i=Maxline; end = Maxline + num_read;
+     if((num_read < BlockSize) && buffer[end-1] != '\n') buffer[end] = '\n';
+     if(FIRST_TIME) {         /* if first time in the loop add a newline */
+         buffer[i-1] = '\n';  /* in front the  text.  */
+ 	i--;
+         FIRST_TIME = 0;
+     }
+     while (i < end )
+     {
+         c = buffer[i];
+         CMask = Mask[c];
+         if(c !=  Newline)
+         {
+            if(CMask != 0) {  
+               r2 = B[0];
+               r1 = Init1 & r2;
+               A[0] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | r1;
+               r3 = B[1];
+               r1 = Init1 & r3;
+               r0 = r2 | A[0];     /* A[0] | B[0] */
+               A[1] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) |                                       (( r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
+                      if(D == 1) goto Nextchar;
+               r2 = B[2];
+               r1 = Init1 & r2;
+               r0 = r3 | A[1];
+               A[2] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) |                                       ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
+                      if(D == 2) goto Nextchar;
+               r3 = B[3];
+               r1 = Init1 & r3;
+               r0 = r2 | A[2];
+               A[3] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) |                                       ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
+                      if(D == 3) goto Nextchar;
+               r2 = B[4];
+               r1 = Init1 & r2;
+               r0 = r3 | A[3];
+               A[4] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) |                                        ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
+                      if(D == 4)  goto Nextchar;
+            }  /* if(CMask) */
+ 	   else  {
+               r2 = B[0];
+               A[0] = r2 & Init1; 
+               r3 = B[1];
+               r1 = Init1 & r3;
+               r0 = r2 | A[0];
+               A[1] = ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
+                    if(D == 1) goto Nextchar;
+               r2 = B[2];
+               r1 = Init1 & r2;
+               r0 = r3 | A[1];
+               A[2] = ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
+                    if(D == 2) goto Nextchar;
+               r3 = B[3];
+               r1 = Init1 & r3;
+               r0 = r2 | A[2];
+               A[3] = ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
+                    if(D == 3) goto Nextchar;
+               r2 = B[4];
+               r1 = Init1 & r2;
+               r0 = r3 | A[3];
+               A[4] = ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
+                    if(D == 4) goto Nextchar;
+            }
+         }
+         else {  j++;
+               r1 = Init1 & B[D];            /* match against endofline */
+               A[D] = ((Next[B[D]>>hh] | Next1[B[D]&LL]) & CMask) | r1;
+               if(TAIL) A[D] = ( Next[A[D]>>hh] | Next1[A[D]&LL] ) | A[D]; 
+                                            /* epsilon move */
+               if(( A[D] & 1 ) ^ INVERSE) {
+                    if(FILENAMEONLY) {
+                           num_of_matched++;
+                           printf("%s\n", CurrentFileName);
+                           return;
+                    } 
+                    r_output(buffer, i, end, j);
+               }
+               for(k=0; k<=D; k++)  B[k] = Init[0];
+               r1 = Init1 & B[0];
+               A[0] = (( Next[B[0]>>hh] | Next1[B[0]&LL]) & CMask) | r1;
+               for(k=1; k<=D; k++) {
+                    r3 = B[k];
+                    r1 = Init1 & r3;
+                    r2 = A[k-1] | B[k-1];
+                    A[k] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) |                                       ((B[k-1] | Next[r2>>hh] | Next1[r2&LL]) & r_NO_ERR) | r1;
+               }
+         }
+ Nextchar: i=i+1;
+         c = buffer[i];
+         CMask = Mask[c];
+         if(c != Newline)
+         {
+            if(CMask != 0) {  
+               r2 = A[0];
+               r1 = Init1 & r2;
+               B[0] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) | r1;
+               r3 = A[1];
+               r1 = Init1 & r3;
+               r0 = B[0] | r2;
+               B[1] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) |                                       ((r2 | Next[r0>>hh] | Next1[r0&LL]) & r_NO_ERR) | r1 ;  
+                      if(D == 1) goto Nextchar1;
+               r2 = A[2];
+               r1 = Init1 & r2;
+               r0 = B[1] | r3;
+               B[2] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) |                                   ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
+                      if(D == 2) goto Nextchar1;
+               r3 = A[3];
+               r1 = Init1 & r3;
+               r0 = B[2] | r2;
+               B[3] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) |                                       ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
+                      if(D == 3) goto Nextchar1;
+               r2 = A[4];
+               r1 = Init1 & r2;
+               r0 = B[3] | r3;
+               B[4] = ((Next[r2>>hh] | Next1[r2&LL]) & CMask) |                                       ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
+                      if(D == 4)   goto Nextchar1;
+            }  /* if(CMask) */
+ 	   else  {
+               r2 = A[0];
+               B[0] = r2 & Init1; 
+               r3 = A[1];
+               r1 = Init1 & r3;
+               r0 = B[0] | r2;
+               B[1] = ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
+                    if(D == 1) goto Nextchar1;
+               r2 = A[2];
+               r1 = Init1 & r2;
+               r0 = B[1] | r3;
+               B[2] = ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
+                    if(D == 2) goto Nextchar1;
+               r3 = A[3];
+               r1 = Init1 & r3;
+               r0 = B[2] | r2;
+               B[3] = ((r2 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
+                    if(D == 3) goto Nextchar1;
+               r2 = A[4];
+               r1 = Init1 & r2;
+               r0 = B[3] | r3;
+               B[4] = ((r3 | Next[r0>>hh] | Next1[r0&LL])&r_NO_ERR) | r1 ;  
+                    if(D == 4) goto Nextchar1;
+            }
+         } /* if(NOT Newline) */
+         else {  j++;
+               r1 = Init1 & A[D];            /* match against endofline */
+               B[D] = ((Next[A[D]>>hh] | Next1[A[D]&LL]) & CMask) | r1;
+               if(TAIL) B[D] = ( Next[B[D]>>hh] | Next1[B[D]&LL] ) | B[D]; 
+                                            /* epsilon move */
+               if(( B[D] & 1 ) ^ INVERSE) {
+                    if(FILENAMEONLY) {
+                           num_of_matched++;
+                           printf("%s\n", CurrentFileName);
+                           return;
+                    } 
+                    r_output(buffer, i, end, j);
+               }
+               for(k=0; k<=D; k++) A[k] = Init0; 
+               r1 = Init1 & A[0];
+               B[0] = ((Next[A[0]>>hh] | Next1[A[0]&LL]) & CMask) | r1;
+               for(k=1; k<=D; k++) {
+                    r3 = A[k];
+                    r1 = Init1 & r3;
+                    r2 = A[k-1] | B[k-1];
+                    B[k] = ((Next[r3>>hh] | Next1[r3&LL]) & CMask) |                                       ((A[k-1] | Next[r2>>hh] | Next1[r2&LL]) & r_NO_ERR) | r1;
+               }
+         }
+ Nextchar1: i=i+1;
+     } /* while */
+     strncpy(buffer, buffer+num_read, Maxline);
+   } /* while */
+   return;
+ } /* re1 */
+    
+ void re(int Text, int M, int D)
+ {
+   register unsigned i, c, r1, r2, r3, CMask, k, Newline, Init0, Init1, end; 
+   register unsigned r_even, r_odd, r_NO_ERR ;
+   unsigned RMask[MAXSYM];
+   unsigned A[MaxRerror+1], B[MaxRerror+1];
+   int num_read, j=0, lasti, base, ResidueSize; 
+   int FIRST_TIME; /* Flag */ 
+   base = WORD - M;
+   k = 2*exponen(M);
+   if(FIRST_IN_RE) {
+          compute_next(M, Next, Next1); 
+          FIRST_IN_RE = 0;    }
+   for(i=0; i< MAXSYM; i++) RMask[i] = Mask[i];
+   r_NO_ERR = NO_ERR_MASK;
+   Newline = '\n';
+   lasti = Maxline;
+   Init0 = Init[0] = Bit[base];
+   if(HEAD) Init0  = Init[0] = Init0 | Bit[base+1] ;
+   for(i=1; i<= D; i++) Init[i] = Init[i-1] | Next[Init[i-1]]; /* can be out? */
+   Init1 = Init0 | 1; 
+   r2 = r3 = Init0;
+   for(k=0; k<= D; k++) { A[k] = B[k] = Init[0]; }  /* can be out? */
+   FIRST_TIME = ON;
+   if ( D == 0 )
+   {
+     while ((num_read = read(Text, buffer + Maxline, BlockSize)) > 0)
+     {
+       i=Maxline; end = Maxline + num_read ;
+       if((num_read < BlockSize)&&buffer[end-1] != '\n') buffer[end] = '\n';
+       if(FIRST_TIME) {
+          buffer[i-1] = '\n';
+ 	 i--;
+          FIRST_TIME = 0;
+       }
+       while (i < end) 
+       {              
+         c = buffer[i++];
+         CMask = RMask[c];
+         if(c != Newline)
+         {  
+               r1 = Init1 & r3;
+               r2 = (Next[r3] & CMask) | r1;
+         }
+         else {  
+               r1 = Init1 & r3;            /* match against '\n' */
+               r2 = Next[r3] & CMask | r1;
+               j++;
+               if(TAIL) r2 = Next[r2] | r2 ;   /* epsilon move */
+               if(( r2 & 1) ^ INVERSE) {
+                    if(FILENAMEONLY) {
+                           num_of_matched++;
+                           printf("%s\n", CurrentFileName);
+                           return;
+                    } 
+                    r_output(buffer, i-1, end, j);
+               }
+               lasti = i - 1;
+               r3 = Init0;
+               r2 = (Next[r3] & CMask) | Init0;
+         }
+         c = buffer[i++];   
+         CMask = RMask[c];
+         if(c != Newline)
+         {
+               r1 = Init1 & r2;
+               r3 = (Next[r2] & CMask) | r1;
+         }
+         else {  j++;
+               r1 = Init1 & r2;            /* match against endofline */
+               r3 = Next[r2] & CMask | r1;
+               if(TAIL) r3 = Next[r3] | r3;
+               if(( r3 & 1) ^ INVERSE) {
+                    if(FILENAMEONLY) {
+                           num_of_matched++;
+                           printf("%s\n", CurrentFileName);
+                           return;
+                    } 
+                    r_output(buffer, i-1, end, j);
+               }
+               lasti = i - 1;
+               r2 = Init0; 
+               r3 = (Next[r2] & CMask) | Init0;  /* match the newline */
+         }
+       } /* while */
+       ResidueSize = Maxline + num_read - lasti;
+       if(ResidueSize > Maxline) {
+            ResidueSize = Maxline;  }
+       strncpy(buffer+Maxline-ResidueSize, buffer+lasti, ResidueSize);
+       lasti = Maxline - ResidueSize;
+     } /* while */
+   return;
+   } /* end if(D==0) */
+   while ((num_read = read(Text, buffer + Maxline, BlockSize)) > 0)
+   {
+     i=Maxline; end = Maxline+num_read;
+     if((num_read < BlockSize) && buffer[end-1] != '\n') buffer[end] = '\n';
+     if(FIRST_TIME) {
+         buffer[i-1] = '\n';
+ 	i--;
+         FIRST_TIME = 0;
+     }
+     while (i < end)
+     {   c = buffer[i++];
+         CMask = RMask[c];
+         if (c != Newline)
+         {  
+               r_even = B[0];
+               r1 = Init1 & r_even;
+               A[0] = (Next[r_even] & CMask) | r1;
+               r_odd = B[1];
+               r1 = Init1 & r_odd;
+               r2 = (r_even | Next[r_even|A[0]]) &r_NO_ERR;
+               A[1] = (Next[r_odd] & CMask) | r2 | r1 ;  
+                      if(D == 1) goto Nextchar;
+               r_even = B[2];
+               r1 = Init1 & r_even;
+               r2 = (r_odd | Next[r_odd|A[1]]) &r_NO_ERR;
+               A[2] = (Next[r_even] & CMask) | r2 | r1 ;  
+                      if(D == 2) goto Nextchar;
+               r_odd = B[3];
+               r1 = Init1 & r_odd;
+               r2 = (r_even | Next[r_even|A[2]]) &r_NO_ERR;
+               A[3] = (Next[r_odd] & CMask) | r2 | r1 ;  
+                      if(D == 3) goto Nextchar;
+               r_even = B[4];
+               r1 = Init1 & r_even;
+               r2 = (r_odd | Next[r_odd|A[3]]) &r_NO_ERR;
+               A[4] = (Next[r_even] & CMask) | r2 | r1 ;  
+               goto Nextchar;
+         } /* if NOT Newline */
+         else {  j++;
+               r1 = Init1 & B[D];               /* match endofline */
+               A[D] = (Next[B[D]] & CMask) | r1;
+               if(TAIL) A[D] = Next[A[D]] | A[D];
+               if((A[D] & 1) ^ INVERSE )  {
+                    if(FILENAMEONLY) {
+                           num_of_matched++;    
+                           printf("%s\n", CurrentFileName);
+                           return;
+                    }  
+                    r_output(buffer, i-1, end, j);
+               }
+               for(k=0; k<= D; k++) { A[k] = B[k] = Init[k]; }
+               r1 = Init1 & B[0]; 
+               A[0] = (Next[B[0]] & CMask) | r1;
+               for(k=1; k<= D; k++) {
+                     r1 = Init1 & B[k];
+                     r2 = (B[k-1] | Next[A[k-1]|B[k-1]]) &r_NO_ERR;
+                     A[k] = (Next[B[k]] & CMask) | r1 | r2;
+               }
+         }
+ Nextchar: 
+         c = buffer[i];
+         CMask = RMask[c];
+         if(c != Newline)
+         { 
+               r1 = Init1 & A[0];
+               B[0] = (Next[A[0]] & CMask) | r1;
+               r1 = Init1 & A[1];
+               B[1] = (Next[A[1]] & CMask) |                                                          ((A[0] | Next[A[0] | B[0]]) & r_NO_ERR) | r1 ;  
+                      if(D == 1) goto Nextchar1;
+               r1 = Init1 & A[2];
+               B[2] = (Next[A[2]] & CMask) | ((A[1] | Next[A[1] | B[1]]) &r_NO_ERR) | r1 ;  
+                      if(D == 2) goto Nextchar1;
+               r1 = Init1 & A[3];
+               B[3] = (Next[A[3]] & CMask) | ((A[2] | Next[A[2] | B[2]])&r_NO_ERR) | r1 ;  
+                      if(D == 3) goto Nextchar1;
+               r1 = Init1 & A[4];
+               B[4] = (Next[A[4]] & CMask) | ((A[3] | Next[A[3] | B[3]])&r_NO_ERR) | r1 ;  
+               goto Nextchar1;
+         } /* if(NOT Newline) */
+         else {  j++;
+               r1 = Init1 & A[D];               /* match endofline */
+               B[D] = (Next[A[D]] & CMask) | r1;
+               if(TAIL) B[D] = Next[B[D]] | B[D];
+               if((B[D] & 1) ^ INVERSE )  {
+                    if(FILENAMEONLY) {
+                           num_of_matched++;
+                           printf("%s\n", CurrentFileName);
+                           return;
+                    } 
+                    r_output(buffer, i, end, j);
+               }
+               for(k=0; k<= D; k++) { A[k] = B[k] = Init[k]; }
+               r1 = Init1 & A[0]; 
+               B[0] = (Next[A[0]] & CMask) | r1;
+               for(k=1; k<= D; k++) {
+                     r1 = Init1 & A[k];
+                     r2 = (A[k-1] | Next[A[k-1]|B[k-1]])&r_NO_ERR;
+                     B[k] = (Next[A[k]] & CMask) | r1 | r2;
+               }
+         }
+ Nextchar1: i++;
+     } /* while i < end */
+     strncpy(buffer, buffer+num_read, Maxline);
+   } /* while  read() */
+   return;
+ } /* re */
+ 
+ 
+ void r_output(CHAR *buffer, int i, int end, int j)
+ {
+ int bp;
+       if(i >= end) return;
+       num_of_matched++;
+       if(COUNT)  return; 
+       if(FNAME) printf("%s: ", CurrentFileName);
+       bp = i-1;
+       while ((buffer[bp] != '\n') && (bp > 0)) bp--;
+       if(LINENUM) printf("%d: ", j); 
+       if(buffer[bp] != '\n') bp = Maxline-1;
+       bp++; 
+       while (bp <= i ) putchar(buffer[bp++]);
+ }
+ 
+ void file_out(char *fname)
+ {
+ int num_read;
+ int fd;
+ int i, len;
+ CHAR buf[4097];
+ 	if(FNAME) {
+ 		len = strlen(fname);
+ 		putchar('\n');
+ 		for(i=0; i< len; i++) putchar(':');
+ 		putchar('\n');
+ 		printf("%s\n", CurrentFileName);
+ 		len = strlen(fname);
+ 		for(i=0; i< len; i++) putchar(':');
+ 		putchar('\n');
+ 		fflush(stdout);
+ 	}
+ 	fd = open(fname, 0);
+ 	while((num_read = read(fd, buf, 4096)) > 0) 
+ 		write(1, buf, num_read);
+ }
+ 
+ 
+ void usage(void)
+ {
+     	fprintf(stderr, "usage: %s [-#cdehiklnpstvwxBDGIS] [-f patternfile] pattern [files]\n", Progname); 
+  	printf("\n");	
+ 	fprintf(stderr, "summary of frequently used options:\n");
+ 	fprintf(stderr, "-#: find matches with at most # errors\n");
+ 	fprintf(stderr, "-c: output the number of matched records\n");
+ 	fprintf(stderr, "-d: define record delimiter\n");
+ 	fprintf(stderr, "-h: do not output file names\n");
+ 	fprintf(stderr, "-i: case-insensitive search, e.g., 'a' = 'A'\n");
+ 	fprintf(stderr, "-l: output the names of files that contain a match\n");
+ 	fprintf(stderr, "-n: output record prefixed by record number\n");
+ 	fprintf(stderr, "-v: output those records containing no matches\n");
+ 	fprintf(stderr, "-w: pattern has to match as a word, e.g., 'win' will not match 'wind'\n");
+ 	fprintf(stderr, "-B: best match mode. find the closest matches to the pattern\n"); 
+ 	fprintf(stderr, "-G: output the files that contain a match\n");
+  	printf("\n");	
+ 
+     	exit(2);
+ }
+ 
+ void checksg(CHAR *Pattern, int D)
+ {                          
+   char c;
+   int i, m;
+   m = strlen(Pattern);
+   if(!(PAT_FILE) && m <= D) {
+       fprintf(stderr, "%s: size of pattern must be greater than number of errors\n", Progname);
+       exit(2);
+   }
+   SIMPLEPATTERN = ON;
+   for (i=0; i < m; i++) 
+   {
+       switch(Pattern[i])
+       {
+          case ';' : SIMPLEPATTERN = OFF; break;
+          case ',' : SIMPLEPATTERN = OFF; break;
+          case '.' : SIMPLEPATTERN = OFF; break;
+          case '*' : SIMPLEPATTERN = OFF; break;
+          case '-' : SIMPLEPATTERN = OFF; break;
+          case '[' : SIMPLEPATTERN = OFF; break;
+          case ']' : SIMPLEPATTERN = OFF; break;
+          case '(' : SIMPLEPATTERN = OFF; break;
+          case ')' : SIMPLEPATTERN = OFF; break;
+          case '<' : SIMPLEPATTERN = OFF; break;
+          case '>' : SIMPLEPATTERN = OFF; break;
+          case '^' : if(D > 0) SIMPLEPATTERN = OFF; 
+ 		    break;
+          case '$' : if(D > 0) SIMPLEPATTERN = OFF; 
+ 		    break;
+          case '|' : SIMPLEPATTERN = OFF; break;
+          case '#' : SIMPLEPATTERN = OFF; break;
+          case '\\' : SIMPLEPATTERN = OFF; break;
+          default  : break;
+       }
+   }
+   if (CONSTANT) SIMPLEPATTERN = ON;
+   if (SIMPLEPATTERN == OFF) return;
+   if (NOUPPER && D) return;     
+   if (JUMP == ON) return;
+   if (I == 0) return;
+   if (LINENUM) return;
+   if (DELIMITER) return;   
+   if (INVERSE) return;
+   if (WORDBOUND && D > 0) return;  
+   if (WHOLELINE && D > 0) return;  
+   if (SILENT) return;     /* REMINDER: to be removed */
+   SGREP = ON;
+   if(m >= 16) DNA = ON;
+   for(i=0; i<m; i++) {
+ 	c = Pattern[i];
+ 	if(c == 'a' || c == 'c' || c == 't' || c == 'g' ) ;
+ 	else DNA = OFF;
+   }
+   return;
+ }
+ 
+ void output(register CHAR *buffer, int i1, int i2, int j)  
+ {
+ register CHAR *bp, *outend;
+ 	if(i1 > i2) return;
+         num_of_matched++;
+         if(COUNT)  return;
+         if(SILENT) return;
+ 	if(OUTTAIL) {
+               i1 = i1 + D_length;
+               i2 = i2 + D_length;
+         }
+         if(DELIMITER) j = j+1;
+         if(FIRSTOUTPUT) {
+            if (buffer[i1] == '\n')  {
+                i1++;
+                EATFIRST = ON;
+            }
+            FIRSTOUTPUT = 0;
+         }
+         if(TRUNCATE) {
+            fprintf(stderr, "WARNING!!!  some lines have been truncated in output record #%d\n", num_of_matched-1);
+         }
+         while(buffer[i1] == '\n' && i1 <= i2) {
+ 	   printf("\n");
+            i1++;
+         }
+         if(FNAME == ON) printf("%s: ", CurrentFileName);
+         if(LINENUM) printf("%d: ", j-1); 
+ 	bp = buffer + i1;
+ 	outend = buffer + i2;
+ 	while(bp <= outend) putchar(*bp++);
+ }
+ 
+ /* end of main.c */


Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/maskgen.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/maskgen.c:1.1
*** /dev/null	Tue Oct  5 13:03:12 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/maskgen.c	Tue Oct  5 13:02:58 2004
***************
*** 0 ****
--- 1,167 ----
+ /* Copyright (c) 1991 Sun Wu and Udi Manber.  All Rights Reserved. */
+ #include "agrep.h"
+  
+ extern unsigned D_endpos, endposition, Init1, wildmask;
+ extern Mask[], Bit[], Init[], NO_ERR_MASK;
+ extern int AND, SIMPLEPATTERN, REGEX, NOUPPER, D_length;
+ extern unsigned char Progname[];
+ 	   
+ int maskgen(unsigned char *Pattern, int D)
+ {
+ struct term { int flag; unsigned char class1[WORD];
+             } position[WORD+10];
+ unsigned char c;
+ 
+ int i, j, k, l, M, OR=0, EVEN = 0, base, No_error;
+ 
+ 
+ for(i=0; i<WORD; i++) position[i].class1[0] = '\0';
+ for(i=0; i<WORD; i++) position[i].flag = 0;
+ wildmask = NO_ERR_MASK = endposition = 0;
+ No_error = 0;
+ M = strlen(Pattern);
+ if(NOUPPER) {
+               for(i=0; i<M; i++) if(isalpha(Pattern[i])) 
+                      if (isupper(Pattern[i])) Pattern[i] = tolower(Pattern[i]);
+             }
+ #ifdef DEBUG
+ 	for(i=0; i<M; i++) printf(" %d", Pattern[i]);
+ 	printf("\n");
+ #endif
+ for (i=0, j=1; i< M; i++)
+ {
+   switch (Pattern[i])
+   {
+     case WILDCD : if(REGEX) {
+                      position[j].class1[0] = '.';
+                      position[j].class1[1] = '.';
+                      position[j++].class1[2] = '\0'; 
+                      break;
+                   }
+                   wildmask = wildmask | Bit[j-1]; break;
+     case STAR   : break; 
+     case ORSYM  : break; 
+     case LPARENT: break;
+     case RPARENT: break;
+     case LANGLE : No_error = ON; EVEN++;
+                   break;
+     case RANGLE : No_error = OFF; EVEN--;
+                   if(EVEN < 0) {
+                      fprintf(stderr, "%s: illegal pattern, unmatched '<', '>'\n", Progname);
+                      exit(2);
+                   }
+                   break;
+     case LRANGE : if(No_error == ON) NO_ERR_MASK = NO_ERR_MASK | Bit[j]; 
+                   i=i+1; 
+                   if (Pattern[i] == NOTSYM) { position[j].flag = Compl; i++; }
+                   k=0;
+                   while (Pattern[i] != RRANGE && i < M)
+                   { 
+                     if(Pattern[i] == HYPHEN) 
+                        { position[j].class1[k-1] = Pattern[i+1]; i=i+2; }
+                     else { 
+                      position[j].class1[k] = position[j].class1[k+1] = Pattern[i];
+                      k = k+2; i++;
+                     }
+                   }
+                   if(i == M) {
+                      fprintf(stderr, "%s: illegal pattern, unmatched '[', ']'\n",Progname);
+                      exit(2);
+                   }
+                   position[j].class1[k] = '\0';
+                   j++; break;
+     case RRANGE : fprintf(stderr, "%s: illegal pattern, unmatched '[', ']'\n", Progname); 
+                   exit(2);
+                   break;     
+     case ORPAT  : if(REGEX == ON || AND == ON) {
+                      fprintf(stderr, "illegal pattern \n");
+                      exit(2);
+                   }
+                   OR = ON;
+                   position[j].flag = 2; position[j].class1[0] = '\0';
+                   endposition = endposition | Bit[j++]; break;
+     case ANDPAT : position[j].flag = 2; position[j].class1[0] = '\0'; 
+                   if(j > D_length) AND = ON;
+                   if(OR || (REGEX == ON && j>D_length)) {
+                      fprintf(stderr, "illegal pattern \n");
+                      exit(2);
+                   }
+                   endposition = endposition | Bit[j++]; break;
+ /*
+     case ' '    : if (Pattern[i-1] == ORPAT || Pattern[i-1] == ANDPAT) break;
+                   if(No_error == ON) NO_ERR_MASK = NO_ERR_MASK | Bit[j];
+                   position[j].flag = 0;
+                   position[j].class1[0] = position[j].class1[1] = Pattern[i];
+                   position[j++].class1[2] = '\0';  break;
+ */
+     case '\n'   : NO_ERR_MASK = NO_ERR_MASK | Bit[j];
+                   position[j].class1[0] = position[j].class1[1] = '\n';
+                   position[j++].class1[2] = '\0'; 
+                   break;
+     case WORDB  : NO_ERR_MASK = NO_ERR_MASK | Bit[j];
+                   position[j].class1[0] = 1;
+                   position[j].class1[1] = 47;
+                   position[j].class1[2] = 58;
+                   position[j].class1[3] = 64;
+                   position[j].class1[4] = 91;
+                   position[j].class1[5] = 96;
+                   position[j].class1[6] = 123;
+                   position[j].class1[7] = 127;
+                   position[j++].class1[8] = '\0';
+                   break;    
+     case NNLINE : NO_ERR_MASK |= Bit[j];
+                   position[j].class1[0] = position[j].class1[1] = '\n';
+                   position[j].class1[2] = position[j].class1[3] = NNLINE;
+                   position[j++].class1[4] = '\0';
+                   break;
+     default : if(No_error == ON) NO_ERR_MASK = NO_ERR_MASK | Bit[j];
+                   position[j].flag = 0;
+                   position[j].class1[0] = position[j].class1[1] = Pattern[i];
+                   position[j++].class1[2] = '\0'; 
+   }
+   if(j > WORD) {
+      fprintf(stderr, "%s: pattern too long\n", Progname);
+      exit(2);
+   }
+ }
+   if (EVEN != 0) {
+      fprintf(stderr, "%s: illegal pattern, unmatched '<', '>'\n", Progname);
+      exit(2);
+   }
+ M = j - 1;
+ base = WORD - M;
+ wildmask = (wildmask >> base);
+ endposition = (endposition >> base);
+ NO_ERR_MASK = (NO_ERR_MASK >> 1) & (~Bit[1]);
+ NO_ERR_MASK = ~NO_ERR_MASK >> (base-1);
+   for (i=1; i<= WORD - M ; i++) Init[0] = Init[0] | Bit[i];
+   Init[0] = Init[0] | endposition;
+              /* not necessary for INit[i], i>0, */
+              /* but at every begining of the matching process append one
+                 no-match character to initialize the error vectors */
+   endposition = ( endposition << 1 ) + 1;
+   Init1 = (Init[0] | wildmask | endposition) ;
+   D_endpos = ( endposition >> ( M - D_length ) ) << ( M - D_length);
+   endposition = endposition ^ D_endpos;
+ #ifdef DEBUG
+ 	printf("endposition: %o\n", endposition);
+ 	printf("no_err_mask: %o\n", NO_ERR_MASK);
+ #endif
+   for(c=0, i=0; i < MAXSYM; c++, i++)
+   {
+      for (k=1, l=0; k<=M ; k++, l=0)  {
+          while (position[k].class1[l] != '\0') {
+                if (position[k].class1[l] == NOCARE && (c != '\n' || REGEX) ) 
+                   {  Mask[c] = Mask[c] | Bit[base + k]; break; }
+                if (c >= position[k].class1[l] && c <= position[k].class1[l+1])
+                   {  Mask[c] = Mask[c] | Bit[base + k]; break; }
+                l = l + 2;  }
+          if (position[k].flag == Compl) Mask[c] = Mask[c] ^ Bit[base+k];
+      }
+   }
+   if(NOUPPER) for(c='A'; c<='Z'; c=c+1) if (isupper(c)) 
+                   Mask[c] = Mask[tolower(c)]; 
+   return(M);
+ }
+ 
+ 


Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/mgrep.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/mgrep.c:1.1
*** /dev/null	Tue Oct  5 13:03:12 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/mgrep.c	Tue Oct  5 13:02:58 2004
***************
*** 0 ****
--- 1,321 ----
+ /* Copyright (c) 1991 Sun Wu and Udi Manber.  All Rights Reserved. */
+ /* multipattern matcher */
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <ctype.h>
+ #define MAXPAT  256
+ #define MAXLINE 1024
+ #define MAXSYM  256
+ #define MAXMEMBER1 4096
+ #define MAXPATFILE 260000
+ #define BLOCKSIZE  8192
+ #define MAXHASH    8192
+ #define mm 	   8191
+ #define max_num    30000  
+ #define W_DELIM	   128
+ #define L_DELIM    10 
+ 
+ extern COUNT, FNAME, SILENT, FILENAMEONLY, num_of_matched;
+ extern INVERSE;
+ extern WORDBOUND, WHOLELINE, NOUPPER;
+ extern unsigned char  CurrentFileName[], Progname[]; 
+ extern total_line;
+ 
+ int LONG  = 0;
+ int SHORT = 0;
+ int p_size=0;
+ unsigned char SHIFT1[MAXMEMBER1];
+ unsigned char tr[MAXSYM];
+ unsigned char tr1[MAXSYM];
+ struct pat_list {
+ 	int  index;
+ 	struct pat_list *next;
+ } *HASH[MAXHASH];
+ struct pat_list  *pt, *qt;
+ unsigned char buf[MAXPATFILE+BLOCKSIZE];
+ unsigned char pat_spool[MAXPATFILE+2*max_num+MAXPAT];
+ unsigned char *patt[max_num];
+ unsigned char pat_len[max_num];
+ 
+ extern char *strncpy(char *, const char *, size_t);
+ 
+ void countline(unsigned char *text, int len)
+ {
+ int i;
+ 	for (i=0; i<len; i++) if(text[i] == '\n') total_line++;
+ }
+ 
+ void m_short( register unsigned char *text, int start, int end  )
+ {
+ register unsigned char *textend;
+ register int  j; 
+ register struct pat_list *p;
+ register int pat_index; 
+ int MATCHED=0;
+ int OUT=0;
+ unsigned char *lastout;
+ unsigned char *qx;
+ 
+ textend = text + end;
+ lastout = text + start + 1;
+ text = text + start - 1 ;
+ while (++text <= textend) {
+ 		p = HASH[*text];
+ 		while(p != 0) {
+ 			pat_index = p->index;
+ 			p = p->next;
+ 			qx = text;
+ 			j = 0;
+ 			while(tr[patt[pat_index][j]] == tr[*(qx++)]) j++;
+ 			if(pat_len[pat_index] <= j) {
+ 				if(text >= textend) return;
+                 		num_of_matched++;
+                 		if(FILENAMEONLY || SILENT)  return;
+ 	        		if(COUNT) {
+ 			  		while (*text != '\n') text++;
+ 				}
+ 				else {
+ 			  	    if(FNAME) printf("%s: ",CurrentFileName);
+ 				    if(!INVERSE) {
+                           		while(*(--text) != '\n');
+                           		while(*(++text) != '\n') putchar(*text);
+ 			  		printf("\n");
+ 					MATCHED = 1;
+ 				    }
+ 				    else {
+                           		while(*(--text) != '\n');
+ 					if(lastout < text) OUT=1;
+ 					while(lastout < text) putchar(*lastout++);
+ 					if(OUT) {
+ 						putchar('\n');
+ 						OUT=0;
+ 					}
+                           		while(*(++text) != '\n');
+ 					lastout=text+1;
+ 					MATCHED = 1;
+ 				    }
+ 				}
+                 	}
+ 			if(MATCHED) break;
+ 		}
+ 		MATCHED = 0;
+   } /* while */
+   if(INVERSE && !COUNT) while(lastout <= textend) putchar(*lastout++);
+ }
+ 
+ void f_prep(int pat_index, unsigned char *Pattern)
+ {
+ int i, m;
+ register unsigned hash, Mask=15;
+ 	m = p_size;
+ 	for (i = m-1; i>=(1+LONG); i--) {
+ 		hash = (Pattern[i] & Mask);
+ 		hash = (hash << 4) + (Pattern[i-1]& Mask);
+ 		if(LONG) hash = (hash << 4) + (Pattern[i-2] & Mask);
+ 		if(SHIFT1[hash] >= m-1-i) SHIFT1[hash] = m-1-i;
+ 	}
+ 	if(SHORT) Mask = 255;  /* 011111111 */
+ 	hash = 0;
+ 	for(i = m-1; i>=0; i--)  {
+ 	    hash = (hash << 4) + (tr[Pattern[i]]&Mask);
+ 	}
+ /*
+ 	if(INVERSE) hash = Pattern[1];
+ */
+ 	hash=hash&mm;
+ 	qt = (struct pat_list *) malloc(sizeof(struct pat_list));
+ 	qt->index = pat_index;
+ 	pt = HASH[hash];
+ 	qt->next = pt;
+ 	HASH[hash] = qt;
+ }
+ 
+ void prepf(int fp)
+ {
+     int length=0, i, p=1, num_pat;
+     unsigned char *pat_ptr=pat_spool;
+     unsigned Mask = 15;
+     int num_read;
+ 
+     while((num_read = read(fp, buf+length, BLOCKSIZE)) > 0) {
+ 	length = length + num_read;
+ 	if(length > MAXPATFILE) {
+ 		fprintf(stderr, "%s: maximum pattern file size is %d\n", Progname, MAXPATFILE);
+ 		exit(2);
+ 	}
+     }
+     buf[length] = '\n';
+     i = 0; p=1;
+     while(i<length) {
+ 	patt[p] = pat_ptr;
+ 	if(WORDBOUND) *pat_ptr++ = W_DELIM;
+ 	if(WHOLELINE) *pat_ptr++ = L_DELIM;
+ 	while((*pat_ptr = buf[i++]) != '\n') pat_ptr++;
+ 	if(WORDBOUND) *pat_ptr++ = W_DELIM;
+ 	if(WHOLELINE) *pat_ptr++ = L_DELIM;           /* Can't be both on */
+ 	*pat_ptr++ = 0;
+ 	p++;  
+     }
+     if(p>max_num) {
+ 	fprintf(stderr, "%s: maximum number of patterns is %d\n", Progname, max_num); 
+ 	exit(2);
+     }
+     for(i=1; i<20; i++) *pat_ptr = i;  /* boundary safety zone */
+     for(i=0; i< MAXSYM; i++) tr[i] = i;
+     if(NOUPPER) {
+ 	for(i='A'; i<= 'Z'; i++) tr[i] = i + 'a' - 'A';
+     }
+     if(WORDBOUND) {
+ 	for(i=0; i<128; i++) if(!isalnum(i)) tr[i] = W_DELIM;
+     }
+     for(i=0; i< MAXSYM; i++) tr1[i] = tr[i]&Mask;
+     num_pat = p-1;
+     p_size = MAXPAT;
+     for(i=1 ; i <= num_pat; i++) {
+ 	p = strlen(patt[i]);
+ 	pat_len[i] = p;
+ 	if(p!=0 && p < p_size) p_size = p;
+     }
+     if(p_size == 0) {
+ 	fprintf(stderr, "the pattern file is empty\n");
+ 	exit(2);
+     }
+     if(length > 400 && p_size > 2) LONG = 1;
+     if(p_size == 1) SHORT = 1;
+     for(i=0; i<MAXMEMBER1; i++) SHIFT1[i] = p_size - 2;
+     for(i=0; i<MAXHASH; i++) {
+ 	HASH[i] = 0;
+     }
+     for(i=1; i<= num_pat; i++) f_prep(i, patt[i]);
+ }
+ 
+ void monkey1( register unsigned char *text, int start, int end  )
+ {
+ register unsigned char *textend;
+ register unsigned hash, i;
+ register unsigned char shift; 
+ register int  m1, j, Long=LONG; 
+ int pat_index, m=p_size; 
+ int MATCHED=0;
+ register unsigned char *qx;
+ register struct pat_list *p;
+ unsigned char *lastout;
+ int OUT=0;
+ 
+ textend = text + end;
+ m1 = m - 1;
+ lastout = text+start+1;
+ text = text + start + m1 ;
+ while (text <= textend) {
+ 	hash=tr1[*text];
+ 	hash=(hash<<4)+(tr1[*(text-1)]);
+ 	if(Long) hash=(hash<<4)+(tr1[*(text-2)]);
+ 	shift = SHIFT1[hash];
+ 	if(shift == 0) {
+ 		hash=0;
+ 		for(i=0;i<=m1;i++)  {
+ 		    hash=(hash<<4)+(tr1[*(text-i)]);
+ 		}
+ 		hash=hash&mm;
+ 		p = HASH[hash];
+ 		while(p != 0) {
+ 			pat_index = p->index;
+ 			p = p->next;
+ 			qx = text-m1;
+ 			j = 0;
+ 			while(tr[patt[pat_index][j]] == tr[*(qx++)]) j++;
+ 	        	if (j > m1 ) { 
+ 			   if(pat_len[pat_index] <= j) {
+ 				if(text > textend) return;
+                 		num_of_matched++;
+                 		if(FILENAMEONLY || SILENT)  return;
+ 				MATCHED=1;
+ 	        		if(COUNT) {
+ 			  		while (*text != '\n') text++;
+ 				}
+ 				else {
+ 				    if(!INVERSE) {
+ 			  		if(FNAME) printf("%s: ",CurrentFileName);
+                           		while(*(--text) != '\n');
+                           		while(*(++text) != '\n') putchar(*text);
+ 			  		printf("\n");
+ 				    }
+ 				    else {
+ 			  		if(FNAME) printf("%s: ",CurrentFileName);
+                           		while(*(--text) != '\n');
+ 					if(lastout < text) OUT=1;
+ 					while(lastout < text) putchar(*lastout++);
+ 					if(OUT) {
+ 						putchar('\n');
+ 						OUT=0;
+ 					}
+                           		while(*(++text) != '\n');
+ 					lastout=text+1;
+ 				    }
+ 				}
+ /*
+ 				else {
+ 			  		if(FNAME) printf("%s: ",CurrentFileName);
+                           		while(*(--text) != '\n');
+                           		while(*(++text) != '\n') putchar(*text);
+ 			  		printf("\n");
+ 				}
+ */
+ 			   }
+                 	}
+ 			if(MATCHED) break;
+ 		}
+ 		if(!MATCHED) shift = 1;
+ 		else {
+ 			MATCHED = 0;
+ 			shift = m1;
+ 		}
+         }
+ 	text = text + shift;
+   }
+   if(INVERSE && !COUNT) while(lastout <= textend) putchar(*lastout++);
+ }
+ 
+ void mgrep(int fd)
+ { 
+     register char r_newline = '\n';
+     unsigned char text[2*BLOCKSIZE+MAXLINE]; 
+     register int buf_end, num_read, start, end, residue = 0;
+ 
+     text[MAXLINE-1] = '\n';  /* initial case */
+     start = MAXLINE-1;
+ 
+     while( (num_read = read(fd, text+MAXLINE, BLOCKSIZE)) > 0) 
+     {
+        if(INVERSE && COUNT) countline(text+MAXLINE, num_read);
+        buf_end = end = MAXLINE + num_read -1 ;
+        while(text[end]  != r_newline && end > MAXLINE) end--;
+        residue = buf_end - end  + 1 ;
+        text[start-1] = r_newline;
+        if(SHORT) m_short(text, start, end);
+        else      monkey1(text, start, end);
+        if(FILENAMEONLY && num_of_matched) {
+ 		printf("%s\n", CurrentFileName);
+ 		return;
+        }
+        start = MAXLINE - residue;
+        if(start < 0) {
+             start = 1; 
+        }
+        strncpy(text+start, text+end, residue);
+     } /* end of while(num_read = ... */
+     text[MAXLINE] = '\n';
+     text[start-1] = '\n';
+     if(residue > 1) {
+         if(SHORT) m_short(text, start, end);
+         else      monkey1(text, start, end);
+     }
+     return;
+ } /* end mgrep */
+ 
+ 
+ 
+ 
+ 
+ 


Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/parse.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/parse.c:1.1
*** /dev/null	Tue Oct  5 13:03:12 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/parse.c	Tue Oct  5 13:02:58 2004
***************
*** 0 ****
--- 1,319 ----
+ /* the functions in this file parse a string that represents
+    a regular expression, and return a pointer to a syntax
+    tree for that regular expression.				*/
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include "re.h"
+ 
+ #define FALSE	0
+ #define TRUE	1
+ 
+ #define NextChar(s)	 *(*s)++
+ #define Unexpected(s, c) (**s == NUL || **s == c)
+ #define Invalid_range(x, y)    (x == NUL || x == '-' || x == ']' || x < y)
+ 
+ extern Stack Push(Stack *s, Re_node v);
+ extern Re_node Pop(Stack *s);
+ extern Re_node Top(Stack s);
+ extern int Size(Stack s);
+ extern Pset pset_union(Pset s1, Pset s2);
+ extern Pset create_pos(int n);
+ 
+ int final_pos, pos_cnt = 0;
+ 
+ /* retract_token() moves the string pointer back, effectively "unseeing"
+    the last character seen.  It is used only to retract a right paren --
+    the idea is that the incarnation of parse_re() that saw the corresponding
+    left paren is supposed to take care of matching the right paren.  This
+    is necessary to prevent recursive calls from mistakenly eating up someone
+    else's right parens.						    */
+ 
+ #define retract_token(s)    --(*s)
+ 
+ /* mk_leaf() creates a leaf node that is (usually) a literal node.	*/
+ 
+ Re_node mk_leaf(short opval, short type, char ch, Ch_Set cset)
+ {
+     Re_node node; Re_Lit l;
+ 
+     l = (Re_Lit) new_node(l);
+     node = (Re_node) new_node(node);
+     if (l == NULL || node == NULL) return NULL;
+     lit_type(l) = type;
+     lit_pos(l)  = pos_cnt++;
+     if (type == C_SET) lit_cset(l) = cset;
+     else lit_char(l) = ch;			/* type == C_LIT */
+     Op(node) = opval;
+     Lit(node) = l;
+     Nullable(node) = FALSE;
+     Firstpos(node) = create_pos(lit_pos(l));
+     Lastpos(node) = Firstpos(node);
+     return node;
+ }
+ 
+ /* parse_cset() takes a pointer to a pointer to a string and parses
+    a prefix of it denoting a character set literal.  It returns a pointer
+    to a Re_node node, NULL if there is an error.			*/
+ 
+ Re_node parse_cset(char **s)
+ {
+     Ch_Set cs_ptr, curr_ptr, prev_ptr;
+     char ch;
+     Ch_Range range;
+ 
+     if (Unexpected(s, ']')) return NULL;
+     curr_ptr = (Ch_Set) new_node(curr_ptr); cs_ptr = curr_ptr;
+     while (!Unexpected(s, ']')) {
+         range = (Ch_Range)new_node(range);
+ 	curr_ptr->elt = range;
+ 	ch = NextChar(s);
+ 	if (ch == '-') return NULL;	/* invalid range */
+ 	range->low_bd = ch;
+ 	if (**s == NUL) return NULL;
+ 	else if (**s == '-') {		/* character range */
+ 	    (*s)++;
+ 	    if (Invalid_range(**s, ch)) return NULL;
+ 	    else range->hi_bd = NextChar(s);
+ 	}
+ 	else range->hi_bd = ch;
+ 	prev_ptr = curr_ptr;
+ 	curr_ptr = (Ch_Set) new_node(curr_ptr);
+ 	prev_ptr->rest = curr_ptr;
+     };
+     if (**s == ']') {
+ 	prev_ptr->rest = NULL;
+ 	return mk_leaf(LITERAL, C_SET, NUL, cs_ptr);
+     }
+     else return NULL;
+ } /* parse_cset */
+ 
+ 
+ /* parse_wildcard() "parses" a wildcard -- a wildcard is treated as a
+    character range whose values span all ASCII values.  parse_wildcard()
+    creates a node representing such a range.				*/
+ 
+ Re_node parse_wildcard(void)
+ {
+     Ch_Set s; Ch_Range r;
+ 
+     r = (Ch_Range) new_node(r);
+     r->low_bd = ASCII_MIN;	/* smallest ASCII value */
+     r->hi_bd  = ASCII_MAX;	/* greatest ASCII value */
+     s = (Ch_Set) new_node(s);
+     s->elt = r;
+     s->rest = NULL;
+     return mk_leaf(LITERAL, C_SET, NUL, s);
+ }
+ 
+ /* parse_chlit() parses a character literal.  It is assumed that the
+    character in question does not have any special meaning.  It returns
+    a pointer to a node for that literal.				*/
+ 
+ Re_node parse_chlit(char ch)
+ {
+     if (ch == NUL) return NULL;
+     else return mk_leaf(LITERAL, C_LIT, ch, NULL);
+ }
+ 
+ 
+ /* get_token() returns the next token -- this may be a character
+    literal, a character set, an escaped character, a punctuation (i.e.
+    parenthesis), or an operator.  It traverses the character string
+    representing the RE, given by a pointer s; leaves s positioned
+    immediately after the unit it parsed, and returns a pointer to
+    a token node for that unit.  */
+ 
+ Tok_node get_token(char **s)
+ {
+     Tok_node rn = NULL;
+ 
+     if (s == NULL || *s == NULL) return NULL;	/* error */
+     rn = (Tok_node) new_node(rn);
+     if (**s == NUL) tok_type(rn) = EOS; /* end of string */
+     else {
+ 	switch (**s) {
+ 	    case '.':			/* wildcard */
+ 		tok_type(rn) = LITERAL;
+ 		tok_val(rn) =  parse_wildcard();
+ 		if (tok_val(rn) == NULL) return NULL;
+ 		break;
+ 	    case '[':			/* character set literal */
+ 		(*s)++;
+ 		tok_type(rn) = LITERAL;
+ 		tok_val(rn) = parse_cset(s);
+ 		if (tok_val(rn) == NULL) return NULL;
+ 		break;
+ 	    case '(':
+ 	        tok_type(rn) = LPAREN;
+ 		break;
+ 	    case ')' : 
+ 	        tok_type(rn) = RPAREN;
+ 		break;
+ 	    case '*' :
+ 	        tok_type(rn) = OPSTAR;
+ 		break;
+ 	    case '|' :
+ 	        tok_type(rn) = OPALT;
+ 		break;
+ 	    case '?' : 
+ 	        tok_type(rn) = OPOPT;
+ 		break;
+ 	    case '\\':			/* escaped character */
+ 		(*s)++;
+ 	    default :			/* must be ordinary character */
+ 		tok_type(rn) = LITERAL;
+ 		tok_val(rn) = parse_chlit(**s);
+ 		if (tok_val(rn) == NULL) return NULL;
+ 		break;
+ 	} /* switch (**s) */
+ 	(*s)++;
+     } /* else */
+     return rn;
+ }
+ 
+ /* cat2() takes a stack of RE-nodes and, if the stack contains
+    more than one node, returns the stack obtained by condensing
+    the top two nodes of the stack into a single CAT-node.  If there
+    is only one node on the stack,  nothing is done.		    */
+ 
+ Stack cat2(Stack *stk)
+ {
+     Re_node r;
+ 
+     if (stk == NULL) return NULL;
+     if (*stk == NULL || (*stk)->next == NULL) return *stk;
+     r = (Re_node) new_node(r);
+     if (r == NULL) return NULL;	    /* can't allocate memory */
+     Op(r) = OPCAT;
+     Rchild(r) = Pop(stk);
+     Lchild(r) = Pop(stk);
+     if (Push(stk, r) == NULL) return NULL;
+     Nullable(r) = Nullable(Lchild(r)) && Nullable(Rchild(r));
+     if (Nullable(Lchild(r)))
+ 	Firstpos(r) = pset_union(Firstpos(Lchild(r)), Firstpos(Rchild(r)));
+     else Firstpos(r) = Firstpos(Lchild(r));
+     if (Nullable(Rchild(r)))
+ 	Lastpos(r) = pset_union(Lastpos(Lchild(r)), Lastpos(Rchild(r)));
+     else Lastpos(r) = Lastpos(Rchild(r));
+     return *stk;
+ }
+ 
+ /* wrap() takes a stack and an operator, takes the top element of the
+    stack and "wraps" that operator around it, then puts this back on the
+    stack and returns the resulting stack.				*/
+ 
+ Stack wrap(Stack *s, short opv)
+ {
+     Re_node r;
+ 
+     if (s == NULL || *s == NULL) return NULL;
+     r = (Re_node) new_node(r);
+     if (r == NULL) return NULL;
+     Op(r) = opv;
+     Child(r) = Pop(s);
+     if (Push(s, r) == NULL) return NULL;
+     Nullable(r) = TRUE;
+     Firstpos(r) = Firstpos(Child(r));
+     Lastpos(r)  = Lastpos(Child(r));
+     return *s;
+ }
+ 
+ /* mk_alt() takes a stack and a regular expression, creates an ALT-node
+    from the top of the stack and the given RE, and replaces the top-of-stack
+    by the resulting ALT-node.						*/   
+ 
+ Stack mk_alt(Stack *s, Re_node r)
+ {
+     Re_node node;
+ 
+     if (s == NULL || *s == NULL || r == NULL) return NULL;
+     node = (Re_node) new_node(node);
+     if (node == NULL) return NULL;
+     Op(node) = OPALT;
+     Lchild(node) = Pop(s);
+     Rchild(node) = r;
+     if (Push(s, node) == NULL) return NULL;
+     Nullable(node) = Nullable(Lchild(node)) || Nullable(Rchild(node));
+     Firstpos(node) = pset_union(Firstpos(Lchild(node)), Firstpos(Rchild(node)));
+     Lastpos(node) = pset_union(Lastpos(Lchild(node)), Lastpos(Rchild(node)));
+     return *s;
+ }
+ 
+ /* parse_re() takes a pointer to a string and traverses that string,
+    returning a pointer to a syntax tree for the regular expression
+    represented by that string, NULL if there is an error.		*/
+ 
+ Re_node parse_re(char **s, short end)
+ {
+     Stack stk = NULL, temp;
+     Tok_node next_token;
+     Re_node re = NULL;
+ 
+     if (s == NULL || *s == NULL) return NULL;
+     while (TRUE) {
+ 	next_token = get_token(s);
+ 	if (next_token == NULL) return NULL;
+ 	switch (tok_type(next_token)) {
+ 	    case RPAREN:
+ 		retract_token(s);
+ 	    case EOS:
+ 		if (end == tok_type(next_token)) return Top(cat2(&stk));
+ 		else return NULL;
+ 	    case LPAREN:
+ 		re = parse_re(s, RPAREN);
+ 		if (Push(&stk, re) == NULL) return NULL;
+ 		if (tok_type(get_token(s)) != RPAREN || re == NULL) return NULL;
+ 		if (Size(stk) > 2) {
+ 		    temp = stk->next;
+ 		    stk->next = cat2(&temp);	/* condense CAT nodes */
+ 		    if (stk->next == NULL) return NULL;
+ 		    else stk->size = stk->next->size + 1;
+ 		}
+ 		break;
+ 	    case OPSTAR:
+ 		if (wrap(&stk, OPSTAR) == NULL) return NULL;
+ 		break;
+ 	    case OPOPT:
+ 		if (wrap(&stk, OPOPT) == NULL) return NULL;
+ 	        break;
+ 	    case OPALT:
+ 		if (cat2(&stk) == NULL) return NULL;
+ 		re = parse_re(s, end);
+ 	        if (re == NULL) return NULL;
+ 		if (mk_alt(&stk, re) == NULL) return NULL;
+ 		break;
+ 	    case LITERAL:
+ 		if (Push(&stk, tok_val(next_token)) == NULL) return NULL;
+ 		if (Size(stk) > 2) {
+ 		    temp = stk->next;
+ 		    stk->next = cat2(&temp);    /* condense CAT nodes */
+ 		    if (stk->next == NULL) return NULL;
+ 		    else stk->size = stk->next->size + 1;
+ 		}
+ 		break;
+ 	    default:
+ 		printf("parse_re: unknown token type %d\n", tok_type(next_token));
+ 		break;
+ 	}
+     }
+ }
+ 
+ /* parse() essentially just calls parse_re().  Its purpose is to stick an
+    end-of-string token at the end of the syntax tree returned by parse_re().
+    It should really be done in parse_re, but the recursion there makes it
+    more desirable to have it here.					*/
+ 
+ Re_node parse(char *s)
+ {
+     Re_node tree, temp;
+     Stack stk = NULL;
+ 
+     tree = parse_re(&s, NUL);
+     if (tree == NULL || Push(&stk, tree) == NULL) return NULL;
+     temp = mk_leaf(EOS, C_LIT, NUL, NULL);
+     if (temp == NULL || Push(&stk, temp) == NULL) return NULL;
+     final_pos = --pos_cnt;
+     return Top(cat2(&stk));
+ }
+ 


Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/preprocess.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/preprocess.c:1.1
*** /dev/null	Tue Oct  5 13:03:12 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/preprocess.c	Tue Oct  5 13:02:58 2004
***************
*** 0 ****
--- 1,216 ----
+ /* Copyright (c) 1991 Sun Wu and Udi Manber.  All Rights Reserved. */
+ /* substitute metachar with special symbol                               */
+ /* if regularr expression, then set flag REGEX                           */
+ /* if REGEX and MULTIPAT then report error message,                      */
+ /* -w only for single word pattern. If WORDBOUND & MULTIWORD error       */
+ /* process start of line, endof line symbol,                             */
+ /* process -w WORDBOUND option, append special symbol at begin&end of    */
+ /* process -d option before this routine                                 */
+ /* the delimiter pattern is in D_pattern (need to end with '; ')          */
+ /* if '-t' (suggestion: how about -B) the pattern is passed to sgrep     */
+ /* and doesn't go here                                                   */
+ /* in that case, -d is ignored? or not necessary                         */
+ /* upon return, Pattern contains the pattern to be processed by maskgen  */
+ /* D_pattern contains transformed D_pattern                              */
+ #include <stdlib.h>
+ #include <string.h>
+ #include "agrep.h"
+   
+ extern int SIMPLEPATTERN, WHOLELINE, REGEX, RE_ERR, DELIMITER, TAIL, WORDBOUND;
+ extern int HEAD;
+ extern CHAR Progname[];
+ extern int D_length;
+ extern int table[WORD][WORD];
+ 
+ extern int init(char *s, int table[32][32]);
+   
+ void preprocess(CHAR *D_pattern, CHAR *Pattern)   /* need two parameters  */
+ {
+   CHAR temp[Maxline], *r_pat, *old_pat;  /* r_pat for r.e. */
+   CHAR old_D_pat[MaxDelimit];
+   int i, j=0, rp=0, m, t=0, num_pos, ANDON = 0;
+   int d_end ;  
+   int IN_RANGE=0;
+   old_pat = Pattern; /* to remember the starting position */
+   m = strlen(Pattern);
+   for(i=0; i< m; i++) {
+       if(Pattern[i] == '\\') i++;
+       else if(Pattern[i] == '|' || Pattern[i] == '*' ) REGEX = ON;   
+   }
+   r_pat = (CHAR *) malloc(strlen(Pattern)+2*strlen(D_pattern));
+   strcpy(temp, D_pattern);
+   d_end = t = strlen(temp);  /* size of D_pattern, including '; ' */
+   if (WHOLELINE) { temp[t++] = LANGLE; 
+                    temp[t++] = NNLINE; 
+                    temp[t++] = RANGLE;
+                    temp[t] = '\0';
+                    strcat(temp, Pattern);
+                    m = strlen(temp);
+                    temp[m++] = LANGLE; 
+                    temp[m++] = '\n'; 
+                    temp[m++] = RANGLE; 
+                    temp[m] = '\0';  }
+   else {
+      if (WORDBOUND) { temp[t++] = LANGLE; 
+                       temp[t++] = WORDB; 
+                       temp[t++] = RANGLE;
+                       temp[t] = '\0'; }
+      strcat(temp, Pattern);
+      m = strlen(temp);
+      if (WORDBOUND) { temp[m++] = LANGLE; 
+                       temp[m++] = WORDB; 
+                       temp[m++] = RANGLE; }
+      temp[m] = '\0';
+   }
+         /* now temp contains augmented pattern , m it's size */
+ 
+   D_length = 0;
+   for (i=0, j=0; i< d_end-2; i++) {
+       switch(temp[i]) 
+       {
+          case '\\' : i++; 
+                      Pattern[j++] = temp[i];
+                      old_D_pat[D_length++] = temp[i];
+                      break;
+          case '<'  : Pattern[j++] = LANGLE;
+                      break;
+          case '>'  : Pattern[j++] = RANGLE;
+                      break;
+          case '^'  : Pattern[j++] = '\n';
+                      old_D_pat[D_length++] = temp[i];
+                      break;
+          case '$'  : Pattern[j++] = '\n';
+                      old_D_pat[D_length++] = temp[i];
+                      break;
+          default  :  Pattern[j++] = temp[i];
+                      old_D_pat[D_length++] = temp[i];
+                      break;
+      }
+   }
+   if(D_length > MAXDELIM) {
+      fprintf(stderr, "%s: delimiter pattern too long\n", Progname);
+      exit(2);
+   }
+   Pattern[j++] = ANDPAT;
+   old_D_pat[D_length] = '\0';
+   strcpy(D_pattern, old_D_pat);
+   D_length++;
+ /*
+   Pattern[j++] = ' ';
+ */
+   Pattern[j] = '\0';
+   rp = 0; 
+   if(REGEX) {
+       r_pat[rp++] = '.';    /* if REGEX: always append '.' in front */
+       r_pat[rp++] = '(';
+       Pattern[j++] = NOCARE;
+       HEAD = ON;
+   }
+   for (i=d_end; i < m ; i++)
+   {
+        switch(temp[i]) 
+        {
+            case '\\': i++;  Pattern[j++] = temp[i]; 
+                       r_pat[rp++] = 'o';   /* the symbol doesn't matter */
+                       break;
+            case '#':  if(REGEX) {
+                          Pattern[j++] = NOCARE;
+                          r_pat[rp++] = '.';
+                          r_pat[rp++] = '*';
+                          break; }
+                       Pattern[j++] = WILDCD;
+                       break; 
+            case '(':  Pattern[j++] = LPARENT; 
+                       r_pat[rp++] = '(';     
+                       break;
+            case ')':  Pattern[j++] = RPARENT; 
+                       r_pat[rp++] = ')'; 
+                       break;
+            case '[':  Pattern[j++] = LRANGE;  
+                       r_pat[rp++] = '[';
+                       IN_RANGE = ON;
+                       break;
+            case ']':  Pattern[j++] = RRANGE;  
+                       r_pat[rp++] = ']'; 
+ 		      IN_RANGE = OFF;
+                       break;
+            case '<':  Pattern[j++] = LANGLE;  
+                       break;
+            case '>':  Pattern[j++] = RANGLE;  
+                       break;
+            case '^':  if (temp[i-1] == '[') Pattern[j++] = NOTSYM;
+                       else Pattern[j++] = '\n';
+                       r_pat[rp++] = '^';
+                       break;
+            case '$':  Pattern[j++] = '\n'; 
+                       r_pat[rp++] = '$';
+                       break;
+            case '.':  Pattern[j++] = NOCARE;
+                       r_pat[rp++] = '.';
+                       break;
+            case '*':  Pattern[j++] = STAR; 
+                       r_pat[rp++] = '*';
+                       break;
+            case '|':  Pattern[j++] = ORSYM; 
+                       r_pat[rp++] = '|';
+                       break;
+            case ',':  Pattern[j++] = ORPAT;  
+                       RE_ERR = ON; 
+                       break;
+            case ';':  if(ANDON) RE_ERR = ON; 
+                       Pattern[j++] = ANDPAT;
+                       ANDON = ON;
+                       break;
+            case '-':  if(IN_RANGE) {
+                           Pattern[j++] = HYPHEN; 
+                           r_pat[rp++] = '-';
+                       }
+                       else { 
+                           Pattern[j++] = temp[i];
+                           r_pat[rp++] = temp[i];
+                       }  
+                       break;
+            case NNLINE :
+                       Pattern[j++] = temp[i];
+                       r_pat[rp++] = 'N';
+                       break;
+            default:   Pattern[j++] = temp[i]; 
+                       r_pat[rp++] = temp[i];
+                       break;
+       }
+   }
+   if(REGEX) {           /* append ').' at end of regular expression */
+       r_pat[rp++] = ')';
+       r_pat[rp++] = '.';
+       Pattern[j++] = NOCARE;
+       TAIL = ON;
+   }
+   Pattern[j] = '\0'; 
+   m = j;
+   r_pat[rp] = '\0'; 
+   if(REGEX)
+   {  
+      if(DELIMITER || WORDBOUND)  {
+           fprintf(stderr, "%s: -d or -w option is not supported for this pattern\n", Progname);
+           exit(2);
+      }
+      if(RE_ERR) {
+         fprintf(stderr, "%s: illegal regular expression\n", Progname);
+         exit(2);
+      }
+      while(*Pattern != NOCARE && m-- > 0) Pattern++;  /* poit to . */
+      num_pos = init(r_pat, table);
+      if(num_pos <= 0) {
+          fprintf(stderr, "%s: illegal regular expression\n", Progname);
+          exit(2);
+      }
+      if(num_pos > 30) {
+         fprintf(stderr, "%s: regular expression too long\n", Progname);
+         exit(2);
+      }
+   strcpy(old_pat, Pattern); /* do real change to the Pattern to be returned */
+   return;
+   } /* if regex */
+ 
+   return;
+ }


Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/re.h
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/re.h:1.1
*** /dev/null	Tue Oct  5 13:03:12 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/re.h	Tue Oct  5 13:02:58 2004
***************
*** 0 ****
--- 1,129 ----
+ /*************************************************************
+  *							     *
+  * 	Macros defining special characters.		     *
+  *							     *
+  *************************************************************/
+ 
+ #define NUL	    '\0'
+ #define ASCII_MIN   '\001'
+ #define ASCII_MAX   '\177'
+ 
+ /*************************************************************
+  *							     *
+  * 	Macros defining lexical categories.		     *
+  *							     *
+  *************************************************************/
+ 
+ #define C_LIT	0   /* individual character literal */
+ #define C_SET	1   /* character set literal	    */
+ 
+ #define EOS		0	/* end-of-string */
+ #define LITERAL		1
+ #define OPSTAR		2
+ #define OPALT		3
+ #define OPOPT		4
+ #define OPCAT		5
+ #define LPAREN		6
+ #define RPAREN		7
+ 
+ /*************************************************************
+  *							     *
+  * 	Macros for manipulating syntax tree nodes.	     *
+  *							     *
+  *************************************************************/
+ 
+ #define lit_type(x)	(x->l_type)
+ #define lit_pos(x)	(x->pos)
+ #define lit_char(x)	((x->val).c)
+ #define lit_cset(x)	((x->val).cset)
+ 
+ #define tok_type(x)	(x->type)
+ #define tok_val(x)	(x->val)
+ #define tok_op(x)       (x->val->op)
+ #define tok_lit(x)	((x->val->refs).lit)
+ 
+ #define Op(x)		(x->op)
+ #define Lit(x)		((x->refs).lit)
+ #define Child(x)	((x->refs).child)
+ #define Lchild(x)	((x->refs).children.l_child)
+ #define Rchild(x)	((x->refs).children.r_child)
+ #define Nullable(x)	(x->nullable)
+ #define Firstpos(x)	(x->firstposn)
+ #define Lastpos(x)	(x->lastposn)
+ 
+ /*************************************************************
+  *							     *
+  *  Macros for manipulating DFA states and sets of states.   *
+  *							     *
+  *************************************************************/
+ 
+ #define Positions(x)	(x->posns)
+ #define Final_St(x)	(x->final)
+ #define Goto(x, c)	((x->trans)[c])
+ #define Next_State(x)	((x)->next_state)
+ 
+ /*************************************************************/
+ 
+ #define new_node(x)	malloc(sizeof(*x))
+ 
+ typedef struct {	/* character range literals */
+ 	    char low_bd, hi_bd;
+ 	} *Ch_Range;
+ 
+ typedef struct ch_set {	    /* character set literals */
+ 	    Ch_Range elt;	/* rep. as list of ranges */
+ 	    struct ch_set *rest;
+ 	} *Ch_Set;
+ 
+ typedef struct {	/* regular expression literal */
+ 	    int pos;	     /* position in syntax tree */
+ 	    short l_type;    /* type of literal */
+ 	    union {
+ 		char c;     /* for character literals */
+ 		Ch_Set cset; /* for character sets */
+ 	    } val;
+ 	} *Re_Lit, *(*Re_lit_array)[];
+ 
+ typedef struct pnode {
+ 	    int posnum;
+ 	    struct pnode *nextpos;
+ 	} *Pset, *(*Pset_array)[];
+ 
+ typedef struct rnode {	/* regular expression node */
+ 	    short op;     /* operator at that node */
+ 	    union {
+ 		Re_Lit lit;		/* child is a leaf node */
+ 		struct rnode *child;	/* child of unary op */
+ 		struct {
+ 		    struct rnode *l_child; 
+ 		    struct rnode *r_child;
+ 		} children;		/* children of binary op */
+ 	    } refs;
+ 	    short nullable;
+ 	    Pset firstposn, lastposn;
+ 	} *Re_node;
+ 
+ typedef struct {			/* token node */
+ 	    short type;
+ 	    Re_node val;
+ 	} *Tok_node;
+ 
+ 
+ typedef struct snode {
+ 	    Re_node val;
+ 	    int size;
+ 	    struct snode *next;
+ 	} *Stack;
+ 
+ typedef struct dfa_st {
+ 	    Pset posns;
+ 	    int final;	    /* 1 if the state is a final state, 0 o/w */
+ 	    struct dfa_st *trans[128];
+ 	} *Dfa_state;
+ 
+ typedef struct dfa_stset {
+ 	    Dfa_state st;
+ 	    struct dfa_stset *next_state;
+ 	} *Dfa_state_set;
+ 
+ 


Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/sgrep.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/sgrep.c:1.1
*** /dev/null	Tue Oct  5 13:03:12 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/sgrep.c	Tue Oct  5 13:02:58 2004
***************
*** 0 ****
--- 1,665 ----
+ /* Copyright (c) 1991 Sun Wu and Udi Manber.  All Rights Reserved. */
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <ctype.h>
+ #define MAXSYM  256
+ #define MAXMEMBER 8192
+ #define	CHARTYPE	unsigned char
+ #define MaxError 20
+ #define MAXPATT 256
+ #define MAXLINE 1024
+ #define MaxCan  2048
+ #define BLOCKSIZE    8192
+ #define MAX_SHIFT_2  4096
+ #define ON      1
+ #define LOG_ASCII 8
+ #define LOG_DNA  3
+ #define MAXMEMBER_1 65536
+ #define LONG_EXAC  20
+ #define LONG_APPX  24
+ #define W_DELIM    128
+ 
+ extern COUNT, FNAME, SILENT, FILENAMEONLY, num_of_matched;
+ extern DNA ;  /* DNA flag is set in checksg when pattern is DNA pattern and
+ 		 p_size > 16  */
+ extern WORDBOUND, WHOLELINE, NOUPPER;
+ extern unsigned char CurrentFileName[],  Progname[]; 
+ extern unsigned Mask[];
+ extern unsigned endposition;
+ 
+ unsigned char BSize;                /* log_c m   */
+ unsigned char char_map[MAXSYM];
+ 	
+ 
+ /* data area */
+ int shift_1;
+ CHARTYPE SHIFT[MAXSYM];
+ CHARTYPE MEMBER[MAXMEMBER];
+ CHARTYPE pat[MAXPATT];
+ unsigned Hashmask;
+ char MEMBER_1[MAXMEMBER_1];
+ CHARTYPE TR[MAXSYM];
+ 
+ void char_tr(unsigned char *pat, int *m)
+ {
+ int i;
+ unsigned char temp[MAXPATT];
+ 	for(i=0; i<MAXSYM; i++) TR[i] = i;
+ 	if(NOUPPER) {
+ 		for(i='A'; i<= 'Z'; i++) TR[i] = i + 'a' - 'A';
+ 	}
+ 	if(WORDBOUND) { /* SUN: To be added to be more complete */
+ 		for(i=0; i<128; i++) {
+ 			if(!isalnum(i)) TR[i] = W_DELIM;
+ 		}
+ 	}
+ 	if(WHOLELINE) {
+ 		memcpy(temp, pat, *m);
+ 		pat[0] = '\n';
+ 		memcpy(pat+1, temp, *m);
+ 		pat[*m+1] = '\n';
+ 		pat[*m+2] = 0;
+ 		*m = *m + 2;
+ 	}
+ }
+ 
+ void s_output (CHARTYPE *text, int *i)
+ {
+ int bp;
+         if(SILENT) return;
+         if(COUNT) {
+ 		while(text[*i] != '\n') *i = *i + 1; 
+ 		return;
+ 	}
+         if(FNAME == ON) printf("%s: ", CurrentFileName);
+         bp = *i;
+         while(text[--bp] != '\n');
+         while(text[++bp] != '\n') putchar(text[bp]);
+         putchar('\n');
+         *i = bp;
+ }
+ 
+ int verify(register int m, register int n, register int D, CHARTYPE *pat, CHARTYPE *text)
+ {   
+     int A[MAXPATT], B[MAXPATT];
+     register int last = D;      
+     register int cost = 0;  
+     register int k, i, c;
+     register int m1 = m+1;
+     CHARTYPE *textend = text+n;
+     CHARTYPE *textbegin = text;
+ 
+    for (i = 0; i <= m1; i++)  A[i] = B[i] = i;
+    while (text < textend)
+    {
+        for (k = 1; k <= last; k++)
+        {
+            cost = B[k-1]+1; 
+            if (pat[k-1] != *text)
+            {   if (B[k]+1 < cost) cost = B[k]+1; 
+                if (A[k-1]+1 < cost) cost = A[k-1]+1; }
+            else cost = cost -1; 
+            A[k] = cost; 
+        }
+        if(pat[last] == *text++) { A[last+1] = B[last]; last++; }
+        if(A[last] < D) A[last+1] = A[last++]+1;
+        while (A[last] > D) last = last - 1;
+        if(last >= m) return(text - textbegin - 1);
+        if(*text == '\n') {
+             last = D;
+ 	    for(c = 0; c<=m1; c++) A[c] = B[c] = c;
+        }
+        for (k = 1; k <= last; k++)
+        {
+            cost = A[k-1]+1; 
+            if (pat[k-1] != *text)
+            {   if (A[k]+1 < cost) cost = A[k]+1; 
+                if (B[k-1]+1 < cost) cost = B[k-1]+1; }
+            else cost = cost -1; 
+            B[k] = cost;
+        }
+        if(pat[last] == *text++) { B[last+1] = A[last]; last++; }
+        if(B[last] < D) B[last+1] = B[last++]+1;
+        while (B[last] > D) last = last -1;
+        if(last >= m)   return(text - textbegin - 1);
+        if(*text == '\n') {
+             last = D;
+ 	    for(c = 0; c<=m1; c++) A[c] = B[c] = c;
+        }
+    }    
+    return(0);
+ }
+ 
+ /* SUN: bm assumes that the content of text[n]...text[n+m-1] is 
+ pat[m-1] such that the skip loop is guaranteed to terminated */
+ 
+ void bm(CHARTYPE *pat, int m, CHARTYPE *text, CHARTYPE *textend)
+ {
+ register int shift;
+ register int  m1, j, d1; 
+ 
+ /*
+ printf("%d\t", textend - text);
+ printf("%c, %c", *text, *textend);
+ */
+ 
+ d1 = shift_1;    /* at least 1 */
+ m1 = m - 1;
+ shift = 0;       
+ while (text <= textend) {
+ 	shift = SHIFT[*(text += shift)];
+ 	while(shift) {          
+ 		shift = SHIFT[*(text += shift)];
+ 		shift = SHIFT[*(text += shift)];
+ 		shift = SHIFT[*(text += shift)];
+ 	}
+ 		j = 0;
+ 		while(TR[pat[m1 - j]] == TR[*(text - j)]) {
+ 			if(++j == m)  break;       /* if statement can be
+ 						    saved, but for safty ... */
+ 		}
+ 	        if (j == m ) { 
+ 			if(text > textend) return;
+ 			if(WORDBOUND) {
+ 				if(TR[*(text+1)] != W_DELIM) goto CONT;
+ 				if(TR[*(text-m)] != W_DELIM) goto CONT;
+ 			}
+ 			num_of_matched++;
+ 			if(FILENAMEONLY) return;
+ 			if(!(COUNT)) {
+ 				if(FNAME) printf("%s: ", CurrentFileName);
+ 				while(*(--text) != '\n');
+ 				while(*(++text) != '\n') putchar(*(text));
+ 				putchar(*text);
+ 			}
+ 			else { while(*text != '\n') text++; } 
+ CONT:
+ 			shift = 1;
+                 }
+ 		else shift = d1;
+   }
+ return;
+ }
+ 
+   
+ /* initmask() initializes the mask table for the pattern                    */ 
+ /* endposition is a mask for the endposition of the pattern                 */
+ /* endposition will contain k mask bits if the pattern contains k fragments */
+ void initmask(CHARTYPE *pattern, unsigned *Mask, register int m, register int D, unsigned *endposition)
+ {
+   register unsigned Bit1, c;
+   register int i, j, frag_num;
+ 
+   Bit1 = 1 << 31;    /* the first bit of Bit1 is 1, others 0.  */
+   frag_num = D+1; *endposition = 0;
+   for (i = 0; i < frag_num; i++) *endposition = *endposition | (Bit1 >> i);
+   *endposition = *endposition >> (m - frag_num);
+   for(i = 0; i < m; i++) 
+           if (pattern[i] == '^' || pattern[i] == '$') {
+               pattern[i] = '\n'; 
+           }
+   for(i = 0; i < MAXSYM; i++) Mask[i] = ~0;
+   for(i = 0; i < m; i++)     /* initialize the mask table */
+   {  c = pattern[i];
+      for ( j = 0; j < m; j++)
+            if( c == pattern[j] )
+                Mask[c] = Mask[c] & ~( Bit1 >> j ) ;
+   }
+ }
+ 
+ void prep(CHARTYPE *Pattern, register int M, register int D)  /* preprocessing for partitioning_bm */
+ {
+ register int i, j, k, p, shift;
+ register unsigned m;
+ unsigned hash, b_size = 3;
+ 	m = M/(D+1);
+ 	p = M - m*(D+1);
+ 	for (i = 0; i < MAXSYM; i++) SHIFT[i] = m;
+ 	for (i = M-1; i>=p ; i--) {
+ 		shift = (M-1-i)%m;
+ 		hash = Pattern[i];
+ 		if(SHIFT[hash] > shift) SHIFT[hash] = shift;
+ 	}
+ #ifdef DEBUG
+ 	for(i=0; i<M; i++) printf(" %d,", SHIFT[Pattern[i]]);
+ 	printf("\n");
+ #endif
+ 	shift_1 = m;
+ 	for(i=0; i<D+1; i++) {
+ 		j = M-1 - m*i;
+ 		for(k=1; k<m; k++) {
+ 			for(p=0; p<D+1; p++) 
+ 				if(Pattern[j-k] == Pattern[M-1-m*p]) 
+ 					if(k < shift_1) shift_1 = k;
+ 		}
+ 	}
+ #ifdef DEBUG
+ 	printf("\nshift_1 = %d", shift_1);
+ #endif
+ 	if(shift_1 == 0) shift_1 = 1;
+ 	for(i=0; i<MAXMEMBER; i++) MEMBER[i] = 0;
+ 	if (m < 3) b_size = m;
+ 	for(i=0; i<D+1; i++) {
+ 		j = M-1 - m*i;
+ 		hash = 0;
+ 		for(k=0; k<b_size; k++) {
+ 			hash = (hash << 2) + Pattern[j-k];
+ 		}
+ #ifdef DEBUG
+ 	printf(" hash = %d,", hash);
+ #endif
+ 		MEMBER[hash] = 1;
+ 	}
+ }
+ 
+ 
+ void agrep( register CHARTYPE *pat, int M, register CHARTYPE *text, register CHARTYPE *textend, int D )
+ {
+   register int i;
+   register int m = M/(D+1);
+   register CHARTYPE *textstart;
+   register int shift, HASH;
+   int  j=0, k, d1;
+   int  n, cdx;
+   int  Candidate[MaxCan][2], round, lastend=0;
+   unsigned R1[MaxError+1], R2[MaxError+1]; 
+   register unsigned int r1, endpos, c; 
+   unsigned currentpos;
+   unsigned Bit1;
+   unsigned r_newline;
+ 
+   Candidate[0][0] = Candidate[0][1] = 0; 
+   d1 = shift_1;
+   cdx = 0;
+   if(m < 3) r1 = m;
+   else r1 = 3;
+   textstart = text;
+   shift = m-1;
+   while (text < textend) {
+ 	shift = SHIFT[*(text += shift)];
+ 	while(shift) {
+ 		shift = SHIFT[*(text += shift)];
+ 		shift = SHIFT[*(text += shift)];
+ 	}
+ 		j = 1; HASH = *text;
+ 		while(j < r1) { HASH = (HASH << 2) + *(text-j);
+ 				j++; }
+ 	        if (MEMBER[HASH]) { 
+ 			i = text - textstart;
+                      	if((i - M - D - 10) > Candidate[cdx][1]) { 	
+ 				Candidate[++cdx][0] = i-M-D-2;
+                           	Candidate[cdx][1] = i+M+D; }
+                      	else Candidate[cdx][1] = i+M+D;
+ 			shift = d1;
+                 }
+ 		else shift = d1;
+   }
+ 
+ 
+   text = textstart;
+   n = textend - textstart;
+   r_newline = '\n';
+   /* for those candidate areas, find the D-error matches                     */
+   if(Candidate[1][0] < 0) Candidate[1][0] = 0;
+   endpos = endposition;                /* the mask table and the endposition */
+   Bit1 = (1 << 31);
+   for(round = 0; round <= cdx; round++)
+   {  i = Candidate[round][0] ; 
+      if(Candidate[round][1] > n) Candidate[round][1] = n;
+      if(i < 0) i = 0;
+ #ifdef DEBUG
+      printf("round: %d, start=%d, end=%d, ", round, i, Candidate[round][1]);
+ #endif
+      R1[0] = R2[0] = ~0;
+      R1[1] = R2[1] = ~Bit1;
+      for(k = 1; k <= D; k++) R1[k] = R2[k] = (R1[k-1] >> 1) & R1[k-1];
+      while (i < Candidate[round][1])                     
+      {  
+ 	    c = text[i++];
+             if(c == r_newline) {
+                for(k = 0 ; k <= D; k++) R1[k] = R2[k] = (~0 );
+             }
+             r1 = Mask[c];
+             R1[0] = (R2[0] >> 1) | r1;
+             for(k=1; k<=D; k++)
+                 R1[k] = ((R2[k] >> 1) | r1) & R2[k-1] & ((R1[k-1] & R2[k-1]) >> 1);
+             if((R1[D] & endpos) == 0) { 
+                                     num_of_matched++;
+                                     if(FILENAMEONLY) { return; }
+                                     currentpos = i;
+                                     if(i <= lastend) i = lastend;
+                                     else {
+                                        s_output(text, &currentpos); 
+                                        i = currentpos; 
+                                     }
+                                     lastend = i;
+                                     for(k=0; k<=D; k++) R1[k] = R2[k] = ~0;
+                                   }
+             c = text[i++];
+             if(c == r_newline) {
+                 for(k = 0 ; k <= D; k++) R1[k] = R2[k] = (~0 );
+             }
+             r1 = Mask[c];
+             R2[0] = (R1[0] >> 1) | r1;
+             for(k = 1; k <= D; k++)
+                 R2[k] = ((R1[k] >> 1) | r1) & R1[k-1] & ((R1[k-1] & R2[k-1]) >> 1);
+             if((R2[D] & endpos) == 0) { currentpos = i;
+                                     num_of_matched++;
+                                     if(FILENAMEONLY) { return; }
+                                     if(i <= lastend) i = lastend;
+                                     else {
+                                        s_output(text, &currentpos); 
+                                        i = currentpos; 
+                                     }
+                                     lastend = i;
+                                     for(k=0; k<=D; k++) R1[k] = R2[k] = ~0;
+                                   }
+      }
+   }
+   return;
+ }
+ 
+ void prep_bm(unsigned char *Pattern, register m)
+ {
+ int i;
+ unsigned hash;
+ unsigned char lastc;
+ 	for (i = 0; i < MAXSYM; i++) SHIFT[i] = m;
+ 	for (i = m-1; i>=0; i--) {
+ 		hash = TR[Pattern[i]];
+ 		if(SHIFT[hash] >= m - 1) SHIFT[hash] = m-1-i;
+ 	}
+ 	shift_1 = m-1;
+ 	lastc = TR[Pattern[m-1]];
+ 	for (i= m-2; i>=0; i--) {
+ 		if(TR[Pattern[i]] == lastc )
+ 			{ shift_1 = m-1 - i;  i = -1; }
+ 	}
+ 	if(shift_1 == 0) shift_1 = 1;
+ 	if(NOUPPER) for(i='A'; i<='Z'; i++) SHIFT[i] = SHIFT[i +  'a' - 'A'];
+ #ifdef DEBUG
+ 	for(i='a'; i<='z'; i++) printf("%c: %d", i, SHIFT[i]); printf("\n");
+ 	for(i='A'; i<='Z'; i++) printf("%c: %d", i, SHIFT[i]); printf("\n");
+ #endif
+ }
+ 
+ 
+ /* a_monkey() the approximate monkey move */
+ 
+ void a_monkey( register CHARTYPE *pat, register int m, register CHARTYPE *text, register CHARTYPE *textend,
+                register int D ) 
+ {
+ register CHARTYPE *oldtext;
+ register unsigned hash, hashmask, suffix_error; 
+ register int  m1 = m-1-D, pos; 
+ 
+   	hashmask = Hashmask;
+   	oldtext  = text;
+   	while (text < textend) {
+      		text = text+m1;
+      		suffix_error = 0;
+      		while(suffix_error <= D) {
+ 			hash = *text--;
+ 			while(MEMBER_1[hash]) {
+ 	      			hash = ((hash << LOG_ASCII) + *(text--)) & hashmask;
+ 			}
+ 			suffix_error++;
+      		}
+      		if(text <= oldtext) {
+ 		           if((pos = verify(m, 2*m+D, D, pat, oldtext)) > 0)  {
+ 				text = oldtext+pos;
+ 				if(text > textend) return;
+ 				num_of_matched++;
+ 				if(FILENAMEONLY) return;
+ 				if(!(COUNT)) {
+ 					if(FNAME) printf("%s: ", CurrentFileName);
+ 					while(*(--text) != '\n');
+ 			 		while(*(++text) != '\n') putchar(*text);
+ 			        	printf("\n");
+ 				}
+ 				else {
+ 					while(*text != '\n') text++;
+ 				}
+ 			   }
+ 			   else { 
+ 			        text = oldtext + m;
+ 			   }
+      		}
+      		oldtext = text; 
+   	}
+ }
+ 
+ /* monkey uses two characters for delta_1 shifting */
+ 
+ CHARTYPE SHIFT_2[MAX_SHIFT_2];
+ 
+ void monkey( register CHARTYPE *pat, register int m, register CHARTYPE *text, register CHARTYPE *textend )
+ {
+ register unsigned hash; 
+ register CHARTYPE shift;
+ register int  m1, j; 
+ register unsigned r_newline;
+ 
+ r_newline = '\n';
+ 
+   m1 = m - 1;
+   text = text+m1;
+   while (text < textend) {
+ 	hash = *text;
+ 	hash = (hash << 3) + *(text-1);
+ 	shift = SHIFT_2[hash];
+ 	while(shift) {
+ 		text = text + shift;
+ 		hash = (*text << 3) + *(text-1);
+ 		shift = SHIFT_2[hash];
+ 	}
+ 	j = 0;
+ 	while(TR[pat[m1 - j]] == TR[*(text - j)]) { if(++j == m) break; }
+ 	if (j == m ) { 
+ 		if(text >= textend) return;
+                 num_of_matched++;
+                 if(FILENAMEONLY)  return;
+ 	        if(COUNT) {
+ 			  while (*text != r_newline) text++;
+ 			  text--;
+ 		}
+ 		else {
+ 			  if(FNAME) printf("%s: ", CurrentFileName);
+                           while(*(--text) != r_newline);
+                           while(*(++text) != r_newline) putchar(*text);
+ 			  printf("\n");
+ 			  text--;
+ 		}
+         }
+ 	text++;
+   }
+ }
+  
+ void am_preprocess(CHARTYPE *Pattern)
+ {
+ int i, m;
+ 	m = strlen(Pattern);
+ 	for (i = 1, Hashmask = 1 ; i<16 ; i++) Hashmask = (Hashmask << 1) + 1 ;
+ 	for (i = 0; i < MAXMEMBER_1; i++) MEMBER_1[i] = 0;
+ 	for (i = m-1; i>=0; i--) {
+ 		MEMBER_1[Pattern[i]] = 1;
+         }
+ 	for (i = m-1; i > 0; i--) {
+ 	   	MEMBER_1[(Pattern[i] << LOG_ASCII) + Pattern[i-1]] = 1;
+ 	}
+ }
+ 
+ /* preprocessing for monkey()   */
+ 
+ void m_preprocess(CHARTYPE *Pattern)
+ {
+ int i, j, m;
+ unsigned hash;
+ 	m = strlen(Pattern);
+ 	for (i = 0; i < MAX_SHIFT_2; i++) SHIFT_2[i] = m;
+ 	for (i = m-1; i>=1; i--) {
+ 		hash = Pattern[i];
+ 		hash = hash << 3;
+ 		for (j = 0; j< MAXSYM; j++) {
+ 			if(SHIFT_2[hash+j] == m) SHIFT_2[hash+j] = m-1;
+ 		}
+ 		hash = hash + Pattern[i-1];
+ 		if(SHIFT_2[hash] >= m - 1) SHIFT_2[hash] = m-1-i;
+ 	}
+ 	shift_1 = m-1;
+ 	for (i= m-2; i>=0; i--) {
+ 		if(Pattern[i] == Pattern[m-1] )
+ 			{ shift_1 = m-1 - i;  i = -1; }
+ 	}
+ 	if(shift_1 == 0) shift_1 = 1;
+ 	SHIFT_2[0] = 0;
+ }
+ 
+ /* monkey4() the approximate monkey move */
+ 
+ char *MEMBER_D;
+ 
+ void monkey4( register unsigned char *pat, register int m, register unsigned char *text, register unsigned char *textend,
+               register int D  )
+ {
+ register unsigned char *oldtext;
+ register unsigned hash, hashmask, suffix_error; 
+ register int m1=m-1-D, pos; 
+ 
+   hashmask = Hashmask;
+   oldtext = text ;
+   while (text < textend) {
+      text = text + m1;
+      suffix_error = 0;
+      while(suffix_error <= D) {
+ 	hash = char_map[*text--];
+ 	hash = ((hash << LOG_DNA) + char_map[*(text--)]) & hashmask;
+ 	while(MEMBER_D[hash]) {
+ 	      hash = ((hash << LOG_DNA) + char_map[*(text--)]) & hashmask;
+ 	}
+ 	suffix_error++;
+      }
+      if(text <= oldtext) {
+ 		           if((pos = verify(m, 2*m+D, D, pat, oldtext)) > 0)  {
+ 				text = oldtext+pos;
+ 				if(text > textend) return;
+ 				num_of_matched++;
+ 				if(FILENAMEONLY) return;
+ 				if(!(COUNT)) {
+ 					if(FNAME) printf("%s:", CurrentFileName);
+ 					while(*(--text) != '\n');
+ 			 		while(*(++text) != '\n') putchar(*text);
+ 			        	printf("\n");
+ 					text++;
+ 				}
+ 				else {
+ 					while(*text != '\n') text++;
+ 					text++;
+ 				}
+ 			   }
+ 			   else text = oldtext + m;
+      }
+      oldtext = text; 
+   }
+ }
+ 
+ int blog(int base, int m )
+ {
+ int i, exp;
+ 	exp = base;
+         m = m + m/2;
+ 	for (i = 1; exp < m; i++) exp = exp * base;
+ 	return(i);
+ }
+  
+ void prep4(char *Pattern, int m)
+ {
+ int i, j, k;
+ unsigned hash;
+ 
+ for(i=0; i< MAXSYM; i++) char_map[i] = 0;
+ char_map['a'] = char_map['A'] = 4;
+ char_map['g'] = char_map['g'] = 1;
+ char_map['t'] = char_map['t'] = 2;
+ char_map['c'] = char_map['c'] = 3;
+ char_map['n'] = char_map['n'] = 5;
+ 
+ 	BSize = blog(4, m);
+ 	for (i = 1, Hashmask = 1 ; i<BSize*LOG_DNA; i++) Hashmask = (Hashmask << 1) + 1 ;
+ 	MEMBER_D = (char *) malloc((Hashmask+1)  * sizeof(char));
+ #ifdef DEBUG
+ 	printf("BSize = %d", BSize);
+ #endif 
+ 	for (i=0; i <= Hashmask; i++) MEMBER_D[i] = 0;
+ 	for (j=0; j < BSize; j++) {
+             for(i=m-1; i >= j; i--) {
+                hash = 0;
+ 	       for(k=0; k <= j; k++) 
+ 		  hash = (hash << LOG_DNA) +char_map[Pattern[i-k]]; 
+ #ifdef DEBUG
+ 	       printf("< %d >, ", hash);
+ #endif
+ 	       MEMBER_D[hash] = 1;
+             }
+         }
+ }
+ 
+ void sgrep(CHARTYPE *pat, int m, int fd, int D)
+ { 
+     CHARTYPE text[BLOCKSIZE+2*MAXLINE+MAXPATT]; /* input text stream */
+     int offset = 2*MAXLINE;
+     int buf_end, num_read, i, start, end, residue = 0;
+     if(pat[0] == '^' || pat[0] == '$') pat[0] = '\n';
+     if(pat[m-1] == '^' || pat[m-1] == '$') pat[m-1] = '\n';
+     char_tr(pat, &m);   /* will change pat, and m if WHOLELINE is ON */
+     text[offset-1] = '\n';  /* initial case */
+     for(i=0; i < MAXLINE; i++) text[i] = 0;   /* security zone */
+     start = offset;   
+     if(WHOLELINE) start--;
+     if(m >= MAXPATT) {
+          fprintf(stderr, "%s: pattern too long\n", Progname);
+          exit(2);
+     }
+     if(D == 0) {
+ 	if(m > LONG_EXAC) m_preprocess(pat);
+ 	else prep_bm(pat, m);
+     }
+     else if (DNA) prep4(pat, m);
+ 	 else 	if(m >= LONG_APPX) am_preprocess(pat);
+ 		else {
+ 			prep(pat, m, D);
+ 			initmask(pat, Mask, m, 0, &endposition); 
+ 		}
+     for(i=1; i<=m; i++) text[BLOCKSIZE+offset+i] = pat[m-1];
+ 		/* to make sure the skip loop in bm() won't go out of bound */
+     while( (num_read = read(fd, text+offset, BLOCKSIZE)) > 0) 
+     {
+        buf_end = end = offset + num_read -1 ;
+        while(text[end]  != '\n' && end > offset) end--;
+        residue = buf_end - end + 1 ;
+        text[start-1] = '\n';
+        if(D==0)  {
+ 		if(m > LONG_EXAC) monkey(pat, m, text+start, text+end);
+ 		else bm(pat, m, text+start, text+end);
+        }
+        else {
+ 		if(DNA) monkey4( pat, m, text+start, text+end, D  );
+ 		else {
+ 		  if(m >= LONG_APPX) a_monkey(pat, m, text+start, text+end, D);
+ 		  else       agrep(pat, m, text+start, text+end, D);
+ 		}
+        }
+        if(FILENAMEONLY && num_of_matched) {
+             printf("%s\n", CurrentFileName);
+             return; }
+        start = offset - residue ;
+        if(start < MAXLINE) {
+             start = MAXLINE; 
+        }
+        strncpy(text+start, text+end, residue);
+        start++;
+     } /* end of while(num_read = ... */
+     return;
+ } /* end sgrep */
+ 


Index: llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/utilities.c
diff -c /dev/null llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/utilities.c:1.1
*** /dev/null	Tue Oct  5 13:03:12 2004
--- llvm-test/MultiSource/Benchmarks/Prolangs-C/agrep/utilities.c	Tue Oct  5 13:02:58 2004
***************
*** 0 ****
--- 1,127 ----
+ /* this file contains various utility functions for accessing
+    and manipulating regular expression syntax trees.	*/
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include "re.h"
+ 
+ /************************************************************************/
+ /*                                                                      */
+ /*  the following routines implement an abstract data type "stack".	*/
+ /*                                                                      */
+ /************************************************************************/
+ 
+ Stack Push(Stack *s, Re_node v)
+ {
+     Stack node;
+ 
+     node = (Stack) new_node(node);
+     if (s == NULL || node == NULL) return NULL;	    /* can't allocate */
+     node->next = *s;
+     node->val = v;
+     if (*s == NULL) node->size = 1;
+     else node->size = (*s)->size + 1;
+     *s = node;
+     return *s;
+ }
+ 
+ Re_node Pop(Stack *s)
+ {
+     Re_node node;
+     Stack temp;
+ 
+     if (s == NULL || *s == NULL) return NULL;
+     else {
+ 	temp = *s;
+ 	node = (*s)->val;
+ 	*s = (*s)->next;
+ 	free(temp);
+ 	return node;
+     }
+ }
+ 
+ Re_node Top(Stack s)
+ {
+     if (s == NULL) return NULL;
+     else return s->val;
+ }
+ 
+ int Size(Stack s)
+ {
+     if (s == NULL) return 0;
+     else return s->size;
+ }
+ 
+ /************************************************************************/
+ /*                                                                      */
+ /*	the following routines manipulate sets of positions.		*/
+ /*                                                                      */
+ /************************************************************************/
+ 
+ int occurs_in(int n, Pset p)
+ {
+     while (p != NULL)
+ 	if (n == p->posnum) return 1;
+ 	else p = p->nextpos;
+     return 0;
+ }
+ 
+ /* pset_union() takes two position-sets and returns their union.    */
+ 
+ Pset pset_union(Pset s1, Pset s2)
+ {
+     Pset hd, curr, new1;
+ 
+     hd = NULL; curr = NULL;
+     while (s1 != NULL) {
+ 	if (!occurs_in(s1->posnum, s2)) {
+ 	    new1 = (Pset) new_node(new1);
+ 	    if (new1 == NULL) return NULL;
+ 	    new1->posnum = s1->posnum;
+ 	    if (hd == NULL) hd = new1;
+ 	    else curr->nextpos = new1;
+ 	}
+ 	curr = new1;
+ 	s1 = s1->nextpos;
+     }
+     if (hd == NULL) hd = s2;
+     else curr->nextpos = s2;
+     return hd;
+ }
+ 
+ /* create_pos() creates a position node with the position value given,
+    then returns a pointer to this node.					*/
+ 
+ Pset create_pos(int n)
+ {
+     Pset x;
+ 
+     x = (Pset) new_node(x);
+     if (x == NULL) return NULL;
+     x->posnum = n;
+     x->nextpos = NULL;
+     return x;
+ }
+ 
+ /* eq_pset() takes two position sets and checks to see if they are
+    equal.  It returns 1 if the sets are equal, 0 if they are not.	*/
+ 
+ int subset_pset(Pset s1, Pset s2)
+ {
+     int subs = 1;
+ 
+     while (s1 != NULL && subs != 0) {
+ 	subs = 0;
+ 	while (s2 != NULL && subs != 1)
+ 	    if (s1->posnum == s2->posnum) subs = 1;
+ 	    else s2 = s2->nextpos;
+ 	s1 = s1->nextpos;
+     }
+     return subs;
+ }	
+ 
+ int eq_pset(Pset s1, Pset s2)
+ {
+     return subset_pset(s1, s2) && subset_pset(s2, s1);
+ }
+ 






More information about the llvm-commits mailing list