fix pr46851 and pr60340: remove unmaintained omega dependence test

Regstrapped on amd64-linux.

2015-07-18  Sebastian Pop  <s.pop@samsung.com>

	PR middle-end/46851
	PR middle-end/60340
	* Makefile.in: Removed omega.o.
	* common.opt: Remove flag fcheck-data-deps.
	* doc/invoke.texi: Remove documentation for fcheck-data-deps and
	its associated params: omega-max-vars, omega-max-geqs,
	omega-max-eqs, omega-max-wild-cards, omega-hash-table-size,
	omega-max-keys, omega-eliminate-redundant-constraints.
	* doc/loop.texi: Remove all the section on Omega.
	* graphite-blocking.c: Include missing params.h: it used to be
	included through tree-data-ref.h and omega.h.
	* graphite-isl-ast-to-gimple.c: Same.
	* graphite-optimize-isl.c: Same.
	* graphite-sese-to-poly.c: Same.
	* graphite.c: Same.
	* omega.c: Remove.
	* omega.h: Remove.
	* params.def: Removed PARAM_OMEGA_MAX_VARS, PARAM_OMEGA_MAX_GEQS,
	PARAM_OMEGA_MAX_EQS, PARAM_OMEGA_MAX_WILD_CARDS,
	PARAM_OMEGA_HASH_TABLE_SIZE, PARAM_OMEGA_MAX_KEYS, and
	PARAM_OMEGA_ELIMINATE_REDUNDANT_CONSTRAINTS.
	* passes.def: Remove pass_check_data_deps.
	* tree-data-ref.c (dump_affine_function): Declare DEBUG_FUNCTION.
	(dump_conflict_function): Same.
	(dump_subscript): Same.
	(print_direction_vector): Same.
	(print_dir_vectors): Same.
	(print_lambda_vector): Same.
	(print_dist_vectors): Same.
	(dump_data_dependence_relation): Same.
	(dump_data_dependence_relations): Same.
	(dump_dist_dir_vectors): Same.
	(dump_ddrs): Same.
	(init_omega_eq_with_af): Removed.
	(omega_extract_distance_vectors): Removed.
	(omega_setup_subscript): Removed.
	(init_omega_for_ddr_1): Removed.
	(init_omega_for_ddr): Removed.
	(ddr_consistent_p): Removed.
	(compute_affine_dependence): Do not use omega to check data
	dependences.
	(compute_data_dependences_for_bb): Removed.
	(analyze_all_data_dependences): Removed.
	(tree_check_data_deps): Removed.
	* tree-data-ref.h: Do not include omega.h.
	(compute_data_dependences_for_bb): Removed.
	(tree_check_data_deps): Removed.
	* tree-ssa-loop.c (pass_check_data_deps): Removed.
	(make_pass_check_data_deps): Removed.
	* tree-ssa-phiopt.c: Include params.h.
	* tree-vect-data-refs.c: Same.
	* tree-vect-slp.c: Same.

testsuite/
	* gcc.dg/tree-ssa/pr42327.c: Removed.
	* g++.dg/other/pr35011.C: Removed.

From-SVN: r225979
This commit is contained in:
Sebastian Pop 2015-07-18 01:11:05 +00:00 committed by Sebastian Pop
parent ca4b5dbd8a
commit 49b8fe6c1a
23 changed files with 84 additions and 6738 deletions

View File

@ -1,3 +1,58 @@
2015-07-18 Sebastian Pop <s.pop@samsung.com>
PR middle-end/46851
PR middle-end/60340
* Makefile.in: Removed omega.o.
* common.opt: Document flag fcheck-data-deps as deprecated.
* doc/invoke.texi: Remove documentation for fcheck-data-deps and
its associated params: omega-max-vars, omega-max-geqs,
omega-max-eqs, omega-max-wild-cards, omega-hash-table-size,
omega-max-keys, omega-eliminate-redundant-constraints.
* doc/loop.texi: Remove all the section on Omega.
* graphite-blocking.c: Include missing params.h: it used to be
included through tree-data-ref.h and omega.h.
* graphite-isl-ast-to-gimple.c: Same.
* graphite-optimize-isl.c: Same.
* graphite-sese-to-poly.c: Same.
* graphite.c: Same.
* omega.c: Remove.
* omega.h: Remove.
* params.def: Removed PARAM_OMEGA_MAX_VARS, PARAM_OMEGA_MAX_GEQS,
PARAM_OMEGA_MAX_EQS, PARAM_OMEGA_MAX_WILD_CARDS,
PARAM_OMEGA_HASH_TABLE_SIZE, PARAM_OMEGA_MAX_KEYS, and
PARAM_OMEGA_ELIMINATE_REDUNDANT_CONSTRAINTS.
* passes.def: Remove pass_check_data_deps.
* tree-data-ref.c (dump_affine_function): Declare DEBUG_FUNCTION.
(dump_conflict_function): Same.
(dump_subscript): Same.
(print_direction_vector): Same.
(print_dir_vectors): Same.
(print_lambda_vector): Same.
(print_dist_vectors): Same.
(dump_data_dependence_relation): Same.
(dump_data_dependence_relations): Same.
(dump_dist_dir_vectors): Same.
(dump_ddrs): Same.
(init_omega_eq_with_af): Removed.
(omega_extract_distance_vectors): Removed.
(omega_setup_subscript): Removed.
(init_omega_for_ddr_1): Removed.
(init_omega_for_ddr): Removed.
(ddr_consistent_p): Removed.
(compute_affine_dependence): Do not use omega to check data
dependences.
(compute_data_dependences_for_bb): Removed.
(analyze_all_data_dependences): Removed.
(tree_check_data_deps): Removed.
* tree-data-ref.h: Do not include omega.h.
(compute_data_dependences_for_bb): Removed.
(tree_check_data_deps): Removed.
* tree-ssa-loop.c (pass_check_data_deps): Removed.
(make_pass_check_data_deps): Removed.
* tree-ssa-phiopt.c: Include params.h.
* tree-vect-data-refs.c: Same.
* tree-vect-slp.c: Same.
2015-07-18 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (pushsf splitter): Pass curr_insn to

View File

@ -1347,7 +1347,6 @@ OBJS = \
mcf.o \
mode-switching.o \
modulo-sched.o \
omega.o \
omp-low.o \
optabs.o \
options-save.o \

