View Issue Details

IDProjectCategoryView StatusLast Update
0036353FPCCompilerpublic2019-11-26 23:10
ReporterJ. Gareth MoretonAssigned ToFlorian 
PrioritylowSeverityminorReproducibilityN/A
Status resolvedResolutionfixed 
PlatformCross-platformOSMicrosoft WindowsOS Version10 Professional
Product Version3.3.1Product Buildr43582 
Target VersionFixed in Version3.3.1 
Summary0036353: [Refactor] Peephole Semantics
DescriptionThis patch, mentioned briefly in the core mailing list, seeks to improve maintainability, safety and efficiency in the peephole optimizer by slightly modifying some function headers based on their intended purpose. See "Additional Information" for a complete list.

Code generatd by the compiler should be completely identical.
Steps To ReproduceApply patch and confirm correct compilation on all platforms.
Additional Information- Non-virtual methods and class methods that don't need to access any fields from the current object are now static methods, thus removing the hidden "Self" parameter and reducing overhead. This includes a large number of frequently-used functions such as SkipEntryExitMarker and SuperRegistersEqual.

- GetNextInstruction, GetLastInstruction, SkipEntryExitMarker and SkipLabels have had their 'var' parameter changed to an 'out' parameter because they shouldn't depend on its input value. This will cause the compiler to throw warnings if you start using the value without initialising it first, and may open up optimisation opportunities in the future (e.g. storing written values in a temporary register and only writing it to the actual variable when the routine exits).
Tagscompiler, optimizations, patch, refactor
Fixed in Revision43595
FPCOldBugId
FPCTarget-
Attached Files
  • peephole_semantics.patch (13,766 bytes)
    Index: compiler/aoptbase.pas
    ===================================================================
    --- compiler/aoptbase.pas	(revision 43561)
    +++ compiler/aoptbase.pas	(working copy)
    @@ -49,9 +49,9 @@
             { returns true if register Reg is used by instruction p1 }
             Function RegInInstruction(Reg: TRegister; p1: tai): Boolean;virtual;
             { returns true if register Reg occurs in operand op }
    -        Function RegInOp(Reg: TRegister; const op: toper): Boolean;
    +        class function RegInOp(Reg: TRegister; const op: toper): Boolean; static;
             { returns true if register Reg is used in the reference Ref }
    -        Function RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
    +        class function RegInRef(Reg: TRegister; Const Ref: TReference): Boolean; static;
     
             function RegModifiedByInstruction(Reg: TRegister; p1: tai): boolean;virtual;
     
    @@ -61,13 +61,13 @@
             { gets the next tai object after current that contains info relevant }
             { to the optimizer in p1. If there is none, it returns false and     }
             { sets p1 to nil                                                     }
    -        class Function GetNextInstruction(Current: tai; Var Next: tai): Boolean;
    -        { gets the previous tai object after current that contains info  }
    -        { relevant to the optimizer in last. If there is none, it retuns }
    -        { false and sets last to nil                                     }
    -        Function GetLastInstruction(Current: tai; Var Last: tai): Boolean;
    +        class function GetNextInstruction(Current: tai; out Next: tai): Boolean; static;
    +        { gets the previous tai object after current that contains info   }
    +        { relevant to the optimizer in last. If there is none, it returns }
    +        { false and sets last to nil                                      }
    +        class function GetLastInstruction(Current: tai; out Last: tai): Boolean; static;
     
    -        function SkipEntryExitMarker(current: tai; var next: tai): boolean;
    +        class function SkipEntryExitMarker(current: tai; out next: tai): boolean; static;
     
             { processor dependent methods }
     
    @@ -104,10 +104,10 @@
     
             { compares reg1 and reg2 having the same type and being the same super registers
               so the register size is neglected }
    -        function SuperRegistersEqual(reg1,reg2 : TRegister) : Boolean;{$ifdef USEINLINE}inline;{$endif}
    +        class function SuperRegistersEqual(reg1,reg2 : TRegister) : Boolean; static; {$ifdef USEINLINE}inline;{$endif}
         end;
     
    -    function labelCanBeSkipped(p: tai_label): boolean;
    +    function labelCanBeSkipped(p: tai_label): boolean; {$ifdef USEINLINE}inline;{$endif}
     
       implementation
     
    @@ -140,7 +140,7 @@
         End;
     
     
    -  Function TAOptBase.RegInOp(Reg: TRegister; const op: toper): Boolean;
    +  class function TAOptBase.RegInOp(Reg: TRegister; const op: toper): Boolean;
         Begin
           Case op.typ Of
             Top_Reg: RegInOp := SuperRegistersEqual(Reg,op.reg);
    @@ -154,7 +154,7 @@
         End;
     
     
    -  Function TAOptBase.RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
    +  class function TAOptBase.RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
       Begin
         RegInRef := SuperRegistersEqual(Ref.Base,Reg)
     {$ifdef cpurefshaveindexreg}
    @@ -176,13 +176,13 @@
       End;
     
     
    -  function labelCanBeSkipped(p: tai_label): boolean; inline;
    +  function labelCanBeSkipped(p: tai_label): boolean; {$ifdef USEINLINE}inline;{$endif}
       begin
         labelCanBeSkipped := not(p.labsym.is_used) or (p.labsym.labeltype<>alt_jump);
       end;
     
     
    -  class Function TAOptBase.GetNextInstruction(Current: tai; Var Next: tai): Boolean;
    +  class function TAOptBase.GetNextInstruction(Current: tai; out Next: tai): Boolean;
       Begin
         Repeat
           Current := tai(Current.Next);
    @@ -221,7 +221,7 @@
             End;
       End;
     
    -  Function TAOptBase.GetLastInstruction(Current: tai; Var Last: tai): Boolean;
    +  class function TAOptBase.GetLastInstruction(Current: tai; out Last: tai): Boolean;
       Begin
         Repeat
           Current := Tai(Current.previous);
    @@ -263,7 +263,7 @@
       End;
     
     
    -  function TAOptBase.SkipEntryExitMarker(current: tai; var next: tai): boolean;
    +  class function TAOptBase.SkipEntryExitMarker(current: tai; out next: tai): boolean;
         begin
           result:=true;
           if current.typ<>ait_marker then
    @@ -316,7 +316,7 @@
         end;
     
     
    -  function TAOptBase.SuperRegistersEqual(reg1,reg2 : TRegister) : Boolean;{$ifdef USEINLINE}inline;{$endif}
    +  class function TAOptBase.SuperRegistersEqual(reg1,reg2 : TRegister) : Boolean;{$ifdef USEINLINE}inline;{$endif}
       Begin
         { Do an optimized version of
     
    Index: compiler/aoptobj.pas
    ===================================================================
    --- compiler/aoptobj.pas	(revision 43561)
    +++ compiler/aoptobj.pas	(working copy)
    @@ -201,13 +201,13 @@
     
             { returns whether the reference Ref is used somewhere in the loading }
             { sequence Content                                                   }
    -        Function RefInSequence(Const Ref: TReference; Content: TContent;
    -          RefsEq: TRefCompare): Boolean;
    +        class function RefInSequence(Const Ref: TReference; Content: TContent;
    +          RefsEq: TRefCompare): Boolean; static;
     
             { returns whether the instruction P reads from and/or writes }
             { to Reg                                                     }
    -        Function RefInInstruction(Const Ref: TReference; p: Tai;
    -          RefsEq: TRefCompare): Boolean;
    +        class function RefInInstruction(Const Ref: TReference; p: Tai;
    +          RefsEq: TRefCompare): Boolean; static;
     
             { returns whether two references with at least one pointing to an array }
             { may point to the same memory location                                 }
    @@ -272,7 +272,7 @@
             Procedure CreateUsedRegs(var regs: TAllUsedRegs);
             Procedure ClearUsedRegs;
             Procedure UpdateUsedRegs(p : Tai);
    -        class procedure UpdateUsedRegs(var Regs: TAllUsedRegs; p: Tai);
    +        class procedure UpdateUsedRegs(var Regs: TAllUsedRegs; p: Tai); static;
     
             { If UpdateUsedRegsAndOptimize has read ahead, the result is one before
               the next valid entry (so "p.Next" returns what's expected).  If no
    @@ -282,16 +282,16 @@
             Function CopyUsedRegs(var dest : TAllUsedRegs) : boolean;
             procedure RestoreUsedRegs(const Regs : TAllUsedRegs);
             procedure TransferUsedRegs(var dest: TAllUsedRegs);
    -        class Procedure ReleaseUsedRegs(const regs : TAllUsedRegs);
    -        class Function RegInUsedRegs(reg : TRegister;regs : TAllUsedRegs) : boolean;
    -        class Procedure IncludeRegInUsedRegs(reg : TRegister;var regs : TAllUsedRegs);
    -        class Procedure ExcludeRegFromUsedRegs(reg: TRegister;var regs : TAllUsedRegs);
    +        class procedure ReleaseUsedRegs(const regs : TAllUsedRegs); static;
    +        class function RegInUsedRegs(reg : TRegister;regs : TAllUsedRegs) : boolean; static;
    +        class procedure IncludeRegInUsedRegs(reg : TRegister;var regs : TAllUsedRegs); static;
    +        class procedure ExcludeRegFromUsedRegs(reg: TRegister;var regs : TAllUsedRegs); static;
     
    -        Function GetAllocationString(const regs : TAllUsedRegs) : string;
    +        class function GetAllocationString(const regs : TAllUsedRegs) : string; static;
     
             { returns true if the label L is found between hp and the next }
             { instruction                                                  }
    -        Function FindLabel(L: TasmLabel; Var hp: Tai): Boolean;
    +        class function FindLabel(L: TasmLabel; Var hp: Tai): Boolean; static;
     
             { inserts new_one between prev and foll in AsmL }
             Procedure InsertLLItem(prev, foll, new_one: TLinkedListItem);
    @@ -299,10 +299,10 @@
             { If P is a Tai object releveant to the optimizer, P is returned
               If it is not relevant tot he optimizer, the first object after P
               that is relevant is returned                                     }
    -        Function SkipHead(P: Tai): Tai;
    +        class function SkipHead(P: Tai): Tai; static;
     
             { returns true if the operands o1 and o2 are completely equal }
    -        Function OpsEqual(const o1,o2:toper): Boolean;
    +        class function OpsEqual(const o1,o2:toper): Boolean; static;
     
             { Returns the next ait_alloc object with ratype ra_alloc for
               Reg is found in the block
    @@ -310,7 +310,7 @@
               instruction. If none is found, it returns
               nil
             }
    -        Function FindRegAlloc(Reg: TRegister; StartPai: Tai): tai_regalloc;
    +        class function FindRegAlloc(Reg: TRegister; StartPai: Tai): tai_regalloc; static;
     
             { Returns the last ait_alloc object with ratype ra_alloc for
               Reg is found in the block
    @@ -318,7 +318,7 @@
               instruction. If none is found, it returns
               nil
             }
    -        Function FindRegAllocBackward(Reg : TRegister; StartPai : Tai) : tai_regalloc;
    +        class function FindRegAllocBackward(Reg : TRegister; StartPai : Tai) : tai_regalloc; static;
     
     
             { Returns the next ait_alloc object with ratype ra_dealloc
    @@ -325,7 +325,7 @@
               for Reg which is found in the block of Tai's starting with StartPai
               and ending with the next "real" instruction. If none is found, it returns
               nil                                                                        }
    -        Function FindRegDeAlloc(Reg: TRegister; StartPai: Tai): tai_regalloc;
    +        class function FindRegDeAlloc(Reg: TRegister; StartPai: Tai): tai_regalloc; static;
     
             { allocates register reg between (and including) instructions p1 and p2
               the type of p1 and p2 must not be in SkipInstr }
    @@ -890,7 +890,7 @@
             Else s := 0
           End;
     
    -      Function TPaiProp.RefInInstruction(Const Ref: TReference; p: Tai;
    +      class Function TPaiProp.RefInInstruction(Const Ref: TReference; p: Tai;
             RefsEq: TRefCompare): Boolean;
           Var Count: AWord;
               TmpResult: Boolean;
    @@ -908,7 +908,7 @@
             RefInInstruction := TmpResult;
           End;
     
    -      Function TPaiProp.RefInSequence(Const Ref: TReference; Content: TContent;
    +      class function TPaiProp.RefInSequence(Const Ref: TReference; Content: TContent;
             RefsEq: TRefCompare): Boolean;
           Var p: Tai;
               Counter: Byte;
    @@ -1161,7 +1161,7 @@
           end;
     
     
    -      function TAOptObj.GetAllocationString(const regs: TAllUsedRegs): string;
    +      class function TAOptObj.GetAllocationString(const regs: TAllUsedRegs): string;
           var
             i : TRegisterType;
             j : TSuperRegister;
    @@ -1173,7 +1173,7 @@
           end;
     
     
    -      Function TAOptObj.FindLabel(L: TasmLabel; Var hp: Tai): Boolean;
    +      class function TAOptObj.FindLabel(L: TasmLabel; Var hp: Tai): Boolean;
           Var TempP: Tai;
           Begin
             TempP := hp;
    @@ -1213,7 +1213,7 @@
           End;
     
     
    -      Function TAOptObj.SkipHead(P: Tai): Tai;
    +      class function TAOptObj.SkipHead(P: Tai): Tai;
           Var OldP: Tai;
           Begin
             Repeat
    @@ -1239,7 +1239,7 @@
             SkipHead := P;
           End;
     
    -      Function TAOptObj.OpsEqual(const o1,o2:toper): Boolean;
    +      class function TAOptObj.OpsEqual(const o1,o2:toper): Boolean;
           Begin
             if o1.typ=o2.typ then
               Case o1.typ Of
    @@ -1261,7 +1261,7 @@
           End;
     
     
    -      Function TAOptObj.FindRegAlloc(Reg: TRegister; StartPai: Tai): tai_regalloc;
    +      class function TAOptObj.FindRegAlloc(Reg: TRegister; StartPai: Tai): tai_regalloc;
           Begin
             Result:=nil;
             Repeat
    @@ -1291,7 +1291,7 @@
           End;
     
     
    -      Function TAOptObj.FindRegAllocBackward(Reg: TRegister; StartPai: Tai): tai_regalloc;
    +      class function TAOptObj.FindRegAllocBackward(Reg: TRegister; StartPai: Tai): tai_regalloc;
           Begin
             Result:=nil;
             Repeat
    @@ -1317,7 +1317,7 @@
           End;
     
     
    -      function TAOptObj.FindRegDeAlloc(Reg: TRegister; StartPai: Tai): tai_regalloc;
    +      class function TAOptObj.FindRegDeAlloc(Reg: TRegister; StartPai: Tai): tai_regalloc;
           Begin
              Result:=nil;
              Repeat
    Index: compiler/aoptutils.pas
    ===================================================================
    --- compiler/aoptutils.pas	(revision 43561)
    +++ compiler/aoptutils.pas	(working copy)
    @@ -36,7 +36,7 @@
     {$endif max_operands>2}
     
         { skips all labels and returns the next "real" instruction }
    -    function SkipLabels(hp: tai; var hp2: tai): boolean;
    +    function SkipLabels(hp: tai; out hp2: tai): boolean;
     
         { sets hp2 to hp and returns True if hp is not nil }
         function SetAndTest(const hp: tai; out hp2: tai): Boolean;
    @@ -68,7 +68,7 @@
     
     
         { skips all labels and returns the next "real" instruction }
    -    function SkipLabels(hp: tai; var hp2: tai): boolean;
    +    function SkipLabels(hp: tai; out hp2: tai): boolean;
           begin
             while assigned(hp.next) and
                   (tai(hp.next).typ in SkipInstr + [ait_label,ait_align]) Do
    Index: compiler/x86/aoptx86.pas
    ===================================================================
    --- compiler/x86/aoptx86.pas	(revision 43561)
    +++ compiler/x86/aoptx86.pas	(working copy)
    @@ -52,8 +52,8 @@
     
             procedure DebugMsg(const s : string; p : tai);inline;
     
    -        class function IsExitCode(p : tai) : boolean;
    -        class function isFoldableArithOp(hp1 : taicpu; reg : tregister) : boolean;
    +        class function IsExitCode(p : tai) : boolean; static;
    +        class function isFoldableArithOp(hp1 : taicpu; reg : tregister) : boolean; static;
             procedure RemoveLastDeallocForFuncRes(p : tai);
     
             function DoSubAddOpt(var p : tai) : Boolean;
    
    peephole_semantics.patch (13,766 bytes)

Activities

J. Gareth Moreton

2019-11-25 00:50

developer  

peephole_semantics.patch (13,766 bytes)
Index: compiler/aoptbase.pas
===================================================================
--- compiler/aoptbase.pas	(revision 43561)
+++ compiler/aoptbase.pas	(working copy)
@@ -49,9 +49,9 @@
         { returns true if register Reg is used by instruction p1 }
         Function RegInInstruction(Reg: TRegister; p1: tai): Boolean;virtual;
         { returns true if register Reg occurs in operand op }
-        Function RegInOp(Reg: TRegister; const op: toper): Boolean;
+        class function RegInOp(Reg: TRegister; const op: toper): Boolean; static;
         { returns true if register Reg is used in the reference Ref }
-        Function RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
+        class function RegInRef(Reg: TRegister; Const Ref: TReference): Boolean; static;
 
         function RegModifiedByInstruction(Reg: TRegister; p1: tai): boolean;virtual;
 
@@ -61,13 +61,13 @@
         { gets the next tai object after current that contains info relevant }
         { to the optimizer in p1. If there is none, it returns false and     }
         { sets p1 to nil                                                     }
-        class Function GetNextInstruction(Current: tai; Var Next: tai): Boolean;
-        { gets the previous tai object after current that contains info  }
-        { relevant to the optimizer in last. If there is none, it retuns }
-        { false and sets last to nil                                     }
-        Function GetLastInstruction(Current: tai; Var Last: tai): Boolean;
+        class function GetNextInstruction(Current: tai; out Next: tai): Boolean; static;
+        { gets the previous tai object after current that contains info   }
+        { relevant to the optimizer in last. If there is none, it returns }
+        { false and sets last to nil                                      }
+        class function GetLastInstruction(Current: tai; out Last: tai): Boolean; static;
 
-        function SkipEntryExitMarker(current: tai; var next: tai): boolean;
+        class function SkipEntryExitMarker(current: tai; out next: tai): boolean; static;
 
         { processor dependent methods }
 
@@ -104,10 +104,10 @@
 
         { compares reg1 and reg2 having the same type and being the same super registers
           so the register size is neglected }
-        function SuperRegistersEqual(reg1,reg2 : TRegister) : Boolean;{$ifdef USEINLINE}inline;{$endif}
+        class function SuperRegistersEqual(reg1,reg2 : TRegister) : Boolean; static; {$ifdef USEINLINE}inline;{$endif}
     end;
 
-    function labelCanBeSkipped(p: tai_label): boolean;
+    function labelCanBeSkipped(p: tai_label): boolean; {$ifdef USEINLINE}inline;{$endif}
 
   implementation
 
@@ -140,7 +140,7 @@
     End;
 
 
-  Function TAOptBase.RegInOp(Reg: TRegister; const op: toper): Boolean;
+  class function TAOptBase.RegInOp(Reg: TRegister; const op: toper): Boolean;
     Begin
       Case op.typ Of
         Top_Reg: RegInOp := SuperRegistersEqual(Reg,op.reg);
@@ -154,7 +154,7 @@
     End;
 
 
-  Function TAOptBase.RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
+  class function TAOptBase.RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
   Begin
     RegInRef := SuperRegistersEqual(Ref.Base,Reg)
 {$ifdef cpurefshaveindexreg}
@@ -176,13 +176,13 @@
   End;
 
 
-  function labelCanBeSkipped(p: tai_label): boolean; inline;
+  function labelCanBeSkipped(p: tai_label): boolean; {$ifdef USEINLINE}inline;{$endif}
   begin
     labelCanBeSkipped := not(p.labsym.is_used) or (p.labsym.labeltype<>alt_jump);
   end;
 
 
-  class Function TAOptBase.GetNextInstruction(Current: tai; Var Next: tai): Boolean;
+  class function TAOptBase.GetNextInstruction(Current: tai; out Next: tai): Boolean;
   Begin
     Repeat
       Current := tai(Current.Next);
@@ -221,7 +221,7 @@
         End;
   End;
 
-  Function TAOptBase.GetLastInstruction(Current: tai; Var Last: tai): Boolean;
+  class function TAOptBase.GetLastInstruction(Current: tai; out Last: tai): Boolean;
   Begin
     Repeat
       Current := Tai(Current.previous);
@@ -263,7 +263,7 @@
   End;
 
 
-  function TAOptBase.SkipEntryExitMarker(current: tai; var next: tai): boolean;
+  class function TAOptBase.SkipEntryExitMarker(current: tai; out next: tai): boolean;
     begin
       result:=true;
       if current.typ<>ait_marker then
@@ -316,7 +316,7 @@
     end;
 
 
-  function TAOptBase.SuperRegistersEqual(reg1,reg2 : TRegister) : Boolean;{$ifdef USEINLINE}inline;{$endif}
+  class function TAOptBase.SuperRegistersEqual(reg1,reg2 : TRegister) : Boolean;{$ifdef USEINLINE}inline;{$endif}
   Begin
     { Do an optimized version of
 
Index: compiler/aoptobj.pas
===================================================================
--- compiler/aoptobj.pas	(revision 43561)
+++ compiler/aoptobj.pas	(working copy)
@@ -201,13 +201,13 @@
 
         { returns whether the reference Ref is used somewhere in the loading }
         { sequence Content                                                   }
-        Function RefInSequence(Const Ref: TReference; Content: TContent;
-          RefsEq: TRefCompare): Boolean;
+        class function RefInSequence(Const Ref: TReference; Content: TContent;
+          RefsEq: TRefCompare): Boolean; static;
 
         { returns whether the instruction P reads from and/or writes }
         { to Reg                                                     }
-        Function RefInInstruction(Const Ref: TReference; p: Tai;
-          RefsEq: TRefCompare): Boolean;
+        class function RefInInstruction(Const Ref: TReference; p: Tai;
+          RefsEq: TRefCompare): Boolean; static;
 
         { returns whether two references with at least one pointing to an array }
         { may point to the same memory location                                 }
@@ -272,7 +272,7 @@
         Procedure CreateUsedRegs(var regs: TAllUsedRegs);
         Procedure ClearUsedRegs;
         Procedure UpdateUsedRegs(p : Tai);
-        class procedure UpdateUsedRegs(var Regs: TAllUsedRegs; p: Tai);
+        class procedure UpdateUsedRegs(var Regs: TAllUsedRegs; p: Tai); static;
 
         { If UpdateUsedRegsAndOptimize has read ahead, the result is one before
           the next valid entry (so "p.Next" returns what's expected).  If no
@@ -282,16 +282,16 @@
         Function CopyUsedRegs(var dest : TAllUsedRegs) : boolean;
         procedure RestoreUsedRegs(const Regs : TAllUsedRegs);
         procedure TransferUsedRegs(var dest: TAllUsedRegs);
-        class Procedure ReleaseUsedRegs(const regs : TAllUsedRegs);
-        class Function RegInUsedRegs(reg : TRegister;regs : TAllUsedRegs) : boolean;
-        class Procedure IncludeRegInUsedRegs(reg : TRegister;var regs : TAllUsedRegs);
-        class Procedure ExcludeRegFromUsedRegs(reg: TRegister;var regs : TAllUsedRegs);
+        class procedure ReleaseUsedRegs(const regs : TAllUsedRegs); static;
+        class function RegInUsedRegs(reg : TRegister;regs : TAllUsedRegs) : boolean; static;
+        class procedure IncludeRegInUsedRegs(reg : TRegister;var regs : TAllUsedRegs); static;
+        class procedure ExcludeRegFromUsedRegs(reg: TRegister;var regs : TAllUsedRegs); static;
 
-        Function GetAllocationString(const regs : TAllUsedRegs) : string;
+        class function GetAllocationString(const regs : TAllUsedRegs) : string; static;
 
         { returns true if the label L is found between hp and the next }
         { instruction                                                  }
-        Function FindLabel(L: TasmLabel; Var hp: Tai): Boolean;
+        class function FindLabel(L: TasmLabel; Var hp: Tai): Boolean; static;
 
         { inserts new_one between prev and foll in AsmL }
         Procedure InsertLLItem(prev, foll, new_one: TLinkedListItem);
@@ -299,10 +299,10 @@
         { If P is a Tai object releveant to the optimizer, P is returned
           If it is not relevant tot he optimizer, the first object after P
           that is relevant is returned                                     }
-        Function SkipHead(P: Tai): Tai;
+        class function SkipHead(P: Tai): Tai; static;
 
         { returns true if the operands o1 and o2 are completely equal }
-        Function OpsEqual(const o1,o2:toper): Boolean;
+        class function OpsEqual(const o1,o2:toper): Boolean; static;
 
         { Returns the next ait_alloc object with ratype ra_alloc for
           Reg is found in the block
@@ -310,7 +310,7 @@
           instruction. If none is found, it returns
           nil
         }
-        Function FindRegAlloc(Reg: TRegister; StartPai: Tai): tai_regalloc;
+        class function FindRegAlloc(Reg: TRegister; StartPai: Tai): tai_regalloc; static;
 
         { Returns the last ait_alloc object with ratype ra_alloc for
           Reg is found in the block
@@ -318,7 +318,7 @@
           instruction. If none is found, it returns
           nil
         }
-        Function FindRegAllocBackward(Reg : TRegister; StartPai : Tai) : tai_regalloc;
+        class function FindRegAllocBackward(Reg : TRegister; StartPai : Tai) : tai_regalloc; static;
 
 
         { Returns the next ait_alloc object with ratype ra_dealloc
@@ -325,7 +325,7 @@
           for Reg which is found in the block of Tai's starting with StartPai
           and ending with the next "real" instruction. If none is found, it returns
           nil                                                                        }
-        Function FindRegDeAlloc(Reg: TRegister; StartPai: Tai): tai_regalloc;
+        class function FindRegDeAlloc(Reg: TRegister; StartPai: Tai): tai_regalloc; static;
 
         { allocates register reg between (and including) instructions p1 and p2
           the type of p1 and p2 must not be in SkipInstr }
@@ -890,7 +890,7 @@
         Else s := 0
       End;
 
-      Function TPaiProp.RefInInstruction(Const Ref: TReference; p: Tai;
+      class Function TPaiProp.RefInInstruction(Const Ref: TReference; p: Tai;
         RefsEq: TRefCompare): Boolean;
       Var Count: AWord;
           TmpResult: Boolean;
@@ -908,7 +908,7 @@
         RefInInstruction := TmpResult;
       End;
 
-      Function TPaiProp.RefInSequence(Const Ref: TReference; Content: TContent;
+      class function TPaiProp.RefInSequence(Const Ref: TReference; Content: TContent;
         RefsEq: TRefCompare): Boolean;
       Var p: Tai;
           Counter: Byte;
@@ -1161,7 +1161,7 @@
       end;
 
 
-      function TAOptObj.GetAllocationString(const regs: TAllUsedRegs): string;
+      class function TAOptObj.GetAllocationString(const regs: TAllUsedRegs): string;
       var
         i : TRegisterType;
         j : TSuperRegister;
@@ -1173,7 +1173,7 @@
       end;
 
 
-      Function TAOptObj.FindLabel(L: TasmLabel; Var hp: Tai): Boolean;
+      class function TAOptObj.FindLabel(L: TasmLabel; Var hp: Tai): Boolean;
       Var TempP: Tai;
       Begin
         TempP := hp;
@@ -1213,7 +1213,7 @@
       End;
 
 
-      Function TAOptObj.SkipHead(P: Tai): Tai;
+      class function TAOptObj.SkipHead(P: Tai): Tai;
       Var OldP: Tai;
       Begin
         Repeat
@@ -1239,7 +1239,7 @@
         SkipHead := P;
       End;
 
-      Function TAOptObj.OpsEqual(const o1,o2:toper): Boolean;
+      class function TAOptObj.OpsEqual(const o1,o2:toper): Boolean;
       Begin
         if o1.typ=o2.typ then
           Case o1.typ Of
@@ -1261,7 +1261,7 @@
       End;
 
 
-      Function TAOptObj.FindRegAlloc(Reg: TRegister; StartPai: Tai): tai_regalloc;
+      class function TAOptObj.FindRegAlloc(Reg: TRegister; StartPai: Tai): tai_regalloc;
       Begin
         Result:=nil;
         Repeat
@@ -1291,7 +1291,7 @@
       End;
 
 
-      Function TAOptObj.FindRegAllocBackward(Reg: TRegister; StartPai: Tai): tai_regalloc;
+      class function TAOptObj.FindRegAllocBackward(Reg: TRegister; StartPai: Tai): tai_regalloc;
       Begin
         Result:=nil;
         Repeat
@@ -1317,7 +1317,7 @@
       End;
 
 
-      function TAOptObj.FindRegDeAlloc(Reg: TRegister; StartPai: Tai): tai_regalloc;
+      class function TAOptObj.FindRegDeAlloc(Reg: TRegister; StartPai: Tai): tai_regalloc;
       Begin
          Result:=nil;
          Repeat
Index: compiler/aoptutils.pas
===================================================================
--- compiler/aoptutils.pas	(revision 43561)
+++ compiler/aoptutils.pas	(working copy)
@@ -36,7 +36,7 @@
 {$endif max_operands>2}
 
     { skips all labels and returns the next "real" instruction }
-    function SkipLabels(hp: tai; var hp2: tai): boolean;
+    function SkipLabels(hp: tai; out hp2: tai): boolean;
 
     { sets hp2 to hp and returns True if hp is not nil }
     function SetAndTest(const hp: tai; out hp2: tai): Boolean;
@@ -68,7 +68,7 @@
 
 
     { skips all labels and returns the next "real" instruction }
-    function SkipLabels(hp: tai; var hp2: tai): boolean;
+    function SkipLabels(hp: tai; out hp2: tai): boolean;
       begin
         while assigned(hp.next) and
               (tai(hp.next).typ in SkipInstr + [ait_label,ait_align]) Do
Index: compiler/x86/aoptx86.pas
===================================================================
--- compiler/x86/aoptx86.pas	(revision 43561)
+++ compiler/x86/aoptx86.pas	(working copy)
@@ -52,8 +52,8 @@
 
         procedure DebugMsg(const s : string; p : tai);inline;
 
-        class function IsExitCode(p : tai) : boolean;
-        class function isFoldableArithOp(hp1 : taicpu; reg : tregister) : boolean;
+        class function IsExitCode(p : tai) : boolean; static;
+        class function isFoldableArithOp(hp1 : taicpu; reg : tregister) : boolean; static;
         procedure RemoveLastDeallocForFuncRes(p : tai);
 
         function DoSubAddOpt(var p : tai) : Boolean;
peephole_semantics.patch (13,766 bytes)

Florian

2019-11-26 23:10

administrator   ~0119519

Thanks, applied.

Issue History

Date Modified Username Field Change
2019-11-25 00:50 J. Gareth Moreton New Issue
2019-11-25 00:50 J. Gareth Moreton File Added: peephole_semantics.patch
2019-11-25 00:51 J. Gareth Moreton Priority normal => low
2019-11-25 00:51 J. Gareth Moreton FPCTarget => -
2019-11-25 00:52 J. Gareth Moreton Description Updated View Revisions
2019-11-25 00:53 J. Gareth Moreton Description Updated View Revisions
2019-11-25 01:05 J. Gareth Moreton Tag Attached: patch
2019-11-25 01:05 J. Gareth Moreton Tag Attached: compiler
2019-11-25 01:05 J. Gareth Moreton Tag Attached: optimizations
2019-11-25 01:05 J. Gareth Moreton Tag Attached: refactor
2019-11-26 23:10 Florian Assigned To => Florian
2019-11-26 23:10 Florian Status new => resolved
2019-11-26 23:10 Florian Resolution open => fixed
2019-11-26 23:10 Florian Fixed in Version => 3.3.1
2019-11-26 23:10 Florian Fixed in Revision => 43595
2019-11-26 23:10 Florian Note Added: 0119519