Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor subrange assertion generation and propagation #55186

Merged

Commits on Sep 17, 2021

  1. Refactor subrange generation

    Move it into its own function.
    
    No diffs.
    SingleAccretion committed Sep 17, 2021
    Configuration menu
    Copy the full SHA
    2ddaefa View commit details
    Browse the repository at this point in the history
  2. Stop generating assertions for TYP_U/INT ranges

    They are not useful: they do not tell us anything about the value.
    They can be harmful: code operating on the assertions can wrongly
    remove a checked cast because of an assertion for a non-checked one.
    SingleAccretion committed Sep 17, 2021
    Configuration menu
    Copy the full SHA
    d6b7073 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    0f24634 View commit details
    Browse the repository at this point in the history
  4. Refactor subrange assertions

    This change completely refactors the way subrange assertions are
    generated and consumed. It rationalizes and generalizes the model
    for subrange assertions which are generated and propagated for casts,
    makes AssertionDsc::Range into an actual abstraction, eliminates bugs
    related to wrong assertions generated for TYP_BOOL (without CQ loss),
    enables propagation for checked casts to non-small types both on 64
    and 32 bit, all the while making the AssertionDsc structure smaller.
    
    There are quite a few moving parts, but at the heart of this change
    are following items:
    
    1. Make ranges symbolic, i. e. made up of symbolic upper and lower
       bounds, represented by the new SymbolicIntegerValue enum class.
       This is necessary to not regress memory consumption and throughput
       of operations on 32 bit while handling long subranges.
    2. Split the concept of "input" and "output" for a cast node.
       To properly handle checked cast and make the code "obviously correct",
       it is necessary to split the two values, one the cast node produces
       and one it consumes, apart. The old code only handles the "easy" case
       of the "input" and "output" ranges matching (such is the case for small
       types), the new code must be, and is, robust in reasoning about, e. g.
       CAST_OVF(uint <- ulong) vs CAST_OVF(int <- long). The ranges that
       represent these values are consistently in the "signed" format, making
       handling them easy.
    3. Tweak the propagation code to not remove representation-changing casts,
       make it explicit and obvious in what cases (and why) it retypes the
       local under the cast.
    
    As a side-effect of the above changes, TYP_BOOL is now treated as TYP_UBYTE
    in propagation, as it should be. Actually, the old code didn't remove
    redundant casts to TYP_BOOL, the new code does, which is also where the
    bulk of the positive diffs come from.
    
    The old code also generated "useless" ranges like [INT_MIN..INT_MAX], the new
    code only generates ranges that could be used in subsequent propagation.
    
    Also, some miscellaneous cleanup, such as adding function headers, was performed.
    SingleAccretion committed Sep 17, 2021
    Configuration menu
    Copy the full SHA
    fd3db65 View commit details
    Browse the repository at this point in the history
  5. Use correct ranges for global subrange assertions

    In global assertion propagation, tentative assertions are
    created for casts, with the expectation that proving them
    via implication will allow for removing the cast.
    
    The old code did this through the common path with local
    assertions, however, this cannot be done the same way anymore
    because the two types of assertions are fundamnetally different.
    
    In local assertion propagation, subranges are derived from ASGs,
    where the cast is on the RHS and the local - LHS, so the "output"
    range for the cast must be used - local is assigned value the cast
    **produces**.
    
    In contrast, global subrange assertions say that the value the
    cast **consumes** is within the correct bounds for the cast to
    become a no-op or non-overflowing.
    
    Because of this fundamnetal distinction, I chose to make global
    assertions for casts in a new method instead of plumbing it
    through "optCreateAssertion". Note that it would be possible to
    do it via "optCreateAssertion" as well - global propagation
    always passes OAK_SUBRANGE to it, while local - OAK_EQUAL, but
    I decided against that option for the reason that it seems
    unintuitive to me that it would work the way it would. These
    tentative assertions are a very special case, so I think it is
    better to treat them that way. This leads to some minor code
    duplication, but I think that's ok.
    
    No diffs for this commit, though that's expected as "proving"
    the generated assertion is quite rare.
    SingleAccretion committed Sep 17, 2021
    Configuration menu
    Copy the full SHA
    9d47aac View commit details
    Browse the repository at this point in the history
  6. Refactor AssertionDsc::Range into its own class

    Make IntegralRange the owner of the logic for various
    methods relating to it and decouple it from AssertionDsc.
    
    IntegralRange will be useful in the future for other code
    that deals with cast removal, e. g. in fgMorphCast.
    
    Also some miscellaneous formatting fixups.
    SingleAccretion committed Sep 17, 2021
    Configuration menu
    Copy the full SHA
    5a4434c View commit details
    Browse the repository at this point in the history
  7. Change the implementation of SymbolicToRealValue

    Using a static array results in smaller and more
    efficient code on all compilers.
    SingleAccretion committed Sep 17, 2021
    Configuration menu
    Copy the full SHA
    452a4a2 View commit details
    Browse the repository at this point in the history
  8. FP & GC castees in IntegralRange::ForCastOutput

    This change is for completeness, since "fgMorphCast" decomposes
    casts from FP types to small types today and as such assertions
    are generated for them anyway.
    
    No diffs for this commit as expected.
    SingleAccretion committed Sep 17, 2021
    Configuration menu
    Copy the full SHA
    9b35f21 View commit details
    Browse the repository at this point in the history
  9. Add the TYP_BOOL quirk

    To avoid regressions.
    SingleAccretion committed Sep 17, 2021
    Configuration menu
    Copy the full SHA
    9412c7e View commit details
    Browse the repository at this point in the history
  10. Fix the input ranges for non-overflowing casts

    They did not handle "long" cases and as such were too conservative.
    SingleAccretion committed Sep 17, 2021
    Configuration menu
    Copy the full SHA
    4b658dc View commit details
    Browse the repository at this point in the history
  11. Configuration menu
    Copy the full SHA
    723da4d View commit details
    Browse the repository at this point in the history
  12. Configuration menu
    Copy the full SHA
    b43f07b View commit details
    Browse the repository at this point in the history
  13. Configuration menu
    Copy the full SHA
    a697d02 View commit details
    Browse the repository at this point in the history
  14. Fix build break

    SingleAccretion committed Sep 17, 2021
    Configuration menu
    Copy the full SHA
    763a95f View commit details
    Browse the repository at this point in the history
  15. Configuration menu
    Copy the full SHA
    c513b9a View commit details
    Browse the repository at this point in the history
  16. Tweak the comment

    SingleAccretion committed Sep 17, 2021
    Configuration menu
    Copy the full SHA
    995f0f8 View commit details
    Browse the repository at this point in the history