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

Last change on this file since 4025 was 4025, checked in by matszpk, 6 months ago

CLRadeonExtender: AsmRegAlloc?: Fixed usagePos in CodeBlocks? (now is correct position in RVU).
Fixed segfault in GCNUsageHandler::getUsageDependencies. Fixes in createLivenesses.

File size: 11.7 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::EqualToDep EqualToDep;
38typedef AsmRegAllocator::VarIndexMap VarIndexMap;
39
40struct LinearDep2
41{
42    cxbyte align;
43    Array<size_t> prevVidxes;
44    Array<size_t> nextVidxes;
45};
46struct EqualToDep2
47{
48    Array<size_t> prevVidxes;
49    Array<size_t> nextVidxes;
50};
51
52struct AsmLivenessesCase
53{
54    const char* input;
55    Array<OutLiveness> livenesses[MAX_REGTYPES_NUM];
56    Array<std::pair<size_t, LinearDep2> > linearDepMaps[MAX_REGTYPES_NUM];
57    Array<std::pair<size_t, EqualToDep2> > equalToDepMaps[MAX_REGTYPES_NUM];
58    bool good;
59    const char* errorMessages;
60};
61
62static const AsmLivenessesCase createLivenessesCasesTbl[] =
63{
64#if 0
65    {   // 0 - simple case
66        R"ffDXD(.regvar sa:s:8, va:v:10
67        s_mov_b32 sa[4], sa[2]  # 0
68        s_add_u32 sa[4], sa[4], s3
69        v_xor_b32 va[4], va[2], v3
70)ffDXD",
71        {   // livenesses
72            {   // for SGPRs
73                { },
74                { },
75                { },
76                { }
77            },
78            {   // for VGPRs
79                { },
80                { },
81                { }
82            },
83            { },
84            { }
85        },
86        {   // linearDepMaps
87        },
88        {   // equalToDepMaps
89        }, true, ""
90    }
91#endif
92};
93
94static TestSingleVReg getTestSingleVReg(const AsmSingleVReg& vr,
95        const std::unordered_map<const AsmRegVar*, CString>& rvMap)
96{
97    if (vr.regVar == nullptr)
98        return { "", vr.index };
99   
100    auto it = rvMap.find(vr.regVar);
101    if (it == rvMap.end())
102        throw Exception("getTestSingleVReg: RegVar not found!!");
103    return { it->second, vr.index };
104}
105
106static void testCreateLivenessesCase(cxuint i, const AsmLivenessesCase& testCase)
107{
108    std::istringstream input(testCase.input);
109    std::ostringstream errorStream;
110   
111    Assembler assembler("test.s", input,
112                    (ASM_ALL&~ASM_ALTMACRO) | ASM_TESTRUN | ASM_TESTRESOLVE,
113                    BinaryFormat::RAWCODE, GPUDeviceType::CAPE_VERDE, errorStream);
114    bool good = assembler.assemble();
115    if (assembler.getSections().size()<1)
116    {
117        std::ostringstream oss;
118        oss << "FAILED for " << " testAsmLivenesses#" << i;
119        throw Exception(oss.str());
120    }
121    const AsmSection& section = assembler.getSections()[0];
122   
123    AsmRegAllocator regAlloc(assembler);
124   
125    regAlloc.createCodeStructure(section.codeFlow, section.getSize(),
126                            section.content.data());
127    regAlloc.createSSAData(*section.usageHandler);
128    regAlloc.applySSAReplaces();
129    regAlloc.createLivenesses(*section.usageHandler);
130   
131    std::ostringstream oss;
132    oss << " testAsmLivenesses case#" << i;
133    const std::string testCaseName = oss.str();
134   
135    assertValue<bool>("testAsmLivenesses", testCaseName+".good",
136                      testCase.good, good);
137    assertString("testAsmLivenesses", testCaseName+".errorMessages",
138              testCase.errorMessages, errorStream.str());
139   
140    std::unordered_map<const AsmRegVar*, CString> regVarNamesMap;
141    for (const auto& rvEntry: assembler.getRegVarMap())
142        regVarNamesMap.insert(std::make_pair(&rvEntry.second, rvEntry.first));
143   
144    // generate livenesses indices conversion table
145    const VarIndexMap* vregIndexMaps = regAlloc.getVregIndexMaps();
146   
147    std::vector<size_t> lvIndexCvtTables[MAX_REGTYPES_NUM];
148    for (size_t r = 0; r < MAX_REGTYPES_NUM; r++)
149    {
150        const VarIndexMap& vregIndexMap = vregIndexMaps[r];
151        Array<std::pair<TestSingleVReg, const std::vector<size_t>*> > outVregIdxMap(
152                    vregIndexMap.size());
153       
154        size_t i = 0;
155        for (const auto& entry: vregIndexMap)
156        {
157            TestSingleVReg vreg = getTestSingleVReg(entry.first, regVarNamesMap);
158            outVregIdxMap[i++] = std::make_pair(vreg, &entry.second);
159        }
160        mapSort(outVregIdxMap.begin(), outVregIdxMap.end());
161       
162        std::vector<size_t>& lvIndexCvtTable = lvIndexCvtTables[r];
163        // generate livenessCvt table
164        for (const auto& entry: outVregIdxMap)
165        {
166            for (size_t v: *entry.second)
167                if (v != SIZE_MAX)
168                    lvIndexCvtTable.push_back(v);
169        }
170    }
171   
172    const Array<OutLiveness>* resLivenesses = regAlloc.getOutLivenesses();
173    for (size_t r = 0; r < MAX_REGTYPES_NUM; r++)
174    {
175        std::ostringstream rOss;
176        rOss << "live.regtype#" << r;
177        rOss.flush();
178        std::string rtname(rOss.str());
179       
180        assertValue("testAsmLivenesses", testCaseName + rtname + ".size",
181                    testCase.livenesses[r].size(), resLivenesses[r].size());
182       
183        for (size_t li = 0; li < resLivenesses[r].size(); li++)
184        {
185            std::ostringstream lOss;
186            lOss << ".liveness#" << li;
187            lOss.flush();
188            std::string lvname(rtname + lOss.str());
189            const OutLiveness& expLv = testCase.livenesses[r][li];
190            const OutLiveness& resLv = resLivenesses[r][lvIndexCvtTables[r][li]];
191           
192            // checking liveness
193            assertValue("testAsmLivenesses", testCaseName + lvname + ".size",
194                    expLv.size(), resLv.size());
195            for (size_t k = 0; k < resLv.size(); k++)
196            {
197                std::ostringstream regOss;
198                regOss << ".reg#" << k;
199                regOss.flush();
200                std::string regname(lvname + regOss.str());
201                assertValue("testAsmLivenesses", testCaseName + regname + ".first",
202                    expLv[k].first, resLv[k].first);
203                assertValue("testAsmLivenesses", testCaseName + regname + ".second",
204                    expLv[k].second, resLv[k].second);
205            }
206        }
207    }
208   
209    const std::unordered_map<size_t, LinearDep>* resLinearDepMaps =
210                regAlloc.getLinearDepMaps();
211    for (size_t r = 0; r < MAX_REGTYPES_NUM; r++)
212    {
213        std::ostringstream rOss;
214        rOss << "lndep.regtype#" << r;
215        rOss.flush();
216        std::string rtname(rOss.str());
217       
218        assertValue("testAsmLivenesses", testCaseName + rtname + ".size",
219                    testCase.linearDepMaps[r].size(), resLinearDepMaps[r].size());
220       
221        for (size_t di = 0; di < testCase.linearDepMaps[r].size(); di++)
222        {
223            std::ostringstream lOss;
224            lOss << ".lndep#" << di;
225            lOss.flush();
226            std::string ldname(rtname + lOss.str());
227            const auto& expLinearDepEntry = testCase.linearDepMaps[r][di];
228            auto rlit = resLinearDepMaps[r].find(expLinearDepEntry.first);
229           
230            std::ostringstream vOss;
231            vOss << expLinearDepEntry.first;
232            vOss.flush();
233            assertTrue("testAsmLivenesses", testCaseName + ldname + ".key=" + vOss.str(),
234                        rlit != resLinearDepMaps[r].end());
235            const LinearDep2& expLinearDep = expLinearDepEntry.second;
236            const LinearDep& resLinearDep = rlit->second;
237           
238            assertValue("testAsmLivenesses", testCaseName + ldname + ".align",
239                        cxuint(expLinearDep.align), cxuint(resLinearDep.align));
240           
241            Array<size_t> expPrevVidxes(expLinearDep.prevVidxes.size());
242            // convert to res ssaIdIndices
243            for (size_t k = 0; k < expLinearDep.prevVidxes.size(); k++)
244                expPrevVidxes[k] = lvIndexCvtTables[r][expLinearDep.prevVidxes[k]];
245           
246            assertArray("testAsmLivenesses", testCaseName + ldname + ".prevVidxes",
247                        expPrevVidxes, resLinearDep.prevVidxes);
248           
249            Array<size_t> expNextVidxes(expLinearDep.nextVidxes.size());
250            // convert to res ssaIdIndices
251            for (size_t k = 0; k < expLinearDep.nextVidxes.size(); k++)
252                expNextVidxes[k] = lvIndexCvtTables[r][expLinearDep.nextVidxes[k]];
253           
254            assertArray("testAsmLivenesses", testCaseName + ldname + ".nextVidxes",
255                        expNextVidxes, resLinearDep.nextVidxes);
256        }
257    }
258   
259    const std::unordered_map<size_t, EqualToDep>* resEqualToDepMaps =
260                regAlloc.getEqualToDepMaps();
261    for (size_t r = 0; r < MAX_REGTYPES_NUM; r++)
262    {
263        std::ostringstream rOss;
264        rOss << "eqtodep.regtype#" << r;
265        rOss.flush();
266        std::string rtname(rOss.str());
267       
268        assertValue("testAsmLivenesses", testCaseName + rtname + ".size",
269                    testCase.equalToDepMaps[r].size(), resEqualToDepMaps[r].size());
270       
271        for (size_t di = 0; di < testCase.equalToDepMaps[r].size(); di++)
272        {
273            std::ostringstream lOss;
274            lOss << ".eqtodep#" << di;
275            lOss.flush();
276            std::string ldname(rtname + lOss.str());
277            const auto& expEqualToDepEntry = testCase.equalToDepMaps[r][di];
278            auto reit = resEqualToDepMaps[r].find(expEqualToDepEntry.first);
279           
280            std::ostringstream vOss;
281            vOss << expEqualToDepEntry.first;
282            vOss.flush();
283            assertTrue("testAsmLivenesses", testCaseName + ldname + ".key=" + vOss.str(),
284                        reit != resEqualToDepMaps[r].end());
285            const EqualToDep2& expEqualToDep = expEqualToDepEntry.second;
286            const EqualToDep& resEqualToDep = reit->second;
287           
288            Array<size_t> expPrevVidxes(expEqualToDep.prevVidxes.size());
289            // convert to res ssaIdIndices
290            for (size_t k = 0; k < expEqualToDep.prevVidxes.size(); k++)
291                expPrevVidxes[k] = lvIndexCvtTables[r][expEqualToDep.prevVidxes[k]];
292           
293            assertArray("testAsmLivenesses", testCaseName + ldname + ".prevVidxes",
294                        expPrevVidxes, resEqualToDep.prevVidxes);
295           
296            Array<size_t> expNextVidxes(expEqualToDep.nextVidxes.size());
297            // convert to res ssaIdIndices
298            for (size_t k = 0; k < expEqualToDep.nextVidxes.size(); k++)
299                expNextVidxes[k] = lvIndexCvtTables[r][expEqualToDep.nextVidxes[k]];
300           
301            assertArray("testAsmLivenesses", testCaseName + ldname + ".nextVidxes",
302                        expNextVidxes, resEqualToDep.nextVidxes);
303        }
304    }
305}
306
307int main(int argc, const char** argv)
308{
309    int retVal = 0;
310    for (size_t i = 0; i < sizeof(createLivenessesCasesTbl)/sizeof(AsmLivenessesCase); i++)
311        try
312        { testCreateLivenessesCase(i, createLivenessesCasesTbl[i]); }
313        catch(const std::exception& ex)
314        {
315            std::cerr << ex.what() << std::endl;
316            retVal = 1;
317        }
318    return retVal;
319}
Note: See TracBrowser for help on using the repository browser.