GCC Middle and Back End API Reference
tree-data-ref.c File Reference

Data Structures

struct  datadep_stats
struct  data_ref_loc_d

Typedefs

typedef struct data_ref_loc_d data_ref_loc

Functions

static bool subscript_dependence_tester_1 (struct data_dependence_relation *, struct data_reference *, struct data_reference *, struct loop *)
static bool tree_fold_divides_p ()
static bool int_divides_p ()
static void dump_data_references ()
DEBUG_FUNCTION void debug ()
DEBUG_FUNCTION void debug_data_references ()
DEBUG_FUNCTION void debug_data_reference ()
void dump_data_reference (FILE *outf, struct data_reference *dr)
static void dump_affine_function ()
static void dump_conflict_function ()
static void dump_subscript ()
static void print_direction_vector (FILE *outf, lambda_vector dirv, int length)
static void print_dir_vectors (FILE *outf, vec< lambda_vector > dir_vects, int length)
static void print_lambda_vector ()
static void print_dist_vectors (FILE *outf, vec< lambda_vector > dist_vects, int length)
static void dump_data_dependence_relation (FILE *outf, struct data_dependence_relation *ddr)
DEBUG_FUNCTION void debug_data_dependence_relation ()
void dump_data_dependence_relations (FILE *file, vec< ddr_p > ddrs)
DEBUG_FUNCTION void debug_data_dependence_relations ()
static void dump_dist_dir_vectors ()
static void dump_ddrs ()
DEBUG_FUNCTION void debug_ddrs ()
static bool split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1, tree *var, tree *off)
void split_constant_offset ()
static tree canonicalize_base_object_address ()
bool dr_analyze_innermost ()
static void dr_analyze_indices ()
static void dr_analyze_alias ()
void free_data_ref ()
struct data_referencecreate_data_ref (loop_p nest, loop_p loop, tree memref, gimple stmt, bool is_read)
static bool dr_equal_offsets_p1 ()
bool dr_equal_offsets_p (struct data_reference *dra, struct data_reference *drb)
static bool affine_function_equal_p ()
static affine_fn common_affine_function ()
static tree affine_function_base ()
static bool affine_function_constant_p ()
static bool affine_function_zero_p ()
static tree signed_type_for_types ()
static affine_fn affine_fn_op ()
static affine_fn affine_fn_plus ()
static affine_fn affine_fn_minus ()
static void affine_fn_free ()
static void compute_subscript_distance ()
static conflict_functionconflict_fn_not_known ()
static conflict_functionconflict_fn_no_dependence ()
static bool object_address_invariant_in_loop_p ()
bool dr_may_alias_p (const struct data_reference *a, const struct data_reference *b, bool loop_nest)
struct data_dependence_relationinitialize_data_dependence_relation (struct data_reference *a, struct data_reference *b, vec< loop_p > loop_nest)
static void free_conflict_function ()
static void free_subscripts ()
static void finalize_ddr_dependent (struct data_dependence_relation *ddr, tree chrec)
static void non_affine_dependence_relation ()
static bool ziv_subscript_p ()
static bool siv_subscript_p ()
static conflict_functionconflict_fn ()
static affine_fn affine_fn_cst ()
static affine_fn affine_fn_univar ()
static void analyze_ziv_subscript (tree chrec_a, tree chrec_b, conflict_function **overlaps_a, conflict_function **overlaps_b, tree *last_conflicts)
static tree max_stmt_executions_tree ()
static bool chrec_is_positive ()
static void analyze_siv_subscript_cst_affine (tree chrec_a, tree chrec_b, conflict_function **overlaps_a, conflict_function **overlaps_b, tree *last_conflicts)
static tree initialize_matrix_A ()
static void compute_overlap_steps_for_affine_univar (int niter, int step_a, int step_b, affine_fn *overlaps_a, affine_fn *overlaps_b, tree *last_conflicts, int dim)
static void compute_overlap_steps_for_affine_1_2 (tree chrec_a, tree chrec_b, conflict_function **overlaps_a, conflict_function **overlaps_b, tree *last_conflicts)
static void lambda_vector_copy (lambda_vector vec1, lambda_vector vec2, int size)
static void lambda_matrix_copy (lambda_matrix mat1, lambda_matrix mat2, int m, int n)
static void lambda_matrix_id ()
static int lambda_vector_first_nz ()
static void lambda_matrix_row_add ()
static void lambda_matrix_row_exchange ()
static void lambda_vector_mult_const (lambda_vector vec1, lambda_vector vec2, int size, int const1)
static void lambda_vector_negate (lambda_vector vec1, lambda_vector vec2, int size)
static void lambda_matrix_row_negate ()
static bool lambda_vector_equal ()
static void lambda_matrix_right_hermite (lambda_matrix A, int m, int n, lambda_matrix S, lambda_matrix U)
static void analyze_subscript_affine_affine (tree chrec_a, tree chrec_b, conflict_function **overlaps_a, conflict_function **overlaps_b, tree *last_conflicts)
static bool can_use_analyze_subscript_affine_affine ()
static void analyze_siv_subscript (tree chrec_a, tree chrec_b, conflict_function **overlaps_a, conflict_function **overlaps_b, tree *last_conflicts, int loop_nest_num)
static bool gcd_of_steps_may_divide_p ()
static void analyze_miv_subscript (tree chrec_a, tree chrec_b, conflict_function **overlaps_a, conflict_function **overlaps_b, tree *last_conflicts, struct loop *loop_nest)
static void analyze_overlapping_iterations (tree chrec_a, tree chrec_b, conflict_function **overlap_iterations_a, conflict_function **overlap_iterations_b, tree *last_conflicts, struct loop *loop_nest)
static void save_dist_v ()
static void save_dir_v ()
static void add_outer_distances (struct data_dependence_relation *ddr, lambda_vector dist_v, int index)
static bool build_classic_dist_vector_1 (struct data_dependence_relation *ddr, struct data_reference *ddr_a, struct data_reference *ddr_b, lambda_vector dist_v, bool *init_b, int *index_carry)
static bool constant_access_functions ()
static void add_multivariate_self_dist ()
static void add_other_self_distances ()
static void insert_innermost_unit_dist_vector ()
static void add_distance_for_zero_overlaps ()
static bool build_classic_dist_vector (struct data_dependence_relation *ddr, struct loop *loop_nest)
static enum
data_dependence_direction 
dir_from_dist ()
static void build_classic_dir_vector ()
static void subscript_dependence_tester (struct data_dependence_relation *ddr, struct loop *loop_nest)
static bool access_functions_are_affine_or_constant_p (const struct data_reference *a, const struct loop *loop_nest)
static bool init_omega_eq_with_af (omega_pb pb, unsigned eq, unsigned int offset, tree access_fun, struct data_dependence_relation *ddr)
static void omega_extract_distance_vectors (omega_pb pb, struct data_dependence_relation *ddr)
static bool omega_setup_subscript (tree access_fun_a, tree access_fun_b, struct data_dependence_relation *ddr, omega_pb pb, bool *maybe_dependent)
static bool init_omega_for_ddr_1 (struct data_reference *dra, struct data_reference *drb, struct data_dependence_relation *ddr, omega_pb pb, bool *maybe_dependent)
static bool init_omega_for_ddr (struct data_dependence_relation *ddr, bool *maybe_dependent)
static bool ddr_consistent_p (FILE *file, struct data_dependence_relation *ddr, vec< lambda_vector > dist_vects, vec< lambda_vector > dir_vects)
void compute_affine_dependence (struct data_dependence_relation *ddr, struct loop *loop_nest)
bool compute_all_dependences (vec< data_reference_p > datarefs, vec< ddr_p > *dependence_relations, vec< loop_p > loop_nest, bool compute_self_and_rr)
static bool get_references_in_stmt ()
bool find_data_references_in_stmt (struct loop *nest, gimple stmt, vec< data_reference_p > *datarefs)
bool graphite_find_data_references_in_stmt (loop_p nest, loop_p loop, gimple stmt, vec< data_reference_p > *datarefs)
tree find_data_references_in_bb (struct loop *loop, basic_block bb, vec< data_reference_p > *datarefs)
tree find_data_references_in_loop (struct loop *loop, vec< data_reference_p > *datarefs)
static bool find_loop_nest_1 ()
bool find_loop_nest ()
bool compute_data_dependences_for_loop (struct loop *loop, bool compute_self_and_read_read_dependences, vec< loop_p > *loop_nest, vec< data_reference_p > *datarefs, vec< ddr_p > *dependence_relations)
bool compute_data_dependences_for_bb (basic_block bb, bool compute_self_and_read_read_dependences, vec< data_reference_p > *datarefs, vec< ddr_p > *dependence_relations)
static void analyze_all_data_dependences ()
void tree_check_data_deps ()
void free_dependence_relation ()
void free_dependence_relations ()
void free_data_refs ()

