harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From var...@apache.org
Subject svn commit: r489320 - in /harmony/enhanced/drlvm/trunk/vm: jitrino/config/ia32/ jitrino/src/codegenerator/ia32/ jitrino/src/optimizer/ jitrino/src/shared/ jitrino/src/translator/ port/src/encoder/ia32_em64t/
Date Thu, 21 Dec 2006 11:05:11 GMT
Author: varlax
Date: Thu Dec 21 03:05:07 2006
New Revision: 489320

URL: http://svn.apache.org/viewvc?view=rev&rev=489320
Log:
Applied HARMONY-2778 [drlvm][jitrino] Inlining of API methods as magics. Platform dependent
part of the framework.
Made minimal corrections to original patch: fixed em64t compilation, clarified comment.
Tested on SUSE9@ia32 & SUSE9@x64

Added:
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32APIMagics.cpp   (with
props)
Modified:
    harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf
    harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/opt.emconf
    harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf
    harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.emconf
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/ControlFlowGraph.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/methodtable.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/methodtable.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.cpp
    harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_defs.h
    harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf?view=diff&rev=489320&r1=489319&r2=489320
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/client.emconf Thu Dec 21 03:05:07
2006
@@ -54,7 +54,7 @@
 -XDjit.CD_OPT.path=opt_init,translator,optimizer,hir2lir,codegen
 
 -XDjit.CD_OPT.path.optimizer=ssa,devirt,inline,uce,purge,simplify,dce,uce,lazyexc,memopt,simplify,dce,uce,lower,dessa,statprof,markglobals
--XDjit.CD_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
+-XDjit.CD_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
 -XDjit.CD_OPT.path.dce1=cg_dce
 -XDjit.CD_OPT.path.dce2=cg_dce
 -XDjit.CD_OPT.path.regalloc=bp_regalloc1,bp_regalloc2

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/opt.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/opt.emconf?view=diff&rev=489320&r1=489319&r2=489320
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/opt.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/opt.emconf Thu Dec 21 03:05:07 2006
@@ -25,7 +25,7 @@
 -XDjit.CS_OPT.path=opt_init,translator,optimizer,hir2lir,codegen
 
 -XDjit.CS_OPT.path.optimizer=ssa,devirt,inline,uce,purge,simplify,dce,uce,lazyexc,memopt,simplify,dce,uce,lower,dessa,statprof,markglobals
--XDjit.CS_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
+-XDjit.CS_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
 -XDjit.CS_OPT.path.dce1=cg_dce
 -XDjit.CS_OPT.path.dce2=cg_dce
 -XDjit.CS_OPT.path.regalloc=bp_regalloc1,bp_regalloc2

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf?view=diff&rev=489320&r1=489319&r2=489320
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf Thu Dec 21 03:05:07
2006
@@ -46,7 +46,7 @@
 -XDjit.SD1_OPT.path=opt_init,translator,optimizer,hir2lir,codegen
 
 -XDjit.SD1_OPT.path.optimizer=ssa,simplify,dce,uce,vp_instrument,edge_instrument,dessa,statprof,markglobals
--XDjit.SD1_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
+-XDjit.SD1_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
 -XDjit.SD1_OPT.path.dce1=cg_dce
 -XDjit.SD1_OPT.path.dce2=cg_dce
 -XDjit.SD1_OPT.path.regalloc=bp_regalloc1,bp_regalloc2
@@ -60,7 +60,7 @@
 -XDjit.SD2_OPT.path=opt_init,translator,optimizer,hir2lir,codegen
 
 -XDjit.SD2_OPT.path.optimizer=ssa,simplify,dce,uce,edge_annotate,devirt,inline,uce,purge,simplify,dce,uce,lazyexc,inline_helpers,purge,simplify,uce,dce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,lower,dce,uce,memopt,reassoc,dce,uce,hvn,dce,uce,abcd,dce,uce,gcm,dessa,statprof,markglobals
--XDjit.SD2_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
+-XDjit.SD2_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
 -XDjit.SD2_OPT.path.dce1=cg_dce
 -XDjit.SD2_OPT.path.dce2=cg_dce
 -XDjit.SD2_OPT.path.regalloc=bp_regalloc1,bp_regalloc2

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.emconf?view=diff&rev=489320&r1=489319&r2=489320
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.emconf Thu Dec 21 03:05:07
2006
@@ -25,7 +25,7 @@
 -XDjit.SS_OPT.path=opt_init,translator,optimizer,hir2lir,codegen
 
 -XDjit.SS_OPT.path.optimizer=ssa,simplify,dce,uce,statprof,devirt,inline,uce,purge,simplify,dce,uce,lazyexc,hvn,dce,uce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,lower,dce,uce,memopt,reassoc,dce,uce,hvn,dce,uce,abcd,dce,uce,gcm,dessa,statprof,markglobals
