private void OptimizeLocalVariables(ref int localVarNumber) { List <List <VariableLifetimeCycle> > localVariablesLifeCycles = new List <List <VariableLifetimeCycle> >(localVarNumber); for (int i = 0; i < localVarNumber; i++) { localVariablesLifeCycles.Add(new List <VariableLifetimeCycle>()); } for (int i = 0; i < IlInstructions.Count; i++) { if (IlInstructions[i].OpCode == OpCodes.Stloc) { localVariablesLifeCycles[(int)IlInstructions[i].Arg].Add(new VariableLifetimeCycle(i, i)); } else if (IlInstructions[i].OpCode == OpCodes.Ldloc) { var cycles = localVariablesLifeCycles[(int)IlInstructions[i].Arg]; cycles[cycles.Count - 1] = new VariableLifetimeCycle(cycles[cycles.Count - 1].BeginInd, i); } } for (int i = 1; i < localVariablesLifeCycles.Count; i++) { for (int k = 0; k < i; k++) { for (int j = 0; j < localVariablesLifeCycles[i].Count; j++) { if (!IsIntersect(localVariablesLifeCycles[i][j], localVariablesLifeCycles[k])) { IlInstructions[localVariablesLifeCycles[i][j].BeginInd] = new OpCodeArg(OpCodes.Stloc, k); for (int l = localVariablesLifeCycles[i][j].BeginInd + 1; l <= localVariablesLifeCycles[i][j].EndInd; l++) { if (IlInstructions[l].OpCode == OpCodes.Ldloc && (int)IlInstructions[l].Arg == i) { IlInstructions[l] = new OpCodeArg(OpCodes.Ldloc, k); } } localVariablesLifeCycles[k].Add(localVariablesLifeCycles[i][j]); localVariablesLifeCycles[i].RemoveAt(j); } } } } for (int i = localVariablesLifeCycles.Count - 1; i >= 0; i--) { if (localVariablesLifeCycles[i].Count == 0) { localVariablesLifeCycles.RemoveAt(i); } else { break; } } localVarNumber = localVariablesLifeCycles.Count; }
private static void EmitInstruction(ILProcessor ilProcessor, OpCodeArg instr, bool staticFunc) { if (instr.Arg == null) { ilProcessor.Emit(instr.OpCode); } else if (instr.Arg is int) { if (instr.OpCode == OpCodes.Ldarg) { EmitArgLoad(ilProcessor, (int)instr.Arg + (staticFunc ? 0 : 1)); } else if (instr.OpCode == OpCodes.Ldloc) { EmitLocalLoad(ilProcessor, (int)instr.Arg); } else if (instr.OpCode == OpCodes.Stloc) { EmitLocalSave(ilProcessor, (int)instr.Arg); } else { ilProcessor.Emit(instr.OpCode, (int)instr.Arg); } } else if (instr.Arg is double) { ilProcessor.Emit(instr.OpCode, (double)instr.Arg); } else if (instr.Arg is float) { ilProcessor.Emit(instr.OpCode, (float)instr.Arg); } else if (instr.Arg is string) { ilProcessor.Emit(instr.OpCode, (string)instr.Arg); } else if (instr.Arg is byte) { ilProcessor.Emit(instr.OpCode, (byte)instr.Arg); } else if (instr.Arg is sbyte) { ilProcessor.Emit(instr.OpCode, (sbyte)instr.Arg); } else if (instr.Arg is CallSite) { ilProcessor.Emit(instr.OpCode, (CallSite)instr.Arg); } else if (instr.Arg is FieldReference) { ilProcessor.Emit(instr.OpCode, (FieldReference)instr.Arg); } else if (instr.Arg is Instruction) { ilProcessor.Emit(instr.OpCode, (Instruction)instr.Arg); } else if (instr.Arg is Instruction[]) { ilProcessor.Emit(instr.OpCode, (Instruction[])instr.Arg); } else if (instr.Arg is MethodReference) { ilProcessor.Emit(instr.OpCode, (MethodReference)instr.Arg); } else if (instr.Arg is ParameterDefinition) { ilProcessor.Emit(instr.OpCode, (ParameterDefinition)instr.Arg); } else if (instr.Arg is TypeReference) { ilProcessor.Emit(instr.OpCode, (TypeReference)instr.Arg); } else if (instr.Arg is VariableDefinition) { ilProcessor.Emit(instr.OpCode, (VariableDefinition)instr.Arg); } }
private void OptimizeInstructions() { int i = 0; while (i < IlInstructions.Count) { if (i < IlInstructions.Count - 1) { var firstOpCode = IlInstructions[i].OpCode; if ((firstOpCode == OpCodes.Ldarg || firstOpCode == OpCodes.Ldc_R8) && IlInstructions[i + 1].OpCode == OpCodes.Stloc) { var locNumber = (int)IlInstructions[i + 1].Arg; for (int j = i + 2; j < IlInstructions.Count; j++) { if ((IlInstructions[j].OpCode == OpCodes.Stloc) && (int)IlInstructions[j].Arg == locNumber) { break; } if ((IlInstructions[j].OpCode == OpCodes.Ldloc) && (int)IlInstructions[j].Arg == locNumber) { IlInstructions[j] = new OpCodeArg(firstOpCode, IlInstructions[i].Arg); } } IlInstructions.RemoveRange(i, 2); continue; } if (firstOpCode == OpCodes.Ldloc && IlInstructions[i + 1].OpCode == OpCodes.Stloc) { if ((int)IlInstructions[i].Arg == (int)IlInstructions[i + 1].Arg) { IlInstructions.RemoveRange(i, 2); continue; } else { var locNumber1 = (int)IlInstructions[i].Arg; var locNumber2 = (int)IlInstructions[i + 1].Arg; bool arg2IsUsed = false; for (int j = i + 2; j < IlInstructions.Count; j++) { if ((IlInstructions[j].OpCode == OpCodes.Stloc) && (int)IlInstructions[j].Arg == locNumber1) { break; } if ((IlInstructions[j].OpCode == OpCodes.Stloc) && (int)IlInstructions[j].Arg == locNumber2) { break; } if ((IlInstructions[j].OpCode == OpCodes.Ldloc) && (int)IlInstructions[j].Arg == locNumber2) { IlInstructions[j] = new OpCodeArg(OpCodes.Ldloc, locNumber1); arg2IsUsed = true; } } if (arg2IsUsed) { IlInstructions.RemoveRange(i, 2); continue; } } } if (firstOpCode == OpCodes.Stloc && IlInstructions[i + 1].OpCode == OpCodes.Ldloc && (int)IlInstructions[i].Arg == (int)IlInstructions[i + 1].Arg) { var locNumber = (int)IlInstructions[i].Arg; bool remove = true; for (int j = i + 2; j < IlInstructions.Count; j++) { if ((IlInstructions[j].OpCode == OpCodes.Ldloc) && (int)IlInstructions[j].Arg == locNumber) { remove = false; break; } } if (remove) { IlInstructions.RemoveRange(i, 2); continue; } } } i++; } }
private static void EmitInstruction(ILProcessor ilProcessor, OpCodeArg instr, bool staticFunc) { if (instr.Arg == null) ilProcessor.Emit(instr.OpCode); else if (instr.Arg is int) { if (instr.OpCode == OpCodes.Ldarg) EmitArgLoad(ilProcessor, (int)instr.Arg + (staticFunc ? 0 : 1)); else if (instr.OpCode == OpCodes.Ldloc) EmitLocalLoad(ilProcessor, (int)instr.Arg); else if (instr.OpCode == OpCodes.Stloc) EmitLocalSave(ilProcessor, (int)instr.Arg); else ilProcessor.Emit(instr.OpCode, (int)instr.Arg); } else if (instr.Arg is double) ilProcessor.Emit(instr.OpCode, (double)instr.Arg); else if (instr.Arg is float) ilProcessor.Emit(instr.OpCode, (float)instr.Arg); else if (instr.Arg is string) ilProcessor.Emit(instr.OpCode, (string)instr.Arg); else if (instr.Arg is byte) ilProcessor.Emit(instr.OpCode, (byte)instr.Arg); else if (instr.Arg is sbyte) ilProcessor.Emit(instr.OpCode, (sbyte)instr.Arg); else if (instr.Arg is CallSite) ilProcessor.Emit(instr.OpCode, (CallSite)instr.Arg); else if (instr.Arg is FieldReference) ilProcessor.Emit(instr.OpCode, (FieldReference)instr.Arg); else if (instr.Arg is Instruction) ilProcessor.Emit(instr.OpCode, (Instruction)instr.Arg); else if (instr.Arg is Instruction[]) ilProcessor.Emit(instr.OpCode, (Instruction[])instr.Arg); else if (instr.Arg is MethodReference) ilProcessor.Emit(instr.OpCode, (MethodReference)instr.Arg); else if (instr.Arg is ParameterDefinition) ilProcessor.Emit(instr.OpCode, (ParameterDefinition)instr.Arg); else if (instr.Arg is TypeReference) ilProcessor.Emit(instr.OpCode, (TypeReference)instr.Arg); else if (instr.Arg is VariableDefinition) ilProcessor.Emit(instr.OpCode, (VariableDefinition)instr.Arg); }
private void OptimizeInstructions() { int i = 0; while (i < IlInstructions.Count) { if (i < IlInstructions.Count - 1) { var firstOpCode = IlInstructions[i].OpCode; if ((firstOpCode == OpCodes.Ldarg || firstOpCode == OpCodes.Ldc_R8) && IlInstructions[i + 1].OpCode == OpCodes.Stloc) { var locNumber = (int)IlInstructions[i + 1].Arg; for (int j = i + 2; j < IlInstructions.Count; j++) { if ((IlInstructions[j].OpCode == OpCodes.Stloc) && (int)IlInstructions[j].Arg == locNumber) break; if ((IlInstructions[j].OpCode == OpCodes.Ldloc) && (int)IlInstructions[j].Arg == locNumber) IlInstructions[j] = new OpCodeArg(firstOpCode, IlInstructions[i].Arg); } IlInstructions.RemoveRange(i, 2); continue; } if (firstOpCode == OpCodes.Ldloc && IlInstructions[i + 1].OpCode == OpCodes.Stloc) { if ((int)IlInstructions[i].Arg == (int)IlInstructions[i + 1].Arg) { IlInstructions.RemoveRange(i, 2); continue; } else { var locNumber1 = (int)IlInstructions[i].Arg; var locNumber2 = (int)IlInstructions[i + 1].Arg; bool arg2IsUsed = false; for (int j = i + 2; j < IlInstructions.Count; j++) { if ((IlInstructions[j].OpCode == OpCodes.Stloc) && (int)IlInstructions[j].Arg == locNumber1) break; if ((IlInstructions[j].OpCode == OpCodes.Stloc) && (int)IlInstructions[j].Arg == locNumber2) break; if ((IlInstructions[j].OpCode == OpCodes.Ldloc) && (int)IlInstructions[j].Arg == locNumber2) { IlInstructions[j] = new OpCodeArg(OpCodes.Ldloc, locNumber1); arg2IsUsed = true; } } if (arg2IsUsed) { IlInstructions.RemoveRange(i, 2); continue; } } } if (firstOpCode == OpCodes.Stloc && IlInstructions[i + 1].OpCode == OpCodes.Ldloc && (int)IlInstructions[i].Arg == (int)IlInstructions[i + 1].Arg) { var locNumber = (int)IlInstructions[i].Arg; bool remove = true; for (int j = i + 2; j < IlInstructions.Count; j++) if ((IlInstructions[j].OpCode == OpCodes.Ldloc) && (int)IlInstructions[j].Arg == locNumber) { remove = false; break; } if (remove) { IlInstructions.RemoveRange(i, 2); continue; } } } i++; } }
private void OptimizeLocalVariables(ref int localVarNumber) { List<List<VariableLifetimeCycle>> localVariablesLifeCycles = new List<List<VariableLifetimeCycle>>(localVarNumber); for (int i = 0; i < localVarNumber; i++) localVariablesLifeCycles.Add(new List<VariableLifetimeCycle>()); for (int i = 0; i < IlInstructions.Count; i++) if (IlInstructions[i].OpCode == OpCodes.Stloc) localVariablesLifeCycles[(int)IlInstructions[i].Arg].Add(new VariableLifetimeCycle(i, i)); else if (IlInstructions[i].OpCode == OpCodes.Ldloc) { var cycles = localVariablesLifeCycles[(int)IlInstructions[i].Arg]; cycles[cycles.Count - 1] = new VariableLifetimeCycle(cycles[cycles.Count - 1].BeginInd, i); } for (int i = 1; i < localVariablesLifeCycles.Count; i++) for (int k = 0; k < i; k++) for (int j = 0; j < localVariablesLifeCycles[i].Count; j++) if (!IsIntersect(localVariablesLifeCycles[i][j], localVariablesLifeCycles[k])) { IlInstructions[localVariablesLifeCycles[i][j].BeginInd] = new OpCodeArg(OpCodes.Stloc, k); for (int l = localVariablesLifeCycles[i][j].BeginInd + 1; l <= localVariablesLifeCycles[i][j].EndInd; l++) if (IlInstructions[l].OpCode == OpCodes.Ldloc && (int)IlInstructions[l].Arg == i) IlInstructions[l] = new OpCodeArg(OpCodes.Ldloc, k); localVariablesLifeCycles[k].Add(localVariablesLifeCycles[i][j]); localVariablesLifeCycles[i].RemoveAt(j); } for (int i = localVariablesLifeCycles.Count - 1; i >= 0; i--) if (localVariablesLifeCycles[i].Count == 0) localVariablesLifeCycles.RemoveAt(i); else break; localVarNumber = localVariablesLifeCycles.Count; }