aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Froyd <froydnj@codesourcery.com>2007-12-22 18:50:44 +0000
committerNathan Froyd <froydnj@codesourcery.com>2007-12-22 18:50:44 +0000
commitf8a741aab3159ca00514fa2c09af6489a96e35fe (patch)
tree2d0680ca3de125d9cfb789346a425b2ce62526fa
parentfcb7b820dcee423e722c27e67c387cacf7557f48 (diff)
gcc/
* dwarf2out.c (force_decl_die): Unset the DECL_IGNORED_P flag if we are called from LTO. Remove the DW_AT_declaration flag if the decl has an initial value. * lto-function-out.c (output_expr_operand): Add explicit check for statics or externs rathen than use DECL_CONTEXT. (output_local_vars): Serialize the DECL_INITIAL field of local statics and add it the unexpanded_vars_list as necessary. gcc/lto/ * lto-read.c (input_expr_operand): Fixed uninitialize var warning. (input_local_vars): Read in DECL_INITIAL and context for local statics that need to be put in unexpanded_vars_list. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/lto@131137 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog.lto11
-rw-r--r--gcc/dwarf2out.c20
-rw-r--r--gcc/lto-function-out.c55
-rw-r--r--gcc/lto/ChangeLog7
-rw-r--r--gcc/lto/lto-read.c40
5 files changed, 116 insertions, 17 deletions
diff --git a/gcc/ChangeLog.lto b/gcc/ChangeLog.lto
index e7ff78a4fe6..18979370a9b 100644
--- a/gcc/ChangeLog.lto
+++ b/gcc/ChangeLog.lto
@@ -1,3 +1,14 @@
+2007-12-22 Nathan Froyd <froydnj@codesourcery.com>
+ Kenneth Zadeck <zadeck@naturalbridge.com>
+
+ * dwarf2out.c (force_decl_die): Unset the DECL_IGNORED_P flag if
+ we are called from LTO. Remove the DW_AT_declaration flag if the
+ decl has an initial value.
+ * lto-function-out.c (output_expr_operand): Add explicit check
+ for statics or externs rathen than use DECL_CONTEXT.
+ (output_local_vars): Serialize the DECL_INITIAL field of local
+ statics and add it the unexpanded_vars_list as necessary.
+
2007-12-19 Doug Kwan <dougkwan@google.com>
* dwarf2out.c (base_type_de): Use DW_ATE_GNU_complex_unsigned
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index e2429ce840a..1c2d89e5e0b 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -13538,6 +13538,7 @@ force_decl_die (tree decl)
{
dw_die_ref decl_die;
unsigned saved_external_flag;
+ unsigned saved_ignored_flag;
tree save_fn = NULL_TREE;
decl_die = lookup_decl_die (decl);
if (!decl_die)
@@ -13571,11 +13572,21 @@ force_decl_die (tree decl)
}
else
{
- /* Set external flag to force declaration die. Restore it after
- gen_decl_die() call. */
+ /* Set external flag to force declaration die, thereby
+ associating the decl with the generated die. Unset the
+ ignored flag if we are running from LTO and are thereby
+ forcing everything we can. Restore these flags after
+ the gen_decl_die() call. */
saved_external_flag = DECL_EXTERNAL (decl);
+ if (dwarf2_called_from_lto_p)
+ {
+ saved_ignored_flag = DECL_IGNORED_P (decl);
+ DECL_IGNORED_P (decl) = 0;
+ }
DECL_EXTERNAL (decl) = 1;
gen_decl_die (decl, context_die);
+ if (dwarf2_called_from_lto_p)
+ DECL_IGNORED_P (decl) = saved_ignored_flag;
DECL_EXTERNAL (decl) = saved_external_flag;
}
break;
@@ -13592,6 +13603,11 @@ force_decl_die (tree decl)
if (!decl_die)
decl_die = lookup_decl_die (decl);
gcc_assert (decl_die);
+ /* The LTO reading code checks the DW_AT_declaration attribute to
+ decide whether to read the initializer for a variable. So if
+ this variable has an initial value, remove that attribute. */
+ if (TREE_CODE (decl) == VAR_DECL && DECL_INITIAL (decl))
+ remove_AT (decl_die, DW_AT_declaration);
}
return decl_die;
diff --git a/gcc/lto-function-out.c b/gcc/lto-function-out.c
index 1031c735520..fae34e6dae4 100644
--- a/gcc/lto-function-out.c
+++ b/gcc/lto-function-out.c
@@ -1420,7 +1420,7 @@ output_expr_operand (struct output_block *ob, tree expr)
break;
case VAR_DECL:
- if (DECL_CONTEXT (expr) == NULL_TREE)
+ if (TREE_STATIC (expr) || DECL_EXTERNAL (expr))
{
/* Static or extern VAR_DECLs. */
unsigned int index;
@@ -1830,6 +1830,8 @@ output_local_vars (struct output_block *ob, struct function *fn)
tree t;
int i = 0;
struct output_stream *tmp_stream = ob->main_stream;
+ bitmap local_statics = BITMAP_ALLOC (NULL);
+
ob->main_stream = ob->local_decl_stream;
/* We have found MOST of the local vars by scanning the function.
@@ -1837,26 +1839,58 @@ output_local_vars (struct output_block *ob, struct function *fn)
Other local vars can be found by walking the unexpanded vars
list. */
+ /* Need to put out the local statics first, to avoid the pointer
+ games used for the regular locals. */
+ LTO_DEBUG_TOKEN ("local statics");
for (t = fn->unexpanded_var_list; t; t = TREE_CHAIN (t))
{
tree lv = TREE_VALUE (t);
- int j;
- j = output_local_decl_ref (ob, lv, false);
- /* Just for the fun of it, some of the locals are in the
- unexpanded_var_list more than once. */
- if (VEC_index (int, ob->unexpanded_local_decls_index, j) == -1)
- VEC_replace (int, ob->unexpanded_local_decls_index, j, i++);
+ if (TREE_STATIC (lv))
+ {
+ /* Do not put the static in the chain more than once, even
+ if it was in the chain more than once to start. */
+ if (!bitmap_bit_p (local_statics, DECL_UID (lv)))
+ {
+ bitmap_set_bit (local_statics, DECL_UID (lv));
+ output_expr_operand (ob, lv);
+ if (DECL_CONTEXT (lv) == fn->decl)
+ {
+ output_uleb128 (ob, 1); /* Restore context. */
+ if (DECL_INITIAL (lv))
+ output_expr_operand (ob, DECL_INITIAL (lv));
+ else
+ output_zero (ob); /* DECL_INITIAL. */
+ }
+ else
+ {
+ output_zero (ob); /* Restore context. */
+ output_zero (ob); /* DECL_INITIAL. */
+ }
+ }
+ }
+ else
+ {
+ int j = output_local_decl_ref (ob, lv, false);
+ /* Just for the fun of it, some of the locals are in the
+ unexpanded_var_list more than once. */
+ if (VEC_index (int, ob->unexpanded_local_decls_index, j) == -1)
+ VEC_replace (int, ob->unexpanded_local_decls_index, j, i++);
+ }
}
+
+ /* End of statics. */
+ output_zero (ob);
+ BITMAP_FREE (local_statics);
+
/* The easiest way to get all of this stuff generated is to play
pointer games with the streams and reuse the code for putting out
the function bodies for putting out the local decls. It needs to
go into a separate stream because the LTO reader will want to
process the local variables first, rather than have to back patch
- them.
- */
-
+ them. */
+ LTO_DEBUG_TOKEN ("local vars");
while (index < VEC_length (tree, ob->local_decls))
output_local_var (ob, index++);
@@ -2389,6 +2423,7 @@ output_function (tree function)
destroy_output_block (ob, true);
current_function_decl = NULL;
+
pop_cfun ();
}
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog
index 79d51337825..eaf80bb9193 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -1,3 +1,10 @@
+2007-12-22 Nathan Froyd <froydnj@codesourcery.com>
+ Kenneth Zadeck <zadeck@naturalbridge.com>
+
+ * lto-read.c (input_expr_operand): Fixed uninitialize var warning.
+ (input_local_vars): Read in DECL_INITIAL and context for local
+ statics that need to be put in unexpanded_vars_list.
+
2007-12-21 Nathan Froyd <froydnj@codesourcery.com>
* lto-read.c (input_real): Use a separate null-terminated buffer
diff --git a/gcc/lto/lto-read.c b/gcc/lto/lto-read.c
index e27e84909bb..727446a101d 100644
--- a/gcc/lto/lto-read.c
+++ b/gcc/lto/lto-read.c
@@ -774,6 +774,10 @@ input_expr_operand (struct input_block *ib, struct data_in *data_in,
result = data_in->local_decls [lv_index];
if (result == NULL)
{
+ /* Create a context to read the local variable so that
+ it does not disturb the position of the code that is
+ calling for the local variable. This allows locals
+ to refer to other locals. */
struct input_block lib;
#ifdef LTO_STREAM_DEBUGGING
@@ -788,7 +792,6 @@ input_expr_operand (struct input_block *ib, struct data_in *data_in,
lto_debug_context.indent = 0;
lto_debug_context.current_data = &debug;
#endif
-
lib.data = ib->data;
lib.len = ib->len;
lib.p = data_in->local_decls_index[lv_index];
@@ -1043,7 +1046,7 @@ input_expr_operand (struct input_block *ib, struct data_in *data_in,
{
tree value;
tree purpose;
- tree next;
+ tree next = NULL;
tree elt;
enum LTO_tags tag = input_record_start (ib);
@@ -1392,12 +1395,40 @@ input_local_vars (struct input_block *ib, struct data_in *data_in,
struct function *fn, unsigned int count)
{
int i;
-
+ unsigned int tag;
+
data_in->unexpanded_indexes = xcalloc (count, sizeof (int));
data_in->local_decls = xcalloc (count, sizeof (tree*));
memset (data_in->unexpanded_indexes, -1, count * sizeof (int));
+ /* Recreate the unexpanded_var_list. Put the statics at the end.*/
+ fn->unexpanded_var_list = NULL;
+ LTO_DEBUG_TOKEN ("local statics");
+ tag = input_record_start (ib);
+
+ while (tag)
+ {
+ tree var = input_expr_operand (ib, data_in, fn, tag);
+ fn->unexpanded_var_list
+ = tree_cons (NULL_TREE, var, fn->unexpanded_var_list);
+
+ if (input_uleb128 (ib))
+ DECL_CONTEXT (var) = fn->decl;
+
+ /* DECL_INITIAL. */
+ tag = input_record_start (ib);
+ if (tag)
+ DECL_INITIAL (var) = input_expr_operand (ib, data_in, fn, tag);
+
+ /* Statics never have external visibility. */
+ DECL_EXTERNAL (var) = 0;
+
+ /* Next static. */
+ tag = input_record_start (ib);
+ }
+
+ LTO_DEBUG_TOKEN ("local vars");
for (i = 0; i < (int)count; i++)
/* Some local decls may have already been read in if they are used
as part of a previous local_decl. */
@@ -1411,8 +1442,7 @@ input_local_vars (struct input_block *ib, struct data_in *data_in,
input_local_var (ib, data_in, fn, i);
}
- /* Recreate the unexpanded_var_list. */
- fn->unexpanded_var_list = NULL;
+ /* Add the regular locals in the proper order. */
for (i = count - 1; i >= 0; i--)
if (data_in->unexpanded_indexes[i] != -1)
fn->unexpanded_var_list