mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-19 02:25:01 +00:00
[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
This commit is contained in:
@@ -138,9 +138,23 @@ public:
|
|||||||
|
|
||||||
BranchInst *getBranch() const { return Branch; }
|
BranchInst *getBranch() const { return Branch; }
|
||||||
|
|
||||||
/// Represents an integer range [Range.first, Range.second). If Range.second
|
/// Represents an signed integer range [Range.getBegin(), Range.getEnd()). If
|
||||||
/// < Range.first, then the value denotes the empty range.
|
/// R.getEnd() sle R.getBegin(), then R denotes the empty range.
|
||||||
typedef std::pair<Value *, Value *> 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<InductiveRangeCheck> AllocatorTy;
|
typedef SpecificBumpPtrAllocator<InductiveRangeCheck> AllocatorTy;
|
||||||
|
|
||||||
/// This is the value the condition of the branch needs to evaluate to for the
|
/// This is the value the condition of the branch needs to evaluate to for the
|
||||||
@@ -710,9 +724,7 @@ Optional<LoopConstrainer::SubRanges>
|
|||||||
LoopConstrainer::calculateSubRanges(Value *&HeaderCountOut) const {
|
LoopConstrainer::calculateSubRanges(Value *&HeaderCountOut) const {
|
||||||
IntegerType *Ty = cast<IntegerType>(LatchTakenCount->getType());
|
IntegerType *Ty = cast<IntegerType>(LatchTakenCount->getType());
|
||||||
|
|
||||||
assert(Range.first->getType() == Range.second->getType() &&
|
if (Range.getType() != Ty)
|
||||||
"ill-typed range!");
|
|
||||||
if (Range.first->getType() != Ty)
|
|
||||||
return None;
|
return None;
|
||||||
|
|
||||||
SCEVExpander Expander(SE, "irce");
|
SCEVExpander Expander(SE, "irce");
|
||||||
@@ -731,8 +743,8 @@ LoopConstrainer::calculateSubRanges(Value *&HeaderCountOut) const {
|
|||||||
ConstantInt *One = ConstantInt::get(Ty, 1);
|
ConstantInt *One = ConstantInt::get(Ty, 1);
|
||||||
HeaderCountOut = MaybeSimplify(B.CreateAdd(LatchCountV, One, "header.count"));
|
HeaderCountOut = MaybeSimplify(B.CreateAdd(LatchCountV, One, "header.count"));
|
||||||
|
|
||||||
const SCEV *RangeBegin = SE.getSCEV(Range.first);
|
const SCEV *RangeBegin = SE.getSCEV(Range.getBegin());
|
||||||
const SCEV *RangeEnd = SE.getSCEV(Range.second);
|
const SCEV *RangeEnd = SE.getSCEV(Range.getEnd());
|
||||||
const SCEV *HeaderCountSCEV = SE.getSCEV(HeaderCountOut);
|
const SCEV *HeaderCountSCEV = SE.getSCEV(HeaderCountOut);
|
||||||
const SCEV *Zero = SE.getConstant(Ty, 0);
|
const SCEV *Zero = SE.getConstant(Ty, 0);
|
||||||
|
|
||||||
@@ -741,12 +753,12 @@ LoopConstrainer::calculateSubRanges(Value *&HeaderCountOut) const {
|
|||||||
bool ProvablyNoPreloop =
|
bool ProvablyNoPreloop =
|
||||||
SE.isKnownPredicate(ICmpInst::ICMP_SLE, RangeBegin, Zero);
|
SE.isKnownPredicate(ICmpInst::ICMP_SLE, RangeBegin, Zero);
|
||||||
if (!ProvablyNoPreloop)
|
if (!ProvablyNoPreloop)
|
||||||
Result.ExitPreLoopAt = ConstructSMinOf(HeaderCountOut, Range.first, B);
|
Result.ExitPreLoopAt = ConstructSMinOf(HeaderCountOut, Range.getBegin(), B);
|
||||||
|
|
||||||
bool ProvablyNoPostLoop =
|
bool ProvablyNoPostLoop =
|
||||||
SE.isKnownPredicate(ICmpInst::ICMP_SLE, HeaderCountSCEV, RangeEnd);
|
SE.isKnownPredicate(ICmpInst::ICMP_SLE, HeaderCountSCEV, RangeEnd);
|
||||||
if (!ProvablyNoPostLoop)
|
if (!ProvablyNoPostLoop)
|
||||||
Result.ExitMainLoopAt = ConstructSMinOf(HeaderCountOut, Range.second, B);
|
Result.ExitMainLoopAt = ConstructSMinOf(HeaderCountOut, Range.getEnd(), B);
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
@@ -1127,26 +1139,24 @@ InductiveRangeCheck::computeSafeIterationSpace(ScalarEvolution &SE,
|
|||||||
Value *Begin = MaybeSimplify(B.CreateNeg(OffsetV));
|
Value *Begin = MaybeSimplify(B.CreateNeg(OffsetV));
|
||||||
Value *End = MaybeSimplify(B.CreateSub(getLength(), OffsetV));
|
Value *End = MaybeSimplify(B.CreateSub(getLength(), OffsetV));
|
||||||
|
|
||||||
return std::make_pair(Begin, End);
|
return InductiveRangeCheck::Range(Begin, End);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Optional<InductiveRangeCheck::Range>
|
static Optional<InductiveRangeCheck::Range>
|
||||||
IntersectRange(const Optional<InductiveRangeCheck::Range> &R1,
|
IntersectRange(const Optional<InductiveRangeCheck::Range> &R1,
|
||||||
const InductiveRangeCheck::Range &R2, IRBuilder<> &B) {
|
const InductiveRangeCheck::Range &R2, IRBuilder<> &B) {
|
||||||
assert(R2.first->getType() == R2.second->getType() && "ill-typed range!");
|
|
||||||
|
|
||||||
if (!R1.hasValue())
|
if (!R1.hasValue())
|
||||||
return R2;
|
return R2;
|
||||||
auto &R1Value = R1.getValue();
|
auto &R1Value = R1.getValue();
|
||||||
|
|
||||||
// TODO: we could widen the smaller range and have this work; but for now we
|
// TODO: we could widen the smaller range and have this work; but for now we
|
||||||
// bail out to keep things simple.
|
// bail out to keep things simple.
|
||||||
if (R1Value.first->getType() != R2.first->getType())
|
if (R1Value.getType() != R2.getType())
|
||||||
return None;
|
return None;
|
||||||
|
|
||||||
Value *NewMin = ConstructSMaxOf(R1Value.first, R2.first, B);
|
Value *NewMin = ConstructSMaxOf(R1Value.getBegin(), R2.getBegin(), B);
|
||||||
Value *NewMax = ConstructSMinOf(R1Value.second, R2.second, B);
|
Value *NewMax = ConstructSMinOf(R1Value.getEnd(), R2.getEnd(), B);
|
||||||
return std::make_pair(NewMin, NewMax);
|
return InductiveRangeCheck::Range(NewMin, NewMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InductiveRangeCheckElimination::runOnLoop(Loop *L, LPPassManager &LPM) {
|
bool InductiveRangeCheckElimination::runOnLoop(Loop *L, LPPassManager &LPM) {
|
||||||
|
Reference in New Issue
Block a user