#ifndef LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H
#define LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/LoopPass.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/raw_ostream.h"
-#include <iosfwd>
namespace llvm {
class AliasAnalysis;
class AnalysisUsage;
class ScalarEvolution;
+class SCEV;
class Value;
+class raw_ostream;
class LoopDependenceAnalysis : public LoopPass {
AliasAnalysis *AA;
/// TODO: doc
enum DependenceResult { Independent = 0, Dependent = 1, Unknown = 2 };
+ /// TODO: doc
+ struct Subscript {
+ /// TODO: Add distance, direction, breaking conditions, ...
+ };
+
/// DependencePair - Represents a data dependence relation between to memory
/// reference instructions.
- ///
- /// TODO: add subscripts vector
struct DependencePair : public FastFoldingSetNode {
Value *A;
Value *B;
DependenceResult Result;
+ SmallVector<Subscript, 4> Subscripts;
DependencePair(const FoldingSetNodeID &ID, Value *a, Value *b) :
- FastFoldingSetNode(ID), A(a), B(b), Result(Unknown) {}
+ FastFoldingSetNode(ID), A(a), B(b), Result(Unknown), Subscripts() {}
};
/// findOrInsertDependencePair - Return true if a DependencePair for the
/// created. The third argument is set to the pair found or created.
bool findOrInsertDependencePair(Value*, Value*, DependencePair*&);
+ /// getLoops - Collect all loops of the loop nest L in which
+ /// a given SCEV is variant.
+ void getLoops(const SCEV*, DenseSet<const Loop*>*) const;
+
+ /// isLoopInvariant - True if a given SCEV is invariant in all loops of the
+ /// loop nest starting at the innermost loop L.
+ bool isLoopInvariant(const SCEV*) const;
+
+ /// isAffine - An SCEV is affine with respect to the loop nest starting at
+ /// the innermost loop L if it is of the form A+B*X where A, B are invariant
+ /// in the loop nest and X is a induction variable in the loop nest.
+ bool isAffine(const SCEV*) const;
+
/// TODO: doc
- void analysePair(DependencePair *P) const;
+ bool isZIVPair(const SCEV*, const SCEV*) const;
+ bool isSIVPair(const SCEV*, const SCEV*) const;
+ DependenceResult analyseZIV(const SCEV*, const SCEV*, Subscript*) const;
+ DependenceResult analyseSIV(const SCEV*, const SCEV*, Subscript*) const;
+ DependenceResult analyseMIV(const SCEV*, const SCEV*, Subscript*) const;
+ DependenceResult analyseSubscript(const SCEV*, const SCEV*, Subscript*) const;
+ DependenceResult analysePair(DependencePair*) const;
public:
static char ID; // Class identification, replacement for typeinfo
- LoopDependenceAnalysis() : LoopPass(&ID) {}
+ LoopDependenceAnalysis() : LoopPass(ID) {
+ initializeLoopDependenceAnalysisPass(*PassRegistry::getPassRegistry());
+ }
- /// isDependencePair - Check wether two values can possibly give rise to a
- /// data dependence: that is the case if both are instructions accessing
+ /// isDependencePair - Check whether two values can possibly give rise to
+ /// a data dependence: that is the case if both are instructions accessing
/// memory and at least one of those accesses is a write.
bool isDependencePair(const Value*, const Value*) const;
virtual void releaseMemory();
virtual void getAnalysisUsage(AnalysisUsage&) const;
void print(raw_ostream&, const Module* = 0) const;
- virtual void print(std::ostream&, const Module* = 0) const;
private:
FoldingSet<DependencePair> Pairs;
BumpPtrAllocator PairAllocator;
}; // class LoopDependenceAnalysis
-
// createLoopDependenceAnalysisPass - This creates an instance of the
// LoopDependenceAnalysis pass.
//