Changeset 4094 in CLRX


Ignore:
Timestamp:
May 6, 2018, 10:40:09 PM (4 months ago)
Author:
matszpk
Message:

CLRadeonExtender: AsmRegAlloc?: Add tentative joinVRegRecur and fillUpInsideRoutine.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • CLRadeonExtender/trunk/amdasm/AsmRegAlloc.cpp

    r4093 r4094  
    787787        }
    788788}
     789
     790static void fillUpInsideRoutine(std::vector<bool>& visited,
     791            const std::vector<CodeBlock>& codeBlocks, size_t startBlock,
     792            const AsmSingleVReg& svreg, Liveness& lv)
     793{
     794    std::deque<FlowStackEntry3> flowStack;
     795    flowStack.push_back({ startBlock, 0 });
     796   
     797    if (lv.contain(codeBlocks[startBlock].end-1))
     798        // already filled, then do nothing
     799        return;
     800   
     801    while (!flowStack.empty())
     802    {
     803        FlowStackEntry3& entry = flowStack.back();
     804        const CodeBlock& cblock = codeBlocks[entry.blockIndex];
     805       
     806        if (entry.nextIndex == 0)
     807        {
     808            if (!visited[entry.blockIndex])
     809            {
     810                visited[entry.blockIndex] = true;
     811                size_t cbStart = cblock.start;
     812                if (flowStack.size() == 1)
     813                {
     814                    // if first block, then get last occurrence in this path
     815                    auto sinfoIt = cblock.ssaInfoMap.find(svreg);
     816                    if (sinfoIt != cblock.ssaInfoMap.end())
     817                        cbStart = sinfoIt->second.lastPos+1;
     818                }
     819                // just insert
     820                lv.insert(cbStart, cblock.end);
     821            }
     822            else
     823            {
     824                flowStack.pop_back();
     825                continue;
     826            }
     827        }
     828       
     829        if (entry.nextIndex < cblock.nexts.size())
     830        {
     831            flowStack.push_back({ cblock.nexts[entry.nextIndex].block, 0 });
     832            entry.nextIndex++;
     833        }
     834        else if (((entry.nextIndex==0 && cblock.nexts.empty()) ||
     835                // if have any call then go to next block
     836                (cblock.haveCalls && entry.nextIndex==cblock.nexts.size())) &&
     837                 !cblock.haveReturn && !cblock.haveEnd)
     838        {
     839            flowStack.push_back({ entry.blockIndex+1, 0 });
     840            entry.nextIndex++;
     841        }
     842        else // back
     843            flowStack.pop_back();
     844    }
     845}
     846           
     847
     848static void joinVRegRecur(const std::deque<FlowStackEntry3>& flowStack,
     849            const std::vector<CodeBlock>& codeBlocks, const RoutineLvMap& routineMap,
     850            size_t flowStackStart, const AsmSingleVReg& svreg,
     851            const LastAccessBlockPos& lastAccessPos,
     852            const VarIndexMap* vregIndexMaps, std::vector<Liveness>* livenesses,
     853            size_t regTypesNum, const cxuint* regRanges)
     854{
     855    struct JoinEntry
     856    {
     857        size_t blockIndex; // block index where is call
     858        size_t nextIndex; // next index of routine call
     859        size_t lastAccessIndex; // last access pos index
     860        bool inSubroutines;
     861    };
     862    Liveness* lv = nullptr;
     863    std::vector<bool> visited(codeBlocks.size(), false);
     864   
     865    std::stack<JoinEntry> rjStack; // routine join stack
     866    if (lastAccessPos.inSubroutines)
     867        rjStack.push({ lastAccessPos.blockIndex, 0, 0, true });
     868   
     869    while (!rjStack.empty())
     870    {
     871        JoinEntry& entry = rjStack.top();
     872        const CodeBlock& cblock = codeBlocks[entry.blockIndex];
     873       
     874        if (entry.inSubroutines && entry.nextIndex < cblock.nexts.size())
     875        {
     876            bool doNextIndex = false; // true if to next call
     877            if (cblock.nexts[entry.nextIndex].isCall)
     878            {
     879                const RoutineDataLv& rdata =
     880                        routineMap.find(cblock.nexts[entry.nextIndex].block)->second;
     881                auto lastAccessIt = rdata.lastAccessMap.find(svreg);
     882                if (lastAccessIt != rdata.lastAccessMap.end())
     883                {
     884                    if (entry.lastAccessIndex < lastAccessIt->second.size())
     885                    {
     886                        const auto& lastAccess =
     887                                lastAccessIt->second[entry.lastAccessIndex];
     888                        rjStack.push({ lastAccess.blockIndex, 0,
     889                                    0, lastAccess.inSubroutines });
     890                        entry.lastAccessIndex++;
     891                    }
     892                    else
     893                        doNextIndex = true;
     894                }
     895                else
     896                    doNextIndex = true;
     897            }
     898            else
     899                doNextIndex = true;
     900           
     901            if (doNextIndex)
     902            {
     903                // to next call
     904                entry.nextIndex++;
     905                entry.lastAccessIndex = 0;
     906            }
     907        }
     908        else
     909        {
     910            size_t blockStart = entry.blockIndex;
     911            if (lv == nullptr)
     912            {
     913                const SSAInfo& ssaInfo = codeBlocks[blockStart]
     914                            .ssaInfoMap.find(svreg)->second;
     915                lv = &getLiveness2(svreg, (ssaInfo.ssaIdChange==0) ?
     916                        ssaInfo.ssaIdBefore : ssaInfo.ssaIdLast,
     917                        livenesses, vregIndexMaps, regTypesNum, regRanges);
     918            }
     919            if (!entry.inSubroutines)
     920                fillUpInsideRoutine(visited, codeBlocks, blockStart, svreg, *lv);
     921            else
     922            {
     923                // fill up next block in path (do not fill start block)
     924                const CodeBlock& cbstart = codeBlocks[blockStart];
     925                for (size_t k = 0; k < cbstart.nexts.size(); k++)
     926                    if (!cbstart.nexts[k].isCall)
     927                        fillUpInsideRoutine(visited, codeBlocks,
     928                                cbstart.nexts[k].block, svreg, *lv);
     929            }
     930            rjStack.pop();
     931        }
     932    }
     933   
     934    auto flit = flowStack.begin() + flowStackStart;
     935    if (lv == nullptr)
     936    {
     937        size_t blockStart = flit->blockIndex;
     938        auto ssaInfoIt = codeBlocks[blockStart].ssaInfoMap.find(svreg);
     939        size_t ssaId = 0;
     940        if (ssaInfoIt != codeBlocks[blockStart].ssaInfoMap.end())
     941            ssaId = (ssaInfoIt->second.ssaIdChange==0) ? ssaInfoIt->second.ssaIdLast :
     942                    ssaInfoIt->second.ssaIdBefore;
     943        lv = &getLiveness2(svreg, ssaId, livenesses, vregIndexMaps,
     944                        regTypesNum, regRanges);
     945    }
     946   
     947    // fill up to this
     948    for (++flit; flit != flowStack.end(); ++flit)
     949    {
     950        const CodeBlock& cblock = codeBlocks[flit->blockIndex];
     951        lv->insert(cblock.start, cblock.end);
     952    }
     953}
     954           
    789955
    790956static void joinSVregWithVisited(const SVRegMap* stackVarMap, const AsmSingleVReg& vreg,
Note: See TracChangeset for help on using the changeset viewer.