You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by eg...@apache.org on 2009/04/12 21:05:30 UTC

svn commit: r764315 - in /harmony/enhanced/drlvm/trunk/vm/jitrino: config/em64t/ config/ia32/ src/optimizer/ src/optimizer/abcd/

Author: egor
Date: Sun Apr 12 19:05:29 2009
New Revision: 764315

URL: http://svn.apache.org/viewvc?rev=764315&view=rev
Log:
HARMONY-6007 [drlvm][jit][abcd] classic abcd pass fixes

0001-more-constrained-operands-and-new-pi-operand-renamin.patch

ran test2 and smoke.test on server_static on x86/Ubuntu, DaCapo:
    no new bugs found, eliminates checks now

Modified:
    harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server.emconf
    harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server_static.emconf
    harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf
    harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_aggressive.emconf
    harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.emconf
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/abcd/classic_abcd.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/abcd/classic_abcd_solver.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/abcd/classic_abcd_solver.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/abcd/insertpi.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/opndmap.h

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server.emconf?rev=764315&r1=764314&r2=764315&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server.emconf Sun Apr 12 19:05:29 2009
@@ -81,7 +81,7 @@
 -XX:jit.SD2_OPT.path.optimizer=ssa,simplify,dce,uce,devirt_virtual,edge_annotate,unguard,devirt_intf,hlo_api_magic,inline,purge,simplify,dce,uce,osr_path,escape_path,dce,uce,hvn,dce,uce,inline_helpers,purge,simplify,uce,dce,uce,abce,lower,dce,uce,memopt,dce,uce,hvn,dce,uce,gcm,dessa,statprof
 -XX:jit.SD2_OPT.path.osr_path=gcm,osr,simplify,dce,uce
 -XX:jit.SD2_OPT.path.escape_path=hvn,simplify,dce,uce,escape
--XX:jit.SD2_OPT.path.abce=classic_abcd,dce,uce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,memopt,dce,uce,dessa,fastArrayFill,ssa,statprof,dabce,dce,uce
+-XX:jit.SD2_OPT.path.abce=memopt,dce,uce,simplify,dce,uce,classic_abcd,dce,uce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,memopt,dce,uce,dessa,fastArrayFill,ssa,statprof,dabce,dce,uce
 -XX:jit.SD2_OPT.path.codegen=lock_method,bbp,gcpoints,cafl,dce1,i8l-,api_magic,light_jni-,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

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server_static.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server_static.emconf?rev=764315&r1=764314&r2=764315&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server_static.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/em64t/server_static.emconf Sun Apr 12 19:05:29 2009
@@ -35,7 +35,7 @@
 -XX:jit.SS_OPT.path.optimizer=ssa,simplify,dce,uce,statprof,devirt_virtual,unguard,devirt_intf,hlo_api_magic,inline,purge,simplify,dce,uce,osr_path,escape_path,dce,uce,hvn,dce,uce,inline_helpers-,purge,simplify,uce,dce,uce,abce,lower,dce,uce,memopt,dce,uce,hvn,dce,uce,gcm,dessa,statprof
 -XX:jit.SS_OPT.path.osr_path=gcm,osr,simplify,dce,uce
 -XX:jit.SS_OPT.path.escape_path=hvn,simplify,dce,uce,escape
--XX:jit.SS_OPT.path.abce=classic_abcd,dce,uce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,memopt,dce,uce,dessa,fastArrayFill,ssa,statprof,dabce,dce,uce
+-XX:jit.SS_OPT.path.abce=memopt,dce,uce,simplify,dce,uce,classic_abcd,dce,uce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,memopt,dce,uce,dessa,fastArrayFill,ssa,statprof,dabce,dce,uce
 -XX:jit.SS_OPT.path.codegen=bbp,gcpoints,cafl,dce1,i8l-,api_magic,light_jni-,early_prop-,itrace-,native,cg_fastArrayFill,constraints,dce2,regalloc,spillgen,layout,copy,rce-,stack,break-,iprof-,emitter!,si_insts,gcmap,info
 -XX:jit.SS_OPT.path.dce1=cg_dce
 -XX:jit.SS_OPT.path.dce2=cg_dce

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf?rev=764315&r1=764314&r2=764315&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server.emconf Sun Apr 12 19:05:29 2009
@@ -83,7 +83,7 @@
 -XX:jit.SD2_OPT.path.optimizer=ssa,simplify,dce,uce,devirt_virtual,edge_annotate,unguard,devirt_intf,hlo_api_magic,inline,purge,simplify,dce,uce,osr_path,lazyexc,throwopt,escape_path,inline_helpers,purge,simplify,uce,dce,uce,abce,lower,dce,uce,statprof,unroll,ssa,simplify,dce,uce,memopt,dce,uce,hvn,dce,uce,gcm,dessa,statprof
 -XX:jit.SD2_OPT.path.osr_path=gcm,osr,simplify,dce,uce
 -XX:jit.SD2_OPT.path.escape_path=hvn,simplify,dce,uce,escape
