Преглед на файлове

+ 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 години
родител
ревизия
09f430de39
променени са 2 файла, в които са добавени 62 реда и са изтрити 48 реда
  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.New2OldReg[ProcInfo.FramePointer] := ProcInfo.FramePointer;
       RegInfo.New2OldReg[R_ESP] := R_ESP;
-      RegInfo.Old2NewReg := RegInfo.New2OldReg;
       Found := 0;
       hp2 := PPaiProp(PrevNonRemovablePai^.fileinfo.line)^.Regs[RegCounter].StartMod;
       If (PrevNonRemovablePai <> PPaiProp(PrevNonRemovablePai^.fileinfo.line)^.Regs[RegCounter].StartMod)
@@ -554,7 +553,11 @@ End.
 
 {
  $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
    * tree.pas: changed inlinenumber (and associated constructor/vars) to a byte
 

+ 57 - 46
compiler/daopt386.pas

@@ -42,15 +42,18 @@ Type
   TRegInfo = Record
                 NewRegsEncountered, OldRegsEncountered: TRegSet;
                 RegsLoadedForRef: TRegSet;
-                Old2NewReg, New2OldReg: TRegArray;
+                New2OldReg: TRegArray;
               End;
 
+{possible actions on an operand: read, write or modify (= read & write)}
+  TOpAction = (OpAct_Read, OpAct_Write, OpAct_Modify, OpAct_Unknown);
+
 {*********************** Procedures and Functions ************************}
 
 Procedure InsertLLItem(AsmL: PAasmOutput; prev, foll, new_one: PLinkedList_Item);
 
 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 IsGP32Reg(Reg: TRegister): 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;
 
 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 OpsEqual(typ: Longint; op1, op2: Pointer): Boolean;
 
@@ -830,21 +833,18 @@ Begin
       NewRegsEncountered := NewRegsEncountered + [NewReg];
       OldRegsEncountered := OldRegsEncountered + [OldReg];
       New2OldReg[NewReg] := OldReg;
-      Old2NewReg[OldReg] := NewReg;
       Case OldReg Of
         R_EAX..R_EDI:
           Begin
             NewRegsEncountered := NewRegsEncountered + [Reg32toReg16(NewReg)];
             OldRegsEncountered := OldRegsEncountered + [Reg32toReg16(OldReg)];
             New2OldReg[Reg32toReg16(NewReg)] := Reg32toReg16(OldReg);
-            Old2NewReg[Reg32toReg16(OldReg)] := Reg32toReg16(NewReg);
             If (NewReg in [R_EAX..R_EBX]) And
                (OldReg in [R_EAX..R_EBX]) Then
               Begin
                 NewRegsEncountered := NewRegsEncountered + [Reg32toReg8(NewReg)];
                 OldRegsEncountered := OldRegsEncountered + [Reg32toReg8(OldReg)];
                 New2OldReg[Reg32toReg8(NewReg)] := Reg32toReg8(OldReg);
-                Old2NewReg[Reg32toReg8(OldReg)] := Reg32toReg8(NewReg);
               End;
           End;
         R_AX..R_DI:
@@ -852,14 +852,12 @@ Begin
             NewRegsEncountered := NewRegsEncountered + [Reg16toReg32(NewReg)];
             OldRegsEncountered := OldRegsEncountered + [Reg16toReg32(OldReg)];
             New2OldReg[Reg16toReg32(NewReg)] := Reg16toReg32(OldReg);
-            Old2NewReg[Reg16toReg32(OldReg)] := Reg16toReg32(NewReg);
             If (NewReg in [R_AX..R_BX]) And
                (OldReg in [R_AX..R_BX]) Then
               Begin
                 NewRegsEncountered := NewRegsEncountered + [Reg16toReg8(NewReg)];
                 OldRegsEncountered := OldRegsEncountered + [Reg16toReg8(OldReg)];
                 New2OldReg[Reg16toReg8(NewReg)] := Reg16toReg8(OldReg);
-                Old2NewReg[Reg16toReg8(OldReg)] := Reg16toReg8(NewReg);
               End;
           End;
         R_AL..R_BL:
@@ -869,7 +867,6 @@ Begin
             OldRegsEncountered := OldRegsEncountered + [Reg8toReg32(OldReg)]
                                + [Reg8toReg16(OldReg)];
             New2OldReg[Reg8toReg32(NewReg)] := Reg8toReg32(OldReg);
-            Old2NewReg[Reg8toReg16(OldReg)] := Reg8toReg16(NewReg);
           End;
       End;
     End;
@@ -892,7 +889,7 @@ Begin
 End;
 
 
-Function RegsEquivalent(OldReg, NewReg: TRegister; Var RegInfo: TRegInfo): Boolean;
+Function RegsEquivalent(OldReg, NewReg: TRegister; Var RegInfo: TRegInfo; OPAct: TOpAction): Boolean;
 Begin
   If Not((OldReg = R_NO) Or (NewReg = R_NO)) 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
  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}
