Hi!

The following patch implements what I've mentioned in the 64-bit
location_t thread.
struct tree_exp had unsigned condition_uid member added for something
rarely used (-fcondition-coverage) and even there used only on very small
subset of trees only for the duration of the gimplification.

The following patch uses a hash_map instead, which allows shrinking
tree_exp to its previous size (32 bytes + (number of operands - 1) * sizeof
(tree)).

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

2024-12-14  Jakub Jelinek  <ja...@redhat.com>

        * tree-core.h (struct tree_exp): Remove condition_uid member.
        * tree.h (SET_EXPR_UID, EXPR_COND_UID): Remove.
        * gimplify.cc (nextuid): Rename to ...
        (nextconduid): ... this.
        (cond_uids): New static variable.
        (next_cond_uid, reset_cond_uid): Adjust for the renaming,
        formatting fix.
        (tree_associate_condition_with_expr): New function.
        (shortcut_cond_r, tag_shortcut_cond, shortcut_cond_expr): Use it
        instead of SET_EXPR_UID.
        (gimplify_cond_expr): Look up cond_uid in cond_uids hash map if
        non-NULL instead of using EXPR_COND_UID.
        (gimplify_function_tree): Delete cond_uids and set it to NULL.

--- gcc/tree-core.h.jj  2024-12-11 17:27:52.686218415 +0100
+++ gcc/tree-core.h     2024-12-14 11:35:37.474933446 +0100
@@ -1670,9 +1670,6 @@ enum omp_clause_linear_kind
 struct GTY(()) tree_exp {
   struct tree_typed typed;
   location_t locus;
-  /* Discriminator for basic conditions in a Boolean expressions.  Trees that
-     are operands of the same Boolean expression should have the same uid.  */
-  unsigned condition_uid;
   tree GTY ((length ("TREE_OPERAND_LENGTH ((tree)&%h)"))) operands[1];
 };
 
--- gcc/tree.h.jj       2024-12-06 09:08:20.940872922 +0100
+++ gcc/tree.h  2024-12-14 11:36:26.610255103 +0100
@@ -1373,10 +1373,6 @@ class auto_suppress_location_wrappers
   ~auto_suppress_location_wrappers () { --suppress_location_wrappers; }
 };
 
-/* COND_EXPR identificer/discriminator accessors.  */
-#define SET_EXPR_UID(t, v) EXPR_CHECK ((t))->exp.condition_uid = (v)
-#define EXPR_COND_UID(t) EXPR_CHECK ((t))->exp.condition_uid
-
 /* In a TARGET_EXPR node.  */
 #define TARGET_EXPR_SLOT(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 0)
 #define TARGET_EXPR_INITIAL(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 
1)
--- gcc/gimplify.cc.jj  2024-12-12 19:46:59.723178720 +0100
+++ gcc/gimplify.cc     2024-12-14 15:02:53.588744025 +0100
@@ -76,14 +76,20 @@ along with GCC; see the file COPYING3.
    its Boolean expression.  Basic conditions given the same uid (in the same
    function) are parts of the same ANDIF/ORIF expression.  Used for condition
    coverage.  */
-static unsigned nextuid = 1;
+static unsigned nextconduid = 1;
+
+/* Annotated gconds so that basic conditions in the same expression map to
+   the same uid.  This is used for condition coverage.  */
+static hash_map <tree, unsigned> *cond_uids;
+
 /* Get a fresh identifier for a new condition expression.  This is used for
    condition coverage.  */
 static unsigned
 next_cond_uid ()
 {
-    return nextuid++;
+  return nextconduid++;
 }
+
 /* Reset the condition uid to the value it should have when compiling a new
    function.  0 is already the default/untouched value, so start at non-zero.
    A valid and set id should always be > 0.  This is used for condition
@@ -91,7 +97,24 @@ next_cond_uid ()
 static void
 reset_cond_uid ()
 {
-    nextuid = 1;
+  nextconduid = 1;
+}
+
+/* Associate the condition STMT with the discriminator UID.  STMTs that are
+   broken down with ANDIF/ORIF from the same Boolean expression should be given
+   the same UID; 'if (a && b && c) { if (d || e) ... } ...' should yield the
+   { a: 1, b: 1, c: 1, d: 2, e: 2 } when gimplification is done.  This is used
+   for condition coverage.  */
+static void
+tree_associate_condition_with_expr (tree stmt, unsigned uid)
+{
+  if (!condition_coverage_flag)
+    return;
+
+  if (!cond_uids)
+    cond_uids = new hash_map <tree, unsigned> ();
+
+  cond_uids->put (stmt, uid);
 }
 
 /* Hash set of poisoned variables in a bind expr.  */
@@ -4443,7 +4466,7 @@ shortcut_cond_r (tree pred, tree *true_l
                     shortcut_cond_r (TREE_OPERAND (pred, 2), true_label_p,
                                      false_label_p, new_locus,
                                      condition_uid));
-      SET_EXPR_UID (expr, condition_uid);
+      tree_associate_condition_with_expr (expr, condition_uid);
     }
   else
     {
@@ -4451,7 +4474,7 @@ shortcut_cond_r (tree pred, tree *true_l
                     build_and_jump (true_label_p),
                     build_and_jump (false_label_p));
       SET_EXPR_LOCATION (expr, locus);
-      SET_EXPR_UID (expr, condition_uid);
+      tree_associate_condition_with_expr (expr, condition_uid);
     }
 
   if (local_label)
@@ -4523,13 +4546,13 @@ tag_shortcut_cond (tree pred, unsigned c
          || TREE_CODE (fst) == TRUTH_ORIF_EXPR)
        tag_shortcut_cond (fst, condition_uid);
       else if (TREE_CODE (fst) == COND_EXPR)
-       SET_EXPR_UID (fst, condition_uid);
+       tree_associate_condition_with_expr (fst, condition_uid);
 
       if (TREE_CODE (lst) == TRUTH_ANDIF_EXPR
          || TREE_CODE (lst) == TRUTH_ORIF_EXPR)
        tag_shortcut_cond (lst, condition_uid);
       else if (TREE_CODE (lst) == COND_EXPR)
-       SET_EXPR_UID (lst, condition_uid);
+       tree_associate_condition_with_expr (lst, condition_uid);
     }
 }
 
@@ -4599,7 +4622,7 @@ shortcut_cond_expr (tree expr, unsigned
     }
 
   /* The expr tree should also have the expression id set.  */
-  SET_EXPR_UID (expr, condition_uid);
+  tree_associate_condition_with_expr (expr, condition_uid);
 
   /* If we're done, great.  */
   if (TREE_CODE (pred) != TRUTH_ANDIF_EXPR
@@ -5040,7 +5063,10 @@ gimplify_cond_expr (tree *expr_p, gimple
   else
     label_false = create_artificial_label (UNKNOWN_LOCATION);
 
-  unsigned cond_uid = EXPR_COND_UID (expr);
+  unsigned cond_uid = 0;
+  if (cond_uids)
+    if (unsigned *v = cond_uids->get (expr))
+      cond_uid = *v;
   if (cond_uid == 0)
     cond_uid = next_cond_uid ();
 
@@ -20178,6 +20204,11 @@ gimplify_function_tree (tree fndecl)
     push_struct_function (fndecl);
 
   reset_cond_uid ();
+  if (cond_uids)
+    {
+      delete cond_uids;
+      cond_uids = NULL;
+    }
 
   /* Tentatively set PROP_gimple_lva here, and reset it in gimplify_va_arg_expr
      if necessary.  */

        Jakub

Reply via email to