--XX:jit.SD2_OPT.path.abce=classic_abcd,dce,uce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,memopt,dce,uce,dessa,fastArrayFill,ssa,statprof,dabce,dce,uce
+-XX:jit.SD2_OPT.path.abce=memopt,dce,uce,simplify,dce,uce,classic_abcd,dce,uce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,memopt,dce,uce,dessa,fastArrayFill,ssa,statprof,dabce,dce,uce
 -XX:jit.SD2_OPT.path.codegen=lock_method,bbp,btr,gcpoints,cafl,dce1,i8l,api_magic,light_jni-,early_prop,global_prop,peephole,itrace-,native,cg_fastArrayFill,constraints,dce2,regalloc,spillgen,copy,i586,layout,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
 -XX:jit.SD2_OPT.path.dce1=cg_dce
 -XX:jit.SD2_OPT.path.dce2=cg_dce

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_aggressive.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_aggressive.emconf?rev=764315&r1=764314&r2=764315&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_aggressive.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_aggressive.emconf Sun Apr 12 19:05:29 2009
@@ -76,7 +76,7 @@
 -XX:jit.SD2_OPT.path.optimizer=ssa,simplify,dce,uce,edge_annotate,devirt,hlo_api_magic,inline,purge,osr_path-,simplify,dce,uce,lazyexc,throwopt,escape_path,inline_helpers,purge,simplify,uce,dce,uce,abce,lower,dce,uce,statprof,unroll,ssa,simplify,dce,uce,memopt,dce,uce,hvn,dce,uce,gcm,dessa,statprof,markglobals
 -XX:jit.SD2_OPT.path.osr_path=simplify,dce,uce,gcm,osr
 -XX:jit.SD2_OPT.path.escape_path=hvn,simplify,dce,uce,escape
--XX:jit.SD2_OPT.path.abce=classic_abcd,dce,uce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,memopt,dce,uce,dessa,fastArrayFill,ssa,statprof,dabce,dce,uce
+-XX:jit.SD2_OPT.path.abce=memopt,dce,uce,simplify,dce,uce,classic_abcd,dce,uce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,memopt,dce,uce,dessa,fastArrayFill,ssa,statprof,dabce,dce,uce
 
 -XX:jit.SD2_OPT.path.codegen=lock_method,bbp,btr,gcpoints,cafl,dce1,i8l,api_magic,early_prop,global_prop,peephole,itrace-,native,cg_fastArrayFill,constraints,dce2,regalloc,spillgen,copy,i586,layout,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
 -XX:jit.SD2_OPT.path.dce1=cg_dce

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.emconf
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.emconf?rev=764315&r1=764314&r2=764315&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.emconf (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/config/ia32/server_static.emconf Sun Apr 12 19:05:29 2009
@@ -35,7 +35,7 @@
 -XX:jit.SS_OPT.path.optimizer=ssa,simplify,dce,uce,devirt_virtual,statprof,unguard,devirt_intf,hlo_api_magic,inline,purge,simplify,dce,uce,osr_path,lazyexc,throwopt,escape_path,inline_helpers-,purge,simplify,uce,dce,uce,abce,lower,dce,uce,statprof,unroll,ssa,simplify,dce,uce,memopt,dce,uce,hvn,dce,uce,gcm,dessa,statprof
 -XX:jit.SS_OPT.path.osr_path=gcm,osr,simplify,dce,uce
 -XX:jit.SS_OPT.path.escape_path=hvn,simplify,dce,uce,escape
--XX:jit.SS_OPT.path.abce=classic_abcd,dce,uce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,memopt,dce,uce,dessa,fastArrayFill,ssa,statprof,dabce,dce,uce
+-XX:jit.SS_OPT.path.abce=memopt,dce,uce,simplify,dce,uce,classic_abcd,dce,uce,dessa,statprof,peel,ssa,hvn,simplify,dce,uce,memopt,dce,uce,dessa,fastArrayFill,ssa,statprof,dabce,dce,uce
 -XX:jit.SS_OPT.path.codegen=lock_method,bbp,btr,gcpoints,cafl,dce1,i8l,api_magic,light_jni-,early_prop,global_prop,peephole,itrace-,native,cg_fastArrayFill,constraints,dce2,regalloc,spillgen,copy,i586,layout,rce+,stack,break-,iprof-,peephole,emitter!,si_insts,gcmap,info,unlock_method
 -XX:jit.SS_OPT.path.dce1=cg_dce
 -XX:jit.SS_OPT.path.dce2=cg_dce

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/abcd/classic_abcd.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/abcd/classic_abcd.cpp?rev=764315&r1=764314&r2=764315&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/abcd/classic_abcd.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/abcd/classic_abcd.cpp Sun Apr 12 19:05:29 2009
@@ -64,7 +64,7 @@
         }
     }
 
-    Opnd* getOrg() const { assert(_opnd); return _opnd; }
+    Opnd* getOrg() const { return _opnd; }
 
     static U_32 getProxyIdByOpnd(Opnd* opnd);
 private:
@@ -150,7 +150,7 @@
 
 class BuildInequalityGraphWalker {
 public:
-    BuildInequalityGraphWalker(InequalityGraph* igraph, bool isLower) :
+    BuildInequalityGraphWalker(InequalityGraph* igraph) :
         _igraph(igraph), _const_id_counter(1 /*reserve 0 for solver*/),
         _map_opnd_to_pi_inst(igraph->getMemoryManager())
     {}
@@ -325,14 +325,14 @@
             Opnd* src1 = inst->getSrc(1);
             addEdgeIfConstOpnd(proxy_dst, src0, src1, false /* negate */) 
             || addEdgeIfConstOpnd(proxy_dst, src1, src0, false /* negate */);
-        } 
+        }
             break;
         case Op_Sub:
         {
             proxy_dst = addOldOrCreateOpnd(inst->getDst());
             addEdgeIfConstOpnd(proxy_dst, inst->getSrc(1), inst->getSrc(0),
                                true /* negate */ );
-        } 
+        }
             break;
         case Op_TauPi:
         {
@@ -350,10 +350,17 @@
         }
             break;
         case Op_TauArrayLen:
