On 2/4/2022 6:49 AM, Richard Biener via Gcc-patches wrote:
This adds explicit variable birth CLOBBERs in an attempt to fix
PR90348 and duplicates.  The birth / death CLOBBER pairs are
used to compute liveness and conflicts for stack variable
coalescing where the lack of an explicit birth but instead
use of first mention causes misrepresentation of variable life
ranges when optimization moves the first mention upwards the
original birth point at the variables bind expression start.

Birth CLOBBERs are represented as traditional CLOBBERs with all
the accompaning effect on optimization.  While they do not serve
as a barrier for address mentions they act as barrier for the
actual accesses which is enough for determining conflicts in
the context of stack slot sharing.  The birth CLOBBERs are
distinguished from death CLOBBERs by setting CLOBBER_MARKS_BIRTH
using the private_flag on the CONSTRUCTOR node and amend the
CLOBBER_MARK_EOL marked clobbers introduced earlier.

The patch changes how we handle stack variables that are not marked
with CLOBBERs.  For those the first mention started live which then
lasted upon function exit which means effectively all not marked
variables conflicted with each other variable.  This property is best
represented by an extra flag rather than the full conflict bitmap
which is what the patch introduces with conflicts_represented which
is cleared at start and set to true once we visit the first birth
CLOBBER.  From that on we assume all variable accesses are properly
fenced by birth/death CLOBBERs.

Variables without explicit births will not take part in stack slot
sharing after this change.

Currently birth CLOBBERs are added when gimplification adds
corresponding end-of-life CLOBBERs, during bind and target expression
gimplification.  Generally inserting births at DECL_EXPRs is
more precise so we also do it there (also noting not all such variables
are mentioned in BINDs).  Avoiding redundant births is on the TOOD
list and might also remove the need for the warn_switch_unreachable_r
hunk.

This is the meat of the PR90348 fix, the following 3 patches perform
testcase adjustments and followup fixes to avoid regressions.

Bootstrapped on x86_64-unknown-linux-gnu - re-testing in progress.

Any comments?  I have mixed feelings with proposing this for GCC 12
but like to hear from others as well.  I didn't try to evaluate
the quality of stack slot sharing before/after this change besides
fixing the testsuite fallout (we have a few testcases checking for
specific instances).

Thanks,
Richard.

2022-02-01  Richard Biener  <rguent...@suse.de>

        PR middle-end/90348
        PR middle-end/103006
        * tree-core.h (clobber_kind): Add CLOBBER_BIRTH.
        * gimplify.cc (gimplify_bind_expr): Also add birth CLOBBERs.
        (gimplify_target_expr): Likewise.
        (gimplify_decl_expr): Likewise.
        (warn_switch_unreachable_r): Do not treat birth CLOBBERs as
        real stmt - they get added at BIND starts but that's before
        the case labels.
        * tree-pretty-print.cc (dump_generic_node): Mark birth CLOBBERs.
        * cfgexpand.cc (stack_var::conflicts_represented): New.
        (add_stack_var): Initialize conflicts_represented.
        (add_stack_var_conflict): Assert the conflicts for the
        vars are represented.
        (stack_var_conflict_p): Honor conflicts_represented flag.
        (visit_op): Remove.
        (visit_conflict): Likewise.
        (add_scope_conflicts_1): Simplify by only considering birth
        and death CLOBBERs.
        (add_scope_conflicts): Adjust comment.
        (add_stack_protection_conflicts): Only add conflicts for
        variables that have them represented.

        * gcc.dg/torture/pr103006-1.c: New testcase.
        * gcc.dg/torture/pr103006-2.c: Likewise.
        * gcc.dg/torture/pr90348.c: Likewise.
The lack of explicit birth/death points in gimple has been a long standing problem, so definitely happy to see this moving forward. As you note, it's not clear if we should go forward now or wait for the next stage1 cycle.

In the past stack sharing has been quite important for the linux kernel.  So perhaps one of the tests we should do if we wanted to go forward in this cycle would be to test kernel builds to see if any start tripping over the stack space diagnostics they've put in place over the years.

Jeff

Reply via email to