Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5563 serge 1
/*
2
 * Copyright 2013 Vadim Girlin 
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * copy of this software and associated documentation files (the "Software"),
6
 * to deal in the Software without restriction, including without limitation
7
 * on the rights to use, copy, modify, merge, publish, distribute, sub
8
 * license, and/or sell copies of the Software, and to permit persons to whom
9
 * the Software is furnished to do so, subject to the following conditions:
10
 *
11
 * The above copyright notice and this permission notice (including the next
12
 * paragraph) shall be included in all copies or substantial portions of the
13
 * Software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18
 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22
 *
23
 * Authors:
24
 *      Vadim Girlin
25
 */
26
 
27
#include "sb_shader.h"
28
#include "sb_pass.h"
29
 
30
namespace r600_sb {
31
 
32
bool dump::visit(node& n, bool enter) {
33
	if (enter) {
34
		indent();
35
		dump_flags(n);
36
 
37
		switch (n.subtype) {
38
			case NST_PHI:
39
				dump_op(n, "* phi");
40
				break;
41
			case NST_PSI:
42
				dump_op(n, "* psi");
43
				break;
44
			case NST_COPY:
45
				dump_op(n, "* copy");
46
				break;
47
			default:
48
				assert(!"invalid node subtype");
49
				break;
50
		}
51
		sblog << "\n";
52
	}
53
	return false;
54
}
55
 
56
bool dump::visit(container_node& n, bool enter) {
57
	if (enter) {
58
		if (!n.empty()) {
59
			indent();
60
			dump_flags(n);
61
			sblog << "{  ";
62
			if (!n.dst.empty()) {
63
				sblog << " preloaded inputs [";
64
				dump_vec(n.dst);
65
				sblog << "]  ";
66
			}
67
			dump_live_values(n, true);
68
		}
69
		++level;
70
	} else {
71
		--level;
72
		if (!n.empty()) {
73
			indent();
74
			sblog << "}  ";
75
			if (!n.src.empty()) {
76
				sblog << " results [";
77
				dump_vec(n.src);
78
				sblog << "]  ";
79
			}
80
			dump_live_values(n, false);
81
		}
82
	}
83
	return true;
84
}
85
 
86
bool dump::visit(bb_node& n, bool enter) {
87
	if (enter) {
88
		indent();
89
		dump_flags(n);
90
		sblog << "{ BB_" << n.id << "    loop_level = " << n.loop_level << "  ";
91
		dump_live_values(n, true);
92
		++level;
93
	} else {
94
		--level;
95
		indent();
96
		sblog << "} end BB_" << n.id << "  ";
97
		dump_live_values(n, false);
98
	}
99
	return true;
100
}
101
 
102
bool dump::visit(alu_group_node& n, bool enter) {
103
	if (enter) {
104
		indent();
105
		dump_flags(n);
106
		sblog << "[  ";
107
		dump_live_values(n, true);
108
 
109
		++level;
110
	} else {
111
		--level;
112
 
113
		indent();
114
		sblog << "]  ";
115
		dump_live_values(n, false);
116
	}
117
	return true;
118
}
119
 
120
bool dump::visit(cf_node& n, bool enter) {
121
	if (enter) {
122
		indent();
123
		dump_flags(n);
124
		dump_op(n, n.bc.op_ptr->name);
125
 
126
		if (n.bc.op_ptr->flags & CF_BRANCH) {
127
			sblog << " @" << (n.bc.addr << 1);
128
		}
129
 
130
		dump_common(n);
131
		sblog << "\n";
132
 
133
		if (!n.empty()) {
134
			indent();
135
			sblog << "<  ";
136
			dump_live_values(n, true);
137
		}
138
 
139
		++level;
140
	} else {
141
		--level;
142
		if (!n.empty()) {
143
			indent();
144
			sblog << ">  ";
145
			dump_live_values(n, false);
146
		}
147
	}
148
	return true;
149
}
150
 
151
bool dump::visit(alu_node& n, bool enter) {
152
	if (enter) {
153
		indent();
154
		dump_flags(n);
155
		dump_alu(&n);
156
		dump_common(n);
157
		sblog << "\n";
158
 
159
		++level;
160
	} else {
161
		--level;
162
 
163
	}
164
	return true;
165
}
166
 
167
bool dump::visit(alu_packed_node& n, bool enter) {
168
	if (enter) {
169
		indent();
170
		dump_flags(n);
171
		dump_op(n, n.op_ptr()->name);
172
		sblog << "  ";
173
		dump_live_values(n, true);
174
 
175
		++level;
176
	} else {
177
		--level;
178
		if (!n.live_after.empty()) {
179
			indent();
180
			dump_live_values(n, false);
181
		}
182
 
183
	}
184
	// proccess children only if their src/dst aren't moved to this node yet
185
	return n.src.empty();
186
}
187
 
188
bool dump::visit(fetch_node& n, bool enter) {
189
	if (enter) {
190
		indent();
191
		dump_flags(n);
192
		dump_op(n, n.bc.op_ptr->name);
193
		sblog << "\n";
194
 
195
		++level;
196
	} else {
197
		--level;
198
	}
199
	return true;
200
}
201
 
202
bool dump::visit(region_node& n, bool enter) {
203
	if (enter) {
204
		indent();
205
		dump_flags(n);
206
		sblog << "region #" << n.region_id << "   ";
207
		dump_common(n);
208
 
209
		if (!n.vars_defined.empty()) {
210
			sblog << "vars_defined: ";
211
			dump_set(sh, n.vars_defined);
212
		}
213
 
214
		dump_live_values(n, true);
215
 
216
		++level;
217
 
218
		if (n.loop_phi)
219
			run_on(*n.loop_phi);
220
	} else {
221
		--level;
222
 
223
		if (n.phi)
224
			run_on(*n.phi);
225
 
226
		indent();
227
		dump_live_values(n, false);
228
	}
229
	return true;
230
}
231
 
232
bool dump::visit(repeat_node& n, bool enter) {
233
	if (enter) {
234
		indent();
235
		dump_flags(n);
236
		sblog << "repeat region #" << n.target->region_id;
237
		sblog << (n.empty() ? "   " : " after {  ");
238
		dump_common(n);
239
		sblog << "   ";
240
		dump_live_values(n, true);
241
 
242
		++level;
243
	} else {
244
		--level;
245
 
246
		if (!n.empty()) {
247
			indent();
248
			sblog << "} end_repeat   ";
249
			dump_live_values(n, false);
250
		}
251
	}
252
	return true;
253
}
254
 
255
bool dump::visit(depart_node& n, bool enter) {
256
	if (enter) {
257
		indent();
258
		dump_flags(n);
259
		sblog << "depart region #" << n.target->region_id;
260
		sblog << (n.empty() ? "   " : " after {  ");
261
		dump_common(n);
262
		sblog << "  ";
263
		dump_live_values(n, true);
264
 
265
		++level;
266
	} else {
267
		--level;
268
		if (!n.empty()) {
269
			indent();
270
			sblog << "} end_depart   ";
271
			dump_live_values(n, false);
272
		}
273
	}
274
	return true;
275
}
276
 
277
bool dump::visit(if_node& n, bool enter) {
278
	if (enter) {
279
		indent();
280
		dump_flags(n);
281
		sblog << "if " << *n.cond << "    ";
282
		dump_common(n);
283
		sblog << "   ";
284
		dump_live_values(n, true);
285
 
286
		indent();
287
		sblog <<"{\n";
288
 
289
		++level;
290
	} else {
291
		--level;
292
		indent();
293
		sblog << "} endif   ";
294
		dump_live_values(n, false);
295
	}
296
	return true;
297
}
298
 
299
void dump::indent() {
300
	sblog.print_wl("", level * 4);
301
}
302
 
303
void dump::dump_vec(const vvec & vv) {
304
	bool first = true;
305
	for(vvec::const_iterator I = vv.begin(), E = vv.end(); I != E; ++I) {
306
		value *v = *I;
307
		if (!first)
308
			sblog << ", ";
309
		else
310
			first = false;
311
 
312
		if (v) {
313
			sblog << *v;
314
		} else {
315
			sblog << "__";
316
		}
317
	}
318
}
319
 
320
void dump::dump_rels(vvec & vv) {
321
	for(vvec::iterator I = vv.begin(), E = vv.end(); I != E; ++I) {
322
		value *v = *I;
323
 
324
		if (!v || !v->is_rel())
325
			continue;
326
 
327
		sblog << "\n\t\t\t\t\t";
328
		sblog << "    rels: " << *v << " : ";
329
		dump_vec(v->mdef);
330
		sblog << " <= ";
331
		dump_vec(v->muse);
332
	}
333
}
334
 
335
void dump::dump_op(node &n, const char *name) {
336
 
337
	if (n.pred) {
338
		alu_node &a = static_cast(n);
339
		sblog << (a.bc.pred_sel-2) << " [" << *a.pred << "] ";
340
	}
341
 
342
	sblog << name;
343
 
344
	bool has_dst = !n.dst.empty();
345
 
346
	if (n.subtype == NST_CF_INST) {
347
		cf_node *c = static_cast(&n);
348
		if (c->bc.op_ptr->flags & CF_EXP) {
349
			static const char *exp_type[] = {"PIXEL", "POS  ", "PARAM"};
350
			sblog << "  " << exp_type[c->bc.type] << " " << c->bc.array_base;
351
			has_dst = false;
352
		} else if (c->bc.op_ptr->flags & CF_STRM) {
353
			static const char *exp_type[] = {"WRITE", "WRITE_IND", "WRITE_ACK",
354
					"WRITE_IND_ACK"};
355
			sblog << "  " << exp_type[c->bc.type] << " " << c->bc.array_base
356
					<< "   ES:" << c->bc.elem_size;
357
			has_dst = false;
358
		}
359
	}
360
 
361
	sblog << "     ";
362
 
363
	if (has_dst) {
364
		dump_vec(n.dst);
365
		sblog << ",       ";
366
	}
367
 
368
	dump_vec(n.src);
369
}
370
 
371
void dump::dump_set(shader &sh, val_set& v) {
372
	sblog << "[";
373
	for(val_set::iterator I = v.begin(sh), E = v.end(sh); I != E; ++I) {
374
		value *val = *I;
375
		sblog << *val << " ";
376
	}
377
	sblog << "]";
378
}
379
 
380
void dump::dump_common(node& n) {
381
}
382
 
383
void dump::dump_flags(node &n) {
384
	if (n.flags & NF_DEAD)
385
		sblog << "### DEAD  ";
386
	if (n.flags & NF_REG_CONSTRAINT)
387
		sblog << "R_CONS  ";
388
	if (n.flags & NF_CHAN_CONSTRAINT)
389
		sblog << "CH_CONS  ";
390
	if (n.flags & NF_ALU_4SLOT)
391
		sblog << "4S  ";
392
}
393
 
394
void dump::dump_val(value* v) {
395
	sblog << *v;
396
}
397
 
398
void dump::dump_alu(alu_node *n) {
399
 
400
	if (n->is_copy_mov())
401
		sblog << "(copy) ";
402
 
403
	if (n->pred) {
404
		sblog << (n->bc.pred_sel-2) << " [" << *n->pred << "] ";
405
	}
406
 
407
	sblog << n->bc.op_ptr->name;
408
 
409
	if (n->bc.omod) {
410
		static const char *omod_str[] = {"", "*2", "*4", "/2"};
411
		sblog << omod_str[n->bc.omod];
412
	}
413
 
414
	if (n->bc.clamp) {
415
		sblog << "_sat";
416
	}
417
 
418
	bool has_dst = !n->dst.empty();
419
 
420
	sblog << "     ";
421
 
422
	if (has_dst) {
423
		dump_vec(n->dst);
424
		sblog << ",    ";
425
	}
426
 
427
	unsigned s = 0;
428
	for (vvec::iterator I = n->src.begin(), E = n->src.end(); I != E;
429
			++I, ++s) {
430
 
431
		bc_alu_src &src = n->bc.src[s];
432
 
433
		if (src.neg)
434
			sblog << "-";
435
 
436
		if (src.abs)
437
			sblog << "|";
438
 
439
		dump_val(*I);
440
 
441
		if (src.abs)
442
			sblog << "|";
443
 
444
		if (I + 1 != E)
445
			sblog << ", ";
446
	}
447
 
448
	dump_rels(n->dst);
449
	dump_rels(n->src);
450
 
451
}
452
 
453
void dump::dump_op(node* n) {
454
	if (n->type == NT_IF) {
455
		dump_op(*n, "IF ");
456
		return;
457
	}
458
 
459
	switch(n->subtype) {
460
	case NST_ALU_INST:
461
		dump_alu(static_cast(n));
462
		break;
463
	case NST_FETCH_INST:
464
		dump_op(*n, static_cast(n)->bc.op_ptr->name);
465
		break;
466
	case NST_CF_INST:
467
	case NST_ALU_CLAUSE:
468
	case NST_TEX_CLAUSE:
469
	case NST_VTX_CLAUSE:
470
		dump_op(*n, static_cast(n)->bc.op_ptr->name);
471
		break;
472
	case NST_ALU_PACKED_INST:
473
		dump_op(*n, static_cast(n)->op_ptr()->name);
474
		break;
475
	case NST_PHI:
476
		dump_op(*n, "PHI");
477
		break;
478
	case NST_PSI:
479
		dump_op(*n, "PSI");
480
		break;
481
	case NST_COPY:
482
		dump_op(*n, "COPY");
483
		break;
484
	default:
485
		dump_op(*n, "??unknown_op");
486
	}
487
}
488
 
489
void dump::dump_op_list(container_node* c) {
490
	for (node_iterator I = c->begin(), E = c->end(); I != E; ++I) {
491
		dump_op(*I);
492
		sblog << "\n";
493
	}
494
}
495
 
496
void dump::dump_queue(sched_queue& q) {
497
	for (sched_queue::iterator I = q.begin(), E = q.end(); I != E; ++I) {
498
		dump_op(*I);
499
		sblog << "\n";
500
	}
501
}
502
 
503
void dump::dump_live_values(container_node &n, bool before) {
504
	if (before) {
505
		if (!n.live_before.empty()) {
506
			sblog << "live_before: ";
507
			dump_set(sh, n.live_before);
508
		}
509
	} else {
510
		if (!n.live_after.empty()) {
511
			sblog << "live_after: ";
512
			dump_set(sh, n.live_after);
513
		}
514
	}
515
	sblog << "\n";
516
}
517
 
518
} // namespace r600_sb