mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-25 12:29:25 +02:00
* if left is a smaller type, then an extension operation for shr can be removed
git-svn-id: trunk@49231 -
This commit is contained in:
parent
e6045673ee
commit
71dc62dde6
@ -2948,6 +2948,11 @@ implementation
|
|||||||
gotsint:=true;
|
gotsint:=true;
|
||||||
result:=docheckremoveinttypeconvs(tunarynode(n).left);
|
result:=docheckremoveinttypeconvs(tunarynode(n).left);
|
||||||
end;
|
end;
|
||||||
|
shrn:
|
||||||
|
begin
|
||||||
|
result:=wasoriginallysmallerint(tbinarynode(n).left) and
|
||||||
|
docheckremoveinttypeconvs(tbinarynode(n).right);
|
||||||
|
end;
|
||||||
notn:
|
notn:
|
||||||
result:=docheckremoveinttypeconvs(tunarynode(n).left);
|
result:=docheckremoveinttypeconvs(tunarynode(n).left);
|
||||||
addn,muln,divn,modn,andn,shln:
|
addn,muln,divn,modn,andn,shln:
|
||||||
@ -2981,15 +2986,26 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
{ 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(level : dword;var n: tnode; todef: tdef; forceunsigned: boolean; signedtype,unsignedtype : tdef);
|
||||||
var
|
var
|
||||||
newblock: tblocknode;
|
newblock: tblocknode;
|
||||||
newstatements: tstatementnode;
|
newstatements: tstatementnode;
|
||||||
originaldivtree: tnode;
|
originaldivtree: tnode;
|
||||||
tempnode: ttempcreatenode;
|
tempnode: ttempcreatenode;
|
||||||
begin
|
begin
|
||||||
|
{ we may not recurse into shr nodes:
|
||||||
|
|
||||||
|
dword1:=dword1+((dword2+dword3) shr 2);
|
||||||
|
|
||||||
|
while we can remove an extension on the addition, we cannot remove it from the shr
|
||||||
|
}
|
||||||
|
if (n.nodetype=shrn) and (level<>0) then
|
||||||
|
begin
|
||||||
|
inserttypeconv_internal(n,todef);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
case n.nodetype of
|
case n.nodetype of
|
||||||
subn,addn,muln,divn,modn,xorn,andn,orn,shln:
|
subn,addn,muln,divn,modn,xorn,andn,orn,shln,shrn:
|
||||||
begin
|
begin
|
||||||
exclude(n.flags,nf_internal);
|
exclude(n.flags,nf_internal);
|
||||||
if not forceunsigned and
|
if not forceunsigned and
|
||||||
@ -2998,8 +3014,8 @@ implementation
|
|||||||
originaldivtree:=nil;
|
originaldivtree:=nil;
|
||||||
if n.nodetype in [divn,modn] then
|
if n.nodetype in [divn,modn] then
|
||||||
originaldivtree:=n.getcopy;
|
originaldivtree:=n.getcopy;
|
||||||
doremoveinttypeconvs(tbinarynode(n).left,signedtype,false,signedtype,unsignedtype);
|
doremoveinttypeconvs(level+1,tbinarynode(n).left,signedtype,false,signedtype,unsignedtype);
|
||||||
doremoveinttypeconvs(tbinarynode(n).right,signedtype,false,signedtype,unsignedtype);
|
doremoveinttypeconvs(level+1,tbinarynode(n).right,signedtype,false,signedtype,unsignedtype);
|
||||||
n.resultdef:=signedtype;
|
n.resultdef:=signedtype;
|
||||||
if n.nodetype in [divn,modn] then
|
if n.nodetype in [divn,modn] then
|
||||||
begin
|
begin
|
||||||
@ -3026,8 +3042,8 @@ implementation
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
doremoveinttypeconvs(tbinarynode(n).left,unsignedtype,forceunsigned,signedtype,unsignedtype);
|
doremoveinttypeconvs(level+1,tbinarynode(n).left,unsignedtype,forceunsigned,signedtype,unsignedtype);
|
||||||
doremoveinttypeconvs(tbinarynode(n).right,unsignedtype,forceunsigned,signedtype,unsignedtype);
|
doremoveinttypeconvs(level+1,tbinarynode(n).right,unsignedtype,forceunsigned,signedtype,unsignedtype);
|
||||||
n.resultdef:=unsignedtype;
|
n.resultdef:=unsignedtype;
|
||||||
end;
|
end;
|
||||||
//if ((n.nodetype=andn) and (tbinarynode(n).left.nodetype=ordconstn) and
|
//if ((n.nodetype=andn) and (tbinarynode(n).left.nodetype=ordconstn) and
|
||||||
@ -3044,12 +3060,12 @@ implementation
|
|||||||
if not forceunsigned and
|
if not forceunsigned and
|
||||||
is_signed(n.resultdef) then
|
is_signed(n.resultdef) then
|
||||||
begin
|
begin
|
||||||
doremoveinttypeconvs(tunarynode(n).left,signedtype,false,signedtype,unsignedtype);
|
doremoveinttypeconvs(level+1,tunarynode(n).left,signedtype,false,signedtype,unsignedtype);
|
||||||
n.resultdef:=signedtype;
|
n.resultdef:=signedtype;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
doremoveinttypeconvs(tunarynode(n).left,unsignedtype,forceunsigned,signedtype,unsignedtype);
|
doremoveinttypeconvs(level+1,tunarynode(n).left,unsignedtype,forceunsigned,signedtype,unsignedtype);
|
||||||
n.resultdef:=unsignedtype;
|
n.resultdef:=unsignedtype;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -3344,22 +3360,22 @@ implementation
|
|||||||
to 64 bit }
|
to 64 bit }
|
||||||
if (resultdef.size <= 4) and
|
if (resultdef.size <= 4) and
|
||||||
is_64bitint(left.resultdef) and
|
is_64bitint(left.resultdef) and
|
||||||
(left.nodetype in [subn,addn,muln,divn,modn,xorn,andn,orn,notn,unaryminusn,shln]) and
|
(left.nodetype in [subn,addn,muln,divn,modn,xorn,andn,orn,notn,unaryminusn,shln,shrn]) and
|
||||||
checkremovebiginttypeconvs(left,foundsint,[s8bit,u8bit,s16bit,u16bit,s32bit,u32bit],int64(low(longint)),high(cardinal)) then
|
checkremovebiginttypeconvs(left,foundsint,[s8bit,u8bit,s16bit,u16bit,s32bit,u32bit],int64(low(longint)),high(cardinal)) then
|
||||||
doremoveinttypeconvs(left,generrordef,not foundsint,s32inttype,u32inttype);
|
doremoveinttypeconvs(0,left,generrordef,not foundsint,s32inttype,u32inttype);
|
||||||
{$if defined(cpu16bitalu)}
|
{$if defined(cpu16bitalu)}
|
||||||
if (resultdef.size <= 2) and
|
if (resultdef.size <= 2) and
|
||||||
(is_32bitint(left.resultdef) or is_64bitint(left.resultdef)) and
|
(is_32bitint(left.resultdef) or is_64bitint(left.resultdef)) and
|
||||||
(left.nodetype in [subn,addn,muln,divn,modn,xorn,andn,orn,notn,unaryminusn,shln]) and
|
(left.nodetype in [subn,addn,muln,divn,modn,xorn,andn,orn,notn,unaryminusn,shln,shrn]) and
|
||||||
checkremovebiginttypeconvs(left,foundsint,[s8bit,u8bit,s16bit,u16bit],int64(low(smallint)),high(word)) then
|
checkremovebiginttypeconvs(left,foundsint,[s8bit,u8bit,s16bit,u16bit],int64(low(smallint)),high(word)) then
|
||||||
doremoveinttypeconvs(left,generrordef,not foundsint,s16inttype,u16inttype);
|
doremoveinttypeconvs(0,left,generrordef,not foundsint,s16inttype,u16inttype);
|
||||||
{$endif defined(cpu16bitalu)}
|
{$endif defined(cpu16bitalu)}
|
||||||
{$if defined(cpu8bitalu)}
|
{$if defined(cpu8bitalu)}
|
||||||
if (resultdef.size<left.resultdef.size) and
|
if (resultdef.size<left.resultdef.size) and
|
||||||
is_integer(left.resultdef) and
|
is_integer(left.resultdef) and
|
||||||
(left.nodetype in [subn,addn,muln,divn,modn,xorn,andn,orn,notn,unaryminusn,shln]) and
|
(left.nodetype in [subn,addn,muln,divn,modn,xorn,andn,orn,notn,unaryminusn,shln,shrn]) and
|
||||||
checkremovebiginttypeconvs(left,foundsint,[s8bit,u8bit],int64(low(shortint)),high(byte)) then
|
checkremovebiginttypeconvs(left,foundsint,[s8bit,u8bit],int64(low(shortint)),high(byte)) then
|
||||||
doremoveinttypeconvs(left,generrordef,not foundsint,s8inttype,u8inttype);
|
doremoveinttypeconvs(0,left,generrordef,not foundsint,s8inttype,u8inttype);
|
||||||
{$endif defined(cpu8bitalu)}
|
{$endif defined(cpu8bitalu)}
|
||||||
{ the above simplification may have left a redundant equal
|
{ the above simplification may have left a redundant equal
|
||||||
typeconv (e.g. int32 to int32). If that's the case, we remove it }
|
typeconv (e.g. int32 to int32). If that's the case, we remove it }
|
||||||
|
Loading…
Reference in New Issue
Block a user