Selaa lähdekoodia

+ extra checks in RegsEquivalent so some more optimizations can be done (which
where disabled by the second fix from revision 1.22)

Jonas Maebe 27 vuotta sitten
vanhempi
commit
09f430de39
2 muutettua tiedostoa jossa 62 lisäystä ja 48 poistoa
  1. 5 2
      compiler/csopt386.pas
  2. 57 46
      compiler/daopt386.pas

+ 5 - 2
compiler/csopt386.pas

@@ -88,7 +88,6 @@ Begin {CheckSequence}
       RegInfo.OldRegsEncountered := RegInfo.NewRegsEncountered;
       RegInfo.OldRegsEncountered := RegInfo.NewRegsEncountered;
       RegInfo.New2OldReg[ProcInfo.FramePointer] := ProcInfo.FramePointer;
       RegInfo.New2OldReg[ProcInfo.FramePointer] := ProcInfo.FramePointer;
       RegInfo.New2OldReg[R_ESP] := R_ESP;
       RegInfo.New2OldReg[R_ESP] := R_ESP;
-      RegInfo.Old2NewReg := RegInfo.New2OldReg;
       Found := 0;
       Found := 0;
       hp2 := PPaiProp(PrevNonRemovablePai^.fileinfo.line)^.Regs[RegCounter].StartMod;
       hp2 := PPaiProp(PrevNonRemovablePai^.fileinfo.line)^.Regs[RegCounter].StartMod;
       If (PrevNonRemovablePai <> PPaiProp(PrevNonRemovablePai^.fileinfo.line)^.Regs[RegCounter].StartMod)
       If (PrevNonRemovablePai <> PPaiProp(PrevNonRemovablePai^.fileinfo.line)^.Regs[RegCounter].StartMod)
@@ -554,7 +553,11 @@ End.
 
 
 {
 {
  $Log$
  $Log$
- Revision 1.16  1998-12-02 16:23:31  jonas
+ Revision 1.17  1998-12-17 16:37:39  jonas
+   + extra checks in RegsEquivalent so some more optimizations can be done (which
+     where disabled by the second fix from revision 1.22)
+
+ Revision 1.16  1998/12/02 16:23:31  jonas
    * changed "if longintvar in set" to case or "if () or () .." statements
    * changed "if longintvar in set" to case or "if () or () .." statements
    * tree.pas: changed inlinenumber (and associated constructor/vars) to a byte
    * tree.pas: changed inlinenumber (and associated constructor/vars) to a byte
 
 

+ 57 - 46
compiler/daopt386.pas

@@ -42,15 +42,18 @@ Type
   TRegInfo = Record
   TRegInfo = Record
                 NewRegsEncountered, OldRegsEncountered: TRegSet;
                 NewRegsEncountered, OldRegsEncountered: TRegSet;
                 RegsLoadedForRef: TRegSet;
                 RegsLoadedForRef: TRegSet;
-                Old2NewReg, New2OldReg: TRegArray;
+                New2OldReg: TRegArray;
               End;
               End;
 
 
+{possible actions on an operand: read, write or modify (= read & write)}
+  TOpAction = (OpAct_Read, OpAct_Write, OpAct_Modify, OpAct_Unknown);
+
 {*********************** Procedures and Functions ************************}
 {*********************** Procedures and Functions ************************}
 
 
 Procedure InsertLLItem(AsmL: PAasmOutput; prev, foll, new_one: PLinkedList_Item);
 Procedure InsertLLItem(AsmL: PAasmOutput; prev, foll, new_one: PLinkedList_Item);
 
 
 Function Reg32(Reg: TRegister): TRegister;
 Function Reg32(Reg: TRegister): TRegister;
-Function RefsEquivalent(Const R1, R2: TReference; Var RegInfo: TRegInfo): Boolean;
+Function RefsEquivalent(Const R1, R2: TReference; Var RegInfo: TRegInfo; OpAct: TOpAction): Boolean;
 Function RefsEqual(Const R1, R2: TReference): Boolean;
 Function RefsEqual(Const R1, R2: TReference): Boolean;
 Function IsGP32Reg(Reg: TRegister): Boolean;
 Function IsGP32Reg(Reg: TRegister): Boolean;
 Function RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
 Function RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
@@ -61,7 +64,7 @@ Function GetNextInstruction(Current: Pai; Var Next: Pai): Boolean;
 Function GetLastInstruction(Current: Pai; Var Last: Pai): Boolean;
 Function GetLastInstruction(Current: Pai; Var Last: Pai): Boolean;
 
 
 Procedure UpdateUsedRegs(Var UsedRegs: TRegSet; p: Pai);
 Procedure UpdateUsedRegs(Var UsedRegs: TRegSet; p: Pai);
-Function RegsEquivalent(OldReg, NewReg: TRegister; Var RegInfo: TRegInfo): Boolean;
+Function RegsEquivalent(OldReg, NewReg: TRegister; Var RegInfo: TRegInfo; OpAct: TopAction): Boolean;
 Function InstructionsEquivalent(p1, p2: Pai; Var RegInfo: TRegInfo): Boolean;
 Function InstructionsEquivalent(p1, p2: Pai; Var RegInfo: TRegInfo): Boolean;
 Function OpsEqual(typ: Longint; op1, op2: Pointer): Boolean;
 Function OpsEqual(typ: Longint; op1, op2: Pointer): Boolean;
 
 
@@ -830,21 +833,18 @@ Begin
       NewRegsEncountered := NewRegsEncountered + [NewReg];
       NewRegsEncountered := NewRegsEncountered + [NewReg];
       OldRegsEncountered := OldRegsEncountered + [OldReg];
       OldRegsEncountered := OldRegsEncountered + [OldReg];
       New2OldReg[NewReg] := OldReg;
       New2OldReg[NewReg] := OldReg;
-      Old2NewReg[OldReg] := NewReg;
       Case OldReg Of
       Case OldReg Of
         R_EAX..R_EDI:
         R_EAX..R_EDI:
           Begin
           Begin
             NewRegsEncountered := NewRegsEncountered + [Reg32toReg16(NewReg)];
             NewRegsEncountered := NewRegsEncountered + [Reg32toReg16(NewReg)];
             OldRegsEncountered := OldRegsEncountered + [Reg32toReg16(OldReg)];
             OldRegsEncountered := OldRegsEncountered + [Reg32toReg16(OldReg)];
             New2OldReg[Reg32toReg16(NewReg)] := Reg32toReg16(OldReg);
             New2OldReg[Reg32toReg16(NewReg)] := Reg32toReg16(OldReg);
-            Old2NewReg[Reg32toReg16(OldReg)] := Reg32toReg16(NewReg);
             If (NewReg in [R_EAX..R_EBX]) And
             If (NewReg in [R_EAX..R_EBX]) And
                (OldReg in [R_EAX..R_EBX]) Then
                (OldReg in [R_EAX..R_EBX]) Then
               Begin
               Begin
                 NewRegsEncountered := NewRegsEncountered + [Reg32toReg8(NewReg)];
                 NewRegsEncountered := NewRegsEncountered + [Reg32toReg8(NewReg)];
                 OldRegsEncountered := OldRegsEncountered + [Reg32toReg8(OldReg)];
                 OldRegsEncountered := OldRegsEncountered + [Reg32toReg8(OldReg)];
                 New2OldReg[Reg32toReg8(NewReg)] := Reg32toReg8(OldReg);
                 New2OldReg[Reg32toReg8(NewReg)] := Reg32toReg8(OldReg);
-                Old2NewReg[Reg32toReg8(OldReg)] := Reg32toReg8(NewReg);
               End;
               End;
           End;
           End;
         R_AX..R_DI:
         R_AX..R_DI:
@@ -852,14 +852,12 @@ Begin
             NewRegsEncountered := NewRegsEncountered + [Reg16toReg32(NewReg)];
             NewRegsEncountered := NewRegsEncountered + [Reg16toReg32(NewReg)];
             OldRegsEncountered := OldRegsEncountered + [Reg16toReg32(OldReg)];
             OldRegsEncountered := OldRegsEncountered + [Reg16toReg32(OldReg)];
             New2OldReg[Reg16toReg32(NewReg)] := Reg16toReg32(OldReg);
             New2OldReg[Reg16toReg32(NewReg)] := Reg16toReg32(OldReg);
-            Old2NewReg[Reg16toReg32(OldReg)] := Reg16toReg32(NewReg);
             If (NewReg in [R_AX..R_BX]) And
             If (NewReg in [R_AX..R_BX]) And
                (OldReg in [R_AX..R_BX]) Then
                (OldReg in [R_AX..R_BX]) Then
               Begin
               Begin
                 NewRegsEncountered := NewRegsEncountered + [Reg16toReg8(NewReg)];
                 NewRegsEncountered := NewRegsEncountered + [Reg16toReg8(NewReg)];
                 OldRegsEncountered := OldRegsEncountered + [Reg16toReg8(OldReg)];
                 OldRegsEncountered := OldRegsEncountered + [Reg16toReg8(OldReg)];
                 New2OldReg[Reg16toReg8(NewReg)] := Reg16toReg8(OldReg);
                 New2OldReg[Reg16toReg8(NewReg)] := Reg16toReg8(OldReg);
-                Old2NewReg[Reg16toReg8(OldReg)] := Reg16toReg8(NewReg);
               End;
               End;
           End;
           End;
         R_AL..R_BL:
         R_AL..R_BL:
@@ -869,7 +867,6 @@ Begin
             OldRegsEncountered := OldRegsEncountered + [Reg8toReg32(OldReg)]
             OldRegsEncountered := OldRegsEncountered + [Reg8toReg32(OldReg)]
                                + [Reg8toReg16(OldReg)];
                                + [Reg8toReg16(OldReg)];
             New2OldReg[Reg8toReg32(NewReg)] := Reg8toReg32(OldReg);
             New2OldReg[Reg8toReg32(NewReg)] := Reg8toReg32(OldReg);
-            Old2NewReg[Reg8toReg16(OldReg)] := Reg8toReg16(NewReg);
           End;
           End;
       End;
       End;
     End;
     End;
@@ -892,7 +889,7 @@ Begin
 End;
 End;
 
 
 
 
-Function RegsEquivalent(OldReg, NewReg: TRegister; Var RegInfo: TRegInfo): Boolean;
+Function RegsEquivalent(OldReg, NewReg: TRegister; Var RegInfo: TRegInfo; OPAct: TOpAction): Boolean;
 Begin
 Begin
   If Not((OldReg = R_NO) Or (NewReg = R_NO)) Then
   If Not((OldReg = R_NO) Or (NewReg = R_NO)) Then
     If RegsSameSize(OldReg, NewReg) Then
     If RegsSameSize(OldReg, NewReg) Then
@@ -902,27 +899,44 @@ Begin
  processed. This happens if it has been compared with a register that doesn't
  processed. This happens if it has been compared with a register that doesn't
  have an 8 bit component (such as EDI). In that case the 8 bit component is
  have an 8 bit component (such as EDI). In that case the 8 bit component is
  still set to R_NO and the comparison in the Else-part will fail}
  still set to R_NO and the comparison in the Else-part will fail}
