Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/DataDependencyGraph.hh
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace pdg
void addAliasEdges(llvm::Instruction &inst);
llvm::AliasResult queryAliasUnderApproximate(llvm::Value &v1, llvm::Value &v2);

void dumpDataDepGraph(llvm::Function &F);
private:
llvm::MemoryDependenceResults *_mem_dep_res;
};
Expand Down
4 changes: 4 additions & 0 deletions include/Graph.hh
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ namespace pdg
ValueNodeMap &getValueNodeMap() { return _val_node_map; }
void dumpGraph();

std::set<Node *> findNodesReachedByEdges(Node &src, const std::set<EdgeType> &edge_types, bool is_backward = false);

protected:
ValueNodeMap _val_node_map;
EdgeSet _edge_set;
Expand Down Expand Up @@ -85,8 +87,10 @@ namespace pdg
void addFormalTreeNodesToGraph(FunctionWrapper &func_w);
bool isAnnotationCallInst(llvm::Instruction &inst);
void buildGlobalAnnotationNodes(llvm::Module &M);

void dumpDataDepGraph(llvm::Function &F);


private:
FuncWrapperMap _func_wrapper_map;
CallWrapperMap _call_wrapper_map;
Expand Down
3 changes: 1 addition & 2 deletions include/LLVMEssentials.hh
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include "llvm/IR/DebugInfo.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/GraphWriter.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/Support/CommandLine.h"
#endif
3 changes: 3 additions & 0 deletions include/ProgramDependencyGraph.hh
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ namespace pdg
bool canReach(Node &src, Node &dst);
bool canReach(Node &src, Node &dst, std::set<EdgeType> exclude_edge_types);

bool isIndirectCallCandidates(CallWrapper &cw, FunctionWrapper &fw);
bool checkChildNodes(Tree* src_tree, Tree* dst_tree);

private:
llvm::Module *_module;
ProgramGraph *_PDG;
Expand Down
4 changes: 2 additions & 2 deletions include/Tree.hh
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ namespace pdg
std::vector<TreeNode *> &getChildNodes() { return _children; }
std::unordered_set<llvm::Value *> &getAddrVars() { return _addr_vars; }
void computeDerivedAddrVarsFromParent();
TreeNode *getParentNode() { return _parent_node; }
TreeNode *getParentNode() const { return _parent_node; }
Tree *getTree() { return _tree; }
int getDepth() { return _depth; }
int getDepth() const { return _depth; }
void addAccessTag(AccessTag acc_tag) { _acc_tag_set.insert(acc_tag); }
std::set<AccessTag> &getAccessTags() { return _acc_tag_set; }
bool isRootNode() {return _parent_node == nullptr;}
Expand Down
9 changes: 5 additions & 4 deletions src/CallWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ void pdg::CallWrapper::buildActualTreeForArgs(FunctionWrapper &callee_fw)
while (actual_arg_iter != _arg_list.end())
{
Tree* arg_formal_in_tree = callee_fw.getArgFormalInTree(**formal_arg_iter);
if (!arg_formal_in_tree)
{
if (!arg_formal_in_tree) {
// in some case, not each parameter has tree, for example, a function with structure parameter
actual_arg_iter++;
formal_arg_iter++;
// in some case, not each parameter has tree, for example, a function with structure parameter
continue;
}


// build actual in tree, copying the formal_in tree structure at the moment
Tree* arg_actual_in_tree = new Tree(*arg_formal_in_tree);
arg_actual_in_tree->setBaseVal(**actual_arg_iter);
Expand Down Expand Up @@ -82,4 +83,4 @@ pdg::Tree *pdg::CallWrapper::getArgActualOutTree(Value &actual_arg)
if (iter == _arg_actual_out_tree_map.end())
return nullptr;
return _arg_actual_out_tree_map[&actual_arg];
}
}
11 changes: 5 additions & 6 deletions src/DataDependencyGraph.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include "DataDependencyGraph.hh"
#include "PDGUtils.hh"

char pdg::DataDependencyGraph::ID = 0;

Expand All @@ -19,15 +18,13 @@ bool pdg::DataDependencyGraph::runOnModule(Module &M)
{
if (F.isDeclaration() || F.empty())
continue;

_mem_dep_res = &getAnalysis<MemoryDependenceWrapperPass>(F).getMemDep();
// setup alias query interface for each function
for (auto inst_iter = inst_begin(F); inst_iter != inst_end(F); inst_iter++)
{
addDefUseEdges(*inst_iter);
addAliasEdges(*inst_iter);
addRAWEdges(*inst_iter);
// some RAW could be missing due to the unsound alias analysis, need to swap the alias analysis used by the memory dependency analysis to obtain more precise results.
addRAWEdgesUnderapproximate(*inst_iter);
}
}
Expand Down Expand Up @@ -82,8 +79,10 @@ void pdg::DataDependencyGraph::addRAWEdges(Instruction &inst)
ProgramGraph &g = ProgramGraph::getInstance();
auto dep_res = _mem_dep_res->getDependency(&inst);
auto dep_inst = dep_res.getInst();

if (!dep_inst || !isa<StoreInst>(dep_inst))

if (!dep_inst)
return;
if (!isa<StoreInst>(dep_inst))
return;

Node *src = g.getNode(inst);
Expand Down Expand Up @@ -167,4 +166,4 @@ AliasResult pdg::DataDependencyGraph::queryAliasUnderApproximate(Value &v1, Valu
}

static RegisterPass<pdg::DataDependencyGraph>
DDG("ddg", "Data Dependency Graph Construction", false, true);
DDG("ddg", "Data Dependency Graph Construction", false, true);
52 changes: 40 additions & 12 deletions src/Graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ void pdg::ProgramGraph::build(Module &M)

