diff options
author | spop <spop@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-10-15 16:24:15 +0000 |
---|---|---|
committer | spop <spop@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-10-15 16:24:15 +0000 |
commit | be8d200b02193648532fec45160982c6a17f4702 (patch) | |
tree | 330d6f9c765630d4d31dbcd29bd050c5cd5fa243 /gcc/graphite.c | |
parent | 7dd3db6ea365e42e565bb546b2e2729ef4828638 (diff) | |
download | gcc-be8d200b02193648532fec45160982c6a17f4702.tar.gz |
2008-10-15 Jan Sjodin <jan.sjodin@amd.com>
Harsha Jagasia <harsha.jagasia@amd.com>
PR tree-optimization/37485
* graphite.c (gmp_cst_to_tree): Moved.
(iv_stack_entry_is_constant): New.
(iv_stack_entry_is_iv): New.
(loop_iv_stack_push): Renamed to loop_iv_stack_push_iv.
(loop_iv_stack_insert_constant): New.
(loop_iv_stack_pop): Use new datatpype.
(loop_iv_stack_get_iv): Same.
(loop_iv_stack_get_iv_from_name): Same.
(loop_iv_stack_debug): Renamed to debug_loop_iv_stack.
(loop_iv_stack_patch_for_consts): New.
(loop_iv_stack_remove_constants): New.
(graphite_create_new_loop): Use loop_iv_stack_push_iv.
(translate_clast): Call loop_iv_stack_patch_for_consts and
loop_iv_stack_remove_constants.
(gloog): Use new datatype. Redirect construction edge to end
block to avoid accidental deletion.
* graphite.h (enum iv_stack_entry_kind): New. Tag for data in
iv stack entry.
(union iv_stack_entry_data): New. Data in iv stack entry.
(struct iv_stack_entry): New. Datatype for iv stack entries.
2008-10-15 Sebastian Pop <sebastian.pop@amd.com>
* tree-data-ref.c (stmt_simple_memref_p): Fix memleak.
* graphite.c (free_scop): Same.
(build_scops): Same.
(free_scattering): New.
(build_cloog_prog): Call free_scattering.
(patch_phis_for_virtual_defs): Fix memleak.
(graphite_trans_bb_strip_mine): Same.
(limit_scops): Same.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@141143 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/graphite.c')
-rw-r--r-- | gcc/graphite.c | 255 |
1 files changed, 203 insertions, 52 deletions
diff --git a/gcc/graphite.c b/gcc/graphite.c index c31c305cf99..18174eecd91 100644 --- a/gcc/graphite.c +++ b/gcc/graphite.c @@ -60,6 +60,14 @@ along with GCC; see the file COPYING3. If not see static VEC (scop_p, heap) *current_scops; +/* Converts a GMP constant V to a tree and returns it. */ + +static tree +gmp_cst_to_tree (Value v) +{ + return build_int_cst (integer_type_node, value_get_si (v)); +} + /* Debug the list of old induction variables for this SCOP. */ void @@ -95,24 +103,62 @@ debug_loop_vec (graphite_bb_p gb) fprintf (stderr, "\n"); } +/* Returns true if stack ENTRY is a constant. */ + +static bool +iv_stack_entry_is_constant (iv_stack_entry *entry) +{ + return entry->kind == iv_stack_entry_const; +} + +/* Returns true if stack ENTRY is an induction variable. */ + +static bool +iv_stack_entry_is_iv (iv_stack_entry *entry) +{ + return entry->kind == iv_stack_entry_iv; +} + /* Push (IV, NAME) on STACK. */ static void -loop_iv_stack_push (loop_iv_stack stack, tree iv, const char *name) +loop_iv_stack_push_iv (loop_iv_stack stack, tree iv, const char *name) { + iv_stack_entry *entry = XNEW (iv_stack_entry); name_tree named_iv = XNEW (struct name_tree); named_iv->t = iv; named_iv->name = name; - VEC_safe_push (name_tree, heap, *stack, named_iv); + + entry->kind = iv_stack_entry_iv; + entry->data.iv = named_iv; + + VEC_safe_push (iv_stack_entry_p, heap, *stack, entry); +} + +/* Inserts a CONSTANT in STACK at INDEX. */ + +static void +loop_iv_stack_insert_constant (loop_iv_stack stack, int index, + tree constant) +{ + iv_stack_entry *entry = XNEW (iv_stack_entry); + + entry->kind = iv_stack_entry_const; + entry->data.constant = constant; + + VEC_safe_insert (iv_stack_entry_p, heap, *stack, index, entry); } -/* Pops an element out of STACK. */ +/* Pops and frees an element out of STACK. */ static void loop_iv_stack_pop (loop_iv_stack stack) { - VEC_pop (name_tree, *stack); + iv_stack_entry_p entry = VEC_pop (iv_stack_entry_p, *stack); + + free (entry->data.iv); + free (entry); } /* Get the IV at INDEX in STACK. */ @@ -120,9 +166,14 @@ loop_iv_stack_pop (loop_iv_stack stack) static tree loop_iv_stack_get_iv (loop_iv_stack stack, int index) { - name_tree named_iv = VEC_index (name_tree, *stack, index); + iv_stack_entry_p entry = VEC_index (iv_stack_entry_p, *stack, index); + + tree result = NULL; + + if (entry->kind != iv_stack_entry_const) + result = entry->data.iv->t; - return named_iv->t; + return result; } /* Get the IV from its NAME in STACK. */ @@ -131,11 +182,14 @@ static tree loop_iv_stack_get_iv_from_name (loop_iv_stack stack, const char* name) { int i; - name_tree iv; + iv_stack_entry_p entry; - for (i = 0; VEC_iterate (name_tree, *stack, i, iv); i++) - if (!strcmp (name, iv->name)) - return iv->t; + for (i = 0; VEC_iterate (iv_stack_entry_p, *stack, i, entry); i++) + { + name_tree iv = entry->data.iv; + if (!strcmp (name, iv->name)) + return iv->t; + } return NULL; } @@ -143,27 +197,102 @@ loop_iv_stack_get_iv_from_name (loop_iv_stack stack, const char* name) /* Prints on stderr the contents of STACK. */ void -loop_iv_stack_debug (loop_iv_stack stack) +debug_loop_iv_stack (loop_iv_stack stack) { int i; - name_tree iv; + iv_stack_entry_p entry; bool first = true; fprintf (stderr, "("); - for (i = 0; VEC_iterate (name_tree, *stack, i, iv); i++) + for (i = 0; VEC_iterate (iv_stack_entry_p, *stack, i, entry); i++) { if (first) first = false; else fprintf (stderr, " "); - fprintf (stderr, "%s:", iv->name); - print_generic_expr (stderr, iv->t, 0); + + if (iv_stack_entry_is_iv (entry)) + { + name_tree iv = entry->data.iv; + fprintf (stderr, "%s:", iv->name); + print_generic_expr (stderr, iv->t, 0); + } + else + { + tree constant = entry->data.constant; + print_generic_expr (stderr, constant, 0); + fprintf (stderr, ":"); + print_generic_expr (stderr, constant, 0); + } } fprintf (stderr, ")\n"); } +/* Frees STACK. */ + +static void +free_loop_iv_stack (loop_iv_stack stack) +{ + int i; + iv_stack_entry_p entry; + + for (i = 0; VEC_iterate (iv_stack_entry_p, *stack, i, entry); i++) + { + free (entry->data.iv); + free (entry); + } + + VEC_free (iv_stack_entry_p, heap, *stack); +} + +/* Inserts constants derived from the USER_STMT argument list into the + STACK. This is needed to map old ivs to constants when loops have + been eliminated. */ + +static void +loop_iv_stack_patch_for_consts (loop_iv_stack stack, + struct clast_user_stmt *user_stmt) +{ + struct clast_stmt *t; + int index = 0; + for (t = user_stmt->substitutions; t; t = t->next) + { + struct clast_term *term = (struct clast_term*) + ((struct clast_assignment *)t)->RHS; + + /* FIXME: What should be done with expr_bin, expr_red? */ + if (((struct clast_assignment *)t)->RHS->type == expr_term + && !term->var) + { + tree value = gmp_cst_to_tree (term->val); + loop_iv_stack_insert_constant (stack, index, value); + } + index = index + 1; + } +} + +/* Removes all constants in the iv STACK. */ + +static void +loop_iv_stack_remove_constants (loop_iv_stack stack) +{ + int i; + iv_stack_entry *entry; + + for (i = 0; VEC_iterate (iv_stack_entry_p, *stack, i, entry);) + { + if (iv_stack_entry_is_constant (entry)) + { + free (VEC_index (iv_stack_entry_p, *stack, i)); + VEC_ordered_remove (iv_stack_entry_p, *stack, i); + } + else + i++; + } +} + /* In SCOP, get the induction variable from NAME. OLD is the original loop that contained the definition of NAME. */ @@ -939,6 +1068,7 @@ free_scop (scop_p scop) int i; name_tree p; struct graphite_bb *gb; + name_tree iv; for (i = 0; VEC_iterate (graphite_bb_p, SCOP_BBS (scop), i, gb); i++) free_graphite_bb (gb); @@ -947,6 +1077,9 @@ free_scop (scop_p scop) BITMAP_FREE (SCOP_BBS_B (scop)); BITMAP_FREE (SCOP_LOOPS (scop)); VEC_free (loop_p, heap, SCOP_LOOP_NEST (scop)); + + for (i = 0; VEC_iterate (name_tree, SCOP_OLDIVS (scop), i, iv); i++) + free (iv); VEC_free (name_tree, heap, SCOP_OLDIVS (scop)); for (i = 0; VEC_iterate (name_tree, SCOP_PARAMS (scop), i, p); i++) @@ -1688,6 +1821,7 @@ build_scops (void) build_scops_1 (single_succ (ENTRY_BLOCK_PTR), &tmp_scops, loop); create_sese_edges (tmp_scops); build_graphite_scops (tmp_scops); + VEC_free (sd_region, heap, tmp_scops); } /* Gather the basic blocks belonging to the SCOP. */ @@ -2433,7 +2567,7 @@ build_loop_iteration_domains (scop_p scop, struct loop *loop, value_assign (cstr->p[i][j], outer_cstr->p[i][j]); /* Leave an empty column in CSTR for the current loop, and then - copy the parameter columns. */ + copy the parameter columns. */ for (j = loop_col; j < outer_cstr->NbColumns; j++) value_assign (cstr->p[i][j + 1], outer_cstr->p[i][j]); } @@ -2861,10 +2995,10 @@ build_scop_iteration_domain (scop_p scop) -first column: eq/ineq boolean -last column: a constant -scop_nb_params columns for the parameters used in the scop. */ - outer_cstr = cloog_matrix_alloc (0, scop_nb_params (scop) + 2); - build_loop_iteration_domains (scop, loop, outer_cstr, 0); - cloog_matrix_free (outer_cstr); - } + outer_cstr = cloog_matrix_alloc (0, scop_nb_params (scop) + 2); + build_loop_iteration_domains (scop, loop, outer_cstr, 0); + cloog_matrix_free (outer_cstr); + } return (i != 0); } @@ -2988,14 +3122,6 @@ build_scop_data_accesses (scop_p scop) } } -/* Converts a GMP constant value to a tree and returns it. */ - -static tree -gmp_cst_to_tree (Value v) -{ - return build_int_cst (integer_type_node, value_get_si (v)); -} - /* Returns the tree variable from the name NAME that was given in Cloog representation. All the parameters are stored in PARAMS, and all the loop induction variables are stored in IVSTACK. @@ -3250,7 +3376,7 @@ graphite_create_new_loop (scop_p scop, edge entry_edge, &iv_before, outer ? outer : entry_edge->src->loop_father); - loop_iv_stack_push (ivstack, iv_before, stmt->iterator); + loop_iv_stack_push_iv (ivstack, iv_before, stmt->iterator); return loop; } @@ -3347,9 +3473,10 @@ expand_scalar_variables_expr (tree type, tree op0, enum tree_code code, tree op1, graphite_bb_p gbb, scop_p scop, loop_p old_loop_father, loop_iv_stack ivstack) { - if (TREE_CODE_CLASS (code) == tcc_constant - && code == INTEGER_CST) - return op0; + if ((TREE_CODE_CLASS (code) == tcc_constant + && code == INTEGER_CST) + || TREE_CODE_CLASS (code) == tcc_reference) + return op0; if (TREE_CODE_CLASS (code) == tcc_unary) { @@ -3596,8 +3723,11 @@ translate_clast (scop_p scop, struct loop *context_loop, mark_virtual_ops_in_bb (bb); next_e = make_edge (bb, context_loop ? context_loop->latch : EXIT_BLOCK_PTR, - EDGE_FALLTHRU);; + EDGE_FALLTHRU); + loop_iv_stack_patch_for_consts (ivstack, + (struct clast_user_stmt *) stmt); graphite_rename_ivs (gbb, scop, old_loop_father, ivstack); + loop_iv_stack_remove_constants (ivstack); return translate_clast (scop, context_loop, stmt->next, next_e, ivstack); } @@ -3643,6 +3773,22 @@ translate_clast (scop_p scop, struct loop *context_loop, gcc_unreachable (); } +/* Free the SCATTERING domain list. */ + +static void +free_scattering (CloogDomainList *scattering) +{ + while (scattering) + { + CloogDomain *dom = cloog_domain (scattering); + CloogDomainList *next = cloog_next_domain (scattering); + + cloog_domain_free (dom); + free (scattering); + scattering = next; + } +} + /* Build cloog program for SCoP. */ static void @@ -3725,6 +3871,7 @@ build_cloog_prog (scop_p scop) /* Apply scattering. */ cloog_program_scatter (prog, scattering); + free_scattering (scattering); /* Iterators corresponding to scalar dimensions have to be extracted. */ cloog_names_scalarize (cloog_program_names (prog), nbs, @@ -3806,7 +3953,6 @@ debug_clast_stmt (struct clast_stmt *stmt) static struct clast_stmt * find_transform (scop_p scop) { - CloogProgram *prog; struct clast_stmt *stmt; CloogOptions *options = set_cloog_options (); @@ -3820,14 +3966,14 @@ find_transform (scop_p scop) fprintf (dump_file, "]\n"); } - prog = cloog_program_generate (SCOP_PROG (scop), options); - stmt = cloog_clast_create (prog, options); + SCOP_PROG (scop) = cloog_program_generate (SCOP_PROG (scop), options); + stmt = cloog_clast_create (SCOP_PROG (scop), options); if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Cloog Output[\n"); pprint (dump_file, stmt, 0, options); - cloog_program_dump_cloog (dump_file, prog); + cloog_program_dump_cloog (dump_file, SCOP_PROG (scop)); fprintf (dump_file, "]\n"); } @@ -3964,6 +4110,8 @@ patch_phis_for_virtual_defs (void) gsi = gsi_for_stmt (phi); remove_phi_node (&gsi, false); } + + VEC_free (gimple, heap, virtual_phis); } /* Mark the original loops of SCOP for removal, replacing their header @@ -4132,9 +4280,10 @@ gloog (scop_p scop, struct clast_stmt *stmt) { edge new_scop_exit_edge = NULL; basic_block scop_exit = SCOP_EXIT (scop); - VEC (tree, heap)* phi_args = + VEC (tree, heap) *phi_args = collect_scop_exit_phi_args (SESE_EXIT (SCOP_REGION (scop))); - VEC (name_tree, heap) *ivstack = VEC_alloc (name_tree, heap, 10); + VEC (iv_stack_entry_p, heap) *ivstack = + VEC_alloc (iv_stack_entry_p, heap, 10); edge construction_edge = SESE_ENTRY (SCOP_REGION (scop)); basic_block old_scop_exit_idom = get_immediate_dominator (CDI_DOMINATORS, scop_exit); @@ -4145,10 +4294,13 @@ gloog (scop_p scop, struct clast_stmt *stmt) return; } + redirect_edge_succ_nodup (construction_edge, EXIT_BLOCK_PTR); new_scop_exit_edge = translate_clast (scop, construction_edge->src->loop_father, stmt, construction_edge, &ivstack); + free_loop_iv_stack (&ivstack); redirect_edge_succ (new_scop_exit_edge, scop_exit); + if (!old_scop_exit_idom || !dominated_by_p (CDI_DOMINATORS, SCOP_ENTRY (scop), old_scop_exit_idom) @@ -4165,6 +4317,7 @@ gloog (scop_p scop, struct clast_stmt *stmt) delete_unreachable_blocks (); patch_phis_for_virtual_defs (); patch_scop_exit_phi_args (new_scop_exit_edge, phi_args); + VEC_free (tree, heap, phi_args); mark_old_loops (scop); remove_dead_loops (); rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); @@ -4416,7 +4569,6 @@ static void get_lower_bound (CloogMatrix *domain, int loop, Value lower_bound_result) { int lower_bound_row = get_lower_bound_row (domain, loop); - value_init (lower_bound_result); value_assign (lower_bound_result, domain->p[lower_bound_row][const_column_index(domain)]); } @@ -4427,7 +4579,6 @@ static void get_upper_bound (CloogMatrix *domain, int loop, Value upper_bound_result) { int upper_bound_row = get_upper_bound_row (domain, loop); - value_init (upper_bound_result); value_assign (upper_bound_result, domain->p[upper_bound_row][const_column_index(domain)]); } @@ -4450,7 +4601,6 @@ graphite_trans_bb_strip_mine (graphite_bb_p gb, int loop_depth, int stride) Value old_lower_bound; Value old_upper_bound; - gcc_assert (loop_depth <= gbb_nb_loops (gb) - 1); VEC_safe_insert (loop_p, heap, GBB_LOOPS (gb), loop_depth, NULL); @@ -4470,13 +4620,9 @@ graphite_trans_bb_strip_mine (graphite_bb_p gb, int loop_depth, int stride) for (row = 0; row < domain->NbRows; row++) for (col = 0; col < domain->NbColumns; col++) if (col <= loop_depth) - { - value_assign (new_domain->p[row][col], domain->p[row][col]); - } + value_assign (new_domain->p[row][col], domain->p[row][col]); else - { - value_assign (new_domain->p[row][col + 1], domain->p[row][col]); - } + value_assign (new_domain->p[row][col + 1], domain->p[row][col]); /* @@ -4495,7 +4641,8 @@ graphite_trans_bb_strip_mine (graphite_bb_p gb, int loop_depth, int stride) row = domain->NbRows; /* Add outer loop. */ - + value_init (old_lower_bound); + value_init (old_upper_bound); get_lower_bound (new_domain, col_loop_old, old_lower_bound); get_upper_bound (new_domain, col_loop_old, old_upper_bound); @@ -4504,6 +4651,7 @@ graphite_trans_bb_strip_mine (graphite_bb_p gb, int loop_depth, int stride) value_set_si (new_domain->p[row][col_loop_strip], 1); value_assign (new_domain->p[row][const_column_index (new_domain)], old_lower_bound); + value_clear (old_lower_bound); row++; @@ -4524,12 +4672,10 @@ graphite_trans_bb_strip_mine (graphite_bb_p gb, int loop_depth, int stride) Value strip_size_value; value_init (new_upper_bound); - value_init (strip_size_value); value_set_si (strip_size_value, (int) stride); - - value_pdivision(new_upper_bound,old_upper_bound,strip_size_value); + value_pdivision (new_upper_bound, old_upper_bound, strip_size_value); value_add_int (new_upper_bound, new_upper_bound, 1); /* Set Upper Bound */ @@ -4537,6 +4683,10 @@ graphite_trans_bb_strip_mine (graphite_bb_p gb, int loop_depth, int stride) value_set_si (new_domain->p[row][col_loop_strip], -1); value_assign (new_domain->p[row][const_column_index (new_domain)], new_upper_bound); + + value_clear (strip_size_value); + value_clear (old_upper_bound); + value_clear (new_upper_bound); row++; } /* @@ -4983,6 +5133,7 @@ limit_scops (void) create_sese_edges (tmp_scops); build_graphite_scops (tmp_scops); + VEC_free (sd_region, heap, tmp_scops); } /* Perform a set of linear transforms on the loops of the current |