View File

@ -987,7 +987,7 @@ Save registers around function calls
fcheck-data-deps
Common Report Var(flag_check_data_deps)
Compare the results of several data dependence analyzers.
This switch is deprecated; do not use.
fcheck-new
Common Var(flag_check_new)

View File

@ -385,7 +385,7 @@ Objective-C and Objective-C++ Dialects}.
-fauto-inc-dec -fbranch-probabilities @gol
-fbranch-target-load-optimize -fbranch-target-load-optimize2 @gol
-fbtr-bb-exclusive -fcaller-saves @gol
-fcheck-data-deps -fcombine-stack-adjustments -fconserve-stack @gol
-fcombine-stack-adjustments -fconserve-stack @gol
-fcompare-elim -fcprop-registers -fcrossjumping @gol
-fcse-follow-jumps -fcse-skip-blocks -fcx-fortran-rules @gol
-fcx-limited-range @gol
@ -8812,11 +8812,6 @@ be parallelized. Parallelize all the loops that can be analyzed to
not contain loop carried dependences without checking that it is
profitable to parallelize the loops.
@item -fcheck-data-deps
@opindex fcheck-data-deps
Compare the results of several data dependence analyzers. This option
is used for debugging the data dependence analyzers.
@item -ftree-loop-if-convert
@opindex ftree-loop-if-convert
Attempt to transform conditional jumps in the innermost loops to
@ -10475,34 +10470,6 @@ Large expressions slow the analyzer.
Bound on the complexity of the expressions in the scalar evolutions analyzer.
Complex expressions slow the analyzer.
@item omega-max-vars
The maximum number of variables in an Omega constraint system.
The default value is 128.
@item omega-max-geqs
The maximum number of inequalities in an Omega constraint system.
The default value is 256.
@item omega-max-eqs
The maximum number of equalities in an Omega constraint system.
The default value is 128.
@item omega-max-wild-cards
The maximum number of wildcard variables that the Omega solver is
able to insert. The default value is 18.
@item omega-hash-table-size
The size of the hash table in the Omega solver. The default value is
550.
@item omega-max-keys
The maximal number of keys used by the Omega solver. The default
value is 500.
@item omega-eliminate-redundant-constraints
When set to 1, use expensive methods to eliminate all redundant
constraints. The default value is 0.
@item vect-max-version-for-alignment-checks
The maximum number of run-time checks that can be performed when
doing loop versioning for alignment in the vectorizer.

View File

@ -25,7 +25,6 @@ variable analysis and number of iterations analysis).
* loop-iv:: Induction variables on RTL.
* Number of iterations:: Number of iterations analysis.
* Dependency analysis:: Data dependency analysis.
* Omega:: A solver for linear programming problems.
@end menu
@node Loop representation
@ -602,33 +601,3 @@ maximum verbosity the details of a data dependence relations array,
direction vectors for a data dependence relations array, and
@code{dump_data_references} prints the details of the data references
contained in a data reference array.
@node Omega
@section Omega a solver for linear programming problems
@cindex Omega a solver for linear programming problems
The data dependence analysis contains several solvers triggered
sequentially from the less complex ones to the more sophisticated.
For ensuring the consistency of the results of these solvers, a data
dependence check pass has been implemented based on two different
solvers. The second method that has been integrated to GCC is based
on the Omega dependence solver, written in the 1990's by William Pugh
and David Wonnacott. Data dependence tests can be formulated using a
subset of the Presburger arithmetics that can be translated to linear
constraint systems. These linear constraint systems can then be
solved using the Omega solver.
The Omega solver is using Fourier-Motzkin's algorithm for variable
elimination: a linear constraint system containing @code{n} variables
is reduced to a linear constraint system with @code{n-1} variables.
The Omega solver can also be used for solving other problems that can
be expressed under the form of a system of linear equalities and
inequalities. The Omega solver is known to have an exponential worst
case, also known under the name of ``omega nightmare'' in the
literature, but in practice, the omega test is known to be efficient
for the common data dependence tests.
The interface used by the Omega solver for describing the linear
programming problems is described in @file{omega.h}, and the solver is
@code{omega_solve_problem}.

View File

@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfghooks.h"
#include "tree.h"
#include "gimple.h"
#include "params.h"
#include "fold-const.h"
#include "gimple-iterator.h"
#include "tree-ssa-loop.h"

View File

