public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
@ 2013-06-03  2:14 Kugan
  2013-06-17  1:31 ` [ping][PATCH][1 " Kugan
  0 siblings, 1 reply; 38+ messages in thread
From: Kugan @ 2013-06-03  2:14 UTC (permalink / raw)
  To: gcc-patches, patches
  Cc: Richard Biener, rdsandiford, ramana.radhakrishnan, Richard Earnshaw

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

Hi,

This patch adds value range information to tree SSA_NAME during Value 
Range Propagation (VRP) pass  in preparation to removes some of the 
redundant sign/zero extensions during RTL expansion.

This is based on the original patch posted in 
http://gcc.gnu.org/ml/gcc-patches/2013-05/msg00610.html and addresses 
the review comments of  Richard Biener.

Tested  on X86_64 and ARM.

I would like review comments on this.

Thanks,
Kugan


+2013-06-03  Kugan Vivekanandarajah  <kuganv@linaro.org>
+
+	* gcc/gcc/tree-flow.h: Declared structure range_info_def and function
+	definition for mark_range_info_unknown.
+	* gcc/tree-ssa-alias.c (dump_alias_info) : Check pointer type
+	* gcc/tree-ssanames.c (make_ssa_name_fn) : Check pointer type in
+	initialize.
+	* (mark_range_info_unknown) : New function.
+	* (duplicate_ssa_name_range_info) : Likewise.
+	* (duplicate_ssa_name_fn) : Check pointer type and call correct
+	duplicate function.
+	* gcc/tree-vrp.c (extract_exp_value_range): New function.
+	* (simplify_stmt_using_ranges): Call extract_exp_value_range and
+	tree_ssa_set_value_range.
+	* gcc/tree.c (tree_ssa_set_value_range): New function.
+	* gcc/tree.h (SSA_NAME_PTR_INFO) : changed to access via union
+	* gcc/tree.h (SSA_NAME_RANGE_INFO) : New macro
+




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

diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 24fcfbf..dd4e2f5 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -147,6 +147,19 @@ struct GTY(()) ptr_info_def
   unsigned int misalign;
 };
 
+/* Value range information for SSA_NAMEs representing non-pointer variables.  */
+
+struct GTY (()) range_info_def {
+  /* Set to true if VR_RANGE and false if VR_ANTI_RANGE.  */
+  bool vr_range;
+  /* Minmum for value range.  */
+  double_int min;
+  /* Maximum for value range.  */
+  double_int max;
+  /* Set to true if range is valid.  */
+  bool valid;
+};
+
 
 /* It is advantageous to avoid things like life analysis for variables which
    do not need PHI nodes.  This enum describes whether or not a particular
@@ -532,6 +545,7 @@ extern void replace_ssa_name_symbol (tree, tree);
 extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *,
 				    unsigned int *);
 extern void mark_ptr_info_alignment_unknown (struct ptr_info_def *);
+extern void mark_range_info_unknown (struct range_info_def *);
 extern void set_ptr_info_alignment (struct ptr_info_def *, unsigned int,
 				    unsigned int);
 extern void adjust_ptr_info_misalignment (struct ptr_info_def *,
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 2ecd139..8ccecb5 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -404,6 +404,7 @@ dump_alias_info (FILE *file)
       struct ptr_info_def *pi;
 
       if (ptr == NULL_TREE
+          || !POINTER_TYPE_P (TREE_TYPE (ptr))
 	  || SSA_NAME_IN_FREE_LIST (ptr))
 	continue;
 
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index 0a405ce..420ae00 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -151,7 +151,11 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt)
       SET_SSA_NAME_VAR_OR_IDENTIFIER (t, var);
     }
   SSA_NAME_DEF_STMT (t) = stmt;
-  SSA_NAME_PTR_INFO (t) = NULL;
+  if (POINTER_TYPE_P (TREE_TYPE (t)))
+    SSA_NAME_PTR_INFO (t) = NULL;
+  else
+    SSA_NAME_RANGE_INFO (t) = NULL;
+
   SSA_NAME_IN_FREE_LIST (t) = 0;
   SSA_NAME_IS_DEFAULT_DEF (t) = 0;
   imm = &(SSA_NAME_IMM_USE_NODE (t));
@@ -266,6 +270,14 @@ mark_ptr_info_alignment_unknown (struct ptr_info_def *pi)
   pi->misalign = 0;
 }
 
+/* Set the range described by RI has invalid values.  */
+
+void
+mark_range_info_unknown (struct range_info_def *ri)
+{
+  ri->valid = false;
+}
+
 /* Store the the power-of-two byte alignment and the deviation from that
    alignment of pointer described by PI to ALIOGN and MISALIGN
    respectively.  */
@@ -359,6 +371,26 @@ duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info)
   SSA_NAME_PTR_INFO (name) = new_ptr_info;
 }
 
+/* Creates a duplicate of the range_info_def at RANGE_INFO for use by
+   the SSA name NAME.  */
+void
+duplicate_ssa_name_range_info (tree name, struct range_info_def *range_info)
+{
+  struct range_info_def *new_range_info;
+
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  gcc_assert (!SSA_NAME_RANGE_INFO (name));
+
+  if (!range_info)
+    return;
+
+  new_range_info = ggc_alloc_range_info_def ();
+  *new_range_info = *range_info;
+
+  SSA_NAME_RANGE_INFO (name) = new_range_info;
+}
+
+
 
 /* Creates a duplicate of a ssa name NAME tobe defined by statement STMT
    in function FN.  */
@@ -367,10 +399,20 @@ tree
 duplicate_ssa_name_fn (struct function *fn, tree name, gimple stmt)
 {
   tree new_name = copy_ssa_name_fn (fn, name, stmt);
-  struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
+  if (POINTER_TYPE_P (TREE_TYPE (name)))
+    {
+      struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
+
+      if (old_ptr_info)
+        duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+    }
+  else
+    {
+      struct range_info_def *old_range_info = SSA_NAME_RANGE_INFO (name);
 
-  if (old_ptr_info)
-    duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+      if (old_range_info)
+        duplicate_ssa_name_range_info (new_name, old_range_info);
+    }
 
   return new_name;
 }
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index ec7ef8f..36ec5fa 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -8950,6 +8950,62 @@ simplify_float_conversion_using_ranges (gimple_stmt_iterator *gsi, gimple stmt)
   return true;
 }
 
+/* Extract the value range of assigned exprassion for GIMPLE_ASSIGN stmt.
+   If the extracted value range is valid, return true else return
+   false.  */
+static bool
+extract_exp_value_range (gimple stmt, value_range_t *vr)
+{
+  gcc_assert (is_gimple_assign (stmt));
+  tree rhs1 = gimple_assign_rhs1 (stmt);
+  tree lhs = gimple_assign_lhs (stmt);
+  enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
+
+  /* Skip if the lhs is not integeral.  */
+  if (!INTEGRAL_TYPE_P (TREE_TYPE (lhs))
+      || CONSTANT_CLASS_P (lhs))
+    return false;
+
+  if (TREE_CODE_CLASS (rhs_code) == tcc_unary)
+    {
+      /* Get the value range for the expression.  */
+      if ((rhs_code == NOP_EXPR || rhs_code == CONVERT_EXPR)
+          && (TREE_CODE (rhs1) == SSA_NAME))
+        {
+          value_range_t *temp =  get_value_range (rhs1);
+          *vr = *temp;
+        }
+      else
+        extract_range_from_unary_expr (vr,
+                                     gimple_assign_rhs_code (stmt),
+                                     TREE_TYPE (rhs1), rhs1);
+    }
+    /* Process binary assign stmt.  */
+  else if (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
+           == tcc_binary)
+    {
+      tree rhs2 = gimple_assign_rhs2 (stmt);
+      gcc_assert (rhs1);
+      gcc_assert (rhs2);
+
+      /* Get the value range for the expression.  */
+      extract_range_from_binary_expr (vr,
+                                    gimple_assign_rhs_code (stmt),
+                                    TREE_TYPE (rhs1), rhs1, rhs2);
+    }
+
+    /* Is the laue range valid.  */
+    if ((vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
+        && !is_overflow_infinity (vr->min)
+        && !is_overflow_infinity (vr->max)
+        && (TREE_CODE (vr->min) == INTEGER_CST)
+        && (TREE_CODE (vr->max) == INTEGER_CST))
+      return true;
+    else
+      return false;
+}
+
+
 /* Simplify STMT using ranges if possible.  */
 
 static bool
@@ -8960,6 +9016,23 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
     {
       enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
       tree rhs1 = gimple_assign_rhs1 (stmt);
+      tree lhs = gimple_assign_lhs (stmt);
+
+      /* Set value range information for ssa.  */
+      if (!POINTER_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
+          && (TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
+          && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
+          && !SSA_NAME_RANGE_INFO (lhs))
+        {
+          value_range_t vr = VR_INITIALIZER;
+
+          /* If value range is valid, set that.  */
+          if (extract_exp_value_range (stmt, &vr))
+            tree_ssa_set_value_range (lhs,
+                                      tree_to_double_int (vr.min),
+                                      tree_to_double_int (vr.max),
+                                      vr.type == VR_RANGE);
+        }
 
       switch (rhs_code)
 	{
diff --git a/gcc/tree.c b/gcc/tree.c
index 6c71025..bf8c816 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -270,6 +270,31 @@ const char * const omp_clause_code_name[] =
 };
 
 
+/* Set zero/sign extension redundant for ssa def stmt.  */
+
+void
+tree_ssa_set_value_range (tree ssa, double_int min,
+                          double_int max, bool vr_range)
+{
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (ssa)));
+  gcc_assert (TREE_CODE (ssa) == SSA_NAME);
+  range_info_def *ri = SSA_NAME_RANGE_INFO (ssa);
+
+  /* Allocate if not available.  */
+  if (ri == NULL)
+    {
+      ri = ggc_alloc_cleared_range_info_def ();
+      mark_range_info_unknown (ri);
+      SSA_NAME_RANGE_INFO (ssa) = ri;
+    }
+
+  /* Set the values.  */
+  ri->valid = true;
+  ri->min = min;
+  ri->max = max;
+  ri->vr_range = vr_range;
+}
+
 /* Return the tree node structure used by tree code CODE.  */
 
 static inline enum tree_node_structure_enum
diff --git a/gcc/tree.h b/gcc/tree.h
index 1d2b252..7629de8 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1950,10 +1950,19 @@ struct GTY(()) tree_exp {
 
 /* Attributes for SSA_NAMEs for pointer-type variables.  */
 #define SSA_NAME_PTR_INFO(N) \
-    SSA_NAME_CHECK (N)->ssa_name.ptr_info
+   SSA_NAME_CHECK (N)->ssa_name.vrp.ptr_info
+
+/* Value range info Attributes for SSA_NAMEs of non pointer-type variables.  */
+#define SSA_NAME_RANGE_INFO(N) \
+    SSA_NAME_CHECK (N)->ssa_name.vrp.range_info
+
+/* Sets the value range extreacted from VRP into ssa.  */
+void tree_ssa_set_value_range (tree ssa, double_int min,
+                               double_int max, bool vr_range);
 
 /* Defined in tree-flow.h.  */
 struct ptr_info_def;
+struct range_info_def;
 
 /* Immediate use linking structure.  This structure is used for maintaining
    a doubly linked list of uses of an SSA_NAME.  */
@@ -1969,6 +1978,12 @@ typedef struct GTY(()) ssa_use_operand_d {
   tree *GTY((skip(""))) use;
 } ssa_use_operand_t;
 
+
+/* The garbage collector needs to know the interpretation of the
+   value range info in the tree_ssa_name.  */
+#define TREE_SSA_PTR_INFO   (0)
+#define TREE_SSA_RANGE_INFO (1)
+
 /* Return the immediate_use information for an SSA_NAME. */
 #define SSA_NAME_IMM_USE_NODE(NODE) SSA_NAME_CHECK (NODE)->ssa_name.imm_uses
 
@@ -1981,8 +1996,13 @@ struct GTY(()) tree_ssa_name {
   /* Statement that defines this SSA name.  */
   gimple def_stmt;
 
-  /* Pointer attributes used for alias analysis.  */
-  struct ptr_info_def *ptr_info;
+  /* Value range information.  */
+  union vrp_info_type {
+    /* Pointer attributes used for alias analysis.  */
+    struct GTY ((tag ("TREE_SSA_PTR_INFO"))) ptr_info_def *ptr_info;
+    /* Value range attributes used for zero/sign extension elimination.  */
+    struct GTY ((tag ("TREE_SSA_RANGE_INFO"))) range_info_def *range_info;
+  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE ((tree)&%1))"))) vrp;
 
   /* Immediate uses list for this SSA_NAME.  */
   struct ssa_use_operand_d imm_uses;




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

* [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-06-03  2:14 [PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL Kugan
@ 2013-06-17  1:31 ` Kugan
  2013-06-17  9:03   ` Richard Biener
  0 siblings, 1 reply; 38+ messages in thread
From: Kugan @ 2013-06-17  1:31 UTC (permalink / raw)
  To: gcc-patches
  Cc: Richard Biener, ebotcazou, ramana.radhakrishnan, Richard Earnshaw

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

Can you please help to review this patch? Richard reviewed the original 
patch and asked it to be split into two parts. Also, he wanted a review 
from RTL maintainer for the RTL changes.

Thanks,
Kugan

On 03/06/13 11:43, Kugan wrote:
> Hi,
>
> This patch adds value range information to tree SSA_NAME during Value
> Range Propagation (VRP) pass  in preparation to removes some of the
> redundant sign/zero extensions during RTL expansion.
>
> This is based on the original patch posted in
> http://gcc.gnu.org/ml/gcc-patches/2013-05/msg00610.html and addresses
> the review comments of  Richard Biener.
>
> Tested  on X86_64 and ARM.
>
> I would like review comments on this.
>
> Thanks,
> Kugan
>
>
> +2013-06-03  Kugan Vivekanandarajah  <kuganv@linaro.org>
> +
> +    * gcc/gcc/tree-flow.h: Declared structure range_info_def and function
> +    definition for mark_range_info_unknown.
> +    * gcc/tree-ssa-alias.c (dump_alias_info) : Check pointer type
> +    * gcc/tree-ssanames.c (make_ssa_name_fn) : Check pointer type in
> +    initialize.
> +    * (mark_range_info_unknown) : New function.
> +    * (duplicate_ssa_name_range_info) : Likewise.
> +    * (duplicate_ssa_name_fn) : Check pointer type and call correct
> +    duplicate function.
> +    * gcc/tree-vrp.c (extract_exp_value_range): New function.
> +    * (simplify_stmt_using_ranges): Call extract_exp_value_range and
> +    tree_ssa_set_value_range.
> +    * gcc/tree.c (tree_ssa_set_value_range): New function.
> +    * gcc/tree.h (SSA_NAME_PTR_INFO) : changed to access via union
> +    * gcc/tree.h (SSA_NAME_RANGE_INFO) : New macro
> +
>
>
>


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

diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 24fcfbf..dd4e2f5 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -147,6 +147,19 @@ struct GTY(()) ptr_info_def
   unsigned int misalign;
 };
 
+/* Value range information for SSA_NAMEs representing non-pointer variables.  */
+
+struct GTY (()) range_info_def {
+  /* Set to true if VR_RANGE and false if VR_ANTI_RANGE.  */
+  bool vr_range;
+  /* Minmum for value range.  */
+  double_int min;
+  /* Maximum for value range.  */
+  double_int max;
+  /* Set to true if range is valid.  */
+  bool valid;
+};
+
 
 /* It is advantageous to avoid things like life analysis for variables which
    do not need PHI nodes.  This enum describes whether or not a particular
@@ -532,6 +545,7 @@ extern void replace_ssa_name_symbol (tree, tree);
 extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *,
 				    unsigned int *);
 extern void mark_ptr_info_alignment_unknown (struct ptr_info_def *);
+extern void mark_range_info_unknown (struct range_info_def *);
 extern void set_ptr_info_alignment (struct ptr_info_def *, unsigned int,
 				    unsigned int);
 extern void adjust_ptr_info_misalignment (struct ptr_info_def *,
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 2ecd139..8ccecb5 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -404,6 +404,7 @@ dump_alias_info (FILE *file)
       struct ptr_info_def *pi;
 
       if (ptr == NULL_TREE
+          || !POINTER_TYPE_P (TREE_TYPE (ptr))
 	  || SSA_NAME_IN_FREE_LIST (ptr))
 	continue;
 
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index 0a405ce..420ae00 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -151,7 +151,11 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt)
       SET_SSA_NAME_VAR_OR_IDENTIFIER (t, var);
     }
   SSA_NAME_DEF_STMT (t) = stmt;
-  SSA_NAME_PTR_INFO (t) = NULL;
+  if (POINTER_TYPE_P (TREE_TYPE (t)))
+    SSA_NAME_PTR_INFO (t) = NULL;
+  else
+    SSA_NAME_RANGE_INFO (t) = NULL;
+
   SSA_NAME_IN_FREE_LIST (t) = 0;
   SSA_NAME_IS_DEFAULT_DEF (t) = 0;
   imm = &(SSA_NAME_IMM_USE_NODE (t));
@@ -266,6 +270,14 @@ mark_ptr_info_alignment_unknown (struct ptr_info_def *pi)
   pi->misalign = 0;
 }
 
+/* Set the range described by RI has invalid values.  */
+
+void
+mark_range_info_unknown (struct range_info_def *ri)
+{
+  ri->valid = false;
+}
+
 /* Store the the power-of-two byte alignment and the deviation from that
    alignment of pointer described by PI to ALIOGN and MISALIGN
    respectively.  */
@@ -359,6 +371,26 @@ duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info)
   SSA_NAME_PTR_INFO (name) = new_ptr_info;
 }
 
+/* Creates a duplicate of the range_info_def at RANGE_INFO for use by
+   the SSA name NAME.  */
+void
+duplicate_ssa_name_range_info (tree name, struct range_info_def *range_info)
+{
+  struct range_info_def *new_range_info;
+
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  gcc_assert (!SSA_NAME_RANGE_INFO (name));
+
+  if (!range_info)
+    return;
+
+  new_range_info = ggc_alloc_range_info_def ();
+  *new_range_info = *range_info;
+
+  SSA_NAME_RANGE_INFO (name) = new_range_info;
+}
+
+
 
 /* Creates a duplicate of a ssa name NAME tobe defined by statement STMT
    in function FN.  */
@@ -367,10 +399,20 @@ tree
 duplicate_ssa_name_fn (struct function *fn, tree name, gimple stmt)
 {
   tree new_name = copy_ssa_name_fn (fn, name, stmt);
-  struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
+  if (POINTER_TYPE_P (TREE_TYPE (name)))
+    {
+      struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
+
+      if (old_ptr_info)
+        duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+    }
+  else
+    {
+      struct range_info_def *old_range_info = SSA_NAME_RANGE_INFO (name);
 
-  if (old_ptr_info)
-    duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+      if (old_range_info)
+        duplicate_ssa_name_range_info (new_name, old_range_info);
+    }
 
   return new_name;
 }
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index ec7ef8f..36ec5fa 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -8950,6 +8950,62 @@ simplify_float_conversion_using_ranges (gimple_stmt_iterator *gsi, gimple stmt)
   return true;
 }
 
+/* Extract the value range of assigned exprassion for GIMPLE_ASSIGN stmt.
+   If the extracted value range is valid, return true else return
+   false.  */
+static bool
+extract_exp_value_range (gimple stmt, value_range_t *vr)
+{
+  gcc_assert (is_gimple_assign (stmt));
+  tree rhs1 = gimple_assign_rhs1 (stmt);
+  tree lhs = gimple_assign_lhs (stmt);
+  enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
+
+  /* Skip if the lhs is not integeral.  */
+  if (!INTEGRAL_TYPE_P (TREE_TYPE (lhs))
+      || CONSTANT_CLASS_P (lhs))
+    return false;
+
+  if (TREE_CODE_CLASS (rhs_code) == tcc_unary)
+    {
+      /* Get the value range for the expression.  */
+      if ((rhs_code == NOP_EXPR || rhs_code == CONVERT_EXPR)
+          && (TREE_CODE (rhs1) == SSA_NAME))
+        {
+          value_range_t *temp =  get_value_range (rhs1);
+          *vr = *temp;
+        }
+      else
+        extract_range_from_unary_expr (vr,
+                                     gimple_assign_rhs_code (stmt),
+                                     TREE_TYPE (rhs1), rhs1);
+    }
+    /* Process binary assign stmt.  */
+  else if (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
+           == tcc_binary)
+    {
+      tree rhs2 = gimple_assign_rhs2 (stmt);
+      gcc_assert (rhs1);
+      gcc_assert (rhs2);
+
+      /* Get the value range for the expression.  */
+      extract_range_from_binary_expr (vr,
+                                    gimple_assign_rhs_code (stmt),
+                                    TREE_TYPE (rhs1), rhs1, rhs2);
+    }
+
+    /* Is the laue range valid.  */
+    if ((vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
+        && !is_overflow_infinity (vr->min)
+        && !is_overflow_infinity (vr->max)
+        && (TREE_CODE (vr->min) == INTEGER_CST)
+        && (TREE_CODE (vr->max) == INTEGER_CST))
+      return true;
+    else
+      return false;
+}
+
+
 /* Simplify STMT using ranges if possible.  */
 
 static bool
@@ -8960,6 +9016,23 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
     {
       enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
       tree rhs1 = gimple_assign_rhs1 (stmt);
+      tree lhs = gimple_assign_lhs (stmt);
+
+      /* Set value range information for ssa.  */
+      if (!POINTER_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
+          && (TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
+          && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
+          && !SSA_NAME_RANGE_INFO (lhs))
+        {
+          value_range_t vr = VR_INITIALIZER;
+
+          /* If value range is valid, set that.  */
+          if (extract_exp_value_range (stmt, &vr))
+            tree_ssa_set_value_range (lhs,
+                                      tree_to_double_int (vr.min),
+                                      tree_to_double_int (vr.max),
+                                      vr.type == VR_RANGE);
+        }
 
       switch (rhs_code)
 	{
diff --git a/gcc/tree.c b/gcc/tree.c
index 6c71025..bf8c816 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -270,6 +270,31 @@ const char * const omp_clause_code_name[] =
 };
 
 
+/* Set zero/sign extension redundant for ssa def stmt.  */
+
+void
+tree_ssa_set_value_range (tree ssa, double_int min,
+                          double_int max, bool vr_range)
+{
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (ssa)));
+  gcc_assert (TREE_CODE (ssa) == SSA_NAME);
+  range_info_def *ri = SSA_NAME_RANGE_INFO (ssa);
+
+  /* Allocate if not available.  */
+  if (ri == NULL)
+    {
+      ri = ggc_alloc_cleared_range_info_def ();
+      mark_range_info_unknown (ri);
+      SSA_NAME_RANGE_INFO (ssa) = ri;
+    }
+
+  /* Set the values.  */
+  ri->valid = true;
+  ri->min = min;
+  ri->max = max;
+  ri->vr_range = vr_range;
+}
+
 /* Return the tree node structure used by tree code CODE.  */
 
 static inline enum tree_node_structure_enum
diff --git a/gcc/tree.h b/gcc/tree.h
index 1d2b252..7629de8 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1950,10 +1950,19 @@ struct GTY(()) tree_exp {
 
 /* Attributes for SSA_NAMEs for pointer-type variables.  */
 #define SSA_NAME_PTR_INFO(N) \
-    SSA_NAME_CHECK (N)->ssa_name.ptr_info
+   SSA_NAME_CHECK (N)->ssa_name.vrp.ptr_info
+
+/* Value range info Attributes for SSA_NAMEs of non pointer-type variables.  */
+#define SSA_NAME_RANGE_INFO(N) \
+    SSA_NAME_CHECK (N)->ssa_name.vrp.range_info
+
+/* Sets the value range extreacted from VRP into ssa.  */
+void tree_ssa_set_value_range (tree ssa, double_int min,
+                               double_int max, bool vr_range);
 
 /* Defined in tree-flow.h.  */
 struct ptr_info_def;
+struct range_info_def;
 
 /* Immediate use linking structure.  This structure is used for maintaining
    a doubly linked list of uses of an SSA_NAME.  */
@@ -1969,6 +1978,12 @@ typedef struct GTY(()) ssa_use_operand_d {
   tree *GTY((skip(""))) use;
 } ssa_use_operand_t;
 
+
+/* The garbage collector needs to know the interpretation of the
+   value range info in the tree_ssa_name.  */
+#define TREE_SSA_PTR_INFO   (0)
+#define TREE_SSA_RANGE_INFO (1)
+
 /* Return the immediate_use information for an SSA_NAME. */
 #define SSA_NAME_IMM_USE_NODE(NODE) SSA_NAME_CHECK (NODE)->ssa_name.imm_uses
 
@@ -1981,8 +1996,13 @@ struct GTY(()) tree_ssa_name {
   /* Statement that defines this SSA name.  */
   gimple def_stmt;
 
-  /* Pointer attributes used for alias analysis.  */
-  struct ptr_info_def *ptr_info;
+  /* Value range information.  */
+  union vrp_info_type {
+    /* Pointer attributes used for alias analysis.  */
+    struct GTY ((tag ("TREE_SSA_PTR_INFO"))) ptr_info_def *ptr_info;
+    /* Value range attributes used for zero/sign extension elimination.  */
+    struct GTY ((tag ("TREE_SSA_RANGE_INFO"))) range_info_def *range_info;
+  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE ((tree)&%1))"))) vrp;
 
   /* Immediate uses list for this SSA_NAME.  */
   struct ssa_use_operand_d imm_uses;

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-06-17  1:31 ` [ping][PATCH][1 " Kugan
@ 2013-06-17  9:03   ` Richard Biener
  2013-07-03 12:26     ` Kugan
  0 siblings, 1 reply; 38+ messages in thread
From: Richard Biener @ 2013-06-17  9:03 UTC (permalink / raw)
  To: Kugan; +Cc: gcc-patches, ebotcazou, ramana.radhakrishnan, Richard Earnshaw

On Mon, 17 Jun 2013, Kugan wrote:

> Can you please help to review this patch? Richard reviewed the original patch
> and asked it to be split into two parts. Also, he wanted a review from RTL
> maintainer for the RTL changes.
> 
> Thanks,
> Kugan
> 
> On 03/06/13 11:43, Kugan wrote:
> > Hi,
> > 
> > This patch adds value range information to tree SSA_NAME during Value
> > Range Propagation (VRP) pass  in preparation to removes some of the
> > redundant sign/zero extensions during RTL expansion.
> > 
> > This is based on the original patch posted in
> > http://gcc.gnu.org/ml/gcc-patches/2013-05/msg00610.html and addresses
> > the review comments of  Richard Biener.
> > 
> > Tested  on X86_64 and ARM.
> > 
> > I would like review comments on this.
> > 
> > Thanks,
> > Kugan
> > 
> > 
> > +2013-06-03  Kugan Vivekanandarajah  <kuganv@linaro.org>
> > +
> > +    * gcc/gcc/tree-flow.h: Declared structure range_info_def and function
> > +    definition for mark_range_info_unknown.
> > +    * gcc/tree-ssa-alias.c (dump_alias_info) : Check pointer type
> > +    * gcc/tree-ssanames.c (make_ssa_name_fn) : Check pointer type in
> > +    initialize.
> > +    * (mark_range_info_unknown) : New function.
> > +    * (duplicate_ssa_name_range_info) : Likewise.
> > +    * (duplicate_ssa_name_fn) : Check pointer type and call correct
> > +    duplicate function.
> > +    * gcc/tree-vrp.c (extract_exp_value_range): New function.
> > +    * (simplify_stmt_using_ranges): Call extract_exp_value_range and
> > +    tree_ssa_set_value_range.
> > +    * gcc/tree.c (tree_ssa_set_value_range): New function.
> > +    * gcc/tree.h (SSA_NAME_PTR_INFO) : changed to access via union
> > +    * gcc/tree.h (SSA_NAME_RANGE_INFO) : New macro

These go to gcc/ChangeLog and thus do not need the gcc/ prefix.

+/* Value range information for SSA_NAMEs representing non-pointer 
variables.  */
+
+struct GTY (()) range_info_def {
+  /* Set to true if VR_RANGE and false if VR_ANTI_RANGE.  */
+  bool vr_range;
+  /* Minmum for value range.  */
+  double_int min;
+  /* Maximum for value range.  */
+  double_int max;
+  /* Set to true if range is valid.  */
+  bool valid;
+};

this way you waste a lot of padding, so please move the two bool
members next to each other.

+/* Extract the value range of assigned exprassion for GIMPLE_ASSIGN stmt.
+   If the extracted value range is valid, return true else return
+   false.  */
+static bool
+extract_exp_value_range (gimple stmt, value_range_t *vr)
+{
+  gcc_assert (is_gimple_assign (stmt));
+  tree rhs1 = gimple_assign_rhs1 (stmt);
+  tree lhs = gimple_assign_lhs (stmt);
+  enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
...
@@ -8960,6 +9016,23 @@ simplify_stmt_using_ranges (gimple_stmt_iterator 
*gsi)
     {
       enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
       tree rhs1 = gimple_assign_rhs1 (stmt);
+      tree lhs = gimple_assign_lhs (stmt);
+
+      /* Set value range information for ssa.  */
+      if (!POINTER_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
+          && (TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
+          && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
+          && !SSA_NAME_RANGE_INFO (lhs))
+        {
+          value_range_t vr = VR_INITIALIZER;
...
+          if (extract_exp_value_range (stmt, &vr))
+            tree_ssa_set_value_range (lhs,
+                                      tree_to_double_int (vr.min),
+                                      tree_to_double_int (vr.max),
+                                      vr.type == VR_RANGE);
+        }

This looks overly complicated to me.  In vrp_finalize you can simply do

  for (i = 0; i < num_vr_values; i++)
    if (vr_value[i])
      {
        tree name = ssa_name (i);
        if (POINTER_TYPE_P (name))
          continue;
        if (vr_value[i].type == VR_RANGE
            || vr_value[i].type == VR_ANTI_RANGE)
          tree_ssa_set_value_range (name, tree_to_double_int 
(vr_value[i].min), tree_to_double_int (vr_value[i].max), vr_value[i].type 
== VR_RANGE);
      }

that is, transfer directly from the lattice.

+/* Set zero/sign extension redundant for ssa def stmt.  */
+
+void
+tree_ssa_set_value_range (tree ssa, double_int min,
+                          double_int max, bool vr_range)
+{

The comment needs updating.  Also this doesn't belong in tree.c
but in tree-ssanames.c with a more suitable name like
set_range_info ().

+/* The garbage collector needs to know the interpretation of the
+   value range info in the tree_ssa_name.  */
+#define TREE_SSA_PTR_INFO   (0)
+#define TREE_SSA_RANGE_INFO (1)

no need for those, just use GTY ((tag ("0")) and "1".

+  /* Value range information.  */

/* SSA name annotations.  */

+  union vrp_info_type {
+    /* Pointer attributes used for alias analysis.  */
+    struct GTY ((tag ("TREE_SSA_PTR_INFO"))) ptr_info_def *ptr_info;
+    /* Value range attributes used for zero/sign extension elimination.  
*/

/* Value range information.  */

+    struct GTY ((tag ("TREE_SSA_RANGE_INFO"))) range_info_def 
*range_info;
+  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE 
((tree)&%1))"))) vrp;

why do you need to test %1.def_stmt here?

Please add a way to dump the associated range information (I'm fine
doing it at the time and with the same flags we dump SSA_NAME_PTR_INFO,
see gimple-pretty-print.c.

Sorry for taking so long to review this again.

Thanks,
Richard.

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-06-17  9:03   ` Richard Biener
@ 2013-07-03 12:26     ` Kugan
  2013-08-14  7:19       ` Kugan
  2013-09-02 12:45       ` Richard Biener
  0 siblings, 2 replies; 38+ messages in thread
From: Kugan @ 2013-07-03 12:26 UTC (permalink / raw)
  To: Richard Biener
  Cc: gcc-patches, ebotcazou, ramana.radhakrishnan, Richard Earnshaw

On 17/06/13 18:33, Richard Biener wrote:
> On Mon, 17 Jun 2013, Kugan wrote:
> +/* Extract the value range of assigned exprassion for GIMPLE_ASSIGN stmt.
> +   If the extracted value range is valid, return true else return
> +   false.  */
> +static bool
> +extract_exp_value_range (gimple stmt, value_range_t *vr)
> +{
> +  gcc_assert (is_gimple_assign (stmt));
> +  tree rhs1 = gimple_assign_rhs1 (stmt);
> +  tree lhs = gimple_assign_lhs (stmt);
> +  enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
> ...
> @@ -8960,6 +9016,23 @@ simplify_stmt_using_ranges (gimple_stmt_iterator
> *gsi)
>       {
>         enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
>         tree rhs1 = gimple_assign_rhs1 (stmt);
> +      tree lhs = gimple_assign_lhs (stmt);
> +
> +      /* Set value range information for ssa.  */
> +      if (!POINTER_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
> +          && (TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
> +          && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
> +          && !SSA_NAME_RANGE_INFO (lhs))
> +        {
> +          value_range_t vr = VR_INITIALIZER;
> ...
> +          if (extract_exp_value_range (stmt, &vr))
> +            tree_ssa_set_value_range (lhs,
> +                                      tree_to_double_int (vr.min),
> +                                      tree_to_double_int (vr.max),
> +                                      vr.type == VR_RANGE);
> +        }
>
> This looks overly complicated to me.  In vrp_finalize you can simply do
>
>    for (i = 0; i < num_vr_values; i++)
>      if (vr_value[i])
>        {
>          tree name = ssa_name (i);
>          if (POINTER_TYPE_P (name))
>            continue;
>          if (vr_value[i].type == VR_RANGE
>              || vr_value[i].type == VR_ANTI_RANGE)
>            tree_ssa_set_value_range (name, tree_to_double_int
> (vr_value[i].min), tree_to_double_int (vr_value[i].max), vr_value[i].type
> == VR_RANGE);
>        }
>

Thanks Richard for taking time to review it.

I was doing something like what you are suggesting earlier but noticed 
some problems and thatÂ’s the reason why I changed.

For example, for the following testcase from the test suite,

unsigned long l = (unsigned long)-2;
unsigned short s;

int main () {
   long t = l + 1;
   s = l;
   if (s != (unsigned short) -2)
     abort ();
   exit (0);
}

with the following gimple stmts

main ()
{
   short unsigned int s.1;
   long unsigned int l.0;

;;   basic block 2, loop depth 0
;;    pred:       ENTRY
   l.0_2 = l;
   s.1_3 = (short unsigned int) l.0_2;
   s = s.1_3;
   if (s.1_3 != 65534)
     goto <bb 3>;
   else
     goto <bb 4>;
;;    succ:       3
;;                4

;;   basic block 3, loop depth 0
;;    pred:       2
   abort ();
;;    succ:

;;   basic block 4, loop depth 0
;;    pred:       2
   exit (0);
;;    succ:

}



has the following value range.

l.0_2: VARYING
s.1_3: [0, +INF]


 From zero/sign extension point of view, the variable s.1_3 is expected 
to have a value that will overflow (or varying) as this is what is 
assigned to a smaller variable. extract_range_from_assignment initially 
calculates the value range as VARYING but later changed to [0, +INF] by 
extract_range_basic. What I need here is the value that will be assigned 
from the rhs expression and not the value that we will have with proper 
assignment.

I understand that the above code of mine needs to be changed but not 
convinced about the best way to do that.

I can possibly re-factor extract_range_from_assignment to give me this 
information with an additional argument. Could you kindly let me know 
your preference.


>
> /* SSA name annotations.  */
>
> +  union vrp_info_type {
> +    /* Pointer attributes used for alias analysis.  */
> +    struct GTY ((tag ("TREE_SSA_PTR_INFO"))) ptr_info_def *ptr_info;
> +    /* Value range attributes used for zero/sign extension elimination.
> */
>
> /* Value range information.  */
>
> +    struct GTY ((tag ("TREE_SSA_RANGE_INFO"))) range_info_def
> *range_info;
> +  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE
> ((tree)&%1))"))) vrp;
>
> why do you need to test %1.def_stmt here?


I have seen some tree_ssa_name with def_stmt NULL. Thats why I added 
this. Is that something that should never happen.


Thanks,
Kugan

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-07-03 12:26     ` Kugan
@ 2013-08-14  7:19       ` Kugan
  2013-09-02  9:31         ` Kugan
  2013-09-02 12:45       ` Richard Biener
  1 sibling, 1 reply; 38+ messages in thread
From: Kugan @ 2013-08-14  7:19 UTC (permalink / raw)
  To: Richard Biener
  Cc: gcc-patches, ebotcazou, ramana.radhakrishnan, Richard Earnshaw

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

Hi Richard,

Here is an attempt to address your earlier review comments. Bootstrapped 
and there is no new regression for X86_64 and arm. Thank you very much 
for your time.

Thanks,
Kugan

--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,25 @@
+2013-08-14  Kugan Vivekanandarajah  <kuganv@linaro.org>
+
+	* tree-flow.h (mark_range_info_unknown): New function definition.
+	* tree-ssa-alias.c (dump_alias_info) : Check pointer type.
+	* tree-ssa-copy.c (fini_copy_prop) : Check pointer type and copy
+	range info.
+	* tree-ssanames.c (make_ssa_name_fn) : Check pointer type in
+	initialize.
+	* (mark_range_info_unknown) : New function.
+	* (duplicate_ssa_name_range_info) : Likewise.
+	* (duplicate_ssa_name_fn) : Check pointer type and call correct
+	duplicate function.
+	* tree-vrp.c (extract_exp_value_range): New function.
+	* (simplify_stmt_using_ranges): Call extract_exp_value_range and
+	tree_ssa_set_value_range.
+	* tree-ssaname.c (ssa_range_info): New function.
+	* tree.h (SSA_NAME_PTR_INFO) : changed to access via union
+	* tree.h (SSA_NAME_RANGE_INFO) : New macro
+	* gimple-pretty-print.c (print_double_int) : New function.
+	* gimple-pretty-print.c (dump_gimple_phi) : Dump range info.
+	* (pp_gimple_stmt_1) : Likewise.
+
   2013-08-09  Jan Hubicka  <jh@suse.cz>

   	* cgraph.c (cgraph_create_edge_1): Clear speculative flag.

On 03/07/13 21:55, Kugan wrote:
> On 17/06/13 18:33, Richard Biener wrote:
>> On Mon, 17 Jun 2013, Kugan wrote:
>> +/* Extract the value range of assigned exprassion for GIMPLE_ASSIGN
>> stmt.
>> +   If the extracted value range is valid, return true else return
>> +   false.  */
>> +static bool
>> +extract_exp_value_range (gimple stmt, value_range_t *vr)
>> +{
>> +  gcc_assert (is_gimple_assign (stmt));
>> +  tree rhs1 = gimple_assign_rhs1 (stmt);
>> +  tree lhs = gimple_assign_lhs (stmt);
>> +  enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
>> ...
>> @@ -8960,6 +9016,23 @@ simplify_stmt_using_ranges (gimple_stmt_iterator
>> *gsi)
>>       {
>>         enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
>>         tree rhs1 = gimple_assign_rhs1 (stmt);
>> +      tree lhs = gimple_assign_lhs (stmt);
>> +
>> +      /* Set value range information for ssa.  */
>> +      if (!POINTER_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
>> +          && (TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
>> +          && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
>> +          && !SSA_NAME_RANGE_INFO (lhs))
>> +        {
>> +          value_range_t vr = VR_INITIALIZER;
>> ...
>> +          if (extract_exp_value_range (stmt, &vr))
>> +            tree_ssa_set_value_range (lhs,
>> +                                      tree_to_double_int (vr.min),
>> +                                      tree_to_double_int (vr.max),
>> +                                      vr.type == VR_RANGE);
>> +        }
>>
>> This looks overly complicated to me.  In vrp_finalize you can simply do
>>
>>    for (i = 0; i < num_vr_values; i++)
>>      if (vr_value[i])
>>        {
>>          tree name = ssa_name (i);
>>          if (POINTER_TYPE_P (name))
>>            continue;
>>          if (vr_value[i].type == VR_RANGE
>>              || vr_value[i].type == VR_ANTI_RANGE)
>>            tree_ssa_set_value_range (name, tree_to_double_int
>> (vr_value[i].min), tree_to_double_int (vr_value[i].max), vr_value[i].type
>> == VR_RANGE);
>>        }
>>
>
> Thanks Richard for taking time to review it.
>
> I was doing something like what you are suggesting earlier but noticed
> some problems and thatÂ’s the reason why I changed.
>
> For example, for the following testcase from the test suite,
>
> unsigned long l = (unsigned long)-2;
> unsigned short s;
>
> int main () {
>    long t = l + 1;
>    s = l;
>    if (s != (unsigned short) -2)
>      abort ();
>    exit (0);
> }
>
> with the following gimple stmts
>
> main ()
> {
>    short unsigned int s.1;
>    long unsigned int l.0;
>
> ;;   basic block 2, loop depth 0
> ;;    pred:       ENTRY
>    l.0_2 = l;
>    s.1_3 = (short unsigned int) l.0_2;
>    s = s.1_3;
>    if (s.1_3 != 65534)
>      goto <bb 3>;
>    else
>      goto <bb 4>;
> ;;    succ:       3
> ;;                4
>
> ;;   basic block 3, loop depth 0
> ;;    pred:       2
>    abort ();
> ;;    succ:
>
> ;;   basic block 4, loop depth 0
> ;;    pred:       2
>    exit (0);
> ;;    succ:
>
> }
>
>
>
> has the following value range.
>
> l.0_2: VARYING
> s.1_3: [0, +INF]
>
>
>  From zero/sign extension point of view, the variable s.1_3 is expected
> to have a value that will overflow (or varying) as this is what is
> assigned to a smaller variable. extract_range_from_assignment initially
> calculates the value range as VARYING but later changed to [0, +INF] by
> extract_range_basic. What I need here is the value that will be assigned
> from the rhs expression and not the value that we will have with proper
> assignment.
>
> I understand that the above code of mine needs to be changed but not
> convinced about the best way to do that.
>
> I can possibly re-factor extract_range_from_assignment to give me this
> information with an additional argument. Could you kindly let me know
> your preference.
>

>>
>> /* SSA name annotations.  */
>>
>> +  union vrp_info_type {
>> +    /* Pointer attributes used for alias analysis.  */
>> +    struct GTY ((tag ("TREE_SSA_PTR_INFO"))) ptr_info_def *ptr_info;
>> +    /* Value range attributes used for zero/sign extension elimination.
>> */
>>
>> /* Value range information.  */
>>
>> +    struct GTY ((tag ("TREE_SSA_RANGE_INFO"))) range_info_def
>> *range_info;
>> +  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE
>> ((tree)&%1))"))) vrp;
>>
>> why do you need to test %1.def_stmt here?
>
>
> I have seen some tree_ssa_name with def_stmt NULL. Thats why I added
> this. Is that something that should never happen.
>
>
> Thanks,
> Kugan



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

diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 1d40680..70e3f0d 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -1581,6 +1581,24 @@ dump_gimple_asm (pretty_printer *buffer, gimple gs, int spc, int flags)
     }
 }
 
+/* Dumps double_int CST to BUFFER.  */
+
+static void
+print_double_int (pretty_printer *buffer, double_int cst)
+{
+  tree node = double_int_to_tree (integer_type_node, cst);
+  if (TREE_INT_CST_HIGH (node) == 0)
+    pp_printf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED, TREE_INT_CST_LOW (node));
+  else if (TREE_INT_CST_HIGH (node) == -1
+           && TREE_INT_CST_LOW (node) != 0)
+    pp_printf (buffer, "-" HOST_WIDE_INT_PRINT_UNSIGNED,
+               -TREE_INT_CST_LOW (node));
+  else
+    pp_printf (buffer, "0x%" HOST_LONG_FORMAT "x%" HOST_LONG_FORMAT "x",
+             (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (node),
+             (unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (node));
+}
+
 
 /* Dump a PHI node PHI.  BUFFER, SPC and FLAGS are as in pp_gimple_stmt_1.
    The caller is responsible for calling pp_flush on BUFFER to finalize
@@ -1609,6 +1627,19 @@ dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags)
       pp_string (buffer, "# ");
     }
 
+  if (!POINTER_TYPE_P (TREE_TYPE (lhs))
+      && SSA_NAME_RANGE_INFO (lhs))
+    {
+      struct range_info_def *ri = SSA_NAME_RANGE_INFO (lhs);
+      pp_printf (buffer, "# RANGE ");
+      pp_printf (buffer, "%s[", ri->vr_range ? "" : "~");
+      print_double_int (buffer, ri->min);
+      pp_printf (buffer, ", ");
+      print_double_int (buffer, ri->max);
+      pp_printf (buffer, "] VALID = %u ", ri->valid);
+      newline_and_indent (buffer, spc);
+    }
+
   if (flags & TDF_RAW)
       dump_gimple_fmt (buffer, spc, flags, "%G <%T, ", phi,
                        gimple_phi_result (phi));
@@ -1911,6 +1942,24 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags)
 	}
     }
 
+  if (gimple_has_lhs (gs))
+    {
+      tree lhs = gimple_get_lhs (gs);
+      if ((TREE_CODE (lhs) == SSA_NAME)
+          && !POINTER_TYPE_P (TREE_TYPE (lhs))
+          && SSA_NAME_RANGE_INFO (lhs))
+        {
+          struct range_info_def *ri = SSA_NAME_RANGE_INFO (lhs);
+          pp_printf (buffer, "# RANGE ");
+          pp_printf (buffer, "%s[", ri->vr_range ? "" : "~");
+          print_double_int (buffer, ri->min);
+          pp_printf (buffer, ", ");
+          print_double_int (buffer, ri->max);
+          pp_printf (buffer, "] VALID = %u ", ri->valid);
+          newline_and_indent (buffer, spc);
+        }
+    }
+
   switch (gimple_code (gs))
     {
     case GIMPLE_ASM:
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index caa8d74..51546ce 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -147,6 +147,19 @@ struct GTY(()) ptr_info_def
   unsigned int misalign;
 };
 
+/* Value range information for SSA_NAMEs representing non-pointer variables.  */
+
+struct GTY (()) range_info_def {
+  /* Minmum for value range.  */
+  double_int min;
+  /* Maximum for value range.  */
+  double_int max;
+  /* Set to true if VR_RANGE and false if VR_ANTI_RANGE.  */
+  bool vr_range;
+  /* Set to true if range is valid.  */
+  bool valid;
+};
+
 
 /* It is advantageous to avoid things like life analysis for variables which
    do not need PHI nodes.  This enum describes whether or not a particular
@@ -526,12 +539,14 @@ extern tree make_ssa_name_fn (struct function *, tree, gimple);
 extern tree copy_ssa_name_fn (struct function *, tree, gimple);
 extern tree duplicate_ssa_name_fn (struct function *, tree, gimple);
 extern void duplicate_ssa_name_ptr_info (tree, struct ptr_info_def *);
+extern void duplicate_ssa_name_range_info (tree, struct range_info_def *);
 extern void release_ssa_name (tree);
 extern void release_defs (gimple);
 extern void replace_ssa_name_symbol (tree, tree);
 extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *,
 				    unsigned int *);
 extern void mark_ptr_info_alignment_unknown (struct ptr_info_def *);
+extern void mark_range_info_unknown (struct range_info_def *);
 extern void set_ptr_info_alignment (struct ptr_info_def *, unsigned int,
 				    unsigned int);
 extern void adjust_ptr_info_misalignment (struct ptr_info_def *,
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 2ecd139..8ccecb5 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -404,6 +404,7 @@ dump_alias_info (FILE *file)
       struct ptr_info_def *pi;
 
       if (ptr == NULL_TREE
+          || !POINTER_TYPE_P (TREE_TYPE (ptr))
 	  || SSA_NAME_IN_FREE_LIST (ptr))
 	continue;
 
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index 75ab54a..23f07e9 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -761,11 +761,19 @@ fini_copy_prop (void)
 	 of the representative to the first solution we find if
 	 it doesn't have one already.  */
       if (copy_of[i].value != var
-	  && TREE_CODE (copy_of[i].value) == SSA_NAME
-	  && POINTER_TYPE_P (TREE_TYPE (var))
-	  && SSA_NAME_PTR_INFO (var)
-	  && !SSA_NAME_PTR_INFO (copy_of[i].value))
-	duplicate_ssa_name_ptr_info (copy_of[i].value, SSA_NAME_PTR_INFO (var));
+          && TREE_CODE (copy_of[i].value) == SSA_NAME)
+        {
+          if (POINTER_TYPE_P (TREE_TYPE (var))
+              && SSA_NAME_PTR_INFO (var)
+              && !SSA_NAME_PTR_INFO (copy_of[i].value))
+            duplicate_ssa_name_ptr_info (copy_of[i].value,
+                                         SSA_NAME_PTR_INFO (var));
+          else if (!POINTER_TYPE_P (TREE_TYPE (var))
+                   && SSA_NAME_RANGE_INFO (var)
+                   && !SSA_NAME_RANGE_INFO (copy_of[i].value))
+            duplicate_ssa_name_range_info (copy_of[i].value,
+                                           SSA_NAME_RANGE_INFO (var));
+        }
     }
 
   /* Don't do DCE if SCEV is initialized.  It would destroy the scev cache.  */
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index a6af3da..8750f11 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -151,7 +151,11 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt)
       SET_SSA_NAME_VAR_OR_IDENTIFIER (t, var);
     }
   SSA_NAME_DEF_STMT (t) = stmt;
-  SSA_NAME_PTR_INFO (t) = NULL;
+  if (POINTER_TYPE_P (TREE_TYPE (t)))
+    SSA_NAME_PTR_INFO (t) = NULL;
+  else
+    SSA_NAME_RANGE_INFO (t) = NULL;
+
   SSA_NAME_IN_FREE_LIST (t) = 0;
   SSA_NAME_IS_DEFAULT_DEF (t) = 0;
   imm = &(SSA_NAME_IMM_USE_NODE (t));
@@ -163,6 +167,31 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt)
   return t;
 }
 
+/* Store range information MIN, MAX and VR_RANGE type
+   from value range propagation to tree ssa_name NAME.  */
+
+void
+set_range_info (tree name, double_int min,
+                          double_int max, bool vr_range)
+{
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  gcc_assert (TREE_CODE (name) == SSA_NAME);
+  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
+
+  /* Allocate if not available.  */
+  if (ri == NULL)
+    {
+      ri = ggc_alloc_cleared_range_info_def ();
+      mark_range_info_unknown (ri);
+      SSA_NAME_RANGE_INFO (name) = ri;
+    }
+
+  /* Set the values.  */
+  ri->valid = true;
+  ri->min = min;
+  ri->max = max;
+  ri->vr_range = vr_range;
+}
 
 /* We no longer need the SSA_NAME expression VAR, release it so that
    it may be reused.
@@ -266,6 +295,14 @@ mark_ptr_info_alignment_unknown (struct ptr_info_def *pi)
   pi->misalign = 0;
 }
 
+/* Set the range described by RI has invalid values.  */
+
+void
+mark_range_info_unknown (struct range_info_def *ri)
+{
+  ri->valid = false;
+}
+
 /* Store the the power-of-two byte alignment and the deviation from that
    alignment of pointer described by PI to ALIOGN and MISALIGN
    respectively.  */
@@ -359,6 +396,26 @@ duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info)
   SSA_NAME_PTR_INFO (name) = new_ptr_info;
 }
 
+/* Creates a duplicate of the range_info_def at RANGE_INFO for use by
+   the SSA name NAME.  */
+void
+duplicate_ssa_name_range_info (tree name, struct range_info_def *range_info)
+{
+  struct range_info_def *new_range_info;
+
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  gcc_assert (!SSA_NAME_RANGE_INFO (name));
+
+  if (!range_info)
+    return;
+
+  new_range_info = ggc_alloc_range_info_def ();
+  *new_range_info = *range_info;
+
+  SSA_NAME_RANGE_INFO (name) = new_range_info;
+}
+
+
 
 /* Creates a duplicate of a ssa name NAME tobe defined by statement STMT
    in function FN.  */
@@ -367,10 +424,20 @@ tree
 duplicate_ssa_name_fn (struct function *fn, tree name, gimple stmt)
 {
   tree new_name = copy_ssa_name_fn (fn, name, stmt);
-  struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
+  if (POINTER_TYPE_P (TREE_TYPE (name)))
+    {
+      struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
+
+      if (old_ptr_info)
+        duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+    }
+  else
+    {
+      struct range_info_def *old_range_info = SSA_NAME_RANGE_INFO (name);
 
-  if (old_ptr_info)
-    duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+      if (old_range_info)
+        duplicate_ssa_name_range_info (new_name, old_range_info);
+    }
 
   return new_name;
 }
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index ff82591..cb06793 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -3753,11 +3753,10 @@ extract_range_basic (value_range_t *vr, gimple stmt)
 }
 
 
-/* Try to compute a useful range out of assignment STMT and store it
-   in *VR.  */
-
+/* Compute a useful range out of assignment STMT and store it
+   in VR.  */
 static void
-extract_range_from_assignment (value_range_t *vr, gimple stmt)
+extract_range_from_assignment_1 (value_range_t *vr, gimple stmt)
 {
   enum tree_code code = gimple_assign_rhs_code (stmt);
 
@@ -3787,6 +3786,19 @@ extract_range_from_assignment (value_range_t *vr, gimple stmt)
   else
     set_value_range_to_varying (vr);
 
+}
+
+/* Try to compute a useful range out of assignment STMT and store it
+   in *VR.  */
+
+static void
+extract_range_from_assignment (value_range_t *vr, gimple stmt)
+{
+  extract_range_from_assignment_1 (vr, stmt);
+
+  /* If range is varying try to derive nonnegative or nonzero
+     range out of STMT relying primarily on generic routines
+     in fold in conjunction with range data.  */
   if (vr->type == VR_VARYING)
     extract_range_basic (vr, stmt);
 }
@@ -9124,6 +9136,34 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
     {
       enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
       tree rhs1 = gimple_assign_rhs1 (stmt);
+      tree lhs = gimple_assign_lhs (stmt);
+
+      /* Set value range information for ssa.  */
+      if (!POINTER_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
+          && (TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
+          && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
+          && !SSA_NAME_RANGE_INFO (lhs))
+        {
+          value_range_t vr = VR_INITIALIZER;
+
+          /* Extract the value range of assigned exprassion
+             not considering the lhs type.  */
+          if ((gimple_assign_rhs_code (stmt) == NOP_EXPR)
+               || (gimple_assign_rhs_code (stmt) == CONVERT_EXPR))
+            extract_range_from_unary_expr (&vr, gimple_assign_rhs_code (stmt),
+                                           TREE_TYPE (rhs1),
+                                           gimple_assign_rhs1 (stmt));
+          else
+            extract_range_from_assignment_1 (&vr, stmt);
+
+          /* If value range is valid, set that.  */
+          if ((vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)
+              && range_int_cst_p (&vr))
+            set_range_info (lhs,
+                            tree_to_double_int (vr.min),
+                            tree_to_double_int (vr.max),
+                            vr.type == VR_RANGE);
+        }
 
       switch (rhs_code)
 	{
diff --git a/gcc/tree.h b/gcc/tree.h
index 94f112f..9330845 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1950,10 +1950,19 @@ struct GTY(()) tree_exp {
 
 /* Attributes for SSA_NAMEs for pointer-type variables.  */
 #define SSA_NAME_PTR_INFO(N) \
-    SSA_NAME_CHECK (N)->ssa_name.ptr_info
+   SSA_NAME_CHECK (N)->ssa_name.vrp.ptr_info
+
+/* Value range info Attributes for SSA_NAMEs of non pointer-type variables.  */
+#define SSA_NAME_RANGE_INFO(N) \
+    SSA_NAME_CHECK (N)->ssa_name.vrp.range_info
+
+/* Sets the value range extreacted from VRP into SSA.  */
+void set_range_info (tree ssa, double_int min,
+                               double_int max, bool vr_range);
 
 /* Defined in tree-flow.h.  */
 struct ptr_info_def;
+struct range_info_def;
 
 /* Immediate use linking structure.  This structure is used for maintaining
    a doubly linked list of uses of an SSA_NAME.  */
@@ -1981,8 +1990,13 @@ struct GTY(()) tree_ssa_name {
   /* Statement that defines this SSA name.  */
   gimple def_stmt;
 
-  /* Pointer attributes used for alias analysis.  */
-  struct ptr_info_def *ptr_info;
+  /* Value range information.  */
+  union vrp_info_type {
+    /* Pointer attributes used for alias analysis.  */
+    struct GTY ((tag ("0"))) ptr_info_def *ptr_info;
+    /* Value range attributes used for zero/sign extension elimination.  */
+    struct GTY ((tag ("1"))) range_info_def *range_info;
+  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE ((tree)&%1))"))) vrp;
 
   /* Immediate uses list for this SSA_NAME.  */
   struct ssa_use_operand_d imm_uses;


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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-08-14  7:19       ` Kugan
@ 2013-09-02  9:31         ` Kugan
  0 siblings, 0 replies; 38+ messages in thread
From: Kugan @ 2013-09-02  9:31 UTC (permalink / raw)
  To: Richard Biener
  Cc: gcc-patches, ebotcazou, ramana.radhakrishnan, Richard Earnshaw

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

I'd like to ping this  patch 1 of 2 that removes redundant zero/sign 
extension using value range information.

Bootstrapped and no new regression for  x86_64-unknown-linux-gnu and 
arm-none-linux-gnueabi.

Thanks you for your time.
Kugan

n 14/08/13 16:49, Kugan wrote:
> Hi Richard,
>
> Here is an attempt to address your earlier review comments. Bootstrapped
> and there is no new regression for X86_64 and arm. Thank you very much
> for your time.
>
> Thanks,
> Kugan
>
> --- a/gcc/ChangeLog
> +++ b/gcc/ChangeLog
> @@ -1,3 +1,25 @@
> +2013-08-14  Kugan Vivekanandarajah  <kuganv@linaro.org>
> +
> +    * tree-flow.h (mark_range_info_unknown): New function definition.
> +    * tree-ssa-alias.c (dump_alias_info) : Check pointer type.
> +    * tree-ssa-copy.c (fini_copy_prop) : Check pointer type and copy
> +    range info.
> +    * tree-ssanames.c (make_ssa_name_fn) : Check pointer type in
> +    initialize.
> +    * (mark_range_info_unknown) : New function.
> +    * (duplicate_ssa_name_range_info) : Likewise.
> +    * (duplicate_ssa_name_fn) : Check pointer type and call correct
> +    duplicate function.
> +    * tree-vrp.c (extract_exp_value_range): New function.
> +    * (simplify_stmt_using_ranges): Call extract_exp_value_range and
> +    tree_ssa_set_value_range.
> +    * tree-ssaname.c (ssa_range_info): New function.
> +    * tree.h (SSA_NAME_PTR_INFO) : changed to access via union
> +    * tree.h (SSA_NAME_RANGE_INFO) : New macro
> +    * gimple-pretty-print.c (print_double_int) : New function.
> +    * gimple-pretty-print.c (dump_gimple_phi) : Dump range info.
> +    * (pp_gimple_stmt_1) : Likewise.
> +
>    2013-08-09  Jan Hubicka  <jh@suse.cz>
>
>        * cgraph.c (cgraph_create_edge_1): Clear speculative flag.
>
> On 03/07/13 21:55, Kugan wrote:
>> On 17/06/13 18:33, Richard Biener wrote:
>>> On Mon, 17 Jun 2013, Kugan wrote:
>>> +/* Extract the value range of assigned exprassion for GIMPLE_ASSIGN
>>> stmt.
>>> +   If the extracted value range is valid, return true else return
>>> +   false.  */
>>> +static bool
>>> +extract_exp_value_range (gimple stmt, value_range_t *vr)
>>> +{
>>> +  gcc_assert (is_gimple_assign (stmt));
>>> +  tree rhs1 = gimple_assign_rhs1 (stmt);
>>> +  tree lhs = gimple_assign_lhs (stmt);
>>> +  enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
>>> ...
>>> @@ -8960,6 +9016,23 @@ simplify_stmt_using_ranges (gimple_stmt_iterator
>>> *gsi)
>>>       {
>>>         enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
>>>         tree rhs1 = gimple_assign_rhs1 (stmt);
>>> +      tree lhs = gimple_assign_lhs (stmt);
>>> +
>>> +      /* Set value range information for ssa.  */
>>> +      if (!POINTER_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
>>> +          && (TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
>>> +          && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
>>> +          && !SSA_NAME_RANGE_INFO (lhs))
>>> +        {
>>> +          value_range_t vr = VR_INITIALIZER;
>>> ...
>>> +          if (extract_exp_value_range (stmt, &vr))
>>> +            tree_ssa_set_value_range (lhs,
>>> +                                      tree_to_double_int (vr.min),
>>> +                                      tree_to_double_int (vr.max),
>>> +                                      vr.type == VR_RANGE);
>>> +        }
>>>
>>> This looks overly complicated to me.  In vrp_finalize you can simply do
>>>
>>>    for (i = 0; i < num_vr_values; i++)
>>>      if (vr_value[i])
>>>        {
>>>          tree name = ssa_name (i);
>>>          if (POINTER_TYPE_P (name))
>>>            continue;
>>>          if (vr_value[i].type == VR_RANGE
>>>              || vr_value[i].type == VR_ANTI_RANGE)
>>>            tree_ssa_set_value_range (name, tree_to_double_int
>>> (vr_value[i].min), tree_to_double_int (vr_value[i].max),
>>> vr_value[i].type
>>> == VR_RANGE);
>>>        }
>>>
>>
>> Thanks Richard for taking time to review it.
>>
>> I was doing something like what you are suggesting earlier but noticed
>> some problems and thatÂ’s the reason why I changed.
>>
>> For example, for the following testcase from the test suite,
>>
>> unsigned long l = (unsigned long)-2;
>> unsigned short s;
>>
>> int main () {
>>    long t = l + 1;
>>    s = l;
>>    if (s != (unsigned short) -2)
>>      abort ();
>>    exit (0);
>> }
>>
>> with the following gimple stmts
>>
>> main ()
>> {
>>    short unsigned int s.1;
>>    long unsigned int l.0;
>>
>> ;;   basic block 2, loop depth 0
>> ;;    pred:       ENTRY
>>    l.0_2 = l;
>>    s.1_3 = (short unsigned int) l.0_2;
>>    s = s.1_3;
>>    if (s.1_3 != 65534)
>>      goto <bb 3>;
>>    else
>>      goto <bb 4>;
>> ;;    succ:       3
>> ;;                4
>>
>> ;;   basic block 3, loop depth 0
>> ;;    pred:       2
>>    abort ();
>> ;;    succ:
>>
>> ;;   basic block 4, loop depth 0
>> ;;    pred:       2
>>    exit (0);
>> ;;    succ:
>>
>> }
>>
>>
>>
>> has the following value range.
>>
>> l.0_2: VARYING
>> s.1_3: [0, +INF]
>>
>>
>>  From zero/sign extension point of view, the variable s.1_3 is expected
>> to have a value that will overflow (or varying) as this is what is
>> assigned to a smaller variable. extract_range_from_assignment initially
>> calculates the value range as VARYING but later changed to [0, +INF] by
>> extract_range_basic. What I need here is the value that will be assigned
>> from the rhs expression and not the value that we will have with proper
>> assignment.
>>
>> I understand that the above code of mine needs to be changed but not
>> convinced about the best way to do that.
>>
>> I can possibly re-factor extract_range_from_assignment to give me this
>> information with an additional argument. Could you kindly let me know
>> your preference.
>>
>
>>>
>>> /* SSA name annotations.  */
>>>
>>> +  union vrp_info_type {
>>> +    /* Pointer attributes used for alias analysis.  */
>>> +    struct GTY ((tag ("TREE_SSA_PTR_INFO"))) ptr_info_def *ptr_info;
>>> +    /* Value range attributes used for zero/sign extension elimination.
>>> */
>>>
>>> /* Value range information.  */
>>>
>>> +    struct GTY ((tag ("TREE_SSA_RANGE_INFO"))) range_info_def
>>> *range_info;
>>> +  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE
>>> ((tree)&%1))"))) vrp;
>>>
>>> why do you need to test %1.def_stmt here?
>>
>>
>> I have seen some tree_ssa_name with def_stmt NULL. Thats why I added
>> this. Is that something that should never happen.
>>
>>
>> Thanks,
>> Kugan
>
>


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

diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 1d40680..70e3f0d 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -1581,6 +1581,24 @@ dump_gimple_asm (pretty_printer *buffer, gimple gs, int spc, int flags)
     }
 }
 
+/* Dumps double_int CST to BUFFER.  */
+
+static void
+print_double_int (pretty_printer *buffer, double_int cst)
+{
+  tree node = double_int_to_tree (integer_type_node, cst);
+  if (TREE_INT_CST_HIGH (node) == 0)
+    pp_printf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED, TREE_INT_CST_LOW (node));
+  else if (TREE_INT_CST_HIGH (node) == -1
+           && TREE_INT_CST_LOW (node) != 0)
+    pp_printf (buffer, "-" HOST_WIDE_INT_PRINT_UNSIGNED,
+               -TREE_INT_CST_LOW (node));
+  else
+    pp_printf (buffer, "0x%" HOST_LONG_FORMAT "x%" HOST_LONG_FORMAT "x",
+             (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (node),
+             (unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (node));
+}
+
 
 /* Dump a PHI node PHI.  BUFFER, SPC and FLAGS are as in pp_gimple_stmt_1.
    The caller is responsible for calling pp_flush on BUFFER to finalize
@@ -1609,6 +1627,19 @@ dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags)
       pp_string (buffer, "# ");
     }
 
+  if (!POINTER_TYPE_P (TREE_TYPE (lhs))
+      && SSA_NAME_RANGE_INFO (lhs))
+    {
+      struct range_info_def *ri = SSA_NAME_RANGE_INFO (lhs);
+      pp_printf (buffer, "# RANGE ");
+      pp_printf (buffer, "%s[", ri->vr_range ? "" : "~");
+      print_double_int (buffer, ri->min);
+      pp_printf (buffer, ", ");
+      print_double_int (buffer, ri->max);
+      pp_printf (buffer, "] VALID = %u ", ri->valid);
+      newline_and_indent (buffer, spc);
+    }
+
   if (flags & TDF_RAW)
       dump_gimple_fmt (buffer, spc, flags, "%G <%T, ", phi,
                        gimple_phi_result (phi));
@@ -1911,6 +1942,24 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags)
 	}
     }
 
+  if (gimple_has_lhs (gs))
+    {
+      tree lhs = gimple_get_lhs (gs);
+      if ((TREE_CODE (lhs) == SSA_NAME)
+          && !POINTER_TYPE_P (TREE_TYPE (lhs))
+          && SSA_NAME_RANGE_INFO (lhs))
+        {
+          struct range_info_def *ri = SSA_NAME_RANGE_INFO (lhs);
+          pp_printf (buffer, "# RANGE ");
+          pp_printf (buffer, "%s[", ri->vr_range ? "" : "~");
+          print_double_int (buffer, ri->min);
+          pp_printf (buffer, ", ");
+          print_double_int (buffer, ri->max);
+          pp_printf (buffer, "] VALID = %u ", ri->valid);
+          newline_and_indent (buffer, spc);
+        }
+    }
+
   switch (gimple_code (gs))
     {
     case GIMPLE_ASM:
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index caa8d74..51546ce 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -147,6 +147,19 @@ struct GTY(()) ptr_info_def
   unsigned int misalign;
 };
 
+/* Value range information for SSA_NAMEs representing non-pointer variables.  */
+
+struct GTY (()) range_info_def {
+  /* Minmum for value range.  */
+  double_int min;
+  /* Maximum for value range.  */
+  double_int max;
+  /* Set to true if VR_RANGE and false if VR_ANTI_RANGE.  */
+  bool vr_range;
+  /* Set to true if range is valid.  */
+  bool valid;
+};
+
 
 /* It is advantageous to avoid things like life analysis for variables which
    do not need PHI nodes.  This enum describes whether or not a particular
@@ -526,12 +539,14 @@ extern tree make_ssa_name_fn (struct function *, tree, gimple);
 extern tree copy_ssa_name_fn (struct function *, tree, gimple);
 extern tree duplicate_ssa_name_fn (struct function *, tree, gimple);
 extern void duplicate_ssa_name_ptr_info (tree, struct ptr_info_def *);
+extern void duplicate_ssa_name_range_info (tree, struct range_info_def *);
 extern void release_ssa_name (tree);
 extern void release_defs (gimple);
 extern void replace_ssa_name_symbol (tree, tree);
 extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *,
 				    unsigned int *);
 extern void mark_ptr_info_alignment_unknown (struct ptr_info_def *);
+extern void mark_range_info_unknown (struct range_info_def *);
 extern void set_ptr_info_alignment (struct ptr_info_def *, unsigned int,
 				    unsigned int);
 extern void adjust_ptr_info_misalignment (struct ptr_info_def *,
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 2ecd139..8ccecb5 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -404,6 +404,7 @@ dump_alias_info (FILE *file)
       struct ptr_info_def *pi;
 
       if (ptr == NULL_TREE
+          || !POINTER_TYPE_P (TREE_TYPE (ptr))
 	  || SSA_NAME_IN_FREE_LIST (ptr))
 	continue;
 
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index 75ab54a..23f07e9 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -761,11 +761,19 @@ fini_copy_prop (void)
 	 of the representative to the first solution we find if
 	 it doesn't have one already.  */
       if (copy_of[i].value != var
-	  && TREE_CODE (copy_of[i].value) == SSA_NAME
-	  && POINTER_TYPE_P (TREE_TYPE (var))
-	  && SSA_NAME_PTR_INFO (var)
-	  && !SSA_NAME_PTR_INFO (copy_of[i].value))
-	duplicate_ssa_name_ptr_info (copy_of[i].value, SSA_NAME_PTR_INFO (var));
+          && TREE_CODE (copy_of[i].value) == SSA_NAME)
+        {
+          if (POINTER_TYPE_P (TREE_TYPE (var))
+              && SSA_NAME_PTR_INFO (var)
+              && !SSA_NAME_PTR_INFO (copy_of[i].value))
+            duplicate_ssa_name_ptr_info (copy_of[i].value,
+                                         SSA_NAME_PTR_INFO (var));
+          else if (!POINTER_TYPE_P (TREE_TYPE (var))
+                   && SSA_NAME_RANGE_INFO (var)
+                   && !SSA_NAME_RANGE_INFO (copy_of[i].value))
+            duplicate_ssa_name_range_info (copy_of[i].value,
+                                           SSA_NAME_RANGE_INFO (var));
+        }
     }
 
   /* Don't do DCE if SCEV is initialized.  It would destroy the scev cache.  */
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index a6af3da..8750f11 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -151,7 +151,11 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt)
       SET_SSA_NAME_VAR_OR_IDENTIFIER (t, var);
     }
   SSA_NAME_DEF_STMT (t) = stmt;
-  SSA_NAME_PTR_INFO (t) = NULL;
+  if (POINTER_TYPE_P (TREE_TYPE (t)))
+    SSA_NAME_PTR_INFO (t) = NULL;
+  else
+    SSA_NAME_RANGE_INFO (t) = NULL;
+
   SSA_NAME_IN_FREE_LIST (t) = 0;
   SSA_NAME_IS_DEFAULT_DEF (t) = 0;
   imm = &(SSA_NAME_IMM_USE_NODE (t));
@@ -163,6 +167,31 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt)
   return t;
 }
 
+/* Store range information MIN, MAX and VR_RANGE type
+   from value range propagation to tree ssa_name NAME.  */
+
+void
+set_range_info (tree name, double_int min,
+                          double_int max, bool vr_range)
+{
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  gcc_assert (TREE_CODE (name) == SSA_NAME);
+  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
+
+  /* Allocate if not available.  */
+  if (ri == NULL)
+    {
+      ri = ggc_alloc_cleared_range_info_def ();
+      mark_range_info_unknown (ri);
+      SSA_NAME_RANGE_INFO (name) = ri;
+    }
+
+  /* Set the values.  */
+  ri->valid = true;
+  ri->min = min;
+  ri->max = max;
+  ri->vr_range = vr_range;
+}
 
 /* We no longer need the SSA_NAME expression VAR, release it so that
    it may be reused.
@@ -266,6 +295,14 @@ mark_ptr_info_alignment_unknown (struct ptr_info_def *pi)
   pi->misalign = 0;
 }
 
+/* Set the range described by RI has invalid values.  */
+
+void
+mark_range_info_unknown (struct range_info_def *ri)
+{
+  ri->valid = false;
+}
+
 /* Store the the power-of-two byte alignment and the deviation from that
    alignment of pointer described by PI to ALIOGN and MISALIGN
    respectively.  */
@@ -359,6 +396,26 @@ duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info)
   SSA_NAME_PTR_INFO (name) = new_ptr_info;
 }
 
+/* Creates a duplicate of the range_info_def at RANGE_INFO for use by
+   the SSA name NAME.  */
+void
+duplicate_ssa_name_range_info (tree name, struct range_info_def *range_info)
+{
+  struct range_info_def *new_range_info;
+
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  gcc_assert (!SSA_NAME_RANGE_INFO (name));
+
+  if (!range_info)
+    return;
+
+  new_range_info = ggc_alloc_range_info_def ();
+  *new_range_info = *range_info;
+
+  SSA_NAME_RANGE_INFO (name) = new_range_info;
+}
+
+
 
 /* Creates a duplicate of a ssa name NAME tobe defined by statement STMT
    in function FN.  */
@@ -367,10 +424,20 @@ tree
 duplicate_ssa_name_fn (struct function *fn, tree name, gimple stmt)
 {
   tree new_name = copy_ssa_name_fn (fn, name, stmt);
-  struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
+  if (POINTER_TYPE_P (TREE_TYPE (name)))
+    {
+      struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
+
+      if (old_ptr_info)
+        duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+    }
+  else
+    {
+      struct range_info_def *old_range_info = SSA_NAME_RANGE_INFO (name);
 
-  if (old_ptr_info)
-    duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+      if (old_range_info)
+        duplicate_ssa_name_range_info (new_name, old_range_info);
+    }
 
   return new_name;
 }
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index ff82591..cb06793 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -3753,11 +3753,10 @@ extract_range_basic (value_range_t *vr, gimple stmt)
 }
 
 
-/* Try to compute a useful range out of assignment STMT and store it
-   in *VR.  */
-
+/* Compute a useful range out of assignment STMT and store it
+   in VR.  */
 static void
-extract_range_from_assignment (value_range_t *vr, gimple stmt)
+extract_range_from_assignment_1 (value_range_t *vr, gimple stmt)
 {
   enum tree_code code = gimple_assign_rhs_code (stmt);
 
@@ -3787,6 +3786,19 @@ extract_range_from_assignment (value_range_t *vr, gimple stmt)
   else
     set_value_range_to_varying (vr);
 
+}
+
+/* Try to compute a useful range out of assignment STMT and store it
+   in *VR.  */
+
+static void
+extract_range_from_assignment (value_range_t *vr, gimple stmt)
+{
+  extract_range_from_assignment_1 (vr, stmt);
+
+  /* If range is varying try to derive nonnegative or nonzero
+     range out of STMT relying primarily on generic routines
+     in fold in conjunction with range data.  */
   if (vr->type == VR_VARYING)
     extract_range_basic (vr, stmt);
 }
@@ -9124,6 +9136,34 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
     {
       enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
       tree rhs1 = gimple_assign_rhs1 (stmt);
+      tree lhs = gimple_assign_lhs (stmt);
+
+      /* Set value range information for ssa.  */
+      if (!POINTER_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
+          && (TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
+          && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
+          && !SSA_NAME_RANGE_INFO (lhs))
+        {
+          value_range_t vr = VR_INITIALIZER;
+
+          /* Extract the value range of assigned exprassion
+             not considering the lhs type.  */
+          if ((gimple_assign_rhs_code (stmt) == NOP_EXPR)
+               || (gimple_assign_rhs_code (stmt) == CONVERT_EXPR))
+            extract_range_from_unary_expr (&vr, gimple_assign_rhs_code (stmt),
+                                           TREE_TYPE (rhs1),
+                                           gimple_assign_rhs1 (stmt));
+          else
+            extract_range_from_assignment_1 (&vr, stmt);
+
+          /* If value range is valid, set that.  */
+          if ((vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)
+              && range_int_cst_p (&vr))
+            set_range_info (lhs,
+                            tree_to_double_int (vr.min),
+                            tree_to_double_int (vr.max),
+                            vr.type == VR_RANGE);
+        }
 
       switch (rhs_code)
 	{
diff --git a/gcc/tree.h b/gcc/tree.h
index 94f112f..9330845 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1950,10 +1950,19 @@ struct GTY(()) tree_exp {
 
 /* Attributes for SSA_NAMEs for pointer-type variables.  */
 #define SSA_NAME_PTR_INFO(N) \
-    SSA_NAME_CHECK (N)->ssa_name.ptr_info
+   SSA_NAME_CHECK (N)->ssa_name.vrp.ptr_info
+
+/* Value range info Attributes for SSA_NAMEs of non pointer-type variables.  */
+#define SSA_NAME_RANGE_INFO(N) \
+    SSA_NAME_CHECK (N)->ssa_name.vrp.range_info
+
+/* Sets the value range extreacted from VRP into SSA.  */
+void set_range_info (tree ssa, double_int min,
+                               double_int max, bool vr_range);
 
 /* Defined in tree-flow.h.  */
 struct ptr_info_def;
+struct range_info_def;
 
 /* Immediate use linking structure.  This structure is used for maintaining
    a doubly linked list of uses of an SSA_NAME.  */
@@ -1981,8 +1990,13 @@ struct GTY(()) tree_ssa_name {
   /* Statement that defines this SSA name.  */
   gimple def_stmt;
 
-  /* Pointer attributes used for alias analysis.  */
-  struct ptr_info_def *ptr_info;
+  /* Value range information.  */
+  union vrp_info_type {
+    /* Pointer attributes used for alias analysis.  */
+    struct GTY ((tag ("0"))) ptr_info_def *ptr_info;
+    /* Value range attributes used for zero/sign extension elimination.  */
+    struct GTY ((tag ("1"))) range_info_def *range_info;
+  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE ((tree)&%1))"))) vrp;
 
   /* Immediate uses list for this SSA_NAME.  */
   struct ssa_use_operand_d imm_uses;

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-07-03 12:26     ` Kugan
  2013-08-14  7:19       ` Kugan
@ 2013-09-02 12:45       ` Richard Biener
  2013-09-03 12:15         ` Kugan
  1 sibling, 1 reply; 38+ messages in thread
From: Richard Biener @ 2013-09-02 12:45 UTC (permalink / raw)
  To: Kugan
  Cc: Richard Biener, gcc-patches, Eric Botcazou, Ramana Radhakrishnan,
	Richard Earnshaw

On Wed, Jul 3, 2013 at 2:25 PM, Kugan <kugan.vivekanandarajah@linaro.org> wrote:
> On 17/06/13 18:33, Richard Biener wrote:
>>
>> On Mon, 17 Jun 2013, Kugan wrote:
>> +/* Extract the value range of assigned exprassion for GIMPLE_ASSIGN stmt.
>> +   If the extracted value range is valid, return true else return
>> +   false.  */
>> +static bool
>> +extract_exp_value_range (gimple stmt, value_range_t *vr)
>> +{
>> +  gcc_assert (is_gimple_assign (stmt));
>> +  tree rhs1 = gimple_assign_rhs1 (stmt);
>> +  tree lhs = gimple_assign_lhs (stmt);
>> +  enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
>> ...
>> @@ -8960,6 +9016,23 @@ simplify_stmt_using_ranges (gimple_stmt_iterator
>> *gsi)
>>       {
>>         enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
>>         tree rhs1 = gimple_assign_rhs1 (stmt);
>> +      tree lhs = gimple_assign_lhs (stmt);
>> +
>> +      /* Set value range information for ssa.  */
>> +      if (!POINTER_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
>> +          && (TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
>> +          && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
>> +          && !SSA_NAME_RANGE_INFO (lhs))
>> +        {
>> +          value_range_t vr = VR_INITIALIZER;
>> ...
>> +          if (extract_exp_value_range (stmt, &vr))
>> +            tree_ssa_set_value_range (lhs,
>> +                                      tree_to_double_int (vr.min),
>> +                                      tree_to_double_int (vr.max),
>> +                                      vr.type == VR_RANGE);
>> +        }
>>
>> This looks overly complicated to me.  In vrp_finalize you can simply do
>>
>>    for (i = 0; i < num_vr_values; i++)
>>      if (vr_value[i])
>>        {
>>          tree name = ssa_name (i);
>>          if (POINTER_TYPE_P (name))
>>            continue;
>>          if (vr_value[i].type == VR_RANGE
>>              || vr_value[i].type == VR_ANTI_RANGE)
>>            tree_ssa_set_value_range (name, tree_to_double_int
>> (vr_value[i].min), tree_to_double_int (vr_value[i].max), vr_value[i].type
>> == VR_RANGE);
>>        }
>>
>
> Thanks Richard for taking time to review it.
>
> I was doing something like what you are suggesting earlier but noticed some
> problems and that’s the reason why I changed.
>
> For example, for the following testcase from the test suite,
>
> unsigned long l = (unsigned long)-2;
> unsigned short s;
>
> int main () {
>   long t = l + 1;
>   s = l;
>   if (s != (unsigned short) -2)
>     abort ();
>   exit (0);
> }
>
> with the following gimple stmts
>
> main ()
> {
>   short unsigned int s.1;
>   long unsigned int l.0;
>
> ;;   basic block 2, loop depth 0
> ;;    pred:       ENTRY
>   l.0_2 = l;
>   s.1_3 = (short unsigned int) l.0_2;
>   s = s.1_3;
>   if (s.1_3 != 65534)
>     goto <bb 3>;
>   else
>     goto <bb 4>;
> ;;    succ:       3
> ;;                4
>
> ;;   basic block 3, loop depth 0
> ;;    pred:       2
>   abort ();
> ;;    succ:
>
> ;;   basic block 4, loop depth 0
> ;;    pred:       2
>   exit (0);
> ;;    succ:
>
> }
>
>
>
> has the following value range.
>
> l.0_2: VARYING
> s.1_3: [0, +INF]
>
>
> From zero/sign extension point of view, the variable s.1_3 is expected to
> have a value that will overflow (or varying) as this is what is assigned to
> a smaller variable. extract_range_from_assignment initially calculates the
> value range as VARYING but later changed to [0, +INF] by
> extract_range_basic. What I need here is the value that will be assigned
> from the rhs expression and not the value that we will have with proper
> assignment.

I don't understand this.  The relevant statement is

  s.1_3 = (short unsigned int) l.0_2;

right?  You have value-ranges for both s.1_3 and l.0_2 as above.  And
you clearly cannot optimize the truncation away (and if you could,
you wond't need value-range information for that fact).

> I understand that the above code of mine needs to be changed but not
> convinced about the best way to do that.
>
> I can possibly re-factor extract_range_from_assignment to give me this
> information with an additional argument. Could you kindly let me know your
> preference.
>
>
>
>>
>> /* SSA name annotations.  */
>>
>> +  union vrp_info_type {
>> +    /* Pointer attributes used for alias analysis.  */
>> +    struct GTY ((tag ("TREE_SSA_PTR_INFO"))) ptr_info_def *ptr_info;
>> +    /* Value range attributes used for zero/sign extension elimination.
>> */
>>
>> /* Value range information.  */
>>
>> +    struct GTY ((tag ("TREE_SSA_RANGE_INFO"))) range_info_def
>> *range_info;
>> +  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE
>> ((tree)&%1))"))) vrp;
>>
>> why do you need to test %1.def_stmt here?
>
>
>
> I have seen some tree_ssa_name with def_stmt NULL. Thats why I added this.
> Is that something that should never happen.

It should never happen - they should have a GIMPLE_NOP.

+void
+set_range_info (tree name, double_int min,
+                          double_int max, bool vr_range)

you have some whitespace issues here (please properly use tabs)

+  /* Allocate if not available.  */
+  if (ri == NULL)
+    {
+      ri = ggc_alloc_cleared_range_info_def ();
+      mark_range_info_unknown (ri);

that looks superfluous to me.

+      SSA_NAME_RANGE_INFO (name) = ri;

-  /* Pointer attributes used for alias analysis.  */
-  struct ptr_info_def *ptr_info;
+  /* Value range information.  */
+  union vrp_info_type {
+    /* Pointer attributes used for alias analysis.  */
+    struct GTY ((tag ("0"))) ptr_info_def *ptr_info;
+    /* Value range attributes used for zero/sign extension elimination.  */
+    struct GTY ((tag ("1"))) range_info_def *range_info;
+  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE
((tree)&%1))"))) vrp;

please change vrp_info_type and vrp to other names - this is not vrp
specific info
after all, I suggest ssa_name_info_type and info.

The genric bits otherwise look ok to me, the VRP bits still look wrong (see my
above question) and need explanation.

Thanks,
Richard.

>
> Thanks,
> Kugan

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-02 12:45       ` Richard Biener
@ 2013-09-03 12:15         ` Kugan
  2013-09-06  6:47           ` Richard Biener
  0 siblings, 1 reply; 38+ messages in thread
From: Kugan @ 2013-09-03 12:15 UTC (permalink / raw)
  To: Richard Biener
  Cc: Richard Biener, gcc-patches, Eric Botcazou, Ramana Radhakrishnan,
	Richard Earnshaw

Thanks Richard for reviewing.

On 02/09/13 22:15, Richard Biener wrote:
> On Wed, Jul 3, 2013 at 2:25 PM, Kugan <kugan.vivekanandarajah@linaro.org> wrote:
>> On 17/06/13 18:33, Richard Biener wrote:
>>>
>>> On Mon, 17 Jun 2013, Kugan wrote:
>>> +/* Extract the value range of assigned exprassion for GIMPLE_ASSIGN stmt.
>>> +   If the extracted value range is valid, return true else return
>>> +   false.  */
>>> +static bool
>>> +extract_exp_value_range (gimple stmt, value_range_t *vr)
>>> +{
>>> +  gcc_assert (is_gimple_assign (stmt));
>>> +  tree rhs1 = gimple_assign_rhs1 (stmt);
>>> +  tree lhs = gimple_assign_lhs (stmt);
>>> +  enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
>>> ...
>>> @@ -8960,6 +9016,23 @@ simplify_stmt_using_ranges (gimple_stmt_iterator
>>> *gsi)
>>>        {
>>>          enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
>>>          tree rhs1 = gimple_assign_rhs1 (stmt);
>>> +      tree lhs = gimple_assign_lhs (stmt);
>>> +
>>> +      /* Set value range information for ssa.  */
>>> +      if (!POINTER_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
>>> +          && (TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
>>> +          && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
>>> +          && !SSA_NAME_RANGE_INFO (lhs))
>>> +        {
>>> +          value_range_t vr = VR_INITIALIZER;
>>> ...
>>> +          if (extract_exp_value_range (stmt, &vr))
>>> +            tree_ssa_set_value_range (lhs,
>>> +                                      tree_to_double_int (vr.min),
>>> +                                      tree_to_double_int (vr.max),
>>> +                                      vr.type == VR_RANGE);
>>> +        }
>>>
>>> This looks overly complicated to me.  In vrp_finalize you can simply do
>>>
>>>     for (i = 0; i < num_vr_values; i++)
>>>       if (vr_value[i])
>>>         {
>>>           tree name = ssa_name (i);
>>>           if (POINTER_TYPE_P (name))
>>>             continue;
>>>           if (vr_value[i].type == VR_RANGE
>>>               || vr_value[i].type == VR_ANTI_RANGE)
>>>             tree_ssa_set_value_range (name, tree_to_double_int
>>> (vr_value[i].min), tree_to_double_int (vr_value[i].max), vr_value[i].type
>>> == VR_RANGE);
>>>         }
>>>
>>
>> Thanks Richard for taking time to review it.
>>
>> I was doing something like what you are suggesting earlier but noticed some
>> problems and thatÂ’s the reason why I changed.
>>
>> For example, for the following testcase from the test suite,
>>
>> unsigned long l = (unsigned long)-2;
>> unsigned short s;
>>
>> int main () {
>>    long t = l + 1;
>>    s = l;
>>    if (s != (unsigned short) -2)
>>      abort ();
>>    exit (0);
>> }
>>
>> with the following gimple stmts
>>
>> main ()
>> {
>>    short unsigned int s.1;
>>    long unsigned int l.0;
>>
>> ;;   basic block 2, loop depth 0
>> ;;    pred:       ENTRY
>>    l.0_2 = l;
>>    s.1_3 = (short unsigned int) l.0_2;
>>    s = s.1_3;
>>    if (s.1_3 != 65534)
>>      goto <bb 3>;
>>    else
>>      goto <bb 4>;
>> ;;    succ:       3
>> ;;                4
>>
>> ;;   basic block 3, loop depth 0
>> ;;    pred:       2
>>    abort ();
>> ;;    succ:
>>
>> ;;   basic block 4, loop depth 0
>> ;;    pred:       2
>>    exit (0);
>> ;;    succ:
>>
>> }
>>
>>
>>
>> has the following value range.
>>
>> l.0_2: VARYING
>> s.1_3: [0, +INF]
>>
>>
>>  From zero/sign extension point of view, the variable s.1_3 is expected to
>> have a value that will overflow (or varying) as this is what is assigned to
>> a smaller variable. extract_range_from_assignment initially calculates the
>> value range as VARYING but later changed to [0, +INF] by
>> extract_range_basic. What I need here is the value that will be assigned
>> from the rhs expression and not the value that we will have with proper
>> assignment.
>
> I don't understand this.  The relevant statement is
>
>    s.1_3 = (short unsigned int) l.0_2;
>
> right?  You have value-ranges for both s.1_3 and l.0_2 as above.  And
> you clearly cannot optimize the truncation away (and if you could,
> you wond't need value-range information for that fact).
>
This is true. But just by looking at the value range of s.1.3 we will 
only see [0 +INF], as we are transferring directly from the lattice to 
lhs its value range.

[0, +INF] here tells us  vrp_val_is_max and it is not 
is_positive_overflow_infinity (or varying). Thats why we need to get the 
value range of RHS expression which will tell us the actual range. We 
can then use this range and see of we can fit it to lhs type without 
truncation.

>> I understand that the above code of mine needs to be changed but not
>> convinced about the best way to do that.
>>
>> I can possibly re-factor extract_range_from_assignment to give me this
>> information with an additional argument. Could you kindly let me know your
>> preference.
>>
>>
>>
>>>
>>> /* SSA name annotations.  */
>>>
>>> +  union vrp_info_type {
>>> +    /* Pointer attributes used for alias analysis.  */
>>> +    struct GTY ((tag ("TREE_SSA_PTR_INFO"))) ptr_info_def *ptr_info;
>>> +    /* Value range attributes used for zero/sign extension elimination.
>>> */
>>>
>>> /* Value range information.  */
>>>
>>> +    struct GTY ((tag ("TREE_SSA_RANGE_INFO"))) range_info_def
>>> *range_info;
>>> +  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE
>>> ((tree)&%1))"))) vrp;
>>>
>>> why do you need to test %1.def_stmt here?
>>
>>
>>
>> I have seen some tree_ssa_name with def_stmt NULL. Thats why I added this.
>> Is that something that should never happen.
>
> It should never happen - they should have a GIMPLE_NOP.
>

I am seeing def_stmt of NULL for TREE_NOTHROW node.
debug_tree dumps the following in this case:

<ssa_name 0x2aaaabd89af8 nothrow var <var_decl 0x2aaaadb384c0 t>def_stmt

     version 11 in-free-list>

> +void
> +set_range_info (tree name, double_int min,
> +                          double_int max, bool vr_range)
>
> you have some whitespace issues here (please properly use tabs)
>

I will change it.

> +  /* Allocate if not available.  */
> +  if (ri == NULL)
> +    {
> +      ri = ggc_alloc_cleared_range_info_def ();
> +      mark_range_info_unknown (ri);
>
> that looks superfluous to me.
>
> +      SSA_NAME_RANGE_INFO (name) = ri;
>
> -  /* Pointer attributes used for alias analysis.  */
> -  struct ptr_info_def *ptr_info;
> +  /* Value range information.  */
> +  union vrp_info_type {
> +    /* Pointer attributes used for alias analysis.  */
> +    struct GTY ((tag ("0"))) ptr_info_def *ptr_info;
> +    /* Value range attributes used for zero/sign extension elimination.  */
> +    struct GTY ((tag ("1"))) range_info_def *range_info;
> +  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE
> ((tree)&%1))"))) vrp;
>
> please change vrp_info_type and vrp to other names - this is not vrp
> specific info
> after all, I suggest ssa_name_info_type and info.
>

I will change this too.
> The genric bits otherwise look ok to me, the VRP bits still look wrong (see my
> above question) and need explanation.
>
> Thanks,
> Richard.
>
>>
>> Thanks,
>> Kugan


Thanks,
Kugan

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-03 12:15         ` Kugan
@ 2013-09-06  6:47           ` Richard Biener
  2013-09-09  0:15             ` Kugan
  0 siblings, 1 reply; 38+ messages in thread
From: Richard Biener @ 2013-09-06  6:47 UTC (permalink / raw)
  To: Kugan
  Cc: Richard Biener, gcc-patches, Eric Botcazou, Ramana Radhakrishnan,
	Richard Earnshaw

On 9/3/13 2:15 PM, Kugan wrote:
> Thanks Richard for reviewing.
> 
> On 02/09/13 22:15, Richard Biener wrote:
>> On Wed, Jul 3, 2013 at 2:25 PM, Kugan
>> <kugan.vivekanandarajah@linaro.org> wrote:
>>> On 17/06/13 18:33, Richard Biener wrote:
>>>>
>>>> On Mon, 17 Jun 2013, Kugan wrote:
>>>> +/* Extract the value range of assigned exprassion for GIMPLE_ASSIGN
>>>> stmt.
>>>> +   If the extracted value range is valid, return true else return
>>>> +   false.  */
>>>> +static bool
>>>> +extract_exp_value_range (gimple stmt, value_range_t *vr)
>>>> +{
>>>> +  gcc_assert (is_gimple_assign (stmt));
>>>> +  tree rhs1 = gimple_assign_rhs1 (stmt);
>>>> +  tree lhs = gimple_assign_lhs (stmt);
>>>> +  enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
>>>> ...
>>>> @@ -8960,6 +9016,23 @@ simplify_stmt_using_ranges (gimple_stmt_iterator
>>>> *gsi)
>>>>        {
>>>>          enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
>>>>          tree rhs1 = gimple_assign_rhs1 (stmt);
>>>> +      tree lhs = gimple_assign_lhs (stmt);
>>>> +
>>>> +      /* Set value range information for ssa.  */
>>>> +      if (!POINTER_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
>>>> +          && (TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
>>>> +          && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_lhs (stmt)))
>>>> +          && !SSA_NAME_RANGE_INFO (lhs))
>>>> +        {
>>>> +          value_range_t vr = VR_INITIALIZER;
>>>> ...
>>>> +          if (extract_exp_value_range (stmt, &vr))
>>>> +            tree_ssa_set_value_range (lhs,
>>>> +                                      tree_to_double_int (vr.min),
>>>> +                                      tree_to_double_int (vr.max),
>>>> +                                      vr.type == VR_RANGE);
>>>> +        }
>>>>
>>>> This looks overly complicated to me.  In vrp_finalize you can simply do
>>>>
>>>>     for (i = 0; i < num_vr_values; i++)
>>>>       if (vr_value[i])
>>>>         {
>>>>           tree name = ssa_name (i);
>>>>           if (POINTER_TYPE_P (name))
>>>>             continue;
>>>>           if (vr_value[i].type == VR_RANGE
>>>>               || vr_value[i].type == VR_ANTI_RANGE)
>>>>             tree_ssa_set_value_range (name, tree_to_double_int
>>>> (vr_value[i].min), tree_to_double_int (vr_value[i].max),
>>>> vr_value[i].type
>>>> == VR_RANGE);
>>>>         }
>>>>
>>>
>>> Thanks Richard for taking time to review it.
>>>
>>> I was doing something like what you are suggesting earlier but
>>> noticed some
>>> problems and thatÂ’s the reason why I changed.
>>>
>>> For example, for the following testcase from the test suite,
>>>
>>> unsigned long l = (unsigned long)-2;
>>> unsigned short s;
>>>
>>> int main () {
>>>    long t = l + 1;
>>>    s = l;
>>>    if (s != (unsigned short) -2)
>>>      abort ();
>>>    exit (0);
>>> }
>>>
>>> with the following gimple stmts
>>>
>>> main ()
>>> {
>>>    short unsigned int s.1;
>>>    long unsigned int l.0;
>>>
>>> ;;   basic block 2, loop depth 0
>>> ;;    pred:       ENTRY
>>>    l.0_2 = l;
>>>    s.1_3 = (short unsigned int) l.0_2;
>>>    s = s.1_3;
>>>    if (s.1_3 != 65534)
>>>      goto <bb 3>;
>>>    else
>>>      goto <bb 4>;
>>> ;;    succ:       3
>>> ;;                4
>>>
>>> ;;   basic block 3, loop depth 0
>>> ;;    pred:       2
>>>    abort ();
>>> ;;    succ:
>>>
>>> ;;   basic block 4, loop depth 0
>>> ;;    pred:       2
>>>    exit (0);
>>> ;;    succ:
>>>
>>> }
>>>
>>>
>>>
>>> has the following value range.
>>>
>>> l.0_2: VARYING
>>> s.1_3: [0, +INF]
>>>
>>>
>>>  From zero/sign extension point of view, the variable s.1_3 is
>>> expected to
>>> have a value that will overflow (or varying) as this is what is
>>> assigned to
>>> a smaller variable. extract_range_from_assignment initially
>>> calculates the
>>> value range as VARYING but later changed to [0, +INF] by
>>> extract_range_basic. What I need here is the value that will be assigned
>>> from the rhs expression and not the value that we will have with proper
>>> assignment.
>>
>> I don't understand this.  The relevant statement is
>>
>>    s.1_3 = (short unsigned int) l.0_2;
>>
>> right?  You have value-ranges for both s.1_3 and l.0_2 as above.  And
>> you clearly cannot optimize the truncation away (and if you could,
>> you wond't need value-range information for that fact).
>>
> This is true. But just by looking at the value range of s.1.3 we will
> only see [0 +INF], as we are transferring directly from the lattice to
> lhs its value range.
> 
> [0, +INF] here tells us  vrp_val_is_max and it is not
> is_positive_overflow_infinity (or varying). Thats why we need to get the
> value range of RHS expression which will tell us the actual range. We
> can then use this range and see of we can fit it to lhs type without
> truncation.

Well, my point is you want to look at the l.0_2 value-range for this.
Storing the l.0_2 value-range for s.1_3 is wrong.

>>> I understand that the above code of mine needs to be changed but not
>>> convinced about the best way to do that.
>>>
>>> I can possibly re-factor extract_range_from_assignment to give me this
>>> information with an additional argument. Could you kindly let me know
>>> your
>>> preference.
>>>
>>>
>>>
>>>>
>>>> /* SSA name annotations.  */
>>>>
>>>> +  union vrp_info_type {
>>>> +    /* Pointer attributes used for alias analysis.  */
>>>> +    struct GTY ((tag ("TREE_SSA_PTR_INFO"))) ptr_info_def *ptr_info;
>>>> +    /* Value range attributes used for zero/sign extension
>>>> elimination.
>>>> */
>>>>
>>>> /* Value range information.  */
>>>>
>>>> +    struct GTY ((tag ("TREE_SSA_RANGE_INFO"))) range_info_def
>>>> *range_info;
>>>> +  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE
>>>> ((tree)&%1))"))) vrp;
>>>>
>>>> why do you need to test %1.def_stmt here?
>>>
>>>
>>>
>>> I have seen some tree_ssa_name with def_stmt NULL. Thats why I added
>>> this.
>>> Is that something that should never happen.
>>
>> It should never happen - they should have a GIMPLE_NOP.
>>
> 
> I am seeing def_stmt of NULL for TREE_NOTHROW node.
> debug_tree dumps the following in this case:
> 
> <ssa_name 0x2aaaabd89af8 nothrow var <var_decl 0x2aaaadb384c0 t>def_stmt
> 
>     version 11 in-free-list>

This is an invalid SSA name (in-free-list) that has been released.  You
shouldn't look at it at all.

Richard.

>> +void
>> +set_range_info (tree name, double_int min,
>> +                          double_int max, bool vr_range)
>>
>> you have some whitespace issues here (please properly use tabs)
>>
> 
> I will change it.
> 
>> +  /* Allocate if not available.  */
>> +  if (ri == NULL)
>> +    {
>> +      ri = ggc_alloc_cleared_range_info_def ();
>> +      mark_range_info_unknown (ri);
>>
>> that looks superfluous to me.
>>
>> +      SSA_NAME_RANGE_INFO (name) = ri;
>>
>> -  /* Pointer attributes used for alias analysis.  */
>> -  struct ptr_info_def *ptr_info;
>> +  /* Value range information.  */
>> +  union vrp_info_type {
>> +    /* Pointer attributes used for alias analysis.  */
>> +    struct GTY ((tag ("0"))) ptr_info_def *ptr_info;
>> +    /* Value range attributes used for zero/sign extension
>> elimination.  */
>> +    struct GTY ((tag ("1"))) range_info_def *range_info;
>> +  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE
>> ((tree)&%1))"))) vrp;
>>
>> please change vrp_info_type and vrp to other names - this is not vrp
>> specific info
>> after all, I suggest ssa_name_info_type and info.
>>
> 
> I will change this too.
>> The genric bits otherwise look ok to me, the VRP bits still look wrong
>> (see my
>> above question) and need explanation.
>>
>> Thanks,
>> Richard.
>>
>>>
>>> Thanks,
>>> Kugan
> 
> 
> Thanks,
> Kugan
> 

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-06  6:47           ` Richard Biener
@ 2013-09-09  0:15             ` Kugan
  2013-09-09  9:37               ` Richard Biener
  0 siblings, 1 reply; 38+ messages in thread
From: Kugan @ 2013-09-09  0:15 UTC (permalink / raw)
  To: Richard Biener
  Cc: Richard Biener, gcc-patches, Eric Botcazou, Ramana Radhakrishnan,
	Richard Earnshaw


On 06/09/13 16:16, Richard Biener wrote:
> On 9/3/13 2:15 PM, Kugan wrote:
>> Thanks Richard for reviewing.
>>
>> On 02/09/13 22:15, Richard Biener wrote:
>>> On Wed, Jul 3, 2013 at 2:25 PM, Kugan
>>> <kugan.vivekanandarajah@linaro.org> wrote:
>>>> On 17/06/13 18:33, Richard Biener wrote:
>>>>>
>>>>> On Mon, 17 Jun 2013, Kugan wrote:
>>>>> +/* Extract the value range of assigned exprassion for GIMPLE_ASSIGN
>>>>> stmt.
>>>>> +   If the extracted value range is valid, return true else return
>>>>> +   false.  */
>>>>> +static bool

[snip]

>>>>>
>>>>>      for (i = 0; i < num_vr_values; i++)
>>>>>        if (vr_value[i])
>>>>>          {
>>>>>            tree name = ssa_name (i);
>>>>>            if (POINTER_TYPE_P (name))
>>>>>              continue;
>>>>>            if (vr_value[i].type == VR_RANGE
>>>>>                || vr_value[i].type == VR_ANTI_RANGE)
>>>>>              tree_ssa_set_value_range (name, tree_to_double_int
>>>>> (vr_value[i].min), tree_to_double_int (vr_value[i].max),
>>>>> vr_value[i].type
>>>>> == VR_RANGE);
>>>>>          }
>>>>>
>>>>
>>>> Thanks Richard for taking time to review it.
>>>>
>>>> I was doing something like what you are suggesting earlier but
>>>> noticed some
>>>> problems and thatÂ’s the reason why I changed.
>>>>
>>>> For example, for the following testcase from the test suite,
>>>>
>>>> unsigned long l = (unsigned long)-2;
>>>> unsigned short s;
>>>>
>>>> int main () {
>>>>     long t = l + 1;
>>>>     s = l;
>>>>     if (s != (unsigned short) -2)
>>>>       abort ();
>>>>     exit (0);
>>>> }
>>>>
>>>> with the following gimple stmts
>>>>
>>>> main ()
>>>> {
>>>>     short unsigned int s.1;
>>>>     long unsigned int l.0;
>>>>
>>>> ;;   basic block 2, loop depth 0
>>>> ;;    pred:       ENTRY
>>>>     l.0_2 = l;
>>>>     s.1_3 = (short unsigned int) l.0_2;
>>>>     s = s.1_3;
>>>>     if (s.1_3 != 65534)
>>>>       goto <bb 3>;
>>>>     else
>>>>       goto <bb 4>;
>>>> ;;    succ:       3
>>>> ;;                4
>>>>
>>>> ;;   basic block 3, loop depth 0
>>>> ;;    pred:       2
>>>>     abort ();
>>>> ;;    succ:
>>>>
>>>> ;;   basic block 4, loop depth 0
>>>> ;;    pred:       2
>>>>     exit (0);
>>>> ;;    succ:
>>>>
>>>> }
>>>>
>>>>
>>>>
>>>> has the following value range.
>>>>
>>>> l.0_2: VARYING
>>>> s.1_3: [0, +INF]
>>>>
>>>>
>>>>   From zero/sign extension point of view, the variable s.1_3 is
>>>> expected to
>>>> have a value that will overflow (or varying) as this is what is
>>>> assigned to
>>>> a smaller variable. extract_range_from_assignment initially
>>>> calculates the
>>>> value range as VARYING but later changed to [0, +INF] by
>>>> extract_range_basic. What I need here is the value that will be assigned
>>>> from the rhs expression and not the value that we will have with proper
>>>> assignment.
>>>
>>> I don't understand this.  The relevant statement is
>>>
>>>     s.1_3 = (short unsigned int) l.0_2;
>>>
>>> right?  You have value-ranges for both s.1_3 and l.0_2 as above.  And
>>> you clearly cannot optimize the truncation away (and if you could,
>>> you wond't need value-range information for that fact).
>>>
>> This is true. But just by looking at the value range of s.1.3 we will
>> only see [0 +INF], as we are transferring directly from the lattice to
>> lhs its value range.
>>
>> [0, +INF] here tells us  vrp_val_is_max and it is not
>> is_positive_overflow_infinity (or varying). Thats why we need to get the
>> value range of RHS expression which will tell us the actual range. We
>> can then use this range and see of we can fit it to lhs type without
>> truncation.
>
> Well, my point is you want to look at the l.0_2 value-range for this.
> Storing the l.0_2 value-range for s.1_3 is wrong.
>

Yes, tree SSA_NAME should have it's correct value range. But, assigning 
rhs expression's value range is not totally wrong , it is just that it 
can be conservative value range (please correct me if I am wrong here) 
in few cases, as it can have wider range.

I can use the rhs value range in the above case. We can also eliminate 
redundant zero/sign extensions for gimple binary and ternary stmts. In 
this case we will have to calculate the value range.  We will have to 
reuse these logic in tree-vrp.

Other option is to add another attribute in range_info_t to indicate if 
set_value_range_to_nonnegative is used in value range extraction.

What is your preferred solution please.


>>>> I understand that the above code of mine needs to be changed but not
>>>> convinced about the best way to do that.
>>>>
>>>> I can possibly re-factor extract_range_from_assignment to give me this
>>>> information with an additional argument. Could you kindly let me know
>>>> your
>>>> preference.
>>>>
>>>>
>>>>
>>>>>
>>>>> /* SSA name annotations.  */
>>>>>
>>>>> +  union vrp_info_type {
>>>>> +    /* Pointer attributes used for alias analysis.  */
>>>>> +    struct GTY ((tag ("TREE_SSA_PTR_INFO"))) ptr_info_def *ptr_info;
>>>>> +    /* Value range attributes used for zero/sign extension
>>>>> elimination.
>>>>> */
>>>>>
>>>>> /* Value range information.  */
>>>>>
>>>>> +    struct GTY ((tag ("TREE_SSA_RANGE_INFO"))) range_info_def
>>>>> *range_info;
>>>>> +  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE
>>>>> ((tree)&%1))"))) vrp;
>>>>>
>>>>> why do you need to test %1.def_stmt here?
>>>>
>>>>
>>>>
>>>> I have seen some tree_ssa_name with def_stmt NULL. Thats why I added
>>>> this.
>>>> Is that something that should never happen.
>>>
>>> It should never happen - they should have a GIMPLE_NOP.
>>>
>>
>> I am seeing def_stmt of NULL for TREE_NOTHROW node.
>> debug_tree dumps the following in this case:
>>
>> <ssa_name 0x2aaaabd89af8 nothrow var <var_decl 0x2aaaadb384c0 t>def_stmt
>>
>>      version 11 in-free-list>
>
> This is an invalid SSA name (in-free-list) that has been released.  You
> shouldn't look at it at all.

This is actually happening in garbage collection. If i remove the check, 
I get the following:

make[2]: *** [_mulsc3.o] Error 1
0x97755f crash_signal
	/home/kugan/work/sources/gcc-fsf/test/gcc/toplev.c:335
0x55f7d1 gt_ggc_mx_lang_tree_node(void*)
	./gt-c-c-decl.h:531
0x802e36 gt_ggc_mx<tree_node*>
	/home/kugan/work/sources/gcc-fsf/test/gcc/vec.h:1152
0x802e36 gt_ggc_mx_vec_tree_va_gc_(void*)
	/home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:1205
0x8081ed gt_ggc_mx_gimple_df(void*)
	/home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:1066
0x80825f gt_ggc_mx_function
	/home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:1280
0x80825f gt_ggc_mx_function(void*)
	/home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:1272
0x55f692 gt_ggc_mx_lang_tree_node(void*)
	./gt-c-c-decl.h:389
0x807dd5 gt_ggc_mx_symtab_node_def(void*)
	/home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:709
0x807fb0 gt_ggc_m_P15symtab_node_def4htab(void*)
	/home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:2928
0x7b7915 ggc_mark_root_tab
	/home/kugan/work/sources/gcc-fsf/test/gcc/ggc-common.c:133
0x7b7c60 ggc_mark_roots()
	/home/kugan/work/sources/gcc-fsf/test/gcc/ggc-common.c:152
0x615669 ggc_collect()
	/home/kugan/work/sources/gcc-fsf/test/gcc/ggc-page.c:2077




Thanks a lot.

Kugan

> Richard.
>
>>> +void
>>> +set_range_info (tree name, double_int min,
>>> +                          double_int max, bool vr_range)
>>>
>>> you have some whitespace issues here (please properly use tabs)
>>>
>>
>> I will change it.
>>
>>> +  /* Allocate if not available.  */
>>> +  if (ri == NULL)
>>> +    {
>>> +      ri = ggc_alloc_cleared_range_info_def ();
>>> +      mark_range_info_unknown (ri);
>>>
>>> that looks superfluous to me.
>>>
>>> +      SSA_NAME_RANGE_INFO (name) = ri;
>>>
>>> -  /* Pointer attributes used for alias analysis.  */
>>> -  struct ptr_info_def *ptr_info;
>>> +  /* Value range information.  */
>>> +  union vrp_info_type {
>>> +    /* Pointer attributes used for alias analysis.  */
>>> +    struct GTY ((tag ("0"))) ptr_info_def *ptr_info;
>>> +    /* Value range attributes used for zero/sign extension
>>> elimination.  */
>>> +    struct GTY ((tag ("1"))) range_info_def *range_info;
>>> +  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE
>>> ((tree)&%1))"))) vrp;
>>>
>>> please change vrp_info_type and vrp to other names - this is not vrp
>>> specific info
>>> after all, I suggest ssa_name_info_type and info.
>>>
>>
>> I will change this too.
>>> The genric bits otherwise look ok to me, the VRP bits still look wrong
>>> (see my
>>> above question) and need explanation.
>>>
>>> Thanks,
>>> Richard.
>>>
>>>>
>>>> Thanks,
>>>> Kugan
>>
>>
>> Thanks,
>> Kugan
>>
>

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-09  0:15             ` Kugan
@ 2013-09-09  9:37               ` Richard Biener
  2013-09-10  5:27                 ` Kugan
  0 siblings, 1 reply; 38+ messages in thread
From: Richard Biener @ 2013-09-09  9:37 UTC (permalink / raw)
  To: Kugan
  Cc: Richard Biener, gcc-patches, Eric Botcazou, Ramana Radhakrishnan,
	Richard Earnshaw

On Mon, Sep 9, 2013 at 1:09 AM, Kugan <kugan.vivekanandarajah@linaro.org> wrote:
>
> On 06/09/13 16:16, Richard Biener wrote:
>>
>> On 9/3/13 2:15 PM, Kugan wrote:
>>>
>>> Thanks Richard for reviewing.
>>>
>>> On 02/09/13 22:15, Richard Biener wrote:
>>>>
>>>> On Wed, Jul 3, 2013 at 2:25 PM, Kugan
>>>> <kugan.vivekanandarajah@linaro.org> wrote:
>>>>>
>>>>> On 17/06/13 18:33, Richard Biener wrote:
>>>>>>
>>>>>>
>>>>>> On Mon, 17 Jun 2013, Kugan wrote:
>>>>>> +/* Extract the value range of assigned exprassion for GIMPLE_ASSIGN
>>>>>> stmt.
>>>>>> +   If the extracted value range is valid, return true else return
>>>>>> +   false.  */
>>>>>> +static bool
>
>
> [snip]
>
>
>>>>>>
>>>>>>      for (i = 0; i < num_vr_values; i++)
>>>>>>        if (vr_value[i])
>>>>>>          {
>>>>>>            tree name = ssa_name (i);
>>>>>>            if (POINTER_TYPE_P (name))
>>>>>>              continue;
>>>>>>            if (vr_value[i].type == VR_RANGE
>>>>>>                || vr_value[i].type == VR_ANTI_RANGE)
>>>>>>              tree_ssa_set_value_range (name, tree_to_double_int
>>>>>> (vr_value[i].min), tree_to_double_int (vr_value[i].max),
>>>>>> vr_value[i].type
>>>>>> == VR_RANGE);
>>>>>>          }
>>>>>>
>>>>>
>>>>> Thanks Richard for taking time to review it.
>>>>>
>>>>> I was doing something like what you are suggesting earlier but
>>>>> noticed some
>>>>> problems and that’s the reason why I changed.
>>>>>
>>>>> For example, for the following testcase from the test suite,
>>>>>
>>>>> unsigned long l = (unsigned long)-2;
>>>>> unsigned short s;
>>>>>
>>>>> int main () {
>>>>>     long t = l + 1;
>>>>>     s = l;
>>>>>     if (s != (unsigned short) -2)
>>>>>       abort ();
>>>>>     exit (0);
>>>>> }
>>>>>
>>>>> with the following gimple stmts
>>>>>
>>>>> main ()
>>>>> {
>>>>>     short unsigned int s.1;
>>>>>     long unsigned int l.0;
>>>>>
>>>>> ;;   basic block 2, loop depth 0
>>>>> ;;    pred:       ENTRY
>>>>>     l.0_2 = l;
>>>>>     s.1_3 = (short unsigned int) l.0_2;
>>>>>     s = s.1_3;
>>>>>     if (s.1_3 != 65534)
>>>>>       goto <bb 3>;
>>>>>     else
>>>>>       goto <bb 4>;
>>>>> ;;    succ:       3
>>>>> ;;                4
>>>>>
>>>>> ;;   basic block 3, loop depth 0
>>>>> ;;    pred:       2
>>>>>     abort ();
>>>>> ;;    succ:
>>>>>
>>>>> ;;   basic block 4, loop depth 0
>>>>> ;;    pred:       2
>>>>>     exit (0);
>>>>> ;;    succ:
>>>>>
>>>>> }
>>>>>
>>>>>
>>>>>
>>>>> has the following value range.
>>>>>
>>>>> l.0_2: VARYING
>>>>> s.1_3: [0, +INF]
>>>>>
>>>>>
>>>>>   From zero/sign extension point of view, the variable s.1_3 is
>>>>> expected to
>>>>> have a value that will overflow (or varying) as this is what is
>>>>> assigned to
>>>>> a smaller variable. extract_range_from_assignment initially
>>>>> calculates the
>>>>> value range as VARYING but later changed to [0, +INF] by
>>>>> extract_range_basic. What I need here is the value that will be
>>>>> assigned
>>>>> from the rhs expression and not the value that we will have with proper
>>>>> assignment.
>>>>
>>>>
>>>> I don't understand this.  The relevant statement is
>>>>
>>>>     s.1_3 = (short unsigned int) l.0_2;
>>>>
>>>> right?  You have value-ranges for both s.1_3 and l.0_2 as above.  And
>>>> you clearly cannot optimize the truncation away (and if you could,
>>>> you wond't need value-range information for that fact).
>>>>
>>> This is true. But just by looking at the value range of s.1.3 we will
>>> only see [0 +INF], as we are transferring directly from the lattice to
>>> lhs its value range.
>>>
>>> [0, +INF] here tells us  vrp_val_is_max and it is not
>>> is_positive_overflow_infinity (or varying). Thats why we need to get the
>>> value range of RHS expression which will tell us the actual range. We
>>> can then use this range and see of we can fit it to lhs type without
>>> truncation.
>>
>>
>> Well, my point is you want to look at the l.0_2 value-range for this.
>> Storing the l.0_2 value-range for s.1_3 is wrong.
>>
>
> Yes, tree SSA_NAME should have it's correct value range. But, assigning rhs
> expression's value range is not totally wrong , it is just that it can be
> conservative value range (please correct me if I am wrong here) in few
> cases, as it can have wider range.

If it's a sign-changing conversion it can be surely wrong.

> I can use the rhs value range in the above case. We can also eliminate
> redundant zero/sign extensions for gimple binary and ternary stmts. In this
> case we will have to calculate the value range.  We will have to reuse these
> logic in tree-vrp.

I fail to see the issue given no concrete example.

> Other option is to add another attribute in range_info_t to indicate if
> set_value_range_to_nonnegative is used in value range extraction.

Why should the result of this not be accurately represented in the lattice?

> What is your preferred solution please.

I don't know because I do not understand the problem at hand.

>>>>> I understand that the above code of mine needs to be changed but not
>>>>> convinced about the best way to do that.
>>>>>
>>>>> I can possibly re-factor extract_range_from_assignment to give me this
>>>>> information with an additional argument. Could you kindly let me know
>>>>> your
>>>>> preference.
>>>>>
>>>>>
>>>>>
>>>>>>
>>>>>> /* SSA name annotations.  */
>>>>>>
>>>>>> +  union vrp_info_type {
>>>>>> +    /* Pointer attributes used for alias analysis.  */
>>>>>> +    struct GTY ((tag ("TREE_SSA_PTR_INFO"))) ptr_info_def *ptr_info;
>>>>>> +    /* Value range attributes used for zero/sign extension
>>>>>> elimination.
>>>>>> */
>>>>>>
>>>>>> /* Value range information.  */
>>>>>>
>>>>>> +    struct GTY ((tag ("TREE_SSA_RANGE_INFO"))) range_info_def
>>>>>> *range_info;
>>>>>> +  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE
>>>>>> ((tree)&%1))"))) vrp;
>>>>>>
>>>>>> why do you need to test %1.def_stmt here?
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> I have seen some tree_ssa_name with def_stmt NULL. Thats why I added
>>>>> this.
>>>>> Is that something that should never happen.
>>>>
>>>>
>>>> It should never happen - they should have a GIMPLE_NOP.
>>>>
>>>
>>> I am seeing def_stmt of NULL for TREE_NOTHROW node.
>>> debug_tree dumps the following in this case:
>>>
>>> <ssa_name 0x2aaaabd89af8 nothrow var <var_decl 0x2aaaadb384c0 t>def_stmt
>>>
>>>      version 11 in-free-list>
>>
>>
>> This is an invalid SSA name (in-free-list) that has been released.  You
>> shouldn't look at it at all.
>
>
> This is actually happening in garbage collection. If i remove the check, I
> get the following:

Ah, ok.  Well, that shows that the field is not properly zeroed at SSA name
release time.  Or that the garbage collector visits the ptr_info (your .vrp)
even if it is NULL.  You can look at the gtype-desc.c code and the
way the callers are wrapped via gtype-desc.h.

I suspect that the right answer is to instead do

GTY ((desc (%1.ptr_info && ...)))

that is, make sure the pointer is not NULL.  Or push the union into the
pointer target instead.

Do others have a better solution?  The issue is that the descriptor for
the GT machinery is not valid if the "field" (either of the pointers in the
union) is NULL.  But then it wouldn't matter anyway.  The GTY machinery
doesn't seem to handle this special-case (all-pointers in the union).

Richard.

> make[2]: *** [_mulsc3.o] Error 1
> 0x97755f crash_signal
>         /home/kugan/work/sources/gcc-fsf/test/gcc/toplev.c:335
> 0x55f7d1 gt_ggc_mx_lang_tree_node(void*)
>         ./gt-c-c-decl.h:531
> 0x802e36 gt_ggc_mx<tree_node*>
>         /home/kugan/work/sources/gcc-fsf/test/gcc/vec.h:1152
> 0x802e36 gt_ggc_mx_vec_tree_va_gc_(void*)
>
> /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:1205
> 0x8081ed gt_ggc_mx_gimple_df(void*)
>
> /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:1066
> 0x80825f gt_ggc_mx_function
>
> /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:1280
> 0x80825f gt_ggc_mx_function(void*)
>
> /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:1272
> 0x55f692 gt_ggc_mx_lang_tree_node(void*)
>         ./gt-c-c-decl.h:389
> 0x807dd5 gt_ggc_mx_symtab_node_def(void*)
>
> /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:709
> 0x807fb0 gt_ggc_m_P15symtab_node_def4htab(void*)
>
> /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:2928
> 0x7b7915 ggc_mark_root_tab
>         /home/kugan/work/sources/gcc-fsf/test/gcc/ggc-common.c:133
> 0x7b7c60 ggc_mark_roots()
>         /home/kugan/work/sources/gcc-fsf/test/gcc/ggc-common.c:152
> 0x615669 ggc_collect()
>         /home/kugan/work/sources/gcc-fsf/test/gcc/ggc-page.c:2077
>
>
>
>
> Thanks a lot.
>
> Kugan
>
>
>> Richard.
>>
>>>> +void
>>>> +set_range_info (tree name, double_int min,
>>>> +                          double_int max, bool vr_range)
>>>>
>>>> you have some whitespace issues here (please properly use tabs)
>>>>
>>>
>>> I will change it.
>>>
>>>> +  /* Allocate if not available.  */
>>>> +  if (ri == NULL)
>>>> +    {
>>>> +      ri = ggc_alloc_cleared_range_info_def ();
>>>> +      mark_range_info_unknown (ri);
>>>>
>>>> that looks superfluous to me.
>>>>
>>>> +      SSA_NAME_RANGE_INFO (name) = ri;
>>>>
>>>> -  /* Pointer attributes used for alias analysis.  */
>>>> -  struct ptr_info_def *ptr_info;
>>>> +  /* Value range information.  */
>>>> +  union vrp_info_type {
>>>> +    /* Pointer attributes used for alias analysis.  */
>>>> +    struct GTY ((tag ("0"))) ptr_info_def *ptr_info;
>>>> +    /* Value range attributes used for zero/sign extension
>>>> elimination.  */
>>>> +    struct GTY ((tag ("1"))) range_info_def *range_info;
>>>> +  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE
>>>> ((tree)&%1))"))) vrp;
>>>>
>>>> please change vrp_info_type and vrp to other names - this is not vrp
>>>> specific info
>>>> after all, I suggest ssa_name_info_type and info.
>>>>
>>>
>>> I will change this too.
>>>>
>>>> The genric bits otherwise look ok to me, the VRP bits still look wrong
>>>> (see my
>>>> above question) and need explanation.
>>>>
>>>> Thanks,
>>>> Richard.
>>>>
>>>>>
>>>>> Thanks,
>>>>> Kugan
>>>
>>>
>>>
>>> Thanks,
>>> Kugan
>>>
>>
>

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-09  9:37               ` Richard Biener
@ 2013-09-10  5:27                 ` Kugan
  2013-09-10 13:29                   ` Richard Biener
  0 siblings, 1 reply; 38+ messages in thread
From: Kugan @ 2013-09-10  5:27 UTC (permalink / raw)
  To: Richard Biener
  Cc: Richard Biener, gcc-patches, Eric Botcazou, Ramana Radhakrishnan,
	Richard Earnshaw

On 09/09/13 19:01, Richard Biener wrote:
> On Mon, Sep 9, 2013 at 1:09 AM, Kugan <kugan.vivekanandarajah@linaro.org> wrote:
>>
>> On 06/09/13 16:16, Richard Biener wrote:
>>>
>>> On 9/3/13 2:15 PM, Kugan wrote:
>>>>
>>>> Thanks Richard for reviewing.
>>>>
>>>> On 02/09/13 22:15, Richard Biener wrote:
>>>>>
>>>>> On Wed, Jul 3, 2013 at 2:25 PM, Kugan
>>>>> <kugan.vivekanandarajah@linaro.org> wrote:
>>>>>>
>>>>>> On 17/06/13 18:33, Richard Biener wrote:
>>>>>>>
>>>>>>>
>>>>>>> On Mon, 17 Jun 2013, Kugan wrote:
>>>>>>> +/* Extract the value range of assigned exprassion for GIMPLE_ASSIGN
>>>>>>> stmt.
>>>>>>> +   If the extracted value range is valid, return true else return
>>>>>>> +   false.  */
>>>>>>> +static bool
>>
>>
>> [snip]
>>
>>
>>>>>>>
>>>>>>>       for (i = 0; i < num_vr_values; i++)
>>>>>>>         if (vr_value[i])
>>>>>>>           {
>>>>>>>             tree name = ssa_name (i);
>>>>>>>             if (POINTER_TYPE_P (name))
>>>>>>>               continue;
>>>>>>>             if (vr_value[i].type == VR_RANGE
>>>>>>>                 || vr_value[i].type == VR_ANTI_RANGE)
>>>>>>>               tree_ssa_set_value_range (name, tree_to_double_int
>>>>>>> (vr_value[i].min), tree_to_double_int (vr_value[i].max),
>>>>>>> vr_value[i].type
>>>>>>> == VR_RANGE);
>>>>>>>           }
>>>>>>>
>>>>>>
>>>>>> Thanks Richard for taking time to review it.
>>>>>>
>>>>>> I was doing something like what you are suggesting earlier but
>>>>>> noticed some
>>>>>> problems and thatÂ’s the reason why I changed.
>>>>>>
>>>>>> For example, for the following testcase from the test suite,
>>>>>>
>>>>>> unsigned long l = (unsigned long)-2;
>>>>>> unsigned short s;
>>>>>>
>>>>>> int main () {
>>>>>>      long t = l + 1;
>>>>>>      s = l;
>>>>>>      if (s != (unsigned short) -2)
>>>>>>        abort ();
>>>>>>      exit (0);
>>>>>> }
>>>>>>
>>>>>> with the following gimple stmts
>>>>>>
>>>>>> main ()
>>>>>> {
>>>>>>      short unsigned int s.1;
>>>>>>      long unsigned int l.0;
>>>>>>
>>>>>> ;;   basic block 2, loop depth 0
>>>>>> ;;    pred:       ENTRY
>>>>>>      l.0_2 = l;
>>>>>>      s.1_3 = (short unsigned int) l.0_2;
>>>>>>      s = s.1_3;
>>>>>>      if (s.1_3 != 65534)
>>>>>>        goto <bb 3>;
>>>>>>      else
>>>>>>        goto <bb 4>;
>>>>>> ;;    succ:       3
>>>>>> ;;                4
>>>>>>
>>>>>> ;;   basic block 3, loop depth 0
>>>>>> ;;    pred:       2
>>>>>>      abort ();
>>>>>> ;;    succ:
>>>>>>
>>>>>> ;;   basic block 4, loop depth 0
>>>>>> ;;    pred:       2
>>>>>>      exit (0);
>>>>>> ;;    succ:
>>>>>>
>>>>>> }
>>>>>>
>>>>>>
>>>>>>
>>>>>> has the following value range.
>>>>>>
>>>>>> l.0_2: VARYING
>>>>>> s.1_3: [0, +INF]
>>>>>>
>>>>>>
>>>>>>    From zero/sign extension point of view, the variable s.1_3 is
>>>>>> expected to
>>>>>> have a value that will overflow (or varying) as this is what is
>>>>>> assigned to
>>>>>> a smaller variable. extract_range_from_assignment initially
>>>>>> calculates the
>>>>>> value range as VARYING but later changed to [0, +INF] by
>>>>>> extract_range_basic. What I need here is the value that will be
>>>>>> assigned
>>>>>> from the rhs expression and not the value that we will have with proper
>>>>>> assignment.
>>>>>
>>>>>
>>>>> I don't understand this.  The relevant statement is
>>>>>
>>>>>      s.1_3 = (short unsigned int) l.0_2;
>>>>>
>>>>> right?  You have value-ranges for both s.1_3 and l.0_2 as above.  And
>>>>> you clearly cannot optimize the truncation away (and if you could,
>>>>> you wond't need value-range information for that fact).
>>>>>
>>>> This is true. But just by looking at the value range of s.1.3 we will
>>>> only see [0 +INF], as we are transferring directly from the lattice to
>>>> lhs its value range.
>>>>
>>>> [0, +INF] here tells us  vrp_val_is_max and it is not
>>>> is_positive_overflow_infinity (or varying). Thats why we need to get the
>>>> value range of RHS expression which will tell us the actual range. We
>>>> can then use this range and see of we can fit it to lhs type without
>>>> truncation.
>>>
>>>
>>> Well, my point is you want to look at the l.0_2 value-range for this.
>>> Storing the l.0_2 value-range for s.1_3 is wrong.
>>>
>>
>> Yes, tree SSA_NAME should have it's correct value range. But, assigning rhs
>> expression's value range is not totally wrong , it is just that it can be
>> conservative value range (please correct me if I am wrong here) in few
>> cases, as it can have wider range.
>
> If it's a sign-changing conversion it can be surely wrong.
>

It is not sign-changing conversion. Rather, when we have rhs expression 
  value which is VR_VARYING it is set to [0, +INF]


i.e, in extract_range_from_assignment, if the value range is VR_VARYING, 
follwing is done
  if (vr->type == VR_VARYING)
      extract_range_basic (vr, stmt);

In extract_range_basic (when the value range is varying), when the 
following code executes, it changes VR_VARYING to [0, +INF],

  if (INTEGRAL_TYPE_P (type)
        && gimple_stmt_nonnegative_warnv_p (stmt, &sop))
      set_value_range_to_nonnegative (vr, type,
                                      sop || stmt_overflow_infinity (stmt));

This will happen only when we have VR_VARYING for the rhs expression. 
This is wrong from zero/sign extension elimination point of view as we 
cant rely on this converted value range.


Currently I am leaving this as varying so that we can decide whether to 
eliminate the zero/sign extension. This is not completely wrong.

unsigned short s;
s.1_3 = (short unsigned int) l.0_2;
l.0_2: VARYING
s.1_3: [0, +INF]

Similarly (extracted form a testcase)

unsigned char _4;
unsigned char _2;
unsigned char _5;

   _5 = _4 + _2;
value range extracted for expression (_4 + _2) 
extract_range_from_binary_expr is VARYING and
_5 has value range [0 +INF] or [0, 255] after 
set_value_range_to_nonnegative is done.


>> I can use the rhs value range in the above case. We can also eliminate
>> redundant zero/sign extensions for gimple binary and ternary stmts. In this
>> case we will have to calculate the value range.  We will have to reuse these
>> logic in tree-vrp.
>
> I fail to see the issue given no concrete example.
>

I hope I have explained it better this time.

>> Other option is to add another attribute in range_info_t to indicate if
>> set_value_range_to_nonnegative is used in value range extraction.
>
> Why should the result of this not be accurately represented in the lattice?
>
>> What is your preferred solution please.
>
> I don't know because I do not understand the problem at hand.
>

Could you please suggest the preferred way now.

>>>>>> I understand that the above code of mine needs to be changed but not
>>>>>> convinced about the best way to do that.
>>>>>>
>>>>>> I can possibly re-factor extract_range_from_assignment to give me this
>>>>>> information with an additional argument. Could you kindly let me know
>>>>>> your
>>>>>> preference.
>>>>>>
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> /* SSA name annotations.  */
>>>>>>>
>>>>>>> +  union vrp_info_type {
>>>>>>> +    /* Pointer attributes used for alias analysis.  */
>>>>>>> +    struct GTY ((tag ("TREE_SSA_PTR_INFO"))) ptr_info_def *ptr_info;
>>>>>>> +    /* Value range attributes used for zero/sign extension
>>>>>>> elimination.
>>>>>>> */
>>>>>>>
>>>>>>> /* Value range information.  */
>>>>>>>
>>>>>>> +    struct GTY ((tag ("TREE_SSA_RANGE_INFO"))) range_info_def
>>>>>>> *range_info;
>>>>>>> +  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE
>>>>>>> ((tree)&%1))"))) vrp;
>>>>>>>
>>>>>>> why do you need to test %1.def_stmt here?
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> I have seen some tree_ssa_name with def_stmt NULL. Thats why I added
>>>>>> this.
>>>>>> Is that something that should never happen.
>>>>>
>>>>>
>>>>> It should never happen - they should have a GIMPLE_NOP.
>>>>>
>>>>
>>>> I am seeing def_stmt of NULL for TREE_NOTHROW node.
>>>> debug_tree dumps the following in this case:
>>>>
>>>> <ssa_name 0x2aaaabd89af8 nothrow var <var_decl 0x2aaaadb384c0 t>def_stmt
>>>>
>>>>       version 11 in-free-list>
>>>
>>>
>>> This is an invalid SSA name (in-free-list) that has been released.  You
>>> shouldn't look at it at all.
>>
>>
>> This is actually happening in garbage collection. If i remove the check, I
>> get the following:
>
> Ah, ok.  Well, that shows that the field is not properly zeroed at SSA name
> release time.  Or that the garbage collector visits the ptr_info (your .vrp)
> even if it is NULL.  You can look at the gtype-desc.c code and the
> way the callers are wrapped via gtype-desc.h.
>
> I suspect that the right answer is to instead do
>
> GTY ((desc (%1.ptr_info && ...)))
>
> that is, make sure the pointer is not NULL.  Or push the union into the
> pointer target instead.
>
> Do others have a better solution?  The issue is that the descriptor for
> the GT machinery is not valid if the "field" (either of the pointers in the
> union) is NULL.  But then it wouldn't matter anyway.  The GTY machinery
> doesn't seem to handle this special-case (all-pointers in the union).
>
> Richard.
>
>> make[2]: *** [_mulsc3.o] Error 1
>> 0x97755f crash_signal
>>          /home/kugan/work/sources/gcc-fsf/test/gcc/toplev.c:335
>> 0x55f7d1 gt_ggc_mx_lang_tree_node(void*)
>>          ./gt-c-c-decl.h:531
>> 0x802e36 gt_ggc_mx<tree_node*>
>>          /home/kugan/work/sources/gcc-fsf/test/gcc/vec.h:1152
>> 0x802e36 gt_ggc_mx_vec_tree_va_gc_(void*)
>>
>> /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:1205
>> 0x8081ed gt_ggc_mx_gimple_df(void*)
>>
>> /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:1066
>> 0x80825f gt_ggc_mx_function
>>
>> /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:1280
>> 0x80825f gt_ggc_mx_function(void*)
>>
>> /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:1272
>> 0x55f692 gt_ggc_mx_lang_tree_node(void*)
>>          ./gt-c-c-decl.h:389
>> 0x807dd5 gt_ggc_mx_symtab_node_def(void*)
>>
>> /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:709
>> 0x807fb0 gt_ggc_m_P15symtab_node_def4htab(void*)
>>
>> /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:2928
>> 0x7b7915 ggc_mark_root_tab
>>          /home/kugan/work/sources/gcc-fsf/test/gcc/ggc-common.c:133
>> 0x7b7c60 ggc_mark_roots()
>>          /home/kugan/work/sources/gcc-fsf/test/gcc/ggc-common.c:152
>> 0x615669 ggc_collect()
>>          /home/kugan/work/sources/gcc-fsf/test/gcc/ggc-page.c:2077
>>
>>
>>
>>
>> Thanks a lot.
>>
>> Kugan
>>
>>
>>> Richard.
>>>
>>>>> +void
>>>>> +set_range_info (tree name, double_int min,
>>>>> +                          double_int max, bool vr_range)
>>>>>
>>>>> you have some whitespace issues here (please properly use tabs)
>>>>>
>>>>
>>>> I will change it.
>>>>
>>>>> +  /* Allocate if not available.  */
>>>>> +  if (ri == NULL)
>>>>> +    {
>>>>> +      ri = ggc_alloc_cleared_range_info_def ();
>>>>> +      mark_range_info_unknown (ri);
>>>>>
>>>>> that looks superfluous to me.
>>>>>
>>>>> +      SSA_NAME_RANGE_INFO (name) = ri;
>>>>>
>>>>> -  /* Pointer attributes used for alias analysis.  */
>>>>> -  struct ptr_info_def *ptr_info;
>>>>> +  /* Value range information.  */
>>>>> +  union vrp_info_type {
>>>>> +    /* Pointer attributes used for alias analysis.  */
>>>>> +    struct GTY ((tag ("0"))) ptr_info_def *ptr_info;
>>>>> +    /* Value range attributes used for zero/sign extension
>>>>> elimination.  */
>>>>> +    struct GTY ((tag ("1"))) range_info_def *range_info;
>>>>> +  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE
>>>>> ((tree)&%1))"))) vrp;
>>>>>
>>>>> please change vrp_info_type and vrp to other names - this is not vrp
>>>>> specific info
>>>>> after all, I suggest ssa_name_info_type and info.
>>>>>
>>>>
>>>> I will change this too.
>>>>>
>>>>> The genric bits otherwise look ok to me, the VRP bits still look wrong
>>>>> (see my
>>>>> above question) and need explanation.
>>>>>
>>>>> Thanks,
>>>>> Richard.
>>>>>
>>>>>>
>>>>>> Thanks,
>>>>>> Kugan
>>>>
>>>>
>>>>
>>>> Thanks,
>>>> Kugan
>>>>
>>>
>>

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-10  5:27                 ` Kugan
@ 2013-09-10 13:29                   ` Richard Biener
  2013-09-10 13:49                     ` Jakub Jelinek
  2013-09-11  6:39                     ` Kugan
  0 siblings, 2 replies; 38+ messages in thread
From: Richard Biener @ 2013-09-10 13:29 UTC (permalink / raw)
  To: Kugan
  Cc: Richard Biener, gcc-patches, Eric Botcazou, Ramana Radhakrishnan,
	Richard Earnshaw

On Tue, 10 Sep 2013, Kugan wrote:

> On 09/09/13 19:01, Richard Biener wrote:
> > On Mon, Sep 9, 2013 at 1:09 AM, Kugan <kugan.vivekanandarajah@linaro.org>
> > wrote:
> > > 
> > > On 06/09/13 16:16, Richard Biener wrote:
> > > > 
> > > > On 9/3/13 2:15 PM, Kugan wrote:
> > > > > 
> > > > > Thanks Richard for reviewing.
> > > > > 
> > > > > On 02/09/13 22:15, Richard Biener wrote:
> > > > > > 
> > > > > > On Wed, Jul 3, 2013 at 2:25 PM, Kugan
> > > > > > <kugan.vivekanandarajah@linaro.org> wrote:
> > > > > > > 
> > > > > > > On 17/06/13 18:33, Richard Biener wrote:
> > > > > > > > 
> > > > > > > > 
> > > > > > > > On Mon, 17 Jun 2013, Kugan wrote:
> > > > > > > > +/* Extract the value range of assigned exprassion for
> > > > > > > > GIMPLE_ASSIGN
> > > > > > > > stmt.
> > > > > > > > +   If the extracted value range is valid, return true else
> > > > > > > > return
> > > > > > > > +   false.  */
> > > > > > > > +static bool
> > > 
> > > 
> > > [snip]
> > > 
> > > 
> > > > > > > > 
> > > > > > > >       for (i = 0; i < num_vr_values; i++)
> > > > > > > >         if (vr_value[i])
> > > > > > > >           {
> > > > > > > >             tree name = ssa_name (i);
> > > > > > > >             if (POINTER_TYPE_P (name))
> > > > > > > >               continue;
> > > > > > > >             if (vr_value[i].type == VR_RANGE
> > > > > > > >                 || vr_value[i].type == VR_ANTI_RANGE)
> > > > > > > >               tree_ssa_set_value_range (name, tree_to_double_int
> > > > > > > > (vr_value[i].min), tree_to_double_int (vr_value[i].max),
> > > > > > > > vr_value[i].type
> > > > > > > > == VR_RANGE);
> > > > > > > >           }
> > > > > > > > 
> > > > > > > 
> > > > > > > Thanks Richard for taking time to review it.
> > > > > > > 
> > > > > > > I was doing something like what you are suggesting earlier but
> > > > > > > noticed some
> > > > > > > problems and that?s the reason why I changed.
> > > > > > > 
> > > > > > > For example, for the following testcase from the test suite,
> > > > > > > 
> > > > > > > unsigned long l = (unsigned long)-2;
> > > > > > > unsigned short s;
> > > > > > > 
> > > > > > > int main () {
> > > > > > >      long t = l + 1;
> > > > > > >      s = l;
> > > > > > >      if (s != (unsigned short) -2)
> > > > > > >        abort ();
> > > > > > >      exit (0);
> > > > > > > }
> > > > > > > 
> > > > > > > with the following gimple stmts
> > > > > > > 
> > > > > > > main ()
> > > > > > > {
> > > > > > >      short unsigned int s.1;
> > > > > > >      long unsigned int l.0;
> > > > > > > 
> > > > > > > ;;   basic block 2, loop depth 0
> > > > > > > ;;    pred:       ENTRY
> > > > > > >      l.0_2 = l;
> > > > > > >      s.1_3 = (short unsigned int) l.0_2;
> > > > > > >      s = s.1_3;
> > > > > > >      if (s.1_3 != 65534)
> > > > > > >        goto <bb 3>;
> > > > > > >      else
> > > > > > >        goto <bb 4>;
> > > > > > > ;;    succ:       3
> > > > > > > ;;                4
> > > > > > > 
> > > > > > > ;;   basic block 3, loop depth 0
> > > > > > > ;;    pred:       2
> > > > > > >      abort ();
> > > > > > > ;;    succ:
> > > > > > > 
> > > > > > > ;;   basic block 4, loop depth 0
> > > > > > > ;;    pred:       2
> > > > > > >      exit (0);
> > > > > > > ;;    succ:
> > > > > > > 
> > > > > > > }
> > > > > > > 
> > > > > > > 
> > > > > > > 
> > > > > > > has the following value range.
> > > > > > > 
> > > > > > > l.0_2: VARYING
> > > > > > > s.1_3: [0, +INF]
> > > > > > > 
> > > > > > > 
> > > > > > >    From zero/sign extension point of view, the variable s.1_3 is
> > > > > > > expected to
> > > > > > > have a value that will overflow (or varying) as this is what is
> > > > > > > assigned to
> > > > > > > a smaller variable. extract_range_from_assignment initially
> > > > > > > calculates the
> > > > > > > value range as VARYING but later changed to [0, +INF] by
> > > > > > > extract_range_basic. What I need here is the value that will be
> > > > > > > assigned
> > > > > > > from the rhs expression and not the value that we will have with
> > > > > > > proper
> > > > > > > assignment.
> > > > > > 
> > > > > > 
> > > > > > I don't understand this.  The relevant statement is
> > > > > > 
> > > > > >      s.1_3 = (short unsigned int) l.0_2;
> > > > > > 
> > > > > > right?  You have value-ranges for both s.1_3 and l.0_2 as above.
> > > > > > And
> > > > > > you clearly cannot optimize the truncation away (and if you could,
> > > > > > you wond't need value-range information for that fact).
> > > > > > 
> > > > > This is true. But just by looking at the value range of s.1.3 we will
> > > > > only see [0 +INF], as we are transferring directly from the lattice to
> > > > > lhs its value range.
> > > > > 
> > > > > [0, +INF] here tells us  vrp_val_is_max and it is not
> > > > > is_positive_overflow_infinity (or varying). Thats why we need to get
> > > > > the
> > > > > value range of RHS expression which will tell us the actual range. We
> > > > > can then use this range and see of we can fit it to lhs type without
> > > > > truncation.
> > > > 
> > > > 
> > > > Well, my point is you want to look at the l.0_2 value-range for this.
> > > > Storing the l.0_2 value-range for s.1_3 is wrong.
> > > > 
> > > 
> > > Yes, tree SSA_NAME should have it's correct value range. But, assigning
> > > rhs
> > > expression's value range is not totally wrong , it is just that it can be
> > > conservative value range (please correct me if I am wrong here) in few
> > > cases, as it can have wider range.
> > 
> > If it's a sign-changing conversion it can be surely wrong.
> > 
> 
> It is not sign-changing conversion. Rather, when we have rhs expression  value
> which is VR_VARYING it is set to [0, +INF]
> 
> 
> i.e, in extract_range_from_assignment, if the value range is VR_VARYING,
> follwing is done
>  if (vr->type == VR_VARYING)
>      extract_range_basic (vr, stmt);
> 
> In extract_range_basic (when the value range is varying), when the following
> code executes, it changes VR_VARYING to [0, +INF],
> 
>  if (INTEGRAL_TYPE_P (type)
>        && gimple_stmt_nonnegative_warnv_p (stmt, &sop))
>      set_value_range_to_nonnegative (vr, type,
>                                      sop || stmt_overflow_infinity (stmt));
> 
> This will happen only when we have VR_VARYING for the rhs expression. This is
> wrong from zero/sign extension elimination point of view as we cant rely on
> this converted value range.
> 
> 
> Currently I am leaving this as varying so that we can decide whether to
> eliminate the zero/sign extension. This is not completely wrong.
> 
> unsigned short s;
> s.1_3 = (short unsigned int) l.0_2;
> l.0_2: VARYING
> s.1_3: [0, +INF]

Note that [0, +INF] is the same as VARYING and [-INF, +INF] and VARYING for
l.0_2 is the same as [-INF, +INF].

> Similarly (extracted form a testcase)
> 
> unsigned char _4;
> unsigned char _2;
> unsigned char _5;
> 
>   _5 = _4 + _2;
> value range extracted for expression (_4 + _2) extract_range_from_binary_expr
> is VARYING and
> _5 has value range [0 +INF] or [0, 255] after set_value_range_to_nonnegative
> is done.

See above.

> 
> > > I can use the rhs value range in the above case. We can also eliminate
> > > redundant zero/sign extensions for gimple binary and ternary stmts. In
> > > this
> > > case we will have to calculate the value range.  We will have to reuse
> > > these
> > > logic in tree-vrp.
> > 
> > I fail to see the issue given no concrete example.
> > 
> 
> I hope I have explained it better this time.

Not really.  What's the desired value-range and what's the value-range
that you get from the lattice?

> > > Other option is to add another attribute in range_info_t to indicate if
> > > set_value_range_to_nonnegative is used in value range extraction.
> > 
> > Why should the result of this not be accurately represented in the lattice?
> > 
> > > What is your preferred solution please.
> > 
> > I don't know because I do not understand the problem at hand.
> > 
> 
> Could you please suggest the preferred way now.

Use the value-range from the lattice.

Richard.

> > I suspect that the right answer is to instead do
> > 
> > GTY ((desc (%1.ptr_info && ...)))
> > 
> > that is, make sure the pointer is not NULL.  Or push the union into the
> > pointer target instead.
> > 
> > Do others have a better solution?  The issue is that the descriptor for
> > the GT machinery is not valid if the "field" (either of the pointers in the
> > union) is NULL.  But then it wouldn't matter anyway.  The GTY machinery
> > doesn't seem to handle this special-case (all-pointers in the union).

Micha just suggested

  union vrp_info_type {
    /* Pointer attributes used for alias analysis.  */
    struct GTY ((tag ("0"))) ptr_info_def *ptr_info;
    /* Value range attributes used for zero/sign extension elimination.  
*/
    struct GTY ((tag ("1"))) range_info_def *range_info;
  } GTY ((desc ("%1.typed.type ? !POINTER_TYPE_P (TREE_TYPE 
((tree)&%1)) : 2"))) vrp

that is, if TREE_TYPE is NULL (released SSA names), do not walk
either.

Richard.

> > Richard.
> > 
> > > make[2]: *** [_mulsc3.o] Error 1
> > > 0x97755f crash_signal
> > >          /home/kugan/work/sources/gcc-fsf/test/gcc/toplev.c:335
> > > 0x55f7d1 gt_ggc_mx_lang_tree_node(void*)
> > >          ./gt-c-c-decl.h:531
> > > 0x802e36 gt_ggc_mx<tree_node*>
> > >          /home/kugan/work/sources/gcc-fsf/test/gcc/vec.h:1152
> > > 0x802e36 gt_ggc_mx_vec_tree_va_gc_(void*)
> > > 
> > > /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:1205
> > > 0x8081ed gt_ggc_mx_gimple_df(void*)
> > > 
> > > /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:1066
> > > 0x80825f gt_ggc_mx_function
> > > 
> > > /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:1280
> > > 0x80825f gt_ggc_mx_function(void*)
> > > 
> > > /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:1272
> > > 0x55f692 gt_ggc_mx_lang_tree_node(void*)
> > >          ./gt-c-c-decl.h:389
> > > 0x807dd5 gt_ggc_mx_symtab_node_def(void*)
> > > 
> > > /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:709
> > > 0x807fb0 gt_ggc_m_P15symtab_node_def4htab(void*)
> > > 
> > > /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:2928
> > > 0x7b7915 ggc_mark_root_tab
> > >          /home/kugan/work/sources/gcc-fsf/test/gcc/ggc-common.c:133
> > > 0x7b7c60 ggc_mark_roots()
> > >          /home/kugan/work/sources/gcc-fsf/test/gcc/ggc-common.c:152
> > > 0x615669 ggc_collect()
> > >          /home/kugan/work/sources/gcc-fsf/test/gcc/ggc-page.c:2077
> > > 
> > > 
> > > 
> > > 
> > > Thanks a lot.
> > > 
> > > Kugan
> > > 
> > > 
> > > > Richard.
> > > > 
> > > > > > +void
> > > > > > +set_range_info (tree name, double_int min,
> > > > > > +                          double_int max, bool vr_range)
> > > > > > 
> > > > > > you have some whitespace issues here (please properly use tabs)
> > > > > > 
> > > > > 
> > > > > I will change it.
> > > > > 
> > > > > > +  /* Allocate if not available.  */
> > > > > > +  if (ri == NULL)
> > > > > > +    {
> > > > > > +      ri = ggc_alloc_cleared_range_info_def ();
> > > > > > +      mark_range_info_unknown (ri);
> > > > > > 
> > > > > > that looks superfluous to me.
> > > > > > 
> > > > > > +      SSA_NAME_RANGE_INFO (name) = ri;
> > > > > > 
> > > > > > -  /* Pointer attributes used for alias analysis.  */
> > > > > > -  struct ptr_info_def *ptr_info;
> > > > > > +  /* Value range information.  */
> > > > > > +  union vrp_info_type {
> > > > > > +    /* Pointer attributes used for alias analysis.  */
> > > > > > +    struct GTY ((tag ("0"))) ptr_info_def *ptr_info;
> > > > > > +    /* Value range attributes used for zero/sign extension
> > > > > > elimination.  */
> > > > > > +    struct GTY ((tag ("1"))) range_info_def *range_info;
> > > > > > +  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE
> > > > > > ((tree)&%1))"))) vrp;
> > > > > > 
> > > > > > please change vrp_info_type and vrp to other names - this is not vrp
> > > > > > specific info
> > > > > > after all, I suggest ssa_name_info_type and info.
> > > > > > 
> > > > > 
> > > > > I will change this too.
> > > > > > 
> > > > > > The genric bits otherwise look ok to me, the VRP bits still look
> > > > > > wrong
> > > > > > (see my
> > > > > > above question) and need explanation.
> > > > > > 
> > > > > > Thanks,
> > > > > > Richard.
> > > > > > 
> > > > > > > 
> > > > > > > Thanks,
> > > > > > > Kugan
> > > > > 
> > > > > 
> > > > > 
> > > > > Thanks,
> > > > > Kugan
> > > > > 
> > > > 
> > > 
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imend

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-10 13:29                   ` Richard Biener
@ 2013-09-10 13:49                     ` Jakub Jelinek
  2013-09-11  7:01                       ` Kugan
  2013-09-11  6:39                     ` Kugan
  1 sibling, 1 reply; 38+ messages in thread
From: Jakub Jelinek @ 2013-09-10 13:49 UTC (permalink / raw)
  To: Richard Biener
  Cc: Kugan, Richard Biener, gcc-patches, Eric Botcazou,
	Ramana Radhakrishnan, Richard Earnshaw

On Tue, Sep 10, 2013 at 03:17:50PM +0200, Richard Biener wrote:
> > unsigned short s;
> > s.1_3 = (short unsigned int) l.0_2;
> > l.0_2: VARYING
> > s.1_3: [0, +INF]
> 
> Note that [0, +INF] is the same as VARYING and [-INF, +INF] and VARYING for
> l.0_2 is the same as [-INF, +INF].

Yeah, I don't see much value in differentiating between VR_VARYING and
VR_RANGE [TYPE_MIN_VALUE, TYPE_MAX_VALUE] (perhaps a question is what to do
for types with precisions different from TYPE_MODE's bitsize, if we should
store for VARYING/UNDEFINED a range of all possible values in the mode).
Unsigned type will be always >= 0, even if it is VARYING or UNDEFINED.
What is the valid bit good for?  Is it meant just for integrals with >
2*HOST_BITS_PER_WIDE_INT precision, which we can't represent in double_int?
I'd say we just don't want to keep track on the value ranges for those.
And, do we need to distinguish between VR_RANGE and VR_ANTI_RANGE?
I mean, can't we always store the range in VR_RANGE format?  Instead of
-[3,7] we'd store [8,2] and define that if the min double_int is bigger than
max double_int, then it is [min,+infinity] merged with [-infinity,max] range
(i.e. -[max+1,min-1])?

> Micha just suggested
> 
>   union vrp_info_type {
>     /* Pointer attributes used for alias analysis.  */
>     struct GTY ((tag ("0"))) ptr_info_def *ptr_info;
>     /* Value range attributes used for zero/sign extension elimination.  
> */
>     struct GTY ((tag ("1"))) range_info_def *range_info;
>   } GTY ((desc ("%1.typed.type ? !POINTER_TYPE_P (TREE_TYPE 

Why not TREE_TYPE(&%1) here and why the (tree) cast?

	Jakub

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-10 13:29                   ` Richard Biener
  2013-09-10 13:49                     ` Jakub Jelinek
@ 2013-09-11  6:39                     ` Kugan
  1 sibling, 0 replies; 38+ messages in thread
From: Kugan @ 2013-09-11  6:39 UTC (permalink / raw)
  To: Richard Biener
  Cc: Richard Biener, gcc-patches, Eric Botcazou, Ramana Radhakrishnan,
	Richard Earnshaw

On 10/09/13 22:47, Richard Biener wrote:
> On Tue, 10 Sep 2013, Kugan wrote:
>
>> On 09/09/13 19:01, Richard Biener wrote:
>>> On Mon, Sep 9, 2013 at 1:09 AM, Kugan <kugan.vivekanandarajah@linaro.org>
>>> wrote:
>>>>
>>>> On 06/09/13 16:16, Richard Biener wrote:
>>>>>
>>>>> On 9/3/13 2:15 PM, Kugan wrote:
>>>>>>
>>>>>> Thanks Richard for reviewing.
>>>>>>
>>>>>> On 02/09/13 22:15, Richard Biener wrote:
>>>>>>>
>>>>>>> On Wed, Jul 3, 2013 at 2:25 PM, Kugan
>>>>>>> <kugan.vivekanandarajah@linaro.org> wrote:
>>>>>>>>
>>>>>>>> On 17/06/13 18:33, Richard Biener wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Mon, 17 Jun 2013, Kugan wrote:
>>>>>>>>> +/* Extract the value range of assigned exprassion for
>>>>>>>>> GIMPLE_ASSIGN
>>>>>>>>> stmt.
>>>>>>>>> +   If the extracted value range is valid, return true else
>>>>>>>>> return
>>>>>>>>> +   false.  */
>>>>>>>>> +static bool
>>>>
>>>>
>>>> [snip]
>>>>
>>>>
>>>>>>>>>
>>>>>>>>>        for (i = 0; i < num_vr_values; i++)
>>>>>>>>>          if (vr_value[i])
>>>>>>>>>            {
>>>>>>>>>              tree name = ssa_name (i);
>>>>>>>>>              if (POINTER_TYPE_P (name))
>>>>>>>>>                continue;
>>>>>>>>>              if (vr_value[i].type == VR_RANGE
>>>>>>>>>                  || vr_value[i].type == VR_ANTI_RANGE)
>>>>>>>>>                tree_ssa_set_value_range (name, tree_to_double_int
>>>>>>>>> (vr_value[i].min), tree_to_double_int (vr_value[i].max),
>>>>>>>>> vr_value[i].type
>>>>>>>>> == VR_RANGE);
>>>>>>>>>            }
>>>>>>>>>
>>>>>>>>
>>>>>>>> Thanks Richard for taking time to review it.
>>>>>>>>
>>>>>>>> I was doing something like what you are suggesting earlier but
>>>>>>>> noticed some
>>>>>>>> problems and that?s the reason why I changed.
>>>>>>>>
>>>>>>>> For example, for the following testcase from the test suite,
>>>>>>>>
>>>>>>>> unsigned long l = (unsigned long)-2;
>>>>>>>> unsigned short s;
>>>>>>>>
>>>>>>>> int main () {
>>>>>>>>       long t = l + 1;
>>>>>>>>       s = l;
>>>>>>>>       if (s != (unsigned short) -2)
>>>>>>>>         abort ();
>>>>>>>>       exit (0);
>>>>>>>> }
>>>>>>>>
>>>>>>>> with the following gimple stmts
>>>>>>>>
>>>>>>>> main ()
>>>>>>>> {
>>>>>>>>       short unsigned int s.1;
>>>>>>>>       long unsigned int l.0;
>>>>>>>>
>>>>>>>> ;;   basic block 2, loop depth 0
>>>>>>>> ;;    pred:       ENTRY
>>>>>>>>       l.0_2 = l;
>>>>>>>>       s.1_3 = (short unsigned int) l.0_2;
>>>>>>>>       s = s.1_3;
>>>>>>>>       if (s.1_3 != 65534)
>>>>>>>>         goto <bb 3>;
>>>>>>>>       else
>>>>>>>>         goto <bb 4>;
>>>>>>>> ;;    succ:       3
>>>>>>>> ;;                4
>>>>>>>>
>>>>>>>> ;;   basic block 3, loop depth 0
>>>>>>>> ;;    pred:       2
>>>>>>>>       abort ();
>>>>>>>> ;;    succ:
>>>>>>>>
>>>>>>>> ;;   basic block 4, loop depth 0
>>>>>>>> ;;    pred:       2
>>>>>>>>       exit (0);
>>>>>>>> ;;    succ:
>>>>>>>>
>>>>>>>> }
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> has the following value range.
>>>>>>>>
>>>>>>>> l.0_2: VARYING
>>>>>>>> s.1_3: [0, +INF]
>>>>>>>>
>>>>>>>>
>>>>>>>>     From zero/sign extension point of view, the variable s.1_3 is
>>>>>>>> expected to
>>>>>>>> have a value that will overflow (or varying) as this is what is
>>>>>>>> assigned to
>>>>>>>> a smaller variable. extract_range_from_assignment initially
>>>>>>>> calculates the
>>>>>>>> value range as VARYING but later changed to [0, +INF] by
>>>>>>>> extract_range_basic. What I need here is the value that will be
>>>>>>>> assigned
>>>>>>>> from the rhs expression and not the value that we will have with
>>>>>>>> proper
>>>>>>>> assignment.
>>>>>>>
>>>>>>>
>>>>>>> I don't understand this.  The relevant statement is
>>>>>>>
>>>>>>>       s.1_3 = (short unsigned int) l.0_2;
>>>>>>>
>>>>>>> right?  You have value-ranges for both s.1_3 and l.0_2 as above.
>>>>>>> And
>>>>>>> you clearly cannot optimize the truncation away (and if you could,
>>>>>>> you wond't need value-range information for that fact).
>>>>>>>
>>>>>> This is true. But just by looking at the value range of s.1.3 we will
>>>>>> only see [0 +INF], as we are transferring directly from the lattice to
>>>>>> lhs its value range.
>>>>>>
>>>>>> [0, +INF] here tells us  vrp_val_is_max and it is not
>>>>>> is_positive_overflow_infinity (or varying). Thats why we need to get
>>>>>> the
>>>>>> value range of RHS expression which will tell us the actual range. We
>>>>>> can then use this range and see of we can fit it to lhs type without
>>>>>> truncation.
>>>>>
>>>>>
>>>>> Well, my point is you want to look at the l.0_2 value-range for this.
>>>>> Storing the l.0_2 value-range for s.1_3 is wrong.
>>>>>
>>>>
>>>> Yes, tree SSA_NAME should have it's correct value range. But, assigning
>>>> rhs
>>>> expression's value range is not totally wrong , it is just that it can be
>>>> conservative value range (please correct me if I am wrong here) in few
>>>> cases, as it can have wider range.
>>>
>>> If it's a sign-changing conversion it can be surely wrong.
>>>
>>
>> It is not sign-changing conversion. Rather, when we have rhs expression  value
>> which is VR_VARYING it is set to [0, +INF]
>>
>>
>> i.e, in extract_range_from_assignment, if the value range is VR_VARYING,
>> follwing is done
>>   if (vr->type == VR_VARYING)
>>       extract_range_basic (vr, stmt);
>>
>> In extract_range_basic (when the value range is varying), when the following
>> code executes, it changes VR_VARYING to [0, +INF],
>>
>>   if (INTEGRAL_TYPE_P (type)
>>         && gimple_stmt_nonnegative_warnv_p (stmt, &sop))
>>       set_value_range_to_nonnegative (vr, type,
>>                                       sop || stmt_overflow_infinity (stmt));
>>
>> This will happen only when we have VR_VARYING for the rhs expression. This is
>> wrong from zero/sign extension elimination point of view as we cant rely on
>> this converted value range.
>>
>>
>> Currently I am leaving this as varying so that we can decide whether to
>> eliminate the zero/sign extension. This is not completely wrong.
>>
>> unsigned short s;
>> s.1_3 = (short unsigned int) l.0_2;
>> l.0_2: VARYING
>> s.1_3: [0, +INF]
>
> Note that [0, +INF] is the same as VARYING and [-INF, +INF] and VARYING for
> l.0_2 is the same as [-INF, +INF].
>

I get it now. I will all the above as varying.

>> Similarly (extracted form a testcase)
>>
>> unsigned char _4;
>> unsigned char _2;
>> unsigned char _5;
>>
>>    _5 = _4 + _2;
>> value range extracted for expression (_4 + _2) extract_range_from_binary_expr
>> is VARYING and
>> _5 has value range [0 +INF] or [0, 255] after set_value_range_to_nonnegative
>> is done.
>
> See above.
>
>>
>>>> I can use the rhs value range in the above case. We can also eliminate
>>>> redundant zero/sign extensions for gimple binary and ternary stmts. In
>>>> this
>>>> case we will have to calculate the value range.  We will have to reuse
>>>> these
>>>> logic in tree-vrp.
>>>
>>> I fail to see the issue given no concrete example.
>>>
>>
>> I hope I have explained it better this time.
>
> Not really.  What's the desired value-range and what's the value-range
> that you get from the lattice?
>
>>>> Other option is to add another attribute in range_info_t to indicate if
>>>> set_value_range_to_nonnegative is used in value range extraction.
>>>
>>> Why should the result of this not be accurately represented in the lattice?
>>>
>>>> What is your preferred solution please.
>>>
>>> I don't know because I do not understand the problem at hand.
>>>
>>
>> Could you please suggest the preferred way now.
>
> Use the value-range from the lattice.
I will do that.

>
> Richard.
>
>>> I suspect that the right answer is to instead do
>>>
>>> GTY ((desc (%1.ptr_info && ...)))
>>>
>>> that is, make sure the pointer is not NULL.  Or push the union into the
>>> pointer target instead.
>>>
>>> Do others have a better solution?  The issue is that the descriptor for
>>> the GT machinery is not valid if the "field" (either of the pointers in the
>>> union) is NULL.  But then it wouldn't matter anyway.  The GTY machinery
>>> doesn't seem to handle this special-case (all-pointers in the union).
>
> Micha just suggested
>
>    union vrp_info_type {
>      /* Pointer attributes used for alias analysis.  */
>      struct GTY ((tag ("0"))) ptr_info_def *ptr_info;
>      /* Value range attributes used for zero/sign extension elimination.
> */
>      struct GTY ((tag ("1"))) range_info_def *range_info;
>    } GTY ((desc ("%1.typed.type ? !POINTER_TYPE_P (TREE_TYPE
> ((tree)&%1)) : 2"))) vrp
>

Thanks. I will change it.


Thanks,
Kugan

> that is, if TREE_TYPE is NULL (released SSA names), do not walk
> either.
>
> Richard.
>
>>> Richard.
>>>
>>>> make[2]: *** [_mulsc3.o] Error 1
>>>> 0x97755f crash_signal
>>>>           /home/kugan/work/sources/gcc-fsf/test/gcc/toplev.c:335
>>>> 0x55f7d1 gt_ggc_mx_lang_tree_node(void*)
>>>>           ./gt-c-c-decl.h:531
>>>> 0x802e36 gt_ggc_mx<tree_node*>
>>>>           /home/kugan/work/sources/gcc-fsf/test/gcc/vec.h:1152
>>>> 0x802e36 gt_ggc_mx_vec_tree_va_gc_(void*)
>>>>
>>>> /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:1205
>>>> 0x8081ed gt_ggc_mx_gimple_df(void*)
>>>>
>>>> /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:1066
>>>> 0x80825f gt_ggc_mx_function
>>>>
>>>> /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:1280
>>>> 0x80825f gt_ggc_mx_function(void*)
>>>>
>>>> /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:1272
>>>> 0x55f692 gt_ggc_mx_lang_tree_node(void*)
>>>>           ./gt-c-c-decl.h:389
>>>> 0x807dd5 gt_ggc_mx_symtab_node_def(void*)
>>>>
>>>> /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:709
>>>> 0x807fb0 gt_ggc_m_P15symtab_node_def4htab(void*)
>>>>
>>>> /home/kugan/work/builds/gcc-fsf-test/obj-arm-none-linux-gnueabi/gcc1/gcc/gtype-desc.c:2928
>>>> 0x7b7915 ggc_mark_root_tab
>>>>           /home/kugan/work/sources/gcc-fsf/test/gcc/ggc-common.c:133
>>>> 0x7b7c60 ggc_mark_roots()
>>>>           /home/kugan/work/sources/gcc-fsf/test/gcc/ggc-common.c:152
>>>> 0x615669 ggc_collect()
>>>>           /home/kugan/work/sources/gcc-fsf/test/gcc/ggc-page.c:2077
>>>>
>>>>
>>>>
>>>>
>>>> Thanks a lot.
>>>>
>>>> Kugan
>>>>
>>>>
>>>>> Richard.
>>>>>
>>>>>>> +void
>>>>>>> +set_range_info (tree name, double_int min,
>>>>>>> +                          double_int max, bool vr_range)
>>>>>>>
>>>>>>> you have some whitespace issues here (please properly use tabs)
>>>>>>>
>>>>>>
>>>>>> I will change it.
>>>>>>
>>>>>>> +  /* Allocate if not available.  */
>>>>>>> +  if (ri == NULL)
>>>>>>> +    {
>>>>>>> +      ri = ggc_alloc_cleared_range_info_def ();
>>>>>>> +      mark_range_info_unknown (ri);
>>>>>>>
>>>>>>> that looks superfluous to me.
>>>>>>>
>>>>>>> +      SSA_NAME_RANGE_INFO (name) = ri;
>>>>>>>
>>>>>>> -  /* Pointer attributes used for alias analysis.  */
>>>>>>> -  struct ptr_info_def *ptr_info;
>>>>>>> +  /* Value range information.  */
>>>>>>> +  union vrp_info_type {
>>>>>>> +    /* Pointer attributes used for alias analysis.  */
>>>>>>> +    struct GTY ((tag ("0"))) ptr_info_def *ptr_info;
>>>>>>> +    /* Value range attributes used for zero/sign extension
>>>>>>> elimination.  */
>>>>>>> +    struct GTY ((tag ("1"))) range_info_def *range_info;
>>>>>>> +  } GTY ((desc ("%1.def_stmt && !POINTER_TYPE_P (TREE_TYPE
>>>>>>> ((tree)&%1))"))) vrp;
>>>>>>>
>>>>>>> please change vrp_info_type and vrp to other names - this is not vrp
>>>>>>> specific info
>>>>>>> after all, I suggest ssa_name_info_type and info.
>>>>>>>
>>>>>>
>>>>>> I will change this too.
>>>>>>>
>>>>>>> The genric bits otherwise look ok to me, the VRP bits still look
>>>>>>> wrong
>>>>>>> (see my
>>>>>>> above question) and need explanation.
>>>>>>>
>>>>>>> Thanks,
>>>>>>> Richard.
>>>>>>>
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Kugan
>>>>>>
>>>>>>
>>>>>>
>>>>>> Thanks,
>>>>>> Kugan
>>>>>>
>>>>>
>>>>
>>
>>
>

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-10 13:49                     ` Jakub Jelinek
@ 2013-09-11  7:01                       ` Kugan
  2013-09-11  9:11                         ` Richard Biener
  0 siblings, 1 reply; 38+ messages in thread
From: Kugan @ 2013-09-11  7:01 UTC (permalink / raw)
  To: Jakub Jelinek
  Cc: Richard Biener, Richard Biener, gcc-patches, Eric Botcazou,
	Ramana Radhakrishnan, Richard Earnshaw

Thanks Jakub for the review.

On 10/09/13 23:10, Jakub Jelinek wrote:
> On Tue, Sep 10, 2013 at 03:17:50PM +0200, Richard Biener wrote:
>>> unsigned short s;
>>> s.1_3 = (short unsigned int) l.0_2;
>>> l.0_2: VARYING
>>> s.1_3: [0, +INF]
>>
>> Note that [0, +INF] is the same as VARYING and [-INF, +INF] and VARYING for
>> l.0_2 is the same as [-INF, +INF].
>
> Yeah, I don't see much value in differentiating between VR_VARYING and
> VR_RANGE [TYPE_MIN_VALUE, TYPE_MAX_VALUE] (perhaps a question is what to do
> for types with precisions different from TYPE_MODE's bitsize, if we should
> store for VARYING/UNDEFINED a range of all possible values in the mode).
> Unsigned type will be always >= 0, even if it is VARYING or UNDEFINED.
> What is the valid bit good for?  Is it meant just for integrals with >
> 2*HOST_BITS_PER_WIDE_INT precision, which we can't represent in double_int?
> I'd say we just don't want to keep track on the value ranges for those.

Ok, I will remove the valid.

> And, do we need to distinguish between VR_RANGE and VR_ANTI_RANGE?
> I mean, can't we always store the range in VR_RANGE format?  Instead of
> -[3,7] we'd store [8,2] and define that if the min double_int is bigger than
> max double_int, then it is [min,+infinity] merged with [-infinity,max] range
> (i.e. -[max+1,min-1])?
>

Ok, I will change this too.


Thanks,
Kugan


>> Micha just suggested
>>
>>    union vrp_info_type {
>>      /* Pointer attributes used for alias analysis.  */
>>      struct GTY ((tag ("0"))) ptr_info_def *ptr_info;
>>      /* Value range attributes used for zero/sign extension elimination.
>> */
>>      struct GTY ((tag ("1"))) range_info_def *range_info;
>>    } GTY ((desc ("%1.typed.type ? !POINTER_TYPE_P (TREE_TYPE
>
> Why not TREE_TYPE(&%1) here and why the (tree) cast?
>
> 	Jakub
>

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-11  7:01                       ` Kugan
@ 2013-09-11  9:11                         ` Richard Biener
  2013-09-11  9:54                           ` Jakub Jelinek
  0 siblings, 1 reply; 38+ messages in thread
From: Richard Biener @ 2013-09-11  9:11 UTC (permalink / raw)
  To: Kugan
  Cc: Jakub Jelinek, Richard Biener, gcc-patches, Eric Botcazou,
	Ramana Radhakrishnan, Richard Earnshaw

On Wed, 11 Sep 2013, Kugan wrote:

> Thanks Jakub for the review.
> 
> On 10/09/13 23:10, Jakub Jelinek wrote:
> > On Tue, Sep 10, 2013 at 03:17:50PM +0200, Richard Biener wrote:
> > > > unsigned short s;
> > > > s.1_3 = (short unsigned int) l.0_2;
> > > > l.0_2: VARYING
> > > > s.1_3: [0, +INF]
> > > 
> > > Note that [0, +INF] is the same as VARYING and [-INF, +INF] and VARYING
> > > for
> > > l.0_2 is the same as [-INF, +INF].
> > 
> > Yeah, I don't see much value in differentiating between VR_VARYING and
> > VR_RANGE [TYPE_MIN_VALUE, TYPE_MAX_VALUE] (perhaps a question is what to do
> > for types with precisions different from TYPE_MODE's bitsize, if we should
> > store for VARYING/UNDEFINED a range of all possible values in the mode).
> > Unsigned type will be always >= 0, even if it is VARYING or UNDEFINED.
> > What is the valid bit good for?  Is it meant just for integrals with >
> > 2*HOST_BITS_PER_WIDE_INT precision, which we can't represent in double_int?
> > I'd say we just don't want to keep track on the value ranges for those.
> 
> Ok, I will remove the valid.
> 
> > And, do we need to distinguish between VR_RANGE and VR_ANTI_RANGE?
> > I mean, can't we always store the range in VR_RANGE format?  Instead of
> > -[3,7] we'd store [8,2] and define that if the min double_int is bigger than
> > max double_int, then it is [min,+infinity] merged with [-infinity,max] range
> > (i.e. -[max+1,min-1])?
> > 
> 
> Ok, I will change this too.

Make sure to add a predicate that can tell whether its an anti-range
then.

Richard.

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-11  9:11                         ` Richard Biener
@ 2013-09-11  9:54                           ` Jakub Jelinek
  2013-09-11 10:00                             ` Richard Biener
  0 siblings, 1 reply; 38+ messages in thread
From: Jakub Jelinek @ 2013-09-11  9:54 UTC (permalink / raw)
  To: Richard Biener
  Cc: Kugan, Richard Biener, gcc-patches, Eric Botcazou,
	Ramana Radhakrishnan, Richard Earnshaw

On Wed, Sep 11, 2013 at 11:02:30AM +0200, Richard Biener wrote:
> Make sure to add a predicate that can tell whether its an anti-range
> then.

Or perhaps extraction routine, that given an SSA_NAME will give you
a triplet, 
{ enum value_range_type vr_type; double_int min, max; }
For non-integral SSA_NAMEs, or SSA_NAMEs with NULL RANGE_INFO
(should include integral types with > 2 * HOST_BITS_PER_WIDE_INT
precision) will give you VR_VARYING, for the case where
min <= max VR_RANGE and otherwise decode the max > min range
into VR_ANTI_RANGE with adjusted min/max?

Then the min/max encoding of anti range would be just a more compact
way of encoding it to lower memory usage.

	Jakub

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-11  9:54                           ` Jakub Jelinek
@ 2013-09-11 10:00                             ` Richard Biener
  2013-09-13  6:17                               ` Kugan
  0 siblings, 1 reply; 38+ messages in thread
From: Richard Biener @ 2013-09-11 10:00 UTC (permalink / raw)
  To: Jakub Jelinek
  Cc: Kugan, gcc-patches, Eric Botcazou, Ramana Radhakrishnan,
	Richard Earnshaw

On Wed, 11 Sep 2013, Jakub Jelinek wrote:

> On Wed, Sep 11, 2013 at 11:02:30AM +0200, Richard Biener wrote:
> > Make sure to add a predicate that can tell whether its an anti-range
> > then.
> 
> Or perhaps extraction routine, that given an SSA_NAME will give you
> a triplet, 
> { enum value_range_type vr_type; double_int min, max; }
> For non-integral SSA_NAMEs, or SSA_NAMEs with NULL RANGE_INFO
> (should include integral types with > 2 * HOST_BITS_PER_WIDE_INT
> precision) will give you VR_VARYING, for the case where
> min <= max VR_RANGE and otherwise decode the max > min range
> into VR_ANTI_RANGE with adjusted min/max?
> 
> Then the min/max encoding of anti range would be just a more compact
> way of encoding it to lower memory usage.

Yeah, that also works.

Richard.

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-11 10:00                             ` Richard Biener
@ 2013-09-13  6:17                               ` Kugan
  2013-09-16  6:46                                 ` Kugan
  0 siblings, 1 reply; 38+ messages in thread
From: Kugan @ 2013-09-13  6:17 UTC (permalink / raw)
  To: Richard Biener, Jakub Jelinek
  Cc: gcc-patches, Eric Botcazou, Ramana Radhakrishnan, Richard Earnshaw

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


Here is the modified patch that addresses the comments form Richard and 
Jakub.

This also includes:
1. Added TDF_RANGE to dump range_info
2. Moved enum value_range_type to tree.h (Is this the right place?)

Bootstrapped and regtested for x86_64-unknown-linux-gnu and arm-none 
linux-gnueabi.

Is this Ok,

Thanks,
Kugan

+2013-09-12  Kugan Vivekanandarajah  <kuganv@linaro.org>
+
+	* cfgexpand.c (maybe_dump_rtl_for_gimple_stmt) : Add range to dump.
+	* gimple-pretty-print.c (print_double_int) : New function.
+	* gimple-pretty-print.c (dump_gimple_phi) : Dump range info.
+	* (pp_gimple_stmt_1) : Likewise.
+	* tree-ssa-alias.c (dump_alias_info) : Check pointer type.
+	* tree-ssa-copy.c (fini_copy_prop) : Check pointer type and copy
+	range info.
+	* tree-ssanames.c (make_ssa_name_fn) : Check pointer type in
+	initialize.
+	* (set_range_info) : New function.
+	* (get_range_info) : Likewise.
+	* (duplicate_ssa_name_range_info) : Likewise.
+	* (duplicate_ssa_name_fn) : Check pointer type and call correct
+	duplicate function.
+	* tree-vrp.c (vrp_finalize): Call set_range_info to upddate
+	value range of SSA_NAMEs.
+	* tree.h (SSA_NAME_PTR_INFO) : changed to access via union
+	* tree.h (SSA_NAME_RANGE_INFO) : New macro
+






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

diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index a7d9170..f3fdd49 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -1820,7 +1820,7 @@ maybe_dump_rtl_for_gimple_stmt (gimple stmt, rtx since)
     {
       fprintf (dump_file, "\n;; ");
       print_gimple_stmt (dump_file, stmt, 0,
-			 TDF_SLIM | (dump_flags & TDF_LINENO));
+			 TDF_SLIM | TDF_RANGE | (dump_flags & TDF_LINENO));
       fprintf (dump_file, "\n");
 
       print_rtl (dump_file, since ? NEXT_INSN (since) : since);
diff --git a/gcc/dumpfile.h b/gcc/dumpfile.h
index 77f5de6..354dd92 100644
--- a/gcc/dumpfile.h
+++ b/gcc/dumpfile.h
@@ -82,9 +82,10 @@ enum tree_dump_index
 #define TDF_CSELIB	(1 << 23)	/* Dump cselib details.  */
 #define TDF_SCEV	(1 << 24)	/* Dump SCEV details.  */
 #define TDF_COMMENT	(1 << 25)	/* Dump lines with prefix ";;"  */
-#define MSG_OPTIMIZED_LOCATIONS  (1 << 26)  /* -fopt-info optimized sources */
-#define MSG_MISSED_OPTIMIZATION  (1 << 27)  /* missed opportunities */
-#define MSG_NOTE                 (1 << 28)  /* general optimization info */
+#define TDF_RANGE       (1 << 26)       /* Dump range information.  */ 
+#define MSG_OPTIMIZED_LOCATIONS  (1 << 27)  /* -fopt-info optimized sources */
+#define MSG_MISSED_OPTIMIZATION  (1 << 28)  /* missed opportunities */
+#define MSG_NOTE                 (1 << 29)  /* general optimization info */
 #define MSG_ALL         (MSG_OPTIMIZED_LOCATIONS | MSG_MISSED_OPTIMIZATION \
                          | MSG_NOTE)
 
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 1d40680..af1a13d 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -1581,6 +1581,24 @@ dump_gimple_asm (pretty_printer *buffer, gimple gs, int spc, int flags)
     }
 }
 
+/* Dumps double_int CST to BUFFER.  */
+
+static void
+print_double_int (pretty_printer *buffer, double_int cst)
+{
+  tree node = double_int_to_tree (integer_type_node, cst);
+  if (TREE_INT_CST_HIGH (node) == 0)
+    pp_printf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED, TREE_INT_CST_LOW (node));
+  else if (TREE_INT_CST_HIGH (node) == -1
+           && TREE_INT_CST_LOW (node) != 0)
+    pp_printf (buffer, "-" HOST_WIDE_INT_PRINT_UNSIGNED,
+               -TREE_INT_CST_LOW (node));
+  else
+    pp_printf (buffer, "0x%" HOST_LONG_FORMAT "x%" HOST_LONG_FORMAT "x",
+               (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (node),
+               (unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (node));
+}
+
 
 /* Dump a PHI node PHI.  BUFFER, SPC and FLAGS are as in pp_gimple_stmt_1.
    The caller is responsible for calling pp_flush on BUFFER to finalize
@@ -1609,6 +1627,27 @@ dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags)
       pp_string (buffer, "# ");
     }
 
+  if ((flags & TDF_RANGE)
+      && !POINTER_TYPE_P (TREE_TYPE (lhs))
+      && SSA_NAME_RANGE_INFO (lhs))
+    {
+      double_int min, max;
+      value_range_type range_type;
+      get_range_info (lhs, min, max, range_type);
+      if (range_type == VR_VARYING)
+        pp_printf (buffer, "# RANGE  VR_VARYING");
+      else if (range_type == VR_RANGE || range_type == VR_ANTI_RANGE)
+      {
+        pp_printf (buffer, "# RANGE ");
+        pp_printf (buffer, "%s[", range_type == VR_RANGE ? "" : "~");
+        print_double_int (buffer, min);
+        pp_printf (buffer, ", ");
+        print_double_int (buffer, max);
+        pp_printf (buffer, "]");
+        newline_and_indent (buffer, spc);
+      }
+    }
+
   if (flags & TDF_RAW)
       dump_gimple_fmt (buffer, spc, flags, "%G <%T, ", phi,
                        gimple_phi_result (phi));
@@ -1911,6 +1950,32 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags)
 	}
     }
 
+  if ((flags & TDF_RANGE)
+      && gimple_has_lhs (gs))
+    {
+      tree lhs = gimple_get_lhs (gs);
+      if ((TREE_CODE (lhs) == SSA_NAME)
+          && !POINTER_TYPE_P (TREE_TYPE (lhs))
+          && SSA_NAME_RANGE_INFO (lhs))
+        {
+          double_int min, max;
+          value_range_type range_type;
+          get_range_info (lhs, min, max, range_type);
+          if (range_type == VR_VARYING)
+            pp_printf (buffer, "# RANGE  VR_VARYING");
+          else if (range_type == VR_RANGE || range_type == VR_ANTI_RANGE)
+            {
+              pp_printf (buffer, "# RANGE ");
+              pp_printf (buffer, "%s[", range_type == VR_RANGE ? "" : "~");
+              print_double_int (buffer, min);
+              pp_printf (buffer, ", ");
+              print_double_int (buffer, max);
+              pp_printf (buffer, "]");
+              newline_and_indent (buffer, spc);
+            }
+        }
+    }
+
   switch (gimple_code (gs))
     {
     case GIMPLE_ASM:
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index caa8d74..7006eab 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -147,6 +147,15 @@ struct GTY(()) ptr_info_def
   unsigned int misalign;
 };
 
+/* Value range information for SSA_NAMEs representing non-pointer variables.  */
+
+struct GTY (()) range_info_def {
+  /* Minmum for value range.  */
+  double_int min;
+  /* Maximum for value range.  */
+  double_int max;
+};
+
 
 /* It is advantageous to avoid things like life analysis for variables which
    do not need PHI nodes.  This enum describes whether or not a particular
@@ -526,6 +535,7 @@ extern tree make_ssa_name_fn (struct function *, tree, gimple);
 extern tree copy_ssa_name_fn (struct function *, tree, gimple);
 extern tree duplicate_ssa_name_fn (struct function *, tree, gimple);
 extern void duplicate_ssa_name_ptr_info (tree, struct ptr_info_def *);
+extern void duplicate_ssa_name_range_info (tree, struct range_info_def *);
 extern void release_ssa_name (tree);
 extern void release_defs (gimple);
 extern void replace_ssa_name_symbol (tree, tree);
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 2ecd139..8ccecb5 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -404,6 +404,7 @@ dump_alias_info (FILE *file)
       struct ptr_info_def *pi;
 
       if (ptr == NULL_TREE
+          || !POINTER_TYPE_P (TREE_TYPE (ptr))
 	  || SSA_NAME_IN_FREE_LIST (ptr))
 	continue;
 
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index 75ab54a..23f07e9 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -761,11 +761,19 @@ fini_copy_prop (void)
 	 of the representative to the first solution we find if
 	 it doesn't have one already.  */
       if (copy_of[i].value != var
-	  && TREE_CODE (copy_of[i].value) == SSA_NAME
-	  && POINTER_TYPE_P (TREE_TYPE (var))
-	  && SSA_NAME_PTR_INFO (var)
-	  && !SSA_NAME_PTR_INFO (copy_of[i].value))
-	duplicate_ssa_name_ptr_info (copy_of[i].value, SSA_NAME_PTR_INFO (var));
+          && TREE_CODE (copy_of[i].value) == SSA_NAME)
+        {
+          if (POINTER_TYPE_P (TREE_TYPE (var))
+              && SSA_NAME_PTR_INFO (var)
+              && !SSA_NAME_PTR_INFO (copy_of[i].value))
+            duplicate_ssa_name_ptr_info (copy_of[i].value,
+                                         SSA_NAME_PTR_INFO (var));
+          else if (!POINTER_TYPE_P (TREE_TYPE (var))
+                   && SSA_NAME_RANGE_INFO (var)
+                   && !SSA_NAME_RANGE_INFO (copy_of[i].value))
+            duplicate_ssa_name_range_info (copy_of[i].value,
+                                           SSA_NAME_RANGE_INFO (var));
+        }
     }
 
   /* Don't do DCE if SCEV is initialized.  It would destroy the scev cache.  */
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index a6af3da..6eb6271 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -151,7 +151,11 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt)
       SET_SSA_NAME_VAR_OR_IDENTIFIER (t, var);
     }
   SSA_NAME_DEF_STMT (t) = stmt;
-  SSA_NAME_PTR_INFO (t) = NULL;
+  if (POINTER_TYPE_P (TREE_TYPE (t)))
+    SSA_NAME_PTR_INFO (t) = NULL;
+  else
+    SSA_NAME_RANGE_INFO (t) = NULL;
+
   SSA_NAME_IN_FREE_LIST (t) = 0;
   SSA_NAME_IS_DEFAULT_DEF (t) = 0;
   imm = &(SSA_NAME_IMM_USE_NODE (t));
@@ -163,6 +167,64 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt)
   return t;
 }
 
+/* Store range information MIN, and MAX to tree ssa_name NAME.  */
+
+void
+set_range_info (tree name, double_int min, double_int max)
+{
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  gcc_assert (TREE_CODE (name) == SSA_NAME);
+  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
+
+  /* Allocate if not available.  */
+  if (ri == NULL)
+    {
+      ri = ggc_alloc_cleared_range_info_def ();
+      SSA_NAME_RANGE_INFO (name) = ri;
+    }
+
+  /* Set the values.  */
+  ri->min = min;
+  ri->max = max;
+}
+
+
+/* Get range information MIN, MAX and RANGE_TYPE
+   corresponding to tree ssa_name NAME.  */
+
+void
+get_range_info (tree name, double_int &min, double_int &max,
+                enum value_range_type &range_type)
+{
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  gcc_assert (TREE_CODE (name) == SSA_NAME);
+  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
+
+  /* Return VR_VARYING for SSA_NAMEs with NULL RANGE_INFO or SSA_NAMEs
+     with integral types width > 2 * HOST_BITS_PER_WIDE_INT precision.  */
+  if (!ri || (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (name)))
+              > 2 * HOST_BITS_PER_WIDE_INT))
+    {
+      range_type = VR_VARYING;
+      return;
+    }
+
+  /* If min > max, it is  VR_ANTI_RANGE.  */
+  if (ri->min.scmp (ri->max) == 1)
+    {
+      /* VR_ANTI_RANGE ~[min, max] is encoded as [max + 1, min - 1].  */
+      range_type = VR_ANTI_RANGE;
+      min = ri->max + double_int_one;
+      max = ri->min - double_int_one;
+    }
+  else
+  {
+    /* Otherwise (when min <= max), it is  VR_RANGE.  */
+    range_type = VR_RANGE;
+    min = ri->min;
+    max = ri->max;
+  }
+}
 
 /* We no longer need the SSA_NAME expression VAR, release it so that
    it may be reused.
@@ -359,6 +421,26 @@ duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info)
   SSA_NAME_PTR_INFO (name) = new_ptr_info;
 }
 
+/* Creates a duplicate of the range_info_def at RANGE_INFO for use by
+   the SSA name NAME.  */
+void
+duplicate_ssa_name_range_info (tree name, struct range_info_def *range_info)
+{
+  struct range_info_def *new_range_info;
+
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  gcc_assert (!SSA_NAME_RANGE_INFO (name));
+
+  if (!range_info)
+    return;
+
+  new_range_info = ggc_alloc_range_info_def ();
+  *new_range_info = *range_info;
+
+  SSA_NAME_RANGE_INFO (name) = new_range_info;
+}
+
+
 
 /* Creates a duplicate of a ssa name NAME tobe defined by statement STMT
    in function FN.  */
@@ -367,10 +449,20 @@ tree
 duplicate_ssa_name_fn (struct function *fn, tree name, gimple stmt)
 {
   tree new_name = copy_ssa_name_fn (fn, name, stmt);
-  struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
+  if (POINTER_TYPE_P (TREE_TYPE (name)))
+    {
+      struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
 
-  if (old_ptr_info)
-    duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+      if (old_ptr_info)
+        duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+    }
+  else
+    {
+      struct range_info_def *old_range_info = SSA_NAME_RANGE_INFO (name);
+
+      if (old_range_info)
+        duplicate_ssa_name_range_info (new_name, old_range_info);
+    }
 
   return new_name;
 }
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index ff82591..7d539f7 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -41,9 +41,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "optabs.h"
 
 
-/* Type of value ranges.  See value_range_d for a description of these
-   types.  */
-enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING };
 
 /* Range of values that can be associated with an SSA_NAME after VRP
    has executed.  */
@@ -9436,6 +9433,39 @@ vrp_finalize (void)
      the datastructures built by VRP.  */
   identify_jump_threads ();
 
+  /* Set value range to non pointer SSA_NAMEs.  */
+  for (i  = 0; i < num_vr_values; i++)
+   if (vr_value[i])
+    {
+      tree name = ssa_name (i);
+
+      if (POINTER_TYPE_P (TREE_TYPE (name))
+          || (vr_value[i]->type == VR_VARYING)
+          || (vr_value[i]->type == VR_UNDEFINED))
+        continue;
+
+      if ((TREE_CODE (vr_value[i]->min) == INTEGER_CST)
+          && (TREE_CODE (vr_value[i]->max) == INTEGER_CST))
+        {
+          if (vr_value[i]->type == VR_RANGE)
+            set_range_info (name,
+                            tree_to_double_int (vr_value[i]->min),
+                            tree_to_double_int (vr_value[i]->max));
+          else if (vr_value[i]->type == VR_ANTI_RANGE)
+            {
+              /* VR_ANTI_RANGE ~[min, max] is encoded compactly as
+                 [max + 1, min - 1] without additional attributes.
+                 When min value > max value, we know that it is
+                 VR_ANTI_RANGE; it is VR_RANGE othewise.  */
+              set_range_info (name,
+                              tree_to_double_int (vr_value[i]->max)
+                              + double_int_one,
+                              tree_to_double_int (vr_value[i]->min)
+                              - double_int_one);
+            }
+        }
+    }
+
   /* Free allocated memory.  */
   for (i = 0; i < num_vr_values; i++)
     if (vr_value[i])
diff --git a/gcc/tree.h b/gcc/tree.h
index 94f112f..6383de8 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1950,10 +1950,26 @@ struct GTY(()) tree_exp {
 
 /* Attributes for SSA_NAMEs for pointer-type variables.  */
 #define SSA_NAME_PTR_INFO(N) \
-    SSA_NAME_CHECK (N)->ssa_name.ptr_info
+   SSA_NAME_CHECK (N)->ssa_name.info.ptr_info
+
+/* Value range info Attributes for SSA_NAMEs of non pointer-type variables.  */
+#define SSA_NAME_RANGE_INFO(N) \
+    SSA_NAME_CHECK (N)->ssa_name.info.range_info
+
+
+/* Type of value ranges.  See value_range_d In tree-vrp.c for a
+   description of these types.  */
+enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING };
+
+/* Sets the value range to SSA.  */
+void set_range_info (tree ssa, double_int min, double_int max);
+/* Gets the value range from SSA.  */
+void get_range_info (tree name, double_int &min, double_int &max,
+                     enum value_range_type &range_type);
 
 /* Defined in tree-flow.h.  */
 struct ptr_info_def;
+struct range_info_def;
 
 /* Immediate use linking structure.  This structure is used for maintaining
    a doubly linked list of uses of an SSA_NAME.  */
@@ -1981,8 +1997,14 @@ struct GTY(()) tree_ssa_name {
   /* Statement that defines this SSA name.  */
   gimple def_stmt;
 
-  /* Pointer attributes used for alias analysis.  */
-  struct ptr_info_def *ptr_info;
+  /* Value range information.  */
+  union ssa_name_info_type {
+    /* Pointer attributes used for alias analysis.  */
+    struct GTY ((tag ("0"))) ptr_info_def *ptr_info;
+    /* Value range attributes used for zero/sign extension elimination.  */
+    struct GTY ((tag ("1"))) range_info_def *range_info;
+  } GTY ((desc ("%1.typed.type ?" \
+                "!POINTER_TYPE_P (TREE_TYPE ((tree)&%1)) : 2"))) info;
 
   /* Immediate uses list for this SSA_NAME.  */
   struct ssa_use_operand_d imm_uses;



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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-13  6:17                               ` Kugan
@ 2013-09-16  6:46                                 ` Kugan
  2013-09-16 14:32                                   ` Richard Biener
  0 siblings, 1 reply; 38+ messages in thread
From: Kugan @ 2013-09-16  6:46 UTC (permalink / raw)
  To: Richard Biener, Jakub Jelinek
  Cc: gcc-patches, Eric Botcazou, Ramana Radhakrishnan, Richard Earnshaw

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

Hi,

Updated the patch to the latest changes in trunk that splits tree.h. I 
also noticed an error in printing double_int and fixed it.

Is this OK?

Thanks,
Kugan


+2013-09-12  Kugan Vivekanandarajah  <kuganv@linaro.org>
+
+	* cfgexpand.c (maybe_dump_rtl_for_gimple_stmt) : Add range to dump.
+	* gimple-pretty-print.c (print_double_int) : New function.
+	* gimple-pretty-print.c (dump_gimple_phi) : Dump range info.
+	* (pp_gimple_stmt_1) : Likewise.
+	* tree-ssa-alias.c (dump_alias_info) : Check pointer type.
+	* tree-ssa-copy.c (fini_copy_prop) : Check pointer type and copy
+	range info.
+	* tree-ssanames.c (make_ssa_name_fn) : Check pointer type in
+	initialize.
+	* (set_range_info) : New function.
+	* (get_range_info) : Likewise.
+	* (duplicate_ssa_name_range_info) : Likewise.
+	* (duplicate_ssa_name_fn) : Check pointer type and call correct
+	duplicate function.
+	* tree-vrp.c (vrp_finalize): Call set_range_info to upddate
+	value range of SSA_NAMEs.
+	* tree.h (SSA_NAME_PTR_INFO) : changed to access via union
+	* tree.h (SSA_NAME_RANGE_INFO) : New macro
+



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

diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 88e48c2..302188e 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -1820,7 +1820,7 @@ maybe_dump_rtl_for_gimple_stmt (gimple stmt, rtx since)
     {
       fprintf (dump_file, "\n;; ");
       print_gimple_stmt (dump_file, stmt, 0,
-			 TDF_SLIM | (dump_flags & TDF_LINENO));
+			 TDF_SLIM | TDF_RANGE | (dump_flags & TDF_LINENO));
       fprintf (dump_file, "\n");
 
       print_rtl (dump_file, since ? NEXT_INSN (since) : since);
diff --git a/gcc/dumpfile.h b/gcc/dumpfile.h
index ddc770a..8896d89 100644
--- a/gcc/dumpfile.h
+++ b/gcc/dumpfile.h
@@ -83,9 +83,10 @@ enum tree_dump_index
 #define TDF_CSELIB	(1 << 23)	/* Dump cselib details.  */
 #define TDF_SCEV	(1 << 24)	/* Dump SCEV details.  */
 #define TDF_COMMENT	(1 << 25)	/* Dump lines with prefix ";;"  */
-#define MSG_OPTIMIZED_LOCATIONS  (1 << 26)  /* -fopt-info optimized sources */
-#define MSG_MISSED_OPTIMIZATION  (1 << 27)  /* missed opportunities */
-#define MSG_NOTE                 (1 << 28)  /* general optimization info */
+#define TDF_RANGE       (1 << 26)       /* Dump range information.  */
+#define MSG_OPTIMIZED_LOCATIONS  (1 << 27)  /* -fopt-info optimized sources */
+#define MSG_MISSED_OPTIMIZATION  (1 << 28)  /* missed opportunities */
+#define MSG_NOTE                 (1 << 29)  /* general optimization info */
 #define MSG_ALL         (MSG_OPTIMIZED_LOCATIONS | MSG_MISSED_OPTIMIZATION \
                          | MSG_NOTE)
 
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 01a1ab5..6531010 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -1600,6 +1600,25 @@ dump_gimple_asm (pretty_printer *buffer, gimple gs, int spc, int flags)
     }
 }
 
+/* Dumps double_int CST to BUFFER.  */
+
+static void
+print_double_int (pretty_printer *buffer, double_int cst)
+{
+  tree node = double_int_to_tree (integer_type_node, cst);
+  if (TREE_INT_CST_HIGH (node) == 0)
+    pp_printf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED, TREE_INT_CST_LOW (node));
+  else if (TREE_INT_CST_HIGH (node) == -1
+           && TREE_INT_CST_LOW (node) != 0)
+    pp_printf (buffer, "-" HOST_WIDE_INT_PRINT_UNSIGNED,
+               -TREE_INT_CST_LOW (node));
+  else
+    sprintf (pp_buffer (buffer)->digit_buffer,
+             HOST_WIDE_INT_PRINT_DOUBLE_HEX,
+             (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (node),
+             (unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (node));
+}
+
 
 /* Dump a PHI node PHI.  BUFFER, SPC and FLAGS are as in pp_gimple_stmt_1.
    The caller is responsible for calling pp_flush on BUFFER to finalize
@@ -1628,6 +1647,27 @@ dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags)
       pp_string (buffer, "# ");
     }
 
+  if ((flags & TDF_RANGE)
+      && !POINTER_TYPE_P (TREE_TYPE (lhs))
+      && SSA_NAME_RANGE_INFO (lhs))
+    {
+      double_int min, max;
+      value_range_type range_type;
+      get_range_info (lhs, min, max, range_type);
+      if (range_type == VR_VARYING)
+        pp_printf (buffer, "# RANGE  VR_VARYING");
+      else if (range_type == VR_RANGE || range_type == VR_ANTI_RANGE)
+      {
+        pp_printf (buffer, "# RANGE ");
+        pp_printf (buffer, "%s[", range_type == VR_RANGE ? "" : "~");
+        print_double_int (buffer, min);
+        pp_printf (buffer, ", ");
+        print_double_int (buffer, max);
+        pp_printf (buffer, "]");
+        newline_and_indent (buffer, spc);
+      }
+    }
+
   if (flags & TDF_RAW)
       dump_gimple_fmt (buffer, spc, flags, "%G <%T, ", phi,
                        gimple_phi_result (phi));
@@ -1930,6 +1970,32 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags)
 	}
     }
 
+  if ((flags & TDF_RANGE)
+      && gimple_has_lhs (gs))
+    {
+      tree lhs = gimple_get_lhs (gs);
+      if ((TREE_CODE (lhs) == SSA_NAME)
+          && !POINTER_TYPE_P (TREE_TYPE (lhs))
+          && SSA_NAME_RANGE_INFO (lhs))
+        {
+          double_int min, max;
+          value_range_type range_type;
+          get_range_info (lhs, min, max, range_type);
+          if (range_type == VR_VARYING)
+            pp_printf (buffer, "# RANGE  VR_VARYING");
+          else if (range_type == VR_RANGE || range_type == VR_ANTI_RANGE)
+            {
+              pp_printf (buffer, "# RANGE ");
+              pp_printf (buffer, "%s[", range_type == VR_RANGE ? "" : "~");
+              print_double_int (buffer, min);
+              pp_printf (buffer, ", ");
+              print_double_int (buffer, max);
+              pp_printf (buffer, "]");
+              newline_and_indent (buffer, spc);
+            }
+        }
+    }
+
   switch (gimple_code (gs))
     {
     case GIMPLE_ASM:
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index b1bc56a..30e0557 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -43,6 +43,7 @@ struct function;
 struct real_value;
 struct fixed_value;
 struct ptr_info_def;
+struct range_info_def;
 struct die_struct;
 struct pointer_set_t;
 
@@ -1041,8 +1042,14 @@ struct GTY(()) tree_ssa_name {
   /* Statement that defines this SSA name.  */
   gimple def_stmt;
 
-  /* Pointer attributes used for alias analysis.  */
-  struct ptr_info_def *ptr_info;
+  /* Value range information.  */
+  union ssa_name_info_type {
+    /* Pointer attributes used for alias analysis.  */
+    struct GTY ((tag ("0"))) ptr_info_def *ptr_info;
+    /* Value range attributes used for zero/sign extension elimination.  */
+    struct GTY ((tag ("1"))) range_info_def *range_info;
+  } GTY ((desc ("%1.typed.type ?" \
+                "!POINTER_TYPE_P (TREE_TYPE ((tree)&%1)) : 2"))) info;
 
   /* Immediate uses list for this SSA_NAME.  */
   struct ssa_use_operand_d imm_uses;
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 9c5d979..f76f1bf 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -131,6 +131,15 @@ enum need_phi_state {
   NEED_PHI_STATE_MAYBE
 };
 
+/* Value range information for SSA_NAMEs representing non-pointer variables.  */
+
+struct GTY (()) range_info_def {
+  /* Minmum for value range.  */
+  double_int min;
+  /* Maximum for value range.  */
+  double_int max;
+};
+
 
 /* Immediate use lists are used to directly access all uses for an SSA
    name and get pointers to the statement for each use.
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 9a6d5f4..0ef7401 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -404,6 +404,7 @@ dump_alias_info (FILE *file)
       struct ptr_info_def *pi;
 
       if (ptr == NULL_TREE
+          || !POINTER_TYPE_P (TREE_TYPE (ptr))
 	  || SSA_NAME_IN_FREE_LIST (ptr))
 	continue;
 
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index 3197917..25a43ff 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -767,11 +767,19 @@ fini_copy_prop (void)
 	 of the representative to the first solution we find if
 	 it doesn't have one already.  */
       if (copy_of[i].value != var
-	  && TREE_CODE (copy_of[i].value) == SSA_NAME
-	  && POINTER_TYPE_P (TREE_TYPE (var))
-	  && SSA_NAME_PTR_INFO (var)
-	  && !SSA_NAME_PTR_INFO (copy_of[i].value))
-	duplicate_ssa_name_ptr_info (copy_of[i].value, SSA_NAME_PTR_INFO (var));
+          && TREE_CODE (copy_of[i].value) == SSA_NAME)
+        {
+          if (POINTER_TYPE_P (TREE_TYPE (var))
+              && SSA_NAME_PTR_INFO (var)
+              && !SSA_NAME_PTR_INFO (copy_of[i].value))
+            duplicate_ssa_name_ptr_info (copy_of[i].value,
+                                         SSA_NAME_PTR_INFO (var));
+          else if (!POINTER_TYPE_P (TREE_TYPE (var))
+                   && SSA_NAME_RANGE_INFO (var)
+                   && !SSA_NAME_RANGE_INFO (copy_of[i].value))
+            duplicate_ssa_name_range_info (copy_of[i].value,
+                                           SSA_NAME_RANGE_INFO (var));
+        }
     }
 
   /* Don't do DCE if SCEV is initialized.  It would destroy the scev cache.  */
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index e64bd65..4489f2b 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -154,7 +154,11 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt)
       SET_SSA_NAME_VAR_OR_IDENTIFIER (t, var);
     }
   SSA_NAME_DEF_STMT (t) = stmt;
-  SSA_NAME_PTR_INFO (t) = NULL;
+  if (POINTER_TYPE_P (TREE_TYPE (t)))
+    SSA_NAME_PTR_INFO (t) = NULL;
+  else
+    SSA_NAME_RANGE_INFO (t) = NULL;
+
   SSA_NAME_IN_FREE_LIST (t) = 0;
   SSA_NAME_IS_DEFAULT_DEF (t) = 0;
   imm = &(SSA_NAME_IMM_USE_NODE (t));
@@ -166,6 +170,64 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt)
   return t;
 }
 
+/* Store range information MIN, and MAX to tree ssa_name NAME.  */
+
+void
+set_range_info (tree name, double_int min, double_int max)
+{
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  gcc_assert (TREE_CODE (name) == SSA_NAME);
+  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
+
+  /* Allocate if not available.  */
+  if (ri == NULL)
+    {
+      ri = ggc_alloc_cleared_range_info_def ();
+      SSA_NAME_RANGE_INFO (name) = ri;
+    }
+
+  /* Set the values.  */
+  ri->min = min;
+  ri->max = max;
+}
+
+
+/* Get range information MIN, MAX and RANGE_TYPE
+   corresponding to tree ssa_name NAME.  */
+
+void
+get_range_info (tree name, double_int &min, double_int &max,
+                enum value_range_type &range_type)
+{
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  gcc_assert (TREE_CODE (name) == SSA_NAME);
+  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
+
+  /* Return VR_VARYING for SSA_NAMEs with NULL RANGE_INFO or SSA_NAMEs
+     with integral types width > 2 * HOST_BITS_PER_WIDE_INT precision.  */
+  if (!ri || (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (name)))
+              > 2 * HOST_BITS_PER_WIDE_INT))
+    {
+      range_type = VR_VARYING;
+      return;
+    }
+
+  /* If min > max, it is  VR_ANTI_RANGE.  */
+  if (ri->min.scmp (ri->max) == 1)
+    {
+      /* VR_ANTI_RANGE ~[min, max] is encoded as [max + 1, min - 1].  */
+      range_type = VR_ANTI_RANGE;
+      min = ri->max + double_int_one;
+      max = ri->min - double_int_one;
+    }
+  else
+  {
+    /* Otherwise (when min <= max), it is  VR_RANGE.  */
+    range_type = VR_RANGE;
+    min = ri->min;
+    max = ri->max;
+  }
+}
 
 /* We no longer need the SSA_NAME expression VAR, release it so that
    it may be reused.
@@ -362,6 +424,26 @@ duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info)
   SSA_NAME_PTR_INFO (name) = new_ptr_info;
 }
 
+/* Creates a duplicate of the range_info_def at RANGE_INFO for use by
+   the SSA name NAME.  */
+void
+duplicate_ssa_name_range_info (tree name, struct range_info_def *range_info)
+{
+  struct range_info_def *new_range_info;
+
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  gcc_assert (!SSA_NAME_RANGE_INFO (name));
+
+  if (!range_info)
+    return;
+
+  new_range_info = ggc_alloc_range_info_def ();
+  *new_range_info = *range_info;
+
+  SSA_NAME_RANGE_INFO (name) = new_range_info;
+}
+
+
 
 /* Creates a duplicate of a ssa name NAME tobe defined by statement STMT
    in function FN.  */
@@ -370,10 +452,20 @@ tree
 duplicate_ssa_name_fn (struct function *fn, tree name, gimple stmt)
 {
   tree new_name = copy_ssa_name_fn (fn, name, stmt);
-  struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
+  if (POINTER_TYPE_P (TREE_TYPE (name)))
+    {
+      struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
 
-  if (old_ptr_info)
-    duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+      if (old_ptr_info)
+        duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+    }
+  else
+    {
+      struct range_info_def *old_range_info = SSA_NAME_RANGE_INFO (name);
+
+      if (old_range_info)
+        duplicate_ssa_name_range_info (new_name, old_range_info);
+    }
 
   return new_name;
 }
diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h
index 8cc3efd..5224bfb 100644
--- a/gcc/tree-ssanames.h
+++ b/gcc/tree-ssanames.h
@@ -71,6 +71,7 @@ extern struct ptr_info_def *get_ptr_info (tree);
 extern tree copy_ssa_name_fn (struct function *, tree, gimple);
 extern void duplicate_ssa_name_ptr_info (tree, struct ptr_info_def *);
 extern tree duplicate_ssa_name_fn (struct function *, tree, gimple);
+extern void duplicate_ssa_name_range_info (tree, struct range_info_def *);
 extern void release_defs (gimple);
 extern void replace_ssa_name_symbol (tree, tree);
 
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index ae27dc4..057abc2 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -41,9 +41,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "optabs.h"
 
 
-/* Type of value ranges.  See value_range_d for a description of these
-   types.  */
-enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING };
 
 /* Range of values that can be associated with an SSA_NAME after VRP
    has executed.  */
@@ -9452,6 +9449,39 @@ vrp_finalize (void)
      the datastructures built by VRP.  */
   identify_jump_threads ();
 
+  /* Set value range to non pointer SSA_NAMEs.  */
+  for (i  = 0; i < num_vr_values; i++)
+   if (vr_value[i])
+    {
+      tree name = ssa_name (i);
+
+      if (POINTER_TYPE_P (TREE_TYPE (name))
+          || (vr_value[i]->type == VR_VARYING)
+          || (vr_value[i]->type == VR_UNDEFINED))
+        continue;
+
+      if ((TREE_CODE (vr_value[i]->min) == INTEGER_CST)
+          && (TREE_CODE (vr_value[i]->max) == INTEGER_CST))
+        {
+          if (vr_value[i]->type == VR_RANGE)
+            set_range_info (name,
+                            tree_to_double_int (vr_value[i]->min),
+                            tree_to_double_int (vr_value[i]->max));
+          else if (vr_value[i]->type == VR_ANTI_RANGE)
+            {
+              /* VR_ANTI_RANGE ~[min, max] is encoded compactly as
+                 [max + 1, min - 1] without additional attributes.
+                 When min value > max value, we know that it is
+                 VR_ANTI_RANGE; it is VR_RANGE othewise.  */
+              set_range_info (name,
+                              tree_to_double_int (vr_value[i]->max)
+                              + double_int_one,
+                              tree_to_double_int (vr_value[i]->min)
+                              - double_int_one);
+            }
+        }
+    }
+
   /* Free allocated memory.  */
   for (i = 0; i < num_vr_values; i++)
     if (vr_value[i])
diff --git a/gcc/tree.h b/gcc/tree.h
index a263a2c..6eb7e56 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1336,7 +1336,22 @@ extern void protected_set_expr_location (tree, location_t);
 
 /* Attributes for SSA_NAMEs for pointer-type variables.  */
 #define SSA_NAME_PTR_INFO(N) \
-    SSA_NAME_CHECK (N)->ssa_name.ptr_info
+   SSA_NAME_CHECK (N)->ssa_name.info.ptr_info
+
+/* Value range info Attributes for SSA_NAMEs of non pointer-type variables.  */
+#define SSA_NAME_RANGE_INFO(N) \
+    SSA_NAME_CHECK (N)->ssa_name.info.range_info
+
+
+/* Type of value ranges.  See value_range_d In tree-vrp.c for a
+   description of these types.  */
+enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING };
+
+/* Sets the value range to SSA.  */
+void set_range_info (tree ssa, double_int min, double_int max);
+/* Gets the value range from SSA.  */
+void get_range_info (tree name, double_int &min, double_int &max,
+                     enum value_range_type &range_type);
 
 /* Return the immediate_use information for an SSA_NAME. */
 #define SSA_NAME_IMM_USE_NODE(NODE) SSA_NAME_CHECK (NODE)->ssa_name.imm_uses

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-16  6:46                                 ` Kugan
@ 2013-09-16 14:32                                   ` Richard Biener
  2013-09-18  7:24                                     ` Kugan
  2013-09-18  9:07                                     ` Richard Earnshaw
  0 siblings, 2 replies; 38+ messages in thread
From: Richard Biener @ 2013-09-16 14:32 UTC (permalink / raw)
  To: Kugan
  Cc: Jakub Jelinek, gcc-patches, Eric Botcazou, Ramana Radhakrishnan,
	Richard Earnshaw

On Mon, 16 Sep 2013, Kugan wrote:

> Hi,
> 
> Updated the patch to the latest changes in trunk that splits tree.h. I also
> noticed an error in printing double_int and fixed it.
> 
> Is this OK?

       print_gimple_stmt (dump_file, stmt, 0,
-                        TDF_SLIM | (dump_flags & TDF_LINENO));
+                        TDF_SLIM | TDF_RANGE | (dump_flags & 
TDF_LINENO));

this should be (dump_flags & (TDF_LINENO|TDF_RANGE)) do not always
dump range info.  I'd have simply re-used TDF_ALIAS (and interpret
it as SSA annotation info), adding -range in dump file modifiers
is ok with me.

+static void
+print_double_int (pretty_printer *buffer, double_int cst)
+{
+  tree node = double_int_to_tree (integer_type_node, cst);
+  if (TREE_INT_CST_HIGH (node) == 0)
+    pp_printf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED, TREE_INT_CST_LOW 
(node));
+  else if (TREE_INT_CST_HIGH (node) == -1
+           && TREE_INT_CST_LOW (node) != 0)
+    pp_printf (buffer, "-" HOST_WIDE_INT_PRINT_UNSIGNED,
+               -TREE_INT_CST_LOW (node));
+  else
+    sprintf (pp_buffer (buffer)->digit_buffer,
+             HOST_WIDE_INT_PRINT_DOUBLE_HEX,
+             (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (node),
+             (unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (node));

using sprintf here looks like a layering violation to me.  You
probably want to factor out code from the INTEGER_CST handling
of tree-pretty-print.c:dump_generic_node into a pp_double_int
function in pretty-print.[ch] instead.

@@ -1628,6 +1647,27 @@ dump_gimple_phi (pretty_printer *buffer, gimple 
phi, int spc, int flags)
       pp_string (buffer, "# ");
     }

+  if ((flags & TDF_RANGE)
+      && !POINTER_TYPE_P (TREE_TYPE (lhs))
+      && SSA_NAME_RANGE_INFO (lhs))
+    {
+      double_int min, max;
+      value_range_type range_type;

I realize the scheme is pre-existing but can you try factoring
out the dumping of SSA_NAME_PTR_INFO / SSA_NAME_RANGE_INFO into
a separate routine that can be shared by dump_gimple_phi and
pp_gimple_stmt_1?

+get_range_info (tree name, double_int &min, double_int &max,
+                enum value_range_type &range_type)
+{
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  gcc_assert (TREE_CODE (name) == SSA_NAME);
+  range_info_def *ri = SSA_NAME_RANGE_INFO (name);

the TREE_CODE (name) == SSA_NAME assert is redundant with the
tree-checking performed by SSA_NAME_RANGE_INFO.  Likewise in
the other functions.

+void
+get_range_info (tree name, double_int &min, double_int &max,
+                enum value_range_type &range_type)

I'm not sure we want to use references.  Well - first time.

+  /* If min > max, it is  VR_ANTI_RANGE.  */
+  if (ri->min.scmp (ri->max) == 1)
+    {

I think that's wrong and needs to be conditional on TYPE_UNSIGNED
of the SSA name.

+          else if (vr_value[i]->type == VR_ANTI_RANGE)
+            {
+              /* VR_ANTI_RANGE ~[min, max] is encoded compactly as
+                 [max + 1, min - 1] without additional attributes.
+                 When min value > max value, we know that it is
+                 VR_ANTI_RANGE; it is VR_RANGE othewise.  */
+              set_range_info (name,
+                              tree_to_double_int (vr_value[i]->max)
+                              + double_int_one,
+                              tree_to_double_int (vr_value[i]->min)
+                              - double_int_one);

there is a complication for when max + 1 or min - 1 overflow - those
should be non-canonical ranges I think, but double-check this
(check set_and_canonicalize_value_range).

+/* Type of value ranges.  See value_range_d In tree-vrp.c for a
+   description of these types.  */
+enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING 
};
+
+/* Sets the value range to SSA.  */
+void set_range_info (tree ssa, double_int min, double_int max);
+/* Gets the value range from SSA.  */
+void get_range_info (tree name, double_int &min, double_int &max,
+                     enum value_range_type &range_type);

put these into tree-ssanames.h please, likewise struct GTY (()) 
range_info_def - this is where the ptr-info stuff went very recently.

Thanks,
Richard.



> Thanks,
> Kugan
> 
> 
> +2013-09-12  Kugan Vivekanandarajah  <kuganv@linaro.org>
> +
> +	* cfgexpand.c (maybe_dump_rtl_for_gimple_stmt) : Add range to dump.
> +	* gimple-pretty-print.c (print_double_int) : New function.
> +	* gimple-pretty-print.c (dump_gimple_phi) : Dump range info.
> +	* (pp_gimple_stmt_1) : Likewise.
> +	* tree-ssa-alias.c (dump_alias_info) : Check pointer type.
> +	* tree-ssa-copy.c (fini_copy_prop) : Check pointer type and copy
> +	range info.
> +	* tree-ssanames.c (make_ssa_name_fn) : Check pointer type in
> +	initialize.
> +	* (set_range_info) : New function.
> +	* (get_range_info) : Likewise.
> +	* (duplicate_ssa_name_range_info) : Likewise.
> +	* (duplicate_ssa_name_fn) : Check pointer type and call correct
> +	duplicate function.
> +	* tree-vrp.c (vrp_finalize): Call set_range_info to upddate
> +	value range of SSA_NAMEs.
> +	* tree.h (SSA_NAME_PTR_INFO) : changed to access via union
> +	* tree.h (SSA_NAME_RANGE_INFO) : New macro
> +
> 
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imend

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-16 14:32                                   ` Richard Biener
@ 2013-09-18  7:24                                     ` Kugan
  2013-09-18  9:45                                       ` Richard Biener
  2013-09-18  9:07                                     ` Richard Earnshaw
  1 sibling, 1 reply; 38+ messages in thread
From: Kugan @ 2013-09-18  7:24 UTC (permalink / raw)
  To: Richard Biener
  Cc: Jakub Jelinek, gcc-patches, Ramana Radhakrishnan, Richard Earnshaw

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


Thanks Richard for the review.
On 16/09/13 23:43, Richard Biener wrote:
> On Mon, 16 Sep 2013, Kugan wrote:
>
>> Hi,
>>
>> Updated the patch to the latest changes in trunk that splits tree.h. I also
>> noticed an error in printing double_int and fixed it.
>>
>> Is this OK?
>
>         print_gimple_stmt (dump_file, stmt, 0,
> -                        TDF_SLIM | (dump_flags & TDF_LINENO));
> +                        TDF_SLIM | TDF_RANGE | (dump_flags &
> TDF_LINENO));
>
> this should be (dump_flags & (TDF_LINENO|TDF_RANGE)) do not always
> dump range info.  I'd have simply re-used TDF_ALIAS (and interpret
> it as SSA annotation info), adding -range in dump file modifiers
> is ok with me.
>
> +static void
> +print_double_int (pretty_printer *buffer, double_int cst)
> +{
> +  tree node = double_int_to_tree (integer_type_node, cst);
> +  if (TREE_INT_CST_HIGH (node) == 0)
> +    pp_printf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED, TREE_INT_CST_LOW
> (node));
> +  else if (TREE_INT_CST_HIGH (node) == -1
> +           && TREE_INT_CST_LOW (node) != 0)
> +    pp_printf (buffer, "-" HOST_WIDE_INT_PRINT_UNSIGNED,
> +               -TREE_INT_CST_LOW (node));
> +  else
> +    sprintf (pp_buffer (buffer)->digit_buffer,
> +             HOST_WIDE_INT_PRINT_DOUBLE_HEX,
> +             (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (node),
> +             (unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (node));
>
> using sprintf here looks like a layering violation to me.  You
> probably want to factor out code from the INTEGER_CST handling
> of tree-pretty-print.c:dump_generic_node into a pp_double_int
> function in pretty-print.[ch] instead.
>
> @@ -1628,6 +1647,27 @@ dump_gimple_phi (pretty_printer *buffer, gimple
> phi, int spc, int flags)
>         pp_string (buffer, "# ");
>       }
>
> +  if ((flags & TDF_RANGE)
> +      && !POINTER_TYPE_P (TREE_TYPE (lhs))
> +      && SSA_NAME_RANGE_INFO (lhs))
> +    {
> +      double_int min, max;
> +      value_range_type range_type;
>
> I realize the scheme is pre-existing but can you try factoring
> out the dumping of SSA_NAME_PTR_INFO / SSA_NAME_RANGE_INFO into
> a separate routine that can be shared by dump_gimple_phi and
> pp_gimple_stmt_1?
>
> +get_range_info (tree name, double_int &min, double_int &max,
> +                enum value_range_type &range_type)
> +{
> +  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
> +  gcc_assert (TREE_CODE (name) == SSA_NAME);
> +  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
>
> the TREE_CODE (name) == SSA_NAME assert is redundant with the
> tree-checking performed by SSA_NAME_RANGE_INFO.  Likewise in
> the other functions.
>
> +void
> +get_range_info (tree name, double_int &min, double_int &max,
> +                enum value_range_type &range_type)
>
> I'm not sure we want to use references.  Well - first time.
>
> +  /* If min > max, it is  VR_ANTI_RANGE.  */
> +  if (ri->min.scmp (ri->max) == 1)
> +    {
>
> I think that's wrong and needs to be conditional on TYPE_UNSIGNED
> of the SSA name.
>
> +          else if (vr_value[i]->type == VR_ANTI_RANGE)
> +            {
> +              /* VR_ANTI_RANGE ~[min, max] is encoded compactly as
> +                 [max + 1, min - 1] without additional attributes.
> +                 When min value > max value, we know that it is
> +                 VR_ANTI_RANGE; it is VR_RANGE othewise.  */
> +              set_range_info (name,
> +                              tree_to_double_int (vr_value[i]->max)
> +                              + double_int_one,
> +                              tree_to_double_int (vr_value[i]->min)
> +                              - double_int_one);
>
> there is a complication for when max + 1 or min - 1 overflow - those
> should be non-canonical ranges I think, but double-check this
> (check set_and_canonicalize_value_range).
>
I have now added a check for min == 0 for unsigned type. AFAIK, For 
double_int type, this is the only case we should check.

I have also made the other changes you have asked me to do. Please find 
the modified patch and ChangeLog.

Bootstrapped and regtested for x86_64-unknown-linux-gnu.  Is this OK.

Thanks,
Kugan


+2013-09-17  Kugan Vivekanandarajah  <kuganv@linaro.org>
+
+	* gimple-pretty-print.c (dump_ssaname_info) : New function.
+	* gimple-pretty-print.c (dump_gimple_phi) : Dump range info.
+	* (pp_gimple_stmt_1) : Likewise.
+	* tree-pretty-print.c (dump_intger_cst_node) : New function.
+	* (dump_generic_node) : Call dump_intger_cst_node for INTEGER_CST.
+	* tree-ssa-alias.c (dump_alias_info) : Check pointer type.
+	* tree-ssa-copy.c (fini_copy_prop) : Check pointer type and copy
+	range info.
+	* tree-ssanames.c (make_ssa_name_fn) : Check pointer type in
+	initialize.
+	* (set_range_info) : New function.
+	* (get_range_info) : Likewise.
+	* (duplicate_ssa_name_range_info) : Likewise.
+	* (duplicate_ssa_name_fn) : Check pointer type and call correct
+	duplicate function.
+	* tree-vrp.c (vrp_finalize): Call set_range_info to upddate
+	value range of SSA_NAMEs.
+	* tree.h (SSA_NAME_PTR_INFO) : changed to access via union
+	* tree.h (SSA_NAME_RANGE_INFO) : New macro
+



> +/* Type of value ranges.  See value_range_d In tree-vrp.c for a
> +   description of these types.  */
> +enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING
> };
> +
> +/* Sets the value range to SSA.  */
> +void set_range_info (tree ssa, double_int min, double_int max);
> +/* Gets the value range from SSA.  */
> +void get_range_info (tree name, double_int &min, double_int &max,
> +                     enum value_range_type &range_type);
>
> put these into tree-ssanames.h please, likewise struct GTY (())
> range_info_def - this is where the ptr-info stuff went very recently.
>
> Thanks,
> Richard.
>
>


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

diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 01a1ab5..fd36247 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -1600,23 +1600,17 @@ dump_gimple_asm (pretty_printer *buffer, gimple gs, int spc, int flags)
     }
 }
 
-
-/* Dump a PHI node PHI.  BUFFER, SPC and FLAGS are as in pp_gimple_stmt_1.
-   The caller is responsible for calling pp_flush on BUFFER to finalize
-   pretty printer.  */
+/* Dump ptr_info and range_info for NODE on pretty_printer BUFFER with
+   SPC spaces of indent.  */
 
 static void
-dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags)
+dump_ssaname_info (pretty_printer *buffer, tree node, int spc)
 {
-  size_t i;
-  tree lhs = gimple_phi_result (phi);
-
-  if (flags & TDF_ALIAS
-      && POINTER_TYPE_P (TREE_TYPE (lhs))
-      && SSA_NAME_PTR_INFO (lhs))
+  if (POINTER_TYPE_P (TREE_TYPE (node))
+      && SSA_NAME_PTR_INFO (node))
     {
       unsigned int align, misalign;
-      struct ptr_info_def *pi = SSA_NAME_PTR_INFO (lhs);
+      struct ptr_info_def *pi = SSA_NAME_PTR_INFO (node);
       pp_string (buffer, "PT = ");
       pp_points_to_solution (buffer, &pi->pt);
       newline_and_indent (buffer, spc);
@@ -1628,6 +1622,43 @@ dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags)
       pp_string (buffer, "# ");
     }
 
+  if (!POINTER_TYPE_P (TREE_TYPE (node))
+      && SSA_NAME_RANGE_INFO (node))
+    {
+      double_int min, max;
+      value_range_type range_type = get_range_info (node, &min, &max);
+
+      if (range_type == VR_VARYING)
+        pp_printf (buffer, "# RANGE  VR_VARYING");
+      else if (range_type == VR_RANGE || range_type == VR_ANTI_RANGE)
+      {
+        pp_printf (buffer, "# RANGE ");
+        pp_printf (buffer, "%s[", range_type == VR_RANGE ? "" : "~");
+        dump_intger_cst_node (buffer,
+                              double_int_to_tree (TREE_TYPE (node), min));
+        pp_printf (buffer, ", ");
+        dump_intger_cst_node (buffer,
+                              double_int_to_tree (TREE_TYPE (node), max));
+        pp_printf (buffer, "]");
+        newline_and_indent (buffer, spc);
+      }
+    }
+}
+
+
+/* Dump a PHI node PHI.  BUFFER, SPC and FLAGS are as in pp_gimple_stmt_1.
+   The caller is responsible for calling pp_flush on BUFFER to finalize
+   pretty printer.  */
+
+static void
+dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags)
+{
+  size_t i;
+  tree lhs = gimple_phi_result (phi);
+
+  if (flags & TDF_ALIAS)
+    dump_ssaname_info (buffer, lhs, spc);
+
   if (flags & TDF_RAW)
       dump_gimple_fmt (buffer, spc, flags, "%G <%T, ", phi,
                        gimple_phi_result (phi));
@@ -1908,27 +1939,9 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags)
       && gimple_has_mem_ops (gs))
     dump_gimple_mem_ops (buffer, gs, spc, flags);
 
-  if ((flags & TDF_ALIAS)
-      && gimple_has_lhs (gs))
-    {
-      tree lhs = gimple_get_lhs (gs);
-      if (TREE_CODE (lhs) == SSA_NAME
-	  && POINTER_TYPE_P (TREE_TYPE (lhs))
-	  && SSA_NAME_PTR_INFO (lhs))
-	{
-	  unsigned int align, misalign;
-	  struct ptr_info_def *pi = SSA_NAME_PTR_INFO (lhs);
-	  pp_string (buffer, "# PT = ");
-	  pp_points_to_solution (buffer, &pi->pt);
-	  newline_and_indent (buffer, spc);
-	  if (get_ptr_info_alignment (pi, &align, &misalign))
-	    {
-	      pp_printf (buffer, "# ALIGN = %u, MISALIGN = %u",
-			 align, misalign);
-	      newline_and_indent (buffer, spc);
-	    }
-	}
-    }
+  if (gimple_has_lhs (gs)
+      && (flags & TDF_ALIAS))
+    dump_ssaname_info (buffer, gimple_get_lhs (gs), spc);
 
   switch (gimple_code (gs))
     {
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 69777dc..2acc379 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -43,6 +43,7 @@ struct function;
 struct real_value;
 struct fixed_value;
 struct ptr_info_def;
+struct range_info_def;
 struct die_struct;
 struct pointer_set_t;
 
@@ -1050,8 +1051,14 @@ struct GTY(()) tree_ssa_name {
   /* Statement that defines this SSA name.  */
   gimple def_stmt;
 
-  /* Pointer attributes used for alias analysis.  */
-  struct ptr_info_def *ptr_info;
+  /* Value range information.  */
+  union ssa_name_info_type {
+    /* Pointer attributes used for alias analysis.  */
+    struct GTY ((tag ("0"))) ptr_info_def *ptr_info;
+    /* Value range attributes used for zero/sign extension elimination.  */
+    struct GTY ((tag ("1"))) range_info_def *range_info;
+  } GTY ((desc ("%1.typed.type ?" \
+                "!POINTER_TYPE_P (TREE_TYPE ((tree)&%1)) : 2"))) info;
 
   /* Immediate uses list for this SSA_NAME.  */
   struct ssa_use_operand_d imm_uses;
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index 4c04816..1b2d1d5 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -617,6 +617,62 @@ dump_block_node (pretty_printer *buffer, tree block, int spc, int flags)
     }
 }
 
+/* Dump INTEGER_CST NODE on pretty_printer BUFFER with SPC spaces of
+   indent.  FLAGS specifies details to show in the dump (see TDF_* in
+   dumpfile.h).  */
+
+void
+dump_intger_cst_node (pretty_printer *buffer, tree node)
+{
+  if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
+    {
+      /* In the case of a pointer, one may want to divide by the
+	 size of the pointed-to type.  Unfortunately, this not
+	 straightforward.  The C front-end maps expressions
+
+	 (int *) 5
+	 int *p; (p + 5)
+
+	 in such a way that the two INTEGER_CST nodes for "5" have
+	 different values but identical types.  In the latter
+	 case, the 5 is multiplied by sizeof (int) in c-common.c
+	 (pointer_int_sum) to convert it to a byte address, and
+	 yet the type of the node is left unchanged.  Argh.  What
+	 is consistent though is that the number value corresponds
+	 to bytes (UNITS) offset.
+
+         NB: Neither of the following divisors can be trivially
+         used to recover the original literal:
+
+         TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
+	 TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node)))  */
+      pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
+      pp_string (buffer, "B"); /* pseudo-unit.  */
+    }
+  else if (host_integerp (node, 0))
+    pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
+  else if (host_integerp (node, 1))
+    pp_unsigned_wide_integer (buffer, TREE_INT_CST_LOW (node));
+  else
+    {
+      tree val = node;
+      unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (val);
+      HOST_WIDE_INT high = TREE_INT_CST_HIGH (val);
+
+      if (tree_int_cst_sgn (val) < 0)
+        {
+	  pp_minus (buffer);
+	  high = ~high + !low;
+	  low = -low;
+	}
+      /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
+	 systems?  */
+      sprintf (pp_buffer (buffer)->digit_buffer,
+	       HOST_WIDE_INT_PRINT_DOUBLE_HEX,
+	       (unsigned HOST_WIDE_INT) high, low);
+      pp_string (buffer, pp_buffer (buffer)->digit_buffer);
+    }
+}
 
 /* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of
    indent.  FLAGS specifies details to show in the dump (see TDF_* in
@@ -1037,56 +1093,8 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       break;
 
     case INTEGER_CST:
-      if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
-	{
-	  /* In the case of a pointer, one may want to divide by the
-	     size of the pointed-to type.  Unfortunately, this not
-	     straightforward.  The C front-end maps expressions
-
-	     (int *) 5
-	     int *p; (p + 5)
-
-	     in such a way that the two INTEGER_CST nodes for "5" have
-	     different values but identical types.  In the latter
-	     case, the 5 is multiplied by sizeof (int) in c-common.c
-	     (pointer_int_sum) to convert it to a byte address, and
-	     yet the type of the node is left unchanged.  Argh.  What
-	     is consistent though is that the number value corresponds
-	     to bytes (UNITS) offset.
-
-             NB: Neither of the following divisors can be trivially
-             used to recover the original literal:
-
-             TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (node)))
-	     TYPE_PRECISION (TREE_TYPE (TREE_TYPE (node)))  */
-	  pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
-	  pp_string (buffer, "B"); /* pseudo-unit */
-	}
-      else if (host_integerp (node, 0))
-	pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
-      else if (host_integerp (node, 1))
-	pp_unsigned_wide_integer (buffer, TREE_INT_CST_LOW (node));
-      else
-	{
-	  tree val = node;
-	  unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (val);
-	  HOST_WIDE_INT high = TREE_INT_CST_HIGH (val);
-
-	  if (tree_int_cst_sgn (val) < 0)
-	    {
-	      pp_minus (buffer);
-	      high = ~high + !low;
-	      low = -low;
-	    }
-	  /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
-	     systems?  */
-	  sprintf (pp_buffer (buffer)->digit_buffer,
-		   HOST_WIDE_INT_PRINT_DOUBLE_HEX,
-		   (unsigned HOST_WIDE_INT) high, low);
-	  pp_string (buffer, pp_buffer (buffer)->digit_buffer);
-	}
+      dump_intger_cst_node (buffer, node);
       break;
-
     case REAL_CST:
       /* Code copied from print_node.  */
       {
diff --git a/gcc/tree-pretty-print.h b/gcc/tree-pretty-print.h
index 7da8000..bea4add 100644
--- a/gcc/tree-pretty-print.h
+++ b/gcc/tree-pretty-print.h
@@ -35,6 +35,7 @@ extern void pp_tree_identifier (pretty_printer *, tree);
 /* In tree-pretty-print.c  */
 extern void print_declaration (pretty_printer *, tree, int, int);
 extern int dump_generic_node (pretty_printer *, tree, int, int, bool);
+extern void dump_intger_cst_node (pretty_printer *buffer, tree node);
 extern void print_generic_stmt (FILE *, tree, int);
 extern void print_generic_stmt_indented (FILE *, tree, int, int);
 extern void print_generic_expr (FILE *, tree, int);
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 9a6d5f4..0ef7401 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -404,6 +404,7 @@ dump_alias_info (FILE *file)
       struct ptr_info_def *pi;
 
       if (ptr == NULL_TREE
+          || !POINTER_TYPE_P (TREE_TYPE (ptr))
 	  || SSA_NAME_IN_FREE_LIST (ptr))
 	continue;
 
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index 3197917..25a43ff 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -767,11 +767,19 @@ fini_copy_prop (void)
 	 of the representative to the first solution we find if
 	 it doesn't have one already.  */
       if (copy_of[i].value != var
-	  && TREE_CODE (copy_of[i].value) == SSA_NAME
-	  && POINTER_TYPE_P (TREE_TYPE (var))
-	  && SSA_NAME_PTR_INFO (var)
-	  && !SSA_NAME_PTR_INFO (copy_of[i].value))
-	duplicate_ssa_name_ptr_info (copy_of[i].value, SSA_NAME_PTR_INFO (var));
+          && TREE_CODE (copy_of[i].value) == SSA_NAME)
+        {
+          if (POINTER_TYPE_P (TREE_TYPE (var))
+              && SSA_NAME_PTR_INFO (var)
+              && !SSA_NAME_PTR_INFO (copy_of[i].value))
+            duplicate_ssa_name_ptr_info (copy_of[i].value,
+                                         SSA_NAME_PTR_INFO (var));
+          else if (!POINTER_TYPE_P (TREE_TYPE (var))
+                   && SSA_NAME_RANGE_INFO (var)
+                   && !SSA_NAME_RANGE_INFO (copy_of[i].value))
+            duplicate_ssa_name_range_info (copy_of[i].value,
+                                           SSA_NAME_RANGE_INFO (var));
+        }
     }
 
   /* Don't do DCE if SCEV is initialized.  It would destroy the scev cache.  */
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index e64bd65..cd19640 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -154,7 +154,11 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt)
       SET_SSA_NAME_VAR_OR_IDENTIFIER (t, var);
     }
   SSA_NAME_DEF_STMT (t) = stmt;
-  SSA_NAME_PTR_INFO (t) = NULL;
+  if (POINTER_TYPE_P (TREE_TYPE (t)))
+    SSA_NAME_PTR_INFO (t) = NULL;
+  else
+    SSA_NAME_RANGE_INFO (t) = NULL;
+
   SSA_NAME_IN_FREE_LIST (t) = 0;
   SSA_NAME_IS_DEFAULT_DEF (t) = 0;
   imm = &(SSA_NAME_IMM_USE_NODE (t));
@@ -166,6 +170,62 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt)
   return t;
 }
 
+/* Store range information MIN, and MAX to tree ssa_name NAME.  */
+
+void
+set_range_info (tree name, double_int min, double_int max)
+{
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
+
+  /* Allocate if not available.  */
+  if (ri == NULL)
+    {
+      ri = ggc_alloc_cleared_range_info_def ();
+      SSA_NAME_RANGE_INFO (name) = ri;
+    }
+
+  /* Set the values.  */
+  ri->min = min;
+  ri->max = max;
+}
+
+
+/* Gets range information MIN, MAX and returns enum value_range_type
+   corresponding to tree ssa_name NAME.  enum value_range_type returned
+   is used to determine MIN and MAX are valid values.  */
+
+enum value_range_type
+get_range_info (tree name, double_int *min, double_int *max)
+{
+  enum value_range_type range_type;
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  gcc_assert (min && max);
+  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
+
+  /* Return VR_VARYING for SSA_NAMEs with NULL RANGE_INFO or SSA_NAMEs
+     with integral types width > 2 * HOST_BITS_PER_WIDE_INT precision.  */
+  if (!ri || (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (name)))
+              > 2 * HOST_BITS_PER_WIDE_INT))
+    return VR_VARYING;
+
+  /* If min > max, it is  VR_ANTI_RANGE.  */
+  if (ri->min.cmp (ri->max, TYPE_UNSIGNED (TREE_TYPE (name))) == 1)
+    {
+      /* VR_ANTI_RANGE ~[min, max] is encoded as [max + 1, min - 1].  */
+      range_type = VR_ANTI_RANGE;
+      *min = ri->max + double_int_one;
+      *max = ri->min - double_int_one;
+    }
+  else
+  {
+    /* Otherwise (when min <= max), it is  VR_RANGE.  */
+    range_type = VR_RANGE;
+    *min = ri->min;
+    *max = ri->max;
+  }
+  return range_type;
+}
 
 /* We no longer need the SSA_NAME expression VAR, release it so that
    it may be reused.
@@ -362,6 +422,26 @@ duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info)
   SSA_NAME_PTR_INFO (name) = new_ptr_info;
 }
 
+/* Creates a duplicate of the range_info_def at RANGE_INFO for use by
+   the SSA name NAME.  */
+void
+duplicate_ssa_name_range_info (tree name, struct range_info_def *range_info)
+{
+  struct range_info_def *new_range_info;
+
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  gcc_assert (!SSA_NAME_RANGE_INFO (name));
+
+  if (!range_info)
+    return;
+
+  new_range_info = ggc_alloc_range_info_def ();
+  *new_range_info = *range_info;
+
+  SSA_NAME_RANGE_INFO (name) = new_range_info;
+}
+
+
 
 /* Creates a duplicate of a ssa name NAME tobe defined by statement STMT
    in function FN.  */
@@ -370,10 +450,20 @@ tree
 duplicate_ssa_name_fn (struct function *fn, tree name, gimple stmt)
 {
   tree new_name = copy_ssa_name_fn (fn, name, stmt);
-  struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
+  if (POINTER_TYPE_P (TREE_TYPE (name)))
+    {
+      struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
+
+      if (old_ptr_info)
+        duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+    }
+  else
+    {
+      struct range_info_def *old_range_info = SSA_NAME_RANGE_INFO (name);
 
-  if (old_ptr_info)
-    duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+      if (old_range_info)
+        duplicate_ssa_name_range_info (new_name, old_range_info);
+    }
 
   return new_name;
 }
diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h
index 8cc3efd..9a8ea14 100644
--- a/gcc/tree-ssanames.h
+++ b/gcc/tree-ssanames.h
@@ -45,6 +45,15 @@ struct GTY(()) ptr_info_def
   unsigned int misalign;
 };
 
+/* Value range information for SSA_NAMEs representing non-pointer variables.  */
+
+struct GTY (()) range_info_def {
+  /* Minmum for value range.  */
+  double_int min;
+  /* Maximum for value range.  */
+  double_int max;
+};
+
 
 #define SSANAMES(fun) (fun)->gimple_df->ssa_names
 #define MODIFIED_NORETURN_CALLS(fun) (fun)->gimple_df->modified_noreturn_calls
@@ -54,6 +63,15 @@ struct GTY(()) ptr_info_def
 #define ssa_name(i) ((*cfun->gimple_df->ssa_names)[(i)])
 
 
+/* Type of value ranges.  See value_range_d In tree-vrp.c for a
+   description of these types.  */
+enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING };
+
+/* Sets the value range to SSA.  */
+extern void set_range_info (tree ssa, double_int min, double_int max);
+/* Gets the value range from SSA.  */
+extern enum value_range_type  get_range_info (tree name, double_int *min,
+                                              double_int *max);
 extern void init_ssanames (struct function *, int);
 extern void fini_ssanames (void);
 extern void ssanames_print_statistics (void);
@@ -71,6 +89,7 @@ extern struct ptr_info_def *get_ptr_info (tree);
 extern tree copy_ssa_name_fn (struct function *, tree, gimple);
 extern void duplicate_ssa_name_ptr_info (tree, struct ptr_info_def *);
 extern tree duplicate_ssa_name_fn (struct function *, tree, gimple);
+extern void duplicate_ssa_name_range_info (tree, struct range_info_def *);
 extern void release_defs (gimple);
 extern void replace_ssa_name_symbol (tree, tree);
 
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index ae27dc4..10e5844 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -41,9 +41,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "optabs.h"
 
 
-/* Type of value ranges.  See value_range_d for a description of these
-   types.  */
-enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING };
 
 /* Range of values that can be associated with an SSA_NAME after VRP
    has executed.  */
@@ -9452,6 +9449,44 @@ vrp_finalize (void)
      the datastructures built by VRP.  */
   identify_jump_threads ();
 
+  /* Set value range to non pointer SSA_NAMEs.  */
+  for (i  = 0; i < num_vr_values; i++)
+   if (vr_value[i])
+    {
+      tree name = ssa_name (i);
+
+      if (POINTER_TYPE_P (TREE_TYPE (name))
+          || (vr_value[i]->type == VR_VARYING)
+          || (vr_value[i]->type == VR_UNDEFINED))
+        continue;
+
+      if ((TREE_CODE (vr_value[i]->min) == INTEGER_CST)
+          && (TREE_CODE (vr_value[i]->max) == INTEGER_CST))
+        {
+          if (vr_value[i]->type == VR_RANGE)
+            set_range_info (name,
+                            tree_to_double_int (vr_value[i]->min),
+                            tree_to_double_int (vr_value[i]->max));
+          else if (vr_value[i]->type == VR_ANTI_RANGE)
+            {
+              /* VR_ANTI_RANGE ~[min, max] is encoded compactly as
+                 [max + 1, min - 1] without additional attributes.
+                 When min value > max value, we know that it is
+                 VR_ANTI_RANGE; it is VR_RANGE othewise.  */
+
+	      /* Check for an empty range with minimum zero (of type
+                 unsigned) that will wraparround.  */
+              if (!(TYPE_UNSIGNED (TREE_TYPE (name))
+                  && integer_zerop (vr_value[i]->min)))
+                set_range_info (name,
+                                tree_to_double_int (vr_value[i]->max)
+                                + double_int_one,
+                                tree_to_double_int (vr_value[i]->min)
+                                - double_int_one);
+            }
+        }
+    }
+
   /* Free allocated memory.  */
   for (i = 0; i < num_vr_values; i++)
     if (vr_value[i])
diff --git a/gcc/tree.h b/gcc/tree.h
index a263a2c..fb7c057 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1336,7 +1336,11 @@ extern void protected_set_expr_location (tree, location_t);
 
 /* Attributes for SSA_NAMEs for pointer-type variables.  */
 #define SSA_NAME_PTR_INFO(N) \
-    SSA_NAME_CHECK (N)->ssa_name.ptr_info
+   SSA_NAME_CHECK (N)->ssa_name.info.ptr_info
+
+/* Value range info Attributes for SSA_NAMEs of non pointer-type variables.  */
+#define SSA_NAME_RANGE_INFO(N) \
+    SSA_NAME_CHECK (N)->ssa_name.info.range_info
 
 /* Return the immediate_use information for an SSA_NAME. */
 #define SSA_NAME_IMM_USE_NODE(NODE) SSA_NAME_CHECK (NODE)->ssa_name.imm_uses

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-16 14:32                                   ` Richard Biener
  2013-09-18  7:24                                     ` Kugan
@ 2013-09-18  9:07                                     ` Richard Earnshaw
  2013-09-18  9:12                                       ` Richard Biener
  1 sibling, 1 reply; 38+ messages in thread
From: Richard Earnshaw @ 2013-09-18  9:07 UTC (permalink / raw)
  To: Richard Biener
  Cc: Kugan, Jakub Jelinek, gcc-patches, Eric Botcazou, Ramana Radhakrishnan

On 16/09/13 15:13, Richard Biener wrote:
> +void
> +get_range_info (tree name, double_int &min, double_int &max,
> +                enum value_range_type &range_type)
> 
> I'm not sure we want to use references.  Well - first time.

Personally, I don't think we should ever allow non-const references.
Use of references means you can't tell from the source code that an
argument to a function can be modified.  It leads to confusion and makes
things harder to debug.  It can also lead to more object code bloat
because more things end up being addressable.

R.

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-18  9:07                                     ` Richard Earnshaw
@ 2013-09-18  9:12                                       ` Richard Biener
  2013-09-18  9:16                                         ` Jakub Jelinek
  0 siblings, 1 reply; 38+ messages in thread
From: Richard Biener @ 2013-09-18  9:12 UTC (permalink / raw)
  To: Richard Earnshaw
  Cc: Kugan, Jakub Jelinek, gcc-patches, Eric Botcazou, Ramana Radhakrishnan

On Wed, 18 Sep 2013, Richard Earnshaw wrote:

> On 16/09/13 15:13, Richard Biener wrote:
> > +void
> > +get_range_info (tree name, double_int &min, double_int &max,
> > +                enum value_range_type &range_type)
> > 
> > I'm not sure we want to use references.  Well - first time.
> 
> Personally, I don't think we should ever allow non-const references.
> Use of references means you can't tell from the source code that an
> argument to a function can be modified.  It leads to confusion and makes
> things harder to debug.

That's a good argument, so please make get_range_info take pointers
to min/max/range_type.

Richard.

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-18  9:12                                       ` Richard Biener
@ 2013-09-18  9:16                                         ` Jakub Jelinek
  2013-09-18  9:26                                           ` Jan Hubicka
  0 siblings, 1 reply; 38+ messages in thread
From: Jakub Jelinek @ 2013-09-18  9:16 UTC (permalink / raw)
  To: Richard Biener
  Cc: Richard Earnshaw, Kugan, gcc-patches, Eric Botcazou,
	Ramana Radhakrishnan

On Wed, Sep 18, 2013 at 10:57:57AM +0200, Richard Biener wrote:
> On Wed, 18 Sep 2013, Richard Earnshaw wrote:
> 
> > On 16/09/13 15:13, Richard Biener wrote:
> > > +void
> > > +get_range_info (tree name, double_int &min, double_int &max,
> > > +                enum value_range_type &range_type)
> > > 
> > > I'm not sure we want to use references.  Well - first time.
> > 
> > Personally, I don't think we should ever allow non-const references.
> > Use of references means you can't tell from the source code that an
> > argument to a function can be modified.  It leads to confusion and makes
> > things harder to debug.
> 
> That's a good argument, so please make get_range_info take pointers
> to min/max/range_type.

Or return range_type and just take min/max pointers?

	Jakub

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-18  9:16                                         ` Jakub Jelinek
@ 2013-09-18  9:26                                           ` Jan Hubicka
  2013-09-18 10:21                                             ` Richard Biener
  0 siblings, 1 reply; 38+ messages in thread
From: Jan Hubicka @ 2013-09-18  9:26 UTC (permalink / raw)
  To: Jakub Jelinek
  Cc: Richard Biener, Richard Earnshaw, Kugan, gcc-patches,
	Eric Botcazou, Ramana Radhakrishnan

> On Wed, Sep 18, 2013 at 10:57:57AM +0200, Richard Biener wrote:
> > On Wed, 18 Sep 2013, Richard Earnshaw wrote:
> > 
> > > On 16/09/13 15:13, Richard Biener wrote:
> > > > +void
> > > > +get_range_info (tree name, double_int &min, double_int &max,
> > > > +                enum value_range_type &range_type)
> > > > 
> > > > I'm not sure we want to use references.  Well - first time.
> > > 
> > > Personally, I don't think we should ever allow non-const references.
> > > Use of references means you can't tell from the source code that an
> > > argument to a function can be modified.  It leads to confusion and makes
> > > things harder to debug.

I use non-const references in ipa-devirt code and speculative indirect call removal.
I am not thrilled by them, just it seems common in C++ source bases.  If we don't want
them, i will remove these (they are used on two or three places, so it is  easy)

Honza
> > 
> > That's a good argument, so please make get_range_info take pointers
> > to min/max/range_type.
> 
> Or return range_type and just take min/max pointers?
> 
> 	Jakub

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-18  7:24                                     ` Kugan
@ 2013-09-18  9:45                                       ` Richard Biener
  2013-09-19  7:25                                         ` Kugan
  0 siblings, 1 reply; 38+ messages in thread
From: Richard Biener @ 2013-09-18  9:45 UTC (permalink / raw)
  To: Kugan; +Cc: Jakub Jelinek, gcc-patches, Ramana Radhakrishnan, Richard Earnshaw

On Wed, 18 Sep 2013, Kugan wrote:

> 
> Thanks Richard for the review.
> On 16/09/13 23:43, Richard Biener wrote:
> > On Mon, 16 Sep 2013, Kugan wrote:
> > 
> > > Hi,
> > > 
> > > Updated the patch to the latest changes in trunk that splits tree.h. I
> > > also
> > > noticed an error in printing double_int and fixed it.
> > > 
> > > Is this OK?
> > 
> >         print_gimple_stmt (dump_file, stmt, 0,
> > -                        TDF_SLIM | (dump_flags & TDF_LINENO));
> > +                        TDF_SLIM | TDF_RANGE | (dump_flags &
> > TDF_LINENO));
> > 
> > this should be (dump_flags & (TDF_LINENO|TDF_RANGE)) do not always
> > dump range info.  I'd have simply re-used TDF_ALIAS (and interpret
> > it as SSA annotation info), adding -range in dump file modifiers
> > is ok with me.
> > 
> > +static void
> > +print_double_int (pretty_printer *buffer, double_int cst)
> > +{
> > +  tree node = double_int_to_tree (integer_type_node, cst);
> > +  if (TREE_INT_CST_HIGH (node) == 0)
> > +    pp_printf (buffer, HOST_WIDE_INT_PRINT_UNSIGNED, TREE_INT_CST_LOW
> > (node));
> > +  else if (TREE_INT_CST_HIGH (node) == -1
> > +           && TREE_INT_CST_LOW (node) != 0)
> > +    pp_printf (buffer, "-" HOST_WIDE_INT_PRINT_UNSIGNED,
> > +               -TREE_INT_CST_LOW (node));
> > +  else
> > +    sprintf (pp_buffer (buffer)->digit_buffer,
> > +             HOST_WIDE_INT_PRINT_DOUBLE_HEX,
> > +             (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (node),
> > +             (unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (node));
> > 
> > using sprintf here looks like a layering violation to me.  You
> > probably want to factor out code from the INTEGER_CST handling
> > of tree-pretty-print.c:dump_generic_node into a pp_double_int
> > function in pretty-print.[ch] instead.
> > 
> > @@ -1628,6 +1647,27 @@ dump_gimple_phi (pretty_printer *buffer, gimple
> > phi, int spc, int flags)
> >         pp_string (buffer, "# ");
> >       }
> > 
> > +  if ((flags & TDF_RANGE)
> > +      && !POINTER_TYPE_P (TREE_TYPE (lhs))
> > +      && SSA_NAME_RANGE_INFO (lhs))
> > +    {
> > +      double_int min, max;
> > +      value_range_type range_type;
> > 
> > I realize the scheme is pre-existing but can you try factoring
> > out the dumping of SSA_NAME_PTR_INFO / SSA_NAME_RANGE_INFO into
> > a separate routine that can be shared by dump_gimple_phi and
> > pp_gimple_stmt_1?
> > 
> > +get_range_info (tree name, double_int &min, double_int &max,
> > +                enum value_range_type &range_type)
> > +{
> > +  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
> > +  gcc_assert (TREE_CODE (name) == SSA_NAME);
> > +  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
> > 
> > the TREE_CODE (name) == SSA_NAME assert is redundant with the
> > tree-checking performed by SSA_NAME_RANGE_INFO.  Likewise in
> > the other functions.
> > 
> > +void
> > +get_range_info (tree name, double_int &min, double_int &max,
> > +                enum value_range_type &range_type)
> > 
> > I'm not sure we want to use references.  Well - first time.
> > 
> > +  /* If min > max, it is  VR_ANTI_RANGE.  */
> > +  if (ri->min.scmp (ri->max) == 1)
> > +    {
> > 
> > I think that's wrong and needs to be conditional on TYPE_UNSIGNED
> > of the SSA name.
> > 
> > +          else if (vr_value[i]->type == VR_ANTI_RANGE)
> > +            {
> > +              /* VR_ANTI_RANGE ~[min, max] is encoded compactly as
> > +                 [max + 1, min - 1] without additional attributes.
> > +                 When min value > max value, we know that it is
> > +                 VR_ANTI_RANGE; it is VR_RANGE othewise.  */
> > +              set_range_info (name,
> > +                              tree_to_double_int (vr_value[i]->max)
> > +                              + double_int_one,
> > +                              tree_to_double_int (vr_value[i]->min)
> > +                              - double_int_one);
> > 
> > there is a complication for when max + 1 or min - 1 overflow - those
> > should be non-canonical ranges I think, but double-check this
> > (check set_and_canonicalize_value_range).
> > 
> I have now added a check for min == 0 for unsigned type. AFAIK, For double_int
> type, this is the only case we should check.
> 
> I have also made the other changes you have asked me to do. Please find the
> modified patch and ChangeLog.
> 
> Bootstrapped and regtested for x86_64-unknown-linux-gnu.  Is this OK.
> 
> Thanks,
> Kugan
> 
> 
> +2013-09-17  Kugan Vivekanandarajah  <kuganv@linaro.org>
> +
> +	* gimple-pretty-print.c (dump_ssaname_info) : New function.
> +	* gimple-pretty-print.c (dump_gimple_phi) : Dump range info.
> +	* (pp_gimple_stmt_1) : Likewise.

ChangeLog should be formated

	* gimple-pretty-print.c (dump_ssaname_info): New function.
	(dump_gimple_phi): Call it.
	(pp_gimple_stmt_1: Likewise.
	* tree-pretty-print.c (dump_intger_cst_node): New function.
...


+        pp_printf (buffer, "# RANGE ");
+        pp_printf (buffer, "%s[", range_type == VR_RANGE ? "" : "~");
+        dump_intger_cst_node (buffer,
+                              double_int_to_tree (TREE_TYPE (node), 
min));

I was asking for a pp_double_int, not a dump_integer_cst_node function
as now you are creating a tree node in GC memory just to dump its
contents ...  pp_double_int needs to be passed information on the
signedness of the value.  It would roughly look like

pp_double_int (pretty_printer *pp, double_int d, bool uns)
{
  if (d.fits_shwi ())
    pp_wide_integer (pp, d.low);
  else if (d.fits_uhwi ())
    pp_unsigned_wide_integer (pp, d.low);
  else
    {
       unsigned HOST_WIDE_INT low = d.low;
       HOST_WIDE_INT high = d.high;
          if (!uns && d.is_negative ())
            {
              pp_minus (pp);
              high = ~high + !low;
              low = -low;
            }
          /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
             systems?  */
          sprintf (pp_buffer (pp)->digit_buffer,
                   HOST_WIDE_INT_PRINT_DOUBLE_HEX,
                   (unsigned HOST_WIDE_INT) high, low);
          pp_string (pp, pp_buffer (pp)->digit_buffer);
    }
}

and the INTEGER_CST case would use it like

    if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
      ...
    else
      pp_double_int (buffer, tree_to_double_int (node),
	             TYPE_UNSIGNED (TREE_TYPE (node)));


+enum value_range_type
+get_range_info (tree name, double_int *min, double_int *max)
+{

ah, I see you have already made an appropriate change here.

+             /* Check for an empty range with minimum zero (of type
+                 unsigned) that will wraparround.  */
+              if (!(TYPE_UNSIGNED (TREE_TYPE (name))
+                  && integer_zerop (vr_value[i]->min)))
+                set_range_info (name,
+                                tree_to_double_int (vr_value[i]->max)
+                                + double_int_one,
+                                tree_to_double_int (vr_value[i]->min)
+                                - double_int_one);

Yeah, I think ~[0,0] is the only anti-range that can be represented as
range that we keep.  So maybe

		if (TYPE_UNSIGNED (TREE_TYPE (name))
		    && integer_zerop (vr_value[i]->min)
                    && integer_zerop (vr_value[i]->max))
                  set_range_info (name,
                                  double_int_one,
                                  double_int::max_value
				  (TYPE_PRECISION (TREE_TYPE (name)), true));
		else
                  set_range_info (name,
+                                tree_to_double_int (vr_value[i]->max)
+                                + double_int_one,
+                                tree_to_double_int (vr_value[i]->min)
+                                - double_int_one);

to preserve ~[0,0] which looks like an important case when for example
looking at a divisor in a division.

Ok with those changes.

Thanks,
Richard.
k

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-18  9:26                                           ` Jan Hubicka
@ 2013-09-18 10:21                                             ` Richard Biener
  0 siblings, 0 replies; 38+ messages in thread
From: Richard Biener @ 2013-09-18 10:21 UTC (permalink / raw)
  To: Jan Hubicka
  Cc: Jakub Jelinek, Richard Earnshaw, Kugan, gcc-patches,
	Eric Botcazou, Ramana Radhakrishnan

On Wed, 18 Sep 2013, Jan Hubicka wrote:

> > On Wed, Sep 18, 2013 at 10:57:57AM +0200, Richard Biener wrote:
> > > On Wed, 18 Sep 2013, Richard Earnshaw wrote:
> > > 
> > > > On 16/09/13 15:13, Richard Biener wrote:
> > > > > +void
> > > > > +get_range_info (tree name, double_int &min, double_int &max,
> > > > > +                enum value_range_type &range_type)
> > > > > 
> > > > > I'm not sure we want to use references.  Well - first time.
> > > > 
> > > > Personally, I don't think we should ever allow non-const references.
> > > > Use of references means you can't tell from the source code that an
> > > > argument to a function can be modified.  It leads to confusion and makes
> > > > things harder to debug.
> 
> I use non-const references in ipa-devirt code and speculative indirect call removal.
> I am not thrilled by them, just it seems common in C++ source bases.  If we don't want
> them, i will remove these (they are used on two or three places, so it is  easy)

Yeah, I think we should amend the coding conventions appropriately.

Richard.

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-18  9:45                                       ` Richard Biener
@ 2013-09-19  7:25                                         ` Kugan
  2013-09-23 11:39                                           ` Richard Biener
  0 siblings, 1 reply; 38+ messages in thread
From: Kugan @ 2013-09-19  7:25 UTC (permalink / raw)
  To: Richard Biener
  Cc: Jakub Jelinek, gcc-patches, Ramana Radhakrishnan, Richard Earnshaw

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

Thanks Richard for the review.

On 18/09/13 18:55, Richard Biener wrote:
> On Wed, 18 Sep 2013, Kugan wrote:
>
>>
>> Thanks Richard for the review.
>> On 16/09/13 23:43, Richard Biener wrote:
>>> On Mon, 16 Sep 2013, Kugan wrote:
>>>

[Snip]

>>
>> +2013-09-17  Kugan Vivekanandarajah  <kuganv@linaro.org>
>> +
>> +	* gimple-pretty-print.c (dump_ssaname_info) : New function.
>> +	* gimple-pretty-print.c (dump_gimple_phi) : Dump range info.
>> +	* (pp_gimple_stmt_1) : Likewise.
>
> ChangeLog should be formated
>
> 	* gimple-pretty-print.c (dump_ssaname_info): New function.
> 	(dump_gimple_phi): Call it.
> 	(pp_gimple_stmt_1: Likewise.
> 	* tree-pretty-print.c (dump_intger_cst_node): New function.
> ...
>
>
> +        pp_printf (buffer, "# RANGE ");
> +        pp_printf (buffer, "%s[", range_type == VR_RANGE ? "" : "~");
> +        dump_intger_cst_node (buffer,
> +                              double_int_to_tree (TREE_TYPE (node),
> min));
>
> I was asking for a pp_double_int, not a dump_integer_cst_node function
> as now you are creating a tree node in GC memory just to dump its
> contents ...  pp_double_int needs to be passed information on the
> signedness of the value.  It would roughly look like
>

Sorry, I understood it wrong.

> pp_double_int (pretty_printer *pp, double_int d, bool uns)
> {
>    if (d.fits_shwi ())
>      pp_wide_integer (pp, d.low);
>    else if (d.fits_uhwi ())
>      pp_unsigned_wide_integer (pp, d.low);
>    else
>      {
>         unsigned HOST_WIDE_INT low = d.low;
>         HOST_WIDE_INT high = d.high;
>            if (!uns && d.is_negative ())
>              {
>                pp_minus (pp);
>                high = ~high + !low;
>                low = -low;
>              }
>            /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
>               systems?  */
>            sprintf (pp_buffer (pp)->digit_buffer,
>                     HOST_WIDE_INT_PRINT_DOUBLE_HEX,
>                     (unsigned HOST_WIDE_INT) high, low);
>            pp_string (pp, pp_buffer (pp)->digit_buffer);
>      }
> }
>
> and the INTEGER_CST case would use it like
>
>      if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
>        ...
>      else
>        pp_double_int (buffer, tree_to_double_int (node),
> 	             TYPE_UNSIGNED (TREE_TYPE (node)));
>
>
> +enum value_range_type
> +get_range_info (tree name, double_int *min, double_int *max)
> +{
>
> ah, I see you have already made an appropriate change here.
>
> +             /* Check for an empty range with minimum zero (of type
> +                 unsigned) that will wraparround.  */
> +              if (!(TYPE_UNSIGNED (TREE_TYPE (name))
> +                  && integer_zerop (vr_value[i]->min)))
> +                set_range_info (name,
> +                                tree_to_double_int (vr_value[i]->max)
> +                                + double_int_one,
> +                                tree_to_double_int (vr_value[i]->min)
> +                                - double_int_one);
>
> Yeah, I think ~[0,0] is the only anti-range that can be represented as
> range that we keep.  So maybe
>
> 		if (TYPE_UNSIGNED (TREE_TYPE (name))
> 		    && integer_zerop (vr_value[i]->min)
>                      && integer_zerop (vr_value[i]->max))
>                    set_range_info (name,
>                                    double_int_one,
>                                    double_int::max_value
> 				  (TYPE_PRECISION (TREE_TYPE (name)), true));
> 		else
>                    set_range_info (name,
> +                                tree_to_double_int (vr_value[i]->max)
> +                                + double_int_one,
> +                                tree_to_double_int (vr_value[i]->min)
> +                                - double_int_one);
>
> to preserve ~[0,0] which looks like an important case when for example
> looking at a divisor in a division.
>
> Ok with those changes.
>

I have changed all of the above in the attached patch and ChangeLog. If 
this is OK, could someone please commit it for me. I donÂ’t have access 
to commit it.

Bootstrapped and regtested on x86_64-unknown-linux-gnu and arm-none 
linux-gnueabi.

Thanks,
Kugan



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

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ad70c24..6331636 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,24 @@
+2013-09-19  Kugan Vivekanandarajah  <kuganv@linaro.org>
+
+	* gimple-pretty-print.c (dump_ssaname_info) : New function.
+	* gimple-pretty-print.c (dump_gimple_phi) : Call dump_ssaname_info.
+	* (pp_gimple_stmt_1) : Likewise.
+	* tree-pretty-print.c (pp_double_int) : New function.
+	* (dump_generic_node) : Call pp_double_int.
+	* tree-ssa-alias.c (dump_alias_info) : Check pointer type.
+	* tree-ssanames.c (make_ssa_name_fn) : Check pointer type in
+	initialize.
+	* (set_range_info) : New function.
+	* (get_range_info) : Likewise.
+	* (duplicate_ssa_name_range_info) : Likewise.
+	* (duplicate_ssa_name_fn) : Check pointer type and call
+	duplicate_ssa_name_range_info.
+	* tree-ssa-copy.c (fini_copy_prop) : Likewise.
+	* tree-vrp.c (vrp_finalize): Call set_range_info to update
+	value range of SSA_NAMEs.
+	* tree.h (SSA_NAME_PTR_INFO) : Macro changed to access via union.
+	* tree.h (SSA_NAME_RANGE_INFO) : New macro.
+
 2013-09-18  Vladimir Makarov  <vmakarov@redhat.com>
 
 	* lra-constraints.c (need_for_all_save_p): Use macro

[-- Attachment #3: vrp_extension_elimination_patch1_r6.diff --]
[-- Type: text/x-patch, Size: 18135 bytes --]

diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 01a1ab5..bc01bea 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -1600,23 +1600,20 @@ dump_gimple_asm (pretty_printer *buffer, gimple gs, int spc, int flags)
     }
 }
 
-
-/* Dump a PHI node PHI.  BUFFER, SPC and FLAGS are as in pp_gimple_stmt_1.
-   The caller is responsible for calling pp_flush on BUFFER to finalize
-   pretty printer.  */
+/* Dump ptr_info and range_info for NODE on pretty_printer BUFFER with
+   SPC spaces of indent.  */
 
 static void
-dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags)
+dump_ssaname_info (pretty_printer *buffer, tree node, int spc)
 {
-  size_t i;
-  tree lhs = gimple_phi_result (phi);
+  if (TREE_CODE (node) != SSA_NAME)
+    return;
 
-  if (flags & TDF_ALIAS
-      && POINTER_TYPE_P (TREE_TYPE (lhs))
-      && SSA_NAME_PTR_INFO (lhs))
+  if (POINTER_TYPE_P (TREE_TYPE (node))
+      && SSA_NAME_PTR_INFO (node))
     {
       unsigned int align, misalign;
-      struct ptr_info_def *pi = SSA_NAME_PTR_INFO (lhs);
+      struct ptr_info_def *pi = SSA_NAME_PTR_INFO (node);
       pp_string (buffer, "PT = ");
       pp_points_to_solution (buffer, &pi->pt);
       newline_and_indent (buffer, spc);
@@ -1628,6 +1625,41 @@ dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags)
       pp_string (buffer, "# ");
     }
 
+  if (!POINTER_TYPE_P (TREE_TYPE (node))
+      && SSA_NAME_RANGE_INFO (node))
+    {
+      double_int min, max;
+      value_range_type range_type = get_range_info (node, &min, &max);
+
+      if (range_type == VR_VARYING)
+        pp_printf (buffer, "# RANGE  VR_VARYING");
+      else if (range_type == VR_RANGE || range_type == VR_ANTI_RANGE)
+        {
+          pp_printf (buffer, "# RANGE ");
+          pp_printf (buffer, "%s[", range_type == VR_RANGE ? "" : "~");
+          pp_double_int (buffer, min, TYPE_UNSIGNED (TREE_TYPE (node)));
+          pp_printf (buffer, ", ");
+          pp_double_int (buffer, max, TYPE_UNSIGNED (TREE_TYPE (node)));
+          pp_printf (buffer, "]");
+          newline_and_indent (buffer, spc);
+        }
+    }
+}
+
+
+/* Dump a PHI node PHI.  BUFFER, SPC and FLAGS are as in pp_gimple_stmt_1.
+   The caller is responsible for calling pp_flush on BUFFER to finalize
+   pretty printer.  */
+
+static void
+dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags)
+{
+  size_t i;
+  tree lhs = gimple_phi_result (phi);
+
+  if (flags & TDF_ALIAS)
+    dump_ssaname_info (buffer, lhs, spc);
+
   if (flags & TDF_RAW)
       dump_gimple_fmt (buffer, spc, flags, "%G <%T, ", phi,
                        gimple_phi_result (phi));
@@ -1908,27 +1940,9 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags)
       && gimple_has_mem_ops (gs))
     dump_gimple_mem_ops (buffer, gs, spc, flags);
 
-  if ((flags & TDF_ALIAS)
-      && gimple_has_lhs (gs))
-    {
-      tree lhs = gimple_get_lhs (gs);
-      if (TREE_CODE (lhs) == SSA_NAME
-	  && POINTER_TYPE_P (TREE_TYPE (lhs))
-	  && SSA_NAME_PTR_INFO (lhs))
-	{
-	  unsigned int align, misalign;
-	  struct ptr_info_def *pi = SSA_NAME_PTR_INFO (lhs);
-	  pp_string (buffer, "# PT = ");
-	  pp_points_to_solution (buffer, &pi->pt);
-	  newline_and_indent (buffer, spc);
-	  if (get_ptr_info_alignment (pi, &align, &misalign))
-	    {
-	      pp_printf (buffer, "# ALIGN = %u, MISALIGN = %u",
-			 align, misalign);
-	      newline_and_indent (buffer, spc);
-	    }
-	}
-    }
+  if (gimple_has_lhs (gs)
+      && (flags & TDF_ALIAS))
+    dump_ssaname_info (buffer, gimple_get_lhs (gs), spc);
 
   switch (gimple_code (gs))
     {
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 69777dc..2acc379 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -43,6 +43,7 @@ struct function;
 struct real_value;
 struct fixed_value;
 struct ptr_info_def;
+struct range_info_def;
 struct die_struct;
 struct pointer_set_t;
 
@@ -1050,8 +1051,14 @@ struct GTY(()) tree_ssa_name {
   /* Statement that defines this SSA name.  */
   gimple def_stmt;
 
-  /* Pointer attributes used for alias analysis.  */
-  struct ptr_info_def *ptr_info;
+  /* Value range information.  */
+  union ssa_name_info_type {
+    /* Pointer attributes used for alias analysis.  */
+    struct GTY ((tag ("0"))) ptr_info_def *ptr_info;
+    /* Value range attributes used for zero/sign extension elimination.  */
+    struct GTY ((tag ("1"))) range_info_def *range_info;
+  } GTY ((desc ("%1.typed.type ?" \
+                "!POINTER_TYPE_P (TREE_TYPE ((tree)&%1)) : 2"))) info;
 
   /* Immediate uses list for this SSA_NAME.  */
   struct ssa_use_operand_d imm_uses;
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index 4c04816..a5f9a71 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -1062,29 +1062,9 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 	  pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
 	  pp_string (buffer, "B"); /* pseudo-unit */
 	}
-      else if (host_integerp (node, 0))
-	pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
-      else if (host_integerp (node, 1))
-	pp_unsigned_wide_integer (buffer, TREE_INT_CST_LOW (node));
       else
-	{
-	  tree val = node;
-	  unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (val);
-	  HOST_WIDE_INT high = TREE_INT_CST_HIGH (val);
-
-	  if (tree_int_cst_sgn (val) < 0)
-	    {
-	      pp_minus (buffer);
-	      high = ~high + !low;
-	      low = -low;
-	    }
-	  /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
-	     systems?  */
-	  sprintf (pp_buffer (buffer)->digit_buffer,
-		   HOST_WIDE_INT_PRINT_DOUBLE_HEX,
-		   (unsigned HOST_WIDE_INT) high, low);
-	  pp_string (buffer, pp_buffer (buffer)->digit_buffer);
-	}
+        pp_double_int (buffer, tree_to_double_int (node),
+                       TYPE_UNSIGNED (TREE_TYPE (node)));
       break;
 
     case REAL_CST:
@@ -3196,3 +3176,31 @@ dump_function_header (FILE *dump_file, tree fdecl, int flags)
   else
     fprintf (dump_file, ")\n\n");
 }
+
+/* Dump double_int D to pretty_printer PP.  UNS is true
+   if D is unsigned and false otherwise.  */
+void
+pp_double_int (pretty_printer *pp, double_int d, bool uns)
+{
+  if (d.fits_shwi ())
+    pp_wide_integer (pp, d.low);
+  else if (d.fits_uhwi ())
+    pp_unsigned_wide_integer (pp, d.low);
+  else
+    {
+      unsigned HOST_WIDE_INT low = d.low;
+      HOST_WIDE_INT high = d.high;
+      if (!uns && d.is_negative ())
+        {
+          pp_minus (pp);
+          high = ~high + !low;
+          low = -low;
+        }
+      /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
+         systems?  */
+      sprintf (pp_buffer (pp)->digit_buffer,
+               HOST_WIDE_INT_PRINT_DOUBLE_HEX,
+               (unsigned HOST_WIDE_INT) high, low);
+      pp_string (pp, pp_buffer (pp)->digit_buffer);
+    }
+}
diff --git a/gcc/tree-pretty-print.h b/gcc/tree-pretty-print.h
index 7da8000..ec421fa 100644
--- a/gcc/tree-pretty-print.h
+++ b/gcc/tree-pretty-print.h
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3.  If not see
 #define GCC_TREE_PRETTY_PRINT_H
 
 #include "pretty-print.h"
+#include "double-int.h"
 
 #define pp_unsupported_tree(PP, T)                         \
   pp_verbatim (PP, "#%qs not supported by %s#", \
@@ -46,6 +47,7 @@ extern void debug_generic_stmt (tree);
 extern void debug_tree_chain (tree);
 extern void percent_K_format (text_info *);
 extern void dump_function_header (FILE *, tree, int);
+extern void pp_double_int (pretty_printer *pp, double_int d, bool uns);
 /* In c-pretty-print.c  */
 extern void debug_c_tree (tree);
 
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 9a6d5f4..0ef7401 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -404,6 +404,7 @@ dump_alias_info (FILE *file)
       struct ptr_info_def *pi;
 
       if (ptr == NULL_TREE
+          || !POINTER_TYPE_P (TREE_TYPE (ptr))
 	  || SSA_NAME_IN_FREE_LIST (ptr))
 	continue;
 
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index 3197917..25a43ff 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -767,11 +767,19 @@ fini_copy_prop (void)
 	 of the representative to the first solution we find if
 	 it doesn't have one already.  */
       if (copy_of[i].value != var
-	  && TREE_CODE (copy_of[i].value) == SSA_NAME
-	  && POINTER_TYPE_P (TREE_TYPE (var))
-	  && SSA_NAME_PTR_INFO (var)
-	  && !SSA_NAME_PTR_INFO (copy_of[i].value))
-	duplicate_ssa_name_ptr_info (copy_of[i].value, SSA_NAME_PTR_INFO (var));
+          && TREE_CODE (copy_of[i].value) == SSA_NAME)
+        {
+          if (POINTER_TYPE_P (TREE_TYPE (var))
+              && SSA_NAME_PTR_INFO (var)
+              && !SSA_NAME_PTR_INFO (copy_of[i].value))
+            duplicate_ssa_name_ptr_info (copy_of[i].value,
+                                         SSA_NAME_PTR_INFO (var));
+          else if (!POINTER_TYPE_P (TREE_TYPE (var))
+                   && SSA_NAME_RANGE_INFO (var)
+                   && !SSA_NAME_RANGE_INFO (copy_of[i].value))
+            duplicate_ssa_name_range_info (copy_of[i].value,
+                                           SSA_NAME_RANGE_INFO (var));
+        }
     }
 
   /* Don't do DCE if SCEV is initialized.  It would destroy the scev cache.  */
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index e64bd65..cd19640 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -154,7 +154,11 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt)
       SET_SSA_NAME_VAR_OR_IDENTIFIER (t, var);
     }
   SSA_NAME_DEF_STMT (t) = stmt;
-  SSA_NAME_PTR_INFO (t) = NULL;
+  if (POINTER_TYPE_P (TREE_TYPE (t)))
+    SSA_NAME_PTR_INFO (t) = NULL;
+  else
+    SSA_NAME_RANGE_INFO (t) = NULL;
+
   SSA_NAME_IN_FREE_LIST (t) = 0;
   SSA_NAME_IS_DEFAULT_DEF (t) = 0;
   imm = &(SSA_NAME_IMM_USE_NODE (t));
@@ -166,6 +170,62 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt)
   return t;
 }
 
+/* Store range information MIN, and MAX to tree ssa_name NAME.  */
+
+void
+set_range_info (tree name, double_int min, double_int max)
+{
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
+
+  /* Allocate if not available.  */
+  if (ri == NULL)
+    {
+      ri = ggc_alloc_cleared_range_info_def ();
+      SSA_NAME_RANGE_INFO (name) = ri;
+    }
+
+  /* Set the values.  */
+  ri->min = min;
+  ri->max = max;
+}
+
+
+/* Gets range information MIN, MAX and returns enum value_range_type
+   corresponding to tree ssa_name NAME.  enum value_range_type returned
+   is used to determine MIN and MAX are valid values.  */
+
+enum value_range_type
+get_range_info (tree name, double_int *min, double_int *max)
+{
+  enum value_range_type range_type;
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  gcc_assert (min && max);
+  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
+
+  /* Return VR_VARYING for SSA_NAMEs with NULL RANGE_INFO or SSA_NAMEs
+     with integral types width > 2 * HOST_BITS_PER_WIDE_INT precision.  */
+  if (!ri || (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (name)))
+              > 2 * HOST_BITS_PER_WIDE_INT))
+    return VR_VARYING;
+
+  /* If min > max, it is  VR_ANTI_RANGE.  */
+  if (ri->min.cmp (ri->max, TYPE_UNSIGNED (TREE_TYPE (name))) == 1)
+    {
+      /* VR_ANTI_RANGE ~[min, max] is encoded as [max + 1, min - 1].  */
+      range_type = VR_ANTI_RANGE;
+      *min = ri->max + double_int_one;
+      *max = ri->min - double_int_one;
+    }
+  else
+  {
+    /* Otherwise (when min <= max), it is  VR_RANGE.  */
+    range_type = VR_RANGE;
+    *min = ri->min;
+    *max = ri->max;
+  }
+  return range_type;
+}
 
 /* We no longer need the SSA_NAME expression VAR, release it so that
    it may be reused.
@@ -362,6 +422,26 @@ duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info)
   SSA_NAME_PTR_INFO (name) = new_ptr_info;
 }
 
+/* Creates a duplicate of the range_info_def at RANGE_INFO for use by
+   the SSA name NAME.  */
+void
+duplicate_ssa_name_range_info (tree name, struct range_info_def *range_info)
+{
+  struct range_info_def *new_range_info;
+
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  gcc_assert (!SSA_NAME_RANGE_INFO (name));
+
+  if (!range_info)
+    return;
+
+  new_range_info = ggc_alloc_range_info_def ();
+  *new_range_info = *range_info;
+
+  SSA_NAME_RANGE_INFO (name) = new_range_info;
+}
+
+
 
 /* Creates a duplicate of a ssa name NAME tobe defined by statement STMT
    in function FN.  */
@@ -370,10 +450,20 @@ tree
 duplicate_ssa_name_fn (struct function *fn, tree name, gimple stmt)
 {
   tree new_name = copy_ssa_name_fn (fn, name, stmt);
-  struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
+  if (POINTER_TYPE_P (TREE_TYPE (name)))
+    {
+      struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
+
+      if (old_ptr_info)
+        duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+    }
+  else
+    {
+      struct range_info_def *old_range_info = SSA_NAME_RANGE_INFO (name);
 
-  if (old_ptr_info)
-    duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+      if (old_range_info)
+        duplicate_ssa_name_range_info (new_name, old_range_info);
+    }
 
   return new_name;
 }
diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h
index 8cc3efd..9a8ea14 100644
--- a/gcc/tree-ssanames.h
+++ b/gcc/tree-ssanames.h
@@ -45,6 +45,15 @@ struct GTY(()) ptr_info_def
   unsigned int misalign;
 };
 
+/* Value range information for SSA_NAMEs representing non-pointer variables.  */
+
+struct GTY (()) range_info_def {
+  /* Minmum for value range.  */
+  double_int min;
+  /* Maximum for value range.  */
+  double_int max;
+};
+
 
 #define SSANAMES(fun) (fun)->gimple_df->ssa_names
 #define MODIFIED_NORETURN_CALLS(fun) (fun)->gimple_df->modified_noreturn_calls
@@ -54,6 +63,15 @@ struct GTY(()) ptr_info_def
 #define ssa_name(i) ((*cfun->gimple_df->ssa_names)[(i)])
 
 
+/* Type of value ranges.  See value_range_d In tree-vrp.c for a
+   description of these types.  */
+enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING };
+
+/* Sets the value range to SSA.  */
+extern void set_range_info (tree ssa, double_int min, double_int max);
+/* Gets the value range from SSA.  */
+extern enum value_range_type  get_range_info (tree name, double_int *min,
+                                              double_int *max);
 extern void init_ssanames (struct function *, int);
 extern void fini_ssanames (void);
 extern void ssanames_print_statistics (void);
@@ -71,6 +89,7 @@ extern struct ptr_info_def *get_ptr_info (tree);
 extern tree copy_ssa_name_fn (struct function *, tree, gimple);
 extern void duplicate_ssa_name_ptr_info (tree, struct ptr_info_def *);
 extern tree duplicate_ssa_name_fn (struct function *, tree, gimple);
+extern void duplicate_ssa_name_range_info (tree, struct range_info_def *);
 extern void release_defs (gimple);
 extern void replace_ssa_name_symbol (tree, tree);
 
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index ae27dc4..ad448f9 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -41,9 +41,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "optabs.h"
 
 
-/* Type of value ranges.  See value_range_d for a description of these
-   types.  */
-enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING };
 
 /* Range of values that can be associated with an SSA_NAME after VRP
    has executed.  */
@@ -9452,6 +9449,50 @@ vrp_finalize (void)
      the datastructures built by VRP.  */
   identify_jump_threads ();
 
+  /* Set value range to non pointer SSA_NAMEs.  */
+  for (i  = 0; i < num_vr_values; i++)
+   if (vr_value[i])
+    {
+      tree name = ssa_name (i);
+
+      if (POINTER_TYPE_P (TREE_TYPE (name))
+          || (vr_value[i]->type == VR_VARYING)
+          || (vr_value[i]->type == VR_UNDEFINED))
+        continue;
+
+      if ((TREE_CODE (vr_value[i]->min) == INTEGER_CST)
+          && (TREE_CODE (vr_value[i]->max) == INTEGER_CST))
+        {
+          if (vr_value[i]->type == VR_RANGE)
+            set_range_info (name,
+                            tree_to_double_int (vr_value[i]->min),
+                            tree_to_double_int (vr_value[i]->max));
+          else if (vr_value[i]->type == VR_ANTI_RANGE)
+            {
+              /* VR_ANTI_RANGE ~[min, max] is encoded compactly as
+                 [max + 1, min - 1] without additional attributes.
+                 When min value > max value, we know that it is
+                 VR_ANTI_RANGE; it is VR_RANGE othewise.  */
+
+	      /* ~[0,0] anti-range is represented as
+                 range.  */
+              if (TYPE_UNSIGNED (TREE_TYPE (name))
+                  && integer_zerop (vr_value[i]->min)
+                  && integer_zerop (vr_value[i]->max))
+                set_range_info (name,
+                                double_int_one,
+                                double_int::max_value
+                                (TYPE_PRECISION (TREE_TYPE (name)), true));
+              else
+                set_range_info (name,
+                                tree_to_double_int (vr_value[i]->max)
+                                + double_int_one,
+                                tree_to_double_int (vr_value[i]->min)
+                                - double_int_one);
+            }
+        }
+    }
+
   /* Free allocated memory.  */
   for (i = 0; i < num_vr_values; i++)
     if (vr_value[i])
diff --git a/gcc/tree.h b/gcc/tree.h
index a263a2c..fb7c057 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1336,7 +1336,11 @@ extern void protected_set_expr_location (tree, location_t);
 
 /* Attributes for SSA_NAMEs for pointer-type variables.  */
 #define SSA_NAME_PTR_INFO(N) \
-    SSA_NAME_CHECK (N)->ssa_name.ptr_info
+   SSA_NAME_CHECK (N)->ssa_name.info.ptr_info
+
+/* Value range info Attributes for SSA_NAMEs of non pointer-type variables.  */
+#define SSA_NAME_RANGE_INFO(N) \
+    SSA_NAME_CHECK (N)->ssa_name.info.range_info
 
 /* Return the immediate_use information for an SSA_NAME. */
 #define SSA_NAME_IMM_USE_NODE(NODE) SSA_NAME_CHECK (NODE)->ssa_name.imm_uses

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-19  7:25                                         ` Kugan
@ 2013-09-23 11:39                                           ` Richard Biener
  2013-09-23 15:55                                             ` Christophe Lyon
  0 siblings, 1 reply; 38+ messages in thread
From: Richard Biener @ 2013-09-23 11:39 UTC (permalink / raw)
  To: Kugan
  Cc: Richard Biener, Jakub Jelinek, gcc-patches, Ramana Radhakrishnan,
	Richard Earnshaw

On Thu, Sep 19, 2013 at 7:07 AM, Kugan
<kugan.vivekanandarajah@linaro.org> wrote:
> Thanks Richard for the review.
>
> On 18/09/13 18:55, Richard Biener wrote:
>>
>> On Wed, 18 Sep 2013, Kugan wrote:
>>
>>>
>>> Thanks Richard for the review.
>>> On 16/09/13 23:43, Richard Biener wrote:
>>>>
>>>> On Mon, 16 Sep 2013, Kugan wrote:
>>>>
>
> [Snip]
>
>
>>>
>>> +2013-09-17  Kugan Vivekanandarajah  <kuganv@linaro.org>
>>> +
>>> +       * gimple-pretty-print.c (dump_ssaname_info) : New function.
>>> +       * gimple-pretty-print.c (dump_gimple_phi) : Dump range info.
>>> +       * (pp_gimple_stmt_1) : Likewise.
>>
>>
>> ChangeLog should be formated
>>
>>         * gimple-pretty-print.c (dump_ssaname_info): New function.
>>         (dump_gimple_phi): Call it.
>>         (pp_gimple_stmt_1: Likewise.
>>         * tree-pretty-print.c (dump_intger_cst_node): New function.
>> ...
>>
>>
>> +        pp_printf (buffer, "# RANGE ");
>> +        pp_printf (buffer, "%s[", range_type == VR_RANGE ? "" : "~");
>> +        dump_intger_cst_node (buffer,
>> +                              double_int_to_tree (TREE_TYPE (node),
>> min));
>>
>> I was asking for a pp_double_int, not a dump_integer_cst_node function
>> as now you are creating a tree node in GC memory just to dump its
>> contents ...  pp_double_int needs to be passed information on the
>> signedness of the value.  It would roughly look like
>>
>
> Sorry, I understood it wrong.
>
>
>> pp_double_int (pretty_printer *pp, double_int d, bool uns)
>> {
>>    if (d.fits_shwi ())
>>      pp_wide_integer (pp, d.low);
>>    else if (d.fits_uhwi ())
>>      pp_unsigned_wide_integer (pp, d.low);
>>    else
>>      {
>>         unsigned HOST_WIDE_INT low = d.low;
>>         HOST_WIDE_INT high = d.high;
>>            if (!uns && d.is_negative ())
>>              {
>>                pp_minus (pp);
>>                high = ~high + !low;
>>                low = -low;
>>              }
>>            /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
>>               systems?  */
>>            sprintf (pp_buffer (pp)->digit_buffer,
>>                     HOST_WIDE_INT_PRINT_DOUBLE_HEX,
>>                     (unsigned HOST_WIDE_INT) high, low);
>>            pp_string (pp, pp_buffer (pp)->digit_buffer);
>>      }
>> }
>>
>> and the INTEGER_CST case would use it like
>>
>>      if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
>>        ...
>>      else
>>        pp_double_int (buffer, tree_to_double_int (node),
>>                      TYPE_UNSIGNED (TREE_TYPE (node)));
>>
>>
>> +enum value_range_type
>> +get_range_info (tree name, double_int *min, double_int *max)
>> +{
>>
>> ah, I see you have already made an appropriate change here.
>>
>> +             /* Check for an empty range with minimum zero (of type
>> +                 unsigned) that will wraparround.  */
>> +              if (!(TYPE_UNSIGNED (TREE_TYPE (name))
>> +                  && integer_zerop (vr_value[i]->min)))
>> +                set_range_info (name,
>> +                                tree_to_double_int (vr_value[i]->max)
>> +                                + double_int_one,
>> +                                tree_to_double_int (vr_value[i]->min)
>> +                                - double_int_one);
>>
>> Yeah, I think ~[0,0] is the only anti-range that can be represented as
>> range that we keep.  So maybe
>>
>>                 if (TYPE_UNSIGNED (TREE_TYPE (name))
>>                     && integer_zerop (vr_value[i]->min)
>>                      && integer_zerop (vr_value[i]->max))
>>                    set_range_info (name,
>>                                    double_int_one,
>>                                    double_int::max_value
>>                                   (TYPE_PRECISION (TREE_TYPE (name)),
>> true));
>>                 else
>>                    set_range_info (name,
>> +                                tree_to_double_int (vr_value[i]->max)
>> +                                + double_int_one,
>> +                                tree_to_double_int (vr_value[i]->min)
>> +                                - double_int_one);
>>
>> to preserve ~[0,0] which looks like an important case when for example
>> looking at a divisor in a division.
>>
>> Ok with those changes.
>>
>
> I have changed all of the above in the attached patch and ChangeLog. If this
> is OK, could someone please commit it for me. I don’t have access to commit
> it.
>
> Bootstrapped and regtested on x86_64-unknown-linux-gnu and arm-none
> linux-gnueabi.

Ok.

Thanks and sorry that it took so long,
Richard.

> Thanks,
> Kugan
>
>

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-23 11:39                                           ` Richard Biener
@ 2013-09-23 15:55                                             ` Christophe Lyon
  2013-09-23 21:03                                               ` Eric Botcazou
  0 siblings, 1 reply; 38+ messages in thread
From: Christophe Lyon @ 2013-09-23 15:55 UTC (permalink / raw)
  To: Richard Biener
  Cc: Kugan, Richard Biener, Jakub Jelinek, gcc-patches,
	Ramana Radhakrishnan, Richard Earnshaw

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

Kugan,

>> I have changed all of the above in the attached patch and ChangeLog. If this
>> is OK, could someone please commit it for me. I don’t have access to commit
>> it.
>>
>> Bootstrapped and regtested on x86_64-unknown-linux-gnu and arm-none
>> linux-gnueabi.
>
> Ok.
>
> Thanks and sorry that it took so long,
> Richard.
>
>> Thanks,
>> Kugan
>>
>>
I have committed it for you (rev 202831), with a few modifications
(ChangeLog formatting, typos).
Here is what I have committed:

2013-09-23  Kugan Vivekanandarajah  <kuganv@linaro.org>

    * gimple-pretty-print.c (dump_ssaname_info): New function.
    (dump_gimple_phi): Call it.
    (pp_gimple_stmt_1): Likewise.
    * tree-core.h (tree_ssa_name): New union ssa_name_info_type field.
    (range_info_def): Declare.
    * tree-pretty-print.c (pp_double_int): New function.
    (dump_generic_node): Call it.
    * tree-pretty-print.h (pp_double_int): Declare.
    * tree-ssa-alias.c (dump_alias_info): Check pointer type.
    * tree-ssanames.h (range_info_def): New structure.
    (value_range_type): Move definition here.
    (set_range_info, value_range_type, duplicate_ssa_name_range_info):
    Declare.
    * tree-ssanames.c (make_ssa_name_fn): Check pointer type at
    initialization.
    (set_range_info): New function.
    (get_range_info): Likewise.
    (duplicate_ssa_name_range_info): Likewise.
    (duplicate_ssa_name_fn): Check pointer type and call
    duplicate_ssa_name_range_info.
    * tree-ssa-copy.c (fini_copy_prop): Likewise.
    * tree-vrp.c (value_range_type): Remove definition, now in
    tree-ssanames.h.
    (vrp_finalize): Call set_range_info to update value range of
    SSA_NAMEs.
    * tree.h (SSA_NAME_PTR_INFO): Macro changed to access via union.
    (SSA_NAME_RANGE_INFO): New macro.

[-- Attachment #2: patch-vrp.txt --]
[-- Type: text/plain, Size: 18263 bytes --]

Index: gcc/gimple-pretty-print.c
===================================================================
--- gcc/gimple-pretty-print.c	(revision 202830)
+++ gcc/gimple-pretty-print.c	(working copy)
@@ -1600,23 +1600,20 @@ dump_gimple_asm (pretty_printer *buffer,
     }
 }
 
-
-/* Dump a PHI node PHI.  BUFFER, SPC and FLAGS are as in pp_gimple_stmt_1.
-   The caller is responsible for calling pp_flush on BUFFER to finalize
-   pretty printer.  */
+/* Dump ptr_info and range_info for NODE on pretty_printer BUFFER with
+   SPC spaces of indent.  */
 
 static void
-dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags)
+dump_ssaname_info (pretty_printer *buffer, tree node, int spc)
 {
-  size_t i;
-  tree lhs = gimple_phi_result (phi);
+  if (TREE_CODE (node) != SSA_NAME)
+    return;
 
-  if (flags & TDF_ALIAS
-      && POINTER_TYPE_P (TREE_TYPE (lhs))
-      && SSA_NAME_PTR_INFO (lhs))
+  if (POINTER_TYPE_P (TREE_TYPE (node))
+      && SSA_NAME_PTR_INFO (node))
     {
       unsigned int align, misalign;
-      struct ptr_info_def *pi = SSA_NAME_PTR_INFO (lhs);
+      struct ptr_info_def *pi = SSA_NAME_PTR_INFO (node);
       pp_string (buffer, "PT = ");
       pp_points_to_solution (buffer, &pi->pt);
       newline_and_indent (buffer, spc);
@@ -1628,6 +1625,41 @@ dump_gimple_phi (pretty_printer *buffer,
       pp_string (buffer, "# ");
     }
 
+  if (!POINTER_TYPE_P (TREE_TYPE (node))
+      && SSA_NAME_RANGE_INFO (node))
+    {
+      double_int min, max;
+      value_range_type range_type = get_range_info (node, &min, &max);
+
+      if (range_type == VR_VARYING)
+        pp_printf (buffer, "# RANGE  VR_VARYING");
+      else if (range_type == VR_RANGE || range_type == VR_ANTI_RANGE)
+        {
+          pp_printf (buffer, "# RANGE ");
+          pp_printf (buffer, "%s[", range_type == VR_RANGE ? "" : "~");
+          pp_double_int (buffer, min, TYPE_UNSIGNED (TREE_TYPE (node)));
+          pp_printf (buffer, ", ");
+          pp_double_int (buffer, max, TYPE_UNSIGNED (TREE_TYPE (node)));
+          pp_printf (buffer, "]");
+          newline_and_indent (buffer, spc);
+        }
+    }
+}
+
+
+/* Dump a PHI node PHI.  BUFFER, SPC and FLAGS are as in pp_gimple_stmt_1.
+   The caller is responsible for calling pp_flush on BUFFER to finalize
+   pretty printer.  */
+
+static void
+dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags)
+{
+  size_t i;
+  tree lhs = gimple_phi_result (phi);
+
+  if (flags & TDF_ALIAS)
+    dump_ssaname_info (buffer, lhs, spc);
+
   if (flags & TDF_RAW)
       dump_gimple_fmt (buffer, spc, flags, "%G <%T, ", phi,
                        gimple_phi_result (phi));
@@ -1908,27 +1940,9 @@ pp_gimple_stmt_1 (pretty_printer *buffer
       && gimple_has_mem_ops (gs))
     dump_gimple_mem_ops (buffer, gs, spc, flags);
 
-  if ((flags & TDF_ALIAS)
-      && gimple_has_lhs (gs))
-    {
-      tree lhs = gimple_get_lhs (gs);
-      if (TREE_CODE (lhs) == SSA_NAME
-	  && POINTER_TYPE_P (TREE_TYPE (lhs))
-	  && SSA_NAME_PTR_INFO (lhs))
-	{
-	  unsigned int align, misalign;
-	  struct ptr_info_def *pi = SSA_NAME_PTR_INFO (lhs);
-	  pp_string (buffer, "# PT = ");
-	  pp_points_to_solution (buffer, &pi->pt);
-	  newline_and_indent (buffer, spc);
-	  if (get_ptr_info_alignment (pi, &align, &misalign))
-	    {
-	      pp_printf (buffer, "# ALIGN = %u, MISALIGN = %u",
-			 align, misalign);
-	      newline_and_indent (buffer, spc);
-	    }
-	}
-    }
+  if (gimple_has_lhs (gs)
+      && (flags & TDF_ALIAS))
+    dump_ssaname_info (buffer, gimple_get_lhs (gs), spc);
 
   switch (gimple_code (gs))
     {
Index: gcc/tree-core.h
===================================================================
--- gcc/tree-core.h	(revision 202830)
+++ gcc/tree-core.h	(working copy)
@@ -43,6 +43,7 @@ struct function;
 struct real_value;
 struct fixed_value;
 struct ptr_info_def;
+struct range_info_def;
 struct die_struct;
 struct pointer_set_t;
 
@@ -1050,8 +1051,14 @@ struct GTY(()) tree_ssa_name {
   /* Statement that defines this SSA name.  */
   gimple def_stmt;
 
-  /* Pointer attributes used for alias analysis.  */
-  struct ptr_info_def *ptr_info;
+  /* Value range information.  */
+  union ssa_name_info_type {
+    /* Pointer attributes used for alias analysis.  */
+    struct GTY ((tag ("0"))) ptr_info_def *ptr_info;
+    /* Value range attributes used for zero/sign extension elimination.  */
+    struct GTY ((tag ("1"))) range_info_def *range_info;
+  } GTY ((desc ("%1.typed.type ?" \
+                "!POINTER_TYPE_P (TREE_TYPE ((tree)&%1)) : 2"))) info;
 
   /* Immediate uses list for this SSA_NAME.  */
   struct ssa_use_operand_d imm_uses;
Index: gcc/tree-pretty-print.c
===================================================================
--- gcc/tree-pretty-print.c	(revision 202830)
+++ gcc/tree-pretty-print.c	(working copy)
@@ -1062,29 +1062,9 @@ dump_generic_node (pretty_printer *buffe
 	  pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
 	  pp_string (buffer, "B"); /* pseudo-unit */
 	}
-      else if (host_integerp (node, 0))
-	pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
-      else if (host_integerp (node, 1))
-	pp_unsigned_wide_integer (buffer, TREE_INT_CST_LOW (node));
       else
-	{
-	  tree val = node;
-	  unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (val);
-	  HOST_WIDE_INT high = TREE_INT_CST_HIGH (val);
-
-	  if (tree_int_cst_sgn (val) < 0)
-	    {
-	      pp_minus (buffer);
-	      high = ~high + !low;
-	      low = -low;
-	    }
-	  /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
-	     systems?  */
-	  sprintf (pp_buffer (buffer)->digit_buffer,
-		   HOST_WIDE_INT_PRINT_DOUBLE_HEX,
-		   (unsigned HOST_WIDE_INT) high, low);
-	  pp_string (buffer, pp_buffer (buffer)->digit_buffer);
-	}
+        pp_double_int (buffer, tree_to_double_int (node),
+                       TYPE_UNSIGNED (TREE_TYPE (node)));
       break;
 
     case REAL_CST:
@@ -3196,3 +3176,31 @@ dump_function_header (FILE *dump_file, t
   else
     fprintf (dump_file, ")\n\n");
 }
+
+/* Dump double_int D to pretty_printer PP.  UNS is true
+   if D is unsigned and false otherwise.  */
+void
+pp_double_int (pretty_printer *pp, double_int d, bool uns)
+{
+  if (d.fits_shwi ())
+    pp_wide_integer (pp, d.low);
+  else if (d.fits_uhwi ())
+    pp_unsigned_wide_integer (pp, d.low);
+  else
+    {
+      unsigned HOST_WIDE_INT low = d.low;
+      HOST_WIDE_INT high = d.high;
+      if (!uns && d.is_negative ())
+        {
+          pp_minus (pp);
+          high = ~high + !low;
+          low = -low;
+        }
+      /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
+         systems?  */
+      sprintf (pp_buffer (pp)->digit_buffer,
+               HOST_WIDE_INT_PRINT_DOUBLE_HEX,
+               (unsigned HOST_WIDE_INT) high, low);
+      pp_string (pp, pp_buffer (pp)->digit_buffer);
+    }
+}
Index: gcc/tree-pretty-print.h
===================================================================
--- gcc/tree-pretty-print.h	(revision 202830)
+++ gcc/tree-pretty-print.h	(working copy)
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3.  
 #define GCC_TREE_PRETTY_PRINT_H
 
 #include "pretty-print.h"
+#include "double-int.h"
 
 #define pp_unsupported_tree(PP, T)                         \
   pp_verbatim (PP, "#%qs not supported by %s#", \
@@ -46,6 +47,7 @@ extern void debug_generic_stmt (tree);
 extern void debug_tree_chain (tree);
 extern void percent_K_format (text_info *);
 extern void dump_function_header (FILE *, tree, int);
+extern void pp_double_int (pretty_printer *pp, double_int d, bool uns);
 /* In c-pretty-print.c  */
 extern void debug_c_tree (tree);
 
Index: gcc/tree-ssa-alias.c
===================================================================
--- gcc/tree-ssa-alias.c	(revision 202830)
+++ gcc/tree-ssa-alias.c	(working copy)
@@ -404,6 +404,7 @@ dump_alias_info (FILE *file)
       struct ptr_info_def *pi;
 
       if (ptr == NULL_TREE
+          || !POINTER_TYPE_P (TREE_TYPE (ptr))
 	  || SSA_NAME_IN_FREE_LIST (ptr))
 	continue;
 
Index: gcc/tree-ssa-copy.c
===================================================================
--- gcc/tree-ssa-copy.c	(revision 202830)
+++ gcc/tree-ssa-copy.c	(working copy)
@@ -767,11 +767,19 @@ fini_copy_prop (void)
 	 of the representative to the first solution we find if
 	 it doesn't have one already.  */
       if (copy_of[i].value != var
-	  && TREE_CODE (copy_of[i].value) == SSA_NAME
-	  && POINTER_TYPE_P (TREE_TYPE (var))
-	  && SSA_NAME_PTR_INFO (var)
-	  && !SSA_NAME_PTR_INFO (copy_of[i].value))
-	duplicate_ssa_name_ptr_info (copy_of[i].value, SSA_NAME_PTR_INFO (var));
+          && TREE_CODE (copy_of[i].value) == SSA_NAME)
+        {
+          if (POINTER_TYPE_P (TREE_TYPE (var))
+              && SSA_NAME_PTR_INFO (var)
+              && !SSA_NAME_PTR_INFO (copy_of[i].value))
+            duplicate_ssa_name_ptr_info (copy_of[i].value,
+                                         SSA_NAME_PTR_INFO (var));
+          else if (!POINTER_TYPE_P (TREE_TYPE (var))
+                   && SSA_NAME_RANGE_INFO (var)
+                   && !SSA_NAME_RANGE_INFO (copy_of[i].value))
+            duplicate_ssa_name_range_info (copy_of[i].value,
+                                           SSA_NAME_RANGE_INFO (var));
+        }
     }
 
   /* Don't do DCE if SCEV is initialized.  It would destroy the scev cache.  */
Index: gcc/tree-ssanames.c
===================================================================
--- gcc/tree-ssanames.c	(revision 202830)
+++ gcc/tree-ssanames.c	(working copy)
@@ -154,7 +154,11 @@ make_ssa_name_fn (struct function *fn, t
       SET_SSA_NAME_VAR_OR_IDENTIFIER (t, var);
     }
   SSA_NAME_DEF_STMT (t) = stmt;
-  SSA_NAME_PTR_INFO (t) = NULL;
+  if (POINTER_TYPE_P (TREE_TYPE (t)))
+    SSA_NAME_PTR_INFO (t) = NULL;
+  else
+    SSA_NAME_RANGE_INFO (t) = NULL;
+
   SSA_NAME_IN_FREE_LIST (t) = 0;
   SSA_NAME_IS_DEFAULT_DEF (t) = 0;
   imm = &(SSA_NAME_IMM_USE_NODE (t));
@@ -166,6 +170,62 @@ make_ssa_name_fn (struct function *fn, t
   return t;
 }
 
+/* Store range information MIN, and MAX to tree ssa_name NAME.  */
+
+void
+set_range_info (tree name, double_int min, double_int max)
+{
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
+
+  /* Allocate if not available.  */
+  if (ri == NULL)
+    {
+      ri = ggc_alloc_cleared_range_info_def ();
+      SSA_NAME_RANGE_INFO (name) = ri;
+    }
+
+  /* Set the values.  */
+  ri->min = min;
+  ri->max = max;
+}
+
+
+/* Gets range information MIN, MAX and returns enum value_range_type
+   corresponding to tree ssa_name NAME.  enum value_range_type returned
+   is used to determine if MIN and MAX are valid values.  */
+
+enum value_range_type
+get_range_info (tree name, double_int *min, double_int *max)
+{
+  enum value_range_type range_type;
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  gcc_assert (min && max);
+  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
+
+  /* Return VR_VARYING for SSA_NAMEs with NULL RANGE_INFO or SSA_NAMEs
+     with integral types width > 2 * HOST_BITS_PER_WIDE_INT precision.  */
+  if (!ri || (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (name)))
+              > 2 * HOST_BITS_PER_WIDE_INT))
+    return VR_VARYING;
+
+  /* If min > max, it is VR_ANTI_RANGE.  */
+  if (ri->min.cmp (ri->max, TYPE_UNSIGNED (TREE_TYPE (name))) == 1)
+    {
+      /* VR_ANTI_RANGE ~[min, max] is encoded as [max + 1, min - 1].  */
+      range_type = VR_ANTI_RANGE;
+      *min = ri->max + double_int_one;
+      *max = ri->min - double_int_one;
+    }
+  else
+  {
+    /* Otherwise (when min <= max), it is VR_RANGE.  */
+    range_type = VR_RANGE;
+    *min = ri->min;
+    *max = ri->max;
+  }
+  return range_type;
+}
 
 /* We no longer need the SSA_NAME expression VAR, release it so that
    it may be reused.
@@ -362,6 +422,26 @@ duplicate_ssa_name_ptr_info (tree name, 
   SSA_NAME_PTR_INFO (name) = new_ptr_info;
 }
 
+/* Creates a duplicate of the range_info_def at RANGE_INFO for use by
+   the SSA name NAME.  */
+void
+duplicate_ssa_name_range_info (tree name, struct range_info_def *range_info)
+{
+  struct range_info_def *new_range_info;
+
+  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
+  gcc_assert (!SSA_NAME_RANGE_INFO (name));
+
+  if (!range_info)
+    return;
+
+  new_range_info = ggc_alloc_range_info_def ();
+  *new_range_info = *range_info;
+
+  SSA_NAME_RANGE_INFO (name) = new_range_info;
+}
+
+
 
 /* Creates a duplicate of a ssa name NAME tobe defined by statement STMT
    in function FN.  */
@@ -370,10 +450,20 @@ tree
 duplicate_ssa_name_fn (struct function *fn, tree name, gimple stmt)
 {
   tree new_name = copy_ssa_name_fn (fn, name, stmt);
-  struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
+  if (POINTER_TYPE_P (TREE_TYPE (name)))
+    {
+      struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
 
-  if (old_ptr_info)
-    duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+      if (old_ptr_info)
+        duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+    }
+  else
+    {
+      struct range_info_def *old_range_info = SSA_NAME_RANGE_INFO (name);
+
+      if (old_range_info)
+        duplicate_ssa_name_range_info (new_name, old_range_info);
+    }
 
   return new_name;
 }
Index: gcc/tree-ssanames.h
===================================================================
--- gcc/tree-ssanames.h	(revision 202830)
+++ gcc/tree-ssanames.h	(working copy)
@@ -45,6 +45,15 @@ struct GTY(()) ptr_info_def
   unsigned int misalign;
 };
 
+/* Value range information for SSA_NAMEs representing non-pointer variables.  */
+
+struct GTY (()) range_info_def {
+  /* Minimum for value range.  */
+  double_int min;
+  /* Maximum for value range.  */
+  double_int max;
+};
+
 
 #define SSANAMES(fun) (fun)->gimple_df->ssa_names
 #define MODIFIED_NORETURN_CALLS(fun) (fun)->gimple_df->modified_noreturn_calls
@@ -54,6 +63,15 @@ struct GTY(()) ptr_info_def
 #define ssa_name(i) ((*cfun->gimple_df->ssa_names)[(i)])
 
 
+/* Type of value ranges.  See value_range_d In tree-vrp.c for a
+   description of these types.  */
+enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING };
+
+/* Sets the value range to SSA.  */
+extern void set_range_info (tree ssa, double_int min, double_int max);
+/* Gets the value range from SSA.  */
+extern enum value_range_type  get_range_info (tree name, double_int *min,
+                                              double_int *max);
 extern void init_ssanames (struct function *, int);
 extern void fini_ssanames (void);
 extern void ssanames_print_statistics (void);
@@ -71,6 +89,7 @@ extern struct ptr_info_def *get_ptr_info
 extern tree copy_ssa_name_fn (struct function *, tree, gimple);
 extern void duplicate_ssa_name_ptr_info (tree, struct ptr_info_def *);
 extern tree duplicate_ssa_name_fn (struct function *, tree, gimple);
+extern void duplicate_ssa_name_range_info (tree, struct range_info_def *);
 extern void release_defs (gimple);
 extern void replace_ssa_name_symbol (tree, tree);
 
Index: gcc/tree-vrp.c
===================================================================
--- gcc/tree-vrp.c	(revision 202830)
+++ gcc/tree-vrp.c	(working copy)
@@ -41,9 +41,6 @@ along with GCC; see the file COPYING3.  
 #include "optabs.h"
 
 
-/* Type of value ranges.  See value_range_d for a description of these
-   types.  */
-enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING };
 
 /* Range of values that can be associated with an SSA_NAME after VRP
    has executed.  */
@@ -9452,6 +9449,50 @@ vrp_finalize (void)
      the datastructures built by VRP.  */
   identify_jump_threads ();
 
+  /* Set value range to non pointer SSA_NAMEs.  */
+  for (i  = 0; i < num_vr_values; i++)
+   if (vr_value[i])
+    {
+      tree name = ssa_name (i);
+
+      if (POINTER_TYPE_P (TREE_TYPE (name))
+          || (vr_value[i]->type == VR_VARYING)
+          || (vr_value[i]->type == VR_UNDEFINED))
+        continue;
+
+      if ((TREE_CODE (vr_value[i]->min) == INTEGER_CST)
+          && (TREE_CODE (vr_value[i]->max) == INTEGER_CST))
+        {
+          if (vr_value[i]->type == VR_RANGE)
+            set_range_info (name,
+                            tree_to_double_int (vr_value[i]->min),
+                            tree_to_double_int (vr_value[i]->max));
+          else if (vr_value[i]->type == VR_ANTI_RANGE)
+            {
+              /* VR_ANTI_RANGE ~[min, max] is encoded compactly as
+                 [max + 1, min - 1] without additional attributes.
+                 When min value > max value, we know that it is
+                 VR_ANTI_RANGE; it is VR_RANGE otherwise.  */
+
+	      /* ~[0,0] anti-range is represented as
+                 range.  */
+              if (TYPE_UNSIGNED (TREE_TYPE (name))
+                  && integer_zerop (vr_value[i]->min)
+                  && integer_zerop (vr_value[i]->max))
+                set_range_info (name,
+                                double_int_one,
+                                double_int::max_value
+                                (TYPE_PRECISION (TREE_TYPE (name)), true));
+              else
+                set_range_info (name,
+                                tree_to_double_int (vr_value[i]->max)
+                                + double_int_one,
+                                tree_to_double_int (vr_value[i]->min)
+                                - double_int_one);
+            }
+        }
+    }
+
   /* Free allocated memory.  */
   for (i = 0; i < num_vr_values; i++)
     if (vr_value[i])
Index: gcc/tree.h
===================================================================
--- gcc/tree.h	(revision 202830)
+++ gcc/tree.h	(working copy)
@@ -1336,7 +1336,11 @@ extern void protected_set_expr_location 
 
 /* Attributes for SSA_NAMEs for pointer-type variables.  */
 #define SSA_NAME_PTR_INFO(N) \
-    SSA_NAME_CHECK (N)->ssa_name.ptr_info
+   SSA_NAME_CHECK (N)->ssa_name.info.ptr_info
+
+/* Value range info attributes for SSA_NAMEs of non pointer-type variables.  */
+#define SSA_NAME_RANGE_INFO(N) \
+    SSA_NAME_CHECK (N)->ssa_name.info.range_info
 
 /* Return the immediate_use information for an SSA_NAME. */
 #define SSA_NAME_IMM_USE_NODE(NODE) SSA_NAME_CHECK (NODE)->ssa_name.imm_uses

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-23 15:55                                             ` Christophe Lyon
@ 2013-09-23 21:03                                               ` Eric Botcazou
  2013-09-24 10:13                                                 ` Richard Biener
  2013-09-24 16:25                                                 ` Christophe Lyon
  0 siblings, 2 replies; 38+ messages in thread
From: Eric Botcazou @ 2013-09-23 21:03 UTC (permalink / raw)
  To: Christophe Lyon
  Cc: gcc-patches, Richard Biener, Kugan, Richard Biener,
	Jakub Jelinek, Ramana Radhakrishnan, Richard Earnshaw

> I have committed it for you (rev 202831), with a few modifications
> (ChangeLog formatting, typos).
> Here is what I have committed:
> 
> 2013-09-23  Kugan Vivekanandarajah  <kuganv@linaro.org>
> 
>     * gimple-pretty-print.c (dump_ssaname_info): New function.
>     (dump_gimple_phi): Call it.
>     (pp_gimple_stmt_1): Likewise.
>     * tree-core.h (tree_ssa_name): New union ssa_name_info_type field.
>     (range_info_def): Declare.
>     * tree-pretty-print.c (pp_double_int): New function.
>     (dump_generic_node): Call it.
>     * tree-pretty-print.h (pp_double_int): Declare.
>     * tree-ssa-alias.c (dump_alias_info): Check pointer type.
>     * tree-ssanames.h (range_info_def): New structure.
>     (value_range_type): Move definition here.
>     (set_range_info, value_range_type, duplicate_ssa_name_range_info):
>     Declare.
>     * tree-ssanames.c (make_ssa_name_fn): Check pointer type at
>     initialization.
>     (set_range_info): New function.
>     (get_range_info): Likewise.
>     (duplicate_ssa_name_range_info): Likewise.
>     (duplicate_ssa_name_fn): Check pointer type and call
>     duplicate_ssa_name_range_info.
>     * tree-ssa-copy.c (fini_copy_prop): Likewise.
>     * tree-vrp.c (value_range_type): Remove definition, now in
>     tree-ssanames.h.
>     (vrp_finalize): Call set_range_info to update value range of
>     SSA_NAMEs.
>     * tree.h (SSA_NAME_PTR_INFO): Macro changed to access via union.
>     (SSA_NAME_RANGE_INFO): New macro.

Nice patch, but the formatting is totally wrong wrt spaces, please reformat 
using 2-space indentation and 8-space TABs, as already used in the files.

The patch has also introduced 2 regressions in Ada:

                === acats tests ===
FAIL:   c37211b
FAIL:   c37211c

                === acats Summary ===
# of expected passes            2318
# of unexpected failures        2


Program received signal SIGSEGV, Segmentation fault.
vrp_finalize () at /home/eric/svn/gcc/gcc/tree-vrp.c:9458
9458          if (POINTER_TYPE_P (TREE_TYPE (name))
(gdb) bt
#0  vrp_finalize () at /home/eric/svn/gcc/gcc/tree-vrp.c:9458
#1  execute_vrp () at /home/eric/svn/gcc/gcc/tree-vrp.c:9583
#2  (anonymous namespace)::pass_vrp::execute (this=<optimized out>)
    at /home/eric/svn/gcc/gcc/tree-vrp.c:9673
#3  0x0000000000c52c9a in execute_one_pass (pass=pass@entry=0x22e2210)
    at /home/eric/svn/gcc/gcc/passes.c:2201
#4  0x0000000000c52e76 in execute_pass_list (pass=0x22e2210)
    at /home/eric/svn/gcc/gcc/passes.c:2253
#5  0x0000000000c52e88 in execute_pass_list (pass=0x22e04d0)
    at /home/eric/svn/gcc/gcc/passes.c:2254
#6  0x00000000009b9c49 in expand_function (node=0x7ffff6d12e40)
    at /home/eric/svn/gcc/gcc/cgraphunit.c:1750
#7  0x00000000009bbc17 in expand_all_functions ()
    at /home/eric/svn/gcc/gcc/cgraphunit.c:1855
#8  compile () at /home/eric/svn/gcc/gcc/cgraphunit.c:2192
#9  0x00000000009bc1fa in finalize_compilation_unit ()
    at /home/eric/svn/gcc/gcc/cgraphunit.c:2269
#10 0x00000000006681b5 in gnat_write_global_declarations ()
    at /home/eric/svn/gcc/gcc/ada/gcc-interface/utils.c:5630
#11 0x0000000000d4577d in compile_file ()
    at /home/eric/svn/gcc/gcc/toplev.c:560
#12 0x0000000000d4750a in do_compile () at 
/home/eric/svn/gcc/gcc/toplev.c:1891
#13 toplev_main (argc=14, argv=0x7fffffffdca8)
    at /home/eric/svn/gcc/gcc/toplev.c:1967
#14 0x00007ffff6f2a23d in __libc_start_main () from /lib64/libc.so.6
#15 0x0000000000635381 in _start () at ../sysdeps/x86_64/elf/start.S:113
(gdb) p name
$1 = (tree) 0x0


-- 
Eric Botcazou

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-23 21:03                                               ` Eric Botcazou
@ 2013-09-24 10:13                                                 ` Richard Biener
  2013-09-24 10:34                                                   ` Kugan
  2013-09-24 10:45                                                   ` Richard Biener
  2013-09-24 16:25                                                 ` Christophe Lyon
  1 sibling, 2 replies; 38+ messages in thread
From: Richard Biener @ 2013-09-24 10:13 UTC (permalink / raw)
  To: Eric Botcazou
  Cc: Christophe Lyon, GCC Patches, Kugan, Richard Biener,
	Jakub Jelinek, Ramana Radhakrishnan, Richard Earnshaw

On Mon, Sep 23, 2013 at 10:34 PM, Eric Botcazou <ebotcazou@adacore.com> wrote:
>> I have committed it for you (rev 202831), with a few modifications
>> (ChangeLog formatting, typos).
>> Here is what I have committed:
>>
>> 2013-09-23  Kugan Vivekanandarajah  <kuganv@linaro.org>
>>
>>     * gimple-pretty-print.c (dump_ssaname_info): New function.
>>     (dump_gimple_phi): Call it.
>>     (pp_gimple_stmt_1): Likewise.
>>     * tree-core.h (tree_ssa_name): New union ssa_name_info_type field.
>>     (range_info_def): Declare.
>>     * tree-pretty-print.c (pp_double_int): New function.
>>     (dump_generic_node): Call it.
>>     * tree-pretty-print.h (pp_double_int): Declare.
>>     * tree-ssa-alias.c (dump_alias_info): Check pointer type.
>>     * tree-ssanames.h (range_info_def): New structure.
>>     (value_range_type): Move definition here.
>>     (set_range_info, value_range_type, duplicate_ssa_name_range_info):
>>     Declare.
>>     * tree-ssanames.c (make_ssa_name_fn): Check pointer type at
>>     initialization.
>>     (set_range_info): New function.
>>     (get_range_info): Likewise.
>>     (duplicate_ssa_name_range_info): Likewise.
>>     (duplicate_ssa_name_fn): Check pointer type and call
>>     duplicate_ssa_name_range_info.
>>     * tree-ssa-copy.c (fini_copy_prop): Likewise.
>>     * tree-vrp.c (value_range_type): Remove definition, now in
>>     tree-ssanames.h.
>>     (vrp_finalize): Call set_range_info to update value range of
>>     SSA_NAMEs.
>>     * tree.h (SSA_NAME_PTR_INFO): Macro changed to access via union.
>>     (SSA_NAME_RANGE_INFO): New macro.
>
> Nice patch, but the formatting is totally wrong wrt spaces, please reformat
> using 2-space indentation and 8-space TABs, as already used in the files.
>
> The patch has also introduced 2 regressions in Ada:
>
>                 === acats tests ===
> FAIL:   c37211b
> FAIL:   c37211c
>
>                 === acats Summary ===
> # of expected passes            2318
> # of unexpected failures        2
>
>
> Program received signal SIGSEGV, Segmentation fault.
> vrp_finalize () at /home/eric/svn/gcc/gcc/tree-vrp.c:9458
> 9458          if (POINTER_TYPE_P (TREE_TYPE (name))
> (gdb) bt

I'm testing a trivial patch to fix that.

Richard.

> #0  vrp_finalize () at /home/eric/svn/gcc/gcc/tree-vrp.c:9458
> #1  execute_vrp () at /home/eric/svn/gcc/gcc/tree-vrp.c:9583
> #2  (anonymous namespace)::pass_vrp::execute (this=<optimized out>)
>     at /home/eric/svn/gcc/gcc/tree-vrp.c:9673
> #3  0x0000000000c52c9a in execute_one_pass (pass=pass@entry=0x22e2210)
>     at /home/eric/svn/gcc/gcc/passes.c:2201
> #4  0x0000000000c52e76 in execute_pass_list (pass=0x22e2210)
>     at /home/eric/svn/gcc/gcc/passes.c:2253
> #5  0x0000000000c52e88 in execute_pass_list (pass=0x22e04d0)
>     at /home/eric/svn/gcc/gcc/passes.c:2254
> #6  0x00000000009b9c49 in expand_function (node=0x7ffff6d12e40)
>     at /home/eric/svn/gcc/gcc/cgraphunit.c:1750
> #7  0x00000000009bbc17 in expand_all_functions ()
>     at /home/eric/svn/gcc/gcc/cgraphunit.c:1855
> #8  compile () at /home/eric/svn/gcc/gcc/cgraphunit.c:2192
> #9  0x00000000009bc1fa in finalize_compilation_unit ()
>     at /home/eric/svn/gcc/gcc/cgraphunit.c:2269
> #10 0x00000000006681b5 in gnat_write_global_declarations ()
>     at /home/eric/svn/gcc/gcc/ada/gcc-interface/utils.c:5630
> #11 0x0000000000d4577d in compile_file ()
>     at /home/eric/svn/gcc/gcc/toplev.c:560
> #12 0x0000000000d4750a in do_compile () at
> /home/eric/svn/gcc/gcc/toplev.c:1891
> #13 toplev_main (argc=14, argv=0x7fffffffdca8)
>     at /home/eric/svn/gcc/gcc/toplev.c:1967
> #14 0x00007ffff6f2a23d in __libc_start_main () from /lib64/libc.so.6
> #15 0x0000000000635381 in _start () at ../sysdeps/x86_64/elf/start.S:113
> (gdb) p name
> $1 = (tree) 0x0
>
>
> --
> Eric Botcazou

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-24 10:13                                                 ` Richard Biener
@ 2013-09-24 10:34                                                   ` Kugan
  2013-09-24 10:45                                                   ` Richard Biener
  1 sibling, 0 replies; 38+ messages in thread
From: Kugan @ 2013-09-24 10:34 UTC (permalink / raw)
  To: Richard Biener, Eric Botcazou
  Cc: Christophe Lyon, GCC Patches, Richard Biener, Jakub Jelinek,
	Ramana Radhakrishnan, Richard Earnshaw

On 24/09/13 19:23, Richard Biener wrote:
> On Mon, Sep 23, 2013 at 10:34 PM, Eric Botcazou <ebotcazou@adacore.com> wrote:
>>> I have committed it for you (rev 202831), with a few modifications
>>> (ChangeLog formatting, typos).
>>> Here is what I have committed:
>>>
>>> 2013-09-23  Kugan Vivekanandarajah  <kuganv@linaro.org>
>>>
>>>      * gimple-pretty-print.c (dump_ssaname_info): New function.
>>>      (dump_gimple_phi): Call it.
>>>      (pp_gimple_stmt_1): Likewise.
>>>      * tree-core.h (tree_ssa_name): New union ssa_name_info_type field.
>>>      (range_info_def): Declare.
>>>      * tree-pretty-print.c (pp_double_int): New function.
>>>      (dump_generic_node): Call it.
>>>      * tree-pretty-print.h (pp_double_int): Declare.
>>>      * tree-ssa-alias.c (dump_alias_info): Check pointer type.
>>>      * tree-ssanames.h (range_info_def): New structure.
>>>      (value_range_type): Move definition here.
>>>      (set_range_info, value_range_type, duplicate_ssa_name_range_info):
>>>      Declare.
>>>      * tree-ssanames.c (make_ssa_name_fn): Check pointer type at
>>>      initialization.
>>>      (set_range_info): New function.
>>>      (get_range_info): Likewise.
>>>      (duplicate_ssa_name_range_info): Likewise.
>>>      (duplicate_ssa_name_fn): Check pointer type and call
>>>      duplicate_ssa_name_range_info.
>>>      * tree-ssa-copy.c (fini_copy_prop): Likewise.
>>>      * tree-vrp.c (value_range_type): Remove definition, now in
>>>      tree-ssanames.h.
>>>      (vrp_finalize): Call set_range_info to update value range of
>>>      SSA_NAMEs.
>>>      * tree.h (SSA_NAME_PTR_INFO): Macro changed to access via union.
>>>      (SSA_NAME_RANGE_INFO): New macro.
>>
>> Nice patch, but the formatting is totally wrong wrt spaces, please reformat
>> using 2-space indentation and 8-space TABs, as already used in the files.
>>

I am looking at everything and will send a patch to fix that.

>> The patch has also introduced 2 regressions in Ada:
>>
>>                  === acats tests ===
>> FAIL:   c37211b
>> FAIL:   c37211c
>>
>>                  === acats Summary ===
>> # of expected passes            2318
>> # of unexpected failures        2
>>

I am sorry I missed this as I didnt test ada. I wrongly assumed that all 
the frontends are enabled by dafault.

>>
>> Program received signal SIGSEGV, Segmentation fault.
>> vrp_finalize () at /home/eric/svn/gcc/gcc/tree-vrp.c:9458
>> 9458          if (POINTER_TYPE_P (TREE_TYPE (name))
>> (gdb) bt
>
> I'm testing a trivial patch to fix that.
>
I think the return value of ssa_name () (i.e. name) can be NULL and it 
has to be checked for NULL. In tree-vrp.c it is not checked in some 
other places related to debugging. In other places (eg. in 
tree-ssa-pre.c) there are checks .

Thanks for looking into it and I will wait for your fix.

Thanks,
Kugan


> Richard.
>
>> #0  vrp_finalize () at /home/eric/svn/gcc/gcc/tree-vrp.c:9458
>> #1  execute_vrp () at /home/eric/svn/gcc/gcc/tree-vrp.c:9583
>> #2  (anonymous namespace)::pass_vrp::execute (this=<optimized out>)
>>      at /home/eric/svn/gcc/gcc/tree-vrp.c:9673
>> #3  0x0000000000c52c9a in execute_one_pass (pass=pass@entry=0x22e2210)
>>      at /home/eric/svn/gcc/gcc/passes.c:2201
>> #4  0x0000000000c52e76 in execute_pass_list (pass=0x22e2210)
>>      at /home/eric/svn/gcc/gcc/passes.c:2253
>> #5  0x0000000000c52e88 in execute_pass_list (pass=0x22e04d0)
>>      at /home/eric/svn/gcc/gcc/passes.c:2254
>> #6  0x00000000009b9c49 in expand_function (node=0x7ffff6d12e40)
>>      at /home/eric/svn/gcc/gcc/cgraphunit.c:1750
>> #7  0x00000000009bbc17 in expand_all_functions ()
>>      at /home/eric/svn/gcc/gcc/cgraphunit.c:1855
>> #8  compile () at /home/eric/svn/gcc/gcc/cgraphunit.c:2192
>> #9  0x00000000009bc1fa in finalize_compilation_unit ()
>>      at /home/eric/svn/gcc/gcc/cgraphunit.c:2269
>> #10 0x00000000006681b5 in gnat_write_global_declarations ()
>>      at /home/eric/svn/gcc/gcc/ada/gcc-interface/utils.c:5630
>> #11 0x0000000000d4577d in compile_file ()
>>      at /home/eric/svn/gcc/gcc/toplev.c:560
>> #12 0x0000000000d4750a in do_compile () at
>> /home/eric/svn/gcc/gcc/toplev.c:1891
>> #13 toplev_main (argc=14, argv=0x7fffffffdca8)
>>      at /home/eric/svn/gcc/gcc/toplev.c:1967
>> #14 0x00007ffff6f2a23d in __libc_start_main () from /lib64/libc.so.6
>> #15 0x0000000000635381 in _start () at ../sysdeps/x86_64/elf/start.S:113
>> (gdb) p name
>> $1 = (tree) 0x0
>>
>>
>> --
>> Eric Botcazou

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-24 10:13                                                 ` Richard Biener
  2013-09-24 10:34                                                   ` Kugan
@ 2013-09-24 10:45                                                   ` Richard Biener
  1 sibling, 0 replies; 38+ messages in thread
From: Richard Biener @ 2013-09-24 10:45 UTC (permalink / raw)
  To: Richard Biener
  Cc: Eric Botcazou, Christophe Lyon, GCC Patches, Kugan,
	Jakub Jelinek, Ramana Radhakrishnan, Richard Earnshaw

On Tue, 24 Sep 2013, Richard Biener wrote:

> On Mon, Sep 23, 2013 at 10:34 PM, Eric Botcazou <ebotcazou@adacore.com> wrote:
> >> I have committed it for you (rev 202831), with a few modifications
> >> (ChangeLog formatting, typos).
> >> Here is what I have committed:
> >>
> >> 2013-09-23  Kugan Vivekanandarajah  <kuganv@linaro.org>
> >>
> >>     * gimple-pretty-print.c (dump_ssaname_info): New function.
> >>     (dump_gimple_phi): Call it.
> >>     (pp_gimple_stmt_1): Likewise.
> >>     * tree-core.h (tree_ssa_name): New union ssa_name_info_type field.
> >>     (range_info_def): Declare.
> >>     * tree-pretty-print.c (pp_double_int): New function.
> >>     (dump_generic_node): Call it.
> >>     * tree-pretty-print.h (pp_double_int): Declare.
> >>     * tree-ssa-alias.c (dump_alias_info): Check pointer type.
> >>     * tree-ssanames.h (range_info_def): New structure.
> >>     (value_range_type): Move definition here.
> >>     (set_range_info, value_range_type, duplicate_ssa_name_range_info):
> >>     Declare.
> >>     * tree-ssanames.c (make_ssa_name_fn): Check pointer type at
> >>     initialization.
> >>     (set_range_info): New function.
> >>     (get_range_info): Likewise.
> >>     (duplicate_ssa_name_range_info): Likewise.
> >>     (duplicate_ssa_name_fn): Check pointer type and call
> >>     duplicate_ssa_name_range_info.
> >>     * tree-ssa-copy.c (fini_copy_prop): Likewise.
> >>     * tree-vrp.c (value_range_type): Remove definition, now in
> >>     tree-ssanames.h.
> >>     (vrp_finalize): Call set_range_info to update value range of
> >>     SSA_NAMEs.
> >>     * tree.h (SSA_NAME_PTR_INFO): Macro changed to access via union.
> >>     (SSA_NAME_RANGE_INFO): New macro.
> >
> > Nice patch, but the formatting is totally wrong wrt spaces, please reformat
> > using 2-space indentation and 8-space TABs, as already used in the files.
> >
> > The patch has also introduced 2 regressions in Ada:
> >
> >                 === acats tests ===
> > FAIL:   c37211b
> > FAIL:   c37211c
> >
> >                 === acats Summary ===
> > # of expected passes            2318
> > # of unexpected failures        2
> >
> >
> > Program received signal SIGSEGV, Segmentation fault.
> > vrp_finalize () at /home/eric/svn/gcc/gcc/tree-vrp.c:9458
> > 9458          if (POINTER_TYPE_P (TREE_TYPE (name))
> > (gdb) bt
> 
> I'm testing a trivial patch to fix that.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2013-09-24  Richard Biener  <rguenther@suse.de>

	* tree-vrp.c (vrp_finalize): Check for SSA name presence.

Index: gcc/tree-vrp.c
===================================================================
--- gcc/tree-vrp.c	(revision 202860)
+++ gcc/tree-vrp.c	(working copy)
@@ -9455,7 +9455,8 @@ vrp_finalize (void)
     {
       tree name = ssa_name (i);
 
-      if (POINTER_TYPE_P (TREE_TYPE (name))
+      if (!name
+	  || POINTER_TYPE_P (TREE_TYPE (name))
           || (vr_value[i]->type == VR_VARYING)
           || (vr_value[i]->type == VR_UNDEFINED))
         continue;

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-23 21:03                                               ` Eric Botcazou
  2013-09-24 10:13                                                 ` Richard Biener
@ 2013-09-24 16:25                                                 ` Christophe Lyon
  2013-09-25 18:04                                                   ` Eric Botcazou
  1 sibling, 1 reply; 38+ messages in thread
From: Christophe Lyon @ 2013-09-24 16:25 UTC (permalink / raw)
  To: Eric Botcazou
  Cc: gcc-patches, Richard Biener, Kugan, Richard Biener,
	Jakub Jelinek, Ramana Radhakrishnan, Richard Earnshaw

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

On 23 September 2013 22:34, Eric Botcazou <ebotcazou@adacore.com> wrote:
> Nice patch, but the formatting is totally wrong wrt spaces, please reformat
> using 2-space indentation and 8-space TABs, as already used in the files.
>

Sorry for missing this problem when committing Kugan's patch.

I have just committed the attached patch, which I hope fixes all the
spaces/indentation issues introduced.

Christophe.

2013-09-24  Christophe Lyon  <christophe.lyon@linaro.org>

    * gimple-pretty-print.c: Various whitespace tweaks.
    * tree-core.h: Likewise.
    * tree-pretty-print.c: Likewise.
    * tree-ssa-alias.c: Likewise.
    * tree-ssa-copy.c: Likewise.
    * tree-ssanames.c: Likewise.
    * tree-ssanames.h: Likewise.
    * tree-vrp.c: Likewise.

[-- Attachment #2: spaces.txt --]
[-- Type: text/plain, Size: 10815 bytes --]

Index: gcc/tree-vrp.c
===================================================================
--- gcc/tree-vrp.c	(revision 202868)
+++ gcc/tree-vrp.c	(revision 202869)
@@ -9451,48 +9451,48 @@ vrp_finalize (void)
 
   /* Set value range to non pointer SSA_NAMEs.  */
   for (i  = 0; i < num_vr_values; i++)
-   if (vr_value[i])
-    {
-      tree name = ssa_name (i);
+    if (vr_value[i])
+      {
+	tree name = ssa_name (i);
 
       if (!name
 	  || POINTER_TYPE_P (TREE_TYPE (name))
-          || (vr_value[i]->type == VR_VARYING)
-          || (vr_value[i]->type == VR_UNDEFINED))
-        continue;
-
-      if ((TREE_CODE (vr_value[i]->min) == INTEGER_CST)
-          && (TREE_CODE (vr_value[i]->max) == INTEGER_CST))
-        {
-          if (vr_value[i]->type == VR_RANGE)
-            set_range_info (name,
-                            tree_to_double_int (vr_value[i]->min),
-                            tree_to_double_int (vr_value[i]->max));
-          else if (vr_value[i]->type == VR_ANTI_RANGE)
-            {
-              /* VR_ANTI_RANGE ~[min, max] is encoded compactly as
-                 [max + 1, min - 1] without additional attributes.
-                 When min value > max value, we know that it is
-                 VR_ANTI_RANGE; it is VR_RANGE otherwise.  */
-
-	      /* ~[0,0] anti-range is represented as
-                 range.  */
-              if (TYPE_UNSIGNED (TREE_TYPE (name))
-                  && integer_zerop (vr_value[i]->min)
-                  && integer_zerop (vr_value[i]->max))
-                set_range_info (name,
-                                double_int_one,
-                                double_int::max_value
-                                (TYPE_PRECISION (TREE_TYPE (name)), true));
-              else
-                set_range_info (name,
-                                tree_to_double_int (vr_value[i]->max)
-                                + double_int_one,
-                                tree_to_double_int (vr_value[i]->min)
-                                - double_int_one);
-            }
-        }
-    }
+	  || (vr_value[i]->type == VR_VARYING)
+	  || (vr_value[i]->type == VR_UNDEFINED))
+	continue;
+
+	if ((TREE_CODE (vr_value[i]->min) == INTEGER_CST)
+	    && (TREE_CODE (vr_value[i]->max) == INTEGER_CST))
+	  {
+	    if (vr_value[i]->type == VR_RANGE)
+	      set_range_info (name,
+			      tree_to_double_int (vr_value[i]->min),
+			      tree_to_double_int (vr_value[i]->max));
+	    else if (vr_value[i]->type == VR_ANTI_RANGE)
+	      {
+		/* VR_ANTI_RANGE ~[min, max] is encoded compactly as
+		   [max + 1, min - 1] without additional attributes.
+		   When min value > max value, we know that it is
+		   VR_ANTI_RANGE; it is VR_RANGE otherwise.  */
+
+		/* ~[0,0] anti-range is represented as
+		   range.  */
+		if (TYPE_UNSIGNED (TREE_TYPE (name))
+		    && integer_zerop (vr_value[i]->min)
+		    && integer_zerop (vr_value[i]->max))
+		  set_range_info (name,
+				  double_int_one,
+				  double_int::max_value
+				  (TYPE_PRECISION (TREE_TYPE (name)), true));
+		else
+		  set_range_info (name,
+				  tree_to_double_int (vr_value[i]->max)
+				  + double_int_one,
+				  tree_to_double_int (vr_value[i]->min)
+				  - double_int_one);
+	      }
+	  }
+      }
 
   /* Free allocated memory.  */
   for (i = 0; i < num_vr_values; i++)
Index: gcc/tree-pretty-print.c
===================================================================
--- gcc/tree-pretty-print.c	(revision 202868)
+++ gcc/tree-pretty-print.c	(revision 202869)
@@ -1063,8 +1063,8 @@ dump_generic_node (pretty_printer *buffe
 	  pp_string (buffer, "B"); /* pseudo-unit */
 	}
       else
-        pp_double_int (buffer, tree_to_double_int (node),
-                       TYPE_UNSIGNED (TREE_TYPE (node)));
+	pp_double_int (buffer, tree_to_double_int (node),
+		       TYPE_UNSIGNED (TREE_TYPE (node)));
       break;
 
     case REAL_CST:
@@ -3191,16 +3191,16 @@ pp_double_int (pretty_printer *pp, doubl
       unsigned HOST_WIDE_INT low = d.low;
       HOST_WIDE_INT high = d.high;
       if (!uns && d.is_negative ())
-        {
-          pp_minus (pp);
-          high = ~high + !low;
-          low = -low;
-        }
+	{
+	  pp_minus (pp);
+	  high = ~high + !low;
+	  low = -low;
+	}
       /* Would "%x%0*x" or "%x%*0x" get zero-padding on all
-         systems?  */
+	 systems?  */
       sprintf (pp_buffer (pp)->digit_buffer,
-               HOST_WIDE_INT_PRINT_DOUBLE_HEX,
-               (unsigned HOST_WIDE_INT) high, low);
+	       HOST_WIDE_INT_PRINT_DOUBLE_HEX,
+	       (unsigned HOST_WIDE_INT) high, low);
       pp_string (pp, pp_buffer (pp)->digit_buffer);
     }
 }
Index: gcc/tree-ssa-alias.c
===================================================================
--- gcc/tree-ssa-alias.c	(revision 202868)
+++ gcc/tree-ssa-alias.c	(revision 202869)
@@ -404,7 +404,7 @@ dump_alias_info (FILE *file)
       struct ptr_info_def *pi;
 
       if (ptr == NULL_TREE
-          || !POINTER_TYPE_P (TREE_TYPE (ptr))
+	  || !POINTER_TYPE_P (TREE_TYPE (ptr))
 	  || SSA_NAME_IN_FREE_LIST (ptr))
 	continue;
 
Index: gcc/gimple-pretty-print.c
===================================================================
--- gcc/gimple-pretty-print.c	(revision 202868)
+++ gcc/gimple-pretty-print.c	(revision 202869)
@@ -1632,17 +1632,17 @@ dump_ssaname_info (pretty_printer *buffe
       value_range_type range_type = get_range_info (node, &min, &max);
 
       if (range_type == VR_VARYING)
-        pp_printf (buffer, "# RANGE  VR_VARYING");
+	pp_printf (buffer, "# RANGE  VR_VARYING");
       else if (range_type == VR_RANGE || range_type == VR_ANTI_RANGE)
-        {
-          pp_printf (buffer, "# RANGE ");
-          pp_printf (buffer, "%s[", range_type == VR_RANGE ? "" : "~");
-          pp_double_int (buffer, min, TYPE_UNSIGNED (TREE_TYPE (node)));
-          pp_printf (buffer, ", ");
-          pp_double_int (buffer, max, TYPE_UNSIGNED (TREE_TYPE (node)));
-          pp_printf (buffer, "]");
-          newline_and_indent (buffer, spc);
-        }
+	{
+	  pp_printf (buffer, "# RANGE ");
+	  pp_printf (buffer, "%s[", range_type == VR_RANGE ? "" : "~");
+	  pp_double_int (buffer, min, TYPE_UNSIGNED (TREE_TYPE (node)));
+	  pp_printf (buffer, ", ");
+	  pp_double_int (buffer, max, TYPE_UNSIGNED (TREE_TYPE (node)));
+	  pp_printf (buffer, "]");
+	  newline_and_indent (buffer, spc);
+	}
     }
 }
 
@@ -1661,8 +1661,8 @@ dump_gimple_phi (pretty_printer *buffer,
     dump_ssaname_info (buffer, lhs, spc);
 
   if (flags & TDF_RAW)
-      dump_gimple_fmt (buffer, spc, flags, "%G <%T, ", phi,
-                       gimple_phi_result (phi));
+    dump_gimple_fmt (buffer, spc, flags, "%G <%T, ", phi,
+		     gimple_phi_result (phi));
   else
     {
       dump_generic_node (buffer, lhs, spc, flags, false);
Index: gcc/tree-ssa-copy.c
===================================================================
--- gcc/tree-ssa-copy.c	(revision 202868)
+++ gcc/tree-ssa-copy.c	(revision 202869)
@@ -767,19 +767,19 @@ fini_copy_prop (void)
 	 of the representative to the first solution we find if
 	 it doesn't have one already.  */
       if (copy_of[i].value != var
-          && TREE_CODE (copy_of[i].value) == SSA_NAME)
-        {
-          if (POINTER_TYPE_P (TREE_TYPE (var))
-              && SSA_NAME_PTR_INFO (var)
-              && !SSA_NAME_PTR_INFO (copy_of[i].value))
-            duplicate_ssa_name_ptr_info (copy_of[i].value,
-                                         SSA_NAME_PTR_INFO (var));
-          else if (!POINTER_TYPE_P (TREE_TYPE (var))
-                   && SSA_NAME_RANGE_INFO (var)
-                   && !SSA_NAME_RANGE_INFO (copy_of[i].value))
-            duplicate_ssa_name_range_info (copy_of[i].value,
-                                           SSA_NAME_RANGE_INFO (var));
-        }
+	  && TREE_CODE (copy_of[i].value) == SSA_NAME)
+	{
+	  if (POINTER_TYPE_P (TREE_TYPE (var))
+	      && SSA_NAME_PTR_INFO (var)
+	      && !SSA_NAME_PTR_INFO (copy_of[i].value))
+	    duplicate_ssa_name_ptr_info (copy_of[i].value,
+					 SSA_NAME_PTR_INFO (var));
+	  else if (!POINTER_TYPE_P (TREE_TYPE (var))
+		   && SSA_NAME_RANGE_INFO (var)
+		   && !SSA_NAME_RANGE_INFO (copy_of[i].value))
+	    duplicate_ssa_name_range_info (copy_of[i].value,
+					   SSA_NAME_RANGE_INFO (var));
+	}
     }
 
   /* Don't do DCE if SCEV is initialized.  It would destroy the scev cache.  */
Index: gcc/tree-core.h
===================================================================
--- gcc/tree-core.h	(revision 202868)
+++ gcc/tree-core.h	(revision 202869)
@@ -1058,7 +1058,7 @@ struct GTY(()) tree_ssa_name {
     /* Value range attributes used for zero/sign extension elimination.  */
     struct GTY ((tag ("1"))) range_info_def *range_info;
   } GTY ((desc ("%1.typed.type ?" \
-                "!POINTER_TYPE_P (TREE_TYPE ((tree)&%1)) : 2"))) info;
+		"!POINTER_TYPE_P (TREE_TYPE ((tree)&%1)) : 2"))) info;
 
   /* Immediate uses list for this SSA_NAME.  */
   struct ssa_use_operand_d imm_uses;
Index: gcc/tree-ssanames.c
===================================================================
--- gcc/tree-ssanames.c	(revision 202868)
+++ gcc/tree-ssanames.c	(revision 202869)
@@ -206,7 +206,7 @@ get_range_info (tree name, double_int *m
   /* Return VR_VARYING for SSA_NAMEs with NULL RANGE_INFO or SSA_NAMEs
      with integral types width > 2 * HOST_BITS_PER_WIDE_INT precision.  */
   if (!ri || (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (name)))
-              > 2 * HOST_BITS_PER_WIDE_INT))
+	      > 2 * HOST_BITS_PER_WIDE_INT))
     return VR_VARYING;
 
   /* If min > max, it is VR_ANTI_RANGE.  */
@@ -455,14 +455,14 @@ duplicate_ssa_name_fn (struct function *
       struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
 
       if (old_ptr_info)
-        duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+	duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
     }
   else
     {
       struct range_info_def *old_range_info = SSA_NAME_RANGE_INFO (name);
 
       if (old_range_info)
-        duplicate_ssa_name_range_info (new_name, old_range_info);
+	duplicate_ssa_name_range_info (new_name, old_range_info);
     }
 
   return new_name;
Index: gcc/tree-ssanames.h
===================================================================
--- gcc/tree-ssanames.h	(revision 202868)
+++ gcc/tree-ssanames.h	(revision 202869)
@@ -71,7 +71,7 @@ enum value_range_type { VR_UNDEFINED, VR
 extern void set_range_info (tree ssa, double_int min, double_int max);
 /* Gets the value range from SSA.  */
 extern enum value_range_type  get_range_info (tree name, double_int *min,
-                                              double_int *max);
+					      double_int *max);
 extern void init_ssanames (struct function *, int);
 extern void fini_ssanames (void);
 extern void ssanames_print_statistics (void);

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

* Re: [ping][PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL
  2013-09-24 16:25                                                 ` Christophe Lyon
@ 2013-09-25 18:04                                                   ` Eric Botcazou
  0 siblings, 0 replies; 38+ messages in thread
From: Eric Botcazou @ 2013-09-25 18:04 UTC (permalink / raw)
  To: Christophe Lyon
  Cc: gcc-patches, Richard Biener, Kugan, Richard Biener,
	Jakub Jelinek, Ramana Radhakrishnan, Richard Earnshaw

> Sorry for missing this problem when committing Kugan's patch.
> 
> I have just committed the attached patch, which I hope fixes all the
> spaces/indentation issues introduced.

Thanks a lot!

-- 
Eric Botcazou

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

end of thread, other threads:[~2013-09-25 17:34 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-03  2:14 [PATCH][1 of 2] Add value range info to SSA_NAME for zero sign extension elimination in RTL Kugan
2013-06-17  1:31 ` [ping][PATCH][1 " Kugan
2013-06-17  9:03   ` Richard Biener
2013-07-03 12:26     ` Kugan
2013-08-14  7:19       ` Kugan
2013-09-02  9:31         ` Kugan
2013-09-02 12:45       ` Richard Biener
2013-09-03 12:15         ` Kugan
2013-09-06  6:47           ` Richard Biener
2013-09-09  0:15             ` Kugan
2013-09-09  9:37               ` Richard Biener
2013-09-10  5:27                 ` Kugan
2013-09-10 13:29                   ` Richard Biener
2013-09-10 13:49                     ` Jakub Jelinek
2013-09-11  7:01                       ` Kugan
2013-09-11  9:11                         ` Richard Biener
2013-09-11  9:54                           ` Jakub Jelinek
2013-09-11 10:00                             ` Richard Biener
2013-09-13  6:17                               ` Kugan
2013-09-16  6:46                                 ` Kugan
2013-09-16 14:32                                   ` Richard Biener
2013-09-18  7:24                                     ` Kugan
2013-09-18  9:45                                       ` Richard Biener
2013-09-19  7:25                                         ` Kugan
2013-09-23 11:39                                           ` Richard Biener
2013-09-23 15:55                                             ` Christophe Lyon
2013-09-23 21:03                                               ` Eric Botcazou
2013-09-24 10:13                                                 ` Richard Biener
2013-09-24 10:34                                                   ` Kugan
2013-09-24 10:45                                                   ` Richard Biener
2013-09-24 16:25                                                 ` Christophe Lyon
2013-09-25 18:04                                                   ` Eric Botcazou
2013-09-18  9:07                                     ` Richard Earnshaw
2013-09-18  9:12                                       ` Richard Biener
2013-09-18  9:16                                         ` Jakub Jelinek
2013-09-18  9:26                                           ` Jan Hubicka
2013-09-18 10:21                                             ` Richard Biener
2013-09-11  6:39                     ` Kugan

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