Example #1
0
/** Perform simple tests to remove redundant blocks. */
void optimize(BlockList & blocks)
{
    int changes = 1;
    while (changes > 0)
    {
        changes = 0;
        BlockIter it = blocks.begin();
        while (it != blocks.end())
        {
            // Negative start indicates block is unreachable.
            if ((*it)->start < 0)
            {
                it = blocks.erase(it);
                ++changes;
            }

            // A block can be removed if it has no statements
            // and does not change locking status.
            else if ((*it)->stmts.size() == 0 && !(*it)->unlock)
            {
                int start = (*it)->start;

                //            cerr << "\nRemoving " << start << endl;

                Node closure = (*it)->closure;
                int transfer = (*it)->transfer;
                for (BlockIter ib = blocks.begin(); ib != blocks.end(); ++ib)
                {
                    if ((*ib)->start == transfer && closure !=0)
                        (*ib)->closure = closure;
                    if ((*ib)->transfer == start)
                        (*ib)->transfer = transfer;
                    if ((*ib)->altTransfer == start)
                        (*ib)->altTransfer = transfer;
                }
                it = blocks.erase(it);
                ++changes;
            }
            else
                ++it;
        }

        // Build a set of all labels in use
        set<int> labels;
        for (BlockIter it = blocks.begin(); it != blocks.end(); ++it)
        {
            labels.insert((*it)->transfer);
            labels.insert((*it)->altTransfer);

            // Include addresses of option nodes
            for (ListIter is = (*it)->stmts.begin(); is != (*it)->stmts.end(); ++is)
            {
                NodeKind k = (*is)->kind();
                if (k == OPTION_NODE || k == RECEIVE_OPTION_NODE || k == SEND_OPTION_NODE)
                    labels.insert((*it)->start);
            }
        }

        //      cerr << "Labels: ";
        //      for (set<int>::iterator it = labels.begin(); it != labels.end(); ++it)
        //         cerr << ' ' << *it;
        //      cerr << endl;

        it = blocks.begin();
        while (it != blocks.end())
        {
            if ((*it)->closure == 0 && labels.find((*it)->start) == labels.end())
            {
                it = blocks.erase(it);
                ++changes;
            }
            else
                ++it;
        }
    }
}