Browse Source

* the optimizer now keeps track of flags register usage. This fixes some
optimizer bugs with int64 calculations (because of the carry flag usage)
* fixed another bug which caused wrong optimizations with complex
array expressions

Jonas Maebe 24 years ago
parent
commit
003549eba1
3 changed files with 221 additions and 128 deletions
  1. 134 116
      compiler/i386/csopt386.pas
  2. 74 8
      compiler/i386/daopt386.pas
  3. 13 4
      compiler/i386/rropt386.pas

+ 134 - 116
compiler/i386/csopt386.pas

@@ -180,104 +180,6 @@ begin
   end;
   end;
 end;
 end;
 
 
-function getPrevSequence(p: Tai; reg: tregister; currentPrev: Tai; var newPrev: Tai;
-  var passedJump: boolean; var regsNotRead, regsStillValid: tregset): tregister;
-
-const
-  current_reg: tregister = R_NO;
-
-  function stillValid(p: Tai): boolean;
-  begin
-    stillValid :=
-      (p.typ = ait_instruction) and
-      (Taicpu(p).opcode <> a_jmp) and
-      (pTaiprop(p.optinfo)^.regs[reg].wstate =
-         pTaiprop(currentPrev.optinfo)^.regs[reg].wstate) and
-     { in case destroyreg is called with doIncState = false }
-      (pTaiprop(p.optinfo)^.regs[reg].typ =
-         pTaiprop(currentPrev.optinfo)^.regs[reg].typ) and
-      (reg in (regsNotRead * regsStillValid));
-    passedJump :=
-      (p.typ = ait_instruction) and
-      (Taicpu(p).is_jmp);
-  end;
-
-  function findChangedRegister(p: Tai): tregister;
-  var
-    regCounter: tregister;
-  begin
-    for regCounter := succ(current_reg) to R_EDI do
-      with pTaiprop(p.optinfo)^.regs[regCounter] do
-      if ((startmod <>
-            pTaiprop(currentPrev.optinfo)^.regs[regCounter].startmod)  or
-          (nrOfMods <>
-            pTaiprop(currentPrev.optinfo)^.regs[regCounter].nrOfMods)) and
-         (pTaiprop(p.optinfo)^.regs[regCounter].typ in
-           [con_ref,con_noRemoveRef]) then
-        begin
-          findChangedRegister := regCounter;
-          current_reg := regCounter;
-          exit;
-        end;
-    current_reg := R_NO;
-    findChangedRegister := R_NO;
-  end;
-
-var
-  hp, prevFound: Tai;
-  tmpResult, regCounter: tregister;
-begin
-  if not(current_reg in [R_NO,R_EDI]) then
-    begin
-      tmpResult := findChangedRegister(currentPrev);
-      if tmpResult <> R_NO then
-        begin
-          getPrevSequence := tmpResult;
-          exit;
-        end;
-    end;
-
-  getPrevSequence := R_NO;
-  passedJump := passedJump or
-    ((currentPrev.typ = ait_instruction) and
-     (Taicpu(currentPrev).is_jmp));
-
-  if (passedJump and not(reg in (usableregs+[R_EDI]))) or
-     not getLastInstruction(currentPrev,hp) then
-    exit;
-
-  prevFound := currentPrev;
-  tmpResult := R_NO;
-
-  while (tmpResult = R_NO) and
-        stillValid(hp) and
-        (pTaiprop(prevFound.optinfo)^.canBeRemoved or
-         not(modifiesConflictingMemLocation(prevFound,reg,
-           pTaiprop(p.optinfo)^.regs,regsStillValid))) do
-    begin
-      { only update the regsread for the instructions we already passed }
-      if not(pTaiprop(prevFound.optinfo)^.canBeRemoved) then
-        for regCounter := R_EAX to R_EDI do
-          if regReadByInstruction(regCounter,prevFound) then
-            exclude(regsNotRead,regCounter);
-
-      { in case getPreviousInstruction fails and sets hp to nil in the }
-      { next iteration                                                 }
-      prevFound := hp;
-      if not(pTaiprop(hp.optinfo)^.canBeRemoved) then
-        tmpResult := findChangedRegister(hp);
-      if { do not load the self pointer or a regvar before a (conditional)  }
-         { jump with a new value, since if the jump is taken, the old value }
-         { is (probably) still necessary                                    }
-         (passedJump and not(reg in (usableregs+[R_EDI]))) or
-         not getLastInstruction(hp,hp) then
-        break;
-    end;
-  getPrevSequence := tmpResult;
-  if tmpResult <> R_NO then
-    newPrev := prevFound;
-end;
-
 
 
 function isSimpleMemLoc(const ref: treference): boolean;
 function isSimpleMemLoc(const ref: treference): boolean;
 begin
 begin
