mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 13:29:19 +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;
|
end;
|
||||||
p := tai(p.next)
|
p := tai(p.next)
|
||||||
end;
|
end;
|
||||||
|
OptReferences;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ unit aoptcpu;
|
|||||||
Type
|
Type
|
||||||
TCpuAsmOptimizer = class(TX86AsmOptimizer)
|
TCpuAsmOptimizer = class(TX86AsmOptimizer)
|
||||||
function PeepHoleOptPass1Cpu(var p : tai) : boolean; override;
|
function PeepHoleOptPass1Cpu(var p : tai) : boolean; override;
|
||||||
|
procedure PostPeepHoleOpts; override;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Implementation
|
Implementation
|
||||||
@ -112,6 +113,13 @@ unit aoptcpu;
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TCpuAsmOptimizer.PostPeepHoleOpts;
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
OptReferences;
|
||||||
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
casmoptimizer:=TCpuAsmOptimizer;
|
casmoptimizer:=TCpuAsmOptimizer;
|
||||||
end.
|
end.
|
||||||
|
@ -496,6 +496,7 @@ interface
|
|||||||
function is_16_bit_ref(const ref:treference):boolean;
|
function is_16_bit_ref(const ref:treference):boolean;
|
||||||
function get_ref_address_size(const ref:treference):byte;
|
function get_ref_address_size(const ref:treference):byte;
|
||||||
function get_default_segment_of_ref(const ref:treference):tregister;
|
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_load(const ref:treference;r:tregister):Taicpu;
|
||||||
function spilling_create_store(r:tregister; const ref:treference):Taicpu;
|
function spilling_create_store(r:tregister; const ref:treference):Taicpu;
|
||||||
@ -1868,6 +1869,48 @@ implementation
|
|||||||
end;
|
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;
|
function taicpu.needaddrprefix(opidx:byte):boolean;
|
||||||
begin
|
begin
|
||||||
{$if defined(x86_64)}
|
{$if defined(x86_64)}
|
||||||
|
@ -73,6 +73,8 @@ unit aoptx86;
|
|||||||
function OptPass2Jcc(var p : tai) : boolean;
|
function OptPass2Jcc(var p : tai) : boolean;
|
||||||
|
|
||||||
procedure PostPeepholeOptMov(const p : tai);
|
procedure PostPeepholeOptMov(const p : tai);
|
||||||
|
|
||||||
|
procedure OptReferences;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function MatchInstruction(const instr: tai; const op: TAsmOp; const opsize: topsizes): boolean;
|
function MatchInstruction(const instr: tai; const op: TAsmOp; const opsize: topsizes): boolean;
|
||||||
@ -2665,5 +2667,24 @@ unit aoptx86;
|
|||||||
end;
|
end;
|
||||||
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.
|
end.
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ type
|
|||||||
function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
|
function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
|
||||||
function PeepHoleOptPass2Cpu(var p: tai): boolean; override;
|
function PeepHoleOptPass2Cpu(var p: tai): boolean; override;
|
||||||
function PostPeepHoleOptsCpu(var p : tai) : boolean; override;
|
function PostPeepHoleOptsCpu(var p : tai) : boolean; override;
|
||||||
|
procedure PostPeepHoleOpts; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -146,6 +147,13 @@ uses
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TCpuAsmOptimizer.PostPeepHoleOpts;
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
OptReferences;
|
||||||
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
casmoptimizer := TCpuAsmOptimizer;
|
casmoptimizer := TCpuAsmOptimizer;
|
||||||
end.
|
end.
|
||||||
|
Loading…
Reference in New Issue
Block a user