source: CLRX/CLRadeonExtender/trunk/tests/amdasm/AsmRegAlloc3.cpp @ 4058

Last change on this file since 4058 was 4058, checked in by matszpk, 14 months ago

CLRadeonExtender: AsmRegAlloc?: Add next testcase (createLivenesses).

File size: 33.3 KB
Line 
1/*
2 *  CLRadeonExtender - Unofficial OpenCL Radeon Extensions Library
3 *  Copyright (C) 2014-2018 Mateusz Szpakowski
4 *
5 *  This library is free software; you can redistribute it and/or
6 *  modify it under the terms of the GNU Lesser General Public
7 *  License as published by the Free Software Foundation; either
8 *  version 2.1 of the License, or (at your option) any later version.
9 *
10 *  This library is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 *  Lesser General Public License for more details.
14 *
15 *  You should have received a copy of the GNU Lesser General Public
16 *  License along with this library; if not, write to the Free Software
17 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19
20#include <CLRX/Config.h>
21#include <algorithm>
22#include <iostream>
23#include <sstream>
24#include <string>
25#include <vector>
26#include <cstring>
27#include <CLRX/utils/Utilities.h>
28#include <CLRX/amdasm/Assembler.h>
29#include <CLRX/utils/Containers.h>
30#include "../TestUtils.h"
31#include "AsmRegAlloc.h"
32
33using namespace CLRX;
34
35typedef AsmRegAllocator::OutLiveness OutLiveness;
36typedef AsmRegAllocator::LinearDep LinearDep;
37typedef AsmRegAllocator::VarIndexMap VarIndexMap;
38
39struct LinearDep2
40{
41    cxbyte align;
42    Array<size_t> prevVidxes;
43    Array<size_t> nextVidxes;
44};
45
46struct AsmLivenessesCase
47{
48    const char* input;
49    Array<OutLiveness> livenesses[MAX_REGTYPES_NUM];
50    Array<std::pair<size_t, LinearDep2> > linearDepMaps[MAX_REGTYPES_NUM];
51    bool good;
52    const char* errorMessages;
53};
54
55static const AsmLivenessesCase createLivenessesCasesTbl[] =
56{
57#if 0
58    {   // 0 - simple case
59        R"ffDXD(.regvar sa:s:8, va:v:10
60        s_mov_b32 sa[4], sa[2]  # 0
61        s_add_u32 sa[4], sa[4], s3
62        v_xor_b32 va[4], va[2], v3
63)ffDXD",
64        {   // livenesses
65            {   // for SGPRs
66                { { 0, 5 } }, // S3
67                { { 0, 1 } }, // sa[2]'0
68                { { 1, 5 } }, // sa[4]'0
69                { { 5, 6 } }  // sa[4]'1
70            },
71            {   // for VGPRs
72                { { 0, 9 } }, // V3
73                { { 0, 9 } }, // va[2]'0
74                { { 9, 10 } } // va[4]'0 : out of range code block
75            },
76            { },
77            { }
78        },
79        { },  // linearDepMaps
80        true, ""
81    },
82    {   // 1 - simple case 2
83        R"ffDXD(.regvar sa:s:8, va:v:10
84        s_mov_b32 sa[4], sa[2]  # 0
85        s_add_u32 sa[4], sa[4], s3
86        v_xor_b32 va[4], va[2], v3
87        s_endpgm
88)ffDXD",
89        {   // livenesses
90            {   // for SGPRs
91                { { 0, 5 } }, // S3
92                { { 0, 1 } }, // sa[2]'0
93                { { 1, 5 } }, // sa[4]'0
94                { { 5, 6 } }  // sa[4]'1
95            },
96            {   // for VGPRs
97                { { 0, 9 } }, // V3
98                { { 0, 9 } }, // va[2]'0
99                { { 9, 10 } } // va[4]'0 : out of range code block
100            },
101            { },
102            { }
103        },
104        { },  // linearDepMaps
105        true, ""
106    },
107    {   // 2 - simple case (linear dep)
108        R"ffDXD(.regvar sa:s:8, va:v:10
109        .regvar sbuf:s:4, rbx4:v:6
110        s_mov_b64 sa[4:5], sa[2:3]  # 0
111        s_and_b64 sa[4:5], sa[4:5], s[4:5]
112        v_add_f64 va[4:5], va[2:3], v[3:4]
113        buffer_load_dwordx4 rbx4[1:5], va[6], sbuf[0:3], sa[7] idxen offset:603 tfe
114)ffDXD",
115        {   // livenesses
116            {   // for SGPRs
117                { { 0, 5 } }, // S4
118                { { 0, 5 } }, // S5
119                { { 0, 1 } }, // sa[2]'0
120                { { 0, 1 } }, // sa[3]'0
121                { { 1, 5 } }, // sa[4]'0
122                { { 5, 6 } }, // sa[4]'1
123                { { 1, 5 } }, // sa[5]'0
124                { { 5, 6 } }, // sa[5]'1
125                { { 0, 17 } }, // sa[7]'0
126                { { 0, 17 } }, // sbuf[0]'0
127                { { 0, 17 } }, // sbuf[1]'0
128                { { 0, 17 } }, // sbuf[2]'0
129                { { 0, 17 } }, // sbuf[3]'0
130            },
131            {   // for VGPRs
132                { { 0, 9 } }, // V3
133                { { 0, 9 } }, // V4
134                { { 17, 18 } }, // rbx4[1]'0
135                { { 17, 18 } }, // rbx4[2]'0
136                { { 17, 18 } }, // rbx4[3]'0
137                { { 17, 18 } }, // rbx4[4]'0
138                { { 0, 17 } }, // rbx4[5]'0: tfe - read before write
139                { { 0, 9 } }, // va[2]'0
140                { { 0, 9 } }, // va[3]'0
141                { { 9, 10 } }, // va[4]'0 : out of range code block
142                { { 9, 10 } }, // va[5]'0 : out of range code block
143                { { 0, 17 } } // va[6]'0
144            },
145            { },
146            { }
147        },
148        {   // linearDepMaps
149            {   // for SGPRs
150                { 0, { 0, { }, { 1 } } },  // S4
151                { 1, { 0, { 0 }, { } } },  // S5
152                { 2, { 2, { }, { 3 } } },  // sa[2]'0
153                { 3, { 0, { 2 }, { } } },  // sa[3]'0
154                { 4, { 2, { }, { 6 } } },  // sa[4]'0
155                { 5, { 2, { }, { 7, 7 } } },  // sa[4]'1
156                { 6, { 0, { 4 }, { } } },  // sa[5]'0
157                { 7, { 0, { 5, 5 }, { } } },   // sa[5]'1
158                { 9, { 4, { }, { 10 } } }, // sbuf[0]'0
159                { 10, { 0, { 9 }, { 11 } } }, // sbuf[1]'0
160                { 11, { 0, { 10 }, { 12 } } }, // sbuf[2]'0
161                { 12, { 0, { 11 }, { } } }  // sbuf[3]'0
162            },
163            {   // for VGPRs
164                { 0, { 0, { }, { 1 } } },  // V3
165                { 1, { 0, { 0 }, { } } },  // V4
166                { 2, { 1, { }, { 3 } } }, // rbx4[1]'0
167                { 3, { 0, { 2 }, { 4 } } }, // rbx4[2]'0
168                { 4, { 0, { 3 }, { 5 } } }, // rbx4[3]'0
169                { 5, { 0, { 4 }, { 6 } } }, // rbx4[4]'0
170                { 6, { 0, { 5 }, { } } }, // rbx4[5]'0
171                { 7, { 1, { }, { 8 } } },  // va[2]'0
172                { 8, { 0, { 7 }, { } } },  // va[3]'0
173                { 9, { 1, { }, { 10 } } },  // va[4]'0
174                { 10, { 0, { 9 }, { } } }  // va[5]'0
175            },
176            { },
177            { }
178        },
179        true, ""
180    },
181    {   // 3 - next simple case
182        R"ffDXD(.regvar sa:s:8, va:v:10
183        s_mov_b32 sa[4], sa[2]  # 0
184        s_add_u32 sa[4], sa[4], s3
185        v_xor_b32 va[4], va[2], v3
186        v_mov_b32 va[3], 1.45s
187        v_mov_b32 va[6], -7.45s
188        v_lshlrev_b32 va[5], sa[4], va[4]
189        v_mac_f32 va[3], va[6], v0
190        s_mul_i32 sa[7], sa[2], sa[3]
191        v_mac_f32 va[3], va[7], v0
192        s_endpgm
193)ffDXD",
194        {   // livenesses
195            {   // for SGPRs
196                { { 0, 5 } }, // 0: S3
197                { { 0, 37 } }, // 1: sa[2]'0
198                { { 0, 37 } }, // 2: sa[3]'0
199                { { 1, 5 } }, // 3: sa[4]'0
200                { { 5, 29 } }, // 4: sa[4]'1
201                { { 37, 38 } }  // 5: sa[7]'0
202            },
203            {   // for VGPRs
204                { { 0, 41 } }, // 0: v0
205                { { 0, 9 } }, // 1: v3
206                { { 0, 9 } }, // 2: va[2]'0
207                { { 13, 41 } }, // 3: va[3]'0
208                { { 9, 29 } }, // 4: va[4]'0
209                { { 29, 30 } }, // 5: va[5]'0
210                { { 21, 33 } }, // 6: va[6]'0
211                { { 0, 41 } }  // 7: va[7]'0
212            },
213            { },
214            { }
215        },
216        { }, // linearDepMaps
217        true, ""
218    },
219    {   // 4 - next test case
220        R"ffDXD(.regvar sa:s:8, va:v:10
221        s_mov_b32 sa[4], sa[2]  # 0
222        s_add_u32 sa[4], sa[4], s3  # 4
223       
224        v_xor_b32 v4, va[2], v3         # 8
225        v_xor_b32 va[5], v4, va[5]      # 12
226       
227        s_sub_u32 sa[4], sa[4], sa[3]   # 16
228       
229        v_xor_b32 v4, va[5], v3         # 20
230        v_xor_b32 va[6], v4, va[6]      # 24
231       
232        s_mul_i32 sa[4], sa[4], sa[1]   # 28
233        s_mul_i32 sa[4], sa[4], sa[0]   # 32
234       
235        v_xor_b32 v4, va[6], v3         # 36
236        v_xor_b32 va[7], v4, va[7]      # 40
237)ffDXD",
238        {   // livenesses
239            {   // for SGPRs
240                { { 0, 5 } },   // 0: S3
241                { { 0, 33 } },  // 1: sa[0]'0
242                { { 0, 29 } },  // 2: sa[1]'0
243                { { 0, 1 } },   // 3: sa[2]'0
244                { { 0, 17 } },  // 4: sa[3]'0
245                { { 1, 5 } },   // 5: sa[4]'0
246                { { 5, 17 } },  // 6: sa[4]'1
247                { { 17, 29 } }, // 7: sa[4]'2
248                { { 29, 33 } }, // 8: sa[4]'3
249                { { 33, 34 } }  // 9: sa[4]'4
250            },
251            {   // for VGPRs
252                { { 0, 37 } },   // 0: v3
253                { { 9, 13 }, { 21, 25 }, { 37, 41 } }, // 1: v4
254                { { 0, 9 } },    // 2: va[2]'0
255                { { 0, 13 } },   // 3: va[5]'0
256                { { 13, 21 } },  // 4: va[5]'1
257                { { 0, 25 } },   // 5: va[6]'0
258                { { 25, 37 } },  // 6: va[6]'1
259                { { 0, 41 } },   // 7: va[7]'0
260                { { 41, 42 } }   // 8: va[7]'1
261            },
262            { },
263            { }
264        },
265        { }, // linearDepMaps
266        true, ""
267    },
268    {   // 5 - blocks
269        R"ffDXD(.regvar sa:s:8, va:v:10
270        s_mov_b32 sa[4], sa[2]          # 0
271        s_add_u32 sa[4], sa[4], s3      # 4
272        v_mad_f32 va[0], va[1], va[2], v0  # 8
273        .cf_jump a0,a1,a2
274        s_setpc_b64 s[0:1]              # 16
275       
276a0:     s_mul_i32 sa[3], sa[4], s3      # 20
277        s_xor_b32 s4, sa[2], s4         # 24
278        s_endpgm                        # 28
279       
280a1:     v_add_f32 va[2], sa[5], va[0]   # 32
281        v_mul_f32 va[3], va[2], v0      # 36
282        s_endpgm                        # 40
283       
284a2:     s_cselect_b32 sa[2], sa[4], sa[3]   # 44
285        v_cndmask_b32 va[3], va[0], va[1], vcc     # 48
286        s_endpgm                        # 52
287)ffDXD",
288        {   // livenesses
289            {   // for SGPRs
290                { { 0, 17 } }, // 0: S0
291                { { 0, 17 } }, // 1: S1
292                { { 0, 21 } }, // 2: S3
293                { { 0, 26 } }, // 3: S4
294                { { 0, 25 } }, // 4: sa[2]'0
295                { { 45, 46 } }, // 5: sa[2]'1
296                { { 0, 20 }, { 44, 45 } }, // 6: sa[3]'0
297                { { 21, 22 } }, // 7: sa[3]'1
298                { { 1, 5 } }, // 8: sa[4]'0
299                { { 5, 21 }, { 44, 45 } }, // 9: sa[4]'1
300                { { 0, 20 }, { 32, 33 } }  // 10: sa[5]
301            },
302            {   // for VGPRs
303                { { 0, 20 }, { 32, 37 } }, // 0: V0
304                { { 9, 20 }, { 32, 33 }, { 44, 49 } }, // 1: va[0]'0
305                { { 0, 20 }, { 44, 49 } }, // 2: va[1]'0
306                { { 0, 9 } }, // 3: va[2]'0
307                { { 33, 37 } }, // 4: va[2]'1
308                { { 37, 38 } }, // 5: va[3]'0
309                { { 49, 50 } }  // 6: va[3]'1
310            },
311            { },
312            { }
313        },
314        {   // linearDepMaps
315            {   // for SGPRs
316                { 0, { 0, { }, { 1 } } },
317                { 1, { 0, { 0 }, { } } }
318            },
319            { },
320            { },
321            { }
322        },
323        true, ""
324    },
325    {   // 6 - blocks
326        R"ffDXD(.regvar sa:s:8, va:v:10
327        s_mov_b32 sa[4], sa[2]              # 0
328        s_add_u32 sa[4], sa[4], s3          # 4
329        v_mad_f32 va[0], va[1], va[2], v0   # 8
330        s_xor_b32 sa[6], sa[2], sa[4]       # 16
331        .cf_jump a0,a1,a2
332        s_setpc_b64 s[0:1]                  # 20
333       
334a0:     s_mul_i32 sa[3], sa[4], s3          # 24
335        s_xor_b32 s4, sa[2], s4             # 28
336        s_cbranch_scc1 a01                  # 32
337a00:    s_add_u32 sa[4], sa[4], s4          # 36
338        s_endpgm                            # 40
339a01:    s_add_u32 sa[6], sa[6], s4          # 44
340        s_endpgm                            # 48
341       
342a1:     v_add_f32 va[2], sa[5], va[0]       # 52
343        v_mul_f32 va[3], va[2], v0          # 56
344        s_cbranch_scc1 a11                  # 60
345a10:    s_add_u32 sa[5], sa[7], s7          # 64
346        s_endpgm                            # 68
347a11:    v_add_f32 va[5], va[3], va[1]       # 72
348        s_endpgm                            # 76
349       
350a2:     s_cselect_b32 sa[2], sa[4], sa[3]   # 80
351        v_cndmask_b32 va[3], va[0], va[1], vcc  # 84
352        s_cbranch_scc1 a21                  # 88
353a20:    v_add_f32 va[1], va[3], va[4]       # 92
354        s_endpgm                            # 96
355a21:    v_add_f32 va[2], va[1], va[0]       # 100
356        s_endpgm                            # 104
357)ffDXD",
358        {   // livenesses
359            {   // for SGPRs
360                { { 0, 21 } }, // 0: S0
361                { { 0, 21 } }, // 1: S1
362                { { 0, 25 } }, // 2: S3
363                { { 0, 37 }, { 44, 45 } }, // 3: S4
364                { { 0, 24 }, { 52, 65 } }, // 4: S7
365                { { 0, 29 } }, // 5: sa[2]'0
366                { { 81, 82 } }, // 6: sa[2]'1
367                { { 0, 24 }, { 80, 81 } }, // 7: sa[3]'0
368                { { 25, 26 } }, // 8: sa[3]'1
369                { { 1, 5 } }, // 9: sa[4]'0
370                { { 5, 37, }, { 80, 81 } }, // 10 sa[4]'1
371                { { 37, 38 } }, // 11: sa[4]'2
372                { { 0, 24 }, { 52, 53 } }, // 12: sa[5]'0
373                { { 65, 66 } }, // 13: sa[5]'1
374                { { 17, 36 }, { 44, 45 } }, // 14: sa[6]'0
375                { { 45, 46 } }, // 15: sa[6]'1
376                { { 0, 24 }, { 52, 65 }  }  // 16: sa[7]'0
377            },
378            {   // for VGPRs
379                { { 0, 24 }, { 52, 57 } }, // 1: V0
380                { { 9, 24 }, { 52, 53 }, { 80, 92 }, { 100, 101 } }, // 1: va[0]'0
381                { { 0, 24 }, { 52, 64 }, { 72, 73 },
382                            { 80, 92 }, { 100, 101 } }, // 2: va[1]'0
383                { { 93, 94 } }, // 3: va[1]'1
384                { { 0, 9 } }, // 4: va[2]'0
385                { { 53, 57 } }, // 5: va[2]'1
386                { { 101, 102 } }, // 6: va[2]'2
387                { { 57, 64 }, { 72, 73 } }, // 7: va[3]'0
388                { { 85, 93 } }, // 8: va[3]'1
389                { { 0, 24 }, { 80, 93 } }, // 8: va[4]'0
390                { { 73, 74 } }  // 10: va[5]'0
391            },
392            { },
393            { }
394        },
395        {   // linearDepMaps
396            {   // for SGPRs
397                { 0, { 0, { }, { 1 } } },
398                { 1, { 0, { 0 }, { } } }
399            },
400            { },
401            { },
402            { }
403        },
404        true, ""
405    },
406    {   // 7 - empty blocks
407        R"ffDXD(.regvar sa:s:8, va:v:10
408        s_mov_b32 sa[0], sa[2]              # 0
409        s_add_u32 sa[1], sa[3], s3          # 4
410        v_mad_f32 va[0], va[1], va[2], v0   # 8
411        s_xor_b32 sa[2], sa[4], sa[3]       # 16
412        .cf_jump a0,a1
413        s_setpc_b64 s[0:1]                  # 20
414       
415a0:     s_mul_i32 sa[1], sa[2], s3          # 24
416        s_nop 7                             # 28
417        s_cbranch_scc1 a01                  # 32
418        s_nop 7                             # 36
419        s_cbranch_execz a02                 # 40
420        s_nop 7                             # 44
421        s_cbranch_vccz a03                  # 48
422        s_nop 7                             # 52
423        s_cbranch_vccnz a04                 # 56
424        s_nop 7                             # 60
425        s_mul_i32 s2, sa[4], sa[2]          # 64
426        s_cbranch_scc0 a05                  # 68
427        s_endpgm                            # 72
428       
429a01:    s_mul_i32 sa[0], s2, s3             # 76
430        s_endpgm                            # 80
431       
432a02:    s_mul_i32 sa[1], s2, sa[4]          # 84
433        s_endpgm                            # 88
434       
435a03:    v_add_f32 va[3], va[1], va[0]       # 92
436        s_endpgm                            # 96
437       
438a04:    v_add_f32 va[3], va[3], va[4]       # 100
439        s_endpgm                            # 104
440       
441a05:    s_mul_i32 sa[5], s4, sa[6]          # 108
442        s_endpgm                            # 112
443
444a1:     v_mul_f32 va[1], sa[1], va[1]       # 116
445        v_nop                               # 120
446        s_cbranch_scc1 a11                  # 124
447        v_nop                               # 128
448        s_cbranch_execz a12                 # 132
449        v_nop                               # 136
450        s_cbranch_vccz a13                  # 140
451        v_nop                               # 144
452        s_cbranch_vccnz a14                 # 148
453        v_nop                               # 152
454        s_mul_i32 s2, sa[4], sa[2]          # 156
455        s_cbranch_scc0 a15                  # 160
456        s_endpgm                            # 164
457
458a11:    v_add_f32 v2, va[2], va[3]          # 168
459        s_endpgm                            # 172
460       
461a12:    v_add_f32 v2, va[0], va[3]          # 176
462        s_endpgm                            # 180
463       
464a13:    v_nop                               # 184
465        s_endpgm                            # 188
466       
467a14:    v_nop                               # 192
468        s_endpgm                            # 196
469       
470a15:    s_mul_i32 sa[5], s4, sa[1]          # 200
471        s_endpgm                            # 204
472)ffDXD",
473        {   // livenesses
474            {   // for SGPRs
475                { { 0, 21 } }, // 0: S0
476                { { 0, 21 } }, // 1: S1
477                { { 0, 44 }, { 65, 66 }, { 76, 77 },
478                        { 84, 85 }, { 157, 158 } }, // 2: S2
479                { { 0, 36 }, { 76, 77 } }, // 3: S3
480                { { 0, 72 }, { 108, 109 }, { 116, 164 }, { 200, 201 } }, // 4: S4
481                { { 1, 2 } }, // 5: sa[0]'0
482                { { 77, 78 } }, // 6: sa[0]'1
483                { { 5, 24 }, { 116, 164 }, { 200, 201 } }, // 7: sa[1]'0
484                { { 25, 26 } }, // 8: sa[1]'1
485                { { 85, 86 } }, // 9: sa[1]'2
486                { { 0, 1 } }, // 10: sa[2]'0
487                { { 17, 65 }, { 116, 157 } }, // 11: sa[2]'1
488                { { 0, 17 } }, // 12: sa[3]'0
489                { { 0, 65 }, { 84, 85 }, { 116, 157 } }, // 13: sa[4]'0
490                { { 109, 110 } }, // 14: sa[5]'0
491                { { 201, 202 } }, // 15: sa[5]'1
492                { { 0, 72 }, { 108, 109 } }  // 16: sa[6]'0
493            },
494            {   // for VGPRs
495                { { 0, 9 } }, // 0: V0
496                { { 169, 170 }, { 177, 178 } }, // 1: V2
497                { { 9, 52 }, { 92, 93 }, { 116, 136 }, { 176, 177 } }, // 2: va[0]'0
498                { { 0, 52 }, { 92, 93 }, { 116, 117 } }, // 3: va[1]'0
499                { { 117, 118 } }, // 4: va[1]'1
500                { { 0, 24 }, { 116, 128 }, { 168, 169 } }, // 5: va[2]'0
501                { { 0, 60 }, { 100, 101 }, { 116, 136 },
502                        { 168, 169 }, { 176, 177 } }, // 6: va[3]'0
503                { { 101, 102 } }, // 7: va[3]'1
504                { { 93, 94 } }, // 8: va[3]'2
505                { { 0, 60 }, { 100, 101 } }  // 9: va[4]'0
506            },
507            { },
508            { }
509        },
510        {   // linearDepMaps
511            {   // for SGPRs
512                { 0, { 0, { }, { 1 } } },
513                { 1, { 0, { 0 }, { } } }
514            },
515            { },
516            { },
517            { }
518        },
519        true, ""
520    },
521    {   // 8 - empty blocks
522        R"ffDXD(.regvar sa:s:8, va:v:10
523        s_mov_b32 sa[0], sa[2]              # 0
524        s_add_u32 sa[1], sa[3], s3          # 4
525        v_mad_f32 va[0], va[1], va[2], v0   # 8
526        s_xor_b32 sa[2], sa[4], sa[3]       # 16
527        .cf_jump a0
528        s_setpc_b64 s[0:1]                  # 20
529       
530a0:     s_mul_i32 sa[1], sa[2], s3          # 24
531        s_nop 7                             # 28
532        s_cbranch_scc1 a01                  # 32
533        s_nop 7                             # 36
534        s_cbranch_execz a02                 # 40
535        s_nop 7                             # 44
536        s_cbranch_vccz a03                  # 48
537        s_nop 7                             # 52
538        s_cbranch_vccnz a04                 # 56
539        s_nop 7                             # 60
540        s_nop 1                             # 64
541        s_cbranch_scc0 a05                  # 68
542        s_endpgm                            # 72
543       
544a01:    s_mul_i32 sa[0], s2, s3             # 76
545        s_endpgm                            # 80
546       
547a02:    s_mul_i32 sa[1], s2, sa[4]          # 84
548        s_endpgm                            # 88
549       
550a03:    v_add_f32 va[3], va[1], va[0]       # 92
551        s_endpgm                            # 96
552       
553a04:    v_add_f32 va[3], va[3], va[4]       # 100
554        s_endpgm                            # 104
555       
556a05:    s_mul_i32 sa[5], s4, sa[6]          # 108
557        s_endpgm                            # 112
558)ffDXD",
559        {   // livenesses
560            {   // for SGPRs
561                { { 0, 21 } }, // 0: S0
562                { { 0, 21 } }, // 1: S1
563                { { 0, 44 }, { 76, 77 }, { 84, 85 } }, // 2: S2
564                { { 0, 36 }, { 76, 77 } }, // 3: S3
565                { { 0, 72 }, { 108, 109 } }, // 4: S4
566                { { 1, 2 } }, // 5: sa[0]'0
567                { { 77, 78 } }, // 6: sa[0]'1
568                { { 5, 6 } }, // 7: sa[1]'0
569                { { 25, 26 } }, // 8: sa[1]'1
570                { { 85, 86 } }, // 9: sa[1]'2
571                { { 0, 1 } }, // 10: sa[2]'0
572                { { 17, 25 } }, // 11: sa[2]'1
573                { { 0, 17 } }, // 12: sa[3]'0
574                { { 0, 44 }, { 84, 85 } }, // 13: sa[4]'0
575                { { 109, 110 } }, // 14: sa[5]'0
576                { { 0, 72 }, { 108, 109 } }  // 16: sa[6]'0
577            },
578            {   // for VGPRs
579                { { 0, 9 } }, // 0: V0
580                { { 9, 52 }, { 92, 93 } }, // 2: va[0]'0
581                { { 0, 52 }, { 92, 93 } }, // 4: va[1]'1
582                { { 0, 9 } }, // 5: va[2]'0
583                { { 0, 60 }, { 100, 101 } }, // 6: va[3]'0
584                { { 101, 102 } }, // 7: va[3]'1
585                { { 93, 94 } }, // 8: va[3]'2
586                { { 0, 60 }, { 100, 101 } }  // 9: va[4]'0
587            },
588            { },
589            { }
590        },
591        {   // linearDepMaps
592            {   // for SGPRs
593                { 0, { 0, { }, { 1 } } },
594                { 1, { 0, { 0 }, { } } }
595            },
596            { },
597            { },
598            { }
599        },
600        true, ""
601    },
602    {   // 9 - simple joins
603        R"ffDXD(.regvar sa:s:12, va:v:8
604        s_mov_b32 sa[2], s2     # 0
605        .cf_jump a1,a2,a3
606        s_setpc_b64 s[0:1]      # 4
607       
608a1:     s_add_u32 sa[2], sa[2], sa[3]   # 8
609        s_add_u32 sa[2], sa[2], sa[3]   # 12
610        s_branch end                    # 16
611a2:     s_add_u32 sa[2], sa[2], sa[4]   # 20
612        s_add_u32 sa[2], sa[2], sa[4]   # 24
613        s_branch end                    # 28
614a3:     s_add_u32 sa[2], sa[2], sa[5]   # 32
615        s_add_u32 sa[2], sa[2], sa[5]   # 36
616        s_branch end                    # 40
617
618end:    s_xor_b32 sa[2], sa[2], s3      # 44
619        s_endpgm                        # 48
620)ffDXD",
621        {   // livenesses
622            {   // for SGPRs
623                { { 0, 5 } }, // 0: S0
624                { { 0, 5 } }, // 1: S1
625                { { 0, 1 } }, // 2: S2
626                { { 0, 45 } }, // 3: S3
627                { { 1, 9 }, { 20, 21 }, { 32, 33 } }, // 4: sa[2]'0
628                { { 9, 13 } }, // 5: sa[2]'1
629                { { 13, 20 }, { 25, 32 }, { 37, 45 } }, // 6: sa[2]'2
630                { { 45, 46 } }, // 7: sa[2]'3
631                { { 21, 25 } }, // 8: sa[2]'4
632                { { 33, 37 } }, // 9: sa[2]'5
633                { { 0, 13 } }, // 10: sa[3]'0
634                { { 0, 8 }, { 20, 25 } }, // 11: sa[4]'0
635                { { 0, 8 }, { 32, 37 } }  // 12: sa[5]'0
636            },
637            { },
638            { },
639            { }
640        },
641        {   // linearDepMaps
642            { // for SGPRs
643                { 0, { 0, { }, { 1 } } },
644                { 1, { 0, { 0 }, { } } }
645            },
646            { },
647            { },
648            { }
649        },
650        true, ""
651    },
652#endif
653    {   // 10 - more complex join
654        R"ffDXD(.regvar sa:s:12, va:v:8
655        s_mov_b32 sa[2], s2             # 0
656        s_xor_b32 sa[6], sa[2], s3      # 4
657        .cf_jump a1,a2,a3
658        s_setpc_b64 s[0:1]              # 8
659       
660a1:     s_add_u32 sa[2], sa[2], sa[3]   # 12
661        s_add_u32 sa[2], sa[2], sa[3]   # 16
662        .cf_jump b1,b2
663        s_setpc_b64 s[0:1]              # 20
664a2:     s_add_u32 sa[2], sa[2], sa[4]   # 24
665        s_add_u32 sa[2], sa[2], sa[4]   # 28
666        .cf_jump b1,b2
667        s_setpc_b64 s[0:1]              # 32
668a3:     s_add_u32 sa[2], sa[2], sa[5]   # 36
669        s_add_u32 sa[2], sa[2], sa[5]   # 40
670        .cf_jump b1,b2
671        s_setpc_b64 s[0:1]              # 44
672       
673b1:     s_add_u32 sa[5], sa[6], sa[4]   # 48
674        s_branch end                    # 52
675b2:     s_add_u32 sa[6], sa[5], sa[4]   # 56
676        s_branch end                    # 60
677       
678end:    s_xor_b32 sa[2], sa[2], s3      # 64
679        s_xor_b32 sa[3], sa[6], s4      # 68
680        s_endpgm                        # 72
681)ffDXD",
682        {   // livenesses
683            {   // for SGPRs
684                { { 0, 21 }, { 24, 33 }, { 36, 45 } }, // 0: S0
685                { { 0, 21 }, { 24, 33 }, { 36, 45 } }, // 1: S1
686                { { 0, 1 } }, // 2: S2
687                { { 0, 65 } }, // 3: S3
688                { { 0, 69 } }, // 4: S4
689                { { 1, 13 }, { 24, 25 }, { 36, 37 } }, // 5: sa[2]'0
690                { { 13, 17 } }, // 6: sa[2]'1
691                { { 17, 24 }, { 29, 36 }, { 41, 65 } }, // 7: sa[2]'2
692                { { 65, 66 } }, // 8: sa[2]'3
693                { { 25, 29 } }, // 9: sa[2]'4
694                { { 37, 41 } }, // 10: sa[2]'5
695                { { 0, 17 } }, // 11: sa[3]'0
696                { { 69, 70 } }, // 12: sa[3]'1
697                { { 0, 49 }, { 56, 57 } }, // 13: sa[4]'0
698                { { 0, 48 }, { 56, 57 } }, // 14: sa[5]'0
699                { { 49, 50 } }, // 15: sa[5]'0
700                { { 5, 56 }, { 57, 69 } }  // 16: sa[6]'0
701            },
702            { },
703            { },
704            { }
705        },
706        {   // linearDepMaps
707            { // for SGPRs
708                { 0, { 0, { }, { 1, 1, 1, 1 } } },
709                { 1, { 0, { 0, 0, 0, 0 }, { } } }
710            },
711            { },
712            { },
713            { }
714        },
715        true, ""
716    }
717};
718
719static TestSingleVReg getTestSingleVReg(const AsmSingleVReg& vr,
720        const std::unordered_map<const AsmRegVar*, CString>& rvMap)
721{
722    if (vr.regVar == nullptr)
723        return { "", vr.index };
724   
725    auto it = rvMap.find(vr.regVar);
726    if (it == rvMap.end())
727        throw Exception("getTestSingleVReg: RegVar not found!!");
728    return { it->second, vr.index };
729}
730
731static void testCreateLivenessesCase(cxuint i, const AsmLivenessesCase& testCase)
732{
733    std::istringstream input(testCase.input);
734    std::ostringstream errorStream;
735   
736    Assembler assembler("test.s", input,
737                    (ASM_ALL&~ASM_ALTMACRO) | ASM_TESTRUN | ASM_TESTRESOLVE,
738                    BinaryFormat::RAWCODE, GPUDeviceType::CAPE_VERDE, errorStream);
739    bool good = assembler.assemble();
740    if (assembler.getSections().size()<1)
741    {
742        std::ostringstream oss;
743        oss << "FAILED for " << " testAsmLivenesses#" << i;
744        throw Exception(oss.str());
745    }
746    const AsmSection& section = assembler.getSections()[0];
747   
748    AsmRegAllocator regAlloc(assembler);
749   
750    regAlloc.createCodeStructure(section.codeFlow, section.getSize(),
751                            section.content.data());
752    regAlloc.createSSAData(*section.usageHandler);
753    regAlloc.applySSAReplaces();
754    regAlloc.createLivenesses(*section.usageHandler);
755   
756    std::ostringstream oss;
757    oss << " testAsmLivenesses case#" << i;
758    const std::string testCaseName = oss.str();
759   
760    assertValue<bool>("testAsmLivenesses", testCaseName+".good",
761                      testCase.good, good);
762    assertString("testAsmLivenesses", testCaseName+".errorMessages",
763              testCase.errorMessages, errorStream.str());
764   
765    std::unordered_map<const AsmRegVar*, CString> regVarNamesMap;
766    for (const auto& rvEntry: assembler.getRegVarMap())
767        regVarNamesMap.insert(std::make_pair(&rvEntry.second, rvEntry.first));
768   
769    // generate livenesses indices conversion table
770    const VarIndexMap* vregIndexMaps = regAlloc.getVregIndexMaps();
771   
772    std::vector<size_t> lvIndexCvtTables[MAX_REGTYPES_NUM];
773    std::vector<size_t> revLvIndexCvtTables[MAX_REGTYPES_NUM];
774    for (size_t r = 0; r < MAX_REGTYPES_NUM; r++)
775    {
776        const VarIndexMap& vregIndexMap = vregIndexMaps[r];
777        Array<std::pair<TestSingleVReg, const std::vector<size_t>*> > outVregIdxMap(
778                    vregIndexMap.size());
779       
780        size_t j = 0;
781        for (const auto& entry: vregIndexMap)
782        {
783            TestSingleVReg vreg = getTestSingleVReg(entry.first, regVarNamesMap);
784            outVregIdxMap[j++] = std::make_pair(vreg, &entry.second);
785        }
786        mapSort(outVregIdxMap.begin(), outVregIdxMap.end());
787       
788        std::vector<size_t>& lvIndexCvtTable = lvIndexCvtTables[r];
789        std::vector<size_t>& revLvIndexCvtTable = revLvIndexCvtTables[r];
790        // generate livenessCvt table
791        for (const auto& entry: outVregIdxMap)
792            for (size_t v: *entry.second)
793                if (v != SIZE_MAX)
794                {
795                    /*std::cout << "lvidx: " << v << ": " << entry.first.name << ":" <<
796                            entry.first.index << std::endl;*/
797                    size_t j = lvIndexCvtTable.size();
798                    lvIndexCvtTable.push_back(v);
799                    if (v+1 > revLvIndexCvtTable.size())
800                        revLvIndexCvtTable.resize(v+1);
801                    revLvIndexCvtTable[v] = j;
802                }
803    }
804   
805    const Array<OutLiveness>* resLivenesses = regAlloc.getOutLivenesses();
806    for (size_t r = 0; r < MAX_REGTYPES_NUM; r++)
807    {
808        std::ostringstream rOss;
809        rOss << "live.regtype#" << r;
810        rOss.flush();
811        std::string rtname(rOss.str());
812       
813        assertValue("testAsmLivenesses", testCaseName + rtname + ".size",
814                    testCase.livenesses[r].size(), resLivenesses[r].size());
815       
816        for (size_t li = 0; li < resLivenesses[r].size(); li++)
817        {
818            std::ostringstream lOss;
819            lOss << ".liveness#" << li;
820            lOss.flush();
821            std::string lvname(rtname + lOss.str());
822            const OutLiveness& expLv = testCase.livenesses[r][li];
823            const OutLiveness& resLv = resLivenesses[r][lvIndexCvtTables[r][li]];
824           
825            // checking liveness
826            assertValue("testAsmLivenesses", testCaseName + lvname + ".size",
827                    expLv.size(), resLv.size());
828            for (size_t k = 0; k < resLv.size(); k++)
829            {
830                std::ostringstream regOss;
831                regOss << ".reg#" << k;
832                regOss.flush();
833                std::string regname(lvname + regOss.str());
834                assertValue("testAsmLivenesses", testCaseName + regname + ".first",
835                    expLv[k].first, resLv[k].first);
836                assertValue("testAsmLivenesses", testCaseName + regname + ".second",
837                    expLv[k].second, resLv[k].second);
838            }
839        }
840    }
841   
842    const std::unordered_map<size_t, LinearDep>* resLinearDepMaps =
843                regAlloc.getLinearDepMaps();
844    for (size_t r = 0; r < MAX_REGTYPES_NUM; r++)
845    {
846        std::ostringstream rOss;
847        rOss << "lndep.regtype#" << r;
848        rOss.flush();
849        std::string rtname(rOss.str());
850       
851        assertValue("testAsmLivenesses", testCaseName + rtname + ".size",
852                    testCase.linearDepMaps[r].size(), resLinearDepMaps[r].size());
853       
854        for (size_t di = 0; di < testCase.linearDepMaps[r].size(); di++)
855        {
856            std::ostringstream lOss;
857            lOss << ".lndep#" << di;
858            lOss.flush();
859            std::string ldname(rtname + lOss.str());
860            const auto& expLinearDepEntry = testCase.linearDepMaps[r][di];
861            auto rlit = resLinearDepMaps[r].find(
862                            lvIndexCvtTables[r][expLinearDepEntry.first]);
863           
864            std::ostringstream vOss;
865            vOss << expLinearDepEntry.first;
866            vOss.flush();
867            assertTrue("testAsmLivenesses", testCaseName + ldname + ".key=" + vOss.str(),
868                        rlit != resLinearDepMaps[r].end());
869            const LinearDep2& expLinearDep = expLinearDepEntry.second;
870            const LinearDep& resLinearDep = rlit->second;
871           
872            assertValue("testAsmLivenesses", testCaseName + ldname + ".align",
873                        cxuint(expLinearDep.align), cxuint(resLinearDep.align));
874           
875            Array<size_t> resPrevVidxes(resLinearDep.prevVidxes.size());
876            // convert to res ssaIdIndices
877            for (size_t k = 0; k < resLinearDep.prevVidxes.size(); k++)
878                resPrevVidxes[k] = revLvIndexCvtTables[r][resLinearDep.prevVidxes[k]];
879           
880            assertArray("testAsmLivenesses", testCaseName + ldname + ".prevVidxes",
881                        expLinearDep.prevVidxes, resPrevVidxes);
882           
883            Array<size_t> resNextVidxes(resLinearDep.nextVidxes.size());
884            // convert to res ssaIdIndices
885            for (size_t k = 0; k < resLinearDep.nextVidxes.size(); k++)
886                resNextVidxes[k] = revLvIndexCvtTables[r][resLinearDep.nextVidxes[k]];
887           
888            assertArray("testAsmLivenesses", testCaseName + ldname + ".nextVidxes",
889                        expLinearDep.nextVidxes, resNextVidxes);
890        }
891    }
892}
893
894int main(int argc, const char** argv)
895{
896    int retVal = 0;
897    for (size_t i = 0; i < sizeof(createLivenessesCasesTbl)/sizeof(AsmLivenessesCase); i++)
898        try
899        { testCreateLivenessesCase(i, createLivenessesCasesTbl[i]); }
900        catch(const std::exception& ex)
901        {
902            std::cerr << ex.what() << std::endl;
903            retVal = 1;
904        }
905    return retVal;
906}
Note: See TracBrowser for help on using the repository browser.