LLVM 24.0.0git
BundleVec.h
Go to the documentation of this file.
1//===- BundleVec.h ----------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// A vectorizer pass that forms bundles by walking the def-use chain bottom-up
10// or top-down, depending on the auxiliary pass argument.
11//
12
13#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_BUNDLEVEC_H
14#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_BUNDLEVEC_H
15
16#include "llvm/ADT/ArrayRef.h"
17#include "llvm/ADT/StringRef.h"
19#include "llvm/SandboxIR/Pass.h"
25
26namespace llvm::sandboxir {
27
28/// This is a simple bottom-up (top-down) vectorizer Region pass.
29/// It expects a "seed slice" as an input in the Region's Aux vector.
30/// The "seed slice" is a vector of instructions that can be used as a starting
31/// point for vectorization, like stores (loads) to consecutive memory
32/// addresses. Starting from the seed instructions, it recursively walks up
33/// (down) the use-def (def-use) chains, forming a bundle of instructions per
34/// operand (user) position, for as long as these bundles can be vectorized.
35/// This pass will generate vector code if it can legally vectorize the code,
36/// regardless of whether it is profitable or not. For now profitability is
37/// checked at the end of the region pass pipeline by a dedicated pass that
38/// accepts or rejects the IR transaction, depending on the cost.
39class LLVM_ABI BundleVec final : public RegionPass {
40private:
41 /// Set to true whenever the pass modifies the IR.
42 bool Change = false;
43 static constexpr StringRef TopDownArgStr = "top-down";
44 static constexpr StringRef BottomUpArgStr = "bottom-up";
45 /// Direction for vectorization, set from the mandatory aux argument.
47 /// The original instructions that are potentially dead after vectorization.
48 DenseSet<Instruction *> DeadInstrCandidates;
49 /// Maps scalars to vectors.
50 std::unique_ptr<InstrMaps> IMaps;
51 /// Counter used for force-stopping the vectorizer after this many
52 /// invocations. Used for debugging miscompiles.
53 unsigned long InvocationCnt = 0;
54
55 /// Creates and returns a vector instruction that replaces the instructions in
56 /// \p Bndl. \p Operands are the already vectorized operands.
57 Value *createVectorInstr(ArrayRef<Value *> Bndl, ArrayRef<Value *> Operands);
58 /// Erases all dead instructions from the dead instruction candidates
59 /// collected during vectorization.
60 void tryEraseDeadInstrs();
61 /// Creates a shuffle instruction that shuffles \p VecOp according to \p Mask.
62 /// \p UserBB is the block of the user bundle.
63 Value *createShuffle(Value *VecOp, const ShuffleMask &Mask,
64 BasicBlock *UserBB);
65 /// Packs all elements of \p ToPack into a vector and returns that vector. \p
66 /// UserBB is the block of the user bundle.
67 Value *createPack(ArrayRef<Value *> ToPack, BasicBlock *UserBB);
68 /// After we create vectors for groups of instructions, the original
69 /// instructions are potentially dead and may need to be removed. This
70 /// function helps collect these instructions (along with the pointer operands
71 /// for loads/stores) so that they can be cleaned up later.
72 void collectPotentiallyDeadInstrs(ArrayRef<Value *> Bndl);
73
74 /// Helper class describing how(if) to vectorize the code.
75 class ActionsVector {
76 private:
78
79 public:
80 auto begin() const { return Actions.begin(); }
81 auto end() const { return Actions.end(); }
82 void push_back(std::unique_ptr<Action> &&ActPtr) {
83 ActPtr->Idx = Actions.size();
84 Actions.push_back(std::move(ActPtr));
85 }
86 void clear() { Actions.clear(); }
87#ifndef NDEBUG
88 void print(raw_ostream &OS) const;
89 void dump() const;
90#endif // NDEBUG
91 };
92 ActionsVector Actions;
93 /// Helper counter for debugging. It counts the bundles that we attempt to
94 /// vectorize in vectorizeRec().
95 unsigned DebugBndlCnt = 0;
96
97 /// Recursively try to vectorize \p Bndl. \p UserBndl identifies the
98 /// users that this recursive call originates from.
99 Action *vectorizeRec(ArrayRef<Value *> Bndl, ArrayRef<Value *> UserBndl,
100 unsigned Depth, LegalityAnalysis &Legality);
101 /// If the values in \p Bndl have external users, then emit unpacks and
102 /// connect them to the users. \p Vec is the vectorized form of \p Bndl.
103 void emitUnpacksForExternalUses(const ArrayRef<Value *> Bndl, Value *Vec);
104 /// Generate vector instructions based on `Actions` and return the last vector
105 /// created.
106 Value *emitVectors();
107 /// Entry point for vectorization starting from \p Seeds.
108 bool tryVectorize(ArrayRef<Value *> Seeds, LegalityAnalysis &Legality);
109
110public:
111 BundleVec(StringRef AuxArg) : RegionPass("bundle-vec") {
112 if (AuxArg == BottomUpArgStr) {
114 } else if (AuxArg == TopDownArgStr) {
116 } else {
117 std::string ErrStr;
118 raw_string_ostream ErrSS(ErrStr);
119 ErrSS << "bundle-vec requires either '" << BottomUpArgStr << "' or '"
120 << TopDownArgStr << "' as its aux argument!\n";
121 reportFatalUsageError(ErrStr.c_str());
122 }
123 }
124
125 bool runOnRegion(Region &Rgn, const Analyses &A) final;
126};
127
128} // namespace llvm::sandboxir
129
130#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_BUNDLEVEC_H
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_ABI
Definition Compiler.h:215
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Implements a dense probed hash-table based set.
Definition DenseSet.h:281
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
BundleVec(StringRef AuxArg)
Definition BundleVec.h:111
Performs the legality analysis and returns a LegalityResult object.
Definition Legality.h:318
LLVM_ABI virtual LLVM_DUMP_METHOD void dump() const
RegionPass(StringRef Name)
Name can't contain any spaces or start with '-'.
Definition Pass.h:87
A SandboxIR Value has users. This is the base class.
Definition Value.h:72
BasicBlock(llvm::BasicBlock *BB, Context &SBCtx)
Definition BasicBlock.h:75
iterator end() const
Definition BasicBlock.h:89
LLVM_ABI iterator begin() const
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177