Browse Source

+ optimize pascal code surrounding assembler blocks

Jonas Maebe 26 years ago
parent
commit
8cf4da6d5e
7 changed files with 161 additions and 80 deletions
  1. 5 2
      compiler/aasm.pas
  2. 33 13
      compiler/aopt386.pas
  3. 11 9
      compiler/csopt386.pas
  4. 77 43
      compiler/daopt386.pas
  5. 6 2
      compiler/hcodegen.pas
  6. 13 10
      compiler/popt386.pas
  7. 16 1
      compiler/pstatmnt.pas

+ 5 - 2
compiler/aasm.pas

@@ -254,7 +254,7 @@ unit aasm;
           constructor init_end;
           constructor init_end;
        end;
        end;
 
 
-       TMarker = (NoPropInfoStart, NoPropInfoEnd);
+       TMarker = (NoPropInfoStart, NoPropInfoEnd, AsmBlockStart, AsmBlockEnd);
        pai_marker = ^tai_marker;
        pai_marker = ^tai_marker;
        tai_marker = object(tai)
        tai_marker = object(tai)
          Kind: TMarker;
          Kind: TMarker;
@@ -912,7 +912,10 @@ uses
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.28  1998-12-16 00:27:16  peter
+  Revision 1.29  1998-12-29 18:48:24  jonas
+    + optimize pascal code surrounding assembler blocks
+
+  Revision 1.28  1998/12/16 00:27:16  peter
     * removed some obsolete version checks
     * removed some obsolete version checks
 
 
   Revision 1.27  1998/12/11 00:02:37  peter
   Revision 1.27  1998/12/11 00:02:37  peter

+ 33 - 13
compiler/aopt386.pas

@@ -38,32 +38,52 @@ Uses
 
 
 
 
 Procedure Optimize(AsmL: PAasmOutput);
 Procedure Optimize(AsmL: PAasmOutput);
-Var BlockEnd: Pai;
+Var BlockStart, BlockEnd: Pai;
 Begin
 Begin
 {setup labeltable, always necessary}
 {setup labeltable, always necessary}
-  DFAPass1(AsmL);
+  BlockStart := Pai(AsmL^.First);
+  BlockEnd := DFAPass1(AsmL, BlockStart);
+{Blockend now either contains an ait_marker with Kind = AsmBlockStart, or nil}
+  While Assigned(BlockStart) Do
+    Begin
 {peephole optimizations}
 {peephole optimizations}
-  PeepHoleOptPass1(AsmL);
-  PeepHoleOptPass1(AsmL);
+      PeepHoleOptPass1(AsmL, BlockStart, BlockEnd);
+      PeepHoleOptPass1(AsmL, BlockStart, BlockEnd);
 {data flow analyzer}
 {data flow analyzer}
-  If (cs_slowoptimize in aktglobalswitches) Then
-    Begin
-      BlockEnd := DFAPass2(AsmL);
-      If BlockEnd <> Nil Then
+      If (cs_slowoptimize in aktglobalswitches) Then
+        Begin
+          If DFAPass2(AsmL, BlockStart, BlockEnd) Then
 {common subexpression elimination}
 {common subexpression elimination}
-        CSE(AsmL, Pai(AsmL^.First), BlockEnd);
-    End;
+            CSE(AsmL, BlockStart, BlockEnd);
+        End;
 {more peephole optimizations}
 {more peephole optimizations}
-  PeepHoleOptPass2(AsmL);
+      PeepHoleOptPass2(AsmL, BlockStart, BlockEnd);
 {dispose labeltabel}
 {dispose labeltabel}
