* Rewrite the error cost comparison in terms of explicit, discrete conditions. * Allow merging versions have different error costs. * Store the depth of each stack version since the last error. Use this state to prevent incorrect merging. * Sort the stack versions in order of preference and put a hard limit on the version count.
46 lines
1.3 KiB
C
46 lines
1.3 KiB
C
#include "runtime/error_costs.h"
|
|
|
|
static const unsigned MAX_COST_DIFFERENCE = 16 * ERROR_COST_PER_SKIPPED_TREE;
|
|
static const unsigned MAX_PUSH_COUNT_WITH_COUNT_DIFFERENCE = 24;
|
|
|
|
ErrorComparison error_status_compare(ErrorStatus a, ErrorStatus b, bool are_mergeable) {
|
|
if (a.count < b.count) {
|
|
if (are_mergeable ||
|
|
a.cost <= b.cost ||
|
|
a.count + 1 < b.count ||
|
|
b.push_count > MAX_PUSH_COUNT_WITH_COUNT_DIFFERENCE) {
|
|
return ErrorComparisonTakeLeft;
|
|
} else {
|
|
return ErrorComparisonPreferLeft;
|
|
}
|
|
}
|
|
|
|
if (b.count < a.count) {
|
|
if (are_mergeable ||
|
|
b.cost <= a.cost ||
|
|
b.count + 1 < a.count ||
|
|
a.push_count > MAX_PUSH_COUNT_WITH_COUNT_DIFFERENCE) {
|
|
return ErrorComparisonTakeRight;
|
|
} else {
|
|
return ErrorComparisonPreferRight;
|
|
}
|
|
}
|
|
|
|
if (a.cost < b.cost) {
|
|
if (are_mergeable || (b.cost - a.cost) * (1 + a.push_count) > MAX_COST_DIFFERENCE) {
|
|
return ErrorComparisonTakeLeft;
|
|
} else {
|
|
return ErrorComparisonPreferLeft;
|
|
}
|
|
}
|
|
|
|
if (b.cost < a.cost) {
|
|
if (are_mergeable || (a.cost - b.cost) * (1 + b.push_count) > MAX_COST_DIFFERENCE) {
|
|
return ErrorComparisonTakeRight;
|
|
} else {
|
|
return ErrorComparisonPreferRight;
|
|
}
|
|
}
|
|
|
|
return ErrorComparisonNone;
|
|
}
|