Skip to content

Commit

Permalink
[MacroFusion] Support multiple predicators (#72219)
Browse files Browse the repository at this point in the history
The user can provide multiple predicators to MacroFusion and the
DAG mutation will be applied if one of them is evalated to true.

`ShouldSchedulePredTy` is renamed to `MacroFusionPredTy`.
  • Loading branch information
wangpc-pp committed Dec 12, 2023
1 parent ce08c7e commit d11e54f
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 23 deletions.
20 changes: 11 additions & 9 deletions llvm/include/llvm/CodeGen/MacroFusion.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#ifndef LLVM_CODEGEN_MACROFUSION_H
#define LLVM_CODEGEN_MACROFUSION_H

#include <functional>
#include "llvm/ADT/ArrayRef.h"
#include <memory>

namespace llvm {
Expand All @@ -29,10 +29,10 @@ class SUnit;
/// Check if the instr pair, FirstMI and SecondMI, should be fused
/// together. Given SecondMI, when FirstMI is unspecified, then check if
/// SecondMI may be part of a fused pair at all.
using ShouldSchedulePredTy = std::function<bool(const TargetInstrInfo &TII,
const TargetSubtargetInfo &TSI,
const MachineInstr *FirstMI,
const MachineInstr &SecondMI)>;
using MacroFusionPredTy = bool (*)(const TargetInstrInfo &TII,
const TargetSubtargetInfo &STI,
const MachineInstr *FirstMI,
const MachineInstr &SecondMI);

/// Checks if the number of cluster edges between SU and its predecessors is
/// less than FuseLimit
Expand All @@ -48,15 +48,17 @@ bool fuseInstructionPair(ScheduleDAGInstrs &DAG, SUnit &FirstSU,

/// Create a DAG scheduling mutation to pair instructions back to back
/// for instructions that benefit according to the target-specific
/// shouldScheduleAdjacent predicate function.
/// predicate functions. shouldScheduleAdjacent will be true if any of the
/// provided predicates are true.
std::unique_ptr<ScheduleDAGMutation>
createMacroFusionDAGMutation(ShouldSchedulePredTy shouldScheduleAdjacent);
createMacroFusionDAGMutation(ArrayRef<MacroFusionPredTy> Predicates);

/// Create a DAG scheduling mutation to pair branch instructions with one
/// of their predecessors back to back for instructions that benefit according
/// to the target-specific shouldScheduleAdjacent predicate function.
/// to the target-specific predicate functions. shouldScheduleAdjacent will be
/// true if any of the provided predicates are true.
std::unique_ptr<ScheduleDAGMutation>
createBranchMacroFusionDAGMutation(ShouldSchedulePredTy shouldScheduleAdjacent);
createBranchMacroFusionDAGMutation(ArrayRef<MacroFusionPredTy> Predicates);

} // end namespace llvm

Expand Down
37 changes: 25 additions & 12 deletions llvm/lib/CodeGen/MacroFusion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,19 +137,34 @@ namespace {
/// Post-process the DAG to create cluster edges between instrs that may
/// be fused by the processor into a single operation.
class MacroFusion : public ScheduleDAGMutation {
ShouldSchedulePredTy shouldScheduleAdjacent;
std::vector<MacroFusionPredTy> Predicates;
bool FuseBlock;
bool scheduleAdjacentImpl(ScheduleDAGInstrs &DAG, SUnit &AnchorSU);

public:
MacroFusion(ShouldSchedulePredTy shouldScheduleAdjacent, bool FuseBlock)
: shouldScheduleAdjacent(shouldScheduleAdjacent), FuseBlock(FuseBlock) {}
MacroFusion(ArrayRef<MacroFusionPredTy> Predicates, bool FuseBlock)
: Predicates(Predicates.begin(), Predicates.end()), FuseBlock(FuseBlock) {
}

void apply(ScheduleDAGInstrs *DAGInstrs) override;

bool shouldScheduleAdjacent(const TargetInstrInfo &TII,
const TargetSubtargetInfo &STI,
const MachineInstr *FirstMI,
const MachineInstr &SecondMI);
};

} // end anonymous namespace

bool MacroFusion::shouldScheduleAdjacent(const TargetInstrInfo &TII,
const TargetSubtargetInfo &STI,
const MachineInstr *FirstMI,
const MachineInstr &SecondMI) {
return llvm::any_of(Predicates, [&](MacroFusionPredTy Predicate) {
return Predicate(TII, STI, FirstMI, SecondMI);
});
}

void MacroFusion::apply(ScheduleDAGInstrs *DAG) {
if (FuseBlock)
// For each of the SUnits in the scheduling block, try to fuse the instr in
Expand Down Expand Up @@ -197,17 +212,15 @@ bool MacroFusion::scheduleAdjacentImpl(ScheduleDAGInstrs &DAG, SUnit &AnchorSU)
}

std::unique_ptr<ScheduleDAGMutation>
llvm::createMacroFusionDAGMutation(
ShouldSchedulePredTy shouldScheduleAdjacent) {
if(EnableMacroFusion)
return std::make_unique<MacroFusion>(shouldScheduleAdjacent, true);
llvm::createMacroFusionDAGMutation(ArrayRef<MacroFusionPredTy> Predicates) {
if (EnableMacroFusion)
return std::make_unique<MacroFusion>(Predicates, true);
return nullptr;
}

std::unique_ptr<ScheduleDAGMutation>
llvm::createBranchMacroFusionDAGMutation(
ShouldSchedulePredTy shouldScheduleAdjacent) {
if(EnableMacroFusion)
return std::make_unique<MacroFusion>(shouldScheduleAdjacent, false);
std::unique_ptr<ScheduleDAGMutation> llvm::createBranchMacroFusionDAGMutation(
ArrayRef<MacroFusionPredTy> Predicates) {
if (EnableMacroFusion)
return std::make_unique<MacroFusion>(Predicates, false);
return nullptr;
}
4 changes: 2 additions & 2 deletions llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,10 @@ namespace {
/// be turned into VOPD instructions
/// Greedily pairs instruction candidates. O(n^2) algorithm.
struct VOPDPairingMutation : ScheduleDAGMutation {
ShouldSchedulePredTy shouldScheduleAdjacent; // NOLINT: function pointer
MacroFusionPredTy shouldScheduleAdjacent; // NOLINT: function pointer

VOPDPairingMutation(
ShouldSchedulePredTy shouldScheduleAdjacent) // NOLINT: function pointer
MacroFusionPredTy shouldScheduleAdjacent) // NOLINT: function pointer
: shouldScheduleAdjacent(shouldScheduleAdjacent) {}

void apply(ScheduleDAGInstrs *DAG) override {
Expand Down

0 comments on commit d11e54f

Please sign in to comment.