diff --git a/llvm/include/llvm/CodeGen/MacroFusion.h b/llvm/include/llvm/CodeGen/MacroFusion.h index ea2c7a5faae38..41a027ea06696 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,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 ShouldSchedulePredTy = std::function; +using MacroFusionPredTy = function_ref; /// Checks if the number of cluster edges between SU and its predecessors is /// less than FuseLimit @@ -48,15 +47,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..aff4d95781f45 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(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(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 {