public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/aoliva/heads/testme)] avoid early reference to debug-only symbol
@ 2021-07-10 0:08 Alexandre Oliva
0 siblings, 0 replies; 4+ messages in thread
From: Alexandre Oliva @ 2021-07-10 0:08 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:fa050c2ae06c9bd1dd0191aad04184b3980c5d80
commit fa050c2ae06c9bd1dd0191aad04184b3980c5d80
Author: Alexandre Oliva <oliva@adacore.com>
Date: Fri Jul 9 19:54:46 2021 -0300
avoid early reference to debug-only symbol
If some IPA pass replaces the only reference to a constant non-public
non-automatic variable with its initializer, namely the address of
another such variable, the former becomes unreferenced and it's
discarded by symbol_table::remove_unreachable_nodes. It calls
debug_hooks->late_global_decl while at that, and this expands the
initializer, which assigs RTL to the latter variable and forces it to
be retained by remove_unreferenced_decls, and eventually be output
despite not being referenced. Without debug information, it's not
output.
This has caused a bootstrap-debug compare failure in
libdecnumber/decContext.o, while developing a transformation that ends
up enabling the above substitution in constprop.
This patch makes reference_to_unused slightly more conservative about
such variables at the end of IPA passes, falling back onto
expand_debug_expr for expressions referencing symbols that might or
might not be output, avoiding the loss of debug information when the
symbol is output, while avoiding a symbol output only because of debug
info.
Diff:
---
gcc/cfgexpand.c | 12 +++++++++---
gcc/dwarf2out.c | 15 +++++++++++++--
gcc/expr.h | 2 ++
3 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 3edd53c37dc..b731a559823 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -91,8 +91,6 @@ struct ssaexpand SA;
of comminucating the profile info to the builtin expanders. */
gimple *currently_expanding_gimple_stmt;
-static rtx expand_debug_expr (tree);
-
static bool defer_stack_allocation (tree, bool);
static void record_alignment_for_reg_var (unsigned int);
@@ -4413,7 +4411,7 @@ expand_debug_parm_decl (tree decl)
/* Return an RTX equivalent to the value of the tree expression EXP. */
-static rtx
+rtx
expand_debug_expr (tree exp)
{
rtx op0 = NULL_RTX, op1 = NULL_RTX, op2 = NULL_RTX;
@@ -5285,6 +5283,14 @@ expand_debug_expr (tree exp)
else
goto flag_unsupported;
+ case COMPOUND_LITERAL_EXPR:
+ exp = COMPOUND_LITERAL_EXPR_DECL_EXPR (exp);
+ /* DECL_EXPR is a tcc_statement, which expand_debug_expr does
+ not expect, so instead of recursing we take care of it right
+ away. */
+ exp = DECL_EXPR_DECL (exp);
+ return expand_debug_expr (exp);
+
case CALL_EXPR:
/* ??? Maybe handle some builtins? */
return NULL;
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 82783c4968b..bb7e2b8dc4e 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -20170,7 +20170,8 @@ add_const_value_attribute (dw_die_ref die, rtx rtl)
if (dwarf_version >= 4 || !dwarf_strict)
{
dw_loc_descr_ref loc_result;
- resolve_one_addr (&rtl);
+ if (!resolve_one_addr (&rtl))
+ return false;
rtl_addr:
loc_result = new_addr_loc_descr (rtl, dtprel_false);
add_loc_descr (&loc_result, new_loc_descr (DW_OP_stack_value, 0, 0));
@@ -20255,6 +20256,12 @@ reference_to_unused (tree * tp, int * walk_subtrees,
varpool_node *node = varpool_node::get (*tp);
if (!node || !node->definition)
return *tp;
+ /* If it's local, it might still be optimized out, unless we've
+ already committed to outputting it by assigning RTL to it. */
+ if (! TREE_PUBLIC (*tp) && ! TREE_ASM_WRITTEN (*tp)
+ && symtab->state <= IPA_SSA_AFTER_INLINING
+ && ! DECL_RTL_SET_P (*tp))
+ return *tp;
}
else if (TREE_CODE (*tp) == FUNCTION_DECL
&& (!DECL_EXTERNAL (*tp) || DECL_DECLARED_INLINE_P (*tp)))
@@ -20279,6 +20286,7 @@ static rtx
rtl_for_decl_init (tree init, tree type)
{
rtx rtl = NULL_RTX;
+ bool valid_p = false;
STRIP_NOPS (init);
@@ -20322,7 +20330,7 @@ rtl_for_decl_init (tree init, tree type)
/* If the initializer is something that we know will expand into an
immediate RTL constant, expand it now. We must be careful not to
reference variables which won't be output. */
- else if (initializer_constant_valid_p (init, type)
+ else if ((valid_p = initializer_constant_valid_p (init, type))
&& ! walk_tree (&init, reference_to_unused, NULL, NULL))
{
/* Convert vector CONSTRUCTOR initializers to VECTOR_CST if
@@ -20367,6 +20375,9 @@ rtl_for_decl_init (tree init, tree type)
/* If expand_expr returns a MEM, it wasn't immediate. */
gcc_assert (!rtl || !MEM_P (rtl));
}
+ else if (valid_p)
+ /* Perhaps we could just use this and skip all of the above? */
+ rtl = expand_debug_expr (init);
return rtl;
}
diff --git a/gcc/expr.h b/gcc/expr.h
index a4f44265759..7b060462020 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -307,6 +307,8 @@ expand_normal (tree exp)
return expand_expr_real (exp, NULL_RTX, VOIDmode, EXPAND_NORMAL, NULL, false);
}
+/* This one is defined in cfgexpand.c. */
+extern rtx expand_debug_expr (tree);
/* Return STRING_CST and set offset, size and decl, if the first
argument corresponds to a string constant. */
^ permalink raw reply [flat|nested] 4+ messages in thread
* [gcc(refs/users/aoliva/heads/testme)] avoid early reference to debug-only symbol
@ 2021-07-10 9:43 Alexandre Oliva
0 siblings, 0 replies; 4+ messages in thread
From: Alexandre Oliva @ 2021-07-10 9:43 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:7a0d3299c7af17c36d533ed2e476c110bcfbd424
commit 7a0d3299c7af17c36d533ed2e476c110bcfbd424
Author: Alexandre Oliva <oliva@adacore.com>
Date: Fri Jul 9 19:54:46 2021 -0300
avoid early reference to debug-only symbol
If some IPA pass replaces the only reference to a constant non-public
non-automatic variable with its initializer, namely the address of
another such variable, the former becomes unreferenced and it's
discarded by symbol_table::remove_unreachable_nodes. It calls
debug_hooks->late_global_decl while at that, and this expands the
initializer, which assigs RTL to the latter variable and forces it to
be retained by remove_unreferenced_decls, and eventually be output
despite not being referenced. Without debug information, it's not
output.
This has caused a bootstrap-debug compare failure in
libdecnumber/decContext.o, while developing a transformation that ends
up enabling the above substitution in constprop.
This patch makes reference_to_unused slightly more conservative about
such variables at the end of IPA passes, falling back onto
expand_debug_expr for expressions referencing symbols that might or
might not be output, avoiding the loss of debug information when the
symbol is output, while avoiding a symbol output only because of debug
info.
Diff:
---
gcc/cfgexpand.c | 12 +++++++++---
gcc/dwarf2out.c | 15 +++++++++++++--
gcc/expr.h | 2 ++
3 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 3edd53c37dc..b731a559823 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -91,8 +91,6 @@ struct ssaexpand SA;
of comminucating the profile info to the builtin expanders. */
gimple *currently_expanding_gimple_stmt;
-static rtx expand_debug_expr (tree);
-
static bool defer_stack_allocation (tree, bool);
static void record_alignment_for_reg_var (unsigned int);
@@ -4413,7 +4411,7 @@ expand_debug_parm_decl (tree decl)
/* Return an RTX equivalent to the value of the tree expression EXP. */
-static rtx
+rtx
expand_debug_expr (tree exp)
{
rtx op0 = NULL_RTX, op1 = NULL_RTX, op2 = NULL_RTX;
@@ -5285,6 +5283,14 @@ expand_debug_expr (tree exp)
else
goto flag_unsupported;
+ case COMPOUND_LITERAL_EXPR:
+ exp = COMPOUND_LITERAL_EXPR_DECL_EXPR (exp);
+ /* DECL_EXPR is a tcc_statement, which expand_debug_expr does
+ not expect, so instead of recursing we take care of it right
+ away. */
+ exp = DECL_EXPR_DECL (exp);
+ return expand_debug_expr (exp);
+
case CALL_EXPR:
/* ??? Maybe handle some builtins? */
return NULL;
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 82783c4968b..bb7e2b8dc4e 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -20170,7 +20170,8 @@ add_const_value_attribute (dw_die_ref die, rtx rtl)
if (dwarf_version >= 4 || !dwarf_strict)
{
dw_loc_descr_ref loc_result;
- resolve_one_addr (&rtl);
+ if (!resolve_one_addr (&rtl))
+ return false;
rtl_addr:
loc_result = new_addr_loc_descr (rtl, dtprel_false);
add_loc_descr (&loc_result, new_loc_descr (DW_OP_stack_value, 0, 0));
@@ -20255,6 +20256,12 @@ reference_to_unused (tree * tp, int * walk_subtrees,
varpool_node *node = varpool_node::get (*tp);
if (!node || !node->definition)
return *tp;
+ /* If it's local, it might still be optimized out, unless we've
+ already committed to outputting it by assigning RTL to it. */
+ if (! TREE_PUBLIC (*tp) && ! TREE_ASM_WRITTEN (*tp)
+ && symtab->state <= IPA_SSA_AFTER_INLINING
+ && ! DECL_RTL_SET_P (*tp))
+ return *tp;
}
else if (TREE_CODE (*tp) == FUNCTION_DECL
&& (!DECL_EXTERNAL (*tp) || DECL_DECLARED_INLINE_P (*tp)))
@@ -20279,6 +20286,7 @@ static rtx
rtl_for_decl_init (tree init, tree type)
{
rtx rtl = NULL_RTX;
+ bool valid_p = false;
STRIP_NOPS (init);
@@ -20322,7 +20330,7 @@ rtl_for_decl_init (tree init, tree type)
/* If the initializer is something that we know will expand into an
immediate RTL constant, expand it now. We must be careful not to
reference variables which won't be output. */
- else if (initializer_constant_valid_p (init, type)
+ else if ((valid_p = initializer_constant_valid_p (init, type))
&& ! walk_tree (&init, reference_to_unused, NULL, NULL))
{
/* Convert vector CONSTRUCTOR initializers to VECTOR_CST if
@@ -20367,6 +20375,9 @@ rtl_for_decl_init (tree init, tree type)
/* If expand_expr returns a MEM, it wasn't immediate. */
gcc_assert (!rtl || !MEM_P (rtl));
}
+ else if (valid_p)
+ /* Perhaps we could just use this and skip all of the above? */
+ rtl = expand_debug_expr (init);
return rtl;
}
diff --git a/gcc/expr.h b/gcc/expr.h
index a4f44265759..7b060462020 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -307,6 +307,8 @@ expand_normal (tree exp)
return expand_expr_real (exp, NULL_RTX, VOIDmode, EXPAND_NORMAL, NULL, false);
}
+/* This one is defined in cfgexpand.c. */
+extern rtx expand_debug_expr (tree);
/* Return STRING_CST and set offset, size and decl, if the first
argument corresponds to a string constant. */
^ permalink raw reply [flat|nested] 4+ messages in thread
* [gcc(refs/users/aoliva/heads/testme)] avoid early reference to debug-only symbol
@ 2021-06-30 4:16 Alexandre Oliva
0 siblings, 0 replies; 4+ messages in thread
From: Alexandre Oliva @ 2021-06-30 4:16 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:8848482ec9b71aeebfe2205f48e6a9ad71d5009a
commit 8848482ec9b71aeebfe2205f48e6a9ad71d5009a
Author: Alexandre Oliva <oliva@adacore.com>
Date: Mon Jun 28 12:40:33 2021 -0300
avoid early reference to debug-only symbol
If some IPA pass replaces the only reference to a constant non-public
non-automatic variable with its initializer, namely the address of
another such variable, the former becomes unreferenced and it's
discarded by symbol_table::remove_unreachable_nodes. It calls
debug_hooks->late_global_decl while at that, and this expands the
initializer, which assigs RTL to the latter variable and forces it to
be retained by remove_unreferenced_decls, and eventually be output
despite not being referenced. Without debug information, it's not
output.
This has caused a bootstrap-debug compare failure in
libdecnumber/decContext.o, while developing a transformation that ends
up enabling the above substitution in constprop.
This patch makes reference_to_unused slightly more conservative about
such variables at the end of IPA passes, falling back onto
expand_debug_expr for expressions referencing symbols that might or
might not be output, avoiding the loss of debug information when the
symbol is output, while avoiding a symbol output only because of debug
info.
Diff:
---
gcc/cfgexpand.c | 12 +++++++++---
gcc/dwarf2out.c | 15 +++++++++++++--
gcc/expr.h | 2 ++
3 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 3edd53c37dc..b731a559823 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -91,8 +91,6 @@ struct ssaexpand SA;
of comminucating the profile info to the builtin expanders. */
gimple *currently_expanding_gimple_stmt;
-static rtx expand_debug_expr (tree);
-
static bool defer_stack_allocation (tree, bool);
static void record_alignment_for_reg_var (unsigned int);
@@ -4413,7 +4411,7 @@ expand_debug_parm_decl (tree decl)
/* Return an RTX equivalent to the value of the tree expression EXP. */
-static rtx
+rtx
expand_debug_expr (tree exp)
{
rtx op0 = NULL_RTX, op1 = NULL_RTX, op2 = NULL_RTX;
@@ -5285,6 +5283,14 @@ expand_debug_expr (tree exp)
else
goto flag_unsupported;
+ case COMPOUND_LITERAL_EXPR:
+ exp = COMPOUND_LITERAL_EXPR_DECL_EXPR (exp);
+ /* DECL_EXPR is a tcc_statement, which expand_debug_expr does
+ not expect, so instead of recursing we take care of it right
+ away. */
+ exp = DECL_EXPR_DECL (exp);
+ return expand_debug_expr (exp);
+
case CALL_EXPR:
/* ??? Maybe handle some builtins? */
return NULL;
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 9a91981acb0..e56773decfb 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -20170,7 +20170,8 @@ add_const_value_attribute (dw_die_ref die, rtx rtl)
if (dwarf_version >= 4 || !dwarf_strict)
{
dw_loc_descr_ref loc_result;
- resolve_one_addr (&rtl);
+ if (!resolve_one_addr (&rtl))
+ return false;
rtl_addr:
loc_result = new_addr_loc_descr (rtl, dtprel_false);
add_loc_descr (&loc_result, new_loc_descr (DW_OP_stack_value, 0, 0));
@@ -20255,6 +20256,12 @@ reference_to_unused (tree * tp, int * walk_subtrees,
varpool_node *node = varpool_node::get (*tp);
if (!node || !node->definition)
return *tp;
+ /* If it's local, it might still be optimized out, unless we've
+ already committed to outputting it by assigning RTL to it. */
+ if (! TREE_PUBLIC (*tp) && ! TREE_ASM_WRITTEN (*tp)
+ && symtab->state <= IPA_SSA_AFTER_INLINING
+ && ! DECL_RTL_SET_P (*tp))
+ return *tp;
}
else if (TREE_CODE (*tp) == FUNCTION_DECL
&& (!DECL_EXTERNAL (*tp) || DECL_DECLARED_INLINE_P (*tp)))
@@ -20279,6 +20286,7 @@ static rtx
rtl_for_decl_init (tree init, tree type)
{
rtx rtl = NULL_RTX;
+ bool valid_p = false;
STRIP_NOPS (init);
@@ -20322,7 +20330,7 @@ rtl_for_decl_init (tree init, tree type)
/* If the initializer is something that we know will expand into an
immediate RTL constant, expand it now. We must be careful not to
reference variables which won't be output. */
- else if (initializer_constant_valid_p (init, type)
+ else if ((valid_p = initializer_constant_valid_p (init, type))
&& ! walk_tree (&init, reference_to_unused, NULL, NULL))
{
/* Convert vector CONSTRUCTOR initializers to VECTOR_CST if
@@ -20367,6 +20375,9 @@ rtl_for_decl_init (tree init, tree type)
/* If expand_expr returns a MEM, it wasn't immediate. */
gcc_assert (!rtl || !MEM_P (rtl));
}
+ else if (valid_p)
+ /* Perhaps we could just use this and skip all of the above? */
+ rtl = expand_debug_expr (init);
return rtl;
}
diff --git a/gcc/expr.h b/gcc/expr.h
index a4f44265759..7b060462020 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -307,6 +307,8 @@ expand_normal (tree exp)
return expand_expr_real (exp, NULL_RTX, VOIDmode, EXPAND_NORMAL, NULL, false);
}
+/* This one is defined in cfgexpand.c. */
+extern rtx expand_debug_expr (tree);
/* Return STRING_CST and set offset, size and decl, if the first
argument corresponds to a string constant. */
^ permalink raw reply [flat|nested] 4+ messages in thread
* [gcc(refs/users/aoliva/heads/testme)] avoid early reference to debug-only symbol
@ 2021-06-28 15:42 Alexandre Oliva
0 siblings, 0 replies; 4+ messages in thread
From: Alexandre Oliva @ 2021-06-28 15:42 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:15a15d0d27afe203b98dbb9f3bd1633221c0bc73
commit 15a15d0d27afe203b98dbb9f3bd1633221c0bc73
Author: Alexandre Oliva <oliva@adacore.com>
Date: Mon Jun 28 12:40:33 2021 -0300
avoid early reference to debug-only symbol
If some IPA pass replaces the only reference to a constant non-public
non-automatic variable with its initializer, namely the address of
another such variable, the former becomes unreferenced and it's
discarded by symbol_table::remove_unreachable_nodes. It calls
debug_hooks->late_global_decl while at that, and this expands the
initializer, which assigs RTL to the latter variable and forces it to
be retained by remove_unreferenced_decls, and eventually be output
despite not being referenced. Without debug information, it's not
output.
This has caused a bootstrap-debug compare failure in
libdecnumber/decContext.o, while developing a transformation that ends
up enabling the above substitution in constprop.
This patch makes reference_to_unused slightly more conservative about
such variables at the end of IPA passes, falling back onto
expand_debug_expr for expressions referencing symbols that might or
might not be output, avoiding the loss of debug information when the
symbol is output, while avoiding a symbol output only because of debug
info.
Diff:
---
gcc/cfgexpand.c | 4 +---
gcc/dwarf2out.c | 12 +++++++++++-
gcc/expr.h | 2 ++
3 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 3edd53c37dc..6e629669148 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -91,8 +91,6 @@ struct ssaexpand SA;
of comminucating the profile info to the builtin expanders. */
gimple *currently_expanding_gimple_stmt;
-static rtx expand_debug_expr (tree);
-
static bool defer_stack_allocation (tree, bool);
static void record_alignment_for_reg_var (unsigned int);
@@ -4413,7 +4411,7 @@ expand_debug_parm_decl (tree decl)
/* Return an RTX equivalent to the value of the tree expression EXP. */
-static rtx
+rtx
expand_debug_expr (tree exp)
{
rtx op0 = NULL_RTX, op1 = NULL_RTX, op2 = NULL_RTX;
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 9a91981acb0..65b0bd6fe24 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -20255,6 +20255,12 @@ reference_to_unused (tree * tp, int * walk_subtrees,
varpool_node *node = varpool_node::get (*tp);
if (!node || !node->definition)
return *tp;
+ /* If it's local, it might still be optimized out, unless we've
+ already committed to outputting it by assigning RTL to it. */
+ if (! TREE_PUBLIC (*tp) && ! TREE_ASM_WRITTEN (*tp)
+ && symtab->state <= IPA_SSA_AFTER_INLINING
+ && ! DECL_RTL_SET_P (*tp))
+ return *tp;
}
else if (TREE_CODE (*tp) == FUNCTION_DECL
&& (!DECL_EXTERNAL (*tp) || DECL_DECLARED_INLINE_P (*tp)))
@@ -20279,6 +20285,7 @@ static rtx
rtl_for_decl_init (tree init, tree type)
{
rtx rtl = NULL_RTX;
+ bool valid_p = false;
STRIP_NOPS (init);
@@ -20322,7 +20329,7 @@ rtl_for_decl_init (tree init, tree type)
/* If the initializer is something that we know will expand into an
immediate RTL constant, expand it now. We must be careful not to
reference variables which won't be output. */
- else if (initializer_constant_valid_p (init, type)
+ else if ((valid_p = initializer_constant_valid_p (init, type))
&& ! walk_tree (&init, reference_to_unused, NULL, NULL))
{
/* Convert vector CONSTRUCTOR initializers to VECTOR_CST if
@@ -20367,6 +20374,9 @@ rtl_for_decl_init (tree init, tree type)
/* If expand_expr returns a MEM, it wasn't immediate. */
gcc_assert (!rtl || !MEM_P (rtl));
}
+ else if (valid_p)
+ /* Perhaps we could just use this and skip all of the above? */
+ rtl = expand_debug_expr (init);
return rtl;
}
diff --git a/gcc/expr.h b/gcc/expr.h
index a4f44265759..7b060462020 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -307,6 +307,8 @@ expand_normal (tree exp)
return expand_expr_real (exp, NULL_RTX, VOIDmode, EXPAND_NORMAL, NULL, false);
}
+/* This one is defined in cfgexpand.c. */
+extern rtx expand_debug_expr (tree);
/* Return STRING_CST and set offset, size and decl, if the first
argument corresponds to a string constant. */
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-07-10 9:43 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-10 0:08 [gcc(refs/users/aoliva/heads/testme)] avoid early reference to debug-only symbol Alexandre Oliva
-- strict thread matches above, loose matches on Subject: below --
2021-07-10 9:43 Alexandre Oliva
2021-06-30 4:16 Alexandre Oliva
2021-06-28 15:42 Alexandre Oliva
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).