[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