aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis/LiveVariables.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Analysis/LiveVariables.cpp')
-rw-r--r--clang/lib/Analysis/LiveVariables.cpp323
1 files changed, 0 insertions, 323 deletions
diff --git a/clang/lib/Analysis/LiveVariables.cpp b/clang/lib/Analysis/LiveVariables.cpp
deleted file mode 100644
index 4148d9e..0000000
--- a/clang/lib/Analysis/LiveVariables.cpp
+++ /dev/null
@@ -1,323 +0,0 @@
-//=- LiveVariables.cpp - Live Variable Analysis for Source CFGs -*- C++ --*-==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-// details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements Live Variables analysis for source-level CFGs.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/Analyses/LiveVariables.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/CFG.h"
-#include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h"
-#include "clang/Analysis/FlowSensitive/DataflowSolver.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/Compiler.h"
-
-#include <string.h>
-#include <stdio.h>
-
-using namespace clang;
-
-//===----------------------------------------------------------------------===//
-// Useful constants.
-//===----------------------------------------------------------------------===//
-
-static const bool Alive = true;
-static const bool Dead = false;
-
-//===----------------------------------------------------------------------===//
-// Dataflow initialization logic.
-//===----------------------------------------------------------------------===//
-
-namespace {
-class VISIBILITY_HIDDEN RegisterDecls
- : public CFGRecStmtDeclVisitor<RegisterDecls> {
-
- LiveVariables::AnalysisDataTy& AD;
-
- typedef llvm::SmallVector<VarDecl*, 20> AlwaysLiveTy;
- AlwaysLiveTy AlwaysLive;
-
-
-public:
- RegisterDecls(LiveVariables::AnalysisDataTy& ad) : AD(ad) {}
-
- ~RegisterDecls() {
-
- AD.AlwaysLive.resetValues(AD);
-
- for (AlwaysLiveTy::iterator I = AlwaysLive.begin(), E = AlwaysLive.end();
- I != E; ++ I)
- AD.AlwaysLive(*I, AD) = Alive;
- }
-
- void VisitVarDecl(VarDecl* VD) {
- // Register the VarDecl for tracking.
- AD.Register(VD);
-
- // Does the variable have global storage? If so, it is always live.
- if (VD->hasGlobalStorage())
- AlwaysLive.push_back(VD);
- }
-
- void VisitUnaryOperator(UnaryOperator* U) {
- // Check for '&'. Any VarDecl whose value has its address-taken we
- // treat as always being live (flow-insensitive).
-
- Expr* E = U->getSubExpr()->IgnoreParenCasts();
-
- if (U->getOpcode() == UnaryOperator::AddrOf)
- if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(E))
- if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl())) {
- AD.Register(VD);
- AlwaysLive.push_back(VD);
- return;
- }
-
- Visit(E);
- }
-
- CFG& getCFG() { return AD.getCFG(); }
-};
-} // end anonymous namespace
-
-
-LiveVariables::LiveVariables(CFG& cfg) {
- // Register all referenced VarDecls.
- getAnalysisData().setCFG(&cfg);
- RegisterDecls R(getAnalysisData());
- cfg.VisitBlockStmts(R);
-}
-
-//===----------------------------------------------------------------------===//
-// Transfer functions.
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class VISIBILITY_HIDDEN TransferFuncs : public CFGRecStmtVisitor<TransferFuncs>{
- LiveVariables::AnalysisDataTy& AD;
- LiveVariables::ValTy LiveState;
-public:
- TransferFuncs(LiveVariables::AnalysisDataTy& ad) : AD(ad) {}
-
- LiveVariables::ValTy& getVal() { return LiveState; }
- CFG& getCFG() { return AD.getCFG(); }
-
- void VisitDeclRefExpr(DeclRefExpr* DR);
- void VisitBinaryOperator(BinaryOperator* B);
- void VisitAssign(BinaryOperator* B);
- void VisitDeclStmt(DeclStmt* DS);
- void VisitUnaryOperator(UnaryOperator* U);
- void Visit(Stmt *S);
- void VisitTerminator(CFGBlock* B);
-
- void SetTopValue(LiveVariables::ValTy& V) {
- V = AD.AlwaysLive;
- }
-
-};
-
-void TransferFuncs::Visit(Stmt *S) {
- if (AD.Observer)
- AD.Observer->ObserveStmt(S,AD,LiveState);
-
- if (S == getCurrentBlkStmt()) {
- if (getCFG().isBlkExpr(S)) LiveState(S,AD) = Dead;
- StmtVisitor<TransferFuncs,void>::Visit(S);
- }
- else if (!getCFG().isBlkExpr(S))
- StmtVisitor<TransferFuncs,void>::Visit(S);
- else
- // For block-level expressions, mark that they are live.
- LiveState(S,AD) = Alive;
-}
-
-void TransferFuncs::VisitTerminator(CFGBlock* B) {
-
- const Expr* E = B->getTerminatorCondition();
-
- if (!E)
- return;
-
- assert (getCFG().isBlkExpr(E));
- LiveState(E, AD) = Alive;
-}
-
-void TransferFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
- if (VarDecl* V = dyn_cast<VarDecl>(DR->getDecl()))
- LiveState(V,AD) = Alive;
-}
-
-void TransferFuncs::VisitBinaryOperator(BinaryOperator* B) {
- if (B->isAssignmentOp()) VisitAssign(B);
- else VisitStmt(B);
-}
-
-void TransferFuncs::VisitUnaryOperator(UnaryOperator* U) {
- Expr *E = U->getSubExpr();
-
- switch (U->getOpcode()) {
- case UnaryOperator::SizeOf: return;
- case UnaryOperator::PostInc:
- case UnaryOperator::PostDec:
- case UnaryOperator::PreInc:
- case UnaryOperator::PreDec:
- // Walk through the subexpressions, blasting through ParenExprs
- // until we either find a DeclRefExpr or some non-DeclRefExpr
- // expression.
- if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(E->IgnoreParens()))
- if (VarDecl* VD = dyn_cast<VarDecl>(DR->getDecl())) {
- // Treat the --/++ operator as a kill.
- if (AD.Observer) { AD.Observer->ObserverKill(DR); }
- LiveState(VD, AD) = Alive;
- return VisitDeclRefExpr(DR);
- }
-
- // Fall-through.
-
- default:
- return Visit(E);
- }
-}
-
-void TransferFuncs::VisitAssign(BinaryOperator* B) {
- Expr* LHS = B->getLHS();
-
- // Assigning to a variable?
- if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS->IgnoreParens())) {
-
- // Update liveness inforamtion.
- unsigned bit = AD.getIdx(DR->getDecl());
- LiveState.getDeclBit(bit) = Dead | AD.AlwaysLive.getDeclBit(bit);
-
- if (AD.Observer) { AD.Observer->ObserverKill(DR); }
-
- // Handle things like +=, etc., which also generate "uses"
- // of a variable. Do this just by visiting the subexpression.
- if (B->getOpcode() != BinaryOperator::Assign)
- VisitDeclRefExpr(DR);
- }
- else // Not assigning to a variable. Process LHS as usual.
- Visit(LHS);
-
- Visit(B->getRHS());
-}
-
-void TransferFuncs::VisitDeclStmt(DeclStmt* DS) {
- // Declarations effectively "kill" a variable since they cannot
- // possibly be live before they are declared.
- for (ScopedDecl* D = DS->getDecl(); D != NULL; D = D->getNextDeclarator())
- if (VarDecl* VD = dyn_cast<VarDecl>(D)) {
-
- // Update liveness information.
- unsigned bit = AD.getIdx(VD);
- LiveState.getDeclBit(bit) = Dead | AD.AlwaysLive.getDeclBit(bit);
-
- if (Expr* Init = VD->getInit())
- Visit(Init);
- }
-}
-
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// Merge operator: if something is live on any successor block, it is live
-// in the current block (a set union).
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-struct Merge {
- typedef ExprDeclBitVector_Types::ValTy ValTy;
-
- void operator()(ValTy& Dst, const ValTy& Src) {
- Dst.OrDeclBits(Src);
- Dst.AndExprBits(Src);
- }
-};
-
-typedef DataflowSolver<LiveVariables, TransferFuncs, Merge> Solver;
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// External interface to run Liveness analysis.
-//===----------------------------------------------------------------------===//
-
-void LiveVariables::runOnCFG(CFG& cfg) {
- Solver S(*this);
- S.runOnCFG(cfg);
-}
-
-void LiveVariables::runOnAllBlocks(const CFG& cfg,
- LiveVariables::ObserverTy* Obs,
- bool recordStmtValues) {
- Solver S(*this);
- ObserverTy* OldObserver = getAnalysisData().Observer;
- getAnalysisData().Observer = Obs;
- S.runOnAllBlocks(cfg, recordStmtValues);
- getAnalysisData().Observer = OldObserver;
-}
-
-//===----------------------------------------------------------------------===//
-// liveness queries
-//
-
-bool LiveVariables::isLive(const CFGBlock* B, const VarDecl* D) const {
- DeclBitVector_Types::Idx i = getAnalysisData().getIdx(D);
- return i.isValid() ? getBlockData(B).getBit(i) : false;
-}
-
-bool LiveVariables::isLive(const ValTy& Live, const VarDecl* D) const {
- DeclBitVector_Types::Idx i = getAnalysisData().getIdx(D);
- return i.isValid() ? Live.getBit(i) : false;
-}
-
-bool LiveVariables::isLive(const Stmt* Loc, const Stmt* StmtVal) const {
- return getStmtData(Loc)(StmtVal,getAnalysisData());
-}
-
-bool LiveVariables::isLive(const Stmt* Loc, const VarDecl* D) const {
- return getStmtData(Loc)(D,getAnalysisData());
-}
-
-//===----------------------------------------------------------------------===//
-// printing liveness state for debugging
-//
-
-void LiveVariables::dumpLiveness(const ValTy& V, SourceManager& SM) const {
- const AnalysisDataTy& AD = getAnalysisData();
-
- for (AnalysisDataTy::decl_iterator I = AD.begin_decl(),
- E = AD.end_decl(); I!=E; ++I)
- if (V.getDeclBit(I->second)) {
- SourceLocation PhysLoc = SM.getPhysicalLoc(I->first->getLocation());
-
- fprintf(stderr, " %s <%s:%u:%u>\n",
- I->first->getIdentifier()->getName(),
- SM.getSourceName(PhysLoc),
- SM.getLineNumber(PhysLoc),
- SM.getColumnNumber(PhysLoc));
- }
-}
-
-void LiveVariables::dumpBlockLiveness(SourceManager& M) const {
- for (BlockDataMapTy::iterator I = getBlockDataMap().begin(),
- E = getBlockDataMap().end(); I!=E; ++I) {
- fprintf(stderr, "\n[ B%d (live variables at block exit) ]\n",
- I->first->getBlockID());
-
- dumpLiveness(I->second,M);
- }
-
- fprintf(stderr,"\n");
-}