[polly] r211114 - Subject: [PATCH-v5] Detect and mark reduction like statements
Johannes Doerfert
jdoerfert at codeaurora.org
Tue Jun 17 10:31:37 PDT 2014
Author: jdoerfert
Date: Tue Jun 17 12:31:36 2014
New Revision: 211114
URL: http://llvm.org/viewvc/llvm-project?rev=211114&view=rev
Log:
Subject: [PATCH-v5] Detect and mark reduction like statements
+ Flag to indicate reduction like statements
+ Command line option to (dis)allow multiplicative reduction opcodes
+ Two simple positive test cases, one fp test case w and w/o fast math
+ One "negative" test case (only reduction like but no reduction)
Modified:
polly/trunk/include/polly/ScopInfo.h
polly/trunk/lib/Analysis/ScopInfo.cpp
Modified: polly/trunk/include/polly/ScopInfo.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/ScopInfo.h?rev=211114&r1=211113&r2=211114&view=diff
==============================================================================
--- polly/trunk/include/polly/ScopInfo.h (original)
+++ polly/trunk/include/polly/ScopInfo.h Tue Jun 17 12:31:36 2014
@@ -270,6 +270,31 @@ class ScopStmt {
MemoryAccessVec MemAccs;
std::map<const Instruction *, MemoryAccess *> InstructionToAccess;
+ /// @brief Flag to indicate reduction like statements.
+ ///
+ /// A statement is reduction like if it contains exactly one load and one
+ /// store both accessing the same memory location (use the same LLVM-IR value
+ /// as pointer reference). Furthermore, between the load and the store there
+ /// is exactly one binary operator which is known to be associative and
+ /// commutative.
+ ///
+ /// TODO:
+ ///
+ /// We can later lift the constraint that the same LLVM-IR value defines the
+ /// memory location to handle scops such as the following:
+ ///
+ /// for i
+ /// for j
+ /// sum[i+j] = sum[i] + 3;
+ ///
+ /// Here not all iterations access the same memory location, but iterations
+ /// for which j = 0 holds do. After lifing the equality check in ScopInfo,
+ /// subsequent transformations do not only need check if a statement is
+ /// reduction like, but they also need to verify that that the reduction
+ /// property is only exploited for statement instances that load from and
+ /// store to the same data location. Doing so at dependence analysis time
+ /// could allow us to handle the above example.
+ bool IsReductionLike = false;
//@}
/// The BasicBlock represented by this statement.
@@ -294,6 +319,7 @@ class ScopStmt {
__isl_give isl_set *buildDomain(TempScop &tempScop, const Region &CurRegion);
void buildScattering(SmallVectorImpl<unsigned> &Scatter);
void buildAccesses(TempScop &tempScop, const Region &CurRegion);
+ void checkForReduction();
//@}
/// Create the ScopStmt from a BasicBlock.
@@ -305,6 +331,10 @@ class ScopStmt {
public:
~ScopStmt();
+
+ /// @brief Return true iff this statement is a reduction like statement
+ bool isReductionLike() const { return IsReductionLike; }
+
/// @brief Get an isl_ctx pointer.
isl_ctx *getIslCtx() const;
Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=211114&r1=211113&r2=211114&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Tue Jun 17 12:31:36 2014
@@ -20,6 +20,7 @@
#include "polly/CodeGen/BlockGenerators.h"
#include "polly/LinkAllPasses.h"
#include "polly/ScopInfo.h"
+#include "polly/Options.h"
#include "polly/Support/GICHelper.h"
#include "polly/Support/SCEVValidator.h"
#include "polly/Support/ScopHelper.h"
@@ -30,7 +31,6 @@
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/RegionIterator.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "isl/constraint.h"
@@ -55,6 +55,15 @@ using namespace polly;
STATISTIC(ScopFound, "Number of valid Scops");
STATISTIC(RichScopFound, "Number of Scops containing a loop");
+// Multiplicative reductions can be disabled seperately as these kind of
+// operations can overflow easily. Additive reductions and bit operations
+// are in contrast pretty stable.
+static cl::opt<bool>
+DisableMultiplicativeReductions("polly-disable-multiplicative-reductions",
+ cl::desc("Disable multiplicative reductions"),
+ cl::Hidden, cl::ZeroOrMore, cl::init(false),
+ cl::cat(PollyCategory));
+
/// Translate a 'const SCEV *' expression in an isl_pw_aff.
struct SCEVAffinator : public SCEVVisitor<SCEVAffinator, isl_pw_aff *> {
public:
@@ -696,6 +705,44 @@ ScopStmt::ScopStmt(Scop &parent, TempSco
Domain = buildDomain(tempScop, CurRegion);
buildScattering(Scatter);
buildAccesses(tempScop, CurRegion);
+ checkForReduction();
+}
+
+void ScopStmt::checkForReduction() {
+ // Skip statements with more than one binary reduction
+ if (MemAccs.size() != 2)
+ return;
+
+ // Skip if there is not exactly one load and one store
+ unsigned LoadIdx = MemAccs[0]->isRead() ? 0 : 1;
+ auto *Load = dyn_cast<LoadInst>(MemAccs[LoadIdx]->getAccessInstruction());
+ auto *Store =
+ dyn_cast<StoreInst>(MemAccs[1 - LoadIdx]->getAccessInstruction());
+ if (!Load || !Store ||
+ Load->getPointerOperand() != Store->getPointerOperand())
+ return;
+
+ // Skip if there is not one binary operator between the load and the store
+ auto *BinOp = dyn_cast<BinaryOperator>(Store->getValueOperand());
+ if (!BinOp || (BinOp->getOperand(0) != Load && BinOp->getOperand(1) != Load))
+ return;
+
+ // Skip if the opcode of the binary operator is not commutative/associative
+ if (!BinOp->isCommutative() || !BinOp->isAssociative())
+ return;
+
+ // Skip if the load has multiple uses
+ if (Load->getNumUses() != 1)
+ return;
+
+ // Skip if it is a multiplicative reduction and we disabled them
+ if (DisableMultiplicativeReductions &&
+ (BinOp->getOpcode() == Instruction::Mul ||
+ BinOp->getOpcode() == Instruction::FMul))
+ return;
+
+ // Valid reduction like statement
+ IsReductionLike = true;
}
std::string ScopStmt::getDomainStr() const { return stringFromIslObj(Domain); }
@@ -751,6 +798,7 @@ ScopStmt::~ScopStmt() {
void ScopStmt::print(raw_ostream &OS) const {
OS << "\t" << getBaseName() << "\n";
+ OS.indent(8) << "Reduction like: " << isReductionLike() << "\n";
OS.indent(12) << "Domain :=\n";
More information about the llvm-commits
mailing list