From 602c6cfc79ce4ae61e277107e0a60079c1a93a97 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Fri, 13 Nov 2020 15:58:41 +0100 Subject: Improve handling of memory operands in ipa-icf 2/4 this patch iplements new class ao_compare that is derived from operand_compare and adds a method to compare and hash ao_refs. This is used by ICF to enable more merging. Comparsion is done as follows 1) Verify that the memory access will happen at the same address and will have same size. For constant addresses this is done by comparing ao_ref_base and offset/size For varable accesses it uses operand_equal_p but with OEP_ADDRESS (that does not match TBAA metadata) and then operand_equal_p on type size. 2) Compare alignments. I use get_object_alignment_1 like ipa-icf did before revamp to operand_equal_p in gcc 9. I noticed that return value is bitodd so added a comment 3) Match MR_DEPENDENCE_CLIQUE At this point the memory refrences are same except for TBAA information. We continue by checking 4) ref and base alias sets. Now if lto streaming is going to happen instead of comparing alias sets themselves we compare alias_ptr_types (the patch depends on the ao_ref_alias_ptr_tyep and ao_ref_base_alias_ptr_type acessors I sent yesterday) 5) See if accesses are view converted. If they are we are done since access path is not present 6) Compare the part of access path relevant for TBAA. I recall FRE relies on the fact that if base and ref types are same the access path is, but I do not thing this is 100% reliable especially with LTO alias sets. The access path comparsion logic is also useful for modref (for next stage1). Tracking the access paths improves quite noticeably disambiguation in C++ code by being able to distinquish different fields of same type within a struct. I had the comparsion logic in my tree for some time and it seems to work quite well. During cc1plus build we have some cases where we find mismatch after matching the base/ref alias sets. These are due to failed type merging: access path oracle in LTO uses TYPE_MAIN_VARIANTs. I implemented relatively basic hashing using base and offset. gcc/ChangeLog: * ipa-icf-gimple.c: Include tree-ssa-alias-compare.h. (find_checker::func_checker): Initialize m_tbaa. (func_checker::hash_operand): Use hash_ao_ref for memory accesses. (func_checker::compare_operand): Use compare_ao_refs for memory accesses. (func_checker::cmopare_gimple_assign): Do not check LHS types of memory stores. * ipa-icf-gimple.h (func_checker): Derive from ao_compare; add m_tbaa. * ipa-icf.c: Include tree-ssa-alias-compare.h. (sem_function::equals_private): Update call of func_checker::func_checker. * ipa-utils.h (lto_streaming_expected_p): New inline predicate. * tree-ssa-alias-compare.h: New file. * tree-ssa-alias.c: Include tree-ssa-alias-compare.h and bultins.h (view_converted_memref_p): New function. (types_equal_for_same_type_for_tbaa_p): New function. (ao_ref_alias_ptr_type, ao_ref_base_alias_ptr_type): New functions. (ao_compare::compare_ao_refs): New member function. (ao_compare::hash_ao_ref): New function * tree-ssa-alias.h (ao_ref_base_alias_ptr_type, ao_ref_alias_ptr_type): Declare. gcc/testsuite/ChangeLog: * c-c++-common/Wstringop-overflow-2.c: Disable ICF. * g++.dg/warn/Warray-bounds-8.C: Disable ICF. --- gcc/ipa-utils.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'gcc/ipa-utils.h') diff --git a/gcc/ipa-utils.h b/gcc/ipa-utils.h index 178c2cb..880e527 100644 --- a/gcc/ipa-utils.h +++ b/gcc/ipa-utils.h @@ -265,4 +265,16 @@ get_odr_name_for_type (tree type) return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (type_name)); } +/* Return true if we are going to do LTO streaming. */ + +inline bool +lto_streaming_expected_p () +{ + /* Compilation before LTO stremaing. */ + if (flag_lto && !in_lto_p && symtab->state < IPA_SSA_AFTER_INLINING) + return true; + /* WPA or incremental link. */ + return (flag_wpa || flag_incremental_link == INCREMENTAL_LINK_LTO); +} + #endif /* GCC_IPA_UTILS_H */ -- cgit v1.1 From 18dd295638724b455e072cd790451ace15a3d463 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Tue, 17 Nov 2020 15:38:13 +0100 Subject: Make ltrans type canonicals compatible with WPA ones This patch fixes profiledbootstrap failure with LTO enabled. Not refining alias sets from WPA to ltrans time is a good invariant to maintain and the canonical type hash behaves this way. However I broke this with the ODR logic. Normally we define canonical types for C++ ODR types according to their type names. However to make ODR types compatible with C types we check if structurally equivalent C type exists and if so, we ignore ODR names giving up on the precision. This however is not stable between WPA and ltrans since at ltrans the type merging does not see as many types as WPA does. To make this consistent the patch makes WPA ODR_TYPE_P == 0 for ODR types that conflicted with non-ODR type. I had to drop one sanity check in ipa-utils.h (that I think is not very important - I added it while introducing CXX_ODR_P machinery) and also it now may happen that we query odr_based_tbaa_p before registering first ODR type so we do not want to ICE here. ODR type registration happens early to produce ODR violation warings. Those are not done at ltrans, so dropping the registration is safe. The type will still be added while computing the type inheritance graph if needed for devirtualization (and late devirtualization is not very useful anyway since it won't enable inlining). gcc/ChangeLog: PR bootstrap/97857 * ipa-devirt.c (odr_based_tbaa_p): Do not ICE when odr_hash is not initialized * ipa-utils.h (type_with_linkage_p): Do not sanity check CXX_ODR_P. * tree-streamer-out.c (pack_ts_type_common_value_fields): Set CXX_ODR_P according to the canonical type. gcc/lto/ChangeLog: PR bootstrap/97857 * lto-common.c (gimple_register_canonical_type_1): Only register types with TYPE_CXX_ODR_P flag; sanity check that no conflict happens at ltrans time. --- gcc/ipa-utils.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'gcc/ipa-utils.h') diff --git a/gcc/ipa-utils.h b/gcc/ipa-utils.h index 880e527..91571d8 100644 --- a/gcc/ipa-utils.h +++ b/gcc/ipa-utils.h @@ -211,8 +211,6 @@ type_with_linkage_p (const_tree t) if (!TYPE_CONTEXT (t)) return false; - gcc_checking_assert (TREE_CODE (t) == ENUMERAL_TYPE || TYPE_CXX_ODR_P (t)); - return true; } -- cgit v1.1