mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-30 07:40:27 +02:00
+ optimization type converted (modulo) divisions as well by removing up/down converting but,
insert a test and separate code path for -1 if needed git-svn-id: trunk@47521 -
This commit is contained in:
parent
ebb199b9d4
commit
ea11517d27
@ -322,7 +322,7 @@ implementation
|
|||||||
globtype,systems,constexp,compinnr,
|
globtype,systems,constexp,compinnr,
|
||||||
cutils,verbose,globals,widestr,ppu,
|
cutils,verbose,globals,widestr,ppu,
|
||||||
symconst,symdef,symsym,symcpu,symtable,
|
symconst,symdef,symsym,symcpu,symtable,
|
||||||
ncon,ncal,nset,nadd,nmem,nmat,nbas,nutils,ninl,
|
ncon,ncal,nset,nadd,nmem,nmat,nbas,nutils,ninl,nflw,
|
||||||
cgbase,procinfo,
|
cgbase,procinfo,
|
||||||
htypechk,blockutl,pass_1,cpuinfo;
|
htypechk,blockutl,pass_1,cpuinfo;
|
||||||
|
|
||||||
@ -2872,6 +2872,9 @@ implementation
|
|||||||
|
|
||||||
function checkremovebiginttypeconvs(n: tnode; out gotsint: boolean;validints : tordtypeset;const l,h : Tconstexprint): boolean;
|
function checkremovebiginttypeconvs(n: tnode; out gotsint: boolean;validints : tordtypeset;const l,h : Tconstexprint): boolean;
|
||||||
var
|
var
|
||||||
|
gotminus1,
|
||||||
|
gotsigned,
|
||||||
|
gotunsigned,
|
||||||
gotdivmod: boolean;
|
gotdivmod: boolean;
|
||||||
|
|
||||||
{ checks whether a node has an accepted resultdef, or originally
|
{ checks whether a node has an accepted resultdef, or originally
|
||||||
@ -2880,6 +2883,13 @@ implementation
|
|||||||
begin
|
begin
|
||||||
if (n.resultdef.typ<>orddef) then
|
if (n.resultdef.typ<>orddef) then
|
||||||
exit(false);
|
exit(false);
|
||||||
|
gotsigned:=gotsigned or is_signed(n.resultdef);
|
||||||
|
gotunsigned:=gotunsigned or not(is_signed(n.resultdef));
|
||||||
|
{ actually, we should only check right (denominator) nodes here, but
|
||||||
|
setting it always is a safe approximation }
|
||||||
|
if ((n.nodetype=ordconstn) and
|
||||||
|
(tordconstnode(n).value=-1)) then
|
||||||
|
gotminus1:=true;
|
||||||
if (torddef(n.resultdef).ordtype in validints) then
|
if (torddef(n.resultdef).ordtype in validints) then
|
||||||
begin
|
begin
|
||||||
if is_signed(n.resultdef) then
|
if is_signed(n.resultdef) then
|
||||||
@ -2904,7 +2914,12 @@ implementation
|
|||||||
is_signed(ttypeconvnode(n).left.resultdef)) or
|
is_signed(ttypeconvnode(n).left.resultdef)) or
|
||||||
((n.nodetype=ordconstn) and
|
((n.nodetype=ordconstn) and
|
||||||
(tordconstnode(n).value<0)) then
|
(tordconstnode(n).value<0)) then
|
||||||
gotsint:=true;
|
begin
|
||||||
|
gotsint:=true;
|
||||||
|
gotsigned:=true;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
gotunsigned:=true;
|
||||||
exit(true);
|
exit(true);
|
||||||
end;
|
end;
|
||||||
result:=false;
|
result:=false;
|
||||||
@ -2938,7 +2953,10 @@ implementation
|
|||||||
gotdivmod:=true;
|
gotdivmod:=true;
|
||||||
result:=
|
result:=
|
||||||
(docheckremoveinttypeconvs(tbinarynode(n).left) and
|
(docheckremoveinttypeconvs(tbinarynode(n).left) and
|
||||||
docheckremoveinttypeconvs(tbinarynode(n).right)) or
|
docheckremoveinttypeconvs(tbinarynode(n).right) and
|
||||||
|
|
||||||
|
(not(n.nodetype in [modn,divn]) or (not(gotminus1)))
|
||||||
|
) or
|
||||||
{ in case of div/mod, the result of that division/modulo can
|
{ in case of div/mod, the result of that division/modulo can
|
||||||
usually be different in 32 and 64 bit }
|
usually be different in 32 and 64 bit }
|
||||||
(not gotdivmod and
|
(not gotdivmod and
|
||||||
@ -2953,14 +2971,22 @@ implementation
|
|||||||
begin { checkremove64bittypeconvs }
|
begin { checkremove64bittypeconvs }
|
||||||
gotdivmod:=false;
|
gotdivmod:=false;
|
||||||
gotsint:=false;
|
gotsint:=false;
|
||||||
|
gotminus1:=false;
|
||||||
|
gotsigned:=false;
|
||||||
|
gotunsigned:=false;
|
||||||
result:=
|
result:=
|
||||||
docheckremoveinttypeconvs(n) and
|
docheckremoveinttypeconvs(n) and
|
||||||
not(gotdivmod and gotsint);
|
(not(gotdivmod) or (gotsigned xor gotunsigned));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ remove int type conversions and set the result to the given type }
|
{ remove int type conversions and set the result to the given type }
|
||||||
procedure doremoveinttypeconvs(var n: tnode; todef: tdef; forceunsigned: boolean; signedtype,unsignedtype : tdef);
|
procedure doremoveinttypeconvs(var n: tnode; todef: tdef; forceunsigned: boolean; signedtype,unsignedtype : tdef);
|
||||||
|
var
|
||||||
|
newblock: tblocknode;
|
||||||
|
newstatements: tstatementnode;
|
||||||
|
originaldivtree: tnode;
|
||||||
|
tempnode: ttempcreatenode;
|
||||||
begin
|
begin
|
||||||
case n.nodetype of
|
case n.nodetype of
|
||||||
subn,addn,muln,divn,modn,xorn,andn,orn:
|
subn,addn,muln,divn,modn,xorn,andn,orn:
|
||||||
@ -2969,9 +2995,34 @@ implementation
|
|||||||
if not forceunsigned and
|
if not forceunsigned and
|
||||||
is_signed(n.resultdef) then
|
is_signed(n.resultdef) then
|
||||||
begin
|
begin
|
||||||
|
originaldivtree:=nil;
|
||||||
|
if n.nodetype in [divn,modn] then
|
||||||
|
originaldivtree:=n.getcopy;
|
||||||
doremoveinttypeconvs(tbinarynode(n).left,signedtype,false,signedtype,unsignedtype);
|
doremoveinttypeconvs(tbinarynode(n).left,signedtype,false,signedtype,unsignedtype);
|
||||||
doremoveinttypeconvs(tbinarynode(n).right,signedtype,false,signedtype,unsignedtype);
|
doremoveinttypeconvs(tbinarynode(n).right,signedtype,false,signedtype,unsignedtype);
|
||||||
n.resultdef:=signedtype;
|
n.resultdef:=signedtype;
|
||||||
|
if n.nodetype in [divn,modn] then
|
||||||
|
begin
|
||||||
|
newblock:=internalstatements(newstatements);
|
||||||
|
tempnode:=ctempcreatenode.create(n.resultdef,n.resultdef.size,tt_persistent,true);
|
||||||
|
addstatement(newstatements,tempnode);
|
||||||
|
addstatement(newstatements,cifnode.create_internal(
|
||||||
|
caddnode.create_internal(equaln,tbinarynode(n).right.getcopy,cordconstnode.create(-1,n.resultdef,false)),
|
||||||
|
cassignmentnode.create_internal(
|
||||||
|
ctemprefnode.create(tempnode),
|
||||||
|
cmoddivnode.create(n.nodetype,tbinarynode(originaldivtree).left.getcopy,cordconstnode.create(-1,tbinarynode(originaldivtree).right.resultdef,false))
|
||||||
|
),
|
||||||
|
cassignmentnode.create_internal(
|
||||||
|
ctemprefnode.create(tempnode),n
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
addstatement(newstatements,ctempdeletenode.create_normal_temp(tempnode));
|
||||||
|
addstatement(newstatements,ctemprefnode.create(tempnode));
|
||||||
|
n:=newblock;
|
||||||
|
do_typecheckpass(n);
|
||||||
|
originaldivtree.free;
|
||||||
|
end;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
|
Loading…
Reference in New Issue
Block a user