harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mloe...@apache.org
Subject svn commit: r469924 - in /incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf: ./ include/
Date Wed, 01 Nov 2006 14:55:46 GMT
Author: mloenko
Date: Wed Nov  1 06:55:45 2006
New Revision: 469924

URL: http://svn.apache.org/viewvc?view=rev&rev=469924
Log:
applied patch for HARMONY-1941
[drlvm][ipf] implementation and support for new code layoting algorithm

Modified:
    incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCfg.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCfgVerifier.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCodeLayouter.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfEmitter.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfInst.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfIrPrinter.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfRegisterAllocator.cpp
    incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfCfg.h
    incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfCodeLayouter.h
    incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfEmitter.h
    incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfIrPrinter.h
    incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfType.h

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCfg.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCfg.cpp?view=diff&rev=469924&r1=469923&r2=469924
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCfg.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCfg.cpp Wed Nov  1 06:55:45 2006
@@ -14,7 +14,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-
+                                                                                                            
 /**
  * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin
  * @version $Revision$
@@ -32,8 +32,8 @@
 // Edge
 //========================================================================================//
 
-Edge::Edge(Node *source_, Node *target_, double prob_) : 
-    edgeKind(EDGE_THROUGH),
+Edge::Edge(Node *source_, Node *target_, double prob_, EdgeKind edgeKind_) : 
+    edgeKind(edgeKind_),
     source(source_), 
     target(target_), 
     prob(prob_) {
@@ -41,11 +41,36 @@
 
 //----------------------------------------------------------------------------------------//
 
-Edge::Edge(Node *source_, Node *target_, double prob_, EdgeKind edgeKind_) : 
-    edgeKind(edgeKind_),
-    source(source_), 
-    target(target_), 
-    prob(prob_) {
+void Edge::remove() {
+    
+    source->removeEdge(this);
+    target->removeEdge(this);
+}
+
+//----------------------------------------------------------------------------------------//
+
+void Edge::insert() {
+
+    source->addEdge(this);
+    target->addEdge(this);
+}
+    
+//----------------------------------------------------------------------------------------//
+
+void Edge::changeSource(Node *source_) {
+    
+    source->removeEdge(this);
+    source = source_;
+    source->addEdge(this);
+}
+
+//----------------------------------------------------------------------------------------//
+
+void Edge::changeTarget(Node *target_) {
+    
+    target->removeEdge(this);
+    target = target_;
+    target->addEdge(this);
 }
 
 //----------------------------------------------------------------------------------------//
@@ -85,10 +110,9 @@
                              double  prob_, 
                              Type   *exceptionType_, 
                              uint32  priority_) :
-    Edge(source_, target_, prob_), 
+    Edge(source_, target_, prob_, EDGE_EXCEPTION), 
     exceptionType(exceptionType_),
     priority(priority_) {
-    setEdgeKind(EDGE_EXCEPTION);
 }
 
 //========================================================================================//
@@ -105,58 +129,62 @@
 
 void Node::addEdge(Edge *edge) {
 
-    if(edge->getSource() == this) outEdges.push_back(edge);
-    if(edge->getTarget() == this) inEdges.push_back(edge);
+    if (edge->getSource() == this) outEdges.push_back(edge);
+    if (edge->getTarget() == this) inEdges.push_back(edge);
 }
 
 //----------------------------------------------------------------------------------------//
 
 void Node::removeEdge(Edge *edge) {
-    if(edge->getSource() == this) remove(outEdges.begin(), outEdges.end(), edge);
-    if(edge->getTarget() == this) remove(inEdges.begin(), inEdges.end(), edge);
+
+    if (edge->getSource() == this) { 
+        EdgeIterator it = find(outEdges.begin(), outEdges.end(), edge); 
+        if (it != outEdges.end()) outEdges.erase(it); 
+    }
+    
+    if (edge->getTarget() == this) { 
+        EdgeIterator it = find(inEdges.begin(), inEdges.end(), edge); 
+        if (it != inEdges.end()) inEdges.erase(it); 
+    }
 }
 
 //----------------------------------------------------------------------------------------//
 
 Edge *Node::getOutEdge(EdgeKind edgeKind) {
     
-    Edge *edge = NULL;
     for(uint16 i=0; i<outEdges.size(); i++) {
-        if(outEdges[i]->getEdgeKind() == edgeKind) {
-            if(edge != NULL) assert(0);
-            edge = outEdges[i];
-        }
+        if(outEdges[i]->getEdgeKind() == edgeKind) return outEdges[i];
     }
-    return edge;
+    return NULL;
 }
 
 //----------------------------------------------------------------------------------------//
 
-Edge *Node::getOutEdge(Node *targetNode) {
-    for(uint16 i=0; i<outEdges.size(); i++)
-        if(outEdges[i]->getTarget() == targetNode) return outEdges[i];
+Edge *Node::getInEdge(EdgeKind edgeKind) {
+    
+    for(uint16 i=0; i<inEdges.size(); i++) {
+        if(inEdges[i]->getEdgeKind() == edgeKind) return inEdges[i];
+    }
     return NULL;
 }
 
 //----------------------------------------------------------------------------------------//
 
-Edge *Node::getInEdge(EdgeKind edgeKind) {
-    
-    Edge *edge = NULL;
-    for(uint16 i=0; i<inEdges.size(); i++) {
-        if(inEdges[i]->getEdgeKind() == edgeKind) {
-            if(edge != NULL) assert(0);
-            edge = inEdges[i];
-        }
+Edge *Node::getOutEdge(Node *targetNode) {
+
+    for(uint16 i=0; i<outEdges.size(); i++) {
+        if(outEdges[i]->getTarget() == targetNode) return outEdges[i];
     }
-    return edge;
+    return NULL;
 }
 
 //----------------------------------------------------------------------------------------//
 
 Edge *Node::getInEdge(Node *sourceNode) {
-    for(uint16 i=0; i<inEdges.size(); i++)
+
+    for(uint16 i=0; i<inEdges.size(); i++) {
         if(inEdges[i]->getSource() == sourceNode) return inEdges[i];
+    }
     return NULL;
 }
 
@@ -181,6 +209,21 @@
 
 //----------------------------------------------------------------------------------------//
 
+void Node::remove() {
+    
+    EdgeVector edges;
+    
+    // remove out edges
+    edges = outEdges;                          
+    for (uint16 i=0; i<edges.size(); i++) edges[i]->remove();                    
+    
+    // remove in edges
+    edges = inEdges;
+    for (uint16 i=0; i<edges.size(); i++) edges[i]->remove();                    
+}
+
+//----------------------------------------------------------------------------------------//
+
 void Node::removeInEdge(Edge *edge) {
 //    remove(inEdges.begin(), inEdges.end(), edge);
     EdgeVector::iterator last=inEdges.end();
@@ -241,39 +284,13 @@
 
 Cfg::Cfg(MemoryManager &mm, CompilationInterface &compilationInterface):
     mm(mm),
-    compilationInterface(compilationInterface),
-    enterNode(NULL),
-    lastSearchKind(SEARCH_UNDEF_ORDER),
-    maxNodeId(0) {
-
-    opndManager = new(mm) OpndManager(mm, compilationInterface);
-}
-
-//----------------------------------------------------------------------------------------//
-
-void Cfg::addEdge(Edge *edge) {
-
-    edge->getSource()->addEdge(edge);
-    edge->getTarget()->addEdge(edge);
-}
-
-//----------------------------------------------------------------------------------------//
-
-void Cfg::removeEdge(Edge *edge) {
-
-    edge->getSource()->removeEdge(edge);
-    edge->getTarget()->removeEdge(edge);
-}
-
-//----------------------------------------------------------------------------------------//
-
-void Cfg::removeNode(Node *node) {
-
-    EdgeVector &inEdges  = node->getInEdges();
-    EdgeVector &outEdges = node->getOutEdges();
+    compilationInterface(compilationInterface) {
 
-    for(uint16 i=0; i<inEdges.size();  i++) inEdges[i]->getSource()->removeEdge(inEdges[i]);
-    for(uint16 i=0; i<outEdges.size(); i++) outEdges[i]->getSource()->removeEdge(outEdges[i]);
+    maxNodeId      = 0;
+    opndManager    = new(mm) OpndManager(mm, compilationInterface);
+    enterNode      = NULL;
+    exitNode       = NULL;
+    lastSearchKind = SEARCH_UNDEF_ORDER;
 }
 
 //----------------------------------------------------------------------------------------//
@@ -287,11 +304,11 @@
     searchResult.clear();
 
     switch(searchKind) {
-        case SEARCH_DIRECT_ORDER : makeDirectOrdered(exitNode, visitedNodes);     break;
-        case SEARCH_POST_ORDER   : makePostOrdered(enterNode, visitedNodes);    break;
-        case SEARCH_LAYOUT_ORDER : makeLayoutOrdered();                         break;
-        case SEARCH_UNDEF_ORDER     :                                              break;
-        default                  : IPF_LOG << IPF_ERROR << endl;  break;
+        case SEARCH_DIRECT_ORDER : makeDirectOrdered(exitNode, visitedNodes); break;
+        case SEARCH_POST_ORDER   : makePostOrdered(enterNode, visitedNodes);  break;
+        case SEARCH_LAYOUT_ORDER : makeLayoutOrdered();                       break;
+        case SEARCH_UNDEF_ORDER  :                                            break;
+        default                  : IPF_ERR << endl;                           break;
     }
     
     return searchResult; 

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCfgVerifier.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCfgVerifier.cpp?view=diff&rev=469924&r1=469923&r2=469924
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCfgVerifier.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCfgVerifier.cpp Wed Nov  1 06:55:45 2006
@@ -14,7 +14,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-
+                                                                                                            
 /**
  * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin
  * @version $Revision$
@@ -620,7 +620,7 @@
 
 //---------------------------------------------------------------------------//
 void IpfCfgVerifier::setDefs() {
-    OpndVector&  args = cfg.getArgs();
+    OpndVector args; // = cfg.getArgs();
     BitSet* enterIn=getVertex(cfg.getEnterNode())->in;
     for (uint k=0; k<args.size(); k++) {
         enterIn->setBit(args[k]->getId());

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCodeLayouter.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCodeLayouter.cpp?view=diff&rev=469924&r1=469923&r2=469924
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCodeLayouter.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfCodeLayouter.cpp Wed Nov  1 06:55:45 2006
@@ -14,14 +14,13 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-
+                                                                                                            
 /**
  * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin
  * @version $Revision$
  *
  */
 
