From a76038e1d1eb5a07a2cab78044e793f947247457 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Fri, 27 May 2022 21:24:59 +0200 Subject: [PATCH] hlcgobj: new getlocal and recordnewsymloc methods Call hlcg.getlocal instead of tg.getlocal when used for actual parameters/local variables. Has an extra tsym parameter, which will enable the LLVM backend to insert debug information. Call hlcg.recordnewsymloc when the location of a (local/para) symbol changes, so debug info tracking can be updated (only done for LLVM currently) --- compiler/hlcgobj.pas | 20 ++++++++++++++++++- compiler/llvm/hlcgllvm.pas | 39 ++++++++++++++++++++++++++++++++++++++ compiler/ncgld.pas | 1 + compiler/ncgutil.pas | 6 +++--- 4 files changed, 62 insertions(+), 4 deletions(-) diff --git a/compiler/hlcgobj.pas b/compiler/hlcgobj.pas index 29df13be25..0ca2498872 100644 --- a/compiler/hlcgobj.pas +++ b/compiler/hlcgobj.pas @@ -638,6 +638,11 @@ unit hlcgobj; procedure gen_load_para_value(list:TAsmList);virtual; { helpers called by gen_load_para_value } procedure g_copyvalueparas(p:TObject;arg:pointer);virtual; + + { allocate a local temp to serve as storage for a para/localsym } + procedure getlocal(list: TAsmList; sym: tsym; size: asizeint; alignment: shortint; def: tdef; out ref : treference); + { the symbol is stored at this location from now on } + procedure recordnewsymloc(list: TAsmList; sym: tsym; def: tdef; const ref: treference); virtual; protected procedure gen_loadfpu_loc_cgpara(list: TAsmList; size: tdef; const l: tlocation;const cgpara: tcgpara;locintsize: longint);virtual; procedure init_paras(p:TObject;arg:pointer); @@ -5206,7 +5211,7 @@ implementation l:=tparavarsym(p).getsize; localcopyloc.loc:=LOC_REFERENCE; localcopyloc.size:=int_cgsize(l); - tg.GetLocal(list,l,tparavarsym(p).vardef,localcopyloc.reference); + getlocal(list,tparavarsym(p),l,tparavarsym(p).vardef.alignment,tparavarsym(p).vardef,localcopyloc.reference); { Copy data } if is_shortstring(tparavarsym(p).vardef) then begin @@ -5237,6 +5242,19 @@ implementation end; end; + + procedure thlcgobj.getlocal(list: TAsmList; sym: tsym; size: asizeint; alignment: shortint; def: tdef; out ref: treference); + begin + tg.getlocal(list,size,alignment,def,ref); + recordnewsymloc(list,sym,def,ref); + end; + + procedure thlcgobj.recordnewsymloc(list: TAsmList; sym: tsym; def: tdef; const ref: treference); + begin + // do nothing + end; + + procedure thlcgobj.gen_loadfpu_loc_cgpara(list: TAsmList; size: tdef; const l: tlocation; const cgpara: tcgpara; locintsize: longint); var tmploc: tlocation; diff --git a/compiler/llvm/hlcgllvm.pas b/compiler/llvm/hlcgllvm.pas index 46947a9627..1eb144dd2e 100644 --- a/compiler/llvm/hlcgllvm.pas +++ b/compiler/llvm/hlcgllvm.pas @@ -52,6 +52,9 @@ uses procedure allocallcpuregisters(list: TAsmList); override; procedure deallocallcpuregisters(list: TAsmList); override; + procedure recordnewsymloc(list: TAsmList; sym: tsym; def: tdef; const ref: treference); override; + + public procedure a_bit_test_reg_reg_reg(list: TAsmList; bitnumbersize, valuesize, destsize: tdef; bitnumber, value, destreg: tregister); override; procedure a_bit_set_reg_reg(list: TAsmList; doset: boolean; bitnumbersize, destsize: tdef; bitnumber, dest: tregister); override; @@ -384,6 +387,42 @@ implementation end; + procedure thlcgllvm.recordnewsymloc(list: TAsmList; sym: tsym; def: tdef; const ref: treference); + var + varmetapara, + symmetadatapara, + exprmetapara: tcgpara; + pd: tprocdef; + begin + if assigned(sym) and + (sym.visibility<>vis_hidden) and + (cs_debuginfo in current_settings.moduleswitches) then + begin + pd:=search_system_proc('llvm_dbg_addr'); + varmetapara.init; + symmetadatapara.init; + exprmetapara.init; + paramanager.getcgtempparaloc(current_asmdata.CurrAsmList,pd,1,varmetapara); + paramanager.getcgtempparaloc(current_asmdata.CurrAsmList,pd,1,symmetadatapara); + paramanager.getcgtempparaloc(current_asmdata.CurrAsmList,pd,1,exprmetapara); + { the local location of the var/para } + varmetapara.Location^.def:=cpointerdef.getreusable(def); + varmetapara.Location^.register:=ref.base; + { the variable/para metadata } + symmetadatapara.Location^.llvmloc.loc:=LOC_CREFERENCE; + symmetadatapara.Location^.llvmloc.localsym:=sym; + { dummy for the expression metadata } + exprmetapara.Location^.llvmloc.loc:=LOC_CONSTANT; + exprmetapara.Location^.llvmloc.value:=0; + g_call_system_proc(list,pd,[@varmetapara,@symmetadatapara,@exprmetapara],nil).resetiftemp; + + varmetapara.done; + symmetadatapara.done; + exprmetapara.done; + end; + end; + + procedure thlcgllvm.a_bit_test_reg_reg_reg(list: TAsmList; bitnumbersize, valuesize, destsize: tdef; bitnumber, value, destreg: tregister); var tmpbitnumberreg: tregister; diff --git a/compiler/ncgld.pas b/compiler/ncgld.pas index 726f781c6e..cd214b626f 100644 --- a/compiler/ncgld.pas +++ b/compiler/ncgld.pas @@ -236,6 +236,7 @@ implementation location.reference:=ref; tg.ChangeTempType(current_asmdata.CurrAsmList,location.reference,oldtemptype); tabstractnormalvarsym(symtableentry).localloc:=location; + hlcg.recordnewsymloc(current_asmdata.CurrAsmList,symtableentry,tabstractnormalvarsym(symtableentry).vardef,location.reference); end; diff --git a/compiler/ncgutil.pas b/compiler/ncgutil.pas index e5f16bb920..b525048499 100644 --- a/compiler/ncgutil.pas +++ b/compiler/ncgutil.pas @@ -980,10 +980,10 @@ implementation if isaddr then begin ptrdef:=cpointerdef.getreusable(vs.vardef); - tg.GetLocal(list,ptrdef.size,ptrdef,vs.initialloc.reference) + hlcg.GetLocal(list,vs,ptrdef.size,ptrdef.alignment,ptrdef,vs.initialloc.reference) end else - tg.GetLocal(list,vs.getsize,tparavarsym(vs).paraloc[calleeside].alignment,vs.vardef,vs.initialloc.reference); + hlcg.GetLocal(list,vs,vs.getsize,tparavarsym(vs).paraloc[calleeside].alignment,vs.vardef,vs.initialloc.reference); end; end; end; @@ -1029,7 +1029,7 @@ implementation else begin vs.initialloc.loc:=LOC_REFERENCE; - tg.GetLocal(list,vs.getsize,vs.vardef,vs.initialloc.reference); + hlcg.GetLocal(list,vs,vs.getsize,vs.vardef.alignment,vs.vardef,vs.initialloc.reference); end; hlcg.varsym_set_localloc(list,vs); end;