Optimization of type conversion with boxed values (transform Integer.valueOf(x). .. .longValue() -> I2L and etc)

This commit is contained in:
Denis Zharkov
2014-07-09 11:56:23 +04:00
committed by Alexander Udalov
parent 270e58cf4e
commit cb3eef4b86
4 changed files with 46 additions and 6 deletions
@@ -16,6 +16,7 @@
package org.jetbrains.jet.codegen.optimization.boxing;
import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.AsmUtil;
@@ -30,6 +31,7 @@ import java.util.Set;
public class BoxedBasicValue extends BasicValue {
private final Set<AbstractInsnNode> associatedInsns = new HashSet<AbstractInsnNode>();
private final Set<Pair<AbstractInsnNode, Type>> unboxingWithCastInsns = new HashSet<Pair<AbstractInsnNode, Type>>();
private final AbstractInsnNode boxingInsn;
private final Set<Integer> associatedVariables = new HashSet<Integer>();
private final Set<BoxedBasicValue> mergedWith = new HashSet<BoxedBasicValue>();
@@ -134,4 +136,13 @@ public class BoxedBasicValue extends BasicValue {
public ProgressionIteratorBasicValue getProgressionIterator() {
return progressionIterator;
}
public void addUnboxingWithCastTo(@NotNull AbstractInsnNode insn, @NotNull Type type) {
unboxingWithCastInsns.add(Pair.create(insn, type));
}
@NotNull
public Set<Pair<AbstractInsnNode, Type>> getUnboxingWithCastInsns() {
return unboxingWithCastInsns;
}
}
@@ -156,9 +156,8 @@ public class BoxingInterpreter extends OptimizationBasicInterpreter {
return createNewBoxing(insn, value.getType(), null);
}
else if (isUnboxing(insn) &&
firstArg instanceof BoxedBasicValue &&
value.getType().equals(((BoxedBasicValue) firstArg).getPrimitiveType())) {
onUnboxing((BoxedBasicValue) firstArg, insn);
firstArg instanceof BoxedBasicValue) {
onUnboxing(insn, (BoxedBasicValue) firstArg, value.getType());
}
else if (isIteratorMethodCallOfProgression(insn, values)) {
return new ProgressionIteratorBasicValue(
@@ -229,7 +228,7 @@ public class BoxingInterpreter extends OptimizationBasicInterpreter {
}
protected void onUnboxing(@NotNull BoxedBasicValue value, @NotNull AbstractInsnNode insn) {
protected void onUnboxing(@NotNull AbstractInsnNode insn, @NotNull BoxedBasicValue value, @NotNull Type resultType) {
}
@@ -20,8 +20,10 @@ import com.google.common.collect.ImmutableSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.org.objectweb.asm.Opcodes;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
import org.jetbrains.org.objectweb.asm.tree.InsnList;
import org.jetbrains.org.objectweb.asm.tree.TypeInsnNode;
import org.jetbrains.org.objectweb.asm.tree.VarInsnNode;
import org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException;
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue;
@@ -144,9 +146,14 @@ class RedundantBoxingInterpreter extends BoxingInterpreter {
@Override
protected void onUnboxing(
@NotNull BoxedBasicValue value, @NotNull AbstractInsnNode insn
@NotNull AbstractInsnNode insn, @NotNull BoxedBasicValue value, @NotNull Type resultType
) {
addAssociatedInsn(value, insn);
if (value.getPrimitiveType().equals(resultType)) {
addAssociatedInsn(value, insn);
}
else {
value.addUnboxingWithCastTo(insn, resultType);
}
}
@Override
@@ -18,10 +18,13 @@ package org.jetbrains.jet.codegen.optimization.boxing;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.codegen.optimization.OptimizationUtils;
import org.jetbrains.jet.codegen.optimization.transformer.MethodTransformer;
import org.jetbrains.org.objectweb.asm.Opcodes;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.org.objectweb.asm.tree.*;
import org.jetbrains.org.objectweb.asm.tree.analysis.Analyzer;
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue;
@@ -272,6 +275,10 @@ public class RedundantBoxingMethodTransformer extends MethodTransformer {
private static void adaptInstructionsForBoxedValue(@NotNull MethodNode node, @NotNull BoxedBasicValue value) {
adaptBoxingInstruction(node, value);
for (Pair<AbstractInsnNode, Type> cast : value.getUnboxingWithCastInsns()) {
adaptCastInstruction(node, value, cast);
}
for (AbstractInsnNode insn : value.getAssociatedInsns()) {
adaptInstruction(node, insn, value);
}
@@ -305,6 +312,22 @@ public class RedundantBoxingMethodTransformer extends MethodTransformer {
}
}
private static void adaptCastInstruction(
@NotNull MethodNode node,
@NotNull BoxedBasicValue value,
@NotNull Pair<AbstractInsnNode, Type> castWithType
) {
AbstractInsnNode castInsn = castWithType.getFirst();
MethodNode castInsnsListener = new MethodNode(OptimizationUtils.API);
new InstructionAdapter(castInsnsListener).cast(value.getPrimitiveType(), castWithType.getSecond());
for (AbstractInsnNode insn : castInsnsListener.instructions.toArray()) {
node.instructions.insertBefore(castInsn, insn);
}
node.instructions.remove(castInsn);
}
private static void adaptInstruction(
@NotNull MethodNode node, @NotNull AbstractInsnNode insn, @NotNull BoxedBasicValue value
) {