in vm/jitrino/src/optimizer/syncopt.cpp [1782:2020]
void SyncOpt::findBalancedExits(bool optimistic, bool use_IncRecCount)
{
OpndManager &opndManager = irManager.getOpndManager();
InstFactory &instFactory = irManager.getInstFactory();
ControlFlowGraph &fg = irManager.getFlowGraph();
U_32 numNodes = fg.getMaxNodeId();
SyncOptDfValue *entrySolution, *exitSolution;
U_32 numCliques = findBalancedExits_Stage1(optimistic, use_IncRecCount, numNodes,
entrySolution, exitSolution);
if (Log::isEnabled()) {
Log::out() << "numNodes is " << (int) numNodes << ::std::endl;
Log::out() << "numCliques is " << (int) numCliques << ::std::endl;
}
SyncClique *cliquesHeap = new (mm) SyncClique[numCliques];
SyncClique **entryCliques = new (mm) SyncClique *[numNodes];
SyncClique **exitCliques = new (mm) SyncClique *[numNodes];
U_32 cliqueHeapIndex = 0;
{
for (U_32 i = 0; i<numNodes; i++) {
U_32 lin = entrySolution[i].getDepth();
U_32 lout = exitSolution[i].getDepth();
entryCliques[i] = &cliquesHeap[cliqueHeapIndex];
cliqueHeapIndex += lin;
exitCliques[i] = &cliquesHeap[cliqueHeapIndex];
cliqueHeapIndex += lout;
if (Log::isEnabled()) {
Log::out() << " node " << (int) i << " has " << (int) lin << " cliques in: [ ";
for (U_32 j = 0; j<lin; ++j) {
entryCliques[i][j].print(Log::out());
Log::out() << " ";
}
Log::out() << "]" << ::std::endl;
Log::out() << " node " << (int) i << " has " << (int) lout << " cliques out: [ ";
for (U_32 jout = 0; jout<lout; ++jout) {
exitCliques[i][jout].print(Log::out());
Log::out() << " ";
}
Log::out() << "]" << ::std::endl;
}
}
}
assert(cliqueHeapIndex <= numCliques);
if (Log::isEnabled()) {
Log::out() << "finished dataflow solution" << ::std::endl;
}
SyncClique *bottomClique = new (mm) SyncClique();
if (Log::isEnabled()) {
Log::out() << "Bottom clique is ";
bottomClique->print(Log::out());
Log::out() << ::std::endl;
}
// process each node and edge (except exception edges) to union monitor cliques
StlMap<Inst *, StlVectorSet<SyncClique *> *> needRecCount(mm);
StlMap<Inst *, SyncClique *> monitorCliques(mm);
findBalancedExits_Stage2(optimistic, use_IncRecCount,
entrySolution, exitSolution,
bottomClique, entryCliques, exitCliques,
needRecCount, monitorCliques);
// now, each monitorEnter/Exit has an associated clique,
// and we have applied UnionFind::link to them appropriately (ignoring monexit exceptions)
// if usereccount, then needRecCount[invalidateInst]=cliques to be incremented
// before the invalidating instruction
// also, needRecCount[monitorExit]=cliques to be invalidated if monitorExit opnd
// doesn't match, or if the monitorExit clique is/was invalidated
SyncClique *bottomCliqueRoot = bottomClique->find();
if (Log::isEnabled()) {
Log::out() << "Bottom clique root is ";
bottomCliqueRoot->print(Log::out());
Log::out() << ::std::endl;
}
// stage 3a
// stage 3b:
// at this point, opnd should be set for each clique root; check whether
// monitorExit opnd matches the clique opnd, if not, add it to newBadMonitorExits.
findBalancedExits_Stage3(optimistic, use_IncRecCount,
entrySolution, exitSolution,
bottomClique, entryCliques, exitCliques,
needRecCount, monitorCliques);
// at this point, a monitor inst monInst is unbalanced if monitorCliques[monInst] =~ bottom
// stage 3: Now that we know which cliques are balanceable, modify code.
// Other cliques we don't bother with.
{
StlMap<Inst *, SyncClique *>::iterator
miter = monitorCliques.begin(),
mend = monitorCliques.end();
for ( ; miter != mend; ++miter) {
Inst *inst = (*miter).first;
SyncClique *clique = (*miter).second;
if (Log::isEnabled()) {
Log::out() << "Considering balancing instruction: ";
inst->print(Log::out());
Log::out() << " with ";
clique->print(Log::out());
Log::out() << ::std::endl;
}
clique = clique->find();
if ((clique == bottomCliqueRoot)) {
if (Log::isEnabled()) {
Log::out() << " Clique == bottom" << ::std::endl;
}
continue;
}
{
// we can balance it
Opnd *obj = inst->getSrc(0);
assert(obj == clique->opnd);
VarOpnd *lockVar = getLockVar(obj);
VarOpnd *oldValueVar = getOldValueOpnd(clique);
Opnd *lockAddrTmp = opndManager.createSsaTmpOpnd(lockAddrType);
Opnd *oldValueTmp = opndManager.createSsaTmpOpnd(lockType);
Opnd *tau = 0;
switch (inst->getOpcode()) {
case Op_TauOptimisticBalancedMonitorEnter:
if (optimistic) break; // we can ignore this if optimistic, otherwise try to convert it to unoptimistic balmonenter
tau = inst->getSrc(2);
case Op_TauMonitorEnter:
{
if (!tau)
tau = inst->getSrc(1);
assert(tau->getType()->tag == Type::Tau);
Inst *ldVarLockAddr = instFactory.makeLdVar(lockAddrTmp, lockVar);
Inst *balmonenter = (optimistic
? instFactory.makeTauOptimisticBalancedMonitorEnter(oldValueTmp,
obj,
lockAddrTmp,
tau)
: instFactory.makeTauBalancedMonitorEnter(oldValueTmp,
obj,
lockAddrTmp,
tau));
Inst *stVarOldValue = instFactory.makeStVar(oldValueVar, oldValueTmp);
ldVarLockAddr->insertAfter(inst);
balmonenter->insertAfter(ldVarLockAddr);
stVarOldValue->insertAfter(balmonenter);
inst->unlink();
}
break;
case Op_OptimisticBalancedMonitorExit:
if (optimistic) break; // we can ignore this if optimistic, otherwise convert it to un-optimistic balmonexit
case Op_TauMonitorExit:
{
Inst *ldVarLockAddr = instFactory.makeLdVar(lockAddrTmp, lockVar);
Inst *ldVarOldValue = instFactory.makeLdVar(oldValueTmp,
oldValueVar);
Inst *balmonexit = (optimistic
? instFactory.makeOptimisticBalancedMonitorExit(obj,
lockAddrTmp,
oldValueTmp)
: instFactory.makeBalancedMonitorExit(obj,
lockAddrTmp,
oldValueTmp));
ldVarLockAddr->insertAfter(inst);
ldVarOldValue->insertAfter(ldVarLockAddr);
balmonexit->insertAfter(ldVarOldValue);
if (!optimistic) {
// remove exception edge
Node *node = inst->getNode();
Edge* edge = (Edge *)node->getExceptionEdge();
assert(edge != NULL);
fg.removeEdge(edge);
}
inst->unlink();
}
break;
default:
break;
}
}
}
}
if (use_IncRecCount) {
StlVectorSet<SyncClique *> doneCliques(mm);
StlMap<Inst *, StlVectorSet<SyncClique *> *>::iterator
miter = needRecCount.begin(),
mend = needRecCount.end();
for ( ; miter != mend; ++miter) {
Inst *invalidatingInst = (*miter).first;
StlVectorSet<SyncClique *> *cliques = (*miter).second;
assert(cliques);
if (Log::isEnabled()) {
Log::out() << "Considering increccount for instruction: ";
invalidatingInst->print(Log::out());
Log::out() << ::std::endl;
}
doneCliques.clear();
StlVectorSet<SyncClique *>::iterator
cliter = cliques->begin(),
clend = cliques->end();
for ( ; cliter != clend; ++cliter) {
SyncClique *thisClique = *cliter;
thisClique = thisClique->find();
if ((thisClique != bottomCliqueRoot) &&
!doneCliques.has(thisClique)) {
doneCliques.insert(thisClique);
Opnd *obj = thisClique->opnd;
assert(obj);
// insert incrreccount
VarOpnd *oldValueVar = getOldValueOpnd(thisClique);
Opnd *oldValueTmp = opndManager.createSsaTmpOpnd(lockType);
Inst *ldVarOldValue = instFactory.makeLdVar(oldValueTmp,
oldValueVar);
Inst *increcInst = instFactory.makeIncRecCount(obj, oldValueTmp);
ldVarOldValue->insertBefore(invalidatingInst);
increcInst->insertAfter(ldVarOldValue);
}
}
}
}
}