diff --git a/compiler/ncal.pas b/compiler/ncal.pas index 8b2e2869ae..ac587440b7 100644 --- a/compiler/ncal.pas +++ b/compiler/ncal.pas @@ -24,6 +24,8 @@ unit ncal; {$i fpcdefs.inc} +{ define NODEINLINE} + interface uses @@ -67,8 +69,9 @@ interface procedure order_parameters; procedure createinlineparas(var createstatement, deletestatement: tstatementnode); - function replaceparaload(var n: tnode; arg: pointer): foreachnoderesult; + function replaceparaload(var n: tnode; arg: pointer): foreachnoderesult; procedure createlocaltemps(p:TNamedIndexItem;arg:pointer); + function pass1_inline:tnode; protected pushedparasize : longint; public @@ -85,8 +88,10 @@ interface methodpointerinit, methodpointerdone : tblocknode; methodpointer : tnode; +{$ifdef PASS2INLINE} { inline function body } inlinecode : tnode; +{$endif PASS2INLINE} { varargs parasyms } varargsparas : tvarargsparalist; { node that specifies where the result should be put for calls } @@ -707,7 +712,9 @@ type methodpointerdone:=nil; procdefinition:=nil; _funcretnode:=nil; +{$ifdef PASS2INLINE} inlinecode:=nil; +{$endif PASS2INLINE} paralength:=-1; varargsparas:=nil; end; @@ -724,7 +731,9 @@ type procdefinition:=nil; callnodeflags:=[cnf_return_value_used]; _funcretnode:=nil; +{$ifdef PASS2INLINE} inlinecode:=nil; +{$endif PASS2INLINE} paralength:=-1; varargsparas:=nil; end; @@ -823,7 +832,9 @@ type methodpointerinit.free; methodpointerdone.free; _funcretnode.free; +{$ifdef PASS2INLINE} inlinecode.free; +{$endif PASS2INLINE} if assigned(varargsparas) then begin for i:=0 to varargsparas.count-1 do @@ -848,7 +859,9 @@ type methodpointerinit:=tblocknode(ppuloadnode(ppufile)); methodpointerdone:=tblocknode(ppuloadnode(ppufile)); _funcretnode:=ppuloadnode(ppufile); +{$ifdef PASS2INLINE} inlinecode:=ppuloadnode(ppufile); +{$endif PASS2INLINE} end; @@ -862,7 +875,9 @@ type ppuwritenode(ppufile,methodpointerinit); ppuwritenode(ppufile,methodpointerdone); ppuwritenode(ppufile,_funcretnode); +{$ifdef PASS2INLINE} ppuwritenode(ppufile,inlinecode); +{$endif PASS2INLINE} end; @@ -879,8 +894,10 @@ type methodpointerdone.buildderefimpl; if assigned(_funcretnode) then _funcretnode.buildderefimpl; +{$ifdef PASS2INLINE} if assigned(inlinecode) then inlinecode.buildderefimpl; +{$endif PASS2INLINE} end; @@ -901,8 +918,10 @@ type methodpointerdone.derefimpl; if assigned(_funcretnode) then _funcretnode.derefimpl; +{$ifdef PASS2INLINE} if assigned(inlinecode) then inlinecode.derefimpl; +{$endif PASS2INLINE} { Connect parasyms } pt:=tcallparanode(left); while assigned(pt) and @@ -961,10 +980,12 @@ type n._funcretnode:=_funcretnode.getcopy else n._funcretnode:=nil; +{$ifdef PASS2INLINE} if assigned(inlinecode) then n.inlinecode:=inlinecode.getcopy else n.inlinecode:=nil; +{$endif PASS2INLINE} if assigned(varargsparas) then begin n.varargsparas:=tvarargsparalist.create; @@ -1955,7 +1976,7 @@ type end else begin - tempnode := ctempcreatenode.create(tabstractvarsym(p).vartype,tabstractvarsym(p).vartype.def.size,tt_persistent,tparavarsym(p).varregable<>vr_none); + tempnode := ctempcreatenode.create(tabstractvarsym(p).vartype,tabstractvarsym(p).vartype.def.size,tt_persistent,tabstractvarsym(p).varregable<>vr_none); addstatement(tempinfo^.createstatement,tempnode); if assigned(tlocalvarsym(p).defaultconstsym) then begin @@ -2049,13 +2070,48 @@ type end; - function tcallnode.pass_1 : tnode; + + function tcallnode.pass1_inline:tnode; var createstatement,deletestatement: tstatementnode; createblock,deleteblock: tblocknode; i: longint; - label - errorexit; + begin + if not assigned(tprocdef(procdefinition).inlininginfo^.code) then + internalerror(200412021); + { inherit flags } + current_procinfo.flags := current_procinfo.flags + ((procdefinition as tprocdef).inlininginfo^.flags*inherited_inlining_flags); + { create blocks for loading/deleting of local data } + createblock:=internalstatements(createstatement); + deleteblock:=internalstatements(deletestatement); + inlinelocals:=tlist.create; + { replace complex parameters with temps } + createinlineparas(createstatement,deletestatement); + { replace the parameter loads with the parameter values } + foreachnode(result,@replaceparaload,@fileinfo); + { free the temps for the locals } + for i := 0 to inlinelocals.count-1 do + if assigned(inlinelocals[i]) then + tnode(inlinelocals[i]).free; + inlinelocals.free; + inlinelocals:=nil; + addstatement(createstatement,tprocdef(procdefinition).inlininginfo^.code.getcopy); + addstatement(createstatement,deleteblock); + { set function result location if necessary } + if assigned(funcretnode) and + (cnf_return_value_used in callnodeflags) then + addstatement(createstatement,funcretnode.getcopy); + { consider it must not be inlined if called + again inside the args or itself } + procdefinition.proccalloption:=pocall_default; + firstpass(createblock); + procdefinition.proccalloption:=pocall_inline; + { return inlined block } + result := createblock; + end; + + + function tcallnode.pass_1 : tnode; begin result:=nil; @@ -2064,49 +2120,8 @@ type { can we inline this procedure at the node level? } (tprocdef(procdefinition).inlininginfo^.inlinenode) then begin - { inherit flags } - current_procinfo.flags := current_procinfo.flags + ((procdefinition as tprocdef).inlininginfo^.flags*inherited_inlining_flags); - - if assigned(methodpointer) then - CGMessage(cg_e_unable_inline_object_methods); - if assigned(right) then - CGMessage(cg_e_unable_inline_procvar); - if assigned(inlinecode) then - internalerror(2004071110); - - if assigned(tprocdef(procdefinition).inlininginfo^.code) then - result:=tprocdef(procdefinition).inlininginfo^.code.getcopy - else - CGMessage(cg_e_no_code_for_inline_stored); - if assigned(result) then - begin - createblock := internalstatements(createstatement); - deleteblock := internalstatements(deletestatement); - inlinelocals:=tlist.create; - { replace complex parameters with temps } - createinlineparas(createstatement,deletestatement); - { replace the parameter loads with the parameter values } - foreachnode(result,@replaceparaload,@fileinfo); - { free the temps for the locals } - for i := 0 to inlinelocals.count-1 do - if assigned(inlinelocals[i]) then - tnode(inlinelocals[i]).free; - inlinelocals.free; - inlinelocals:=nil; - addstatement(createstatement,result); - addstatement(createstatement,deleteblock); - { set function result location if necessary } - if assigned(funcretnode) and - (cnf_return_value_used in callnodeflags) then - addstatement(createstatement,funcretnode.getcopy); - result := createblock; - { consider it must not be inlined if called - again inside the args or itself } - procdefinition.proccalloption:=pocall_default; - firstpass(result); - procdefinition.proccalloption:=pocall_inline; - exit; - end; + result:=pass1_inline; + exit; end; {$endif NODEINLINE} @@ -2157,6 +2172,7 @@ type begin if procdefinition.deftype<>procdef then internalerror(200411071); +{$ifdef PASS2INLINE} { calc the correture value for the register } { handle predefined procedures } if (procdefinition.proccalloption=pocall_inline) then @@ -2184,6 +2200,7 @@ type end; end else +{$endif PASS2INLINE} begin if not (block_type in [bt_const,bt_type]) then include(current_procinfo.flags,pi_do_call); @@ -2292,16 +2309,18 @@ type end; end; +{$ifdef PASS2INLINE} { determine the registers of the procedure variable } { is this OK for inlined procs also ?? (PM) } if assigned(inlinecode) then begin registersfpu:=max(inlinecode.registersfpu,registersfpu); registersint:=max(inlinecode.registersint,registersint); -{$ifdef SUPPORT_MMX} + {$ifdef SUPPORT_MMX} registersmmx:=max(inlinecode.registersmmx,registersmmx); -{$endif SUPPORT_MMX} + {$endif SUPPORT_MMX} end; +{$endif PASS2INLINE} { determine the registers of the procedure variable } { is this OK for inlined procs also ?? (PM) } if assigned(right) then @@ -2321,9 +2340,10 @@ type registersmmx:=max(left.registersmmx,registersmmx); {$endif SUPPORT_MMX} end; - errorexit: +{$ifdef PASS2INLINE} if assigned(inlinecode) then procdefinition.proccalloption:=pocall_inline; +{$endif PASS2INLINE} end; {$ifdef state_tracking} @@ -2409,7 +2429,10 @@ begin end. { $Log$ - Revision 1.265 2004-11-28 14:34:59 jonas + Revision 1.266 2004-12-02 19:26:14 peter + * disable pass2inline + + Revision 1.265 2004/11/28 14:34:59 jonas * only try to replace locals from the inlined procedure with temps, cycle now works with -dNODEINLINE diff --git a/compiler/ncgbas.pas b/compiler/ncgbas.pas index 51c564152c..1c95ab536d 100644 --- a/compiler/ncgbas.pas +++ b/compiler/ncgbas.pas @@ -68,7 +68,7 @@ interface uses globtype,systems, - cutils,verbose,cpuinfo, + cutils,verbose, aasmbase,aasmtai,aasmcpu,symsym,symconst, defutil, nflw,pass_2, @@ -324,9 +324,17 @@ interface procedure tcgblocknode.pass_2; var hp : tstatementnode; + oldexitlabel : tasmlabel; begin location_reset(location,LOC_VOID,OS_NO); + { replace exitlabel? } + if nf_block_with_exit in flags then + begin + oldexitlabel:=current_procinfo.aktexitlabel; + objectlibrary.getlabel(current_procinfo.aktexitlabel); + end; + { do second pass on left node } if assigned(left) then begin @@ -342,6 +350,13 @@ interface hp:=tstatementnode(hp.right); end; end; + + { write exitlabel } + if nf_block_with_exit in flags then + begin + cg.a_label(exprasmlist,current_procinfo.aktexitlabel); + current_procinfo.aktexitlabel:=oldexitlabel; + end; end; @@ -491,7 +506,10 @@ begin end. { $Log$ - Revision 1.71 2004-11-11 19:31:33 peter + Revision 1.72 2004-12-02 19:26:15 peter + * disable pass2inline + + Revision 1.71 2004/11/11 19:31:33 peter * fixed compile of powerpc,sparc,arm Revision 1.70 2004/11/08 22:09:59 peter diff --git a/compiler/ncgcal.pas b/compiler/ncgcal.pas index fd4af09c4d..edba20c55b 100644 --- a/compiler/ncgcal.pas +++ b/compiler/ncgcal.pas @@ -48,7 +48,9 @@ interface private procedure release_para_temps; procedure normal_pass_2; +{$ifdef PASS2INLINE} procedure inlined_pass_2; +{$endif PASS2INLINE} procedure pushparas; procedure freeparas; protected @@ -364,10 +366,12 @@ implementation objectlibrary.getlabel(falselabel); secondpass(left); - if not(assigned(aktcallnode.inlinecode)) then - paramanager.createtempparaloc(exprasmlist,aktcallnode.procdefinition.proccalloption,parasym,tempcgpara) +{$ifdef PASS2INLINE} + if assigned(aktcallnode.inlinecode) then + paramanager.duplicateparaloc(exprasmlist,aktcallnode.procdefinition.proccalloption,parasym,tempcgpara) else - paramanager.duplicateparaloc(exprasmlist,aktcallnode.procdefinition.proccalloption,parasym,tempcgpara); +{$endif PASS2INLINE} + paramanager.createtempparaloc(exprasmlist,aktcallnode.procdefinition.proccalloption,parasym,tempcgpara); { handle varargs first, because parasym is not valid } if (cpf_varargs_para in callparaflags) then @@ -698,7 +702,9 @@ implementation { better check for the real location of the parameter here, when stack passed parameters are saved temporary in registers, checking for the tmpparaloc.loc is wrong } +{$ifdef PASS2INLINE} if not assigned(inlinecode) then +{$endif PASS2INLINE} paramanager.freeparaloc(exprasmlist,ppn.tempcgpara); tmpparaloc:=ppn.tempcgpara.location; callerparaloc:=ppn.parasym.paraloc[callerside].location; @@ -738,7 +744,9 @@ implementation end; LOC_REFERENCE: begin +{$ifdef PASS2INLINE} if not assigned(inlinecode) then +{$endif PASS2INLINE} begin {$ifdef cputargethasfixedstack} reference_reset_base(href,callerparaloc^.reference.index,callerparaloc^.reference.offset); @@ -781,7 +789,10 @@ implementation ppn:=tcgcallparanode(left); while assigned(ppn) do begin - if not assigned(inlinecode) or + if +{$ifdef PASS2INLINE} + not assigned(inlinecode) or +{$endif PASS2INLINE} (ppn.parasym.paraloc[callerside].location^.loc <> LOC_REFERENCE) then paramanager.freeparaloc(exprasmlist,ppn.parasym.paraloc[callerside]); ppn:=tcgcallparanode(ppn.right); @@ -1030,6 +1041,7 @@ implementation end; +{$ifdef PASS2INLINE} procedure tcgcallnode.inlined_pass_2; var oldaktcallnode : tcallnode; @@ -1224,6 +1236,7 @@ implementation current_procinfo:=oldprocinfo; inlining_procedure:=oldinlining_procedure; end; +{$endif PASS2INLINE} procedure tcgcallnode.pass_2; @@ -1231,9 +1244,11 @@ implementation if assigned(methodpointerinit) then secondpass(methodpointerinit); +{$ifdef PASS2INLINE} if assigned(inlinecode) then inlined_pass_2 else +{$endif PASS2INLINE} normal_pass_2; if assigned(methodpointerdone) then @@ -1247,7 +1262,10 @@ begin end. { $Log$ - Revision 1.188 2004-11-21 18:13:31 peter + Revision 1.189 2004-12-02 19:26:15 peter + * disable pass2inline + + Revision 1.188 2004/11/21 18:13:31 peter * fixed funcretloc for sparc Revision 1.187 2004/11/21 17:54:59 peter diff --git a/compiler/node.pas b/compiler/node.pas index 968374ee4d..77b346ed1e 100644 --- a/compiler/node.pas +++ b/compiler/node.pas @@ -240,7 +240,10 @@ interface nf_inlineconst, { tasmnode } - nf_get_asm_position + nf_get_asm_position, + + { tblocknode } + nf_block_with_exit ); tnodeflags = set of tnodeflag; @@ -1136,7 +1139,10 @@ implementation end. { $Log$ - Revision 1.90 2004-11-02 12:55:16 peter + Revision 1.91 2004-12-02 19:26:15 peter + * disable pass2inline + + Revision 1.90 2004/11/02 12:55:16 peter * nf_internal flag for internal inserted typeconvs. This will supress the generation of warning/hints diff --git a/compiler/nutils.pas b/compiler/nutils.pas index c490d808d5..45d713d3d7 100644 --- a/compiler/nutils.pas +++ b/compiler/nutils.pas @@ -101,7 +101,9 @@ implementation begin { not in one statement, won't work because of b- } result := foreachnode(tcallnode(n).methodpointer,f,arg) or result; +{$ifdef PASS2INLINE} result := foreachnode(tcallnode(n).inlinecode,f,arg) or result; +{$endif PASS2INLINE} end; ifn, whilerepeatn, forn: begin @@ -147,7 +149,9 @@ implementation calln: begin result := foreachnodestatic(tcallnode(n).methodpointer,f,arg) or result; +{$ifdef PASS2INLINE} result := foreachnodestatic(tcallnode(n).inlinecode,f,arg) or result; +{$endif PASS2INLINE} end; ifn, whilerepeatn, forn: begin @@ -526,7 +530,10 @@ end. { $Log$ - Revision 1.22 2004-11-28 19:29:45 jonas + Revision 1.23 2004-12-02 19:26:15 peter + * disable pass2inline + + Revision 1.22 2004/11/28 19:29:45 jonas * loadvmtaddrn and loadparentfpn both have complexity 1 (the latter fixes compilation of tw0935 with nodeinlining) diff --git a/compiler/psub.pas b/compiler/psub.pas index ca79db3964..85f085fd36 100644 --- a/compiler/psub.pas +++ b/compiler/psub.pas @@ -937,15 +937,6 @@ implementation end; - function containsforbiddennode(var n: tnode; arg: pointer): foreachnoderesult; - begin - if (n.nodetype <> exitn) then - result := fen_false - else - result := fen_norecurse_true; - end; - - function checknodeinlining(procdef: tprocdef): boolean; var i : integer; @@ -966,8 +957,7 @@ implementation is_special_array(currpara.vartype.def) then exit; end; - { we currently can't handle exit-statements (would exit the caller) } - result := not foreachnodestatic(procdef.inlininginfo^.code,@containsforbiddennode,nil); + result:=true; end; @@ -1057,6 +1047,8 @@ implementation procdef.inlininginfo^.code:=code.getcopy; procdef.inlininginfo^.flags:=current_procinfo.flags; procdef.inlininginfo^.inlinenode:=checknodeinlining(procdef); + if procdef.inlininginfo^.code.nodetype=blockn then + include(procdef.inlininginfo^.code.flags,nf_block_with_exit); end else procdef.inlininginfo^.code:=code; @@ -1438,7 +1430,10 @@ implementation end. { $Log$ - Revision 1.220 2004-11-29 18:50:15 peter + Revision 1.221 2004-12-02 19:26:15 peter + * disable pass2inline + + Revision 1.220 2004/11/29 18:50:15 peter * os2 fixes for import * asmsymtype support for intel reader