mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 15:39:24 +01:00 
			
		
		
		
	* load all complex loads of parameters that are needed multiple times
to a temp to prevent calling functions twice
This commit is contained in:
		
							parent
							
								
									50bbe3c205
								
							
						
					
					
						commit
						521b7cfa3b
					
				@ -221,28 +221,35 @@ type
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    procedure maybe_load_para_in_temp(var p:tnode);
 | 
					    procedure maybe_load_para_in_temp(var p:tnode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        function is_simple_node(hp:tnode):boolean;
 | 
				
			||||||
 | 
					        begin
 | 
				
			||||||
 | 
					          is_simple_node:=(hp.nodetype in [typen,loadvmtaddrn,loadn,arrayconstructorn]);
 | 
				
			||||||
 | 
					        end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      var
 | 
					      var
 | 
				
			||||||
        hp    : tnode;
 | 
					        hp,
 | 
				
			||||||
 | 
					        loadp,
 | 
				
			||||||
 | 
					        refp  : tnode;
 | 
				
			||||||
 | 
					        htype : ttype;
 | 
				
			||||||
        ptemp : ttempcreatenode;
 | 
					        ptemp : ttempcreatenode;
 | 
				
			||||||
 | 
					        usederef : boolean;
 | 
				
			||||||
        newinitstatement,
 | 
					        newinitstatement,
 | 
				
			||||||
        newdonestatement : tstatementnode;
 | 
					        newdonestatement : tstatementnode;
 | 
				
			||||||
      begin
 | 
					      begin
 | 
				
			||||||
        if not assigned(aktcallnode) then
 | 
					        if not assigned(aktcallnode) then
 | 
				
			||||||
          internalerror(200410121);
 | 
					          internalerror(200410121);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        { Load all complex loads into a temp to prevent
 | 
				
			||||||
 | 
					          double calls to a function. We can't simply check for a hp.nodetype=calln
 | 
				
			||||||
 | 
					           }
 | 
				
			||||||
        hp:=p;
 | 
					        hp:=p;
 | 
				
			||||||
        while assigned(hp) and
 | 
					        while assigned(hp) and
 | 
				
			||||||
              (hp.nodetype=typeconvn) do
 | 
					              (hp.nodetype=typeconvn) and
 | 
				
			||||||
 | 
					              (ttypeconvnode(hp).convtype=tc_equal) do
 | 
				
			||||||
          hp:=tunarynode(hp).left;
 | 
					          hp:=tunarynode(hp).left;
 | 
				
			||||||
        if assigned(hp) and
 | 
					        if assigned(hp) and
 | 
				
			||||||
           (
 | 
					           not is_simple_node(hp) then
 | 
				
			||||||
            { call result must always be loaded in temp to prevent
 | 
					 | 
				
			||||||
              double creation }
 | 
					 | 
				
			||||||
            (hp.nodetype=calln)
 | 
					 | 
				
			||||||
            { Also optimize also complex loads }
 | 
					 | 
				
			||||||
{$warning Complex loads can also be optimized}
 | 
					 | 
				
			||||||
//            or not(hp.nodetype in [typen,loadvmtaddrn,loadn])
 | 
					 | 
				
			||||||
           )  then
 | 
					 | 
				
			||||||
          begin
 | 
					          begin
 | 
				
			||||||
            if not assigned(aktcallnode.methodpointerinit) then
 | 
					            if not assigned(aktcallnode.methodpointerinit) then
 | 
				
			||||||
              begin
 | 
					              begin
 | 
				
			||||||
@ -255,17 +262,35 @@ type
 | 
				
			|||||||
                newdonestatement:=laststatement(aktcallnode.methodpointerdone);
 | 
					                newdonestatement:=laststatement(aktcallnode.methodpointerdone);
 | 
				
			||||||
              end;
 | 
					              end;
 | 
				
			||||||
            { temp create }
 | 
					            { temp create }
 | 
				
			||||||
            ptemp:=ctempcreatenode.create(p.resulttype,p.resulttype.def.size,tt_persistent,true);
 | 
					            usederef:=(p.resulttype.def.deftype in [arraydef,recorddef]) or
 | 
				
			||||||
 | 
					                      is_shortstring(p.resulttype.def) or
 | 
				
			||||||
 | 
					                      is_object(p.resulttype.def);
 | 
				
			||||||
 | 
					            if usederef then
 | 
				
			||||||
 | 
					              htype.setdef(tpointerdef.create(p.resulttype))
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					              htype:=p.resulttype;
 | 
				
			||||||
 | 
					            ptemp:=ctempcreatenode.create(htype,htype.def.size,tt_persistent,true);
 | 
				
			||||||
 | 
					            if usederef then
 | 
				
			||||||
 | 
					              begin
 | 
				
			||||||
 | 
					                loadp:=caddrnode.create_internal(p);
 | 
				
			||||||
 | 
					                refp:=cderefnode.create(ctemprefnode.create(ptemp));
 | 
				
			||||||
 | 
					              end
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					              begin
 | 
				
			||||||
 | 
					                loadp:=p;
 | 
				
			||||||
 | 
					                refp:=ctemprefnode.create(ptemp);
 | 
				
			||||||
 | 
					              end;
 | 
				
			||||||
            addstatement(newinitstatement,ptemp);
 | 
					            addstatement(newinitstatement,ptemp);
 | 
				
			||||||
            addstatement(newinitstatement,cassignmentnode.create(
 | 
					            addstatement(newinitstatement,cassignmentnode.create(
 | 
				
			||||||
                ctemprefnode.create(ptemp),
 | 
					                ctemprefnode.create(ptemp),
 | 
				
			||||||
                p));
 | 
					                loadp));
 | 
				
			||||||
            resulttypepass(aktcallnode.methodpointerinit);
 | 
					 | 
				
			||||||
            { new tree is only a temp reference }
 | 
					            { new tree is only a temp reference }
 | 
				
			||||||
            p:=ctemprefnode.create(ptemp);
 | 
					            p:=refp;
 | 
				
			||||||
            resulttypepass(p);
 | 
					 | 
				
			||||||
            { temp release }
 | 
					            { temp release }
 | 
				
			||||||
            addstatement(newdonestatement,ctempdeletenode.create(ptemp));
 | 
					            addstatement(newdonestatement,ctempdeletenode.create(ptemp));
 | 
				
			||||||
 | 
					            { call resulttypepass for new nodes }
 | 
				
			||||||
 | 
					            resulttypepass(p);
 | 
				
			||||||
 | 
					            resulttypepass(aktcallnode.methodpointerinit);
 | 
				
			||||||
            resulttypepass(aktcallnode.methodpointerdone);
 | 
					            resulttypepass(aktcallnode.methodpointerdone);
 | 
				
			||||||
          end;
 | 
					          end;
 | 
				
			||||||
      end;
 | 
					      end;
 | 
				
			||||||
@ -504,6 +529,8 @@ type
 | 
				
			|||||||
                 { set some settings needed for arrayconstructor }
 | 
					                 { set some settings needed for arrayconstructor }
 | 
				
			||||||
                 if is_array_constructor(left.resulttype.def) then
 | 
					                 if is_array_constructor(left.resulttype.def) then
 | 
				
			||||||
                  begin
 | 
					                  begin
 | 
				
			||||||
 | 
					                    if left.nodetype<>arrayconstructorn then
 | 
				
			||||||
 | 
					                      internalerror(200504041);
 | 
				
			||||||
                    if is_array_of_const(parasym.vartype.def) then
 | 
					                    if is_array_of_const(parasym.vartype.def) then
 | 
				
			||||||
                     begin
 | 
					                     begin
 | 
				
			||||||
                       { force variant array }
 | 
					                       { force variant array }
 | 
				
			||||||
@ -2520,7 +2547,11 @@ begin
 | 
				
			|||||||
end.
 | 
					end.
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  $Log$
 | 
					  $Log$
 | 
				
			||||||
  Revision 1.282  2005-03-28 15:05:17  peter
 | 
					  Revision 1.283  2005-04-05 21:07:43  peter
 | 
				
			||||||
 | 
					    * load all complex loads of parameters that are needed multiple times
 | 
				
			||||||
 | 
					      to a temp to prevent calling functions twice
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Revision 1.282  2005/03/28 15:05:17  peter
 | 
				
			||||||
  fix type of temps generated for parameters during inlining
 | 
					  fix type of temps generated for parameters during inlining
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Revision 1.281  2005/03/25 22:20:18  peter
 | 
					  Revision 1.281  2005/03/25 22:20:18  peter
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user