diff options
author | Manman Ren <mren@apple.com> | 2013-03-22 22:34:41 +0000 |
---|---|---|
committer | Manman Ren <mren@apple.com> | 2013-03-22 22:34:41 +0000 |
commit | a2e3834d1644889484ef3a8a94189b7369e3eaf9 (patch) | |
tree | 7f0a6382f595e2dfbd128967aa1bfacc56b4c2a5 | |
parent | 1f9c4407c0e66f0c473ed5d6e3abcedda3a838c9 (diff) |
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.cpp | 72 | ||||
-rw-r--r-- | test/Analysis/TypeBasedAliasAnalysis/placement-tbaa.ll | 104 |
2 files changed, 176 insertions, 0 deletions
diff --git a/lib/Analysis/AliasAnalysisEvaluator.cpp b/lib/Analysis/AliasAnalysisEvaluator.cpp index e58dde3d93..a571463dfe 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 0000000000..f1edb4482c --- /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} |