Skip to content

Commit 0f292a9

Browse files
committed
add selective build and update policy generation pass
1 parent 38f8da8 commit 0f292a9

27 files changed

Lines changed: 2029 additions & 644 deletions

include/ControlDepLib.hh

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
//===- IntraProc/ControlDependenceGraph.h -----------------------*- C++ -*-===//
2+
//
3+
// Static Program Analysis for LLVM
4+
//
5+
// This file is distributed under a Modified BSD License (see LICENSE.TXT).
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file defines the ControlDependenceGraph class, which allows fast and
10+
// efficient control dependence queries. It is based on Ferrante et al's "The
11+
// Program Dependence Graph and Its Use in Optimization."
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
#ifndef ANALYSIS_CONTROLDEPENDENCEGRAPH_H
16+
#define ANALYSIS_CONTROLDEPENDENCEGRAPH_H
17+
18+
#include "llvm/ADT/DepthFirstIterator.h"
19+
#include "llvm/ADT/GraphTraits.h"
20+
#include "llvm/Analysis/PostDominators.h"
21+
#include "llvm/IR/Module.h"
22+
#include "llvm/Pass.h"
23+
#include "llvm/Support/DOTGraphTraits.h"
24+
25+
#include <map>
26+
#include <set>
27+
#include <iterator>
28+
29+
namespace llvm {
30+
31+
class BasicBlock;
32+
class ControlDependenceGraphBase;
33+
34+
class ControlDependenceNode {
35+
public:
36+
enum EdgeType { TRUE, FALSE, OTHER };
37+
typedef std::set<ControlDependenceNode *>::iterator node_iterator;
38+
typedef std::set<ControlDependenceNode *>::const_iterator const_node_iterator;
39+
40+
struct edge_iterator {
41+
typedef node_iterator::value_type value_type;
42+
typedef node_iterator::difference_type difference_type;
43+
typedef node_iterator::reference reference;
44+
typedef node_iterator::pointer pointer;
45+
typedef std::input_iterator_tag iterator_category;
46+
47+
edge_iterator(ControlDependenceNode *n) :
48+
node(n), stage(TRUE), it(n->TrueChildren.begin()), end(n->TrueChildren.end()) {
49+
while ((stage != OTHER) && (it == end)) this->operator++();
50+
}
51+
edge_iterator(ControlDependenceNode *n, EdgeType t, node_iterator i, node_iterator e) :
52+
node(n), stage(t), it(i), end(e) {
53+
while ((stage != OTHER) && (it == end)) this->operator++();
54+
}
55+
EdgeType type() const { return stage; }
56+
bool operator==(edge_iterator const &other) const {
57+
return (this->stage == other.stage) && (this->it == other.it);
58+
}
59+
bool operator!=(edge_iterator const &other) const { return !(*this == other); }
60+
reference operator*() { return *this->it; }
61+
pointer operator->() { return &*this->it; }
62+
edge_iterator& operator++() {
63+
if (it != end) ++it;
64+
while ((stage != OTHER) && (it == end)) {
65+
if (stage == TRUE) {
66+
it = node->FalseChildren.begin();
67+
end = node->FalseChildren.end();
68+
stage = FALSE;
69+
} else {
70+
it = node->OtherChildren.begin();
71+
end = node->OtherChildren.end();
72+
stage = OTHER;
73+
}
74+
}
75+
return *this;
76+
}
77+
edge_iterator operator++(int) {
78+
edge_iterator ret(*this);
79+
assert(ret.stage == OTHER || ret.it != ret.end);
80+
this->operator++();
81+
return ret;
82+
}
83+
private:
84+
ControlDependenceNode *node;
85+
EdgeType stage;
86+
node_iterator it, end;
87+
};
88+
89+
edge_iterator begin() { return edge_iterator(this); }
90+
edge_iterator end() { return edge_iterator(this, OTHER, OtherChildren.end(), OtherChildren.end()); }
91+
92+
node_iterator true_begin() { return TrueChildren.begin(); }
93+
node_iterator true_end() { return TrueChildren.end(); }
94+
95+
node_iterator false_begin() { return FalseChildren.begin(); }
96+
node_iterator false_end() { return FalseChildren.end(); }
97+
98+
node_iterator other_begin() { return OtherChildren.begin(); }
99+
node_iterator other_end() { return OtherChildren.end(); }
100+
101+
node_iterator parent_begin() { return Parents.begin(); }
102+
node_iterator parent_end() { return Parents.end(); }
103+
const_node_iterator parent_begin() const { return Parents.begin(); }
104+
const_node_iterator parent_end() const { return Parents.end(); }
105+
106+
BasicBlock *getBlock() const { return TheBB; }
107+
size_t getNumParents() const { return Parents.size(); }
108+
size_t getNumChildren() const {
109+
return TrueChildren.size() + FalseChildren.size() + OtherChildren.size();
110+
}
111+
bool isRegion() const { return TheBB == NULL; }
112+
const ControlDependenceNode *enclosingRegion() const;
113+
114+
private:
115+
BasicBlock *TheBB;
116+
std::set<ControlDependenceNode *> Parents;
117+
std::set<ControlDependenceNode *> TrueChildren;
118+
std::set<ControlDependenceNode *> FalseChildren;
119+
std::set<ControlDependenceNode *> OtherChildren;
120+
121+
friend class ControlDependenceGraphBase;
122+
123+
void clearAllChildren() {
124+
TrueChildren.clear();
125+
FalseChildren.clear();
126+
OtherChildren.clear();
127+
}
128+
void clearAllParents() { Parents.clear(); }
129+
130+
void addTrue(ControlDependenceNode *Child);
131+
void addFalse(ControlDependenceNode *Child);
132+
void addOther(ControlDependenceNode *Child);
133+
void addParent(ControlDependenceNode *Parent);
134+
void removeTrue(ControlDependenceNode *Child);
135+
void removeFalse(ControlDependenceNode *Child);
136+
void removeOther(ControlDependenceNode *Child);
137+
void removeParent(ControlDependenceNode *Child);
138+
139+
ControlDependenceNode() : TheBB(NULL) {}
140+
ControlDependenceNode(BasicBlock *bb) : TheBB(bb) {}
141+
};
142+
143+
class ControlDependenceGraphBase {
144+
public:
145+
ControlDependenceGraphBase() : root(NULL) {}
146+
virtual ~ControlDependenceGraphBase() { releaseMemory(); }
147+
virtual void releaseMemory() {
148+
for (ControlDependenceNode::node_iterator n = nodes.begin(), e = nodes.end();
149+
n != e; ++n) delete *n;
150+
nodes.clear();
151+
bbMap.clear();
152+
root = NULL;
153+
}
154+
155+
void graphForFunction(Function &F, PostDominatorTree &pdt);
156+
157+
ControlDependenceNode *getRoot() { return root; }
158+
const ControlDependenceNode *getRoot() const { return root; }
159+
ControlDependenceNode *operator[](const BasicBlock *BB) { return getNode(BB); }
160+
const ControlDependenceNode *operator[](const BasicBlock *BB) const { return getNode(BB); }
161+
ControlDependenceNode *getNode(const BasicBlock *BB) {
162+
return bbMap[BB];
163+
}
164+
const ControlDependenceNode *getNode(const BasicBlock *BB) const {
165+
return (bbMap.find(BB) != bbMap.end()) ? bbMap.find(BB)->second : NULL;
166+
}
167+
bool controls(BasicBlock *A, BasicBlock *B) const;
168+
bool influences(BasicBlock *A, BasicBlock *B) const;
169+
const ControlDependenceNode *enclosingRegion(BasicBlock *BB) const;
170+
171+
private:
172+
ControlDependenceNode *root;
173+
std::set<ControlDependenceNode *> nodes;
174+
std::map<const BasicBlock *,ControlDependenceNode *> bbMap;
175+
static ControlDependenceNode::EdgeType getEdgeType(const BasicBlock *, const BasicBlock *);
176+
void computeDependencies(Function &F, PostDominatorTree &pdt);
177+
void insertRegions(PostDominatorTree &pdt);
178+
};
179+
180+
class ControlDependenceGraph : public FunctionPass, public ControlDependenceGraphBase {
181+
public:
182+
static char ID;
183+
184+
ControlDependenceGraph() : FunctionPass(ID), ControlDependenceGraphBase() {}
185+
virtual ~ControlDependenceGraph() { }
186+
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
187+
AU.addRequired<PostDominatorTreeWrapperPass>();
188+
AU.setPreservesAll();
189+
}
190+
virtual bool runOnFunction(Function &F) {
191+
PostDominatorTree &pdt = getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
192+
graphForFunction(F,pdt);
193+
return false;
194+
}
195+
};
196+
197+
} // namespace llvm
198+
199+
#endif // ANALYSIS_CONTROLDEPENDENCEGRAPH_H

