public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [patch] Move generic tree functions from expr.h to tree.h
@ 2015-05-27 10:25 Eric Botcazou
  2015-05-27 11:01 ` Richard Biener
  0 siblings, 1 reply; 5+ messages in thread
From: Eric Botcazou @ 2015-05-27 10:25 UTC (permalink / raw)
  To: gcc-patches

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

Hi,

a few functions manipulating generic trees from expr.c are useful for FEs too 
and some of them (array_ref_{low,up}_bound, get_inner_reference) are already 
declared in tree.h instead of expr.h.  This patch moves 3 similar functions 
(array_ref_element_size, array_at_struct_end_p, component_ref_field_offset).

Tested on x86_64-suse-linux, OK for the mainline?


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

	* expr.h (array_at_struct_end_p): Move to...
	(array_ref_element_size): Likewise.
	(component_ref_field_offset): Likewise.
	* tree.h (array_ref_element_size): ...here.
	(array_at_struct_end_p): Likewise.
	(component_ref_field_offset): Likewise.
	* expr.c (array_ref_up_bound): Move around.


-- 
Eric Botcazou

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

Index: expr.h
===================================================================
--- expr.h	(revision 223736)
+++ expr.h	(working copy)
@@ -281,19 +281,10 @@ rtx get_personality_function (tree);
 extern int can_move_by_pieces (unsigned HOST_WIDE_INT, unsigned int);
 
 extern unsigned HOST_WIDE_INT highest_pow2_factor (const_tree);
-bool array_at_struct_end_p (tree);
-
-/* Return a tree of sizetype representing the size, in bytes, of the element
-   of EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
-extern tree array_ref_element_size (tree);
 
 extern bool categorize_ctor_elements (const_tree, HOST_WIDE_INT *,
 				      HOST_WIDE_INT *, bool *);
 
-/* Return a tree representing the offset, in bytes, of the field referenced
-   by EXP.  This does not include any offset in DECL_FIELD_BIT_OFFSET.  */
-extern tree component_ref_field_offset (tree);
-
 extern void expand_operands (tree, tree, rtx, rtx*, rtx*,
 			     enum expand_modifier);
 
Index: expr.c
===================================================================
--- expr.c	(revision 223736)
+++ expr.c	(working copy)
@@ -7002,6 +7002,23 @@ array_ref_low_bound (tree exp)
   return build_int_cst (TREE_TYPE (TREE_OPERAND (exp, 1)), 0);
 }
 
+/* Return a tree representing the upper bound of the array mentioned in
+   EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
+
+tree
+array_ref_up_bound (tree exp)
+{
+  tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0)));
+
+  /* If there is a domain type and it has an upper bound, use it, substituting
+     for a PLACEHOLDER_EXPR as needed.  */
+  if (domain_type && TYPE_MAX_VALUE (domain_type))
+    return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MAX_VALUE (domain_type), exp);
+
+  /* Otherwise fail.  */
+  return NULL_TREE;
+}
+
 /* Returns true if REF is an array reference to an array at the end of
    a structure.  If this is the case, the array may be allocated larger
    than its upper bound implies.  */
@@ -7039,23 +7056,6 @@ array_at_struct_end_p (tree ref)
   return true;
 }
 
-/* Return a tree representing the upper bound of the array mentioned in
-   EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
-
-tree
-array_ref_up_bound (tree exp)
-{
-  tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0)));
-
-  /* If there is a domain type and it has an upper bound, use it, substituting
-     for a PLACEHOLDER_EXPR as needed.  */
-  if (domain_type && TYPE_MAX_VALUE (domain_type))
-    return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MAX_VALUE (domain_type), exp);
-
-  /* Otherwise fail.  */
-  return NULL_TREE;
-}
-
 /* Return a tree representing the offset, in bytes, of the field referenced
    by EXP.  This does not include any offset in DECL_FIELD_BIT_OFFSET.  */
 
Index: tree.h
===================================================================
--- tree.h	(revision 223736)
+++ tree.h	(working copy)
@@ -5051,12 +5051,6 @@ tree_int_cst_compare (const_tree t1, con
 extern void set_decl_rtl (tree, rtx);
 extern bool complete_ctor_at_level_p (const_tree, HOST_WIDE_INT, const_tree);
 
-/* Return a tree representing the upper bound of the array mentioned in
-   EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
-extern tree array_ref_up_bound (tree);
-
-extern tree build_personality_function (const char *);
-
 /* Given an expression EXP that is a handled_component_p,
    look for the ultimate containing object, which is returned and specify
    the access position and size.  */
@@ -5064,10 +5058,28 @@ extern tree get_inner_reference (tree, H
 				 tree *, machine_mode *, int *, int *,
 				 bool);
 
+/* Return a tree of sizetype representing the size, in bytes, of the element
+   of EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
+extern tree array_ref_element_size (tree);
+
+/* Return a tree representing the upper bound of the array mentioned in
+   EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
+extern tree array_ref_up_bound (tree);
+
 /* Return a tree representing the lower bound of the array mentioned in
    EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
 extern tree array_ref_low_bound (tree);
 
+/* Returns true if REF is an array reference to an array at the end of
+   a structure.  If this is the case, the array may be allocated larger
+   than its upper bound implies.  */
+extern bool array_at_struct_end_p (tree);
+
+/* Return a tree representing the offset, in bytes, of the field referenced
+   by EXP.  This does not include any offset in DECL_FIELD_BIT_OFFSET.  */
+extern tree component_ref_field_offset (tree);
+
+extern tree build_personality_function (const char *);
 
 struct GTY(()) int_n_trees_t {
   /* These parts are initialized at runtime */

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

* Re: [patch] Move generic tree functions from expr.h to tree.h
  2015-05-27 10:25 [patch] Move generic tree functions from expr.h to tree.h Eric Botcazou
@ 2015-05-27 11:01 ` Richard Biener
  2015-05-27 12:28   ` Eric Botcazou
  0 siblings, 1 reply; 5+ messages in thread
From: Richard Biener @ 2015-05-27 11:01 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: GCC Patches

On Wed, May 27, 2015 at 12:00 PM, Eric Botcazou <ebotcazou@adacore.com> wrote:
> Hi,
>
> a few functions manipulating generic trees from expr.c are useful for FEs too
> and some of them (array_ref_{low,up}_bound, get_inner_reference) are already
> declared in tree.h instead of expr.h.  This patch moves 3 similar functions
> (array_ref_element_size, array_at_struct_end_p, component_ref_field_offset).
>
> Tested on x86_64-suse-linux, OK for the mainline?

No.  Prototypes of functions defined in A.c should be in A.h, not in some other
header.  We've been (slowly) moving to that.  You should have moved them all
to expr.h instead, or move the implementations to tree.c.

Richard.

>
> 2015-05-27  Eric Botcazou  <ebotcazou@adacore.com>
>
>         * expr.h (array_at_struct_end_p): Move to...
>         (array_ref_element_size): Likewise.
>         (component_ref_field_offset): Likewise.
>         * tree.h (array_ref_element_size): ...here.
>         (array_at_struct_end_p): Likewise.
>         (component_ref_field_offset): Likewise.
>         * expr.c (array_ref_up_bound): Move around.
>
>
> --
> Eric Botcazou

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

* Re: [patch] Move generic tree functions from expr.h to tree.h
  2015-05-27 11:01 ` Richard Biener
