7 #include <barvinok/isl.h>
9 #include "size_bernstein.h"
10 #include "size_simulate.h"
11 #include "size_options.h"
20 #ifndef USE_SIZE_SIMULATE
21 int selfloop_size_simulate(__isl_take isl_map
*dep
, __isl_take isl_set
*read
)
29 static bool is_rectangular_dependence(__isl_keep isl_map
*dep
)
34 ok
= isl_map_is_translation(dep
);
39 dom
= isl_map_domain(isl_map_copy(dep
));
40 ok
= isl_set_is_box(dom
);
47 /* Compute the number of tokens in the FIFO at the reference point(s) ref.
48 * That is, the number of dependences that have started but not finished
49 * before any point in ref. Note that the same read iteration may
50 * depend on several write iterations, so we cannot simply count the
51 * number of writes and reads and take the differences, as the total
52 * number of reads may be smaller than the total number of writes.
53 * Instead, we set up two mappings between the reference point
54 * and the dependences, one where the write happens before the
55 * reference point and one where the read happens before the reference
56 * point. We then take the set difference and then count the number
57 * of elements in this difference.
59 isl_pw_qpolynomial
*selfloop_tokens_in_fifo(__isl_take isl_map
*dep
,
60 __isl_take isl_set
*ref
)
64 isl_map
*read_before_ref
;
65 isl_map
*write_before_ref
;
67 dep
= isl_map_make_disjoint(dep
);
68 ref
= isl_set_make_disjoint(ref
);
70 d
= isl_map_dim(dep
, isl_dim_in
);
71 dep
= isl_map_move_dims(dep
, isl_dim_in
, d
, isl_dim_out
, 0, d
);
72 dep_set
= isl_map_domain(dep
);
74 read_before_ref
= isl_map_lex_gt(isl_set_get_space(ref
));
75 read_before_ref
= isl_map_intersect_domain(read_before_ref
, ref
);
76 write_before_ref
= isl_map_copy(read_before_ref
);
78 read_before_ref
= isl_map_insert_dims(read_before_ref
, isl_dim_out
, 0, d
);
79 write_before_ref
= isl_map_add_dims(write_before_ref
, isl_dim_out
, d
);
81 read_before_ref
= isl_map_intersect_range(read_before_ref
,
82 isl_set_copy(dep_set
));
83 write_before_ref
= isl_map_intersect_range(write_before_ref
, dep_set
);
85 write_before_ref
= isl_map_subtract(write_before_ref
, read_before_ref
);
87 return isl_map_card(write_before_ref
);
90 /* Compute the maximum of the difference in number of writes and number
91 * of reads before any read. The difference is equal to the number
92 * of token in the FIFO and the maximum is the buffer size of the FIFO.
93 * The procedure assumes that the dependence is non-parametric and
94 * may actually iterate over all reads to compute the maximum.
96 static int selfloop_size_full(__isl_take isl_map
*dep
,
97 __isl_take isl_set
*ref
)
99 isl_pw_qpolynomial
*qp_diff
;
103 qp_diff
= selfloop_tokens_in_fifo(dep
, ref
);
105 v
= isl_pw_qpolynomial_max(qp_diff
);
106 assert(isl_val_is_int(v
));
108 size
= isl_val_get_num_si(v
);
115 enumerator::operator pdg::enumerator
*() const
119 return new pdg::enumerator(v
);
122 isl_printer
*printer
;
125 printer
= isl_printer_to_str(pdg
->get_isl_ctx());
126 printer
= isl_printer_set_output_format(printer
, ISL_FORMAT_C
);
128 printer
= isl_printer_print_pw_qpolynomial(printer
, pwqp
);
130 printer
= isl_printer_print_pw_qpolynomial_fold(printer
, pwf
);
131 str
= isl_printer_get_str(printer
);
133 isl_printer_free(printer
);
135 return new pdg::enumerator(s
);
142 integer
*enumerator::evaluate() const
146 return new integer(v
);
154 dim
= isl_space_params_alloc(pdg
->get_isl_ctx(), pdg
->params
.size());
155 isl_dim_set_parameter_names(dim
, pdg
->params
);
156 pnt
= isl_point_zero(dim
);
157 for (int i
= 0; i
< pdg
->params
.size(); ++i
) {
158 int n
= pdg
->params
[i
]->value
->v
;
159 pnt
= isl_point_add_ui(pnt
, isl_dim_param
, i
, n
);
161 if (type
== enumerator::qp
)
162 n
= isl_pw_qpolynomial_eval(
163 isl_pw_qpolynomial_copy(pwqp
), pnt
);
165 n
= isl_pw_qpolynomial_fold_eval(
166 isl_pw_qpolynomial_fold_copy(pwf
), pnt
);
167 n
= isl_val_floor(n
);
168 v
= isl_val_get_num_si(n
);
170 return new integer(v
);
178 size::enumerator
*selfloop_size(pdg::PDG
*pdg
, __isl_take isl_map
*dep
,
179 size_options
*options
)
181 int nparam
= isl_map_dim(dep
, isl_dim_param
);
184 assert(isl_map_dim(dep
, isl_dim_in
) == isl_map_dim(dep
, isl_dim_out
));
186 read
= isl_map_range(isl_map_copy(dep
));
188 bool rect
= !nparam
&& is_rectangular_dependence(dep
);
190 size::enumerator
*e
= NULL
;
191 if (!nparam
&& options
->flags
!= SIZE_BERNSTEIN
) {
193 if (options
->flags
== SIZE_SIMULATE
) {
194 maxsize
= selfloop_size_simulate(dep
, read
);
196 maxsize
= selfloop_size_full(dep
, read
);
198 isl_set
*ref
= isl_set_lexmin(read
);
199 maxsize
= selfloop_size_full(dep
, ref
);
201 e
= new enumerator(maxsize
);
203 e
= selfloop_size_bernstein(pdg
, dep
, read
);