include/ControlDependencyGraph.hh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#define CONTROLDEPENDENCYGRAPH_H_
33
#include "Graph.hh"
44
#include "PDGCallGraph.hh"
5-
#include "llvm/Analysis/PostDominators.h"
5+
#include "ControlDepLib.hh"
66

77
namespace pdg
88
{
@@ -17,8 +17,9 @@ namespace pdg
1717
void addControlDepFromNodeToBB(Node &n, llvm::BasicBlock &bb, EdgeType edge_type);
1818
void addControlDepFromEntryNodeToEntryBlock(llvm::Function &F);
1919
void addControlDepFromDominatedBlockToDominator(llvm::Function &F);
20+
std::unordered_set<llvm::BasicBlock *> findAllIntraprocSuccBB(llvm::BasicBlock &BB);
2021
private:
21-
llvm::PostDominatorTree *_PDT;
22+
llvm::ControlDependenceGraph *_CDG;
2223
};
2324
} // namespace pdg
2425

include/FunctionWrapper.hh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ namespace pdg
4545
bool hasNullRetVal() { return (_retValFormalInTree == nullptr); }
4646
std::set<llvm::Value *> computeAddrVarDerivedFromArg(llvm::Argument &arg);
4747
int getArgIdxByFormalInTree(Tree* tree);
48+
void setControlDepBuilt() { hasControlDep = true; }
49+
bool hasControlDepBuilt() { return hasControlDep; }
4850

