* factored out PrePeepholeOptSxx

+ x86-64 uses PrePeepholeOptSxx now as well

git-svn-id: trunk@36158 -
This commit is contained in:
florian 2017-05-08 20:44:24 +00:00
parent 9fc420b546
commit 06c4c651fd
3 changed files with 106 additions and 68 deletions

View File

@ -607,67 +607,9 @@ begin
end;
end;
end;
A_SAR, A_SHR:
{changes the code sequence
shr/sar const1, x
shl const2, x
to either "sar/and", "shl/and" or just "and" depending on const1 and const2}
begin
if GetNextInstruction(p, hp1) and
(tai(hp1).typ = ait_instruction) and
(taicpu(hp1).opcode = A_SHL) and
(taicpu(p).oper[0]^.typ = top_const) and
(taicpu(hp1).oper[0]^.typ = top_const) and
(taicpu(hp1).opsize = taicpu(p).opsize) and
(taicpu(hp1).oper[1]^.typ = taicpu(p).oper[1]^.typ) and
OpsEqual(taicpu(hp1).oper[1]^, taicpu(p).oper[1]^) then
if (taicpu(p).oper[0]^.val > taicpu(hp1).oper[0]^.val) and
not(cs_opt_size in current_settings.optimizerswitches) then
{ shr/sar const1, %reg
shl const2, %reg
with const1 > const2 }
begin
taicpu(p).loadConst(0,taicpu(p).oper[0]^.val-taicpu(hp1).oper[0]^.val);
taicpu(hp1).opcode := A_AND;
l := (1 shl (taicpu(hp1).oper[0]^.val)) - 1;
case taicpu(p).opsize Of
S_L: taicpu(hp1).loadConst(0,l Xor aint($ffffffff));
S_B: taicpu(hp1).loadConst(0,l Xor $ff);
S_W: taicpu(hp1).loadConst(0,l Xor $ffff);
end;
end
else if (taicpu(p).oper[0]^.val<taicpu(hp1).oper[0]^.val) and
not(cs_opt_size in current_settings.optimizerswitches) then
{ shr/sar const1, %reg
shl const2, %reg
with const1 < const2 }
begin
taicpu(hp1).loadConst(0,taicpu(hp1).oper[0]^.val-taicpu(p).oper[0]^.val);
taicpu(p).opcode := A_AND;
l := (1 shl (taicpu(p).oper[0]^.val))-1;
case taicpu(p).opsize Of
S_L: taicpu(p).loadConst(0,l Xor aint($ffffffff));
S_B: taicpu(p).loadConst(0,l Xor $ff);
S_W: taicpu(p).loadConst(0,l Xor $ffff);
end;
end
else
{ shr/sar const1, %reg
shl const2, %reg
with const1 = const2 }
if (taicpu(p).oper[0]^.val = taicpu(hp1).oper[0]^.val) then
begin
taicpu(p).opcode := A_AND;
l := (1 shl (taicpu(p).oper[0]^.val))-1;
case taicpu(p).opsize Of
S_B: taicpu(p).loadConst(0,l Xor $ff);
S_W: taicpu(p).loadConst(0,l Xor $ffff);
S_L: taicpu(p).loadConst(0,l Xor aint($ffffffff));
end;
asml.remove(hp1);
hp1.free;
end;
end;
A_SAR,A_SHR:
if PrePeepholeOptSxx(p) then
continue;
A_XOR:
if (taicpu(p).oper[0]^.typ = top_reg) and
(taicpu(p).oper[1]^.typ = top_reg) and

View File

@ -46,7 +46,14 @@ unit aoptx86;
depend on the value in AH). }
function Reg1ReadDependsOnReg2(reg1, reg2: tregister): boolean;
procedure PostPeepholeOptMov(const p : tai);
procedure DebugMsg(const s : string; p : tai);inline;
procedure AllocRegBetween(reg : tregister; p1,p2 : tai;var initialusedregs : TAllUsedRegs);
class function IsExitCode(p : tai) : boolean;
class function isFoldableArithOp(hp1 : taicpu; reg : tregister) : boolean;
procedure RemoveLastDeallocForFuncRes(p : tai);
function PrePeepholeOptSxx(var p : tai) : boolean;
function OptPass1AND(var p : tai) : boolean;
function OptPass1VMOVAP(var p : tai) : boolean;
@ -58,12 +65,7 @@ unit aoptx86;
function OptPass2Jmp(var p : tai) : boolean;
function OptPass2Jcc(var p : tai) : boolean;
procedure DebugMsg(const s : string; p : tai);inline;
procedure AllocRegBetween(reg : tregister; p1,p2 : tai;var initialusedregs : TAllUsedRegs);
class function IsExitCode(p : tai) : boolean;
class function isFoldableArithOp(hp1 : taicpu; reg : tregister) : boolean;
procedure RemoveLastDeallocForFuncRes(p : tai);
procedure PostPeepholeOptMov(const p : tai);
end;
function MatchInstruction(const instr: tai; const op: TAsmOp; const opsize: topsizes): boolean;
@ -284,6 +286,85 @@ unit aoptx86;
end;
function TX86AsmOptimizer.PrePeepholeOptSxx(var p : tai) : boolean;
var
hp1 : tai;
l : TCGInt;
begin
result:=false;
{ changes the code sequence
shr/sar const1, x
shl const2, x
to
either "sar/and", "shl/and" or just "and" depending on const1 and const2 }
if GetNextInstruction(p, hp1) and
MatchInstruction(hp1,A_SHL,[]) and
(taicpu(p).oper[0]^.typ = top_const) and
(taicpu(hp1).oper[0]^.typ = top_const) and
(taicpu(hp1).opsize = taicpu(p).opsize) and
(taicpu(hp1).oper[1]^.typ = taicpu(p).oper[1]^.typ) and
OpsEqual(taicpu(hp1).oper[1]^, taicpu(p).oper[1]^) then
begin
if (taicpu(p).oper[0]^.val > taicpu(hp1).oper[0]^.val) and
not(cs_opt_size in current_settings.optimizerswitches) then
begin
{ shr/sar const1, %reg
shl const2, %reg
with const1 > const2 }
taicpu(p).loadConst(0,taicpu(p).oper[0]^.val-taicpu(hp1).oper[0]^.val);
taicpu(hp1).opcode := A_AND;
l := (1 shl (taicpu(hp1).oper[0]^.val)) - 1;
case taicpu(p).opsize Of
S_B: taicpu(hp1).loadConst(0,l Xor $ff);
S_W: taicpu(hp1).loadConst(0,l Xor $ffff);
S_L: taicpu(hp1).loadConst(0,l Xor aint($ffffffff));
S_Q: taicpu(hp1).loadConst(0,l Xor aint($ffffffffffffffff));
else
Internalerror(2017050703)
end;
end
else if (taicpu(p).oper[0]^.val<taicpu(hp1).oper[0]^.val) and
not(cs_opt_size in current_settings.optimizerswitches) then
begin
{ shr/sar const1, %reg
shl const2, %reg
with const1 < const2 }
taicpu(hp1).loadConst(0,taicpu(hp1).oper[0]^.val-taicpu(p).oper[0]^.val);
taicpu(p).opcode := A_AND;
l := (1 shl (taicpu(p).oper[0]^.val))-1;
case taicpu(p).opsize Of
S_B: taicpu(p).loadConst(0,l Xor $ff);
S_W: taicpu(p).loadConst(0,l Xor $ffff);
S_L: taicpu(p).loadConst(0,l Xor aint($ffffffff));
S_Q: taicpu(p).loadConst(0,l Xor aint($ffffffffffffffff));
else
Internalerror(2017050702)
end;
end
else if (taicpu(p).oper[0]^.val = taicpu(hp1).oper[0]^.val) then
begin
{ shr/sar const1, %reg
shl const2, %reg
with const1 = const2 }
taicpu(p).opcode := A_AND;
l := (1 shl (taicpu(p).oper[0]^.val))-1;
case taicpu(p).opsize Of
S_B: taicpu(p).loadConst(0,l Xor $ff);
S_W: taicpu(p).loadConst(0,l Xor $ffff);
S_L: taicpu(p).loadConst(0,l Xor aint($ffffffff));
S_Q: taicpu(p).loadConst(0,l Xor aint($ffffffffffffffff));
else
Internalerror(2017050701)
end;
asml.remove(hp1);
hp1.free;
end;
end;
end;
{ allocates register reg between (and including) instructions p1 and p2
the type of p1 and p2 must not be in SkipInstr
note that this routine is both called from the peephole optimizer

View File

@ -31,6 +31,7 @@ uses cgbase, cpubase, aasmtai, aopt, aoptx86, aoptcpub;
type
TCpuAsmOptimizer = class(TX86AsmOptimizer)
function PrePeepHoleOptsCpu(var p: tai): boolean; override;
function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
function PeepHoleOptPass2Cpu(var p: tai): boolean; override;
function PostPeepHoleOptsCpu(var p : tai) : boolean; override;
@ -47,6 +48,20 @@ uses
aasmbase, aasmdata, aasmcpu,
itcpugas;
function TCpuAsmOptimizer.PrePeepHoleOptsCpu(var p : tai) : boolean;
begin
result := false;
case p.typ of
ait_instruction:
begin
case taicpu(p).opcode of
A_SAR,A_SHR:
result:=PrePeepholeOptSxx(p);
end;
end;
end;
end;
function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
var
hp1, hp2: tai;