@@ -297,14 +199,114 @@ end;
 Function CheckSequence(p: Tai; var prev: Tai; Reg: TRegister; Var Found: Longint;
 Function CheckSequence(p: Tai; var prev: Tai; Reg: TRegister; Var Found: Longint;
            Var RegInfo: TRegInfo; findPrevSeqs: boolean): Boolean;
            Var RegInfo: TRegInfo; findPrevSeqs: boolean): Boolean;
 
 
-const
-  checkingPrevSequences: boolean = false;
 var
 var
-  regsNotRead, regsStillValid: tregset;
+  regsNotRead, regsStillValid : tregset;
+  checkingPrevSequences,
+  passedFlagsModifyingInstr,
+  passedJump                  : boolean;
 
 
-  function getNextRegToTest(var prev: Tai; currentReg: tregister): tregister;
+  function getPrevSequence(p: Tai; reg: tregister; currentPrev: Tai; var newPrev: Tai): tregister;
+  
   const
   const
-    passedJump: boolean = false;
+    current_reg: tregister = R_NO;
+  
+    function stillValid(p: Tai): boolean;
+    begin
+      stillValid :=
+        (p.typ = ait_instruction) and
+        (Taicpu(p).opcode <> a_jmp) and
+        (pTaiprop(p.optinfo)^.regs[reg].wstate =
+           pTaiprop(currentPrev.optinfo)^.regs[reg].wstate) and
+       { in case destroyreg is called with doIncState = false }
+        (pTaiprop(p.optinfo)^.regs[reg].typ =
+           pTaiprop(currentPrev.optinfo)^.regs[reg].typ) and
+        (reg in (regsNotRead * regsStillValid));
+      passedJump :=
+        (p.typ = ait_instruction) and
+        (Taicpu(p).is_jmp);
+      passedFlagsModifyingInstr :=
+        instrWritesFlags(currentPrev);
+    end;
+  
+    function findChangedRegister(p: Tai): tregister;
+    var
+      regCounter: tregister;
+    begin
+      for regCounter := succ(current_reg) to R_EDI do
+        with pTaiprop(p.optinfo)^.regs[regCounter] do
+        if ((startmod <>
+              pTaiprop(currentPrev.optinfo)^.regs[regCounter].startmod)  or
+            (nrOfMods <>
+              pTaiprop(currentPrev.optinfo)^.regs[regCounter].nrOfMods)) and
+           (pTaiprop(p.optinfo)^.regs[regCounter].typ in
+             [con_ref,con_noRemoveRef]) then
+          begin
+            findChangedRegister := regCounter;
+            current_reg := regCounter;
+            exit;
+          end;
+      current_reg := R_NO;
+      findChangedRegister := R_NO;
+    end;
+  
+  var
+    hp, prevFound: Tai;
+    tmpResult, regCounter: tregister;
+  begin
+    if not(current_reg in [R_NO,R_EDI]) then
+      begin
+        tmpResult := findChangedRegister(currentPrev);
+        if tmpResult <> R_NO then
+          begin
+            getPrevSequence := tmpResult;
+            exit;
+          end;
+      end;
+  
+    getPrevSequence := R_NO;
+    passedJump := passedJump or
+      ((currentPrev.typ = ait_instruction) and
+       (Taicpu(currentPrev).is_jmp));
+    passedFlagsModifyingInstr := instrWritesFlags(currentPrev);
+  
+    if (passedJump and not(reg in (usableregs+[R_EDI]))) or
+       not getLastInstruction(currentPrev,hp) then
+      exit;
+  
+    prevFound := currentPrev;
+    tmpResult := R_NO;
+  
+    while (tmpResult = R_NO) and
+          stillValid(hp) and
+          (pTaiprop(prevFound.optinfo)^.canBeRemoved or
+           not(modifiesConflictingMemLocation(prevFound,reg,
+             pTaiprop(p.optinfo)^.regs,regsStillValid))) do
+      begin
+        { only update the regsread for the instructions we already passed }
+        if not(pTaiprop(prevFound.optinfo)^.canBeRemoved) then
+          for regCounter := R_EAX to R_EDI do
+            if regReadByInstruction(regCounter,prevFound) then
+              exclude(regsNotRead,regCounter);
+  
+        { in case getPreviousInstruction fails and sets hp to nil in the }
+        { next iteration                                                 }
+        prevFound := hp;
+        if not(pTaiprop(hp.optinfo)^.canBeRemoved) then
+          tmpResult := findChangedRegister(hp);
+        if { do not load the self pointer or a regvar before a (conditional)  }
+           { jump with a new value, since if the jump is taken, the old value }
+           { is (probably) still necessary                                    }
+           (passedJump and not(reg in (usableregs+[R_EDI]))) or
+           not getLastInstruction(hp,hp) then
+          break;
+      end;
+    getPrevSequence := tmpResult;
+    if tmpResult <> R_NO then
+      newPrev := prevFound;
+  end;
+  
+
+  function getNextRegToTest(var prev: Tai; currentReg: tregister): tregister;
   begin
   begin
     if not checkingPrevSequences then
     if not checkingPrevSequences then
       begin
       begin