-        If Not((Reg32(NewReg) in NewRegsEncountered) Or
-               (Reg32(OldReg) in OldRegsEncountered)) Then
-          Begin
-            AddReg2RegInfo(OldReg, NewReg, RegInfo);
-            RegsEquivalent := True
-          End
-        Else RegsEquivalent :=
-               (Reg32(NewReg) in NewRegsEncountered) And
-               (Reg32(OldReg) in OldRegsEncountered) And
-               (OldReg = New2OldReg[NewReg])
+        If (Reg32(OldReg) in OldRegsEncountered) Then
+          If (Reg32(NewReg) in NewRegsEncountered) Then
+            RegsEquivalent := (OldReg = New2OldReg[NewReg])
+
+ { If we haven't encountered the new register yet, but we have encountered the
+   old one already, the new one can only be correct if it's being written to
+   (and consequently the old one is also being written to), otherwise
+
+   movl -8(%ebp), %eax        and         movl -8(%ebp), %eax
+   movl (%eax), %eax                      movl (%edx), %edx
+
+   are considered equivalent}
+
+          Else
+            If (OpAct = OpAct_Write) Then
+              Begin
+                AddReg2RegInfo(OldReg, NewReg, RegInfo);
+                RegsEquivalent := True
+              End
+            Else Regsequivalent := False
+        Else
+          If Not(Reg32(NewReg) in NewRegsEncountered) Then
+            Begin
+              AddReg2RegInfo(OldReg, NewReg, RegInfo);
+              RegsEquivalent := True
+            End
+          Else RegsEquivalent := False
     Else RegsEquivalent := False
     Else RegsEquivalent := False
   Else RegsEquivalent := OldReg = NewReg
   Else RegsEquivalent := OldReg = NewReg
 End;
 End;
 
 
