diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 05b5764ffcafc..9def58811d30b 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -2821,11 +2821,8 @@ void InnerLoopVectorizer::fixNonInductionPHIs(VPTransformState &State) { PHINode *NewPhi = cast(State.get(VPPhi)); // Make sure the builder has a valid insert point. Builder.SetInsertPoint(NewPhi); - for (unsigned Idx = 0; Idx < VPPhi->getNumIncoming(); ++Idx) { - VPValue *Inc = VPPhi->getIncomingValue(Idx); - const VPBasicBlock *VPBB = VPPhi->getIncomingBlock(Idx); + for (const auto &[Inc, VPBB] : VPPhi->incoming_values_and_blocks()) NewPhi->addIncoming(State.get(Inc), State.CFG.VPBB2IRBB[VPBB]); - } } } } diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h index 16c461cd60919..c1cc641a73226 100644 --- a/llvm/lib/Transforms/Vectorize/VPlan.h +++ b/llvm/lib/Transforms/Vectorize/VPlan.h @@ -1127,6 +1127,42 @@ class VPPhiAccessors { return getAsRecipe()->getNumOperands(); } + /// Returns an interator range over the incoming values. + VPUser::const_operand_range incoming_values() const { + return make_range(getAsRecipe()->op_begin(), + getAsRecipe()->op_begin() + getNumIncoming()); + } + + using const_incoming_block_iterator = + mapped_iterator>; + using const_incoming_blocks_range = + iterator_range; + + const_incoming_block_iterator incoming_block_begin() const { + return const_incoming_block_iterator( + detail::index_iterator(0), + [this](size_t Idx) { return getIncomingBlock(Idx); }); + } + const_incoming_block_iterator incoming_block_end() const { + return const_incoming_block_iterator( + detail::index_iterator(getNumIncoming()), + [this](size_t Idx) { return getIncomingBlock(Idx); }); + } + + /// Returns an iterator range over the incoming blocks. + const_incoming_blocks_range incoming_blocks() const { + return make_range(incoming_block_begin(), incoming_block_end()); + } + + /// Returns an iterator range over pairs of incoming values and corresponding + /// incoming blocks. + detail::zippy + incoming_values_and_blocks() const { + return zip_equal(incoming_values(), incoming_blocks()); + } + #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) /// Print the recipe. void printPhiOperands(raw_ostream &O, VPSlotTracker &SlotTracker) const; @@ -2202,6 +2238,11 @@ class VPReductionPHIRecipe : public VPHeaderPHIRecipe, VPSlotTracker &SlotTracker) const override; #endif + /// Returns the number of incoming values, also number of incoming blocks. + /// Note that at the moment, VPWidenPointerInductionRecipe only has a single + /// incoming value, its start value. + unsigned getNumIncoming() const override { return 2; } + const RecurrenceDescriptor &getRecurrenceDescriptor() const { return RdxDesc; } diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp index 18229780bc4a5..b88f0eb51ef1f 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp @@ -1201,12 +1201,12 @@ void VPIRPhi::print(raw_ostream &O, const Twine &Indent, if (getNumOperands() != 0) { O << " (extra operand" << (getNumOperands() > 1 ? "s" : "") << ": "; - interleaveComma( - enumerate(operands()), O, [this, &O, &SlotTracker](auto Op) { - Op.value()->printAsOperand(O, SlotTracker); - O << " from "; - getParent()->getPredecessors()[Op.index()]->printAsOperand(O); - }); + interleaveComma(incoming_values_and_blocks(), O, + [&O, &SlotTracker](auto Op) { + std::get<0>(Op)->printAsOperand(O, SlotTracker); + O << " from "; + std::get<1>(Op)->printAsOperand(O); + }); O << ")"; } } diff --git a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp index 54cf8ac2ed04a..92665431baf0f 100644 --- a/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanVerifier.cpp @@ -220,17 +220,15 @@ bool VPlanVerifier::verifyVPBasicBlock(const VPBasicBlock *VPBB) { for (const VPUser *U : V->users()) { auto *UI = cast(U); if (auto *Phi = dyn_cast(UI)) { - for (unsigned Idx = 0; Idx != Phi->getNumIncoming(); ++Idx) { - VPValue *IncomingVPV = Phi->getIncomingValue(Idx); + for (const auto &[IncomingVPV, IncomingVPBB] : + Phi->incoming_values_and_blocks()) { if (IncomingVPV != V) continue; - const VPBasicBlock *IncomingVPBB = Phi->getIncomingBlock(Idx); if (VPDT.dominates(VPBB, IncomingVPBB)) continue; - errs() << "Incoming def at index " << Idx - << " does not dominate incoming block!\n"; + errs() << "Incoming def does not dominate incoming block!\n"; #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) VPSlotTracker Tracker(VPBB->getPlan()); IncomingVPV->getDefiningRecipe()->print(errs(), " ", Tracker); diff --git a/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp index 0cce111ccd22c..30be4c6798c2d 100644 --- a/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/VPlanVerifierTest.cpp @@ -174,9 +174,8 @@ TEST_F(VPVerifierTest, VPPhiIncomingValueDoesntDominateIncomingBlock) { " EMIT vp<%1> = phi [ vp<%2>, preheader ]", ::testing::internal::GetCapturedStderr().c_str()); #else - EXPECT_STREQ("Incoming def at index 0 does not dominate incoming block!\n", :: - testing::internal::GetCapturedStderr() - .c_str()); + EXPECT_STREQ("Incoming def at index 0 does not dominate incoming block!\n", + ::testing::internal::GetCapturedStderr().c_str()); #endif #endif }