From b51b170ce4edfe4240a2222e4a7694a5aa15b723 Mon Sep 17 00:00:00 2001 From: Sanjoy Das Date: Thu, 22 Jan 2015 09:32:02 +0000 Subject: [PATCH] [NFC] Introduce a 'struct Range' for IRCE Use the struct instead of a std::pair. 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 --- .../Scalar/InductiveRangeCheckElimination.cpp | 44 ++++++++++++------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp b/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp index be62e4c745c..ea621ba6642 100644 --- a/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp +++ b/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp @@ -138,9 +138,23 @@ public: BranchInst *getBranch() const { return Branch; } - /// Represents an integer range [Range.first, Range.second). If Range.second - /// < Range.first, then the value denotes the empty range. - typedef std::pair Range; + /// Represents an signed integer range [Range.getBegin(), Range.getEnd()). If + /// R.getEnd() sle R.getBegin(), then R denotes the empty range. + + class Range { + Value *Begin; + Value *End; + + public: + Range(Value *Begin, Value *End) : Begin(Begin), End(End) { + assert(Begin->getType() == End->getType() && "ill-typed range!"); + } + + Type *getType() const { return Begin->getType(); } + Value *getBegin() const { return Begin; } + Value *getEnd() const { return End; } + }; + typedef SpecificBumpPtrAllocator AllocatorTy; /// This is the value the condition of the branch needs to evaluate to for the @@ -710,9 +724,7 @@ Optional LoopConstrainer::calculateSubRanges(Value *&HeaderCountOut) const { IntegerType *Ty = cast(LatchTakenCount->getType()); - assert(Range.first->getType() == Range.second->getType() && - "ill-typed range!"); - if (Range.first->getType() != Ty) + if (Range.getType() != Ty) return None; SCEVExpander Expander(SE, "irce"); @@ -731,8 +743,8 @@ LoopConstrainer::calculateSubRanges(Value *&HeaderCountOut) const { ConstantInt *One = ConstantInt::get(Ty, 1); HeaderCountOut = MaybeSimplify(B.CreateAdd(LatchCountV, One, "header.count")); - const SCEV *RangeBegin = SE.getSCEV(Range.first); - const SCEV *RangeEnd = SE.getSCEV(Range.second); + const SCEV *RangeBegin = SE.getSCEV(Range.getBegin()); + const SCEV *RangeEnd = SE.getSCEV(Range.getEnd()); const SCEV *HeaderCountSCEV = SE.getSCEV(HeaderCountOut); const SCEV *Zero = SE.getConstant(Ty, 0); @@ -741,12 +753,12 @@ LoopConstrainer::calculateSubRanges(Value *&HeaderCountOut) const { bool ProvablyNoPreloop = SE.isKnownPredicate(ICmpInst::ICMP_SLE, RangeBegin, Zero); if (!ProvablyNoPreloop) - Result.ExitPreLoopAt = ConstructSMinOf(HeaderCountOut, Range.first, B); + Result.ExitPreLoopAt = ConstructSMinOf(HeaderCountOut, Range.getBegin(), B); bool ProvablyNoPostLoop = SE.isKnownPredicate(ICmpInst::ICMP_SLE, HeaderCountSCEV, RangeEnd); if (!ProvablyNoPostLoop) - Result.ExitMainLoopAt = ConstructSMinOf(HeaderCountOut, Range.second, B); + Result.ExitMainLoopAt = ConstructSMinOf(HeaderCountOut, Range.getEnd(), B); return Result; } @@ -1127,26 +1139,24 @@ InductiveRangeCheck::computeSafeIterationSpace(ScalarEvolution &SE, Value *Begin = MaybeSimplify(B.CreateNeg(OffsetV)); Value *End = MaybeSimplify(B.CreateSub(getLength(), OffsetV)); - return std::make_pair(Begin, End); + return InductiveRangeCheck::Range(Begin, End); } static Optional IntersectRange(const Optional &R1, const InductiveRangeCheck::Range &R2, IRBuilder<> &B) { - assert(R2.first->getType() == R2.second->getType() && "ill-typed range!"); - if (!R1.hasValue()) return R2; auto &R1Value = R1.getValue(); // TODO: we could widen the smaller range and have this work; but for now we // bail out to keep things simple. - if (R1Value.first->getType() != R2.first->getType()) + if (R1Value.getType() != R2.getType()) return None; - Value *NewMin = ConstructSMaxOf(R1Value.first, R2.first, B); - Value *NewMax = ConstructSMinOf(R1Value.second, R2.second, B); - return std::make_pair(NewMin, NewMax); + Value *NewMin = ConstructSMaxOf(R1Value.getBegin(), R2.getBegin(), B); + Value *NewMax = ConstructSMinOf(R1Value.getEnd(), R2.getEnd(), B); + return InductiveRangeCheck::Range(NewMin, NewMax); } bool InductiveRangeCheckElimination::runOnLoop(Loop *L, LPPassManager &LPM) {