diff --git /dev/null b/test/tools/opt-viewer/Outputs/filter/basic_or.c.html new mode 100644 index 0000000..005cc2e 100644 --- /dev/null +++ b/test/tools/opt-viewer/Outputs/filter/basic_or.c.html @@ -1,0 +1,260 @@ + + +or.c + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Line +Hotness +Optimization +Source +Inline Context +
1
void bar();
2
void foo() { bar(); }
inline
             
bar will not be inlined into foo because its definition is unavailable 
foo
3
4
#include "or.h"
5
6
void Test(int *res, int *c, int *d, int *p, int n) {
7
  int i;
8
9
#pragma clang loop vectorize(assume_safety)
10
  for (i = 0; i < 1600; i++) {
11
    res[i] = (p[i] == 0) ? res[i] : res[i] + d[i];
12
  }
13
14
  for (i = 0; i < 16; i++) {
15
    res[i] = (p[i] == 0) ? res[i] : res[i] + d[i];
16
  }
17
18
  foo();
inline
  
foo can be inlined into Test with cost=30 (threshold=412) 
Test
inline
  
foo inlined into Test 
Test
19
20
  foo(); bar(); foo();
inline
         
bar will not be inlined into Test because its definition is unavailable 
Test
inline
  
foo can be inlined into Test with cost=30 (threshold=412) 
Test
inline
  
foo inlined into Test 
Test
inline
                
foo can be inlined into Test with cost=30 (threshold=412) 
Test
inline
                
foo inlined into Test 
Test
21
}
22
+ + diff --git /dev/null b/test/tools/opt-viewer/Outputs/filter/basic_or.h.html new mode 100644 index 0000000..19b0f1e 100644 --- /dev/null +++ b/test/tools/opt-viewer/Outputs/filter/basic_or.h.html @@ -1,0 +1,217 @@ + + +or.h + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Line +Hotness +Optimization +Source +Inline Context +
1
void TestH(int *res, int *c, int *d, int *p, int n) {
2
  int i;
3
4
#pragma clang loop vectorize(assume_safety)
5
  for (i = 0; i < 1600; i++) {
6
    res[i] = (p[i] == 0) ? res[i] : res[i] + d[i];
7
  }
8
9
  for (i = 0; i < 16; i++) {
10
    res[i] = (p[i] == 0) ? res[i] : res[i] + d[i];
11
  }
12
13
  foo();
inline
  
foo can be inlined into TestH with cost=30 (threshold=412) 
TestH
inline
  
foo inlined into TestH 
TestH
14
15
  foo(); bar(); foo();
inline
         
bar will not be inlined into TestH because its definition is unavailable 
TestH
inline
  
foo can be inlined into TestH with cost=30 (threshold=412) 
TestH
inline
  
foo inlined into TestH 
TestH
inline
                
foo can be inlined into TestH with cost=30 (threshold=412) 
TestH
inline
                
foo inlined into TestH 
TestH
16
}
17
+ + diff --git /dev/null b/test/tools/opt-viewer/Outputs/filter/index.html new mode 100644 index 0000000..57aa9c8 100644 --- /dev/null +++ b/test/tools/opt-viewer/Outputs/filter/index.html @@ -1,0 +1,124 @@ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Source LocationHotnessFunctionPass
basic/or.c:2:14fooinline
basic/or.c:18:3Testinline
basic/or.c:18:3Testinline
basic/or.c:20:3Testinline
basic/or.c:20:3Testinline
basic/or.c:20:10Testinline
basic/or.c:20:17Testinline
basic/or.c:20:17Testinline
basic/or.h:13:3TestHinline
basic/or.h:13:3TestHinline
basic/or.h:15:3TestHinline
basic/or.h:15:3TestHinline
basic/or.h:15:10TestHinline
basic/or.h:15:17TestHinline
basic/or.h:15:17TestHinline
+ + diff --git /dev/null b/test/tools/opt-viewer/filter.test new mode 100644 index 0000000..a6913ce 100644 --- /dev/null +++ b/test/tools/opt-viewer/filter.test @@ -1,0 +1,8 @@ +# Since we're performing a full compare of the generate HTML files disable +# syntax highlighting; pygments generates slightly different code with +# different versions. + +RUN: %opt-viewer --filter inline -s %p/Inputs -o %t %p/Inputs/basic/or.yaml --no-highlight --demangler=llvm-cxxfilt +RUN: diff %p/Outputs/filter/index.html %t/index.html +RUN: diff %p/Outputs/filter/basic_or.h.html %t/basic_or.h.html +RUN: diff %p/Outputs/filter/basic_or.c.html %t/basic_or.c.html diff --git a/tools/opt-viewer/opt-viewer.py b/tools/opt-viewer/opt-viewer.py index 8aec321..4c10588 100755 --- a/tools/opt-viewer/opt-viewer.py +++ b/tools/opt-viewer/opt-viewer.py @@ -239,7 +239,7 @@ ''', file=self.stream) -def _render_file(source_dir, output_dir, ctx, no_highlight, entry): +def _render_file(source_dir, output_dir, ctx, no_highlight, entry, filter_): global context context = ctx filename, remarks = entry @@ -344,6 +344,11 @@ '--demangler', help='Set the demangler to be used (defaults to %s)' % optrecord.Remark.default_demangler) + parser.add_argument( + '--filter', + default='', + help='Only display remarks from passes matching filter expression') + # Do not make this a global variable. Values needed to be propagated through # to individual classes and functions to be portable with multiprocessing across # Windows and non-Windows. @@ -359,7 +364,7 @@ sys.exit(1) all_remarks, file_remarks, should_display_hotness = \ - optrecord.gather_results(files, args.jobs, print_progress) + optrecord.gather_results(files, args.jobs, print_progress, args.filter) map_remarks(all_remarks) diff --git a/tools/opt-viewer/optpmap.py b/tools/opt-viewer/optpmap.py index ff3e683..8124c8c 100644 --- a/tools/opt-viewer/optpmap.py +++ b/tools/opt-viewer/optpmap.py @@ -14,7 +14,7 @@ def _wrapped_func(func_and_args): - func, argument, should_print_progress = func_and_args + func, argument, should_print_progress, filter_ = func_and_args if should_print_progress: with _current.get_lock(): @@ -22,10 +22,10 @@ sys.stdout.write('\r\t{} of {}'.format(_current.value, _total.value)) sys.stdout.flush() - return func(argument) + return func(argument, filter_) -def pmap(func, iterable, processes, should_print_progress, *args, **kwargs): +def pmap(func, iterable, processes, should_print_progress, filter_=None, *args, **kwargs): """ A parallel map function that reports on its progress. @@ -40,7 +40,7 @@ _current = multiprocessing.Value('i', 0) _total = multiprocessing.Value('i', len(iterable)) - func_and_args = [(func, arg, should_print_progress,) for arg in iterable] + func_and_args = [(func, arg, should_print_progress, filter_) for arg in iterable] if processes == 1: result = list(map(_wrapped_func, func_and_args, *args, **kwargs)) else: diff --git a/tools/opt-viewer/optrecord.py b/tools/opt-viewer/optrecord.py index 0193d25..e952d1b 100644 --- a/tools/opt-viewer/optrecord.py +++ b/tools/opt-viewer/optrecord.py @@ -23,6 +23,8 @@ from sys import intern except: pass + +import re import optpmap @@ -263,18 +265,24 @@ return "red" -def get_remarks(input_file): +def get_remarks(input_file, filter_): max_hotness = 0 all_remarks = dict() file_remarks = defaultdict(functools.partial(defaultdict, list)) with open(input_file) as f: docs = yaml.load_all(f, Loader=Loader) + + filter_e = re.compile(filter_) for remark in docs: remark.canonicalize() # Avoid remarks withoug debug location or if they are duplicated if not hasattr(remark, 'DebugLoc') or remark.key in all_remarks: continue + + if filter_ and not filter_e.search(remark.Pass): + continue + all_remarks[remark.key] = remark file_remarks[remark.File][remark.Line].append(remark) @@ -289,13 +297,13 @@ return max_hotness, all_remarks, file_remarks -def gather_results(filenames, num_jobs, should_print_progress): +def gather_results(filenames, num_jobs, should_print_progress, filter_): if should_print_progress: print('Reading YAML files...') if not Remark.demangler_proc: Remark.set_demangler(Remark.default_demangler) remarks = optpmap.pmap( - get_remarks, filenames, num_jobs, should_print_progress) + get_remarks, filenames, num_jobs, should_print_progress, filter_) max_hotness = max(entry[0] for entry in remarks) def merge_file_remarks(file_remarks_job, all_remarks, merged):