Author: jbevain
Date: 2007-10-18 19:25:32 -0400 (Thu, 18 Oct 2007)
New Revision: 87804

Modified:
   trunk/mcs/class/Mono.Cecil/ChangeLog
   trunk/mcs/class/Mono.Cecil/Mono.Cecil.Cil/MethodBody.cs
   trunk/mcs/class/Mono.Cecil/Mono.Cecil/AssemblyInfo.cs
Log:
2007-10-18  Jb Evain  <[EMAIL PROTECTED]>

        * Mono.Cecil.Cil/MethodBody.cs: Add an Optimize method which
        is the opposite of Simplify. Based on a patch by Carlo.


Modified: trunk/mcs/class/Mono.Cecil/ChangeLog
===================================================================
--- trunk/mcs/class/Mono.Cecil/ChangeLog        2007-10-18 22:22:34 UTC (rev 
87803)
+++ trunk/mcs/class/Mono.Cecil/ChangeLog        2007-10-18 23:25:32 UTC (rev 
87804)
@@ -1,5 +1,8 @@
 2007-10-18  Jb Evain  <[EMAIL PROTECTED]>
 
+       * Mono.Cecil.Cil/MethodBody.cs: Add an Optimize method which
+       is the opposite of Simplify. Based on a patch by Carlo.
+
        * Mono.Cecil.Cil/CodeWriter.cs: don't care about reducing MaxStack.
 
 2007-10-11  Jb Evain  <[EMAIL PROTECTED]>

Modified: trunk/mcs/class/Mono.Cecil/Mono.Cecil/AssemblyInfo.cs
===================================================================
--- trunk/mcs/class/Mono.Cecil/Mono.Cecil/AssemblyInfo.cs       2007-10-18 
22:22:34 UTC (rev 87803)
+++ trunk/mcs/class/Mono.Cecil/Mono.Cecil/AssemblyInfo.cs       2007-10-18 
23:25:32 UTC (rev 87804)
@@ -43,7 +43,7 @@
 [assembly: CLSCompliant (false)]
 [assembly: ComVisible (false)]
 
-[assembly: AssemblyVersion ("0.6.8.7798")]
+[assembly: AssemblyVersion ("0.6.8.7804")]
 
 #if KEYFILE
 [assembly: AssemblyKeyFile("../../mono.snk")]

Modified: trunk/mcs/class/Mono.Cecil/Mono.Cecil.Cil/MethodBody.cs
===================================================================
--- trunk/mcs/class/Mono.Cecil/Mono.Cecil.Cil/MethodBody.cs     2007-10-18 
22:22:34 UTC (rev 87803)
+++ trunk/mcs/class/Mono.Cecil/Mono.Cecil.Cil/MethodBody.cs     2007-10-18 
23:25:32 UTC (rev 87804)
@@ -201,7 +201,7 @@
                        return nb;
                }
 
-               public void Simplify ()
+               public void Modify ()
                {
                        foreach (Instruction i in this.Instructions) {
                                if (i.OpCode.OpCodeType != OpCodeType.Macro)
@@ -209,51 +209,51 @@
 
                                switch (i.OpCode.Code) {
                                case Code.Ldarg_0 :
-                                       Simplify (i, OpCodes.Ldarg,
+                                       Modify (i, OpCodes.Ldarg,
                                                CodeReader.GetParameter (this, 
0));
                                        break;
                                case Code.Ldarg_1 :
-                                       Simplify (i, OpCodes.Ldarg,
+                                       Modify (i, OpCodes.Ldarg,
                                                CodeReader.GetParameter (this, 
1));
                                        break;
                                case Code.Ldarg_2 :
-                                       Simplify (i, OpCodes.Ldarg,
+                                       Modify (i, OpCodes.Ldarg,
                                                CodeReader.GetParameter (this, 
2));
                                        break;
                                case Code.Ldarg_3 :
-                                       Simplify (i, OpCodes.Ldarg,
+                                       Modify (i, OpCodes.Ldarg,
                                                CodeReader.GetParameter (this, 
3));
                                        break;
                                case Code.Ldloc_0 :
-                                       Simplify (i, OpCodes.Ldloc,
+                                       Modify (i, OpCodes.Ldloc,
                                                CodeReader.GetVariable (this, 
0));
                                        break;
                                case Code.Ldloc_1 :
-                                       Simplify (i, OpCodes.Ldloc,
+                                       Modify (i, OpCodes.Ldloc,
                                                CodeReader.GetVariable (this, 
1));
                                        break;
                                case Code.Ldloc_2 :
-                                       Simplify (i, OpCodes.Ldloc,
+                                       Modify (i, OpCodes.Ldloc,
                                                CodeReader.GetVariable (this, 
2));
                                        break;
                                case Code.Ldloc_3 :
-                                       Simplify (i, OpCodes.Ldloc,
+                                       Modify (i, OpCodes.Ldloc,
                                                CodeReader.GetVariable (this, 
3));
                                        break;
                                case Code.Stloc_0 :
-                                       Simplify (i, OpCodes.Stloc,
+                                       Modify (i, OpCodes.Stloc,
                                                CodeReader.GetVariable (this, 
0));
                                        break;
                                case Code.Stloc_1 :
-                                       Simplify (i, OpCodes.Stloc,
+                                       Modify (i, OpCodes.Stloc,
                                                CodeReader.GetVariable (this, 
1));
                                        break;
                                case Code.Stloc_2 :
-                                       Simplify (i, OpCodes.Stloc,
+                                       Modify (i, OpCodes.Stloc,
                                                CodeReader.GetVariable (this, 
2));
                                        break;
                                case Code.Stloc_3 :
-                                       Simplify (i, OpCodes.Stloc,
+                                       Modify (i, OpCodes.Stloc,
                                                CodeReader.GetVariable (this, 
3));
                                        break;
                                case Code.Ldarg_S :
@@ -275,34 +275,34 @@
                                        i.OpCode = OpCodes.Stloc;
                                        break;
                                case Code.Ldc_I4_M1 :
-                                       Simplify (i, OpCodes.Ldc_I4, -1);
+                                       Modify (i, OpCodes.Ldc_I4, -1);
                                        break;
                                case Code.Ldc_I4_0 :
-                                       Simplify (i, OpCodes.Ldc_I4, 0);
+                                       Modify (i, OpCodes.Ldc_I4, 0);
                                        break;
                                case Code.Ldc_I4_1 :
-                                       Simplify (i, OpCodes.Ldc_I4, 1);
+                                       Modify (i, OpCodes.Ldc_I4, 1);
                                        break;
                                case Code.Ldc_I4_2 :
-                                       Simplify (i, OpCodes.Ldc_I4, 2);
+                                       Modify (i, OpCodes.Ldc_I4, 2);
                                        break;
                                case Code.Ldc_I4_3 :
-                                       Simplify (i, OpCodes.Ldc_I4, 3);
+                                       Modify (i, OpCodes.Ldc_I4, 3);
                                        break;
                                case Code.Ldc_I4_4 :
-                                       Simplify (i, OpCodes.Ldc_I4, 4);
+                                       Modify (i, OpCodes.Ldc_I4, 4);
                                        break;
                                case Code.Ldc_I4_5 :
-                                       Simplify (i, OpCodes.Ldc_I4, 5);
+                                       Modify (i, OpCodes.Ldc_I4, 5);
                                        break;
                                case Code.Ldc_I4_6 :
-                                       Simplify (i, OpCodes.Ldc_I4, 6);
+                                       Modify (i, OpCodes.Ldc_I4, 6);
                                        break;
                                case Code.Ldc_I4_7 :
-                                       Simplify (i, OpCodes.Ldc_I4, 7);
+                                       Modify (i, OpCodes.Ldc_I4, 7);
                                        break;
                                case Code.Ldc_I4_8 :
-                                       Simplify (i, OpCodes.Ldc_I4, 8);
+                                       Modify (i, OpCodes.Ldc_I4, 8);
                                        break;
                                case Code.Ldc_I4_S :
                                        i.OpCode = OpCodes.Ldc_I4;
@@ -354,8 +354,216 @@
                        }
                }
 
-               static void Simplify (Instruction i, OpCode op, object operand)
+               public void Optimize ()
                {
+                       foreach (Instruction instr in m_instructions) {
+                               int index;
+                               switch (instr.OpCode.Code) {
+                               case Code.Ldarg:
+                                       index = m_method.Parameters.IndexOf 
((ParameterDefinition) instr.Operand);
+                                       if (index == -1 && instr.Operand == 
m_method.This)
+                                               index = 0;
+                                       else if (m_method.HasThis)
+                                               index++;
+
+                                       switch (index) {
+                                       case 0:
+                                               Modify (instr, OpCodes.Ldarg_0, 
null);
+                                               break;
+                                       case 1:
+                                               Modify (instr, OpCodes.Ldarg_1, 
null);
+                                               break;
+                                       case 2:
+                                               Modify (instr, OpCodes.Ldarg_2, 
null);
+                                               break;
+                                       case 3:
+                                               Modify (instr, OpCodes.Ldarg_3, 
null);
+                                               break;
+                                       default:
+                                               if (index < 256)
+                                                       Modify (instr, 
OpCodes.Ldarg_S, instr.Operand);
+                                               break;
+                                       }
+                                       break;
+                               case Code.Ldloc:
+                                       index = m_variables.IndexOf 
((VariableDefinition) instr.Operand);
+                                       switch (index) {
+                                       case 0:
+                                               Modify (instr, OpCodes.Ldloc_0, 
null);
+                                               break;
+                                       case 1:
+                                               Modify (instr, OpCodes.Ldloc_1, 
null);
+                                               break;
+                                       case 2:
+                                               Modify (instr, OpCodes.Ldloc_2, 
null);
+                                               break;
+                                       case 3:
+                                               Modify (instr, OpCodes.Ldloc_3, 
null);
+                                               break;
+                                       default:
+                                               if (index < 256)
+                                                       Modify (instr, 
OpCodes.Ldloc_S, instr.Operand);
+                                               break;
+                                       }
+                                       break;
+                               case Code.Stloc:
+                                       index = m_variables.IndexOf 
((VariableDefinition) instr.Operand);
+                                       switch (index) {
+                                       case 0:
+                                               Modify (instr, OpCodes.Stloc_0, 
null);
+                                               break;
+                                       case 1:
+                                               Modify (instr, OpCodes.Stloc_1, 
null);
+                                               break;
+                                       case 2:
+                                               Modify (instr, OpCodes.Stloc_2, 
null);
+                                               break;
+                                       case 3:
+                                               Modify (instr, OpCodes.Stloc_3, 
null);
+                                               break;
+                                       default:
+                                               if (index < 256)
+                                                       Modify (instr, 
OpCodes.Stloc_S, instr.Operand);
+                                               break;
+                                       }
+                                       break;
+                               case Code.Ldarga:
+                                       index = m_method.Parameters.IndexOf 
((ParameterDefinition) instr.Operand);
+                                       if (index == -1 && instr.Operand == 
m_method.This)
+                                               index = 0;
+                                       else if (m_method.HasThis)
+                                               index++;
+                                       if (index < 256)
+                                               Modify (instr, 
OpCodes.Ldarga_S, instr.Operand);
+                                       break;
+                               case Code.Ldloca:
+                                       if (m_variables.IndexOf 
((VariableDefinition) instr.Operand) < 256)
+                                               Modify (instr, 
OpCodes.Ldloca_S, instr.Operand);
+                                       break;
+                               case Code.Ldc_I4:
+                                       int i = (int) instr.Operand;
+                                       switch (i) {
+                                       case -1:
+                                               Modify (instr, 
OpCodes.Ldc_I4_M1, null);
+                                               break;
+                                       case 0:
+                                               Modify (instr, 
OpCodes.Ldc_I4_0, null);
+                                               break;
+                                       case 1:
+                                               Modify (instr, 
OpCodes.Ldc_I4_1, null);
+                                               break;
+                                       case 2:
+                                               Modify (instr, 
OpCodes.Ldc_I4_2, null);
+                                               break;
+                                       case 3:
+                                               Modify (instr, 
OpCodes.Ldc_I4_3, null);
+                                               break;
+                                       case 4:
+                                               Modify (instr, 
OpCodes.Ldc_I4_4, null);
+                                               break;
+                                       case 5:
+                                               Modify (instr, 
OpCodes.Ldc_I4_5, null);
+                                               break;
+                                       case 6:
+                                               Modify (instr, 
OpCodes.Ldc_I4_6, null);
+                                               break;
+                                       case 7:
+                                               Modify (instr, 
OpCodes.Ldc_I4_7, null);
+                                               break;
+                                       case 8:
+                                               Modify (instr, 
OpCodes.Ldc_I4_8, null);
+                                               break;
+                                       default:
+                                               if (i >= -128 || i < 128)
+                                                       Modify (instr, 
OpCodes.Ldc_I4_S, (sbyte) i);
+                                               break;
+                                       }
+                                       break;
+                               }
+                       }
+
+                       OptimizeBranches ();
+               }
+
+               void OptimizeBranches ()
+               {
+                       ComputeOffsets ();
+
+                       foreach (Instruction instr in m_instructions) {
+                               if (instr.OpCode.OperandType != 
OperandType.InlineBrTarget)
+                                       continue;
+
+                               if (OptimizeBranch (instr))
+                                       ComputeOffsets ();
+                       }
+               }
+
+               static bool OptimizeBranch (Instruction instr)
+               {
+                       int offset = ((Instruction) instr.Operand).Offset - 
(instr.Offset + instr.OpCode.Size + 4);
+                       if (! (offset >= -128 && offset <= 127))
+                               return false;
+
+                       switch (instr.OpCode.Code) {
+                       case Code.Br:
+                               instr.OpCode = OpCodes.Br_S;
+                               break;
+                       case Code.Brfalse:
+                               instr.OpCode = OpCodes.Brfalse_S;
+                               break;
+                       case Code.Brtrue:
+                               instr.OpCode = OpCodes.Brtrue_S;
+                               break;
+                       case Code.Beq:
+                               instr.OpCode = OpCodes.Beq_S;
+                               break;
+                       case Code.Bge:
+                               instr.OpCode = OpCodes.Bge_S;
+                               break;
+                       case Code.Bgt:
+                               instr.OpCode = OpCodes.Bgt_S;
+                               break;
+                       case Code.Ble:
+                               instr.OpCode = OpCodes.Ble_S;
+                               break;
+                       case Code.Blt:
+                               instr.OpCode = OpCodes.Blt_S;
+                               break;
+                       case Code.Bne_Un:
+                               instr.OpCode = OpCodes.Bne_Un_S;
+                               break;
+                       case Code.Bge_Un:
+                               instr.OpCode = OpCodes.Bge_Un_S;
+                               break;
+                       case Code.Bgt_Un:
+                               instr.OpCode = OpCodes.Bgt_Un_S;
+                               break;
+                       case Code.Ble_Un:
+                               instr.OpCode = OpCodes.Ble_Un_S;
+                               break;
+                       case Code.Blt_Un:
+                               instr.OpCode = OpCodes.Blt_Un_S;
+                               break;
+                       case Code.Leave:
+                               instr.OpCode = OpCodes.Leave_S;
+                               break;
+                       }
+
+                       return true;
+               }
+
+               void ComputeOffsets ()
+               {
+                       int offset = 0;
+
+                       foreach (Instruction instr in m_instructions) {
+                               instr.Offset = offset;
+                               offset += instr.GetSize ();
+                       }
+               }
+
+               static void Modify (Instruction i, OpCode op, object operand)
+               {
                        i.OpCode = op;
                        i.Operand = operand;
                }

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to