* MIPS: improved code generation in make_simple_ref

* Clean up the peephole optimizer
+ More peephole optimizations.

git-svn-id: trunk@28892 -
This commit is contained in:
sergei 2014-10-21 21:05:46 +00:00
parent 0041024e5f
commit 06ee500352
2 changed files with 68 additions and 39 deletions

View File

@ -37,8 +37,6 @@ unit aoptcpu;
function RegModifiedByInstruction(Reg: TRegister; p1: tai): boolean; override;
function GetNextInstructionUsingReg(Current: tai;
var Next: tai; reg: TRegister): Boolean;
function RegUsedAfterInstruction(reg: Tregister; p: tai;
var AllUsedRegs: TAllUsedRegs): Boolean;
function TryRemoveMov(var p: tai; opcode: TAsmOp): boolean;
function TryRemoveMovToRefIndex(var p: tai; next: taicpu): boolean;
function TryRemoveMovBeforeStore(var p: tai; next: taicpu; const storeops: TAsmOpSet): boolean;
@ -49,7 +47,7 @@ unit aoptcpu;
Implementation
uses
globals,aasmbase,cpuinfo,verbose;
cutils,globals,aasmbase,cpuinfo,verbose;
function MatchInstruction(const instr: tai; const op: TAsmOp): boolean;
@ -210,21 +208,6 @@ unit aoptcpu;
end;
function TCpuAsmOptimizer.RegUsedAfterInstruction(reg: Tregister; p: tai;
var AllUsedRegs: TAllUsedRegs): Boolean;
begin
AllUsedRegs[getregtype(reg)].Update(tai(p.Next),true);
RegUsedAfterInstruction :=
AllUsedRegs[getregtype(reg)].IsUsed(reg) and
not(regLoadedWithNewValue(reg,p)) and
(
not(GetNextInstruction(p,p)) or
instructionLoadsFromReg(reg,p) or
not(regLoadedWithNewValue(reg,p))
);
end;
function TCpuAsmOptimizer.TryRemoveMov(var p: tai; opcode: TAsmOp): boolean;
var
next,hp1: tai;
@ -281,6 +264,25 @@ unit aoptcpu;
asml.remove(next);
next.free;
result:=true;
end
else // no dealloc found
begin
{ try to optimize the typical call sequence
lw $reg, (whatever)
<alloc volatile registers>
move $t9,$reg
jalr $t9 }
if (opcode=A_MOVE) and
(taicpu(next).oper[0]^.reg=NR_R25) and
GetNextInstruction(next,hp1) and
MatchInstruction(hp1,A_JALR) and
MatchOperand(taicpu(hp1).oper[0]^,NR_R25) then
begin
taicpu(p).loadreg(0,taicpu(next).oper[0]^.reg);
asml.remove(next);
next.free;
result:=true;
end;
end;
end;
end;
@ -322,7 +324,6 @@ unit aoptcpu;
function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
var
next,next2: tai;
TmpUsedRegs: TAllUsedRegs;
begin
result:=false;
case p.typ of
@ -443,18 +444,13 @@ unit aoptcpu;
((taicpu(p).oper[2]^.val=255) and MatchInstruction(next,A_SB)) or
((taicpu(p).oper[2]^.val=65535) and MatchInstruction(next,A_SH)) and
(taicpu(next).oper[0]^.typ=top_reg) and
(taicpu(next).oper[0]^.reg=taicpu(p).oper[0]^.reg) then
(taicpu(next).oper[0]^.reg=taicpu(p).oper[0]^.reg) and
assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(next.next))) then
begin
CopyUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(p.next));
if not RegUsedAfterInstruction(taicpu(p).oper[0]^.reg,next,TmpUsedRegs) then
begin
taicpu(next).loadreg(0,taicpu(p).oper[1]^.reg);
asml.remove(p);
p.free;
p:=next;
end;
ReleaseUsedRegs(TmpUsedRegs);
taicpu(next).loadreg(0,taicpu(p).oper[1]^.reg);
asml.remove(p);
p.free;
p:=next;
end
else
TryRemoveMov(p,A_MOVE);
@ -566,9 +562,49 @@ unit aoptcpu;
end;
end;
A_ADDIU:
begin
{ ADDIU Rx,Ry,const; load/store Rz,(Rx); dealloc Rx ==> load/store Rz,const(Ry)
ADDIU Rx,Ry,%lo(sym); load/store Rz,(Rx); dealloc Rx ==> load/store Rz,%lo(sym)(Ry)
ADDIU Rx,Ry,const; load Rx,(Rx) ==> load Rx,const(Ry)
ADDIU Rx,Ry,%lo(sym); load Rx,(Rx) ==> load Rx,%lo(sym)(Ry) }
if GetNextInstructionUsingReg(p,next,taicpu(p).oper[0]^.reg) and
(next.typ=ait_instruction) and
(taicpu(next).opcode in [A_LB,A_LBU,A_LH,A_LHU,A_LW,A_SB,A_SH,A_SW]) and
(taicpu(p).oper[0]^.reg=taicpu(next).oper[1]^.ref^.base) and
(taicpu(next).oper[1]^.ref^.offset=0) and
(taicpu(next).oper[1]^.ref^.symbol=nil) and
(
Assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(next.next))) or
(
(taicpu(p).oper[0]^.reg=taicpu(next).oper[0]^.reg) and
(taicpu(next).opcode in [A_LB,A_LBU,A_LH,A_LHU,A_LW])
)
) and
(not RegModifiedBetween(taicpu(p).oper[1]^.reg,p,next)) then
begin
case taicpu(p).oper[2]^.typ of
top_const:
taicpu(next).oper[1]^.ref^.offset:=taicpu(p).oper[2]^.val;
top_ref:
taicpu(next).oper[1]^.ref^:=taicpu(p).oper[2]^.ref^;
else
InternalError(2014100401);
end;
taicpu(next).oper[1]^.ref^.base:=taicpu(p).oper[1]^.reg;
asml.remove(p);
p.free;
p:=next;
result:=true;
end
else
result:=TryRemoveMov(p,A_MOVE);
end;
A_LB,A_LBU,A_LH,A_LHU,A_LW,
A_ADD,A_ADDU,
A_ADDI,A_ADDIU,
A_ADDI,
A_SUB,A_SUBU,
A_SRA,A_SRAV,
A_SRLV,

View File

@ -197,16 +197,9 @@ begin
{ PIC global symbol }
ref.symbol:=nil;
if (ref.offset=0) then
exit;
if (ref.offset>=simm16lo) and
(ref.offset<=simm16hi-sizeof(pint)) then
begin
list.concat(taicpu.op_reg_reg_const(A_ADDIU,ref.base,ref.base,ref.offset));
ref.offset:=0;
exit;
end;
exit;
{ fallthrough to the case of large offset }
end;