[llvm-commits] CVS: llvm/lib/Analysis/DataStructure/PgmDependenceGraph.h Parallelize.cpp PgmDependenceGraph.cpp

Chris Lattner lattner at cs.uiuc.edu
Sun Jun 27 19:21:09 PDT 2004


Changes in directory llvm/lib/Analysis/DataStructure:

PgmDependenceGraph.h added (r1.1)
Parallelize.cpp updated: 1.14 -> 1.15
PgmDependenceGraph.cpp updated: 1.4 -> 1.5

---
Log message:

Move PgmDependenceGraph.h out of the public include hierarchy


---
Diffs of the changes:  (+304 -2)

Index: llvm/lib/Analysis/DataStructure/PgmDependenceGraph.h
diff -c /dev/null llvm/lib/Analysis/DataStructure/PgmDependenceGraph.h:1.1
*** /dev/null	Sun Jun 27 19:20:14 2004
--- llvm/lib/Analysis/DataStructure/PgmDependenceGraph.h	Sun Jun 27 19:20:04 2004
***************
*** 0 ****
--- 1,302 ----
+ //===- PgmDependenceGraph.h - Enumerate the PDG for a function --*- C++ -*-===//
+ // 
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by the LLVM research group and is distributed under
+ // the University of Illinois Open Source License. See LICENSE.TXT for details.
+ // 
+ //===----------------------------------------------------------------------===//
+ // 
+ // The Program Dependence Graph (PDG) for a single function represents all
+ // data and control dependences for the function.  This file provides an
+ // iterator to enumerate all these dependences.  In particular, it enumerates:
+ // 
+ // -- Data dependences on memory locations, computed using the
+ //    MemoryDepAnalysis pass;
+ // -- Data dependences on SSA registers, directly from Def-Use edges of Values;
+ // -- Control dependences, computed using postdominance frontiers
+ //    (NOT YET IMPLEMENTED).
+ // 
+ // Note that this file does not create an explicit dependence graph --
+ // it only provides an iterator to traverse the PDG conceptually.
+ // The MemoryDepAnalysis does build an explicit graph, which is used internally
+ // here.  That graph could be augmented with the other dependences above if
+ // desired, but for most uses there will be little need to do that.
+ // 
+ // Key Classes:
+ // 
+ // enum PDGIteratorFlags -- Specify which dependences to enumerate.
+ // 
+ // class PDGIterator     -- The PDG iterator.  This is essentially like a
+ //                          pointer to class Dependence, but doesn't explicitly
+ //                          construct a Dependence object for each dependence.
+ //
+ // class PgmDependenceGraph -- Interface to obtain PDGIterators for each
+ //                          instruction.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef LLVM_ANALYSIS_PGMDEPENDENCEGRAPH_H
+ #define LLVM_ANALYSIS_PGMDEPENDENCEGRAPH_H
+ 
+ #include "llvm/Analysis/DependenceGraph.h"
+ #include "llvm/Analysis/MemoryDepAnalysis.h"
+ /* #include "llvm/Analysis/PostDominators.h" -- see below */
+ #include "llvm/Instruction.h"
+ #include "llvm/Pass.h"
+ #include "Support/iterator"
+ 
+ namespace llvm {
+ 
+ class DSGraph;
+ class DependenceGraph;
+ class PgmDependenceGraph;
+ 
+ //---------------------------------------------------------------------------
+ /// enum PDGIteratorFlags - specify which dependences incident on a statement
+ /// are to be enumerated: Memory deps, SSA deps, Control deps, or any
+ /// combination thereof.
+ ///
+ enum PDGIteratorFlags {
+   MemoryDeps  = 0x1,                                 // load/store/call deps
+   SSADeps     = 0x2,                                 // SSA deps (true)
+   ControlDeps = /* 0x4*/ 0x0,                        // control dependences
+   AllDataDeps = MemoryDeps | SSADeps,                // shorthand for data deps
+   AllDeps     = MemoryDeps | SSADeps | ControlDeps   // shorthand for all three
+ };
+ 
+ //---------------------------------------------------------------------------
+ /// struct DepIterState - an internal implementation detail.
+ /// It are exposed here only to give inlinable access to field dep,
+ /// which is the representation for the current dependence pointed to by
+ /// a PgmDependenceGraph::iterator.
+ ///
+ class DepIterState {
+ private:
+   typedef char IterStateFlags;
+   static const IterStateFlags NoFlag, MemDone, SSADone, AllDone, FirstTimeFlag;
+ 
+ public:
+   DepGraphNode*              depNode;        // the node being enumerated
+   DependenceGraph::iterator  memDepIter;     // pointer to current memory dep
+   Instruction::op_iterator   ssaInEdgeIter;  // pointer to current SSA in-dep
+   Value::use_iterator        ssaOutEdgeIter; // pointer to current SSA out-dep
+   DependenceGraph*           memDepGraph;    // the core dependence graph
+   Dependence                 dep;            // the "current" dependence
+   PDGIteratorFlags           depFlags:8;     // which deps are we enumerating?
+   IterStateFlags             iterFlags:8;    // marking where the iter stands
+ 
+   DepIterState(DependenceGraph* _memDepGraph,
+                Instruction&     I, 
+                bool             incomingDeps,
+                PDGIteratorFlags whichDeps);
+ 
+   bool operator==(const DepIterState& S) {
+     assert(memDepGraph == S.memDepGraph &&
+            "Incompatible iterators! This is a probable sign of something BAD.");
+     return (iterFlags == S.iterFlags &&
+             dep == S.dep && depFlags == S.depFlags && depNode == S.depNode &&
+             memDepIter == S.memDepIter && ssaInEdgeIter == S.ssaInEdgeIter &&
+             ssaOutEdgeIter == S.ssaOutEdgeIter);
+   }
+ 
+   // Is the iteration completely done?
+   // 
+   bool done() const { return iterFlags & AllDone; }
+ 
+   /// Next - Bump this iterator logically by 1 (to next dependence) and reset
+   /// the dep field to represent the new dependence if there is one.
+   /// Set done = true otherwise.
+   /// 
+   void Next();
+ 
+   /// SetFirstMemoryDep - Find the first memory dependence for the current Mem
+   /// In/Out iterators. Sets dep to that dependence and returns true if one is
+   /// found. Returns false and leaves dep unchanged otherwise.
+   /// 
+   bool SetFirstMemoryDep();
+ 
+   /// SetFirstSSADep - Find the next valid data dependence for the current SSA
+   /// In/Out iterators. A valid data dependence is one that is to/from an
+   /// Instruction. E.g., an SSA edge from a formal parameter is not a valid
+   /// dependence. Sets dep to that dependence and returns true if a valid one is
+   /// found. Returns false and leaves dep unchanged otherwise.
+   ///
+   bool SetFirstSSADep();
+ };
+ 
+ 
+ //---------------------------------------------------------------------------
+ /// PDGIterator Class - represents a pointer to a single dependence in the
+ /// program dependence graph.  It is essentially like a pointer to an object of
+ /// class Dependence but it is much more efficient to retrieve information about
+ /// the dependence directly rather than constructing the equivalent Dependence
+ /// object (since that object is normally not constructed for SSA def-use
+ /// dependences).
+ ///
+ class PDGIterator: public forward_iterator<Dependence, ptrdiff_t> {
+   DepIterState* istate;
+ 
+ #if 0
+   /*copy*/     PDGIterator    (const PDGIterator& I);   // do not implement!
+   PDGIterator& operator=      (const PDGIterator& I);   // do not implement!
+ 
+   /*copy*/     PDGIterator    (PDGIterator& I) : istate(I.istate) {
+     I.istate = NULL;                  // ensure this is not deleted twice.
+   }
+ #endif
+ 
+   friend class PgmDependenceGraph;
+ 
+ public:
+   typedef PDGIterator _Self;
+ 
+   PDGIterator(DepIterState* _istate) : istate(_istate) {}
+   ~PDGIterator() { delete istate; }
+ 
+   PDGIterator(const PDGIterator& I) :istate(new DepIterState(*I.istate)) {}
+ 
+   PDGIterator& operator=(const PDGIterator& I) {
+     if (istate) delete istate;
+     istate = new DepIterState(*I.istate);
+     return *this;
+   }
+ 
+   /// fini - check if the iteration is complete
+   /// 
+   bool fini() const { return !istate || istate->done(); }
+ 
+   // Retrieve the underlying Dependence.  Returns NULL if fini().
+   // 
+   Dependence* operator*()  const { return fini() ?  NULL : &istate->dep; }
+   Dependence* operator->() const { assert(!fini()); return &istate->dep; }
+ 
+   // Increment the iterator
+   // 
+   _Self& operator++() { if (!fini()) istate->Next(); return *this;}
+   _Self& operator++(int);   // do not implement!
+ 
+   // Equality comparison: a "null" state should compare equal to done
+   // This is efficient for comparing with "end" or with itself, but could
+   // be quite inefficient for other cases.
+   // 
+   bool operator==(const PDGIterator& I) const {
+     if (I.istate == NULL)               // most common case: iter == end()
+       return (istate == NULL || istate->done());
+     if (istate == NULL)
+       return (I.istate == NULL || I.istate->done());
+     return (*istate == *I.istate);
+   }
+   bool operator!=(const PDGIterator& I) const {
+     return ! (*this == I);
+   }
+ };
+ 
+ 
+ ///---------------------------------------------------------------------------
+ /// class PgmDependenceGraph:
+ ///
+ /// This pass enumerates dependences incident on each instruction in a function.
+ /// It can be made a FunctionPass once a Pass (such as Parallelize) is
+ /// allowed to use a FunctionPass such as this one.
+ ///---------------------------------------------------------------------------
+ 
+ class PgmDependenceGraph: public Pass {
+ 
+   /// Information about the function being analyzed.
+   /// 
+   DependenceGraph* memDepGraph;
+   
+   // print helper function.
+   void printOutgoingSSADeps(Instruction& I, std::ostream &O);
+ 
+   /// MakeIterator - creates and initializes an iterator as specified.
+   ///
+   PDGIterator   MakeIterator(Instruction&     I,
+                              bool             incomingDeps,
+                              PDGIteratorFlags whichDeps);
+   
+   /// MakeIterator - creates a null iterator representing end-of-iteration.
+   /// 
+   PDGIterator  MakeIterator() { return PDGIterator(NULL); }
+ 
+   friend class PDGIterator;
+   friend class DepIterState;
+ 
+ public:
+   typedef PDGIterator iterator;
+   /* typedef PDGIterator<const Dependence> const iterator; */
+ 
+ public:
+   PgmDependenceGraph() : memDepGraph(NULL) {}
+   ~PgmDependenceGraph() {}
+ 
+   /// Iterators to enumerate the program dependence graph for a function.
+   /// Note that this does not provide "end" iterators to check for completion.
+   /// Instead, just use iterator::fini() or iterator::operator*() == NULL
+   ///
+   iterator  inDepBegin(Instruction& I, PDGIteratorFlags whichDeps = AllDeps) {
+     return MakeIterator(I, /*inDeps*/ true, whichDeps);
+   }
+   iterator  inDepEnd  (Instruction& I, PDGIteratorFlags whichDeps = AllDeps) {
+     return MakeIterator();
+   }
+   iterator  outDepBegin(Instruction& I, PDGIteratorFlags whichDeps = AllDeps) {
+     return MakeIterator(I, /*inDeps*/ false, whichDeps);
+   }
+   iterator  outDepEnd  (Instruction& I, PDGIteratorFlags whichDeps = AllDeps) {
+     return MakeIterator();
+   }
+ 
+   //------------------------------------------------------------------------
+   /// TEMPORARY FUNCTIONS TO MAKE THIS A MODULE PASS ---
+   /// These functions will go away once this class becomes a FunctionPass.
+ 
+   /// Driver function to compute dependence graphs for every function.
+   /// 
+   bool run(Module& M) { return true; }
+ 
+   /// getGraph() -- Retrieve the pgm dependence graph for a function.
+   /// This is temporary and will go away once this is a FunctionPass.
+   /// At that point, this class itself will be the PgmDependenceGraph you want.
+   /// 
+   PgmDependenceGraph& getGraph(Function& F) {
+     Visiting(F);
+     return *this;
+   }
+ 
+   private:
+   void Visiting(Function& F) {
+     memDepGraph = &getAnalysis<MemoryDepAnalysis>().getGraph(F);
+   }
+   public:
+   ///----END TEMPORARY FUNCTIONS---------------------------------------------
+ 
+ 
+   /// This initializes the program dependence graph iterator for a function.
+   /// 
+   bool runOnFunction(Function& func) {
+     Visiting(func);
+     return true;
+   }
+ 
+   /// getAnalysisUsage - This does not modify anything.
+   /// It uses the Memory Dependence Analysis pass.
+   /// It needs to use the PostDominanceFrontier pass, but cannot because
+   /// that is a FunctionPass.  This means control dependence are not emumerated.
+   ///
+   void getAnalysisUsage(AnalysisUsage &AU) const {
+     AU.setPreservesAll();
+     AU.addRequired<MemoryDepAnalysis>();
+     /* AU.addRequired<PostDominanceFrontier>(); */
+   }
+ 
+   /// Debugging support methods
+   /// 
+   void print(std::ostream &O) const;
+   void dump() const;
+ };
+ 
+ } // End llvm namespace
+ 
+ #endif


