Просмотр исходного кода

+ first implementation of choosing least used register for alignment code
(not yet working, between ifdef alignreg)

Jonas Maebe 26 лет назад
Родитель
Сommit
2688bfd9ec
4 измененных файлов с 251 добавлено и 30 удалено
  1. 19 2
      compiler/aasm.pas
  2. 37 1
      compiler/cpuasm.pas
  3. 156 1
      compiler/csopt386.pas
  4. 39 26
      compiler/daopt386.pas

+ 19 - 2
compiler/aasm.pas

@@ -185,8 +185,14 @@ unit aasm;
 
 
        { alignment for operator }
+
+{$ifndef alignreg}
        pai_align = ^tai_align;
        tai_align = object(tai)
+{$else alignreg}
+       pai_align_abstract = ^tai_align_abstract;
+       tai_align_abstract = object(tai)
+{$endif alignreg}
           aligntype : byte;   { 1 = no align, 2 = word align, 4 = dword align }
           fillsize  : byte;   { real size to fill }
           fillop    : byte;   { value to fill with - optional }
@@ -695,7 +701,11 @@ uses
                               TAI_ALIGN
  ****************************************************************************}
 
+{$ifndef alignreg}
      constructor tai_align.init(b: byte);
+{$else alignreg}
+     constructor tai_align_abstract.init(b: byte);
+{$endif alignreg}
 
        begin
           inherited init;
@@ -710,7 +720,11 @@ uses
        end;
 
 
+{$ifndef alignreg}
      constructor tai_align.init_op(b: byte; _op: byte);
+{$else alignreg}
+     constructor tai_align_abstract.init_op(b: byte; _op: byte);
+{$endif alignreg}
 
        begin
           inherited init;
@@ -724,7 +738,6 @@ uses
           use_op:=true;
        end;
 
-
 {****************************************************************************
                               TAI_CUT
  ****************************************************************************}
