瀏覽代碼

* nf_is_funcret node flag added
* remove ti_is_funcret, use new node flag instead
* check for funcret node in doreplace instead of funcretsym

git-svn-id: trunk@8578 -

peter 18 年之前
父節點
當前提交
4525df9ea0
共有 4 個文件被更改,包括 15 次插入23 次删除
  1. 2 11
      compiler/nbas.pas
  2. 8 6
      compiler/ncal.pas
  3. 4 6
      compiler/ncgutil.pas
  4. 1 0
      compiler/node.pas

+ 2 - 11
compiler/nbas.pas

@@ -94,12 +94,11 @@ interface
 
 
        ttempcreatenode = class;
        ttempcreatenode = class;
 
 
-       ttempinfoflag = (ti_may_be_in_reg,ti_valid,ti_nextref_set_hookoncopy_nil,ti_is_funcret,
-        ti_addr_taken);
+       ttempinfoflag = (ti_may_be_in_reg,ti_valid,ti_nextref_set_hookoncopy_nil,ti_addr_taken);
        ttempinfoflags = set of ttempinfoflag;
        ttempinfoflags = set of ttempinfoflag;
 
 
 const
 const
-       tempinfostoreflags = [ti_may_be_in_reg,ti_is_funcret,ti_addr_taken];
+       tempinfostoreflags = [ti_may_be_in_reg,ti_addr_taken];
 
 
 type
 type
        { to allow access to the location by temp references even after the temp has }
        { to allow access to the location by temp references even after the temp has }
@@ -133,7 +132,6 @@ type
           { to it and *not* generate a ttempdeletenode                          }
           { to it and *not* generate a ttempdeletenode                          }
           constructor create(_typedef: tdef; _size: aint; _temptype: ttemptype;allowreg:boolean); virtual;
           constructor create(_typedef: tdef; _size: aint; _temptype: ttemptype;allowreg:boolean); virtual;
           constructor create_withnode(_typedef: tdef; _size: aint; _temptype: ttemptype; allowreg:boolean; withnode: tnode); virtual;
           constructor create_withnode(_typedef: tdef; _size: aint; _temptype: ttemptype; allowreg:boolean; withnode: tnode); virtual;
-          constructor create_funcret(_typedef: tdef; _size: aint; _temptype: ttemptype; allowreg:boolean); virtual;
           constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
           constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure buildderefimpl;override;
           procedure buildderefimpl;override;
@@ -742,13 +740,6 @@ implementation
       end;
       end;
 
 
 
 
-    constructor ttempcreatenode.create_funcret(_typedef: tdef; _size: aint; _temptype: ttemptype; allowreg:boolean);
-      begin
-        self.create(_typedef,_size,_temptype,allowreg);
-        include(tempinfo^.flags,ti_is_funcret);
-      end;
-
-
     function ttempcreatenode.dogetcopy: tnode;
     function ttempcreatenode.dogetcopy: tnode;
       var
       var
         n: ttempcreatenode;
         n: ttempcreatenode;

+ 8 - 6
compiler/ncal.pas

@@ -1696,11 +1696,14 @@ implementation
                ) then
                ) then
               begin
               begin
                 funcretnode:=aktassignmentnode.left.getcopy;
                 funcretnode:=aktassignmentnode.left.getcopy;
+                include(funcretnode.flags,nf_is_funcret);
+                { notify the assignment node that the assignment can be removed }
                 include(aktassignmentnode.flags,nf_assign_done_in_right);
                 include(aktassignmentnode.flags,nf_assign_done_in_right);
               end
               end
             else
             else
               begin
               begin
-                temp:=ctempcreatenode.create_funcret(resultdef,resultdef.size,tt_persistent,false);
+                temp:=ctempcreatenode.create(resultdef,resultdef.size,tt_persistent,false);
+                include(temp.flags,nf_is_funcret);
                 add_init_statement(temp);
                 add_init_statement(temp);
                 { When the function result is not used in an inlined function
                 { When the function result is not used in an inlined function
                   we need to delete the temp. This can currently only be done by
                   we need to delete the temp. This can currently only be done by
@@ -1711,6 +1714,7 @@ implementation
                 else
                 else
                   add_done_statement(ctempdeletenode.create_normal_temp(temp));
                   add_done_statement(ctempdeletenode.create_normal_temp(temp));
                 funcretnode:=ctemprefnode.create(temp);
                 funcretnode:=ctemprefnode.create(temp);
+                include(funcretnode.flags,nf_is_funcret);
               end;
               end;
           end;
           end;
       end;
       end;
@@ -3056,7 +3060,6 @@ implementation
         hp  : tstatementnode;
         hp  : tstatementnode;
         hp2 : tnode;
         hp2 : tnode;
         resassign : tassignmentnode;
         resassign : tassignmentnode;
-        funcrettemp : ttempcreatenode;
       begin
       begin
         result:=nil;
         result:=nil;
         if not assigned(funcretnode) or
         if not assigned(funcretnode) or
@@ -3067,9 +3070,8 @@ implementation
         hp:=tstatementnode(inlineblock.left);
         hp:=tstatementnode(inlineblock.left);
         if not(assigned(hp)) or
         if not(assigned(hp)) or
            (hp.left.nodetype <> tempcreaten) or
            (hp.left.nodetype <> tempcreaten) or
-           not(ti_is_funcret in ttempcreatenode(hp.left).tempinfo^.flags) then
+           not(nf_is_funcret in hp.left.flags) then
           exit;
           exit;
-        funcrettemp:=ttempcreatenode(hp.left);
 
 
         { constant assignment? right must be a constant (mainly to avoid trying
         { constant assignment? right must be a constant (mainly to avoid trying
           to reuse local temps which may already be freed afterwards once these
           to reuse local temps which may already be freed afterwards once these
@@ -3088,7 +3090,7 @@ implementation
         if (hp2.nodetype=typeconvn) and (ttypeconvnode(hp2).convtype=tc_equal) then
         if (hp2.nodetype=typeconvn) and (ttypeconvnode(hp2).convtype=tc_equal) then
           hp2:=ttypeconvnode(hp2).left;
           hp2:=ttypeconvnode(hp2).left;
         if (hp2.nodetype<>temprefn) or
         if (hp2.nodetype<>temprefn) or
-           (ttemprefnode(hp2).tempinfo^.owner<>funcrettemp) then
+           not(nf_is_funcret in hp2.flags) then
           exit;
           exit;
 
 
         { tempdelete to normal of the function result }
         { tempdelete to normal of the function result }
@@ -3101,7 +3103,7 @@ implementation
         hp:=tstatementnode(hp.right);
         hp:=tstatementnode(hp.right);
         if not(assigned(hp)) or
         if not(assigned(hp)) or
            (hp.left.nodetype<>temprefn) or
            (hp.left.nodetype<>temprefn) or
-           (ttemprefnode(hp.left).tempinfo^.owner<>funcrettemp) then
+           not(nf_is_funcret in hp.left.flags) then
           exit;
           exit;
 
 
         { should be the end }
         { should be the end }

+ 4 - 6
compiler/ncgutil.pas

@@ -2488,14 +2488,14 @@ implementation
         rr: preplaceregrec absolute para;
         rr: preplaceregrec absolute para;
       begin
       begin
         result := fen_false;
         result := fen_false;
+        if (nf_is_funcret in n.flags) and (fc_exit in flowcontrol) then
+          exit;
         case n.nodetype of
         case n.nodetype of
           loadn:
           loadn:
             begin
             begin
               if (tabstractvarsym(tloadnode(n).symtableentry).varoptions * [vo_is_dll_var, vo_is_thread_var] = []) and
               if (tabstractvarsym(tloadnode(n).symtableentry).varoptions * [vo_is_dll_var, vo_is_thread_var] = []) and
                  not assigned(tloadnode(n).left) and
                  not assigned(tloadnode(n).left) and
-                 (((tloadnode(n).symtableentry <> rr^.ressym) and
-                   not(vo_is_funcret in tabstractvarsym(tloadnode(n).symtableentry).varoptions)) or
-                  not(fc_exit in flowcontrol)) and
+                 (tloadnode(n).symtableentry <> rr^.ressym) and
                  (tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.loc in [LOC_CREGISTER,LOC_CFPUREGISTER,LOC_CMMXREGISTER,LOC_CMMREGISTER]) and
                  (tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.loc in [LOC_CREGISTER,LOC_CFPUREGISTER,LOC_CMMXREGISTER,LOC_CMMREGISTER]) and
                  (tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.register = rr^.old) then
                  (tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.register = rr^.old) then
                 begin
                 begin
@@ -2516,9 +2516,7 @@ implementation
             begin
             begin
               if (ti_valid in ttemprefnode(n).tempinfo^.flags) and
               if (ti_valid in ttemprefnode(n).tempinfo^.flags) and
                  (ttemprefnode(n).tempinfo^.location.loc in [LOC_CREGISTER,LOC_CFPUREGISTER,LOC_CMMXREGISTER,LOC_CMMREGISTER]) and
                  (ttemprefnode(n).tempinfo^.location.loc in [LOC_CREGISTER,LOC_CFPUREGISTER,LOC_CMMXREGISTER,LOC_CMMREGISTER]) and
-                 (ttemprefnode(n).tempinfo^.location.register = rr^.old) and
-                 (not(ti_is_funcret in ttemprefnode(n).tempinfo^.flags) or
-                  not(fc_exit in flowcontrol)) then
+                 (ttemprefnode(n).tempinfo^.location.register = rr^.old) then
                 begin
                 begin
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
                   { it's possible a 64 bit location was shifted and/xor typecasted }
                   { it's possible a 64 bit location was shifted and/xor typecasted }

+ 1 - 0
compiler/node.pas

@@ -202,6 +202,7 @@ interface
          { general }
          { general }
          nf_pass1_done,
          nf_pass1_done,
          nf_write,       { Node is written to            }
          nf_write,       { Node is written to            }
+         nf_is_funcret,
          nf_isproperty,
          nf_isproperty,
          nf_processing,
          nf_processing,