@@ -329,7 +331,7 @@ var
     if checkingPrevSequences then
     if checkingPrevSequences then
       if findPrevSeqs then
       if findPrevSeqs then
         getNextRegToTest :=
         getNextRegToTest :=
-          getPrevSequence(p,reg,prev,prev,passedJump,regsNotRead,RegsStillValid)
+          getPrevSequence(p,reg,prev,prev)
       else
       else
         getNextRegToTest := R_NO;
         getNextRegToTest := R_NO;
   end;
   end;
@@ -341,8 +343,7 @@ Var hp2, hp3{, EndMod},highPrev, orgPrev: Tai;
     HighFound, OrgRegFound: Byte;
     HighFound, OrgRegFound: Byte;
     RegCounter, regCounter2, tmpreg, base, index: TRegister;
     RegCounter, regCounter2, tmpreg, base, index: TRegister;
     OrgRegResult: Boolean;
     OrgRegResult: Boolean;
-    TmpResult: Boolean;
-    {TmpState: Byte;}
+    TmpResult, flagResultsNeeded: Boolean;
 Begin {CheckSequence}
 Begin {CheckSequence}
   Reg := Reg32(Reg);
   Reg := Reg32(Reg);
   TmpResult := False;
   TmpResult := False;
@@ -360,6 +361,8 @@ Begin {CheckSequence}
     end;
     end;
 
 
   checkingPrevSequences := false;
   checkingPrevSequences := false;
+  passedFlagsModifyingInstr := false;
+  flagResultsNeeded := false;
   regsNotRead := [R_EAX,R_EBX,R_ECX,R_EDX,R_ESP,R_EBP,R_EDI,R_ESI];
   regsNotRead := [R_EAX,R_EBX,R_ECX,R_EDX,R_ESP,R_EBP,R_EDI,R_ESI];
   regsStillValid := regsNotRead;
   regsStillValid := regsNotRead;
   GetLastInstruction(p, prev);
   GetLastInstruction(p, prev);
