mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-06 19:10:18 +02:00
* generate better code for length(<dyn. type>)=0, resolves #36060
git-svn-id: trunk@43272 -
This commit is contained in:
parent
e251c8e2ab
commit
e80eee5da5
@ -22,6 +22,7 @@
|
||||
unit nadd;
|
||||
|
||||
{$i fpcdefs.inc}
|
||||
{$modeswitch nestedprocvars}
|
||||
|
||||
{ define addstringopt}
|
||||
|
||||
@ -446,6 +447,35 @@ implementation
|
||||
result:=true;
|
||||
end;
|
||||
|
||||
function IsLengthZero(n1,n2 : tnode) : Boolean;
|
||||
begin
|
||||
result:=is_inlinefunction(n1,in_length_x) and is_constintvalue(n2,0) and not(is_shortstring(tinlinenode(n1).left.resultdef));
|
||||
end;
|
||||
|
||||
|
||||
function TransformLengthZero(n1,n2 : tnode) : tnode;
|
||||
var
|
||||
len : Tconstexprint;
|
||||
begin
|
||||
if is_dynamic_array(tinlinenode(n1).left.resultdef) then
|
||||
len:=-1
|
||||
else
|
||||
len:=0;
|
||||
result:=caddnode.create_internal(orn,
|
||||
caddnode.create_internal(equaln,ctypeconvnode.create_internal(tinlinenode(n1).left.getcopy,voidpointertype),
|
||||
cpointerconstnode.create(0,voidpointertype)),
|
||||
caddnode.create_internal(equaln,
|
||||
ctypeconvnode.create_internal(
|
||||
cderefnode.create(
|
||||
caddnode.create_internal(subn,ctypeconvnode.create_internal(tinlinenode(n1).left.getcopy,voidpointertype),
|
||||
cordconstnode.create(0,sizesinttype,false))
|
||||
),sizesinttype
|
||||
),
|
||||
cordconstnode.create(len,sizesinttype,false))
|
||||
);
|
||||
end;
|
||||
|
||||
|
||||
var
|
||||
t , vl: tnode;
|
||||
lt,rt : tnodetype;
|
||||
@ -1172,7 +1202,9 @@ implementation
|
||||
else
|
||||
;
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else if (nodetype=equaln) and MatchAndTransformNodesCommutative(left,right,@IsLengthZero,@TransformLengthZero,Result) then
|
||||
exit;
|
||||
end;
|
||||
|
||||
{ using sqr(x) for reals instead of x*x might reduces register pressure and/or
|
||||
|
@ -22,13 +22,14 @@
|
||||
unit nutils;
|
||||
|
||||
{$i fpcdefs.inc}
|
||||
{$modeswitch nestedprocvars}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
globtype,constexp,
|
||||
symtype,symsym,symbase,symtable,
|
||||
node;
|
||||
node,compinnr;
|
||||
|
||||
const
|
||||
NODE_COMPLEXITY_INF = 255;
|
||||
@ -168,10 +169,24 @@ interface
|
||||
if it is not an orn/andn with boolean operans, the result is undefined }
|
||||
function doshortbooleval(p : tnode) : Boolean;
|
||||
|
||||
{ returns true if the node has the int value l }
|
||||
function is_constintvalue(p : tnode;l : Tconstexprint) : Boolean;
|
||||
|
||||
{ returns true if the node is an inline node of type i }
|
||||
function is_inlinefunction(p : tnode;i : tinlinenumber) : Boolean;
|
||||
|
||||
type
|
||||
TMatchProc2 = function(n1,n2 : tnode) : Boolean is nested;
|
||||
TTransformProc2 = function(n1,n2 : tnode) : tnode is nested;
|
||||
|
||||
{ calls matchproc with n1 and n2 as parameters, if it returns true, transformproc is called, does the same with the nodes swapped,
|
||||
the result of transformproc is assigned to res }
|
||||
function MatchAndTransformNodesCommutative(n1,n2 : tnode;matchproc : TMatchProc2;transformproc : TTransformProc2;var res : tnode) : Boolean;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
cutils,verbose,globals,compinnr,
|
||||
cutils,verbose,globals,
|
||||
symconst,symdef,
|
||||
defcmp,defutil,
|
||||
nbas,ncon,ncnv,nld,nflw,nset,ncal,nadd,nmem,ninl,
|
||||
@ -1530,4 +1545,29 @@ implementation
|
||||
Result:=(p.nodetype in [orn,andn]) and ((nf_short_bool in taddnode(p).flags) or not(cs_full_boolean_eval in p.localswitches));
|
||||
end;
|
||||
|
||||
|
||||
function is_constintvalue(p: tnode; l: Tconstexprint): Boolean;
|
||||
begin
|
||||
Result:=is_constintnode(p) and (tordconstnode(p).value=l);
|
||||
end;
|
||||
|
||||
|
||||
function is_inlinefunction(p: tnode; i: tinlinenumber): Boolean;
|
||||
begin
|
||||
Result:=(p.nodetype=inlinen) and (tinlinenode(p).inlinenumber=i);
|
||||
end;
|
||||
|
||||
|
||||
function MatchAndTransformNodesCommutative(n1,n2 : tnode;matchproc : TMatchProc2;transformproc : TTransformProc2;var res : tnode) : Boolean;
|
||||
begin
|
||||
res:=nil;
|
||||
result:=true;
|
||||
if matchproc(n1,n2) then
|
||||
res:=transformproc(n1,n2)
|
||||
else if matchproc(n2,n1) then
|
||||
res:=transformproc(n2,n1)
|
||||
else
|
||||
result:=false;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user