summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2020-08-30 20:53:59 +0000
committerflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2020-08-30 20:53:59 +0000
commitc463051a2959f0a71c556931a39e7b2e7a1726a3 (patch)
tree111b365d2d8c698e42c7955aca92c4ea3e2b0bc1
parentb625955efb7d1bc5f2706e6cf91852c49c492601 (diff)
downloadfpc-c463051a2959f0a71c556931a39e7b2e7a1726a3.tar.gz
* better calculation of estimated stack frame size
git-svn-id: https://svn.freepascal.org/svn/fpc/trunk@46733 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r--compiler/ncal.pas4
-rw-r--r--compiler/nld.pas2
-rw-r--r--compiler/xtensa/cgcpu.pas10
-rw-r--r--compiler/xtensa/cpupara.pas40
-rw-r--r--compiler/xtensa/cpupi.pas22
5 files changed, 66 insertions, 12 deletions
diff --git a/compiler/ncal.pas b/compiler/ncal.pas
index e29ded90ea..84c7c61fec 100644
--- a/compiler/ncal.pas
+++ b/compiler/ncal.pas
@@ -4446,6 +4446,10 @@ implementation
not tabstractprocdef(right.resultdef).is_addressonly then
maybe_load_in_temp(right);
+ { the return value might be stored on the current stack by allocating a temp. }
+ if not(paramanager.ret_in_param(procdefinition.returndef,procdefinition)) then
+ inc(current_procinfo.estimatedtempsize,procdefinition.returndef.size);
+
{ Create destination (temp or assignment-variable reuse) for function result if it not yet set }
maybe_create_funcret_node;
diff --git a/compiler/nld.pas b/compiler/nld.pas
index e2bccbc080..ab05bd8776 100644
--- a/compiler/nld.pas
+++ b/compiler/nld.pas
@@ -1253,6 +1253,8 @@ implementation
if do_variant then
tarraydef(resultdef).elementdef:=search_system_type('TVARREC').typedef;
expectloc:=LOC_CREFERENCE;
+
+ inc(current_procinfo.estimatedtempsize,(tarraydef(resultdef).highrange+1)*tarraydef(resultdef).elementdef.size);
end;
diff --git a/compiler/xtensa/cgcpu.pas b/compiler/xtensa/cgcpu.pas
index c28b66cc54..8b2862867e 100644
--- a/compiler/xtensa/cgcpu.pas
+++ b/compiler/xtensa/cgcpu.pas
@@ -704,6 +704,7 @@ implementation
list.concat(tai_comment.Create(strpnew(' Max. outgoing parameter size: '+tostr(txtensaprocinfo(current_procinfo).maxpushedparasize))));
list.concat(tai_comment.Create(strpnew(' End of last temporary location: '+tostr(tg.lasttemp))));
list.concat(tai_comment.Create(strpnew(' Max. window rotation in bytes: '+tostr(txtensaprocinfo(current_procinfo).maxcall*4))));
+ list.concat(tai_comment.Create(strpnew(' Required size after code generation: '+tostr(localsize))));
{ should never happen as localsize is derived from
txtensaprocinfo(current_procinfo).stackframesize }
@@ -712,8 +713,15 @@ implementation
localsize:=txtensaprocinfo(current_procinfo).stackframesize;
end
else
- localsize:=align(localsize,current_settings.alignment.localalignmax);
+ begin
+ localsize:=align(localsize,current_settings.alignment.localalignmax);
+ inc(localsize,4*4);
+ if pi_do_call in current_procinfo.flags then
+ inc(localsize,txtensaprocinfo(current_procinfo).maxcall*4);
+ end;
+ if localsize<0 then
+ Internalerror(2020083001);
if localsize>32760 then
begin
list.concat(taicpu.op_reg_const(A_ENTRY,NR_STACK_POINTER_REG,32));
diff --git a/compiler/xtensa/cpupara.pas b/compiler/xtensa/cpupara.pas
index febc0ce201..3a4e3e3577 100644
--- a/compiler/xtensa/cpupara.pas
+++ b/compiler/xtensa/cpupara.pas
@@ -151,7 +151,7 @@ unit cpupara;
recorddef :
result:=(varspez = vs_const);
arraydef:
- result:=(tarraydef(def).highrange>=tarraydef(def).lowrange) or
+ result:=((varspez = vs_const) and (tarraydef(def).highrange>=tarraydef(def).lowrange)) or
is_open_array(def) or
is_array_of_const(def) or
is_array_constructor(def);
@@ -299,7 +299,9 @@ unit cpupara;
begin
init_values(p,side,curintreg,cur_stack_offset);
- result := create_paraloc_info_intern(p,side,p.paras,curintreg,cur_stack_offset,false);
+ result:=create_paraloc_info_intern(p,side,p.paras,curintreg,cur_stack_offset,false);
+ if result<cur_stack_offset then
+ Internalerror(2020083001);
create_funcretloc_info(p,side);
end;
@@ -327,6 +329,20 @@ unit cpupara;
if po_explicitparaloc in p.procoptions then
internalerror(200411141);
{$endif extdebug}
+ loc.reset;
+ { currently only support C-style array of const }
+ if (p.proccalloption in cstylearrayofconst) and
+ is_array_of_const(paradef) then
+ begin
+ paraloc:=loc.add_location;
+ { hack: the paraloc must be valid, but is not actually used }
+ paraloc^.loc := LOC_REGISTER;
+ paraloc^.register := NR_A2;
+ paraloc^.size := OS_ADDR;
+ paraloc^.def:=voidpointertype;
+ result:=cur_stack_offset;
+ exit;
+ end;
result:=0;
nextintreg := curintreg;
@@ -469,12 +485,32 @@ unit cpupara;
end;
paralen := 0;
end;
+<<<<<<< HEAD
firstparaloc:=false;
end;
end;
curintreg:=nextintreg;
cur_stack_offset:=stack_offset;
result:=stack_offset;
+=======
+ paralen := 0;
+ end;
+ firstparaloc:=false;
+ end;
+ result:=cur_stack_offset;
+ end;
+
+
+ function tcpuparamanager.create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras:tparalist;
+ var curintreg: tsuperregister; var cur_stack_offset: aword; varargsparas: boolean):longint;
+ var
+ i : integer;
+ begin
+ result:=0;
+ for i:=0 to paras.count-1 do
+ result:=create_paraloc1_info_intern(p,side,tparavarsym(paras[i]).vardef,tparavarsym(paras[i]).paraloc[side],tparavarsym(paras[i]).varspez,
+ tparavarsym(paras[i]).varoptions,curintreg,cur_stack_offset,false);
+>>>>>>> 7962bf60e6... * squash stack frame size
end;
diff --git a/compiler/xtensa/cpupi.pas b/compiler/xtensa/cpupi.pas
index 014334becc..abda6612ae 100644
--- a/compiler/xtensa/cpupi.pas
+++ b/compiler/xtensa/cpupi.pas
@@ -76,7 +76,6 @@ unit cpupi;
maxcall:=8;
{ we do not use a frame pointer for the windowed abi }
- include(flags,pi_estimatestacksize);
framepointer:=NR_STACK_POINTER_REG;
end
else
@@ -94,7 +93,7 @@ unit cpupi;
localsize : aint;
i : longint;
begin
- maxpushedparasize:=Align(maxpushedparasize,4);
+ maxpushedparasize:=Align(maxpushedparasize,target_info.alignment.localalignmax);
tg.setfirsttemp(maxpushedparasize);
if po_nostackframe in procdef.procoptions then
@@ -127,13 +126,16 @@ unit cpupi;
inc(localsize,256)
else
begin
- localsize:=align(localsize,tabstractnormalvarsym(procdef.parast.SymList[i]).vardef.alignment);
+ localsize:=align(localsize,tparavarsym(procdef.parast.SymList[i]).paraloc[calleeside].alignment);
inc(localsize,tabstractnormalvarsym(procdef.parast.SymList[i]).getsize);
end;
end;
inc(stackframesize,localsize);
- stackframesize:=align(stackframesize,4);
+ stackframesize:=align(stackframesize,target_info.alignment.localalignmax);
+ inc(stackframesize,estimatedtempsize);
+
+ stackframesize:=align(stackframesize,4);
if pi_needs_implicit_finally in flags then
inc(stackframesize,40);
@@ -150,8 +152,6 @@ unit cpupi;
if pi_do_call in current_procinfo.flags then
inc(stackframesize,maxcall*4);
- inc(stackframesize,estimatedtempsize);
-
stackframesize:=Align(stackframesize,target_info.alignment.localalignmax);
end;
end;
@@ -159,13 +159,17 @@ unit cpupi;
function txtensaprocinfo.calc_stackframe_size:longint;
var
- r : byte;
+ r, extra: byte;
regs: tcpuregisterset;
begin
- maxpushedparasize:=align(maxpushedparasize,max(current_settings.alignment.localalignmin,4));
+// maxpushedparasize:=align(maxpushedparasize,max(current_settings.alignment.localalignmin,4));
if pi_estimatestacksize in flags then
begin
- if Align(tg.direction*tg.lasttemp,max(current_settings.alignment.localalignmin,4))+4*4+maxcall*4>stackframesize then
+ if pi_do_call in current_procinfo.flags then
+ extra:=4*4+maxcall*4
+ else
+ extra:=0;
+ if Align(tg.direction*tg.lasttemp,max(current_settings.alignment.localalignmin,4))+extra>stackframesize then
InternalError(2020082801);
result:=stackframesize
end