Files
SAPFOR/dvm/fdvm/trunk/Sage/lib/oldsrc/ndeps.c
2023-09-14 19:43:13 +03:00

1077 lines
33 KiB
C

/*********************************************************************/
/* pC++/Sage++ Copyright (C) 1993 */
/* Indiana University University of Oregon University of Rennes */
/*********************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include "db.h"
#include "compatible.h"
#ifdef SYS5
#include <string.h>
#else
#include <strings.h>
#endif
#ifdef __SPF
extern void addToCollection(const int line, const char *file, void *pointer, int type);
#endif
static PTR_BFND current_par_loop = NULL;
static char *depstrs[] = { "flow","anti","output","huh??","got me?"};
static char *dirstrs[] = { " ", "= ", "- ", "0-", "+ ", "0+", ". ", "+-"};
extern PCF UnparseBfnd[];
extern PCF UnparseLlnd[];
extern PTR_FILE cur_file;
/* Forward definitions */
static PTR_BLOB1 Nsearch_deps();
static void subtract_list();
static int same_loop();
void search_and_replace_call();
extern void normal_form();
extern int identical();
PTR_LLND search_call(ll, s)
PTR_LLND ll;
PTR_SYMB *s;
{
PTR_LLND t;
*s = NULL;
if(ll == NULL) return(NULL);
if(ll->variant == FUNC_CALL){
*s = ll->entry.Template.symbol;
return(ll->entry.Template.ll_ptr1);
}
else{
t = search_call(ll->entry.Template.ll_ptr1,s);
if(t != NULL) return(t);
return(search_call(ll->entry.Template.ll_ptr2,s));
}
}
PTR_REFL build_refl(b,s)
PTR_BFND b;
PTR_LLND s;
{
PTR_REFL p,h,l,alloc_ref();
h = NULL; l = NULL;
while(s!= NULL){
p = alloc_ref(b,s->entry.Template.ll_ptr1);
if(p != NULL){
if(h == NULL){ h = p;}
if(l != NULL) l->next = p;
l = p;
}
s = s->entry.Template.ll_ptr2;
}
return(h);
}
/* find loop bounds takes a bif pointer b and addresses of */
/* three other pointers low, hi, inc and computes loop bounds */
/* and returns 1 if it succeds in finding these in terms of */
/* constants, parameters and external varaibles and returns */
/* 0 if it failed. */
int find_loop_bounds(b,low,hi,inc)
PTR_BFND b;
PTR_LLND *low, *hi, *inc;
{return (0);}
/* bind call site info will take a pointer to a call statement and */
/* return a expression list of the used and modified sets in terms */
/* of the actual parameters. */
void bind_call_site_info(b, used, modified)
PTR_BFND b;
PTR_LLND *used, *modified;
{
PTR_LLND funargs, formal_used, formal_modified;
PTR_SYMB fun, s,formal_args[50];
PTR_BFND fun_bif;
/* PTR_BLOB bl; */
PTR_LLND u, m, explst;
int i, num_formal_args;
PTR_LLND called_with[50];
PTR_LLND copy_llnd();
PTR_BFND find_fun_by_name();
int fun_found ;
*used = NULL; *modified = NULL; fun = NULL; fun_found = 0;
formal_used = NULL; formal_modified = NULL;
formal_args[0] = NULL; num_formal_args = 0;;
if(b == NULL) return;
if(b->variant == PROC_STAT){
funargs = b->entry.Template.ll_ptr1;
fun = b->entry.Template.symbol;
}
else if(b->variant == ASSIGN_STAT){
funargs = search_call(b->entry.Template.ll_ptr2,&fun);
}
else if(b->variant == EXPR_STMT_NODE){
funargs = search_call(b->entry.Template.ll_ptr1,&fun);
}
/* if(fun != NULL)
fprintf(stderr, "funargs = %s\n",
(UnparseBfnd[cur_file->lang])(funargs)); */
else {
fprintf(stderr, "serch_call error. node is %s",
(UnparseBfnd[cur_file->lang])(b));
fprintf(stderr, "node type is %d\n",b->variant);
return;
}
if(fun == NULL) return;
if(funargs == NULL) return;
fun_bif = find_fun_by_name(fun->ident); /*no longer need loop search*/
if(fun_bif == NULL){
fprintf(stderr, "find fun_by_name failed %s\n",fun->ident);
return;
}
else if (strcmp(fun_bif->entry.Template.symbol->ident,fun->ident)){
fprintf(stderr, "find fun by name returned wrong fun\n");
return;
}
if(fun_bif->variant == PROC_HEDR || fun_bif->variant == FUNC_HEDR){
if(!strcmp(fun_bif->entry.Template.symbol->ident,fun->ident)){
fun_found = 1;
s = fun_bif->entry.Template.symbol;
s = s->entry.proc_decl.in_list;
while(s != NULL){ /* gather formal args in formal_args */
formal_args[num_formal_args++] = s;
s = s->entry.var_decl.next_in;
}
explst = fun_bif->entry.Template.ll_ptr3;
if(explst == NULL) return;
if(explst->entry.Template.ll_ptr2 == NULL){
/* only first pass analysis done */
formal_used = explst->entry.Template.ll_ptr1; /* bif graph */
}
else
formal_used = explst->entry.Template.ll_ptr2;
explst = fun_bif->entry.Template.ll_ptr2;
if(explst == NULL) return;
if(explst->entry.Template.ll_ptr2 == NULL){
/* only first pass analysis done */
formal_modified = explst->entry.Template.ll_ptr1; /* bif graph*/
}
else
formal_modified = explst->entry.Template.ll_ptr2;
}
}
if(fun_found == 0){
fprintf(stderr, "could not locate source for function %s\n",fun->ident);
return;
}
if(num_formal_args == 0) return;
u = copy_llnd(formal_used);
m = copy_llnd(formal_modified);
for(i = 0; i < num_formal_args; i++){ /* gather actual args in called_with*/
if(funargs == NULL){
printf("ERROR: function not called with enough arguments\n");
exit(0);
}
called_with[i] = copy_llnd(funargs->entry.Template.ll_ptr1);
funargs = funargs->entry.Template.ll_ptr2;
}
search_and_replace_call(&u,num_formal_args,formal_args,called_with);
search_and_replace_call(&m,num_formal_args,formal_args,called_with);
*used = u;
*modified = m;
/*
fprintf(stderr, "formal_used are:\n");
fprintf(stderr, "%s",UnparseLlnd[cur_file->lang](formal_used));
fprintf(stderr, "actual used are:\n");
fprintf(stderr, "%s",UnparseLlnd[cur_file->lang](u));
fprintf(stderr, "formal_modified are:\n");
fprintf(stderr, "%s",UnparseLlnd[cur_file->lang](formal_modified));
fprintf(stderr, "actual modified are:\n");
fprintf(stderr, "%s",UnparseLlnd[cur_file->lang](m));
fprintf(stderr, "called with:\n");
for(i = 0; i < num_formal_args; i++)
fprintf(stderr, " %s,",UnparseLlnd[cur_file->lang](called_with[i]));
fprintf(stderr, "\n");
if(formal_args[0] == NULL) return;
fprintf(stderr, "formal args are:\n");
for(i = 0; i < num_formal_args; i++)
fprintf(stderr, " %s,",formal_args[i]->ident);
fprintf(stderr, "\n");
*/
}
int get_fargs_index(s,n,fargs)
PTR_SYMB s;
int n;
PTR_SYMB fargs[];
{
int i;
for(i = 0; i < n; i++)
if(fargs[i] == s) return(i);
return(-1);
}
void add_offset(offset,term)
PTR_LLND offset, *term;
{
PTR_LLND p,q,r, make_llnd(), copy_llnd();
if(offset == NULL){
fprintf(stderr, "bad offset in add_offset\n");
return;
}
if(term == NULL){
fprintf(stderr, "badd term in add_offset\n");
return;
}
if(*term == NULL){
fprintf(stderr, " null term in add_offset\n");
}
if(*term == NULL || (
offset->variant == DDOT && *term != NULL && (*term)->variant == DDOT)){
q = make_llnd(cur_file, STAR_RANGE,NULL,NULL,NULL);
*term = q;
}
else if((*term)->variant == STAR_RANGE){
/* term is of the form x[:] and no offset will help */
}
else if(offset->variant == STAR_RANGE){ /* MANNHO add 9/10 */
*term = offset;
}
else if((*term)->variant == DDOT){
PTR_LLND offset1, offset2;
offset1 = copy_llnd(offset);
p = (*term)->entry.Template.ll_ptr1;
q = make_llnd(cur_file, ADD_OP,p,offset1,NULL);
/* MANNHO delete
if(cur_file->lang == ForSrc){
p = make_llnd(cur_file, INT_VAL,NULL,NULL,NULL);
p->entry.ival = 1;
q = make_llnd(cur_file, SUBT_OP,q,p,NULL);
}
*/
normal_form(&q); /* normal_form(&q); */
(*term)->entry.Template.ll_ptr1 = q;
p = (*term)->entry.Template.ll_ptr2;
offset2 = copy_llnd(offset);
q = make_llnd(cur_file, ADD_OP,p,offset2,NULL);
/* MANNHO delete
if(cur_file->lang == ForSrc){
p = make_llnd(cur_file, INT_VAL,NULL,NULL,NULL);
p->entry.ival = 1;
q = make_llnd(cur_file, SUBT_OP,q,p,NULL);
}
*/
/* normal_form(&q); */
normal_form(&q);
(*term)->entry.Template.ll_ptr2 = q;
}
else if(offset->variant == DDOT){
r = copy_llnd(*term);
offset = copy_llnd(offset);
p = offset->entry.Template.ll_ptr1;
q = make_llnd(cur_file, ADD_OP,p,r,NULL);
offset->entry.Template.ll_ptr1 = q;
p = offset->entry.Template.ll_ptr2;
q = make_llnd(cur_file, ADD_OP,p,r,NULL);
offset->entry.Template.ll_ptr2 = q;
*term = offset;
}
else{
offset = copy_llnd(offset);
q = make_llnd(cur_file, ADD_OP,*term,offset,NULL);
*term = q;
}
}
PTR_LLND get_array_dim_decl(AR) /* MANNHO add */
PTR_LLND AR; /* ARRAY_REF */
{
PTR_LLND RL, R_L = NULL, ll0, ll1;
PTR_TYPE TY;
PTR_LLND copy_llnd(), make_llnd();
TY = AR->entry.Template.symbol->type;
switch (TY->variant) {
case T_ARRAY : /* MANNHO mod */
R_L = TY->entry.ar_decl.ranges;
if (R_L->variant != EXPR_LIST) R_L = R_L->entry.Template.ll_ptr1;
break;
case T_POINTER :
R_L = NULL;
break;
}
if (R_L == NULL) return(NULL);
RL = R_L = copy_llnd(R_L);
while (RL) {
ll1 = RL->entry.Template.ll_ptr1;
if (ll1->variant != DDOT) {
if (cur_file->lang == ForSrc)
ll0 = make_llnd(cur_file, INT_VAL, NULL, NULL, 1);
else
ll0 = make_llnd(cur_file, INT_VAL, NULL, NULL, 0);
RL->entry.Template.ll_ptr1 = make_llnd(cur_file, DDOT, ll0, ll1, NULL);
}
RL = RL->entry.Template.ll_ptr2;
}
return (R_L);
}
/* u is a reference to an expression describing the result of an action */
/* by a call to the function. fargs is the associated set of formal */
/* formal parameters. call is the actual values passed to the formal */
/* parameter. search_and_replace modifies u so that it reflects the */
/* the action in terms of the actual parameters. */
void search_and_replace_call(u,n,fargs,call)
PTR_LLND *u;
int n;
PTR_SYMB fargs[];
PTR_LLND call[];
{
int i;
PTR_LLND v,index,a,b, b1, b2;
PTR_LLND make_llnd(), copy_llnd(), linearize_array_range();
PTR_LLND get_array_dim_decl();
if (*u == NULL) return ;
/* *u is the result of the call in terms of the formal params */
switch((*u)->variant){
case VAR_REF:
/* find the position of *u in the parameter list */
i = get_fargs_index((*u)->entry.Template.symbol,n,fargs);
if (i<0) return ;
if(call[i]->variant == ADDRESS_OP) v = call[i]->entry.Template.ll_ptr1;
else v = call[i];
*u = copy_llnd(v);
break;
case ARRAY_REF:
i = get_fargs_index((*u)->entry.Template.symbol,n,fargs);
if(i < 0) return ;
v = call[i]; /* v is the expression that is passed in position i */
if(v->variant == VAR_REF){
(*u)->entry.Template.symbol = v->entry.Template.symbol;
search_and_replace_call(&((*u)->entry.Template.ll_ptr1),
n,fargs,call);
search_and_replace_call(&((*u)->entry.Template.ll_ptr2),
n,fargs,call);
}
else if(cur_file->lang != ForSrc && v->variant == ARRAY_REF){
/* if v has dim 1 greater than *u */
index = (*u)->entry.Template.ll_ptr1;
(*u)->entry.Template.symbol = v->entry.Template.symbol;
search_and_replace_call(&index,n,fargs,call);
index = v->entry.Template.ll_ptr1;
while(index->entry.Template.ll_ptr2 != NULL)
index = index->entry.Template.ll_ptr2;
index->entry.Template.ll_ptr2 = (*u)->entry.Template.ll_ptr1;
(*u)->entry.Template.ll_ptr1 = v->entry.Template.ll_ptr1;
}
else if(v->variant == ADDRESS_OP){
/* something like &(x[i]) */
a = v->entry.Template.ll_ptr1; /* the x[i] part */
if(a->variant == EXPR_LIST) a = a->entry.Template.ll_ptr1;
(*u)->entry.Template.symbol=a->entry.Template.symbol;
if(a->variant == VAR_REF ){
search_and_replace_call(&((*u)->entry.Template.ll_ptr1),
n,fargs,call);
}
else if(a->variant == ARRAY_REF){
PTR_LLND second_index;
/* we are adding the offset from &(x[i]) to y[10:2] */
/* u is a *pointer to the summary data and a is a pointer to */
/* the actual argument. make u look like a */
search_and_replace_call(&((*u)->entry.Template.ll_ptr1),
n,fargs,call);
b = (*u)->entry.Template.ll_ptr1; /* range list */
index = a->entry.Template.ll_ptr1; /*range list */
if(index != NULL) second_index = index->entry.Template.ll_ptr2;
else second_index = NULL;
if(index == NULL){
}
else if(b == NULL){
(*u)->entry.Template.ll_ptr1 = copy_llnd(index);
}
else {
b1 = b->entry.Template.ll_ptr1;
b2 = b->entry.Template.ll_ptr2;
b->entry.Template.ll_ptr1 =
copy_llnd(index->entry.Template.ll_ptr1);
b->entry.Template.ll_ptr2 = copy_llnd(second_index);
while (b->entry.Template.ll_ptr2 != NULL)
b = b->entry.Template.ll_ptr2;
add_offset(b1, &(b->entry.Template.ll_ptr1));
b->entry.Template.ll_ptr2 = b2;
}
}
else fprintf(stderr, "a variant is %d\n",a->variant);
}
else if (cur_file->lang == ForSrc && v->variant == ARRAY_REF) {
/* u is a *pointer to a copy of the summary data and v points to */
/* the passed argument. make u look like v. */
int udim, adim;
a = v;
if(a->variant == EXPR_LIST) a = a->entry.Template.ll_ptr1;
if(a->variant == VAR_REF ){
(*u)->entry.Template.symbol=a->entry.Template.symbol;
/* u now has the symbol of v, now do the substitution on the subscripts */
search_and_replace_call(&((*u)->entry.Template.ll_ptr1),
n,fargs,call);
}
else if(a->variant == ARRAY_REF){
PTR_LLND size,ls,rs,adec;
/* we are adding the offset from &(a[i]) to u[10:2] */
/* u is a *pointer to the summary data and a is a pointer to */
/* the actual argument. make u look like a. first fix the index */
/* terms in u */
search_and_replace_call(&((*u)->entry.Template.ll_ptr1),
n,fargs,call);
/* next get the dimensions of these array references. */
/* let b be the index expression range list for *u. */
udim = (*u)->entry.Template.symbol->type->entry.ar_decl.num_dimensions;
adim = a->entry.Template.symbol->type->entry.ar_decl.num_dimensions;
size = get_array_dim_decl(*u); /* MANNHO mod */
adec = get_array_dim_decl(a);
if(adec->variant == EXPR_LIST || adec->variant == RANGE_LIST) adec = adec->entry.Template.ll_ptr1;
search_and_replace_call(&size,n,fargs,call);
(*u)->entry.Template.symbol=a->entry.Template.symbol;
/* we now must linearize the segments described by *u and */
/* then add the offset provided by a */
b = (*u)->entry.Template.ll_ptr1; /* range list */
index = a->entry.Template.ll_ptr1; /*range list */
if(index == NULL && udim == adim){
/* *u already has the correct form */
}
else if(index == NULL && adim < udim){
/* if adim = 1 and udim is bigger */
b = linearize_array_range(b,udim,size);
ls = b->entry.Template.ll_ptr1->entry.Template.ll_ptr1;
rs = b->entry.Template.ll_ptr1->entry.Template.ll_ptr2;
add_offset(adec->entry.Template.ll_ptr1,
&(b->entry.Template.ll_ptr1));
b->entry.Template.ll_ptr2 = NULL;
/* fprintf(stderr," %s ",UnparseLlnd[cur_file->lang](b)); */
}
else if(b == NULL){
(*u)->entry.Template.ll_ptr1 = copy_llnd(index);
}
else if(index == NULL && adim > udim){
int ii;
PTR_LLND c;
c = make_llnd(cur_file, INT_VAL,NULL,NULL,NULL);
c->entry.ival = 1;
for(ii = 0; ii < (adim-udim); ii++){
b->entry.Template.ll_ptr2 =
make_llnd(cur_file, EXPR_LIST,copy_llnd(c),NULL,NULL);
b = b->entry.Template.ll_ptr2;
}
b->entry.Template.ll_ptr2 = NULL;
}
else {
b = linearize_array_range(b,udim,size);
add_offset(index->entry.Template.ll_ptr1,
&(b->entry.Template.ll_ptr1));
if(index->entry.Template.ll_ptr2 == NULL) b->entry.Template.ll_ptr2 = NULL;
else{
if(index->entry.Template.ll_ptr2 !=NULL &&
index->entry.Template.ll_ptr2->variant != EXPR_LIST)
b->entry.Template.ll_ptr2 =
make_llnd(cur_file, EXPR_LIST,index->entry.Template.ll_ptr2,NULL,NULL);
else b->entry.Template.ll_ptr2 = index->entry.Template.ll_ptr2;
}
}
}
else fprintf(stderr, "a variant is %d\n",a->variant);
}
else{ /* something like p+3 for a pointer p */
fprintf(stderr, "a strange pointer case in ser. and repl.\n");
}
break;
default: /* an expression */
search_and_replace_call(&((*u)->entry.Template.ll_ptr1),
n,fargs,call);
search_and_replace_call(&((*u)->entry.Template.ll_ptr2),
n,fargs,call);;
}
}
/* MANNHO delete whole this procedure
PTR_LLND get_leading_arr_dim(s)
PTR_SYMB s;
{
PTR_LLND x, copy_llnd();
x = s->type->entry.ar_decl.ranges;
if(x->variant == ARRAY_REF) x = x->entry.Template.ll_ptr1;
if(x->variant == EXPR_LIST) x = x->entry.Template.ll_ptr1;
return(copy_llnd(x));
}
*/
void make_zero_base(ref, decl) /* MANNHO add */
PTR_LLND ref, decl;
{
PTR_LLND ref_index, ref_low, ref_up, decl_low, dlow;
PTR_LLND make_llnd(), copy_llnd();
while (ref) {
ref_index = ref->entry.Template.ll_ptr1;
decl_low =decl->entry.Template.ll_ptr1->entry.Template.ll_ptr1;
if (ref_index->variant == DDOT) {
ref_low = ref_index->entry.Template.ll_ptr1;
ref_up = ref_index->entry.Template.ll_ptr2;
if(ref_low != NULL && decl_low != NULL){
dlow = copy_llnd(decl_low);
ref_low = make_llnd(cur_file, SUBT_OP, ref_low, dlow, NULL);
}
if(ref_up != NULL && decl_low != NULL){
dlow = copy_llnd(decl_low);
ref_up = make_llnd(cur_file, SUBT_OP, ref_up, dlow, NULL);
}
ref_index->entry.Template.ll_ptr1 = ref_low;
ref_index->entry.Template.ll_ptr2 = ref_up;
}
else if(decl_low != NULL && ref_index->variant != STAR_RANGE){
dlow = copy_llnd(decl_low);
ref_index = make_llnd(cur_file, SUBT_OP, ref_index, dlow, NULL);
ref->entry.Template.ll_ptr1 = ref_index;
}
ref = ref->entry.Template.ll_ptr2;
decl = decl->entry.Template.ll_ptr2;
}
}
/* linearize_array_range takes a range list and returns a range */
/* list consiting of a 1-D ddot discription of the range */
PTR_LLND linearize_array_range(rl,dim,size) /* MANNHO mod */
PTR_LLND rl; /* a range list of expressions and ddots */
int dim;
PTR_LLND size; /* size is the declared dimension of the parameter */
{
PTR_LLND RL, sz1, s;
PTR_LLND size_upto, size_up, addend, low, up, one;
PTR_LLND index, index_low, index_up;
int shift_needed;
PTR_LLND make_llnd(), copy_llnd();
make_zero_base(rl, size);
s = size; shift_needed = 0;
while(s != NULL){
sz1 = s->entry.Template.ll_ptr1;
if(sz1->entry.Template.ll_ptr1 != NULL &&
(( sz1->entry.Template.ll_ptr1->variant != CONST_REF &&
sz1->entry.Template.ll_ptr1->variant != INT_VAL) ||
sz1->entry.Template.ll_ptr1->entry.ival != 1)){
printf(" ival is %d\n",sz1->entry.Template.ll_ptr1->entry.ival);
shift_needed = 1;
}
s = s->entry.Template.ll_ptr2;
}
s = copy_llnd(size);
make_zero_base(size, s);
if(shift_needed) s = copy_llnd(size);
/*
fprintf(stderr, " rl = %s",UnparseLlnd[cur_file->lang](rl));
fprintf(stderr, " size = %s",UnparseLlnd[cur_file->lang](size));
*/
size_upto = NULL; low = NULL; up = NULL;
RL = rl;
while (RL) {
index = RL->entry.Template.ll_ptr1;
sz1 = size->entry.Template.ll_ptr1;
if (index->variant == DDOT) {
index_low = index->entry.Template.ll_ptr1;
index_up = index->entry.Template.ll_ptr2;
} else {
index_low = index;
index_up = copy_llnd(index);
}
if(index->variant == STAR_RANGE){
index->variant = DDOT;
index_low = sz1->entry.Template.ll_ptr1;
index_up = sz1->entry.Template.ll_ptr2;
}
if (low == NULL) { /* 1st index */
low = index_low;
up = index_up;
}
else {
if(low != NULL && size_upto != NULL){
addend = make_llnd(cur_file, MULT_OP, copy_llnd(size_upto),
index_low, NULL);
low = make_llnd(cur_file, ADD_OP, low, addend, NULL);
}
if(up != NULL && size_upto != NULL){
addend = make_llnd(cur_file, MULT_OP, copy_llnd(size_upto),
index_up, NULL);
up = make_llnd(cur_file, ADD_OP, up, addend, NULL);
}
}
size_up = s->entry.Template.ll_ptr1->entry.Template.ll_ptr2;
if(shift_needed){
one = make_llnd(cur_file, INT_VAL, NULL, NULL, 1);
size_up = make_llnd(cur_file, ADD_OP, size_up, one, NULL);
}
size_upto = (size_upto == NULL) ?
size_up :
make_llnd(cur_file, MULT_OP, size_upto, size_up, NULL);
size = size->entry.Template.ll_ptr2;
s = s->entry.Template.ll_ptr2;
RL = RL->entry.Template.ll_ptr2;
}
if (low == NULL && up == NULL){
RL = make_llnd(cur_file,STAR_RANGE,NULL, NULL, NULL);
}
else if (identical(low, up)) {
RL = low;
/* free_ll_tree(up); */
} else {
RL = make_llnd(cur_file, DDOT, low, up, NULL);
}
rl->entry.Template.ll_ptr1 = RL;
rl->entry.Template.ll_ptr2 = NULL;
return(rl);
}
PTR_BLOB1
NGetCallInfo(filename,line)
char *filename;
int line;
{
PTR_BLOB1 lb, nb,tb;
PTR_BFND b, FindBifNode();
char *s;
PTR_LLND used, modified;
used = NULL; modified = NULL;
b = FindBifNode(filename,line);
if(b == NULL){
nb = (PTR_BLOB1) malloc(sizeof(struct blob1));
s = malloc(256);
#ifdef __SPF
addToCollection(__LINE__, __FILE__,nb, 0);
addToCollection(__LINE__, __FILE__,s, 0);
#endif
sprintf(s,"Could not find code at line %d\n",line);
nb->ref = s;
nb->next = NULL;
return(nb);
}
if(b->variant != PROC_STAT && b->variant != EXPR_STMT_NODE){
nb = (PTR_BLOB1) malloc(sizeof(struct blob1));
s = malloc(256);
#ifdef __SPF
addToCollection(__LINE__, __FILE__,nb, 0);
addToCollection(__LINE__, __FILE__,s, 0);
#endif
sprintf(s,"Cound not find call at line %d\n",line);
nb->ref = s;
nb->next = NULL;
return(nb);
}
bind_call_site_info(b,&used,&modified);
if(used == NULL){
tb = nb = (PTR_BLOB1) malloc(sizeof(struct blob1));
s = malloc(256);
#ifdef __SPF
addToCollection(__LINE__, __FILE__,tb, 0);
addToCollection(__LINE__, __FILE__,s, 0);
#endif
sprintf(s,"nothing used in call. \n");
nb->ref = s;
nb->next = NULL;
lb = nb;
}
else{
tb = nb = (PTR_BLOB1) malloc(sizeof(struct blob1));
s = malloc(256);
#ifdef __SPF
addToCollection(__LINE__, __FILE__,tb, 0);
addToCollection(__LINE__, __FILE__,s, 0);
#endif
sprintf(s,"variables used in call are: \n");
nb->ref = s;
tb->next = nb = (PTR_BLOB1) malloc(sizeof(struct blob1));
#ifdef __SPF
addToCollection(__LINE__, __FILE__,tb->next, 0);
#endif
s = (UnparseLlnd[cur_file->lang])(used);
nb->ref = s;
nb->next = NULL;
lb = nb;
}
if(modified == NULL){
lb->next = nb = (PTR_BLOB1) malloc(sizeof(struct blob1));
s = malloc(256);
#ifdef __SPF
addToCollection(__LINE__, __FILE__,lb->next, 0);
addToCollection(__LINE__, __FILE__,s, 0);
#endif
sprintf(s,"nothing modified by call. \n");
nb->ref = s;
nb->next = NULL;
return(tb);
}
else{
lb->next = nb = (PTR_BLOB1) malloc(sizeof(struct blob1));
s = malloc(256);
#ifdef __SPF
addToCollection(__LINE__, __FILE__,lb->next, 0);
addToCollection(__LINE__, __FILE__,s, 0);
#endif
sprintf(s,"variables modified in call are: \n");
nb->ref = s;
nb->next = (PTR_BLOB1) malloc(sizeof(struct blob1));
#ifdef __SPF
addToCollection(__LINE__, __FILE__,nb->next, 0);
#endif
nb = nb->next;
s = (UnparseLlnd[cur_file->lang])(modified);
nb->ref = s;
nb->next = NULL;
return(tb);
}
}
PTR_BLOB1
NGetDepInfo(filename, line)
char *filename;
int line;
{
PTR_BFND b,bpar;
PTR_DEP d;
int depth;
char * s;
PTR_BLOB1 nb, lb, btmp;
PTR_BLOB q;
PTR_SYMB induct_list[100], local_list[100], rename_list[100];
int induct_num, local_num, rename_num;
/* PTR_LLND used, modified; */
PTR_BFND FindBifNode();
int i;
induct_num = 0; local_num = 0; rename_num = 0;
b = FindBifNode(filename,line);
/* bind_call_site_info(b,&used,&modified);*/
if(b == NULL){
nb = (PTR_BLOB1) malloc(sizeof(struct blob1));
s = malloc(256);
#ifdef __SPF
addToCollection(__LINE__, __FILE__,nb, 0);
addToCollection(__LINE__, __FILE__,s, 0);
#endif
sprintf(s,"Could not find code at line %d\n",line);
nb->ref = s;
nb->next = NULL;
return(nb);
}
/* if b is a loop, we look for all loop carried deps for */
/* this loop. otherwise just list dependence going out */
if(b->variant == FOR_NODE || b->variant == WHILE_NODE){
depth = 0;
bpar = b;
current_par_loop = b;
while(bpar != NULL && bpar->variant != GLOBAL){
if(bpar->variant == FOR_NODE ||
bpar->variant == CDOALL_NODE ||
bpar->variant == WHILE_NODE ||
bpar->variant == FORALL_NODE) depth++;
bpar = bpar->control_parent;
}
q = b->entry.Template.bl_ptr1;
nb = (PTR_BLOB1) malloc(sizeof(struct blob1));
s = malloc(256);
#ifdef __SPF
addToCollection(__LINE__, __FILE__,nb, 0);
addToCollection(__LINE__, __FILE__,s, 0);
#endif
sprintf(s,"Loop Carried Dependences Prohibiting Parallelism:\n");
nb->ref = s;
nb->next = NULL;
nb = Nsearch_deps(nb,q,depth,induct_list, &induct_num,
local_list,&local_num, rename_list, &rename_num);
if (nb->next == NULL)
{
if (induct_num == 0 && local_num == 0 && rename_num == 0)
sprintf(nb->ref, "this loop is perfect! parallelize it.\n");
else
sprintf(nb->ref,
"Loop is Parallelizable. First fix these problems.\n");
}
for(lb = nb; lb->next != NULL; lb = lb->next);
if(induct_num > 0){
btmp = (PTR_BLOB1) malloc(sizeof(struct blob1));
lb->next = btmp; lb = btmp;
s = malloc(256);
#ifdef __SPF
addToCollection(__LINE__, __FILE__,btmp, 0);
addToCollection(__LINE__, __FILE__,s, 0);
#endif
sprintf(s,"The following seem to be pseudo induction variables:\n");
lb->ref = s;
lb->next = NULL;
for(i = 0; i < induct_num; i++){
lb->next = (PTR_BLOB1) malloc(sizeof(struct blob1));
#ifdef __SPF
addToCollection(__LINE__, __FILE__,lb->next, 0);
#endif
lb = lb->next;
s = malloc(3+strlen(induct_list[i]->ident) );
#ifdef __SPF
addToCollection(__LINE__, __FILE__,s, 0);
#endif
sprintf(s,"%s\n",induct_list[i]->ident);
lb->next = NULL;
lb->ref = s;
}
subtract_list(induct_list,&induct_num,local_list,&local_num);
subtract_list(induct_list,&induct_num,rename_list,&rename_num);
}
if(local_num > 0){
btmp = (PTR_BLOB1) malloc(sizeof(struct blob1));
#ifdef __SPF
addToCollection(__LINE__, __FILE__,btmp, 0);
#endif
lb->next = btmp; lb = btmp;
s = malloc(256);
#ifdef __SPF
addToCollection(__LINE__, __FILE__,s, 0);
#endif
sprintf(s,"Variables that should be made local to loop:\n");
lb->ref = s;
lb->next = NULL;
for(i = 0; i < local_num; i++){
lb->next = (PTR_BLOB1) malloc(sizeof(struct blob1));
#ifdef __SPF
addToCollection(__LINE__, __FILE__,lb->next, 0);
#endif
lb = lb->next;
s = malloc(3+strlen(local_list[i]->ident));
#ifdef __SPF
addToCollection(__LINE__, __FILE__,s, 0);
#endif
sprintf(s,"%s\n",local_list[i]->ident);
lb->next = NULL;
lb->ref = s;
}
subtract_list(local_list, &local_num, rename_list, &rename_num);
}
if(rename_num > 0){
btmp = (PTR_BLOB1) malloc(sizeof(struct blob1));
#ifdef __SPF
addToCollection(__LINE__, __FILE__,btmp, 0);
#endif
lb->next = btmp; lb = btmp;
s = malloc(256);
#ifdef __SPF
addToCollection(__LINE__, __FILE__,s, 0);
#endif
sprintf(s,"Variables that are reused in a funny way:\n");
lb->ref = s;
lb->next = NULL;
for(i = 0; i < rename_num; i++){
lb->next = (PTR_BLOB1) malloc(sizeof(struct blob1));
#ifdef __SPF
addToCollection(__LINE__, __FILE__,lb->next, 0);
#endif
lb = lb->next;
s = malloc(64);
#ifdef __SPF
addToCollection(__LINE__, __FILE__,s, 0);
#endif
sprintf(s,"%s\n",rename_list[i]->ident);
lb->next = NULL;
lb->ref = s;
}
}
return(nb);
} /* if loop case */
d = b->entry.Template.dep_ptr1;
nb = NULL;
btmp = (PTR_BLOB1) malloc(sizeof(struct blob1));
#ifdef __SPF
addToCollection(__LINE__, __FILE__,btmp, 0);
#endif
s = malloc(256);
#ifdef __SPF
addToCollection(__LINE__, __FILE__,s, 0);
#endif
sprintf(s,"variant of this node is %d\n",b->variant);
btmp->ref = s;
btmp->next = NULL;
nb = lb = btmp;
while(d != NULL){
btmp = (PTR_BLOB1) malloc( sizeof(struct blob1));
#ifdef __SPF
addToCollection(__LINE__, __FILE__,btmp, 0);
#endif
if (nb == NULL){ nb = btmp; lb = btmp;}
else{ lb->next = btmp; lb = btmp;}
s = malloc(256);
#ifdef __SPF
addToCollection(__LINE__, __FILE__,s, 0);
#endif
sprintf(s,"id:%s type:%s to line %d dir_vect =(%s,%s,%s)\n",
d->symbol->ident, depstrs[(int) (d->type)],
d->to.stmt->g_line,
dirstrs[(int) (d->direct[1])], dirstrs[(int) (d->direct[2])],
dirstrs[(int) (d->direct[3])]);
btmp->ref = s;
btmp->next = NULL;
d = d->from_fwd;
}
return(nb);
}
static void subtract_list(a,na, b, nb)
PTR_SYMB a[], b[];
int *na, *nb;
{
int i, j;
for(i = 0; i < *na; i++){
for(j = 0; j < *nb; j++){
if(a[i] == b[j]){
if(j < *nb-1) b[j] = b[*nb -1];
(*nb)--;
}
}
}
}
int pointer_as_array(d)
PTR_DEP d;
{
/*
if(d->from.refer == NULL) fprintf(stderr, "no from llnode\n");
if(d->to.refer == NULL) fprintf(stderr, "no to llnode\n");
fprintf(stderr, " from <%s to <%s\n",
unparse_llnd(d->from.refer), unparse_llnd(d->to.refer));
*/
if (d->to.refer->variant == ARRAY_REF || d->from.refer->variant==ARRAY_REF)
return 1;
else return 0;
}
static PTR_BLOB1
Nsearch_deps(nb,q,depth,induct_list, induct_num,
local_list,local_num,rename_list,rename_num)
PTR_BLOB1 nb;
PTR_BLOB q;
int depth;
PTR_SYMB induct_list[], local_list[], rename_list[];
int *induct_num, *local_num, *rename_num;
{
PTR_BFND bchild;
PTR_DEP d;
char *s;
PTR_BLOB1 lb = NULL, btmp;
int i,found;
PTR_LLND from_list[500];
int from_line[500], to_line[500];
int from_num;
if(nb != NULL) lb = nb;
from_num = 0;
while(q != NULL){
bchild = q->ref;
q = q->next;
d = bchild->entry.Template.dep_ptr1;
while(d != NULL){
/* if the dependence is a carried array dependence (on a array type */
/* or used as an array (fix)) or it is a flow dependence that is */
/* caried then classify appropriately. */
if (((d->symbol->type->variant == T_ARRAY || pointer_as_array(d)) &&
d->direct[depth] >1) || (d->type == 0 && d->direct[depth] >1)){
/* this is a loop carried flow dependence */
if(d->from.stmt == d->to.stmt &&
(d->symbol->type->variant == T_INT ||
(pointer_as_array(d) == 0 &&
d->symbol->type->variant == T_POINTER) )){
for(i = 0, found = 0; i < *induct_num; i++)
if( induct_list[i] == d->symbol) found = 1;
if(found == 0) induct_list[(*induct_num)++] = d->symbol;
}
else if(same_loop(d->from.stmt,d->to.stmt)){
found = 0;
for(i = 0; i < from_num; i++)
if(d->from.refer == from_list[i] && d->from.stmt->g_line == from_line[i]
&& d->to.stmt->g_line == to_line[i]) found = 1;
if(found == 0){
btmp = (PTR_BLOB1) malloc( sizeof(struct blob1));
#ifdef __SPF
addToCollection(__LINE__, __FILE__,btmp, 0);
#endif
if (nb == NULL){ nb = btmp; lb = btmp;}
else{ lb->next = btmp; lb = btmp;}
s = malloc(256);
#ifdef __SPF
addToCollection(__LINE__, __FILE__,s, 0);
#endif
sprintf(s, "an assignment to %s at line %d used in line %d in another iteration\n",
(UnparseLlnd[cur_file->lang])(d->from.refer),
d->from.stmt->g_line, d->to.stmt->g_line);
btmp->ref = s;
btmp->next = NULL;
from_list[from_num] = d->from.refer;
from_line[from_num] = d->from.stmt->g_line;
to_line[from_num++] = d->to.stmt->g_line;
}
}
}
else if(d->symbol->type->variant != T_ARRAY && d->type != 0 &&
d->direct[depth] > 1 && same_loop(d->from.stmt,d->to.stmt)){
/* this is a loop caried output or anti dep */
/* add symbol to list for suggestion for localization */
for(i = 0, found = 0; i < *local_num; i++)
if( local_list[i] == d->symbol) found = 1;
if(found == 0) local_list[(*local_num)++] = d->symbol;
}
else if(d->type == 2 && d->direct[depth] <= 1 &&
same_loop(d->from.stmt,d->to.stmt)){
/* this is an output dependence of distance 0 */
/* suggest renaming. */
for(i = 0, found = 0; i < *rename_num; i++)
if( rename_list[i] == d->symbol) found = 1;
if(found == 0) rename_list[(*rename_num)++] = d->symbol;
}
d = d->from_fwd;
}
if(bchild->entry.Template.bl_ptr1 != NULL){
nb = Nsearch_deps(nb,bchild->entry.Template.bl_ptr1,depth,induct_list,
induct_num, local_list,
local_num, rename_list, rename_num);
lb = nb; while(lb != NULL && lb->next != NULL) lb = lb->next;
}
if(bchild->entry.Template.bl_ptr2 != NULL){
nb = Nsearch_deps(nb,bchild->entry.Template.bl_ptr2,depth,induct_list,
induct_num, local_list,
local_num, rename_list, rename_num);
lb = nb; while(lb != NULL && lb->next != NULL) lb = lb->next;
}
}
return(nb);
}
static int same_loop(from, to)
PTR_BFND from, to;
{
PTR_BFND c;
c = from;
while(c != NULL && c->variant != GLOBAL && c != current_par_loop)
c = c->control_parent;
if(c != current_par_loop) return(0);
c = to;
while(c != NULL && c->variant != GLOBAL && c != current_par_loop)
c = c->control_parent;
if(c != current_par_loop) return(0);
return(1);
}