X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAnalysis%2FConstantFolding.cpp;h=9f94ee383374abf100ae8bd1e714162771e99aac;hb=24d3b38a0a02a31f524aa73892e1558160ea70bc;hp=91c745e9326072492727f9e43bf69f8f4637e660;hpb=76e2e4a2bc78a0ca2617e3b336081e29cb00d749;p=oota-llvm.git diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index 91c745e9326..9f94ee38337 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -65,8 +65,9 @@ static bool IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV, // Otherwise, add any offset that our operands provide. gep_type_iterator GTI = gep_type_begin(CE); - for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i, ++GTI) { - ConstantInt *CI = dyn_cast(CE->getOperand(i)); + for (User::const_op_iterator i = CE->op_begin() + 1, e = CE->op_end(); + i != e; ++i, ++GTI) { + ConstantInt *CI = dyn_cast(*i); if (!CI) return false; // Index isn't a simple constant? if (CI->getZExtValue() == 0) continue; // Not adding anything. @@ -297,8 +298,8 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const TargetData *TD) { // Scan the operand list, checking to see if they are all constants, if so, // hand off to ConstantFoldInstOperands. SmallVector Ops; - for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) - if (Constant *Op = dyn_cast(I->getOperand(i))) + for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i) + if (Constant *Op = dyn_cast(*i)) Ops.push_back(Op); else return 0; // All operands not constant! @@ -311,6 +312,25 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const TargetData *TD) { &Ops[0], Ops.size(), TD); } +/// 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. +Constant *llvm::ConstantFoldConstantExpression(ConstantExpr *CE, + const TargetData *TD) { + assert(TD && "ConstantFoldConstantExpression requires a valid TargetData."); + + SmallVector Ops; + for (User::op_iterator i = CE->op_begin(), e = CE->op_end(); i != e; ++i) + Ops.push_back(cast(*i)); + + if (CE->isCompare()) + return ConstantFoldCompareInstOperands(CE->getPredicate(), + &Ops[0], Ops.size(), TD); + else + return ConstantFoldInstOperands(CE->getOpcode(), CE->getType(), + &Ops[0], Ops.size(), TD); +} + /// ConstantFoldInstOperands - Attempt to constant fold an instruction with the /// specified opcode and operands. If successful, the constant result is /// returned, if not, null is returned. Note that this function can fail when @@ -338,6 +358,8 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy, return 0; case Instruction::ICmp: case Instruction::FCmp: + case Instruction::VICmp: + case Instruction::VFCmp: assert(0 &&"This function is invalid for compares: no predicate specified"); case Instruction::PtrToInt: // If the input is a inttoptr, eliminate the pair. This requires knowing @@ -346,16 +368,31 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy, if (TD && CE->getOpcode() == Instruction::IntToPtr) { Constant *Input = CE->getOperand(0); unsigned InWidth = Input->getType()->getPrimitiveSizeInBits(); - Constant *Mask = - ConstantInt::get(APInt::getLowBitsSet(InWidth, - TD->getPointerSizeInBits())); - Input = ConstantExpr::getAnd(Input, Mask); + if (TD->getPointerSizeInBits() < InWidth) { + Constant *Mask = + ConstantInt::get(APInt::getLowBitsSet(InWidth, + TD->getPointerSizeInBits())); + Input = ConstantExpr::getAnd(Input, Mask); + } // Do a zext or trunc to get to the dest size. return ConstantExpr::getIntegerCast(Input, DestTy, false); } } return ConstantExpr::getCast(Opcode, Ops[0], DestTy); case Instruction::IntToPtr: + // If the input is a ptrtoint, turn the pair into a ptr to ptr bitcast if + // the int size is >= the ptr size. This requires knowing the width of a + // pointer, so it can't be done in ConstantExpr::getCast. + if (ConstantExpr *CE = dyn_cast(Ops[0])) { + if (TD && CE->getOpcode() == Instruction::PtrToInt && + TD->getPointerSizeInBits() <= + CE->getType()->getPrimitiveSizeInBits()) { + Constant *Input = CE->getOperand(0); + Constant *C = FoldBitCast(Input, DestTy, *TD); + return C ? C : ConstantExpr::getBitCast(Input, DestTy); + } + } + return ConstantExpr::getCast(Opcode, Ops[0], DestTy); case Instruction::Trunc: case Instruction::ZExt: case Instruction::SExt: @@ -397,7 +434,7 @@ Constant *llvm::ConstantFoldCompareInstOperands(unsigned Predicate, const TargetData *TD) { // fold: icmp (inttoptr x), null -> icmp x, 0 // fold: icmp (ptrtoint x), 0 -> icmp x, null - // fold: icmp (inttoptr x), (inttoptr y) -> icmp x, y + // fold: icmp (inttoptr x), (inttoptr y) -> icmp trunc/zext x, trunc/zext y // fold: icmp (ptrtoint x), (ptrtoint y) -> icmp x, y // // ConstantExpr::getCompare cannot do this, because it doesn't have TD @@ -425,25 +462,35 @@ Constant *llvm::ConstantFoldCompareInstOperands(unsigned Predicate, } } - if (TD && isa(Ops[1]) && - cast(Ops[1])->getOpcode() == CE0->getOpcode()) { - const Type *IntPtrTy = TD->getIntPtrType(); - // Only do this transformation if the int is intptrty in size, otherwise - // there is a truncation or extension that we aren't modeling. - if ((CE0->getOpcode() == Instruction::IntToPtr && - CE0->getOperand(0)->getType() == IntPtrTy && - Ops[1]->getOperand(0)->getType() == IntPtrTy) || - (CE0->getOpcode() == Instruction::PtrToInt && - CE0->getType() == IntPtrTy && - CE0->getOperand(0)->getType() == Ops[1]->getOperand(0)->getType())) { - Constant *NewOps[] = { - CE0->getOperand(0), cast(Ops[1])->getOperand(0) - }; - return ConstantFoldCompareInstOperands(Predicate, NewOps, 2, TD); + if (ConstantExpr *CE1 = dyn_cast(Ops[1])) { + if (TD && CE0->getOpcode() == CE1->getOpcode()) { + const Type *IntPtrTy = TD->getIntPtrType(); + + if (CE0->getOpcode() == Instruction::IntToPtr) { + // Convert the integer value to the right size to ensure we get the + // proper extension or truncation. + Constant *C0 = ConstantExpr::getIntegerCast(CE0->getOperand(0), + IntPtrTy, false); + Constant *C1 = ConstantExpr::getIntegerCast(CE1->getOperand(0), + IntPtrTy, false); + Constant *NewOps[] = { C0, C1 }; + return ConstantFoldCompareInstOperands(Predicate, NewOps, 2, TD); + } + + // Only do this transformation if the int is intptrty in size, otherwise + // there is a truncation or extension that we aren't modeling. + if ((CE0->getOpcode() == Instruction::PtrToInt && + CE0->getType() == IntPtrTy && + CE0->getOperand(0)->getType() == CE1->getOperand(0)->getType())) { + Constant *NewOps[] = { + CE0->getOperand(0), CE1->getOperand(0) + }; + return ConstantFoldCompareInstOperands(Predicate, NewOps, 2, TD); + } } } } - return ConstantExpr::getCompare(Predicate, Ops[0], Ops[1]); + return ConstantExpr::getCompare(Predicate, Ops[0], Ops[1]); } @@ -602,6 +649,7 @@ static Constant *ConstantFoldFP(double (*NativeFP)(double), double V, if (Ty == Type::DoubleTy) return ConstantFP::get(APFloat(V)); assert(0 && "Can only constant fold float/double"); + return 0; // dummy return to suppress warning } static Constant *ConstantFoldBinaryFP(double (*NativeFP)(double, double), @@ -619,6 +667,7 @@ static Constant *ConstantFoldBinaryFP(double (*NativeFP)(double, double), if (Ty == Type::DoubleTy) return ConstantFP::get(APFloat(V)); assert(0 && "Can only constant fold float/double"); + return 0; // dummy return to suppress warning } /// ConstantFoldCall - Attempt to constant fold a call to the specified function