[Polly][PATCH 7/8] [RTC] Build and print alias groups
Johannes Doerfert
doerfert at cs.uni-saarland.de
Sun Aug 10 00:50:28 PDT 2014
This change will build and print all alias groups (minimal/maximal
accesses to possible aliasing base pointers) we have to check before
we can assume an alias free environment.
---
include/polly/ScopDetection.h | 3 +-
include/polly/ScopInfo.h | 40 ++++++-
include/polly/Support/GICHelper.h | 6 ++
lib/Analysis/ScopDetection.cpp | 19 +++-
lib/Analysis/ScopInfo.cpp | 115 +++++++++++++++++++++
test/Isl/CodeGen/MemAccess/codegen_simple_float.ll | 41 ++++++++
.../CodeGen/MemAccess/codegen_simple_md_float.ll | 71 +++++++++++++
.../simple___%for.cond---%for.end14.jscop | 28 +++++
...mple___%for.cond---%for.end14.jscop.transformed | 28 +++++
test/ScopDetect/aliasing_parametric_simple_1.ll | 35 +++++++
test/ScopDetect/aliasing_parametric_simple_2.ll | 39 +++++++
test/ScopDetect/aliasing_simple_1.ll | 33 ++++++
test/ScopDetect/aliasing_simple_2.ll | 36 +++++++
test/ScopInfo/Alias-0.ll | 6 +-
test/ScopInfo/Alias-1.ll | 6 +-
test/ScopInfo/Alias-2.ll | 6 +-
test/ScopInfo/Alias-3.ll | 6 +-
test/ScopInfo/Alias-4.ll | 6 +-
test/ScopInfo/aliasing_multiple_alias_groups.ll | 52 ++++++++++
19 files changed, 562 insertions(+), 14 deletions(-)
create mode 100644 test/Isl/CodeGen/MemAccess/codegen_simple_float.ll
create mode 100644 test/Isl/CodeGen/MemAccess/codegen_simple_md_float.ll
create mode 100644 test/Isl/CodeGen/MemAccess/simple___%for.cond---%for.end14.jscop
create mode 100644 test/Isl/CodeGen/MemAccess/simple___%for.cond---%for.end14.jscop.transformed
create mode 100644 test/ScopDetect/aliasing_parametric_simple_1.ll
create mode 100644 test/ScopDetect/aliasing_parametric_simple_2.ll
create mode 100644 test/ScopDetect/aliasing_simple_1.ll
create mode 100644 test/ScopDetect/aliasing_simple_2.ll
create mode 100644 test/ScopInfo/aliasing_multiple_alias_groups.ll
diff --git a/include/polly/ScopDetection.h b/include/polly/ScopDetection.h
index 96eeaef..1fd6b1d 100644
--- a/include/polly/ScopDetection.h
+++ b/include/polly/ScopDetection.h
@@ -107,6 +107,7 @@ typedef std::map<const SCEVUnknown *, const SCEV *> BaseToElSize;
extern bool PollyTrackFailures;
extern bool PollyDelinearize;
+extern bool PollyUseRuntimeAliasChecks;
/// @brief A function attribute which will cause Polly to skip the function
extern llvm::StringRef PollySkipFnAttr;
@@ -267,7 +268,7 @@ class ScopDetection : public FunctionPass {
public:
static char ID;
- explicit ScopDetection() : FunctionPass(ID) {}
+ explicit ScopDetection();
/// @brief Get the RegionInfo stored in this pass.
///
diff --git a/include/polly/ScopInfo.h b/include/polly/ScopInfo.h
index 7c7afb6..c5a9e14 100644
--- a/include/polly/ScopInfo.h
+++ b/include/polly/ScopInfo.h
@@ -47,6 +47,7 @@ struct isl_union_set;
struct isl_union_map;
struct isl_space;
struct isl_constraint;
+struct isl_pw_multi_aff;
namespace polly {
@@ -493,7 +494,17 @@ static inline raw_ostream &operator<<(raw_ostream &O, const ScopStmt &S) {
/// This context contains information about the values the parameters
/// can take and relations between different parameters.
class Scop {
- //===-------------------------------------------------------------------===//
+public:
+ /// @brief Type to represent a pair of minimal/maximal access to an array.
+ using MinMaxAccessTy = std::pair<isl_pw_multi_aff *, isl_pw_multi_aff *>;
+
+ /// @brief A vector of minimal/maximal accesses to different arrays.
+ using MinMaxVectorTy = SmallVector<MinMaxAccessTy, 4>;
+
+ /// @brief A set of minimal/maximal access vectors one for each alias group.
+ using MinMaxVectorSetTy = SmallPtrSet<MinMaxVectorTy *, 4>;
+
+private:
Scop(const Scop &) LLVM_DELETED_FUNCTION;
const Scop &operator=(const Scop &) LLVM_DELETED_FUNCTION;
@@ -532,6 +543,21 @@ class Scop {
/// this scop and that need to be code generated as a run-time test.
isl_set *AssumedContext;
+ /// @brief The set of minimal/maximal accesses for each alias group.
+ ///
+ /// When building runtime alias checks we look at all memory instructions and
+ /// build so called alias groups. Each group contains a set of a accesses to
+ /// different base arrays which might alias with each other. However, between
+ /// alias groups there is no aliasing possible.
+ ///
+ /// In a program with int and float pointer annotated with tbaa information we
+ /// would probably generate two alias groups, one for the int pointers and one
+ /// for the float pointers.
+ ///
+ /// During code generation we will create a runtime alias check for each alias
+ /// group to ensure the SCoP is executed in a alias free environment.
+ MinMaxVectorSetTy MinMaxAliasGroups;
+
/// Create the static control part with a region, max loop depth of this
/// region and parameters used in this region.
Scop(TempScop &TempScop, LoopInfo &LI, ScalarEvolution &SE, isl_ctx *ctx);
@@ -563,9 +589,13 @@ class Scop {
// The scattering numbers
SmallVectorImpl<unsigned> &Scatter, LoopInfo &LI);
- /// Helper function for printing the Scop.
+ /// @name Helper function for printing the Scop.
+ ///
+ ///{
void printContext(raw_ostream &OS) const;
void printStatements(raw_ostream &OS) const;
+ void printAliasAssumptions(raw_ostream &OS) const;
+ ///}
friend class ScopInfo;
@@ -664,6 +694,12 @@ public:
/// to hold.
void addAssumption(__isl_take isl_set *Set);
+ /// @brief Build all alias groups for this SCoP.
+ void buildAliasGroups(AliasAnalysis &AA);
+
+ /// @brief Return all alias groups for this SCoP.
+ const MinMaxVectorSetTy &getAliasGroups() const { return MinMaxAliasGroups; }
+
/// @brief Get an isl string representing the context.
std::string getContextStr() const;
diff --git a/include/polly/Support/GICHelper.h b/include/polly/Support/GICHelper.h
index 39c2336..c5fb4a1 100755
--- a/include/polly/Support/GICHelper.h
+++ b/include/polly/Support/GICHelper.h
@@ -65,6 +65,12 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
return OS;
}
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+ __isl_keep isl_pw_multi_aff *PMA) {
+ OS << polly::stringFromIslObj(PMA);
+ return OS;
+}
+
/// @brief Return @p Prefix + @p Val->getName() + @p Suffix but Isl compatible.
std::string getIslCompatibleName(std::string Prefix, const llvm::Value *Val,
std::string Suffix);
diff --git a/lib/Analysis/ScopDetection.cpp b/lib/Analysis/ScopDetection.cpp
index 75d6731..ed191f0 100644
--- a/lib/Analysis/ScopDetection.cpp
+++ b/lib/Analysis/ScopDetection.cpp
@@ -184,6 +184,23 @@ void DiagnosticScopFound::print(DiagnosticPrinter &DP) const {
//===----------------------------------------------------------------------===//
// ScopDetection.
+ScopDetection::ScopDetection() : FunctionPass(ID) {
+ if (!PollyUseRuntimeAliasChecks)
+ return;
+
+ if (PollyDelinearize) {
+ DEBUG(errs() << "WARNING: We disable runtime alias checks as "
+ "delinearization is enabled.\n");
+ PollyUseRuntimeAliasChecks = false;
+ }
+
+ if (AllowNonAffine) {
+ DEBUG(errs() << "WARNING: We disable runtime alias checks as non affine "
+ "accesses are enabled.\n");
+ PollyUseRuntimeAliasChecks = false;
+ }
+}
+
template <class RR, typename... Args>
inline bool ScopDetection::invalid(DetectionContext &Context, bool Assert,
Args &&... Arguments) const {
@@ -464,7 +481,7 @@ bool ScopDetection::isValidMemoryAccess(Instruction &Inst,
if (IntToPtrInst *Inst = dyn_cast<IntToPtrInst>(BaseValue))
return invalid<ReportIntToPtr>(Context, /*Assert=*/true, Inst);
- if (IgnoreAliasing)
+ if (PollyUseRuntimeAliasChecks || IgnoreAliasing)
return true;
// Check if the base pointer of the memory access does alias with
diff --git a/lib/Analysis/ScopInfo.cpp b/lib/Analysis/ScopInfo.cpp
index 963aa80..317e8a3 100644
--- a/lib/Analysis/ScopInfo.cpp
+++ b/lib/Analysis/ScopInfo.cpp
@@ -29,6 +29,7 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/RegionIterator.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Support/Debug.h"
@@ -63,6 +64,13 @@ static cl::opt<bool> DisableMultiplicativeReductions(
cl::desc("Disable multiplicative reductions"), cl::Hidden, cl::ZeroOrMore,
cl::init(false), cl::cat(PollyCategory));
+bool polly::PollyUseRuntimeAliasChecks;
+static cl::opt<bool, true> XPollyUseRuntimeAliasChecks(
+ "polly-use-runtime-alias-checks",
+ cl::desc("Use runtime alias checks to resolve possible aliasing."),
+ cl::location(PollyUseRuntimeAliasChecks), cl::Hidden, cl::ZeroOrMore,
+ cl::init(false), cl::cat(PollyCategory));
+
/// Translate a 'const SCEV *' expression in an isl_pw_aff.
struct SCEVAffinator : public SCEVVisitor<SCEVAffinator, isl_pw_aff *> {
public:
@@ -1118,6 +1126,85 @@ void Scop::simplifyAssumedContext() {
isl_set_gist_params(AssumedContext, isl_union_set_params(getDomains()));
}
+/// @brief Add the minimal/maximal access in @p Set to @p User.
+static int buildMinMaxAccess(__isl_take isl_set *Set, void *User) {
+ Scop::MinMaxVectorTy *MinMaxAccesses = (Scop::MinMaxVectorTy *)User;
+ isl_pw_multi_aff *MinPMA, *MaxPMA;
+
+ MinPMA = isl_set_lexmin_pw_multi_aff(isl_set_copy(Set));
+ MaxPMA = isl_set_lexmax_pw_multi_aff(isl_set_copy(Set));
+
+ MinMaxAccesses->push_back(std::make_pair(MinPMA, MaxPMA));
+
+ isl_set_free(Set);
+ return 0;
+}
+
+void Scop::buildAliasGroups(AliasAnalysis &AA) {
+ // To create sound alias checks we perform the following steps:
+ // o) Use the alias analysis and an alias set tracker to build alias sets
+ // for all memory accesses inside the SCoP.
+ // 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
+ // and maximal accesses to each array in this group.
+ using AliasGroupTy = SmallVector<MemoryAccess *, 4>;
+
+ AliasSetTracker AST(AA);
+
+ DenseMap<Value *, MemoryAccess *> PtrToAcc;
+ for (ScopStmt *Stmt : *this) {
+ for (MemoryAccess *MA : *Stmt) {
+ Instruction *Acc = MA->getAccessInstruction();
+ PtrToAcc[getPointerOperand(*Acc)] = MA;
+ AST.add(Acc);
+ }
+ }
+
+ SmallVector<AliasGroupTy, 4> AliasGroups;
+ for (AliasSet &AS : AST) {
+ if (AS.isMustAlias())
+ continue;
+ AliasGroupTy AG;
+ for (auto PR : AS)
+ AG.push_back(PtrToAcc[PR.getValue()]);
+ assert(AG.size() > 1 &&
+ "Alias groups should contain at least two accesses");
+ 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);
+ }
+
+ for (AliasGroupTy &AG : AliasGroups) {
+ MinMaxVectorTy *MinMaxAccesses = new MinMaxVectorTy();
+ MinMaxAccesses->reserve(AG.size());
+
+ isl_union_map *Accesses = isl_union_map_empty(getParamSpace());
+ for (MemoryAccess *MA : AG)
+ Accesses = isl_union_map_add_map(Accesses, MA->getAccessRelation());
+ Accesses = isl_union_map_intersect_domain(Accesses, getDomains());
+
+ isl_union_set *Locations = isl_union_map_range(Accesses);
+ Locations = isl_union_set_intersect_params(Locations, getAssumedContext());
+ Locations = isl_union_set_coalesce(Locations);
+ Locations = isl_union_set_detect_equalities(Locations);
+ isl_union_set_foreach_set(Locations, buildMinMaxAccess, MinMaxAccesses);
+ isl_union_set_free(Locations);
+
+ MinMaxAliasGroups.insert(MinMaxAccesses);
+ }
+}
+
Scop::Scop(TempScop &tempScop, LoopInfo &LI, ScalarEvolution &ScalarEvolution,
isl_ctx *Context)
: SE(&ScalarEvolution), R(tempScop.getMaxRegion()),
@@ -1148,6 +1235,13 @@ Scop::~Scop() {
// Free the statements;
for (ScopStmt *Stmt : *this)
delete Stmt;
+
+ // Free the alias groups
+ for (MinMaxVectorTy *MinMaxAccesses : MinMaxAliasGroups) {
+ for (MinMaxAccessTy &MMA : *MinMaxAccesses)
+ isl_pw_multi_aff_free(MMA.first) || isl_pw_multi_aff_free(MMA.second);
+ delete MinMaxAccesses;
+ }
}
std::string Scop::getContextStr() const { return stringFromIslObj(Context); }
@@ -1209,6 +1303,20 @@ void Scop::printContext(raw_ostream &OS) const {
}
}
+void Scop::printAliasAssumptions(raw_ostream &OS) const {
+ OS.indent(4) << "Alias Groups (" << MinMaxAliasGroups.size() << "):\n";
+ if (MinMaxAliasGroups.empty()) {
+ OS.indent(8) << "n/a\n";
+ return;
+ }
+ for (MinMaxVectorTy *MinMaxAccesses : MinMaxAliasGroups) {
+ OS.indent(8) << "[[";
+ for (MinMaxAccessTy &MinMacAccess : *MinMaxAccesses)
+ OS << " <" << MinMacAccess.first << ", " << MinMacAccess.second << ">";
+ OS << " ]]\n";
+ }
+}
+
void Scop::printStatements(raw_ostream &OS) const {
OS << "Statements {\n";
@@ -1223,6 +1331,7 @@ void Scop::print(raw_ostream &OS) const {
<< "\n";
OS.indent(4) << "Region: " << getNameStr() << "\n";
printContext(OS.indent(4));
+ printAliasAssumptions(OS);
printStatements(OS.indent(4));
}
@@ -1409,11 +1518,13 @@ void ScopInfo::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<RegionInfoPass>();
AU.addRequired<ScalarEvolution>();
AU.addRequired<TempScopInfo>();
+ AU.addRequired<AliasAnalysis>();
AU.setPreservesAll();
}
bool ScopInfo::runOnRegion(Region *R, RGPassManager &RGM) {
LoopInfo &LI = getAnalysis<LoopInfo>();
+ AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
ScalarEvolution &SE = getAnalysis<ScalarEvolution>();
TempScop *tempScop = getAnalysis<TempScopInfo>().getTempScop(R);
@@ -1431,6 +1542,9 @@ bool ScopInfo::runOnRegion(Region *R, RGPassManager &RGM) {
scop = new Scop(*tempScop, LI, SE, ctx);
+ if (PollyUseRuntimeAliasChecks)
+ scop->buildAliasGroups(AA);
+
return false;
}
@@ -1441,6 +1555,7 @@ Pass *polly::createScopInfoPass() { return new ScopInfo(); }
INITIALIZE_PASS_BEGIN(ScopInfo, "polly-scops",
"Polly - Create polyhedral description of Scops", false,
false);
+INITIALIZE_AG_DEPENDENCY(AliasAnalysis);
INITIALIZE_PASS_DEPENDENCY(LoopInfo);
INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
INITIALIZE_PASS_DEPENDENCY(ScalarEvolution);
diff --git a/test/Isl/CodeGen/MemAccess/codegen_simple_float.ll b/test/Isl/CodeGen/MemAccess/codegen_simple_float.ll
new file mode 100644
index 0000000..01b1b55
--- /dev/null
+++ b/test/Isl/CodeGen/MemAccess/codegen_simple_float.ll
@@ -0,0 +1,41 @@
+;RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed -polly-codegen-isl -instnamer < %s -S | FileCheck %s
+;
+;float A[100];
+;
+;int codegen_simple () {
+; for (int i = 0; i < 12; i++)
+; A[13] = A[i] + A[i-1];
+;
+; return 0;
+;}
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
+
+ at A = common global [100 x float] zeroinitializer, align 4
+
+define i32 @codegen_simple() nounwind {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %tmp1 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+ %tmp = add i32 %tmp1, -1
+ %arrayidx4 = getelementptr [100 x float]* @A, i32 0, i32 %tmp
+ %arrayidx = getelementptr [100 x float]* @A, i32 0, i32 %tmp1
+ %exitcond = icmp ne i32 %tmp1, 12
+ br i1 %exitcond, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %tmp2 = load float* %arrayidx, align 4
+ %tmp5 = load float* %arrayidx4, align 4
+ %add = fadd float %tmp2, %tmp5
+ store float %add, float* getelementptr inbounds ([100 x float]* @A, i32 0, i32 13), align 4
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %inc = add nsw i32 %tmp1, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret i32 0
+}
+; CHECK: load float* getelementptr inbounds ([100 x float]* @A, i64 0, i64 0)
diff --git a/test/Isl/CodeGen/MemAccess/codegen_simple_md_float.ll b/test/Isl/CodeGen/MemAccess/codegen_simple_md_float.ll
new file mode 100644
index 0000000..01bd46d
--- /dev/null
+++ b/test/Isl/CodeGen/MemAccess/codegen_simple_md_float.ll
@@ -0,0 +1,71 @@
+;RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed+withconst -polly-codegen-isl < %s -S | FileCheck -check-prefix=WITHCONST %s
+;RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed+withoutconst -polly-codegen-isl < %s -S | FileCheck -check-prefix=WITHOUTCONST %s
+;RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed+withconst -polly-codegen-isl -polly-codegen-scev < %s -S | FileCheck -check-prefix=WITHCONST %s
+;RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed+withoutconst -polly-codegen-isl -polly-codegen-scev < %s -S | FileCheck -check-prefix=WITHOUTCONST %s
+;
+;float A[1040];
+;
+;int codegen_simple_md() {
+; for (int i = 0; i < 32; ++i)
+; for (int j = 0; j < 32; ++j)
+; A[32*i+j] = 100;
+;}
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
+
+ at A = common global [1040 x float] zeroinitializer, align 4
+
+define void @codegen_simple_md() nounwind {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc4, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc5, %for.inc4 ]
+ %exitcond1 = icmp ne i32 %i.0, 32
+ br i1 %exitcond1, label %for.body, label %for.end6
+
+for.body: ; preds = %for.cond
+ br label %for.cond1
+
+for.cond1: ; preds = %for.inc, %for.body
+ %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ]
+ %exitcond = icmp ne i32 %j.0, 32
+ br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3: ; preds = %for.cond1
+ %mul = shl nsw i32 %i.0, 5
+ %add = add nsw i32 %mul, %j.0
+ %arrayidx = getelementptr inbounds [1040 x float]* @A, i32 0, i32 %add
+ store float 100.0, float* %arrayidx, align 4
+ br label %for.inc
+
+for.inc: ; preds = %for.body3
+ %inc = add nsw i32 %j.0, 1
+ br label %for.cond1
+
+for.end: ; preds = %for.cond1
+ br label %for.inc4
+
+for.inc4: ; preds = %for.end
+ %inc5 = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end6: ; preds = %for.cond
+ ret void
+}
+
+; WITHCONST: %[[IVOut:polly.indvar[0-9]*]] = phi i64 [ 0, %polly.loop_preheader{{[0-9]*}} ], [ %polly.indvar_next{{[0-9]*}}, %polly.{{[._a-zA-Z0-9]*}} ]
+; WITHCONST: %[[IVIn:polly.indvar[0-9]*]] = phi i64 [ 0, %polly.loop_preheader{{[0-9]*}} ], [ %polly.indvar_next{{[0-9]*}}, %polly.{{[._a-zA-Z0-9]*}} ]
+; WITHCONST: %[[MUL1:[._a-zA-Z0-9]+]] = mul nsw i64 16, %[[IVOut]]
+; WITHCONST: %[[MUL2:[._a-zA-Z0-9]+]] = mul nsw i64 2, %[[IVIn]]
+; WITHCONST: %[[SUM1:[._a-zA-Z0-9]+]] = add nsw i64 %[[MUL1]], %[[MUL2]]
+; WITHCONST: %[[SUM2:[._a-zA-Z0-9]+]] = add nsw i64 %[[SUM1]], 5
+; WITHCONST: %[[ACC:[._a-zA-Z0-9]*]] = getelementptr [1040 x float]* @A, i64 0, i64 %[[SUM2]]
+; WITHCONST: store float 1.000000e+02, float* %[[ACC]]
+
+; WITHOUTCONST: %[[IVOut:polly.indvar[0-9]*]] = phi i64 [ 0, %polly.loop_preheader{{[0-9]*}} ], [ %polly.indvar_next{{[0-9]*}}, %polly.{{[._a-zA-Z0-9]*}} ]
+; WITHOUTCONST: %[[IVIn:polly.indvar[0-9]*]] = phi i64 [ 0, %polly.loop_preheader{{[0-9]*}} ], [ %polly.indvar_next{{[0-9]*}}, %polly.{{[._a-zA-Z0-9]*}} ]
+; WITHOUTCONST: %[[MUL1:[._a-zA-Z0-9]+]] = mul nsw i64 16, %[[IVOut]]
+; WITHOUTCONST: %[[MUL2:[._a-zA-Z0-9]+]] = mul nsw i64 2, %[[IVIn]]
+; WITHOUTCONST: %[[SUM1:[._a-zA-Z0-9]+]] = add nsw i64 %[[MUL1]], %[[MUL2]]
+; WITHOUTCONST: %[[ACC:[._a-zA-Z0-9]*]] = getelementptr [1040 x float]* @A, i64 0, i64 %[[SUM1]]
+; WITHOUTCONST: store float 1.000000e+02, float* %[[ACC]]
diff --git a/test/Isl/CodeGen/MemAccess/simple___%for.cond---%for.end14.jscop b/test/Isl/CodeGen/MemAccess/simple___%for.cond---%for.end14.jscop
new file mode 100644
index 0000000..88fafec
--- /dev/null
+++ b/test/Isl/CodeGen/MemAccess/simple___%for.cond---%for.end14.jscop
@@ -0,0 +1,28 @@
+{
+ "context" : "{ : }",
+ "name" : "for.cond => for.end14",
+ "statements" : [
+ {
+ "accesses" : [
+ {
+ "kind" : "write",
+ "relation" : "{ Stmt_for_body[i0] -> MemRef_A[i0] }"
+ }
+ ],
+ "domain" : "{ Stmt_for_body[i0] : i0 >= 0 and i0 <= 11 }",
+ "name" : "Stmt_for_body",
+ "schedule" : "{ Stmt_for_body[i0] -> scattering[0, i0, 0] }"
+ },
+ {
+ "accesses" : [
+ {
+ "kind" : "write",
+ "relation" : "{ Stmt_for_body7[i0] -> MemRef_B[i0] }"
+ }
+ ],
+ "domain" : "{ Stmt_for_body7[i0] : i0 >= 0 and i0 <= 11 }",
+ "name" : "Stmt_for_body7",
+ "schedule" : "{ Stmt_for_body7[i0] -> scattering[0, i0, 0] }"
+ }
+ ]
+}
diff --git a/test/Isl/CodeGen/MemAccess/simple___%for.cond---%for.end14.jscop.transformed b/test/Isl/CodeGen/MemAccess/simple___%for.cond---%for.end14.jscop.transformed
new file mode 100644
index 0000000..b1808f1
--- /dev/null
+++ b/test/Isl/CodeGen/MemAccess/simple___%for.cond---%for.end14.jscop.transformed
@@ -0,0 +1,28 @@
+{
+ "context" : "{ : }",
+ "name" : "for.cond => for.end14",
+ "statements" : [
+ {
+ "accesses" : [
+ {
+ "kind" : "write",
+ "relation" : "{ Stmt_for_body[i0] -> MemRef_A[0] }"
+ }
+ ],
+ "domain" : "{ Stmt_for_body[i0] : i0 >= 0 and i0 <= 11 }",
+ "name" : "Stmt_for_body",
+ "schedule" : "{ Stmt_for_body[i0] -> scattering[0, i0, 0] }"
+ },
+ {
+ "accesses" : [
+ {
+ "kind" : "write",
+ "relation" : "{ Stmt_for_body7[i0] -> MemRef_B[0] }"
+ }
+ ],
+ "domain" : "{ Stmt_for_body7[i0] : i0 >= 0 and i0 <= 11 }",
+ "name" : "Stmt_for_body7",
+ "schedule" : "{ Stmt_for_body7[i0] -> scattering[0, i0, 0] }"
+ }
+ ]
+}
diff --git a/test/ScopDetect/aliasing_parametric_simple_1.ll b/test/ScopDetect/aliasing_parametric_simple_1.ll
new file mode 100644
index 0000000..a5fdfdb
--- /dev/null
+++ b/test/ScopDetect/aliasing_parametric_simple_1.ll
@@ -0,0 +1,35 @@
+; RUN: opt %loadPolly -polly-use-runtime-alias-checks=true -polly-detect -analyze < %s | FileCheck %s
+;
+; CHECK: Valid Region for Scop:
+;
+; void jd(int *A, int *B, int c) {
+; for (int i = 0; i < 1024; i++)
+; A[i] = B[c];
+; }
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @jd(i32* %A, i32* %B, i32 %c) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
+ %exitcond = icmp ne i64 %indvars.iv, 1024
+ br i1 %exitcond, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %idxprom = sext i32 %c to i64
+ %arrayidx = getelementptr inbounds i32* %B, i64 %idxprom
+ %tmp = load i32* %arrayidx, align 4
+ %arrayidx2 = getelementptr inbounds i32* %A, i64 %indvars.iv
+ store i32 %tmp, i32* %arrayidx2, align 4
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
diff --git a/test/ScopDetect/aliasing_parametric_simple_2.ll b/test/ScopDetect/aliasing_parametric_simple_2.ll
new file mode 100644
index 0000000..f518d68
--- /dev/null
+++ b/test/ScopDetect/aliasing_parametric_simple_2.ll
@@ -0,0 +1,39 @@
+; RUN: opt %loadPolly -polly-use-runtime-alias-checks=true -polly-detect -analyze < %s | FileCheck %s
+;
+; CHECK: Valid Region for Scop:
+;
+; void jd(int *A, int *B, int c) {
+; for (int i = 0; i < 1024; i++)
+; A[i] = B[c - 10] + B[5];
+; }
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @jd(i32* %A, i32* %B, i32 %c) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
+ %exitcond = icmp ne i64 %indvars.iv, 1024
+ br i1 %exitcond, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %sub = add nsw i32 %c, -10
+ %idxprom = sext i32 %sub to i64
+ %arrayidx = getelementptr inbounds i32* %B, i64 %idxprom
+ %tmp = load i32* %arrayidx, align 4
+ %arrayidx1 = getelementptr inbounds i32* %B, i64 5
+ %tmp1 = load i32* %arrayidx1, align 4
+ %add = add nsw i32 %tmp, %tmp1
+ %arrayidx3 = getelementptr inbounds i32* %A, i64 %indvars.iv
+ store i32 %add, i32* %arrayidx3, align 4
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
diff --git a/test/ScopDetect/aliasing_simple_1.ll b/test/ScopDetect/aliasing_simple_1.ll
new file mode 100644
index 0000000..9009111
--- /dev/null
+++ b/test/ScopDetect/aliasing_simple_1.ll
@@ -0,0 +1,33 @@
+; RUN: opt %loadPolly -polly-use-runtime-alias-checks=true -polly-detect -analyze < %s | FileCheck %s
+;
+; CHECK: Valid Region for Scop:
+;
+; void jd(int *A, int *B) {
+; for (int i = 0; i < 1024; i++)
+; A[i] = B[0];
+; }
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @jd(i32* %A, i32* %B) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
+ %exitcond = icmp ne i64 %indvars.iv, 1024
+ br i1 %exitcond, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %tmp = load i32* %B, align 4
+ %arrayidx2 = getelementptr inbounds i32* %A, i64 %indvars.iv
+ store i32 %tmp, i32* %arrayidx2, align 4
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
diff --git a/test/ScopDetect/aliasing_simple_2.ll b/test/ScopDetect/aliasing_simple_2.ll
new file mode 100644
index 0000000..5db8e6f
--- /dev/null
+++ b/test/ScopDetect/aliasing_simple_2.ll
@@ -0,0 +1,36 @@
+; RUN: opt %loadPolly -polly-use-runtime-alias-checks=true -polly-detect -analyze < %s | FileCheck %s
+;
+; CHECK: Valid Region for Scop:
+;
+; void jd(int *A, int *B) {
+; for (int i = 0; i < 1024; i++)
+; A[i] = B[0] + B[1023];
+; }
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @jd(i32* %A, i32* %B) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
+ %exitcond = icmp ne i64 %indvars.iv, 1024
+ br i1 %exitcond, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %tmp = load i32* %B, align 4
+ %arrayidx1 = getelementptr inbounds i32* %B, i64 1023
+ %tmp1 = load i32* %arrayidx1, align 4
+ %add = add nsw i32 %tmp, %tmp1
+ %arrayidx2 = getelementptr inbounds i32* %A, i64 %indvars.iv
+ store i32 %add, i32* %arrayidx2, align 4
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
diff --git a/test/ScopInfo/Alias-0.ll b/test/ScopInfo/Alias-0.ll
index 8474131..3d64e8d 100755
--- a/test/ScopInfo/Alias-0.ll
+++ b/test/ScopInfo/Alias-0.ll
@@ -1,4 +1,5 @@
-; RUN: opt %loadPolly -polly-analyze-ir -analyze < %s -stats 2>&1 | FileCheck %s
+; RUN: opt %loadPolly -polly-analyze-ir -polly-use-runtime-alias-checks=true -analyze < %s -stats 2>&1 | FileCheck %s --check-prefix=RTA
+; RUN: opt %loadPolly -polly-analyze-ir -polly-use-runtime-alias-checks=false -analyze < %s -stats 2>&1 | FileCheck %s --check-prefix=NORTA
; REQUIRES: asserts
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
@@ -32,4 +33,5 @@ return: ; preds = %bb3
declare i32 @rnd(...)
-; CHECK: 1 polly-detect - Number of bad regions for Scop: Found base address alias
+; RTA: 1 polly-detect - Number of regions that a valid part of Scop
+; NORTA: 1 polly-detect - Number of bad regions for Scop: Found base address alias
diff --git a/test/ScopInfo/Alias-1.ll b/test/ScopInfo/Alias-1.ll
index c8f0093..c33f73d 100755
--- a/test/ScopInfo/Alias-1.ll
+++ b/test/ScopInfo/Alias-1.ll
@@ -1,4 +1,5 @@
-; RUN: opt %loadPolly -polly-analyze-ir -analyze < %s -stats 2>&1 | FileCheck %s
+; RUN: opt %loadPolly -polly-analyze-ir -polly-use-runtime-alias-checks=true -analyze < %s -stats 2>&1 | FileCheck %s --check-prefix=RTA
+; RUN: opt %loadPolly -polly-analyze-ir -polly-use-runtime-alias-checks=false -analyze < %s -stats 2>&1 | FileCheck %s --check-prefix=NORTA
; REQUIRES: asserts
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
@@ -33,4 +34,5 @@ return: ; preds = %bb3
declare i32 @rnd(...)
-; CHECK: 1 polly-detect - Number of bad regions for Scop: Found base address alias
+; RTA: 1 polly-detect - Number of regions that a valid part of Scop
+; NORTA: 1 polly-detect - Number of bad regions for Scop: Found base address alias
diff --git a/test/ScopInfo/Alias-2.ll b/test/ScopInfo/Alias-2.ll
index 3a70bf4..0be3e73 100755
--- a/test/ScopInfo/Alias-2.ll
+++ b/test/ScopInfo/Alias-2.ll
@@ -1,4 +1,5 @@
-; RUN: opt %loadPolly -polly-analyze-ir -analyze < %s -stats 2>&1 | FileCheck %s
+; RUN: opt %loadPolly -polly-analyze-ir -polly-use-runtime-alias-checks=true -analyze < %s -stats 2>&1 | FileCheck %s --check-prefix=RTA
+; RUN: opt %loadPolly -polly-analyze-ir -polly-use-runtime-alias-checks=false -analyze < %s -stats 2>&1 | FileCheck %s --check-prefix=NORTA
; REQUIRES: asserts
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
@@ -31,4 +32,5 @@ return: ; preds = %bb
ret void
}
-; CHECK: 1 polly-detect - Number of bad regions for Scop: Found base address alias
+; RTA: 1 polly-detect - Number of regions that a valid part of Scop
+; NORTA: 1 polly-detect - Number of bad regions for Scop: Found base address alias
diff --git a/test/ScopInfo/Alias-3.ll b/test/ScopInfo/Alias-3.ll
index 7ad9ad6..89d0140 100755
--- a/test/ScopInfo/Alias-3.ll
+++ b/test/ScopInfo/Alias-3.ll
@@ -1,4 +1,5 @@
-; RUN: opt %loadPolly -polly-analyze-ir -analyze < %s -stats 2>&1 | FileCheck %s
+; RUN: opt %loadPolly -polly-analyze-ir -polly-use-runtime-alias-checks=true -analyze < %s -stats 2>&1 | FileCheck %s --check-prefix=RTA
+; RUN: opt %loadPolly -polly-analyze-ir -polly-use-runtime-alias-checks=false -analyze < %s -stats 2>&1 | FileCheck %s --check-prefix=NORTA
; REQUIRES: asserts
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
@@ -24,4 +25,5 @@ return: ; preds = %bb
}
-; CHECK: 1 polly-detect - Number of bad regions for Scop: Found base address alias
+; RTA: 1 polly-detect - Number of regions that a valid part of Scop
+; NORTA: 1 polly-detect - Number of bad regions for Scop: Found base address alias
diff --git a/test/ScopInfo/Alias-4.ll b/test/ScopInfo/Alias-4.ll
index a47f799..92fd76e 100755
--- a/test/ScopInfo/Alias-4.ll
+++ b/test/ScopInfo/Alias-4.ll
@@ -1,4 +1,5 @@
-; RUN: opt %loadPolly -basicaa -polly-analyze-ir -analyze < %s -stats 2>&1 | not FileCheck %s
+; RUN: opt %loadPolly -polly-analyze-ir -polly-use-runtime-alias-checks=true -analyze < %s -stats 2>&1 | FileCheck %s --check-prefix=RTA
+; RUN: opt %loadPolly -polly-analyze-ir -polly-use-runtime-alias-checks=false -analyze < %s -stats 2>&1 | FileCheck %s --check-prefix=NORTA
; REQUIRES: asserts
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
@@ -24,4 +25,5 @@ return: ; preds = %bb
}
-; CHECK: Found base address alias
+; RTA: 1 polly-detect - Number of regions that a valid part of Scop
+; NORTA: 1 polly-detect - Number of bad regions for Scop: Found base address alias
diff --git a/test/ScopInfo/aliasing_multiple_alias_groups.ll b/test/ScopInfo/aliasing_multiple_alias_groups.ll
new file mode 100644
index 0000000..24d7f86
--- /dev/null
+++ b/test/ScopInfo/aliasing_multiple_alias_groups.ll
@@ -0,0 +1,52 @@
+; RUN: opt %loadPolly -polly-use-runtime-alias-checks=true -polly-scops -analyze < %s | FileCheck %s --check-prefix=NOAA
+; RUN: opt %loadPolly -polly-use-runtime-alias-checks=true -polly-scops -analyze -tbaa < %s | FileCheck %s --check-prefix=TBAA
+;
+; void jd(int *Int0, int *Int1, float *Float0, float *Float1) {
+; for (int i = 0; i < 1024; i++) {
+; Int0[i] = Int1[i];
+; Float0[i] = Float1[i];
+; }
+; }
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @jd(i32* nocapture %Int0, i32* nocapture readonly %Int1, float* nocapture %Float0, float* nocapture readonly %Float1) {
+entry:
+ br label %for.body
+
+for.body: ; preds = %for.body, %entry
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %arrayidx = getelementptr inbounds i32* %Int1, i64 %indvars.iv
+ %tmp = load i32* %arrayidx, align 4, !tbaa !0
+ %arrayidx2 = getelementptr inbounds i32* %Int0, i64 %indvars.iv
+ store i32 %tmp, i32* %arrayidx2, align 4, !tbaa !0
+ %arrayidx4 = getelementptr inbounds float* %Float1, i64 %indvars.iv
+ %tmp1 = load float* %arrayidx4, align 4, !tbaa !4
+ %arrayidx6 = getelementptr inbounds float* %Float0, i64 %indvars.iv
+ store float %tmp1, float* %arrayidx6, align 4, !tbaa !4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond = icmp eq i64 %indvars.iv.next, 1024
+ br i1 %exitcond, label %for.end, label %for.body
+
+for.end: ; preds = %for.body
+ ret void
+}
+
+!0 = metadata !{metadata !1, metadata !1, i64 0}
+!1 = metadata !{metadata !"int", metadata !2, i64 0}
+!2 = metadata !{metadata !"omnipotent char", metadata !3, i64 0}
+!3 = metadata !{metadata !"Simple C/C++ TBAA"}
+!4 = metadata !{metadata !5, metadata !5, i64 0}
+!5 = metadata !{metadata !"float", metadata !2, i64 0}
+
+; NOAA: Alias Groups (1):
+; NOAA-DAG: <{ MemRef_Int0[(0)] }, { MemRef_Int0[(1023)] }>
+; NOAA-DAG: <{ MemRef_Int1[(0)] }, { MemRef_Int1[(1023)] }>
+; NOAA-DAG: <{ MemRef_Float0[(0)] }, { MemRef_Float0[(1023)] }>
+; NOAA-DAG: <{ MemRef_Float1[(0)] }, { MemRef_Float1[(1023)] }>
+
+; TBAA-DAG: Alias Groups (2):
+; TBAA-DAG: <{ MemRef_Int0[(0)] }, { MemRef_Int0[(1023)] }>
+; TBAA-DAG: <{ MemRef_Int1[(0)] }, { MemRef_Int1[(1023)] }>
+; TBAA-DAG: <{ MemRef_Float0[(0)] }, { MemRef_Float0[(1023)] }>
+; TBAA-DAG: <{ MemRef_Float1[(0)] }, { MemRef_Float1[(1023)] }>
--
2.0.4
More information about the llvm-commits
mailing list