mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-13 21:29:19 +02:00
* also perform "SSA" for certain loads (currently derefn, righthand side of
assignmentn and callparan), reduces number of long lived conflicts. Mainly helpful on register-starved cpus such as i386. git-svn-id: trunk@4606 -
This commit is contained in:
parent
aa9808f6ce
commit
6997121c18
@ -375,6 +375,7 @@ interface
|
|||||||
var
|
var
|
||||||
cgop : TOpCg;
|
cgop : TOpCg;
|
||||||
otl,ofl : tasmlabel;
|
otl,ofl : tasmlabel;
|
||||||
|
oldflowcontrol : tflowcontrol;
|
||||||
begin
|
begin
|
||||||
{ And,Or will only evaluate from left to right only the
|
{ And,Or will only evaluate from left to right only the
|
||||||
needed nodes unless full boolean evaluation is enabled }
|
needed nodes unless full boolean evaluation is enabled }
|
||||||
@ -405,8 +406,14 @@ interface
|
|||||||
else
|
else
|
||||||
internalerror(200307044);
|
internalerror(200307044);
|
||||||
end;
|
end;
|
||||||
|
{ these jumps mean we're now in a flow control construct }
|
||||||
|
oldflowcontrol:=flowcontrol;
|
||||||
|
include(flowcontrol,fc_inflowcontrol);
|
||||||
|
|
||||||
secondpass(right);
|
secondpass(right);
|
||||||
maketojumpbool(current_asmdata.CurrAsmList,right,lr_load_regvars);
|
maketojumpbool(current_asmdata.CurrAsmList,right,lr_load_regvars);
|
||||||
|
|
||||||
|
flowcontrol:=oldflowcontrol+(flowcontrol-[fc_inflowcontrol]);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
|
@ -370,6 +370,8 @@ implementation
|
|||||||
current_asmdata.getjumplabel(current_procinfo.CurrFalseLabel);
|
current_asmdata.getjumplabel(current_procinfo.CurrFalseLabel);
|
||||||
secondpass(left);
|
secondpass(left);
|
||||||
|
|
||||||
|
maybechangeloadnodereg(current_asmdata.CurrAsmList,left,true);
|
||||||
|
|
||||||
{ release memory for refcnt out parameters }
|
{ release memory for refcnt out parameters }
|
||||||
if (parasym.varspez=vs_out) and
|
if (parasym.varspez=vs_out) and
|
||||||
(left.resulttype.def.needs_inittable) then
|
(left.resulttype.def.needs_inittable) then
|
||||||
|
@ -400,6 +400,11 @@ implementation
|
|||||||
begin
|
begin
|
||||||
{ set defaults }
|
{ set defaults }
|
||||||
addconstant:=true;
|
addconstant:=true;
|
||||||
|
{ first secondpass second argument, because if the first arg }
|
||||||
|
{ is used in that expression then SSL may move it to another }
|
||||||
|
{ register }
|
||||||
|
if assigned(tcallparanode(left).right) then
|
||||||
|
secondpass(tcallparanode(tcallparanode(left).right).left);
|
||||||
{ load first parameter, must be a reference }
|
{ load first parameter, must be a reference }
|
||||||
secondpass(tcallparanode(left).left);
|
secondpass(tcallparanode(left).left);
|
||||||
cgsize:=def_cgsize(tcallparanode(left).left.resulttype.def);
|
cgsize:=def_cgsize(tcallparanode(left).left.resulttype.def);
|
||||||
@ -421,7 +426,6 @@ implementation
|
|||||||
{ second_ argument specified?, must be a s32bit in register }
|
{ second_ argument specified?, must be a s32bit in register }
|
||||||
if assigned(tcallparanode(left).right) then
|
if assigned(tcallparanode(left).right) then
|
||||||
begin
|
begin
|
||||||
secondpass(tcallparanode(tcallparanode(left).right).left);
|
|
||||||
{ when constant, just multiply the addvalue }
|
{ when constant, just multiply the addvalue }
|
||||||
if is_constintnode(tcallparanode(tcallparanode(left).right).left) then
|
if is_constintnode(tcallparanode(tcallparanode(left).right).left) then
|
||||||
addvalue:=addvalue*get_ordinal_value(tcallparanode(tcallparanode(left).right).left)
|
addvalue:=addvalue*get_ordinal_value(tcallparanode(tcallparanode(left).right).left)
|
||||||
|
@ -558,7 +558,8 @@ implementation
|
|||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
{ SSA support }
|
{ SSA support }
|
||||||
maybechangeloadnodereg(left);
|
maybechangeloadnodereg(current_asmdata.CurrAsmList,left,false);
|
||||||
|
maybechangeloadnodereg(current_asmdata.CurrAsmList,right,true);
|
||||||
case right.location.loc of
|
case right.location.loc of
|
||||||
LOC_CONSTANT :
|
LOC_CONSTANT :
|
||||||
begin
|
begin
|
||||||
|
@ -188,6 +188,7 @@ implementation
|
|||||||
LOC_CREGISTER,
|
LOC_CREGISTER,
|
||||||
LOC_REGISTER:
|
LOC_REGISTER:
|
||||||
begin
|
begin
|
||||||
|
maybechangeloadnodereg(current_asmdata.CurrAsmList,left,true);
|
||||||
{$ifdef cpu_uses_separate_address_registers}
|
{$ifdef cpu_uses_separate_address_registers}
|
||||||
if getregtype(left.location.register)<>R_ADDRESSREGISTER then
|
if getregtype(left.location.register)<>R_ADDRESSREGISTER then
|
||||||
begin
|
begin
|
||||||
|
@ -102,8 +102,9 @@ interface
|
|||||||
procedure gen_sync_regvars(list:TAsmList; var rv: tusedregvars);
|
procedure gen_sync_regvars(list:TAsmList; var rv: tusedregvars);
|
||||||
|
|
||||||
{ if the result of n is a LOC_C(..)REGISTER, try to find the corresponding }
|
{ if the result of n is a LOC_C(..)REGISTER, try to find the corresponding }
|
||||||
{ loadn and change its location to a new register (= SSA) }
|
{ loadn and change its location to a new register (= SSA). In case reload }
|
||||||
procedure maybechangeloadnodereg(var n: tnode);
|
{ is true, transfer the old to the new register }
|
||||||
|
procedure maybechangeloadnodereg(list: TAsmList; var n: tnode; reload: boolean);
|
||||||
|
|
||||||
{#
|
{#
|
||||||
Allocate the buffers for exception management and setjmp environment.
|
Allocate the buffers for exception management and setjmp environment.
|
||||||
@ -2466,11 +2467,21 @@ implementation
|
|||||||
result := fen_norecurse_true;
|
result := fen_norecurse_true;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
{ optimize the searching a bit }
|
||||||
|
derefn,addrn,
|
||||||
|
calln,inlinen,casen,
|
||||||
|
addn,subn,muln,
|
||||||
|
andn,orn,xorn,
|
||||||
|
ltn,lten,gtn,gten,equaln,unequaln,
|
||||||
|
slashn,divn,shrn,shln,notn,
|
||||||
|
inn,
|
||||||
|
asn,isn:
|
||||||
|
result := fen_norecurse_false;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure maybechangeloadnodereg(var n: tnode);
|
procedure maybechangeloadnodereg(list: TAsmList; var n: tnode; reload: boolean);
|
||||||
var
|
var
|
||||||
rr: treplaceregrec;
|
rr: treplaceregrec;
|
||||||
begin
|
begin
|
||||||
@ -2519,6 +2530,29 @@ implementation
|
|||||||
if not foreachnodestatic(n,@doreplace,@rr) then
|
if not foreachnodestatic(n,@doreplace,@rr) then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
if reload then
|
||||||
|
case n.location.loc of
|
||||||
|
LOC_CREGISTER:
|
||||||
|
begin
|
||||||
|
{$ifndef cpu64bit}
|
||||||
|
if (n.location.size in [OS_64,OS_S64]) then
|
||||||
|
cg64.a_load64_reg_reg(list,n.location.register64,joinreg64(rr.new,rr.newhi))
|
||||||
|
else
|
||||||
|
{$endif cpu64bit}
|
||||||
|
cg.a_load_reg_reg(list,n.location.size,n.location.size,n.location.register,rr.new);
|
||||||
|
end;
|
||||||
|
LOC_CFPUREGISTER:
|
||||||
|
cg.a_loadfpu_reg_reg(list,n.location.size,n.location.register,rr.new);
|
||||||
|
{$ifdef SUPPORT_MMX}
|
||||||
|
LOC_CMMXREGISTER:
|
||||||
|
cg.a_loadmm_reg_reg(list,OS_M64,OS_M64,n.location.register,rr.new,nil);
|
||||||
|
{$endif SUPPORT_MMX}
|
||||||
|
LOC_CMMREGISTER:
|
||||||
|
cg.a_loadmm_reg_reg(list,n.location.size,n.location.size,n.location.register,rr.new,nil);
|
||||||
|
else
|
||||||
|
internalerror(2006090920);
|
||||||
|
end;
|
||||||
|
|
||||||
{ now that we've change the loadn/temp, also change the node result location }
|
{ now that we've change the loadn/temp, also change the node result location }
|
||||||
{$ifndef cpu64bit}
|
{$ifndef cpu64bit}
|
||||||
if (n.location.size in [OS_64,OS_S64]) then
|
if (n.location.size in [OS_64,OS_S64]) then
|
||||||
|
Loading…
Reference in New Issue
Block a user