mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
Generalize the HazardRecognizer interface so that it can be used
to support MachineInstr-based scheduling in addition to SDNode-based scheduling. llvm-svn: 62284
This commit is contained in:
parent
23a5f63b21
commit
3e0dcbbd15
@ -19,45 +19,6 @@
|
||||
#include "llvm/CodeGen/SelectionDAG.h"
|
||||
|
||||
namespace llvm {
|
||||
/// HazardRecognizer - This determines whether or not an instruction can be
|
||||
/// issued this cycle, and whether or not a noop needs to be inserted to handle
|
||||
/// the hazard.
|
||||
class HazardRecognizer {
|
||||
public:
|
||||
virtual ~HazardRecognizer();
|
||||
|
||||
enum HazardType {
|
||||
NoHazard, // This instruction can be emitted at this cycle.
|
||||
Hazard, // This instruction can't be emitted at this cycle.
|
||||
NoopHazard // This instruction can't be emitted, and needs noops.
|
||||
};
|
||||
|
||||
/// getHazardType - Return the hazard type of emitting this node. There are
|
||||
/// three possible results. Either:
|
||||
/// * NoHazard: it is legal to issue this instruction on this cycle.
|
||||
/// * Hazard: issuing this instruction would stall the machine. If some
|
||||
/// other instruction is available, issue it first.
|
||||
/// * NoopHazard: issuing this instruction would break the program. If
|
||||
/// some other instruction can be issued, do so, otherwise issue a noop.
|
||||
virtual HazardType getHazardType(SDNode *) {
|
||||
return NoHazard;
|
||||
}
|
||||
|
||||
/// EmitInstruction - This callback is invoked when an instruction is
|
||||
/// emitted, to advance the hazard state.
|
||||
virtual void EmitInstruction(SDNode *) {}
|
||||
|
||||
/// AdvanceCycle - This callback is invoked when no instructions can be
|
||||
/// issued on this cycle without a hazard. This should increment the
|
||||
/// internal state of the hazard recognizer so that previously "Hazard"
|
||||
/// instructions will now not be hazards.
|
||||
virtual void AdvanceCycle() {}
|
||||
|
||||
/// EmitNoop - This callback is invoked when a noop was added to the
|
||||
/// instruction stream.
|
||||
virtual void EmitNoop() {}
|
||||
};
|
||||
|
||||
/// ScheduleDAGSDNodes - A ScheduleDAG for scheduling SDNode-based DAGs.
|
||||
///
|
||||
/// Edges between SUnits are initially based on edges in the SelectionDAG,
|
||||
|
63
include/llvm/CodeGen/ScheduleHazardRecognizer.h
Normal file
63
include/llvm/CodeGen/ScheduleHazardRecognizer.h
Normal file
@ -0,0 +1,63 @@
|
||||
//=- llvm/CodeGen/ScheduleHazardRecognizer.h - Scheduling Support -*- 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 ScheduleHazardRecognizer class, which implements
|
||||
// hazard-avoidance heuristics for scheduling.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CODEGEN_SCHEDULEHAZARDRECOGNIZER_H
|
||||
#define LLVM_CODEGEN_SCHEDULEHAZARDRECOGNIZER_H
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class SUnit;
|
||||
|
||||
/// HazardRecognizer - This determines whether or not an instruction can be
|
||||
/// issued this cycle, and whether or not a noop needs to be inserted to handle
|
||||
/// the hazard.
|
||||
class ScheduleHazardRecognizer {
|
||||
public:
|
||||
virtual ~ScheduleHazardRecognizer();
|
||||
|
||||
enum HazardType {
|
||||
NoHazard, // This instruction can be emitted at this cycle.
|
||||
Hazard, // This instruction can't be emitted at this cycle.
|
||||
NoopHazard // This instruction can't be emitted, and needs noops.
|
||||
};
|
||||
|
||||
/// getHazardType - Return the hazard type of emitting this node. There are
|
||||
/// three possible results. Either:
|
||||
/// * NoHazard: it is legal to issue this instruction on this cycle.
|
||||
/// * Hazard: issuing this instruction would stall the machine. If some
|
||||
/// other instruction is available, issue it first.
|
||||
/// * NoopHazard: issuing this instruction would break the program. If
|
||||
/// some other instruction can be issued, do so, otherwise issue a noop.
|
||||
virtual HazardType getHazardType(SUnit *) {
|
||||
return NoHazard;
|
||||
}
|
||||
|
||||
/// EmitInstruction - This callback is invoked when an instruction is
|
||||
/// emitted, to advance the hazard state.
|
||||
virtual void EmitInstruction(SUnit *) {}
|
||||
|
||||
/// AdvanceCycle - This callback is invoked when no instructions can be
|
||||
/// issued on this cycle without a hazard. This should increment the
|
||||
/// internal state of the hazard recognizer so that previously "Hazard"
|
||||
/// instructions will now not be hazards.
|
||||
virtual void AdvanceCycle() {}
|
||||
|
||||
/// EmitNoop - This callback is invoked when a noop was added to the
|
||||
/// instruction stream.
|
||||
virtual void EmitNoop() {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -33,7 +33,7 @@ namespace llvm {
|
||||
class TargetLowering;
|
||||
class TargetInstrInfo;
|
||||
class FunctionLoweringInfo;
|
||||
class HazardRecognizer;
|
||||
class ScheduleHazardRecognizer;
|
||||
class GCFunctionInfo;
|
||||
class ScheduleDAG;
|
||||
|
||||
@ -93,7 +93,7 @@ public:
|
||||
|
||||
/// CreateTargetHazardRecognizer - Return a newly allocated hazard recognizer
|
||||
/// to use for this target when scheduling the DAG.
|
||||
virtual HazardRecognizer *CreateTargetHazardRecognizer();
|
||||
virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer();
|
||||
|
||||
protected:
|
||||
/// DAGSize - Size of DAG being instruction selected.
|
||||
|
@ -1293,7 +1293,23 @@ public:
|
||||
return getOperand(getNumOperands()-1).getNode();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// If this is a pseudo op, like copyfromreg, look to see if there is a
|
||||
// real target node flagged to it. If so, return the target node.
|
||||
const SDNode *getFlaggedMachineNode() const {
|
||||
const SDNode *FoundNode = this;
|
||||
|
||||
// Climb up flag edges until a machine-opcode node is found, or the
|
||||
// end of the chain is reached.
|
||||
while (!FoundNode->isMachineOpcode()) {
|
||||
const SDNode *N = FoundNode->getFlaggedNode();
|
||||
if (!N) break;
|
||||
FoundNode = N;
|
||||
}
|
||||
|
||||
return FoundNode;
|
||||
}
|
||||
|
||||
/// getNumValues - Return the number of values defined/returned by this
|
||||
/// operator.
|
||||
///
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#define DEBUG_TYPE "pre-RA-sched"
|
||||
#include "llvm/CodeGen/ScheduleDAG.h"
|
||||
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
@ -561,3 +562,5 @@ void ScheduleDAGTopologicalSort::Allocate(int n, int index) {
|
||||
ScheduleDAGTopologicalSort::ScheduleDAGTopologicalSort(
|
||||
std::vector<SUnit> &sunits)
|
||||
: SUnits(sunits) {}
|
||||
|
||||
ScheduleHazardRecognizer::~ScheduleHazardRecognizer() {}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#define DEBUG_TYPE "pre-RA-sched"
|
||||
#include "llvm/CodeGen/LatencyPriorityQueue.h"
|
||||
#include "llvm/CodeGen/ScheduleDAGSDNodes.h"
|
||||
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
|
||||
#include "llvm/CodeGen/SchedulerRegistry.h"
|
||||
#include "llvm/CodeGen/SelectionDAGISel.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
@ -58,12 +59,12 @@ private:
|
||||
std::vector<SUnit*> PendingQueue;
|
||||
|
||||
/// HazardRec - The hazard recognizer to use.
|
||||
HazardRecognizer *HazardRec;
|
||||
ScheduleHazardRecognizer *HazardRec;
|
||||
|
||||
public:
|
||||
ScheduleDAGList(MachineFunction &mf,
|
||||
SchedulingPriorityQueue *availqueue,
|
||||
HazardRecognizer *HR)
|
||||
ScheduleHazardRecognizer *HR)
|
||||
: ScheduleDAGSDNodes(mf),
|
||||
AvailableQueue(availqueue), HazardRec(HR) {
|
||||
}
|
||||
@ -82,9 +83,6 @@ private:
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
HazardRecognizer::~HazardRecognizer() {}
|
||||
|
||||
|
||||
/// Schedule - Schedule the DAG using list scheduling.
|
||||
void ScheduleDAGList::Schedule() {
|
||||
DOUT << "********** List Scheduling **********\n";
|
||||
@ -190,31 +188,20 @@ void ScheduleDAGList::ListScheduleTopDown() {
|
||||
}
|
||||
|
||||
SUnit *FoundSUnit = 0;
|
||||
SDNode *FoundNode = 0;
|
||||
|
||||
bool HasNoopHazards = false;
|
||||
while (!AvailableQueue->empty()) {
|
||||
SUnit *CurSUnit = AvailableQueue->pop();
|
||||
|
||||
// Get the node represented by this SUnit.
|
||||
FoundNode = CurSUnit->getNode();
|
||||
|
||||
// If this is a pseudo op, like copyfromreg, look to see if there is a
|
||||
// real target node flagged to it. If so, use the target node.
|
||||
while (!FoundNode->isMachineOpcode()) {
|
||||
SDNode *N = FoundNode->getFlaggedNode();
|
||||
if (!N) break;
|
||||
FoundNode = N;
|
||||
}
|
||||
|
||||
HazardRecognizer::HazardType HT = HazardRec->getHazardType(FoundNode);
|
||||
if (HT == HazardRecognizer::NoHazard) {
|
||||
ScheduleHazardRecognizer::HazardType HT =
|
||||
HazardRec->getHazardType(CurSUnit);
|
||||
if (HT == ScheduleHazardRecognizer::NoHazard) {
|
||||
FoundSUnit = CurSUnit;
|
||||
break;
|
||||
}
|
||||
|
||||
// Remember if this is a noop hazard.
|
||||
HasNoopHazards |= HT == HazardRecognizer::NoopHazard;
|
||||
HasNoopHazards |= HT == ScheduleHazardRecognizer::NoopHazard;
|
||||
|
||||
NotReady.push_back(CurSUnit);
|
||||
}
|
||||
@ -228,7 +215,7 @@ void ScheduleDAGList::ListScheduleTopDown() {
|
||||
// If we found a node to schedule, do it now.
|
||||
if (FoundSUnit) {
|
||||
ScheduleNodeTopDown(FoundSUnit, CurCycle);
|
||||
HazardRec->EmitInstruction(FoundNode);
|
||||
HazardRec->EmitInstruction(FoundSUnit);
|
||||
|
||||
// If this is a pseudo-op node, we don't want to increment the current
|
||||
// cycle.
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/ScheduleDAGSDNodes.h"
|
||||
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
|
||||
#include "llvm/CodeGen/SchedulerRegistry.h"
|
||||
#include "llvm/CodeGen/SelectionDAG.h"
|
||||
#include "llvm/CodeGen/DwarfWriter.h"
|
||||
@ -1079,8 +1080,8 @@ ScheduleDAG *SelectionDAGISel::Schedule() {
|
||||
}
|
||||
|
||||
|
||||
HazardRecognizer *SelectionDAGISel::CreateTargetHazardRecognizer() {
|
||||
return new HazardRecognizer();
|
||||
ScheduleHazardRecognizer *SelectionDAGISel::CreateTargetHazardRecognizer() {
|
||||
return new ScheduleHazardRecognizer();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include "SPUHazardRecognizers.h"
|
||||
#include "SPU.h"
|
||||
#include "SPUInstrInfo.h"
|
||||
#include "llvm/CodeGen/ScheduleDAG.h"
|
||||
#include "llvm/CodeGen/SelectionDAGNodes.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
|
||||
using namespace llvm;
|
||||
@ -38,14 +40,15 @@ SPUHazardRecognizer::SPUHazardRecognizer(const TargetInstrInfo &tii) :
|
||||
/// instruction. Currently returns NoHazard.
|
||||
///
|
||||
/// \return NoHazard
|
||||
HazardRecognizer::HazardType
|
||||
SPUHazardRecognizer::getHazardType(SDNode *Node)
|
||||
ScheduleHazardRecognizer::HazardType
|
||||
SPUHazardRecognizer::getHazardType(SUnit *SU)
|
||||
{
|
||||
// Initial thoughts on how to do this, but this code cannot work unless the
|
||||
// function's prolog and epilog code are also being scheduled so that we can
|
||||
// accurately determine which pipeline is being scheduled.
|
||||
#if 0
|
||||
HazardRecognizer::HazardType retval = NoHazard;
|
||||
const SDNode *Node = SU->getNode()->getFlaggedMachineNode();
|
||||
ScheduleHazardRecognizer::HazardType retval = NoHazard;
|
||||
bool mustBeOdd = false;
|
||||
|
||||
switch (Node->getOpcode()) {
|
||||
@ -120,7 +123,7 @@ SPUHazardRecognizer::getHazardType(SDNode *Node)
|
||||
#endif
|
||||
}
|
||||
|
||||
void SPUHazardRecognizer::EmitInstruction(SDNode *Node)
|
||||
void SPUHazardRecognizer::EmitInstruction(SUnit *SU)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -15,13 +15,14 @@
|
||||
#ifndef SPUHAZRECS_H
|
||||
#define SPUHAZRECS_H
|
||||
|
||||
#include "llvm/CodeGen/ScheduleDAGSDNodes.h"
|
||||
#include "SPUInstrInfo.h"
|
||||
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class TargetInstrInfo;
|
||||
|
||||
/// SPUHazardRecognizer
|
||||
class SPUHazardRecognizer : public HazardRecognizer
|
||||
class SPUHazardRecognizer : public ScheduleHazardRecognizer
|
||||
{
|
||||
private:
|
||||
const TargetInstrInfo &TII;
|
||||
@ -29,8 +30,8 @@ private:
|
||||
|
||||
public:
|
||||
SPUHazardRecognizer(const TargetInstrInfo &TII);
|
||||
virtual HazardType getHazardType(SDNode *Node);
|
||||
virtual void EmitInstruction(SDNode *Node);
|
||||
virtual HazardType getHazardType(SUnit *SU);
|
||||
virtual void EmitInstruction(SUnit *SU);
|
||||
virtual void AdvanceCycle();
|
||||
virtual void EmitNoop();
|
||||
};
|
||||
@ -38,4 +39,3 @@ public:
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -353,7 +353,7 @@ public:
|
||||
|
||||
/// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
|
||||
/// this target when scheduling the DAG.
|
||||
virtual HazardRecognizer *CreateTargetHazardRecognizer() {
|
||||
virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer() {
|
||||
const TargetInstrInfo *II = TM.getInstrInfo();
|
||||
assert(II && "No InstrInfo?");
|
||||
return new SPUHazardRecognizer(*II);
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "PPCHazardRecognizers.h"
|
||||
#include "PPC.h"
|
||||
#include "PPCInstrInfo.h"
|
||||
#include "llvm/CodeGen/ScheduleDAG.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
using namespace llvm;
|
||||
|
||||
@ -118,8 +119,9 @@ isLoadOfStoredAddress(unsigned LoadSize, SDValue Ptr1, SDValue Ptr2) const {
|
||||
/// terminate terminate the dispatch group. We turn NoopHazard for any
|
||||
/// instructions that wouldn't terminate the dispatch group that would cause a
|
||||
/// pipeline flush.
|
||||
HazardRecognizer::HazardType PPCHazardRecognizer970::
|
||||
getHazardType(SDNode *Node) {
|
||||
ScheduleHazardRecognizer::HazardType PPCHazardRecognizer970::
|
||||
getHazardType(SUnit *SU) {
|
||||
const SDNode *Node = SU->getNode()->getFlaggedMachineNode();
|
||||
bool isFirst, isSingle, isCracked, isLoad, isStore;
|
||||
PPCII::PPC970_Unit InstrType =
|
||||
GetInstrType(Node->getOpcode(), isFirst, isSingle, isCracked,
|
||||
@ -217,7 +219,8 @@ getHazardType(SDNode *Node) {
|
||||
return NoHazard;
|
||||
}
|
||||
|
||||
void PPCHazardRecognizer970::EmitInstruction(SDNode *Node) {
|
||||
void PPCHazardRecognizer970::EmitInstruction(SUnit *SU) {
|
||||
const SDNode *Node = SU->getNode()->getFlaggedMachineNode();
|
||||
bool isFirst, isSingle, isCracked, isLoad, isStore;
|
||||
PPCII::PPC970_Unit InstrType =
|
||||
GetInstrType(Node->getOpcode(), isFirst, isSingle, isCracked,
|
||||
|
@ -14,7 +14,8 @@
|
||||
#ifndef PPCHAZRECS_H
|
||||
#define PPCHAZRECS_H
|
||||
|
||||
#include "llvm/CodeGen/ScheduleDAGSDNodes.h"
|
||||
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
|
||||
#include "llvm/CodeGen/SelectionDAGNodes.h"
|
||||
#include "PPCInstrInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
@ -25,7 +26,7 @@ namespace llvm {
|
||||
/// avoid structural hazards that cause significant performance penalties (e.g.
|
||||
/// setting the CTR register then branching through it within a dispatch group),
|
||||
/// or storing then loading from the same address within a dispatch group.
|
||||
class PPCHazardRecognizer970 : public HazardRecognizer {
|
||||
class PPCHazardRecognizer970 : public ScheduleHazardRecognizer {
|
||||
const TargetInstrInfo &TII;
|
||||
|
||||
unsigned NumIssued; // Number of insts issued, including advanced cycles.
|
||||
@ -47,8 +48,8 @@ class PPCHazardRecognizer970 : public HazardRecognizer {
|
||||
|
||||
public:
|
||||
PPCHazardRecognizer970(const TargetInstrInfo &TII);
|
||||
virtual HazardType getHazardType(SDNode *Node);
|
||||
virtual void EmitInstruction(SDNode *Node);
|
||||
virtual HazardType getHazardType(SUnit *SU);
|
||||
virtual void EmitInstruction(SUnit *SU);
|
||||
virtual void AdvanceCycle();
|
||||
virtual void EmitNoop();
|
||||
|
||||
|
@ -181,7 +181,7 @@ namespace {
|
||||
|
||||
/// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
|
||||
/// this target when scheduling the DAG.
|
||||
virtual HazardRecognizer *CreateTargetHazardRecognizer() {
|
||||
virtual ScheduleHazardRecognizer *CreateTargetHazardRecognizer() {
|
||||
// Should use subtarget info to pick the right hazard recognizer. For
|
||||
// now, always return a PPC970 recognizer.
|
||||
const TargetInstrInfo *II = TM.getInstrInfo();
|
||||
|
Loading…
x
Reference in New Issue
Block a user