Ver Fonte

* fixed tracking of usage of flags register
* fixed destroying of "memwrite"'s
* fixed checking of entire sequences in all cases (previously this was
only guaranteed if the new sequence was longer than the old one, and
not if vice versa)
* fixed wrong removal of sequences if a register load was already
completely removed in the previous sequence (because in that case,
that register has to be removed and renamed in the new sequence as
well before removing the new sequence)

Jonas Maebe há 20 anos atrás
pai
commit
84aa52942f
2 ficheiros alterados com 119 adições e 41 exclusões
  1. 104 38
      compiler/i386/csopt386.pas
  2. 15 3
      compiler/i386/daopt386.pas

+ 104 - 38
compiler/i386/csopt386.pas

@@ -258,7 +258,7 @@ var
            getlastinstruction(p,hp) then
            getlastinstruction(p,hp) then
           stillValid := stillValid and
           stillValid := stillValid and
            not(supreg in ptaiprop(hp.optinfo)^.usedregs);
            not(supreg in ptaiprop(hp.optinfo)^.usedregs);
-        passedFlagsModifyingInstr :=
+        passedFlagsModifyingInstr := passedFlagsModifyingInstr or
           instrWritesFlags(currentPrev);
           instrWritesFlags(currentPrev);
       end;
       end;
 
 
@@ -274,9 +274,9 @@ var
       for regCounter := loopstart to RS_EDI do
       for regCounter := loopstart to RS_EDI do
         with ptaiprop(p.optinfo)^.regs[regCounter] do
         with ptaiprop(p.optinfo)^.regs[regCounter] do
         if ((startmod <>
         if ((startmod <>
-              ptaiprop(currentPrev.optinfo)^.regs[regCounter].startmod)  or
+             ptaiprop(currentPrev.optinfo)^.regs[regCounter].startmod)  or
             (nrofMods <>
             (nrofMods <>
-              ptaiprop(currentPrev.optinfo)^.regs[regCounter].nrofMods)) and
+             ptaiprop(currentPrev.optinfo)^.regs[regCounter].nrofMods)) and
            (ptaiprop(p.optinfo)^.regs[regCounter].typ in [con_ref,con_noRemoveRef]) then
            (ptaiprop(p.optinfo)^.regs[regCounter].typ in [con_ref,con_noRemoveRef]) then
           begin
           begin
             findChangedRegister := regCounter;
             findChangedRegister := regCounter;
@@ -305,7 +305,8 @@ var
       end;
       end;
 
 
     getPrevSequence := RS_INVALID;
     getPrevSequence := RS_INVALID;
-    passedFlagsModifyingInstr := instrWritesFlags(currentPrev);
+    passedFlagsModifyingInstr := passedFlagsModifyingInstr or
+      instrWritesFlags(currentPrev);
 
 
     if not getLastInstruction(currentPrev,hp) then
     if not getLastInstruction(currentPrev,hp) then
       exit;
       exit;
@@ -402,7 +403,7 @@ var
   hp2, hp3{, EndMod},highPrev, orgPrev: tai;
   hp2, hp3{, EndMod},highPrev, orgPrev: tai;
   {Cnt,} OldNrofMods: Longint;
   {Cnt,} OldNrofMods: Longint;
   startRegInfo, OrgRegInfo, HighRegInfo: toptreginfo;
   startRegInfo, OrgRegInfo, HighRegInfo: toptreginfo;
-  regModified: array[RS_EAX..RS_ESP] of boolean;
+  regModified, lastregloadremoved: array[RS_EAX..RS_ESP] of boolean;
   HighFound, OrgRegFound: longint;
   HighFound, OrgRegFound: longint;
   regcounter, regCounter2, tmpreg, base, index: tsuperregister;
   regcounter, regCounter2, tmpreg, base, index: tsuperregister;
   OrgRegResult: Boolean;
   OrgRegResult: Boolean;
@@ -434,6 +435,7 @@ begin {CheckSequence}
   while (regcounter <> RS_INVALID) do
   while (regcounter <> RS_INVALID) do
     begin
     begin
       fillchar(regModified,sizeof(regModified),0);
       fillchar(regModified,sizeof(regModified),0);
+      fillchar(lastregloadremoved,sizeof(lastregloadremoved),0);
       reginfo := startRegInfo;
       reginfo := startRegInfo;
       Found := 0;
       Found := 0;
       hp2 := ptaiprop(prev.optinfo)^.Regs[regcounter].StartMod;
       hp2 := ptaiprop(prev.optinfo)^.Regs[regcounter].StartMod;
