Skip to content

Commit

Permalink
Scalarizer: limit scalarization for small element types
Browse files Browse the repository at this point in the history
Scalarization can expose optimization opportunities for the individual
elements of a vector, and can therefore be beneficial on targets like
GPUs that tend to operate on scalars anyway.

However, notably with 16-bit operations it is often beneficial to keep
<2 x i16 / half> vectors around since there are packed instructions for
those.

Refactor the code to operate on "fragments" of split vectors. The
fragments are usually scalars, but may themselves be smaller vectors
when the scalarizer-min-bits option is used. If the split is uneven,
the last fragment is a shorter remainder.

This is almost NFC when the new option is unused, but it happens to
clean up some code in the fully scalarized case as well.

Differential Revision: https://reviews.llvm.org/D149842
  • Loading branch information
nhaehnle committed Jun 13, 2023
1 parent fc7e60f commit 2cb5c6d
Show file tree
Hide file tree
Showing 7 changed files with 1,328 additions and 811 deletions.
14 changes: 10 additions & 4 deletions llvm/include/llvm/Transforms/Scalar/Scalarizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
//===----------------------------------------------------------------------===//
//
/// \file
/// This pass converts vector operations into scalar operations, in order
/// to expose optimization opportunities on the individual scalar operations.
/// This pass converts vector operations into scalar operations (or, optionally,
/// operations on smaller vector widths), in order to expose optimization
/// opportunities on the individual scalar operations.
/// It is mainly intended for targets that do not have vector units, but it
/// may also be useful for revectorizing code to different vector widths.
//
Expand All @@ -26,24 +27,29 @@ class Function;
class FunctionPass;

struct ScalarizerPassOptions {
// These optional booleans correspond 1:1 to cl::opt<bool> options defined in
// These options correspond 1:1 to cl::opt options defined in
// Scalarizer.cpp. When the cl::opt are specified, they take precedence.
// When the cl::opt are not specified, the present optional booleans allow to
// When the cl::opt are not specified, the present optional values allow to
// override the cl::opt's default values.
std::optional<bool> ScalarizeVariableInsertExtract;
std::optional<bool> ScalarizeLoadStore;
std::optional<unsigned> ScalarizeMinBits;
};

class ScalarizerPass : public PassInfoMixin<ScalarizerPass> {
ScalarizerPassOptions Options;

public:
ScalarizerPass() = default;
ScalarizerPass(const ScalarizerPassOptions &Options) : Options(Options) {}

PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);

void setScalarizeVariableInsertExtract(bool Value) {
Options.ScalarizeVariableInsertExtract = Value;
}
void setScalarizeLoadStore(bool Value) { Options.ScalarizeLoadStore = Value; }
void setScalarizeMinBits(unsigned Value) { Options.ScalarizeMinBits = Value; }
};

/// Create a legacy pass manager instance of the Scalarizer pass
Expand Down

0 comments on commit 2cb5c6d

Please sign in to comment.