From 5d0735bbf07d39be3e3dd35c8ee310072c09c43a Mon Sep 17 00:00:00 2001 From: Sam Byass Date: Sun, 10 Oct 2021 12:03:00 +0100 Subject: [PATCH] Performance enhancement for unused local stripper. Closes #5 --- .../ARM64/Arm64FieldReadToRegAction.cs | 4 ++-- .../ARM64/Arm64ImmediateToFieldAction.cs | 2 +- .../ARM64/Arm64ManagedFunctionCallAction.cs | 2 +- .../Actions/ARM64/Arm64NewObjectAction.cs | 2 +- .../ARM64/Arm64RegisterToFieldAction.cs | 4 ++-- .../Actions/ARM64/Arm64ReturnAction.cs | 2 +- .../Actions/Base/AbstractCallAction.cs | 8 ++++---- .../Actions/Base/AbstractComparisonAction.cs | 4 ++-- .../Base/AbstractConditionalJumpAction.cs | 12 ++++++------ .../Analysis/Actions/Base/BaseAction.cs | 3 ++- .../ConstantArrayOffsetPointerToRegAction.cs | 2 +- .../x86/ConstantToStackOffsetAction.cs | 2 +- .../x86/ImmediateToStackOffsetAction.cs | 2 +- .../x86/Important/AddRegToRegAction.cs | 4 ++-- .../x86/Important/AllocateArrayAction.cs | 4 ++-- .../x86/Important/AllocateInstanceAction.cs | 2 +- .../Important/ArrayElementReadToRegAction.cs | 4 ++-- .../Important/CallManagedFunctionAction.cs | 2 +- .../CallManagedFunctionInRegAction.cs | 2 +- .../x86/Important/CallMethodSpecAction.cs | 2 +- .../x86/Important/CallVirtualMethodAction.cs | 2 +- .../ConstantArrayOffsetToRegAction.cs | 2 +- .../x86/Important/EbpOffsetToLocalAction.cs | 2 +- .../x86/Important/FieldToLocalAction.cs | 4 ++-- .../x86/Important/ImmediateToFieldAction.cs | 2 +- .../Important/Implicit4ByteFieldReadAction.cs | 2 +- .../RegOffsetArrayValueReadRegToRegAction.cs | 4 ++-- .../RegToConstantArrayOffsetAction.cs | 4 ++-- .../Actions/x86/Important/RegToFieldAction.cs | 10 +++++----- .../x86/Important/RegToStaticFieldAction.cs | 2 +- .../x86/Important/ReturnFromFunctionAction.cs | 2 +- .../x86/Important/SubtractRegFromRegAction.cs | 4 ++-- .../x86/Important/ThreeOperandImulAction.cs | 4 ++-- .../Actions/x86/Important/ThrowAction.cs | 2 +- .../x86/IntegerDivisionShiftStepAction.cs | 2 +- .../Actions/x86/LocalToStackOffsetAction.cs | 2 +- .../Actions/x86/PushRegisterAction.cs | 2 +- Cpp2IL.Core/Analysis/AsmAnalyzerBase.cs | 7 +++++-- Cpp2IL.Core/Analysis/AsmAnalyzerX86.cs | 19 +++++++++++-------- .../0RemovedUnusedLocalsPostProcessor.cs | 19 ++++++++++++------- .../Analysis/ResultModels/MethodAnalysis.cs | 2 ++ Cpp2IL.Core/Cpp2IlApi.cs | 2 ++ Cpp2IL.Core/SharedState.cs | 4 ++++ 43 files changed, 97 insertions(+), 77 deletions(-) diff --git a/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64FieldReadToRegAction.cs b/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64FieldReadToRegAction.cs index fb5bbafd..37bbe8a4 100644 --- a/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64FieldReadToRegAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64FieldReadToRegAction.cs @@ -20,11 +20,11 @@ public Arm64FieldReadToRegAction(MethodAnalysis context, Arm64 if(FieldRead == null) return; - RegisterUsedLocal(ReadFrom); + RegisterUsedLocal(ReadFrom, context); LocalWritten = context.MakeLocal(FieldRead.GetFinalType()!, reg: destReg); - RegisterUsedLocal(LocalWritten); + RegisterUsedLocal(LocalWritten, context); } } } \ No newline at end of file diff --git a/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64ImmediateToFieldAction.cs b/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64ImmediateToFieldAction.cs index 5f8ae504..0ee487f0 100644 --- a/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64ImmediateToFieldAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64ImmediateToFieldAction.cs @@ -19,7 +19,7 @@ public Arm64ImmediateToFieldAction(MethodAnalysis context, Arm if(InstanceBeingSetOn?.Type == null) return; - RegisterUsedLocal(InstanceBeingSetOn); + RegisterUsedLocal(InstanceBeingSetOn, context); FieldWritten = FieldUtils.GetFieldBeingAccessed(InstanceBeingSetOn.Type, (ulong)instruction.MemoryOffset(), false); } diff --git a/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64ManagedFunctionCallAction.cs b/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64ManagedFunctionCallAction.cs index 08e718d1..7ad74c1a 100644 --- a/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64ManagedFunctionCallAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64ManagedFunctionCallAction.cs @@ -59,7 +59,7 @@ private void HandleReturnType(MethodAnalysis context) { CreateLocalForReturnType(context); - RegisterLocals(); + RegisterLocals(context); if (ManagedMethodBeingCalled?.FullName == "System.Void System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(System.Array,System.RuntimeFieldHandle)") { diff --git a/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64NewObjectAction.cs b/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64NewObjectAction.cs index 5da83f0b..d5a46a38 100644 --- a/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64NewObjectAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64NewObjectAction.cs @@ -19,7 +19,7 @@ public Arm64NewObjectAction(MethodAnalysis context, Arm64Instr LocalReturned = context.MakeLocal(TypeCreated, reg: "x0"); - RegisterUsedLocal(LocalReturned); + RegisterUsedLocal(LocalReturned, context); } } } \ No newline at end of file diff --git a/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64RegisterToFieldAction.cs b/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64RegisterToFieldAction.cs index 2b3c6dc6..56b617f9 100644 --- a/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64RegisterToFieldAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64RegisterToFieldAction.cs @@ -21,10 +21,10 @@ public Arm64RegisterToFieldAction(MethodAnalysis context, Arm6 if(InstanceBeingSetOn?.Type == null) return; - RegisterUsedLocal(InstanceBeingSetOn); + RegisterUsedLocal(InstanceBeingSetOn, context); if(_sourceOperand is LocalDefinition l) - RegisterUsedLocal(l); + RegisterUsedLocal(l, context); FieldWritten = FieldUtils.GetFieldBeingAccessed(InstanceBeingSetOn.Type, (ulong)instruction.MemoryOffset(), sourceReg[0] == 'v'); } diff --git a/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64ReturnAction.cs b/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64ReturnAction.cs index 1569e449..309e7297 100644 --- a/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64ReturnAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/ARM64/Arm64ReturnAction.cs @@ -25,7 +25,7 @@ public Arm64ReturnAction(MethodAnalysis context, Arm64Instruct }; if (returnValue is LocalDefinition l) - RegisterUsedLocal(l); + RegisterUsedLocal(l, context); } } } \ No newline at end of file diff --git a/Cpp2IL.Core/Analysis/Actions/Base/AbstractCallAction.cs b/Cpp2IL.Core/Analysis/Actions/Base/AbstractCallAction.cs index 0ecf1001..43218dd0 100644 --- a/Cpp2IL.Core/Analysis/Actions/Base/AbstractCallAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/Base/AbstractCallAction.cs @@ -173,7 +173,7 @@ protected void CreateLocalForReturnType(MethodAnalysis context) ReturnedLocal = context.MakeLocal(returnType, reg: destReg); //todo maybe improve? - RegisterUsedLocal(ReturnedLocal); + RegisterUsedLocal(ReturnedLocal, context); } } @@ -212,11 +212,11 @@ private TypeReference ResolveGenericReturnTypeIfNeeded(TypeReference returnType, return returnType; } - protected void RegisterLocals() + protected void RegisterLocals(MethodAnalysis context) { - Arguments?.Where(o => o is LocalDefinition).ToList().ForEach(o => RegisterUsedLocal((LocalDefinition) o!)); + Arguments?.Where(o => o is LocalDefinition).ToList().ForEach(o => RegisterUsedLocal((LocalDefinition) o!, context)); if (InstanceBeingCalledOn != null) - RegisterUsedLocal(InstanceBeingCalledOn); + RegisterUsedLocal(InstanceBeingCalledOn, context); } public List GetILToLoadParams(MethodAnalysis context, ILProcessor processor, bool includeThis = true) diff --git a/Cpp2IL.Core/Analysis/Actions/Base/AbstractComparisonAction.cs b/Cpp2IL.Core/Analysis/Actions/Base/AbstractComparisonAction.cs index 373eaf11..ed5f0550 100644 --- a/Cpp2IL.Core/Analysis/Actions/Base/AbstractComparisonAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/Base/AbstractComparisonAction.cs @@ -62,10 +62,10 @@ protected AbstractComparisonAction(MethodAnalysis context, T associatedInstru } if (ArgumentOne is LocalDefinition l1) - RegisterUsedLocal(l1); + RegisterUsedLocal(l1, context); if (ArgumentTwo is LocalDefinition l2) - RegisterUsedLocal(l2); + RegisterUsedLocal(l2, context); } public override Instruction[] ToILInstructions(MethodAnalysis context, ILProcessor processor) diff --git a/Cpp2IL.Core/Analysis/Actions/Base/AbstractConditionalJumpAction.cs b/Cpp2IL.Core/Analysis/Actions/Base/AbstractConditionalJumpAction.cs index 4ce8a54e..396b769d 100644 --- a/Cpp2IL.Core/Analysis/Actions/Base/AbstractConditionalJumpAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/Base/AbstractConditionalJumpAction.cs @@ -38,18 +38,18 @@ protected AbstractConditionalJumpAction(MethodAnalysis context, ulong branchT // } if (associatedCompare?.ArgumentOne is LocalDefinition l) - RegisterUsedLocal(l); + RegisterUsedLocal(l, context); else if (associatedCompare?.ArgumentOne is ComparisonDirectFieldAccess a) - RegisterUsedLocal(a.localAccessedOn); + RegisterUsedLocal(a.localAccessedOn, context); else if (associatedCompare?.ArgumentOne is ComparisonDirectPropertyAccess p) - RegisterUsedLocal(p.localAccessedOn); + RegisterUsedLocal(p.localAccessedOn, context); if (associatedCompare?.ArgumentTwo is LocalDefinition l2) - RegisterUsedLocal(l2); + RegisterUsedLocal(l2, context); else if (associatedCompare?.ArgumentTwo is ComparisonDirectFieldAccess a2) - RegisterUsedLocal(a2.localAccessedOn); + RegisterUsedLocal(a2.localAccessedOn, context); else if (associatedCompare?.ArgumentTwo is ComparisonDirectPropertyAccess p2) - RegisterUsedLocal(p2.localAccessedOn); + RegisterUsedLocal(p2.localAccessedOn, context); var (currBlockStart, currBlockEnd) = context.GetMostRecentBlock(AssociatedInstruction.GetInstructionAddress()); diff --git a/Cpp2IL.Core/Analysis/Actions/Base/BaseAction.cs b/Cpp2IL.Core/Analysis/Actions/Base/BaseAction.cs index 0008e5ca..1b3aa45e 100644 --- a/Cpp2IL.Core/Analysis/Actions/Base/BaseAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/Base/BaseAction.cs @@ -35,9 +35,10 @@ public List GetUsedLocals() return UsedLocals; } - protected void RegisterUsedLocal(LocalDefinition l) + protected void RegisterUsedLocal(LocalDefinition l, MethodAnalysis context) { UsedLocals.Add(l); + context.UnusedLocals.Remove(l); } public List GetRegisteredLocalsWithoutSideEffects() diff --git a/Cpp2IL.Core/Analysis/Actions/x86/ConstantArrayOffsetPointerToRegAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/ConstantArrayOffsetPointerToRegAction.cs index bcc1aa23..b1200643 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/ConstantArrayOffsetPointerToRegAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/ConstantArrayOffsetPointerToRegAction.cs @@ -26,7 +26,7 @@ public ConstantArrayOffsetPointerToRegAction(MethodAnalysis context if (_arrayLocal?.Type?.IsArray != true) return; - RegisterUsedLocal(_arrayLocal); + RegisterUsedLocal(_arrayLocal, context); _index = (int) ((arrayOffset - Il2CppArrayUtils.FirstItemOffset) / Utils.GetPointerSizeBytes()); diff --git a/Cpp2IL.Core/Analysis/Actions/x86/ConstantToStackOffsetAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/ConstantToStackOffsetAction.cs index e724a98e..36d6e613 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/ConstantToStackOffsetAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/ConstantToStackOffsetAction.cs @@ -23,7 +23,7 @@ public ConstantToStackOffsetAction(MethodAnalysis context, Instruct _newLocal = context.MakeLocal(Utils.TryLookupTypeDefKnownNotGeneric(_sourceConstant.Type.FullName)!, knownInitialValue: _sourceConstant.Value); context.StackStoredLocals[(int) _stackOffset] = _newLocal; - RegisterUsedLocal(_newLocal); + RegisterUsedLocal(_newLocal, context); } public override Mono.Cecil.Cil.Instruction[] ToILInstructions(MethodAnalysis context, ILProcessor processor) diff --git a/Cpp2IL.Core/Analysis/Actions/x86/ImmediateToStackOffsetAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/ImmediateToStackOffsetAction.cs index 156b65ca..08ac87ce 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/ImmediateToStackOffsetAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/ImmediateToStackOffsetAction.cs @@ -18,7 +18,7 @@ public ImmediateToStackOffsetAction(MethodAnalysis context, Instruc _newLocal = context.MakeLocal(Utils.UInt64Reference, knownInitialValue: _sourceImmediate); context.StackStoredLocals[(int) _stackOffset] = _newLocal; - RegisterUsedLocal(_newLocal); + RegisterUsedLocal(_newLocal, context); } public override Mono.Cecil.Cil.Instruction[] ToILInstructions(MethodAnalysis context, ILProcessor processor) diff --git a/Cpp2IL.Core/Analysis/Actions/x86/Important/AddRegToRegAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/Important/AddRegToRegAction.cs index b8067d31..56433bef 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/Important/AddRegToRegAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/Important/AddRegToRegAction.cs @@ -20,10 +20,10 @@ public AddRegToRegAction(MethodAnalysis context, Instruction instru _secondOp = context.GetOperandInRegister(secondReg); if(_firstOp != null) - RegisterUsedLocal(_firstOp); + RegisterUsedLocal(_firstOp, context); if(_secondOp is LocalDefinition l) - RegisterUsedLocal(l); + RegisterUsedLocal(l, context); } public override Mono.Cecil.Cil.Instruction[] ToILInstructions(MethodAnalysis context, ILProcessor processor) diff --git a/Cpp2IL.Core/Analysis/Actions/x86/Important/AllocateArrayAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/Important/AllocateArrayAction.cs index b350fd7c..15ce6344 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/Important/AllocateArrayAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/Important/AllocateArrayAction.cs @@ -32,7 +32,7 @@ public AllocateArrayAction(MethodAnalysis context, Instruction inst if (sizeOperand is LocalDefinition local && (local.KnownInitialValue is ulong || local.KnownInitialValue is uint)) { - RegisterUsedLocal(local); + RegisterUsedLocal(local, context); SizeAllocated = Convert.ToInt32(local.KnownInitialValue); } else if (sizeOperand is ConstantDefinition {Value: ulong sizeC}) @@ -46,7 +46,7 @@ public AllocateArrayAction(MethodAnalysis context, Instruction inst if (TypeOfArray is not ArrayType arrayType) return; LocalWritten = context.MakeLocal(arrayType, reg: "rax", knownInitialValue: new AllocatedArray(SizeAllocated, arrayType)); - RegisterUsedLocal(LocalWritten); //Used implicitly until I can find out what's causing these issues + RegisterUsedLocal(LocalWritten, context); //Used implicitly until I can find out what's causing these issues } } } \ No newline at end of file diff --git a/Cpp2IL.Core/Analysis/Actions/x86/Important/AllocateInstanceAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/Important/AllocateInstanceAction.cs index c964f9d8..8786b15e 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/Important/AllocateInstanceAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/Important/AllocateInstanceAction.cs @@ -19,7 +19,7 @@ public AllocateInstanceAction(MethodAnalysis context, Instruction i LocalReturned = context.MakeLocal(TypeCreated, reg: "rax"); //Keeping this as used implicitly because we have to create instances of things. - RegisterUsedLocal(LocalReturned); + RegisterUsedLocal(LocalReturned, context); if (LibCpp2IlMain.Binary.is32Bit) context.Stack.Pop(); //Pop off the type created diff --git a/Cpp2IL.Core/Analysis/Actions/x86/Important/ArrayElementReadToRegAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/Important/ArrayElementReadToRegAction.cs index a305be26..e8674a99 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/Important/ArrayElementReadToRegAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/Important/ArrayElementReadToRegAction.cs @@ -29,10 +29,10 @@ public ArrayElementReadToRegAction(MethodAnalysis context, Instruct LocalMade = context.MakeLocal(ArrType.ElementType, reg: destReg); - RegisterUsedLocal(ArrayLocal); + RegisterUsedLocal(ArrayLocal, context); if(OffsetLocal != null) - RegisterUsedLocal(OffsetLocal); + RegisterUsedLocal(OffsetLocal, context); } } } \ No newline at end of file diff --git a/Cpp2IL.Core/Analysis/Actions/x86/Important/CallManagedFunctionAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/Important/CallManagedFunctionAction.cs index f71fa6b4..a826afc2 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/Important/CallManagedFunctionAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/Important/CallManagedFunctionAction.cs @@ -216,7 +216,7 @@ private void HandleReturnType(MethodAnalysis context) { CreateLocalForReturnType(context); - RegisterLocals(); + RegisterLocals(context); if (ManagedMethodBeingCalled?.FullName == "System.Void System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray(System.Array,System.RuntimeFieldHandle)") { diff --git a/Cpp2IL.Core/Analysis/Actions/x86/Important/CallManagedFunctionInRegAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/Important/CallManagedFunctionInRegAction.cs index a7c1951c..709bd9ae 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/Important/CallManagedFunctionInRegAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/Important/CallManagedFunctionInRegAction.cs @@ -45,7 +45,7 @@ public CallManagedFunctionInRegAction(MethodAnalysis context, Instr CreateLocalForReturnType(context); - RegisterLocals(); + RegisterLocals(context); } } } \ No newline at end of file diff --git a/Cpp2IL.Core/Analysis/Actions/x86/Important/CallMethodSpecAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/Important/CallMethodSpecAction.cs index fab5d5b3..038b5ff5 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/Important/CallMethodSpecAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/Important/CallMethodSpecAction.cs @@ -32,7 +32,7 @@ public CallMethodSpecAction(MethodAnalysis context, Instruction ins ManagedMethodBeingCalled = ManagedMethodBeingCalled.MakeMethodOnGenericType(methodSpec.GenericClassParams.Select(p => Utils.TryResolveTypeReflectionData(p, ManagedMethodBeingCalled)).ToArray()!); CreateLocalForReturnType(context); - RegisterLocals(); + RegisterLocals(context); } } } \ No newline at end of file diff --git a/Cpp2IL.Core/Analysis/Actions/x86/Important/CallVirtualMethodAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/Important/CallVirtualMethodAction.cs index 472fb593..f3e39e5d 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/Important/CallVirtualMethodAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/Important/CallVirtualMethodAction.cs @@ -26,7 +26,7 @@ public CallVirtualMethodAction(MethodAnalysis context, Instruction AddComment("Arguments are incorrect?"); CreateLocalForReturnType(context); - RegisterLocals(); + RegisterLocals(context); } } } \ No newline at end of file diff --git a/Cpp2IL.Core/Analysis/Actions/x86/Important/ConstantArrayOffsetToRegAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/Important/ConstantArrayOffsetToRegAction.cs index ce701a01..0791c3a0 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/Important/ConstantArrayOffsetToRegAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/Important/ConstantArrayOffsetToRegAction.cs @@ -26,7 +26,7 @@ public ConstantArrayOffsetToRegAction(MethodAnalysis context, Instr if (_arrayLocal?.Type?.IsArray != true) return; - RegisterUsedLocal(_arrayLocal); + RegisterUsedLocal(_arrayLocal, context); _index = (int) ((arrayOffset - Il2CppArrayUtils.FirstItemOffset) / Utils.GetPointerSizeBytes()); diff --git a/Cpp2IL.Core/Analysis/Actions/x86/Important/EbpOffsetToLocalAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/Important/EbpOffsetToLocalAction.cs index 52c14a32..db184339 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/Important/EbpOffsetToLocalAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/Important/EbpOffsetToLocalAction.cs @@ -19,7 +19,7 @@ public EbpOffsetToLocalAction(MethodAnalysis context, Instruction i if (localBeingRead == null) return; - RegisterUsedLocal(localBeingRead); + RegisterUsedLocal(localBeingRead, context); _destReg = Utils.GetRegisterNameNew(instruction.Op0Register); diff --git a/Cpp2IL.Core/Analysis/Actions/x86/Important/FieldToLocalAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/Important/FieldToLocalAction.cs index cd20c824..93911a16 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/Important/FieldToLocalAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/Important/FieldToLocalAction.cs @@ -22,13 +22,13 @@ public FieldToLocalAction(MethodAnalysis context, Instruction instr { readFromType = result.castTo; ReadFrom = result.original; - RegisterUsedLocal(ReadFrom); + RegisterUsedLocal(ReadFrom, context); } else if(readFrom is LocalDefinition {IsMethodInfoParam: false} l && l.Type?.Resolve() != null) { ReadFrom = l; readFromType = ReadFrom!.Type!; - RegisterUsedLocal(ReadFrom); + RegisterUsedLocal(ReadFrom, context); } else { AddComment($"This shouldn't be a field read? Op in reg {sourceRegName} is {context.GetOperandInRegister(sourceRegName)}, offset is {sourceFieldOffset} (0x{sourceFieldOffset:X})"); diff --git a/Cpp2IL.Core/Analysis/Actions/x86/Important/ImmediateToFieldAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/Important/ImmediateToFieldAction.cs index 24c5d8e2..b2cb1d7c 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/Important/ImmediateToFieldAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/Important/ImmediateToFieldAction.cs @@ -23,7 +23,7 @@ public ImmediateToFieldAction(MethodAnalysis context, Instruction i if(InstanceBeingSetOn?.Type?.Resolve() == null) return; - RegisterUsedLocal(InstanceBeingSetOn); + RegisterUsedLocal(InstanceBeingSetOn, context); FieldWritten = FieldUtils.GetFieldBeingAccessed(InstanceBeingSetOn.Type, destFieldOffset, false); diff --git a/Cpp2IL.Core/Analysis/Actions/x86/Important/Implicit4ByteFieldReadAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/Important/Implicit4ByteFieldReadAction.cs index 387fd1ad..09598f06 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/Important/Implicit4ByteFieldReadAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/Important/Implicit4ByteFieldReadAction.cs @@ -20,7 +20,7 @@ public Implicit4ByteFieldReadAction(MethodAnalysis context, Instruc if(_readOn == null) return; - RegisterUsedLocal(_readOn); + RegisterUsedLocal(_readOn, context); _read = FieldUtils.GetFieldBeingAccessed(_readOn.Type!, 0, false); if(_read == null) diff --git a/Cpp2IL.Core/Analysis/Actions/x86/Important/RegOffsetArrayValueReadRegToRegAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/Important/RegOffsetArrayValueReadRegToRegAction.cs index c18ddc47..7d6d9a34 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/Important/RegOffsetArrayValueReadRegToRegAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/Important/RegOffsetArrayValueReadRegToRegAction.cs @@ -22,12 +22,12 @@ public RegOffsetArrayValueReadRegToRegAction(MethodAnalysis context if (_arrayLocal?.Type?.IsArray != true) return; - RegisterUsedLocal(_arrayLocal); + RegisterUsedLocal(_arrayLocal, context); _indexLocal = context.GetLocalInReg(indexReg); if(_indexLocal != null) - RegisterUsedLocal(_indexLocal); + RegisterUsedLocal(_indexLocal, context); //Regardless of if we have an index local, we can still work out the type of the array and make a local. //Resolve() turns array types into non-array types diff --git a/Cpp2IL.Core/Analysis/Actions/x86/Important/RegToConstantArrayOffsetAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/Important/RegToConstantArrayOffsetAction.cs index 00ade8cd..9e620646 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/Important/RegToConstantArrayOffsetAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/Important/RegToConstantArrayOffsetAction.cs @@ -30,10 +30,10 @@ public RegToConstantArrayOffsetAction(MethodAnalysis context, Instr _opRead = context.GetOperandInRegister(regRead); if(TheArray != null) - RegisterUsedLocal(TheArray); + RegisterUsedLocal(TheArray, context); if(_opRead is LocalDefinition l) - RegisterUsedLocal(l); + RegisterUsedLocal(l, context); } protected override int GetOffsetWritten() => (int)_offsetIdx; diff --git a/Cpp2IL.Core/Analysis/Actions/x86/Important/RegToFieldAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/Important/RegToFieldAction.cs index d648cc64..fe00dfe8 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/Important/RegToFieldAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/Important/RegToFieldAction.cs @@ -20,7 +20,7 @@ public RegToFieldAction(MethodAnalysis context, Instruction instruc InstanceBeingSetOn = context.GetLocalInReg(destRegName); if(ValueRead is LocalDefinition loc) - RegisterUsedLocal(loc); + RegisterUsedLocal(loc, context); if (ValueRead is ConstantDefinition { Value: StackPointer s }) { @@ -36,14 +36,14 @@ public RegToFieldAction(MethodAnalysis context, Instruction instruc if (context.GetConstantInReg(destRegName) is {Value: FieldPointer p}) { InstanceBeingSetOn = p.OnWhat; - RegisterUsedLocal(InstanceBeingSetOn); + RegisterUsedLocal(InstanceBeingSetOn, context); FieldWritten = p.Field; } return; } - RegisterUsedLocal(InstanceBeingSetOn); + RegisterUsedLocal(InstanceBeingSetOn, context); FieldWritten = FieldUtils.GetFieldBeingAccessed(InstanceBeingSetOn.Type, destFieldOffset, false); } @@ -56,8 +56,8 @@ internal RegToFieldAction(MethodAnalysis context, Instruction instr InstanceBeingSetOn = instanceWrittenOn; ValueRead = readFrom; - RegisterUsedLocal(InstanceBeingSetOn); - RegisterUsedLocal(readFrom); + RegisterUsedLocal(InstanceBeingSetOn, context); + RegisterUsedLocal(readFrom, context); } protected override string? GetValuePseudocode() => ValueRead?.GetPseudocodeRepresentation(); diff --git a/Cpp2IL.Core/Analysis/Actions/x86/Important/RegToStaticFieldAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/Important/RegToStaticFieldAction.cs index 7b72e9e2..1e13e3a3 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/Important/RegToStaticFieldAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/Important/RegToStaticFieldAction.cs @@ -16,7 +16,7 @@ public RegToStaticFieldAction(MethodAnalysis context, Instruction i return; if (_sourceOperand is LocalDefinition l) - RegisterUsedLocal(l); + RegisterUsedLocal(l, context); _theField = FieldUtils.GetStaticFieldByOffset(staticFieldsPtr, staticFieldOffset); } diff --git a/Cpp2IL.Core/Analysis/Actions/x86/Important/ReturnFromFunctionAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/Important/ReturnFromFunctionAction.cs index 0012ff40..d00f3550 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/Important/ReturnFromFunctionAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/Important/ReturnFromFunctionAction.cs @@ -12,7 +12,7 @@ public ReturnFromFunctionAction(MethodAnalysis context, Instruction returnValue = returnType.ShouldBeInFloatingPointRegister() ? context.GetOperandInRegister("xmm0") : context.GetOperandInRegister("rax"); if (returnValue is LocalDefinition l) - RegisterUsedLocal(l); + RegisterUsedLocal(l, context); } } } \ No newline at end of file diff --git a/Cpp2IL.Core/Analysis/Actions/x86/Important/SubtractRegFromRegAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/Important/SubtractRegFromRegAction.cs index 633ae0b8..ecdecc26 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/Important/SubtractRegFromRegAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/Important/SubtractRegFromRegAction.cs @@ -20,10 +20,10 @@ public SubtractRegFromRegAction(MethodAnalysis context, Instruction _secondOp = context.GetOperandInRegister(secondReg); if(_firstOp != null) - RegisterUsedLocal(_firstOp); + RegisterUsedLocal(_firstOp, context); if(_secondOp is LocalDefinition l) - RegisterUsedLocal(l); + RegisterUsedLocal(l, context); } public override Mono.Cecil.Cil.Instruction[] ToILInstructions(MethodAnalysis context, ILProcessor processor) diff --git a/Cpp2IL.Core/Analysis/Actions/x86/Important/ThreeOperandImulAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/Important/ThreeOperandImulAction.cs index 5cb53dc4..a1649a5d 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/Important/ThreeOperandImulAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/Important/ThreeOperandImulAction.cs @@ -42,9 +42,9 @@ public ThreeOperandImulAction(MethodAnalysis context, Instruction i } if(_argOne is LocalDefinition l1) - RegisterUsedLocal(l1); + RegisterUsedLocal(l1, context); if(_argTwo is LocalDefinition l2) - RegisterUsedLocal(l2); + RegisterUsedLocal(l2, context); _resultLocal = context.MakeLocal(Utils.Int64Reference, reg: _destReg); } diff --git a/Cpp2IL.Core/Analysis/Actions/x86/Important/ThrowAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/Important/ThrowAction.cs index 2fe7aeef..c02133f0 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/Important/ThrowAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/Important/ThrowAction.cs @@ -14,7 +14,7 @@ public ThrowAction(MethodAnalysis context, Instruction instruction) exceptionToThrow = context.GetOperandInRegister("rcx"); if(exceptionToThrow is LocalDefinition l) - RegisterUsedLocal(l); + RegisterUsedLocal(l, context); } public override Mono.Cecil.Cil.Instruction[] ToILInstructions(MethodAnalysis context, ILProcessor processor) diff --git a/Cpp2IL.Core/Analysis/Actions/x86/IntegerDivisionShiftStepAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/IntegerDivisionShiftStepAction.cs index e3259762..400b12a0 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/IntegerDivisionShiftStepAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/IntegerDivisionShiftStepAction.cs @@ -47,7 +47,7 @@ public IntegerDivisionShiftStepAction(MethodAnalysis context, Instr } _localMade = context.MakeLocal(Utils.UInt64Reference, reg: _regBeingShifted); - RegisterUsedLocal(_localMade); + RegisterUsedLocal(_localMade, context); } public override Mono.Cecil.Cil.Instruction[] ToILInstructions(MethodAnalysis context, ILProcessor processor) diff --git a/Cpp2IL.Core/Analysis/Actions/x86/LocalToStackOffsetAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/LocalToStackOffsetAction.cs index 9fc851e2..4c6e5fb3 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/LocalToStackOffsetAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/LocalToStackOffsetAction.cs @@ -21,7 +21,7 @@ public LocalToStackOffsetAction(MethodAnalysis context, Instruction return; context.StackStoredLocals[(int) _stackOffset] = _sourceLocal; - RegisterUsedLocal(_sourceLocal); + RegisterUsedLocal(_sourceLocal, context); } public override Mono.Cecil.Cil.Instruction[] ToILInstructions(MethodAnalysis context, ILProcessor processor) diff --git a/Cpp2IL.Core/Analysis/Actions/x86/PushRegisterAction.cs b/Cpp2IL.Core/Analysis/Actions/x86/PushRegisterAction.cs index 2d2590ff..7a4418db 100644 --- a/Cpp2IL.Core/Analysis/Actions/x86/PushRegisterAction.cs +++ b/Cpp2IL.Core/Analysis/Actions/x86/PushRegisterAction.cs @@ -21,7 +21,7 @@ public PushRegisterAction(MethodAnalysis context, Instruction instr context.PushEmptyStackFrames(1); if (whatIsPushed is LocalDefinition l) - RegisterUsedLocal(l); + RegisterUsedLocal(l, context); } public override Mono.Cecil.Cil.Instruction[] ToILInstructions(MethodAnalysis context, ILProcessor processor) diff --git a/Cpp2IL.Core/Analysis/AsmAnalyzerBase.cs b/Cpp2IL.Core/Analysis/AsmAnalyzerBase.cs index 3546ef32..7f59c473 100644 --- a/Cpp2IL.Core/Analysis/AsmAnalyzerBase.cs +++ b/Cpp2IL.Core/Analysis/AsmAnalyzerBase.cs @@ -29,12 +29,12 @@ internal AsmAnalyzerBase(ulong methodPointer, IEnumerable instructions, BaseK _keyFunctionAddresses = keyFunctionAddresses ?? throw new ArgumentNullException(nameof(keyFunctionAddresses)); _instructions = new(); CppAssembly = LibCpp2IlMain.Binary!; - + foreach (var instruction in instructions) { _instructions.Add(instruction); } - + Analysis = new(methodPointer, MethodEnd, _instructions); Analysis.OnExpansionRequested += AnalysisRequestedExpansion; @@ -175,6 +175,7 @@ public StringBuilder BuildILToString() success = false; break; } + builder.Append("\n\t"); } catch (TaintedInstructionException e) @@ -188,6 +189,7 @@ public StringBuilder BuildILToString() success = false; break; } + builder.Append("\n\t"); } catch (Exception e) @@ -201,6 +203,7 @@ public StringBuilder BuildILToString() success = false; break; } + builder.Append("\n\t"); } } diff --git a/Cpp2IL.Core/Analysis/AsmAnalyzerX86.cs b/Cpp2IL.Core/Analysis/AsmAnalyzerX86.cs index bbf99a9b..cb6b4def 100644 --- a/Cpp2IL.Core/Analysis/AsmAnalyzerX86.cs +++ b/Cpp2IL.Core/Analysis/AsmAnalyzerX86.cs @@ -21,14 +21,10 @@ internal partial class AsmAnalyzerX86 : AsmAnalyzerBase Mnemonic.Add, Mnemonic.Sub }; - internal AsmAnalyzerX86(ulong methodPointer, InstructionList instructions, BaseKeyFunctionAddresses keyFunctionAddresses) : base(methodPointer, instructions, keyFunctionAddresses) - { - } + internal AsmAnalyzerX86(ulong methodPointer, InstructionList instructions, BaseKeyFunctionAddresses keyFunctionAddresses) : base(methodPointer, instructions, keyFunctionAddresses) { } internal AsmAnalyzerX86(MethodDefinition methodDefinition, ulong methodStart, BaseKeyFunctionAddresses keyFunctionAddresses) - : base(methodDefinition, methodStart, LibCpp2ILUtils.DisassembleBytesNew(LibCpp2IlMain.Binary!.is32Bit, methodDefinition.AsUnmanaged().CppMethodBodyBytes, methodStart), keyFunctionAddresses) - { - } + : base(methodDefinition, methodStart, LibCpp2ILUtils.DisassembleBytesNew(LibCpp2IlMain.Binary!.is32Bit, methodDefinition.AsUnmanaged().CppMethodBodyBytes, methodStart), keyFunctionAddresses) { } protected override void AnalysisRequestedExpansion(ulong ptr) { @@ -45,13 +41,20 @@ protected override bool FindInstructionWhichOverran(out int idx) foreach (var i in _instructions.Skip(1)) { idx++; - if (SharedState.MethodsByAddress.ContainsKey(i.IP) || LibCpp2IlMain.Binary!.AllCustomAttributeGenerators.Contains(i.IP)) + + if (i.Code == Code.Int3) { return true; } - if (i.Code == Code.Int3) + if (MethodDefinition != null && SharedState.MethodsByAddress.ContainsKey(i.IP)) + { + //Have method def - so are managed method - and hit another one here. + return true; + } + if (MethodDefinition == null && SharedState.AttributeGeneratorStarts.Contains(i.IP)) { + //We have no method def - so are an attrib gen - and another attrib gen here. return true; } } diff --git a/Cpp2IL.Core/Analysis/PostProcessActions/0RemovedUnusedLocalsPostProcessor.cs b/Cpp2IL.Core/Analysis/PostProcessActions/0RemovedUnusedLocalsPostProcessor.cs index 28e84414..6b3d540c 100644 --- a/Cpp2IL.Core/Analysis/PostProcessActions/0RemovedUnusedLocalsPostProcessor.cs +++ b/Cpp2IL.Core/Analysis/PostProcessActions/0RemovedUnusedLocalsPostProcessor.cs @@ -1,6 +1,8 @@ // #define PRINT_UNUSED_LOCAL_DATA +using System.Collections.Generic; using System.Linq; +using Cpp2IL.Core.Analysis.Actions.Base; using Cpp2IL.Core.Analysis.ResultModels; namespace Cpp2IL.Core.Analysis.PostProcessActions @@ -9,20 +11,23 @@ public class RemovedUnusedLocalsPostProcessor : PostProcessor { public override void PostProcess(MethodAnalysis analysis) { - var unused = analysis.Locals.Where(l => !analysis.FunctionArgumentLocals.Contains(l) && analysis.Actions.All(a => !a.GetUsedLocals().Contains(l))).ToList(); + var unused = analysis.UnusedLocals; #if PRINT_UNUSED_LOCAL_DATA Console.WriteLine($"Found {unused.Count} unused locals for method {definition}: "); #endif + var toRemove = new List>(); foreach (var unusedLocal in unused) { -#if PRINT_UNUSED_LOCAL_DATA - Console.WriteLine($"\t{unusedLocal.Name}"); -#endif - analysis.Actions = analysis.Actions.Where(a => !a.GetRegisteredLocalsWithoutSideEffects().Contains(unusedLocal)).ToList(); + foreach (var analysisAction in analysis.Actions) + { + if(analysisAction.GetRegisteredLocalsWithoutSideEffects().Contains(unusedLocal)) + toRemove.Add(analysisAction); + } } - - analysis.Locals.RemoveAll(l => unused.Contains(l)); + + toRemove.ForEach(a => analysis.Actions.Remove(a)); + unused.ForEach(l => analysis.Locals.Remove(l)); } } } \ No newline at end of file diff --git a/Cpp2IL.Core/Analysis/ResultModels/MethodAnalysis.cs b/Cpp2IL.Core/Analysis/ResultModels/MethodAnalysis.cs index 2e0862ae..a2281323 100644 --- a/Cpp2IL.Core/Analysis/ResultModels/MethodAnalysis.cs +++ b/Cpp2IL.Core/Analysis/ResultModels/MethodAnalysis.cs @@ -17,6 +17,7 @@ public class MethodAnalysis { public delegate void PtrConsumer(ulong ptr); + public readonly List UnusedLocals = new(); public readonly List Locals = new(); public readonly List Constants = new(); public List> Actions = new(); @@ -296,6 +297,7 @@ public LocalDefinition MakeLocal(TypeReference type, string? name = null, string }; Locals.Add(local); + UnusedLocals.Add(local); if (reg != null) RegisterData[reg] = local; diff --git a/Cpp2IL.Core/Cpp2IlApi.cs b/Cpp2IL.Core/Cpp2IlApi.cs index 4d02bbac..f31ddaf5 100644 --- a/Cpp2IL.Core/Cpp2IlApi.cs +++ b/Cpp2IL.Core/Cpp2IlApi.cs @@ -219,6 +219,8 @@ public static void RunAttributeRestorationForAllAssemblies(BaseKeyFunctionAddres { CheckLibInitialized(); + SharedState.AttributeGeneratorStarts = LibCpp2IlMain.Binary!.AllCustomAttributeGenerators.ToList(); + var enumerable = (IEnumerable) SharedState.AssemblyList; if (parallel) diff --git a/Cpp2IL.Core/SharedState.cs b/Cpp2IL.Core/SharedState.cs index 05317576..872deba4 100644 --- a/Cpp2IL.Core/SharedState.cs +++ b/Cpp2IL.Core/SharedState.cs @@ -39,6 +39,8 @@ public static class SharedState //Assemblies internal static readonly List AssemblyList = new List(); internal static readonly Dictionary ManagedToUnmanagedAssemblies = new Dictionary(); + + internal static List AttributeGeneratorStarts = new(); internal static void Clear() { @@ -66,6 +68,8 @@ internal static void Clear() AssemblyList.Clear(); ManagedToUnmanagedAssemblies.Clear(); + + AttributeGeneratorStarts.Clear(); } } } \ No newline at end of file