From b88fb055c45193bad7550f22f6879a1e581091de Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 28 Jun 2004 00:32:33 +0000 Subject: [PATCH] Move DependenceGraph.* to lib/Analysis/DataStructure git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@14452 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../DataStructure/DependenceGraph.cpp | 87 ++++++ lib/Analysis/DataStructure/DependenceGraph.h | 255 ++++++++++++++++++ .../DataStructure/MemoryDepAnalysis.h | 2 +- .../DataStructure/PgmDependenceGraph.h | 1 - 4 files changed, 343 insertions(+), 2 deletions(-) create mode 100644 lib/Analysis/DataStructure/DependenceGraph.cpp create mode 100644 lib/Analysis/DataStructure/DependenceGraph.h diff --git a/lib/Analysis/DataStructure/DependenceGraph.cpp b/lib/Analysis/DataStructure/DependenceGraph.cpp new file mode 100644 index 00000000000..de3f45a447e --- /dev/null +++ b/lib/Analysis/DataStructure/DependenceGraph.cpp @@ -0,0 +1,87 @@ +//===- DependenceGraph.cpp - Dependence graph 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. +// +//===----------------------------------------------------------------------===// +// +// This file implements an explicit representation for the dependence graph +// of a function, with one node per instruction and one edge per dependence. +// Dependences include both data and control dependences. +// +// Each dep. graph node (class DepGraphNode) keeps lists of incoming and +// outgoing dependence edges. +// +// Each dep. graph edge (class Dependence) keeps a pointer to one end-point +// of the dependence. This saves space and is important because dep. graphs +// can grow quickly. It works just fine because the standard idiom is to +// start with a known node and enumerate the dependences to or from that node. +//===----------------------------------------------------------------------===// + + +#include "DependenceGraph.h" +#include "llvm/Function.h" + +namespace llvm { + +//---------------------------------------------------------------------------- +// class Dependence: +// +// A representation of a simple (non-loop-related) dependence +//---------------------------------------------------------------------------- + +void Dependence::print(std::ostream &O) const +{ + assert(depType != NoDependence && "This dependence should never be created!"); + switch (depType) { + case TrueDependence: O << "TRUE dependence"; break; + case AntiDependence: O << "ANTI dependence"; break; + case OutputDependence: O << "OUTPUT dependence"; break; + case ControlDependence: O << "CONTROL dependence"; break; + default: assert(0 && "Invalid dependence type"); break; + } +} + + +//---------------------------------------------------------------------------- +// class DepGraphNode +//---------------------------------------------------------------------------- + +void DepGraphNode::print(std::ostream &O) const +{ + const_iterator DI = outDepBegin(), DE = outDepEnd(); + + O << "\nDeps. from instr:" << getInstr(); + + for ( ; DI != DE; ++DI) + { + O << "\t"; + DI->print(O); + O << " to instruction:"; + O << DI->getSink()->getInstr(); + } +} + +//---------------------------------------------------------------------------- +// class DependenceGraph +//---------------------------------------------------------------------------- + +DependenceGraph::~DependenceGraph() +{ + // Free all DepGraphNode objects created for this graph + for (map_iterator I = depNodeMap.begin(), E = depNodeMap.end(); I != E; ++I) + delete I->second; +} + +void DependenceGraph::print(const Function& func, std::ostream &O) const +{ + O << "DEPENDENCE GRAPH FOR FUNCTION " << func.getName() << ":\n"; + for (Function::const_iterator BB=func.begin(), FE=func.end(); BB != FE; ++BB) + for (BasicBlock::const_iterator II=BB->begin(), IE=BB->end(); II !=IE; ++II) + if (const DepGraphNode* dgNode = this->getNode(*II)) + dgNode->print(O); +} + +} // End llvm namespace diff --git a/lib/Analysis/DataStructure/DependenceGraph.h b/lib/Analysis/DataStructure/DependenceGraph.h new file mode 100644 index 00000000000..679ecd7d135 --- /dev/null +++ b/lib/Analysis/DataStructure/DependenceGraph.h @@ -0,0 +1,255 @@ +//===- DependenceGraph.h - Dependence graph 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. +// +//===----------------------------------------------------------------------===// +// +// This file provides an explicit representation for the dependence graph +// of a function, with one node per instruction and one edge per dependence. +// Dependences include both data and control dependences. +// +// Each dep. graph node (class DepGraphNode) keeps lists of incoming and +// outgoing dependence edges. +// +// Each dep. graph edge (class Dependence) keeps a pointer to one end-point +// of the dependence. This saves space and is important because dep. graphs +// can grow quickly. It works just fine because the standard idiom is to +// start with a known node and enumerate the dependences to or from that node. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_DEPENDENCEGRAPH_H +#define LLVM_ANALYSIS_DEPENDENCEGRAPH_H + +#include "Support/hash_map" +#include +#include +#include +#include + +namespace llvm { + +class Instruction; +class Function; +class Dependence; +class DepGraphNode; +class DependenceGraph; + +//---------------------------------------------------------------------------- +/// enum DependenceType - The standard data dependence types +/// +enum DependenceType { + NoDependence = 0x0, + TrueDependence = 0x1, + AntiDependence = 0x2, + OutputDependence = 0x4, + ControlDependence = 0x8, // from a terminator to some other instr. + IncomingFlag = 0x10 // is this an incoming or outgoing dep? +}; + +//---------------------------------------------------------------------------- +/// Dependence Class - A representation of a simple (non-loop-related) +/// dependence. +/// +class Dependence { + DepGraphNode* toOrFromNode; + unsigned char depType; + +public: + Dependence(DepGraphNode* toOrFromN, DependenceType type, bool isIncoming) + : toOrFromNode(toOrFromN), + depType(type | (isIncoming? IncomingFlag : 0x0)) { } + + Dependence(const Dependence& D) : toOrFromNode(D.toOrFromNode), + depType(D.depType) { } + + bool operator==(const Dependence& D) const { + return toOrFromNode == D.toOrFromNode && depType == D.depType; + } + + /// Get information about the type of dependence. + /// + unsigned getDepType() const { + return depType; + } + + /// Get source or sink depending on what type of node this is! + /// + DepGraphNode* getSrc() { + assert(depType & IncomingFlag); return toOrFromNode; + } + const DepGraphNode* getSrc() const { + assert(depType & IncomingFlag); return toOrFromNode; + } + + DepGraphNode* getSink() { + assert(! (depType & IncomingFlag)); return toOrFromNode; + } + const DepGraphNode* getSink() const { + assert(! (depType & IncomingFlag)); return toOrFromNode; + } + + /// Debugging support methods + /// + void print(std::ostream &O) const; + + // Default constructor: Do not use directly except for graph builder code + // + Dependence() : toOrFromNode(NULL), depType(NoDependence) { } +}; + +#ifdef SUPPORTING_LOOP_DEPENDENCES +struct LoopDependence: public Dependence { + DependenceDirection dir; + int distance; + short level; + LoopInfo* enclosingLoop; +}; +#endif + + +//---------------------------------------------------------------------------- +/// DepGraphNode Class - A representation of a single node in a dependence +/// graph, corresponding to a single instruction. +/// +class DepGraphNode { + Instruction* instr; + std::vector inDeps; + std::vector outDeps; + friend class DependenceGraph; + + typedef std::vector:: iterator iterator; + typedef std::vector::const_iterator const_iterator; + + iterator inDepBegin() { return inDeps.begin(); } + const_iterator inDepBegin() const { return inDeps.begin(); } + iterator inDepEnd() { return inDeps.end(); } + const_iterator inDepEnd() const { return inDeps.end(); } + + iterator outDepBegin() { return outDeps.begin(); } + const_iterator outDepBegin() const { return outDeps.begin(); } + iterator outDepEnd() { return outDeps.end(); } + const_iterator outDepEnd() const { return outDeps.end(); } + +public: + DepGraphNode(Instruction& I) : instr(&I) { } + + Instruction& getInstr() { return *instr; } + const Instruction& getInstr() const { return *instr; } + + /// Debugging support methods + /// + void print(std::ostream &O) const; +}; + + +//---------------------------------------------------------------------------- +/// DependenceGraph Class - A representation of a dependence graph for a +/// procedure. The primary query operation here is to look up a DepGraphNode for +/// a particular instruction, and then use the in/out dependence iterators +/// for the node. +/// +class DependenceGraph { + DependenceGraph(const DependenceGraph&); // DO NOT IMPLEMENT + void operator=(const DependenceGraph&); // DO NOT IMPLEMENT + + typedef hash_map DepNodeMapType; + typedef DepNodeMapType:: iterator map_iterator; + typedef DepNodeMapType::const_iterator const_map_iterator; + + DepNodeMapType depNodeMap; + + inline DepGraphNode* getNodeInternal(Instruction& inst, + bool createIfMissing = false) { + map_iterator I = depNodeMap.find(&inst); + if (I == depNodeMap.end()) + return (!createIfMissing)? NULL : + depNodeMap.insert( + std::make_pair(&inst, new DepGraphNode(inst))).first->second; + else + return I->second; + } + +public: + typedef std::vector:: iterator iterator; + typedef std::vector::const_iterator const_iterator; + +public: + DependenceGraph() { } + ~DependenceGraph(); + + /// Get the graph node for an instruction. There will be one if and + /// only if there are any dependences incident on this instruction. + /// If there is none, these methods will return NULL. + /// + DepGraphNode* getNode(Instruction& inst, bool createIfMissing = false) { + return getNodeInternal(inst, createIfMissing); + } + const DepGraphNode* getNode(const Instruction& inst) const { + return const_cast(this) + ->getNodeInternal(const_cast(inst)); + } + + iterator inDepBegin(DepGraphNode& T) { + return T.inDeps.begin(); + } + const_iterator inDepBegin (const DepGraphNode& T) const { + return T.inDeps.begin(); + } + + iterator inDepEnd(DepGraphNode& T) { + return T.inDeps.end(); + } + const_iterator inDepEnd(const DepGraphNode& T) const { + return T.inDeps.end(); + } + + iterator outDepBegin(DepGraphNode& F) { + return F.outDeps.begin(); + } + const_iterator outDepBegin(const DepGraphNode& F) const { + return F.outDeps.begin(); + } + + iterator outDepEnd(DepGraphNode& F) { + return F.outDeps.end(); + } + const_iterator outDepEnd(const DepGraphNode& F) const { + return F.outDeps.end(); + } + + /// Debugging support methods + /// + void print(const Function& func, std::ostream &O) const; + +public: + /// AddSimpleDependence - adding and modifying the dependence graph. + /// These should to be used only by dependence analysis implementations. + /// + void AddSimpleDependence(Instruction& fromI, Instruction& toI, + DependenceType depType) { + DepGraphNode* fromNode = getNodeInternal(fromI, /*create*/ true); + DepGraphNode* toNode = getNodeInternal(toI, /*create*/ true); + fromNode->outDeps.push_back(Dependence(toNode, depType, false)); + toNode-> inDeps. push_back(Dependence(fromNode, depType, true)); + } + +#ifdef SUPPORTING_LOOP_DEPENDENCES + // This interface is a placeholder to show what information is needed. + // It will probably change when it starts being used. + void AddLoopDependence(Instruction& fromI, + Instruction& toI, + DependenceType depType, + DependenceDirection dir, + int distance, + short level, + LoopInfo* enclosingLoop); +#endif // SUPPORTING_LOOP_DEPENDENCES +}; + +} // End llvm namespace + +#endif diff --git a/lib/Analysis/DataStructure/MemoryDepAnalysis.h b/lib/Analysis/DataStructure/MemoryDepAnalysis.h index b63ffa564a4..04d78dafff8 100644 --- a/lib/Analysis/DataStructure/MemoryDepAnalysis.h +++ b/lib/Analysis/DataStructure/MemoryDepAnalysis.h @@ -20,7 +20,7 @@ #ifndef LLVM_ANALYSIS_MEMORYDEPANALYSIS_H #define LLVM_ANALYSIS_MEMORYDEPANALYSIS_H -#include "llvm/Analysis/DependenceGraph.h" +#include "DependenceGraph.h" #include "llvm/Pass.h" #include "Support/hash_map" diff --git a/lib/Analysis/DataStructure/PgmDependenceGraph.h b/lib/Analysis/DataStructure/PgmDependenceGraph.h index 8906682eff9..5f7f7d581b9 100644 --- a/lib/Analysis/DataStructure/PgmDependenceGraph.h +++ b/lib/Analysis/DataStructure/PgmDependenceGraph.h @@ -39,7 +39,6 @@ #ifndef LLVM_ANALYSIS_PGMDEPENDENCEGRAPH_H #define LLVM_ANALYSIS_PGMDEPENDENCEGRAPH_H -#include "llvm/Analysis/DependenceGraph.h" #include "MemoryDepAnalysis.h" /* #include "llvm/Analysis/PostDominators.h" -- see below */ #include "llvm/Instruction.h"