Teach BasicAA about noalias parameter attributes, but do it correctly this time.

llvm-svn: 40711
This commit is contained in:
Christopher Lamb 2007-08-02 01:18:14 +00:00
parent c5549fc3a0
commit 1a80201426
3 changed files with 58 additions and 1 deletions

View File

@ -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...

View File

@ -0,0 +1,10 @@
; RUN: llvm-as %s -o - | opt -basicaa -aa-eval -print-all-alias-modref-info -disable-output &| grep 'MayAlias: i32* %y, i32* %x'
declare i32* @unclear(i32* %a)
define void @foo(i32* noalias %x) {
%y = call i32* @unclear(i32* %x)
store i32 0, i32* %x
store i32 0, i32* %y
ret void
}

View File

@ -0,0 +1,17 @@
; RUN: llvm-as %s -o - | opt -basicaa -aa-eval -print-all-alias-modref-info -disable-output &| grep '9 no alias'
; RUN: llvm-as %s -o - | opt -basicaa -aa-eval -print-all-alias-modref-info -disable-output &| grep '6 may alias'
; RUN: llvm-as %s -o - | opt -basicaa -aa-eval -print-all-alias-modref-info -disable-output &| grep 'MayAlias: i32* %pj, i32* %pi'
define void @foo(i32* noalias %p, i32* noalias %q, i32 %i, i32 %j) {
%pi = getelementptr i32* %p, i32 %i
%qi = getelementptr i32* %q, i32 %i
%pj = getelementptr i32* %p, i32 %j
%qj = getelementptr i32* %q, i32 %j
store i32 0, i32* %p
store i32 0, i32* %pi
store i32 0, i32* %pj
store i32 0, i32* %q
store i32 0, i32* %qi
store i32 0, i32* %qj
ret void
}