mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-31 10:11:27 +01:00 
			
		
		
		
	* Improvements of tprocinfo class:
* Moved nestedprocs from tcgprocinfo to tprocinfo, in order to be able to access the entire nested procedure hierarchy without depending on psub.pas or code generator. * Creating an instance of tprocinfo automatically inserts it into list of parent's nested procedures. * nestedprocs list is created on demand. Public read-only access is provided by has_nestedprocs and get_first_nestedproc functions. + Method destroy_tree is provided for destroying the entire hierarchy of procinfo's. It can be called on any procinfo object in the tree. + Also added methods save_jump_labels and restore_jump_labels for asmlabel maintenance, which is currently being repeatedly done all over the codegenerator. git-svn-id: trunk@17197 -
This commit is contained in:
		
							parent
							
								
									ad52fe0f23
								
							
						
					
					
						commit
						1c01d52ea6
					
				| @ -544,7 +544,6 @@ implementation | |||||||
|     destructor tmodule.Destroy; |     destructor tmodule.Destroy; | ||||||
|       var |       var | ||||||
|         i : longint; |         i : longint; | ||||||
|         hpi : tprocinfo; |  | ||||||
|       begin |       begin | ||||||
|         if assigned(unitmap) then |         if assigned(unitmap) then | ||||||
|           freemem(unitmap); |           freemem(unitmap); | ||||||
| @ -582,12 +581,7 @@ implementation | |||||||
|                 current_specializedef:=nil; |                 current_specializedef:=nil; | ||||||
|               end; |               end; | ||||||
|             { release procinfo tree } |             { release procinfo tree } | ||||||
|             while assigned(procinfo) do |             tprocinfo(procinfo).destroy_tree; | ||||||
|              begin |  | ||||||
|                hpi:=tprocinfo(procinfo).parent; |  | ||||||
|                tprocinfo(procinfo).free; |  | ||||||
|                procinfo:=hpi; |  | ||||||
|              end; |  | ||||||
|           end; |           end; | ||||||
|         DoneDebugInfo(self); |         DoneDebugInfo(self); | ||||||
|         used_units.free; |         used_units.free; | ||||||
| @ -642,7 +636,6 @@ implementation | |||||||
| 
 | 
 | ||||||
|     procedure tmodule.reset; |     procedure tmodule.reset; | ||||||
|       var |       var | ||||||
|         hpi : tprocinfo; |  | ||||||
|         i   : longint; |         i   : longint; | ||||||
|       begin |       begin | ||||||
|         if assigned(scanner) then |         if assigned(scanner) then | ||||||
| @ -664,12 +657,7 @@ implementation | |||||||
|                 current_specializedef:=nil; |                 current_specializedef:=nil; | ||||||
|               end; |               end; | ||||||
|             { release procinfo tree } |             { release procinfo tree } | ||||||
|             while assigned(procinfo) do |             tprocinfo(procinfo).destroy_tree; | ||||||
|              begin |  | ||||||
|                hpi:=tprocinfo(procinfo).parent; |  | ||||||
|                tprocinfo(procinfo).free; |  | ||||||
|                procinfo:=hpi; |  | ||||||
|              end; |  | ||||||
|           end; |           end; | ||||||
|         if assigned(asmdata) then |         if assigned(asmdata) then | ||||||
|           begin |           begin | ||||||
|  | |||||||
| @ -47,10 +47,17 @@ unit procinfo; | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     type |     type | ||||||
|  |        tsavedlabels = array[Boolean] of TAsmLabel; | ||||||
|  | 
 | ||||||
