llvm.org GIT mirror llvm / 78dce25
[SCEV] Compute affine range in another way to avoid bitwidth extending. Summary: This approach has two major advantages over the existing one: 1. We don't need to extend bitwidth in our computations. Extending bitwidth is a big issue for compile time as we often end up working with APInts wider than 64bit, which is a slow case for APInt. 2. When we zero extend a wrapped range, we lose some information (we replace the range with [0, 1 << src bit width)). Thus, avoiding such extensions better preserves information. Correctness testing: I ran 'ninja check' with assertions that the new implementation of getRangeForAffineAR gives the same results as the old one (this functionality is not present in this patch). There were several failures - I inspected them manually and found out that they all are caused by the fact that we're returning more accurate results now (see bullet (2) above). Without such assertions 'ninja check' works just fine, as well as SPEC2006. Compile time testing: CTMark/Os: - mafft/pairlocalalign -16.98% - tramp3d-v4/tramp3d-v4 -12.72% - lencod/lencod -11.51% - Bullet/bullet -4.36% - ClamAV/clamscan -3.66% - 7zip/7zip-benchmark -3.19% - sqlite3/sqlite3 -2.95% - SPASS/SPASS -2.74% - Average -5.81% Performance testing: The changes are expected to be neutral for runtime performance. Reviewers: sanjoy, atrick, pete Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D30477 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297992 91177308-0d34-0410-b5e6-96231b3b80d8 Michael Zolotukhin 3 years ago
2 changed file(s) with 96 addition(s) and 51 deletion(s). Raw diff Collapse all Expand all
47124712 return setRange(S, SignHint, ConservativeResult);
47134713 }
47144714
4715 // Given a StartRange, Step and MaxBECount for an expression compute a range of
4716 // values that the expression can take. Initially, the expression has a value
4717 // from StartRange and then is changed by Step up to MaxBECount times. Signed
4718 // argument defines if we treat Step as signed or unsigned.
4719 static ConstantRange getRangeForAffineARHelper(APInt Step,
4720 ConstantRange StartRange,
4721 APInt MaxBECount,
4722 unsigned BitWidth, bool Signed) {
4723 // If either Step or MaxBECount is 0, then the expression won't change, and we
4724 // just need to return the initial range.
4725 if (Step == 0 || MaxBECount == 0)
4726 return StartRange;
4727
4728 // If we don't know anything about the inital value (i.e. StartRange is
4729 // FullRange), then we don't know anything about the final range either.
4730 // Return FullRange.
4731 if (StartRange.isFullSet())
4732 return ConstantRange(BitWidth, /* isFullSet = */ true);
4733
4734 // If Step is signed and negative, then we use its absolute value, but we also
4735 // note that we're moving in the opposite direction.
4736 bool Descending = Signed && Step.isNegative();
4737
4738 if (Signed)
4739 // This is correct even for INT_SMIN. Let's look at i8 to illustrate this:
4740 // abs(INT_SMIN) = abs(-128) = abs(0x80) = -0x80 = 0x80 = 128.
4741 // This equations hold true due to the well-defined wrap-around behavior of
4742 // APInt.
4743 Step = Step.abs();
4744
4745 // Check if Offset is more than full span of BitWidth. If it is, the
4746 // expression is guaranteed to overflow.
4747 if (APInt::getMaxValue(StartRange.getBitWidth()).udiv(Step).ult(MaxBECount))
4748 return ConstantRange(BitWidth, /* isFullSet = */ true);
4749
4750 // Offset is by how much the expression can change. Checks above guarantee no
4751 // overflow here.
4752 APInt Offset = Step * MaxBECount;
4753
4754 // Minimum value of the final range will match the minimal value of StartRange
4755 // if the expression is increasing and will be decreased by Offset otherwise.
4756 // Maximum value of the final range will match the maximal value of StartRange
4757 // if the expression is decreasing and will be increased by Offset otherwise.
4758 APInt StartLower = StartRange.getLower();
4759 APInt StartUpper = StartRange.getUpper() - 1;
4760 APInt MovedBoundary =
4761 Descending ? (StartLower - Offset) : (StartUpper + Offset);
4762
4763 // It's possible that the new minimum/maximum value will fall into the initial
4764 // range (due to wrap around). This means that the expression can take any
4765 // value in this bitwidth, and we have to return full range.
4766 if (StartRange.contains(MovedBoundary))
4767 return ConstantRange(BitWidth, /* isFullSet = */ true);
4768
4769 APInt NewLower, NewUpper;
4770 if (Descending) {
4771 NewLower = MovedBoundary;
4772 NewUpper = StartUpper;
4773 } else {
4774 NewLower = StartLower;
4775 NewUpper = MovedBoundary;
4776 }
4777
4778 // If we end up with full range, return a proper full range.
4779 if (NewLower == NewUpper + 1)
4780 return ConstantRange(BitWidth, /* isFullSet = */ true);
4781
4782 // No overflow detected, return [StartLower, StartUpper + Offset + 1) range.
4783 return ConstantRange(NewLower, NewUpper + 1);
4784 }
4785
47154786 ConstantRange ScalarEvolution::getRangeForAffineAR(const SCEV *Start,
47164787 const SCEV *Step,
47174788 const SCEV *MaxBECount,
47204791 getTypeSizeInBits(MaxBECount->getType()) <= BitWidth &&
47214792 "Precondition!");
47224793
4723 ConstantRange Result(BitWidth, /* isFullSet = */ true);
4724
4725 // Check for overflow. This must be done with ConstantRange arithmetic
4726 // because we could be called from within the ScalarEvolution overflow
4727 // checking code.
4728
47294794 MaxBECount = getNoopOrZeroExtend(MaxBECount, Start->getType());
47304795 ConstantRange MaxBECountRange = getUnsignedRange(MaxBECount);
4731 ConstantRange ZExtMaxBECountRange = MaxBECountRange.zextOrTrunc(BitWidth * 2);
4732
4796 APInt MaxBECountValue = MaxBECountRange.getUnsignedMax();
4797
4798 // First, consider step signed.
4799 ConstantRange StartSRange = getSignedRange(Start);
47334800 ConstantRange StepSRange = getSignedRange(Step);
4734 ConstantRange SExtStepSRange = StepSRange.sextOrTrunc(BitWidth * 2);
4735
4736 ConstantRange StartURange = getUnsignedRange(Start);
4737 ConstantRange EndURange =
4738 StartURange.add(MaxBECountRange.multiply(StepSRange));
4739
4740 // Check for unsigned overflow.
4741 ConstantRange ZExtStartURange = StartURange.zextOrTrunc(BitWidth * 2);
4742 ConstantRange ZExtEndURange = EndURange.zextOrTrunc(BitWidth * 2);
4743 if (ZExtStartURange.add(ZExtMaxBECountRange.multiply(SExtStepSRange)) ==
4744 ZExtEndURange) {
4745 APInt Min = APIntOps::umin(StartURange.getUnsignedMin(),
4746 EndURange.getUnsignedMin());
4747 APInt Max = APIntOps::umax(StartURange.getUnsignedMax(),
4748 EndURange.getUnsignedMax());
4749 bool IsFullRange = Min.isMinValue() && Max.isMaxValue();
4750 if (!IsFullRange)
4751 Result =
4752 Result.intersectWith(ConstantRange(Min, Max + 1));
4753 }
4754
4755 ConstantRange StartSRange = getSignedRange(Start);
4756 ConstantRange EndSRange =
4757 StartSRange.add(MaxBECountRange.multiply(StepSRange));
4758
4759 // Check for signed overflow. This must be done with ConstantRange
4760 // arithmetic because we could be called from within the ScalarEvolution
4761 // overflow checking code.
4762 ConstantRange SExtStartSRange = StartSRange.sextOrTrunc(BitWidth * 2);
4763 ConstantRange SExtEndSRange = EndSRange.sextOrTrunc(BitWidth * 2);
4764 if (SExtStartSRange.add(ZExtMaxBECountRange.multiply(SExtStepSRange)) ==
4765 SExtEndSRange) {
4766 APInt Min =
4767 APIntOps::smin(StartSRange.getSignedMin(), EndSRange.getSignedMin());
4768 APInt Max =
4769 APIntOps::smax(StartSRange.getSignedMax(), EndSRange.getSignedMax());
4770 bool IsFullRange = Min.isMinSignedValue() && Max.isMaxSignedValue();
4771 if (!IsFullRange)
4772 Result =
4773 Result.intersectWith(ConstantRange(Min, Max + 1));
4774 }
4775
4776 return Result;
4801
4802 // If Step can be both positive and negative, we need to find ranges for the
4803 // maximum absolute step values in both directions and union them.
4804 ConstantRange SR =
4805 getRangeForAffineARHelper(StepSRange.getSignedMin(), StartSRange,
4806 MaxBECountValue, BitWidth, /* Signed = */ true);
4807 SR = SR.unionWith(getRangeForAffineARHelper(StepSRange.getSignedMax(),
4808 StartSRange, MaxBECountValue,
4809 BitWidth, /* Signed = */ true));
4810
4811 // Next, consider step unsigned.
4812 ConstantRange UR = getRangeForAffineARHelper(
4813 getUnsignedRange(Step).getUnsignedMax(), getUnsignedRange(Start),
4814 MaxBECountValue, BitWidth, /* Signed = */ false);
4815
4816 // Finally, intersect signed and unsigned ranges.
4817 return SR.intersectWith(UR);
47774818 }
47784819
47794820 ConstantRange ScalarEvolution::getRangeViaFactoring(const SCEV *Start,
55 br label %bb.i
66
77 bb.i: ; preds = %bb1.i, %bb.nph
8 ; We should be able to find the range for this expression.
9 ; CHECK: %l_95.0.i1 = phi i8
10 ; CHECK: --> {0,+,-1}<%bb.i> U: [2,1) S: [2,1){{ *}}Exits: 2
11
812 %l_95.0.i1 = phi i8 [ %tmp1, %bb.i ], [ 0, %entry ]
913
1014 ; This cast shouldn't be folded into the addrec.