+ added an optimization pass, that optimizes x86 references

git-svn-id: trunk@37494 -
This commit is contained in:
nickysn 2017-10-20 15:55:55 +00:00
parent d28a790a43
commit 80226e3af4
5 changed files with 81 additions and 0 deletions

View File

@ -1462,6 +1462,7 @@ begin
end;
p := tai(p.next)
end;
OptReferences;
end;

View File

@ -34,6 +34,7 @@ unit aoptcpu;
Type
TCpuAsmOptimizer = class(TX86AsmOptimizer)
function PeepHoleOptPass1Cpu(var p : tai) : boolean; override;
procedure PostPeepHoleOpts; override;
End;
Implementation
@ -112,6 +113,13 @@ unit aoptcpu;
end;
end;
procedure TCpuAsmOptimizer.PostPeepHoleOpts;
begin
inherited;
OptReferences;
end;
begin
casmoptimizer:=TCpuAsmOptimizer;
end.

View File

@ -496,6 +496,7 @@ interface
function is_16_bit_ref(const ref:treference):boolean;
function get_ref_address_size(const ref:treference):byte;
function get_default_segment_of_ref(const ref:treference):tregister;
procedure optimize_ref(var ref:treference; inlineasm: boolean);
function spilling_create_load(const ref:treference;r:tregister):Taicpu;
function spilling_create_store(r:tregister; const ref:treference):Taicpu;
@ -1868,6 +1869,48 @@ implementation
end;
procedure optimize_ref(var ref:treference; inlineasm: boolean);
var
ss_equals_ds: boolean;
begin
if inlineasm then
ss_equals_ds:=False
else
ss_equals_ds:=segment_regs_equal(NR_DS,NR_SS);
{ remove redundant segment overrides }
if (ref.segment<>NR_NO) and (ref.segment=get_default_segment_of_ref(ref)) then
ref.segment:=NR_NO;
if not is_16_bit_ref(ref) then
begin
{ Switching index to base position gives shorter assembler instructions.
Converting index*2 to base+index also gives shorter instructions. }
if (ref.base=NR_NO) and (ref.index<>NR_NO) and (ref.scalefactor<=2) and
(ss_equals_ds or (ref.segment<>NR_NO) or (ref.index<>NR_EBP)) then
begin
ref.base:=ref.index;
if ref.scalefactor=2 then
ref.scalefactor:=1
else
begin
ref.index:=NR_NO;
ref.scalefactor:=0;
end;
end;
{ Switching EBP+reg to reg+EBP sometimes gives shorter instructions (if there's no offset) }
if (ref.base=NR_EBP) and (ref.index<>NR_NO) and (ref.index<>NR_EBP) and
(ref.scalefactor<=1) and (ref.offset=0) and (ref.refaddr=addr_no) and
(ss_equals_ds or (ref.segment<>NR_NO)) then
begin
ref.base:=ref.index;
ref.index:=NR_EBP;
end;
end;
{ remove redundant segment overrides again }
if (ref.segment<>NR_NO) and (ref.segment=get_default_segment_of_ref(ref)) then
ref.segment:=NR_NO;
end;
function taicpu.needaddrprefix(opidx:byte):boolean;
begin
{$if defined(x86_64)}

View File

@ -73,6 +73,8 @@ unit aoptx86;
function OptPass2Jcc(var p : tai) : boolean;
procedure PostPeepholeOptMov(const p : tai);
procedure OptReferences;
end;
function MatchInstruction(const instr: tai; const op: TAsmOp; const opsize: topsizes): boolean;
@ -2665,5 +2667,24 @@ unit aoptx86;
end;
end;
procedure TX86AsmOptimizer.OptReferences;
var
p: tai;
i: Integer;
begin
p := BlockStart;
while (p <> BlockEnd) Do
begin
if p.typ=ait_instruction then
begin
for i:=0 to taicpu(p).ops-1 do
if taicpu(p).oper[i]^.typ=top_ref then
optimize_ref(taicpu(p).oper[i]^.ref^,false);
end;
p:=tai(p.next);
end;
end;
end.

View File

@ -35,6 +35,7 @@ type
function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
function PeepHoleOptPass2Cpu(var p: tai): boolean; override;
function PostPeepHoleOptsCpu(var p : tai) : boolean; override;
procedure PostPeepHoleOpts; override;
end;
implementation
@ -146,6 +147,13 @@ uses
end;
end;
procedure TCpuAsmOptimizer.PostPeepHoleOpts;
begin
inherited;
OptReferences;
end;
begin
casmoptimizer := TCpuAsmOptimizer;
end.