#!/usr/bin/perl -w

$#ARGV gt -1 or die "usage: process-branches.pl branch_all [branch_annotated ...]\n";

my $incorrect_limit = 10000;
my $correct_percent = 70;

my $miss_hit_limit = 50000;
my $miss_hit_percent = 90;

my @files = @ARGV;

my %correct;
my %incorrect;

my %hit;
my %miss;

my %func;

sub process_miss_hit {
    my ($miss, $hit, $func, $file, $line) = @_;

    my $name = "$func.$file.$line";
    
    $hit{$name} += $hit;
    $miss{$name} += $miss;
}

sub process_likely {
    my ($correct, $incorrect, $func, $file, $line) = @_;

    my $name = "$func.$file.$line";
    
    $correct{$name} += $correct;
    $incorrect{$name} += $incorrect;
}

sub process_file {
    my ($file) = @_;
    my $type = 0;

    open(IN, $file) or die "Can't read file $file";

    while (<IN>) {
	if (!$type) {
	    if (/^\s+miss\s+hit\s/) {
		$type = 1;
	    } elsif (/^\s+correct\s+incorrect\s/) {
		$type = 2;
	    } else {
		warn "Unknow type for $file\n";
		last;
	    }
	} elsif (/^\s+---/) {
	    next;
	    
	} elsif (/^\s*(\d+)\s+(\d+)\s+\d+\s+(\S+)\s+(\S+)\s+(\d+)/) {
	    if ($type eq 1) {
		my $miss = $1;
		my $hit = $2;
		my $func = $3;
		my $file = $4;
		my $line = $5;

		process_miss_hit($miss, $hit, $func, $file, $line);
	    } else {
		my $correct = $1;
		my $incorrect = $2;
		my $func = $3;
		my $file = $4;
		my $line = $5;

		process_likely($correct, $incorrect, $func, $file, $line);
	    }
	}
    }
    close IN;
}

foreach my $file (@files) {
    process_file $file;
}

my %percent_correct;
my %percent_miss_hit;

foreach my $branch (keys %incorrect) {
    next if ($incorrect{$branch} < $incorrect_limit);
    my $percent = $correct{$branch} ?
	$correct{$branch} * 100 / ($correct{$branch} + $incorrect{$branch}):
	0;
    if ($percent < $correct_percent) {
	$percent_correct{$branch} = $percent;
    }
}

foreach my $branch (keys %hit) {
    # the likely and unlikely may cover this
    next if (defined($incorrect{$branch}));

    next if ($miss{$branch} < $miss_hit_limit &&
	     $hit{$branch} < $miss_hit_limit);

    my $top;
    my $bottom;

    if ($miss{$branch} > $hit{$branch}) {
	$top = $miss{$branch};
	$bottom = $hit{$branch};
    } else {
	$top = $hit{$branch};
	$bottom = $miss{$branch};
    }

    my $percent = $top * 100 / ($bottom + $top);

    if ($percent >= $miss_hit_percent) {
	$percent_miss_hit{$branch} = $percent;
    }
}

print "\n------ likely / unlikely incorrect -----\n\n";

print "          function.file.line          \t  correct \tincorrect \tpercent\n";
print "--------------------------------------\t----------\t----------\t----------\n";
for my $branch (sort {$percent_correct{$a} <=> $percent_correct{$b}} keys %percent_correct) {
    printf "%-38s\t%10d\t%10d\t%%%.2f\n", $branch, $correct{$branch},
    $incorrect{$branch}, $percent_correct{$branch};
}


print "\n------ miss / hit -----\n\n";

print "          function.file.line          \t   miss   \t   hit    \tpercent\n";
print "--------------------------------------\t----------\t----------\t----------\n";
for my $branch (sort {$percent_miss_hit{$b} <=> $percent_miss_hit{$a}} keys %percent_miss_hit) {
    printf "%-38s\t%10d\t%10d\t%%%.2f\n", $branch, $miss{$branch},
    $hit{$branch}, $percent_miss_hit{$branch};
}

