Patchwork [PR,45934,4/5] Introduce a flag to control devirtualization

login
register
mail settings
Submitter Martin Jambor
Date Dec. 15, 2010, 4:49 p.m.
Message ID <20101215164917.406217162@virgil.suse.cz>
Download mbox | patch
Permalink /patch/75657/
State New
Headers show

Comments

Martin Jambor - Dec. 15, 2010, 4:49 p.m.
For various reasons it is probably desirable to be able to switch
devirtualization off.  This is to be accomplished by a flag
-fdevirtualize added by this patch.  I am open to suggestions for a
better name, I was considering that we somehow include in the name
that we mean type based devirtualization but then I thought I'd
suggest the simple name first.

For IPA devirtualization, it is enough never to produce TYPE_KNOWN
jump messages in order to avoid any devirtualization when doing IPA-CP
or inlining.  However, I also made the flag disable the type-change
detection mechanism so that it can be used to debug or workaround
problems there.

Intraprocedural devirtualization is another matter.  The main
type-based intraprocedural devirtualization is implemented in the next
patch and the new version has a test included in it.  However, we do
some very simple devirtualization when folding too and I have decided
not to condition that on the new flag because we would regress at -O1.
However, adding the test is very simple if that is not considered a
problem.  Alternatively, we can also decide to run both
intraprocedural devirtualizations at -O1 if we decide to be even
bolder.

I have bootstrapped and tested this patch on x86_64-linux and it has
passed make check-c++ on i686 together with the next patch too.  I
have also verified the documentation changes by make pdf.  I'd be
happy to respond to any comments and/or suggestions.

Thanks,

Martin


2010-12-13  Martin Jambor  <mjambor@suse.cz>

	* common.opt (fdevirtualize): New flag.
	* doc/invoke.texi (Option Summary): Document it.
	* opts.c (default_options_table): Add devirtualize flag.
	* ipa-prop.c (detect_type_change): Return immediately if
	devirtualize flag is not set.
	(detect_type_change_ssa): Likewise.
	(compute_known_type_jump_func): Likewise.
	(ipa_analyze_virtual_call_uses): Likewise.


Index: icln/gcc/gimple-fold.c
===================================================================
--- icln.orig/gcc/gimple-fold.c
+++ icln/gcc/gimple-fold.c
Ralf Wildenhues - Dec. 15, 2010, 6:13 p.m.
* Martin Jambor wrote on Wed, Dec 15, 2010 at 05:49:06PM CET:
> 	* common.opt (fdevirtualize): New flag.
> 	* doc/invoke.texi (Option Summary): Document it.
> 	* opts.c (default_options_table): Add devirtualize flag.
> 	* ipa-prop.c (detect_type_change): Return immediately if
> 	devirtualize flag is not set.
> 	(detect_type_change_ssa): Likewise.
> 	(compute_known_type_jump_func): Likewise.
> 	(ipa_analyze_virtual_call_uses): Likewise.

> --- icln.orig/gcc/doc/invoke.texi
> +++ icln/gcc/doc/invoke.texi

> @@ -6420,6 +6421,14 @@ Otherwise it is enabled at all levels: @
>  @option{-O2}, @option{-O3}, @option{-Os}.  Passes that use the information
>  are enabled independently at different optimization levels.
>  
> +@item -fdevirtualize
> +@opindex fdevirtualize
> +Attempt to convert calls to virtual functions to direct calls.  This
> +is done both within a procedure and inteprocedurally as part of

interprocedurally

> +indirect inlining (@code{-findirect-inlining}) and inteprocedural copy

interprocedural

> +propagation (@option{-fipa-cp}).
> +Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.

Cheers,
Ralf
Martin Jambor - Dec. 16, 2010, 11:28 a.m.
Hi,

On Wed, Dec 15, 2010 at 07:13:39PM +0100, Ralf Wildenhues wrote:
> * Martin Jambor wrote on Wed, Dec 15, 2010 at 05:49:06PM CET:
> > 	* common.opt (fdevirtualize): New flag.
> > 	* doc/invoke.texi (Option Summary): Document it.
> > 	* opts.c (default_options_table): Add devirtualize flag.
> > 	* ipa-prop.c (detect_type_change): Return immediately if
> > 	devirtualize flag is not set.
> > 	(detect_type_change_ssa): Likewise.
> > 	(compute_known_type_jump_func): Likewise.
> > 	(ipa_analyze_virtual_call_uses): Likewise.
> 
> > --- icln.orig/gcc/doc/invoke.texi
> > +++ icln/gcc/doc/invoke.texi
> 
> > @@ -6420,6 +6421,14 @@ Otherwise it is enabled at all levels: @
> >  @option{-O2}, @option{-O3}, @option{-Os}.  Passes that use the information
> >  are enabled independently at different optimization levels.
> >  
> > +@item -fdevirtualize
> > +@opindex fdevirtualize
> > +Attempt to convert calls to virtual functions to direct calls.  This
> > +is done both within a procedure and inteprocedurally as part of
> 
> interprocedurally
> 
> > +indirect inlining (@code{-findirect-inlining}) and inteprocedural copy
> 
> interprocedural

... and constant propagation, not copy propagation.

Thanks, I must have forgotten to switch on my spell checker.  All of
the above is corrected in my version of the patch now.

Martin

> 
> > +propagation (@option{-fipa-cp}).
> > +Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
> 
> Cheers,
> Ralf
Richard Guenther - Jan. 13, 2011, 11:58 a.m.
On Wed, 15 Dec 2010, Martin Jambor wrote:

> For various reasons it is probably desirable to be able to switch
> devirtualization off.  This is to be accomplished by a flag
> -fdevirtualize added by this patch.  I am open to suggestions for a
> better name, I was considering that we somehow include in the name
> that we mean type based devirtualization but then I thought I'd
> suggest the simple name first.
> 
> For IPA devirtualization, it is enough never to produce TYPE_KNOWN
> jump messages in order to avoid any devirtualization when doing IPA-CP
> or inlining.  However, I also made the flag disable the type-change
> detection mechanism so that it can be used to debug or workaround
> problems there.
> 
> Intraprocedural devirtualization is another matter.  The main
> type-based intraprocedural devirtualization is implemented in the next
> patch and the new version has a test included in it.  However, we do
> some very simple devirtualization when folding too and I have decided
> not to condition that on the new flag because we would regress at -O1.
> However, adding the test is very simple if that is not considered a
> problem.  Alternatively, we can also decide to run both
> intraprocedural devirtualizations at -O1 if we decide to be even
> bolder.
> 
> I have bootstrapped and tested this patch on x86_64-linux and it has
> passed make check-c++ on i686 together with the next patch too.  I
> have also verified the documentation changes by make pdf.  I'd be
> happy to respond to any comments and/or suggestions.

Ok with the suggested typo changes.

Thanks,
Richard.

> Thanks,
> 
> Martin
> 
> 
> 2010-12-13  Martin Jambor  <mjambor@suse.cz>
> 
> 	* common.opt (fdevirtualize): New flag.
> 	* doc/invoke.texi (Option Summary): Document it.
> 	* opts.c (default_options_table): Add devirtualize flag.
> 	* ipa-prop.c (detect_type_change): Return immediately if
> 	devirtualize flag is not set.
> 	(detect_type_change_ssa): Likewise.
> 	(compute_known_type_jump_func): Likewise.
> 	(ipa_analyze_virtual_call_uses): Likewise.
> 
> 
> Index: icln/gcc/common.opt
> ===================================================================
> --- icln.orig/gcc/common.opt
> +++ icln/gcc/common.opt
> @@ -911,6 +911,10 @@ fdelete-null-pointer-checks
>  Common Report Var(flag_delete_null_pointer_checks) Init(1) Optimization
>  Delete useless null pointer checks
>  
> +fdevirtualize
> +Common Report Var(flag_devirtualize) Optimization
> +Try to convert virtual calls to direct ones.
> +
>  fdiagnostics-show-location=
>  Common Joined RejectNegative Enum(diagnostic_prefixing_rule)
>  -fdiagnostics-show-location=[once|every-line]	How often to emit source location at the beginning of line-wrapped diagnostics
> Index: icln/gcc/ipa-prop.c
> ===================================================================
> --- icln.orig/gcc/ipa-prop.c
> +++ icln/gcc/ipa-prop.c
> @@ -514,7 +514,7 @@ detect_type_change (tree arg, tree base,
>  		       || handled_component_p (arg));
>    /* Const calls cannot call virtual methods through VMT and so type changes do
>       not matter.  */
> -  if (!gimple_vuse (call))
> +  if (!flag_devirtualize || !gimple_vuse (call))
>      return false;
>  
>    ao.ref = arg;
> @@ -568,7 +568,8 @@ static bool
>  detect_type_change_ssa (tree arg, gimple call, struct ipa_jump_func *jfunc)
>  {
>    gcc_checking_assert (TREE_CODE (arg) == SSA_NAME);
> -  if (!POINTER_TYPE_P (TREE_TYPE (arg))
> +  if (!flag_devirtualize
> +      || !POINTER_TYPE_P (TREE_TYPE (arg))
>        || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != RECORD_TYPE)
>      return false;
>  
> @@ -770,7 +771,8 @@ compute_known_type_jump_func (tree op, s
>    HOST_WIDE_INT offset, size, max_size;
>    tree base, binfo;
>  
> -  if (TREE_CODE (op) != ADDR_EXPR
> +  if (!flag_devirtualize
> +      || TREE_CODE (op) != ADDR_EXPR
>        || TREE_CODE (TREE_TYPE (TREE_TYPE (op))) != RECORD_TYPE)
>      return;
>  
> @@ -1459,6 +1461,9 @@ ipa_analyze_virtual_call_uses (struct cg
>    tree var;
>    int index;
>  
> +  if (!flag_devirtualize)
> +    return;
> +
>    if (TREE_CODE (obj) == ADDR_EXPR)
>      {
>        do
> Index: icln/gcc/opts.c
> ===================================================================
> --- icln.orig/gcc/opts.c
> +++ icln/gcc/opts.c
> @@ -485,6 +485,7 @@ static const struct default_options defa
>      { OPT_LEVELS_2_PLUS, OPT_ftree_pre, NULL, 1 },
>      { OPT_LEVELS_2_PLUS, OPT_ftree_switch_conversion, NULL, 1 },
>      { OPT_LEVELS_2_PLUS, OPT_fipa_cp, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 },
>      { OPT_LEVELS_2_PLUS, OPT_fipa_sra, NULL, 1 },
>      { OPT_LEVELS_2_PLUS, OPT_falign_loops, NULL, 1 },
>      { OPT_LEVELS_2_PLUS, OPT_falign_jumps, NULL, 1 },
> Index: icln/gcc/doc/invoke.texi
> ===================================================================
> --- icln.orig/gcc/doc/invoke.texi
> +++ icln/gcc/doc/invoke.texi
> @@ -340,8 +340,8 @@ Objective-C and Objective-C++ Dialects}.
>  -fcprop-registers -fcrossjumping @gol
>  -fcse-follow-jumps -fcse-skip-blocks -fcx-fortran-rules @gol
>  -fcx-limited-range @gol
> --fdata-sections -fdce -fdce @gol
> --fdelayed-branch -fdelete-null-pointer-checks -fdse -fdse @gol
> +-fdata-sections -fdce -fdce -fdelayed-branch @gol
> +-fdelete-null-pointer-checks -fdse -fdevirtualize -fdse @gol
>  -fearly-inlining -fipa-sra -fexpensive-optimizations -ffast-math @gol
>  -ffinite-math-only -ffloat-store -fexcess-precision=@var{style} @gol
>  -fforward-propagate -ffp-contract=@var{style} -ffunction-sections @gol
> @@ -5917,6 +5917,7 @@ also turns on the following optimization
>  -fcrossjumping @gol
>  -fcse-follow-jumps  -fcse-skip-blocks @gol
>  -fdelete-null-pointer-checks @gol
> +-fdevirtualize @gol
>  -fexpensive-optimizations @gol
>  -fgcse  -fgcse-lm  @gol
>  -finline-small-functions @gol
> @@ -6420,6 +6421,14 @@ Otherwise it is enabled at all levels: @
>  @option{-O2}, @option{-O3}, @option{-Os}.  Passes that use the information
>  are enabled independently at different optimization levels.
>  
> +@item -fdevirtualize
> +@opindex fdevirtualize
> +Attempt to convert calls to virtual functions to direct calls.  This
> +is done both within a procedure and inteprocedurally as part of
> +indirect inlining (@code{-findirect-inlining}) and inteprocedural copy
> +propagation (@option{-fipa-cp}).
> +Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
> +
>  @item -fexpensive-optimizations
>  @opindex fexpensive-optimizations
>  Perform a number of minor optimizations that are relatively expensive.
> Index: icln/gcc/gimple-fold.c
> ===================================================================
> --- icln.orig/gcc/gimple-fold.c
> +++ icln/gcc/gimple-fold.c
> 
>

Patch

Index: icln/gcc/common.opt
===================================================================
--- icln.orig/gcc/common.opt
+++ icln/gcc/common.opt
@@ -911,6 +911,10 @@  fdelete-null-pointer-checks
 Common Report Var(flag_delete_null_pointer_checks) Init(1) Optimization
 Delete useless null pointer checks
 
+fdevirtualize
+Common Report Var(flag_devirtualize) Optimization
+Try to convert virtual calls to direct ones.
+
 fdiagnostics-show-location=
 Common Joined RejectNegative Enum(diagnostic_prefixing_rule)
 -fdiagnostics-show-location=[once|every-line]	How often to emit source location at the beginning of line-wrapped diagnostics
Index: icln/gcc/ipa-prop.c
===================================================================
--- icln.orig/gcc/ipa-prop.c
+++ icln/gcc/ipa-prop.c
@@ -514,7 +514,7 @@  detect_type_change (tree arg, tree base,
 		       || handled_component_p (arg));
   /* Const calls cannot call virtual methods through VMT and so type changes do
      not matter.  */
-  if (!gimple_vuse (call))
+  if (!flag_devirtualize || !gimple_vuse (call))
     return false;
 
   ao.ref = arg;
@@ -568,7 +568,8 @@  static bool
 detect_type_change_ssa (tree arg, gimple call, struct ipa_jump_func *jfunc)
 {
   gcc_checking_assert (TREE_CODE (arg) == SSA_NAME);
-  if (!POINTER_TYPE_P (TREE_TYPE (arg))
+  if (!flag_devirtualize
+      || !POINTER_TYPE_P (TREE_TYPE (arg))
       || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != RECORD_TYPE)
     return false;
 
@@ -770,7 +771,8 @@  compute_known_type_jump_func (tree op, s
   HOST_WIDE_INT offset, size, max_size;
   tree base, binfo;
 
-  if (TREE_CODE (op) != ADDR_EXPR
+  if (!flag_devirtualize
+      || TREE_CODE (op) != ADDR_EXPR
       || TREE_CODE (TREE_TYPE (TREE_TYPE (op))) != RECORD_TYPE)
     return;
 
@@ -1459,6 +1461,9 @@  ipa_analyze_virtual_call_uses (struct cg
   tree var;
   int index;
 
+  if (!flag_devirtualize)
+    return;
+
   if (TREE_CODE (obj) == ADDR_EXPR)
     {
       do
Index: icln/gcc/opts.c
===================================================================
--- icln.orig/gcc/opts.c
+++ icln/gcc/opts.c
@@ -485,6 +485,7 @@  static const struct default_options defa
     { OPT_LEVELS_2_PLUS, OPT_ftree_pre, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_ftree_switch_conversion, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_fipa_cp, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_fipa_sra, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_falign_loops, NULL, 1 },
     { OPT_LEVELS_2_PLUS, OPT_falign_jumps, NULL, 1 },
Index: icln/gcc/doc/invoke.texi
===================================================================
--- icln.orig/gcc/doc/invoke.texi
+++ icln/gcc/doc/invoke.texi
@@ -340,8 +340,8 @@  Objective-C and Objective-C++ Dialects}.
 -fcprop-registers -fcrossjumping @gol
 -fcse-follow-jumps -fcse-skip-blocks -fcx-fortran-rules @gol
 -fcx-limited-range @gol
--fdata-sections -fdce -fdce @gol
--fdelayed-branch -fdelete-null-pointer-checks -fdse -fdse @gol
+-fdata-sections -fdce -fdce -fdelayed-branch @gol
+-fdelete-null-pointer-checks -fdse -fdevirtualize -fdse @gol
 -fearly-inlining -fipa-sra -fexpensive-optimizations -ffast-math @gol
 -ffinite-math-only -ffloat-store -fexcess-precision=@var{style} @gol
 -fforward-propagate -ffp-contract=@var{style} -ffunction-sections @gol
@@ -5917,6 +5917,7 @@  also turns on the following optimization
 -fcrossjumping @gol
 -fcse-follow-jumps  -fcse-skip-blocks @gol
 -fdelete-null-pointer-checks @gol
+-fdevirtualize @gol
 -fexpensive-optimizations @gol
 -fgcse  -fgcse-lm  @gol
 -finline-small-functions @gol
@@ -6420,6 +6421,14 @@  Otherwise it is enabled at all levels: @
 @option{-O2}, @option{-O3}, @option{-Os}.  Passes that use the information
 are enabled independently at different optimization levels.
 
+@item -fdevirtualize
+@opindex fdevirtualize
+Attempt to convert calls to virtual functions to direct calls.  This
+is done both within a procedure and inteprocedurally as part of
+indirect inlining (@code{-findirect-inlining}) and inteprocedural copy
+propagation (@option{-fipa-cp}).
+Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
+
 @item -fexpensive-optimizations
 @opindex fexpensive-optimizations
 Perform a number of minor optimizations that are relatively expensive.