mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-25 13:24:46 +00:00
Be careful about scheduling nodes above previous calls. It increase usages of
more callee-saved registers and introduce copies. Only allows it if scheduling a node above calls would end up lessen register pressure. Call operands also has added ABI restrictions for register allocation, so be extra careful with hoisting them above calls. rdar://9329627 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@130245 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -1732,7 +1732,17 @@ unsigned RegReductionPQBase::getNodePriority(const SUnit *SU) const {
|
||||
// If SU does not have a register def, schedule it close to its uses
|
||||
// because it does not lengthen any live ranges.
|
||||
return 0;
|
||||
#if 1
|
||||
return SethiUllmanNumbers[SU->NodeNum];
|
||||
#else
|
||||
unsigned Priority = SethiUllmanNumbers[SU->NodeNum];
|
||||
if (SU->isCallOp) {
|
||||
// FIXME: This assumes all of the defs are used as call operands.
|
||||
int NP = (int)Priority - SU->getNode()->getNumValues();
|
||||
return (NP > 0) ? NP : 0;
|
||||
}
|
||||
return Priority;
|
||||
#endif
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -2238,11 +2248,35 @@ static bool BURRSort(SUnit *left, SUnit *right, RegReductionPQBase *SPQ) {
|
||||
// Prioritize by Sethi-Ulmann number and push CopyToReg nodes down.
|
||||
unsigned LPriority = SPQ->getNodePriority(left);
|
||||
unsigned RPriority = SPQ->getNodePriority(right);
|
||||
|
||||
// Be really careful about hoisting call operands above previous calls.
|
||||
// Only allows it if it would reduce register pressure.
|
||||
if (left->isCall && right->isCallOp) {
|
||||
unsigned RNumVals = right->getNode()->getNumValues();
|
||||
RPriority = (RPriority > RNumVals) ? (RPriority - RNumVals) : 0;
|
||||
}
|
||||
if (right->isCall && left->isCallOp) {
|
||||
unsigned LNumVals = left->getNode()->getNumValues();
|
||||
LPriority = (LPriority > LNumVals) ? (LPriority - LNumVals) : 0;
|
||||
}
|
||||
|
||||
if (LPriority != RPriority) {
|
||||
DEBUG(++FactorCount[FactStatic]);
|
||||
return LPriority > RPriority;
|
||||
}
|
||||
|
||||
// One or both of the nodes are calls and their sethi-ullman numbers are the
|
||||
// same, then keep source order.
|
||||
if (left->isCall || right->isCall) {
|
||||
unsigned LOrder = SPQ->getNodeOrdering(left);
|
||||
unsigned ROrder = SPQ->getNodeOrdering(right);
|
||||
|
||||
// Prefer an ordering where the lower the non-zero order number, the higher
|
||||
// the preference.
|
||||
if ((LOrder || ROrder) && LOrder != ROrder)
|
||||
return LOrder != 0 && (LOrder < ROrder || ROrder == 0);
|
||||
}
|
||||
|
||||
// Try schedule def + use closer when Sethi-Ullman numbers are the same.
|
||||
// e.g.
|
||||
// t1 = op t2, c1
|
||||
@@ -2275,7 +2309,14 @@ static bool BURRSort(SUnit *left, SUnit *right, RegReductionPQBase *SPQ) {
|
||||
return LScratch > RScratch;
|
||||
}
|
||||
|
||||
if (!DisableSchedCycles) {
|
||||
// Comparing latency against a call makes little sense unless the node
|
||||
// is register pressure-neutral.
|
||||
if ((left->isCall && RPriority > 0) || (right->isCall && LPriority > 0))
|
||||
return (left->NodeQueueId > right->NodeQueueId);
|
||||
|
||||
// Do not compare latencies when one or both of the nodes are calls.
|
||||
if (!DisableSchedCycles &&
|
||||
!(left->isCall || right->isCall)) {
|
||||
int result = BUCompareLatency(left, right, false /*checkPref*/, SPQ);
|
||||
if (result != 0)
|
||||
return result > 0;
|
||||
|
@@ -83,6 +83,7 @@ SUnit *ScheduleDAGSDNodes::Clone(SUnit *Old) {
|
||||
SU->Latency = Old->Latency;
|
||||
SU->isVRegCycle = Old->isVRegCycle;
|
||||
SU->isCall = Old->isCall;
|
||||
SU->isCallOp = Old->isCallOp;
|
||||
SU->isTwoAddress = Old->isTwoAddress;
|
||||
SU->isCommutable = Old->isCommutable;
|
||||
SU->hasPhysRegDefs = Old->hasPhysRegDefs;
|
||||
@@ -285,6 +286,7 @@ void ScheduleDAGSDNodes::BuildSchedUnits() {
|
||||
Worklist.push_back(DAG->getRoot().getNode());
|
||||
Visited.insert(DAG->getRoot().getNode());
|
||||
|
||||
SmallVector<SUnit*, 8> CallSUnits;
|
||||
while (!Worklist.empty()) {
|
||||
SDNode *NI = Worklist.pop_back_val();
|
||||
|
||||
@@ -337,6 +339,9 @@ void ScheduleDAGSDNodes::BuildSchedUnits() {
|
||||
if (!HasGlueUse) break;
|
||||
}
|
||||
|
||||
if (NodeSUnit->isCall)
|
||||
CallSUnits.push_back(NodeSUnit);
|
||||
|
||||
// Schedule zero-latency TokenFactor below any nodes that may increase the
|
||||
// schedule height. Otherwise, ancestors of the TokenFactor may appear to
|
||||
// have false stalls.
|
||||
@@ -356,6 +361,20 @@ void ScheduleDAGSDNodes::BuildSchedUnits() {
|
||||
// Assign the Latency field of NodeSUnit using target-provided information.
|
||||
ComputeLatency(NodeSUnit);
|
||||
}
|
||||
|
||||
// Find all call operands.
|
||||
while (!CallSUnits.empty()) {
|
||||
SUnit *SU = CallSUnits.pop_back_val();
|
||||
for (const SDNode *SUNode = SU->getNode(); SUNode;
|
||||
SUNode = SUNode->getGluedNode()) {
|
||||
if (SUNode->getOpcode() != ISD::CopyToReg)
|
||||
continue;
|
||||
SDNode *SrcN = SUNode->getOperand(2).getNode();
|
||||
if (isPassiveNode(SrcN)) continue; // Not scheduled.
|
||||
SUnit *SrcSU = &SUnits[SrcN->getNodeId()];
|
||||
SrcSU->isCallOp = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScheduleDAGSDNodes::AddSchedEdges() {
|
||||
|
Reference in New Issue
Block a user