#!/usr/bin/awk -f
# vim: ft=awk ts=4 sw=4 et
#
# This script compares two files generated by the frame_sizes script, which
# each contain information about stack frame sizes in a version of the Mercury
# compiler. It compares the average stack frame sizes of the two versions, and
# reports the procedures for which the two versions have different stack frame
# sizes.
#
# Usage: compare_frame_sizes SP.batch.version1 SP.batch.version2

    {
        if (NF != 5) {
            printf "error: NF != 5\n"
            printf "%s\n", $0;
            next;
        }

        batch = $1 "";

        # We expect to encounter two values of batch. The first becomes
        # the value of base; the second becomes the value of new.

        if (batch != base && batch != new) {
            if (base == "") {
                 base = batch;
            } else if (new == "") {
                 new = batch;
            } else {
                printf "error: unknown batch %s (%s %s)\n", batch, base, new;
                exit 1;
            }
        }

        proc = $3 " " $4 " " $5;
        framesize = $2;

        repcount = count[batch "@" proc];
        count[batch "@" proc] = repcount + 1;

        if (repcount > 0) {
            repcount++;
            proc = proc "#" repcount;
        }

        procs[proc] = 1;

        sizes[batch "@" proc] = framesize;
        exist[batch "@" proc] = 1;
    }
END {
        basetotal  = 0;
        newtotal   = 0;
        proccount  = 0;
        basebetter = 0;
        newbetter  = 0;

        for (proc in procs) {
            if (exist[base "@" proc] == 1 && exist[new "@" proc] == 1) {
                basesize = sizes[base "@" proc];
                newsize  = sizes[new  "@" proc];
                basetotal += basesize;
                newtotal  += newsize;
                proccount += 1;

                if (basesize < newsize) {
                    basebetter += 1;
                    worsened = worsened proc "  " basesize "->" newsize "\n"
                } else if (basesize > newsize) {
                    newbetter  += 1;
                    improved = improved proc "  " basesize "->" newsize "\n"
                }
            } else {
                printf "error: mismatch for %s\n", proc;
            }
        }

        printf "base slots: %5d, %5.2f, %6.2f\n", basetotal, basetotal / proccount, 100;
        printf "new  slots: %5d, %5.2f, %6.2f\n", newtotal, newtotal / proccount, 100 * newtotal / basetotal;
        printf "number of procedures: %d\n", proccount;
        printf "base better: %d, %5.2f\n", basebetter, 100 * basebetter  / proccount;
        printf "new  better: %d, %5.2f\n", newbetter, 100 * newbetter  / proccount;
        printf "\n";
        printf "improved:\n%s", improved;
        printf "\n";
        printf "worsened:\n%s", worsened;
    }
