diff mbox

Optimize away unnecessary clobbers (PR tree-optimization/51117)

Message ID 20111208195740.GQ1957@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Dec. 8, 2011, 7:57 p.m. UTC
Hi!

This patch optimizes away clobber stmts that immediately precede 
GIMPLE_RETURN or GIMPLE_RESX that throws externally, which allows
doing EH cleanups.  For both libstdc++.so.6 and go1 this
results in slight reduction of .gcc_except_table size:
$ readelf -WS obj96[24]/x86*/libstdc*/src/.libs/libstdc++.so.6 | grep gcc_except_table
  [16] .gcc_except_table PROGBITS        00000000000e4714 0e4714 004d1c 00   A  0   0  4
  [16] .gcc_except_table PROGBITS        00000000000e425c 0e425c 004964 00   A  0   0  4
$ readelf -WS obj96[24]/gcc/go1 | grep gcc_except_table
  [17] .gcc_except_table PROGBITS        000000000160c7fc 120c7fc 003d75 00   A  0   0  4
  [17] .gcc_except_table PROGBITS        000000000160c914 120c914 0039be 00   A  0   0  4

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2011-12-08  Jakub Jelinek  <jakub@redhat.com>
	    Andrew Pinski  <apinski@cavium.com>

	PR tree-optimization/51117
	* tree-eh.c (optimize_clobbers): New function.
	(execute_lower_eh_dispatch): Call it.


	Jakub

Comments

Richard Henderson Dec. 8, 2011, 11:53 p.m. UTC | #1
On 12/08/2011 11:57 AM, Jakub Jelinek wrote:
> +      else if (gimple_code (last) == GIMPLE_RETURN
> +	       || (gimple_code (last) == GIMPLE_RESX
> +		   && stmt_can_throw_external (last)))
> +	optimize_clobbers (bb);

If you need to do this for returns as well as resx, then
this is the wrong place, since we'll only get here if there
are exception regions in the current function.

If you don't need to do this for returns... why do them?


r~
Jakub Jelinek Dec. 9, 2011, midnight UTC | #2
On Thu, Dec 08, 2011 at 03:53:40PM -0800, Richard Henderson wrote:
> On 12/08/2011 11:57 AM, Jakub Jelinek wrote:
> > +      else if (gimple_code (last) == GIMPLE_RETURN
> > +	       || (gimple_code (last) == GIMPLE_RESX
> > +		   && stmt_can_throw_external (last)))
> > +	optimize_clobbers (bb);
> 
> If you need to do this for returns as well as resx, then
> this is the wrong place, since we'll only get here if there
> are exception regions in the current function.

I don't need to do it for returns, on the other side those clobbers
before return are useless and removing them perhaps might decrease
memory consumptions (after collect).

But if you prefer to keep it just for GIMPLE_RESX, fine with me.

It can be done anywhere else after inlining and before ehcleanup2
too if you have suggestions where to do it instead.

	Jakub
Richard Henderson Dec. 9, 2011, 12:24 a.m. UTC | #3
On 12/08/2011 04:00 PM, Jakub Jelinek wrote:
> On Thu, Dec 08, 2011 at 03:53:40PM -0800, Richard Henderson wrote:
>> On 12/08/2011 11:57 AM, Jakub Jelinek wrote:
>>> +      else if (gimple_code (last) == GIMPLE_RETURN
>>> +	       || (gimple_code (last) == GIMPLE_RESX
>>> +		   && stmt_can_throw_external (last)))
>>> +	optimize_clobbers (bb);
>>
>> If you need to do this for returns as well as resx, then
>> this is the wrong place, since we'll only get here if there
>> are exception regions in the current function.
> 
> I don't need to do it for returns, on the other side those clobbers
> before return are useless and removing them perhaps might decrease
> memory consumptions (after collect).
> 
> But if you prefer to keep it just for GIMPLE_RESX, fine with me.
> 
> It can be done anywhere else after inlining and before ehcleanup2
> too if you have suggestions where to do it instead.

*shrug* Maybe just a new pass immediately before ehcleanup2?
It's just a quick pass over the basic blocks...


r~
Richard Biener Dec. 9, 2011, 9:35 a.m. UTC | #4
On Fri, Dec 9, 2011 at 1:24 AM, Richard Henderson <rth@redhat.com> wrote:
> On 12/08/2011 04:00 PM, Jakub Jelinek wrote:
>> On Thu, Dec 08, 2011 at 03:53:40PM -0800, Richard Henderson wrote:
>>> On 12/08/2011 11:57 AM, Jakub Jelinek wrote:
>>>> +      else if (gimple_code (last) == GIMPLE_RETURN
>>>> +          || (gimple_code (last) == GIMPLE_RESX
>>>> +              && stmt_can_throw_external (last)))
>>>> +   optimize_clobbers (bb);
>>>
>>> If you need to do this for returns as well as resx, then
>>> this is the wrong place, since we'll only get here if there
>>> are exception regions in the current function.
>>
>> I don't need to do it for returns, on the other side those clobbers
>> before return are useless and removing them perhaps might decrease
>> memory consumptions (after collect).
>>
>> But if you prefer to keep it just for GIMPLE_RESX, fine with me.
>>
>> It can be done anywhere else after inlining and before ehcleanup2
>> too if you have suggestions where to do it instead.
>
> *shrug* Maybe just a new pass immediately before ehcleanup2?
> It's just a quick pass over the basic blocks...

I'd just not care for the ones preceeding a return.  Not at this point
at least.

Richard.

>
> r~
diff mbox

Patch

--- gcc/tree-eh.c.jj	2011-12-01 11:45:06.000000000 +0100
+++ gcc/tree-eh.c	2011-12-08 17:48:58.009908793 +0100
@@ -3173,6 +3173,30 @@  struct gimple_opt_pass pass_lower_resx =
  }
 };
 
+/* Try to optimize var = {v} {CLOBBER} stmts followed just by return
+   or external throw.  */
+
+static void
+optimize_clobbers (basic_block bb)
+{
+  gimple_stmt_iterator gsi = gsi_last_bb (bb);
+  for (gsi_prev (&gsi); !gsi_end_p (gsi);)
+    {
+      gimple stmt = gsi_stmt (gsi);
+      if (is_gimple_debug (stmt))
+	{
+	  gsi_prev (&gsi);
+	  continue;
+	}
+      if (!gimple_assign_single_p (stmt)
+	  || TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
+	  || !TREE_CLOBBER_P (gimple_assign_rhs1 (stmt)))
+	return;
+      unlink_stmt_vdef (stmt);
+      gsi_remove (&gsi, true);
+      release_defs (stmt);
+    }
+}
 
 /* At the end of inlining, we can lower EH_DISPATCH.  Return true when 
    we have found some duplicate labels and removed some edges.  */
@@ -3337,11 +3361,17 @@  execute_lower_eh_dispatch (void)
   FOR_EACH_BB (bb)
     {
       gimple last = last_stmt (bb);
-      if (last && gimple_code (last) == GIMPLE_EH_DISPATCH)
+      if (last == NULL)
+	continue;
+      if (gimple_code (last) == GIMPLE_EH_DISPATCH)
 	{
 	  redirected |= lower_eh_dispatch (bb, last);
 	  any_rewritten = true;
 	}
+      else if (gimple_code (last) == GIMPLE_RETURN
+	       || (gimple_code (last) == GIMPLE_RESX
+		   && stmt_can_throw_external (last)))
+	optimize_clobbers (bb);
     }
 
   if (redirected)