|
@@ -77,6 +77,7 @@ unit opttail;
|
|
|
tempnode : ttempcreatenode;
|
|
|
loadnode : tloadnode;
|
|
|
oldnodetree : tnode;
|
|
|
+ useaddr : boolean;
|
|
|
begin
|
|
|
{ no tail call found and replaced so far }
|
|
|
result:=false;
|
|
@@ -120,7 +121,10 @@ unit opttail;
|
|
|
paranode:=tcallparanode(usedcallnode.left);
|
|
|
while assigned(paranode) do
|
|
|
begin
|
|
|
- if paranode.parasym.varspez=vs_var then
|
|
|
+ useaddr:=(paranode.parasym.varspez in [vs_var,vs_constref]) or
|
|
|
+ ((paranode.parasym.varspez=vs_const) and
|
|
|
+ paramanager.push_addr_param(paranode.parasym.varspez,paranode.parasym.vardef,p.proccalloption));
|
|
|
+ if useaddr then
|
|
|
begin
|
|
|
tempnode:=ctempcreatenode.create(voidpointertype,voidpointertype.size,tt_persistent,true);
|
|
|
addstatement(calcstatements,tempnode);
|
|
@@ -146,7 +150,7 @@ unit opttail;
|
|
|
include(tloadnode(loadnode).loadnodeflags,loadnf_isinternal_ignoreconst);
|
|
|
|
|
|
{ load the address of the symbol instead of symbol }
|
|
|
- if paranode.parasym.varspez=vs_var then
|
|
|
+ if useaddr then
|
|
|
include(tloadnode(loadnode).loadnodeflags,loadnf_load_addr);
|
|
|
addstatement(copystatements,
|
|
|
cassignmentnode.create_internal(
|
|
@@ -206,14 +210,12 @@ unit opttail;
|
|
|
{ check if the parameters actually would support tail recursion elimination }
|
|
|
for i:=0 to p.paras.count-1 do
|
|
|
with tparavarsym(p.paras[i]) do
|
|
|
- if (varspez in [vs_out,{vs_var,}vs_constref]) or
|
|
|
- ((varspez=vs_const) and
|
|
|
- (paramanager.push_addr_param(varspez,vardef,p.proccalloption)) or
|
|
|
+ if (varspez=vs_out) or
|
|
|
{ parameters requiring tables are too complicated to handle
|
|
|
and slow down things anyways so a tail recursion call
|
|
|
makes no sense
|
|
|
}
|
|
|
- is_managed_type(vardef)) then
|
|
|
+ is_managed_type(vardef) then
|
|
|
exit;
|
|
|
|
|
|
labelsym:=clabelsym.create('$opttail');
|