[fpc-devel] Kit's ambitions!
Florian Klämpfl
florian at freepascal.org
Thu Jun 14 22:58:43 CEST 2018
Am 13.06.2018 um 20:50 schrieb J. Gareth Moreton:
> I haven't fully uncovered the secrets of
> the compiler yet, but I did notice "pre-
> peephole pass" under x86, but I think the
> only functions it touched was one of the
> bit shifts. Does this occur before
> register allocation or was it just
> something that had to be done before Pass
> 1?
It is only before pass 1.
I attached a patch I once started which shows the idea.
-------------- next part --------------
From 7c679b8365e7819f1c39e57c2c222b08bc935f72 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20Kl=C3=A4mpfl?= <florian at freepascal.org>
Date: Sat, 11 Jun 2016 13:15:55 +0200
Subject: [PATCH] unfinished: + new pass to carry out peep hole optimizations
before register allocation, this might reduce register pressure + x86:
optmize LeaMov2Mov
---
compiler/aopt.pas | 32 ++++++++++++++++++++++++++++----
compiler/aoptobj.pas | 25 +++++++++++++++++++++++++
compiler/psub.pas | 4 ++++
compiler/x86/aoptx86.pas | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 103 insertions(+), 5 deletions(-)
diff --git a/compiler/aopt.pas b/compiler/aopt.pas
index fde868713e..ad3590e1a1 100644
--- a/compiler/aopt.pas
+++ b/compiler/aopt.pas
@@ -39,9 +39,11 @@ Unit aopt;
{ _AsmL is the PAasmOutpout list that has to be optimized }
Constructor create(_AsmL: TAsmList); virtual; reintroduce;
+ Destructor destroy;override;
+
{ call the necessary optimizer procedures }
Procedure Optimize;virtual;
- Destructor destroy;override;
+ procedure PreRegallocOptimize;virtual;
private
procedure FindLoHiLabels;
@@ -68,6 +70,7 @@ Unit aopt;
casmoptimizer : TAsmOptimizerClass;
cpreregallocscheduler : TAsmSchedulerClass;
+ procedure PreRegallocOptimize(AsmL:TAsmList);
procedure Optimize(AsmL:TAsmList);
procedure PreRegallocSchedule(AsmL:TAsmList);
@@ -86,6 +89,7 @@ Unit aopt;
inherited create(_asml,nil,nil,nil);
{ setup labeltable, always necessary }
New(LabelInfo);
+ LabelInfo^.LabelTable:=nil;
End;
procedure TAsmOptimizer.FindLoHiLabels;
@@ -315,11 +319,21 @@ Unit aopt;
End;
+ Procedure TAsmOptimizer.PreRegallocOptimize;
+ begin
+ BlockStart := tai(AsmL.First);
+ PreRegAllocPeepHoleOptPass;
+ end;
+
+
Destructor TAsmOptimizer.Destroy;
Begin
- if assigned(LabelInfo^.LabelTable) then
- Freemem(LabelInfo^.LabelTable);
- Dispose(LabelInfo);
+ if assigned(LabelInfo) then
+ begin
+ if assigned(LabelInfo^.LabelTable) then
+ Freemem(LabelInfo^.LabelTable);
+ Dispose(LabelInfo);
+ end;
inherited Destroy;
End;
@@ -375,6 +389,16 @@ Unit aopt;
End;
+ procedure PreRegallocOptimize(AsmL:TAsmList);
+ var
+ p : TAsmOptimizer;
+ begin
+ p:=casmoptimizer.Create(AsmL);
+ p.PreRegallocOptimize;
+ p.free;
+ end;
+
+
procedure Optimize(AsmL:TAsmList);
var
p : TAsmOptimizer;
diff --git a/compiler/aoptobj.pas b/compiler/aoptobj.pas
index 02fc330167..985c03ec2b 100644
--- a/compiler/aoptobj.pas
+++ b/compiler/aoptobj.pas
@@ -344,12 +344,16 @@ Unit AoptObj;
procedure PeepHoleOptPass2; virtual;
procedure PostPeepHoleOpts; virtual;
+ procedure PreRegAllocPeepHoleOptPass; virtual;
+
{ processor dependent methods }
// if it returns true, perform a "continue"
function PrePeepHoleOptsCpu(var p: tai): boolean; virtual;
function PeepHoleOptPass1Cpu(var p: tai): boolean; virtual;
function PeepHoleOptPass2Cpu(var p: tai): boolean; virtual;
function PostPeepHoleOptsCpu(var p: tai): boolean; virtual;
+
+ function PreRegAllocPeepHoleOptPassCpu(var p : tai) : boolean; virtual;
End;
Function ArrayRefsEq(const r1, r2: TReference): Boolean;
@@ -1572,4 +1576,25 @@ Unit AoptObj;
result := false;
end;
+
+ procedure TAOptObj.PreRegAllocPeepHoleOptPass;
+ var
+ p: tai;
+ begin
+ p := BlockStart;
+ while (p <> BlockEnd) Do
+ begin
+ if PreRegAllocPeepHoleOptPassCPU(p) then
+ continue;
+ p:=tai(p.next);
+ end;
+ end;
+
+
+ function TAOptObj.PreRegAllocPeepHoleOptPassCpu(var p: tai): boolean;
+ begin
+ result := false;
+ end;
+
+
End.
diff --git a/compiler/psub.pas b/compiler/psub.pas
index 95e5030631..b070145d77 100644
--- a/compiler/psub.pas
+++ b/compiler/psub.pas
@@ -1585,6 +1585,10 @@ implementation
}
+ if (cs_opt_level1 in current_settings.optimizerswitches) and
+ { do not optimize pure assembler procedures }
+ not(pi_is_assembler in flags) then
+ PreRegallocOptimize(aktproccode);
{$ifndef NoOpt}
{$ifndef i386}
if (cs_opt_scheduler in current_settings.optimizerswitches) and
diff --git a/compiler/x86/aoptx86.pas b/compiler/x86/aoptx86.pas
index 01605a1a96..fcf7521613 100644
--- a/compiler/x86/aoptx86.pas
+++ b/compiler/x86/aoptx86.pas
@@ -37,6 +37,8 @@ unit aoptx86;
type
TX86AsmOptimizer = class(TAsmOptimizer)
function RegLoadedWithNewValue(reg : tregister; hp : tai) : boolean; override;
+ private
+ function PreRegAllocPeepHoleOptLea(var p : tai) : boolean;
protected
procedure PostPeepholeOptMov(const p : tai);
@@ -53,6 +55,8 @@ unit aoptx86;
class function IsExitCode(p : tai) : boolean;
class function isFoldableArithOp(hp1 : taicpu; reg : tregister) : boolean;
procedure RemoveLastDeallocForFuncRes(p : tai);
+
+ function PreRegAllocPeepHoleOptPassCpu(var p : tai) : boolean; override;
end;
function MatchInstruction(const instr: tai; const op: TAsmOp; const opsize: topsizes): boolean;
@@ -75,7 +79,7 @@ unit aoptx86;
uses
cutils,
verbose,
- procinfo,
+ cgobj,procinfo,
symconst,symsym,
itcpugas;
@@ -1245,5 +1249,46 @@ unit aoptx86;
end;
end;
+
+ function TX86AsmOptimizer.PreRegAllocPeepHoleOptLea(var p : tai) : boolean;
+ var
+ hp1 : tai;
+ begin
+ Result:=false;
+ if GetNextInstruction(p,hp1) and
+ (hp1.typ=ait_instruction) and
+ MatchInstruction(hp1,A_MOV,[S_L]) and
+ MatchOpType(hp1,top_reg,top_reg) and
+ MatchOperand(taicpu(p).oper[1]^,taicpu(hp1).oper[0]^) and
+ (cg.rg[getregtype(taicpu(p).oper[1]^.reg)].live_start[getsupreg(taicpu(p).oper[1]^.reg)]=p) and
+ (cg.rg[getregtype(taicpu(p).oper[1]^.reg)].live_end[getsupreg(taicpu(p).oper[1]^.reg)]=hp1) then
+ begin
+ taicpu(p).oper[1]^.reg:=taicpu(hp1).oper[0]^.reg;
+
+ if cg.rg[getregtype(taicpu(hp1).oper[1]^.reg)].live_end[getsupreg(taicpu(hp1).oper[1]^.reg)]=hp1 then
+ cg.rg[getregtype(taicpu(hp1).oper[1]^.reg)].live_end[getsupreg(taicpu(p).oper[1]^.reg)]:=p;
+
+ if cg.rg[getregtype(taicpu(hp1).oper[1]^.reg)].live_start[getsupreg(taicpu(hp1).oper[1]^.reg)]=hp1 then
+ cg.rg[getregtype(taicpu(hp1).oper[1]^.reg)].live_start[getsupreg(taicpu(p).oper[1]^.reg)]:=p;
+
+ AsmL.Remove(hp1);
+ hp1.Free;
+ cg.rg[getregtype(taicpu(p).oper[1]^.reg)].live_start[getsupreg(taicpu(p).oper[1]^.reg)]:=nil;
+ cg.rg[getregtype(taicpu(p).oper[1]^.reg)].live_end[getsupreg(taicpu(p).oper[1]^.reg)]:=nil;
+ end;
+ end;
+
+
+ function TX86AsmOptimizer.PreRegAllocPeepHoleOptPassCpu(var p : tai) : boolean;
+ begin
+ Result:=false;
+ case p.typ of
+ ait_instruction:
+ case taicpu(p).opcode of
+ A_LEA:
+ Result:=PreRegAllocPeepHoleOptLea(p);
+ end;
+ end;
+ end;
end.
--
2.13.3.windows.1
More information about the fpc-devel
mailing list