Add DAG mutation interface to the post-RA scheduler

Differential Revision: http://reviews.llvm.org/D17868

llvm-svn: 262774
This commit is contained in:
Krzysztof Parzyszek 2016-03-05 15:45:23 +00:00
parent 7f6d50b229
commit 5c61d11a6d
5 changed files with 64 additions and 15 deletions

View File

@ -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 <memory>
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

View File

@ -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

View File

@ -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 <vector>
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<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const {
}
// For use with PostRAScheduling: get the minimum optimization level needed
// to enable post-RA scheduling.
virtual CodeGenOpt::Level getOptLevelToEnablePostRAScheduler() const {

View File

@ -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<SUnit*> Loads, ScheduleDAGMI *DAG);
};
@ -1429,7 +1429,9 @@ void LoadClusterMutation::clusterNeighboringLoads(ArrayRef<SUnit*> 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<ScheduleDAGMI*>(DAGInstrs);
// Map DAG NodeNum to store chain ID.
DenseMap<unsigned, unsigned> 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<ScheduleDAGMI*>(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<ScheduleDAGMI*>(DAGInstrs);
assert(DAG->hasVRegLiveness() && "Expect VRegs with LiveIntervals");
MachineBasicBlock::iterator FirstPos = nextIfDebug(DAG->begin(), DAG->end());

View File

@ -128,6 +128,9 @@ namespace {
/// The schedule. Null SUnit*'s represent noop instructions.
std::vector<SUnit*> Sequence;
/// Ordered list of DAG postprocessing steps.
std::vector<std::unique_ptr<ScheduleDAGMutation>> 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
//===----------------------------------------------------------------------===//