diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/AliasAnalysis.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/Target/README.txt | 4 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 15 |
3 files changed, 24 insertions, 6 deletions
diff --git a/llvm/lib/Analysis/AliasAnalysis.cpp b/llvm/lib/Analysis/AliasAnalysis.cpp index dee9b535871..371dcafa9f3 100644 --- a/llvm/lib/Analysis/AliasAnalysis.cpp +++ b/llvm/lib/Analysis/AliasAnalysis.cpp @@ -116,13 +116,16 @@ AliasAnalysis::getModRefBehavior(Function *F, return DoesNotAccessMemory; if (F->onlyReadsMemory()) return OnlyReadsMemory; - if (unsigned id = F->getIntrinsicID()) { + if (unsigned id = F->getIntrinsicID()) + return getModRefBehavior(id); + } + return UnknownModRefBehavior; +} + +AliasAnalysis::ModRefBehavior AliasAnalysis::getModRefBehavior(unsigned iid) { #define GET_INTRINSIC_MODREF_BEHAVIOR #include "llvm/Intrinsics.gen" #undef GET_INTRINSIC_MODREF_BEHAVIOR - } - } - return UnknownModRefBehavior; } AliasAnalysis::ModRefResult diff --git a/llvm/lib/Target/README.txt b/llvm/lib/Target/README.txt index 22dadfeb3dd..38c3daa9383 100644 --- a/llvm/lib/Target/README.txt +++ b/llvm/lib/Target/README.txt @@ -1678,8 +1678,8 @@ And functionattrs doesn't realize that the p.0 load points to function local memory. Also, functionattrs doesn't know about memcpy/memset. This function should be -marked readnone, since it only twiddles local memory, but functionattrs doesn't -handle memset/memcpy/memmove aggressively: +marked readnone rather than readonly, since it only twiddles local memory, but +functionattrs doesn't handle memset/memcpy/memmove aggressively: struct X { int *p; int *q; }; int foo() { diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp index a16d335ef50..0bff2b94e9d 100644 --- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp +++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp @@ -136,6 +136,21 @@ bool FunctionAttrs::AddReadAttrs(const std::vector<CallGraphNode *> &SCC) { // Ignore calls to functions in the same SCC. if (SCCNodes.count(CS.getCalledFunction())) continue; + // Ignore intrinsics that only access local memory. + if (unsigned id = CS.getCalledFunction()->getIntrinsicID()) + if (AliasAnalysis::getModRefBehavior(id) == + AliasAnalysis::AccessesArguments) { + // Check that all pointer arguments point to local memory. + for (CallSite::arg_iterator CI = CS.arg_begin(), CE = CS.arg_end(); + CI != CE; ++CI) { + Value *Arg = *CI; + if (isa<PointerType>(Arg->getType()) && !PointsToLocalMemory(Arg)) + // Writes memory. Just give up. + return false; + } + // Only reads and writes local memory. + continue; + } } else if (LoadInst *LI = dyn_cast<LoadInst>(I)) { // Ignore loads from local memory. if (PointsToLocalMemory(LI->getPointerOperand())) |