@@ -454,8 +456,8 @@ begin {CheckSequence}
           if checkingprevsequences then
           if checkingprevsequences then
             begin
             begin
               prevreginfo := reginfo;
               prevreginfo := reginfo;
-            end
-          else if (hp3.typ = ait_instruction) and
+            end;
+          if (hp3.typ = ait_instruction) and
              ((taicpu(hp3).opcode = A_MOV) or
              ((taicpu(hp3).opcode = A_MOV) or
               (taicpu(hp3).opcode = A_MOVZX) or
               (taicpu(hp3).opcode = A_MOVZX) or
               (taicpu(hp3).opcode = A_LEA) or
               (taicpu(hp3).opcode = A_LEA) or
@@ -464,6 +466,7 @@ begin {CheckSequence}
              not(regInOp(getsupreg(taicpu(hp3).oper[1]^.reg),taicpu(hp3).oper[0]^)) then
              not(regInOp(getsupreg(taicpu(hp3).oper[1]^.reg),taicpu(hp3).oper[0]^)) then
             begin
             begin
               tmpreg := getsupreg(taicpu(hp3).oper[1]^.reg);
               tmpreg := getsupreg(taicpu(hp3).oper[1]^.reg);
+              lastregloadremoved[tmpreg] := ptaiprop(hp2.optinfo)^.canberemoved;
               reginfo.lastReload[tmpreg] := hp3;
               reginfo.lastReload[tmpreg] := hp3;
               case taicpu(hp3).oper[0]^.typ of
               case taicpu(hp3).oper[0]^.typ of
                 top_ref:
                 top_ref:
@@ -481,13 +484,22 @@ begin {CheckSequence}
                         with ptaiprop(hp3.optinfo)^.regs[tmpreg] do
                         with ptaiprop(hp3.optinfo)^.regs[tmpreg] do
                           if nrofMods > (oldNrofMods - found) then
                           if nrofMods > (oldNrofMods - found) then
                             oldNrofMods := found + nrofMods;
                             oldNrofMods := found + nrofMods;
+                        { next is safe because instructions are equivalent }
+                        with ptaiprop(hp2.optinfo)^.regs[getsupreg(taicpu(hp2).oper[1]^.reg)] do
+                          if nrofMods > (oldNrofMods - found) then
+                            oldNrofMods := found + nrofMods;
                       end;
                       end;
                   end;
                   end;
                 top_reg:
                 top_reg:
                   if regModified[getsupreg(taicpu(hp3).oper[0]^.reg)] then
                   if regModified[getsupreg(taicpu(hp3).oper[0]^.reg)] then
-                    with ptaiprop(hp3.optinfo)^.regs[tmpreg] do
-                      if nrofMods > (oldNrofMods - found) then
-                        oldNrofMods := found + nrofMods;
+                    begin
+                      with ptaiprop(hp3.optinfo)^.regs[tmpreg] do
+                        if nrofMods > (oldNrofMods - found) then
+                          oldNrofMods := found + nrofMods;
+                      with ptaiprop(hp2.optinfo)^.regs[getsupreg(taicpu(hp2).oper[1]^.reg)] do
+                        if nrofMods > (oldNrofMods - found) then
+                          oldNrofMods := found + nrofMods;
+                    end;
               end;
               end;
             end;
             end;
           for regCounter2 := RS_EAX to RS_EDI do
           for regCounter2 := RS_EAX to RS_EDI do
@@ -505,8 +517,9 @@ begin {CheckSequence}
       for regCounter2 := RS_EAX to RS_EDI do
       for regCounter2 := RS_EAX to RS_EDI do
         if (reginfo.new2OldReg[regCounter2] <> RS_INVALID) and
         if (reginfo.new2OldReg[regCounter2] <> RS_INVALID) and
            (regCounter2 in ptaiprop(hp3.optinfo)^.usedRegs) and
            (regCounter2 in ptaiprop(hp3.optinfo)^.usedRegs) and
-           not regLoadedWithNewValue(regCounter2,false,hp3) then
-          include(reginfo.regsStillUsedAfterSeq,regCounter2);
+           not regLoadedWithNewValue(regCounter2,false,hp3) and
+           lastregloadremoved[regcounter2] then
+          found := 0;
 
 
       if checkingPrevSequences then
       if checkingPrevSequences then
         begin
         begin
@@ -836,7 +849,7 @@ var
   l: longint;
   l: longint;
 {$endif replaceregdebug}
 {$endif replaceregdebug}
   dummyregs: tregset;
   dummyregs: tregset;
-  tmpState: byte;
+  tmpState, newrstate: byte;
   prevcontenttyp: byte;
   prevcontenttyp: byte;
   memconflict: boolean;
   memconflict: boolean;
   invalsmemwrite: boolean;
   invalsmemwrite: boolean;
@@ -852,19 +865,31 @@ begin
     hp.previous.next := hp;
     hp.previous.next := hp;
 {$endif replaceregdebug}
 {$endif replaceregdebug}
 {  ptaiprop(p.optinfo)^.Regs[reg] := c;}
 {  ptaiprop(p.optinfo)^.Regs[reg] := c;}
+  newrstate := c.rstate;
+  incstate(newrstate,$7f);
   while (p <> endP) do
   while (p <> endP) do
     begin
     begin
+      if not(ptaiprop(p.optinfo)^.canberemoved) and
+         regreadbyinstruction(supreg,p) then
+        incstate(newrstate,1);
       ptaiprop(p.optinfo)^.Regs[supreg] := c;
       ptaiprop(p.optinfo)^.Regs[supreg] := c;
+      ptaiprop(p.optinfo)^.Regs[supreg].rstate := newrstate;
       getNextInstruction(p,p);
       getNextInstruction(p,p);
     end;
     end;
   tmpState := ptaiprop(p.optinfo)^.Regs[supreg].wState;
   tmpState := ptaiprop(p.optinfo)^.Regs[supreg].wState;
+  if (newrstate = ptaiprop(p.optinfo)^.Regs[supreg].rState) then
+    internalerror(2004101012);
   dummyregs := [supreg];
   dummyregs := [supreg];
   repeat
   repeat
+    newrstate := ptaiprop(p.optinfo)^.Regs[supreg].rState;
     prevcontenttyp := ptaiprop(p.optinfo)^.Regs[supreg].typ;
     prevcontenttyp := ptaiprop(p.optinfo)^.Regs[supreg].typ;
     // is this a write to memory that destroys the contents we are restoring?
     // is this a write to memory that destroys the contents we are restoring?
     memconflict := modifiesConflictingMemLocation(p,supreg,ptaiprop(p.optinfo)^.regs,dummyregs,true,invalsmemwrite);
     memconflict := modifiesConflictingMemLocation(p,supreg,ptaiprop(p.optinfo)^.regs,dummyregs,true,invalsmemwrite);
     if not memconflict and not invalsmemwrite then
     if not memconflict and not invalsmemwrite then
-      ptaiprop(p.optinfo)^.Regs[supreg] := c;
+      begin
+        ptaiprop(p.optinfo)^.Regs[supreg] := c;
+        ptaiprop(p.optinfo)^.Regs[supreg].rstate := newrstate;
+      end;
   until invalsmemwrite or
   until invalsmemwrite or
         memconflict or
         memconflict or
         not getNextInstruction(p,p) or
         not getNextInstruction(p,p) or
@@ -873,10 +898,13 @@ begin
         ((prevcontenttyp <> con_invalid) and
         ((prevcontenttyp <> con_invalid) and
          (ptaiprop(p.optinfo)^.Regs[supreg].typ = con_invalid));
          (ptaiprop(p.optinfo)^.Regs[supreg].typ = con_invalid));
   if assigned(p) and
   if assigned(p) and
-     ((p.typ = ait_label) or
-      memconflict or
-      invalsmemwrite) then
-    clearRegContentsFrom(supreg,p,p);
+     (p.typ <> ait_marker) then
+    if ((p.typ = ait_label) or
+       memconflict or
+       invalsmemwrite) then
+      clearRegContentsFrom(supreg,p,p)
+    else if (ptaiprop(p.optinfo)^.Regs[supreg].rstate = newrstate) then
+      incstate(ptaiprop(p.optinfo)^.Regs[supreg].rstate,20);
 {$ifdef replaceregdebug}
 {$ifdef replaceregdebug}
   if assigned(p) then
   if assigned(p) then
     begin
     begin
@@ -1186,24 +1214,13 @@ begin
 end;
 end;
 
 
 
 
-function ReplaceReg(asml: TAAsmOutput; orgsupreg, newsupreg: tsuperregister; p,
-          seqstart: tai; const c: TContent; orgRegCanBeModified: Boolean;
-          var returnEndP: tai): Boolean;
-{ Tries to replace orgsupreg with newsupreg in all instructions coming after p }
-{ until orgsupreg gets loaded with a new value. Returns true if successful, }
-{ false otherwise. if successful, the contents of newsupreg are set to c,   }
-{ which should hold the contents of newsupreg before the current sequence   }
-{ started                                                                }
-{ if the function returns true, returnEndP holds the last instruction    }
-{ where newsupreg was replaced by orgsupreg                                    }
+function canreplacereg(orgsupreg, newsupreg: tsuperregister; p: tai;
+  orgRegCanBeModified: boolean; var resnewregmodified, resorgregread, resremovelast: boolean; var returnendp: tai): boolean;
 var
 var
   endP, hp: tai;
   endP, hp: tai;
-  removeLast, sequenceEnd, tmpResult, newRegModified, orgRegRead,
-    stateChanged, readStateChanged: Boolean;
-
-
+  removeLast, sequenceEnd, tmpResult, newRegModified, orgRegRead: boolean;
 begin
 begin
-  ReplaceReg := false;
+  canreplacereg := false;
   tmpResult := true;
   tmpResult := true;
   sequenceEnd := false;
   sequenceEnd := false;
   newRegModified := false;
   newRegModified := false;
@@ -1281,7 +1298,7 @@ begin
             not RegModifiedByInstruction(orgsupreg,endP);
             not RegModifiedByInstruction(orgsupreg,endP);
         end;
         end;
     end;
     end;
-  sequenceEnd := sequenceEnd and
+  canreplacereg := sequenceEnd and
      (removeLast  or
      (removeLast  or
       (orgRegCanBeModified or not(newRegModified))) and
       (orgRegCanBeModified or not(newRegModified))) and
      (not(assigned(endp)) or
      (not(assigned(endp)) or
@@ -1291,7 +1308,35 @@ begin
        not(newRegModified and
        not(newRegModified and
            (orgsupreg in ptaiprop(endp.optinfo)^.usedRegs) and
            (orgsupreg in ptaiprop(endp.optinfo)^.usedRegs) and
            not(RegLoadedWithNewValue(orgsupreg,true,taicpu(endP))))));
            not(RegLoadedWithNewValue(orgsupreg,true,taicpu(endP))))));
