summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-08-18 16:46:41 +0000
committerDan Gohman <gohman@apple.com>2009-08-18 16:46:41 +0000
commitc40f17b08774c2dcc5787fd83241e3c64ba82974 (patch)
treeae3c3455972b1fca1b2c67e7381205bba7dc2843 /include
parent4d35fce60c5ac108d24428829e51a97eeca7836c (diff)
downloadllvm-c40f17b08774c2dcc5787fd83241e3c64ba82974.tar.gz
llvm-c40f17b08774c2dcc5787fd83241e3c64ba82974.tar.bz2
llvm-c40f17b08774c2dcc5787fd83241e3c64ba82974.tar.xz
Generalize ScalarEvolution to be able to analyze GEPs when
TargetData is not present. It still uses TargetData when available. This generalization also fixed some limitations in the TargetData case; the attached testcase covers this. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79344 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/llvm/Analysis/ScalarEvolution.h2
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpander.h4
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpressions.h92
3 files changed, 96 insertions, 2 deletions
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h
index b98f535217..558cd011f5 100644
--- a/include/llvm/Analysis/ScalarEvolution.h
+++ b/include/llvm/Analysis/ScalarEvolution.h
@@ -433,6 +433,8 @@ namespace llvm {
const SCEV *getUMaxExpr(SmallVectorImpl<const SCEV *> &Operands);
const SCEV *getSMinExpr(const SCEV *LHS, const SCEV *RHS);
const SCEV *getUMinExpr(const SCEV *LHS, const SCEV *RHS);
+ const SCEV *getFieldOffsetExpr(const StructType *STy, unsigned FieldNo);
+ const SCEV *getAllocSizeExpr(const Type *AllocTy);
const SCEV *getUnknown(Value *V);
const SCEV *getCouldNotCompute();
diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h
index 9266bf9713..cc0204b6fa 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpander.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpander.h
@@ -115,6 +115,10 @@ namespace llvm {
Value *visitUMaxExpr(const SCEVUMaxExpr *S);
+ Value *visitFieldOffsetExpr(const SCEVFieldOffsetExpr *S);
+
+ Value *visitAllocSizeExpr(const SCEVAllocSizeExpr *S);
+
Value *visitUnknown(const SCEVUnknown *S) {
return S->getValue();
}
diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h
index 99df1dfefc..35372be126 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpressions.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h
@@ -26,8 +26,8 @@ namespace llvm {
// These should be ordered in terms of increasing complexity to make the
// folders simpler.
scConstant, scTruncate, scZeroExtend, scSignExtend, scAddExpr, scMulExpr,
- scUDivExpr, scAddRecExpr, scUMaxExpr, scSMaxExpr, scUnknown,
- scCouldNotCompute
+ scUDivExpr, scAddRecExpr, scUMaxExpr, scSMaxExpr,
+ scFieldOffset, scAllocSize, scUnknown, scCouldNotCompute
};
//===--------------------------------------------------------------------===//
@@ -488,6 +488,90 @@ namespace llvm {
}
};
+ //===--------------------------------------------------------------------===//
+ /// SCEVTargetDataConstant - This node is the base class for representing
+ /// target-dependent values in a target-independent way.
+ ///
+ class SCEVTargetDataConstant : public SCEV {
+ protected:
+ const Type *Ty;
+ SCEVTargetDataConstant(const FoldingSetNodeID &ID, enum SCEVTypes T,
+ const Type *ty) :
+ SCEV(ID, T), Ty(ty) {}
+
+ public:
+ virtual bool isLoopInvariant(const Loop *) const { return true; }
+ virtual bool hasComputableLoopEvolution(const Loop *) const {
+ return false; // not computable
+ }
+
+ virtual bool hasOperand(const SCEV *) const {
+ return false;
+ }
+
+ bool dominates(BasicBlock *, DominatorTree *) const {
+ return true;
+ }
+
+ virtual const Type *getType() const { return Ty; }
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SCEVTargetDataConstant *S) { return true; }
+ static inline bool classof(const SCEV *S) {
+ return S->getSCEVType() == scFieldOffset ||
+ S->getSCEVType() == scAllocSize;
+ }
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVFieldOffsetExpr - This node represents an offsetof expression.
+ ///
+ class SCEVFieldOffsetExpr : public SCEVTargetDataConstant {
+ friend class ScalarEvolution;
+
+ const StructType *STy;
+ unsigned FieldNo;
+ SCEVFieldOffsetExpr(const FoldingSetNodeID &ID, const Type *ty,
+ const StructType *sty, unsigned fieldno) :
+ SCEVTargetDataConstant(ID, scFieldOffset, ty),
+ STy(sty), FieldNo(fieldno) {}
+
+ public:
+ const StructType *getStructType() const { return STy; }
+ unsigned getFieldNo() const { return FieldNo; }
+
+ virtual void print(raw_ostream &OS) const;
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SCEVFieldOffsetExpr *S) { return true; }
+ static inline bool classof(const SCEV *S) {
+ return S->getSCEVType() == scFieldOffset;
+ }
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVAllocSize - This node represents a sizeof expression.
+ ///
+ class SCEVAllocSizeExpr : public SCEVTargetDataConstant {
+ friend class ScalarEvolution;
+
+ const Type *AllocTy;
+ SCEVAllocSizeExpr(const FoldingSetNodeID &ID,
+ const Type *ty, const Type *allocty) :
+ SCEVTargetDataConstant(ID, scAllocSize, ty),
+ AllocTy(allocty) {}
+
+ public:
+ const Type *getAllocType() const { return AllocTy; }
+
+ virtual void print(raw_ostream &OS) const;
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SCEVAllocSizeExpr *S) { return true; }
+ static inline bool classof(const SCEV *S) {
+ return S->getSCEVType() == scAllocSize;
+ }
+ };
//===--------------------------------------------------------------------===//
/// SCEVUnknown - This means that we are dealing with an entirely unknown SCEV
@@ -552,6 +636,10 @@ namespace llvm {
return ((SC*)this)->visitSMaxExpr((const SCEVSMaxExpr*)S);
case scUMaxExpr:
return ((SC*)this)->visitUMaxExpr((const SCEVUMaxExpr*)S);
+ case scFieldOffset:
+ return ((SC*)this)->visitFieldOffsetExpr((const SCEVFieldOffsetExpr*)S);
+ case scAllocSize:
+ return ((SC*)this)->visitAllocSizeExpr((const SCEVAllocSizeExpr*)S);
case scUnknown:
return ((SC*)this)->visitUnknown((const SCEVUnknown*)S);
case scCouldNotCompute: