mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-04 21:31:03 +00:00
Chain dependencies used to enforce memory order should have latency of 0 (except for true dependency of Store followed by aliased Load... we estimate that case with a single cycle of latency assuming the hardware will bypass)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85807 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
28989a8ddc
commit
7c9b1ac507
@ -317,29 +317,35 @@ void ScheduleDAGInstrs::BuildSchedGraph(AliasAnalysis *AA) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add chain dependencies.
|
// Add chain dependencies.
|
||||||
|
// Chain dependencies used to enforce memory order should have
|
||||||
|
// latency of 0 (except for true dependency of Store followed by
|
||||||
|
// aliased Load... we estimate that with a single cycle of latency
|
||||||
|
// assuming the hardware will bypass)
|
||||||
// Note that isStoreToStackSlot and isLoadFromStackSLot are not usable
|
// Note that isStoreToStackSlot and isLoadFromStackSLot are not usable
|
||||||
// after stack slots are lowered to actual addresses.
|
// after stack slots are lowered to actual addresses.
|
||||||
// TODO: Use an AliasAnalysis and do real alias-analysis queries, and
|
// TODO: Use an AliasAnalysis and do real alias-analysis queries, and
|
||||||
// produce more precise dependence information.
|
// produce more precise dependence information.
|
||||||
|
#define STORE_LOAD_LATENCY 1
|
||||||
|
unsigned TrueMemOrderLatency = 0;
|
||||||
if (TID.isCall() || TID.hasUnmodeledSideEffects()) {
|
if (TID.isCall() || TID.hasUnmodeledSideEffects()) {
|
||||||
new_chain:
|
new_chain:
|
||||||
// This is the conservative case. Add dependencies on all memory
|
// This is the conservative case. Add dependencies on all memory
|
||||||
// references.
|
// references.
|
||||||
if (Chain)
|
if (Chain)
|
||||||
Chain->addPred(SDep(SU, SDep::Order, SU->Latency));
|
Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0));
|
||||||
Chain = SU;
|
Chain = SU;
|
||||||
for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k)
|
for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k)
|
||||||
PendingLoads[k]->addPred(SDep(SU, SDep::Order, SU->Latency));
|
PendingLoads[k]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency));
|
||||||
PendingLoads.clear();
|
PendingLoads.clear();
|
||||||
for (std::map<const Value *, SUnit *>::iterator I = MemDefs.begin(),
|
for (std::map<const Value *, SUnit *>::iterator I = MemDefs.begin(),
|
||||||
E = MemDefs.end(); I != E; ++I) {
|
E = MemDefs.end(); I != E; ++I) {
|
||||||
I->second->addPred(SDep(SU, SDep::Order, SU->Latency));
|
I->second->addPred(SDep(SU, SDep::Order, /*Latency=*/0));
|
||||||
I->second = SU;
|
I->second = SU;
|
||||||
}
|
}
|
||||||
for (std::map<const Value *, std::vector<SUnit *> >::iterator I =
|
for (std::map<const Value *, std::vector<SUnit *> >::iterator I =
|
||||||
MemUses.begin(), E = MemUses.end(); I != E; ++I) {
|
MemUses.begin(), E = MemUses.end(); I != E; ++I) {
|
||||||
for (unsigned i = 0, e = I->second.size(); i != e; ++i)
|
for (unsigned i = 0, e = I->second.size(); i != e; ++i)
|
||||||
I->second[i]->addPred(SDep(SU, SDep::Order, SU->Latency));
|
I->second[i]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency));
|
||||||
I->second.clear();
|
I->second.clear();
|
||||||
}
|
}
|
||||||
// See if it is known to just have a single memory reference.
|
// See if it is known to just have a single memory reference.
|
||||||
@ -356,12 +362,13 @@ void ScheduleDAGInstrs::BuildSchedGraph(AliasAnalysis *AA) {
|
|||||||
// Unknown memory accesses. Assume the worst.
|
// Unknown memory accesses. Assume the worst.
|
||||||
ChainMMO = 0;
|
ChainMMO = 0;
|
||||||
} else if (TID.mayStore()) {
|
} else if (TID.mayStore()) {
|
||||||
|
TrueMemOrderLatency = STORE_LOAD_LATENCY;
|
||||||
if (const Value *V = getUnderlyingObjectForInstr(MI, MFI)) {
|
if (const Value *V = getUnderlyingObjectForInstr(MI, MFI)) {
|
||||||
// A store to a specific PseudoSourceValue. Add precise dependencies.
|
// A store to a specific PseudoSourceValue. Add precise dependencies.
|
||||||
// Handle the def in MemDefs, if there is one.
|
// Handle the def in MemDefs, if there is one.
|
||||||
std::map<const Value *, SUnit *>::iterator I = MemDefs.find(V);
|
std::map<const Value *, SUnit *>::iterator I = MemDefs.find(V);
|
||||||
if (I != MemDefs.end()) {
|
if (I != MemDefs.end()) {
|
||||||
I->second->addPred(SDep(SU, SDep::Order, SU->Latency, /*Reg=*/0,
|
I->second->addPred(SDep(SU, SDep::Order, /*Latency=*/0, /*Reg=*/0,
|
||||||
/*isNormalMemory=*/true));
|
/*isNormalMemory=*/true));
|
||||||
I->second = SU;
|
I->second = SU;
|
||||||
} else {
|
} else {
|
||||||
@ -372,35 +379,37 @@ void ScheduleDAGInstrs::BuildSchedGraph(AliasAnalysis *AA) {
|
|||||||
MemUses.find(V);
|
MemUses.find(V);
|
||||||
if (J != MemUses.end()) {
|
if (J != MemUses.end()) {
|
||||||
for (unsigned i = 0, e = J->second.size(); i != e; ++i)
|
for (unsigned i = 0, e = J->second.size(); i != e; ++i)
|
||||||
J->second[i]->addPred(SDep(SU, SDep::Order, SU->Latency, /*Reg=*/0,
|
J->second[i]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency,
|
||||||
/*isNormalMemory=*/true));
|
/*Reg=*/0, /*isNormalMemory=*/true));
|
||||||
J->second.clear();
|
J->second.clear();
|
||||||
}
|
}
|
||||||
// Add dependencies from all the PendingLoads, since without
|
// Add dependencies from all the PendingLoads, since without
|
||||||
// memoperands we must assume they alias anything.
|
// memoperands we must assume they alias anything.
|
||||||
for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k)
|
for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k)
|
||||||
PendingLoads[k]->addPred(SDep(SU, SDep::Order, SU->Latency));
|
PendingLoads[k]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency));
|
||||||
// Add a general dependence too, if needed.
|
// Add a general dependence too, if needed.
|
||||||
if (Chain)
|
if (Chain)
|
||||||
Chain->addPred(SDep(SU, SDep::Order, SU->Latency));
|
Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0));
|
||||||
} else
|
} else {
|
||||||
// Treat all other stores conservatively.
|
// Treat all other stores conservatively.
|
||||||
goto new_chain;
|
goto new_chain;
|
||||||
|
}
|
||||||
} else if (TID.mayLoad()) {
|
} else if (TID.mayLoad()) {
|
||||||
|
TrueMemOrderLatency = 0;
|
||||||
if (MI->isInvariantLoad(AA)) {
|
if (MI->isInvariantLoad(AA)) {
|
||||||
// Invariant load, no chain dependencies needed!
|
// Invariant load, no chain dependencies needed!
|
||||||
} else if (const Value *V = getUnderlyingObjectForInstr(MI, MFI)) {
|
} else if (const Value *V = getUnderlyingObjectForInstr(MI, MFI)) {
|
||||||
// A load from a specific PseudoSourceValue. Add precise dependencies.
|
// A load from a specific PseudoSourceValue. Add precise dependencies.
|
||||||
std::map<const Value *, SUnit *>::iterator I = MemDefs.find(V);
|
std::map<const Value *, SUnit *>::iterator I = MemDefs.find(V);
|
||||||
if (I != MemDefs.end())
|
if (I != MemDefs.end())
|
||||||
I->second->addPred(SDep(SU, SDep::Order, SU->Latency, /*Reg=*/0,
|
I->second->addPred(SDep(SU, SDep::Order, /*Latency=*/0, /*Reg=*/0,
|
||||||
/*isNormalMemory=*/true));
|
/*isNormalMemory=*/true));
|
||||||
MemUses[V].push_back(SU);
|
MemUses[V].push_back(SU);
|
||||||
|
|
||||||
// Add a general dependence too, if needed.
|
// Add a general dependence too, if needed.
|
||||||
if (Chain && (!ChainMMO ||
|
if (Chain && (!ChainMMO ||
|
||||||
(ChainMMO->isStore() || ChainMMO->isVolatile())))
|
(ChainMMO->isStore() || ChainMMO->isVolatile())))
|
||||||
Chain->addPred(SDep(SU, SDep::Order, SU->Latency));
|
Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0));
|
||||||
} else if (MI->hasVolatileMemoryRef()) {
|
} else if (MI->hasVolatileMemoryRef()) {
|
||||||
// Treat volatile loads conservatively. Note that this includes
|
// Treat volatile loads conservatively. Note that this includes
|
||||||
// cases where memoperand information is unavailable.
|
// cases where memoperand information is unavailable.
|
||||||
@ -411,10 +420,10 @@ void ScheduleDAGInstrs::BuildSchedGraph(AliasAnalysis *AA) {
|
|||||||
// we can't even assume that the load doesn't alias well-behaved
|
// we can't even assume that the load doesn't alias well-behaved
|
||||||
// memory locations.
|
// memory locations.
|
||||||
if (Chain)
|
if (Chain)
|
||||||
Chain->addPred(SDep(SU, SDep::Order, SU->Latency));
|
Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0));
|
||||||
for (std::map<const Value *, SUnit *>::iterator I = MemDefs.begin(),
|
for (std::map<const Value *, SUnit *>::iterator I = MemDefs.begin(),
|
||||||
E = MemDefs.end(); I != E; ++I)
|
E = MemDefs.end(); I != E; ++I)
|
||||||
I->second->addPred(SDep(SU, SDep::Order, SU->Latency));
|
I->second->addPred(SDep(SU, SDep::Order, /*Latency=*/0));
|
||||||
PendingLoads.push_back(SU);
|
PendingLoads.push_back(SU);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user