Browse Source

+ all code generator generated "mov reg1,reg2" instructions are now
attempted to be removed using the replacereg code
(-dnewoptimizations)
* small fixes to -dreplacereg code

Jonas Maebe 25 years ago
parent
commit
02381105d6
1 changed files with 69 additions and 45 deletions
  1. 69 45
      compiler/csopt386.pas

+ 69 - 45
compiler/csopt386.pas

@@ -189,12 +189,11 @@ Begin {CheckSequence}
 { hp2 now containts the last instruction of the sequence }
 { get the writestate at this point of the register in TmpState }
           TmpState := PPaiProp(hp2^.OptInfo)^.Regs[RegCounter].WState;
-{ hp3 := first instruction after the sequence }
-          GetNextInstruction(hp2, hp2);
 { now, even though reg is in RegsLoadedForRef, sometimes it's still used  }
 { afterwards. It is not if either it is not in usedregs anymore after the }
 { sequence, or if it is loaded with a new value right after the sequence  }
-          If (TmpState = PPaiProp(hp2^.OptInfo)^.Regs[RegCounter].WState) And
+          If GetNextInstruction(hp2, hp2) and
+             (TmpState = PPaiProp(hp2^.OptInfo)^.Regs[RegCounter].WState) And
              (RegCounter in PPaiProp(hp2^.OptInfo)^.UsedRegs) Then
 { it is still used, so remove it from RegsLoadedForRef }
             Begin
@@ -430,24 +429,6 @@ begin
     end
 end;
 
-function regLoadedWithNewValue(reg: tregister; hp: pai): boolean;
-{ assumes reg is a 32bit register }
-var p: paicpu;
-begin
-  p := paicpu(hp);
-  regLoadedWithNewValue :=
-    assigned(hp) and
-    ((hp^.typ = ait_instruction) and
-     (((p^.opcode = A_MOV) or
-       (p^.opcode = A_MOVZX) or
-       (p^.opcode = A_MOVSX) or
-       (p^.opcode = A_LEA)) and
-      (p^.oper[1].typ = top_reg) and
-      (Reg32(p^.oper[1].reg) = reg)) or
-     ((p^.opcode = A_POP) and
-      (Reg32(p^.oper[0].reg) = reg)));
-end;
-
 Procedure RestoreRegContentsTo(reg: TRegister; const c: TContent; p, endP: pai);
 var
 {$ifdef replaceregdebug}
@@ -526,19 +507,20 @@ end;
 function NoHardCodedRegs(p: paicpu): boolean;
 var chCount: byte;
 begin
-  if (p^.opcode = A_IMUL) then
-    noHardCodedRegs := p^.ops <> 1
-  else
-    begin
-      NoHardCodedRegs := true;
-      with InsProp[p^.opcode] do
-      for chCount := 1 to MaxCh do
-        if Ch[chCount] in ([Ch_REAX..Ch_MEDI,Ch_WMemEDI,Ch_All]-[Ch_RESP,Ch_WESP,Ch_RWESP]) then
-          begin
-            NoHardCodedRegs := false;
-            break
-          end;
-    end;
+  case p^.opcode of
+    A_IMUL: noHardCodedRegs := p^.ops <> 1;
+    else
+      begin
+        NoHardCodedRegs := true;
+        with InsProp[p^.opcode] do
+          for chCount := 1 to MaxCh do
+            if Ch[chCount] in ([Ch_REAX..Ch_MEDI,Ch_WMemEDI,Ch_All]-[Ch_RESP,Ch_WESP,Ch_RWESP]) then
+              begin
+                NoHardCodedRegs := false;
+                break
+              end;
+      end;
+  end;
 end;
 
 Procedure ChangeReg(var Reg: TRegister; orgReg, newReg: TRegister);
@@ -575,7 +557,8 @@ function RegSizesOK(oldReg,newReg: TRegister; p: paicpu): boolean;
 var opCount: byte;
 begin
   RegSizesOK := true;
-  if not(IsGP32reg(oldReg) and IsGP32Reg(newReg)) then
+  { if only one of them is a general purpose register ... }
+  if (IsGP32reg(oldReg) xor IsGP32Reg(newReg)) then
     begin
       for opCount := 0 to 2 do
         if (p^.oper[opCount].typ = top_reg) and
@@ -690,7 +673,7 @@ begin
 end;
 
 function ReplaceReg(orgReg, newReg: TRegister; p: pai;
-           const c: TContent): Boolean;
+           const c: TContent; orgRegCanBeModified: Boolean): Boolean;
 { Tries to replace orgreg with newreg in all instructions coming after p }
 { until orgreg gets loaded with a new value. Returns true if successful, }
 { false otherwise. If successful, the contents of newReg are set to c,   }
@@ -709,23 +692,42 @@ begin
     begin
       tmpResult :=
         getNextInstruction(endP,endP);
