- for (unsigned i = 0, e = SCC.size(); i != e && FunctionEffect != ModRef;
- ++i)
- for (inst_iterator II = inst_begin(SCC[i]->getFunction()),
- E = inst_end(SCC[i]->getFunction());
- II != E && FunctionEffect != ModRef; ++II)
- if (LoadInst *LI = dyn_cast<LoadInst>(&*II)) {
+ for (auto *Node : SCC) {
+ if (FunctionEffect == ModRef)
+ break; // The mod/ref lattice saturates here.
+ for (Instruction &I : inst_range(Node->getFunction())) {
+ if (FunctionEffect == ModRef)
+ break; // The mod/ref lattice saturates here.
+
+ // We handle calls specially because the graph-relevant aspects are
+ // handled above.
+ if (auto CS = CallSite(&I)) {
+ if (isAllocationFn(&I, TLI) || isFreeCall(&I, TLI)) {
+ // FIXME: It is completely unclear why this is necessary and not
+ // handled by the above graph code.
+ FunctionEffect |= ModRef;
+ } else if (Function *Callee = CS.getCalledFunction()) {
+ // The callgraph doesn't include intrinsic calls.
+ if (Callee->isIntrinsic()) {
+ ModRefBehavior Behaviour =
+ AliasAnalysis::getModRefBehavior(Callee);
+ FunctionEffect |= (Behaviour & ModRef);
+ }
+ }
+ continue;
+ }
+
+ // All non-call instructions we use the primary predicates for whether
+ // thay read or write memory.
+ if (I.mayReadFromMemory())