Skip to content

[Scalar] Dedicated pass for identifying redundant operations on packed bytes #146364

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions llvm/include/llvm/InitializePasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ initializeOptimizationRemarkEmitterWrapperPassPass(PassRegistry &);
LLVM_ABI void initializeOptimizePHIsLegacyPass(PassRegistry &);
LLVM_ABI void initializePEILegacyPass(PassRegistry &);
LLVM_ABI void initializePHIEliminationPass(PassRegistry &);
LLVM_ABI void initializePackedIntegerCombineLegacyPassPass(PassRegistry &);
LLVM_ABI void initializePartiallyInlineLibCallsLegacyPassPass(PassRegistry &);
LLVM_ABI void initializePatchableFunctionLegacyPass(PassRegistry &);
LLVM_ABI void initializePeepholeOptimizerLegacyPass(PassRegistry &);
Expand Down
9 changes: 9 additions & 0 deletions llvm/include/llvm/Transforms/Scalar.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,15 @@ LLVM_ABI FunctionPass *
createInferAddressSpacesPass(unsigned AddressSpace = ~0u);
LLVM_ABI extern char &InferAddressSpacesID;

//===----------------------------------------------------------------------===//
//
// PackedIntegerCombinePass - Tracks individual bytes through instructions to
// systematically identify redundant byte packing or unpacking operations.
//
LLVM_ABI FunctionPass *
createPackedIntegerCombinePass(unsigned MaxCollectionIterations = 2,
bool AggressiveRewriting = false);

//===----------------------------------------------------------------------===//
//
// PartiallyInlineLibCalls - Tries to inline the fast path of library
Expand Down
48 changes: 48 additions & 0 deletions llvm/include/llvm/Transforms/Scalar/PackedIntegerCombinePass.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//===- PackedIntegerCombinePass.h -------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
///
/// This file provides the interface for LLVM's Packed Integer Combine pass.
/// This pass tries to treat integers as packed chunks of individual bytes,
/// and leverage this to coalesce needlessly fragmented
/// computations.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_TRANSFORMS_SCALAR_PACKEDINTCOMBINE_H
#define LLVM_TRANSFORMS_SCALAR_PACKEDINTCOMBINE_H

#include "llvm/IR/PassManager.h"

namespace llvm {

struct PackedIntegerCombineOptions {
/// Maximum number of iterations to isolate final packed instructions.
unsigned MaxCollectionIterations = 2;
/// Aggressively rewrite packed instructions.
bool AggressiveRewriting = false;
};

class PackedIntegerCombinePass
: public PassInfoMixin<PackedIntegerCombinePass> {

PackedIntegerCombineOptions Options;

public:
PackedIntegerCombinePass(PackedIntegerCombineOptions Options = {})
: Options(Options) {}

LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
LLVM_ABI void
printPipeline(raw_ostream &OS,
function_ref<StringRef(StringRef)> MapClassName2PassName);
};

} // end namespace llvm

#endif // LLVM_TRANSFORMS_SCALAR_PACKEDINTCOMBINE_H
30 changes: 30 additions & 0 deletions llvm/lib/Passes/PassBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@
#include "llvm/Transforms/Scalar/MergedLoadStoreMotion.h"
#include "llvm/Transforms/Scalar/NaryReassociate.h"
#include "llvm/Transforms/Scalar/NewGVN.h"
#include "llvm/Transforms/Scalar/PackedIntegerCombinePass.h"
#include "llvm/Transforms/Scalar/PartiallyInlineLibCalls.h"
#include "llvm/Transforms/Scalar/PlaceSafepoints.h"
#include "llvm/Transforms/Scalar/Reassociate.h"
Expand Down Expand Up @@ -1169,6 +1170,35 @@ Expected<bool> parseMergedLoadStoreMotionOptions(StringRef Params) {
return Result;
}

Expected<PackedIntegerCombineOptions>
parsePackedIntegerCombineOptions(StringRef Params) {
PackedIntegerCombineOptions Options;
while (!Params.empty()) {
StringRef ParamName;
std::tie(ParamName, Params) = Params.split(';');

if (ParamName.consume_front("max-iterations=")) {
if (ParamName.getAsInteger(0, Options.MaxCollectionIterations))
return make_error<StringError>(
formatv("invalid max iteration count for PackedIntegerCombine "
"pass: '{}'",
ParamName)
.str(),
inconvertibleErrorCode());
} else if (ParamName == "aggressive") {
Options.AggressiveRewriting = true;
} else {
return make_error<StringError>(
formatv("invalid argument for PackedIntegerCombinePass: '{}'",
ParamName)
.str(),
inconvertibleErrorCode());
}
}

return Options;
}

