From f2bbfed740a8cb35e5cd122f841ed3556ec9bd2b Mon Sep 17 00:00:00 2001 From: ishland Date: Tue, 19 Nov 2024 18:04:08 +0800 Subject: [PATCH] perf: fold ConstantNode into calling methods --- .../common/ast/binary/AbstractBinaryNode.java | 17 +- .../dfc/common/ast/binary/MaxShortNode.java | 8 +- .../dfc/common/ast/binary/MinShortNode.java | 8 +- .../opts/dfc/common/ast/binary/MulNode.java | 8 +- .../dfc/common/ast/misc/CacheLikeNode.java | 8 +- .../dfc/common/ast/misc/RangeChoiceNode.java | 14 +- .../opts/dfc/common/ast/misc/RootNode.java | 4 +- .../ast/noise/DFTWeirdScaledSamplerNode.java | 4 +- .../common/ast/noise/ShiftedNoiseNode.java | 32 +--- .../dfc/common/ast/spline/SplineAstNode.java | 21 ++- .../common/ast/unary/AbstractUnaryNode.java | 4 +- .../c2me/opts/dfc/common/gen/BytecodeGen.java | 145 +++++++++++++----- 12 files changed, 154 insertions(+), 119 deletions(-) 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 3f4f2da19..cf95505ef 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 @@ -77,8 +77,8 @@ public AstNode transform(AstTransformer transformer) { @Override public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { - String leftMethod = context.newSingleMethod(this.left); - String rightMethod = context.newSingleMethod(this.right); + BytecodeGen.Context.ValuesMethodDefD leftMethod = context.newSingleMethod(this.left); + BytecodeGen.Context.ValuesMethodDefD rightMethod = context.newSingleMethod(this.right); context.callDelegateSingle(m, leftMethod); context.callDelegateSingle(m, rightMethod); @@ -86,8 +86,8 @@ public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter @Override public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { - String leftMethod = context.newMultiMethod(this.left); - String rightMethod = context.newMultiMethod(this.right); + 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)); @@ -98,14 +98,7 @@ public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m 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); - m.load(0, InstructionAdapter.OBJECT_TYPE); - m.load(res1, InstructionAdapter.OBJECT_TYPE); - m.load(2, InstructionAdapter.OBJECT_TYPE); - m.load(3, InstructionAdapter.OBJECT_TYPE); - m.load(4, InstructionAdapter.OBJECT_TYPE); - m.load(5, InstructionAdapter.OBJECT_TYPE); - m.load(6, InstructionAdapter.OBJECT_TYPE); - m.invokevirtual(context.className, rightMethod, BytecodeGen.Context.MULTI_DESC, false); + context.callDelegateMulti(m, rightMethod, res1); context.doCountedLoop(m, localVarConsumer, idx -> bytecodeGenMultiBody(m, idx, res1)); 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 4d672a582..b735e048a 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 @@ -37,8 +37,8 @@ public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) { @Override public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { - String leftMethod = context.newSingleMethod(this.left); - String rightMethod = context.newSingleMethod(this.right); + BytecodeGen.Context.ValuesMethodDefD leftMethod = context.newSingleMethod(this.left); + BytecodeGen.Context.ValuesMethodDefD rightMethod = context.newSingleMethod(this.right); Label minLabel = new Label(); @@ -62,8 +62,8 @@ public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter @Override public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { - String leftMethod = context.newMultiMethod(this.left); - String rightMethodSingle = context.newSingleMethod(this.right); + BytecodeGen.Context.ValuesMethodDefD leftMethod = context.newMultiMethod(this.left); + BytecodeGen.Context.ValuesMethodDefD rightMethodSingle = context.newSingleMethod(this.right); context.callDelegateMulti(m, leftMethod); context.doCountedLoop(m, localVarConsumer, idx -> { 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 44fd85e80..c925674d8 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 @@ -37,8 +37,8 @@ public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) { @Override public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { - String leftMethod = context.newSingleMethod(this.left); - String rightMethod = context.newSingleMethod(this.right); + BytecodeGen.Context.ValuesMethodDefD leftMethod = context.newSingleMethod(this.left); + BytecodeGen.Context.ValuesMethodDefD rightMethod = context.newSingleMethod(this.right); Label minLabel = new Label(); @@ -62,8 +62,8 @@ public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter @Override public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { - String leftMethod = context.newMultiMethod(this.left); - String rightMethodSingle = context.newSingleMethod(this.right); + BytecodeGen.Context.ValuesMethodDefD leftMethod = context.newMultiMethod(this.left); + BytecodeGen.Context.ValuesMethodDefD rightMethodSingle = context.newSingleMethod(this.right); context.callDelegateMulti(m, leftMethod); context.doCountedLoop(m, localVarConsumer, idx -> { 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 0c3acba2d..e6c26e4ad 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 @@ -34,8 +34,8 @@ public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) { @Override public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { - String leftMethod = context.newSingleMethod(this.left); - String rightMethod = context.newSingleMethod(this.right); + BytecodeGen.Context.ValuesMethodDefD leftMethod = context.newSingleMethod(this.left); + BytecodeGen.Context.ValuesMethodDefD rightMethod = context.newSingleMethod(this.right); Label notZero = new Label(); @@ -55,8 +55,8 @@ public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter @Override public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { - String leftMethod = context.newMultiMethod(this.left); - String rightMethodSingle = context.newSingleMethod(this.right); + BytecodeGen.Context.ValuesMethodDefD leftMethod = context.newMultiMethod(this.left); + BytecodeGen.Context.ValuesMethodDefD rightMethodSingle = context.newSingleMethod(this.right); context.callDelegateMulti(m, leftMethod); context.doCountedLoop(m, localVarConsumer, idx -> { diff --git a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/misc/CacheLikeNode.java b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/misc/CacheLikeNode.java index 4be577271..d4dc17259 100644 --- a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/misc/CacheLikeNode.java +++ b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/misc/CacheLikeNode.java @@ -73,7 +73,7 @@ public AstNode transform(AstTransformer transformer) { @Override public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { - String delegateMethod = context.newSingleMethod(this.delegate); + BytecodeGen.Context.ValuesMethodDefD delegateMethod = context.newSingleMethod(this.delegate); String cacheLikeField = context.newField(IFastCacheLike.class, this.cacheLike); genPostprocessingMethod(context, cacheLikeField); @@ -123,7 +123,7 @@ public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter @Override public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { - String delegateMethod = context.newMultiMethod(this.delegate); + BytecodeGen.Context.ValuesMethodDefD delegateMethod = context.newMultiMethod(this.delegate); String cacheLikeField = context.newField(IFastCacheLike.class, this.cacheLike); genPostprocessingMethod(context, cacheLikeField); @@ -164,8 +164,8 @@ public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m private void genPostprocessingMethod(BytecodeGen.Context context, String cacheLikeField) { String methodName = String.format("postProcessing_%s", cacheLikeField); - String delegateSingle = context.newSingleMethod(this.delegate); - String delegateMulti = context.newMultiMethod(this.delegate); + String delegateSingle = context.newSingleMethodUnoptimized(this.delegate); + String delegateMulti = context.newMultiMethodUnoptimized(this.delegate); context.genPostprocessingMethod(methodName, m -> { Label cacheExists = new Label(); diff --git a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/misc/RangeChoiceNode.java b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/misc/RangeChoiceNode.java index 4cac0a3bf..1a181df2a 100644 --- a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/misc/RangeChoiceNode.java +++ b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/misc/RangeChoiceNode.java @@ -201,9 +201,9 @@ public AstNode transform(AstTransformer transformer) { @Override public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { - String inputMethod = context.newSingleMethod(this.input); - String whenInRangeMethod = context.newSingleMethod(this.whenInRange); - String whenOutOfRangeMethod = context.newSingleMethod(this.whenOutOfRange); + BytecodeGen.Context.ValuesMethodDefD inputMethod = context.newSingleMethod(this.input); + BytecodeGen.Context.ValuesMethodDefD whenInRangeMethod = context.newSingleMethod(this.whenInRange); + BytecodeGen.Context.ValuesMethodDefD whenOutOfRangeMethod = context.newSingleMethod(this.whenOutOfRange); int inputValue = localVarConsumer.createLocalVariable("inputValue", Type.DOUBLE_TYPE.getDescriptor()); context.callDelegateSingle(m, inputMethod); @@ -241,10 +241,10 @@ public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter @Override public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { - String inputSingle = context.newSingleMethod(this.input); - String whenInRangeSingle = context.newSingleMethod(this.whenInRange); - String whenOutOfRangeSingle = context.newSingleMethod(this.whenOutOfRange); - String inputMulti = context.newMultiMethod(this.input); + BytecodeGen.Context.ValuesMethodDefD inputSingle = context.newSingleMethod(this.input); + BytecodeGen.Context.ValuesMethodDefD whenInRangeSingle = context.newSingleMethod(this.whenInRange); + BytecodeGen.Context.ValuesMethodDefD whenOutOfRangeSingle = context.newSingleMethod(this.whenOutOfRange); + BytecodeGen.Context.ValuesMethodDefD inputMulti = context.newMultiMethod(this.input); // String whenInRangeMulti = context.newMultiMethod(this.whenInRange); // String whenOutOfRangeMulti = context.newMultiMethod(this.whenOutOfRange); diff --git a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/misc/RootNode.java b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/misc/RootNode.java index b282ddeb9..57bad1da2 100644 --- a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/misc/RootNode.java +++ b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/misc/RootNode.java @@ -44,14 +44,14 @@ public AstNode transform(AstTransformer transformer) { @Override public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { - String nextMethod = context.newSingleMethod(this.next); + BytecodeGen.Context.ValuesMethodDefD nextMethod = context.newSingleMethod(this.next); context.callDelegateSingle(m, nextMethod); m.areturn(Type.DOUBLE_TYPE); } @Override public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { - String nextMethod = context.newMultiMethod(this.next); + BytecodeGen.Context.ValuesMethodDefD nextMethod = context.newMultiMethod(this.next); context.callDelegateMulti(m, nextMethod); m.areturn(Type.VOID_TYPE); } diff --git a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/noise/DFTWeirdScaledSamplerNode.java b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/noise/DFTWeirdScaledSamplerNode.java index 554a1a28c..63ff27e18 100644 --- a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/noise/DFTWeirdScaledSamplerNode.java +++ b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/noise/DFTWeirdScaledSamplerNode.java @@ -59,7 +59,7 @@ public AstNode transform(AstTransformer transformer) { @Override public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { - String inputMethod = context.newSingleMethod(this.input); + BytecodeGen.Context.ValuesMethodDefD inputMethod = context.newSingleMethod(this.input); String noiseField = context.newField(DensityFunction.Noise.class, this.noise); int scale = localVarConsumer.createLocalVariable("scale", Type.DOUBLE_TYPE.getDescriptor()); @@ -120,7 +120,7 @@ public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter @Override public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { - String inputMethod = context.newMultiMethod(this.input); + BytecodeGen.Context.ValuesMethodDefD inputMethod = context.newMultiMethod(this.input); String noiseField = context.newField(DensityFunction.Noise.class, this.noise); context.callDelegateMulti(m, inputMethod); diff --git a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/noise/ShiftedNoiseNode.java b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/noise/ShiftedNoiseNode.java index 8e2137016..cc98d30c1 100644 --- a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/noise/ShiftedNoiseNode.java +++ b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/noise/ShiftedNoiseNode.java @@ -76,9 +76,9 @@ public AstNode transform(AstTransformer transformer) { public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { String noiseField = context.newField(Noise.class, this.noise); - String shiftXMethod = context.newSingleMethod(this.shiftX); - String shiftYMethod = context.newSingleMethod(this.shiftY); - String shiftZMethod = context.newSingleMethod(this.shiftZ); + BytecodeGen.Context.ValuesMethodDefD shiftXMethod = context.newSingleMethod(this.shiftX); + BytecodeGen.Context.ValuesMethodDefD shiftYMethod = context.newSingleMethod(this.shiftY); + BytecodeGen.Context.ValuesMethodDefD shiftZMethod = context.newSingleMethod(this.shiftZ); m.load(0, InstructionAdapter.OBJECT_TYPE); m.getfield(context.className, noiseField, Type.getDescriptor(Noise.class)); @@ -117,9 +117,9 @@ public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { String noiseField = context.newField(Noise.class, this.noise); - String shiftXMethod = context.newMultiMethod(this.shiftX); - String shiftYMethod = context.newMultiMethod(this.shiftY); - String shiftZMethod = context.newMultiMethod(this.shiftZ); + BytecodeGen.Context.ValuesMethodDefD shiftXMethod = context.newMultiMethod(this.shiftX); + BytecodeGen.Context.ValuesMethodDefD shiftYMethod = context.newMultiMethod(this.shiftY); + BytecodeGen.Context.ValuesMethodDefD shiftZMethod = context.newMultiMethod(this.shiftZ); int res1 = localVarConsumer.createLocalVariable("res1", Type.getDescriptor(double[].class)); int res2 = localVarConsumer.createLocalVariable("res2", Type.getDescriptor(double[].class)); @@ -139,24 +139,8 @@ public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m m.store(res2, InstructionAdapter.OBJECT_TYPE); context.callDelegateMulti(m, shiftXMethod); - - m.load(0, InstructionAdapter.OBJECT_TYPE); - m.load(res1, InstructionAdapter.OBJECT_TYPE); - m.load(2, InstructionAdapter.OBJECT_TYPE); - m.load(3, InstructionAdapter.OBJECT_TYPE); - m.load(4, InstructionAdapter.OBJECT_TYPE); - m.load(5, InstructionAdapter.OBJECT_TYPE); - m.load(6, InstructionAdapter.OBJECT_TYPE); - m.invokevirtual(context.className, shiftYMethod, BytecodeGen.Context.MULTI_DESC, false); - - m.load(0, InstructionAdapter.OBJECT_TYPE); - m.load(res2, InstructionAdapter.OBJECT_TYPE); - m.load(2, InstructionAdapter.OBJECT_TYPE); - m.load(3, InstructionAdapter.OBJECT_TYPE); - m.load(4, InstructionAdapter.OBJECT_TYPE); - m.load(5, InstructionAdapter.OBJECT_TYPE); - m.load(6, InstructionAdapter.OBJECT_TYPE); - m.invokevirtual(context.className, shiftZMethod, BytecodeGen.Context.MULTI_DESC, false); + context.callDelegateMulti(m, shiftYMethod, res1); + context.callDelegateMulti(m, shiftZMethod, res2); context.doCountedLoop(m, localVarConsumer, idx -> { m.load(1, InstructionAdapter.OBJECT_TYPE); diff --git a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/spline/SplineAstNode.java b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/spline/SplineAstNode.java index 417997ac3..717822c1f 100644 --- a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/spline/SplineAstNode.java +++ b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/spline/SplineAstNode.java @@ -56,21 +56,21 @@ public AstNode transform(AstTransformer transformer) { @Override public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { - ValuesMethodDef splineMethod = doBytecodeGenSpline(context, this.spline); + BytecodeGen.Context.ValuesMethodDefF splineMethod = doBytecodeGenSpline(context, this.spline); callSplineSingle(context, m, splineMethod); m.cast(Type.FLOAT_TYPE, Type.DOUBLE_TYPE); m.areturn(Type.DOUBLE_TYPE); } - private static ValuesMethodDef doBytecodeGenSpline(BytecodeGen.Context context, Spline spline) { + private static BytecodeGen.Context.ValuesMethodDefF doBytecodeGenSpline(BytecodeGen.Context context, Spline spline) { { String cachedSplineMethod = context.getCachedSplineMethod(spline); if (cachedSplineMethod != null) { - return new ValuesMethodDef(false, cachedSplineMethod, 0.0F); + return new BytecodeGen.Context.ValuesMethodDefF(cachedSplineMethod); } } if (spline instanceof Spline.FixedFloatFunction spline1) { - return new ValuesMethodDef(true, null, spline1.value()); + return new BytecodeGen.Context.ValuesMethodDefF(spline1.value()); } String name = context.nextMethodName("Spline"); InstructionAdapter m = new InstructionAdapter( @@ -99,9 +99,9 @@ private static ValuesMethodDef doBytecodeGenSpline(BytecodeGen.Context context, }; if (spline instanceof Spline.Implementation impl) { - ValuesMethodDef[] valuesMethods = impl.values().stream() + BytecodeGen.Context.ValuesMethodDefF[] valuesMethods = impl.values().stream() .map(spline1 -> doBytecodeGenSpline(context, spline1)) - .toArray(ValuesMethodDef[]::new); + .toArray(BytecodeGen.Context.ValuesMethodDefF[]::new); String locations = context.newField(float[].class, impl.locations()); String derivatives = context.newField(float[].class, impl.derivatives()); @@ -111,7 +111,7 @@ private static ValuesMethodDef doBytecodeGenSpline(BytecodeGen.Context context, int lastConst = impl.locations().length - 1; - String locationFunction = context.newSingleMethod(McToAst.toAst(impl.locationFunction().function().value())); + BytecodeGen.Context.ValuesMethodDefD locationFunction = context.newSingleMethod(McToAst.toAst(impl.locationFunction().function().value())); context.callDelegateSingle(m, locationFunction); m.cast(Type.DOUBLE_TYPE, Type.FLOAT_TYPE); m.store(point, Type.FLOAT_TYPE); @@ -395,10 +395,10 @@ private static ValuesMethodDef doBytecodeGenSpline(BytecodeGen.Context context, context.cacheSplineMethod(spline, name); - return new ValuesMethodDef(false, name, 0.0F); + return new BytecodeGen.Context.ValuesMethodDefF(name); } - private static void callSplineSingle(BytecodeGen.Context context, InstructionAdapter m, ValuesMethodDef target) { + private static void callSplineSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.ValuesMethodDefF target) { if (target.isConst()) { m.fconst(target.constValue()); } else { @@ -411,9 +411,6 @@ private static void callSplineSingle(BytecodeGen.Context context, InstructionAda } } - private record ValuesMethodDef(boolean isConst, String generatedMethod, float constValue) { - } - @Override public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { context.delegateAllToSingle(m, localVarConsumer, this); diff --git a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/unary/AbstractUnaryNode.java b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/unary/AbstractUnaryNode.java index c2266d129..7cf35c247 100644 --- a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/unary/AbstractUnaryNode.java +++ b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/ast/unary/AbstractUnaryNode.java @@ -70,13 +70,13 @@ public AstNode transform(AstTransformer transformer) { @Override public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { - String operandMethod = context.newSingleMethod(this.operand); + BytecodeGen.Context.ValuesMethodDefD operandMethod = context.newSingleMethod(this.operand); context.callDelegateSingle(m, operandMethod); } @Override public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) { - String operandMethod = context.newMultiMethod(this.operand); + BytecodeGen.Context.ValuesMethodDefD operandMethod = context.newMultiMethod(this.operand); context.callDelegateMulti(m, operandMethod); } } diff --git a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/gen/BytecodeGen.java b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/gen/BytecodeGen.java index 423bffc87..9b8227db0 100644 --- a/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/gen/BytecodeGen.java +++ b/c2me-opts-dfc/src/main/java/com/ishland/c2me/opts/dfc/common/gen/BytecodeGen.java @@ -37,6 +37,7 @@ import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.ListIterator; @@ -347,15 +348,24 @@ public String nextMethodName(String suffix) { return String.format("method_%d_%s", methodIdx++, suffix); } - public String newSingleMethod(AstNode node) { + public ValuesMethodDefD newSingleMethod(AstNode node) { + if (node instanceof ConstantNode constantNode) { + return new ValuesMethodDefD(constantNode.getValue()); + } else { + String generated = this.newSingleMethodUnoptimized(node); + return new ValuesMethodDefD(generated); + } + } + + public String newSingleMethodUnoptimized(AstNode node) { return this.singleMethods.computeIfAbsent(node, (AstNode node1) -> this.newSingleMethod((adapter, localVarConsumer) -> node1.doBytecodeGenSingle(this, adapter, localVarConsumer), nextMethodName(node.getClass().getSimpleName()))); } - public String newSingleMethod(BiConsumer generator) { + private String newSingleMethod(BiConsumer generator) { return newSingleMethod(generator, nextMethodName()); } - public String newSingleMethod(BiConsumer generator, String name) { + private String newSingleMethod(BiConsumer generator, String name) { newSingleMethod0(generator, name, false); return name; } @@ -397,15 +407,24 @@ private void newSingleMethod0(BiConsumer g adapter.visitMaxs(0, 0); } - public String newMultiMethod(AstNode node) { + public ValuesMethodDefD newMultiMethod(AstNode node) { + if (node instanceof ConstantNode constantNode) { + return new ValuesMethodDefD(constantNode.getValue()); + } else { + String generated = newMultiMethodUnoptimized(node); + return new ValuesMethodDefD(generated); + } + } + + public String newMultiMethodUnoptimized(AstNode node) { return this.multiMethods.computeIfAbsent(node, (AstNode node1) -> this.newMultiMethod((adapter, localVarConsumer) -> node1.doBytecodeGenMulti(this, adapter, localVarConsumer), nextMethodName(node.getClass().getSimpleName()))); } - public String newMultiMethod(BiConsumer generator) { + private String newMultiMethod(BiConsumer generator) { return newMultiMethod(generator, nextMethodName()); } - public String newMultiMethod(BiConsumer generator, String name) { + private String newMultiMethod(BiConsumer generator, String name) { newMultiMethod0(generator, name, false); return name; } @@ -457,45 +476,63 @@ public void cacheSplineMethod(Spline String newField(Class type, T data) { @@ -536,7 +573,7 @@ public void doCountedLoop(InstructionAdapter m, LocalVarConsumer localVarConsume } public void delegateAllToSingle(InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer, AstNode current) { - String singleMethod = this.newSingleMethod(current); + ValuesMethodDefD singleMethod = this.newSingleMethod(current); this.doCountedLoop(m, localVarConsumer, idx -> { m.load(1, InstructionAdapter.OBJECT_TYPE); m.load(idx, Type.INT_TYPE); @@ -580,6 +617,30 @@ public static interface LocalVarConsumer { int createLocalVariable(String name, String descriptor); } + public record ValuesMethodDefF(boolean isConst, String generatedMethod, float constValue) { + + public ValuesMethodDefF(String generatedMethod) { + this(false, generatedMethod, Float.NaN); + } + + public ValuesMethodDefF(float constValue) { + this(true, null, constValue); + } + + } + + public record ValuesMethodDefD(boolean isConst, String generatedMethod, double constValue) { + + public ValuesMethodDefD(String generatedMethod) { + this(false, generatedMethod, Double.NaN); + } + + public ValuesMethodDefD(double constValue) { + this(true, null, constValue); + } + + } + private static record FieldRecord(String name, int ordinal, Class type) { } }