--XDjit.SS_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
+-XDjit.SS_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l,api_magic,early_prop,peephole,itrace-,native,constraints,dce2,regalloc,spillgen,layout,copy,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
 -XDjit.SS_OPT.path.dce1=cg_dce
 -XDjit.SS_OPT.path.dce2=cg_dce
 -XDjit.SS_OPT.path.regalloc=bp_regalloc1,bp_regalloc2

Added: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32APIMagics.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32APIMagics.cpp?view=auto&rev=489320
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32APIMagics.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32APIMagics.cpp Thu Dec
21 03:05:07 2006
@@ -0,0 +1,299 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/**
+ * @author Intel, Mikhail Y. Fursov
+ */
+
+#include "Ia32Inst.h"
+#include "Ia32IRManager.h"
+
+
+//#define ENABLE_GC_RT_CHECKS
+
+namespace Jitrino {
+namespace  Ia32 {
+
+class APIMagicsHandlerSession: public SessionAction {
+    void runImpl();
+    uint32 getNeedInfo()const{ return 0; }
+    uint32 getSideEffects()const{ return 0; }
+    bool isIRDumpEnabled(){ return true; }
+};
+
+static ActionFactory<APIMagicsHandlerSession> _api_magics("api_magic");
+
+static Opnd* getCallDst(CallInst* callInst) {
+    Inst::Opnds defs(callInst, Inst::OpndRole_InstLevel | Inst::OpndRole_Def | Inst::OpndRole_Explicit);
+    uint32 idx = defs.begin();
+    return callInst->getOpnd(idx);
+}
+static Opnd* getCallSrc(CallInst* callInst, uint32 n) {
+    Inst::Opnds uses(callInst, Inst::OpndRole_InstLevel | Inst::OpndRole_Use | Inst::OpndRole_Explicit);
+    uint32 idx  = uses.begin(); //the first use is call addr
+    for (uint32 i=0; i<=n; i++) {
+        idx = uses.next(idx);
+    }
+    return  callInst->getOpnd(idx);
+}
+
+class APIMagicHandler {
+public:
+    APIMagicHandler(IRManager* _irm, CallInst* _inst, MethodDesc* _md)   : irm(_irm), callInst(_inst),
md(_md) {
+        cfg = irm->getFlowGraph();
+    }
+    virtual ~APIMagicHandler(){};
+
+    virtual void run()=0;
+protected:
+
+    IRManager* irm;
+    CallInst* callInst;
+    MethodDesc*  md;
+    ControlFlowGraph* cfg;
+};
+
+#define DECLARE_HELPER_INLINER(name)\
+class name : public APIMagicHandler {\
+public:\
+    name (IRManager* irm, CallInst* inst, MethodDesc* md)\
+    : APIMagicHandler(irm, inst, md){}\
+    \
+    virtual void run();\
+};\
+
+DECLARE_HELPER_INLINER(Integer_numberOfLeadingZeros_Handler_x_I_x_I);
+DECLARE_HELPER_INLINER(Integer_numberOfTrailingZeros_Handler_x_I_x_I);
+DECLARE_HELPER_INLINER(Long_numberOfLeadingZeros_Handler_x_J_x_I);
+DECLARE_HELPER_INLINER(Long_numberOfTrailingZeros_Handler_x_J_x_I);
+
+void APIMagicsHandlerSession::runImpl() {
+    CompilationContext* cc = getCompilationContext();
+    MemoryManager tmpMM(1024, "Inline API methods");
+    //finding all api magic calls
+    IRManager* irm = cc->getLIRManager();
+    ControlFlowGraph* fg = irm->getFlowGraph();
+    StlVector<APIMagicHandler*> handlers(tmpMM);
+    const Nodes& nodes = fg->getNodesPostOrder();//process checking only reachable
nodes.
+    for (Nodes::const_iterator it = nodes.begin(), end = nodes.end(); it!=end; ++it) {
+        Node* node = *it;
+        if (node->isBlockNode()) {
+            for (Inst* inst = (Inst*)node->getFirstInst(); inst!=NULL; inst = inst->getNextInst())
{
+                if (!inst->hasKind(Inst::Kind_CallInst) || !((CallInst*)inst)->isDirect())
{
+                    continue;
+                }
+                CallInst* callInst = (CallInst*)inst;
+                Opnd * targetOpnd=callInst->getOpnd(callInst->getTargetOpndIndex());
+                assert(targetOpnd->isPlacedIn(OpndKind_Imm));
+                Opnd::RuntimeInfo * ri=targetOpnd->getRuntimeInfo();
+                if( !ri || ri->getKind() != Opnd::RuntimeInfo::Kind_MethodDirectAddr)
{ 
+                    continue; 
+                };
+                MethodDesc * md = (MethodDesc*)ri->getValue(0);
+                const char* className = md->getParentType()->getName();
+                const char* methodName = md->getName();
+                const char* signature = md->getSignatureString();
+                if (!strcmp(className, "java/lang/Integer")) {
+                    if (!strcmp(methodName, "numberOfLeadingZeros") && !strcmp(signature,
"(I)I")) {
+                        handlers.push_back(new (tmpMM) Integer_numberOfLeadingZeros_Handler_x_I_x_I(irm,
callInst, md));
+                    } else if (!strcmp(methodName, "numberOfTrailingZeros") && !strcmp(signature,
"(I)I")) {
+                        handlers.push_back(new (tmpMM) Integer_numberOfTrailingZeros_Handler_x_I_x_I(irm,
callInst, md));
+                    }
+                } else if (!strcmp(className, "java/lang/Long")) {
+                    if (!strcmp(methodName, "numberOfLeadingZeros") && !strcmp(signature,
"(J)I")) {
+                        handlers.push_back(new (tmpMM) Long_numberOfLeadingZeros_Handler_x_J_x_I(irm,
callInst, md));
+                    } else if (!strcmp(methodName, "numberOfTrailingZeros") && !strcmp(signature,
"(J)I")) {
+                        handlers.push_back(new (tmpMM) Long_numberOfTrailingZeros_Handler_x_J_x_I(irm,
callInst, md));
+                    }
+                }
+
+            }
+        }
+    }
+
+    //running all handlers
+    for (StlVector<APIMagicHandler*>::const_iterator it = handlers.begin(), end = handlers.end();
it!=end; ++it) {
+        APIMagicHandler* handler = *it;
+        handler->run();
+    }
+    if (handlers.size() > 0) {
+        irm->invalidateLivenessInfo();
+    }
+}
+
+
+void Integer_numberOfLeadingZeros_Handler_x_I_x_I::run() {
+    //mov r2,-1
+    //bsr r1,arg
+    //cmovz r1,r2
+    //return 31 - r1;
+    Type * i32Type =irm->getTypeFromTag(Type::Int32);
+    Opnd* r1 = irm->newOpnd(i32Type);
+    Opnd* r2 = irm->newOpnd(i32Type);
+    Opnd* arg = getCallSrc(callInst, 0);
+    Opnd* res = getCallDst(callInst);
+
+    
+    irm->newCopyPseudoInst(Mnemonic_MOV, r2, irm->newImmOpnd(i32Type, -1))->insertBefore(callInst);
+    irm->newInstEx(Mnemonic_BSR, 1, r1, arg)->insertBefore(callInst);
+    irm->newInstEx(Mnemonic_CMOVZ, 1, r1, r2)->insertBefore(callInst);
+    irm->newInstEx(Mnemonic_SUB, 1, res, irm->newImmOpnd(i32Type, 31), r1)->insertBefore(callInst);
+
+    callInst->unlink();
+}
+
+void Integer_numberOfTrailingZeros_Handler_x_I_x_I::run() {
+    //mov r2,32
+    //bsf r1,arg
+    //cmovz r1,r2
+    //return r1
+    Type * i32Type =irm->getTypeFromTag(Type::Int32);
+    Opnd* r1 = irm->newOpnd(i32Type);
+    Opnd* r2 = irm->newOpnd(i32Type);
+    Opnd* arg = getCallSrc(callInst, 0);
+    Opnd* res = getCallDst(callInst);
+
+    irm->newCopyPseudoInst(Mnemonic_MOV, r2, irm->newImmOpnd(i32Type, 32))->insertBefore(callInst);
+    irm->newInstEx(Mnemonic_BSF, 1, r1, arg)->insertBefore(callInst);
+    irm->newInstEx(Mnemonic_CMOVZ, 1, r1, r2)->insertBefore(callInst);
+    irm->newCopyPseudoInst(Mnemonic_MOV, res, r1)->insertBefore(callInst);
+
+    callInst->unlink();
+}
+
+void Long_numberOfLeadingZeros_Handler_x_J_x_I::run() {
+#ifdef _EM64T_
+    return;
+#else
+//  bsr r1,hi
+//  jz high_part_is_zero 
+//high_part_is_not_zero:
+//  return 31-r1
+//high_part_is_zero:
+//  mov r2,-1
+//  bsr r1,lw
+//  cmovz r1, r2
+//  return 63 - r1;
+
+    
+    Type * i32Type =irm->getTypeFromTag(Type::Int32);
+    Opnd* r1 = irm->newOpnd(i32Type);
+    Opnd* r2 = irm->newOpnd(i32Type);
+    Opnd* lwOpnd = getCallSrc(callInst, 0);
+    Opnd* hiOpnd = getCallSrc(callInst, 1);
+    Opnd* res = getCallDst(callInst);
+    
+    if (callInst!=callInst->getNode()->getLastInst()) {
+        cfg->splitNodeAtInstruction(callInst, true, true, NULL);
+    }
+    Node* node = callInst->getNode();
+    Node* nextNode = node->getUnconditionalEdgeTarget();
+    assert(nextNode!=NULL);
+    cfg->removeEdge(node->getUnconditionalEdge());
+    callInst->unlink();
+
+    Node* hiZeroNode = cfg->createBlockNode();
+    Node* hiNotZeroNode = cfg->createBlockNode();
+    
+    //node
+    node->appendInst(irm->newInstEx(Mnemonic_BSR, 1, r1, hiOpnd));
+    node->appendInst(irm->newBranchInst(Mnemonic_JZ, hiZeroNode, hiNotZeroNode));
+    
+    
+    //high_part_is_not_zero
+    hiNotZeroNode->appendInst(irm->newInstEx(Mnemonic_SUB, 1, res, irm->newImmOpnd(i32Type,
31), r1));
+    
+    //high_part_is_zero
+    hiZeroNode->appendInst(irm->newCopyPseudoInst(Mnemonic_MOV, r2, irm->newImmOpnd(i32Type,
-1)));
+    hiZeroNode->appendInst(irm->newInstEx(Mnemonic_BSR, 1, r1, lwOpnd));
+    hiZeroNode->appendInst(irm->newInstEx(Mnemonic_CMOVZ, 1, r1, r2));
+    hiZeroNode->appendInst(irm->newInstEx(Mnemonic_SUB, 1, res, irm->newImmOpnd(i32Type,
63), r1));
+
+
+    cfg->addEdge(node, hiZeroNode, 0.3);
+    cfg->addEdge(node, hiNotZeroNode, 0.7);
+    cfg->addEdge(hiZeroNode, nextNode);
+    cfg->addEdge(hiNotZeroNode, nextNode);
+
+#endif
+}
+
+void Long_numberOfTrailingZeros_Handler_x_J_x_I::run() {
+#ifdef _EM64T_
+    return;
+#else
+
+//    bsf r1,lw
+//    jz low_part_is_zero 
+//low_part_is_not_zero:
+//    return r1;
+//low_part_is_zero:
+//    bsf r1,hi
+//    jz zero
+//not_zero;
+//    return 32 + r1;
+//zero:
+//    return 64;
+
+    Type * i32Type =irm->getTypeFromTag(Type::Int32);
+    Opnd* r1 = irm->newOpnd(i32Type);
+    Opnd* lwOpnd = getCallSrc(callInst, 0);
+    Opnd* hiOpnd = getCallSrc(callInst, 1);
+    Opnd* res = getCallDst(callInst);
+
+    if (callInst!=callInst->getNode()->getLastInst()) {
+        cfg->splitNodeAtInstruction(callInst, true, true, NULL);
+    }
+    Node* node = callInst->getNode();
+    Node* nextNode = node->getUnconditionalEdgeTarget();
+    assert(nextNode!=NULL);
+    cfg->removeEdge(node->getUnconditionalEdge());
+    callInst->unlink();
+
+    Node* lowZeroNode = cfg->createBlockNode();
+    Node* lowNotZeroNode = cfg->createBlockNode();
+    Node* notZeroNode = cfg->createBlockNode();
+    Node* zeroNode = cfg->createBlockNode();
+    
+    //node:
+    node->appendInst(irm->newInstEx(Mnemonic_BSF, 1, r1, lwOpnd));
+    node->appendInst(irm->newBranchInst(Mnemonic_JZ, lowZeroNode, lowNotZeroNode));
+
+    //low_part_is_not_zero:
+    lowNotZeroNode->appendInst(irm->newCopyPseudoInst(Mnemonic_MOV, res, r1));
+
+    //low_part_is_zero:
+    lowZeroNode->appendInst(irm->newInstEx(Mnemonic_BSF, 1, r1, hiOpnd)); 
+    lowZeroNode->appendInst(irm->newBranchInst(Mnemonic_JZ, zeroNode, notZeroNode));
   
+
+    //not zero:
+    notZeroNode->appendInst(irm->newInstEx(Mnemonic_ADD, 1, res, r1, irm->newImmOpnd(i32Type,
32)));
+
+    //zero:
+    zeroNode->appendInst(irm->newCopyPseudoInst(Mnemonic_MOV, res, irm->newImmOpnd(i32Type,
64)));
+
+    cfg->addEdge(node, lowNotZeroNode, 0.7);
+    cfg->addEdge(node, lowZeroNode, 0.3);
+    cfg->addEdge(lowNotZeroNode, nextNode);
+    cfg->addEdge(lowZeroNode, zeroNode, 0.1);
+    cfg->addEdge(lowZeroNode, notZeroNode, 0.9);
+    cfg->addEdge(notZeroNode, nextNode);
+    cfg->addEdge(zeroNode, nextNode);
+
+#endif
+}
+
+}} //namespace

