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