* 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:
Jonas Maebe 2006-09-10 16:21:50 +00:00
parent aa9808f6ce
commit 6997121c18
6 changed files with 54 additions and 5 deletions

View File

@ -375,6 +375,7 @@ interface
var
cgop : TOpCg;
otl,ofl : tasmlabel;
oldflowcontrol : tflowcontrol;
begin
{ And,Or will only evaluate from left to right only the
needed nodes unless full boolean evaluation is enabled }
@ -405,8 +406,14 @@ interface
else
internalerror(200307044);
end;
{ these jumps mean we're now in a flow control construct }
oldflowcontrol:=flowcontrol;
include(flowcontrol,fc_inflowcontrol);
secondpass(right);
maketojumpbool(current_asmdata.CurrAsmList,right,lr_load_regvars);
flowcontrol:=oldflowcontrol+(flowcontrol-[fc_inflowcontrol]);
end
else
begin

View File

@ -370,6 +370,8 @@ implementation
current_asmdata.getjumplabel(current_procinfo.CurrFalseLabel);
secondpass(left);
maybechangeloadnodereg(current_asmdata.CurrAsmList,left,true);
{ release memory for refcnt out parameters }
if (parasym.varspez=vs_out) and
(left.resulttype.def.needs_inittable) then

View File

@ -400,6 +400,11 @@ implementation
begin
{ set defaults }
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 }
secondpass(tcallparanode(left).left);
cgsize:=def_cgsize(tcallparanode(left).left.resulttype.def);
@ -421,7 +426,6 @@ implementation
{ second_ argument specified?, must be a s32bit in register }
if assigned(tcallparanode(left).right) then
begin
secondpass(tcallparanode(tcallparanode(left).right).left);
{ when constant, just multiply the addvalue }
if is_constintnode(tcallparanode(tcallparanode(left).right).left) then
addvalue:=addvalue*get_ordinal_value(tcallparanode(tcallparanode(left).right).left)

View File

@ -558,7 +558,8 @@ implementation
else
begin
{ SSA support }
maybechangeloadnodereg(left);
maybechangeloadnodereg(current_asmdata.CurrAsmList,left,false);
maybechangeloadnodereg(current_asmdata.CurrAsmList,right,true);
case right.location.loc of
LOC_CONSTANT :
begin

View File

@ -188,6 +188,7 @@ implementation
LOC_CREGISTER,
LOC_REGISTER:
begin
maybechangeloadnodereg(current_asmdata.CurrAsmList,left,true);
{$ifdef cpu_uses_separate_address_registers}
if getregtype(left.location.register)<>R_ADDRESSREGISTER then
begin

View File

@ -102,8 +102,9 @@ interface
procedure gen_sync_regvars(list:TAsmList; var rv: tusedregvars);
{ 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) }
procedure maybechangeloadnodereg(var n: tnode);
{ loadn and change its location to a new register (= SSA). In case reload }
{ 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.
@ -2466,11 +2467,21 @@ implementation
result := fen_norecurse_true;
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;
procedure maybechangeloadnodereg(var n: tnode);
procedure maybechangeloadnodereg(list: TAsmList; var n: tnode; reload: boolean);
var
rr: treplaceregrec;
begin
@ -2519,6 +2530,29 @@ implementation
if not foreachnodestatic(n,@doreplace,@rr) then
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 }
{$ifndef cpu64bit}
if (n.location.size in [OS_64,OS_S64]) then