const Instruction *Inst;
// Set of visited Instructions for this query.
DenseSet<MemoryAccessPair> Visited;
- // Set of visited call accesses for this query. This is separated out because
- // you can always cache and lookup the result of call queries (IE when IsCall
- // == true) for every call in the chain. The calls have no AA location
+ // Vector of visited call accesses for this query. This is separated out
+ // because you can always cache and lookup the result of call queries (IE when
+ // IsCall == true) for every call in the chain. The calls have no AA location
// associated with them with them, and thus, no context dependence.
- SmallPtrSet<const MemoryAccess *, 32> VisitedCalls;
+ SmallVector<const MemoryAccess *, 32> VisitedCalls;
// The MemoryAccess we actually got called with, used to test local domination
const MemoryAccess *OriginalAccess;
// The Datalayout for the module we started in
// If this is a call, mark it for caching
if (ImmutableCallSite(DefMemoryInst))
- Q.VisitedCalls.insert(MD);
+ Q.VisitedCalls.push_back(MD);
ModRefInfo I = AA->getModRefInfo(DefMemoryInst, ImmutableCallSite(Q.Inst));
return I != MRI_NoModRef;
}
break;
}
+ std::size_t InitialVisitedCallSize = Q.VisitedCalls.size();
+
// Recurse on PHI nodes, since we need to change locations.
// TODO: Allow graphtraits on pairs, which would turn this whole function
// into a normal single depth first walk.
if (!ModifyingAccess) {
assert(FirstDef && "Found a Phi with no upward defs?");
ModifyingAccess = FirstDef;
+ } else {
+ // If we can't optimize this Phi, then we can't safely cache any of the
+ // calls we visited when trying to optimize it. Wipe them out now.
+ Q.VisitedCalls.resize(InitialVisitedCallSize);
}
break;
}
%3 = add i32 %2, %1
ret i32 %3
}
+
+declare void @readEverything() readonly
+declare void @clobberEverything()
+
+; CHECK-LABEL: define void @bar
+define void @bar() {
+; CHECK: 1 = MemoryDef(liveOnEntry)
+; CHECK-NEXT: call void @clobberEverything()
+ call void @clobberEverything()
+ br i1 undef, label %if.end, label %if.then
+
+if.then:
+; CHECK: MemoryUse(1)
+; CHECK-NEXT: call void @readEverything()
+ call void @readEverything()
+; CHECK: 2 = MemoryDef(1)
+; CHECK-NEXT: call void @clobberEverything()
+ call void @clobberEverything()
+ br label %if.end
+
+if.end:
+; CHECK: 3 = MemoryPhi({%0,1},{if.then,2})
+; CHECK: MemoryUse(3)
+; CHECK-NEXT: call void @readEverything()
+ call void @readEverything()
+ ret void
+}