4951
private:
5052
Node *_entryNode;
@@ -61,6 +63,7 @@ namespace pdg
6163
std::map<llvm::Argument *, Tree *> _argFormalOutTreeMap;
6264
Tree *_retValFormalInTree;
6365
Tree *_retValFormalOutTree;
66+
bool hasControlDep= false;
6467

6568
};
6669
} // namespace pdg

include/Graph.hh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ namespace pdg
4141
void setIsBuild() { _isBuild = true; }
4242
bool isBuild() { return _isBuild; }
4343
bool canReach(Node &src, Node &dst, std::set<EdgeType> &includeEdgeTypes, std::set<std::vector<llvm::Function *>> *allPaths, bool recordPath);
44+
bool canReach(Node &src, Node &dst, std::set<EdgeType> &edgeTypes);
45+
bool canReachIntraproc(Node &src, Node &dst, std::set<EdgeType> &edgeTypes);
4446
void dfs(Node *currentNode, Node &dst, std::set<EdgeType> &includeEdgeTypes, std::unordered_set<Node *> &visited, std::vector<llvm::Function *> &currentPath, std::set<std::vector<llvm::Function *>> *allPaths, bool recordPath);
4547
std::unordered_set<Node *> findNodesReachedByEdge(Node &src, EdgeType edgeTy, bool isIntra = false);
4648
std::unordered_set<Node *> findNodesReachedByEdges(Node &src, std::set<EdgeType> &edgeTypes, bool isBackward = false);
@@ -65,6 +67,9 @@ namespace pdg
6567
typedef std::unordered_map<llvm::CallInst *, CallWrapper *> CallWrapperMap;
6668
typedef std::unordered_map<Node *, llvm::DIType *> NodeDIMap;
6769
typedef std::unordered_map<llvm::GlobalVariable*, Tree*> GlobalVarTreeMap;
70+
std::set<std::string> iFuncNames;
71+
std::set<llvm::Function *> interfaceFuncs;
72+
std::unordered_set<llvm::Function*> funcToBuild;
6873

