You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by va...@apache.org on 2007/04/20 13:23:24 UTC

svn commit: r530744 - in /harmony/enhanced/drlvm/trunk: src/test/regression/H3652/ vm/jitrino/src/codegenerator/ia32/ vm/jitrino/src/shared/

Author: varlax
Date: Fri Apr 20 04:23:23 2007
New Revision: 530744

URL: http://svn.apache.org/viewvc?view=rev&rev=530744
Log:
HARMONY-3652 [drlvm][jit][opt] I8Lowerer produces code that does not pass internal verification
added regression test

Added:
    harmony/enhanced/drlvm/trunk/src/test/regression/H3652/
    harmony/enhanced/drlvm/trunk/src/test/regression/H3652/Test.java
    harmony/enhanced/drlvm/trunk/src/test/regression/H3652/run.test.xml
Modified:
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32BranchTrans.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/ControlFlowGraph.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/ControlFlowGraph.h

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3652/Test.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3652/Test.java?view=auto&rev=530744
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3652/Test.java (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3652/Test.java Fri Apr 20 04:23:23 2007
@@ -0,0 +1,30 @@
+package org.apache.harmony.drlvm.tests.regression.h3652;
+
+import junit.framework.TestCase;
+
+public class Test extends TestCase {
+
+    public void test() {
+       // assertEquals(20, foo()); 
+       foo(10);
+       System.out.println(buf); 
+    } 
+
+    String buf =""; 
+    public Test foo(long l) { 
+        boolean flag = false; 
+        if (l >= 20L) { 
+            flag = true; 
+        } 
+        if(flag || l >= 10L) { 
+            int k = (int)(l / 11L); 
+            writeDigits(k, flag); 
+        } 
+        return this; 
+
+    } 
+
+    void writeDigits(int i, boolean flag) { 
+        buf+=i; 
+    } 
+}

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3652/run.test.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3652/run.test.xml?view=auto&rev=530744
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3652/run.test.xml (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3652/run.test.xml Fri Apr 20 04:23:23 2007
@@ -0,0 +1,8 @@
+<project name="RUN HARMONY-3652 Regression Test">
+  <target name="run-test">
+    <run-junit-test 
+        test="org.apache.harmony.drlvm.tests.regression.h3652.Test"
+        vmarg="-Xem:opt -XX:jit.arg.verify=2">
+    </run-junit-test>
+  </target>
+</project>

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32BranchTrans.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32BranchTrans.cpp?view=diff&rev=530744&r1=530743&r2=530744
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32BranchTrans.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32BranchTrans.cpp Fri Apr 20 04:23:23 2007
@@ -264,9 +264,9 @@
                                             continue; //can't retarget this edge -> var is not a const
                                         }
                                         if (branchDirection(opnd->getImmValue(), cmpOp2->getImmValue(),cmpOp1->getSize(),condMnem)) {
-                                            irManager->getFlowGraph()->replaceEdgeTarget(edge, trueBB);
+                                            irManager->getFlowGraph()->replaceEdgeTarget(edge, trueBB, true);
                                         } else {
-                                            irManager->getFlowGraph()->replaceEdgeTarget(edge, falseBB);
+                                            irManager->getFlowGraph()->replaceEdgeTarget(edge, falseBB, true);
                                         }
                                         for(Inst * copy = (Inst *)bb->getFirstInst();copy!=NULL; copy=copy->getNextInst()) {
                                             if (copy != inst && copy !=cmpInst) {
@@ -275,10 +275,15 @@
                                                 Inst * newInst = copy->getKind() == Inst::Kind_I8PseudoInst?
                                                     irManager->newI8PseudoInst(Mnemonic_MOV,1,copy->getOpnd(0),copy->getOpnd(1)):
                                                     irManager->newCopyPseudoInst(Mnemonic_MOV,copy->getOpnd(0),copy->getOpnd(1));
-                                                if (lastInst->getKind()== Inst::Kind_BranchInst) 
-                                                    sourceBB->prependInst(newInst, lastInst);
-                                                else
+                                                if (lastInst->getKind()== Inst::Kind_BranchInst) {
+                                                    //WAS: sourceBB->prependInst(newInst, lastInst);
+                                                    //create new block instead of prepending to branchInst
+                                                    //some algorithms like I8Lowerer are very sensitive to CMP/JCC pattern
+                                                    //and fails if any inst is inserted between CMP and JCC
+                                                    irManager->getFlowGraph()->spliceBlockOnEdge(edge, newInst, true);
+                                                } else {
                                                     sourceBB->appendInst(newInst);
+                                                }
                                             }
                                         }
                                     }
@@ -401,7 +406,7 @@
                             bb->prependInst(irManager->newInstEx(Mnemonic(Mnemonic_CMOVcc+condMnem), 1, tfOp,tfOp,tsOp),inst);
                         }
                             //link bb with successor of trueBB and falseBB
