diff options
author | jonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2014-03-19 21:53:10 +0000 |
---|---|---|
committer | jonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2014-03-19 21:53:10 +0000 |
commit | 83776a22643506e88638f2d879cb077858451292 (patch) | |
tree | 0490bf75020489955eb82902273987626df84a99 | |
parent | 16017992bda2d8f4bde9ed576d07ccb8bb694ad2 (diff) | |
download | fpc-83776a22643506e88638f2d879cb077858451292.tar.gz |
* moved po_has_inlininginfo from procoptions to procimploptions so that
the availability of the body of a function declared as "inline" no
longer changes the CRC and hence no longer triggers recompilations
(mantis #24121)
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@27192 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r-- | compiler/ncal.pas | 6 | ||||
-rw-r--r-- | compiler/ppu.pas | 2 | ||||
-rw-r--r-- | compiler/psub.pas | 4 | ||||
-rw-r--r-- | compiler/symconst.pas | 5 | ||||
-rw-r--r-- | compiler/symdef.pas | 45 | ||||
-rw-r--r-- | compiler/utils/ppuutils/ppudump.pp | 16 |
6 files changed, 49 insertions, 29 deletions
diff --git a/compiler/ncal.pas b/compiler/ncal.pas index d3d181976d..262e24efd4 100644 --- a/compiler/ncal.pas +++ b/compiler/ncal.pas @@ -3437,7 +3437,9 @@ implementation para : tcallparanode; begin { Can we inline the procedure? } - if ([po_inline,po_has_inlininginfo] <= procdefinition.procoptions) then + if (po_inline in procdefinition.procoptions) and + (procdefinition.typ=procdef) and + tprocdef(procdefinition).has_inlininginfo then begin include(callnodeflags,cnf_do_inline); { Check if we can inline the procedure when it references proc/var that @@ -3527,7 +3529,7 @@ implementation { allow only certain proc options } ((tprocdef(procdefinition).procoptions-[po_none,po_classmethod,po_staticmethod, po_interrupt,po_iocheck,po_assembler,po_msgstr,po_msgint,po_exports,po_external,po_overload, - po_nostackframe,po_has_mangledname,po_has_public_name,po_forward,po_global,po_has_inlininginfo, + po_nostackframe,po_has_mangledname,po_has_public_name,po_forward,po_global, po_inline,po_compilerproc,po_has_importdll,po_has_importname,po_kylixlocal,po_dispid,po_delphi_nested_cc, po_rtlproc,po_ignore_for_overload_resolution,po_auto_raised_visibility])=[]) then begin diff --git a/compiler/ppu.pas b/compiler/ppu.pas index 4c8e506363..5864ea1e41 100644 --- a/compiler/ppu.pas +++ b/compiler/ppu.pas @@ -43,7 +43,7 @@ type {$endif Test_Double_checksum} const - CurrentPPUVersion = 166; + CurrentPPUVersion = 167; { buffer sizes } maxentrysize = 1024; diff --git a/compiler/psub.pas b/compiler/psub.pas index 70a908a778..eed8e969ff 100644 --- a/compiler/psub.pas +++ b/compiler/psub.pas @@ -1128,12 +1128,12 @@ implementation procedure TCGProcinfo.CreateInlineInfo; begin new(procdef.inlininginfo); - include(procdef.procoptions,po_has_inlininginfo); procdef.inlininginfo^.code:=code.getcopy; procdef.inlininginfo^.flags:=flags; { The blocknode needs to set an exit label } if procdef.inlininginfo^.code.nodetype=blockn then include(procdef.inlininginfo^.code.flags,nf_block_with_exit); + procdef.has_inlininginfo:=true; end; @@ -1218,7 +1218,7 @@ implementation { inlining not turned off? } (cs_do_inline in current_settings.localswitches) and { no inlining yet? } - not(po_has_inlininginfo in procdef.procoptions) and not(has_nestedprocs) and + not(procdef.has_inlininginfo) and not(has_nestedprocs) and not(procdef.proctypeoption in [potype_proginit,potype_unitinit,potype_unitfinalize,potype_constructor, potype_destructor,potype_class_constructor,potype_class_destructor]) and ((procdef.procoptions*[po_exports,po_external,po_interrupt,po_virtualmethod,po_iocheck])=[]) and diff --git a/compiler/symconst.pas b/compiler/symconst.pas index a65da9de76..f82929fd35 100644 --- a/compiler/symconst.pas +++ b/compiler/symconst.pas @@ -303,7 +303,6 @@ type po_has_public_name, po_forward, po_global, - po_has_inlininginfo, { The different kind of syscalls on MorphOS } po_syscall_legacy, po_syscall_sysv, @@ -362,7 +361,9 @@ type between the interface and the implementation } timplprocoption = ( { the routine contains no code } - pio_empty + pio_empty, + { the inline body of this routine is available } + pio_has_inlininginfo ); timplprocoptions = set of timplprocoption; diff --git a/compiler/symdef.pas b/compiler/symdef.pas index 1f05518734..cee2d92773 100644 --- a/compiler/symdef.pas +++ b/compiler/symdef.pas @@ -644,6 +644,8 @@ interface procedure Sethasforward(AValue: boolean); function GetIsEmpty: boolean; procedure SetIsEmpty(AValue: boolean); + function GetHasInliningInfo: boolean; + procedure SetHasInliningInfo(AValue: boolean); public messageinf : tmessageinf; dispid : longint; @@ -771,6 +773,8 @@ interface property hasforward: boolean read Gethasforward write Sethasforward; { true if the routine's body is empty } property isempty: boolean read GetIsEmpty write SetIsEmpty; + { true if all information required to inline this routine is available } + property has_inlininginfo: boolean read GetHasInliningInfo write SetHasInliningInfo; end; { single linked list of overloaded procs } @@ -4677,6 +4681,21 @@ implementation end; + function tprocdef.GetHasInliningInfo: boolean; + begin + result:=pio_has_inlininginfo in implprocoptions; + end; + + + procedure tprocdef.SetHasInliningInfo(AValue: boolean); + begin + if AValue then + include(implprocoptions,pio_has_inlininginfo) + else + exclude(implprocoptions,pio_has_inlininginfo); + end; + + procedure tprocdef.Setinterfacedef(AValue: boolean); begin if not assigned(implprocdefinfo) then @@ -4788,7 +4807,8 @@ implementation if (po_dispid in procoptions) then dispid:=ppufile.getlongint; { inline stuff } - if (po_has_inlininginfo in procoptions) then + ppufile.getsmallset(implprocoptions); + if has_inlininginfo then begin ppufile.getderef(funcretsymderef); new(inlininginfo); @@ -4806,13 +4826,11 @@ implementation for i:=1 to aliasnamescount do aliasnames.insert(ppufile.getstring); - ppufile.getsmallset(implprocoptions); - { load para symtable } parast:=tparasymtable.create(self,level); tparasymtable(parast).ppuload(ppufile); { load local symtable } - if (po_has_inlininginfo in procoptions) then + if has_inlininginfo then begin localst:=tlocalsymtable.create(self,level); tlocalsymtable(localst).ppuload(ppufile); @@ -4820,7 +4838,7 @@ implementation else localst:=nil; { inline stuff } - if (po_has_inlininginfo in procoptions) then + if has_inlininginfo then inlininginfo^.code:=ppuloadnodetree(ppufile); { default values for no persistent data } if (cs_link_deffile in current_settings.globalswitches) and @@ -4828,7 +4846,7 @@ implementation (po_exports in procoptions) then deffile.AddExport(mangledname); { Disable po_has_inlining until the derefimpl is done } - exclude(procoptions,po_has_inlininginfo); + has_inlininginfo:=false; {$ifdef i386} fpu_used:=maxfpuregs; {$endif i386} @@ -4941,7 +4959,8 @@ implementation { inline stuff } oldintfcrc:=ppufile.do_crc; ppufile.do_crc:=false; - if (po_has_inlininginfo in procoptions) then + ppufile.putsmallset(implprocoptions); + if has_inlininginfo then begin ppufile.putderef(funcretsymderef); ppufile.putsmallset(inlininginfo^.flags); @@ -4965,8 +4984,6 @@ implementation item:=TCmdStrListItem(item.next); end; - ppufile.putsmallset(implprocoptions); - ppufile.do_crc:=oldintfcrc; { write this entry } @@ -4977,7 +4994,7 @@ implementation { save localsymtable for inline procedures or when local browser info is requested, this has no influence on the crc } - if (po_has_inlininginfo in procoptions) then + if has_inlininginfo then begin oldintfcrc:=ppufile.do_crc; ppufile.do_crc:=false; @@ -4988,7 +5005,7 @@ implementation { node tree for inlining } oldintfcrc:=ppufile.do_crc; ppufile.do_crc:=false; - if (po_has_inlininginfo in procoptions) then + if has_inlininginfo then ppuwritenodetree(ppufile,inlininginfo^.code); ppufile.do_crc:=oldintfcrc; end; @@ -5204,7 +5221,7 @@ implementation inherited buildderefimpl; { inline tree } - if (po_has_inlininginfo in procoptions) then + if has_inlininginfo then begin { Localst is not available for main/unit init } if assigned(localst) then @@ -5239,10 +5256,10 @@ implementation structure is available. The has_inlininginfo was disabled after the load, since the data was invalid } if assigned(inlininginfo) then - include(procoptions,po_has_inlininginfo); + has_inlininginfo:=true; { Inline } - if (po_has_inlininginfo in procoptions) then + if has_inlininginfo then begin { Locals } if assigned(localst) then diff --git a/compiler/utils/ppuutils/ppudump.pp b/compiler/utils/ppuutils/ppudump.pp index 661e04021d..051c8fe824 100644 --- a/compiler/utils/ppuutils/ppudump.pp +++ b/compiler/utils/ppuutils/ppudump.pp @@ -1717,7 +1717,6 @@ const (mask:po_has_public_name; str:'HasPublicName'), (mask:po_forward; str:'Forward'), (mask:po_global; str:'Global'), - (mask:po_has_inlininginfo;str:'HasInliningInfo'), (mask:po_syscall_legacy; str:'SyscallLegacy'), (mask:po_syscall_sysv; str:'SyscallSysV'), (mask:po_syscall_basesysv;str:'SyscallBaseSysV'), @@ -1952,7 +1951,7 @@ begin end; -procedure readprocimploptions(const space: string); +procedure readprocimploptions(const space: string; out implprocoptions: timplprocoptions); type tpiopt=record mask : timplprocoption; @@ -1960,10 +1959,10 @@ type end; const piopt : array[low(timplprocoption)..high(timplprocoption)] of tpiopt=( - (mask:pio_empty; str:'IsEmpty') + (mask:pio_empty; str:'IsEmpty'), + (mask:pio_has_inlininginfo; str:'HasInliningInfo') ); var - implprocoptions: timplprocoptions; i: timplprocoption; first: boolean; begin @@ -2620,6 +2619,7 @@ var l,j : longint; calloption : tproccalloption; procoptions : tprocoptions; + implprocoptions: timplprocoptions; defoptions: tdefoptions; iexpr: Tconstexprint; def: TPpuDef; @@ -2906,7 +2906,8 @@ begin writeln([space,' MsgStr : ',getstring]); if (po_dispid in procoptions) then writeln([space,' DispID: ',ppufile.getlongint]); - if (po_has_inlininginfo in procoptions) then + readprocimploptions(space,implprocoptions); + if (pio_has_inlininginfo in implprocoptions) then begin write ([space,' FuncretSym : ']); readderef(''); @@ -2924,16 +2925,15 @@ begin end; writeln; end; - readprocimploptions(space); if not EndOfEntry then HasMoreInfos; space:=' '+space; { parast } readsymtable('parast', TPpuProcDef(def)); { localst } - if (po_has_inlininginfo in procoptions) then + if (pio_has_inlininginfo in implprocoptions) then readsymtable('localst'); - if (po_has_inlininginfo in procoptions) then + if (pio_has_inlininginfo in implprocoptions) then readnodetree; delete(space,1,4); end; |