void DFSSortClusters::dfs(uint32_t cid) { if (m_visited.test(cid)) return; m_visited.set(cid); m_list.push_back(Vlabel(cid)); // find the best successor, which is the one to which cid has the // highest weight among the ones that haven't been visited yet int64_t maxWgt = 0; uint32_t bestSucc = uint32_t(-1); for (auto& sInfo : m_clusterSuccs[cid]) { auto succId = sInfo.first; if (m_visited.test(succId)) continue; auto wgt = sInfo.second; if (wgt >= maxWgt) { maxWgt = wgt; bestSucc = succId; } } if (bestSucc == uint32_t(-1)) return; // visit bestSucc first dfs(bestSucc); // now visit the remaining ones for (auto& sInfo : m_clusterSuccs[cid]) { if (sInfo.first != bestSucc) { dfs(sInfo.first); } } }
void natural_loop_dfs(jit::vector<Block*>& out, Visited& visited, Block* blk) { if (visited.test(blk->id())) return; visited.set(blk->id()); blk->forEachPred([&] (Block* pred) { natural_loop_dfs(out, visited, pred); }); out.push_back(blk); }
void Vgen::emit(jcc& i) { assertx(i.cc != CC_None); if (i.targets[1] != i.targets[0]) { if (next == i.targets[1]) { // the taken branch is the fall-through block, invert the branch. i = jcc{ccNegate(i.cc), i.sf, {i.targets[1], i.targets[0]}}; } jccs.push_back({a->frontier(), i.targets[1]}); // B.cond range is +/- 1MB but this uses BR backend.emitSmashableJump(*codeBlock, kEndOfTargetChain, i.cc); } emit(jmp{i.targets[0]}); }
void Vgen::emit(tbcc& i) { assertx(i.cc == vixl::ne || i.cc == vixl::eq); if (i.targets[1] != i.targets[0]) { if (next == i.targets[1]) { // the taken branch is the fall-through block, invert the branch. i = tbcc{i.cc == vixl::ne ? vixl::eq : vixl::ne, i.bit, i.s, {i.targets[1], i.targets[0]}}; } bccs.push_back({a->frontier(), i.targets[1]}); // offset range +/- 32KB if (i.cc == vixl::ne) { a->tbnz(X(i.s), i.bit, 0); } else { a->tbz(X(i.s), i.bit, 0); } } emit(jmp{i.targets[0]}); }
void Vgen::emit(jmp i) { if (next == i.target) return; jmps.push_back({a->frontier(), i.target}); // B range is +/- 128MB but this uses BR backend.emitSmashableJump(*codeBlock, kEndOfTargetChain, CC_None); }
void Vgen::emit(hcunwind& i) { catches.push_back({points[i.call], i.targets[1]}); emit(jmp{i.targets[0]}); }