@@ -999,7 +1012,11 @@ uses
 end.
 {
   $Log$
-  Revision 1.66  1999-11-02 15:06:56  peter
+  Revision 1.67  1999-11-05 16:01:45  jonas
+    + first implementation of choosing least used register for alignment code
+       (not yet working, between ifdef alignreg)
+
+  Revision 1.66  1999/11/02 15:06:56  peter
     * import library fixes for win32
     * alignment works again
 

+ 37 - 1
compiler/cpuasm.pas

@@ -53,6 +53,15 @@ type
      constructor dealloc(r : tregister);
   end;
 
+{$ifdef alignreg}
+       { alignment for operator }
+       pai_align = ^tai_align;
+       tai_align = object(tai_align_abstract)
+          reg       : tregister;
+          constructor init(b:byte);
+          constructor init_op(b: byte; _op: byte);
+       end;
+{$endif alignreg}
 
   paicpu = ^taicpu;
   taicpu = object(tai)
@@ -155,6 +164,29 @@ uses
       end;
 
 
+{$ifdef alignreg}
+{****************************************************************************
+                              TAI_ALIGN
+ ****************************************************************************}
+
+     constructor tai_align.init(b: byte);
+
+       begin
+          inherited init(b);
+          reg := R_ECX;
+       end;
+
+
+     constructor tai_align.init_op(b: byte; _op: byte);
+
+       begin
+          inherited init_op(b,_op);
+          reg := R_ECX;
+       end;
+
+{$endif alignreg}
+
+
 {*****************************************************************************
                                  Taicpu Constructors
 *****************************************************************************}
@@ -1496,7 +1528,11 @@ end;
 end.
 {
   $Log$
-  Revision 1.3  1999-08-25 11:59:57  jonas
+  Revision 1.4  1999-11-05 16:01:46  jonas
+    + first implementation of choosing least used register for alignment code
+       (not yet working, between ifdef alignreg)
+
+  Revision 1.3  1999/08/25 11:59:57  jonas
     * changed pai386, paippc and paiapha (same for tai*) to paicpu (taicpu)
 
   Revision 1.2  1999/08/12 14:36:01  peter

+ 156 - 1
compiler/csopt386.pas

@@ -238,6 +238,153 @@ Begin
   Until p1 = p2;
 End;
 
+{$ifdef alignreg}
+Procedure SetAlignReg(p: Pai);
+var regsUsable: TRegSet;
+    prevInstrCount, nextInstrCount: Longint;
+    prevState, nextWState,nextRState: Array[R_EAX..R_EDI] of byte;
+    regCounter, lastRemoved: TRegister;
+    prev, next: Pai;
+{$ifdef alignregdebug}
+    temp: Pai;
+{$endif alignregdebug}
+begin
+  regsUsable := [R_EAX,R_ECX,R_EDX,R_EBX,{R_ESP,R_EBP,}R_ESI,R_EDI];
+  for regCounter := R_EAX to R_EDI do
+    begin
+      prevState[regCounter] := PPaiProp(p^.optInfo)^.Regs[regCounter].wState;
+      nextWState[regCounter] := PPaiProp(p^.optInfo)^.Regs[regCounter].wState;
+      nextRState[regCounter] := PPaiProp(p^.optInfo)^.Regs[regCounter].rState;
+    end;
+  getLastInstruction(p,prev);
+  getNextInstruction(p,next);
+  lastRemoved := pai_align(p)^.reg;
+  nextInstrCount := 0;
+  prevInstrCount := 0;
+  while ((assigned(prev) and
+          assigned(prev^.optInfo) and
+          (prevInstrCount < 10)) or
+         (assigned(next) and
+          assigned(next^.optInfo) and
+          (nextInstrCount < 10))) And
+        (regsUsable <> []) Do
+    begin
+      if assigned(prev) and assigned(prev^.optinfo) and
+         (prevInstrCount < 10) then
+        begin
+          if (prev^.typ = ait_instruction) And
+             (insProp[PaiCpu(prev)^.opcode].ch[1] <> Ch_ALL) and
+             (PaiCpu(prev)^.opcode <> a_jmp) then
+            begin
+              inc(prevInstrCount);
+              for regCounter := R_EAX to R_EDI do
+                begin
+                  if (regCounter in regsUsable) And
+                     (PPaiProp(prev^.optInfo)^.Regs[regCounter].wState <>
+                       prevState[regCounter]) then
+                    begin
+                      lastRemoved := regCounter;
+                      exclude(regsUsable,regCounter);
+  {$ifdef alignregdebug}
+                      if regsUsable = [] then
+                        begin
+                          temp := new(pai_asm_comment,init(strpnew(
+                                    'regsUsable empty here')));
+                          temp^.next := prev^.next;
+                          temp^.previous := prev;
+                          prev^.next := temp;
+                          if assigned(temp^.next) then
+                            temp^.next^.previous := temp;
+                        end;
+  {$endif alignregdebug}
+                    end;
+                  prevState[regCounter] :=
+                    PPaiProp(prev^.optInfo)^.Regs[regCounter].wState;
+                end
+            end
+          else
+            for regCounter := R_EAX to R_EDI do
+              prevState[regCounter] :=
+                PPaiProp(prev^.optInfo)^.Regs[regCounter].wState;
+          getLastInstruction(prev,prev);
+        end;
+      if assigned(next) and assigned(next^.optInfo) and
+         (nextInstrCount < 10) then
+        begin
+          if (next^.typ = ait_instruction) and
+             (insProp[PaiCpu(next)^.opcode].ch[1] <> Ch_ALL) and
+             (PaiCpu(next)^.opcode <> a_jmp) then
+            begin
+              inc(nextInstrCount);
+              for regCounter := R_EAX to R_EDI do
+                begin
+                  if (regCounter in regsUsable) And
+                     ((PPaiProp(next^.optInfo)^.Regs[regCounter].wState <>
+                       nextWState[regCounter]) or
+                      (PPaiProp(next^.optInfo)^.Regs[regCounter].rState <>
+                       nextRState[regCounter])) Then
+                    begin
+                      lastRemoved := regCounter;
+                      exclude(regsUsable,regCounter);
+{$ifdef alignregdebug}
+                      if regsUsable = [] then
+                        begin
+                          temp := new(pai_asm_comment,init(strpnew(
+                                    'regsUsable empty here')));
+                          temp^.next := next^.next;
+                          temp^.previous := next;
+                          next^.next := temp;
+                          if assigned(temp^.next) then
+                            temp^.next^.previous := temp;
+                        end;
+{$endif alignregdebug}
+                    end;
+                  nextWState[regCounter] :=
+                    PPaiProp(next^.optInfo)^.Regs[regCounter].wState;
+                  nextRState[regCounter] :=
+                    PPaiProp(next^.optInfo)^.Regs[regCounter].rState;
+                end
+            end
+          else
+            for regCounter := R_EAX to R_EDI do
+              begin
+                nextWState[regCounter] :=
+                  PPaiProp(next^.optInfo)^.Regs[regCounter].wState;
+                nextRState[regCounter] :=
+                  PPaiProp(next^.optInfo)^.Regs[regCounter].rState;
+              end;
+          getNextInstruction(next,next);
+        end;
+    end;
+  if regsUsable <> [] then
+    for regCounter := R_EAX to R_EDI do
+      if regCounter in regsUsable then
+        begin
+{$ifdef alignregdebug}
+          next := new(pai_asm_comment,init(strpnew('regsusable not empty')));
+          next^.next := p^.next;
+          next^.previous := p;
+          p^.next := next;
+          if assigned(next^.next) then
+            next^.next^.previous := next;
+{$endif alignregdebug}
+
+          lastRemoved := regCounter;
+          break
+        end;
+{$ifdef alignregdebug}
+  next := new(pai_asm_comment,init(strpnew(att_reg2str[lastRemoved]+
+               ' chosen as alignment register')));
+  next^.next := p^.next;
+  next^.previous := p;
+  p^.next := next;
+  if assigned(next^.next) then
+    next^.next^.previous := next;
+{$endif alignregdebug}
+  pai_align(p)^.reg := lastRemoved;
+End;
+{$endif alignreg}
+
 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
@@ -258,6 +405,10 @@ Begin
   While (p <> Last) Do
     Begin
       Case p^.typ Of
+{$ifdef alignreg}
+        ait_align:
+          SetAlignReg(p);
+{$endif alignreg}
         ait_instruction:
           Begin
             Case Paicpu(p)^.opcode Of
@@ -530,7 +681,11 @@ End.
 
 {
  $Log$
- Revision 1.28  1999-10-11 11:11:31  jonas
+ Revision 1.29  1999-11-05 16:01:46  jonas
+   + first implementation of choosing least used register for alignment code
+      (not yet working, between ifdef alignreg)
+
+ Revision 1.28  1999/10/11 11:11:31  jonas
    * fixed bug which sometimes caused a crash when optimizing blocks of code with
      assembler blocks (didn't notice before because of lack of zero page protection
      under Win9x :( )

+ 39 - 26
compiler/daopt386.pas

@@ -85,10 +85,13 @@ Const
 {ait_* types which don't result in executable code or which don't influence
  the way the program runs/behaves}
 
-  SkipInstr = [ait_comment, ait_align, ait_symbol
+  SkipInstr = [ait_comment, ait_symbol
 {$ifdef GDB}
   ,ait_stabs, ait_stabn, ait_stab_function_name
 {$endif GDB}
+{$ifndef alignreg}
+  ,ait_align
+{$endif alignreg}
   ,ait_regalloc, ait_tempalloc
   ];
 
@@ -638,7 +641,7 @@ Begin
     Else
       Begin
         GetNextInstruction := False;
-        Next := Nil;
+        Next := nil;
       End;
 End;
 
@@ -675,7 +678,7 @@ Begin
       (Pai_Marker(Current)^.Kind = AsmBlockEnd))
     Then
       Begin
-        Last := Nil;
+        Last := nil;
         GetLastInstruction := False
       End
     Else
@@ -828,9 +831,13 @@ Begin
   RegInSequence := TmpResult
 End;
 
-Procedure DestroyReg(p1: PPaiProp; Reg: TRegister);
+Procedure DestroyReg(p1: PPaiProp; Reg: TRegister; doIncState:Boolean);
 {Destroys the contents of the register Reg in the PPaiProp p1, as well as the
- contents of registers are loaded with a memory location based on Reg}
+ contents of registers are loaded with a memory location based on Reg.
+ doIncState is false when this register has to be destroyed not because
+ it's contents are directly modified/overwritten, but because of an indirect
+ action (ie. this register holds the contents of a variable and the value
+ of the variable in memory is changed }
 Var TmpWState, TmpRState: Byte;
     Counter: TRegister;
 Begin
@@ -841,7 +848,8 @@ Begin
       Begin
         With p1^.Regs[Reg] Do
           Begin
-            IncState(WState);
+            if doIncState then
+              IncState(WState);
             TmpWState := WState;
             TmpRState := RState;
             FillChar(p1^.Regs[Reg], SizeOf(TContent), 0);
@@ -854,7 +862,8 @@ Begin
                RegInSequence(Reg, p1^.Regs[Counter])
               Then
                 Begin
-                  IncState(WState);
+                  if doIncState then
+                    IncState(WState);
                   TmpWState := WState;
                   TmpRState := RState;
                   FillChar(p1^.Regs[Counter], SizeOf(TContent), 0);
@@ -1195,7 +1204,7 @@ Begin
                 )
                )
               Then
-                DestroyReg(PPaiProp(p^.OptInfo), Counter)
+                DestroyReg(PPaiProp(p^.OptInfo), Counter, false)
           End
     End
   Else
@@ -1220,7 +1229,7 @@ Begin
               )
              )
          )