@@ -417,6 +420,10 @@ Begin {CheckSequence}
           for regCounter2 := R_EAX to R_EDI do
           for regCounter2 := R_EAX to R_EDI do
             regModified[regCounter2] := regModified[regCounter2] or
             regModified[regCounter2] := regModified[regCounter2] or
               regModifiedByInstruction(regCounter2,hp3);
               regModifiedByInstruction(regCounter2,hp3);
+          if flagResultsNeeded then
+            flagResultsNeeded := not instrReadsFlags(hp3);
+          if not flagResultsNeeded then
+            flagResultsNeeded := pTaiprop(hp3.optinfo)^.FlagsUsed;
           GetNextInstruction(hp2, hp2);
           GetNextInstruction(hp2, hp2);
           GetNextInstruction(hp3, hp3);
           GetNextInstruction(hp3, hp3);
           Inc(Found);
           Inc(Found);
@@ -429,15 +436,18 @@ Begin {CheckSequence}
           include(regInfo.regsStillUsedAfterSeq,regCounter2);
           include(regInfo.regsStillUsedAfterSeq,regCounter2);
 
 
       if checkingPrevSequences then
       if checkingPrevSequences then
-        for regCounter2 := R_EAX to R_EDI do
-          if not(regInfo.new2OldReg[regCounter2] in [R_NO,regCounter2]) and
-             (not(regCounter2 in (regsNotRead * regsStillValid)) or
-              not(regInfo.new2OldReg[regCounter2] in regsStillValid)) then
-            begin
+        begin
+          for regCounter2 := R_EAX to R_EDI do
+            if not(regInfo.new2OldReg[regCounter2] in [R_NO,regCounter2]) and
+               (not(regCounter2 in (regsNotRead * regsStillValid)) or
+               not(regInfo.new2OldReg[regCounter2] in regsStillValid)) then
+              begin
+                found := 0;
+                break;
+              end;
+           if passedFlagsModifyingInstr and flagResultsNeeded then
               found := 0;
               found := 0;