Expected<GVNOptions> parseGVNOptions(StringRef Params) {
GVNOptions Result;
while (!Params.empty()) {
Expand Down
9 changes: 8 additions & 1 deletion llvm/lib/Passes/PassBuilderPipelines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
#include "llvm/Transforms/Scalar/MemCpyOptimizer.h"
#include "llvm/Transforms/Scalar/MergedLoadStoreMotion.h"
#include "llvm/Transforms/Scalar/NewGVN.h"
#include "llvm/Transforms/Scalar/PackedIntegerCombinePass.h"
#include "llvm/Transforms/Scalar/Reassociate.h"
#include "llvm/Transforms/Scalar/SCCP.h"
#include "llvm/Transforms/Scalar/SROA.h"
Expand Down Expand Up @@ -542,6 +543,9 @@ PassBuilder::buildO1FunctionSimplificationPipeline(OptimizationLevel Level,
// opportunities that creates).
FPM.addPass(BDCEPass());

// Simplify bit-packed operations before cleaning up with instcombine.
FPM.addPass(PackedIntegerCombinePass());

// Run instcombine after redundancy and dead bit elimination to exploit
// opportunities opened up by them.
FPM.addPass(InstCombinePass());
Expand Down Expand Up @@ -743,6 +747,9 @@ PassBuilder::buildFunctionSimplificationPipeline(OptimizationLevel Level,
// opportunities that creates).
FPM.addPass(BDCEPass());

// Simplify bit-packed operations before cleaning up with instcombine.
FPM.addPass(PackedIntegerCombinePass());

// Run instcombine after redundancy and dead bit elimination to exploit
// opportunities opened up by them.
FPM.addPass(InstCombinePass());
Expand Down Expand Up @@ -2354,4 +2361,4 @@ AAManager PassBuilder::buildDefaultAAPipeline() {
bool PassBuilder::isInstrumentedPGOUse() const {
return (PGOOpt && PGOOpt->Action == PGOOptions::IRUse) ||
!UseCtxProfile.empty();
}
}
6 changes: 6 additions & 0 deletions llvm/lib/Passes/PassRegistry.def
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,12 @@ FUNCTION_PASS_WITH_PARAMS(
return MergedLoadStoreMotionPass(Opts);
},
parseMergedLoadStoreMotionOptions, "no-split-footer-bb;split-footer-bb")
FUNCTION_PASS_WITH_PARAMS(
"packed-integer-combine", "PackedIntegerCombinePass",
[](PackedIntegerCombineOptions Options) {
return PackedIntegerCombinePass(Options);
},
parsePackedIntegerCombineOptions, "max-iterations=N;aggressive")
FUNCTION_PASS_WITH_PARAMS(
"print<access-info>", "LoopAccessInfoPrinterPass",
[](bool AllowPartial) {
Expand Down
11 changes: 9 additions & 2 deletions llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
#include "llvm/Transforms/Scalar/InferAddressSpaces.h"
#include "llvm/Transforms/Scalar/LoopDataPrefetch.h"
#include "llvm/Transforms/Scalar/NaryReassociate.h"
#include "llvm/Transforms/Scalar/PackedIntegerCombinePass.h"
#include "llvm/Transforms/Scalar/SeparateConstOffsetFromGEP.h"
#include "llvm/Transforms/Scalar/Sink.h"
#include "llvm/Transforms/Scalar/StraightLineStrengthReduce.h"
Expand Down Expand Up @@ -1378,8 +1379,11 @@ void AMDGPUPassConfig::addCodeGenPrepare() {

TargetPassConfig::addCodeGenPrepare();

if (isPassEnabled(EnableLoadStoreVectorizer))
if (isPassEnabled(EnableLoadStoreVectorizer)) {
addPass(createLoadStoreVectorizerPass());
// LSV pass opens up more opportunities for packed integer combining.
addPass(createPackedIntegerCombinePass());
Comment on lines +1384 to +1385
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a phase ordering test for this?

}

// LowerSwitch pass may introduce unreachable blocks that can
// cause unexpected behavior for subsequent passes. Placing it
Expand Down Expand Up @@ -2101,8 +2105,11 @@ void AMDGPUCodeGenPassBuilder::addCodeGenPrepare(AddIRPass &addPass) const {

Base::addCodeGenPrepare(addPass);

if (isPassEnabled(EnableLoadStoreVectorizer))
if (isPassEnabled(EnableLoadStoreVectorizer)) {
addPass(LoadStoreVectorizerPass());
// LSV pass opens up more opportunities for packed integer combining.
addPass(PackedIntegerCombinePass());
}

// LowerSwitch pass may introduce unreachable blocks that can cause unexpected
// behavior for subsequent passes. Placing it here seems better that these
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Transforms/Scalar/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ add_llvm_component_library(LLVMScalarOpts
NaryReassociate.cpp
NewGVN.cpp
PartiallyInlineLibCalls.cpp
PackedIntegerCombinePass.cpp
PlaceSafepoints.cpp
Reassociate.cpp
Reg2Mem.cpp
Expand Down
Loading
Loading