diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h index c091fa9ede8..5d5c49e4975 100644 --- a/include/llvm/CodeGen/MachineScheduler.h +++ b/include/llvm/CodeGen/MachineScheduler.h @@ -81,6 +81,7 @@ #include "llvm/CodeGen/MachinePassRegistry.h" #include "llvm/CodeGen/RegisterPressure.h" #include "llvm/CodeGen/ScheduleDAGInstrs.h" +#include "llvm/CodeGen/ScheduleDAGMutation.h" #include namespace llvm { @@ -220,15 +221,6 @@ public: virtual void releaseBottomNode(SUnit *SU) = 0; }; -/// Mutate the DAG as a postpass after normal DAG building. -class ScheduleDAGMutation { - virtual void anchor(); -public: - virtual ~ScheduleDAGMutation() {} - - virtual void apply(ScheduleDAGMI *DAG) = 0; -}; - /// ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply /// schedules machine instructions according to the given MachineSchedStrategy /// without much extra book-keeping. This is the common functionality between diff --git a/include/llvm/CodeGen/ScheduleDAGMutation.h b/include/llvm/CodeGen/ScheduleDAGMutation.h new file mode 100644 index 00000000000..02fe2294815 --- /dev/null +++ b/include/llvm/CodeGen/ScheduleDAGMutation.h @@ -0,0 +1,31 @@ +//==- ScheduleDAGMutation.h - MachineInstr Scheduling ------------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the ScheduleDAGMutation class, which represents +// a target-specific mutation of the dependency graph for scheduling. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_SCHEDULEDAGMUTATION_H +#define LLVM_CODEGEN_SCHEDULEDAGMUTATION_H + +namespace llvm { + class ScheduleDAGInstrs; + + /// Mutate the DAG as a postpass after normal DAG building. + class ScheduleDAGMutation { + virtual void anchor(); + public: + virtual ~ScheduleDAGMutation() {} + + virtual void apply(ScheduleDAGInstrs *DAG) = 0; + }; +} + +#endif diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h index c2e36be74ae..4c7a9975d30 100644 --- a/include/llvm/Target/TargetSubtargetInfo.h +++ b/include/llvm/Target/TargetSubtargetInfo.h @@ -16,8 +16,10 @@ #include "llvm/CodeGen/PBQPRAConstraint.h" #include "llvm/CodeGen/SchedulerRegistry.h" +#include "llvm/CodeGen/ScheduleDAGMutation.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Support/CodeGen.h" +#include namespace llvm { @@ -165,6 +167,12 @@ public: return CriticalPathRCs.clear(); } + // \brief Provide an ordered list of schedule DAG mutations for the post-RA + // scheduler. + virtual void getPostRAMutations( + std::vector> &Mutations) const { + } + // For use with PostRAScheduling: get the minimum optimization level needed // to enable post-RA scheduling. virtual CodeGenOpt::Level getOptLevelToEnablePostRAScheduler() const { diff --git a/lib/CodeGen/MachineScheduler.cpp b/lib/CodeGen/MachineScheduler.cpp index 99536ebb3e4..604d8219794 100644 --- a/lib/CodeGen/MachineScheduler.cpp +++ b/lib/CodeGen/MachineScheduler.cpp @@ -1377,7 +1377,7 @@ public: const TargetRegisterInfo *tri) : TII(tii), TRI(tri) {} - void apply(ScheduleDAGMI *DAG) override; + void apply(ScheduleDAGInstrs *DAGInstrs) override; protected: void clusterNeighboringLoads(ArrayRef Loads, ScheduleDAGMI *DAG); }; @@ -1429,7 +1429,9 @@ void LoadClusterMutation::clusterNeighboringLoads(ArrayRef Loads, } /// \brief Callback from DAG postProcessing to create cluster edges for loads. -void LoadClusterMutation::apply(ScheduleDAGMI *DAG) { +void LoadClusterMutation::apply(ScheduleDAGInstrs *DAGInstrs) { + ScheduleDAGMI *DAG = static_cast(DAGInstrs); + // Map DAG NodeNum to store chain ID. DenseMap StoreChainIDs; // Map each store chain to a set of dependent loads. @@ -1474,7 +1476,7 @@ public: MacroFusion(const TargetInstrInfo &TII, const TargetRegisterInfo &TRI) : TII(TII), TRI(TRI) {} - void apply(ScheduleDAGMI *DAG) override; + void apply(ScheduleDAGInstrs *DAGInstrs) override; }; } // anonymous @@ -1494,7 +1496,9 @@ static bool HasDataDep(const TargetRegisterInfo &TRI, const MachineInstr &MI, /// \brief Callback from DAG postProcessing to create cluster edges to encourage /// fused operations. -void MacroFusion::apply(ScheduleDAGMI *DAG) { +void MacroFusion::apply(ScheduleDAGInstrs *DAGInstrs) { + ScheduleDAGMI *DAG = static_cast(DAGInstrs); + // For now, assume targets can only fuse with the branch. SUnit &ExitSU = DAG->ExitSU; MachineInstr *Branch = ExitSU.getInstr(); @@ -1545,7 +1549,7 @@ class CopyConstrain : public ScheduleDAGMutation { public: CopyConstrain(const TargetInstrInfo *, const TargetRegisterInfo *) {} - void apply(ScheduleDAGMI *DAG) override; + void apply(ScheduleDAGInstrs *DAGInstrs) override; protected: void constrainLocalCopy(SUnit *CopySU, ScheduleDAGMILive *DAG); @@ -1698,7 +1702,8 @@ void CopyConstrain::constrainLocalCopy(SUnit *CopySU, ScheduleDAGMILive *DAG) { /// \brief Callback from DAG postProcessing to create weak edges to encourage /// copy elimination. -void CopyConstrain::apply(ScheduleDAGMI *DAG) { +void CopyConstrain::apply(ScheduleDAGInstrs *DAGInstrs) { + ScheduleDAGMI *DAG = static_cast(DAGInstrs); assert(DAG->hasVRegLiveness() && "Expect VRegs with LiveIntervals"); MachineBasicBlock::iterator FirstPos = nextIfDebug(DAG->begin(), DAG->end()); diff --git a/lib/CodeGen/PostRASchedulerList.cpp b/lib/CodeGen/PostRASchedulerList.cpp index 06a88bfb4c6..4266dec82d7 100644 --- a/lib/CodeGen/PostRASchedulerList.cpp +++ b/lib/CodeGen/PostRASchedulerList.cpp @@ -128,6 +128,9 @@ namespace { /// The schedule. Null SUnit*'s represent noop instructions. std::vector Sequence; + /// Ordered list of DAG postprocessing steps. + std::vector> Mutations; + /// The index in BB of RegionEnd. /// /// This is the instruction number from the top of the current block, not @@ -176,6 +179,9 @@ namespace { void finishBlock() override; private: + /// Apply each ScheduleDAGMutation step in order. + void postprocessDAG(); + void ReleaseSucc(SUnit *SU, SDep *SuccEdge); void ReleaseSuccessors(SUnit *SU); void ScheduleNodeTopDown(SUnit *SU, unsigned CurCycle); @@ -203,6 +209,7 @@ SchedulePostRATDList::SchedulePostRATDList( HazardRec = MF.getSubtarget().getInstrInfo()->CreateTargetPostRAHazardRecognizer( InstrItins, this); + MF.getSubtarget().getPostRAMutations(Mutations); assert((AntiDepMode == TargetSubtargetInfo::ANTIDEP_NONE || MRI.tracksLiveness()) && @@ -429,6 +436,12 @@ void SchedulePostRATDList::finishBlock() { ScheduleDAGInstrs::finishBlock(); } +/// Apply each ScheduleDAGMutation step in order. +void SchedulePostRATDList::postprocessDAG() { + for (auto &M : Mutations) + M->apply(this); +} + //===----------------------------------------------------------------------===// // Top-Down Scheduling //===----------------------------------------------------------------------===//