[cfe-commits] r41737 - in /cfe/trunk: Analysis/ Analysis/LiveVariables.cpp Analysis/Makefile Driver/ASTStreamers.cpp Driver/ASTStreamers.h Driver/Makefile Driver/clang.cpp clang.xcodeproj/project.pbxproj include/clang/Analysis/ include/clang/Analysis/LiveVariables.h
Ted Kremenek
kremenek at apple.com
Wed Sep 5 17:17:54 PDT 2007
Author: kremenek
Date: Wed Sep 5 19:17:54 2007
New Revision: 41737
URL: http://llvm.org/viewvc/llvm-project?rev=41737&view=rev
Log:
Added an early implementation of Live-Variables analysis built on
source-level CFGs. This code may change significantly in the near
future as we explore different means to implement dataflow analyses.
Added a driver option, -dump-live-variables, to view the output of
live variable analysis. This output is very ALPHA; it will be improved shortly.
Added:
cfe/trunk/Analysis/
cfe/trunk/Analysis/LiveVariables.cpp
cfe/trunk/Analysis/Makefile
cfe/trunk/include/clang/Analysis/
cfe/trunk/include/clang/Analysis/LiveVariables.h
Modified:
cfe/trunk/Driver/ASTStreamers.cpp
cfe/trunk/Driver/ASTStreamers.h
cfe/trunk/Driver/Makefile
cfe/trunk/Driver/clang.cpp
cfe/trunk/clang.xcodeproj/project.pbxproj
Added: cfe/trunk/Analysis/LiveVariables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/LiveVariables.cpp?rev=41737&view=auto
==============================================================================
--- cfe/trunk/Analysis/LiveVariables.cpp (added)
+++ cfe/trunk/Analysis/LiveVariables.cpp Wed Sep 5 19:17:54 2007
@@ -0,0 +1,282 @@
+//==- LiveVariables.cpp - Live Variable Analysis for Source CFGs -*- C++ --*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Ted Kremenek and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements Live Variables analysis for source-level CFGs.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/LiveVariables.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/CFG.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/Lex/IdentifierTable.h"
+#include "llvm/ADT/SmallPtrSet.h"
+
+#include <iostream>
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// RegisterDecls - Utility class to create VarInfo objects for all
+// Decls referenced in a function.
+//
+
+namespace {
+
+class RegisterDecls : public StmtVisitor<RegisterDecls,void> {
+ LiveVariables& L;
+ const CFG& cfg;
+public:
+ RegisterDecls(LiveVariables& l, const CFG& c)
+ : L(l), cfg(c) {}
+
+ void VisitStmt(Stmt* S);
+ void VisitDeclRefExpr(DeclRefExpr* DR);
+ void Register(Decl* D);
+ void RegisterUsedDecls();
+};
+
+void RegisterDecls::VisitStmt(Stmt* S) {
+ for (Stmt::child_iterator I = S->child_begin(),E = S->child_end(); I != E;++I)
+ Visit(*I);
+}
+
+void RegisterDecls::VisitDeclRefExpr(DeclRefExpr* DR) {
+ for (Decl* D = DR->getDecl() ; D != NULL ; D = D->getNextDeclarator())
+ Register(D);
+}
+
+void RegisterDecls::Register(Decl* D) {
+ LiveVariables::VPair& VP = L.getVarInfoMap()[const_cast<const Decl*>(D)];
+
+ VP.V.AliveBlocks.reserve(cfg.getNumBlockIDs());
+ VP.Idx = L.getNumDecls()++;
+}
+
+void RegisterDecls::RegisterUsedDecls() {
+ for (CFG::const_iterator BI = cfg.begin(), BE = cfg.end(); BI != BE; ++BI)
+ for (CFGBlock::const_iterator SI=BI->begin(),SE = BI->end();SI != SE;++SI)
+ Visit(const_cast<Stmt*>(*SI));
+}
+
+
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// WorkList - Data structure representing the liveness algorithm worklist.
+//
+
+namespace {
+
+class WorkListTy {
+ typedef llvm::SmallPtrSet<const CFGBlock*,20> BlockSet;
+ BlockSet wlist;
+public:
+ void enqueue(const CFGBlock* B) { wlist.insert(B); }
+
+ const CFGBlock* dequeue() {
+ assert (!wlist.empty());
+ const CFGBlock* B = *wlist.begin();
+ wlist.erase(B);
+ return B;
+ }
+
+ bool isEmpty() const { return wlist.empty(); }
+};
+
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// TFuncs
+//
+
+namespace {
+
+class LivenessTFuncs : public StmtVisitor<LivenessTFuncs,void> {
+ LiveVariables& L;
+ llvm::BitVector Live;
+ llvm::BitVector Killed;
+public:
+ LivenessTFuncs(LiveVariables& l) : L(l) {
+ Live.resize(l.getNumDecls());
+ Killed.resize(l.getNumDecls());
+ }
+
+ void VisitStmt(Stmt* S);
+ void VisitDeclRefExpr(DeclRefExpr* DR);
+ void VisitBinaryOperator(BinaryOperator* B);
+ void VisitAssign(BinaryOperator* B);
+ void VisitStmtExpr(StmtExpr* S);
+
+ unsigned getIdx(const Decl* D) {
+ LiveVariables::VarInfoMap& V = L.getVarInfoMap();
+ LiveVariables::VarInfoMap::iterator I = V.find(D);
+ assert (I != V.end());
+ return I->second.Idx;
+ }
+
+ bool ProcessBlock(const CFGBlock* B);
+ llvm::BitVector* getLiveness(const CFGBlock* B);
+
+};
+
+void LivenessTFuncs::VisitStmt(Stmt* S) {
+ // Evaluate the transfer functions for all subexpressions. Note that
+ // each invocation of "Visit" will have a side-effect: "Liveness" and "Kills"
+ // will be updated.
+ for (Stmt::child_iterator I = S->child_begin(),E = S->child_end(); I != E;++I)
+ Visit(*I);
+}
+
+void LivenessTFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
+ // Register a use of the variable.
+ Live.set(getIdx(DR->getDecl()));
+}
+
+void LivenessTFuncs::VisitStmtExpr(StmtExpr* S) {
+ // Do nothing. The substatements of S are segmented into separate
+ // statements in the CFG.
+}
+
+void LivenessTFuncs::VisitBinaryOperator(BinaryOperator* B) {
+ switch (B->getOpcode()) {
+ case BinaryOperator::LAnd:
+ case BinaryOperator::LOr:
+ case BinaryOperator::Comma:
+ // Do nothing. These operations are broken up into multiple
+ // statements in the CFG. All these expressions do is return
+ // the value of their subexpressions, but these expressions will
+ // be evalualated elsewhere in the CFG.
+ break;
+
+ // FIXME: handle '++' and '--'
+ default:
+ if (B->isAssignmentOp()) VisitAssign(B);
+ else Visit(B);
+ }
+}
+
+
+void LivenessTFuncs::VisitAssign(BinaryOperator* B) {
+ Stmt* LHS = B->getLHS();
+
+ if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(LHS)) {
+ unsigned i = getIdx(DR->getDecl());
+ Live.reset(i);
+ Killed.set(i);
+ }
+ else Visit(LHS);
+
+ Visit(B->getRHS());
+}
+
+
+llvm::BitVector* LivenessTFuncs::getLiveness(const CFGBlock* B) {
+ LiveVariables::BlockLivenessMap& BMap = L.getLiveAtBlockEntryMap();
+
+ LiveVariables::BlockLivenessMap::iterator I = BMap.find(B);
+ return (I == BMap.end()) ? NULL : &(I->second);
+}
+
+bool LivenessTFuncs::ProcessBlock(const CFGBlock* B) {
+ // First: merge all predecessors.
+ Live.reset();
+ Killed.reset();
+
+ for (CFGBlock::const_succ_iterator I=B->succ_begin(),E=B->succ_end();I!=E;++I)
+ if (llvm::BitVector* V = getLiveness(*I))
+ Live |= *V;
+
+ // Second: march up the statements and process the transfer functions.
+ for (CFGBlock::const_reverse_iterator I=B->rbegin(), E=B->rend(); I!=E; ++I) {
+ Visit(*I);
+ }
+
+ // Third: compare the computed "Live" values with what we already have
+ // for this block.
+ bool hasChanged = false;
+
+ LiveVariables::BlockLivenessMap& BMap = L.getLiveAtBlockEntryMap();
+ LiveVariables::BlockLivenessMap::iterator I = BMap.find(B);
+ if (I == BMap.end()) {
+ hasChanged = true;
+ llvm::BitVector& V = BMap[B];
+ V.resize(L.getNumDecls());
+ V |= Live;
+ }
+ else if (I->second != Live) {
+ hasChanged = true;
+ I->second = Live;
+ }
+
+ return hasChanged;
+}
+
+} // end anonymous namespace
+
+//===----------------------------------------------------------------------===//
+// runOnCFG - Method to run the actual liveness computation.
+//
+
+void LiveVariables::runOnCFG(const CFG& cfg) {
+ // Scan a CFG for DeclRefStmts. For each one, create a VarInfo object.
+ {
+ RegisterDecls R(*this,cfg);
+ R.RegisterUsedDecls();
+ }
+
+ // Create the worklist and enqueue the exit block.
+ WorkListTy WorkList;
+ WorkList.enqueue(&cfg.getExit());
+
+ // Create the state for transfer functions.
+ LivenessTFuncs TF(*this);
+
+ // Process the worklist until it is empty.
+
+ while (!WorkList.isEmpty()) {
+ const CFGBlock* B = WorkList.dequeue();
+ if (TF.ProcessBlock(B))
+ for (CFGBlock::const_pred_iterator I = B->pred_begin(), E = B->pred_end();
+ I != E; ++I)
+ WorkList.enqueue(*I);
+ }
+
+ // Go through each block and reserve a bitvector.
+ for (CFG::const_iterator I = cfg.begin(), E = cfg.end(); I != E; ++I)
+ LiveAtBlockEntryMap[&(*I)].resize(NumDecls);
+}
+
+//===----------------------------------------------------------------------===//
+// printing liveness state for debugging
+//
+
+void LiveVariables::printLiveness(const llvm::BitVector& V,
+ std::ostream& OS) const {
+
+ for (VarInfoMap::iterator I = VarInfos.begin(), E=VarInfos.end(); I!=E; ++I) {
+ if (V[I->second.Idx]) {
+ OS << I->first->getIdentifier()->getName() << "\n";
+ }
+ }
+}
+
+void LiveVariables::printBlockLiveness(std::ostream& OS) const {
+ for (BlockLivenessMap::iterator I = LiveAtBlockEntryMap.begin(),
+ E = LiveAtBlockEntryMap.end();
+ I != E; ++I) {
+ OS << "\n[ B" << I->first->getBlockID()
+ << " (live variables at block entry) ]\n";
+ printLiveness(I->second, OS);
+ }
+}
+
+void LiveVariables::DumpBlockLiveness() const {
+ printBlockLiveness(std::cerr);
+}
\ No newline at end of file
Added: cfe/trunk/Analysis/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Analysis/Makefile?rev=41737&view=auto
==============================================================================
--- cfe/trunk/Analysis/Makefile (added)
+++ cfe/trunk/Analysis/Makefile Wed Sep 5 19:17:54 2007
@@ -0,0 +1,22 @@
+##===- clang/CodeGen/Makefile ------------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by Ted Kremenek and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+#
+# This implements analyses built on top of source-level CFGs.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../..
+LIBRARYNAME := clangAnalysis
+BUILD_ARCHIVE = 1
+CXXFLAGS = -fno-rtti
+
+CPPFLAGS += -I$(PROJ_SRC_DIR)/../include
+
+include $(LEVEL)/Makefile.common
+
Modified: cfe/trunk/Driver/ASTStreamers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/ASTStreamers.cpp?rev=41737&r1=41736&r2=41737&view=diff
==============================================================================
--- cfe/trunk/Driver/ASTStreamers.cpp (original)
+++ cfe/trunk/Driver/ASTStreamers.cpp Wed Sep 5 19:17:54 2007
@@ -14,6 +14,7 @@
#include "ASTStreamers.h"
#include "clang/AST/AST.h"
#include "clang/AST/CFG.h"
+#include "clang/Analysis/LiveVariables.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/ASTStreamer.h"
using namespace clang;
@@ -184,4 +185,28 @@
ASTStreamer_Terminate(Streamer);
}
+void clang::AnalyzeLiveVariables(Preprocessor &PP, unsigned MainFileID)
+{
+ ASTContext Context(PP.getTargetInfo(), PP.getIdentifierTable());
+ ASTStreamerTy *Streamer = ASTStreamer_Init(PP, Context, MainFileID);
+
+ while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ if (FD->getBody()) {
+ PrintFunctionDeclStart(FD);
+ fprintf(stderr,"\n");
+ if (CFG* C = CFG::buildCFG(FD->getBody())) {
+ LiveVariables L;
+ L.runOnCFG(*C);
+ L.DumpBlockLiveness();
+ }
+ else
+ fprintf(stderr," Error processing CFG.\n");
+ }
+ }
+ }
+
+ ASTStreamer_Terminate(Streamer);
+}
+
Modified: cfe/trunk/Driver/ASTStreamers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/ASTStreamers.h?rev=41737&r1=41736&r2=41737&view=diff
==============================================================================
--- cfe/trunk/Driver/ASTStreamers.h (original)
+++ cfe/trunk/Driver/ASTStreamers.h Wed Sep 5 19:17:54 2007
@@ -26,6 +26,8 @@
void DumpCFGs(Preprocessor &PP, unsigned MainFileID,
bool Stats, bool use_graphviz = false);
+
+void AnalyzeLiveVariables(Preprocessor &PP, unsigned MainFileID);
} // end clang namespace
Modified: cfe/trunk/Driver/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/Makefile?rev=41737&r1=41736&r2=41737&view=diff
==============================================================================
--- cfe/trunk/Driver/Makefile (original)
+++ cfe/trunk/Driver/Makefile Wed Sep 5 19:17:54 2007
@@ -3,6 +3,6 @@
CXXFLAGS = -fno-rtti
TOOLNAME = clang
-USEDLIBS = clangCodeGen.a clangSEMA.a clangAST.a clangParse.a clangLex.a clangBasic.a LLVMCore.a LLVMSupport.a LLVMSystem.a
+USEDLIBS = clangCodeGen.a clangSEMA.a clangAnalysis.a clangAST.a clangParse.a clangLex.a clangBasic.a LLVMCore.a LLVMSupport.a LLVMSystem.a
include $(LEVEL)/Makefile.common
Modified: cfe/trunk/Driver/clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/clang.cpp?rev=41737&r1=41736&r2=41737&view=diff
==============================================================================
--- cfe/trunk/Driver/clang.cpp (original)
+++ cfe/trunk/Driver/clang.cpp Wed Sep 5 19:17:54 2007
@@ -54,6 +54,7 @@
ParseAST, // Parse ASTs.
ParseCFGDump, // Parse ASTS. Build CFGs. Print CFGs.
ParseCFGView, // Parse ASTS. Build CFGs. View CFGs (Graphviz).
+ AnalysisLiveVariables, // Print results of live-variable analysis.
ParsePrintCallbacks, // Parse and print each callback.
ParseSyntaxOnly, // Parse and perform semantic analysis.
ParseNoop, // Parse with noop callbacks.
@@ -89,9 +90,11 @@
clEnumValN(ParseCFGDump, "dump-cfg",
"Run parser, then build and print CFGs."),
clEnumValN(ParseCFGView, "view-cfg",
- "Run parser, then build and view CFGs with Graphviz."),
+ "Run parser, then build and view CFGs with Graphviz."),
+ clEnumValN(AnalysisLiveVariables, "dump-live-variables",
+ "Run parser and print results of live variable analysis."),
clEnumValN(EmitLLVM, "emit-llvm",
- "Build ASTs then convert to LLVM, emit .ll file"),
+ "Build ASTs then convert to LLVM, emit .ll file"),
clEnumValEnd));
//===----------------------------------------------------------------------===//
@@ -846,6 +849,9 @@
case ParseCFGView:
DumpCFGs(PP, MainFileID, Stats, true);
break;
+ case AnalysisLiveVariables:
+ AnalyzeLiveVariables(PP, MainFileID);
+ break;
case EmitLLVM:
EmitLLVMFromASTs(PP, MainFileID, Stats);
break;
Modified: cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=41737&r1=41736&r2=41737&view=diff
==============================================================================
--- cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/trunk/clang.xcodeproj/project.pbxproj Wed Sep 5 19:17:54 2007
@@ -13,6 +13,7 @@
1A869AA80BA21ABA008DA07A /* LiteralSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */; };
1ABC36940C7A4BDC006DB0AB /* CGBuiltin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */; };
35260CA50C7F75C000D66CE9 /* ExprCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 35260CA40C7F75C000D66CE9 /* ExprCXX.cpp */; };
+ 356EF9B50C8F7DDF006650F5 /* LiveVariables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 356EF9B40C8F7DDF006650F5 /* LiveVariables.cpp */; };
84D9A8880C1A57E100AC7ABC /* AttributeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */; };
84D9A88C0C1A581300AC7ABC /* AttributeList.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 84D9A88B0C1A581300AC7ABC /* AttributeList.h */; };
DE01DA490B12ADA300AC22CE /* PPCallbacks.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE01DA480B12ADA300AC22CE /* PPCallbacks.h */; };
@@ -209,6 +210,8 @@
1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CGBuiltin.cpp; path = CodeGen/CGBuiltin.cpp; sourceTree = "<group>"; };
35260CA40C7F75C000D66CE9 /* ExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ExprCXX.cpp; path = AST/ExprCXX.cpp; sourceTree = "<group>"; };
3547129D0C88881300B3E1D5 /* PrettyPrinter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PrettyPrinter.h; path = clang/AST/PrettyPrinter.h; sourceTree = "<group>"; };
+ 356EF9B20C8F7DBA006650F5 /* LiveVariables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LiveVariables.h; path = clang/Analysis/LiveVariables.h; sourceTree = "<group>"; };
+ 356EF9B40C8F7DDF006650F5 /* LiveVariables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LiveVariables.cpp; path = Analysis/LiveVariables.cpp; sourceTree = "<group>"; };
84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = Parse/AttributeList.cpp; sourceTree = "<group>"; };
84D9A88B0C1A581300AC7ABC /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Parse/AttributeList.h; sourceTree = "<group>"; };
8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -361,6 +364,7 @@
DEC8D9920A9433F400353FCA /* AST */,
DE67E7070C020EAB00F66BC5 /* Sema */,
DE927FCC0C0557CD00231DA4 /* CodeGen */,
+ 356EF9B30C8F7DCA006650F5 /* Analysis */,
);
name = Source;
sourceTree = "<group>";
@@ -373,6 +377,22 @@
name = Products;
sourceTree = "<group>";
};
+ 356EF9AF0C8F7DA4006650F5 /* Analysis */ = {
+ isa = PBXGroup;
+ children = (
+ 356EF9B20C8F7DBA006650F5 /* LiveVariables.h */,
+ );
+ name = Analysis;
+ sourceTree = "<group>";
+ };
+ 356EF9B30C8F7DCA006650F5 /* Analysis */ = {
+ isa = PBXGroup;
+ children = (
+ 356EF9B40C8F7DDF006650F5 /* LiveVariables.cpp */,
+ );
+ name = Analysis;
+ sourceTree = "<group>";
+ };
C6859E8C029090F304C91782 /* Documentation */ = {
isa = PBXGroup;
children = (
@@ -539,6 +559,7 @@
DEC8D98B0A9433BC00353FCA /* AST */,
DE67E7260C02108300F66BC5 /* Sema */,
DE928B140C05659A00231DA4 /* CodeGen */,
+ 356EF9AF0C8F7DA4006650F5 /* Analysis */,
);
path = include;
sourceTree = "<group>";
@@ -637,6 +658,7 @@
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
+ compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 1;
mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
projectDirPath = "";
@@ -718,6 +740,7 @@
DE2252700C7E82D000D370A5 /* CGExprScalar.cpp in Sources */,
35260CA50C7F75C000D66CE9 /* ExprCXX.cpp in Sources */,
DE2255FC0C8004E600D370A5 /* ParseDeclCXX.cpp in Sources */,
+ 356EF9B50C8F7DDF006650F5 /* LiveVariables.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Added: cfe/trunk/include/clang/Analysis/LiveVariables.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/LiveVariables.h?rev=41737&view=auto
==============================================================================
--- cfe/trunk/include/clang/Analysis/LiveVariables.h (added)
+++ cfe/trunk/include/clang/Analysis/LiveVariables.h Wed Sep 5 19:17:54 2007
@@ -0,0 +1,111 @@
+//===- LiveVariables.h - Live Variable Analysis for Source CFGs -*- C++ --*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Ted Kremenek and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements Live Variables analysis for source-level CFGs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIVEVARIABLES_H
+#define LLVM_CLANG_LIVEVARIABLES_H
+
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include <iosfwd>
+#include <vector>
+
+namespace clang {
+
+ class Stmt;
+ class DeclRefStmt;
+ class Decl;
+ class CFG;
+ class CFGBlock;
+
+class LiveVariables {
+public:
+
+ struct VarInfo {
+ /// AliveBlocks - Set of blocks of which this value is alive completely
+ /// through. This is a bit set which uses the basic block number as an
+ /// index.
+ llvm::BitVector AliveBlocks;
+
+ /// Kills - List of statements which are the last use of a variable
+ /// (kill it) in their basic block. The first pointer in the pair
+ /// is the statement in the list of statements of a basic block where
+ /// this occurs, while the DeclRefStmt is the subexpression of this
+ /// statement where the actual last reference takes place.
+ std::vector< std::pair<const Stmt*,const DeclRefStmt*> > Kills;
+
+ void print(std::ostream& OS) const;
+ };
+
+ struct VPair {
+ VarInfo V;
+ unsigned Idx;
+ };
+
+ typedef llvm::DenseMap<const Decl*, VPair > VarInfoMap;
+ typedef llvm::DenseMap<const CFGBlock*, llvm::BitVector > BlockLivenessMap;
+
+public:
+
+ LiveVariables() : NumDecls(0) {}
+
+ /// runOnCFG - Computes live variable information for a given CFG.
+ void runOnCFG(const CFG& cfg);
+
+ /// KillsVar - Return true if the specified statement kills the
+ /// specified variable.
+ bool KillsVar(const Stmt* S, const Decl* D) const;
+
+ /// IsLive - Return true if a variable is live at beginning of a specified
+ // block.
+ bool IsLive(const CFGBlock* B, const Decl* D) const;
+
+ /// getVarInfo - Return the liveness information associated with a given
+ /// variable.
+ VarInfo& getVarInfo(const Decl* D);
+
+ const VarInfo& getVarInfo(const Decl* D) const;
+
+ /// getVarInfoMap
+ VarInfoMap& getVarInfoMap() { return VarInfos; }
+
+ const VarInfoMap& getVarInfoMap() const { return VarInfos; }
+
+ // printLiveness
+ void printLiveness(const llvm::BitVector& V, std::ostream& OS) const;
+
+ // printBlockLiveness
+ void printBlockLiveness(std::ostream& OS) const;
+ void DumpBlockLiveness() const;
+
+ // getLiveAtBlockEntryMap
+ BlockLivenessMap& getLiveAtBlockEntryMap() { return LiveAtBlockEntryMap; }
+
+ const BlockLivenessMap& getLiveAtBlockEntryMap() const {
+ return LiveAtBlockEntryMap;
+ }
+
+ // getNumDecls
+ unsigned& getNumDecls() { return NumDecls; }
+ unsigned getNumDecls() const { return NumDecls; }
+
+protected:
+
+ unsigned NumDecls;
+ VarInfoMap VarInfos;
+ BlockLivenessMap LiveAtBlockEntryMap;
+
+};
+
+} // end namespace clang
+
+#endif
More information about the cfe-commits
mailing list