moved
This commit is contained in:
14
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/Exit.h
Normal file
14
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/Exit.h
Normal file
@@ -0,0 +1,14 @@
|
||||
void Message_Add(char * str);
|
||||
void Exit(int c);
|
||||
void ErrAssert(char *t);
|
||||
|
||||
#ifdef MIN
|
||||
#undef MIN
|
||||
#endif
|
||||
|
||||
#ifdef MAX
|
||||
#undef MAX
|
||||
#endif
|
||||
|
||||
static int inline MIN(int X, int Y) { return ((X) < (Y) ? (X) : (Y)); }
|
||||
static int inline MAX(int X, int Y) { return ((X) > (Y) ? (X) : (Y)); }
|
||||
@@ -0,0 +1,12 @@
|
||||
/* add-assert.h,v 1.1 1993/09/17 22:14:04 fbodin Exp */
|
||||
|
||||
#ifndef Already_Included_AddAssert
|
||||
#define Already_Included_AddAssert 1
|
||||
|
||||
#include "portable.h"
|
||||
#include "lang-interf.h"
|
||||
|
||||
typedef enum { impossible, possible, too_hard } elimination_possible;
|
||||
elimination_possible possible_to_eliminate(dd_current dd);
|
||||
|
||||
#endif
|
||||
52
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/affine.h
Normal file
52
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/affine.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* affine.h,v 1.1 1993/09/17 22:14:06 fbodin Exp */
|
||||
|
||||
#ifndef Already_Included_Affine
|
||||
#define Already_Included_Affine 1
|
||||
|
||||
#include "lang-interf.h"
|
||||
#include "ip.h"
|
||||
|
||||
/* This file defines the affine_expr structure and macros & functions
|
||||
that are independent of tiny - that is, code that examines existing
|
||||
affine expressions. Code that builds affine expressions from the
|
||||
parse tree, or part of the parse tree, is in find_affine.h, as that
|
||||
code is tiny-specific.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
var_id tiny_var; /* pointer to symbol table entry */
|
||||
int coefficient; /* co-efficient */
|
||||
} affine_term;
|
||||
|
||||
typedef struct _affine_expr {
|
||||
int nterms;
|
||||
affine_term terms[maxVars]; /* 1st entry var is always 0 */
|
||||
struct _affine_expr *other_branch; /* if min or max */
|
||||
} affine_expr;
|
||||
|
||||
|
||||
#define is_affine(AE) ( (AE) != ¬_affine )
|
||||
#define node_is_affine(NODE) ( (NODE)->nodeaffine != (void *)¬_affine )
|
||||
|
||||
extern bool nodes_subs_are_affine(a_access A);
|
||||
/* the above is needed only for one assertion - for some
|
||||
array access A, return true iff all subscripts of A are affine */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" affine_expr not_affine;
|
||||
#else
|
||||
extern affine_expr not_affine;
|
||||
#endif
|
||||
/* affine_expr should point to not_affine if expression is not affine */
|
||||
|
||||
/* compare 2 affine exprs.
|
||||
return 1 if different, 0 if same
|
||||
*/
|
||||
int CmpAffineExprs(affine_expr *, affine_expr *);
|
||||
|
||||
/* return a copy allocated with malloc */
|
||||
affine_expr *CopyAffineExpr(affine_expr *);
|
||||
void FreeAffineExpr(affine_expr *);
|
||||
|
||||
|
||||
#endif
|
||||
36
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/cover.h
Normal file
36
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/cover.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/* cover.h,v 1.1 1993/09/17 22:14:07 fbodin Exp */
|
||||
|
||||
#ifndef Already_Included_cover
|
||||
#define Already_Included_cover
|
||||
|
||||
/*
|
||||
test to see if a dependence covers to_acc
|
||||
can be used for flow or output dependences
|
||||
*/
|
||||
int test_for_coverage(a_access from_acc, a_access to_acc,
|
||||
uint from_nest, uint to_nest, uint common_nest,
|
||||
dir_and_dist_info *dd, char *dd_as_string);
|
||||
|
||||
/*
|
||||
test to see if a dependence terminates from_acc
|
||||
can be used for output or anti dependences
|
||||
*/
|
||||
int test_for_termination(a_access from_acc, a_access to_acc,
|
||||
uint from_nest, uint to_nest, uint common_nest,
|
||||
dir_and_dist_info *dd, char *dd_as_string);
|
||||
|
||||
|
||||
typedef enum { really_not_there = 0,
|
||||
really_there = 1,
|
||||
didnt_test,
|
||||
non_affine_red_bound,
|
||||
non_affine_red_sub } possible_reasons;
|
||||
extern possible_reasons why_no_cover_or_terminator;
|
||||
|
||||
#define set_reason(X) (why_no_cover_or_terminator = (X))
|
||||
#define because(X) (why_no_cover_or_terminator == (X))
|
||||
/* use: if (!cover(...))
|
||||
if(because(non_affine_red)) ...
|
||||
*/
|
||||
|
||||
#endif
|
||||
69
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/dddir.h
Normal file
69
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/dddir.h
Normal file
@@ -0,0 +1,69 @@
|
||||
typedef long unsigned int dddirection;
|
||||
|
||||
/* directions: */
|
||||
#define ddlt (dddirection)0x1
|
||||
#define ddeq (dddirection)0x2
|
||||
#define ddgt (dddirection)0x4
|
||||
#define ddall (dddirection)0x7
|
||||
#define ddrr (dddirection)0x8
|
||||
#define ddne (dddirection)0xd
|
||||
#define ddanydir (dddirection)0xf
|
||||
/* #define ddeqeq (dddirection)0x10000000 unused */
|
||||
#define ddallnone (dddirection)0
|
||||
#define ddcovers (dddirection)0x80000000
|
||||
#define ddterminates (dddirection)0x40000000
|
||||
#define ddrefined (dddirection)0x20000000
|
||||
#define ddisCovered (dddirection)0x10000000
|
||||
#define ddisTerminated (dddirection)0x08000000
|
||||
#define ddisRefined (dddirection)0x04000000 /* what dd was before refine */
|
||||
#define ddkilled (dddirection)0x02000000
|
||||
#define ddzappableWC (dddirection)0x01000000
|
||||
#define ddzappable (dddirection)0x00800000
|
||||
#define dddirBits (dddirection)0x00777777
|
||||
/* added new flags 2/92 - 3/92 davew@cs.umd.edu */
|
||||
|
||||
/* test to see if a dd has been killed by a kill or cover */
|
||||
#define ddisDead(d) ((d) & (ddkilled | ddisCovered | ddisTerminated| ddisRefined))
|
||||
/* shift a direction 'd' to appropriate position for nest 'n' */
|
||||
#define dddirnest(d,n) ((d)<<(((n)-1)*4))
|
||||
/* test if direction vector 'dv' has direction 'd' set at nest 'n' */
|
||||
#define dddirtest(dv,d,n) ((dv)&dddirnest(d,n))
|
||||
/* test if direction vector 'dv' all-equal bit set */
|
||||
#define ddeqtest(dv) ((dv)&(ddallequal))
|
||||
/* return direction vector except for direction n */
|
||||
#define ddallBut(dv,n) ((dv)&(dddirBits & ~dddirnest(ddall,n)))
|
||||
/* set direction 'd' at nest 'dv' for nest 'n' */
|
||||
#define dddirset(dv,d,n) (dv|=dddirnest(d,n))
|
||||
/* reset all directions at nest 'n' in 'dv' except for 'd' */
|
||||
#define dddironly(dv,d,n) (dv=(((dv)&~dddirnest(ddanydir,n))|((dv)&dddirnest(d,n))))
|
||||
/* reset all directions at nest 'n' in 'dv', then set 'd' */
|
||||
#define dddirsetonly(dv,d,n) (dv=(((dv)&~dddirnest(ddanydir,n))|(dddirnest(d,n))))
|
||||
/* set all-equal bit in 'dv' */
|
||||
#define ddeqset(dv) (dv|=(ddallequal))
|
||||
/* reset direction 'd' at nest 'n' in 'dv' */
|
||||
#define dddirreset(dv,d,n) (dv&=(~dddirnest(d,n)))
|
||||
/* reset all-equal bit in 'dv' */
|
||||
#define ddeqreset(dv) (dv&=(~(ddallequal)))
|
||||
/* extract direction vector element at nest 'n' from 'dv' */
|
||||
#define ddextract1(dv,n) (((dv)>>(((n)-1)*4))&0xF)
|
||||
/* test direction 'd' in extracted direction vector element 'dv' */
|
||||
#define ddtest1(dv,d) ((dv)&(d))
|
||||
/* reset direction 'd' in extracted direction vector element 'dv' */
|
||||
#define ddreset1(dv,d) (dv&=(~(d)))
|
||||
/* set direction 'd' in extracted direction vector element 'dv' */
|
||||
#define ddset1(dv,d) (dv|=(d))
|
||||
/* filter all direction vector elements with direction 'd' set in 'dv' */
|
||||
#define ddfilter(dv,d) (((dv)&((d)|(d<<4)|(d<<8)|(d<<12)|(d<<16)|(d<<20)|(d<<24)))/d)
|
||||
/* set all filtered direction vector elements to direction 'd' */
|
||||
#define ddsetfilter(dv,f,d) (dv|=((f)*(d)))
|
||||
|
||||
/* unknown distance */
|
||||
#define ddunknown (dddirection)0x80000000
|
||||
|
||||
/* return the depth of the loop that carries dv, or the length+1 for loop ind.
|
||||
dv has only the 0 bit set at levels [1 .. dd_carried_by(dv, length(dv))]
|
||||
*/
|
||||
extern int dd_carried_by(dddirection dv, int length);
|
||||
extern int leading_zeros(dddirection dv, int length);
|
||||
extern void append_dd_flags(char *, dddirection dv);
|
||||
/* code for the above is currently in ddodriver.c */
|
||||
@@ -0,0 +1,148 @@
|
||||
/* ddomega-build.h,v 1.1 1993/09/17 22:14:08 fbodin Exp */
|
||||
|
||||
#ifndef Already_Included_DDOmega_Build
|
||||
#define Already_Included_DDOmega_Build
|
||||
|
||||
#include "range.h"
|
||||
#include "ip.h"
|
||||
|
||||
/* adjust the problem to include equality of subscript expressions at
|
||||
nodes access1 and access2. Index variables for access1 are looked
|
||||
up in range i1, and those for access2 in range i2. The non-index
|
||||
variables are looked up in the range non_i.
|
||||
|
||||
returns 0 if subscripts could not possibly be equal
|
||||
returns 1 if the conditions for their equality have been completely
|
||||
described by the constraints added to p
|
||||
returns 2 if there was a non-affine expression, in which case the
|
||||
constraints added to p must be true for equality (but they
|
||||
may also be true for some non-equal cases). If color==red,
|
||||
we stop trying to bound subscripts immediately.
|
||||
*/
|
||||
typedef enum { not_possible = 0, complete = 1, partial = 2 } equate_descr;
|
||||
|
||||
equate_descr equate_subscripts(Problem *p, range *i1, range *i2, range *non_i,
|
||||
int color, a_access access1, a_access access2);
|
||||
|
||||
/* Establish bounds for the loop indices and conditionals
|
||||
that enclose node n.
|
||||
If we come across a non-affine expression return 0.
|
||||
If we successfully bound everything return 1.
|
||||
Note that we finish doing all the bounds we can,
|
||||
in either case, so zapping will work well.
|
||||
|
||||
Assume that "outer" outer loops have been taken care of
|
||||
in some other way - i.e. that we are building the red
|
||||
part of some problem which represents a dependence with
|
||||
"outer" leading 0's, so we will take care of these
|
||||
variables by setting them equal to the black loop indices.
|
||||
|
||||
If "skip_outer_ifs_containing_me" is non-nil, any ifs
|
||||
that are within exactly "outer" loops and contain it in
|
||||
either the "then" or "else" code.
|
||||
|
||||
This corresponds to the situation:
|
||||
for1
|
||||
for2
|
||||
if1 then
|
||||
if2a then
|
||||
access a
|
||||
endif
|
||||
if2b then
|
||||
access skip_outer_ifs_containing_me
|
||||
endif
|
||||
endif
|
||||
endfor
|
||||
endfor
|
||||
|
||||
in which we want to skip if1 when bounding a in the 0,0 dependence
|
||||
from a to skip_outer_ifs_containing_me. Note that we don't have to
|
||||
distinguish between the then & else parts, as we can't have a 0,0
|
||||
if one access is is each.
|
||||
*/
|
||||
|
||||
int
|
||||
bound_inner_indices_and_conditionals(Problem *p,
|
||||
range *indices,range *steps,range *non_i,
|
||||
int outer, a_access skip_outer_ifs_containing_me,
|
||||
int color, a_access a);
|
||||
|
||||
|
||||
#define bound_indices_and_conditionals(P,IND,ST,NONI,COL,A) \
|
||||
bound_inner_indices_and_conditionals(P,IND,ST,NONI,0,NULL,COL,A)
|
||||
|
||||
/* in the functions below,
|
||||
var_id points to op_declare for symbolic constants,
|
||||
op_dolimit for index variables
|
||||
or some sort of expression for iteration #'s
|
||||
in 1st & 2nd cases, node's value points to S.T. entry */
|
||||
|
||||
|
||||
/* set bounds[1...depth(n)] to point to the dolimits of the loops containing n
|
||||
set *Nsteps to the # of loops that have step expressions
|
||||
set steps[0 ... *Nsteps - 1] to point to these step expressions
|
||||
also set the nodetag field of any step expressions to their index
|
||||
into the steps array. Steps for inner loops come first in "steps".
|
||||
*/
|
||||
void load_bounds_and_count_steps(a_access n, var_id bounds[],
|
||||
var_id steps[], int *Nsteps);
|
||||
|
||||
/* ensure that all symbolic constants used in affine subscript
|
||||
expressions appear in consts[0..*Nconsts-1], and that they
|
||||
are tagged with their indices.
|
||||
*Nconsts should be set before calling this function
|
||||
*/
|
||||
void load_constants_for_subscripts(a_access access,
|
||||
var_id consts[], int *Nconsts);
|
||||
|
||||
/* same for affine expressions used in loop bounds of loops surrounding n
|
||||
*Nconsts should be set before calling this function
|
||||
*/
|
||||
void load_constants_for_bounds(a_access n, var_id consts[], int *Nconsts);
|
||||
|
||||
|
||||
|
||||
/* low-level more problem manipulation functions */
|
||||
|
||||
void init_prob(Problem *p, uint Nvars, uint Nprot,
|
||||
char *(*getVarName)(unsigned int, void *),
|
||||
void *getVarNameArgs);
|
||||
uint prob_add_EQ(Problem *p, int color);
|
||||
uint prob_add_zero_EQ(Problem *p, int color);
|
||||
uint prob_add_GEQ(Problem *p, int color);
|
||||
uint prob_add_zero_GEQ(Problem *p, int color);
|
||||
|
||||
/* delta = access1 - access2, so for flow dep, delta = write - read */
|
||||
void set_deltas(Problem *p, int delta_color,
|
||||
range *deltas, range *a1, range *a2);
|
||||
|
||||
|
||||
/*
|
||||
Constrain a problem with the minimal constraints needed to
|
||||
enforce the direction vector in dd.
|
||||
Use restraint vector unless it is not convex or the direction
|
||||
vector is "=".
|
||||
*/
|
||||
|
||||
void constrain_with_dd(Problem *pr, range *dd_to, range *dd_from,
|
||||
dir_and_dist_info *dd, int color);
|
||||
|
||||
/*
|
||||
Constrain *pr with the direction vector in dd.
|
||||
*/
|
||||
void constrain_with_dddirs(Problem *pr, range *dd_to, range *dd_from,
|
||||
dir_and_dist_info *dd, int color);
|
||||
|
||||
/*
|
||||
*dir MUST NOT BE +-
|
||||
Constrain *pr with dimension j of *dir.
|
||||
Use equations of color "color".
|
||||
|
||||
It handles 0 by adding both var[j] >= 0 and var[j] <= 0,
|
||||
which is not bad, because red equalities are just converted back
|
||||
to pairs of inequalities anyway. Perhaps it would be better to
|
||||
add special case code for black 0's.
|
||||
*/
|
||||
void constrain_with_convex_dddir(Problem *pr, range *dd_to, range *dd_from,
|
||||
dddirection *dir, int j, int color);
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
/* ddomega-use.h,v 1.1 1993/09/17 22:14:09 fbodin Exp */
|
||||
|
||||
#ifndef Already_Included_DDOmega_Use
|
||||
#define Already_Included_DDOmega_Use
|
||||
|
||||
/* compute DD vectors, add them to nodes */
|
||||
|
||||
void calculateDDVectors(Problem *problemPtr, a_access access1,a_access access2,
|
||||
ddnature oitype, ddnature iotype,
|
||||
uint nest1, uint nest2, uint bnest, uint nonloops);
|
||||
|
||||
#endif
|
||||
77
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/ddomega.h
Normal file
77
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/ddomega.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/* ddomega.h,v 1.1 1993/09/17 22:14:10 fbodin Exp */
|
||||
|
||||
/*
|
||||
This file now contains only the main dependence test function.
|
||||
see refine.h, cover.h, and kill.h for the other functions that
|
||||
used to be declared here.
|
||||
|
||||
The structures used in these functions are now also declared here.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef Already_Included_DDOmega
|
||||
#define Already_Included_DDOmega
|
||||
|
||||
/*
|
||||
perform the omega test on the array accesses access1 and access2
|
||||
see dddriver.h for a description of "dd" arguments.
|
||||
*/
|
||||
|
||||
void dd_omega_test(a_access access1, a_access access2,
|
||||
ddnature oitype, ddnature iotype,
|
||||
uint nest1, uint nest2, uint bnest);
|
||||
|
||||
|
||||
#include "range.h"
|
||||
#include "ip.h"
|
||||
|
||||
|
||||
extern var_id *current_set_of_vars; /* used in getVarName fns */
|
||||
|
||||
/*
|
||||
delta problem description contains information needed
|
||||
to associate variable accesses in the tiny program with
|
||||
variables in the integer programming problem.
|
||||
The different ranges show which part of the array of
|
||||
variables in the IP problem correspond to different
|
||||
accesses in the tiny program.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
range deltas; /* deltas for common indices */
|
||||
range access1s; /* index variables for access 1 */
|
||||
range access2s; /* index variables for access 2 */
|
||||
range nonloops; /* symbolic constants */
|
||||
range steps1; /* step constraints for a1 */
|
||||
range steps2; /* step constraints for a1 */
|
||||
var_id vars[maxVars];
|
||||
} delta_prob_desc;
|
||||
|
||||
|
||||
/*
|
||||
build a delta_prob_desc for the dependence from access1 to access2,
|
||||
return 0 if it obviously can't have solutions because
|
||||
the subscripts obviously can't be equal.
|
||||
|
||||
Note that *dpd should be allocated at least as long as *prob,
|
||||
since the _getVarNameArgs filed of *prob will point to it.
|
||||
*/
|
||||
|
||||
int build_delta_prob_desc(delta_prob_desc *dpd, Problem *prob,
|
||||
a_access access1, a_access access2,
|
||||
int nest1, int nest2, int bnest);
|
||||
|
||||
/* the following are used by build_delta_prob_desc */
|
||||
|
||||
void delta_init(delta_prob_desc *dpd, Problem *p,
|
||||
int delta_color, uint Nd,
|
||||
uint Na1, var_id a1_vars[],
|
||||
uint Na2, var_id a2_vars[],
|
||||
uint Nsc, var_id sc_vars[],
|
||||
uint Ns1, var_id s1_vars[],
|
||||
uint Ns2, var_id s2_vars[]);
|
||||
void delta_inv(delta_prob_desc *dpd, Problem *p);
|
||||
void delta_cleanup(delta_prob_desc *dpd);
|
||||
#define delta_Nvars(dpd) (r_last(&(dpd)->steps2))
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,5 @@
|
||||
/* debug.h,v 1.1.1.2 1992/07/10 02:40:09 davew Exp */
|
||||
|
||||
extern int n_strange_occurances;
|
||||
extern FILE *debug2;
|
||||
extern void strange_occurance(char *message);
|
||||
47
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/flags.h
Normal file
47
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/flags.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Global flag variables
|
||||
*/
|
||||
|
||||
#if !defined(GLOB)
|
||||
#define GLOB extern
|
||||
#endif
|
||||
|
||||
GLOB int quiet;
|
||||
GLOB int AllowComments;
|
||||
|
||||
GLOB int ivr_on;
|
||||
GLOB int ivr_debug;
|
||||
GLOB int ivr_ElimUnused;
|
||||
GLOB int ivr_DepAnalysis;
|
||||
GLOB int ivr_Assert;
|
||||
GLOB int ivr_RepAffine;
|
||||
GLOB int ivr_DefEntryClass;
|
||||
GLOB int ivr_SubstScalars;
|
||||
GLOB int makeReductionOps;
|
||||
GLOB int doArrayExpn;
|
||||
GLOB int repeatArrayExpn;
|
||||
GLOB int doPrivatization;
|
||||
GLOB int arrDefInOut;
|
||||
GLOB int doEEdeps;
|
||||
#if defined OMIT_DDS_FOR_TOPLEVEL
|
||||
#define omitScalars 1
|
||||
#else
|
||||
GLOB int omitScalars;
|
||||
#endif
|
||||
|
||||
GLOB int debugLevel;
|
||||
GLOB int omegaPrintResult;
|
||||
GLOB int printing_zap_gists;
|
||||
|
||||
#if ! defined SKIP_OMEGA2
|
||||
GLOB int skipping_omega2;
|
||||
#endif
|
||||
|
||||
#if defined OMIT_DDS_FOR_TOPLEVEL
|
||||
#define omitTopLevel 1
|
||||
#else
|
||||
GLOB int omitTopLevel;
|
||||
#endif
|
||||
|
||||
GLOB char **Argv;
|
||||
GLOB int Argc;
|
||||
273
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/ip.h
Normal file
273
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/ip.h
Normal file
@@ -0,0 +1,273 @@
|
||||
|
||||
|
||||
#ifndef Already_Included_IP
|
||||
#define Already_Included_IP 1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#define maxVars 50
|
||||
#define maxGEQs 150
|
||||
#define maxEQs 27
|
||||
|
||||
|
||||
typedef int EqnKey;
|
||||
typedef struct _eqn
|
||||
{
|
||||
/*_eqn()
|
||||
{
|
||||
coef.resize(maxVars + 1);
|
||||
|
||||
std::fill(coef.begin(), coef.end(), 0);
|
||||
key = 0;
|
||||
touched = 0;
|
||||
color = 0;
|
||||
}*/
|
||||
|
||||
EqnKey key;
|
||||
int touched;
|
||||
int color;
|
||||
std::vector<int> coef;
|
||||
//int coef[maxVars + 1];
|
||||
} *Eqn;
|
||||
|
||||
#define headerWords 3
|
||||
|
||||
typedef struct _problem
|
||||
{
|
||||
private:
|
||||
int _nVars;
|
||||
int _numEQs, _numGEQs, _numSUBs;
|
||||
|
||||
void resizeEqs()
|
||||
{
|
||||
//printf("%d %d %d -> %d\n", _numEQs, _numGEQs, _numSUBs, _nVars + 2);
|
||||
for (int z = 0; z < _numEQs; ++z)
|
||||
_EQs[z].coef.resize(_nVars + 2);
|
||||
for (int z = 0; z < _numGEQs; ++z)
|
||||
_GEQs[z].coef.resize(_nVars + 2);
|
||||
for (int z = 0; z < _numSUBs; ++z)
|
||||
_SUBs[z].coef.resize(_nVars + 2);
|
||||
}
|
||||
public:
|
||||
_problem()
|
||||
{
|
||||
_numEQs = _numGEQs = 0;
|
||||
_numSUBs = 1;
|
||||
forwardingAddress.resize(maxVars + 2);
|
||||
_var.resize(maxVars + 2);
|
||||
_GEQs.resize(maxGEQs);
|
||||
_EQs.resize(maxEQs);
|
||||
_SUBs.resize(maxVars + 1);
|
||||
}
|
||||
|
||||
void _init()
|
||||
{
|
||||
forwardingAddress.resize(maxVars + 2);
|
||||
_var.resize(maxVars + 2);
|
||||
_GEQs.resize(maxGEQs);
|
||||
_EQs.resize(maxEQs);
|
||||
_SUBs.resize(maxVars + 1);
|
||||
}
|
||||
|
||||
void _init(int eqs, int ges, int subs, int nvars)
|
||||
{
|
||||
_nVars = nvars;
|
||||
_numEQs = eqs;
|
||||
_numGEQs = ges;
|
||||
_numSUBs = subs;
|
||||
resizeEqs();
|
||||
}
|
||||
|
||||
|
||||
int getVarsN() const { return _nVars; }
|
||||
void setVarsN(const int nvars)
|
||||
{
|
||||
_nVars = nvars;
|
||||
resizeEqs();
|
||||
}
|
||||
void addToVarsN(const int nvars)
|
||||
{
|
||||
_nVars += nvars;
|
||||
resizeEqs();
|
||||
}
|
||||
|
||||
int getNumEqs() const { return _numEQs; }
|
||||
int getNumGEqs() const { return _numGEQs; }
|
||||
int getNumSUBs() const { return _numSUBs; }
|
||||
|
||||
void setNumEqs(const int val)
|
||||
{
|
||||
_numEQs = val;
|
||||
//printf("EQ %d -> %d\n", _numEQs, _nVars + 2);
|
||||
for (int z = 0; z < _numEQs; ++z)
|
||||
_EQs[z].coef.resize(_nVars + 2);
|
||||
}
|
||||
void setNumGEqs(const int val)
|
||||
{
|
||||
_numGEQs = val;
|
||||
//printf("GEQ %d -> %d\n", _numGEQs, _nVars + 2);
|
||||
for (int z = 0; z < _numGEQs; ++z)
|
||||
_GEQs[z].coef.resize(_nVars + 2);
|
||||
}
|
||||
void setNumSUBs(const int val)
|
||||
{
|
||||
_numSUBs = val;
|
||||
//printf("SUB %d -> %d\n", _numSUBs, _nVars + 2);
|
||||
for (int z = 0; z < _numSUBs; ++z)
|
||||
_SUBs[z].coef.resize(_nVars + 2);
|
||||
}
|
||||
|
||||
void addNumEqs(const int val)
|
||||
{
|
||||
_numEQs += val;
|
||||
//printf("EQ %d -> %d\n", _numEQs, _nVars + 2);
|
||||
for (int z = 0; z < _numEQs; ++z)
|
||||
_EQs[z].coef.resize(_nVars + 2);
|
||||
}
|
||||
void addNumGEqs(const int val)
|
||||
{
|
||||
_numGEQs += val;
|
||||
//printf("GEQ %d -> %d\n", _numGEQs, _nVars + 2);
|
||||
for (int z = 0; z < _numGEQs; ++z)
|
||||
_GEQs[z].coef.resize(_nVars + 2);
|
||||
}
|
||||
void addNumSUBs(const int val)
|
||||
{
|
||||
_numSUBs += val;
|
||||
//printf("SUB %d -> %d\n", _numSUBs, _nVars + 2);
|
||||
for (int z = 0; z < _numSUBs; ++z)
|
||||
_SUBs[z].coef.resize(_nVars + 2);
|
||||
}
|
||||
|
||||
int _safeVars;
|
||||
int hashVersion;
|
||||
int variablesInitialized;
|
||||
int variablesFreed;
|
||||
std::vector<int> _var;
|
||||
//int _var[maxVars + 2];
|
||||
std::vector<int> forwardingAddress;
|
||||
//int forwardingAddress[maxVars + 2];
|
||||
char *(*_getVarName)(unsigned int var, void *args);
|
||||
void *_getVarNameArgs;
|
||||
std::vector<_eqn> _GEQs;
|
||||
//_eqn _GEQs [maxGEQs];
|
||||
std::vector<_eqn> _EQs;
|
||||
//_eqn _EQs[maxEQs];
|
||||
std::vector<_eqn> _SUBs;
|
||||
//_eqn _SUBs[maxVars + 1];
|
||||
} Problem;
|
||||
|
||||
|
||||
|
||||
#define UNKNOWN 2
|
||||
#define SIMPLIFY 3
|
||||
#define posInfinity (0x7ffffff)
|
||||
#define negInfinity (-0x7ffffff)
|
||||
#define red 1
|
||||
#define black 0
|
||||
|
||||
//#define eqnncpy(e1,e2,s) {int *p00,*q00,*r00; p00 = (int *)(e1); q00 = (int *)(e2); r00 = &p00[headerWords+1+s]; while(p00 < r00) *p00++ = *q00++; }
|
||||
|
||||
static void eqnncpy(_eqn *dst, const _eqn *src, const int s)
|
||||
{
|
||||
dst->color = src->color;
|
||||
dst->key = src->key;
|
||||
dst->touched = src->touched;
|
||||
dst->coef.resize((src->coef.size() > s + 2) ? src->coef.size() : s + 2);
|
||||
std::fill(dst->coef.begin(), dst->coef.end(), 0);
|
||||
|
||||
for (int z = 0; z < ((src->coef.size() < s + 1) ? src->coef.size() : s + 1); ++z)
|
||||
dst->coef[z] = src->coef[z];
|
||||
}
|
||||
|
||||
#define eqncpy(e1,e2) eqnncpy(e1, e2, nVars)
|
||||
//#define eqnnzero(e,s) { int *p00,*r00; p00 = (int *)(e); r00 = &p00[headerWords+1+(s)]; while(p00 < r00) *p00++ = 0;}
|
||||
|
||||
static void eqnnzero(_eqn *dst, const int s)
|
||||
{
|
||||
dst->color = 0;
|
||||
dst->key = 0;
|
||||
dst->touched = 0;
|
||||
dst->coef.resize(s + 2);
|
||||
for (int z = 0; z < s + 2; ++z)
|
||||
dst->coef[z] = 0;
|
||||
}
|
||||
|
||||
#define eqnzero(e) eqnnzero(e,nVars)
|
||||
|
||||
#define intDiv(a,b) ((1024 * b + a)/b - 1024)
|
||||
#define intMod(a,b) ((a)-(b)*intDiv(a,b))
|
||||
|
||||
|
||||
#define singleVarGEQ(e,nV) ((e).key != 0 && -maxVars <= (e).key && (e).key <= maxVars)
|
||||
|
||||
|
||||
extern void initializeOmega();
|
||||
|
||||
extern void initializeProblem(Problem *);
|
||||
extern void problemcpy(Problem *, Problem *);
|
||||
extern void printProblem(Problem *);
|
||||
extern void printRedEquations(Problem *);
|
||||
extern void prettyPrintProblem(Problem *);
|
||||
extern int simplifyProblem(Problem *);
|
||||
extern int simplifyApproximate(Problem *);
|
||||
extern void unprotectVariable(Problem *, int var);
|
||||
extern void negateGEQ(Problem *, int);
|
||||
|
||||
|
||||
/* set extra to 0 for normal use */
|
||||
extern void printEqn (Problem *p, Eqn e, int is_geq, int extra);
|
||||
extern void sprintEqn (char *str, Problem *p, Eqn e, int is_geq, int extra);
|
||||
|
||||
/*
|
||||
Return 1 if red equations constrain the set of possible solutions.
|
||||
We assume that there are solutions to the black equations by themselves,
|
||||
so if there is no solution to the combined problem, we return 1.
|
||||
*/
|
||||
extern int hasRedEquations(Problem * problemPtr, bool expensive);
|
||||
|
||||
extern int eliminateRedundant (Problem *problemPtr, bool expensive);
|
||||
extern void eliminateRed (Problem *problemPtr, bool eliminateAll);
|
||||
|
||||
/* constrainVariableSign also unprotects var & simplifies the problem */
|
||||
extern int
|
||||
constrainVariableSign(Problem *, int color, int var, int sign);
|
||||
|
||||
/* constrainVariableValue adds an EQ that makes variable var have
|
||||
value "value", even if variable i has been substituted out */
|
||||
extern void
|
||||
constrainVariableValue(Problem *problemPtr, int color, int var, int value);
|
||||
|
||||
extern int
|
||||
queryVariable(Problem *, int var, int *lowerBound, int *upperBound);
|
||||
|
||||
extern int
|
||||
queryVariableSigns(Problem *, int, int, int, int, int,
|
||||
int,
|
||||
bool *,
|
||||
int*);
|
||||
|
||||
extern int
|
||||
queryVariableBounds(Problem * problemPtr, int i, int *l, int *u);
|
||||
|
||||
extern int solve(Problem *problemPtr, int desiredResult);
|
||||
|
||||
extern void setOutputFile(FILE *file);
|
||||
/* set "file" to the file to which the output of printProblem should go */
|
||||
|
||||
extern int reduceWithSubs;
|
||||
|
||||
extern int omegaPrintResult;
|
||||
/* set to non-zero to have constrainVariableSign and simplifyProblem
|
||||
print the resulting simplified problems */
|
||||
|
||||
extern int firstCheckForRedundantEquations;
|
||||
|
||||
extern void (*whenReduced)(Problem *problemPtr);
|
||||
extern void noProcedure(Problem *problemPtr);
|
||||
extern void Exit(int c);
|
||||
|
||||
#endif
|
||||
|
||||
79
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/kill.h
Normal file
79
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/kill.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/* kill.h,v 1.1 1993/09/17 22:14:14 fbodin Exp */
|
||||
|
||||
#ifndef Already_Included_kill
|
||||
#define Already_Included_kill
|
||||
|
||||
/*
|
||||
Do quick but possibly indecisive kill tests to see
|
||||
if dependence dd (from from_acc to to_acc) is killed.
|
||||
|
||||
If dd is obviously killed by an intervening write that
|
||||
covers its destination or terminaties its source,
|
||||
return ddisCovered or ddisTerminated.
|
||||
Otherwise, return 0 (is which case dd may or may not be killed -
|
||||
call accurate_test_for_kill to find out).
|
||||
|
||||
this_dep identifies the dependence being tested, so that we will
|
||||
not try to kill a dependence with itself. this_dep will be
|
||||
passed to dd_i_i_cur_is and dd_o_i_cur_is.
|
||||
|
||||
This function may update dd if dd is partly killed.
|
||||
In this case, dd's ddrefined bit will be set.
|
||||
|
||||
Quick test for kill works for flow, output, or anti dependences
|
||||
*/
|
||||
|
||||
dddirection
|
||||
quick_test_for_kill(dir_and_dist_info *dd, char *dd_as_string,
|
||||
a_access from_acc, a_access to_acc,
|
||||
dd_current this_dep);
|
||||
|
||||
/*
|
||||
Test to see if flow dependence dd (from from_acc to to_acc)
|
||||
can be killed. If so, return ddisKilled.
|
||||
|
||||
This should be called if quick_test_for_kill returns 0.
|
||||
|
||||
Works for flow and output dependences - why not anti?
|
||||
*/
|
||||
|
||||
dddirection
|
||||
accurate_test_for_kill(dir_and_dist_info *dd, char *dd_as_string,
|
||||
a_access from_acc, a_access to_acc,
|
||||
dd_current this_dep);
|
||||
|
||||
|
||||
/*
|
||||
for "READS" type problems,
|
||||
non-index vars and reads are protected
|
||||
|
||||
This type of problem is used in killing, cover & termination testing,
|
||||
and in refinement
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
range nonloops;
|
||||
range reads; /* index variables @ time of read */
|
||||
range rsteps;
|
||||
range write1s; /* index variables @ time of write #1 */
|
||||
range w1steps;
|
||||
range write2s; /* index variables @ time of write #2 */
|
||||
range w2steps;
|
||||
var_id vars[maxVars];
|
||||
} read_prob_desc;
|
||||
|
||||
/* there is no equivalent to build_delta_prob_desc, as the various
|
||||
functions that build read_prob_desc's do so in different ways. */
|
||||
|
||||
typedef enum { sc_and_r, sc_r_and_w1 } protect_in_read;
|
||||
void read_init(read_prob_desc *rpd, Problem *p,
|
||||
protect_in_read protect_which, uint Nsc, var_id sc_vars[],
|
||||
uint Nr, var_id r_vars[], uint Nrs, var_id rs_vars[],
|
||||
uint Nw1, var_id w1_vars[], uint Nw1s, var_id w1s_vars[],
|
||||
uint Nw2, var_id w2_vars[], uint Nw2s, var_id w2s_vars[]);
|
||||
void read_inv(read_prob_desc *rpd, Problem *p);
|
||||
void read_cleanup(read_prob_desc *rpd);
|
||||
#define read_Nvars(rpd) (r_last(&(rpd)->w2steps))
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,373 @@
|
||||
/* lang-interf.generic,v 1.1 1993/09/17 22:14:15 fbodin Exp */
|
||||
|
||||
/*
|
||||
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
|
||||
|
||||
/* 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 6 /* (32 bits - 6 used in dddir.h) / 4 bits per dd */
|
||||
|
||||
typedef enum { ddflow, ddanti, ddoutput, ddreduce } 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.
|
||||
*/
|
||||
|
||||
typedef void *a_access;
|
||||
|
||||
#define access_as_string(A) ("a[i]") /* only used in debugging output */
|
||||
#define accesss_sym(A) (void *)0 /* currently only used in 1 assertion */
|
||||
#define accesss_lineno(A) 42 /* currently only in debugging output */
|
||||
#define accesss_cover_depth(A) ( *((int *) 0) )
|
||||
#define accesss_terminator_depth(A) ( *((int *) 0) )
|
||||
#define accesss_depth(A) 7
|
||||
#define accesss_shared_depth(A1,A2) 6
|
||||
|
||||
/* does A access a private var - if so, at what level is it private? */
|
||||
#define access_private_var_p(A) 0
|
||||
#define access_private_var_level(A) 3
|
||||
|
||||
#define access_fetch_p(A) 1
|
||||
#define access_store_p(A) 1
|
||||
#define access_update_p(A) 1
|
||||
/* Are A1 and A2 updates of the same kind (ie both += or both *=) */
|
||||
#define access_same_update_type_p(A1, A2) 1
|
||||
|
||||
/* can we execute A1 and then A2 without going to another iteration */
|
||||
#define access_lexically_preceeds(A1, A2) 1
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
typedef void *sub_iterator;
|
||||
#define sub_i_for_access(A) ((sub_iterator *) 0)
|
||||
#define sub_i_next(SUBI)
|
||||
#define sub_i_done(SUBI) (1)
|
||||
#define sub_i_cur_is_affine(SUBI) (1)
|
||||
#define sub_i_cur_affine(SUBI) ((affine_expr *) 0)
|
||||
#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.
|
||||
*/
|
||||
|
||||
typedef void *context_iterator;
|
||||
extern context_iterator cont_i_for_access(a_access a);
|
||||
#define cont_i_next(C)
|
||||
#define cont_i_done(C) 1
|
||||
#define cont_i_cur_loop_p(C) 1
|
||||
#define cont_i_cur_if_p(C) 0
|
||||
#define cont_i_cur_if(C) (C)
|
||||
#define cont_i_cur_loop(C) (C)
|
||||
#define cont_i_cur_depth(C) 7
|
||||
/* 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) 0
|
||||
/* 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) 42
|
||||
|
||||
|
||||
/* 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).
|
||||
*/
|
||||
|
||||
typedef void *loop_context;
|
||||
|
||||
#define loop_var_id(LOOP) ((var_id *) 0)
|
||||
#define loop_start(LOOP) ((affine_expr *) 0)
|
||||
#define loop_end(LOOP) ((affine_expr *) 0)
|
||||
#define loop_has_step_p(LOOP) 1
|
||||
#define loops_step(LOOP,S,KNOWN) { *S = 2; *KNOWN = 1; }
|
||||
#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 void *if_context;
|
||||
|
||||
typedef enum { greater = 0, greater_eq = 1, less = 2, less_eq = 3 }
|
||||
if_compare_operators;
|
||||
|
||||
#define if_condition_ok(IC) (0)
|
||||
#define if_compare_op(IC) (greater) /* one of if_compare_operators */
|
||||
#define if_compare_left(IC) ((affine_expr *) 0) /* lhs of compare op */
|
||||
#define if_compare_right(IC) ((affine_expr *) 0) /* rhs of compare op */
|
||||
#define if_else_branch(IC) (0) /* 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.
|
||||
*/
|
||||
|
||||
typedef void *var_id;
|
||||
|
||||
#define var_id_const_p(AE_VAR) (1)
|
||||
#define var_id_index_p(AE_VAR) (1)
|
||||
#define var_ids_loop_no(AE_VAR) (7 /* depth of associated loop */ )
|
||||
#define var_ids_tag(AE_VAR) (*(int *)0)
|
||||
#define var_ids_name(AE_VAR) ("a variable 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.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
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 */
|
||||
} 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) { \
|
||||
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) ;
|
||||
503
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/lang-interf.h
Normal file
503
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/lang-interf.h
Normal file
@@ -0,0 +1,503 @@
|
||||
/* 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
|
||||
37
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/missing.h
Normal file
37
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/missing.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/* missing.h,v 1.1.1.2 1992/07/10 02:40:55 davew Exp */
|
||||
#ifndef Already_Included_Missing
|
||||
#define Already_Included_Missing
|
||||
|
||||
|
||||
/* You may need to comment these out */
|
||||
|
||||
extern int delwin();
|
||||
extern int touchwin();
|
||||
extern int waddch();
|
||||
extern int waddstr();
|
||||
extern int wclear();
|
||||
extern int wclrtoeol();
|
||||
extern int wdeleteln();
|
||||
extern int wgetch();
|
||||
extern int wgetstr();
|
||||
extern int winsch();
|
||||
extern int winsertln();
|
||||
extern int wmove();
|
||||
extern int wrefresh();
|
||||
extern int wstandend();
|
||||
extern int wstandout();
|
||||
extern int printw();
|
||||
extern int wprintw();
|
||||
extern int mvwprintw();
|
||||
extern int endwin();
|
||||
extern int stty();
|
||||
|
||||
extern char *getwd();
|
||||
|
||||
extern int wait3();
|
||||
|
||||
extern int mkdir();
|
||||
|
||||
extern int getrusage();
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,50 @@
|
||||
/* omega2flags.h,v 1.1 1993/09/17 22:14:18 fbodin Exp */
|
||||
|
||||
/* compile time and run time flags that control the behavior of the
|
||||
code that eliminates dead dependences */
|
||||
|
||||
|
||||
#ifndef Already_Included_Omega2flags
|
||||
#define Already_Included_Omega2flags
|
||||
|
||||
|
||||
#if defined SKIP_OMEGA2
|
||||
#define skipping_omega2 1
|
||||
#else
|
||||
extern int skipping_omega2;
|
||||
#endif
|
||||
|
||||
#if defined SKIP_ZAPPABLE
|
||||
#define skipping_zappable 1
|
||||
#else
|
||||
#define skipping_zappable 0
|
||||
#endif
|
||||
|
||||
|
||||
#if defined ONLY_CHANGE_FLOW_LEVEL
|
||||
#define skipping_plus_refinement 1
|
||||
#define skipping_o_a_tightening 1
|
||||
#else
|
||||
#define skipping_plus_refinement 0
|
||||
#define skipping_o_a_tightening 0
|
||||
#endif
|
||||
|
||||
#if ! defined skipping_all_tightening
|
||||
#define skipping_all_tightening 0
|
||||
#endif
|
||||
|
||||
#if ! defined skipping_bailout
|
||||
#define skipping_bailout 0
|
||||
#endif
|
||||
|
||||
#if defined EXTRAVAGANT
|
||||
#define doing_all_accurate_kills 1
|
||||
/* do refinement of all kinds of dds: "skipping_plus_refinement" still works */
|
||||
#define doing_all_refines 1
|
||||
#else
|
||||
#define doing_all_accurate_kills 0
|
||||
/* do refinement of all kinds of dds: "skipping_plus_refinement" still works */
|
||||
#define doing_all_refines 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
57
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/portable.h
Normal file
57
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/portable.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* portable.h,v 1.1 1993/09/17 22:14:20 fbodin Exp */
|
||||
|
||||
#ifndef Already_Included_Portable
|
||||
#define Already_Included_Portable
|
||||
|
||||
/* define integer type names for portability */
|
||||
/* use 'sint' and 'uint' unless space is at a premium */
|
||||
|
||||
typedef long int sint;
|
||||
typedef char sint8;
|
||||
typedef short int sint16;
|
||||
typedef long int sint32;
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned short int uint16;
|
||||
typedef unsigned long int uint32;
|
||||
#ifndef __cplusplus
|
||||
typedef unsigned char bool;
|
||||
#endif
|
||||
|
||||
/* tiny uses arrays of characters to buffer I/O at various points.
|
||||
These really should be dynamically sized strings, but since that
|
||||
is a pain in C, we just make arrays of the following size.
|
||||
In many cases, the size is not tested, so, for example, running
|
||||
tiny on a file with a really long name can cause a core dump.
|
||||
This ought to be at least 256, as thats the largest constant that
|
||||
we replaced with TINYBUFSIZ. This is in portable.h for irony */
|
||||
#define TINYBUFSIZ 256
|
||||
|
||||
#ifndef __TURBOC__
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#define uint unsigned int
|
||||
|
||||
#ifndef NIL
|
||||
#define NIL 0L
|
||||
#endif
|
||||
|
||||
#define ANSI_libraries
|
||||
|
||||
#define TYPEPROCPTR typedef
|
||||
#define EXPROC extern
|
||||
#define PROC
|
||||
|
||||
#define SWAP(TYPE, V1, V2) \
|
||||
{ TYPE TMP; \
|
||||
TMP = V1; \
|
||||
V1 = V2; \
|
||||
V2 = TMP; \
|
||||
}
|
||||
|
||||
/*
|
||||
#define MIN(X,Y) ((X)<(Y)?(X):(Y))
|
||||
#define MAX(X,Y) ((X)>(Y)?(X):(Y))
|
||||
*/
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
/* portable.h.origine,v 1.1 1993/09/17 22:14:21 fbodin Exp */
|
||||
|
||||
#ifndef Already_Included_Portable
|
||||
#define Already_Included_Portable
|
||||
|
||||
/* define integer type names for portability */
|
||||
/* use 'sint' and 'uint' unless space is at a premium */
|
||||
|
||||
typedef long int sint;
|
||||
typedef char sint8;
|
||||
typedef short int sint16;
|
||||
typedef long int sint32;
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned short int uint16;
|
||||
typedef unsigned long int uint32;
|
||||
typedef unsigned char bool;
|
||||
|
||||
/* tiny uses arrays of characters to buffer I/O at various points.
|
||||
These really should be dynamically sized strings, but since that
|
||||
is a pain in C, we just make arrays of the following size.
|
||||
In many cases, the size is not tested, so, for example, running
|
||||
tiny on a file with a really long name can cause a core dump.
|
||||
This ought to be at least 256, as thats the largest constant that
|
||||
we replaced with TINYBUFSIZ. This is in portable.h for irony */
|
||||
#define TINYBUFSIZ 256
|
||||
|
||||
#ifndef __TURBOC__
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#define uint unsigned int
|
||||
|
||||
#ifndef NIL
|
||||
#define NIL 0L
|
||||
#endif
|
||||
|
||||
#define ANSI_libraries
|
||||
|
||||
#define TYPEPROCPTR typedef
|
||||
#define EXPROC extern
|
||||
#define PROC
|
||||
|
||||
#define SWAP(TYPE, V1, V2) \
|
||||
{ TYPE TMP; \
|
||||
TMP = V1; \
|
||||
V1 = V2; \
|
||||
V2 = TMP; \
|
||||
}
|
||||
|
||||
#define MIN(X,Y) ((X)<(Y)?(X):(Y))
|
||||
#define MAX(X,Y) ((X)>(Y)?(X):(Y))
|
||||
|
||||
#endif
|
||||
19
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/range.h
Normal file
19
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/range.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/* range.h,v 1.1.1.1 1992/07/10 02:41:06 davew Exp */
|
||||
|
||||
#ifndef Already_Included_Range
|
||||
#define Already_Included_Range
|
||||
|
||||
typedef struct {
|
||||
uint _first;
|
||||
uint _length;
|
||||
} range;
|
||||
|
||||
#define r_first(r) ((r)->_first)
|
||||
#define r_last(r) ((r)->_first + (r)->_length - 1)
|
||||
#define r_length(r) ((r)->_length)
|
||||
#define r_in(r, i) ((i) >= r_first(r) && (i) <= r_last(r))
|
||||
/* #define r_grow(r) (++(r)->_length)
|
||||
grow is no longer allowed, as variables after the last region are
|
||||
used for iteration number counts */
|
||||
|
||||
#endif
|
||||
37
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/refine.h
Normal file
37
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/refine.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/* refine.h,v 1.1 1993/09/17 22:14:23 fbodin Exp */
|
||||
|
||||
#ifndef Already_Included_refine
|
||||
#define Already_Included_refine
|
||||
|
||||
/*
|
||||
if from_acc is a write, try to refine the source
|
||||
if to_acc is a write, try to refine the destination
|
||||
(If both are writes, I think we could get a bit more refinement
|
||||
by having a refine_both, which tries to refine either the source
|
||||
or the destination at each loop nest. I also think this would be
|
||||
so rare that its not worth writing the code.)
|
||||
|
||||
*d_info will be updated if refinement is successful
|
||||
|
||||
can be used for flow, output, or anti dependences
|
||||
*/
|
||||
void refine_dependence(a_access from, a_access to,
|
||||
dir_and_dist_info *d_info);
|
||||
|
||||
/*
|
||||
try to refine a covers leading 0+'s into 0's.
|
||||
can be used for output or flow dependences
|
||||
*/
|
||||
void tighten_cover(a_access from_acc, a_access to_acc,
|
||||
dir_and_dist_info *d_info,
|
||||
char *dd_as_string);
|
||||
|
||||
/*
|
||||
try to refine a terminators leading 0+'s into 0's.
|
||||
can be used for output or anti dependences
|
||||
*/
|
||||
void tighten_terminator(a_access from_acc, a_access to_acc,
|
||||
dir_and_dist_info *d_info,
|
||||
char *dd_as_string);
|
||||
|
||||
#endif
|
||||
124
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/screen.h
Normal file
124
Sapfor/_src/SageAnalysisTool/OmegaForSage/include/screen.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/* screen.h,v 1.1.1.2 1992/07/10 02:41:20 davew Exp */
|
||||
|
||||
|
||||
#ifndef Already_Included_Screen
|
||||
#define Already_Included_Screen
|
||||
|
||||
|
||||
/* Define 6 screen primitives:
|
||||
screen_init() what to call to initialize the graphics system.
|
||||
screen_print like 'printf' to write to the virtual screen
|
||||
screen_move(line,col) to move to an (line,col) position on the virtual screen
|
||||
screen_where(line,col) get the current (line,col) position
|
||||
screen_highlight() print with reverse video
|
||||
screen_lowlight() end reverse-video printing
|
||||
screen_getchar(ch,line,col) get the char at position (line,col)
|
||||
[may move cursor]
|
||||
screen_clear() how to clear the screen
|
||||
screen_clrline(line) move to the start of line 'line' and clear it
|
||||
screen_clreol() clear to end of this line from current pos
|
||||
screen_clrrest() clear to end of screen from this line
|
||||
screen_update() after _print, how to update the actual screen
|
||||
screen_fini() what to call when done with graphics.
|
||||
|
||||
two variables:
|
||||
COLS : number of columns on screen
|
||||
LINES: number of lines on screen
|
||||
|
||||
0 <= line < LINES
|
||||
0 <= col < COLS
|
||||
*/
|
||||
|
||||
#ifdef __TURBOC__
|
||||
/* no good way to use Turbo C to detect number of lines/cols on screen */
|
||||
#define LINES 25
|
||||
#define COLS 80
|
||||
|
||||
#include <conio.h>
|
||||
/* #define screen_init() textattr((BLUE<<4)+LIGHTGRAY) */
|
||||
#define screen_init() textattr((BLACK<<4)+LIGHTGRAY), 1
|
||||
/* added ,1 to make it return TRUE. 3.21.91 davew@panache.cs.umd.edu */
|
||||
#define screen_print cprintf
|
||||
#define screen_move(line,col) gotoxy(col+1,line+1)
|
||||
#define screen_where(line,col) line=wherey()-1;col=wherex()-1
|
||||
/* #define screen_highlight() textattr((LIGHTGRAY<<4)+BLUE) */
|
||||
/* #define screen_lowlight() textattr((BLUE<<4)+LIGHTGRAY) */
|
||||
#define screen_highlight() textattr((LIGHTGRAY<<4)+BLACK)
|
||||
#define screen_lowlight() textattr((BLACK<<4)+LIGHTGRAY)
|
||||
#define screen_getchar(ch,line,col) \
|
||||
{ char c[2];\
|
||||
gettext(col+1,line+1,col+1,line+1,c);\
|
||||
ch = c[2]; }
|
||||
#define screen_clear() clrscr()
|
||||
#define screen_clrline(line) gotoxy(1,line+1);clreol()
|
||||
#define screen_clreol() clreol()
|
||||
#define screen_clrrest() { uint l;\
|
||||
for(l=wherey();l<=LINES-2;++l){\
|
||||
gotoxy(1,l);\
|
||||
clreol();\
|
||||
}\
|
||||
}
|
||||
#define screen_update()
|
||||
#define screen_fini()
|
||||
#else
|
||||
#include <curses.h>
|
||||
#include "missing.h"
|
||||
#undef bool
|
||||
/* #define screen_init() initscr();refresh() */
|
||||
|
||||
/* Three new functions for use with scrolling */
|
||||
#define screen_putchar mvaddch
|
||||
#define screen_waddch mvwaddch
|
||||
#define screen_insertln insertln
|
||||
#define screen_deleteln deleteln
|
||||
#define screen_print printw
|
||||
#define screen_wprint mvwprintw
|
||||
#define screen_move(line,col) move(line,col)
|
||||
#define screen_where(line,col) getyx(stdscr,line,col)
|
||||
#define screen_highlight() standout()
|
||||
#define screen_lowlight() standend()
|
||||
#define screen_dhighlight() wstandout(depend)
|
||||
#define screen_dlowlight() wstandend(depend)
|
||||
#define screen_touch() touchwin(stdscr)
|
||||
#define screen_dtouch() touchwin(depend)
|
||||
#define screen_dclose() delwin(depend)
|
||||
|
||||
/* get the character directly from the curses data structure so that the */
|
||||
/* attribute bit is not stripped off */
|
||||
#define screen_getchar(ch,line,col) ch=stdscr->_y[line][col]
|
||||
|
||||
#define screen_clear() { clear();\
|
||||
if (depend_shown)\
|
||||
wclear(depend);\
|
||||
}
|
||||
#define screen_clrline(line) {move(line,0);clrtoeol();}
|
||||
#define screen_clreol() clrtoeol()
|
||||
#define screen_clrrest() { uint l,c;\
|
||||
getyx(stdscr,l,c);\
|
||||
for(l=l;l<LINES-2;++l){\
|
||||
move(l,0);\
|
||||
clrtoeol();\
|
||||
}\
|
||||
}
|
||||
#define screen_update() { refresh();\
|
||||
if (depend_shown){\
|
||||
wrefresh(depend);\
|
||||
}\
|
||||
}
|
||||
#define screen_touch_and_update() { touchwin(stdscr); refresh();\
|
||||
if (depend_shown){\
|
||||
touchwin(depend); wrefresh(depend);\
|
||||
}\
|
||||
}
|
||||
|
||||
extern int screen_init();
|
||||
extern void screen_fini();
|
||||
/* changed to functions for better results from curses
|
||||
3/20/91 davew@panache.cs.umd.edu */
|
||||
|
||||
#endif
|
||||
|
||||
WINDOW *depend;
|
||||
int depend_shown;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
Reference in New Issue
Block a user