Return-Path: Delivered-To: apmail-harmony-commits-archive@www.apache.org Received: (qmail 50086 invoked from network); 21 Dec 2006 11:06:03 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 21 Dec 2006 11:06:03 -0000 Received: (qmail 1787 invoked by uid 500); 21 Dec 2006 11:06:10 -0000 Delivered-To: apmail-harmony-commits-archive@harmony.apache.org Received: (qmail 1773 invoked by uid 500); 21 Dec 2006 11:06:10 -0000 Mailing-List: contact commits-help@harmony.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@harmony.apache.org Delivered-To: mailing list commits@harmony.apache.org Received: (qmail 1764 invoked by uid 99); 21 Dec 2006 11:06:10 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 21 Dec 2006 03:06:10 -0800 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 21 Dec 2006 03:06:01 -0800 Received: by eris.apache.org (Postfix, from userid 65534) id 3A6A61A981A; Thu, 21 Dec 2006 03:05:12 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit 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 -0000 To: commits@harmony.apache.org From: varlax@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20061221110512.3A6A61A981A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 _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 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::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 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},