diff --git a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/AbstractBinaryNode.java b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/AbstractBinaryNode.java index 6708d1ae..abf786f7 100644 --- a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/AbstractBinaryNode.java +++ b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/AbstractBinaryNode.java @@ -97,27 +97,33 @@ public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m BytecodeGen.Context.ValuesMethodDefD leftMethod = context.newMultiMethod(this.left); BytecodeGen.Context.ValuesMethodDefD rightMethod = context.newMultiMethod(this.right); - int res1 = localVarConsumer.createLocalVariable("res1", Type.getDescriptor(double[].class)); - - m.load(6, InstructionAdapter.OBJECT_TYPE); - m.load(1, InstructionAdapter.OBJECT_TYPE); - m.arraylength(); - m.iconst(0); - m.invokevirtual(Type.getInternalName(ArrayCache.class), "getDoubleArray", Type.getMethodDescriptor(Type.getType(double[].class), Type.INT_TYPE, Type.BOOLEAN_TYPE), false); - m.store(res1, InstructionAdapter.OBJECT_TYPE); - context.callDelegateMulti(m, leftMethod); - context.callDelegateMulti(m, rightMethod, res1); - - context.doCountedLoop(m, localVarConsumer, idx -> bytecodeGenMultiBody(m, idx, res1)); - - m.load(6, InstructionAdapter.OBJECT_TYPE); - m.load(res1, InstructionAdapter.OBJECT_TYPE); - m.invokevirtual(Type.getInternalName(ArrayCache.class), "recycle", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(double[].class)), false); + if (leftMethod.isConst()) { + context.callDelegateMulti(m, rightMethod); + context.doCountedLoop(m, localVarConsumer, idx -> bytecodeGenConstMultiBody(m, idx, leftMethod.constValue())); + } else { + int res1 = localVarConsumer.createLocalVariable("res1", Type.getDescriptor(double[].class)); + + m.load(6, InstructionAdapter.OBJECT_TYPE); + m.load(1, InstructionAdapter.OBJECT_TYPE); + m.arraylength(); + m.iconst(0); + m.invokevirtual(Type.getInternalName(ArrayCache.class), "getDoubleArray", Type.getMethodDescriptor(Type.getType(double[].class), Type.INT_TYPE, Type.BOOLEAN_TYPE), false); + m.store(res1, InstructionAdapter.OBJECT_TYPE); + context.callDelegateMulti(m, leftMethod); + context.callDelegateMulti(m, rightMethod, res1); + + context.doCountedLoop(m, localVarConsumer, idx -> bytecodeGenMultiBody(m, idx, res1)); + + m.load(6, InstructionAdapter.OBJECT_TYPE); + m.load(res1, InstructionAdapter.OBJECT_TYPE); + m.invokevirtual(Type.getInternalName(ArrayCache.class), "recycle", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(double[].class)), false); + } m.areturn(Type.VOID_TYPE); } protected abstract void bytecodeGenMultiBody(InstructionAdapter m, int idx, int res1); + protected abstract void bytecodeGenConstMultiBody(InstructionAdapter m, int idx, double constLeft); } diff --git a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/AddNode.java b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/AddNode.java index 5599ece3..e137c03e 100644 --- a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/AddNode.java +++ b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/AddNode.java @@ -51,4 +51,16 @@ protected void bytecodeGenMultiBody(InstructionAdapter m, int idx, int res1) { m.add(Type.DOUBLE_TYPE); m.astore(Type.DOUBLE_TYPE); } + + @Override + protected void bytecodeGenConstMultiBody(InstructionAdapter m, int idx, double constLeft) { + m.load(1, InstructionAdapter.OBJECT_TYPE); + m.load(idx, Type.INT_TYPE); + m.dconst(constLeft); + m.load(1, InstructionAdapter.OBJECT_TYPE); + m.load(idx, Type.INT_TYPE); + m.aload(Type.DOUBLE_TYPE); + m.add(Type.DOUBLE_TYPE); + m.astore(Type.DOUBLE_TYPE); + } } diff --git a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/MaxNode.java b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/MaxNode.java index 8026dd58..b6992f36 100644 --- a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/MaxNode.java +++ b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/MaxNode.java @@ -61,4 +61,21 @@ protected void bytecodeGenMultiBody(InstructionAdapter m, int idx, int res1) { ); m.astore(Type.DOUBLE_TYPE); } + + @Override + protected void bytecodeGenConstMultiBody(InstructionAdapter m, int idx, double constLeft) { + m.load(1, InstructionAdapter.OBJECT_TYPE); + m.load(idx, Type.INT_TYPE); + m.dconst(constLeft); + m.load(1, InstructionAdapter.OBJECT_TYPE); + m.load(idx, Type.INT_TYPE); + m.aload(Type.DOUBLE_TYPE); + m.invokestatic( + Type.getInternalName(Math.class), + "max", + Type.getMethodDescriptor(Type.DOUBLE_TYPE, Type.DOUBLE_TYPE, Type.DOUBLE_TYPE), + false + ); + m.astore(Type.DOUBLE_TYPE); + } } diff --git a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/MaxShortNode.java b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/MaxShortNode.java index a8822eef..f41014c0 100644 --- a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/MaxShortNode.java +++ b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/MaxShortNode.java @@ -108,4 +108,9 @@ public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m protected void bytecodeGenMultiBody(InstructionAdapter m, int idx, int res1) { throw new UnsupportedOperationException(); } + + @Override + protected void bytecodeGenConstMultiBody(InstructionAdapter m, int idx, double constLeft) { + throw new UnsupportedOperationException(); + } } diff --git a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/MinNode.java b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/MinNode.java index 77410d3b..48bf605a 100644 --- a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/MinNode.java +++ b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/MinNode.java @@ -61,4 +61,21 @@ protected void bytecodeGenMultiBody(InstructionAdapter m, int idx, int res1) { ); m.astore(Type.DOUBLE_TYPE); } + + @Override + protected void bytecodeGenConstMultiBody(InstructionAdapter m, int idx, double constLeft) { + m.load(1, InstructionAdapter.OBJECT_TYPE); + m.load(idx, Type.INT_TYPE); + m.dconst(constLeft); + m.load(1, InstructionAdapter.OBJECT_TYPE); + m.load(idx, Type.INT_TYPE); + m.aload(Type.DOUBLE_TYPE); + m.invokestatic( + Type.getInternalName(Math.class), + "min", + Type.getMethodDescriptor(Type.DOUBLE_TYPE, Type.DOUBLE_TYPE, Type.DOUBLE_TYPE), + false + ); + m.astore(Type.DOUBLE_TYPE); + } } diff --git a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/MinShortNode.java b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/MinShortNode.java index e6075fd4..f7402b5d 100644 --- a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/MinShortNode.java +++ b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/MinShortNode.java @@ -108,4 +108,9 @@ public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m protected void bytecodeGenMultiBody(InstructionAdapter m, int idx, int res1) { throw new UnsupportedOperationException(); } + + @Override + protected void bytecodeGenConstMultiBody(InstructionAdapter m, int idx, double constLeft) { + throw new UnsupportedOperationException(); + } } diff --git a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/MulNode.java b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/MulNode.java index 916c9415..fb446640 100644 --- a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/MulNode.java +++ b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/binary/MulNode.java @@ -127,4 +127,9 @@ public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m protected void bytecodeGenMultiBody(InstructionAdapter m, int idx, int res1) { throw new UnsupportedOperationException(); } + + @Override + protected void bytecodeGenConstMultiBody(InstructionAdapter m, int idx, double constLeft) { + throw new UnsupportedOperationException(); + } }