Link ScopArrayInfo objects

We will record if a SAI is the base of another SAI or derived from it.
  This will allow to reason about indirect base pointers later on and
  allows a clearer picture of indirection also in the SCoP dump.

llvm-svn: 245584
This commit is contained in:
Johannes Doerfert 2015-08-20 18:04:22 +00:00
parent 43556bb7f0
commit 4eed5bea54
5 changed files with 124 additions and 0 deletions

View File

@ -92,6 +92,14 @@ public:
/// @brief Return the base pointer.
Value *getBasePtr() const { return BasePtr; }
/// @brief For indirect accesses return the origin SAI of the BP, else null.
const ScopArrayInfo *getBasePtrOriginSAI() const { return BasePtrOriginSAI; }
/// @brief The set of derived indirect SAIs for this origin SAI.
const SmallPtrSetImpl<ScopArrayInfo *> &getDerivedSAIs() const {
return DerivedSAIs;
};
/// @brief Return the number of dimensions.
unsigned getNumberOfDimensions() const { return DimensionSizes.size(); }
@ -147,6 +155,16 @@ public:
static const ScopArrayInfo *getFromId(__isl_take isl_id *Id);
private:
void addDerivedSAI(ScopArrayInfo *DerivedSAI) {
DerivedSAIs.insert(DerivedSAI);
}
/// @brief For indirect accesses this is the SAI of the BP origin.
const ScopArrayInfo *BasePtrOriginSAI;
/// @brief For origin SAIs the set of derived indirect SAIs.
SmallPtrSet<ScopArrayInfo *, 2> DerivedSAIs;
/// @brief The base pointer.
Value *BasePtr;

View File

@ -118,6 +118,28 @@ static __isl_give isl_set *addRangeBoundsToSet(__isl_take isl_set *S,
return isl_set_intersect(SLB, SUB);
}
static const ScopArrayInfo *identifyBasePtrOriginSAI(Scop *S, Value *BasePtr) {
LoadInst *BasePtrLI = dyn_cast<LoadInst>(BasePtr);
if (!BasePtrLI)
return nullptr;
if (!S->getRegion().contains(BasePtrLI))
return nullptr;
ScalarEvolution &SE = *S->getSE();
auto *OriginBaseSCEV =
SE.getPointerBase(SE.getSCEV(BasePtrLI->getPointerOperand()));
if (!OriginBaseSCEV)
return nullptr;
auto *OriginBaseSCEVUnknown = dyn_cast<SCEVUnknown>(OriginBaseSCEV);
if (!OriginBaseSCEVUnknown)
return nullptr;
return S->getScopArrayInfo(OriginBaseSCEVUnknown->getValue());
}
ScopArrayInfo::ScopArrayInfo(Value *BasePtr, Type *ElementType, isl_ctx *Ctx,
const SmallVector<const SCEV *, 4> &DimensionSizes,
bool IsPHI, Scop *S)
@ -130,6 +152,10 @@ ScopArrayInfo::ScopArrayInfo(Value *BasePtr, Type *ElementType, isl_ctx *Ctx,
isl_pw_aff *Size = S->getPwAff(Expr);
DimensionSizesPw.push_back(Size);
}
BasePtrOriginSAI = identifyBasePtrOriginSAI(S, BasePtr);
if (BasePtrOriginSAI)
const_cast<ScopArrayInfo *>(BasePtrOriginSAI)->addDerivedSAI(this);
}
ScopArrayInfo::~ScopArrayInfo() {
@ -161,6 +187,9 @@ void ScopArrayInfo::print(raw_ostream &OS, bool SizeAsPwAff) const {
OS << "]";
}
if (BasePtrOriginSAI)
OS << " [BasePtrOrigin: " << BasePtrOriginSAI->getName() << "]";
OS << " // Element size " << getElemSizeInBytes() << "\n";
}

View File

