diff mbox

Minor tweak to size functions

Message ID 1961080.nQ7DLJsfTp@polaris
State New
Headers show

Commit Message

Eric Botcazou April 27, 2015, 10:26 a.m. UTC
The size functions are used by the Ada compiler to factor out the large size 
computations in self-referential types (dynamic types whose size depends on a 
discriminant in the object).  We generate useless leaf size functions for size 
expressions involving discriminants:

_Global.Sz4_Q 
(ada__streams__stream_element_count___XDLU_0__9223372036854775807 p0)
{
  return (bitsizetype) p0 * 8;


_Global.Sz5_Q 
(ada__streams__stream_element_count___XDLU_0__9223372036854775807 p0)
{
  return (sizetype) p0;


_Global.Sz6_Q 
(ada__streams__stream_element_count___XDLU_0__9223372036854775807 p0)
{
  return (bitsizetype) p0 * 8;


_Global.Sz7_Q 
(ada__streams__stream_element_count___XDLU_0__9223372036854775807 p0)
{
  return (sizetype) p0;


The wrapped expressions are simple arithmetic operations so there is no real 
point in creating a size function for them.  That's already ensured for non-
leaf size functions (size functions calling other size functions) and it's 
immediate to extend it down to the leaves.

Tested on x86_64-suse-linux, applied on the mainline (this only affects the 
Ada compiler).  The tree-cfg.c hunk adds the missing curly bracket at the end 
in the above dumps, applied as obvious.


2015-04-27  Eric Botcazou  <ebotcazou@adacore.com>

	* stor-layout.c (self_referential_component_ref_p): New predicate.
	(copy_self_referential_tree_r): Use it.
	(self_referential_size): Punt for simple operations directly involving
	self-referential component references.
	* tree-cfg.c (dump_function_to_file): Add missing final curly bracket.
diff mbox

Patch

Index: stor-layout.c
===================================================================
--- stor-layout.c	(revision 222439)
+++ stor-layout.c	(working copy)
@@ -127,6 +127,20 @@  variable_size (tree size)
 /* An array of functions used for self-referential size computation.  */
 static GTY(()) vec<tree, va_gc> *size_functions;
 
+/* Return true if T is a self-referential component reference.  */
+
+static bool
+self_referential_component_ref_p (tree t)
+{
+  if (TREE_CODE (t) != COMPONENT_REF)
+    return false;
+
+  while (REFERENCE_CLASS_P (t))
+    t = TREE_OPERAND (t, 0);
+
+  return (TREE_CODE (t) == PLACEHOLDER_EXPR);
+}
+
 /* Similar to copy_tree_r but do not copy component references involving
    PLACEHOLDER_EXPRs.  These nodes are spotted in find_placeholder_in_expr
    and substituted in substitute_in_expr.  */
@@ -154,19 +168,10 @@  copy_self_referential_tree_r (tree *tp,
     }
 
   /* Default case: the component reference.  */
-  else if (code == COMPONENT_REF)
+  else if (self_referential_component_ref_p (*tp))
     {
-      tree inner;
-      for (inner = TREE_OPERAND (*tp, 0);
-	   REFERENCE_CLASS_P (inner);
-	   inner = TREE_OPERAND (inner, 0))
-	;
-
-      if (TREE_CODE (inner) == PLACEHOLDER_EXPR)
-	{
-	  *walk_subtrees = 0;
-	  return NULL_TREE;
-	}
+      *walk_subtrees = 0;
+      return NULL_TREE;
     }
 
   /* We're not supposed to have them in self-referential size trees
@@ -199,7 +204,7 @@  self_referential_size (tree size)
 
   /* Do not factor out simple operations.  */
   t = skip_simple_constant_arithmetic (size);
-  if (TREE_CODE (t) == CALL_EXPR)
+  if (TREE_CODE (t) == CALL_EXPR || self_referential_component_ref_p (t))
     return size;
 
   /* Collect the list of self-references in the expression.  */
Index: tree-cfg.c
===================================================================
--- tree-cfg.c	(revision 222439)
+++ tree-cfg.c	(working copy)
@@ -7441,7 +7441,11 @@  dump_function_to_file (tree fndecl, FILE
       else
 	{
 	  if (!ignore_topmost_bind)
-	    fprintf (file, "{\n");
+	    {
+	      fprintf (file, "{\n");
+	      /* No topmost bind, pretend it's ignored for later.  */
+	      ignore_topmost_bind = true;
+	    }
 	  indent = 2;
 	}