summaryrefslogtreecommitdiff
path: root/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-04-27 17:44:50 +0000
committerChris Lattner <sabre@nondot.org>2007-04-27 17:44:50 +0000
commitd3e28347e533d77c8274ab4dc764c5e4a7e7387e (patch)
tree8404b978834cc57ab4c3a99057073fc8028a5423 /lib/Transforms
parenteb7f34f2cb1584f155b9cefdb246b300fb2fc9c4 (diff)
downloadllvm-d3e28347e533d77c8274ab4dc764c5e4a7e7387e.tar.gz
llvm-d3e28347e533d77c8274ab4dc764c5e4a7e7387e.tar.bz2
llvm-d3e28347e533d77c8274ab4dc764c5e4a7e7387e.tar.xz
refactor some code relating to pointer cast xforms, pulling it out of the codepath
for unrelated casts. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36511 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp109
1 files changed, 56 insertions, 53 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 93a08a613e..40e7624b19 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -193,6 +193,7 @@ namespace {
BinaryOperator &I);
Instruction *commonCastTransforms(CastInst &CI);
Instruction *commonIntCastTransforms(CastInst &CI);
+ Instruction *commonPointerCastTransforms(CastInst &CI);
Instruction *visitTrunc(TruncInst &CI);
Instruction *visitZExt(ZExtInst &CI);
Instruction *visitSExt(SExtInst &CI);
@@ -204,7 +205,7 @@ namespace {
Instruction *visitSIToFP(CastInst &CI);
Instruction *visitPtrToInt(CastInst &CI);
Instruction *visitIntToPtr(CastInst &CI);
- Instruction *visitBitCast(CastInst &CI);
+ Instruction *visitBitCast(BitCastInst &CI);
Instruction *FoldSelectOpOp(SelectInst &SI, Instruction *TI,
Instruction *FI);
Instruction *visitSelectInst(SelectInst &CI);
@@ -350,7 +351,7 @@ namespace {
bool isSub, Instruction &I);
Instruction *InsertRangeTest(Value *V, Constant *Lo, Constant *Hi,
bool isSigned, bool Inside, Instruction &IB);
- Instruction *PromoteCastOfAllocation(CastInst &CI, AllocationInst &AI);
+ Instruction *PromoteCastOfAllocation(BitCastInst &CI, AllocationInst &AI);
Instruction *MatchBSwap(BinaryOperator &I);
bool SimplifyStoreAtEndOfBlock(StoreInst &SI);
@@ -6085,10 +6086,9 @@ static Value *DecomposeSimpleLinearExpr(Value *Val, unsigned &Scale,
/// PromoteCastOfAllocation - If we find a cast of an allocation instruction,
/// try to eliminate the cast by moving the type information into the alloc.
-Instruction *InstCombiner::PromoteCastOfAllocation(CastInst &CI,
+Instruction *InstCombiner::PromoteCastOfAllocation(BitCastInst &CI,
AllocationInst &AI) {
- const PointerType *PTy = dyn_cast<PointerType>(CI.getType());
- if (!PTy) return 0; // Not casting the allocation to a pointer type.
+ const PointerType *PTy = cast<PointerType>(CI.getType());
// Remove any uses of AI that are dead.
assert(!CI.use_empty() && "Dead instructions should be removed earlier!");
@@ -6326,18 +6326,28 @@ Instruction *InstCombiner::commonCastTransforms(CastInst &CI) {
}
}
+ // If we are casting a select then fold the cast into the select
+ if (SelectInst *SI = dyn_cast<SelectInst>(Src))
+ if (Instruction *NV = FoldOpIntoSelect(CI, SI, this))
+ return NV;
+
+ // If we are casting a PHI then fold the cast into the PHI
+ if (isa<PHINode>(Src))
+ if (Instruction *NV = FoldOpIntoPhi(CI))
+ return NV;
+
+ return 0;
+}
+
+/// @brief Implement the transforms for cast of pointer (bitcast/ptrtoint)
+Instruction *InstCombiner::commonPointerCastTransforms(CastInst &CI) {
+ Value *Src = CI.getOperand(0);
+
// If casting the result of a getelementptr instruction with no offset, turn
// this into a cast of the original pointer!
//
if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Src)) {
- bool AllZeroOperands = true;
- for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i)
- if (!isa<Constant>(GEP->getOperand(i)) ||
- !cast<Constant>(GEP->getOperand(i))->isNullValue()) {
- AllZeroOperands = false;
- break;
- }
- if (AllZeroOperands) {
+ if (GEP->hasAllZeroIndices()) {
// Changing the cast operand is usually not a good idea but it is safe
// here because the pointer operand is being replaced with another
// pointer operand so the opcode doesn't need to change.
@@ -6346,24 +6356,10 @@ Instruction *InstCombiner::commonCastTransforms(CastInst &CI) {
}
}
- // If we are casting a malloc or alloca to a pointer to a type of the same
- // size, rewrite the allocation instruction to allocate the "right" type.
- if (AllocationInst *AI = dyn_cast<AllocationInst>(Src))
- if (Instruction *V = PromoteCastOfAllocation(CI, *AI))
- return V;
+ return commonCastTransforms(CI);
+}
- // If we are casting a select then fold the cast into the select
- if (SelectInst *SI = dyn_cast<SelectInst>(Src))
- if (Instruction *NV = FoldOpIntoSelect(CI, SI, this))
- return NV;
- // If we are casting a PHI then fold the cast into the PHI
- if (isa<PHINode>(Src))
- if (Instruction *NV = FoldOpIntoPhi(CI))
- return NV;
-
- return 0;
-}
/// Only the TRUNC, ZEXT, SEXT, and BITCAST can both operand and result as
/// integer types. This function implements the common transforms for all those
@@ -6786,15 +6782,14 @@ Instruction *InstCombiner::visitSIToFP(CastInst &CI) {
}
Instruction *InstCombiner::visitPtrToInt(CastInst &CI) {
- return commonCastTransforms(CI);
+ return commonPointerCastTransforms(CI);
}
Instruction *InstCombiner::visitIntToPtr(CastInst &CI) {
return commonCastTransforms(CI);
}
-Instruction *InstCombiner::visitBitCast(CastInst &CI) {
-
+Instruction *InstCombiner::visitBitCast(BitCastInst &CI) {
// If the operands are integer typed then apply the integer transforms,
// otherwise just apply the common ones.
Value *Src = CI.getOperand(0);
@@ -6804,6 +6799,9 @@ Instruction *InstCombiner::visitBitCast(CastInst &CI) {
if (SrcTy->isInteger() && DestTy->isInteger()) {
if (Instruction *Result = commonIntCastTransforms(CI))
return Result;
+ } else if (isa<PointerType>(SrcTy)) {
+ if (Instruction *I = commonPointerCastTransforms(CI))
+ return I;
} else {
if (Instruction *Result = commonCastTransforms(CI))
return Result;
@@ -6815,28 +6813,33 @@ Instruction *InstCombiner::visitBitCast(CastInst &CI) {
if (DestTy == Src->getType())
return ReplaceInstUsesWith(CI, Src);
- // If the source and destination are pointers, and this cast is equivalent to
- // a getelementptr X, 0, 0, 0... turn it into the appropriate getelementptr.
- // This can enhance SROA and other transforms that want type-safe pointers.
if (const PointerType *DstPTy = dyn_cast<PointerType>(DestTy)) {
- if (const PointerType *SrcPTy = dyn_cast<PointerType>(SrcTy)) {
- const Type *DstElTy = DstPTy->getElementType();
- const Type *SrcElTy = SrcPTy->getElementType();
-
- Constant *ZeroUInt = Constant::getNullValue(Type::Int32Ty);
- unsigned NumZeros = 0;
- while (SrcElTy != DstElTy &&
- isa<CompositeType>(SrcElTy) && !isa<PointerType>(SrcElTy) &&
- SrcElTy->getNumContainedTypes() /* not "{}" */) {
- SrcElTy = cast<CompositeType>(SrcElTy)->getTypeAtIndex(ZeroUInt);
- ++NumZeros;
- }
-
- // If we found a path from the src to dest, create the getelementptr now.
- if (SrcElTy == DstElTy) {
- SmallVector<Value*, 8> Idxs(NumZeros+1, ZeroUInt);
- return new GetElementPtrInst(Src, &Idxs[0], Idxs.size());
- }
+ const PointerType *SrcPTy = cast<PointerType>(SrcTy);
+ const Type *DstElTy = DstPTy->getElementType();
+ const Type *SrcElTy = SrcPTy->getElementType();
+
+ // If we are casting a malloc or alloca to a pointer to a type of the same
+ // size, rewrite the allocation instruction to allocate the "right" type.
+ if (AllocationInst *AI = dyn_cast<AllocationInst>(Src))
+ if (Instruction *V = PromoteCastOfAllocation(CI, *AI))
+ return V;
+
+ // If the source and destination are pointers, and this cast is equivalent to
+ // a getelementptr X, 0, 0, 0... turn it into the appropriate getelementptr.
+ // This can enhance SROA and other transforms that want type-safe pointers.
+ Constant *ZeroUInt = Constant::getNullValue(Type::Int32Ty);
+ unsigned NumZeros = 0;
+ while (SrcElTy != DstElTy &&
+ isa<CompositeType>(SrcElTy) && !isa<PointerType>(SrcElTy) &&
+ SrcElTy->getNumContainedTypes() /* not "{}" */) {
+ SrcElTy = cast<CompositeType>(SrcElTy)->getTypeAtIndex(ZeroUInt);
+ ++NumZeros;
+ }
+
+ // If we found a path from the src to dest, create the getelementptr now.
+ if (SrcElTy == DstElTy) {
+ SmallVector<Value*, 8> Idxs(NumZeros+1, ZeroUInt);
+ return new GetElementPtrInst(Src, &Idxs[0], Idxs.size());
}
}