-              break;
-            end;
-
+        end;
       If (Found <> OldNrOfMods) or
       If (Found <> OldNrOfMods) or
  { the following is to avoid problems with rangecheck code (see testcse2) }
  { the following is to avoid problems with rangecheck code (see testcse2) }
          (assigned(hp3) and
          (assigned(hp3) and
@@ -1375,6 +1385,7 @@ Begin
                                    Cnt2 := 1;
                                    Cnt2 := 1;
                                    While Cnt2 <= Cnt Do
                                    While Cnt2 <= Cnt Do
                                      Begin
                                      Begin
+(*
                                        If not(regInInstruction(Taicpu(hp2).oper[1].reg, p)) and
                                        If not(regInInstruction(Taicpu(hp2).oper[1].reg, p)) and
                                           not(pTaiprop(p.optinfo)^.canBeRemoved) then
                                           not(pTaiprop(p.optinfo)^.canBeRemoved) then
                                          begin
                                          begin
@@ -1409,8 +1420,9 @@ Begin
                                                PTaiProp(p.OptInfo)^.CanBeRemoved := True
                                                PTaiProp(p.OptInfo)^.CanBeRemoved := True
 {$endif noremove}
 {$endif noremove}
                                          end
                                          end
+*)
 {$ifndef noremove}
 {$ifndef noremove}
-                                       else
+(*                                       else *)
                                          PTaiProp(p.OptInfo)^.CanBeRemoved := True
                                          PTaiProp(p.OptInfo)^.CanBeRemoved := True
 {$endif noremove}
 {$endif noremove}
                                        ; Inc(Cnt2);
                                        ; Inc(Cnt2);
@@ -1718,7 +1730,13 @@ End.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.16  2001-08-26 13:36:55  florian
+  Revision 1.17  2001-08-29 14:07:43  jonas
+    * the optimizer now keeps track of flags register usage. This fixes some
+      optimizer bugs with int64 calculations (because of the carry flag usage)
+    * fixed another bug which caused wrong optimizations with complex
+      array expressions
+
+  Revision 1.16  2001/08/26 13:36:55  florian
     * some cg reorganisation
     * some cg reorganisation
     * some PPC updates
     * some PPC updates
 
 

+ 74 - 8
compiler/i386/daopt386.pas

@@ -130,6 +130,8 @@ type
 {$endif tempOpts}
 {$endif tempOpts}
     { can this instruction be removed? }
     { can this instruction be removed? }
                CanBeRemoved: Boolean;
                CanBeRemoved: Boolean;
+               { are the resultflags set by this instruction used? }
+               FlagsUsed: Boolean;
              End;
              End;
 
 
   PTaiProp = ^TTaiProp;
   PTaiProp = ^TTaiProp;
@@ -164,6 +166,8 @@ function RegReadByInstruction(reg: TRegister; hp: Tai): boolean;
 function RegModifiedByInstruction(Reg: TRegister; p1: Tai): Boolean;
 function RegModifiedByInstruction(Reg: TRegister; p1: Tai): Boolean;
 function RegInInstruction(Reg: TRegister; p1: Tai): Boolean;
 function RegInInstruction(Reg: TRegister; p1: Tai): Boolean;
 function RegInOp(Reg: TRegister; const o:toper): Boolean;
 function RegInOp(Reg: TRegister; const o:toper): Boolean;
+function instrWritesFlags(p: Tai): boolean;
+function instrReadsFlags(p: Tai): boolean;
 
 
 function writeToMemDestroysContents(regWritten: tregister; const ref: treference;
 function writeToMemDestroysContents(regWritten: tregister; const ref: treference;
   reg: tregister; const c: tcontent): boolean;
   reg: tregister; const c: tcontent): boolean;
@@ -952,6 +956,46 @@ Begin
   RegModifiedByInstruction := TmpResult
   RegModifiedByInstruction := TmpResult
 End;
 End;
 
 
+
+function instrWritesFlags(p: Tai): boolean;
+var
+  l: longint;
+begin
+  instrWritesFlags := true;
+  case p.typ of
+    ait_instruction:
+      begin
+        for l := 1 to MaxCh do
+          if InsProp[Taicpu(p).opcode].Ch[l] in [Ch_WFlags,Ch_RWFlags,Ch_All] then
+            exit;
+      end;
+    ait_label:
+      exit;
+    else
+      instrWritesFlags := false;
+  end;
+end;
+
+function instrReadsFlags(p: Tai): boolean;
+var
+  l: longint;
+begin
+  instrReadsFlags := true;
+  case p.typ of
+    ait_instruction:
+      begin
+        for l := 1 to MaxCh do
+          if InsProp[Taicpu(p).opcode].Ch[l] in [Ch_RFlags,Ch_RWFlags,Ch_All] then
+            exit;
+      end;
+    ait_label:
+      exit;
+    else
+      instrReadsFlags := false;
+  end;
+end;
+
+
 {********************* GetNext and GetLastInstruction *********************}
 {********************* GetNext and GetLastInstruction *********************}
 Function GetNextInstruction(Current: Tai; Var Next: Tai): Boolean;
 Function GetNextInstruction(Current: Tai; Var Next: Tai): Boolean;
 { skips ait_regalloc, ait_regdealloc and ait_stab* objects and puts the }
 { skips ait_regalloc, ait_regdealloc and ait_stab* objects and puts the }
@@ -1877,11 +1921,11 @@ BlockStart, BlockEnd: Tai);
  contents for the instructions starting with p. Returns the last Tai which has
  contents for the instructions starting with p. Returns the last Tai which has
  been processed}
  been processed}
 Var
 Var
-    CurProp: PTaiProp;
+    CurProp, LastFlagsChangeProp: PTaiProp;
     Cnt, InstrCnt : Longint;
     Cnt, InstrCnt : Longint;
     InstrProp: TInsProp;
     InstrProp: TInsProp;
     UsedRegs: TRegSet;
     UsedRegs: TRegSet;
-    p, hp : Tai;
+    prev, p, hp : Tai;
     TmpRef: TReference;
     TmpRef: TReference;
     TmpReg: TRegister;
     TmpReg: TRegister;
 {$ifdef AnalyzeLoops}
 {$ifdef AnalyzeLoops}
@@ -1889,6 +1933,8 @@ Var
 {$endif AnalyzeLoops}
 {$endif AnalyzeLoops}
 Begin
 Begin
   p := BlockStart;
   p := BlockStart;
+  LastFlagsChangeProp := nil;
+  prev := nil;
   UsedRegs := [];
   UsedRegs := [];
   UpdateUsedregs(UsedRegs, p);
   UpdateUsedregs(UsedRegs, p);
   SkipHead(P);
   SkipHead(P);
@@ -1898,16 +1944,16 @@ Begin
   While (P <> BlockEnd) Do
   While (P <> BlockEnd) Do
     Begin
     Begin
       CurProp := @TaiPropBlock^[InstrCnt];
       CurProp := @TaiPropBlock^[InstrCnt];
-      If (p <> BlockStart)
+      If assigned(prev)
         Then
         Then
           Begin
           Begin
 {$ifdef JumpAnal}
 {$ifdef JumpAnal}
             If (p.Typ <> ait_label) Then
             If (p.Typ <> ait_label) Then
 {$endif JumpAnal}
 {$endif JumpAnal}
               Begin
               Begin
-                GetLastInstruction(p, hp);
-                CurProp^.regs := PTaiProp(hp.OptInfo)^.Regs;
-                CurProp^.DirFlag := PTaiProp(hp.OptInfo)^.DirFlag;
+                CurProp^.regs := PTaiProp(prev.OptInfo)^.Regs;
+                CurProp^.DirFlag := PTaiProp(prev.OptInfo)^.DirFlag;
+                CurProp^.FlagsUsed := false;
               End
               End
           End
           End
         Else
         Else
@@ -2332,7 +2378,18 @@ Begin
                             tmpRef.index := R_EDI;
                             tmpRef.index := R_EDI;
                             DestroyRefs(p, TmpRef, R_NO)
                             DestroyRefs(p, TmpRef, R_NO)
                           End;
                           End;
-                        Ch_RFlags, Ch_WFlags, Ch_RWFlags, Ch_FPU:
+                        Ch_RFlags:
+                          if assigned(LastFlagsChangeProp) then
+                            LastFlagsChangeProp^.FlagsUsed := true;
+                        Ch_WFlags:
+                          LastFlagsChangeProp := CurProp;
+                        Ch_RWFlags:
+                          begin
+                            if assigned(LastFlagsChangeProp) then
+                              LastFlagsChangeProp^.FlagsUsed := true;
+                            LastFlagsChangeProp := CurProp;
+                          end;
+                         Ch_FPU:;
                         Else
                         Else
                           Begin
                           Begin
 {$ifdef statedebug}
 {$ifdef statedebug}
@@ -2341,6 +2398,7 @@ Begin
                             insertllitem(asml,p, p.next,hp);
                             insertllitem(asml,p, p.next,hp);
 {$endif statedebug}
 {$endif statedebug}
                             DestroyAllRegs(CurProp);
                             DestroyAllRegs(CurProp);
+                            LastFlagsChangeProp := CurProp;
                           End;
                           End;
                       End;
                       End;
                       Inc(Cnt);
                       Inc(Cnt);
@@ -2360,6 +2418,7 @@ Begin
           End;
           End;
       End;
       End;
       Inc(InstrCnt);
       Inc(InstrCnt);
+      prev := p;
       GetNextInstruction(p, p);
       GetNextInstruction(p, p);
     End;
     End;
 End;
 End;
