From 94f3fffdecd64139019fcd8a6d5231f1d26eacb8 Mon Sep 17 00:00:00 2001 From: Jessie Lesbian Date: Sat, 28 Dec 2019 20:49:39 +0700 Subject: [PATCH] IKVM v8.6.3.0 preoptimizer update: more aggresive optimizations + branch optimization --- CommonAssemblyInfo.cs.in | 2 +- openjdk/commonAttributes.class | Bin 3029 -> 3029 bytes openjdk/java/lang/PropertyConstants.class | Bin 537 -> 537 bytes runtime/compiler.cs | 2 +- runtime/jessielesbian.cs | 198 ++++++++++++++++------ 5 files changed, 150 insertions(+), 52 deletions(-) diff --git a/CommonAssemblyInfo.cs.in b/CommonAssemblyInfo.cs.in index f65fe044a..8d08dc8d7 100644 --- a/CommonAssemblyInfo.cs.in +++ b/CommonAssemblyInfo.cs.in @@ -29,7 +29,7 @@ using System.Reflection; [assembly: AssemblyCopyright("Copyright (C) 2019 Jessie Lesbian (based on work by Jeroen Frijters and Windward Studios)")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("8.6.2.0")] +[assembly: AssemblyVersion("8.6.3.0")] #if SIGNCODE #pragma warning disable 1699 diff --git a/openjdk/commonAttributes.class b/openjdk/commonAttributes.class index 22248184b36538d5830510afd4d9517aa85013db..3eae2957450242227c35cd83b6f18318391745fa 100644 GIT binary patch delta 14 VcmcaAepP&fG#jJwW*N4ftN 0); } } @@ -35,6 +36,85 @@ private static Instruction GetInstuction(NormalizedByteCode bc, int arg1, short instruction.PatchOpCode(bc, arg1, arg2); return instruction; } + private static bool IsBranchInstruction(Instruction instruction) + { + switch (instruction.NormalizedOpCode) + { + case NormalizedByteCode.__goto: + case NormalizedByteCode.__goto_finally: + case NormalizedByteCode.__ifeq: + case NormalizedByteCode.__ifge: + case NormalizedByteCode.__ifgt: + case NormalizedByteCode.__ifle: + case NormalizedByteCode.__iflt: + case NormalizedByteCode.__ifne: + case NormalizedByteCode.__ifnonnull: + case NormalizedByteCode.__ifnull: + case NormalizedByteCode.__if_acmpeq: + case NormalizedByteCode.__if_acmpne: + case NormalizedByteCode.__if_icmpeq: + case NormalizedByteCode.__if_icmpge: + case NormalizedByteCode.__if_icmpgt: + case NormalizedByteCode.__if_icmple: + case NormalizedByteCode.__if_icmplt: + case NormalizedByteCode.__if_icmpne: + return true; + default: + return false; + } + } + private static bool IsLoadInstruction(Instruction instruction) + { + switch (instruction.NormalizedOpCode) + { + case NormalizedByteCode.__aload: + case NormalizedByteCode.__iload: + case NormalizedByteCode.__lload: + case NormalizedByteCode.__dload: + case NormalizedByteCode.__fload: + case NormalizedByteCode.__aconst_null: + case NormalizedByteCode.__iconst: + case NormalizedByteCode.__lconst_0: + case NormalizedByteCode.__lconst_1: + case NormalizedByteCode.__dconst_0: + case NormalizedByteCode.__dconst_1: + case NormalizedByteCode.__fconst_0: + case NormalizedByteCode.__fconst_1: + case NormalizedByteCode.__fconst_2: + case NormalizedByteCode.__ldc: + return true; + default: + return false; + } + } + private static bool IsArrayLoadInstruction(Instruction instruction) + { + switch (instruction.NormalizedOpCode) + { + case NormalizedByteCode.__aaload: + case NormalizedByteCode.__iaload: + case NormalizedByteCode.__laload: + case NormalizedByteCode.__daload: + case NormalizedByteCode.__faload: + return true; + default: + return false; + } + } + private static bool IsStoreInstruction(Instruction instruction) + { + switch (instruction.NormalizedOpCode) + { + case NormalizedByteCode.__astore: + case NormalizedByteCode.__istore: + case NormalizedByteCode.__lstore: + case NormalizedByteCode.__dstore: + case NormalizedByteCode.__fstore: + return true; + default: + return false; + } + } internal static Instruction[] Optimize(Instruction[] instructions) { //Jessie Lesbian's IKVM.NET JIT Optimizer @@ -45,30 +125,9 @@ internal static Instruction[] Optimize(Instruction[] instructions) List brtargets = new List(instructions.Length); for (int i = 1; i < instructions.Length; i++) { - switch (instructions[i].NormalizedOpCode) + if (IsBranchInstruction(instructions[i])) { - case NormalizedByteCode.__goto: - case NormalizedByteCode.__goto_finally: - case NormalizedByteCode.__ifeq: - case NormalizedByteCode.__ifge: - case NormalizedByteCode.__ifgt: - case NormalizedByteCode.__ifle: - case NormalizedByteCode.__iflt: - case NormalizedByteCode.__ifne: - case NormalizedByteCode.__ifnonnull: - case NormalizedByteCode.__ifnull: - case NormalizedByteCode.__if_acmpeq: - case NormalizedByteCode.__if_acmpne: - case NormalizedByteCode.__if_icmpeq: - case NormalizedByteCode.__if_icmpge: - case NormalizedByteCode.__if_icmpgt: - case NormalizedByteCode.__if_icmple: - case NormalizedByteCode.__if_icmplt: - case NormalizedByteCode.__if_icmpne: - brtargets.Add(instructions[i].TargetIndex); - break; - default: - continue; + brtargets.Add(i); } } while (optimizations != 0) @@ -76,6 +135,15 @@ internal static Instruction[] Optimize(Instruction[] instructions) optimizations = 0; for (int i = 1; i < instructions.Length; i++) { + int prevIndex = i - 1; + while (prevIndex > 0 || instructions[prevIndex].NormalizedOpCode == NormalizedByteCode.__nop) + { + prevIndex--; + } + if (brtargets.Contains(prevIndex) || IsBranchInstruction(instructions[prevIndex])) + { + continue; + } Instruction current = instructions[i]; Instruction prev = instructions[i - 1]; if (brtargets.Contains(i)) @@ -90,7 +158,7 @@ internal static Instruction[] Optimize(Instruction[] instructions) { continue; } - //peephole optimization: removal of unused arithmethc operations + //peephole optimization: anihilation of pops if (current.NormalizedOpCode == NormalizedByteCode.__pop) { switch (prev.NormalizedOpCode) @@ -135,20 +203,21 @@ internal static Instruction[] Optimize(Instruction[] instructions) prev = GetInstuction(NormalizedByteCode.__pop); optimizations = optimizations + 1; break; - case NormalizedByteCode.__dup: - prev = GetInstuction(NormalizedByteCode.__nop); - current = GetInstuction(NormalizedByteCode.__nop); - optimizations = optimizations + 1; - break; - case NormalizedByteCode.__aload: + case NormalizedByteCode.__anewarray: prev = GetInstuction(NormalizedByteCode.__nop); - current = GetInstuction(NormalizedByteCode.__nop); - break; - case NormalizedByteCode.__aaload: - prev = GetInstuction(NormalizedByteCode.__pop); - current = GetInstuction(NormalizedByteCode.__pop); break; default: + if (IsBranchInstruction(prev)) + { + prev = GetInstuction(NormalizedByteCode.__nop); + current = GetInstuction(NormalizedByteCode.__nop); + optimizations = optimizations + 1; + } + if (IsArrayLoadInstruction(prev)) + { + prev = GetInstuction(NormalizedByteCode.__pop); + optimizations = optimizations + 1; + } break; } } @@ -170,10 +239,21 @@ internal static Instruction[] Optimize(Instruction[] instructions) break; } } + //peephole optimization: strength reduction + if (current.NormalizedOpCode == prev.NormalizedOpCode && IsBranchInstruction(current) && current.NormalizedArg1 == prev.NormalizedArg1) + { + current = GetInstuction(NormalizedByteCode.__dup); + optimizations = optimizations + 1; + } + if (current.NormalizedOpCode == prev.NormalizedOpCode && IsStoreInstruction(current) && current.NormalizedArg1 == prev.NormalizedArg1) + { + prev = GetInstuction(NormalizedByteCode.__pop); + optimizations = optimizations + 1; + } //peephole optimization: optimize addition and subtraction - if((prev.NormalizedOpCode == NormalizedByteCode.__ineg)) + if ((prev.NormalizedOpCode == NormalizedByteCode.__ineg)) { - if(current.NormalizedOpCode == NormalizedByteCode.__iadd) + if (current.NormalizedOpCode == NormalizedByteCode.__iadd) { current = GetInstuction(NormalizedByteCode.__isub); prev = GetInstuction(NormalizedByteCode.__nop); @@ -232,7 +312,7 @@ internal static Instruction[] Optimize(Instruction[] instructions) } } //peephole optimization: remove unnecessary swaps - if(prev.NormalizedOpCode == NormalizedByteCode.__swap) + if (prev.NormalizedOpCode == NormalizedByteCode.__swap) { switch (current.NormalizedOpCode) { @@ -256,17 +336,6 @@ internal static Instruction[] Optimize(Instruction[] instructions) current = GetInstuction(NormalizedByteCode.__nop); optimizations = optimizations + 1; } - //peephole optimization: local variable acession optimization - if (current.NormalizedOpCode == prev.NormalizedOpCode && current.NormalizedOpCode == NormalizedByteCode.__aload && current.NormalizedArg1 == prev.NormalizedArg1) - { - current = GetInstuction(NormalizedByteCode.__dup); - optimizations = optimizations + 1; - } - if (current.NormalizedOpCode == prev.NormalizedOpCode && current.NormalizedOpCode == NormalizedByteCode.__astore && current.NormalizedArg1 == prev.NormalizedArg1) - { - prev = GetInstuction(NormalizedByteCode.__pop); - optimizations = optimizations + 1; - } //peephole optimization: return optimization if (current.NormalizedOpCode == NormalizedByteCode.__return) { @@ -284,7 +353,36 @@ internal static Instruction[] Optimize(Instruction[] instructions) break; } } - //sorry, I can't implement branch optimizations. + //branch optimizations + if(prev.NormalizedOpCode == NormalizedByteCode.__aconst_null) + { + if(current.NormalizedOpCode == NormalizedByteCode.__ifnull) + { + prev = GetInstuction(NormalizedByteCode.__nop); + current.PatchOpCode(NormalizedByteCode.__goto); + optimizations = optimizations + 1; + } + else if (current.NormalizedOpCode == NormalizedByteCode.__ifnonnull) + { + prev = GetInstuction(NormalizedByteCode.__nop); + current = prev; + optimizations = optimizations + 1; + } + } + if(IsBranchInstruction(current)) + { + Instruction target = instructions[current.TargetIndex]; + if (target.NormalizedOpCode == NormalizedByteCode.__goto) + { + current.TargetIndex = target.TargetIndex; + optimizations = optimizations + 1; + } + else if(target.NormalizedOpCode == NormalizedByteCode.__nop) + { + current.TargetIndex++; + optimizations = optimizations + 1; + } + } instructions[i] = current; instructions[i - 1] = prev; }