Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/Vectorize/VPlanSLP.h
213799 views
//===- VPlan.h - VPlan-based SLP ------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8/// \file9/// This file contains the declarations for VPlan-based SLP.10///11//===----------------------------------------------------------------------===//1213#ifndef LLVM_TRANSFORMS_VECTORIZE_VPLANSLP_H14#define LLVM_TRANSFORMS_VECTORIZE_VPLANSLP_H1516#include "llvm/ADT/DenseMap.h"17#include "llvm/ADT/SmallPtrSet.h"18#include "llvm/ADT/SmallVector.h"19#include "llvm/Analysis/VectorUtils.h"2021namespace llvm {2223class VPBasicBlock;24class VPBlockBase;25class VPRegionBlock;26class VPlan;27class VPValue;28class VPInstruction;2930class VPInterleavedAccessInfo {31DenseMap<VPInstruction *, InterleaveGroup<VPInstruction> *>32InterleaveGroupMap;3334/// Type for mapping of instruction based interleave groups to VPInstruction35/// interleave groups36using Old2NewTy = DenseMap<InterleaveGroup<Instruction> *,37InterleaveGroup<VPInstruction> *>;3839/// Recursively \p Region and populate VPlan based interleave groups based on40/// \p IAI.41void visitRegion(VPRegionBlock *Region, Old2NewTy &Old2New,42InterleavedAccessInfo &IAI);43/// Recursively traverse \p Block and populate VPlan based interleave groups44/// based on \p IAI.45void visitBlock(VPBlockBase *Block, Old2NewTy &Old2New,46InterleavedAccessInfo &IAI);4748public:49LLVM_ABI_FOR_TEST VPInterleavedAccessInfo(VPlan &Plan,50InterleavedAccessInfo &IAI);51VPInterleavedAccessInfo(const VPInterleavedAccessInfo &) = delete;52VPInterleavedAccessInfo &operator=(const VPInterleavedAccessInfo &) = delete;5354~VPInterleavedAccessInfo() {55// Avoid releasing a pointer twice.56SmallPtrSet<InterleaveGroup<VPInstruction> *, 4> DelSet(57llvm::from_range, llvm::make_second_range(InterleaveGroupMap));58for (auto *Ptr : DelSet)59delete Ptr;60}6162/// Get the interleave group that \p Instr belongs to.63///64/// \returns nullptr if doesn't have such group.65InterleaveGroup<VPInstruction> *66getInterleaveGroup(VPInstruction *Instr) const {67return InterleaveGroupMap.lookup(Instr);68}69};7071/// Class that maps (parts of) an existing VPlan to trees of combined72/// VPInstructions.73class VPlanSlp {74enum class OpMode { Failed, Load, Opcode };7576/// Mapping of values in the original VPlan to a combined VPInstruction.77DenseMap<SmallVector<VPValue *, 4>, VPInstruction *> BundleToCombined;7879VPInterleavedAccessInfo &IAI;8081/// Basic block to operate on. For now, only instructions in a single BB are82/// considered.83const VPBasicBlock &BB;8485/// Indicates whether we managed to combine all visited instructions or not.86bool CompletelySLP = true;8788/// Width of the widest combined bundle in bits.89unsigned WidestBundleBits = 0;9091using MultiNodeOpTy =92typename std::pair<VPInstruction *, SmallVector<VPValue *, 4>>;9394// Input operand bundles for the current multi node. Each multi node operand95// bundle contains values not matching the multi node's opcode. They will96// be reordered in reorderMultiNodeOps, once we completed building a97// multi node.98SmallVector<MultiNodeOpTy, 4> MultiNodeOps;99100/// Indicates whether we are building a multi node currently.101bool MultiNodeActive = false;102103/// Check if we can vectorize Operands together.104bool areVectorizable(ArrayRef<VPValue *> Operands) const;105106/// Add combined instruction \p New for the bundle \p Operands.107void addCombined(ArrayRef<VPValue *> Operands, VPInstruction *New);108109/// Indicate we hit a bundle we failed to combine. Returns nullptr for now.110VPInstruction *markFailed();111112/// Reorder operands in the multi node to maximize sequential memory access113/// and commutative operations.114SmallVector<MultiNodeOpTy, 4> reorderMultiNodeOps();115116/// Choose the best candidate to use for the lane after \p Last. The set of117/// candidates to choose from are values with an opcode matching \p Last's118/// or loads consecutive to \p Last.119std::pair<OpMode, VPValue *> getBest(OpMode Mode, VPValue *Last,120SmallPtrSetImpl<VPValue *> &Candidates,121VPInterleavedAccessInfo &IAI);122123#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)124/// Print bundle \p Values to dbgs().125void dumpBundle(ArrayRef<VPValue *> Values);126#endif127128public:129VPlanSlp(VPInterleavedAccessInfo &IAI, VPBasicBlock &BB) : IAI(IAI), BB(BB) {}130131~VPlanSlp() = default;132133/// Tries to build an SLP tree rooted at \p Operands and returns a134/// VPInstruction combining \p Operands, if they can be combined.135LLVM_ABI_FOR_TEST VPInstruction *buildGraph(ArrayRef<VPValue *> Operands);136137/// Return the width of the widest combined bundle in bits.138unsigned getWidestBundleBits() const { return WidestBundleBits; }139140/// Return true if all visited instruction can be combined.141bool isCompletelySLP() const { return CompletelySLP; }142};143} // end namespace llvm144145#endif // LLVM_TRANSFORMS_VECTORIZE_VPLAN_H146147148