Variables

static struct datadep_stats dependence_stats

Typedef Documentation

typedef struct data_ref_loc_d data_ref_loc
   Describes a location of a memory reference.  

Function Documentation

static bool access_functions_are_affine_or_constant_p ( const struct data_reference a,
const struct loop loop_nest 
)
static
   Returns true when all the access functions of A are affine or
   constant with respect to LOOP_NEST.  
static void add_distance_for_zero_overlaps ( )
static
   Adds a unit distance vector to DDR when there is a 0 overlap.  This
   is the case for example when access functions are the same and
   equal to a constant, as in:

   | loop_1
   |   A[3] = ...
   |   ... = A[3]
   | endloop_1

   in which case the distance vectors are (0) and (1).  

Referenced by add_multivariate_self_dist().

static void add_multivariate_self_dist ( )
static
   Helper function for the case where DDR_A and DDR_B are the same
   multivariate access function with a constant step.  For an example
   see pr34635-1.c.  
     Polynomials with more than 2 variables are not handled yet.  When
     the evolution steps are parameters, it is not possible to
     represent the dependence using classical distance vectors.  
     For "{{0, +, 2}_1, +, 3}_2" the distance vector is (3, -2).  

References add_distance_for_zero_overlaps(), add_other_self_distances(), constant_access_functions(), DDR_NB_LOOPS, lambda_vector_new(), and save_dist_v().

static void add_other_self_distances ( )
static
   Helper function for the case where DDR_A and DDR_B are the same
   access functions.  
                   The evolution step is not constant: it varies in
                   the outer loop, so this cannot be represented by a
                   distance vector.  For example in pr34635.c the
                   evolution is {0, +, {0, +, 4}_1}_2.  

Referenced by add_multivariate_self_dist().

static void add_outer_distances ( struct data_dependence_relation ddr,
lambda_vector  dist_v,
int  index 
)
static
   Add a distance of 1 on all the loops outer than INDEX.  If we
   haven't yet determined a distance for this outer loop, push a new
   distance vector composed of the previous distance, and a distance
   of 1 for this outer loop.  Example:

   | loop_1
   |   loop_2
   |     A[10]
   |   endloop_2
   | endloop_1

   Saved vectors are of the form (dist_in_1, dist_in_2).  First, we
   save (0, 1), then we have to save (1, 0).  
     For each outer loop where init_v is not set, the accesses are
     in dependence of distance 1 in the loop.  
static affine_fn affine_fn_cst ( )
static
   Returns constant affine function with value CST.  

Referenced by analyze_miv_subscript(), chrec_is_positive(), and lambda_matrix_row_exchange().

static void affine_fn_free ( )
static
   Frees affine function FN.  

References conflict_function::n, and NO_DEPENDENCE.

static affine_fn affine_fn_minus ( )
static
   Returns the difference of affine functions FNA and FNB.  

References conflict_function::n, and NOT_KNOWN.

static affine_fn affine_fn_op ( )
static
   Applies operation OP on affine functions FNA and FNB, and returns the
   result.  
static affine_fn affine_fn_plus ( )
static
   Returns the sum of affine functions FNA and FNB.  
static affine_fn affine_fn_univar ( )
static
   Returns affine function with single variable, CST + COEF * x_DIM.  

References chrec_dont_know, double_int_fits_to_tree_p(), double_int_to_tree(), and max_stmt_executions().

static tree affine_function_base ( )
static
   Returns the base of the affine function FN.  
static bool affine_function_constant_p ( )
static
   Returns true if FN is a constant.  
static bool affine_function_equal_p ( )
static
   Returns true if FNA == FNB.  

References integer_zerop().

static bool affine_function_zero_p ( )
static
   Returns true if FN is the zero constant function.  
static void analyze_all_data_dependences ( )
static
   Entry point (for testing only).  Analyze all the data references
   and the dependence relations in LOOP.

   The data references are computed first.

   A relation on these nodes is represented by a complete graph.  Some
   of the relations could be of no interest, thus the relations can be
   computed on demand.

   In the following function we compute all the relations.  This is
   just a first implementation that is here for:
   - for showing how to ask for the dependence relations,
   - for the debugging the whole dependence graph,
   - for the dejagnu testcases and maintenance.

   It is possible to ask only for a part of the graph, avoiding to
   compute the whole dependence graph.  The computed dependences are
   stored in a knowledge base (KB) such that later queries don't
   recompute the same information.  The implementation of this KB is
   transparent to the optimizer, and thus the KB can be changed with a
   more efficient implementation, or the KB could be disabled.  
     Compute DDs on the whole function.  
static void analyze_miv_subscript ( tree  chrec_a,
tree  chrec_b,
conflict_function **  overlaps_a,
conflict_function **  overlaps_b,
tree last_conflicts,
struct loop loop_nest 
)
static
   Analyze a MIV (Multiple Index Variable) subscript with respect to
   LOOP_NEST.  *OVERLAPS_A and *OVERLAPS_B are initialized to the
   functions that describe the relation between the elements accessed
   twice by CHREC_A and CHREC_B.  For k >= 0, the following property
   is verified:

   CHREC_A (*OVERLAPS_A (k)) = CHREC_B (*OVERLAPS_B (k)).  
         Access functions are the same: all the elements are accessed
         in the same order.  
              For the moment, the following is verified:
              evolution_function_is_affine_multivariate_p (chrec_a,
              loop_nest->num) 
         testsuite/.../ssa-chrec-33.c
         {{21, +, 2}_1, +, -2}_2  vs.  {{20, +, 2}_1, +, -2}_2

         The difference is 1, and all the evolution steps are multiples
         of 2, consequently there are no overlapping elements.  
         testsuite/.../ssa-chrec-35.c
         {0, +, 1}_2  vs.  {0, +, 1}_3
         the overlapping elements are respectively located at iterations:
         {0, +, 1}_x and {0, +, 1}_x,
         in other words, we have the equality:
         {0, +, 1}_2 ({0, +, 1}_x) = {0, +, 1}_3 ({0, +, 1}_x)

         Other examples:
         {{0, +, 1}_1, +, 2}_2 ({0, +, 1}_x, {0, +, 1}_y) =
         {0, +, 1}_1 ({{0, +, 1}_x, +, 2}_y)

         {{0, +, 2}_1, +, 3}_2 ({0, +, 1}_y, {0, +, 1}_x) =
         {{0, +, 3}_1, +, 2}_2 ({0, +, 1}_x, {0, +, 1}_y)
         When the analysis is too difficult, answer "don't know".  