-        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 := OldReg = NewReg
 End;
 
-Function RefsEquivalent(Const R1, R2: TReference; var RegInfo: TRegInfo): Boolean;
+Function RefsEquivalent(Const R1, R2: TReference; var RegInfo: TRegInfo; OpAct: TOpAction): Boolean;
 Begin
   If R1.IsIntValue
      Then RefsEquivalent := R2.IsIntValue and (R1.Offset = R2.Offset)
      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)
             Then
               Begin
@@ -1266,12 +1280,12 @@ Begin
     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}
   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_Ref: OpsEquivalent := RefsEquivalent(TReference(OldOp^), TReference(NewOp^), RegInfo);
+    Top_Ref: OpsEquivalent := RefsEquivalent(TReference(OldOp^), TReference(NewOp^), RegInfo, OpAct);
     Top_None: OpsEquivalent := True
     Else OpsEquivalent := False
   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}
                 InstructionsEquivalent :=
                   RegsEquivalent(TRegister(Pai386(p1)^.op2), TRegister(Pai386(p2)^.op2),
-                                 RegInfo);
+                                 RegInfo, OpAct_Write);
               End
  {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"
@@ -1343,57 +1357,50 @@ Begin {checks whether two Pai386 instructions are equal}
                                 Reg32(TRegister(Pai386(p2)^.op2)),R_NO,R_ESP])
  {it won't do any harm if the register is already in RegsLoadedForRef}
                   Then
-{$ifdef csdebug}
                     Begin
-{$endif csdebug}
                       RegInfo.RegsLoadedForRef := RegInfo.RegsLoadedForRef + [Base];
 {$ifdef csdebug}
                       Writeln(att_reg2str[base], ' added');
-                    end;
 {$endif csdebug}
+                    end;
                 If Not(Index in [ProcInfo.FramePointer,
                                  Reg32(TRegister(Pai386(p2)^.op2)),R_NO,R_ESP])
                   Then
-{$ifdef csdebug}
                     Begin
-{$endif csdebug}
                       RegInfo.RegsLoadedForRef := RegInfo.RegsLoadedForRef + [Index];
 {$ifdef csdebug}
                       Writeln(att_reg2str[index], ' added');
-                    end;
 {$endif csdebug}
+                    end;
 
               End;
             If Not(Reg32(TRegister(Pai386(p2)^.op2)) In [ProcInfo.FramePointer,
                                                          R_NO,R_ESP])
               Then
-{$ifdef csdebug}
                 Begin
-{$endif csdebug}
-
                   RegInfo.RegsLoadedForRef := RegInfo.RegsLoadedForRef -
                                                  [Reg32(TRegister(Pai386(p2)^.op2))];
 {$ifdef csdebug}
                   Writeln(att_reg2str[Reg32(TRegister(Pai386(p2)^.op2))], ' removed');
-                end;
 {$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
       Else
  {an instruction <> mov, movzx, movsx}
         If (Pai386(p1)^.op3t = top_none) Then
           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
           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)),
-                          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)),
-                          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
   not equivalent}
     Else InstructionsEquivalent := False;
@@ -2084,7 +2091,11 @@ End.
 
 {
  $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
 
  Revision 1.31  1998/12/11 00:03:13  peter