Browse Source

* less unnecessary regvar loading with if-statements

Jonas Maebe 24 years ago
parent
commit
6dbf240bde
5 changed files with 123 additions and 33 deletions
  1. 12 10
      compiler/i386/n386add.pas
  2. 3 3
      compiler/i386/n386inl.pas
  3. 5 2
      compiler/i386/n386mat.pas
  4. 19 6
      compiler/i386/n386util.pas
  5. 84 12
      compiler/ncgflw.pas

+ 12 - 10
compiler/i386/n386add.pas

@@ -128,16 +128,15 @@ interface
     { ti386addnode.first_string and implement the shortstring concat    }
     { ti386addnode.first_string and implement the shortstring concat    }
     { manually! The generic routine is different from the i386 one (JM) }
     { manually! The generic routine is different from the i386 one (JM) }
     function ti386addnode.first_addstring : tnode;
     function ti386addnode.first_addstring : tnode;
+
       begin
       begin
         { special cases for shortstrings, handled in pass_2 (JM) }
         { special cases for shortstrings, handled in pass_2 (JM) }
         { can't handle fpc_shortstr_compare with compilerproc either because it }
         { can't handle fpc_shortstr_compare with compilerproc either because it }
         { returns its results in the flags instead of in eax                    }
         { returns its results in the flags instead of in eax                    }
-        if ((nodetype = addn) and
-           is_shortstring(resulttype.def)) or
-           ((nodetype in [ltn,lten,gtn,gten,equaln,unequaln]) and
-            not(((left.nodetype=stringconstn) and (str_length(left)=0)) or
-                ((right.nodetype=stringconstn) and (str_length(right)=0))) and
-            is_shortstring(left.resulttype.def)) then
+        if (((nodetype = addn) and
+             is_shortstring(resulttype.def)) or
+            ((nodetype in [ltn,lten,gtn,gten,equaln,unequaln]) and
+             is_shortstring(left.resulttype.def))) then
           begin
           begin
             if nodetype = addn then
             if nodetype = addn then
               location.loc := LOC_MEM
               location.loc := LOC_MEM
@@ -463,7 +462,7 @@ interface
                                   otl:=truelabel;
                                   otl:=truelabel;
                                   getlabel(truelabel);
                                   getlabel(truelabel);
                                   secondpass(left);
                                   secondpass(left);
-                                  maketojumpbool(left);
+                                  maketojumpbool(left,lr_load_regvars);
                                   emitlab(truelabel);
                                   emitlab(truelabel);
                                   truelabel:=otl;
                                   truelabel:=otl;
                                end;
                                end;
@@ -471,7 +470,7 @@ interface
                                  ofl:=falselabel;
                                  ofl:=falselabel;
                                  getlabel(falselabel);
                                  getlabel(falselabel);
                                  secondpass(left);
                                  secondpass(left);
-                                 maketojumpbool(left);
+                                 maketojumpbool(left,lr_load_regvars);
                                  emitlab(falselabel);
                                  emitlab(falselabel);
                                  falselabel:=ofl;
                                  falselabel:=ofl;
                               end;
                               end;
@@ -479,7 +478,7 @@ interface
                          CGMessage(type_e_mismatch);
                          CGMessage(type_e_mismatch);
                        end;
                        end;
                        secondpass(right);
                        secondpass(right);
-                       maketojumpbool(right);
+                       maketojumpbool(right,lr_load_regvars);
                      end;
                      end;
              else
              else
                CGMessage(type_e_mismatch);
                CGMessage(type_e_mismatch);
@@ -1864,7 +1863,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.25  2001-10-12 13:51:51  jonas
+  Revision 1.26  2001-12-02 16:19:17  jonas
+    * less unnecessary regvar loading with if-statements
+
+  Revision 1.25  2001/10/12 13:51:51  jonas
     * fixed internalerror(10) due to previous fpu overflow fixes ("merged")
     * fixed internalerror(10) due to previous fpu overflow fixes ("merged")
     * fixed bug in n386add (introduced after compilerproc changes for string
     * fixed bug in n386add (introduced after compilerproc changes for string
       operations) where calcregisters wasn't called for shortstring addnodes
       operations) where calcregisters wasn't called for shortstring addnodes

+ 3 - 3
compiler/i386/n386inl.pas

@@ -97,7 +97,7 @@ implementation
                  getlabel(truelabel);
                  getlabel(truelabel);
                  getlabel(falselabel);
                  getlabel(falselabel);
                  secondpass(tcallparanode(left).left);
                  secondpass(tcallparanode(left).left);
-                 maketojumpbool(tcallparanode(left).left);
+                 maketojumpbool(tcallparanode(left).left,lr_load_regvars);
                  emitlab(falselabel);
                  emitlab(falselabel);
                  { erroraddr }
                  { erroraddr }
                  emit_reg(A_PUSH,S_L,R_EBP);
                  emit_reg(A_PUSH,S_L,R_EBP);
@@ -843,8 +843,8 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.27  2001-09-30 16:16:28  jonas
-    - removed unused units form uses-clause and unused local vars
+  Revision 1.28  2001-12-02 16:19:17  jonas
+    * less unnecessary regvar loading with if-statements
 
 
   Revision 1.26  2001/09/28 20:38:51  jonas
   Revision 1.26  2001/09/28 20:38:51  jonas
     * fixed big bug in my previous changes (the arguent for bts/btr is always
     * fixed big bug in my previous changes (the arguent for bts/btr is always

+ 5 - 2
compiler/i386/n386mat.pas

@@ -860,7 +860,7 @@ implementation
                   truelabel:=falselabel;
                   truelabel:=falselabel;
                   falselabel:=hl;
                   falselabel:=hl;
                   secondpass(left);
                   secondpass(left);
-                  maketojumpbool(left);
+                  maketojumpbool(left,lr_load_regvars);
                   hl:=truelabel;
                   hl:=truelabel;
                   truelabel:=falselabel;
                   truelabel:=falselabel;
                   falselabel:=hl;
                   falselabel:=hl;
@@ -1016,7 +1016,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.16  2001-09-05 15:22:10  jonas
+  Revision 1.17  2001-12-02 16:19:17  jonas
+    * less unnecessary regvar loading with if-statements
+
+  Revision 1.16  2001/09/05 15:22:10  jonas
     * made multiplying, dividing and mod'ing of int64 and qword processor
     * made multiplying, dividing and mod'ing of int64 and qword processor
       independent with compilerprocs (+ small optimizations by using shift/and
       independent with compilerprocs (+ small optimizations by using shift/and
       where possible)
       where possible)

+ 19 - 6
compiler/i386/n386util.pas

@@ -29,6 +29,9 @@ interface
     uses
     uses
       symtype,node;
       symtype,node;
 
 
+    type
+      tloadregvars = (lr_dont_load_regvars, lr_load_regvars);
+
     function maybe_push(needed : byte;p : tnode;isint64 : boolean) : boolean;
     function maybe_push(needed : byte;p : tnode;isint64 : boolean) : boolean;
     function maybe_pushfpu(needed : byte;p : tnode) : boolean;
     function maybe_pushfpu(needed : byte;p : tnode) : boolean;
 {$ifdef TEMPS_NOT_PUSH}
 {$ifdef TEMPS_NOT_PUSH}
@@ -47,7 +50,7 @@ interface
     procedure loadwide2short(source,dest : tnode);
     procedure loadwide2short(source,dest : tnode);
     procedure loadinterfacecom(p: tbinarynode);
     procedure loadinterfacecom(p: tbinarynode);
 
 
-    procedure maketojumpbool(p : tnode);
+    procedure maketojumpbool(p : tnode; loadregvars: tloadregvars);
     procedure emitoverflowcheck(p:tnode);
     procedure emitoverflowcheck(p:tnode);
     procedure emitrangecheck(p:tnode;todef:tdef);
     procedure emitrangecheck(p:tnode;todef:tdef);
     procedure firstcomplex(p : tbinarynode);
     procedure firstcomplex(p : tbinarynode);
@@ -869,9 +872,14 @@ implementation
                            Emit Functions
                            Emit Functions
 *****************************************************************************}
 *****************************************************************************}
 
 
-    procedure maketojumpbool(p : tnode);
+    procedure maketojumpbool(p : tnode; loadregvars: tloadregvars);
     {
     {
       produces jumps to true respectively false labels using boolean expressions
       produces jumps to true respectively false labels using boolean expressions
+
+      depending on whether the loading of regvars is currently being
+      synchronized manually (such as in an if-node) or automatically (most of
+      the other cases where this procedure is called), loadregvars can be
+      "lr_load_regvars" or "lr_dont_load_regvars"
     }
     }
       var
       var
         opsize : topsize;
         opsize : topsize;
@@ -883,7 +891,8 @@ implementation
          aktfilepos:=p.fileinfo;
          aktfilepos:=p.fileinfo;
          if is_boolean(p.resulttype.def) then
          if is_boolean(p.resulttype.def) then
            begin
            begin
-              load_all_regvars(exprasmlist);
+              if loadregvars = lr_load_regvars then
+                load_all_regvars(exprasmlist);
               if is_constboolnode(p) then
               if is_constboolnode(p) then
                 begin
                 begin
                    if tordconstnode(p).value<>0 then
                    if tordconstnode(p).value<>0 then
@@ -896,6 +905,8 @@ implementation
                    opsize:=def_opsize(p.resulttype.def);
                    opsize:=def_opsize(p.resulttype.def);
                    case p.location.loc of
                    case p.location.loc of
                       LOC_CREGISTER,LOC_REGISTER : begin
                       LOC_CREGISTER,LOC_REGISTER : begin
+                                        if (p.location.loc = LOC_CREGISTER) then
+                                          load_regvar_reg(exprasmlist,p.location.register);
                                         emit_reg_reg(A_OR,opsize,p.location.register,
                                         emit_reg_reg(A_OR,opsize,p.location.register,
                                           p.location.register);
                                           p.location.register);
                                         ungetregister(p.location.register);
                                         ungetregister(p.location.register);
@@ -1155,8 +1166,6 @@ implementation
          else
          else
           op:=A_MOVZX;
           op:=A_MOVZX;
         is_reg:=(p.location.loc in [LOC_REGISTER,LOC_CREGISTER]);
         is_reg:=(p.location.loc in [LOC_REGISTER,LOC_CREGISTER]);
-        getexplicitregister32(R_EDI);
-
         { use the trick that                                                 }
         { use the trick that                                                 }
         { a <= x <= b <=> 0 <= x-a <= b-a <=> cardinal(x-a) <= cardinal(b-a) }
         { a <= x <= b <=> 0 <= x-a <= b-a <=> cardinal(x-a) <= cardinal(b-a) }
 
 
@@ -1199,6 +1208,7 @@ implementation
                 lto := 0;
                 lto := 0;
             end;
             end;
 
 
+        getexplicitregister32(R_EDI);
         if is_reg and
         if is_reg and
            (opsize = S_L) then
            (opsize = S_L) then
           emit_ref_reg(A_LEA,opsize,new_reference(p.location.register,-lto),
           emit_ref_reg(A_LEA,opsize,new_reference(p.location.register,-lto),
@@ -1534,7 +1544,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.22  2001-10-12 13:51:52  jonas
+  Revision 1.23  2001-12-02 16:19:17  jonas
+    * less unnecessary regvar loading with if-statements
+
+  Revision 1.22  2001/10/12 13:51:52  jonas
     * fixed internalerror(10) due to previous fpu overflow fixes ("merged")
     * fixed internalerror(10) due to previous fpu overflow fixes ("merged")
     * fixed bug in n386add (introduced after compilerproc changes for string
     * fixed bug in n386add (introduced after compilerproc changes for string
       operations) where calcregisters wasn't called for shortstring addnodes
       operations) where calcregisters wasn't called for shortstring addnodes

+ 84 - 12
compiler/ncgflw.pas

@@ -66,7 +66,7 @@ interface
 implementation
 implementation
 
 
     uses
     uses
-      verbose,globals,systems,
+      verbose,globals,systems,globtype,
       symconst,symdef,symsym,aasm,types,
       symconst,symdef,symsym,aasm,types,
       cgbase,temp_gen,pass_2,
       cgbase,temp_gen,pass_2,
       cpubase,cpuasm,cpuinfo,
       cpubase,cpuasm,cpuinfo,
@@ -130,9 +130,7 @@ implementation
          cleartempgen;
          cleartempgen;
          secondpass(left);
          secondpass(left);
 
 
-         load_all_regvars(exprasmlist);
-
-         maketojumpbool(left);
+         maketojumpbool(left,lr_load_regvars);
          cg.a_label(exprasmlist,lbreak);
          cg.a_label(exprasmlist,lbreak);
          truelabel:=otlabel;
          truelabel:=otlabel;
          falselabel:=oflabel;
          falselabel:=oflabel;
@@ -152,6 +150,13 @@ implementation
 
 
       var
       var
          hl,otlabel,oflabel : tasmlabel;
          hl,otlabel,oflabel : tasmlabel;
+         org_regvar_loaded,
+         then_regvar_loaded,
+         else_regvar_loaded : regvar_booleanarray;
+         org_list,
+         then_list,
+         else_list : taasmoutput;
+         regcounter: tregister;
 
 
       begin
       begin
          otlabel:=truelabel;
          otlabel:=truelabel;
@@ -160,40 +165,104 @@ implementation
          getlabel(falselabel);
          getlabel(falselabel);
          cleartempgen;
          cleartempgen;
          secondpass(left);
          secondpass(left);
-         load_all_regvars(exprasmlist);
-         maketojumpbool(left);
+
+
+         { save regvars loaded in the beginning so that we can restore them }
+         { when processing the else-block                                   }
+         if cs_regalloc in aktglobalswitches then
+           begin
+             org_list := exprasmlist;
+             exprasmlist := taasmoutput.create;
+           end;
+         maketojumpbool(left,lr_dont_load_regvars);
+
+         if cs_regalloc in aktglobalswitches then
+           org_regvar_loaded := regvar_loaded;
+
          if assigned(right) then
          if assigned(right) then
            begin
            begin
               cg.a_label(exprasmlist,truelabel);
               cg.a_label(exprasmlist,truelabel);
               cleartempgen;
               cleartempgen;
               secondpass(right);
               secondpass(right);
-              { automatically done for blocks, but not for statements (JM) }
-              load_all_regvars(exprasmlist);
            end;
            end;
+
+         { save current asmlist (previous instructions + then-block) and }
+         { loaded regvar state and create new clean ones                 }
+         if cs_regalloc in aktglobalswitches then
+           begin
+             then_regvar_loaded := regvar_loaded;
+             regvar_loaded := org_regvar_loaded;
+             then_list := exprasmlist;
+             exprasmlist := taasmoutput.create;
+           end;
+
          if assigned(t1) then
          if assigned(t1) then
            begin
            begin
               if assigned(right) then
               if assigned(right) then
                 begin
                 begin
                    getlabel(hl);
                    getlabel(hl);
                    { do go back to if line !! }
                    { do go back to if line !! }
-                   aktfilepos:=exprasmList.getlasttaifilepos^;
+                   if not(cs_regalloc in aktglobalswitches) then
+                     aktfilepos:=exprasmList.getlasttaifilepos^
+                   else
+                     aktfilepos:=then_list.getlasttaifilepos^;
                    cg.a_jmp_cond(exprasmlist,OC_None,hl);
                    cg.a_jmp_cond(exprasmlist,OC_None,hl);
                 end;
                 end;
               cg.a_label(exprasmlist,falselabel);
               cg.a_label(exprasmlist,falselabel);
               cleartempgen;
               cleartempgen;
               secondpass(t1);
               secondpass(t1);
-              load_all_regvars(exprasmlist);
+              { save current asmlist (previous instructions + else-block) }
+              { and loaded regvar state and create a new clean list       }
+              if cs_regalloc in aktglobalswitches then
+                begin
+                  else_regvar_loaded := regvar_loaded;
+                  else_list := exprasmlist;
+                  exprasmlist := taasmoutput.create;
+                end;
               if assigned(right) then
               if assigned(right) then
                 cg.a_label(exprasmlist,hl);
                 cg.a_label(exprasmlist,hl);
            end
            end
          else
          else
            begin
            begin
+              if cs_regalloc in aktglobalswitches then
+                begin
+                  else_regvar_loaded := regvar_loaded;
+                  else_list := exprasmlist;
+                  exprasmlist := taasmoutput.create;
+                end;
               cg.a_label(exprasmlist,falselabel);
               cg.a_label(exprasmlist,falselabel);
            end;
            end;
          if not(assigned(right)) then
          if not(assigned(right)) then
            begin
            begin
               cg.a_label(exprasmlist,truelabel);
               cg.a_label(exprasmlist,truelabel);
            end;
            end;
+
+         if cs_regalloc in aktglobalswitches then
+           begin
+             { add loads of regvars at the end of the then- and else-blocks  }
+             { so that at the end of both blocks the same regvars are loaded }
+
+             { no else block? }
+             if not assigned(t1) then
+               sync_regvars(org_list,then_list,org_regvar_loaded,
+                 then_regvar_loaded)
+             { no then block? }
+             else if not assigned(right) then
+               sync_regvars(org_list,else_list,org_regvar_loaded,
+                 else_regvar_loaded)
+             { both else and then blocks }
+             else
+               sync_regvars(then_list,else_list,then_regvar_loaded,
+                 else_regvar_loaded);
+             { add all lists together }
+             org_list.concatlist(then_list);
+             then_list.free;
+             org_list.concatlist(else_list);
+             else_list.free;
+             org_list.concatlist(exprasmlist);
+             exprasmlist.free;
+             exprasmlist := org_list;
+           end;
          truelabel:=otlabel;
          truelabel:=otlabel;
          falselabel:=oflabel;
          falselabel:=oflabel;
       end;
       end;
@@ -390,7 +459,7 @@ implementation
       label
       label
          do_jmp;
          do_jmp;
       begin
       begin
-         load_all_regvars(exprasmlist);
+{         load_all_regvars(exprasmlist); }
          include(flowcontrol,fc_exit);
          include(flowcontrol,fc_exit);
          if assigned(left) then
          if assigned(left) then
          if left.nodetype=assignn then
          if left.nodetype=assignn then
@@ -582,7 +651,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.4  2001-11-02 22:58:01  peter
+  Revision 1.5  2001-12-02 16:19:17  jonas
+    * less unnecessary regvar loading with if-statements
+
+  Revision 1.4  2001/11/02 22:58:01  peter
     * procsym definition rewrite
     * procsym definition rewrite
 
 
   Revision 1.3  2001/10/04 14:33:28  jonas
   Revision 1.3  2001/10/04 14:33:28  jonas