@@ -2413,6 +2472,7 @@ Begin
     Begin
     Begin
       InitDFAPass2 := True;
       InitDFAPass2 := True;
       GetMem(TaiPropBlock, NrOfTaiObjs*SizeOf(TTaiProp));
       GetMem(TaiPropBlock, NrOfTaiObjs*SizeOf(TTaiProp));
+      fillchar(TaiPropBlock^,NrOfTaiObjs*SizeOf(TTaiProp),0);
       p := BlockStart;
       p := BlockStart;
       SkipHead(p);
       SkipHead(p);
       For Count := 1 To NrOfTaiObjs Do
       For Count := 1 To NrOfTaiObjs Do
@@ -2452,7 +2512,13 @@ End.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.19  2001-08-26 13:36:55  florian
+  Revision 1.20  2001-08-29 14:07:43  jonas
+    * the optimizer now keeps track of flags register usage. This fixes some
+      optimizer bugs with int64 calculations (because of the carry flag usage)
+    * fixed another bug which caused wrong optimizations with complex
+      array expressions
+
+  Revision 1.19  2001/08/26 13:36:55  florian
     * some cg reorganisation
     * some cg reorganisation
     * some PPC updates
     * some PPC updates
 
 

+ 13 - 4
compiler/i386/rropt386.pas

@@ -51,7 +51,8 @@ begin
       canBeFirstSwitch :=
       canBeFirstSwitch :=
         (p.ops >= 2) and
         (p.ops >= 2) and
         (reg32(p.oper[p.ops-1].reg) = reg) and
         (reg32(p.oper[p.ops-1].reg) = reg) and
-        (p.oper[0].typ <> top_ref);
+        (p.oper[0].typ <> top_ref) and
+        (not pTaiprop(p.optinfo)^.FlagsUsed);
     A_INC,A_DEC,A_SUB,A_ADD:
     A_INC,A_DEC,A_SUB,A_ADD:
       canBeFirstSwitch :=
       canBeFirstSwitch :=
         (p.oper[1].typ = top_reg) and
         (p.oper[1].typ = top_reg) and
@@ -59,14 +60,16 @@ begin
         (reg32(p.oper[1].reg) = reg) and
         (reg32(p.oper[1].reg) = reg) and
         (p.oper[0].typ <> top_ref) and
         (p.oper[0].typ <> top_ref) and
         ((p.opcode <> A_SUB) or
         ((p.opcode <> A_SUB) or
-         (p.oper[0].typ = top_const));
+         (p.oper[0].typ = top_const)) and
+        (not pTaiprop(p.optinfo)^.FlagsUsed);
     A_SHL:
     A_SHL:
       canBeFirstSwitch :=
       canBeFirstSwitch :=
         (p.opsize = S_L) and
         (p.opsize = S_L) and
         (p.oper[1].typ = top_reg) and
         (p.oper[1].typ = top_reg) and
         (p.oper[1].reg = reg) and
         (p.oper[1].reg = reg) and
         (p.oper[0].typ = top_const) and
         (p.oper[0].typ = top_const) and
-        (p.oper[0].val in [1,2,3]);
+        (p.oper[0].val in [1,2,3]) and
+        (not pTaiprop(p.optinfo)^.FlagsUsed);
   end;
   end;
 end;
 end;
 
 
@@ -335,7 +338,13 @@ End.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.6  2001-01-06 23:35:06  jonas
+  Revision 1.7  2001-08-29 14:07:43  jonas
+    * the optimizer now keeps track of flags register usage. This fixes some
+      optimizer bugs with int64 calculations (because of the carry flag usage)
+    * fixed another bug which caused wrong optimizations with complex
+      array expressions
+
+  Revision 1.6  2001/01/06 23:35:06  jonas
     * fixed webbug 1323
     * fixed webbug 1323
 
 
   Revision 1.5  2000/12/25 00:07:34  peter
   Revision 1.5  2000/12/25 00:07:34  peter