Optimizer.BCP.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using ILRuntime.Mono.Cecil;
  6. using ILRuntime.Mono.Cecil.Cil;
  7. using ILRuntime.CLR.TypeSystem;
  8. using ILRuntime.CLR.Method;
  9. using ILRuntime.Runtime.Intepreter.OpCodes;
  10. namespace ILRuntime.Runtime.Intepreter.RegisterVM
  11. {
  12. partial class Optimizer
  13. {
  14. public static void BackwardsCopyPropagation(List<CodeBasicBlock> blocks, bool hasReturn,short stackRegisterBegin)
  15. {
  16. foreach (var b in blocks)
  17. {
  18. var lst = b.FinalInstructions;
  19. HashSet<int> canRemove = b.CanRemove;
  20. //HashSet<int> pendingBCP = b.PendingCP;
  21. bool isInline = false;
  22. for (int i = lst.Count - 1; i >= 0; i--)
  23. {
  24. if (canRemove.Contains(i))
  25. continue;
  26. OpCodeR X = lst[i];
  27. if (X.Code == OpCodeREnum.InlineStart)
  28. {
  29. isInline = false;
  30. continue;
  31. }
  32. if (X.Code == OpCodeREnum.InlineEnd)
  33. {
  34. isInline = true;
  35. continue;
  36. }
  37. //if (isInline)
  38. // continue;
  39. if (X.Code == OpCodeREnum.Nop)
  40. {
  41. canRemove.Add(i);
  42. continue;
  43. }
  44. if (X.Code == OpCodeREnum.Move)
  45. {
  46. short xSrc, xSrc2, xSrc3, xDst;
  47. GetOpcodeSourceRegister(ref X, hasReturn, out xSrc, out xSrc2, out xSrc3);
  48. GetOpcodeDestRegister(ref X, out xDst);
  49. if (xDst == xSrc)
  50. {
  51. canRemove.Add(i);
  52. continue;
  53. }
  54. //Only deal with stack->local
  55. if (xSrc < stackRegisterBegin || xDst >= stackRegisterBegin || isInline)
  56. continue;
  57. bool ended = false;
  58. bool propagationInline = false;
  59. for (int j = i - 1; j >= 0; j--)
  60. {
  61. OpCodeR Y = lst[j];
  62. if (Y.Code == OpCodeREnum.InlineStart)
  63. propagationInline = false;
  64. else if (Y.Code == OpCodeREnum.InlineEnd)
  65. {
  66. propagationInline = true;
  67. }
  68. short ySrc, ySrc2, ySrc3;
  69. if (GetOpcodeSourceRegister(ref Y, hasReturn, out ySrc, out ySrc2, out ySrc3))
  70. {
  71. if (ySrc >= 0 && ySrc == xDst)
  72. {
  73. break;
  74. }
  75. if (ySrc2 >= 0 && ySrc2 == xDst)
  76. {
  77. break;
  78. }
  79. if (ySrc3 >= 0 && ySrc3 == xDst)
  80. {
  81. break;
  82. }
  83. }
  84. short yDst;
  85. if (GetOpcodeDestRegister(ref Y, out yDst))
  86. {
  87. if (xDst == yDst && !propagationInline)
  88. {
  89. ended = true;
  90. break;
  91. }
  92. if (xSrc == yDst)
  93. {
  94. if (propagationInline)
  95. {
  96. ended = true;
  97. break;
  98. }
  99. ReplaceOpcodeDest(ref Y, xDst);
  100. for (int k = j + 1; k < lst.Count; k++)
  101. {
  102. OpCodeR Z = lst[k];
  103. bool replaced = false;
  104. short zSrc, zSrc2, zSrc3;
  105. short zDst;
  106. GetOpcodeDestRegister(ref Z, out zDst);
  107. if (GetOpcodeSourceRegister(ref Z, hasReturn, out zSrc, out zSrc2, out zSrc3))
  108. {
  109. if(zSrc == yDst)
  110. {
  111. replaced = true;
  112. ReplaceOpcodeSource(ref Z, 0, xDst);
  113. }
  114. if (zSrc2 == yDst)
  115. {
  116. replaced = true;
  117. ReplaceOpcodeSource(ref Z, 1, xDst);
  118. }
  119. if (zSrc3 == yDst)
  120. {
  121. replaced = true;
  122. ReplaceOpcodeSource(ref Z, 2, xDst);
  123. }
  124. }
  125. if (replaced)
  126. lst[k] = Z;
  127. if (zDst >= 0)
  128. {
  129. if (zDst == yDst)
  130. break;
  131. }
  132. }
  133. canRemove.Add(i);
  134. ended = true;
  135. lst[j] = Y;
  136. break;
  137. }
  138. }
  139. }
  140. /*if (!ended)
  141. {
  142. if (xDst < stackRegisterBegin)
  143. {
  144. pendingBCP.Add(i);
  145. throw new NotImplementedException();
  146. }
  147. }*/
  148. }
  149. }
  150. }
  151. }
  152. }
  153. }