You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by va...@apache.org on 2007/03/15 11:27:24 UTC
svn commit: r518565 [2/3] - in /harmony/enhanced/drlvm/trunk:
src/test/microbenchmark/harmony-2874/ vm/jitrino/config/em64t/
vm/jitrino/config/ia32/ vm/jitrino/src/optimizer/
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp?view=diff&rev=518565&r1=518564&r2=518565
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp Thu Mar 15 03:27:22 2007
@@ -34,12 +34,26 @@
#include "optpass.h"
#include "devirtualizer.h"
#include "DrlVMInterface.h"
+//#include "Windows.h"
namespace Jitrino {
+const char* help =
+ " escape flags:\n"
+ " escape.max_level[=0] - max level callee method analysis\n"
+ " escape.do_sync_removal[={on,OFF}] - do synchonization removal optimization\n"
+ " escape.do_scalar_repl[={ON,off}] - do scalar replacement optimization for\n"
+ " local and escaped objects\n"
+ " escape.do_esc_scalar_repl[={ON,off}] - scalar replacement for escaped objects\n"
+ " escape.do_scalar_repl_only_final_fields[={on,OFF}] \n"
+ " escape.scalarize_final_fields[={on,OFF}] - scalarize final field usage when\n"
+ " escaped object wasn't optimized\n"
+ " escape.exec_count_mult[=0] - entry node execCount multiplier\n";
+
DEFINE_SESSION_ACTION(EscapeAnalysisPass, escape, "Escape Analysis")
+
struct ComObjStat {
ComObjStat() :_n0(0), _n_ge(0), _n_ae(0), _n_ne(0), _n_lo(0) {};
uint32 _n0;
@@ -82,29 +96,48 @@
EscAnalyzer::EscAnalyzer(MemoryManager& mm, SessionAction* argSource, IRManager& irm)
-: eaMemManager(mm), irManager(irm), mh(irm.getMethodDesc())
+: eaMemManager(mm), irManager(irm), mh(irm.getMethodDesc()),os_sc(Log::out()),
+ compInterface(irm.getCompilationInterface())
{
maxMethodExamLevel = (uint32)argSource->getIntArg("max_level",maxMethodExamLevel_default);
allProps = (uint32)argSource->getIntArg("d_prop",0);
debug_method = argSource->getStringArg("d_method", NULL);
method_ea_level = 0; // determines level of method scan
-
+ do_sync_removal = argSource->getBoolArg("do_sync_removal",false);
+ do_scalar_repl = argSource->getBoolArg("do_scalar_repl",true);
+ do_esc_scalar_repl = argSource->getBoolArg("do_esc_scalar_repl",true);
+ print_scinfo = argSource->getBoolArg("sc_info",false);
+ execCountMultiplier_string = argSource->getStringArg("exec_count_mult", NULL);
+ ec_mult = ( execCountMultiplier_string==NULL ? 0 : atof(execCountMultiplier_string) );
+ do_scalar_repl_only_final_fields = argSource->getBoolArg("do_scalar_repl_only_final_fields",false);
+ scalarize_final_fields = argSource->getBoolArg("scalarize_final_fields",false);
+
const char* translatorName = argSource->getStringArg("translatorActionName", "translator");
translatorAction = (TranslatorAction*)PMF::getAction(argSource->getPipeline(), translatorName);
assert(translatorAction);
init();
+
+ if (compInterface.isBCMapInfoRequired()) {
+ isBCmapRequired = true;
+ MethodDesc* meth = compInterface.getMethodToCompile();
+ bc2HIRMapHandler = new VectorHandler(bcOffset2HIRHandlerName, meth);
+ } else {
+ isBCmapRequired = false;
+ bc2HIRMapHandler = NULL;
+ }
}
EscAnalyzer::EscAnalyzer(EscAnalyzer* parent, IRManager& irm)
-: eaMemManager(parent->eaMemManager), irManager(irm), mh(irm.getMethodDesc())
+: eaMemManager(parent->eaMemManager), irManager(irm), mh(irm.getMethodDesc()), os_sc(Log::out()),
+ compInterface(irm.getCompilationInterface())
{
maxMethodExamLevel = parent->maxMethodExamLevel;
allProps = parent->allProps;
debug_method = parent->debug_method;
translatorAction = parent->translatorAction;
method_ea_level = parent->method_ea_level + 1;
-
+
init();
}
@@ -115,9 +148,12 @@
initNodeType = 0; // type of initial scanned node
scannedObjs = new (eaMemManager) ObjIds(eaMemManager);
+ scannedObjsRev = new (eaMemManager) ObjIds(eaMemManager);
scannedInsts = new (eaMemManager) ObjIds(eaMemManager);
scannedSucNodes = new (eaMemManager) ObjIds(eaMemManager);
monitorInstUnits = new (eaMemManager) MonInstUnits(eaMemManager);
+ methodEndInsts = new (eaMemManager) Insts(eaMemManager);
+ checkInsts = new (eaMemManager) Insts(eaMemManager);
_cfgirun=0;
_instrInfo=0;
@@ -129,6 +165,13 @@
_printstat=0;
_eainfo=0;
_seinfo=0;
+ if (Log::isEnabled())
+ _scinfo = 1;
+ else
+ if (print_scinfo)
+ _scinfo=1;
+ else
+ _scinfo=0;
std::fill(prsArr, prsArr + prsNum, 0);
@@ -157,6 +200,20 @@
}
}
+void
+EscAnalyzer::showFlags(std::ostream& os) {
+ os << " escape flags:"<<std::endl;
+ os << " escape.max_level[=0] - max level callee method analysis" << std::endl;
+ os << " escape.do_sync_removal[={on,OFF}] - do synchonization removal optimization" << std::endl;
+ os << " escape.do_scalar_repl[={ON,off}] - do scalar replacement optimization for" << std::endl;
+ os << " local and escaped objects" << std::endl;
+ os << " escape.do_esc_scalar_repl[={ON,off}] - scalar replacement for escaped objects" << std::endl;
+ os << " escape.do_scalar_repl_only_final_fields[={on,OFF}] " << std::endl;
+ os << " escape.scalarize_final_fields[={on,OFF}] - scalarize final field usage when" << std::endl;
+ os << " escaped object wasn't optimized" << std::endl;
+ os << " escape.exec_count_mult[=0] - entry node execCount multiplier" << std::endl;
+}
+
void
EscAnalyzer::doAnalysis() {
const char* mn = mh.getName();
@@ -190,8 +247,10 @@
Log::out() << "_printstat " << _printstat << std::endl;
Log::out() << "_eainfo " << _eainfo << std::endl;
Log::out() << "_seinfo " << _seinfo << std::endl;
- }
+ Log::out() << "_scinfo " << _scinfo << std::endl;
+ }
}
+
if (_eainfo || _seinfo) {
Log::out()<<"====== doAnalysis ====== "<<mn<<" level: ";
Log::out()<<method_ea_level<<" ";
@@ -262,12 +321,12 @@
setCreatedObjectStates();
-#ifdef _DEBUG
+//#ifdef _DEBUG
if (_eainfo) {
if (Log::isEnabled())
printCreatedObjectsInfo(Log::out());
}
-#endif
+//#endif
saveScannedMethodInfo(); //??? to save states of contained obj, if needed
@@ -294,7 +353,7 @@
markNotEscInsts();
}
-#ifdef _DEBUG
+//#ifdef _DEBUG
if (_cngnodes) {
Log::out() <<"printCnGNodes: ";
if (Log::isEnabled())
@@ -303,19 +362,28 @@
if (Log::isEnabled())
printCnGNodes("Marked nodes",Log::out());
}
-#endif
+//#endif
if (method_ea_level == 0) {
createdObjectInfo(); // prints if _printstat==1
}
if (method_ea_level == 0) {
- scanSyncInsts();
-
+ if (do_sync_removal) {
+ scanSyncInsts();
+ }
+ if (do_scalar_repl) {
+ scanLocalObjects();
+ eaFixupVars(irManager);
+ if (do_esc_scalar_repl) {
+ scanEscapedObjects();
+ eaFixupVars(irManager);
+ }
+ }
#ifdef _DEBUG
if (_seinfo && Log::isEnabled()) {
printCreatedObjectsInfo(Log::out());
- Log::out() << "================ this agrument of sync method"
+ Log::out() << "================ this argument of sync method"
<< std::endl;
CnGNodes::iterator it;
for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
@@ -371,6 +439,21 @@
void
+EscAnalyzer::eaFixupVars(IRManager& irm) {
+ OptPass::computeDominators(irm);
+ DominatorTree* dominatorTree = irm.getDominatorTree();
+ ControlFlowGraph& flowGraph = irm.getFlowGraph();
+
+ DomFrontier frontier(irm.getNestedMemoryManager(),*dominatorTree,&flowGraph);
+ SSABuilder ssaBuilder(irm.getOpndManager(),irm.getInstFactory(),frontier,&flowGraph, irm.getOptimizerFlags());
+ bool phiInserted = ssaBuilder.fixupVars(&irm.getFlowGraph(), irm.getMethodDesc());
+ irm.setInSsa(true);
+ if (phiInserted)
+ irm.setSsaUpdated();
+}
+
+
+void
EscAnalyzer::scanSyncInsts() {
MonInstUnits::iterator it;
Insts::iterator it1;
@@ -613,12 +696,12 @@
} // checkCallSyncMethod()
-/*
-* Inserts ldc0, if it was not inserted previously,
-* jit helper call to save this arg of direct call method.
-* Parameter:
-* CnGNode corresponding to this arg of direct call sync method.
-*/
+/**
+ * Inserts ldc0, if it was not inserted previously,
+ * jit helper call to save this arg of direct call method.
+ * Parameter:
+ * CnGNode corresponding to this arg of direct call sync method.
+ */
void
EscAnalyzer::insertSaveJitHelperCall(CnGNode* node) {
SsaTmpOpnd* stVal;
@@ -661,15 +744,15 @@
} // insertSaveJitHelperCall(CnGNode* node)
-/*
-* Inserts ldc0, if it was not inserted previously,
-* jit helper call to read this arg of the method.
-* Parameter:
-* CnGNode corresponding to this arg of direct call sync method.
-* Returns:
-* Opnd* stored_value
-* 0 - this argument is thread local, 1 - this argument is thread global
-*/
+/**
+ * Inserts ldc0, if it was not inserted previously,
+ * jit helper call to read this arg of the method.
+ * Parameter:
+ * CnGNode corresponding to this arg of direct call sync method.
+ * Returns:
+ * Opnd* stored_value
+ * 0 - this argument is thread local, 1 - this argument is thread global
+ */
Opnd*
EscAnalyzer::insertReadJitHelperCall() {
ControlFlowGraph& fg = irManager.getFlowGraph();
@@ -710,11 +793,11 @@
} // insertReadJitHelperCall()
-/*
-* Checks, that method contains monitor instructions with parameter
-* which is this or subobject of this.
-* Returns: true, if such monitors exist, false overwise.
-*/
+/**
+ * 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;
@@ -830,8 +913,8 @@
printMethodInfo(mtdInfo);
}
#endif
- }
- }
+ }
+ }
}
findObject1(einst);
collectSuccessors(einst->getNode());
@@ -867,10 +950,10 @@
} // setSencEscState(CnGNode* node,Insts* syncInsts)
-/*
-* Collect all reachable from specified node nodes in FlowGraph.
-* scannedSucNodes - result of collection.
-*/
+/**
+ * Collect all reachable from specified node nodes in FlowGraph.
+ * scannedSucNodes - result of collection.
+ */
void
EscAnalyzer::collectSuccessors(Node* node) {
Node* n;
@@ -892,7 +975,7 @@
void
EscAnalyzer::collectGlobalNodeSuccessors(CnGNode* node) {
CnGEdges::iterator it;
- CnGRefs::iterator it2;
+ CnGRefs::iterator it2;
Inst* einst;
bool pGlobalObj = false;
#ifdef _DEBUG
@@ -954,7 +1037,7 @@
}
#endif
}
- }
+ }
}
if (einst->getOpcode() == Op_IndirectMemoryCall)
pGlobalObj = true;
@@ -1069,7 +1152,6 @@
scannedObjs->clear();
}
}
-
}
} // removeMonitorInsts(Insts* syncInsts)
@@ -1116,15 +1198,15 @@
} // removeNode(Node* node)
-/*
-* Creates i32_0 or i32_1 SsaTmpOpnd (in accordance with value: 0 or 1)
-* if it was'n created before.
-* Inserts ldc0 or ldc1 instruction after first instruction in entry Node,
-* if SsaTmpOpnd was created.
-* Returns:
-* i32_0, if value = 0
-* i32_1, if value = 1
-*/
+/**
+ * Creates i32_0 or i32_1 SsaTmpOpnd (in accordance with value: 0 or 1)
+ * if it was'n created before.
+ * Inserts ldc0 or ldc1 instruction after first instruction in entry Node,
+ * if SsaTmpOpnd was created.
+ * Returns:
+ * i32_0, if value = 0
+ * i32_1, if value = 1
+ */
SsaTmpOpnd*
EscAnalyzer::insertLdConst(uint32 value) {
TypeManager& _typeManager = irManager.getTypeManager();
@@ -1243,11 +1325,11 @@
} // fixMonitorInstsVCalls(MonUnit* mu)
-/*
-* Insers flag check before monitor instruction.
-* If flag = 0 monitor instruction isn't executed.
-* Operand flag may be VarOpnd* or SsaTmpOpnd* type.
-*/
+/**
+ * Inserts flag check before monitor instruction.
+ * If flag = 0 monitor instruction isn't executed.
+ * Operand flag may be VarOpnd* or SsaTmpOpnd* type.
+ */
void
EscAnalyzer::insertFlagCheck(Insts* syncInsts, Opnd* muflag) {
Insts::iterator inst_it;
@@ -1340,13 +1422,13 @@
} // printNode(Node* n,::std::ostream& os)
-/*
-* 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
-*/
+/**
+ * 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;
@@ -1387,7 +1469,7 @@
if (st <= GLOBAL_ESCAPE)
return st;
switch (inst->getOpcode()) {
- case Op_LdRef: // ldstr
+ case Op_LdRef: // ldref
case Op_NewObj: // newobj
case Op_NewArray: // newarray
case Op_NewMultiArray: // newmultiarray
@@ -1433,7 +1515,7 @@
if (scannedObjs->size()!=0) {
if (checkScannedObjs(inst->getId())) {
#ifdef _DEBUG
- if (_seinfo) {
+ if (_seinfo || _scinfo) {
Log::out() << "instId " << inst->getId()
<< " . . . " << std::endl;
}
@@ -1442,7 +1524,7 @@
}
}
#ifdef _DEBUG
- if (_seinfo) {
+ if (_seinfo || _scinfo) {
Log::out() << text;
if (Log::isEnabled())
inst->print(Log::out());
@@ -1455,7 +1537,7 @@
CnGNode* n = findCnGNode_op(returnOpnd->getId());
if (n != NULL) {
#ifdef _DEBUG
- if (_seinfo) {
+ if (_seinfo || _scinfo) {
Log::out()<< text << " ";
if (Log::isEnabled())
printCnGNode(n,Log::out());
@@ -1466,8 +1548,13 @@
}
if (inst->getOpcode()==Op_IndirectMemoryCall) {
#ifdef _DEBUG
- MethodDesc* md = inst->getSrc(0)->getInst()->asMethodInst()->getMethodDesc();
- if (_seinfo) {
+ 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 << " ";
if (Log::isEnabled())
md->printFullName(Log::out() );
@@ -1482,7 +1569,7 @@
CnGNode* n = findCnGNode_op(dst->getId());
if (n != NULL) {
#ifdef _DEBUG
- if (_seinfo) {
+ if (_seinfo || _scinfo) {
Log::out()<< text << " ";
if (Log::isEnabled())
printCnGNode(n,Log::out());
@@ -1492,7 +1579,7 @@
}
}
switch (inst->getOpcode()) {
- case Op_LdRef: // ldstr
+ case Op_LdRef: // ldref
case Op_NewObj: // newobj
case Op_NewArray: // newarray
case Op_NewMultiArray: // newmultiarray
@@ -1501,7 +1588,7 @@
CnGNode* n = findCnGNode_in(inst->getId());
if (n != NULL) {
#ifdef _DEBUG
- if (_seinfo) {
+ if (_seinfo || _scinfo) {
Log::out() << text << " ";
if (Log::isEnabled())
printCnGNode(n,Log::out() );
@@ -1525,9 +1612,9 @@
} // findObject(Inst* inst,std::string text)
-/*
-* Finds (prints) origin objects of monitor instruction operand.
-*/
+/**
+ * Finds (prints) origin objects of monitor instruction operand.
+ */
void
EscAnalyzer::findObject1(Inst* inst,std::string text) {
Inst* inst1;
@@ -1535,48 +1622,45 @@
if (scannedObjs->size()!=0) {
if (checkScannedObjs(inst->getId())) {
-#ifdef _DEBUG
- if (_seinfo) {
+ if (_seinfo || _scinfo) {
Log::out() << "instId " << inst->getId()
<< " . . . " << std::endl;
}
-#endif
return;
}
}
-#ifdef _DEBUG
- if (_seinfo) {
+ if (_seinfo || _scinfo) {
Log::out() << text;
if (Log::isEnabled())
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) {
+ if (_seinfo || _scinfo) {
Log::out()<< text << " ";
if (Log::isEnabled())
printCnGNode(n,Log::out());
Log::out()<< std::endl;
}
-#endif
}
}
if (inst->getOpcode()==Op_IndirectMemoryCall) {
-#ifdef _DEBUG
- MethodDesc* md = inst->getSrc(0)->getInst()->asMethodInst()->getMethodDesc();
- if (_seinfo) {
+ 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 << " ";
if (Log::isEnabled())
md->printFullName(Log::out() );
Log::out() << std::endl;
}
-#endif
}
return;
}
@@ -1584,18 +1668,16 @@
Opnd *dst = inst->getDst();
CnGNode* n = findCnGNode_op(dst->getId());
if (n != NULL) {
-#ifdef _DEBUG
- if (_seinfo) {
+ if (_seinfo || _scinfo) {
Log::out()<< text << " ";
if (Log::isEnabled())
printCnGNode(n,Log::out());
Log::out()<< std::endl;
}
-#endif
}
}
switch (inst->getOpcode()) {
- case Op_LdRef: // ldstr
+ case Op_LdRef: // ldref
case Op_NewObj: // newobj
case Op_NewArray: // newarray
case Op_NewMultiArray: // newmultiarray
@@ -1603,14 +1685,12 @@
{
CnGNode* n = findCnGNode_in(inst->getId());
if (n != NULL) {
-#ifdef _DEBUG
- if (_seinfo) {
+ if (_seinfo || _scinfo) {
Log::out() << text << " ";
if (Log::isEnabled())
printCnGNode(n,Log::out() );
Log::out() << std::endl;
}
-#endif
}
break;
}
@@ -1660,10 +1740,10 @@
} // markNotEscInsts()
-/*
-* Summarizes common number of objects with the same state.
-* Prints statictics if required.
-*/
+/**
+ * Summarizes common number of objects with the same state.
+ * Prints statictics if required.
+ */
void
EscAnalyzer::createdObjectInfo() {
CnGNodes::iterator it;
@@ -1721,13 +1801,16 @@
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 (calledMethodInfos==NULL) {
+//std::cout<< "*1****** lock "<<GetCurrentThreadId()<<std::endl;
calledMethodInfosLock.lock();
if (calledMethodInfos==NULL)
calledMethodInfos = new (globalMM) CalledMethodInfos(globalMM);
+//std::cout<< "*1****** unlock "<<GetCurrentThreadId()<<std::endl;
calledMethodInfosLock.unlock();
} else {
CalledMethodInfo* mtdInfo = getMethodInfo(ch1,ch2,ch3);
@@ -1736,10 +1819,11 @@
}
if (getMethodInfo(ch1,ch2,ch3)!=NULL) // info was saved by another jit
return;
-
+//std::cout<< "*2****** lock "<<GetCurrentThreadId()<<std::endl;
calledMethodInfosLock.lock(); // Lock to save method info in common memory
if (getMethodInfo(ch1,ch2,ch3)!=NULL) { // already saved by another jit
+//std::cout<< "*2 ***** unlock "<<GetCurrentThreadId()<<std::endl;
calledMethodInfosLock.unlock(); // Unlock
return;
}
@@ -1783,7 +1867,7 @@
}
}
calledMethodInfos->push_back(minfo);
-
+//std::cout<< "*2****** unlock "<<GetCurrentThreadId()<<std::endl;
calledMethodInfosLock.unlock(); // Unlock
#ifdef _DEBUG
@@ -1905,19 +1989,20 @@
ci.setBCMapInfoRequired(false);
}
- CompilationContext inlineCC(irManager.getMemoryManager(), &ci, ci.getCompilationContext());
- inlineCC.setHIRManager(inlinedIRM);
- runTranslatorSession(inlineCC);
+ {
+ CompilationContext inlineCC(irManager.getMemoryManager(), &ci, ci.getCompilationContext());
+ inlineCC.setHIRManager(inlinedIRM);
+ runTranslatorSession(inlineCC);
+ }
optimizeTranslatedCode(*inlinedIRM);
-
- if (cibcmap) {
- ci.setBCMapInfoRequired(true);
- }
EscAnalyzer ea1(this, *inlinedIRM);
ea1.doAnalysis();
+ if (cibcmap) {
+ ci.setBCMapInfoRequired(true);
+ }
} // scanCalleeMethod(Inst* call, MemoryManager& mm)
void EscAnalyzer::runTranslatorSession(CompilationContext& inlineCC) {
@@ -1944,8 +2029,8 @@
irm.setSsaUpdated();
// run devirt pass
- Devirtualizer pass(irm);
- pass.guardCallsInRegion(irm, dominatorTree);
+// Devirtualizer pass(irm);
+// pass.guardCallsInRegion(irm, dominatorTree);
} // optimizeTranslatedCode(IRManager& irManager)
@@ -1967,10 +2052,11 @@
Log::out() << std::endl;
}
#endif
- scanCnGNodeRefsGE(*it);
+ scanCnGNodeRefsGE(*it,false);
}
}
scannedObjs->clear();
+ scannedObjsRev->clear();
for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
if ((*it)->nodeType&NT_EXITVAL) { // returned, thrown
#ifdef _DEBUG
@@ -1983,10 +2069,11 @@
}
#endif
initNodeType = (*it)->nodeType;
- scanCnGNodeRefsGE(*it);
+ scanCnGNodeRefsGE(*it,false);
}
}
scannedObjs->clear();
+ scannedObjsRev->clear();
for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
if ((*it)->nodeType==NT_DEFARG) {
#ifdef _DEBUG
@@ -1999,11 +2086,13 @@
}
#endif
initNodeType = NT_DEFARG;
- scanCnGNodeRefsGE(*it);
+ scanCnGNodeRefsGE(*it,false);
scannedObjs->clear(); // temporary
+ scannedObjsRev->clear();
}
}
scannedObjs->clear();
+ scannedObjsRev->clear();
for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
if ((*it)->nodeType==NT_ACTARG) {
curMDNode=(*it)->cngNodeId;
@@ -2017,10 +2106,13 @@
}
#endif
initNodeType = NT_ACTARG;
- scanCnGNodeRefsAE(*it);
+ scanCnGNodeRefsAE(*it,false);
+ scannedObjs->clear();
+ scannedObjsRev->clear();
}
}
scannedObjs->clear();
+ scannedObjsRev->clear();
if (method_ea_level==0) {
DominatorTree* dominatorTree = irManager.getDominatorTree();
if (!(dominatorTree && dominatorTree->isValid())) {
@@ -2062,13 +2154,24 @@
}
for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
uint32 nt = (*it)->nodeType;
- if ((nt&NT_OBJECT || nt==NT_LDOBJ) && (getEscState(*it)==ARG_ESCAPE)) {
+// if (((nt&(NT_OBJECT|NT_RETVAL) || nt==NT_LDOBJ)&&((*it)->nodeRefType!=NR_PRIM)) && (getEscState(*it)==ARG_ESCAPE)) {
+ if ((nt&(NT_OBJECT|NT_RETVAL) || nt==NT_LDOBJ) && (getEscState(*it)==ARG_ESCAPE)) {
for (it1 = (*it)->nodeMDs->begin(); it1 != (*it)->nodeMDs->end();
it1++) {
CnGNode* n=findCnGNode_id(*it1); // method argument node
assert(n!=NULL);
MethodDesc* mdesc = (MethodDesc*)n->refObj;
Inst* callInst = n->nInst;
+#ifdef _DEBUG
+ if (_setState) {
+ Log::out()<<"--setSt chk arg_esc: node " <<(*it)->cngNodeId
+ <<" opndId " <<(*it)->opndId<<" state ";
+ printState(*it); Log::out() << std::endl;
+ Log::out() << " ";
+ callInst->print(Log::out());
+ Log::out() << std::endl;
+ }
+#endif
if (mdesc->isNative()) { // not scanned native methods
if (strcmp(mdesc->getParentType()->getName(),"java/lang/VMMemoryManager")==0
&&strcmp(mdesc->getName(),"arrayCopy")==0) {
@@ -2103,15 +2206,16 @@
break;
}
if (callInst->getOpcode()!=Op_DirectCall) { // not direct call
- if (method_ea_level == 0) {
+ setVirtualCall(*it);
+ if (method_ea_level == 0 && do_sync_removal) {
MonUnit* mu = NULL;
if (monitorInstUnits!=NULL)
mu = findMonUnit((*it)->opndId);
if (mu != NULL) {
- setVirtualCall(*it);
+// setVirtualCall(*it);
addMonUnitVCall(mu,callInst);
#ifdef _DEBUG
- if (Log::isEnabled()) {
+ if (_seinfo&&Log::isEnabled()) {
Log::out() << "=-=-=-=- callimem for this ";
Log::out() << std::endl;
Log::out() << "=-=- ";
@@ -2129,8 +2233,7 @@
continue;
}
}
-
- setEscState(*it,GLOBAL_ESCAPE);
+ // setEscState(*it,GLOBAL_ESCAPE);
#ifdef _DEBUG
if (_scanMtds==1) {
if (Log::isEnabled()) {
@@ -2173,13 +2276,13 @@
<<" state ";
if (Log::isEnabled())
printState(*it);
- Log::out() <<" to gl.esc."
+// Log::out() <<" to gl.esc."
+ Log::out() <<" to v.call."
<< std::endl;
}
#endif
- break;
+ continue; //break;
}
-
CalledMethodInfo* mtdInfo = findMethodInfo(mdesc,callInst);
if (mtdInfo == NULL) { // no info about called method
setEscState(*it,GLOBAL_ESCAPE);
@@ -2239,8 +2342,9 @@
}
}
if (getEscState(*it)==GLOBAL_ESCAPE) { // to set gl.escape for contained objects
- scanCnGNodeRefsGE(*it); //??? to set initNodeType?
+ scanCnGNodeRefsGE(*it,false); //??? to set initNodeType?
scannedObjs->clear();
+ scannedObjsRev->clear();
}
}
}
@@ -2342,6 +2446,7 @@
}
scannedObjs->clear();
+ scannedObjsRev->clear();
}
@@ -2430,12 +2535,12 @@
} // findMethodInfo(MethodDesc* mdesc)
-/*
-* Finds specified parameter in specified method info.
-* Returns:
-* state - for existent parameter,
-* 0 - for another cases.
-*/
+/**
+ * Finds specified parameter in specified method info.
+ * Returns:
+ * state - for existent parameter,
+ * 0 - for another cases.
+ */
uint32
EscAnalyzer::getMethodParamState(CalledMethodInfo* mi, uint32 np) {
ParamInfos::iterator it;
@@ -2460,7 +2565,8 @@
irManager.getMethodDesc().printFullName(os);
os << std::endl;
for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
- if ((*it)->nodeType & NT_OBJECT || (*it)->nodeType==NT_LDOBJ) {
+ uint32 nt = (*it)->nodeType;
+ if (nt&(NT_OBJECT|NT_RETVAL) || nt==NT_LDOBJ) {
printCnGNode(*it,os);
((Opnd*)(*it)->refObj)->printWithType(os);
if (getEscState(*it)==ARG_ESCAPE) {
@@ -2485,25 +2591,32 @@
void
-EscAnalyzer::scanCnGNodeRefsGE(CnGNode* cgn) {
+EscAnalyzer::scanCnGNodeRefsGE(CnGNode* cgn, bool check_var_src, bool check_field_elem) {
// CnGEdges* cge = cngEdges;
CnGEdges::iterator it;
CnGRefs::iterator it1;
+ CnGNode* next_node;
+ ObjIds* scObjs = check_var_src ? scannedObjsRev : scannedObjs;
uint32 nscan=0;
- if (scannedObjs->size()!=0) {
- if (checkScannedObjs(cgn->cngNodeId))
- return;
- }
+ uint32 ni_opcode = cgn->nInst->getOpcode();
+
#ifdef _DEBUG
if (_setState) {
Log::out() <<"--scanGE 1: node "<<cgn->cngNodeId
<<" opndId "<<cgn->opndId<<" state ";
if (Log::isEnabled())
printState(cgn);
- Log::out() <<" "
- << nodeTypeToString(cgn) << cgn->nodeType << std::endl;
+ Log::out() <<" " << nodeTypeToString(cgn) <<cgn->nodeType
+ <<" check_var_src " << check_var_src
+ <<" check_field_elem " << check_field_elem << std::endl;
}
#endif
+ if (cgn->nodeType == NT_LDVAL)
+ return;
+ if (scObjs->size()!=0) {
+ if (checkScanned(scObjs,cgn->cngNodeId))
+ return;
+ }
if (cgn->nodeType&NT_OBJS) {
if (initNodeType!=NT_EXITVAL && initNodeType!=NT_DEFARG) { //
if (getEscState(cgn) > GLOBAL_ESCAPE) {
@@ -2539,51 +2652,98 @@
// The objects created in the method are not global escaped through return
}
if (initNodeType==NT_DEFARG) {
- if (getCalleeEscaped(cgn) == 0) {
+ if (getCalleeEscaped(cgn) == 0) {
#ifdef _DEBUG
- if (_setState) {
- Log::out() <<"--scanGE 5: node "
- <<cgn->cngNodeId<<" opndId "<<cgn->opndId <<" state ";
- if (Log::isEnabled())
- printState(cgn);
- Log::out() <<" to callee.esc."<< std::endl;
- Log::out() <<"--scanGE 5: "<< nodeTypeToString(cgn)
- << cgn->nodeType <<" initNode "<<initNodeType<< std::endl;
- }
+ if (_setState) {
+ Log::out() <<"--scanGE 4: node "
+ <<cgn->cngNodeId<<" opndId "<<cgn->opndId <<" state ";
+ if (Log::isEnabled())
+ printState(cgn);
+ Log::out() <<" to callee.esc."<< std::endl;
+ Log::out() <<"--scanGE 4: "<< nodeTypeToString(cgn)
+ << cgn->nodeType <<" initNode "<<initNodeType<< std::endl;
+ }
#endif
- setCalleeEscaped(cgn);
- }
+ setCalleeEscaped(cgn);
+ }
}
}
- scannedObjs->push_back(cgn->cngNodeId);
+// scannedObjs->push_back(cgn->cngNodeId);
+ scObjs->push_back(cgn->cngNodeId);
if (cgn->outEdges != NULL) {
+ bool to_check_var_src = check_var_src;
+ bool to_check_field_elem = check_field_elem;
+ if (cgn->nodeType!=NT_INSTFLD && cgn->nodeType!=NT_ARRELEM)
+ to_check_field_elem = true;
for (it1 = cgn->outEdges->begin( ); it1 != cgn->outEdges->end( ); it1++ ) {
- scanCnGNodeRefsGE(findCnGNode_id((*it1)->cngNodeTo->cngNodeId));
+ next_node = (*it1)->cngNodeTo;
+ if (next_node->nodeType == NT_LDOBJ)
+ if (next_node->nInst->getOpcode()==Op_LdVar && cgn->nodeType!=NT_VARVAL)
+ to_check_var_src = true;
+#ifdef _DEBUG
+ if (_setState) {
+ Log::out() <<"--scanGE 5 next: node "
+ <<next_node->cngNodeId<<" opndId "<<next_node->opndId <<" state ";
+ printState(next_node); Log::out() << std::endl;
+ }
+#endif
+ scanCnGNodeRefsGE(next_node,to_check_var_src,to_check_field_elem);
if ((*it1)->edgeType!=ET_POINT)
nscan++;
}
}
+ if (check_var_src) {
+ if (ni_opcode == Op_LdVar || ni_opcode == Op_StVar || ni_opcode ==Op_Phi) {
+ uint32 nsrc=cgn->nInst->getNumSrcOperands();
+ for (uint32 i=0; i<nsrc; i++) {
+ next_node = findCnGNode_op(cgn->nInst->getSrc(i)->getId());
+#ifdef _DEBUG
+ if (_setState) {
+ Log::out() <<"--scanGE 6 next: node "
+ <<next_node->cngNodeId<<" opndId "<<next_node->opndId <<" state ";
+ printState(next_node); Log::out() << std::endl;
+ }
+#endif
+ scanCnGNodeRefsGE(next_node,check_var_src);
+ }
+ }
+ }
#ifdef _DEBUG
if (_setState) {
- Log::out()<<"--scanGE 6: nscan "<<nscan<<" opndId "<<cgn->opndId<<std::endl;
+ Log::out()<<"--scanGE: nscan "<<nscan<<" opndId "<<cgn->opndId<<std::endl;
}
#endif
- if (cgn->nodeType==NT_ARRELEM && nscan==0) {
- Inst* inst_ldbase= ((Opnd*)(cgn->refObj))->getInst()->getSrc(0)->getInst();
+ if (cgn->nodeType==NT_ARRELEM) {
+ Inst* inst_ldbase = cgn->nInst;
+ if (inst_ldbase->getOpcode()==Op_AddScaledIndex)
+ inst_ldbase = ((Opnd*)(cgn->refObj))->getInst()->getSrc(0)->getInst();
CnGNode* cgnode=findCnGNode_op(inst_ldbase->getSrc(0)->getId());
#ifdef _DEBUG
if (_setState) {
- Log::out() <<"--scanGE arrElem: ";
+ Log::out() <<"--scanGE 7 arrElem: ";
if (Log::isEnabled())
inst_ldbase->print(Log::out());
Log::out() << std::endl;
- Log::out() <<"--scanGE next: " << cgnode->cngNodeId << " - "
+ Log::out() <<"--scanGE 7 next: " << cgnode->cngNodeId << " - "
<< cgnode->opndId << std::endl;
}
#endif
- scanCnGNodeRefsGE(cgnode);
+ // if some array element is escaped, then all array elements are escaped
+ if (cgnode->outEdges != NULL) {
+ for (it1 = cgnode->outEdges->begin( ); it1 != cgnode->outEdges->end( ); it1++ ) {
+ next_node = (*it1)->cngNodeTo;
+#ifdef _DEBUG
+ if (_setState) {
+ Log::out() <<"--scanGE 7 next arrElem: node "
+ <<next_node->cngNodeId<<" opndId "<<next_node->opndId <<" state ";
+ printState(next_node); Log::out() << std::endl;
+ }
+#endif
+ scanCnGNodeRefsGE(next_node,check_var_src,false);
+ }
+ }
}
- if (cgn->nodeType==NT_LDOBJ && nscan==0) {
+ if (cgn->nodeType==NT_LDOBJ && check_field_elem) {
Inst* ldinst =((Opnd*)(cgn->refObj))->getInst();
if (ldinst->getOpcode()==Op_TauLdInd) { //tttt
Inst* inst_fldaddr= ldinst->getSrc(0)->getInst();
@@ -2591,7 +2751,7 @@
CnGNode* cgnode=findCnGNode_fl(inst_fldaddr,NT_INSTFLD);
#ifdef _DEBUG
if (_setState) {
- Log::out() << "TO FIND 1 for opnd "
+ Log::out() << "--scanGE 8 TO FIND 1 for opnd "
<< cgn->opndId << std::endl;
if (Log::isEnabled())
ldinst->print(Log::out());
@@ -2605,13 +2765,14 @@
<< cgnode->opndId << std::endl;
}
#endif
- scanCnGNodeRefsGE(cgnode);
+ scanCnGNodeRefsGE(cgnode,check_var_src,false);
} else {
- if (inst_fldaddr->getOpcode()==Op_AddScaledIndex) {
+ uint32 oc = inst_fldaddr->getOpcode();
+ if (oc==Op_AddScaledIndex || oc == Op_LdArrayBaseAddr) {
CnGNode* cgnode=findCnGNode_op(ldinst->getSrc(0)->getId());
#ifdef _DEBUG
if (_setState) {
- Log::out() << "TO FIND 2 for opnd "
+ Log::out() << "--scanGE 8 TO FIND 2 for opnd "
<< cgn->opndId << std::endl;
if (Log::isEnabled())
ldinst->print(Log::out());
@@ -2625,140 +2786,129 @@
<< cgnode->opndId << std::endl;
}
#endif
- scanCnGNodeRefsGE(cgnode);
+ scanCnGNodeRefsGE(cgnode,check_var_src,false);
}
}
}
}
-} // scanCnGNodeRefsGE(CnGNode* cgn)
+} // scanCnGNodeRefsGE(CnGNode* cgn, bool check_var_src, bool check_field_elem)
void
-EscAnalyzer::scanCnGNodeRefsEV(CnGNode* cgn) {
+EscAnalyzer::scanCnGNodeRefsAE(CnGNode* cgn, bool check_var_src, bool check_field_elem) {
+ CnGEdges::iterator it;
CnGRefs::iterator it1;
- if (scannedObjs->size()!=0) {
- if (checkScannedObjs(cgn->cngNodeId))
- return;
- }
+ CnGNode* next_node;
+ ObjIds* scObjs = check_var_src ? scannedObjsRev : scannedObjs;
+ uint32 nscan=0;
+ uint32 ni_opcode = cgn->nInst->getOpcode();
+
#ifdef _DEBUG
if (_setState) {
- Log::out() <<"--scanEV: node "<<cgn->cngNodeId
- <<" opndId "<<cgn->opndId <<" state ";
+ Log::out() <<"--scanAE < 1: node "<<cgn->cngNodeId
+ <<" opndId "<<cgn->opndId<<" state ";
if (Log::isEnabled())
- printState(cgn);
- Log::out() << " "
- << nodeTypeToString(cgn) << cgn->nodeType << std::endl;
+ printState(cgn);
+ Log::out() <<" " << nodeTypeToString(cgn) <<cgn->nodeType
+ <<" check_var_src " << check_var_src
+ <<" check_field_elem " << check_field_elem << std::endl;
}
#endif
- if (cgn->nodeType==NT_OBJECT) // object is escaped if it is returned
- if (getEscState(cgn) > GLOBAL_ESCAPE) {
- setEscState(cgn,GLOBAL_ESCAPE);
+ if (cgn->nodeType == NT_LDVAL) { // primitive type value
+#ifdef _DEBUG
+ if (_setState) {
+ Log::out() <<"--scanAE > 1: primitive type " << std::endl;
+ }
+#endif
+ return;
+ }
+ if (scObjs->size()!=0) {
+ if (checkScanned(scObjs,cgn->cngNodeId)) {
#ifdef _DEBUG
if (_setState) {
- Log::out() <<"--scanEV: node "<<cgn->cngNodeId
- <<" opndId "<<cgn->opndId<<" state ";
- if (Log::isEnabled())
- printState(cgn);
- Log::out() <<" to gl.esc."<< std::endl;
+ Log::out() <<"--scanAE > 2: was scanned earlier " << std::endl;
}
#endif
- }
- scannedObjs->push_back(cgn->cngNodeId);
- if (cgn->outEdges != NULL) {
- for (it1 = cgn->outEdges->begin( ); it1 != cgn->outEdges->end( ); it1++ ) {
- scanCnGNodeRefsGE(findCnGNode_id((*it1)->cngNodeTo->cngNodeId));
- }
- }
-} // scanCnGNodeRefsEV(CnGNode* cgn)
-
-
-void
-EscAnalyzer::scanCnGNodeRefsDA(CnGNode* cgn) {
- CnGEdges* cge = cngEdges;
- CnGEdges::iterator it;
- CnGRefs::iterator it1;
- uint32 cgntype=cgn->nodeType;
- bool first=true;
- if (scannedObjs->size()!=0) {
- first=false;
- if (checkScannedObjs(cgn->cngNodeId))
return;
+ }
}
+ if (getEscState(cgn) < ARG_ESCAPE) { // not scan global escaped
#ifdef _DEBUG
- if (_setState) {
- Log::out() <<"--scanDA: node "<<cgn->cngNodeId
- <<" opndId "<<cgn->opndId<<" state ";
- if (Log::isEnabled())
- printState(cgn);
- Log::out() <<" "<<nodeTypeToString(cgn)<<cgn->nodeType<< std::endl;
- }
+ if (_setState) {
+ Log::out() <<"--scanAE > 3: global escaped " << std::endl;
+ }
#endif
- if ((cgntype&NT_OBJECT && !first)||(cgntype==NT_OBJECT && first))
- scannedObjs->push_back(cgn->cngNodeId);
- for (it = cge->begin( ); it != cge->end( ); it++ ) {
- if ((*it)->cngNodeFrom == cgn) {
- for (it1 = (*it)->refList->begin( ); it1 != (*it)->refList->end( ); it1++ ) {
- scanCnGNodeRefsGE(findCnGNode_id((*it1)->cngNodeTo->cngNodeId));
- }
- }
- }
-} // scanCnGNodeRefsDA(CnGNode* cgn)
-
-
-void
-EscAnalyzer::scanCnGNodeRefsAE(CnGNode* cgn) {
- CnGEdges* cge = cngEdges;
- CnGEdges::iterator it;
- CnGRefs::iterator it1;
- uint32 nscan=0;
- if (scannedObjs->size()!=0) {
- if (checkScannedObjs(cgn->cngNodeId))
- return;
+ return;
}
+ if (cgn->nodeType&NT_OBJS) {
+// if (cgn->nodeMDs!=NULL && check_field_elem) {
+ if (cgn->nodeMDs!=NULL) {
+ cgn->nodeMDs->push_back(curMDNode);
#ifdef _DEBUG
- if (_setState) {
- Log::out() <<"--scanAE: node "<<cgn->cngNodeId
- <<" opndId "<<cgn->opndId<<" state ";
- if (Log::isEnabled())
- printState(cgn);
- Log::out() <<" " << nodeTypeToString(cgn) <<cgn->nodeType<< std::endl;
- }
+ if (_setState) {
+ Log::out() <<"--scanAE 1_1: node "<<cgn->cngNodeId
+ <<" opndId "<<cgn->opndId <<" curMDNode "<<curMDNode<< std::endl;
+ }
#endif
- if (cgn->nodeType&NT_OBJS)
- if (getEscState(cgn) >= ARG_ESCAPE) {
- setEscState(cgn,ARG_ESCAPE);
+ }
+ if (getEscState(cgn) > ARG_ESCAPE) {
#ifdef _DEBUG
if (_setState) {
- Log::out() <<"--scanAE: node "<<cgn->cngNodeId
+ Log::out() <<"--scanAE 2: node "<<cgn->cngNodeId
<<" opndId "<<cgn->opndId<<" state ";
if (Log::isEnabled())
printState(cgn);
Log::out() <<" to arg.esc."<< std::endl;
}
#endif
- if (cgn->nodeMDs==NULL) {
- Log::out() <<"--scanAE: node "<<cgn->cngNodeId
- <<" opndId "<<cgn->opndId<<" state ";
- if (Log::isEnabled())
- printState(cgn);
- Log::out() <<" " << nodeTypeToString(cgn)
- << cgn->nodeType << std::endl;
+ setEscState(cgn,ARG_ESCAPE);
+ }
+ }
+// scannedObjs->push_back(cgn->cngNodeId);
+ scObjs->push_back(cgn->cngNodeId);
+ if (cgn->outEdges != NULL) {
+ bool to_check_var_src = check_var_src;
+ bool to_check_field_elem = check_field_elem;
+ if (cgn->nodeType!=NT_INSTFLD && cgn->nodeType!=NT_ARRELEM)
+ to_check_field_elem = true;
+ for (it1 = cgn->outEdges->begin( ); it1 != cgn->outEdges->end( ); it1++ ) {
+ next_node = (*it1)->cngNodeTo;
+#ifdef _DEBUG
+ if (_setState) {
+ Log::out() <<"--scanAE 3 next: node "
+ <<next_node->cngNodeId<<" opndId "<<next_node->opndId <<" state ";
+ printState(next_node);
+ Log::out() << " " << nodeTypeToString(next_node)
+ << " ref.type " << next_node->nodeRefType << std::endl;
}
- cgn->nodeMDs->push_back(curMDNode);
+#endif
+ if (next_node->nodeType == NT_LDVAL)
+ continue;
+ if (next_node->nodeType == NT_LDOBJ)
+ if (next_node->nInst->getOpcode()==Op_LdVar && cgn->nodeType!=NT_VARVAL)
+ to_check_var_src = true;
+ scanCnGNodeRefsAE(next_node,to_check_var_src,to_check_field_elem);
+ if ((*it1)->edgeType!=ET_POINT)
+ nscan++;
}
- scannedObjs->push_back(cgn->cngNodeId);
- for (it = cge->begin( ); it != cge->end( ); it++ ) {
- if ((*it)->cngNodeFrom == cgn) {
- for (it1 = (*it)->refList->begin( ); it1 != (*it)->refList->end( ); it1++ ) {
- if ((*it1)->edgeType==ET_FIELD) // do not scan field edge
- continue;
- scanCnGNodeRefsAE(findCnGNode_id((*it1)->cngNodeTo->cngNodeId));
- if ((*it1)->edgeType!=ET_POINT)
- nscan++;
+ }
+ if (check_var_src) {
+ if (ni_opcode == Op_LdVar || ni_opcode == Op_StVar || ni_opcode ==Op_Phi) {
+ uint32 nsrc=cgn->nInst->getNumSrcOperands();
+ for (uint32 i=0; i<nsrc; i++) {
+ next_node = findCnGNode_op(cgn->nInst->getSrc(i)->getId());
+#ifdef _DEBUG
+ if (_setState) {
+ Log::out() <<"--scanAE 4 next: node "
+ <<next_node->cngNodeId<<" opndId "<<next_node->opndId <<" state ";
+ printState(next_node); Log::out() << std::endl;
+ }
+#endif
+ scanCnGNodeRefsAE(next_node,check_var_src);
}
}
}
- if (cgn->nodeType==NT_ARRELEM && nscan==0) {
+ if (cgn->nodeType==NT_ARRELEM && check_field_elem) {
Inst* inst_addindex = ((Opnd*)(cgn->refObj))->getInst();
Inst* inst_ldbase = inst_addindex->getSrc(0)->getInst();
if (inst_addindex->getOpcode() == Op_LdArrayBaseAddr)
@@ -2766,90 +2916,89 @@
CnGNode* cgnode=findCnGNode_op(inst_ldbase->getSrc(0)->getId());
#ifdef _DEBUG
if (_setState) {
- Log::out() <<"--scanAE check1: ";
+ Log::out() <<"--scanAE 5 check1: ";
if (Log::isEnabled())
inst_ldbase->print(Log::out());
Log::out() << std::endl;
- Log::out() <<"--scanAE check2: ";
+ Log::out() <<"--scanAE 5 check2: ";
if (cgnode==NULL)
Log::out() <<"cngnode==null "<< std::endl;
- Inst* inst_addindex= ((Opnd*)(cgn->refObj))->getInst();
- Log::out() <<"--scanAE arrElem: ";
- if (Log::isEnabled())
- inst_addindex->print(Log::out());
- Log::out() << std::endl;
- Log::out() <<"--scanAE arrElem: ";
- if (Log::isEnabled())
- inst_ldbase->print(Log::out());
- Log::out() << std::endl;
- Log::out() <<"--scanAE next: " << cgnode->cngNodeId << " - "
+ Log::out() <<"--scanAE 5 next: " << cgnode->cngNodeId << " - "
<< cgnode->opndId << std::endl;
}
#endif
- scanCnGNodeRefsAE(cgnode);
+ if (cgnode->outEdges != NULL) {
+ for (it1 = cgnode->outEdges->begin( ); it1 != cgnode->outEdges->end( ); it1++ ) {
+ next_node = (*it1)->cngNodeTo;
+#ifdef _DEBUG
+ if (_setState) {
+ Log::out() <<"--scanAE 5 next arrElem: node "
+ <<next_node->cngNodeId<<" opndId "<<next_node->opndId <<" state ";
+ printState(next_node); Log::out() << std::endl;
+ }
+#endif
+ scanCnGNodeRefsAE(next_node,check_var_src,false);
+ }
+ }
}
- if (cgn->nodeType==NT_LDOBJ && nscan==0) {
+ if (cgn->nodeType==NT_LDOBJ && check_field_elem) {
Inst* ldinst =((Opnd*)(cgn->refObj))->getInst();
if (ldinst->getOpcode()==Op_TauLdInd) {
- CnGNode* cgnode=findCnGNode_op(ldinst->getSrc(0)->getId());
+ Inst* inst_fldaddr= ldinst->getSrc(0)->getInst();
+ if (inst_fldaddr->getOpcode()==Op_LdFieldAddr) {
+ CnGNode* cgnode=findCnGNode_fl(inst_fldaddr,NT_INSTFLD);
#ifdef _DEBUG
- if (_setState) {
- Log::out() <<"TO FIND for opnd "
- << cgn->opndId << std::endl;
- if (Log::isEnabled())
- ldinst->print(Log::out());
- Log::out() << std::endl;
- Log::out() << cgn->cngNodeId << "-"
- << cgn->opndId << " -> ";
- Log::out() << cgnode->cngNodeId << "-"
- << cgnode->opndId << std::endl;
- }
-#endif
- scanCnGNodeRefsAE(cgnode);
- }
- }
- if ((cgn->nodeType==NT_INSTFLD) && nscan==0) { //????????
- if (getEscState(cgn) > ARG_ESCAPE)
- setEscState(cgn,ARG_ESCAPE); // for instance fields of method parameters & array elements
- }
- scannedObjs->pop_back();
-} // scanCnGNodeRefsAE(CnGNode* cgn)
-
-
-bool
-EscAnalyzer::checkScannedObjs(uint32 id) {
- ObjIds::iterator it;
- for (it = scannedObjs->begin( ); it != scannedObjs->end( ); it++ ) {
- if ((*it)==id) {
- return true;
- }
- }
- return false;
-} // checkScannedObjs(CnGNode* cgn)
-
-
-bool
-EscAnalyzer::checkScannedInsts(uint32 id) {
- ObjIds::iterator it;
- for (it = scannedInsts->begin( ); it != scannedInsts->end( ); it++ ) {
- if ((*it)==id) {
- return true;
+ if (_setState) {
+ Log::out() <<"--scanAE 6 TO FIND 1 for opnd "
+ << cgn->opndId << std::endl;
+ if (Log::isEnabled())
+ ldinst->print(Log::out());
+ Log::out() << std::endl;
+ if (Log::isEnabled())
+ inst_fldaddr->print(Log::out());
+ Log::out() << std::endl;
+ Log::out() << cgn->cngNodeId << "-"
+ << cgn->opndId << " -> ";
+ Log::out() << cgnode->cngNodeId << "-"
+ << cgnode->opndId << std::endl;
+ }
+#endif
+ scanCnGNodeRefsAE(cgnode,check_var_src,false);
+ } else {
+ uint32 oc = inst_fldaddr->getOpcode();
+ if (oc==Op_AddScaledIndex || oc == Op_LdArrayBaseAddr) {
+ CnGNode* cgnode=findCnGNode_op(ldinst->getSrc(0)->getId());
+#ifdef _DEBUG
+ if (_setState) {
+ Log::out() << "--scanAE 6 TO FIND 2 for opnd "
+ << cgn->opndId << std::endl;
+ if (Log::isEnabled())
+ ldinst->print(Log::out());
+ Log::out() << std::endl;
+ if (Log::isEnabled())
+ inst_fldaddr->print(Log::out());
+ Log::out() << std::endl;
+ Log::out() << cgn->cngNodeId << "-"
+ << cgn->opndId << " -> ";
+ Log::out() << cgnode->cngNodeId << "-"
+ << cgnode->opndId << std::endl;
+ }
+#endif
+ scanCnGNodeRefsAE(cgnode,check_var_src,false);
+ }
+ }
}
}
- return false;
-} // checkScannedInsts(CnGNode* cgn)
-
-
-bool
-EscAnalyzer::checkScannedSucNodes(uint32 id) {
- ObjIds::iterator it;
- for (it = scannedSucNodes->begin( ); it != scannedSucNodes->end( ); it++ ) {
- if ((*it)==id) {
- return true;
- }
+#ifdef _DEBUG
+ if (_setState) {
+ Log::out() <<"--scanAE > 4: exit: node "<<cgn->cngNodeId
+ <<" opndId "<<cgn->opndId<<" state "; printState(cgn);
+ Log::out() <<" " << nodeTypeToString(cgn) <<cgn->nodeType
+ <<" check_var_src " << check_var_src
+ <<" check_field_elem " << check_field_elem << std::endl;
}
- return false;
-} // checkScannedSucNodes(CnGNode* cgn)
+#endif
+} // scanCnGNodeRefsAE(CnGNode* cgn, bool check_var_src, bool check_field_elem)
void
@@ -3062,7 +3211,8 @@
os << " id. " <<opnd->getId();
os << " type " << type->getName() << " " << type->tag<<" ";
os << " isRef " << type->isReference();
- os << " isObj " << type->isObject() << std::endl;
+ os << " isObj " << type->isObject();
+ os << " isVal " << type->isValue() << std::endl;
if (type->isReference())
ref_type_info(type,os);
os << " ";
@@ -3101,25 +3251,38 @@
if ((ntype==NT_STFLD)||ntype==NT_THRVAL)
setFullState(cgnode,GLOBAL_ESCAPE);
else {
- if (ntype==NT_ACTARG)
+ if (ntype==NT_ACTARG) {
setFullState(cgnode,ARG_ESCAPE);
- else
+ if (inst->getOpcode()==Op_IndirectMemoryCall)
+ setVirtualCall(cgnode);
+ } else
setFullState(cgnode,NO_ESCAPE);
}
if (ntype==NT_EXITVAL)
setCalleeEscaped(cgnode);
- if (type->isArray()) {
- if (type->asArrayType()->isReference()) {
- cgnode->nodeRefType = NR_REFARR;
+ cgnode->nodeMDs = NULL;
+ if (type->isReference()) {
+ if (type->isArray()) {
+ if (type->asArrayType()->getElementType()->isReference()) {
+ cgnode->nodeRefType = NR_REFARR;
+ } else
+ cgnode->nodeRefType = NR_ARR;
} else
- cgnode->nodeRefType = NR_ARR;
- } else
- cgnode->nodeRefType = NR_REF;
- if (ntype&(NT_OBJECT|NT_RETVAL)||ntype==NT_LDOBJ||ntype==NT_VARVAL||ntype==NT_REF||ntype==NT_ARRELEM) {
- cgnode->nodeMDs = new (eaMemManager) NodeMDs(eaMemManager); // to collect methods receiving object
- } else
- cgnode->nodeMDs = NULL;
+ cgnode->nodeRefType = NR_REF;
+ if (ntype&(NT_OBJECT|NT_RETVAL)||ntype==NT_LDOBJ) {
+ cgnode->nodeMDs = new (eaMemManager) NodeMDs(eaMemManager); // to collect methods receiving object
+ }
+ } else {
+ cgnode->nodeRefType = NR_PRIM;
+ }
cngNodes->push_back(cgnode);
+#ifdef _DEBUG
+ if (_cngnodes) {
+ Log::out() <<"++++ addNode "<<cgnode->cngNodeId
+ <<" opndId "<<cgnode->opndId; printCnGNode(cgnode,Log::out());
+ Log::out() << std::endl;
+ }
+#endif
return cgnode;
} // addCnGNode(MemoryManager& mm, Type* type, Inst* inst, uint32 ntype)
@@ -3231,7 +3394,8 @@
insnum++;
ntype=0;
if (_instrInfo) {
- Log::out() <<"++Node Id."<<node->getId()<<" "<<node->getDfNum()<<std::endl;
+ Log::out() <<"instrExam:" << std::endl;
+ Log::out() <<"++Node Id."<<node->getId()<<" "<<node->getDfNum()<<std::endl; Log::out() <<"instrExam++Node Id."<<node->getId()<<" "<<node->getDfNum()<<std::endl;
Log::out() << "==";
if (Log::isEnabled())
inst->print(Log::out());
@@ -3239,7 +3403,7 @@
}
switch (inst->getOpcode()) {
- case Op_LdRef: // ldstr
+ case Op_LdRef: // ldref
case Op_NewObj: // newobj
case Op_NewArray: // newarray
case Op_NewMultiArray: // newmultiarray
@@ -3266,6 +3430,21 @@
}
break;
+ case Op_Conv: // conv
+#ifdef _DEBUG
+ if (_instrInfo) {
+ Log::out() <<"Node Id."<<node->getId()<<std::endl;
+ if (Log::isEnabled())
+ debug_inst_info(inst,Log::out());
+ }
+#endif
+ if (inst->getDst()->getType()->isObject()) {
+ type=inst->getDst()->getType();
+ assert(findCnGNode_op(inst->getDst()->getId())==NULL);
+ cgnode = addCnGNode_op(inst,type,NT_OBJECT);
+ }
+ break;
+
case Op_LdFieldAddr: // ldflda
ntype=NT_INSTFLD;
case Op_LdStaticAddr: // ldsflda
@@ -3284,11 +3463,23 @@
if (type->isReference()) {
assert(findCnGNode_op(inst->getDst()->getId())==NULL);
cgnode = addCnGNode_op(inst,type,NT_REF);
- if (findCnGNode_fl(inst,ntype)==NULL) {
- CnGNode* n = addCnGNode_fl(inst,ntype);
- cgnode->lNode=n; // stick nodes // and if fl node exists ? bug?
+ CnGNode* n = findCnGNode_fl(inst,ntype);
+ if (n==NULL) {
+ n = addCnGNode_fl(inst,ntype);
}
+ cgnode->lNode=n; // stick nodes
addInst(cfgnode, inst);
+ } else {
+ if (ntype==NT_INSTFLD) {
+ assert(findCnGNode_op(inst->getDst()->getId())==NULL);
+ cgnode = addCnGNode_op(inst,type,NT_REF);
+ CnGNode* n = findCnGNode_fl(inst,ntype);
+ if (n==NULL) {
+ n = addCnGNode_fl(inst,ntype);
+ }
+ addInst(cfgnode, inst);
+ cgnode->lNode=n; // stick nodes
+ }
}
}
break;
@@ -3301,12 +3492,20 @@
debug_inst_info(inst,Log::out());
}
#endif
- if (inst->getDst()->getType()->isObject()) {
- type=inst->getDst()->getType();
+ type = inst->getDst()->getType();
+ if (type->isReference()) { //isObject()) {
+// type=inst->getDst()->getType();
assert(findCnGNode_op(inst->getDst()->getId())==NULL);
cgnode = addCnGNode_op(inst,type,NT_LDOBJ);
addInst(cfgnode, inst);
}
+ if (inst->getSrc(0)->getInst()->getOpcode()==Op_LdStaticAddr)
+ break;
+ if (type->isValue()) {
+ assert(findCnGNode_op(inst->getDst()->getId())==NULL);
+ cgnode = addCnGNode_op(inst,type,NT_LDVAL);
+ addInst(cfgnode, inst);
+ }
break;
case Op_LdArrayBaseAddr: // ldbase
@@ -3318,6 +3517,10 @@
debug_inst_info(inst,Log::out());
}
#endif
+// if (inst->getSrc(0)->getInst()->getOpcode()==Op_VMHelperCall) {
+// Log::out() << "break "; inst->print(Log::out()); Log::out() << std::endl;
+// break;
+// }
if (inst->getDst()->getType()->isReference()) {
type=inst->getDst()->getType();
assert(findCnGNode_op(inst->getDst()->getId())==NULL);
@@ -3326,6 +3529,38 @@
}
break;
+ case Op_VMHelperCall: // callvmhelper
+#ifdef _DEBUG
+ if (_instrInfo) {
+ Log::out() <<"Node Id."<<node->getId()<<std::endl;
+ if (Log::isEnabled())
+ debug_inst_info(inst,Log::out());
+ }
+#endif
+ if (!inst->getDst()->isNull()) {
+ if (inst->getDst()->getType()->isObject()) {
+ CompilationInterface::RuntimeHelperId callId =
+ inst->asVMHelperCallInst()->getVMHelperId();
+ switch(callId) {
+ case CompilationInterface::Helper_GetTLSBase:
+ ntype = NT_ARRELEM;
+ break;
+ case CompilationInterface::Helper_NewObj_UsingVtable:
+ case CompilationInterface::Helper_NewVector_UsingVtable:
+ ntype = NT_OBJECT;
+ break;
+ default:
+ ntype = 0;
+ assert(0);
+ }
+ type=inst->getDst()->getType();
+ assert(findCnGNode_op(inst->getDst()->getId())==NULL);
+ cgnode = addCnGNode_op(inst,type,ntype);
+ // addInst(cfgnode, inst);
+ }
+ }
+ break;
+
case Op_TauStInd: // stind
#ifdef _DEBUG
if (_instrInfo) {
@@ -3334,7 +3569,7 @@
debug_inst_info(inst,Log::out());
}
#endif
- if (inst->getSrc(0)->getType()->isObject()) {
+ if ((type=inst->getSrc(0)->getType())->isObject() || type->isValue()) {
addInst(cfgnode, inst);
}
break;
@@ -3406,7 +3641,14 @@
}
}
method_inst=inst->getSrc(0)->getInst();
- md=method_inst->asMethodInst()->getMethodDesc();
+ if (method_inst->getOpcode() == Op_LdVar) {
+ Opnd* funptr = inst->getSrc(0);
+ Type* optype = funptr->getType();
+ MethodPtrType* opmtype = optype->asMethodPtrType();
+ md = opmtype->getMethodDesc();
+ } else {
+ md=method_inst->asMethodInst()->getMethodDesc();
+ }
msd = md->getMethodSig();
n=msd->getNumParams();
addinst=false;
@@ -3561,16 +3803,18 @@
case Op_TauMonitorEnter: // monenter
case Op_TauMonitorExit: // monexit
- addMonInst(inst);
+ if (do_sync_removal && method_ea_level == 0) {
+ addMonInst(inst);
#ifdef _DEBUG
- if (_seinfo) {
- Log::out() << "iE: monX Node Id."
+ if (_seinfo) {
+ Log::out() << "iE: monX Node Id."
<< node->getId() << " ";
- if (Log::isEnabled())
- inst->print(Log::out());
- Log::out()<<std::endl;
- }
+ if (Log::isEnabled())
+ inst->print(Log::out());
+ Log::out()<<std::endl;
+ }
#endif
+ }
break;
case Op_TypeMonitorEnter:// tmonenter
@@ -3650,9 +3894,11 @@
ntype=NT_STFLD; // for LdStaticAddr
FieldAccessInst* fainst;
if ((fainst=inst->asFieldAccessInst())!=NULL) {
- if (fainst->getFieldDesc()->getFieldType()->isReference()) {
+ bool isref = fainst->getFieldDesc()->getFieldType()->isReference();
+ if (isref || ntype==NT_INSTFLD) {
cgn_src=findCnGNode_op(inst->getDst()->getId()); // field address node
- assert(cgn_src!=NULL);
+ if (isref)
+ assert(cgn_src!=NULL);
cgnode=findCnGNode_fl(inst,ntype); // field node
assert(cgnode!=NULL);
// adding edge from fld node to address node
@@ -3671,7 +3917,16 @@
break;
case Op_TauLdInd: // ldind
- if (inst->getDst()->getType()->isObject()) {
+ type=inst->getDst()->getType();
+ if (type->isObject()) {
+ cgnode=findCnGNode_op(inst->getDst()->getId());
+ assert(cgnode!=NULL);
+ // ref to loaded object
+ cgn_src=findCnGNode_op(inst->getSrc(0)->getId());
+ assert(cgn_src!=NULL);
+ addEdge(cgn_src,cgnode,ET_POINT,inst);
+ }
+ if (type->isValue()) {
cgnode=findCnGNode_op(inst->getDst()->getId());
assert(cgnode!=NULL);
// ref to loaded object
@@ -3686,14 +3941,19 @@
if (inst->getDst()->getType()->isReference()) {
cgnode=findCnGNode_op(inst->getDst()->getId());
assert(cgnode!=NULL);
- // ref to loaded address
- cgn_src=findCnGNode_op(inst->getSrc(0)->getId());
- assert(cgn_src!=NULL);
+ // ref to loaded address
if (inst->getOpcode()==Op_LdArrayBaseAddr) {
- cgnode->lNode=cgn_src; //stick array object & array base address nodes
+ cgn_src=findCnGNode_op(inst->getSrc(0)->getId());
+ assert(cgn_src!=NULL);
+ addEdge(cgn_src,cgnode,ET_FIELD,inst); // ref to base element
}
if (inst->getOpcode()==Op_AddScaledIndex) {
- addEdge(cgn_src,cgnode,ET_FIELD,inst); // ref from array object to inner objects
+ if (inst->getSrc(0)->getInst()->getOpcode()==Op_LdArrayBaseAddr) {
+ cgn_src=findCnGNode_op(
+ inst->getSrc(0)->getInst()->getSrc(0)->getId());
+ assert(cgn_src!=NULL);
+ addEdge(cgn_src,cgnode,ET_FIELD,inst); // ref from array object to inner objects
+ }
}
}
break;
@@ -3706,6 +3966,19 @@
cgnode=findCnGNode_op(inst->getSrc(1)->getId());
assert(cgnode!=NULL);
addEdge(cgnode,cgn_src,ET_DEFER,inst);
+ break;
+ }
+ if ((type=inst->getSrc(0)->getType())->isValue()) {
+ uint32 src_opcode = inst->getSrc(1)->getInst()->getOpcode();
+ if (src_opcode==Op_LdStaticAddr)
+ break;
+ cgn_src=findCnGNode_op(inst->getSrc(0)->getId());
+ if (cgn_src==NULL) {
+ cgn_src = addCnGNode_op(inst->getSrc(0)->getInst(),type,NT_LDVAL);
+ }
+ cgnode=findCnGNode_op(inst->getSrc(1)->getId());
+ assert(cgnode!=NULL);
+ addEdge(cgnode,cgn_src,ET_DEFER,inst);
}
break;
@@ -3727,7 +4000,12 @@
case Op_IndirectMemoryCall: //callimem
method_inst=inst->getSrc(0)->getInst();
- md=method_inst->asMethodInst()->getMethodDesc();
+ if (method_inst->getOpcode() == Op_LdVar) {
+ MethodPtrType* mpt = inst->getSrc(0)->getType()->asMethodPtrType();
+ md = mpt->getMethodDesc();
+ } else {
+ md=method_inst->asMethodInst()->getMethodDesc();
+ }
msd = md->getMethodSig();
n=msd->getNumParams();
for (uint32 i = 0; i < n; i++) {
@@ -3748,7 +4026,7 @@
assert(cgnode!=NULL);
cgn_src=findCnGNode_op(inst->getSrc(0)->getId());
assert(cgn_src!=NULL);
- addEdge(cgnode,cgn_src,ET_DEFER,inst);
+ addEdge(cgn_src,cgnode,ET_DEFER,inst);
}
break;
@@ -3760,7 +4038,7 @@
for (uint32 i=0; i<nsrc; i++) {
cgn_src=findCnGNode_op(inst->getSrc(i)->getId());
assert(cgn_src!=NULL);
- addEdge(cgnode,cgn_src,ET_DEFER,inst);
+ addEdge(cgn_src,cgnode,ET_DEFER,inst);
}
}
break;
@@ -3827,7 +4105,7 @@
std::string t2;
os << "nodeId "<<cgn->cngNodeId<<" ";
- if (cgn->nodeType & NT_OBJS) { //node of object created in the method
+ if (cgn->nodeType & (NT_OBJS|NT_LDVAL)) { //node of object created in the method
os << "opId "<<cgn->opndId<<" ";
} else {
if (cgn->nodeType & NT_ACTARG) { //node of actual method parameter
@@ -3839,6 +4117,7 @@
os << " nArg "<<cgn->argNumber<<" "; //Arg number for defarg
os << " inst "<<cgn->instrId<<" ("<<nodeTypeToString(cgn)<<cgn->nodeType<<", ";
switch (cgn->nodeRefType) {
+ case NR_PRIM : t2="Prim-"; break;
case NR_REF : t2="Ref -"; break;
case NR_ARR : t2="Arr -"; break;
case NR_REFARR : t2="RArr-"; break;
@@ -3848,7 +4127,7 @@
if (cgn->lNode)
os << "( " << cgn->lNode->cngNodeId << "-" << cgn->lNode->opndId << " ) ";
os << "st. ";
- printState(cgn); os << " ";
+ printState(cgn,os); os << " ";
} // printCnGNode(CnGNode* cgn,::std::ostream& os)
@@ -3870,6 +4149,7 @@
case NT_ACTARG : t1="AArg-"; break;
case NT_EXITVAL : t1="EVal-"; break;
case NT_THRVAL : t1="TVal-"; break;
+ case NT_LDVAL : t1="LVal-"; break;
default : t1=" -";
}
return t1;
@@ -3901,7 +4181,7 @@
printCnGNode(*it,os);
os << std::endl;
os << " ";
- if ((*it)->nodeType & (NT_OBJS|NT_EXITVAL)) { //node of created or exit object
+ if ((*it)->nodeType & (NT_OBJS|NT_EXITVAL|NT_LDVAL)) { //node of created or exit object
((Opnd*)(*it)->refObj)->printWithType(os);
}
if ((*it)->nodeType == NT_RETVAL) {
@@ -3909,7 +4189,12 @@
Inst* inst = ((Opnd*)(*it)->refObj)->getInst();
inst->print(os);
if (inst->getOpcode()==Op_IndirectMemoryCall) {
- MethodDesc* md = inst->getSrc(0)->getInst()->asMethodInst()->getMethodDesc();
+ 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();
+ }
os << std::endl; os << " ";
md->printFullName(os);
}
@@ -3946,17 +4231,23 @@
os << std::endl;
os << text; cgn->nInst->print(os); os << std::endl;
scannedObjs->push_back(cgn->cngNodeId);
- if (cgn->outEdges != NULL)
+ if (cgn->outEdges != NULL) {
for (it1 = cgn->outEdges->begin( ); it1 != cgn->outEdges->end( ); it1++ ) {
os << text << edgeTypeToString(*it1) << std::endl;
if ((node=findCnGNode_id((*it1)->cngNodeTo->cngNodeId))!=NULL)
printCnGNodeRefs(node,text+" ",os);
}
+ }
scannedObjs->pop_back();
if (cgn->nodeType==NT_RETVAL) {
inst = cgn->nInst;
if (inst->getOpcode()==Op_IndirectMemoryCall) {
- MethodDesc* md = inst->getSrc(0)->getInst()->asMethodInst()->getMethodDesc();
+ 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();
+ }
os << text << " ";
md->printFullName(os); os << std::endl;
}
@@ -3990,7 +4281,12 @@
}
}
if (inst->getOpcode()==Op_IndirectMemoryCall) {
- MethodDesc* md = inst->getSrc(0)->getInst()->asMethodInst()->getMethodDesc();
+ 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();
+ }
os << text << " "; md->printFullName(os); os << std::endl;
}
return;
@@ -4041,7 +4337,7 @@
EscAnalyzer::findCnGNode_op(uint32 nId) {
CnGNodes::iterator it;
for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
- if ((*it)->opndId==nId && ((*it)->nodeType & NT_OBJS))
+ if ((*it)->opndId==nId && ((*it)->nodeType & (NT_OBJS|NT_LDVAL)))
return (*it);
}
return(NULL);
@@ -4127,9 +4423,9 @@
} // findCnGNode_fl(Opnd* opnd, uint32 ntype)
-/*
-* Creates edge if it doesn't exist yet.
-*/
+/**
+ * Creates edge if it doesn't exist yet.
+ */
void
EscAnalyzer::addEdge(CnGNode* cgnfrom, CnGNode* cgnto,
uint32 etype, Inst* inst) {
@@ -4145,10 +4441,6 @@
assert(cgn1!=NULL);
}
- if (cgnto->lNode) {
- cgn2=findCnGNode_id(cgnto->lNode->cngNodeId);
- assert(cgn2!=NULL);
- }
#ifdef _DEBUG
if (_cngedges) {
Log::out()
@@ -4185,7 +4477,7 @@
}
}
} else {
- for ( itr = (*it)->refList->begin( ); itr != (*it)->refList->end( ); itr++ )
+/* for ( itr = (*it)->refList->begin( ); itr != (*it)->refList->end( ); itr++ )
if ((*itr)->cngNodeTo == cgn2) { // needed edge exists
done = true;
#ifdef _DEBUG
@@ -4193,7 +4485,7 @@
Log::out() << "++++ addEdge: needed edge exists" << std::endl;
}
#endif
- }
+ }--nvg */
}
if (!done) {
ref = new (eaMemManager) CnGRef;
@@ -4228,6 +4520,2162 @@
#endif
} // addEdge(CnGNode* cgnfrom, CnGNode* cgnto, uint32 etype, Inst* inst)
+
+
+/*
+ Scalar replacement optimization
+*/
+
+void
+EscAnalyzer::scanLocalObjects() {
+ CnGNodes::iterator it;
+ uint32 lo_count=0; // number of local objects
+ ObjIds* lnoids = NULL; // list of new opnds to optimize
+ ObjIds* lloids = NULL; // list of load opnds to optimize
+ ObjIds::iterator lo_it;
+ bool prTitle = true;
+ CnGNode* stnode = NULL;
+
+ for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
+ if ((*it)->nodeType == NT_OBJECT && getEscState(*it)==NO_ESCAPE
+ && getCalleeEscaped(*it) == 0 && !((*it)->nInst->getOpcode()==Op_LdRef)) {
+ if (prTitle) {
+ if (_scinfo) {
+ os_sc << "================ Local Object States < ";
+ irManager.getMethodDesc().printFullName(os_sc);
+ os_sc << std::endl;
+ }
+ prTitle = false;
+ }
+ lo_count++; // number of local objects
+ stnode = checkCnG(*it,true);
+ if (stnode != NULL) {
+ if (stnode->nodeType == NT_OBJECT) {
+ if (lnoids == NULL) {
+ lnoids = new (eaMemManager) ObjIds(eaMemManager);
+ }
+ lnoids->push_back(stnode->opndId);
+ } else {
+ if (lloids == NULL) {
+ lloids = new (eaMemManager) ObjIds(eaMemManager);
+ }
+ lloids->push_back(stnode->opndId);
+ }
+ }
+ if (_scinfo) {
+ os_sc << "- - - checkCnG returns ";
+ if (stnode == NULL) {
+ os_sc << " null ";
+ os_sc << std::endl;
+ } else {
+ printCnGNode(stnode,os_sc); os_sc << std::endl;
+ }
+ }
+ }
+ }
+ if (prTitle)
+ return;
+ if (_scinfo) {
+ os_sc << "CFGOpnds: " << irManager.getOpndManager().getNumSsaOpnds() << " CnGNodes: "
+ << cngNodes->size() << " Local Objects: " << lo_count << std::endl;
+ }
+ if (lnoids != NULL || lloids != NULL) {
+ if (_scinfo) {
+ if (lnoids != NULL) {
+ if (lnoids->size()>0) {
+ os_sc << "lnoids size: " << lnoids->size() << " - ";
+ for (lo_it=lnoids->begin(); lo_it!=lnoids->end(); lo_it++) {
+ os_sc << " " << (*lo_it);
+ }
+ os_sc << std::endl;
+ }
+ }
+ if (lloids != NULL) {
+ if (lloids->size()>0) {
+ os_sc << "lloids size: " << lloids->size() << " - ";
+ for (lo_it=lloids->begin(); lo_it!=lloids->end(); lo_it++) {
+ os_sc << " " << (*lo_it);
+ }
+ os_sc << std::endl;
+ }
+ }
+ }
+ methodEndInsts->clear();
+ checkInsts->clear();
+ checkOpndUsage(lnoids,lloids,true);
+ bool doopt = false;
+ if (lnoids != NULL) {
+ if (lnoids->size()>0) {
+ doopt = true;
+ if (_scinfo) {
+ os_sc << "lnoids size: " << lnoids->size() << " - ";
+ for (lo_it=lnoids->begin(); lo_it!=lnoids->end(); lo_it++) {
+ os_sc << " " << (*lo_it);
+ }
+ os_sc << std::endl;
+ }
+ } else {
+ if (_scinfo) {
+ os_sc << "lnoids size: 0" << std::endl;
+ }
+ }
+ }
+ if (lloids != NULL) {
+ if (lloids->size()>0) {
+ doopt = true;
+ if (_scinfo) {
+ os_sc << "lloids size: " << lloids->size() << " - ";
+ for (lo_it=lloids->begin(); lo_it!=lloids->end(); lo_it++) {
+ os_sc << " " << (*lo_it);
+ }
+ os_sc << std::endl;
+ }
+ } else {
+ if (_scinfo) {
+ os_sc << "lloids size: 0" << std::endl;
+ }
+ }
+ }
+ if (doopt && do_scalar_repl) {
+ if (lnoids != NULL) {
+ doLOScalarReplacement(lnoids);
+ }
+ if (lloids != NULL) {
+ doLOScalarReplacement(lloids);
+ }
+ } }
+ if (_scinfo) {
+ os_sc << "================ > " ;
+ irManager.getMethodDesc().printFullName(os_sc);
+ os_sc << std::endl;
+ }
+} // scanLocalObjects()
+
+
+void
+EscAnalyzer::scanEscapedObjects() {
+ CnGNodes::iterator it;
+ uint32 vco_count=0; // number of local objects
+ uint32 ob_ref_type=0; // object ref type
+ ObjIds* lnoids = NULL; // list of new opnds to optimize
+ ObjIds* lloids = NULL; // list of load opnds to optimize
+ ObjIds::iterator lo_it;
+ bool prTitle = true;
+ CnGNode* stnode = NULL;
+
+ for (it = cngNodes->begin( ); it != cngNodes->end( ); it++ ) {
+// if ((*it)->nodeType == NT_OBJECT && getEscState(*it)!=NO_ESCAPE
+ if ((*it)->nodeType == NT_OBJECT
+ && getCalleeEscaped(*it) == 0 && !((*it)->nInst->getOpcode()==Op_LdRef)) {
+ if ((*it)->nInst->getNode() == NULL && getEscState(*it)==NO_ESCAPE) {
+ continue; // already scalarized
+ }
+ ob_ref_type = (*it)->nodeRefType; // object ref type
+ if (ob_ref_type != NR_REF) {
+ continue; // vc arrays not scalarized
+ }
+ vco_count++; // number of vc objects
+ if (prTitle) {
+ if (_scinfo) {
+ os_sc << "================ Escaped Object States < ";
+ irManager.getMethodDesc().printFullName(os_sc);
+ os_sc << std::endl;
+ }
+ prTitle = false;
+ }
+
+ stnode = checkCnG(*it,false);
+ if (stnode != NULL) {
+ if (stnode->nodeType == NT_OBJECT) {
+ if (lnoids == NULL) {
+ lnoids = new (eaMemManager) ObjIds(eaMemManager);
+ }
+ lnoids->push_back(stnode->opndId);
+ } else {
+ if (lloids == NULL) {
+ lloids = new (eaMemManager) ObjIds(eaMemManager);
+ }
+ lloids->push_back(stnode->opndId);
+ }
+ }
+ if (_scinfo) {
+ os_sc << "- - - checkCnG returns ";
+ if (stnode == NULL) {
+ os_sc << " null ";
+ os_sc << std::endl;
+ } else {
+ printCnGNode(stnode,os_sc); os_sc << std::endl;
+ }
+ }
+
+ }
+ }
+
+ if (prTitle)
+ return;
+
+ if (_scinfo) {
+ os_sc << "CFGOpnds: " << irManager.getOpndManager().getNumSsaOpnds() << " CnGNodes: "
+ << cngNodes->size() << " VC Objects: " << vco_count << " lnoids size "
+ << (lnoids!=NULL?lnoids->size():0) << " lloids size "
+ << (lloids!=NULL?lloids->size():0)<< std::endl;
+ }
+ if (lnoids != NULL || lloids != NULL) {
+ if (_scinfo) {
+ if (lnoids != NULL) {
+ if (lnoids->size()>0) {
+ os_sc << "lnoids size: " << lnoids->size() << " - ";
+ for (lo_it=lnoids->begin(); lo_it!=lnoids->end(); lo_it++) {
+ os_sc << " " << (*lo_it);
+ }
+ os_sc << std::endl;
+ }
+ }
+ if (lloids != NULL) {
+ if (lloids->size()>0) {
+ os_sc << "lloids size: " << lloids->size() << " - ";
+ for (lo_it=lloids->begin(); lo_it!=lloids->end(); lo_it++) {
+ os_sc << " " << (*lo_it);
+ }
+ os_sc << std::endl;
+ }
+ }
+ }
+ methodEndInsts->clear();
+ checkInsts->clear();
+ checkOpndUsage(lnoids,lloids,false);
+ bool doopt = false;
+ if (lnoids != NULL) {
+ if (lnoids->size()>0) {
+ doopt = true;
+ if (_scinfo) {
+ os_sc << "lnoids size: " << lnoids->size() << " - ";
+ for (lo_it=lnoids->begin(); lo_it!=lnoids->end(); lo_it++) {
+ os_sc << " " << (*lo_it);
+ }
+ os_sc << std::endl;
+ }
+ }
+ }
+ if (lloids != NULL) {
+ if (lloids->size()>0) {
+ doopt = true;
+ if (_scinfo) {
+ os_sc << "lloids size: " << lloids->size() << " - ";
+ for (lo_it=lloids->begin(); lo_it!=lloids->end(); lo_it++) {
+ os_sc << " " << (*lo_it);
+ }
+ os_sc << std::endl;
+ }
+ }
+ }
+ if (doopt && do_scalar_repl) {
+ if (lnoids != NULL) {
+ doEOScalarReplacement(lnoids);
+ }
+ if (lloids != NULL) {
+ doEOScalarReplacement(lloids);
+ }
+ }
+ }
+
+ if (_scinfo) {
+ os_sc << "================ > " ;
+ irManager.getMethodDesc().printFullName(os_sc);
+ os_sc << std::endl;
+ }
+} // scanEscapedObjects()
+
+
+void
+EscAnalyzer::doLOScalarReplacement(ObjIds* loids) {
+ ObjIds::iterator lo_it;
+ CnGNode* onode;
+ Opnd* oopnd;
+ Type* otype;
+ Inst* inst;
+ Inst* st_inst;
+ Insts::iterator it3;
+ OpndManager& _opndManager = irManager.getOpndManager();
+ InstFactory& _instFactory = irManager.getInstFactory();
+ ScObjFlds* scObjFlds = new (eaMemManager) ScObjFlds(eaMemManager);
+ ScObjFld* sco = NULL;
+ ScObjFlds::iterator ito;
+
+ if (loids == NULL)
+ return;
+ if (loids->size() == 0)
+ return;
+ for (lo_it=loids->begin(); lo_it!=loids->end(); lo_it++) {
+ onode = findCnGNode_op(*lo_it);
+ if (onode == NULL) {
+ if (_scinfo) {
+ os_sc << " - - no cng node for opId " << *lo_it << std::endl;
+ }
+ continue;
+ }
+ if (onode->nodeRefType == NR_PRIM) {
+ continue;
+ }
+ oopnd = (Opnd*)(onode->refObj);
+ otype = oopnd->getType();
+ if (_scinfo) {
+ os_sc << " - - method: ";
+ irManager.getMethodDesc().printFullName(os_sc);
+ os_sc << std::endl;
+ if (onode->nodeRefType == NR_REF)
+ os_sc << " - - scalarized local instance ";
+ else
+ os_sc << " - - scalarized local array ";
+ os_sc << " "; printCnGNode(onode,os_sc);
+ ((Opnd*)onode->refObj)->printWithType(os_sc);
+ os_sc << std::endl;
+ }
+
+ // to collect stind & ldind instructions
+ scObjFlds->clear();
+ collectStLdInsts(onode, scObjFlds);
+
+ if (_scinfo) {
+ os_sc << " found objects " << scObjFlds->size() << std::endl;
+ }
+
+ if (onode->nodeType == NT_LDOBJ) {
+ if (_scinfo) {
+ os_sc << "*-*-*- not optimized " << std::endl;
+ }
+ continue;
+ }
+
+ if (scObjFlds->size() > 0) {
+ for (ito = scObjFlds->begin( ); ito != scObjFlds->end( ); ito++ ){
+ sco = (*ito);
+ if (sco->ls_insts->size()==0) {
+ continue;
+ }
+ bool do_fld_sc = false;
+ for (it3 = sco->ls_insts->begin(); it3 != sco->ls_insts->end( ); it3++ ) {
+ if ((*it3)->getOpcode() == Op_TauLdInd) {
+ do_fld_sc = true;
+ break;
+ }
+ }
+ if (do_fld_sc) {
+ Type* fl_type = NULL;
+ Inst* ii = sco->ls_insts->front();
+ if (ii->getOpcode()==Op_TauStInd) {
+ fl_type = ii->getSrc(1)->getType()->asPtrType()->getPointedToType();
+ } else {
+ fl_type = ii->getSrc(0)->getType()->asPtrType()->getPointedToType();
+ }
+ VarOpnd* fl_var_opnd = _opndManager.createVarOpnd(fl_type, false);
+ SsaTmpOpnd* fl_init_opnd = _opndManager.createSsaTmpOpnd(fl_type);
+ Inst* ld_init_val_inst = NULL;
+ Inst* st_init_val_inst = NULL;
+ sco->fldVarOpnd = fl_var_opnd;
+
+ if (_scinfo) {
+ os_sc<<" PoitedType "; fl_type->print(os_sc); os_sc <<std::endl;
+ }
+ if (fl_type->isReference()) {
+ ld_init_val_inst = _instFactory.makeLdNull(fl_init_opnd);
+ } else {
+ ld_init_val_inst = _instFactory.makeLdConst(fl_init_opnd, 0);
+ }
+ st_init_val_inst = _instFactory.makeStVar(fl_var_opnd, fl_init_opnd);
+
+ scalarizeOFldUsage(sco);
+ if (_scinfo) {
+ os_sc << "++++ old newobj added fld_var: before" << std::endl;
+ FlowGraph::print(os_sc,onode->nInst->getNode());
+ os_sc << "++++ old newobj: before end" << std::endl;
+ }
+ ld_init_val_inst->insertBefore(onode->nInst);
+ _instFactory.makeStVar(fl_var_opnd,fl_init_opnd)->insertBefore(onode->nInst);
+ if (_scinfo) {
+ os_sc << "++++ old newobj added fld_var: after" << std::endl;
+ FlowGraph::print(os_sc,onode->nInst->getNode());
+ os_sc << "++++ old newobj: after end" << std::endl;
+ }
+ } else { // there was no ldind instructions
+ for (it3 = sco->ls_insts->begin(); it3 != sco->ls_insts->end( ); it3++ ) {
+ st_inst = *it3;
+ removeInst(st_inst);
[... 1779 lines stripped ...]