References affine_fn_cst(), chrec_dont_know, conflict_fn(), dependence_stats, and datadep_stats::num_same_subscript_function.

static void analyze_overlapping_iterations ( tree  chrec_a,
tree  chrec_b,
conflict_function **  overlap_iterations_a,
conflict_function **  overlap_iterations_b,
tree last_conflicts,
struct loop loop_nest 
)
static
@verbatim 

Determines the iterations for which CHREC_A is equal to CHREC_B in with respect to LOOP_NEST. OVERLAP_ITERATIONS_A and OVERLAP_ITERATIONS_B are initialized with two functions that describe the iterations that contain conflicting elements.

Remark: For an integer k >= 0, the following equality is true:

CHREC_A (OVERLAP_ITERATIONS_A (k)) == CHREC_B (OVERLAP_ITERATIONS_B (k)).

     If they are the same chrec, and are affine, they overlap
     on every iteration.  
     If they aren't the same, and aren't affine, we can't do anything
     yet.  

References chrec_contains_undetermined(), chrec_known, DDR_LOOP_NEST, DDR_NB_LOOPS, DDR_NUM_SUBSCRIPTS, DDR_SUBSCRIPT, DR_ACCESS_FN, finalize_ddr_dependent(), index_in_loop_nest(), int_cst_value(), lambda_vector_new(), non_affine_dependence_relation(), operand_equal_p(), and SUB_DISTANCE.

static void analyze_siv_subscript ( tree  chrec_a,
tree  chrec_b,
conflict_function **  overlaps_a,
conflict_function **  overlaps_b,
tree last_conflicts,
int  loop_nest_num 
)
static
   Analyze a SIV (Single Index Variable) subscript.  *OVERLAPS_A and
   *OVERLAPS_B are initialized to the functions that describe the
   relation between the elements accessed twice by CHREC_A and
   CHREC_B.  For k >= 0, the following property is verified:

   CHREC_A (*OVERLAPS_A (k)) = CHREC_B (*OVERLAPS_B (k)).  
static void analyze_siv_subscript_cst_affine ( tree  chrec_a,
tree  chrec_b,
conflict_function **  overlaps_a,
conflict_function **  overlaps_b,
tree last_conflicts 
)
static
   Analyze a SIV (Single Index Variable) subscript where CHREC_A is a
   constant, and CHREC_B is an affine function.  *OVERLAPS_A and
   *OVERLAPS_B are initialized to the functions that describe the
   relation between the elements accessed twice by CHREC_A and
   CHREC_B.  For k >= 0, the following property is verified:

   CHREC_A (*OVERLAPS_A (k)) = CHREC_B (*OVERLAPS_B (k)).  
     Special case overlap in the first iteration.  
                     Example:
                     chrec_a = 12
                     chrec_b = {10, +, 1}
                         Perform weak-zero siv test to see if overlap is
                         outside the loop bounds.  
                     When the step does not divide the difference, there are
                     no overlaps.  
                     Example:
                     chrec_a = 12
                     chrec_b = {10, +, -1}

                     In this case, chrec_a will not overlap with chrec_b.  
                     Example:
                     chrec_a = 3
                     chrec_b = {10, +, -1}
                         Perform weak-zero siv test to see if overlap is
                         outside the loop bounds.  
                     When the step does not divide the difference, there
                     are no overlaps.  
                     Example:
                     chrec_a = 3
                     chrec_b = {4, +, 1}

                     In this case, chrec_a will not overlap with chrec_b.  

References conflict_fn_no_dependence(), dependence_stats, and datadep_stats::num_siv_independent.

static void analyze_subscript_affine_affine ( tree  chrec_a,
tree  chrec_b,
conflict_function **  overlaps_a,
conflict_function **  overlaps_b,
tree last_conflicts 
)
static
   Determines the overlapping elements due to accesses CHREC_A and
   CHREC_B, that are affine functions.  This function cannot handle
   symbolic evolution functions, ie. when initial conditions are
   parameters, because it uses lambda matrices of integers.  
         The accessed index overlaps for each iteration in the
         loop.  
     For determining the initial intersection, we have to solve a
     Diophantine equation.  This is the most time consuming part.

     For answering to the question: "Is there a dependence?" we have
     to prove that there exists a solution to the Diophantine
     equation, and that the solution is in the iteration domain,
     i.e. the solution is positive or zero, and that the solution
     happens before the upper bound loop.nb_iterations.  Otherwise
     there is no dependence.  This function outputs a description of
     the iterations that hold the intersections.  
     Don't do all the hard work of solving the Diophantine equation
     when we already know the solution: for example,
     | {3, +, 1}_1
     | {3, +, 4}_2
     | gamma = 3 - 3 = 0.
     Then the first overlap occurs during the first iterations:
     | {3, +, 1}_1 ({0, +, 4}_x) = {3, +, 4}_2 ({0, +, 1}_x)
     U.A = S 
     Something went wrong: for example in {1, +, 0}_5 vs. {0, +, 0}_5,
     but that is a quite strange case.  Instead of ICEing, answer
     don't know.  
     The classic "gcd-test".  
         The "gcd-test" has determined that there is no integer
         solution, i.e. there is no dependence.  
     Both access functions are univariate.  This includes SIV and MIV cases.  
         Both functions should have the same evolution sign.  
             The solutions are given by:
             |
             | [GAMMA/GCD_ALPHA_BETA  t].[u11 u12]  = [x0]
             |                           [u21 u22]    [y0]

             For a given integer t.  Using the following variables,

             | i0 = u11 * gamma / gcd_alpha_beta
             | j0 = u12 * gamma / gcd_alpha_beta
             | i1 = u21
             | j1 = u22

             the solutions are:

             | x0 = i0 + i1 * t,
             | y0 = j0 + j1 * t.  
                 There is no solution.
                 FIXME: The case "i0 > nb_iterations, j0 > nb_iterations"
                 falls in here, but for the moment we don't look at the
                 upper bound of the iteration domain.  
                 (X0, Y0) is a solution of the Diophantine equation:
                 "chrec_a (X0) = chrec_b (Y0)".  
                 (X1, Y1) is the smallest positive solution of the eq
                 "chrec_a (X1) = chrec_b (Y1)", i.e. this is where the
                 first conflict occurs.  
                     If the overlap occurs outside of the bounds of the
                     loop, there is no dependence.  
                 FIXME: For the moment, the upper bound of the
                 iteration domain for i and j is not checked.  