-#include "BitSet.h"
 #include "IpfCodeLayouter.h"
 #include "IpfIrPrinter.h"
 #include "IpfOpndManager.h"
@@ -33,7 +32,7 @@
 // Compare two edges by prob value
 //========================================================================================//
 
-bool greaterEdge (Edge *e1, Edge *e2) { return e1->getProb() > e2->getProb(); }
+bool greaterEdge(Edge *e1, Edge *e2) { return e1->getProb() > e2->getProb(); }
  
 //========================================================================================//
 // CodeLayouter
@@ -50,12 +49,14 @@
 
     IPF_LOG << endl << "  Merge Nodes" << endl;
     mergeNodes();
+    checkUnwind();
 
     IPF_LOG << endl << "  Make Chains" << endl;
     makeChains();
+    layoutNodes();
     
-    IPF_LOG << endl << "  Fix Branches" << endl;
-    fixBranches();
+    IPF_LOG << endl << "  Set Branch Targets" << endl;
+    setBranchTargets();
     
     IPF_STAT << endl << "STAT_NUM_NODES " << cfg.search(SEARCH_POST_ORDER).size() << endl;
 }
@@ -64,269 +65,327 @@
 
 void CodeLayouter::mergeNodes() {
     
-    NodeVector& nodes      = cfg.search(SEARCH_DIRECT_ORDER);
-    bool        cfgChanged = false;
-
-    for (uint i=0; i<nodes.size(); i++) {  // iterate through nodes
-        Node* node = nodes[i];
+    NodeVector& nodeVector = cfg.search(SEARCH_POST_ORDER);
+    NodeList    nodes(nodeVector.begin(), nodeVector.end());
 
-        if (LOG_ON) {
-            IPF_LOG << "    node" << setw(2) << left << node->getId() << flush;
-            node->printEdges(LOG_OUT);
-        }
-        
-        // don't merge with enter node
-        if (cfg.getEnterNode() == nodes[i]) {
-            IPF_LOG << " - ignore (don't merge with enter node)" << endl;
-            continue;
-        }
-        
-        // check node has only one successor (not taking in account unwind node)
-        EdgeVector& outEdges = node->getOutEdges();
-        if (outEdges.size() != 1) {
-            IPF_LOG << " - ignore (has more than one successor)" << endl;
-            continue;
-        }
+    // try to merge current node with its successor
+    for (NodeListIterator it=nodes.begin(); it!=nodes.end(); it++) {
         
-        // check if node is basic block 
-        if (node->getNodeKind() != NODE_BB) { 
-            IPF_LOG << " - ignore (is not basic block)" << endl;
-            continue;
-        }
-        
-        // don't merge with enter node
-        if (cfg.getEnterNode() == outEdges[0]->getTarget()) {
-            IPF_LOG << " - ignore (don't merge with enter node)" << endl;
-            continue;
-        }
+        Node *node = *it;
+        if (node->getNodeKind() != NODE_BB) continue; // node is not BB - ignore
+        if (node == cfg.getEnterNode())     continue; // do not merge enter node
         
-        // don't merge with enter node
-        if (outEdges[0]->getTarget()->getNodeKind() != NODE_BB) {
-            IPF_LOG << " - ignore (target is not basic block)" << endl;
-            continue;
-        }
+        BbNode *pred = (BbNode *)node;                // let's name current node "pred"
+        BbNode *succ = getSucc(pred);                 // check if it has mergable successor
+        if (succ == NULL)              continue;      // current node does not have mergable successor
+        if (succ == cfg.getExitNode()) continue;      // do not merge exit node
+        if (checkSucc(succ) == false)  continue;      // succ can not be merged with pred
         
-        cfgChanged |= mergeNode((BbNode*)node, outEdges[0]);
+        merge(pred, succ);                            // merge pred and succ nodes
+        nodes.remove(succ);                           // remove succ node from current nodes list
     }
+    cfg.search(SEARCH_UNDEF_ORDER);                   // we could remove some nodes - old search is broken
+}
+
+//----------------------------------------------------------------------------------------//
+// if node has only one succ (not taking in account unwind) - return the succ
+
+BbNode* CodeLayouter::getSucc(BbNode *node) {
     
-    if (cfgChanged) {
-        cfg.search(SEARCH_UNDEF_ORDER); // we have removed some nodes - old search is broken
+    Node       *succ     = NULL;
+    EdgeVector &outEdges = node->getOutEdges();
+
+    for (uint16 i=0; i<outEdges.size(); i++) {
+        Node *target = outEdges[i]->getTarget();            // get successor of current node
+        if (target->getNodeKind() == NODE_UNWIND) continue; // if it is unwind node - ignore
+        if (succ != NULL) return NULL;                      // there is more than one succ - node can not be merged
+        succ = target;                                      // it is first succ
     }
+    
+    if (succ == NULL)                   return NULL;        // there is no successor
+    if (succ->getNodeKind() != NODE_BB) return NULL;        // if succ is not BB - node can not be merged
+    return (BbNode *)succ;
+}
+
+//----------------------------------------------------------------------------------------//
+// check if succ can be merged with pred (has only one pred)
+
+bool CodeLayouter::checkSucc(BbNode *node) {
+
+    EdgeVector &inEdges = node->getInEdges();   // get succ in edges
+    if (inEdges.size() > 1) return false;       // succ has more than one pred - it can not be merged
+    return true;
 }
     
 //----------------------------------------------------------------------------------------//
+// merge two nodes
 
-bool CodeLayouter::mergeNode(BbNode *pred, Edge* pred2succ) {    
-    BbNode*  succ = (BbNode*)pred2succ->getTarget(); 
-    IPF_LOG << " - try to merge with node" << setw(2) << left;
-    IPF_LOG << succ->getId() << flush;    
-    if (succ->getNodeKind() != NODE_BB) { // if succ is NODE_DISPATCH - ignore
-        IPF_LOG << " - succ is not NODE_BB - ignore" << endl;
-        return false;
+void CodeLayouter::merge(BbNode *pred, BbNode *succ) {
+    
+    // copy succ's insts in pred node
+    InstVector &predInsts = pred->getInsts();
+    InstVector &succInsts = succ->getInsts();
+    predInsts.insert(predInsts.end(), succInsts.begin(), succInsts.end());
+    
+    // remove pred out edges
+    EdgeVector predOutEdges = pred->getOutEdges();    // make copy of pred out edges vector
+    for (uint16 i=0; i<predOutEdges.size(); i++) {    // iterate edges
+        predOutEdges[i]->remove();                    // remove edge
+    }
+    
+    // redirect succ's out edges on pred
+    EdgeVector succOutEdges = succ->getOutEdges();    // make copy of succ out edges vector
+    for (uint16 i=0; i<succOutEdges.size(); i++) {    // iterate edges
+        succOutEdges[i]->changeSource(pred);          // redirect edge
     }
+    
+    IPF_LOG << "    node" << left << setw(3) << pred->getId() << " merged with node" << succ->getId() << endl;
 
-    InstVector &predInsts = pred->getInsts();
-    if (predInsts.size() != 0) {  // checks applicaple to non-empty blocks:
-        // do not merge non-empty node with exit node
-         if (succ == cfg.getExitNode()) {
-            IPF_LOG << " - merge canceled (succ is Exit Node)" << endl;
-             return false;
-        }
-        // if Succ has predecessors other than pred - return
-        if (succ->getInEdges().size()!=1) {
-            IPF_LOG << " - succInEdges.size()!=1" << endl;
-            return false;
-        }
-        // insert Succ instructions after Pred instructions
-        InstVector &succInsts = succ->getInsts();
-        for (uint i=0, succsize = succInsts.size(); i<succsize; i++) {
-            predInsts.push_back(succInsts[i]);
-        }
-        // move combined instruction set to Succ
-        succInsts.swap(predInsts);
-    }  // end if non-empty block
-    
-     // remove Pred's out-edge
-       pred2succ->disconnect();
-    // reconnect Pred's in-edges to Succ 
-    EdgeVector &predInEdges = pred->getInEdges();
-    while (predInEdges.size()>0) {
-        predInEdges[predInEdges.size()-1]->connect(succ);
-    }
-    // if Pred is enter node - set Succ as new enter node
-    if (pred == cfg.getEnterNode()) {
-        cfg.setEnterNode(succ);
-        IPF_LOG << " - new enter";
+    if (LOG_ON) {
+        if (succ->getInEdges().size()  != 0) IPF_ERR << " size " << succ->getInEdges().size() << endl;
+        if (succ->getOutEdges().size() != 0) IPF_ERR << " size " << succ->getOutEdges().size() << endl;
     }
+}
+        
+//----------------------------------------------------------------------------------------//
+// if unwind node does not have predecessors (they could be removed during merging) - it can 
+// be removed
+
+void CodeLayouter::checkUnwind() {
     
-    IPF_LOG << " - merge successful" << endl;
-    return true;
+    // find unwind node (it must be predecessor of exit node)
+    Node       *unwind  = NULL;
+    Node       *exit    = cfg.getExitNode();
+    EdgeVector &inEdges = exit->getInEdges();            // get exit node in edges
+    for (uint16 i=0; i<inEdges.size(); i++) {            // iterate them
+        unwind = inEdges[i]->getSource();                // get edge source
+        if (unwind->getNodeKind() == NODE_UNWIND) break; // if the source is unwind node - we have found it
+    }
+    
+    // check if unwind can be removed
+    if (unwind == NULL)                  return;         // there is no unwind node
+    if (unwind->getInEdges().size() > 0) return;         // unwind node is alive - nothind to do
+    
+    // remove useless unwind
+    unwind->remove();
+    IPF_LOG << endl << "    unwind node removed" << endl;
 }
 
 //----------------------------------------------------------------------------------------//
 
 void CodeLayouter::makeChains() {
 
-    uint maxNodeId=cfg.getMaxNodeId();
-    BbNode **availNodes=new(mm) BbNode*[maxNodeId];
-    for(uint i=0; i<maxNodeId; i++) {
-        availNodes[i] = NULL;
-    }
-    
-    NodeVector& nodes = cfg.search(SEARCH_DIRECT_ORDER);   // actually, order does not matter
-    for(uint i=0; i<nodes.size(); i++) {
-        Node* node=nodes[i];
-        if (node->getNodeKind() != NODE_BB) continue; // ignore not BB nodes
-        availNodes[node->getId()] = (BbNode*)node;
-    }
-    
-    BbNode *currNode = (BbNode*) cfg.getEnterNode();  // start from the Enter Node
-    uint availPos=0; // where to look for next available node
-    IPF_LOG << "    new chain:";
-    for (;;) {
-        availNodes[currNode->getId()] = NULL;  // mark curr node consumed
-        IPF_LOG << " node" << currNode->getId() << "->";
-        
-        BbNode* nextNode=NULL;
+    // make edge list
+    EdgeVector edges;
+    NodeVector &nodes = cfg.search(SEARCH_POST_ORDER);               // get nodes vector
+    for (uint16 i=0; i<nodes.size(); i++) {                          // iterate throgh it
+        EdgeVector &outEdges = nodes[i]->getOutEdges();              // get out edges of current node
+        edges.insert(edges.end(), outEdges.begin(), outEdges.end()); // add them in edges list
+    }
+    
+    // sort edge list by prob
+    sort(edges.begin(), edges.end(), greaterEdge);
+    
+    // make chain list
+    for (uint16 i=0; i<edges.size(); i++) inChainList(edges[i]);
+}
 
-        // find out edge with max prob 
-        double currProb            = -10.0;
-        EdgeVector& outEdges = currNode->getOutEdges();
-        for(uint32 j=0; j<outEdges.size(); j++) {
-            BbNode* candidate = (BbNode*) outEdges[j]->getTarget();
-            if (availNodes[candidate->getId()] == NULL) continue; // ignore consumed nodes
-            if (currProb < outEdges[j]->getProb()) {          // we have found edge with prob greater then curr
-                currProb        = outEdges[j]->getProb();    // reset curr max prob 
-                nextNode         = candidate;                  // curr cand to be placed in chain
-            }
-        }
-        if (nextNode==NULL) {
-            IPF_LOG << endl;  // current chain finished
-            // try to start next chain
-            for (; availPos<maxNodeId; availPos++) {
-                nextNode = availNodes[availPos];
-                if (nextNode!=NULL) {
-                    break;
-                }
-            }
-            if (nextNode==NULL) {
-                return;  // no more nodes available
-            }
-            IPF_LOG << "    new chain:";
+//----------------------------------------------------------------------------------------//
+// if there is chain that can be connected with the edge - connect, else - create new chain
+
+void CodeLayouter::inChainList(Edge *edge) {
+    
+    Node  *sourceNode  = edge->getSource();
+    Node  *targetNode  = edge->getTarget();
+    Chain *targetChain = NULL;
+    Chain *sourceChain = NULL;
+
+    // try to find chains to add current edge in
+    for (ChainListIterator it=chains.begin(); it!=chains.end(); it++) {
+        if ((*it)->front() == targetNode) targetChain = *it;
+        if ((*it)->back()  == sourceNode) sourceChain = *it;
+    }
+    
+    if (targetChain!=NULL && sourceChain!=NULL) {               // edge connects two existing chains
+        if (targetChain == sourceChain) return;                 // do not merge chain with itself
+        sourceChain->splice(sourceChain->end(), *targetChain);  // merge chains in source chain
+        chains.remove(targetChain);                             // erase target chain
+        return;
+    }
+    
+    if (sourceChain != NULL) {                                  // sourceChain ending with edge source
+        pushBack(sourceChain, targetNode);                      // push target back in sourceChain
+        return;
+    }
+    
+    if (targetChain != NULL) {                                  // targetChain starting with edge target 
+        pushFront(targetChain, sourceNode);                     // push source front in targetChain
+        return;
+    }
+
+    // there is no chain that can be merged with the edge 
+    Chain *newChain = new Chain();                              // create new chain
+    pushBack(newChain, sourceNode);                             // push source back in new chain
+    pushBack(newChain, targetNode);                             // push target back in new chain
+    if (newChain->size() > 0) chains.push_back(newChain);       // insert new chain in chain list
+}
+
+//----------------------------------------------------------------------------------------//
+// push node in chain end
+
+void CodeLayouter::pushBack(Chain *chain, Node *node) {
+    if (visitedNodes.count(node) != 0) return; // node has already been inserted in some chain
+    visitedNodes.insert(node);                 // mark node as visited
+    chain->push_back(node);                    // push node back in the chain
+}
+
+//----------------------------------------------------------------------------------------//
+// push node in chain begining
+
+void CodeLayouter::pushFront(Chain *chain, Node *node) {
+    if (visitedNodes.count(node) != 0) return; // node has already been inserted in some chain
+    visitedNodes.insert(node);                 // mark node as visited
+    chain->push_front(node);                   // push node front in the chain
+}
+
+//----------------------------------------------------------------------------------------//
+// set layout successors for BbNodes
+
+void CodeLayouter::layoutNodes() {
+    
+    // sort chains 
+    ChainMap order;
+    for (ChainListIterator it=chains.begin(); it!=chains.end(); it++) {
+        uint32 weight = calculateChainWeight(*it);  // calculate chain weight
+        order.insert( make_pair(weight, *it) );     // insert pair weight->chain in map
+    }
+
+    // set layout successors for BbNodes
+    BbNode *pred = new(mm) BbNode(0, 0);            // current pred node (init with fake node)
+    BbNode *succ = NULL;                            // currend succ node
+    for (ChainMapIterator it1=order.begin(); it1!=order.end(); it1++) {
+        Chain *chain = it1->second;                 // current chain
+        IPF_LOG << "    weight: " << setw(10) << it1->first;
+        IPF_LOG << " chain: " << IrPrinter::toString(*(it1->second)) << endl;
+        
+        for (ChainIterator it2=chain->begin(); it2!=chain->end(); it2++) {
+            if ((*it2)->isBb() == false) continue;  // if current node is not BB - it does not need layouting
+            succ = (BbNode *)*it2;                  //
+            pred->setLayoutSucc(succ);              // set current node as layouted successor of pred
+            pred = succ;                            // current pred is current node
         }
-        currNode->setLayoutSucc(nextNode);
-        currNode=nextNode;
     }
 }
+
 //----------------------------------------------------------------------------------------//
+// chain weight is exec counters summ of all nodes in the chain
 
-void CodeLayouter::fixBranches() {
+uint32 CodeLayouter::calculateChainWeight(Chain *chain) {
+
+    if (chain->front() == cfg.getEnterNode()) return UINT_MAX;  // enter node always goes first
     
-    BbNode *node = (BbNode*) cfg.getEnterNode();
+    uint32 weight = 0;
+    for (ChainIterator it=chain->begin(); it!=chain->end(); it++) {
+        if ((*it)->isBb() == false) continue;
+        BbNode *node = (BbNode *) *it;
+        weight += node->getExecCounter();
+    }
+    return weight;
+}
 
+//----------------------------------------------------------------------------------------//
+// branch targets have not been set yet. In this method we iterate through each node and 
+// check if it ends with branch (needs branch target)
+
+void CodeLayouter::setBranchTargets() {
+    
+    BbNode *node = (BbNode*) cfg.getEnterNode();
     for(; node != NULL; node = node->getLayoutSucc()) {
 
-        IPF_LOG << "    node" << setw(2) << left << node->getId();
+        IPF_LOG << "    node" << left << setw(3) << node->getId();
         InstVector& insts = node->getInsts();
 
-        // check if last inst is conditional branch
         if(insts.size() != 0) {
-            CompVector& compList = insts.back()->getComps();
-            if(compList.size()>0 && compList[0] == CMPLT_BTYPE_COND) {
-                IPF_LOG << " fix conditional branch" << endl;
-                fixConditionalBranch(node);
+            Inst *lastInst = insts.back();
+
+            if (lastInst->isRet()) {
+                IPF_LOG << " last inst is \"ret\"" << endl;
                 continue;
             }
-        }
-        
-        // check if last inst is ret
-        if(insts.size() != 0) {
-            CompVector& compList = insts.back()->getComps();
-            if(compList.size()>0 && compList[0] == CMPLT_BTYPE_RET) {
-                IPF_LOG << " last inst is \"ret\"" << endl;
+
+            if (lastInst->isConditionalBranch() && lastInst->getComps().size() != 0) {
+                IPF_LOG << " fix conditional branch:";
+                fixConditionalBranch(node);
                 continue;
             }
-        }
-        
-        // check if last inst is switch
-        if(insts.size() !=0) {
-            if(insts.back()->getInstCode() == INST_SWITCH) {
+
+            if(lastInst->getInstCode() == INST_SWITCH) {
                 IPF_LOG << " fix switch" << endl;
                 fixSwitch(node);
                 continue;
             }
         }
-
+        
         // thus, it is unconditional branch
-        IPF_LOG << " fix unconditional branch" << endl;
+        IPF_LOG << " fix unconditional branch:";
         fixUnconditionalBranch(node);
     }
-    cfg.search(SEARCH_UNDEF_ORDER); // it is possible that we have removed some nodes - old search is broken
 }
 
 
 //----------------------------------------------------------------------------------------//
-// (p0)   cmp4.ge     p8, p0 = r32, r2
-// (p8)   br          unknown target
-//
-// Sets branch target accordingly 
+// set conditional branch target 
 
 void CodeLayouter::fixConditionalBranch(BbNode *node) {
     
-    InstVector& insts      = node->getInsts();
-    Inst*       branchInst = insts.back();
-
-    Edge *branchEdge  = node->getOutEdge(EDGE_BRANCH);
-    Edge *throughEdge = node->getOutEdge(EDGE_THROUGH);
+    InstVector &insts       = node->getInsts();
+    Inst       *branchInst  = insts.back();
+    Edge       *branchEdge  = node->getOutEdge(EDGE_BRANCH);
+    Edge       *throughEdge = node->getOutEdge(EDGE_THROUGH);
 
-    IPF_LOG << "        old branch target is node" << branchEdge->getTarget()->getId() << endl;
-    
-    // check if branch edge target coinsides with layout successor
+    // if branch edge target coinsides with layout successor
     if (branchEdge->getTarget() == node->getLayoutSucc()) {
         // swap fall through and branch edges            
         throughEdge->setEdgeKind(EDGE_BRANCH);
         branchEdge->setEdgeKind(EDGE_THROUGH);
-        Edge *tmpEdge=throughEdge;
-        throughEdge=branchEdge; branchEdge=tmpEdge;
+        Edge *tmpEdge = throughEdge;
+        throughEdge = branchEdge; 
+        branchEdge  = tmpEdge;
         
         // swap predicate registers of the "cmp" instruction
-        Inst* cmpInst = *(insts.end() - 2);         // get "cmp" inst
+        Inst* cmpInst = *(insts.end() - 2);         // get "cmp" inst (it must stay right before "br")
         Opnd* p1 = cmpInst->getOpnd(POS_CMP_P1);    // get p1 opnd
         Opnd* p2 = cmpInst->getOpnd(POS_CMP_P2);    // get p2 opnd
         cmpInst->setOpnd(POS_CMP_P1, p2);           // set p2 on p1's position
         cmpInst->setOpnd(POS_CMP_P2, p1);           // set p1 on p2's position
+        
+        IPF_LOG << " branch retargeted,";
     }
 
+    BbNode *branchTargetNode = (BbNode *)branchEdge->getTarget();
+    BbNode *fallThroughNode  = (BbNode *)throughEdge->getTarget();
+    BbNode *layoutSuccNode   = (BbNode *)node->getLayoutSucc();
+
     // Set target for branch instruction
-    NodeRef *targetOpnd = (NodeRef*)branchInst->getOpnd(POS_BR_TARGET);
-    targetOpnd->setNode((BbNode*)branchEdge->getTarget());
+    NodeRef *targetOpnd = (NodeRef *)branchInst->getOpnd(POS_BR_TARGET);
+    targetOpnd->setNode(branchTargetNode);
 
-    IPF_LOG << "        new branch target is node" << branchEdge->getTarget()->getId() << endl;
+    IPF_LOG << " branch target is node" << branchTargetNode->getId() << endl;
     
-    // If through edge target coinsides with layout successor - do nothing
-    BbNode* target=(BbNode*) throughEdge->getTarget();
-    if (target == node->getLayoutSucc()) {
-        IPF_LOG << "        through edge coinsides with layout successor" << endl;
-        return;
-    }
-    IPF_LOG << "        through edge points to" << target->getId() << endl;
+    // if fall through node coinsides with layout successor - noting more to do
+    if (fallThroughNode == layoutSuccNode) return;
+    
+    // create new node for unconditional branch on through edge target node
+    BbNode *branchNode = new(mm) BbNode(cfg.getNextNodeId(), fallThroughNode->getExecCounter());
+    branchNode->setLayoutSucc(layoutSuccNode); // layout successor of current node becomes layoute successor of new node
+    node->setLayoutSucc(branchNode);           // the new node becomes layout successor of current node
 
-    // add intermediate basic block for unconditional branch
-    BbNode *intNode = new(mm) BbNode(cfg.getNextNodeId(), 0xFFFF);  //-1?TBD
-    IPF_LOG << "        generate intermediate node" << intNode->getId() << endl;
-    intNode->setLayoutSucc(node->getLayoutSucc());
-    node->setLayoutSucc(intNode);
-//    nodes.push_back(intNode);
-    throughEdge->connect(intNode);
-     Edge *intEdge = new(mm) Edge(intNode, target, throughEdge->getProb(), EDGE_BRANCH);
-    cfg.addEdge(intEdge);
-    cfg.search(SEARCH_UNDEF_ORDER); // old search is broken
- 
-     // Add branch instruction
-    OpndManager*  opndManager = cfg.getOpndManager();
-    Opnd*    p0         = opndManager->getP0();
-    NodeRef* targetNodeRef = opndManager->newNodeRef(target);
-    intNode->addInst(new(mm) Inst(INST_BR, p0, targetNodeRef));  
+    throughEdge->changeTarget(branchNode);     // retarget trough edge on the new node
+    Edge *edge = new(mm) Edge(branchNode, fallThroughNode, throughEdge->getProb(), EDGE_THROUGH);
+    edge->insert();                            // new edge connects the new node and fall through node
+
+    IPF_LOG << ", through node generated: node" << branchNode->getId() << endl;
+    cfg.search(SEARCH_UNDEF_ORDER);            // old search is broken
 }
     
 //----------------------------------------------------------------------------------------//
@@ -336,7 +395,7 @@
     Inst* lastInst = node->getInsts().back();
 
     // Find edge corresponding to layout successor and mark it fall through
-    Edge *throughEdge = node->getOutEdge((Node*) node->getLayoutSucc());
+    Edge *throughEdge = node->getOutEdge(node->getLayoutSucc());
     throughEdge->setEdgeKind(EDGE_THROUGH);
     
     Opnd           *troughTargetImm   =                   lastInst->getOpnd(POS_SWITCH_THROUGH);
@@ -360,25 +419,27 @@
 
 void CodeLayouter::fixUnconditionalBranch(BbNode *node) {
     
-    Edge* throughEdge = node->getOutEdge(EDGE_THROUGH);
-    if(throughEdge == NULL) { // there is no through edge - nothing to do
-        IPF_LOG << "        there is no through edge" << endl;
+    // if there is no through edge - do nothing
+    Edge *throughEdge = node->getOutEdge(EDGE_THROUGH);
+    if(throughEdge == NULL) { 
+        IPF_LOG << " there is no through edge - ignore" << endl;
         return; 
     }
 
-    // If through edge target coinsides with layout successor - do nothing
-    BbNode* target=(BbNode*) throughEdge->getTarget();
-    if (target == (Node*) node->getLayoutSucc()) {
-        IPF_LOG << "        through edge coinsides with layout successor" << endl;
+    // if through edge target coinsides with layout successor - do nothing
+    BbNode *target = (BbNode *)throughEdge->getTarget();
+    if (target == node->getLayoutSucc()) {
+        IPF_LOG << " through edge coinsides with layout successor - ignore" << endl;
         return;
     }
 
     // Add branch to through edge target
-    Opnd*    p0         = cfg.getOpndManager()->getP0();
-    NodeRef* targetNode = cfg.getOpndManager()->newNodeRef(target);
-    node->addInst(new(mm) Inst(INST_BR, p0, targetNode));
+    Opnd    *p0         = cfg.getOpndManager()->getP0();
+    NodeRef *targetNode = cfg.getOpndManager()->newNodeRef(target);
+    node->addInst(new(mm) Inst(INST_BR, CMPLT_BTYPE_COND, p0, targetNode));
     
     throughEdge->setEdgeKind(EDGE_BRANCH);
+    IPF_LOG << " branch on node" << target->getId() << " added" << endl;
 }
     
 } // IPF

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfEmitter.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfEmitter.cpp?view=diff&rev=469924&r1=469923&r2=469924
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfEmitter.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfEmitter.cpp Wed Nov  1 06:55:45 2006
@@ -14,7 +14,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-
+                                                                                                            
 /**
  * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin
  * @version $Revision$
@@ -70,26 +70,6 @@
 namespace Jitrino {
 namespace IPF {
 
-vector<char *> ipfCompileMethodList;
-vector<char *> ipfNotCompileMethodList;
-vector<char *> ipfBreakMethodList;
-vector<int>    ipfBreakBbList;
-vector<char *> ipfLogoutMethodList;
-bool           ipfEnableSigillBreakActionHandler = false;
-bool           ipfEnableAutoSigillBreak = false;
-bool           ipfSigillBreakAllBB = false;
-bool           ipfNotifyWhenMethodIsRecompiled = true;
-bool           ipfCompileAllMethods = true;
-int            ipfSigillBreakCount = 0;
-bool           ipfLogoutAllMethods = false;
-bool           __IPF_ONLY__ = false;
-
-bool isIpfCompiled(MethodDesc* method) { return false; }
-bool isIpfMethod(MethodDesc* method) { return false; }
-bool isIpfBreakBb(unsigned int nodeid) { return false; }
-bool isIpfBreakMethod(MethodDesc* method, bool recompile) { return false; }
-bool isIpfLogoutMethod(MethodDesc* method) { return false; }
-
 //============================================================================//
 
 Bundle::Bundle(Cfg& cfg, uint32 itmp, Inst *i0, Inst *i1, Inst *i2) {
@@ -256,7 +236,7 @@
 
 //============================================================================//
 EmitterBb::EmitterBb(Cfg & cfg, CompilationInterface & compilationinterface
-        , BbNode  * node_, bool _setbreak) : 
+        , BbNode  * node_, bool _break4cafe, bool _nop4cafe) : 
     node(node_), 
     insts(node->getInsts())
 {
@@ -272,13 +252,13 @@
     consts=new(mm) vectorconst;
     bsize=0;
 
-//    if (__IPF_ONLY__) return; TODO
-    if (!_setbreak) {
-        bundles->addBundle(0x01
-            , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))
-            , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))
-            , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)));
-        return;
+    if (!_break4cafe) {
+        if (_nop4cafe) {
+            bundles->addBundle(0x01
+                , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))
+                , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))
+                , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)));
+        }
     } else {
 #ifdef SIGILL_BREAK_ACTION_HANDLER
         if (ipfEnableSigillBreakActionHandler) {
@@ -295,22 +275,61 @@
                 , new(mm) Inst(INST_BREAK, p0, IMM(INST_BREAKPOINT_IMM_VALUE))
                 , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)));
         } else {
+            if (_nop4cafe) {
+                bundles->addBundle(0x01
+                    , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))
+                    , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))
+                    , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)));
+            }
+        }
+#else
+        if (_nop4cafe) {
             bundles->addBundle(0x01
                 , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))
                 , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))
                 , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)));
         }
-#else
-        bundles->addBundle(0x01
-            , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))
-            , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE))
-            , new(mm) Inst(INST_NOP, p0, IMM(INST_BREAKPOINT_IMM_VALUE)));
 #endif
     }
 
 };
 
 //============================================================================//
+Emitter::Emitter(Cfg & cfg_, CompilationInterface & compilationinterface_) : 
+        mm(cfg_.getMM()),
+        cfg(cfg_),
+        compilationinterface(compilationinterface_)
+    {
+
+    removeUselessInst(cfg, compilationinterface);
+    
+    (new(mm) IpfVerifier(cfg, compilationinterface))->verifyMethod();
+
+    bbs = new(mm) vectorbb;
+    BbNode  * node = (BbNode *)cfg.getEnterNode();
+    EmitterBb * bbdesc;
+    bool break4cafe = ipfEnableSigillBreakActionHandler 
+                && (ipfEnableAutoSigillBreak
+                    || isIpfBreakMethod(compilationinterface.getMethodToCompile()));
+    bool nop4cafe = true;
+
+    do {
+        // for debugging
+        // tricking(node->getInsts(), mm, cfg);
+        
+        if (isIpfBreakBb(node->getId())) {
+            bbdesc = new(mm) EmitterBb(cfg, compilationinterface, node, true, nop4cafe);
+        } else {
+            bbdesc = new(mm) EmitterBb(cfg, compilationinterface, node, break4cafe, nop4cafe);
+        }
+        bbs->push_back(bbdesc);
+        if (!ipfSigillBreakAllBB) break4cafe = false;
+        nop4cafe = false;
+    } while( (node = node->getLayoutSucc()) != NULL );
+    
+};
+
+//============================================================================//
 int  Emitter::removeUselessInst(Cfg & cfg, CompilationInterface & compilationinterface) {
     BbNode  * node = (BbNode *)cfg.getEnterNode();
     int methoduseless = 0;
@@ -329,7 +348,7 @@
                     OpndVector &opnds = inst->getOpnds();
                     if (opnds[1]->isReg() && opnds[2]->isReg() 
                             && opnds[1]->getValue()==opnds[2]->getValue()) {
-                        LOG_OUT << "USELESS: " << IrPrinter::toString(inst) << "\n";
+                        IPF_LOG << "USELESS: " << IrPrinter::toString(inst) << "\n";
                         insts.erase(insts.begin() + i);
                         methoduseless++;
                         continue;
@@ -342,7 +361,7 @@
                     OpndVector &opnds = inst->getOpnds();
                     if (opnds[2]->getValue()==0
                             && opnds[1]->getValue()==opnds[3]->getValue()) {
-                        LOG_OUT << "USELESS: " << IrPrinter::toString(inst) << "\n";
+                        IPF_LOG << "USELESS: " << IrPrinter::toString(inst) << "\n";
                         insts.erase(insts.begin() + i);
                         methoduseless++;
                         continue;
@@ -358,55 +377,20 @@
         static int alluseless = 0;
         static int allafter = 0;
         alluseless += methoduseless;
-        clog << "USELESS: method: " << methoduseless 
+        IPF_LOG << "USELESS: method: " << methoduseless 
             << "(" << (((float)methoduseless)/(methoduseless + methodafter)) << "%) instructions\n";
-        clog << "USELESS: all: " << alluseless 
+        IPF_LOG << "USELESS: all: " << alluseless 
             << "(" << (((float)alluseless)/(alluseless + allafter)) << "%) instructions\n";
     }
 
     if (methoduseless > 0) {
-        LOG_OUT << "USELESS: removed " << methoduseless 
+        IPF_LOG << "USELESS: removed " << methoduseless 
             << "(" << (((float)methoduseless)/(methoduseless + methodafter)) << "%) instructions\n";
     }
     return methoduseless;
 }
 
 //============================================================================//
-Emitter::Emitter(Cfg & cfg_, CompilationInterface & compilationinterface_
-        , bool break4cafe_) : 
-    mm(cfg_.getMM()),
-    cfg(cfg_),
-    compilationinterface(compilationinterface_),
-    break4cafe(break4cafe_) {
-
-    removeUselessInst(cfg, compilationinterface);
-    
-    (new(mm) IpfVerifier(cfg, compilationinterface))->verifyMethod();
-
-    bbs = new(mm) vectorbb;
-    BbNode  * node = (BbNode *)cfg.getEnterNode();
-    EmitterBb * bbdesc;
-    bool setbreak = ipfEnableAutoSigillBreak
-                    || isIpfBreakMethod(compilationinterface.getMethodToCompile());
-
-    if (break4cafe_) setbreak = true;
-    
-    do {
-        // for debugging
-        // tricking(node->getInsts(), mm, cfg);
-        
-        if (isIpfBreakBb(node->getId())) {
-            bbdesc = new(mm) EmitterBb(cfg, compilationinterface, node, true);
-        } else {
-            bbdesc = new(mm) EmitterBb(cfg, compilationinterface, node, setbreak);
-        }
-        bbs->push_back(bbdesc);
-        if (!ipfSigillBreakAllBB) setbreak = false;
-    } while( (node = node->getLayoutSucc()) != NULL );
-    
-};
-
-//============================================================================//
 InstructionType Emitter::getExecUnitType(int templateindex, int slotindex) {
     return (InstructionType)((Emitter::BundleDesc[templateindex].slots >> (slotindex * 8)) & 0xFF);
 }
@@ -1167,8 +1151,6 @@
 
 void Emitter::registerDirectCall(Inst * inst, uint64 data)
 {
-    if (!ipfNotifyWhenMethodIsRecompiled) return;
-    
     InstCode     icode  = inst->getInstCode();
     unsigned int is13 = (icode==INST_BRL13 ? 1 : 0);  // must be 1 or 0
     

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfInst.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfInst.cpp?view=diff&rev=469924&r1=469923&r2=469924
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfInst.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfInst.cpp Wed Nov  1 06:55:45 2006
@@ -14,7 +14,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-
+                                                                                                            
 /**
  * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin
  * @version $Revision$
@@ -87,6 +87,43 @@
     if(op4 != NULL) opndList.push_back(op4);
     if(op5 != NULL) opndList.push_back(op5);
     if(op6 != NULL) opndList.push_back(op6);
+}
+
+//----------------------------------------------------------------------------------------//
+
+bool Inst::isBr() {
+    if (instCode == INST_BR)    return true;
+    if (instCode == INST_BRL)   return true;
+    if (instCode == INST_BR13)  return true;
+    if (instCode == INST_BRL13) return true;
+    return false;
+}
+
+//----------------------------------------------------------------------------------------//
+
+bool Inst::isCall() {
+    if (isBr() == false)                 return false;
+    if (compList.size() == 0)            return false;
+    if (compList[0] == CMPLT_BTYPE_CALL) return true;
+    return false;
+}
+
+//----------------------------------------------------------------------------------------//
+
+bool Inst::isRet() {
+    if (isBr() == false)                return false;
+    if (compList.size() == 0)           return false;
+    if (compList[0] == CMPLT_BTYPE_RET) return true;
+    return false;
+}
+
+//----------------------------------------------------------------------------------------//
+
+bool Inst::isConditionalBranch() {
+    if (isBr() == false)                 return false;
+    if (compList.size() == 0)            return true;
+    if (compList[0] == CMPLT_BTYPE_COND) return true;
+    return false;
 }
 
 } // IPF

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfIrPrinter.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfIrPrinter.cpp?view=diff&rev=469924&r1=469923&r2=469924
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfIrPrinter.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfIrPrinter.cpp Wed Nov  1 06:55:45 2006
@@ -14,7 +14,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-
+                                                                                                            
 /**
  * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin
  * @version $Revision$
@@ -389,6 +389,19 @@
     return oss.str();
 }
 
+//----------------------------------------------------------------------------------------//
+
+string IrPrinter::toString(Chain &chain) {
+
+    ostringstream oss;
+    for(ChainIterator i=chain.begin(); i!=chain.end();) {
+        oss << "node" << (*i)->getId();
+        i++;
+        if (i!=chain.end()) oss << "->";
+    }
+    return oss.str();
+}
+    
 //----------------------------------------------------------------------------------------//
 
 string IrPrinter::toString(NodeKind nodeKind) {

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfRegisterAllocator.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfRegisterAllocator.cpp?view=diff&rev=469924&r1=469923&r2=469924
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfRegisterAllocator.cpp (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/IpfRegisterAllocator.cpp Wed Nov  1 06:55:45 2006
@@ -14,7 +14,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-
+                                                                                                            
 /**
  * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin
  * @version $Revision$
@@ -171,7 +171,8 @@
         RegOpnd *opnd = opndVector[i];
         IPF_LOG << "      " << left << setw(5) << IrPrinter::toString(opnd); 
         opndManager->assignLocation(opnd);  // assign location for current opnd
-        IPF_LOG << " after assignment " << IrPrinter::toString(opnd) << endl; 
+        IPF_LOG << " after assignment " << left << setw(5) << IrPrinter::toString(opnd);
+        IPF_LOG << " spill cost: " << opnd->getSpillCost() << endl; 
         
         if (opnd->isMem()) continue;        // if opnd assigned on stack - nothing more to do 
         

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfCfg.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfCfg.h?view=diff&rev=469924&r1=469923&r2=469924
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfCfg.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfCfg.h Wed Nov  1 06:55:45 2006
@@ -14,7 +14,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-
+                                                                                                            
 /**
  * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin
  * @version $Revision$
@@ -271,24 +271,27 @@
     CompVector  &getComps()                          { return compList; }
     Completer   getComp(uint16 num)                  { return compList[num]; }
     void        addComp(Completer comp_)             { compList.push_back(comp_); }
-    void        removeLastComp()                     { compList.pop_back(); }
     void        setComp(uint32 num, Completer comp_) { compList[num] = comp_; }
 
     void        addOpnd(Opnd *opnd_)                 { opndList.push_back(opnd_); }
     void        removeLastOpnd()                     { opndList.pop_back(); }
-    OpndVector &getOpnds()                           { return opndList; }
+    OpndVector  &getOpnds()                          { return opndList; }
     void        setOpnd(uint32 num, Opnd *opnd_)     { opndList[num] = opnd_; }
     Opnd        *getOpnd(uint32 num)                 { return opndList[num]; }
-    char        *getInstMnemonic()                   { return Encoder::getMnemonic(instCode); }
-
-    char        *getCompMnemonic(Completer comp)     { return Encoder::getMnemonic(comp); }
     uint16      getNumDst()                          { return Encoder::getNumDst(instCode); }
     uint16      getNumOpnd()                         { return Encoder::getNumOpnd(instCode); }
-    Inst&       set_qp(Opnd *p1)                     { setOpnd(0, p1); return *this; }
+
+    char        *getInstMnemonic()                   { return Encoder::getMnemonic(instCode); }
+    char        *getCompMnemonic(Completer comp)     { return Encoder::getMnemonic(comp); }
 
     uint32      getAddr()                            { return addr; }
     void        setAddr(uint32 addr_)                { addr = addr_; }
     
+    bool        isBr();
+    bool        isCall();
+    bool        isRet();
+    bool        isConditionalBranch();
+    
 protected:
     InstCode    instCode;
     CompVector  compList;
@@ -302,16 +305,17 @@
 
 class Edge {
 public:
-                Edge(Node *source_, Node *target_, double prob_);
                 Edge(Node *source_, Node *target_, double prob_, EdgeKind kind_);
-    void        setSource(Node *source_)    { source = source_; }
     Node        *getSource()                { return source; }
-    void        setTarget(Node *target_)    { target = target_; }
     Node        *getTarget()                { return target; }
     double      getProb()                   { return prob; }
     void        setProb(double prob_)       { prob = prob_; }
     EdgeKind    getEdgeKind()               { return edgeKind; }
     void        setEdgeKind(EdgeKind kind_) { edgeKind = kind_; }
+    void        remove();
+    void        insert();
+    void        changeSource(Node *source_);
+    void        changeTarget(Node *target_);
     bool        isBackEdge();
     void        connect(Node *target);
     void        disconnect();
@@ -346,6 +350,7 @@
 public:
                 Node(uint32 id_, NodeKind kind_ = NODE_INVALID);
 
+    void        remove();
     void        addEdge(Edge *edge);
     void        removeEdge(Edge *edge);
     Edge        *getOutEdge(EdgeKind edgeKind);
@@ -355,14 +360,14 @@
     Node        *getDispatchNode();
     void        mergeOutLiveSets(RegOpndSet &resultSet);
 
-    EdgeVector &getInEdges()                     { return inEdges; }
-    EdgeVector &getOutEdges()                    { return outEdges; }
+    EdgeVector  &getInEdges()                    { return inEdges; }
+    EdgeVector  &getOutEdges()                   { return outEdges; }
     void        setNodeKind(NodeKind kind_)      { nodeKind = kind_; }
     NodeKind    getNodeKind()                    { return nodeKind; }
     void        setId(uint32 id_)                { id = id_; }
     uint32      getId()                          { return id; }
     void        setLiveSet(RegOpndSet& liveSet_) { liveSet = liveSet_; }
-    RegOpndSet &getLiveSet()                     { return liveSet; }
+    RegOpndSet  &getLiveSet()                    { return liveSet; }
     void        clearLiveSet()                   { liveSet.clear(); }
     void        setLoopHeader(Node *loopHeader_) { loopHeader = loopHeader_; }
     Node        *getLoopHeader()                 { return loopHeader; }
@@ -387,8 +392,7 @@
 
 class BbNode : public Node {
 public:
-                BbNode(uint32 execCounter_);
-                BbNode(uint32 execCounter_, uint32 id_);
+                BbNode(uint32 id_, uint32 execCounter_);
     void        addInst(Inst *inst); 
     void        removeInst(Inst *inst)              { insts.erase(find(insts.begin(),insts.end(),inst)); } 
     InstVector  &getInsts()                         { return insts; }
@@ -413,38 +417,34 @@
 
 class Cfg {
 public:
-                   Cfg(MemoryManager &mm, CompilationInterface &compilationInterface);
-    void           addEdge(Edge *edge);
-    void           removeEdge(Edge *edge);
-    void           removeNode(Node *node);
-    NodeVector     &search(SearchKind searchKind);
+                         Cfg(MemoryManager &mm, CompilationInterface &compilationInterface);
+    NodeVector           &search(SearchKind searchKind);
     
-    MemoryManager  &getMM()                       { return mm; }
-    void           setEnterNode(Node *enterNode_) { enterNode = enterNode_; }
-    Node           *getEnterNode()                { return enterNode; }
-    void           setExitNode(Node *exitNode_)   { exitNode = exitNode_; }
-    Node           *getExitNode()                 { return exitNode; }
-    OpndManager    *getOpndManager()              { return opndManager; }
-    uint16         getNextNodeId()                { return maxNodeId++; }
-    uint16         getMaxNodeId()                 { return maxNodeId; }
-    MethodDesc     *getMethodDesc()               { return compilationInterface.getMethodToCompile(); }
-    void           addArg(Opnd *opnd_)            { argList.push_back(opnd_); }
-    OpndVector     &getArgs()                     { return argList; }    
-protected:
-    void           makePostOrdered(Node *node, NodeSet &visitedNodes);
-    void           makeDirectOrdered(Node *node, NodeSet &visitedNodesd);
-    void           makeLayoutOrdered();
+    MemoryManager        &getMM()                       { return mm; }
+    CompilationInterface &getCompilationInterface()     { return compilationInterface; }
+    uint16               getNextNodeId()                { return maxNodeId++; }
+    uint16               getMaxNodeId()                 { return maxNodeId; }
+    void                 setEnterNode(Node *enterNode_) { enterNode = enterNode_; }
+    void                 setExitNode(Node *exitNode_)   { exitNode = exitNode_; }
+    Node                 *getEnterNode()                { return enterNode; }
+    Node                 *getExitNode()                 { return exitNode; }
+    OpndManager          *getOpndManager()              { return opndManager; }
+    MethodDesc           *getMethodDesc()               { return compilationInterface.getMethodToCompile(); }
+
+protected:
+    void                 makePostOrdered(Node *node, NodeSet &visitedNodes);
+    void                 makeDirectOrdered(Node *node, NodeSet &visitedNodesd);
+    void                 makeLayoutOrdered();
 
     MemoryManager        &mm;
     CompilationInterface &compilationInterface;
 
-    Node           *enterNode;
-    Node           *exitNode;
-    NodeVector     searchResult;
-    SearchKind     lastSearchKind;
-    OpndManager    *opndManager;
-    uint16         maxNodeId;
-    OpndVector     argList;
+    uint16               maxNodeId;
+    OpndManager          *opndManager;
+    Node                 *enterNode;
+    Node                 *exitNode;
+    NodeVector           searchResult;
+    SearchKind           lastSearchKind;
 };
 
 } // IPF

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfCodeLayouter.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfCodeLayouter.h?view=diff&rev=469924&r1=469923&r2=469924
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfCodeLayouter.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfCodeLayouter.h Wed Nov  1 06:55:45 2006
@@ -14,7 +14,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-
+                                                                                                            
 /**
  * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin
  * @version $Revision$
@@ -30,12 +30,6 @@
 namespace IPF {
 
 //========================================================================================//
-// Typedefs
-//========================================================================================//
-
-typedef vector< NodeVector* > ChainVector;
-
-//========================================================================================//
 // CodeLayouter
 //========================================================================================//
 
@@ -45,17 +39,31 @@
     void          layout();
 
 protected:
+    // merge sequential nodes
     void          mergeNodes();
-    bool          mergeNode(BbNode *pred, Edge *pred2succ);
+    BbNode*       getSucc(BbNode*);
+    bool          checkSucc(BbNode*);
+    void          merge(BbNode*, BbNode*);
+    void          checkUnwind();
+
+    // layout nodes
     void          makeChains();
-    void          fixBranches();
-    void          fixConditionalBranch(BbNode *node);
-    void          fixSwitch(BbNode *node);
-    void          fixUnconditionalBranch(BbNode *node);
+    void          inChainList(Edge*);
+    void          pushBack(Chain*, Node*);
+    void          pushFront(Chain*, Node*);
+    void          layoutNodes();
+    uint32        calculateChainWeight(Chain*);
+
+    // set branch targets
+    void          setBranchTargets();
+    void          fixConditionalBranch(BbNode*);
+    void          fixSwitch(BbNode*);
+    void          fixUnconditionalBranch(BbNode*);
     
     MemoryManager &mm;
     Cfg           &cfg;
-    ChainVector   chains;
+    ChainList     chains;
+    NodeSet       visitedNodes;
 };
 
 } // IPF

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfEmitter.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfEmitter.h?view=diff&rev=469924&r1=469923&r2=469924
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfEmitter.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfEmitter.h Wed Nov  1 06:55:45 2006
@@ -14,7 +14,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-
+                                                                                                            
 /**
  * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin
  * @version $Revision$
@@ -165,9 +165,9 @@
 class EmitterBb {
   public:
     EmitterBb(Cfg & cfg_, CompilationInterface & compilationinterface_
-            , BbNode  * node_, bool _setbreak=false);
+            , BbNode  * node_, bool _break4cafe=false, bool _nop4cafe=false);
     
-    BbNode    * node;
+    BbNode       * node;
     InstVector   & insts;
     long           isize;
     vectorbool   * stops;
@@ -189,8 +189,7 @@
 
 class Emitter {
   public:
-    Emitter(Cfg & cfg_, CompilationInterface & compilationinterface_
-        , bool break4cafe_=false);
+    Emitter(Cfg & cfg_, CompilationInterface & compilationinterface_);
 
     bool emit();
     void printInsts(char *);
@@ -228,7 +227,6 @@
     MemoryManager& mm;
     Cfg      & cfg;
     CompilationInterface & compilationinterface;
-    bool       break4cafe;
     vectorbb * bbs;
     char *     dataoff;
     long       datasize;  // full size of data block

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfIrPrinter.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfIrPrinter.h?view=diff&rev=469924&r1=469923&r2=469924
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfIrPrinter.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfIrPrinter.h Wed Nov  1 06:55:45 2006
@@ -14,7 +14,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-
+                                                                                                            
 /**
  * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin
  * @version $Revision$
@@ -50,6 +50,7 @@
     static string  toString(OpndVector&);
     static string  toString(InstVector&);
     static string  toString(InstList&);
+    static string  toString(Chain&);
     static string  toString(NodeKind);
     static string  toString(EdgeKind);
     static string  toString(OpndKind);

Modified: incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfType.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfType.h?view=diff&rev=469924&r1=469923&r2=469924
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfType.h (original)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ipf/include/IpfType.h Wed Nov  1 06:55:45 2006
@@ -14,7 +14,7 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-
+                                                                                                            
 /**
  * @author Intel, Konstantin M. Anisimov, Igor V. Chebykin
  * @version $Revision$
@@ -43,22 +43,6 @@
 namespace Jitrino {
 namespace IPF {
 
-// TODO
-#define IpfCOUT std::cerr
-extern bool isIpfCompiled(MethodDesc* method);
-extern bool isIpfMethod(MethodDesc* method);
-extern bool isIpfBreakBb(unsigned int nodeid);
-extern bool isIpfBreakMethod(MethodDesc* method, bool recompile=false);
-extern bool isIpfLogoutMethod(MethodDesc* method);
-extern bool ipfEnableSigillBreakActionHandler;
-extern bool ipfEnableAutoSigillBreak;
-extern bool ipfSigillBreakAllBB;
-extern bool ipfNotifyWhenMethodIsRecompiled;
-extern bool ipfCompileAllMethods;
-extern int  ipfSigillBreakCount;
-extern bool ipfLogoutAllMethods;
-extern bool __IPF_ONLY__;
-
 //========================================================================================//
 // Forward declaration
 //========================================================================================//
@@ -120,10 +104,8 @@
 #define ROOT_SET_HEADER_SIZE    4   // header size in root set info block
 #define SAFE_POINT_HEADER_SIZE 12   // header size in safe points info block
 
-//#define LOG_ON                ipfLogIsOn      // Log for Code Generator is on
-//#define VERIFY_ON             ipfVerifyIsOn   // verification for Code Generator is on
-#define LOG_ON                1      // Log for Code Generator is on
-#define VERIFY_ON             1     // verification for Code Generator is on
+#define LOG_ON                ipfLogIsOn      // Log for Code Generator is on
+#define VERIFY_ON             ipfVerifyIsOn   // verification for Code Generator is on
 #define LOG_OUT               Log::out()
 #define STAT_ON               0               // Log for statistic
 
@@ -219,6 +201,8 @@
 typedef vector< Edge* >                 EdgeVector;
 typedef vector< uint32 >                Uint32Vector;
 typedef list< Inst* >                   InstList;
+typedef list< Node* >                   NodeList;
+typedef list< Edge* >                   EdgeList;
 typedef set< Opnd* >                    OpndSet;
 typedef set< RegOpnd* >                 RegOpndSet;
 typedef set< Node* >                    NodeSet;
@@ -229,11 +213,21 @@
 typedef NodeVector::iterator            NodeIterator;
 typedef InstVector::iterator            InstIterator;
 typedef OpndVector::iterator            OpndIterator;
+typedef EdgeVector::iterator            EdgeIterator;
 typedef OpndSet::iterator               OpndSetIterator;
 typedef RegOpndSet::iterator            RegOpndSetIterator;
 typedef InstList::iterator              InstListIterator;
+typedef NodeList::iterator              NodeListIterator;
+typedef EdgeList::iterator              EdgeListIterator;
 typedef Inst2RegOpndSetMap::iterator    Inst2RegOpndSetMapIterator;
 typedef Uint642RegOpndSetMap::iterator  Uint642RegOpndSetMapIterator;
+
+typedef NodeList                        Chain;
+typedef list< Chain* >                  ChainList;
+typedef multimap< uint32, Chain*, greater < uint32 > > ChainMap;
+typedef Chain::iterator                 ChainIterator;
+typedef ChainList::iterator             ChainListIterator;
+typedef ChainMap::iterator              ChainMapIterator;
 
 //========================================================================================//
 // IpfType



Mime
View raw message