re PR middle-end/32018 (ICE on optimization)
PR middle-end/32018 * tree-ssa-threadupdate.c (thread_through_loop_header): Use set_loop_copy. (thread_through_all_blocks): Call initialize_original_copy_tables and free_original_copy_tables. * cfgloopmanip.c (duplicate_loop, duplicate_loop_to_header_edge): Use set_loop_copy. * tree-cfg.c (tree_duplicate_sese_region): Ditto. * cfghooks.c (duplicate_block): Use get_loop_copy. * cfg.c: Include cfgloop.h. (loop_copy): New hash table. (initialize_original_copy_tables): Initialize loop_copy table. (free_original_copy_tables): Free loop_copy table. (copy_original_table_clear, copy_original_table_set, set_loop_copy, get_loop_copy): New functions. (set_bb_original, set_bb_copy): Use copy_original_table_set. * cfgloop.h (struct loop): Remove copy field. * Makefile.in (cfg.o): Add CFGLOOP_H dependency. * basic-block.h (set_loop_copy, get_loop_copy): Declare. From-SVN: r125024
This commit is contained in:
parent
66da42bc85
commit
561e8a90fd
9 changed files with 121 additions and 52 deletions
|
@ -1,3 +1,25 @@
|
|||
2007-05-24 Zdenek Dvorak <dvorakz@suse.cz>
|
||||
|
||||
PR middle-end/32018
|
||||
* tree-ssa-threadupdate.c (thread_through_loop_header): Use
|
||||
set_loop_copy.
|
||||
(thread_through_all_blocks): Call initialize_original_copy_tables
|
||||
and free_original_copy_tables.
|
||||
* cfgloopmanip.c (duplicate_loop, duplicate_loop_to_header_edge):
|
||||
Use set_loop_copy.
|
||||
* tree-cfg.c (tree_duplicate_sese_region): Ditto.
|
||||
* cfghooks.c (duplicate_block): Use get_loop_copy.
|
||||
* cfg.c: Include cfgloop.h.
|
||||
(loop_copy): New hash table.
|
||||
(initialize_original_copy_tables): Initialize loop_copy table.
|
||||
(free_original_copy_tables): Free loop_copy table.
|
||||
(copy_original_table_clear, copy_original_table_set,
|
||||
set_loop_copy, get_loop_copy): New functions.
|
||||
(set_bb_original, set_bb_copy): Use copy_original_table_set.
|
||||
* cfgloop.h (struct loop): Remove copy field.
|
||||
* Makefile.in (cfg.o): Add CFGLOOP_H dependency.
|
||||
* basic-block.h (set_loop_copy, get_loop_copy): Declare.
|
||||
|
||||
2007-05-24 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
* config/i386/i386.c (ix86_handle_option): Handle SSE4.1 for
|
||||
|
|
|
@ -2517,7 +2517,8 @@ flow.o : flow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
|||
$(EXPR_H) $(TM_P_H) $(OBSTACK_H) $(SPLAY_TREE_H) $(TIMEVAR_H) tree-pass.h
|
||||
cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(FLAGS_H) \
|
||||
$(REGS_H) hard-reg-set.h output.h toplev.h $(FUNCTION_H) except.h $(GGC_H) \
|
||||
$(TM_P_H) $(TIMEVAR_H) $(OBSTACK_H) $(TREE_H) alloc-pool.h $(HASHTAB_H)
|
||||
$(TM_P_H) $(TIMEVAR_H) $(OBSTACK_H) $(TREE_H) alloc-pool.h $(HASHTAB_H) \
|
||||
$(CFGLOOP_H)
|
||||
cfghooks.o: cfghooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
|
||||
$(TREE_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(TIMEVAR_H) toplev.h $(CFGLOOP_H)
|
||||
cfgexpand.o : cfgexpand.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
|
||||
|
|
|
@ -988,6 +988,9 @@ extern void set_bb_original (basic_block, basic_block);
|
|||
extern basic_block get_bb_original (basic_block);
|
||||
extern void set_bb_copy (basic_block, basic_block);
|
||||
extern basic_block get_bb_copy (basic_block);
|
||||
void set_loop_copy (struct loop *, struct loop *);
|
||||
struct loop *get_loop_copy (struct loop *);
|
||||
|
||||
|
||||
extern rtx insert_insn_end_bb_new (rtx, basic_block);
|
||||
|
||||
|
|
119
gcc/cfg.c
119
gcc/cfg.c
|
@ -66,6 +66,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
|
|||
#include "ggc.h"
|
||||
#include "hashtab.h"
|
||||
#include "alloc-pool.h"
|
||||
#include "cfgloop.h"
|
||||
|
||||
/* The obstack on which the flow graph components are allocated. */
|
||||
|
||||
|
@ -1027,6 +1028,9 @@ scale_bbs_frequencies_gcov_type (basic_block *bbs, int nbbs, gcov_type num,
|
|||
copies. */
|
||||
static htab_t bb_original;
|
||||
static htab_t bb_copy;
|
||||
|
||||
/* And between loops and copies. */
|
||||
static htab_t loop_copy;
|
||||
static alloc_pool original_copy_bb_pool;
|
||||
|
||||
struct htab_bb_copy_original_entry
|
||||
|
@ -1068,6 +1072,7 @@ initialize_original_copy_tables (void)
|
|||
bb_original = htab_create (10, bb_copy_original_hash,
|
||||
bb_copy_original_eq, NULL);
|
||||
bb_copy = htab_create (10, bb_copy_original_hash, bb_copy_original_eq, NULL);
|
||||
loop_copy = htab_create (10, bb_copy_original_hash, bb_copy_original_eq, NULL);
|
||||
}
|
||||
|
||||
/* Free the data structures to maintain mapping between blocks and
|
||||
|
@ -1078,35 +1083,64 @@ free_original_copy_tables (void)
|
|||
gcc_assert (original_copy_bb_pool);
|
||||
htab_delete (bb_copy);
|
||||
htab_delete (bb_original);
|
||||
htab_delete (loop_copy);
|
||||
free_alloc_pool (original_copy_bb_pool);
|
||||
bb_copy = NULL;
|
||||
bb_original = NULL;
|
||||
loop_copy = NULL;
|
||||
original_copy_bb_pool = NULL;
|
||||
}
|
||||
|
||||
/* Removes the value associated with OBJ from table TAB. */
|
||||
|
||||
static void
|
||||
copy_original_table_clear (htab_t tab, unsigned obj)
|
||||
{
|
||||
void **slot;
|
||||
struct htab_bb_copy_original_entry key, *elt;
|
||||
|
||||
if (!original_copy_bb_pool)
|
||||
return;
|
||||
|
||||
key.index1 = obj;
|
||||
slot = htab_find_slot (tab, &key, NO_INSERT);
|
||||
if (!slot)
|
||||
return;
|
||||
|
||||
elt = *slot;
|
||||
htab_clear_slot (tab, slot);
|
||||
pool_free (original_copy_bb_pool, elt);
|
||||
}
|
||||
|
||||
/* Sets the value associated with OBJ in table TAB to VAL.
|
||||
Do nothing when data structures are not initialized. */
|
||||
|
||||
static void
|
||||
copy_original_table_set (htab_t tab, unsigned obj, unsigned val)
|
||||
{
|
||||
struct htab_bb_copy_original_entry **slot;
|
||||
struct htab_bb_copy_original_entry key;
|
||||
|
||||
if (!original_copy_bb_pool)
|
||||
return;
|
||||
|
||||
key.index1 = obj;
|
||||
slot = (struct htab_bb_copy_original_entry **)
|
||||
htab_find_slot (tab, &key, INSERT);
|
||||
if (!*slot)
|
||||
{
|
||||
*slot = pool_alloc (original_copy_bb_pool);
|
||||
(*slot)->index1 = obj;
|
||||
}
|
||||
(*slot)->index2 = val;
|
||||
}
|
||||
|
||||
/* Set original for basic block. Do nothing when data structures are not
|
||||
initialized so passes not needing this don't need to care. */
|
||||
void
|
||||
set_bb_original (basic_block bb, basic_block original)
|
||||
{
|
||||
if (original_copy_bb_pool)
|
||||
{
|
||||
struct htab_bb_copy_original_entry **slot;
|
||||
struct htab_bb_copy_original_entry key;
|
||||
|
||||
key.index1 = bb->index;
|
||||
slot =
|
||||
(struct htab_bb_copy_original_entry **) htab_find_slot (bb_original,
|
||||
&key, INSERT);
|
||||
if (*slot)
|
||||
(*slot)->index2 = original->index;
|
||||
else
|
||||
{
|
||||
*slot = pool_alloc (original_copy_bb_pool);
|
||||
(*slot)->index1 = bb->index;
|
||||
(*slot)->index2 = original->index;
|
||||
}
|
||||
}
|
||||
copy_original_table_set (bb_original, bb->index, original->index);
|
||||
}
|
||||
|
||||
/* Get the original basic block. */
|
||||
|
@ -1131,24 +1165,7 @@ get_bb_original (basic_block bb)
|
|||
void
|
||||
set_bb_copy (basic_block bb, basic_block copy)
|
||||
{
|
||||
if (original_copy_bb_pool)
|
||||
{
|
||||
struct htab_bb_copy_original_entry **slot;
|
||||
struct htab_bb_copy_original_entry key;
|
||||
|
||||
key.index1 = bb->index;
|
||||
slot =
|
||||
(struct htab_bb_copy_original_entry **) htab_find_slot (bb_copy,
|
||||
&key, INSERT);
|
||||
if (*slot)
|
||||
(*slot)->index2 = copy->index;
|
||||
else
|
||||
{
|
||||
*slot = pool_alloc (original_copy_bb_pool);
|
||||
(*slot)->index1 = bb->index;
|
||||
(*slot)->index2 = copy->index;
|
||||
}
|
||||
}
|
||||
copy_original_table_set (bb_copy, bb->index, copy->index);
|
||||
}
|
||||
|
||||
/* Get the copy of basic block. */
|
||||
|
@ -1167,3 +1184,33 @@ get_bb_copy (basic_block bb)
|
|||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set copy for LOOP to COPY. Do nothing when data structures are not
|
||||
initialized so passes not needing this don't need to care. */
|
||||
|
||||
void
|
||||
set_loop_copy (struct loop *loop, struct loop *copy)
|
||||
{
|
||||
if (!copy)
|
||||
copy_original_table_clear (loop_copy, loop->num);
|
||||
else
|
||||
copy_original_table_set (loop_copy, loop->num, copy->num);
|
||||
}
|
||||
|
||||
/* Get the copy of LOOP. */
|
||||
|
||||
struct loop *
|
||||
get_loop_copy (struct loop *loop)
|
||||
{
|
||||
struct htab_bb_copy_original_entry *entry;
|
||||
struct htab_bb_copy_original_entry key;
|
||||
|
||||
gcc_assert (original_copy_bb_pool);
|
||||
|
||||
key.index1 = loop->num;
|
||||
entry = (struct htab_bb_copy_original_entry *) htab_find (loop_copy, &key);
|
||||
if (entry)
|
||||
return get_loop (entry->index2);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -928,9 +928,8 @@ duplicate_block (basic_block bb, edge e, basic_block after)
|
|||
if (current_loops != NULL)
|
||||
{
|
||||
struct loop *cloop = bb->loop_father;
|
||||
if (cloop->copy)
|
||||
cloop = cloop->copy;
|
||||
add_bb_to_loop (new_bb, cloop);
|
||||
struct loop *copy = get_loop_copy (cloop);
|
||||
add_bb_to_loop (new_bb, copy ? copy : cloop);
|
||||
}
|
||||
|
||||
return new_bb;
|
||||
|
|
|
@ -123,9 +123,6 @@ struct loop GTY ((chain_next ("%h.next")))
|
|||
/* Link to the next (sibling) loop. */
|
||||
struct loop *next;
|
||||
|
||||
/* Loop that is copy of this loop. */
|
||||
struct loop *copy;
|
||||
|
||||
/* Auxiliary info specific to a pass. */
|
||||
PTR GTY ((skip (""))) aux;
|
||||
|
||||
|
|
|
@ -653,7 +653,7 @@ duplicate_loop (struct loop *loop, struct loop *target)
|
|||
place_new_loop (cloop);
|
||||
|
||||
/* Mark the new loop as copy of LOOP. */
|
||||
loop->copy = cloop;
|
||||
set_loop_copy (loop, cloop);
|
||||
|
||||
/* Add it to target. */
|
||||
flow_loop_tree_node_add (target, cloop);
|
||||
|
@ -917,7 +917,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e,
|
|||
for (aloop = loop->inner, i = 0; aloop; aloop = aloop->next, i++)
|
||||
orig_loops[i] = aloop;
|
||||
|
||||
loop->copy = target;
|
||||
set_loop_copy (loop, target);
|
||||
|
||||
first_active = XNEWVEC (basic_block, n);
|
||||
if (is_latch)
|
||||
|
|
|
@ -4360,14 +4360,14 @@ tree_duplicate_sese_region (edge entry, edge exit,
|
|||
return false;
|
||||
}
|
||||
|
||||
loop->copy = loop;
|
||||
set_loop_copy (loop, loop);
|
||||
|
||||
/* In case the function is used for loop header copying (which is the primary
|
||||
use), ensure that EXIT and its copy will be new latch and entry edges. */
|
||||
if (loop->header == entry->dest)
|
||||
{
|
||||
copying_header = true;
|
||||
loop->copy = loop_outer (loop);
|
||||
set_loop_copy (loop, loop_outer (loop));
|
||||
|
||||
if (!dominated_by_p (CDI_DOMINATORS, loop->latch, exit->src))
|
||||
return false;
|
||||
|
|
|
@ -918,10 +918,10 @@ thread_through_loop_header (struct loop *loop, bool may_peel_loop_headers)
|
|||
|
||||
/* The duplicate of the header is the new preheader of the loop. Ensure
|
||||
that it is placed correctly in the loop hierarchy. */
|
||||
loop->copy = loop_outer (loop);
|
||||
set_loop_copy (loop, loop_outer (loop));
|
||||
|
||||
thread_block (header, false);
|
||||
loop->copy = NULL;
|
||||
set_loop_copy (loop, NULL);
|
||||
new_preheader = e->dest;
|
||||
|
||||
/* Create the new latch block. This is always necessary, as the latch
|
||||
|
@ -1031,9 +1031,7 @@ thread_through_all_blocks (bool may_peel_loop_headers)
|
|||
|
||||
mark_threaded_blocks (threaded_blocks);
|
||||
|
||||
if (current_loops)
|
||||
FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
|
||||
loop->copy = NULL;
|
||||
initialize_original_copy_tables ();
|
||||
|
||||
/* First perform the threading requests that do not affect
|
||||
loop structure. */
|
||||
|
@ -1067,6 +1065,8 @@ thread_through_all_blocks (bool may_peel_loop_headers)
|
|||
fprintf (dump_file, "\nJumps threaded: %lu\n",
|
||||
thread_stats.num_threaded_edges);
|
||||
|
||||
free_original_copy_tables ();
|
||||
|
||||
BITMAP_FREE (threaded_blocks);
|
||||
threaded_blocks = NULL;
|
||||
VEC_free (edge, heap, threaded_edges);
|
||||
|
|
Loading…
Add table
Reference in a new issue