mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
Allow targets more controls on what nodes are scheduled by reg pressure, what for latency in hybrid mode.
llvm-svn: 104293
This commit is contained in:
parent
3274120902
commit
b5de7de4ce
@ -16,6 +16,7 @@
|
|||||||
#define LLVM_CODEGEN_SCHEDULEDAG_H
|
#define LLVM_CODEGEN_SCHEDULEDAG_H
|
||||||
|
|
||||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||||
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/BitVector.h"
|
#include "llvm/ADT/BitVector.h"
|
||||||
#include "llvm/ADT/GraphTraits.h"
|
#include "llvm/ADT/GraphTraits.h"
|
||||||
@ -238,7 +239,7 @@ namespace llvm {
|
|||||||
typedef SmallVector<SDep, 4>::iterator succ_iterator;
|
typedef SmallVector<SDep, 4>::iterator succ_iterator;
|
||||||
typedef SmallVector<SDep, 4>::const_iterator const_pred_iterator;
|
typedef SmallVector<SDep, 4>::const_iterator const_pred_iterator;
|
||||||
typedef SmallVector<SDep, 4>::const_iterator const_succ_iterator;
|
typedef SmallVector<SDep, 4>::const_iterator const_succ_iterator;
|
||||||
|
|
||||||
unsigned NodeNum; // Entry # of node in the node vector.
|
unsigned NodeNum; // Entry # of node in the node vector.
|
||||||
unsigned NodeQueueId; // Queue id of node.
|
unsigned NodeQueueId; // Queue id of node.
|
||||||
unsigned short Latency; // Node latency.
|
unsigned short Latency; // Node latency.
|
||||||
@ -255,6 +256,7 @@ namespace llvm {
|
|||||||
bool isScheduled : 1; // True once scheduled.
|
bool isScheduled : 1; // True once scheduled.
|
||||||
bool isScheduleHigh : 1; // True if preferable to schedule high.
|
bool isScheduleHigh : 1; // True if preferable to schedule high.
|
||||||
bool isCloned : 1; // True if this node has been cloned.
|
bool isCloned : 1; // True if this node has been cloned.
|
||||||
|
Sched::Preference SchedulingPref; // Scheduling preference.
|
||||||
|
|
||||||
SmallVector<MachineInstr*, 4> DbgInstrList; // dbg_values referencing this.
|
SmallVector<MachineInstr*, 4> DbgInstrList; // dbg_values referencing this.
|
||||||
private:
|
private:
|
||||||
@ -275,6 +277,7 @@ namespace llvm {
|
|||||||
hasPhysRegDefs(false), hasPhysRegClobbers(false),
|
hasPhysRegDefs(false), hasPhysRegClobbers(false),
|
||||||
isPending(false), isAvailable(false), isScheduled(false),
|
isPending(false), isAvailable(false), isScheduled(false),
|
||||||
isScheduleHigh(false), isCloned(false),
|
isScheduleHigh(false), isCloned(false),
|
||||||
|
SchedulingPref(Sched::None),
|
||||||
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
|
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
|
||||||
CopyDstRC(NULL), CopySrcRC(NULL) {}
|
CopyDstRC(NULL), CopySrcRC(NULL) {}
|
||||||
|
|
||||||
@ -287,6 +290,7 @@ namespace llvm {
|
|||||||
hasPhysRegDefs(false), hasPhysRegClobbers(false),
|
hasPhysRegDefs(false), hasPhysRegClobbers(false),
|
||||||
isPending(false), isAvailable(false), isScheduled(false),
|
isPending(false), isAvailable(false), isScheduled(false),
|
||||||
isScheduleHigh(false), isCloned(false),
|
isScheduleHigh(false), isCloned(false),
|
||||||
|
SchedulingPref(Sched::None),
|
||||||
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
|
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
|
||||||
CopyDstRC(NULL), CopySrcRC(NULL) {}
|
CopyDstRC(NULL), CopySrcRC(NULL) {}
|
||||||
|
|
||||||
@ -298,6 +302,7 @@ namespace llvm {
|
|||||||
hasPhysRegDefs(false), hasPhysRegClobbers(false),
|
hasPhysRegDefs(false), hasPhysRegClobbers(false),
|
||||||
isPending(false), isAvailable(false), isScheduled(false),
|
isPending(false), isAvailable(false), isScheduled(false),
|
||||||
isScheduleHigh(false), isCloned(false),
|
isScheduleHigh(false), isCloned(false),
|
||||||
|
SchedulingPref(Sched::None),
|
||||||
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
|
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
|
||||||
CopyDstRC(NULL), CopySrcRC(NULL) {}
|
CopyDstRC(NULL), CopySrcRC(NULL) {}
|
||||||
|
|
||||||
@ -390,7 +395,7 @@ namespace llvm {
|
|||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dump(const ScheduleDAG *G) const;
|
void dump(const ScheduleDAG *G) const;
|
||||||
void dumpAll(const ScheduleDAG *G) const;
|
void dumpAll(const ScheduleDAG *G) const;
|
||||||
void print(raw_ostream &O, const ScheduleDAG *G) const;
|
void print(raw_ostream &O, const ScheduleDAG *G) const;
|
||||||
|
@ -149,6 +149,13 @@ public:
|
|||||||
return SchedPreferenceInfo;
|
return SchedPreferenceInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// getSchedulingPreference - Some scheduler, e.g. hybrid, can switch to
|
||||||
|
/// different scheduling heuristics for different nodes. This function returns
|
||||||
|
/// the preference (or none) for the given node.
|
||||||
|
virtual Sched::Preference getSchedulingPreference(SDNode *N) const {
|
||||||
|
return Sched::None;
|
||||||
|
}
|
||||||
|
|
||||||
/// getRegClassFor - Return the register class that should be used for the
|
/// getRegClassFor - Return the register class that should be used for the
|
||||||
/// specified value type.
|
/// specified value type.
|
||||||
virtual TargetRegisterClass *getRegClassFor(EVT VT) const {
|
virtual TargetRegisterClass *getRegClassFor(EVT VT) const {
|
||||||
|
@ -72,6 +72,7 @@ namespace CodeGenOpt {
|
|||||||
|
|
||||||
namespace Sched {
|
namespace Sched {
|
||||||
enum Preference {
|
enum Preference {
|
||||||
|
None, // No preference
|
||||||
Latency, // Scheduling for shortest total latency.
|
Latency, // Scheduling for shortest total latency.
|
||||||
RegPressure, // Scheduling for lowest register pressure.
|
RegPressure, // Scheduling for lowest register pressure.
|
||||||
Hybrid // Scheduling for both latency and register pressure.
|
Hybrid // Scheduling for both latency and register pressure.
|
||||||
|
@ -1256,8 +1256,10 @@ bool src_ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool hybrid_ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const{
|
bool hybrid_ls_rr_sort::operator()(const SUnit *left, const SUnit *right) const{
|
||||||
bool LStall = SPQ->getCurCycle() < left->getHeight();
|
bool LStall = left->SchedulingPref == Sched::Latency &&
|
||||||
bool RStall = SPQ->getCurCycle() < right->getHeight();
|
SPQ->getCurCycle() < left->getHeight();
|
||||||
|
bool RStall = right->SchedulingPref == Sched::Latency &&
|
||||||
|
SPQ->getCurCycle() < right->getHeight();
|
||||||
// If scheduling one of the node will cause a pipeline stall, delay it.
|
// If scheduling one of the node will cause a pipeline stall, delay it.
|
||||||
// If scheduling either one of the node will cause a pipeline stall, sort them
|
// If scheduling either one of the node will cause a pipeline stall, sort them
|
||||||
// according to their height.
|
// according to their height.
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "llvm/CodeGen/SelectionDAG.h"
|
#include "llvm/CodeGen/SelectionDAG.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include "llvm/Target/TargetInstrInfo.h"
|
#include "llvm/Target/TargetInstrInfo.h"
|
||||||
|
#include "llvm/Target/TargetLowering.h"
|
||||||
#include "llvm/Target/TargetRegisterInfo.h"
|
#include "llvm/Target/TargetRegisterInfo.h"
|
||||||
#include "llvm/Target/TargetSubtarget.h"
|
#include "llvm/Target/TargetSubtarget.h"
|
||||||
#include "llvm/ADT/DenseMap.h"
|
#include "llvm/ADT/DenseMap.h"
|
||||||
@ -44,6 +45,24 @@ void ScheduleDAGSDNodes::Run(SelectionDAG *dag, MachineBasicBlock *bb,
|
|||||||
ScheduleDAG::Run(bb, insertPos);
|
ScheduleDAG::Run(bb, insertPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// NewSUnit - Creates a new SUnit and return a ptr to it.
|
||||||
|
///
|
||||||
|
SUnit *ScheduleDAGSDNodes::NewSUnit(SDNode *N) {
|
||||||
|
#ifndef NDEBUG
|
||||||
|
const SUnit *Addr = 0;
|
||||||
|
if (!SUnits.empty())
|
||||||
|
Addr = &SUnits[0];
|
||||||
|
#endif
|
||||||
|
SUnits.push_back(SUnit(N, (unsigned)SUnits.size()));
|
||||||
|
assert((Addr == 0 || Addr == &SUnits[0]) &&
|
||||||
|
"SUnits std::vector reallocated on the fly!");
|
||||||
|
SUnits.back().OrigNode = &SUnits.back();
|
||||||
|
SUnit *SU = &SUnits.back();
|
||||||
|
const TargetLowering &TLI = DAG->getTargetLoweringInfo();
|
||||||
|
SU->SchedulingPref = TLI.getSchedulingPreference(N);
|
||||||
|
return SU;
|
||||||
|
}
|
||||||
|
|
||||||
SUnit *ScheduleDAGSDNodes::Clone(SUnit *Old) {
|
SUnit *ScheduleDAGSDNodes::Clone(SUnit *Old) {
|
||||||
SUnit *SU = NewSUnit(Old->getNode());
|
SUnit *SU = NewSUnit(Old->getNode());
|
||||||
SU->OrigNode = Old->OrigNode;
|
SU->OrigNode = Old->OrigNode;
|
||||||
@ -52,6 +71,7 @@ SUnit *ScheduleDAGSDNodes::Clone(SUnit *Old) {
|
|||||||
SU->isCommutable = Old->isCommutable;
|
SU->isCommutable = Old->isCommutable;
|
||||||
SU->hasPhysRegDefs = Old->hasPhysRegDefs;
|
SU->hasPhysRegDefs = Old->hasPhysRegDefs;
|
||||||
SU->hasPhysRegClobbers = Old->hasPhysRegClobbers;
|
SU->hasPhysRegClobbers = Old->hasPhysRegClobbers;
|
||||||
|
SU->SchedulingPref = Old->SchedulingPref;
|
||||||
Old->isCloned = true;
|
Old->isCloned = true;
|
||||||
return SU;
|
return SU;
|
||||||
}
|
}
|
||||||
|
@ -66,18 +66,7 @@ namespace llvm {
|
|||||||
|
|
||||||
/// NewSUnit - Creates a new SUnit and return a ptr to it.
|
/// NewSUnit - Creates a new SUnit and return a ptr to it.
|
||||||
///
|
///
|
||||||
SUnit *NewSUnit(SDNode *N) {
|
SUnit *NewSUnit(SDNode *N);
|
||||||
#ifndef NDEBUG
|
|
||||||
const SUnit *Addr = 0;
|
|
||||||
if (!SUnits.empty())
|
|
||||||
Addr = &SUnits[0];
|
|
||||||
#endif
|
|
||||||
SUnits.push_back(SUnit(N, (unsigned)SUnits.size()));
|
|
||||||
assert((Addr == 0 || Addr == &SUnits[0]) &&
|
|
||||||
"SUnits std::vector reallocated on the fly!");
|
|
||||||
SUnits.back().OrigNode = &SUnits.back();
|
|
||||||
return &SUnits.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Clone - Creates a clone of the specified SUnit. It does not copy the
|
/// Clone - Creates a clone of the specified SUnit. It does not copy the
|
||||||
/// predecessors / successors info nor the temporary scheduling states.
|
/// predecessors / successors info nor the temporary scheduling states.
|
||||||
|
@ -466,6 +466,7 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
|
|||||||
setTargetDAGCombine(ISD::MUL);
|
setTargetDAGCombine(ISD::MUL);
|
||||||
|
|
||||||
setStackPointerRegisterToSaveRestore(ARM::SP);
|
setStackPointerRegisterToSaveRestore(ARM::SP);
|
||||||
|
|
||||||
setSchedulingPreference(Sched::RegPressure);
|
setSchedulingPreference(Sched::RegPressure);
|
||||||
|
|
||||||
// FIXME: If-converter should use instruction latency to determine
|
// FIXME: If-converter should use instruction latency to determine
|
||||||
@ -600,6 +601,15 @@ unsigned ARMTargetLowering::getFunctionAlignment(const Function *F) const {
|
|||||||
return getTargetMachine().getSubtarget<ARMSubtarget>().isThumb() ? 0 : 1;
|
return getTargetMachine().getSubtarget<ARMSubtarget>().isThumb() ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Sched::Preference ARMTargetLowering::getSchedulingPreference(SDNode *N) const {
|
||||||
|
for (unsigned i = 0, e = N->getNumValues(); i != e; ++i) {
|
||||||
|
EVT VT = N->getValueType(i);
|
||||||
|
if (VT.isFloatingPoint() || VT.isVector())
|
||||||
|
return Sched::Latency;
|
||||||
|
}
|
||||||
|
return Sched::RegPressure;
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Lowering Code
|
// Lowering Code
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -247,6 +247,8 @@ namespace llvm {
|
|||||||
/// getFunctionAlignment - Return the Log2 alignment of this function.
|
/// getFunctionAlignment - Return the Log2 alignment of this function.
|
||||||
virtual unsigned getFunctionAlignment(const Function *F) const;
|
virtual unsigned getFunctionAlignment(const Function *F) const;
|
||||||
|
|
||||||
|
Sched::Preference getSchedulingPreference(SDNode *N) const;
|
||||||
|
|
||||||
bool isShuffleMaskLegal(const SmallVectorImpl<int> &M, EVT VT) const;
|
bool isShuffleMaskLegal(const SmallVectorImpl<int> &M, EVT VT) const;
|
||||||
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
|
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user