-                            irManager->getFlowGraph()->replaceEdgeTarget(bb->getFalseEdge(), nextBB);
+                            irManager->getFlowGraph()->replaceEdgeTarget(bb->getFalseEdge(), nextBB, true);
                             irManager->getFlowGraph()->removeEdge(bb->getTrueEdge());
                             inst->unlink();
                             irManager->getFlowGraph()->removeNode(falseBB);

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/ControlFlowGraph.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/ControlFlowGraph.cpp?view=diff&rev=530744&r1=530743&r2=530744
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/ControlFlowGraph.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/ControlFlowGraph.cpp Fri Apr 20 04:23:23 2007
@@ -237,11 +237,13 @@
     // Remove incident edges
     while (!node->inEdges.empty()) {
         Edge* edge = node->inEdges.front();
+        assert(edge->getTargetNode() == node);
         removeEdge(edge);
     }
     
     while (!node->outEdges.empty()) {
         Edge* edge = node->outEdges.front();
+        assert(edge->getSourceNode() == node);
         removeEdge(edge);
     }
 
@@ -310,7 +312,12 @@
     Edge* newEdge = NULL;
     if (keepOldBody) {
         edge->target = newTarget;
+        newTarget->inEdges.push_back(edge);
+        Edges& oldInEdges = oldTarget->inEdges;
+        oldInEdges.erase(std::remove(oldInEdges.begin(), oldInEdges.end(), edge));
         newEdge = edge;
+        // Mark the graph modified.
+        lastModifiedTraversalNumber = traversalNumber;
     } else {
         removeEdge(edge);
         newEdge = addEdge(source, newTarget);
@@ -441,13 +448,13 @@
 }
 
 // Splice a new empty block on the CFG edge.
-Node* ControlFlowGraph::spliceBlockOnEdge(Edge* edge, CFGInst* inst) {
+Node* ControlFlowGraph::spliceBlockOnEdge(Edge* edge, CFGInst* inst, bool keepOldEdge) {
     Node*    source = edge->getSourceNode();
     double edgeProb = edge->getEdgeProb();
     double edgeFreq = source->getExecCount()*edgeProb;
 
     // Split the edge
-    Node* split =  splitEdge(edge, inst);
+    Node* split =  splitEdge(edge, inst, keepOldEdge);
     split->setExecCount(edgeFreq);
 
     // Set the incoming edge probability
@@ -479,7 +486,7 @@
                     Node* source = thisEdge->getSourceNode();
                     if ((source->getOutDegree() > 1) && (includeExceptionEdges || !source->isDispatchNode())) {
                         // it's a critical edge, split it
-                        Node* newNode = splitEdge(thisEdge, NULL);
+                        Node* newNode = splitEdge(thisEdge, NULL, false); //TODO: keep old edge?
                         if (newNodes) {
                             newNodes->push_back(newNode);
                         }
@@ -811,11 +818,11 @@
     return newNode;
 }
 
-Node* ControlFlowGraph::splitEdge(Edge *edge, CFGInst* inst) {
+Node* ControlFlowGraph::splitEdge(Edge *edge, CFGInst* inst, bool keepOldEdge) {
     Node* target = edge->getTargetNode();
     Node* newNode = createBlockNode(inst);
 
-    replaceEdgeTarget(edge, newNode);
+    replaceEdgeTarget(edge, newNode, keepOldEdge);
     addEdge(newNode, target);
 
     return newNode;

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/ControlFlowGraph.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/ControlFlowGraph.h?view=diff&rev=530744&r1=530743&r2=530744
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/ControlFlowGraph.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/ControlFlowGraph.h Fri Apr 20 04:23:23 2007
@@ -1438,10 +1438,11 @@
    *
    * @param[in] edge - the edge to splice
    * @param[in] inst - the instruction to add to a new node
+   * @param[in] keepOldEdge  - keep old edge and use it to connect source and new nodes
    *
    * @return The newly created node.
    */
-    Node* spliceBlockOnEdge(Edge* edge, CFGInst* inst = NULL);
+    Node* spliceBlockOnEdge(Edge* edge, CFGInst* inst = NULL, bool keepOldEdge=false);
 
   /** 
    * Inlines <code>inlineFG</code> into this CFG after <code>instAfter</code>, 
@@ -1653,7 +1654,7 @@
 
   /// Splits the edge and adds <code>newBlockInst</code> to a new node.
    
-    Node* splitEdge(Edge* edge, CFGInst* newBlockInst);
+    Node* splitEdge(Edge* edge, CFGInst* newBlockInst, bool keepOldEdge);
     
   /// Checks whether the <code>Source</code> node can be merged with the <code>Target</code> node.