Propchange: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32APIMagics.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.cpp?view=diff&rev=489320&r1=489319&r2=489320
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.cpp Thu Dec 21 03:05:07
2006
@@ -116,12 +116,29 @@
     _inlineExactAllBonus = argSource->getIntArg("exact_all_parameter_bonus", INLINE_EXACT_ALL_BONUS);
 
     _inlineSkipExceptionPath = argSource->getBoolArg("skip_exception_path", INLINE_SKIP_EXCEPTION_PATH);
-    const char* skipMethods = argSource->getStringArg("skip_methods", NULL);
-    if(skipMethods == NULL) {
-        _inlineSkipMethodTable = NULL;
-    } else {
+#if defined  (_EM64T_) || defined (_IPF_)
+    _inlineSkipApiMagicMethods  = true;
+#else
+    _inlineSkipApiMagicMethods = argSource->getBoolArg("skip_api_magics", false);
+#endif 
+
+    const char* skipMethods = argSource->getStringArg("skip_methods", "");
+    _inlineSkipMethodTable = NULL;
+    if(skipMethods != NULL || !_inlineSkipApiMagicMethods) {
         std::string skipMethodsStr = skipMethods;
-        _inlineSkipMethodTable = new (_tmpMM) Method_Table(skipMethodsStr.c_str(), "SKIP_METHODS",
true);
+        _inlineSkipMethodTable = new (_tmpMM) Method_Table(_tmpMM, skipMethodsStr.c_str(),
"SKIP_METHODS", true);
+        if (!_inlineSkipApiMagicMethods) {
+#if defined  (_EM64T_) || defined (_IPF_)
+//TODO: IA32 helpers should work on EM64T too -> TODO test
+#else
+            //is_accepted will return 'true' for these methods by skip table-> no inlining
will be done
+            Method_Table::Decision des = Method_Table::mt_accepted; 
+            _inlineSkipMethodTable->add_method_record("java/lang/Integer", "numberOfLeadingZeros",
"(I)I", des, false);
+            _inlineSkipMethodTable->add_method_record("java/lang/Integer", "numberOfTrailingZeros",
"(I)I", des, false);
+            _inlineSkipMethodTable->add_method_record("java/lang/Long", "numberOfLeadingZeros",
"(J)I", des, false);
+            _inlineSkipMethodTable->add_method_record("java/lang/Long", "numberOfTrailingZeros",
"(J)I", des, false);
+#endif 
+        }
     }
 
     _usesOptimisticBalancedSync = argSource->getBoolArg("sync_optimistic", false) ? argSource->getBoolArg("sync_optcatch",
true) : false;

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.h?view=diff&rev=489320&r1=489319&r2=489320
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.h Thu Dec 21 03:05:07 2006
@@ -171,8 +171,9 @@
     int32 _inlineRecursionPenalty;
     int32 _inlineExactArgBonus;
     int32 _inlineExactAllBonus;
-
+    
     bool _inlineSkipExceptionPath;
+    bool _inlineSkipApiMagicMethods;
     Method_Table* _inlineSkipMethodTable;
 
     uint64 oldMethodId;

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=489320&r1=489319&r2=489320
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/ControlFlowGraph.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/ControlFlowGraph.cpp Thu Dec 21 03:05:07
2006
@@ -760,9 +760,10 @@
             }
             if(redundant) {
                 // Edge is redundant - eliminate.
-                if(pred->getOutDegree() == 2) {
+                if(pred->getOutDegree() == 2 || (pred->getOutDegree()==3 &&
pred->getExceptionEdge()!=NULL)) {
                     // Pred already has edge to node and succ, and no other successors. 

                     // We can eliminate the branch and the edge to succ.
+                    // Another case is branch+exception for extended form
                     if(pred->isBlockNode()) {
                         lastInst->removeRedundantBranch();
                     }

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/methodtable.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/methodtable.cpp?view=diff&rev=489320&r1=489319&r2=489320
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/methodtable.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/methodtable.cpp Thu Dec 21 03:05:07
2006
@@ -73,24 +73,10 @@
 #define REF_END_CHAR ';'
 #define FILE_CHAR ':'
 
-// Make sure method_table can hold one more element.
-static void resize_table(struct Method_Table::method_record *&table, int &size, int
&capacity)
-{
-    if (capacity == 0)
-    {
-        capacity = 100;  // a reasonable initial guess
-        table = (struct Method_Table::method_record *) malloc(capacity * sizeof(*table));
-    }
-    if (size >= capacity)
-    {
-        capacity *= 2;
-        table = (struct Method_Table::method_record *) realloc(table, capacity * sizeof(*table));
-    }
-}
 
 void Method_Table::make_filename(char *str, int len)
 {
-    _method_file = (char *)malloc(1+len);
+    _method_file = new (_mm) char[1+len];
     strncpy(_method_file, str, len);
     _method_file[len] = '\0';
 }
@@ -133,7 +119,7 @@
 }
 
 // [class::][method][(signature)]
-static void parse_method_string(char *str, struct Method_Table::method_record *rec)
+static void parse_method_string(MemoryManager& _mm, char *str, Method_Table::method_record
*rec)
 {
     int i;
     int len = (int) strlen(str);
@@ -165,7 +151,7 @@
     if (is_at_class_method_separator)
     {
         // extract the class
-        rec->class_name = (char *)malloc(i-1 + 1);
+        rec->class_name = new (_mm) char[i-1 + 1];
         strncpy(rec->class_name, str, i-1);
         rec->class_name[i-1] = '\0';
         // skip ahead to the descriptor
@@ -186,7 +172,7 @@
     // we're at the start of the signature, with the method name preceding
     if (i > 0)
     {
-        rec->method_name = (char *)malloc(i+1);
+        rec->method_name = new (_mm) char[i+1];
         strncpy(rec->method_name, str, i);
         rec->method_name[i] = '\0';
     }
@@ -211,16 +197,15 @@
             buf[buflen-1] = '\0';
         if (buf[buflen-2] == '\r') // file generated on NT and used on Linux,
             buf[buflen-2] = '\0';    // this case happens
-        resize_table(_method_table, _mrec_size, _mrec_capacity);
-        parse_method_string(buf, &_method_table[_mrec_size]);
-        _method_table[_mrec_size].decision = mt_undecided;
-        _mrec_size ++;
+        method_record* rec = new (_mm) method_record();
+        parse_method_string(_mm, buf, rec);
+        _method_table.push_back(rec);
     }
     fclose(file);
     return true;
 }
 
-static bool matches(struct Method_Table::method_record *test_entry,
+static bool matches(Method_Table::method_record *test_entry,
                     const char *class_name, const char *method_name, const char *signature)
 {
     if (test_entry->class_name != NULL && strcmp(test_entry->class_name, class_name)
!= 0)
@@ -315,49 +300,48 @@
         {
             _default_decision = mt_rejected;
         }
-        if (rangestr[0] >= '0' && rangestr[0] <= '9')
-        {
+        if (rangestr[0] >= '0' && rangestr[0] <= '9') {
             // look for a range of numbers
             sscanf(rangestr, "%d", &start);
             end = start;
-            while (rangestr[0] != '\0' && rangestr[0] != '-')
+            while (rangestr[0] != '\0' && rangestr[0] != '-') {
                 rangestr ++;
-            if (rangestr[0] == '-')
+            }
+            if (rangestr[0] == '-') {
                 sscanf(rangestr+1, "%d", &end);
+            }
             start --;
-            if (start < 0)
+            if (start < 0) {
                 start = 0;
+            }
             end --;
-            for (i=start; i<=end && i<_mrec_size; i++)
-            {
-                _method_table[i].decision = (opposite ? mt_rejected : mt_accepted);
+            for (i=start; i<=end && i<(int)_method_table.size(); i++) {
+                _method_table[i]->decision = (opposite ? mt_rejected : mt_accepted);
             }
-        }
-        else
-        {
-            resize_table(_decision_table, _dtable_size, _dtable_capacity);
-            parse_method_string(rangestr, &_decision_table[_dtable_size]);
-            _decision_table[_dtable_size].decision = (opposite ? mt_rejected : mt_accepted);
-            _dtable_size ++;
+        } else {
+            method_record* rec = new (_mm) method_record();
+            parse_method_string(_mm, rangestr, rec);
+            rec->decision = (opposite ? mt_rejected : mt_accepted);
+            _decision_table.push_back(rec);
         }
     }
 
-    // change all "undecided" to default_decision
-    for (i=0; i<_mrec_size; i++)
-        if (_method_table[i].decision == mt_undecided)
-            _method_table[i].decision = _default_decision;
+    // change all "undecided" to default decision
+    for (i=0; i<(int)_method_table.size(); i++) {
+        if (_method_table[i]->decision == mt_undecided) {
+            _method_table[i]->decision = _default_decision;
+        }
+    }
     
 }
 
-Method_Table::Method_Table(const char *default_envvar,
+Method_Table::Method_Table(MemoryManager& memManager, 
+                           const char *default_envvar,
                            const char *envvarname,
                            bool accept_by_default):
-  _method_table     (NULL),
-  _mrec_size        (0),
-  _mrec_capacity    (0),
-  _decision_table   (NULL),
-  _dtable_size      (0),
-  _dtable_capacity  (0),
+  _mm(memManager),
+  _method_table     (_mm),
+  _decision_table   (_mm),
   _default_decision (mt_accepted),
   _accept_all       (false),
   _dump_to_file     (false),
@@ -394,22 +378,20 @@
     }
 
     // First look through the decision_table strings.
-    for (i=0; i<_dtable_size; i++)
+    for (i=0; i<(int)_decision_table.size(); i++)
     {
-        if (matches(&_decision_table[i], classname, methodname, signature))
-            return (_decision_table[i].decision == mt_accepted);
+        if (matches(_decision_table[i], classname, methodname, signature)) {
+            return (_decision_table[i]->decision == mt_accepted);
+        }
     }
 
     // Then look through the method table.
-    for (i=0; i<_mrec_size; i++)
-    {
-    if (
-        (_method_table[i].class_name==NULL || !strcmp(_method_table[i].class_name, classname))
&&
-        (_method_table[i].method_name==NULL || !strcmp(_method_table[i].method_name, methodname))
&&
-        (_method_table[i].signature==NULL || matching_signature(_method_table[i].signature,
signature))
-       )
+    for (i=0; i<(int)_method_table.size(); i++) {
+        if ((_method_table[i]->class_name==NULL || !strcmp(_method_table[i]->class_name,
classname)) &&
+            (_method_table[i]->method_name==NULL || !strcmp(_method_table[i]->method_name,
methodname)) &&
+            (_method_table[i]->signature==NULL || matching_signature(_method_table[i]->signature,
signature)))
         {
-            return (_method_table[i].decision == mt_accepted);
+            return (_method_table[i]->decision == mt_accepted);
         }
     }
     return (_default_decision == mt_rejected ? false : true);
@@ -419,4 +401,28 @@
     return _dump_to_file;
 }
 
+void Method_Table::add_method_record(const char* className, const char* methodName, const
char* signature, Method_Table::Decision decision, bool copyVals) {
+    method_record* rec = new (_mm) method_record();
+    if (copyVals) {
+        size_t len = strlen(className)+1; //+1 == '\0' char
+        rec->class_name = new (_mm) char[len];
+        strncpy(rec->class_name, className, len);
+        
+        len = strlen(methodName)+1; //+1 == '\0' char
+        rec->method_name= new (_mm) char[len];
+        strncpy(rec->method_name, methodName, len);
+
+        len = strlen(signature)+1; //+1 == '\0' char
+        rec->signature= new (_mm) char[len];
+        strncpy(rec->signature, signature, len);
+    } else {
+        rec->class_name = (char*)className;
+        rec->method_name = (char*)methodName;
+        rec->signature = (char*)signature;
+    }
+    rec->decision = decision;
+    _method_table.push_back(rec);
+}
+
 } //namespace Jitrino 
+

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/methodtable.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/methodtable.h?view=diff&rev=489320&r1=489319&r2=489320
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/methodtable.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/methodtable.h Thu Dec 21 03:05:07 2006
@@ -24,6 +24,9 @@
 #ifndef _JITRINO_METHOD_TABLE_H
 #define _JITRINO_METHOD_TABLE_H
 
+#include "MemoryManager.h"
+#include "Stl.h"
+
 namespace Jitrino {
 
 class MethodDesc;
@@ -31,31 +34,38 @@
 class Method_Table
 {
 public:
-    Method_Table(const char *default_envvar, const char *envvarname, bool accept_by_default);
+    Method_Table(MemoryManager& mm, const char *default_envvar, const char *envvarname,
bool accept_by_default);
     ~Method_Table() {}
+    
     bool accept_this_method(MethodDesc &md);
     bool accept_this_method(const char* classname, const char *methodname, const char *signature);
     bool is_in_list_generation_mode();
-    enum Decision
-    {
+    
+    enum Decision {
         mt_rejected,
         mt_undecided,
         mt_accepted
     };
-    struct method_record
-    {
+
+    class method_record {
+    public:
+        method_record() : class_name(NULL), method_name(NULL), signature(NULL), decision(mt_undecided){}
+        ~method_record(){}
+
         char *class_name;
         char *method_name;
         char *signature;
         Decision decision;
     };
 
+    void add_method_record(const char* className, const char* methodName, const char* signature,
Decision decision, bool copyVals);
     
 private:
-    struct method_record *_method_table;
-    int _mrec_size, _mrec_capacity;
-    struct method_record *_decision_table;
-    int _dtable_size, _dtable_capacity;
+    MemoryManager& _mm;
+
+    typedef StlVector<method_record*> Records;
+    Records _method_table;
+    Records _decision_table;
     Decision _default_decision;
     bool _accept_all;
     bool _dump_to_file;

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.cpp?view=diff&rev=489320&r1=489319&r2=489320
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.cpp Thu Dec 21
03:05:07 2006
@@ -134,7 +134,8 @@
     if(skipMethods == NULL) {
         flags.inlineSkipTable = NULL;
     } else {
-        flags.inlineSkipTable = new Method_Table(strdup(skipMethods), "SKIP_METHODS", true);
+        MemoryManager& mm = Jitrino::getGlobalMM();
+        flags.inlineSkipTable = new (mm) Method_Table(mm, strdup(skipMethods), "SKIP_METHODS",
true);
     }
 
 }

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_defs.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_defs.h?view=diff&rev=489320&r1=489319&r2=489320
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_defs.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_defs.h Thu Dec 21 03:05:07
2006
@@ -408,6 +408,7 @@
 Mnemonic_ADDSS,                         // Add Scalar Single-Precision Floating-Point Values
 Mnemonic_AND,                           // Logical AND
 
+Mnemonic_BSF,                           // Bit scan forward
 Mnemonic_BSR,                           // Bit scan reverse
 
 Mnemonic_CALL,                          // Call Procedure

Modified: harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp?view=diff&rev=489320&r1=489319&r2=489320
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/port/src/encoder/ia32_em64t/enc_tabl.cpp Thu Dec 21 03:05:07
2006
@@ -447,6 +447,12 @@
 END_MNEMONIC()
 
 
+BEGIN_MNEMONIC(BSF, MF_AFFECTS_FLAGS, N)
+BEGIN_OPCODES()
+{OpcodeInfo::all, {0x0F, 0xBC},   {r32, r_m32},   D_U},
+END_OPCODES()
+END_MNEMONIC()
+
 BEGIN_MNEMONIC(BSR, MF_AFFECTS_FLAGS, N)
 BEGIN_OPCODES()
     {OpcodeInfo::all, {0x0F, 0xBD},   {r32, r_m32},   D_U},



Mime
View raw message