-  if SequenceEnd then
+  if canreplacereg then
+    begin
+      resnewregmodified := newregmodified;
+      resorgregread := orgregread;
+      resremovelast := removelast;
+      returnendp := endp;
+    end;
+end;
+
+
+
+function ReplaceReg(asml: TAAsmOutput; orgsupreg, newsupreg: tsuperregister; p,
+          seqstart: tai; const c: TContent; orgRegCanBeModified: Boolean;
+          var returnEndP: tai): Boolean;
+{ Tries to replace orgsupreg with newsupreg in all instructions coming after p }
+{ until orgsupreg gets loaded with a new value. Returns true if successful, }
+{ false otherwise. if successful, the contents of newsupreg are set to c,   }
+{ which should hold the contents of newsupreg before the current sequence   }
+{ started                                                                }
+{ if the function returns true, returnEndP holds the last instruction    }
+{ where newsupreg was replaced by orgsupreg                                    }
+var
+  endP, hp: tai;
+  removeLast, sequenceEnd, newRegModified, orgRegRead,
+    stateChanged, readStateChanged: Boolean;
+
+begin
+  replacereg := false;
+  if canreplacereg(orgsupreg,newsupreg,p,orgregcanbemodified,newregmodified, orgregread, removelast,endp) then
     begin
     begin
 {$ifdef replaceregdebug}
 {$ifdef replaceregdebug}
       hp := tai_comment.Create(strpnew(
       hp := tai_comment.Create(strpnew(
@@ -1424,7 +1469,7 @@ procedure removePrevNotUsedLoad(p: tai; supreg: tsuperregister; check: boolean);
 { (e.g. when you have a "mov 8(%ebp),%eax", you can be sure the previous }
 { (e.g. when you have a "mov 8(%ebp),%eax", you can be sure the previous }
 { value of %eax isn't used anymore later on)                             }
 { value of %eax isn't used anymore later on)                             }
 var
 var
-  hp1: tai;
+  hp1, next, beforestartmod: tai;
 begin
 begin
   if getLastInstruction(p,hp1) then
   if getLastInstruction(p,hp1) then
     with ptaiprop(hp1.optinfo)^.regs[supreg] do
     with ptaiprop(hp1.optinfo)^.regs[supreg] do
@@ -1435,7 +1480,17 @@ begin
           (not(regInInstruction(supreg,p)) and
           (not(regInInstruction(supreg,p)) and
            (not(supreg in ptaiprop(hp1.optinfo)^.usedRegs) or
            (not(supreg in ptaiprop(hp1.optinfo)^.usedRegs) or
             findRegDealloc(supreg,p)))) then
             findRegDealloc(supreg,p)))) then
-        ptaiprop(startMod.optinfo)^.canBeRemoved := true;
+        begin
+          ptaiprop(startMod.optinfo)^.canBeRemoved := true;
+          getnextinstruction(p,next);
+          { give the register that was modified by this instruction again }
+          { the contents it had before this instruction                   }
+          if getlastinstruction(startmod,beforestartmod) then
+            RestoreRegContentsTo(supreg,ptaiprop(beforestartmod.optinfo)^.regs[supreg],
+             startmod,p)
+          else
+            ClearRegContentsFrom(supreg,startmod,hp1);
+        end;
 end;
 end;
 
 
 
 
@@ -2122,7 +2177,18 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.69  2004-10-31 21:45:03  peter
+  Revision 1.70  2004-12-18 15:16:10  jonas
+    * fixed tracking of usage of flags register
+    * fixed destroying of "memwrite"'s
+    * fixed checking of entire sequences in all cases (previously this was
+      only guaranteed if the new sequence was longer than the old one, and
+      not if vice versa)
+    * fixed wrong removal of sequences if a register load was already
+      completely removed in the previous sequence (because in that case,
+      that register has to be removed and renamed in the new sequence as
+      well before removing the new sequence)
+
+  Revision 1.69  2004/10/31 21:45:03  peter
     * generic tlocation
     * generic tlocation
     * move tlocation to cgutils
     * move tlocation to cgutils
 
 

+ 15 - 3
compiler/i386/daopt386.pas

@@ -70,7 +70,6 @@ type
   toptreginfo = Record
   toptreginfo = Record
                 NewRegsEncountered, OldRegsEncountered: TRegSet;
                 NewRegsEncountered, OldRegsEncountered: TRegSet;
                 RegsLoadedForRef: TRegSet;
                 RegsLoadedForRef: TRegSet;
-                regsStillUsedAfterSeq: TRegSet;
                 lastReload: array[RS_EAX..RS_ESP] of tai;
                 lastReload: array[RS_EAX..RS_ESP] of tai;
                 New2OldReg: TRegArray;
                 New2OldReg: TRegArray;
               end;
               end;
@@ -2574,7 +2573,8 @@ begin
 {                  DestroyReg(curprop, RS_EAX, true);}
 {                  DestroyReg(curprop, RS_EAX, true);}
                   AddInstr2RegContents({$ifdef statedebug}list,{$endif}
                   AddInstr2RegContents({$ifdef statedebug}list,{$endif}
                     taicpu(p), RS_EAX);
                     taicpu(p), RS_EAX);
-                  DestroyReg(curprop, RS_EDX, true)
+                  DestroyReg(curprop, RS_EDX, true);
+                  LastFlagsChangeProp := curprop;
                 end;
                 end;
               A_IMUL:
               A_IMUL:
                 begin
                 begin
@@ -2601,6 +2601,7 @@ begin
                   else
                   else
                     AddInstr2OpContents({$ifdef statedebug}list,{$endif}
                     AddInstr2OpContents({$ifdef statedebug}list,{$endif}
                       taicpu(p), taicpu(p).oper[2]^);
                       taicpu(p), taicpu(p).oper[2]^);
+                  LastFlagsChangeProp := curprop;
                 end;
                 end;
               A_LEA:
               A_LEA:
                 begin
                 begin
@@ -2791,7 +2792,18 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.76  2004-12-18 14:07:35  jonas
+  Revision 1.77  2004-12-18 15:16:10  jonas
+    * fixed tracking of usage of flags register
+    * fixed destroying of "memwrite"'s
+    * fixed checking of entire sequences in all cases (previously this was
+      only guaranteed if the new sequence was longer than the old one, and
+      not if vice versa)
+    * fixed wrong removal of sequences if a register load was already
+      completely removed in the previous sequence (because in that case,
+      that register has to be removed and renamed in the new sequence as
+      well before removing the new sequence)
+
+  Revision 1.76  2004/12/18 14:07:35  jonas
     * fixed compilation with -dcsdebug -dallocregdebug
     * fixed compilation with -dcsdebug -dallocregdebug
 
 
   Revision 1.75  2004/12/12 10:50:34  florian
   Revision 1.75  2004/12/12 10:50:34  florian