diff --git a/compiler/fmodule.pas b/compiler/fmodule.pas index e4e9f38dc9..bff735d8cf 100644 --- a/compiler/fmodule.pas +++ b/compiler/fmodule.pas @@ -143,6 +143,7 @@ interface checkforwarddefs, deflist, symlist : TFPObjectList; + ptrdefs : THashSet; { list of pointerdefs created in this module so we can reuse them (not saved/restored) } wpoinfo : tunitwpoinfobase; { whole program optimization-related information that is generated during the current run for this unit } globalsymtable, { pointer to the global symtable of this unit } localsymtable : TSymtable;{ pointer to the local symtable of this unit } @@ -525,6 +526,7 @@ implementation derefdataintflen:=0; deflist:=TFPObjectList.Create(false); symlist:=TFPObjectList.Create(false); + ptrdefs:=THashSet.Create(64,true,false); wpoinfo:=nil; checkforwarddefs:=TFPObjectList.Create(false); extendeddefs := TFPHashObjectList.Create(true); @@ -640,6 +642,7 @@ implementation derefdata.free; deflist.free; symlist.free; + ptrdefs.free; wpoinfo.free; checkforwarddefs.free; globalsymtable.free; @@ -699,6 +702,8 @@ implementation deflist:=TFPObjectList.Create(false); symlist.free; symlist:=TFPObjectList.Create(false); + ptrdefs.free; + ptrdefs:=THashSet.Create(64,true,false); wpoinfo.free; wpoinfo:=nil; checkforwarddefs.free; diff --git a/compiler/nadd.pas b/compiler/nadd.pas index 9b4b1db124..3d21afc521 100644 --- a/compiler/nadd.pas +++ b/compiler/nadd.pas @@ -1752,7 +1752,7 @@ implementation begin if is_zero_based_array(rd) then begin - resultdef:=tpointerdef.create(tarraydef(rd).elementdef); + resultdef:=getpointerdef(tarraydef(rd).elementdef); inserttypeconv(right,resultdef); end else @@ -1782,7 +1782,7 @@ implementation begin if is_zero_based_array(ld) then begin - resultdef:=tpointerdef.create(tarraydef(ld).elementdef); + resultdef:=getpointerdef(tarraydef(ld).elementdef); inserttypeconv(left,resultdef); end else diff --git a/compiler/ncal.pas b/compiler/ncal.pas index 59c31bc670..a7b994cbf4 100644 --- a/compiler/ncal.pas +++ b/compiler/ncal.pas @@ -1451,7 +1451,7 @@ implementation is_object(p.resultdef); if usederef then - hdef:=tpointerdef.create(p.resultdef) + hdef:=getpointerdef(p.resultdef) else hdef:=p.resultdef; @@ -3715,7 +3715,7 @@ implementation { temp } else if (paracomplexity > 1) then begin - ptrtype:=tpointerdef.create(para.left.resultdef); + ptrtype:=getpointerdef(para.left.resultdef); tempnode := ctempcreatenode.create(ptrtype,ptrtype.size,tt_persistent,tparavarsym(para.parasym).is_regvar(true)); addstatement(inlineinitstatement,tempnode); addstatement(inlinecleanupstatement,ctempdeletenode.create(tempnode)); diff --git a/compiler/nld.pas b/compiler/nld.pas index b03422b783..2ed6f56ba6 100644 --- a/compiler/nld.pas +++ b/compiler/nld.pas @@ -312,7 +312,7 @@ implementation resultdef:=tclassrefdef.create(resultdef) else if (is_object(resultdef) or is_record(resultdef)) and (nf_load_self_pointer in flags) then - resultdef:=tpointerdef.create(resultdef); + resultdef:=getpointerdef(resultdef); end else if vo_is_vmt in tabstractvarsym(symtableentry).varoptions then begin diff --git a/compiler/nmem.pas b/compiler/nmem.pas index 80cd05d5e6..4f4620f9db 100644 --- a/compiler/nmem.pas +++ b/compiler/nmem.pas @@ -573,7 +573,7 @@ implementation (tabsolutevarsym(tloadnode(hp).symtableentry).abstyp=toaddr) then begin if nf_typedaddr in flags then - result:=cpointerconstnode.create(tabsolutevarsym(tloadnode(hp).symtableentry).addroffset,tpointerdef.create(left.resultdef)) + result:=cpointerconstnode.create(tabsolutevarsym(tloadnode(hp).symtableentry).addroffset,getpointerdef(left.resultdef)) else result:=cpointerconstnode.create(tabsolutevarsym(tloadnode(hp).symtableentry).addroffset,voidpointertype); exit; @@ -584,7 +584,7 @@ implementation if not(nf_typedaddr in flags) then resultdef:=voidpointertype else - resultdef:=tpointerdef.create(left.resultdef); + resultdef:=getpointerdef(left.resultdef); end else CGMessage(type_e_variable_id_expected); diff --git a/compiler/pexpr.pas b/compiler/pexpr.pas index a7582117c6..71a1327175 100644 --- a/compiler/pexpr.pas +++ b/compiler/pexpr.pas @@ -242,7 +242,7 @@ implementation begin typecheckpass(p1); result:=internalstatements(newstatement); - hdef:=tpointerdef.create(p1.resultdef); + hdef:=getpointerdef(p1.resultdef); temp:=ctempcreatenode.create(hdef,sizeof(pint),tt_persistent,false); addstatement(newstatement,temp); addstatement(newstatement,cassignmentnode.create(ctemprefnode.create(temp),caddrnode.create_internal(p1))); diff --git a/compiler/ptype.pas b/compiler/ptype.pas index 2f663ef0f3..e4628d7c45 100644 --- a/compiler/ptype.pas +++ b/compiler/ptype.pas @@ -1568,6 +1568,8 @@ implementation begin consume(_CARET); single_type(tt2,SingleTypeOptionsInTypeBlock[block_type=bt_type]); + { don't use getpointerdef() here, since this is a type + declaration (-> must create new typedef) } def:=tpointerdef.create(tt2); if tt2.typ=forwarddef then current_module.checkforwarddefs.add(def); diff --git a/compiler/symcreat.pas b/compiler/symcreat.pas index 34ad0d63d8..c211a54b5d 100644 --- a/compiler/symcreat.pas +++ b/compiler/symcreat.pas @@ -692,7 +692,7 @@ implementation {$endif} symtablestack.free; symtablestack:=old_symtablestack.getcopyuntil(pd.localst); - pnestedvarsdef:=tpointerdef.create(nestedvarsdef); + pnestedvarsdef:=getpointerdef(nestedvarsdef); nestedvars:=tlocalvarsym.create('$nestedvars',vs_var,nestedvarsdef,[]); pd.localst.insert(nestedvars); pd.parentfpstruct:=nestedvars; @@ -723,7 +723,7 @@ implementation nestedvarsst:=trecorddef(nestedvarsdef).symtable; { indicate whether or not this is a var/out/constref/... parameter } if addrparam then - fieldvardef:=tpointerdef.create(vardef) + fieldvardef:=getpointerdef(vardef) else fieldvardef:=vardef; result:=tfieldvarsym.create(sym.realname,vs_value,fieldvardef,[]); diff --git a/compiler/symdef.pas b/compiler/symdef.pas index 71e55ab4c6..319fcb5c97 100644 --- a/compiler/symdef.pas +++ b/compiler/symdef.pas @@ -928,6 +928,10 @@ interface function use_vectorfpu(def : tdef) : boolean; + { returns a pointerdef for def, reusing an existing one in case it exists + in the current module } + function getpointerdef(def: tdef): tpointerdef; + implementation uses @@ -6480,4 +6484,23 @@ implementation {$endif} end; + + function getpointerdef(def: tdef): tpointerdef; + var + res: PHashSetItem; + begin + if not assigned(current_module) then + internalerror(2011071101); + res:=current_module.ptrdefs.FindOrAdd(@def,sizeof(def)); + if not assigned(res^.Data) then + begin + { since these pointerdefs can be reused anywhere in the current + unit, add them to the global/staticsymtable } + symtablestack.push(current_module.localsymtable); + res^.Data:=tpointerdef.create(def); + symtablestack.pop(current_module.localsymtable); + end; + result:=tpointerdef(res^.Data); + end; + end.