diff options
author | Dan Gohman <gohman@apple.com> | 2010-05-28 16:45:33 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2010-05-28 16:45:33 +0000 |
commit | 17d95965cbf529f96277130b75c018f5f3873b66 (patch) | |
tree | 4e091349742dc848c12cb8be44fdd949a6299c64 /lib/Analysis/Lint.cpp | |
parent | 34220aedc4242ab6a1356ca664a0f65c48d093f5 (diff) |
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.cpp | 25 |
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; |