References conflict_fn_no_dependence().

static void analyze_ziv_subscript ( tree  chrec_a,
tree  chrec_b,
conflict_function **  overlaps_a,
conflict_function **  overlaps_b,
tree last_conflicts 
)
static
   Analyze a ZIV (Zero Index Variable) subscript.  *OVERLAPS_A and
   *OVERLAPS_B are initialized to the functions that describe the
   relation between the elements accessed twice by CHREC_A and
   CHREC_B.  For k >= 0, the following property is verified:

   CHREC_A (*OVERLAPS_A (k)) = CHREC_B (*OVERLAPS_B (k)).  
             The difference is equal to zero: the accessed index
             overlaps for each iteration in the loop.  
             The accesses do not overlap.  
         We're not sure whether the indexes overlap.  For the moment,
         conservatively answer "don't know".  

References build_int_cst(), chrec_apply(), chrec_contains_undetermined(), chrec_fold_minus(), chrec_is_positive(), evolution_function_is_affine_p(), get_chrec_loop(), number_of_latch_executions(), and tree_int_cst_sgn().

static void build_classic_dir_vector ( )
static
   Compute the classic per loop direction vector.  DDR is the data
   dependence relation to build a vector from.  
static bool build_classic_dist_vector ( struct data_dependence_relation ddr,
struct loop loop_nest 
)
static
   Compute the classic per loop distance vector.  DDR is the data
   dependence relation to build a vector from.  Return false when fail
   to represent the data dependence as a distance vector.  
         Save the 0 vector.  
     Save the distance vector if we initialized one.  
         Verify a basic constraint: classic distance vectors should
         always be lexicographically positive.

         Data references are collected in the order of execution of
         the program, thus for the following loop

         | for (i = 1; i < 100; i++)
         |   for (j = 1; j < 100; j++)
         |     {
         |       t = T[j+1][i-1];  // A
         |       T[j][i] = t + 2;  // B
         |     }

         references are collected following the direction of the wind:
         A then B.  The data dependence tests are performed also
         following this order, such that we're looking at the distance
         separating the elements accessed by A from the elements later
         accessed by B.  But in this example, the distance returned by
         test_dep (A, B) is lexicographically negative (-1, 1), that
         means that the access A occurs later than B with respect to
         the outer loop, ie. we're actually looking upwind.  In this
         case we solve test_dep (B, A) looking downwind to the
         lexicographically positive solution, that returns the
         distance vector (1, -1).  
             In this case there is a dependence forward for all the
             outer loops:

             | for (k = 1; k < 100; k++)
             |  for (i = 1; i < 100; i++)
             |   for (j = 1; j < 100; j++)
             |     {
             |       t = T[j+1][i-1];  // A
             |       T[j][i] = t + 2;  // B
             |     }

             the vectors are:
             (0,  1, -1)
             (1,  1, -1)
             (1, -1,  1)
         There is a distance of 1 on all the outer loops: Example:
         there is a dependence of distance 1 on loop_1 for the array A.

         | loop_1
         |   A[5] = ...
         | endloop
static bool build_classic_dist_vector_1 ( struct data_dependence_relation ddr,
struct data_reference ddr_a,
struct data_reference ddr_b,
lambda_vector  dist_v,
bool *  init_b,
int *  index_carry 
)
static
   Return false when fail to represent the data dependence as a
   distance vector.  INIT_B is set to true when a component has been
   added to the distance vector DIST_V.  INDEX_CARRY is then set to
   the index in DIST_V that carries the dependence.  
             This is the subscript coupling test.  If we have already
             recorded a distance for this loop (a distance coming from
             another subscript), it should be the same.  For example,
             in the following code, there is no dependence:

             | loop i = 0, N, 1
             |   T[i+1][i] = ...
             |   ... = T[i][i]
             | endloop
             This can be for example an affine vs. constant dependence
             (T[i] vs. T[3]) that is not an affine dependence and is
             not representable as a distance vector.  
static bool can_use_analyze_subscript_affine_affine ( )
static
@verbatim 

Returns true when analyze_subscript_affine_affine can be used for determining the dependence relation between chrec_a and chrec_b, that contain symbols. This function modifies chrec_a and chrec_b such that the analysis result is the same, and such that they don't contain symbols, and then can safely be passed to the analyzer.

Example: The analysis of the following tuples of evolutions produce the same results: {x+1, +, 1}_1 vs. {x+3, +, 1}_1, and {-2, +, 1}_1 vs. {0, +, 1}_1

{x+1, +, 1}_1 ({2, +, 1}_1) = {x+3, +, 1}_1 ({0, +, 1}_1) {-2, +, 1}_1 ({2, +, 1}_1) = {0, +, 1}_1 ({0, +, 1}_1)

       FIXME: For the moment not handled.  Might be refined later.  
static tree canonicalize_base_object_address ( )
static
   Returns the address ADDR of an object in a canonical shape (without nop
   casts, and with type of pointer to the object).  
     The base address may be obtained by casting from integer, in that case
     keep the cast.  
static bool chrec_is_positive ( )
static
   Determine whether the CHREC is always positive/negative.  If the expression
   cannot be statically analyzed, return false, otherwise set the answer into
   VALUE.  
         FIXME -- overflows.  
         Otherwise the chrec is under the form: "{-197, +, 2}_1",
         and the proof consists in showing that the sign never
         changes during the execution of the loop, from 0 to
         loop->nb_iterations.  
         TODO -- If the test is after the exit, we may decrease the number of
         iterations by one.  

References affine_fn_cst(), and conflict_fn().

Referenced by analyze_ziv_subscript().

static affine_fn common_affine_function ( )
static
   If all the functions in CF are the same, returns one of them,
   otherwise returns NULL.  

References signed_type_for().

void compute_affine_dependence ( struct data_dependence_relation ddr,
struct loop loop_nest 
)
   This computes the affine dependence relation between A and B with
   respect to LOOP_NEST.  CHREC_KNOWN is used for representing the
   independence between two accesses, while CHREC_DONT_KNOW is used
   for representing the unknown relation.

   Note that it is possible to stop the computation of the dependence
   relation the first time we detect a CHREC_KNOWN element for a given
   subscript.  
     Analyze only when the dependence relation is not yet known.  
                 Dump the dependences from the first algorithm.  
                     Save the result of the first DD analyzer.  
                     Reset the information.  
                     Compute the same information using Omega.  
                     Check that we get the same information.  
         As a last case, if the dependence cannot be determined, or if
         the dependence is considered too difficult to determine, answer
         "don't know".  

Referenced by ddr_consistent_p().

bool compute_all_dependences ( vec< data_reference_p datarefs,
vec< ddr_p > *  dependence_relations,
vec< loop_p loop_nest,
bool  compute_self_and_rr 
)
   Compute in DEPENDENCE_RELATIONS the data dependence graph for all
   the data references in DATAREFS, in the LOOP_NEST.  When
   COMPUTE_SELF_AND_RR is FALSE, don't compute read-read and self
   relations.  Return true when successful, i.e. data references number
   is small enough to be handled.  
         Insert a single relation into dependence_relations:
         chrec_dont_know.  