Node * n = new Node(global_var, node_type);
_val_node_map.insert(std::pair<Value *, Node *>(&global_var, n));

addNode(*n);
}

Expand All @@ -129,10 +130,6 @@ void pdg::ProgramGraph::build(Module &M)
node_type = GraphNodeType::INST_FUNCALL;
if (isa<BranchInst>(&*inst_iter))
node_type = GraphNodeType::INST_BR;

Node *n = new Node(*inst_iter, node_type);

// handle values used inside instructions, e.g., tmp gep inst...
if (isa<StoreInst>(&*inst_iter)) {
for (auto operand : inst_iter->operand_values()) {
if (!isa<Instruction>(operand)) {
Expand All @@ -141,7 +138,7 @@ void pdg::ProgramGraph::build(Module &M)
}
}
}

Node *n = new Node(*inst_iter, node_type);
_val_node_map.insert(std::pair<Value *, Node *>(&*inst_iter, n));
func_w->addInst(*inst_iter);
addNode(*n);
Expand All @@ -153,10 +150,10 @@ void pdg::ProgramGraph::build(Module &M)
_func_wrapper_map.insert(std::make_pair(&F, func_w));
}

// build call graph
auto &call_g = PDGCallGraph::getInstance();
auto &call_g = pdg::PDGCallGraph::getInstance();
if (!call_g.isBuild())
call_g.build(M);

// handle call sites
for (auto &F : M)
{
Expand All @@ -170,12 +167,12 @@ void pdg::ProgramGraph::build(Module &M)
for (auto ci : call_insts)
{
auto called_func = pdgutils::getCalledFunc(*ci);
if (called_func == nullptr)
{
// handle indirect call
if (called_func == nullptr) {
auto ind_call_candidates = call_g.getIndirectCallCandidates(*ci, M);
if (ind_call_candidates.size() > 0)
called_func = *ind_call_candidates.begin();
else
continue;
}
if (!hasFuncWrapper(*called_func))
continue;
Expand Down Expand Up @@ -387,16 +384,47 @@ void pdg::ProgramGraph::buildGlobalAnnotationNodes(Module &M)
}
}


std::set<pdg::Node *> pdg::GenericGraph::findNodesReachedByEdges(pdg::Node &src, const std::set<EdgeType> &edge_types, bool is_backward)
{
std::set<Node *> ret;
std::queue<Node *> node_queue;
node_queue.push(&src);
std::set<Node *> visited;
while (!node_queue.empty())
{
Node *current_node = node_queue.front();
node_queue.pop();
if (visited.find(current_node) != visited.end())
continue;
visited.insert(current_node);
ret.insert(current_node);
Node::EdgeSet edge_set;
if (is_backward)
edge_set = current_node->getInEdgeSet();
else
edge_set = current_node->getOutEdgeSet();
for (auto edge : edge_set)
{
if (edge_types.find(edge->getEdgeType()) == edge_types.end())
continue;
node_queue.push(edge->getDstNode());
}
}
return ret;
}


void pdg::ProgramGraph::dumpDataDepGraph(Function &F) {
for (auto iter1 = inst_begin(F); iter1 != inst_end(F); iter1++) {
for (auto iter2 = inst_begin(F); iter2 != inst_end(F); iter2++) {
if (&*iter1 == &*iter2)
continue;
continue;
Node* n1 = getNode(*iter1);
Node* n2 = getNode(*iter2);
assert((n1 && n2) && "cannot process null node");
if (canReach(*n1, *n2))
errs() << *iter1 << " - " << *iter2 << "\n";
}
}
}
}
5 changes: 4 additions & 1 deletion src/PDGCallGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ bool pdg::PDGCallGraph::isTypeEqual(Type& t1, Type &t2)
return (t1_name == t2_name);
}



std::set<Function *> pdg::PDGCallGraph::getIndirectCallCandidates(CallInst &ci, Module &M)
{
Type *call_func_ty = ci.getFunctionType();
Expand All @@ -102,8 +104,9 @@ std::set<Function *> pdg::PDGCallGraph::getIndirectCallCandidates(CallInst &ci,
{
if (F.isDeclaration() || F.empty())
continue;
if (isFuncSignatureMatch(ci, F))
if (isFuncSignatureMatch(ci, F)) {
ind_call_cand.insert(&F);
}
}
return ind_call_cand;
}
Expand Down
5 changes: 2 additions & 3 deletions src/PDGUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ uint64_t pdg::pdgutils::getGEPOffsetInBits(Module& M, StructType &struct_type, G
auto const struct_layout = data_layout.getStructLayout(&struct_type);
if (gep_offset >= struct_type.getNumElements())
{
errs() << "dubious gep access outof bound: " << gep << " in func " << gep.getFunction()->getName() << "\n";
//errs() << "dubious gep access outof bound: " << gep << " in func " << gep.getFunction()->getName() << "\n";
return INT_MIN;
}
uint64_t field_bit_offset = struct_layout->getElementOffsetInBits(gep_offset);
Expand Down Expand Up @@ -391,7 +391,6 @@ std::string& pdg::pdgutils::rtrim(std::string& s, const char* t)
return s;
}


// check if i1 is precede of i2
bool pdg::pdgutils::isPrecedeInst(Instruction &i1, Instruction &i2, Function& F)
{
Expand All @@ -403,4 +402,4 @@ bool pdg::pdgutils::isPrecedeInst(Instruction &i1, Instruction &i2, Function& F)
return false;
}
return false;
}
}
Loading