diff --git a/doc/ProgressReport/Evolution/01_Disassemble.cs b/doc/ProgressReport/Evolution/01_Disassemble.cs new file mode 100644 index 000000000..da74293f0 --- /dev/null +++ b/doc/ProgressReport/Evolution/01_Disassemble.cs @@ -0,0 +1,190 @@ +abstract class QuickSortProgram +{ + public static void Main(System.String[] args) + { + IL_00: nop # Pop0->Push0 + IL_01: ldarg args # Pop0->Push1 + IL_02: ldlen # Popref->Pushi + IL_03: conv.i4 # Pop1->Pushi + IL_04: newarr System.Int32# Popi->Pushref + IL_09: stloc V_0 # Pop1->Push0 + IL_0A: ldc.i4 0 # Pop0->Pushi + IL_0B: stloc V_1 # Pop1->Push0 + IL_0C: br IL_1F # Pop0->Push0 Flow=Branch + IL_0E: nop # Pop0->Push0 + IL_0F: ldloc V_0 # Pop0->Push1 + IL_10: ldloc V_1 # Pop0->Push1 + IL_11: ldarg args # Pop0->Push1 + IL_12: ldloc V_1 # Pop0->Push1 + IL_13: ldelem.ref # Popref_popi->Pushref + IL_14: call Parse() # Varpop->Varpush Flow=Call + IL_19: stelem.i4 # Popref_popi_popi->Push0 + IL_1A: nop # Pop0->Push0 + IL_1B: ldloc V_1 # Pop0->Push1 + IL_1C: ldc.i4 1 # Pop0->Pushi + IL_1D: add.ovf # Pop1_pop1->Push1 + IL_1E: stloc V_1 # Pop1->Push0 + IL_1F: ldloc V_1 # Pop0->Push1 + IL_20: ldloc V_0 # Pop0->Push1 + IL_21: ldlen # Popref->Pushi + IL_22: conv.i4 # Pop1->Pushi + IL_23: clt # Pop1_pop1->Pushi + IL_25: stloc V_2 # Pop1->Push0 + IL_26: ldloc V_2 # Pop0->Push1 + IL_27: brtrue IL_0E # Popi->Push0 Flow=Cond_Branch + IL_29: ldloc V_0 # Pop0->Push1 + IL_2A: ldc.i4 0 # Pop0->Pushi + IL_2B: ldloc V_0 # Pop0->Push1 + IL_2C: ldlen # Popref->Pushi + IL_2D: conv.i4 # Pop1->Pushi + IL_2E: ldc.i4 1 # Pop0->Pushi + IL_2F: sub.ovf # Pop1_pop1->Push1 + IL_30: call QuickSort() # Varpop->Varpush Flow=Call + IL_35: nop # Pop0->Push0 + IL_36: ldc.i4 0 # Pop0->Pushi + IL_37: stloc V_1 # Pop1->Push0 + IL_38: br IL_5C # Pop0->Push0 Flow=Branch + IL_3A: nop # Pop0->Push0 + IL_3B: ldloc V_0 # Pop0->Push1 + IL_3C: ldloc V_1 # Pop0->Push1 + IL_3D: ldelema System.Int32# Popref_popi->Pushi + IL_42: call ToString() # Varpop->Varpush Flow=Call + IL_47: ldstr \" \" # Pop0->Pushref + IL_4C: call Concat() # Varpop->Varpush Flow=Call + IL_51: call Write() # Varpop->Varpush Flow=Call + IL_56: nop # Pop0->Push0 + IL_57: nop # Pop0->Push0 + IL_58: ldloc V_1 # Pop0->Push1 + IL_59: ldc.i4 1 # Pop0->Pushi + IL_5A: add.ovf # Pop1_pop1->Push1 + IL_5B: stloc V_1 # Pop1->Push0 + IL_5C: ldloc V_1 # Pop0->Push1 + IL_5D: ldloc V_0 # Pop0->Push1 + IL_5E: ldlen # Popref->Pushi + IL_5F: conv.i4 # Pop1->Pushi + IL_60: clt # Pop1_pop1->Pushi + IL_62: stloc V_2 # Pop1->Push0 + IL_63: ldloc V_2 # Pop0->Push1 + IL_64: brtrue IL_3A # Popi->Push0 Flow=Cond_Branch + IL_66: ret # Varpop->Push0 Flow=Return + } + public static void QuickSort(System.Int32[] array, int left, int right) + { + IL_00: nop # Pop0->Push0 + IL_01: ldarg right # Pop0->Push1 + IL_02: ldarg left # Pop0->Push1 + IL_03: cgt # Pop1_pop1->Pushi + IL_05: ldc.i4 0 # Pop0->Pushi + IL_06: ceq # Pop1_pop1->Pushi + IL_08: stloc V_2 # Pop1->Push0 + IL_09: ldloc V_2 # Pop0->Push1 + IL_0A: brtrue IL_34 # Popi->Push0 Flow=Cond_Branch + IL_0C: nop # Pop0->Push0 + IL_0D: ldarg left # Pop0->Push1 + IL_0E: ldarg right # Pop0->Push1 + IL_0F: add.ovf # Pop1_pop1->Push1 + IL_10: ldc.i4 2 # Pop0->Pushi + IL_11: div # Pop1_pop1->Push1 + IL_12: stloc V_0 # Pop1->Push0 + IL_13: ldarg array # Pop0->Push1 + IL_14: ldarg left # Pop0->Push1 + IL_15: ldarg right # Pop0->Push1 + IL_16: ldloc V_0 # Pop0->Push1 + IL_17: call Partition() # Varpop->Varpush Flow=Call + IL_1C: stloc V_1 # Pop1->Push0 + IL_1D: ldarg array # Pop0->Push1 + IL_1E: ldarg left # Pop0->Push1 + IL_1F: ldloc V_1 # Pop0->Push1 + IL_20: ldc.i4 1 # Pop0->Pushi + IL_21: sub.ovf # Pop1_pop1->Push1 + IL_22: call QuickSort() # Varpop->Varpush Flow=Call + IL_27: nop # Pop0->Push0 + IL_28: ldarg array # Pop0->Push1 + IL_29: ldloc V_1 # Pop0->Push1 + IL_2A: ldc.i4 1 # Pop0->Pushi + IL_2B: add.ovf # Pop1_pop1->Push1 + IL_2C: ldarg right # Pop0->Push1 + IL_2D: call QuickSort() # Varpop->Varpush Flow=Call + IL_32: nop # Pop0->Push0 + IL_33: nop # Pop0->Push0 + IL_34: ret # Varpop->Push0 Flow=Return + } + private static int Partition(System.Int32[] array, int left, int right, int pivotIndex) + { + IL_00: nop # Pop0->Push0 + IL_01: ldarg array # Pop0->Push1 + IL_02: ldarg pivotIndex # Pop0->Push1 + IL_03: ldelem.i4 # Popref_popi->Pushi + IL_04: stloc V_0 # Pop1->Push0 + IL_05: ldarg array # Pop0->Push1 + IL_06: ldarg pivotIndex # Pop0->Push1 + IL_07: ldarg right # Pop0->Push1 + IL_08: call Swap() # Varpop->Varpush Flow=Call + IL_0D: nop # Pop0->Push0 + IL_0E: ldarg left # Pop0->Push1 + IL_0F: stloc V_1 # Pop1->Push0 + IL_10: ldarg left # Pop0->Push1 + IL_11: stloc V_2 # Pop1->Push0 + IL_12: br IL_35 # Pop0->Push0 Flow=Branch + IL_14: nop # Pop0->Push0 + IL_15: ldarg array # Pop0->Push1 + IL_16: ldloc V_2 # Pop0->Push1 + IL_17: ldelem.i4 # Popref_popi->Pushi + IL_18: ldloc V_0 # Pop0->Push1 + IL_19: cgt # Pop1_pop1->Pushi + IL_1B: stloc V_4 # Pop1->Push0 + IL_1D: ldloc V_4 # Pop0->Push1 + IL_1F: brtrue IL_30 # Popi->Push0 Flow=Cond_Branch + IL_21: nop # Pop0->Push0 + IL_22: ldarg array # Pop0->Push1 + IL_23: ldloc V_1 # Pop0->Push1 + IL_24: ldloc V_2 # Pop0->Push1 + IL_25: call Swap() # Varpop->Varpush Flow=Call + IL_2A: nop # Pop0->Push0 + IL_2B: ldloc V_1 # Pop0->Push1 + IL_2C: ldc.i4 1 # Pop0->Pushi + IL_2D: add.ovf # Pop1_pop1->Push1 + IL_2E: stloc V_1 # Pop1->Push0 + IL_2F: nop # Pop0->Push0 + IL_30: nop # Pop0->Push0 + IL_31: ldloc V_2 # Pop0->Push1 + IL_32: ldc.i4 1 # Pop0->Pushi + IL_33: add.ovf # Pop1_pop1->Push1 + IL_34: stloc V_2 # Pop1->Push0 + IL_35: ldloc V_2 # Pop0->Push1 + IL_36: ldarg right # Pop0->Push1 + IL_37: clt # Pop1_pop1->Pushi + IL_39: stloc V_4 # Pop1->Push0 + IL_3B: ldloc V_4 # Pop0->Push1 + IL_3D: brtrue IL_14 # Popi->Push0 Flow=Cond_Branch + IL_3F: ldarg array # Pop0->Push1 + IL_40: ldarg right # Pop0->Push1 + IL_41: ldloc V_1 # Pop0->Push1 + IL_42: call Swap() # Varpop->Varpush Flow=Call + IL_47: nop # Pop0->Push0 + IL_48: ldloc V_1 # Pop0->Push1 + IL_49: stloc V_3 # Pop1->Push0 + IL_4A: br IL_4C # Pop0->Push0 Flow=Branch + IL_4C: ldloc V_3 # Pop0->Push1 + IL_4D: ret # Varpop->Push0 Flow=Return + } + private static void Swap(System.Int32[] array, int index1, int index2) + { + IL_00: nop # Pop0->Push0 + IL_01: ldarg array # Pop0->Push1 + IL_02: ldarg index1 # Pop0->Push1 + IL_03: ldelem.i4 # Popref_popi->Pushi + IL_04: stloc V_0 # Pop1->Push0 + IL_05: ldarg array # Pop0->Push1 + IL_06: ldarg index1 # Pop0->Push1 + IL_07: ldarg array # Pop0->Push1 + IL_08: ldarg index2 # Pop0->Push1 + IL_09: ldelem.i4 # Popref_popi->Pushi + IL_0A: stelem.i4 # Popref_popi_popi->Push0 + IL_0B: ldarg array # Pop0->Push1 + IL_0C: ldarg index2 # Pop0->Push1 + IL_0D: ldloc V_0 # Pop0->Push1 + IL_0E: stelem.i4 # Popref_popi_popi->Push0 + IL_0F: ret # Varpop->Push0 Flow=Return + } +} diff --git a/doc/ProgressReport/Evolution/02_Peephole_decompilation.cs b/doc/ProgressReport/Evolution/02_Peephole_decompilation.cs new file mode 100644 index 000000000..412d12aec --- /dev/null +++ b/doc/ProgressReport/Evolution/02_Peephole_decompilation.cs @@ -0,0 +1,190 @@ +abstract class QuickSortProgram +{ + public static void Main(System.String[] args) + { + IL_00: // No-op + IL_01: System.String[] expr01 = args; + IL_02: int expr02 = arg1.Length; + IL_03: int expr03 = (Int32)arg1; + IL_04: object expr04 = new int[arg1]; + IL_09: V_0 = arg1; + IL_0A: short expr0A = 0; + IL_0B: V_1 = arg1; + IL_0C: goto IL_1F; + IL_0E: // No-op + IL_0F: System.Int32[] expr0F = V_0; + IL_10: int expr10 = V_1; + IL_11: System.String[] expr11 = args; + IL_12: int expr12 = V_1; + IL_13: object expr13 = arg1[arg2]; + IL_14: int expr14 = System.Int32.Parse(arg0); + IL_19: arg1[arg2] = arg3; + IL_1A: // No-op + IL_1B: int expr1B = V_1; + IL_1C: short expr1C = 1; + IL_1D: int expr1D = arg1 + arg2; + IL_1E: V_1 = arg1; + IL_1F: int expr1F = V_1; + IL_20: System.Int32[] expr20 = V_0; + IL_21: int expr21 = arg1.Length; + IL_22: int expr22 = (Int32)arg1; + IL_23: bool expr23 = arg1 < arg2; + IL_25: V_2 = arg1; + IL_26: bool expr26 = V_2; + IL_27: if (arg1) goto IL_0E; + IL_29: System.Int32[] expr29 = V_0; + IL_2A: short expr2A = 0; + IL_2B: System.Int32[] expr2B = V_0; + IL_2C: int expr2C = arg1.Length; + IL_2D: int expr2D = (Int32)arg1; + IL_2E: short expr2E = 1; + IL_2F: int expr2F = arg1 - arg2; + IL_30: QuickSortProgram.QuickSort(arg0, arg1, arg2); + IL_35: // No-op + IL_36: short expr36 = 0; + IL_37: V_1 = arg1; + IL_38: goto IL_5C; + IL_3A: // No-op + IL_3B: System.Int32[] expr3B = V_0; + IL_3C: int expr3C = V_1; + IL_3D: object expr3D = arg1[arg2]; + IL_42: string expr42 = arg1.ToString(); + IL_47: string expr47 = " "; + IL_4C: string expr4C = System.String.Concat(arg0, arg1); + IL_51: System.Console.Write(arg0); + IL_56: // No-op + IL_57: // No-op + IL_58: int expr58 = V_1; + IL_59: short expr59 = 1; + IL_5A: int expr5A = arg1 + arg2; + IL_5B: V_1 = arg1; + IL_5C: int expr5C = V_1; + IL_5D: System.Int32[] expr5D = V_0; + IL_5E: int expr5E = arg1.Length; + IL_5F: int expr5F = (Int32)arg1; + IL_60: bool expr60 = arg1 < arg2; + IL_62: V_2 = arg1; + IL_63: bool expr63 = V_2; + IL_64: if (arg1) goto IL_3A; + IL_66: return; + } + public static void QuickSort(System.Int32[] array, int left, int right) + { + IL_00: // No-op + IL_01: int expr01 = right; + IL_02: int expr02 = left; + IL_03: bool expr03 = arg1 > arg2; + IL_05: short expr05 = 0; + IL_06: bool expr06 = arg1 == arg2; + IL_08: V_2 = arg1; + IL_09: bool expr09 = V_2; + IL_0A: if (arg1) goto IL_34; + IL_0C: // No-op + IL_0D: int expr0D = left; + IL_0E: int expr0E = right; + IL_0F: int expr0F = arg1 + arg2; + IL_10: short expr10 = 2; + IL_11: int expr11 = arg1 / arg2; + IL_12: V_0 = arg1; + IL_13: System.Int32[] expr13 = array; + IL_14: int expr14 = left; + IL_15: int expr15 = right; + IL_16: int expr16 = V_0; + IL_17: int expr17 = QuickSortProgram.Partition(arg0, arg1, arg2, arg3); + IL_1C: V_1 = arg1; + IL_1D: System.Int32[] expr1D = array; + IL_1E: int expr1E = left; + IL_1F: int expr1F = V_1; + IL_20: short expr20 = 1; + IL_21: int expr21 = arg1 - arg2; + IL_22: QuickSortProgram.QuickSort(arg0, arg1, arg2); + IL_27: // No-op + IL_28: System.Int32[] expr28 = array; + IL_29: int expr29 = V_1; + IL_2A: short expr2A = 1; + IL_2B: int expr2B = arg1 + arg2; + IL_2C: int expr2C = right; + IL_2D: QuickSortProgram.QuickSort(arg0, arg1, arg2); + IL_32: // No-op + IL_33: // No-op + IL_34: return; + } + private static int Partition(System.Int32[] array, int left, int right, int pivotIndex) + { + IL_00: // No-op + IL_01: System.Int32[] expr01 = array; + IL_02: int expr02 = pivotIndex; + IL_03: int expr03 = arg1[arg2]; + IL_04: V_0 = arg1; + IL_05: System.Int32[] expr05 = array; + IL_06: int expr06 = pivotIndex; + IL_07: int expr07 = right; + IL_08: QuickSortProgram.Swap(arg0, arg1, arg2); + IL_0D: // No-op + IL_0E: int expr0E = left; + IL_0F: V_1 = arg1; + IL_10: int expr10 = left; + IL_11: V_2 = arg1; + IL_12: goto IL_35; + IL_14: // No-op + IL_15: System.Int32[] expr15 = array; + IL_16: int expr16 = V_2; + IL_17: int expr17 = arg1[arg2]; + IL_18: int expr18 = V_0; + IL_19: bool expr19 = arg1 > arg2; + IL_1B: V_4 = arg1; + IL_1D: bool expr1D = V_4; + IL_1F: if (arg1) goto IL_30; + IL_21: // No-op + IL_22: System.Int32[] expr22 = array; + IL_23: int expr23 = V_1; + IL_24: int expr24 = V_2; + IL_25: QuickSortProgram.Swap(arg0, arg1, arg2); + IL_2A: // No-op + IL_2B: int expr2B = V_1; + IL_2C: short expr2C = 1; + IL_2D: int expr2D = arg1 + arg2; + IL_2E: V_1 = arg1; + IL_2F: // No-op + IL_30: // No-op + IL_31: int expr31 = V_2; + IL_32: short expr32 = 1; + IL_33: int expr33 = arg1 + arg2; + IL_34: V_2 = arg1; + IL_35: int expr35 = V_2; + IL_36: int expr36 = right; + IL_37: bool expr37 = arg1 < arg2; + IL_39: V_4 = arg1; + IL_3B: bool expr3B = V_4; + IL_3D: if (arg1) goto IL_14; + IL_3F: System.Int32[] expr3F = array; + IL_40: int expr40 = right; + IL_41: int expr41 = V_1; + IL_42: QuickSortProgram.Swap(arg0, arg1, arg2); + IL_47: // No-op + IL_48: int expr48 = V_1; + IL_49: V_3 = arg1; + IL_4A: goto IL_4C; + IL_4C: int expr4C = V_3; + IL_4D: return arg1; + } + private static void Swap(System.Int32[] array, int index1, int index2) + { + IL_00: // No-op + IL_01: System.Int32[] expr01 = array; + IL_02: int expr02 = index1; + IL_03: int expr03 = arg1[arg2]; + IL_04: V_0 = arg1; + IL_05: System.Int32[] expr05 = array; + IL_06: int expr06 = index1; + IL_07: System.Int32[] expr07 = array; + IL_08: int expr08 = index2; + IL_09: int expr09 = arg1[arg2]; + IL_0A: arg1[arg2] = arg3; + IL_0B: System.Int32[] expr0B = array; + IL_0C: int expr0C = index2; + IL_0D: int expr0D = V_0; + IL_0E: arg1[arg2] = arg3; + IL_0F: return; + } +} diff --git a/doc/ProgressReport/Evolution/03_Dataflow.cs b/doc/ProgressReport/Evolution/03_Dataflow.cs new file mode 100644 index 000000000..ba7acff8d --- /dev/null +++ b/doc/ProgressReport/Evolution/03_Dataflow.cs @@ -0,0 +1,203 @@ +using System; +abstract class QuickSortProgram +{ + public static void Main(System.String[] args) + { + System.Int32[] V_0; + int V_1; + bool V_2; + // No-op + System.String[] expr01 = args; + int expr02 = expr01.Length; + int expr03 = (Int32)expr02; + System.Int32[] expr04 = new int[expr03]; + V_0 = expr04; + int expr0A = 0; + V_1 = expr0A; + goto IL_1F; + IL_0E: // No-op + System.Int32[] expr0F = V_0; + int expr10 = V_1; + System.String[] expr11 = args; + int expr12 = V_1; + string expr13 = expr11[expr12]; + int expr14 = System.Int32.Parse(expr13); + expr0F[expr10] = expr14; + // No-op + int expr1B = V_1; + int expr1C = 1; + int expr1D = expr1B + expr1C; + V_1 = expr1D; + IL_1F: int expr1F = V_1; + System.Int32[] expr20 = V_0; + int expr21 = expr20.Length; + int expr22 = (Int32)expr21; + bool expr23 = expr1F < expr22; + V_2 = expr23; + bool expr26 = V_2; + if (expr26) goto IL_0E; + System.Int32[] expr29 = V_0; + int expr2A = 0; + System.Int32[] expr2B = V_0; + int expr2C = expr2B.Length; + int expr2D = (Int32)expr2C; + int expr2E = 1; + int expr2F = expr2D - expr2E; + QuickSortProgram.QuickSort(expr29, expr2A, expr2F); + // No-op + int expr36 = 0; + V_1 = expr36; + goto IL_5C; + IL_3A: // No-op + System.Int32[] expr3B = V_0; + int expr3C = V_1; + object expr3D = expr3B[expr3C]; + string expr42 = expr3D.ToString(); + string expr47 = " "; + string expr4C = System.String.Concat(expr42, expr47); + System.Console.Write(expr4C); + // No-op + // No-op + int expr58 = V_1; + int expr59 = 1; + int expr5A = expr58 + expr59; + V_1 = expr5A; + IL_5C: int expr5C = V_1; + System.Int32[] expr5D = V_0; + int expr5E = expr5D.Length; + int expr5F = (Int32)expr5E; + bool expr60 = expr5C < expr5F; + V_2 = expr60; + bool expr63 = V_2; + if (expr63) goto IL_3A; + return; + } + public static void QuickSort(System.Int32[] array, int left, int right) + { + int V_0; + int V_1; + bool V_2; + // No-op + int expr01 = right; + int expr02 = left; + bool expr03 = expr01 > expr02; + int expr05 = 0; + bool expr06 = expr03 == (expr05 != 0); + V_2 = expr06; + bool expr09 = V_2; + if (expr09) goto IL_34; + // No-op + int expr0D = left; + int expr0E = right; + int expr0F = expr0D + expr0E; + int expr10 = 2; + int expr11 = expr0F / expr10; + V_0 = expr11; + System.Int32[] expr13 = array; + int expr14 = left; + int expr15 = right; + int expr16 = V_0; + int expr17 = QuickSortProgram.Partition(expr13, expr14, expr15, expr16); + V_1 = expr17; + System.Int32[] expr1D = array; + int expr1E = left; + int expr1F = V_1; + int expr20 = 1; + int expr21 = expr1F - expr20; + QuickSortProgram.QuickSort(expr1D, expr1E, expr21); + // No-op + System.Int32[] expr28 = array; + int expr29 = V_1; + int expr2A = 1; + int expr2B = expr29 + expr2A; + int expr2C = right; + QuickSortProgram.QuickSort(expr28, expr2B, expr2C); + // No-op + // No-op + IL_34: return; + } + private static int Partition(System.Int32[] array, int left, int right, int pivotIndex) + { + int V_0; + int V_1; + int V_2; + int V_3; + bool V_4; + // No-op + System.Int32[] expr01 = array; + int expr02 = pivotIndex; + int expr03 = expr01[expr02]; + V_0 = expr03; + System.Int32[] expr05 = array; + int expr06 = pivotIndex; + int expr07 = right; + QuickSortProgram.Swap(expr05, expr06, expr07); + // No-op + int expr0E = left; + V_1 = expr0E; + int expr10 = left; + V_2 = expr10; + goto IL_35; + IL_14: // No-op + System.Int32[] expr15 = array; + int expr16 = V_2; + int expr17 = expr15[expr16]; + int expr18 = V_0; + bool expr19 = expr17 > expr18; + V_4 = expr19; + bool expr1D = V_4; + if (expr1D) goto IL_30; + // No-op + System.Int32[] expr22 = array; + int expr23 = V_1; + int expr24 = V_2; + QuickSortProgram.Swap(expr22, expr23, expr24); + // No-op + int expr2B = V_1; + int expr2C = 1; + int expr2D = expr2B + expr2C; + V_1 = expr2D; + // No-op + IL_30: // No-op + int expr31 = V_2; + int expr32 = 1; + int expr33 = expr31 + expr32; + V_2 = expr33; + IL_35: int expr35 = V_2; + int expr36 = right; + bool expr37 = expr35 < expr36; + V_4 = expr37; + bool expr3B = V_4; + if (expr3B) goto IL_14; + System.Int32[] expr3F = array; + int expr40 = right; + int expr41 = V_1; + QuickSortProgram.Swap(expr3F, expr40, expr41); + // No-op + int expr48 = V_1; + V_3 = expr48; + goto IL_4C; + IL_4C: int expr4C = V_3; + return expr4C; + } + private static void Swap(System.Int32[] array, int index1, int index2) + { + int V_0; + // No-op + System.Int32[] expr01 = array; + int expr02 = index1; + int expr03 = expr01[expr02]; + V_0 = expr03; + System.Int32[] expr05 = array; + int expr06 = index1; + System.Int32[] expr07 = array; + int expr08 = index2; + int expr09 = expr07[expr08]; + expr05[expr06] = expr09; + System.Int32[] expr0B = array; + int expr0C = index2; + int expr0D = V_0; + expr0B[expr0C] = expr0D; + return; + } +} diff --git a/doc/ProgressReport/Evolution/03_Dataflow_Comments.cs b/doc/ProgressReport/Evolution/03_Dataflow_Comments.cs new file mode 100644 index 000000000..ff6262a94 --- /dev/null +++ b/doc/ProgressReport/Evolution/03_Dataflow_Comments.cs @@ -0,0 +1,378 @@ +using System; +abstract class QuickSortProgram +{ + public static void Main(System.String[] args) + { + System.Int32[] V_0; + int V_1; + bool V_2; + // No-op + // Stack: {} + System.String[] expr01 = args; + // Stack: {expr01} + int expr02 = expr01.Length; + // Stack: {expr02} + int expr03 = (Int32)expr02; + // Stack: {expr03} + System.Int32[] expr04 = new int[expr03]; + // Stack: {expr04} + V_0 = expr04; + // Stack: {} + int expr0A = 0; + // Stack: {expr0A} + V_1 = expr0A; + // Stack: {} + goto IL_1F; + // Stack: {} + IL_0E: // No-op + // Stack: {} + System.Int32[] expr0F = V_0; + // Stack: {expr0F} + int expr10 = V_1; + // Stack: {expr0F, expr10} + System.String[] expr11 = args; + // Stack: {expr0F, expr10, expr11} + int expr12 = V_1; + // Stack: {expr0F, expr10, expr11, expr12} + string expr13 = expr11[expr12]; + // Stack: {expr0F, expr10, expr13} + int expr14 = System.Int32.Parse(expr13); + // Stack: {expr0F, expr10, expr14} + expr0F[expr10] = expr14; + // Stack: {} + // No-op + // Stack: {} + int expr1B = V_1; + // Stack: {expr1B} + int expr1C = 1; + // Stack: {expr1B, expr1C} + int expr1D = expr1B + expr1C; + // Stack: {expr1D} + V_1 = expr1D; + // Stack: {} + IL_1F: int expr1F = V_1; + // Stack: {expr1F} + System.Int32[] expr20 = V_0; + // Stack: {expr1F, expr20} + int expr21 = expr20.Length; + // Stack: {expr1F, expr21} + int expr22 = (Int32)expr21; + // Stack: {expr1F, expr22} + bool expr23 = expr1F < expr22; + // Stack: {expr23} + V_2 = expr23; + // Stack: {} + bool expr26 = V_2; + // Stack: {expr26} + if (expr26) goto IL_0E; + // Stack: {} + System.Int32[] expr29 = V_0; + // Stack: {expr29} + int expr2A = 0; + // Stack: {expr29, expr2A} + System.Int32[] expr2B = V_0; + // Stack: {expr29, expr2A, expr2B} + int expr2C = expr2B.Length; + // Stack: {expr29, expr2A, expr2C} + int expr2D = (Int32)expr2C; + // Stack: {expr29, expr2A, expr2D} + int expr2E = 1; + // Stack: {expr29, expr2A, expr2D, expr2E} + int expr2F = expr2D - expr2E; + // Stack: {expr29, expr2A, expr2F} + QuickSortProgram.QuickSort(expr29, expr2A, expr2F); + // Stack: {} + // No-op + // Stack: {} + int expr36 = 0; + // Stack: {expr36} + V_1 = expr36; + // Stack: {} + goto IL_5C; + // Stack: {} + IL_3A: // No-op + // Stack: {} + System.Int32[] expr3B = V_0; + // Stack: {expr3B} + int expr3C = V_1; + // Stack: {expr3B, expr3C} + object expr3D = expr3B[expr3C]; + // Stack: {expr3D} + string expr42 = expr3D.ToString(); + // Stack: {expr42} + string expr47 = " "; + // Stack: {expr42, expr47} + string expr4C = System.String.Concat(expr42, expr47); + // Stack: {expr4C} + System.Console.Write(expr4C); + // Stack: {} + // No-op + // Stack: {} + // No-op + // Stack: {} + int expr58 = V_1; + // Stack: {expr58} + int expr59 = 1; + // Stack: {expr58, expr59} + int expr5A = expr58 + expr59; + // Stack: {expr5A} + V_1 = expr5A; + // Stack: {} + IL_5C: int expr5C = V_1; + // Stack: {expr5C} + System.Int32[] expr5D = V_0; + // Stack: {expr5C, expr5D} + int expr5E = expr5D.Length; + // Stack: {expr5C, expr5E} + int expr5F = (Int32)expr5E; + // Stack: {expr5C, expr5F} + bool expr60 = expr5C < expr5F; + // Stack: {expr60} + V_2 = expr60; + // Stack: {} + bool expr63 = V_2; + // Stack: {expr63} + if (expr63) goto IL_3A; + // Stack: {} + return; + // Stack: {} + } + public static void QuickSort(System.Int32[] array, int left, int right) + { + int V_0; + int V_1; + bool V_2; + // No-op + // Stack: {} + int expr01 = right; + // Stack: {expr01} + int expr02 = left; + // Stack: {expr01, expr02} + bool expr03 = expr01 > expr02; + // Stack: {expr03} + int expr05 = 0; + // Stack: {expr03, expr05} + bool expr06 = expr03 == (expr05 != 0); + // Stack: {expr06} + V_2 = expr06; + // Stack: {} + bool expr09 = V_2; + // Stack: {expr09} + if (expr09) goto IL_34; + // Stack: {} + // No-op + // Stack: {} + int expr0D = left; + // Stack: {expr0D} + int expr0E = right; + // Stack: {expr0D, expr0E} + int expr0F = expr0D + expr0E; + // Stack: {expr0F} + int expr10 = 2; + // Stack: {expr0F, expr10} + int expr11 = expr0F / expr10; + // Stack: {expr11} + V_0 = expr11; + // Stack: {} + System.Int32[] expr13 = array; + // Stack: {expr13} + int expr14 = left; + // Stack: {expr13, expr14} + int expr15 = right; + // Stack: {expr13, expr14, expr15} + int expr16 = V_0; + // Stack: {expr13, expr14, expr15, expr16} + int expr17 = QuickSortProgram.Partition(expr13, expr14, expr15, expr16); + // Stack: {expr17} + V_1 = expr17; + // Stack: {} + System.Int32[] expr1D = array; + // Stack: {expr1D} + int expr1E = left; + // Stack: {expr1D, expr1E} + int expr1F = V_1; + // Stack: {expr1D, expr1E, expr1F} + int expr20 = 1; + // Stack: {expr1D, expr1E, expr1F, expr20} + int expr21 = expr1F - expr20; + // Stack: {expr1D, expr1E, expr21} + QuickSortProgram.QuickSort(expr1D, expr1E, expr21); + // Stack: {} + // No-op + // Stack: {} + System.Int32[] expr28 = array; + // Stack: {expr28} + int expr29 = V_1; + // Stack: {expr28, expr29} + int expr2A = 1; + // Stack: {expr28, expr29, expr2A} + int expr2B = expr29 + expr2A; + // Stack: {expr28, expr2B} + int expr2C = right; + // Stack: {expr28, expr2B, expr2C} + QuickSortProgram.QuickSort(expr28, expr2B, expr2C); + // Stack: {} + // No-op + // Stack: {} + // No-op + // Stack: {} + IL_34: return; + // Stack: {} + } + private static int Partition(System.Int32[] array, int left, int right, int pivotIndex) + { + int V_0; + int V_1; + int V_2; + int V_3; + bool V_4; + // No-op + // Stack: {} + System.Int32[] expr01 = array; + // Stack: {expr01} + int expr02 = pivotIndex; + // Stack: {expr01, expr02} + int expr03 = expr01[expr02]; + // Stack: {expr03} + V_0 = expr03; + // Stack: {} + System.Int32[] expr05 = array; + // Stack: {expr05} + int expr06 = pivotIndex; + // Stack: {expr05, expr06} + int expr07 = right; + // Stack: {expr05, expr06, expr07} + QuickSortProgram.Swap(expr05, expr06, expr07); + // Stack: {} + // No-op + // Stack: {} + int expr0E = left; + // Stack: {expr0E} + V_1 = expr0E; + // Stack: {} + int expr10 = left; + // Stack: {expr10} + V_2 = expr10; + // Stack: {} + goto IL_35; + // Stack: {} + IL_14: // No-op + // Stack: {} + System.Int32[] expr15 = array; + // Stack: {expr15} + int expr16 = V_2; + // Stack: {expr15, expr16} + int expr17 = expr15[expr16]; + // Stack: {expr17} + int expr18 = V_0; + // Stack: {expr17, expr18} + bool expr19 = expr17 > expr18; + // Stack: {expr19} + V_4 = expr19; + // Stack: {} + bool expr1D = V_4; + // Stack: {expr1D} + if (expr1D) goto IL_30; + // Stack: {} + // No-op + // Stack: {} + System.Int32[] expr22 = array; + // Stack: {expr22} + int expr23 = V_1; + // Stack: {expr22, expr23} + int expr24 = V_2; + // Stack: {expr22, expr23, expr24} + QuickSortProgram.Swap(expr22, expr23, expr24); + // Stack: {} + // No-op + // Stack: {} + int expr2B = V_1; + // Stack: {expr2B} + int expr2C = 1; + // Stack: {expr2B, expr2C} + int expr2D = expr2B + expr2C; + // Stack: {expr2D} + V_1 = expr2D; + // Stack: {} + // No-op + // Stack: {} + IL_30: // No-op + // Stack: {} + int expr31 = V_2; + // Stack: {expr31} + int expr32 = 1; + // Stack: {expr31, expr32} + int expr33 = expr31 + expr32; + // Stack: {expr33} + V_2 = expr33; + // Stack: {} + IL_35: int expr35 = V_2; + // Stack: {expr35} + int expr36 = right; + // Stack: {expr35, expr36} + bool expr37 = expr35 < expr36; + // Stack: {expr37} + V_4 = expr37; + // Stack: {} + bool expr3B = V_4; + // Stack: {expr3B} + if (expr3B) goto IL_14; + // Stack: {} + System.Int32[] expr3F = array; + // Stack: {expr3F} + int expr40 = right; + // Stack: {expr3F, expr40} + int expr41 = V_1; + // Stack: {expr3F, expr40, expr41} + QuickSortProgram.Swap(expr3F, expr40, expr41); + // Stack: {} + // No-op + // Stack: {} + int expr48 = V_1; + // Stack: {expr48} + V_3 = expr48; + // Stack: {} + goto IL_4C; + // Stack: {} + IL_4C: int expr4C = V_3; + // Stack: {expr4C} + return expr4C; + // Stack: {} + } + private static void Swap(System.Int32[] array, int index1, int index2) + { + int V_0; + // No-op + // Stack: {} + System.Int32[] expr01 = array; + // Stack: {expr01} + int expr02 = index1; + // Stack: {expr01, expr02} + int expr03 = expr01[expr02]; + // Stack: {expr03} + V_0 = expr03; + // Stack: {} + System.Int32[] expr05 = array; + // Stack: {expr05} + int expr06 = index1; + // Stack: {expr05, expr06} + System.Int32[] expr07 = array; + // Stack: {expr05, expr06, expr07} + int expr08 = index2; + // Stack: {expr05, expr06, expr07, expr08} + int expr09 = expr07[expr08]; + // Stack: {expr05, expr06, expr09} + expr05[expr06] = expr09; + // Stack: {} + System.Int32[] expr0B = array; + // Stack: {expr0B} + int expr0C = index2; + // Stack: {expr0B, expr0C} + int expr0D = V_0; + // Stack: {expr0B, expr0C, expr0D} + expr0B[expr0C] = expr0D; + // Stack: {} + return; + // Stack: {} + } +} diff --git a/doc/ProgressReport/Evolution/04_Inline_expressions.cs b/doc/ProgressReport/Evolution/04_Inline_expressions.cs new file mode 100644 index 000000000..e2353fd42 --- /dev/null +++ b/doc/ProgressReport/Evolution/04_Inline_expressions.cs @@ -0,0 +1,49 @@ +using System; +abstract class QuickSortProgram +{ + public static void Main(System.String[] args) + { + System.Int32[] V_0 = new int[((Int32)args.Length)]; + int V_1 = 0; + goto IL_1C; + IL_0D: V_0[V_1] = System.Int32.Parse(args[V_1]); + V_1 = (V_1 + 1); + IL_1C: if (V_1 < ((Int32)V_0.Length)) goto IL_0D; + QuickSortProgram.QuickSort(V_0, 0, (((Int32)V_0.Length) - 1)); + int V_2 = 0; + goto IL_51; + IL_32: System.Console.Write(System.String.Concat((V_0[V_2]).ToString(), " ")); + V_2 = (V_2 + 1); + IL_51: if (V_2 < ((Int32)V_0.Length)) goto IL_32; + } + public static void QuickSort(System.Int32[] array, int left, int right) + { + if (right <= left) goto IL_28; + int V_0 = ((left + right) / 2); + int V_1 = QuickSortProgram.Partition(array, left, right, V_0); + QuickSortProgram.QuickSort(array, left, (V_1 - 1)); + QuickSortProgram.QuickSort(array, (V_1 + 1), right); + IL_28: return; + } + private static int Partition(System.Int32[] array, int left, int right, int pivotIndex) + { + int V_0 = array[pivotIndex]; + QuickSortProgram.Swap(array, pivotIndex, right); + int V_1 = left; + int V_2 = left; + goto IL_28; + IL_12: if (array[V_2] > V_0) goto IL_24; + QuickSortProgram.Swap(array, V_1, V_2); + V_1 = (V_1 + 1); + IL_24: V_2 = (V_2 + 1); + IL_28: if (V_2 < right) goto IL_12; + QuickSortProgram.Swap(array, right, V_1); + return V_1; + } + private static void Swap(System.Int32[] array, int index1, int index2) + { + int V_0 = array[index1]; + array[index1] = array[index2]; + array[index2] = V_0; + } +} \ No newline at end of file diff --git a/doc/ProgressReport/Evolution/05_Find_basic_blocks.cs b/doc/ProgressReport/Evolution/05_Find_basic_blocks.cs new file mode 100644 index 000000000..44a54b741 --- /dev/null +++ b/doc/ProgressReport/Evolution/05_Find_basic_blocks.cs @@ -0,0 +1,78 @@ +using System; +abstract class QuickSortProgram +{ + public static void Main(System.String[] args) + { + BasicBlock_1: + System.Int32[] V_0 = new int[((int)args.Length)]; + int i = 0; + goto BasicBlock_3; + BasicBlock_2: + V_0[i] = System.Int32.Parse(args[i]); + i = (i + 1); + goto BasicBlock_3; + BasicBlock_3: + if (i < ((int)V_0.Length)) goto BasicBlock_2; + goto BasicBlock_4; + BasicBlock_4: + QuickSortProgram.QuickSort(V_0, 0, (((int)V_0.Length) - 1)); + int j = 0; + goto BasicBlock_6; + BasicBlock_5: + System.Console.Write(System.String.Concat((V_0[j]).ToString(), " ")); + j = (j + 1); + goto BasicBlock_6; + BasicBlock_6: + if (j < ((int)V_0.Length)) goto BasicBlock_5; + goto BasicBlock_7; + BasicBlock_7: + return; + } + public static void QuickSort(System.Int32[] array, int left, int right) + { + BasicBlock_9: + if (right <= left) goto BasicBlock_11; + goto BasicBlock_10; + BasicBlock_10: + int i = ((left + right) / 2); + int j = QuickSortProgram.Partition(array, left, right, i); + QuickSortProgram.QuickSort(array, left, (j - 1)); + QuickSortProgram.QuickSort(array, (j + 1), right); + goto BasicBlock_11; + BasicBlock_11: + return; + } + private static int Partition(System.Int32[] array, int left, int right, int pivotIndex) + { + BasicBlock_13: + int i = array[pivotIndex]; + QuickSortProgram.Swap(array, pivotIndex, right); + int j = left; + int k = left; + goto BasicBlock_17; + BasicBlock_14: + if (array[k] > i) goto BasicBlock_16; + goto BasicBlock_15; + BasicBlock_15: + QuickSortProgram.Swap(array, j, k); + j = (j + 1); + goto BasicBlock_16; + BasicBlock_16: + k = (k + 1); + goto BasicBlock_17; + BasicBlock_17: + if (k < right) goto BasicBlock_14; + goto BasicBlock_18; + BasicBlock_18: + QuickSortProgram.Swap(array, right, j); + return j; + } + private static void Swap(System.Int32[] array, int index1, int index2) + { + BasicBlock_20: + int i = array[index1]; + array[index1] = array[index2]; + array[index2] = i; + return; + } +} diff --git a/doc/ProgressReport/Evolution/06_Find_loops.cs b/doc/ProgressReport/Evolution/06_Find_loops.cs new file mode 100644 index 000000000..c87766cbb --- /dev/null +++ b/doc/ProgressReport/Evolution/06_Find_loops.cs @@ -0,0 +1,87 @@ +using System; +abstract class QuickSortProgram +{ + public static void Main(System.String[] args) + { + BasicBlock_1: + System.Int32[] V_0 = new int[((int)args.Length)]; + int i = 0; + goto Loop_8; + Loop_8: + for (;;) { + BasicBlock_3: + if (i < ((int)V_0.Length)) goto BasicBlock_2; + break; + BasicBlock_2: + V_0[i] = System.Int32.Parse(args[i]); + i = (i + 1); + continue; + } + BasicBlock_4: + QuickSortProgram.QuickSort(V_0, 0, (((int)V_0.Length) - 1)); + int j = 0; + goto Loop_11; + Loop_11: + for (;;) { + BasicBlock_6: + if (j < ((int)V_0.Length)) goto BasicBlock_5; + break; + BasicBlock_5: + System.Console.Write(System.String.Concat((V_0[j]).ToString(), " ")); + j = (j + 1); + continue; + } + BasicBlock_7: + return; + } + public static void QuickSort(System.Int32[] array, int left, int right) + { + BasicBlock_15: + if (right <= left) goto BasicBlock_17; + goto BasicBlock_16; + BasicBlock_16: + int i = ((left + right) / 2); + int j = QuickSortProgram.Partition(array, left, right, i); + QuickSortProgram.QuickSort(array, left, (j - 1)); + QuickSortProgram.QuickSort(array, (j + 1), right); + goto BasicBlock_17; + BasicBlock_17: + return; + } + private static int Partition(System.Int32[] array, int left, int right, int pivotIndex) + { + BasicBlock_21: + int i = array[pivotIndex]; + QuickSortProgram.Swap(array, pivotIndex, right); + int j = left; + int k = left; + goto Loop_29; + Loop_29: + for (;;) { + BasicBlock_25: + if (k < right) goto BasicBlock_22; + break; + BasicBlock_22: + if (array[k] > i) goto BasicBlock_24; + goto BasicBlock_23; + BasicBlock_23: + QuickSortProgram.Swap(array, j, k); + j = (j + 1); + goto BasicBlock_24; + BasicBlock_24: + k = (k + 1); + continue; + } + BasicBlock_26: + QuickSortProgram.Swap(array, right, j); + return j; + } + private static void Swap(System.Int32[] array, int index1, int index2) + { + BasicBlock_33: + int i = array[index1]; + array[index1] = array[index2]; + array[index2] = i; + return; + } +} diff --git a/doc/ProgressReport/Evolution/07_Find_conditionals.cs b/doc/ProgressReport/Evolution/07_Find_conditionals.cs new file mode 100644 index 000000000..7f7e46c04 --- /dev/null +++ b/doc/ProgressReport/Evolution/07_Find_conditionals.cs @@ -0,0 +1,122 @@ +using System; +abstract class QuickSortProgram +{ + public static void Main(System.String[] args) + { + BasicBlock_1: + System.Int32[] V_0 = new int[((int)args.Length)]; + int i = 0; + goto Loop_8; + Loop_8: + for (;;) { + ConditionalNode_16: + BasicBlock_3: + if (!(i < ((int)V_0.Length))) { + break; + Block_14: + } + else { + goto BasicBlock_2; + Block_15: + } + BasicBlock_2: + V_0[i] = System.Int32.Parse(args[i]); + i = (i + 1); + continue; + } + BasicBlock_4: + QuickSortProgram.QuickSort(V_0, 0, (((int)V_0.Length) - 1)); + int j = 0; + goto Loop_11; + Loop_11: + for (;;) { + ConditionalNode_19: + BasicBlock_6: + if (!(j < ((int)V_0.Length))) { + break; + Block_17: + } + else { + goto BasicBlock_5; + Block_18: + } + BasicBlock_5: + System.Console.Write(System.String.Concat((V_0[j]).ToString(), " ")); + j = (j + 1); + continue; + } + BasicBlock_7: + return; + } + public static void QuickSort(System.Int32[] array, int left, int right) + { + ConditionalNode_28: + BasicBlock_21: + if (!(right <= left)) { + goto Block_26; + Block_26: + BasicBlock_22: + int i = ((left + right) / 2); + int j = QuickSortProgram.Partition(array, left, right, i); + QuickSortProgram.QuickSort(array, left, (j - 1)); + QuickSortProgram.QuickSort(array, (j + 1), right); + goto BasicBlock_23; + } + else { + goto BasicBlock_23; + Block_27: + } + BasicBlock_23: + return; + } + private static int Partition(System.Int32[] array, int left, int right, int pivotIndex) + { + BasicBlock_30: + int i = array[pivotIndex]; + QuickSortProgram.Swap(array, pivotIndex, right); + int j = left; + int k = left; + goto Loop_38; + Loop_38: + for (;;) { + ConditionalNode_43: + BasicBlock_34: + if (!(k < right)) { + break; + Block_41: + } + else { + goto ConditionalNode_46; + Block_42: + } + ConditionalNode_46: + BasicBlock_31: + if (!(array[k] > i)) { + goto Block_44; + Block_44: + BasicBlock_32: + QuickSortProgram.Swap(array, j, k); + j = (j + 1); + goto BasicBlock_33; + } + else { + goto BasicBlock_33; + Block_45: + } + BasicBlock_33: + k = (k + 1); + continue; + } + BasicBlock_35: + QuickSortProgram.Swap(array, right, j); + return j; + } + private static void Swap(System.Int32[] array, int index1, int index2) + { + BasicBlock_48: + int i = array[index1]; + array[index1] = array[index2]; + array[index2] = i; + return; + } +} diff --git a/doc/ProgressReport/Evolution/08_Remove_dead_jumps.cs b/doc/ProgressReport/Evolution/08_Remove_dead_jumps.cs new file mode 100644 index 000000000..811afa178 --- /dev/null +++ b/doc/ProgressReport/Evolution/08_Remove_dead_jumps.cs @@ -0,0 +1,69 @@ +using System; +abstract class QuickSortProgram +{ + public static void Main(System.String[] args) + { + System.Int32[] V_0 = new int[((int)args.Length)]; + int i = 0; + for (;;) { + if (!(i < ((int)V_0.Length))) { + break; + } + else { + } + V_0[i] = System.Int32.Parse(args[i]); + i = (i + 1); + } + QuickSortProgram.QuickSort(V_0, 0, (((int)V_0.Length) - 1)); + int j = 0; + for (;;) { + if (!(j < ((int)V_0.Length))) { + break; + } + else { + } + System.Console.Write(System.String.Concat((V_0[j]).ToString(), " ")); + j = (j + 1); + } + } + public static void QuickSort(System.Int32[] array, int left, int right) + { + if (!(right <= left)) { + int i = ((left + right) / 2); + int j = QuickSortProgram.Partition(array, left, right, i); + QuickSortProgram.QuickSort(array, left, (j - 1)); + QuickSortProgram.QuickSort(array, (j + 1), right); + } + else { + } + } + private static int Partition(System.Int32[] array, int left, int right, int pivotIndex) + { + int i = array[pivotIndex]; + QuickSortProgram.Swap(array, pivotIndex, right); + int j = left; + int k = left; + for (;;) { + if (!(k < right)) { + break; + } + else { + } + if (!(array[k] > i)) { + QuickSortProgram.Swap(array, j, k); + j = (j + 1); + } + else { + } + k = (k + 1); + } + QuickSortProgram.Swap(array, right, j); + return j; + } + private static void Swap(System.Int32[] array, int index1, int index2) + { + int i = array[index1]; + array[index1] = array[index2]; + array[index2] = i; + } +} diff --git a/doc/ProgressReport/Evolution/09_Reduce_loops.cs b/doc/ProgressReport/Evolution/09_Reduce_loops.cs new file mode 100644 index 000000000..c13e9d451 --- /dev/null +++ b/doc/ProgressReport/Evolution/09_Reduce_loops.cs @@ -0,0 +1,51 @@ +using System; +abstract class QuickSortProgram +{ + public static void Main(System.String[] args) + { + System.Int32[] V_0 = new int[((int)args.Length)]; + + for (int i = 0; (i < ((int)V_0.Length)); i = (i + 1)) { + V_0[i] = System.Int32.Parse(args[i]); + } + QuickSortProgram.QuickSort(V_0, 0, (((int)V_0.Length) - 1)); + + for (int j = 0; (j < ((int)V_0.Length)); j = (j + 1)) { + System.Console.Write(System.String.Concat((V_0[j]).ToString(), " ")); + } + } + public static void QuickSort(System.Int32[] array, int left, int right) + { + if (!(right <= left)) { + int i = ((left + right) / 2); + int j = QuickSortProgram.Partition(array, left, right, i); + QuickSortProgram.QuickSort(array, left, (j - 1)); + QuickSortProgram.QuickSort(array, (j + 1), right); + } + else { + } + } + private static int Partition(System.Int32[] array, int left, int right, int pivotIndex) + { + int i = array[pivotIndex]; + QuickSortProgram.Swap(array, pivotIndex, right); + int j = left; + + for (int k = left; (k < right); k = (k + 1)) { + if (!(array[k] > i)) { + QuickSortProgram.Swap(array, j, k); + j = (j + 1); + } + else { + } + } + QuickSortProgram.Swap(array, right, j); + return j; + } + private static void Swap(System.Int32[] array, int index1, int index2) + { + int i = array[index1]; + array[index1] = array[index2]; + array[index2] = i; + } +} diff --git a/doc/ProgressReport/Evolution/10_Short_type_names.cs b/doc/ProgressReport/Evolution/10_Short_type_names.cs new file mode 100644 index 000000000..71910645f --- /dev/null +++ b/doc/ProgressReport/Evolution/10_Short_type_names.cs @@ -0,0 +1,44 @@ +using System; +abstract class QuickSortProgram +{ + public static void Main(string[] args) + { + int[] V_0 = new int[((int)args.Length)]; + for (int i = 0; (i < ((int)V_0.Length)); i = (i + 1)) { + V_0[i] = Int32.Parse(args[i]); + } + QuickSort(V_0, 0, (((int)V_0.Length) - 1)); + for (int j = 0; (j < ((int)V_0.Length)); j = (j + 1)) { + Console.Write((V_0[j]).ToString() + " "); + } + } + public static void QuickSort(int[] array, int left, int right) + { + if (!(right <= left)) { + int i = ((left + right) / 2); + int j = Partition(array, left, right, i); + QuickSort(array, left, (j - 1)); + QuickSort(array, (j + 1), right); + } + } + private static int Partition(int[] array, int left, int right, int pivotIndex) + { + int i = array[pivotIndex]; + Swap(array, pivotIndex, right); + int j = left; + for (int k = left; (k < right); k = (k + 1)) { + if (!(array[k] > i)) { + Swap(array, j, k); + j = (j + 1); + } + } + Swap(array, right, j); + return j; + } + private static void Swap(int[] array, int index1, int index2) + { + int i = array[index1]; + array[index1] = array[index2]; + array[index2] = i; + } +} diff --git a/doc/ProgressReport/Evolution/QuickSort_original.cs b/doc/ProgressReport/Evolution/QuickSort_original.cs new file mode 100644 index 000000000..715694e7b --- /dev/null +++ b/doc/ProgressReport/Evolution/QuickSort_original.cs @@ -0,0 +1,43 @@ +static class QuickSortProgram +{ + public static void Main(string[] args) + { + int[] intArray = new int[args.Length]; + for (int i = 0; i < intArray.Length; i++) { + intArray[i] = int.Parse(args[i]); + } + QuickSort(intArray, 0, intArray.Length - 1); + for (int i = 0; i < intArray.Length; i++) { + System.Console.Write(intArray[i].ToString() + " "); + } + } + public static void QuickSort(int[] array, int left, int right) + { + if (right > left) { + int pivotIndex = (left + right) / 2; + int pivotNew = Partition(array, left, right, pivotIndex); + QuickSort(array, left, pivotNew - 1); + QuickSort(array, pivotNew + 1, right); + } + } + static int Partition(int[] array, int left, int right, int pivotIndex) + { + int pivotValue = array[pivotIndex]; + Swap(array, pivotIndex, right); + int storeIndex = left; + for(int i = left; i < right; i++) { + if (array[i] <= pivotValue) { + Swap(array, storeIndex, i); + storeIndex = storeIndex + 1; + } + } + Swap(array, right, storeIndex); + return storeIndex; + } + static void Swap(int[] array, int index1, int index2) + { + int tmp = array[index1]; + array[index1] = array[index2]; + array[index2] = tmp; + } +} \ No newline at end of file diff --git a/doc/ProgressReport/ProgressReport.tex b/doc/ProgressReport/ProgressReport.tex new file mode 100644 index 000000000..88cc9e70f --- /dev/null +++ b/doc/ProgressReport/ProgressReport.tex @@ -0,0 +1,243 @@ +\documentclass[12pt]{article} +\usepackage{a4wide} +\usepackage{listings} + +\parindent 0pt +\parskip 6pt + +\begin{document} + +\thispagestyle{empty} + +\rightline{\large\emph{David Srbeck\'y}} +\medskip +\rightline{\large\emph{Jesus College}} +\medskip +\rightline{\large\emph{ds417}} + +\vspace{0.675in} + +\centerline{\large Progress Report} +\vspace{0.4in} +\centerline{\Large\bf .NET Decompiler} +\vspace{0.3in} +\centerline{\large\emph{January~30,~2008}} + +\vspace{0.675in} + +{\bf Project Originator:} \emph{David Srbeck\'y} + +\vspace{0.1in} + +{\bf Project Supervisor:} \emph{Alan Mycroft} + +\vspace{0.1in} + +{\bf Director of Studies:} \emph{Jean Bacon} and \emph{David Ingram} + +\vspace{0.1in} + +{\bf Overseers:} \emph{Anuj Dawar} and \emph{Andrew Moore} + +\vspace{0.1in} + +\vfil +\eject + +\newcommand{\CS}{\emph{C\#} } + +\lstset{ + basicstyle=\small, + language={[Sharp]C}, + tabsize=4, + numbers=left, + frame=single, + frameround=tfft +} + +\section*{Work completed so far} +\subsection*{Disassemble \emph{.NET} bytecode} + +The \emph{.NET} assembly is read using the \emph{Cecil} library +and the class structure is created. Method bodies contain the +disassembly of the IL bytecode. The debugging comment on the +right indicates the stack behavior of the given instruction. +This, of course, is not valid \CS code yet. + +\lstinputlisting[lastline=32] +{./Evolution/01_Disassemble.cs} + +\newpage +\subsection*{Start creating expressions} + +The bytecodes are converted to \CS expressions on individual basis. +Only one bytecode is considered at a time and thus the expressions +are completely independent. The resulting output is a valid \CS code +which however does not compile since the dummy arguments \verb|arg1|, +\verb|arg2|, etc\dots{} are never defined. Conditional and unconditional +branches are converted to \verb|goto| goto statements. + +\lstinputlisting[lastline=32] +{./Evolution/02_Peephole_decompilation.cs} + +\newpage +\subsection*{Data-flow analysis} + +The execution of the bytecode is simulated and the state of the stack is +recorded for each position. We are interested in the number of +elements on the stack as well as which instruction has pushed the +individual elements on the stack. This information can then be used to eliminate +the dummy \verb|arg1| arguments. Result of each instruction is stored +in new temporary variable. When an instruction pops a stack value +we look-up which instruction has allocated the value and use the temporary +variable of the allocating instruction. +This code compiles and works correctly. + +\lstinputlisting[firstline=21, lastline=52] +{./Evolution/03_Dataflow_Comments.cs} + +\newpage +\subsection*{In-lineing expressions} + +Many of the temporary variables can be in-lined into the expressions in which +they are used. This is in general non-trivial optimization, however it is +simpler in this case since the temporary variables generated to store the +stack values are guaranteed to be single static assignment variables (the +variable is assigned only once during the push instruction and is used +only once during the pop instruction). +Having said that, we still need to check that doing the optimization is +safe with regards to expression evaluation order and with regrads to branching. + +\lstinputlisting[firstline=1, lastline=32] +{./Evolution/04_Inline_expressions.cs} + +\newpage +\subsection*{Finding basic blocks} + +The first step of reconstructing any high-level structures is the +decomposition of the program into basic blocks. This is an easy +algorithm to implement. + +I chose to use the following constraint for the output: +``Each basic block starts with a label and is exited by an explicit +\verb|goto| statement.'' +Therefore except for the method entry, the order +of the blocks is completely irrelevant. Any swapping of the basic +blocks is not going change the semantics of the program in any way. + +\lstinputlisting[firstline=1, lastline=30] +{./Evolution/05_Find_basic_blocks.cs} + +\newpage +\subsection*{Finding loops} + +The algorithm for finding loops is inspired by T1-T2 transformations. +T1-T2 transformations are used to determine whether a graph is +reducible or not. The core idea is that if a block of code has +only one predecessor then the block of code can be merged +with its predecessor to form a directed acyclic graph. Using this, +loops will reduce to single self-referencing nodes. +This also works for nested loops. + +Note that merely adding a loop does not change the program in any way -- +the loop is completely redundant as far as control flow goes. +The basic blocks still explicitly transfer control using \verb|goto| +statements, so the control flow never reaches the loop. + +This is desirable property. It ensures that the program will run +correctly. The order of basic blocks and their nesting within loops +does not have any effect on program correctness. + +The only advantage of the loop is readability and that some \verb|goto| +statements can be replaced by \verb|break| and \verb|continue| statements +if they have the same semantics in the given context. + +\lstinputlisting[firstline=1, lastline=25] +{./Evolution/06_Find_loops.cs} + +\newpage +\subsection*{Finding conditionals} + +The current algorithm for finding conditionals works as follows: +First find a node that has two successors. Get all nodes accessible +\emph{only} from the `true' branch -- these form the `true' body of +the conditional. Similarly, all nodes accessible \emph{only} from the +`false' branch form the `false' body. The rest of the nodes is +not part of the conditional. + +Similarly as for the loops, adding a conditional does not have any +effect on program correctness. + +\lstinputlisting[firstline=1, lastline=32] +{./Evolution/07_Find_conditionals.cs} + +\newpage +\subsection*{Remove dead jumps} + +There are many \verb|goto| statements in the form: +\begin{verbatim} +goto BasicBlock_X; +BasicBlock_X: +\end{verbatim} +These \verb|goto| statement can be removed. As a result of +doing that, several labels will become dead; these can be +removed as well. + +\lstinputlisting[firstline=1, lastline=32] +{./Evolution/08_Remove_dead_jumps.cs} + +\newpage +\subsection*{Reduce loops} + +It is common for loops to be preceded by a temporary variable +initialization, start by evaluating a condition and finally +end by doing an increment on a variable. We can look +for these patterns and if they are found move the code +to the \verb|for(;;)| part of the statement. + +\lstinputlisting[firstline=1, lastline=32] +{./Evolution/09_Reduce_loops.cs} + +\newpage +\subsection*{Clean up} + +Finally some minor cleanups like removing empty statements and +simplifying type names. + +\lstinputlisting[firstline=1, lastline=42] +{./Evolution/10_Short_type_names.cs} + +\newpage +\subsection*{Original source code} +Here is the original source code for reference. + +\lstinputlisting[firstline=1, lastline=41] +{./Evolution/QuickSort_original.cs} + +\newpage +\subsection*{Unexpected difficulties} + +The \emph{CodeDom} library that I have initially intended to use +to output source code in arbitrary \emph{.NET} language has turned out to be +quite incomplete. That is, since the library aims to be +able to represent source code for any language, it has +feature set limited to the lowest common denominator. +Therefore, I have switched to \emph{NRefactory} library which +is specifically designed with \CS and \emph{VB.NET} in mind. + +Using \emph{T1-T2} transformations for loop finding turned out to be +a slightly more difficult since the algorithm is, after all, +originally intended to produce a yes or no answer to whether the graph +is reducible. However, it was not problematic to refactor +the idea to suit a different purpose. + +\subsection*{Summary} + +The project tasks were performed in the planned order and +the project is progressing according to the schedule. + +The quality of decompilation of the Quick-Sort algorithm is +almost `as good as it gets' so I intend to look for some more +complex assembly to tackle. + +\end{document} diff --git a/doc/ProgressReport/srbecky-ProgressReport-draft-1.pdf b/doc/ProgressReport/srbecky-ProgressReport-draft-1.pdf new file mode 100644 index 000000000..500a657ec Binary files /dev/null and b/doc/ProgressReport/srbecky-ProgressReport-draft-1.pdf differ