@ 2015-05-27 12:28   ` Eric Botcazou
  2015-05-27 12:47     ` Richard Biener
  0 siblings, 1 reply; 5+ messages in thread
From: Eric Botcazou @ 2015-05-27 12:28 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

> No.  Prototypes of functions defined in A.c should be in A.h, not in some
> other header.  We've been (slowly) moving to that.  You should have moved
> them all to expr.h instead, or move the implementations to tree.c.

The former is simply not possible since expr.h is poisoned for FEs...  I can 
move the implementations to tree.c but get_inner_reference is one of them.

-- 
Eric Botcazou

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

* Re: [patch] Move generic tree functions from expr.h to tree.h
  2015-05-27 12:28   ` Eric Botcazou
@ 2015-05-27 12:47     ` Richard Biener
  2015-05-27 18:09       ` Eric Botcazou
  0 siblings, 1 reply; 5+ messages in thread
From: Richard Biener @ 2015-05-27 12:47 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: GCC Patches

On Wed, May 27, 2015 at 12:50 PM, Eric Botcazou <ebotcazou@adacore.com> wrote:
>> No.  Prototypes of functions defined in A.c should be in A.h, not in some
>> other header.  We've been (slowly) moving to that.  You should have moved
>> them all to expr.h instead, or move the implementations to tree.c.
>
> The former is simply not possible since expr.h is poisoned for FEs...  I can
> move the implementations to tree.c but get_inner_reference is one of them.

You can leave get_inner_reference in its place then ... or move it.  It's hardly
only used by expansion now.

Richard.

> --
> Eric Botcazou

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

* Re: [patch] Move generic tree functions from expr.h to tree.h
  2015-05-27 12:47     ` Richard Biener
