diff options
author | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2020-08-30 20:53:59 +0000 |
---|---|---|
committer | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2020-08-30 20:53:59 +0000 |
commit | c463051a2959f0a71c556931a39e7b2e7a1726a3 (patch) | |
tree | 111b365d2d8c698e42c7955aca92c4ea3e2b0bc1 | |
parent | b625955efb7d1bc5f2706e6cf91852c49c492601 (diff) | |
download | fpc-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.pas | 4 | ||||
-rw-r--r-- | compiler/nld.pas | 2 | ||||
-rw-r--r-- | compiler/xtensa/cgcpu.pas | 10 | ||||
-rw-r--r-- | compiler/xtensa/cpupara.pas | 40 | ||||
-rw-r--r-- | compiler/xtensa/cpupi.pas | 22 |
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 |