mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-22 06:49:27 +02:00
+ x86: LeaLea2Lea optimization
git-svn-id: trunk@43177 -
This commit is contained in:
parent
fb91899457
commit
00c2fd4005
@ -39,6 +39,7 @@ unit aoptx86;
|
||||
function RegLoadedWithNewValue(reg : tregister; hp : tai) : boolean; override;
|
||||
function InstructionLoadsFromReg(const reg : TRegister; const hp : tai) : boolean; override;
|
||||
function RegReadByInstruction(reg : TRegister; hp : tai) : boolean;
|
||||
function GetNextInstructionUsingReg(Current: tai; out Next: tai; reg: TRegister): Boolean;
|
||||
protected
|
||||
{ checks whether loading a new value in reg1 overwrites the entirety of reg2 }
|
||||
function Reg1WriteOverwritesReg2Entirely(reg1, reg2: tregister): boolean;
|
||||
@ -274,6 +275,19 @@ unit aoptx86;
|
||||
end;
|
||||
|
||||
|
||||
function TX86AsmOptimizer.GetNextInstructionUsingReg(Current: tai; out Next: tai; reg: TRegister): Boolean;
|
||||
begin
|
||||
Next:=Current;
|
||||
repeat
|
||||
Result:=GetNextInstruction(Next,Next);
|
||||
until not (Result) or
|
||||
not(cs_opt_level3 in current_settings.optimizerswitches) or
|
||||
(Next.typ<>ait_instruction) or
|
||||
RegInInstruction(reg,Next) or
|
||||
is_calljmp(taicpu(Next).opcode);
|
||||
end;
|
||||
|
||||
|
||||
function TX86AsmOptimizer.InstructionLoadsFromReg(const reg: TRegister;const hp: tai): boolean;
|
||||
begin
|
||||
Result:=RegReadByInstruction(reg,hp);
|
||||
@ -2181,6 +2195,34 @@ unit aoptx86;
|
||||
result:=true;
|
||||
end;
|
||||
end;
|
||||
{ changes
|
||||
lea offset1(regX), reg1
|
||||
lea offset2(reg1), reg1
|
||||
to
|
||||
lea offset1+offset2(regX), reg1 }
|
||||
if GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[1]^.reg) and
|
||||
MatchInstruction(hp1,A_LEA,[S_L]) and
|
||||
MatchOperand(taicpu(p).oper[1]^,taicpu(hp1).oper[1]^) and
|
||||
(taicpu(hp1).oper[0]^.ref^.base=taicpu(p).oper[1]^.reg) and
|
||||
(taicpu(p).oper[0]^.ref^.index=NR_NO) and
|
||||
(taicpu(p).oper[0]^.ref^.relsymbol=nil) and
|
||||
(taicpu(p).oper[0]^.ref^.scalefactor in [0,1]) and
|
||||
(taicpu(p).oper[0]^.ref^.segment=NR_NO) and
|
||||
(taicpu(p).oper[0]^.ref^.symbol=nil) and
|
||||
(taicpu(p).oper[0]^.ref^.index=taicpu(hp1).oper[0]^.ref^.index) and
|
||||
(taicpu(p).oper[0]^.ref^.relsymbol=taicpu(hp1).oper[0]^.ref^.relsymbol) and
|
||||
(taicpu(p).oper[0]^.ref^.scalefactor=taicpu(hp1).oper[0]^.ref^.scalefactor) and
|
||||
(taicpu(p).oper[0]^.ref^.segment=taicpu(hp1).oper[0]^.ref^.segment) and
|
||||
(taicpu(p).oper[0]^.ref^.symbol=taicpu(hp1).oper[0]^.ref^.symbol) then
|
||||
begin
|
||||
DebugMsg(SPeepholeOptimization + 'LeaLea2Lea done',p);
|
||||
inc(taicpu(hp1).oper[0]^.ref^.offset,taicpu(p).oper[0]^.ref^.offset);
|
||||
taicpu(hp1).oper[0]^.ref^.base:=taicpu(p).oper[0]^.ref^.base;
|
||||
asml.Remove(p);
|
||||
p.Free;
|
||||
p:=hp1;
|
||||
result:=true;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user