@ -44,6 +44,7 @@ extern "C" {
#include "cfghooks.h"
#include "tree.h"
#include "gimple.h"
#include "params.h"
#include "fold-const.h"
#include "gimple-iterator.h"
#include "tree-ssa-loop.h"

View File

@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfgloop.h"
#include "tree-data-ref.h"
#include "graphite-poly.h"
#include "params.h"
static isl_union_set *
scop_get_domains (scop_p scop ATTRIBUTE_UNUSED)

View File

@ -47,6 +47,7 @@ extern "C" {
#include "tree.h"
#include "gimple.h"
#include "ssa.h"
#include "params.h"
#include "fold-const.h"
#include "gimple-iterator.h"
#include "gimplify.h"

View File

@ -50,6 +50,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic-core.h"
#include "cfgloop.h"
#include "tree-pass.h"
#include "params.h"
#ifdef HAVE_isl
#include "cfghooks.h"

File diff suppressed because it is too large Load Diff

View File

@ -1,341 +0,0 @@
/* Source code for an implementation of the Omega test, an integer
programming algorithm for dependence analysis, by William Pugh,
appeared in Supercomputing '91 and CACM Aug 92.
This code has no license restrictions, and is considered public
domain.
Changes copyright (C) 2005-2015 Free Software Foundation, Inc.
Contributed by Sebastian Pop <sebastian.pop@inria.fr>
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_OMEGA_H
#define GCC_OMEGA_H
#include "params.h"
#define OMEGA_MAX_VARS PARAM_VALUE (PARAM_OMEGA_MAX_VARS)
#define OMEGA_MAX_GEQS PARAM_VALUE (PARAM_OMEGA_MAX_GEQS)
#define OMEGA_MAX_EQS PARAM_VALUE (PARAM_OMEGA_MAX_EQS)
#define pos_infinity (0x7ffffff)
#define neg_infinity (-0x7ffffff)
/* Results of the Omega solver. */
enum omega_result {
omega_false = 0,
omega_true = 1,
/* Value returned when the solver is unable to determine an
answer. */
omega_unknown = 2,
/* Value used for asking the solver to simplify the system. */
omega_simplify = 3
};
/* Values used for labeling equations. Private (not used outside the
solver). */
enum omega_eqn_color {
omega_black = 0,
omega_red = 1
};
/* Structure for equations. */
typedef struct eqn_d
{
int key;
int touched;
enum omega_eqn_color color;
/* Array of coefficients for the equation. The layout of the data
is as follows: coef[0] is the constant, coef[i] for 1 <= i <=
OMEGA_MAX_VARS, are the coefficients for each dimension. Examples:
the equation 0 = 9 + x + 0y + 5z is encoded as [9 1 0 5], the
inequality 0 <= -8 + x + 2y + 3z is encoded as [-8 1 2 3]. */
int *coef;
} *eqn;
typedef struct omega_pb_d
{
/* The number of variables in the system of equations. */
int num_vars;
/* Safe variables are not eliminated during the Fourier-Motzkin
simplification of the system. Safe variables are all those
variables that are placed at the beginning of the array of
variables: PB->var[1, ..., SAFE_VARS]. PB->var[0] is not used,
as PB->eqs[x]->coef[0] represents the constant of the equation. */
int safe_vars;
/* Number of elements in eqs[]. */
int num_eqs;
/* Number of elements in geqs[]. */
int num_geqs;
/* Number of elements in subs[]. */
int num_subs;
int hash_version;
bool variables_initialized;
bool variables_freed;
/* Index or name of variables. Negative integers are reserved for
wildcard variables. Maps the index of variables in the original
problem to the new index of the variable. The index for a
variable in the coef array of an equation can change as some
variables are eliminated. */
int *var;
int *forwarding_address;
/* Inequalities in the system of constraints. */
eqn geqs;
/* Equations in the system of constraints. */
eqn eqs;
/* A map of substituted variables. */
eqn subs;
} *omega_pb;
extern void omega_initialize (void);
extern omega_pb omega_alloc_problem (int, int);
extern enum omega_result omega_solve_problem (omega_pb, enum omega_result);
extern enum omega_result omega_simplify_problem (omega_pb);
extern enum omega_result omega_simplify_approximate (omega_pb);
extern enum omega_result omega_constrain_variable_sign (omega_pb,
enum omega_eqn_color,
int, int);
extern void debug (omega_pb_d &ref);
extern void debug (omega_pb_d *ptr);
extern void debug_omega_problem (omega_pb);
extern void omega_print_problem (FILE *, omega_pb);
extern void omega_print_red_equations (FILE *, omega_pb);
extern int omega_count_red_equations (omega_pb);
extern void omega_pretty_print_problem (FILE *, omega_pb);
extern void omega_unprotect_variable (omega_pb, int var);
extern void omega_negate_geq (omega_pb, int);
extern void omega_convert_eq_to_geqs (omega_pb, int eq);
extern void omega_print_eqn (FILE *, omega_pb, eqn, bool, int);
extern bool omega_problem_has_red_equations (omega_pb);
extern enum omega_result omega_eliminate_redundant (omega_pb, bool);
extern void omega_eliminate_red (omega_pb, bool);
extern void omega_constrain_variable_value (omega_pb, enum omega_eqn_color,
int, int);
extern bool omega_query_variable (omega_pb, int, int *, int *);
extern int omega_query_variable_signs (omega_pb, int, int, int, int,
int, int, bool *, int *);
extern bool omega_query_variable_bounds (omega_pb, int, int *, int *);
extern void (*omega_when_reduced) (omega_pb);
extern void omega_no_procedure (omega_pb);
/* Return true when variable I in problem PB is a wildcard. */
static inline bool
omega_wildcard_p (omega_pb pb, int i)
{
return (pb->var[i] < 0);
}
/* Return true when variable I in problem PB is a safe variable. */
static inline bool
omega_safe_var_p (omega_pb pb, int i)
{
/* The constant of an equation is not a variable. */
gcc_assert (0 < i);
return (i <= pb->safe_vars);
}
/* Print to FILE equality E from PB. */
static inline void
omega_print_eq (FILE *file, omega_pb pb, eqn e)
{
omega_print_eqn (file, pb, e, false, 0);
}
/* Print to FILE inequality E from PB. */
static inline void
omega_print_geq (FILE *file, omega_pb pb, eqn e)
{
omega_print_eqn (file, pb, e, true, 0);
}
/* Print to FILE inequality E from PB. */
static inline void
omega_print_geq_extra (FILE *file, omega_pb pb, eqn e)
{
omega_print_eqn (file, pb, e, true, 1);
}
/* E1 = E2, make a copy of E2 into E1. Equations contain S variables. */
static inline void
omega_copy_eqn (eqn e1, eqn e2, int s)
{
e1->key = e2->key;
e1->touched = e2->touched;
e1->color = e2->color;
memcpy (e1->coef, e2->coef, (s + 1) * sizeof (int));
}
/* Initialize E = 0. Equation E contains S variables. */
static inline void
omega_init_eqn_zero (eqn e, int s)
{
e->key = 0;
e->touched = 0;
e->color = omega_black;
memset (e->coef, 0, (s + 1) * sizeof (int));
}
/* Allocate N equations with S variables. */
static inline eqn
omega_alloc_eqns (int s, int n)
{
int i;
eqn res = (eqn) (xcalloc (n, sizeof (struct eqn_d)));
for (i = n - 1; i >= 0; i--)
{
res[i].coef = (int *) (xcalloc (OMEGA_MAX_VARS + 1, sizeof (int)));
omega_init_eqn_zero (&res[i], s);
}
return res;
}
/* Free N equations from array EQ. */
static inline void
omega_free_eqns (eqn eq, int n)
{
int i;
for (i = n - 1; i >= 0; i--)
free (eq[i].coef);
free (eq);
}
/* Returns true when E is an inequality with a single variable. */
static inline bool
single_var_geq (eqn e, int nv ATTRIBUTE_UNUSED)
{
return (e->key != 0
&& -OMEGA_MAX_VARS <= e->key && e->key <= OMEGA_MAX_VARS);
}
/* Allocate a new equality with all coefficients 0, and tagged with
COLOR. Return the index of this equality in problem PB. */
static inline int
omega_add_zero_eq (omega_pb pb, enum omega_eqn_color color)
{
int idx = pb->num_eqs++;
gcc_assert (pb->num_eqs <= OMEGA_MAX_EQS);
omega_init_eqn_zero (&pb->eqs[idx], pb->num_vars);
pb->eqs[idx].color = color;
return idx;
}
/* Allocate a new inequality with all coefficients 0, and tagged with
COLOR. Return the index of this inequality in problem PB. */
static inline int
omega_add_zero_geq (omega_pb pb, enum omega_eqn_color color)
{
int idx = pb->num_geqs;
pb->num_geqs++;
gcc_assert (pb->num_geqs <= OMEGA_MAX_GEQS);
omega_init_eqn_zero (&pb->geqs[idx], pb->num_vars);
pb->geqs[idx].touched = 1;
pb->geqs[idx].color = color;
return idx;
}
/* Initialize variables for problem PB. */
static inline void
omega_initialize_variables (omega_pb pb)
{
int i;
for (i = pb->num_vars; i >= 0; i--)
pb->forwarding_address[i] = pb->var[i] = i;
pb->variables_initialized = true;
}
/* Free problem PB. */
static inline void
omega_free_problem (omega_pb pb)
{
free (pb->var);
free (pb->forwarding_address);
omega_free_eqns (pb->geqs, OMEGA_MAX_GEQS);
omega_free_eqns (pb->eqs, OMEGA_MAX_EQS);
omega_free_eqns (pb->subs, OMEGA_MAX_VARS + 1);
free (pb);
}
/* Copy omega problems: P1 = P2. */
static inline void
omega_copy_problem (omega_pb p1, omega_pb p2)
{
int e, i;
p1->num_vars = p2->num_vars;
p1->hash_version = p2->hash_version;
p1->variables_initialized = p2->variables_initialized;
p1->variables_freed = p2->variables_freed;
p1->safe_vars = p2->safe_vars;
p1->num_eqs = p2->num_eqs;
p1->num_subs = p2->num_subs;
p1->num_geqs = p2->num_geqs;
for (e = p2->num_eqs - 1; e >= 0; e--)
omega_copy_eqn (&(p1->eqs[e]), &(p2->eqs[e]), p2->num_vars);
for (e = p2->num_geqs - 1; e >= 0; e--)
omega_copy_eqn (&(p1->geqs[e]), &(p2->geqs[e]), p2->num_vars);
for (e = p2->num_subs - 1; e >= 0; e--)
omega_copy_eqn (&(p1->subs[e]), &(p2->subs[e]), p2->num_vars);
for (i = p2->num_vars; i >= 0; i--)
p1->var[i] = p2->var[i];
for (i = OMEGA_MAX_VARS; i >= 0; i--)
p1->forwarding_address[i] = p2->forwarding_address[i];
}
#endif /* GCC_OMEGA_H */

View File

@ -525,41 +525,6 @@ DEFPARAM(PARAM_SCEV_MAX_EXPR_COMPLEXITY,
"Bound on the complexity of the expressions in the scalar evolutions analyzer",
10, 0, 0)
DEFPARAM(PARAM_OMEGA_MAX_VARS,
"omega-max-vars",
"Bound on the number of variables in Omega constraint systems",
128, 0, 0)
DEFPARAM(PARAM_OMEGA_MAX_GEQS,
"omega-max-geqs",
"Bound on the number of inequalities in Omega constraint systems",
256, 0, 0)
DEFPARAM(PARAM_OMEGA_MAX_EQS,
"omega-max-eqs",
"Bound on the number of equalities in Omega constraint systems",
128, 0, 0)
DEFPARAM(PARAM_OMEGA_MAX_WILD_CARDS,
"omega-max-wild-cards",
"Bound on the number of wild cards in Omega constraint systems",
18, 0, 0)
DEFPARAM(PARAM_OMEGA_HASH_TABLE_SIZE,
"omega-hash-table-size",
"Bound on the size of the hash table in Omega constraint systems",
550, 0, 0)
DEFPARAM(PARAM_OMEGA_MAX_KEYS,
"omega-max-keys",
"Bound on the number of keys in Omega constraint systems",
500, 0, 0)
DEFPARAM(PARAM_OMEGA_ELIMINATE_REDUNDANT_CONSTRAINTS,
"omega-eliminate-redundant-constraints",
"When set to 1, use expensive methods to eliminate all redundant constraints",
0, 0, 1)
DEFPARAM(PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS,
"vect-max-version-for-alignment-checks",
"Bound on number of runtime checks inserted by the vectorizer's loop versioning for alignment check",

View File

@ -233,7 +233,6 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_tree_unswitch);
NEXT_PASS (pass_scev_cprop);
NEXT_PASS (pass_record_bounds);
NEXT_PASS (pass_check_data_deps);
NEXT_PASS (pass_loop_distribution);
NEXT_PASS (pass_copy_prop);
NEXT_PASS (pass_graphite);

View File

@ -1,3 +1,10 @@
2015-07-18 Sebastian Pop <s.pop@samsung.com>
PR middle-end/46851
PR middle-end/60340
* gcc.dg/tree-ssa/pr42327.c: Removed.
* g++.dg/other/pr35011.C: Removed.
2015-07-17 H.J. Lu <hongjiu.lu@intel.com>
PR target/66906

View File

@ -1,26 +0,0 @@
// { dg-do compile }
// { dg-options "-O3 -fcheck-data-deps" }
double foo(const double* p0, const double* p1, const double* q0)
{
double d;
for (; p0 != p1; ++p0, ++q0)
d += *p0 * *q0;
return d;
}
struct A
{
double x[3];
const double* begin() const { return x; }
};
struct B
{
A a0, a1;
double d;
B(const A&);
};
B::B(const A& a) : a0(a), a1(a), d(foo(a0.begin(), a0.begin()+3, a1.begin()))
{}

View File

@ -1,7 +0,0 @@
/* { dg-do compile } */
/* { dg-options "-O1 -fcheck-data-deps" } */
void foo(char *str)
{
while (*str != 0) *str++ = 0;
}

View File

@ -249,7 +249,7 @@ debug (data_reference *ptr)
/* Dumps the affine function described by FN to the file OUTF. */
static void
DEBUG_FUNCTION void
dump_affine_function (FILE *outf, affine_fn fn)
{
unsigned i;
@ -266,7 +266,7 @@ dump_affine_function (FILE *outf, affine_fn fn)
/* Dumps the conflict function CF to the file OUTF. */
static void
DEBUG_FUNCTION void
dump_conflict_function (FILE *outf, conflict_function *cf)
{
unsigned i;
@ -290,7 +290,7 @@ dump_conflict_function (FILE *outf, conflict_function *cf)
/* Dump function for a SUBSCRIPT structure. */
static void
DEBUG_FUNCTION void
dump_subscript (FILE *outf, struct subscript *subscript)
{
conflict_function *cf = SUB_CONFLICTS_IN_A (subscript);
@ -322,7 +322,7 @@ dump_subscript (FILE *outf, struct subscript *subscript)
/* Print the classic direction vector DIRV to OUTF. */
static void
DEBUG_FUNCTION void
print_direction_vector (FILE *outf,
lambda_vector dirv,
int length)
@ -367,7 +367,7 @@ print_direction_vector (FILE *outf,
/* Print a vector of direction vectors. */
static void
DEBUG_FUNCTION void
print_dir_vectors (FILE *outf, vec<lambda_vector> dir_vects,
int length)
{
@ -380,7 +380,7 @@ print_dir_vectors (FILE *outf, vec<lambda_vector> dir_vects,
/* Print out a vector VEC of length N to OUTFILE. */
static inline void
DEBUG_FUNCTION void
print_lambda_vector (FILE * outfile, lambda_vector vector, int n)
{
int i;
@ -392,7 +392,7 @@ print_lambda_vector (FILE * outfile, lambda_vector vector, int n)
/* Print a vector of distance vectors. */
static void
DEBUG_FUNCTION void
print_dist_vectors (FILE *outf, vec<lambda_vector> dist_vects,
int length)
{
@ -405,7 +405,7 @@ print_dist_vectors (FILE *outf, vec<lambda_vector> dist_vects,
/* Dump function for a DATA_DEPENDENCE_RELATION structure. */
static void
DEBUG_FUNCTION void
dump_data_dependence_relation (FILE *outf,
struct data_dependence_relation *ddr)
{
@ -488,7 +488,7 @@ debug_data_dependence_relation (struct data_dependence_relation *ddr)
/* Dump into FILE all the dependence relations from DDRS. */
void
DEBUG_FUNCTION void
dump_data_dependence_relations (FILE *file,
vec<ddr_p> ddrs)
{
@ -528,7 +528,7 @@ debug_data_dependence_relations (vec<ddr_p> ddrs)
dependence vectors, or in other words the number of loops in the
considered nest. */
static void
DEBUG_FUNCTION void
dump_dist_dir_vectors (FILE *file, vec<ddr_p> ddrs)
{
unsigned int i, j;
@ -558,7 +558,7 @@ dump_dist_dir_vectors (FILE *file, vec<ddr_p> ddrs)
/* Dumps the data dependence relations DDRS in FILE. */
static void
DEBUG_FUNCTION void
dump_ddrs (FILE *file, vec<ddr_p> ddrs)
{
unsigned int i;
@ -3682,531 +3682,6 @@ access_functions_are_affine_or_constant_p (const struct data_reference *a,
return true;
}
/* 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. */
static bool
init_omega_eq_with_af (omega_pb pb, unsigned eq,
unsigned int offset, tree access_fun,
struct data_dependence_relation *ddr)
{
switch (TREE_CODE (access_fun))
{
case POLYNOMIAL_CHREC:
{
tree left = CHREC_LEFT (access_fun);
tree right = CHREC_RIGHT (access_fun);
int var = CHREC_VARIABLE (access_fun);
unsigned var_idx;
if (TREE_CODE (right) != INTEGER_CST)
return false;
var_idx = index_in_loop_nest (var, DDR_LOOP_NEST (ddr));
pb->eqs[eq].coef[offset + var_idx + 1] = int_cst_value (right);
/* Compute the innermost loop index. */
DDR_INNER_LOOP (ddr) = MAX (DDR_INNER_LOOP (ddr), var_idx);
if (offset == 0)
pb->eqs[eq].coef[var_idx + DDR_NB_LOOPS (ddr) + 1]
+= int_cst_value (right);
switch (TREE_CODE (left))
{
case POLYNOMIAL_CHREC:
return init_omega_eq_with_af (pb, eq, offset, left, ddr);
case INTEGER_CST:
pb->eqs[eq].coef[0] += int_cst_value (left);
return true;
default:
return false;
}
}
case INTEGER_CST:
pb->eqs[eq].coef[0] += int_cst_value (access_fun);
return true;
default:
return false;
}
}
/* 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. */
static void
omega_extract_distance_vectors (omega_pb pb,
struct data_dependence_relation *ddr)
{
int eq, geq;
unsigned i, j;
struct loop *loopi, *loopj;
enum omega_result res;
/* 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 (i = 0; i <= DDR_INNER_LOOP (ddr)
&& DDR_LOOP_NEST (ddr).iterate (i, &loopi); i++)
{
int dist = 0;
omega_pb copy = omega_alloc_problem (2 * DDR_NB_LOOPS (ddr),
DDR_NB_LOOPS (ddr));
omega_copy_problem (copy, pb);
/* For all the outer loops "loop_j", add "dj = 0". */
for (j = 0; j < i && DDR_LOOP_NEST (ddr).iterate (j, &loopj); j++)
{
eq = omega_add_zero_eq (copy, omega_black);
copy->eqs[eq].coef[j + 1] = 1;
}
/* For "loop_i", add "0 <= di". */
geq = omega_add_zero_geq (copy, omega_black);
copy->geqs[geq].coef[i + 1] = 1;
/* Reduce the constraint system, and test that the current
problem is feasible. */
res = omega_simplify_problem (copy);
if (res == omega_false
|| res == omega_unknown
|| copy->num_geqs > (int) DDR_NB_LOOPS (ddr))
goto next_problem;
for (eq = 0; eq < copy->num_subs; eq++)
if (copy->subs[eq].key == (int) i + 1)
{
dist = copy->subs[eq].coef[0];
goto found_dist;
}
if (dist == 0)
{
/* Reinitialize problem... */
omega_copy_problem (copy, pb);
for (j = 0; j < i && DDR_LOOP_NEST (ddr).iterate (j, &loopj); j++)
{
eq = omega_add_zero_eq (copy, omega_black);
copy->eqs[eq].coef[j + 1] = 1;
}
/* ..., but this time "di = 1". */
eq = omega_add_zero_eq (copy, omega_black);
copy->eqs[eq].coef[i + 1] = 1;
copy->eqs[eq].coef[0] = -1;
res = omega_simplify_problem (copy);
if (res == omega_false
|| res == omega_unknown
|| copy->num_geqs > (int) DDR_NB_LOOPS (ddr))
goto next_problem;
for (eq = 0; eq < copy->num_subs; eq++)
if (copy->subs[eq].key == (int) i + 1)
{
dist = copy->subs[eq].coef[0];
goto found_dist;
}
}
found_dist:;
/* Save the lexicographically positive distance vector. */
if (dist >= 0)
{
lambda_vector dist_v = lambda_vector_new (DDR_NB_LOOPS (ddr));
lambda_vector dir_v = lambda_vector_new (DDR_NB_LOOPS (ddr));
dist_v[i] = dist;
for (eq = 0; eq < copy->num_subs; eq++)
if (copy->subs[eq].key > 0)
{
dist = copy->subs[eq].coef[0];
dist_v[copy->subs[eq].key - 1] = dist;
}
for (j = 0; j < DDR_NB_LOOPS (ddr); j++)
dir_v[j] = dir_from_dist (dist_v[j]);
save_dist_v (ddr, dist_v);
save_dir_v (ddr, dir_v);
}
next_problem:;
omega_free_problem (copy);
}
}
/* This is called for each subscript of a tuple of data references:
insert an equality for representing the conflicts. */
static bool
omega_setup_subscript (tree access_fun_a, tree access_fun_b,
struct data_dependence_relation *ddr,
omega_pb pb, bool *maybe_dependent)
{
int eq;
tree type = signed_type_for_types (TREE_TYPE (access_fun_a),
TREE_TYPE (access_fun_b));
tree fun_a = chrec_convert (type, access_fun_a, NULL);
tree fun_b = chrec_convert (type, access_fun_b, NULL);
tree difference = chrec_fold_minus (type, fun_a, fun_b);
tree minus_one;
/* When the fun_a - fun_b is not constant, the dependence is not
captured by the classic distance vector representation. */
if (TREE_CODE (difference) != INTEGER_CST)
return false;
/* ZIV test. */
if (ziv_subscript_p (fun_a, fun_b) && !integer_zerop (difference))
{
/* There is no dependence. */
*maybe_dependent = false;
return true;
}
minus_one = build_int_cst (type, -1);
fun_b = chrec_fold_multiply (type, fun_b, minus_one);
eq = omega_add_zero_eq (pb, omega_black);
if (!init_omega_eq_with_af (pb, eq, DDR_NB_LOOPS (ddr), fun_a, ddr)
|| !init_omega_eq_with_af (pb, eq, 0, fun_b, ddr))
/* There is probably a dependence, but the system of
constraints cannot be built: answer "don't know". */
return false;
/* GCD test. */
if (DDR_NB_LOOPS (ddr) != 0 && pb->eqs[eq].coef[0]
&& !int_divides_p (lambda_vector_gcd
((lambda_vector) &(pb->eqs[eq].coef[1]),
2 * DDR_NB_LOOPS (ddr)),
pb->eqs[eq].coef[0]))
{
/* There is no dependence. */
*maybe_dependent = false;
return true;
}
return true;
}
/* Helper function, same as init_omega_for_ddr but specialized for
data references A and B. */
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)
{
unsigned i;
int ineq;
struct loop *loopi;
unsigned nb_loops = DDR_NB_LOOPS (ddr);
/* Insert an equality per subscript. */
for (i = 0; i < DDR_NUM_SUBSCRIPTS (ddr); i++)
{
if (!omega_setup_subscript (DR_ACCESS_FN (dra, i), DR_ACCESS_FN (drb, i),
ddr, pb, maybe_dependent))
return false;
else if (*maybe_dependent == false)
{
/* There is no dependence. */
DDR_ARE_DEPENDENT (ddr) = chrec_known;
return true;
}
}
/* 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".
*/
for (i = 0; i <= DDR_INNER_LOOP (ddr)
&& DDR_LOOP_NEST (ddr).iterate (i, &loopi); i++)
{
HOST_WIDE_INT nbi = max_stmt_executions_int (loopi);
/* 0 <= loop_x */
ineq = omega_add_zero_geq (pb, omega_black);
pb->geqs[ineq].coef[i + nb_loops + 1] = 1;
/* 0 <= loop_x + dx */
ineq = omega_add_zero_geq (pb, omega_black);
pb->geqs[ineq].coef[i + nb_loops + 1] = 1;
pb->geqs[ineq].coef[i + 1] = 1;
if (nbi != -1)
{
/* loop_x <= nb_iters */
ineq = omega_add_zero_geq (pb, omega_black);
pb->geqs[ineq].coef[i + nb_loops + 1] = -1;
pb->geqs[ineq].coef[0] = nbi;
/* loop_x + dx <= nb_iters */
ineq = omega_add_zero_geq (pb, omega_black);
pb->geqs[ineq].coef[i + nb_loops + 1] = -1;
pb->geqs[ineq].coef[i + 1] = -1;
pb->geqs[ineq].coef[0] = nbi;
/* A step "dx" bigger than nb_iters is not feasible, so
add "0 <= nb_iters + dx", */
ineq = omega_add_zero_geq (pb, omega_black);
pb->geqs[ineq].coef[i + 1] = 1;
pb->geqs[ineq].coef[0] = nbi;
/* and "dx <= nb_iters". */
ineq = omega_add_zero_geq (pb, omega_black);
pb->geqs[ineq].coef[i + 1] = -1;
pb->geqs[ineq].coef[0] = nbi;
}
}
omega_extract_distance_vectors (pb, ddr);
return true;
}
/* 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".
*/
static bool
init_omega_for_ddr (struct data_dependence_relation *ddr,
bool *maybe_dependent)
{
omega_pb pb;
bool res = false;
*maybe_dependent = true;
if (same_access_functions (ddr))
{
unsigned j;
lambda_vector dir_v;
/* Save the 0 vector. */
save_dist_v (ddr, lambda_vector_new (DDR_NB_LOOPS (ddr)));
dir_v = lambda_vector_new (DDR_NB_LOOPS (ddr));
for (j = 0; j < DDR_NB_LOOPS (ddr); j++)
dir_v[j] = dir_equal;
save_dir_v (ddr, dir_v);
/* Save the dependences carried by outer loops. */
pb = omega_alloc_problem (2 * DDR_NB_LOOPS (ddr), DDR_NB_LOOPS (ddr));
res = init_omega_for_ddr_1 (DDR_A (ddr), DDR_B (ddr), ddr, pb,
maybe_dependent);
omega_free_problem (pb);
return res;
}
/* 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. */
pb = omega_alloc_problem (2 * DDR_NB_LOOPS (ddr), DDR_NB_LOOPS (ddr));
res = init_omega_for_ddr_1 (DDR_A (ddr), DDR_B (ddr), ddr, pb,
maybe_dependent);
omega_free_problem (pb);
/* Stop computation if not decidable, or no dependence. */
if (res == false || *maybe_dependent == false)
return res;
pb = omega_alloc_problem (2 * DDR_NB_LOOPS (ddr), DDR_NB_LOOPS (ddr));
res = init_omega_for_ddr_1 (DDR_B (ddr), DDR_A (ddr), ddr, pb,
maybe_dependent);
omega_free_problem (pb);
return res;
}
/* Return true when DDR contains the same information as that stored
in DIR_VECTS and in DIST_VECTS, return false otherwise. */
static bool
ddr_consistent_p (FILE *file,
struct data_dependence_relation *ddr,
vec<lambda_vector> dist_vects,
vec<lambda_vector> dir_vects)
{
unsigned int i, j;
/* If dump_file is set, output there. */
if (dump_file && (dump_flags & TDF_DETAILS))
file = dump_file;
if (dist_vects.length () != DDR_NUM_DIST_VECTS (ddr))
{
lambda_vector b_dist_v;
fprintf (file, "\n(Number of distance vectors differ: Banerjee has %d, Omega has %d.\n",
dist_vects.length (),
DDR_NUM_DIST_VECTS (ddr));
fprintf (file, "Banerjee dist vectors:\n");
FOR_EACH_VEC_ELT (dist_vects, i, b_dist_v)
print_lambda_vector (file, b_dist_v, DDR_NB_LOOPS (ddr));
fprintf (file, "Omega dist vectors:\n");
for (i = 0; i < DDR_NUM_DIST_VECTS (ddr); i++)
print_lambda_vector (file, DDR_DIST_VECT (ddr, i), DDR_NB_LOOPS (ddr));
fprintf (file, "data dependence relation:\n");
dump_data_dependence_relation (file, ddr);
fprintf (file, ")\n");
return false;
}
if (dir_vects.length () != DDR_NUM_DIR_VECTS (ddr))
{
fprintf (file, "\n(Number of direction vectors differ: Banerjee has %d, Omega has %d.)\n",
dir_vects.length (),
DDR_NUM_DIR_VECTS (ddr));
return false;
}
for (i = 0; i < DDR_NUM_DIST_VECTS (ddr); i++)
{
lambda_vector a_dist_v;
lambda_vector b_dist_v = DDR_DIST_VECT (ddr, i);
/* Distance vectors are not ordered in the same way in the DDR
and in the DIST_VECTS: search for a matching vector. */
FOR_EACH_VEC_ELT (dist_vects, j, a_dist_v)
if (lambda_vector_equal (a_dist_v, b_dist_v, DDR_NB_LOOPS (ddr)))
break;
if (j == dist_vects.length ())
{
fprintf (file, "\n(Dist vectors from the first dependence analyzer:\n");
print_dist_vectors (file, dist_vects, DDR_NB_LOOPS (ddr));
fprintf (file, "not found in Omega dist vectors:\n");
print_dist_vectors (file, DDR_DIST_VECTS (ddr), DDR_NB_LOOPS (ddr));
fprintf (file, "data dependence relation:\n");
dump_data_dependence_relation (file, ddr);
fprintf (file, ")\n");
}
}
for (i = 0; i < DDR_NUM_DIR_VECTS (ddr); i++)
{
lambda_vector a_dir_v;
lambda_vector b_dir_v = DDR_DIR_VECT (ddr, i);
/* Direction vectors are not ordered in the same way in the DDR
and in the DIR_VECTS: search for a matching vector. */
FOR_EACH_VEC_ELT (dir_vects, j, a_dir_v)
if (lambda_vector_equal (a_dir_v, b_dir_v, DDR_NB_LOOPS (ddr)))
break;
if (j == dist_vects.length ())
{
fprintf (file, "\n(Dir vectors from the first dependence analyzer:\n");
print_dir_vectors (file, dir_vects, DDR_NB_LOOPS (ddr));
fprintf (file, "not found in Omega dir vectors:\n");
print_dir_vectors (file, DDR_DIR_VECTS (ddr), DDR_NB_LOOPS (ddr));
fprintf (file, "data dependence relation:\n");
dump_data_dependence_relation (file, ddr);
fprintf (file, ")\n");
}
}
return true;
}
/* 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
@ -4239,55 +3714,13 @@ compute_affine_dependence (struct data_dependence_relation *ddr,
if (access_functions_are_affine_or_constant_p (dra, loop_nest)
&& access_functions_are_affine_or_constant_p (drb, loop_nest))
{
subscript_dependence_tester (ddr, loop_nest);
if (flag_check_data_deps)
{
/* Dump the dependences from the first algorithm. */
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "\n\nBanerjee Analyzer\n");
dump_data_dependence_relation (dump_file, ddr);
}
if (DDR_ARE_DEPENDENT (ddr) == NULL_TREE)
{
bool maybe_dependent;
vec<lambda_vector> dir_vects, dist_vects;
/* Save the result of the first DD analyzer. */
dist_vects = DDR_DIST_VECTS (ddr);
dir_vects = DDR_DIR_VECTS (ddr);
/* Reset the information. */
DDR_DIST_VECTS (ddr).create (0);
DDR_DIR_VECTS (ddr).create (0);
/* Compute the same information using Omega. */
if (!init_omega_for_ddr (ddr, &maybe_dependent))
goto csys_dont_know;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Omega Analyzer\n");
dump_data_dependence_relation (dump_file, ddr);
}
/* Check that we get the same information. */
if (maybe_dependent)
gcc_assert (ddr_consistent_p (stderr, ddr, dist_vects,
dir_vects));
}
}
}
subscript_dependence_tester (ddr, loop_nest);
/* As a last case, if the dependence cannot be determined, or if
the dependence is considered too difficult to determine, answer
"don't know". */
else
{
csys_dont_know:;
dependence_stats.num_dependence_undetermined++;
if (dump_file && (dump_flags & TDF_DETAILS))
@ -4731,110 +4164,6 @@ compute_data_dependences_for_loop (struct loop *loop,
return res;
}
/* 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_bb (basic_block bb,
bool compute_self_and_read_read_dependences,
vec<data_reference_p> *datarefs,
vec<ddr_p> *dependence_relations)
{
if (find_data_references_in_bb (NULL, bb, datarefs) == chrec_dont_know)
return false;
return compute_all_dependences (*datarefs, dependence_relations, vNULL,
compute_self_and_read_read_dependences);
}
/* 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. */
static void
analyze_all_data_dependences (struct loop *loop)
{
unsigned int i;
int nb_data_refs = 10;
vec<data_reference_p> datarefs;
datarefs.create (nb_data_refs);
vec<ddr_p> dependence_relations;
dependence_relations.create (nb_data_refs * nb_data_refs);
vec<loop_p> loop_nest;
loop_nest.create (3);
/* Compute DDs on the whole function. */
compute_data_dependences_for_loop (loop, false, &loop_nest, &datarefs,
&dependence_relations);
if (dump_file)
{
dump_data_dependence_relations (dump_file, dependence_relations);
fprintf (dump_file, "\n\n");
if (dump_flags & TDF_DETAILS)
dump_dist_dir_vectors (dump_file, dependence_relations);
if (dump_flags & TDF_STATS)
{
unsigned nb_top_relations = 0;
unsigned nb_bot_relations = 0;
unsigned nb_chrec_relations = 0;
struct data_dependence_relation *ddr;
FOR_EACH_VEC_ELT (dependence_relations, i, ddr)
{
if (chrec_contains_undetermined (DDR_ARE_DEPENDENT (ddr)))
nb_top_relations++;
else if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
nb_bot_relations++;
else
nb_chrec_relations++;
}
gather_stats_on_scev_database ();
}
}
loop_nest.release ();
free_dependence_relations (dependence_relations);
free_data_refs (datarefs);
}
/* Computes all the data dependences and check that the results of
several analyzers are the same. */
void
tree_check_data_deps (void)
{
struct loop *loop_nest;
FOR_EACH_LOOP (loop_nest, 0)
analyze_all_data_dependences (loop_nest);
}
/* Free the memory used by a data dependence relation DDR. */
void

View File

@ -22,7 +22,6 @@ along with GCC; see the file COPYING3. If not see
#define GCC_TREE_DATA_REF_H
#include "graphds.h"
#include "omega.h"
#include "tree-chrec.h"
/*
@ -301,9 +300,6 @@ extern bool compute_data_dependences_for_loop (struct loop *, bool,
vec<loop_p> *,
vec<data_reference_p> *,
vec<ddr_p> *);
extern bool compute_data_dependences_for_bb (basic_block, bool,
vec<data_reference_p> *,
vec<ddr_p> *);
extern void debug_ddrs (vec<ddr_p> );
extern void dump_data_reference (FILE *, struct data_reference *);
extern void debug (data_reference &ref);
@ -343,8 +339,6 @@ extern bool dr_may_alias_p (const struct data_reference *,
const struct data_reference *, bool);
extern bool dr_equal_offsets_p (struct data_reference *,
struct data_reference *);
extern void tree_check_data_deps (void);
/* Return true when the base objects of data references A and B are
the same memory object. */

View File

@ -286,54 +286,6 @@ make_pass_vectorize (gcc::context *ctxt)
return new pass_vectorize (ctxt);
}
/* Check the correctness of the data dependence analyzers. */
namespace {
const pass_data pass_data_check_data_deps =
{
GIMPLE_PASS, /* type */
"ckdd", /* name */
OPTGROUP_LOOP, /* optinfo_flags */
TV_CHECK_DATA_DEPS, /* tv_id */
( PROP_cfg | PROP_ssa ), /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
0, /* todo_flags_finish */
};
class pass_check_data_deps : public gimple_opt_pass
{
public:
pass_check_data_deps (gcc::context *ctxt)
: gimple_opt_pass (pass_data_check_data_deps, ctxt)
{}
/* opt_pass methods: */
virtual bool gate (function *) { return flag_check_data_deps != 0; }
virtual unsigned int execute (function *);
}; // class pass_check_data_deps
unsigned int
pass_check_data_deps::execute (function *fun)
{
if (number_of_loops (fun) <= 1)
return 0;
tree_check_data_deps ();
return 0;
}
} // anon namespace
gimple_opt_pass *
make_pass_check_data_deps (gcc::context *ctxt)
{
return new pass_check_data_deps (ctxt);
}
/* Propagation of constants using scev. */
namespace {

View File

@ -57,6 +57,7 @@ along with GCC; see the file COPYING3. If not see
#include "optabs.h"
#include "tree-scalar-evolution.h"
#include "tree-inline.h"
#include "params.h"
static unsigned int tree_ssa_phiopt_worker (bool, bool);
static bool conditional_replacement (basic_block, basic_block,

View File

@ -63,6 +63,7 @@ along with GCC; see the file COPYING3. If not see
#include "insn-codes.h"
#include "optabs.h"
#include "builtins.h"
#include "params.h"
/* Return true if load- or store-lanes optab OPTAB is implemented for
COUNT vectors of type VECTYPE. NAME is the name of OPTAB. */

View File

@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "params.h"
#include "rtl.h"
#include "ssa.h"
#include "alias.h"