From: "Martin Liška" <mliska@suse.cz>
To: gcc-patches@gcc.gnu.org
Subject: Re: [PATCH 6/9] Integrate that for IPA ICF.
Date: Fri, 16 Aug 2019 11:10:00 -0000 [thread overview]
Message-ID: <a3a03230-b98c-7b33-6991-1476b73b8ab5@suse.cz> (raw)
In-Reply-To: <c05a92fffe29b3a2dd10fb17149a8d755c1e215a.1565105736.git.mliska@suse.cz>
[-- Attachment #1: Type: text/plain, Size: 167 bytes --]
I'm sending updated version of the patch.
Note: there are some (tree)const_cast<tree> (t2) casting. I've got a clean up
patch for that which will improve it.
Martin
[-- Attachment #2: 0006-Integrate-that-for-IPA-ICF.patch --]
[-- Type: text/x-patch, Size: 10541 bytes --]
From 20020586beabf1fc9f7860f46bb0c092f8536539 Mon Sep 17 00:00:00 2001
From: Martin Liska <mliska@suse.cz>
Date: Mon, 10 Jun 2019 14:34:15 +0200
Subject: [PATCH 6/9] Integrate that for IPA ICF.
gcc/ChangeLog:
2019-08-15 Martin Liska <mliska@suse.cz>
* ipa-icf-gimple.c (func_checker::hash_operand): New.
(func_checker::compare_cst_or_decl): Remove handling
of FIELD_DECL.
(func_checker::compare_operand): Transform to ...
(func_checker::operand_equal_p): ... this.
* ipa-icf-gimple.h (class func_checker): Add
operand_equal_p and hash_operand.
* ipa-icf.c (sem_function::equals_private): Fix
pushing and popping of cfun.
---
gcc/ipa-icf-gimple.c | 228 +++++++++++++++----------------------------
gcc/ipa-icf-gimple.h | 12 ++-
gcc/ipa-icf.c | 7 +-
3 files changed, 95 insertions(+), 152 deletions(-)
diff --git a/gcc/ipa-icf-gimple.c b/gcc/ipa-icf-gimple.c
index 4060c0e8eb3..96e688c129d 100644
--- a/gcc/ipa-icf-gimple.c
+++ b/gcc/ipa-icf-gimple.c
@@ -324,6 +324,34 @@ func_checker::compare_memory_operand (tree t1, tree t2)
/* Function compare for equality given trees T1 and T2 which
can be either a constant or a declaration type. */
+void
+func_checker::hash_operand (const_tree arg, inchash::hash &hstate,
+ unsigned int flags)
+{
+ if (arg == NULL_TREE)
+ {
+ hstate.merge_hash (0);
+ return;
+ }
+
+ switch (TREE_CODE (arg))
+ {
+ case FUNCTION_DECL:
+ case VAR_DECL:
+ case LABEL_DECL:
+ case PARM_DECL:
+ case RESULT_DECL:
+ case CONST_DECL:
+ case SSA_NAME:
+ return;
+
+ default:
+ break;
+ }
+
+ return operand_compare::hash_operand (arg, hstate, flags);
+}
+
bool
func_checker::compare_cst_or_decl (tree t1, tree t2)
{
@@ -347,19 +375,6 @@ func_checker::compare_cst_or_decl (tree t1, tree t2)
return true;
case VAR_DECL:
return return_with_debug (compare_variable_decl (t1, t2));
- case FIELD_DECL:
- {
- tree offset1 = DECL_FIELD_OFFSET (t1);
- tree offset2 = DECL_FIELD_OFFSET (t2);
-
- tree bit_offset1 = DECL_FIELD_BIT_OFFSET (t1);
- tree bit_offset2 = DECL_FIELD_BIT_OFFSET (t2);
-
- ret = compare_operand (offset1, offset2)
- && compare_operand (bit_offset1, bit_offset2);
-
- return return_with_debug (ret);
- }
case LABEL_DECL:
{
if (t1 == t2)
@@ -383,165 +398,80 @@ func_checker::compare_cst_or_decl (tree t1, tree t2)
}
}
-/* Function responsible for comparison of various operands T1 and T2.
- If these components, from functions FUNC1 and FUNC2, are equal, true
- is returned. */
-
bool
-func_checker::compare_operand (tree t1, tree t2)
+func_checker::operand_equal_p (const_tree t1, const_tree t2,
+ unsigned int flags)
{
- tree x1, x2, y1, y2, z1, z2;
- bool ret;
+ bool r;
+ if (verify_hash_value (t1, t2, flags, &r))
+ return r;
- if (!t1 && !t2)
+ if (t1 == t2)
return true;
else if (!t1 || !t2)
return false;
- tree tt1 = TREE_TYPE (t1);
- tree tt2 = TREE_TYPE (t2);
-
- if (!func_checker::compatible_types_p (tt1, tt2))
- return false;
-
if (TREE_CODE (t1) != TREE_CODE (t2))
return return_false ();
+ tree tree1 = (tree)const_cast<tree> (t1);
+ tree tree2 = (tree)const_cast<tree> (t2);
+
switch (TREE_CODE (t1))
{
- case CONSTRUCTOR:
+ case FUNCTION_DECL:
+ /* All function decls are in the symbol table and known to match
+ before we start comparing bodies. */
+ return true;
+ case VAR_DECL:
+ return return_with_debug (compare_variable_decl (tree1, tree2));
+ case LABEL_DECL:
{
- unsigned length1 = CONSTRUCTOR_NELTS (t1);
- unsigned length2 = CONSTRUCTOR_NELTS (t2);
-
- if (length1 != length2)
- return return_false ();
-
- for (unsigned i = 0; i < length1; i++)
- if (!compare_operand (CONSTRUCTOR_ELT (t1, i)->value,
- CONSTRUCTOR_ELT (t2, i)->value))
- return return_false();
-
- return true;
+ int *bb1 = m_label_bb_map.get (tree1);
+ int *bb2 = m_label_bb_map.get (tree2);
+ /* Labels can point to another function (non-local GOTOs). */
+ return return_with_debug (bb1 != NULL && bb2 != NULL && *bb1 == *bb2);
}
- case ARRAY_REF:
- case ARRAY_RANGE_REF:
- /* First argument is the array, second is the index. */
- x1 = TREE_OPERAND (t1, 0);
- x2 = TREE_OPERAND (t2, 0);
- y1 = TREE_OPERAND (t1, 1);
- y2 = TREE_OPERAND (t2, 1);
-
- if (!compare_operand (array_ref_low_bound (t1),
- array_ref_low_bound (t2)))
- return return_false_with_msg ("");
- if (!compare_operand (array_ref_element_size (t1),
- array_ref_element_size (t2)))
- return return_false_with_msg ("");
-
- if (!compare_operand (x1, x2))
- return return_false_with_msg ("");
- return compare_operand (y1, y2);
- case MEM_REF:
- {
- x1 = TREE_OPERAND (t1, 0);
- x2 = TREE_OPERAND (t2, 0);
- y1 = TREE_OPERAND (t1, 1);
- y2 = TREE_OPERAND (t2, 1);
-
- /* See if operand is an memory access (the test originate from
- gimple_load_p).
-
- In this case the alias set of the function being replaced must
- be subset of the alias set of the other function. At the moment
- we seek for equivalency classes, so simply require inclussion in
- both directions. */
- if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2)))
- return return_false ();
-
- if (!compare_operand (x1, x2))
- return return_false_with_msg ("");
-
- /* Type of the offset on MEM_REF does not matter. */
- return known_eq (wi::to_poly_offset (y1), wi::to_poly_offset (y2));
- }
- case COMPONENT_REF:
+ case PARM_DECL:
+ case RESULT_DECL:
+ case CONST_DECL:
+ return compare_decl (tree1, tree2);
+ case SSA_NAME:
+ return compare_ssa_name (tree1, tree2);
+ case FIELD_DECL:
{
- x1 = TREE_OPERAND (t1, 0);
- x2 = TREE_OPERAND (t2, 0);
- y1 = TREE_OPERAND (t1, 1);
- y2 = TREE_OPERAND (t2, 1);
+ tree offset1 = DECL_FIELD_OFFSET (t1);
+ tree offset2 = DECL_FIELD_OFFSET (t2);
- ret = compare_operand (x1, x2)
- && compare_cst_or_decl (y1, y2);
+ tree bit_offset1 = DECL_FIELD_BIT_OFFSET (t1);
+ tree bit_offset2 = DECL_FIELD_BIT_OFFSET (t2);
+ bool ret = (compare_operand (offset1, offset2)
+ && compare_operand (bit_offset1, bit_offset2));
return return_with_debug (ret);
}
- /* Virtual table call. */
- case OBJ_TYPE_REF:
- {
- if (!compare_ssa_name (OBJ_TYPE_REF_EXPR (t1), OBJ_TYPE_REF_EXPR (t2)))
- return return_false ();
- if (opt_for_fn (m_source_func_decl, flag_devirtualize)
- && virtual_method_call_p (t1))
- {
- if (tree_to_uhwi (OBJ_TYPE_REF_TOKEN (t1))
- != tree_to_uhwi (OBJ_TYPE_REF_TOKEN (t2)))
- return return_false_with_msg ("OBJ_TYPE_REF token mismatch");
- if (!types_same_for_odr (obj_type_ref_class (t1),
- obj_type_ref_class (t2)))
- return return_false_with_msg ("OBJ_TYPE_REF OTR type mismatch");
- if (!compare_operand (OBJ_TYPE_REF_OBJECT (t1),
- OBJ_TYPE_REF_OBJECT (t2)))
- return return_false_with_msg ("OBJ_TYPE_REF object mismatch");
- }
-
- return return_with_debug (true);
- }
- case IMAGPART_EXPR:
- case REALPART_EXPR:
- case ADDR_EXPR:
- {
- x1 = TREE_OPERAND (t1, 0);
- x2 = TREE_OPERAND (t2, 0);
+ default:
+ break;
+ }
- ret = compare_operand (x1, x2);
- return return_with_debug (ret);
- }
- case BIT_FIELD_REF:
- {
- x1 = TREE_OPERAND (t1, 0);
- x2 = TREE_OPERAND (t2, 0);
- y1 = TREE_OPERAND (t1, 1);
- y2 = TREE_OPERAND (t2, 1);
- z1 = TREE_OPERAND (t1, 2);
- z2 = TREE_OPERAND (t2, 2);
+ return operand_compare::operand_equal_p (t1, t2, flags);
+}
- ret = compare_operand (x1, x2)
- && compare_cst_or_decl (y1, y2)
- && compare_cst_or_decl (z1, z2);
+/* Function responsible for comparison of various operands T1 and T2.
+ If these components, from functions FUNC1 and FUNC2, are equal, true
+ is returned. */
- return return_with_debug (ret);
- }
- case SSA_NAME:
- return compare_ssa_name (t1, t2);
- case INTEGER_CST:
- case COMPLEX_CST:
- case VECTOR_CST:
- case STRING_CST:
- case REAL_CST:
- case FUNCTION_DECL:
- case VAR_DECL:
- case FIELD_DECL:
- case LABEL_DECL:
- case PARM_DECL:
- case RESULT_DECL:
- case CONST_DECL:
- return compare_cst_or_decl (t1, t2);
- default:
- return return_false_with_msg ("Unknown TREE code reached");
- }
+bool
+func_checker::compare_operand (tree t1, tree t2)
+{
+ if (!t1 && !t2)
+ return true;
+ else if (!t1 || !t2)
+ return false;
+ if (operand_equal_p (t1, t2, OEP_MATCH_SIDE_EFFECTS))
+ return true;
+ return return_false_with_msg ("operand_equal_p failed");
}
bool
diff --git a/gcc/ipa-icf-gimple.h b/gcc/ipa-icf-gimple.h
index 351bddfb2f6..f56427b13e5 100644
--- a/gcc/ipa-icf-gimple.h
+++ b/gcc/ipa-icf-gimple.h
@@ -118,7 +118,7 @@ public:
/* A class aggregating all connections and semantic equivalents
for a given pair of semantic function candidates. */
-class func_checker
+class func_checker : operand_compare
{
public:
/* Initialize internal structures for a given SOURCE_FUNC_DECL and
@@ -134,7 +134,7 @@ public:
hash_set<symtab_node *> *ignored_target_nodes = NULL);
/* Memory release routine. */
- ~func_checker();
+ virtual ~func_checker ();
/* Function visits all gimple labels and creates corresponding
mapping between basic blocks and labels. */
@@ -267,6 +267,14 @@ private:
/* Flag if ignore labels in comparison. */
bool m_ignore_labels;
+
+ /* Return true if two operands are equal. The flags fields can be used
+ to specify OEP flags described above. */
+ virtual bool operand_equal_p (const_tree, const_tree, unsigned int flags);
+
+ /* Generate a hash value for an expression. This can be used iteratively
+ by passing a previous result as the HSTATE argument. */
+ virtual void hash_operand (const_tree, inchash::hash &, unsigned flags);
};
} // ipa_icf_gimple namespace
diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
index c9c3cb4a331..8b8cc26a69f 100644
--- a/gcc/ipa-icf.c
+++ b/gcc/ipa-icf.c
@@ -878,9 +878,14 @@ sem_function::equals_private (sem_item *item)
}
/* Checking all basic blocks. */
+ push_cfun (DECL_STRUCT_FUNCTION (decl));
for (unsigned i = 0; i < bb_sorted.length (); ++i)
if(!m_checker->compare_bb (bb_sorted[i], m_compared_func->bb_sorted[i]))
- return return_false();
+ {
+ pop_cfun ();
+ return return_false ();
+ }
+ pop_cfun ();
auto_vec <int> bb_dict;
--
2.22.0
next prev parent reply other threads:[~2019-08-16 11:05 UTC|newest]
Thread overview: 59+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-22 12:50 [RFC] operand_equal_p with valueization Jan Hubicka
2015-05-22 13:40 ` Richard Biener
2015-05-22 14:12 ` Jan Hubicka
2015-05-26 8:18 ` Richard Biener
2015-05-26 19:09 ` Jan Hubicka
2015-05-27 8:49 ` Richard Biener
2019-06-18 11:10 ` [RFC] " Martin Liška
2019-08-06 15:44 ` [PATCH 0/9] IPA ICF overhaul Martin Liska
2019-08-06 15:43 ` [PATCH 1/9] Replace int with boolean in predicate functions Martin Liska
2019-08-07 12:38 ` Richard Biener
2019-08-06 15:43 ` [PATCH 4/9] Strengthen alias_ptr_types_compatible_p in LTO mode Martin Liska
2019-08-07 12:05 ` Richard Biener
2019-08-08 12:09 ` Martin Liška
2019-08-09 11:20 ` Richard Biener
2019-08-06 15:43 ` [PATCH 8/9] Remove comparison for polymorphic types Martin Liska
2019-08-06 15:43 ` [PATCH 2/9] operand_equal_p: add support for FIELD_DECL Martin Liska
2019-08-07 12:21 ` Richard Biener
2019-08-15 14:19 ` Jan Hubicka
2019-08-16 9:28 ` Richard Biener
2019-08-16 12:17 ` Jan Hubicka
2019-09-11 12:58 ` Martin Liška
2019-08-06 15:43 ` [PATCH 7/9] IPA ICF: remove dead code Martin Liska
2019-08-08 14:44 ` Jeff Law
2019-08-06 15:43 ` [PATCH 5/9] Come up with an abstraction Martin Liska
2019-08-08 16:29 ` Michael Matz
2019-08-12 11:49 ` Martin Liška
2019-08-12 12:27 ` Richard Biener
2019-08-12 12:43 ` Martin Liška
2019-08-12 13:26 ` Richard Biener
2019-08-12 14:48 ` Martin Liška
2019-08-14 13:17 ` Richard Biener
2019-08-14 13:50 ` Martin Liška
2019-08-14 14:38 ` Richard Biener
2019-08-16 11:06 ` Martin Liška
2019-09-18 7:56 ` Martin Liška
2019-09-19 11:30 ` Richard Biener
2019-08-12 13:40 ` Michael Matz
2019-08-09 11:48 ` Richard Biener
2019-08-06 15:43 ` [PATCH 9/9] Remove alias set comparison Martin Liska
2019-08-07 15:58 ` Martin Sebor
2019-08-08 8:43 ` Martin Liška
2019-08-08 15:21 ` Martin Sebor
2019-08-08 14:44 ` Jeff Law
2019-08-06 15:43 ` [PATCH 6/9] Integrate that for IPA ICF Martin Liska
2019-08-16 11:10 ` Martin Liška [this message]
2019-08-06 15:55 ` [PATCH 3/9] operand_equal_p: add support for OBJ_TYPE_REF Martin Liska
2019-08-07 12:09 ` Richard Biener
2019-08-15 15:44 ` Jan Hubicka
2019-08-16 9:25 ` Richard Biener
2019-08-16 12:11 ` Jan Hubicka
2019-08-19 14:03 ` Richard Biener
2019-08-19 15:12 ` Jan Hubicka
2019-08-20 14:29 ` Richard Biener
2019-08-20 14:42 ` Jan Hubicka
2019-09-13 12:30 ` Martin Liška
2019-09-16 6:45 ` Richard Biener
2019-08-16 11:53 ` [PATCH 10/N] Use const_tree more in IPA ICF Martin Liška
2019-08-19 13:57 ` Richard Biener
2019-10-30 11:54 ` [PATCH 0/9] IPA ICF overhaul Martin Liška
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=a3a03230-b98c-7b33-6991-1476b73b8ab5@suse.cz \
--to=mliska@suse.cz \
--cc=gcc-patches@gcc.gnu.org \
/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).