summaryrefslogtreecommitdiffstats
path: root/llvm/lib/VMCore/ConstantFold.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2010-01-28 02:15:55 +0000
committerDan Gohman <gohman@apple.com>2010-01-28 02:15:55 +0000
commitcf9138307dba746470ece630e3eeb340af5f3432 (patch)
tree1214eb9c882517581729caac386ee773324414fc /llvm/lib/VMCore/ConstantFold.cpp
parent08ad1cceb30b2d35b5c751ac8d83c449615e88c0 (diff)
downloadbcm5719-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.cpp33
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)) {
OpenPOWER on IntegriCloud