[Dexter] Collate penalties of the same type into a single line for each

Currently in Dexter, every step at which a DexExpectWatchValue/Type does
not have the correct value is printed on a separate line. This patch
reduces the size of the text output by instead printing each incorrect
result (i.e. each incorrect value seen, 'Variable optimized out', and so
on) on its own line, alongside a list of the steps at which that result
was seen. This makes for much less spam in the output when watches are
missing or wrong for many steps.

Differential Revision: https://reviews.llvm.org/D120716
This commit is contained in:
Stephen Tozer 2022-03-01 13:20:51 +00:00
parent 1477964413
commit 1c8366f9f2
2 changed files with 43 additions and 5 deletions

View File

@ -98,6 +98,32 @@ def add_heuristic_tool_arguments(parser):
metavar='<int>') metavar='<int>')
class PenaltyLineRanges:
def __init__(self, first_step, penalty):
self.ranges = [(first_step, first_step)]
self.penalty = penalty
def add_step(self, next_step, penalty):
last_range = self.ranges[-1]
last_step = last_range[1]
if (next_step == last_step + 1):
self.ranges[-1] = (last_range[0], next_step)
else:
self.ranges.append((next_step, next_step))
self.penalty += penalty
def __str__(self):
range_to_str = lambda r: str(r[0]) if r[0] == r[1] else f'{r[0]}-{r[1]}'
if self.ranges[0][0] == self.ranges[-1][1]:
text = f'step {self.ranges[0][0]}'
else:
step_list = ', '.join([range_to_str(r) for r in self.ranges])
text = f'steps [{step_list}]'
if self.penalty:
text += ' <r>[-{}]</>'.format(self.penalty)
return text
class Heuristic(object): class Heuristic(object):
def __init__(self, context, steps): def __init__(self, context, steps):
self.context = context self.context = context
@ -456,11 +482,23 @@ class Heuristic(object):
for category in sorted(pen_cmd.pen_dict): for category in sorted(pen_cmd.pen_dict):
lines.append(' <r>{}</>:\n'.format(category)) lines.append(' <r>{}</>:\n'.format(category))
step_value_results = {}
for result, penalty in pen_cmd.pen_dict[category]:
if not isinstance(result, StepValueInfo):
continue
if result.expected_value not in step_value_results:
step_value_results[result.expected_value] = PenaltyLineRanges(result.step_index, penalty)
else:
step_value_results[result.expected_value].add_step(result.step_index, penalty)
for value, penalty_line_range in step_value_results.items():
text = f'({value}): {penalty_line_range}'
total_penalty += penalty_line_range.penalty
lines.append(' {}\n'.format(text))
for result, penalty in pen_cmd.pen_dict[category]: for result, penalty in pen_cmd.pen_dict[category]:
if isinstance(result, StepValueInfo): if isinstance(result, StepValueInfo):
text = 'step {}'.format(result.step_index) continue
if result.expected_value:
text += ' ({})'.format(result.expected_value)
else: else:
text = str(result) text = str(result)
if penalty: if penalty:

View File

@ -30,8 +30,8 @@
// CHECK-NEXT: address 'x_2' (0x[[X2_VAL]]) // CHECK-NEXT: address 'x_2' (0x[[X2_VAL]])
// CHECK-NEXT: address 'y' (0x[[Y_VAL]]) // CHECK-NEXT: address 'y' (0x[[Y_VAL]])
// CHECK: misordered result: // CHECK: misordered result:
// CHECK-NEXT: step 4 (0x[[Y_VAL]]) // CHECK-NEXT: (0x[[Y_VAL]]): step 4
// CHECK-NEXT: step 5 (0x[[X2_VAL]]) // CHECK-NEXT: (0x[[X2_VAL]]): step 5
int main() { int main() {
int *x = new int(5); int *x = new int(5);