[polly] r221393 - BlockGenerator: Recompute values from SCEV before handing back the original values

Tobias Grosser tobias at grosser.es
Wed Nov 5 12:48:56 PST 2014


Author: grosser
Date: Wed Nov  5 14:48:56 2014
New Revision: 221393

URL: http://llvm.org/viewvc/llvm-project?rev=221393&view=rev
Log:
BlockGenerator: Recompute values from SCEV before handing back the original values

This patch moves the SCEV based (re)generation of values before the checking for
scop-constant terms. It enables us to provide SCEV based replacements, which
are necessary to correctly generate OpenMP subfunctions when using the SCEV
based code generation.

When recomputing a new value for a value used in the code of the original scop,
we previously directly returned the same original value for all scop-constant
expressions without even trying to regenerate these values using our SCEV
expression. This is correct when the newly generated code remains fully in the
same function, however in case we want to outline parts of the newly generated
scop into subfunctions, this approach means we do not have any opportunity to
update these values in the SCEV based code generation. (In the non-SCEV based
code generation, we can provide such updates through the GlobalMap). To ensure
we have this opportunity, we first try to regenerate scalar terms with our SCEV
builder and will only return scop-constant expressions if SCEV based code
generation was not possible.

This change should not affect the results of the existing code generation
passes. It only impacts the upcoming OpenMP based code generation.

This commit also adds a test case. This test case passes before and after this
commit. It was added to ensure test coverage for the changed code.

Added:
    polly/trunk/test/Isl/CodeGen/scalar-references-used-in-scop-compute.ll
Modified:
    polly/trunk/include/polly/CodeGen/BlockGenerators.h
    polly/trunk/lib/CodeGen/BlockGenerators.cpp

Modified: polly/trunk/include/polly/CodeGen/BlockGenerators.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/CodeGen/BlockGenerators.h?rev=221393&r1=221392&r2=221393&view=diff
==============================================================================
--- polly/trunk/include/polly/CodeGen/BlockGenerators.h (original)
+++ polly/trunk/include/polly/CodeGen/BlockGenerators.h Wed Nov  5 14:48:56 2014
@@ -103,10 +103,11 @@ protected:
   /// @brief Get the new version of a value.
   ///
   /// Given an old value, we first check if a new version of this value is
-  /// available in the BBMap or GlobalMap. If the value is scop constant, we
-  /// assume it is a parameter and return the old value. In case it is not and
-  /// the value can be recomputed using SCEV, we do so. If the value can still
-  /// not be derived, this function will assert.
+  /// available in the BBMap or GlobalMap. In case it is not and the value can
+  /// be recomputed using SCEV, we do so. If we can not recompute a value
+  /// using SCEV, but we understand that the value is constant within the scop,
+  /// we return the old value.  If the value can still not be derived, this
+  /// function will assert.
   ///
   /// @param Old       The old Value.
   /// @param BBMap     A mapping from old values to their new values

Modified: polly/trunk/lib/CodeGen/BlockGenerators.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/BlockGenerators.cpp?rev=221393&r1=221392&r2=221393&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/BlockGenerators.cpp (original)
+++ polly/trunk/lib/CodeGen/BlockGenerators.cpp Wed Nov  5 14:48:56 2014
@@ -88,15 +88,6 @@ Value *BlockGenerator::getNewValue(const
     return New;
   }
 
-  // Or it is probably a scop-constant value defined as global, function
-  // parameter or an instruction not within the scop.
-  if (isa<GlobalValue>(Old) || isa<Argument>(Old))
-    return const_cast<Value *>(Old);
-
-  if (const Instruction *Inst = dyn_cast<Instruction>(Old))
-    if (!Statement.getParent()->getRegion().contains(Inst->getParent()))
-      return const_cast<Value *>(Old);
-
   if (Value *New = BBMap.lookup(Old))
     return New;
 
@@ -117,8 +108,16 @@ Value *BlockGenerator::getNewValue(const
       }
     }
 
-  // Now the scalar dependence is neither available nor SCEVCodegenable, this
-  // should never happen in the current code generator.
+  // A scop-constant value defined by a global or a function parameter.
+  if (isa<GlobalValue>(Old) || isa<Argument>(Old))
+    return const_cast<Value *>(Old);
+
+  // A scop-constant value defined by an instruction executed outside the scop.
+  if (const Instruction *Inst = dyn_cast<Instruction>(Old))
+    if (!Statement.getParent()->getRegion().contains(Inst->getParent()))
+      return const_cast<Value *>(Old);
+
+  // The scalar dependence is neither available nor SCEVCodegenable.
   llvm_unreachable("Unexpected scalar dependence in region!");
   return nullptr;
 }

Added: polly/trunk/test/Isl/CodeGen/scalar-references-used-in-scop-compute.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/scalar-references-used-in-scop-compute.ll?rev=221393&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/scalar-references-used-in-scop-compute.ll (added)
+++ polly/trunk/test/Isl/CodeGen/scalar-references-used-in-scop-compute.ll Wed Nov  5 14:48:56 2014
@@ -0,0 +1,51 @@
+; RUN: opt %loadPolly -polly-codegen-isl -S -polly-codegen-scev < %s | FileCheck %s
+
+; Test the code generation in the presence of a scalar out-of-scop value being
+; used from within the SCoP.
+
+; CHECH-LABEL: @scalar-function-argument
+; CHECK: polly.split_new_and_old
+
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @scalar-function-argument(float* %A, float %sqrinv) {
+entry:
+  br label %for.body
+
+for.body:
+  %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ]
+  %mul104 = fmul float 1.0, %sqrinv
+  %rp107 = getelementptr float* %A, i64 %indvar
+  store float %mul104, float* %rp107, align 4
+  %indvar.next = add nsw i64 %indvar, 1
+  %cmp = icmp slt i64 1024, %indvar.next
+  br i1 %cmp, label %for.end, label %for.body
+
+for.end:
+  ret void
+}
+
+; CHECH-LABEL: @scalar-outside-of-scop
+; CHECK: polly.split_new_and_old
+
+define void @scalar-outside-of-scop(float* %A) {
+entry:
+  %sqrinv = call float @getFloat()
+  br label %for.body
+
+for.body:
+  %indvar = phi i64 [ %indvar.next, %for.body ], [ 0, %entry ]
+  %mul104 = fmul float 1.0, %sqrinv
+  %rp107 = getelementptr float* %A, i64 %indvar
+  store float %mul104, float* %rp107, align 4
+  %indvar.next = add nsw i64 %indvar, 1
+  %cmp = icmp slt i64 1024, %indvar.next
+  br i1 %cmp, label %for.end, label %for.body
+
+for.end:
+  ret void
+}
+
+declare float @getFloat()





More information about the llvm-commits mailing list