mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
C: reduce number of synthesized null checks
This commit is contained in:
parent
9ad0ddd891
commit
a240537e36
|
@ -191,6 +191,17 @@ public class ExceptionHandlingShadowStackContributor {
|
||||||
BasicBlock initialBlock = block;
|
BasicBlock initialBlock = block;
|
||||||
|
|
||||||
for (Instruction insn : block) {
|
for (Instruction insn : block) {
|
||||||
|
insn.acceptVisitor(defExtractor);
|
||||||
|
for (Variable definedVar : defExtractor.getDefinedVariables()) {
|
||||||
|
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
||||||
|
int jointReceiver = jointReceiverMaps.get(tryCatch.getHandler().getIndex())[definedVar.getIndex()];
|
||||||
|
if (jointReceiver >= 0) {
|
||||||
|
currentJointSources[jointReceiver] = definedVar.getIndex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
variablesDefinedHere.add(definedVar.getIndex());
|
||||||
|
}
|
||||||
|
|
||||||
if (isCallInstruction(insn)) {
|
if (isCallInstruction(insn)) {
|
||||||
BasicBlock next;
|
BasicBlock next;
|
||||||
boolean last = false;
|
boolean last = false;
|
||||||
|
@ -250,17 +261,6 @@ public class ExceptionHandlingShadowStackContributor {
|
||||||
block = next;
|
block = next;
|
||||||
variablesDefinedHere.clear();
|
variablesDefinedHere.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
insn.acceptVisitor(defExtractor);
|
|
||||||
for (Variable definedVar : defExtractor.getDefinedVariables()) {
|
|
||||||
for (TryCatchBlock tryCatch : block.getTryCatchBlocks()) {
|
|
||||||
int jointReceiver = jointReceiverMaps.get(tryCatch.getHandler().getIndex())[definedVar.getIndex()];
|
|
||||||
if (jointReceiver >= 0) {
|
|
||||||
currentJointSources[jointReceiver] = definedVar.getIndex();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
variablesDefinedHere.add(definedVar.getIndex());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fixOutgoingPhis(initialBlock, block, currentJointSources, variablesDefinedHere);
|
fixOutgoingPhis(initialBlock, block, currentJointSources, variablesDefinedHere);
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.model.lowlevel;
|
package org.teavm.model.lowlevel;
|
||||||
|
|
||||||
|
import com.carrotsearch.hppc.IntHashSet;
|
||||||
|
import com.carrotsearch.hppc.IntSet;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import org.teavm.model.BasicBlock;
|
import org.teavm.model.BasicBlock;
|
||||||
|
@ -32,6 +34,8 @@ import org.teavm.model.instructions.NullCheckInstruction;
|
||||||
import org.teavm.model.instructions.PutFieldInstruction;
|
import org.teavm.model.instructions.PutFieldInstruction;
|
||||||
import org.teavm.model.instructions.RaiseInstruction;
|
import org.teavm.model.instructions.RaiseInstruction;
|
||||||
import org.teavm.model.instructions.UnwrapArrayInstruction;
|
import org.teavm.model.instructions.UnwrapArrayInstruction;
|
||||||
|
import org.teavm.model.util.DominatorWalker;
|
||||||
|
import org.teavm.model.util.DominatorWalkerCallback;
|
||||||
import org.teavm.model.util.PhiUpdater;
|
import org.teavm.model.util.PhiUpdater;
|
||||||
|
|
||||||
public class NullCheckInsertion {
|
public class NullCheckInsertion {
|
||||||
|
@ -42,23 +46,51 @@ public class NullCheckInsertion {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void transformProgram(Program program, MethodReference methodReference) {
|
public void transformProgram(Program program, MethodReference methodReference) {
|
||||||
if (!characteristics.isManaged(methodReference)) {
|
if (!characteristics.isManaged(methodReference) || program.basicBlockCount() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
InsertionVisitor visitor = new InsertionVisitor();
|
InsertionVisitor visitor = new InsertionVisitor(program.variableCount());
|
||||||
for (BasicBlock block : program.getBasicBlocks()) {
|
new DominatorWalker(program).walk(visitor);
|
||||||
for (Instruction instruction : block) {
|
|
||||||
instruction.acceptVisitor(visitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (visitor.changed) {
|
if (visitor.changed) {
|
||||||
new PhiUpdater().updatePhis(program, methodReference.parameterCount() + 1);
|
new PhiUpdater().updatePhis(program, methodReference.parameterCount() + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class InsertionVisitor extends AbstractInstructionVisitor {
|
class InsertionVisitor extends AbstractInstructionVisitor implements DominatorWalkerCallback<BlockNullness> {
|
||||||
boolean changed;
|
boolean changed;
|
||||||
|
boolean[] notNullVariables;
|
||||||
|
BlockNullness blockNullness;
|
||||||
|
|
||||||
|
InsertionVisitor(int variableCount) {
|
||||||
|
notNullVariables = new boolean[variableCount];
|
||||||
|
if (variableCount > 0) {
|
||||||
|
notNullVariables[0] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockNullness visit(BasicBlock block) {
|
||||||
|
blockNullness = new BlockNullness();
|
||||||
|
|
||||||
|
if (block.getExceptionVariable() != null) {
|
||||||
|
notNullVariables[block.getExceptionVariable().getIndex()] = true;
|
||||||
|
blockNullness.notNullVariables.add(block.getExceptionVariable().getIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Instruction instruction : block) {
|
||||||
|
instruction.acceptVisitor(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return blockNullness;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endVisit(BasicBlock block, BlockNullness state) {
|
||||||
|
for (int variable : state.notNullVariables.toArray()) {
|
||||||
|
notNullVariables[variable] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(RaiseInstruction insn) {
|
public void visit(RaiseInstruction insn) {
|
||||||
|
@ -114,6 +146,13 @@ public class NullCheckInsertion {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (notNullVariables[value.getIndex()]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
notNullVariables[value.getIndex()] = true;
|
||||||
|
blockNullness.notNullVariables.add(value.getIndex());
|
||||||
|
|
||||||
NullCheckInstruction nullCheck = new NullCheckInstruction();
|
NullCheckInstruction nullCheck = new NullCheckInstruction();
|
||||||
nullCheck.setValue(value);
|
nullCheck.setValue(value);
|
||||||
nullCheck.setReceiver(value);
|
nullCheck.setReceiver(value);
|
||||||
|
@ -123,4 +162,8 @@ public class NullCheckInsertion {
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class BlockNullness {
|
||||||
|
IntSet notNullVariables = new IntHashSet();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,8 +48,8 @@ public class LivenessAnalyzer {
|
||||||
public void analyze(Program program) {
|
public void analyze(Program program) {
|
||||||
Graph cfg = ProgramUtils.buildControlFlowGraph(program);
|
Graph cfg = ProgramUtils.buildControlFlowGraph(program);
|
||||||
DominatorTree dominatorTree = GraphUtils.buildDominatorTree(cfg);
|
DominatorTree dominatorTree = GraphUtils.buildDominatorTree(cfg);
|
||||||
liveVars = new BitSet[cfg.size()];
|
liveVars = new BitSet[program.basicBlockCount()];
|
||||||
liveOutVars = new BitSet[cfg.size()];
|
liveOutVars = new BitSet[program.basicBlockCount()];
|
||||||
for (int i = 0; i < liveVars.length; ++i) {
|
for (int i = 0; i < liveVars.length; ++i) {
|
||||||
liveVars[i] = new BitSet(program.basicBlockCount());
|
liveVars[i] = new BitSet(program.basicBlockCount());
|
||||||
liveOutVars[i] = new BitSet(program.basicBlockCount());
|
liveOutVars[i] = new BitSet(program.basicBlockCount());
|
||||||
|
|
|
@ -760,8 +760,8 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
||||||
optimizations.add(new LoopInvariantMotion());
|
optimizations.add(new LoopInvariantMotion());
|
||||||
}
|
}
|
||||||
optimizations.add(new GlobalValueNumbering(optimizationLevel == TeaVMOptimizationLevel.SIMPLE));
|
optimizations.add(new GlobalValueNumbering(optimizationLevel == TeaVMOptimizationLevel.SIMPLE));
|
||||||
|
optimizations.add(new RedundantNullCheckElimination());
|
||||||
if (optimizationLevel.ordinal() >= TeaVMOptimizationLevel.ADVANCED.ordinal()) {
|
if (optimizationLevel.ordinal() >= TeaVMOptimizationLevel.ADVANCED.ordinal()) {
|
||||||
optimizations.add(new RedundantNullCheckElimination());
|
|
||||||
optimizations.add(new ConstantConditionElimination());
|
optimizations.add(new ConstantConditionElimination());
|
||||||
optimizations.add(new RedundantJumpElimination());
|
optimizations.add(new RedundantJumpElimination());
|
||||||
optimizations.add(new UnusedVariableElimination());
|
optimizations.add(new UnusedVariableElimination());
|
||||||
|
|
|
@ -39,6 +39,7 @@ import org.teavm.model.instructions.ConstructInstruction;
|
||||||
import org.teavm.model.instructions.ExitInstruction;
|
import org.teavm.model.instructions.ExitInstruction;
|
||||||
import org.teavm.model.instructions.InvocationType;
|
import org.teavm.model.instructions.InvocationType;
|
||||||
import org.teavm.model.instructions.InvokeInstruction;
|
import org.teavm.model.instructions.InvokeInstruction;
|
||||||
|
import org.teavm.model.instructions.JumpInstruction;
|
||||||
import org.teavm.runtime.Fiber;
|
import org.teavm.runtime.Fiber;
|
||||||
|
|
||||||
public class AsyncMethodProcessor implements ClassHolderTransformer {
|
public class AsyncMethodProcessor implements ClassHolderTransformer {
|
||||||
|
@ -89,8 +90,14 @@ public class AsyncMethodProcessor implements ClassHolderTransformer {
|
||||||
|
|
||||||
Program program = new Program();
|
Program program = new Program();
|
||||||
method.setProgram(program);
|
method.setProgram(program);
|
||||||
|
|
||||||
|
BasicBlock startBlock = program.createBasicBlock();
|
||||||
BasicBlock block = program.createBasicBlock();
|
BasicBlock block = program.createBasicBlock();
|
||||||
|
|
||||||
|
JumpInstruction jumpToBlock = new JumpInstruction();
|
||||||
|
jumpToBlock.setTarget(block);
|
||||||
|
startBlock.add(jumpToBlock);
|
||||||
|
|
||||||
InvokeInstruction constructorInvocation = new InvokeInstruction();
|
InvokeInstruction constructorInvocation = new InvokeInstruction();
|
||||||
constructorInvocation.setType(InvocationType.SPECIAL);
|
constructorInvocation.setType(InvocationType.SPECIAL);
|
||||||
List<ValueType> signature = new ArrayList<>();
|
List<ValueType> signature = new ArrayList<>();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user