forked from OSchip/llvm-project
parent
601c94b309
commit
2cd1fd4a82
|
@ -23,6 +23,7 @@
|
|||
#include "llvm/CallGraphSCCPass.h"
|
||||
#include "llvm/GlobalVariable.h"
|
||||
#include "llvm/IntrinsicInst.h"
|
||||
#include "llvm/LLVMContext.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/CallGraph.h"
|
||||
#include "llvm/Analysis/CaptureTracking.h"
|
||||
|
@ -140,10 +141,14 @@ bool FunctionAttrs::AddReadAttrs(const CallGraphSCC &SCC) {
|
|||
for (CallSite::arg_iterator CI = CS.arg_begin(), CE = CS.arg_end();
|
||||
CI != CE; ++CI) {
|
||||
Value *Arg = *CI;
|
||||
if (Arg->getType()->isPointerTy() &&
|
||||
!AA->pointsToConstantMemory(Arg, /*OrLocal=*/true))
|
||||
// Writes memory. Just give up.
|
||||
return false;
|
||||
if (Arg->getType()->isPointerTy()) {
|
||||
AliasAnalysis::Location Loc(Arg,
|
||||
AliasAnalysis::UnknownSize,
|
||||
I->getMetadata(LLVMContext::MD_tbaa));
|
||||
if (!AA->pointsToConstantMemory(Arg, /*OrLocal=*/true))
|
||||
// Writes memory. Just give up.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Only reads and writes local memory.
|
||||
continue;
|
||||
|
@ -153,16 +158,23 @@ bool FunctionAttrs::AddReadAttrs(const CallGraphSCC &SCC) {
|
|||
}
|
||||
} else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
|
||||
// Ignore non-volatile loads from local memory.
|
||||
if (!LI->isVolatile() &&
|
||||
AA->pointsToConstantMemory(LI->getPointerOperand(),
|
||||
/*OrLocal=*/true))
|
||||
continue;
|
||||
if (!LI->isVolatile()) {
|
||||
AliasAnalysis::Location Loc(LI->getPointerOperand(),
|
||||
AA->getTypeStoreSize(LI->getType()),
|
||||
LI->getMetadata(LLVMContext::MD_tbaa));
|
||||
if (AA->pointsToConstantMemory(Loc, /*OrLocal=*/true))
|
||||
continue;
|
||||
}
|
||||
} else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
|
||||
// Ignore non-volatile stores to local memory.
|
||||
if (!SI->isVolatile() &&
|
||||
AA->pointsToConstantMemory(SI->getPointerOperand(),
|
||||
/*OrLocal=*/true))
|
||||
continue;
|
||||
if (!SI->isVolatile()) {
|
||||
const Type *StoredType = SI->getValueOperand()->getType();
|
||||
AliasAnalysis::Location Loc(SI->getPointerOperand(),
|
||||
AA->getTypeStoreSize(StoredType),
|
||||
SI->getMetadata(LLVMContext::MD_tbaa));
|
||||
if (AA->pointsToConstantMemory(Loc, /*OrLocal=*/true))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Any remaining instructions need to be taken seriously! Check if they
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
; RUN: opt < %s -enable-tbaa -tbaa -basicaa -functionattrs -S | FileCheck %s
|
||||
|
||||
; FunctionAttrs should make use of TBAA.
|
||||
|
||||
; CHECK: define void @test0_yes(i32* nocapture %p) nounwind readnone {
|
||||
define void @test0_yes(i32* %p) nounwind {
|
||||
store i32 0, i32* %p, !tbaa !1
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: define void @test0_no(i32* nocapture %p) nounwind {
|
||||
define void @test0_no(i32* %p) nounwind {
|
||||
store i32 0, i32* %p, !tbaa !2
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: define void @test1_yes(i32* %p) nounwind readonly {
|
||||
define void @test1_yes(i32* %p) nounwind {
|
||||
call void @callee(i32* %p), !tbaa !1
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: define void @test1_no(i32* %p) nounwind {
|
||||
define void @test1_no(i32* %p) nounwind {
|
||||
call void @callee(i32* %p), !tbaa !2
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @callee(i32* %p) nounwind
|
||||
|
||||
; Root note.
|
||||
!0 = metadata !{ }
|
||||
|
||||
; Invariant memory.
|
||||
!1 = metadata !{ metadata !"foo", metadata !0, i1 1 }
|
||||
; Not invariant memory.
|
||||
!2 = metadata !{ metadata !"foo", metadata !0, i1 0 }
|
Loading…
Reference in New Issue