From 25ca91c93e8ef5d5be08df78dd9a6d69e20dde8d Mon Sep 17 00:00:00 2001 From: Prakalp Srivastava <psrivas2@illinois.edu> Date: Fri, 20 Sep 2013 17:44:23 +0000 Subject: [PATCH] Partial update on graph traits --- llvm/include/llvm/IR/DFGraph.h | 161 +++++++++++++++++++--- llvm/include/llvm/IR/IntrinsicsVISC.td | 12 +- llvm/lib/Transforms/BuildDFG/BuildDFG.cpp | 44 +++--- 3 files changed, 174 insertions(+), 43 deletions(-) diff --git a/llvm/include/llvm/IR/DFGraph.h b/llvm/include/llvm/IR/DFGraph.h index fc48c37662..abfa026cc7 100644 --- a/llvm/include/llvm/IR/DFGraph.h +++ b/llvm/include/llvm/IR/DFGraph.h @@ -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 diff --git a/llvm/include/llvm/IR/IntrinsicsVISC.td b/llvm/include/llvm/IR/IntrinsicsVISC.td index 4527736a22..97927f0f26 100644 --- a/llvm/include/llvm/IR/IntrinsicsVISC.td +++ b/llvm/include/llvm/IR/IntrinsicsVISC.td @@ -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(); diff --git a/llvm/lib/Transforms/BuildDFG/BuildDFG.cpp b/llvm/lib/Transforms/BuildDFG/BuildDFG.cpp index a3e87f2b73..bc0e5364c4 100644 --- a/llvm/lib/Transforms/BuildDFG/BuildDFG.cpp +++ b/llvm/lib/Transforms/BuildDFG/BuildDFG.cpp @@ -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); -- GitLab