-        Then DestroyReg(PPaiProp(p^.OptInfo), Counter)
+        Then DestroyReg(PPaiProp(p^.OptInfo), Counter, false)
 End;
 
 Procedure DestroyAllRegs(p: PPaiProp);
@@ -1229,7 +1238,7 @@ Begin {initializes/desrtoys all registers}
   For Counter := R_EAX To R_EDI Do
     Begin
       ReadReg(p, Counter);
-      DestroyReg(p, Counter);
+      DestroyReg(p, Counter, true);
     End;
   p^.DirFlag := F_Unknown;
 End;
@@ -1237,7 +1246,7 @@ End;
 Procedure DestroyOp(PaiObj: Pai; const o:Toper);
 Begin
   Case o.typ Of
-    top_reg: DestroyReg(PPaiProp(PaiObj^.OptInfo), o.reg);
+    top_reg: DestroyReg(PPaiProp(PaiObj^.OptInfo), o.reg, true);
     top_ref:
       Begin
         ReadRef(PPaiProp(PaiObj^.OptInfo), o.ref);
@@ -1284,7 +1293,7 @@ Begin
         End
       Else
         Begin
-          DestroyReg(PPaiProp(p^.optinfo), Reg);
+          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))));
           InsertLLItem(AsmL, p, p^.next, hp);