bool compute_data_dependences_for_bb ( basic_block  bb,
bool  compute_self_and_read_read_dependences,
vec< data_reference_p > *  datarefs,
vec< ddr_p > *  dependence_relations 
)
   Returns true when the data dependences for the basic block BB have been
   computed, false otherwise.
   DATAREFS is initialized to all the array elements contained in this basic
   block, DEPENDENCE_RELATIONS contains the relations between the data
   references. Compute read-read and self relations if
   COMPUTE_SELF_AND_READ_READ_DEPENDENCES is TRUE.  
bool compute_data_dependences_for_loop ( struct loop loop,
bool  compute_self_and_read_read_dependences,
vec< loop_p > *  loop_nest,
vec< data_reference_p > *  datarefs,
vec< ddr_p > *  dependence_relations 
)
   Returns true when the data dependences have been computed, false otherwise.
   Given a loop nest LOOP, the following vectors are returned:
   DATAREFS is initialized to all the array elements contained in this loop,
   DEPENDENCE_RELATIONS contains the relations between the data references.
   Compute read-read and self relations if
   COMPUTE_SELF_AND_READ_READ_DEPENDENCES is TRUE.  
     If the loop nest is not well formed, or one of the data references
     is not computable, give up without spending time to compute other
     dependences.  
static void compute_overlap_steps_for_affine_1_2 ( tree  chrec_a,
tree  chrec_b,
conflict_function **  overlaps_a,
conflict_function **  overlaps_b,
tree last_conflicts 
)
static
   Solves the special case of a Diophantine equation where CHREC_A is
   an affine bivariate function, and CHREC_B is an affine univariate
   function.  For example,

   | {{0, +, 1}_x, +, 1335}_y = {0, +, 1336}_z

   has the following overlapping functions:

   | x (t, u, v) = {{0, +, 1336}_t, +, 1}_v
   | y (t, u, v) = {{0, +, 1336}_u, +, 1}_v
   | z (t, u, v) = {{{0, +, 1}_t, +, 1335}_u, +, 1}_v

   FORNOW: This is a specialized implementation for a case occurring in
   a common benchmark.  Implement the general algorithm.  
static void compute_overlap_steps_for_affine_univar ( int  niter,
int  step_a,
int  step_b,
affine_fn overlaps_a,
affine_fn overlaps_b,
tree last_conflicts,
int  dim 
)
static
   Solves the special case of the Diophantine equation:
   | {0, +, STEP_A}_x (OVERLAPS_A) = {0, +, STEP_B}_y (OVERLAPS_B)

   Computes the descriptions OVERLAPS_A and OVERLAPS_B.  NITER is the
   number of iterations that loops X and Y run.  The overlaps will be
   constructed as evolutions in dimension DIM.  

Referenced by initialize_matrix_A(), and lambda_vector_equal().

static void compute_subscript_distance ( )
static
   Determine for each subscript in the data dependence relation DDR
   the distance.  

References chrec_contains_symbols_defined_in_loop(), handled_component_p(), and loop::num.

static conflict_function* conflict_fn ( )
static
   Creates a conflict function with N dimensions.  The affine functions
   in each dimension follow.  

Referenced by analyze_miv_subscript(), chrec_is_positive(), and lambda_matrix_row_exchange().

static conflict_function* conflict_fn_no_dependence ( )
static
static conflict_function* conflict_fn_not_known ( )
static
   Returns the conflict function for "unknown".  

References DR_BASE_OBJECT.

Referenced by gcd_of_steps_may_divide_p(), and initialize_matrix_A().

static bool constant_access_functions ( )
static
   Return true when the DDR contains only constant access functions.  

Referenced by add_multivariate_self_dist().

struct data_reference* create_data_ref ( loop_p  nest,
loop_p  loop,
tree  memref,
gimple  stmt,
bool  is_read 
)
read
   Analyzes memory reference MEMREF accessed in STMT.  The reference
   is read if IS_READ is true, write otherwise.  Returns the
   data_reference description of MEMREF.  NEST is the outermost loop
   in which the reference should be instantiated, LOOP is the loop in
   which the data reference should be analyzed.  
static bool ddr_consistent_p ( FILE *  file,
struct data_dependence_relation ddr,
vec< lambda_vector dist_vects,
vec< lambda_vector dir_vects 
)
static
   Return true when DDR contains the same information as that stored
   in DIR_VECTS and in DIST_VECTS, return false otherwise.   
     If dump_file is set, output there.  
         Distance vectors are not ordered in the same way in the DDR
         and in the DIST_VECTS: search for a matching vector.  
         Direction vectors are not ordered in the same way in the DDR
         and in the DIR_VECTS: search for a matching vector.  

References compute_affine_dependence(), DR_IS_WRITE, and initialize_data_dependence_relation().

DEBUG_FUNCTION void debug ( )
   Unified dump into FILE all the data references from DATAREFS.  
   Unified dump function for a DATA_REFERENCE structure.  

References debug.

DEBUG_FUNCTION void debug_data_dependence_relation ( )
   Debug version.  

References dump_data_dependence_relations().

DEBUG_FUNCTION void debug_data_dependence_relations ( )
   Dump to STDERR all the dependence relations from DDRS.  

References DDR_NB_LOOPS, and print_lambda_vector().

DEBUG_FUNCTION void debug_data_reference ( )
   Print to STDERR the data_reference DR.  

References DR_STMT, and print_gimple_stmt().

DEBUG_FUNCTION void debug_data_references ( )
   Dump into STDERR all the data references from DATAREFS.  

References dump_data_reference().

DEBUG_FUNCTION void debug_ddrs ( )
static enum data_dependence_direction dir_from_dist ( )
inlinestatic
   Return the direction for a given distance.
   FIXME: Computing dir this way is suboptimal, since dir can catch
   cases that dist is unable to represent.  

References init_omega_eq_with_af(), and int_cst_value().

static void dr_analyze_alias ( )
static
   Extracts the alias analysis information from the memory reference DR.  
static void dr_analyze_indices ( )
static
   Determines the base object and the list of indices of memory reference
   DR, analyzed in LOOP and instantiated in loop nest NEST.  
     If analyzing a basic-block there are no indices to analyze
     and thus no access functions.  
     REALPART_EXPR and IMAGPART_EXPR can be handled like accesses
     into a two element array with a constant index.  The base is
     then just the immediate underlying object.  
     Analyze access functions of dimensions we know to be independent.  
             For COMPONENT_REFs of records (but not unions!) use the
             FIELD_DECL offset as constant access function so we can
             disambiguate a[i].f1 and a[i].f2.  
           If we have an unhandled component we could not translate
           to an access function stop analyzing.  We have determined
           our base object in this case.  
     If the address operand of a MEM_REF base has an evolution in the
     analyzed nest, add it as an additional independent access-function.  
             Fold the MEM_REF offset into the evolutions initial
             value to make more bases comparable.  
             ???  This is still not a suitable base object for
             dr_may_alias_p - the base object needs to be an
             access that covers the object as whole.  With
             an evolution in the pointer this cannot be
             guaranteed.
             As a band-aid, mark the access so we can special-case
             it in dr_may_alias_p.  
         Canonicalize DR_BASE_OBJECT to MEM_REF form.  