6974
ProgramGraph() = default;
7075
ProgramGraph(const ProgramGraph &) = delete;

include/GraphWriter.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ namespace llvm
7676
switch (edgeTy)
7777
{
7878
case pdg::EdgeType::CONTROL:
79-
return "";
79+
return "label = \"{C}\"";
8080
case pdg::EdgeType::DATA_DEF_USE:
8181
return "style=dotted,label = \"{DEF_USE}\" ";
8282
case pdg::EdgeType::DATA_ALIAS:

include/KSplitStatsCollector.hh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,9 @@ namespace pdg
220220
unsigned _char_array_num = 0;
221221
unsigned _struct_array_num = 0;
222222
unsigned _unknown_ptr_num = 0;
223+
224+
// SoK related
225+
unsigned _drv_read_fields = 0;
223226
};
224227
}
225228

include/LLVMEssentials.hh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@
2121
namespace pdg
2222
{
2323
extern bool EnableAnalysisStats;
24+
extern bool OnlyControlledPath;
2425
extern bool DEBUG;
26+
extern bool SingleFuncAnalysis;
27+
extern std::string TargetFuncNameStr;
28+
extern llvm::cl::opt<std::string> TargetFuncName;
2529
}
2630

2731
#endif

include/PDGEnums.hh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ namespace pdg
2222
CONTROL_FLOW, // control flow edges
2323
DATA_DEF_USE,
2424
DATA_RAW,
25-
DATA_RAW_REV,
26-
DATA_READ,
25+
DATA_DEF_USE_LOAD,
26+
DATA_DEF_USE_GEP,
27+
DATA_DEF_USE_CAST,
28+
DATA_DEF_USE_ARITH,
2729
DATA_MAY_ALIAS,
2830
DATA_MUST_ALIAS,
2931
DATA_ALIAS,

include/PDGUtils.hh

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ namespace pdg
2727
bool hasReadAccess(llvm::Value &v);
2828
bool hasWriteAccess(llvm::Value &v);
2929
bool hasPtrDereference(llvm::Value &v);
30+
bool hasUpdateThroughPtr(llvm::Value &v);
3031
bool hasDoubleLoad(llvm::Value &v);
32+
bool hasWriteAfterLoad(llvm::Value &v);
3133
bool isSentinelType(llvm::GlobalVariable &gv);
3234
bool isUserOfSentinelTypeVal(llvm::Value &v);
3335
bool isVoidPointerHasMultipleCasts(TreeNode &treeNode);
@@ -71,8 +73,7 @@ namespace pdg
7173
void readLinesFromFile(std::set<std::string> &lines, std::string fileName);
7274
void printSourceLocation(llvm::Instruction &I, llvm::raw_ostream &OutputStream = llvm::errs());
7375
unsigned getSourceLineNo(llvm::Instruction &I);
74-
std::string getSourceLocationStr(llvm::Instruction &I);
75-
std::string getSourceLocationStrForInlineInst(llvm::Instruction &I);
76+
std::string getSourceLocationStr(llvm::Instruction &I, bool isInline=true);
7677
std::string getInstructionString(llvm::Instruction &I);
7778
llvm::DILocation* getTopDebugLocation(llvm::DILocation *DL);
7879
std::string getFuncSourceLocStr(llvm::Function &F);
@@ -81,6 +82,8 @@ namespace pdg
8182
unsigned computeFieldUniqueId(unsigned funcId, unsigned argIdx, unsigned fieldOffset);
8283
std::string edgeTypeToString(EdgeType edgeType);
8384
std::string nodeTypeToString(GraphNodeType nodeType);
85+
std::string riskyDataTypeToString(RiskyDataType riskyDataType);
86+
bool isTargetFunc(llvm::Function &F);
8487
} // namespace pdgutils
8588
} // namespace pdg
8689
#endif

include/ProgramDependencyGraph.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include "Graph.hh"
55
#include "PDGCallGraph.hh"
66
#include "DataDependencyGraph.hh"
7-
#include "ControlDependencyGraph.hh"
7+
// #include "ControlDependencyGraph.hh"
88

99
namespace pdg
1010
{

0 commit comments

Comments
 (0)