summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2008-01-20 20:45:00 +0000
committerflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2008-01-20 20:45:00 +0000
commit8a9986c2c48fdf64712e6a6c6ca03c771fb84b85 (patch)
treeacb5554504749b323ba5d4d24f66aa97201e6370
parent09a0149604fb7981f5c2f44377d856bf7313ce24 (diff)
downloadfpc-ssa.tar.gz
* first approach to fix -O2 with ssassa
git-svn-id: http://svn.freepascal.org/svn/fpc/branches/ssa@9825 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r--compiler/ncgflw.pas47
-rw-r--r--compiler/ncgutil.pas25
2 files changed, 48 insertions, 24 deletions
diff --git a/compiler/ncgflw.pas b/compiler/ncgflw.pas
index c9f8e397c2..26d6c19089 100644
--- a/compiler/ncgflw.pas
+++ b/compiler/ncgflw.pas
@@ -140,7 +140,19 @@ implementation
oldclabel,oldblabel : tasmlabel;
otlabel,oflabel : tasmlabel;
oldflowcontrol : tflowcontrol;
+ createphi : boolean;
begin
+ createphi:=has_life_info(self) and has_life_info(successor);
+ if createphi then
+ begin
+ { break }
+ getregmapping(successor.optinfo^.life,successor.optinfo^.regmap);
+ { loop/continue
+ they can share the register mapping because they are only separated by
+ the abort condition code which does no ssa }
+ getregmapping(optinfo^.life,optinfo^.regmap);
+ end;
+
location_reset(location,LOC_VOID,OS_NO);
current_asmdata.getjumplabel(lloop);
@@ -156,11 +168,11 @@ implementation
{$ifdef OLDREGVARS}
load_all_regvars(current_asmdata.CurrAsmList);
{$endif OLDREGVARS}
+
+ if createphi then
+ generate_phi(current_asmdata.CurrAsmList,optinfo^.life,optinfo^.regmap);
{ handling code at the end as it is much more efficient, and makes
while equal to repeat loop, only the end true/false is swapped (PFV) }
- if assigned(optinfo) then
- generate_phi(current_asmdata.CurrAsmList,self.optinfo^.life,self.optinfo^.regmap);
-
if lnf_testatbegin in loopflags then
cg.a_jmp_always(current_asmdata.CurrAsmList,lcont);
@@ -170,16 +182,16 @@ implementation
cg.a_label(current_asmdata.CurrAsmList,lloop);
- if assigned(optinfo) then
- update_phi(current_asmdata.CurrAsmList,self.optinfo^.life,self.optinfo^.regmap);
+ if createphi then
+ update_phi(current_asmdata.CurrAsmList,optinfo^.life,optinfo^.regmap);
current_procinfo.CurrContinueLabel:=lcont;
current_procinfo.CurrBreakLabel:=lbreak;
if assigned(right) then
secondpass(right);
- if assigned(optinfo) then
- generate_phi(current_asmdata.CurrAsmList,self.optinfo^.life,self.optinfo^.regmap);
+ if createphi then
+ generate_phi(current_asmdata.CurrAsmList,optinfo^.life,optinfo^.regmap);
{$ifdef OLDREGVARS}
load_all_regvars(current_asmdata.CurrAsmList);
@@ -199,13 +211,21 @@ implementation
current_procinfo.CurrFalseLabel:=lbreak;
end;
- if assigned(optinfo) then
- update_phi(current_asmdata.CurrAsmList,self.optinfo^.life,self.optinfo^.regmap);
+ if createphi then
+ update_phi(current_asmdata.CurrAsmList,optinfo^.life,optinfo^.regmap);
secondpass(left);
maketojumpbool(current_asmdata.CurrAsmList,left,lr_load_regvars);
- cg.a_label(current_asmdata.CurrAsmList,lbreak);
+
+ if createphi then
+ begin
+ { when comming from a break or continue label, we've to generate phi nodes first }
+ cg.a_label(current_asmdata.CurrAsmList,lbreak);
+ update_phi(current_asmdata.CurrAsmList,successor.optinfo^.life,successor.optinfo^.regmap);
+ end
+ else
+ cg.a_label(current_asmdata.CurrAsmList,lbreak);
// sync_regvars(false);
@@ -246,9 +266,8 @@ implementation
block_regmap:=nil;
join_regmap:=nil;
- if assigned(t1) then
- if has_life_info(t1) then
- getregmapping(t1.optinfo^.life,block_regmap);
+ if has_life_info(t1) then
+ getregmapping(t1.optinfo^.life,block_regmap);
{ then block ? }
if assigned(right) then
@@ -719,7 +738,7 @@ implementation
secondpass(left);
if has_life_info(successor) then
- generate_phi(current_asmdata.CurrAsmList,optinfo^.life,optinfo^.regmap);
+ generate_phi(current_asmdata.CurrAsmList,successor.optinfo^.life,successor.optinfo^.regmap);
cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrExitLabel);
end;
diff --git a/compiler/ncgutil.pas b/compiler/ncgutil.pas
index 32c03efa67..e45728e05b 100644
--- a/compiler/ncgutil.pas
+++ b/compiler/ncgutil.pas
@@ -2680,7 +2680,7 @@ implementation
{ now we've a valid map, now move things to those registers }
regmapindex:=0;
old_add_reg_instruction_hook:=add_reg_instruction_hook;
- // add_reg_instruction_hook:=nil;
+// add_reg_instruction_hook:=nil;
writeln('Regmap size: ',regmap.count);
for i:=0 to get_current_dfabuilder.nodemap.count-1 do
begin
@@ -2706,6 +2706,7 @@ implementation
begin
newreg:=cg.getintregister(list,varsym.localloc.size);
cg.a_reg_dealloc(list,varsym.localloc.register);
+ cg.a_reg_alloc(list,newreg);
cg.a_load_reg_reg(list,varsym.localloc.size,varsym.localloc.size,
varsym.localloc.register,newreg);
@@ -2732,6 +2733,7 @@ implementation
begin
newreg:=cg.getmmregister(list,varsym.localloc.size);
cg.a_reg_dealloc(list,varsym.localloc.register);
+ cg.a_reg_alloc(list,newreg);
cg.a_loadmm_reg_reg(list,varsym.localloc.size,varsym.localloc.size,
varsym.localloc.register,newreg,mms_movescalar);
@@ -2792,7 +2794,9 @@ implementation
begin
newreg:=cg.getintregister(list,varsym.localloc.size);
cg.rg[R_INTREGISTER].set_alias(getsupreg(newreg),getsupreg(tregister(regmap[regmapindex])));
+ cg.a_reg_dealloc(list,varsym.localloc.register);
varsym.localloc.register:=newreg;
+ cg.a_reg_alloc(list,varsym.localloc.register);
{$ifdef DEBUG_SSA}
list.concat(tai_comment.create(strpnew(varsym.name+' causes combine '+
generic_regname(tregister(regmap[regmapindex]))+' and '+generic_regname(newreg))));
@@ -2814,7 +2818,9 @@ implementation
begin
newreg:=cg.getmmregister(list,varsym.localloc.size);
cg.rg[R_MMREGISTER].set_alias(getsupreg(newreg),getsupreg(tregister(regmap[regmapindex])));
+ cg.a_reg_dealloc(list,varsym.localloc.register);
varsym.localloc.register:=newreg;
+ cg.a_reg_sync(list,varsym.localloc.register);
{$ifdef DEBUG_SSA}
list.concat(tai_comment.create(strpnew(varsym.name+' causes combine '+
generic_regname(tregister(regmap[regmapindex]))+' and '+generic_regname(newreg))));
@@ -2872,10 +2878,10 @@ implementation
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);
}
- end;
+ LOC_CMMREGISTER:
+ regmap.Add(pointer(ord(varsym.localloc.register)));
+ end;
end;
end;
end;
@@ -2919,9 +2925,6 @@ implementation
{$endif cpu64bit}
begin
varsym.localloc.register:=tregister(regmap[regmapindex]);
-{$ifdef DEBUG_SSA}
- list.concat(tai_comment.create(strpnew(varsym.name+' now in '+generic_regname(varsym.localloc.register))));
-{$endif DEBUG_SSA}
{ entry used }
inc(regmapindex);
end;
@@ -2937,18 +2940,20 @@ implementation
LOC_CMMREGISTER:
begin
varsym.localloc.register:=tregister(regmap[regmapindex]);
-{$ifdef DEBUG_SSA}
- list.concat(tai_comment.create(strpnew(varsym.name+' now in '+generic_regname(varsym.localloc.register))));
-{$endif DEBUG_SSA}
{ entry used }
inc(regmapindex);
end;
end;
+{$ifdef DEBUG_SSA}
+ list.concat(tai_comment.create(strpnew(varsym.name+' now in '+generic_regname(varsym.localloc.register))));
+{$endif DEBUG_SSA}
+ cg.a_reg_alloc(list,varsym.localloc.register);
end;
end;
end;
end;
+
procedure gen_free_symtable(list:TAsmList;st:TSymtable);
var
i : longint;