@ 2015-05-27 18:09       ` Eric Botcazou
  0 siblings, 0 replies; 5+ messages in thread
From: Eric Botcazou @ 2015-05-27 18:09 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

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

> You can leave get_inner_reference in its place then ... or move it.  It's
> hardly only used by expansion now.

Yes, but it's a hot function and I'd rather preserve its SVN history so I'm 
leaving it in its original place.  Thanks for the review.

Here's the patch I have installed after having tested it on x86_64-suse-linux.


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

	* expr.h (array_at_struct_end_p): Move to...
	(array_ref_element_size): Likewise.
	(component_ref_field_offset): Likewise.
	* tree.h (array_ref_element_size): ...here.
	(array_at_struct_end_p): Likewise.
	(component_ref_field_offset): Likewise.
	* expr.c (array_ref_element_size): Move to...
	(array_ref_low_bound): Likewise.
	(array_at_struct_end_p): Likewise.
	(array_ref_up_bound): Likewise.
	(component_ref_field_offset): Likewise.
	* tree.c (array_ref_element_size): ...here.
	(array_ref_low_bound): Likewise.
	(array_ref_up_bound): Likewise.
	(array_at_struct_end_p): Likewise.
	(component_ref_field_offset): Likewise.


-- 
Eric Botcazou

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

Index: expr.h
===================================================================
--- expr.h	(revision 223736)
+++ expr.h	(working copy)
@@ -281,19 +281,10 @@ rtx get_personality_function (tree);
 extern int can_move_by_pieces (unsigned HOST_WIDE_INT, unsigned int);
 
 extern unsigned HOST_WIDE_INT highest_pow2_factor (const_tree);
-bool array_at_struct_end_p (tree);
-
-/* Return a tree of sizetype representing the size, in bytes, of the element
-   of EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
-extern tree array_ref_element_size (tree);
 
 extern bool categorize_ctor_elements (const_tree, HOST_WIDE_INT *,
 				      HOST_WIDE_INT *, bool *);
 
-/* Return a tree representing the offset, in bytes, of the field referenced
-   by EXP.  This does not include any offset in DECL_FIELD_BIT_OFFSET.  */
-extern tree component_ref_field_offset (tree);
-
 extern void expand_operands (tree, tree, rtx, rtx*, rtx*,
 			     enum expand_modifier);
 
Index: expr.c
===================================================================
--- expr.c	(revision 223736)
+++ expr.c	(working copy)
@@ -6953,139 +6953,6 @@ get_inner_reference (tree exp, HOST_WIDE
   return exp;
 }
 
-/* Return a tree of sizetype representing the size, in bytes, of the element
-   of EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
-
-tree
-array_ref_element_size (tree exp)
-{
-  tree aligned_size = TREE_OPERAND (exp, 3);
-  tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)));
-  location_t loc = EXPR_LOCATION (exp);
-
-  /* If a size was specified in the ARRAY_REF, it's the size measured
-     in alignment units of the element type.  So multiply by that value.  */
-  if (aligned_size)
-    {
-      /* ??? tree_ssa_useless_type_conversion will eliminate casts to
-	 sizetype from another type of the same width and signedness.  */
-      if (TREE_TYPE (aligned_size) != sizetype)
-	aligned_size = fold_convert_loc (loc, sizetype, aligned_size);
-      return size_binop_loc (loc, MULT_EXPR, aligned_size,
-			     size_int (TYPE_ALIGN_UNIT (elmt_type)));
-    }
-
-  /* Otherwise, take the size from that of the element type.  Substitute
-     any PLACEHOLDER_EXPR that we have.  */
-  else
-    return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (elmt_type), exp);
-}
-
-/* Return a tree representing the lower bound of the array mentioned in
-   EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
-
-tree
-array_ref_low_bound (tree exp)
-{
-  tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0)));
-
-  /* If a lower bound is specified in EXP, use it.  */
-  if (TREE_OPERAND (exp, 2))
-    return TREE_OPERAND (exp, 2);
-
-  /* Otherwise, if there is a domain type and it has a lower bound, use it,
-     substituting for a PLACEHOLDER_EXPR as needed.  */
-  if (domain_type && TYPE_MIN_VALUE (domain_type))
-    return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MIN_VALUE (domain_type), exp);
-
-  /* Otherwise, return a zero of the appropriate type.  */
-  return build_int_cst (TREE_TYPE (TREE_OPERAND (exp, 1)), 0);
-}
-
-/* Returns true if REF is an array reference to an array at the end of
-   a structure.  If this is the case, the array may be allocated larger
-   than its upper bound implies.  */
-
-bool
-array_at_struct_end_p (tree ref)
-{
-  if (TREE_CODE (ref) != ARRAY_REF
-      && TREE_CODE (ref) != ARRAY_RANGE_REF)
-    return false;
-
-  while (handled_component_p (ref))
-    {
-      /* If the reference chain contains a component reference to a
-         non-union type and there follows another field the reference
-	 is not at the end of a structure.  */
-      if (TREE_CODE (ref) == COMPONENT_REF
-	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == RECORD_TYPE)
-	{
-	  tree nextf = DECL_CHAIN (TREE_OPERAND (ref, 1));
-	  while (nextf && TREE_CODE (nextf) != FIELD_DECL)
-	    nextf = DECL_CHAIN (nextf);
-	  if (nextf)
-	    return false;
-	}
-
-      ref = TREE_OPERAND (ref, 0);
-    }
-
-  /* If the reference is based on a declared entity, the size of the array
-     is constrained by its given domain.  */
-  if (DECL_P (ref))
-    return false;
-
-  return true;
-}
-
-/* Return a tree representing the upper bound of the array mentioned in
-   EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
-
-tree
-array_ref_up_bound (tree exp)
-{
-  tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0)));
-
-  /* If there is a domain type and it has an upper bound, use it, substituting
-     for a PLACEHOLDER_EXPR as needed.  */
-  if (domain_type && TYPE_MAX_VALUE (domain_type))
-    return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MAX_VALUE (domain_type), exp);
-
-  /* Otherwise fail.  */
-  return NULL_TREE;
-}
-
-/* Return a tree representing the offset, in bytes, of the field referenced
-   by EXP.  This does not include any offset in DECL_FIELD_BIT_OFFSET.  */
-
-tree
-component_ref_field_offset (tree exp)
-{
-  tree aligned_offset = TREE_OPERAND (exp, 2);
-  tree field = TREE_OPERAND (exp, 1);
-  location_t loc = EXPR_LOCATION (exp);
-
-  /* If an offset was specified in the COMPONENT_REF, it's the offset measured
-     in units of DECL_OFFSET_ALIGN / BITS_PER_UNIT.  So multiply by that
-     value.  */
-  if (aligned_offset)
-    {
-      /* ??? tree_ssa_useless_type_conversion will eliminate casts to
-	 sizetype from another type of the same width and signedness.  */
-      if (TREE_TYPE (aligned_offset) != sizetype)
-	aligned_offset = fold_convert_loc (loc, sizetype, aligned_offset);
-      return size_binop_loc (loc, MULT_EXPR, aligned_offset,
-			     size_int (DECL_OFFSET_ALIGN (field)
-				       / BITS_PER_UNIT));
-    }
-
-  /* Otherwise, take the offset from that of the field.  Substitute
-     any PLACEHOLDER_EXPR that we have.  */
-  else
-    return SUBSTITUTE_PLACEHOLDER_IN_EXPR (DECL_FIELD_OFFSET (field), exp);
-}
-
 /* Alignment in bits the TARGET of an assignment may be assumed to have.  */
 
 static unsigned HOST_WIDE_INT
Index: tree.h
===================================================================
--- tree.h	(revision 223736)
+++ tree.h	(working copy)
@@ -4563,8 +4563,34 @@ extern tree walk_tree_without_duplicates
 #define walk_tree_without_duplicates(a,b,c) \
 	walk_tree_without_duplicates_1 (a, b, c, NULL)
 
-extern tree get_base_address (tree t);
 extern tree drop_tree_overflow (tree);
+
+/* Given a memory reference expression T, return its base address.
+   The base address of a memory reference expression is the main
+   object being referenced.  */
+extern tree get_base_address (tree t);
+
+/* Return a tree of sizetype representing the size, in bytes, of the element
+   of EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
+extern tree array_ref_element_size (tree);
+
+/* Return a tree representing the upper bound of the array mentioned in
+   EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
+extern tree array_ref_up_bound (tree);
+
+/* Return a tree representing the lower bound of the array mentioned in
+   EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
+extern tree array_ref_low_bound (tree);
+
+/* Returns true if REF is an array reference to an array at the end of
+   a structure.  If this is the case, the array may be allocated larger
+   than its upper bound implies.  */
+extern bool array_at_struct_end_p (tree);
+
+/* Return a tree representing the offset, in bytes, of the field referenced
+   by EXP.  This does not include any offset in DECL_FIELD_BIT_OFFSET.  */
+extern tree component_ref_field_offset (tree);
+
 extern int tree_map_base_eq (const void *, const void *);
 extern unsigned int tree_map_base_hash (const void *);
 extern int tree_map_base_marked_p (const void *);
@@ -5051,12 +5077,6 @@ tree_int_cst_compare (const_tree t1, con
 extern void set_decl_rtl (tree, rtx);
 extern bool complete_ctor_at_level_p (const_tree, HOST_WIDE_INT, const_tree);
 
-/* Return a tree representing the upper bound of the array mentioned in
-   EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
-extern tree array_ref_up_bound (tree);
-
-extern tree build_personality_function (const char *);
-
 /* Given an expression EXP that is a handled_component_p,
    look for the ultimate containing object, which is returned and specify
    the access position and size.  */
@@ -5064,10 +5084,7 @@ extern tree get_inner_reference (tree, H
 				 tree *, machine_mode *, int *, int *,
 				 bool);
 
-/* Return a tree representing the lower bound of the array mentioned in
-   EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
-extern tree array_ref_low_bound (tree);
-
+extern tree build_personality_function (const char *);
 
 struct GTY(()) int_n_trees_t {
   /* These parts are initialized at runtime */
Index: tree.c
===================================================================
--- tree.c	(revision 223736)
+++ tree.c	(working copy)
@@ -24,8 +24,8 @@ along with GCC; see the file COPYING3.
    tables index by tree code that describe how to take apart
    nodes of that code.
 
-   It is intended to be language-independent, but occasionally
-   calls language-dependent routines defined (for C) in typecheck.c.  */
+   It is intended to be language-independent but can occasionally
+   calls language-dependent routines.  */
 
 #include "config.h"
 #include "system.h"
@@ -12453,6 +12453,139 @@ get_base_address (tree t)
   return t;
 }
 
+/* Return a tree of sizetype representing the size, in bytes, of the element
+   of EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
+
+tree
+array_ref_element_size (tree exp)
+{
+  tree aligned_size = TREE_OPERAND (exp, 3);
+  tree elmt_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)));
+  location_t loc = EXPR_LOCATION (exp);
+
+  /* If a size was specified in the ARRAY_REF, it's the size measured
+     in alignment units of the element type.  So multiply by that value.  */
+  if (aligned_size)
+    {
+      /* ??? tree_ssa_useless_type_conversion will eliminate casts to
+	 sizetype from another type of the same width and signedness.  */
+      if (TREE_TYPE (aligned_size) != sizetype)
+	aligned_size = fold_convert_loc (loc, sizetype, aligned_size);
+      return size_binop_loc (loc, MULT_EXPR, aligned_size,
+			     size_int (TYPE_ALIGN_UNIT (elmt_type)));
+    }
+
+  /* Otherwise, take the size from that of the element type.  Substitute
+     any PLACEHOLDER_EXPR that we have.  */
+  else
+    return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (elmt_type), exp);
+}
+
+/* Return a tree representing the lower bound of the array mentioned in
+   EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
+
+tree
+array_ref_low_bound (tree exp)
+{
+  tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0)));
+
+  /* If a lower bound is specified in EXP, use it.  */
+  if (TREE_OPERAND (exp, 2))
+    return TREE_OPERAND (exp, 2);
+
+  /* Otherwise, if there is a domain type and it has a lower bound, use it,
+     substituting for a PLACEHOLDER_EXPR as needed.  */
+  if (domain_type && TYPE_MIN_VALUE (domain_type))
+    return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MIN_VALUE (domain_type), exp);
+
+  /* Otherwise, return a zero of the appropriate type.  */
+  return build_int_cst (TREE_TYPE (TREE_OPERAND (exp, 1)), 0);
+}
+
+/* Return a tree representing the upper bound of the array mentioned in
+   EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
+
+tree
+array_ref_up_bound (tree exp)
+{
+  tree domain_type = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0)));
+
+  /* If there is a domain type and it has an upper bound, use it, substituting
+     for a PLACEHOLDER_EXPR as needed.  */
+  if (domain_type && TYPE_MAX_VALUE (domain_type))
+    return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MAX_VALUE (domain_type), exp);
+
+  /* Otherwise fail.  */
+  return NULL_TREE;
+}
+
+/* Returns true if REF is an array reference to an array at the end of
+   a structure.  If this is the case, the array may be allocated larger
+   than its upper bound implies.  */
+
+bool
+array_at_struct_end_p (tree ref)
+{
+  if (TREE_CODE (ref) != ARRAY_REF
+      && TREE_CODE (ref) != ARRAY_RANGE_REF)
+    return false;
+
+  while (handled_component_p (ref))
+    {
+      /* If the reference chain contains a component reference to a
+         non-union type and there follows another field the reference
+	 is not at the end of a structure.  */
+      if (TREE_CODE (ref) == COMPONENT_REF
+	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == RECORD_TYPE)
+	{
+	  tree nextf = DECL_CHAIN (TREE_OPERAND (ref, 1));
+	  while (nextf && TREE_CODE (nextf) != FIELD_DECL)
+	    nextf = DECL_CHAIN (nextf);
+	  if (nextf)
+	    return false;
+	}
+
+      ref = TREE_OPERAND (ref, 0);
+    }
+
+  /* If the reference is based on a declared entity, the size of the array
+     is constrained by its given domain.  */
+  if (DECL_P (ref))
+    return false;
+
+  return true;
+}
+
+/* Return a tree representing the offset, in bytes, of the field referenced
+   by EXP.  This does not include any offset in DECL_FIELD_BIT_OFFSET.  */
+
+tree
+component_ref_field_offset (tree exp)
+{
+  tree aligned_offset = TREE_OPERAND (exp, 2);
+  tree field = TREE_OPERAND (exp, 1);
+  location_t loc = EXPR_LOCATION (exp);
+
+  /* If an offset was specified in the COMPONENT_REF, it's the offset measured
+     in units of DECL_OFFSET_ALIGN / BITS_PER_UNIT.  So multiply by that
+     value.  */
+  if (aligned_offset)
+    {
+      /* ??? tree_ssa_useless_type_conversion will eliminate casts to
+	 sizetype from another type of the same width and signedness.  */
+      if (TREE_TYPE (aligned_offset) != sizetype)
+	aligned_offset = fold_convert_loc (loc, sizetype, aligned_offset);
+      return size_binop_loc (loc, MULT_EXPR, aligned_offset,
+			     size_int (DECL_OFFSET_ALIGN (field)
+				       / BITS_PER_UNIT));
+    }
+
+  /* Otherwise, take the offset from that of the field.  Substitute
+     any PLACEHOLDER_EXPR that we have.  */
+  else
+    return SUBSTITUTE_PLACEHOLDER_IN_EXPR (DECL_FIELD_OFFSET (field), exp);
+}
+
 /* Return the machine mode of T.  For vectors, returns the mode of the
    inner type.  The main use case is to feed the result to HONOR_NANS,
    avoiding the BLKmode that a direct TYPE_MODE (T) might return.  */

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

end of thread, other threads:[~2015-05-27 18:01 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-27 10:25 [patch] Move generic tree functions from expr.h to tree.h Eric Botcazou
2015-05-27 11:01 ` Richard Biener
2015-05-27 12:28   ` Eric Botcazou
2015-05-27 12:47     ` Richard Biener
2015-05-27 18:09       ` Eric Botcazou

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