Allow targets more controls on what nodes are scheduled by reg pressure, what for latency in hybrid mode.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104293 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2010-05-20 23:26:43 +00:00
parent 0fe46d9b48
commit 1cc3984148
8 changed files with 52 additions and 16 deletions

View File

@ -16,6 +16,7 @@
#define LLVM_CODEGEN_SCHEDULEDAG_H
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/GraphTraits.h"
@ -238,7 +239,7 @@ namespace llvm {
typedef SmallVector<SDep, 4>::iterator succ_iterator;
typedef SmallVector<SDep, 4>::const_iterator const_pred_iterator;
typedef SmallVector<SDep, 4>::const_iterator const_succ_iterator;
unsigned NodeNum; // Entry # of node in the node vector.
unsigned NodeQueueId; // Queue id of node.
unsigned short Latency; // Node latency.
@ -255,6 +256,7 @@ namespace llvm {
bool isScheduled : 1; // True once scheduled.
bool isScheduleHigh : 1; // True if preferable to schedule high.
bool isCloned : 1; // True if this node has been cloned.
Sched::Preference SchedulingPref; // Scheduling preference.
SmallVector<MachineInstr*, 4> DbgInstrList; // dbg_values referencing this.
private:
@ -275,6 +277,7 @@ namespace llvm {
hasPhysRegDefs(false), hasPhysRegClobbers(false),
isPending(false), isAvailable(false), isScheduled(false),
isScheduleHigh(false), isCloned(false),
SchedulingPref(Sched::None),
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
CopyDstRC(NULL), CopySrcRC(NULL) {}
@ -287,6 +290,7 @@ namespace llvm {
hasPhysRegDefs(false), hasPhysRegClobbers(false),
isPending(false), isAvailable(false), isScheduled(false),
isScheduleHigh(false), isCloned(false),
SchedulingPref(Sched::None),
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
CopyDstRC(NULL), CopySrcRC(NULL) {}
@ -298,6 +302,7 @@ namespace llvm {
hasPhysRegDefs(false), hasPhysRegClobbers(false),
isPending(false), isAvailable(false), isScheduled(false),
isScheduleHigh(false), isCloned(false),
SchedulingPref(Sched::None),
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
CopyDstRC(NULL), CopySrcRC(NULL) {}
@ -390,7 +395,7 @@ namespace llvm {
return true;
return false;
}
void dump(const ScheduleDAG *G) const;
void dumpAll(const ScheduleDAG *G) const;
void print(raw_ostream &O, const ScheduleDAG *G) const;

View File

@ -149,6 +149,13 @@ public:
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
/// specified value type.
virtual TargetRegisterClass *getRegClassFor(EVT VT) const {

View File

@ -72,6 +72,7 @@ namespace CodeGenOpt {
namespace Sched {
enum Preference {
None, // No preference
Latency, // Scheduling for shortest total latency.
RegPressure, // Scheduling for lowest register pressure.
Hybrid // Scheduling for both latency and register pressure.

View File

@ -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 LStall = SPQ->getCurCycle() < left->getHeight();
bool RStall = SPQ->getCurCycle() < right->getHeight();
bool LStall = left->SchedulingPref == Sched::Latency &&
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 either one of the node will cause a pipeline stall, sort them
// according to their height.

View File

@ -19,6 +19,7 @@
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetSubtarget.h"
#include "llvm/ADT/DenseMap.h"
@ -44,6 +45,24 @@ void ScheduleDAGSDNodes::Run(SelectionDAG *dag, MachineBasicBlock *bb,
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 *SU = NewSUnit(Old->getNode());
SU->OrigNode = Old->OrigNode;
@ -52,6 +71,7 @@ SUnit *ScheduleDAGSDNodes::Clone(SUnit *Old) {
SU->isCommutable = Old->isCommutable;
SU->hasPhysRegDefs = Old->hasPhysRegDefs;
SU->hasPhysRegClobbers = Old->hasPhysRegClobbers;
SU->SchedulingPref = Old->SchedulingPref;
Old->isCloned = true;
return SU;
}

View File

@ -66,18 +66,7 @@ namespace llvm {
/// NewSUnit - Creates a new SUnit and return a ptr to it.
///
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();
}
SUnit *NewSUnit(SDNode *N);
/// Clone - Creates a clone of the specified SUnit. It does not copy the
/// predecessors / successors info nor the temporary scheduling states.

View File

@ -466,6 +466,7 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
setTargetDAGCombine(ISD::MUL);
setStackPointerRegisterToSaveRestore(ARM::SP);
setSchedulingPreference(Sched::RegPressure);
// 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;
}
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
//===----------------------------------------------------------------------===//

View File

@ -247,6 +247,8 @@ namespace llvm {
/// getFunctionAlignment - Return the Log2 alignment of this function.
virtual unsigned getFunctionAlignment(const Function *F) const;
Sched::Preference getSchedulingPreference(SDNode *N) const;
bool isShuffleMaskLegal(const SmallVectorImpl<int> &M, EVT VT) const;
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;