diff options
| author | David Goodwin <david_goodwin@apple.com> | 2009-11-03 20:15:00 +0000 |
|---|---|---|
| committer | David Goodwin <david_goodwin@apple.com> | 2009-11-03 20:15:00 +0000 |
| commit | a86f919763938395cb77a1a92fc0a4d75b52675d (patch) | |
| tree | fa6a9e9838e18c8f4f46090f6d492e71a6fa4f86 /llvm/lib | |
| parent | 5cd73a34707725ddea3dbed61b61af503c89e6e3 (diff) | |
| download | bcm5719-llvm-a86f919763938395cb77a1a92fc0a4d75b52675d.tar.gz bcm5719-llvm-a86f919763938395cb77a1a92fc0a4d75b52675d.zip | |
<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
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/ScheduleDAGInstrs.cpp | 58 |
1 files changed, 43 insertions, 15 deletions
diff --git a/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp b/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp index a65e8a006db..6070ff6ed19 100644 --- a/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp +++ b/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp @@ -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); } } |

