Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 15 additions & 27 deletions llvm/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h
Original file line number Diff line number Diff line change
Expand Up @@ -391,25 +391,22 @@ class LoopVectorizationLegality {

/// Returns true if the loop has an uncountable early exit, i.e. an
/// uncountable exit that isn't the latch block.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be good to clarify there must be single edge

Suggested change
/// Returns true if the loop has an uncountable early exit, i.e. an
/// uncountable exit that isn't the latch block.
/// Returns true if the loop has exactly one uncountable early exit, i.e. an
/// uncountable exit that isn't the latch block.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

bool hasUncountableEarlyExit() const { return HasUncountableEarlyExit; }
bool hasUncountableEarlyExit() const {
return getUncountableEdge().has_value();
}

/// Returns the uncountable early exiting block.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Returns the uncountable early exiting block.
/// Returns the uncountable early exiting block, if there is a single one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

BasicBlock *getUncountableEarlyExitingBlock() const {
if (!HasUncountableEarlyExit) {
assert(getUncountableExitingBlocks().empty() &&
"Expected no uncountable exiting blocks");
if (!hasUncountableEarlyExit())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: may be more compact

Suggested change
if (!hasUncountableEarlyExit())
return hasUncountableEarlyExit() ? getUncountableEdge()->first : nullptr;`

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

return nullptr;
}
assert(getUncountableExitingBlocks().size() == 1 &&
"Expected only a single uncountable exiting block");
return getUncountableExitingBlocks()[0];
return (*getUncountableEdge()).first;
}

/// Returns the destination of an uncountable early exiting block.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Returns the destination of an uncountable early exiting block.
/// Returns the destination of the uncountable early exiting block, there is a single one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

BasicBlock *getUncountableEarlyExitBlock() const {
assert(getUncountableExitBlocks().size() == 1 &&
"Expected only a single uncountable exit block");
return getUncountableExitBlocks()[0];
if (!hasUncountableEarlyExit())
return nullptr;
return (*getUncountableEdge()).second;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this and other places just use ->?

Suggested change
return (*getUncountableEdge()).second;
return getUncountableEdge()->second;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}

/// Returns true if vector representation of the instruction \p I
Expand Down Expand Up @@ -463,14 +460,10 @@ class LoopVectorizationLegality {
return CountableExitingBlocks;
}

/// Returns all the exiting blocks with an uncountable exit.
const SmallVector<BasicBlock *, 4> &getUncountableExitingBlocks() const {
return UncountableExitingBlocks;
}

/// Returns all the exit blocks from uncountable exiting blocks.
SmallVector<BasicBlock *, 4> getUncountableExitBlocks() const {
return UncountableExitBlocks;
/// Returns the loop edge with an uncountable exit.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to cover also the empty case, perhaps something like

Suggested change
/// Returns the loop edge with an uncountable exit.
/// Returns the loop edge with an uncountable exit or std::nullopt if there isn't a single such edge.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

std::optional<std::pair<BasicBlock *, BasicBlock *>>
getUncountableEdge() const {
return UncountableEdge;
}

private:
Expand Down Expand Up @@ -654,18 +647,13 @@ class LoopVectorizationLegality {
/// supported.
bool StructVecCallFound = false;

/// Indicates whether this loop has an uncountable early exit, i.e. an
/// uncountable exiting block that is not the latch.
bool HasUncountableEarlyExit = false;

/// Keep track of all the countable and uncountable exiting blocks if
/// the exact backedge taken count is not computable.
SmallVector<BasicBlock *, 4> CountableExitingBlocks;
SmallVector<BasicBlock *, 4> UncountableExitingBlocks;

/// Keep track of the destinations of all uncountable exits if the
/// exact backedge taken count is not computable.
SmallVector<BasicBlock *, 4> UncountableExitBlocks;
/// Keep track of the loop edge with an uncountable exit, comprising a pair
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Keep track of the loop edge with an uncountable exit, comprising a pair
/// Keep track of the loop edge to an uncountable exit, comprising a pair

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

/// of (Exiting, Exit) blocks.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// of (Exiting, Exit) blocks.
/// of (Exiting, Exit) blocks, if there is exactly one early exit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

std::optional<std::pair<BasicBlock *, BasicBlock *>> UncountableEdge;
};

} // namespace llvm
Expand Down
17 changes: 7 additions & 10 deletions llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1631,12 +1631,11 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {

// Keep a record of all the exiting blocks.
SmallVector<const SCEVPredicate *, 4> Predicates;
SmallVector<std::pair<BasicBlock *, BasicBlock *>, 4> UncountableEdges;
for (BasicBlock *BB : ExitingBlocks) {
const SCEV *EC =
PSE.getSE()->getPredicatedExitCount(TheLoop, BB, &Predicates);
if (isa<SCEVCouldNotCompute>(EC)) {
UncountableExitingBlocks.push_back(BB);

SmallVector<BasicBlock *, 2> Succs(successors(BB));
if (Succs.size() != 2) {
reportVectorizationFailure(
Expand All @@ -1653,7 +1652,7 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
assert(!TheLoop->contains(Succs[1]));
ExitBlock = Succs[1];
}
UncountableExitBlocks.push_back(ExitBlock);
UncountableEdges.push_back({BB, ExitBlock});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simpler to exit here once we hit more than one, now that we only store one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

} else
CountableExitingBlocks.push_back(BB);
}
Expand All @@ -1664,7 +1663,7 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
Predicates.clear();

// We only support one uncountable early exit.
if (getUncountableExitingBlocks().size() != 1) {
if (UncountableEdges.size() != 1) {
reportVectorizationFailure(
"Loop has too many uncountable exits",
"Cannot vectorize early exit loop with more than one early exit",
Expand All @@ -1675,7 +1674,7 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
// The only supported early exit loops so far are ones where the early
// exiting block is a unique predecessor of the latch block.
BasicBlock *LatchPredBB = LatchBB->getUniquePredecessor();
if (LatchPredBB != getUncountableEarlyExitingBlock()) {
if (LatchPredBB != UncountableEdges[0].first) {
reportVectorizationFailure("Early exit is not the latch predecessor",
"Cannot vectorize early exit loop",
"EarlyExitNotLatchPredecessor", ORE, TheLoop);
Expand Down Expand Up @@ -1728,7 +1727,7 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
}

// The vectoriser cannot handle loads that occur after the early exit block.
assert(LatchBB->getUniquePredecessor() == getUncountableEarlyExitingBlock() &&
assert(LatchBB->getUniquePredecessor() == UncountableEdges[0].first &&
"Expected latch predecessor to be the early exiting block");

// TODO: Handle loops that may fault.
Expand All @@ -1751,6 +1750,7 @@ bool LoopVectorizationLegality::isVectorizableEarlyExitLoop() {
LLVM_DEBUG(dbgs() << "LV: Found an early exit loop with symbolic max "
"backedge taken count: "
<< *SymbolicMaxBTC << '\n');
UncountableEdge = UncountableEdges[0];
return true;
}

Expand Down Expand Up @@ -1812,7 +1812,6 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
return false;
}

HasUncountableEarlyExit = false;
if (isa<SCEVCouldNotCompute>(PSE.getBackedgeTakenCount())) {
if (TheLoop->getExitingBlock()) {
reportVectorizationFailure("Cannot vectorize uncountable loop",
Expand All @@ -1822,10 +1821,8 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
else
return false;
} else {
HasUncountableEarlyExit = true;
if (!isVectorizableEarlyExitLoop()) {
UncountableExitingBlocks.clear();
HasUncountableEarlyExit = false;
UncountableEdge = std::nullopt;
if (DoExtraAnalysis)
Result = false;
else
Expand Down
Loading