#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "tm.h"
-#include "ggc.h"
-#include "tree.h"
-#include "rtl.h"
-#include "basic-block.h"
-#include "diagnostic.h"
+#include "diagnostic-core.h"
#include "tree-flow.h"
-#include "toplev.h"
#include "tree-dump.h"
-#include "timevar.h"
#include "cfgloop.h"
#include "tree-chrec.h"
#include "tree-data-ref.h"
#include "tree-scalar-evolution.h"
-#include "tree-pass.h"
-#include "domwalk.h"
-#include "value-prof.h"
-#include "pointer-set.h"
-#include "gimple.h"
-#include "langhooks.h"
#include "sese.h"
#ifdef HAVE_cloog
#include "ppl_c.h"
#include "graphite-cloog-util.h"
#include "graphite-ppl.h"
-#include "graphite.h"
#include "graphite-poly.h"
-#include "graphite-scop-detection.h"
#include "graphite-clast-to-gimple.h"
#include "graphite-dependences.h"
#include "graphite-cloog-compat.h"
#ifdef ENABLE_CHECKING
verify_loop_structure ();
verify_dominators (CDI_DOMINATORS);
- verify_dominators (CDI_POST_DOMINATORS);
verify_loop_closed_ssa (true);
#endif
}
if (slot)
{
- if (*slot)
- free (*slot);
+ free (*slot);
*slot = new_clast_name_index (name, index);
}
int p2 = TYPE_PRECISION (type2);
int precision;
tree type;
+ enum machine_mode mode;
if (p1 > p2)
precision = TYPE_UNSIGNED (type1) ? p1 * 2 : p1;
else
precision = TYPE_UNSIGNED (type2) ? p2 * 2 : p2;
- type = lang_hooks.types.type_for_size (precision, false);
+ if (precision > BITS_PER_WORD)
+ {
+ gloog_error = true;
+ return integer_type_node;
+ }
+
+ mode = smallest_mode_for_size (precision, MODE_INT);
+ precision = GET_MODE_PRECISION (mode);
+ type = build_nonstandard_integer_type (precision, false);
if (!type)
{
gloog_error = true;
return integer_type_node;
}
+
return type;
}
if (mpz_sgn (y) < 0)
mpz_neg (y, y);
- while (mpz_cmp (y, x) > 0)
+ while (mpz_cmp (y, x) >= 0)
{
mpz_mul (x, x, two);
precision++;
gcc_assert (mpz_cmp (low, up) <= 0);
- if (mpz_sgn (low) < 0)
- unsigned_p = false;
-
prec_up = precision_for_value (up);
prec_int = precision_for_interval (low, up);
precision = MAX (prec_up, prec_int);
return integer_type_node;
}
+ if (mpz_sgn (low) <= 0)
+ unsigned_p = false;
+
+ else if (precision < BITS_PER_WORD)
+ {
+ unsigned_p = false;
+ precision++;
+ }
+
mode = smallest_mode_for_size (precision, MODE_INT);
precision = GET_MODE_PRECISION (mode);
type = build_nonstandard_integer_type (precision, unsigned_p);
ppl_max_for_le_pointset (ps, le, up);
ppl_min_for_le_pointset (ps, le, low);
+ ppl_delete_Linear_Expression (le);
+ ppl_delete_Pointset_Powerset_C_Polyhedron (ps);
}
/* Compute the type for the induction variable at LEVEL for the
newivs_index, params_index);
tree ub = clast_to_gcc_expression (type, stmt->UB, region, newivs,
newivs_index, params_index);
- tree one = POINTER_TYPE_P (type) ? size_one_node
- : fold_convert (type, integer_one_node);
- /* Adding +1 and using LT_EXPR helps with loop latches that have a
- loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes
- 2^{32|64}, and the condition lb <= ub is true, even if we do not want this.
- However lb < ub + 1 is false, as expected. */
- tree ub_one = fold_build2 (POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR
- : PLUS_EXPR, type, ub, one);
-
- /* When ub + 1 wraps around, use lb <= ub. */
- if (integer_zerop (ub_one))
+ /* When ub is simply a constant or a parameter, use lb <= ub. */
+ if (TREE_CODE (ub) == INTEGER_CST || TREE_CODE (ub) == SSA_NAME)
cond_expr = fold_build2 (LE_EXPR, boolean_type_node, lb, ub);
else
- cond_expr = fold_build2 (LT_EXPR, boolean_type_node, lb, ub_one);
+ {
+ tree one = (POINTER_TYPE_P (type)
+ ? size_one_node
+ : fold_convert (type, integer_one_node));
+ /* Adding +1 and using LT_EXPR helps with loop latches that have a
+ loop iteration count of "PARAMETER - 1". For PARAMETER == 0 this becomes
+ 2^k-1 due to integer overflow, and the condition lb <= ub is true,
+ even if we do not want this. However lb < ub + 1 is false, as
+ expected. */
+ tree ub_one = fold_build2 (POINTER_TYPE_P (type) ? POINTER_PLUS_EXPR
+ : PLUS_EXPR, type, ub, one);
+
+ cond_expr = fold_build2 (LT_EXPR, boolean_type_node, lb, ub_one);
+ }
exit_edge = create_empty_if_region_on_edge (entry_edge, cond_expr);
/* Free the SCATTERING domain list. */
static void
-free_scattering (CloogDomainList *scattering)
+free_scattering (CloogScatteringList *scattering)
{
while (scattering)
{
- CloogDomain *dom = cloog_domain (scattering);
- CloogDomainList *next = cloog_next_domain (scattering);
+ CloogScattering *dom = cloog_scattering (scattering);
+ CloogScatteringList *next = cloog_next_scattering (scattering);
- cloog_domain_free (dom);
+ cloog_scattering_free (dom);
free (scattering);
scattering = next;
}
scattering);
}
+/* Initialize a CLooG input file. */
+
+static FILE *
+init_cloog_input_file (int scop_number)
+{
+ FILE *graphite_out_file;
+ int len = strlen (dump_base_name);
+ char *dumpname = XNEWVEC (char, len + 25);
+ char *s_scop_number = XNEWVEC (char, 15);
+
+ memcpy (dumpname, dump_base_name, len + 1);
+ strip_off_ending (dumpname, len);
+ sprintf (s_scop_number, ".%d", scop_number);
+ strcat (dumpname, s_scop_number);
+ strcat (dumpname, ".cloog");
+ graphite_out_file = fopen (dumpname, "w+b");
+
+ if (graphite_out_file == 0)
+ fatal_error ("can%'t open %s for writing: %m", dumpname);
+
+ free (dumpname);
+
+ return graphite_out_file;
+}
+
/* Build cloog program for SCoP. */
static void
-build_cloog_prog (scop_p scop, CloogProgram *prog, CloogOptions *options)
+build_cloog_prog (scop_p scop, CloogProgram *prog,
+ CloogOptions *options)
{
int i;
int max_nb_loops = scop_max_loop_depth (scop);
poly_bb_p pbb;
CloogLoop *loop_list = NULL;
CloogBlockList *block_list = NULL;
- CloogDomainList *scattering = NULL;
+ CloogScatteringList *scattering = NULL;
int nbs = 2 * max_nb_loops + 1;
int *scaldims;
cloog_program_set_context
- (prog, new_Cloog_Domain_from_ppl_Pointset_Powerset (SCOP_CONTEXT (scop)));
+ (prog, new_Cloog_Domain_from_ppl_Pointset_Powerset (SCOP_CONTEXT (scop),
+ scop_nb_params (scop), cloog_state));
nbs = unify_scattering_dimensions (scop);
scaldims = (int *) xmalloc (nbs * (sizeof (int)));
cloog_program_set_nb_scattdims (prog, nbs);
initialize_cloog_names (scop, prog);
- for (i = 0; VEC_iterate (poly_bb_p, SCOP_BBS (scop), i, pbb); i++)
+ FOR_EACH_VEC_ELT (poly_bb_p, SCOP_BBS (scop), i, pbb)
{
CloogStatement *stmt;
CloogBlock *block;
+ CloogDomain *dom;
/* Dead code elimination: when the domain of a PBB is empty,
don't generate code for the PBB. */
continue;
/* Build the new statement and its block. */
- stmt = cloog_statement_alloc (pbb_index (pbb));
+ stmt = cloog_statement_alloc (cloog_state, pbb_index (pbb));
+ dom = new_Cloog_Domain_from_ppl_Pointset_Powerset (PBB_DOMAIN (pbb),
+ scop_nb_params (scop),
+ cloog_state);
block = cloog_block_alloc (stmt, 0, NULL, pbb_dim_iter_domain (pbb));
cloog_statement_set_usr (stmt, pbb);
/* Build loop list. */
{
- CloogLoop *new_loop_list = cloog_loop_malloc ();
+ CloogLoop *new_loop_list = cloog_loop_malloc (cloog_state);
cloog_loop_set_next (new_loop_list, loop_list);
- cloog_loop_set_domain
- (new_loop_list,
- new_Cloog_Domain_from_ppl_Pointset_Powerset (PBB_DOMAIN (pbb)));
+ cloog_loop_set_domain (new_loop_list, dom);
cloog_loop_set_block (new_loop_list, block);
loop_list = new_loop_list;
}
/* Build scattering list. */
{
/* XXX: Replace with cloog_domain_list_alloc(), when available. */
- CloogDomainList *new_scattering
- = (CloogDomainList *) xmalloc (sizeof (CloogDomainList));
+ CloogScatteringList *new_scattering
+ = (CloogScatteringList *) xmalloc (sizeof (CloogScatteringList));
ppl_Polyhedron_t scat;
- CloogDomain *dom;
+ CloogScattering *dom;
scat = PBB_TRANSFORMED_SCATTERING (pbb);
- dom = new_Cloog_Domain_from_ppl_Polyhedron (scat);
+ dom = new_Cloog_Scattering_from_ppl_Polyhedron
+ (scat, scop_nb_params (scop), pbb_nb_scattering_transform (pbb),
+ cloog_state);
- cloog_set_next_domain (new_scattering, scattering);
- cloog_set_domain (new_scattering, dom);
+ cloog_set_next_scattering (new_scattering, scattering);
+ cloog_set_scattering (new_scattering, dom);
scattering = new_scattering;
}
}
/* Extract scalar dimensions to simplify the code generation problem. */
cloog_program_extract_scalars (prog, scattering, options);
+ /* Dump a .cloog input file, if requested. This feature is only
+ enabled in the Graphite branch. */
+ if (0)
+ {
+ static size_t file_scop_number = 0;
+ FILE *cloog_file = init_cloog_input_file (file_scop_number);
+
+ cloog_program_dump_cloog (cloog_file, prog, scattering);
+ ++file_scop_number;
+ }
+
/* Apply scattering. */
cloog_program_scatter (prog, scattering, options);
free_scattering (scattering);
static CloogOptions *
set_cloog_options (void)
{
- CloogOptions *options = cloog_options_malloc ();
+ CloogOptions *options = cloog_options_malloc (cloog_state);
/* Change cloog output language to C. If we do use FORTRAN instead, cloog
will stop e.g. with "ERROR: unbounded loops not allowed in FORTRAN.", if
print_generated_program (FILE *file, scop_p scop)
{
CloogOptions *options = set_cloog_options ();
+
cloog_prog_clast pc = scop_to_clast (scop);
fprintf (file, " (prog: \n");
&newivs, newivs_index,
bb_pbb_mapping, 1, params_index);
graphite_verify ();
- scev_reset_htab ();
+ scev_reset ();
recompute_all_dominators ();
graphite_verify ();
return !gloog_error;
}
-
#endif