Explorar el Código

* Added some code to keep track of move instructions in register
allocator

daniel hace 22 años
padre
commit
0c93e261e7
Se han modificado 3 ficheros con 67 adiciones y 33 borrados
  1. 20 6
      compiler/i386/cga.pas
  2. 23 3
      compiler/rgobj.pas
  3. 24 24
      compiler/x86/cgx86.pas

+ 20 - 6
compiler/i386/cga.pas

@@ -152,11 +152,21 @@ implementation
       end;
       end;
 
 
     procedure emit_reg_reg(i : tasmop;s : topsize;reg1,reg2 : tregister);
     procedure emit_reg_reg(i : tasmop;s : topsize;reg1,reg2 : tregister);
-      begin
-         if not ((reg1.enum=R_INTREGISTER) and (reg2.enum<>R_INTREGISTER) and
-            (reg1.number=reg2.number) and (i=A_MOV)) then
-           exprasmlist.concat(Taicpu.op_reg_reg(i,s,reg1,reg2));
-      end;
+
+    var instr:Taicpu;
+
+    begin
+      if not ((reg1.enum=R_INTREGISTER) and (reg2.enum=R_INTREGISTER) and
+              (reg1.number=reg2.number) and (i=A_MOV)) then
+        begin
+          instr:=Taicpu.op_reg_reg(i,s,reg1,reg2);
+          exprasmlist.concat(instr);
+{$ifdef newra}
+          if i=A_MOV then
+            rg.add_move_instruction(instr);
+{$endif newra}
+        end;
+    end;
 
 
     procedure emit_const_reg_reg(i : tasmop;s : topsize;c : longint;reg1,reg2 : tregister);
     procedure emit_const_reg_reg(i : tasmop;s : topsize;c : longint;reg1,reg2 : tregister);
       begin
       begin
@@ -176,7 +186,11 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.37  2003-03-08 08:59:07  daniel
+  Revision 1.38  2003-04-17 16:48:21  daniel
+    * Added some code to keep track of move instructions in register
+      allocator
+
+  Revision 1.37  2003/03/08 08:59:07  daniel
     + $define newra will enable new register allocator
     + $define newra will enable new register allocator
     + getregisterint will return imaginary registers with $newra
     + getregisterint will return imaginary registers with $newra
     + -sr switch added, will skip register allocation so you can see
     + -sr switch added, will skip register allocation so you can see

+ 23 - 3
compiler/rgobj.pas

@@ -108,6 +108,13 @@ unit rgobj;
       end;
       end;
       Pinterferencegraph=^Tinterferencegraph;
       Pinterferencegraph=^Tinterferencegraph;
 
 
