-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[VPlan] Dispatch to multiple exit blocks via middle blocks. #112138
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
245b56a
47258de
9265fb1
3831acb
e64888a
64db0ee
3259e66
0f8aedf
9212f96
5cb0851
e849195
7b98d34
c53eca6
43a8ef7
e26af8e
06c3d39
552bd91
2042a43
00dea4a
7b8866d
4d5608f
b9ee739
43d5590
cba7dce
95f4276
c3d3b39
a875249
65d0288
8d04383
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,6 +43,10 @@ AllowStridedPointerIVs("lv-strided-pointer-ivs", cl::init(false), cl::Hidden, | |
cl::desc("Enable recognition of non-constant strided " | ||
"pointer induction variables.")); | ||
|
||
static cl::opt<bool> | ||
EnableEarlyExitVectorization("enable-early-exit-vectorization", | ||
cl::init(false), cl::Hidden, cl::desc("")); | ||
|
||
namespace llvm { | ||
cl::opt<bool> | ||
HintsAllowReordering("hints-allow-reordering", cl::init(true), cl::Hidden, | ||
|
@@ -1375,6 +1379,10 @@ bool LoopVectorizationLegality::isFixedOrderRecurrence( | |
} | ||
|
||
bool LoopVectorizationLegality::blockNeedsPredication(BasicBlock *BB) const { | ||
// When vectorizing early exits, create predicates for all blocks, except the | ||
// header. | ||
if (canVectorizeEarlyExit() && BB != TheLoop->getHeader()) | ||
return true; | ||
return LoopAccessInfo::blockNeedsPredication(BB, TheLoop, DT); | ||
} | ||
|
||
|
@@ -1511,6 +1519,27 @@ bool LoopVectorizationLegality::canVectorizeWithIfConvert() { | |
return true; | ||
} | ||
|
||
bool LoopVectorizationLegality::canVectorizeEarlyExit() const { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It feels a little odd to have both There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Originally I tried to limit the scope to just support vectorizing loops with multiple countable exits, but this probably made things a bit more complicated for not too much gain. Updated to use the existing I removed the new codegen tests (only kept the VPlan version). Are there any existing tests already for which adding the flag would be sufficient now that this is using the existing checks? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you can also able enable early exit autovec with Transforms/LoopVectorize/single_early_exit.ll |
||
// Currently only allow vectorizing loops with early exits, if early-exit | ||
// vectorization is explicitly enabled and the loop has metadata to force | ||
// vectorization. | ||
if (!EnableEarlyExitVectorization) | ||
return false; | ||
|
||
SmallVector<BasicBlock *> Exiting; | ||
TheLoop->getExitingBlocks(Exiting); | ||
if (Exiting.size() == 1) | ||
return false; | ||
|
||
LoopVectorizeHints Hints(TheLoop, true, *ORE); | ||
if (Hints.getForce() == LoopVectorizeHints::FK_Undefined) | ||
return false; | ||
|
||
Function *Fn = TheLoop->getHeader()->getParent(); | ||
return Hints.allowVectorization(Fn, TheLoop, | ||
true /*VectorizeOnlyWhenForced*/); | ||
} | ||
|
||
// Helper function to canVectorizeLoopNestCFG. | ||
bool LoopVectorizationLegality::canVectorizeLoopCFG(Loop *Lp, | ||
bool UseVPlanNativePath) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1365,9 +1365,11 @@ class LoopVectorizationCostModel { | |
// If we might exit from anywhere but the latch, must run the exiting | ||
// iteration in scalar form. | ||
if (TheLoop->getExitingBlock() != TheLoop->getLoopLatch()) { | ||
LLVM_DEBUG( | ||
dbgs() << "LV: Loop requires scalar epilogue: multiple exits\n"); | ||
return true; | ||
if (!Legal->canVectorizeEarlyExit()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you can fold the conditions together into a single if statement:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. folded thanks! |
||
LLVM_DEBUG( | ||
dbgs() << "LV: Loop requires scalar epilogue: multiple exits\n"); | ||
return true; | ||
} | ||
} | ||
if (IsVectorizing && InterleaveInfo.requiresScalarEpilogue()) { | ||
LLVM_DEBUG(dbgs() << "LV: Loop requires scalar epilogue: " | ||
|
@@ -2577,7 +2579,8 @@ void InnerLoopVectorizer::createVectorLoopSkeleton(StringRef Prefix) { | |
LoopVectorPreHeader = OrigLoop->getLoopPreheader(); | ||
assert(LoopVectorPreHeader && "Invalid loop structure"); | ||
LoopExitBlock = OrigLoop->getUniqueExitBlock(); // may be nullptr | ||
assert((LoopExitBlock || Cost->requiresScalarEpilogue(VF.isVector())) && | ||
assert((LoopExitBlock || Cost->requiresScalarEpilogue(VF.isVector()) || | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can completely remove the need for the Then in #88385 I think we can replace this assert with:
because even if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good! |
||
Legal->canVectorizeEarlyExit()) && | ||
"multiple exit loop without required epilogue?"); | ||
|
||
LoopMiddleBlock = | ||
|
@@ -2761,8 +2764,6 @@ void InnerLoopVectorizer::fixupIVUsers(PHINode *OrigPhi, | |
// value (the value that feeds into the phi from the loop latch). | ||
// We allow both, but they, obviously, have different values. | ||
|
||
assert(OrigLoop->getUniqueExitBlock() && "Expected a single exit block"); | ||
|
||
DenseMap<Value *, Value *> MissingVals; | ||
|
||
// An external user of the last iteration's value should see the value that | ||
|
@@ -2822,6 +2823,9 @@ void InnerLoopVectorizer::fixupIVUsers(PHINode *OrigPhi, | |
if (PHI->getBasicBlockIndex(MiddleBlock) == -1) | ||
PHI->addIncoming(I.second, MiddleBlock); | ||
} | ||
|
||
assert((MissingVals.empty() || OrigLoop->getUniqueExitBlock()) && | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps the assert would be more accurate with the statement Also, might be worth moving the assert to before the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated, thanks! |
||
"Expected a single exit block"); | ||
} | ||
|
||
namespace { | ||
|
@@ -3596,7 +3600,8 @@ void LoopVectorizationCostModel::collectLoopUniforms(ElementCount VF) { | |
TheLoop->getExitingBlocks(Exiting); | ||
for (BasicBlock *E : Exiting) { | ||
auto *Cmp = dyn_cast<Instruction>(E->getTerminator()->getOperand(0)); | ||
if (Cmp && TheLoop->contains(Cmp) && Cmp->hasOneUse()) | ||
if (Cmp && TheLoop->contains(Cmp) && Cmp->hasOneUse() && | ||
(TheLoop->getLoopLatch() == E || !Legal->canVectorizeEarlyExit())) | ||
AddToWorklistIfAllowed(Cmp); | ||
} | ||
|
||
|
@@ -7735,6 +7740,7 @@ DenseMap<const SCEV *, Value *> LoopVectorizationPlanner::executePlan( | |
LoopVectorizeHints Hints(L, true, *ORE); | ||
Hints.setAlreadyVectorized(); | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: stray white space There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed, thanks! |
||
TargetTransformInfo::UnrollingPreferences UP; | ||
TTI.getUnrollingPreferences(L, *PSE.getSE(), UP, ORE); | ||
if (!UP.UnrollVectorizedLoop || CanonicalIVStartValue) | ||
|
@@ -7747,15 +7753,17 @@ DenseMap<const SCEV *, Value *> LoopVectorizationPlanner::executePlan( | |
ILV.printDebugTracesAtEnd(); | ||
|
||
// 4. Adjust branch weight of the branch in the middle block. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... "if the latter exists"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated, thanks! |
||
auto *MiddleTerm = | ||
cast<BranchInst>(State.CFG.VPBB2IRBB[ExitVPBB]->getTerminator()); | ||
if (MiddleTerm->isConditional() && | ||
hasBranchWeightMD(*OrigLoop->getLoopLatch()->getTerminator())) { | ||
// Assume that `Count % VectorTripCount` is equally distributed. | ||
unsigned TripCount = BestVPlan.getUF() * State.VF.getKnownMinValue(); | ||
assert(TripCount > 0 && "trip count should not be zero"); | ||
const uint32_t Weights[] = {1, TripCount - 1}; | ||
setBranchWeights(*MiddleTerm, Weights, /*IsExpected=*/false); | ||
if (ExitVPBB) { | ||
auto *MiddleTerm = | ||
cast<BranchInst>(State.CFG.VPBB2IRBB[ExitVPBB]->getTerminator()); | ||
if (MiddleTerm->isConditional() && | ||
hasBranchWeightMD(*OrigLoop->getLoopLatch()->getTerminator())) { | ||
// Assume that `Count % VectorTripCount` is equally distributed. | ||
unsigned TripCount = BestVPlan.getUF() * State.VF.getKnownMinValue(); | ||
assert(TripCount > 0 && "trip count should not be zero"); | ||
const uint32_t Weights[] = {1, TripCount - 1}; | ||
setBranchWeights(*MiddleTerm, Weights, /*IsExpected=*/false); | ||
} | ||
} | ||
|
||
return State.ExpandedSCEVs; | ||
|
@@ -8140,7 +8148,7 @@ VPValue *VPRecipeBuilder::createEdgeMask(BasicBlock *Src, BasicBlock *Dst) { | |
// If source is an exiting block, we know the exit edge is dynamically dead | ||
// in the vector loop, and thus we don't need to restrict the mask. Avoid | ||
// adding uses of an otherwise potentially dead instruction. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Update comment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated, thanks! |
||
if (OrigLoop->isLoopExiting(Src)) | ||
if (!Legal->canVectorizeEarlyExit() && OrigLoop->isLoopExiting(Src)) | ||
return EdgeMaskCache[Edge] = SrcMask; | ||
|
||
VPValue *EdgeMask = getVPValueOrAddLiveIn(BI->getCondition()); | ||
|
@@ -9164,11 +9172,17 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) { | |
"VPBasicBlock"); | ||
RecipeBuilder.fixHeaderPhis(); | ||
|
||
addScalarResumePhis(RecipeBuilder, *Plan); | ||
SetVector<VPIRInstruction *> ExitUsersToFix = collectUsersInExitBlock( | ||
OrigLoop, RecipeBuilder, *Plan, Legal->getInductionVars()); | ||
addExitUsersForFirstOrderRecurrences(*Plan, ExitUsersToFix); | ||
addUsersInExitBlock(*Plan, ExitUsersToFix); | ||
if (Legal->canVectorizeEarlyExit()) { | ||
VPlanTransforms::convertToMultiCond(*Plan, *PSE.getSE(), OrigLoop, | ||
RecipeBuilder); | ||
} else { | ||
addScalarResumePhis(RecipeBuilder, *Plan); | ||
SetVector<VPIRInstruction *> ExitUsersToFix = collectUsersInExitBlock( | ||
OrigLoop, RecipeBuilder, *Plan, Legal->getInductionVars()); | ||
addExitUsersForFirstOrderRecurrences(*Plan, ExitUsersToFix); | ||
addUsersInExitBlock(*Plan, ExitUsersToFix); | ||
} | ||
|
||
// --------------------------------------------------------------------------- | ||
// Transform initial VPlan: Apply previously taken decisions, in order, to | ||
// bring the VPlan to its final state. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -924,8 +924,15 @@ VPlanPtr VPlan::createInitialVPlan(Type *InductionTy, | |
// we unconditionally branch to the scalar preheader. Do nothing. | ||
// 3) Otherwise, construct a runtime check. | ||
BasicBlock *IRExitBlock = TheLoop->getUniqueExitBlock(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you should just be able to do
here and remove the logic below. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done, thanks! |
||
if (!IRExitBlock) { | ||
auto *Term = cast<BranchInst>(TheLoop->getLoopLatch()->getTerminator()); | ||
IRExitBlock = TheLoop->contains(Term->getSuccessor(0)) | ||
? Term->getSuccessor(1) | ||
: Term->getSuccessor(0); | ||
} | ||
auto *VPExitBlock = VPIRBasicBlock::fromBasicBlock(IRExitBlock); | ||
// The connection order corresponds to the operands of the conditional branch. | ||
// The connection order corresponds to the operands of the conditional | ||
// branch. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: unrelated. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Undone, thanks |
||
VPBlockUtils::insertBlockAfter(VPExitBlock, MiddleVPBB); | ||
VPBlockUtils::connectBlocks(MiddleVPBB, ScalarPH); | ||
|
||
|
@@ -1050,7 +1057,10 @@ void VPlan::execute(VPTransformState *State) { | |
{{DominatorTree::Delete, ScalarPh, ScalarPh->getSingleSuccessor()}}); | ||
|
||
// Generate code in the loop pre-header and body. | ||
for (VPBlockBase *Block : vp_depth_first_shallow(Entry)) | ||
ReversePostOrderTraversal<VPBlockShallowTraversalWrapper<VPBlockBase *>> RPOT( | ||
Entry); | ||
|
||
for (VPBlockBase *Block : RPOT) | ||
Block->execute(State); | ||
|
||
VPBasicBlock *LatchVPBB = getVectorLoopRegion()->getExitingBasicBlock(); | ||
|
@@ -1082,7 +1092,10 @@ void VPlan::execute(VPTransformState *State) { | |
// Move the last step to the end of the latch block. This ensures | ||
// consistent placement of all induction updates. | ||
Instruction *Inc = cast<Instruction>(Phi->getIncomingValue(1)); | ||
Inc->moveBefore(VectorLatchBB->getTerminator()->getPrevNode()); | ||
if (VectorLatchBB->getTerminator() == &*VectorLatchBB->getFirstNonPHI()) | ||
Inc->moveBefore(VectorLatchBB->getTerminator()); | ||
else | ||
Inc->moveBefore(VectorLatchBB->getTerminator()->getPrevNode()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Worth extending the comment? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The change is not needed in the latest version, restored the original code. |
||
|
||
// Use the steps for the last part as backedge value for the induction. | ||
if (auto *IV = dyn_cast<VPWidenIntOrFpInductionRecipe>(&R)) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1230,6 +1230,7 @@ class VPInstruction : public VPRecipeWithIRFlags, | |
// operand). Only generates scalar values (either for the first lane only or | ||
// for all lanes, depending on its uses). | ||
PtrAdd, | ||
AnyOf, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps worth adding a simple comment here? Something along the lines of:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added, thanks There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some explanation how AnyOf relates (or should relate) to ComputeReductionResult? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think AnyOf also needs adding to the switch statement in VPRecipeBase::mayWriteToMemory and return false? |
||
}; | ||
|
||
private: | ||
|
@@ -3821,10 +3822,10 @@ class VPlan { | |
/// whether to execute the scalar tail loop or the exit block from the loop | ||
/// latch. | ||
const VPBasicBlock *getMiddleBlock() const { | ||
return cast<VPBasicBlock>(getVectorLoopRegion()->getSingleSuccessor()); | ||
return cast<VPBasicBlock>(getScalarPreheader()->getSinglePredecessor()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This restricts to use of getMiddleBlock() to before bypassing guards are introduced? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it doesn't really restrict the use of getMiddleBlock, it just updates the anchor point we use to identify it; the scalar preheader (and single predecessor ) can be more easily identified and works automatically with the changes to the skeleton. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Works as long as the scalar preheader has a single predecessor, i.e., until runtime guards are introduced as additional predecessors. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, this will need some extra work for #114292, which I plan to land after this PR. |
||
} | ||
VPBasicBlock *getMiddleBlock() { | ||
return cast<VPBasicBlock>(getVectorLoopRegion()->getSingleSuccessor()); | ||
return cast<VPBasicBlock>(getScalarPreheader()->getSinglePredecessor()); | ||
} | ||
|
||
/// The trip count of the original loop. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -68,6 +68,8 @@ bool VPRecipeBase::mayWriteToMemory() const { | |
default: | ||
return true; | ||
} | ||
case VPExpandSCEVSC: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it necessary to add the VPExpandSCEVSC here and below for this patch? In b27a332#diff-6d0b73adfa9f8465923d2225ab6674ddcdeab71666f7a73dfaec7fa1246b3a1fL929 I managed to remove this and nothing broke. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not needed in the latest version, removed, thanks |
||
return getParent()->getPlan()->getTripCount() == getVPSingleValue(); | ||
case VPInterleaveSC: | ||
return cast<VPInterleaveRecipe>(this)->getNumStoreOperands() > 0; | ||
case VPWidenStoreEVLSC: | ||
|
@@ -163,6 +165,8 @@ bool VPRecipeBase::mayHaveSideEffects() const { | |
case VPScalarCastSC: | ||
case VPReverseVectorPointerSC: | ||
return false; | ||
case VPExpandSCEVSC: | ||
return getParent()->getPlan()->getTripCount() == getVPSingleValue(); | ||
case VPInstructionSC: | ||
return mayWriteToMemory(); | ||
case VPWidenCallSC: { | ||
|
@@ -361,6 +365,7 @@ bool VPInstruction::canGenerateScalarForFirstLane() const { | |
case VPInstruction::CanonicalIVIncrementForPart: | ||
case VPInstruction::PtrAdd: | ||
case VPInstruction::ExplicitVectorLength: | ||
case VPInstruction::AnyOf: | ||
return true; | ||
default: | ||
return false; | ||
|
@@ -636,6 +641,10 @@ Value *VPInstruction::generate(VPTransformState &State) { | |
} | ||
return NewPhi; | ||
} | ||
case VPInstruction::AnyOf: { | ||
Value *A = State.get(getOperand(0)); | ||
return Builder.CreateOrReduce(A); | ||
} | ||
|
||
default: | ||
llvm_unreachable("Unsupported opcode for instruction"); | ||
|
@@ -644,7 +653,8 @@ Value *VPInstruction::generate(VPTransformState &State) { | |
|
||
bool VPInstruction::isVectorToScalar() const { | ||
return getOpcode() == VPInstruction::ExtractFromEnd || | ||
getOpcode() == VPInstruction::ComputeReductionResult; | ||
getOpcode() == VPInstruction::ComputeReductionResult || | ||
getOpcode() == VPInstruction::AnyOf; | ||
} | ||
|
||
bool VPInstruction::isSingleScalar() const { | ||
|
@@ -707,6 +717,7 @@ bool VPInstruction::onlyFirstLaneUsed(const VPValue *Op) const { | |
return false; | ||
case Instruction::ICmp: | ||
case Instruction::Select: | ||
case Instruction::Or: | ||
case VPInstruction::PtrAdd: | ||
// TODO: Cover additional opcodes. | ||
return vputils::onlyFirstLaneUsed(this); | ||
|
@@ -802,6 +813,9 @@ void VPInstruction::print(raw_ostream &O, const Twine &Indent, | |
case VPInstruction::PtrAdd: | ||
O << "ptradd"; | ||
break; | ||
case VPInstruction::AnyOf: | ||
O << "any-of"; | ||
break; | ||
default: | ||
O << Instruction::getOpcodeName(getOpcode()); | ||
} | ||
|
@@ -819,12 +833,13 @@ void VPInstruction::print(raw_ostream &O, const Twine &Indent, | |
void VPIRInstruction::execute(VPTransformState &State) { | ||
assert((isa<PHINode>(&I) || getNumOperands() == 0) && | ||
"Only PHINodes can have extra operands"); | ||
if (getNumOperands() == 1) { | ||
VPValue *ExitValue = getOperand(0); | ||
for (const auto &[Idx, Op] : enumerate(operands())) { | ||
VPValue *ExitValue = Op; | ||
auto Lane = vputils::isUniformAfterVectorization(ExitValue) | ||
? VPLane::getFirstLane() | ||
: VPLane::getLastLaneForVF(State.VF); | ||
auto *PredVPBB = cast<VPBasicBlock>(getParent()->getSinglePredecessor()); | ||
VPBlockBase *Pred = getParent()->getPredecessors()[Idx]; | ||
auto *PredVPBB = Pred->getExitingBasicBlock(); | ||
BasicBlock *PredBB = State.CFG.VPBB2IRBB[PredVPBB]; | ||
// Set insertion point in PredBB in case an extract needs to be generated. | ||
// TODO: Model extracts explicitly. | ||
|
@@ -857,7 +872,7 @@ void VPIRInstruction::print(raw_ostream &O, const Twine &Indent, | |
O << Indent << "IR " << I; | ||
|
||
if (getNumOperands() != 0) { | ||
assert(getNumOperands() == 1 && "can have at most 1 operand"); | ||
// assert(getNumOperands() == 1 && "can have at most 1 operand"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: commented code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed, thanks! |
||
O << " (extra operand: "; | ||
printOperands(O, SlotTracker); | ||
O << ")"; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need a description here, such as what I had in https://github.com/llvm/llvm-project/pull/88385/files for the same flag? Or is the idea to try to not expose this too much at this stage?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to move it to LoopVectorize.cpp, thanks. Originally this was only used in combination with the new helper introduced to LVL, but that changed after using the existing checks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, the flag still seems to be in the old place. Perhaps the patch hasn't updated correctly?