You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by mf...@apache.org on 2007/10/16 14:03:18 UTC
svn commit: r585128 - in /harmony/enhanced/drlvm/trunk/vm/jitrino/src:
optimizer/FlowGraph.cpp shared/LoopTree.cpp
translator/java/JavaFlowGraphBuilder.cpp
translator/java/JavaFlowGraphBuilder.h translator/java/JavaLabelPrepass.cpp
Author: mfursov
Date: Tue Oct 16 05:03:11 2007
New Revision: 585128
URL: http://svn.apache.org/viewvc?rev=585128&view=rev
Log:
Fix for HARMONY-4948 [drlvm][jit] Avoid generation of IR with dispatch nodes as loop headers
Modified:
harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/LoopTree.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaFlowGraphBuilder.cpp
harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaFlowGraphBuilder.h
harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.cpp
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.cpp?rev=585128&r1=585127&r2=585128&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/FlowGraph.cpp Tue Oct 16 05:03:11 2007
@@ -348,57 +348,6 @@
}
}
-
-
-
-static void breakMonitorExitLoop(ControlFlowGraph& fg, Node* node, Inst* monExit) {
-
- // Look for the following type of loop where a handler with a
- // monitorexit handles itself.
- // D1:
- //
- // B1:
- // t1 = catch
- // ...
- //
- // B2:
- // monitorExit t2 ---> D1
- assert(node->getLastInst() == monExit);
- assert(monExit->getOpcode() == Op_TauMonitorExit);
-
- Node* dispatch = node->getExceptionEdge()->getTargetNode();
- Node* catchBlock = node;
- std::vector<Edge*> exceptionEdges;
- exceptionEdges.push_back(node->getExceptionEdge());
-
- // Look for a catchBlock that dominates the node. Assume no control flow.
- while(!((Inst*)catchBlock->getFirstInst())->isCatchLabel() && catchBlock->getInEdges().size() == 1) {
- catchBlock = catchBlock->getInEdges().front()->getSourceNode();
- Edge* exceptionEdge = catchBlock->getExceptionEdge();
- if(exceptionEdge == NULL || exceptionEdge->getTargetNode() != dispatch)
- return;
- exceptionEdges.push_back(exceptionEdge);
- }
-
- if(((Inst*)catchBlock->getFirstInst())->isCatchLabel()) {
- // We are in a catch.
- if(dispatch->findTargetEdge(catchBlock)) {
- // We have a cycle!
- Node* newDispatch = dispatch->getExceptionEdge()->getTargetNode();
- assert(newDispatch != NULL);
-
- std::vector<Edge*>::iterator i;
- for(i = exceptionEdges.begin(); i != exceptionEdges.end(); ++i) {
- Edge* exceptionEdge = *i;
- assert(exceptionEdge->getTargetNode() == dispatch);
- fg.replaceEdgeTarget(exceptionEdge, newDispatch);
- }
- }
- }
-}
-
-
-
//
// used to find 'saveret' that starts the node
// 'labelinst' and 'stvar' are skipped
@@ -847,10 +796,17 @@
InstFactory& instFactory = irm.getInstFactory();
OpndManager& opndManager = irm.getOpndManager();
+
static CountTime cleanupPhaseTimer("ptra::fg::cleanupPhase");
AutoTimer tm(cleanupPhaseTimer);
fg.purgeUnreachableNodes();
+#ifdef _DEBUG
+ //check if loop structure is valid after translator
+ OptPass::computeLoops(irm, false);
+#endif
+
+
inlineJSRs(&irm);
fg.purgeUnreachableNodes();
@@ -866,11 +822,7 @@
continue;
}
Inst *last = (Inst*)node->getLastInst();
- if (last->getOpcode() == Op_TauMonitorExit) {
- // Check for monitor exit loop.
- breakMonitorExitLoop(fg, node, last);
- }
- else if (last->isBranch()) {
+ if (last->isBranch()) {
if (last->isLeave()) {
// Inline Finally - only necessary after translation
inlineFinally(irm, node);
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/LoopTree.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/LoopTree.cpp?rev=585128&r1=585127&r2=585128&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/LoopTree.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/LoopTree.cpp Tue Oct 16 05:03:11 2007
@@ -50,6 +50,7 @@
for(eiter = edges.begin(); eiter != edges.end(); ++eiter) {
Node* pred = (*eiter)->getSourceNode();
if (dom->dominates(n, pred)) {
+ assert(n->isBlockNode());
headers.push_back(n);
break;
}
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaFlowGraphBuilder.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaFlowGraphBuilder.cpp?rev=585128&r1=585127&r2=585128&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaFlowGraphBuilder.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaFlowGraphBuilder.cpp Tue Oct 16 05:03:11 2007
@@ -273,186 +273,8 @@
// second phase: construct edges
//
createCFGEdges();
-
- eliminateUnnestedLoopsOnDispatch();
-}
-
-
-//
-// look for edge patterns like this:
-//
-// D C
-// C S
-// S has >1 in-edges
-// D has >1 in-edges
-//
-// S -- start node (sycle header)
-// D -- dispatch node
-// C -- catch node
-//
-// and this:
-//
-// S ME
-// ME D
-// S D
-// D C
-// C S
-// S has >1 in-edges
-// D has >2 in-edges
-//
-// S -- start node (sycle header)
-// D -- dispatch node
-// C -- catch node
-// ME -- node with last instruction: 'monitorexit'
-//
-// when found,
-// for each in-node of D (except 1st) do
-// duplicate D -> D2,
-// retarget the in-node to D2
-// for all nodes (Cx) following D
-// if catch node
-// duplicate Cx -> Cy
-// add edge 'D2 Cy'
-// add edge 'Cy succ(Cx)' // assertion failure if many succsessors
-// else
-// add edge 'D2 Cx'
-//
-void JavaFlowGraphBuilder::eliminateUnnestedLoopsOnDispatch()
-{
- MemoryManager matched_nodes_mm("unnested_loops_mm");
- Nodes matched_dispatches(matched_nodes_mm);
- bool found_goto_into_loop_warning = false;
- const Nodes& nodes = fg->getNodes();
- Nodes::const_iterator niter;
- for (niter = nodes.begin(); niter != nodes.end(); ++niter) {
- Node* dispatch = *niter;
- if ( dispatch->isDispatchNode() && dispatch->getInDegree() > 1 ) {
- const Edges& out_edges = dispatch->getOutEdges();
- for (Edges::const_iterator out_iter = out_edges.begin();
- out_iter != out_edges.end();
- out_iter++) {
-
- Node* catch_node = (*out_iter)->getTargetNode();
- if ( !catch_node->isCatchBlock() ) {
- continue;
- }
- Node* catch_target = (*(catch_node->getOutEdges().begin()))->getTargetNode();
- if ( catch_target->getInDegree() <= 1 ) {
- continue;
- }
- bool found_monitorexit = false;
- bool dispatch_is_after_target = false;
- bool monitorexit_after_catch_target = false;
- bool monitorexit_after_catch = false;
- // number of edges leading
- // from within the searched loop to the current dispatch
- uint32 eins_from_loop = 0;
- const Edges& in_edges = dispatch->getInEdges();
- for (Edges::const_iterator in_iter = in_edges.begin();
- in_iter != in_edges.end();
- in_iter++) {
- Node* pre_dispatch = (*in_iter)->getSourceNode();
- if ( pre_dispatch == catch_target ) {
- dispatch_is_after_target = true;
- eins_from_loop++;
- }
- if ( lastInstIsMonitorExit(pre_dispatch) ) {
- found_monitorexit = true;
- const Edges& in_monexit_edges = pre_dispatch->getInEdges();
- Edges::const_iterator in_monexit_it = in_monexit_edges.begin();
- Edges::const_iterator in_monexit_end = in_monexit_edges.end();
- for (; in_monexit_it != in_monexit_end; in_monexit_it++) {
- Node* mon_pred = (*in_monexit_it)->getSourceNode();
- if ( mon_pred == catch_target ) {
- monitorexit_after_catch_target = true;
- eins_from_loop++;
- assert(((Inst*)catch_target->getLastInst())->getOpcode() == Op_TauCheckNull);
- }
- if ( mon_pred == catch_node ) {
- monitorexit_after_catch = true;
- }
- }
- }
- }
-
- if ( Log::isEnabled() ) {
- Log::out() << "eliminateUnnestedLoopsOnDispatch()" << std::endl;
- Log::out() << " monitorexit_after_catch_target="
- << monitorexit_after_catch_target << std::endl;
- Log::out() << " dispatch_is_after_target="
- << dispatch_is_after_target << std::endl;
- Log::out() << " monitorexit_after_catch="
- << monitorexit_after_catch << std::endl;
- }
-
- if ( dispatch->getInDegree() <= eins_from_loop ) {
- // no second entrance into the loop
- continue;
- }
- if ( found_monitorexit &&
- ((monitorexit_after_catch_target && dispatch_is_after_target) ||
- monitorexit_after_catch)) {
-
- matched_dispatches.push_back(dispatch);
- if ( Log::isEnabled() ) {
- Log::out() << "goto into loop found, fixing..." << std::endl;
- }
- break;
- }
- if ( !found_goto_into_loop_warning ) {
- if ( Log::isEnabled() ) {
- Log::out() << "warning: maybe goto into loop with exception"
- << std::endl;
- }
- found_goto_into_loop_warning = true;
- }
- }
- }
- }
- InstFactory* instFactory = irBuilder.getInstFactory();
- for ( Nodes::const_iterator dispatch_iter = matched_dispatches.begin();
- dispatch_iter != matched_dispatches.end();
- dispatch_iter++ ) {
-
- Node* dispatch = (*dispatch_iter);
- const Edges& in_edges = dispatch->getInEdges();
- assert(dispatch->getInDegree() > 1);
- while (in_edges.size() > 1) {
- Edge* in_edge = *(++in_edges.begin());
- Node* dup_dispatch = createDispatchNode();
- fg->replaceEdgeTarget(in_edge, dup_dispatch);
- const Edges& out_edges = dispatch->getOutEdges();
- for (Edges::const_iterator out_edge_iter = out_edges.begin();
- out_edge_iter != out_edges.end();
- out_edge_iter++) {
- Node* dispatch_target = (*out_edge_iter)->getTargetNode();
- if ( !dispatch_target->isCatchBlock() ) {
- fg->addEdge(dup_dispatch, dispatch_target);
- }else{
- CatchLabelInst* catch_label = (CatchLabelInst*)dispatch_target->getFirstInst();
- assert(dispatch_target->getInstCount() == 0);
- LabelInst* dupCatchInst = instFactory->makeCatchLabel( catch_label->getOrder(), catch_label->getExceptionType());
- dupCatchInst->setBCOffset(catch_label->getBCOffset());
- Node* dup_catch = createBlockNodeOrdered(dupCatchInst);
- fg->addEdge(dup_dispatch, dup_catch);
- assert(dispatch_target->getOutDegree() == 1);
- fg->addEdge(dup_catch, (*dispatch_target->getOutEdges().begin())->getTargetNode());
- }
-
- }
- }
- }
}
-bool JavaFlowGraphBuilder::lastInstIsMonitorExit(Node* node)
-{
- Inst* last = (Inst*)node->getLastInst();
- if ( last->getOpcode() == Op_TypeMonitorExit ||
- last->getOpcode() == Op_TauMonitorExit ) {
- return true;
- }
- return false;
-}
JavaFlowGraphBuilder::JavaFlowGraphBuilder(MemoryManager& mm, IRBuilder &irB) :
memManager(mm), currentBlock(NULL), irBuilder(irB), fallThruNodes(mm)
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaFlowGraphBuilder.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaFlowGraphBuilder.h?rev=585128&r1=585127&r2=585128&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaFlowGraphBuilder.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaFlowGraphBuilder.h Tue Oct 16 05:03:11 2007
@@ -46,9 +46,7 @@
Node* edgesForBlock(Node* block);
void edgesForHandler(Node* entry);
void edgeForFallthrough(Node* block);
- void eliminateUnnestedLoopsOnDispatch();
- bool lastInstIsMonitorExit(Node* node);
-
+
Node* createBlockNodeOrdered(LabelInst* label);
Node* createBlockNodeAfter(Node* node, LabelInst* label);
void addEdge(Node* source, Node* target);
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.cpp?rev=585128&r1=585127&r2=585128&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.cpp Tue Oct 16 05:03:11 2007
@@ -453,11 +453,36 @@
//
// add new CatchBlock
//
- prevCatch = catchBlock =
- new (memManager) CatchBlock(nextRegionId++, tryOffset, endOffset, numCatch++);
- prepass.stateTable->getStateInfo(tryOffset)->addExceptionInfo(catchBlock);
- prepass.exceptionTable.push_back(catchBlock);
- addHandlerForCatchBlock(catchBlock, handlerOffset, exceptionType);
+ if (handlerOffset < endOffset && handlerOffset > tryOffset) {
+ //self-handling block: add 2 CatchBlocks(ExceptionInfos) with the following boundaries:
+ //[tryOffset, handlerOffset], [handlerOffset, endOffset]
+ //The reason is to avoid loops with dispatch node as header:
+ // Details:
+ // For a single CatchBlock(ExceptionInfo) we have only 1 dispatch node today
+ // (dispatch node is referenced by LabelInfo field in ExceptionInfo structure)
+ // Having single dispatch node for self-catching regions we will have a loop with
+ // dispatch node as a loop-header.
+ // To avoid having dispatch nodes as a loop-header we create 2 (CatchBlocks)ExceptionInfos here:
+ // doing this we have 2 dispatch nodes for 2 ExceptionInfos and loop-header is automatically
+ // moved to the next (after the second dispatch)block node with CatchLabelInst instruction.
+ // Example to reproduce: comment out this if clause and check IR for monexit loops.
+
+ prevCatch = catchBlock = new (memManager) CatchBlock(nextRegionId++, tryOffset, handlerOffset, numCatch++);
+ prepass.stateTable->getStateInfo(tryOffset)->addExceptionInfo(catchBlock);
+ prepass.exceptionTable.push_back(catchBlock);
+ addHandlerForCatchBlock(catchBlock, handlerOffset, exceptionType);
+
+ prevCatch = catchBlock = new (memManager) CatchBlock(nextRegionId++, handlerOffset, endOffset, numCatch++);
+ prepass.stateTable->getStateInfo(handlerOffset)->addExceptionInfo(catchBlock);
+ prepass.exceptionTable.push_back(catchBlock);
+ addHandlerForCatchBlock(catchBlock, handlerOffset, exceptionType);
+ } else {
+ prevCatch = catchBlock = new (memManager) CatchBlock(nextRegionId++, tryOffset, endOffset, numCatch++);
+ prepass.stateTable->getStateInfo(tryOffset)->addExceptionInfo(catchBlock);
+ prepass.exceptionTable.push_back(catchBlock);
+ addHandlerForCatchBlock(catchBlock, handlerOffset, exceptionType);
+ }
+
}
return 1; // all exceptionTypes are OK
}