-        case Op_LdConstant:
+        case Op_LdConstant: case Op_LdStatic: case Op_TauLdInd:
+        case Op_TauLdField: case Op_TauLdElem:
+        case Op_DirectCall: case Op_TauVirtualCall: case Op_IndirectCall:
+        case Op_IndirectMemoryCall: case Op_JitHelperCall: case Op_VMHelperCall:
+        case Op_DefArg:
+            // All these load instructions may potentially produce an operand
+            // that would be a parameter to a newarray, hence we need it to be
+            // reachable with inequality edges. Need to keep it constrained.
             addOldOrCreateOpnd(inst->getDst());
             break;
-        case Op_TauStInd: case Op_TauStElem: case Op_TauStField: 
+        case Op_TauStInd: case Op_TauStElem: case Op_TauStField:
         case Op_TauStRef: case Op_TauStStatic:
             break;
         default:
@@ -412,6 +419,12 @@
         }
         _igraph->addEdge(src->getID(), dst->getID(), (I_32)constant);
         return true;
+    } else {
+        if ( Log::isEnabled() ) {
+            Log::out() << "addDistance(): skipping edge, operand is unconstrained: ";
+            src->printName(Log::out());
+            Log::out() << std::endl;
+        }
     }
     return false;
 }
@@ -610,7 +623,7 @@
     insertPi.insertPi();
     InequalityGraph igraph(ineq_mm);
     igraph.addOpnd(_zeroIOp);
-    BuildInequalityGraphWalker igraph_walker(&igraph, false /*lower*/);
+    BuildInequalityGraphWalker igraph_walker(&igraph);
     typedef ScopedDomNodeInst2DomWalker<true, BuildInequalityGraphWalker>
         IneqBuildDomWalker;
     IneqBuildDomWalker dom_walker(igraph_walker);
@@ -644,7 +657,7 @@
             Opnd *tauOp = opndManager.createSsaTmpOpnd(typeManager.getTauType());
             Inst* tau_point = instFactory.makeTauPoint(tauOp);
             tau_point->insertBefore(redundant_inst);
