Skip to content
Snippets Groups Projects
Commit 25ca91c9 authored by Prakalp Srivastava's avatar Prakalp Srivastava
Browse files

Partial update on graph traits

parent 9733edac
No related branches found
No related tags found
No related merge requests found
......@@ -24,12 +24,15 @@
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Compiler.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
class DFNode;
class DFEdge;
class DFNodeVisitor;
class DFTreeTraversal;
class DFEdgeVisitor;
class DFGraph {
......@@ -49,6 +52,10 @@ public:
ChildrenList.push_back(child);
}
void addDFEdge(DFEdge* E) {
DFEdgeList.push_back(E);
}
// Iterators
typedef DFNodeListType::iterator children_iterator;
typedef DFNodeListType::const_iterator const_children_iterator;
......@@ -71,7 +78,7 @@ public:
const DFNode *back() const { return ChildrenList.back(); }
DFNode *back() { return ChildrenList.back(); }
//===--------------------------------------------------------------------===//
//===--------------------------------------------------------------------===//
//===--------------------------------------------------------------------===//
// DFEdgeList iterator forwarding functions
......@@ -88,7 +95,7 @@ public:
const DFEdge *dfedge_back() const { return DFEdgeList.back(); }
DFEdge *dfedge_back() { return DFEdgeList.back(); }
//===--------------------------------------------------------------------===//
//===--------------------------------------------------------------------===//
};
......@@ -106,14 +113,39 @@ public:
class DFNode {
private:
typedef std::vector<DFNode*> DFNodeListType;
// Important things that make up a Dataflow Node
IntrinsicInst* II; ///< Associated IntrinsicInst/Value
Function* FuncPointer; ///< Associated Function
DFNode* Parent; ///< Pointer to parent dataflow Node
int NumOfDim; ///< Number of dimensions
std::vector<Value*> DimLimits; ///< Number of instances in each dimension
DFNodeListType Successors; ///< List of successors i.e.,
///< destination DFNodes to DFEdges
///< originating from this DFNode
public:
// Iterators
typedef DFNodeListType::iterator successor_iterator;
typedef DFNodeListType::const_iterator const_successor_iterator;
//===--------------------------------------------------------------------===//
// DFNodeList iterator forwarding functions
//
successor_iterator successors_begin() { return Successors.begin(); }
const_successor_iterator successors_begin() const { return Successors.begin(); }
successor_iterator successors_end () { return Successors.end(); }
const_successor_iterator successors_end () const { return Successors.end(); }
size_t successors_size() const { return Successors.size(); }
bool successors_empty() const { return Successors.empty(); }
const DFNode* successors_front() const { return Successors.front(); }
DFNode* successors_front() { return Successors.front(); }
const DFNode* successors_back() const { return Successors.back(); }
DFNode* successors_back() { return Successors.back(); }
//===--------------------------------------------------------------------===//
// Functions
DFNode(IntrinsicInst* _II, Function* _FuncPointer, DFNode* _Parent,
......@@ -121,29 +153,29 @@ public:
FuncPointer(_FuncPointer), Parent(_Parent), NumOfDim(_NumOfDim),
DimLimits(_DimLimits) {}
// FIXME: unused - should remove it probably
static DFNode *Create(IntrinsicInst* II, Function* FuncPointer,
DFNode* Parent = NULL, int NumOfDim = 0,
std::vector<Value*> DimLimits = std::vector<Value*>()) {
return new DFNode(II, FuncPointer, Parent, NumOfDim, DimLimits);
void addSuccessor(DFNode* N) {
Successors.push_back(N);
}
// FIXME: When constructor and create method are removed, these should be virtual methods
void applyDFNodeVisitor(DFNodeVisitor &V);
void applyDFEdgeVisitor(DFEdgeVisitor &V);
Function* getFuncPointer() {
return FuncPointer;
}
virtual void applyDFNodeVisitor(DFNodeVisitor &V) = 0;
// virtual void applyDFEdgeVisitor(DFEdgeVisitor &V) = 0;
};
class DFInternalNode : public DFNode {
private:
DFGraph* Graph;
DFGraph* childGraph;
// Constructor
DFInternalNode(IntrinsicInst* II, Function* FuncPointer, DFNode* Parent,
int NumOfDim, std::vector<Value*> DimLimits) :
DFNode(II, FuncPointer, Parent, NumOfDim, DimLimits) {
Graph = new DFGraph();
childGraph = new DFGraph();
}
public:
......@@ -154,12 +186,19 @@ public:
}
void addChildToDFGraph(DFNode* N) {
Graph->addChildDFNode(N);
childGraph->addChildDFNode(N);
}
void addEdgeToDFGraph(DFEdge* E) {
childGraph->addDFEdge(E);
}
void applyDFNodeVisitor(DFNodeVisitor &V);
void applyDFEdgeVisitor(DFEdgeVisitor &V);
DFGraph* getChildGraph() {
return childGraph;
}
void applyDFNodeVisitor(DFNodeVisitor &V); /*virtual*/
// void applyDFEdgeVisitor(DFEdgeVisitor &V); /*virtual*/
};
class DFLeafNode : public DFNode {
......@@ -178,8 +217,8 @@ public:
return new DFLeafNode(II, FuncPointer, Parent, NumOfDim, DimLimits);
}
void applyDFNodeVisitor(DFNodeVisitor &V);
void applyDFEdgeVisitor(DFEdgeVisitor &V);
void applyDFNodeVisitor(DFNodeVisitor &V); /*virtual*/
// void applyDFEdgeVisitor(DFEdgeVisitor &V); /*virtual*/
};
......@@ -225,16 +264,98 @@ public:
// Visitor for DFNode objects
class DFNodeVisitor {
public:
virtual void visit(DFInternalNode &)=0;
virtual void visit(DFLeafNode &)=0;
virtual void visit(DFInternalNode* N) = 0;
virtual void visit(DFLeafNode* N) = 0;
};
void DFInternalNode::applyDFNodeVisitor(DFNodeVisitor &V) {
V.visit(this);
}
void DFLeafNode::applyDFNodeVisitor(DFNodeVisitor &V) {
V.visit(this);
}
class DFTreeTraversal : public DFNodeVisitor {
public:
virtual void visit(DFInternalNode* N){
errs() << "Visted Node (I) - " << N->getFuncPointer()->getName() << "\n";
for(DFGraph::children_iterator i = N->getChildGraph()->begin(),
e = N->getChildGraph()->end(); i != e; ++i) {
DFNode* child = *i;
child->applyDFNodeVisitor(*this);
}
}
virtual void visit(DFLeafNode* N) {
errs() << "Visted Node (L) - " << N->getFuncPointer()->getName() << "\n";
}
};
class FollowSuccessors : public DFNodeVisitor {
public:
virtual void visit(DFInternalNode* N) {
errs() << "Visted Node (I) - " << N->getFuncPointer()->getName() << "\n";
for(DFInternalNode::successor_iterator i = N->successors_begin(),
e = N->successors_end(); i != e; ++i) {
/* Traverse the graph.
* Choose the kind of traversal we want
* Do we do a DAG kind of traversal?
*/
}
}
virtual void visit(DFLeafNode* N) {
errs() << "Visted Node (L) - " << N->getFuncPointer()->getName() << "\n";
}
};
/*
// Visitor for DFEdge objects
class DFEdgeVisitor {
public:
virtual void visit(DFEdge &)=0;
virtual void visit(DFEdge* E) = 0;
};
*/
//===--------------------------------------------------------------------===//
// GraphTraits specializations for DFNode graph (DFG)
//===--------------------------------------------------------------------===//
// Provide specializations of GraphTraits to be able to treat a DFNode as a
// graph of DFNodes...
template <> struct GraphTraits<DFNode*> {
typedef DFNode NodeType;
typedef DFNode::successor_iterator ChildIteratorType;
static NodeType *getEntryNode(DFNode *N) { return N; }
static inline ChildIteratorType child_begin(NodeType *N) {
return N->successors_begin();
}
static inline ChildIteratorType child_end(NodeType *N) {
return N->successors_end();
}
};
template <> struct GraphTraits<const DFNode*> {
typedef const DFNode NodeType;
typedef DFNode::const_successor_iterator ChildIteratorType;
static NodeType *getEntryNode(const DFNode *N) { return N; }
static inline ChildIteratorType child_begin(NodeType *N) {
return N->successors_begin();
}
static inline ChildIteratorType child_end(NodeType *N) {
return N->successors_end();
}
};
} // End llvm namespace
#endif
......@@ -20,24 +20,26 @@ let TargetPrefix = "visc" in {
/* Create Node intrinsic -
* i8* llvm.visc.createNode(function*);
*/
def int_visc_createNode : Intrinsic<[llvm_ptr_ty], [llvm_anyptr_ty], []>;
def int_visc_test : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], []>;
def int_visc_createNode : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty], []>;
/* Create Node 1D array intrinsic -
* i8* llvm.visc.createNode1D(function*, i32);
*/
def int_visc_createNode1D : Intrinsic<[llvm_ptr_ty], [llvm_anyptr_ty,
def int_visc_createNode1D : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty,
llvm_i32_ty], []>;
/* Create Node 2D array intrinsic -
* i8* llvm.visc.createNode2D(function*, i32, i32);
*/
def int_visc_createNode2D : Intrinsic<[llvm_ptr_ty], [llvm_anyptr_ty,
def int_visc_createNode2D : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty,
llvm_i32_ty, llvm_i32_ty], []>;
/* Create Node 3D array intrinsic -
* i8* llvm.visc.createNode2D(function*, i32, i32, i32);
*/
def int_visc_createNode3D : Intrinsic<[llvm_ptr_ty], [llvm_anyptr_ty,
def int_visc_createNode3D : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty,
llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
[]>;
......@@ -45,7 +47,7 @@ let TargetPrefix = "visc" in {
* i8* llvm.visc.createEdge(i8*, i8*, funtion*, function*);
*/
def int_visc_createEdge : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_ptr_ty,
llvm_anyptr_ty, llvm_anyptr_ty], []>;
llvm_ptr_ty, llvm_ptr_ty], []>;
/* Find associated dataflow node intrinsic -
* i8* llvm.visc.getNode();
......
......@@ -42,27 +42,31 @@ namespace {
// Functions
bool isViscIntrinsic(Instruction * I);
void handleCreateNode (DFInternalNode* N, IntrinsicInst* II);
void handleCreateEdge (DFNode* N, IntrinsicInst* II);
void handleCreateEdge (DFInternalNode* N, IntrinsicInst* II);
void BuildGraph (DFInternalNode* N, Function* F);
public:
virtual bool runOnModule(Module &M) {
// Iterate over all functions in the Module
for (Module::iterator f = M.begin(), e = M.end(); f != e; ++f) {
errs() << "Function: " << f->getName() << "\n";
ValueSymbolTable& V = f->getValueSymbolTable();
errs() << "----------- Dumping Symbol Table ----------\n";
V.dump();
errs() << "------------------ Done -------------------\n\n";
// Loop over all of the global variables
for (Module::const_global_iterator i = M.global_begin(),
e = M.global_end(); i != e; ++i) {
errs() << "Global: " << i->getName() << "\t" << *(i->getOperand(0))<< "\n";
// Find the function associated with root dataflow graph node
// Start from root to build the dataflow graph in top-down fashion
// The name of the root node function is llvm.visc.root (for now)
if((f->getName()).equals("llvm.visc.root")) {
if((i->getName()).equals("llvm.visc.root")) {
errs() << "----------- Found Root Node -------------\n\n";
Function* f = cast<Function>(i->getOperand(0));
Root = DFInternalNode::Create(NULL, f);
BuildGraph(Root, f);
break;
}
else {
errs() << "Root Node not found yet :( \n";
}
}
return false; //TODO: What does returning "false" mean?
......@@ -73,7 +77,7 @@ namespace {
// Returns true if the instruction I is a visc intrinsic, false otherwise
bool BuildDFG::isViscIntrinsic(Instruction* I) {
if (IntrinsicInst* II = dyn_cast<IntrinsicInst>(I)) {
if (((II->getCalledFunction()->getName()).startswith("llvm.visc."))) {
if (((II->getCalledFunction()->getName()).startswith("llvm.visc.create"))) {
// It is a visc intrinsic
return true;
}
......@@ -85,7 +89,7 @@ namespace {
void BuildDFG::handleCreateNode(DFInternalNode* N, IntrinsicInst* II) {
bool isInternalNode = false;
Function* F = cast<Function>(II->getOperand(0));
Function* F = cast<Function>((II->getOperand(0))->stripPointerCasts());
// Check if the function associated with this intrinsic is a leaf or
// internal node
......@@ -121,7 +125,7 @@ namespace {
}
}
void BuildDFG::handleCreateEdge (DFNode* N, IntrinsicInst* II) {
void BuildDFG::handleCreateEdge (DFInternalNode* N, IntrinsicInst* II) {
// The DFNode structures must be in the map before the edge is processed
HandleToDFNode::iterator DFI = HandleToDFNodeMap.find(II->getOperand(0));
assert(DFI != HandleToDFNodeMap.end());
......@@ -134,10 +138,8 @@ namespace {
Function* ArgMapFunc = cast<Function>(II->getOperand(3));
DFEdge* NewDFEdge = DFEdge::Create(SrcDF, DestDF, DFMapFunc, ArgMapFunc);
// FIXME Need interface of DFNode for the following:
// N->addOutgoingEdge(NewDFEdge);
// N->addIncomingEdge(NewDFEdge);
// SrcDF->addSuccesor(probably NewDFEdge, could be DestDF);
// DestDF->addPredeccesor(probably NewDFEdge, could be SrcDF);
N->addEdgeToDFGraph(NewDFEdge);
SrcDF->addSuccessor(DestDF);
}
void BuildDFG::BuildGraph (DFInternalNode* N, Function *F) {
......@@ -150,10 +152,13 @@ namespace {
// intrinsics.
for (inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i) {
Instruction* I = &*i; // Grab pointer to instruction reference
// errs() << *I << "\n";
errs() << *I << "\n";
if(IntrinsicInst* II = dyn_cast<IntrinsicInst>(I)) {
errs() << "IntrinsicID = " << II->getIntrinsicID() << ": " << II->getCalledFunction()->getName()<<"\n";
switch(II->getIntrinsicID()) {
case Intrinsic::visc_test:
errs() << "Found Test Intrinsic";
break;
case Intrinsic::visc_createNode:
case Intrinsic::visc_createNode1D:
......@@ -171,10 +176,13 @@ namespace {
break;
}
}
else {
errs() << "Non-intrinsic instruction\n";
}
}
}
} // End of namespace
char BuildDFG::ID = 0;
static RegisterPass<BuildDFG> X("buildDFG", "Hierarchical Dataflow Graph Builder Pass");
static RegisterPass<BuildDFG> X("buildDFG", "Hierarchical Dataflow Graph Builder Pass", false, false);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment