/* ddomega-use.c,v 1.1 1993/09/17 22:13:50 fbodin Exp */ /* calls to omega test to determine data dependencies from a problem (as defined in ddomega.c & built by the code in ddomega-build.c) */ #include #include "include/portable.h" #include #include #include #include "include/debug.h" #include "include/lang-interf.h" #include "include/ip.h" #include "include/ddomega-build.h" #include "include/ddomega-use.h" #include "include/ddomega.h" #include "include/omega2flags.h" #include "include/refine.h" #include "include/cover.h" #include "include/missing.h" #include "include/Exit.h" #include "include/timeTrials.h" /* information about nodes involved in dependence */ typedef struct { a_access access1, access2; ddnature oitype, iotype; uint nest1, nest2, commonNesting; } situation; void out_of_memory() { fprintf(debug2, "Memory Allocation failed\n"); Exit(2); } static dddirection dd_convert[] = { ddgt, ddeq, ddlt }; /* dd_convert(i+1) is dddirection for i */ #if !defined SPEED static char *dir_and_dist_as_str(dir_and_dist_info *d_info, ddnature type, a_access from_access, a_access to_access) { static char buf[TINYBUFSIZ]; char f[TINYBUFSIZ]; uint n, l, l0; char ch; dddirection thisdd; strcpy(f, access_as_string(from_access)); { char *ss; switch (type) { case ddflow: ss = "flow"; break; case ddanti: ss = "anti"; break; case ddoutput: ss = "output"; break; case ddreduce: ss = "reduce"; break; default: ss = ""; /* make compiler happy */ ErrAssert("dir_and_dist_as_str: wrong dependence type"); } sprintf(buf, "%-6s %3ld: %-15.15s --> %3ld: %-15.15s ", ss, accesss_lineno(from_access), f, accesss_lineno(to_access), access_as_string(to_access)); } l0 = l = strlen(buf); ch = '('; for (n = 1; n <= d_info->nest; ++n) { buf[l++] = ch; ch = ','; thisdd = ddextract1(d_info->direction, n); if (d_info->distanceKnown[n]) { sprintf(&(buf[l]), "%ld", d_info->distance[n]); l = strlen(buf); } else if (thisdd == ddlt + ddeq + ddgt) { buf[l++] = '*'; } else { if (ddtest1(thisdd, ddeq)) buf[l++] = '0'; if (ddtest1(thisdd, ddlt)) buf[l++] = '+'; if (ddtest1(thisdd, ddgt)) buf[l++] = '-'; } } if (d_info->nest > 0) buf[l++] = ')'; while (l < l0 + 18) buf[l++] = ' '; buf[l] = 0; append_dd_flags(buf, d_info->direction); return buf; } #endif /* do refinement, cover, and termination tests, set appropriate flags, then store dependence. */ static void flag_and_store_dependence(ddnature nature, a_access from_access, a_access to_access, dir_and_dist_info *d_info) { store_dependence(nature, from_access, to_access, d_info); if (!skipping_omega2) { #if !defined SPEED char *str = dir_and_dist_as_str(d_info, nature, from_access, to_access); #else char *str = "Tiny must be compiled without -DSPEED for debug2 output"; #endif if ((nature == ddflow || nature == ddoutput) && from_access != Entry && to_access != ExitNode) { int covers, j; covers = test_for_coverage(from_access, to_access, accesss_depth(from_access), accesss_depth(to_access), d_info->nest, d_info, str); assert(covers < 2); if (!covers && because(non_affine_red_bound)) { /* see if all 0's covers */ dir_and_dist_info new_info = *d_info; #if !defined SPEED char *str2 = dir_and_dist_as_str(d_info, nature, from_access, to_access); #else char *str2 = "Tiny must be compiled without -DSPEED for debug2 output"; #endif new_info.nest = d_info->nest; for (j = 1; j <= new_info.nest; j++) { assert(dddirtest(d_info->direction, ddeq, j)); /* otherwise we would have no cover because 'didnt_test' */ dddirsetonly(new_info.direction, ddeq, j); dddirsetonly(new_info.restraint, ddeq, j); new_info.distanceKnown[j] = 1; new_info.distance[j] = 0; } if (test_for_coverage(from_access, to_access, accesss_depth(from_access), accesss_depth(to_access), new_info.nest, &new_info, str2)) { if (!(d_info->direction & ddrefined)) clone_dd_graph_node_for_refinement(d_info->dd_graph_node_to_be_cloned); *d_info = new_info; d_info->direction |= ddrefined; covers = 2; } } if (covers) { d_info->direction |= ddcovers; if (covers != 2 && !skipping_all_tightening && (!skipping_o_a_tightening || nature == ddflow)) { tighten_cover(from_access, to_access, d_info, str); } accesss_cover_depth(to_access) = MAX(accesss_cover_depth(to_access), dd_carried_by(d_info->direction, d_info->nest) - 1); } } if ((nature == ddoutput || nature == ddanti) && from_access != ExitNode && to_access != Entry) { int terminates, j; terminates = test_for_termination(from_access, to_access, accesss_depth(from_access), accesss_depth(to_access), d_info->nest, d_info, str); assert(terminates < 2); if (!terminates && because(non_affine_red_bound)) { /* see if all 0's terminates */ dir_and_dist_info new_info = *d_info; #if !defined SPEED char *str2 = dir_and_dist_as_str(d_info, nature, from_access, to_access); #else char *str2 = "Tiny must be compiled without -DSPEED for debug2 output"; #endif new_info.nest = d_info->nest; for (j = 1; j <= new_info.nest; j++) { assert(dddirtest(d_info->direction, ddeq, j)); /* otherwise we would have no cover because 'didnt_test' */ dddirsetonly(new_info.direction, ddeq, j); dddirsetonly(new_info.restraint, ddeq, j); new_info.distanceKnown[j] = 1; new_info.distance[j] = 0; } if (test_for_termination(from_access, to_access, accesss_depth(from_access), accesss_depth(to_access), new_info.nest, &new_info, str2)) { if (!(d_info->direction & ddrefined)) clone_dd_graph_node_for_refinement(d_info->dd_graph_node_to_be_cloned); *d_info = new_info; d_info->direction |= ddrefined; terminates = 2; } } if (terminates) { d_info->direction |= ddterminates; if (terminates != 2 && !skipping_o_a_tightening && !skipping_all_tightening) { tighten_terminator(from_access, to_access, d_info, str); } accesss_terminator_depth(from_access) = MAX(accesss_terminator_depth(from_access), dd_carried_by(d_info->direction, d_info->nest) - 1); } } #if !defined NDEBUG d_info_inv(d_info); #endif /* copy all the changes into the ddnode */ #if defined newTimeTrials if (storeResult) dir_and_dist_into_ddnode(d_info, d_info->dd_graph_node_to_be_cloned); #else dir_and_dist_into_ddnode(d_info, d_info->dd_graph_node_to_be_cloned); #endif } #if defined newTimeTrials if (!storeResult) return; else stores++; #endif } /* split a set of flow, anti, or output dependencies into pieces that are all forward in time if we have a situation with an exposed 0+ followed by an exposed -, then filterValid will call itself recursively to split the 0+ into 0 and + (eliminating the 0...- case) else filterValid will store only one dependency these dependeces are passed to flag_and_store_dependence. */ static void filterValid(ddnature nature, a_access from_access, a_access to_access, int commonNesting, dir_and_dist_info *d_info, int allEQallowed) { int less_at, j; int forbidden; /* * For private variables: -- vadik 11/05/92 * dependencies can not be carried by loops-privatizers */ if (from_access != Entry && from_access != ExitNode && to_access != ExitNode && to_access != Entry && access_private_var_p(from_access)) { int PrivLev = access_private_var_level(from_access); assert(PrivLev <= commonNesting); for (j = 1; j <= PrivLev; j++) { dddirreset(d_info->direction, ddlt | ddgt, j); if (!dddirtest(d_info->direction, ddgt | ddlt | ddeq, j)) return; dddirreset(d_info->restraint, ddlt | ddgt, j); d_info->distance[j] = 0; d_info->distanceKnown[j] = 1; } } #if 0 /* * Reduction dependences aren't forward or backward in time, * so they all are valid by default ??? -- vadik * However, we have to ignore (0,0,...,0) reduction dependences. */ if (nature == ddreduce) { for (j = 1; j <= commonNesting; ++j) { if (dddirtest(d_info->direction, ddlt | ddgt, j)) break; } if (j <= commonNesting || from_access != to_access) { flag_and_store_dependence(nature, from_access, to_access, d_info); } return; } #endif /* remove all -'s before 1st + */ for (j = 1; j <= commonNesting; ++j) { if (!dddirtest(d_info->direction, ddlt | ddeq, j)) return; if (dddirtest(d_info->direction, ddgt, j)) { dddirreset(d_info->direction, ddgt, j); d_info_do_eq(d_info, j); dddirreset(d_info->restraint, ddgt, j); } if (dddirtest(d_info->direction, ddlt, j)) break; } /* check for all 0's or no common Nesting */ less_at = j; if (less_at > commonNesting) { if (allEQallowed) { flag_and_store_dependence(nature, from_access, to_access, d_info); } return; } /* if we start with 0+ rather than just +, check for possible all 0's */ if (dddirtest(d_info->direction, ddeq, less_at)) { for (j = less_at + 1; j <= commonNesting && !dddirtest(d_info->direction, ddlt | ddgt, j); j++); if (j <= commonNesting && !dddirtest(d_info->direction, ddlt | ddeq, j)) { /* we have some 0's, a 0+, more 0's, then a - so, 0+ -> just + */ dddirreset(d_info->direction, ddeq, less_at); dddirreset(d_info->restraint, ddeq, less_at); } else { /* we have some 0's, a 0+, more 0's, then either 0- or something with a + */ forbidden = !allEQallowed; for (j = commonNesting; j >= less_at; j--) { forbidden = dddirtest(d_info->direction, ddgt, j) || (dddirtest(d_info->direction, ddeq, j) && forbidden); /* "forbidden" = some loop outside j must force this dependence to go strictly forward in time */ } if (forbidden) { /* split into leading 0 vs. leading + */ dir_and_dist_info plus, zero; plus = zero = *d_info; dddirreset(plus.direction, ddeq, less_at); dddirreset(plus.restraint, ddeq, less_at); dddirreset(zero.direction, ddlt, less_at); dddirreset(zero.restraint, ddlt, less_at); zero.distance[less_at] = 0; zero.distanceKnown[less_at] = 1; filterValid(nature, from_access, to_access, commonNesting, &plus, allEQallowed); filterValid(nature, from_access, to_access, commonNesting, &zero, allEQallowed); return; } } } flag_and_store_dependence(nature, from_access, to_access, d_info); if (omegaPrintResult == 1) { fprintf(debug2, ">>>>>>>>>>>>>>>>>>>>>>>> ("); for (j = 1; j <= commonNesting; j++) { if (dddirtest(d_info->restraint, ddeq, j)) fprintf(debug2, "0"); if (dddirtest(d_info->restraint, ddlt, j)) fprintf(debug2, "+"); if (dddirtest(d_info->restraint, ddgt, j)) fprintf(debug2, "-"); if (j < commonNesting) fprintf(debug2, ","); } fprintf(debug2, ")\n"); fprintf(debug2, "------------------------ ("); for (j = 1; j <= commonNesting; j++) { if (dddirtest(d_info->direction, ddeq, j)) fprintf(debug2, "0"); if (dddirtest(d_info->direction, ddlt, j)) fprintf(debug2, "+"); if (dddirtest(d_info->direction, ddgt, j)) fprintf(debug2, "-"); if (j < commonNesting) fprintf(debug2, ","); } fprintf(debug2, ")\n"); } } static void dd_to_debug(dir_and_dist_info *d_info) { int j; fprintf(debug2, "("); for (j = 1; j <= d_info->nest; j++) { if (d_info->distanceKnown[j]) fprintf(debug2, "%d", d_info->distance[j]); else if (ddextract1(d_info->direction, j) == ddall) fprintf(debug2, "*"); else { if (dddirtest(d_info->direction, ddeq, j)) fprintf(debug2, "0"); if (dddirtest(d_info->direction, ddlt, j)) fprintf(debug2, "+"); if (dddirtest(d_info->direction, ddgt, j)) fprintf(debug2, "-"); } if (j < d_info->nest) fprintf(debug2, ","); } fprintf(debug2, ") restraint = ("); for (j = 1; j <= d_info->nest; j++) { if (ddextract1(d_info->restraint, j) == ddall) fprintf(debug2, "*"); else { if (dddirtest(d_info->restraint, ddeq, j)) fprintf(debug2, "0"); if (dddirtest(d_info->restraint, ddlt, j)) fprintf(debug2, "+"); if (dddirtest(d_info->restraint, ddgt, j)) fprintf(debug2, "-"); } if (j < d_info->nest) fprintf(debug2, ","); } fprintf(debug2, ")"); } /* call filterValid for the dependence from access1 to access2, and if they are distinct, for the dependence the other way. */ static void noteDependence(situation *sit, dir_and_dist_info *d_info) { dddirection deq, dgt, dlt, req, rgt, rlt; dir_and_dist_info backward; int j; backward.dd_graph_node_to_be_cloned = 0; deq = ddfilter(d_info->direction, ddeq); dlt = ddfilter(d_info->direction, ddlt); dgt = ddfilter(d_info->direction, ddgt); req = ddfilter(d_info->restraint, ddeq); rlt = ddfilter(d_info->restraint, ddlt); rgt = ddfilter(d_info->restraint, ddgt); if (sit->access1 != sit->access2) { backward.direction = backward.restraint = 0; ddsetfilter(backward.direction, deq, ddeq); ddsetfilter(backward.direction, dlt, ddgt); ddsetfilter(backward.direction, dgt, ddlt); ddsetfilter(backward.restraint, req, ddeq); ddsetfilter(backward.restraint, rlt, ddgt); ddsetfilter(backward.restraint, rgt, ddlt); backward.nest = d_info->nest; for (j = 1; j <= sit->commonNesting; ++j) { backward.distanceKnown[j] = d_info->distanceKnown[j]; if (backward.distanceKnown[j]) backward.distance[j] = -d_info->distance[j]; } } filterValid(sit->oitype, sit->access1, sit->access2, sit->commonNesting, d_info, access_lexically_preceeds(sit->access1, sit->access2)); if (omegaPrintResult == 1) { fprintf(debug2, "%%%%%%%%%%%%%%%%%%%%%%%% "); dd_to_debug(d_info); fprintf(debug2, "\n"); } if (sit->access1 != sit->access2) { filterValid(sit->iotype, sit->access2, sit->access1, sit->commonNesting, &backward, access_lexically_preceeds(sit->access2, sit->access1)); if (omegaPrintResult == 1) { fprintf(debug2, "%%%%%%%% backward %%%%%% "); dd_to_debug(&backward); fprintf(debug2, "\n"); } } } /* noteDependence */ /* info used during construction */ typedef struct { int unknownDirection[maxCommonNest]; int unknownDirections; } unknowns; /* process the omega test problem into dependence vectors if dependencies are not coupled, just read them out. else break into cases for each possible dependence in (+,0,-) in each dimension by doing a recursive call each time a dependence vector is found, call noteDependence to store it */ static void findDirectionVector(Problem * prob, situation *sit, dir_and_dist_info *d_info, unknowns *u_info) { int i, j; int l, u, coupled; int l2, u2, best, score, bestScore; int unprotectThese[maxCommonNest]; int numToUnprotect = 0; int simplificationNeeded = u_info->unknownDirections == 0; int initialUnknownDirections = u_info->unknownDirections; u2 = 2; l2 = -2; bestScore = 10000; best = -1; /* keep compiler from complaining, allow later assertion */ for (i = 0; i < u_info->unknownDirections; i++) { j = u_info->unknownDirection[i]; d_info->distanceKnown[j] = 0; coupled = queryVariable(prob, j, &l, &u); if (l == u) { d_info->distanceKnown[j] = 1; d_info->distance[j] = l; } else { if (l > 1) l = 1; else if (l < -1) l = -1; if (u < -1) u = -1; else if (u > 1) u = 1; } if (!coupled || l == u) { dddirsetonly(d_info->direction, 0, j); if (l < 0) dddirset(d_info->direction, ddgt, j); if (l <= 0 && 0 <= u) dddirset(d_info->direction, ddeq, j); if (0 < u) dddirset(d_info->direction, ddlt, j); d_info_do_eq(d_info, j); unprotectThese[numToUnprotect++] = j; u_info->unknownDirection[i] = u_info->unknownDirection[--u_info->unknownDirections]; i--; if (coupled) simplificationNeeded = 1; } else if (coupled && initialUnknownDirections == 1 && prob->getVarsN() + prob->getNumSUBs() == 2 && prob->getNumEqs() + prob->getNumSUBs() == 1) { dddirsetonly(d_info->direction, queryVariableSigns(prob, j, ddlt, ddeq, ddgt, negInfinity, posInfinity, &(d_info->distanceKnown[j]), &(d_info->distance[j])), j); d_info_do_eq(d_info, j); noteDependence(sit, d_info); return; } else { score = 2 * (u - l) + j; if (prob->getVarsN() > 1 && prob->forwardingAddress[j] > 0) score -= 3; if (score <= bestScore) { u2 = u; l2 = l; best = j; bestScore = score; } } } if (u_info->unknownDirections == 0) { prob->_safeVars = 0; prob->setNumSUBs(0); if (!simplificationNeeded || solve(prob, UNKNOWN)) noteDependence(sit, d_info); } else { for (i = 0; i < numToUnprotect; i++) { j = unprotectThese[i]; unprotectVariable(prob, j); } if (simplificationNeeded || (u_info->unknownDirections == 1 && initialUnknownDirections > 1)) { simplifyProblem(prob); findDirectionVector(prob, sit, d_info, u_info); } else { int s; int oldUnknownDirections; int oldUnknownDirection[maxCommonNest]; if (u_info->unknownDirections == 2 && prob->getVarsN() == 1 && prob->getNumSUBs() == 1) { i = u_info->unknownDirection[0]; j = u_info->unknownDirection[1]; if (prob->forwardingAddress[i] != -1) { int t; t = i; i = j; j = t; } if (prob->forwardingAddress[i] == -1 && prob->forwardingAddress[j] == 1) { int j1, j2, j3, i1, i2, i3; j1 = ddlt; i1 = queryVariableSigns(prob, i, ddlt, ddeq, ddgt, 1, posInfinity, &(d_info->distanceKnown[i]), &(d_info->distance[i])); if (d_info->distanceKnown[i]) { dddirsetonly(d_info->direction, i1, i); dddirsetonly(d_info->direction, j1, j); /* dddirsetonly(d_info->restraint, i1, i);not needed */ dddirsetonly(d_info->restraint, j1, j); noteDependence(sit, d_info); i1 = 0; } j2 = ddeq; i2 = queryVariableSigns(prob, i, ddlt, ddeq, ddgt, 0, 0, &(d_info->distanceKnown[i]), &(d_info->distance[i])); if (d_info->distanceKnown[i]) { int oldDistj = d_info->distance[j]; bool oldDistKj = d_info->distanceKnown[j]; dddirsetonly(d_info->direction, i2, i); dddirsetonly(d_info->direction, j2, j); assert(j2 == ddeq); d_info->distanceKnown[j] = 1; d_info->distance[j] = 0; /* dddirsetonly(d_info->restraint, i2, i);not needed */ dddirsetonly(d_info->restraint, j2, j); noteDependence(sit, d_info); i2 = 0; d_info->distanceKnown[j] = oldDistKj; d_info->distance[j] = oldDistj; } j3 = ddgt; i3 = queryVariableSigns(prob, i, ddlt, ddeq, ddgt, negInfinity, -1, &(d_info->distanceKnown[i]), &(d_info->distance[i])); if (d_info->distanceKnown[i]) { dddirsetonly(d_info->direction, i3, i); dddirsetonly(d_info->direction, j3, j); /* dddirsetonly(d_info->restraint, i3, i);not needed */ dddirsetonly(d_info->restraint, j3, j); noteDependence(sit, d_info); i3 = 0; } d_info->distanceKnown[i] = 0; if (i3 == i2) { j2 |= j3; i3 = 0; } if (i2 == i1) { j1 |= j2; i2 = 0; } if (i3 == i1) { j1 |= j3; i3 = 0; } if (i1) { bool oldDisti = d_info->distance[i]; bool oldDistKi = d_info->distanceKnown[i]; bool oldDistj = d_info->distance[j]; bool oldDistKj = d_info->distanceKnown[j]; dddirsetonly(d_info->direction, i1, i); dddirsetonly(d_info->direction, j1, j); /* dddirsetonly(d_info->restraint, i1, i);not needed */ dddirsetonly(d_info->restraint, j1, j); d_info_do_eq(d_info, i); d_info_do_eq(d_info, j); noteDependence(sit, d_info); d_info->distanceKnown[i] = oldDistKi; if (oldDistKi) d_info->distance[i] = oldDisti; d_info->distanceKnown[j] = oldDistKj; if (oldDistKj) d_info->distance[j] = oldDistj; } if (i2) { bool oldDisti = d_info->distance[i]; bool oldDistKi = d_info->distanceKnown[i]; bool oldDistj = d_info->distance[j]; bool oldDistKj = d_info->distanceKnown[j]; dddirsetonly(d_info->direction, i2, i); dddirsetonly(d_info->direction, j2, j); /* dddirsetonly(d_info->restraint, i2, i);not needed */ dddirsetonly(d_info->restraint, j2, j); d_info_do_eq(d_info, i); d_info_do_eq(d_info, j); noteDependence(sit, d_info); d_info->distanceKnown[i] = oldDistKi; if (oldDistKi) d_info->distance[i] = oldDisti; d_info->distanceKnown[j] = oldDistKj; if (oldDistKj) d_info->distance[j] = oldDistj; } if (i3) { bool oldDisti = d_info->distance[i]; bool oldDistKi = d_info->distanceKnown[i]; bool oldDistj = d_info->distance[j]; bool oldDistKj = d_info->distanceKnown[j]; dddirsetonly(d_info->direction, i3, i); dddirsetonly(d_info->direction, j3, j); /* dddirsetonly(d_info->restraint, i3, i);not needed */ dddirsetonly(d_info->restraint, j3, j); d_info_do_eq(d_info, i); d_info_do_eq(d_info, j); noteDependence(sit, d_info); d_info->distanceKnown[i] = oldDistKi; if (oldDistKi) d_info->distance[i] = oldDisti; d_info->distanceKnown[j] = oldDistKj; if (oldDistKj) d_info->distance[j] = oldDistj; } return; } } assert(best >= 0); if (omegaPrintResult == 1) fprintf(debug2, "doing recursive analysis of %d..%d on var %s (#%d)\n", l2, u2, (*prob->_getVarName)(best, prob->_getVarNameArgs), best); j = best; i = 0; while (u_info->unknownDirection[i] != j) i++; u_info->unknownDirection[i] = u_info->unknownDirection[--u_info->unknownDirections]; oldUnknownDirections = u_info->unknownDirections; for (i = 0; i < u_info->unknownDirections; i++) oldUnknownDirection[i] = u_info->unknownDirection[i]; for (s = l2; s <= u2; s++) { Problem tmpProblem; dddirection oldDirection = d_info->direction; dddirection oldRestraint = d_info->restraint; int oldDistj = d_info->distance[j]; int oldDistKj = d_info->distanceKnown[j]; problemcpy(&tmpProblem, prob); if (omegaPrintResult == 1) fprintf(debug2, "considering sign = %d of %s (%d)\n", s, (*prob->_getVarName)(best, prob->_getVarNameArgs), best); if (s == 0) { d_info->distance[j] = 0; d_info->distanceKnown[j] = 1; } else { d_info->distanceKnown[j] = 0; } dddirsetonly(d_info->direction, dd_convert[s + 1], j); dddirsetonly(d_info->restraint, dd_convert[s + 1], j); d_info_inv(d_info); if (constrainVariableSign(&tmpProblem, black, j, s)) findDirectionVector(&tmpProblem, sit, d_info, u_info); if (s < u2) { d_info->direction = oldDirection; d_info->restraint = oldRestraint; d_info->distance[j] = oldDistj; d_info->distanceKnown[j] = oldDistKj; d_info->dd_graph_node_to_be_cloned = 0; u_info->unknownDirections = oldUnknownDirections; for (i = 0; i < u_info->unknownDirections; i++) u_info->unknownDirection[i] = oldUnknownDirection[i]; } } } } } /* findDirectionVector */ /* calculateDDVectors just calls findDirectionVector now. The arrays dddir[] and dddist[] need to have at least maxnest+1 spaces allocated */ extern int nonConvex; void calculateDDVectors(Problem *problemPtr, a_access access1, a_access access2, ddnature oitype, ddnature iotype, uint nest1, uint nest2, uint bnest, uint nonloops) { int i; situation sit; unknowns u_info; dir_and_dist_info d_info; d_info.dd_graph_node_to_be_cloned = 0; d_info.nest = bnest; u_info.unknownDirections = bnest; for (i = 0; i < u_info.unknownDirections; i++) u_info.unknownDirection[i] = i + 1; #if defined newTimeTrials if (storeResult) { int e; int reducable = ((problemPtr->_safeVars) == 1); int coupledSubstitutions = 0; int coupled = 0; int nonUnary = 0; for (e = problemPtr->_numSUBs - 1; e >= 0; e--) if (problemPtr->_SUBs[e].coef[0] != 0) reducable = 0; for (e = problemPtr->_numGEQs - 1; e >= 0; e--) { if (!singleVarGEQ(problemPtr->_GEQs[e], problemPtr->_nVars)) coupled = 1; for (i = problemPtr->_nVars; i > 0; i--) if (problemPtr->_GEQs[e].coef[i] > 1 || problemPtr->_GEQs[e].coef[i] < -1) nonUnary = 1; }; for (e = problemPtr->_numSUBs - 1; e >= 0; e--) { for (i = problemPtr->_nVars; i > 0; i--) if (problemPtr->_SUBs[e].coef[i] != 0) coupledSubstitutions = 1; }; ddCategory[0] = 0; if (reducable) strncat(ddCategory, "r ", TINYBUFSIZ); if (coupledSubstitutions) strncat(ddCategory, "s ", TINYBUFSIZ); if (coupled) strncat(ddCategory, "c ", TINYBUFSIZ); if (nonUnary) strncat(ddCategory, "u ", TINYBUFSIZ); if (nonConvex) strncat(ddCategory, "v ", TINYBUFSIZ); } #endif sit.access1 = access1; sit.access2 = access2; sit.oitype = oitype; sit.iotype = iotype; sit.nest1 = nest1; sit.nest2 = nest2; sit.commonNesting = bnest; d_info.direction = 0; d_info.restraint = -1; /* d_info built by findDirectionVector */ findDirectionVector(problemPtr, &sit, &d_info, &u_info); }