Simplification.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. using ARMeilleure.IntermediateRepresentation;
  2. using System;
  3. using static ARMeilleure.IntermediateRepresentation.OperandHelper;
  4. namespace ARMeilleure.CodeGen.Optimizations
  5. {
  6. static class Simplification
  7. {
  8. public static void RunPass(Operation operation)
  9. {
  10. switch (operation.Instruction)
  11. {
  12. case Instruction.Add:
  13. TryEliminateBinaryOpComutative(operation, 0);
  14. break;
  15. case Instruction.BitwiseAnd:
  16. TryEliminateBitwiseAnd(operation);
  17. break;
  18. case Instruction.BitwiseOr:
  19. TryEliminateBitwiseOr(operation);
  20. break;
  21. case Instruction.BitwiseExclusiveOr:
  22. TryEliminateBitwiseExclusiveOr(operation);
  23. break;
  24. case Instruction.ConditionalSelect:
  25. TryEliminateConditionalSelect(operation);
  26. break;
  27. case Instruction.Divide:
  28. TryEliminateBinaryOpY(operation, 1);
  29. break;
  30. case Instruction.Multiply:
  31. TryEliminateBinaryOpComutative(operation, 1);
  32. break;
  33. case Instruction.ShiftLeft:
  34. case Instruction.ShiftRightSI:
  35. case Instruction.ShiftRightUI:
  36. case Instruction.Subtract:
  37. TryEliminateBinaryOpY(operation, 0);
  38. break;
  39. }
  40. }
  41. private static void TryEliminateBitwiseAnd(Operation operation)
  42. {
  43. // Try to recognize and optimize those 3 patterns (in order):
  44. // x & 0xFFFFFFFF == x, 0xFFFFFFFF & y == y,
  45. // x & 0x00000000 == 0x00000000, 0x00000000 & y == 0x00000000
  46. Operand x = operation.GetSource(0);
  47. Operand y = operation.GetSource(1);
  48. if (IsConstEqual(x, AllOnes(x.Type)))
  49. {
  50. operation.TurnIntoCopy(y);
  51. }
  52. else if (IsConstEqual(y, AllOnes(y.Type)))
  53. {
  54. operation.TurnIntoCopy(x);
  55. }
  56. else if (IsConstEqual(x, 0) || IsConstEqual(y, 0))
  57. {
  58. operation.TurnIntoCopy(Const(0));
  59. }
  60. }
  61. private static void TryEliminateBitwiseOr(Operation operation)
  62. {
  63. // Try to recognize and optimize those 3 patterns (in order):
  64. // x | 0x00000000 == x, 0x00000000 | y == y,
  65. // x | 0xFFFFFFFF == 0xFFFFFFFF, 0xFFFFFFFF | y == 0xFFFFFFFF
  66. Operand x = operation.GetSource(0);
  67. Operand y = operation.GetSource(1);
  68. if (IsConstEqual(x, 0))
  69. {
  70. operation.TurnIntoCopy(y);
  71. }
  72. else if (IsConstEqual(y, 0))
  73. {
  74. operation.TurnIntoCopy(x);
  75. }
  76. else if (IsConstEqual(x, AllOnes(x.Type)) || IsConstEqual(y, AllOnes(y.Type)))
  77. {
  78. operation.TurnIntoCopy(Const(AllOnes(x.Type)));
  79. }
  80. }
  81. private static void TryEliminateBitwiseExclusiveOr(Operation operation)
  82. {
  83. // Try to recognize and optimize those 2 patterns (in order):
  84. // x ^ y == 0x00000000 when x == y
  85. // 0x00000000 ^ y == y, x ^ 0x00000000 == x
  86. Operand x = operation.GetSource(0);
  87. Operand y = operation.GetSource(1);
  88. if (x == y && x.Type.IsInteger())
  89. {
  90. operation.TurnIntoCopy(Const(x.Type, 0));
  91. }
  92. else
  93. {
  94. TryEliminateBinaryOpComutative(operation, 0);
  95. }
  96. }
  97. private static void TryEliminateBinaryOpY(Operation operation, ulong comparand)
  98. {
  99. Operand x = operation.GetSource(0);
  100. Operand y = operation.GetSource(1);
  101. if (IsConstEqual(y, comparand))
  102. {
  103. operation.TurnIntoCopy(x);
  104. }
  105. }
  106. private static void TryEliminateBinaryOpComutative(Operation operation, ulong comparand)
  107. {
  108. Operand x = operation.GetSource(0);
  109. Operand y = operation.GetSource(1);
  110. if (IsConstEqual(x, comparand))
  111. {
  112. operation.TurnIntoCopy(y);
  113. }
  114. else if (IsConstEqual(y, comparand))
  115. {
  116. operation.TurnIntoCopy(x);
  117. }
  118. }
  119. private static void TryEliminateConditionalSelect(Operation operation)
  120. {
  121. Operand cond = operation.GetSource(0);
  122. if (cond.Kind != OperandKind.Constant)
  123. {
  124. return;
  125. }
  126. // The condition is constant, we can turn it into a copy, and select
  127. // the source based on the condition value.
  128. int srcIndex = cond.Value != 0 ? 1 : 2;
  129. Operand source = operation.GetSource(srcIndex);
  130. operation.TurnIntoCopy(source);
  131. }
  132. private static bool IsConstEqual(Operand operand, ulong comparand)
  133. {
  134. if (operand.Kind != OperandKind.Constant || !operand.Type.IsInteger())
  135. {
  136. return false;
  137. }
  138. return operand.Value == comparand;
  139. }
  140. private static ulong AllOnes(OperandType type)
  141. {
  142. switch (type)
  143. {
  144. case OperandType.I32: return ~0U;
  145. case OperandType.I64: return ~0UL;
  146. }
  147. throw new ArgumentException("Invalid operand type \"" + type + "\".");
  148. }
  149. }
  150. }