Make memory accesses with different element types optional
authorTobias Grosser <tobias@grosser.es>
Sun, 7 Feb 2016 08:48:57 +0000 (08:48 +0000)
committerTobias Grosser <tobias@grosser.es>
Sun, 7 Feb 2016 08:48:57 +0000 (08:48 +0000)
We also disable this feature by default, as there are still some issues in
combination with invariant load hoisting that slipped through my initial
testing.

llvm-svn: 260025

13 files changed:
polly/include/polly/ScopDetectionDiagnostic.h
polly/lib/Analysis/ScopDetection.cpp
polly/lib/Analysis/ScopDetectionDiagnostic.cpp
polly/lib/CodeGen/CodeGeneration.cpp
polly/test/Isl/CodeGen/MemAccess/multiple_types.ll
polly/test/Isl/CodeGen/invariant_load_different_sized_types.ll
polly/test/Isl/CodeGen/multiple-types-invariant-load-2.ll
polly/test/ScopInfo/multiple-types-access-offset-not-dividable-by-element-size.ll
polly/test/ScopInfo/multiple-types-non-power-of-two-2.ll
polly/test/ScopInfo/multiple-types-non-power-of-two.ll
polly/test/ScopInfo/multiple-types-two-dimensional-2.ll
polly/test/ScopInfo/multiple-types-two-dimensional.ll
polly/test/ScopInfo/multiple-types.ll

index abc60b1..4f16a1c 100644 (file)
@@ -75,6 +75,7 @@ enum RejectReasonKind {
   rrkUndefBasePtr,
   rrkVariantBasePtr,
   rrkNonAffineAccess,
+  rrkDifferentElementSize,
   rrkLastAffFunc,
 
   rrkLoopBound,
@@ -520,6 +521,30 @@ public:
 };
 
 //===----------------------------------------------------------------------===//
+/// @brief Report array accesses with differing element size.
+class ReportDifferentArrayElementSize : public ReportAffFunc {
+  //===--------------------------------------------------------------------===//
+
+  // The base pointer of the memory access.
+  const Value *BaseValue;
+
+public:
+  ReportDifferentArrayElementSize(const Instruction *Inst, const Value *V)
+      : ReportAffFunc(rrkDifferentElementSize, Inst), BaseValue(V) {}
+
+  /// @name LLVM-RTTI interface
+  //@{
+  static bool classof(const RejectReason *RR);
+  //@}
+
+  /// @name RejectReason interface
+  //@{
+  virtual std::string getMessage() const override;
+  virtual std::string getEndUserMessage() const override;
+  //@}
+};
+
+//===----------------------------------------------------------------------===//
 /// @brief Captures errors with non affine loop bounds.
 class ReportLoopBound : public RejectReason {
   //===--------------------------------------------------------------------===//
index 5122c20..3d24596 100644 (file)
@@ -121,6 +121,11 @@ static cl::opt<bool>
                 cl::desc("Print information about the activities of Polly"),
                 cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
 
+static cl::opt<bool> AllowDifferentTypes(
+    "polly-allow-differing-element-types",
+    cl::desc("Allow different element types for array accesses"), cl::Hidden,
+    cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
+
 static cl::opt<bool>
     AllowNonAffine("polly-allow-nonaffine",
                    cl::desc("Allow non affine access functions in arrays"),
@@ -787,11 +792,16 @@ bool ScopDetection::isValidMemoryAccess(MemAccInst Inst,
   AccessFunction = SE->getMinusSCEV(AccessFunction, BasePointer);
 
   const SCEV *Size = SE->getElementSize(Inst);
-  if (Context.ElementSize[BasePointer])
+  if (Context.ElementSize[BasePointer]) {
+    if (!AllowDifferentTypes && Context.ElementSize[BasePointer] != Size)
+      return invalid<ReportDifferentArrayElementSize>(Context, /*Assert=*/true,
+                                                      Inst, BaseValue);
+
     Context.ElementSize[BasePointer] =
         SE->getSMinExpr(Size, Context.ElementSize[BasePointer]);
-  else
+  } else {
     Context.ElementSize[BasePointer] = Size;
+  }
 
   bool isVariantInNonAffineLoop = false;
   SetVector<const Loop *> Loops;
index 879449b..5d5a1a4 100644 (file)
@@ -270,6 +270,24 @@ bool ReportVariantBasePtr::classof(const RejectReason *RR) {
 }
 
 //===----------------------------------------------------------------------===//
+// ReportDifferentArrayElementSize
+
+std::string ReportDifferentArrayElementSize::getMessage() const {
+  return "Access to one array through data types of different size";
+}
+
+bool ReportDifferentArrayElementSize::classof(const RejectReason *RR) {
+  return RR->getKind() == rrkDifferentElementSize;
+}
+
+std::string ReportDifferentArrayElementSize::getEndUserMessage() const {
+  llvm::StringRef BaseName = BaseValue->getName();
+  std::string Name = (BaseName.size() > 0) ? BaseName : "UNKNOWN";
+  return "The array \"" + Name + "\" is accessed through elements that differ "
+                                 "in size";
+}
+
+//===----------------------------------------------------------------------===//
 // ReportNonAffineAccess.
 
 std::string ReportNonAffineAccess::getMessage() const {
index 750c8b9..12ef856 100644 (file)
@@ -174,9 +174,6 @@ public:
       fixRegionInfo(EnteringBB->getParent(), R->getParent());
     }
 
-    assert(!verifyGeneratedFunction(S, *EnteringBB->getParent()) &&
-           "Verification of generated function failed");
-
     // Mark the function such that we run additional cleanup passes on this
     // function (e.g. mem2reg to rediscover phi nodes).
     Function *F = EnteringBB->getParent();
index e7f097f..816ff22 100644 (file)
@@ -1,4 +1,5 @@
 ; RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S \
+; RUN: -polly-allow-differing-element-types \
 ; RUN:   -polly-codegen -S    < %s | FileCheck %s
 ;
 ;    // Check that accessing one array with different types works.
index 32008bd..969a87f 100644 (file)
@@ -1,4 +1,5 @@
-; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-codegen -S \
+; RUN: -polly-allow-differing-element-types < %s | FileCheck %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 
index af269c1..4f3ffb5 100644 (file)
@@ -1,4 +1,5 @@
-; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-codegen -S \
+; RUN: -polly-allow-differing-element-types < %s | FileCheck %s
 
 ; CHECK: polly
 
index cf6ef15..2001d33 100644 (file)
@@ -1,4 +1,5 @@
 ; RUN: opt %loadPolly -polly-scops -pass-remarks-analysis="polly-scops" \
+; RUN: -polly-allow-differing-element-types \
 ; RUN:                -analyze < %s  2>&1 | FileCheck %s
 ;
 ;    // For the following accesses the offset expression from the base pointer
index b499e0e..ec0154c 100644 (file)
@@ -1,4 +1,5 @@
-; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-scops -analyze \
+; RUN: -polly-allow-differing-element-types < %s | FileCheck %s
 ;
 ;  void multiple_types(i128 *A) {
 ;    for (long i = 0; i < 100; i++) {
index 5616a98..f95aa12 100644 (file)
@@ -1,4 +1,5 @@
-; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-scops -analyze \
+; RUN: -polly-allow-differing-element-types < %s | FileCheck %s
 ;
 ;  void multiple_types(i8 *A) {
 ;    for (long i = 0; i < 100; i++) {
index 9946fc0..116bdac 100644 (file)
@@ -1,4 +1,5 @@
 ; RUN: opt %loadPolly -polly-scops -pass-remarks-analysis="polly-scops" \
+; RUN:                -polly-allow-differing-element-types \
 ; RUN:                -analyze < %s  2>&1 | FileCheck %s
 ;
 ;
index b329b54..5885595 100644 (file)
@@ -1,4 +1,5 @@
 ; RUN: opt %loadPolly -polly-scops -pass-remarks-analysis="polly-scops" \
+; RUN: -polly-allow-differing-element-types \
 ; RUN:                -analyze < %s  2>&1 | FileCheck %s
 ;
 ;    void foo(long n, long m, char A[][m]) {
index 84e3935..a776f3e 100644 (file)
@@ -1,4 +1,5 @@
-; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-scops -analyze \
+; RUN: -polly-allow-differing-element-types < %s | FileCheck %s
 ;
 ;    // Check that accessing one array with different types works.
 ;    void multiple_types(char *Short, char *Float, char *Double) {