[llvm-commits] [llvm] r69215 - /llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
Chris Lattner
clattner at apple.com
Wed Apr 15 14:01:39 PDT 2009
On Apr 15, 2009, at 1:41 PM, Dale Johannesen wrote:
> Author: johannes
> Date: Wed Apr 15 15:41:02 2009
> New Revision: 69215
>
> URL: http://llvm.org/viewvc/llvm-project?rev=69215&view=rev
> Log:
> Eliminate zext over (iv & const) or ((iv+const)&const)
> if a longer iv is available. These subscript forms are
> not common; they're a bottleneck in OpenSSL.
Testcase? :)
-Chris
>
>
>
> Modified:
> llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
>
> Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=69215&r1=69214&r2=69215&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Wed Apr 15
> 15:41:02 2009
> @@ -798,48 +798,106 @@
> if (PN == OrigControllingPHI && PN->getType() != LargestType)
> for (Value::use_iterator UI = PN->use_begin(), UE = PN-
> >use_end();
> UI != UE; ++UI) {
> - if (isa<SExtInst>(UI) && NoSignedWrap) {
> + Instruction *UInst = dyn_cast<Instruction>(*UI);
> + if (UInst && isa<SExtInst>(UInst) && NoSignedWrap) {
> Value *TruncIndVar = getSignExtendedTruncVar(AR, SE,
> LargestType, L,
> - UI->getType(),
> Rewriter, InsertPt);
> - UI->replaceAllUsesWith(TruncIndVar);
> - if (Instruction *DeadUse = dyn_cast<Instruction>(*UI))
> - DeadInsts.insert(DeadUse);
> + UInst->getType(),
> Rewriter, InsertPt);
> + UInst->replaceAllUsesWith(TruncIndVar);
> + DeadInsts.insert(UInst);
> }
> // See if we can figure out sext(i+constant) doesn't wrap,
> so we can
> // use a larger add. This is common in subscripting.
> - Instruction *UInst = dyn_cast<Instruction>(*UI);
> if (UInst && UInst->getOpcode()==Instruction::Add &&
> UInst->hasOneUse() &&
> isa<ConstantInt>(UInst->getOperand(1)) &&
> - isa<SExtInst>(UInst->use_begin()) && NoSignedWrap &&
> LimitVal) {
> - uint64_t numBits = LimitVal->getValue().getBitWidth();
> - ConstantInt* RHS = dyn_cast<ConstantInt>(UInst-
> >getOperand(1));
> - if (((APInt::getSignedMaxValue(numBits) - IncrVal-
> >getValue()) -
> - RHS->getValue()).sgt(LimitVal->getValue())) {
> - SExtInst* oldSext = dyn_cast<SExtInst>(UInst-
> >use_begin());
> - Value *TruncIndVar = getSignExtendedTruncVar(AR, SE,
> LargestType, L,
> - oldSext->getType(),
> Rewriter,
> - InsertPt);
> - APInt APcopy = APInt(RHS->getValue());
> - ConstantInt* newRHS =
> - ConstantInt::get(APcopy.sext(oldSext->getType()->
> -
> getPrimitiveSizeInBits()));
> - Value *NewAdd = BinaryOperator::CreateAdd(TruncIndVar,
> newRHS,
> - UInst-
> >getName()+".nosex",
> - UInst);
> - oldSext->replaceAllUsesWith(NewAdd);
> - if (Instruction *DeadUse =
> dyn_cast<Instruction>(oldSext))
> - DeadInsts.insert(DeadUse);
> - if (Instruction *DeadUse = dyn_cast<Instruction>(UInst))
> - DeadInsts.insert(DeadUse);
> + NoSignedWrap && LimitVal) {
> + uint64_t oldBitSize = LimitVal->getValue().getBitWidth();
> + uint64_t newBitSize = LargestType-
> >getPrimitiveSizeInBits();
> + ConstantInt* AddRHS = dyn_cast<ConstantInt>(UInst-
> >getOperand(1));
> + if (((APInt::getSignedMaxValue(oldBitSize) - IncrVal-
> >getValue()) -
> + AddRHS->getValue()).sgt(LimitVal->getValue())) {
> + // We've determined this is (i+constant) and it won't
> overflow.
> + if (isa<SExtInst>(UInst->use_begin())) {
> + SExtInst* oldSext = dyn_cast<SExtInst>(UInst-
> >use_begin());
> + Value *TruncIndVar = getSignExtendedTruncVar(AR, SE,
> LargestType,
> + L, oldSext-
> >getType(), Rewriter,
> + InsertPt);
> + APInt APcopy = APInt(AddRHS->getValue());
> + ConstantInt* newAddRHS
> =ConstantInt::get(APcopy.sext(newBitSize));
> + Value *NewAdd =
> + BinaryOperator::CreateAdd(TruncIndVar, newAddRHS,
> + UInst->getName()
> +".nosex", UInst);
> + oldSext->replaceAllUsesWith(NewAdd);
> + if (Instruction *DeadUse =
> dyn_cast<Instruction>(oldSext))
> + DeadInsts.insert(DeadUse);
> + DeadInsts.insert(UInst);
> + }
> }
> }
> - if (isa<ZExtInst>(UI) && NoUnsignedWrap) {
> + if (UInst && isa<ZExtInst>(UInst) && NoUnsignedWrap) {
> Value *TruncIndVar = getZeroExtendedTruncVar(AR, SE,
> LargestType, L,
> - UI->getType(),
> Rewriter, InsertPt);
> - UI->replaceAllUsesWith(TruncIndVar);
> - if (Instruction *DeadUse = dyn_cast<Instruction>(*UI))
> + UInst->getType(),
> Rewriter, InsertPt);
> + UInst->replaceAllUsesWith(TruncIndVar);
> + DeadInsts.insert(UInst);
> + }
> + // If we have zext(i&constant), we can use the larger
> variable. This
> + // is not common but is a bottleneck in Openssl.
> + // (RHS doesn't have to be constant. There should be a
> better approach
> + // than bottom-up pattern matching for this...)
> + if (UInst && UInst->getOpcode()==Instruction::And &&
> + UInst->hasOneUse() &&
> + isa<ConstantInt>(UInst->getOperand(1)) &&
> + isa<ZExtInst>(UInst->use_begin())) {
> + uint64_t newBitSize = LargestType-
> >getPrimitiveSizeInBits();
> + ConstantInt* AndRHS = dyn_cast<ConstantInt>(UInst-
> >getOperand(1));
> + ZExtInst* oldZext = dyn_cast<ZExtInst>(UInst->use_begin());
> + Value *TruncIndVar = getSignExtendedTruncVar(AR, SE,
> LargestType,
> + L, oldZext->getType(), Rewriter,
> InsertPt);
> + APInt APcopy = APInt(AndRHS->getValue());
> + ConstantInt* newAndRHS =
> ConstantInt::get(APcopy.zext(newBitSize));
> + Value *NewAnd =
> + BinaryOperator::CreateAnd(TruncIndVar, newAndRHS,
> + UInst->getName()
> +".nozex", UInst);
> + oldZext->replaceAllUsesWith(NewAnd);
> + if (Instruction *DeadUse = dyn_cast<Instruction>(oldZext))
> DeadInsts.insert(DeadUse);
> + DeadInsts.insert(UInst);
> + }
> + // If we have zext((i+constant)&constant), we can use the
> larger
> + // variable even if the add does overflow. This works
> whenever the
> + // constant being ANDed is the same size as i, which it
> presumably is.
> + // We don't need to restrict the expression being and'ed to
> i+const,
> + // but we have to promote everything in it, so it's
> convenient.
> + if (UInst && UInst->getOpcode()==Instruction::Add &&
> + UInst->hasOneUse() &&
> + isa<ConstantInt>(UInst->getOperand(1))) {
> + uint64_t newBitSize = LargestType-
> >getPrimitiveSizeInBits();
> + ConstantInt* AddRHS = dyn_cast<ConstantInt>(UInst-
> >getOperand(1));
> + Instruction *UInst2 = dyn_cast<Instruction>(UInst-
> >use_begin());
> + if (UInst2 && UInst2->getOpcode() == Instruction::And &&
> + UInst2->hasOneUse() &&
> + isa<ConstantInt>(UInst2->getOperand(1)) &&
> + isa<ZExtInst>(UInst2->use_begin())) {
> + ZExtInst* oldZext = dyn_cast<ZExtInst>(UInst2-
> >use_begin());
> + Value *TruncIndVar = getSignExtendedTruncVar(AR, SE,
> LargestType,
> + L, oldZext->getType(),
> Rewriter, InsertPt);
> + ConstantInt* AndRHS = dyn_cast<ConstantInt>(UInst2-
> >getOperand(1));
> + APInt APcopy = APInt(AddRHS->getValue());
> + ConstantInt* newAddRHS =
> ConstantInt::get(APcopy.zext(newBitSize));
> + Value *NewAdd =
> + BinaryOperator::CreateAdd(TruncIndVar, newAddRHS,
> + UInst->getName()
> +".nozex", UInst2);
> + APInt APcopy2 = APInt(AndRHS->getValue());
> + ConstantInt* newAndRHS =
> ConstantInt::get(APcopy2.zext(newBitSize));
> + Value *NewAnd =
> + BinaryOperator::CreateAnd(NewAdd, newAndRHS,
> + UInst->getName()
> +".nozex", UInst2);
> + oldZext->replaceAllUsesWith(NewAnd);
> + if (Instruction *DeadUse =
> dyn_cast<Instruction>(oldZext))
> + DeadInsts.insert(DeadUse);
> + DeadInsts.insert(UInst);
> + DeadInsts.insert(UInst2);
> + }
> }
> }
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list