diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-11-04 14:58:56 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-11-04 14:58:56 +0000 |
commit | 7ff99155c39edd73ebf1c6adfa023b1048fee9a4 (patch) | |
tree | b4dc751bcee540346911aa4115729eff2f991657 /lib/Analysis/ConstantFolding.cpp | |
parent | d1f06de484602e72707476a6152974847bac1570 (diff) | |
download | FreeBSD-src-7ff99155c39edd73ebf1c6adfa023b1048fee9a4.zip FreeBSD-src-7ff99155c39edd73ebf1c6adfa023b1048fee9a4.tar.gz |
Update LLVM to r86025.
Diffstat (limited to 'lib/Analysis/ConstantFolding.cpp')
-rw-r--r-- | lib/Analysis/ConstantFolding.cpp | 277 |
1 files changed, 147 insertions, 130 deletions
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index 214caeb..33a5792 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -39,6 +39,138 @@ using namespace llvm; // Constant Folding internal helper functions //===----------------------------------------------------------------------===// +/// FoldBitCast - Constant fold bitcast, symbolically evaluating it with +/// TargetData. This always returns a non-null constant, but it may be a +/// ConstantExpr if unfoldable. +static Constant *FoldBitCast(Constant *C, const Type *DestTy, + const TargetData &TD) { + + // This only handles casts to vectors currently. + const VectorType *DestVTy = dyn_cast<VectorType>(DestTy); + if (DestVTy == 0) + return ConstantExpr::getBitCast(C, DestTy); + + // If this is a scalar -> vector cast, convert the input into a <1 x scalar> + // vector so the code below can handle it uniformly. + if (isa<ConstantFP>(C) || isa<ConstantInt>(C)) { + Constant *Ops = C; // don't take the address of C! + return FoldBitCast(ConstantVector::get(&Ops, 1), DestTy, TD); + } + + // If this is a bitcast from constant vector -> vector, fold it. + ConstantVector *CV = dyn_cast<ConstantVector>(C); + if (CV == 0) + return ConstantExpr::getBitCast(C, DestTy); + + // If the element types match, VMCore can fold it. + unsigned NumDstElt = DestVTy->getNumElements(); + unsigned NumSrcElt = CV->getNumOperands(); + if (NumDstElt == NumSrcElt) + return ConstantExpr::getBitCast(C, DestTy); + + const Type *SrcEltTy = CV->getType()->getElementType(); + const Type *DstEltTy = DestVTy->getElementType(); + + // Otherwise, we're changing the number of elements in a vector, which + // requires endianness information to do the right thing. For example, + // bitcast (<2 x i64> <i64 0, i64 1> to <4 x i32>) + // folds to (little endian): + // <4 x i32> <i32 0, i32 0, i32 1, i32 0> + // and to (big endian): + // <4 x i32> <i32 0, i32 0, i32 0, i32 1> + + // First thing is first. We only want to think about integer here, so if + // we have something in FP form, recast it as integer. + if (DstEltTy->isFloatingPoint()) { + // Fold to an vector of integers with same size as our FP type. + unsigned FPWidth = DstEltTy->getPrimitiveSizeInBits(); + const Type *DestIVTy = + VectorType::get(IntegerType::get(C->getContext(), FPWidth), NumDstElt); + // Recursively handle this integer conversion, if possible. + C = FoldBitCast(C, DestIVTy, TD); + if (!C) return ConstantExpr::getBitCast(C, DestTy); + + // Finally, VMCore can handle this now that #elts line up. + return ConstantExpr::getBitCast(C, DestTy); + } + + // Okay, we know the destination is integer, if the input is FP, convert + // it to integer first. + if (SrcEltTy->isFloatingPoint()) { + unsigned FPWidth = SrcEltTy->getPrimitiveSizeInBits(); + const Type *SrcIVTy = + VectorType::get(IntegerType::get(C->getContext(), FPWidth), NumSrcElt); + // Ask VMCore to do the conversion now that #elts line up. + C = ConstantExpr::getBitCast(C, SrcIVTy); + CV = dyn_cast<ConstantVector>(C); + if (!CV) // If VMCore wasn't able to fold it, bail out. + return C; + } + + // Now we know that the input and output vectors are both integer vectors + // of the same size, and that their #elements is not the same. Do the + // conversion here, which depends on whether the input or output has + // more elements. + bool isLittleEndian = TD.isLittleEndian(); + + SmallVector<Constant*, 32> Result; + if (NumDstElt < NumSrcElt) { + // Handle: bitcast (<4 x i32> <i32 0, i32 1, i32 2, i32 3> to <2 x i64>) + Constant *Zero = Constant::getNullValue(DstEltTy); + unsigned Ratio = NumSrcElt/NumDstElt; + unsigned SrcBitSize = SrcEltTy->getPrimitiveSizeInBits(); + unsigned SrcElt = 0; + for (unsigned i = 0; i != NumDstElt; ++i) { + // Build each element of the result. + Constant *Elt = Zero; + unsigned ShiftAmt = isLittleEndian ? 0 : SrcBitSize*(Ratio-1); + for (unsigned j = 0; j != Ratio; ++j) { + Constant *Src = dyn_cast<ConstantInt>(CV->getOperand(SrcElt++)); + if (!Src) // Reject constantexpr elements. + return ConstantExpr::getBitCast(C, DestTy); + + // Zero extend the element to the right size. + Src = ConstantExpr::getZExt(Src, Elt->getType()); + + // Shift it to the right place, depending on endianness. + Src = ConstantExpr::getShl(Src, + ConstantInt::get(Src->getType(), ShiftAmt)); + ShiftAmt += isLittleEndian ? SrcBitSize : -SrcBitSize; + + // Mix it in. + Elt = ConstantExpr::getOr(Elt, Src); + } + Result.push_back(Elt); + } + } else { + // Handle: bitcast (<2 x i64> <i64 0, i64 1> to <4 x i32>) + unsigned Ratio = NumDstElt/NumSrcElt; + unsigned DstBitSize = DstEltTy->getPrimitiveSizeInBits(); + + // Loop over each source value, expanding into multiple results. + for (unsigned i = 0; i != NumSrcElt; ++i) { + Constant *Src = dyn_cast<ConstantInt>(CV->getOperand(i)); + if (!Src) // Reject constantexpr elements. + return ConstantExpr::getBitCast(C, DestTy); + + unsigned ShiftAmt = isLittleEndian ? 0 : DstBitSize*(Ratio-1); + for (unsigned j = 0; j != Ratio; ++j) { + // Shift the piece of the value into the right place, depending on + // endianness. + Constant *Elt = ConstantExpr::getLShr(Src, + ConstantInt::get(Src->getType(), ShiftAmt)); + ShiftAmt += isLittleEndian ? DstBitSize : -DstBitSize; + + // Truncate and remember this piece. + Result.push_back(ConstantExpr::getTrunc(Elt, DstEltTy)); + } + } + } + + return ConstantVector::get(Result.data(), Result.size()); +} + + /// IsConstantOffsetFromGlobal - If this constant is actually a constant offset /// from a global, return the global and the constant. Because of /// constantexprs, this function is recursive. @@ -103,6 +235,8 @@ static bool ReadDataFromGlobal(Constant *C, uint64_t ByteOffset, assert(ByteOffset <= TD.getTypeAllocSize(C->getType()) && "Out of range access"); + // If this element is zero or undefined, we can just return since *CurPtr is + // zero initialized. if (isa<ConstantAggregateZero>(C) || isa<UndefValue>(C)) return true; @@ -115,7 +249,7 @@ static bool ReadDataFromGlobal(Constant *C, uint64_t ByteOffset, unsigned IntBytes = unsigned(CI->getBitWidth()/8); for (unsigned i = 0; i != BytesLeft && ByteOffset != IntBytes; ++i) { - CurPtr[i] = (unsigned char)(Val >> ByteOffset * 8); + CurPtr[i] = (unsigned char)(Val >> (ByteOffset * 8)); ++ByteOffset; } return true; @@ -123,13 +257,14 @@ static bool ReadDataFromGlobal(Constant *C, uint64_t ByteOffset, if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) { if (CFP->getType()->isDoubleTy()) { - C = ConstantExpr::getBitCast(C, Type::getInt64Ty(C->getContext())); + C = FoldBitCast(C, Type::getInt64Ty(C->getContext()), TD); return ReadDataFromGlobal(C, ByteOffset, CurPtr, BytesLeft, TD); } if (CFP->getType()->isFloatTy()){ - C = ConstantExpr::getBitCast(C, Type::getInt32Ty(C->getContext())); + C = FoldBitCast(C, Type::getInt32Ty(C->getContext()), TD); return ReadDataFromGlobal(C, ByteOffset, CurPtr, BytesLeft, TD); } + return false; } if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C)) { @@ -161,6 +296,7 @@ static bool ReadDataFromGlobal(Constant *C, uint64_t ByteOffset, return true; // Move to the next element of the struct. + CurPtr += NextEltOffset-CurEltOffset-ByteOffset; BytesLeft -= NextEltOffset-CurEltOffset-ByteOffset; ByteOffset = 0; CurEltOffset = NextEltOffset; @@ -231,9 +367,9 @@ static Constant *FoldReinterpretLoadFromConstPtr(Constant *C, } else return 0; - C = ConstantExpr::getBitCast(C, MapTy); + C = FoldBitCast(C, MapTy, TD); if (Constant *Res = FoldReinterpretLoadFromConstPtr(C, TD)) - return ConstantExpr::getBitCast(Res, LoadTy); + return FoldBitCast(Res, LoadTy, TD); return 0; } @@ -246,8 +382,7 @@ static Constant *FoldReinterpretLoadFromConstPtr(Constant *C, return 0; GlobalVariable *GV = dyn_cast<GlobalVariable>(GVal); - if (!GV || !GV->isConstant() || !GV->hasInitializer() || - !GV->hasDefinitiveInitializer() || + if (!GV || !GV->isConstant() || !GV->hasDefinitiveInitializer() || !GV->getInitializer()->getType()->isSized()) return 0; @@ -476,126 +611,11 @@ static Constant *SymbolicallyEvaluateGEP(Constant* const* Ops, unsigned NumOps, // If we ended up indexing a member with a type that doesn't match // the type of what the original indices indexed, add a cast. if (Ty != cast<PointerType>(ResultTy)->getElementType()) - C = ConstantExpr::getBitCast(C, ResultTy); + C = FoldBitCast(C, ResultTy, *TD); return C; } -/// FoldBitCast - Constant fold bitcast, symbolically evaluating it with -/// targetdata. Return 0 if unfoldable. -static Constant *FoldBitCast(Constant *C, const Type *DestTy, - const TargetData &TD, LLVMContext &Context) { - // If this is a bitcast from constant vector -> vector, fold it. - if (ConstantVector *CV = dyn_cast<ConstantVector>(C)) { - if (const VectorType *DestVTy = dyn_cast<VectorType>(DestTy)) { - // If the element types match, VMCore can fold it. - unsigned NumDstElt = DestVTy->getNumElements(); - unsigned NumSrcElt = CV->getNumOperands(); - if (NumDstElt == NumSrcElt) - return 0; - - const Type *SrcEltTy = CV->getType()->getElementType(); - const Type *DstEltTy = DestVTy->getElementType(); - - // Otherwise, we're changing the number of elements in a vector, which - // requires endianness information to do the right thing. For example, - // bitcast (<2 x i64> <i64 0, i64 1> to <4 x i32>) - // folds to (little endian): - // <4 x i32> <i32 0, i32 0, i32 1, i32 0> - // and to (big endian): - // <4 x i32> <i32 0, i32 0, i32 0, i32 1> - - // First thing is first. We only want to think about integer here, so if - // we have something in FP form, recast it as integer. - if (DstEltTy->isFloatingPoint()) { - // Fold to an vector of integers with same size as our FP type. - unsigned FPWidth = DstEltTy->getPrimitiveSizeInBits(); - const Type *DestIVTy = VectorType::get( - IntegerType::get(Context, FPWidth), NumDstElt); - // Recursively handle this integer conversion, if possible. - C = FoldBitCast(C, DestIVTy, TD, Context); - if (!C) return 0; - - // Finally, VMCore can handle this now that #elts line up. - return ConstantExpr::getBitCast(C, DestTy); - } - - // Okay, we know the destination is integer, if the input is FP, convert - // it to integer first. - if (SrcEltTy->isFloatingPoint()) { - unsigned FPWidth = SrcEltTy->getPrimitiveSizeInBits(); - const Type *SrcIVTy = VectorType::get( - IntegerType::get(Context, FPWidth), NumSrcElt); - // Ask VMCore to do the conversion now that #elts line up. - C = ConstantExpr::getBitCast(C, SrcIVTy); - CV = dyn_cast<ConstantVector>(C); - if (!CV) return 0; // If VMCore wasn't able to fold it, bail out. - } - - // Now we know that the input and output vectors are both integer vectors - // of the same size, and that their #elements is not the same. Do the - // conversion here, which depends on whether the input or output has - // more elements. - bool isLittleEndian = TD.isLittleEndian(); - - SmallVector<Constant*, 32> Result; - if (NumDstElt < NumSrcElt) { - // Handle: bitcast (<4 x i32> <i32 0, i32 1, i32 2, i32 3> to <2 x i64>) - Constant *Zero = Constant::getNullValue(DstEltTy); - unsigned Ratio = NumSrcElt/NumDstElt; - unsigned SrcBitSize = SrcEltTy->getPrimitiveSizeInBits(); - unsigned SrcElt = 0; - for (unsigned i = 0; i != NumDstElt; ++i) { - // Build each element of the result. - Constant *Elt = Zero; - unsigned ShiftAmt = isLittleEndian ? 0 : SrcBitSize*(Ratio-1); - for (unsigned j = 0; j != Ratio; ++j) { - Constant *Src = dyn_cast<ConstantInt>(CV->getOperand(SrcElt++)); - if (!Src) return 0; // Reject constantexpr elements. - - // Zero extend the element to the right size. - Src = ConstantExpr::getZExt(Src, Elt->getType()); - - // Shift it to the right place, depending on endianness. - Src = ConstantExpr::getShl(Src, - ConstantInt::get(Src->getType(), ShiftAmt)); - ShiftAmt += isLittleEndian ? SrcBitSize : -SrcBitSize; - - // Mix it in. - Elt = ConstantExpr::getOr(Elt, Src); - } - Result.push_back(Elt); - } - } else { - // Handle: bitcast (<2 x i64> <i64 0, i64 1> to <4 x i32>) - unsigned Ratio = NumDstElt/NumSrcElt; - unsigned DstBitSize = DstEltTy->getPrimitiveSizeInBits(); - - // Loop over each source value, expanding into multiple results. - for (unsigned i = 0; i != NumSrcElt; ++i) { - Constant *Src = dyn_cast<ConstantInt>(CV->getOperand(i)); - if (!Src) return 0; // Reject constantexpr elements. - - unsigned ShiftAmt = isLittleEndian ? 0 : DstBitSize*(Ratio-1); - for (unsigned j = 0; j != Ratio; ++j) { - // Shift the piece of the value into the right place, depending on - // endianness. - Constant *Elt = ConstantExpr::getLShr(Src, - ConstantInt::get(Src->getType(), ShiftAmt)); - ShiftAmt += isLittleEndian ? DstBitSize : -DstBitSize; - - // Truncate and remember this piece. - Result.push_back(ConstantExpr::getTrunc(Elt, DstEltTy)); - } - } - } - - return ConstantVector::get(Result.data(), Result.size()); - } - } - - return 0; -} //===----------------------------------------------------------------------===// @@ -721,11 +741,9 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy, if (TD && TD->getPointerSizeInBits() <= CE->getType()->getScalarSizeInBits()) { - if (CE->getOpcode() == Instruction::PtrToInt) { - Constant *Input = CE->getOperand(0); - Constant *C = FoldBitCast(Input, DestTy, *TD, Context); - return C ? C : ConstantExpr::getBitCast(Input, DestTy); - } + if (CE->getOpcode() == Instruction::PtrToInt) + return FoldBitCast(CE->getOperand(0), DestTy, *TD); + // If there's a constant offset added to the integer value before // it is casted back to a pointer, see if the expression can be // converted into a GEP. @@ -771,8 +789,7 @@ Constant *llvm::ConstantFoldInstOperands(unsigned Opcode, const Type *DestTy, return ConstantExpr::getCast(Opcode, Ops[0], DestTy); case Instruction::BitCast: if (TD) - if (Constant *C = FoldBitCast(Ops[0], DestTy, *TD, Context)) - return C; + return FoldBitCast(Ops[0], DestTy, *TD); return ConstantExpr::getBitCast(Ops[0], DestTy); case Instruction::Select: return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2]); |