source: CLRX/CLRadeonExtender/trunk/tests/amdasm/AsmRegAlloc2.cpp @ 3997

Last change on this file since 3997 was 3997, checked in by matszpk, 15 months ago

CLRadeonExtender: AsmRegAlloc?: First testcase for AsmRegAlloc::applySSAReplaces routine. Add new constructor to AsmRegAllocator? (to simplify testing).
Add new constructor to VectoSet?.

File size: 12.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
35struct AsmApplySSAReplacesCase
36{
37    Array<CCodeBlock2> inCodeBlocks;
38    Array<std::pair<TestSingleVReg2, Array<SSAReplace> > > inSSAReplaces;
39    Array<CCodeBlock2> codeBlocks; // expected code blocks
40};
41
42static const AsmApplySSAReplacesCase ssaApplyReplacesCasesTbl[] =
43{
44    {   // 0 - first testcase
45        {
46            // block 0 - start
47            { 0, 8,
48                { },
49                {
50                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
51                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
52                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
53                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) }
54                }, false, false, false },
55            // block 1 - loop
56            { 8, 16,
57                { { 2, false }, { 4, false } },
58                {
59                    { { "sa", 2 }, SSAInfo(1, 2, 2, 2, 1, true) },
60                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
61                }, false, false, false },
62            // block 2 - loop part 2
63            { 16, 24,
64                { { 1, false }, { 3, false } },
65                {
66                    { { "sa", 2 }, SSAInfo(2, SIZE_MAX, 3, SIZE_MAX, 0, true) },
67                    { { "sa", 3 }, SSAInfo(1, 2, 2, 2, 1, false) },
68                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
69                }, false, false, false },
70            // block 3 - end 2
71            { 24, 28,
72                { },
73                { }, false, false, true },
74            // block 4 - end
75            { 28, 36,
76                { },
77                {
78                    { { "sa", 3 }, SSAInfo(1, 3, 3, 3, 1, true) },
79                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
80                }, false, false, true }
81        },
82        {
83            { { "sa", 2 }, { { 2, 1 } } },
84            // must be
85            { { "sa", 3 }, { { 2, 1 } } }
86        },
87        // expected code blocks
88        {
89            // block 0 - start
90            { 0, 8,
91                { },
92                {
93                    { { "", 4 }, SSAInfo(0, 0, 0, 0, 0, true) },
94                    { { "", 5 }, SSAInfo(0, 0, 0, 0, 0, true) },
95                    { { "sa", 2 }, SSAInfo(0, 1, 1, 1, 1, false) },
96                    { { "sa", 3 }, SSAInfo(0, 1, 1, 1, 1, false) }
97                }, false, false, false },
98            // block 1 - loop
99            { 8, 16,
100                { { 2, false }, { 4, false } },
101                {
102                    { { "sa", 2 }, SSAInfo(1, 1, 2, 1, 1, true) },
103                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
104                }, false, false, false },
105            // block 2 - loop part 2
106            { 16, 24,
107                { { 1, false }, { 3, false } },
108                {
109                    { { "sa", 2 }, SSAInfo(1, SIZE_MAX, 3, SIZE_MAX, 0, true) },
110                    { { "sa", 3 }, SSAInfo(1, 1, 2, 1, 1, false) },
111                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
112                }, false, false, false },
113            // block 3 - end 2
114            { 24, 28,
115                { },
116                { }, false, false, true },
117            // block 4 - end
118            { 28, 36,
119                { },
120                {
121                    { { "sa", 3 }, SSAInfo(1, 3, 3, 3, 1, true) },
122                    { { "sa", 4 }, SSAInfo(0, SIZE_MAX, 1, SIZE_MAX, 0, true) }
123                }, false, false, true }
124        }
125    }
126};
127
128std::ostream& operator<<(std::ostream& os, const TestSingleVReg& vreg)
129{
130    if (!vreg.name.empty())
131        os << vreg.name << "[" << vreg.index << "]";
132    else
133        os << "@REG[" << vreg.index << "]";
134    return os;
135}
136
137static TestSingleVReg getTestSingleVReg(const AsmSingleVReg& vr,
138        const std::unordered_map<const AsmRegVar*, CString>& rvMap)
139{
140    if (vr.regVar == nullptr)
141        return { "", vr.index };
142   
143    auto it = rvMap.find(vr.regVar);
144    if (it == rvMap.end())
145        throw Exception("getTestSingleVReg: RegVar not found!!");
146    return { it->second, vr.index };
147}
148
149static void testApplySSAReplaces(cxuint i, const AsmApplySSAReplacesCase& testCase)
150{
151    std::istringstream input("");
152    Assembler assembler("test.s", input, ASM_ALL&~ASM_ALTMACRO,
153                    BinaryFormat::RAWCODE, GPUDeviceType::CAPE_VERDE);
154   
155    std::unordered_map<CString, AsmRegVar> regVars;
156    std::vector<CodeBlock> inCodeBlocks;
157    // generate input code blocks
158    for (size_t i = 0; i < testCase.inCodeBlocks.size(); i++)
159    {
160        const CCodeBlock2& cc = testCase.inCodeBlocks[i];
161        CodeBlock inCodeBlock{ cc.start, cc.end,
162            std::vector<AsmRegAllocator::NextBlock>(cc.nexts.begin(), cc.nexts.end()),
163            cc.haveCalls, cc.haveReturn, cc.haveEnd };
164        for (const auto& v: cc.ssaInfos)
165        {
166            AsmSingleVReg vreg{ nullptr, v.first.index };
167            if (v.first.name != nullptr)
168            {
169                auto res = regVars.insert({ v.first.name , AsmRegVar{ 0, 100 } });
170                vreg.regVar = &res.first->second;
171            }
172            inCodeBlock.ssaInfoMap.insert({ vreg, v.second });
173        }
174        inCodeBlocks.push_back(inCodeBlock);
175    }
176    SSAReplacesMap inSSAReplaces;
177    // generate SSA replaces
178    for (const auto& replace: testCase.inSSAReplaces)
179    {
180        AsmSingleVReg vreg{ nullptr, replace.first.index };
181        if (replace.first.name != nullptr)
182        {
183            auto res = regVars.insert({ replace.first.name , AsmRegVar{ 0, 100 } });
184            vreg.regVar = &res.first->second;
185        }
186        inSSAReplaces.insert({ vreg, VectorSet<SSAReplace>(
187                    replace.second.begin(), replace.second.end()) });
188    }
189   
190    AsmRegAllocator regAlloc(assembler, inCodeBlocks, inSSAReplaces);
191    regAlloc.applySSAReplaces();
192   
193    const std::vector<CodeBlock>& resCodeBlocks = regAlloc.getCodeBlocks();
194    std::ostringstream oss;
195    oss << " testAsmSSAReplace case#" << i;
196    const std::string testCaseName = oss.str();
197   
198    assertValue("testAsmSSAReplace", testCaseName+".codeBlocks.size",
199                testCase.codeBlocks.size(), resCodeBlocks.size());
200   
201    std::unordered_map<const AsmRegVar*, CString> regVarNamesMap;
202    for (const auto& rvEntry: regVars)
203        regVarNamesMap.insert(std::make_pair(&rvEntry.second, rvEntry.first));
204   
205    for (size_t j = 0; j < resCodeBlocks.size(); j++)
206    {
207        const CCodeBlock2& expCBlock = testCase.codeBlocks[j];
208        const CodeBlock& resCBlock = resCodeBlocks[j];
209        std::ostringstream codeBlockOss;
210        codeBlockOss << ".codeBlock#" << j << ".";
211        codeBlockOss.flush();
212        std::string cbname(codeBlockOss.str());
213        assertValue("testAsmSSAReplace", testCaseName + cbname + "start",
214                    expCBlock.start, resCBlock.start);
215        assertValue("testAsmSSAReplace", testCaseName + cbname + "end",
216                    expCBlock.end, resCBlock.end);
217        assertValue("testAsmSSAReplace", testCaseName + cbname + "nextsSize",
218                    expCBlock.nexts.size(), resCBlock.nexts.size());
219       
220        for (size_t k = 0; k < expCBlock.nexts.size(); k++)
221        {
222            std::ostringstream nextOss;
223            nextOss << "next#" << k << ".";
224            nextOss.flush();
225            std::string nname(nextOss.str());
226           
227            assertValue("testAsmSSAReplace", testCaseName + cbname + nname + "block",
228                    expCBlock.nexts[k].block, resCBlock.nexts[k].block);
229            assertValue("testAsmSSAReplace", testCaseName + cbname + nname + "isCall",
230                    int(expCBlock.nexts[k].isCall), int(resCBlock.nexts[k].isCall));
231        }
232       
233        assertValue("testAsmSSAReplace", testCaseName + cbname + "ssaInfoSize",
234                    expCBlock.ssaInfos.size(), resCBlock.ssaInfoMap.size());
235       
236        Array<std::pair<TestSingleVReg, SSAInfo> > resSSAInfos(
237                        resCBlock.ssaInfoMap.size());
238        std::transform(resCBlock.ssaInfoMap.begin(), resCBlock.ssaInfoMap.end(),
239            resSSAInfos.begin(),
240            [&regVarNamesMap](const std::pair<AsmSingleVReg, SSAInfo>& a)
241            -> std::pair<TestSingleVReg, SSAInfo>
242            { return { getTestSingleVReg(a.first, regVarNamesMap), a.second }; });
243        mapSort(resSSAInfos.begin(), resSSAInfos.end());
244       
245        for (size_t k = 0; k < expCBlock.ssaInfos.size(); k++)
246        {
247            std::ostringstream ssaOss;
248            ssaOss << "ssaInfo#" << k << ".";
249            ssaOss.flush();
250            std::string ssaName(ssaOss.str());
251           
252            const TestSingleVReg expVReg = { expCBlock.ssaInfos[k].first.name,
253                    expCBlock.ssaInfos[k].first.index };
254           
255            assertValue("testAsmSSAReplace", testCaseName + cbname + ssaName + "svreg",
256                        expVReg, resSSAInfos[k].first);
257            const SSAInfo& expSInfo = expCBlock.ssaInfos[k].second;
258            const SSAInfo& resSInfo = resSSAInfos[k].second;
259            assertValue("testAsmSSAReplace",
260                        testCaseName + cbname + ssaName + "ssaIdBefore",
261                        expSInfo.ssaIdBefore, resSInfo.ssaIdBefore);
262            assertValue("testAsmSSAReplace", testCaseName + cbname + ssaName + "ssaId",
263                        expSInfo.ssaId, resSInfo.ssaId);
264            assertValue("testAsmSSAReplace",
265                        testCaseName + cbname + ssaName + "ssaIdChange",
266                        expSInfo.ssaIdChange, resSInfo.ssaIdChange);
267            assertValue("testAsmSSAReplace",
268                        testCaseName + cbname + ssaName + "ssaIdFirst",
269                        expSInfo.ssaIdFirst, resSInfo.ssaIdFirst);
270            assertValue("testAsmSSAReplace",
271                        testCaseName + cbname + ssaName + "ssaIdLast",
272                        expSInfo.ssaIdLast, resSInfo.ssaIdLast);
273            assertValue("testAsmSSAReplace", testCaseName + cbname + ssaName +
274                        "readBeforeWrite", int(expSInfo.readBeforeWrite),
275                        int(resSInfo.readBeforeWrite));
276        }
277       
278        assertValue("testAsmSSAReplace", testCaseName + cbname + "haveCalls",
279                    int(expCBlock.haveCalls), int(resCBlock.haveCalls));
280        assertValue("testAsmSSAReplace", testCaseName + cbname + "haveReturn",
281                    int(expCBlock.haveReturn), int(resCBlock.haveReturn));
282        assertValue("testAsmSSAReplace", testCaseName + cbname + "haveEnd",
283                    int(expCBlock.haveEnd), int(resCBlock.haveEnd));
284    }
285}
286
287int main(int argc, const char** argv)
288{
289    int retVal = 0;
290    for (size_t i = 0; i < sizeof(ssaApplyReplacesCasesTbl)/
291                        sizeof(AsmApplySSAReplacesCase); i++)
292        try
293        { testApplySSAReplaces(i, ssaApplyReplacesCasesTbl[i]); }
294        catch(const std::exception& ex)
295        {
296            std::cerr << ex.what() << std::endl;
297            retVal = 1;
298        }
299    return retVal;
300}
Note: See TracBrowser for help on using the repository browser.