PIPS
toposort.c
Go to the documentation of this file.
1 /*
2 
3  $Id: toposort.c 23065 2016-03-02 09:05:50Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 /* toposort.c
28 
29  Entry point: list topologically_sorted_module_list(mod)
30 
31  returns the list of subroutines/functions called in the module mod
32  sorted as follow: we recursively build the graph of calls, taking
33  mod for root, and we apply on it the topological sort.
34  The first of the list is the module mod itself.
35 
36  Pierre Berthomier, May 1990
37  Lei Zhou, January 1991
38 */
39 #include <stdio.h>
40 #include <string.h>
41 
42 #include "genC.h"
43 #include "linear.h"
44 
45 #include "misc.h"
46 #include "pipsdbm.h"
47 
48 #include "ri.h"
49 #include "ri-util.h"
50 
51 #include "icfg.h"
52 
53 /* get all the callees of the module module_name,return the no-empty
54  list of string.
55  if the module has callee(s),the first element of the return list
56  is the module's last callee.
57 */
58 
60 const char* module_name;
61 {
62  callees cl;
63  static hash_table hash_table_to_callees_string;
64  static bool hash_table_is_created = false;
65  list callees_list=NIL;
66 
67  cl = (callees)db_get_memory_resource(DBR_CALLEES,module_name,true);
68 
69  if ( !hash_table_is_created ) {
70  hash_table_to_callees_string = hash_table_make(hash_pointer, 0);
71  hash_table_is_created = true;
72  }
73 
74  callees_list = (list)hash_get(hash_table_to_callees_string, module_name);
75 
76  if ( callees_list == (list)HASH_UNDEFINED_VALUE ) {
77  callees_list = callees_callees(cl);
78  hash_put(hash_table_to_callees_string, module_name,
79  (char *)callees_list);
80  }
81 
82  return(callees_list);
83 }
84 
86 entity mod;
87 {
88  list return_list = NIL;
89  list callees_list = code_declarations(entity_code(mod));
90 
91  MAPL(ce,{
92  entity e = ENTITY(CAR(ce));
94  return_list = CONS(ENTITY,
96  return_list);
97  },callees_list);
98 
99  return(return_list);
100 }
101 
102 void topological_number_assign_to_module(hash_module_to_depth, mod, n)
103 hash_table hash_module_to_depth;
104 entity mod;
105 size_t n;
106 {
107  size_t depth = (size_t) hash_get(hash_module_to_depth, (char *) mod);
108  list callees_list = module_to_callees(mod);
109 
110  if ((depth == (size_t) ICFG_NOT_FOUND) || (depth < n))
111  hash_put(hash_module_to_depth, (char *) mod, (char *) n);
112 
113  if ( callees_list != NIL ) {
114  /* assigns depth n+1 to callees of current module */
115  MAPL(pm,
116  { entity e = ENTITY(CAR(pm));
117  topological_number_assign_to_module(hash_module_to_depth, e, n+1);
118  },
119  callees_list);
120  }
121 }
122 
123 list module_list_sort(hash_module_to_depth, current_list, mod, n)
124 hash_table hash_module_to_depth;
125 list current_list;
126 entity mod;
127 size_t n;
128 {
129  list callees_list = NIL;
130  static list same_depth_list = NIL;
131  size_t depth;
132 
133  /* create the callees list whose caller has the depth n */
134  if ( same_depth_list == NIL )
135  callees_list = module_to_callees(mod);
136  else {
137  MAPL(pm,{ entity e = ENTITY(CAR(pm));
138  callees_list = gen_nconc(callees_list,
140  },
141  same_depth_list);
142  }
143 
144  /* free the same_depth_list for later use */
145 
146  same_depth_list = NIL;
147 
148  /* create same_depth_list whose depth is n+1 */
149  if ( callees_list != NIL ) {
150  MAPL(pm,{ entity e = ENTITY(CAR(pm));
151  depth = (size_t) hash_get(hash_module_to_depth, (char *) e);
152  if ( depth == n+1 ) {
153  same_depth_list = gen_nconc(same_depth_list,
154  CONS(ENTITY, e, NIL));
155  hash_put(hash_module_to_depth,
156  (char *) e, (char *) -1);
157  }
158  },
159  callees_list);
160 
161  /* concatenate former current_list with same_depth_list */
162  current_list = gen_nconc(current_list, same_depth_list);
163 
164  /* use module_list_sort recursively */
165  current_list = module_list_sort(hash_module_to_depth,
166  current_list,
167  ENTITY(CAR(same_depth_list)),
168  n+1);
169  }
170  return (current_list);
171 }
172 
174 entity mod;
175 {
176  /* "depth" of subroutine or function for topological sort */
177  hash_table hash_module_to_depth = (hash_table) NULL;
178  list sorted_list;
179 
180  hash_module_to_depth = hash_table_make(hash_pointer, 0);
182 
183  topological_number_assign_to_module(hash_module_to_depth, mod, 0);
184 
185  sorted_list = module_list_sort(hash_module_to_depth, NIL, mod, 0);
186 
187  pips_assert("free_hash_table",
188  hash_module_to_depth != (hash_table) NULL);
189  hash_table_free(hash_module_to_depth);
190  hash_module_to_depth = (hash_table) NULL;
191 
192  return (sorted_list);
193 }
194 
196 const char* module_name;
197 {
198  list sorted_list = NIL;
199  string filename;
200  FILE *fp;
202 
203  pips_assert("print_module_name_to_toposorts", mod != entity_undefined &&
204  entity_module_p(mod));
205 
206  fprintf(stderr, "topological-sorting callees for %s ...\n",
207  entity_name(mod));
208 
210 
211  sorted_list = (list) topologically_sorted_module_list(mod);
213  "/", module_name, ".topo",NULL));
214 
215  fp = safe_fopen(filename, "w");
216 
217  MAPL(pm,
218  { fprintf(fp, "%s\n",entity_name(ENTITY(CAR(pm)))); },
219  sorted_list);
220 
221  safe_fclose(fp, filename);
222  fprintf(stderr, "result written to %s\n", filename);
223 
224  debug_off();
225 }
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
FILE * safe_fopen(const char *filename, const char *what)
Definition: file.c:67
int safe_fclose(FILE *stream, const char *filename)
Definition: file.c:77
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define MAPL(_map_list_cp, _code, _l)
Apply some code on the addresses of all the elements of a list.
Definition: newgen_list.h:203
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
Definition: database.c:755
void hash_dont_warn_on_redefinition(void)
Definition: hash.c:188
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:449
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
Definition: hash.c:364
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
#define ICFG_NOT_FOUND
Definition: icfg-local.h:29
#define ICFG_DEBUG_LEVEL
Definition: icfg-local.h:35
#define debug_on(env)
Definition: misc-local.h:157
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define debug_off()
Definition: misc-local.h:160
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
@ hash_pointer
Definition: newgen_hash.h:32
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
Definition: newgen_hash.h:56
struct __hash_table * hash_table
Define hash_table structure which is hidden.
Definition: newgen_hash.h:43
struct cons * list
Definition: newgen_types.h:106
string db_get_current_workspace_directory(void)
Definition: workspace.c:96
size_t size_t
Definition: properties.c:413
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
entity local_name_to_top_level_entity(const char *n)
This function try to find a top-level entity from a local name.
Definition: entity.c:1450
code entity_code(entity e)
Definition: entity.c:1098
bool entity_module_p(entity e)
Definition: entity.c:683
#define type_functional_p(x)
Definition: ri.h:2950
struct _newgen_struct_callees_ * callees
Definition: ri.h:55
#define callees_callees(x)
Definition: ri.h:675
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define code_declarations(x)
Definition: ri.h:784
#define entity_undefined
Definition: ri.h:2761
#define entity_name(x)
Definition: ri.h:2790
#define entity_type(x)
Definition: ri.h:2792
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
static int depth
la sequence de nids
void print_module_name_to_toposorts(char *module_name) const
Definition: toposort.c:195
list topologically_sorted_module_list(entity mod)
Definition: toposort.c:173
list module_list_sort(hash_table hash_module_to_depth, list current_list, entity mod, size_t n)
Definition: toposort.c:123
list module_name_to_callees(char *module_name) const
toposort.c
Definition: toposort.c:59
list module_to_callees(entity mod)
Definition: toposort.c:85
void topological_number_assign_to_module(hash_table hash_module_to_depth, entity mod, size_t n)
Definition: toposort.c:102