summaryrefslogtreecommitdiff
path: root/lib/Analysis/Lint.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2010-05-28 16:45:33 +0000
committerDan Gohman <gohman@apple.com>2010-05-28 16:45:33 +0000
commit17d95965cbf529f96277130b75c018f5f3873b66 (patch)
tree4e091349742dc848c12cb8be44fdd949a6299c64 /lib/Analysis/Lint.cpp
parent34220aedc4242ab6a1356ca664a0f65c48d093f5 (diff)
downloadllvm-17d95965cbf529f96277130b75c018f5f3873b66.tar.gz
llvm-17d95965cbf529f96277130b75c018f5f3873b66.tar.bz2
llvm-17d95965cbf529f96277130b75c018f5f3873b66.tar.xz
Detect self-referential values.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104957 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/Lint.cpp')
-rw-r--r--lib/Analysis/Lint.cpp25
1 files changed, 19 insertions, 6 deletions
diff --git a/lib/Analysis/Lint.cpp b/lib/Analysis/Lint.cpp
index 4b9f284c9d..751c41ce39 100644
--- a/lib/Analysis/Lint.cpp
+++ b/lib/Analysis/Lint.cpp
@@ -93,6 +93,8 @@ namespace {
void visitUnreachableInst(UnreachableInst &I);
Value *findValue(Value *V, bool OffsetOk) const;
+ Value *findValueImpl(Value *V, bool OffsetOk,
+ SmallPtrSet<Value *, 4> &Visited) const;
public:
Module *Mod;
@@ -498,6 +500,17 @@ void Lint::visitUnreachableInst(UnreachableInst &I) {
/// will simplify most of these kinds of things away. But it's a goal of
/// this Lint pass to be useful even on non-optimized IR.
Value *Lint::findValue(Value *V, bool OffsetOk) const {
+ SmallPtrSet<Value *, 4> Visited;
+ return findValueImpl(V, OffsetOk, Visited);
+}
+
+/// findValueImpl - Implementation helper for findValue.
+Value *Lint::findValueImpl(Value *V, bool OffsetOk,
+ SmallPtrSet<Value *, 4> &Visited) const {
+ // Detect self-referential values.
+ if (!Visited.insert(V))
+ return UndefValue::get(V->getType());
+
// TODO: Look through sext or zext cast, when the result is known to
// be interpreted as signed or unsigned, respectively.
// TODO: Look through calls with unique return values.
@@ -509,7 +522,7 @@ Value *Lint::findValue(Value *V, bool OffsetOk) const {
for (;;) {
if (Value *U = FindAvailableLoadedValue(L->getPointerOperand(),
BB, BBI, 6, AA))
- return findValue(U, OffsetOk);
+ return findValueImpl(U, OffsetOk, Visited);
BB = L->getParent()->getUniquePredecessor();
if (!BB) break;
BBI = BB->end();
@@ -517,27 +530,27 @@ Value *Lint::findValue(Value *V, bool OffsetOk) const {
} else if (CastInst *CI = dyn_cast<CastInst>(V)) {
if (CI->isNoopCast(TD ? TD->getIntPtrType(V->getContext()) :
Type::getInt64Ty(V->getContext())))
- return findValue(CI->getOperand(0), OffsetOk);
+ return findValueImpl(CI->getOperand(0), OffsetOk, Visited);
} else if (PHINode *PN = dyn_cast<PHINode>(V)) {
if (Value *W = PN->hasConstantValue(DT))
- return findValue(W, OffsetOk);
+ return findValueImpl(W, OffsetOk, Visited);
} else if (ExtractValueInst *Ex = dyn_cast<ExtractValueInst>(V)) {
if (Value *W = FindInsertedValue(Ex->getAggregateOperand(),
Ex->idx_begin(),
Ex->idx_end()))
if (W != V)
- return findValue(W, OffsetOk);
+ return findValueImpl(W, OffsetOk, Visited);
}
// As a last resort, try SimplifyInstruction or constant folding.
if (Instruction *Inst = dyn_cast<Instruction>(V)) {
if (Value *W = SimplifyInstruction(Inst, TD))
if (W != Inst)
- return findValue(W, OffsetOk);
+ return findValueImpl(W, OffsetOk, Visited);
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
if (Value *W = ConstantFoldConstantExpression(CE, TD))
if (W != V)
- return findValue(W, OffsetOk);
+ return findValueImpl(W, OffsetOk, Visited);
}
return V;