public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [patch] couple of small optimization tweaks
@ 2011-09-24 19:58 Eric Botcazou
  2011-09-25 10:27 ` Richard Guenther
  0 siblings, 1 reply; 2+ messages in thread
From: Eric Botcazou @ 2011-09-24 19:58 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 2105 bytes --]

Hi,

this is a couple of small tweaks to the GIMPLE optimizers aimed at helping 
vectorization in Ada.  More changes will be needed, so no testcases yet.


  1. pass_fold_builtins knows how to delete a call to __builtin_stack_restore 
that is the only real statement in a cleanup, i.e. to turn

<L101>:
  .builtin_stack_restore (saved_stack.116_22);
  resx 1

into

<L101>:
  GIMPLE_NOP
  resx 1

This is valid when the block has no outgoing edge.  Then ehcleanup can in turn 
delete the cleanup as empty.  The problem is that pass_fold_builtins runs very 
late in the game, so most of the optimizations, e.g. vectorization, are 
constrained by the EH structure, all the more so if -fnon-call-exceptions is 
enabled like in Ada.  This happens as soon as you do dynamic stack allocation, 
because then you have a call to __builtin_stack_restore in the FINALLY part of 
a TRY-FINALLY structure, hence the cleanup.

The first change enhances ehcleanup so as to remove this kind of cleanups on 
its own, without the need to wait for pass_fold_builtins.


  2. The introduction of MEM_REF has disabled vectorization for parameters 
passed by reference in Ada.  This used to work because dr_analyze_innermost 
was always building a pointer via build_fold_addr_expr; now, if the base is a 
MEM_REF, it can just take the first operand, which is a reference and not a 
pointer for a parameter passed by reference in Ada.  And simple_iv, unlike 
other functions in tree-scalar-evolution.c, accepts only pointer types:

  type = TREE_TYPE (op);
  if (TREE_CODE (type) != INTEGER_TYPE
      && TREE_CODE (type) != POINTER_TYPE)
    return false;

The second change makes simple_iv use the same test as the other functions in 
tree-scalar-evolution.c.


Bootstrapped/regtested on x86_64-suse-linux, OK for mainline?


2011-09-24  Eric Botcazou  <ebotcazou@adacore.com>

	* tree-eh.c (is_gimple_stack_restore): New predicate.
	(cleanup_empty_eh): Allow a call to __builtin_stack_restore if there
	is no outgoing edge.

	* tree-scalar-evolution.c (simple_iv): Accept all pointer and integral
	types.


-- 
Eric Botcazou

[-- Attachment #2: p.diff --]
[-- Type: text/x-diff, Size: 2051 bytes --]

Index: tree-eh.c
===================================================================
--- tree-eh.c	(revision 179038)
+++ tree-eh.c	(working copy)
@@ -3818,6 +3818,26 @@ infinite_empty_loop_p (edge e_first)
   return inf_loop;
 }
 
+/* Return true if STMT is a call to __builtin_stack_restore.  */
+
+static bool
+is_gimple_stack_restore (gimple stmt)
+{
+  tree callee;
+
+  if (gimple_code (stmt) != GIMPLE_CALL)
+    return false;
+
+  callee = gimple_call_fndecl (stmt);
+
+  if (callee
+      && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
+      && DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_RESTORE)
+    return true;
+
+  return false;
+}
+
 /* Examine the block associated with LP to determine if it's an empty
    handler for its EH region.  If so, attempt to redirect EH edges to
    an outer region.  Return true the CFG was updated in any way.  This
@@ -3863,8 +3883,15 @@ cleanup_empty_eh (eh_landing_pad lp)
       return cleanup_empty_eh_unsplit (bb, e_out, lp);
     }
 
-  /* The block should consist only of a single RESX statement.  */
+  /* The block should consist only of a single RESX statement, modulo a
+     preceding call to __builtin_stack_restore if there is no outgoing
+     edge, since the call can be eliminated in this case.  */
   resx = gsi_stmt (gsi);
+  if (!e_out && is_gimple_stack_restore (resx))
+    {
+      gsi_next (&gsi);
+      resx = gsi_stmt (gsi);
+    }
   if (!is_gimple_resx (resx))
     return false;
   gcc_assert (gsi_one_before_end_p (gsi));
Index: tree-scalar-evolution.c
===================================================================
--- tree-scalar-evolution.c	(revision 179038)
+++ tree-scalar-evolution.c	(working copy)
@@ -3172,8 +3172,8 @@ simple_iv (struct loop *wrto_loop, struc
   iv->no_overflow = false;
 
   type = TREE_TYPE (op);
-  if (TREE_CODE (type) != INTEGER_TYPE
-      && TREE_CODE (type) != POINTER_TYPE)
+  if (!POINTER_TYPE_P (type)
+      && !INTEGRAL_TYPE_P (type))
     return false;
 
   ev = analyze_scalar_evolution_in_loop (wrto_loop, use_loop, op,

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [patch] couple of small optimization tweaks
  2011-09-24 19:58 [patch] couple of small optimization tweaks Eric Botcazou
@ 2011-09-25 10:27 ` Richard Guenther
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Guenther @ 2011-09-25 10:27 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches

On Sat, Sep 24, 2011 at 6:41 PM, Eric Botcazou <ebotcazou@adacore.com> wrote:
> Hi,
>
> this is a couple of small tweaks to the GIMPLE optimizers aimed at helping
> vectorization in Ada.  More changes will be needed, so no testcases yet.
>
>
>  1. pass_fold_builtins knows how to delete a call to __builtin_stack_restore
> that is the only real statement in a cleanup, i.e. to turn
>
> <L101>:
>  .builtin_stack_restore (saved_stack.116_22);
>  resx 1
>
> into
>
> <L101>:
>  GIMPLE_NOP
>  resx 1
>
> This is valid when the block has no outgoing edge.  Then ehcleanup can in turn
> delete the cleanup as empty.  The problem is that pass_fold_builtins runs very
> late in the game, so most of the optimizations, e.g. vectorization, are
> constrained by the EH structure, all the more so if -fnon-call-exceptions is
> enabled like in Ada.  This happens as soon as you do dynamic stack allocation,
> because then you have a call to __builtin_stack_restore in the FINALLY part of
> a TRY-FINALLY structure, hence the cleanup.
>
> The first change enhances ehcleanup so as to remove this kind of cleanups on
> its own, without the need to wait for pass_fold_builtins.
>
>
>  2. The introduction of MEM_REF has disabled vectorization for parameters
> passed by reference in Ada.  This used to work because dr_analyze_innermost
> was always building a pointer via build_fold_addr_expr; now, if the base is a
> MEM_REF, it can just take the first operand, which is a reference and not a
> pointer for a parameter passed by reference in Ada.  And simple_iv, unlike
> other functions in tree-scalar-evolution.c, accepts only pointer types:
>
>  type = TREE_TYPE (op);
>  if (TREE_CODE (type) != INTEGER_TYPE
>      && TREE_CODE (type) != POINTER_TYPE)
>    return false;
>
> The second change makes simple_iv use the same test as the other functions in
> tree-scalar-evolution.c.
>
>
> Bootstrapped/regtested on x86_64-suse-linux, OK for mainline?

Use gimple_call_builtin_p (stmt, BUILT_IN_STACK_RESTORE) instead
of re-inventing it with is_gimple_stack_restore.

Otherwise ok.

Thanks,
Richard.

>
>
> 2011-09-24  Eric Botcazou  <ebotcazou@adacore.com>
>
>        * tree-eh.c (is_gimple_stack_restore): New predicate.
>        (cleanup_empty_eh): Allow a call to __builtin_stack_restore if there
>        is no outgoing edge.
>
>        * tree-scalar-evolution.c (simple_iv): Accept all pointer and integral
>        types.
>
>
> --
> Eric Botcazou
>

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2011-09-25  8:27 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-24 19:58 [patch] couple of small optimization tweaks Eric Botcazou
2011-09-25 10:27 ` Richard Guenther

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).