diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-19 18:19:39 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-19 18:19:39 +0000 |
commit | e56043cd2c207982e812ce6fcecb7353dea58363 (patch) | |
tree | 01a6f37ad5a9ae6b18bdc20f052b04e19b4255c0 /gcc/tree-ssa-live.c | |
parent | 2e02a1a4548f2ee1ea519c88e68b20621ad16fcc (diff) | |
download | gcc-e56043cd2c207982e812ce6fcecb7353dea58363.tar.gz |
2010-09-19 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 164348, with some improvements
in gcc/melt-runtime.[ch]
2010-09-19 Basile Starynkevitch <basile@starynkevitch.net>
[[merged with trunk rev.164348, so improved MELT runtime!]]
* gcc/melt-runtime.h: improved comments.
(melt_debug_garbcoll, melt_debuggc_eprintf): Moved from melt-runtime.c.
(melt_obmag_string): New declaration.
(struct meltobject_st, struct meltclosure_st, struct
meltroutine_st, struct meltmixbigint_st, struct meltstring_st):
using GTY variable_size and @@MELTGTY@@ comment.
(melt_mark_special): added debug print.
* gcc/melt-runtime.c: Improved comments.
Include bversion.h, realmpfr.h, gimple-pretty-print.h.
(ggc_force_collect) Declared external.
(melt_forward_counter): Added.
(melt_obmag_string): New function.
(melt_alptr_1, melt_alptr_2, melt_break_alptr_1_at)
(melt_break_alptr_2_at, melt_break_alptr_1,melt_break_alptr_1)
(melt_allocate_young_gc_zone, melt_free_young_gc_zone): New.
(delete_special, meltgc_make_special): Improved debug printf and
use melt_break_alptr_1...
(ggc_alloc_*) macros defined for backport to GCC 4.5
(melt_forwarded_copy): Don't clear the new destination zone in old
GGC heap.
(meltgc_add_out_raw_len): Use ggc_alloc_atomic.
(meltgc_raw_new_mappointers, meltgc_raw_put_mappointers)
(meltgc_raw_remove_mappointers): Corrected length argument to
ggc_alloc_cleared_vec_entrypointermelt_st.
(melt_really_initialize): Call melt_allocate_young_gc_zone.
(melt_initialize): Set flag_plugin_added.
(melt_val2passflag): TODO_verify_loops only in GCC 4.5
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@164424 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-live.c')
-rw-r--r-- | gcc/tree-ssa-live.c | 211 |
1 files changed, 161 insertions, 50 deletions
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c index c0ccb4fe20d..715b5a71c07 100644 --- a/gcc/tree-ssa-live.c +++ b/gcc/tree-ssa-live.c @@ -1,6 +1,6 @@ /* Liveness for SSA trees. - Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, - Inc. + Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. Contributed by Andrew MacLeod <amacleod@redhat.com> This file is part of GCC. @@ -24,14 +24,17 @@ along with GCC; see the file COPYING3. If not see #include "coretypes.h" #include "tm.h" #include "tree.h" -#include "diagnostic.h" +#include "tree-pretty-print.h" +#include "gimple-pretty-print.h" #include "bitmap.h" #include "tree-flow.h" #include "tree-dump.h" #include "tree-ssa-live.h" +#include "diagnostic-core.h" #include "toplev.h" #include "debug.h" #include "flags.h" +#include "gimple.h" #ifdef ENABLE_CHECKING static void verify_live_on_entry (tree_live_info_p); @@ -359,13 +362,13 @@ mark_all_vars_used_1 (tree *tp, int *walk_subtrees, void *data) && (b = TREE_BLOCK (t)) != NULL) TREE_USED (b) = true; - /* Ignore TREE_ORIGINAL for TARGET_MEM_REFS, as well as other - fields that do not contain vars. */ + /* Ignore TMR_OFFSET and TMR_STEP for TARGET_MEM_REFS, as those + fields do not contain vars. */ if (TREE_CODE (t) == TARGET_MEM_REF) { - mark_all_vars_used (&TMR_SYMBOL (t), data); mark_all_vars_used (&TMR_BASE (t), data); mark_all_vars_used (&TMR_INDEX (t), data); + mark_all_vars_used (&TMR_INDEX2 (t), data); *walk_subtrees = 0; return NULL; } @@ -374,13 +377,18 @@ mark_all_vars_used_1 (tree *tp, int *walk_subtrees, void *data) eliminated as unused. */ if (TREE_CODE (t) == VAR_DECL) { - if (data != NULL && bitmap_bit_p ((bitmap) data, DECL_UID (t))) - { - bitmap_clear_bit ((bitmap) data, DECL_UID (t)); - mark_all_vars_used (&DECL_INITIAL (t), data); - } + if (data != NULL && bitmap_clear_bit ((bitmap) data, DECL_UID (t))) + mark_all_vars_used (&DECL_INITIAL (t), data); set_is_used (t); } + /* remove_unused_scope_block_p requires information about labels + which are not DECL_IGNORED_P to tell if they might be used in the IL. */ + if (TREE_CODE (t) == LABEL_DECL) + /* Although the TREE_USED values that the frontend uses would be + acceptable (albeit slightly over-conservative) for our purposes, + init_vars_expansion clears TREE_USED for LABEL_DECLs too, so we + must re-compute it here. */ + TREE_USED (t) = 1; if (IS_TYPE_OR_DECL_P (t)) *walk_subtrees = 0; @@ -425,7 +433,7 @@ remove_unused_scope_block_p (tree scope) for (t = &BLOCK_VARS (scope); *t; t = next) { - next = &TREE_CHAIN (*t); + next = &DECL_CHAIN (*t); /* Debug info of nested function refers to the block of the function. We might stil call it even if all statements @@ -449,7 +457,7 @@ remove_unused_scope_block_p (tree scope) /* Remove everything we don't generate debug info for. */ else if (DECL_IGNORED_P (*t)) { - *t = TREE_CHAIN (*t); + *t = DECL_CHAIN (*t); next = t; } @@ -460,6 +468,19 @@ remove_unused_scope_block_p (tree scope) else if ((ann = var_ann (*t)) != NULL && ann->used) unused = false; + else if (TREE_CODE (*t) == LABEL_DECL && TREE_USED (*t)) + /* For labels that are still used in the IL, the decision to + preserve them must not depend DEBUG_INFO_LEVEL, otherwise we + risk having different ordering in debug vs. non-debug builds + during inlining or versioning. + A label appearing here (we have already checked DECL_IGNORED_P) + should not be used in the IL unless it has been explicitly used + before, so we use TREE_USED as an approximation. */ + /* In principle, we should do the same here as for the debug case + below, however, when debugging, there might be additional nested + levels that keep an upper level with a label live, so we have to + force this block to be considered used, too. */ + unused = false; /* When we are not doing full debug info, we however can keep around only the used variables for cfgexpand's memory packing saving quite @@ -479,7 +500,7 @@ remove_unused_scope_block_p (tree scope) ; else { - *t = TREE_CHAIN (*t); + *t = DECL_CHAIN (*t); next = t; } } @@ -602,7 +623,7 @@ dump_scope_block (FILE *file, int indent, tree scope, int flags) } } fprintf (file, " \n"); - for (var = BLOCK_VARS (scope); var; var = TREE_CHAIN (var)) + for (var = BLOCK_VARS (scope); var; var = DECL_CHAIN (var)) { bool used = false; var_ann_t ann; @@ -630,7 +651,7 @@ dump_scope_block (FILE *file, int indent, tree scope, int flags) /* Dump the tree of lexical scopes starting at SCOPE to stderr. FLAGS is as in print_generic_expr. */ -void +DEBUG_FUNCTION void debug_scope_block (tree scope, int flags) { dump_scope_block (stderr, 0, scope, flags); @@ -650,7 +671,7 @@ dump_scope_blocks (FILE *file, int flags) /* Dump the tree of lexical scopes of current_function_decl to stderr. FLAGS is as in print_generic_expr. */ -void +DEBUG_FUNCTION void debug_scope_blocks (int flags) { dump_scope_blocks (stderr, flags); @@ -662,10 +683,11 @@ void remove_unused_locals (void) { basic_block bb; - tree t, *cell; + tree var, t; referenced_var_iterator rvi; var_ann_t ann; bitmap global_unused_vars = NULL; + unsigned srcidx, dstidx, num; /* Removing declarations from lexical blocks when not optimizing is not only a waste of time, it actually causes differences in stack @@ -732,10 +754,10 @@ remove_unused_locals (void) cfun->has_local_explicit_reg_vars = false; /* Remove unmarked local vars from local_decls. */ - for (cell = &cfun->local_decls; *cell; ) + num = VEC_length (tree, cfun->local_decls); + for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++) { - tree var = TREE_VALUE (*cell); - + var = VEC_index (tree, cfun->local_decls, srcidx); if (TREE_CODE (var) != FUNCTION_DECL && (!(ann = var_ann (var)) || !ann->used)) @@ -747,58 +769,57 @@ remove_unused_locals (void) bitmap_set_bit (global_unused_vars, DECL_UID (var)); } else - { - *cell = TREE_CHAIN (*cell); - continue; - } + continue; } else if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var) && !is_global_var (var)) cfun->has_local_explicit_reg_vars = true; - cell = &TREE_CHAIN (*cell); + + if (srcidx != dstidx) + VEC_replace (tree, cfun->local_decls, dstidx, var); + dstidx++; } + if (dstidx != num) + VEC_truncate (tree, cfun->local_decls, dstidx); /* Remove unmarked global vars from local_decls. */ if (global_unused_vars != NULL) { - for (t = cfun->local_decls; t; t = TREE_CHAIN (t)) - { - tree var = TREE_VALUE (t); - - if (TREE_CODE (var) == VAR_DECL - && is_global_var (var) - && (ann = var_ann (var)) != NULL - && ann->used) - mark_all_vars_used (&DECL_INITIAL (var), global_unused_vars); - } - - for (cell = &cfun->local_decls; *cell; ) + tree var; + unsigned ix; + FOR_EACH_LOCAL_DECL (cfun, ix, var) + if (TREE_CODE (var) == VAR_DECL + && is_global_var (var) + && (ann = var_ann (var)) != NULL + && ann->used) + mark_all_vars_used (&DECL_INITIAL (var), global_unused_vars); + + num = VEC_length (tree, cfun->local_decls); + for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++) { - tree var = TREE_VALUE (*cell); - + var = VEC_index (tree, cfun->local_decls, srcidx); if (TREE_CODE (var) == VAR_DECL && is_global_var (var) && bitmap_bit_p (global_unused_vars, DECL_UID (var))) - *cell = TREE_CHAIN (*cell); - else - cell = &TREE_CHAIN (*cell); + continue; + + if (srcidx != dstidx) + VEC_replace (tree, cfun->local_decls, dstidx, var); + dstidx++; } + if (dstidx != num) + VEC_truncate (tree, cfun->local_decls, dstidx); BITMAP_FREE (global_unused_vars); } - /* Remove unused variables from REFERENCED_VARs. As a special - exception keep the variables that are believed to be aliased. - Those can't be easily removed from the alias sets and operand - caches. They will be removed shortly after the next may_alias - pass is performed. */ + /* Remove unused variables from REFERENCED_VARs. */ FOR_EACH_REFERENCED_VAR (t, rvi) if (!is_global_var (t) && TREE_CODE (t) != PARM_DECL && TREE_CODE (t) != RESULT_DECL && !(ann = var_ann (t))->used - && !ann->is_heapvar - && !TREE_ADDRESSABLE (t)) + && !ann->is_heapvar) remove_referenced_var (t); remove_unused_scope_block_p (DECL_INITIAL (current_function_decl)); if (dump_file && (dump_flags & TDF_DETAILS)) @@ -1168,6 +1189,96 @@ dump_live_info (FILE *f, tree_live_info_p live, int flag) } } +struct GTY(()) numbered_tree_d +{ + tree t; + int num; +}; +typedef struct numbered_tree_d numbered_tree; + +DEF_VEC_O (numbered_tree); +DEF_VEC_ALLOC_O (numbered_tree, heap); + +/* Compare two declarations references by their DECL_UID / sequence number. + Called via qsort. */ + +static int +compare_decls_by_uid (const void *pa, const void *pb) +{ + const numbered_tree *nt_a = ((const numbered_tree *)pa); + const numbered_tree *nt_b = ((const numbered_tree *)pb); + + if (DECL_UID (nt_a->t) != DECL_UID (nt_b->t)) + return DECL_UID (nt_a->t) - DECL_UID (nt_b->t); + return nt_a->num - nt_b->num; +} + +/* Called via walk_gimple_stmt / walk_gimple_op by dump_enumerated_decls. */ +static tree +dump_enumerated_decls_push (tree *tp, int *walk_subtrees, void *data) +{ + struct walk_stmt_info *wi = (struct walk_stmt_info *) data; + VEC (numbered_tree, heap) **list = (VEC (numbered_tree, heap) **) &wi->info; + numbered_tree nt; + + if (!DECL_P (*tp)) + return NULL_TREE; + nt.t = *tp; + nt.num = VEC_length (numbered_tree, *list); + VEC_safe_push (numbered_tree, heap, *list, &nt); + *walk_subtrees = 0; + return NULL_TREE; +} + +/* Find all the declarations used by the current function, sort them by uid, + and emit the sorted list. Each declaration is tagged with a sequence + number indicating when it was found during statement / tree walking, + so that TDF_NOUID comparisons of anonymous declarations are still + meaningful. Where a declaration was encountered more than once, we + emit only the sequence number of the first encounter. + FILE is the dump file where to output the list and FLAGS is as in + print_generic_expr. */ +void +dump_enumerated_decls (FILE *file, int flags) +{ + basic_block bb; + struct walk_stmt_info wi; + VEC (numbered_tree, heap) *decl_list = VEC_alloc (numbered_tree, heap, 40); + + memset (&wi, '\0', sizeof (wi)); + wi.info = (void*) decl_list; + FOR_EACH_BB (bb) + { + gimple_stmt_iterator gsi; + + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + if (!is_gimple_debug (gsi_stmt (gsi))) + walk_gimple_stmt (&gsi, NULL, dump_enumerated_decls_push, &wi); + } + decl_list = (VEC (numbered_tree, heap) *) wi.info; + qsort (VEC_address (numbered_tree, decl_list), + VEC_length (numbered_tree, decl_list), + sizeof (numbered_tree), compare_decls_by_uid); + if (VEC_length (numbered_tree, decl_list)) + { + unsigned ix; + numbered_tree *ntp; + tree last = NULL_TREE; + + fprintf (file, "Declarations used by %s, sorted by DECL_UID:\n", + current_function_name ()); + FOR_EACH_VEC_ELT (numbered_tree, decl_list, ix, ntp) + { + if (ntp->t == last) + continue; + fprintf (file, "%d: ", ntp->num); + print_generic_decl (file, ntp->t, flags); + fprintf (file, "\n"); + last = ntp->t; + } + } + VEC_free (numbered_tree, heap, decl_list); +} #ifdef ENABLE_CHECKING /* Verify that SSA_VAR is a non-virtual SSA_NAME. */ |