https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104954

--- Comment #7 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by David Malcolm <dmalc...@gcc.gnu.org>:

https://gcc.gnu.org/g:5f6197d7c197f9d2b7fb2e1a19dac39a023755e8

commit r12-7809-g5f6197d7c197f9d2b7fb2e1a19dac39a023755e8
Author: David Malcolm <dmalc...@redhat.com>
Date:   Thu Mar 24 20:58:10 2022 -0400

    analyzer: add region::tracked_p to optimize state objects [PR104954]

    PR analyzer/104954 tracks that -fanalyzer was taking a very long time
    on a particular source file in the Linux kernel:
      drivers/gpu/drm/amd/display/dc/calcs/dce_calcs.c

    One issue occurs with the repeated use of dynamic debug lines e.g. via
    the DC_LOG_BANDWIDTH_CALCS macro, such as in print_bw_calcs_dceip in
    drivers/gpu/drm/amd/display/dc/calcs/calcs_logger.h:

     
DC_LOG_BANDWIDTH_CALCS("#####################################################################");
      DC_LOG_BANDWIDTH_CALCS("struct bw_calcs_dceip");
     
DC_LOG_BANDWIDTH_CALCS("#####################################################################");

      [...snip dozens of lines...]

      DC_LOG_BANDWIDTH_CALCS("[bw_fixed] dmif_request_buffer_size: %d",
                             bw_fixed_to_int(dceip->dmif_request_buffer_size));

    When this is configured to use __dynamic_pr_debug, each of these becomes
    code like:

      do {
        static struct _ddebug __attribute__((__aligned__(8)))
        __attribute__((__section__("__dyndbg"))) __UNIQUE_ID_ddebug277 = {
          [...snip...]
        };
        if (arch_static_branch(&__UNIQUE_ID_ddebug277.key, false))
          __dynamic_pr_debug(&__UNIQUE_ID_ddebug277, [...the message...]);
      } while (0);

    The analyzer was naively seeing each call to __dynamic_pr_debug, noting
    that the __UNIQUE_ID_nnnn object escapes.  At each call, as successive
    __UNIQUE_ID_nnnn object escapes, there are N escaped objects, and thus N
    need clobbering, and so we have O(N^2) clobbering of escaped objects
overall,
    leading to huge amounts of pointless work: print_bw_calcs_data has 225
    uses of DC_LOG_BANDWIDTH_CALCS, many of which are in loops.

    This patch adds a way to identify declarations that aren't interesting
    to the analyzer, so that we don't attempt to create binding_clusters
    for them (i.e. we don't store any state for them in our state objects).
    This is implemented by adding a new region::tracked_p, implemented for
    declarations by walking the existing IPA data the first time the
    analyzer sees a declaration, setting it to false for global vars that
    have no loads/stores/aliases, and "sufficiently safe" address-of
    ipa-refs.

    The patch gives a large speedup of -fanalyzer on the above kernel
    source file:
                               Before  After
    Total cc1 wallclock time:    180s    36s
    analyzer wallclock time:     162s    17s
    % spent in analyzer:          90%    47%

    gcc/analyzer/ChangeLog:
            PR analyzer/104954
            * analyzer.opt (-fdump-analyzer-untracked): New option.
            * engine.cc (impl_run_checkers): Handle it.
            * region-model-asm.cc (region_model::on_asm_stmt): Don't attempt
            to clobber regions with !tracked_p ().
            * region-model-manager.cc (dump_untracked_region): New.
            (region_model_manager::dump_untracked_regions): New.
            (frame_region::dump_untracked_regions): New.
            * region-model.h (region_model_manager::dump_untracked_regions):
            New decl.
            * region.cc (ipa_ref_requires_tracking): New.
            (symnode_requires_tracking_p): New.
            (decl_region::calc_tracked_p): New.
            * region.h (region::tracked_p): New vfunc.
            (frame_region::dump_untracked_regions): New decl.
            (class decl_region): Note that this is also used fo SSA names.
            (decl_region::decl_region): Initialize m_tracked.
            (decl_region::tracked_p): New.
            (decl_region::calc_tracked_p): New decl.
            (decl_region::m_tracked): New.
            * store.cc (store::get_or_create_cluster): Assert that we
            don't try to create clusters for base regions that aren't
            trackable.
            (store::mark_as_escaped): Don't mark base regions that we're not
            tracking.

    gcc/ChangeLog:
            PR analyzer/104954
            * doc/invoke.texi (Static Analyzer Options): Add
            -fdump-analyzer-untracked.

    gcc/testsuite/ChangeLog:
            PR analyzer/104954
            * gcc.dg/analyzer/asm-x86-dyndbg-1.c: New test.
            * gcc.dg/analyzer/asm-x86-dyndbg-2.c: New test.
            * gcc.dg/analyzer/many-unused-locals.c: New test.
            * gcc.dg/analyzer/untracked-1.c: New test.
            * gcc.dg/analyzer/unused-local-1.c: New test.

    Signed-off-by: David Malcolm <dmalc...@redhat.com>

Reply via email to