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_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 brw_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 = brw_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_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 brw_builder & bld,const brw_reg & dst,const brw_reg & desc,const brw_reg & payload)109 emit_SEND(const brw_builder &bld, const brw_reg &dst,
110 const brw_reg &desc, const brw_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 inline struct tgl_swsb
regdist(enum tgl_pipe pipe,unsigned d)118 regdist(enum tgl_pipe pipe, unsigned d)
119 {
120 assert(d);
121 const struct tgl_swsb swsb = { d, pipe };
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.pipe == b.pipe &&
129 a.regdist == b.regdist &&
130 (a.mode == TGL_SBID_NULL || a.sbid == b.sbid);
131 }
132
operator <<(std::ostream & os,const tgl_swsb & swsb)133 std::ostream &operator<<(std::ostream &os, const tgl_swsb &swsb) {
134 char *buf;
135 size_t len;
136 FILE *f = open_memstream(&buf, &len);
137
138 /* Because we don't have a devinfo to pass here, for TGL we'll see
139 * F@1 annotations instead of @1 since the float pipe is the only one
140 * used there.
141 */
142 brw_print_swsb(f, NULL, swsb);
143 fflush(f);
144 fclose(f);
145
146 os << buf;
147 free(buf);
148
149 return os;
150 }
151
TEST_F(scoreboard_test,RAW_inorder_inorder)152 TEST_F(scoreboard_test, RAW_inorder_inorder)
153 {
154 brw_reg g[16];
155 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
156 g[i] = bld.vgrf(BRW_TYPE_D);
157
158 brw_reg x = bld.vgrf(BRW_TYPE_D);
159 brw_reg y = bld.vgrf(BRW_TYPE_D);
160 bld.ADD( x, g[1], g[2]);
161 bld.MUL( y, g[3], g[4]);
162 bld.AND(g[5], x, y);
163
164 brw_calculate_cfg(*v);
165 bblock_t *block0 = v->cfg->blocks[0];
166 ASSERT_EQ(0, block0->start_ip);
167 ASSERT_EQ(2, block0->end_ip);
168
169 lower_scoreboard(v);
170 ASSERT_EQ(0, block0->start_ip);
171 ASSERT_EQ(2, block0->end_ip);
172
173 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
174 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
175 EXPECT_EQ(instruction(block0, 2)->sched, regdist(TGL_PIPE_FLOAT, 1));
176 }
177
TEST_F(scoreboard_test,RAW_inorder_outoforder)178 TEST_F(scoreboard_test, RAW_inorder_outoforder)
179 {
180 brw_reg g[16];
181 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
182 g[i] = bld.vgrf(BRW_TYPE_D);
183
184 brw_reg x = bld.vgrf(BRW_TYPE_D);
185 bld.ADD( x, g[1], g[2]);
186 bld.MUL( g[3], g[4], g[5]);
187 emit_SEND(bld, g[6], g[7], x);
188
189 brw_calculate_cfg(*v);
190 bblock_t *block0 = v->cfg->blocks[0];
191 ASSERT_EQ(0, block0->start_ip);
192 ASSERT_EQ(2, block0->end_ip);
193
194 lower_scoreboard(v);
195 ASSERT_EQ(0, block0->start_ip);
196 ASSERT_EQ(2, block0->end_ip);
197
198 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
199 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
200
201 tgl_swsb expected = {
202 .regdist = 2,
203 .pipe = TGL_PIPE_FLOAT,
204 .mode = TGL_SBID_SET,
205 };
206
207 EXPECT_EQ(instruction(block0, 2)->sched, expected);
208 }
209
TEST_F(scoreboard_test,RAW_outoforder_inorder)210 TEST_F(scoreboard_test, RAW_outoforder_inorder)
211 {
212 brw_reg g[16];
213 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
214 g[i] = bld.vgrf(BRW_TYPE_D);
215
216 brw_reg x = bld.vgrf(BRW_TYPE_D);
217 brw_reg y = bld.vgrf(BRW_TYPE_D);
218 emit_SEND(bld, x, g[1], g[2]);
219 bld.MUL( y, g[3], g[4]);
220 bld.AND( g[5], x, y);
221
222 brw_calculate_cfg(*v);
223 bblock_t *block0 = v->cfg->blocks[0];
224 ASSERT_EQ(0, block0->start_ip);
225 ASSERT_EQ(2, block0->end_ip);
226
227 lower_scoreboard(v);
228 ASSERT_EQ(0, block0->start_ip);
229 ASSERT_EQ(2, block0->end_ip);
230
231 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
232 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
233
234 tgl_swsb expected = {
235 .regdist = 1,
236 .pipe = TGL_PIPE_FLOAT,
237 .mode = TGL_SBID_DST,
238 };
239
240 EXPECT_EQ(instruction(block0, 2)->sched, expected);
241 }
242
TEST_F(scoreboard_test,RAW_outoforder_outoforder)243 TEST_F(scoreboard_test, RAW_outoforder_outoforder)
244 {
245 brw_reg g[16];
246 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
247 g[i] = bld.vgrf(BRW_TYPE_D);
248
249 /* The second SEND depends on the first, and would need to refer to two
250 * SBIDs. Since it is not possible we expect a SYNC instruction to be
251 * added.
252 */
253 brw_reg x = bld.vgrf(BRW_TYPE_D);
254 emit_SEND(bld, x, g[1], g[2]);
255 emit_SEND(bld, g[3], x, g[4])->sfid++;
256
257 brw_calculate_cfg(*v);
258 bblock_t *block0 = v->cfg->blocks[0];
259 ASSERT_EQ(0, block0->start_ip);
260 ASSERT_EQ(1, block0->end_ip);
261
262 lower_scoreboard(v);
263 ASSERT_EQ(0, block0->start_ip);
264 ASSERT_EQ(2, block0->end_ip);
265
266 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
267
268 fs_inst *sync = instruction(block0, 1);
269 EXPECT_EQ(sync->opcode, BRW_OPCODE_SYNC);
270 EXPECT_EQ(sync->sched, tgl_swsb_sbid(TGL_SBID_DST, 0));
271
272 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_sbid(TGL_SBID_SET, 1));
273 }
274
TEST_F(scoreboard_test,WAR_inorder_inorder)275 TEST_F(scoreboard_test, WAR_inorder_inorder)
276 {
277 brw_reg g[16];
278 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
279 g[i] = bld.vgrf(BRW_TYPE_D);
280
281 brw_reg x = bld.vgrf(BRW_TYPE_D);
282 bld.ADD(g[1], x, g[2]);
283 bld.MUL(g[3], g[4], g[5]);
284 bld.AND( x, g[6], g[7]);
285
286 brw_calculate_cfg(*v);
287 bblock_t *block0 = v->cfg->blocks[0];
288 ASSERT_EQ(0, block0->start_ip);
289 ASSERT_EQ(2, block0->end_ip);
290
291 lower_scoreboard(v);
292 ASSERT_EQ(0, block0->start_ip);
293 ASSERT_EQ(2, block0->end_ip);
294
295 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
296 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
297 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_null());
298 }
299
TEST_F(scoreboard_test,WAR_inorder_outoforder)300 TEST_F(scoreboard_test, WAR_inorder_outoforder)
301 {
302 brw_reg g[16];
303 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
304 g[i] = bld.vgrf(BRW_TYPE_D);
305
306 brw_reg x = bld.vgrf(BRW_TYPE_D);
307 bld.ADD( g[1], x, g[2]);
308 bld.MUL( g[3], g[4], g[5]);
309 emit_SEND(bld, x, g[6], g[7]);
310
311 brw_calculate_cfg(*v);
312 bblock_t *block0 = v->cfg->blocks[0];
313 ASSERT_EQ(0, block0->start_ip);
314 ASSERT_EQ(2, block0->end_ip);
315
316 lower_scoreboard(v);
317 ASSERT_EQ(0, block0->start_ip);
318 ASSERT_EQ(2, block0->end_ip);
319
320 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
321 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
322
323 tgl_swsb expected = {
324 .regdist = 2,
325 .pipe = TGL_PIPE_FLOAT,
326 .mode = TGL_SBID_SET,
327 };
328
329 EXPECT_EQ(instruction(block0, 2)->sched, expected);
330 }
331
TEST_F(scoreboard_test,WAR_outoforder_inorder)332 TEST_F(scoreboard_test, WAR_outoforder_inorder)
333 {
334 brw_reg g[16];
335 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
336 g[i] = bld.vgrf(BRW_TYPE_D);
337
338 brw_reg x = bld.vgrf(BRW_TYPE_D);
339 emit_SEND(bld, g[1], g[2], x);
340 bld.MUL( g[4], g[5], g[6]);
341 bld.AND( x, g[7], g[8]);
342
343 brw_calculate_cfg(*v);
344 bblock_t *block0 = v->cfg->blocks[0];
345 ASSERT_EQ(0, block0->start_ip);
346 ASSERT_EQ(2, 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 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
354 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_sbid(TGL_SBID_SRC, 0));
355 }
356
TEST_F(scoreboard_test,WAR_outoforder_outoforder)357 TEST_F(scoreboard_test, WAR_outoforder_outoforder)
358 {
359 brw_reg g[16];
360 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
361 g[i] = bld.vgrf(BRW_TYPE_D);
362
363 brw_reg x = bld.vgrf(BRW_TYPE_D);
364 emit_SEND(bld, g[1], g[2], x);
365 emit_SEND(bld, x, g[3], g[4])->sfid++;
366
367 brw_calculate_cfg(*v);
368 bblock_t *block0 = v->cfg->blocks[0];
369 ASSERT_EQ(0, block0->start_ip);
370 ASSERT_EQ(1, block0->end_ip);
371
372 lower_scoreboard(v);
373 ASSERT_EQ(0, block0->start_ip);
374 ASSERT_EQ(2, block0->end_ip);
375
376 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
377
378 fs_inst *sync = instruction(block0, 1);
379 EXPECT_EQ(sync->opcode, BRW_OPCODE_SYNC);
380 EXPECT_EQ(sync->sched, tgl_swsb_sbid(TGL_SBID_SRC, 0));
381
382 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_sbid(TGL_SBID_SET, 1));
383 }
384
TEST_F(scoreboard_test,WAW_inorder_inorder)385 TEST_F(scoreboard_test, WAW_inorder_inorder)
386 {
387 brw_reg g[16];
388 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
389 g[i] = bld.vgrf(BRW_TYPE_D);
390
391 brw_reg x = bld.vgrf(BRW_TYPE_D);
392 bld.ADD( x, g[1], g[2]);
393 bld.MUL(g[3], g[4], g[5]);
394 bld.AND( x, g[6], g[7]);
395
396 brw_calculate_cfg(*v);
397 bblock_t *block0 = v->cfg->blocks[0];
398 ASSERT_EQ(0, block0->start_ip);
399 ASSERT_EQ(2, block0->end_ip);
400
401 lower_scoreboard(v);
402 ASSERT_EQ(0, block0->start_ip);
403 ASSERT_EQ(2, block0->end_ip);
404
405 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
406 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
407
408 /* NOTE: We only need this RegDist if a long instruction is followed by a
409 * short one. The pass is currently conservative about this and adding the
410 * annotation.
411 */
412 EXPECT_EQ(instruction(block0, 2)->sched, regdist(TGL_PIPE_FLOAT, 2));
413 }
414
TEST_F(scoreboard_test,WAW_inorder_outoforder)415 TEST_F(scoreboard_test, WAW_inorder_outoforder)
416 {
417 brw_reg g[16];
418 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
419 g[i] = bld.vgrf(BRW_TYPE_D);
420
421 brw_reg x = bld.vgrf(BRW_TYPE_D);
422 bld.ADD( x, g[1], g[2]);
423 bld.MUL( g[3], g[4], g[5]);
424 emit_SEND(bld, x, g[6], g[7]);
425
426 brw_calculate_cfg(*v);
427 bblock_t *block0 = v->cfg->blocks[0];
428 ASSERT_EQ(0, block0->start_ip);
429 ASSERT_EQ(2, block0->end_ip);
430
431 lower_scoreboard(v);
432 ASSERT_EQ(0, block0->start_ip);
433 ASSERT_EQ(2, block0->end_ip);
434
435 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
436 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
437
438 tgl_swsb expected = {
439 .regdist = 2,
440 .pipe = TGL_PIPE_FLOAT,
441 .mode = TGL_SBID_SET,
442 };
443
444 EXPECT_EQ(instruction(block0, 2)->sched, expected);
445 }
446
TEST_F(scoreboard_test,WAW_outoforder_inorder)447 TEST_F(scoreboard_test, WAW_outoforder_inorder)
448 {
449 brw_reg g[16];
450 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
451 g[i] = bld.vgrf(BRW_TYPE_D);
452
453 brw_reg x = bld.vgrf(BRW_TYPE_D);
454 emit_SEND(bld, x, g[1], g[2]);
455 bld.MUL( g[3], g[4], g[5]);
456 bld.AND( x, g[6], g[7]);
457
458 brw_calculate_cfg(*v);
459 bblock_t *block0 = v->cfg->blocks[0];
460 ASSERT_EQ(0, block0->start_ip);
461 ASSERT_EQ(2, block0->end_ip);
462
463 lower_scoreboard(v);
464 ASSERT_EQ(0, block0->start_ip);
465 ASSERT_EQ(2, block0->end_ip);
466
467 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
468 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
469 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_sbid(TGL_SBID_DST, 0));
470 }
471
TEST_F(scoreboard_test,WAW_outoforder_outoforder)472 TEST_F(scoreboard_test, WAW_outoforder_outoforder)
473 {
474 brw_reg g[16];
475 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
476 g[i] = bld.vgrf(BRW_TYPE_D);
477
478 brw_reg x = bld.vgrf(BRW_TYPE_D);
479 emit_SEND(bld, x, g[1], g[2]);
480 emit_SEND(bld, x, g[3], g[4])->sfid++;
481
482 brw_calculate_cfg(*v);
483 bblock_t *block0 = v->cfg->blocks[0];
484 ASSERT_EQ(0, block0->start_ip);
485 ASSERT_EQ(1, block0->end_ip);
486
487 lower_scoreboard(v);
488 ASSERT_EQ(0, block0->start_ip);
489 ASSERT_EQ(2, block0->end_ip);
490
491 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
492
493 fs_inst *sync = instruction(block0, 1);
494 EXPECT_EQ(sync->opcode, BRW_OPCODE_SYNC);
495 EXPECT_EQ(sync->sched, tgl_swsb_sbid(TGL_SBID_DST, 0));
496
497 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_sbid(TGL_SBID_SET, 1));
498 }
499
500
TEST_F(scoreboard_test,loop1)501 TEST_F(scoreboard_test, loop1)
502 {
503 brw_reg g[16];
504 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
505 g[i] = bld.vgrf(BRW_TYPE_D);
506
507 brw_reg x = bld.vgrf(BRW_TYPE_D);
508 bld.XOR( x, g[1], g[2]);
509
510 bld.emit(BRW_OPCODE_DO);
511
512 bld.ADD( x, g[1], g[2]);
513 bld.emit(BRW_OPCODE_WHILE)->predicate = BRW_PREDICATE_NORMAL;
514
515 bld.MUL( x, g[1], g[2]);
516
517 brw_calculate_cfg(*v);
518 lower_scoreboard(v);
519
520 bblock_t *body = v->cfg->blocks[2];
521 fs_inst *add = instruction(body, 0);
522 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
523 EXPECT_EQ(add->sched, regdist(TGL_PIPE_FLOAT, 1));
524
525 bblock_t *last_block = v->cfg->blocks[3];
526 fs_inst *mul = instruction(last_block, 0);
527 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
528 EXPECT_EQ(mul->sched, regdist(TGL_PIPE_FLOAT, 1));
529 }
530
TEST_F(scoreboard_test,loop2)531 TEST_F(scoreboard_test, loop2)
532 {
533 brw_reg g[16];
534 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
535 g[i] = bld.vgrf(BRW_TYPE_D);
536
537 brw_reg x = bld.vgrf(BRW_TYPE_D);
538 bld.XOR( x, g[1], g[2]);
539 bld.XOR(g[3], g[1], g[2]);
540 bld.XOR(g[4], g[1], g[2]);
541 bld.XOR(g[5], g[1], g[2]);
542
543 bld.emit(BRW_OPCODE_DO);
544
545 bld.ADD( x, g[1], g[2]);
546 bld.emit(BRW_OPCODE_WHILE)->predicate = BRW_PREDICATE_NORMAL;
547
548 bld.MUL( x, g[1], g[2]);
549
550 brw_calculate_cfg(*v);
551 lower_scoreboard(v);
552
553 /* Now the write in ADD has the tightest RegDist for both ADD and MUL. */
554
555 bblock_t *body = v->cfg->blocks[2];
556 fs_inst *add = instruction(body, 0);
557 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
558 EXPECT_EQ(add->sched, regdist(TGL_PIPE_FLOAT, 2));
559
560 bblock_t *last_block = v->cfg->blocks[3];
561 fs_inst *mul = instruction(last_block, 0);
562 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
563 EXPECT_EQ(mul->sched, regdist(TGL_PIPE_FLOAT, 2));
564 }
565
TEST_F(scoreboard_test,loop3)566 TEST_F(scoreboard_test, loop3)
567 {
568 brw_reg g[16];
569 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
570 g[i] = bld.vgrf(BRW_TYPE_D);
571
572 brw_reg x = bld.vgrf(BRW_TYPE_D);
573 bld.XOR( x, g[1], g[2]);
574
575 bld.emit(BRW_OPCODE_DO);
576
577 /* For the ADD in the loop body this extra distance will always apply. */
578 bld.XOR(g[3], g[1], g[2]);
579 bld.XOR(g[4], g[1], g[2]);
580 bld.XOR(g[5], g[1], g[2]);
581 bld.XOR(g[6], g[1], g[2]);
582
583 bld.ADD( x, g[1], g[2]);
584 bld.emit(BRW_OPCODE_WHILE)->predicate = BRW_PREDICATE_NORMAL;
585
586 bld.MUL( x, g[1], g[2]);
587
588 brw_calculate_cfg(*v);
589 lower_scoreboard(v);
590
591 bblock_t *body = v->cfg->blocks[2];
592 fs_inst *add = instruction(body, 4);
593 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
594 EXPECT_EQ(add->sched, regdist(TGL_PIPE_FLOAT, 5));
595
596 bblock_t *last_block = v->cfg->blocks[3];
597 fs_inst *mul = instruction(last_block, 0);
598 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
599 EXPECT_EQ(mul->sched, regdist(TGL_PIPE_FLOAT, 1));
600 }
601
602
TEST_F(scoreboard_test,conditional1)603 TEST_F(scoreboard_test, conditional1)
604 {
605 brw_reg g[16];
606 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
607 g[i] = bld.vgrf(BRW_TYPE_D);
608
609 brw_reg x = bld.vgrf(BRW_TYPE_D);
610 bld.XOR( x, g[1], g[2]);
611 bld.emit(BRW_OPCODE_IF);
612
613 bld.ADD( x, g[1], g[2]);
614
615 bld.emit(BRW_OPCODE_ENDIF);
616 bld.MUL( x, g[1], g[2]);
617
618 brw_calculate_cfg(*v);
619 lower_scoreboard(v);
620
621 bblock_t *body = v->cfg->blocks[1];
622 fs_inst *add = instruction(body, 0);
623 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
624 EXPECT_EQ(add->sched, regdist(TGL_PIPE_FLOAT, 2));
625
626 bblock_t *last_block = v->cfg->blocks[2];
627 fs_inst *mul = instruction(last_block, 1);
628 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
629 EXPECT_EQ(mul->sched, regdist(TGL_PIPE_FLOAT, 2));
630 }
631
TEST_F(scoreboard_test,conditional2)632 TEST_F(scoreboard_test, conditional2)
633 {
634 brw_reg g[16];
635 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
636 g[i] = bld.vgrf(BRW_TYPE_D);
637
638 brw_reg x = bld.vgrf(BRW_TYPE_D);
639 bld.XOR( x, g[1], g[2]);
640 bld.XOR(g[3], g[1], g[2]);
641 bld.XOR(g[4], g[1], g[2]);
642 bld.XOR(g[5], g[1], g[2]);
643 bld.emit(BRW_OPCODE_IF);
644
645 bld.ADD( x, g[1], g[2]);
646
647 bld.emit(BRW_OPCODE_ENDIF);
648 bld.MUL( x, g[1], g[2]);
649
650 brw_calculate_cfg(*v);
651 lower_scoreboard(v);
652
653 bblock_t *body = v->cfg->blocks[1];
654 fs_inst *add = instruction(body, 0);
655 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
656 EXPECT_EQ(add->sched, regdist(TGL_PIPE_FLOAT, 5));
657
658 bblock_t *last_block = v->cfg->blocks[2];
659 fs_inst *mul = instruction(last_block, 1);
660 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
661 EXPECT_EQ(mul->sched, regdist(TGL_PIPE_FLOAT, 2));
662 }
663
TEST_F(scoreboard_test,conditional3)664 TEST_F(scoreboard_test, conditional3)
665 {
666 brw_reg g[16];
667 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
668 g[i] = bld.vgrf(BRW_TYPE_D);
669
670 brw_reg x = bld.vgrf(BRW_TYPE_D);
671 bld.XOR( x, g[1], g[2]);
672 bld.emit(BRW_OPCODE_IF);
673
674 bld.XOR(g[3], g[1], g[2]);
675 bld.XOR(g[4], g[1], g[2]);
676 bld.XOR(g[5], g[1], g[2]);
677 bld.ADD( x, g[1], g[2]);
678
679 bld.emit(BRW_OPCODE_ENDIF);
680 bld.MUL( x, g[1], g[2]);
681
682 brw_calculate_cfg(*v);
683 lower_scoreboard(v);
684
685 bblock_t *body = v->cfg->blocks[1];
686 fs_inst *add = instruction(body, 3);
687 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
688 EXPECT_EQ(add->sched, regdist(TGL_PIPE_FLOAT, 5));
689
690 bblock_t *last_block = v->cfg->blocks[2];
691 fs_inst *mul = instruction(last_block, 1);
692 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
693 EXPECT_EQ(mul->sched, regdist(TGL_PIPE_FLOAT, 2));
694 }
695
TEST_F(scoreboard_test,conditional4)696 TEST_F(scoreboard_test, conditional4)
697 {
698 brw_reg g[16];
699 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
700 g[i] = bld.vgrf(BRW_TYPE_D);
701
702 brw_reg x = bld.vgrf(BRW_TYPE_D);
703 bld.XOR( x, g[1], g[2]);
704 bld.emit(BRW_OPCODE_IF);
705
706 bld.ADD( x, g[1], g[2]);
707 bld.XOR(g[3], g[1], g[2]);
708 bld.XOR(g[4], g[1], g[2]);
709 bld.XOR(g[5], g[1], g[2]);
710
711 bld.emit(BRW_OPCODE_ENDIF);
712 bld.MUL( x, g[1], g[2]);
713
714 brw_calculate_cfg(*v);
715 lower_scoreboard(v);
716
717 bblock_t *body = v->cfg->blocks[1];
718 fs_inst *add = instruction(body, 0);
719 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
720 EXPECT_EQ(add->sched, regdist(TGL_PIPE_FLOAT, 2));
721
722 bblock_t *last_block = v->cfg->blocks[2];
723 fs_inst *mul = instruction(last_block, 1);
724 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
725 EXPECT_EQ(mul->sched, regdist(TGL_PIPE_FLOAT, 3));
726 }
727
TEST_F(scoreboard_test,conditional5)728 TEST_F(scoreboard_test, conditional5)
729 {
730 brw_reg g[16];
731 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
732 g[i] = bld.vgrf(BRW_TYPE_D);
733
734 brw_reg x = bld.vgrf(BRW_TYPE_D);
735 bld.XOR( x, g[1], g[2]);
736 bld.emit(BRW_OPCODE_IF);
737
738 bld.ADD( x, g[1], g[2]);
739 bld.emit(BRW_OPCODE_ELSE);
740
741 bld.ROL( x, g[1], g[2]);
742
743 bld.emit(BRW_OPCODE_ENDIF);
744 bld.MUL( x, g[1], g[2]);
745
746 brw_calculate_cfg(*v);
747 lower_scoreboard(v);
748
749 bblock_t *then_body = v->cfg->blocks[1];
750 fs_inst *add = instruction(then_body, 0);
751 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
752 EXPECT_EQ(add->sched, regdist(TGL_PIPE_FLOAT, 2));
753
754 bblock_t *else_body = v->cfg->blocks[2];
755 fs_inst *rol = instruction(else_body, 0);
756 EXPECT_EQ(rol->opcode, BRW_OPCODE_ROL);
757 EXPECT_EQ(rol->sched, regdist(TGL_PIPE_FLOAT, 2));
758
759 bblock_t *last_block = v->cfg->blocks[3];
760 fs_inst *mul = instruction(last_block, 1);
761 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
762 EXPECT_EQ(mul->sched, regdist(TGL_PIPE_FLOAT, 2));
763 }
764
TEST_F(scoreboard_test,conditional6)765 TEST_F(scoreboard_test, conditional6)
766 {
767 brw_reg g[16];
768 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
769 g[i] = bld.vgrf(BRW_TYPE_D);
770
771 brw_reg x = bld.vgrf(BRW_TYPE_D);
772 bld.XOR( x, g[1], g[2]);
773 bld.emit(BRW_OPCODE_IF);
774
775 bld.XOR(g[3], g[1], g[2]);
776 bld.XOR(g[4], g[1], g[2]);
777 bld.XOR(g[5], g[1], g[2]);
778 bld.ADD( x, g[1], g[2]);
779 bld.emit(BRW_OPCODE_ELSE);
780
781 bld.XOR(g[6], g[1], g[2]);
782 bld.XOR(g[7], g[1], g[2]);
783 bld.XOR(g[8], g[1], g[2]);
784 bld.XOR(g[9], g[1], g[2]);
785 bld.ROL( x, g[1], g[2]);
786
787 bld.emit(BRW_OPCODE_ENDIF);
788 bld.MUL( x, g[1], g[2]);
789
790 brw_calculate_cfg(*v);
791 lower_scoreboard(v);
792
793 bblock_t *then_body = v->cfg->blocks[1];
794 fs_inst *add = instruction(then_body, 3);
795 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
796 EXPECT_EQ(add->sched, regdist(TGL_PIPE_FLOAT, 5));
797
798 bblock_t *else_body = v->cfg->blocks[2];
799 fs_inst *rol = instruction(else_body, 4);
800 EXPECT_EQ(rol->opcode, BRW_OPCODE_ROL);
801 EXPECT_EQ(rol->sched, regdist(TGL_PIPE_FLOAT, 6));
802
803 bblock_t *last_block = v->cfg->blocks[3];
804 fs_inst *mul = instruction(last_block, 1);
805 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
806 EXPECT_EQ(mul->sched, regdist(TGL_PIPE_FLOAT, 2));
807 }
808
TEST_F(scoreboard_test,conditional7)809 TEST_F(scoreboard_test, conditional7)
810 {
811 brw_reg g[16];
812 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
813 g[i] = bld.vgrf(BRW_TYPE_D);
814
815 brw_reg x = bld.vgrf(BRW_TYPE_D);
816 bld.XOR( x, g[1], g[2]);
817 bld.emit(BRW_OPCODE_IF);
818
819 bld.ADD( x, g[1], g[2]);
820 bld.XOR(g[3], g[1], g[2]);
821 bld.XOR(g[4], g[1], g[2]);
822 bld.XOR(g[5], g[1], g[2]);
823 bld.emit(BRW_OPCODE_ELSE);
824
825 bld.ROL( x, g[1], g[2]);
826 bld.XOR(g[6], g[1], g[2]);
827 bld.XOR(g[7], g[1], g[2]);
828 bld.XOR(g[8], g[1], g[2]);
829 bld.XOR(g[9], g[1], g[2]);
830
831 bld.emit(BRW_OPCODE_ENDIF);
832 bld.MUL( x, g[1], g[2]);
833
834 brw_calculate_cfg(*v);
835 lower_scoreboard(v);
836
837 bblock_t *then_body = v->cfg->blocks[1];
838 fs_inst *add = instruction(then_body, 0);
839 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
840 EXPECT_EQ(add->sched, regdist(TGL_PIPE_FLOAT, 2));
841
842 bblock_t *else_body = v->cfg->blocks[2];
843 fs_inst *rol = instruction(else_body, 0);
844 EXPECT_EQ(rol->opcode, BRW_OPCODE_ROL);
845 EXPECT_EQ(rol->sched, regdist(TGL_PIPE_FLOAT, 2));
846
847 bblock_t *last_block = v->cfg->blocks[3];
848 fs_inst *mul = instruction(last_block, 1);
849 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
850 EXPECT_EQ(mul->sched, regdist(TGL_PIPE_FLOAT, 6));
851 }
852
TEST_F(scoreboard_test,conditional8)853 TEST_F(scoreboard_test, conditional8)
854 {
855 brw_reg g[16];
856 for (unsigned i = 0; i < ARRAY_SIZE(g); i++)
857 g[i] = bld.vgrf(BRW_TYPE_D);
858
859 brw_reg x = bld.vgrf(BRW_TYPE_D);
860 bld.XOR( x, g[1], g[2]);
861 bld.XOR(g[3], g[1], g[2]);
862 bld.XOR(g[4], g[1], g[2]);
863 bld.XOR(g[5], g[1], g[2]);
864 bld.XOR(g[6], g[1], g[2]);
865 bld.XOR(g[7], g[1], g[2]);
866 bld.emit(BRW_OPCODE_IF);
867
868 bld.ADD( x, g[1], g[2]);
869 bld.emit(BRW_OPCODE_ELSE);
870
871 bld.ROL( x, g[1], g[2]);
872
873 bld.emit(BRW_OPCODE_ENDIF);
874 bld.MUL( x, g[1], g[2]);
875
876 brw_calculate_cfg(*v);
877 lower_scoreboard(v);
878
879 bblock_t *then_body = v->cfg->blocks[1];
880 fs_inst *add = instruction(then_body, 0);
881 EXPECT_EQ(add->opcode, BRW_OPCODE_ADD);
882 EXPECT_EQ(add->sched, regdist(TGL_PIPE_FLOAT, 7));
883
884 /* Note that the ROL will have RegDist 2 and not 7, illustrating the
885 * physical CFG edge between the then-block and the else-block.
886 */
887 bblock_t *else_body = v->cfg->blocks[2];
888 fs_inst *rol = instruction(else_body, 0);
889 EXPECT_EQ(rol->opcode, BRW_OPCODE_ROL);
890 EXPECT_EQ(rol->sched, regdist(TGL_PIPE_FLOAT, 2));
891
892 bblock_t *last_block = v->cfg->blocks[3];
893 fs_inst *mul = instruction(last_block, 1);
894 EXPECT_EQ(mul->opcode, BRW_OPCODE_MUL);
895 EXPECT_EQ(mul->sched, regdist(TGL_PIPE_FLOAT, 2));
896 }
897
TEST_F(scoreboard_test,gfx125_RaR_over_different_pipes)898 TEST_F(scoreboard_test, gfx125_RaR_over_different_pipes)
899 {
900 devinfo->verx10 = 125;
901 brw_init_isa_info(&compiler->isa, devinfo);
902
903 brw_reg a = bld.vgrf(BRW_TYPE_D);
904 brw_reg b = bld.vgrf(BRW_TYPE_D);
905 brw_reg f = bld.vgrf(BRW_TYPE_F);
906 brw_reg x = bld.vgrf(BRW_TYPE_D);
907
908 bld.ADD(f, x, x);
909 bld.ADD(a, x, x);
910 bld.ADD(x, b, b);
911
912 brw_calculate_cfg(*v);
913 bblock_t *block0 = v->cfg->blocks[0];
914 ASSERT_EQ(0, block0->start_ip);
915 ASSERT_EQ(2, block0->end_ip);
916
917 lower_scoreboard(v);
918 ASSERT_EQ(0, block0->start_ip);
919 ASSERT_EQ(2, block0->end_ip);
920
921 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
922 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
923 EXPECT_EQ(instruction(block0, 2)->sched, regdist(TGL_PIPE_ALL, 1));
924 }
925
TEST_F(scoreboard_test,gitlab_issue_from_mr_29723)926 TEST_F(scoreboard_test, gitlab_issue_from_mr_29723)
927 {
928 brw_init_isa_info(&compiler->isa, devinfo);
929
930 struct brw_reg a = brw_ud8_grf(29, 0);
931 struct brw_reg b = brw_ud8_grf(2, 0);
932
933 auto bld1 = bld.exec_all().group(1, 0);
934 bld1.ADD( a, stride(b, 0, 1, 0), brw_imm_ud(256));
935 bld1.CMP(brw_null_reg(), stride(a, 2, 1, 2), stride(b, 0, 1, 0), BRW_CONDITIONAL_L);
936
937 brw_calculate_cfg(*v);
938 bblock_t *block0 = v->cfg->blocks[0];
939 ASSERT_EQ(0, block0->start_ip);
940 ASSERT_EQ(1, block0->end_ip);
941
942 lower_scoreboard(v);
943 ASSERT_EQ(0, block0->start_ip);
944 ASSERT_EQ(1, block0->end_ip);
945
946 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
947 EXPECT_EQ(instruction(block0, 1)->sched, regdist(TGL_PIPE_FLOAT, 1));
948 }
949
TEST_F(scoreboard_test,combine_regdist_float_and_int_with_sbid_set)950 TEST_F(scoreboard_test, combine_regdist_float_and_int_with_sbid_set)
951 {
952 devinfo->ver = 20;
953 devinfo->verx10 = 200;
954 brw_init_isa_info(&compiler->isa, devinfo);
955
956 brw_reg a = retype(brw_ud8_grf(1, 0), BRW_TYPE_F);
957 brw_reg b = brw_ud8_grf(2, 0);
958 brw_reg x = brw_ud8_grf(3, 0);
959
960 bld.ADD( a, a, a);
961 bld.ADD( b, b, b);
962 emit_SEND(bld, x, a, b);
963
964 brw_calculate_cfg(*v);
965 bblock_t *block0 = v->cfg->blocks[0];
966 ASSERT_EQ(0, block0->start_ip);
967 ASSERT_EQ(2, block0->end_ip);
968
969 lower_scoreboard(v);
970 ASSERT_EQ(0, block0->start_ip);
971 ASSERT_EQ(2, block0->end_ip);
972
973 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
974 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
975
976 const tgl_swsb expected = {
977 .regdist = 1,
978 .pipe = TGL_PIPE_ALL,
979 .mode = TGL_SBID_SET,
980 };
981
982 EXPECT_EQ(instruction(block0, 2)->sched, expected);
983 }
984
TEST_F(scoreboard_test,combine_regdist_float_with_sbid_set)985 TEST_F(scoreboard_test, combine_regdist_float_with_sbid_set)
986 {
987 devinfo->ver = 20;
988 devinfo->verx10 = 200;
989 brw_init_isa_info(&compiler->isa, devinfo);
990
991 brw_reg a = retype(brw_ud8_grf(1, 0), BRW_TYPE_F);
992 brw_reg b = retype(brw_ud8_grf(2, 0), BRW_TYPE_F);
993 brw_reg x = brw_ud8_grf(3, 0);
994
995 bld.ADD( a, a, a);
996 bld.ADD( b, b, b);
997 emit_SEND(bld, x, a, b);
998
999 brw_calculate_cfg(*v);
1000 bblock_t *block0 = v->cfg->blocks[0];
1001 ASSERT_EQ(0, block0->start_ip);
1002 ASSERT_EQ(2, block0->end_ip);
1003
1004 lower_scoreboard(v);
1005 ASSERT_EQ(0, block0->start_ip);
1006 ASSERT_EQ(2, block0->end_ip);
1007
1008 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
1009 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
1010
1011 const tgl_swsb expected = {
1012 .regdist = 1,
1013 .pipe = TGL_PIPE_FLOAT,
1014 .mode = TGL_SBID_SET,
1015 };
1016
1017 EXPECT_EQ(instruction(block0, 2)->sched, expected);
1018 }
1019
TEST_F(scoreboard_test,combine_regdist_int_with_sbid_set)1020 TEST_F(scoreboard_test, combine_regdist_int_with_sbid_set)
1021 {
1022 devinfo->ver = 20;
1023 devinfo->verx10 = 200;
1024 brw_init_isa_info(&compiler->isa, devinfo);
1025
1026 brw_reg a = brw_ud8_grf(1, 0);
1027 brw_reg b = brw_ud8_grf(2, 0);
1028 brw_reg x = brw_ud8_grf(3, 0);
1029
1030 bld.ADD( a, a, a);
1031 bld.ADD( b, b, b);
1032 emit_SEND(bld, x, a, b);
1033
1034 brw_calculate_cfg(*v);
1035 bblock_t *block0 = v->cfg->blocks[0];
1036 ASSERT_EQ(0, block0->start_ip);
1037 ASSERT_EQ(2, block0->end_ip);
1038
1039 lower_scoreboard(v);
1040 ASSERT_EQ(0, block0->start_ip);
1041 ASSERT_EQ(2, block0->end_ip);
1042
1043 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
1044 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_null());
1045
1046 const tgl_swsb expected = {
1047 .regdist = 1,
1048 .pipe = TGL_PIPE_INT,
1049 .mode = TGL_SBID_SET,
1050 };
1051
1052 EXPECT_EQ(instruction(block0, 2)->sched, expected);
1053 }
1054
TEST_F(scoreboard_test,gitlab_issue_11069)1055 TEST_F(scoreboard_test, gitlab_issue_11069)
1056 {
1057 brw_init_isa_info(&compiler->isa, devinfo);
1058
1059 struct brw_reg a = brw_ud8_grf(76, 0);
1060 struct brw_reg b = brw_ud8_grf(2, 0);
1061
1062 auto bld1 = bld.exec_all().group(1, 0);
1063 bld1.ADD(stride(a, 2, 1, 2), stride(b, 0, 1, 0), brw_imm_ud(0x80));
1064 bld1.CMP( brw_null_reg(), stride(a, 0, 1, 0), stride(b, 0, 1, 0), BRW_CONDITIONAL_L);
1065
1066 brw_calculate_cfg(*v);
1067 bblock_t *block0 = v->cfg->blocks[0];
1068 ASSERT_EQ(0, block0->start_ip);
1069 ASSERT_EQ(1, block0->end_ip);
1070
1071 lower_scoreboard(v);
1072 ASSERT_EQ(0, block0->start_ip);
1073 ASSERT_EQ(1, block0->end_ip);
1074
1075 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
1076 EXPECT_EQ(instruction(block0, 1)->sched, regdist(TGL_PIPE_FLOAT, 1));
1077 }
1078
TEST_F(scoreboard_test,gfx120_can_embed_outoforder_src_dependency_in_send_eot)1079 TEST_F(scoreboard_test, gfx120_can_embed_outoforder_src_dependency_in_send_eot) {
1080 brw_reg a = brw_ud8_grf(1, 0);
1081 brw_reg b = brw_ud8_grf(2, 0);
1082 brw_reg x = brw_ud8_grf(3, 0);
1083 brw_reg desc = brw_ud8_grf(4, 0);
1084
1085 emit_SEND(bld, a, desc, x);
1086 emit_SEND(bld, b, desc, x)->eot = true;
1087
1088 brw_calculate_cfg(*v);
1089 bblock_t *block0 = v->cfg->blocks[0];
1090 ASSERT_EQ(0, block0->start_ip);
1091 ASSERT_EQ(1, block0->end_ip);
1092
1093 lower_scoreboard(v);
1094 ASSERT_EQ(0, block0->start_ip);
1095 ASSERT_EQ(1, block0->end_ip);
1096
1097 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
1098 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_sbid(TGL_SBID_SRC, 0));
1099 }
1100
TEST_F(scoreboard_test,gfx120_can_embed_outoforder_dst_dependency_in_send_eot)1101 TEST_F(scoreboard_test, gfx120_can_embed_outoforder_dst_dependency_in_send_eot) {
1102 brw_reg a = brw_ud8_grf(1, 0);
1103 brw_reg b = brw_ud8_grf(2, 0);
1104 brw_reg x = brw_ud8_grf(3, 0);
1105 brw_reg desc = brw_ud8_grf(4, 0);
1106
1107 emit_SEND(bld, x, desc, a);
1108 emit_SEND(bld, b, desc, x)->eot = true;
1109
1110 brw_calculate_cfg(*v);
1111 bblock_t *block0 = v->cfg->blocks[0];
1112 ASSERT_EQ(0, block0->start_ip);
1113 ASSERT_EQ(1, block0->end_ip);
1114
1115 lower_scoreboard(v);
1116 ASSERT_EQ(0, block0->start_ip);
1117 ASSERT_EQ(1, block0->end_ip);
1118
1119 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
1120 EXPECT_EQ(instruction(block0, 1)->sched, tgl_swsb_sbid(TGL_SBID_DST, 0));
1121 }
1122
TEST_F(scoreboard_test,gfx200_cannot_embed_outoforder_src_dependency_in_send_eot)1123 TEST_F(scoreboard_test, gfx200_cannot_embed_outoforder_src_dependency_in_send_eot) {
1124 devinfo->ver = 20;
1125 devinfo->verx10 = 200;
1126 brw_init_isa_info(&compiler->isa, devinfo);
1127
1128 brw_reg a = brw_ud8_grf(1, 0);
1129 brw_reg b = brw_ud8_grf(2, 0);
1130 brw_reg x = brw_ud8_grf(3, 0);
1131 brw_reg desc = brw_ud8_grf(4, 0);
1132
1133 emit_SEND(bld, a, desc, x);
1134 emit_SEND(bld, b, desc, x)->eot = true;
1135
1136 brw_calculate_cfg(*v);
1137 bblock_t *block0 = v->cfg->blocks[0];
1138 ASSERT_EQ(0, block0->start_ip);
1139 ASSERT_EQ(1, block0->end_ip);
1140
1141 lower_scoreboard(v);
1142 ASSERT_EQ(0, block0->start_ip);
1143 ASSERT_EQ(2, block0->end_ip);
1144
1145 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
1146
1147 fs_inst *sync = instruction(block0, 1);
1148 EXPECT_EQ(sync->opcode, BRW_OPCODE_SYNC);
1149 EXPECT_EQ(sync->sched, tgl_swsb_sbid(TGL_SBID_SRC, 0));
1150
1151 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_null());
1152 }
1153
TEST_F(scoreboard_test,gfx200_cannot_embed_outoforder_dst_dependency_in_send_eot)1154 TEST_F(scoreboard_test, gfx200_cannot_embed_outoforder_dst_dependency_in_send_eot) {
1155 devinfo->ver = 20;
1156 devinfo->verx10 = 200;
1157 brw_init_isa_info(&compiler->isa, devinfo);
1158
1159 brw_reg a = brw_ud8_grf(1, 0);
1160 brw_reg b = brw_ud8_grf(2, 0);
1161 brw_reg x = brw_ud8_grf(3, 0);
1162 brw_reg desc = brw_ud8_grf(4, 0);
1163
1164 emit_SEND(bld, x, desc, a);
1165 emit_SEND(bld, b, desc, x)->eot = true;
1166
1167 brw_calculate_cfg(*v);
1168 bblock_t *block0 = v->cfg->blocks[0];
1169 ASSERT_EQ(0, block0->start_ip);
1170 ASSERT_EQ(1, block0->end_ip);
1171
1172 lower_scoreboard(v);
1173 ASSERT_EQ(0, block0->start_ip);
1174 ASSERT_EQ(2, block0->end_ip);
1175
1176 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_sbid(TGL_SBID_SET, 0));
1177
1178 fs_inst *sync = instruction(block0, 1);
1179 EXPECT_EQ(sync->opcode, BRW_OPCODE_SYNC);
1180 EXPECT_EQ(sync->sched, tgl_swsb_sbid(TGL_SBID_DST, 0));
1181
1182 EXPECT_EQ(instruction(block0, 2)->sched, tgl_swsb_null());
1183 }
1184
1185 static brw_reg
brw_s0_with_region(enum brw_reg_type type,unsigned subnr,unsigned v,unsigned w,unsigned h)1186 brw_s0_with_region(enum brw_reg_type type, unsigned subnr, unsigned v, unsigned w, unsigned h)
1187 {
1188 return brw_make_reg(ARF,
1189 BRW_ARF_SCALAR,
1190 subnr,
1191 0,
1192 0,
1193 type,
1194 cvt(v),
1195 cvt(w)-1,
1196 cvt(h),
1197 BRW_SWIZZLE_XYZW,
1198 WRITEMASK_XYZW);
1199 }
1200
TEST_F(scoreboard_test,scalar_register_mov_immediate_is_in_scalar_pipe)1201 TEST_F(scoreboard_test, scalar_register_mov_immediate_is_in_scalar_pipe)
1202 {
1203 devinfo->ver = 30;
1204 devinfo->verx10 = 300;
1205 brw_init_isa_info(&compiler->isa, devinfo);
1206
1207 brw_reg scalar = brw_s0_with_region(BRW_TYPE_UW, 0, 0, 1, 0);
1208
1209 bld.group(1, 0).exec_all().MOV(scalar, brw_imm_uw(0x1415));
1210 bld .MOV(brw_uw8_grf(20, 0), scalar);
1211
1212 brw_calculate_cfg(*v);
1213 lower_scoreboard(v);
1214
1215 bblock_t *block0 = v->cfg->blocks[0];
1216
1217 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
1218 EXPECT_EQ(instruction(block0, 1)->sched, regdist(TGL_PIPE_SCALAR, 1));
1219 }
1220
TEST_F(scoreboard_test,scalar_register_mov_grf_is_not_in_scalar_pipe)1221 TEST_F(scoreboard_test, scalar_register_mov_grf_is_not_in_scalar_pipe)
1222 {
1223 devinfo->ver = 30;
1224 devinfo->verx10 = 300;
1225 brw_init_isa_info(&compiler->isa, devinfo);
1226
1227 brw_reg scalar = brw_s0_with_region(BRW_TYPE_UW, 0, 0, 1, 0);
1228
1229 bld.group(1, 0).exec_all().MOV(scalar, brw_uw8_grf(0, 0));
1230 bld .MOV(brw_uw8_grf(20, 0), scalar);
1231
1232 brw_calculate_cfg(*v);
1233 lower_scoreboard(v);
1234
1235 bblock_t *block0 = v->cfg->blocks[0];
1236
1237 EXPECT_EQ(instruction(block0, 0)->sched, tgl_swsb_null());
1238 EXPECT_EQ(instruction(block0, 1)->sched, regdist(TGL_PIPE_INT, 1));
1239 }
1240