• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &params, 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