fpc/compiler/jvm/aoptcpu.pas
Jonas Maebe 281b3ad276 * fix case completeness and unreachable code warnings in compiler that would
be introduced by the next commit

git-svn-id: trunk@42046 -
2019-05-12 14:29:03 +00:00

187 lines
5.0 KiB
ObjectPascal

{
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.