Index: vm/jitrino/config/em64t/server.emconf =================================================================== --- vm/jitrino/config/em64t/server.emconf (revision 536166) +++ vm/jitrino/config/em64t/server.emconf (working copy) @@ -62,7 +62,7 @@ -XX:jit.SD2_OPT.path=opt_init,translator,optimizer,hir2lir,codegen --XX:jit.SD2_OPT.path.optimizer=ssa,simplify,dce,uce,devirt_virtual,edge_annotate,unguard,devirt_intf,inline,uce,purge,simplify,dce,uce,so2-,simplify,dce,uce,escape,hvn,dce,uce,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,fastArrayFill,statprof,markglobals +-XX:jit.SD2_OPT.path.optimizer=ssa,simplify,dce,uce,devirt_virtual,edge_annotate,unguard,devirt_intf,inline,uce,purge,simplify,dce,uce,so2-,simplify,dce,uce,escape,dce,uce,hvn,dce,uce,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,fastArrayFill,statprof,markglobals -XX:jit.SD2_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l-,early_prop-,itrace-,native,cg_fastArrayFill,constraints,dce2,regalloc,spillgen,layout,copy,rce-,stack,break-,iprof-,emitter!,si_insts,gcmap,info,unlock_method -XX:jit.SD2_OPT.path.dce1=cg_dce -XX:jit.SD2_OPT.path.dce2=cg_dce Index: vm/jitrino/src/optimizer/escanalyzer.cpp =================================================================== --- vm/jitrino/src/optimizer/escanalyzer.cpp (revision 536166) +++ vm/jitrino/src/optimizer/escanalyzer.cpp (working copy) @@ -40,10 +40,10 @@ const char* help = " escape flags:\n" " escape.max_level[=0] - max level callee method analysis\n" - " escape.do_sync_removal[={on,OFF}] - do synchronization removal optimization\n" - " escape.do_sync_removal_vc[={ON,off}] - do synchronization removal optimization\n" + " escape.do_sync_removal[={on,OFF}] - do synchonization removal optimization\n" + " escape.do_sync_removal_vc[={ON,off}] - do synchonization removal optimization\n" " for virtual call escaped operands\n" - " escape.do_sync_removal_sm[={ON,off}] - do synchronization removal optimization\n" + " escape.do_sync_removal_sm[={ON,off}] - do synchonization removal optimization\n" " for synchronized methods\n" " escape.do_scalar_repl[={ON,off}] - do scalar replacement optimization for\n" " local and escaped objects\n" @@ -296,25 +296,20 @@ cngEdges=new (eaMemManager) CnGEdges(eaMemManager); // Common part of connection graph (edges) instrExam2(); -#ifdef _DEBUG if (_cngedges) { Log::out() <<"printCnGEdges: "; mh.printFullName(Log::out()); Log::out() << std::endl; printCnGEdges("resulting OUT CnGEdges",Log::out()); } -#endif - setCreatedObjectStates(); -//#ifdef _DEBUG if (_eainfo) { printCreatedObjectsInfo(Log::out()); } -//#endif - saveScannedMethodInfo(); //??? to save states of contained obj, if needed + saveScannedMethodInfo(); // to save states of contained obj, if needed #ifdef _DEBUG if (_cngedges) { @@ -328,14 +323,6 @@ } #endif - if (method_ea_level == 0) { // mark inst that may be optimized -#ifdef _DEBUG - if (_cngedges) - Log::out() <<"+++++++++++++++++ markNotEscInsts()"<< std::endl; -#endif - markNotEscInsts(); - } - if (_cngnodes) { Log::out() <<"printCnGNodes: "; mh.printFullName(Log::out()); @@ -1376,9 +1363,6 @@ } // findCnGNode_fl(Opnd* opnd, uint32 ntype) -/** - * Creates edge if it doesn't exist yet. - */ void EscAnalyzer::addEdge(CnGNode* cgnfrom, CnGNode* cgnto, uint32 etype, Inst* inst) { @@ -1861,7 +1845,6 @@ continue; for (it2 = (*it)->outEdges->begin( ); it2 != (*it)->outEdges->end( ); it2++ ) { cgn = (*it2)->cngNodeTo; - // rs = getSubobjectStates(cgn); if (getEscState(cgn)<=(rs&ESC_MASK)) rs = getFullState(cgn); } @@ -1954,12 +1937,20 @@ Log::out() <<"--scanGE 4: nodeId " <cngNodeId<<" opId "<opndId <<" state "; printState(cgn); - Log::out() <<" to callee.esc."<< std::endl; + if (cgn->nodeType == NT_OBJECT ) { + Log::out() <<" to gl.esc."<< std::endl; + } else { + Log::out() <<" to callee.esc."<< std::endl; + } Log::out() <<"--scanGE 4: "<< nodeTypeToString(cgn) << cgn->nodeType <<" initNode "<nodeType == NT_OBJECT ) { + setEscState(cgn,GLOBAL_ESCAPE); //objects escaped through defarg - global escape + } else { + setCalleeEscaped(cgn); + } } } } @@ -2267,44 +2258,6 @@ } // checkSubobjectStates(CnGNode* node) -uint32 -EscAnalyzer::getSubobjectStates(CnGNode* node) { - uint32 st = NO_ESCAPE, rs; - CnGRefs::iterator it; - CnGNode* cgn; - - if (scannedObjs->size()!=0) { - if (checkScannedObjs(node->cngNodeId)) - return st; - } - if (node->outEdges==NULL) - return st; - for (it = node->outEdges->begin( ); it != node->outEdges->end( ); it++ ) { - cgn = (*it)->cngNodeTo; -#ifdef _DEBUG - if (_setState) { - Log::out() <<"--getSOS : node " - <cngNodeId<<" opndId "<opndId <<" state "; - printState(cgn); - Log::out() << std::endl; - } -#endif - if (st > getEscState(cgn)) - st = getEscState(cgn); - if (st == GLOBAL_ESCAPE) - return st; - scannedObjs->push_back(node->cngNodeId); - rs = getSubobjectStates(cgn); - scannedObjs->pop_back(); - if (st > rs) - st = rs; - if (st == GLOBAL_ESCAPE) - return st; - } - return st; -} // getSubobjectStates(CnGNode* node) - - EscAnalyzer::CalleeMethodInfo* EscAnalyzer::findMethodInfo(MethodDesc* mdesc,Inst* callInst) { const char* ch1 = mdesc->getParentType()->getName(); @@ -2449,16 +2402,13 @@ CnGNodes::iterator it; MethodDesc* mdesc = &irManager.getMethodDesc(); MemoryManager& globalMM = irManager.getCurrentJITContext()->getGlobalMemoryManager(); -// MemoryManager& globalMM = eaMemManager; const char* ch1 = mdesc->getParentType()->getName(); const char* ch2 = mdesc->getName(); const char* ch3 = mdesc->getSignatureString(); if (calleeMethodInfos==NULL) { -//std::cout<< "*1****** lock "<push_back(minfo); -//std::cout<< "*2****** unlock "<getNumSrcOperands(); if (scannedObjs->size()!=0) { if (checkScannedObjs(inst->getId())) { -#ifdef _DEBUG if (_seinfo || _scinfo) { Log::out() << "instId " << inst->getId() << " . . . " << std::endl; } -#endif return; } } -#ifdef _DEBUG if (_seinfo || _scinfo) { Log::out() << text; inst->print(Log::out()); Log::out() << std::endl; } -#endif if (inst->getOpcode()==Op_DirectCall || inst->getOpcode()==Op_IndirectMemoryCall) { Opnd *returnOpnd = inst->getDst(); if (returnOpnd != NULL) { CnGNode* n = findCnGNode_op(returnOpnd->getId()); if (n != NULL) { -#ifdef _DEBUG if (_seinfo || _scinfo) { Log::out()<< text << " "; printCnGNode(n,Log::out()); Log::out()<< std::endl; } -#endif } } if (inst->getOpcode()==Op_IndirectMemoryCall) { -#ifdef _DEBUG MethodDesc* md; if (inst->getSrc(0)->getInst()->getOpcode()== Op_LdVar) { md = inst->getSrc(0)->getType()->asMethodPtrType()->getMethodDesc(); @@ -2998,7 +2928,6 @@ md->printFullName(Log::out() ); Log::out() << std::endl; } -#endif } return; } @@ -3006,13 +2935,11 @@ Opnd *dst = inst->getDst(); CnGNode* n = findCnGNode_op(dst->getId()); if (n != NULL) { -#ifdef _DEBUG if (_seinfo || _scinfo) { Log::out()<< text << " "; printCnGNode(n,Log::out()); Log::out()<< std::endl; } -#endif } } switch (inst->getOpcode()) { @@ -3024,15 +2951,11 @@ { CnGNode* n = findCnGNode_in(inst->getId()); if (n != NULL) { -#ifdef _DEBUG if (_seinfo || _scinfo) { Log::out() << text << " "; printCnGNode(n,Log::out() ); Log::out() << std::endl; - // if (getEscState(n) == GLOBAL_ESCAPE) - // return; } -#endif } break; } @@ -3040,138 +2963,36 @@ break; } scannedObjs->push_back(inst->getId()); - for (uint32 i=0; igetSrc(i)->getInst(); - printOriginObject(inst1,text+" "); - } - scannedObjs->pop_back(); -} // printOriginObject(Inst* inst,std::string text) - - -void -EscAnalyzer::printOriginObject1(Inst* inst,std::string text) { - Inst* inst1; - uint32 nsrc=inst->getNumSrcOperands(); - - if (scannedObjs->size()!=0) { - if (checkScannedObjs(inst->getId())) { - if (_seinfo || _scinfo) { - Log::out() << "instId " << inst->getId() - << " . . . " << std::endl; - } - return; + if (all) { + for (uint32 i=0; igetSrc(i)->getInst(); + printOriginObjects(inst1,true,text+" "); } - } - if (_seinfo || _scinfo) { - Log::out() << text; - inst->print(Log::out()); - Log::out() << std::endl; - } - if (inst->getOpcode()==Op_DirectCall || inst->getOpcode()==Op_IndirectMemoryCall) { - Opnd *returnOpnd = inst->getDst(); - if (returnOpnd != NULL) { - CnGNode* n = findCnGNode_op(returnOpnd->getId()); - if (n != NULL) { - if (_seinfo || _scinfo) { - Log::out()<< text << " "; - printCnGNode(n,Log::out()); - Log::out()<< std::endl; + } else { + switch (inst->getOpcode()) { + case Op_TauLdInd: // ldind + case Op_AddScaledIndex: // addindex + inst1 = inst->getSrc(0)->getInst(); + printOriginObjects(inst1,false,text+" "); + break; + case Op_TauStInd: // stind + for (uint32 i=0; i<2; i++) { + inst1 = inst->getSrc(i)->getInst(); + printOriginObjects(inst1,false,text+" "); } - } - } - if (inst->getOpcode()==Op_IndirectMemoryCall) { - MethodDesc* md; - if (inst->getSrc(0)->getInst()->getOpcode()== Op_LdVar) { - md = inst->getSrc(0)->getType()->asMethodPtrType()->getMethodDesc(); - } else { - md = inst->getSrc(0)->getInst()->asMethodInst()->getMethodDesc(); - } - if (_seinfo || _scinfo) { - Log::out() << text << " "; - md->printFullName(Log::out() ); - Log::out() << std::endl; - } - } - return; - } - if (inst->getOpcode()==Op_TauLdInd || inst->getOpcode()==Op_LdVar) { // ldind,ldvar - Opnd *dst = inst->getDst(); - CnGNode* n = findCnGNode_op(dst->getId()); - if (n != NULL) { - if (_seinfo || _scinfo) { - Log::out()<< text << " "; - printCnGNode(n,Log::out()); - Log::out()<< std::endl; - } - } - } - switch (inst->getOpcode()) { - case Op_LdRef: // ldref - case Op_NewObj: // newobj - case Op_NewArray: // newarray - case Op_NewMultiArray: // newmultiarray - case Op_DefArg: // defarg - { - CnGNode* n = findCnGNode_in(inst->getId()); - if (n != NULL) { - if (_seinfo || _scinfo) { - Log::out() << text << " "; - printCnGNode(n,Log::out() ); - Log::out() << std::endl; + break; + default: + for (uint32 i=0; igetSrc(i)->getInst(); + printOriginObjects(inst1,false,text+" "); } - } - break; } - default: - break; } - scannedObjs->push_back(inst->getId()); - switch (inst->getOpcode()) { - case Op_TauLdInd: // ldind - case Op_AddScaledIndex: // addindex - inst1 = inst->getSrc(0)->getInst(); - printOriginObject1(inst1,text+" "); - break; - case Op_TauStInd: // stind - for (uint32 i=0; i<2; i++) { - inst1 = inst->getSrc(i)->getInst(); - printOriginObject1(inst1,text+" "); - } - break; - default: - for (uint32 i=0; igetSrc(i)->getInst(); - printOriginObject1(inst1,text+" "); - } - } scannedObjs->pop_back(); -} // printOriginObject1(Inst* inst,std::string text) +} // printOriginObjects(Inst* inst, bool all, std::string text) void -EscAnalyzer::printMethodInfos() { - CalleeMethodInfos::iterator it1; - ParamInfos::iterator it2; - Log::out() << "==== debug ===== calleeMethodInfos; " << std::endl; - if (calleeMethodInfos==NULL) - Log::out() << " calleeMethodInfos is NULL " << std::endl; - if (calleeMethodInfos!=NULL) - for (it1 = calleeMethodInfos->begin( ); it1 != calleeMethodInfos->end( ); it1++) { - Log::out() << (*it1)->methodIdent->parentName << " "; - Log::out() << (*it1)->methodIdent->name << " "; - Log::out() << (*it1)->methodIdent->signature << " "; - Log::out() << (*it1)->numberOfArgs<< " " << std::endl; - for (it2 = (*it1)->paramInfos->begin( ); - it2 != (*it1)->paramInfos->end( ); it2++) { - Log::out() << (*it2)->paramNumber << " st." - << (*it2)->state << std::endl; - } - } - Log::out() << "==== end ===== calleeMethodInfos; " << std::endl; -} // printMethodInfos() - - -void EscAnalyzer::printMethodInfo(CalleeMethodInfo* mi) { ParamInfos::iterator it2; Log::out() << "==== debug ===== calleeMethodInfo " << std::endl; @@ -3424,11 +3245,6 @@ } // addMonUnitVCall(MonUnit* mu, Inst* inst) -/** - * Checks, that method contains monitor instructions with parameter - * which is this or subobject of this. - * Returns: true, if such monitors exist, false overwise. - */ bool EscAnalyzer::checkMonitorsOnThis() { MonInstUnits::iterator it; @@ -3451,11 +3267,10 @@ if (opndInst->getOpcode()==Op_DefArg && opndInst->getDefArgModifier()==NonNullThisArg) { #ifdef _DEBUG if (_seinfo) { - Log::out() << " checkMOT: "; - Log::out() << (int)(opndInst->getDefArgModifier()) << " " << - (opndInst->getDefArgModifier()==DefArgNoModifier) << " " << - (opndInst->getDefArgModifier()==NonNullThisArg) << " " << - (opndInst->getDefArgModifier()==DefArgBothModifiers) << " state: "; + Log::out() << " checkMOT: " << (int)(opndInst->getDefArgModifier()) << " " + << (opndInst->getDefArgModifier()==DefArgNoModifier) << " " + << (opndInst->getDefArgModifier()==NonNullThisArg) << " " + << (opndInst->getDefArgModifier()==DefArgBothModifiers) << " state: "; printState(node,Log::out()); Log::out() << std::endl; if (getEscState(node) != GLOBAL_ESCAPE) { @@ -3566,19 +3381,8 @@ } } #endif -#ifdef _DEBUG - if (getEscState(node) == GLOBAL_ESCAPE) - checkSencEscState(node,syncInsts); -#endif if (getVirtualCall(node)!=0) { if (checkedState > GLOBAL_ESCAPE && do_sync_removal_vc) { -/* if (!checkSencEscState(node,syncInsts)) { - if (_seinfo) { - Log::out() << "=-=- cannot be optimized" << std::endl; - printCnGNode(node,Log::out()); Log::out() << std::endl; - } - continue; - }*/ uint32 bs_size = irManager.getFlowGraph().getMaxNodeId(); if (fgnodes.getSetSize() < bs_size) { fgnodes.resizeClear(bs_size); @@ -3589,24 +3393,24 @@ #ifdef _DEBUG if (_seinfo) { Log::out() << "=-=- vc loc.esc." << std::endl; - printOriginObject(node->nInst); + printOriginObjects(node->nInst,false); scannedObjs->clear(); } #endif if (node->nodeType==NT_OBJECT) { -#ifdef _DEBUG if (_seinfo) { - Log::out() << "=-=- vc to optimize object" << std::endl; + Log::out() << "=-=- vc to optimize object "; + node->nInst->print(Log::out()); + Log::out() << std::endl; } -#endif fixMonitorInstsVCalls(*it,&fgnodes); } if (node->nodeType==NT_RETVAL) { -#ifdef _DEBUG if (_seinfo) { - Log::out() << "=-=- vc to optimize retval" << std::endl; + Log::out() << "=-=- vc to optimize retval "; + node->nInst->print(Log::out()); + Log::out() << std::endl; } -#endif fixMonitorInstsVCalls(*it,&fgnodes); } to_fix_ssa = true; @@ -3614,28 +3418,24 @@ #ifdef _DEBUG if (_seinfo && do_sync_removal_vc) { Log::out() << "=-=- vc gl.esc." << std::endl; - printOriginObject(node->nInst); + printOriginObjects(node->nInst,false); scannedObjs->clear(); } #endif } } else { if (node->nodeType==NT_OBJECT && getEscState(node) != GLOBAL_ESCAPE) { -#ifdef _DEBUG if (_seinfo) { Log::out() << "++++ to optimize (remove) object" << std::endl; } -#endif removeMonitorInsts(syncInsts); } if (node->nodeType==NT_DEFARG && getEscState(node) != GLOBAL_ESCAPE && node->nInst->getDefArgModifier()==NonNullThisArg && mh.isSynchronized()) { -#ifdef _DEBUG if (_seinfo) { Log::out() << "++++ to optimize (fix) defarg.ths" << std::endl; } -#endif #ifndef PLATFORM_POSIX if (do_sync_removal_sm) { fixSyncMethodMonitorInsts(syncInsts); @@ -3746,13 +3546,6 @@ } // markLockedNodes2(BitSet* bs, Insts* syncInsts) -/** - * Checks state for NT_LDOBJ nodes. - * Returns - * GLOBAL_ESCAPE - for global escaped NT_OBJECT, NT_RETVAL, NT_DEFARG - * node state - for not global escaped NT_OBJECT - * 0 - for not global escaped ?NT_RETVAL, NT_DEFARG - */ uint32 EscAnalyzer::checkState(Inst* inst,uint32 st) { uint32 st1; @@ -3831,238 +3624,7 @@ } // checkState(Inst* inst,uint32 st) -bool -EscAnalyzer::checkSencEscState(CnGNode* node,Insts* syncInsts) { - CnGEdges::iterator it; - Insts::iterator it1; - CnGRefs::iterator it2; - Inst* einst; - bool pLocalObj = true; - bool pLocalCurObj = false; -#ifdef _DEBUG - if (_seinfo) { - Log::out() << "=- to node " << node->cngNodeId - << std::endl; - } -#endif - scannedSucNodes->clear(); // prepared for successor collection - for (it = cngEdges->begin( ); it != cngEdges->end( ); it++ ) { - for (it2 = (*it)->refList->begin( ); it2 != (*it)->refList->end( ); it2++ ) { - if ((*it2)->cngNodeTo == node) { - pLocalCurObj = false; - einst = (*it2)->edgeInst; -#ifdef _DEBUG - if (_seinfo) { - Log::out() << "=- "; - Log::out() << einst->getNode()->getId() << " "; - FlowGraph::printLabel(Log::out(),einst->getNode()); - Log::out() << " "; einst->print(Log::out()); - Log::out() << std::endl; - } -#endif - if (einst->getOpcode() == Op_DirectCall) { - MethodDesc* md=einst->asMethodInst()->getMethodDesc(); - const char* ch1 = md->getParentType()->getName(); - const char* ch2 = md->getName(); - const char* ch3 = md->getSignatureString(); - CalleeMethodInfo* mtdInfo = getMethodInfo(ch1,ch2,ch3); - if (mtdInfo==NULL) { -#ifdef _DEBUG - if (_seinfo) { - Log::out() << "=- Methodinfo is NULL"; - Log::out() << std::endl; - } -#endif - } else { - uint32 st = getMethodParamState(mtdInfo,(*it)->cngNodeFrom->argNumber); -#ifdef _DEBUG - if (_seinfo) { - Log::out() << "=-=- Method param " - << (*it)->cngNodeFrom->argNumber << " state is "; - printState(st); - Log::out() << std::endl; - } -#endif - if ((st&ESC_MASK)>GLOBAL_ESCAPE) { - pLocalCurObj = true; -#ifdef _DEBUG - if (_seinfo) { - Log::out() << "=- Method param " - << (*it)->cngNodeFrom->argNumber << " state is "; - printState(st); - Log::out() << std::endl; - } -#endif - } else { -#ifdef _DEBUG - if (_seinfo) { - printMethodInfo(mtdInfo); - } -#endif - } - } - } - if (_seinfo) { - printOriginObject1(einst); - } - collectSuccessors(einst->getNode()); - } - } - for (it1 = syncInsts->begin(); it1 != syncInsts->end( ); it1++ ) { - if (scannedSucNodes->size()!=0) { - if (checkScannedSucNodes((*it1)->getNode()->getId())!=0) { -#ifdef _DEBUG - if (_seinfo) { - if (pLocalCurObj) - Log::out() << " "; - Log::out() << "=- contains " - << (*it1)->getNode()->getId() << " "; - FlowGraph::printLabel(Log::out(),(*it1)->getNode()); - Log::out() << std::endl; - } -#endif - if (!pLocalCurObj) - pLocalObj = false; - } - } - } - scannedSucNodes->clear(); - } -#ifdef _DEBUG - if (_seinfo) { - if (pLocalObj) { - Log::out() << "=- may be optimized" - << std::endl; - } - } -#endif - return pLocalObj; -} // checkSencEscState(CnGNode* node,Insts* syncInsts) - - -/** - * Collect all reachable from specified node nodes in FlowGraph. - * scannedSucNodes - result of collection. - */ void -EscAnalyzer::collectSuccessors(Node* node) { - Node* n; - Edges::const_iterator eit; - const Edges& out_edges = node->getOutEdges(); - if (scannedSucNodes->size()!=0) { - if (checkScannedSucNodes(node->getId())!=0) { - return; - } - } - scannedSucNodes->push_back(node->getId()); - for (eit = out_edges.begin(); eit != out_edges.end(); ++eit) { - n = (*eit)->getTargetNode(); - collectSuccessors(n); - } -} // collectSuccessors(Node* node) - - -void -EscAnalyzer::collectGlobalNodeSuccessors(CnGNode* node) { - CnGEdges::iterator it; - CnGRefs::iterator it2; - Inst* einst; - bool pGlobalObj = false; -#ifdef _DEBUG - if (_seinfo) { - Log::out() << "=- to node " << node->cngNodeId - << std::endl; - } -#endif - scannedSucNodes->clear(); // prepared for successor collection - for (it = cngEdges->begin( ); it != cngEdges->end( ); it++ ) { - for (it2 = (*it)->refList->begin( ); it2 != (*it)->refList->end( ); it2++ ) { - if ((*it2)->cngNodeTo == node) { - pGlobalObj = false; - einst = (*it2)->edgeInst; -#ifdef _DEBUG - if (_seinfo) { - Log::out() << "=-ggns "; - Log::out() << einst->getNode()->getId() - << " "; - einst->print(Log::out()); - Log::out() << std::endl; - } -#endif - if (einst->getOpcode() == Op_DirectCall) { - MethodDesc* md=einst->asMethodInst()->getMethodDesc(); - const char* ch1 = md->getParentType()->getName(); - const char* ch2 = md->getName(); - const char* ch3 = md->getSignatureString(); - CalleeMethodInfo* mtdInfo = getMethodInfo(ch1,ch2,ch3); - if (mtdInfo==NULL) { - pGlobalObj = true; -#ifdef _DEBUG - if (_seinfo) { - Log::out() << "ggns=- Methodinfo is NULL"; - Log::out() << std::endl; - } -#endif - } else { - uint32 st = getMethodParamState(mtdInfo,(*it)->cngNodeFrom->argNumber); -#ifdef _DEBUG - if (_seinfo) { - Log::out() << "ggns=-=- Method param " - << (*it)->cngNodeFrom->argNumber << " state is "; - printState(st); - Log::out() << std::endl; - } -#endif - if ((st&ESC_MASK)<=GLOBAL_ESCAPE) { - pGlobalObj = true; -#ifdef _DEBUG - if (_seinfo) { - Log::out() << "ggns=- Method param " - << (*it)->cngNodeFrom->argNumber << " state is "; - printState(st); - Log::out() << std::endl; - } -#endif - } - } - } - if (einst->getOpcode() == Op_IndirectMemoryCall) - pGlobalObj = true; - if (einst->getOpcode() == Op_TauStInd) { - Inst* i1 = einst->getSrc(0)->getInst(); - if (i1->getOpcode()==Op_LdStaticAddr) - pGlobalObj = true; - uint32 st = getContainingObjState(i1); - if ((st&ESC_MASK)<=GLOBAL_ESCAPE) { - pGlobalObj = true; - } - } - printOriginObject1(einst); - if (pGlobalObj) - collectSuccessors(einst->getNode()); - } - } - } -} // collectGlobalNodeSuccessors(CnGNode* node) - - -uint32 -EscAnalyzer::getContainingObjState(Inst* linst) { - Opnd* cop = NULL; - if (linst->getOpcode()==Op_LdStaticAddr) - return GLOBAL_ESCAPE; - if (linst->getOpcode()==Op_LdFieldAddr || linst->getOpcode()==Op_LdArrayBaseAddr) - cop = linst->getSrc(0); - if (linst->getOpcode()==Op_AddScaledIndex) - cop = linst->getSrc(0)->getInst()->getSrc(0); - else - return GLOBAL_ESCAPE; - CnGNode* n = findCnGNode_op(cop->getId()); - return n->state; -} // getContainingObjState(Inst* linst) - - -void EscAnalyzer::fixMonitorInstsVCalls(MonUnit* mu, BitSet* bs) { Inst* opi = findCnGNode_op(mu->opndId)->nInst; OpndManager& _opndManager = irManager.getOpndManager(); @@ -4082,7 +3644,6 @@ #ifdef _DEBUG Node* entry_node = fg.getEntryNode(); Node* muo_node = opi->getNode(); -// Node* node; #endif // values 0 and 1 to set flag variable @@ -4101,7 +3662,7 @@ } #endif - // insert flag=0 after monitor instruction opnd creation instruction + // insert flag=0 before monitor instruction source opnd creation instruction #ifdef _DEBUG if (_seinfo) { Log::out() << "=-=- w1 Before " << std::endl; @@ -4128,7 +3689,6 @@ addedMonNode = NULL; newCallNode = NULL; #ifdef _DEBUG - // node = (*inst_it)->getNode(); if (_seinfo) { Log::out() << "=-=- w2 Before " << std::endl; FlowGraph::print(Log::out(),oldCallNode); @@ -4179,14 +3739,9 @@ insertFlagCheck(syncInsts,muflag,0); -} // fixMonitorInstsVCalls(MonUnit* mu) +} // fixMonitorInstsVCalls(MonUnit* mu, BitSet* bs) -/** - * Inserts flag check before monitor instruction. - * If flag = i32_chk value monitor instruction isn't executed. - * Operand flag may be VarOpnd* or SsaTmpOpnd* type. - */ void EscAnalyzer::insertFlagCheck(Insts* syncInsts, Opnd* muflag, uint32 chk) { Insts::iterator inst_it; @@ -4316,13 +3871,11 @@ #endif reminst->unlink(); -#ifdef _DEBUG if (_seinfo) { Log::out() << " unlinked: "; reminst->print(Log::out()); Log::out() << std::endl; } -#endif if (targetnode != NULL) { if (targetnode->getInEdges().size() > 1) { fg.removeEdge(excedge); @@ -4491,12 +4044,11 @@ aanode = node->outEdges->front()->cngNodeTo; if (!isGlobalState(aanode->state)&& (aanode->nodeType==NT_OBJECT||aanode->nodeType==NT_RETVAL)) { -#ifdef _DEBUG if (_seinfo) { - Log::out() - << "=-=- sm this.agr.saving" << std::endl; + Log::out() << "=-=- sm this.agr.saving for "; + node->nInst->print(Log::out()); + Log::out() << std::endl; } -#endif insertLdConst(1); insertSaveJitHelperCall(node->nInst,i32_1); #ifdef _DEBUG @@ -4522,9 +4074,9 @@ void EscAnalyzer::insertSaveJitHelperCall(Inst* inst_before, SsaTmpOpnd* stVal) { - - ControlFlowGraph& fg = irManager.getFlowGraph(); Node* oldBlock = inst_before->getNode(); + ControlFlowGraph& fg = irManager.getFlowGraph(); + #ifdef _DEBUG Node* icBlock = stVal->getInst()->getNode(); if (_seinfo) { @@ -5045,11 +4597,13 @@ } double path_prob = -1; path_prob = checkLocalPath(onode->nInst); - os_sc<<"pp " << (path_prob )<nInst); + printOriginObjects(onode->nInst,false); } #endif if (onode->nInst->getOpcode() != Op_LdVar) { @@ -5200,11 +4754,9 @@ } } TypeManager& _typeManager = irManager.getTypeManager(); - Type* typeInt32 = _typeManager.getInt32Type(); Inst* nobj_inst = nonode->nInst; // optimized newobj inst for ldvar opnd Inst* lobj_inst = NULL; // load opnd inst for ldvar opnd Edge* excedge = NULL; - VarOpnd* ob_flag_opnd = _opndManager.createVarOpnd(typeInt32, false); VarOpnd* ob_var_opnd = _opndManager.createVarOpnd(nobj_inst->getDst()->getType(), false); SsaTmpOpnd* ob_init_opnd = _opndManager.createSsaTmpOpnd(ob_var_opnd->getType()); uint32 ob_id = onode->opndId; @@ -5214,9 +4766,6 @@ Node* node_no = nobj_inst->getNode(); ScObjFld* sco = NULL; - insertLdConst(1); - insertLdConst(0); - if (nobj_inst->getOperation().canThrow()==true) { excedge = (Edge*)nobj_inst->getNode()->getExceptionEdge(); assert(excedge != NULL); @@ -5309,8 +4858,7 @@ scalarizeOFldUsage(sco); } } - restoreEOCreation(vc_insts, scObjFlds, ob_var_opnd, ob_flag_opnd, - ob_exc_tnode, ob_id); + restoreEOCreation(vc_insts, scObjFlds, ob_var_opnd, ob_exc_tnode, ob_id); if (_scinfo) { os_sc << "++++ old newobj: before" << std::endl; FlowGraph::print(os_sc,node_no); @@ -5321,11 +4869,9 @@ os_sc << "++++ old ldobj: before end" << std::endl; } } - _instFactory.makeStVar(ob_flag_opnd, i32_0)->insertBefore(nobj_inst); _instFactory.makeLdNull(ob_init_opnd)->insertBefore(nobj_inst); _instFactory.makeStVar(ob_var_opnd,ob_init_opnd)->insertBefore(nobj_inst); if (lobj_opt) { - _instFactory.makeStVar(ob_flag_opnd, i32_1)->insertAfter(lonode->nInst); _instFactory.makeStVar(ob_var_opnd,(Opnd*)(lonode->refObj))->insertAfter(lonode->nInst); } if (methodEndInsts->size()!=0) @@ -5931,7 +5477,7 @@ CnGNode* lobj = getLObj(vnode); // scalarizable load object if (lobj != NULL) { if (_scinfo) { - printOriginObject1(lobj->nInst," "); + printOriginObjects(lobj->nInst,false," "); } bool notnullsrcs = checkVVarSrcs(lobj->nInst); if (_scinfo) { @@ -6146,7 +5692,7 @@ void EscAnalyzer::restoreEOCreation(Insts* vc_insts, ScObjFlds* scObjFlds, VarOpnd* ob_var_opnd, - VarOpnd* ob_flag_var_opnd, Node* tnode, uint32 oid) { + Node* tnode, uint32 oid) { Insts::iterator itvc; InstFactory& _instFactory = irManager.getInstFactory(); ControlFlowGraph& fg = irManager.getFlowGraph(); @@ -6161,7 +5707,6 @@ ScObjFlds::iterator ito; const bool splitAfter = true; SsaTmpOpnd* ob_opnd = NULL; - Opnd* ld_tau_op = NULL; for (itvc = vc_insts->begin( ); itvc != vc_insts->end( ); itvc++ ) { Inst* vc = *itvc; @@ -6181,7 +5726,7 @@ node_before=vc->getNode(); node_obj1 = NULL; node_after1 = NULL; - ld_tau_op = NULL; + node_var1 = NULL; if (_scinfo) { os_sc << "++++ objectCreate: before" << std::endl; FlowGraph::print(os_sc,node_before); @@ -6256,16 +5801,13 @@ // storing created newobj result in object var opnd Inst* stvobj=_instFactory.makeStVar(ob_var_opnd,nob_opnd); stvobj->insertBefore(ldobj); - // resetting ob_flag_var_opnd to 1 (object created) - Inst* stvflag=_instFactory.makeStVar(ob_flag_var_opnd, i32_1); - stvflag->insertBefore(ldobj); // node with call inst after opt - node_var=fg.splitNodeAtInstruction(stvflag,splitAfter,false,_instFactory.makeLabel()); - // checkinf flag: if object created goto node_var node - SsaTmpOpnd* ob_flag_opnd = _opndManager.createSsaTmpOpnd(ob_flag_var_opnd->getType()); - _instFactory.makeLdVar(ob_flag_opnd,ob_flag_var_opnd)->insertBefore(newobj); - Inst* branch_inst = _instFactory.makeBranch(Cmp_EQ, Type::Int32, - ob_flag_opnd, i32_1, (LabelInst*)(node_var->getFirstInst())); + node_var=fg.splitNodeAtInstruction(stvobj,splitAfter,false,_instFactory.makeLabel()); + // checking, if the object is created goto node_var node + SsaTmpOpnd* ob_opnd_as_flag = _opndManager.createSsaTmpOpnd(ob_var_opnd->getType()); + _instFactory.makeLdVar(ob_opnd_as_flag,ob_var_opnd)->insertBefore(newobj); + Inst* branch_inst = _instFactory.makeBranch(Cmp_NonZero, ob_opnd_as_flag->getType()->tag, + ob_opnd_as_flag, (LabelInst*)(node_var->getFirstInst())); branch_inst->insertBefore(newobj); // node with newobj instruction after opt node_obj=fg.splitNodeAtInstruction(branch_inst,splitAfter,false,_instFactory.makeLabel()); @@ -6273,8 +5815,8 @@ // created oject field initialization ScObjFld* sco = NULL; if (scObjFlds->size() > 0) { - Opnd* st_tau_op = _opndManager.createSsaTmpOpnd(_typeManager.getTauType()); - _instFactory.makeTauUnsafe(st_tau_op)->insertBefore(stvobj); + Opnd* tau_op = _opndManager.createSsaTmpOpnd(_typeManager.getTauType()); + _instFactory.makeTauUnsafe(tau_op)->insertBefore(branch_inst); for (ito = scObjFlds->begin( ); ito != scObjFlds->end( ); ito++ ){ sco = (*ito); if (sco->ls_insts->size()==0) { @@ -6302,35 +5844,42 @@ (Modifier(Store_WriteBarrier)|compressMod) : (Modifier(Store_NoWriteBarrier)|compressMod); SsaTmpOpnd* fl_tmp_opnd_st = _opndManager.createSsaTmpOpnd(type); - _instFactory.makeLdVar(fl_tmp_opnd_st, sco->fldVarOpnd)->insertBefore(stvobj); + Inst* ldflvar_inst = _instFactory.makeLdVar(fl_tmp_opnd_st, sco->fldVarOpnd); + if (sco->isFinalFld) { + ldflvar_inst->insertBefore(stvobj); // after newobj + } else { + ldflvar_inst->insertAfter(ldobj); // after ldvar obj_var_opnd + } Opnd* dst = _opndManager.createSsaTmpOpnd(iadr->getDst()->getType()); FieldDesc* fd = iadr->asFieldAccessInst()->getFieldDesc(); - _instFactory.makeLdFieldAddr(dst,nob_opnd,fd)->insertBefore(stvobj); + Inst* ldfladr_inst = NULL; + if (sco->isFinalFld) { + ldfladr_inst = _instFactory.makeLdFieldAddr(dst,nob_opnd,fd); + ldfladr_inst->insertBefore(stvobj); // after newobj + } else { + ldfladr_inst = _instFactory.makeLdFieldAddr(dst,ob_opnd,fd); + ldfladr_inst->insertAfter(ldflvar_inst); // after ldvar ob_var_opnd + } Inst* nstind=_instFactory.makeTauStInd(mod,type->tag, - fl_tmp_opnd_st,dst,st_tau_op,st_tau_op,st_tau_op); - nstind->insertBefore(stvobj); + fl_tmp_opnd_st,dst,tau_op,tau_op,tau_op); if (sco->isFinalFld) { + nstind->insertBefore(stvobj); continue; + } else { + nstind->insertAfter(ldfladr_inst); } - // updating non-final fields after call + // updating non-final field var.opnds after call if (node_after1 == NULL) { - ld_tau_op = _opndManager.createSsaTmpOpnd(_typeManager.getTauType()); - Inst* itau = _instFactory.makeTauUnsafe(ld_tau_op); node_after1=fg.createBlockNode(_instFactory.makeLabel()); - node_after1->appendInst(itau); } - // loading field address - Opnd* dst_ld = _opndManager.createSsaTmpOpnd(iadr->getDst()->getType()); - Inst* lda = _instFactory.makeLdFieldAddr(dst_ld,ob_opnd,fd); - node_after1->appendInst(lda); // loading field value SsaTmpOpnd* fl_tmp_opnd_ld = _opndManager.createSsaTmpOpnd(type); bool comprRefs = compressedReferencesArg || (VMInterface::areReferencesCompressed()); Modifier mod1 = comprRefs ? AutoCompress_Yes : AutoCompress_No; - Inst* ldf = _instFactory.makeTauLdInd(mod1,type->tag,fl_tmp_opnd_ld,dst_ld, - ld_tau_op,ld_tau_op); + Inst* ldf = _instFactory.makeTauLdInd(mod1,type->tag,fl_tmp_opnd_ld,dst, + tau_op,tau_op); node_after1->appendInst(ldf); // storing field value in field var opnd Inst* stv = _instFactory.makeStVar(sco->fldVarOpnd,fl_tmp_opnd_ld); @@ -6340,11 +5889,15 @@ if (_scinfo) { os_sc << "!!!! to restore not final fields " << std::endl; } + Node* node_call = node_var; + if (node_var1 != NULL) { + node_call = node_var1; + } // next node after node with call inst - Node* node_after = node_var->getUnconditionalEdgeTarget(); + Node* node_after = node_call->getUnconditionalEdgeTarget(); // inserting node with updating field var opnds - fg.removeEdge(node_var->getUnconditionalEdge()); - fg.addEdge(node_var,node_after1); + fg.removeEdge(node_call->getUnconditionalEdge()); + fg.addEdge(node_call,node_after1); fg.addEdge(node_after1,node_after); } } @@ -6527,11 +6080,6 @@ #endif if (inst->getOpcode()==Op_DirectCall || inst->getOpcode()==Op_IndirectMemoryCall) { -#ifdef _DEBUG - if (_scinfo) { - os_sc << " 6 returns false " << std::endl; - } -#endif return false; } if (nsrc == 0) { @@ -6539,36 +6087,16 @@ FieldDesc* fd = inst->asFieldAccessInst()->getFieldDesc(); const char* ptn = fd->getParentType()->getName(); if (checkObjectType(ptn) && strcmp(fd->getName(),"CACHE")==0 ) { -#ifdef _DEBUG - if (_scinfo) { - os_sc << " 5 returns true " << std::endl; - } -#endif return true; } else { -#ifdef _DEBUG - if (_scinfo) { - os_sc << " 4 returns false " << std::endl; - } -#endif return false; } } if (inst->getOpcode() == Op_NewObj || inst->getOpcode() == Op_NewArray || inst->getOpcode() == Op_NewMultiArray) { -#ifdef _DEBUG - if (_scinfo) { - os_sc << " 3 returns true " << std::endl; - } -#endif return true; } if (inst->getOpcode() == Op_LdRef || inst->getOpcode() == Op_DefArg ) { -#ifdef _DEBUG - if (_scinfo) { - os_sc << " 2 returns false " << std::endl; - } -#endif return false; } } @@ -6702,22 +6230,30 @@ if (_scinfo) { os_sc << "########################" << std::endl; printCnGNode(onode,os_sc); os_sc << std::endl; -// checkOpndUsage(onode->opndId); - // to collect stind & ldind instructions - scObjFlds->clear(); - collectStLdInsts(onode, scObjFlds); - if (scObjFlds->size() != 0) { + } + scObjFlds->clear(); + collectStLdInsts(onode, scObjFlds); + if (scObjFlds->size() != 0) { + if (_scinfo) { os_sc << " used fields: " << scObjFlds->size() << " final fields exist: "; - for (ito = scObjFlds->begin( ); ito != scObjFlds->end( ); ito++ ){ - sco = (*ito); + } + for (ito = scObjFlds->begin( ); ito != scObjFlds->end( ); ito++ ){ + sco = (*ito); + if (_scinfo) { os_sc << sco->isFinalFld << " "; - if (sco->isFinalFld) { - do_fsc = true; - } + } + if (sco->isFinalFld) { + do_fsc = true; + } + if (_scinfo) { os_sc << " field usage : " << sco->ls_insts->size(); } + } + if (_scinfo) { os_sc << std::endl; } + } + if (_scinfo) { if (scObjFlds->size() != 0 && do_fsc) { printCnGNode(onode,os_sc); os_sc << std::endl; os_sc << " ############# try to do" << std::endl; Index: vm/jitrino/src/optimizer/escanalyzer.h =================================================================== --- vm/jitrino/src/optimizer/escanalyzer.h (revision 536166) +++ vm/jitrino/src/optimizer/escanalyzer.h (working copy) @@ -399,15 +399,6 @@ void checkSubobjectStates(CnGNode* node); /** - * Scans connection graph nodes specified NT_EXITVAL node refers to. - * @param node - NT_EXITVAL connection graph node. - * @return GLOBAL_ESCAPE, if any of nodes node reference to is GLOBAL_ESCAPE, otherwise - * ARG_ESCAPE, if any of nodes node reference to is ARG_ESCAPE, otherwise - * NO_ESCAPE. - */ - uint32 getSubobjectStates(CnGNode* node); - -/** * Finds specified method escape analysis information in the common repository and compiles * the method if it is required and possible. * @param md - method description, @@ -537,25 +528,15 @@ void createdObjectInfo(); /** - * Prints origin operands of specified instruction operands. - * @param inst - instruction, + * Prints origin operands of specified instruction. + * @param inst - specified instruction, + * @param all - if true for all source operands of the instruction, + * if false for main source operand of some instructions, * @param text - text to print before the instruction. */ - void printOriginObject(Inst* inst,std::string text=" "); + void printOriginObjects(Inst* inst, bool all, std::string text=" "); /** - * Prints origin operands of specified instruction main operand. - * @param inst - instruction, - * @param text - text to print before the instruction. - */ - void printOriginObject1(Inst* inst,std::string text=" "); - -/** - * Prints escape analysis method information stored in common repository. - */ - void printMethodInfos(); - -/** * Prints escape analysis method information for specified parameter. * @param mi - method info from common repository. */ @@ -745,19 +726,6 @@ void collectSuccessors(Node* node); /** - * Collects global node successors to scannedSucNodes list. - * @param node - CnG node. - */ - void collectGlobalNodeSuccessors(CnGNode* node); - -/** - * Returns state of object containing address for Op_TauStInd instruction. - * @param linst - Op_TauStInd instruction. - * @return object state. - */ - uint32 getContainingObjState(Inst* linst); - -/** * Inserts flag for specified monitor unit. Flag is set to 0 after operand creation instruction. * Flag is set to 1 before call instruction from vcInsts list. * Inserts flag check before monitor instruction from monInsts list. @@ -922,7 +890,7 @@ * Performs checks for CnGNode operand using connection graph. * @param scnode - CnG node of optimized operand * @param check_loc - if true checks for local objects, - * if false checks for virtual call escaped objects. + * if false checks for method call escaped objects. * @return CnGNode* for operand that may be optimized; * NULL otherwise. */ @@ -953,12 +921,11 @@ * @param vc_insts - list of call instructions optimized object is escaped to, * @param objs - list of optimized object fields, * @param ob_var_opnd - varOpnd replacing optimized object, - * @param ob_flag_var_opnd - sign if optimized object was created, * @param tnode - target CFG node for newobj instruction exception edge, * @param oid - escaped optimized object Id. */ void restoreEOCreation(Insts* vc_insts, ScObjFlds* objs, VarOpnd* ob_var_opnd, - VarOpnd* ob_flag_var_opnd, Node* tnode, uint32 oid); + Node* tnode, uint32 oid); /** * Removes specified instruction from ControlFlowGraph. @@ -1025,8 +992,7 @@ void fixCheckInsts(uint32 opId); /** - * Checks (using connection graph) if CnGNode operand has final fields and adds it to - * the list of possible optimized final fields operands. + * Checks (using connection graph) if CnGNode operand has final fields and scalarizes them. * @param onode - CnG node of optimized operand, * @param scObjFlds - list to collect onode operand field usage. */