1e60b36cfSFlorian Hahn //===-- VPlanTransforms.cpp - Utility VPlan to VPlan transforms -----------===// 2e60b36cfSFlorian Hahn // 3e60b36cfSFlorian Hahn // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e60b36cfSFlorian Hahn // See https://llvm.org/LICENSE.txt for license information. 5e60b36cfSFlorian Hahn // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e60b36cfSFlorian Hahn // 7e60b36cfSFlorian Hahn //===----------------------------------------------------------------------===// 8e60b36cfSFlorian Hahn /// 9e60b36cfSFlorian Hahn /// \file 10e60b36cfSFlorian Hahn /// This file implements a set of utility VPlan to VPlan transformations. 11e60b36cfSFlorian Hahn /// 12e60b36cfSFlorian Hahn //===----------------------------------------------------------------------===// 13e60b36cfSFlorian Hahn 14e60b36cfSFlorian Hahn #include "VPlanTransforms.h" 15e60b36cfSFlorian Hahn #include "llvm/ADT/PostOrderIterator.h" 16e60b36cfSFlorian Hahn 17e60b36cfSFlorian Hahn using namespace llvm; 18e60b36cfSFlorian Hahn 19e60b36cfSFlorian Hahn void VPlanTransforms::VPInstructionsToVPRecipes( 20e60b36cfSFlorian Hahn Loop *OrigLoop, VPlanPtr &Plan, 21d0d38df0SDavid Green LoopVectorizationLegality::InductionList &Inductions, 22e60b36cfSFlorian Hahn SmallPtrSetImpl<Instruction *> &DeadInstructions) { 23e60b36cfSFlorian Hahn 24e60b36cfSFlorian Hahn auto *TopRegion = cast<VPRegionBlock>(Plan->getEntry()); 25e60b36cfSFlorian Hahn ReversePostOrderTraversal<VPBlockBase *> RPOT(TopRegion->getEntry()); 26e60b36cfSFlorian Hahn 27e60b36cfSFlorian Hahn // Condition bit VPValues get deleted during transformation to VPRecipes. 28e60b36cfSFlorian Hahn // Create new VPValues and save away as condition bits. These will be deleted 29e60b36cfSFlorian Hahn // after finalizing the vector IR basic blocks. 30e60b36cfSFlorian Hahn for (VPBlockBase *Base : RPOT) { 31e60b36cfSFlorian Hahn VPBasicBlock *VPBB = Base->getEntryBasicBlock(); 32e60b36cfSFlorian Hahn if (auto *CondBit = VPBB->getCondBit()) { 33e60b36cfSFlorian Hahn auto *NCondBit = new VPValue(CondBit->getUnderlyingValue()); 34e60b36cfSFlorian Hahn VPBB->setCondBit(NCondBit); 35e60b36cfSFlorian Hahn Plan->addCBV(NCondBit); 36e60b36cfSFlorian Hahn } 37e60b36cfSFlorian Hahn } 38e60b36cfSFlorian Hahn for (VPBlockBase *Base : RPOT) { 39e60b36cfSFlorian Hahn // Do not widen instructions in pre-header and exit blocks. 40e60b36cfSFlorian Hahn if (Base->getNumPredecessors() == 0 || Base->getNumSuccessors() == 0) 41e60b36cfSFlorian Hahn continue; 42e60b36cfSFlorian Hahn 43e60b36cfSFlorian Hahn VPBasicBlock *VPBB = Base->getEntryBasicBlock(); 44e60b36cfSFlorian Hahn // Introduce each ingredient into VPlan. 45e60b36cfSFlorian Hahn for (auto I = VPBB->begin(), E = VPBB->end(); I != E;) { 46e60b36cfSFlorian Hahn VPRecipeBase *Ingredient = &*I++; 47e60b36cfSFlorian Hahn // Can only handle VPInstructions. 48e60b36cfSFlorian Hahn VPInstruction *VPInst = cast<VPInstruction>(Ingredient); 49e60b36cfSFlorian Hahn Instruction *Inst = cast<Instruction>(VPInst->getUnderlyingValue()); 50e60b36cfSFlorian Hahn if (DeadInstructions.count(Inst)) { 51e60b36cfSFlorian Hahn Ingredient->eraseFromParent(); 52e60b36cfSFlorian Hahn continue; 53e60b36cfSFlorian Hahn } 54e60b36cfSFlorian Hahn 55e60b36cfSFlorian Hahn VPRecipeBase *NewRecipe = nullptr; 56e60b36cfSFlorian Hahn // Create VPWidenMemoryInstructionRecipe for loads and stores. 57078c8633SGil Rapaport if (LoadInst *Load = dyn_cast<LoadInst>(Inst)) 588647a72cSGil Rapaport NewRecipe = new VPWidenMemoryInstructionRecipe( 59078c8633SGil Rapaport *Load, Plan->getOrAddVPValue(getLoadStorePointerOperand(Inst)), 608647a72cSGil Rapaport nullptr /*Mask*/); 61078c8633SGil Rapaport else if (StoreInst *Store = dyn_cast<StoreInst>(Inst)) 62078c8633SGil Rapaport NewRecipe = new VPWidenMemoryInstructionRecipe( 63078c8633SGil Rapaport *Store, Plan->getOrAddVPValue(getLoadStorePointerOperand(Inst)), 64078c8633SGil Rapaport Plan->getOrAddVPValue(Store->getValueOperand()), nullptr /*Mask*/); 65e60b36cfSFlorian Hahn else if (PHINode *Phi = dyn_cast<PHINode>(Inst)) { 66d0d38df0SDavid Green InductionDescriptor II = Inductions.lookup(Phi); 67e60b36cfSFlorian Hahn if (II.getKind() == InductionDescriptor::IK_IntInduction || 68e60b36cfSFlorian Hahn II.getKind() == InductionDescriptor::IK_FpInduction) { 69e60b36cfSFlorian Hahn NewRecipe = new VPWidenIntOrFpInductionRecipe(Phi); 70e60b36cfSFlorian Hahn } else 71e60b36cfSFlorian Hahn NewRecipe = new VPWidenPHIRecipe(Phi); 72e60b36cfSFlorian Hahn } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Inst)) { 73*c0cdba72SFlorian Hahn NewRecipe = new VPWidenGEPRecipe( 74*c0cdba72SFlorian Hahn GEP, Plan->mapToVPValues(GEP->operands()), OrigLoop); 7549d00824SFlorian Hahn } else 76e8937985SFlorian Hahn NewRecipe = 77e8937985SFlorian Hahn new VPWidenRecipe(*Inst, Plan->mapToVPValues(Inst->operands())); 78e60b36cfSFlorian Hahn 79e60b36cfSFlorian Hahn NewRecipe->insertBefore(Ingredient); 80e60b36cfSFlorian Hahn Ingredient->eraseFromParent(); 81e60b36cfSFlorian Hahn } 82e60b36cfSFlorian Hahn } 83e60b36cfSFlorian Hahn } 84