aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanjoy Das2015-01-22 03:32:02 -0600
committerSanjoy Das2015-01-22 03:32:02 -0600
commitb51b170ce4edfe4240a2222e4a7694a5aa15b723 (patch)
treed4792ebabee2a376ec3376f99203c53f8296f8b4
parentdeb2e51099a71092ef765ce0e8be40616a89f7d9 (diff)
downloadllvm-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.cpp44
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>
710LoopConstrainer::calculateSubRanges(Value *&HeaderCountOut) const { 724LoopConstrainer::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
1133static Optional<InductiveRangeCheck::Range> 1145static Optional<InductiveRangeCheck::Range>
1134IntersectRange(const Optional<InductiveRangeCheck::Range> &R1, 1146IntersectRange(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
1152bool InductiveRangeCheckElimination::runOnLoop(Loop *L, LPPassManager &LPM) { 1162bool InductiveRangeCheckElimination::runOnLoop(Loop *L, LPPassManager &LPM) {