mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-16 16:19:21 +02:00
* less unnecessary regvar loading with if-statements
This commit is contained in:
parent
a52d9a8b79
commit
6dbf240bde
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user