diff options
Diffstat (limited to 'lib/Analysis/IPA/GlobalsModRef.cpp')
-rw-r--r-- | lib/Analysis/IPA/GlobalsModRef.cpp | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/lib/Analysis/IPA/GlobalsModRef.cpp b/lib/Analysis/IPA/GlobalsModRef.cpp index 18d45dd..28fb49c 100644 --- a/lib/Analysis/IPA/GlobalsModRef.cpp +++ b/lib/Analysis/IPA/GlobalsModRef.cpp @@ -440,30 +440,39 @@ void GlobalsModRef::AnalyzeCallGraph(CallGraph &CG, Module &M) { } // Scan the function bodies for explicit loads or stores. - 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()) FunctionEffect |= Ref; - if (LI->isVolatile()) - // Volatile loads may have side-effects, so mark them as writing - // memory (for example, a flag inside the processor). - FunctionEffect |= Mod; - } else if (StoreInst *SI = dyn_cast<StoreInst>(&*II)) { + if (I.mayWriteToMemory()) FunctionEffect |= Mod; - if (SI->isVolatile()) - // Treat volatile stores as reading memory somewhere. - FunctionEffect |= Ref; - } else if (isAllocationFn(&*II, TLI) || isFreeCall(&*II, TLI)) { - FunctionEffect |= ModRef; - } else if (IntrinsicInst *Intrinsic = dyn_cast<IntrinsicInst>(&*II)) { - // The callgraph doesn't include intrinsic calls. - Function *Callee = Intrinsic->getCalledFunction(); - ModRefBehavior Behaviour = AliasAnalysis::getModRefBehavior(Callee); - FunctionEffect |= (Behaviour & ModRef); - } + } + } if ((FunctionEffect & Mod) == 0) ++NumReadMemFunctions; |