Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
ir_graph_util.h
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 /* ====================================================================
00037  * ====================================================================
00038  *
00039  * Author: Seema Hiranandani
00040  *
00041  *
00042  * Revision history:
00043  *  19-Aug-95 - Original Version
00044  *
00045  * Description:
00046  *
00047  * This module contains data structures for a graph abstraction.
00048  * This graph is used to construct, for instance, a call graph.
00049  *
00050  * ====================================================================
00051  * ====================================================================
00052  */
00053 
00054 #ifndef ip_graph_INCLUDED
00055 #define ip_graph_INCLUDED
00056 #ifdef __cplusplus
00057 extern "C" {
00058 #endif
00059 
00060 /* ====================================================================
00061  *
00062  * VERTEX / EDGE / GRAPH : Directed graph implementation
00063  *
00064  * A GRAPH is a set of VERTEX objects, connected by a set of EDGE
00065  * objects.  These sets are implemented as a vector of VERTEXes and a
00066  * vector of EDGEs, with all references being indices into these
00067  * vectors.  The sets are allowed to grow (by adding VERTEXes or EDGEs)
00068  * or to shrink (by deleting them).  Growth may cause reallocation of
00069  * the vector.  To minimize reallocation cost, it is done in larger
00070  * chunks than necessary.  To avoid rearrangement of the data upon
00071  * deletion, the deleted VERTEX/EDGE is simply marked invalid.
00072  *
00073  * ====================================================================
00074  */
00075 
00076 /* EDGE/VERTEX index types, and reserved index values: */
00077 typedef int EINDEX;
00078 typedef int VINDEX;
00079 #define INVALID_EINDEX -1
00080 #define INVALID_VINDEX -1
00081 
00082 /* ====================================================================
00083  *
00084  * A VERTEX contains two singly-linked lists of EDGEs, one of EDGEs
00085  * starting at that VERTEX, and one of EDGEs ending at that VERTEX.  
00086  * Each list is represented in the VERTEX by the index of its first
00087  * element (VERTEX_from and VERTEX_to) and a count of its elements
00088  * (VERTEX_fcnt and VERTEX_tcnt).  An invalid (i.e. unused) VERTEX is
00089  * indicated by VERTEX_fcnt == INVALID_EINDEX.  The VERTEX also
00090  * contains a pointer VERTEX_user to additional data required by the
00091  * client derived graph. The level of a vertex is defined as the (max level
00092  * of the immediate successors of the vertex) + 1
00093  * ====================================================================
00094  */
00095 
00096 typedef struct vertex {
00097   void* user;         /* user information */
00098   EINDEX from, to;    /* first edge from and to this vertex */
00099   EINDEX fcnt, tcnt;  /* from/to counts                     */
00100   int level;          /* level of the vertex                */
00101 } VERTEX;
00102 
00103 /* Field access macros: */
00104 #define VERTEX_user(vertex) ((vertex)->user)
00105 #define VERTEX_from(vertex) ((vertex)->from)
00106 #define VERTEX_to(vertex)   ((vertex)->to)
00107 #define VERTEX_fcnt(vertex) ((vertex)->fcnt)
00108 #define VERTEX_tcnt(vertex) ((vertex)->tcnt)
00109 #define VERTEX_level(vertex) ((vertex)->level)
00110 /* ====================================================================
00111  *
00112  * A EDGE contains two VERTEXes, its from VERTEX (EDGE_from) and its
00113  * to vertex (EDGE_to).  It contains links (indices) to the next edges
00114  * in the VERTEX_from list for its from VERTEX (EDGE_nfrom), and in the
00115  * VERTEX_to list for its to VERTEX (EDGE_nto).  It contains a flag
00116  * word containing attributes, and a pointer EDGE_user to additional
00117  * data required by the client derived graph.
00118  *
00119  * ====================================================================
00120  */
00121 
00122 /* EDGE data structure: */
00123 
00124 typedef int ETYPEX;
00125 typedef int BOOL;
00126 #ifndef FALSE
00127 #define FALSE 0
00128 #define TRUE  1
00129 #endif
00130 typedef char MEM_POOL;
00131 
00132 typedef struct edge {
00133   void * user;        /* user information     */
00134   VINDEX from, to;    /* from and to vertices */
00135   EINDEX nfrom;       /* next edge from the from vertex */
00136   EINDEX nto;         /* next edge to the to vertex */
00137   ETYPEX etype;       /* edge type, i.e. is it a back edge resulting */
00138                       /* in a cycle: used to locate recursion  */
00139 } EDGE; 
00140 
00141 /* Field access macros: */
00142 #define EDGE_user(edge)  ((edge)->user)
00143 #define EDGE_from(edge)  ((edge)->from)
00144 #define EDGE_to(edge)    ((edge)->to)
00145 #define EDGE_nfrom(edge) ((edge)->nfrom)
00146 #define EDGE_nto(edge)   ((edge)->nto)
00147 #define EDGE_etype(edge)   ((edge)->etype)
00148 
00149 /* Flag access: */
00150 #define EDGE_RECURSIVE 1
00151 #define Set_EDGE_recursive(edge) (EDGE_etype(edge) |= EDGE_RECURSIVE)
00152 #define EDGE_recursive(edge)   (EDGE_etype(edge) & EDGE_RECURSIVE)
00153 
00154 /* ====================================================================
00155  *
00156  * A GRAPH is the top-level directed graph data structure.  For both
00157  * vertices and edges, it contains the number of VERTEX/EDGE structures
00158  * actually allocated (GRAPH_vmax, GRAPH_emax), the number of actual
00159  * VERTEX/EDGE components of the graph (GRAPH_vcnt, GRAPH_ecnt), the
00160  * number of free VERTEX/EDGE structures that are allocated and
00161  * available for use (GRAPH_vfree, GRAPH_efree), and the vector of
00162  * VERTEX_EDGE components (GRAPH_v, GRAPH_e).  It also contains the
00163  * root of the graph (GRAPH_root) and the memory pool to use for
00164  * allocation (GRAPH_m).
00165  *
00166  * ====================================================================
00167  */
00168 
00169 typedef struct graph {
00170   VINDEX vcnt;  /* vertex count            */
00171   VINDEX vmax;  /* max vertices            */
00172   VINDEX vfree; /* number of free vertices */
00173 
00174   EINDEX ecnt;  /* edge count              */
00175   EINDEX emax;  /* max edges               */
00176   EINDEX efree; /* number of free edges    */
00177  
00178   VINDEX root;  /* root of the graph       */
00179   VERTEX *v;    /* list of vertices        */
00180   EDGE *e;      /* list of edges           */
00181   MEM_POOL *m;  /* mem pool                */
00182 } GRAPH;
00183 
00184 #define DEF_VERTEX_SIZE 8
00185 #define DEF_EDGE_SIZE   8
00186 
00187 /* Field access macros: */
00188 #define GRAPH_vcnt(g) ((g)->vcnt)
00189 #define GRAPH_vmax(g) ((g)->vmax)
00190 #define GRAPH_vfree(g)((g)->vfree)
00191 #define GRAPH_ecnt(g) ((g)->ecnt)
00192 #define GRAPH_emax(g) ((g)->emax)
00193 #define GRAPH_efree(g) ((g)->efree)
00194 #define GRAPH_root(g)  ((g)->root)
00195 #define GRAPH_m(g) ((g)->m)
00196 #define GRAPH_v(g)  ((g)->v)
00197 #define GRAPH_v_i(g,index) ((g)->v[index])
00198 #define GRAPH_e(g)  ((g)->e)
00199 #define GRAPH_e_i(g,index) ((g)->e[index])
00200 
00201 /* Walk all the valid vertices in the graph g, using VINDEX v: */
00202 #define FOR_EACH_VERTEX(g,v)    \
00203         for ( v = 0; v < GRAPH_vmax(g); v++ )   \
00204           if ( VERTEX_fcnt (&GRAPH_v_i(g,v)) != INVALID_VINDEX )
00205 
00206 /* ====================================================================
00207  *
00208  * DFN: Depth-first numbering graph traversal control struct
00209  *
00210  * This struct is used to store an ordering of the nodes in a graph, to
00211  * control traversal in a particular order.  It contains a vector of
00212  * the graph vertices in the traversal order (DFN_v_list), and the
00213  * indices of the first useful index in the vector (GRAV_first) and of
00214  * the index after the last useful index in the vector (DFN_end).
00215  *
00216  * ====================================================================
00217  */
00218 
00219 typedef struct dfn {
00220   int first;
00221   int end;
00222   VINDEX* v_list;
00223   void **user;
00224 } DFN;
00225 
00226 /* Field access macros: */
00227 #define DFN_v_list(d) ((d)->v_list)
00228 #define DFN_v_list_i(d,i) ((d)->v_list[i])
00229 #define DFN_first(d) ((d)->first)
00230 #define DFN_end(d) ((d)->end)
00231 #define DFN_user(d) ((d)->user)
00232 #define DFN_user_i(d,i) ((d)->user[i])
00233 
00234 /* Trace a DFN ordering: */
00235 extern void Print_DFN ( DFN *, GRAPH *g, void (*)(),  void (*)());
00236 
00237 /* Construct a depth-first numbering of the given graph: */
00238 extern DFN* Depth_First_Ordering ( GRAPH *, MEM_POOL * );
00239 
00240 /* De-allocate a DFN ordering: */
00241 extern void Free_DFN ( DFN *, MEM_POOL * );
00242 
00243 /* ====================================================================
00244  *
00245  * V_ITER: Vertex iterator control struct
00246  *
00247  * This struct is used to control an iterator over vertices.
00248  *
00249  * ====================================================================
00250  */
00251 
00252 typedef struct v_iter {
00253   GRAPH *g;       /* the graph */
00254   VINDEX c_v;     /* the current vertex */
00255   EINDEX from_e;  /* from edge   */
00256   EINDEX to_e;    /* to edge     */
00257   EINDEX  fcnt;   /* from count  */
00258   EINDEX nfrom;   /* next from edge */
00259   EINDEX tcnt;    /* to count      */
00260   EINDEX nto;     /* next to edges */
00261   EINDEX c_e;     /* current edge  */
00262   MEM_POOL *m;     /* mempool  */
00263 } V_ITER;
00264 
00265 /* Field access macros: */
00266 #define V_ITER_g(vi) ((vi)->g)
00267 #define V_ITER_c_v(vi) ((vi)->c_v)
00268 #define V_ITER_from_e(vi) ((vi)->from_e)
00269 #define V_ITER_to_e(vi) ((vi)->to_e)
00270 #define V_ITER_fcnt(vi) ((vi)->fcnt)
00271 #define V_ITER_nfrom(vi) ((vi)->nfrom)
00272 #define V_ITER_tcnt(vi)  ((vi)->tcnt)
00273 #define V_ITER_nto(vi)   ((vi)->nto)
00274 #define V_ITER_c_e(vi)   ((vi)->c_e)
00275 #define V_ITER_m(vi)   ((vi)->m)
00276 
00277 #define GR_ASSERT(EX, p)      if (!(EX)) { printf("Graph assertion: "); printf(p); exit(1);}
00278 #define MEM_POOL_Alloc(m, s)            malloc(s)
00279 #define MEM_POOL_Realloc(m, ob, os, ns) realloc(ob, ns)
00280 #define MEM_POOL_FREE(m, s)             free(s)
00281 
00282 /* ====================================================================
00283  *
00284  * External function declarations
00285  *
00286  * ====================================================================
00287  */
00288 
00289 extern GRAPH* build_graph_u(VINDEX, EINDEX, MEM_POOL*);
00290 extern GRAPH* build_graph(MEM_POOL*);
00291 
00292 extern VINDEX add_vertex(GRAPH*, void*);
00293 extern EINDEX add_edge(GRAPH*, VINDEX, VINDEX, void*);
00294 
00295 extern BOOL is_vertex(GRAPH*, VINDEX);
00296 extern BOOL is_edge(GRAPH*, EINDEX);
00297 
00298 extern void  delete_edge(GRAPH*, EINDEX);
00299 extern void* delete_vertex(GRAPH*, VINDEX);
00300 
00301 extern void* get_vertex(GRAPH*, VINDEX);
00302 extern void* get_edge(GRAPH*, VINDEX, VINDEX);
00303 extern void* get_edge_u(GRAPH*, EINDEX );
00304 extern void set_edge_u (GRAPH *, EINDEX, void *);
00305 
00306 extern int num_preds(GRAPH*, VINDEX);
00307 extern int num_succs(GRAPH*, VINDEX);
00308 extern int edge_count(GRAPH*, VINDEX from, VINDEX to);
00309 
00310 extern VINDEX next_vertex(GRAPH *g, VINDEX vertex);
00311 
00312 extern V_ITER* create_vertex_iter(GRAPH*, VINDEX, MEM_POOL*);
00313 extern VINDEX  first_v_preds(V_ITER*);
00314 extern VINDEX  next_v_preds(V_ITER*);
00315 extern VINDEX  first_v_succs(V_ITER*);
00316 extern VINDEX  next_v_succs(V_ITER*);
00317 
00318 /* related to the level of a vertex in the graph */
00319 extern void set_vertex_level(GRAPH*, VINDEX r, int level);
00320 extern int get_vertex_level(GRAPH*, VINDEX r);
00321 
00322 #ifdef __cplusplus
00323 }
00324 #endif
00325 #endif /* ip_graph_INCLUDED */
00326 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines