Skip to content

Blockfill optimization fixes potpourri #493

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

Closed
wants to merge 4 commits into from

Conversation

Wuerfel21
Copy link
Contributor

Currently failing test is due to diff noise in one of the expect tests.

I made FindPrevSetterForReplace work with conditional instructions, but this causes minor regressions in some functions because we can not get rid of a conditional dead set (i.e. where both the original set and the one that kills it have the same condition) and I'm not in the mood to mess with IsDeadAfter today. Because of that and the usual concerns, the code is behind experimental flag.

@Wuerfel21
Copy link
Contributor Author

Also, a script I used to verify the mindboggling condition thing:

bad_check = false

def subset(sup,sub)
    sub == (sup|sub)
end

(0..15).each do |orig_cond|

    good = (0..3).all? do |orig_flags|
        c_flags = orig_flags | 2
        nc_flags = orig_flags & ~2
        wr_cond = orig_cond | 0b1100
        if orig_cond[orig_flags] == 1 # Should not run anything
            next false if wr_cond[orig_flags] == 0 # writes anyways
        else # Should write
            next false if wr_cond[nc_flags] == 1 # Fail to write when needed!
            next false if wr_cond[c_flags] == 0 # NC
        end
        next true
    end

    check = subset(orig_cond,(orig_cond>>2)|12)
    bad_check = true if check != good

    puts "Cond %04b (real %04b) : %s %s" % [orig_cond,orig_cond^15,good ? "GOOD" : "BAD ",check ? "PASS" : "FAIL"]

end
puts "BAD CHECK" if bad_check

@totalspectrum
Copy link
Owner

It may take me a while to wrap my head around this, it seems a bit complicated :)

@Wuerfel21
Copy link
Contributor Author

That complicated condition thing is a bugfix, the existing check has failure cases, where it would let, for example, if_c_or_z through and compile incorrect code.
Mind, I had to write that script to prove it exhaustively, it really is not intuitive to understand.
Though with the unmodified FindPrevSetterForReplace it would be somewhat unlikely for the bug to trigger.

@Wuerfel21
Copy link
Contributor Author

To elaborate on that:

Normally it inserts this sequence to replace a call:

      sub arg03,#1 wc
if_nc setq arg03
if_nc wrlong #something,arg01

If this enters with C=1, Z=0 and arg03 > 0, the first line clears C and the write erroneously doesn't execute

If the original CALL being replaced was if_c_or_z, then the replacement sequence would be

if_c_or_z   sub arg03,#1 wc
if_nc_and_z setq arg03
if_nc_and_z wrlong #something,arg01

If this enters with C=1, Z=0 and arg03 > 0, the first line clears C and the write erroneously doesn't execute. So it isn't valid with that condition. Thus there's a condition check in the first place, but the one I put there originally isn't quite correct.

@Wuerfel21
Copy link
Contributor Author

(Incidentally all of this came from taking a glance at the allocator for different reasons)

@totalspectrum
Copy link
Owner

Thanks for the clarification Ada. I've merged this by hand so I'm closing the pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants