504 lines
18 KiB
C
504 lines
18 KiB
C
|
|
/* lang-interf.h,v 1.2 1994/07/05 15:34:09 fbodin Exp */
|
||
|
|
|
||
|
|
#ifndef Already_Included_Lang_Interf
|
||
|
|
#define Already_Included_Lang_Interf 1
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
Omega-test to programming language interface spec
|
||
|
|
|
||
|
|
To adapt the omega test to do data dependence for some language other
|
||
|
|
than tiny, use the files ip.[hc], ddomega.[hc], ddomega-use.[hc],
|
||
|
|
ddomega-build.[hc], cover.[ch], kill.[ch], refine.[ch], add-assert.[ch],
|
||
|
|
debug.[hc], and portable.h unchanged.
|
||
|
|
|
||
|
|
Modify affine.c to create affine_expr structures for each expression
|
||
|
|
that may be relevent to the omega test (loop bounds and array
|
||
|
|
subscripts). You may or may not need to modify affine.h.
|
||
|
|
|
||
|
|
Modify ddodriver.c, or provide your own code, to call the omega test
|
||
|
|
for all the array pairs where you need to test for dependence, and
|
||
|
|
call the test_for_cover, test_for_termination, quick_test_for_kill
|
||
|
|
and accurate_test_for_kill if you wish to use them. If you are
|
||
|
|
feeling bold, you may even want to try to get the "zap" functions
|
||
|
|
"possible_to_eliminate" and "try_to_eliminate" (in add-assert.c) to
|
||
|
|
work.
|
||
|
|
|
||
|
|
The flags in omega2flags.h control some of the optional behaviors
|
||
|
|
that can be obtained from the dependence killing & refining code.
|
||
|
|
They affect both ddodriver.c and the files that you do not need to
|
||
|
|
change.
|
||
|
|
|
||
|
|
If you want to have debugging output, make sure you open the debug
|
||
|
|
file and set omegaPrintResult to 1.
|
||
|
|
|
||
|
|
Create a file lang-interf.h, defining numerous macros that the
|
||
|
|
omega test needs to access the parsed program. Your lang-interf.h
|
||
|
|
can be based on this generic version, or the lang-interf.h that we
|
||
|
|
wrote for tiny, depending on whether you prefer to read my cryptic
|
||
|
|
comments here or my even more cryptic code there. In the generic
|
||
|
|
version, the macros are defined to produce a meaningless result of
|
||
|
|
the right type, so that ddomega.c, ddomega-use.c, and ddomega-build.c
|
||
|
|
can all be compiled.
|
||
|
|
|
||
|
|
In case of trouble, please feel free to contact me at:
|
||
|
|
davew@cs.umd.edu
|
||
|
|
Department of Computer Science
|
||
|
|
A. V. Williams Building
|
||
|
|
University of Maryland
|
||
|
|
College Park, Maryland 20742
|
||
|
|
|
||
|
|
Remember that it is a federal crime to send explosives or certain
|
||
|
|
other dangerous materials in the U.S. Mail.
|
||
|
|
|
||
|
|
David Wonnacott
|
||
|
|
*/
|
||
|
|
|
||
|
|
|
||
|
|
#define NOT_TINY 1
|
||
|
|
|
||
|
|
/* include for the sage macro */
|
||
|
|
/* #include "macro.h"*/
|
||
|
|
|
||
|
|
struct _affine_expr; /* define later in affine.h */
|
||
|
|
struct omegaIterator ; /* define later in this file */
|
||
|
|
struct omegaLoop; /* define later in this file */
|
||
|
|
struct omegaIf; /* define later in this file */
|
||
|
|
struct omegaVar; /* define later in this file */
|
||
|
|
struct omegaContIter;
|
||
|
|
|
||
|
|
/* Note:
|
||
|
|
The omega test data dependence functions, and the macros defined
|
||
|
|
here, often require strings giving the printed representations of
|
||
|
|
data dependences or array accesses, etc. These strings are used
|
||
|
|
only for generating debugging output in trace.out. If you don't
|
||
|
|
care about debugging output, you can just make anything with the
|
||
|
|
word "string" in it = "".
|
||
|
|
*/
|
||
|
|
|
||
|
|
/* define the maximum length of a data dependence vector */
|
||
|
|
#define maxCommonNest 10 /* (32 bits - 6 used in dddir.h) / 4 bits per dd */
|
||
|
|
|
||
|
|
typedef enum { ddflow, ddanti, ddoutput, ddreduce, dd_unknown, ddnovalue } ddnature;
|
||
|
|
|
||
|
|
|
||
|
|
/* define the type "a_access", which identifies an array access,
|
||
|
|
and provides access to information about the access (such as
|
||
|
|
its depth, line number, the symbol accessed, and the type of
|
||
|
|
access (read or write)).
|
||
|
|
|
||
|
|
It must also be possible to extract information about the
|
||
|
|
subscript expressions used in the access, with "sub_i_for_access",
|
||
|
|
information about the "context" of an access (the enclosing reads
|
||
|
|
& writes), with "cont_i_for_access", and information about the
|
||
|
|
dependences to or from an access, as per the stuff later in this file.
|
||
|
|
|
||
|
|
accesss_cover_depth and accesss_terminator_depth must be lvalues
|
||
|
|
where we can store the depth at which the access is covered or
|
||
|
|
terminated. These should both be initialized to -1.
|
||
|
|
|
||
|
|
accesss_shared_depth must give the number of loops contianing both
|
||
|
|
A1 and A2.
|
||
|
|
|
||
|
|
Two a_accesses must be equal in a self-dependence test
|
||
|
|
|
||
|
|
If there is no existing structure that provides all this information,
|
||
|
|
you may need to create an aggregate with pointers to the different
|
||
|
|
structures you use.
|
||
|
|
*/
|
||
|
|
|
||
|
|
struct omegaAccess {
|
||
|
|
|
||
|
|
char *str;
|
||
|
|
struct omegaVar *symb;
|
||
|
|
struct omegaIterator *subiter;
|
||
|
|
struct omegaContIter *context;
|
||
|
|
int inIfStmt;
|
||
|
|
int line,cdepth,tdepth;
|
||
|
|
int depth;
|
||
|
|
int idforsage;
|
||
|
|
int shareddepth;
|
||
|
|
int pri;
|
||
|
|
int level;
|
||
|
|
int fetch;
|
||
|
|
int store;
|
||
|
|
int update;
|
||
|
|
int lexord;
|
||
|
|
};
|
||
|
|
|
||
|
|
typedef struct omegaAccess *a_access;
|
||
|
|
|
||
|
|
#define access_as_string(A) (A->str) /* only used in debugging output */
|
||
|
|
#define accesss_sym(A) (A->symb) /* currently only used in 1 assertion */
|
||
|
|
#define accesss_lineno(A) (A->line) /* currently only in debugging output */
|
||
|
|
#define accesss_cover_depth(A) (A->cdepth)
|
||
|
|
#define accesss_terminator_depth(A) (A->tdepth)
|
||
|
|
#define accesss_depth(A) (A->depth)
|
||
|
|
#define accesss_shared_depth(A1,A2) (A1->shareddepth)
|
||
|
|
/* this is wrong
|
||
|
|
#define accesss_shared_depth(A1,A2) ((A1->depth > A2->depth)?(A1->depth - A2->depth):(A2->depth > A1->depth))
|
||
|
|
*/
|
||
|
|
|
||
|
|
/* does A access a private var - if so, at what level is it private? */
|
||
|
|
#define access_private_var_p(A) (A->pri)
|
||
|
|
#define access_private_var_level(A) (A->level)
|
||
|
|
|
||
|
|
#define access_fetch_p(A) (A->fetch)
|
||
|
|
#define access_store_p(A) (A->store)
|
||
|
|
#define access_update_p(A) (A->update)
|
||
|
|
/* Are A1 and A2 updates of the same kind (ie both += or both *=) */
|
||
|
|
#define access_same_update_type_p(A1, A2) 0
|
||
|
|
|
||
|
|
/* can we execute A1 and then A2 without going to another iteration */
|
||
|
|
#define access_lexically_preceeds(A1, A2) (A1->lexord > A2->lexord)
|
||
|
|
|
||
|
|
|
||
|
|
/* pointers to Entry and Exit node for testing for dependence to
|
||
|
|
points before or after the routine being analyzed. It must
|
||
|
|
be possible to compare these to a variable of type a_access */
|
||
|
|
|
||
|
|
#define Entry ((a_access)0)
|
||
|
|
#define ExitNode ((a_access)0)
|
||
|
|
|
||
|
|
/* define the type "sub_iterator" - an iterator over the
|
||
|
|
subscripts of an array access. We need to test these
|
||
|
|
subscripts to see if they are affine expressions of the
|
||
|
|
loop index variables and symbolic constants, and if so,
|
||
|
|
find the associated affine_expr structure.
|
||
|
|
We also need to have access to all the variables used in
|
||
|
|
the expression (for the purpose of building the set of
|
||
|
|
variables used), via the function sub_i_map_over_cur_vars,
|
||
|
|
which calls F(V,ARGS) for each variable V in the expression.
|
||
|
|
*/
|
||
|
|
struct omegaIterator {
|
||
|
|
|
||
|
|
struct omegaIterator *next;
|
||
|
|
int isaffine;
|
||
|
|
struct _affine_expr *affine;
|
||
|
|
struct omegaVar *constante;
|
||
|
|
int cstvalue;
|
||
|
|
|
||
|
|
} ;
|
||
|
|
|
||
|
|
typedef struct omegaIterator *sub_iterator;
|
||
|
|
|
||
|
|
|
||
|
|
#define sub_i_for_access(A) ((A)->subiter)
|
||
|
|
#define sub_i_next(SUBI) (SUBI = SUBI->next)
|
||
|
|
#define sub_i_done(SUBI) (SUBI == NULL)
|
||
|
|
#define sub_i_cur_is_affine(SUBI) (SUBI->isaffine)
|
||
|
|
#define sub_i_cur_affine(SUBI) (SUBI->affine)
|
||
|
|
/*
|
||
|
|
#define sub_i_map_over_cur_vars(SUBI,F,ARGS) {(F)(SUBI->constante,ARGS);}
|
||
|
|
*/
|
||
|
|
#define sub_i_map_over_cur_vars(SUBI,F,ARGS)
|
||
|
|
|
||
|
|
|
||
|
|
/* define the type "sub_iterator" - an iterator over the
|
||
|
|
enclosing contexts of an array access. Each cont_i_next
|
||
|
|
operation must select the next enclosing loop or if.
|
||
|
|
We must be able to tell which we have selected, and
|
||
|
|
get a "loop_context" or "if_context" object from it.
|
||
|
|
*/
|
||
|
|
|
||
|
|
struct omegaContIter {
|
||
|
|
struct omegaContIter *next;
|
||
|
|
int depth;
|
||
|
|
int line;
|
||
|
|
struct omegaLoop *loop;
|
||
|
|
struct omegaIf *ifstmt;
|
||
|
|
int loopiter;
|
||
|
|
};
|
||
|
|
|
||
|
|
typedef struct omegaContIter *context_iterator;
|
||
|
|
|
||
|
|
|
||
|
|
/*extern context_iterator cont_i_for_access(a_access a);*/
|
||
|
|
#define cont_i_for_access(A) (A->context)
|
||
|
|
|
||
|
|
#define cont_i_next(C) (C = C->next)
|
||
|
|
#define cont_i_done(C) (C == NULL)
|
||
|
|
#define cont_i_cur_loop_p(C) (C->loopiter)
|
||
|
|
#define cont_i_cur_if_p(C) (!(C->loopiter))
|
||
|
|
#define cont_i_cur_if(C) (C->ifstmt)
|
||
|
|
#define cont_i_cur_loop(C) (C->loop)
|
||
|
|
#define cont_i_cur_depth(C) (C->depth)
|
||
|
|
|
||
|
|
/* cur_depth valid for loops - # of loops around stmts in this loop */
|
||
|
|
/* cur_depth is also needed for ifs as of release 3.0 */
|
||
|
|
/* #define access_is_in_then_or_else_of(A,C) ((A)->inIfStmt)*/
|
||
|
|
extern int access_is_in_then_or_else_of(a_access A,context_iterator C);
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/* access A is in the then or the else part of C,
|
||
|
|
where cont_i_cur_if_p must be true of C */
|
||
|
|
#define cont_i_cur_lineno(C) (C->line)
|
||
|
|
|
||
|
|
|
||
|
|
/* a "loop_context" provides information about a loop.
|
||
|
|
We need to be able to find affine_exprs for the start
|
||
|
|
and end bounds (if a bound is not affine, we should
|
||
|
|
get a result for which "is_affine" is false).
|
||
|
|
We also need to know if there is a step expression,
|
||
|
|
and whether it is known at compile time, and if so,
|
||
|
|
what it is. These last two must be answered by the
|
||
|
|
function "loops_step(LOOP,S,KNOWN)", which sets *KNOWN
|
||
|
|
to true if the step is known at compile time, and sets
|
||
|
|
*S to the step if it is known.
|
||
|
|
We must also be able to map a function over all the
|
||
|
|
variables used in the start and end bounds (as we did
|
||
|
|
for the variables used in the step expressions).
|
||
|
|
*/
|
||
|
|
|
||
|
|
|
||
|
|
struct omegaLoop {
|
||
|
|
struct omegaVar *symb;
|
||
|
|
struct _affine_expr *startl;
|
||
|
|
struct _affine_expr *endl;
|
||
|
|
int hasstep;
|
||
|
|
int stepl;
|
||
|
|
int knownstep;
|
||
|
|
struct omegaVar *constantestart;
|
||
|
|
int cstvaluestart;
|
||
|
|
struct omegaVar *constanteend;
|
||
|
|
int cstvaluesend;
|
||
|
|
};
|
||
|
|
|
||
|
|
typedef struct omegaLoop *loop_context;
|
||
|
|
|
||
|
|
#define loop_var_id(LOOP) (LOOP->symb)
|
||
|
|
#define loop_start(LOOP) (LOOP->startl)
|
||
|
|
#define loop_end(LOOP) (LOOP->endl)
|
||
|
|
#define loop_has_step_p(LOOP) (LOOP->hasstep)
|
||
|
|
#define loops_step(LOOP,S,KNOWN) { *S = LOOP->stepl; *KNOWN = LOOP->knownstep; }
|
||
|
|
/*
|
||
|
|
#define loop_map_over_start_vars(LOOP,F,ARGS) {(F)(LOOP->constantestart,ARGS);}
|
||
|
|
#define loop_map_over_end_vars(LOOP,F,ARGS) {(F)(LOOP->constanteend,ARGS);}
|
||
|
|
*/
|
||
|
|
#define loop_map_over_start_vars(LOOP,F,ARGS)
|
||
|
|
#define loop_map_over_end_vars(LOOP,F,ARGS)
|
||
|
|
|
||
|
|
/* an "if context" provides information about the conditions
|
||
|
|
surrounding an array access.
|
||
|
|
The current code can handle ifs with single >, >=, <, or <= conditions.
|
||
|
|
Note that it is not OK to just leave this out - it will prevent the
|
||
|
|
refinement, cover, termination, and kill tests from determining whether
|
||
|
|
or not they have exact information.
|
||
|
|
If, for some reason, you can not supply this information,
|
||
|
|
make sure that the context iterator for an array access in an if
|
||
|
|
yeilds one if_context for which if_condition_ok is false
|
||
|
|
*/
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
typedef enum { greater = 0, greater_eq = 1, less = 2, less_eq = 3 }
|
||
|
|
if_compare_operators;
|
||
|
|
|
||
|
|
|
||
|
|
struct omegaIf {
|
||
|
|
int condOK;
|
||
|
|
int ident;
|
||
|
|
if_compare_operators oper;
|
||
|
|
struct _affine_expr *left;
|
||
|
|
struct _affine_expr *right;
|
||
|
|
int partelse;
|
||
|
|
};
|
||
|
|
|
||
|
|
typedef struct omegaIf *if_context;
|
||
|
|
|
||
|
|
#define if_condition_ok(IC) (IC->condOK)
|
||
|
|
#define if_compare_op(IC) (IC->oper) /* one of if_compare_operators */
|
||
|
|
#define if_compare_left(IC) (IC->left) /* lhs of compare op */
|
||
|
|
#define if_compare_right(IC) (IC->right) /* rhs of compare op */
|
||
|
|
#define if_else_branch(IC) (IC->partelse) /* true in body of "else" clause */
|
||
|
|
#define if_map_over_vars(IC,F,ARGS)
|
||
|
|
|
||
|
|
|
||
|
|
/* define the type used to identify a variable (typically
|
||
|
|
a pointer into the symbol table or some such).
|
||
|
|
It must be possible to tell the difference between a loop
|
||
|
|
index and a symbolic constant, and for a loop index, we must
|
||
|
|
be able to find the depth of the loop.
|
||
|
|
We must also be able to associate a integer "tag" with each
|
||
|
|
variable - all tags must start out with the value UNTAGGED.
|
||
|
|
*/
|
||
|
|
|
||
|
|
struct omegaVar {
|
||
|
|
int loop;
|
||
|
|
int constp;
|
||
|
|
int indexp;
|
||
|
|
int tag;
|
||
|
|
char *name;
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
typedef struct omegaVar *var_id;
|
||
|
|
|
||
|
|
#define var_id_const_p(AE_VAR) (AE_VAR->constp)
|
||
|
|
#define var_id_index_p(AE_VAR) (AE_VAR->indexp)
|
||
|
|
#define var_ids_loop_no(AE_VAR) (AE_VAR->loop)
|
||
|
|
#define var_ids_tag(AE_VAR) (AE_VAR->tag)
|
||
|
|
#define var_ids_name(AE_VAR) (AE_VAR->name) /* only for debug */
|
||
|
|
#define UNTAGGED -1
|
||
|
|
|
||
|
|
|
||
|
|
/* representations of Data Dependences follow -
|
||
|
|
You probably should not change these, but simply convert from
|
||
|
|
this format into whatever you use, and vice versa, when getting
|
||
|
|
information from/to the omega test
|
||
|
|
*/
|
||
|
|
|
||
|
|
/* information about dd direction vectors.
|
||
|
|
works only if unsigned long int has at least 32 bits */
|
||
|
|
#include "dddir.h"
|
||
|
|
|
||
|
|
/*
|
||
|
|
A dir_and_dist_info structure contains information about a dependence
|
||
|
|
This is the form in which some of the omega test functions expect
|
||
|
|
dependence information.
|
||
|
|
*/
|
||
|
|
|
||
|
|
#include "portable.h"
|
||
|
|
typedef struct DD_info {
|
||
|
|
uint nest;
|
||
|
|
dddirection direction;
|
||
|
|
dddirection restraint;
|
||
|
|
bool distanceKnown[maxCommonNest];
|
||
|
|
int distance[maxCommonNest];
|
||
|
|
void * dd_graph_node_to_be_cloned;
|
||
|
|
/* dd_graph_node_to_be_cloned points to the structure
|
||
|
|
that must be duplicated when we need to make a copy
|
||
|
|
of an existing entry in the dependence graph using
|
||
|
|
the function clone_dd_graph_node_for_refinement */
|
||
|
|
|
||
|
|
DD_info()
|
||
|
|
{
|
||
|
|
nest = 0;
|
||
|
|
direction = 0;
|
||
|
|
restraint = 0;
|
||
|
|
for (int z = 0; z < maxCommonNest; ++z)
|
||
|
|
{
|
||
|
|
distanceKnown[z] = false;
|
||
|
|
distance[z] = 0;
|
||
|
|
}
|
||
|
|
dd_graph_node_to_be_cloned = NULL;
|
||
|
|
}
|
||
|
|
} dir_and_dist_info;
|
||
|
|
|
||
|
|
/* Duplicate the dd graph node, setting "isRefined" in the copy.
|
||
|
|
This bit will hopefully get cleaner in the next release */
|
||
|
|
void clone_dd_graph_node_for_refinement(void *dd_graph_node_to_be_cloned);
|
||
|
|
|
||
|
|
#define d_info_do_eq(D_INFO, J) \
|
||
|
|
if (ddextract1((D_INFO)->direction,(J)) == ddeq) \
|
||
|
|
{ \
|
||
|
|
(D_INFO)->distanceKnown[(J)] = 1; \
|
||
|
|
(D_INFO)->distance[(J)] = 0; \
|
||
|
|
}
|
||
|
|
|
||
|
|
#if ! defined NDEBUG
|
||
|
|
#define d_info_inv(D_INFO) \
|
||
|
|
{ \
|
||
|
|
int i; \
|
||
|
|
for (i=1; i<=(D_INFO)->nest; i++) { \
|
||
|
|
if (ddextract1((D_INFO)->direction,i) == ddeq) { \
|
||
|
|
if (!((D_INFO)->distanceKnown[i] && (D_INFO)->distance[i] == 0))\
|
||
|
|
{\
|
||
|
|
printf("%lld %lld %lld\n", (D_INFO)->nest, (D_INFO)->direction, (D_INFO)->restraint);\
|
||
|
|
for (int z = 0; z < maxCommonNest; ++z)\
|
||
|
|
printf("[%d]: %d %d\n", z, (D_INFO)->distanceKnown[z], (D_INFO)->distance[z]);\
|
||
|
|
}\
|
||
|
|
assert((D_INFO)->distanceKnown[i] && (D_INFO)->distance[i] == 0); \
|
||
|
|
} \
|
||
|
|
} \
|
||
|
|
}
|
||
|
|
#else
|
||
|
|
#define d_info_inv(X)
|
||
|
|
#endif
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
odd_iterators are now obsolete.
|
||
|
|
they have been replaced.
|
||
|
|
*/
|
||
|
|
|
||
|
|
/* dd_in_iterators and dd_out_iterators allow iteration thru all the
|
||
|
|
dependences into a given access or out of a given access.
|
||
|
|
|
||
|
|
We may need to find the source or destination node of the current
|
||
|
|
dependence, or find out whether it is a flow or output dependence,
|
||
|
|
and whether it covers or terminates.
|
||
|
|
|
||
|
|
We must also be able to identify a dependence, so that we don't
|
||
|
|
test it against itself in certain circumstances
|
||
|
|
|
||
|
|
For either type, we must be able to select the current dependence,
|
||
|
|
which we identify with the type dd_current.
|
||
|
|
|
||
|
|
From this current element, we may determine the nesting level, or
|
||
|
|
information about the dependence distances or directions or the
|
||
|
|
restraint vector.
|
||
|
|
*/
|
||
|
|
|
||
|
|
typedef void *dd_in_iterator; /* iterate thru dds in to an access */
|
||
|
|
typedef void *dd_out_iterator; /* iterate thru dds out from an access */
|
||
|
|
|
||
|
|
typedef void *dd_current; /* point to the dd the iterator is on */
|
||
|
|
|
||
|
|
#define dd_current_nest(DDC) (3)
|
||
|
|
#define dd_current_dist(DDC) ((int *)0) /* distance array */
|
||
|
|
#define dd_current_dist_known(DDC,j) 1 /* dd_current_dist(DDC)[j] meaningful?*/
|
||
|
|
#define dd_current_dir(DDC) (*((dddirection *)0)) /* direction */
|
||
|
|
#define dd_current_restr(DDC) (*((dddirection *)0)) /* restraint */
|
||
|
|
#define dd_current_as_string(DDC) "a dependence"
|
||
|
|
#define dd_current_src(DDC) ((a_access) 0)
|
||
|
|
#define dd_current_dest(DDC) ((a_access) 0)
|
||
|
|
|
||
|
|
|
||
|
|
#define dd_i_i_for_access(ACC) ((dd_in_iterator) 0)
|
||
|
|
#define dd_i_i_done(DD_I_I) (1)
|
||
|
|
#define dd_i_i_next(DD_I_I)
|
||
|
|
|
||
|
|
#define dd_i_i_current(DD_I_I) ((dd_current) 0)
|
||
|
|
#define dd_i_i_cur_src(DD_I_I) ((a_access) 0)
|
||
|
|
#define dd_i_i_cur_dest(DD_I_I) ((a_access) 0)
|
||
|
|
#define dd_i_i_cur_flow_p(DD_I_I) 0
|
||
|
|
#define dd_i_i_cur_output_p(DD_I_I) 0
|
||
|
|
#define dd_i_i_cur_cover_p(DD_I_I) 0
|
||
|
|
#define dd_i_i_cur_is(DD_I_I, DEP) (dd_i_i_current(DD_I_I) == (DEP))
|
||
|
|
|
||
|
|
#define dd_o_i_for_access(ACC) ((dd_out_iterator) 0)
|
||
|
|
#define dd_o_i_done(DD_O_I) 1
|
||
|
|
#define dd_o_i_next(DD_O_I)
|
||
|
|
|
||
|
|
#define dd_o_i_current(DD_O_I) ((dd_current) 0)
|
||
|
|
#define dd_o_i_cur_src(DD_O_I) ((a_access) 0)
|
||
|
|
#define dd_o_i_cur_dest(DD_O_I) ((a_access) 0)
|
||
|
|
#define dd_o_i_cur_output_p(DD_O_I) 0
|
||
|
|
#define dd_o_i_cur_terminate_p(DD_O_I) 0
|
||
|
|
#define dd_o_i_cur_is(DD_O_I, DEP) (dd_o_i_current(DD_O_I) == (DEP))
|
||
|
|
|
||
|
|
|
||
|
|
/* the function "store_dependence" will be called when the omega test
|
||
|
|
has detected a data dependence. It should convert from the
|
||
|
|
dir_and_dist_info into whatever form is used by the rest of the system */
|
||
|
|
|
||
|
|
void store_dependence(ddnature nature, a_access from_access,
|
||
|
|
a_access to_access, dir_and_dist_info *d_info);
|
||
|
|
|
||
|
|
|
||
|
|
/* convert dd nodes into stuff our functions can handle */
|
||
|
|
void ddnode_to_dir_and_dist(dd_current, dir_and_dist_info *);
|
||
|
|
|
||
|
|
/* copy info from a dir_and_dist_info into an existing dd node */
|
||
|
|
void dir_and_dist_into_ddnode(const dir_and_dist_info *ddi, dd_current);
|
||
|
|
|
||
|
|
|
||
|
|
/* take inequality number GEQ, and turn it into an assertion */
|
||
|
|
#define add_GEQ_assertion(P, VARS, GEQ) ;
|
||
|
|
|
||
|
|
|
||
|
|
#endif
|