moved
This commit is contained in:
865
Sapfor/_src/SageAnalysisTool/OmegaForSage/ddomega-use.cpp
Normal file
865
Sapfor/_src/SageAnalysisTool/OmegaForSage/ddomega-use.cpp
Normal file
@@ -0,0 +1,865 @@
|
||||
/* 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);
|
||||
}
|
||||
Reference in New Issue
Block a user