LCOV - code coverage report
Current view: top level - metalib_isl - isl_tarjan.c (source / functions) Hit Total Coverage
Test: 2018-10-31_point_maint_greina16.lcov Lines: 0 80 0.0 %
Date: 2018-11-01 11:27:00 Functions: 0 5 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2010-2011 INRIA Saclay
       3             :  * Copyright 2012      Ecole Normale Superieure
       4             :  *
       5             :  * Use of this software is governed by the MIT license
       6             :  *
       7             :  * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
       8             :  * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
       9             :  * 91893 Orsay, France
      10             :  * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
      11             :  */
      12             : 
      13             : #include <stdlib.h>
      14             : #include <isl/ctx.h>
      15             : #include <isl_tarjan.h>
      16             : 
      17           0 : struct isl_tarjan_graph *isl_tarjan_graph_free(struct isl_tarjan_graph *g)
      18             : {
      19           0 :         if (!g)
      20           0 :                 return NULL;
      21           0 :         free(g->node);
      22           0 :         free(g->stack);
      23           0 :         free(g->order);
      24           0 :         free(g);
      25           0 :         return NULL;
      26             : }
      27             : 
      28           0 : static struct isl_tarjan_graph *isl_tarjan_graph_alloc(isl_ctx *ctx, int len)
      29             : {
      30             :         struct isl_tarjan_graph *g;
      31             :         int i;
      32             : 
      33           0 :         g = isl_calloc_type(ctx, struct isl_tarjan_graph);
      34           0 :         if (!g)
      35           0 :                 return NULL;
      36           0 :         g->len = len;
      37           0 :         g->node = isl_alloc_array(ctx, struct isl_tarjan_node, len);
      38           0 :         if (len && !g->node)
      39           0 :                 goto error;
      40           0 :         for (i = 0; i < len; ++i)
      41           0 :                 g->node[i].index = -1;
      42           0 :         g->stack = isl_alloc_array(ctx, int, len);
      43           0 :         if (len && !g->stack)
      44           0 :                 goto error;
      45           0 :         g->order = isl_alloc_array(ctx, int, 2 * len);
      46           0 :         if (len && !g->order)
      47           0 :                 goto error;
      48             : 
      49           0 :         g->sp = 0;
      50           0 :         g->index = 0;
      51           0 :         g->op = 0;
      52             : 
      53           0 :         return g;
      54             : error:
      55           0 :         isl_tarjan_graph_free(g);
      56           0 :         return NULL;
      57             : }
      58             : 
      59             : /* Perform Tarjan's algorithm for computing the strongly connected components
      60             :  * in the graph with g->len nodes and with edges defined by "follows".
      61             :  */
      62           0 : static isl_stat isl_tarjan_components(struct isl_tarjan_graph *g, int i,
      63             :         isl_bool (*follows)(int i, int j, void *user), void *user)
      64             : {
      65             :         int j;
      66             : 
      67           0 :         g->node[i].index = g->index;
      68           0 :         g->node[i].min_index = g->index;
      69           0 :         g->node[i].on_stack = 1;
      70           0 :         g->index++;
      71           0 :         g->stack[g->sp++] = i;
      72             : 
      73           0 :         for (j = g->len - 1; j >= 0; --j) {
      74             :                 isl_bool f;
      75             : 
      76           0 :                 if (j == i)
      77           0 :                         continue;
      78           0 :                 if (g->node[j].index >= 0 &&
      79           0 :                         (!g->node[j].on_stack ||
      80           0 :                          g->node[j].index > g->node[i].min_index))
      81           0 :                         continue;
      82             : 
      83           0 :                 f = follows(i, j, user);
      84           0 :                 if (f < 0)
      85           0 :                         return isl_stat_error;
      86           0 :                 if (!f)
      87           0 :                         continue;
      88             : 
      89           0 :                 if (g->node[j].index < 0) {
      90           0 :                         isl_tarjan_components(g, j, follows, user);
      91           0 :                         if (g->node[j].min_index < g->node[i].min_index)
      92           0 :                                 g->node[i].min_index = g->node[j].min_index;
      93           0 :                 } else if (g->node[j].index < g->node[i].min_index)
      94           0 :                         g->node[i].min_index = g->node[j].index;
      95             :         }
      96             : 
      97           0 :         if (g->node[i].index != g->node[i].min_index)
      98           0 :                 return isl_stat_ok;
      99             : 
     100             :         do {
     101           0 :                 j = g->stack[--g->sp];
     102           0 :                 g->node[j].on_stack = 0;
     103           0 :                 g->order[g->op++] = j;
     104           0 :         } while (j != i);
     105           0 :         g->order[g->op++] = -1;
     106             : 
     107           0 :         return isl_stat_ok;
     108             : }
     109             : 
     110             : /* Decompose the graph with "len" nodes and edges defined by "follows"
     111             :  * into strongly connected components (SCCs).
     112             :  * follows(i, j, user) should return 1 if "i" follows "j" and 0 otherwise.
     113             :  * It should return -1 on error.
     114             :  *
     115             :  * If SCC a contains a node i that follows a node j in another SCC b
     116             :  * (i.e., follows(i, j, user) returns 1), then SCC a will appear after SCC b
     117             :  * in the result.
     118             :  */
     119           0 : struct isl_tarjan_graph *isl_tarjan_graph_init(isl_ctx *ctx, int len,
     120             :         isl_bool (*follows)(int i, int j, void *user), void *user)
     121             : {
     122             :         int i;
     123           0 :         struct isl_tarjan_graph *g = NULL;
     124             : 
     125           0 :         g = isl_tarjan_graph_alloc(ctx, len);
     126           0 :         if (!g)
     127           0 :                 return NULL;
     128           0 :         for (i = len - 1; i >= 0; --i) {
     129           0 :                 if (g->node[i].index >= 0)
     130           0 :                         continue;
     131           0 :                 if (isl_tarjan_components(g, i, follows, user) < 0)
     132           0 :                         return isl_tarjan_graph_free(g);
     133             :         }
     134             : 
     135           0 :         return g;
     136             : }
     137             : 
     138             : /* Decompose the graph with "len" nodes and edges defined by "follows"
     139             :  * into the strongly connected component (SCC) that contains "node"
     140             :  * as well as all SCCs that are followed by this SCC.
     141             :  * follows(i, j, user) should return 1 if "i" follows "j" and 0 otherwise.
     142             :  * It should return -1 on error.
     143             :  *
     144             :  * The SCC containing "node" will appear as the last component
     145             :  * in g->order.
     146             :  */
     147           0 : struct isl_tarjan_graph *isl_tarjan_graph_component(isl_ctx *ctx, int len,
     148             :         int node, isl_bool (*follows)(int i, int j, void *user), void *user)
     149             : {
     150             :         struct isl_tarjan_graph *g;
     151             : 
     152           0 :         g = isl_tarjan_graph_alloc(ctx, len);
     153           0 :         if (!g)
     154           0 :                 return NULL;
     155           0 :         if (isl_tarjan_components(g, node, follows, user) < 0)
     156           0 :                 return isl_tarjan_graph_free(g);
     157             : 
     158           0 :         return g;
     159             : }

Generated by: LCOV version 1.12