[WIP] Avoid -fcompare-debug regressions due to ipa-polymorphic-call stuff (PR ipa/65610)

Jan Hubicka hubicka@ucw.cz
Mon Mar 30 18:45:00 GMT 2015


> Hi!
> 
> As discussed in the PR, we have -fcompare-debug failures, because
> remove_unused_scope_block_p can sometimes remove blocks relevant
> to ipa-polymorphic-call.c analysis (where it is checking if
> there is some ctor or dtor in BLOCKs from current tree block upward in
> BLOCK_SUPERCONTEXT hierarchy) - and for -fcompare-debug removes them just
> with -g0 and not with -g.
> 
> This patch, bootstrapped/regtested on x86_64-linux and i686-linux, fixes
> that, but only for !cfun->after_inlining - dunno if the polymorphic IPA
> optimizations can happen even after IPA passes, if yes, then 
> +  if (!cfun->after_inlining)
> +    {
> and
> +    }
> should be removed and the code reindented.

We do another round of polymorphic call analysis in PRE pass. (it is not that
important to do so as it is too late to inline the call, but we do that)

> Also, looking for better name of the function if you have ideas.

I think inlined_polymorphic_ctor_dtor_block_p may be descriptive name? :)

> +/* Return a FUNCTION_DECL if BLOCK represents a constructor or destructor.
> +   If CHECK_CLONES is true, also check for clones of ctor/dtors.  */
> +
> +tree
> +ctor_dtor_block_p (tree block, bool check_clones)
> +{
> +  tree fn = BLOCK_ABSTRACT_ORIGIN (block);
> +  if (fn == NULL || TREE_CODE (fn) != FUNCTION_DECL)
> +    return NULL_TREE;
> +
> +  if (TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
> +      || (!DECL_CXX_CONSTRUCTOR_P (fn) && !DECL_CXX_DESTRUCTOR_P (fn)))
> +    {
> +      if (!check_clones)
> +	return NULL_TREE;
> +
> +      /* Watch for clones where we constant propagated the first
> +	 argument (pointer to the instance).  */
> +      fn = DECL_ABSTRACT_ORIGIN (fn);
> +      if (!fn
> +	  || TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
> +	  || (!DECL_CXX_CONSTRUCTOR_P (fn) && !DECL_CXX_DESTRUCTOR_P (fn)))
> +	return NULL_TREE;
> +    }
> +
> +  if (flags_from_decl_or_type (fn) & (ECF_PURE | ECF_CONST))
> +    return NULL_TREE;
> +
> +  return fn;
> +}

Looking at it, the function is unnecesarily conservative - it can rule out all
non-polymorphic cdtors.  I will drop that to my TODO for next stage1.

There is one extra occurence of the same code in param_type_may_change_p.
Please unify it, too.  I should not have introduced the duplicates at first place
but initial version of the code had those all different.

> --- gcc/tree-ssa-live.c.jj	2015-03-09 08:05:13.000000000 +0100
> +++ gcc/tree-ssa-live.c	2015-03-30 11:57:25.492574441 +0200
> @@ -76,6 +76,10 @@ along with GCC; see the file COPYING3.
>  #include "diagnostic-core.h"
>  #include "debug.h"
>  #include "tree-ssa.h"
> +#include "lto-streamer.h"
> +#include "ipa-ref.h"
> +#include "cgraph.h"
> +#include "ipa-utils.h"

Header flattening still makes me sad ;(
>  
>  #ifdef ENABLE_CHECKING
>  static void  verify_live_on_entry (tree_live_info_p);
> @@ -509,11 +513,30 @@ mark_scope_block_unused (tree scope)
>     done by the inliner.  */
>  
>  static bool
> -remove_unused_scope_block_p (tree scope)
> +remove_unused_scope_block_p (tree scope, bool in_ctor_dtor_block)
>  {
>    tree *t, *next;
>    bool unused = !TREE_USED (scope);
>    int nsubblocks = 0;
> +  if (!cfun->after_inlining)
> +    {
> +      /* For ipa-polymorphic-call.c purposes, preserve blocks:
> +	 1) with BLOCK_ABSTRACT_ORIGIN of a ctor/dtor or their clones  */
> +      if (ctor_dtor_block_p (scope, true))

Please drop the cfun->after_inlining check.
I do not think it is major problem - the blocks of inlined cdtors should not be that
common (we can alternatively add the check for the polymorphic type in the predicate
above - polymorphic cdtors are even less common, but I doubt that is going to make
memory use difference).

Patch is OK with these changes.
Thanks a lot!
Honza



More information about the Gcc-patches mailing list