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: