소스 검색

* writing to a position in an array now only destroys registers
containing a reference pointing somewhere in that array (since my last
fix, it behaved like a write to a pointer location)

Jonas Maebe 26 년 전
부모
커밋
e62d58ea51
1개의 변경된 파일93개의 추가작업 그리고 56개의 파일을 삭제
  1. 93 56
      compiler/daopt386.pas

+ 93 - 56
compiler/daopt386.pas

@@ -240,6 +240,8 @@ Implementation
 Uses
 Uses
   globals, systems, strings, verbose, hcodegen;
   globals, systems, strings, verbose, hcodegen;
 
 
+Type TRefCompare = function(const r1, r2: TReference): Boolean;
+
 Const AsmInstr: Array[tasmop] Of TAsmInstrucProp = (
 Const AsmInstr: Array[tasmop] Of TAsmInstrucProp = (
   {A_<NONE>} (Ch: (C_All, C_None, C_None)), { new }
   {A_<NONE>} (Ch: (C_All, C_None, C_None)), { new }
   {A_LOCK} (Ch: (C_None, C_None, C_None)),
   {A_LOCK} (Ch: (C_None, C_None, C_None)),
@@ -1584,7 +1586,34 @@ Begin {checks whether two Paicpu instructions are equal}
 End;
 End;
 *)
 *)
 
 
-Function RefInInstruction(Const Ref: TReference; p: Pai): Boolean;
+Procedure ReadReg(p: PPaiProp; Reg: TRegister);
+Begin
+  Reg := Reg32(Reg);
+  If Reg in [R_EAX..R_EDI] Then
+    IncState(p^.Regs[Reg].RState)
+End;
+
+
+Procedure ReadRef(p: PPaiProp; Ref: PReference);
+Begin
+  If Ref^.Base <> R_NO Then
+    ReadReg(p, Ref^.Base);
+  If Ref^.Index <> R_NO Then
+    ReadReg(p, Ref^.Index);
+End;
+
+Procedure ReadOp(P: PPaiProp;const o:toper);
+Begin
+  Case o.typ Of
+    top_reg: ReadReg(P, o.reg);
+    top_ref: ReadRef(P, o.ref);
+    top_symbol : ;
+  End;
+End;
+
+
+Function RefInInstruction(Const Ref: TReference; p: Pai;
+           RefsEq: TRefCompare): Boolean;
 {checks whehter Ref is used in P}
 {checks whehter Ref is used in P}
 Var TmpResult: Boolean;
 Var TmpResult: Boolean;
 Begin
 Begin
@@ -1592,14 +1621,17 @@ Begin
   If (p^.typ = ait_instruction) Then
   If (p^.typ = ait_instruction) Then
     Begin
     Begin
       If (Paicpu(p)^.oper[0].typ = Top_Ref) Then
       If (Paicpu(p)^.oper[0].typ = Top_Ref) Then
-        TmpResult := RefsEqual(Ref, Paicpu(p)^.oper[0].ref^);
+        TmpResult := RefsEq(Ref, Paicpu(p)^.oper[0].ref^);
       If Not(TmpResult) And (Paicpu(p)^.oper[1].typ = Top_Ref) Then
       If Not(TmpResult) And (Paicpu(p)^.oper[1].typ = Top_Ref) Then
-        TmpResult := RefsEqual(Ref, Paicpu(p)^.oper[1].ref^);
+        TmpResult := RefsEq(Ref, Paicpu(p)^.oper[1].ref^);
+      If Not(TmpResult) And (Paicpu(p)^.oper[2].typ = Top_Ref) Then
+        TmpResult := RefsEq(Ref, Paicpu(p)^.oper[2].ref^);
     End;
     End;
   RefInInstruction := TmpResult;
   RefInInstruction := TmpResult;
 End;
 End;
 
 
-Function RefInSequence(Const Ref: TReference; Content: TContent): Boolean;
+Function RefInSequence(Const Ref: TReference; Content: TContent;
+           RefsEq: TRefCompare): Boolean;
 {checks the whole sequence of Content (so StartMod and and the next NrOfMods
 {checks the whole sequence of Content (so StartMod and and the next NrOfMods
  Pai objects) to see whether Ref is used somewhere}
  Pai objects) to see whether Ref is used somewhere}
 Var p: Pai;
 Var p: Pai;
@@ -1613,7 +1645,7 @@ Begin
         (Counter <= Content.NrOfMods) Do
         (Counter <= Content.NrOfMods) Do
     Begin
     Begin
       If (p^.typ = ait_instruction) And
       If (p^.typ = ait_instruction) And
-         RefInInstruction(Ref, p)
+         RefInInstruction(Ref, p, RefsEq)
         Then TmpResult := True;
         Then TmpResult := True;
       Inc(Counter);
       Inc(Counter);
       GetNextInstruction(p,p)
       GetNextInstruction(p,p)
@@ -1621,18 +1653,34 @@ Begin
   RefInSequence := TmpResult
   RefInSequence := TmpResult
 End;
 End;
 
 
+Function ArrayRefsEq(const r1, r2: TReference): Boolean;
+Begin
+  ArrayRefsEq := (R1.Offset+R1.OffsetFixup = R2.Offset+R2.OffsetFixup) And
+                 (R1.Segment = R2.Segment) And (R1.Base = R2.Base) And
+                 (R1.Symbol=R2.Symbol);
+End;
+
+
 Procedure DestroyRefs(p: pai; Const Ref: TReference; WhichReg: TRegister);
 Procedure DestroyRefs(p: pai; Const Ref: TReference; WhichReg: TRegister);
 {destroys all registers which possibly contain a reference to Ref, WhichReg
 {destroys all registers which possibly contain a reference to Ref, WhichReg
  is the register whose contents are being written to memory (if this proc
  is the register whose contents are being written to memory (if this proc
  is called because of a "mov?? %reg, (mem)" instruction)}
  is called because of a "mov?? %reg, (mem)" instruction)}
-Var Counter: TRegister;
+Var RefsEq: TRefCompare;
+    Counter: TRegister;
 Begin
 Begin
   WhichReg := Reg32(WhichReg);
   WhichReg := Reg32(WhichReg);