|        {# This object gives information on the current routine being |        {# This object gives information on the current routine being | ||||||
|           compiled. |           compiled. | ||||||
|        } |        } | ||||||
|        tprocinfo = class(tlinkedlistitem) |        tprocinfo = class(tlinkedlistitem) | ||||||
|  |        private | ||||||
|  |           { list to store the procinfo's of the nested procedures } | ||||||
|  |           nestedprocs : tlinkedlist; | ||||||
|  |           procedure addnestedproc(child: tprocinfo); | ||||||
|  |        public | ||||||
|           { pointer to parent in nested procedures } |           { pointer to parent in nested procedures } | ||||||
|           parent : tprocinfo; |           parent : tprocinfo; | ||||||
|           {# the definition of the routine itself } |           {# the definition of the routine itself } | ||||||
| @ -123,6 +130,18 @@ unit procinfo; | |||||||
| 
 | 
 | ||||||
|           { Allocate got register } |           { Allocate got register } | ||||||
|           procedure allocate_got_register(list: TAsmList);virtual; |           procedure allocate_got_register(list: TAsmList);virtual; | ||||||
|  | 
 | ||||||
|  |           { Destroy the entire procinfo tree, starting from the outermost parent } | ||||||
|  |           procedure destroy_tree; | ||||||
|  | 
 | ||||||
|  |           { Store CurrTrueLabel and CurrFalseLabel to saved and generate new ones } | ||||||
|  |           procedure save_jump_labels(out saved: tsavedlabels); | ||||||
|  | 
 | ||||||
|  |           { Restore CurrTrueLabel and CurrFalseLabel from saved } | ||||||
|  |           procedure restore_jump_labels(const saved: tsavedlabels); | ||||||
|  | 
 | ||||||
|  |           function get_first_nestedproc: tprocinfo; | ||||||
|  |           function has_nestedprocs: boolean; | ||||||
|        end; |        end; | ||||||
|        tcprocinfo = class of tprocinfo; |        tcprocinfo = class of tprocinfo; | ||||||
| 
 | 
 | ||||||
| @ -165,15 +184,61 @@ implementation | |||||||
|         CurrTrueLabel:=nil; |         CurrTrueLabel:=nil; | ||||||
|         CurrFalseLabel:=nil; |         CurrFalseLabel:=nil; | ||||||
|         maxpushedparasize:=0; |         maxpushedparasize:=0; | ||||||
|  |         if Assigned(parent) and (parent.procdef.parast.symtablelevel>=normal_function_level) then | ||||||
|  |           parent.addnestedproc(Self); | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     destructor tprocinfo.destroy; |     destructor tprocinfo.destroy; | ||||||
|       begin |       begin | ||||||
|  |          nestedprocs.free; | ||||||
|          aktproccode.free; |          aktproccode.free; | ||||||
|          aktlocaldata.free; |          aktlocaldata.free; | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
|  |     procedure tprocinfo.destroy_tree; | ||||||
|  |       var | ||||||
|  |         hp: tprocinfo; | ||||||
|  |       begin | ||||||
|  |         hp:=Self; | ||||||
|  |         while Assigned(hp.parent) do | ||||||
|  |           hp:=hp.parent; | ||||||
|  |         hp.Free; | ||||||
|  |       end; | ||||||
|  | 
 | ||||||
|  |     procedure tprocinfo.addnestedproc(child: tprocinfo); | ||||||
|  |       begin | ||||||
|  |         if nestedprocs=nil then | ||||||
|  |           nestedprocs:=TLinkedList.Create; | ||||||
|  |         nestedprocs.insert(child); | ||||||
|  |       end; | ||||||
|  | 
 | ||||||
|  |     function tprocinfo.get_first_nestedproc: tprocinfo; | ||||||
|  |       begin | ||||||
|  |         if assigned(nestedprocs) then | ||||||
|  |           result:=tprocinfo(nestedprocs.first) | ||||||
|  |         else | ||||||
|  |           result:=nil; | ||||||
|  |       end; | ||||||
|  | 
 | ||||||
|  |     function tprocinfo.has_nestedprocs: boolean; | ||||||
|  |       begin | ||||||
|  |         result:=assigned(nestedprocs) and (nestedprocs.count>0); | ||||||
|  |       end; | ||||||
|  | 
 | ||||||
|  |     procedure tprocinfo.save_jump_labels(out saved: tsavedlabels); | ||||||
|  |       begin | ||||||
|  |         saved[false]:=CurrFalseLabel; | ||||||
|  |         saved[true]:=CurrTrueLabel; | ||||||
|  |         current_asmdata.getjumplabel(CurrTrueLabel); | ||||||
|  |         current_asmdata.getjumplabel(CurrFalseLabel); | ||||||
|  |       end; | ||||||
|  | 
 | ||||||
|  |     procedure tprocinfo.restore_jump_labels(const saved: tsavedlabels); | ||||||
|  |       begin | ||||||
|  |         CurrFalseLabel:=saved[false]; | ||||||
|  |         CurrTrueLabel:=saved[true]; | ||||||
|  |       end; | ||||||
| 
 | 
 | ||||||
|     procedure tprocinfo.allocate_push_parasize(size:longint); |     procedure tprocinfo.allocate_push_parasize(size:longint); | ||||||
|       begin |       begin | ||||||
|  | |||||||
| @ -45,10 +45,7 @@ interface | |||||||
|         stackcheck_asmnode, |         stackcheck_asmnode, | ||||||
|         init_asmnode, |         init_asmnode, | ||||||
|         final_asmnode : tasmnode; |         final_asmnode : tasmnode; | ||||||
|         { list to store the procinfo's of the nested procedures } |  | ||||||
|         nestedprocs : tlinkedlist; |  | ||||||
|         dfabuilder : TDFABuilder; |         dfabuilder : TDFABuilder; | ||||||
|         constructor create(aparent:tprocinfo);override; |  | ||||||
|         destructor  destroy;override; |         destructor  destroy;override; | ||||||
|         procedure printproc(pass:string); |         procedure printproc(pass:string); | ||||||
|         procedure generate_code; |         procedure generate_code; | ||||||
| @ -555,16 +552,8 @@ implementation | |||||||
|                                   TCGProcInfo |                                   TCGProcInfo | ||||||
| ****************************************************************************} | ****************************************************************************} | ||||||
| 
 | 
 | ||||||
|     constructor tcgprocinfo.create(aparent:tprocinfo); |  | ||||||
|       begin |  | ||||||
|         inherited Create(aparent); |  | ||||||
|         nestedprocs:=tlinkedlist.create; |  | ||||||
|       end; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|      destructor tcgprocinfo.destroy; |      destructor tcgprocinfo.destroy; | ||||||
|        begin |        begin | ||||||
|          nestedprocs.free; |  | ||||||
|          if assigned(code) then |          if assigned(code) then | ||||||
|            code.free; |            code.free; | ||||||
|          inherited destroy; |          inherited destroy; | ||||||
| @ -794,10 +783,10 @@ implementation | |||||||
| 
 | 
 | ||||||
|     function tcgprocinfo.has_assembler_child : boolean; |     function tcgprocinfo.has_assembler_child : boolean; | ||||||
|       var |       var | ||||||
|         hp : tcgprocinfo; |         hp : tprocinfo; | ||||||
|       begin |       begin | ||||||
|         result:=false; |         result:=false; | ||||||
|         hp:=tcgprocinfo(nestedprocs.first); |         hp:=get_first_nestedproc; | ||||||
|         while assigned(hp) do |         while assigned(hp) do | ||||||
|           begin |           begin | ||||||
|             if (hp.flags*[pi_has_assembler_block,pi_is_assembler])<>[] then |             if (hp.flags*[pi_has_assembler_block,pi_is_assembler])<>[] then | ||||||
| @ -805,7 +794,7 @@ implementation | |||||||
|                 result:=true; |                 result:=true; | ||||||
|                 exit; |                 exit; | ||||||
|               end; |               end; | ||||||
|             hp:=tcgprocinfo(hp.next); |             hp:=tprocinfo(hp.next); | ||||||
|           end; |           end; | ||||||
|       end; |       end; | ||||||
| 
 | 
 | ||||||
| @ -1549,7 +1538,7 @@ implementation | |||||||
|           { generate code for this procedure } |           { generate code for this procedure } | ||||||
|           pi.generate_code; |           pi.generate_code; | ||||||
|           { process nested procs } |           { process nested procs } | ||||||
|           hpi:=tcgprocinfo(pi.nestedprocs.first); |           hpi:=tcgprocinfo(pi.get_first_nestedproc); | ||||||
|           while assigned(hpi) do |           while assigned(hpi) do | ||||||
|            begin |            begin | ||||||
|              do_generate_code(hpi); |              do_generate_code(hpi); | ||||||
| @ -1602,7 +1591,7 @@ implementation | |||||||
|         { We can't support inlining for procedures that have nested |         { We can't support inlining for procedures that have nested | ||||||
|           procedures because the nested procedures use a fixed offset |           procedures because the nested procedures use a fixed offset | ||||||
|           for accessing locals in the parent procedure (PFV) } |           for accessing locals in the parent procedure (PFV) } | ||||||
|         if (tcgprocinfo(current_procinfo).nestedprocs.count>0) then |         if current_procinfo.has_nestedprocs then | ||||||
|           begin |           begin | ||||||
|             if (df_generic in current_procinfo.procdef.defoptions) then |             if (df_generic in current_procinfo.procdef.defoptions) then | ||||||
|               Comment(V_Error,'Generic methods cannot have nested procedures') |               Comment(V_Error,'Generic methods cannot have nested procedures') | ||||||
| @ -1618,9 +1607,7 @@ implementation | |||||||
|         { When it's a nested procedure then defer the code generation, |         { When it's a nested procedure then defer the code generation, | ||||||
|           when back at normal function level then generate the code |           when back at normal function level then generate the code | ||||||
|           for all defered nested procedures and the current procedure } |           for all defered nested procedures and the current procedure } | ||||||
|         if isnestedproc then |         if not isnestedproc then | ||||||
|           tcgprocinfo(current_procinfo.parent).nestedprocs.insert(current_procinfo) |  | ||||||
|         else |  | ||||||
|           begin |           begin | ||||||
|             if not(df_generic in current_procinfo.procdef.defoptions) then |             if not(df_generic in current_procinfo.procdef.defoptions) then | ||||||
|               do_generate_code(tcgprocinfo(current_procinfo)); |               do_generate_code(tcgprocinfo(current_procinfo)); | ||||||
|  | |||||||
| @ -148,7 +148,7 @@ implementation | |||||||
|       if (cs_opt_regvar in current_settings.optimizerswitches) and |       if (cs_opt_regvar in current_settings.optimizerswitches) and | ||||||
|         { we have to store regvars back to memory in this case (the nested } |         { we have to store regvars back to memory in this case (the nested } | ||||||
|         { procedures can access the variables of the parent)               } |         { procedures can access the variables of the parent)               } | ||||||
|         (tcgprocinfo(current_procinfo).nestedprocs.count = 0) and |         (not current_procinfo.has_nestedprocs) and | ||||||
|          not(pi_has_assembler_block in current_procinfo.flags) and |          not(pi_has_assembler_block in current_procinfo.flags) and | ||||||
|          not(pi_uses_exceptions in current_procinfo.flags) then |          not(pi_uses_exceptions in current_procinfo.flags) then | ||||||
|         begin |         begin | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 sergei
						sergei