aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/BasicAliasAnalysis.cpp
diff options
context:
space:
mode:
authorChristopher Lamb <christopher.lamb@gmail.com>2007-08-02 01:18:14 +0000
committerChristopher Lamb <christopher.lamb@gmail.com>2007-08-02 01:18:14 +0000
commit406bfa3e21e8fab3deab240c30c763e78eddf2f5 (patch)
tree589affc9709d498e55ec8ebb5994063773431aa6 /lib/Analysis/BasicAliasAnalysis.cpp
parent8409747efadda025aa3cce626b1a2c33429fd5e5 (diff)
Teach BasicAA about noalias parameter attributes, but do it correctly this time.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@40711 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/BasicAliasAnalysis.cpp')
-rw-r--r--lib/Analysis/BasicAliasAnalysis.cpp32
1 files changed, 31 insertions, 1 deletions
diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp
index 580f7e5d9e..39f232e3e5 100644
--- a/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/lib/Analysis/BasicAliasAnalysis.cpp
@@ -18,6 +18,7 @@
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
+#include "llvm/ParameterAttributes.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Instructions.h"
#include "llvm/Pass.h"
@@ -260,6 +261,21 @@ BasicAliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
return AliasAnalysis::getModRefInfo(CS, P, Size);
}
+static bool isNoAliasArgument(const Argument *Arg) {
+ const Function *Func = Arg->getParent();
+ const ParamAttrsList *Attr = Func->getFunctionType()->getParamAttrs();
+ if (Attr) {
+ unsigned Idx = 1;
+ for (Function::const_arg_iterator I = Func->arg_begin(),
+ E = Func->arg_end(); I != E; ++I, ++Idx) {
+ if (&(*I) == Arg &&
+ Attr->paramHasAttr(Idx, ParamAttr::NoAlias))
+ return true;
+ }
+ }
+ return false;
+}
+
// alias - Provide a bunch of ad-hoc rules to disambiguate in common cases, such
// as array references. Note that this function is heavily tail recursive.
// Hopefully we have a smart C++ compiler. :)
@@ -298,10 +314,24 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
if (isa<Argument>(O1)) {
// Incoming argument cannot alias locally allocated object!
if (isa<AllocationInst>(O2)) return NoAlias;
+
+ // If they are two different objects, and one is a noalias argument
+ // then they do not alias.
+ if (O1 != O2 && isNoAliasArgument(cast<Argument>(O1)))
+ return NoAlias;
+
// Otherwise, nothing is known...
- } else if (isa<Argument>(O2)) {
+ }
+
+ if (isa<Argument>(O2)) {
// Incoming argument cannot alias locally allocated object!
if (isa<AllocationInst>(O1)) return NoAlias;
+
+ // If they are two different objects, and one is a noalias argument
+ // then they do not alias.
+ if (O1 != O2 && isNoAliasArgument(cast<Argument>(O2)))
+ return NoAlias;
+
// Otherwise, nothing is known...
} else if (O1 != O2) {
// If they are two different objects, we know that we have no alias...