/** 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; } } }