-Function RefsEquivalent(Const R1, R2: TReference; var RegInfo: TRegInfo): Boolean;
+Function RefsEquivalent(Const R1, R2: TReference; var RegInfo: TRegInfo; OpAct: TOpAction): Boolean;
 Begin
 Begin
   If R1.IsIntValue
   If R1.IsIntValue
      Then RefsEquivalent := R2.IsIntValue and (R1.Offset = R2.Offset)
      Then RefsEquivalent := R2.IsIntValue and (R1.Offset = R2.Offset)
      Else If (R1.Offset = R2.Offset) And
      Else If (R1.Offset = R2.Offset) And
-             RegsEquivalent(R1.Base, R2.Base, RegInfo) And
-             RegsEquivalent(R1.Index, R2.Index, RegInfo) And
+             RegsEquivalent(R1.Base, R2.Base, RegInfo, OpAct) And
+             RegsEquivalent(R1.Index, R2.Index, RegInfo, OpAct) And
              (R1.Segment = R2.Segment) And (R1.ScaleFactor = R2.ScaleFactor)
              (R1.Segment = R2.Segment) And (R1.ScaleFactor = R2.ScaleFactor)
             Then
             Then
               Begin
               Begin
@@ -1266,12 +1280,12 @@ Begin
     End;
     End;
 End;}
 End;}
 
 
-Function OpsEquivalent(typ: Longint; OldOp, NewOp: Pointer; Var RegInfo: TRegInfo): Boolean;
+Function OpsEquivalent(typ: Longint; OldOp, NewOp: Pointer; Var RegInfo: TRegInfo; OpAct: TopAction): Boolean;
 Begin {checks whether the two ops are equivalent}
 Begin {checks whether the two ops are equivalent}
   Case typ Of
   Case typ Of
-    Top_Reg: OpsEquivalent := RegsEquivalent(TRegister(OldOp), TRegister(NewOp), RegInfo);
+    Top_Reg: OpsEquivalent :=RegsEquivalent(TRegister(OldOp), TRegister(NewOp), RegInfo, OpAct);
     Top_Const: OpsEquivalent := OldOp = NewOp;
     Top_Const: OpsEquivalent := OldOp = NewOp;
-    Top_Ref: OpsEquivalent := RefsEquivalent(TReference(OldOp^), TReference(NewOp^), RegInfo);
+    Top_Ref: OpsEquivalent := RefsEquivalent(TReference(OldOp^), TReference(NewOp^), RegInfo, OpAct);
     Top_None: OpsEquivalent := True
     Top_None: OpsEquivalent := True
     Else OpsEquivalent := False
     Else OpsEquivalent := False
   End;
   End;
