mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-26 02:58:20 +02:00
* if a for loop does not change a variable, we can propate it if it is a constant, resolves #39726
This commit is contained in:
parent
8817e896db
commit
a1ee4e04ed
@ -55,9 +55,11 @@ unit optconstprop;
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
|
globtype,
|
||||||
pass_1,procinfo,compinnr,
|
pass_1,procinfo,compinnr,
|
||||||
symsym, symconst,
|
symsym, symconst,
|
||||||
nutils, nbas, ncnv, nld, nflw, ncal, ninl;
|
nutils, nbas, ncnv, nld, nflw, ncal, ninl,
|
||||||
|
optbase, optutils;
|
||||||
|
|
||||||
function check_written(var n: tnode; arg: pointer): foreachnoderesult;
|
function check_written(var n: tnode; arg: pointer): foreachnoderesult;
|
||||||
begin
|
begin
|
||||||
@ -71,7 +73,8 @@ unit optconstprop;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ propagates the constant assignment passed in arg into n }
|
{ propagates the constant assignment passed in arg into n, it returns true if
|
||||||
|
the search can continue with the next statement }
|
||||||
function replaceBasicAssign(var n: tnode; arg: tnode; var tree_modified: boolean): boolean;
|
function replaceBasicAssign(var n: tnode; arg: tnode; var tree_modified: boolean): boolean;
|
||||||
var
|
var
|
||||||
st2, oldnode: tnode;
|
st2, oldnode: tnode;
|
||||||
@ -131,6 +134,20 @@ unit optconstprop;
|
|||||||
if result then
|
if result then
|
||||||
replaceBasicAssign(tfornode(n).t1, arg, tree_modified2);
|
replaceBasicAssign(tfornode(n).t1, arg, tree_modified2);
|
||||||
tree_modified:=tree_modified or tree_modified2;
|
tree_modified:=tree_modified or tree_modified2;
|
||||||
|
if pi_dfaavailable in current_procinfo.flags then
|
||||||
|
begin
|
||||||
|
CalcDefSum(tfornode(n).t2);
|
||||||
|
{ the constant can propagete if is is not the counter variable ... }
|
||||||
|
if not(tassignmentnode(arg).left.isequal(tfornode(n).left)) and
|
||||||
|
{ if it is a temprefn or its address is not taken in case of loadn }
|
||||||
|
((tassignmentnode(arg).left.nodetype=temprefn) or not(tabstractvarsym(tloadnode(tassignmentnode(arg).left).symtableentry).addr_taken)) and
|
||||||
|
{ and no definition in the loop? }
|
||||||
|
not(DFASetIn(tfornode(n).t2.optinfo^.defsum,tassignmentnode(arg).left.optinfo^.index)) then
|
||||||
|
begin
|
||||||
|
replaceBasicAssign(tfornode(n).t2, arg, tree_modified3);
|
||||||
|
tree_modified:=tree_modified or tree_modified3;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
{ after a for node we cannot continue with our simple approach }
|
{ after a for node we cannot continue with our simple approach }
|
||||||
result:=false;
|
result:=false;
|
||||||
end
|
end
|
||||||
@ -317,6 +334,11 @@ unit optconstprop;
|
|||||||
is_constenumnode(a.right) or
|
is_constenumnode(a.right) or
|
||||||
is_conststringnode(a.right)) then
|
is_conststringnode(a.right)) then
|
||||||
begin
|
begin
|
||||||
|
{$ifdef DEBUG_CONSTPROP}
|
||||||
|
writeln('******************************* propagating ***********************************');
|
||||||
|
printnode(a);
|
||||||
|
writeln('*******************************************************************************');
|
||||||
|
{$endif DEBUG_CONSTPROP}
|
||||||
st2:=tstatementnode(tstatementnode(st).right);
|
st2:=tstatementnode(tstatementnode(st).right);
|
||||||
old:=@tstatementnode(st).right;
|
old:=@tstatementnode(st).right;
|
||||||
while assigned(st2) do
|
while assigned(st2) do
|
||||||
|
@ -1221,6 +1221,12 @@ implementation
|
|||||||
include(flags,pi_dfaavailable);
|
include(flags,pi_dfaavailable);
|
||||||
RedoDFA:=false;
|
RedoDFA:=false;
|
||||||
|
|
||||||
|
if cs_opt_constant_propagate in current_settings.optimizerswitches then
|
||||||
|
do_optconstpropagate(code);
|
||||||
|
|
||||||
|
if RedoDFA then
|
||||||
|
dfabuilder.redodfainfo(code);
|
||||||
|
|
||||||
if (cs_opt_loopstrength in current_settings.optimizerswitches)
|
if (cs_opt_loopstrength in current_settings.optimizerswitches)
|
||||||
{ our induction variable strength reduction doesn't like
|
{ our induction variable strength reduction doesn't like
|
||||||
for loops with more than one entry }
|
for loops with more than one entry }
|
||||||
|
Loading…
Reference in New Issue
Block a user