Files
SAPFOR/Sapfor/_src/SageAnalysisTool/OmegaForSage/ddomega-use.cpp
2025-03-25 20:39:29 +03:00

866 lines
32 KiB
C++

/* 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 <assert.h>
#include "include/portable.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#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);
}