+ very limited SSA support (only outside control flow

constructs for now)

git-svn-id: trunk@3671 -
This commit is contained in:
Jonas Maebe 2006-05-25 11:45:08 +00:00
parent 4bcfd1af9a
commit e531c4f125
5 changed files with 152 additions and 3 deletions

View File

@ -148,6 +148,7 @@ implementation
oldflowcontrol:=flowcontrol;
oldclabel:=current_procinfo.CurrContinueLabel;
oldblabel:=current_procinfo.CurrBreakLabel;
include(flowcontrol,fc_inflowcontrol);
sync_regvars(true);
{$ifdef OLDREGVARS}
@ -199,7 +200,7 @@ implementation
current_procinfo.CurrContinueLabel:=oldclabel;
current_procinfo.CurrBreakLabel:=oldblabel;
{ a break/continue in a while/repeat block can't be seen outside }
flowcontrol:=oldflowcontrol+(flowcontrol-[fc_break,fc_continue]);
flowcontrol:=oldflowcontrol+(flowcontrol-[fc_break,fc_continue,fc_inflowcontrol]);
end;
@ -211,6 +212,7 @@ implementation
var
hl,otlabel,oflabel : tasmlabel;
oldflowcontrol: tflowcontrol;
(*
org_regvar_loaded_other,
then_regvar_loaded_other,
@ -226,6 +228,8 @@ implementation
begin
location_reset(location,LOC_VOID,OS_NO);
oldflowcontrol := flowcontrol;
include(flowcontrol,fc_inflowcontrol);
otlabel:=current_procinfo.CurrTrueLabel;
oflabel:=current_procinfo.CurrFalseLabel;
current_asmdata.getjumplabel(current_procinfo.CurrTrueLabel);
@ -359,6 +363,7 @@ implementation
current_procinfo.CurrTrueLabel:=otlabel;
current_procinfo.CurrFalseLabel:=oflabel;
flowcontrol := oldflowcontrol + (flowcontrol - [fc_inflowcontrol]);
end;
@ -416,6 +421,7 @@ implementation
begin
location_reset(location,LOC_VOID,OS_NO);
oldflowcontrol:=flowcontrol;
include(flowcontrol,fc_inflowcontrol);
oldclabel:=current_procinfo.CurrContinueLabel;
oldblabel:=current_procinfo.CurrBreakLabel;
current_asmdata.getjumplabel(current_procinfo.CurrContinueLabel);
@ -759,7 +765,7 @@ implementation
current_procinfo.CurrContinueLabel:=oldclabel;
current_procinfo.CurrBreakLabel:=oldblabel;
{ a break/continue in a while/repeat block can't be seen outside }
flowcontrol:=oldflowcontrol+(flowcontrol-[fc_break,fc_continue]);
flowcontrol:=oldflowcontrol+(flowcontrol-[fc_break,fc_continue,fc_inflowcontrol]);
end;
@ -830,6 +836,7 @@ implementation
begin
location_reset(location,LOC_VOID,OS_NO);
include(flowcontrol,fc_gotolabel);
{$ifdef OLDREGVARS}
load_all_regvars(current_asmdata.CurrAsmList);
{$endif OLDREGVARS}
@ -853,6 +860,7 @@ implementation
begin
location_reset(location,LOC_VOID,OS_NO);
include(flowcontrol,fc_gotolabel);
{$ifdef OLDREGVARS}
load_all_regvars(current_asmdata.CurrAsmList);
{$endif OLDREGVARS}

View File

@ -557,6 +557,8 @@ implementation
end
else
begin
{ SSA support }
maybechangeloadnodereg(left);
case right.location.loc of
LOC_CONSTANT :
begin

View File

@ -683,6 +683,7 @@ implementation
procedure tcgcasenode.pass_2;
var
oldflowcontrol: tflowcontrol;
i : longint;
lv,hv,
max_label: tconstexprint;
@ -695,6 +696,8 @@ implementation
begin
location_reset(location,LOC_VOID,OS_NO);
oldflowcontrol := flowcontrol;
include(flowcontrol,fc_inflowcontrol);
{ Allocate labels }
current_asmdata.getjumplabel(endlabel);
current_asmdata.getjumplabel(elselabel);
@ -862,6 +865,7 @@ implementation
{ Reset labels }
for i:=0 to blocks.count-1 do
pcaseblock(blocks[i])^.blocklabel:=nil;
flowcontrol := oldflowcontrol + (flowcontrol - [fc_inflowcontrol]);
end;

View File

@ -101,6 +101,9 @@ interface
// procedure get_used_regvars_common(n: tnode; var rv: tusedregvarscommon);
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);
{#
Allocate the buffers for exception management and setjmp environment.
@ -167,6 +170,9 @@ implementation
{$ifdef powerpc64}
, cpupi
{$endif}
{$ifdef SUPPORT_MMX}
, cgx86
{$endif SUPPORT_MMX}
;
@ -2240,6 +2246,135 @@ implementation
end;
{*****************************************************************************
SSA support
*****************************************************************************}
type
preplaceregrec = ^treplaceregrec;
treplaceregrec = record
old, new: tregister;
{$ifndef cpu64bit}
oldhi, newhi: tregister;
{$endif cpu64bit}
ressym: tsym;
end;
function doreplace(var n: tnode; para: pointer): foreachnoderesult;
var
rr: preplaceregrec absolute para;
begin
result := fen_false;
case n.nodetype of
loadn:
begin
if (tabstractvarsym(tloadnode(n).symtableentry).varoptions * [vo_is_dll_var, vo_is_thread_var] = []) and
not assigned(tloadnode(n).left) and
(((tloadnode(n).symtableentry <> rr^.ressym) and
not(vo_is_funcret in tabstractvarsym(tloadnode(n).symtableentry).varoptions)) or
not(fc_exit in flowcontrol)) and
(tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.loc in [LOC_CREGISTER,LOC_CFPUREGISTER,LOC_CMMXREGISTER,LOC_CMMREGISTER]) and
(tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.register = rr^.old) then
begin
{$ifndef cpu64bit}
{ it's possible a 64 bit location was shifted and/xor typecasted }
{ in a 32 bit value, so only 1 register was left in the location }
if (tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.size in [OS_64,OS_S64]) then
if (tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.register64.reghi = rr^.oldhi) then
tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.register64.reghi := rr^.newhi
else
exit;
{$endif cpu64bit}
tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.register := rr^.new;
result := fen_norecurse_true;
end;
end;
temprefn:
begin
if (ttemprefnode(n).tempinfo^.valid) and
(ttemprefnode(n).tempinfo^.location.loc in [LOC_CREGISTER,LOC_CFPUREGISTER,LOC_CMMXREGISTER,LOC_CMMREGISTER]) and
(ttemprefnode(n).tempinfo^.location.register = rr^.old) then
begin
{$ifndef cpu64bit}
{ it's possible a 64 bit location was shifted and/xor typecasted }
{ in a 32 bit value, so only 1 register was left in the location }
if (ttemprefnode(n).tempinfo^.location.size in [OS_64,OS_S64]) then
if (ttemprefnode(n).tempinfo^.location.register64.reghi = rr^.oldhi) then
ttemprefnode(n).tempinfo^.location.register64.reghi := rr^.newhi
else
exit;
{$endif cpu64bit}
ttemprefnode(n).tempinfo^.location.register := rr^.new;
result := fen_norecurse_true;
end;
end;
end;
end;
procedure maybechangeloadnodereg(var n: tnode);
var
rr: treplaceregrec;
begin
if not (n.location.loc in [LOC_CREGISTER,LOC_CFPUREGISTER,LOC_CMMXREGISTER,LOC_CMMREGISTER]) or
([fc_inflowcontrol,fc_gotolabel] * flowcontrol <> []) then
exit;
rr.old := n.location.register;
rr.ressym := nil;
{$ifndef cpu64bit}
rr.oldhi := NR_NO;
{$endif cpu64bit}
case n.location.loc of
LOC_CREGISTER:
begin
{$ifndef cpu64bit}
if (n.location.size in [OS_64,OS_S64]) then
begin
rr.oldhi := n.location.register64.reghi;
rr.new := cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
rr.newhi := cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
end
else
{$endif cpu64bit}
rr.new := cg.getintregister(current_asmdata.CurrAsmList,n.location.size);
end;
LOC_CFPUREGISTER:
rr.new := cg.getfpuregister(current_asmdata.CurrAsmList,n.location.size);
{$ifdef SUPPORT_MMX}
LOC_CMMXREGISTER:
rr.new := tcgx86(cg).getmmxregister(current_asmdata.CurrAsmList);
{$endif SUPPORT_MMX}
LOC_CMMREGISTER:
rr.new := cg.getmmregister(current_asmdata.CurrAsmList,n.location.size);
else
exit;
end;
if (current_procinfo.procdef.funcretloc[calleeside].loc<>LOC_VOID) and
assigned(current_procinfo.procdef.funcretsym) and
(tabstractvarsym(current_procinfo.procdef.funcretsym).refs <> 0) then
if (current_procinfo.procdef.proctypeoption=potype_constructor) then
rr.ressym:=tsym(current_procinfo.procdef.parast.search('self'))
else
rr.ressym:=current_procinfo.procdef.funcretsym;
if not foreachnodestatic(n,@doreplace,@rr) then
exit;
{ 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
begin
n.location.register64.reglo := rr.new;
n.location.register64.reghi := rr.newhi;
end
else
{$endif cpu64bit}
n.location.register := rr.new;
end;
procedure gen_free_symtable(list:TAsmList;st:tsymtable);
var
sym : tsym;

View File

@ -29,7 +29,7 @@ uses
node;
type
tenumflowcontrol = (fc_exit,fc_break,fc_continue);
tenumflowcontrol = (fc_exit,fc_break,fc_continue,fc_inflowcontrol,fc_gotolabel);
tflowcontrol = set of tenumflowcontrol;
var