1 /*
2 * Copyright © 2019 Intel Corporation
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 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * 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 NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include <gtest/gtest.h>
25 #include "brw_fs.h"
26 #include "brw_fs_builder.h"
27 #include "brw_cfg.h"
28
29 using namespace brw;
30
31 class scoreboard_test : public ::testing::Test {
32 protected:
33 scoreboard_test();
34 ~scoreboard_test() override;
35
36 struct brw_compiler *compiler;
37 struct brw_compile_params params;
38 struct intel_device_info *devinfo;
39 void *ctx;
40 struct brw_wm_prog_data *prog_data;
41 struct gl_shader_program *shader_prog;
42 fs_visitor *v;
43 fs_builder bld;
44 };
45
scoreboard_test()46 scoreboard_test::scoreboard_test()
47 : bld(NULL, 0)
48 {
49 ctx = ralloc_context(NULL);
50 compiler = rzalloc(ctx, struct brw_compiler);
51 devinfo = rzalloc(ctx, struct intel_device_info);
52 devinfo->ver = 12;
53 devinfo->verx10 = devinfo->ver * 10;
54
55 compiler->devinfo = devinfo;
56 brw_init_isa_info(&compiler->isa, devinfo);
57
58 params = {};
59 params.mem_ctx = ctx;
60
61 prog_data = ralloc(ctx, struct brw_wm_prog_data);
62 nir_shader *shader =
63 nir_shader_create(ctx, MESA_SHADER_FRAGMENT, NULL, NULL);
64
65 v = new fs_visitor(compiler, ¶ms, NULL, &prog_data->base, shader, 8,
66 false, false);
67
68 bld = fs_builder(v).at_end();
69 }
70
~scoreboard_test()71 scoreboard_test::~scoreboard_test()
72 {
73 delete v;
74 v = NULL;
75
76 ralloc_free(ctx);
77 ctx = NULL;
78 }
79
80 static fs_inst *
instruction(bblock_t * block,int num)81 instruction(bblock_t *block, int num)
82 {
83 fs_inst *inst = (fs_inst *)block->start();
84 for (int i = 0; i < num; i++) {
85 inst = (fs_inst *)inst->next;
86 }
87 return inst;
88 }
89
90 static void
lower_scoreboard(fs_visitor * v)91 lower_scoreboard(fs_visitor *v)
92 {
93 const bool print = getenv("TEST_DEBUG");
94
95 if (print) {
96 fprintf(stderr, "= Before =\n");
97 v->cfg->dump();
98 }
99
100 brw_fs_lower_scoreboard(*v);
101
102 if (print) {
103 fprintf(stderr, "\n= After =\n");
104 v->cfg->dump();
105 }
106 }
107
108 fs_inst *
emit_SEND(const fs_builder & bld,const fs_reg & dst,const fs_reg & desc,const fs_reg & payload)109 emit_SEND(const fs_builder &bld, const fs_reg &dst,
110 const fs_reg &desc, const fs_reg &payload)
111 {
112 fs_inst *inst = bld.emit(SHADER_OPCODE_SEND, dst, desc, desc, payload);
113 inst->mlen = 1;
114 return inst;
115 }
116
117 static tgl_swsb
tgl_swsb_testcase(unsigned regdist,unsigned sbid,enum tgl_sbid_mode mode)118 tgl_swsb_testcase(unsigned regdist, unsigned sbid, enum tgl_sbid_mode mode)
119 {
120 tgl_swsb swsb = tgl_swsb_sbid(mode, sbid);
121 swsb.regdist = regdist;
122 return swsb;
123 }
124
operator ==(const tgl_swsb & a,const tgl_swsb & b)125 bool operator ==(const tgl_swsb &a, const tgl_swsb &b)
126 {
127 return a.mode == b.mode &&
128 a.regdist == b.regdist &&
129 (a.mode == TGL_SBID_NULL || a.sbid == b.sbid);
130 }
131
operator <<(std::ostream & os,const tgl_swsb & swsb)132 std::ostream &operator<<(std::ostream &os, const tgl_swsb &swsb) {
133 if (swsb.regdist)
134 os << "@" << swsb.regdist;
135
136 if (swsb.mode) {
137 if (swsb.regdist)
138 os << " ";
139 os << "$" << swsb.sbid;
140 if (swsb.mode & TGL_SBID_DST)
141 os << ".dst";
142 if (swsb.mode & TGL_SBID_SRC)
143 os << ".src";
144 }
145
146 return os;
147 }
148
TEST_F(scoreboard_test,RAW_inorder_inorder)149 TEST_F(scoreboard_test, RAW_inorder_inorder)
150 {
151 fs_reg g[16];
152 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
153 g[i] = v->vgrf(glsl_int_type());
154
155 fs_reg x = v->vgrf(glsl_int_type());
156 fs_reg y = v->vgrf(glsl_int_type());
157 bld.ADD( x, g[1], g[2]);
158 bld.MUL( y, g[3], g[4]);
159 bld.AND(g[5], x, y);
160
161 v->calculate_cfg();
162 bblock_t *block0 = v->cfg->blocks[0];
163 ASSERT_EQ(0, block0->start_ip);
164 ASSERT_EQ(2, block0->end_ip);
165
166 lower_scoreboard(v);
167 ASSERT_EQ(0, block0->start_ip);
168 ASSERT_EQ(2, block0->end_ip);
169
170 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
171 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
172 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_regdist(1));
173 }
174
TEST_F(scoreboard_test,RAW_inorder_outoforder)175 TEST_F(scoreboard_test, RAW_inorder_outoforder)
176 {
177 fs_reg g[16];
178 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
179 g[i] = v->vgrf(glsl_int_type());
180
181 fs_reg x = v->vgrf(glsl_int_type());
182 bld.ADD( x, g[1], g[2]);
183 bld.MUL( g[3], g[4], g[5]);
184 emit_SEND(bld, g[6], g[7], x);
185
186 v->calculate_cfg();
187 bblock_t *block0 = v->cfg->blocks[0];
188 ASSERT_EQ(0, block0->start_ip);
189 ASSERT_EQ(2, block0->end_ip);
190
191 lower_scoreboard(v);
192 ASSERT_EQ(0, block0->start_ip);
193 ASSERT_EQ(2, block0->end_ip);
194
195 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
196 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
197 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_testcase(2, 0, TGL_SBID_SET));
198 }
199
TEST_F(scoreboard_test,RAW_outoforder_inorder)200 TEST_F(scoreboard_test, RAW_outoforder_inorder)
201 {
202 fs_reg g[16];
203 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
204 g[i] = v->vgrf(glsl_int_type());
205
206 fs_reg x = v->vgrf(glsl_int_type());
207 fs_reg y = v->vgrf(glsl_int_type());
208 emit_SEND(bld, x, g[1], g[2]);
209 bld.MUL( y, g[3], g[4]);
210 bld.AND( g[5], x, y);
211
212 v->calculate_cfg();
213 bblock_t *block0 = v->cfg->blocks[0];
214 ASSERT_EQ(0, block0->start_ip);
215 ASSERT_EQ(2, block0->end_ip);
216
217 lower_scoreboard(v);
218 ASSERT_EQ(0, block0->start_ip);
219 ASSERT_EQ(2, block0->end_ip);
220
221 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
222 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
223 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_testcase(1, 0, TGL_SBID_DST));
224 }
225
TEST_F(scoreboard_test,RAW_outoforder_outoforder)226 TEST_F(scoreboard_test, RAW_outoforder_outoforder)
227 {
228 fs_reg g[16];
229 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
230 g[i] = v->vgrf(glsl_int_type());
231
232 /* The second SEND depends on the first, and would need to refer to two
233 * SBIDs. Since it is not possible we expect a SYNC instruction to be
234 * added.
235 */
236 fs_reg x = v->vgrf(glsl_int_type());
237 emit_SEND(bld, x, g[1], g[2]);
238 emit_SEND(bld, g[3], x, g[4])->sfid++;
239
240 v->calculate_cfg();
241 bblock_t *block0 = v->cfg->blocks[0];
242 ASSERT_EQ(0, block0->start_ip);
243 ASSERT_EQ(1, block0->end_ip);
244
245 lower_scoreboard(v);
246 ASSERT_EQ(0, block0->start_ip);
247 ASSERT_EQ(2, block0->end_ip);
248
249 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
250
251 fs_inst *sync = instruction(block0, 1);
252 EXPECT_EQ(sync->opcode, BRW_OPCODE_SYNC);
253 EXPECT_EQ(sync->sched, tgl_swsb_sbid(TGL_SBID_DST, 0));
254
255 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_sbid(TGL_SBID_SET, 1));
256 }
257
TEST_F(scoreboard_test,WAR_inorder_inorder)258 TEST_F(scoreboard_test, WAR_inorder_inorder)
259 {
260 fs_reg g[16];
261 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
262 g[i] = v->vgrf(glsl_int_type());
263
264 fs_reg x = v->vgrf(glsl_int_type());
265 bld.ADD(g[1], x, g[2]);
266 bld.MUL(g[3], g[4], g[5]);
267 bld.AND( x, g[6], g[7]);
268
269 v->calculate_cfg();
270 bblock_t *block0 = v->cfg->blocks[0];
271 ASSERT_EQ(0, block0->start_ip);
272 ASSERT_EQ(2, block0->end_ip);
273
274 lower_scoreboard(v);
275 ASSERT_EQ(0, block0->start_ip);
276 ASSERT_EQ(2, block0->end_ip);
277
278 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
279 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
280 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_null());
281 }
282
TEST_F(scoreboard_test,WAR_inorder_outoforder)283 TEST_F(scoreboard_test, WAR_inorder_outoforder)
284 {
285 fs_reg g[16];
286 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
287 g[i] = v->vgrf(glsl_int_type());
288
289 fs_reg x = v->vgrf(glsl_int_type());
290 bld.ADD( g[1], x, g[2]);
291 bld.MUL( g[3], g[4], g[5]);
292 emit_SEND(bld, x, g[6], g[7]);
293
294 v->calculate_cfg();
295 bblock_t *block0 = v->cfg->blocks[0];
296 ASSERT_EQ(0, block0->start_ip);
297 ASSERT_EQ(2, block0->end_ip);
298
299 lower_scoreboard(v);
300 ASSERT_EQ(0, block0->start_ip);
301 ASSERT_EQ(2, block0->end_ip);
302
303 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
304 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
305 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_testcase(2, 0, TGL_SBID_SET));
306 }
307
TEST_F(scoreboard_test,WAR_outoforder_inorder)308 TEST_F(scoreboard_test, WAR_outoforder_inorder)
309 {
310 fs_reg g[16];
311 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
312 g[i] = v->vgrf(glsl_int_type());
313
314 fs_reg x = v->vgrf(glsl_int_type());
315 emit_SEND(bld, g[1], g[2], x);
316 bld.MUL( g[4], g[5], g[6]);
317 bld.AND( x, g[7], g[8]);
318
319 v->calculate_cfg();
320 bblock_t *block0 = v->cfg->blocks[0];
321 ASSERT_EQ(0, block0->start_ip);
322 ASSERT_EQ(2, block0->end_ip);
323
324 lower_scoreboard(v);
325 ASSERT_EQ(0, block0->start_ip);
326 ASSERT_EQ(2, block0->end_ip);
327
328 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
329 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
330 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_sbid(TGL_SBID_SRC, 0));
331 }
332
TEST_F(scoreboard_test,WAR_outoforder_outoforder)333 TEST_F(scoreboard_test, WAR_outoforder_outoforder)
334 {
335 fs_reg g[16];
336 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
337 g[i] = v->vgrf(glsl_int_type());
338
339 fs_reg x = v->vgrf(glsl_int_type());
340 emit_SEND(bld, g[1], g[2], x);
341 emit_SEND(bld, x, g[3], g[4])->sfid++;
342
343 v->calculate_cfg();
344 bblock_t *block0 = v->cfg->blocks[0];
345 ASSERT_EQ(0, block0->start_ip);
346 ASSERT_EQ(1, block0->end_ip);
347
348 lower_scoreboard(v);
349 ASSERT_EQ(0, block0->start_ip);
350 ASSERT_EQ(2, block0->end_ip);
351
352 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
353
354 fs_inst *sync = instruction(block0, 1);
355 EXPECT_EQ(sync->opcode, BRW_OPCODE_SYNC);
356 EXPECT_EQ(sync->sched, tgl_swsb_sbid(TGL_SBID_SRC, 0));
357
358 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_sbid(TGL_SBID_SET, 1));
359 }
360
TEST_F(scoreboard_test,WAW_inorder_inorder)361 TEST_F(scoreboard_test, WAW_inorder_inorder)
362 {
363 fs_reg g[16];
364 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
365 g[i] = v->vgrf(glsl_int_type());
366
367 fs_reg x = v->vgrf(glsl_int_type());
368 bld.ADD( x, g[1], g[2]);
369 bld.MUL(g[3], g[4], g[5]);
370 bld.AND( x, g[6], g[7]);
371
372 v->calculate_cfg();
373 bblock_t *block0 = v->cfg->blocks[0];
374 ASSERT_EQ(0, block0->start_ip);
375 ASSERT_EQ(2, block0->end_ip);
376
377 lower_scoreboard(v);
378 ASSERT_EQ(0, block0->start_ip);
379 ASSERT_EQ(2, block0->end_ip);
380
381 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
382 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
383
384 /* NOTE: We only need this RegDist if a long instruction is followed by a
385 * short one. The pass is currently conservative about this and adding the
386 * annotation.
387 */
388 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_regdist(2));
389 }
390
TEST_F(scoreboard_test,WAW_inorder_outoforder)391 TEST_F(scoreboard_test, WAW_inorder_outoforder)
392 {
393 fs_reg g[16];
394 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
395 g[i] = v->vgrf(glsl_int_type());
396
397 fs_reg x = v->vgrf(glsl_int_type());
398 bld.ADD( x, g[1], g[2]);
399 bld.MUL( g[3], g[4], g[5]);
400 emit_SEND(bld, x, g[6], g[7]);
401
402 v->calculate_cfg();
403 bblock_t *block0 = v->cfg->blocks[0];
404 ASSERT_EQ(0, block0->start_ip);
405 ASSERT_EQ(2, block0->end_ip);
406
407 lower_scoreboard(v);
408 ASSERT_EQ(0, block0->start_ip);
409 ASSERT_EQ(2, block0->end_ip);
410
411 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
412 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
413 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_testcase(2, 0, TGL_SBID_SET));
414 }
415
TEST_F(scoreboard_test,WAW_outoforder_inorder)416 TEST_F(scoreboard_test, WAW_outoforder_inorder)
417 {
418 fs_reg g[16];
419 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
420 g[i] = v->vgrf(glsl_int_type());
421
422 fs_reg x = v->vgrf(glsl_int_type());
423 emit_SEND(bld, x, g[1], g[2]);
424 bld.MUL( g[3], g[4], g[5]);
425 bld.AND( x, g[6], g[7]);
426
427 v->calculate_cfg();
428 bblock_t *block0 = v->cfg->blocks[0];
429 ASSERT_EQ(0, block0->start_ip);
430 ASSERT_EQ(2, block0->end_ip);
431
432 lower_scoreboard(v);
433 ASSERT_EQ(0, block0->start_ip);
434 ASSERT_EQ(2, block0->end_ip);
435
436 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
437 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
438 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_sbid(TGL_SBID_DST, 0));
439 }
440
TEST_F(scoreboard_test,WAW_outoforder_outoforder)441 TEST_F(scoreboard_test, WAW_outoforder_outoforder)
442 {
443 fs_reg g[16];
444 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
445 g[i] = v->vgrf(glsl_int_type());
446
447 fs_reg x = v->vgrf(glsl_int_type());
448 emit_SEND(bld, x, g[1], g[2]);
449 emit_SEND(bld, x, g[3], g[4])->sfid++;
450
451 v->calculate_cfg();
452 bblock_t *block0 = v->cfg->blocks[0];
453 ASSERT_EQ(0, block0->start_ip);
454 ASSERT_EQ(1, block0->end_ip);
455
456 lower_scoreboard(v);
457 ASSERT_EQ(0, block0->start_ip);
458 ASSERT_EQ(2, block0->end_ip);
459
460 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
461
462 fs_inst *sync = instruction(block0, 1);
463 EXPECT_EQ(sync->opcode, BRW_OPCODE_SYNC);
464 EXPECT_EQ(sync->sched, tgl_swsb_sbid(TGL_SBID_DST, 0));
465
466 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_sbid(TGL_SBID_SET, 1));
467 }
468
469
TEST_F(scoreboard_test,loop1)470 TEST_F(scoreboard_test, loop1)
471 {
472 fs_reg g[16];
473 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
474 g[i] = v->vgrf(glsl_int_type());
475
476 fs_reg x = v->vgrf(glsl_int_type());
477 bld.XOR( x, g[1], g[2]);
478
479 bld.emit(BRW_OPCODE_DO);
480
481 bld.ADD( x, g[1], g[2]);
482 bld.emit(BRW_OPCODE_WHILE)->predicate = BRW_PREDICATE_NORMAL;
483
484 bld.MUL( x, g[1], g[2]);
485
486 v->calculate_cfg();
487 lower_scoreboard(v);
488
489 bblock_t *body = v->cfg->blocks[2];
490 fs_inst *add = instruction(body, 0);
491 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
492 EXPECT_EQ(add->sched, tgl_swsb_regdist(1));
493
494 bblock_t *last_block = v->cfg->blocks[3];
495 fs_inst *mul = instruction(last_block, 0);
496 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
497 EXPECT_EQ(mul->sched, tgl_swsb_regdist(1));
498 }
499
TEST_F(scoreboard_test,loop2)500 TEST_F(scoreboard_test, loop2)
501 {
502 fs_reg g[16];
503 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
504 g[i] = v->vgrf(glsl_int_type());
505
506 fs_reg x = v->vgrf(glsl_int_type());
507 bld.XOR( x, g[1], g[2]);
508 bld.XOR(g[3], g[1], g[2]);
509 bld.XOR(g[4], g[1], g[2]);
510 bld.XOR(g[5], g[1], g[2]);
511
512 bld.emit(BRW_OPCODE_DO);
513
514 bld.ADD( x, g[1], g[2]);
515 bld.emit(BRW_OPCODE_WHILE)->predicate = BRW_PREDICATE_NORMAL;
516
517 bld.MUL( x, g[1], g[2]);
518
519 v->calculate_cfg();
520 lower_scoreboard(v);
521
522 /* Now the write in ADD has the tightest RegDist for both ADD and MUL. */
523
524 bblock_t *body = v->cfg->blocks[2];
525 fs_inst *add = instruction(body, 0);
526 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
527 EXPECT_EQ(add->sched, tgl_swsb_regdist(2));
528
529 bblock_t *last_block = v->cfg->blocks[3];
530 fs_inst *mul = instruction(last_block, 0);
531 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
532 EXPECT_EQ(mul->sched, tgl_swsb_regdist(2));
533 }
534
TEST_F(scoreboard_test,loop3)535 TEST_F(scoreboard_test, loop3)
536 {
537 fs_reg g[16];
538 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
539 g[i] = v->vgrf(glsl_int_type());
540
541 fs_reg x = v->vgrf(glsl_int_type());
542 bld.XOR( x, g[1], g[2]);
543
544 bld.emit(BRW_OPCODE_DO);
545
546 /* For the ADD in the loop body this extra distance will always apply. */
547 bld.XOR(g[3], g[1], g[2]);
548 bld.XOR(g[4], g[1], g[2]);
549 bld.XOR(g[5], g[1], g[2]);
550 bld.XOR(g[6], g[1], g[2]);
551
552 bld.ADD( x, g[1], g[2]);
553 bld.emit(BRW_OPCODE_WHILE)->predicate = BRW_PREDICATE_NORMAL;
554
555 bld.MUL( x, g[1], g[2]);
556
557 v->calculate_cfg();
558 lower_scoreboard(v);
559
560 bblock_t *body = v->cfg->blocks[2];
561 fs_inst *add = instruction(body, 4);
562 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
563 EXPECT_EQ(add->sched, tgl_swsb_regdist(5));
564
565 bblock_t *last_block = v->cfg->blocks[3];
566 fs_inst *mul = instruction(last_block, 0);
567 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
568 EXPECT_EQ(mul->sched, tgl_swsb_regdist(1));
569 }
570
571
TEST_F(scoreboard_test,conditional1)572 TEST_F(scoreboard_test, conditional1)
573 {
574 fs_reg g[16];
575 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
576 g[i] = v->vgrf(glsl_int_type());
577
578 fs_reg x = v->vgrf(glsl_int_type());
579 bld.XOR( x, g[1], g[2]);
580 bld.emit(BRW_OPCODE_IF);
581
582 bld.ADD( x, g[1], g[2]);
583
584 bld.emit(BRW_OPCODE_ENDIF);
585 bld.MUL( x, g[1], g[2]);
586
587 v->calculate_cfg();
588 lower_scoreboard(v);
589
590 bblock_t *body = v->cfg->blocks[1];
591 fs_inst *add = instruction(body, 0);
592 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
593 EXPECT_EQ(add->sched, tgl_swsb_regdist(2));
594
595 bblock_t *last_block = v->cfg->blocks[2];
596 fs_inst *mul = instruction(last_block, 1);
597 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
598 EXPECT_EQ(mul->sched, tgl_swsb_regdist(2));
599 }
600
TEST_F(scoreboard_test,conditional2)601 TEST_F(scoreboard_test, conditional2)
602 {
603 fs_reg g[16];
604 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
605 g[i] = v->vgrf(glsl_int_type());
606
607 fs_reg x = v->vgrf(glsl_int_type());
608 bld.XOR( x, g[1], g[2]);
609 bld.XOR(g[3], g[1], g[2]);
610 bld.XOR(g[4], g[1], g[2]);
611 bld.XOR(g[5], g[1], g[2]);
612 bld.emit(BRW_OPCODE_IF);
613
614 bld.ADD( x, g[1], g[2]);
615
616 bld.emit(BRW_OPCODE_ENDIF);
617 bld.MUL( x, g[1], g[2]);
618
619 v->calculate_cfg();
620 lower_scoreboard(v);
621
622 bblock_t *body = v->cfg->blocks[1];
623 fs_inst *add = instruction(body, 0);
624 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
625 EXPECT_EQ(add->sched, tgl_swsb_regdist(5));
626
627 bblock_t *last_block = v->cfg->blocks[2];
628 fs_inst *mul = instruction(last_block, 1);
629 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
630 EXPECT_EQ(mul->sched, tgl_swsb_regdist(2));
631 }
632
TEST_F(scoreboard_test,conditional3)633 TEST_F(scoreboard_test, conditional3)
634 {
635 fs_reg g[16];
636 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
637 g[i] = v->vgrf(glsl_int_type());
638
639 fs_reg x = v->vgrf(glsl_int_type());
640 bld.XOR( x, g[1], g[2]);
641 bld.emit(BRW_OPCODE_IF);
642
643 bld.XOR(g[3], g[1], g[2]);
644 bld.XOR(g[4], g[1], g[2]);
645 bld.XOR(g[5], g[1], g[2]);
646 bld.ADD( x, g[1], g[2]);
647
648 bld.emit(BRW_OPCODE_ENDIF);
649 bld.MUL( x, g[1], g[2]);
650
651 v->calculate_cfg();
652 lower_scoreboard(v);
653
654 bblock_t *body = v->cfg->blocks[1];
655 fs_inst *add = instruction(body, 3);
656 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
657 EXPECT_EQ(add->sched, tgl_swsb_regdist(5));
658
659 bblock_t *last_block = v->cfg->blocks[2];
660 fs_inst *mul = instruction(last_block, 1);
661 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
662 EXPECT_EQ(mul->sched, tgl_swsb_regdist(2));
663 }
664
TEST_F(scoreboard_test,conditional4)665 TEST_F(scoreboard_test, conditional4)
666 {
667 fs_reg g[16];
668 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
669 g[i] = v->vgrf(glsl_int_type());
670
671 fs_reg x = v->vgrf(glsl_int_type());
672 bld.XOR( x, g[1], g[2]);
673 bld.emit(BRW_OPCODE_IF);
674
675 bld.ADD( x, g[1], g[2]);
676 bld.XOR(g[3], g[1], g[2]);
677 bld.XOR(g[4], g[1], g[2]);
678 bld.XOR(g[5], g[1], g[2]);
679
680 bld.emit(BRW_OPCODE_ENDIF);
681 bld.MUL( x, g[1], g[2]);
682
683 v->calculate_cfg();
684 lower_scoreboard(v);
685
686 bblock_t *body = v->cfg->blocks[1];
687 fs_inst *add = instruction(body, 0);
688 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
689 EXPECT_EQ(add->sched, tgl_swsb_regdist(2));
690
691 bblock_t *last_block = v->cfg->blocks[2];
692 fs_inst *mul = instruction(last_block, 1);
693 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
694 EXPECT_EQ(mul->sched, tgl_swsb_regdist(3));
695 }
696
TEST_F(scoreboard_test,conditional5)697 TEST_F(scoreboard_test, conditional5)
698 {
699 fs_reg g[16];
700 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
701 g[i] = v->vgrf(glsl_int_type());
702
703 fs_reg x = v->vgrf(glsl_int_type());
704 bld.XOR( x, g[1], g[2]);
705 bld.emit(BRW_OPCODE_IF);
706
707 bld.ADD( x, g[1], g[2]);
708 bld.emit(BRW_OPCODE_ELSE);
709
710 bld.ROL( x, g[1], g[2]);
711
712 bld.emit(BRW_OPCODE_ENDIF);
713 bld.MUL( x, g[1], g[2]);
714
715 v->calculate_cfg();
716 lower_scoreboard(v);
717
718 bblock_t *then_body = v->cfg->blocks[1];
719 fs_inst *add = instruction(then_body, 0);
720 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
721 EXPECT_EQ(add->sched, tgl_swsb_regdist(2));
722
723 bblock_t *else_body = v->cfg->blocks[2];
724 fs_inst *rol = instruction(else_body, 0);
725 EXPECT_EQ(rol->opcode, BRW_OPCODE_ROL);
726 EXPECT_EQ(rol->sched, tgl_swsb_regdist(2));
727
728 bblock_t *last_block = v->cfg->blocks[3];
729 fs_inst *mul = instruction(last_block, 1);
730 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
731 EXPECT_EQ(mul->sched, tgl_swsb_regdist(2));
732 }
733
TEST_F(scoreboard_test,conditional6)734 TEST_F(scoreboard_test, conditional6)
735 {
736 fs_reg g[16];
737 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
738 g[i] = v->vgrf(glsl_int_type());
739
740 fs_reg x = v->vgrf(glsl_int_type());
741 bld.XOR( x, g[1], g[2]);
742 bld.emit(BRW_OPCODE_IF);
743
744 bld.XOR(g[3], g[1], g[2]);
745 bld.XOR(g[4], g[1], g[2]);
746 bld.XOR(g[5], g[1], g[2]);
747 bld.ADD( x, g[1], g[2]);
748 bld.emit(BRW_OPCODE_ELSE);
749
750 bld.XOR(g[6], g[1], g[2]);
751 bld.XOR(g[7], g[1], g[2]);
752 bld.XOR(g[8], g[1], g[2]);
753 bld.XOR(g[9], g[1], g[2]);
754 bld.ROL( x, g[1], g[2]);
755
756 bld.emit(BRW_OPCODE_ENDIF);
757 bld.MUL( x, g[1], g[2]);
758
759 v->calculate_cfg();
760 lower_scoreboard(v);
761
762 bblock_t *then_body = v->cfg->blocks[1];
763 fs_inst *add = instruction(then_body, 3);
764 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
765 EXPECT_EQ(add->sched, tgl_swsb_regdist(5));
766
767 bblock_t *else_body = v->cfg->blocks[2];
768 fs_inst *rol = instruction(else_body, 4);
769 EXPECT_EQ(rol->opcode, BRW_OPCODE_ROL);
770 EXPECT_EQ(rol->sched, tgl_swsb_regdist(6));
771
772 bblock_t *last_block = v->cfg->blocks[3];
773 fs_inst *mul = instruction(last_block, 1);
774 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
775 EXPECT_EQ(mul->sched, tgl_swsb_regdist(2));
776 }
777
TEST_F(scoreboard_test,conditional7)778 TEST_F(scoreboard_test, conditional7)
779 {
780 fs_reg g[16];
781 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
782 g[i] = v->vgrf(glsl_int_type());
783
784 fs_reg x = v->vgrf(glsl_int_type());
785 bld.XOR( x, g[1], g[2]);
786 bld.emit(BRW_OPCODE_IF);
787
788 bld.ADD( x, g[1], g[2]);
789 bld.XOR(g[3], g[1], g[2]);
790 bld.XOR(g[4], g[1], g[2]);
791 bld.XOR(g[5], g[1], g[2]);
792 bld.emit(BRW_OPCODE_ELSE);
793
794 bld.ROL( x, g[1], g[2]);
795 bld.XOR(g[6], g[1], g[2]);
796 bld.XOR(g[7], g[1], g[2]);
797 bld.XOR(g[8], g[1], g[2]);
798 bld.XOR(g[9], g[1], g[2]);
799
800 bld.emit(BRW_OPCODE_ENDIF);
801 bld.MUL( x, g[1], g[2]);
802
803 v->calculate_cfg();
804 lower_scoreboard(v);
805
806 bblock_t *then_body = v->cfg->blocks[1];
807 fs_inst *add = instruction(then_body, 0);
808 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
809 EXPECT_EQ(add->sched, tgl_swsb_regdist(2));
810
811 bblock_t *else_body = v->cfg->blocks[2];
812 fs_inst *rol = instruction(else_body, 0);
813 EXPECT_EQ(rol->opcode, BRW_OPCODE_ROL);
814 EXPECT_EQ(rol->sched, tgl_swsb_regdist(2));
815
816 bblock_t *last_block = v->cfg->blocks[3];
817 fs_inst *mul = instruction(last_block, 1);
818 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
819 EXPECT_EQ(mul->sched, tgl_swsb_regdist(6));
820 }
821
TEST_F(scoreboard_test,conditional8)822 TEST_F(scoreboard_test, conditional8)
823 {
824 fs_reg g[16];
825 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
826 g[i] = v->vgrf(glsl_int_type());
827
828 fs_reg x = v->vgrf(glsl_int_type());
829 bld.XOR( x, g[1], g[2]);
830 bld.XOR(g[3], g[1], g[2]);
831 bld.XOR(g[4], g[1], g[2]);
832 bld.XOR(g[5], g[1], g[2]);
833 bld.XOR(g[6], g[1], g[2]);
834 bld.XOR(g[7], g[1], g[2]);
835 bld.emit(BRW_OPCODE_IF);
836
837 bld.ADD( x, g[1], g[2]);
838 bld.emit(BRW_OPCODE_ELSE);
839
840 bld.ROL( x, g[1], g[2]);
841
842 bld.emit(BRW_OPCODE_ENDIF);
843 bld.MUL( x, g[1], g[2]);
844
845 v->calculate_cfg();
846 lower_scoreboard(v);
847
848 bblock_t *then_body = v->cfg->blocks[1];
849 fs_inst *add = instruction(then_body, 0);
850 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
851 EXPECT_EQ(add->sched, tgl_swsb_regdist(7));
852
853 /* Note that the ROL will have RegDist 2 and not 7, illustrating the
854 * physical CFG edge between the then-block and the else-block.
855 */
856 bblock_t *else_body = v->cfg->blocks[2];
857 fs_inst *rol = instruction(else_body, 0);
858 EXPECT_EQ(rol->opcode, BRW_OPCODE_ROL);
859 EXPECT_EQ(rol->sched, tgl_swsb_regdist(2));
860
861 bblock_t *last_block = v->cfg->blocks[3];
862 fs_inst *mul = instruction(last_block, 1);
863 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
864 EXPECT_EQ(mul->sched, tgl_swsb_regdist(2));
865 }
866
TEST_F(scoreboard_test,gfx125_RaR_over_different_pipes)867 TEST_F(scoreboard_test, gfx125_RaR_over_different_pipes)
868 {
869 devinfo->verx10 = 125;
870 brw_init_isa_info(&compiler->isa, devinfo);
871
872 fs_reg a = v->vgrf(glsl_int_type());
873 fs_reg b = v->vgrf(glsl_int_type());
874 fs_reg f = v->vgrf(glsl_float_type());
875 fs_reg x = v->vgrf(glsl_int_type());
876
877 bld.ADD(f, x, x);
878 bld.ADD(a, x, x);
879 bld.ADD(x, b, b);
880
881 v->calculate_cfg();
882 bblock_t *block0 = v->cfg->blocks[0];
883 ASSERT_EQ(0, block0->start_ip);
884 ASSERT_EQ(2, block0->end_ip);
885
886 lower_scoreboard(v);
887 ASSERT_EQ(0, block0->start_ip);
888 ASSERT_EQ(2, block0->end_ip);
889
890 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
891 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
892 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_regdist(1));
893 }
894