@@ -1397,7 +1406,7 @@ Begin
                               Begin
                                 If (CurProp^.Regs[TmpReg].WState <>
                                     PPaiProp(hp^.OptInfo)^.Regs[TmpReg].WState)
-                                  Then DestroyReg(CurProp, TmpReg)
+                                  Then DestroyReg(CurProp, TmpReg, true)
                               End
                       End
 {$IfDef AnalyzeLoops}
@@ -1462,7 +1471,7 @@ Begin
 {$ifdef GDB}
         ait_stabs, ait_stabn, ait_stab_function_name:;
 {$endif GDB}
-
+        ait_align: ; { may destroy flags !!! }
         ait_instruction:
           Begin
             if paicpu(p)^.is_jmp then
@@ -1488,7 +1497,7 @@ Begin
                         For TmpReg := R_EAX to R_EDI Do
                           If (PaiPropBlock^[InstrNr].Regs[TmpReg].WState <>
                              CurProp^.Regs[TmpReg].WState) Then
-                            DestroyReg(@PaiPropBlock^[InstrNr], TmpReg);
+                            DestroyReg(@PaiPropBlock^[InstrNr], TmpReg, true);
                         Inc(JmpsProcessed);
                       End
 {$ifdef AnalyzeLoops}
@@ -1512,7 +1521,7 @@ Begin
                                   Cnt := InstrNr;
                                   While (TmpState = PaiPropBlock^[Cnt].Regs[TmpReg].WState) Do
                                     Begin
-                                      DestroyReg(@PaiPropBlock^[Cnt], TmpReg);
+                                      DestroyReg(@PaiPropBlock^[Cnt], TmpReg, true);
                                       Inc(Cnt);
                                     End;
                                   While (Cnt <= InstrCnt) Do
@@ -1539,7 +1548,7 @@ Begin
                               TmpState := PaiPropBlock^[InstrNr].Regs[TmpReg].WState;
                               While (TmpState = PaiPropBlock^[Cnt].Regs[TmpReg].WState) Do
                                 Begin
