2
0

aoptcpu.pas 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. {
  2. Copyright (c) 2015 by Jonas Maebe, member of the Free Pascal
  3. Development Team
  4. This unit implements the JVM optimizer object
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. Unit aoptcpu;
  19. {$i fpcdefs.inc}
  20. Interface
  21. uses cpubase, aasmtai, aopt, aoptcpub;
  22. Type
  23. TCpuAsmOptimizer = class(TAsmOptimizer)
  24. protected
  25. function RemoveDoubleSwap(var p: tai): boolean;
  26. function RemoveCommutativeSwap(var p: tai): boolean;
  27. function RemoveLoadLoadSwap(var p: tai): boolean;
  28. public
  29. { uses the same constructor as TAopObj }
  30. function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
  31. procedure PeepHoleOptPass2;override;
  32. function PostPeepHoleOptsCpu(var p: tai): boolean; override;
  33. End;
  34. Implementation
  35. uses
  36. aasmbase,aasmcpu,cgbase;
  37. function TCpuAsmOptimizer.RemoveDoubleSwap(var p: tai): boolean;
  38. var
  39. next, next2: tai;
  40. begin
  41. result:=false;
  42. { remove two successive "swap" instructions }
  43. if (taicpu(p).opcode=a_swap) and
  44. GetNextInstruction(p,next) and
  45. (next.typ=ait_instruction) and
  46. (taicpu(next).opcode=a_swap) then
  47. begin
  48. { can't be the instruction, must end in a return or so }
  49. next2:=tai(next.next);
  50. asml.remove(p);
  51. asml.remove(next);
  52. p.free;
  53. next.free;
  54. p:=next2;
  55. result:=true;
  56. end;
  57. end;
  58. { returns whether p is an instruction that does not consume any stack slots,
  59. and adds a new item on the stack that is one stack slot wide }
  60. function OpCreatesSingleStackSlot(p: tai): boolean;
  61. begin
  62. result:=
  63. (p.typ=ait_instruction) and
  64. (taicpu(p).opcode in
  65. [a_aload, a_aload_0, a_aload_1, a_aload_2, a_aload_3,
  66. a_bipush,
  67. a_fconst_0, a_fconst_1, a_fconst_2,
  68. a_fload, a_fload_0, a_fload_1, a_fload_2, a_fload_3,
  69. a_getstatic,
  70. a_iconst_m1, a_iconst_0, a_iconst_1, a_iconst_2, a_iconst_3,
  71. a_iconst_4, a_iconst_5,
  72. a_iload, a_iload_0, a_iload_1, a_iload_2, a_iload_3,
  73. a_new,
  74. a_sipush]);
  75. end;
  76. function OpIsCommutativeSingleSlots(p: tai): boolean;
  77. begin
  78. result:=
  79. (p.typ=ait_instruction) and
  80. (taicpu(p).opcode in
  81. [a_fadd, a_fmul,
  82. a_iadd, a_iand, a_imul, a_ior, a_ixor,
  83. a_pop2])
  84. end;
  85. function TCpuAsmOptimizer.RemoveCommutativeSwap(var p: tai): boolean;
  86. var
  87. next: tai;
  88. begin
  89. result:=false;
  90. if (taicpu(p).opcode<>a_swap) then
  91. exit;
  92. { if the next opcode is commutative operation, we can remove the swap }
  93. if GetNextInstruction(p,next) and
  94. OpIsCommutativeSingleSlots(next) then
  95. begin
  96. asml.remove(p);
  97. p.free;
  98. p:=next;
  99. result:=true;
  100. exit;
  101. end;
  102. end;
  103. function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
  104. var
  105. next, next2: tai;
  106. begin
  107. result:=false;
  108. case p.typ of
  109. ait_instruction:
  110. begin
  111. if RemoveDoubleSwap(p) or
  112. RemoveCommutativeSwap(p) then
  113. exit(true)
  114. end;
  115. else
  116. ;
  117. end;
  118. end;
  119. procedure TCpuAsmOptimizer.PeepHoleOptPass2;
  120. begin
  121. end;
  122. function TCpuAsmOptimizer.RemoveLoadLoadSwap(var p: tai): boolean;
  123. var
  124. next, prev1, prev2: tai;
  125. begin
  126. result:=false;
  127. if (taicpu(p).opcode<>a_swap) then
  128. exit;
  129. { if we can swap the previous two instructions that put the items on the
  130. stack, we can remove the swap -- only do this in PostPeepholeOpts,
  131. because this may make the temp alloc information invalid. Ideally, we
  132. should move the tempallocs around too }
  133. if GetLastInstruction(p,prev1) and
  134. OpCreatesSingleStackSlot(prev1) and
  135. GetLastInstruction(prev1,prev2) and
  136. OpCreatesSingleStackSlot(prev2) then
  137. begin
  138. next:=tai(p.next);
  139. asml.remove(prev2);
  140. asml.InsertAfter(prev2,prev1);
  141. asml.remove(p);
  142. p.free;
  143. p:=next;
  144. result:=true;
  145. end;
  146. end;
  147. function TCpuAsmOptimizer.PostPeepHoleOptsCpu(var p: tai): boolean;
  148. begin
  149. result:=
  150. (p.typ=ait_instruction) and
  151. RemoveLoadLoadSwap(p);
  152. end;
  153. begin
  154. casmoptimizer:=TCpuAsmOptimizer;
  155. End.