mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-17 13:39:36 +02:00
+ added an optimization pass, that optimizes x86 references
git-svn-id: trunk@37494 -
This commit is contained in:
parent
d28a790a43
commit
80226e3af4
@ -1462,6 +1462,7 @@ begin
|
||||
end;
|
||||
p := tai(p.next)
|
||||
end;
|
||||
OptReferences;
|
||||
end;
|
||||
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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)}
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user