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

Last change on this file since 4054 was 4054, checked in by matszpk, 12 months ago

CLRadeonExtender: AsmRegAlloc?: Add yet another simple testcase for createSSAData. Tentative a working joining a visited paths (createLivenesses).

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