+      Tmoveset=(ms_coalesced_moves,ms_constrained_moves,ms_frozen_moves,
+                ms_worklist_moves,ms_activemoves);
+      Tmoveins=class(Tlinkedlistitem)
+        moveset:Tmoveset;
+        instruction:Taicpu;
+      end;
+
        {#
        {#
           This class implements the abstract register allocator
           This class implements the abstract register allocator
           It is used by the code generator to allocate and free
           It is used by the code generator to allocate and free
@@ -291,6 +298,8 @@ unit rgobj;
        protected
        protected
 {$ifdef newra}
 {$ifdef newra}
           igraph:Tinterferencegraph;
           igraph:Tinterferencegraph;
+          movelist:array[Tsuperregister] of Tlinkedlist;
+          worklistmoves:Tlinkedlist;
 {$endif}
 {$endif}
           { the following two contain the common (generic) code for all }
           { the following two contain the common (generic) code for all }
           { get- and ungetregisterxxx functions/procedures              }
           { get- and ungetregisterxxx functions/procedures              }
@@ -414,6 +423,8 @@ unit rgobj;
 {$endif TEMPREGDEBUG}
 {$endif TEMPREGDEBUG}
 {$ifdef newra}
 {$ifdef newra}
        fillchar(igraph,sizeof(igraph),0);
        fillchar(igraph,sizeof(igraph),0);
+       fillchar(movelist,sizeof(movelist),0);
+       worklistmoves.create;
 {$endif}
 {$endif}
      end;
      end;
 
 
@@ -741,9 +752,14 @@ unit rgobj;
       unusedregsmm:=usableregsmm;
       unusedregsmm:=usableregsmm;
    {$ifdef newra}
    {$ifdef newra}
       for i:=low(Tsuperregister) to high(Tsuperregister) do
       for i:=low(Tsuperregister) to high(Tsuperregister) do
-       if igraph.adjlist[i]<>nil then
-         dispose(igraph.adjlist[i]);
+        begin
+          if igraph.adjlist[i]<>nil then
+            dispose(igraph.adjlist[i]);
+          if movelist[i]<>nil then
+            movelist[i].destroy;
+        end;
       fillchar(igraph,sizeof(igraph),0);
       fillchar(igraph,sizeof(igraph),0);
+      worklistmoves.destroy;
    {$endif}
    {$endif}
     end;
     end;
 
 
@@ -1381,7 +1397,11 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.33  2003-04-17 07:50:24  daniel
+  Revision 1.34  2003-04-17 16:48:21  daniel
+    * Added some code to keep track of move instructions in register
+      allocator
+
+  Revision 1.33  2003/04/17 07:50:24  daniel
     * Some work on interference graph construction
     * Some work on interference graph construction
 
 
   Revision 1.32  2003/03/28 19:16:57  peter
   Revision 1.32  2003/03/28 19:16:57  peter

+ 24 - 24
compiler/x86/cgx86.pas

@@ -479,6 +479,7 @@ unit cgx86;
         op: tasmop;
         op: tasmop;
         s: topsize;
         s: topsize;
         eq:boolean;
         eq:boolean;
+        instr:Taicpu;
 
 
       begin
       begin
         if (reg1.enum=R_INTREGISTER) and (reg2.enum=R_INTREGISTER) then
         if (reg1.enum=R_INTREGISTER) and (reg2.enum=R_INTREGISTER) then
@@ -493,24 +494,14 @@ unit cgx86;
            { "mov reg1, reg1" doesn't make sense }
            { "mov reg1, reg1" doesn't make sense }
            if op = A_MOV then
            if op = A_MOV then
              exit;
              exit;
-           { optimize movzx with "and ffff,<reg>" operation }
-           if (op = A_MOVZX) then
-            begin
-              case fromsize of
-                OS_8:
-                  begin
-                    list.concat(taicpu.op_const_reg(A_AND,reg2opsize(reg2),255,reg2));
-                    exit;
-                  end;
-                OS_16:
-                  begin
-                    list.concat(taicpu.op_const_reg(A_AND,reg2opsize(reg2),65535,reg2));
-                    exit;
-                  end;
-              end;
-            end;
          end;
          end;
-        list.concat(taicpu.op_reg_reg(op,s,reg1,reg2));
+        instr:=taicpu.op_reg_reg(op,s,reg1,reg2);
+        {Notify the register allocator that we have written a move instruction so
+         it can try to eliminate it.}
+{$ifdef newra}
+        rg.add_move_instruction(instr);
+{$endif}
+        list.concat(instr);
       end;
       end;
 
 
 
 
@@ -791,6 +782,7 @@ unit cgx86;
           tmpreg : tregister;
           tmpreg : tregister;
           popecx : boolean;
           popecx : boolean;
           r:Tregister;
           r:Tregister;
+          instr:Taicpu;
 
 
         begin
         begin
           if src.enum<>R_INTREGISTER then
           if src.enum<>R_INTREGISTER then
@@ -875,8 +867,12 @@ unit cgx86;
               begin
               begin
                 if reg2opsize(src) <> dstsize then
                 if reg2opsize(src) <> dstsize then
                   internalerror(200109226);
                   internalerror(200109226);
-                list.concat(taicpu.op_reg_reg(TOpCG2AsmOp[op],dstsize,
-                  src,dst));
+                instr:=taicpu.op_reg_reg(TOpCG2AsmOp[op],dstsize,src,dst);
+{$ifdef newra}
+                if op in [_MOV,_XCHG] then
+                  rg.add_move_instruction(instr);
+{$endif newra}
+                list.concat(instr);
               end;
               end;
           end;
           end;
         end;
         end;
@@ -1441,7 +1437,7 @@ unit cgx86;
         { align stack on 4 bytes }
         { align stack on 4 bytes }
         list.concat(Taicpu.op_const_reg(A_AND,S_L,$fffffff4,rsp));
         list.concat(Taicpu.op_const_reg(A_AND,S_L,$fffffff4,rsp));
         { load destination }
         { load destination }
-        list.concat(Taicpu.op_reg_reg(A_MOV,S_L,rsp,r));
+        a_load_reg_reg(list,OS_INT,OS_INT,rsp,r);
 
 
         { don't destroy the registers! }
         { don't destroy the registers! }
         r2.number:=NR_ECX;
         r2.number:=NR_ECX;
@@ -1451,11 +1447,11 @@ unit cgx86;
 
 
         { load count }
         { load count }
         r2.number:=NR_ECX;
         r2.number:=NR_ECX;
-        list.concat(Taicpu.op_ref_reg(A_MOV,S_L,lenref,r2));
+        a_load_ref_reg(list,OS_INT,lenref,r2);
 
 
         { load source }
         { load source }
         r2.number:=NR_ESI;
         r2.number:=NR_ESI;
-        list.concat(Taicpu.op_ref_reg(A_MOV,S_L,ref,r2));
+        a_load_ref_reg(list,OS_INT,ref,r2);
 
 
         { scheduled .... }
         { scheduled .... }
         r2.number:=NR_ECX;
         r2.number:=NR_ECX;
@@ -1493,7 +1489,7 @@ unit cgx86;
         list.concat(Taicpu.op_reg(A_POP,S_L,r2));
         list.concat(Taicpu.op_reg(A_POP,S_L,r2));
 
 
         { patch the new address }
         { patch the new address }
-        list.concat(Taicpu.op_reg_ref(A_MOV,S_L,rsp,ref));
+        a_load_reg_ref(list,OS_INT,rsp,ref);
       end;
       end;
 
 
 
 
@@ -1843,7 +1839,11 @@ unit cgx86;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.37  2003-03-28 19:16:57  peter
+  Revision 1.38  2003-04-17 16:48:21  daniel
+    * Added some code to keep track of move instructions in register
+      allocator
+
+  Revision 1.37  2003/03/28 19:16:57  peter
     * generic constructor working for i386
     * generic constructor working for i386
     * remove fixed self register
     * remove fixed self register
     * esi added as address register for i386
     * esi added as address register for i386