https://hal.archives-ouvertes.fr/hal-03445821
Raw File
dag.h
/*
   Copyright Universite de Versailles Saint-Quentin en Yvelines 2009
   AUTHORS: Sebastien Briais, Sid Touati

   This file is part of GDD.
   
   GDD is free software: you can redistribute it and/or modify it
   under the terms of the GNU Lesser General Public License as
   published by the Free Software Foundation, either version 3 of the
   License, or (at your option) any later version.
   
   GDD is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.
   
   You should have received a copy of the GNU Lesser General Public
   License along with GDD.  If not, see
   <http://www.gnu.org/licenses/>.
*/
#ifndef __GDD_DAG_H
#define __GDD_DAG_H
/** \file dag.h
    \brief Data Dependency Acyclic Graphs */

#include "opcode.h"
#include "ddg.h"

#include <SCEDA/list.h>
#include <SCEDA/graph.h>
#include <SCEDA/hashmap.h>


/** Type of DAGs (acyclic DDGs) */
typedef struct {
  SCEDA_Graph *g;

  SCEDA_Graph *gf;
  SCEDA_HashMap *g_to_gf;
} GDD_DAG;

/** Create a new GDD_DAG. 

    @param[in] g = underlying DDG (must be acyclic)

    @return a GDD_DAG or NULL if g is not acyclic */
GDD_DAG *GDD_dag_create(SCEDA_Graph *g);

/** Delete a GDD_DAG.

    @param[in] dag = GDD_DAG to delete 

    The underlying graph is not deleted. */
void GDD_dag_delete(GDD_DAG *dag);

/** Updates the precomputed values. This should be called if the underlying DDG
    structure change. 

    @param[in] dag = GDD_DAG to update */
void GDD_dag_update(GDD_DAG *dag);

/** Get the graph of a GDD_DAG.

    @param[in] dag = GDD_DAG

    @return the associated DAG

    \hideinitializer */
#define GDD_dag_get_ddg(dag) ((dag)->g)

/** Test whether there is a path from v1 to v2, where v1 and v2 are
    two vertices of the underlying DAG.

    @param[in] dag = GDD_DAG
    @param[in] v1 = first vertex
    @param[in] v2 = second vertex

    @return TRUE iff there is a path from v1 to v2 */
int GDD_dag_lt(GDD_DAG *dag, SCEDA_Vertex *v1, SCEDA_Vertex *v2);

/** Test whether the two given vertices (of the underlying DAG) are
    parallel.

    @param[in] dag = GDD_DAG
    @param[in] v1 = first vertex
    @param[in] v2 = second vertex

    @return TRUE iff the two vertices are parallel */
int GDD_dag_parallel(GDD_DAG *dag, SCEDA_Vertex *v1, SCEDA_Vertex *v2);

/* Set GDD_DAG_PRECALC to FALSE to disable usage of precomputed data
   (slower but cheaper regarding memory usage) */
#define GDD_DAG_PRECALC 1

#if(GDD_DAG_PRECALC)
/** Iterator over the UpSet of a vertex (of the underlying DAG).

    The upset is the set of vertices reachable from the given vertex. */
typedef SCEDA_VertexSuccIterator GDD_DAG_UpsetIterator;

/** Initialise an upset iterator.

    @param[in] dag = GDD_DAG
    @param[in] v = vertex 
    @param[in] iter = iterator */
void GDD_dag_upset_iterator_init(GDD_DAG *dag, SCEDA_Vertex *v, GDD_DAG_UpsetIterator *iter);

/** Is there a next vertex in the iterator? 

    \hideinitializer */
#define GDD_dag_upset_iterator_has_next SCEDA_vertex_succ_iterator_has_next

/** Get the next vertex in the iterator.

    @param[in] iter = iterator

    @return the next (reachable) vertex */
#define GDD_dag_upset_iterator_next(iter$) (SCEDA_vertex_get_data(SCEDA_Vertex *, SCEDA_vertex_succ_iterator_next(iter$)))

/** Clean up an (upset) iterator.

    \hideinitializer */
#define GDD_dag_upset_iterator_cleanup SCEDA_vertex_succ_iterator_cleanup
#else 
#include <SCEDA/graph_traversal.h>

typedef SCEDA_BFSIterator GDD_DAG_UpsetIterator;

#define GDD_dag_upset_iterator_init(ddg$, v$, iter$) \
  ({ \
    SCEDA_bfs_iterator_init(v$, iter$); \
    SCEDA_bfs_iterator_next(iter$); })

#define GDD_dag_upset_iterator_has_next SCEDA_bfs_iterator_has_next
#define GDD_dag_upset_iterator_next SCEDA_bfs_iterator_next
#define GDD_dag_upset_iterator_cleanup SCEDA_bfs_iterator_cleanup
#endif

#endif

/** \page dag Data Dependency Acyclic Graphs

    \section dag_intro Introduction

    Acyclic DDG are of particular interest: GDD_DAG structure offer new
    functions that operate on an acyclic DDG.

    A GDD_DAG is based on a DDG.

    If \f$v, w\f$ are two vertices of an acyclic DDG, we write \f$v <
    w\f$ if there exists a path from \f$v\f$ to \f$w\f$ in the DDG (ie
    there exists a path \f$v_0 v_1 \ldots v_n\f$ with \f$v = v_0\f$
    and \f$w = v_n\f$ in the DDG). If neither \f$v < w\f$ nor \f$w <
    v\f$, we write \f$v \parallel w\f$ and say that \f$v\f$ and
    \f$w\f$ are parallel.

    The upset of a vertex \f$v\f$ is the set \f$\mathop{U}(v) = \{ w
    \mid v < w \wedge v \neq w \}\f$: it is the set of vertices
    reachable from v in the underlying DDG.

    \section dag_api API

    \code
    GDD_DAG *GDD_dag_create(SCEDA_Graph *g);
    \endcode

    Create a GDD_DAG, corresponding the given graph. It fails if g is not
    acyclic.

    \code
    void GDD_dag_delete(GDD_DAG *dag);
    \endcode
    
    Delete a GDD_DAG (but not its associated graph).

    \code
    void GDD_dag_update(GDD_DAG *dag);
    \endcode

    Update internal structure of a GDD_DAG, reflecting changes to the DDG
    upon which it is based.

    \code
    SCEDA_Graph *GDD_dag_get_ddg(GDD_DAG *dag);
    \endcode

    Return the underlying DDG.

    \code
    int GDD_dag_lt(SCEDA_Vertex *v1, SCEDA_Vertex *v2);
    \endcode

    Test whether there is a path from GDD vertex v1 to GDD vertex v2
    in the underlying GDD, ie perform the test \f$v_1 < v_2\f$.

    \code
    int GDD_dag_parallel(SCEDA_Vertex *v1, SCEDA_Vertex *v2);
    \endcode

    Return TRUE iff there is no path from v1 to v2 and no path from v2
    to v1 in the underlying GDD, ie perform the test \f$v_1 \parallel
    v_2\f$.

    \code
    void GDD_dag_upset_iterator_init(GDD_DAG *dag, SCEDA_Vertex *v, GDD_DAG_UpsetIterator *iter);
    int GDD_dag_upset_iterator_has_next(GDD_DAG_UpsetIterator *iter);
    SCEDA_Vertex *GDD_dag_upset_iterator_next(GDD_DAG_UpsetIterator *iter);
    void GDD_dag_upset_iterator_cleanup(GDD_DAG_UpsetIterator *iter);
    \endcode

    Iterator over the upset of a vertex, ie the set \f$\mathop{U}(v)\f$.

    \section dag_example Example

    \include "dag/main.c"

 */
back to top