mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 22:47:59 +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;
|
||||
result:=docheckremoveinttypeconvs(tunarynode(n).left);
|
||||
end;
|
||||
shrn:
|
||||
begin
|
||||
result:=wasoriginallysmallerint(tbinarynode(n).left) and
|
||||
docheckremoveinttypeconvs(tbinarynode(n).right);
|
||||
end;
|
||||
notn:
|
||||
result:=docheckremoveinttypeconvs(tunarynode(n).left);
|
||||
addn,muln,divn,modn,andn,shln:
|
||||
@ -2981,15 +2986,26 @@ implementation
|
||||
|
||||
|
||||
{ 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
|
||||
newblock: tblocknode;
|
||||
newstatements: tstatementnode;
|
||||
originaldivtree: tnode;
|
||||
tempnode: ttempcreatenode;
|
||||
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
|
||||
subn,addn,muln,divn,modn,xorn,andn,orn,shln:
|
||||
subn,addn,muln,divn,modn,xorn,andn,orn,shln,shrn:
|
||||
begin
|
||||
exclude(n.flags,nf_internal);
|
||||
if not forceunsigned and
|
||||
@ -2998,8 +3014,8 @@ implementation
|
||||
originaldivtree:=nil;
|
||||
if n.nodetype in [divn,modn] then
|
||||
originaldivtree:=n.getcopy;
|
||||
doremoveinttypeconvs(tbinarynode(n).left,signedtype,false,signedtype,unsignedtype);
|
||||
doremoveinttypeconvs(tbinarynode(n).right,signedtype,false,signedtype,unsignedtype);
|
||||
doremoveinttypeconvs(level+1,tbinarynode(n).left,signedtype,false,signedtype,unsignedtype);
|
||||
doremoveinttypeconvs(level+1,tbinarynode(n).right,signedtype,false,signedtype,unsignedtype);
|
||||
n.resultdef:=signedtype;
|
||||
if n.nodetype in [divn,modn] then
|
||||
begin
|
||||
@ -3026,8 +3042,8 @@ implementation
|
||||
end
|
||||
else
|
||||
begin
|
||||
doremoveinttypeconvs(tbinarynode(n).left,unsignedtype,forceunsigned,signedtype,unsignedtype);
|
||||
doremoveinttypeconvs(tbinarynode(n).right,unsignedtype,forceunsigned,signedtype,unsignedtype);
|
||||
doremoveinttypeconvs(level+1,tbinarynode(n).left,unsignedtype,forceunsigned,signedtype,unsignedtype);
|
||||
doremoveinttypeconvs(level+1,tbinarynode(n).right,unsignedtype,forceunsigned,signedtype,unsignedtype);
|
||||
n.resultdef:=unsignedtype;
|
||||
end;
|
||||
//if ((n.nodetype=andn) and (tbinarynode(n).left.nodetype=ordconstn) and
|
||||
@ -3044,12 +3060,12 @@ implementation
|
||||
if not forceunsigned and
|
||||
is_signed(n.resultdef) then
|
||||
begin
|
||||
doremoveinttypeconvs(tunarynode(n).left,signedtype,false,signedtype,unsignedtype);
|
||||
doremoveinttypeconvs(level+1,tunarynode(n).left,signedtype,false,signedtype,unsignedtype);
|
||||
n.resultdef:=signedtype;
|
||||
end
|
||||
else
|
||||
begin
|
||||
doremoveinttypeconvs(tunarynode(n).left,unsignedtype,forceunsigned,signedtype,unsignedtype);
|
||||
doremoveinttypeconvs(level+1,tunarynode(n).left,unsignedtype,forceunsigned,signedtype,unsignedtype);
|
||||
n.resultdef:=unsignedtype;
|
||||
end;
|
||||
end;
|
||||
@ -3344,22 +3360,22 @@ implementation
|
||||
to 64 bit }
|
||||
if (resultdef.size <= 4) 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
|
||||
doremoveinttypeconvs(left,generrordef,not foundsint,s32inttype,u32inttype);
|
||||
doremoveinttypeconvs(0,left,generrordef,not foundsint,s32inttype,u32inttype);
|
||||
{$if defined(cpu16bitalu)}
|
||||
if (resultdef.size <= 2) 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
|
||||
doremoveinttypeconvs(left,generrordef,not foundsint,s16inttype,u16inttype);
|
||||
doremoveinttypeconvs(0,left,generrordef,not foundsint,s16inttype,u16inttype);
|
||||
{$endif defined(cpu16bitalu)}
|
||||
{$if defined(cpu8bitalu)}
|
||||
if (resultdef.size<left.resultdef.size) 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
|
||||
doremoveinttypeconvs(left,generrordef,not foundsint,s8inttype,u8inttype);
|
||||
doremoveinttypeconvs(0,left,generrordef,not foundsint,s8inttype,u8inttype);
|
||||
{$endif defined(cpu8bitalu)}
|
||||
{ the above simplification may have left a redundant equal
|
||||
typeconv (e.g. int32 to int32). If that's the case, we remove it }
|
||||
|
Loading…
Reference in New Issue
Block a user