[polly] r231308 - Rename the Dependences pass to DependenceInfo [NFC]
Johannes Doerfert
doerfert at cs.uni-saarland.de
Wed Mar 4 14:43:40 PST 2015
Author: jdoerfert
Date: Wed Mar 4 16:43:40 2015
New Revision: 231308
URL: http://llvm.org/viewvc/llvm-project?rev=231308&view=rev
Log:
Rename the Dependences pass to DependenceInfo [NFC]
We rename the Dependences pass to DependenceInfo as a first step to a
caching pass policy. The new DependenceInfo pass will later provide
"Dependences" for a SCoP.
To keep consistency the test folder is renamed too.
Added:
polly/trunk/include/polly/DependenceInfo.h
polly/trunk/lib/Analysis/DependenceInfo.cpp
polly/trunk/test/DependenceInfo/
polly/trunk/test/DependenceInfo/computeout.ll
polly/trunk/test/DependenceInfo/do_pluto_matmult.ll
polly/trunk/test/DependenceInfo/reduction_complex_location.ll
polly/trunk/test/DependenceInfo/reduction_dependences_equal_non_reduction_dependences.ll
polly/trunk/test/DependenceInfo/reduction_mixed_reduction_and_non_reduction_dependences.ll
polly/trunk/test/DependenceInfo/reduction_multiple_loops_array_sum.ll
polly/trunk/test/DependenceInfo/reduction_multiple_loops_array_sum_2.ll
polly/trunk/test/DependenceInfo/reduction_multiple_loops_array_sum_3.ll
polly/trunk/test/DependenceInfo/reduction_multiple_reductions.ll
polly/trunk/test/DependenceInfo/reduction_multiple_reductions_2.ll
polly/trunk/test/DependenceInfo/reduction_only_reduction_like_access.ll
polly/trunk/test/DependenceInfo/reduction_partially_escaping_intermediate_in_other_stmt.ll
polly/trunk/test/DependenceInfo/reduction_privatization_deps.ll
polly/trunk/test/DependenceInfo/reduction_privatization_deps_2.ll
polly/trunk/test/DependenceInfo/reduction_privatization_deps_3.ll
polly/trunk/test/DependenceInfo/reduction_privatization_deps_4.ll
polly/trunk/test/DependenceInfo/reduction_privatization_deps_5.ll
polly/trunk/test/DependenceInfo/reduction_simple_iv.ll
polly/trunk/test/DependenceInfo/reduction_simple_iv_debug_wrapped_dependences.ll
polly/trunk/test/DependenceInfo/reduction_simple_privatization_deps_2.ll
polly/trunk/test/DependenceInfo/reduction_simple_privatization_deps_w_parameter.ll
polly/trunk/test/DependenceInfo/reduction_two_reductions_different_rloops.ll
polly/trunk/test/DependenceInfo/sequential_loops.ll
Removed:
polly/trunk/include/polly/Dependences.h
polly/trunk/lib/Analysis/Dependences.cpp
polly/trunk/test/Dependences/
Modified:
polly/trunk/include/polly/LinkAllPasses.h
polly/trunk/lib/CMakeLists.txt
polly/trunk/lib/CodeGen/IslAst.cpp
polly/trunk/lib/CodeGen/IslCodeGeneration.cpp
polly/trunk/lib/Exchange/JSONExporter.cpp
polly/trunk/lib/Makefile
polly/trunk/lib/Support/RegisterPasses.cpp
polly/trunk/lib/Transform/DeadCodeElimination.cpp
polly/trunk/lib/Transform/Pluto.cpp
polly/trunk/lib/Transform/ScheduleOptimizer.cpp
Added: polly/trunk/include/polly/DependenceInfo.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/DependenceInfo.h?rev=231308&view=auto
==============================================================================
--- polly/trunk/include/polly/DependenceInfo.h (added)
+++ polly/trunk/include/polly/DependenceInfo.h Wed Mar 4 16:43:40 2015
@@ -0,0 +1,171 @@
+//===--- polly/DependenceInfo.h - Polyhedral dependency analysis *- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Calculate the data dependency relations for a Scop using ISL.
+//
+// The integer set library (ISL) from Sven, has a integrated dependency analysis
+// to calculate data dependences. This pass takes advantage of this and
+// calculate those dependences a Scop.
+//
+// The dependences in this pass are exact in terms that for a specific read
+// statement instance only the last write statement instance is returned. In
+// case of may writes a set of possible write instances is returned. This
+// analysis will never produce redundant dependences.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_DEPENDENCES_H
+#define POLLY_DEPENDENCES_H
+
+#include "polly/ScopPass.h"
+
+#include <map>
+#include "isl/ctx.h"
+
+struct isl_pw_aff;
+struct isl_union_map;
+struct isl_union_set;
+struct isl_map;
+struct isl_set;
+struct clast_for;
+
+using namespace llvm;
+
+namespace polly {
+
+class Scop;
+class ScopStmt;
+class MemoryAccess;
+
+class DependenceInfo : public ScopPass {
+public:
+ static char ID;
+
+ /// @brief The type of the dependences.
+ ///
+ /// Reduction dependences are separated from RAW/WAW/WAR dependences because
+ /// we can ignore them during the scheduling. This is the case since the order
+ /// in which the reduction statements are executed does not matter. However,
+ /// if they are executed in parallel we need to take additional measures
+ /// (e.g, privatization) to ensure a correct result. The (reverse) transitive
+ /// closure of the reduction dependences are used to check for parallel
+ /// executed reduction statements during code generation. These dependences
+ /// connect all instances of a reduction with each other, they are therefor
+ /// cyclic and possibly "reversed".
+ enum Type {
+ // Write after read
+ TYPE_WAR = 1 << 0,
+
+ // Read after write
+ TYPE_RAW = 1 << 1,
+
+ // Write after write
+ TYPE_WAW = 1 << 2,
+
+ // Reduction dependences
+ TYPE_RED = 1 << 3,
+
+ // Transitive closure of the reduction dependences (& the reverse)
+ TYPE_TC_RED = 1 << 4,
+ };
+
+ typedef std::map<ScopStmt *, isl_map *> StatementToIslMapTy;
+
+ DependenceInfo();
+
+ /// @brief Check if a new scattering is valid.
+ ///
+ /// @param NewScattering The new scatterings
+ ///
+ /// @return bool True if the new scattering is valid, false it it reverses
+ /// dependences.
+ bool isValidScattering(StatementToIslMapTy *NewScatterings);
+
+ /// @brief Check if a partial schedule is parallel wrt to @p Deps.
+ ///
+ /// @param Schedule The subset of the scattering space that we want to
+ /// check.
+ /// @param Deps The dependences @p Schedule needs to respect.
+ /// @param MinDistancePtr If not nullptr, the minimal dependence distance will
+ /// be returned at the address of that pointer
+ ///
+ /// @return Returns true, if executing parallel the outermost dimension of
+ /// @p Schedule is valid according to the dependences @p Deps.
+ bool isParallel(__isl_keep isl_union_map *Schedule,
+ __isl_take isl_union_map *Deps,
+ __isl_give isl_pw_aff **MinDistancePtr = nullptr);
+
+ /// @brief Get the dependences in this Scop.
+ ///
+ /// @param Kinds This integer defines the different kinds of dependences
+ /// that will be returned. To return more than one kind, the
+ /// different kinds are 'ored' together.
+ isl_union_map *getDependences(int Kinds);
+
+ /// @brief Report if valid dependences are available.
+ bool hasValidDependences();
+
+ /// @brief Return the reduction dependences caused by @p MA.
+ ///
+ /// @return The reduction dependences caused by @p MA or nullptr if None.
+ __isl_give isl_map *getReductionDependences(MemoryAccess *MA);
+
+ /// @brief Return the reduction dependences mapped by the causing @p MA.
+ const DenseMap<MemoryAccess *, isl_map *> &getReductionDependences() const {
+ return ReductionDependences;
+ }
+
+ /// @brief Recompute dependences from schedule and memory accesses.
+ void recomputeDependences();
+
+ bool runOnScop(Scop &S) override;
+ void printScop(raw_ostream &OS, Scop &S) const override;
+ void releaseMemory() override;
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+
+private:
+ Scop *S;
+
+ /// @brief The different kinds of dependences we calculate.
+ isl_union_map *RAW;
+ isl_union_map *WAR;
+ isl_union_map *WAW;
+
+ /// @brief The map of reduction dependences
+ isl_union_map *RED = nullptr;
+
+ /// @brief The (reverse) transitive closure of reduction dependences
+ isl_union_map *TC_RED = nullptr;
+
+ /// @brief Map from memory accesses to their reduction dependences.
+ DenseMap<MemoryAccess *, isl_map *> ReductionDependences;
+
+ /// @brief Collect information about the SCoP.
+ void collectInfo(Scop &S, isl_union_map **Read, isl_union_map **Write,
+ isl_union_map **MayWrite, isl_union_map **AccessSchedule,
+ isl_union_map **StmtSchedule);
+
+ /// @brief Calculate and add at the privatization dependences
+ void addPrivatizationDependences();
+
+ /// @brief Calculate the dependences for a certain SCoP.
+ void calculateDependences(Scop &S);
+
+ /// @brief Set the reduction dependences for @p MA to @p Deps.
+ void setReductionDependences(MemoryAccess *MA, __isl_take isl_map *Deps);
+};
+
+} // End polly namespace.
+
+namespace llvm {
+class PassRegistry;
+void initializeDependenceInfoPass(llvm::PassRegistry &);
+}
+
+#endif
Removed: polly/trunk/include/polly/Dependences.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/Dependences.h?rev=231307&view=auto
==============================================================================
--- polly/trunk/include/polly/Dependences.h (original)
+++ polly/trunk/include/polly/Dependences.h (removed)
@@ -1,171 +0,0 @@
-//===------ polly/Dependences.h - Polyhedral dependency analysis *- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Calculate the data dependency relations for a Scop using ISL.
-//
-// The integer set library (ISL) from Sven, has a integrated dependency analysis
-// to calculate data dependences. This pass takes advantage of this and
-// calculate those dependences a Scop.
-//
-// The dependences in this pass are exact in terms that for a specific read
-// statement instance only the last write statement instance is returned. In
-// case of may writes a set of possible write instances is returned. This
-// analysis will never produce redundant dependences.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef POLLY_DEPENDENCES_H
-#define POLLY_DEPENDENCES_H
-
-#include "polly/ScopPass.h"
-
-#include <map>
-#include "isl/ctx.h"
-
-struct isl_pw_aff;
-struct isl_union_map;
-struct isl_union_set;
-struct isl_map;
-struct isl_set;
-struct clast_for;
-
-using namespace llvm;
-
-namespace polly {
-
-class Scop;
-class ScopStmt;
-class MemoryAccess;
-
-class Dependences : public ScopPass {
-public:
- static char ID;
-
- /// @brief The type of the dependences.
- ///
- /// Reduction dependences are separated from RAW/WAW/WAR dependences because
- /// we can ignore them during the scheduling. This is the case since the order
- /// in which the reduction statements are executed does not matter. However,
- /// if they are executed in parallel we need to take additional measures
- /// (e.g, privatization) to ensure a correct result. The (reverse) transitive
- /// closure of the reduction dependences are used to check for parallel
- /// executed reduction statements during code generation. These dependences
- /// connect all instances of a reduction with each other, they are therefor
- /// cyclic and possibly "reversed".
- enum Type {
- // Write after read
- TYPE_WAR = 1 << 0,
-
- // Read after write
- TYPE_RAW = 1 << 1,
-
- // Write after write
- TYPE_WAW = 1 << 2,
-
- // Reduction dependences
- TYPE_RED = 1 << 3,
-
- // Transitive closure of the reduction dependences (& the reverse)
- TYPE_TC_RED = 1 << 4,
- };
-
- typedef std::map<ScopStmt *, isl_map *> StatementToIslMapTy;
-
- Dependences();
-
- /// @brief Check if a new scattering is valid.
- ///
- /// @param NewScattering The new scatterings
- ///
- /// @return bool True if the new scattering is valid, false it it reverses
- /// dependences.
- bool isValidScattering(StatementToIslMapTy *NewScatterings);
-
- /// @brief Check if a partial schedule is parallel wrt to @p Deps.
- ///
- /// @param Schedule The subset of the scattering space that we want to
- /// check.
- /// @param Deps The dependences @p Schedule needs to respect.
- /// @param MinDistancePtr If not nullptr, the minimal dependence distance will
- /// be returned at the address of that pointer
- ///
- /// @return Returns true, if executing parallel the outermost dimension of
- /// @p Schedule is valid according to the dependences @p Deps.
- bool isParallel(__isl_keep isl_union_map *Schedule,
- __isl_take isl_union_map *Deps,
- __isl_give isl_pw_aff **MinDistancePtr = nullptr);
-
- /// @brief Get the dependences in this Scop.
- ///
- /// @param Kinds This integer defines the different kinds of dependences
- /// that will be returned. To return more than one kind, the
- /// different kinds are 'ored' together.
- isl_union_map *getDependences(int Kinds);
-
- /// @brief Report if valid dependences are available.
- bool hasValidDependences();
-
- /// @brief Return the reduction dependences caused by @p MA.
- ///
- /// @return The reduction dependences caused by @p MA or nullptr if None.
- __isl_give isl_map *getReductionDependences(MemoryAccess *MA);
-
- /// @brief Return the reduction dependences mapped by the causing @p MA.
- const DenseMap<MemoryAccess *, isl_map *> &getReductionDependences() const {
- return ReductionDependences;
- }
-
- /// @brief Recompute dependences from schedule and memory accesses.
- void recomputeDependences();
-
- bool runOnScop(Scop &S) override;
- void printScop(raw_ostream &OS, Scop &S) const override;
- void releaseMemory() override;
- void getAnalysisUsage(AnalysisUsage &AU) const override;
-
-private:
- Scop *S;
-
- /// @brief The different kinds of dependences we calculate.
- isl_union_map *RAW;
- isl_union_map *WAR;
- isl_union_map *WAW;
-
- /// @brief The map of reduction dependences
- isl_union_map *RED = nullptr;
-
- /// @brief The (reverse) transitive closure of reduction dependences
- isl_union_map *TC_RED = nullptr;
-
- /// @brief Map from memory accesses to their reduction dependences.
- DenseMap<MemoryAccess *, isl_map *> ReductionDependences;
-
- /// @brief Collect information about the SCoP.
- void collectInfo(Scop &S, isl_union_map **Read, isl_union_map **Write,
- isl_union_map **MayWrite, isl_union_map **AccessSchedule,
- isl_union_map **StmtSchedule);
-
- /// @brief Calculate and add at the privatization dependences
- void addPrivatizationDependences();
-
- /// @brief Calculate the dependences for a certain SCoP.
- void calculateDependences(Scop &S);
-
- /// @brief Set the reduction dependences for @p MA to @p Deps.
- void setReductionDependences(MemoryAccess *MA, __isl_take isl_map *Deps);
-};
-
-} // End polly namespace.
-
-namespace llvm {
-class PassRegistry;
-void initializeDependencesPass(llvm::PassRegistry &);
-}
-
-#endif
Modified: polly/trunk/include/polly/LinkAllPasses.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/LinkAllPasses.h?rev=231308&r1=231307&r2=231308&view=diff
==============================================================================
--- polly/trunk/include/polly/LinkAllPasses.h (original)
+++ polly/trunk/include/polly/LinkAllPasses.h Wed Mar 4 16:43:40 2015
@@ -28,7 +28,7 @@ class RegionPass;
namespace polly {
llvm::Pass *createCodePreparationPass();
llvm::Pass *createDeadCodeElimPass();
-llvm::Pass *createDependencesPass();
+llvm::Pass *createDependenceInfoPass();
llvm::Pass *createDOTOnlyPrinterPass();
llvm::Pass *createDOTOnlyViewerPass();
llvm::Pass *createDOTPrinterPass();
@@ -63,7 +63,7 @@ struct PollyForcePassLinking {
polly::createCodePreparationPass();
polly::createDeadCodeElimPass();
- polly::createDependencesPass();
+ polly::createDependenceInfoPass();
polly::createDOTOnlyPrinterPass();
polly::createDOTOnlyViewerPass();
polly::createDOTPrinterPass();
Added: polly/trunk/lib/Analysis/DependenceInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/DependenceInfo.cpp?rev=231308&view=auto
==============================================================================
--- polly/trunk/lib/Analysis/DependenceInfo.cpp (added)
+++ polly/trunk/lib/Analysis/DependenceInfo.cpp Wed Mar 4 16:43:40 2015
@@ -0,0 +1,638 @@
+//===- Dependences.cpp - Calculate dependency information for a Scop. -----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Calculate the data dependency relations for a Scop using ISL.
+//
+// The integer set library (ISL) from Sven, has a integrated dependency analysis
+// to calculate data dependences. This pass takes advantage of this and
+// calculate those dependences a Scop.
+//
+// The dependences in this pass are exact in terms that for a specific read
+// statement instance only the last write statement instance is returned. In
+// case of may writes a set of possible write instances is returned. This
+// analysis will never produce redundant dependences.
+//
+//===----------------------------------------------------------------------===//
+//
+#include "polly/DependenceInfo.h"
+#include "polly/LinkAllPasses.h"
+#include "polly/Options.h"
+#include "polly/ScopInfo.h"
+#include "polly/Support/GICHelper.h"
+#include "llvm/Support/Debug.h"
+
+#include <isl/aff.h>
+#include <isl/ctx.h>
+#include <isl/flow.h>
+#include <isl/map.h>
+#include <isl/options.h>
+#include <isl/set.h>
+
+using namespace polly;
+using namespace llvm;
+
+#define DEBUG_TYPE "polly-dependence"
+
+static cl::opt<int> OptComputeOut(
+ "polly-dependences-computeout",
+ cl::desc("Bound the dependence analysis by a maximal amount of "
+ "computational steps"),
+ cl::Hidden, cl::init(250000), cl::ZeroOrMore, cl::cat(PollyCategory));
+
+static cl::opt<bool> LegalityCheckDisabled(
+ "disable-polly-legality", cl::desc("Disable polly legality check"),
+ cl::Hidden, cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
+
+enum AnalysisType { VALUE_BASED_ANALYSIS, MEMORY_BASED_ANALYSIS };
+
+static cl::opt<enum AnalysisType> OptAnalysisType(
+ "polly-dependences-analysis-type",
+ cl::desc("The kind of dependence analysis to use"),
+ cl::values(clEnumValN(VALUE_BASED_ANALYSIS, "value-based",
+ "Exact dependences without transitive dependences"),
+ clEnumValN(MEMORY_BASED_ANALYSIS, "memory-based",
+ "Overapproximation of dependences"),
+ clEnumValEnd),
+ cl::Hidden, cl::init(VALUE_BASED_ANALYSIS), cl::ZeroOrMore,
+ cl::cat(PollyCategory));
+
+//===----------------------------------------------------------------------===//
+DependenceInfo::DependenceInfo() : ScopPass(ID) { RAW = WAR = WAW = nullptr; }
+
+void DependenceInfo::collectInfo(Scop &S, isl_union_map **Read,
+ isl_union_map **Write,
+ isl_union_map **MayWrite,
+ isl_union_map **AccessSchedule,
+ isl_union_map **StmtSchedule) {
+ isl_space *Space = S.getParamSpace();
+ *Read = isl_union_map_empty(isl_space_copy(Space));
+ *Write = isl_union_map_empty(isl_space_copy(Space));
+ *MayWrite = isl_union_map_empty(isl_space_copy(Space));
+ *AccessSchedule = isl_union_map_empty(isl_space_copy(Space));
+ *StmtSchedule = isl_union_map_empty(Space);
+
+ SmallPtrSet<const Value *, 8> ReductionBaseValues;
+ for (ScopStmt *Stmt : S)
+ for (MemoryAccess *MA : *Stmt)
+ if (MA->isReductionLike())
+ ReductionBaseValues.insert(MA->getBaseAddr());
+
+ for (ScopStmt *Stmt : S) {
+ for (MemoryAccess *MA : *Stmt) {
+ isl_set *domcp = Stmt->getDomain();
+ isl_map *accdom = MA->getAccessRelation();
+
+ accdom = isl_map_intersect_domain(accdom, domcp);
+
+ if (ReductionBaseValues.count(MA->getBaseAddr())) {
+ // Wrap the access domain and adjust the scattering accordingly.
+ //
+ // An access domain like
+ // Stmt[i0, i1] -> MemAcc_A[i0 + i1]
+ // will be transformed into
+ // [Stmt[i0, i1] -> MemAcc_A[i0 + i1]] -> MemAcc_A[i0 + i1]
+ //
+ // The original scattering looks like
+ // Stmt[i0, i1] -> [0, i0, 2, i1, 0]
+ // but as we transformed the access domain we need the scattering
+ // to match the new access domains, thus we need
+ // [Stmt[i0, i1] -> MemAcc_A[i0 + i1]] -> [0, i0, 2, i1, 0]
+ isl_map *Scatter = Stmt->getScattering();
+ Scatter = isl_map_apply_domain(
+ Scatter, isl_map_reverse(isl_map_domain_map(isl_map_copy(accdom))));
+ accdom = isl_map_range_map(accdom);
+ *AccessSchedule = isl_union_map_add_map(*AccessSchedule, Scatter);
+ }
+
+ if (MA->isRead())
+ *Read = isl_union_map_add_map(*Read, accdom);
+ else
+ *Write = isl_union_map_add_map(*Write, accdom);
+ }
+ *StmtSchedule = isl_union_map_add_map(*StmtSchedule, Stmt->getScattering());
+ }
+
+ *StmtSchedule =
+ isl_union_map_intersect_params(*StmtSchedule, S.getAssumedContext());
+}
+
+/// @brief Fix all dimension of @p Zero to 0 and add it to @p user
+static int fixSetToZero(__isl_take isl_set *Zero, void *user) {
+ isl_union_set **User = (isl_union_set **)user;
+ for (unsigned i = 0; i < isl_set_dim(Zero, isl_dim_set); i++)
+ Zero = isl_set_fix_si(Zero, isl_dim_set, i, 0);
+ *User = isl_union_set_add_set(*User, Zero);
+ return 0;
+}
+
+/// @brief Compute the privatization dependences for a given dependency @p Map
+///
+/// Privatization dependences are widened original dependences which originate
+/// or end in a reduction access. To compute them we apply the transitive close
+/// of the reduction dependences (which maps each iteration of a reduction
+/// statement to all following ones) on the RAW/WAR/WAW dependences. The
+/// dependences which start or end at a reduction statement will be extended to
+/// depend on all following reduction statement iterations as well.
+/// Note: "Following" here means according to the reduction dependences.
+///
+/// For the input:
+///
+/// S0: *sum = 0;
+/// for (int i = 0; i < 1024; i++)
+/// S1: *sum += i;
+/// S2: *sum = *sum * 3;
+///
+/// we have the following dependences before we add privatization dependences:
+///
+/// RAW:
+/// { S0[] -> S1[0]; S1[1023] -> S2[] }
+/// WAR:
+/// { }
+/// WAW:
+/// { S0[] -> S1[0]; S1[1024] -> S2[] }
+/// RED:
+/// { S1[i0] -> S1[1 + i0] : i0 >= 0 and i0 <= 1022 }
+///
+/// and afterwards:
+///
+/// RAW:
+/// { S0[] -> S1[i0] : i0 >= 0 and i0 <= 1023;
+/// S1[i0] -> S2[] : i0 >= 0 and i0 <= 1023}
+/// WAR:
+/// { }
+/// WAW:
+/// { S0[] -> S1[i0] : i0 >= 0 and i0 <= 1023;
+/// S1[i0] -> S2[] : i0 >= 0 and i0 <= 1023}
+/// RED:
+/// { S1[i0] -> S1[1 + i0] : i0 >= 0 and i0 <= 1022 }
+///
+/// Note: This function also computes the (reverse) transitive closure of the
+/// reduction dependences.
+void DependenceInfo::addPrivatizationDependences() {
+ isl_union_map *PrivRAW, *PrivWAW, *PrivWAR;
+
+ // The transitive closure might be over approximated, thus could lead to
+ // dependency cycles in the privatization dependences. To make sure this
+ // will not happen we remove all negative dependences after we computed
+ // the transitive closure.
+ TC_RED = isl_union_map_transitive_closure(isl_union_map_copy(RED), 0);
+
+ // FIXME: Apply the current schedule instead of assuming the identity schedule
+ // here. The current approach is only valid as long as we compute the
+ // dependences only with the initial (identity schedule). Any other
+ // schedule could change "the direction of the backward dependences" we
+ // want to eliminate here.
+ isl_union_set *UDeltas = isl_union_map_deltas(isl_union_map_copy(TC_RED));
+ isl_union_set *Universe = isl_union_set_universe(isl_union_set_copy(UDeltas));
+ isl_union_set *Zero = isl_union_set_empty(isl_union_set_get_space(Universe));
+ isl_union_set_foreach_set(Universe, fixSetToZero, &Zero);
+ isl_union_map *NonPositive = isl_union_set_lex_le_union_set(UDeltas, Zero);
+
+ TC_RED = isl_union_map_subtract(TC_RED, NonPositive);
+
+ TC_RED = isl_union_map_union(
+ TC_RED, isl_union_map_reverse(isl_union_map_copy(TC_RED)));
+ TC_RED = isl_union_map_coalesce(TC_RED);
+
+ isl_union_map **Maps[] = {&RAW, &WAW, &WAR};
+ isl_union_map **PrivMaps[] = {&PrivRAW, &PrivWAW, &PrivWAR};
+ for (unsigned u = 0; u < 3; u++) {
+ isl_union_map **Map = Maps[u], **PrivMap = PrivMaps[u];
+
+ *PrivMap = isl_union_map_apply_range(isl_union_map_copy(*Map),
+ isl_union_map_copy(TC_RED));
+ *PrivMap = isl_union_map_union(
+ *PrivMap, isl_union_map_apply_range(isl_union_map_copy(TC_RED),
+ isl_union_map_copy(*Map)));
+
+ *Map = isl_union_map_union(*Map, *PrivMap);
+ }
+
+ isl_union_set_free(Universe);
+}
+
+void DependenceInfo::calculateDependences(Scop &S) {
+ isl_union_map *Read, *Write, *MayWrite, *AccessSchedule, *StmtSchedule,
+ *Schedule;
+
+ DEBUG(dbgs() << "Scop: \n" << S << "\n");
+
+ collectInfo(S, &Read, &Write, &MayWrite, &AccessSchedule, &StmtSchedule);
+
+ Schedule =
+ isl_union_map_union(AccessSchedule, isl_union_map_copy(StmtSchedule));
+
+ Read = isl_union_map_coalesce(Read);
+ Write = isl_union_map_coalesce(Write);
+ MayWrite = isl_union_map_coalesce(MayWrite);
+
+ long MaxOpsOld = isl_ctx_get_max_operations(S.getIslCtx());
+ isl_ctx_set_max_operations(S.getIslCtx(), OptComputeOut);
+ isl_options_set_on_error(S.getIslCtx(), ISL_ON_ERROR_CONTINUE);
+
+ DEBUG(dbgs() << "Read: " << Read << "\n";
+ dbgs() << "Write: " << Write << "\n";
+ dbgs() << "MayWrite: " << MayWrite << "\n";
+ dbgs() << "Schedule: " << Schedule << "\n");
+
+ // The pointers below will be set by the subsequent calls to
+ // isl_union_map_compute_flow.
+ RAW = WAW = WAR = RED = nullptr;
+
+ if (OptAnalysisType == VALUE_BASED_ANALYSIS) {
+ isl_union_map_compute_flow(
+ isl_union_map_copy(Read), isl_union_map_copy(Write),
+ isl_union_map_copy(MayWrite), isl_union_map_copy(Schedule), &RAW,
+ nullptr, nullptr, nullptr);
+
+ isl_union_map_compute_flow(
+ isl_union_map_copy(Write), isl_union_map_copy(Write),
+ isl_union_map_copy(Read), isl_union_map_copy(Schedule), &WAW, &WAR,
+ nullptr, nullptr);
+ } else {
+ isl_union_map *Empty;
+
+ Empty = isl_union_map_empty(isl_union_map_get_space(Write));
+ Write = isl_union_map_union(Write, isl_union_map_copy(MayWrite));
+
+ isl_union_map_compute_flow(
+ isl_union_map_copy(Read), isl_union_map_copy(Empty),
+ isl_union_map_copy(Write), isl_union_map_copy(Schedule), nullptr, &RAW,
+ nullptr, nullptr);
+
+ isl_union_map_compute_flow(
+ isl_union_map_copy(Write), isl_union_map_copy(Empty),
+ isl_union_map_copy(Read), isl_union_map_copy(Schedule), nullptr, &WAR,
+ nullptr, nullptr);
+
+ isl_union_map_compute_flow(
+ isl_union_map_copy(Write), isl_union_map_copy(Empty),
+ isl_union_map_copy(Write), isl_union_map_copy(Schedule), nullptr, &WAW,
+ nullptr, nullptr);
+ isl_union_map_free(Empty);
+ }
+
+ isl_union_map_free(MayWrite);
+ isl_union_map_free(Write);
+ isl_union_map_free(Read);
+ isl_union_map_free(Schedule);
+
+ RAW = isl_union_map_coalesce(RAW);
+ WAW = isl_union_map_coalesce(WAW);
+ WAR = isl_union_map_coalesce(WAR);
+
+ if (isl_ctx_last_error(S.getIslCtx()) == isl_error_quota) {
+ isl_union_map_free(RAW);
+ isl_union_map_free(WAW);
+ isl_union_map_free(WAR);
+ RAW = WAW = WAR = nullptr;
+ isl_ctx_reset_error(S.getIslCtx());
+ }
+ isl_options_set_on_error(S.getIslCtx(), ISL_ON_ERROR_ABORT);
+ isl_ctx_reset_operations(S.getIslCtx());
+ isl_ctx_set_max_operations(S.getIslCtx(), MaxOpsOld);
+
+ isl_union_map *STMT_RAW, *STMT_WAW, *STMT_WAR;
+ STMT_RAW = isl_union_map_intersect_domain(
+ isl_union_map_copy(RAW),
+ isl_union_map_domain(isl_union_map_copy(StmtSchedule)));
+ STMT_WAW = isl_union_map_intersect_domain(
+ isl_union_map_copy(WAW),
+ isl_union_map_domain(isl_union_map_copy(StmtSchedule)));
+ STMT_WAR = isl_union_map_intersect_domain(isl_union_map_copy(WAR),
+ isl_union_map_domain(StmtSchedule));
+ DEBUG({
+ dbgs() << "Wrapped Dependences:\n";
+ printScop(dbgs(), S);
+ dbgs() << "\n";
+ });
+
+ // To handle reduction dependences we proceed as follows:
+ // 1) Aggregate all possible reduction dependences, namely all self
+ // dependences on reduction like statements.
+ // 2) Intersect them with the actual RAW & WAW dependences to the get the
+ // actual reduction dependences. This will ensure the load/store memory
+ // addresses were __identical__ in the two iterations of the statement.
+ // 3) Relax the original RAW and WAW dependences by substracting the actual
+ // reduction dependences. Binary reductions (sum += A[i]) cause both, and
+ // the same, RAW and WAW dependences.
+ // 4) Add the privatization dependences which are widened versions of
+ // already present dependences. They model the effect of manual
+ // privatization at the outermost possible place (namely after the last
+ // write and before the first access to a reduction location).
+
+ // Step 1)
+ RED = isl_union_map_empty(isl_union_map_get_space(RAW));
+ for (ScopStmt *Stmt : S) {
+ for (MemoryAccess *MA : *Stmt) {
+ if (!MA->isReductionLike())
+ continue;
+ isl_set *AccDomW = isl_map_wrap(MA->getAccessRelation());
+ isl_map *Identity =
+ isl_map_from_domain_and_range(isl_set_copy(AccDomW), AccDomW);
+ RED = isl_union_map_add_map(RED, Identity);
+ }
+ }
+
+ // Step 2)
+ RED = isl_union_map_intersect(RED, isl_union_map_copy(RAW));
+ RED = isl_union_map_intersect(RED, isl_union_map_copy(WAW));
+
+ if (!isl_union_map_is_empty(RED)) {
+
+ // Step 3)
+ RAW = isl_union_map_subtract(RAW, isl_union_map_copy(RED));
+ WAW = isl_union_map_subtract(WAW, isl_union_map_copy(RED));
+
+ // Step 4)
+ addPrivatizationDependences();
+ }
+
+ DEBUG({
+ dbgs() << "Final Wrapped Dependences:\n";
+ printScop(dbgs(), S);
+ dbgs() << "\n";
+ });
+
+ // RED_SIN is used to collect all reduction dependences again after we
+ // split them according to the causing memory accesses. The current assumption
+ // is that our method of splitting will not have any leftovers. In the end
+ // we validate this assumption until we have more confidence in this method.
+ isl_union_map *RED_SIN = isl_union_map_empty(isl_union_map_get_space(RAW));
+
+ // For each reduction like memory access, check if there are reduction
+ // dependences with the access relation of the memory access as a domain
+ // (wrapped space!). If so these dependences are caused by this memory access.
+ // We then move this portion of reduction dependences back to the statement ->
+ // statement space and add a mapping from the memory access to these
+ // dependences.
+ for (ScopStmt *Stmt : S) {
+ for (MemoryAccess *MA : *Stmt) {
+ if (!MA->isReductionLike())
+ continue;
+
+ isl_set *AccDomW = isl_map_wrap(MA->getAccessRelation());
+ isl_union_map *AccRedDepU = isl_union_map_intersect_domain(
+ isl_union_map_copy(TC_RED), isl_union_set_from_set(AccDomW));
+ if (isl_union_map_is_empty(AccRedDepU) && !isl_union_map_free(AccRedDepU))
+ continue;
+
+ isl_map *AccRedDep = isl_map_from_union_map(AccRedDepU);
+ RED_SIN = isl_union_map_add_map(RED_SIN, isl_map_copy(AccRedDep));
+ AccRedDep = isl_map_zip(AccRedDep);
+ AccRedDep = isl_set_unwrap(isl_map_domain(AccRedDep));
+ setReductionDependences(MA, AccRedDep);
+ }
+ }
+
+ assert(isl_union_map_is_equal(RED_SIN, TC_RED) &&
+ "Intersecting the reduction dependence domain with the wrapped access "
+ "relation is not enough, we need to loosen the access relation also");
+ isl_union_map_free(RED_SIN);
+
+ RAW = isl_union_map_zip(RAW);
+ WAW = isl_union_map_zip(WAW);
+ WAR = isl_union_map_zip(WAR);
+ RED = isl_union_map_zip(RED);
+ TC_RED = isl_union_map_zip(TC_RED);
+
+ DEBUG({
+ dbgs() << "Zipped Dependences:\n";
+ printScop(dbgs(), S);
+ dbgs() << "\n";
+ });
+
+ RAW = isl_union_set_unwrap(isl_union_map_domain(RAW));
+ WAW = isl_union_set_unwrap(isl_union_map_domain(WAW));
+ WAR = isl_union_set_unwrap(isl_union_map_domain(WAR));
+ RED = isl_union_set_unwrap(isl_union_map_domain(RED));
+ TC_RED = isl_union_set_unwrap(isl_union_map_domain(TC_RED));
+
+ DEBUG({
+ dbgs() << "Unwrapped Dependences:\n";
+ printScop(dbgs(), S);
+ dbgs() << "\n";
+ });
+
+ RAW = isl_union_map_union(RAW, STMT_RAW);
+ WAW = isl_union_map_union(WAW, STMT_WAW);
+ WAR = isl_union_map_union(WAR, STMT_WAR);
+
+ RAW = isl_union_map_coalesce(RAW);
+ WAW = isl_union_map_coalesce(WAW);
+ WAR = isl_union_map_coalesce(WAR);
+ RED = isl_union_map_coalesce(RED);
+ TC_RED = isl_union_map_coalesce(TC_RED);
+
+ DEBUG(printScop(dbgs(), S));
+}
+
+void DependenceInfo::recomputeDependences() {
+ releaseMemory();
+ calculateDependences(*S);
+}
+
+bool DependenceInfo::runOnScop(Scop &ScopVar) {
+ S = &ScopVar;
+ recomputeDependences();
+ return false;
+}
+
+bool DependenceInfo::isValidScattering(StatementToIslMapTy *NewScattering) {
+ Scop &S = *this->S;
+
+ if (LegalityCheckDisabled)
+ return true;
+
+ isl_union_map *Dependences = getDependences(TYPE_RAW | TYPE_WAW | TYPE_WAR);
+ isl_space *Space = S.getParamSpace();
+ isl_union_map *Scattering = isl_union_map_empty(Space);
+
+ isl_space *ScatteringSpace = nullptr;
+
+ for (ScopStmt *Stmt : S) {
+ isl_map *StmtScat;
+
+ if (NewScattering->find(Stmt) == NewScattering->end())
+ StmtScat = Stmt->getScattering();
+ else
+ StmtScat = isl_map_copy((*NewScattering)[Stmt]);
+
+ if (!ScatteringSpace)
+ ScatteringSpace = isl_space_range(isl_map_get_space(StmtScat));
+
+ Scattering = isl_union_map_add_map(Scattering, StmtScat);
+ }
+
+ Dependences =
+ isl_union_map_apply_domain(Dependences, isl_union_map_copy(Scattering));
+ Dependences = isl_union_map_apply_range(Dependences, Scattering);
+
+ isl_set *Zero = isl_set_universe(isl_space_copy(ScatteringSpace));
+ for (unsigned i = 0; i < isl_set_dim(Zero, isl_dim_set); i++)
+ Zero = isl_set_fix_si(Zero, isl_dim_set, i, 0);
+
+ isl_union_set *UDeltas = isl_union_map_deltas(Dependences);
+ isl_set *Deltas = isl_union_set_extract_set(UDeltas, ScatteringSpace);
+ isl_union_set_free(UDeltas);
+
+ isl_map *NonPositive = isl_set_lex_le_set(Deltas, Zero);
+ bool IsValid = isl_map_is_empty(NonPositive);
+ isl_map_free(NonPositive);
+
+ return IsValid;
+}
+
+// Check if the current scheduling dimension is parallel.
+//
+// We check for parallelism by verifying that the loop does not carry any
+// dependences.
+//
+// Parallelism test: if the distance is zero in all outer dimensions, then it
+// has to be zero in the current dimension as well.
+//
+// Implementation: first, translate dependences into time space, then force
+// outer dimensions to be equal. If the distance is zero in the current
+// dimension, then the loop is parallel. The distance is zero in the current
+// dimension if it is a subset of a map with equal values for the current
+// dimension.
+bool DependenceInfo::isParallel(isl_union_map *Schedule, isl_union_map *Deps,
+ isl_pw_aff **MinDistancePtr) {
+ isl_set *Deltas, *Distance;
+ isl_map *ScheduleDeps;
+ unsigned Dimension;
+ bool IsParallel;
+
+ Deps = isl_union_map_apply_range(Deps, isl_union_map_copy(Schedule));
+ Deps = isl_union_map_apply_domain(Deps, isl_union_map_copy(Schedule));
+
+ if (isl_union_map_is_empty(Deps)) {
+ isl_union_map_free(Deps);
+ return true;
+ }
+
+ ScheduleDeps = isl_map_from_union_map(Deps);
+ Dimension = isl_map_dim(ScheduleDeps, isl_dim_out) - 1;
+
+ for (unsigned i = 0; i < Dimension; i++)
+ ScheduleDeps = isl_map_equate(ScheduleDeps, isl_dim_out, i, isl_dim_in, i);
+
+ Deltas = isl_map_deltas(ScheduleDeps);
+ Distance = isl_set_universe(isl_set_get_space(Deltas));
+
+ // [0, ..., 0, +] - All zeros and last dimension larger than zero
+ for (unsigned i = 0; i < Dimension; i++)
+ Distance = isl_set_fix_si(Distance, isl_dim_set, i, 0);
+
+ Distance = isl_set_lower_bound_si(Distance, isl_dim_set, Dimension, 1);
+ Distance = isl_set_intersect(Distance, Deltas);
+
+ IsParallel = isl_set_is_empty(Distance);
+ if (IsParallel || !MinDistancePtr) {
+ isl_set_free(Distance);
+ return IsParallel;
+ }
+
+ Distance = isl_set_project_out(Distance, isl_dim_set, 0, Dimension);
+ Distance = isl_set_coalesce(Distance);
+
+ // This last step will compute a expression for the minimal value in the
+ // distance polyhedron Distance with regards to the first (outer most)
+ // dimension.
+ *MinDistancePtr = isl_pw_aff_coalesce(isl_set_dim_min(Distance, 0));
+
+ return false;
+}
+
+static void printDependencyMap(raw_ostream &OS, __isl_keep isl_union_map *DM) {
+ if (DM)
+ OS << DM << "\n";
+ else
+ OS << "n/a\n";
+}
+
+void DependenceInfo::printScop(raw_ostream &OS, Scop &) const {
+ OS << "\tRAW dependences:\n\t\t";
+ printDependencyMap(OS, RAW);
+ OS << "\tWAR dependences:\n\t\t";
+ printDependencyMap(OS, WAR);
+ OS << "\tWAW dependences:\n\t\t";
+ printDependencyMap(OS, WAW);
+ OS << "\tReduction dependences:\n\t\t";
+ printDependencyMap(OS, RED);
+ OS << "\tTransitive closure of reduction dependences:\n\t\t";
+ printDependencyMap(OS, TC_RED);
+}
+
+void DependenceInfo::releaseMemory() {
+ isl_union_map_free(RAW);
+ isl_union_map_free(WAR);
+ isl_union_map_free(WAW);
+ isl_union_map_free(RED);
+ isl_union_map_free(TC_RED);
+
+ RED = RAW = WAR = WAW = TC_RED = nullptr;
+
+ for (auto &ReductionDeps : ReductionDependences)
+ isl_map_free(ReductionDeps.second);
+ ReductionDependences.clear();
+}
+
+isl_union_map *DependenceInfo::getDependences(int Kinds) {
+ assert(hasValidDependences() && "No valid dependences available");
+ isl_space *Space = isl_union_map_get_space(RAW);
+ isl_union_map *Deps = isl_union_map_empty(Space);
+
+ if (Kinds & TYPE_RAW)
+ Deps = isl_union_map_union(Deps, isl_union_map_copy(RAW));
+
+ if (Kinds & TYPE_WAR)
+ Deps = isl_union_map_union(Deps, isl_union_map_copy(WAR));
+
+ if (Kinds & TYPE_WAW)
+ Deps = isl_union_map_union(Deps, isl_union_map_copy(WAW));
+
+ if (Kinds & TYPE_RED)
+ Deps = isl_union_map_union(Deps, isl_union_map_copy(RED));
+
+ if (Kinds & TYPE_TC_RED)
+ Deps = isl_union_map_union(Deps, isl_union_map_copy(TC_RED));
+
+ Deps = isl_union_map_coalesce(Deps);
+ Deps = isl_union_map_detect_equalities(Deps);
+ return Deps;
+}
+
+bool DependenceInfo::hasValidDependences() {
+ return (RAW != nullptr) && (WAR != nullptr) && (WAW != nullptr);
+}
+
+isl_map *DependenceInfo::getReductionDependences(MemoryAccess *MA) {
+ return isl_map_copy(ReductionDependences[MA]);
+}
+
+void DependenceInfo::setReductionDependences(MemoryAccess *MA, isl_map *D) {
+ assert(ReductionDependences.count(MA) == 0 &&
+ "Reduction dependences set twice!");
+ ReductionDependences[MA] = D;
+}
+
+void DependenceInfo::getAnalysisUsage(AnalysisUsage &AU) const {
+ ScopPass::getAnalysisUsage(AU);
+}
+
+char DependenceInfo::ID = 0;
+
+Pass *polly::createDependenceInfoPass() { return new DependenceInfo(); }
+
+INITIALIZE_PASS_BEGIN(DependenceInfo, "polly-dependences",
+ "Polly - Calculate dependences", false, false);
+INITIALIZE_PASS_DEPENDENCY(ScopInfo);
+INITIALIZE_PASS_END(DependenceInfo, "polly-dependences",
+ "Polly - Calculate dependences", false, false)
Removed: polly/trunk/lib/Analysis/Dependences.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/Dependences.cpp?rev=231307&view=auto
==============================================================================
--- polly/trunk/lib/Analysis/Dependences.cpp (original)
+++ polly/trunk/lib/Analysis/Dependences.cpp (removed)
@@ -1,637 +0,0 @@
-//===- Dependences.cpp - Calculate dependency information for a Scop. -----===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Calculate the data dependency relations for a Scop using ISL.
-//
-// The integer set library (ISL) from Sven, has a integrated dependency analysis
-// to calculate data dependences. This pass takes advantage of this and
-// calculate those dependences a Scop.
-//
-// The dependences in this pass are exact in terms that for a specific read
-// statement instance only the last write statement instance is returned. In
-// case of may writes a set of possible write instances is returned. This
-// analysis will never produce redundant dependences.
-//
-//===----------------------------------------------------------------------===//
-//
-#include "polly/Dependences.h"
-#include "polly/LinkAllPasses.h"
-#include "polly/Options.h"
-#include "polly/ScopInfo.h"
-#include "polly/Support/GICHelper.h"
-#include "llvm/Support/Debug.h"
-
-#include <isl/aff.h>
-#include <isl/ctx.h>
-#include <isl/flow.h>
-#include <isl/map.h>
-#include <isl/options.h>
-#include <isl/set.h>
-
-using namespace polly;
-using namespace llvm;
-
-#define DEBUG_TYPE "polly-dependence"
-
-static cl::opt<int> OptComputeOut(
- "polly-dependences-computeout",
- cl::desc("Bound the dependence analysis by a maximal amount of "
- "computational steps"),
- cl::Hidden, cl::init(250000), cl::ZeroOrMore, cl::cat(PollyCategory));
-
-static cl::opt<bool> LegalityCheckDisabled(
- "disable-polly-legality", cl::desc("Disable polly legality check"),
- cl::Hidden, cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory));
-
-enum AnalysisType { VALUE_BASED_ANALYSIS, MEMORY_BASED_ANALYSIS };
-
-static cl::opt<enum AnalysisType> OptAnalysisType(
- "polly-dependences-analysis-type",
- cl::desc("The kind of dependence analysis to use"),
- cl::values(clEnumValN(VALUE_BASED_ANALYSIS, "value-based",
- "Exact dependences without transitive dependences"),
- clEnumValN(MEMORY_BASED_ANALYSIS, "memory-based",
- "Overapproximation of dependences"),
- clEnumValEnd),
- cl::Hidden, cl::init(VALUE_BASED_ANALYSIS), cl::ZeroOrMore,
- cl::cat(PollyCategory));
-
-//===----------------------------------------------------------------------===//
-Dependences::Dependences() : ScopPass(ID) { RAW = WAR = WAW = nullptr; }
-
-void Dependences::collectInfo(Scop &S, isl_union_map **Read,
- isl_union_map **Write, isl_union_map **MayWrite,
- isl_union_map **AccessSchedule,
- isl_union_map **StmtSchedule) {
- isl_space *Space = S.getParamSpace();
- *Read = isl_union_map_empty(isl_space_copy(Space));
- *Write = isl_union_map_empty(isl_space_copy(Space));
- *MayWrite = isl_union_map_empty(isl_space_copy(Space));
- *AccessSchedule = isl_union_map_empty(isl_space_copy(Space));
- *StmtSchedule = isl_union_map_empty(Space);
-
- SmallPtrSet<const Value *, 8> ReductionBaseValues;
- for (ScopStmt *Stmt : S)
- for (MemoryAccess *MA : *Stmt)
- if (MA->isReductionLike())
- ReductionBaseValues.insert(MA->getBaseAddr());
-
- for (ScopStmt *Stmt : S) {
- for (MemoryAccess *MA : *Stmt) {
- isl_set *domcp = Stmt->getDomain();
- isl_map *accdom = MA->getAccessRelation();
-
- accdom = isl_map_intersect_domain(accdom, domcp);
-
- if (ReductionBaseValues.count(MA->getBaseAddr())) {
- // Wrap the access domain and adjust the scattering accordingly.
- //
- // An access domain like
- // Stmt[i0, i1] -> MemAcc_A[i0 + i1]
- // will be transformed into
- // [Stmt[i0, i1] -> MemAcc_A[i0 + i1]] -> MemAcc_A[i0 + i1]
- //
- // The original scattering looks like
- // Stmt[i0, i1] -> [0, i0, 2, i1, 0]
- // but as we transformed the access domain we need the scattering
- // to match the new access domains, thus we need
- // [Stmt[i0, i1] -> MemAcc_A[i0 + i1]] -> [0, i0, 2, i1, 0]
- isl_map *Scatter = Stmt->getScattering();
- Scatter = isl_map_apply_domain(
- Scatter, isl_map_reverse(isl_map_domain_map(isl_map_copy(accdom))));
- accdom = isl_map_range_map(accdom);
- *AccessSchedule = isl_union_map_add_map(*AccessSchedule, Scatter);
- }
-
- if (MA->isRead())
- *Read = isl_union_map_add_map(*Read, accdom);
- else
- *Write = isl_union_map_add_map(*Write, accdom);
- }
- *StmtSchedule = isl_union_map_add_map(*StmtSchedule, Stmt->getScattering());
- }
-
- *StmtSchedule =
- isl_union_map_intersect_params(*StmtSchedule, S.getAssumedContext());
-}
-
-/// @brief Fix all dimension of @p Zero to 0 and add it to @p user
-static int fixSetToZero(__isl_take isl_set *Zero, void *user) {
- isl_union_set **User = (isl_union_set **)user;
- for (unsigned i = 0; i < isl_set_dim(Zero, isl_dim_set); i++)
- Zero = isl_set_fix_si(Zero, isl_dim_set, i, 0);
- *User = isl_union_set_add_set(*User, Zero);
- return 0;
-}
-
-/// @brief Compute the privatization dependences for a given dependency @p Map
-///
-/// Privatization dependences are widened original dependences which originate
-/// or end in a reduction access. To compute them we apply the transitive close
-/// of the reduction dependences (which maps each iteration of a reduction
-/// statement to all following ones) on the RAW/WAR/WAW dependences. The
-/// dependences which start or end at a reduction statement will be extended to
-/// depend on all following reduction statement iterations as well.
-/// Note: "Following" here means according to the reduction dependences.
-///
-/// For the input:
-///
-/// S0: *sum = 0;
-/// for (int i = 0; i < 1024; i++)
-/// S1: *sum += i;
-/// S2: *sum = *sum * 3;
-///
-/// we have the following dependences before we add privatization dependences:
-///
-/// RAW:
-/// { S0[] -> S1[0]; S1[1023] -> S2[] }
-/// WAR:
-/// { }
-/// WAW:
-/// { S0[] -> S1[0]; S1[1024] -> S2[] }
-/// RED:
-/// { S1[i0] -> S1[1 + i0] : i0 >= 0 and i0 <= 1022 }
-///
-/// and afterwards:
-///
-/// RAW:
-/// { S0[] -> S1[i0] : i0 >= 0 and i0 <= 1023;
-/// S1[i0] -> S2[] : i0 >= 0 and i0 <= 1023}
-/// WAR:
-/// { }
-/// WAW:
-/// { S0[] -> S1[i0] : i0 >= 0 and i0 <= 1023;
-/// S1[i0] -> S2[] : i0 >= 0 and i0 <= 1023}
-/// RED:
-/// { S1[i0] -> S1[1 + i0] : i0 >= 0 and i0 <= 1022 }
-///
-/// Note: This function also computes the (reverse) transitive closure of the
-/// reduction dependences.
-void Dependences::addPrivatizationDependences() {
- isl_union_map *PrivRAW, *PrivWAW, *PrivWAR;
-
- // The transitive closure might be over approximated, thus could lead to
- // dependency cycles in the privatization dependences. To make sure this
- // will not happen we remove all negative dependences after we computed
- // the transitive closure.
- TC_RED = isl_union_map_transitive_closure(isl_union_map_copy(RED), 0);
-
- // FIXME: Apply the current schedule instead of assuming the identity schedule
- // here. The current approach is only valid as long as we compute the
- // dependences only with the initial (identity schedule). Any other
- // schedule could change "the direction of the backward dependences" we
- // want to eliminate here.
- isl_union_set *UDeltas = isl_union_map_deltas(isl_union_map_copy(TC_RED));
- isl_union_set *Universe = isl_union_set_universe(isl_union_set_copy(UDeltas));
- isl_union_set *Zero = isl_union_set_empty(isl_union_set_get_space(Universe));
- isl_union_set_foreach_set(Universe, fixSetToZero, &Zero);
- isl_union_map *NonPositive = isl_union_set_lex_le_union_set(UDeltas, Zero);
-
- TC_RED = isl_union_map_subtract(TC_RED, NonPositive);
-
- TC_RED = isl_union_map_union(
- TC_RED, isl_union_map_reverse(isl_union_map_copy(TC_RED)));
- TC_RED = isl_union_map_coalesce(TC_RED);
-
- isl_union_map **Maps[] = {&RAW, &WAW, &WAR};
- isl_union_map **PrivMaps[] = {&PrivRAW, &PrivWAW, &PrivWAR};
- for (unsigned u = 0; u < 3; u++) {
- isl_union_map **Map = Maps[u], **PrivMap = PrivMaps[u];
-
- *PrivMap = isl_union_map_apply_range(isl_union_map_copy(*Map),
- isl_union_map_copy(TC_RED));
- *PrivMap = isl_union_map_union(
- *PrivMap, isl_union_map_apply_range(isl_union_map_copy(TC_RED),
- isl_union_map_copy(*Map)));
-
- *Map = isl_union_map_union(*Map, *PrivMap);
- }
-
- isl_union_set_free(Universe);
-}
-
-void Dependences::calculateDependences(Scop &S) {
- isl_union_map *Read, *Write, *MayWrite, *AccessSchedule, *StmtSchedule,
- *Schedule;
-
- DEBUG(dbgs() << "Scop: \n" << S << "\n");
-
- collectInfo(S, &Read, &Write, &MayWrite, &AccessSchedule, &StmtSchedule);
-
- Schedule =
- isl_union_map_union(AccessSchedule, isl_union_map_copy(StmtSchedule));
-
- Read = isl_union_map_coalesce(Read);
- Write = isl_union_map_coalesce(Write);
- MayWrite = isl_union_map_coalesce(MayWrite);
-
- long MaxOpsOld = isl_ctx_get_max_operations(S.getIslCtx());
- isl_ctx_set_max_operations(S.getIslCtx(), OptComputeOut);
- isl_options_set_on_error(S.getIslCtx(), ISL_ON_ERROR_CONTINUE);
-
- DEBUG(dbgs() << "Read: " << Read << "\n";
- dbgs() << "Write: " << Write << "\n";
- dbgs() << "MayWrite: " << MayWrite << "\n";
- dbgs() << "Schedule: " << Schedule << "\n");
-
- // The pointers below will be set by the subsequent calls to
- // isl_union_map_compute_flow.
- RAW = WAW = WAR = RED = nullptr;
-
- if (OptAnalysisType == VALUE_BASED_ANALYSIS) {
- isl_union_map_compute_flow(
- isl_union_map_copy(Read), isl_union_map_copy(Write),
- isl_union_map_copy(MayWrite), isl_union_map_copy(Schedule), &RAW,
- nullptr, nullptr, nullptr);
-
- isl_union_map_compute_flow(
- isl_union_map_copy(Write), isl_union_map_copy(Write),
- isl_union_map_copy(Read), isl_union_map_copy(Schedule), &WAW, &WAR,
- nullptr, nullptr);
- } else {
- isl_union_map *Empty;
-
- Empty = isl_union_map_empty(isl_union_map_get_space(Write));
- Write = isl_union_map_union(Write, isl_union_map_copy(MayWrite));
-
- isl_union_map_compute_flow(
- isl_union_map_copy(Read), isl_union_map_copy(Empty),
- isl_union_map_copy(Write), isl_union_map_copy(Schedule), nullptr, &RAW,
- nullptr, nullptr);
-
- isl_union_map_compute_flow(
- isl_union_map_copy(Write), isl_union_map_copy(Empty),
- isl_union_map_copy(Read), isl_union_map_copy(Schedule), nullptr, &WAR,
- nullptr, nullptr);
-
- isl_union_map_compute_flow(
- isl_union_map_copy(Write), isl_union_map_copy(Empty),
- isl_union_map_copy(Write), isl_union_map_copy(Schedule), nullptr, &WAW,
- nullptr, nullptr);
- isl_union_map_free(Empty);
- }
-
- isl_union_map_free(MayWrite);
- isl_union_map_free(Write);
- isl_union_map_free(Read);
- isl_union_map_free(Schedule);
-
- RAW = isl_union_map_coalesce(RAW);
- WAW = isl_union_map_coalesce(WAW);
- WAR = isl_union_map_coalesce(WAR);
-
- if (isl_ctx_last_error(S.getIslCtx()) == isl_error_quota) {
- isl_union_map_free(RAW);
- isl_union_map_free(WAW);
- isl_union_map_free(WAR);
- RAW = WAW = WAR = nullptr;
- isl_ctx_reset_error(S.getIslCtx());
- }
- isl_options_set_on_error(S.getIslCtx(), ISL_ON_ERROR_ABORT);
- isl_ctx_reset_operations(S.getIslCtx());
- isl_ctx_set_max_operations(S.getIslCtx(), MaxOpsOld);
-
- isl_union_map *STMT_RAW, *STMT_WAW, *STMT_WAR;
- STMT_RAW = isl_union_map_intersect_domain(
- isl_union_map_copy(RAW),
- isl_union_map_domain(isl_union_map_copy(StmtSchedule)));
- STMT_WAW = isl_union_map_intersect_domain(
- isl_union_map_copy(WAW),
- isl_union_map_domain(isl_union_map_copy(StmtSchedule)));
- STMT_WAR = isl_union_map_intersect_domain(isl_union_map_copy(WAR),
- isl_union_map_domain(StmtSchedule));
- DEBUG({
- dbgs() << "Wrapped Dependences:\n";
- printScop(dbgs(), S);
- dbgs() << "\n";
- });
-
- // To handle reduction dependences we proceed as follows:
- // 1) Aggregate all possible reduction dependences, namely all self
- // dependences on reduction like statements.
- // 2) Intersect them with the actual RAW & WAW dependences to the get the
- // actual reduction dependences. This will ensure the load/store memory
- // addresses were __identical__ in the two iterations of the statement.
- // 3) Relax the original RAW and WAW dependences by substracting the actual
- // reduction dependences. Binary reductions (sum += A[i]) cause both, and
- // the same, RAW and WAW dependences.
- // 4) Add the privatization dependences which are widened versions of
- // already present dependences. They model the effect of manual
- // privatization at the outermost possible place (namely after the last
- // write and before the first access to a reduction location).
-
- // Step 1)
- RED = isl_union_map_empty(isl_union_map_get_space(RAW));
- for (ScopStmt *Stmt : S) {
- for (MemoryAccess *MA : *Stmt) {
- if (!MA->isReductionLike())
- continue;
- isl_set *AccDomW = isl_map_wrap(MA->getAccessRelation());
- isl_map *Identity =
- isl_map_from_domain_and_range(isl_set_copy(AccDomW), AccDomW);
- RED = isl_union_map_add_map(RED, Identity);
- }
- }
-
- // Step 2)
- RED = isl_union_map_intersect(RED, isl_union_map_copy(RAW));
- RED = isl_union_map_intersect(RED, isl_union_map_copy(WAW));
-
- if (!isl_union_map_is_empty(RED)) {
-
- // Step 3)
- RAW = isl_union_map_subtract(RAW, isl_union_map_copy(RED));
- WAW = isl_union_map_subtract(WAW, isl_union_map_copy(RED));
-
- // Step 4)
- addPrivatizationDependences();
- }
-
- DEBUG({
- dbgs() << "Final Wrapped Dependences:\n";
- printScop(dbgs(), S);
- dbgs() << "\n";
- });
-
- // RED_SIN is used to collect all reduction dependences again after we
- // split them according to the causing memory accesses. The current assumption
- // is that our method of splitting will not have any leftovers. In the end
- // we validate this assumption until we have more confidence in this method.
- isl_union_map *RED_SIN = isl_union_map_empty(isl_union_map_get_space(RAW));
-
- // For each reduction like memory access, check if there are reduction
- // dependences with the access relation of the memory access as a domain
- // (wrapped space!). If so these dependences are caused by this memory access.
- // We then move this portion of reduction dependences back to the statement ->
- // statement space and add a mapping from the memory access to these
- // dependences.
- for (ScopStmt *Stmt : S) {
- for (MemoryAccess *MA : *Stmt) {
- if (!MA->isReductionLike())
- continue;
-
- isl_set *AccDomW = isl_map_wrap(MA->getAccessRelation());
- isl_union_map *AccRedDepU = isl_union_map_intersect_domain(
- isl_union_map_copy(TC_RED), isl_union_set_from_set(AccDomW));
- if (isl_union_map_is_empty(AccRedDepU) && !isl_union_map_free(AccRedDepU))
- continue;
-
- isl_map *AccRedDep = isl_map_from_union_map(AccRedDepU);
- RED_SIN = isl_union_map_add_map(RED_SIN, isl_map_copy(AccRedDep));
- AccRedDep = isl_map_zip(AccRedDep);
- AccRedDep = isl_set_unwrap(isl_map_domain(AccRedDep));
- setReductionDependences(MA, AccRedDep);
- }
- }
-
- assert(isl_union_map_is_equal(RED_SIN, TC_RED) &&
- "Intersecting the reduction dependence domain with the wrapped access "
- "relation is not enough, we need to loosen the access relation also");
- isl_union_map_free(RED_SIN);
-
- RAW = isl_union_map_zip(RAW);
- WAW = isl_union_map_zip(WAW);
- WAR = isl_union_map_zip(WAR);
- RED = isl_union_map_zip(RED);
- TC_RED = isl_union_map_zip(TC_RED);
-
- DEBUG({
- dbgs() << "Zipped Dependences:\n";
- printScop(dbgs(), S);
- dbgs() << "\n";
- });
-
- RAW = isl_union_set_unwrap(isl_union_map_domain(RAW));
- WAW = isl_union_set_unwrap(isl_union_map_domain(WAW));
- WAR = isl_union_set_unwrap(isl_union_map_domain(WAR));
- RED = isl_union_set_unwrap(isl_union_map_domain(RED));
- TC_RED = isl_union_set_unwrap(isl_union_map_domain(TC_RED));
-
- DEBUG({
- dbgs() << "Unwrapped Dependences:\n";
- printScop(dbgs(), S);
- dbgs() << "\n";
- });
-
- RAW = isl_union_map_union(RAW, STMT_RAW);
- WAW = isl_union_map_union(WAW, STMT_WAW);
- WAR = isl_union_map_union(WAR, STMT_WAR);
-
- RAW = isl_union_map_coalesce(RAW);
- WAW = isl_union_map_coalesce(WAW);
- WAR = isl_union_map_coalesce(WAR);
- RED = isl_union_map_coalesce(RED);
- TC_RED = isl_union_map_coalesce(TC_RED);
-
- DEBUG(printScop(dbgs(), S));
-}
-
-void Dependences::recomputeDependences() {
- releaseMemory();
- calculateDependences(*S);
-}
-
-bool Dependences::runOnScop(Scop &ScopVar) {
- S = &ScopVar;
- recomputeDependences();
- return false;
-}
-
-bool Dependences::isValidScattering(StatementToIslMapTy *NewScattering) {
- Scop &S = *this->S;
-
- if (LegalityCheckDisabled)
- return true;
-
- isl_union_map *Dependences = getDependences(TYPE_RAW | TYPE_WAW | TYPE_WAR);
- isl_space *Space = S.getParamSpace();
- isl_union_map *Scattering = isl_union_map_empty(Space);
-
- isl_space *ScatteringSpace = nullptr;
-
- for (ScopStmt *Stmt : S) {
- isl_map *StmtScat;
-
- if (NewScattering->find(Stmt) == NewScattering->end())
- StmtScat = Stmt->getScattering();
- else
- StmtScat = isl_map_copy((*NewScattering)[Stmt]);
-
- if (!ScatteringSpace)
- ScatteringSpace = isl_space_range(isl_map_get_space(StmtScat));
-
- Scattering = isl_union_map_add_map(Scattering, StmtScat);
- }
-
- Dependences =
- isl_union_map_apply_domain(Dependences, isl_union_map_copy(Scattering));
- Dependences = isl_union_map_apply_range(Dependences, Scattering);
-
- isl_set *Zero = isl_set_universe(isl_space_copy(ScatteringSpace));
- for (unsigned i = 0; i < isl_set_dim(Zero, isl_dim_set); i++)
- Zero = isl_set_fix_si(Zero, isl_dim_set, i, 0);
-
- isl_union_set *UDeltas = isl_union_map_deltas(Dependences);
- isl_set *Deltas = isl_union_set_extract_set(UDeltas, ScatteringSpace);
- isl_union_set_free(UDeltas);
-
- isl_map *NonPositive = isl_set_lex_le_set(Deltas, Zero);
- bool IsValid = isl_map_is_empty(NonPositive);
- isl_map_free(NonPositive);
-
- return IsValid;
-}
-
-// Check if the current scheduling dimension is parallel.
-//
-// We check for parallelism by verifying that the loop does not carry any
-// dependences.
-//
-// Parallelism test: if the distance is zero in all outer dimensions, then it
-// has to be zero in the current dimension as well.
-//
-// Implementation: first, translate dependences into time space, then force
-// outer dimensions to be equal. If the distance is zero in the current
-// dimension, then the loop is parallel. The distance is zero in the current
-// dimension if it is a subset of a map with equal values for the current
-// dimension.
-bool Dependences::isParallel(isl_union_map *Schedule, isl_union_map *Deps,
- isl_pw_aff **MinDistancePtr) {
- isl_set *Deltas, *Distance;
- isl_map *ScheduleDeps;
- unsigned Dimension;
- bool IsParallel;
-
- Deps = isl_union_map_apply_range(Deps, isl_union_map_copy(Schedule));
- Deps = isl_union_map_apply_domain(Deps, isl_union_map_copy(Schedule));
-
- if (isl_union_map_is_empty(Deps)) {
- isl_union_map_free(Deps);
- return true;
- }
-
- ScheduleDeps = isl_map_from_union_map(Deps);
- Dimension = isl_map_dim(ScheduleDeps, isl_dim_out) - 1;
-
- for (unsigned i = 0; i < Dimension; i++)
- ScheduleDeps = isl_map_equate(ScheduleDeps, isl_dim_out, i, isl_dim_in, i);
-
- Deltas = isl_map_deltas(ScheduleDeps);
- Distance = isl_set_universe(isl_set_get_space(Deltas));
-
- // [0, ..., 0, +] - All zeros and last dimension larger than zero
- for (unsigned i = 0; i < Dimension; i++)
- Distance = isl_set_fix_si(Distance, isl_dim_set, i, 0);
-
- Distance = isl_set_lower_bound_si(Distance, isl_dim_set, Dimension, 1);
- Distance = isl_set_intersect(Distance, Deltas);
-
- IsParallel = isl_set_is_empty(Distance);
- if (IsParallel || !MinDistancePtr) {
- isl_set_free(Distance);
- return IsParallel;
- }
-
- Distance = isl_set_project_out(Distance, isl_dim_set, 0, Dimension);
- Distance = isl_set_coalesce(Distance);
-
- // This last step will compute a expression for the minimal value in the
- // distance polyhedron Distance with regards to the first (outer most)
- // dimension.
- *MinDistancePtr = isl_pw_aff_coalesce(isl_set_dim_min(Distance, 0));
-
- return false;
-}
-
-static void printDependencyMap(raw_ostream &OS, __isl_keep isl_union_map *DM) {
- if (DM)
- OS << DM << "\n";
- else
- OS << "n/a\n";
-}
-
-void Dependences::printScop(raw_ostream &OS, Scop &) const {
- OS << "\tRAW dependences:\n\t\t";
- printDependencyMap(OS, RAW);
- OS << "\tWAR dependences:\n\t\t";
- printDependencyMap(OS, WAR);
- OS << "\tWAW dependences:\n\t\t";
- printDependencyMap(OS, WAW);
- OS << "\tReduction dependences:\n\t\t";
- printDependencyMap(OS, RED);
- OS << "\tTransitive closure of reduction dependences:\n\t\t";
- printDependencyMap(OS, TC_RED);
-}
-
-void Dependences::releaseMemory() {
- isl_union_map_free(RAW);
- isl_union_map_free(WAR);
- isl_union_map_free(WAW);
- isl_union_map_free(RED);
- isl_union_map_free(TC_RED);
-
- RED = RAW = WAR = WAW = TC_RED = nullptr;
-
- for (auto &ReductionDeps : ReductionDependences)
- isl_map_free(ReductionDeps.second);
- ReductionDependences.clear();
-}
-
-isl_union_map *Dependences::getDependences(int Kinds) {
- assert(hasValidDependences() && "No valid dependences available");
- isl_space *Space = isl_union_map_get_space(RAW);
- isl_union_map *Deps = isl_union_map_empty(Space);
-
- if (Kinds & TYPE_RAW)
- Deps = isl_union_map_union(Deps, isl_union_map_copy(RAW));
-
- if (Kinds & TYPE_WAR)
- Deps = isl_union_map_union(Deps, isl_union_map_copy(WAR));
-
- if (Kinds & TYPE_WAW)
- Deps = isl_union_map_union(Deps, isl_union_map_copy(WAW));
-
- if (Kinds & TYPE_RED)
- Deps = isl_union_map_union(Deps, isl_union_map_copy(RED));
-
- if (Kinds & TYPE_TC_RED)
- Deps = isl_union_map_union(Deps, isl_union_map_copy(TC_RED));
-
- Deps = isl_union_map_coalesce(Deps);
- Deps = isl_union_map_detect_equalities(Deps);
- return Deps;
-}
-
-bool Dependences::hasValidDependences() {
- return (RAW != nullptr) && (WAR != nullptr) && (WAW != nullptr);
-}
-
-isl_map *Dependences::getReductionDependences(MemoryAccess *MA) {
- return isl_map_copy(ReductionDependences[MA]);
-}
-
-void Dependences::setReductionDependences(MemoryAccess *MA, isl_map *D) {
- assert(ReductionDependences.count(MA) == 0 &&
- "Reduction dependences set twice!");
- ReductionDependences[MA] = D;
-}
-
-void Dependences::getAnalysisUsage(AnalysisUsage &AU) const {
- ScopPass::getAnalysisUsage(AU);
-}
-
-char Dependences::ID = 0;
-
-Pass *polly::createDependencesPass() { return new Dependences(); }
-
-INITIALIZE_PASS_BEGIN(Dependences, "polly-dependences",
- "Polly - Calculate dependences", false, false);
-INITIALIZE_PASS_DEPENDENCY(ScopInfo);
-INITIALIZE_PASS_END(Dependences, "polly-dependences",
- "Polly - Calculate dependences", false, false)
Modified: polly/trunk/lib/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CMakeLists.txt?rev=231308&r1=231307&r2=231308&view=diff
==============================================================================
--- polly/trunk/lib/CMakeLists.txt (original)
+++ polly/trunk/lib/CMakeLists.txt Wed Mar 4 16:43:40 2015
@@ -104,7 +104,7 @@ set (ISL_FILES
add_polly_library(Polly
- Analysis/Dependences.cpp
+ Analysis/DependenceInfo.cpp
Analysis/ScopDetection.cpp
Analysis/ScopDetectionDiagnostic.cpp
Analysis/ScopInfo.cpp
Modified: polly/trunk/lib/CodeGen/IslAst.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/IslAst.cpp?rev=231308&r1=231307&r2=231308&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/IslAst.cpp (original)
+++ polly/trunk/lib/CodeGen/IslAst.cpp Wed Mar 4 16:43:40 2015
@@ -21,7 +21,7 @@
#include "polly/CodeGen/CodeGeneration.h"
#include "polly/CodeGen/IslAst.h"
-#include "polly/Dependences.h"
+#include "polly/DependenceInfo.h"
#include "polly/LinkAllPasses.h"
#include "polly/Options.h"
#include "polly/ScopInfo.h"
@@ -73,7 +73,7 @@ static cl::opt<bool> NoEarlyExit(
namespace polly {
class IslAst {
public:
- IslAst(Scop *Scop, Dependences &D);
+ IslAst(Scop *Scop, DependenceInfo &D);
~IslAst();
@@ -111,7 +111,7 @@ struct AstBuildUserInfo {
: Deps(nullptr), InParallelFor(false), LastForNodeId(nullptr) {}
/// @brief The dependence information used for the parallelism check.
- Dependences *Deps;
+ DependenceInfo *Deps;
/// @brief Flag to indicate that we are inside a parallel for node.
bool InParallelFor;
@@ -197,20 +197,21 @@ static isl_printer *cbPrintFor(__isl_tak
/// we can perform the parallelism check as we are only interested in a zero
/// (or non-zero) dependence distance on the dimension in question.
static bool astScheduleDimIsParallel(__isl_keep isl_ast_build *Build,
- Dependences *D,
+ DependenceInfo *D,
IslAstUserPayload *NodeInfo) {
if (!D->hasValidDependences())
return false;
isl_union_map *Schedule = isl_ast_build_get_schedule(Build);
- isl_union_map *Deps = D->getDependences(
- Dependences::TYPE_RAW | Dependences::TYPE_WAW | Dependences::TYPE_WAR);
+ isl_union_map *Deps =
+ D->getDependences(DependenceInfo::TYPE_RAW | DependenceInfo::TYPE_WAW |
+ DependenceInfo::TYPE_WAR);
if (!D->isParallel(Schedule, Deps, &NodeInfo->MinimalDependenceDistance) &&
!isl_union_map_free(Schedule))
return false;
- isl_union_map *RedDeps = D->getDependences(Dependences::TYPE_TC_RED);
+ isl_union_map *RedDeps = D->getDependences(DependenceInfo::TYPE_TC_RED);
if (!D->isParallel(Schedule, RedDeps))
NodeInfo->IsReductionParallel = true;
@@ -362,7 +363,7 @@ static bool benefitsFromPolly(Scop *Scop
return true;
}
-IslAst::IslAst(Scop *Scop, Dependences &D)
+IslAst::IslAst(Scop *Scop, DependenceInfo &D)
: S(Scop), Root(nullptr), RunCondition(nullptr) {
bool PerformParallelTest = PollyParallel || DetectParallel ||
@@ -427,7 +428,7 @@ bool IslAstInfo::runOnScop(Scop &Scop) {
S = &Scop;
- Dependences &D = getAnalysis<Dependences>();
+ DependenceInfo &D = getAnalysis<DependenceInfo>();
Ast = new IslAst(&Scop, D);
@@ -567,7 +568,7 @@ void IslAstInfo::getAnalysisUsage(Analys
// Get the Common analysis usage of ScopPasses.
ScopPass::getAnalysisUsage(AU);
AU.addRequired<ScopInfo>();
- AU.addRequired<Dependences>();
+ AU.addRequired<DependenceInfo>();
}
char IslAstInfo::ID = 0;
@@ -578,6 +579,6 @@ INITIALIZE_PASS_BEGIN(IslAstInfo, "polly
"Polly - Generate an AST of the SCoP (isl)", false,
false);
INITIALIZE_PASS_DEPENDENCY(ScopInfo);
-INITIALIZE_PASS_DEPENDENCY(Dependences);
+INITIALIZE_PASS_DEPENDENCY(DependenceInfo);
INITIALIZE_PASS_END(IslAstInfo, "polly-ast",
"Polly - Generate an AST from the SCoP (isl)", false, false)
Modified: polly/trunk/lib/CodeGen/IslCodeGeneration.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/IslCodeGeneration.cpp?rev=231308&r1=231307&r2=231308&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/IslCodeGeneration.cpp (original)
+++ polly/trunk/lib/CodeGen/IslCodeGeneration.cpp Wed Mar 4 16:43:40 2015
@@ -25,7 +25,7 @@
#include "polly/CodeGen/IslAst.h"
#include "polly/CodeGen/LoopGenerators.h"
#include "polly/CodeGen/Utils.h"
-#include "polly/Dependences.h"
+#include "polly/DependenceInfo.h"
#include "polly/LinkAllPasses.h"
#include "polly/ScopInfo.h"
#include "polly/Support/GICHelper.h"
@@ -1002,7 +1002,7 @@ public:
AU.addRequired<ScopInfo>();
AU.addRequired<LoopInfoWrapperPass>();
- AU.addPreserved<Dependences>();
+ AU.addPreserved<DependenceInfo>();
AU.addPreserved<LoopInfoWrapperPass>();
AU.addPreserved<DominatorTreeWrapperPass>();
@@ -1026,7 +1026,7 @@ Pass *polly::createIslCodeGenerationPass
INITIALIZE_PASS_BEGIN(IslCodeGeneration, "polly-codegen-isl",
"Polly - Create LLVM-IR from SCoPs", false, false);
-INITIALIZE_PASS_DEPENDENCY(Dependences);
+INITIALIZE_PASS_DEPENDENCY(DependenceInfo);
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass);
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass);
INITIALIZE_PASS_DEPENDENCY(RegionInfoPass);
Modified: polly/trunk/lib/Exchange/JSONExporter.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Exchange/JSONExporter.cpp?rev=231308&r1=231307&r2=231308&view=diff
==============================================================================
--- polly/trunk/lib/Exchange/JSONExporter.cpp (original)
+++ polly/trunk/lib/Exchange/JSONExporter.cpp Wed Mar 4 16:43:40 2015
@@ -12,7 +12,7 @@
//===----------------------------------------------------------------------===//
#include "polly/LinkAllPasses.h"
-#include "polly/Dependences.h"
+#include "polly/DependenceInfo.h"
#include "polly/Options.h"
#include "polly/ScopInfo.h"
#include "polly/ScopPass.h"
@@ -178,11 +178,11 @@ void JSONImporter::printScop(raw_ostream
OS << "New access function '" << *I << "'detected in JSCOP file\n";
}
-typedef Dependences::StatementToIslMapTy StatementToIslMapTy;
+typedef DependenceInfo::StatementToIslMapTy StatementToIslMapTy;
bool JSONImporter::runOnScop(Scop &S) {
Region &R = S.getRegion();
- Dependences *D = &getAnalysis<Dependences>();
+ DependenceInfo *D = &getAnalysis<DependenceInfo>();
const DataLayout &DL = getAnalysis<DataLayoutPass>().getDataLayout();
std::string FileName = ImportDir + "/" + getFileName(S);
@@ -355,7 +355,7 @@ bool JSONImporter::runOnScop(Scop &S) {
void JSONImporter::getAnalysisUsage(AnalysisUsage &AU) const {
ScopPass::getAnalysisUsage(AU);
- AU.addRequired<Dependences>();
+ AU.addRequired<DependenceInfo>();
AU.addRequired<DataLayoutPass>();
}
Pass *polly::createJSONImporterPass() { return new JSONImporter(); }
@@ -364,7 +364,7 @@ INITIALIZE_PASS_BEGIN(JSONExporter, "pol
"Polly - Export Scops as JSON"
" (Writes a .jscop file for each Scop)",
false, false);
-INITIALIZE_PASS_DEPENDENCY(Dependences)
+INITIALIZE_PASS_DEPENDENCY(DependenceInfo)
INITIALIZE_PASS_END(JSONExporter, "polly-export-jscop",
"Polly - Export Scops as JSON"
" (Writes a .jscop file for each Scop)",
@@ -374,7 +374,7 @@ INITIALIZE_PASS_BEGIN(JSONImporter, "pol
"Polly - Import Scops from JSON"
" (Reads a .jscop file for each Scop)",
false, false);
-INITIALIZE_PASS_DEPENDENCY(Dependences)
+INITIALIZE_PASS_DEPENDENCY(DependenceInfo)
INITIALIZE_PASS_DEPENDENCY(DataLayoutPass)
INITIALIZE_PASS_END(JSONImporter, "polly-import-jscop",
"Polly - Import Scops from JSON"
Modified: polly/trunk/lib/Makefile
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Makefile?rev=231308&r1=231307&r2=231308&view=diff
==============================================================================
--- polly/trunk/lib/Makefile (original)
+++ polly/trunk/lib/Makefile Wed Mar 4 16:43:40 2015
@@ -119,7 +119,7 @@ SOURCES= Polly.cpp \
Support/SCEVValidator.cpp \
Support/RegisterPasses.cpp \
Support/ScopHelper.cpp \
- Analysis/Dependences.cpp \
+ Analysis/DependenceInfo.cpp \
Analysis/ScopDetection.cpp \
Analysis/ScopDetectionDiagnostic.cpp \
Analysis/ScopInfo.cpp \
Modified: polly/trunk/lib/Support/RegisterPasses.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/RegisterPasses.cpp?rev=231308&r1=231307&r2=231308&view=diff
==============================================================================
--- polly/trunk/lib/Support/RegisterPasses.cpp (original)
+++ polly/trunk/lib/Support/RegisterPasses.cpp Wed Mar 4 16:43:40 2015
@@ -22,7 +22,7 @@
#include "polly/RegisterPasses.h"
#include "polly/Canonicalization.h"
#include "polly/CodeGen/CodeGeneration.h"
-#include "polly/Dependences.h"
+#include "polly/DependenceInfo.h"
#include "polly/LinkAllPasses.h"
#include "polly/Options.h"
#include "polly/ScopDetection.h"
@@ -142,7 +142,7 @@ void initializePollyPasses(PassRegistry
initializeIslCodeGenerationPass(Registry);
initializeCodePreparationPass(Registry);
initializeDeadCodeElimPass(Registry);
- initializeDependencesPass(Registry);
+ initializeDependenceInfoPass(Registry);
initializeIndependentBlocksPass(Registry);
initializeJSONExporterPass(Registry);
initializeJSONImporterPass(Registry);
Modified: polly/trunk/lib/Transform/DeadCodeElimination.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Transform/DeadCodeElimination.cpp?rev=231308&r1=231307&r2=231308&view=diff
==============================================================================
--- polly/trunk/lib/Transform/DeadCodeElimination.cpp (original)
+++ polly/trunk/lib/Transform/DeadCodeElimination.cpp Wed Mar 4 16:43:40 2015
@@ -32,7 +32,7 @@
//
//===----------------------------------------------------------------------===//
-#include "polly/Dependences.h"
+#include "polly/DependenceInfo.h"
#include "polly/LinkAllPasses.h"
#include "polly/ScopInfo.h"
#include "llvm/Support/CommandLine.h"
@@ -112,14 +112,14 @@ isl_union_set *DeadCodeElim::getLiveOut(
/// combine a certain number of precise steps with one approximating step that
/// simplifies the life set with an affine hull.
bool DeadCodeElim::eliminateDeadCode(Scop &S, int PreciseSteps) {
- Dependences *D = &getAnalysis<Dependences>();
+ DependenceInfo *D = &getAnalysis<DependenceInfo>();
if (!D->hasValidDependences())
return false;
isl_union_set *Live = getLiveOut(S);
isl_union_map *Dep =
- D->getDependences(Dependences::TYPE_RAW | Dependences::TYPE_RED);
+ D->getDependences(DependenceInfo::TYPE_RAW | DependenceInfo::TYPE_RED);
Dep = isl_union_map_reverse(Dep);
if (PreciseSteps == -1)
@@ -168,14 +168,14 @@ void DeadCodeElim::printScop(raw_ostream
void DeadCodeElim::getAnalysisUsage(AnalysisUsage &AU) const {
ScopPass::getAnalysisUsage(AU);
- AU.addRequired<Dependences>();
+ AU.addRequired<DependenceInfo>();
}
Pass *polly::createDeadCodeElimPass() { return new DeadCodeElim(); }
INITIALIZE_PASS_BEGIN(DeadCodeElim, "polly-dce",
"Polly - Remove dead iterations", false, false)
-INITIALIZE_PASS_DEPENDENCY(Dependences)
+INITIALIZE_PASS_DEPENDENCY(DependenceInfo)
INITIALIZE_PASS_DEPENDENCY(ScopInfo)
INITIALIZE_PASS_END(DeadCodeElim, "polly-dce", "Polly - Remove dead iterations",
false, false)
Modified: polly/trunk/lib/Transform/Pluto.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Transform/Pluto.cpp?rev=231308&r1=231307&r2=231308&view=diff
==============================================================================
--- polly/trunk/lib/Transform/Pluto.cpp (original)
+++ polly/trunk/lib/Transform/Pluto.cpp Wed Mar 4 16:43:40 2015
@@ -15,7 +15,7 @@
#ifdef PLUTO_FOUND
#include "polly/CodeGen/CodeGeneration.h"
-#include "polly/Dependences.h"
+#include "polly/DependenceInfo.h"
#include "polly/LinkAllPasses.h"
#include "polly/Options.h"
#include "polly/ScopInfo.h"
@@ -172,10 +172,10 @@ bool PlutoOptimizer::runOnScop(Scop &S)
isl_union_map *Deps, *ToPlutoNames, *Schedule;
PlutoOptions *Options;
- Dependences *D = &getAnalysis<Dependences>();
+ DependenceInfo *D = &getAnalysis<DependenceInfo>();
- int DependencesKinds =
- Dependences::TYPE_RAW | Dependences::TYPE_WAR | Dependences::TYPE_WAW;
+ int DependencesKinds = DependenceInfo::TYPE_RAW | DependenceInfo::TYPE_WAR |
+ DependenceInfo::TYPE_WAW;
Deps = D->getDependences(DependencesKinds);
Domain = S.getDomains();
@@ -254,7 +254,7 @@ void PlutoOptimizer::printScop(raw_ostre
void PlutoOptimizer::getAnalysisUsage(AnalysisUsage &AU) const {
ScopPass::getAnalysisUsage(AU);
- AU.addRequired<Dependences>();
+ AU.addRequired<DependenceInfo>();
}
Pass *polly::createPlutoOptimizerPass() { return new PlutoOptimizer(); }
@@ -262,7 +262,7 @@ Pass *polly::createPlutoOptimizerPass()
INITIALIZE_PASS_BEGIN(PlutoOptimizer, "polly-opt-pluto",
"Polly - Optimize schedule of SCoP (Pluto)", false,
false);
-INITIALIZE_PASS_DEPENDENCY(Dependences);
+INITIALIZE_PASS_DEPENDENCY(DependenceInfo);
INITIALIZE_PASS_DEPENDENCY(ScopInfo);
INITIALIZE_PASS_END(PlutoOptimizer, "polly-opt-pluto",
"Polly - Optimize schedule of SCoP (Pluto)", false, false)
Modified: polly/trunk/lib/Transform/ScheduleOptimizer.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Transform/ScheduleOptimizer.cpp?rev=231308&r1=231307&r2=231308&view=diff
==============================================================================
--- polly/trunk/lib/Transform/ScheduleOptimizer.cpp (original)
+++ polly/trunk/lib/Transform/ScheduleOptimizer.cpp Wed Mar 4 16:43:40 2015
@@ -26,7 +26,7 @@
#include "isl/schedule.h"
#include "isl/space.h"
#include "polly/CodeGen/CodeGeneration.h"
-#include "polly/Dependences.h"
+#include "polly/DependenceInfo.h"
#include "polly/LinkAllPasses.h"
#include "polly/Options.h"
#include "polly/ScopInfo.h"
@@ -481,7 +481,7 @@ bool IslScheduleOptimizer::runOnScop(Sco
return false;
}
- Dependences *D = &getAnalysis<Dependences>();
+ DependenceInfo *D = &getAnalysis<DependenceInfo>();
if (!D->hasValidDependences())
return false;
@@ -490,20 +490,20 @@ bool IslScheduleOptimizer::runOnScop(Sco
LastSchedule = nullptr;
// Build input data.
- int ValidityKinds =
- Dependences::TYPE_RAW | Dependences::TYPE_WAR | Dependences::TYPE_WAW;
+ int ValidityKinds = DependenceInfo::TYPE_RAW | DependenceInfo::TYPE_WAR |
+ DependenceInfo::TYPE_WAW;
int ProximityKinds;
if (OptimizeDeps == "all")
- ProximityKinds =
- Dependences::TYPE_RAW | Dependences::TYPE_WAR | Dependences::TYPE_WAW;
+ ProximityKinds = DependenceInfo::TYPE_RAW | DependenceInfo::TYPE_WAR |
+ DependenceInfo::TYPE_WAW;
else if (OptimizeDeps == "raw")
- ProximityKinds = Dependences::TYPE_RAW;
+ ProximityKinds = DependenceInfo::TYPE_RAW;
else {
errs() << "Do not know how to optimize for '" << OptimizeDeps << "'"
<< " Falling back to optimizing all dependences.\n";
- ProximityKinds =
- Dependences::TYPE_RAW | Dependences::TYPE_WAR | Dependences::TYPE_WAW;
+ ProximityKinds = DependenceInfo::TYPE_RAW | DependenceInfo::TYPE_WAR |
+ DependenceInfo::TYPE_WAW;
}
isl_union_set *Domain = S.getDomains();
@@ -648,7 +648,7 @@ void IslScheduleOptimizer::printScop(raw
void IslScheduleOptimizer::getAnalysisUsage(AnalysisUsage &AU) const {
ScopPass::getAnalysisUsage(AU);
- AU.addRequired<Dependences>();
+ AU.addRequired<DependenceInfo>();
}
Pass *polly::createIslScheduleOptimizerPass() {
@@ -657,7 +657,7 @@ Pass *polly::createIslScheduleOptimizerP
INITIALIZE_PASS_BEGIN(IslScheduleOptimizer, "polly-opt-isl",
"Polly - Optimize schedule of SCoP", false, false);
-INITIALIZE_PASS_DEPENDENCY(Dependences);
+INITIALIZE_PASS_DEPENDENCY(DependenceInfo);
INITIALIZE_PASS_DEPENDENCY(ScopInfo);
INITIALIZE_PASS_END(IslScheduleOptimizer, "polly-opt-isl",
"Polly - Optimize schedule of SCoP", false, false)
Added: polly/trunk/test/DependenceInfo/computeout.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/computeout.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/computeout.ll (added)
+++ polly/trunk/test/DependenceInfo/computeout.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,72 @@
+; RUN: opt -S %loadPolly -polly-detect-unprofitable -basicaa -polly-dependences -analyze < %s | FileCheck %s -check-prefix=VALUE
+; RUN: opt -S %loadPolly -polly-detect-unprofitable -basicaa -polly-dependences -analyze -polly-dependences-computeout=1 < %s | FileCheck %s -check-prefix=TIMEOUT
+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"
+target triple = "x86_64-pc-linux-gnu"
+
+; for(i = 0; i < 100; i++ )
+; S1: A[i] = 2;
+;
+; for (i = 0; i < 10; i++ )
+; S2: A[i] = 5;
+;
+; for (i = 0; i < 200; i++ )
+; S3: A[i] = 5;
+
+define void @sequential_writes() {
+entry:
+ %A = alloca [200 x i32]
+ br label %S1
+
+S1:
+ %indvar.1 = phi i64 [ 0, %entry ], [ %indvar.next.1, %S1 ]
+ %arrayidx.1 = getelementptr [200 x i32], [200 x i32]* %A, i64 0, i64 %indvar.1
+ store i32 2, i32* %arrayidx.1
+ %indvar.next.1 = add i64 %indvar.1, 1
+ %exitcond.1 = icmp ne i64 %indvar.next.1, 100
+ br i1 %exitcond.1, label %S1, label %exit.1
+
+exit.1:
+ br label %S2
+
+S2:
+ %indvar.2 = phi i64 [ 0, %exit.1 ], [ %indvar.next.2, %S2 ]
+ %arrayidx.2 = getelementptr [200 x i32], [200 x i32]* %A, i64 0, i64 %indvar.2
+ store i32 5, i32* %arrayidx.2
+ %indvar.next.2 = add i64 %indvar.2, 1
+ %exitcond.2 = icmp ne i64 %indvar.next.2, 10
+ br i1 %exitcond.2, label %S2, label %exit.2
+
+exit.2:
+ br label %S3
+
+S3:
+ %indvar.3 = phi i64 [ 0, %exit.2 ], [ %indvar.next.3, %S3 ]
+ %arrayidx.3 = getelementptr [200 x i32], [200 x i32]* %A, i64 0, i64 %indvar.3
+ store i32 7, i32* %arrayidx.3
+ %indvar.next.3 = add i64 %indvar.3, 1
+ %exitcond.3 = icmp ne i64 %indvar.next.3, 200
+ br i1 %exitcond.3, label %S3 , label %exit.3
+
+exit.3:
+ ret void
+}
+
+; VALUE: region: 'S1 => exit.3' in function 'sequential_writes':
+; VALUE: RAW dependences:
+; VALUE: { }
+; VALUE: WAR dependences:
+; VALUE: { }
+; VALUE: WAW dependences:
+; VALUE: {
+; VALUE: Stmt_S1[i0] -> Stmt_S2[i0] : i0 >= 0 and i0 <= 9;
+; VALUE: Stmt_S2[i0] -> Stmt_S3[i0] : i0 >= 0 and i0 <= 9;
+; VALUE: Stmt_S1[i0] -> Stmt_S3[i0] : i0 >= 10 and i0 <= 99
+; VALUE: }
+
+; TIMEOUT: region: 'S1 => exit.3' in function 'sequential_writes':
+; TIMEOUT: RAW dependences:
+; TIMEOUT: n/a
+; TIMEOUT: WAR dependences:
+; TIMEOUT: n/a
+; TIMEOUT: WAW dependences:
+; TIMEOUT: n/a
Added: polly/trunk/test/DependenceInfo/do_pluto_matmult.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/do_pluto_matmult.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/do_pluto_matmult.ll (added)
+++ polly/trunk/test/DependenceInfo/do_pluto_matmult.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,81 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -basicaa -polly-dependences -analyze -polly-dependences-analysis-type=value-based < %s | FileCheck %s -check-prefix=VALUE
+; RUN: opt %loadPolly -polly-detect-unprofitable -basicaa -polly-dependences -analyze -polly-dependences-analysis-type=memory-based -polly-delinearize < %s | FileCheck %s -check-prefix=MEMORY
+
+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"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct._IO_FILE = type { i32, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, i8*, %struct._IO_marker*, %struct._IO_FILE*, i32, i32, i64, i16, i8, [1 x i8], i8*, i64, i8*, i8*, i8*, i8*, i64, i32, [20 x i8] }
+%struct._IO_marker = type { %struct._IO_marker*, %struct._IO_FILE*, i32 }
+
+ at A = common global [36 x [49 x double]] zeroinitializer, align 8 ; <[36 x [49 x double]]*> [#uses=3]
+ at B = common global [36 x [49 x double]] zeroinitializer, align 8 ; <[36 x [49 x double]]*> [#uses=3]
+ at C = common global [36 x [49 x double]] zeroinitializer, align 8 ; <[36 x [49 x double]]*> [#uses=4]
+
+define void @do_pluto_matmult() nounwind {
+entry:
+ fence seq_cst
+ br label %do.body
+
+do.body: ; preds = %do.cond42, %entry
+ %indvar3 = phi i64 [ %indvar.next4, %do.cond42 ], [ 0, %entry ] ; <i64> [#uses=3]
+ br label %do.body1
+
+do.body1: ; preds = %do.cond36, %do.body
+ %indvar1 = phi i64 [ %indvar.next2, %do.cond36 ], [ 0, %do.body ] ; <i64> [#uses=3]
+ %arrayidx5 = getelementptr [36 x [49 x double]], [36 x [49 x double]]* @C, i64 0, i64 %indvar3, i64 %indvar1 ; <double*> [#uses=2]
+ br label %do.body2
+
+do.body2: ; preds = %do.cond, %do.body1
+ %indvar = phi i64 [ %indvar.next, %do.cond ], [ 0, %do.body1 ] ; <i64> [#uses=3]
+ %arrayidx13 = getelementptr [36 x [49 x double]], [36 x [49 x double]]* @A, i64 0, i64 %indvar3, i64 %indvar ; <double*> [#uses=1]
+ %arrayidx22 = getelementptr [36 x [49 x double]], [36 x [49 x double]]* @B, i64 0, i64 %indvar, i64 %indvar1 ; <double*> [#uses=1]
+ %tmp6 = load double, double* %arrayidx5 ; <double> [#uses=1]
+ %mul = fmul double 1.000000e+00, %tmp6 ; <double> [#uses=1]
+ %tmp14 = load double, double* %arrayidx13 ; <double> [#uses=1]
+ %mul15 = fmul double 1.000000e+00, %tmp14 ; <double> [#uses=1]
+ %tmp23 = load double, double* %arrayidx22 ; <double> [#uses=1]
+ %mul24 = fmul double %mul15, %tmp23 ; <double> [#uses=1]
+ %add = fadd double %mul, %mul24 ; <double> [#uses=1]
+ store double %add, double* %arrayidx5
+ br label %do.cond
+
+do.cond: ; preds = %do.body2
+ %indvar.next = add i64 %indvar, 1 ; <i64> [#uses=2]
+ %exitcond = icmp ne i64 %indvar.next, 36 ; <i1> [#uses=1]
+ br i1 %exitcond, label %do.body2, label %do.end
+
+do.end: ; preds = %do.cond
+ br label %do.cond36
+
+do.cond36: ; preds = %do.end
+ %indvar.next2 = add i64 %indvar1, 1 ; <i64> [#uses=2]
+ %exitcond5 = icmp ne i64 %indvar.next2, 36 ; <i1> [#uses=1]
+ br i1 %exitcond5, label %do.body1, label %do.end39
+
+do.end39: ; preds = %do.cond36
+ br label %do.cond42
+
+do.cond42: ; preds = %do.end39
+ %indvar.next4 = add i64 %indvar3, 1 ; <i64> [#uses=2]
+ %exitcond6 = icmp ne i64 %indvar.next4, 36 ; <i1> [#uses=1]
+ br i1 %exitcond6, label %do.body, label %do.end45
+
+do.end45: ; preds = %do.cond42
+ fence seq_cst
+ ret void
+}
+
+; VALUE: RAW dependences:
+; VALUE: { Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, 1 + i2] : i0 >= 0 and i0 <= 35 and i1 >= 0 and i1 <= 35 and i2 >= 0 and i2 <= 34 }
+; VALUE: WAR dependences:
+; VALUE: { }
+; VALUE: WAW dependences:
+; VALUE: { Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, 1 + i2] : i0 <= 35 and i0 >= 0 and i1 <= 35 and i1 >= 0 and i2 <= 34 and i2 >= 0 }
+
+
+; MEMORY: RAW dependences:
+; MEMORY: { Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, o2] : i0 <= 35 and i0 >= 0 and i1 <= 35 and i1 >= 0 and i2 >= 0 and o2 >= 1 + i2 and o2 <= 35 and o2 >= 0 }
+; MEMORY: WAR dependences:
+; MEMORY: { Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, o2] : i0 <= 35 and i0 >= 0 and i1 <= 35 and i1 >= 0 and i2 >= 0 and o2 >= 1 + i2 and o2 <= 35 and o2 >= 0 }
+; MEMORY: WAW dependences:
+; MEMORY: { Stmt_do_body2[i0, i1, i2] -> Stmt_do_body2[i0, i1, o2] : i0 <= 35 and i0 >= 0 and i1 <= 35 and i1 >= 0 and i2 >= 0 and o2 >= 1 + i2 and o2 <= 35 and o2 >= 0 }
Added: polly/trunk/test/DependenceInfo/reduction_complex_location.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_complex_location.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_complex_location.ll (added)
+++ polly/trunk/test/DependenceInfo/reduction_complex_location.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,59 @@
+; RUN: opt -basicaa %loadPolly -polly-detect-unprofitable -polly-dependences -analyze < %s | FileCheck %s
+;
+; CHECK: RAW dependences:
+; CHECK: { }
+; CHECK: WAR dependences:
+; CHECK: { }
+; CHECK: WAW dependences:
+; CHECK: { }
+; CHECK: Reduction dependences:
+; CHECK: { Stmt_for_body3[i0, i1] -> Stmt_for_body3[2 + i0, -1 + i1] : i0 <= 97 and i0 >= 0 and i1 <= 99 and i1 >= 1 }
+;
+; void f(int *sum) {
+; for (int i = 0; i < 100; i++)
+; for (int j = 0; j < 100; j++)
+; sum[i+j*2] += j * i;
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc6, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc7, %for.inc6 ]
+ %exitcond1 = icmp ne i32 %i.0, 100
+ br i1 %exitcond1, label %for.body, label %for.end8
+
+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, 100
+ br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3: ; preds = %for.cond1
+ %mul = mul nsw i32 %j.0, %i.0
+ %mul4 = shl nsw i32 %j.0, 1
+ %add = add nsw i32 %i.0, %mul4
+ %arrayidx = getelementptr inbounds i32, i32* %sum, i32 %add
+ %tmp = load i32, i32* %arrayidx, align 4
+ %add5 = add nsw i32 %tmp, %mul
+ store i32 %add5, i32* %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.inc6
+
+for.inc6: ; preds = %for.end
+ %inc7 = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end8: ; preds = %for.cond
+ ret void
+}
Added: polly/trunk/test/DependenceInfo/reduction_dependences_equal_non_reduction_dependences.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_dependences_equal_non_reduction_dependences.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_dependences_equal_non_reduction_dependences.ll (added)
+++ polly/trunk/test/DependenceInfo/reduction_dependences_equal_non_reduction_dependences.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,62 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -basicaa -polly-dependences -analyze < %s | FileCheck %s
+;
+; This loopnest contains a reduction which imposes the same dependences as the
+; accesses to the array A. We need to ensure we keep the dependences of A.
+;
+; CHECK: RAW dependences:
+; CHECK: { Stmt_for_body[i0] -> Stmt_for_body[1 + i0] : i0 >= 0 and i0 <= 1022 }
+; CHECK: WAR dependences:
+; CHECK: { }
+; CHECK: WAW dependences:
+; CHECK: { Stmt_for_body[i0] -> Stmt_for_body[1 + i0] : i0 <= 1022 and i0 >= 0 }
+; CHECK: Reduction dependences:
+; CHECK: { Stmt_for_body[i0] -> Stmt_for_body[1 + i0] : i0 <= 1022 and i0 >= 0 }
+;
+;
+; void AandSum(int *restrict sum, int *restrict A) {
+; for (int i = 0; i < 1024; i++) {
+; A[i] = A[i] + A[i - 1];
+; A[i - 1] = A[i] + A[i - 2];
+; *sum += i;
+; }
+; }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @AandSum(i32* noalias %sum, i32* noalias %A) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+ %exitcond = icmp ne i32 %i.0, 1024
+ br i1 %exitcond, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %arrayidx = getelementptr inbounds i32, i32* %A, i32 %i.0
+ %tmp = load i32, i32* %arrayidx, align 4
+ %sub = add nsw i32 %i.0, -1
+ %arrayidx1 = getelementptr inbounds i32, i32* %A, i32 %sub
+ %tmp1 = load i32, i32* %arrayidx1, align 4
+ %add = add nsw i32 %tmp, %tmp1
+ %arrayidx2 = getelementptr inbounds i32, i32* %A, i32 %i.0
+ store i32 %add, i32* %arrayidx2, align 4
+ %sub4 = add nsw i32 %i.0, -2
+ %arrayidx5 = getelementptr inbounds i32, i32* %A, i32 %sub4
+ %tmp2 = load i32, i32* %arrayidx5, align 4
+ %add6 = add nsw i32 %add, %tmp2
+ %sub7 = add nsw i32 %i.0, -1
+ %arrayidx8 = getelementptr inbounds i32, i32* %A, i32 %sub7
+ store i32 %add6, i32* %arrayidx8, align 4
+ %tmp3 = load i32, i32* %sum, align 4
+ %add9 = add nsw i32 %tmp3, %i.0
+ store i32 %add9, i32* %sum, align 4
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %inc = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
Added: polly/trunk/test/DependenceInfo/reduction_mixed_reduction_and_non_reduction_dependences.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_mixed_reduction_and_non_reduction_dependences.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_mixed_reduction_and_non_reduction_dependences.ll (added)
+++ polly/trunk/test/DependenceInfo/reduction_mixed_reduction_and_non_reduction_dependences.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,59 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -polly-dependences -analyze < %s | FileCheck %s
+;
+; CHECK: RAW dependences:
+; CHECK-DAG: Stmt_for_body3[i0, i1] -> Stmt_for_body3[i0 + i1, o1] : i1 <= 1023 - i0 and i1 >= 0 and i1 <= 1 and i0 >= 0 and o1 <= 511 and o1 >= 1
+; CHECK: WAR dependences:
+; CHECK: { }
+; CHECK: WAW dependences:
+; CHECK-DAG: Stmt_for_body3[i0, i1] -> Stmt_for_body3[1 + i0, -1 + i1] : i0 <= 1022 and i0 >= 0 and i1 <= 511 and i1 >= 2
+; CHECK-DAG: Stmt_for_body3[i0, 2] -> Stmt_for_body3[2 + i0, 0] : i0 <= 1021 and i0 >= 0
+; CHECK: Reduction dependences:
+; CHECK: { Stmt_for_body3[i0, 1] -> Stmt_for_body3[1 + i0, 0] : i0 <= 1022 and i0 >= 0 }
+;
+; void f(int *sum) {
+; for (int i = 0; i < 1024; i++)
+; for (int j = 0; j < 512; j++)
+; sum[i + j] = sum[i] + 3;
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc6, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc7, %for.inc6 ]
+ %exitcond1 = icmp ne i32 %i.0, 1024
+ br i1 %exitcond1, label %for.body, label %for.end8
+
+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, 512
+ br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3: ; preds = %for.cond1
+ %arrayidx = getelementptr inbounds i32, i32* %sum, i32 %i.0
+ %tmp = load i32, i32* %arrayidx, align 4
+ %add = add nsw i32 %tmp, 3
+ %add4 = add nsw i32 %i.0, %j.0
+ %arrayidx5 = getelementptr inbounds i32, i32* %sum, i32 %add4
+ store i32 %add, i32* %arrayidx5, 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.inc6
+
+for.inc6: ; preds = %for.end
+ %inc7 = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end8: ; preds = %for.cond
+ ret void
+}
Added: polly/trunk/test/DependenceInfo/reduction_multiple_loops_array_sum.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_multiple_loops_array_sum.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_multiple_loops_array_sum.ll (added)
+++ polly/trunk/test/DependenceInfo/reduction_multiple_loops_array_sum.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,77 @@
+; RUN: opt -basicaa %loadPolly -polly-detect-unprofitable -polly-dependences -analyze < %s | FileCheck %s
+;
+; Verify that only the inner reduction like accesses cause reduction dependences
+;
+; CHECK: Reduction dependences:
+; CHECK: { Stmt_for_body3[i0, i1] -> Stmt_for_body3[i0, 1 + i1] : i0 <= 99 and i0 >= 0 and i1 <= 98 and i1 >= 0 }
+;
+; void f(int * restrict A, int * restrict sum) {
+; int i, j, k;
+; for (i = 0; i < 100; i++) {
+; *sum *= 7;
+; for (j = 0; j < 100; j++) {
+; *sum += A[i+j];
+; for (k = 0; k< 100; k++) {}
+; }
+; }
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* noalias %A, i32* noalias %sum) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc11, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc12, %for.inc11 ]
+ %exitcond2 = icmp ne i32 %i.0, 100
+ br i1 %exitcond2, label %for.body, label %for.end13
+
+for.body: ; preds = %for.cond
+ %tmp = load i32, i32* %sum, align 4
+ %mul = mul nsw i32 %tmp, 7
+ store i32 %mul, i32* %sum, align 4
+ br label %for.cond1
+
+for.cond1: ; preds = %for.inc8, %for.body
+ %j.0 = phi i32 [ 0, %for.body ], [ %inc9, %for.inc8 ]
+ %exitcond1 = icmp ne i32 %j.0, 100
+ br i1 %exitcond1, label %for.body3, label %for.end10
+
+for.body3: ; preds = %for.cond1
+ %add = add nsw i32 %i.0, %j.0
+ %arrayidx = getelementptr inbounds i32, i32* %A, i32 %add
+ %tmp3 = load i32, i32* %arrayidx, align 4
+ %tmp4 = load i32, i32* %sum, align 4
+ %add4 = add nsw i32 %tmp4, %tmp3
+ store i32 %add4, i32* %sum, align 4
+ br label %for.cond5
+
+for.cond5: ; preds = %for.inc, %for.body3
+ %k.0 = phi i32 [ 0, %for.body3 ], [ %inc, %for.inc ]
+ %exitcond = icmp ne i32 %k.0, 100
+ br i1 %exitcond, label %for.body7, label %for.end
+
+for.body7: ; preds = %for.cond5
+ br label %for.inc
+
+for.inc: ; preds = %for.body7
+ %inc = add nsw i32 %k.0, 1
+ br label %for.cond5
+
+for.end: ; preds = %for.cond5
+ br label %for.inc8
+
+for.inc8: ; preds = %for.end
+ %inc9 = add nsw i32 %j.0, 1
+ br label %for.cond1
+
+for.end10: ; preds = %for.cond1
+ br label %for.inc11
+
+for.inc11: ; preds = %for.end10
+ %inc12 = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end13: ; preds = %for.cond
+ ret void
+}
Added: polly/trunk/test/DependenceInfo/reduction_multiple_loops_array_sum_2.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_multiple_loops_array_sum_2.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_multiple_loops_array_sum_2.ll (added)
+++ polly/trunk/test/DependenceInfo/reduction_multiple_loops_array_sum_2.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,79 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -polly-dependences -analyze -basicaa < %s | FileCheck %s
+;
+; CHECK: RAW dependences:
+; CHECK: { }
+; CHECK: WAR dependences:
+; CHECK: { }
+; CHECK: WAW dependences:
+; CHECK: { }
+; CHECK: Reduction dependences:
+; CHECK-DAG: Stmt_for_body3[i0, i1] -> Stmt_for_body3[i0, 1 + i1] : i0 <= 99 and i0 >= 0 and i1 <= 98 and i1 >= 0
+; CHECK-DAG: Stmt_for_body3[i0, 99] -> Stmt_for_body3[1 + i0, 0] : i0 <= 98 and i0 >= 0
+;
+; int f(int * restrict A, int * restrict sum) {
+; int i, j, k;
+; for (i = 0; i < 100; i++) {
+; for (j = 0; j < 100; j++) {
+; sum += A[i+j];
+; for (k = 0; k< 100; k++) {}
+; }
+; }
+; return sum;
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* noalias %A, i32* noalias %sum) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc11, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc12, %for.inc11 ]
+ %exitcond2 = icmp ne i32 %i.0, 100
+ br i1 %exitcond2, label %for.body, label %for.end13
+
+for.body: ; preds = %for.cond
+ br label %for.cond1
+
+for.cond1: ; preds = %for.inc8, %for.body
+ %j.0 = phi i32 [ 0, %for.body ], [ %inc9, %for.inc8 ]
+ %exitcond1 = icmp ne i32 %j.0, 100
+ br i1 %exitcond1, label %for.body3, label %for.end10
+
+for.body3: ; preds = %for.cond1
+ %add = add nsw i32 %i.0, %j.0
+ %arrayidx = getelementptr inbounds i32, i32* %A, i32 %add
+ %tmp3 = load i32, i32* %arrayidx, align 4
+ %tmp4 = load i32, i32* %sum, align 4
+ %add4 = add nsw i32 %tmp4, %tmp3
+ store i32 %add4, i32* %sum, align 4
+ br label %for.cond5
+
+for.cond5: ; preds = %for.inc, %for.body3
+ %k.0 = phi i32 [ 0, %for.body3 ], [ %inc, %for.inc ]
+ %exitcond = icmp ne i32 %k.0, 100
+ br i1 %exitcond, label %for.body7, label %for.end
+
+for.body7: ; preds = %for.cond5
+ br label %for.inc
+
+for.inc: ; preds = %for.body7
+ %inc = add nsw i32 %k.0, 1
+ br label %for.cond5
+
+for.end: ; preds = %for.cond5
+ br label %for.inc8
+
+for.inc8: ; preds = %for.end
+ %inc9 = add nsw i32 %j.0, 1
+ br label %for.cond1
+
+for.end10: ; preds = %for.cond1
+ br label %for.inc11
+
+for.inc11: ; preds = %for.end10
+ %inc12 = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end13: ; preds = %for.cond
+ ret void
+}
Added: polly/trunk/test/DependenceInfo/reduction_multiple_loops_array_sum_3.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_multiple_loops_array_sum_3.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_multiple_loops_array_sum_3.ll (added)
+++ polly/trunk/test/DependenceInfo/reduction_multiple_loops_array_sum_3.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,73 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -polly-dependences -analyze -basicaa < %s | FileCheck %s
+;
+; CHECK: Reduction dependences:
+; CHECK: { Stmt_for_inc[i0, i1] -> Stmt_for_inc[i0, 1 + i1] : i0 <= 99 and i0 >= 0 and i1 <= 98 and i1 >= 0 }
+;
+; int f(int * __restrict__ A) {
+; int i, j, sum = 0;
+; for (k = 0; k < 37; k = g(k)) {
+; for (i = 0; i < 100; i++) {
+; sum *= 2;
+; for (j = 0; j < 100; j++) {
+; sum += A[i+j];
+; }
+; }
+; }
+; return sum;
+; }
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+declare i64 @g(i64)
+
+define i32 @f(i32* noalias %A) {
+entry:
+ %sum.04.reg2mem = alloca i32
+ %sum.12.reg2mem = alloca i32
+ br label %entry.split
+
+entry.split: ; preds = %entry
+ store i32 0, i32* %sum.04.reg2mem
+ br label %for.body_outer_split
+
+for.body_outer_split: ; preds = %entry.split, %for.inc5
+ %indvars.ivK = phi i64 [ 0, %entry.split ], [ %incK, %for.bos2 ]
+ br label %for.body_outer
+
+for.body_outer: ; preds = %for.body_outer_split
+ %incK = call i64 @g(i64 %indvars.ivK)
+ %exitcondK = icmp eq i64 %incK, 100
+ br i1 %exitcondK, label %for.end7, label %for.body
+
+for.body: ; preds = %for.inc5, %for.body_outer
+ %indvars.iv23 = phi i64 [ 0, %for.body_outer ], [ %3, %for.inc5 ]
+ %sum.04.reload = load i32, i32* %sum.04.reg2mem
+ %mul = shl nsw i32 %sum.04.reload, 1
+ store i32 %mul, i32* %sum.12.reg2mem
+ br label %for.inc
+
+for.inc: ; preds = %for.inc, %for.body
+ %indvars.iv1 = phi i64 [ 0, %for.body ], [ %1, %for.inc ]
+ %sum.12.reload = load i32, i32* %sum.12.reg2mem
+ %0 = add i64 %indvars.iv23, %indvars.iv1
+ %arrayidx = getelementptr i32, i32* %A, i64 %0
+ %tmp5 = load i32, i32* %arrayidx, align 4
+ %add4 = add nsw i32 %tmp5, %sum.12.reload
+ %1 = add nuw nsw i64 %indvars.iv1, 1
+ %exitcond1 = icmp eq i64 %1, 100
+ store i32 %add4, i32* %sum.12.reg2mem
+ br i1 %exitcond1, label %for.inc5, label %for.inc
+
+for.inc5: ; preds = %for.inc
+ %2 = load i32, i32* %sum.12.reg2mem
+ %3 = add nuw nsw i64 %indvars.iv23, 1
+ %exitcond2 = icmp eq i64 %3, 100
+ store i32 %2, i32* %sum.04.reg2mem
+ br i1 %exitcond2, label %for.bos2, label %for.body
+
+for.bos2:
+ br label %for.body_outer_split
+
+for.end7: ; preds = %for.inc5
+ %4 = load i32, i32* %sum.04.reg2mem
+ ret i32 %4
+}
Added: polly/trunk/test/DependenceInfo/reduction_multiple_reductions.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_multiple_reductions.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_multiple_reductions.ll (added)
+++ polly/trunk/test/DependenceInfo/reduction_multiple_reductions.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,59 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -basicaa -polly-dependences -analyze < %s | FileCheck %s
+;
+; Verify we do not have dependences between the if and the else clause
+;
+; CHECK: RAW dependences:
+; CHECK: { }
+; CHECK: WAR dependences:
+; CHECK: { }
+; CHECK: WAW dependences:
+; CHECK: { }
+; CHECK: Reduction dependences:
+; CHECK-DAG: Stmt_if_then[i0] -> Stmt_if_then[1 + i0] : i0 <= 510 and i0 >= 0
+; CHECK-DAG: Stmt_if_else[i0] -> Stmt_if_else[1 + i0] : i0 <= 1022 and i0 >= 512
+;
+; void f(int *restrict sum, int *restrict prod) {
+; for (int i = 0; i < 1024; i++)
+; if (i < 512)
+; *sum += i;
+; else
+; *prod *= i;
+; }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* noalias %sum, i32* noalias %prod) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+ %exitcond = icmp ne i32 %i.0, 1024
+ br i1 %exitcond, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %cmp1 = icmp slt i32 %i.0, 512
+ br i1 %cmp1, label %if.then, label %if.else
+
+if.then: ; preds = %for.body
+ %tmp = load i32, i32* %sum, align 4
+ %add = add nsw i32 %tmp, %i.0
+ store i32 %add, i32* %sum, align 4
+ br label %if.end
+
+if.else: ; preds = %for.body
+ %tmp1 = load i32, i32* %prod, align 4
+ %mul = mul nsw i32 %tmp1, %i.0
+ store i32 %mul, i32* %prod, align 4
+ br label %if.end
+
+if.end: ; preds = %if.else, %if.then
+ br label %for.inc
+
+for.inc: ; preds = %if.end
+ %inc = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
Added: polly/trunk/test/DependenceInfo/reduction_multiple_reductions_2.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_multiple_reductions_2.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_multiple_reductions_2.ll (added)
+++ polly/trunk/test/DependenceInfo/reduction_multiple_reductions_2.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,110 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -basicaa -polly-dependences -analyze < %s | FileCheck %s
+;
+; CHECK: RAW dependences:
+; CHECK-DAG: Stmt_S2[i0, i1] -> Stmt_S3[i0] : i0 <= 1023 and i0 >= 0 and i1 <= 1023 and i1 >= 0
+; CHECK-DAG: Stmt_S3[i0] -> Stmt_S0[1 + i0] : i0 <= 1022 and i0 >= 0
+; CHECK-DAG: Stmt_S0[i0] -> Stmt_S1[i0, o1] : i0 <= 1023 and i0 >= 0 and o1 <= 1023 and o1 >= 0
+; These are the important RAW dependences, as they need to originate/end in only one iteration:
+; CHECK-DAG: Stmt_S1[i0, 1023] -> Stmt_S2[i0, o1] : i0 <= 1023 and i0 >= 0 and o1 <= 1023 and o1 >= 0
+; CHECK-DAG: Stmt_S1[i0, i1] -> Stmt_S2[i0, 0] : i0 <= 1023 and i0 >= 0 and i1 <= 1022 and i1 >= 0
+; CHECK: WAR dependences:
+; CHECK: { }
+; CHECK: WAW dependences:
+; CHECK-DAG: Stmt_S2[i0, i1] -> Stmt_S3[i0] : i0 <= 1023 and i0 >= 0 and i1 <= 1023 and i1 >= 0
+; CHECK-DAG: Stmt_S3[i0] -> Stmt_S0[1 + i0] : i0 <= 1022 and i0 >= 0
+; CHECK-DAG: Stmt_S0[i0] -> Stmt_S1[i0, o1] : i0 <= 1023 and i0 >= 0 and o1 <= 1023 and o1 >= 0
+; These are the important WAW dependences, as they need to originate/end in only one iteration:
+; CHECK-DAG: Stmt_S1[i0, 1023] -> Stmt_S2[i0, o1] : i0 <= 1023 and i0 >= 0 and o1 <= 1023 and o1 >= 0
+; CHECK-DAG: Stmt_S1[i0, i1] -> Stmt_S2[i0, 0] : i0 <= 1023 and i0 >= 0 and i1 <= 1022 and i1 >= 0
+; CHECK: Reduction dependences:
+; CHECK-DAG: Stmt_S1[i0, i1] -> Stmt_S1[i0, 1 + i1] : i0 <= 1023 and i0 >= 0 and i1 <= 1022 and i1 >= 0
+; CHECK-DAG: Stmt_S2[i0, i1] -> Stmt_S2[i0, 1 + i1] : i0 <= 1023 and i0 >= 0 and i1 <= 1022 and i1 >= 0
+;
+; void f(int *restrict red) {
+; for (int j = 0; j < 1024; j++) {
+; S0: *red = 42 + *red * 5;
+; for (int i = 0; i < 1024; i++)
+; S1: *red *= i;
+; for (int i = 0; i < 1024; i++)
+; S2: *red += i;
+; S3: *red = 42 + *red * 7;
+; }
+; }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* noalias %red) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc15, %entry
+ %j.0 = phi i32 [ 0, %entry ], [ %inc16, %for.inc15 ]
+ %exitcond2 = icmp ne i32 %j.0, 1024
+ br i1 %exitcond2, label %for.body, label %for.end17
+
+for.body: ; preds = %for.cond
+ br label %S0
+
+S0: ; preds = %for.body
+ %tmp = load i32, i32* %red, align 4
+ %mul = mul nsw i32 %tmp, 5
+ %add = add nsw i32 %mul, 42
+ store i32 %add, i32* %red, align 4
+ br label %for.cond1
+
+for.cond1: ; preds = %for.inc, %S0
+ %i.0 = phi i32 [ 0, %S0 ], [ %inc, %for.inc ]
+ %exitcond = icmp ne i32 %i.0, 1024
+ br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3: ; preds = %for.cond1
+ br label %S1
+
+S1: ; preds = %for.body3
+ %tmp3 = load i32, i32* %red, align 4
+ %mul4 = mul nsw i32 %tmp3, %i.0
+ store i32 %mul4, i32* %red, align 4
+ br label %for.inc
+
+for.inc: ; preds = %S1
+ %inc = add nsw i32 %i.0, 1
+ br label %for.cond1
+
+for.end: ; preds = %for.cond1
+ br label %for.cond6
+
+for.cond6: ; preds = %for.inc10, %for.end
+ %i5.0 = phi i32 [ 0, %for.end ], [ %inc11, %for.inc10 ]
+ %exitcond1 = icmp ne i32 %i5.0, 1024
+ br i1 %exitcond1, label %for.body8, label %for.end12
+
+for.body8: ; preds = %for.cond6
+ br label %S2
+
+S2: ; preds = %for.body8
+ %tmp4 = load i32, i32* %red, align 4
+ %add9 = add nsw i32 %tmp4, %i5.0
+ store i32 %add9, i32* %red, align 4
+ br label %for.inc10
+
+for.inc10: ; preds = %S2
+ %inc11 = add nsw i32 %i5.0, 1
+ br label %for.cond6
+
+for.end12: ; preds = %for.cond6
+ br label %S3
+
+S3: ; preds = %for.end12
+ %tmp5 = load i32, i32* %red, align 4
+ %mul13 = mul nsw i32 %tmp5, 7
+ %add14 = add nsw i32 %mul13, 42
+ store i32 %add14, i32* %red, align 4
+ br label %for.inc15
+
+for.inc15: ; preds = %S3
+ %inc16 = add nsw i32 %j.0, 1
+ br label %for.cond
+
+for.end17: ; preds = %for.cond
+ ret void
+}
Added: polly/trunk/test/DependenceInfo/reduction_only_reduction_like_access.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_only_reduction_like_access.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_only_reduction_like_access.ll (added)
+++ polly/trunk/test/DependenceInfo/reduction_only_reduction_like_access.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,44 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -polly-dependences -analyze < %s | FileCheck %s
+;
+; FIXME: Change the comment once we allow different pointers
+; The statement is "almost" reduction like but should not yield any reduction dependences
+;
+; We are limited to binary reductions at the moment and this is not one.
+; There are never at least two iterations which read __and__ write to the same
+; location, thus we won't find the RAW and WAW dependences of a reduction,
+; thus we should not find Reduction dependences.
+;
+; CHECK: Reduction dependences:
+; CHECK: { }
+;
+; void f(int *sum) {
+; for (int i = 0; i < 100; i++)
+; sum[i] = sum[99-i] + i;
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+ %exitcond = icmp ne i32 %i.0, 100
+ br i1 %exitcond, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %sub = sub nsw i32 99, %i.0
+ %arrayidx = getelementptr inbounds i32, i32* %sum, i32 %sub
+ %tmp = load i32, i32* %arrayidx, align 4
+ %add = add nsw i32 %tmp, %i.0
+ %arrayidx1 = getelementptr inbounds i32, i32* %sum, i32 %i.0
+ store i32 %add, i32* %arrayidx1, align 4
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %inc = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
Added: polly/trunk/test/DependenceInfo/reduction_partially_escaping_intermediate_in_other_stmt.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_partially_escaping_intermediate_in_other_stmt.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_partially_escaping_intermediate_in_other_stmt.ll (added)
+++ polly/trunk/test/DependenceInfo/reduction_partially_escaping_intermediate_in_other_stmt.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,69 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -polly-dependences -analyze -basicaa < %s | FileCheck %s
+;
+; CHECK: Reduction dependences:
+; CHECK: [N] -> { Stmt_for_body3[i0, i1] -> Stmt_for_body3[i0, 1 + i1] : i0 <= 1023 and i0 >= 0 and i1 <= 1022 and i1 >= 0 and i1 >= 1024 - N + i0 }
+;
+; void f(int N, int * restrict sums, int * restrict escape) {
+; for (int i = 0; i < 1024; i++) {
+; for (int j = 0; j < 1024; j++) {
+; sums[i] += 5;
+; if (N - i + j < 1024)
+; escape[N - i + j] = sums[i];
+; }
+; }
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32 %N, i32* noalias %sums, i32* noalias %escape) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc10, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc11, %for.inc10 ]
+ %exitcond1 = icmp ne i32 %i.0, 1024
+ br i1 %exitcond1, label %for.body, label %for.end12
+
+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, 1024
+ br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3: ; preds = %for.cond1
+ %arrayidx = getelementptr inbounds i32, i32* %sums, i32 %i.0
+ %tmp = load i32, i32* %arrayidx, align 4
+ %add = add nsw i32 %tmp, 5
+ store i32 %add, i32* %arrayidx, align 4
+ %sub = sub nsw i32 %N, %i.0
+ %add4 = add nsw i32 %sub, %j.0
+ %cmp5 = icmp slt i32 %add4, 1024
+ br i1 %cmp5, label %if.then, label %if.end
+
+if.then: ; preds = %for.body3
+ %arrayidx6 = getelementptr inbounds i32, i32* %sums, i32 %i.0
+ %tmp2 = load i32, i32* %arrayidx6, align 4
+ %sub7 = sub nsw i32 %N, %i.0
+ %add8 = add nsw i32 %sub7, %j.0
+ %arrayidx9 = getelementptr inbounds i32, i32* %escape, i32 %add8
+ store i32 %tmp2, i32* %arrayidx9, align 4
+ br label %if.end
+
+if.end: ; preds = %if.then, %for.body3
+ br label %for.inc
+
+for.inc: ; preds = %if.end
+ %inc = add nsw i32 %j.0, 1
+ br label %for.cond1
+
+for.end: ; preds = %for.cond1
+ br label %for.inc10
+
+for.inc10: ; preds = %for.end
+ %inc11 = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end12: ; preds = %for.cond
+ ret void
+}
Added: polly/trunk/test/DependenceInfo/reduction_privatization_deps.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_privatization_deps.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_privatization_deps.ll (added)
+++ polly/trunk/test/DependenceInfo/reduction_privatization_deps.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,111 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -basicaa -polly-dependences -analyze < %s | FileCheck %s
+;
+; CHECK: RAW dependences:
+; CHECK-DAG: Stmt_S0[i0] -> Stmt_S1[o0, i0 - o0] : i0 <= 1023 and o0 >= 0 and o0 <= i0
+; CHECK-DAG: Stmt_S1[i0, i1] -> Stmt_S2[-1 + i0 + i1] : i1 <= 1023 and i1 >= 0 and i1 >= 1 - i0 and i0 >= 0 and i0 <= 1023 and i1 <= 1024 - i0
+; CHECK: WAR dependences:
+; CHECK-DAG: Stmt_S2[i0] -> Stmt_S2[1 + i0] : i0 <= 1022 and i0 >= 0
+; CHECK-DAG: Stmt_S1[i0, i1] -> Stmt_S2[i0 + i1] : i1 <= 1023 - i0 and i1 >= 0 and i1 >= 1 - i0 and i0 >= 0 }
+; CHECK: WAW dependences:
+; CHECK-DAG: Stmt_S0[i0] -> Stmt_S1[o0, i0 - o0] : i0 <= 1023 and o0 >= 0 and o0 <= i0
+; CHECK-DAG: Stmt_S1[0, 0] -> Stmt_S2[0]
+; CHECK: Reduction dependences:
+; CHECK-DAG: Stmt_S1[i0, i1] -> Stmt_S1[1 + i0, -1 + i1] : i0 <= 1022 and i0 >= 0 and i1 <= 1023 and i1 >= 1
+;
+; void f(int *sum) {
+; for (int i = 0; i < 1024; i++)
+; S0: sum[i] = 0;
+; for (int i = 0; i < 1024; i++)
+; for (int j = 0; j < 1024; j++)
+; S1: sum[i + j] += i;
+; for (int i = 0; i < 1024; i++)
+; S2: sum[i] = sum[i + 1] * 3;
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+ %exitcond3 = icmp ne i32 %i.0, 1024
+ br i1 %exitcond3, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ br label %S0
+
+S0: ; preds = %for.body
+ %arrayidx = getelementptr inbounds i32, i32* %sum, i32 %i.0
+ store i32 0, i32* %arrayidx, align 4
+ br label %for.inc
+
+for.inc: ; preds = %S0
+ %inc = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ br label %for.cond2
+
+for.cond2: ; preds = %for.inc13, %for.end
+ %i1.0 = phi i32 [ 0, %for.end ], [ %inc14, %for.inc13 ]
+ %exitcond2 = icmp ne i32 %i1.0, 1024
+ br i1 %exitcond2, label %for.body4, label %for.end15
+
+for.body4: ; preds = %for.cond2
+ br label %for.cond5
+
+for.cond5: ; preds = %for.inc10, %for.body4
+ %j.0 = phi i32 [ 0, %for.body4 ], [ %inc11, %for.inc10 ]
+ %exitcond1 = icmp ne i32 %j.0, 1024
+ br i1 %exitcond1, label %for.body7, label %for.end12
+
+for.body7: ; preds = %for.cond5
+ br label %S1
+
+S1: ; preds = %for.body7
+ %add = add nsw i32 %i1.0, %j.0
+ %arrayidx8 = getelementptr inbounds i32, i32* %sum, i32 %add
+ %tmp = load i32, i32* %arrayidx8, align 4
+ %add9 = add nsw i32 %tmp, %i1.0
+ store i32 %add9, i32* %arrayidx8, align 4
+ br label %for.inc10
+
+for.inc10: ; preds = %S1
+ %inc11 = add nsw i32 %j.0, 1
+ br label %for.cond5
+
+for.end12: ; preds = %for.cond5
+ br label %for.inc13
+
+for.inc13: ; preds = %for.end12
+ %inc14 = add nsw i32 %i1.0, 1
+ br label %for.cond2
+
+for.end15: ; preds = %for.cond2
+ br label %for.cond17
+
+for.cond17: ; preds = %for.inc23, %for.end15
+ %i16.0 = phi i32 [ 0, %for.end15 ], [ %inc24, %for.inc23 ]
+ %exitcond = icmp ne i32 %i16.0, 1024
+ br i1 %exitcond, label %for.body19, label %for.end25
+
+for.body19: ; preds = %for.cond17
+ br label %S2
+
+S2: ; preds = %for.body19
+ %add20 = add nsw i32 %i16.0, 1
+ %arrayidx21 = getelementptr inbounds i32, i32* %sum, i32 %add20
+ %tmp4 = load i32, i32* %arrayidx21, align 4
+ %mul = mul nsw i32 %tmp4, 3
+ %arrayidx22 = getelementptr inbounds i32, i32* %sum, i32 %i16.0
+ store i32 %mul, i32* %arrayidx22, align 4
+ br label %for.inc23
+
+for.inc23: ; preds = %S2
+ %inc24 = add nsw i32 %i16.0, 1
+ br label %for.cond17
+
+for.end25: ; preds = %for.cond17
+ ret void
+}
Added: polly/trunk/test/DependenceInfo/reduction_privatization_deps_2.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_privatization_deps_2.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_privatization_deps_2.ll (added)
+++ polly/trunk/test/DependenceInfo/reduction_privatization_deps_2.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,86 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -polly-dependences -analyze < %s | FileCheck %s
+;
+; We have privatization dependences from a textually later statement to a
+; textually earlier one, but the dependences still go forward in time.
+;
+; CHECK: RAW dependences:
+; CHECK-DAG: Stmt_S3[i0] -> Stmt_S2[1 + i0, o1] : i0 <= 97 and i0 >= 0 and o1 <= 99 and o1 >= 0
+; CHECK-DAG: Stmt_S1[i0] -> Stmt_S3[i0] : i0 <= 98 and i0 >= 0
+; CHECK: WAR dependences:
+; CHECK: { }
+; CHECK: WAW dependences:
+; CHECK-DAG: Stmt_S3[i0] -> Stmt_S2[1 + i0, o1] : i0 <= 97 and i0 >= 0 and o1 <= 99 and o1 >= 0
+; CHECK-DAG: Stmt_S1[i0] -> Stmt_S3[i0] : i0 <= 98 and i0 >= 0
+; CHECK: Reduction dependences:
+; CHECK: { Stmt_S2[i0, i1] -> Stmt_S2[i0, 1 + i1] : i0 <= 98 and i0 >= 0 and i1 <= 98 and i1 >= 0 }
+;
+; void f(int *sum) {
+; int i, j;
+; for (i = 0; i < 99; i++) {
+; S1: sum[i + 1] += 42;
+; for (j = 0; j < 100; j++)
+; S2: sum[i] += i * j;
+; S3: sum[i + 1] += 7;
+; }
+; }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc10, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc11, %for.inc10 ]
+ %exitcond1 = icmp ne i32 %i.0, 99
+ br i1 %exitcond1, label %for.body, label %for.end12
+
+for.body: ; preds = %for.cond
+ br label %S1
+
+S1: ; preds = %for.body
+ %add = add nsw i32 %i.0, 1
+ %arrayidx = getelementptr inbounds i32, i32* %sum, i32 %add
+ %tmp = load i32, i32* %arrayidx, align 4
+ %add1 = add nsw i32 %tmp, 42
+ store i32 %add1, i32* %arrayidx, align 4
+ br label %for.cond2
+
+for.cond2: ; preds = %for.inc, %S1
+ %j.0 = phi i32 [ 0, %S1 ], [ %inc, %for.inc ]
+ %exitcond = icmp ne i32 %j.0, 100
+ br i1 %exitcond, label %for.body4, label %for.end
+
+for.body4: ; preds = %for.cond2
+ br label %S2
+
+S2: ; preds = %for.body4
+ %mul = mul nsw i32 %i.0, %j.0
+ %arrayidx5 = getelementptr inbounds i32, i32* %sum, i32 %i.0
+ %tmp2 = load i32, i32* %arrayidx5, align 4
+ %add6 = add nsw i32 %tmp2, %mul
+ store i32 %add6, i32* %arrayidx5, align 4
+ br label %for.inc
+
+for.inc: ; preds = %S2
+ %inc = add nsw i32 %j.0, 1
+ br label %for.cond2
+
+for.end: ; preds = %for.cond2
+ br label %S3
+
+S3: ; preds = %for.end
+ %add7 = add nsw i32 %i.0, 1
+ %arrayidx8 = getelementptr inbounds i32, i32* %sum, i32 %add7
+ %tmp3 = load i32, i32* %arrayidx8, align 4
+ %add9 = add nsw i32 %tmp3, 7
+ store i32 %add9, i32* %arrayidx8, align 4
+ br label %for.inc10
+
+for.inc10: ; preds = %S3
+ %inc11 = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end12: ; preds = %for.cond
+ ret void
+}
Added: polly/trunk/test/DependenceInfo/reduction_privatization_deps_3.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_privatization_deps_3.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_privatization_deps_3.ll (added)
+++ polly/trunk/test/DependenceInfo/reduction_privatization_deps_3.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,87 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -polly-dependences -analyze < %s | FileCheck %s
+;
+; CHECK: RAW dependences:
+; CHECK-DAG: Stmt_S2[i0, i1] -> Stmt_S3[o0] : o0 <= 1 and i1 <= 1 - i0 and o0 <= 1 + i0 - i1 and o0 >= 1 - i1
+; CHECK-DAG: Stmt_S3[i0] -> Stmt_S2[o0, 1 - i0] : i0 <= 1 and i0 >= 0 and o0 >= 1 + i0 and o0 <= 98
+; CHECK-DAG: Stmt_S1[i0] -> Stmt_S3[2 + i0] : i0 <= 96 and i0 >= 0
+; CHECK: WAR dependences:
+; CHECK: { }
+; CHECK: WAW dependences:
+; CHECK-DAG: Stmt_S2[i0, i1] -> Stmt_S3[o0] : o0 <= 1 and i1 <= 1 - i0 and o0 <= 1 + i0 - i1 and o0 >= 1 - i1
+; CHECK-DAG: Stmt_S3[i0] -> Stmt_S2[o0, 1 - i0] : i0 <= 1 and i0 >= 0 and o0 >= 1 + i0 and o0 <= 98
+; CHECK-DAG: Stmt_S1[i0] -> Stmt_S3[2 + i0] : i0 <= 96 and i0 >= 0
+; CHECK: Reduction dependences:
+; CHECK-DAG: Stmt_S2[i0, i1] -> Stmt_S2[1 + i0, i1] : i0 <= 97 and i0 >= 0 and i1 <= 98 - i0 and i1 >= 0 and i1 >= 2 - i0
+; CHECK-DAG: Stmt_S2[0, 0] -> Stmt_S2[1, 0]
+;
+; void f(int *sum) {
+; int i, j;
+; for (i = 0; i < 99; i++) {
+; S1: sum[i + 1] += 42;
+; for (j = i; j < 100; j++)
+; S2: sum[i - j] += i * j;
+; S3: sum[i - 1] += 7;
+; }
+; }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc10, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc11, %for.inc10 ]
+ %exitcond1 = icmp ne i32 %i.0, 99
+ br i1 %exitcond1, label %for.body, label %for.end12
+
+for.body: ; preds = %for.cond
+ br label %S1
+
+S1: ; preds = %for.body
+ %add = add nsw i32 %i.0, 1
+ %arrayidx = getelementptr inbounds i32, i32* %sum, i32 %add
+ %tmp = load i32, i32* %arrayidx, align 4
+ %add1 = add nsw i32 %tmp, 42
+ store i32 %add1, i32* %arrayidx, align 4
+ br label %for.cond2
+
+for.cond2: ; preds = %for.inc, %S1
+ %j.0 = phi i32 [ %i.0, %S1 ], [ %inc, %for.inc ]
+ %exitcond = icmp ne i32 %j.0, 100
+ br i1 %exitcond, label %for.body4, label %for.end
+
+for.body4: ; preds = %for.cond2
+ br label %S2
+
+S2: ; preds = %for.body4
+ %mul = mul nsw i32 %i.0, %j.0
+ %sub = sub nsw i32 %i.0, %j.0
+ %arrayidx5 = getelementptr inbounds i32, i32* %sum, i32 %sub
+ %tmp2 = load i32, i32* %arrayidx5, align 4
+ %add6 = add nsw i32 %tmp2, %mul
+ store i32 %add6, i32* %arrayidx5, align 4
+ br label %for.inc
+
+for.inc: ; preds = %S2
+ %inc = add nsw i32 %j.0, 1
+ br label %for.cond2
+
+for.end: ; preds = %for.cond2
+ br label %S3
+
+S3: ; preds = %for.end
+ %sub7 = add nsw i32 %i.0, -1
+ %arrayidx8 = getelementptr inbounds i32, i32* %sum, i32 %sub7
+ %tmp3 = load i32, i32* %arrayidx8, align 4
+ %add9 = add nsw i32 %tmp3, 7
+ store i32 %add9, i32* %arrayidx8, align 4
+ br label %for.inc10
+
+for.inc10: ; preds = %S3
+ %inc11 = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end12: ; preds = %for.cond
+ ret void
+}
Added: polly/trunk/test/DependenceInfo/reduction_privatization_deps_4.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_privatization_deps_4.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_privatization_deps_4.ll (added)
+++ polly/trunk/test/DependenceInfo/reduction_privatization_deps_4.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,84 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -polly-dependences -analyze < %s | FileCheck %s
+;
+; CHECK: RAW dependences:
+; CHECK-DAG: Stmt_S2[i0, i1] -> Stmt_S1[i1] : i0 >= 0 and i1 >= 1 + i0 and i1 <= 98
+; CHECK-DAG: Stmt_S1[i0] -> Stmt_S2[i0, i0] : i0 <= 98 and i0 >= 0
+; CHECK-DAG: Stmt_S2[i0, i0] -> Stmt_S3[i0] : i0 <= 98 and i0 >= 0
+; CHECK-DAG: Stmt_S3[i0] -> Stmt_S2[o0, i0] : i0 >= 0 and o0 >= 1 + i0 and o0 <= 98
+; CHECK: WAR dependences:
+; CHECK-DAG: { }
+; CHECK: WAW dependences:
+; CHECK-DAG: Stmt_S2[i0, i1] -> Stmt_S1[i1] : i0 >= 0 and i1 >= 1 + i0 and i1 <= 98
+; CHECK-DAG: Stmt_S1[i0] -> Stmt_S2[i0, i0] : i0 <= 98 and i0 >= 0
+; CHECK-DAG: Stmt_S2[i0, i0] -> Stmt_S3[i0] : i0 <= 98 and i0 >= 0
+; CHECK-DAG: Stmt_S3[i0] -> Stmt_S2[o0, i0] : i0 >= 0 and o0 >= 1 + i0 and o0 <= 98
+; CHECK: Reduction dependences:
+; CHECK-DAG: { Stmt_S2[i0, i1] -> Stmt_S2[1 + i0, i1] : (i0 >= 0 and i1 >= 2 + i0 and i1 <= 99) or (i0 <= 97 and i1 >= 0 and i1 <= -1 + i0) }
+;
+; void f(int *sum) {
+; for (int i = 0; i < 99; i++) {
+; S1: sum[i] += 42;
+; for (int j = 0; j < 100; j++)
+; S2: sum[j] += i * j;
+; S3: sum[i] += 7;
+; }
+; }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc8, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc9, %for.inc8 ]
+ %exitcond1 = icmp ne i32 %i.0, 99
+ br i1 %exitcond1, label %for.body, label %for.end10
+
+for.body: ; preds = %for.cond
+ br label %S1
+
+S1: ; preds = %for.body
+ %arrayidx = getelementptr inbounds i32, i32* %sum, i32 %i.0
+ %tmp = load i32, i32* %arrayidx, align 4
+ %add = add nsw i32 %tmp, 42
+ store i32 %add, i32* %arrayidx, align 4
+ br label %for.cond1
+
+for.cond1: ; preds = %for.inc, %S1
+ %j.0 = phi i32 [ 0, %S1 ], [ %inc, %for.inc ]
+ %exitcond = icmp ne i32 %j.0, 100
+ br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3: ; preds = %for.cond1
+ br label %S2
+
+S2: ; preds = %for.body3
+ %mul = mul nsw i32 %i.0, %j.0
+ %arrayidx4 = getelementptr inbounds i32, i32* %sum, i32 %j.0
+ %tmp2 = load i32, i32* %arrayidx4, align 4
+ %add5 = add nsw i32 %tmp2, %mul
+ store i32 %add5, i32* %arrayidx4, align 4
+ br label %for.inc
+
+for.inc: ; preds = %S2
+ %inc = add nsw i32 %j.0, 1
+ br label %for.cond1
+
+for.end: ; preds = %for.cond1
+ br label %S3
+
+S3: ; preds = %for.end
+ %arrayidx6 = getelementptr inbounds i32, i32* %sum, i32 %i.0
+ %tmp3 = load i32, i32* %arrayidx6, align 4
+ %add7 = add nsw i32 %tmp3, 7
+ store i32 %add7, i32* %arrayidx6, align 4
+ br label %for.inc8
+
+for.inc8: ; preds = %S3
+ %inc9 = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end10: ; preds = %for.cond
+ ret void
+}
Added: polly/trunk/test/DependenceInfo/reduction_privatization_deps_5.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_privatization_deps_5.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_privatization_deps_5.ll (added)
+++ polly/trunk/test/DependenceInfo/reduction_privatization_deps_5.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,88 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -polly-dependences -analyze < %s | FileCheck %s
+;
+; CHECK: RAW dependences:
+; CHECK-DAG: Stmt_S2[i0, 0] -> Stmt_S1[1 + i0, 0] : i0 <= 97 and i0 >= 0
+; CHECK-DAG: Stmt_S1[i0, 0] -> Stmt_S2[i0, 0] : i0 <= 98 and i0 >= 0
+; CHECK: WAR dependences:
+; CHECK-DAG: { }
+; CHECK: WAW dependences:
+; CHECK-DAG: Stmt_S2[i0, 0] -> Stmt_S1[1 + i0, 0] : i0 <= 97 and i0 >= 0
+; CHECK-DAG: Stmt_S1[i0, 0] -> Stmt_S2[i0, 0] : i0 <= 98 and i0 >= 0
+; CHECK: Reduction dependences:
+; CHECK-DAG: { Stmt_S2[i0, i1] -> Stmt_S2[1 + i0, i1] : i0 <= 97 and i0 >= 0 and i1 <= 99 and i1 >= 1 }
+;
+; void f(int *sum) {
+; for (int i = 0; i < 99; i++) {
+; for (int j = 0; j < 1; j++)
+; S1: sum[j] += 42;
+; for (int j = 0; j < 100; j++)
+; S2: sum[j] += i * j;
+; }
+; }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc12, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc13, %for.inc12 ]
+ %exitcond2 = icmp ne i32 %i.0, 99
+ br i1 %exitcond2, label %for.body, label %for.end14
+
+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, 1
+ br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3: ; preds = %for.cond1
+ br label %S1
+
+S1: ; preds = %for.body3
+ %arrayidx = getelementptr inbounds i32, i32* %sum, i32 %j.0
+ %tmp = load i32, i32* %arrayidx, align 4
+ %add = add nsw i32 %tmp, 42
+ store i32 %add, i32* %arrayidx, align 4
+ br label %for.inc
+
+for.inc: ; preds = %S1
+ %inc = add nsw i32 %j.0, 1
+ br label %for.cond1
+
+for.end: ; preds = %for.cond1
+ br label %for.cond4
+
+for.cond4: ; preds = %for.inc9, %for.end
+ %j.1 = phi i32 [ 0, %for.end ], [ %inc10, %for.inc9 ]
+ %exitcond1 = icmp ne i32 %j.1, 100
+ br i1 %exitcond1, label %for.body6, label %for.end11
+
+for.body6: ; preds = %for.cond4
+ br label %S2
+
+S2: ; preds = %for.body6
+ %mul = mul nsw i32 %i.0, %j.1
+ %arrayidx7 = getelementptr inbounds i32, i32* %sum, i32 %j.1
+ %tmp3 = load i32, i32* %arrayidx7, align 4
+ %add8 = add nsw i32 %tmp3, %mul
+ store i32 %add8, i32* %arrayidx7, align 4
+ br label %for.inc9
+
+for.inc9: ; preds = %S2
+ %inc10 = add nsw i32 %j.1, 1
+ br label %for.cond4
+
+for.end11: ; preds = %for.cond4
+ br label %for.inc12
+
+for.inc12: ; preds = %for.end11
+ %inc13 = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end14: ; preds = %for.cond
+ ret void
+}
Added: polly/trunk/test/DependenceInfo/reduction_simple_iv.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_simple_iv.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_simple_iv.ll (added)
+++ polly/trunk/test/DependenceInfo/reduction_simple_iv.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,40 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -polly-dependences -analyze < %s | FileCheck %s
+;
+; CHECK: RAW dependences:
+; CHECK: { }
+; CHECK: WAR dependences:
+; CHECK: { }
+; CHECK: WAW dependences:
+; CHECK: { }
+; CHECK: Reduction dependences:
+; CHECK: { Stmt_for_cond[i0] -> Stmt_for_cond[1 + i0] : i0 <= 99 and i0 >= 0 }
+;
+; void f(int* sum) {
+; for (int i = 0; i <= 100; i++)
+; sum += i * 3;
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum) {
+entry:
+ br label %entry.split1
+
+entry.split1: ; preds = %entry
+ br label %entry.split
+
+entry.split: ; preds = %entry.split1
+ br label %for.cond
+
+for.cond: ; preds = %for.cond, %entry.split
+ %i1.0 = phi i32 [ 0, %entry.split ], [ %inc, %for.cond ]
+ %sum.reload = load i32, i32* %sum
+ %mul = mul nsw i32 %i1.0, 3
+ %add = add nsw i32 %sum.reload, %mul
+ %inc = add nsw i32 %i1.0, 1
+ store i32 %add, i32* %sum
+ %cmp = icmp slt i32 %i1.0, 100
+ br i1 %cmp, label %for.cond, label %for.end
+
+for.end: ; preds = %for.cond
+ ret void
+}
Added: polly/trunk/test/DependenceInfo/reduction_simple_iv_debug_wrapped_dependences.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_simple_iv_debug_wrapped_dependences.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_simple_iv_debug_wrapped_dependences.ll (added)
+++ polly/trunk/test/DependenceInfo/reduction_simple_iv_debug_wrapped_dependences.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,84 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -polly-dependences -analyze -debug-only=polly-dependence 2>&1 < %s | FileCheck %s
+;
+; REQUIRES: asserts
+;
+; CHECK: Read: { [Stmt_for_cond[i0] -> MemRef_sum[0]] -> MemRef_sum[0] : i0 >= 0 and i0 <= 100 }
+; CHECK: Write: { [Stmt_for_cond[i0] -> MemRef_sum[0]] -> MemRef_sum[0] : i0 >= 0 and i0 <= 100 }
+; CHECK: Schedule: {
+; CHECK-DAG: [Stmt_for_cond[i0] -> MemRef_sum[0]] -> [i0] : i0 <= 100 and i0 >= 0
+; CHECK-DAG: Stmt_for_cond[i0] -> [i0]
+; CHECK: }
+; CHECK: Wrapped Dependences:
+; CHECK: RAW dependences:
+; CHECK: { [Stmt_for_cond[i0] -> MemRef_sum[0]] -> [Stmt_for_cond[1 + i0] -> MemRef_sum[0]] : i0 <= 99 and i0 >= 0 }
+; CHECK: WAR dependences:
+; CHECK: { }
+; CHECK: WAW dependences:
+; CHECK: { [Stmt_for_cond[i0] -> MemRef_sum[0]] -> [Stmt_for_cond[1 + i0] -> MemRef_sum[0]] : i0 <= 99 and i0 >= 0 }
+; CHECK: Reduction dependences:
+; CHECK: n/a
+; CHECK: Final Wrapped Dependences:
+; CHECK: RAW dependences:
+; CHECK: { }
+; CHECK: WAR dependences:
+; CHECK: { }
+; CHECK: WAW dependences:
+; CHECK: { }
+; CHECK: Reduction dependences:
+; CHECK: { [Stmt_for_cond[i0] -> MemRef_sum[0]] -> [Stmt_for_cond[1 + i0] -> MemRef_sum[0]] : i0 <= 99 and i0 >= 0 }
+; CHECK: Zipped Dependences:
+; CHECK: RAW dependences:
+; CHECK: { }
+; CHECK: WAR dependences:
+; CHECK: { }
+; CHECK: WAW dependences:
+; CHECK: { }
+; CHECK: Reduction dependences:
+; CHECK: { [Stmt_for_cond[i0] -> Stmt_for_cond[1 + i0]] -> [MemRef_sum[0] -> MemRef_sum[0]] : i0 <= 99 and i0 >= 0 }
+; CHECK: Unwrapped Dependences:
+; CHECK: RAW dependences:
+; CHECK: { }
+; CHECK: WAR dependences:
+; CHECK: { }
+; CHECK: WAW dependences:
+; CHECK: { }
+; CHECK: Reduction dependences:
+; CHECK: { Stmt_for_cond[i0] -> Stmt_for_cond[1 + i0] : i0 <= 99 and i0 >= 0 }
+; CHECK: RAW dependences:
+; CHECK: { }
+; CHECK: WAR dependences:
+; CHECK: { }
+; CHECK: WAW dependences:
+; CHECK: { }
+; CHECK: Reduction dependences:
+; CHECK: { Stmt_for_cond[i0] -> Stmt_for_cond[1 + i0] : i0 <= 99 and i0 >= 0 }
+;
+; void f(int* sum) {
+; for (int i = 0; i <= 100; i++)
+; sum += i * 3;
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum) {
+entry:
+ br label %entry.split1
+
+entry.split1: ; preds = %entry
+ br label %entry.split
+
+entry.split: ; preds = %entry.split1
+ br label %for.cond
+
+for.cond: ; preds = %for.cond, %entry.split
+ %i1.0 = phi i32 [ 0, %entry.split ], [ %inc, %for.cond ]
+ %sum.reload = load i32, i32* %sum
+ %mul = mul nsw i32 %i1.0, 3
+ %add = add nsw i32 %sum.reload, %mul
+ %inc = add nsw i32 %i1.0, 1
+ store i32 %add, i32* %sum
+ %cmp = icmp slt i32 %i1.0, 100
+ br i1 %cmp, label %for.cond, label %for.end
+
+for.end: ; preds = %for.cond
+ ret void
+}
Added: polly/trunk/test/DependenceInfo/reduction_simple_privatization_deps_2.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_simple_privatization_deps_2.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_simple_privatization_deps_2.ll (added)
+++ polly/trunk/test/DependenceInfo/reduction_simple_privatization_deps_2.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,79 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -polly-dependences -analyze < %s | FileCheck %s
+;
+; CHECK: RAW dependences:
+; CHECK-DAG: Stmt_S1[i0, i1] -> Stmt_S2[i0] : i0 <= 99 and i0 >= 0 and i1 <= 99 and i1 >= 0
+; CHECK-DAG: Stmt_S0[i0] -> Stmt_S1[i0, o1] : i0 <= 99 and i0 >= 0 and o1 <= 99 and o1 >= 0
+; CHECK-DAG: Stmt_S2[i0] -> Stmt_S0[1 + i0] : i0 <= 98 and i0 >= 0
+; CHECK: WAR dependences:
+; CHECK-DAG: { }
+; CHECK: WAW dependences:
+; CHECK-DAG: Stmt_S1[i0, i1] -> Stmt_S2[i0] : i0 <= 99 and i0 >= 0 and i1 <= 99 and i1 >= 0
+; CHECK-DAG: Stmt_S0[i0] -> Stmt_S1[i0, o1] : i0 <= 99 and i0 >= 0 and o1 <= 99 and o1 >= 0
+; CHECK-DAG: Stmt_S2[i0] -> Stmt_S0[1 + i0] : i0 <= 98 and i0 >= 0
+; CHECK: Reduction dependences:
+; CHECK-DAG: Stmt_S1[i0, i1] -> Stmt_S1[i0, 1 + i1] : i0 <= 99 and i0 >= 0 and i1 <= 98 and i1 >= 0
+;
+; void f(int *sum) {
+; for (int i = 0; i < 100; i++) {
+; S0: *sum *= 42;
+; for (int j = 0; j < 100; j++)
+; S1: *sum += i * j;
+; S2: *sum *= 7;
+; }
+; }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc6, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc7, %for.inc6 ]
+ %exitcond1 = icmp ne i32 %i.0, 100
+ br i1 %exitcond1, label %for.body, label %for.end8
+
+for.body: ; preds = %for.cond
+ br label %S0
+
+S0: ; preds = %for.body
+ %tmp = load i32, i32* %sum, align 4
+ %mul = mul nsw i32 %tmp, 42
+ store i32 %mul, i32* %sum, align 4
+ br label %for.cond1
+
+for.cond1: ; preds = %for.inc, %S0
+ %j.0 = phi i32 [ 0, %S0 ], [ %inc, %for.inc ]
+ %exitcond = icmp ne i32 %j.0, 100
+ br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3: ; preds = %for.cond1
+ br label %S1
+
+S1: ; preds = %for.body3
+ %mul4 = mul nsw i32 %i.0, %j.0
+ %tmp2 = load i32, i32* %sum, align 4
+ %add = add nsw i32 %tmp2, %mul4
+ store i32 %add, i32* %sum, align 4
+ br label %for.inc
+
+for.inc: ; preds = %S1
+ %inc = add nsw i32 %j.0, 1
+ br label %for.cond1
+
+for.end: ; preds = %for.cond1
+ br label %S2
+
+S2: ; preds = %for.end
+ %tmp3 = load i32, i32* %sum, align 4
+ %mul5 = mul nsw i32 %tmp3, 7
+ store i32 %mul5, i32* %sum, align 4
+ br label %for.inc6
+
+for.inc6: ; preds = %S2
+ %inc7 = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end8: ; preds = %for.cond
+ ret void
+}
Added: polly/trunk/test/DependenceInfo/reduction_simple_privatization_deps_w_parameter.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_simple_privatization_deps_w_parameter.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_simple_privatization_deps_w_parameter.ll (added)
+++ polly/trunk/test/DependenceInfo/reduction_simple_privatization_deps_w_parameter.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,59 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -polly-dependences -analyze < %s | FileCheck %s
+;
+; CHECK: RAW dependences:
+; CHECK-DAG: Stmt_S0[] -> Stmt_S1[o0] : N >= 11 and o0 <= 1023 and o0 >= 0
+; CHECK-DAG: Stmt_S1[i0] -> Stmt_S2[] : N >= 11 and i0 <= 1023 and i0 >= 0
+; CHECK: WAR dependences:
+; CHECK: [N] -> { }
+; CHECK: WAW dependences:
+; CHECK-DAG: Stmt_S0[] -> Stmt_S1[o0] : N >= 11 and o0 <= 1023 and o0 >= 0
+; CHECK-DAG: Stmt_S1[i0] -> Stmt_S2[] : N >= 11 and i0 <= 1023 and i0 >= 0
+; CHECK: Reduction dependences:
+; CHECK: Stmt_S1[i0] -> Stmt_S1[1 + i0] : N >= 11 and i0 <= 1022 and i0 >= 0
+;
+; void f(int *sum, int N) {
+; if (N >= 10) {
+; S0: *sum = 0;
+; for (int i = 0; i < 1024; i++)
+; S1: *sum += i;
+; S2: *sum = *sum * 3;
+; }
+; }
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %sum, i32 %N) {
+entry:
+ br label %entry.1
+
+entry.1:
+ %excond = icmp sgt i32 %N, 10
+ br i1 %excond, label %S0, label %f.end
+
+S0:
+ store i32 0, i32* %sum, align 4
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %S0
+ %i.0 = phi i32 [ 0, %S0 ], [ %inc, %for.inc ]
+ %exitcond = icmp ne i32 %i.0, 1024
+ br i1 %exitcond, label %S1, label %S2
+
+S1: ; preds = %for.cond
+ %tmp = load i32, i32* %sum, align 4
+ %add = add nsw i32 %tmp, %i.0
+ store i32 %add, i32* %sum, align 4
+ br label %for.inc
+
+for.inc: ; preds = %S1
+ %inc = add nsw i32 %i.0, 1
+ br label %for.cond
+
+S2: ; preds = %for.cond
+ %tmp1 = load i32, i32* %sum, align 4
+ %mul = mul nsw i32 %tmp1, 3
+ store i32 %mul, i32* %sum, align 4
+ br label %f.end
+
+f.end:
+ ret void
+}
Added: polly/trunk/test/DependenceInfo/reduction_two_reductions_different_rloops.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/reduction_two_reductions_different_rloops.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/reduction_two_reductions_different_rloops.ll (added)
+++ polly/trunk/test/DependenceInfo/reduction_two_reductions_different_rloops.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,72 @@
+; RUN: opt %loadPolly -polly-detect-unprofitable -basicaa -polly-dependences -analyze < %s | FileCheck %s
+;
+; CHECK: RAW dependences:
+; CHECK: { }
+; CHECK: WAR dependences:
+; CHECK: { }
+; CHECK: WAW dependences:
+; CHECK: { }
+; CHECK: Reduction dependences:
+; CHECK-DAG: Stmt_for_body3[i0, i1] -> Stmt_for_body3[o0, 1 + i0 + i1 - o0] : o0 <= 1 + i0 and o0 >= i0 and o0 <= 1023 and i0 >= 0 and i1 >= 0 and o0 >= -1022 + i0 + i1
+;
+; void f(int *restrict A, int *restrict B, int *restrict Values) {
+; for (int i = 0; i < 1024; i++) {
+; for (int j = 0; j < 1024; j++) {
+; A[i] += Values[i + j - 1];
+; B[j] += Values[i + j + 42];
+; }
+; }
+; }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* noalias %A, i32* noalias %B, i32* noalias %Values) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc11, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc12, %for.inc11 ]
+ %exitcond1 = icmp ne i32 %i.0, 1024
+ br i1 %exitcond1, label %for.body, label %for.end13
+
+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, 1024
+ br i1 %exitcond, label %for.body3, label %for.end
+
+for.body3: ; preds = %for.cond1
+ %add = add nsw i32 %i.0, %j.0
+ %sub = add nsw i32 %add, -1
+ %arrayidx = getelementptr inbounds i32, i32* %Values, i32 %sub
+ %tmp = load i32, i32* %arrayidx, align 4
+ %arrayidx4 = getelementptr inbounds i32, i32* %A, i32 %i.0
+ %tmp2 = load i32, i32* %arrayidx4, align 4
+ %add5 = add nsw i32 %tmp2, %tmp
+ store i32 %add5, i32* %arrayidx4, align 4
+ %add6 = add nsw i32 %i.0, %j.0
+ %add7 = add nsw i32 %add6, 42
+ %arrayidx8 = getelementptr inbounds i32, i32* %Values, i32 %add7
+ %tmp3 = load i32, i32* %arrayidx8, align 4
+ %arrayidx9 = getelementptr inbounds i32, i32* %B, i32 %j.0
+ %tmp4 = load i32, i32* %arrayidx9, align 4
+ %add10 = add nsw i32 %tmp4, %tmp3
+ store i32 %add10, i32* %arrayidx9, 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.inc11
+
+for.inc11: ; preds = %for.end
+ %inc12 = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end13: ; preds = %for.cond
+ ret void
+}
Added: polly/trunk/test/DependenceInfo/sequential_loops.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DependenceInfo/sequential_loops.ll?rev=231308&view=auto
==============================================================================
--- polly/trunk/test/DependenceInfo/sequential_loops.ll (added)
+++ polly/trunk/test/DependenceInfo/sequential_loops.ll Wed Mar 4 16:43:40 2015
@@ -0,0 +1,296 @@
+; RUN: opt -S %loadPolly -polly-detect-unprofitable -basicaa -polly-dependences -analyze -polly-dependences-analysis-type=value-based < %s | FileCheck %s -check-prefix=VALUE
+; RUN: opt -S %loadPolly -polly-detect-unprofitable -basicaa -polly-dependences -analyze -polly-dependences-analysis-type=memory-based < %s | FileCheck %s -check-prefix=MEMORY
+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"
+target triple = "x86_64-pc-linux-gnu"
+
+; for(i = 0; i < 100; i++ )
+; S1: A[i] = 2;
+;
+; for (i = 0; i < 10; i++ )
+; S2: A[i] = 5;
+;
+; for (i = 0; i < 200; i++ )
+; S3: A[i] = 5;
+
+define void @sequential_writes() {
+entry:
+ %A = alloca [200 x i32]
+ br label %S1
+
+S1:
+ %indvar.1 = phi i64 [ 0, %entry ], [ %indvar.next.1, %S1 ]
+ %arrayidx.1 = getelementptr [200 x i32], [200 x i32]* %A, i64 0, i64 %indvar.1
+ store i32 2, i32* %arrayidx.1
+ %indvar.next.1 = add i64 %indvar.1, 1
+ %exitcond.1 = icmp ne i64 %indvar.next.1, 100
+ br i1 %exitcond.1, label %S1, label %exit.1
+
+exit.1:
+ br label %S2
+
+S2:
+ %indvar.2 = phi i64 [ 0, %exit.1 ], [ %indvar.next.2, %S2 ]
+ %arrayidx.2 = getelementptr [200 x i32], [200 x i32]* %A, i64 0, i64 %indvar.2
+ store i32 5, i32* %arrayidx.2
+ %indvar.next.2 = add i64 %indvar.2, 1
+ %exitcond.2 = icmp ne i64 %indvar.next.2, 10
+ br i1 %exitcond.2, label %S2, label %exit.2
+
+exit.2:
+ br label %S3
+
+S3:
+ %indvar.3 = phi i64 [ 0, %exit.2 ], [ %indvar.next.3, %S3 ]
+ %arrayidx.3 = getelementptr [200 x i32], [200 x i32]* %A, i64 0, i64 %indvar.3
+ store i32 7, i32* %arrayidx.3
+ %indvar.next.3 = add i64 %indvar.3, 1
+ %exitcond.3 = icmp ne i64 %indvar.next.3, 200
+ br i1 %exitcond.3, label %S3 , label %exit.3
+
+exit.3:
+ ret void
+}
+
+; VALUE: region: 'S1 => exit.3' in function 'sequential_writes':
+; VALUE: RAW dependences:
+; VALUE: { }
+; VALUE: WAR dependences:
+; VALUE: { }
+; VALUE: WAW dependences:
+; VALUE: {
+; VALUE: Stmt_S1[i0] -> Stmt_S2[i0] : i0 >= 0 and i0 <= 9;
+; VALUE: Stmt_S2[i0] -> Stmt_S3[i0] : i0 >= 0 and i0 <= 9;
+; VALUE: Stmt_S1[i0] -> Stmt_S3[i0] : i0 >= 10 and i0 <= 99
+; VALUE: }
+
+; MEMORY: region: 'S1 => exit.3' in function 'sequential_writes':
+; MEMORY: RAW dependences:
+; MEMORY: { }
+; MEMORY: WAR dependences:
+; MEMORY: { }
+; MEMORY: WAW dependences:
+; MEMORY: {
+; MEMORY: Stmt_S1[i0] -> Stmt_S2[i0] : i0 <= 9 and i0 >= 0;
+; MEMORY: Stmt_S2[i0] -> Stmt_S3[i0] : i0 <= 9 and i0 >= 0;
+; MEMORY: Stmt_S1[i0] -> Stmt_S3[i0] : i0 <= 99 and i0 >= 0
+; MEMORY: }
+
+; for(i = 0; i < 100; i++ )
+; S1: A[i] = 2;
+;
+; for (i = 0; i < 10; i++ )
+; S2: A[i] = 5;
+;
+; for (i = 0; i < 200; i++ )
+; S3: B[i] = A[i];
+
+define void @read_after_writes() {
+entry:
+ %A = alloca [200 x i32]
+ %B = alloca [200 x i32]
+ br label %S1
+
+S1:
+ %indvar.1 = phi i64 [ 0, %entry ], [ %indvar.next.1, %S1 ]
+ %arrayidx.1 = getelementptr [200 x i32], [200 x i32]* %A, i64 0, i64 %indvar.1
+ store i32 2, i32* %arrayidx.1
+ %indvar.next.1 = add i64 %indvar.1, 1
+ %exitcond.1 = icmp ne i64 %indvar.next.1, 100
+ br i1 %exitcond.1, label %S1, label %exit.1
+
+exit.1:
+ br label %S2
+
+S2:
+ %indvar.2 = phi i64 [ 0, %exit.1 ], [ %indvar.next.2, %S2 ]
+ %arrayidx.2 = getelementptr [200 x i32], [200 x i32]* %A, i64 0, i64 %indvar.2
+ store i32 5, i32* %arrayidx.2
+ %indvar.next.2 = add i64 %indvar.2, 1
+ %exitcond.2 = icmp ne i64 %indvar.next.2, 10
+ br i1 %exitcond.2, label %S2, label %exit.2
+
+exit.2:
+ br label %S3
+
+S3:
+ %indvar.3 = phi i64 [ 0, %exit.2 ], [ %indvar.next.3, %S3 ]
+ %arrayidx.3.a = getelementptr [200 x i32], [200 x i32]* %A, i64 0, i64 %indvar.3
+ %arrayidx.3.b = getelementptr [200 x i32], [200 x i32]* %B, i64 0, i64 %indvar.3
+ %val = load i32, i32* %arrayidx.3.a
+ store i32 %val, i32* %arrayidx.3.b
+ %indvar.next.3 = add i64 %indvar.3, 1
+ %exitcond.3 = icmp ne i64 %indvar.next.3, 200
+ br i1 %exitcond.3, label %S3 , label %exit.3
+
+exit.3:
+ ret void
+}
+
+; VALUE: region: 'S1 => exit.3' in function 'read_after_writes':
+; VALUE: RAW dependences:
+; VALUE: {
+; VALUE: Stmt_S2[i0] -> Stmt_S3[i0] : i0 >= 0 and i0 <= 9;
+; VALUE: Stmt_S1[i0] -> Stmt_S3[i0] : i0 >= 10 and i0 <= 99
+; VALUE: }
+; VALUE: WAR dependences:
+; VALUE: { }
+; VALUE: WAW dependences:
+; VALUE: {
+; VALUE: Stmt_S1[i0] -> Stmt_S2[i0] : i0 >= 0 and i0 <= 9
+; VALUE: }
+
+; MEMORY: region: 'S1 => exit.3' in function 'read_after_writes':
+; MEMORY: RAW dependences:
+; MEMORY: {
+; MEMORY: Stmt_S2[i0] -> Stmt_S3[i0] : i0 <= 9 and i0 >= 0;
+; MEMORY: Stmt_S1[i0] -> Stmt_S3[i0] : i0 <= 99 and i0 >= 0
+; MEMORY: }
+; MEMORY: WAR dependences:
+; MEMORY: { }
+; MEMORY: WAW dependences:
+; MEMORY: {
+; MEMORY: Stmt_S1[i0] -> Stmt_S2[i0] : i0 <= 9 and i0 >= 0
+; MEMORY: }
+
+; for(i = 0; i < 100; i++ )
+; S1: B[i] = A[i];
+;
+; for (i = 0; i < 10; i++ )
+; S2: A[i] = 5;
+;
+; for (i = 0; i < 200; i++ )
+; S3: A[i] = 10;
+
+define void @write_after_read() {
+entry:
+ %A = alloca [200 x i32]
+ %B = alloca [200 x i32]
+ br label %S1
+
+S1:
+ %indvar.1 = phi i64 [ 0, %entry ], [ %indvar.next.1, %S1 ]
+ %arrayidx.1.a = getelementptr [200 x i32], [200 x i32]* %A, i64 0, i64 %indvar.1
+ %arrayidx.1.b = getelementptr [200 x i32], [200 x i32]* %B, i64 0, i64 %indvar.1
+ %val = load i32, i32* %arrayidx.1.a
+ store i32 %val, i32* %arrayidx.1.b
+ %indvar.next.1 = add i64 %indvar.1, 1
+ %exitcond.1 = icmp ne i64 %indvar.next.1, 100
+ br i1 %exitcond.1, label %S1, label %exit.1
+
+exit.1:
+ br label %S2
+
+S2:
+ %indvar.2 = phi i64 [ 0, %exit.1 ], [ %indvar.next.2, %S2 ]
+ %arrayidx.2 = getelementptr [200 x i32], [200 x i32]* %A, i64 0, i64 %indvar.2
+ store i32 5, i32* %arrayidx.2
+ %indvar.next.2 = add i64 %indvar.2, 1
+ %exitcond.2 = icmp ne i64 %indvar.next.2, 10
+ br i1 %exitcond.2, label %S2, label %exit.2
+
+exit.2:
+ br label %S3
+
+S3:
+ %indvar.3 = phi i64 [ 0, %exit.2 ], [ %indvar.next.3, %S3 ]
+ %arrayidx.3 = getelementptr [200 x i32], [200 x i32]* %A, i64 0, i64 %indvar.3
+ store i32 10, i32* %arrayidx.3
+ %indvar.next.3 = add i64 %indvar.3, 1
+ %exitcond.3 = icmp ne i64 %indvar.next.3, 200
+ br i1 %exitcond.3, label %S3 , label %exit.3
+
+exit.3:
+ ret void
+}
+
+; VALUE: region: 'S1 => exit.3' in function 'write_after_read':
+; VALUE: RAW dependences:
+; VALUE: {
+; VALUE: }
+; VALUE: WAR dependences:
+; VALUE: {
+; VALUE: Stmt_S1[i0] -> Stmt_S2[i0] : i0 <= 9 and i0 >= 0;
+; VALUE: Stmt_S1[i0] -> Stmt_S3[i0] : i0 <= 99 and i0 >= 10
+; VALUE: }
+; VALUE: WAW dependences:
+; VALUE: {
+; VALUE: Stmt_S2[i0] -> Stmt_S3[i0] : i0 >= 0 and i0 <= 9
+; VALUE: }
+
+; MEMORY: region: 'S1 => exit.3' in function 'write_after_read':
+; MEMORY: RAW dependences:
+; MEMORY: {
+; MEMORY: }
+; MEMORY: WAR dependences:
+; MEMORY: {
+; MEMORY: Stmt_S1[i0] -> Stmt_S2[i0] : i0 <= 9 and i0 >= 0;
+; MEMORY: Stmt_S1[i0] -> Stmt_S3[i0] : i0 <= 99 and i0 >= 0
+; MEMORY: }
+; MEMORY: WAW dependences:
+; MEMORY: {
+; MEMORY: Stmt_S2[i0] -> Stmt_S3[i0] : i0 <= 9 and i0 >= 0
+; MEMORY: }
+
+; for(i = 0; i < 100; i++ )
+; S1: A[i] = 10
+;
+; for(i = 0; i < 100; i++ )
+; S2: B[i] = A[i + p];
+
+define void @parametric_offset(i64 %p) {
+entry:
+ %A = alloca [200 x i32]
+ %B = alloca [200 x i32]
+ br label %S1
+
+S1:
+ %indvar.1 = phi i64 [ 0, %entry ], [ %indvar.next.1, %S1 ]
+ %arrayidx.1 = getelementptr [200 x i32], [200 x i32]* %A, i64 0, i64 %indvar.1
+ store i32 10, i32* %arrayidx.1
+ %indvar.next.1 = add i64 %indvar.1, 1
+ %exitcond.1 = icmp ne i64 %indvar.next.1, 100
+ br i1 %exitcond.1, label %S1, label %exit.1
+
+exit.1:
+ br label %S2
+
+S2:
+ %indvar.2 = phi i64 [ 0, %exit.1 ], [ %indvar.next.2, %S2 ]
+ %sum = add i64 %indvar.2, %p
+ %arrayidx.2.a = getelementptr [200 x i32], [200 x i32]* %A, i64 0, i64 %sum
+ %arrayidx.2.b = getelementptr [200 x i32], [200 x i32]* %B, i64 0, i64 %indvar.2
+ %val = load i32, i32* %arrayidx.2.a
+ store i32 %val, i32* %arrayidx.2.b
+ %indvar.next.2 = add i64 %indvar.2, 1
+ %exitcond.2 = icmp ne i64 %indvar.next.2, 10
+ br i1 %exitcond.2, label %S2, label %exit.2
+
+exit.2:
+ ret void
+}
+
+; VALUE: region: 'S1 => exit.2' in function 'parametric_offset':
+; VALUE: RAW dependences:
+; VALUE: [p] -> {
+; VALUE: Stmt_S1[i0] -> Stmt_S2[-p + i0] :
+; VALUE: p <= 190 and i0 >= p and i0 <= 9 + p and i0 >= 0 and i0 <= 99
+; VALUE: }
+; VALUE: WAR dependences:
+; VALUE: [p] -> {
+; VALUE: }
+; VALUE: WAW dependences:
+; VALUE: [p] -> {
+; VALUE: }
+
+; MEMORY: region: 'S1 => exit.2' in function 'parametric_offset':
+; MEMORY: RAW dependences:
+; MEMORY: [p] -> {
+; MEMORY: Stmt_S1[i0] -> Stmt_S2[-p + i0] :
+; MEMORY: i0 >= p and i0 <= 99 and i0 >= 0 and i0 <= 9 + p
+; MEMORY: }
+; MEMORY: WAR dependences:
+; MEMORY: [p] -> {
+; MEMORY: }
+; MEMORY: WAW dependences:
+; MEMORY: [p] -> {
+; MEMORY: }
More information about the llvm-commits
mailing list