# HG changeset patch # User Thomas Wuerthinger # Date 1303923640 -7200 # Node ID 3fca504f28ba0d54d761216807ad85aa07db6189 # Parent eca17668badf3057f5ce529b586aea08249364f0 Reinsert phi simplifier (does not seem to be optional). Disabled canonicalizer. diff -r eca17668badf -r 3fca504f28ba graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java --- a/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java Wed Apr 27 18:17:18 2011 +0200 +++ b/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java Wed Apr 27 19:00:40 2011 +0200 @@ -204,6 +204,8 @@ this.operands = new OperandPool(compilation.target); + new PhiSimplifier(ir); + // mark the liveness of all instructions if it hasn't already been done by the optimizer LivenessMarker livenessMarker = new LivenessMarker(ir); C1XMetrics.LiveHIRInstructions += livenessMarker.liveCount(); @@ -1275,7 +1277,7 @@ if (suxVal instanceof Phi) { Phi phi = (Phi) suxVal; // curVal can be null without phi being null in conjunction with inlining - if (phi.isLive() && curVal != null && curVal != phi) { + if (phi.isLive() && !phi.isDeadPhi() && curVal != null && curVal != phi) { assert curVal.isLive() : "value not live: " + curVal + ", suxVal=" + suxVal; assert !phi.isIllegal() : "illegal phi cannot be marked as live"; if (curVal instanceof Phi) { @@ -1349,6 +1351,7 @@ } private CiValue operandForPhi(Phi phi) { + assert !phi.isDeadPhi(); if (phi.operand().isIllegal()) { // allocate a variable for this phi CiVariable operand = newVariable(phi.kind); diff -r eca17668badf -r 3fca504f28ba graal/GraalCompiler/src/com/sun/c1x/opt/InstructionSubstituter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/GraalCompiler/src/com/sun/c1x/opt/InstructionSubstituter.java Wed Apr 27 19:00:40 2011 +0200 @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.c1x.opt; + +import com.sun.c1x.ir.*; +import com.sun.c1x.value.*; +import com.sun.c1x.graph.IR; + +/** + * This class allows instructions to be substituted within an IR graph. It allows + * registering substitutions and iterates over the instructions of a program and replaces + * the occurrence of each instruction with its substitution, if it has one. + * + * @author Ben L. Titzer + */ +public final class InstructionSubstituter implements BlockClosure, ValueClosure { + + final IR ir; + boolean hasSubstitution; + + public InstructionSubstituter(IR ir) { + this.ir = ir; + } + + public void apply(BlockBegin block) { + Instruction last = null; + if (block.exceptionHandlerStates() != null) { + for (FrameState s : block.exceptionHandlerStates()) { + s.valuesDo(this); + } + } + for (Instruction n = block; n != null; n = last.next()) { + n.allValuesDo(this); + if (n.subst != null && last != null) { + // this instruction has a substitution, skip it + last.resetNext(n.next()); + } else { + last = n; + } + } + } + + public void finish() { + if (hasSubstitution) { + ir.startBlock.iterateAnyOrder(this, false); + } + } + + public boolean hasSubst(Value i) { + return i.subst != null; + } + + public void setSubst(Value i, Value n) { + if (i == n) { + i.subst = null; + } else { + hasSubstitution = true; + i.subst = n; + } + } + + public Value getSubst(Value i) { + Value p = i; + while (true) { + if (p.subst == null) { + break; + } + p = p.subst; + } + return p; + } + + public Value apply(Value i) { + if (i != null) { + return getSubst(i); + } + return i; + } +} diff -r eca17668badf -r 3fca504f28ba graal/GraalCompiler/src/com/sun/c1x/opt/PhiSimplifier.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/GraalCompiler/src/com/sun/c1x/opt/PhiSimplifier.java Wed Apr 27 19:00:40 2011 +0200 @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.c1x.opt; + +import com.sun.c1x.graph.IR; +import com.sun.c1x.ir.*; +import com.sun.c1x.value.*; + +/** + * The {@code PhiSimplifier} class is a helper class that can reduce phi instructions. + * + * @author Ben L. Titzer + */ +public final class PhiSimplifier implements BlockClosure { + + final IR ir; + final InstructionSubstituter subst; + + public PhiSimplifier(IR ir) { + this.ir = ir; + this.subst = new InstructionSubstituter(ir); + ir.startBlock.iterateAnyOrder(this, false); + subst.finish(); + } + + /** + * This method is called for each block and processes any phi statements in the block. + * @param block the block to apply the simplification to + */ + public void apply(BlockBegin block) { + FrameState state = block.stateBefore(); + for (int i = 0; i < state.stackSize(); i++) { + simplify(state.stackAt(i)); + } + for (int i = 0; i < state.localsSize(); i++) { + simplify(state.localAt(i)); + } + } + + Value simplify(Value x) { + if (x == null || !(x instanceof Phi)) { + return x; + } + Phi phi = (Phi) x; + if (phi.hasSubst()) { + // already substituted, but the subst could be a phi itself, so simplify + return simplify(subst.getSubst(phi)); + } else if (phi.checkFlag(Value.Flag.PhiCannotSimplify)) { + // already tried, cannot simplify this phi + return phi; + } else if (phi.checkFlag(Value.Flag.PhiVisited)) { + // break cycles in phis + return phi; + } else if (phi.isIllegal()) { + // don't bother with illegals + return phi; + } else { + // attempt to simplify the phi by recursively simplifying its operands + phi.setFlag(Value.Flag.PhiVisited); + Value phiSubst = null; + int max = phi.inputCount(); + boolean cannotSimplify = false; + for (int i = 0; i < max; i++) { + Value oldInstr = phi.inputAt(i); + + if (oldInstr == null || oldInstr.isIllegal() || oldInstr.isDeadPhi()) { + // if one operand is illegal, make the entire phi illegal + phi.makeDead(); + phi.clearFlag(Value.Flag.PhiVisited); + return phi; + } + + Value newInstr = simplify(oldInstr); + + if (newInstr == null || newInstr.isIllegal() || newInstr.isDeadPhi()) { + // if the subst instruction is illegal, make the entire phi illegal + phi.makeDead(); + phi.clearFlag(Value.Flag.PhiVisited); + return phi; + } + + // attempt to simplify this operand + if (!cannotSimplify) { + + if (newInstr != phi && newInstr != phiSubst) { + if (phiSubst == null) { + phiSubst = newInstr; + continue; + } + // this phi cannot be simplified + cannotSimplify = true; + } + } + } + if (cannotSimplify) { + phi.setFlag(Value.Flag.PhiCannotSimplify); + phi.clearFlag(Value.Flag.PhiVisited); + return phi; + } + + // successfully simplified the phi + assert phiSubst != null : "illegal phi function"; + phi.clearFlag(Value.Flag.PhiVisited); + subst.setSubst(phi, phiSubst); + return phiSubst; + } + } +} diff -r eca17668badf -r 3fca504f28ba graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotOptions.java --- a/graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotOptions.java Wed Apr 27 18:17:18 2011 +0200 +++ b/graal/GraalRuntime/src/com/oracle/graal/runtime/HotSpotOptions.java Wed Apr 27 19:00:40 2011 +0200 @@ -38,6 +38,7 @@ C1XOptions.CommentedAssembly = false; C1XOptions.MethodEndBreakpointGuards = 2; C1XOptions.ResolveClassBeforeStaticInvoke = false; + C1XOptions.OptCanonicalize = false; } public static boolean setOption(String option) {