[polly] r313842 - Check whether IslAstInfo and DependenceInfo were computed for the same Scop.

Michael Kruse via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 20 17:01:14 PDT 2017


Author: meinersbur
Date: Wed Sep 20 17:01:13 2017
New Revision: 313842

URL: http://llvm.org/viewvc/llvm-project?rev=313842&view=rev
Log:
Check whether IslAstInfo and DependenceInfo were computed for the same Scop.

Since -polly-codegen reports itself to preserve DependenceInfo and IslAstInfo,
we might get those analysis that were computed by a different ScopInfo for a
different Scop structure. This would be unfortunate because DependenceInfo and
IslAstInfo hold references to resources allocated by
ScopInfo/ScopBuilder/Scop (e.g. isl_id). If -polly-codegen and
DependenceInfo/IslAstInfo do not agree on which Scop to use, unpredictable
things can happen.

When the ScopInfo/Scop object is freed, there is a high probability that the
new ScopInfo/Scop object will be created at the same heap position with the
same address. Comparing whether the Scop or ScopInfo address is the expected
therefore is unreliable.

Instead, we compare the address of the isl_ctx object. Both, DependenceInfo
and IslAstInfo must hold a reference to the isl_ctx object to ensure it is
not freed before the destruction of those analyses which might happen after
the destruction of the Scop/ScopInfo they refer to.  Hence, the isl_ctx
will not be freed and its address not reused as long there is a
DependenceInfo or IslAstInfo around.

This fixes llvm.org/PR34441

Added:
    polly/trunk/test/Isl/CodeGen/multiple-codegens.ll
Modified:
    polly/trunk/include/polly/CodeGen/IslAst.h
    polly/trunk/include/polly/DependenceInfo.h
    polly/trunk/lib/CodeGen/CodeGeneration.cpp
    polly/trunk/lib/CodeGen/IslAst.cpp
    polly/trunk/lib/Transform/ScheduleOptimizer.cpp
    polly/trunk/test/ScopDetect/base_pointer_load_setNewAccessRelation.ll

Modified: polly/trunk/include/polly/CodeGen/IslAst.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/CodeGen/IslAst.h?rev=313842&r1=313841&r2=313842&view=diff
==============================================================================
--- polly/trunk/include/polly/CodeGen/IslAst.h (original)
+++ polly/trunk/include/polly/CodeGen/IslAst.h Wed Sep 20 17:01:13 2017
@@ -67,6 +67,8 @@ public:
 
   __isl_give isl_ast_node *getAst();
 
+  const std::shared_ptr<isl_ctx> getSharedIslCtx() const { return Ctx; }
+
   /// Get the run-time conditions for the Scop.
   __isl_give isl_ast_expr *getRunCondition();
 
@@ -131,6 +133,9 @@ private:
 public:
   IslAstInfo(Scop &S, const Dependences &D) : S(S), Ast(IslAst::create(S, D)) {}
 
+  /// Return the isl AST computed by this IslAstInfo.
+  IslAst &getIslAst() { return Ast; }
+
   /// Return a copy of the AST root node.
   __isl_give isl_ast_node *getAst();
 

Modified: polly/trunk/include/polly/DependenceInfo.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/DependenceInfo.h?rev=313842&r1=313841&r2=313842&view=diff
==============================================================================
--- polly/trunk/include/polly/DependenceInfo.h (original)
+++ polly/trunk/include/polly/DependenceInfo.h Wed Sep 20 17:01:13 2017
@@ -92,6 +92,8 @@ struct Dependences {
     TYPE_TC_RED = 1 << 4,
   };
 
+  const std::shared_ptr<isl_ctx> &getSharedIslCtx() const { return IslCtx; }
+
   /// Get the dependences of type @p Kinds.
   ///
   /// @param Kinds This integer defines the different kinds of dependences

Modified: polly/trunk/lib/CodeGen/CodeGeneration.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/CodeGeneration.cpp?rev=313842&r1=313841&r2=313842&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/CodeGeneration.cpp (original)
+++ polly/trunk/lib/CodeGen/CodeGeneration.cpp Wed Sep 20 17:01:13 2017
@@ -182,8 +182,27 @@ static void removeLifetimeMarkers(Region
 
 static bool CodeGen(Scop &S, IslAstInfo &AI, LoopInfo &LI, DominatorTree &DT,
                     ScalarEvolution &SE, RegionInfo &RI) {
+  // Check whether IslAstInfo uses the same isl_ctx. Since -polly-codegen
+  // reports itself to preserve DependenceInfo and IslAstInfo, we might get
+  // those analysis that were computed by a different ScopInfo for a different
+  // Scop structure. When the ScopInfo/Scop object is freed, there is a high
+  // probability that the new ScopInfo/Scop object will be created at the same
+  // heap position with the same address. Comparing whether the Scop or ScopInfo
+  // address is the expected therefore is unreliable.
+  // Instead, we compare the address of the isl_ctx object. Both, DependenceInfo
+  // and IslAstInfo must hold a reference to the isl_ctx object to ensure it is
+  // not freed before the destruction of those analyses which might happen after
+  // the destruction of the Scop/ScopInfo they refer to.  Hence, the isl_ctx
+  // will not be freed and its space not reused as long there is a
+  // DependenceInfo or IslAstInfo around.
+  IslAst &Ast = AI.getIslAst();
+  if (Ast.getSharedIslCtx() != S.getSharedIslCtx()) {
+    DEBUG(dbgs() << "Got an IstAst for a different Scop/isl_ctx\n");
+    return false;
+  }
+
   // Check if we created an isl_ast root node, otherwise exit.
-  isl_ast_node *AstRoot = AI.getAst();
+  isl_ast_node *AstRoot = Ast.getAst();
   if (!AstRoot)
     return false;
 

Modified: polly/trunk/lib/CodeGen/IslAst.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/IslAst.cpp?rev=313842&r1=313841&r2=313842&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/IslAst.cpp (original)
+++ polly/trunk/lib/CodeGen/IslAst.cpp Wed Sep 20 17:01:13 2017
@@ -806,6 +806,12 @@ bool IslAstInfoWrapperPass::runOnScop(Sc
   const Dependences &D =
       getAnalysis<DependenceInfo>().getDependences(Dependences::AL_Statement);
 
+  if (D.getSharedIslCtx() != Scop.getSharedIslCtx()) {
+    DEBUG(dbgs() << "Got dependence analysis for different SCoP/isl_ctx\n");
+    Ast.reset();
+    return false;
+  }
+
   Ast.reset(new IslAstInfo(Scop, D));
 
   DEBUG(printScop(dbgs(), Scop));
@@ -815,7 +821,7 @@ bool IslAstInfoWrapperPass::runOnScop(Sc
 void IslAstInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
   // Get the Common analysis usage of ScopPasses.
   ScopPass::getAnalysisUsage(AU);
-  AU.addRequired<ScopInfoRegionPass>();
+  AU.addRequiredTransitive<ScopInfoRegionPass>();
   AU.addRequired<DependenceInfo>();
 
   AU.addPreserved<DependenceInfo>();

Modified: polly/trunk/lib/Transform/ScheduleOptimizer.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Transform/ScheduleOptimizer.cpp?rev=313842&r1=313841&r2=313842&view=diff
==============================================================================
--- polly/trunk/lib/Transform/ScheduleOptimizer.cpp (original)
+++ polly/trunk/lib/Transform/ScheduleOptimizer.cpp Wed Sep 20 17:01:13 2017
@@ -1485,6 +1485,11 @@ bool IslScheduleOptimizer::runOnScop(Sco
   const Dependences &D =
       getAnalysis<DependenceInfo>().getDependences(Dependences::AL_Statement);
 
+  if (D.getSharedIslCtx() != S.getSharedIslCtx()) {
+    DEBUG(dbgs() << "DependenceInfo for another SCoP/isl_ctx\n");
+    return false;
+  }
+
   if (!D.hasValidDependences())
     return false;
 

Added: polly/trunk/test/Isl/CodeGen/multiple-codegens.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/multiple-codegens.ll?rev=313842&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/multiple-codegens.ll (added)
+++ polly/trunk/test/Isl/CodeGen/multiple-codegens.ll Wed Sep 20 17:01:13 2017
@@ -0,0 +1,61 @@
+; RUN: opt %loadPolly -polly-scops -polly-opt-isl -polly-codegen -polly-scops -polly-codegen -S < %s | FileCheck %s
+;
+; llvm.org/PR34441
+; Properly handle multiple -polly-scops/-polly-codegen in the same
+; RegionPassManager. -polly-codegen must not reuse the -polly-ast analysis the
+; was created for the first -polly-scops pass.
+; The current solution is that only the first -polly-codegen is allowed to
+; generate code, the second detects it is re-using an IslAst that belongs to a
+; different ScopInfo.
+;
+; int a, b, c;
+;
+; int main () {
+;  while (a++)
+;    while (b) {
+;        c = 0;
+;        break;
+;      }
+;  return 0;
+; }
+;
+target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
+
+ at a = common global i32 0, align 4
+ at b = common global i32 0, align 4
+ at c = common global i32 0, align 4
+
+; Function Attrs: nounwind uwtable
+define i32 @main() {
+entry:
+  %retval = alloca i32, align 4
+  store i32 0, i32* %retval, align 4
+  %.pre = load i32, i32* @a, align 4
+  br label %while.cond
+
+while.cond:                                       ; preds = %while.end, %entry
+  %0 = phi i32 [ %inc, %while.end ], [ %.pre, %entry ]
+  %inc = add nsw i32 %0, 1
+  store i32 %inc, i32* @a, align 4
+  %tobool = icmp ne i32 %0, 0
+  br i1 %tobool, label %while.body, label %while.end4
+
+while.body:                                       ; preds = %while.cond
+  %1 = load i32, i32* @b, align 4
+  %tobool2 = icmp ne i32 %1, 0
+  br i1 %tobool2, label %while.body3, label %while.end
+
+while.body3:                                      ; preds = %while.body
+  store i32 0, i32* @c, align 4
+  br label %while.end
+
+while.end:                                        ; preds = %while.body3, %while.body
+  br label %while.cond
+
+while.end4:                                       ; preds = %while.cond
+  ret i32 0
+}
+
+
+; CHECK: polly.start:
+; CHECK-NOT: polly.start:

Modified: polly/trunk/test/ScopDetect/base_pointer_load_setNewAccessRelation.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopDetect/base_pointer_load_setNewAccessRelation.ll?rev=313842&r1=313841&r2=313842&view=diff
==============================================================================
--- polly/trunk/test/ScopDetect/base_pointer_load_setNewAccessRelation.ll (original)
+++ polly/trunk/test/ScopDetect/base_pointer_load_setNewAccessRelation.ll Wed Sep 20 17:01:13 2017
@@ -1,4 +1,4 @@
-; RUN: opt %loadPolly -polly-ignore-aliasing -polly-invariant-load-hoisting=true -polly-import-jscop -polly-scops -polly-codegen -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-ignore-aliasing -polly-invariant-load-hoisting=true -polly-scops -polly-import-jscop -polly-codegen -analyze < %s | FileCheck %s
 ;
 ; This violated an assertion in setNewAccessRelation that assumed base pointers
 ; to be load-hoisted. Without this assertion, it codegen would generate invalid




More information about the llvm-commits mailing list