-      
+
             if (Log::isEnabled()) {
                 Log::out() << "Inserted taupoint inst ";
                 tau_point->print(Log::out());
@@ -659,7 +672,7 @@
             copy->insertBefore(redundant_inst);
             FlowGraph::eliminateCheck(cfg, redundant_inst->getNode(), redundant_inst, false);
             checks_eliminated++;
-            
+
             if (Log::isEnabled()) {
                 Log::out() << "Replaced bound check with inst ";
                 copy->print(Log::out());

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/abcd/classic_abcd_solver.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/abcd/classic_abcd_solver.cpp?rev=764315&r1=764314&r2=764315&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/abcd/classic_abcd_solver.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/abcd/classic_abcd_solver.cpp Sun Apr 12 19:05:29 2009
@@ -242,7 +242,7 @@
     os << "];" << std::endl;
 }
 
-void InequalityGraph::printListWithSetExcluded (std::ostream& os, 
+void InequalityGraph::printListWithSetExcluded (std::ostream& os,
     EdgeSet* edge_set, EdgeList* elist, PrnEdgeType ptype) const
 {
     EdgeList::iterator it = elist->begin(),
@@ -257,12 +257,12 @@
 
 void InequalityGraph::printDotBody(std::ostream& os) const
 {
-    IdToOpndMap::const_iterator it = _id_to_opnd_map.begin(), 
+    IdToOpndMap::const_iterator it = _id_to_opnd_map.begin(),
         last = _id_to_opnd_map.end();
     for (; it != last; it++ ) {
         IOpnd* opnd = it->second;
         os << "\""; opnd->printName(os); os << "\"";
-        os << " [label=\"{"; 
+        os << " [label=\"{";
         opnd->printFullName(os);
         os << "}\"];" << std::endl;
     }
@@ -317,13 +317,13 @@
 
 Bound* BoundAllocator::create_inc1(Bound* bound)
 {
-    return newBound(bound->isUpper() ? bound->_bound + 1 : bound->_bound - 1, 
+    return newBound(bound->isUpper() ? bound->_bound + 1 : bound->_bound - 1,
                     bound->getBoundState());
 }
 
 Bound* BoundAllocator::create_dec1(Bound* bound)
 {
-    return newBound(bound->isUpper() ? bound->_bound - 1 :  bound->_bound + 1, 
+    return newBound(bound->isUpper() ? bound->_bound - 1 :  bound->_bound + 1,
                     bound->getBoundState());
 }
 
@@ -334,19 +334,19 @@
 
 //------------------------------------------------------------------------------
 
-void Bound::printFullName(std::ostream& os) 
-{ 
+void Bound::printFullName(std::ostream& os)
+{
     os << "Bound(";
     if ( isUpper() ) {
         os << "upper";
     }else{
         os << "lower";
     }
-    os << ", " << _bound << ")"; 
+    os << ", " << _bound << ")";
 }
 
-bool Bound::leq(Bound* bound1, Bound* bound2) 
-{ 
+bool Bound::leq(Bound* bound1, Bound* bound2)
+{
     assert(bound1 && bound2);
     assert(bound1->isUpper() == bound2->isUpper());
     return Bound::int32_leq(bound1->_bound, bound2);
@@ -355,22 +355,22 @@
 bool Bound::eq(Bound* bound1, Bound* bound2)
 {
     assert(!bound1 || !bound2 || bound1->isUpper() == bound2->isUpper());
-    return bound1 && bound2 && 
+    return bound1 && bound2 &&
         Bound::leq(bound1, bound2) && Bound::leq(bound2, bound1);
 }
 
-bool Bound::leq_int32(Bound* bound1, I_32 value) 
-{ 
+bool Bound::leq_int32(Bound* bound1, I_32 value)
+{
     assert(bound1);
-    return bound1->isUpper() ? 
-        bound1->_bound <= value : 
+    return bound1->isUpper() ?
+        bound1->_bound <= value :
         bound1->_bound >= value;
 }
 
-bool Bound::int32_leq(I_32 value, Bound* bound1) 
-{ 
+bool Bound::int32_leq(I_32 value, Bound* bound1)
+{
     assert(bound1);
-    return bound1->isUpper() ? 
+    return bound1->isUpper() ?
         value <= bound1->_bound :
         value >= bound1->_bound;
 }
@@ -466,7 +466,7 @@
 
     clearRedundantReduced();
     assert(!_min_reduced || Bound::leq(_min_reduced, _min_true));
-    assert(!_max_false || !_min_reduced || 
+    assert(!_max_false || !_min_reduced ||
            Bound::leq(_max_false, _min_reduced));
 }
 
@@ -611,9 +611,9 @@
 //------------------------------------------------------------------------------
 
 Bound* ActiveOpnds::getBound(IOpnd* opnd) const
-{ 
-    assert(hasOpnd(opnd)); 
-    
+{
+    assert(hasOpnd(opnd));
+
     return _map.find(opnd)->second;
 }
 
@@ -645,7 +645,7 @@
     if (Log::isEnabled() ) {
         Log::out() << "demandProve(";
         _source_opnd->printFullName(Log::out());
-        Log::out() << ", "; 
+        Log::out() << ", ";
         dest->printFullName(Log::out());
         Log::out() << ", ";
         bound.printFullName(Log::out());
@@ -664,9 +664,9 @@
     return true;
 }
 
-void ClassicAbcdSolver::updateMemDistanceWithPredecessors (IOpnd* dest, 
-                                                           Bound* bound, 
-                                                           U_32 prn_level, 
+void ClassicAbcdSolver::updateMemDistanceWithPredecessors (IOpnd* dest,
+                                                           Bound* bound,
+                                                           U_32 prn_level,
                                                       meet_func_t meet_f)
 {
     InequalityGraph::edge_iterator in_it = _igraph.inEdgesBegin(dest);
@@ -676,8 +676,8 @@
     assert(in_edge->getDst() == dest);
     ProveResult res;
     assert(!_mem_distance.hasLeqBoundResult(dest, bound));
-    res = prove(in_edge->getSrc(), 
-                _bound_alloc.create_dec_const(bound, 
+    res = prove(in_edge->getSrc(),
+                _bound_alloc.create_dec_const(bound,
                                               in_edge->getLength()),
                 prn_level + 1);
     in_it.next();
@@ -685,7 +685,7 @@
         if(((res >= Reduced)  && (meet_f == meetBest)) ||
            ((res == False) && (meet_f == meetWorst))) {
             // For any x, meetBest(True, x)    == True
-            //            meetBest(Reduced, x) >= Reduced  
+            //            meetBest(Reduced, x) >= Reduced
             //        and meetWorst(False, x)  == False
             if (Log::isEnabled() ) {
                 Printer prn(prn_level, Log::out());
@@ -698,9 +698,9 @@
         in_edge = in_it.get();
         assert(in_edge->getDst() == dest);
         IOpnd* pred = in_edge->getSrc();
-        res = meet_f(res, 
-                     prove(pred, 
-                           _bound_alloc.create_dec_const(bound, 
+        res = meet_f(res,
+                     prove(pred,
+                           _bound_alloc.create_dec_const(bound,
                                                          in_edge->getLength()),
                            prn_level + 1));
     }
@@ -710,40 +710,40 @@
 //
 // prove that distance between '_source_opnd' and 'dest' is <= bound
 //
-ProveResult ClassicAbcdSolver::prove(IOpnd* dest, Bound* bound, 
+ProveResult ClassicAbcdSolver::prove(IOpnd* dest, Bound* bound,
         U_32 prn_level)
 {
     Printer prn(prn_level, Log::out());
     if ( Log::isEnabled() ) {
-        prn.prnStr("prove("); 
+        prn.prnStr("prove(");
         dest->printFullName(Log::out());
-        Log::out() << ", "; 
+        Log::out() << ", ";
         bound->printFullName(Log::out()); Log::out() << ")" << std::endl;
     }
 
-    // if ( C[dest - _source_opnd <= e] == True    for some e<=bound ) 
+    // if ( C[dest - _source_opnd <= e] == True    for some e<=bound )
     //     return True
     if ( _mem_distance.minTrueDistanceLeqBound(dest, bound) ) {
         prn.prnStrLn("case 3: => True");
         return True;
     }
 
-    // if ( C[dest - _source_opnd <= e] == False   for some e>=bound ) 
+    // if ( C[dest - _source_opnd <= e] == False   for some e>=bound )
     //     return False
     if ( _mem_distance.maxFalseDistanceGeqBound(dest, bound) ) {
         prn.prnStrLn("case 4: => False");
         return False;
     }
 
-    // if ( C[dest - _source_opnd <= e] == Reduced for some e<=bound ) 
+    // if ( C[dest - _source_opnd <= e] == Reduced for some e<=bound )
     //     return Reduced
     if ( _mem_distance.minReducedDistanceLeqBound(dest, bound) ) {
         prn.prnStrLn("case 5: => Reduced");
         return Reduced;
     }
-    
+
     // traversal reached the _source_opnd vertex
-    if ( (dest->getID() == _source_opnd->getID()) && 
+    if ( dest->getID() == _source_opnd->getID() &&
           Bound::int32_leq(0, bound) ) {
         prn.prnStrLn("reached source vertex => True");
         return True;
@@ -751,8 +751,8 @@
 
     // all constant operands are implicitly connected
     if ( dest->isConstant() && _source_opnd->isConstant() ) {
-        if ( Bound::const_distance_leq(_source_opnd->getConstant(), 
-                                       dest->getConstant(), 
+        if ( Bound::const_distance_leq(_source_opnd->getConstant(),
+                                       dest->getConstant(),
                                        bound) ) {
             prn.prnStrLn("reached source vertex (const) => True");
             return True;
@@ -761,7 +761,7 @@
             return False;
         }
     }
-    
+
     // if dest has no predecessor then fail
     InequalityGraph::edge_iterator in_it = _igraph.inEdgesBegin(dest);
     InequalityGraph::edge_iterator in_end = _igraph.inEdgesEnd(dest);
@@ -843,7 +843,7 @@
  *     i2 = i3 + 1;
  *     goto for
  * }
- * 
+ *
  * 0 -(0)-> i0 -(0)-> i1(phi)
  * i1(phi) -(0)-> i3 -(1)-> i2 -(0)-> i1(phi)
  * A.length -(-1)-> i3
@@ -922,7 +922,7 @@
  *     goto for1
  * }
  * 0 -(0)-> i0 -(0)-> i1(phi) -(0)-> i2 -(1)-> i3 -(0)-> i1 (phi)
- * A.length -(-1)-> i2 
+ * A.length -(-1)-> i2
  * 0 -(0)-> j0 -(0)-> j1(phi) -(0)-> j2 -(1)-> j3 -(0)-> j1 (phi)
  * i2 -(-1)-> j2
  *
@@ -935,7 +935,7 @@
     InequalityGraph g(mm);
     ClassicAbcdSolver solver(g, mm);
 
-    IOpnd i0(0), i1(1, true /*phi*/), i2(2), i3(3), 
+    IOpnd i0(0), i1(1, true /*phi*/), i2(2), i3(3),
           j0(10), j1(11, true /*phi*/), j2(12), j3(13), length(20);
     assert(g.isEmpty());
     g.addOpnd(&i0);
@@ -1034,14 +1034,14 @@
     IOpnd length(55); // A.length
 
     IOpnd limit0(00), st0(10), limit1(01, true /*phi*/), st1(11, true /*phi*/),
-          st2(12), limit2(02), st3(13), limit3(03), j0(20), 
+          st2(12), limit2(02), st3(13), limit3(03), j0(20),
           j1(21, true /*phi*/), j2(22), limit4(04), j3(23), t0(30), t1(31),
           j4(24);
- 
-    g.addOpnd(&limit0); g.addOpnd(&limit1); g.addOpnd(&limit2); 
+
+    g.addOpnd(&limit0); g.addOpnd(&limit1); g.addOpnd(&limit2);
         g.addOpnd(&limit3); g.addOpnd(&limit4);
     g.addOpnd(&st0); g.addOpnd(&st1); g.addOpnd(&st2); g.addOpnd(&st3);
-    g.addOpnd(&j0); g.addOpnd(&j1); g.addOpnd(&j2); g.addOpnd(&j3); 
+    g.addOpnd(&j0); g.addOpnd(&j1); g.addOpnd(&j2); g.addOpnd(&j3);
         g.addOpnd(&j4);
     g.addOpnd(&t0); g.addOpnd(&t1);
 
@@ -1129,7 +1129,7 @@
  *     i3 = i2 + 1;
  *     goto for
  * }
- * 
+ *
  * INT_MAX -(0)-> i0 -(0)-> i1(phi)
  * i1(phi) -(0)-> i2 -(1)-> i3 -(0)-> i1(phi)
  * A.length -(-1)-> i2
@@ -1148,11 +1148,11 @@
     ClassicAbcdSolver solver(g, mm);
 
     assert(g.isEmpty());
-    IOpnd i0(00), i1(01, true /*phi */), i2(02), i3(03), 
-          intmax(20, false /* phi */, true /* constant */), 
-          zero(22, false /* phi */, true /* constant */), 
+    IOpnd i0(00), i1(01, true /*phi */), i2(02), i3(03),
+          intmax(20, false /* phi */, true /* constant */),
+          zero(22, false /* phi */, true /* constant */),
           length(21);
-    
+
     intmax.setConstant(INT_MAX);
     zero.setConstant(0);
     g.addOpnd(&zero);
@@ -1278,9 +1278,9 @@
     InequalityGraph g(mm);
 
     assert(g.isEmpty());
-    IOpnd i0(00), i1(01, true /*phi */), i2(02), i3(03), 
-          intmax(20, false /* phi */, true /* constant */), 
-          zero(22, false /* phi */, true /* constant */), 
+    IOpnd i0(00), i1(01, true /*phi */), i2(02), i3(03),
+          intmax(20, false /* phi */, true /* constant */),
+          zero(22, false /* phi */, true /* constant */),
           length(21);
 
     intmax.setConstant(INT_MAX);
@@ -1356,5 +1356,5 @@
     return 0;
 }
 
-} //namespace Jitrino 
+} //namespace Jitrino
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/abcd/classic_abcd_solver.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/abcd/classic_abcd_solver.h?rev=764315&r1=764314&r2=764315&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/abcd/classic_abcd_solver.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/abcd/classic_abcd_solver.h Sun Apr 12 19:05:29 2009
@@ -30,7 +30,7 @@
 class IOpnd {
 public:
     IOpnd(U_32 id, bool is_phi = false, bool is_constant = false) :
-        _id(id), _phi(is_phi), _const(is_constant), 
+        _id(id), _phi(is_phi), _const(is_constant),
         _unconstrained(false), _value(0)
     {}
 
@@ -455,19 +455,19 @@
 
 class MemoizedDistances {
 public:
-    MemoizedDistances(BoundAllocator& alloc) : 
+    MemoizedDistances(BoundAllocator& alloc) :
         _bound_alloc(alloc),
-        _map(_bound_alloc.getMemoryManager()) 
+        _map(_bound_alloc.getMemoryManager())
     {}
 
     void makeEmpty();
 
-    // set [dest - source <= bound] 
+    // set [dest - source <= bound]
     void updateLeqBound(IOpnd* dest, Bound* bound, ProveResult res);
 
     bool hasLeqBoundResult(IOpnd* dest, Bound* bound) const;
 
-    // returns [dest - source <= bound] 
+    // returns [dest - source <= bound]
     //      that is True, Reduced or False
     ProveResult getLeqBoundResult(IOpnd* dest, Bound* bound) const;
 
@@ -510,9 +510,9 @@
 
 class ClassicAbcdSolver {
 public:
-    ClassicAbcdSolver(InequalityGraph& i, MemoryManager& solver_mem_mgr) : 
-        _igraph(i), 
-        _source_opnd(NULL), 
+    ClassicAbcdSolver(InequalityGraph& i, MemoryManager& solver_mem_mgr) :
+        _igraph(i),
+        _source_opnd(NULL),
         _bound_alloc(solver_mem_mgr),
         _mem_distance(_bound_alloc),
         _active(solver_mem_mgr)
@@ -539,7 +539,7 @@
 
     private:
         U_32 _level;
-        std::ostream& _os; 
+        std::ostream& _os;
     };
 
     InequalityGraph& _igraph;
@@ -551,6 +551,6 @@
 
 int classic_abcd_test_main();
 
-} //namespace Jitrino 
+} //namespace Jitrino
 
 #endif /* _CLASSIC_ABCD_SOLVER_H */

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/abcd/insertpi.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/abcd/insertpi.cpp?rev=764315&r1=764314&r2=764315&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/abcd/insertpi.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/abcd/insertpi.cpp Sun Apr 12 19:05:29 2009
@@ -120,15 +120,15 @@
     //  (2) this block dominates all other predecessors
     //  (3) idom has multiple out-edges
     //  (4) idom has only 1 edge to this node
-    
+
     // (1a) if a predecessor dominates it must be idom
     Node *idom = _domTree.getIdom(block);
-    
+
     // (3) must exist and have multiple out-edges
     if ((idom == NULL) || (idom->hasOnlyOneSuccEdge())) {
         return;
     }
-    
+
     if (Log::isEnabled()) {
         Log::out() << "Checking block " << (int)block->getId() << " with idom "
                    << (int) idom->getId() << std::endl;
@@ -184,7 +184,7 @@
                     }
                 }
                 break;
-                
+
             case Edge::Kind_Dispatch: 
                 return;
 
@@ -198,11 +198,10 @@
                     insertPiForUnexceptionalPEI(block, lasti);
                 }
                 // We could look for a bounds check in predecessor.
-                
+
                 // But: since now all useful PEIs have explicit results,
                 // they imply a Pi-like action.
                 break;
-                
             case Edge::Kind_Catch:
                 break;
             default:
@@ -403,7 +402,7 @@
                                        true,
                                        // negate for false edge
                                        (kind == Edge::Kind_False));
-        }                                       
+        }
     }
 }
 //------------------------------------------------------------------------------
@@ -424,8 +423,19 @@
         op->print(Log::out());
         Log::out() << ", ";
         Log::out() << (swap_operands ? "true" : "false");
+        Log::out() << ", ";
         Log::out() << (negate_comparison ? "true" : "false");
-        Log::out() << std::endl;
+        Log::out() << ")" << std::endl;
+
+        // Print last inst from all prev blocks.
+        Edges::const_iterator it = block->getInEdges().begin(),
+            end = block->getInEdges().end();
+        for(; it != end; ++it) {
+            Edge* edge = (*it);
+            Log::out() << "pred inst---> ";
+            ((Inst*)edge->getSourceNode()->getLastInst())->print(Log::out());
+            Log::out() << std::endl;
+        }
     }
 
     PiCondition bounds0 = bounds;
@@ -757,7 +767,7 @@
                 }
                 // now constOpnd0 should be constant
                 // op1 is the non-constant operand
-                
+
                 Inst *inst0 = constOpnd0->getInst();
                 assert(inst0);
                 ConstInst *cinst0 = inst0->asConstInst();
@@ -830,7 +840,7 @@
             Log::out() << " under condition ";
             cond.print(Log::out());
             Log::out() << std::endl;
-        }            
+        }
         AbcdAliases aliases(_mm);
         // check for aliases
         insertPiForOpnd(block, org, cond, tauOpnd);
@@ -921,141 +931,168 @@
     // the piTable.  Since we are visiting in preorder over dominator
     // tree dominator order, any found version will dominate this node.
 
-    // we defer adding any new mappings for the Pi instructions here until
-    // we are past the Pi instructions
-    
-    // first process any pi nodes, just the RHSs
+    // Phase 0: remap just Pi inst source operands.
     Inst* headInst = (Inst*)block->getFirstInst();
-    for (int phase=0; phase < 2; ++phase) {
-        // phase 0: remap just Pi node source operands
-        // phase 1: add Pi remappings, remap source operands of other instructions
-    
-        for (Inst* inst = headInst->getNextInst(); inst != NULL; inst = inst->getNextInst()) {
-            
-            if (inst->getOpcode() == Op_TauPi) {
-                if (phase == 1) {
-                    // add any Pi node destination to the map.
-                    
-                    Opnd *dstOpnd = inst->getDst();
-                    assert(dstOpnd->isPiOpnd());
-                    Opnd *orgOpnd = dstOpnd->asPiOpnd()->getOrg();
-                    if (_useAliases) {
-                        if (orgOpnd->isSsaVarOpnd()) {
-                            orgOpnd = orgOpnd->asSsaVarOpnd()->getVar();
-                        }
+    for (Inst* inst = headInst->getNextInst(); inst != NULL; inst = inst->getNextInst()) {
+        if (inst->getOpcode() == Op_TauPi) {
+            // Replace Pi source operands with renames from the map.
+            Opnd *dstOpnd = inst->getDst();
+            assert(dstOpnd->isPiOpnd());
+            Opnd *srcOpnd = inst->getSrc(0);
+            if (_useAliases) {
+                if (srcOpnd->isSsaVarOpnd()) {
+                    srcOpnd = srcOpnd->asSsaVarOpnd()->getVar();
+                }
+            }
+            // Find the end of the operand replace chain.
+            // The most constrained operand is being used, the more
+            // opportunities we have for optimization.
+            Opnd *replaceOpnd = _piMap->lookupTillEnd(srcOpnd);
+            if (replaceOpnd) {
+                // Disallow remapping source operand of Pi Nodes to their
+                // destination operands.
+                if (Log::isEnabled()) {
+                    Log::out() << "remapping src in Pi: ";
+                    inst->print(Log::out());
+                    Log::out() << ", replaceOpnd: ";
+                    replaceOpnd->print(Log::out());
+                }
+                if (dstOpnd->getId() != replaceOpnd->getId()) {
+                    inst->setSrc(0, replaceOpnd);
+                    srcOpnd = replaceOpnd;
+                    if (Log::isEnabled()) {
+                        Log::out() << "... done" << std::endl;
                     }
-                    _piMap->insert(orgOpnd, dstOpnd);
+                } else {
                     if (Log::isEnabled()) {
-                        Log::out() << "adding remap for Pi of ";
-                        orgOpnd->print(Log::out());
-                        Log::out() << " to ";
-                        inst->getDst()->print(Log::out());
-                        Log::out() << std::endl;
+                        Log::out() << "... defines this opnd, cannot remap" << std::endl;
                     }
-                    
-                    continue; // don't remap Pi sources;
-                }
-            } else {
-                if (phase == 0) {
-                    // no more Pi instructions, we're done with phase 0.
-                    break; 
-                }
-            }
-            
-            // now process source operands
-            U_32 numOpnds = inst->getNumSrcOperands();
-            for (U_32 i=0; i<numOpnds; i++) {
-                Opnd *opnd = inst->getSrc(i);
-                if (opnd->isPiOpnd())
-                    opnd = opnd->asPiOpnd()->getOrg();
-                Opnd *foundOpnd = _piMap->lookup(opnd);
-                if (foundOpnd) {
-                    inst->setSrc(i,foundOpnd);
                 }
             }
 
-            if (inst->getOpcode() == Op_TauPi) {
-                // for a Pi, remap variables appearing in the condition as well
-                if (Log::isEnabled()) {
-                    Log::out() << "remapping condition in ";
-                    inst->print(Log::out());
-                    Log::out() << std::endl;
+            // We now replaced the source. Add any Pi node destination to the map.
+            _piMap->insert(srcOpnd, dstOpnd);
+            if (Log::isEnabled()) {
+                Log::out() << "adding remap for Pi of ";
+                srcOpnd->print(Log::out());
+                Log::out() << " to ";
+                inst->getDst()->print(Log::out());
+                Log::out() << std::endl;
+            }
+        }
+    }
+
+    // Phase 1: add Pi remappings, remap source operands of other instructions
+    // and pi conditions.
+    for (Inst* inst = headInst->getNextInst(); inst != NULL; inst = inst->getNextInst()) {
+
+        // Remap source operands if they match a Pi definition.
+        U_32 numOpnds = inst->getNumSrcOperands();
+        for (U_32 i=0; i<numOpnds; i++) {
+            Opnd *opnd = inst->getSrc(i);
+            while (opnd->isPiOpnd()) {
+                opnd = opnd->asPiOpnd()->getOrg();
+            }
+            // Transitively look up for deepest Pi renamings of this operand.
+            // The most constrained operand is being used, the more
+            // opportunities we have for optimization.
+            Opnd *foundOpnd = _piMap->lookupTillEnd(opnd);
+            if (foundOpnd) {
+                // Remap the source operand except for Pi instruction and for
+                // array argument for chkbounds instruction. The latter is
+                // because (a) we do not need any facts provided by pi renaming
+                // for this operand, (b) we should limit array operand renaming
+                // to be able to search the proof path by exact array operand
+                // id.
+                if (inst->getOpcode() != Op_TauPi &&
+                    (inst->getOpcode() != Op_TauCheckBounds || i != 0)) {
+                    inst->setSrc(i, foundOpnd);
                 }
-                TauPiInst *thePiInst = inst->asTauPiInst();
-                assert(thePiInst);
-                PiCondition *cond = thePiInst->cond;
+            }
+        }
+
+        // Remap variables appearing in the condition of the Pi node.
+        if (inst->getOpcode() == Op_TauPi) {
+            TauPiInst *thePiInst = inst->asTauPiInst();
+            assert(thePiInst);
+
+            if (Log::isEnabled()) {
+                Log::out() << "remapping condition in ";
+                inst->print(Log::out());
+                Log::out() << std::endl;
+            }
+            PiCondition *cond = thePiInst->cond;
+            if (Log::isEnabled()) {
+                Log::out() << "  original condition is ";
+                cond->print(Log::out());
+                Log::out() << std::endl;
+            }
+            Opnd *lbRemap = cond->getLb().getVar().the_var;
+            if (lbRemap) {
                 if (Log::isEnabled()) {
-                    Log::out() << "  original condition is ";
-                    cond->print(Log::out());
+                    Log::out() << "  has lbRemap=";
+                    lbRemap->print(Log::out());
                     Log::out() << std::endl;
                 }
-                Opnd *lbRemap = cond->getLb().getVar().the_var;
-                if (lbRemap) {
+                if (lbRemap->isPiOpnd())
+                    lbRemap = lbRemap->asPiOpnd()->getOrg();
+                Opnd *lbRemapTo = _piMap->lookupTillEnd(lbRemap);
+                if (lbRemapTo) {
                     if (Log::isEnabled()) {
-                        Log::out() << "  has lbRemap=";
+                        Log::out() << "adding remap of lbRemap=";
                         lbRemap->print(Log::out());
-                        Log::out() << std::endl;
+                        Log::out() << " to lbRemapTo=";
+                        lbRemapTo->print(Log::out());
+                        Log::out() << " to condition ";
+                        cond->print(Log::out());
                     }
-                    if (lbRemap->isPiOpnd())
-                        lbRemap = lbRemap->asPiOpnd()->getOrg();
-                    Opnd *lbRemapTo = _piMap->lookup(lbRemap);
-                    if (lbRemapTo) {
-                        if (Log::isEnabled()) {
-                            Log::out() << "adding remap of lbRemap=";
-                            lbRemap->print(Log::out());
-                            Log::out() << " to lbRemapTo=";
-                            lbRemapTo->print(Log::out());
-                            Log::out() << " to condition ";
-                            cond->print(Log::out());
-                        }
-                        PiCondition remapped(*cond, lbRemap, lbRemapTo);
-                        if (Log::isEnabled()) {
-                            Log::out() << " YIELDS1 ";
-                            remapped.print(Log::out());
-                        }
-                        *cond = remapped;
-                        if (Log::isEnabled()) {
-                            Log::out() << " YIELDS ";
-                            cond->print(Log::out());
-                            Log::out() << std::endl;
-                        }
+                    PiCondition remapped(*cond, lbRemap, lbRemapTo);
+                    if (Log::isEnabled()) {
+                        Log::out() << " YIELDS1 ";
+                        remapped.print(Log::out());
+                    }
+                    *cond = remapped;
+                    if (Log::isEnabled()) {
+                        Log::out() << " YIELDS ";
+                        cond->print(Log::out());
+                        Log::out() << std::endl;
                     }
                 }
-                Opnd *ubRemap = cond->getUb().getVar().the_var;
-                if (ubRemap && (lbRemap != ubRemap)) {
+            }
+            Opnd *ubRemap = cond->getUb().getVar().the_var;
+            if (ubRemap && (lbRemap != ubRemap)) {
+                if (Log::isEnabled()) {
+                    Log::out() << "  has ubRemap=";
+                    ubRemap->print(Log::out());
+                    Log::out() << std::endl;
+                }
+                if (ubRemap->isPiOpnd())
+                    ubRemap = ubRemap->asPiOpnd()->getOrg();
+                Opnd *ubRemapTo = _piMap->lookupTillEnd(ubRemap);
+                if (ubRemapTo) {
                     if (Log::isEnabled()) {
-                        Log::out() << "  has ubRemap=";
+                        Log::out() << "adding remap of ubRemap=";
                         ubRemap->print(Log::out());
-                        Log::out() << std::endl;
+                        Log::out() << " to ubRemapTo=";
+                        ubRemapTo->print(Log::out());
+                        Log::out() << " to condition ";
+                        cond->print(Log::out());
                     }
-                    if (ubRemap->isPiOpnd())
-                        ubRemap = ubRemap->asPiOpnd()->getOrg();
-                    Opnd *ubRemapTo = _piMap->lookup(ubRemap);
-                    if (ubRemapTo) {
-                        if (Log::isEnabled()) {
-                            Log::out() << "adding remap of ubRemap=";
-                            ubRemap->print(Log::out());
-                            Log::out() << " to ubRemapTo=";
-                            ubRemapTo->print(Log::out());
-                            Log::out() << " to condition ";
-                            cond->print(Log::out());
-                        }
-                        PiCondition remapped(*cond, ubRemap, ubRemapTo);
-                        if (Log::isEnabled()) {
-                            Log::out() << " YIELDS1 ";
-                            remapped.print(Log::out());
-                        }
-                        *cond = remapped;
-                        if (Log::isEnabled()) {
-                            Log::out() << " YIELDS ";
-                            cond->print(Log::out());
-                            Log::out() << std::endl;
-                        }
+                    PiCondition remapped(*cond, ubRemap, ubRemapTo);
+                    if (Log::isEnabled()) {
+                        Log::out() << " YIELDS1 ";
+                        remapped.print(Log::out());
+                    }
+                    *cond = remapped;
+                    if (Log::isEnabled()) {
+                        Log::out() << " YIELDS ";
+                        cond->print(Log::out());
+                        Log::out() << std::endl;
                     }
                 }
             }
         }
-    }        
+    }
 }
 //------------------------------------------------------------------------------
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/opndmap.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/opndmap.h?rev=764315&r1=764314&r2=764315&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/opndmap.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/opndmap.h Sun Apr 12 19:05:29 2009
@@ -109,6 +109,17 @@
                   U_32 init_factor, U_32 resize_factor, U_32 resize_to) :
         SparseScopedMap<Opnd *, Opnd *>(n, mm, init_factor, resize_factor,
                                         resize_to) {};
+    Opnd *lookupTillEnd(Opnd *o) {
+        Opnd *found = lookup(o);
+        if (NULL == found) {
+            return NULL;
+        }
+        Opnd *foundMore;
+        while (NULL != (foundMore = lookup(found))) {
+            found = foundMore;
+        }
+        return found;
+    }
 };