2 * Copyright 2011 Leiden University. All rights reserved.
7 #include <libxml/xmlwriter.h>
8 #include <isl/union_map.h>
9 #include <cloog/isl/cloog.h>
13 static void writeVar(xmlTextWriterPtr writer
, adg_var
*var
)
18 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"name",
19 BAD_CAST var
->get_expr());
23 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"dataType",
24 BAD_CAST
isl_id_get_name(var
->type
));
28 static void writeVar(xmlTextWriterPtr writer
, const char *type
, adg_var
*var
)
32 rc
= xmlTextWriterStartElement(writer
, BAD_CAST type
);
35 writeVar(writer
, var
);
37 rc
= xmlTextWriterEndElement(writer
);
41 static void writeArg(xmlTextWriterPtr writer
, const char *type
, adg_arg
*arg
)
45 rc
= xmlTextWriterStartElement(writer
, BAD_CAST type
);
48 writeVar(writer
, arg
->var
);
52 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"pass",
56 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"pass",
57 BAD_CAST
"return_value");
59 case adg_arg_reference
:
60 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"pass",
61 BAD_CAST
"reference");
69 rc
= xmlTextWriterEndElement(writer
);
73 /* Print "v * name" onto os.
75 static void print_term(std::ostringstream
&os
, isl_int v
, const char *name
)
77 if (!isl_int_is_one(v
)) {
78 os
<< isl_int_get_si(v
);
84 static void print_aff_expr(std::ostringstream
&os
, __isl_keep isl_aff
*aff
);
86 /* Print "v * div(aff)" onto os.
88 static void print_term(std::ostringstream
&os
, isl_int v
,
89 __isl_take isl_aff
*aff
)
96 print_aff_expr(os
, aff
);
98 isl_aff_get_denominator(aff
, &d
);
99 os
<< isl_int_get_si(d
);
105 /* Print "aff" onto os.
107 static void print_aff_expr(std::ostringstream
&os
, __isl_keep isl_aff
*aff
)
111 enum isl_dim_type types
[] = { isl_dim_in
, isl_dim_param
, isl_dim_div
};
112 int n_type
= sizeof(types
)/sizeof(*types
);
116 for (int t
= 0; t
< n_type
; ++t
) {
117 for (int i
= 0; i
< isl_aff_dim(aff
, types
[t
]); ++i
) {
118 isl_aff_get_coefficient(aff
, types
[t
], i
, &v
);
119 if (isl_int_is_zero(v
))
121 if (!first
&& isl_int_is_pos(v
))
123 if (types
[t
] == isl_dim_div
) {
125 div
= isl_aff_get_div(aff
, i
);
126 print_term(os
, v
, div
);
129 name
= isl_aff_get_dim_name(aff
, types
[t
], i
);
130 print_term(os
, v
, name
);
136 isl_aff_get_constant(aff
, &v
);
137 if (first
|| !isl_int_is_zero(v
)) {
138 if (!first
&& isl_int_is_pos(v
))
140 os
<< isl_int_get_si(v
);
146 struct print_pw_aff_data
{
147 std::ostringstream
&os
;
148 std::vector
<isl_id
*> &iterators
;
151 print_pw_aff_data(std::ostringstream
&os
,
152 std::vector
<isl_id
*> &iterators
) :
153 os(os
), iterators(iterators
), first(true) {}
157 static int print_pw_aff_piece(__isl_take isl_set
*set
,
158 __isl_take isl_aff
*aff
, void *user
);
161 /* Print a single piece of an isl_pw_aff.
162 * We currently assume that there is only a single piece
163 * and abort if there happens to be more than one.
165 static int print_pw_aff_piece(__isl_take isl_set
*set
,
166 __isl_take isl_aff
*aff
, void *user
)
168 struct print_pw_aff_data
*data
= (struct print_pw_aff_data
*) user
;
172 print_aff_expr(data
->os
, aff
);
181 static void print_pw_aff_expr(std::ostringstream
&os
, __isl_keep isl_pw_aff
*pa
,
182 std::vector
<isl_id
*> &iterators
)
184 struct print_pw_aff_data
data(os
, iterators
);
185 isl_pw_aff_foreach_piece(pa
, &print_pw_aff_piece
, &data
);
188 static void writeExpr(xmlTextWriterPtr writer
, const char *type
,
189 const char *expr_name
, adg_expr
*expr
, adg
*graph
)
192 std::ostringstream strm
;
194 rc
= xmlTextWriterStartElement(writer
, BAD_CAST type
);
198 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"name",
199 BAD_CAST
isl_id_get_name(expr
->name
));
203 print_pw_aff_expr(strm
, expr
->expr
, graph
->iterators
);
204 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST expr_name
,
205 BAD_CAST strm
.str().c_str());
208 rc
= xmlTextWriterEndElement(writer
);
212 /* Write out the rows of "mat", each prefixed by the integer "ineq".
213 * The rows are separated by ";". If first is false, then we
214 * also include a ";" before the first row.
216 static void writeMatrix(std::ostream
&os
, __isl_keep isl_mat
*mat
,
217 int ineq
, bool first
)
223 for (i
= 0; i
< isl_mat_rows(mat
); ++i
) {
228 for (j
= 0; j
< isl_mat_cols(mat
); ++j
) {
229 isl_mat_get_element(mat
, i
, j
, &v
);
230 os
<< ", " << isl_int_get_si(v
);
236 /* Find the number of dynamic control variables in "space".
238 * The dynamic control variables, if any, are located in the range
239 * of a wrapped map, with the (possibly lifted) iteration domain
240 * in the domain. After adding the dynamic control variables, the
241 * result may have been lifted as well, so we need dig through
242 * any possible lifting of the form
244 * D -> [D -> local[..]]
246 * until we arrive at the iteration domain, in which case there
247 * are no dynamic control variables, or until we find the control
250 static int n_dynamic_in_space(__isl_take isl_space
*space
)
254 if (!isl_space_is_wrapping(space
)) {
255 isl_space_free(space
);
258 space
= isl_space_unwrap(space
);
259 if (isl_space_has_tuple_id(space
, isl_dim_out
))
260 return n_dynamic_in_space(isl_space_domain(space
));
261 n
= isl_space_dim(space
, isl_dim_out
);
262 isl_space_free(space
);
266 /* Find the position of the first dynamic control variable in "space".
268 * See n_dynamic_in_space.
270 static int pos_dynamic_in_space(__isl_take isl_space
*space
)
274 if (!isl_space_is_wrapping(space
)) {
275 isl_space_free(space
);
278 space
= isl_space_unwrap(space
);
279 if (isl_space_has_tuple_id(space
, isl_dim_out
))
280 return pos_dynamic_in_space(isl_space_domain(space
));
281 pos
= isl_space_dim(space
, isl_dim_in
);
282 isl_space_free(space
);
286 /* Write a matrix corresponding to the constraints of "bset".
287 * The order of the dimensions in the matrix is a follows.
289 * iterators static_controls dynamic_controls parameters constant
291 * Inside "bset", however, in the set dimensions, the dynamic
292 * controls may appear in the middle of the static controls.
294 * We therefore need to move the dynamic controls.
295 * "pos_dynamic" indicates the position of the first dynamic control.
296 * "n_dynamic" indicates the number of dynamic controls.
298 static void writeMatrix(xmlTextWriterPtr writer
, const char *name
,
299 __isl_keep isl_basic_set
*bset
, int n_dynamic
)
303 std::ostringstream strm
;
305 int n_set
= isl_basic_set_dim(bset
, isl_dim_set
);
306 int pos_dynamic
= pos_dynamic_in_space(isl_basic_set_get_space(bset
));
308 rc
= xmlTextWriterStartElement(writer
, BAD_CAST name
);
312 mat
= isl_basic_set_equalities_matrix(bset
,
313 isl_dim_set
, isl_dim_div
, isl_dim_param
, isl_dim_cst
);
314 mat
= isl_mat_move_cols(mat
, n_set
- n_dynamic
, pos_dynamic
, n_dynamic
);
315 writeMatrix(strm
, mat
, 0, first
);
316 first
= isl_mat_rows(mat
) == 0;
319 mat
= isl_basic_set_inequalities_matrix(bset
,
320 isl_dim_set
, isl_dim_div
, isl_dim_param
, isl_dim_cst
);
321 mat
= isl_mat_move_cols(mat
, n_set
- n_dynamic
, pos_dynamic
, n_dynamic
);
322 writeMatrix(strm
, mat
, 1, first
);
326 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"matrix",
327 BAD_CAST strm
.str().c_str());
330 rc
= xmlTextWriterEndElement(writer
);
334 /* Print the coefficients of the affine expression "aff",
335 * separated by commas.
337 * Note that the set dimensions of "aff" are given in the order
339 * iterators static_and_dynamic_controls
341 * while the coefficients should be printed in the order
343 * iterators static_controls dynamic_controls parameters constant
345 static void print_aff_coefficients(std::ostringstream
&os
,
346 __isl_keep isl_aff
*aff
)
355 space
= isl_aff_get_domain_space(aff
);
356 pos_dynamic
= pos_dynamic_in_space(isl_space_copy(space
));
357 n_dynamic
= n_dynamic_in_space(space
);
358 n_index
= isl_aff_dim(aff
, isl_dim_in
) - n_dynamic
;
362 for (int i
= 0; i
< pos_dynamic
; ++i
) {
365 isl_aff_get_coefficient(aff
, isl_dim_in
, i
, &v
);
366 os
<< isl_int_get_si(v
);
370 for (int i
= pos_dynamic
; i
< n_index
; ++i
) {
373 isl_aff_get_coefficient(aff
, isl_dim_in
, n_dynamic
+ i
, &v
);
374 os
<< isl_int_get_si(v
);
378 for (int i
= 0; i
< n_dynamic
; ++i
) {
381 isl_aff_get_coefficient(aff
, isl_dim_in
, pos_dynamic
+ i
, &v
);
382 os
<< isl_int_get_si(v
);
386 for (int i
= 0; i
< isl_aff_dim(aff
, isl_dim_param
); ++i
) {
389 isl_aff_get_coefficient(aff
, isl_dim_param
, i
, &v
);
390 os
<< isl_int_get_si(v
);
396 isl_aff_get_constant(aff
, &v
);
397 os
<< isl_int_get_si(v
);
402 /* Write out "map" in the form of a matrix, with each row
403 * corresponding to an affine expression.
405 static void writeMatrix(xmlTextWriterPtr writer
, const char *name
,
406 __isl_keep isl_multi_aff
*map
)
409 std::ostringstream strm
;
412 rc
= xmlTextWriterStartElement(writer
, BAD_CAST name
);
416 n
= isl_multi_aff_dim(map
, isl_dim_out
);
417 for (int i
= 0; i
< n
; ++i
) {
421 aff
= isl_multi_aff_get_aff(map
, i
);
422 print_aff_coefficients(strm
, aff
);
427 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"matrix",
428 BAD_CAST strm
.str().c_str());
431 rc
= xmlTextWriterEndElement(writer
);
435 struct write_bound_data
{
436 xmlTextWriterPtr writer
;
441 static int write_bound(__isl_take isl_basic_set
*bset
, void *user
)
445 std::ostringstream strm
;
446 write_bound_data
*data
= (write_bound_data
*) user
;
447 xmlTextWriterPtr writer
= data
->writer
;
449 rc
= xmlTextWriterStartElement(writer
, BAD_CAST
"linearbound");
452 for (int i
= 0; i
< data
->graph
->iterators
.size(); ++i
) {
455 strm
<< isl_id_get_name(data
->graph
->iterators
[i
]);
458 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"index",
459 BAD_CAST strm
.str().c_str());
463 for (int i
= 0; i
< data
->domain
->controls
.size(); ++i
) {
466 strm
<< isl_id_get_name(data
->domain
->controls
[i
]->name
);
468 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"staticControl",
469 BAD_CAST strm
.str().c_str());
473 for (int i
= 0; i
< data
->domain
->filters
.size(); ++i
) {
476 strm
<< data
->domain
->filters
[i
]->get_expr();
478 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"dynamicControl",
479 BAD_CAST strm
.str().c_str());
483 nparam
= isl_basic_set_dim(bset
, isl_dim_param
);
484 for (int i
= 0; i
< nparam
; ++i
) {
487 strm
<< isl_basic_set_get_dim_name(bset
, isl_dim_param
, i
);
489 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"parameter",
490 BAD_CAST strm
.str().c_str());
493 writeMatrix(writer
, "constraint", bset
, data
->domain
->filters
.size());
495 isl_basic_set_free(bset
);
497 if (data
->graph
->context
&&
498 !isl_set_plain_is_universe(data
->graph
->context
)) {
499 assert(isl_set_n_basic_set(data
->graph
->context
) == 1);
500 bset
= isl_set_simple_hull(isl_set_copy(data
->graph
->context
));
501 writeMatrix(writer
, "context", bset
, 0);
502 isl_basic_set_free(bset
);
505 for (int i
= 0; i
< data
->domain
->controls
.size(); ++i
)
506 writeExpr(writer
, "control", "exp", data
->domain
->controls
[i
],
509 rc
= xmlTextWriterEndElement(writer
);
515 static void writeDomain(xmlTextWriterPtr writer
, adg_domain
*domain
, adg
*graph
)
518 write_bound_data data
= { writer
, domain
, graph
};
520 rc
= xmlTextWriterStartElement(writer
, BAD_CAST
"domain");
523 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"type",
527 rc
= isl_set_foreach_basic_set(domain
->bounds
, &write_bound
, &data
);
530 rc
= xmlTextWriterEndElement(writer
);
534 static void writePort(xmlTextWriterPtr writer
, adg_port
*port
, bool output
,
540 type
= output
? "outport" : "inport";
542 rc
= xmlTextWriterStartElement(writer
, BAD_CAST type
);
546 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"name",
547 BAD_CAST
isl_id_get_name(port
->name
));
548 assert(port
->node_name
);
549 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"node",
550 BAD_CAST
isl_id_get_name(port
->node_name
));
551 assert(port
->edge_name
);
552 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"edge",
553 BAD_CAST
isl_id_get_name(port
->edge_name
));
555 for (int i
= 0; i
< port
->vars
.size(); ++i
)
556 writeVar(writer
, "bindvariable", port
->vars
[i
]);
558 writeDomain(writer
, port
->domain
, graph
);
560 rc
= xmlTextWriterEndElement(writer
);
564 static void writeGate(xmlTextWriterPtr writer
, adg_gate
*gate
, adg
*graph
)
568 rc
= xmlTextWriterStartElement(writer
, BAD_CAST
"invar");
572 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"name",
573 BAD_CAST
isl_id_get_name(gate
->name
));
575 assert(gate
->in
&& gate
->in
->access
);
576 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"realName",
577 BAD_CAST gate
->in
->get_expr());
580 writeVar(writer
, "bindvariable", gate
->out
);
582 writeDomain(writer
, gate
->domain
, graph
);
584 rc
= xmlTextWriterEndElement(writer
);
588 static void writeFunction(xmlTextWriterPtr writer
, adg_function
*fn
, adg
*graph
)
592 rc
= xmlTextWriterStartElement(writer
, BAD_CAST
"function");
596 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"name",
597 BAD_CAST
isl_id_get_name(fn
->name
));
599 for (int i
= 0; i
< fn
->in
.size(); ++i
)
600 writeArg(writer
, "inargument", fn
->in
[i
]);
601 for (int i
= 0; i
< fn
->out
.size(); ++i
)
602 writeArg(writer
, "outargument", fn
->out
[i
]);
603 for (int i
= 0; i
< fn
->ctrl
.size(); ++i
)
604 writeExpr(writer
, "ctrlvar", "iterator", fn
->ctrl
[i
], graph
);
606 writeDomain(writer
, fn
->domain
, graph
);
608 rc
= xmlTextWriterEndElement(writer
);
612 /* The gates should be printed after the input ports because
613 * they may use data read through an input port.
615 static void writeNode(xmlTextWriterPtr writer
, adg_node
*node
, adg
*graph
)
619 rc
= xmlTextWriterStartElement(writer
, BAD_CAST
"node");
623 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"name",
624 BAD_CAST
isl_id_get_name(node
->name
));
626 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"levelUpNode",
630 for (int i
= 0; i
< node
->input_ports
.size(); ++i
)
631 writePort(writer
, node
->input_ports
[i
], false, graph
);
633 for (int i
= 0; i
< node
->gates
.size(); ++i
)
634 writeGate(writer
, node
->gates
[i
], graph
);
636 for (int i
= 0; i
< node
->output_ports
.size(); ++i
)
637 writePort(writer
, node
->output_ports
[i
], true, graph
);
639 for (int i
= 0; i
< node
->expressions
.size(); ++i
)
640 writeExpr(writer
, "expression", "value",
641 node
->expressions
[i
], graph
);
643 writeFunction(writer
, node
->function
, graph
);
645 writeDomain(writer
, node
->domain
, graph
);
647 rc
= xmlTextWriterEndElement(writer
);
651 static void writeEdge(xmlTextWriterPtr writer
, adg_edge
*edge
)
654 std::ostringstream strm
;
656 rc
= xmlTextWriterStartElement(writer
, BAD_CAST
"edge");
660 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"name",
661 BAD_CAST
isl_id_get_name(edge
->name
));
664 assert(edge
->from_port_name
);
665 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"fromPort",
666 BAD_CAST
isl_id_get_name(edge
->from_port_name
));
669 assert(edge
->from_node_name
);
670 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"fromNode",
671 BAD_CAST
isl_id_get_name(edge
->from_node_name
));
674 assert(edge
->to_port_name
);
675 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"toPort",
676 BAD_CAST
isl_id_get_name(edge
->to_port_name
));
679 assert(edge
->to_node_name
);
680 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"toNode",
681 BAD_CAST
isl_id_get_name(edge
->to_node_name
));
684 strm
<< edge
->value_size
;
685 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"size",
686 BAD_CAST strm
.str().c_str());
689 rc
= xmlTextWriterStartElement(writer
, BAD_CAST
"linearization");
692 switch (edge
->type
) {
694 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"type",
697 case adg_edge_sticky_fifo
:
698 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"type",
699 BAD_CAST
"sticky_fifo");
701 case adg_edge_shift_register
:
702 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"type",
703 BAD_CAST
"shift_register");
705 case adg_edge_broadcast
:
706 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"type",
707 BAD_CAST
"BroadcastInOrder");
709 case adg_edge_generic
:
710 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"type",
711 BAD_CAST
"GenericOutOfOrder");
719 rc
= xmlTextWriterEndElement(writer
);
722 writeMatrix(writer
, "mapping", edge
->map
);
724 rc
= xmlTextWriterEndElement(writer
);
728 static void writeParam(xmlTextWriterPtr writer
, adg_param
*param
, adg
*graph
)
731 std::ostringstream strm
;
733 rc
= xmlTextWriterStartElement(writer
, BAD_CAST
"parameter");
737 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"name",
738 BAD_CAST
isl_id_get_name(param
->name
));
743 print_aff_expr(strm
, param
->lb
);
744 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"lb",
745 BAD_CAST strm
.str().c_str());
751 print_aff_expr(strm
, param
->ub
);
752 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"ub",
753 BAD_CAST strm
.str().c_str());
759 print_aff_expr(strm
, param
->val
);
760 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"value",
761 BAD_CAST strm
.str().c_str());
765 rc
= xmlTextWriterEndElement(writer
);
769 static void writeADG(xmlTextWriterPtr writer
, adg
*graph
)
773 rc
= xmlTextWriterStartElement(writer
, BAD_CAST
"adg");
777 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"name",
778 BAD_CAST
isl_id_get_name(graph
->name
));
780 rc
= xmlTextWriterWriteAttribute(writer
, BAD_CAST
"levelUpNode",
784 for (int i
= 0; i
< graph
->params
.size(); ++i
)
785 writeParam(writer
, graph
->params
[i
], graph
);
787 for (int i
= 0; i
< graph
->nodes
.size(); ++i
)
788 writeNode(writer
, graph
->nodes
[i
], graph
);
790 for (int i
= 0; i
< graph
->edges
.size(); ++i
)
791 writeEdge(writer
, graph
->edges
[i
]);
793 rc
= xmlTextWriterEndElement(writer
);
797 /* Project out all the lifted variables that used to be
798 * existentially quantified. In other words, undo the lifting.
799 * Also project out the dynamic control variables.
801 static __isl_give isl_set
*unwrap(__isl_take isl_set
*dom
)
803 if (!isl_set_is_wrapping(dom
))
805 return unwrap(isl_map_domain(isl_set_unwrap(dom
)));
808 /* Construct a schedule by adding an extra pair of dimensions to
809 * domain->schedule, fixed to "offset1" and "offset2"
810 * and setting the input name to "name".
812 static __isl_give isl_map
*domain_schedule(adg_node
*node
, adg_domain
*domain
,
813 int offset1
, int offset2
, __isl_take isl_id
*name
)
819 n_out
= isl_map_dim(node
->schedule
, isl_dim_out
);
821 dom
= isl_set_copy(domain
->bounds
);
824 sched
= isl_map_copy(node
->schedule
);
825 sched
= isl_map_intersect_domain(sched
, dom
);
826 sched
= isl_map_add_dims(sched
, isl_dim_out
, 2);
827 sched
= isl_map_fix_si(sched
, isl_dim_out
, n_out
, offset1
);
828 sched
= isl_map_fix_si(sched
, isl_dim_out
, n_out
+ 1, offset2
);
829 sched
= isl_map_set_tuple_id(sched
, isl_dim_in
, name
);
834 static __isl_give isl_map
*port_schedule(adg_node
*node
, adg_port
*port
,
837 return domain_schedule(node
, port
->domain
, offset
, port
->arg_pos
,
838 isl_id_copy(port
->name
));
841 static __isl_give isl_map
*gate_schedule(adg_node
*node
, adg_gate
*gate
,
844 return domain_schedule(node
, gate
->domain
, offset
, 0,
845 isl_id_copy(gate
->name
));
848 /* Construct a schedule for all elements in the node.
849 * We add an extra dimension to node->schedule to ensure that
850 * the different elements are executed in the right order:
851 * input ports, gates, function, output ports.
852 * The input ports themselves are ordered according to the access nr.
854 static __isl_give isl_union_map
*collect_node_schedule(adg_node
*node
, int n
)
857 isl_union_map
*sched
;
860 n_out
= isl_map_dim(node
->schedule
, isl_dim_out
);
862 sched_f
= isl_map_copy(node
->schedule
);
863 sched_f
= isl_map_add_dims(sched_f
, isl_dim_out
, 2);
864 sched_f
= isl_map_fix_si(sched_f
, isl_dim_out
, n_out
, 4 * n
+ 2);
865 sched_f
= isl_map_fix_si(sched_f
, isl_dim_out
, n_out
+ 1, 0);
867 sched
= isl_union_map_from_map(sched_f
);
869 for (int i
= 0; i
< node
->input_ports
.size(); ++i
) {
871 sched_p
= port_schedule(node
, node
->input_ports
[i
], 4 * n
+ 0);
872 sched
= isl_union_map_add_map(sched
, sched_p
);
875 for (int i
= 0; i
< node
->gates
.size(); ++i
) {
877 sched_p
= gate_schedule(node
, node
->gates
[i
], 4 * n
+ 1);
878 sched
= isl_union_map_add_map(sched
, sched_p
);
881 for (int i
= 0; i
< node
->output_ports
.size(); ++i
) {
883 sched_p
= port_schedule(node
, node
->output_ports
[i
], 4 * n
+ 3);
884 sched
= isl_union_map_add_map(sched
, sched_p
);
890 /* Construct a schedule for all nodes in the graph.
892 static isl_union_map
*collect_schedule(adg
*graph
)
894 isl_space
*space
= isl_set_get_space(graph
->context
);
895 isl_union_map
*sched
= isl_union_map_empty(space
);
897 for (int i
= 0; i
< graph
->nodes
.size(); ++i
) {
898 isl_union_map
*sched_i
;
899 sched_i
= collect_node_schedule(graph
->nodes
[i
], i
);
900 sched
= isl_union_map_union(sched
, sched_i
);
906 /* Construct a schedule, convert it to a clast using CLooG and then
907 * write out the AST using writeAST.
909 static void writeAST(xmlTextWriterPtr writer
, adg
*graph
)
912 isl_ctx
*ctx
= isl_set_get_ctx(graph
->context
);
913 isl_union_map
*sched
;
914 CloogState
*cloog_state
;
915 CloogOptions
*cloog_options
;
916 CloogDomain
*context
;
917 CloogUnionDomain
*ud
;
920 sched
= collect_schedule(graph
);
922 cloog_state
= cloog_isl_state_malloc(ctx
);
923 cloog_options
= cloog_options_malloc(cloog_state
);
924 context
= cloog_domain_from_isl_set(isl_set_copy(graph
->context
));
925 ud
= cloog_union_domain_from_isl_union_map(sched
);
926 for (int i
= 0; i
< graph
->all_iterators
.size(); ++i
) {
927 const char *name
= isl_id_get_name(graph
->all_iterators
[i
]);
928 ud
= cloog_union_domain_set_name(ud
, CLOOG_SCAT
, i
, name
);
930 input
= cloog_input_alloc(context
, ud
);
931 writeAST(writer
, input
, graph
->all_iterators
.size(), cloog_options
);
932 cloog_options_free(cloog_options
);
933 cloog_state_free(cloog_state
);
936 /* Write out an XML representation of "graph" to "out".
937 * The adg part is obtained by scanning the data structure.
938 * The ast part is obtained by running cloog based on the domain schedules.
940 void adg_print_xml(adg
*graph
, FILE *out
)
943 xmlTextWriterPtr writer
;
948 writer
= xmlNewTextWriterDoc(&doc
, 0);
951 rc
= xmlTextWriterStartDocument(writer
, NULL
, NULL
, NULL
);
954 rc
= xmlTextWriterStartDTD(writer
, BAD_CAST
"sadg",
955 BAD_CAST
"-//LIACS//DTD ESPAM 1//EN",
956 BAD_CAST
"http://www.liacs.nl/~cserc/dtd/espam_1.dtd");
958 rc
= xmlTextWriterEndDTD(writer
);
961 rc
= xmlTextWriterStartElement(writer
, BAD_CAST
"sadg");
964 writeADG(writer
, graph
);
965 writeAST(writer
, graph
);
967 rc
= xmlTextWriterEndElement(writer
);
970 rc
= xmlTextWriterEndDocument(writer
);
973 xmlFreeTextWriter(writer
);
975 rc
= xmlDocFormatDump(out
, doc
, 1);