Index: llvm/lib/Analysis/DataStructure/Parallelize.cpp
diff -u llvm/lib/Analysis/DataStructure/Parallelize.cpp:1.14 llvm/lib/Analysis/DataStructure/Parallelize.cpp:1.15
--- llvm/lib/Analysis/DataStructure/Parallelize.cpp:1.14	Sat Mar 13 20:13:38 2004
+++ llvm/lib/Analysis/DataStructure/Parallelize.cpp	Sun Jun 27 19:20:04 2004
@@ -41,7 +41,7 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/Instructions.h"
 #include "llvm/Module.h"
-#include "llvm/Analysis/PgmDependenceGraph.h"
+#include "PgmDependenceGraph.h"
 #include "llvm/Analysis/DataStructure.h"
 #include "llvm/Analysis/DSGraph.h"
 #include "llvm/Support/InstVisitor.h"


Index: llvm/lib/Analysis/DataStructure/PgmDependenceGraph.cpp
diff -u llvm/lib/Analysis/DataStructure/PgmDependenceGraph.cpp:1.4 llvm/lib/Analysis/DataStructure/PgmDependenceGraph.cpp:1.5
--- llvm/lib/Analysis/DataStructure/PgmDependenceGraph.cpp:1.4	Tue Nov 11 16:41:32 2003
+++ llvm/lib/Analysis/DataStructure/PgmDependenceGraph.cpp	Sun Jun 27 19:20:04 2004
@@ -25,7 +25,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Analysis/PgmDependenceGraph.h"
+#include "PgmDependenceGraph.h"
 #include "llvm/Analysis/MemoryDepAnalysis.h"
 #include "llvm/Analysis/PostDominators.h"
 #include "llvm/Function.h"





More information about the llvm-commits mailing list