llvm.org GIT mirror llvm / 59f81b1
[opt-viewer] Add --filter option to select remarks for displaying. This allows limiting the displayed remarks to the ones with names matching the filter (regular) expression. Generating html pages for a larger project with optimization remarks can result in a huge HTML documents and using --filter allows to focus on a set of interesting remarks. Reviewers: hfinkel, anemet, thegameg, serge-sans-paille Reviewed By: anemet Differential Revision: https://reviews.llvm.org/D57827 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@353322 91177308-0d34-0410-b5e6-96231b3b80d8 Florian Hahn 6 months ago
7 changed file(s) with 631 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
0
1
2 or.c
3
4
5
6
23
24
25
26
27
28
29 Line
30 Hotness
31 Optimization
32 Source
33 Inline Context
34
35
36
37
38
39 1
40
41
42
void bar();
43
44
45
46 2
47
48
49
void foo() { bar(); }
50
51
52
53
54
55 inline
56
             
bar will not be inlined into foo because its definition is unavailable 
57 foo
58
59
60
61 3
62
63
64
65
66
67
68 4
69
70
71
#include "or.h"
72
73
74
75 5
76
77
78
79
80
81
82 6
83
84
85
void Test(int *res, int *c, int *d, int *p, int n) {
86
87
88
89 7
90
91
92
  int i;
93
94
95
96 8
97
98
99
100
101
102
103 9
104
105
106
#pragma clang loop vectorize(assume_safety)
107
108
109
110 10
111
112
113
  for (i = 0; i < 1600; i++) {
114
115
116
117 11
118
119
120
    res[i] = (p[i] == 0) ? res[i] : res[i] + d[i];
121
122
123
124 12
125
126
127
  }
128
129
130
131 13
132
133
134
135
136
137
138 14
139
140
141
  for (i = 0; i < 16; i++) {
142
143
144
145 15
146
147
148
    res[i] = (p[i] == 0) ? res[i] : res[i] + d[i];
149
150
151
152 16
153
154
155
  }
156
157
158
159 17
160
161
162
163
164
165
166 18
167
168
169
  foo();
170
171
172
173
174
175 inline
176
  
foo can be inlined into Test with cost=30 (threshold=412) 
177 Test
178
179
180
181
182
183 inline
184
  
foo inlined into Test 
185 Test
186
187
188
189 19
190
191
192
193
194
195
196 20
197
198
199
  foo(); bar(); foo();
200
201
202
203
204
205 inline
206
         
bar will not be inlined into Test because its definition is unavailable 
207 Test
208
209
210
211
212
213 inline
214
  
foo can be inlined into Test with cost=30 (threshold=412) 
215 Test
216
217
218
219
220
221 inline
222
  
foo inlined into Test 
223 Test
224
225
226
227
228
229 inline
230
                
foo can be inlined into Test with cost=30 (threshold=412) 
231 Test
232
233
234
235
236
237 inline
238
                
foo inlined into Test 
239 Test
240
241
242
243 21
244
245
246
}
247
248
249
250 22
251
252
253
254
255
256
257
258
259
0
1
2 or.h
3
4
5
6
23
24
25
26
27
28
29 Line
30 Hotness
31 Optimization
32 Source
33 Inline Context
34
35
36
37
38
39 1
40
41
42
void TestH(int *res, int *c, int *d, int *p, int n) {
43
44
45
46 2
47
48
49
  int i;
50
51
52
53 3
54
55
56
57
58
59
60 4
61
62
63
#pragma clang loop vectorize(assume_safety)
64
65
66
67 5
68
69
70
  for (i = 0; i < 1600; i++) {
71
72
73
74 6
75
76
77
    res[i] = (p[i] == 0) ? res[i] : res[i] + d[i];
78
79
80
81 7
82
83
84
  }
85
86
87
88 8
89
90
91
92
93
94
95 9
96
97
98
  for (i = 0; i < 16; i++) {
99
100
101
102 10
103
104
105
    res[i] = (p[i] == 0) ? res[i] : res[i] + d[i];
106
107
108
109 11
110
111
112
  }
113
114
115
116 12
117
118
119
120
121
122
123 13
124
125
126
  foo();
127
128
129
130
131
132 inline
133
  
foo can be inlined into TestH with cost=30 (threshold=412) 
134 TestH
135
136
137
138
139
140 inline
141
  
foo inlined into TestH 
142 TestH
143
144
145
146 14
147
148
149
150
151
152
153 15
154
155
156
  foo(); bar(); foo();
157
158
159
160
161
162 inline
163
         
bar will not be inlined into TestH because its definition is unavailable 
164 TestH
165
166
167
168
169
170 inline
171
  
foo can be inlined into TestH with cost=30 (threshold=412) 
172 TestH
173
174
175
176
177
178 inline
179
  
foo inlined into TestH 
180 TestH
181
182
183
184
185
186 inline
187
                
foo can be inlined into TestH with cost=30 (threshold=412) 
188 TestH
189
190
191
192
193
194 inline
195
                
foo inlined into TestH 
196 TestH
197
198
199
200 16
201
202
203
}
204
205
206
207 17
208
209
210
211
212
213
214
215
216
0
1
2
3
4
5
6
7
8
9
10 Source Location
11 Hotness
12 Function
13 Pass
14
15
16
17 basic/or.c:2:14
18
19 foo
20 inline
21
22
23
24 basic/or.c:18:3
25
26 Test
27 inline
28
29
30
31 basic/or.c:18:3
32
33 Test
34 inline
35
36
37
38 basic/or.c:20:3
39
40 Test
41 inline
42
43
44
45 basic/or.c:20:3
46
47 Test
48 inline
49
50
51
52 basic/or.c:20:10
53
54 Test
55 inline
56
57
58
59 basic/or.c:20:17
60
61 Test
62 inline
63
64
65
66 basic/or.c:20:17
67
68 Test
69 inline
70
71
72
73 basic/or.h:13:3
74
75 TestH
76 inline
77
78
79
80 basic/or.h:13:3
81
82 TestH
83 inline
84
85
86
87 basic/or.h:15:3
88
89 TestH
90 inline
91
92
93
94 basic/or.h:15:3
95
96 TestH
97 inline
98
99
100
101 basic/or.h:15:10
102
103 TestH
104 inline
105
106
107
108 basic/or.h:15:17
109
110 TestH
111 inline
112
113
114
115 basic/or.h:15:17
116
117 TestH
118 inline
119
120
121
122
123
0 # Since we're performing a full compare of the generate HTML files disable
1 # syntax highlighting; pygments generates slightly different code with
2 # different versions.
3
4 RUN: %opt-viewer --filter inline -s %p/Inputs -o %t %p/Inputs/basic/or.yaml --no-highlight --demangler=llvm-cxxfilt
5 RUN: diff %p/Outputs/filter/index.html %t/index.html
6 RUN: diff %p/Outputs/filter/basic_or.h.html %t/basic_or.h.html
7 RUN: diff %p/Outputs/filter/basic_or.c.html %t/basic_or.c.html
238238 ''', file=self.stream)
239239
240240
241 def _render_file(source_dir, output_dir, ctx, no_highlight, entry):
241 def _render_file(source_dir, output_dir, ctx, no_highlight, entry, filter_):
242242 global context
243243 context = ctx
244244 filename, remarks = entry
343343 '--demangler',
344344 help='Set the demangler to be used (defaults to %s)' % optrecord.Remark.default_demangler)
345345
346 parser.add_argument(
347 '--filter',
348 default='',
349 help='Only display remarks from passes matching filter expression')
350
346351 # Do not make this a global variable. Values needed to be propagated through
347352 # to individual classes and functions to be portable with multiprocessing across
348353 # Windows and non-Windows.
358363 sys.exit(1)
359364
360365 all_remarks, file_remarks, should_display_hotness = \
361 optrecord.gather_results(files, args.jobs, print_progress)
366 optrecord.gather_results(files, args.jobs, print_progress, args.filter)
362367
363368 map_remarks(all_remarks)
364369
1313
1414
1515 def _wrapped_func(func_and_args):
16 func, argument, should_print_progress = func_and_args
16 func, argument, should_print_progress, filter_ = func_and_args
1717
1818 if should_print_progress:
1919 with _current.get_lock():
2121 sys.stdout.write('\r\t{} of {}'.format(_current.value, _total.value))
2222 sys.stdout.flush()
2323
24 return func(argument)
24 return func(argument, filter_)
2525
2626
27 def pmap(func, iterable, processes, should_print_progress, *args, **kwargs):
27 def pmap(func, iterable, processes, should_print_progress, filter_=None, *args, **kwargs):
2828 """
2929 A parallel map function that reports on its progress.
3030
3939 _current = multiprocessing.Value('i', 0)
4040 _total = multiprocessing.Value('i', len(iterable))
4141
42 func_and_args = [(func, arg, should_print_progress,) for arg in iterable]
42 func_and_args = [(func, arg, should_print_progress, filter_) for arg in iterable]
4343 if processes == 1:
4444 result = list(map(_wrapped_func, func_and_args, *args, **kwargs))
4545 else:
2222 from sys import intern
2323 except:
2424 pass
25
26 import re
2527
2628 import optpmap
2729
262264 return "red"
263265
264266
265 def get_remarks(input_file):
267 def get_remarks(input_file, filter_):
266268 max_hotness = 0
267269 all_remarks = dict()
268270 file_remarks = defaultdict(functools.partial(defaultdict, list))
269271
270272 with open(input_file) as f:
271273 docs = yaml.load_all(f, Loader=Loader)
274
275 filter_e = re.compile(filter_)
272276 for remark in docs:
273277 remark.canonicalize()
274278 # Avoid remarks withoug debug location or if they are duplicated
275279 if not hasattr(remark, 'DebugLoc') or remark.key in all_remarks:
276280 continue
281
282 if filter_ and not filter_e.search(remark.Pass):
283 continue
284
277285 all_remarks[remark.key] = remark
278286
279287 file_remarks[remark.File][remark.Line].append(remark)
288296 return max_hotness, all_remarks, file_remarks
289297
290298
291 def gather_results(filenames, num_jobs, should_print_progress):
299 def gather_results(filenames, num_jobs, should_print_progress, filter_):
292300 if should_print_progress:
293301 print('Reading YAML files...')
294302 if not Remark.demangler_proc:
295303 Remark.set_demangler(Remark.default_demangler)
296304 remarks = optpmap.pmap(
297 get_remarks, filenames, num_jobs, should_print_progress)
305 get_remarks, filenames, num_jobs, should_print_progress, filter_)
298306 max_hotness = max(entry[0] for entry in remarks)
299307
300308 def merge_file_remarks(file_remarks_job, all_remarks, merged):