diff -wu include/llvm/Support/ConstantFolder.h include/llvm/Support/ConstantFolder.h --- include/llvm/Support/ConstantFolder.h (working copy) +++ include/llvm/Support/ConstantFolder.h (working copy) @@ -31,8 +31,8 @@ /// Try to find an instruction identical to this one in the current BB, /// and return it. - inline Value *findBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, - Value *LRHS, const BasicBlock::iterator *I) const + Value *findBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, + Value *LRHS, const BasicBlock *BB) const { unsigned maxUses = 8; // Maximum number of uses to inspect // Loop over all uses of operand to find an identical binop, with @@ -55,21 +55,18 @@ } else continue; } - { - // Only accept instructions before or at the insertion point - // in the same BB, because we can't move instructions here. - BasicBlock::iterator P = UI; - if (*I == UI->getParent()->end() || - (P <= *I && P > UI->getParent()->begin())) + // Only accept instructions in same BB. + // Caller will need to ensure it doesn't move the insertion point + // backwards. + if (UI->getParent() == BB) return UI; } - } return 0; } - inline Value *SimplifyBinOp(Instruction::BinaryOps Opc, + Value *SimplifyBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, Constant *LC, Constant *RC, bool reuseOps, - const BasicBlock::iterator *I) const { + const BasicBlock *BB) const { // Can only simplify if one of the operands is a constant. if (!(LC || RC)) @@ -174,7 +171,7 @@ if (reuseOps) // We'll iterate on uses of LHS/RHS to find an identical instruction. // Choose the non-constant one (constant one may have too many uses). - return findBinOp(Opc, LHS, RHS, LC ? RHS : LHS, I); + return findBinOp(Opc, LHS, RHS, LC ? RHS : LHS, BB); return 0; } @@ -184,15 +181,15 @@ /// belong to an optimization pass (instcombine). /// If reuseOps is specified, it will try to find an instruction identical /// to this one in the current BB, and return it. - inline Value *CreateBinOp(Instruction::BinaryOps Opc, + Value *CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, bool reuseOps, - const BasicBlock::iterator *I) const { + const BasicBlock *BB) const { Constant *LC = dyn_cast(LHS); Constant *RC = dyn_cast(RHS); if (LC && RC) return ConstantExpr::get(Opc, LC, RC); - return SimplifyBinOp(Opc, LHS, RHS, LC, RC, reuseOps, I); + return SimplifyBinOp(Opc, LHS, RHS, LC, RC, reuseOps, BB); } @@ -200,20 +197,20 @@ // Unary Operators //===--------------------------------------------------------------------===// - inline Value *CreateNeg(Value *V, bool reuseOps, - const BasicBlock::iterator *I) const { + Value *CreateNeg(Value *V, bool reuseOps, + const BasicBlock *BB) const { if (Constant *C = dyn_cast(V)) return ConstantExpr::getNeg(C); if (reuseOps) { Value *zero = ConstantExpr::getZeroValueForNegationExpr(V->getType()); - if (Value *R = findBinOp(Instruction::Sub, zero, V, V, I)) + if (Value *R = findBinOp(Instruction::Sub, zero, V, V, BB)) return R; } return 0; } - inline Value *CreateNot(Value *V, bool reuseOps, - const BasicBlock::iterator *I) const { + Value *CreateNot(Value *V, bool reuseOps, + const BasicBlock *BB) const { if (Constant *C = dyn_cast(V)) return ConstantExpr::getNot(C); if (reuseOps) { @@ -224,7 +221,7 @@ } else { C = ConstantInt::getAllOnesValue(V->getType()); } - if (Value *R = findBinOp(Instruction::Xor, V, C, V, I)) + if (Value *R = findBinOp(Instruction::Xor, V, C, V, BB)) return R; } return 0; diff -wu include/llvm/Support/IRBuilder.h include/llvm/Support/IRBuilder.h --- include/llvm/Support/IRBuilder.h (working copy) +++ include/llvm/Support/IRBuilder.h (working copy) @@ -39,7 +39,8 @@ /// specifies a class to use for creating constants. This defaults to creating /// minimally folded constants. /// If you specify reuseOps, it will try to reuse binops already inserted. Only -/// use this if you don't mutate/RAUW instructions after creating them! +/// use this if you don't mutate/RAUW instructions after creating them, and if +/// you don't move the insertion point backwards! template class IRBuilder { BasicBlock *BB; @@ -169,91 +170,91 @@ Value *CreateAdd(Value *LHS, Value *RHS, const char *Name = "") { if (Value *R = Folder.CreateBinOp(Instruction::Add, LHS, RHS, - reuseOps, &InsertPt)) + reuseOps, BB)) return R; return Insert(BinaryOperator::CreateAdd(LHS, RHS), Name); } Value *CreateSub(Value *LHS, Value *RHS, const char *Name = "") { if (Value *R = Folder.CreateBinOp(Instruction::Sub, LHS, RHS, - reuseOps, &InsertPt)) + reuseOps, BB)) return R; return Insert(BinaryOperator::CreateSub(LHS, RHS), Name); } Value *CreateMul(Value *LHS, Value *RHS, const char *Name = "") { if (Value *R = Folder.CreateBinOp(Instruction::Mul, LHS, RHS, - reuseOps, &InsertPt)) + reuseOps, BB)) return R; return Insert(BinaryOperator::CreateMul(LHS, RHS), Name); } Value *CreateUDiv(Value *LHS, Value *RHS, const char *Name = "") { if (Value *R = Folder.CreateBinOp(Instruction::UDiv, LHS, RHS, - reuseOps, &InsertPt)) + reuseOps, BB)) return R; return Insert(BinaryOperator::CreateUDiv(LHS, RHS), Name); } Value *CreateSDiv(Value *LHS, Value *RHS, const char *Name = "") { if (Value *R = Folder.CreateBinOp(Instruction::SDiv, LHS, RHS, - reuseOps, &InsertPt)) + reuseOps, BB)) return R; return Insert(BinaryOperator::CreateSDiv(LHS, RHS), Name); } Value *CreateFDiv(Value *LHS, Value *RHS, const char *Name = "") { if (Value *R = Folder.CreateBinOp(Instruction::FDiv, LHS, RHS, - reuseOps, &InsertPt)) + reuseOps, BB)) return R; return Insert(BinaryOperator::CreateFDiv(LHS, RHS), Name); } Value *CreateURem(Value *LHS, Value *RHS, const char *Name = "") { if (Value *R = Folder.CreateBinOp(Instruction::URem, LHS, RHS, - reuseOps, &InsertPt)) + reuseOps, BB)) return R; return Insert(BinaryOperator::CreateURem(LHS, RHS), Name); } Value *CreateSRem(Value *LHS, Value *RHS, const char *Name = "") { if (Value *R = Folder.CreateBinOp(Instruction::SRem, LHS, RHS, - reuseOps, &InsertPt)) + reuseOps, BB)) return R; return Insert(BinaryOperator::CreateSRem(LHS, RHS), Name); } Value *CreateFRem(Value *LHS, Value *RHS, const char *Name = "") { if (Value *R = Folder.CreateBinOp(Instruction::FRem, LHS, RHS, - reuseOps, &InsertPt)) + reuseOps, BB)) return R; return Insert(BinaryOperator::CreateFRem(LHS, RHS), Name); } Value *CreateShl(Value *LHS, Value *RHS, const char *Name = "") { if (Value *R = Folder.CreateBinOp(Instruction::Shl, LHS, RHS, - reuseOps, &InsertPt)) + reuseOps, BB)) return R; return Insert(BinaryOperator::CreateShl(LHS, RHS), Name); } Value *CreateLShr(Value *LHS, Value *RHS, const char *Name = "") { if (Value *R = Folder.CreateBinOp(Instruction::LShr, LHS, RHS, - reuseOps, &InsertPt)) + reuseOps, BB)) return R; return Insert(BinaryOperator::CreateLShr(LHS, RHS), Name); } Value *CreateAShr(Value *LHS, Value *RHS, const char *Name = "") { if (Value *R = Folder.CreateBinOp(Instruction::AShr, LHS, RHS, - reuseOps, &InsertPt)) + reuseOps, BB)) return R; return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name); } Value *CreateAnd(Value *LHS, Value *RHS, const char *Name = "") { if (Value *R = Folder.CreateBinOp(Instruction::And, LHS, RHS, - reuseOps, &InsertPt)) + reuseOps, BB)) return R; return Insert(BinaryOperator::CreateAnd(LHS, RHS), Name); } Value *CreateOr(Value *LHS, Value *RHS, const char *Name = "") { if (Value *R = Folder.CreateBinOp(Instruction::Or, LHS, RHS, - reuseOps, &InsertPt)) + reuseOps, BB)) return R; return Insert(BinaryOperator::CreateOr(LHS, RHS), Name); } Value *CreateXor(Value *LHS, Value *RHS, const char *Name = "") { if (Value *R = Folder.CreateBinOp(Instruction::Xor, LHS, RHS, - reuseOps, &InsertPt)) + reuseOps, BB)) return R; return Insert(BinaryOperator::CreateXor(LHS, RHS), Name); } @@ -261,20 +262,20 @@ Value *CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const char *Name = "") { if (Value *R = Folder.CreateBinOp(Opc, LHS, RHS, - reuseOps, &InsertPt)) + reuseOps, BB)) return R; return Insert(BinaryOperator::Create(Opc, LHS, RHS), Name); } Value *CreateNeg(Value *V, const char *Name = "") { if (Value *R = Folder.CreateNeg( V, - reuseOps, &InsertPt)) + reuseOps, BB)) return R; return Insert(BinaryOperator::CreateNeg(V), Name); } Value *CreateNot(Value *V, const char *Name = "") { if (Value *R = Folder.CreateNot(V, - reuseOps, &InsertPt)) + reuseOps, BB)) return R; return Insert(BinaryOperator::CreateNot(V), Name); } diff -wu include/llvm/Support/TargetFolder.h include/llvm/Support/TargetFolder.h --- include/llvm/Support/TargetFolder.h (working copy) +++ include/llvm/Support/TargetFolder.h (working copy) @@ -46,13 +46,13 @@ inline Value *CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, bool reuseOps, - const BasicBlock::iterator *I) const { + const BasicBlock *BB) const { Constant *LC = dyn_cast(LHS); Constant *RC = dyn_cast(RHS); if (LC && RC) return Fold(ConstantExpr::get(Opc, LC, RC)); - return SimplifyBinOp(Opc, LHS, RHS, LC, RC, reuseOps, I); + return SimplifyBinOp(Opc, LHS, RHS, LC, RC, reuseOps, BB); } //===--------------------------------------------------------------------===// @@ -60,19 +60,19 @@ //===--------------------------------------------------------------------===// inline Value *CreateNeg(Value *V, bool reuseOps, - const BasicBlock::iterator *I) const { + const BasicBlock *BB) const { if (Constant *C = dyn_cast(V)) return Fold(ConstantExpr::getNeg(C)); if (reuseOps) { Value *zero = ConstantExpr::getZeroValueForNegationExpr(V->getType()); - if (Value *R = findBinOp(Instruction::Sub, zero, V, V, I)) + if (Value *R = findBinOp(Instruction::Sub, zero, V, V, BB)) return R; } return 0; } inline Value *CreateNot(Value *V, bool reuseOps, - const BasicBlock::iterator *I) const { + const BasicBlock *BB) const { if (Constant *C = dyn_cast(V)) return Fold(ConstantExpr::getNot(C)); if (reuseOps) { @@ -83,7 +83,7 @@ } else { C = ConstantInt::getAllOnesValue(V->getType()); } - if (Value *R = findBinOp(Instruction::Xor, V, C, V, I)) + if (Value *R = findBinOp(Instruction::Xor, V, C, V, BB)) return R; } return 0; diff -wu lib/Analysis/ConstantFolding.cpp lib/Analysis/ConstantFolding.cpp --- lib/Analysis/ConstantFolding.cpp (working copy) +++ lib/Analysis/ConstantFolding.cpp (working copy) @@ -313,17 +313,17 @@ } Value *llvm::SimplifyInstruction(Instruction *I, const TargetData *TD) { - // Check whether all operands are constant. - Instruction::const_op_iterator i = I->op_begin(), e = I->op_end(); - for (; i != e; ++i) { - if (!isa(i)) - break; + // Try to constant fold + if (Constant *C = ConstantFoldInstruction(I, TD)) + return C; + + if (BinaryOperator *BO = dyn_cast(I)) { + ConstantFolder CF; + return CF.CreateBinOp(BO->getOpcode(), BO->getOperand(0), BO->getOperand(1), + false, 0); } - if (i == e) - return ConstantFoldInstruction(I, TD); - BinaryOperator *BO = dyn_cast(I); - if (!BO) { + // select ConstantCC, TrueVal, FalseVal if (const SelectInst *SI = dyn_cast(I)) { if (const ConstantInt *CB = dyn_cast(SI->getCondition())) return CB->getZExtValue() ? SI->getTrueValue() : SI->getFalseValue(); @@ -331,12 +331,6 @@ return 0; } - ConstantFolder CF; - BasicBlock::iterator It = BO; - return CF.CreateBinOp(BO->getOpcode(), BO->getOperand(0), BO->getOperand(1), - true, &It); -} - /// ConstantFoldConstantExpression - Attempt to fold the constant expression /// using the specified TargetData. If successful, the constant result is /// result is returned, if not, null is returned.