@@ -9316,12 +9316,8 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) {
93169316 // Construct recipes for the instructions in the loop
93179317 // ---------------------------------------------------------------------------
93189318
9319- // Scan the body of the loop in a topological order to visit each basic block
9320- // after having visited its predecessor basic blocks.
9321- LoopBlocksDFS DFS (OrigLoop);
9322- DFS.perform (LI);
9323-
9324- VPBasicBlock *HeaderVPBB = Plan->getVectorLoopRegion ()->getEntryBasicBlock ();
9319+ VPRegionBlock *LoopRegion = Plan->getVectorLoopRegion ();
9320+ VPBasicBlock *HeaderVPBB = LoopRegion->getEntryBasicBlock ();
93259321 VPBasicBlock *VPBB = HeaderVPBB;
93269322 BasicBlock *HeaderBB = OrigLoop->getHeader ();
93279323 bool NeedsMasks =
@@ -9334,33 +9330,46 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) {
93349330 RecipeBuilder.collectScaledReductions (Range);
93359331
93369332 auto *MiddleVPBB = Plan->getMiddleBlock ();
9333+
9334+ // Scan the body of the loop in a topological order to visit each basic block
9335+ // after having visited its predecessor basic blocks.
93379336 ReversePostOrderTraversal<VPBlockShallowTraversalWrapper<VPBlockBase *>> RPOT (
9338- Plan-> getVectorLoopRegion ()-> getEntry () );
9337+ HeaderVPBB );
93399338
93409339 VPBasicBlock::iterator MBIP = MiddleVPBB->getFirstNonPhi ();
93419340 VPBlockBase *PrevVPBB = nullptr ;
93429341 for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(RPOT)) {
93439342 // Skip VPBBs not corresponding to any input IR basic blocks.
9344- if (!HCFGBuilder.getIRBBForVPB (VPBB))
9345- continue ;
9343+ if (!HCFGBuilder.getIRBBForVPB (VPBB)) {
9344+ assert (VPBB == LoopRegion->getExiting () &&
9345+ " only the latch block shouldn't have a corresponding IRBB" );
9346+ VPBlockUtils::connectBlocks (PrevVPBB, VPBB);
9347+ break ;
9348+ }
93469349
93479350 // Create mask based on the IR BB corresponding to VPBB.
93489351 // TODO: Predicate directly based on VPlan.
9352+ Builder.setInsertPoint (VPBB, VPBB->begin ());
93499353 if (VPBB == HeaderVPBB) {
93509354 Builder.setInsertPoint (VPBB, VPBB->getFirstNonPhi ());
93519355 RecipeBuilder.createHeaderMask ();
93529356 } else if (NeedsMasks) {
9353- Builder.setInsertPoint (VPBB, VPBB->begin ());
93549357 RecipeBuilder.createBlockInMask (HCFGBuilder.getIRBBForVPB (VPBB));
93559358 }
93569359
93579360 // Convert input VPInstructions to widened recipes.
9358- // TODO: Model and preserve debug intrinsics in VPlan.
93599361 for (VPRecipeBase &R : make_early_inc_range (*VPBB)) {
9360- auto *SingleDef = dyn_cast<VPSingleDefRecipe>(&R);
9361- if (!isa<VPWidenPHIRecipe>(&R) &&
9362- (!isa<VPInstruction>(SingleDef) || !SingleDef->getUnderlyingValue ()))
9362+ auto *SingleDef = cast<VPSingleDefRecipe>(&R);
9363+ // Skip recipes that do not need transforming, including canonical IV,
9364+ // wide canonical IV and VPInstructions without underlying values. The
9365+ // latter is added by masking.
9366+ if (isa<VPCanonicalIVPHIRecipe>(SingleDef) ||
9367+ isa<VPWidenCanonicalIVRecipe>(SingleDef) ||
9368+ (isa<VPInstruction>(&R) && !SingleDef->getUnderlyingValue ()))
93639369 continue ;
9370+ assert (isa<VPWidenPHIRecipe>(&R) || (isa<VPInstruction>(SingleDef) &&
9371+ SingleDef->getUnderlyingValue ()) &&
9372+ " unsupported recipe" );
93649373
93659374 if (match (&R, m_BranchOnCond (m_VPValue ())) ||
93669375 (isa<VPInstruction>(&R) &&
@@ -9390,14 +9399,12 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) {
93909399 if ((SI = dyn_cast<StoreInst>(Instr)) &&
93919400 Legal->isInvariantAddressOfReduction (SI->getPointerOperand ())) {
93929401 // Only create recipe for the final invariant store of the reduction.
9393- if (!Legal->isInvariantStoreOfReduction (SI)) {
9394- R.eraseFromParent ();
9395- continue ;
9402+ if (Legal->isInvariantStoreOfReduction (SI)) {
9403+ auto *Recipe = new VPReplicateRecipe (
9404+ SI, make_range (Operands.begin (), Operands.end ()),
9405+ true /* IsUniform */ );
9406+ Recipe->insertBefore (*MiddleVPBB, MBIP);
93969407 }
9397- auto *Recipe = new VPReplicateRecipe (
9398- SI, make_range (Operands.begin (), Operands.end ()),
9399- true /* IsUniform */ );
9400- Recipe->insertBefore (*MiddleVPBB, MBIP);
94019408 R.eraseFromParent ();
94029409 continue ;
94039410 }
@@ -9408,36 +9415,26 @@ LoopVectorizationPlanner::tryToBuildVPlanWithVPRecipes(VFRange &Range) {
94089415 Recipe = RecipeBuilder.handleReplication (Instr, Operands, Range);
94099416
94109417 RecipeBuilder.setRecipe (Instr, Recipe);
9411- if (isa<VPHeaderPHIRecipe>(Recipe)) {
9412- // VPHeaderPHIRecipes must be kept in the phi section of HeaderVPBB. In
9413- // the following cases, VPHeaderPHIRecipes may be created after non-phi
9414- // recipes and need to be moved to the phi section of HeaderVPBB:
9415- // * tail-folding (non-phi recipes computing the header mask are
9416- // introduced earlier than regular header phi recipes, and should appear
9417- // after them)
9418- // * Optimizing truncates to VPWidenIntOrFpInductionRecipe.
9419-
9418+ if (isa<VPWidenIntOrFpInductionRecipe>(Recipe) && isa<TruncInst>(Instr)) {
9419+ // Optimized a truncate truncates to VPWidenIntOrFpInductionRecipe Move
9420+ // it to the phi section in the header.
94209421 Recipe->insertBefore (*HeaderVPBB, HeaderVPBB->getFirstNonPhi ());
94219422 } else
9422- Recipe-> insertBefore (&R );
9423+ Builder. insert (Recipe );
94239424 if (Recipe->getNumDefinedValues () == 1 )
94249425 SingleDef->replaceAllUsesWith (Recipe->getVPSingleValue ());
94259426 else
9426- assert (Recipe->getNumDefinedValues () == 0 );
9427+ assert (Recipe->getNumDefinedValues () == 0 &&
9428+ " Unexpected multidef recipe" );
94279429 R.eraseFromParent ();
94289430 }
94299431
94309432 // Flatten the CFG in the loop. Masks for blocks have already been generated
94319433 // and added to recipes as needed. To do so, first disconnect VPBB from its
9432- // predecessors and successors, except the exiting block. Then connect VPBB
9433- // to the previously visited VPBB.
9434- for (auto *Succ : to_vector (VPBB->getSuccessors ())) {
9435- if (Succ == Plan->getVectorLoopRegion ()->getExiting ())
9436- continue ;
9434+ // predecessors and successors. Then connect VPBB to the previously visited
9435+ // VPBB.
9436+ for (auto *Succ : to_vector (VPBB->getSuccessors ()))
94379437 VPBlockUtils::disconnectBlocks (VPBB, Succ);
9438- }
9439- for (auto *Pred : to_vector (VPBB->getPredecessors ()))
9440- VPBlockUtils::disconnectBlocks (Pred, VPBB);
94419438 if (PrevVPBB)
94429439 VPBlockUtils::connectBlocks (PrevVPBB, VPBB);
94439440 PrevVPBB = VPBB;
0 commit comments