forked from OSchip/llvm-project
Hooked up the GRConstants analysis to the driver.
Fixed some compilation errors with GREngine that showed up during template instantiation. llvm-svn: 46074
This commit is contained in:
parent
aebbe4700a
commit
2e12c2e790
|
@ -288,4 +288,14 @@ void GRConstants::VisitBinAdd(BinaryOperator* B) {
|
||||||
void GRConstants::VisitBinSub(BinaryOperator* B) {
|
void GRConstants::VisitBinSub(BinaryOperator* B) {
|
||||||
AddBinding(B, GetBinding(B->getLHS()) - GetBinding(B->getRHS()));
|
AddBinding(B, GetBinding(B->getLHS()) - GetBinding(B->getRHS()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Driver.
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
namespace clang {
|
||||||
|
void RunGRConstants(CFG& cfg) {
|
||||||
|
GREngine<GRConstants> Engine(cfg);
|
||||||
|
Engine.ExecuteWorkList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -44,6 +44,10 @@ public:
|
||||||
};
|
};
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
|
// Place the dstor for GRWorkList here because it contains virtual member
|
||||||
|
// functions, and we the code for the dstor generated in one compilation unit.
|
||||||
|
GRWorkList::~GRWorkList() {}
|
||||||
|
|
||||||
GRWorkList* GRWorkList::MakeDFS() { return new DFS(); }
|
GRWorkList* GRWorkList::MakeDFS() { return new DFS(); }
|
||||||
|
|
||||||
/// ExecuteWorkList - Run the worklist algorithm for a maximum number of steps.
|
/// ExecuteWorkList - Run the worklist algorithm for a maximum number of steps.
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "clang/AST/ASTConsumer.h"
|
#include "clang/AST/ASTConsumer.h"
|
||||||
#include "clang/AST/CFG.h"
|
#include "clang/AST/CFG.h"
|
||||||
#include "clang/Analysis/Analyses/LiveVariables.h"
|
#include "clang/Analysis/Analyses/LiveVariables.h"
|
||||||
|
#include "clang/Analysis/Analyses/GRConstants.h"
|
||||||
#include "clang/Analysis/LocalCheckers.h"
|
#include "clang/Analysis/LocalCheckers.h"
|
||||||
#include "llvm/Support/Streams.h"
|
#include "llvm/Support/Streams.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -562,22 +563,21 @@ ASTConsumer *clang::CreateUnitValsChecker(Diagnostic &Diags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// GRConstProp - Perform intra-procedural, path-sensitive constant propagation.
|
// GRConstants - Perform intra-procedural, path-sensitive constant propagation.
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class GRConstPropVisitor : public CFGVisitor {
|
class GRConstantsVisitor : public CFGVisitor {
|
||||||
public:
|
public:
|
||||||
virtual void Initialize(ASTContext &Context) {}
|
virtual void Initialize(ASTContext &Context) {}
|
||||||
|
|
||||||
virtual void VisitCFG(CFG& C) {
|
virtual void VisitCFG(CFG& C) {
|
||||||
// FIXME: Implement.
|
RunGRConstants(C);
|
||||||
assert (false && "Not yet implemented.");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
ASTConsumer *clang::CreateGRConstProp() {
|
ASTConsumer *clang::CreateGRConstants() {
|
||||||
return new GRConstPropVisitor();
|
return new GRConstantsVisitor();
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -39,7 +39,7 @@ ASTConsumer *CreateDeadStoreChecker(Diagnostic &Diags);
|
||||||
|
|
||||||
ASTConsumer *CreateUnitValsChecker(Diagnostic &Diags);
|
ASTConsumer *CreateUnitValsChecker(Diagnostic &Diags);
|
||||||
|
|
||||||
ASTConsumer *CreateGRConstProp();
|
ASTConsumer *CreateGRConstants();
|
||||||
|
|
||||||
ASTConsumer *CreateLLVMEmitter(Diagnostic &Diags, const LangOptions &Features);
|
ASTConsumer *CreateLLVMEmitter(Diagnostic &Diags, const LangOptions &Features);
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ enum ProgActions {
|
||||||
ParseCFGDump, // Parse ASTS. Build CFGs. Print CFGs.
|
ParseCFGDump, // Parse ASTS. Build CFGs. Print CFGs.
|
||||||
ParseCFGView, // Parse ASTS. Build CFGs. View CFGs.
|
ParseCFGView, // Parse ASTS. Build CFGs. View CFGs.
|
||||||
AnalysisLiveVariables, // Print results of live-variable analysis.
|
AnalysisLiveVariables, // Print results of live-variable analysis.
|
||||||
AnalysisGRConstProp, // Perform graph-reachability constant prop.
|
AnalysisGRConstants, // Perform graph-reachability constant prop.
|
||||||
WarnDeadStores, // Run DeadStores checker on parsed ASTs.
|
WarnDeadStores, // Run DeadStores checker on parsed ASTs.
|
||||||
WarnDeadStoresCheck, // Check diagnostics for "DeadStores".
|
WarnDeadStoresCheck, // Check diagnostics for "DeadStores".
|
||||||
WarnUninitVals, // Run UnitializedVariables checker.
|
WarnUninitVals, // Run UnitializedVariables checker.
|
||||||
|
@ -109,7 +109,7 @@ ProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore,
|
||||||
"Flag warnings of stores to dead variables."),
|
"Flag warnings of stores to dead variables."),
|
||||||
clEnumValN(WarnUninitVals, "warn-uninit-values",
|
clEnumValN(WarnUninitVals, "warn-uninit-values",
|
||||||
"Flag warnings of uses of unitialized variables."),
|
"Flag warnings of uses of unitialized variables."),
|
||||||
clEnumValN(AnalysisGRConstProp, "gr-const-prop",
|
clEnumValN(AnalysisGRConstants, "gr-const-prop",
|
||||||
"Perform path-sensitive constant propagation."),
|
"Perform path-sensitive constant propagation."),
|
||||||
clEnumValN(TestSerialization, "test-pickling",
|
clEnumValN(TestSerialization, "test-pickling",
|
||||||
"Run prototype serializtion code."),
|
"Run prototype serializtion code."),
|
||||||
|
@ -947,8 +947,8 @@ static ASTConsumer* CreateASTConsumer(const std::string& InFile,
|
||||||
case WarnUninitVals:
|
case WarnUninitVals:
|
||||||
return CreateUnitValsChecker(Diag);
|
return CreateUnitValsChecker(Diag);
|
||||||
|
|
||||||
case AnalysisGRConstProp:
|
case AnalysisGRConstants:
|
||||||
return CreateGRConstProp();
|
return CreateGRConstants();
|
||||||
|
|
||||||
case TestSerialization:
|
case TestSerialization:
|
||||||
return CreateSerializationTest(Diag, FileMgr, LangOpts);
|
return CreateSerializationTest(Diag, FileMgr, LangOpts);
|
||||||
|
|
|
@ -40,9 +40,17 @@ protected:
|
||||||
enum { Size1 = 0x0, SizeOther = 0x1, Infeasible = 0x2, Flags = 0x3 };
|
enum { Size1 = 0x0, SizeOther = 0x1, Infeasible = 0x2, Flags = 0x3 };
|
||||||
uintptr_t P;
|
uintptr_t P;
|
||||||
|
|
||||||
unsigned getKind() const { return P & Flags; }
|
unsigned getKind() const {
|
||||||
void* getPtr() const { return reinterpret_cast<void*>(P & ~Flags); }
|
return P & Flags;
|
||||||
ExplodedNodeImpl* getNode() const;
|
}
|
||||||
|
|
||||||
|
void* getPtr() const {
|
||||||
|
return reinterpret_cast<void*>(P & ~Flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExplodedNodeImpl* getNode() const {
|
||||||
|
return reinterpret_cast<ExplodedNodeImpl*>(getPtr());
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NodeGroup() : P(0) {}
|
NodeGroup() : P(0) {}
|
||||||
|
@ -136,8 +144,8 @@ class ExplodedNode : public ExplodedNodeImpl {
|
||||||
public:
|
public:
|
||||||
/// Construct a ExplodedNodeImpl with the given node ID, program edge,
|
/// Construct a ExplodedNodeImpl with the given node ID, program edge,
|
||||||
/// and state.
|
/// and state.
|
||||||
explicit ExplodedNode(unsigned ID, const ProgramPoint& loc, StateTy state)
|
explicit ExplodedNode(const ProgramPoint& loc, StateTy state)
|
||||||
: ExplodedNodeImpl(ID, loc, GRTrait<StateTy>::toPtr(state)) {}
|
: ExplodedNodeImpl(loc, GRTrait<StateTy>::toPtr(state)) {}
|
||||||
|
|
||||||
/// getState - Returns the state associated with the node.
|
/// getState - Returns the state associated with the node.
|
||||||
inline StateTy getState() const {
|
inline StateTy getState() const {
|
||||||
|
@ -186,13 +194,7 @@ protected:
|
||||||
typedef llvm::DenseMap<ProgramPoint,void*> EdgeNodeSetMap;
|
typedef llvm::DenseMap<ProgramPoint,void*> EdgeNodeSetMap;
|
||||||
typedef llvm::SmallVector<ExplodedNodeImpl*,2> RootsTy;
|
typedef llvm::SmallVector<ExplodedNodeImpl*,2> RootsTy;
|
||||||
typedef llvm::SmallVector<ExplodedNodeImpl*,10> EndNodesTy;
|
typedef llvm::SmallVector<ExplodedNodeImpl*,10> EndNodesTy;
|
||||||
|
|
||||||
/// NodeCounter - The number of nodes that have been created, although
|
|
||||||
/// this need not be the current number of nodes in the graph that
|
|
||||||
/// are reachable from the roots. This counter is used to assign a unique
|
|
||||||
/// number to each node (which is useful for debugging).
|
|
||||||
unsigned NodeCounter;
|
|
||||||
|
|
||||||
/// Roots - The roots of the simulation graph. Usually there will be only
|
/// Roots - The roots of the simulation graph. Usually there will be only
|
||||||
/// one, but clients are free to establish multiple subgraphs within a single
|
/// one, but clients are free to establish multiple subgraphs within a single
|
||||||
/// SimulGraph. Moreover, these subgraphs can often merge when paths from
|
/// SimulGraph. Moreover, these subgraphs can often merge when paths from
|
||||||
|
@ -232,7 +234,6 @@ public:
|
||||||
|
|
||||||
unsigned num_roots() const { return Roots.size(); }
|
unsigned num_roots() const { return Roots.size(); }
|
||||||
unsigned num_eops() const { return EndNodes.size(); }
|
unsigned num_eops() const { return EndNodes.size(); }
|
||||||
unsigned getCounter() const { return NodeCounter; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename CHECKER>
|
template <typename CHECKER>
|
||||||
|
@ -248,7 +249,7 @@ protected:
|
||||||
protected:
|
protected:
|
||||||
virtual ExplodedNodeImpl*
|
virtual ExplodedNodeImpl*
|
||||||
getNodeImpl(const ProgramPoint& L, void* State, bool* IsNew) {
|
getNodeImpl(const ProgramPoint& L, void* State, bool* IsNew) {
|
||||||
return getNode(L,GRTrait<StateTy>::toState(State),IsNew);
|
return getNode(L, GRTrait<StateTy>::toState(State), IsNew);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -275,15 +276,15 @@ public:
|
||||||
void* InsertPos = 0;
|
void* InsertPos = 0;
|
||||||
|
|
||||||
StateTy::Profile(profile, State);
|
StateTy::Profile(profile, State);
|
||||||
NodeTy* V = VSet.FindNodeOrInsertPos(profile, InsertPos);
|
NodeTy* V = VSet->FindNodeOrInsertPos(profile, InsertPos);
|
||||||
|
|
||||||
if (!V) {
|
if (!V) {
|
||||||
// Allocate a new node.
|
// Allocate a new node.
|
||||||
V = (NodeTy*) Allocator.Allocate<NodeTy>();
|
V = (NodeTy*) Allocator.Allocate<NodeTy>();
|
||||||
new (V) NodeTy(NodeCounter++, L, State);
|
new (V) NodeTy(L, State);
|
||||||
|
|
||||||
// Insert the node into the node set and return it.
|
// Insert the node into the node set and return it.
|
||||||
VSet.InsertNode(V, InsertPos);
|
VSet->InsertNode(V, InsertPos);
|
||||||
|
|
||||||
if (IsNew) *IsNew = true;
|
if (IsNew) *IsNew = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,7 +173,7 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
virtual void* getInitialState() {
|
virtual void* getInitialState() {
|
||||||
return GRTrait<StateTy>::toPtr(getCheckerState()->getInitialState());
|
return GRTrait<StateTy>::toPtr(getCheckerState().getInitialState());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void* ProcessEOP(CFGBlock* Blk, void* State) {
|
virtual void* ProcessEOP(CFGBlock* Blk, void* State) {
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
|
|
||||||
class GRWorkList {
|
class GRWorkList {
|
||||||
public:
|
public:
|
||||||
virtual ~GRWorkList() = 0;
|
virtual ~GRWorkList();
|
||||||
virtual bool hasWork() const = 0;
|
virtual bool hasWork() const = 0;
|
||||||
virtual void Enqueue(const GRWorkListUnit& U) = 0;
|
virtual void Enqueue(const GRWorkListUnit& U) = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue