From 9c08050ac7ca5d444b7a4c821b5d0ab086b6123f Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 1 Nov 2006 07:43:41 +0000 Subject: [PATCH] Factor gep instructions through phi nodes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31346 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/InstructionCombining.cpp | 49 +++++++++++++++---- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index b9ce08697c8..52262f46c6b 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -6785,9 +6785,11 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) { /// and a single binop. Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) { Instruction *FirstInst = cast(PN.getIncomingValue(0)); - assert(isa(FirstInst) || isa(FirstInst)); + assert(isa(FirstInst) || isa(FirstInst) || + isa(FirstInst)); unsigned Opc = FirstInst->getOpcode(); const Type *LHSType = FirstInst->getOperand(0)->getType(); + const Type *RHSType = FirstInst->getOperand(1)->getType(); // Scan to see if all operands are the same opcode, all have one use, and all // kill their operands (i.e. the operands have one use). @@ -6795,8 +6797,9 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) { Instruction *I = dyn_cast(PN.getIncomingValue(i)); if (!I || I->getOpcode() != Opc || !I->hasOneUse() || // Verify type of the LHS matches so we don't fold setcc's of different - // types. - I->getOperand(0)->getType() != LHSType) + // types or GEP's with different index types. + I->getOperand(0)->getType() != LHSType || + I->getOperand(1)->getType() != RHSType) return 0; } @@ -6823,14 +6826,35 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) { NewRHS->addIncoming(NewInRHS, PN.getIncomingBlock(i)); } - InsertNewInstBefore(NewLHS, PN); - InsertNewInstBefore(NewRHS, PN); - + Value *LHSVal; + if (InLHS) { + // The new PHI unions all of the same values together. This is really + // common, so we handle it intelligently here for compile-time speed. + LHSVal = InLHS; + delete NewLHS; + } else { + InsertNewInstBefore(NewLHS, PN); + LHSVal = NewLHS; + } + Value *RHSVal; + if (InRHS) { + // The new PHI unions all of the same values together. This is really + // common, so we handle it intelligently here for compile-time speed. + RHSVal = InRHS; + delete NewRHS; + } else { + InsertNewInstBefore(NewRHS, PN); + RHSVal = NewRHS; + } + if (BinaryOperator *BinOp = dyn_cast(FirstInst)) - return BinaryOperator::create(BinOp->getOpcode(), NewLHS, NewRHS); - else - return new ShiftInst(cast(FirstInst)->getOpcode(), - NewLHS, NewRHS); + return BinaryOperator::create(BinOp->getOpcode(), LHSVal, RHSVal); + else if (ShiftInst *SI = dyn_cast(FirstInst)) + return new ShiftInst(SI->getOpcode(), LHSVal, RHSVal); + else { + assert(isa(FirstInst)); + return new GetElementPtrInst(LHSVal, RHSVal); + } } /// isSafeToSinkLoad - Return true if we know that it is safe sink the load out @@ -6875,6 +6899,11 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) { if (LI->getParent() != PN.getIncomingBlock(0) || !isSafeToSinkLoad(LI)) return 0; + } else if (isa(FirstInst)) { + if (FirstInst->getNumOperands() == 2) + return FoldPHIArgBinOpIntoPHI(PN); + // Can't handle general GEPs yet. + return 0; } else { return 0; // Cannot fold this operation. }