소스 검색

* fixed a serious bug in the CSE which (I think) only showed with
-dnewoptimizations when using multi-dimensional arrays with
elements of a size different from 1, 2 or 4 (especially strings).
* made the DFA/CSE more robust (much less dependent on specifics of the
code generator)

Jonas Maebe 25 년 전
부모
커밋
e4ceb46242
2개의 변경된 파일297개의 추가작업 그리고 178개의 파일을 삭제
  1. 48 81
      compiler/csopt386.pas
  2. 249 97
      compiler/daopt386.pas

+ 48 - 81
compiler/csopt386.pas

@@ -172,6 +172,7 @@ Begin {CheckSequence}
 { be used anymore after the sequence, are still used nevertheless (when     }
 { range checking is on for instance, because this is not "normal" generated }
 { code, but more or less manually inserted)                                 }
+(*
 {$ifndef fpc}
   If TmpResult Then
 {$else fpc}
@@ -210,6 +211,7 @@ Begin {CheckSequence}
               Exclude(RegInfo.RegsLoadedForRef,RegCounter);
             End;
         End;
+*)
 {$ifndef fpc}
   CheckSequence := TmpResult;
 {$endif fpc}
@@ -543,69 +545,6 @@ begin
     end;
 end;
 
-function RegReadByInstruction(reg: TRegister; hp: pai): boolean;
-{ assumes hp doesn't modify registers implicitely (like div) }
-{ and that reg is a 32bit register                           }
-var p: paicpu;
-    opCount: byte;
-begin
-  RegReadByInstruction := false;
-  p := paicpu(hp);
-  if hp^.typ <> ait_instruction then
-    exit;
-  case p^.opcode of
-    A_IMUL:
-      case p^.ops of
-        1: regReadByInstruction := (reg = R_EAX) or reginOp(reg,p^.oper[0]);
-        2,3:
-          regReadByInstruction := regInOp(reg,p^.oper[0]) or
-            regInOp(reg,p^.oper[1]);
-      end;
-{    A_IDIV,A_DIV,A_IMUL:
-      begin
-        regReadByInstruction :=
-          regInOp(reg,p^.oper[0]) or
-          (((p^.opcode = A_IDIV) or
-            (p^.opcode = A_DIV)) and
-           (reg = R_EAX));
-      end;}
-    else
-      begin
-        for opCount := 0 to 2 do
-          if (p^.oper[opCount].typ = top_ref) and
-             RegInRef(reg,p^.oper[opCount].ref^) then
-            begin
-              RegReadByInstruction := true;
-              exit
-            end;
-        for opCount := 1 to MaxCh do
-          case InsProp[p^.opcode].Ch[opCount] of
-            Ch_RWOp1,Ch_ROp1{$ifdef arithopt},Ch_MOp1{$endif}:
-              if (p^.oper[0].typ = top_reg) and
-                 (reg32(p^.oper[0].reg) = reg) then
-                begin
-                  RegReadByInstruction := true;
-                  exit
-                end;
-            Ch_RWOp2,Ch_ROp2{$ifdef arithopt},Ch_MOp2{$endif}:
-              if (p^.oper[1].typ = top_reg) and
-                 (reg32(p^.oper[1].reg) = reg) then
-                begin
-                  RegReadByInstruction := true;
-                  exit
-                end;
-            Ch_RWOp3,Ch_ROp3{$ifdef arithopt},Ch_MOp3{$endif}:
-              if (p^.oper[2].typ = top_reg) and
-                 (reg32(p^.oper[2].reg) = reg) then
-                begin
-                  RegReadByInstruction := true;
-                  exit
-                end;
-          end;
-      end;
-  end;
-end;
-
 procedure DoReplaceReadReg(orgReg,newReg: tregister; p: paicpu);
 var opCount: byte;
 begin
@@ -653,7 +592,7 @@ function ReplaceReg(asmL: PaasmOutput; orgReg, newReg: TRegister; p: pai;
 { false otherwise. If successful, the contents of newReg are set to c,   }
 { which should hold the contents of newReg before the current sequence   }
 { started                                                                }
-{ if the functino returns true, returnEndP holds the lat instruction     }
+{ if the function returns true, returnEndP holds the last instruction    }
 { where newReg was replaced by orgReg                                    }
 var endP, hp: Pai;
     removeLast, sequenceEnd, tmpResult, newRegModified, orgRegRead: Boolean;
@@ -878,7 +817,7 @@ Procedure DoCSE(AsmL: PAasmOutput; First, Last: Pai);
 {marks the instructions that can be removed by RemoveInstructs. They're not
  removed immediately because sometimes an instruction needs to be checked in
  two different sequences}
-Var Cnt, Cnt2: Longint;
+Var Cnt, Cnt2, Cnt3: Longint;
     p, hp1, hp2: Pai;
     hp3, hp4: pai;
 {$ifdef replacereg}
@@ -916,9 +855,14 @@ Begin
                           Begin
                             If (p = StartMod) And
                                GetLastInstruction (p, hp1) And
-                               (hp1^.typ <> ait_marker)
-                              Then
+                               (hp1^.typ <> ait_marker) Then
 {so we don't try to check a sequence when p is the first instruction of the block}
+                              begin
+{$ifdef csdebug}
+                               hp5 := new(pai_asm_comment,init(strpnew(
+                                 'cse checking '+att_reg2str[Reg32(Paicpu(p)^.oper[1].reg)])));
+                               insertLLItem(asml,p,p^.next,hp5);
+{$endif csdebug}
                                If CheckSequence(p, Paicpu(p)^.oper[1].reg, Cnt, RegInfo) And
                                   (Cnt > 0) Then
                                  Begin
@@ -943,16 +887,31 @@ Begin
                                    While Cnt2 <= Cnt Do
                                      Begin
                                        If (hp1 = nil) And
-                                          Not(RegInInstruction(Paicpu(hp2)^.oper[1].reg, p) Or
-                                              RegInInstruction(Reg32(Paicpu(hp2)^.oper[1].reg), p)) And
-                                          Not((p^.typ = ait_instruction) And
-                                              (paicpu(p)^.OpCode = A_MOV) And
-                                              (paicpu(p)^.Oper[0].typ = top_ref) And
-                                              (PPaiProp(p^.OptInfo)^.Regs[Reg32(paicpu(p)^.Oper[1].reg)].NrOfMods
-                                                 <= (Cnt - Cnt2 + 1)))
-                                         Then hp1 := p;
+                                          Not(RegInInstruction(Paicpu(hp2)^.oper[1].reg, p)) And
+                                          ((p^.typ = ait_instruction) And
+                                           ((paicpu(p)^.OpCode = A_MOV)  or
+                                            (paicpu(p)^.opcode = A_MOVZX) or
+                                            (paicpu(p)^.opcode = A_MOVSX)) And
+                                           (paicpu(p)^.Oper[0].typ = top_ref)) Then
+                                          if (PPaiProp(p^.OptInfo)^.Regs[Reg32(paicpu(p)^.Oper[1].reg)].NrOfMods
+                                               <= (Cnt - Cnt2 + 1)) and
+                                             (Reg32(paicpu(p)^.Oper[1].reg) in regInfo.regsLoadedForRef) then
+                                            begin
+                                              hp3 := p;
+                                              for Cnt3 := PPaiProp(p^.OptInfo)^.Regs[Reg32(paicpu(p)^.Oper[1].reg)].NrOfMods
+                                                  downto 1 do
+                                                begin
 {$ifndef noremove}
-                                       PPaiProp(p^.OptInfo)^.CanBeRemoved := True;
+                                                  if regInInstruction(paicpu(p)^.Oper[1].reg,hp3) then
+                                                    PPaiProp(hp3^.OptInfo)^.CanBeRemoved := True;
+{$endif noremove}
+                                                  getNextInstruction(hp3,hp3);
+                                                end
+                                            end
+                                          else hp1 := p;
+{$ifndef noremove}
+                                       if regInInstruction(Paicpu(hp2)^.oper[1].reg,p) then
+                                         PPaiProp(p^.OptInfo)^.CanBeRemoved := True;
 {$endif noremove}
                                        Inc(Cnt2);
                                        GetNextInstruction(p, p);
@@ -1072,7 +1031,8 @@ Begin
                                        End;
                                    hp3 := New(Pai_Marker,Init(NoPropInfoEnd));
                                    InsertLLItem(AsmL, Pai(hp2^.Previous), hp2, hp3);
-                                   If hp1 <> nil Then p := hp1;
+                                   If hp1 <> nil Then
+                                     p := hp1;
                                    Continue;
                                  End
                                Else
@@ -1085,14 +1045,14 @@ Begin
                                      Cnt2 := 1;
                                      While Cnt2 <= Cnt Do
                                        Begin
-                                         If RegInInstruction(Paicpu(hp2)^.oper[1].reg, p) Or
-                                            RegInInstruction(Reg32(Paicpu(hp2)^.oper[1].reg), p) Then
+                                         If RegInInstruction(Paicpu(hp2)^.oper[1].reg, p) Then
                                            PPaiProp(p^.OptInfo)^.CanBeRemoved := False;
                                          Inc(Cnt2);
                                          GetNextInstruction(p, p);
                                        End;
                                      Continue;
                                    End;
+                              End;
                           End;
                       End;
 {$ifdef replacereg}
@@ -1216,7 +1176,14 @@ End.
 
 {
  $Log$
- Revision 1.56  2000-03-25 19:05:47  jonas
+ Revision 1.57  2000-04-10 12:45:57  jonas
+   * fixed a serious bug in the CSE which (I think) only showed with
+     -dnewoptimizations when using multi-dimensional arrays with
+     elements of a size different from 1, 2 or 4 (especially strings).
+   * made the DFA/CSE more robust (much less dependent on specifics of the
+     code generator)
+
+ Revision 1.56  2000/03/25 19:05:47  jonas
    * fixed some things for -Or. Make cycle now works with -OG2p3r if
      you use -Aas. There still a bug in popt386.pas that causes a
      problem with the binary writer, but I haven't found it yet
@@ -1352,4 +1319,4 @@ End.
  Revision 1.24  1999/08/25 11:59:58  jonas
    * changed pai386, paippc and paiapha (same for tai*) to paicpu (taicpu)
 
-}
+}

+ 249 - 97
compiler/daopt386.pas

@@ -64,11 +64,10 @@ Function RefsEquivalent(Const R1, R2: TReference; Var RegInfo: TRegInfo; OpAct:
 Function RefsEqual(Const R1, R2: TReference): Boolean;
 Function IsGP32Reg(Reg: TRegister): Boolean;
 Function RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
-Function RegInInstruction(Reg: TRegister; p1: Pai): Boolean;
-{$ifdef newOptimizations}
-Function RegInOp(Reg: TRegister; const o:toper): Boolean;
-{$endif newOptimizations}
-Function RegModifiedByInstruction(Reg: TRegister; p1: Pai): Boolean;
+function RegReadByInstruction(reg: TRegister; hp: pai): boolean;
+function RegModifiedByInstruction(Reg: TRegister; p1: Pai): Boolean;
+function RegInInstruction(Reg: TRegister; p1: Pai): Boolean;
+function RegInOp(Reg: TRegister; const o:toper): Boolean;
 
 Function GetNextInstruction(Current: Pai; Var Next: Pai): Boolean;
 Function GetLastInstruction(Current: Pai; Var Last: Pai): Boolean;
@@ -771,52 +770,138 @@ Begin {checks whether Ref contains a reference to Reg}
   RegInRef := (Ref.Base = Reg) Or (Ref.Index = Reg)
 End;
 
-Function RegInInstruction(Reg: TRegister; p1: Pai): Boolean;
-{checks if Reg is used by the instruction p1}
-Var Counter: Longint;
-    TmpResult: Boolean;
-Begin
-  TmpResult := False;
-  If (Pai(p1)^.typ = ait_instruction) Then
-    Begin
-      Reg := Reg32(Reg);
-      Counter := 0;
-      Repeat
-        Case Paicpu(p1)^.oper[Counter].typ Of
-          Top_Reg: TmpResult := Reg = Reg32(Paicpu(p1)^.oper[Counter].reg);
-          Top_Ref: TmpResult := RegInRef(Reg, Paicpu(p1)^.oper[Counter].ref^);
-        End;
-        Inc(Counter)
-      Until (Counter = 3) or TmpResult;
-    End;
-  RegInInstruction := TmpResult
-End;
+function RegReadByInstruction(reg: TRegister; hp: pai): boolean;
+var p: paicpu;
+    opCount: byte;
+begin
+  RegReadByInstruction := false;
+  reg := reg32(reg);
+  p := paicpu(hp);
+  if hp^.typ <> ait_instruction then
+    exit;
+  case p^.opcode of
+    A_IMUL:
+      case p^.ops of
+        1: regReadByInstruction := (reg = R_EAX) or reginOp(reg,p^.oper[0]);
+        2,3:
+          regReadByInstruction := regInOp(reg,p^.oper[0]) or
+            regInOp(reg,p^.oper[1]);
+      end;
+    A_IDIV,A_DIV,A_MUL:
+      begin
+        regReadByInstruction :=
+          regInOp(reg,p^.oper[0]) or (reg = R_EAX);
+      end;
+    else
+      begin
+        for opCount := 0 to 2 do
+          if (p^.oper[opCount].typ = top_ref) and
+             RegInRef(reg,p^.oper[opCount].ref^) then
+            begin
+              RegReadByInstruction := true;
+              exit
+            end;
+        for opCount := 1 to MaxCh do
+          case InsProp[p^.opcode].Ch[opCount] of
+            Ch_REAX..CH_REDI,CH_RWEAX..Ch_MEDI:
+              if reg = TCh2Reg(InsProp[p^.opcode].Ch[opCount]) then
+                begin
+                  RegReadByInstruction := true;
+                  exit
+                end;
+            Ch_RWOp1,Ch_ROp1{$ifdef arithopt},Ch_MOp1{$endif}:
+              if (p^.oper[0].typ = top_reg) and
+                 (reg32(p^.oper[0].reg) = reg) then
+                begin
+                  RegReadByInstruction := true;
+                  exit
+                end;
+            Ch_RWOp2,Ch_ROp2{$ifdef arithopt},Ch_MOp2{$endif}:
+              if (p^.oper[1].typ = top_reg) and
+                 (reg32(p^.oper[1].reg) = reg) then
+                begin
+                  RegReadByInstruction := true;
+                  exit
+                end;
+            Ch_RWOp3,Ch_ROp3{$ifdef arithopt},Ch_MOp3{$endif}:
+              if (p^.oper[2].typ = top_reg) and
+                 (reg32(p^.oper[2].reg) = reg) then
+                begin
+                  RegReadByInstruction := true;
+                  exit
+                end;
+          end;
+      end;
+  end;
+end;
+
+function regInInstruction(Reg: TRegister; p1: Pai): Boolean;
+{ Checks if Reg is used by the instruction p1                              }
+{ Difference with "regReadBysinstruction() or regModifiedByInstruction()": }
+{ this one ignores CH_ALL opcodes, while regModifiedByInstruction doesn't  }
+var p: paicpu;
+    opCount: byte;
+begin
+  reg := reg32(reg);
+  regInInstruction := false;
+  p := paicpu(p1);
+  if p1^.typ <> ait_instruction then
+    exit;
+  case p^.opcode of
+    A_IMUL:
+      case p^.ops of
+        1: regInInstruction := (reg = R_EAX) or reginOp(reg,p^.oper[0]);
+        2,3:
+          regInInstruction := regInOp(reg,p^.oper[0]) or
+            regInOp(reg,p^.oper[1]) or regInOp(reg,p^.oper[2]);
+      end;
+    A_IDIV,A_DIV,A_MUL:
+      regInInstruction :=
+        regInOp(reg,p^.oper[0]) or
+         (reg = R_EAX) or (reg = R_EDX)
+    else
+      begin
+        for opCount := 1 to MaxCh do
+          case InsProp[p^.opcode].Ch[opCount] of
+            CH_REAX..CH_MEDI:
+              if tch2reg(InsProp[p^.opcode].Ch[opCount]) = reg then
+                begin
+                  regInInstruction := true;
+                  exit;
+                end;
+            Ch_ROp1..Ch_MOp1:
+              if regInOp(reg,p^.oper[0]) then
+                begin
+                  regInInstruction := true;
+                  exit
+                end;
+            Ch_ROp2..Ch_MOp2:
+              if regInOp(reg,p^.oper[1]) then
+                begin
+                  regInInstruction := true;
+                  exit
+                end;
+            Ch_ROp3..Ch_MOp3:
+              if regInOp(reg,p^.oper[2]) then
+                begin
+                  regInInstruction := true;
+                  exit
+                end;
+          end;
+      end;
+  end;
+end;
 
-{$ifdef newOptimizations}
 Function RegInOp(Reg: TRegister; const o:toper): Boolean;
 Begin
   RegInOp := False;
+  reg := reg32(reg);
   Case o.typ Of
-    top_reg: RegInOp := Reg = o.reg;
+    top_reg: RegInOp := Reg = reg32(o.reg);
     top_ref: RegInOp := (Reg = o.ref^.Base) Or
                         (Reg = o.ref^.Index);
   End;
 End;
-{$endif newOptimizations}
-(*
-Function RegModifiedByInstruction(Reg: TRegister; p1: Pai): Boolean;
-{returns true if Reg is modified by the instruction p1. P1 is assumed to be
- of the type ait_instruction}
-Var hp: Pai;
-Begin
-  If GetLastInstruction(p1, hp)
-    Then
-      RegModifiedByInstruction :=
-        PPAiProp(p1^.OptInfo)^.Regs[Reg].WState <>
-          PPAiProp(hp^.OptInfo)^.Regs[Reg].WState
-    Else RegModifiedByInstruction := True;
-End;
-*)
 
 Function RegModifiedByInstruction(Reg: TRegister; p1: Pai): Boolean;
 Var InstrProp: TInsProp;
@@ -830,7 +915,7 @@ Begin
       A_IMUL:
         With paicpu(p1)^ Do
           TmpResult :=
-            ((ops = 1) and (reg = R_EAX)) or
+            ((ops = 1) and (reg in [R_EAX,R_EDX])) or
             ((ops = 2) and (Reg32(oper[1].reg) = reg)) or
             ((ops = 3) and (Reg32(oper[2].reg) = reg));
       A_DIV, A_IDIV, A_MUL:
@@ -1098,10 +1183,11 @@ Begin
     Else s := 0
 End;
 
-Function RegInSequence(Reg: TRegister; Const Content: TContent): Boolean;
-{checks the whole sequence of Content (so StartMod and and the next NrOfMods
- Pai objects) to see whether Reg is used somewhere, without it being loaded
- with something else first}
+Function sequenceDependsonReg(Const Content: TContent; seqReg, Reg: TRegister): Boolean;
+{ Content is the sequence of instructions that describes the contents of   }
+{ seqReg. Reg is being overwritten by the current instruction. If the      }
+{ content of seqReg depends on reg (ie. because of a                       }
+{ "movl (seqreg,reg), seqReg" instruction), this function returns true     }
 Var p: Pai;
     Counter: Byte;
     TmpResult: Boolean;
@@ -1117,35 +1203,30 @@ Begin
       If (p^.typ = ait_instruction) and
          ((Paicpu(p)^.opcode = A_MOV) or
           (Paicpu(p)^.opcode = A_MOVZX) or
-          (Paicpu(p)^.opcode = A_MOVSX))
-        Then
-          Begin
-            If (Paicpu(p)^.oper[0].typ = top_ref) Then
-              With Paicpu(p)^.oper[0].ref^ Do
-                If (Base = procinfo^.FramePointer) And
-                   (Index = R_NO)
-                  Then
-                    Begin
-                      RegsChecked := RegsChecked + [Reg32(Paicpu(p)^.oper[1].reg)];
-                      If Reg = Reg32(Paicpu(p)^.oper[1].reg) Then
-                        Break;
-                    End
-                  Else
-                    Begin
-                      If (Base = Reg) And
-                         Not(Base In RegsChecked)
-                        Then TmpResult := True;
-                      If Not(TmpResult) And
-                         (Index = Reg) And
-                           Not(Index In RegsChecked)
-                        Then TmpResult := True;
-                    End
-          End
-        Else TmpResult := RegInInstruction(Reg, p);
+          (Paicpu(p)^.opcode = A_MOVSX) or
+          (paicpu(p)^.opcode = A_LEA)) and
+         (Paicpu(p)^.oper[0].typ = top_ref) Then
+        With Paicpu(p)^.oper[0].ref^ Do
+          If ((Base = procinfo^.FramePointer) or
+              (assigned(symbol) and (base = R_NO))) And
+             (Index = R_NO) Then
+            Begin
+              RegsChecked := RegsChecked + [Reg32(Paicpu(p)^.oper[1].reg)];
+              If Reg = Reg32(Paicpu(p)^.oper[1].reg) Then
+                Break;
+            End
+          Else
+            tmpResult :=
+              regReadByInstruction(reg,p) and
+              regModifiedByInstruction(seqReg,p)
+      Else
+        tmpResult :=
+          regReadByInstruction(reg,p) and
+          regModifiedByInstruction(seqReg,p);
       Inc(Counter);
       GetNextInstruction(p,p)
     End;
-  RegInSequence := TmpResult
+  sequenceDependsonReg := TmpResult
 End;
 
 Procedure DestroyReg(p1: PPaiProp; Reg: TRegister; doIncState:Boolean);
@@ -1173,20 +1254,19 @@ Begin
             WState := TmpWState;
             RState := TmpRState;
           End;
-        For Counter := R_EAX to R_EDI Do
-          With p1^.Regs[Counter] Do
+        For counter := R_EAX to R_EDI Do
+          With p1^.Regs[counter] Do
             If (Typ = Con_Ref) And
-               RegInSequence(Reg, p1^.Regs[Counter])
-              Then
-                Begin
-                  if doIncState then
-                    IncState(WState);
-                  TmpWState := WState;
-                  TmpRState := RState;
-                  FillChar(p1^.Regs[Counter], SizeOf(TContent), 0);
-                  WState := TmpWState;
-                  RState := TmpRState;
-                End;
+               sequenceDependsOnReg(p1^.Regs[counter],counter,reg) Then
+              Begin
+                if doIncState then
+                  IncState(WState);
+                TmpWState := WState;
+                TmpRState := RState;
+                FillChar(p1^.Regs[Counter], SizeOf(TContent), 0);
+                WState := TmpWState;
+                RState := TmpRState;
+              End;
        End;
 End;
 
@@ -1561,9 +1641,24 @@ Begin {initializes/desrtoys all registers}
 End;
 
 Procedure DestroyOp(PaiObj: Pai; const o:Toper);
+{$ifdef statedebug}
+var hp: pai;
+{$endif statedebug}
+
 Begin
   Case o.typ Of
-    top_reg: DestroyReg(PPaiProp(PaiObj^.OptInfo), o.reg, true);
+    top_reg:
+      begin
+{$ifdef statedebug}
+        hp := new(pai_asm_comment,init(strpnew('destroying '+att_reg2str[o.reg])));
+        hp^.next := paiobj^.next;
+        hp^.previous := paiobj;
+        paiobj^.next := hp;
+        if assigned(hp^.next) then
+          hp^.next^.previous := hp;
+{$endif statedebug}
+        DestroyReg(PPaiProp(PaiObj^.OptInfo), o.reg, true);
+      end;
     top_ref:
       Begin
         ReadRef(PPaiProp(PaiObj^.OptInfo), o.ref);
@@ -1610,6 +1705,10 @@ Begin
         End
       Else
         Begin
+{$ifdef statedebug}
+          hp := new(pai_asm_comment,init(strpnew('destroying '+att_reg2str[reg])));
+          insertllitem(asml,p,p^.next,hp);
+{$endif statedebug}
           DestroyReg(PPaiProp(p^.optinfo), Reg, true);
 {$ifdef StateDebug}
           hp := new(pai_asm_comment,init(strpnew(att_reg2str[reg]+': '+tostr(PPaiProp(p^.optinfo)^.Regs[reg].WState))));
@@ -1890,6 +1989,11 @@ Begin
                       Case Paicpu(p)^.oper[1].typ Of
                         Top_Reg:
                           Begin
+{$ifdef statedebug}
+                            hp := new(pai_asm_comment,init(strpnew('destroying '+
+                              att_reg2str[Paicpu(p)^.oper[1].reg])));
+                            insertllitem(asml,p,p^.next,hp);
+{$endif statedebug}
                             DestroyReg(CurProp, Paicpu(p)^.oper[1].reg, true);
                             ReadReg(CurProp, Paicpu(p)^.oper[0].reg);
 {                            CurProp^.Regs[Paicpu(p)^.oper[1].reg] :=
@@ -1908,7 +2012,6 @@ Begin
                     Top_Ref:
                       Begin {destination is always a register in this case}
                         ReadRef(CurProp, Paicpu(p)^.oper[0].ref);
-                        ReadReg(CurProp, Paicpu(p)^.oper[1].reg);
                         TmpReg := Reg32(Paicpu(p)^.oper[1].reg);
                         If RegInRef(TmpReg, Paicpu(p)^.oper[0].ref^) And
                            (CurProp^.Regs[TmpReg].Typ = Con_Ref)
@@ -1927,6 +2030,10 @@ Begin
                             End
                           Else
                             Begin
+{$ifdef statedebug}
+                              hp := new(pai_asm_comment,init(strpnew('destroying & initing '+att_reg2str[tmpreg])));
+                              insertllitem(asml,p,p^.next,hp);
+{$endif statedebug}
                               DestroyReg(CurProp, TmpReg, true);
                               If Not(RegInRef(TmpReg, Paicpu(p)^.oper[0].ref^)) Then
                                 With CurProp^.Regs[TmpReg] Do
@@ -1948,6 +2055,10 @@ Begin
                           Top_Reg:
                             Begin
                               TmpReg := Reg32(Paicpu(p)^.oper[1].reg);
+{$ifdef statedebug}
+          hp := new(pai_asm_comment,init(strpnew('destroying '+att_reg2str[tmpreg])));
+          insertllitem(asml,p,p^.next,hp);
+{$endif statedebug}
                               With CurProp^.Regs[TmpReg] Do
                                 Begin
                                   DestroyReg(CurProp, TmpReg, true);
@@ -1971,6 +2082,10 @@ Begin
                   If (Paicpu(p)^.OpCode = A_IDIV) or
                      (Paicpu(p)^.OpCode = A_DIV) Then
                     ReadReg(CurProp,R_EDX);
+{$ifdef statedebug}
+                  hp := new(pai_asm_comment,init(strpnew('destroying eax and edx')));
+                  insertllitem(asml,p,p^.next,hp);
+{$endif statedebug}
                   DestroyReg(CurProp, R_EAX, true);
                   DestroyReg(CurProp, R_EDX, true)
                 End;
@@ -1982,18 +2097,25 @@ Begin
                     If (Paicpu(p)^.oper[1].typ = top_none) Then
                       Begin
                         ReadReg(CurProp,R_EAX);
+{$ifdef statedebug}
+                        hp := new(pai_asm_comment,init(strpnew('destroying eax and edx')));
+                        insertllitem(asml,p,p^.next,hp);
+{$endif statedebug}
                         DestroyReg(CurProp, R_EAX, true);
                         DestroyReg(CurProp, R_EDX, true)
                       End
                     Else
             {$ifdef arithopt}
-                      AddInstr2OpContents(Paicpu(p), Paicpu(p)^.oper[1])
+                      AddInstr2OpContents(
+                        {$ifdef statedebug}asml,{$endif}
+                          Paicpu(p), Paicpu(p)^.oper[1])
             {$else arithopt}
                       DestroyOp(p, Paicpu(p)^.oper[1])
             {$endif arithopt}
                   Else
             {$ifdef arithopt}
-                    AddInstr2OpContents(Paicpu(p), Paicpu(p)^.oper[2]);
+                    AddInstr2OpContents({$ifdef statedebug}asml,{$endif}
+                      Paicpu(p), Paicpu(p)^.oper[2]);
             {$else arithopt}
                     DestroyOp(p, Paicpu(p)^.oper[2]);
             {$endif arithopt}
@@ -2003,8 +2125,17 @@ Begin
                 begin
                   readop(curprop,paicpu(p)^.oper[0]);
                   if reginref(paicpu(p)^.oper[1].reg,paicpu(p)^.oper[0].ref^) then
-                    AddInstr2RegContents(paicpu(p), paicpu(p)^.oper[1].reg)
-                  else destroyreg(curprop,paicpu(p)^.oper[1].reg,true);
+                    AddInstr2RegContents({$ifdef statedebug}asml,{$endif}
+                      paicpu(p), paicpu(p)^.oper[1].reg)
+                  else
+                    begin
+{$ifdef statedebug}
+                      hp := new(pai_asm_comment,init(strpnew('destroying '+
+                        att_reg2str[paicpu(p)^.oper[1].reg])));
+                      insertllitem(asml,p,p^.next,hp);
+{$endif statedebug}
+                      destroyreg(curprop,paicpu(p)^.oper[1].reg,true);
+                    end;
                 end;
 {$endif arithopt}
               Else
@@ -2019,13 +2150,17 @@ Begin
                           Begin
                             If (InstrProp.Ch[Cnt] >= Ch_RWEAX) Then
                               ReadReg(CurProp, TCh2Reg(InstrProp.Ch[Cnt]));
+{$ifdef statedebug}
+                            hp := new(pai_asm_comment,init(strpnew('destroying '+
+                              att_reg2str[TCh2Reg(InstrProp.Ch[Cnt])])));
+                            insertllitem(asml,p,p^.next,hp);
+{$endif statedebug}
                             DestroyReg(CurProp, TCh2Reg(InstrProp.Ch[Cnt]), true);
                           End;
 {$ifdef arithopt}
                         Ch_MEAX..Ch_MEDI:
-                          AddInstr2RegContents({$ifdef statedebug} asml, {$endif}
-                                               Paicpu(p),
-                                               TCh2Reg(InstrProp.Ch[Cnt]));
+                          AddInstr2RegContents({$ifdef statedebug} asml,{$endif}
+                                               Paicpu(p),TCh2Reg(InstrProp.Ch[Cnt]));
 {$endif arithopt}
                         Ch_CDirFlag: CurProp^.DirFlag := F_NotSet;
                         Ch_SDirFlag: CurProp^.DirFlag := F_Set;
@@ -2075,6 +2210,11 @@ Begin
                         Ch_RFlags, Ch_WFlags, Ch_RWFlags, Ch_FPU:
                         Else
                           Begin
+{$ifdef statedebug}
+                            hp := new(pai_asm_comment,init(strpnew(
+                              'destroying all regs for prev instruction')));
+                            insertllitem(asml,p, p^.next,hp);
+{$endif statedebug}
                             DestroyAllRegs(CurProp);
                           End;
                       End;
@@ -2086,6 +2226,11 @@ Begin
           End
         Else
           Begin
+{$ifdef statedebug}
+            hp := new(pai_asm_comment,init(strpnew(
+              'destroying all regs: unknown pai: '+tostr(ord(p^.typ)))));
+            insertllitem(asml,p, p^.next,hp);
+{$endif statedebug}
             DestroyAllRegs(CurProp);
           End;
       End;
@@ -2190,7 +2335,14 @@ End.
 
 {
  $Log$
- Revision 1.85  2000-03-25 18:58:00  jonas
+ Revision 1.86  2000-04-10 12:45:56  jonas
+   * fixed a serious bug in the CSE which (I think) only showed with
+     -dnewoptimizations when using multi-dimensional arrays with
+     elements of a size different from 1, 2 or 4 (especially strings).
+   * made the DFA/CSE more robust (much less dependent on specifics of the
+     code generator)
+
+ Revision 1.85  2000/03/25 18:58:00  jonas
    * moved AllocRegBetween() from csopt386 to this unit because it's now
      also used by popt386
 
@@ -2278,4 +2430,4 @@ End.
  Revision 1.62  1999/10/07 16:07:35  jonas
    * small bugfix in ArrayRefsEq
 
-}
+}