Optimization of type conversion with boxed values (transform Integer.valueOf(x). .. .longValue() -> I2L and etc)
This commit is contained in:
committed by
Alexander Udalov
parent
270e58cf4e
commit
cb3eef4b86
+11
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-4
@@ -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) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
+9
-2
@@ -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
|
||||
|
||||
+23
@@ -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
|
||||
) {
|
||||
|
||||
Reference in New Issue
Block a user