-                                  DestroyReg(@PaiPropBlock^[Cnt], TmpReg);
+                                  DestroyReg(@PaiPropBlock^[Cnt], TmpReg, true);
                                   Inc(Cnt);
                                 End;
                               While (Cnt <= InstrCnt) Do
@@ -1564,7 +1573,7 @@ Begin
                       Case Paicpu(p)^.oper[1].typ Of
                         Top_Reg:
                           Begin
-                            DestroyReg(CurProp, Paicpu(p)^.oper[1].reg);
+                            DestroyReg(CurProp, Paicpu(p)^.oper[1].reg, true);
                             ReadReg(CurProp, Paicpu(p)^.oper[0].reg);
 {                            CurProp^.Regs[Paicpu(p)^.oper[1].reg] :=
                               CurProp^.Regs[Paicpu(p)^.oper[0].reg];
@@ -1601,7 +1610,7 @@ Begin
                             End
                           Else
                             Begin
-                              DestroyReg(CurProp, TmpReg);
+                              DestroyReg(CurProp, TmpReg, true);
                               If Not(RegInRef(TmpReg, Paicpu(p)^.oper[0].ref^)) Then
                                 With CurProp^.Regs[TmpReg] Do
                                   Begin
@@ -1624,7 +1633,7 @@ Begin
                               TmpReg := Reg32(Paicpu(p)^.oper[1].reg);
                               With CurProp^.Regs[TmpReg] Do
                                 Begin
-                                  DestroyReg(CurProp, TmpReg);
+                                  DestroyReg(CurProp, TmpReg, true);
                                   typ := Con_Const;
                                   StartMod := p;
                                 End
@@ -1645,7 +1654,7 @@ Begin
                   If (Paicpu(p)^.OpCode = A_IDIV) or
                      (Paicpu(p)^.OpCode = A_DIV) Then
                     ReadReg(CurProp,R_EDX);
-                  DestroyReg(CurProp, R_EAX)
+                  DestroyReg(CurProp, R_EAX, true)
                 End;
               A_IMUL:
                 Begin
@@ -1655,8 +1664,8 @@ Begin
                     If (Paicpu(p)^.oper[1].typ = top_none) Then
                       Begin
                         ReadReg(CurProp,R_EAX);
-                        DestroyReg(CurProp, R_EAX);
-                        DestroyReg(CurProp, R_EDX)
+                        DestroyReg(CurProp, R_EAX, true);
+                        DestroyReg(CurProp, R_EDX, true)
                       End
                     Else
             {$ifdef arithopt}
@@ -1680,7 +1689,7 @@ Begin
                      (Paicpu(p)^.oper[0].reg = Paicpu(p)^.oper[1].reg)
                     Then
                       Begin
-                        DestroyReg(CurProp, Paicpu(p)^.oper[0].reg);
+                        DestroyReg(CurProp, Paicpu(p)^.oper[0].reg, true);
                         CurProp^.Regs[Reg32(Paicpu(p)^.oper[0].reg)].typ := Con_Const;
                         CurProp^.Regs[Reg32(Paicpu(p)^.oper[0].reg)].StartMod := Pointer(0)
                       End
@@ -1699,7 +1708,7 @@ Begin
                           Begin
                             If (InstrProp.Ch[Cnt] >= Ch_RWEAX) Then
                               ReadReg(CurProp, TCh2Reg(InstrProp.Ch[Cnt]));
-                            DestroyReg(CurProp, TCh2Reg(InstrProp.Ch[Cnt]));
+                            DestroyReg(CurProp, TCh2Reg(InstrProp.Ch[Cnt]), true);
                           End;
 {$ifdef arithopt}
                         Ch_MEAX..Ch_MEDI:
@@ -1870,7 +1879,11 @@ End.
 
 {
  $Log$
- Revision 1.65  1999-10-27 16:11:28  peter
+ Revision 1.66  1999-11-05 16:01:46  jonas
+   + first implementation of choosing least used register for alignment code
+      (not yet working, between ifdef alignreg)
+
+ Revision 1.65  1999/10/27 16:11:28  peter
    * insns.dat is used to generate all i386*.inc files
 
  Revision 1.64  1999/10/23 14:44:24  jonas