@ -0,0 +1,54 @@
; RUN: opt %loadPolly -tbaa -polly-scops -polly-ignore-aliasing -analyze < %s | FileCheck %s
;
; CHECK: Arrays {
; CHECK: i32** MemRef_A[*][8]
; CHECK: i32* MemRef_tmp3[*][8] [BasePtrOrigin: MemRef_A]
; CHECK: i32 MemRef_tmp5[*][4] [BasePtrOrigin: MemRef_tmp3]
; CHECK: }
;
; CHECK: Arrays (Bounds as pw_affs) {
; CHECK: i32** MemRef_A[*][ { [] -> [(8)] } ]
; CHECK: i32* MemRef_tmp3[*][ { [] -> [(8)] } ] [BasePtrOrigin: MemRef_A]
; CHECK: i32 MemRef_tmp5[*][ { [] -> [(4)] } ] [BasePtrOrigin: MemRef_tmp3]
; CHECK: }
;
; void f(int ***A) {
; for (int i = 0; i < 1024; i++)
; A[42][32][i] = 0;
; }
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define void @f(i32*** %A) {
bb:
br label %bb1
bb1: ; preds = %bb7, %bb
%indvars.iv = phi i64 [ %indvars.iv.next, %bb7 ], [ 0, %bb ]
%exitcond = icmp ne i64 %indvars.iv, 1024
br i1 %exitcond, label %bb2, label %bb8
bb2: ; preds = %bb1
%tmp = getelementptr inbounds i32**, i32*** %A, i64 42
%tmp3 = load i32**, i32*** %tmp, align 8, !tbaa !1
%tmp4 = getelementptr inbounds i32*, i32** %tmp3, i64 32
%tmp5 = load i32*, i32** %tmp4, align 8, !tbaa !1
%tmp6 = getelementptr inbounds i32, i32* %tmp5, i64 %indvars.iv
store i32 0, i32* %tmp6, align 4, !tbaa !5
br label %bb7
bb7: ; preds = %bb2
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
br label %bb1
bb8: ; preds = %bb1
ret void
}
!0 = !{!"clang version 3.8.0 (http://llvm.org/git/clang.git 9e282ff441e7a367dc711e41fd19d27ffc0f78d6)"}
!1 = !{!2, !2, i64 0}
!2 = !{!"any pointer", !3, i64 0}
!3 = !{!"omnipotent char", !4, i64 0}
!4 = !{!"Simple C/C++ TBAA"}
!5 = !{!6, !6, i64 0}
!6 = !{!"int", !3, i64 0}

View File

@ -13,6 +13,19 @@
; }
;
; CHECK: Region: %bb1---%bb11
;
; CHECK: Arrays {
; CHECK: i32 MemRef_A[*][4]
; CHECK: i32 MemRef_x[*] [BasePtrOrigin: MemRef_A]
; CHECK: i32 MemRef_y__phi[*]
; CHECK: }
;
; CHECK: Arrays (Bounds as pw_affs) {
; CHECK: i32 MemRef_A[*][ { [] -> [(4)] } ]
; CHECK: i32 MemRef_x[*] [BasePtrOrigin: MemRef_A]
; CHECK: i32 MemRef_y__phi[*]
; CHECK: }
;
; CHECK: Stmt_bb2__TO__bb7
; CHECK: Domain :=
; CHECK: { Stmt_bb2__TO__bb7[i0] : i0 >= 0 and i0 <= 1023 };

View File

@ -29,6 +29,16 @@ return:
ret void
}
; CHECK: Arrays {
; CHECK: i64 MemRef_a[*][8]
; CHECK: i64 MemRef_val[*] [BasePtrOrigin: MemRef_a]
; CHECK: }
;
; CHECK: Arrays (Bounds as pw_affs) {
; CHECK: i64 MemRef_a[*][ { [] -> [(8)] } ]
; CHECK: i64 MemRef_val[*] [BasePtrOrigin: MemRef_a]
; CHECK: }
; CHECK: Stmt_S1
; CHECK: Domain :=
; CHECK: [N] -> { Stmt_S1[i0] : i0 >= 0 and i0 <= -1 + N };