fix PR68279: bail out when scev gets instantiated to not_known
Co-Authored-By: Sebastian Pop <s.pop@samsung.com> From-SVN: r230771
This commit is contained in:
parent
8f29e7f5ea
commit
36f40be012
9 changed files with 147 additions and 75 deletions
|
@ -1,3 +1,26 @@
|
|||
2015-11-23 Aditya Kumar <aditya.k7@samsung.com>
|
||||
Sebastian Pop <s.pop@samsung.com>
|
||||
|
||||
PR tree-optimization/68279
|
||||
* graphite-poly.c (new_scop): Remove poly_scop_p.
|
||||
* graphite-poly.h (struct scop): Same.
|
||||
(build_poly_scop): Declare.
|
||||
* graphite-sese-to-poly.c: Do not include graphite-sese-to-poly.h.
|
||||
(cleanup_loop_iter_dom): New.
|
||||
(build_loop_iteration_domains): Early return when scev analysis fails.
|
||||
(create_pw_aff_from_tree): Same.
|
||||
(add_condition_to_pbb): Same.
|
||||
(add_conditions_to_domain): Same.
|
||||
(add_conditions_to_constraints): Same.
|
||||
(build_scop_iteration_domain): Same.
|
||||
(build_poly_scop): Same. Do not initialize poly_scop_p.
|
||||
* graphite-sese-to-poly.h: Remove.
|
||||
* graphite.c: Do not include graphite-sese-to-poly.h.
|
||||
(graphite_transform_loops): Stop before code generation when
|
||||
build_poly_scop fails.
|
||||
* sese.c (scalar_evolution_in_region): Add fixme note about scev
|
||||
analysis.
|
||||
|
||||
2015-11-23 Aditya Kumar <aditya.k7@samsung.com>
|
||||
Sebastian Pop <s.pop@samsung.com>
|
||||
|
||||
|
|
|
@ -308,7 +308,6 @@ new_scop (edge entry, edge exit)
|
|||
scop_set_region (scop, region);
|
||||
scop->original_schedule = NULL;
|
||||
scop->pbbs.create (3);
|
||||
scop->poly_scop_p = false;
|
||||
scop->drs.create (3);
|
||||
|
||||
return scop;
|
||||
|
|
|
@ -420,10 +420,6 @@ struct scop
|
|||
|
||||
/* Original schedule of the SCoP. */
|
||||
isl_union_map *original_schedule;
|
||||
|
||||
/* True when the scop has been converted to its polyhedral
|
||||
representation. */
|
||||
bool poly_scop_p;
|
||||
};
|
||||
|
||||
extern scop_p new_scop (edge, edge);
|
||||
|
@ -468,4 +464,6 @@ carries_deps (__isl_keep isl_union_map *schedule,
|
|||
__isl_keep isl_union_map *deps,
|
||||
int depth);
|
||||
|
||||
bool build_poly_scop (scop_p);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -66,7 +66,6 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include "graphite-poly.h"
|
||||
#include "graphite-sese-to-poly.h"
|
||||
|
||||
/* Assigns to RES the value of the INTEGER_CST T. */
|
||||
|
||||
|
@ -590,10 +589,20 @@ set_scop_parameter_dim (scop_p scop)
|
|||
scop->param_context = isl_set_universe (space);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
cleanup_loop_iter_dom (isl_set *inner, isl_set *outer, isl_space *space, mpz_t g)
|
||||
{
|
||||
isl_set_free (inner);
|
||||
isl_set_free (outer);
|
||||
isl_space_free (space);
|
||||
mpz_clear (g);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Builds the constraint polyhedra for LOOP in SCOP. OUTER_PH gives
|
||||
the constraints for the surrounding loops. */
|
||||
|
||||
static void
|
||||
static bool
|
||||
build_loop_iteration_domains (scop_p scop, struct loop *loop,
|
||||
int nb,
|
||||
isl_set *outer, isl_set **doms)
|
||||
|
@ -638,11 +647,17 @@ build_loop_iteration_domains (scop_p scop, struct loop *loop,
|
|||
|
||||
nb_iters = scalar_evolution_in_region (region, loop, nb_iters);
|
||||
|
||||
/* Bail out as we do not know the scev. */
|
||||
if (chrec_contains_undetermined (nb_iters))
|
||||
return cleanup_loop_iter_dom (inner, outer, space, g);
|
||||
|
||||
aff = extract_affine (scop, nb_iters, isl_set_get_space (inner));
|
||||
isl_set *valid = isl_pw_aff_nonneg_set (isl_pw_aff_copy (aff));
|
||||
valid = isl_set_project_out (valid, isl_dim_set, 0,
|
||||
isl_set_dim (valid, isl_dim_set));
|
||||
scop->param_context = isl_set_intersect (scop->param_context, valid);
|
||||
|
||||
if (valid)
|
||||
scop->param_context = isl_set_intersect (scop->param_context, valid);
|
||||
|
||||
isl_local_space *ls = isl_local_space_from_space (isl_space_copy (space));
|
||||
isl_aff *al = isl_aff_set_coefficient_si (isl_aff_zero_on_domain (ls),
|
||||
|
@ -686,21 +701,24 @@ build_loop_iteration_domains (scop_p scop, struct loop *loop,
|
|||
else
|
||||
gcc_unreachable ();
|
||||
|
||||
if (loop->inner)
|
||||
build_loop_iteration_domains (scop, loop->inner, nb + 1,
|
||||
isl_set_copy (inner), doms);
|
||||
if (loop->inner
|
||||
&& !build_loop_iteration_domains (scop, loop->inner, nb + 1,
|
||||
isl_set_copy (inner), doms))
|
||||
return cleanup_loop_iter_dom (inner, outer, space, g);
|
||||
|
||||
if (nb != 0
|
||||
&& loop->next
|
||||
&& loop_in_sese_p (loop->next, region))
|
||||
build_loop_iteration_domains (scop, loop->next, nb,
|
||||
isl_set_copy (outer), doms);
|
||||
&& loop_in_sese_p (loop->next, region)
|
||||
&& !build_loop_iteration_domains (scop, loop->next, nb,
|
||||
isl_set_copy (outer), doms))
|
||||
return cleanup_loop_iter_dom (inner, outer, space, g);
|
||||
|
||||
doms[loop->num] = inner;
|
||||
|
||||
isl_set_free (outer);
|
||||
isl_space_free (space);
|
||||
mpz_clear (g);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Returns a linear expression for tree T evaluated in PBB. */
|
||||
|
@ -711,6 +729,11 @@ create_pw_aff_from_tree (poly_bb_p pbb, tree t)
|
|||
scop_p scop = PBB_SCOP (pbb);
|
||||
|
||||
t = scalar_evolution_in_region (scop->scop_info->region, pbb_loop (pbb), t);
|
||||
|
||||
/* Bail out as we do not know the scev. */
|
||||
if (chrec_contains_undetermined (t))
|
||||
return NULL;
|
||||
|
||||
gcc_assert (!automatically_generated_chrec_p (t));
|
||||
|
||||
return extract_affine (scop, t, isl_set_get_space (pbb->domain));
|
||||
|
@ -720,13 +743,21 @@ create_pw_aff_from_tree (poly_bb_p pbb, tree t)
|
|||
operator. This allows us to invert the condition or to handle
|
||||
inequalities. */
|
||||
|
||||
static void
|
||||
static bool
|
||||
add_condition_to_pbb (poly_bb_p pbb, gcond *stmt, enum tree_code code)
|
||||
{
|
||||
isl_pw_aff *lhs = create_pw_aff_from_tree (pbb, gimple_cond_lhs (stmt));
|
||||
isl_pw_aff *rhs = create_pw_aff_from_tree (pbb, gimple_cond_rhs (stmt));
|
||||
isl_set *cond;
|
||||
if (!lhs)
|
||||
return false;
|
||||
|
||||
isl_pw_aff *rhs = create_pw_aff_from_tree (pbb, gimple_cond_rhs (stmt));
|
||||
if (!rhs)
|
||||
{
|
||||
isl_pw_aff_free (lhs);
|
||||
return false;
|
||||
}
|
||||
|
||||
isl_set *cond;
|
||||
switch (code)
|
||||
{
|
||||
case LT_EXPR:
|
||||
|
@ -756,17 +787,18 @@ add_condition_to_pbb (poly_bb_p pbb, gcond *stmt, enum tree_code code)
|
|||
default:
|
||||
isl_pw_aff_free (lhs);
|
||||
isl_pw_aff_free (rhs);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
cond = isl_set_coalesce (cond);
|
||||
cond = isl_set_set_tuple_id (cond, isl_set_get_tuple_id (pbb->domain));
|
||||
pbb->domain = isl_set_intersect (pbb->domain, cond);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Add conditions to the domain of PBB. */
|
||||
|
||||
static void
|
||||
static bool
|
||||
add_conditions_to_domain (poly_bb_p pbb)
|
||||
{
|
||||
unsigned int i;
|
||||
|
@ -774,7 +806,7 @@ add_conditions_to_domain (poly_bb_p pbb)
|
|||
gimple_poly_bb_p gbb = PBB_BLACK_BOX (pbb);
|
||||
|
||||
if (GBB_CONDITIONS (gbb).is_empty ())
|
||||
return;
|
||||
return true;
|
||||
|
||||
FOR_EACH_VEC_ELT (GBB_CONDITIONS (gbb), i, stmt)
|
||||
switch (gimple_code (stmt))
|
||||
|
@ -792,7 +824,8 @@ add_conditions_to_domain (poly_bb_p pbb)
|
|||
if (!GBB_CONDITION_CASES (gbb)[i])
|
||||
code = invert_tree_comparison (code, false);
|
||||
|
||||
add_condition_to_pbb (pbb, cond_stmt, code);
|
||||
if (!add_condition_to_pbb (pbb, cond_stmt, code))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -803,19 +836,24 @@ add_conditions_to_domain (poly_bb_p pbb)
|
|||
gcc_unreachable ();
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Traverses all the GBBs of the SCOP and add their constraints to the
|
||||
iteration domains. */
|
||||
|
||||
static void
|
||||
static bool
|
||||
add_conditions_to_constraints (scop_p scop)
|
||||
{
|
||||
int i;
|
||||
poly_bb_p pbb;
|
||||
|
||||
FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
|
||||
add_conditions_to_domain (pbb);
|
||||
if (!add_conditions_to_domain (pbb))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Add constraints on the possible values of parameter P from the type
|
||||
|
@ -895,19 +933,23 @@ build_scop_context (scop_p scop)
|
|||
SCOP, and that vary for the execution of the current basic block.
|
||||
Returns false if there is no loop in SCOP. */
|
||||
|
||||
static void
|
||||
static bool
|
||||
build_scop_iteration_domain (scop_p scop)
|
||||
{
|
||||
sese_info_p region = scop->scop_info;
|
||||
int nb_loops = number_of_loops (cfun);
|
||||
isl_set **doms = XCNEWVEC (isl_set *, nb_loops);
|
||||
|
||||
bool res = true;
|
||||
int i;
|
||||
struct loop *loop;
|
||||
FOR_EACH_VEC_ELT (region->loop_nest, i, loop)
|
||||
if (!loop_in_sese_p (loop_outer (loop), region->region))
|
||||
build_loop_iteration_domains (scop, loop, 0,
|
||||
isl_set_copy (scop->param_context), doms);
|
||||
if (!loop_in_sese_p (loop_outer (loop), region->region)
|
||||
&& !build_loop_iteration_domains (scop, loop, 0,
|
||||
isl_set_copy (scop->param_context), doms))
|
||||
{
|
||||
res = false;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
poly_bb_p pbb;
|
||||
FOR_EACH_VEC_ELT (scop->pbbs, i, pbb)
|
||||
|
@ -923,11 +965,13 @@ build_scop_iteration_domain (scop_p scop)
|
|||
isl_id_for_pbb (scop, pbb));
|
||||
}
|
||||
|
||||
cleanup:
|
||||
for (int i = 0; i < nb_loops; i++)
|
||||
if (doms[i])
|
||||
isl_set_free (doms[i]);
|
||||
|
||||
free (doms);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Add a constrain to the ACCESSES polyhedron for the alias set of
|
||||
|
@ -1187,20 +1231,21 @@ build_scop_drs (scop_p scop)
|
|||
|
||||
/* Builds the polyhedral representation for a SESE region. */
|
||||
|
||||
void
|
||||
bool
|
||||
build_poly_scop (scop_p scop)
|
||||
{
|
||||
set_scop_parameter_dim (scop);
|
||||
build_scop_iteration_domain (scop);
|
||||
if (!build_scop_iteration_domain (scop))
|
||||
return false;
|
||||
|
||||
build_scop_context (scop);
|
||||
add_conditions_to_constraints (scop);
|
||||
|
||||
if (!add_conditions_to_constraints (scop))
|
||||
return false;
|
||||
|
||||
build_scop_drs (scop);
|
||||
build_scop_minimal_scattering (scop);
|
||||
build_scop_original_schedule (scop);
|
||||
|
||||
/* This SCoP has been translated to the polyhedral
|
||||
representation. */
|
||||
scop->poly_scop_p = true;
|
||||
return true;
|
||||
}
|
||||
#endif /* HAVE_isl */
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
/* Conversion of SESE regions to Polyhedra.
|
||||
Copyright (C) 2009-2015 Free Software Foundation, Inc.
|
||||
Contributed by Sebastian Pop <sebastian.pop@amd.com>.
|
||||
|
||||
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_GRAPHITE_SESE_TO_POLY_H
|
||||
#define GCC_GRAPHITE_SESE_TO_POLY_H
|
||||
|
||||
void build_poly_scop (scop_p);
|
||||
|
||||
#endif
|
|
@ -62,7 +62,6 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "graphite-poly.h"
|
||||
#include "graphite-scop-detection.h"
|
||||
#include "graphite-isl-ast-to-gimple.h"
|
||||
#include "graphite-sese-to-poly.h"
|
||||
|
||||
/* Print global statistics to FILE. */
|
||||
|
||||
|
@ -326,20 +325,18 @@ graphite_transform_loops (void)
|
|||
if (dbg_cnt (graphite_scop))
|
||||
{
|
||||
scop->isl_context = ctx;
|
||||
build_poly_scop (scop);
|
||||
if (!build_poly_scop (scop))
|
||||
continue;
|
||||
|
||||
if (dump_file && dump_flags)
|
||||
print_scop (dump_file, scop);
|
||||
if (scop->poly_scop_p
|
||||
&& apply_poly_transforms (scop))
|
||||
{
|
||||
need_cfg_cleanup_p = true;
|
||||
/* When code generation is not successful, do not continue
|
||||
generating code for the next scops: the IR has to be cleaned up
|
||||
and could be in an inconsistent state. */
|
||||
if (!graphite_regenerate_ast_isl (scop))
|
||||
break;
|
||||
}
|
||||
if (!apply_poly_transforms (scop))
|
||||
continue;
|
||||
|
||||
need_cfg_cleanup_p = true;
|
||||
/* When code generation is not successful, do not continue
|
||||
generating code for the next scops: the IR has to be cleaned up
|
||||
and could be in an inconsistent state. */
|
||||
if (!graphite_regenerate_ast_isl (scop))
|
||||
break;
|
||||
}
|
||||
|
||||
free_scops (scops);
|
||||
|
|
|
@ -609,6 +609,8 @@ scalar_evolution_in_region (sese_l ®ion, loop_p loop, tree t)
|
|||
|
||||
if (TREE_CODE (t) != SSA_NAME
|
||||
|| loop_in_sese_p (loop, region))
|
||||
/* FIXME: we would need instantiate SCEV to work on a region, and be more
|
||||
flexible wrt. memory loads that may be invariant in the region. */
|
||||
return instantiate_scev (before, loop,
|
||||
analyze_scalar_evolution (loop, t));
|
||||
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2015-11-23 Aditya Kumar <aditya.k7@samsung.com>
|
||||
Sebastian Pop <s.pop@samsung.com>
|
||||
|
||||
PR tree-optimization/68279
|
||||
* testsuite/gfortran.dg/graphite/pr68279.f90: New.
|
||||
|
||||
2015-11-23 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR tree-optimization/68455
|
||||
|
|
28
gcc/testsuite/gfortran.dg/graphite/pr68279.f90
Normal file
28
gcc/testsuite/gfortran.dg/graphite/pr68279.f90
Normal file
|
@ -0,0 +1,28 @@
|
|||
! { dg-options "-std=legacy -floop-nest-optimize -O2" }
|
||||
|
||||
MODULE dbcsr_mm_accdrv
|
||||
INTEGER, SAVE :: accdrv_binning_nbins = 4096
|
||||
INTEGER, SAVE :: accdrv_binning_binsize = 16
|
||||
INTEGER, PARAMETER, PUBLIC :: dbcsr_ps_width = 7
|
||||
CONTAINS
|
||||
SUBROUTINE stack_binning(params_in, params_out, stack_size)
|
||||
INTEGER, INTENT(IN) :: stack_size
|
||||
INTEGER, DIMENSION(dbcsr_ps_width, &
|
||||
stack_size), INTENT(OUT) :: params_out
|
||||
INTEGER, DIMENSION(dbcsr_ps_width, &
|
||||
stack_size), INTENT(IN) :: params_in
|
||||
INTEGER, DIMENSION(accdrv_binning_nbins) :: bin_top
|
||||
INTEGER, DIMENSION(dbcsr_ps_width) :: val
|
||||
INTEGER, DIMENSION(dbcsr_ps_width, &
|
||||
accdrv_binning_binsize, &
|
||||
accdrv_binning_nbins) :: bin_arr
|
||||
DO i=1,stack_size
|
||||
val(:) = params_in(:,i)
|
||||
IF(bin_top(bin_id) > accdrv_binning_binsize) THEN
|
||||
params_out(:, top:top+bin_top(bin_id)-2) = bin_arr(:, 1:bin_top(bin_id)-1, bin_id)
|
||||
ENDIF
|
||||
bin_arr(:, bin_top(bin_id), bin_id) = val(:)
|
||||
bin_top(bin_id) = bin_top(bin_id) + 1
|
||||
END DO
|
||||
END SUBROUTINE stack_binning
|
||||
END MODULE
|
Loading…
Add table
Reference in a new issue