[polly] r218757 - [RTC] Split alias groups according to read only base addresses

Johannes Doerfert doerfert at cs.uni-saarland.de
Wed Oct 1 05:40:46 PDT 2014


Author: jdoerfert
Date: Wed Oct  1 07:40:46 2014
New Revision: 218757

URL: http://llvm.org/viewvc/llvm-project?rev=218757&view=rev
Log:
[RTC] Split alias groups according to read only base addresses

  If there are multiple read only base addresses in an alias group
  we can split it into multiple alias groups each with only one
  read only access. This way we might reduce the number of
  comparisons significantly as it grows linear in the number of
  alias groups but exponential in their size.

Differential Revision: http://reviews.llvm.org/D5435


Added:
    polly/trunk/test/ScopInfo/run-time-check-read-only-arrays.ll
Modified:
    polly/trunk/lib/Analysis/ScopInfo.cpp
    polly/trunk/test/Isl/Ast/aliasing_multiple_alias_groups.ll
    polly/trunk/test/ScopInfo/aliasing_multiple_alias_groups.ll

Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=218757&r1=218756&r2=218757&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Wed Oct  1 07:40:46 2014
@@ -1198,17 +1198,22 @@ bool Scop::buildAliasGroups(AliasAnalysi
   //   o) For each alias set we then map the aliasing pointers back to the
   //      memory accesses we know, thus obtain groups of memory accesses which
   //      might alias.
-  //   o) For each group with more then one base pointer we then compute minimal
+  //   o) We split groups such that they contain at most one read only base
+  //      address.
+  //   o) For each group with more than one base pointer we then compute minimal
   //      and maximal accesses to each array in this group.
   using AliasGroupTy = SmallVector<MemoryAccess *, 4>;
 
   AliasSetTracker AST(AA);
 
   DenseMap<Value *, MemoryAccess *> PtrToAcc;
+  DenseSet<Value *> HasWriteAccess;
   for (ScopStmt *Stmt : *this) {
     for (MemoryAccess *MA : *Stmt) {
       if (MA->isScalar())
         continue;
+      if (!MA->isRead())
+        HasWriteAccess.insert(MA->getBaseAddr());
       Instruction *Acc = MA->getAccessInstruction();
       PtrToAcc[getPointerOperand(*Acc)] = MA;
       AST.add(Acc);
@@ -1227,19 +1232,54 @@ bool Scop::buildAliasGroups(AliasAnalysi
     AliasGroups.push_back(std::move(AG));
   }
 
-  SmallPtrSet<const Value *, 4> BaseValues;
-  for (auto I = AliasGroups.begin(); I != AliasGroups.end();) {
-    BaseValues.clear();
-    for (MemoryAccess *MA : *I)
-      BaseValues.insert(MA->getBaseAddr());
-    if (BaseValues.size() > 1)
-      I++;
-    else
-      I = AliasGroups.erase(I);
+  DenseMap<const Value *, SmallPtrSet<MemoryAccess *, 8>> ReadOnlyPairs;
+  SmallPtrSet<const Value *, 4> NonReadOnlyBaseValues;
+  for (AliasGroupTy &AG : AliasGroups) {
+    NonReadOnlyBaseValues.clear();
+    ReadOnlyPairs.clear();
+
+    for (auto II = AG.begin(); II != AG.end();) {
+      Value *BaseAddr = (*II)->getBaseAddr();
+      if (HasWriteAccess.count(BaseAddr)) {
+        NonReadOnlyBaseValues.insert(BaseAddr);
+        II++;
+      } else {
+        ReadOnlyPairs[BaseAddr].insert(*II);
+        II = AG.erase(II);
+      }
+    }
+
+    // If we don't have read only pointers check if there are at least two
+    // non read only pointers, otherwise clear the alias group.
+    if (ReadOnlyPairs.empty()) {
+      if (NonReadOnlyBaseValues.size() <= 1)
+        AG.clear();
+      continue;
+    }
+
+    // If we don't have non read only pointers clear the alias group.
+    if (NonReadOnlyBaseValues.empty()) {
+      AG.clear();
+      continue;
+    }
+
+    // If we have both read only and non read only base pointers we combine
+    // the non read only ones with exactly one read only one at a time into a
+    // new alias group and clear the old alias group in the end.
+    for (const auto &ReadOnlyPair : ReadOnlyPairs) {
+      AliasGroupTy AGNonReadOnly = AG;
+      for (MemoryAccess *MA : ReadOnlyPair.second)
+        AGNonReadOnly.push_back(MA);
+      AliasGroups.push_back(std::move(AGNonReadOnly));
+    }
+    AG.clear();
   }
 
   bool Valid = true;
   for (AliasGroupTy &AG : AliasGroups) {
+    if (AG.empty())
+      continue;
+
     MinMaxVectorTy *MinMaxAccesses = new MinMaxVectorTy();
     MinMaxAccesses->reserve(AG.size());
 

Modified: polly/trunk/test/Isl/Ast/aliasing_multiple_alias_groups.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/Ast/aliasing_multiple_alias_groups.ll?rev=218757&r1=218756&r2=218757&view=diff
==============================================================================
--- polly/trunk/test/Isl/Ast/aliasing_multiple_alias_groups.ll (original)
+++ polly/trunk/test/Isl/Ast/aliasing_multiple_alias_groups.ll Wed Oct  1 07:40:46 2014
@@ -12,9 +12,8 @@
 ; NOAA-DAG:    &MemRef_Float0[1024] <= &MemRef_Int0[0] || &MemRef_Int0[1024] <= &MemRef_Float0[0]
 ; NOAA-DAG:    &MemRef_Float1[1024] <= &MemRef_Int0[0] || &MemRef_Int0[1024] <= &MemRef_Float1[0]
 ; NOAA-DAG:    &MemRef_Int1[1024] <= &MemRef_Int0[0] || &MemRef_Int0[1024] <= &MemRef_Int1[0]
-; NOAA-DAG:    &MemRef_Float1[1024] <= &MemRef_Float0[0] || &MemRef_Float0[1024] <= &MemRef_Float1[0]
+; NOAA-DAG:    &MemRef_Float0[1024] <= &MemRef_Float1[0] || &MemRef_Float1[1024] <= &MemRef_Float0[0]
 ; NOAA-DAG:    &MemRef_Int1[1024] <= &MemRef_Float0[0] || &MemRef_Float0[1024] <= &MemRef_Int1[0]
-; NOAA-DAG:    &MemRef_Int1[1024] <= &MemRef_Float1[0] || &MemRef_Float1[1024] <= &MemRef_Int1[0]
 ; NOAA:      ))
 ;
 ; TBAA:      if (1 && (

Modified: polly/trunk/test/ScopInfo/aliasing_multiple_alias_groups.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/aliasing_multiple_alias_groups.ll?rev=218757&r1=218756&r2=218757&view=diff
==============================================================================
--- polly/trunk/test/ScopInfo/aliasing_multiple_alias_groups.ll (original)
+++ polly/trunk/test/ScopInfo/aliasing_multiple_alias_groups.ll Wed Oct  1 07:40:46 2014
@@ -39,14 +39,25 @@ for.end:
 !4 = metadata !{metadata !5, metadata !5, i64 0}
 !5 = metadata !{metadata !"float", metadata !2, i64 0}
 
-; NOAA: Alias Groups (1):
+; NOAA: Alias Groups (2):
+; NOAA-NEXT: {{\[\[}}
 ; NOAA-DAG:      <{ MemRef_Int0[(0)] }, { MemRef_Int0[(1024)] }>
-; NOAA-DAG:      <{ MemRef_Int1[(0)] }, { MemRef_Int1[(1024)] }>
+; NOAA-DAG:      <{ MemRef_{{(Int|Float)}}1[(0)] }, { MemRef_{{(Int|Float)}}1[(1024)] }>
 ; NOAA-DAG:      <{ MemRef_Float0[(0)] }, { MemRef_Float0[(1024)] }>
-; NOAA-DAG:      <{ MemRef_Float1[(0)] }, { MemRef_Float1[(1024)] }>
+; NOAA:      {{\]\]}}
+; NOAA-NEXT: {{\[\[}}
+; NOAA-DAG:      <{ MemRef_Int0[(0)] }, { MemRef_Int0[(1024)] }>
+; NOAA-DAG:      <{ MemRef_Float0[(0)] }, { MemRef_Float0[(1024)] }>
+; NOAA-DAG:      <{ MemRef_{{(Int|Float)}}1[(0)] }, { MemRef_{{(Int|Float)}}1[(1024)] }>
+; NOAA:      {{\]\]}}
+
 
-; TBAA-DAG: Alias Groups (2):
+; TBAA: Alias Groups (2):
+; TBAA-NEXT: {{\[\[}}
 ; TBAA-DAG:      <{ MemRef_Int0[(0)] }, { MemRef_Int0[(1024)] }>
 ; TBAA-DAG:      <{ MemRef_Int1[(0)] }, { MemRef_Int1[(1024)] }>
+; TBAA:      {{\]\]}}
+; TBAA-NEXT: {{\[\[}}
 ; TBAA-DAG:      <{ MemRef_Float0[(0)] }, { MemRef_Float0[(1024)] }>
 ; TBAA-DAG:      <{ MemRef_Float1[(0)] }, { MemRef_Float1[(1024)] }>
+; TBBA:      {{\]\]}}

Added: polly/trunk/test/ScopInfo/run-time-check-read-only-arrays.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/run-time-check-read-only-arrays.ll?rev=218757&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/run-time-check-read-only-arrays.ll (added)
+++ polly/trunk/test/ScopInfo/run-time-check-read-only-arrays.ll Wed Oct  1 07:40:46 2014
@@ -0,0 +1,33 @@
+; RUN: opt %loadPolly -polly-code-generator=isl -polly-scops -analyze < %s | FileCheck %s
+;
+; void foo(float *A, float *B, float *C, long N) {
+; 	for (long i = 0; i < N; i++)
+; 		C[i] = A[i] + B[i];
+; }
+;
+; CHECK: Alias Groups (2):
+;
+; This test case verifies that we do not create run-time checks for two
+; read-only arrays.
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @foo(float* %A, float* %B, float* %C, i64 %N) {
+entry:
+  br label %for.body
+
+for.body:
+  %indvar = phi i64 [ 0, %entry ], [ %indvar.next, %for.body ]
+  %arrayidx.A = getelementptr float* %A, i64 %indvar
+  %arrayidx.B = getelementptr float* %B, i64 %indvar
+  %arrayidx.C = getelementptr float* %C, i64 %indvar
+  %val.A = load float* %arrayidx.A
+  %val.B = load float* %arrayidx.B
+  %add = fadd float %val.A, %val.B
+  store float %add, float* %arrayidx.C
+  %indvar.next = add nsw i64 %indvar, 1
+  %exitcond = icmp ne i64 %indvar.next, %N
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.end:
+  ret void
+}





More information about the llvm-commits mailing list