-  If (Ref.Index = R_NO) And
-     ((Ref.base = procinfo^.FramePointer) Or
-      (Assigned(Ref.Symbol) And
-       (Ref.base = R_NO)))
-    Then
+  If (Ref.base = procinfo^.FramePointer) or
+      Assigned(Ref.Symbol) Then
+    Begin
+      If (Ref.Index = R_NO) And
+         (Not(Assigned(Ref.Symbol)) or
+          (Ref.base = R_NO)) Then
+  { local variable which is not an array }
+        RefsEq := {$ifdef fpc}@{$endif}RefsEqual
+      Else
+  { local variable which is an array }
+        RefsEq := {$ifdef fpc}@{$endif}ArrayRefsEq;
+
 {write something to a parameter, a local or global variable, so
 {write something to a parameter, a local or global variable, so
    * with uncertain optimizations on:
    * with uncertain optimizations on:
       - destroy the contents of registers whose contents have somewhere a
       - destroy the contents of registers whose contents have somewhere a
@@ -1649,12 +1697,12 @@ Begin
                ((Not(cs_UncertainOpts in aktglobalswitches) And
                ((Not(cs_UncertainOpts in aktglobalswitches) And
                  (NrOfMods <> 1)
                  (NrOfMods <> 1)
                 ) Or
                 ) Or
-                (RefInSequence(Ref,PPaiProp(p^.OptInfo)^.Regs[Counter]) And
+                (RefInSequence(Ref,PPaiProp(p^.OptInfo)^.Regs[Counter],RefsEq) And
                  ((Counter <> WhichReg) Or
                  ((Counter <> WhichReg) Or
                   ((NrOfMods <> 1) And
                   ((NrOfMods <> 1) And
  {StarMod is always of the type ait_instruction}
  {StarMod is always of the type ait_instruction}
                    (Paicpu(StartMod)^.oper[0].typ = top_ref) And
                    (Paicpu(StartMod)^.oper[0].typ = top_ref) And
-                   RefsEqual(Paicpu(StartMod)^.oper[0].ref^, Ref)
+                   RefsEq(Paicpu(StartMod)^.oper[0].ref^, Ref)
                   )
                   )
                  )
                  )
                 )
                 )
@@ -1662,7 +1710,8 @@ Begin
               Then
               Then
                 DestroyReg(PPaiProp(p^.OptInfo), Counter)
                 DestroyReg(PPaiProp(p^.OptInfo), Counter)
           End
           End
-    Else
+    End
+  Else
 {write something to a pointer location, so
 {write something to a pointer location, so
    * with uncertain optimzations on:
    * with uncertain optimzations on:
       - do not destroy registers which contain a local/global variable or a
       - do not destroy registers which contain a local/global variable or a
@@ -1670,28 +1719,31 @@ Begin
    * with uncertain optimzations off:
    * with uncertain optimzations off:
       - destroy every register which contains a memory location
       - destroy every register which contains a memory location
       }
       }
-      For Counter := R_EAX to R_EDI Do
-        With PPaiProp(p^.OptInfo)^.Regs[Counter] Do
-        If (typ = Con_Ref) And
-           (Not(cs_UncertainOpts in aktglobalswitches) Or
-        {for movsl}
-            (Ref.Base = R_EDI) Or
-        {don't destroy if reg contains a parameter, local or global variable}
-            Not((NrOfMods = 1) And
-                (Paicpu(StartMod)^.oper[0].typ = top_ref) And
-                ((Paicpu(StartMod)^.oper[0].ref^.base = procinfo^.FramePointer) Or
-                  Assigned(Paicpu(StartMod)^.oper[0].ref^.Symbol)
-                )
-               )
-           )
-          Then DestroyReg(PPaiProp(p^.OptInfo), Counter)
+    For Counter := R_EAX to R_EDI Do
+      With PPaiProp(p^.OptInfo)^.Regs[Counter] Do
+      If (typ = Con_Ref) And
+         (Not(cs_UncertainOpts in aktglobalswitches) Or
+      {for movsl}
+          (Ref.Base = R_EDI) Or
+      {don't destroy if reg contains a parameter, local or global variable}
+          Not((NrOfMods = 1) And
+              (Paicpu(StartMod)^.oper[0].typ = top_ref) And
+              ((Paicpu(StartMod)^.oper[0].ref^.base = procinfo^.FramePointer) Or
+                Assigned(Paicpu(StartMod)^.oper[0].ref^.Symbol)
+              )
+             )
+         )
+        Then DestroyReg(PPaiProp(p^.OptInfo), Counter)
 End;
 End;
 
 
 Procedure DestroyAllRegs(p: PPaiProp);
 Procedure DestroyAllRegs(p: PPaiProp);
 Var Counter: TRegister;
 Var Counter: TRegister;
 Begin {initializes/desrtoys all registers}
 Begin {initializes/desrtoys all registers}
   For Counter := R_EAX To R_EDI Do
   For Counter := R_EAX To R_EDI Do
-    DestroyReg(p, Counter);
+    Begin
+      ReadReg(p, Counter);
+      DestroyReg(p, Counter);
+    End;
   p^.DirFlag := F_Unknown;
   p^.DirFlag := F_Unknown;
 End;
 End;
 
 
@@ -1699,35 +1751,15 @@ Procedure DestroyOp(PaiObj: Pai; const o:Toper);
 Begin
 Begin
   Case o.typ Of
   Case o.typ Of
     top_reg: DestroyReg(PPaiProp(PaiObj^.OptInfo), o.reg);
     top_reg: DestroyReg(PPaiProp(PaiObj^.OptInfo), o.reg);
-    top_ref: DestroyRefs(PaiObj, o.ref^, R_NO);
+    top_ref:
+      Begin
+        ReadRef(PPaiProp(PaiObj^.OptInfo), o.ref);
+        DestroyRefs(PaiObj, o.ref^, R_NO);
+      End;
     top_symbol:;
     top_symbol:;
   End;
   End;
 End;
 End;
 
 
-Procedure ReadReg(p: PPaiProp; Reg: TRegister);
-Begin
-  Reg := Reg32(Reg);
-  If Reg in [R_EAX..R_EDI] Then
-    IncState(p^.Regs[Reg32(Reg)].RState)
-End;
-
-Procedure ReadRef(p: PPaiProp; Ref: PReference);
-Begin
-  If Ref^.Base <> R_NO Then
-    ReadReg(p, Ref^.Base);
-  If Ref^.Index <> R_NO Then
-    ReadReg(p, Ref^.Index);
-End;
-
-Procedure ReadOp(P: PPaiProp;const o:toper);
-Begin
-  Case o.typ Of
-    top_reg: ReadReg(P, o.reg);
-    top_ref: ReadRef(P, o.ref);
-    top_symbol : ;
-  End;
-End;
-
 Function DFAPass1(AsmL: PAasmOutput; BlockStart: Pai): Pai;
 Function DFAPass1(AsmL: PAasmOutput; BlockStart: Pai): Pai;
 {gathers the RegAlloc data... still need to think about where to store it to
 {gathers the RegAlloc data... still need to think about where to store it to
  avoid global vars}
  avoid global vars}
@@ -2351,7 +2383,12 @@ End.
 
 
 {
 {
  $Log$
  $Log$
- Revision 1.60  1999-09-27 23:44:50  peter
+ Revision 1.61  1999-09-29 13:49:53  jonas
+   * writing to a position in an array now only destroys registers
+     containing a reference pointing somewhere in that array (since my last
+     fix, it behaved like a write to a pointer location)
+
+ Revision 1.60  1999/09/27 23:44:50  peter
    * procinfo is now a pointer
    * procinfo is now a pointer
    * support for result setting in sub procedure
    * support for result setting in sub procedure