You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by mf...@apache.org on 2007/10/16 14:03:18 UTC

svn commit: r585128 - in /harmony/enhanced/drlvm/trunk/vm/jitrino/src: optimizer/FlowGraph.cpp shared/LoopTree.cpp translator/java/JavaFlowGraphBuilder.cpp translator/java/JavaFlowGraphBuilder.h translator/java/JavaLabelPrepass.cpp

Author: mfursov
Date: Tue Oct 16 05:03:11 2007
New Revision: 585128

URL: http://svn.apache.org/viewvc?rev=585128&view=rev
Log:
Fix for HARMONY-4948 [drlvm][jit] Avoid generation of IR with dispatch nodes as loop headers
 

Modified:
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/LoopTree.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaFlowGraphBuilder.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaFlowGraphBuilder.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.cpp

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.cpp?rev=585128&r1=585127&r2=585128&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.cpp Tue Oct 16 05:03:11 2007
@@ -348,57 +348,6 @@
     }
 }
 
-
-
-
-static void breakMonitorExitLoop(ControlFlowGraph& fg, Node* node, Inst* monExit) {
-
-    // Look for the following type of loop where a handler with a 
-    // monitorexit handles itself.  
-    // D1:
-    // 
-    // B1:
-    //   t1 = catch
-    //   ...
-    //
-    // B2:
-    //   monitorExit t2 ---> D1
-    assert(node->getLastInst() == monExit);
-    assert(monExit->getOpcode() == Op_TauMonitorExit);
-
-    Node* dispatch =  node->getExceptionEdge()->getTargetNode();
-    Node* catchBlock = node;
-    std::vector<Edge*> exceptionEdges;
-    exceptionEdges.push_back(node->getExceptionEdge());
-
-    // Look for a catchBlock that dominates the node.  Assume no control flow.
-    while(!((Inst*)catchBlock->getFirstInst())->isCatchLabel() && catchBlock->getInEdges().size() == 1) {
-        catchBlock = catchBlock->getInEdges().front()->getSourceNode();
-        Edge* exceptionEdge = catchBlock->getExceptionEdge();
-        if(exceptionEdge == NULL || exceptionEdge->getTargetNode() != dispatch)
-            return;
-        exceptionEdges.push_back(exceptionEdge);
-    }
-
-    if(((Inst*)catchBlock->getFirstInst())->isCatchLabel()) {
-        // We are in a catch.
-        if(dispatch->findTargetEdge(catchBlock)) {
-            // We have a cycle!
-            Node* newDispatch =  dispatch->getExceptionEdge()->getTargetNode();
-            assert(newDispatch != NULL);
-
-            std::vector<Edge*>::iterator i;
-            for(i = exceptionEdges.begin(); i != exceptionEdges.end(); ++i) {
-                Edge* exceptionEdge = *i;
-                assert(exceptionEdge->getTargetNode() == dispatch);
-                fg.replaceEdgeTarget(exceptionEdge, newDispatch);
-            }
-        }
-    }
-}
-
-
-
 //
 // used to find 'saveret' that starts the node
 //     'labelinst' and 'stvar' are skipped
@@ -847,10 +796,17 @@
     InstFactory& instFactory = irm.getInstFactory();
     OpndManager& opndManager = irm.getOpndManager();
 
+
     static CountTime cleanupPhaseTimer("ptra::fg::cleanupPhase");
     AutoTimer tm(cleanupPhaseTimer);
     fg.purgeUnreachableNodes();
 
+#ifdef _DEBUG
+    //check if loop structure is valid after translator
+    OptPass::computeLoops(irm, false);
+#endif
+
+
     inlineJSRs(&irm);
     fg.purgeUnreachableNodes();
 
@@ -866,11 +822,7 @@
                 continue;
             }
             Inst *last = (Inst*)node->getLastInst();
