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/06/09 16:40:03 UTC

svn commit: r545755 - in /harmony/enhanced/drlvm/trunk: src/test/regression/H4073/ src/test/regression/H4073/Test.java src/test/regression/H4073/run.test.xml vm/jitrino/src/codegenerator/ia32/Ia32I8Lowerer.cpp vm/jitrino/src/codegenerator/ia32/Ia32RCE.cpp

Author: varlax
Date: Sat Jun  9 07:40:01 2007
New Revision: 545755

URL: http://svn.apache.org/viewvc?view=rev&rev=545755
Log:
Applied HARMONY-4073 drlvm][jit] RCE must not substitute EFLAGS values produced by CMP with ones produced by SBB

Added:
    harmony/enhanced/drlvm/trunk/src/test/regression/H4073/
    harmony/enhanced/drlvm/trunk/src/test/regression/H4073/Test.java
    harmony/enhanced/drlvm/trunk/src/test/regression/H4073/run.test.xml
Modified:
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32I8Lowerer.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32RCE.cpp

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H4073/Test.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H4073/Test.java?view=auto&rev=545755
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H4073/Test.java (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H4073/Test.java Sat Jun  9 07:40:01 2007
@@ -0,0 +1,19 @@
+package org.apache.harmony.drlvm.tests.regression.h4073;
+
+import junit.framework.TestCase;
+
+public class Test extends TestCase {
+
+    public static void main(String args[]) {
+        (new Test()).test();
+    }
+
+    public void test() {
+        assertTrue(lessThenZero(Long.MIN_VALUE));
+    }
+
+    boolean lessThenZero(long v) {
+        v = -v;
+        return v < 0; 
+    }
+}
\ No newline at end of file

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H4073/run.test.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H4073/run.test.xml?view=auto&rev=545755
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H4073/run.test.xml (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H4073/run.test.xml Sat Jun  9 07:40:01 2007
@@ -0,0 +1,13 @@
+<project name="RUN HARMONY-4073 Regression Test">
+    <target name="run-test">
+        <run-junit-test 
+            test="org.apache.harmony.drlvm.tests.regression.h4073.Test"
+            vmarg="-Xem:jet">
+        </run-junit-test>
+        <run-junit-test 
+            test="org.apache.harmony.drlvm.tests.regression.h4073.Test"
+            vmarg="-Xem:opt">
+        </run-junit-test>
+    </target>
+</project>
+

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32I8Lowerer.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32I8Lowerer.cpp?view=diff&rev=545755&r1=545754&r2=545755
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32I8Lowerer.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32I8Lowerer.cpp Sat Jun  9 07:40:01 2007
@@ -73,7 +73,7 @@
     void buildShiftSubGraph(Inst * inst, Opnd * src1_1, Opnd * src1_2, Opnd * src2, Opnd * dst_1, Opnd * dst_2, Mnemonic mnem, Mnemonic opMnem);
     void buildComplexSubGraph(Inst * inst, Opnd * src1_1,Opnd * src1_2,Opnd * src2_1,Opnd * src2_2, Inst * condInst = NULL);
     void buildSetSubGraph(Inst * inst, Opnd * src1_1,Opnd * src1_2,Opnd * src2_1,Opnd * src2_2, Inst * condInst = NULL);
-    void buildJumpSubGraph(Inst * inst, Opnd * src1_1,Opnd * src1_2,Opnd * src2_1,Opnd * src2_2, Inst * condInst = NULL);
+    void compareAndBranch(Inst * inst, Opnd * src1_1,Opnd * src1_2,Opnd * src2_1,Opnd * src2_2, Inst * condInst = NULL);
     /**
      * Processes I8 IMUL instruction.
      *
@@ -456,7 +456,7 @@
                 Mnemonic mnem = condInst ? getBaseConditionMnemonic(condInst->getMnemonic()) : Mnemonic_NULL;
                 if (mnem != Mnemonic_NULL) {
                             if(condInst->hasKind(Inst::Kind_BranchInst)) {
-                                buildJumpSubGraph(inst,src1_1,src1_2,src2_1,src2_2,condInst);
+                                compareAndBranch(inst,src1_1,src1_2,src2_1,src2_2,condInst);
                             } else {
                                 buildSetSubGraph(inst,src1_1,src1_2,src2_1,src2_2,condInst);
                             }
@@ -559,47 +559,77 @@
     }
 }
 
-void I8Lowerer::buildJumpSubGraph(Inst * inst, Opnd * src1_1,Opnd * src1_2,Opnd * src2_1,Opnd * src2_2, Inst * condInst) {
-    Node * bb=inst->getNode();
-    
-    ControlFlowGraph* subCFG = irManager->createSubCFG(true, false);
-    Node* bbHMain = subCFG->getEntryNode();
-    Node* bbLMain = subCFG->createBlockNode();
-    Node* sinkNode =  subCFG->getReturnNode();
-    
-    bbHMain->appendInst(irManager->newInst(Mnemonic_CMP, src1_2, src2_2));
-    
-    bbLMain->appendInst(irManager->newInst(Mnemonic_CMP, src1_1, src2_1));
-    
-    
-    Node* bbFT = bb->getFalseEdgeTarget();
-    Node* bbDB = bb->getTrueEdgeTarget();
-    
-    Mnemonic mnem = Mnemonic_NULL;
-    switch(condInst->getMnemonic()) {
-        case Mnemonic_JL : mnem = Mnemonic_JB; break;
-        case Mnemonic_JLE : mnem = Mnemonic_JBE; break;
-        case Mnemonic_JG : mnem = Mnemonic_JA; break;
-        case Mnemonic_JGE : mnem = Mnemonic_JAE; break;
-        default: mnem = condInst->getMnemonic(); break;
-    }
-    bbLMain->appendInst(irManager->newBranchInst(mnem, bbDB, bbFT));
+void I8Lowerer::compareAndBranch(Inst * inst, Opnd * src1_1,Opnd * src1_2,Opnd * src2_1,Opnd * src2_2, Inst * condInst) {
+    ControlFlowGraph* cfg = irManager->getFlowGraph();
+
+    Node * bb = inst->getNode();
+    Edge* dbEdge = bb->getTrueEdge();
+    Edge* ftEdge = bb->getFalseEdge();
+    Node* bbDB = dbEdge->getTargetNode();
+    Node* bbFT = ftEdge->getTargetNode();
+    Mnemonic mn = condInst->getMnemonic();
     
-    if (condInst->getMnemonic() == Mnemonic_JZ) {
-        bbHMain->appendInst(irManager->newBranchInst(Mnemonic_JNZ, bbFT, bbLMain));
-        subCFG->addEdge(bbHMain, bbFT, 0.1);
-    } else if (condInst->getMnemonic() == Mnemonic_JNZ) {
-        bbHMain->appendInst(irManager->newBranchInst(Mnemonic_JNZ, bbDB, bbLMain));
-        subCFG->addEdge(bbHMain, bbDB, 0.1);
-    } else {
-        bbHMain->appendInst(irManager->newBranchInst(Mnemonic_JNZ, sinkNode, bbLMain));
-        subCFG->addEdge(bbHMain, sinkNode, 0.1);
-    }
-    subCFG->addEdge(bbHMain, bbLMain, 0.9);
-    subCFG->addEdge(bbLMain, bbFT, 0.1);
-    subCFG->addEdge(bbLMain, bbDB, 0.9);
+    //for == and != algorithms checks low parts first
+    if (mn == Mnemonic_JNZ) { // !=
+        Node* cmpHiNode = cfg->createBlockNode();
+        cfg->replaceEdgeTarget(ftEdge, cmpHiNode, true);
+        
+        //if (lo1!=lo2) return true;
+        bb->appendInst(irManager->newInst(Mnemonic_CMP, src1_1, src2_1));        
+        bb->appendInst(irManager->newBranchInst(Mnemonic_JNZ, bbDB, cmpHiNode));
+
+        //if (hi1!=hi2) return true;
+        cmpHiNode->appendInst(irManager->newInst(Mnemonic_CMP, src1_2, src2_2));
+        cmpHiNode->appendInst(irManager->newBranchInst(Mnemonic_JNZ, bbDB, bbFT));
         
-    irManager->getFlowGraph()->spliceFlowGraphInline(inst, *subCFG);
+        cfg->addEdge(cmpHiNode, bbDB, dbEdge->getEdgeProb());
+        cfg->addEdge(cmpHiNode, bbFT, ftEdge->getEdgeProb());
+    } else if (mn == Mnemonic_JZ) { // ==
+        Node* cmpHiNode = cfg->createBlockNode();
+        cfg->replaceEdgeTarget(dbEdge, cmpHiNode, true);
+       
+        //if lo1==lo2 check hi parts
+        bb->appendInst(irManager->newInst(Mnemonic_CMP, src1_1, src2_1));        
+        bb->appendInst(irManager->newBranchInst(Mnemonic_JZ, cmpHiNode, bbFT));
+
+        //if hi1==hi2 -> return true
+        cmpHiNode->appendInst(irManager->newInst(Mnemonic_CMP, src1_2, src2_2));
+        cmpHiNode->appendInst(irManager->newBranchInst(Mnemonic_JZ, bbDB, bbFT));
+
+        cfg->addEdge(cmpHiNode, bbDB, dbEdge->getEdgeProb());
+        cfg->addEdge(cmpHiNode, bbFT, ftEdge->getEdgeProb());
+    } else { // >=, >, <=, <
+        //if hi parts equals -> compare low parts
+        //else compare hi parts
+        Node* cmpHiNode = cfg->createBlockNode();
+        Node* cmpLoNode = cfg->createBlockNode();
+
+        //check if hi parts are equal
+        cfg->replaceEdgeTarget(dbEdge, cmpHiNode, true);
+        cfg->replaceEdgeTarget(ftEdge, cmpLoNode, true);
+        bb->appendInst(irManager->newInst(Mnemonic_CMP, src1_2, src2_2));        
+        bb->appendInst(irManager->newBranchInst(Mnemonic_JNE, cmpHiNode, cmpLoNode));
+
+        //check hi parts: reuse old CMP result here
+        cmpHiNode->appendInst(irManager->newBranchInst(mn, bbDB, bbFT));
+        cfg->addEdge(cmpHiNode, bbDB, dbEdge->getEdgeProb());
+        cfg->addEdge(cmpHiNode, bbFT, ftEdge->getEdgeProb());
+        
+        //check lo parts, use unsigned comparison
+        Mnemonic unsignedMn = Mnemonic_NULL;
+        switch(mn) {
+            case Mnemonic_JL  : unsignedMn = Mnemonic_JB; break;
+            case Mnemonic_JLE : unsignedMn = Mnemonic_JBE; break;
+            case Mnemonic_JG  : unsignedMn = Mnemonic_JA; break;
+            case Mnemonic_JGE : unsignedMn = Mnemonic_JAE; break;
+            default: unsignedMn = mn; break;
+        }
+        cmpLoNode->appendInst(irManager->newInst(Mnemonic_CMP, src1_1, src2_1));        
+        cmpLoNode->appendInst(irManager->newBranchInst(unsignedMn, bbDB, bbFT));
+        cfg->addEdge(cmpLoNode, bbDB, dbEdge->getEdgeProb());
+        cfg->addEdge(cmpLoNode, bbFT, ftEdge->getEdgeProb());
+    }
+    condInst->unlink();
 }
 
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32RCE.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32RCE.cpp?view=diff&rev=545755&r1=545754&r2=545755
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32RCE.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32RCE.cpp Sat Jun  9 07:40:01 2007
@@ -204,6 +204,7 @@
         case Mnemonic_CALL:
         case Mnemonic_IMUL:
         case Mnemonic_MUL:
+        case Mnemonic_SBB: //SBB does not distinguish between signed and unsigned operands
             //instruction changes flags in the way doesn't correspond CMP
             return false;
         default: