Browse Source

* use saveregisters for incr routines, saves also problems with
the optimizer

peter 23 years ago
parent
commit
268e4bb7e7
6 changed files with 88 additions and 83 deletions
  1. 28 22
      compiler/cgobj.pas
  2. 21 38
      compiler/i386/n386ld.pas
  3. 10 6
      rtl/inc/astrings.inc
  4. 9 5
      rtl/inc/dynarr.inc
  5. 11 7
      rtl/inc/objpas.inc
  6. 9 5
      rtl/inc/wstrings.inc

+ 28 - 22
compiler/cgobj.pas

@@ -1405,62 +1405,64 @@ unit cgobj;
     procedure tcg.g_incrrefcount(list : taasmoutput;t: tdef; const ref: treference);
     procedure tcg.g_incrrefcount(list : taasmoutput;t: tdef; const ref: treference);
       var
       var
         href : treference;
         href : treference;
-        pushedregs : tpushedsaved;
-        decrfunc : string;
+        incrfunc : string;
       begin
       begin
-         rg.saveusedregisters(list,pushedregs,all_registers);
+         { These functions should not change the registers (they use
+           the saveregister proc directive }
          if is_interfacecom(t) then
          if is_interfacecom(t) then
-          decrfunc:='FPC_INTF_INCR_REF'
+          incrfunc:='FPC_INTF_INCR_REF'
          else if is_ansistring(t) then
          else if is_ansistring(t) then
-          decrfunc:='FPC_ANSISTR_INCR_REF'
+          incrfunc:='FPC_ANSISTR_INCR_REF'
          else if is_widestring(t) then
          else if is_widestring(t) then
-          decrfunc:='FPC_WIDESTR_INCR_REF'
+          incrfunc:='FPC_WIDESTR_INCR_REF'
+         else if is_dynamic_array(t) then
+          incrfunc:='FPC_DYNARRAY_INCR_REF'
          else
          else
-          decrfunc:='';
-         { call the special decr function or the generic decref }
-         if decrfunc<>'' then
-          cg.a_param_ref(list,OS_ADDR,ref,1)
+          incrfunc:='';
+         { call the special incr function or the generic addref }
+         if incrfunc<>'' then
+          begin
+            a_param_ref(list,OS_ADDR,ref,1);
+            a_call_name(list,incrfunc,0);
+          end
          else
          else
           begin
           begin
             reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
             reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
             a_paramaddr_ref(list,href,2);
             a_paramaddr_ref(list,href,2);
             a_paramaddr_ref(list,ref,1);
             a_paramaddr_ref(list,ref,1);
-            decrfunc:='FPC_ADDREF';
+            a_call_name(list,'FPC_ADDREF',0);
          end;
          end;
-        rg.saveregvars(exprasmlist,all_registers);
-        a_call_name(list,decrfunc,0);
-        rg.restoreusedregisters(list,pushedregs);
       end;
       end;
 
 
 
 
     procedure tcg.g_decrrefcount(list : taasmoutput;t: tdef; const ref: treference);
     procedure tcg.g_decrrefcount(list : taasmoutput;t: tdef; const ref: treference);
       var
       var
         href : treference;
         href : treference;
-        pushedregs : tpushedsaved;
         decrfunc : string;
         decrfunc : string;
       begin
       begin
-         rg.saveusedregisters(list,pushedregs,all_registers);
          if is_interfacecom(t) then
          if is_interfacecom(t) then
           decrfunc:='FPC_INTF_DECR_REF'
           decrfunc:='FPC_INTF_DECR_REF'
          else if is_ansistring(t) then
          else if is_ansistring(t) then
           decrfunc:='FPC_ANSISTR_DECR_REF'
           decrfunc:='FPC_ANSISTR_DECR_REF'
          else if is_widestring(t) then
          else if is_widestring(t) then
           decrfunc:='FPC_WIDESTR_DECR_REF'
           decrfunc:='FPC_WIDESTR_DECR_REF'
+         else if is_dynamic_array(t) then
+          decrfunc:='FPC_DYNARRAY_INCR_REF'
          else
          else
           decrfunc:='';
           decrfunc:='';
          { call the special decr function or the generic decref }
          { call the special decr function or the generic decref }
          if decrfunc<>'' then
          if decrfunc<>'' then
-          cg.a_paramaddr_ref(list,ref,1)
+          begin
+            a_paramaddr_ref(list,ref,1);
+            a_call_name(list,decrfunc,0);
+          end
          else
          else
           begin
           begin
             reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
             reference_reset_symbol(href,tstoreddef(t).get_rtti_label(initrtti),0);
             a_paramaddr_ref(list,href,2);
             a_paramaddr_ref(list,href,2);
             a_paramaddr_ref(list,ref,1);
             a_paramaddr_ref(list,ref,1);
-            decrfunc:='FPC_DECREF';
+            a_call_name(list,'FPC_DECREF',0);
          end;
          end;
-        rg.saveregvars(exprasmlist,all_registers);
-        a_call_name(list,decrfunc,0);
-        rg.restoreusedregisters(list,pushedregs);
       end;
       end;
 
 
 
 
@@ -1636,7 +1638,11 @@ finalization
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.18  2002-04-25 20:16:38  peter
+  Revision 1.19  2002-04-26 15:19:04  peter
+    * use saveregisters for incr routines, saves also problems with
+      the optimizer
+
+  Revision 1.18  2002/04/25 20:16:38  peter
     * moved more routines from cga/n386util
     * moved more routines from cga/n386util
 
 
   Revision 1.17  2002/04/22 16:30:05  peter
   Revision 1.17  2002/04/22 16:30:05  peter

+ 21 - 38
compiler/i386/n386ld.pas

@@ -418,6 +418,11 @@ implementation
             (right.registers32>=left.registers32)) then
             (right.registers32>=left.registers32)) then
          begin
          begin
            secondpass(right);
            secondpass(right);
+           { increment source reference counter, this is
+             useless for string constants}
+           if (right.resulttype.def.needs_inittable) and
+              (right.nodetype<>stringconstn) then
+            cg.g_incrrefcount(exprasmlist,right.resulttype.def,right.location.reference);
            if codegenerror then
            if codegenerror then
              exit;
              exit;
 
 
@@ -430,6 +435,9 @@ implementation
               { can be false                                             }
               { can be false                                             }
               pushed:=maybe_push(left.registers32,right,false);
               pushed:=maybe_push(left.registers32,right,false);
               secondpass(left);
               secondpass(left);
+              { decrement destination reference counter }
+              if (left.resulttype.def.needs_inittable) then
+               cg.g_decrrefcount(exprasmlist,left.resulttype.def,left.location.reference);
               if pushed then
               if pushed then
                 restore(right,false);
                 restore(right,false);
               if codegenerror then
               if codegenerror then
@@ -443,43 +451,27 @@ implementation
            if not(nf_concat_string in flags) then
            if not(nf_concat_string in flags) then
             begin
             begin
               secondpass(left);
               secondpass(left);
+              { decrement destination reference counter }
+              if (left.resulttype.def.needs_inittable) then
+               cg.g_decrrefcount(exprasmlist,left.resulttype.def,left.location.reference);
               if codegenerror then
               if codegenerror then
                exit;
                exit;
             end;
             end;
 
 
-{$ifdef test_dest_loc}
-           { lets try to optimize this (PM)            }
-           { define a dest_loc that is the location      }
-           { and a ptree to verify that it is the right }
-           { place to insert it                    }
-           if (aktexprlevel<4) then
-             begin
-                dest_loc_known:=true;
-                dest_loc:=left.location;
-                dest_loc_tree:=right;
-             end;
-{$endif test_dest_loc}
-
            { left can't be never a 64 bit LOC_REGISTER, so the 3. arg }
            { left can't be never a 64 bit LOC_REGISTER, so the 3. arg }
            { can be false                                             }
            { can be false                                             }
            pushed:=maybe_push(right.registers32,left,is_64bitint(right.resulttype.def));
            pushed:=maybe_push(right.registers32,left,is_64bitint(right.resulttype.def));
            secondpass(right);
            secondpass(right);
+           { increment source reference counter, this is
+             useless for string constants}
+           if (right.resulttype.def.needs_inittable) and
+              (right.nodetype<>stringconstn) then
+            cg.g_incrrefcount(exprasmlist,right.resulttype.def,right.location.reference);
            if pushed  then
            if pushed  then
              restore(left,false);
              restore(left,false);
 
 
            if codegenerror then
            if codegenerror then
              exit;
              exit;
-
-{$ifdef test_dest_loc}
-           dest_loc_known:=false;
-           if in_dest_loc then
-             begin
-                truelabel:=otlabel;
-                falselabel:=oflabel;
-                in_dest_loc:=false;
-                exit;
-             end;
-{$endif test_dest_loc}
          end;
          end;
 
 
         if not(left.location.loc in [LOC_REFERENCE,LOC_CFPUREGISTER,
         if not(left.location.loc in [LOC_REFERENCE,LOC_CFPUREGISTER,
@@ -575,19 +567,6 @@ implementation
                     LOC_REFERENCE,
                     LOC_REFERENCE,
                     LOC_CREFERENCE :
                     LOC_CREFERENCE :
                       begin
                       begin
-                        if (right.resulttype.def.needs_inittable) then
-                          begin
-                             { this would be a problem }
-                             if not(left.resulttype.def.needs_inittable) then
-                               internalerror(3457);
-                             { increment source reference counter, this is
-                               useless for string constants}
-                             if right.nodetype<>stringconstn then
-                              cg.g_incrrefcount(exprasmlist,right.resulttype.def,right.location.reference);
-                             { decrement destination reference counter }
-                             cg.g_decrrefcount(exprasmlist,left.resulttype.def,left.location.reference);
-                          end;
-
                         concatcopy(right.location.reference,
                         concatcopy(right.location.reference,
                                    left.location.reference,left.resulttype.def.size,true,false);
                                    left.location.reference,left.resulttype.def.size,true,false);
                         { right.location is already released by concatcopy }
                         { right.location is already released by concatcopy }
@@ -744,7 +723,11 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.39  2002-04-25 20:16:40  peter
+  Revision 1.40  2002-04-26 15:19:05  peter
+    * use saveregisters for incr routines, saves also problems with
+      the optimizer
+
+  Revision 1.39  2002/04/25 20:16:40  peter
     * moved more routines from cga/n386util
     * moved more routines from cga/n386util
 
 
   Revision 1.38  2002/04/22 16:30:06  peter
   Revision 1.38  2002/04/22 16:30:06  peter

+ 10 - 6
rtl/inc/astrings.inc

@@ -106,7 +106,7 @@ begin
 end;
 end;
 
 
 
 
-Procedure fpc_AnsiStr_Decr_Ref (Var S : Pointer);[Public,Alias:'FPC_ANSISTR_DECR_REF'];  {$ifdef hascompilerproc} compilerproc; {$endif}
+Procedure fpc_AnsiStr_Decr_Ref (Var S : Pointer);saveregisters;[Public,Alias:'FPC_ANSISTR_DECR_REF'];  {$ifdef hascompilerproc} compilerproc; {$endif}
 {
 {
   Decreases the ReferenceCount of a non constant ansistring;
   Decreases the ReferenceCount of a non constant ansistring;
   If the reference count is zero, deallocate the string;
   If the reference count is zero, deallocate the string;
@@ -132,13 +132,13 @@ end;
 
 
 {$ifdef hascompilerproc}
 {$ifdef hascompilerproc}
 { also define alias for internal use in the system unit }
 { also define alias for internal use in the system unit }
-Procedure fpc_AnsiStr_Decr_Ref (Var S : Pointer); [external name 'FPC_ANSISTR_DECR_REF'];
+Procedure fpc_AnsiStr_Decr_Ref (Var S : Pointer);saveregisters; [external name 'FPC_ANSISTR_DECR_REF'];
 {$endif hascompilerproc}
 {$endif hascompilerproc}
 
 
 {$ifdef hascompilerproc}
 {$ifdef hascompilerproc}
-Procedure fpc_AnsiStr_Incr_Ref (S : Pointer);[Public,Alias:'FPC_ANSISTR_INCR_REF'];  {$ifdef hascompilerproc} compilerproc; {$endif}
+Procedure fpc_AnsiStr_Incr_Ref (S : Pointer);saveregisters;[Public,Alias:'FPC_ANSISTR_INCR_REF'];  {$ifdef hascompilerproc} compilerproc; {$endif}
 {$else}
 {$else}
-Procedure fpc_AnsiStr_Incr_Ref (Var S : Pointer);[Public,Alias:'FPC_ANSISTR_INCR_REF'];
+Procedure fpc_AnsiStr_Incr_Ref (Var S : Pointer);saveregisters;[Public,Alias:'FPC_ANSISTR_INCR_REF'];
 {$endif}
 {$endif}
 Begin
 Begin
   If S=Nil then
   If S=Nil then
@@ -150,7 +150,7 @@ end;
 
 
 {$ifdef hascompilerproc}
 {$ifdef hascompilerproc}
 { also define alias which can be used inside the system unit }
 { also define alias which can be used inside the system unit }
-Procedure fpc_AnsiStr_Incr_Ref (S : Pointer); [external name 'FPC_ANSISTR_INCR_REF'];
+Procedure fpc_AnsiStr_Incr_Ref (S : Pointer);saveregisters; [external name 'FPC_ANSISTR_INCR_REF'];
 {$endif hascompilerproc}
 {$endif hascompilerproc}
 
 
 Procedure fpc_AnsiStr_Assign (Var S1 : Pointer;S2 : Pointer);[Public,Alias:'FPC_ANSISTR_ASSIGN'];  {$ifdef hascompilerproc} compilerproc; {$endif}
 Procedure fpc_AnsiStr_Assign (Var S1 : Pointer;S2 : Pointer);[Public,Alias:'FPC_ANSISTR_ASSIGN'];  {$ifdef hascompilerproc} compilerproc; {$endif}
@@ -801,7 +801,11 @@ end;
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.24  2002-04-25 20:14:56  peter
+  Revision 1.25  2002-04-26 15:19:05  peter
+    * use saveregisters for incr routines, saves also problems with
+      the optimizer
+
+  Revision 1.24  2002/04/25 20:14:56  peter
     * updated compilerprocs
     * updated compilerprocs
     * incr ref count has now a value argument instead of var
     * incr ref count has now a value argument instead of var
 
 

+ 9 - 5
rtl/inc/dynarr.inc

@@ -76,7 +76,7 @@ Procedure fpc_dynarray_clear (var p : pointer;ti : pointer);[external name 'FPC_
 {$endif hascompilerproc}
 {$endif hascompilerproc}
 
 
 
 
-procedure fpc_dynarray_decr_ref(var p : pointer;ti : pointer);[Public,Alias:'FPC_DYNARRAY_DECR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
+procedure fpc_dynarray_decr_ref(var p : pointer;ti : pointer);saveregisters;[Public,Alias:'FPC_DYNARRAY_DECR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
   var
   var
      realp : pdynarray;
      realp : pdynarray;
   begin
   begin
@@ -96,10 +96,10 @@ procedure fpc_dynarray_decr_ref(var p : pointer;ti : pointer);[Public,Alias:'FPC
 
 
 {$ifdef hascompilerproc}
 {$ifdef hascompilerproc}
 { provide local access to dynarr_decr_ref for dynarr_setlength }
 { provide local access to dynarr_decr_ref for dynarr_setlength }
-procedure fpc_dynarray_decr_ref(var p : pointer;ti : pointer); [external name 'FPC_DYNARRAY_DECR_REF'];
+procedure fpc_dynarray_decr_ref(var p : pointer;ti : pointer);saveregisters; [external name 'FPC_DYNARRAY_DECR_REF'];
 {$endif}
 {$endif}
 
 
-procedure fpc_dynarray_incr_ref(p : pointer);[Public,Alias:'FPC_DYNARRAY_INCR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
+procedure fpc_dynarray_incr_ref(p : pointer);saveregisters;[Public,Alias:'FPC_DYNARRAY_INCR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
   var
   var
      realp : pdynarray;
      realp : pdynarray;
   begin
   begin
@@ -115,7 +115,7 @@ procedure fpc_dynarray_incr_ref(p : pointer);[Public,Alias:'FPC_DYNARRAY_INCR_RE
 
 
 {$ifdef hascompilerproc}
 {$ifdef hascompilerproc}
 { provide local access to dynarr_decr_ref for dynarr_setlength }
 { provide local access to dynarr_decr_ref for dynarr_setlength }
-procedure fpc_dynarray_incr_ref(p : pointer); [external name 'FPC_DYNARRAY_INCR_REF'];
+procedure fpc_dynarray_incr_ref(p : pointer);saveregisters; [external name 'FPC_DYNARRAY_INCR_REF'];
 {$endif}
 {$endif}
 
 
 { provide local access to dynarr_setlength }
 { provide local access to dynarr_setlength }
@@ -261,7 +261,11 @@ function fpc_dynarray_copy(var p : pointer;ti : pointer;
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.16  2002-04-25 20:14:56  peter
+  Revision 1.17  2002-04-26 15:19:05  peter
+    * use saveregisters for incr routines, saves also problems with
+      the optimizer
+
+  Revision 1.16  2002/04/25 20:14:56  peter
     * updated compilerprocs
     * updated compilerprocs
     * incr ref count has now a value argument instead of var
     * incr ref count has now a value argument instead of var
 
 

+ 11 - 7
rtl/inc/objpas.inc

@@ -36,11 +36,11 @@
 
 
 {$ifndef HASINTF}
 {$ifndef HASINTF}
     { dummies for make cycle with 1.0.x }
     { dummies for make cycle with 1.0.x }
-    procedure intf_decr_ref(var i: pointer);[public,alias: 'FPC_INTF_DECR_REF'];
+    procedure intf_decr_ref(var i: pointer);saveregisters;[public,alias: 'FPC_INTF_DECR_REF'];
       begin
       begin
       end;
       end;
 
 
-    procedure intf_incr_ref(const i: pointer);[public,alias: 'FPC_INTF_INCR_REF'];
+    procedure intf_incr_ref(const i: pointer);saveregisters;[public,alias: 'FPC_INTF_INCR_REF'];
       begin
       begin
       end;
       end;
 
 
@@ -54,7 +54,7 @@
 
 
 {$else HASINTF}
 {$else HASINTF}
     { interface helpers }
     { interface helpers }
-    procedure fpc_intf_decr_ref(var i: pointer);[public,alias: 'FPC_INTF_DECR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
+    procedure fpc_intf_decr_ref(var i: pointer);saveregisters;[public,alias: 'FPC_INTF_DECR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
       begin
       begin
         if assigned(i) then
         if assigned(i) then
           IUnknown(i)._Release;
           IUnknown(i)._Release;
@@ -63,11 +63,11 @@
 
 
     {$ifdef hascompilerproc}
     {$ifdef hascompilerproc}
     { local declaration for intf_decr_ref for local access }
     { local declaration for intf_decr_ref for local access }
-    procedure intf_decr_ref(var i: pointer); [external name 'FPC_INTF_DECR_REF'];
+    procedure intf_decr_ref(var i: pointer);saveregisters; [external name 'FPC_INTF_DECR_REF'];
     {$endif hascompilerproc}
     {$endif hascompilerproc}
 
 
 
 
-    procedure fpc_intf_incr_ref(i: pointer);[public,alias: 'FPC_INTF_INCR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
+    procedure fpc_intf_incr_ref(i: pointer);saveregisters;[public,alias: 'FPC_INTF_INCR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
       begin
       begin
          if assigned(i) then
          if assigned(i) then
            IUnknown(i)._AddRef;
            IUnknown(i)._AddRef;
@@ -75,7 +75,7 @@
 
 
     {$ifdef hascompilerproc}
     {$ifdef hascompilerproc}
     { local declaration of intf_incr_ref for local access }
     { local declaration of intf_incr_ref for local access }
-    procedure intf_incr_ref(i: pointer); [external name 'FPC_INTF_INCR_REF'];
+    procedure intf_incr_ref(i: pointer);saveregisters; [external name 'FPC_INTF_INCR_REF'];
     {$endif hascompilerproc}
     {$endif hascompilerproc}
 
 
     procedure fpc_intf_assign(var D: pointer; const S: pointer);[public,alias: 'FPC_INTF_ASSIGN']; {$ifdef hascompilerproc} compilerproc; {$endif}
     procedure fpc_intf_assign(var D: pointer; const S: pointer);[public,alias: 'FPC_INTF_ASSIGN']; {$ifdef hascompilerproc} compilerproc; {$endif}
@@ -696,7 +696,11 @@
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.20  2002-04-25 20:14:57  peter
+  Revision 1.21  2002-04-26 15:19:05  peter
+    * use saveregisters for incr routines, saves also problems with
+      the optimizer
+
+  Revision 1.20  2002/04/25 20:14:57  peter
     * updated compilerprocs
     * updated compilerprocs
     * incr ref count has now a value argument instead of var
     * incr ref count has now a value argument instead of var
 
 

+ 9 - 5
rtl/inc/wstrings.inc

@@ -161,7 +161,7 @@ begin
 end;
 end;
 
 
 
 
-Procedure fpc_WideStr_Decr_Ref (Var S : Pointer);[Public,Alias:'FPC_WIDESTR_DECR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
+Procedure fpc_WideStr_Decr_Ref (Var S : Pointer);saveregisters;[Public,Alias:'FPC_WIDESTR_DECR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
 {
 {
   Decreases the ReferenceCount of a non constant widestring;
   Decreases the ReferenceCount of a non constant widestring;
   If the reference count is zero, deallocate the string;
   If the reference count is zero, deallocate the string;
@@ -187,13 +187,13 @@ end;
 
 
 {$ifdef hascompilerproc}
 {$ifdef hascompilerproc}
 { alias for internal use }
 { alias for internal use }
-Procedure fpc_WideStr_Decr_Ref (Var S : Pointer);[external name 'FPC_WIDESTR_DECR_REF'];
+Procedure fpc_WideStr_Decr_Ref (Var S : Pointer);saveregisters;[external name 'FPC_WIDESTR_DECR_REF'];
 {$endif compilerproc}
 {$endif compilerproc}
 
 
 {$ifdef hascompilerproc}
 {$ifdef hascompilerproc}
-Procedure fpc_WideStr_Incr_Ref (S : Pointer);[Public,Alias:'FPC_WIDESTR_INCR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
+Procedure fpc_WideStr_Incr_Ref (S : Pointer);saveregisters;[Public,Alias:'FPC_WIDESTR_INCR_REF']; {$ifdef hascompilerproc} compilerproc; {$endif}
 {$else}
 {$else}
-Procedure fpc_WideStr_Incr_Ref (Var S : Pointer);[Public,Alias:'FPC_WIDESTR_INCR_REF'];
+Procedure fpc_WideStr_Incr_Ref (Var S : Pointer);saveregisters;[Public,Alias:'FPC_WIDESTR_INCR_REF'];
 {$endif compilerproc}
 {$endif compilerproc}
 Begin
 Begin
   If S=Nil then
   If S=Nil then
@@ -849,7 +849,11 @@ end;
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.16  2002-04-25 20:14:57  peter
+  Revision 1.17  2002-04-26 15:19:05  peter
+    * use saveregisters for incr routines, saves also problems with
+      the optimizer
+
+  Revision 1.16  2002/04/25 20:14:57  peter
     * updated compilerprocs
     * updated compilerprocs
     * incr ref count has now a value argument instead of var
     * incr ref count has now a value argument instead of var