* at -O3 level, convert i:=i and/or/xor k to the new in_[and/or/xor]_assign_x_y

inline nodes, which should generate better code for certain CPU targets,
  including x86. Note that the optimization isn't applied yet for all integer
  types (those that have extra implicit typecasts, inserted by the compiler,
  aren't handled yet).

git-svn-id: trunk@35685 -
This commit is contained in:
nickysn 2017-03-29 15:20:57 +00:00
parent f19ebe2acf
commit f29492bdea

View File

@ -589,8 +589,13 @@ implementation
end; end;
if cs_opt_level3 in current_settings.optimizerswitches then if cs_opt_level3 in current_settings.optimizerswitches then
begin begin
{ replace i:=i+k/i:=i-k by inc/dec(i,k)? } { replace i:=i+k by inc(i,k)
if (right.nodetype in [addn,subn]) and i:=i-k by dec(i,k)
i:=i and/or/xor k by in_[and/or/xor]_assign_x_y(i,k)
todo: for some integer types, there are extra implicit
typecasts inserted by the compiler; this code should be
updated to handle them as well }
if (right.nodetype in [addn,subn,andn,orn,xorn]) and
(taddnode(right).left.isequal(left)) and (taddnode(right).left.isequal(left)) and
is_integer(taddnode(right).left.resultdef) and is_integer(taddnode(right).left.resultdef) and
is_integer(taddnode(right).right.resultdef) and is_integer(taddnode(right).right.resultdef) and
@ -599,19 +604,38 @@ implementation
valid_for_var(taddnode(right).left,false) and valid_for_var(taddnode(right).left,false) and
not(might_have_sideeffects(taddnode(right).left)) then not(might_have_sideeffects(taddnode(right).left)) then
begin begin
if right.nodetype=addn then case right.nodetype of
newinlinenodetype:=in_inc_x addn:
newinlinenodetype:=in_inc_x;
subn:
newinlinenodetype:=in_dec_x;
andn:
newinlinenodetype:=in_and_assign_x_y;
orn:
newinlinenodetype:=in_or_assign_x_y;
xorn:
newinlinenodetype:=in_xor_assign_x_y;
else
internalerror(2017032901);
end;
if right.nodetype in [addn,subn] then
result:=cinlinenode.createintern(
newinlinenodetype,false,ccallparanode.create(
left,ccallparanode.create(taddnode(right).right,nil)))
else else
newinlinenodetype:=in_dec_x; result:=cinlinenode.createintern(
result:=cinlinenode.createintern( newinlinenodetype,false,ccallparanode.create(
newinlinenodetype,false,ccallparanode.create( taddnode(right).right,ccallparanode.create(left,nil)));
left,ccallparanode.create(taddnode(right).right,nil)));
left:=nil; left:=nil;
taddnode(right).right:=nil; taddnode(right).right:=nil;
exit; exit;
end; end;
{ replace i:=k+i by inc(i,k)? } { replace i:=k+i by inc(i,k)
if (right.nodetype=addn) and i:=k and/or/xor i by in_[and/or/xor]_assign_x_y(i,k)
todo: for some integer types, there are extra implicit
typecasts inserted by the compiler; this code should be
updated to handle them as well }
if (right.nodetype in [addn,andn,orn,xorn]) and
(taddnode(right).right.isequal(left)) and (taddnode(right).right.isequal(left)) and
is_integer(taddnode(right).left.resultdef) and is_integer(taddnode(right).left.resultdef) and
is_integer(taddnode(right).right.resultdef) and is_integer(taddnode(right).right.resultdef) and
@ -620,9 +644,26 @@ implementation
valid_for_var(taddnode(right).right,false) and valid_for_var(taddnode(right).right,false) and
not(might_have_sideeffects(taddnode(right).right)) then not(might_have_sideeffects(taddnode(right).right)) then
begin begin
result:=cinlinenode.createintern( case right.nodetype of
in_inc_x,false,ccallparanode.create( addn:
left,ccallparanode.create(taddnode(right).left,nil))); newinlinenodetype:=in_inc_x;
andn:
newinlinenodetype:=in_and_assign_x_y;
orn:
newinlinenodetype:=in_or_assign_x_y;
xorn:
newinlinenodetype:=in_xor_assign_x_y;
else
internalerror(2017032902);
end;
if right.nodetype=addn then
result:=cinlinenode.createintern(
newinlinenodetype,false,ccallparanode.create(
left,ccallparanode.create(taddnode(right).left,nil)))
else
result:=cinlinenode.createintern(
newinlinenodetype,false,ccallparanode.create(
taddnode(right).left,ccallparanode.create(left,nil)));
left:=nil; left:=nil;
taddnode(right).left:=nil; taddnode(right).left:=nil;
exit; exit;