-            if (last->getOpcode() == Op_TauMonitorExit) {
-                // Check for monitor exit loop.  
-                breakMonitorExitLoop(fg, node, last);
-            }
-            else if (last->isBranch()) {
+            if (last->isBranch()) {
                 if (last->isLeave()) {
                     // Inline Finally - only necessary after translation
                     inlineFinally(irm, node);

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/LoopTree.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/LoopTree.cpp?rev=585128&r1=585127&r2=585128&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/LoopTree.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/LoopTree.cpp Tue Oct 16 05:03:11 2007
@@ -50,6 +50,7 @@
         for(eiter = edges.begin(); eiter != edges.end(); ++eiter) {
             Node* pred = (*eiter)->getSourceNode();
             if (dom->dominates(n, pred)) {
+                assert(n->isBlockNode());
                 headers.push_back(n);
                 break;
             }

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaFlowGraphBuilder.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaFlowGraphBuilder.cpp?rev=585128&r1=585127&r2=585128&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaFlowGraphBuilder.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaFlowGraphBuilder.cpp Tue Oct 16 05:03:11 2007
@@ -273,186 +273,8 @@
     // second phase: construct edges
     //
     createCFGEdges();
-
-    eliminateUnnestedLoopsOnDispatch();
-}
-
-
-//
-//   look for edge patterns like this:
-//
-//      D C
-//      C S
-//      S has >1 in-edges
-//      D has >1 in-edges
-//
-//      S  -- start node (sycle header)
-//      D  -- dispatch node
-//      C  -- catch node
-//
-//   and this:
-//
-//      S  ME
-//      ME D
-//      S  D
-//      D  C
-//      C  S
-//      S has >1 in-edges
-//      D has >2 in-edges
-//
-//      S  -- start node (sycle header)
-//      D  -- dispatch node
-//      C  -- catch node
-//      ME -- node with last instruction: 'monitorexit'
-//
-//   when found,
-//      for each in-node of D (except 1st) do
-//         duplicate D -> D2, 
-//         retarget the in-node to D2
-//         for all nodes (Cx) following D
-//           if catch node 
-//             duplicate Cx -> Cy
-//             add edge 'D2 Cy'
-//             add edge 'Cy succ(Cx)' // assertion failure if many succsessors
-//           else
-//             add edge 'D2 Cx'
-//
-void JavaFlowGraphBuilder::eliminateUnnestedLoopsOnDispatch()
-{
-    MemoryManager matched_nodes_mm("unnested_loops_mm");
-    Nodes matched_dispatches(matched_nodes_mm);
-    bool found_goto_into_loop_warning = false;
-    const Nodes& nodes = fg->getNodes();
-    Nodes::const_iterator niter;
-    for (niter = nodes.begin(); niter != nodes.end(); ++niter) {
-        Node* dispatch = *niter;
-        if ( dispatch->isDispatchNode() && dispatch->getInDegree() > 1 ) {
-            const Edges& out_edges =  dispatch->getOutEdges();
-            for (Edges::const_iterator out_iter = out_edges.begin();
-                out_iter != out_edges.end();
-                out_iter++) {
-
-                Node* catch_node = (*out_iter)->getTargetNode();
-                if ( !catch_node->isCatchBlock() ) {
-                    continue;
-                }
-                Node* catch_target = (*(catch_node->getOutEdges().begin()))->getTargetNode();
-                if ( catch_target->getInDegree() <= 1 ) {
-                    continue;
-                }
-                bool found_monitorexit = false;
-                bool dispatch_is_after_target = false;
-                bool monitorexit_after_catch_target = false;
-                bool monitorexit_after_catch = false;
-                // number of edges leading 
-                //   from within the searched loop to the current dispatch
-                uint32 eins_from_loop = 0;
-                const Edges& in_edges = dispatch->getInEdges();
-                for (Edges::const_iterator in_iter = in_edges.begin();
-                     in_iter != in_edges.end();
-                     in_iter++) {
-                    Node* pre_dispatch = (*in_iter)->getSourceNode();
-                    if ( pre_dispatch == catch_target ) {
-                        dispatch_is_after_target = true;
-                        eins_from_loop++;
-                    }
-                    if ( lastInstIsMonitorExit(pre_dispatch) ) {
-                        found_monitorexit = true;
-                        const Edges& in_monexit_edges = pre_dispatch->getInEdges();
-                        Edges::const_iterator in_monexit_it = in_monexit_edges.begin();
-                        Edges::const_iterator in_monexit_end = in_monexit_edges.end();
-                        for (; in_monexit_it != in_monexit_end; in_monexit_it++) {
-                            Node* mon_pred = (*in_monexit_it)->getSourceNode();
-                            if ( mon_pred == catch_target ) {
-                               monitorexit_after_catch_target = true;
-                               eins_from_loop++;
-                               assert(((Inst*)catch_target->getLastInst())->getOpcode() == Op_TauCheckNull);
-                            }
-                            if ( mon_pred == catch_node ) {
-                               monitorexit_after_catch = true;
-                            }
-                        }
-                    }
-                }
-
-                if ( Log::isEnabled() ) {
-                    Log::out() << "eliminateUnnestedLoopsOnDispatch()" << std::endl;
-                    Log::out() << "    monitorexit_after_catch_target=" 
-                               << monitorexit_after_catch_target << std::endl;
-                    Log::out() << "    dispatch_is_after_target=" 
-                               << dispatch_is_after_target << std::endl;
-                    Log::out() << "    monitorexit_after_catch=" 
-                               << monitorexit_after_catch << std::endl;
-                }
-
-                if ( dispatch->getInDegree() <= eins_from_loop ) {
-                    // no second entrance into the loop
-                    continue;
-                }
-                if ( found_monitorexit &&
-                     ((monitorexit_after_catch_target && dispatch_is_after_target) ||
-                       monitorexit_after_catch)) {
-
-                    matched_dispatches.push_back(dispatch);
-                    if ( Log::isEnabled() ) {
-                        Log::out() << "goto into loop found, fixing..." << std::endl;
-                    }
-                    break;
-                }
-                if ( !found_goto_into_loop_warning ) {
-                    if ( Log::isEnabled() ) {
-                        Log::out() << "warning: maybe goto into loop with exception" 
-                                   << std::endl;
-                    }
-                    found_goto_into_loop_warning = true;
-                }
-            }
-        }
-    }
-    InstFactory* instFactory = irBuilder.getInstFactory();
-    for ( Nodes::const_iterator dispatch_iter = matched_dispatches.begin();
-          dispatch_iter != matched_dispatches.end();
-          dispatch_iter++ ) {
-        
-        Node* dispatch = (*dispatch_iter);
-        const Edges& in_edges = dispatch->getInEdges();
-        assert(dispatch->getInDegree() > 1);
-        while (in_edges.size() > 1) {
-           Edge* in_edge = *(++in_edges.begin());
-           Node* dup_dispatch = createDispatchNode();
-           fg->replaceEdgeTarget(in_edge, dup_dispatch);
-           const Edges& out_edges = dispatch->getOutEdges();
-           for (Edges::const_iterator out_edge_iter = out_edges.begin(); 
-                out_edge_iter != out_edges.end();
-                out_edge_iter++) {
-               Node* dispatch_target = (*out_edge_iter)->getTargetNode();
-               if ( !dispatch_target->isCatchBlock() ) {
-                   fg->addEdge(dup_dispatch, dispatch_target);
-               }else{
-                   CatchLabelInst* catch_label = (CatchLabelInst*)dispatch_target->getFirstInst();
-                   assert(dispatch_target->getInstCount() == 0);
-                   LabelInst* dupCatchInst = instFactory->makeCatchLabel( catch_label->getOrder(), catch_label->getExceptionType());
-                   dupCatchInst->setBCOffset(catch_label->getBCOffset());
-                   Node* dup_catch = createBlockNodeOrdered(dupCatchInst);
-                   fg->addEdge(dup_dispatch, dup_catch);
-                   assert(dispatch_target->getOutDegree() == 1);
-                   fg->addEdge(dup_catch, (*dispatch_target->getOutEdges().begin())->getTargetNode());
-               }
-
-           }
-        }
-    }
 }
 
-bool JavaFlowGraphBuilder::lastInstIsMonitorExit(Node* node)
-{
-    Inst* last = (Inst*)node->getLastInst();
-    if ( last->getOpcode() == Op_TypeMonitorExit ||
-         last->getOpcode() == Op_TauMonitorExit ) {
-        return true;
-    }
-    return false;
-}
 
 JavaFlowGraphBuilder::JavaFlowGraphBuilder(MemoryManager& mm, IRBuilder &irB) : 
     memManager(mm), currentBlock(NULL), irBuilder(irB), fallThruNodes(mm)

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaFlowGraphBuilder.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaFlowGraphBuilder.h?rev=585128&r1=585127&r2=585128&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaFlowGraphBuilder.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaFlowGraphBuilder.h Tue Oct 16 05:03:11 2007
@@ -46,9 +46,7 @@
     Node*        edgesForBlock(Node* block);
     void         edgesForHandler(Node* entry);
     void         edgeForFallthrough(Node* block);
-    void         eliminateUnnestedLoopsOnDispatch();
-    bool         lastInstIsMonitorExit(Node* node);
-
+    
     Node* createBlockNodeOrdered(LabelInst* label);
     Node* createBlockNodeAfter(Node* node, LabelInst* label);
     void addEdge(Node* source, Node* target);

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.cpp?rev=585128&r1=585127&r2=585128&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.cpp Tue Oct 16 05:03:11 2007
@@ -453,11 +453,36 @@
             //
             // add new CatchBlock
             //
-            prevCatch = catchBlock = 
-                new (memManager) CatchBlock(nextRegionId++, tryOffset, endOffset, numCatch++);
-            prepass.stateTable->getStateInfo(tryOffset)->addExceptionInfo(catchBlock);
-            prepass.exceptionTable.push_back(catchBlock);
-            addHandlerForCatchBlock(catchBlock, handlerOffset, exceptionType);
+            if (handlerOffset < endOffset && handlerOffset > tryOffset) { 
+                //self-handling block: add 2 CatchBlocks(ExceptionInfos) with the following boundaries:
+                //[tryOffset, handlerOffset], [handlerOffset, endOffset]
+                //The reason is to avoid loops with dispatch node as header:
+                // Details:
+                // For a single CatchBlock(ExceptionInfo) we have only 1 dispatch node today 
+                // (dispatch node is referenced by LabelInfo field in ExceptionInfo structure)
+                // Having single dispatch node for self-catching regions we will have a loop with
+                // dispatch node as a loop-header.
+                // To avoid having dispatch nodes as a loop-header we create 2 (CatchBlocks)ExceptionInfos here: 
+                // doing this we have 2 dispatch nodes for 2 ExceptionInfos and loop-header is automatically 
+                // moved to the next (after the second dispatch)block node with CatchLabelInst instruction.
+                // Example to reproduce: comment out this if clause and check IR for monexit loops.
+
+                prevCatch = catchBlock = new (memManager) CatchBlock(nextRegionId++, tryOffset, handlerOffset, numCatch++);
+                prepass.stateTable->getStateInfo(tryOffset)->addExceptionInfo(catchBlock);
+                prepass.exceptionTable.push_back(catchBlock);
+                addHandlerForCatchBlock(catchBlock, handlerOffset, exceptionType);
+
+                prevCatch = catchBlock = new (memManager) CatchBlock(nextRegionId++, handlerOffset, endOffset, numCatch++);
+                prepass.stateTable->getStateInfo(handlerOffset)->addExceptionInfo(catchBlock);
+                prepass.exceptionTable.push_back(catchBlock);
+                addHandlerForCatchBlock(catchBlock, handlerOffset, exceptionType);
+            } else { 
+                prevCatch = catchBlock = new (memManager) CatchBlock(nextRegionId++, tryOffset, endOffset, numCatch++);
+                prepass.stateTable->getStateInfo(tryOffset)->addExceptionInfo(catchBlock);
+                prepass.exceptionTable.push_back(catchBlock);
+                addHandlerForCatchBlock(catchBlock, handlerOffset, exceptionType);
+            } 
+            
         }
         return 1; // all exceptionTypes are OK
     }