X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FConstantFold.cpp;h=2a96291fe49dd2663b836d6bb9513d6debc10f00;hb=c139203f049e1a10e19f3ec4f6785e21323dec6e;hp=0d008870e1fb9110e52e3c9559540d48983850d9;hpb=b228f9c86bcc983e434a3d1df03046d51552bf70;p=oota-llvm.git diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 0d008870e1f..2a96291fe49 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -22,6 +22,7 @@ #include "llvm/Constants.h" #include "llvm/Instructions.h" #include "llvm/DerivedTypes.h" +#include "llvm/Function.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include using namespace llvm; @@ -485,10 +486,10 @@ ConstRules &ConstRules::get(const Constant *V1, const Constant *V2) { static DirectFPRules DoubleR; if (isa(V1) || isa(V2) || - isa(V1) || isa(V2)) + isa(V1) || isa(V2)) return EmptyR; - switch (V1->getType()->getPrimitiveID()) { + switch (V1->getType()->getTypeID()) { default: assert(0 && "Unknown value type for constant folding!"); case Type::BoolTyID: return BoolR; case Type::PointerTyID: return NullPointerR; @@ -523,13 +524,22 @@ Constant *llvm::ConstantFoldCastInstruction(const Constant *V, const Type *DestTy) { if (V->getType() == DestTy) return (Constant*)V; + // Cast of a global address to boolean is always true. + if (const GlobalValue *GV = dyn_cast(V)) + if (DestTy == Type::BoolTy) + // FIXME: When we support 'external weak' references, we have to prevent + // this transformation from happening. In the meantime we avoid folding + // any cast of an external symbol. + if (!GV->isExternal()) + return ConstantBool::True; + if (const ConstantExpr *CE = dyn_cast(V)) if (CE->getOpcode() == Instruction::Cast) { Constant *Op = const_cast(CE->getOperand(0)); // Try to not produce a cast of a cast, which is almost always redundant. if (!Op->getType()->isFloatingPoint() && !CE->getType()->isFloatingPoint() && - !DestTy->getType()->isFloatingPoint()) { + !DestTy->isFloatingPoint()) { unsigned S1 = getSize(Op->getType()), S2 = getSize(CE->getType()); unsigned S3 = getSize(DestTy); if (Op->getType() == DestTy && S3 >= S2) @@ -554,7 +564,7 @@ Constant *llvm::ConstantFoldCastInstruction(const Constant *V, ConstRules &Rules = ConstRules::get(V, V); - switch (DestTy->getPrimitiveID()) { + switch (DestTy->getTypeID()) { case Type::BoolTyID: return Rules.castToBool(V); case Type::UByteTyID: return Rules.castToUByte(V); case Type::SByteTyID: return Rules.castToSByte(V); @@ -572,6 +582,17 @@ Constant *llvm::ConstantFoldCastInstruction(const Constant *V, } } +Constant *llvm::ConstantFoldSelectInstruction(const Constant *Cond, + const Constant *V1, + const Constant *V2) { + if (Cond == ConstantBool::True) + return const_cast(V1); + else if (Cond == ConstantBool::False) + return const_cast(V2); + return 0; +} + + /// IdxCompare - Compare the two constants as though they were getelementptr /// indices. This allows coersion of the types to be the same thing. /// @@ -587,10 +608,10 @@ static int IdxCompare(Constant *C1, Constant *C2) { if (!isa(C1) || !isa(C2)) return -2; // don't know! - // Ok, we have two differing integer indices. Convert them to - // be the same type. Long is always big enough, so we use it. - C1 = ConstantExpr::getCast(C1, Type::LongTy); - C2 = ConstantExpr::getCast(C2, Type::LongTy); + // Ok, we have two differing integer indices. Sign extend them to be the same + // type. Long is always big enough, so we use it. + C1 = ConstantExpr::getSignExtend(C1, Type::LongTy); + C2 = ConstantExpr::getSignExtend(C2, Type::LongTy); if (C1 == C2) return 0; // Are they just differing types? // If they are really different, now that they are the same type, then we @@ -603,15 +624,15 @@ static int IdxCompare(Constant *C1, Constant *C2) { /// evaluateRelation - This function determines if there is anything we can /// decide about the two constants provided. This doesn't need to handle simple -/// things like integer comparisons, but should instead handle ConstantExpr's -/// and ConstantPointerRef's. If we can determine that the two constants have a +/// things like integer comparisons, but should instead handle ConstantExprs +/// and GlobalValuess. If we can determine that the two constants have a /// particular relation to each other, we should return the corresponding SetCC /// code, otherwise return Instruction::BinaryOpsEnd. /// /// To simplify this code we canonicalize the relation so that the first /// operand is always the most "complex" of the two. We consider simple /// constants (like ConstantInt) to be the simplest, followed by -/// ConstantPointerRef's, followed by ConstantExpr's (the most complex). +/// GlobalValues, followed by ConstantExpr's (the most complex). /// static Instruction::BinaryOps evaluateRelation(const Constant *V1, const Constant *V2) { @@ -619,15 +640,15 @@ static Instruction::BinaryOps evaluateRelation(const Constant *V1, "Cannot compare different types of values!"); if (V1 == V2) return Instruction::SetEQ; - if (!isa(V1) && !isa(V1)) { + if (!isa(V1) && !isa(V1)) { // If the first operand is simple, swap operands. - assert((isa(V2) || isa(V2)) && + assert((isa(V2) || isa(V2)) && "Simple cases should have been handled by caller!"); Instruction::BinaryOps SwappedRelation = evaluateRelation(V2, V1); if (SwappedRelation != Instruction::BinaryOpsEnd) return SetCondInst::getSwappedCondition(SwappedRelation); - } else if (const ConstantPointerRef *CPR1 = dyn_cast(V1)){ + } else if (const GlobalValue *CPR1 = dyn_cast(V1)){ if (isa(V2)) { // Swap as necessary. Instruction::BinaryOps SwappedRelation = evaluateRelation(V2, V1); if (SwappedRelation != Instruction::BinaryOpsEnd) @@ -636,11 +657,11 @@ static Instruction::BinaryOps evaluateRelation(const Constant *V1, return Instruction::BinaryOpsEnd; } - // Now we know that the RHS is a ConstantPointerRef or simple constant, + // Now we know that the RHS is a GlobalValue or simple constant, // which (since the types must match) means that it's a ConstantPointerNull. - if (const ConstantPointerRef *CPR2 = dyn_cast(V2)) { - assert(CPR1->getValue() != CPR2->getValue() && - "CPRs for the same value exist at different addresses??"); + if (const GlobalValue *CPR2 = dyn_cast(V2)) { + assert(CPR1 != CPR2 && + "GVs for the same value exist at different addresses??"); // FIXME: If both globals are external weak, they might both be null! return Instruction::SetNE; } else { @@ -664,6 +685,7 @@ static Instruction::BinaryOps evaluateRelation(const Constant *V1, CE1->getType()->isLosslesslyConvertibleTo(CE1Op0->getType())) return evaluateRelation(CE1Op0, Constant::getNullValue(CE1Op0->getType())); + break; case Instruction::GetElementPtr: // Ok, since this is a getelementptr, we know that the constant has a @@ -671,7 +693,7 @@ static Instruction::BinaryOps evaluateRelation(const Constant *V1, if (isa(V2)) { // If we are comparing a GEP to a null pointer, check to see if the base // of the GEP equals the null pointer. - if (isa(CE1Op0)) { + if (isa(CE1Op0)) { // FIXME: this is not true when we have external weak references! // No offset can go from a global to a null pointer. return Instruction::SetGT; @@ -686,13 +708,11 @@ static Instruction::BinaryOps evaluateRelation(const Constant *V1, return Instruction::SetEQ; } // Otherwise, we can't really say if the first operand is null or not. - } else if (const ConstantPointerRef *CPR2 = - dyn_cast(V2)) { + } else if (const GlobalValue *CPR2 = dyn_cast(V2)) { if (isa(CE1Op0)) { // FIXME: This is not true with external weak references. return Instruction::SetLT; - } else if (const ConstantPointerRef *CPR1 = - dyn_cast(CE1Op0)) { + } else if (const GlobalValue *CPR1 = dyn_cast(CE1Op0)) { if (CPR1 == CPR2) { // If this is a getelementptr of the same global, then it must be // different. Because the types must match, the getelementptr could @@ -719,8 +739,7 @@ static Instruction::BinaryOps evaluateRelation(const Constant *V1, case Instruction::GetElementPtr: // By far the most common case to handle is when the base pointers are // obviously to the same or different globals. - if (isa(CE1Op0) && - isa(CE2Op0)) { + if (isa(CE1Op0) && isa(CE2Op0)) { if (CE1Op0 != CE2Op0) // Don't know relative ordering, but not equal return Instruction::SetNE; // Ok, we know that both getelementptr instructions are based on the @@ -873,6 +892,16 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, if (cast(V2)->isAllOnesValue()) return const_cast(V1); // X & -1 == X if (V2->isNullValue()) return const_cast(V2); // X & 0 == 0 + if (CE1->getOpcode() == Instruction::Cast && + isa(CE1->getOperand(0))) { + GlobalValue *CPR =cast(CE1->getOperand(0)); + + // Functions are at least 4-byte aligned. If and'ing the address of a + // function with a constant < 4, fold it to zero. + if (const ConstantInt *CI = dyn_cast(V2)) + if (CI->getRawValue() < 4 && isa(CPR)) + return Constant::getNullValue(CI->getType()); + } break; case Instruction::Or: if (V2->isNullValue()) return const_cast(V1); // X | 0 == X @@ -939,6 +968,18 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, assert(Ty != 0 && "Invalid indices for GEP!"); return ConstantPointerNull::get(PointerType::get(Ty)); } + + if (IdxList.size() == 1) { + const Type *ElTy = cast(C->getType())->getElementType(); + if (unsigned ElSize = ElTy->getPrimitiveSize()) { + // gep null, C is equal to C*sizeof(nullty). If nullty is a known llvm + // type, we can statically fold this. + Constant *R = ConstantUInt::get(Type::UIntTy, ElSize); + R = ConstantExpr::getCast(R, IdxList[0]->getType()); + R = ConstantExpr::getMul(R, IdxList[0]); + return ConstantExpr::getCast(R, C->getType()); + } + } } if (ConstantExpr *CE = dyn_cast(const_cast(C))) { @@ -961,11 +1002,14 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, // Add the last index of the source with the first index of the new GEP. // Make sure to handle the case when they are actually different types. Constant *Combined = CE->getOperand(CE->getNumOperands()-1); - if (!IdxList[0]->isNullValue()) // Otherwise it must be an array + if (!IdxList[0]->isNullValue()) { // Otherwise it must be an array + const Type *IdxTy = Combined->getType(); + if (IdxTy != IdxList[0]->getType()) IdxTy = Type::LongTy; Combined = ConstantExpr::get(Instruction::Add, - ConstantExpr::getCast(IdxList[0], Type::LongTy), - ConstantExpr::getCast(Combined, Type::LongTy)); + ConstantExpr::getCast(IdxList[0], IdxTy), + ConstantExpr::getCast(Combined, IdxTy)); + } NewIndices.push_back(Combined); NewIndices.insert(NewIndices.end(), IdxList.begin()+1, IdxList.end());