> gcc/ChangeLog:
> 
>         * Makefile.in: Add hierarchical_discriminator.o to OBJS.
>         * hierarchical_discriminator.cc: New file.
>         * hierarchical_discriminator.h: New file.
>         * input.cc (location_with_discriminator_components): New function.
>         (get_discriminator_components_from_loc): Likewise.
>         * input.h (DISCR_BASE_BITS): New constant.
>         (DISCR_MULTIPLICITY_BITS): Likewise.
>         (DISCR_COPYID_BITS): Likewise.
>         (DISCR_UNUSED_BITS): Likewise.
>         (DISCR_BASE_MASK): Likewise.
>         (DISCR_MULTIPLICITY_MASK): Likewise.
>         (DISCR_COPYID_MASK): Likewise.
>         (DISCR_BASE_SHIFT): Likewise.
>         (DISCR_MULTIPLICITY_SHIFT): Likewise.
>         (DISCR_COPYID_SHIFT): Likewise.
>         (DISCR_BASE_MAX): Likewise.
>         (DISCR_MULTIPLICITY_MAX): Likewise.
>         (DISCR_COPYID_MAX): Likewise.
>         (location_with_discriminator_components): New function declaration.
>         (get_discriminator_components_from_loc): Likewise.
> 
> Signed-off-by: Kugan Vivekanandarajah <[email protected]>
> 
> Thanks,
> Kugan
> 
> 
> From 46968fce3960772ddbefb9e62bde7512fd8fb8b3 Mon Sep 17 00:00:00 2001
> From: Kugan Vivekanandarajah <[email protected]>
> Date: Tue, 11 Nov 2025 18:00:08 -0800
> Subject: [PATCH 1/4] [Autofdo] Add hierarchical discriminator support
> 
> This patch introduces the basic infrastructure for hierarchical
> discriminators with format [Base:8][Multiplicity:7][CopyID:11][Unused:6].
> It adds helper functions to create and extract discriminator components.
> 
> gcc/ChangeLog:
> 
>       * Makefile.in: Add hierarchical_discriminator.o to OBJS.
>       * hierarchical_discriminator.cc: New file.
>       * hierarchical_discriminator.h: New file.
>       * input.cc (location_with_discriminator_components): New function.
>       (get_discriminator_components_from_loc): Likewise.
>       * input.h (DISCR_BASE_BITS): New constant.
>       (DISCR_MULTIPLICITY_BITS): Likewise.
>       (DISCR_COPYID_BITS): Likewise.
>       (DISCR_UNUSED_BITS): Likewise.
>       (DISCR_BASE_MASK): Likewise.
>       (DISCR_MULTIPLICITY_MASK): Likewise.
>       (DISCR_COPYID_MASK): Likewise.
>       (DISCR_BASE_SHIFT): Likewise.
>       (DISCR_MULTIPLICITY_SHIFT): Likewise.
>       (DISCR_COPYID_SHIFT): Likewise.
>       (DISCR_BASE_MAX): Likewise.
>       (DISCR_MULTIPLICITY_MAX): Likewise.
>       (DISCR_COPYID_MAX): Likewise.
>       (location_with_discriminator_components): New function declaration.
>       (get_discriminator_components_from_loc): Likewise.
> 
> Signed-off-by: Kugan Vivekanandarajah <[email protected]>
> ---
>  gcc/Makefile.in                   |   1 +
>  gcc/hierarchical_discriminator.cc | 108 ++++++++++++++++++++++++++++++
>  gcc/hierarchical_discriminator.h  |  80 ++++++++++++++++++++++
>  gcc/input.cc                      |  35 ++++++++++
>  gcc/input.h                       |  40 +++++++++++
>  5 files changed, 264 insertions(+)
>  create mode 100644 gcc/hierarchical_discriminator.cc
>  create mode 100644 gcc/hierarchical_discriminator.h
> 

> +/* Assign discriminators to all statements in a basic block.  This
> +   function updates the multiplicity and/or copyid discriminator components 
> for
> +   all statements in the given basic block, while preserving the base
> +   discriminator.  */
> +
> +void
> +assign_discriminators_to_bb (basic_block bb,
> +                          unsigned int multiplicity_value,
> +                          unsigned int copyid_value,
> +                          bool update_multiplicity,
> +                          bool update_copyid)

