forked from OSchip/llvm-project
[LoopPred] Convert member function to free helper function [NFC]
llvm-svn: 362411
This commit is contained in:
parent
b8fee677bf
commit
0912b06f78
|
@ -300,19 +300,6 @@ class LoopPredication {
|
|||
// within the loop. We identify such unprofitable loops through BPI.
|
||||
bool isLoopProfitableToPredicate();
|
||||
|
||||
// When the IV type is wider than the range operand type, we can still do loop
|
||||
// predication, by generating SCEVs for the range and latch that are of the
|
||||
// same type. We achieve this by generating a SCEV truncate expression for the
|
||||
// latch IV. This is done iff truncation of the IV is a safe operation,
|
||||
// without loss of information.
|
||||
// Another way to achieve this is by generating a wider type SCEV for the
|
||||
// range check operand, however, this needs a more involved check that
|
||||
// operands do not overflow. This can lead to loss of information when the
|
||||
// range operand is of the form: add i32 %offset, %iv. We need to prove that
|
||||
// sext(x + y) is same as sext(x) + sext(y).
|
||||
// This function returns true if we can safely represent the IV type in
|
||||
// the RangeCheckType without loss of information.
|
||||
bool isSafeToTruncateWideIVType(Type *RangeCheckType);
|
||||
// Return the loopLatchCheck corresponding to the RangeCheckType if safe to do
|
||||
// so.
|
||||
Optional<LoopICmp> generateLoopLatchCheck(Type *RangeCheckType);
|
||||
|
@ -425,6 +412,52 @@ Value *LoopPredication::expandCheck(SCEVExpander &Expander,
|
|||
return Builder.CreateICmp(Pred, LHSV, RHSV);
|
||||
}
|
||||
|
||||
|
||||
// Returns true if its safe to truncate the IV to RangeCheckType.
|
||||
// When the IV type is wider than the range operand type, we can still do loop
|
||||
// predication, by generating SCEVs for the range and latch that are of the
|
||||
// same type. We achieve this by generating a SCEV truncate expression for the
|
||||
// latch IV. This is done iff truncation of the IV is a safe operation,
|
||||
// without loss of information.
|
||||
// Another way to achieve this is by generating a wider type SCEV for the
|
||||
// range check operand, however, this needs a more involved check that
|
||||
// operands do not overflow. This can lead to loss of information when the
|
||||
// range operand is of the form: add i32 %offset, %iv. We need to prove that
|
||||
// sext(x + y) is same as sext(x) + sext(y).
|
||||
// This function returns true if we can safely represent the IV type in
|
||||
// the RangeCheckType without loss of information.
|
||||
bool isSafeToTruncateWideIVType(const DataLayout &DL, ScalarEvolution &SE,
|
||||
const LoopICmp LatchCheck,
|
||||
Type *RangeCheckType) {
|
||||
if (!EnableIVTruncation)
|
||||
return false;
|
||||
assert(DL.getTypeSizeInBits(LatchCheck.IV->getType()) >
|
||||
DL.getTypeSizeInBits(RangeCheckType) &&
|
||||
"Expected latch check IV type to be larger than range check operand "
|
||||
"type!");
|
||||
// The start and end values of the IV should be known. This is to guarantee
|
||||
// that truncating the wide type will not lose information.
|
||||
auto *Limit = dyn_cast<SCEVConstant>(LatchCheck.Limit);
|
||||
auto *Start = dyn_cast<SCEVConstant>(LatchCheck.IV->getStart());
|
||||
if (!Limit || !Start)
|
||||
return false;
|
||||
// This check makes sure that the IV does not change sign during loop
|
||||
// iterations. Consider latchType = i64, LatchStart = 5, Pred = ICMP_SGE,
|
||||
// LatchEnd = 2, rangeCheckType = i32. If it's not a monotonic predicate, the
|
||||
// IV wraps around, and the truncation of the IV would lose the range of
|
||||
// iterations between 2^32 and 2^64.
|
||||
bool Increasing;
|
||||
if (!SE.isMonotonicPredicate(LatchCheck.IV, LatchCheck.Pred, Increasing))
|
||||
return false;
|
||||
// The active bits should be less than the bits in the RangeCheckType. This
|
||||
// guarantees that truncating the latch check to RangeCheckType is a safe
|
||||
// operation.
|
||||
auto RangeCheckTypeBitSize = DL.getTypeSizeInBits(RangeCheckType);
|
||||
return Start->getAPInt().getActiveBits() < RangeCheckTypeBitSize &&
|
||||
Limit->getAPInt().getActiveBits() < RangeCheckTypeBitSize;
|
||||
}
|
||||
|
||||
|
||||
Optional<LoopICmp>
|
||||
LoopPredication::generateLoopLatchCheck(Type *RangeCheckType) {
|
||||
|
||||
|
@ -434,7 +467,7 @@ LoopPredication::generateLoopLatchCheck(Type *RangeCheckType) {
|
|||
// For now, bail out if latch type is narrower than range type.
|
||||
if (DL->getTypeSizeInBits(LatchType) < DL->getTypeSizeInBits(RangeCheckType))
|
||||
return None;
|
||||
if (!isSafeToTruncateWideIVType(RangeCheckType))
|
||||
if (!isSafeToTruncateWideIVType(*DL, *SE, LatchCheck, RangeCheckType))
|
||||
return None;
|
||||
// We can now safely identify the truncated version of the IV and limit for
|
||||
// RangeCheckType.
|
||||
|
@ -873,35 +906,6 @@ Optional<LoopICmp> LoopPredication::parseLoopLatchICmp() {
|
|||
return Result;
|
||||
}
|
||||
|
||||
// Returns true if its safe to truncate the IV to RangeCheckType.
|
||||
bool LoopPredication::isSafeToTruncateWideIVType(Type *RangeCheckType) {
|
||||
if (!EnableIVTruncation)
|
||||
return false;
|
||||
assert(DL->getTypeSizeInBits(LatchCheck.IV->getType()) >
|
||||
DL->getTypeSizeInBits(RangeCheckType) &&
|
||||
"Expected latch check IV type to be larger than range check operand "
|
||||
"type!");
|
||||
// The start and end values of the IV should be known. This is to guarantee
|
||||
// that truncating the wide type will not lose information.
|
||||
auto *Limit = dyn_cast<SCEVConstant>(LatchCheck.Limit);
|
||||
auto *Start = dyn_cast<SCEVConstant>(LatchCheck.IV->getStart());
|
||||
if (!Limit || !Start)
|
||||
return false;
|
||||
// This check makes sure that the IV does not change sign during loop
|
||||
// iterations. Consider latchType = i64, LatchStart = 5, Pred = ICMP_SGE,
|
||||
// LatchEnd = 2, rangeCheckType = i32. If it's not a monotonic predicate, the
|
||||
// IV wraps around, and the truncation of the IV would lose the range of
|
||||
// iterations between 2^32 and 2^64.
|
||||
bool Increasing;
|
||||
if (!SE->isMonotonicPredicate(LatchCheck.IV, LatchCheck.Pred, Increasing))
|
||||
return false;
|
||||
// The active bits should be less than the bits in the RangeCheckType. This
|
||||
// guarantees that truncating the latch check to RangeCheckType is a safe
|
||||
// operation.
|
||||
auto RangeCheckTypeBitSize = DL->getTypeSizeInBits(RangeCheckType);
|
||||
return Start->getAPInt().getActiveBits() < RangeCheckTypeBitSize &&
|
||||
Limit->getAPInt().getActiveBits() < RangeCheckTypeBitSize;
|
||||
}
|
||||
|
||||
bool LoopPredication::isLoopProfitableToPredicate() {
|
||||
if (SkipProfitabilityChecks || !BPI)
|
||||
|
|
Loading…
Reference in New Issue