From 3ff05d1c5d0615aa6f04ab47408e2b69551c6e86 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Wed, 4 Mar 2020 12:14:25 +0300 Subject: [PATCH] Eliminate redundant try/catches in generated bytecode for enums --- .../model/PreOptimizingClassHolderSource.java | 3 + .../NoSuchFieldCatchElimination.java | 56 +++++++++++++++++++ core/src/main/java/org/teavm/vm/TeaVM.java | 2 +- 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 core/src/main/java/org/teavm/model/transformation/NoSuchFieldCatchElimination.java diff --git a/core/src/main/java/org/teavm/model/PreOptimizingClassHolderSource.java b/core/src/main/java/org/teavm/model/PreOptimizingClassHolderSource.java index 6b0852601..80c8998ed 100644 --- a/core/src/main/java/org/teavm/model/PreOptimizingClassHolderSource.java +++ b/core/src/main/java/org/teavm/model/PreOptimizingClassHolderSource.java @@ -20,6 +20,7 @@ import java.util.Map; import java.util.function.Function; import org.teavm.model.optimization.GlobalValueNumbering; import org.teavm.model.optimization.UnusedVariableElimination; +import org.teavm.model.transformation.NoSuchFieldCatchElimination; public class PreOptimizingClassHolderSource implements ClassHolderSource { private ClassHolderSource innerClassSource; @@ -48,8 +49,10 @@ public class PreOptimizingClassHolderSource implements ClassHolderSource { if (cls == null) { return cls; } + NoSuchFieldCatchElimination noSuchFieldCatchElimination = new NoSuchFieldCatchElimination(); for (MethodHolder method : cls.getMethods()) { if (method.getProgram() != null) { + noSuchFieldCatchElimination.apply(method.getProgram()); new GlobalValueNumbering(true).optimize(method.getProgram()); new UnusedVariableElimination().optimize(method, method.getProgram()); } diff --git a/core/src/main/java/org/teavm/model/transformation/NoSuchFieldCatchElimination.java b/core/src/main/java/org/teavm/model/transformation/NoSuchFieldCatchElimination.java new file mode 100644 index 000000000..05bd3e71e --- /dev/null +++ b/core/src/main/java/org/teavm/model/transformation/NoSuchFieldCatchElimination.java @@ -0,0 +1,56 @@ +/* + * Copyright 2020 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.model.transformation; + +import org.teavm.model.BasicBlock; +import org.teavm.model.Incoming; +import org.teavm.model.Phi; +import org.teavm.model.Program; +import org.teavm.model.TryCatchBlock; +import org.teavm.model.optimization.UnreachableBasicBlockEliminator; + +public class NoSuchFieldCatchElimination { + private UnreachableBasicBlockEliminator blockEliminator = new UnreachableBasicBlockEliminator(); + + public void apply(Program program) { + boolean modified = false; + for (BasicBlock block : program.getBasicBlocks()) { + for (int i = 0; i < block.getTryCatchBlocks().size(); ++i) { + TryCatchBlock tryCatch = block.getTryCatchBlocks().get(i); + if (tryCatch.getExceptionType() != null + && tryCatch.getExceptionType().equals(NoSuchFieldError.class.getName())) { + updateTryCatchHandler(tryCatch); + block.getTryCatchBlocks().remove(i--); + modified = true; + } + } + } + if (modified) { + blockEliminator.optimize(program); + } + } + + private void updateTryCatchHandler(TryCatchBlock tryCatch) { + for (Phi phi : tryCatch.getHandler().getPhis()) { + for (int i = 0; i < phi.getIncomings().size(); ++i) { + Incoming incoming = phi.getIncomings().get(i); + if (incoming.getSource() == tryCatch.getProtectedBlock()) { + phi.getIncomings().remove(i--); + } + } + } + } +} diff --git a/core/src/main/java/org/teavm/vm/TeaVM.java b/core/src/main/java/org/teavm/vm/TeaVM.java index 10c885dd6..07fcba50c 100644 --- a/core/src/main/java/org/teavm/vm/TeaVM.java +++ b/core/src/main/java/org/teavm/vm/TeaVM.java @@ -769,7 +769,7 @@ public class TeaVM implements TeaVMHost, ServiceRepository { //optimizations.add(new LoopInversion()); optimizations.add(new LoopInvariantMotion()); } - if (optimizationLevel.ordinal() >= TeaVMOptimizationLevel.FULL.ordinal()) { + if (optimizationLevel.ordinal() >= TeaVMOptimizationLevel.ADVANCED.ordinal()) { optimizations.add(new RepeatedFieldReadElimination()); } optimizations.add(new GlobalValueNumbering(optimizationLevel == TeaVMOptimizationLevel.SIMPLE));