> +/* Return true if DECL_ARGUMENT types are valid to be merged. */ Perhaps bettter as
Perform additional check needed to match types function parameters that are used. Unlike for normal parameters it matters if type is TYPE_RESTRICT and we make an assumption that REFERENCE_TYPE parameters are always non-NULL. > + > +bool > +sem_function::compatible_parm_types_p () > +{ > + tree parm1, parm2; > + unsigned i = 0; > + > + for (parm1 = DECL_ARGUMENTS (decl), > + parm2 = DECL_ARGUMENTS (m_compared_func->decl); > + parm1 && parm2; > + parm1 = DECL_CHAIN (parm1), parm2 = DECL_CHAIN (parm2), i++) I think this is still not right. What you wan to to do is to have 1) comparible_parm_types_p (t1,t2, index) that returns true if T1 and T2 are matching with checks bellow: > + { > + if (!param_used_p (i)) > + continue; > + > + if (POINTER_TYPE_P (parm1) > + && (TYPE_RESTRICT (parm1) != TYPE_RESTRICT (parm2))) > + return return_false_with_msg ("argument restrict flag mismatch"); > + /* nonnull_arg_p implies non-zero range to REFERENCE types. */ > + if (POINTER_TYPE_P (parm1) > + && TREE_CODE (parm1) != TREE_CODE (parm2) > + && opt_for_fn (decl, flag_delete_null_pointer_checks)) > + return return_false_with_msg ("pointer wrt reference mismatch"); > + } withtout actually walking the chain. 2) make equals_wpa to walk TYPE_ARG_TYPES of the function type and match them. This is because DECL_ARGUMENTS are part of function body and before you read it into memory, these are NULL Walking DECL_ARGUMENTS here may cause ipa-icf to give up in case one body is read (and thus have some arguments) and other is not. 3) make equals_private walk DECL_ARGUMENTS and match them (well at the time you populate the map.) You probalby can skip matching PARM_DECLS that are !parm_used_p (i) for anything else than types_compatible_p. We only care they are passed the same way by ABI. Everything else is not relevant. Honza