X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=isl_tab_pip.c;h=2592a285c0e179164254439f4b2c0e0d84bd12ed;hb=da1dc20cb7aa4509e375f703c35beaf27dfa4a15;hp=d5ed6548e9deed050deb9e484ee6de30588074f1;hpb=07bca32eef20102a070cc4c8d6a86f1aa8d8560e;p=platform%2Fupstream%2Fisl.git diff --git a/isl_tab_pip.c b/isl_tab_pip.c index d5ed654..2592a28 100644 --- a/isl_tab_pip.c +++ b/isl_tab_pip.c @@ -124,6 +124,8 @@ struct isl_context_lex { * "M" describes the solution in terms of the dimensions of "dom". * The number of columns of "M" is one more than the total number * of dimensions of "dom". + * + * If "M" is NULL, then there is no solution on "dom". */ struct isl_partial_sol { int level; @@ -322,11 +324,15 @@ static void sol_pop(struct isl_sol *sol) isl_basic_set_free(partial->next->dom); partial->next->dom = bset; M = partial->next->M; - M = isl_mat_drop_cols(M, M->n_col - n, n); - partial->next->M = M; + if (M) { + M = isl_mat_drop_cols(M, M->n_col - n, n); + partial->next->M = M; + if (!M) + goto error; + } partial->next->level = sol->level; - if (!bset || !M) + if (!bset) goto error; sol->partial = partial->next; @@ -3870,6 +3876,24 @@ error: sol->error = 1; } +/* Does "sol" contain a pair of partial solutions that could potentially + * be merged? + * + * We currently only check that "sol" is not in an error state + * and that there are at least two partial solutions of which the final two + * are defined at the same level. + */ +static int sol_has_mergeable_solutions(struct isl_sol *sol) +{ + if (sol->error) + return 0; + if (!sol->partial) + return 0; + if (!sol->partial->next) + return 0; + return sol->partial->level == sol->partial->next->level; +} + /* Compute the lexicographic minimum of the set represented by the main * tableau "tab" within the context "sol->context_tab". * @@ -3880,10 +3904,20 @@ error: * corresponding rows may not be marked as being non-negative. * In parts of the context where the added equality does not hold, * the main tableau is marked as being empty. + * + * Before we embark on the actual computation, we save a copy + * of the context. When we return, we check if there are any + * partial solutions that can potentially be merged. If so, + * we perform a rollback to the initial state of the context. + * The merging of partial solutions happens inside calls to + * sol_dec_level that are pushed onto the undo stack of the context. + * If there are no partial solutions that can potentially be merged + * then the rollback is skipped as it would just be wasted effort. */ static void find_solutions_main(struct isl_sol *sol, struct isl_tab *tab) { int row; + void *saved; if (!tab) goto error; @@ -3933,8 +3967,15 @@ static void find_solutions_main(struct isl_sol *sol, struct isl_tab *tab) row = tab->n_redundant - 1; } + saved = sol->context->op->save(sol->context); + find_solutions(sol, tab); + if (sol_has_mergeable_solutions(sol)) + sol->context->op->restore(sol->context, saved); + else + sol->context->op->discard(saved); + sol->level = 0; sol_pop(sol);