44 #include <osl/macros.h> 46 #include <osl/relation.h> 47 #include <clan/macros.h> 73 CLAN_error(
"relation cannot be array-tagged");
75 osl_relation_insert_blank_row(relation, 0);
76 osl_relation_insert_blank_column(relation, 1);
77 osl_int_set_si(relation->precision, &relation->m[0][1], -1);
78 osl_int_set_si(relation->precision,
79 &relation->m[0][relation->nb_columns - 1], array);
80 relation->nb_output_dims++;
96 osl_relation_p context = NULL;
99 context = osl_relation_pmalloc(options->
precision,
100 nb_parameters, nb_parameters + 2);
101 for (i = 0; i < nb_parameters; i++) {
102 osl_int_set_si(options->
precision, &context->m[i][0], 1);
103 osl_int_set_si(options->
precision, &context->m[i][i + 1], 1);
105 &context->m[i][context->nb_columns - 1], 1);
108 context = osl_relation_pmalloc(options->
precision, 0, nb_parameters + 2);
110 osl_relation_set_type(context, OSL_TYPE_CONTEXT);
111 osl_relation_set_attributes(context, 0, 0, 0, nb_parameters);
135 int i, j, nb_rows, nb_columns;
136 int beta_col, alpha_col;
137 osl_relation_p scattering;
139 nb_rows = (2 * depth + 1);
140 nb_columns = (2 * depth + 1) + (depth) + (CLAN_MAX_PARAMETERS) + 2;
141 scattering = osl_relation_pmalloc(precision, nb_rows, nb_columns);
142 osl_relation_set_type(scattering, OSL_TYPE_SCATTERING);
143 osl_relation_set_attributes(scattering, 2 * depth + 1, depth, 0,
144 CLAN_MAX_PARAMETERS);
147 for (i = 0; i < 2 * depth + 1; i++)
148 osl_int_set_si(precision, &scattering->m[i][i + 1], -1);
152 beta_col = nb_columns - 1;
153 for (i = 0; i < depth; i++) {
154 alpha_col = (2 * depth + 1) + i + 1;
155 osl_int_set_si(precision, &scattering->m[j][beta_col], vector[j]);
156 osl_int_set_si(precision, &scattering->m[j+1][alpha_col], vector[j+1]);
159 osl_int_set_si(precision, &scattering->m[nb_rows-1][beta_col], vector[j]);
176 osl_vector_p vector) {
177 int i, new_col, new_row;
179 if (relation == NULL)
180 CLAN_error(
"cannot add a new output dimension to a NULL relation");
181 else if (vector == NULL)
182 CLAN_error(
"cannot add a NULL expression of an output dimension");
183 else if (relation->precision != vector->precision)
184 CLAN_error(
"incompatible precisions");
186 if (relation->nb_output_dims == OSL_UNDEFINED)
189 new_col = relation->nb_output_dims + 1;
190 new_row = relation->nb_rows;
192 if ((relation->nb_columns - (new_col - 1)) != vector->size)
193 CLAN_error(
"incompatible sizes");
194 else if (!osl_int_zero(vector->precision, vector->v[0]))
195 CLAN_error(
"the output dimension expression should be an equality");
198 osl_relation_insert_blank_column(relation, new_col);
199 osl_relation_insert_blank_row(relation, new_row);
200 relation->nb_output_dims = new_col;
203 osl_int_set_si(relation->precision, &relation->m[new_row][new_col], -1);
204 for (i = 1; i < vector->size; i++)
205 osl_int_assign(relation->precision,
206 &relation->m[new_row][new_col + i], vector->v[i]);
221 int new_col, new_row;
223 if (relation == NULL)
224 CLAN_error(
"cannot add a new output dimension to a NULL relation");
226 if (relation->nb_output_dims == OSL_UNDEFINED)
229 new_col = relation->nb_output_dims + 1;
230 new_row = relation->nb_rows;
233 osl_relation_insert_blank_column(relation, new_col);
234 osl_relation_insert_blank_row(relation, new_row);
235 relation->nb_output_dims = new_col;
238 osl_int_set_si(relation->precision, &relation->m[new_row][new_col], -1);
239 osl_int_set_si(relation->precision,
240 &relation->m[new_row][relation->nb_columns - 1], scalar);
255 int i, j, nb_columns;
256 int nb_output_dims, nb_input_dims, nb_local_dims, nb_out_in_loc;
257 osl_relation_p compacted;
259 while (relation != NULL) {
260 nb_output_dims = relation->nb_output_dims;
261 nb_input_dims = relation->nb_input_dims;
262 nb_local_dims = relation->nb_local_dims;
263 nb_out_in_loc = nb_output_dims + nb_input_dims + nb_local_dims;
265 nb_columns = nb_out_in_loc + nb_parameters + 2;
266 compacted = osl_relation_pmalloc(relation->precision,
267 relation->nb_rows, nb_columns);
269 for (i = 0; i < relation->nb_rows; i++) {
271 for (j = 0; j <= nb_output_dims + nb_input_dims; j++)
272 osl_int_assign(relation->precision,
273 &compacted->m[i][j], relation->m[i][j]);
276 for (j = 0; j < nb_local_dims; j++)
277 osl_int_assign(relation->precision,
278 &compacted->m[i][nb_output_dims + nb_input_dims + 1 + j],
279 relation->m[i][CLAN_MAX_DEPTH + 1 + j]);
282 for (j = 0; j < nb_parameters; j++)
283 osl_int_assign(relation->precision,
284 &compacted->m[i][j + nb_out_in_loc + 1],
285 relation->m[i][relation->nb_columns - CLAN_MAX_PARAMETERS -1 + j]);
288 osl_int_assign(relation->precision,
289 &compacted->m[i][nb_columns - 1],
290 relation->m[i][relation->nb_columns - 1]);
293 osl_relation_free_inside(relation);
296 relation->nb_rows = compacted->nb_rows;
297 relation->nb_columns = compacted->nb_columns;
298 relation->m = compacted->m;
299 relation->nb_parameters = nb_parameters;
304 relation = relation->next;
337 osl_int_t b_min, a_max;
339 if ((min == NULL) || (max == NULL) || (strict < 0) || (strict > 1) ||
340 (min->nb_columns != max->nb_columns))
341 CLAN_error(
"cannot compose relations");
343 precision = min->precision;
344 osl_int_init(precision, &a_max);
345 osl_int_init(precision, &b_min);
346 r = osl_relation_pmalloc(precision,
347 min->nb_rows * max->nb_rows, min->nb_columns);
350 for (imin = 0; imin < min->nb_rows; imin++) {
359 a = osl_int_get_si(precision, min->m[imin][0]);
360 a = (a == 0) ? 1 : a;
362 for (imax = 0; imax < max->nb_rows; imax++) {
364 b = osl_int_get_si(precision, max->m[imax][0]);
365 b = (b == 0) ? 1 : b;
368 for (j = 1; j < max->nb_columns; j++) {
370 osl_int_mul_si(precision, &b_min, min->m[imin][j], b);
373 osl_int_mul_si(precision, &a_max, max->m[imax][j], a);
376 osl_int_sub(precision,
377 &r->m[imin * max->nb_rows + imax][j], b_min, a_max);
381 osl_int_add_si(precision,
382 &r->m[imin * max->nb_rows + imax][max->nb_columns - 1],
383 r->m[imin * max->nb_rows + imax][max->nb_columns - 1],
386 osl_int_set_si(precision, &r->m[imin * max->nb_rows + imax][0], 1);
390 osl_int_clear(precision, &a_max);
391 osl_int_clear(precision, &b_min);
409 for (i = 1; i < relation->nb_columns; i++)
410 osl_int_oppose(relation->precision,
411 &relation->m[row][i], relation->m[row][i]);
414 osl_int_decrement(relation->precision,
415 &relation->m[row][relation->nb_columns - 1],
416 relation->m[row][relation->nb_columns - 1]);
433 osl_relation_p constraint;
435 constraint = osl_relation_pmalloc(precision, 1, relation->nb_columns);
436 constraint->type = relation->type;
437 constraint->nb_output_dims = relation->nb_output_dims;
438 constraint->nb_input_dims = relation->nb_input_dims;
439 constraint->nb_local_dims = relation->nb_local_dims;
440 constraint->nb_parameters = relation->nb_parameters;
442 for (i = 0; i < relation->nb_columns; i++)
443 osl_int_assign(precision, &constraint->m[0][i], relation->m[row][i]);
461 return (osl_int_zero(relation->precision, relation->m[row][0])) ? 1 : 0;
476 if ((relation == NULL) || (relation->nb_rows < row))
477 CLAN_error(
"the constraint cannot be inquality-tagged");
478 osl_int_set_si(relation->precision, &relation->m[row][0], 1);
493 if ((relation == NULL) || (relation->nb_rows < row))
494 CLAN_error(
"the constraint cannot be equality-tagged");
495 osl_int_set_si(relation->precision, &relation->m[row][0], 0);
509 osl_relation_p tmp, tmp_eq = NULL;
511 if (row > relation->nb_rows)
525 osl_int_decrement(relation->precision,
526 &tmp_eq->m[0][tmp_eq->nb_columns - 1],
527 tmp_eq->m[0][tmp_eq->nb_columns - 1]);
547 osl_relation_p not_constraint;
548 osl_relation_p not = NULL, part;
550 while (relation != NULL) {
553 for (i = 0; i < relation->nb_rows; i++) {
555 osl_relation_add(&part, not_constraint);
563 osl_relation_free(part);
565 relation = relation->next;
581 osl_relation_p next_dest,
589 dup_dest = osl_relation_clone(dest);
590 if (dest == NULL || src == NULL)
594 while (next_src != NULL) {
596 while(next_dest != NULL) {
597 osl_relation_insert_constraints(next_dest, next_src, next_dest->nb_rows);
598 next_mem = next_dest;
599 next_dest = next_dest->next;
601 if (next_src->next != NULL)
602 next_mem->next = osl_relation_clone(dup_dest);
604 next_mem->next = NULL;
607 next_src = next_src->next;
608 next_dest = next_mem->next;
610 osl_relation_free(dup_dest);
624 while (relation != NULL) {
625 for (i = 0; i < relation->nb_rows; i++) {
626 for (j = CLAN_MAX_DEPTH + 1;
627 j < CLAN_MAX_DEPTH + CLAN_MAX_LOCAL_DIMS + 1;
629 if (!osl_int_zero(relation->precision, relation->m[i][j]))
633 relation = relation->next;
653 if ((row < 0) || (row >= r->nb_rows))
654 CLAN_error(
"bad row number");
656 for (i = 1; i < r->nb_columns; i++)
657 osl_int_oppose(r->precision, &r->m[row][i], r->m[row][i]);
677 osl_relation_p* bound,
678 osl_relation_p* notbound,
679 int depth,
int lower) {
681 osl_relation_p constraint;
686 if ((depth < 1) || (depth > CLAN_MAX_DEPTH))
687 CLAN_error(
"bad depth");
689 if ((lower < 0) || (lower > 1))
690 CLAN_error(
"lower parameter must be 0 or 1");
693 precision = r->precision;
694 *bound = osl_relation_pmalloc(precision, 0, r->nb_columns);
695 osl_relation_set_attributes(*bound,
700 *notbound = osl_relation_pmalloc(precision, 0, r->nb_columns);
701 osl_relation_set_attributes(*notbound,
708 for (i = 0; i < r->nb_rows; i++) {
711 if (osl_int_zero(precision, constraint->m[0][depth])) {
713 osl_relation_insert_constraints(*notbound, constraint, -1);
714 }
else if (osl_int_zero(precision, constraint->m[0][0])) {
717 osl_int_set_si(precision, &constraint->m[0][0], 1);
718 osl_relation_insert_constraints(*bound, constraint, -1);
719 osl_relation_insert_constraints(*notbound, constraint, -1);
720 if ((lower && osl_int_pos(precision, constraint->m[0][depth])) ||
721 (!lower && osl_int_neg(precision, constraint->m[0][depth]))) {
728 if ((lower && osl_int_pos(precision, constraint->m[0][depth])) ||
729 (!lower && osl_int_neg(precision, constraint->m[0][depth]))) {
730 osl_relation_insert_constraints(*bound, constraint, -1);
732 osl_relation_insert_constraints(*notbound, constraint, -1);
735 osl_relation_free(constraint);
757 for (i = 0; i < r->nb_rows; i++) {
758 mark = osl_int_get_si(r->precision, r->m[i][0]);
759 coef = osl_int_get_si(r->precision, r->m[i][depth]);
760 if ((mark != 1) || (coef == 0))
761 CLAN_error(
"you found a bug");
766 coef = (coef > 0) ? coef : -coef;
768 osl_int_set_si(r->precision, &r->m[i][0], coef);
770 osl_int_set_si(r->precision, &r->m[i][0], 0);
771 osl_int_set_si(r->precision, &r->m[i][depth], 0);
790 osl_relation_p contribution;
791 osl_relation_p constraint;
792 osl_relation_p bound, notbound;
794 osl_relation_p full = NULL;
797 CLAN_error(
"invalid loop depth");
798 else if (stride == 0)
799 CLAN_error(
"unsupported zero stride");
801 precision = r->precision;
802 lower = (stride > 0) ? 1 : 0;
803 stride = (stride > 0) ? stride : -stride;
818 for (i = 0; i < bound->nb_rows; i++) {
829 osl_int_add_si(precision,
830 &bound->m[i - 1][bound->nb_columns - 1],
831 bound->m[i - 1][bound->nb_columns - 1], 1);
833 osl_int_add_si(precision,
834 &bound->m[i - 1][bound->nb_columns - 1],
835 bound->m[i - 1][bound->nb_columns - 1], -1);
846 osl_relation_remove_row(contribution, i);
851 osl_relation_insert_constraints(contribution, constraint, -1);
860 osl_int_set_si(precision,
861 &contribution->m[contribution->nb_rows - 1][depth], 1);
863 osl_int_set_si(precision,
864 &contribution->m[contribution->nb_rows - 1][depth], -1);
868 osl_int_set_si(precision,
869 &contribution->m[contribution->nb_rows - 1][0], 1);
873 osl_relation_insert_constraints(contribution, constraint, -1);
875 osl_int_set_si(precision,
876 &contribution->m[contribution->nb_rows - 1][depth], -1);
879 osl_int_set_si(precision,
880 &contribution->m[contribution->nb_rows - 1]
883 osl_relation_free(constraint);
884 osl_relation_add(&part, contribution);
889 osl_relation_free(bound);
890 osl_relation_free(part);
891 osl_relation_add(&full, notbound);
915 int pivot_row,
int pivot_column) {
916 int i, j, same_sign,
precision, identical;
917 osl_int_p temp, pivot_coef, current_coef;
919 if (relation == NULL)
922 precision = relation->precision;
924 if (relation->next != NULL)
925 OSL_debug(
"gaussian elimination works only on the first part of unions");
927 if ((pivot_row >= relation->nb_rows) || (pivot_row < 0) ||
928 (pivot_column >= relation->nb_columns) || (pivot_column < 0))
929 OSL_error(
"bad pivot position");
931 if (osl_int_zero(precision, relation->m[pivot_row][pivot_column]))
932 OSL_error(
"pivot value is 0");
934 if (!osl_int_zero(precision, relation->m[pivot_row][0]))
935 OSL_warning(
"pivot not in an equality: non equivalent simplified relation");
943 temp = osl_int_malloc(precision);
944 pivot_coef = osl_int_malloc(precision);
945 current_coef = osl_int_malloc(precision);
946 for (i = 0; i < relation->nb_rows; i++) {
953 same_sign = (osl_int_neg(precision, relation->m[pivot_row][pivot_column])&&
954 osl_int_neg(precision, relation->m[i][pivot_column])) ||
955 (osl_int_pos(precision, relation->m[pivot_row][pivot_column])&&
956 osl_int_pos(precision, relation->m[i][pivot_column]));
957 if ((i != pivot_row) &&
958 (!osl_int_zero(precision, relation->m[i][pivot_column])) &&
959 (osl_int_zero(precision, relation->m[pivot_row][0]) ||
960 !osl_int_zero(precision, relation->m[i][0]))) {
961 if (osl_int_zero(precision, relation->m[pivot_row][0]) ||
962 osl_int_zero(precision, relation->m[i][0]) || !same_sign) {
967 osl_int_assign(precision,
968 pivot_coef, relation->m[pivot_row][pivot_column]);
969 osl_int_assign(precision,
970 current_coef, relation->m[i][pivot_column]);
972 if (osl_int_zero(precision, relation->m[pivot_row][0])) {
973 osl_int_oppose(precision, current_coef, *current_coef);
975 osl_int_oppose(precision, pivot_coef, *pivot_coef);
978 osl_int_abs(precision, pivot_coef, *pivot_coef);
979 osl_int_abs(precision, current_coef, *current_coef);
983 for (j = 1; j < relation->nb_columns; j++) {
984 osl_int_mul(precision,
985 temp, *current_coef, relation->m[pivot_row][j]);
986 osl_int_mul(precision,
987 &relation->m[i][j], *pivot_coef, relation->m[i][j]);
988 osl_int_add(precision,
989 &relation->m[i][j], relation->m[i][j], *temp);
995 for (j = 1; j < relation->nb_columns; j++) {
996 if (osl_int_ne(precision,
997 relation->m[i][j], relation->m[pivot_row][j])) {
1003 for (j = 1; j < relation->nb_columns; j++)
1004 osl_int_sub(precision, &relation->m[i][j],
1005 relation->m[i][j], relation->m[i][j]);
1010 osl_int_free(precision, temp);
1011 osl_int_free(precision, pivot_coef);
1012 osl_int_free(precision, current_coef);
1025 osl_relation_p test, temp;
1027 test = relation->next;
1028 while (relation != NULL) {
1029 while (test != NULL) {
1030 if (osl_relation_part_equal(relation, test)) {
1033 if (relation->next == temp)
1034 relation->next = test;
1036 osl_relation_free(temp);
1041 relation = relation->next;
1055 int i, j, k, to_eliminate, offset;
1056 osl_relation_p gauss, reference_gauss, reference = relation;
1058 gauss = osl_relation_clone(relation);
1059 reference_gauss = gauss;
1060 while (relation != NULL) {
1062 for (j = 1; j < gauss->nb_columns; j++) {
1070 for (i = 0; i < gauss->nb_rows; i++) {
1071 if (!osl_int_zero(gauss->precision, gauss->m[i][j]) &&
1072 osl_int_zero(gauss->precision, gauss->m[i][0])) {
1074 for (k = 1; k < j; k++)
1075 if (!osl_int_zero(gauss->precision, gauss->m[i][k]))
1085 for (i = 0; i < gauss->nb_rows; i++) {
1086 for (k = i + 1; k < gauss->nb_rows; k++) {
1088 for (j = 1; j < gauss->nb_columns; j++) {
1089 if (osl_int_ne(gauss->precision, gauss->m[i][j], gauss->m[k][j])) {
1095 for (j = 1; j < gauss->nb_columns; j++)
1096 osl_int_sub(gauss->precision, &gauss->m[k][j],
1097 gauss->m[k][j], gauss->m[k][j]);
1103 for (i = 0; i < gauss->nb_rows; i++) {
1104 if (osl_int_pos(gauss->precision, gauss->m[i][gauss->nb_columns - 1]) &&
1105 !osl_int_zero(gauss->precision, gauss->m[i][0])) {
1107 for (j = 1; j < gauss->nb_columns - 1; j++) {
1108 if (!osl_int_zero(gauss->precision, gauss->m[i][j])) {
1114 osl_int_sub(gauss->precision,
1115 &gauss->m[i][gauss->nb_columns - 1],
1116 gauss->m[i][gauss->nb_columns - 1],
1117 gauss->m[i][gauss->nb_columns - 1]);
1124 for (i = 0; i < gauss->nb_rows; i++) {
1126 for (j = 1; j < gauss->nb_columns; j++) {
1127 if (!osl_int_zero(gauss->precision, gauss->m[i][j])) {
1133 osl_relation_remove_row(relation, i - offset);
1138 gauss = gauss->next;
1139 relation = relation->next;
1141 osl_relation_free(reference_gauss);
1163 osl_relation_p initialization,
1166 osl_relation_p contextual = NULL, temp, first_condition, new_condition;
1168 if ((condition == NULL) || (initialization == NULL))
1171 if (initialization->next != NULL)
1172 OSL_error(
"cannot compute the loop context for an initialization union");
1174 if (initialization->nb_columns != condition->nb_columns)
1175 OSL_error(
"imcompatible number of columns");
1177 for (i = 0; i < initialization->nb_rows; i++)
1178 if (osl_int_zero(initialization->precision, initialization->m[i][0]))
1179 OSL_error(
"no equality is allowed in the initialization relation");
1181 first_condition = condition;
1183 for (i = 0; i < initialization->nb_rows; i++) {
1184 condition = first_condition;
1186 while (condition != NULL) {
1189 temp = osl_relation_nclone(condition, 1);
1190 osl_relation_insert_blank_row(temp, 0);
1191 for (j = 0; j < temp->nb_columns; j++)
1192 osl_int_assign(temp->precision,
1193 &temp->m[0][j], initialization->m[i][j]);
1196 osl_relation_remove_row(temp, 0);
1199 new_condition = osl_relation_nclone(condition, 1);
1200 osl_relation_insert_constraints(new_condition, temp, -1);
1202 osl_relation_free(temp);
1203 osl_relation_add(&contextual, new_condition);
1204 condition = condition->next;
1208 condition = first_condition;
1209 osl_relation_free_inside(condition);
1210 osl_relation_free(condition->next);
1213 condition->nb_rows = contextual->nb_rows;
1214 condition->m = contextual->m;
1215 condition->next = contextual->next;
static void clan_relation_gaussian_elimination(osl_relation_p relation, int pivot_row, int pivot_column)
static void clan_relation_tag_inequality(osl_relation_p relation, int row)
osl_relation_p clan_relation_greater(osl_relation_p min, osl_relation_p max, int strict)
static void clan_relation_negate_inequality(osl_relation_p relation, int row)
osl_relation_p clan_relation_stride(osl_relation_p r, int depth, int stride)
void clan_parser_add_ld(void)
static void clan_relation_to_expressions(osl_relation_p r, int depth)
static void clan_relation_tag_equality(osl_relation_p relation, int row)
osl_relation_p clan_relation_not(osl_relation_p relation)
void clan_relation_tag_array(osl_relation_p relation, int array)
static void clan_relation_extract_bounding(osl_relation_p r, osl_relation_p *bound, osl_relation_p *notbound, int depth, int lower)
void clan_relation_and(osl_relation_p dest, osl_relation_p src)
int clan_parser_nb_ld(void)
void clan_relation_new_output_scalar(osl_relation_p relation, int scalar)
static osl_relation_p clan_relation_extract_constraint(osl_relation_p relation, int row)
void clan_relation_new_output_vector(osl_relation_p relation, osl_vector_p vector)
osl_relation_p clan_relation_scattering(int *vector, int depth, int precision)
static void clan_relation_simplify_parts(osl_relation_p relation)
static int clan_relation_is_equality(osl_relation_p relation, int row)
osl_relation_p clan_relation_build_context(int nb_parameters, clan_options_p options)
void clan_relation_oppose_row(osl_relation_p r, int row)
void clan_relation_compact(osl_relation_p relation, int nb_parameters)
void clan_relation_simplify(osl_relation_p relation)
void clan_relation_loop_context(osl_relation_p condition, osl_relation_p initialization, int depth)
int clan_relation_existential(osl_relation_p relation)
static osl_relation_p clan_relation_constraint_not(osl_relation_p relation, int row)