From: Andreas Bolka Date: Wed, 29 Jul 2009 05:35:53 +0000 (+0000) Subject: Skeleton for pairwise subscript testing. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=15f72dbf972f056b1685786e5118148fb528f233;hp=45ce89ba080f4be72e4e49367567114800f6b3c5;p=oota-llvm.git Skeleton for pairwise subscript testing. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@77437 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Analysis/LoopDependenceAnalysis.h b/include/llvm/Analysis/LoopDependenceAnalysis.h index 3eab6652249..56a6b6eb061 100644 --- a/include/llvm/Analysis/LoopDependenceAnalysis.h +++ b/include/llvm/Analysis/LoopDependenceAnalysis.h @@ -21,6 +21,7 @@ #define LLVM_ANALYSIS_LOOP_DEPENDENCE_ANALYSIS_H #include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Support/Allocator.h" #include @@ -30,6 +31,7 @@ namespace llvm { class AliasAnalysis; class AnalysisUsage; class ScalarEvolution; +class SCEV; class Value; class raw_ostream; @@ -43,17 +45,21 @@ class LoopDependenceAnalysis : public LoopPass { /// 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 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 @@ -62,7 +68,8 @@ class LoopDependenceAnalysis : public LoopPass { bool findOrInsertDependencePair(Value*, Value*, DependencePair*&); /// TODO: doc - DependenceResult analysePair(DependencePair *P) const; + DependenceResult analyseSubscript(const SCEV*, const SCEV*, Subscript*) const; + DependenceResult analysePair(DependencePair*) const; public: static char ID; // Class identification, replacement for typeinfo @@ -88,7 +95,6 @@ private: BumpPtrAllocator PairAllocator; }; // class LoopDependenceAnalysis - // createLoopDependenceAnalysisPass - This creates an instance of the // LoopDependenceAnalysis pass. // diff --git a/lib/Analysis/LoopDependenceAnalysis.cpp b/lib/Analysis/LoopDependenceAnalysis.cpp index 78c3975b6d8..51f6c3aafd9 100644 --- a/lib/Analysis/LoopDependenceAnalysis.cpp +++ b/lib/Analysis/LoopDependenceAnalysis.cpp @@ -15,6 +15,8 @@ // // TODO: adapt as implementation progresses. // +// TODO: document lingo (pair, subscript, index) +// //===----------------------------------------------------------------------===// #define DEBUG_TYPE "lda" @@ -24,6 +26,7 @@ #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Instructions.h" +#include "llvm/Operator.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -87,6 +90,10 @@ static AliasAnalysis::AliasResult UnderlyingObjectsAlias(AliasAnalysis *AA, bObj, AA->getTypeStoreSize(bObj->getType())); } +static inline const SCEV *GetZeroSCEV(ScalarEvolution *SE) { + return SE->getConstant(Type::Int32Ty, 0L); +} + //===----------------------------------------------------------------------===// // Dependence Testing //===----------------------------------------------------------------------===// @@ -116,6 +123,13 @@ bool LoopDependenceAnalysis::findOrInsertDependencePair(Value *A, return false; } +LoopDependenceAnalysis::DependenceResult +LoopDependenceAnalysis::analyseSubscript(const SCEV *A, + const SCEV *B, + Subscript *S) const { + return Unknown; // TODO: Implement. +} + LoopDependenceAnalysis::DependenceResult LoopDependenceAnalysis::analysePair(DependencePair *P) const { DEBUG(errs() << "Analysing:\n" << *P->A << "\n" << *P->B << "\n"); @@ -145,9 +159,37 @@ LoopDependenceAnalysis::analysePair(DependencePair *P) const { break; // The underlying objects alias, test accesses for dependence. } - // We failed to analyse this pair to get a more specific answer. - DEBUG(errs() << "---> [?] cannot analyse\n"); - return Unknown; + const GEPOperator *aGEP = dyn_cast(aPtr); + const GEPOperator *bGEP = dyn_cast(bPtr); + + if (!aGEP || !bGEP) + return Unknown; + + // FIXME: Is filtering coupled subscripts necessary? + + // Analyse indices pairwise (FIXME: use GetGEPOperands from BasicAA), adding + // trailing zeroes to the smaller GEP, if needed. + GEPOperator::const_op_iterator aIdx = aGEP->idx_begin(), + aEnd = aGEP->idx_end(), + bIdx = bGEP->idx_begin(), + bEnd = bGEP->idx_end(); + while (aIdx != aEnd && bIdx != bEnd) { + const SCEV* aSCEV = (aIdx != aEnd) ? SE->getSCEV(*aIdx) : GetZeroSCEV(SE); + const SCEV* bSCEV = (bIdx != bEnd) ? SE->getSCEV(*bIdx) : GetZeroSCEV(SE); + Subscript subscript; + DependenceResult result = analyseSubscript(aSCEV, bSCEV, &subscript); + if (result != Dependent) { + // We either proved independence or failed to analyse this subscript. + // Further subscripts will not improve the situation, so abort early. + return result; + } + P->Subscripts.push_back(subscript); + if (aIdx != aEnd) ++aIdx; + if (bIdx != bEnd) ++bIdx; + } + // Either there were no subscripts or all subscripts were analysed to be + // dependent; in both cases we know the accesses are dependent. + return Dependent; } bool LoopDependenceAnalysis::depends(Value *A, Value *B) {