cl::ZeroOrMore, cl::init(false),
cl::desc("Enable use of AA during MI GAD construction"));
+// FIXME: Enable the use of TBAA. There are two known issues preventing this:
+// 1. Stack coloring does not update TBAA when merging allocas
+// 2. CGP inserts ptrtoint/inttoptr pairs when sinking address computations.
+// Because BasicAA does not handle inttoptr, we'll often miss basic type
+// punning idioms that we need to catch so we don't miscompile real-world
+// code.
+static cl::opt<bool> UseTBAA("use-tbaa-in-sched-mi", cl::Hidden,
+ cl::init(false), cl::desc("Enable use of TBAA during MI GAD construction"));
+
ScheduleDAGInstrs::ScheduleDAGInstrs(MachineFunction &mf,
const MachineLoopInfo &mli,
const MachineDominatorTree &mdt,
if (!V)
return;
+ if (const PseudoSourceValue *PSV = dyn_cast<PseudoSourceValue>(V)) {
+ // 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.
+ if (!PSV->isAliased(MFI)) {
+ bool MayAlias = PSV->mayAlias(MFI);
+ Objects.push_back(UnderlyingObjectsVector::value_type(V, MayAlias));
+ }
+ return;
+ }
+
SmallVector<Value *, 4> Objs;
getUnderlyingObjects(V, Objs);
for (SmallVectorImpl<Value *>::iterator I = Objs.begin(), IE = Objs.end();
I != IE; ++I) {
- bool MayAlias = true;
V = *I;
- if (const PseudoSourceValue *PSV = dyn_cast<PseudoSourceValue>(V)) {
- // 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.
-
- if (PSV->isAliased(MFI)) {
- Objects.clear();
- return;
- }
+ assert(!isa<PseudoSourceValue>(V) && "Underlying value is a stack slot!");
- MayAlias = PSV->mayAlias(MFI);
- } else if (!isIdentifiedObject(V)) {
+ if (!isIdentifiedObject(V)) {
Objects.clear();
return;
}
- Objects.push_back(UnderlyingObjectsVector::value_type(V, MayAlias));
+ Objects.push_back(UnderlyingObjectsVector::value_type(V, true));
}
}
int64_t Overlapb = MMOb->getSize() + MMOb->getOffset() - MinOffset;
AliasAnalysis::AliasResult AAResult = AA->alias(
- AliasAnalysis::Location(MMOa->getValue(), Overlapa,
- MMOa->getTBAAInfo()),
- AliasAnalysis::Location(MMOb->getValue(), Overlapb,
- MMOb->getTBAAInfo()));
+ AliasAnalysis::Location(MMOa->getValue(), Overlapa,
+ UseTBAA ? MMOa->getTBAAInfo() : 0),
+ AliasAnalysis::Location(MMOb->getValue(), Overlapb,
+ UseTBAA ? MMOb->getTBAAInfo() : 0));
return (AAResult != AliasAnalysis::NoAlias);
}
// so that they can be given more precise dependencies. We track
// separately the known memory locations that may alias and those
// that are known not to alias
- MapVector<const Value *, SUnit *> AliasMemDefs, NonAliasMemDefs;
+ MapVector<const Value *, std::vector<SUnit *> > AliasMemDefs, NonAliasMemDefs;
MapVector<const Value *, std::vector<SUnit *> > AliasMemUses, NonAliasMemUses;
std::set<SUnit*> RejectMemNodes;
MachineInstr *DbgMI = NULL;
for (MachineBasicBlock::iterator MII = RegionEnd, MIE = RegionBegin;
MII != MIE; --MII) {
- MachineInstr *MI = prior(MII);
+ MachineInstr *MI = std::prev(MII);
if (MI && DbgMI) {
DbgValues.push_back(std::make_pair(DbgMI, MI));
DbgMI = NULL;
if (RPTracker) {
PressureDiff *PDiff = PDiffs ? &(*PDiffs)[SU->NodeNum] : 0;
RPTracker->recede(/*LiveUses=*/0, PDiff);
- assert(RPTracker->getPos() == prior(MII) && "RPTracker can't find MI");
+ assert(RPTracker->getPos() == std::prev(MII) &&
+ "RPTracker can't find MI");
}
- assert((CanHandleTerminators || (!MI->isTerminator() && !MI->isLabel())) &&
- "Cannot schedule terminators or labels!");
+ assert(
+ (CanHandleTerminators || (!MI->isTerminator() && !MI->isPosition())) &&
+ "Cannot schedule terminators or labels!");
// Add register-based dependencies (data, anti, and output).
bool HasVRegDef = false;
if (isGlobalMemoryObject(AA, MI)) {
// Be conservative with these and add dependencies on all memory
// references, even those that are known to not alias.
- for (MapVector<const Value *, SUnit *>::iterator I =
+ for (MapVector<const Value *, std::vector<SUnit *> >::iterator I =
NonAliasMemDefs.begin(), E = NonAliasMemDefs.end(); I != E; ++I) {
- I->second->addPred(SDep(SU, SDep::Barrier));
+ for (unsigned i = 0, e = I->second.size(); i != e; ++i) {
+ I->second[i]->addPred(SDep(SU, SDep::Barrier));
+ }
}
for (MapVector<const Value *, std::vector<SUnit *> >::iterator I =
NonAliasMemUses.begin(), E = NonAliasMemUses.end(); I != E; ++I) {
for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k)
addChainDependency(AAForDep, MFI, SU, PendingLoads[k], RejectMemNodes,
TrueMemOrderLatency);
- for (MapVector<const Value *, SUnit *>::iterator I = AliasMemDefs.begin(),
- E = AliasMemDefs.end(); I != E; ++I)
- addChainDependency(AAForDep, MFI, SU, I->second, RejectMemNodes);
+ for (MapVector<const Value *, std::vector<SUnit *> >::iterator I =
+ AliasMemDefs.begin(), E = AliasMemDefs.end(); I != E; ++I) {
+ for (unsigned i = 0, e = I->second.size(); i != e; ++i)
+ addChainDependency(AAForDep, MFI, SU, I->second[i], RejectMemNodes);
+ }
for (MapVector<const Value *, std::vector<SUnit *> >::iterator I =
AliasMemUses.begin(), E = AliasMemUses.end(); I != E; ++I) {
for (unsigned i = 0, e = I->second.size(); i != e; ++i)
// A store to a specific PseudoSourceValue. Add precise dependencies.
// Record the def in MemDefs, first adding a dep if there is
// an existing def.
- MapVector<const Value *, SUnit *>::iterator I =
+ MapVector<const Value *, std::vector<SUnit *> >::iterator I =
((ThisMayAlias) ? AliasMemDefs.find(V) : NonAliasMemDefs.find(V));
- MapVector<const Value *, SUnit *>::iterator IE =
+ MapVector<const Value *, std::vector<SUnit *> >::iterator IE =
((ThisMayAlias) ? AliasMemDefs.end() : NonAliasMemDefs.end());
if (I != IE) {
- addChainDependency(AAForDep, MFI, SU, I->second, RejectMemNodes,
- 0, true);
- I->second = SU;
+ for (unsigned i = 0, e = I->second.size(); i != e; ++i)
+ addChainDependency(AAForDep, MFI, SU, I->second[i], RejectMemNodes,
+ 0, true);
+
+ // If we're not using AA, then we only need one store per object.
+ if (!AAForDep)
+ I->second.clear();
+ I->second.push_back(SU);
} else {
- if (ThisMayAlias)
- AliasMemDefs[V] = SU;
- else
- NonAliasMemDefs[V] = SU;
+ if (ThisMayAlias) {
+ if (!AAForDep)
+ AliasMemDefs[V].clear();
+ AliasMemDefs[V].push_back(SU);
+ } else {
+ if (!AAForDep)
+ NonAliasMemDefs[V].clear();
+ NonAliasMemDefs[V].push_back(SU);
+ }
}
// Handle the uses in MemUses, if there are any.
MapVector<const Value *, std::vector<SUnit *> >::iterator J =
if (Objs.empty()) {
// A load with no underlying object. Depend on all
// potentially aliasing stores.
- for (MapVector<const Value *, SUnit *>::iterator I =
+ for (MapVector<const Value *, std::vector<SUnit *> >::iterator I =
AliasMemDefs.begin(), E = AliasMemDefs.end(); I != E; ++I)
- addChainDependency(AAForDep, MFI, SU, I->second, RejectMemNodes);
+ for (unsigned i = 0, e = I->second.size(); i != e; ++i)
+ addChainDependency(AAForDep, MFI, SU, I->second[i],
+ RejectMemNodes);
PendingLoads.push_back(SU);
MayAlias = true;
MayAlias = true;
// A load from a specific PseudoSourceValue. Add precise dependencies.
- MapVector<const Value *, SUnit *>::iterator I =
+ MapVector<const Value *, std::vector<SUnit *> >::iterator I =
((ThisMayAlias) ? AliasMemDefs.find(V) : NonAliasMemDefs.find(V));
- MapVector<const Value *, SUnit *>::iterator IE =
+ MapVector<const Value *, std::vector<SUnit *> >::iterator IE =
((ThisMayAlias) ? AliasMemDefs.end() : NonAliasMemDefs.end());
if (I != IE)
- addChainDependency(AAForDep, MFI, SU, I->second, RejectMemNodes,
- 0, true);
+ for (unsigned i = 0, e = I->second.size(); i != e; ++i)
+ addChainDependency(AAForDep, MFI, SU, I->second[i],
+ RejectMemNodes, 0, true);
if (ThisMayAlias)
AliasMemUses[V].push_back(SU);
else
const SDep *backtrack() {
DFSStack.pop_back();
- return DFSStack.empty() ? 0 : llvm::prior(DFSStack.back().second);
+ return DFSStack.empty() ? 0 : std::prev(DFSStack.back().second);
}
const SUnit *getCurr() const { return DFSStack.back().first; }