@@ -1328,7 +1342,7 @@ Begin {checks whether two Pai386 instructions are equal}
  {the registers from op2 have to be equivalent, but not necessarily equal}
  {the registers from op2 have to be equivalent, but not necessarily equal}
                 InstructionsEquivalent :=
                 InstructionsEquivalent :=
                   RegsEquivalent(TRegister(Pai386(p1)^.op2), TRegister(Pai386(p2)^.op2),
                   RegsEquivalent(TRegister(Pai386(p1)^.op2), TRegister(Pai386(p2)^.op2),
-                                 RegInfo);
+                                 RegInfo, OpAct_Write);
               End
               End
  {the registers are loaded with values from different memory locations. If
  {the registers are loaded with values from different memory locations. If
   this was allowed, the instructions "mov -4(esi),eax" and "mov -4(ebp),eax"
   this was allowed, the instructions "mov -4(esi),eax" and "mov -4(ebp),eax"
@@ -1343,57 +1357,50 @@ Begin {checks whether two Pai386 instructions are equal}
                                 Reg32(TRegister(Pai386(p2)^.op2)),R_NO,R_ESP])
                                 Reg32(TRegister(Pai386(p2)^.op2)),R_NO,R_ESP])
  {it won't do any harm if the register is already in RegsLoadedForRef}
  {it won't do any harm if the register is already in RegsLoadedForRef}
                   Then
                   Then
-{$ifdef csdebug}
                     Begin
                     Begin
-{$endif csdebug}
                       RegInfo.RegsLoadedForRef := RegInfo.RegsLoadedForRef + [Base];
                       RegInfo.RegsLoadedForRef := RegInfo.RegsLoadedForRef + [Base];
 {$ifdef csdebug}
 {$ifdef csdebug}
                       Writeln(att_reg2str[base], ' added');
                       Writeln(att_reg2str[base], ' added');
-                    end;
 {$endif csdebug}
 {$endif csdebug}
+                    end;
                 If Not(Index in [ProcInfo.FramePointer,
                 If Not(Index in [ProcInfo.FramePointer,
                                  Reg32(TRegister(Pai386(p2)^.op2)),R_NO,R_ESP])
                                  Reg32(TRegister(Pai386(p2)^.op2)),R_NO,R_ESP])
                   Then
                   Then
-{$ifdef csdebug}
                     Begin
                     Begin
-{$endif csdebug}
                       RegInfo.RegsLoadedForRef := RegInfo.RegsLoadedForRef + [Index];
                       RegInfo.RegsLoadedForRef := RegInfo.RegsLoadedForRef + [Index];
 {$ifdef csdebug}
 {$ifdef csdebug}
                       Writeln(att_reg2str[index], ' added');
                       Writeln(att_reg2str[index], ' added');
-                    end;
 {$endif csdebug}
 {$endif csdebug}
+                    end;
 
 
               End;
               End;
             If Not(Reg32(TRegister(Pai386(p2)^.op2)) In [ProcInfo.FramePointer,
             If Not(Reg32(TRegister(Pai386(p2)^.op2)) In [ProcInfo.FramePointer,
                                                          R_NO,R_ESP])
                                                          R_NO,R_ESP])
               Then
               Then
-{$ifdef csdebug}
                 Begin
                 Begin
-{$endif csdebug}
-
                   RegInfo.RegsLoadedForRef := RegInfo.RegsLoadedForRef -
                   RegInfo.RegsLoadedForRef := RegInfo.RegsLoadedForRef -
                                                  [Reg32(TRegister(Pai386(p2)^.op2))];
                                                  [Reg32(TRegister(Pai386(p2)^.op2))];
 {$ifdef csdebug}
 {$ifdef csdebug}
                   Writeln(att_reg2str[Reg32(TRegister(Pai386(p2)^.op2))], ' removed');
                   Writeln(att_reg2str[Reg32(TRegister(Pai386(p2)^.op2))], ' removed');
-                end;
 {$endif csdebug}
 {$endif csdebug}
-              InstructionsEquivalent :=
-                 OpsEquivalent(Pai386(p1)^.op1t, Pai386(p1)^.op1, Pai386(p2)^.op1, RegInfo) And
-                 OpsEquivalent(Pai386(p1)^.op2t, Pai386(p1)^.op2, Pai386(p2)^.op2, RegInfo)
+                end;
+            InstructionsEquivalent :=
+               OpsEquivalent(Pai386(p1)^.op1t, Pai386(p1)^.op1, Pai386(p2)^.op1, RegInfo, OpAct_Read) And
+               OpsEquivalent(Pai386(p1)^.op2t, Pai386(p1)^.op2, Pai386(p2)^.op2, RegInfo, OpAct_Write)
           End
           End
       Else
       Else
  {an instruction <> mov, movzx, movsx}
  {an instruction <> mov, movzx, movsx}
         If (Pai386(p1)^.op3t = top_none) Then
         If (Pai386(p1)^.op3t = top_none) Then
           InstructionsEquivalent :=
           InstructionsEquivalent :=
-            OpsEquivalent(Pai386(p1)^.op1t, Pai386(p1)^.op1, Pai386(p2)^.op1, RegInfo) And
-            OpsEquivalent(Pai386(p1)^.op2t, Pai386(p1)^.op2, Pai386(p2)^.op2, RegInfo)
+            OpsEquivalent(Pai386(p1)^.op1t, Pai386(p1)^.op1, Pai386(p2)^.op1, RegInfo, OpAct_Unknown) And
+            OpsEquivalent(Pai386(p1)^.op2t, Pai386(p1)^.op2, Pai386(p2)^.op2, RegInfo, OpAct_Unknown)
         Else
         Else
           InstructionsEquivalent :=
           InstructionsEquivalent :=
-            OpsEquivalent(Pai386(p1)^.op1t, Pai386(p1)^.op1, Pai386(p2)^.op1, RegInfo) And
+            OpsEquivalent(Pai386(p1)^.op1t, Pai386(p1)^.op1, Pai386(p2)^.op1, RegInfo, OpAct_Unknown) And
             OpsEquivalent(Pai386(p1)^.op2t, Pointer(Longint(TwoWords(Pai386(p1)^.op2).Word1)),
             OpsEquivalent(Pai386(p1)^.op2t, Pointer(Longint(TwoWords(Pai386(p1)^.op2).Word1)),
-                          Pointer(Longint(TwoWords(Pai386(p2)^.op2).Word1)), RegInfo) And
+                          Pointer(Longint(TwoWords(Pai386(p2)^.op2).Word1)), RegInfo, OpAct_Unknown) And
             OpsEquivalent(Pai386(p1)^.op3t, Pointer(Longint(TwoWords(Pai386(p1)^.op2).Word2)),
             OpsEquivalent(Pai386(p1)^.op3t, Pointer(Longint(TwoWords(Pai386(p1)^.op2).Word2)),
-                          Pointer(Longint(TwoWords(Pai386(p2)^.op2).Word2)), RegInfo)
+                          Pointer(Longint(TwoWords(Pai386(p2)^.op2).Word2)), RegInfo, OpAct_Unknown)
  {the instructions haven't even got the same structure, so they're certainly
  {the instructions haven't even got the same structure, so they're certainly
   not equivalent}
   not equivalent}
     Else InstructionsEquivalent := False;
     Else InstructionsEquivalent := False;
@@ -2084,7 +2091,11 @@ End.
 
 
 {
 {
  $Log$
  $Log$
- Revision 1.32  1998-12-15 19:33:58  jonas
+ Revision 1.33  1998-12-17 16:37:38  jonas
+   + extra checks in RegsEquivalent so some more optimizations can be done (which
+     where disabled by the second fix from revision 1.22)
+
+ Revision 1.32  1998/12/15 19:33:58  jonas
    * uncommented OpsEqual & added to interface because popt386 uses it now
    * uncommented OpsEqual & added to interface because popt386 uses it now
 
 
  Revision 1.31  1998/12/11 00:03:13  peter
  Revision 1.31  1998/12/11 00:03:13  peter