I would also add stmt version....
> +{
> +  gimple_stmt_iterator gsi;
> +
> +  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
> +    {
> +      gimple *stmt = gsi_stmt (gsi);
> +      location_t loc = gimple_location (stmt);
> +
> +      if (loc == UNKNOWN_LOCATION || is_gimple_debug (stmt))
> +     continue;
> +
> +      /* Get existing discriminator components.  */
> +      unsigned int base, multiplicity, copyid;
> +      get_discriminator_components_from_loc (loc, &base,
> +                                          &multiplicity, &copyid);
> +
> +      /* Update requested components.  */
> +      if (update_multiplicity)
> +     multiplicity = multiplicity_value;

I wonder if it should not be multiplicity *=, since transformations can
combine.
> +      if (update_copyid)
> +     copyid = copyid_value;
> +
> +      /* Set new location.  */
> +      location_t new_loc = location_with_discriminator_components (loc, base,
> +                                                                multiplicity,
> +                                                                copyid);
> +      gimple_set_location (stmt, new_loc);
...
the reason is that there are some extra locators to update.  PHI
statmenets, goto edges and also locations which can be placed in stmt
operands.
> +
> +/* Hierarchical discriminator layout (32 bits total):
> +   Discriminator format: [Base:8][Multiplicity:7][CopyID:11][Unused:6]
> +   - Base: bits 0-7 (8 bits, 0-255)
> +   - Multiplicity: bits 8-14 (7 bits, 0-127)
> +   - CopyID: bits 15-25 (11 bits, 0-2047)
> +   - Unused: bits 26-31 (6 bits, reserved)
> +
> +   Base discriminator: Used by front-end and early passes to distinguish
> +                    different statements on the same source line.
> +
> +   Multiplicity: Duplication factor for unrolling/vectorization.
> +              Represents how many times code is duplicated:
> +              - Loop unrolling factor
> +              - Vectorization width
> +
> +   CopyID: Unique identifier for code copies to distinguish:
> +        - Inlining contexts (different callsites)
> +        - Function cloning
> +
> +   Note: Loop unrolling and versioning use multiplicity, not copyid.
> + */
> +
> +/* Loop versioning discriminators (CopyID values).  */
> +#define DISCRIMINATOR_LOOP_VERSION_VECTORIZED  1  /* Vectorized version.  */
> +#define DISCRIMINATOR_LOOP_VERSION_SCALAR      2  /* Scalar version.  */
> +#define DISCRIMINATOR_LOOP_VERSION_ALIGNED     3  /* Aligned version.  */
> +#define DISCRIMINATOR_LOOP_VERSION_UNALIGNED   4  /* Unaligned version.  */
> +#define DISCRIMINATOR_LOOP_PROLOG           6  /* Prolog loop.  */
> +#define DISCRIMINATOR_LOOP_EPILOG           7  /* Epilog loop.  */
> +#define DISCRIMINATOR_LOOP_EPILOG_VECTORIZED   8  /* Vector epilog loop.  */

It is still not quite clear to me we want to go with pre-assigned copy
ID numbers.  Optimizations can happen mulitple times at same loop (for
exmaple cascaded prologs).  But I guess this is a good start, since it
is simple.
> +
> +/* Helper function to assign discriminators to all statements in a basic
> +   block.  This preserves the base discriminator and only updates the
> +   requested components.  */
> +extern void assign_discriminators_to_bb (basic_block bb,
> +                                       unsigned int multiplicity_value,
> +                                       unsigned int copyid_value,
> +                                       bool update_multiplicity,
> +                                       bool update_copyid);
> +
> +/* Helper function to assign discriminators to all basic blocks in a loop.
> +   This is used by loop versioning passes to distinguish different versions
> +   of the same loop and to indicate vectorization factors.
> +
> +   multiplicity_value: vectorization factor (0 to keep unchanged)
> +   copyid_value: version ID (1=vectorized, 2=scalar, etc.)  */
> +extern void assign_discriminators_to_loop (class loop *loop,
> +                                         unsigned int multiplicity_value,
> +                                         unsigned int copyid_value);
> +
> +#endif /* GCC_HIERARCHICAL_DISCRIMINATOR_H.  */
> diff --git a/gcc/input.cc b/gcc/input.cc
> index aad98394711..520ae33add8 100644
> --- a/gcc/input.cc
> +++ b/gcc/input.cc
> @@ -1074,6 +1074,41 @@ get_discriminator_from_loc (location_t locus)
>    return get_discriminator_from_loc (line_table, locus);
>  }
>  
> +/* Create a location with hierarchical discriminator components.  */
> +
> +location_t
> +location_with_discriminator_components (location_t locus,
> +                                     unsigned int base,
> +                                     unsigned int multiplicity,
> +                                     unsigned int copyid)

Can you please put these values into a structure?
I think it will be then easier to add possible additional fields
and will be more handy to work with.

The patch looks good otherwise, but I think Jakub or Jason 
(with more dwarf knowledge than me) probably should have chance to
comment. Since LLVM uses same scheme, I hope there is no problem with
having much bigger discriminators than before.

Honza

Reply via email to