From f137309d3772b18b83e0a587c7d4065ec4f610b8 Mon Sep 17 00:00:00 2001 From: wangpc Date: Fri, 10 Nov 2023 17:58:00 +0800 Subject: [PATCH 1/3] [MacroFusion] Support multiple predicators 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`. --- llvm/include/llvm/CodeGen/MacroFusion.h | 20 +++++++------ llvm/lib/CodeGen/MacroFusion.cpp | 37 +++++++++++++++++-------- llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp | 4 +-- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/llvm/include/llvm/CodeGen/MacroFusion.h b/llvm/include/llvm/CodeGen/MacroFusion.h index ea2c7a5faae38..a359fca604260 100644 --- a/llvm/include/llvm/CodeGen/MacroFusion.h +++ b/llvm/include/llvm/CodeGen/MacroFusion.h @@ -14,7 +14,7 @@ #ifndef LLVM_CODEGEN_MACROFUSION_H #define LLVM_CODEGEN_MACROFUSION_H -#include +#include "llvm/ADT/ArrayRef.h" #include namespace llvm { @@ -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; +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 @@ -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 -createMacroFusionDAGMutation(ShouldSchedulePredTy shouldScheduleAdjacent); +createMacroFusionDAGMutation(ArrayRef 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 -createBranchMacroFusionDAGMutation(ShouldSchedulePredTy shouldScheduleAdjacent); +createBranchMacroFusionDAGMutation(ArrayRef Predicates); } // end namespace llvm diff --git a/llvm/lib/CodeGen/MacroFusion.cpp b/llvm/lib/CodeGen/MacroFusion.cpp index fa5df68b8abcc..30affc93d4adc 100644 --- a/llvm/lib/CodeGen/MacroFusion.cpp +++ b/llvm/lib/CodeGen/MacroFusion.cpp @@ -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 Predicates; bool FuseBlock; bool scheduleAdjacentImpl(ScheduleDAGInstrs &DAG, SUnit &AnchorSU); public: - MacroFusion(ShouldSchedulePredTy shouldScheduleAdjacent, bool FuseBlock) - : shouldScheduleAdjacent(shouldScheduleAdjacent), FuseBlock(FuseBlock) {} + MacroFusion(ArrayRef 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 @@ -197,17 +212,15 @@ bool MacroFusion::scheduleAdjacentImpl(ScheduleDAGInstrs &DAG, SUnit &AnchorSU) } std::unique_ptr -llvm::createMacroFusionDAGMutation( - ShouldSchedulePredTy shouldScheduleAdjacent) { - if(EnableMacroFusion) - return std::make_unique(shouldScheduleAdjacent, true); +llvm::createMacroFusionDAGMutation(ArrayRef Predicates) { + if (EnableMacroFusion) + return std::make_unique(std::move(Predicates), true); return nullptr; } -std::unique_ptr -llvm::createBranchMacroFusionDAGMutation( - ShouldSchedulePredTy shouldScheduleAdjacent) { - if(EnableMacroFusion) - return std::make_unique(shouldScheduleAdjacent, false); +std::unique_ptr llvm::createBranchMacroFusionDAGMutation( + ArrayRef Predicates) { + if (EnableMacroFusion) + return std::make_unique(std::move(Predicates), false); return nullptr; } diff --git a/llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp b/llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp index 29c9b9ccf2761..0bddeeef9e9b1 100644 --- a/llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp +++ b/llvm/lib/Target/AMDGPU/GCNVOPDUtils.cpp @@ -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 { From f1fc128d7eaaf8f87bae63b96d88c1a4bcf288ad Mon Sep 17 00:00:00 2001 From: wangpc Date: Mon, 11 Dec 2023 11:59:11 +0800 Subject: [PATCH 2/3] Remove std::move --- llvm/lib/CodeGen/MacroFusion.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/CodeGen/MacroFusion.cpp b/llvm/lib/CodeGen/MacroFusion.cpp index 30affc93d4adc..aff4d95781f45 100644 --- a/llvm/lib/CodeGen/MacroFusion.cpp +++ b/llvm/lib/CodeGen/MacroFusion.cpp @@ -214,13 +214,13 @@ bool MacroFusion::scheduleAdjacentImpl(ScheduleDAGInstrs &DAG, SUnit &AnchorSU) std::unique_ptr llvm::createMacroFusionDAGMutation(ArrayRef Predicates) { if (EnableMacroFusion) - return std::make_unique(std::move(Predicates), true); + return std::make_unique(Predicates, true); return nullptr; } std::unique_ptr llvm::createBranchMacroFusionDAGMutation( ArrayRef Predicates) { if (EnableMacroFusion) - return std::make_unique(std::move(Predicates), false); + return std::make_unique(Predicates, false); return nullptr; } From d65b7c36c933d0b0c35b619b5ef7978965123f5a Mon Sep 17 00:00:00 2001 From: wangpc Date: Mon, 11 Dec 2023 20:17:03 +0800 Subject: [PATCH 3/3] Use function_ref --- llvm/include/llvm/CodeGen/MacroFusion.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/CodeGen/MacroFusion.h b/llvm/include/llvm/CodeGen/MacroFusion.h index a359fca604260..41a027ea06696 100644 --- a/llvm/include/llvm/CodeGen/MacroFusion.h +++ b/llvm/include/llvm/CodeGen/MacroFusion.h @@ -29,10 +29,9 @@ 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 MacroFusionPredTy = bool (*)(const TargetInstrInfo &TII, - const TargetSubtargetInfo &STI, - const MachineInstr *FirstMI, - const MachineInstr &SecondMI); +using MacroFusionPredTy = function_ref; /// Checks if the number of cluster edges between SU and its predecessors is /// less than FuseLimit