remove cloog_util
[ppn.git] / dump.cc
blobdb3c7851af58318173e522c22c5598049f8749d7
1 #include "suif_inc.h"
2 #include <map>
3 #include <sstream>
4 #include "convert.h"
5 #include "dump.h"
6 #include <isa/pdg.h>
8 #ifndef HAVE_STRNDUP
9 extern "C" char *strndup(const char *s, size_t n);
10 #endif
12 using pdg::PDG;
13 using pdg::array;
15 void
16 dumper::visit(tree_node *t)
18 if (t->peek_annote(k_static_root)) {
19 /* Only dump a single domain */
20 if (root == 0)
21 root = t->number();
22 else
23 root = -1;
26 if (root <= 0)
27 return;
29 domain_ann *d;
30 if (t->kind() == TREE_INSTR) {
31 instruction *in = ((tree_instr*)t)->instr();
32 d = (domain_ann *)in->peek_annote(k_iteration_domain);
33 } else
34 d = (domain_ann *)t->peek_annote(k_iteration_domain);
35 if (d == NULL)
36 return;
38 nodes.push_back(d);
41 dumper::~dumper()
45 string c_type(type_node *tn)
47 std::ostringstream strm;
49 switch (tn->op()) {
50 case TYPE_INT: {
51 base_type *bt = (base_type *) tn;
53 if (!bt->is_signed())
54 strm << "unsigned ";
55 switch (c_int_type(tn)) {
56 case C_char:
57 if (bt->is_signed())
58 strm << "signed ";
59 strm << "char";
60 break;
61 case C_int:
62 strm << "int";
63 break;
64 case C_short:
65 strm << "short";
66 break;
67 case C_long:
68 strm << "long";
69 break;
70 case C_longlong:
71 strm << "long long";
72 break;
73 default:
74 assert(0);
76 break;
78 case TYPE_FLOAT: {
79 switch (c_float_type(tn)) {
80 case C_float:
81 strm << "float";
82 break;
83 case C_double:
84 strm << "double";
85 break;
86 case C_longdouble:
87 strm << "long double";
88 break;
89 default:
90 assert(0);
92 break;
94 case TYPE_STRUCT: {
95 struct_type *st = (struct_type *) tn;
96 strm << "struct " << st->name();
97 break;
99 default:
100 assert(0);
103 return strm.str();
106 static int compute_total_read(struct stmt_node *node, int c)
108 if (node->is_access()) {
109 stmt_access *sa = static_cast<stmt_access *>(node);
110 return c + !sa->write;
113 stmt_call *sc = static_cast<stmt_call *>(node);
115 for (int i = 0; i < sc->arg.size(); ++i)
116 c = compute_total_read(sc->arg[i], c);
118 return c;
121 static int compute_total_read(struct stmt *s)
123 return compute_total_read(s->tree, 0);
126 static type_node *dereference_type(type_node *tn, array *a)
128 while (tn->is_array() || tn->is_ptr()) {
129 if (tn->is_array()) {
130 array_type *an = dynamic_cast<array_type*>(tn);
131 assert(an->lower_bound().is_constant());
132 assert(an->upper_bound().is_constant());
133 tn = an->elem_type();
134 a->dims.push_back(an->upper_bound().constant() -
135 an->lower_bound().constant() + 1);
136 } else {
137 ptr_type *an = dynamic_cast<ptr_type*>(tn);
138 tn = an->ref_type();
139 a->dims.push_back(-1);
142 return tn;
145 pdg::access *dumper::add_access(pdg::node *pn, stmt_access *sa)
147 isl_ctx *ctx = pdg->get_isl_ctx();
148 pdg::access *a = new pdg::access;
149 for (int i = 0; i < sa->map->nested.size(); ++i)
150 a->nested.push_back(scan_stmt(pn, sa->map->nested[i]));
151 var_sym *av = sa->array;
152 if (av && arrays.find(av) == arrays.end()) {
153 array *a = new array();
154 a->id = av->sym_id();
155 a->name = new str(av->name());
156 type_node *tn = av->type();
157 tn = dereference_type(tn, a);
158 a->element_type = new str(c_type(tn));
159 SRelation *bounds;
160 bounds = (SRelation *)av->peek_annote(k_array_bounds);
161 if (bounds) {
162 isl_set *set = relation2set(ctx, *bounds);
163 set = isl_set_align_params(set, isl_space_copy(dim));
164 a->value_bounds = new pdg::IslSet(set);
166 pdg->arrays.push_back(a);
167 arrays[av] = a;
169 a->array = av ? arrays[av] : NULL;
170 bool write = sa->write;
171 a->type = write ? pdg::access::write : pdg::access::read;
172 isl_map *map = relation2map(ctx, *sa->map);
173 map = isl_map_align_params(map, isl_space_copy(dim));
174 if (sa->map->nested.size() > 0) {
175 isl_space *dim = isl_space_domain(isl_map_get_space(map));
176 isl_map *flatten;
177 int in = isl_space_dim(dim, isl_dim_set) - sa->map->nested.size();
178 dim = isl_space_from_domain(dim);
179 dim = isl_space_move_dims(dim, isl_dim_out, 0,
180 isl_dim_in, in, sa->map->nested.size());
181 dim = isl_space_wrap(dim);
182 flatten = isl_set_flatten_map(isl_set_universe(dim));
183 map = isl_map_apply_domain(map, isl_map_reverse(flatten));
185 a->map = new pdg::IslMap(map);
186 if (write)
187 a->nr = totalread + nwrite++;
188 else
189 a->nr = nread++;
190 pn->statement->accesses.push_back(a);
191 return a;
194 pdg::call_or_access *dumper::scan_stmt(pdg::node *pn, stmt_node *n)
196 pdg::call_or_access *coa = new pdg::call_or_access;
198 if (n->is_access()) {
199 coa->type = pdg::call_or_access::t_access;
200 coa->access = add_access(pn, static_cast<stmt_access *>(n));
201 } else {
202 stmt_call *sc = static_cast<stmt_call *>(n);
203 coa->type = pdg::call_or_access::t_call;
204 coa->call = new pdg::function_call;
205 coa->call->name = new str(string(sc->name));
207 for (int i = 0; i < sc->arg.size(); ++i) {
208 pdg::call_or_access *child;
209 child = scan_stmt(pn, sc->arg[i]);
210 coa->call->arguments.push_back(child);
214 return coa;
217 /* Convert stmt to pdg::function_call and add all accesses to ps */
218 pdg::function_call *dumper::scan_stmt(pdg::node *pn, stmt *s)
220 totalread = compute_total_read(s);
221 nread = 0;
222 nwrite = 0;
224 pdg::function_call *call;
225 pdg::call_or_access *coa = scan_stmt(pn, s->tree);
227 for (int i = 0; i < s->out.size(); ++i)
228 pn->statement->top_outputs.push_back(add_access(pn, s->out[i]));
230 if (coa->type == pdg::call_or_access::t_access) {
231 call = new pdg::function_call;
232 call->arguments.push_back(coa);
233 call->name = new str(string(""));
234 } else {
235 call = coa->call;
236 delete coa;
238 return call;
241 void dumper::dump(int argc, char * argv[])
243 isl_ctx *isl_ctx;
245 if (root <= 0)
246 return;
248 isl_ctx = isl_ctx_alloc();
249 pdg = new PDG(isl_ctx);
250 pdg->placement = new str(string("original"));
251 pdg->root = root;
253 const char *name = tp->proc()->file()->name();
254 const char *dot = strrchr(name, '.');
255 if (!dot)
256 pdg->name = new str(string(name));
257 else {
258 char *basename = strndup(name, dot-name);
259 pdg->name = new str(string(basename));
260 free(basename);
263 map<var_sym *, Param_Iterator *>::iterator gi;
264 for (gi = sa->vars.begin(); gi != sa->vars.end(); ++gi) {
265 if ((*gi).second->iterator)
266 continue;
267 if ((*gi).second->assigned)
268 continue;
269 if ((*gi).second->temp)
270 continue;
271 pdg::parameter *p = new pdg::parameter;
272 p->id = (*gi).first->sym_id();
273 p->name = new str((*gi).second->base_name());
274 if ((*gi).second->lb_set)
275 p->value = new integer((*gi).second->lb);
277 file_symtab *symtab = tp->proc()->file()->symtab();
278 var_def_list_iter j(symtab->var_defs());
279 while (!j.is_empty()) {
280 var_def *def = j.step();
281 if (def->variable() != (*gi).first)
282 continue;
283 annote_list_iter i(def->annotes());
284 while (!i.is_empty()) {
285 annote *an = i.step();
286 if (an->name() != k_repeat_init)
287 continue;
288 immed_list *ims = an->immeds();
289 if ((*ims)[2].kind() != im_int)
290 continue;
291 p->value = new integer((*ims)[2].integer());
295 pdg->params.push_back(p);
298 dim = isl_space_alloc(isl_ctx, pdg->params.size(), 0, 0);
299 isl_dim_set_parameter_names(dim, pdg->params);
301 if (ctx->ctx) {
302 isl_set *set = relation2set(isl_ctx, *ctx->ctx);
303 set = isl_set_align_params(set, isl_space_copy(dim));
304 set = isl_set_params(set);
305 pdg->context = new pdg::IslSet(set);
308 int nodenr = 0;
309 for (int i = 0; i < nodes.size(); ++i) {
310 domain_ann *n = nodes[i];
311 if (!n->domain->is_satisfiable())
312 continue;
313 pdg::node * pn = new pdg::node;
314 pdg::statement * ps = new pdg::statement;
315 pdg->nodes.push_back(pn);
316 pn->nr = nodenr++;
317 pn->statement = ps;
318 ps->operation = n->insn ? n->insn->number() : -1;
319 ps->line = n->line;
320 isl_set *set = relation2set(isl_ctx, *n->domain);
321 set = isl_set_align_params(set, isl_space_copy(dim));
322 pn->source = new pdg::IslSet(set);
323 for (int j = 0; j < n->plevel; ++j)
324 pn->prefix.push_back(n->prefix[j]);
325 ps->top_function = scan_stmt(pn, n->statement);
328 pdg->add_history_line("pers", argc, argv);
329 pdg->Dump();
330 pdg->free();
331 delete pdg;
332 isl_space_free(dim);
333 isl_ctx_free(isl_ctx);
336 static void
337 visit (tree_node *t, void *d)
339 ((dumper *)d)->visit(t);
342 void dumper::scan()
344 root = 0;
345 tp->map(::visit, (void *) this);
348 void dump(tree_proc *tp, context_info *ctx, int argc, char * argv[])
350 dumper d(tp, ctx);
351 d.scan();
352 d.dump(argc, argv);