forked from OSchip/llvm-project
<rdar://problem/7352605>. When building schedule graph use mayAlias information to avoid chaining loads/stores of spill slots with non-aliased memory ops.
llvm-svn: 85934
This commit is contained in:
parent
5cd73a3470
commit
a86f919763
|
@ -98,7 +98,9 @@ static const Value *getUnderlyingObject(const Value *V) {
|
|||
/// information and it can be tracked to a normal reference to a known
|
||||
/// object, return the Value for that object. Otherwise return null.
|
||||
static const Value *getUnderlyingObjectForInstr(const MachineInstr *MI,
|
||||
const MachineFrameInfo *MFI) {
|
||||
const MachineFrameInfo *MFI,
|
||||
bool &MayAlias) {
|
||||
MayAlias = true;
|
||||
if (!MI->hasOneMemOperand() ||
|
||||
!(*MI->memoperands_begin())->getValue() ||
|
||||
(*MI->memoperands_begin())->isVolatile())
|
||||
|
@ -110,6 +112,7 @@ static const Value *getUnderlyingObjectForInstr(const MachineInstr *MI,
|
|||
|
||||
V = getUnderlyingObject(V);
|
||||
if (const PseudoSourceValue *PSV = dyn_cast<PseudoSourceValue>(V)) {
|
||||
MayAlias = PSV->mayAlias(MFI);
|
||||
// For now, ignore PseudoSourceValues which may alias LLVM IR values
|
||||
// because the code that uses this function has no way to cope with
|
||||
// such aliases.
|
||||
|
@ -124,6 +127,23 @@ static const Value *getUnderlyingObjectForInstr(const MachineInstr *MI,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool mayUnderlyingObjectForInstrAlias(const MachineInstr *MI,
|
||||
const MachineFrameInfo *MFI) {
|
||||
if (!MI->hasOneMemOperand() ||
|
||||
!(*MI->memoperands_begin())->getValue() ||
|
||||
(*MI->memoperands_begin())->isVolatile())
|
||||
return true;
|
||||
|
||||
const Value *V = (*MI->memoperands_begin())->getValue();
|
||||
if (!V)
|
||||
return true;
|
||||
|
||||
V = getUnderlyingObject(V);
|
||||
if (const PseudoSourceValue *PSV = dyn_cast<PseudoSourceValue>(V))
|
||||
return PSV->mayAlias(MFI);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScheduleDAGInstrs::StartBlock(MachineBasicBlock *BB) {
|
||||
if (MachineLoop *ML = MLI.getLoopFor(BB))
|
||||
if (BB == ML->getLoopLatch()) {
|
||||
|
@ -362,8 +382,9 @@ void ScheduleDAGInstrs::BuildSchedGraph(AliasAnalysis *AA) {
|
|||
// Unknown memory accesses. Assume the worst.
|
||||
ChainMMO = 0;
|
||||
} else if (TID.mayStore()) {
|
||||
bool MayAlias = true;
|
||||
TrueMemOrderLatency = STORE_LOAD_LATENCY;
|
||||
if (const Value *V = getUnderlyingObjectForInstr(MI, MFI)) {
|
||||
if (const Value *V = getUnderlyingObjectForInstr(MI, MFI, MayAlias)) {
|
||||
// A store to a specific PseudoSourceValue. Add precise dependencies.
|
||||
// Handle the def in MemDefs, if there is one.
|
||||
std::map<const Value *, SUnit *>::iterator I = MemDefs.find(V);
|
||||
|
@ -383,22 +404,26 @@ void ScheduleDAGInstrs::BuildSchedGraph(AliasAnalysis *AA) {
|
|||
/*Reg=*/0, /*isNormalMemory=*/true));
|
||||
J->second.clear();
|
||||
}
|
||||
// Add dependencies from all the PendingLoads, since without
|
||||
// memoperands we must assume they alias anything.
|
||||
for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k)
|
||||
PendingLoads[k]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency));
|
||||
// Add a general dependence too, if needed.
|
||||
if (Chain)
|
||||
Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0));
|
||||
} else {
|
||||
if (MayAlias) {
|
||||
// Add dependencies from all the PendingLoads, since without
|
||||
// memoperands we must assume they alias anything.
|
||||
for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k)
|
||||
PendingLoads[k]->addPred(SDep(SU, SDep::Order, TrueMemOrderLatency));
|
||||
// Add a general dependence too, if needed.
|
||||
if (Chain)
|
||||
Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0));
|
||||
}
|
||||
} else if (MayAlias) {
|
||||
// Treat all other stores conservatively.
|
||||
goto new_chain;
|
||||
}
|
||||
} else if (TID.mayLoad()) {
|
||||
bool MayAlias = true;
|
||||
TrueMemOrderLatency = 0;
|
||||
if (MI->isInvariantLoad(AA)) {
|
||||
// Invariant load, no chain dependencies needed!
|
||||
} else if (const Value *V = getUnderlyingObjectForInstr(MI, MFI)) {
|
||||
} else if (const Value *V =
|
||||
getUnderlyingObjectForInstr(MI, MFI, MayAlias)) {
|
||||
// A load from a specific PseudoSourceValue. Add precise dependencies.
|
||||
std::map<const Value *, SUnit *>::iterator I = MemDefs.find(V);
|
||||
if (I != MemDefs.end())
|
||||
|
@ -414,16 +439,19 @@ void ScheduleDAGInstrs::BuildSchedGraph(AliasAnalysis *AA) {
|
|||
// Treat volatile loads conservatively. Note that this includes
|
||||
// cases where memoperand information is unavailable.
|
||||
goto new_chain;
|
||||
} else {
|
||||
// A normal load. Depend on the general chain, as well as on
|
||||
} else if (MayAlias) {
|
||||
// A "MayAlias" load. Depend on the general chain, as well as on
|
||||
// all stores. In the absense of MachineMemOperand information,
|
||||
// we can't even assume that the load doesn't alias well-behaved
|
||||
// memory locations.
|
||||
if (Chain)
|
||||
Chain->addPred(SDep(SU, SDep::Order, /*Latency=*/0));
|
||||
for (std::map<const Value *, SUnit *>::iterator I = MemDefs.begin(),
|
||||
E = MemDefs.end(); I != E; ++I)
|
||||
I->second->addPred(SDep(SU, SDep::Order, /*Latency=*/0));
|
||||
E = MemDefs.end(); I != E; ++I) {
|
||||
SUnit *DefSU = I->second;
|
||||
if (mayUnderlyingObjectForInstrAlias(DefSU->getInstr(), MFI))
|
||||
DefSU->addPred(SDep(SU, SDep::Order, /*Latency=*/0));
|
||||
}
|
||||
PendingLoads.push_back(SU);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue