+ for (std::map<const Value *, SUnit *>::iterator I = MemDefs.begin(),
+ E = MemDefs.end(); I != E; ++I) {
+ I->second->addPred(SDep(SU, SDep::Order, SU->Latency));
+ I->second = SU;
+ }
+ for (std::map<const Value *, std::vector<SUnit *> >::iterator I =
+ MemUses.begin(), E = MemUses.end(); 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.clear();
+ }
+ // See if it is known to just have a single memory reference.
+ MachineInstr *ChainMI = Chain->getInstr();
+ const TargetInstrDesc &ChainTID = ChainMI->getDesc();
+ if (!ChainTID.isCall() &&
+ !ChainTID.hasUnmodeledSideEffects() &&
+ ChainMI->hasOneMemOperand() &&
+ !(*ChainMI->memoperands_begin())->isVolatile() &&
+ (*ChainMI->memoperands_begin())->getValue())
+ // We know that the Chain accesses one specific memory location.
+ ChainMMO = *ChainMI->memoperands_begin();
+ else
+ // Unknown memory accesses. Assume the worst.
+ ChainMMO = 0;
+ } else if (TID.mayStore()) {
+ if (const Value *V = getUnderlyingObjectForInstr(MI, MFI)) {
+ // 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);
+ if (I != MemDefs.end()) {
+ I->second->addPred(SDep(SU, SDep::Order, SU->Latency, /*Reg=*/0,
+ /*isNormalMemory=*/true));
+ I->second = SU;
+ } else {
+ MemDefs[V] = SU;
+ }
+ // Handle the uses in MemUses, if there are any.
+ std::map<const Value *, std::vector<SUnit *> >::iterator J =
+ MemUses.find(V);
+ if (J != MemUses.end()) {
+ for (unsigned i = 0, e = J->second.size(); i != e; ++i)
+ J->second[i]->addPred(SDep(SU, SDep::Order, SU->Latency, /*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, SU->Latency));
+ // Add a general dependence too, if needed.
+ if (Chain)
+ Chain->addPred(SDep(SU, SDep::Order, SU->Latency));
+ } else
+ // Treat all other stores conservatively.
+ goto new_chain;
+ } else if (TID.mayLoad()) {
+ if (MI->isInvariantLoad(AA)) {
+ // Invariant load, no chain dependencies needed!
+ } else if (const Value *V = getUnderlyingObjectForInstr(MI, MFI)) {
+ // A load from a specific PseudoSourceValue. Add precise dependencies.
+ std::map<const Value *, SUnit *>::iterator I = MemDefs.find(V);
+ if (I != MemDefs.end())
+ I->second->addPred(SDep(SU, SDep::Order, SU->Latency, /*Reg=*/0,
+ /*isNormalMemory=*/true));
+ MemUses[V].push_back(SU);
+
+ // Add a general dependence too, if needed.
+ if (Chain && (!ChainMMO ||
+ (ChainMMO->isStore() || ChainMMO->isVolatile())))
+ Chain->addPred(SDep(SU, SDep::Order, SU->Latency));
+ } else if (MI->hasVolatileMemoryRef()) {
+ // 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
+ // 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, SU->Latency));
+ for (std::map<const Value *, SUnit *>::iterator I = MemDefs.begin(),
+ E = MemDefs.end(); I != E; ++I)
+ I->second->addPred(SDep(SU, SDep::Order, SU->Latency));
+ PendingLoads.push_back(SU);
+ }