aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManman Ren <mren@apple.com>2013-03-22 22:34:41 +0000
committerManman Ren <mren@apple.com>2013-03-22 22:34:41 +0000
commita2e3834d1644889484ef3a8a94189b7369e3eaf9 (patch)
tree7f0a6382f595e2dfbd128967aa1bfacc56b4c2a5
parent1f9c4407c0e66f0c473ed5d6e3abcedda3a838c9 (diff)
downloadexternal_llvm-a2e3834d1644889484ef3a8a94189b7369e3eaf9.zip
external_llvm-a2e3834d1644889484ef3a8a94189b7369e3eaf9.tar.gz
external_llvm-a2e3834d1644889484ef3a8a94189b7369e3eaf9.tar.bz2
Support in AAEvaluator to print alias queries of loads/stores with TBAA tags.
Add "evaluate-tbaa" to print alias queries of loads/stores. Alias queries between pointers do not include TBAA tags. Add testing case for "placement new". TBAA currently says NoAlias. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@177772 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/AliasAnalysisEvaluator.cpp72
-rw-r--r--test/Analysis/TypeBasedAliasAnalysis/placement-tbaa.ll104
2 files changed, 176 insertions, 0 deletions
diff --git a/lib/Analysis/AliasAnalysisEvaluator.cpp b/lib/Analysis/AliasAnalysisEvaluator.cpp
index e58dde3..a571463 100644
--- a/lib/Analysis/AliasAnalysisEvaluator.cpp
+++ b/lib/Analysis/AliasAnalysisEvaluator.cpp
@@ -44,6 +44,8 @@ static cl::opt<bool> PrintMod("print-mod", cl::ReallyHidden);
static cl::opt<bool> PrintRef("print-ref", cl::ReallyHidden);
static cl::opt<bool> PrintModRef("print-modref", cl::ReallyHidden);
+static cl::opt<bool> EvalTBAA("evaluate-tbaa", cl::ReallyHidden);
+
namespace {
class AAEval : public FunctionPass {
unsigned NoAlias, MayAlias, PartialAlias, MustAlias;
@@ -123,6 +125,15 @@ PrintModRefResults(const char *Msg, bool P, CallSite CSA, CallSite CSB,
}
}
+static inline void
+PrintLoadStoreResults(const char *Msg, bool P, const Value *V1,
+ const Value *V2, const Module *M) {
+ if (P) {
+ errs() << " " << Msg << ": " << *V1
+ << " <-> " << *V2 << '\n';
+ }
+}
+
static inline bool isInterestingPointer(Value *V) {
return V->getType()->isPointerTy()
&& !isa<ConstantPointerNull>(V);
@@ -133,6 +144,8 @@ bool AAEval::runOnFunction(Function &F) {
SetVector<Value *> Pointers;
SetVector<CallSite> CallSites;
+ SetVector<Value *> Loads;
+ SetVector<Value *> Stores;
for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I)
if (I->getType()->isPointerTy()) // Add all pointer arguments.
@@ -141,6 +154,10 @@ bool AAEval::runOnFunction(Function &F) {
for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
if (I->getType()->isPointerTy()) // Add all pointer instructions.
Pointers.insert(&*I);
+ if (EvalTBAA && isa<LoadInst>(&*I))
+ Loads.insert(&*I);
+ if (EvalTBAA && isa<StoreInst>(&*I))
+ Stores.insert(&*I);
Instruction &Inst = *I;
if (CallSite CS = cast<Value>(&Inst)) {
Value *Callee = CS.getCalledValue();
@@ -197,6 +214,61 @@ bool AAEval::runOnFunction(Function &F) {
}
}
+ if (EvalTBAA) {
+ // iterate over all pairs of load, store
+ for (SetVector<Value *>::iterator I1 = Loads.begin(), E = Loads.end();
+ I1 != E; ++I1) {
+ for (SetVector<Value *>::iterator I2 = Stores.begin(), E2 = Stores.end();
+ I2 != E2; ++I2) {
+ switch (AA.alias(AA.getLocation(cast<LoadInst>(*I1)),
+ AA.getLocation(cast<StoreInst>(*I2)))) {
+ case AliasAnalysis::NoAlias:
+ PrintLoadStoreResults("NoAlias", PrintNoAlias, *I1, *I2,
+ F.getParent());
+ ++NoAlias; break;
+ case AliasAnalysis::MayAlias:
+ PrintLoadStoreResults("MayAlias", PrintMayAlias, *I1, *I2,
+ F.getParent());
+ ++MayAlias; break;
+ case AliasAnalysis::PartialAlias:
+ PrintLoadStoreResults("PartialAlias", PrintPartialAlias, *I1, *I2,
+ F.getParent());
+ ++PartialAlias; break;
+ case AliasAnalysis::MustAlias:
+ PrintLoadStoreResults("MustAlias", PrintMustAlias, *I1, *I2,
+ F.getParent());
+ ++MustAlias; break;
+ }
+ }
+ }
+
+ // iterate over all pairs of store, store
+ for (SetVector<Value *>::iterator I1 = Stores.begin(), E = Stores.end();
+ I1 != E; ++I1) {
+ for (SetVector<Value *>::iterator I2 = Stores.begin(); I2 != I1; ++I2) {
+ switch (AA.alias(AA.getLocation(cast<StoreInst>(*I1)),
+ AA.getLocation(cast<StoreInst>(*I2)))) {
+ case AliasAnalysis::NoAlias:
+ PrintLoadStoreResults("NoAlias", PrintNoAlias, *I1, *I2,
+ F.getParent());
+ ++NoAlias; break;
+ case AliasAnalysis::MayAlias:
+ PrintLoadStoreResults("MayAlias", PrintMayAlias, *I1, *I2,
+ F.getParent());
+ ++MayAlias; break;
+ case AliasAnalysis::PartialAlias:
+ PrintLoadStoreResults("PartialAlias", PrintPartialAlias, *I1, *I2,
+ F.getParent());
+ ++PartialAlias; break;
+ case AliasAnalysis::MustAlias:
+ PrintLoadStoreResults("MustAlias", PrintMustAlias, *I1, *I2,
+ F.getParent());
+ ++MustAlias; break;
+ }
+ }
+ }
+ }
+
// Mod/ref alias analysis: compare all pairs of calls and values
for (SetVector<CallSite>::iterator C = CallSites.begin(),
Ce = CallSites.end(); C != Ce; ++C) {
diff --git a/test/Analysis/TypeBasedAliasAnalysis/placement-tbaa.ll b/test/Analysis/TypeBasedAliasAnalysis/placement-tbaa.ll
new file mode 100644
index 0000000..f1edb44
--- /dev/null
+++ b/test/Analysis/TypeBasedAliasAnalysis/placement-tbaa.ll
@@ -0,0 +1,104 @@
+; RUN: opt < %s -tbaa -basicaa -aa-eval -evaluate-tbaa -print-no-aliases -print-may-aliases -disable-output 2>&1 | FileCheck %s
+
+; Generated with "clang -cc1 -disable-llvm-optzns -O1 -emit-llvm"
+; #include <new>
+; struct Foo { long i; };
+; struct Bar { void *p; };
+; long foo(int n) {
+; Foo *f = new Foo;
+; f->i = 1;
+; for (int i=0; i<n; ++i) {
+; Bar *b = new (f) Bar;
+; b->p = 0;
+; f = new (f) Foo;
+; f->i = i;
+; }
+; return f->i;
+; }
+
+; Basic AA says MayAlias, TBAA says NoAlias
+; CHECK: MayAlias: i64* %i5, i8** %p
+; CHECK: NoAlias: store i64 %conv, i64* %i5, align 8, !tbaa !4 <-> store i8* null, i8** %p, align 8, !tbaa !3
+
+%struct.Foo = type { i64 }
+%struct.Bar = type { i8* }
+
+define i64 @_Z3fooi(i32 %n) #0 {
+entry:
+ %n.addr = alloca i32, align 4
+ %f = alloca %struct.Foo*, align 8
+ %i1 = alloca i32, align 4
+ %b = alloca %struct.Bar*, align 8
+ store i32 %n, i32* %n.addr, align 4, !tbaa !0
+ %call = call noalias i8* @_Znwm(i64 8)
+ %0 = bitcast i8* %call to %struct.Foo*
+ store %struct.Foo* %0, %struct.Foo** %f, align 8, !tbaa !3
+ %1 = load %struct.Foo** %f, align 8, !tbaa !3
+ %i = getelementptr inbounds %struct.Foo* %1, i32 0, i32 0
+ store i64 1, i64* %i, align 8, !tbaa !4
+ store i32 0, i32* %i1, align 4, !tbaa !0
+ br label %for.cond
+
+for.cond:
+ %2 = load i32* %i1, align 4, !tbaa !0
+ %3 = load i32* %n.addr, align 4, !tbaa !0
+ %cmp = icmp slt i32 %2, %3
+ br i1 %cmp, label %for.body, label %for.end
+
+for.body:
+ %4 = load %struct.Foo** %f, align 8, !tbaa !3
+ %5 = bitcast %struct.Foo* %4 to i8*
+ %new.isnull = icmp eq i8* %5, null
+ br i1 %new.isnull, label %new.cont, label %new.notnull
+
+new.notnull:
+ %6 = bitcast i8* %5 to %struct.Bar*
+ br label %new.cont
+
+new.cont:
+ %7 = phi %struct.Bar* [ %6, %new.notnull ], [ null, %for.body ]
+ store %struct.Bar* %7, %struct.Bar** %b, align 8, !tbaa !3
+ %8 = load %struct.Bar** %b, align 8, !tbaa !3
+ %p = getelementptr inbounds %struct.Bar* %8, i32 0, i32 0
+ store i8* null, i8** %p, align 8, !tbaa !3
+ %9 = load %struct.Foo** %f, align 8, !tbaa !3
+ %10 = bitcast %struct.Foo* %9 to i8*
+ %new.isnull2 = icmp eq i8* %10, null
+ br i1 %new.isnull2, label %new.cont4, label %new.notnull3
+
+new.notnull3:
+ %11 = bitcast i8* %10 to %struct.Foo*
+ br label %new.cont4
+
+new.cont4:
+ %12 = phi %struct.Foo* [ %11, %new.notnull3 ], [ null, %new.cont ]
+ store %struct.Foo* %12, %struct.Foo** %f, align 8, !tbaa !3
+ %13 = load i32* %i1, align 4, !tbaa !0
+ %conv = sext i32 %13 to i64
+ %14 = load %struct.Foo** %f, align 8, !tbaa !3
+ %i5 = getelementptr inbounds %struct.Foo* %14, i32 0, i32 0
+ store i64 %conv, i64* %i5, align 8, !tbaa !4
+ br label %for.inc
+
+for.inc:
+ %15 = load i32* %i1, align 4, !tbaa !0
+ %inc = add nsw i32 %15, 1
+ store i32 %inc, i32* %i1, align 4, !tbaa !0
+ br label %for.cond
+
+for.end:
+ %16 = load %struct.Foo** %f, align 8, !tbaa !3
+ %i6 = getelementptr inbounds %struct.Foo* %16, i32 0, i32 0
+ %17 = load i64* %i6, align 8, !tbaa !4
+ ret i64 %17
+}
+
+declare noalias i8* @_Znwm(i64)
+
+attributes #0 = { nounwind }
+
+!0 = metadata !{metadata !"int", metadata !1}
+!1 = metadata !{metadata !"omnipotent char", metadata !2}
+!2 = metadata !{metadata !"Simple C/C++ TBAA"}
+!3 = metadata !{metadata !"any pointer", metadata !1}
+!4 = metadata !{metadata !"long", metadata !1}