From: Richard Biener <rguenther@suse.de>
To: Jan Hubicka <hubicka@ucw.cz>
Cc: gcc-patches@gcc.gnu.org, mliska@suse.cz
Subject: Re: Add few cases to operand_equal_p
Date: Fri, 22 May 2015 13:34:00 -0000 [thread overview]
Message-ID: <alpine.LSU.2.11.1505221518250.30088@zhemvz.fhfr.qr> (raw)
In-Reply-To: <20150522123341.GD91616@kam.mff.cuni.cz>
On Fri, 22 May 2015, Jan Hubicka wrote:
> Hi,
> I am working on patch that makes operand_equal_p replace logic from
> ipa-icf-gimple's compare_op via a valueizer hook. Currently the patch however
> cuts number of merges on firefox to half (apparently becuase it gives up on
> some tree codes too early)
> The patch bellow merges code from ipa-icf-gimple.c that is missing in
> fold-const and is needed.
>
> Bootstrapped/regtested x86_64-linux, OK?
No, I don't like this.
> Honza
>
> * fold-const.c (operand_equal_p): Handle OBJ_TYPE_REF, CONSTRUCTOR
> and be more tolerant about FIELD_DECL.
> * tree.c (add_expr): Handle FIELD_DECL.
> (prototype_p, virtual_method_call_p, obj_type_ref_class): Constify.
> * tree.h (prototype_p, virtual_method_call_p, obj_type_ref_class):
> Constify.
> Index: fold-const.c
> ===================================================================
> --- fold-const.c (revision 223500)
> @@ -3037,6 +3058,40 @@ operand_equal_p (const_tree arg0, const_
> case DOT_PROD_EXPR:
> return OP_SAME (0) && OP_SAME (1) && OP_SAME (2);
>
> + /* OBJ_TYPE_REF really is just a transparent wrapper around expression,
> + but it holds additional type information for devirtualization that
> + needs to be matched. We may want to intoruce OEP flag if we want
> + to compare the actual value only, or if we also care about effects
> + of potentially merging the code. This flag can bypass this check
> + as well as the alias set matching in MEM_REF. */
> + case OBJ_TYPE_REF:
> + {
> + if (!operand_equal_p (OBJ_TYPE_REF_EXPR (arg0),
> + OBJ_TYPE_REF_EXPR (arg1), flags))
> + return false;
> + if (flag_devirtualize && virtual_method_call_p (arg0))
> + {
> + if (tree_to_uhwi (OBJ_TYPE_REF_TOKEN (arg0))
> + != tree_to_uhwi (OBJ_TYPE_REF_TOKEN (arg1)))
> + return false;
> + if (!types_same_for_odr (obj_type_ref_class (arg0),
> + obj_type_ref_class (arg1)))
> + return false;
devirt machinery in operand_equal_p? please not. not more places!
> + /* OBJ_TYPE_REF_OBJECT is used to track the instance of
> + object THIS pointer points to. Checking that both
> + addresses equal is safe approximation of the fact
> + that dynamic types are equal.
> + Do not care about the other flags, because this expression
> + does not attribute to actual value of OBJ_TYPE_REF */
> + if (!operand_equal_p (OBJ_TYPE_REF_OBJECT (arg0),
> + OBJ_TYPE_REF_OBJECT (arg1),
> + OEP_ADDRESS_OF))
> + return false;
> + }
> +
> + return true;
> + }
> +
> default:
> return 0;
> }
> @@ -3097,6 +3152,21 @@ operand_equal_p (const_tree arg0, const_
> }
>
> case tcc_declaration:
> + /* At LTO time the FIELD_DECL may exist in multiple copies.
> + We only care about offsets and bit offsets for operands. */
Err? Even at LTO time FIELD_DECLs should only appear once.
So - testcase?
IMHO most of this boils down to ICF being too strict about aliasing
because it inlines merged bodies instead of original ones.
> + if (TREE_CODE (arg0) == FIELD_DECL)
> + {
> + tree offset1 = DECL_FIELD_OFFSET (arg0);
> + tree offset2 = DECL_FIELD_OFFSET (arg1);
> +
> + tree bit_offset1 = DECL_FIELD_BIT_OFFSET (arg0);
> + tree bit_offset2 = DECL_FIELD_BIT_OFFSET (arg1);
> +
> + flags &= ~(OEP_CONSTANT_ADDRESS_OF|OEP_ADDRESS_OF);
> +
> + return operand_equal_p (offset1, offset2, flags)
> + && operand_equal_p (bit_offset1, bit_offset2, flags);
> + }
> /* Consider __builtin_sqrt equal to sqrt. */
> return (TREE_CODE (arg0) == FUNCTION_DECL
> && DECL_BUILT_IN (arg0) && DECL_BUILT_IN (arg1)
> @@ -3104,12 +3174,50 @@ operand_equal_p (const_tree arg0, const_
> && DECL_FUNCTION_CODE (arg0) == DECL_FUNCTION_CODE (arg1));
>
> default:
case tcc_exceptional:
> + /* In GIMPLE empty constructors are allowed in initializers of
> + vector types. */
Why this comment about GIMPLE? This is about comparing GENERIC
trees which of course can have CONSTRUCTORs of various sorts.
> + if (TREE_CODE (arg0) == CONSTRUCTOR)
> + {
> + unsigned length1 = vec_safe_length (CONSTRUCTOR_ELTS (arg0));
> + unsigned length2 = vec_safe_length (CONSTRUCTOR_ELTS (arg1));
> +
> + if (length1 != length2)
> + return false;
> +
> + flags &= ~(OEP_CONSTANT_ADDRESS_OF|OEP_ADDRESS_OF);
> +
> + for (unsigned i = 0; i < length1; i++)
> + if (!operand_equal_p (CONSTRUCTOR_ELT (arg0, i)->value,
> + CONSTRUCTOR_ELT (arg1, i)->value, flags))
You need to compare ->index as well here. I'm not sure constructor
values are sorted always so you might get very many false negatives.
> + return false;
> +
> + return true;
> + }
> return 0;
> }
>
> #undef OP_SAME
> #undef OP_SAME_WITH_NULL
> }
> Index: tree.c
> ===================================================================
> --- tree.c (revision 223500)
> +++ tree.c (working copy)
> @@ -7647,6 +7647,12 @@ add_expr (const_tree t, inchash::hash &h
> }
> return;
> }
> + case FIELD_DECL:
> + /* At LTO time the FIELD_DECL may exist in multiple copies.
> + We only care about offsets and bit offsets for operands. */
So explain that this is the reason we don't want to hash by
DECL_UID. I still think this is bogus.
> + inchash::add_expr (DECL_FIELD_OFFSET (t), hstate);
> + inchash::add_expr (DECL_FIELD_BIT_OFFSET (t), hstate);
> + return;
> case FUNCTION_DECL:
> /* When referring to a built-in FUNCTION_DECL, use the __builtin__ form.
> Otherwise nodes that compare equal according to operand_equal_p might
> @@ -11579,7 +11585,7 @@ stdarg_p (const_tree fntype)
> /* Return true if TYPE has a prototype. */
>
> bool
> -prototype_p (tree fntype)
> +prototype_p (const_tree fntype)
This and the following look like independent (and obvious) changes.
> {
> tree t;
>
> @@ -12005,7 +12011,7 @@ lhd_gcc_personality (void)
> can't apply.) */
>
> bool
> -virtual_method_call_p (tree target)
> +virtual_method_call_p (const_tree target)
> {
> if (TREE_CODE (target) != OBJ_TYPE_REF)
> return false;
> @@ -12026,7 +12032,7 @@ virtual_method_call_p (tree target)
> /* REF is OBJ_TYPE_REF, return the class the ref corresponds to. */
>
> tree
> -obj_type_ref_class (tree ref)
> +obj_type_ref_class (const_tree ref)
> {
> gcc_checking_assert (TREE_CODE (ref) == OBJ_TYPE_REF);
> ref = TREE_TYPE (ref);
> Index: tree.h
> ===================================================================
> --- tree.h (revision 223500)
> +++ tree.h (working copy)
> @@ -4375,7 +4375,7 @@ extern int operand_equal_for_phi_arg_p (
> extern tree create_artificial_label (location_t);
> extern const char *get_name (tree);
> extern bool stdarg_p (const_tree);
> -extern bool prototype_p (tree);
> +extern bool prototype_p (const_tree);
> extern bool is_typedef_decl (tree x);
> extern bool typedef_variant_p (tree);
> extern bool auto_var_in_fn_p (const_tree, const_tree);
> @@ -4544,8 +4544,8 @@ extern location_t *block_nonartificial_l
> extern location_t tree_nonartificial_location (tree);
> extern tree block_ultimate_origin (const_tree);
> extern tree get_binfo_at_offset (tree, HOST_WIDE_INT, tree);
> -extern bool virtual_method_call_p (tree);
> -extern tree obj_type_ref_class (tree ref);
> +extern bool virtual_method_call_p (const_tree);
> +extern tree obj_type_ref_class (const_tree ref);
> extern bool types_same_for_odr (const_tree type1, const_tree type2,
> bool strict=false);
> extern bool contains_bitfld_component_ref_p (const_tree);
>
>
--
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Dilip Upmanyu, Graham Norton, HRB 21284 (AG Nuernberg)
next prev parent reply other threads:[~2015-05-22 13:27 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-22 12:44 Jan Hubicka
2015-05-22 13:34 ` Richard Biener [this message]
2015-05-22 14:01 ` Jan Hubicka
2015-05-22 14:59 ` Jan Hubicka
2015-05-26 12:19 ` Richard Biener
2015-05-26 18:53 ` Jan Hubicka
2015-05-27 8:39 ` Richard Biener
2015-05-28 0:26 ` Jan Hubicka
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=alpine.LSU.2.11.1505221518250.30088@zhemvz.fhfr.qr \
--to=rguenther@suse.de \
--cc=gcc-patches@gcc.gnu.org \
--cc=hubicka@ucw.cz \
--cc=mliska@suse.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).