Skip to content

Commit

Permalink
fixes on optimizer about CATCH, ENDFINALLY and PUSHA (#966)
Browse files Browse the repository at this point in the history
* fixes on CATCH and ENDFINALLY

* fix methodEnd

* comments on Abort & Assert tests

* TryGetValue for performance

* set PUSHA target to itself

* correct branch return type

* correct branch return type

* Move basic optimizer

* clean changes

* Update tests/Neo.Compiler.CSharp.UnitTests/UnitTest_Abort.cs

* Change visibility

---------

Co-authored-by: Fernando Diaz Toledano <[email protected]>
  • Loading branch information
Hecate2 and shargon authored Feb 28, 2024
1 parent 277c952 commit 841c440
Show file tree
Hide file tree
Showing 11 changed files with 177 additions and 84 deletions.
3 changes: 2 additions & 1 deletion src/Neo.Compiler.CSharp/CompilationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using Neo.Compiler.Optimizer;
using Neo.Cryptography.ECC;
using Neo.IO;
using Neo.Json;
Expand Down Expand Up @@ -134,7 +135,7 @@ internal void Compile()
instructions.RebuildOffsets();
if (Options.Optimize.HasFlag(CompilationOptions.OptimizationType.Basic))
{
Optimizer.CompressJumps(instructions);
BasicOptimizer.CompressJumps(instructions);
}
instructions.RebuildOperands();
}
Expand Down
3 changes: 2 additions & 1 deletion src/Neo.Compiler.CSharp/MethodConvert/MethodConvert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Neo.Compiler.Optimizer;
using Neo.Cryptography.ECC;
using Neo.IO;
using Neo.SmartContract;
Expand Down Expand Up @@ -238,7 +239,7 @@ public void Convert(SemanticModel model)
AddInstruction(OpCode.RET);
}
if (_context.Options.Optimize.HasFlag(CompilationOptions.OptimizationType.Basic))
Optimizer.RemoveNops(_instructions);
BasicOptimizer.RemoveNops(_instructions);
_startTarget.Instruction = _instructions[0];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
using Neo.VM;
using System.Collections.Generic;

namespace Neo.Compiler
namespace Neo.Compiler.Optimizer
{
static class Optimizer
static class BasicOptimizer
{
public static void RemoveNops(List<Instruction> instructions)
{
Expand Down Expand Up @@ -57,8 +57,8 @@ public static void CompressJumps(IReadOnlyList<Instruction> instructions)
}
if (instruction.OpCode == OpCode.TRY_L)
{
int offset1 = (instruction.Target.Instruction?.Offset - instruction.Offset) ?? 0;
int offset2 = (instruction.Target2!.Instruction?.Offset - instruction.Offset) ?? 0;
int offset1 = instruction.Target.Instruction?.Offset - instruction.Offset ?? 0;
int offset2 = instruction.Target2!.Instruction?.Offset - instruction.Offset ?? 0;
if (offset1 >= sbyte.MinValue && offset1 <= sbyte.MaxValue && offset2 >= sbyte.MinValue && offset2 <= sbyte.MaxValue)
{
compressed = true;
Expand Down
2 changes: 1 addition & 1 deletion src/Neo.Compiler.CSharp/Optimizer/DumpNef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

namespace Neo.Optimizer
{
public static class DumpNef
static class DumpNef
{
#pragma warning disable SYSLIB1045 // Convert to 'GeneratedRegexAttribute'.
private static readonly Regex DocumentRegex = new(@"\[(\d+)\](\d+)\:(\d+)\-(\d+)\:(\d+)", RegexOptions.Compiled);
Expand Down
58 changes: 40 additions & 18 deletions src/Neo.Compiler.CSharp/Optimizer/JumpTarget.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
using Neo.SmartContract;
using Neo.VM;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using static Neo.Optimizer.OpCodeTypes;
using static Neo.VM.OpCode;

namespace Neo.Optimizer
{
public static class JumpTarget
static class JumpTarget
{
public static bool SingleJumpInOperand(Instruction instruction) => SingleJumpInOperand(instruction.OpCode);
public static bool SingleJumpInOperand(OpCode opcode)
Expand Down Expand Up @@ -56,36 +54,60 @@ public static (int catchTarget, int finallyTarget) ComputeTryTarget(int addr, In
};
}

public static (ConcurrentDictionary<Instruction, Instruction>,
ConcurrentDictionary<Instruction, (Instruction, Instruction)>)
public static (Dictionary<Instruction, Instruction>,
Dictionary<Instruction, (Instruction, Instruction)>,
Dictionary<Instruction, HashSet<Instruction>>)
FindAllJumpAndTrySourceToTargets(NefFile nef)
{
Script script = nef.Script;
return FindAllJumpAndTrySourceToTargets(script);
}
public static (ConcurrentDictionary<Instruction, Instruction>,
ConcurrentDictionary<Instruction, (Instruction, Instruction)>)
public static (Dictionary<Instruction, Instruction>,
Dictionary<Instruction, (Instruction, Instruction)>,
Dictionary<Instruction, HashSet<Instruction>>)
FindAllJumpAndTrySourceToTargets(Script script) => FindAllJumpAndTrySourceToTargets(script.EnumerateInstructions().ToList());
public static (ConcurrentDictionary<Instruction, Instruction>,
ConcurrentDictionary<Instruction, (Instruction, Instruction)>)
public static (
Dictionary<Instruction, Instruction>, // jump source to target
Dictionary<Instruction, (Instruction, Instruction)>, // try source to targets
Dictionary<Instruction, HashSet<Instruction>> // target to source
)
FindAllJumpAndTrySourceToTargets(List<(int, Instruction)> addressAndInstructionsList)
{
Dictionary<int, Instruction> addressToInstruction = new();
foreach ((int a, Instruction i) in addressAndInstructionsList)
addressToInstruction.Add(a, i);
ConcurrentDictionary<Instruction, Instruction> jumpSourceToTargets = new();
ConcurrentDictionary<Instruction, (Instruction, Instruction)> trySourceToTargets = new();
Parallel.ForEach(addressAndInstructionsList, item =>
Dictionary<Instruction, Instruction> jumpSourceToTargets = new();
Dictionary<Instruction, (Instruction, Instruction)> trySourceToTargets = new();
Dictionary<Instruction, HashSet<Instruction>> targetToSources = new();
foreach ((int a, Instruction i) in addressAndInstructionsList)
{
(int a, Instruction i) = (item.Item1, item.Item2);
if (SingleJumpInOperand(i))
jumpSourceToTargets.TryAdd(i, addressToInstruction[ComputeJumpTarget(a, i)]);
{
Instruction target = addressToInstruction[ComputeJumpTarget(a, i)];
jumpSourceToTargets.TryAdd(i, target);
if (!targetToSources.TryGetValue(target, out HashSet<Instruction>? sources)) sources = new();
sources.Add(i);
}
if (i.OpCode == TRY)
trySourceToTargets.TryAdd(i, (addressToInstruction[a + i.TokenI8], addressToInstruction[a + i.TokenI8_1]));
{
(Instruction t1, Instruction t2) = (addressToInstruction[a + i.TokenI8], addressToInstruction[a + i.TokenI8_1]);
trySourceToTargets.TryAdd(i, (t1, t2));
if (!targetToSources.TryGetValue(t1, out HashSet<Instruction>? sources1)) sources1 = new();
sources1.Add(i);
if (!targetToSources.TryGetValue(t2, out HashSet<Instruction>? sources2)) sources2 = new();
sources2.Add(i);
}
if (i.OpCode == TRY_L)
trySourceToTargets.TryAdd(i, (addressToInstruction[a + i.TokenI32], addressToInstruction[a + i.TokenI32_1]));
});
return (jumpSourceToTargets, trySourceToTargets);
{
(Instruction t1, Instruction t2) = (addressToInstruction[a + i.TokenI32], addressToInstruction[a + i.TokenI32_1]);
trySourceToTargets.TryAdd(i, (t1, t2));
if (!targetToSources.TryGetValue(t1, out HashSet<Instruction>? sources1)) sources1 = new();
sources1.Add(i);
if (!targetToSources.TryGetValue(t2, out HashSet<Instruction>? sources2)) sources2 = new();
sources2.Add(i);
}
}
return (jumpSourceToTargets, trySourceToTargets, targetToSources);
}
}
}
2 changes: 1 addition & 1 deletion src/Neo.Compiler.CSharp/Optimizer/OpCodeTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Neo.Optimizer
{
public static class OpCodeTypes
static class OpCodeTypes
{
public static readonly HashSet<OpCode> push = new();

Expand Down
2 changes: 1 addition & 1 deletion src/Neo.Compiler.CSharp/Optimizer/Strategies/Optimizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace Neo.Optimizer
{
public class Optimizer
class Optimizer
{
public static readonly int[] OperandSizePrefixTable = new int[256];
public static readonly int[] OperandSizeTable = new int[256];
Expand Down
Loading

0 comments on commit 841c440

Please sign in to comment.