Index: llvm/trunk/include/llvm/CodeGen/MachineScheduler.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineScheduler.h +++ llvm/trunk/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 @@ 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 Index: llvm/trunk/include/llvm/CodeGen/ScheduleDAGMutation.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAGMutation.h +++ llvm/trunk/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 Index: llvm/trunk/include/llvm/Target/TargetSubtargetInfo.h =================================================================== --- llvm/trunk/include/llvm/Target/TargetSubtargetInfo.h +++ llvm/trunk/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 @@ 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 { Index: llvm/trunk/lib/CodeGen/MachineScheduler.cpp =================================================================== --- llvm/trunk/lib/CodeGen/MachineScheduler.cpp +++ llvm/trunk/lib/CodeGen/MachineScheduler.cpp @@ -1377,7 +1377,7 @@ 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 @@ } /// \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 @@ 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 @@ /// \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 @@ 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 @@ /// \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()); Index: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp =================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp @@ -128,6 +128,9 @@ /// 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 @@ 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 @@ HazardRec = MF.getSubtarget().getInstrInfo()->CreateTargetPostRAHazardRecognizer( InstrItins, this); + MF.getSubtarget().getPostRAMutations(Mutations); assert((AntiDepMode == TargetSubtargetInfo::ANTIDEP_NONE || MRI.tracksLiveness()) && @@ -429,6 +436,12 @@ ScheduleDAGInstrs::finishBlock(); } +/// Apply each ScheduleDAGMutation step in order. +void SchedulePostRATDList::postprocessDAG() { + for (auto &M : Mutations) + M->apply(this); +} + //===----------------------------------------------------------------------===// // Top-Down Scheduling //===----------------------------------------------------------------------===//