HashSet<const NaturalLoop*> findLoopsContainingLoopHintWithoutOSREnter(const NaturalLoops& naturalLoops, FTL::CapabilityLevel level)
    {
        HashSet<const NaturalLoop*> loopsContainingLoopHintWithoutOSREnter;
        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
                Node* node = block->at(nodeIndex);
                if (node->op() != LoopHint)
                    continue;

                if (!canOSREnterAtLoopHint(level, block, nodeIndex)) {
                    const NaturalLoop* loop = naturalLoops.innerMostLoopOf(block);
                    while (loop) {
                        loopsContainingLoopHintWithoutOSREnter.add(loop);
                        loop = naturalLoops.innerMostOuterLoop(*loop);
                    }
                }
            }
        }
        return loopsContainingLoopHintWithoutOSREnter;
    }
    HashMap<const NaturalLoop*, unsigned> buildNaturalLoopToLoopHintMap(const NaturalLoops& naturalLoops)
    {
        HashMap<const NaturalLoop*, unsigned> naturalLoopsToLoopHint;

        for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
                Node* node = block->at(nodeIndex);
                if (node->op() != LoopHint)
                    continue;

                if (const NaturalLoop* loop = naturalLoops.innerMostLoopOf(block)) {
                    unsigned bytecodeIndex = node->origin.semantic.bytecodeIndex;
                    naturalLoopsToLoopHint.add(loop, bytecodeIndex);
                }
                break;
            }
        }
        return naturalLoopsToLoopHint;
    }