diff options
author | Sanjoy Das | 2015-01-22 03:32:02 -0600 |
---|---|---|
committer | Sanjoy Das | 2015-01-22 03:32:02 -0600 |
commit | b51b170ce4edfe4240a2222e4a7694a5aa15b723 (patch) | |
tree | d4792ebabee2a376ec3376f99203c53f8296f8b4 | |
parent | deb2e51099a71092ef765ce0e8be40616a89f7d9 (diff) | |
download | llvm-b51b170ce4edfe4240a2222e4a7694a5aa15b723.tar.gz llvm-b51b170ce4edfe4240a2222e4a7694a5aa15b723.tar.xz llvm-b51b170ce4edfe4240a2222e4a7694a5aa15b723.zip |
[NFC] Introduce a 'struct Range' for IRCE
Use the struct instead of a std::pair<Value *, Value *>. This makes a
Range an obviously immutable object, and we can now assert that a
range is well-typed (Begin->getType() == End->getType()) on its
construction.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226804 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp b/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp index be62e4c745..ea621ba664 100644 --- a/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp +++ b/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp | |||
@@ -138,9 +138,23 @@ public: | |||
138 | 138 | ||
139 | BranchInst *getBranch() const { return Branch; } | 139 | BranchInst *getBranch() const { return Branch; } |
140 | 140 | ||
141 | /// Represents an integer range [Range.first, Range.second). If Range.second | 141 | /// Represents an signed integer range [Range.getBegin(), Range.getEnd()). If |
142 | /// < Range.first, then the value denotes the empty range. | 142 | /// R.getEnd() sle R.getBegin(), then R denotes the empty range. |
143 | typedef std::pair<Value *, Value *> Range; | 143 | |
144 | class Range { | ||
145 | Value *Begin; | ||
146 | Value *End; | ||
147 | |||
148 | public: | ||
149 | Range(Value *Begin, Value *End) : Begin(Begin), End(End) { | ||
150 | assert(Begin->getType() == End->getType() && "ill-typed range!"); | ||
151 | } | ||
152 | |||
153 | Type *getType() const { return Begin->getType(); } | ||
154 | Value *getBegin() const { return Begin; } | ||
155 | Value *getEnd() const { return End; } | ||
156 | }; | ||
157 | |||
144 | typedef SpecificBumpPtrAllocator<InductiveRangeCheck> AllocatorTy; | 158 | typedef SpecificBumpPtrAllocator<InductiveRangeCheck> AllocatorTy; |
145 | 159 | ||
146 | /// This is the value the condition of the branch needs to evaluate to for the | 160 | /// This is the value the condition of the branch needs to evaluate to for the |
@@ -710,9 +724,7 @@ Optional<LoopConstrainer::SubRanges> | |||
710 | LoopConstrainer::calculateSubRanges(Value *&HeaderCountOut) const { | 724 | LoopConstrainer::calculateSubRanges(Value *&HeaderCountOut) const { |
711 | IntegerType *Ty = cast<IntegerType>(LatchTakenCount->getType()); | 725 | IntegerType *Ty = cast<IntegerType>(LatchTakenCount->getType()); |
712 | 726 | ||
713 | assert(Range.first->getType() == Range.second->getType() && | 727 | if (Range.getType() != Ty) |
714 | "ill-typed range!"); | ||
715 | if (Range.first->getType() != Ty) | ||
716 | return None; | 728 | return None; |
717 | 729 | ||
718 | SCEVExpander Expander(SE, "irce"); | 730 | SCEVExpander Expander(SE, "irce"); |
@@ -731,8 +743,8 @@ LoopConstrainer::calculateSubRanges(Value *&HeaderCountOut) const { | |||
731 | ConstantInt *One = ConstantInt::get(Ty, 1); | 743 | ConstantInt *One = ConstantInt::get(Ty, 1); |
732 | HeaderCountOut = MaybeSimplify(B.CreateAdd(LatchCountV, One, "header.count")); | 744 | HeaderCountOut = MaybeSimplify(B.CreateAdd(LatchCountV, One, "header.count")); |
733 | 745 | ||
734 | const SCEV *RangeBegin = SE.getSCEV(Range.first); | 746 | const SCEV *RangeBegin = SE.getSCEV(Range.getBegin()); |
735 | const SCEV *RangeEnd = SE.getSCEV(Range.second); | 747 | const SCEV *RangeEnd = SE.getSCEV(Range.getEnd()); |
736 | const SCEV *HeaderCountSCEV = SE.getSCEV(HeaderCountOut); | 748 | const SCEV *HeaderCountSCEV = SE.getSCEV(HeaderCountOut); |
737 | const SCEV *Zero = SE.getConstant(Ty, 0); | 749 | const SCEV *Zero = SE.getConstant(Ty, 0); |
738 | 750 | ||
@@ -741,12 +753,12 @@ LoopConstrainer::calculateSubRanges(Value *&HeaderCountOut) const { | |||
741 | bool ProvablyNoPreloop = | 753 | bool ProvablyNoPreloop = |
742 | SE.isKnownPredicate(ICmpInst::ICMP_SLE, RangeBegin, Zero); | 754 | SE.isKnownPredicate(ICmpInst::ICMP_SLE, RangeBegin, Zero); |
743 | if (!ProvablyNoPreloop) | 755 | if (!ProvablyNoPreloop) |
744 | Result.ExitPreLoopAt = ConstructSMinOf(HeaderCountOut, Range.first, B); | 756 | Result.ExitPreLoopAt = ConstructSMinOf(HeaderCountOut, Range.getBegin(), B); |
745 | 757 | ||
746 | bool ProvablyNoPostLoop = | 758 | bool ProvablyNoPostLoop = |
747 | SE.isKnownPredicate(ICmpInst::ICMP_SLE, HeaderCountSCEV, RangeEnd); | 759 | SE.isKnownPredicate(ICmpInst::ICMP_SLE, HeaderCountSCEV, RangeEnd); |
748 | if (!ProvablyNoPostLoop) | 760 | if (!ProvablyNoPostLoop) |
749 | Result.ExitMainLoopAt = ConstructSMinOf(HeaderCountOut, Range.second, B); | 761 | Result.ExitMainLoopAt = ConstructSMinOf(HeaderCountOut, Range.getEnd(), B); |
750 | 762 | ||
751 | return Result; | 763 | return Result; |
752 | } | 764 | } |
@@ -1127,26 +1139,24 @@ InductiveRangeCheck::computeSafeIterationSpace(ScalarEvolution &SE, | |||
1127 | Value *Begin = MaybeSimplify(B.CreateNeg(OffsetV)); | 1139 | Value *Begin = MaybeSimplify(B.CreateNeg(OffsetV)); |
1128 | Value *End = MaybeSimplify(B.CreateSub(getLength(), OffsetV)); | 1140 | Value *End = MaybeSimplify(B.CreateSub(getLength(), OffsetV)); |
1129 | 1141 | ||
1130 | return std::make_pair(Begin, End); | 1142 | return InductiveRangeCheck::Range(Begin, End); |
1131 | } | 1143 | } |
1132 | 1144 | ||
1133 | static Optional<InductiveRangeCheck::Range> | 1145 | static Optional<InductiveRangeCheck::Range> |
1134 | IntersectRange(const Optional<InductiveRangeCheck::Range> &R1, | 1146 | IntersectRange(const Optional<InductiveRangeCheck::Range> &R1, |
1135 | const InductiveRangeCheck::Range &R2, IRBuilder<> &B) { | 1147 | const InductiveRangeCheck::Range &R2, IRBuilder<> &B) { |
1136 | assert(R2.first->getType() == R2.second->getType() && "ill-typed range!"); | ||
1137 | |||
1138 | if (!R1.hasValue()) | 1148 | if (!R1.hasValue()) |
1139 | return R2; | 1149 | return R2; |
1140 | auto &R1Value = R1.getValue(); | 1150 | auto &R1Value = R1.getValue(); |
1141 | 1151 | ||
1142 | // TODO: we could widen the smaller range and have this work; but for now we | 1152 | // TODO: we could widen the smaller range and have this work; but for now we |
1143 | // bail out to keep things simple. | 1153 | // bail out to keep things simple. |
1144 | if (R1Value.first->getType() != R2.first->getType()) | 1154 | if (R1Value.getType() != R2.getType()) |
1145 | return None; | 1155 | return None; |
1146 | 1156 | ||
1147 | Value *NewMin = ConstructSMaxOf(R1Value.first, R2.first, B); | 1157 | Value *NewMin = ConstructSMaxOf(R1Value.getBegin(), R2.getBegin(), B); |
1148 | Value *NewMax = ConstructSMinOf(R1Value.second, R2.second, B); | 1158 | Value *NewMax = ConstructSMinOf(R1Value.getEnd(), R2.getEnd(), B); |
1149 | return std::make_pair(NewMin, NewMax); | 1159 | return InductiveRangeCheck::Range(NewMin, NewMax); |
1150 | } | 1160 | } |
1151 | 1161 | ||
1152 | bool InductiveRangeCheckElimination::runOnLoop(Loop *L, LPPassManager &LPM) { | 1162 | bool InductiveRangeCheckElimination::runOnLoop(Loop *L, LPPassManager &LPM) { |