This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Another BLOCK issue - PR56570
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Jakub Jelinek <jakub at redhat dot com>
- Date: Fri, 8 Mar 2013 13:59:23 +0100 (CET)
- Subject: [PATCH] Another BLOCK issue - PR56570
This PR shows that when SRA creates DECL_DEBUG_EXPRs with locations
(and blocks) this does not work with inlining. The reason is that
the inliner does not bother to copy vars used only in lhs of
debug-stmts (eek) and thus ends up sharing DECL_DEBUG_EXPRs
(and not re-mapping them and their location blocks). Maybe
a recipie for further desaster ... (who knows). I didn't manage
to get it to "properly" copy things, but basically
else if (TREE_CODE (t) == VAR_DECL
&& !is_global_var (t)
&& !pointer_map_contains (id->decl_map, t))
/* T is a non-localized variable. */;
doesn't work - vars can be not in local-decls (which we all remap)
due to remove-unused-locals. Thus we end up not remapping the
debug var (and refer to the other functions DECL_DEBUG_EXPR).
The following avoids the DECL_DEBUG_EXPR issue by clearing
all location information from it (it's unused anyway).
The above code should nevertheless be inspected ...
I took the liberty to sync the MEM_REF code from the two nearly
identical tree copying routines (eh ...), it was my first guess
as to what goes wrong.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
For 4.9 we'd want a verify_no_location eventually which we can
use to recurse here.
Any comments about the above code?
Thanks,
Richard.
2013-03-08 Richard Biener <rguenther@suse.de>
PR tree-optimization/56570
* tree-cfg.c (verify_expr_location_1): Verify locations for
DECL_DEBUG_EXPR.
* tree-sra.c (create_access_replacement): Strip locations
from DECL_DEBUG_EXPRs.
* tree-inline.c (copy_tree_body_r): Sync MEM_REF code from ...
remap_gimple_op_r.
Index: gcc/tree-cfg.c
===================================================================
*** gcc/tree-cfg.c (revision 196542)
--- gcc/tree-cfg.c (working copy)
*************** verify_expr_location_1 (tree *tp, int *w
*** 4523,4528 ****
--- 4523,4537 ----
{
struct pointer_set_t *blocks = (struct pointer_set_t *) data;
+ if (TREE_CODE (*tp) == VAR_DECL
+ && DECL_DEBUG_EXPR_IS_FROM (*tp))
+ {
+ tree t = DECL_DEBUG_EXPR (*tp);
+ tree addr = walk_tree (&t, verify_expr_location_1, blocks, NULL);
+ if (addr)
+ return addr;
+ }
+
if (!EXPR_P (*tp))
{
*walk_subtrees = false;
Index: gcc/tree-sra.c
===================================================================
*** gcc/tree-sra.c (revision 196541)
--- gcc/tree-sra.c (working copy)
*************** create_access_replacement (struct access
*** 1917,1923 ****
&& !DECL_ARTIFICIAL (access->base))
{
char *pretty_name = make_fancy_name (access->expr);
! tree debug_expr = unshare_expr (access->expr), d;
bool fail = false;
DECL_NAME (repl) = get_identifier (pretty_name);
--- 1917,1923 ----
&& !DECL_ARTIFICIAL (access->base))
{
char *pretty_name = make_fancy_name (access->expr);
! tree debug_expr = unshare_expr_without_location (access->expr), d;
bool fail = false;
DECL_NAME (repl) = get_identifier (pretty_name);
Index: gcc/tree-inline.c
===================================================================
*** gcc/tree-inline.c (revision 196542)
--- gcc/tree-inline.c (working copy)
*************** copy_tree_body_r (tree *tp, int *walk_su
*** 1092,1113 ****
}
else if (TREE_CODE (*tp) == MEM_REF)
{
! /* We need to re-canonicalize MEM_REFs from inline substitutions
! that can happen when a pointer argument is an ADDR_EXPR. */
! tree decl = TREE_OPERAND (*tp, 0);
! tree *n;
! n = (tree *) pointer_map_contains (id->decl_map, decl);
! if (n)
! {
! tree old = *tp;
! *tp = fold_build2 (MEM_REF, TREE_TYPE (*tp),
! unshare_expr (*n), TREE_OPERAND (*tp, 1));
! TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
! TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
! *walk_subtrees = 0;
! return NULL;
! }
}
/* Here is the "usual case". Copy this tree node, and then
--- 1092,1113 ----
}
else if (TREE_CODE (*tp) == MEM_REF)
{
! tree ptr = TREE_OPERAND (*tp, 0);
! tree type = remap_type (TREE_TYPE (*tp), id);
! tree old = *tp;
! /* We need to re-canonicalize MEM_REFs from inline substitutions
! that can happen when a pointer argument is an ADDR_EXPR.
! Recurse here manually to allow that. */
! walk_tree (&ptr, copy_tree_body_r, data, NULL);
! *tp = fold_build2 (MEM_REF, type,
! ptr, TREE_OPERAND (*tp, 1));
! TREE_THIS_NOTRAP (*tp) = TREE_THIS_NOTRAP (old);
! TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
! TREE_SIDE_EFFECTS (*tp) = TREE_SIDE_EFFECTS (old);
! TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
! *walk_subtrees = 0;
! return NULL;
}
/* Here is the "usual case". Copy this tree node, and then