+      if tmpresult and not assigned(endP^.optInfo) then
+        begin
+          hp := new(pai_asm_comment,init(strpnew('next no optinfo')));
+          hp^.next := endp;
+          hp^.previous := endp^.previous;
+          endp^.previous := hp;
+          if assigned(hp^.previous) then
+            hp^.previous^.next := hp;
+          exit;
+        end;
       If tmpResult and
 { don't take into account instructions that will be removed }
          Not (PPaiProp(endP^.optInfo)^.canBeRemoved) then
         begin
           sequenceEnd :=
             noHardCodedRegs(paicpu(endP)) and
-            (RegLoadedWithNewValue(newReg,paicpu(endP)) or
-             (GetNextInstruction(endp,hp) and
-              FindRegDealloc(newReg,hp)));
+            RegLoadedWithNewValue(newReg,true,paicpu(endP)) or
+            (GetNextInstruction(endp,hp) and
+             FindRegDealloc(newReg,hp));
           newRegModified :=
             newRegModified or
             (not(sequenceEnd) and
              RegModifiedByInstruction(newReg,endP));
           orgRegRead := newRegModified and RegReadByInstruction(orgReg,endP);
-          sequenceEnd := SequenceEnd and not(newRegModified and orgRegRead);
+          sequenceEnd := SequenceEnd and
+    { since newReg will be replaced by orgReg, we can't allow that newReg }
+    { gets modified if orgReg is still read afterwards (since after       }
+    { replacing, this would mean that orgReg first gets modified and then }
+    { gets read in the assumption it still contains the unmodified value) }
+                         not(newRegModified and orgRegRead) and
+    { since newReg will be replaced by orgReg, we can't allow that newReg }
+    { gets modified if orgRegCanBeModified = false                        }
+                         (orgRegCanBeModified or not(newRegModified));
           tmpResult :=
             not(newRegModified and orgRegRead) and
+            (orgRegCanBeModified or not(newRegModified)) and
             (endP^.typ = ait_instruction) and
             not(paicpu(endP)^.is_jmp) and
             NoHardCodedRegs(paicpu(endP)) and
@@ -734,9 +736,10 @@ begin
         end;
     end;
   sequenceEnd := sequenceEnd and
+     RegSizesOk(orgReg,newReg,paicpu(endP)) and
      not(newRegModified and
          (orgReg in PPaiProp(endP^.optInfo)^.usedRegs) and
-         not(RegLoadedWithNewValue(orgReg,paicpu(endP))));
+         not(RegLoadedWithNewValue(orgReg,true,paicpu(endP))));
 
   if SequenceEnd then
     begin
@@ -777,11 +780,11 @@ begin
 {     isn't used anymore                                                    }
 { In case b, the newreg was completely replaced by oldreg, so it's contents }
 { are unchanged compared the start of this sequence, so restore them        }
-      If RegLoadedWithNewValue(newReg,endP) then
+      If RegLoadedWithNewValue(newReg,true,endP) then
          GetLastInstruction(endP,hp)
       else hp := endP;
       if (p <> endp) or
-         not RegLoadedWithNewValue(newReg,endP) then
+         not RegLoadedWithNewValue(newReg,true,endP) then
         RestoreRegContentsTo(newReg, c ,p, hp);
 { In both case a and b, it is possible that the new register was modified   }
 { (e.g. an add/sub), so if it was replaced by oldreg in that instruction,   }
@@ -956,7 +959,7 @@ Begin
                                              getLastInstruction(p,hp3);
                                              If not ReplaceReg(RegInfo.New2OldReg[RegCounter],
                                                       regCounter,hp3,
-                                                      PPaiProp(hp4^.optInfo)^.Regs[regCounter]) then
+                                                      PPaiProp(hp4^.optInfo)^.Regs[regCounter],true) then
                                                begin
 {$endif replacereg}
                                                  hp3 := New(Paicpu,Op_Reg_Reg(A_MOV, S_L,
@@ -1064,6 +1067,21 @@ Begin
                                    End;
                           End;
                       End;
+{$ifdef replacereg}
+                    top_Reg:
+                      { try to replace the new reg with the old reg }
+                      if (paicpu(p)^.opcode = A_MOV) and
+                         getLastInstruction(p,hp4) then
+                        begin
+                          Case paicpu(p)^.oper[1].typ of
+                            top_Reg:
+                              if ReplaceReg(paicpu(p)^.oper[0].reg,
+                                   paicpu(p)^.oper[1].reg,p,
+                                   PPaiProp(hp4^.optInfo)^.Regs[regCounter],false) then
+                                PPaiProp(p^.optInfo)^.canBeRemoved := true;
+                          end
+                        end;
+{$endif replacereg}
                     Top_Const:
                       Begin
                         Case Paicpu(p)^.oper[1].typ Of
@@ -1149,7 +1167,13 @@ End.
 
 {
  $Log$
- Revision 1.39  2000-01-13 13:07:05  jonas
+ Revision 1.40  2000-01-22 16:10:06  jonas
+   + all code generator generated "mov reg1,reg2" instructions are now
+     attempted to be removed using the replacereg code
+     (-dnewoptimizations)
+   * small fixes to -dreplacereg code
+
+ Revision 1.39  2000/01/13 13:07:05  jonas
    * released -dalignreg
    * some small fixes to -dnewOptimizations helper procedures