-  ShutDownDFA;
+      ShutDownDFA;
+
+      If Assigned(BlockEnd) And
+         GetNextInstruction(BlockEnd, BlockStart) Then
+       {we stopped at an assmbler block, so skip it}
+        Begin
+          While GetNextInstruction(BlockStart, BlockStart) And
+                ((BlockStart^.Typ <> Ait_Marker) Or
+                 (Pai_Marker(Blockstart)^.Kind <> AsmBlockEnd)) Do;
+          If GetNextInstruction(BlockStart, BlockStart) Then
+            BlockEnd := DFAPass1(AsmL, BlockStart)
+          Else BlockStart := Nil
+        End
+      Else BlockStart := Nil;
+   End;
 End;
 End;
 
 
 End.
 End.
 
 
 {
 {
  $Log$
  $Log$
- Revision 1.23  1998-12-11 00:02:43  peter
+ Revision 1.24  1998-12-29 18:48:23  jonas
+   + optimize pascal code surrounding assembler blocks
+
+ Revision 1.23  1998/12/11 00:02:43  peter
    + globtype,tokens,version unit splitted from globals
    + globtype,tokens,version unit splitted from globals
 
 
  Revision 1.22  1998/08/19 16:07:57  jonas
  Revision 1.22  1998/08/19 16:07:57  jonas

+ 11 - 9
compiler/csopt386.pas

@@ -240,10 +240,9 @@ Var Cnt, Cnt2: Longint;
     TmpState: Byte;
     TmpState: Byte;
 Begin
 Begin
   p := First;
   p := First;
-  If (p^.typ in (SkipInstr+[ait_marker])) Then
-    GetNextInstruction(p, p);
+  SkipHead(p);
   First := p;
   First := p;
-  While Assigned(p) Do
+  While (p <> Last) Do
     Begin
     Begin
       Case p^.typ Of
       Case p^.typ Of
         ait_instruction:
         ait_instruction:
@@ -264,7 +263,8 @@ Begin
                       Begin {destination is always a register in this case}
                       Begin {destination is always a register in this case}
                         With PPaiProp(p^.fileinfo.line)^.Regs[Reg32(Tregister(Pai386(p)^.op2))] Do
                         With PPaiProp(p^.fileinfo.line)^.Regs[Reg32(Tregister(Pai386(p)^.op2))] Do
                           Begin
                           Begin
-                            If GetLastInstruction (p, hp1) Then
+                            If GetLastInstruction (p, hp1) And
+                              (hp1^.typ <> ait_marker) Then
 {so we don't try to check a sequence when p is the first instruction of the block}
 {so we don't try to check a sequence when p is the first instruction of the block}
                                If CheckSequence(p, TRegister(Pai386(p)^.op2), Cnt, RegInfo) And
                                If CheckSequence(p, TRegister(Pai386(p)^.op2), Cnt, RegInfo) And
                                   (Cnt > 0)
                                   (Cnt > 0)
@@ -498,7 +498,7 @@ End;
 
 
 Procedure RemoveInstructs(AsmL: PAasmOutput; First, Last: Pai);
 Procedure RemoveInstructs(AsmL: PAasmOutput; First, Last: Pai);
 {Removes the marked instructions and disposes the PPaiProps of the other
 {Removes the marked instructions and disposes the PPaiProps of the other
- instructions, restoring theirline number}
+ instructions, restoring their line number}
 Var p, hp1: Pai;
 Var p, hp1: Pai;
 {$IfDef TP}
 {$IfDef TP}
     TmpLine: Longint;
     TmpLine: Longint;
@@ -506,10 +506,9 @@ Var p, hp1: Pai;
     InstrCnt: Longint;
     InstrCnt: Longint;
 Begin
 Begin
   p := First;
   p := First;
-  If (p^.typ in (SkipInstr + [ait_marker])) Then
-    GetNextInstruction(p, p);
+  SkipHead(P);
   InstrCnt := 1;
   InstrCnt := 1;
-  While Assigned(p) Do
+  While (p <> Last) Do
     Begin
     Begin
 {$ifndef noinstremove}
 {$ifndef noinstremove}
       If PPaiProp(p^.fileinfo.line)^.CanBeRemoved
       If PPaiProp(p^.fileinfo.line)^.CanBeRemoved
@@ -553,7 +552,10 @@ End.
 
 
 {
 {
  $Log$
  $Log$
- Revision 1.17  1998-12-17 16:37:39  jonas
+ Revision 1.18  1998-12-29 18:48:22  jonas
+   + optimize pascal code surrounding assembler blocks
+
+ Revision 1.17  1998/12/17 16:37:39  jonas
    + extra checks in RegsEquivalent so some more optimizations can be done (which
    + extra checks in RegsEquivalent so some more optimizations can be done (which
      where disabled by the second fix from revision 1.22)
      where disabled by the second fix from revision 1.22)
 
 

+ 77 - 43
compiler/daopt386.pas

@@ -62,14 +62,15 @@ Function RegModifiedByInstruction(Reg: TRegister; p1: Pai): Boolean;
 
 
 Function GetNextInstruction(Current: Pai; Var Next: Pai): Boolean;
 Function GetNextInstruction(Current: Pai; Var Next: Pai): Boolean;
 Function GetLastInstruction(Current: Pai; Var Last: Pai): Boolean;
 Function GetLastInstruction(Current: Pai; Var Last: Pai): Boolean;
+Procedure SkipHead(var P: Pai);
 
 
 Procedure UpdateUsedRegs(Var UsedRegs: TRegSet; p: Pai);
 Procedure UpdateUsedRegs(Var UsedRegs: TRegSet; p: Pai);
 Function RegsEquivalent(OldReg, NewReg: TRegister; Var RegInfo: TRegInfo; OpAct: TopAction): Boolean;
 Function RegsEquivalent(OldReg, NewReg: TRegister; Var RegInfo: TRegInfo; OpAct: TopAction): Boolean;
 Function InstructionsEquivalent(p1, p2: Pai; Var RegInfo: TRegInfo): Boolean;
 Function InstructionsEquivalent(p1, p2: Pai; Var RegInfo: TRegInfo): Boolean;
 Function OpsEqual(typ: Longint; op1, op2: Pointer): Boolean;
 Function OpsEqual(typ: Longint; op1, op2: Pointer): Boolean;
 
 
-Procedure DFAPass1(AsmL: PAasmOutput);
-Function DFAPass2(AsmL: PAasmOutput): Pai;
+Function DFAPass1(AsmL: PAasmOutput; BlockStart: Pai): Pai;
+Function DFAPass2(AsmL: PAasmOutput; BlockStart, BlockEnd: Pai): Boolean;
 Procedure ShutDownDFA;
 Procedure ShutDownDFA;
 
 
 Function FindLabel(L: PLabel; Var hp: Pai): Boolean;
 Function FindLabel(L: PLabel; Var hp: Pai): Boolean;
@@ -611,17 +612,19 @@ Var
 
 
 {************************ Create the Label table ************************}
 {************************ Create the Label table ************************}
 
 
-Procedure FindLoHiLabels(AsmL: PAasmOutput; Var LowLabel, HighLabel, LabelDif: Longint);
+Function FindLoHiLabels(AsmL: PAasmOutput; Var LowLabel, HighLabel, LabelDif: Longint; BlockStart: Pai): Pai;
 {Walks through the paasmlist to find the lowest and highest label number;
 {Walks through the paasmlist to find the lowest and highest label number;
  Since 0.9.3: also removes unused labels}
  Since 0.9.3: also removes unused labels}
 Var LabelFound: Boolean;
 Var LabelFound: Boolean;
-    P{, hp1}: Pai;
+    P: Pai;
 Begin
 Begin
   LabelFound := False;
   LabelFound := False;
   LowLabel := MaxLongint;
   LowLabel := MaxLongint;
   HighLabel := 0;
   HighLabel := 0;
-  P := Pai(AsmL^.first);
-  While Assigned(p) Do
+  P := BlockStart;
+  While Assigned(P) And
+        ((P^.typ <> Ait_Marker) Or
+         (Pai_Marker(P)^.Kind <> AsmBlockStart)) Do
     Begin
     Begin
       If (Pai(p)^.typ = ait_label) Then
       If (Pai(p)^.typ = ait_label) Then
         If (Pai_Label(p)^.l^.is_used)
         If (Pai_Label(p)^.l^.is_used)
@@ -643,6 +646,7 @@ Begin
             End};
             End};
       GetNextInstruction(p, p);
       GetNextInstruction(p, p);
     End;
     End;
+  FindLoHiLabels := p;
   If LabelFound
   If LabelFound
     Then LabelDif := HighLabel+1-LowLabel
     Then LabelDif := HighLabel+1-LowLabel
     Else LabelDif := 0;
     Else LabelDif := 0;
@@ -672,7 +676,7 @@ Begin
 End;
 End;
 
 
 Procedure BuildLabelTableAndFixRegAlloc(AsmL: PAasmOutput; Var LabelTable: PLabelTable; LowLabel: Longint;
 Procedure BuildLabelTableAndFixRegAlloc(AsmL: PAasmOutput; Var LabelTable: PLabelTable; LowLabel: Longint;
-            Var LabelDif: Longint);
+            Var LabelDif: Longint; BlockStart, BlockEnd: Pai);
 {Builds a table with the locations of the labels in the paasmoutput.
 {Builds a table with the locations of the labels in the paasmoutput.
  Also fixes some RegDeallocs like "# %eax released; push (%eax)"}
  Also fixes some RegDeallocs like "# %eax released; push (%eax)"}
 Var p, hp1, hp2: Pai;
 Var p, hp1, hp2: Pai;
@@ -688,8 +692,8 @@ Begin
 {$EndIf TP}
 {$EndIf TP}
             GetMem(LabelTable, LabelDif*SizeOf(TLabelTableItem));
             GetMem(LabelTable, LabelDif*SizeOf(TLabelTableItem));
             FillChar(LabelTable^, LabelDif*SizeOf(TLabelTableItem), 0);
             FillChar(LabelTable^, LabelDif*SizeOf(TLabelTableItem), 0);
-            p := pai(AsmL^.first);
-            While Assigned(p) Do
+            p := BlockStart;
+            While (P <> BlockEnd) Do
               Begin
               Begin
                 Case p^.typ Of
                 Case p^.typ Of
                   ait_Label:
                   ait_Label:
@@ -1048,12 +1052,13 @@ Begin
        (Pai_Marker(Current)^.Kind = NoPropInfoStart) Then
        (Pai_Marker(Current)^.Kind = NoPropInfoStart) Then
       Begin
       Begin
         While Assigned(Current) And
         While Assigned(Current) And
-              Not((Current^.typ = ait_Marker) And
-                  (Pai_Marker(Current)^.Kind = NoPropInfoEnd)) Do
-          Current := Pai(Current^.Next)
+              ((Current^.typ <> ait_Marker) Or
+               (Pai_Marker(Current)^.Kind <> NoPropInfoEnd)) Do
+          Current := Pai(Current^.Next);
       End;
       End;
   Until Not(Assigned(Current)) Or
   Until Not(Assigned(Current)) Or
-        (Current^.typ <> ait_Marker);
+        (Current^.typ <> ait_Marker) Or
+        (Pai_Marker(Current)^.Kind <> NoPropInfoEnd);
   Next := Current;
   Next := Current;
   If Assigned(Current) And
   If Assigned(Current) And
      Not((Current^.typ In SkipInstr) or
      Not((Current^.typ In SkipInstr) or
@@ -1083,12 +1088,13 @@ Begin
        (Pai_Marker(Current)^.Kind = NoPropInfoEnd) Then
        (Pai_Marker(Current)^.Kind = NoPropInfoEnd) Then
       Begin
       Begin
         While Assigned(Current) And
         While Assigned(Current) And
-              Not((Current^.typ = ait_Marker) And
-                  (Pai_Marker(Current)^.Kind = NoPropInfoStart)) Do
+              ((Current^.typ <> ait_Marker) Or
+               (Pai_Marker(Current)^.Kind <> NoPropInfoStart)) Do
           Current := Pai(Current^.previous);
           Current := Pai(Current^.previous);
       End;
       End;
   Until Not(Assigned(Current)) Or
   Until Not(Assigned(Current)) Or
-        (Current^.typ <> ait_Marker);
+        (Current^.typ <> ait_Marker) Or
+        (Pai_Marker(Current)^.Kind <> NoPropInfoStart);
  Last := Current;
  Last := Current;
   If Assigned(Current) And
   If Assigned(Current) And
      Not((Current^.typ In SkipInstr) or
      Not((Current^.typ In SkipInstr) or
@@ -1102,6 +1108,28 @@ Begin
       End;
       End;
 End;
 End;
 
 
+Procedure SkipHead(var P: Pai);
+Var OldP: Pai;
+Begin
+  Repeat
+    OldP := P;
+    If (P^.typ in SkipInstr) Then
+      GetNextInstruction(P, P)
+    Else If ((P^.Typ = Ait_Marker) And
+        (Pai_Marker(P)^.Kind = NoPropInfoStart)) Then
+   {a marker of the NoPropInfoStart can4t be the first instruction of a
+    paasmoutput list}
+      GetNextInstruction(Pai(P^.Previous),P);
+    If (P^.Typ = Ait_Marker) And
+       (Pai_Marker(P)^.Kind = AsmBlockStart) Then
+      Begin
+        P := Pai(P^.Next);
+        While (P^.typ <> Ait_Marker) Or
+              (Pai_Marker(P)^.Kind <> AsmBlockEnd) Do
+          P := Pai(P^.Next)
+      End;
+    Until P = OldP
+End;
 {******************* The Data Flow Analyzer functions ********************}
 {******************* The Data Flow Analyzer functions ********************}
 
 
 Procedure UpdateUsedRegs(Var UsedRegs: TRegSet; p: Pai);
 Procedure UpdateUsedRegs(Var UsedRegs: TRegSet; p: Pai);
@@ -1561,18 +1589,21 @@ Begin
   End;
   End;
 End;
 End;
 
 
-Procedure DFAPass1(AsmL: PAasmOutput);
-{gathers the RegAlloc data... still need to think about where to store it}
+Function DFAPass1(AsmL: PAasmOutput; BlockStart: Pai): Pai;
+{gathers the RegAlloc data... still need to think about where to store it to
+ avoid global vars}
+Var BlockEnd: Pai;
 Begin
 Begin
-  FindLoHiLabels(AsmL, LoLab, HiLab, LabDif);
-  BuildLabelTableAndFixRegAlloc(AsmL, LTable, LoLab, LabDif);
+  BlockEnd := FindLoHiLabels(AsmL, LoLab, HiLab, LabDif, BlockStart);
+  BuildLabelTableAndFixRegAlloc(AsmL, LTable, LoLab, LabDif, BlockStart, BlockEnd);
+  DFAPass1 := BlockEnd;
 End;
 End;
 
 
-Function DoDFAPass2(
+Procedure DoDFAPass2(
 {$Ifdef StateDebug}
 {$Ifdef StateDebug}
 AsmL: PAasmOutput;
 AsmL: PAasmOutput;
 {$endif statedebug}
 {$endif statedebug}
-First: Pai): Pai;
+BlockStart, BlockEnd: Pai);
 {Analyzes the Data Flow of an assembler list. Starts creating the reg
 {Analyzes the Data Flow of an assembler list. Starts creating the reg
  contents for the instructions starting with p. Returns the last pai which has
  contents for the instructions starting with p. Returns the last pai which has
  been processed}
  been processed}
@@ -1588,23 +1619,22 @@ Var
     TmpRef: TReference;
     TmpRef: TReference;
     TmpReg: TRegister;
     TmpReg: TRegister;
 Begin
 Begin
-  p := First;
+  p := BlockStart;
   UsedRegs := [];
   UsedRegs := [];
   UpdateUsedregs(UsedRegs, p);
   UpdateUsedregs(UsedRegs, p);
-  If (First^.typ in SkipInstr) Then
+  If (BlockStart^.typ in SkipInstr) Then
     GetNextInstruction(p, p);
     GetNextInstruction(p, p);
-  First := p;
+  BlockStart := p;
   InstrCnt := 1;
   InstrCnt := 1;
   FillChar(NrOfInstrSinceLastMod, SizeOf(NrOfInstrSinceLastMod), 0);
   FillChar(NrOfInstrSinceLastMod, SizeOf(NrOfInstrSinceLastMod), 0);
-  While Assigned(p) Do
+  While (P <> BlockEnd) Do
     Begin
     Begin
-      DoDFAPass2 := p;
 {$IfDef TP}
 {$IfDef TP}
       New(CurProp);
       New(CurProp);
 {$Else TP}
 {$Else TP}
       CurProp := @PaiPropBlock^[InstrCnt];
       CurProp := @PaiPropBlock^[InstrCnt];
 {$EndIf TP}
 {$EndIf TP}
-      If (p <> First)
+      If (p <> BlockStart)
         Then
         Then
           Begin
           Begin
 {$ifdef JumpAnal}
 {$ifdef JumpAnal}
@@ -2002,7 +2032,7 @@ Begin
     End;
     End;
 End;
 End;
 
 
-Function InitDFAPass2(AsmL: PAasmOutput): Boolean;
+Function InitDFAPass2(AsmL: PAasmOutput; BlockStart, BlockEnd: Pai): Boolean;
 {reserves memory for the PPaiProps in one big memory block when not using
 {reserves memory for the PPaiProps in one big memory block when not using
  TP, returns False if not enough memory is available for the optimizer in all
  TP, returns False if not enough memory is available for the optimizer in all
  cases}
  cases}
@@ -2010,11 +2040,10 @@ Var p: Pai;
     Count: Longint;
     Count: Longint;
 {    TmpStr: String; }
 {    TmpStr: String; }
 Begin
 Begin
-  P := Pai(AsmL^.First);
-  If (p^.typ in SkipInstr) Then
-    GetNextInstruction(p, p);
+  P := BlockStart;
+  SkipHead(P);
   NrOfPaiObjs := 0;
   NrOfPaiObjs := 0;
-  While Assigned(P) Do
+  While (P <> BlockEnd) Do
     Begin
     Begin
 {$IfDef JumpAnal}
 {$IfDef JumpAnal}
       Case P^.Typ Of
       Case P^.Typ Of
@@ -2056,9 +2085,8 @@ Begin
     Begin
     Begin
       InitDFAPass2 := True;
       InitDFAPass2 := True;
       GetMem(PaiPropBlock, NrOfPaiObjs*(((SizeOf(TPaiProp)+3)div 4)*4));
       GetMem(PaiPropBlock, NrOfPaiObjs*(((SizeOf(TPaiProp)+3)div 4)*4));
-      p := Pai(AsmL^.First);
-      If (p^.typ in SkipInstr) Then
-        GetNextInstruction(p, p);
+      p := BlockStart;
+      SkipHead(p);
       For Count := 1 To NrOfPaiObjs Do
       For Count := 1 To NrOfPaiObjs Do
         Begin
         Begin
           PaiPropBlock^[Count].LineSave := p^.fileinfo.line;
           PaiPropBlock^[Count].LineSave := p^.fileinfo.line;
@@ -2070,15 +2098,18 @@ Begin
  {$EndIf TP}
  {$EndIf TP}
 End;
 End;
 
 
-Function DFAPass2(AsmL: PAasmOutPut): Pai;
+Function DFAPass2(AsmL: PAasmOutPut; BlockStart, BlockEnd: Pai): Boolean;
 Begin
 Begin
-  If InitDFAPass2(AsmL)
-    Then DFAPass2 := DoDFAPass2(
+  If InitDFAPass2(AsmL, BlockStart, BlockEnd) Then
+    Begin
+      DoDFAPass2(
 {$ifdef statedebug}
 {$ifdef statedebug}
- asml,
+         asml,
 {$endif statedebug}
 {$endif statedebug}
-    Pai(AsmL^.First))
-    Else DFAPass2 := Nil;
+         BlockStart, BlockEnd);
+      DFAPass2 := True
+    End
+  Else DFAPass2 := False;
 End;
 End;
 
 
 Procedure ShutDownDFA;
 Procedure ShutDownDFA;
@@ -2091,7 +2122,10 @@ End.
 
 
 {
 {
  $Log$
  $Log$
- Revision 1.33  1998-12-17 16:37:38  jonas
+ Revision 1.34  1998-12-29 18:48:19  jonas
+   + optimize pascal code surrounding assembler blocks
+
+ Revision 1.33  1998/12/17 16:37:38  jonas
    + extra checks in RegsEquivalent so some more optimizations can be done (which
    + extra checks in RegsEquivalent so some more optimizations can be done (which
      where disabled by the second fix from revision 1.22)
      where disabled by the second fix from revision 1.22)
 
 

+ 6 - 2
compiler/hcodegen.pas

@@ -42,7 +42,8 @@ unit hcodegen;
        pi_C_import  = $10;      { set, if the procedure is an external C function }
        pi_C_import  = $10;      { set, if the procedure is an external C function }
        pi_uses_exceptions = $20;{ set, if the procedure has a try statement => }
        pi_uses_exceptions = $20;{ set, if the procedure has a try statement => }
                                 { no register variables                        }
                                 { no register variables                        }
-
+       pi_is_assembler = $40;   { set if the procedure is declared as ASSEMBLER
+                                  => don't optimize}
     type
     type
        pprocinfo = ^tprocinfo;
        pprocinfo = ^tprocinfo;
        tprocinfo = record
        tprocinfo = record
@@ -354,7 +355,10 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.23  1998-11-27 14:50:38  peter
+  Revision 1.24  1998-12-29 18:48:18  jonas
+    + optimize pascal code surrounding assembler blocks
+
+  Revision 1.23  1998/11/27 14:50:38  peter
     + open strings, $P switch support
     + open strings, $P switch support
 
 
   Revision 1.22  1998/11/16 12:12:21  peter
   Revision 1.22  1998/11/16 12:12:21  peter

+ 13 - 10
compiler/popt386.pas

@@ -26,8 +26,8 @@ Interface
 
 
 Uses Aasm;
 Uses Aasm;
 
 
-Procedure PeepHoleOptPass1(AsmL: PAasmOutput);
-Procedure PeepHoleOptPass2(AsmL: PAasmOutput);
+Procedure PeepHoleOptPass1(AsmL: PAasmOutput; BlockStart, BlockEnd: Pai);
+Procedure PeepHoleOptPass2(AsmL: PAasmOutput; BlockStart, BlockEnd: Pai);
 
 
 Implementation
 Implementation
 
 
@@ -42,7 +42,7 @@ Begin
   RegUsedAfterInstruction := Reg in UsedRegs
   RegUsedAfterInstruction := Reg in UsedRegs
 End;
 End;
 
 
-Procedure PeepHoleOptPass1(Asml: PAasmOutput);
+Procedure PeepHoleOptPass1(Asml: PAasmOutput; BlockStart, BlockEnd: Pai);
 {First pass of peepholeoptimizations}
 {First pass of peepholeoptimizations}
 
 
 Var
 Var
@@ -79,7 +79,7 @@ Var
 
 
   Begin
   Begin
     If (hp^.lab^.nb >= LoLab) and
     If (hp^.lab^.nb >= LoLab) and
-       (hp^.lab^.nb <= HiLab) and   {range check, necessary?}
+       (hp^.lab^.nb <= HiLab) and   {range check, a jump can go past an assembler block!}
        Assigned(LTable^[hp^.lab^.nb-LoLab].PaiObj) Then
        Assigned(LTable^[hp^.lab^.nb-LoLab].PaiObj) Then
       Begin
       Begin
         p1 := LTable^[hp^.lab^.nb-LoLab].PaiObj; {the jump's destination}
         p1 := LTable^[hp^.lab^.nb-LoLab].PaiObj; {the jump's destination}
@@ -100,9 +100,9 @@ Var
   End;
   End;
 
 
 Begin
 Begin
-  P := Pai(AsmL^.First);
+  P := BlockStart;
   UsedRegs := [];
   UsedRegs := [];
-  While Assigned(P) Do
+  While (P <> BlockEnd) Do
     Begin
     Begin
       UpDateUsedRegs(UsedRegs, Pai(p^.next));
       UpDateUsedRegs(UsedRegs, Pai(p^.next));
       Case P^.Typ Of
       Case P^.Typ Of
@@ -1476,13 +1476,13 @@ Begin
     end;
     end;
 end;
 end;
 
 
-Procedure PeepHoleOptPass2(AsmL: PAasmOutput);
+Procedure PeepHoleOptPass2(AsmL: PAasmOutput; BlockStart, BlockEnd: Pai);
 
 
 var
 var
   p,hp1,hp2: pai;
   p,hp1,hp2: pai;
 Begin
 Begin
-  P := Pai(AsmL^.First);
-  While Assigned(p) Do
+  P := BlockStart;
+  While (P <> BlockEnd) Do
     Begin
     Begin
       Case P^.Typ Of
       Case P^.Typ Of
         Ait_Instruction:
         Ait_Instruction:
@@ -1590,7 +1590,10 @@ End.
 
 
 {
 {
  $Log$
  $Log$
- Revision 1.33  1998-12-23 15:16:21  jonas
+ Revision 1.34  1998-12-29 18:48:17  jonas
+   + optimize pascal code surrounding assembler blocks
+
+ Revision 1.33  1998/12/23 15:16:21  jonas
    * change "inc x/dec x; test x, x"  to "add 1, x/sub 1,x" because inc and dec
    * change "inc x/dec x; test x, x"  to "add 1, x/sub 1,x" because inc and dec
      don't affect the carry flag (test does). This *doesn't* fix the problem with
      don't affect the carry flag (test does). This *doesn't* fix the problem with
     cardinal, that's a cg issue.
     cardinal, that's a cg issue.

+ 16 - 1
compiler/pstatmnt.pas

@@ -680,6 +680,7 @@ unit pstatmnt;
     function _asm_statement : ptree;
     function _asm_statement : ptree;
       var
       var
         asmstat : ptree;
         asmstat : ptree;
+        Marker : Pai;
       begin
       begin
          if (aktprocsym^.definition^.options and poinline)<>0 then
          if (aktprocsym^.definition^.options and poinline)<>0 then
            Begin
            Begin
@@ -762,6 +763,16 @@ unit pstatmnt;
               consume(RECKKLAMMER);
               consume(RECKKLAMMER);
            end
            end
          else usedinproc:=$ff;
          else usedinproc:=$ff;
+
+{ mark the start and the end of the assembler block for the optimizer }
+
+         If Assigned(AsmStat^.p_asm) Then
+           Begin
+             Marker := New(Pai_Marker, Init(AsmBlockStart));
+             AsmStat^.p_asm^.Insert(Marker);
+             Marker := New(Pai_Marker, Init(AsmBlockEnd));
+             AsmStat^.p_asm^.Concat(Marker);
+           End;
          _asm_statement:=asmstat;
          _asm_statement:=asmstat;
       end;
       end;
 
 
@@ -1236,6 +1247,7 @@ unit pstatmnt;
           { force the asm statement }
           { force the asm statement }
             if token<>_ASM then
             if token<>_ASM then
              consume(_ASM);
              consume(_ASM);
+            Procinfo.Flags := ProcInfo.Flags Or pi_is_assembler;
             assembler_block:=_asm_statement;
             assembler_block:=_asm_statement;
           { becuase the END is already read we need to get the
           { becuase the END is already read we need to get the
             last_endtoken_filepos here (PFV) }
             last_endtoken_filepos here (PFV) }
@@ -1245,7 +1257,10 @@ unit pstatmnt;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.56  1998-12-23 22:52:56  peter
+  Revision 1.57  1998-12-29 18:48:15  jonas
+    + optimize pascal code surrounding assembler blocks
+
+  Revision 1.56  1998/12/23 22:52:56  peter
     * fixed new(x) crash if x contains an error
     * fixed new(x) crash if x contains an error
 
 
   Revision 1.55  1998/12/16 12:30:59  jonas
   Revision 1.55  1998/12/16 12:30:59  jonas