From: <cap...@us...> - 2008-04-08 19:28:48
|
Revision: 14100 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=14100&view=rev Author: captain5050 Date: 2008-04-08 12:28:33 -0700 (Tue, 08 Apr 2008) Log Message: ----------- Modify simple escape analysis to run multiple times until it is unable to find any more non-escaping objects. This is based on the observation that if we inline a constructor and then inline another constructor we will remove the outer object but not the inner. Modified Paths: -------------- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/EscapeTransformations.java Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/EscapeTransformations.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/EscapeTransformations.java 2008-04-08 19:20:06 UTC (rev 14099) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/EscapeTransformations.java 2008-04-08 19:28:33 UTC (rev 14100) @@ -19,6 +19,8 @@ import org.jikesrvm.classloader.VM_Type; import org.jikesrvm.compilers.opt.driver.CompilerPhase; +import org.jikesrvm.compilers.opt.driver.OptimizationPlanCompositeElement; +import org.jikesrvm.compilers.opt.driver.OptimizationPlanElement; import org.jikesrvm.compilers.opt.ir.Call; import org.jikesrvm.compilers.opt.ir.IR; import org.jikesrvm.compilers.opt.ir.Instruction; @@ -39,6 +41,15 @@ public class EscapeTransformations extends CompilerPhase { /** + * Transforms to clean the IR prior to another round of escape transformations + */ + private static final OptimizationPlanElement escapeCleanUp = + OptimizationPlanCompositeElement.compose("Clean up escape transformations", + new Object[]{new LocalCopyProp(), + new LocalConstantProp(), + new Simple(0, true, false, false)}); + + /** * Return this instance of this phase. This phase contains no * per-compilation instance fields. * @param ir not used @@ -70,48 +81,59 @@ DefUse.computeDU(ir); DefUse.recomputeSSA(ir); SimpleEscape analyzer = new SimpleEscape(); - FI_EscapeSummary summary = analyzer.simpleEscapeAnalysis(ir); - // pass through registers. look for registers that point - // to objects that do not escape. When found, - // perform the transformations - for (Register reg = ir.regpool.getFirstSymbolicRegister(); reg != null; reg = reg.getNext()) { - // check if register is SSA - if (!reg.isSSA()) { - continue; - } - // The following can occur for guards. Why? - if (reg.defList == null) { - continue; - } - // ********************************************************* - // check if def is allocation. If so, try scalar replacement - // of aggregates - // ********************************************************* - Instruction def = reg.defList.instruction; - if (ir.options.SCALAR_REPLACE_AGGREGATES && summary.isMethodLocal(reg)) { - AggregateReplacer s = null; - if ((def.getOpcode() == NEW_opcode) || (def.getOpcode() == NEWARRAY_opcode)) { - s = getAggregateReplacer(def, ir); + // do multiple passes to catch chains of objects that can be removed + boolean removedAggregate; + do { + removedAggregate = false; + FI_EscapeSummary summary = analyzer.simpleEscapeAnalysis(ir); + // pass through registers. look for registers that point + // to objects that do not escape. When found, + // perform the transformations + for (Register reg = ir.regpool.getFirstSymbolicRegister(); reg != null; reg = reg.getNext()) { + // check if register is SSA + if (!reg.isSSA()) { + continue; } - if (s != null) { - // VM.sysWrite("Scalar replacing "+def+" in "+ir.method+"\n"); - s.transform(); + // The following can occur for guards. Why? + if (reg.defList == null) { + continue; } - } - // ********************************************************* - // Now remove synchronizations - // ********************************************************* - if (ir.options.MONITOR_REMOVAL && summary.isThreadLocal(reg)) { - UnsyncReplacer unsync = null; - if ((def.getOpcode() == NEW_opcode) || (def.getOpcode() == NEWARRAY_opcode)) { - unsync = getUnsyncReplacer(reg, def, ir); + // ********************************************************* + // check if def is allocation. If so, try scalar replacement + // of aggregates + // ********************************************************* + Instruction def = reg.defList.instruction; + if (ir.options.SCALAR_REPLACE_AGGREGATES && summary.isMethodLocal(reg)) { + AggregateReplacer s = null; + if ((def.getOpcode() == NEW_opcode) || (def.getOpcode() == NEWARRAY_opcode)) { + s = getAggregateReplacer(def, ir); + } + if (s != null) { + org.jikesrvm.VM.sysWrite("Scalar replacing "+def+" in "+ir.method+"\n"); + s.transform(); + removedAggregate = true; + } } - if (unsync != null) { - // VM.sysWrite("Removing synchronization on "+def+" in "+ir.method+"\n"); - unsync.transform(); + // ********************************************************* + // Now remove synchronizations + // ********************************************************* + if (ir.options.MONITOR_REMOVAL && summary.isThreadLocal(reg)) { + UnsyncReplacer unsync = null; + if ((def.getOpcode() == NEW_opcode) || (def.getOpcode() == NEWARRAY_opcode)) { + unsync = getUnsyncReplacer(reg, def, ir); + } + if (unsync != null) { + // VM.sysWrite("Removing synchronization on "+def+" in "+ir.method+"\n"); + unsync.transform(); + } } } - } + if (removedAggregate) { + // do quick clean up of IR + org.jikesrvm.VM.sysWrite("Cleaning up IR in "+ir.method+"\n"); + escapeCleanUp.perform(ir); + } + } while (removedAggregate); } /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |