From: Tobias Grosser Date: Sun, 7 Feb 2016 08:48:57 +0000 (+0000) Subject: Make memory accesses with different element types optional X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8ebdc2dd53bc3261c4fec059596fbf34aced5765;p=platform%2Fupstream%2Fllvm.git Make memory accesses with different element types optional 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 --- diff --git a/polly/include/polly/ScopDetectionDiagnostic.h b/polly/include/polly/ScopDetectionDiagnostic.h index abc60b1..4f16a1c 100644 --- a/polly/include/polly/ScopDetectionDiagnostic.h +++ b/polly/include/polly/ScopDetectionDiagnostic.h @@ -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 { //===--------------------------------------------------------------------===// diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp index 5122c20..3d24596 100644 --- a/polly/lib/Analysis/ScopDetection.cpp +++ b/polly/lib/Analysis/ScopDetection.cpp @@ -121,6 +121,11 @@ static cl::opt cl::desc("Print information about the activities of Polly"), cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory)); +static cl::opt 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 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(Context, /*Assert=*/true, + Inst, BaseValue); + Context.ElementSize[BasePointer] = SE->getSMinExpr(Size, Context.ElementSize[BasePointer]); - else + } else { Context.ElementSize[BasePointer] = Size; + } bool isVariantInNonAffineLoop = false; SetVector Loops; diff --git a/polly/lib/Analysis/ScopDetectionDiagnostic.cpp b/polly/lib/Analysis/ScopDetectionDiagnostic.cpp index 879449b..5d5a1a4 100644 --- a/polly/lib/Analysis/ScopDetectionDiagnostic.cpp +++ b/polly/lib/Analysis/ScopDetectionDiagnostic.cpp @@ -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 { diff --git a/polly/lib/CodeGen/CodeGeneration.cpp b/polly/lib/CodeGen/CodeGeneration.cpp index 750c8b9..12ef856 100644 --- a/polly/lib/CodeGen/CodeGeneration.cpp +++ b/polly/lib/CodeGen/CodeGeneration.cpp @@ -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(); diff --git a/polly/test/Isl/CodeGen/MemAccess/multiple_types.ll b/polly/test/Isl/CodeGen/MemAccess/multiple_types.ll index e7f097f..816ff22 100644 --- a/polly/test/Isl/CodeGen/MemAccess/multiple_types.ll +++ b/polly/test/Isl/CodeGen/MemAccess/multiple_types.ll @@ -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. diff --git a/polly/test/Isl/CodeGen/invariant_load_different_sized_types.ll b/polly/test/Isl/CodeGen/invariant_load_different_sized_types.ll index 32008bd..969a87f 100644 --- a/polly/test/Isl/CodeGen/invariant_load_different_sized_types.ll +++ b/polly/test/Isl/CodeGen/invariant_load_different_sized_types.ll @@ -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" diff --git a/polly/test/Isl/CodeGen/multiple-types-invariant-load-2.ll b/polly/test/Isl/CodeGen/multiple-types-invariant-load-2.ll index af269c11..4f3ffb5 100644 --- a/polly/test/Isl/CodeGen/multiple-types-invariant-load-2.ll +++ b/polly/test/Isl/CodeGen/multiple-types-invariant-load-2.ll @@ -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 diff --git a/polly/test/ScopInfo/multiple-types-access-offset-not-dividable-by-element-size.ll b/polly/test/ScopInfo/multiple-types-access-offset-not-dividable-by-element-size.ll index cf6ef15..2001d33 100644 --- a/polly/test/ScopInfo/multiple-types-access-offset-not-dividable-by-element-size.ll +++ b/polly/test/ScopInfo/multiple-types-access-offset-not-dividable-by-element-size.ll @@ -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 diff --git a/polly/test/ScopInfo/multiple-types-non-power-of-two-2.ll b/polly/test/ScopInfo/multiple-types-non-power-of-two-2.ll index b499e0e..ec0154c 100644 --- a/polly/test/ScopInfo/multiple-types-non-power-of-two-2.ll +++ b/polly/test/ScopInfo/multiple-types-non-power-of-two-2.ll @@ -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++) { diff --git a/polly/test/ScopInfo/multiple-types-non-power-of-two.ll b/polly/test/ScopInfo/multiple-types-non-power-of-two.ll index 5616a98..f95aa12 100644 --- a/polly/test/ScopInfo/multiple-types-non-power-of-two.ll +++ b/polly/test/ScopInfo/multiple-types-non-power-of-two.ll @@ -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++) { diff --git a/polly/test/ScopInfo/multiple-types-two-dimensional-2.ll b/polly/test/ScopInfo/multiple-types-two-dimensional-2.ll index 9946fc0..116bdac 100644 --- a/polly/test/ScopInfo/multiple-types-two-dimensional-2.ll +++ b/polly/test/ScopInfo/multiple-types-two-dimensional-2.ll @@ -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 ; ; diff --git a/polly/test/ScopInfo/multiple-types-two-dimensional.ll b/polly/test/ScopInfo/multiple-types-two-dimensional.ll index b329b54..5885595 100644 --- a/polly/test/ScopInfo/multiple-types-two-dimensional.ll +++ b/polly/test/ScopInfo/multiple-types-two-dimensional.ll @@ -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]) { diff --git a/polly/test/ScopInfo/multiple-types.ll b/polly/test/ScopInfo/multiple-types.ll index 84e3935..a776f3e 100644 --- a/polly/test/ScopInfo/multiple-types.ll +++ b/polly/test/ScopInfo/multiple-types.ll @@ -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) {