From 5ac195df5a4528a3d43c68ea4a2ebd3eb43dcc4b Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Sat, 14 May 2016 23:58:48 +0300 Subject: [PATCH] Refactor phi placement --- .../util/PhiUpdater.java} | 69 ++++--------------- .../main/java/org/teavm/parsing/Parser.java | 31 ++++++++- .../java/org/teavm/parsing/ProgramParser.java | 3 +- .../parsing/VariableDebugInformation.java | 27 -------- 4 files changed, 45 insertions(+), 85 deletions(-) rename core/src/main/java/org/teavm/{parsing/SSATransformer.java => model/util/PhiUpdater.java} (87%) delete mode 100644 core/src/main/java/org/teavm/parsing/VariableDebugInformation.java diff --git a/core/src/main/java/org/teavm/parsing/SSATransformer.java b/core/src/main/java/org/teavm/model/util/PhiUpdater.java similarity index 87% rename from core/src/main/java/org/teavm/parsing/SSATransformer.java rename to core/src/main/java/org/teavm/model/util/PhiUpdater.java index e105df432..4f6a6a449 100644 --- a/core/src/main/java/org/teavm/parsing/SSATransformer.java +++ b/core/src/main/java/org/teavm/model/util/PhiUpdater.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 Alexey Andreev. + * Copyright 2016 Alexey Andreev. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.parsing; +package org.teavm.model.util; import java.util.*; import org.teavm.common.DominatorTree; @@ -21,72 +21,39 @@ import org.teavm.common.Graph; import org.teavm.common.GraphUtils; import org.teavm.model.*; import org.teavm.model.instructions.*; -import org.teavm.model.util.DefinitionExtractor; -import org.teavm.model.util.ProgramUtils; -/** - * - * @author Alexey Andreev - */ -public class SSATransformer { +public class PhiUpdater { private Program program; private Graph cfg; - private DominatorTree domTree; private int[][] domFrontiers; private Variable[] variableMap; private BasicBlock currentBlock; private Phi[][] phiMap; private int[][] phiIndexMap; - private ValueType[] arguments; - private VariableDebugInformation variableDebugInfo; - private Map variableDebugMap = new HashMap<>(); - public void transformToSSA(Program program, VariableDebugInformation variableDebugInfo, ValueType[] arguments) { + public void updatePhis(Program program, Variable[] arguments) { if (program.basicBlockCount() == 0) { return; } this.program = program; - this.variableDebugInfo = variableDebugInfo; - this.arguments = arguments; - variableDebugMap.clear(); cfg = ProgramUtils.buildControlFlowGraphWithTryCatch(program); - domTree = GraphUtils.buildDominatorTree(cfg); + DominatorTree domTree = GraphUtils.buildDominatorTree(cfg); domFrontiers = new int[cfg.size()][]; variableMap = new Variable[program.variableCount()]; + for (int i = 0; i < arguments.length; ++i) { + variableMap[i] = arguments[i]; + } phiMap = new Phi[program.basicBlockCount()][]; phiIndexMap = new int[program.basicBlockCount()][]; for (int i = 0; i < phiMap.length; ++i) { phiMap[i] = new Phi[program.variableCount()]; phiIndexMap[i] = new int[program.variableCount()]; } - applySignature(); domFrontiers = GraphUtils.findDominanceFrontiers(cfg, domTree); estimatePhis(); renameVariables(); } - private void applySignature() { - if (program.variableCount() == 0) { - return; - } - int index = 0; - variableMap[index] = program.variableAt(index); - ++index; - for (int i = 0; i < arguments.length; ++i) { - variableMap[index] = program.variableAt(i + 1); - ++index; - ValueType arg = arguments[i]; - if (arg instanceof ValueType.Primitive) { - PrimitiveType kind = ((ValueType.Primitive) arg).getKind(); - if (kind == PrimitiveType.LONG || kind == PrimitiveType.DOUBLE) { - variableMap[index] = variableMap[index - 1]; - ++index; - } - } - } - arguments = null; - } - private void estimatePhis() { DefinitionExtractor definitionExtractor = new DefinitionExtractor(); for (int i = 0; i < program.basicBlockCount(); ++i) { @@ -97,10 +64,13 @@ public class SSATransformer { markAssignment(var); } } + for (Phi phi : currentBlock.getPhis()) { + markAssignment(phi.getReceiver()); + } } } - static class Task { + private static class Task { Variable[] variables; BasicBlock block; } @@ -161,19 +131,17 @@ public class SSATransformer { specialPhis.get(currentBlock.getIndex()).add(phi); } for (Instruction insn : currentBlock.getInstructions()) { - variableDebugMap.putAll(variableDebugInfo.getDebugNames(insn)); insn.acceptVisitor(consumer); } int[] successors = domGraph.outgoingEdges(currentBlock.getIndex()); - for (int i = 0; i < successors.length; ++i) { + for (int successor : successors) { Task next = new Task(); next.variables = Arrays.copyOf(variableMap, variableMap.length); - next.block = program.basicBlockAt(successors[i]); + next.block = program.basicBlockAt(successor); stack[head++] = next; } successors = cfg.outgoingEdges(currentBlock.getIndex()); - for (int i = 0; i < successors.length; ++i) { - int successor = successors[i]; + for (int successor : successors) { int[] phiIndexes = phiIndexMap[successor]; List phis = program.basicBlockAt(successor).getPhis(); for (int j = 0; j < phis.size(); ++j) { @@ -231,10 +199,6 @@ public class SSATransformer { if (mappedVar == null) { throw new AssertionError(); } - String debugName = variableDebugMap.get(var.getIndex()); - if (debugName != null) { - mappedVar.getDebugNames().add(debugName); - } return mappedVar; } @@ -440,9 +404,6 @@ public class SSATransformer { @Override public void visit(UnwrapArrayInstruction insn) { insn.setArray(use(insn.getArray())); - for (String debugName : insn.getArray().getDebugNames()) { - variableDebugMap.put(insn.getReceiver().getIndex(), debugName + ".data"); - } insn.setReceiver(define(insn.getReceiver())); } diff --git a/core/src/main/java/org/teavm/parsing/Parser.java b/core/src/main/java/org/teavm/parsing/Parser.java index 7df874bd2..dce194b41 100644 --- a/core/src/main/java/org/teavm/parsing/Parser.java +++ b/core/src/main/java/org/teavm/parsing/Parser.java @@ -17,12 +17,14 @@ package org.teavm.parsing; import java.lang.reflect.Array; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import org.objectweb.asm.commons.JSRInlinerAdapter; import org.objectweb.asm.tree.*; import org.teavm.model.*; +import org.teavm.model.util.PhiUpdater; import org.teavm.optimization.UnreachableBasicBlockEliminator; /** @@ -47,8 +49,8 @@ public final class Parser { programParser.setFileName(fileName); Program program = programParser.parse(node, className); new UnreachableBasicBlockEliminator().optimize(program); - SSATransformer ssaProducer = new SSATransformer(); - ssaProducer.transformToSSA(program, programParser, method.getParameterTypes()); + PhiUpdater phiUpdater = new PhiUpdater(); + phiUpdater.updatePhis(program, applySignature(program, method.getParameterTypes())); method.setProgram(program); parseAnnotations(method.getAnnotations(), node.visibleAnnotations, node.invisibleAnnotations); while (program.variableCount() <= method.parameterCount()) { @@ -65,6 +67,31 @@ public final class Parser { return method; } + private static Variable[] applySignature(Program program, ValueType[] arguments) { + if (program.variableCount() == 0) { + return new Variable[0]; + } + + Variable[] variableMap = new Variable[program.variableCount()]; + int index = 0; + variableMap[index] = program.variableAt(index); + ++index; + for (int i = 0; i < arguments.length; ++i) { + variableMap[index] = program.variableAt(i + 1); + ++index; + ValueType arg = arguments[i]; + if (arg instanceof ValueType.Primitive) { + PrimitiveType kind = ((ValueType.Primitive) arg).getKind(); + if (kind == PrimitiveType.LONG || kind == PrimitiveType.DOUBLE) { + variableMap[index] = variableMap[index - 1]; + ++index; + } + } + } + + return Arrays.copyOf(variableMap, index); + } + public static ClassHolder parseClass(ClassNode node) { ClassHolder cls = new ClassHolder(node.name.replace('/', '.')); parseModifiers(node.access, cls); diff --git a/core/src/main/java/org/teavm/parsing/ProgramParser.java b/core/src/main/java/org/teavm/parsing/ProgramParser.java index 27a0e1825..831866e47 100644 --- a/core/src/main/java/org/teavm/parsing/ProgramParser.java +++ b/core/src/main/java/org/teavm/parsing/ProgramParser.java @@ -27,7 +27,7 @@ import org.teavm.model.util.ProgramUtils; * * @author Alexey Andreev */ -public class ProgramParser implements VariableDebugInformation { +public class ProgramParser { private static final byte ROOT = 0; private static final byte SINGLE = 1; private static final byte DOUBLE_FIRST_HALF = 2; @@ -159,7 +159,6 @@ public class ProgramParser implements VariableDebugInformation { return depth; } - @Override public Map getDebugNames(Instruction insn) { Map map = variableDebugNames.get(insn); return map != null ? Collections.unmodifiableMap(map) : Collections.emptyMap(); diff --git a/core/src/main/java/org/teavm/parsing/VariableDebugInformation.java b/core/src/main/java/org/teavm/parsing/VariableDebugInformation.java deleted file mode 100644 index d6e2a0380..000000000 --- a/core/src/main/java/org/teavm/parsing/VariableDebugInformation.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2014 Alexey Andreev. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.teavm.parsing; - -import java.util.Map; -import org.teavm.model.Instruction; - -/** - * - * @author Alexey Andreev - */ -public interface VariableDebugInformation { - Map getDebugNames(Instruction insn); -}