diff options
author | Dan Gohman <gohman@apple.com> | 2010-01-28 02:15:55 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2010-01-28 02:15:55 +0000 |
commit | cf9138307dba746470ece630e3eeb340af5f3432 (patch) | |
tree | 1214eb9c882517581729caac386ee773324414fc /llvm/lib/VMCore/ConstantFold.cpp | |
parent | 08ad1cceb30b2d35b5c751ac8d83c449615e88c0 (diff) | |
download | bcm5719-llvm-cf9138307dba746470ece630e3eeb340af5f3432.tar.gz bcm5719-llvm-cf9138307dba746470ece630e3eeb340af5f3432.zip |
Remove SCEVAllocSizeExpr and SCEVFieldOffsetExpr, and in their place
use plain SCEVUnknowns with ConstantExpr::getSizeOf and
ConstantExpr::getOffsetOf constants. This eliminates a bunch of
special-case code.
Also add code for pattern-matching these expressions, for clients that
want to recognize them.
Move ScalarEvolution's logic for expanding array and vector sizeof
expressions into an element count times the element size, to expose
the multiplication to subsequent folding, into the regular constant
folder.
llvm-svn: 94737
Diffstat (limited to 'llvm/lib/VMCore/ConstantFold.cpp')
-rw-r--r-- | llvm/lib/VMCore/ConstantFold.cpp | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/llvm/lib/VMCore/ConstantFold.cpp b/llvm/lib/VMCore/ConstantFold.cpp index ddd55878cb9..24b78ae969a 100644 --- a/llvm/lib/VMCore/ConstantFold.cpp +++ b/llvm/lib/VMCore/ConstantFold.cpp @@ -415,9 +415,38 @@ Constant *llvm::ConstantFoldCastInstruction(LLVMContext &Context, return ConstantPointerNull::get(cast<PointerType>(DestTy)); return 0; // Other pointer types cannot be casted case Instruction::PtrToInt: // always treated as unsigned - if (V->isNullValue()) // is it a null pointer value? + // Is it a null pointer value? + if (V->isNullValue()) return ConstantInt::get(DestTy, 0); - return 0; // Other pointer types cannot be casted + // If this is a sizeof of an array or vector, pull out a multiplication + // by the element size to expose it to subsequent folding. + if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) + if (CE->getOpcode() == Instruction::GetElementPtr && + CE->getNumOperands() == 2 && + CE->getOperand(0)->isNullValue()) + if (ConstantInt *CI = dyn_cast<ConstantInt>(CE->getOperand(1))) + if (CI->isOne()) { + const Type *Ty = + cast<PointerType>(CE->getOperand(0)->getType())->getElementType(); + if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) { + Constant *N = ConstantInt::get(DestTy, ATy->getNumElements()); + Constant *E = ConstantExpr::getSizeOf(ATy->getElementType()); + E = ConstantExpr::getCast(CastInst::getCastOpcode(E, false, + DestTy, false), + E, DestTy); + return ConstantExpr::getMul(N, E); + } + if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) { + Constant *N = ConstantInt::get(DestTy, VTy->getNumElements()); + Constant *E = ConstantExpr::getSizeOf(VTy->getElementType()); + E = ConstantExpr::getCast(CastInst::getCastOpcode(E, false, + DestTy, false), + E, DestTy); + return ConstantExpr::getMul(N, E); + } + } + // Other pointer types cannot be casted + return 0; case Instruction::UIToFP: case Instruction::SIToFP: if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) { |