* base optimiser support for the JVM target

o jump threading only works for unconditional branches until now,
     as conditional ones have limited offsets

git-svn-id: trunk@31448 -
This commit is contained in:
Jonas Maebe 2015-08-29 10:08:19 +00:00
parent c3a7d76c68
commit 8c8657e2d5
9 changed files with 246 additions and 10 deletions

3
.gitattributes vendored
View File

@ -282,6 +282,9 @@ compiler/impdef.pas svneol=native#text/plain
compiler/import.pas svneol=native#text/plain
compiler/jvm/aasmcpu.pas svneol=native#text/plain
compiler/jvm/agjasmin.pas svneol=native#text/plain
compiler/jvm/aoptcpu.pas svneol=native#text/plain
compiler/jvm/aoptcpub.pas svneol=native#text/plain
compiler/jvm/aoptcpud.pas svneol=native#text/plain
compiler/jvm/cgcpu.pas svneol=native#text/plain
compiler/jvm/cpubase.pas svneol=native#text/plain
compiler/jvm/cpuinfo.pas svneol=native#text/plain

View File

@ -1,5 +1,5 @@
#
# Don't edit, this file is generated by FPCMake Version 2.0.0 [2015/06/28]
# Don't edit, this file is generated by FPCMake Version 2.0.0 [2015-07-28 rev 31240]
#
default: all
MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-haiku i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian i386-nativent i386-iphonesim i386-android i386-aros m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded powerpc-wii powerpc-aix sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-netbsd x86_64-solaris x86_64-openbsd x86_64-darwin x86_64-win64 x86_64-embedded x86_64-iphonesim x86_64-aros x86_64-dragonfly arm-linux arm-palmos arm-darwin arm-wince arm-gba arm-nds arm-embedded arm-symbian arm-android powerpc64-linux powerpc64-darwin powerpc64-embedded powerpc64-aix avr-embedded armeb-linux armeb-embedded mips-linux mipsel-linux mipsel-embedded mipsel-android jvm-java jvm-android i8086-msdos aarch64-linux aarch64-darwin
@ -526,7 +526,7 @@ ifeq ($(PPC_TARGET),mipsel)
override LOCALOPT+=-Fumips
endif
ifeq ($(PPC_TARGET),jvm)
override LOCALOPT+=-Fujvm -dNOOPT
override LOCALOPT+=-Fujvm
endif
ifeq ($(PPC_TARGET),i8086)
override LOCALOPT+=-Fux86
@ -2962,6 +2962,7 @@ endif
ifeq ($(OS_SOURCE),openbsd)
override FPCOPT+=-FD$(NEW_BINUTILS_PATH)
override FPCMAKEOPT+=-FD$(NEW_BINUTILS_PATH)
override FPMAKE_BUILD_OPT+=-FD$(NEW_BINUTILS_PATH)
endif
ifndef CROSSBOOTSTRAP
ifneq ($(BINUTILSPREFIX),)
@ -2974,6 +2975,7 @@ endif
ifndef CROSSCOMPILE
ifneq ($(BINUTILSPREFIX),)
override FPCMAKEOPT+=-XP$(BINUTILSPREFIX)
override FPMAKE_BUILD_OPT+=-XP$(BINUTILSPREFIX)
endif
endif
ifdef UNITDIR
@ -3073,6 +3075,9 @@ endif
ifdef OPT
override FPCOPT+=$(OPT)
endif
ifdef FPMAKEBUILDOPT
override FPMAKE_BUILD_OPT+=$(FPMAKEBUILDOPT)
endif
ifdef FPCOPTDEF
override FPCOPT+=$(addprefix -d,$(FPCOPTDEF))
endif
@ -3264,7 +3269,7 @@ endif
fpc_sourceinstall: distclean
$(MKDIR) $(INSTALL_SOURCEDIR)
$(COPYTREE) $(BASEDIR)/* $(INSTALL_SOURCEDIR)
fpc_exampleinstall: $(addsuffix _distclean,$(TARGET_EXAMPLEDIRS))
fpc_exampleinstall: $(EXAMPLEINSTALLTARGET) $(addsuffix _distclean,$(TARGET_EXAMPLEDIRS))
ifdef HASEXAMPLES
$(MKDIR) $(INSTALL_EXAMPLEDIR)
endif
@ -3436,6 +3441,10 @@ endif
ifdef DEBUGSYMEXT
-$(DEL) *$(DEBUGSYMEXT)
endif
ifdef LOCALFPMAKEBIN
-$(DEL) $(LOCALFPMAKEBIN)
-$(DEL) $(FPMAKEBINOBJ)
endif
fpc_distclean: cleanall
.PHONY: fpc_baseinfo
override INFORULES+=fpc_baseinfo

View File

@ -290,7 +290,7 @@ endif
# jvm specific
ifeq ($(PPC_TARGET),jvm)
override LOCALOPT+=-Fujvm -dNOOPT
override LOCALOPT+=-Fujvm
endif
# i8086 specific

View File

@ -1239,7 +1239,7 @@ Unit AoptObj;
if { the next instruction after the label where the jump hp arrives}
{ is unconditional or of the same type as hp, so continue }
IsJumpToLabel(taicpu(p1))
{$ifndef MIPS}
{$if not defined(MIPS) and not defined(JVM)}
{ for MIPS, it isn't enough to check the condition; first operands must be same, too. }
or
conditions_equal(taicpu(p1).condition,hp.condition) or
@ -1256,7 +1256,7 @@ Unit AoptObj;
(IsJumpToLabel(taicpu(p2)) or
(conditions_equal(taicpu(p2).condition,hp.condition))) and
SkipLabels(p1,p1))
{$endif MIPS}
{$endif not MIPS and not JVM}
then
begin
{ quick check for loops of the form "l5: ; jmp l5 }
@ -1277,7 +1277,7 @@ Unit AoptObj;
JumpTargetOp(hp)^.ref^.symbol:=JumpTargetOp(taicpu(p1))^.ref^.symbol;
tasmlabel(JumpTargetOp(hp)^.ref^.symbol).increfs;
end
{$ifndef MIPS}
{$if not defined(MIPS) and not defined(JVM)}
else
if conditions_equal(taicpu(p1).condition,inverse_cond(hp.condition)) then
if not FindAnyLabel(p1,l) then
@ -1308,7 +1308,7 @@ Unit AoptObj;
if not GetFinalDestination(hp,succ(level)) then
exit;
end;
{$endif not MIPS}
{$endif not MIPS and not JVM}
end;
GetFinalDestination := true;
end;
@ -1357,7 +1357,11 @@ Unit AoptObj;
begin
hp2:=p;
while GetNextInstruction(hp2, hp1) and
(hp1.typ <> ait_label) do
(hp1.typ <> ait_label)
{$ifdef JVM}
and (hp1.typ <> ait_jcatch)
{$endif}
do
if not(hp1.typ in ([ait_label,ait_align]+skipinstr)) then
begin
if (hp1.typ = ait_instruction) and

View File

@ -123,7 +123,7 @@ implementation
ops:=1;
is_jmp:=op in [a_if_acmpeq, a_if_acmpne, a_if_icmpeq, a_if_icmpge, a_if_icmpgt,
a_if_icmple, a_if_icmplt, a_if_icmpne,
a_ifeq, a_ifge, a_ifgt, a_ifle, a_iflt, a_ifne, a_ifnonnull, a_ifnull];
a_ifeq, a_ifge, a_ifgt, a_ifle, a_iflt, a_ifne, a_ifnonnull, a_ifnull, a_goto];
loadsymbol(0,_op1,0);
end;

58
compiler/jvm/aoptcpu.pas Normal file
View File

@ -0,0 +1,58 @@
{
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)
{ uses the same constructor as TAopObj }
function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
procedure PeepHoleOptPass2;override;
End;
Implementation
uses
aasmbase,aasmcpu,cgbase;
function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
begin
result := false;
end;
procedure TCpuAsmOptimizer.PeepHoleOptPass2;
begin
end;
begin
casmoptimizer:=TCpuAsmOptimizer;
End.

115
compiler/jvm/aoptcpub.pas Normal file
View File

@ -0,0 +1,115 @@
{
Copyright (c) 2015 by Jonas Maebe, member of the Free Pascal
Development Team
This unit contains several types and constants necessary for the
optimizer to work on the JVM architecture
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 aoptcpub; { Assembler OPTimizer CPU specific Base }
{$i fpcdefs.inc}
{ enable the following define if memory references can have a scaled index }
{ define RefsHaveScale}
{ enable the following define if memory references can have a segment }
{ override }
{ define RefsHaveSegment}
Interface
Uses
aasmcpu,AOptBase, cpubase;
Type
{ type of a normal instruction }
TInstr = Taicpu;
PInstr = ^TInstr;
{ ************************************************************************* }
{ **************************** TCondRegs ********************************** }
{ ************************************************************************* }
{ Info about the conditional registers }
TCondRegs = Object
Constructor Init;
Destructor Done;
End;
{ ************************************************************************* }
{ **************************** TAoptBaseCpu ******************************* }
{ ************************************************************************* }
TAoptBaseCpu = class(TAoptBase)
End;
{ ************************************************************************* }
{ ******************************* Constants ******************************* }
{ ************************************************************************* }
Const
{ the maximum number of things (registers, memory, ...) a single instruction }
{ changes }
MaxCh = 2;
{ the maximum number of operands an instruction has }
MaxOps = 2;
{Oper index of operand that contains the source (reference) with a load }
{instruction }
LoadSrc = 1;
{Oper index of operand that contains the destination (register) with a load }
{instruction }
// LoadDst = 0;
{Oper index of operand that contains the source (register) with a store }
{instruction }
// StoreSrc = 0;
{Oper index of operand that contains the destination (reference) with a load }
{instruction }
StoreDst = 1;
aopt_uncondjmp = A_GOTO;
aopt_condjmp = A_NONE;
Implementation
{ ************************************************************************* }
{ **************************** TCondRegs ********************************** }
{ ************************************************************************* }
Constructor TCondRegs.init;
Begin
End;
Destructor TCondRegs.Done; {$ifdef inl} inline; {$endif inl}
Begin
End;
End.

34
compiler/jvm/aoptcpud.pas Normal file
View File

@ -0,0 +1,34 @@
{
Copyright (c) 1998-2002 by Jonas Maebe, member of the Free Pascal
Development Team
This unit contains the processor specific implementation of the
assembler optimizer data flow analyzer.
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 aoptcpud;
{$i fpcdefs.inc}
Interface
Implementation
End.

View File

@ -288,9 +288,16 @@ uses
function std_regname(r:Tregister):string;
function findreg_by_number(r:Tregister):tregisterindex;
{ since we don't use tasmconds, don't call this routine
(it will internalerror). We need it anyway to get aoptobj
to compile (but it won't execute it).
}
function inverse_cond(const c: TAsmCond): Tasmcond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
implementation
uses
verbose,
rgbase;
{*****************************************************************************
@ -345,4 +352,10 @@ uses
end;
function inverse_cond(const c: TAsmCond): Tasmcond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
begin
result:=C_None;
internalerror(2015082701);
end;
end.