References analyze_scalar_evolution(), component_ref_field_offset(), and instantiate_scev().

bool dr_analyze_innermost ( )
   Analyzes the behavior of the memory reference DR in the innermost loop or
   basic block that contains it.  Returns true if analysis succeed or false
   otherwise.  
bool dr_equal_offsets_p ( struct data_reference dra,
struct data_reference drb 
)
   Check if DRA and DRB have equal offsets.  
static bool dr_equal_offsets_p1 ( )
static
   Check if OFFSET1 and OFFSET2 (DR_OFFSETs of some data-refs) are identical
   expressions.  
bool dr_may_alias_p ( const struct data_reference a,
const struct data_reference b,
bool  loop_nest 
)
   Returns false if we can prove that data references A and B do not alias,
   true otherwise.  If LOOP_NEST is false no cross-iteration aliases are
   considered.  
     If we are not processing a loop nest but scalar code we
     do not need to care about possible cross-iteration dependences
     and thus can process the full original reference.  Do so,
     similar to how loop invariant motion applies extra offset-based
     disambiguation.  
     If we had an evolution in a MEM_REF BASE_OBJECT we do not know
     the size of the base-object.  So we cannot do any offset/overlap
     based analysis but have to rely on points-to information only.  
     Otherwise DR_BASE_OBJECT is an access that covers the whole object
     that is being subsetted in the loop nest.  

Referenced by build_poly_dr().

static void dump_affine_function ( )
static
   Dumps the affine function described by FN to the file OUTF.  
static void dump_conflict_function ( )
static
   Dumps the conflict function CF to the file OUTF.  
static void dump_data_dependence_relation ( FILE *  outf,
struct data_dependence_relation ddr 
)
static
   Dump function for a DATA_DEPENDENCE_RELATION structure.  

Referenced by init_omega_for_ddr().

void dump_data_dependence_relations ( FILE *  file,
vec< ddr_p ddrs 
)
   Dump into FILE all the dependence relations from DDRS.  

Referenced by debug_data_dependence_relation().

void dump_data_reference ( FILE *  outf,
struct data_reference dr 
)
   Dump function for a DATA_REFERENCE structure.  

Referenced by debug_data_references().

static void dump_data_references ( )
static
   Dump into FILE all the data references from DATAREFS.  
static void dump_ddrs ( )
static
   Dumps the data dependence relations DDRS in FILE.  
static void dump_dist_dir_vectors ( )
static
   Dumps the distance and direction vectors in FILE.  DDRS contains
   the dependence relations, and VECT_SIZE is the size of the
   dependence vectors, or in other words the number of loops in the
   considered nest.  
static void dump_subscript ( )
static
   Dump function for a SUBSCRIPT structure.  
static void finalize_ddr_dependent ( struct data_dependence_relation ddr,
tree  chrec 
)
inlinestatic
   Set DDR_ARE_DEPENDENT to CHREC and finalize the subscript overlap
   description.  

References conflict_function::fns, MAX_DIM, and conflict_function::n.

Referenced by analyze_overlapping_iterations().

tree find_data_references_in_bb ( struct loop loop,
basic_block  bb,
vec< data_reference_p > *  datarefs 
)
   Search the data references in LOOP, and record the information into
   DATAREFS.  Returns chrec_dont_know when failing to analyze a
   difficult case, returns NULL_TREE otherwise.  
tree find_data_references_in_loop ( struct loop loop,
vec< data_reference_p > *  datarefs 
)
   Search the data references in LOOP, and record the information into
   DATAREFS.  Returns chrec_dont_know when failing to analyze a
   difficult case, returns NULL_TREE otherwise.

   TODO: This function should be made smarter so that it can handle address
   arithmetic as if they were array accesses, etc.  
bool find_data_references_in_stmt ( struct loop nest,
gimple  stmt,
vec< data_reference_p > *  datarefs 
)
   Stores the data references in STMT to DATAREFS.  If there is an unanalyzable
   reference, returns false, otherwise returns true.  NEST is the outermost
   loop of the loop nest in which the references should be analyzed.  

Referenced by create_rdg_cd_edges().

bool find_loop_nest ( )
   Return false when the LOOP is not well nested.  Otherwise return
   true and insert in LOOP_NEST the loops of the nest.  LOOP_NEST will
   contain the loops from the outermost to the innermost, as they will
   appear in the classic distance vector.  

Referenced by partition_contains_all_rw().

static bool find_loop_nest_1 ( )
static
   Recursive helper function.  
     Inner loops of the nest should not contain siblings.  Example:
     when there are two consecutive loops,

     | loop_0
     |   loop_1
     |     A[{0, +, 1}_1]
     |   endloop_1
     |   loop_2
     |     A[{0, +, 1}_2]
     |   endloop_2
     | endloop_0

     the dependence relation cannot be captured by the distance
     abstraction.  
static void free_conflict_function ( )
static
   Frees memory used by the conflict function F.  

References evolution_function_is_constant_p(), and evolution_function_is_univariate_p().

void free_data_ref ( )
   Frees data reference DR.  
void free_data_refs ( )
   Free the memory used by the data references from DATAREFS.  

Referenced by cond_if_else_store_replacement_1(), stmts_from_loop(), and try_combine_chains().

void free_dependence_relation ( )
   Free the memory used by a data dependence relation DDR.  
void free_dependence_relations ( )
   Free the memory used by the data dependence relations from
   DEPENDENCE_RELATIONS.  

Referenced by try_combine_chains().

static void free_subscripts ( )
static
   Frees memory used by SUBSCRIPTS.  
static bool gcd_of_steps_may_divide_p ( )
static
   Returns false if we can prove that the greatest common divisor of the steps
   of CHREC does not divide CST, false otherwise.  

References chrec_contains_undetermined(), conflict_fn_not_known(), dependence_stats, dump_file, dump_flags, loop::num, datadep_stats::num_subscript_tests, datadep_stats::num_subscript_undetermined, and print_generic_expr().

static bool get_references_in_stmt ( )
static
   Stores the locations of memory references in STMT to REFERENCES.  Returns
   true if STMT clobbers memory, false otherwise.  
     ASM_EXPR and CALL_EXPR may embed arbitrary side effects.
     As we cannot model data-references to not spelled out
     accesses give up if they may occur.  
         Allow IFN_GOMP_SIMD_LANE in their own loops.  
bool graphite_find_data_references_in_stmt ( loop_p  nest,
loop_p  loop,
gimple  stmt,
vec< data_reference_p > *  datarefs 
)
   Stores the data references in STMT to DATAREFS.  If there is an
   unanalyzable reference, returns false, otherwise returns true.
   NEST is the outermost loop of the loop nest in which the references
   should be instantiated, LOOP is the loop in which the references
   should be analyzed.  

Referenced by graphite_can_represent_expr().

static bool init_omega_eq_with_af ( omega_pb  pb,
unsigned  eq,
unsigned int  offset,
tree  access_fun,
struct data_dependence_relation ddr 
)
static
   Initializes an equation for an OMEGA problem using the information
   contained in the ACCESS_FUN.  Returns true when the operation
   succeeded.

   PB is the omega constraint system.
   EQ is the number of the equation to be initialized.
   OFFSET is used for shifting the variables names in the constraints:
   a constrain is composed of 2 * the number of variables surrounding
   dependence accesses.  OFFSET is set either to 0 for the first n variables,
   then it is set to n.
   ACCESS_FUN is expected to be an affine chrec.  
           Compute the innermost loop index.  

Referenced by dir_from_dist().

static bool init_omega_for_ddr ( struct data_dependence_relation ddr,
bool *  maybe_dependent 
)
static
@verbatim 

Sets up the Omega dependence problem for the data dependence relation DDR. Returns false when the constraint system cannot be built, ie. when the test answers "don't know". Returns true otherwise, and when independence has been proved (using one of the trivial dependence test), set MAYBE_DEPENDENT to false, otherwise set MAYBE_DEPENDENT to true.

Example: for setting up the dependence system corresponding to the conflicting accesses

| loop_i | loop_j | A[i, i+1] = ... | ... A[2*j, 2*(i + j)] | endloop_j | endloop_i

the following constraints come from the iteration domain:

0 <= i <= Ni 0 <= i + di <= Ni 0 <= j <= Nj 0 <= j + dj <= Nj

where di, dj are the distance variables. The constraints representing the conflicting elements are:

i = 2 * (j + dj) i + 1 = 2 * (i + di + j + dj)

For asking that the resulting distance vector (di, dj) be lexicographically positive, we insert the constraint "di >= 0". If "di = 0" in the solution, we fix that component to zero, and we look at the inner loops: we set a new problem where all the outer loop distances are zero, and fix this inner component to be positive. When one of the components is positive, we save that distance, and set a new problem where the distance on this loop is zero, searching for other distances in the inner loops. Here is the classic example that illustrates that we have to set for each inner loop a new problem:

| loop_1 | loop_2 | A[10] | endloop_2 | endloop_1

we have to save two distances (1, 0) and (0, 1).

Given two array references, refA and refB, we have to set the dependence problem twice, refA vs. refB and refB vs. refA, and we cannot do a single test, as refB might occur before refA in the inner loops, and the contrary when considering outer loops: ex.

| loop_0 | loop_1 | loop_2 | T[{1,+,1}_2][{1,+,1}_1] // refA | T[{2,+,1}_2][{0,+,1}_1] // refB | endloop_2 | endloop_1 | endloop_0

refB touches the elements in T before refA, and thus for the same loop_0 refB precedes refA: ie. the distance vector (0, 1, -1) but for successive loop_0 iterations, we have (1, -1, 1)

The Omega solver expects the distance variables ("di" in the previous example) to come first in the constraint system (as variables to be protected, or "safe" variables), the constraint system is built using the following layout:

"cst | distance vars | index vars".

         Save the 0 vector.  
         Save the dependences carried by outer loops.  
     Omega expects the protected variables (those that have to be kept
     after elimination) to appear first in the constraint system.
     These variables are the distance variables.  In the following
     initialization we declare NB_LOOPS safe variables, and the total
     number of variables for the constraint system is 2*NB_LOOPS.  
     Stop computation if not decidable, or no dependence.  

References dump_data_dependence_relation(), and dump_file.

static bool init_omega_for_ddr_1 ( struct data_reference dra,
struct data_reference drb,
struct data_dependence_relation ddr,
omega_pb  pb,
bool *  maybe_dependent 
)
static
   Helper function, same as init_omega_for_ddr but specialized for
   data references A and B.  
     Insert an equality per subscript.  
             There is no dependence.  
     Insert inequalities: constraints corresponding to the iteration
     domain, i.e. the loops surrounding the references "loop_x" and
     the distance variables "dx".  The layout of the OMEGA
     representation is as follows:
     - coef[0] is the constant
     - coef[1..nb_loops] are the protected variables that will not be
     removed by the solver: the "dx"
     - coef[nb_loops + 1, 2*nb_loops] are the loop variables: "loop_x".
         0 <= loop_x 
         0 <= loop_x + dx 
             loop_x <= nb_iters 
             loop_x + dx <= nb_iters 
             A step "dx" bigger than nb_iters is not feasible, so
             add "0 <= nb_iters + dx",  
             and "dx <= nb_iters".  

Referenced by omega_setup_subscript().

struct data_dependence_relation* initialize_data_dependence_relation ( struct data_reference a,
struct data_reference b,
vec< loop_p loop_nest 
)
read
   Initialize a data dependence relation between data accesses A and
   B.  NB_LOOPS is the number of loops surrounding the references: the
   size of the classic distance/direction vectors.  
     If the data references do not alias, then they are independent.  
     The case where the references are exactly the same.  
     If the references do not access the same object, we do not know
     whether they alias or not.  
     If the base of the object is not invariant in the loop nest, we cannot
     analyze it.  TODO -- in fact, it would suffice to record that there may
     be arbitrary dependences in the loops where the base object varies.  
     If the number of dimensions of the access to not agree we can have
     a pointer access to a component of the array element type and an
     array access while the base-objects are still the same.  Punt.  

References chrec_dont_know, and DDR_ARE_DEPENDENT.

Referenced by ddr_consistent_p().

static tree initialize_matrix_A ( )
static
   Helper recursive function for initializing the matrix A.  Returns
   the initial value of CHREC.  
           Handle ~X as -1 - X.  

References chrec_dont_know, compute_overlap_steps_for_affine_univar(), conflict_fn_not_known(), dump_file, dump_flags, get_chrec_loop(), HOST_WIDE_INT, int_cst_value(), and max_stmt_executions_int().

static void insert_innermost_unit_dist_vector ( )
static
static bool int_divides_p ( )
inlinestatic
   Returns true iff A divides B.  
static void lambda_matrix_copy ( lambda_matrix  mat1,
lambda_matrix  mat2,
int  m,
int  n 
)
static
   Copy the elements of M x N matrix MAT1 to MAT2.  
static void lambda_matrix_id ( )
static
   Store the N x N identity matrix in MAT.  
static void lambda_matrix_right_hermite ( lambda_matrix  A,
int  m,
int  n,
lambda_matrix  S,
lambda_matrix  U 
)
static
   Given an M x N integer matrix A, this function determines an M x
   M unimodular matrix U, and an M x N echelon matrix S such that
   "U.A = S".  This decomposition is also known as "right Hermite".

   Ref: Algorithm 2.1 page 33 in "Loop Transformations for
   Restructuring Compilers" Utpal Banerjee.  
static void lambda_matrix_row_add ( )
static
   Add a multiple of row R1 of matrix MAT with N columns to row R2:
   R2 = R2 + CONST1 * R1.  
static void lambda_matrix_row_exchange ( )
static
   Swap rows R1 and R2 in matrix MAT.  

References affine_fn_cst(), chrec_dont_know, conflict_fn(), eq_evolutions_p(), HOST_WIDE_INT, and obstack.

static void lambda_matrix_row_negate ( )
static
   Negate row R1 of matrix MAT which has N columns.  
static void lambda_vector_copy ( lambda_vector  vec1,
lambda_vector  vec2,
int  size 
)
static
   Copy the elements of vector VEC1 with length SIZE to VEC2.  
static bool lambda_vector_equal ( )
static
static int lambda_vector_first_nz ( )
static
   Return the first nonzero element of vector VEC1 between START and N.
   We must have START <= N.   Returns N if VEC1 is the zero vector.  
static void lambda_vector_mult_const ( lambda_vector  vec1,
lambda_vector  vec2,
int  size,
int  const1 
)
static
   Multiply vector VEC1 of length SIZE by a constant CONST1,
   and store the result in VEC2.  
static void lambda_vector_negate ( lambda_vector  vec1,
lambda_vector  vec2,
int  size 
)
static
   Negate vector VEC1 with length SIZE and store it in VEC2.  
static tree max_stmt_executions_tree ( )
static
   Similar to max_stmt_executions_int, but returns the bound as a tree,
   and only if it fits to the int type.  If this is not the case, or the
   bound  on the number of iterations of LOOP could not be derived, returns
   chrec_dont_know.  

References chrec_convert(), chrec_fold_minus(), initial_condition(), signed_type_for_types(), and type().

static void non_affine_dependence_relation ( )
inlinestatic
   The dependence relation DDR cannot be represented by a distance
   vector.  

Referenced by analyze_overlapping_iterations().

static bool object_address_invariant_in_loop_p ( )
static
   Returns true if the address of OBJ is invariant in LOOP.  
             Index of the ARRAY_REF was zeroed in analyze_indices, thus we only
             need to check the stride and the lower bound of the reference.  

References DR_UNCONSTRAINED_BASE, and ptr_derefs_may_alias_p().

static void omega_extract_distance_vectors ( omega_pb  pb,
struct data_dependence_relation ddr 
)
static
   As explained in the comments preceding init_omega_for_ddr, we have
   to set up a system for each loop level, setting outer loops
   variation to zero, and current loop variation to positive or zero.
   Save each lexico positive distance vector.  
     Set a new problem for each loop in the nest.  The basis is the
     problem that we have initialized until now.  On top of this we
     add new constraints.  
         For all the outer loops "loop_j", add "dj = 0".  
         For "loop_i", add "0 <= di".  
         Reduce the constraint system, and test that the current
         problem is feasible.  
             Reinitialize problem...  
             ..., but this time "di = 1".  
         Save the lexicographically positive distance vector.  

References chrec_known, and DDR_ARE_DEPENDENT.

static bool omega_setup_subscript ( tree  access_fun_a,
tree  access_fun_b,
struct data_dependence_relation ddr,
omega_pb  pb,
bool *  maybe_dependent 
)
static
   This is called for each subscript of a tuple of data references:
   insert an equality for representing the conflicts.  
     When the fun_a - fun_b is not constant, the dependence is not
     captured by the classic distance vector representation.  
     ZIV test.  
         There is no dependence.  
       There is probably a dependence, but the system of
       constraints cannot be built: answer "don't know".  
     GCD test.  
         There is no dependence.  

References DDR_A, DDR_B, DDR_NB_LOOPS, dir_equal, init_omega_for_ddr_1(), lambda_vector_new(), omega_alloc_problem(), omega_free_problem(), same_access_functions(), save_dir_v(), and save_dist_v().

static void print_dir_vectors ( FILE *  outf,
vec< lambda_vector dir_vects,
int  length 
)
static
   Print a vector of direction vectors.  
static void print_direction_vector ( FILE *  outf,
lambda_vector  dirv,
int  length 
)
static
   Print the classic direction vector DIRV to OUTF.  
static void print_dist_vectors ( FILE *  outf,
vec< lambda_vector dist_vects,
int  length 
)
static
   Print a vector of distance vectors.  
static void print_lambda_vector ( )
inlinestatic
   Print out a vector VEC of length N to OUTFILE.  

Referenced by debug_data_dependence_relations().

static void save_dir_v ( )
static
   Helper function for uniquely inserting direction vectors.  

References DDR_AFFINE_P.

Referenced by omega_setup_subscript().

static void save_dist_v ( )
static
   Helper function for uniquely inserting distance vectors.  

Referenced by add_multivariate_self_dist(), and omega_setup_subscript().

static tree signed_type_for_types ( )
static
   Returns a signed integer type with the largest precision from TA
   and TB.  

Referenced by max_stmt_executions_tree().

static bool siv_subscript_p ( )
static
   Returns true iff CHREC_A and CHREC_B are dependent on an index
   variable, i.e., if the SIV (Single Index Variable) test is true.  
void split_constant_offset ( )
   Expresses EXP as VAR + OFF, where off is a constant.  The type of OFF
   will be ssizetype.  

Referenced by debug_ddrs().

static bool split_constant_offset_1 ( tree  type,
tree  op0,
enum tree_code  code,
tree  op1,
tree var,
tree off 
)
static
   Helper function for split_constant_offset.  Expresses OP0 CODE OP1
   (the type of the result is TYPE) as VAR + OFF, where OFF is a nonzero
   constant of type ssizetype, and returns true.  If we cannot do this
   with OFF nonzero, OFF and VAR are set to NULL_TREE instead and false
   is returned.  
         FALLTHROUGH 
           If variable length types are involved, punt, otherwise casts
           might be converted into ARRAY_REFs in gimplify_conversion.
           To compute that ARRAY_REF's element size TYPE_SIZE_UNIT, which
           possibly no longer appears in current GIMPLE, might resurface.
           This perhaps could run
           if (CONVERT_EXPR_P (var0))
             {
               gimplify_conversion (&var0);
               // Attempt to fill in any within var0 found ARRAY_REF's
               // element size from corresponding op embedded ARRAY_REF,
               // if unsuccessful, just punt.
             }  
           We must not introduce undefined overflow, and we must not change the value.
           Hence we're okay if the inner type doesn't overflow to start with
           (pointer or signed), the outer type also is an integer or pointer
           and the outer precision is at least as large as the inner.  
static void subscript_dependence_tester ( struct data_dependence_relation ddr,
struct loop loop_nest 
)
static
   Computes the conflicting iterations in LOOP_NEST, and initialize DDR.  
static bool subscript_dependence_tester_1 ( struct data_dependence_relation ddr,
struct data_reference dra,
struct data_reference drb,
struct loop loop_nest 
)
static
   Helper function.  Returns true when there is a dependence between
   data references DRA and DRB.  
         If there is any undetermined conflict function we have to
         give a conservative answer in case we cannot prove that
         no dependence exists when analyzing another subscript.  
         When there is a subscript with no dependence we can stop.  

References eqn_d::coef, copy(), DDR_LOOP_NEST, DDR_NB_LOOPS, omega_pb_d::eqs, omega_pb_d::geqs, eqn_d::key, omega_pb_d::num_geqs, omega_pb_d::num_subs, omega_add_zero_eq(), omega_add_zero_geq(), omega_alloc_problem(), omega_black, omega_copy_problem(), omega_false, omega_simplify_problem(), omega_unknown, and omega_pb_d::subs.

void tree_check_data_deps ( void  )
   Computes all the data dependences and check that the results of
   several analyzers are the same.  

Referenced by make_pass_vectorize().

static bool tree_fold_divides_p ( )
inlinestatic
   Returns true iff A divides B.  
static bool ziv_subscript_p ( )
inlinestatic
   This section contains the classic Banerjee tests.  
   Returns true iff CHREC_A and CHREC_B are not dependent on any index
   variables, i.e., if the ZIV (Zero Index Variable) test is true.  

Variable Documentation