diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -10609,8 +10609,7 @@ if (auto *ReductionPhi = dyn_cast(&R)) { if (auto *Resume = MainILV.getReductionResumeValue( ReductionPhi->getRecurrenceDescriptor())) { - VPValue *StartVal = new VPValue(Resume); - BestEpiPlan.addExternalDef(StartVal); + VPValue *StartVal = BestEpiPlan.getOrAddExternalDef(Resume); ReductionPhi->setOperand(0, StartVal); } } diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h --- a/llvm/lib/Transforms/Vectorize/VPlan.h +++ b/llvm/lib/Transforms/Vectorize/VPlan.h @@ -2465,12 +2465,9 @@ /// Holds the name of the VPlan, for printing. std::string Name; - /// Holds all the external definitions created for this VPlan. - // TODO: Introduce a specific representation for external definitions in - // VPlan. External definitions must be immutable and hold a pointer to its - // underlying IR that will be used to implement its structural comparison - // (operators '==' and '<'). - SetVector VPExternalDefs; + /// Holds all the external definitions created for this VPlan. External + /// definitions must be immutable and hold a pointer to their underlying IR. + DenseMap VPExternalDefs; /// Represents the trip count of the original loop, for folding /// the tail. @@ -2518,8 +2515,8 @@ delete TripCount; if (BackedgeTakenCount) delete BackedgeTakenCount; - for (VPValue *Def : VPExternalDefs) - delete Def; + for (auto &P : VPExternalDefs) + delete P.second; } /// Prepare the plan for execution, setting up the required live-in values. @@ -2567,9 +2564,13 @@ void setName(const Twine &newName) { Name = newName.str(); } - /// Add \p VPVal to the pool of external definitions if it's not already - /// in the pool. - void addExternalDef(VPValue *VPVal) { VPExternalDefs.insert(VPVal); } + /// Get the existing or add a new external definition for \p V. + VPValue *getOrAddExternalDef(Value *V) { + auto I = VPExternalDefs.insert({V, nullptr}); + if (I.second) + I.first->second = new VPValue(V); + return I.first->second; + } void addVPValue(Value *V) { assert(Value2VPValueEnabled && diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp --- a/llvm/lib/Transforms/Vectorize/VPlan.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp @@ -914,8 +914,7 @@ // When vectorizing the epilogue loop, the canonical induction start value // needs to be changed from zero to the value after the main vector loop. if (CanonicalIVStartValue) { - VPValue *VPV = new VPValue(CanonicalIVStartValue); - addExternalDef(VPV); + VPValue *VPV = getOrAddExternalDef(CanonicalIVStartValue); auto *IV = getCanonicalIV(); assert(all_of(IV->users(), [](const VPUser *U) { @@ -1727,8 +1726,8 @@ void VPSlotTracker::assignSlots(const VPlan &Plan) { - for (const VPValue *V : Plan.VPExternalDefs) - assignSlot(V); + for (const auto &P : Plan.VPExternalDefs) + assignSlot(P.second); assignSlot(&Plan.VectorTripCount); if (Plan.BackedgeTakenCount) diff --git a/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp b/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp --- a/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanHCFGBuilder.cpp @@ -182,8 +182,7 @@ // A and B: Create VPValue and add it to the pool of external definitions and // to the Value->VPValue map. - VPValue *NewVPVal = new VPValue(IRVal); - Plan.addExternalDef(NewVPVal); + VPValue *NewVPVal = Plan.getOrAddExternalDef(IRVal); IRDef2VPValue[IRVal] = NewVPVal; return NewVPVal; } @@ -258,9 +257,7 @@ for (auto &I : *PreheaderBB) { if (I.getType()->isVoidTy()) continue; - VPValue *VPV = new VPValue(&I); - Plan.addExternalDef(VPV); - IRDef2VPValue[&I] = VPV; + IRDef2VPValue[&I] = Plan.getOrAddExternalDef(&I); } // Create empty VPBB for Loop H so that we can link PH->H. VPBlockBase *HeaderVPBB = getOrCreateVPBB(TheLoop->getHeader()); diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp --- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp +++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp @@ -422,11 +422,9 @@ const SCEV *StepSCEV = ID.getStep(); VPValue *Step = nullptr; if (auto *E = dyn_cast(StepSCEV)) { - Step = new VPValue(E->getValue()); - Plan.addExternalDef(Step); + Step = Plan.getOrAddExternalDef(E->getValue()); } else if (auto *E = dyn_cast(StepSCEV)) { - Step = new VPValue(E->getValue()); - Plan.addExternalDef(Step); + Step = Plan.getOrAddExternalDef(E->getValue()); } else { Step = new VPExpandSCEVRecipe(StepSCEV, SE); } diff --git a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp --- a/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/VPlanTest.cpp @@ -1097,10 +1097,8 @@ BinaryOperator::CreateAdd(UndefValue::get(Int32), UndefValue::get(Int32)); AI->setName("a"); SmallVector Args; - VPValue *ExtVPV1 = new VPValue(); - VPValue *ExtVPV2 = new VPValue(); - Plan.addExternalDef(ExtVPV1); - Plan.addExternalDef(ExtVPV2); + VPValue *ExtVPV1 = Plan.getOrAddExternalDef(ConstantInt::get(Int32, 1)); + VPValue *ExtVPV2 = Plan.getOrAddExternalDef(ConstantInt::get(Int32, 2)); Args.push_back(ExtVPV1); Args.push_back(ExtVPV2); VPWidenRecipe *WidenR = @@ -1117,7 +1115,7 @@ VPV->dump(); exit(0); }, - testing::ExitedWithCode(0), "WIDEN ir<%a> = add vp<%0>, vp<%1>"); + testing::ExitedWithCode(0), "WIDEN ir<%a> = add ir<1>, ir<2>"); // Test VPRecipeBase::dump(). VPRecipeBase *R = WidenR; @@ -1126,7 +1124,7 @@ R->dump(); exit(0); }, - testing::ExitedWithCode(0), "WIDEN ir<%a> = add vp<%0>, vp<%1>"); + testing::ExitedWithCode(0), "WIDEN ir<%a> = add ir<1>, ir<2>"); // Test VPDef::dump(). VPDef *D = WidenR; @@ -1135,7 +1133,7 @@ D->dump(); exit(0); }, - testing::ExitedWithCode(0), "WIDEN ir<%a> = add vp<%0>, vp<%1>"); + testing::ExitedWithCode(0), "WIDEN ir<%a> = add ir<1>, ir<2>"); } delete AI;