diff options
author | Chris Lattner <sabre@nondot.org> | 2007-04-27 17:44:50 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-04-27 17:44:50 +0000 |
commit | d3e28347e533d77c8274ab4dc764c5e4a7e7387e (patch) | |
tree | 8404b978834cc57ab4c3a99057073fc8028a5423 /lib/Transforms | |
parent | eb7f34f2cb1584f155b9cefdb246b300fb2fc9c4 (diff) | |
download | llvm-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.cpp | 109 |
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()); } } |