[llvm-commits] [llvm] r69215 - /llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp

Dale Johannesen dalej at apple.com
Wed Apr 15 14:03:12 PDT 2009


On Apr 15, 2009, at 2:01 PMPDT, Chris Lattner wrote:

>
> 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? :)

Coming.  Apparently I'm in a hurry, although I didn't find that out  
until lunch.
>
> -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
>
> _______________________________________________
> 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