123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- {
- Copyright (c) 2015 by Jonas Maebe, member of the Free Pascal
- Development Team
- This unit implements the JVM optimizer object
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ****************************************************************************
- }
- Unit aoptcpu;
- {$i fpcdefs.inc}
- Interface
- uses cpubase, aasmtai, aopt, aoptcpub;
- Type
- TCpuAsmOptimizer = class(TAsmOptimizer)
- protected
- function RemoveDoubleSwap(var p: tai): boolean;
- function RemoveCommutativeSwap(var p: tai): boolean;
- function RemoveLoadLoadSwap(var p: tai): boolean;
- public
- { uses the same constructor as TAopObj }
- function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
- procedure PeepHoleOptPass2;override;
- function PostPeepHoleOptsCpu(var p: tai): boolean; override;
- End;
- Implementation
- uses
- aasmbase,aasmcpu,cgbase;
- function TCpuAsmOptimizer.RemoveDoubleSwap(var p: tai): boolean;
- var
- next, next2: tai;
- begin
- result:=false;
- { remove two successive "swap" instructions }
- if (taicpu(p).opcode=a_swap) and
- GetNextInstruction(p,next) and
- (next.typ=ait_instruction) and
- (taicpu(next).opcode=a_swap) then
- begin
- { can't be the instruction, must end in a return or so }
- next2:=tai(next.next);
- asml.remove(p);
- asml.remove(next);
- p.free;
- next.free;
- p:=next2;
- result:=true;
- end;
- end;
- { returns whether p is an instruction that does not consume any stack slots,
- and adds a new item on the stack that is one stack slot wide }
- function OpCreatesSingleStackSlot(p: tai): boolean;
- begin
- result:=
- (p.typ=ait_instruction) and
- (taicpu(p).opcode in
- [a_aload, a_aload_0, a_aload_1, a_aload_2, a_aload_3,
- a_bipush,
- a_fconst_0, a_fconst_1, a_fconst_2,
- a_fload, a_fload_0, a_fload_1, a_fload_2, a_fload_3,
- a_getstatic,
- a_iconst_m1, a_iconst_0, a_iconst_1, a_iconst_2, a_iconst_3,
- a_iconst_4, a_iconst_5,
- a_iload, a_iload_0, a_iload_1, a_iload_2, a_iload_3,
- a_new,
- a_sipush]);
- end;
- function OpIsCommutativeSingleSlots(p: tai): boolean;
- begin
- result:=
- (p.typ=ait_instruction) and
- (taicpu(p).opcode in
- [a_fadd, a_fmul,
- a_iadd, a_iand, a_imul, a_ior, a_ixor,
- a_pop2])
- end;
- function TCpuAsmOptimizer.RemoveCommutativeSwap(var p: tai): boolean;
- var
- next: tai;
- begin
- result:=false;
- if (taicpu(p).opcode<>a_swap) then
- exit;
- { if the next opcode is commutative operation, we can remove the swap }
- if GetNextInstruction(p,next) and
- OpIsCommutativeSingleSlots(next) then
- begin
- asml.remove(p);
- p.free;
- p:=next;
- result:=true;
- exit;
- end;
- end;
- function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
- var
- next, next2: tai;
- begin
- result:=false;
- case p.typ of
- ait_instruction:
- begin
- if RemoveDoubleSwap(p) or
- RemoveCommutativeSwap(p) then
- exit(true)
- end;
- else
- ;
- end;
- end;
- procedure TCpuAsmOptimizer.PeepHoleOptPass2;
- begin
- end;
- function TCpuAsmOptimizer.RemoveLoadLoadSwap(var p: tai): boolean;
- var
- next, prev1, prev2: tai;
- begin
- result:=false;
- if (taicpu(p).opcode<>a_swap) then
- exit;
- { if we can swap the previous two instructions that put the items on the
- stack, we can remove the swap -- only do this in PostPeepholeOpts,
- because this may make the temp alloc information invalid. Ideally, we
- should move the tempallocs around too }
- if GetLastInstruction(p,prev1) and
- OpCreatesSingleStackSlot(prev1) and
- GetLastInstruction(prev1,prev2) and
- OpCreatesSingleStackSlot(prev2) then
- begin
- next:=tai(p.next);
- asml.remove(prev2);
- asml.InsertAfter(prev2,prev1);
- asml.remove(p);
- p.free;
- p:=next;
- result:=true;
- end;
- end;
- function TCpuAsmOptimizer.PostPeepHoleOptsCpu(var p: tai): boolean;
- begin
- result:=
- (p.typ=ait_instruction) and
- RemoveLoadLoadSwap(p);
- end;
- begin
- casmoptimizer:=TCpuAsmOptimizer;
- End.
|