* less unnecessary regvar loading with if-statements

This commit is contained in:
Jonas Maebe 2001-12-02 16:19:17 +00:00
parent a52d9a8b79
commit 6dbf240bde
5 changed files with 123 additions and 33 deletions

View File

@ -128,16 +128,15 @@ interface
{ ti386addnode.first_string and implement the shortstring concat } { ti386addnode.first_string and implement the shortstring concat }
{ manually! The generic routine is different from the i386 one (JM) } { manually! The generic routine is different from the i386 one (JM) }
function ti386addnode.first_addstring : tnode; function ti386addnode.first_addstring : tnode;
begin begin
{ special cases for shortstrings, handled in pass_2 (JM) } { special cases for shortstrings, handled in pass_2 (JM) }
{ can't handle fpc_shortstr_compare with compilerproc either because it } { can't handle fpc_shortstr_compare with compilerproc either because it }
{ returns its results in the flags instead of in eax } { returns its results in the flags instead of in eax }
if ((nodetype = addn) and if (((nodetype = addn) and
is_shortstring(resulttype.def)) or is_shortstring(resulttype.def)) or
((nodetype in [ltn,lten,gtn,gten,equaln,unequaln]) and ((nodetype in [ltn,lten,gtn,gten,equaln,unequaln]) and
not(((left.nodetype=stringconstn) and (str_length(left)=0)) or is_shortstring(left.resulttype.def))) then
((right.nodetype=stringconstn) and (str_length(right)=0))) and
is_shortstring(left.resulttype.def)) then
begin begin
if nodetype = addn then if nodetype = addn then
location.loc := LOC_MEM location.loc := LOC_MEM
@ -463,7 +462,7 @@ interface
otl:=truelabel; otl:=truelabel;
getlabel(truelabel); getlabel(truelabel);
secondpass(left); secondpass(left);
maketojumpbool(left); maketojumpbool(left,lr_load_regvars);
emitlab(truelabel); emitlab(truelabel);
truelabel:=otl; truelabel:=otl;
end; end;
@ -471,7 +470,7 @@ interface
ofl:=falselabel; ofl:=falselabel;
getlabel(falselabel); getlabel(falselabel);
secondpass(left); secondpass(left);
maketojumpbool(left); maketojumpbool(left,lr_load_regvars);
emitlab(falselabel); emitlab(falselabel);
falselabel:=ofl; falselabel:=ofl;
end; end;
@ -479,7 +478,7 @@ interface
CGMessage(type_e_mismatch); CGMessage(type_e_mismatch);
end; end;
secondpass(right); secondpass(right);
maketojumpbool(right); maketojumpbool(right,lr_load_regvars);
end; end;
else else
CGMessage(type_e_mismatch); CGMessage(type_e_mismatch);
@ -1864,7 +1863,10 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.25 2001-10-12 13:51:51 jonas Revision 1.26 2001-12-02 16:19:17 jonas
* less unnecessary regvar loading with if-statements
Revision 1.25 2001/10/12 13:51:51 jonas
* fixed internalerror(10) due to previous fpu overflow fixes ("merged") * fixed internalerror(10) due to previous fpu overflow fixes ("merged")
* fixed bug in n386add (introduced after compilerproc changes for string * fixed bug in n386add (introduced after compilerproc changes for string
operations) where calcregisters wasn't called for shortstring addnodes operations) where calcregisters wasn't called for shortstring addnodes

View File

@ -97,7 +97,7 @@ implementation
getlabel(truelabel); getlabel(truelabel);
getlabel(falselabel); getlabel(falselabel);
secondpass(tcallparanode(left).left); secondpass(tcallparanode(left).left);
maketojumpbool(tcallparanode(left).left); maketojumpbool(tcallparanode(left).left,lr_load_regvars);
emitlab(falselabel); emitlab(falselabel);
{ erroraddr } { erroraddr }
emit_reg(A_PUSH,S_L,R_EBP); emit_reg(A_PUSH,S_L,R_EBP);
@ -843,8 +843,8 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.27 2001-09-30 16:16:28 jonas Revision 1.28 2001-12-02 16:19:17 jonas
- removed unused units form uses-clause and unused local vars * less unnecessary regvar loading with if-statements
Revision 1.26 2001/09/28 20:38:51 jonas Revision 1.26 2001/09/28 20:38:51 jonas
* fixed big bug in my previous changes (the arguent for bts/btr is always * fixed big bug in my previous changes (the arguent for bts/btr is always

View File

@ -860,7 +860,7 @@ implementation
truelabel:=falselabel; truelabel:=falselabel;
falselabel:=hl; falselabel:=hl;
secondpass(left); secondpass(left);
maketojumpbool(left); maketojumpbool(left,lr_load_regvars);
hl:=truelabel; hl:=truelabel;
truelabel:=falselabel; truelabel:=falselabel;
falselabel:=hl; falselabel:=hl;
@ -1016,7 +1016,10 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.16 2001-09-05 15:22:10 jonas Revision 1.17 2001-12-02 16:19:17 jonas
* less unnecessary regvar loading with if-statements
Revision 1.16 2001/09/05 15:22:10 jonas
* made multiplying, dividing and mod'ing of int64 and qword processor * made multiplying, dividing and mod'ing of int64 and qword processor
independent with compilerprocs (+ small optimizations by using shift/and independent with compilerprocs (+ small optimizations by using shift/and
where possible) where possible)

View File

@ -29,6 +29,9 @@ interface
uses uses
symtype,node; symtype,node;
type
tloadregvars = (lr_dont_load_regvars, lr_load_regvars);
function maybe_push(needed : byte;p : tnode;isint64 : boolean) : boolean; function maybe_push(needed : byte;p : tnode;isint64 : boolean) : boolean;
function maybe_pushfpu(needed : byte;p : tnode) : boolean; function maybe_pushfpu(needed : byte;p : tnode) : boolean;
{$ifdef TEMPS_NOT_PUSH} {$ifdef TEMPS_NOT_PUSH}
@ -47,7 +50,7 @@ interface
procedure loadwide2short(source,dest : tnode); procedure loadwide2short(source,dest : tnode);
procedure loadinterfacecom(p: tbinarynode); procedure loadinterfacecom(p: tbinarynode);
procedure maketojumpbool(p : tnode); procedure maketojumpbool(p : tnode; loadregvars: tloadregvars);
procedure emitoverflowcheck(p:tnode); procedure emitoverflowcheck(p:tnode);
procedure emitrangecheck(p:tnode;todef:tdef); procedure emitrangecheck(p:tnode;todef:tdef);
procedure firstcomplex(p : tbinarynode); procedure firstcomplex(p : tbinarynode);
@ -869,9 +872,14 @@ implementation
Emit Functions Emit Functions
*****************************************************************************} *****************************************************************************}
procedure maketojumpbool(p : tnode); procedure maketojumpbool(p : tnode; loadregvars: tloadregvars);
{ {
produces jumps to true respectively false labels using boolean expressions produces jumps to true respectively false labels using boolean expressions
depending on whether the loading of regvars is currently being
synchronized manually (such as in an if-node) or automatically (most of
the other cases where this procedure is called), loadregvars can be
"lr_load_regvars" or "lr_dont_load_regvars"
} }
var var
opsize : topsize; opsize : topsize;
@ -883,6 +891,7 @@ implementation
aktfilepos:=p.fileinfo; aktfilepos:=p.fileinfo;
if is_boolean(p.resulttype.def) then if is_boolean(p.resulttype.def) then
begin begin
if loadregvars = lr_load_regvars then
load_all_regvars(exprasmlist); load_all_regvars(exprasmlist);
if is_constboolnode(p) then if is_constboolnode(p) then
begin begin
@ -896,6 +905,8 @@ implementation
opsize:=def_opsize(p.resulttype.def); opsize:=def_opsize(p.resulttype.def);
case p.location.loc of case p.location.loc of
LOC_CREGISTER,LOC_REGISTER : begin LOC_CREGISTER,LOC_REGISTER : begin
if (p.location.loc = LOC_CREGISTER) then
load_regvar_reg(exprasmlist,p.location.register);
emit_reg_reg(A_OR,opsize,p.location.register, emit_reg_reg(A_OR,opsize,p.location.register,
p.location.register); p.location.register);
ungetregister(p.location.register); ungetregister(p.location.register);
@ -1155,8 +1166,6 @@ implementation
else else
op:=A_MOVZX; op:=A_MOVZX;
is_reg:=(p.location.loc in [LOC_REGISTER,LOC_CREGISTER]); is_reg:=(p.location.loc in [LOC_REGISTER,LOC_CREGISTER]);
getexplicitregister32(R_EDI);
{ use the trick that } { use the trick that }
{ a <= x <= b <=> 0 <= x-a <= b-a <=> cardinal(x-a) <= cardinal(b-a) } { a <= x <= b <=> 0 <= x-a <= b-a <=> cardinal(x-a) <= cardinal(b-a) }
@ -1199,6 +1208,7 @@ implementation
lto := 0; lto := 0;
end; end;
getexplicitregister32(R_EDI);
if is_reg and if is_reg and
(opsize = S_L) then (opsize = S_L) then
emit_ref_reg(A_LEA,opsize,new_reference(p.location.register,-lto), emit_ref_reg(A_LEA,opsize,new_reference(p.location.register,-lto),
@ -1534,7 +1544,10 @@ implementation
end. end.
{ {
$Log$ $Log$
Revision 1.22 2001-10-12 13:51:52 jonas Revision 1.23 2001-12-02 16:19:17 jonas
* less unnecessary regvar loading with if-statements
Revision 1.22 2001/10/12 13:51:52 jonas
* fixed internalerror(10) due to previous fpu overflow fixes ("merged") * fixed internalerror(10) due to previous fpu overflow fixes ("merged")
* fixed bug in n386add (introduced after compilerproc changes for string * fixed bug in n386add (introduced after compilerproc changes for string
operations) where calcregisters wasn't called for shortstring addnodes operations) where calcregisters wasn't called for shortstring addnodes

View File

@ -66,7 +66,7 @@ interface
implementation implementation
uses uses
verbose,globals,systems, verbose,globals,systems,globtype,
symconst,symdef,symsym,aasm,types, symconst,symdef,symsym,aasm,types,
cgbase,temp_gen,pass_2, cgbase,temp_gen,pass_2,
cpubase,cpuasm,cpuinfo, cpubase,cpuasm,cpuinfo,
@ -130,9 +130,7 @@ implementation
cleartempgen; cleartempgen;
secondpass(left); secondpass(left);
load_all_regvars(exprasmlist); maketojumpbool(left,lr_load_regvars);
maketojumpbool(left);
cg.a_label(exprasmlist,lbreak); cg.a_label(exprasmlist,lbreak);
truelabel:=otlabel; truelabel:=otlabel;
falselabel:=oflabel; falselabel:=oflabel;
@ -152,6 +150,13 @@ implementation
var var
hl,otlabel,oflabel : tasmlabel; hl,otlabel,oflabel : tasmlabel;
org_regvar_loaded,
then_regvar_loaded,
else_regvar_loaded : regvar_booleanarray;
org_list,
then_list,
else_list : taasmoutput;
regcounter: tregister;
begin begin
otlabel:=truelabel; otlabel:=truelabel;
@ -160,40 +165,104 @@ implementation
getlabel(falselabel); getlabel(falselabel);
cleartempgen; cleartempgen;
secondpass(left); secondpass(left);
load_all_regvars(exprasmlist);
maketojumpbool(left);
{ save regvars loaded in the beginning so that we can restore them }
{ when processing the else-block }
if cs_regalloc in aktglobalswitches then
begin
org_list := exprasmlist;
exprasmlist := taasmoutput.create;
end;
maketojumpbool(left,lr_dont_load_regvars);
if cs_regalloc in aktglobalswitches then
org_regvar_loaded := regvar_loaded;
if assigned(right) then if assigned(right) then
begin begin
cg.a_label(exprasmlist,truelabel); cg.a_label(exprasmlist,truelabel);
cleartempgen; cleartempgen;
secondpass(right); secondpass(right);
{ automatically done for blocks, but not for statements (JM) }
load_all_regvars(exprasmlist);
end; end;
{ save current asmlist (previous instructions + then-block) and }
{ loaded regvar state and create new clean ones }
if cs_regalloc in aktglobalswitches then
begin
then_regvar_loaded := regvar_loaded;
regvar_loaded := org_regvar_loaded;
then_list := exprasmlist;
exprasmlist := taasmoutput.create;
end;
if assigned(t1) then if assigned(t1) then
begin begin
if assigned(right) then if assigned(right) then
begin begin
getlabel(hl); getlabel(hl);
{ do go back to if line !! } { do go back to if line !! }
aktfilepos:=exprasmList.getlasttaifilepos^; if not(cs_regalloc in aktglobalswitches) then
aktfilepos:=exprasmList.getlasttaifilepos^
else
aktfilepos:=then_list.getlasttaifilepos^;
cg.a_jmp_cond(exprasmlist,OC_None,hl); cg.a_jmp_cond(exprasmlist,OC_None,hl);
end; end;
cg.a_label(exprasmlist,falselabel); cg.a_label(exprasmlist,falselabel);
cleartempgen; cleartempgen;
secondpass(t1); secondpass(t1);
load_all_regvars(exprasmlist); { save current asmlist (previous instructions + else-block) }
{ and loaded regvar state and create a new clean list }
if cs_regalloc in aktglobalswitches then
begin
else_regvar_loaded := regvar_loaded;
else_list := exprasmlist;
exprasmlist := taasmoutput.create;
end;
if assigned(right) then if assigned(right) then
cg.a_label(exprasmlist,hl); cg.a_label(exprasmlist,hl);
end end
else else
begin begin
if cs_regalloc in aktglobalswitches then
begin
else_regvar_loaded := regvar_loaded;
else_list := exprasmlist;
exprasmlist := taasmoutput.create;
end;
cg.a_label(exprasmlist,falselabel); cg.a_label(exprasmlist,falselabel);
end; end;
if not(assigned(right)) then if not(assigned(right)) then
begin begin
cg.a_label(exprasmlist,truelabel); cg.a_label(exprasmlist,truelabel);
end; end;
if cs_regalloc in aktglobalswitches then
begin
{ add loads of regvars at the end of the then- and else-blocks }
{ so that at the end of both blocks the same regvars are loaded }
{ no else block? }
if not assigned(t1) then
sync_regvars(org_list,then_list,org_regvar_loaded,
then_regvar_loaded)
{ no then block? }
else if not assigned(right) then
sync_regvars(org_list,else_list,org_regvar_loaded,
else_regvar_loaded)
{ both else and then blocks }
else
sync_regvars(then_list,else_list,then_regvar_loaded,
else_regvar_loaded);
{ add all lists together }
org_list.concatlist(then_list);
then_list.free;
org_list.concatlist(else_list);
else_list.free;
org_list.concatlist(exprasmlist);
exprasmlist.free;
exprasmlist := org_list;
end;
truelabel:=otlabel; truelabel:=otlabel;
falselabel:=oflabel; falselabel:=oflabel;
end; end;
@ -390,7 +459,7 @@ implementation
label label
do_jmp; do_jmp;
begin begin
load_all_regvars(exprasmlist); { load_all_regvars(exprasmlist); }
include(flowcontrol,fc_exit); include(flowcontrol,fc_exit);
if assigned(left) then if assigned(left) then
if left.nodetype=assignn then if left.nodetype=assignn then
@ -582,7 +651,10 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.4 2001-11-02 22:58:01 peter Revision 1.5 2001-12-02 16:19:17 jonas
* less unnecessary regvar loading with if-statements
Revision 1.4 2001/11/02 22:58:01 peter
* procsym definition rewrite * procsym definition rewrite
Revision 1.3 2001/10/04 14:33:28 jonas Revision 1.3 2001/10/04 14:33:28 jonas